as released 2000-06-05
This commit is contained in:
parent
b443b4420e
commit
7e9f0c84ab
2
Network/Delta.txt
Normal file
2
Network/Delta.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Place delta.lst in the valve\ folder ( or a customized copy can be placed in your game directory's folder )
|
||||
|
234
Network/delta.lst
Normal file
234
Network/delta.lst
Normal file
@ -0,0 +1,234 @@
|
||||
// structure name
|
||||
// none == no conditional encode routine
|
||||
// gamedll routine_name : before transmitting data, invoke the named function from the game .dll to reset fields as needed
|
||||
// clientdll routine_name : same as above, except the routine is called via the client.dll
|
||||
|
||||
clientdata_t none
|
||||
{
|
||||
DEFINE_DELTA( flTimeStepSound, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( origin[0], DT_SIGNED | DT_FLOAT, 21, 128.0 ),
|
||||
DEFINE_DELTA( origin[1], DT_SIGNED | DT_FLOAT, 21, 128.0 ),
|
||||
DEFINE_DELTA( velocity[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( velocity[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
|
||||
DEFINE_DELTA( m_flNextAttack, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
|
||||
DEFINE_DELTA( origin[2], DT_SIGNED | DT_FLOAT, 21, 128.0 ),
|
||||
DEFINE_DELTA( velocity[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
|
||||
DEFINE_DELTA( ammo_nails, DT_SIGNED | DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( ammo_shells, DT_SIGNED | DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( ammo_cells, DT_SIGNED | DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( ammo_rockets, DT_SIGNED | DT_INTEGER, 10, 1.0 ),
|
||||
|
||||
DEFINE_DELTA( m_iId, DT_INTEGER, 5, 1.0 ),
|
||||
|
||||
DEFINE_DELTA( punchangle[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( flags, DT_INTEGER, 32, 1.0 ), // Cut to 3 bits?
|
||||
DEFINE_DELTA( weaponanim, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( health, DT_SIGNED | DT_FLOAT, 10, 1.0 ), // Cut # of bits?
|
||||
DEFINE_DELTA( maxspeed, DT_FLOAT, 16, 10.0 ),
|
||||
DEFINE_DELTA( flDuckTime, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( view_ofs[2], DT_SIGNED | DT_FLOAT, 10, 4.0 ),
|
||||
DEFINE_DELTA( punchangle[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( punchangle[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( viewmodel, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( weapons, DT_INTEGER, 32, 1.0 ),
|
||||
|
||||
DEFINE_DELTA( pushmsec, DT_INTEGER, 11, 1.0 ),
|
||||
DEFINE_DELTA( deadflag, DT_INTEGER, 3, 1.0 ),
|
||||
DEFINE_DELTA( fov, DT_FLOAT, 8, 1.0 ),
|
||||
DEFINE_DELTA( physinfo, DT_STRING, 1, 1.0 ),
|
||||
DEFINE_DELTA( bInDuck, DT_INTEGER, 1, 1.0 ),
|
||||
DEFINE_DELTA( flSwimTime, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( waterjumptime, DT_INTEGER, 15, 1.0 ),
|
||||
DEFINE_DELTA( waterlevel, DT_INTEGER, 2, 1.0 )
|
||||
}
|
||||
|
||||
entity_state_t gamedll Entity_Encode
|
||||
{
|
||||
DEFINE_DELTA( animtime, DT_TIMEWINDOW_8, 8, 1.0 ),
|
||||
DEFINE_DELTA( frame, DT_FLOAT, 8, 1.0 ),
|
||||
DEFINE_DELTA( origin[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( angles[0], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( angles[1], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( origin[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( origin[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( sequence, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( modelindex, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( movetype, DT_INTEGER, 4, 1.0 ),
|
||||
DEFINE_DELTA( solid, DT_SHORT, 3, 1.0 ),
|
||||
DEFINE_DELTA( mins[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( mins[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( mins[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( maxs[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( maxs[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( maxs[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
|
||||
DEFINE_DELTA( endpos[0], DT_SIGNED | DT_FLOAT, 13, 1.0 ),
|
||||
DEFINE_DELTA( endpos[1], DT_SIGNED | DT_FLOAT, 13, 1.0 ),
|
||||
DEFINE_DELTA( endpos[2], DT_SIGNED | DT_FLOAT, 13, 1.0 ),
|
||||
DEFINE_DELTA( startpos[0], DT_SIGNED | DT_FLOAT, 13, 1.0 ),
|
||||
DEFINE_DELTA( startpos[1], DT_SIGNED | DT_FLOAT, 13, 1.0 ),
|
||||
DEFINE_DELTA( startpos[2], DT_SIGNED | DT_FLOAT, 13, 1.0 ),
|
||||
DEFINE_DELTA( impacttime, DT_TIMEWINDOW_BIG, 13, 100.0 ),
|
||||
DEFINE_DELTA( starttime, DT_TIMEWINDOW_BIG, 13, 100.0 ),
|
||||
|
||||
DEFINE_DELTA( weaponmodel, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( owner, DT_INTEGER, 5, 1.0 ),
|
||||
DEFINE_DELTA( effects, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( eflags, DT_INTEGER, 1, 1.0 ),
|
||||
DEFINE_DELTA( angles[2], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( colormap, DT_INTEGER, 16, 1.0 ),
|
||||
DEFINE_DELTA( framerate, DT_SIGNED | DT_FLOAT, 8, 16.0 ),
|
||||
DEFINE_DELTA( skin, DT_SHORT | DT_SIGNED, 9, 1.0 ),
|
||||
DEFINE_DELTA( controller[0], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( controller[1], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( controller[2], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( controller[3], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( blending[0], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( blending[1], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( body, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendermode, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( renderamt, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( renderfx, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( scale, DT_FLOAT, 16, 256.0 ),
|
||||
DEFINE_DELTA( rendercolor.r, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.g, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.b, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( aiment, DT_INTEGER, 11, 1.0 ),
|
||||
DEFINE_DELTA( basevelocity[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( basevelocity[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( basevelocity[2], DT_SIGNED | DT_FLOAT, 16, 8.0 )
|
||||
}
|
||||
|
||||
entity_state_player_t gamedll Player_Encode
|
||||
{
|
||||
DEFINE_DELTA( animtime, DT_TIMEWINDOW_8, 8, 1.0 ),
|
||||
DEFINE_DELTA( frame, DT_FLOAT, 8, 1.0 ),
|
||||
DEFINE_DELTA( origin[0], DT_SIGNED | DT_FLOAT, 18, 32.0 ),
|
||||
DEFINE_DELTA( angles[0], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( angles[1], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( origin[1], DT_SIGNED | DT_FLOAT, 18, 32.0 ),
|
||||
DEFINE_DELTA( origin[2], DT_SIGNED | DT_FLOAT, 18, 32.0 ),
|
||||
DEFINE_DELTA( gaitsequence, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( sequence, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( modelindex, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( movetype, DT_INTEGER, 4, 1.0 ),
|
||||
DEFINE_DELTA( solid, DT_SHORT, 3, 1.0 ),
|
||||
DEFINE_DELTA( mins[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( mins[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( mins[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( maxs[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( maxs[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( maxs[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( weaponmodel, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( team, DT_INTEGER, 4, 1.0 )
|
||||
DEFINE_DELTA( playerclass, DT_INTEGER, 4, 1.0 )
|
||||
DEFINE_DELTA( owner, DT_INTEGER, 5, 1.0 ),
|
||||
DEFINE_DELTA( effects, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( angles[2], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( colormap, DT_INTEGER, 16, 1.0 ),
|
||||
DEFINE_DELTA( framerate, DT_SIGNED | DT_FLOAT, 8, 16.0 ),
|
||||
DEFINE_DELTA( skin, DT_SHORT | DT_SIGNED, 9, 1.0 ),
|
||||
DEFINE_DELTA( controller[0], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( controller[1], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( controller[2], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( controller[3], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( blending[0], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( blending[1], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( body, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendermode, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( renderamt, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( renderfx, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( scale, DT_FLOAT, 16, 256.0 ),
|
||||
DEFINE_DELTA( rendercolor.r, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.g, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.b, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( friction, DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( usehull, DT_INTEGER, 1, 1.0 ),
|
||||
DEFINE_DELTA( gravity, DT_SIGNED | DT_FLOAT, 16, 32.0 ),
|
||||
DEFINE_DELTA( aiment, DT_INTEGER, 11, 1.0 ),
|
||||
DEFINE_DELTA( basevelocity[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( basevelocity[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( basevelocity[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( spectator, DT_INTEGER, 1, 1.0 )
|
||||
}
|
||||
|
||||
custom_entity_state_t gamedll Custom_Encode
|
||||
{
|
||||
DEFINE_DELTA( rendermode, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( origin[0], DT_SIGNED | DT_FLOAT, 17, 8.0 ),
|
||||
DEFINE_DELTA( origin[1], DT_SIGNED | DT_FLOAT, 17, 8.0 ),
|
||||
DEFINE_DELTA( origin[2], DT_SIGNED | DT_FLOAT, 17, 8.0 ),
|
||||
DEFINE_DELTA( angles[0], DT_SIGNED | DT_FLOAT, 17, 8.0 ),
|
||||
DEFINE_DELTA( angles[1], DT_SIGNED | DT_FLOAT, 17, 8.0 ),
|
||||
DEFINE_DELTA( angles[2], DT_SIGNED | DT_FLOAT, 17, 8.0 ),
|
||||
DEFINE_DELTA( sequence, DT_INTEGER, 16, 1.0 ),
|
||||
DEFINE_DELTA( skin, DT_INTEGER, 16, 1.0 ),
|
||||
DEFINE_DELTA( modelindex, DT_INTEGER, 16, 1.0 ),
|
||||
DEFINE_DELTA_POST( scale, DT_FLOAT, 8, 1.0, 0.1 ),
|
||||
DEFINE_DELTA( body, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.r, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.g, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.b, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( renderfx, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( renderamt, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( frame, DT_FLOAT, 8, 1.0 ),
|
||||
DEFINE_DELTA_POST( animtime, DT_FLOAT, 8, 1.0, 0.1 )
|
||||
}
|
||||
|
||||
usercmd_t none
|
||||
{
|
||||
DEFINE_DELTA( lerp_msec, DT_SHORT, 9, 1.0 ),
|
||||
DEFINE_DELTA( msec, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( viewangles[1], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( viewangles[0], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( buttons, DT_SHORT, 16, 1.0 ),
|
||||
DEFINE_DELTA( forwardmove, DT_SIGNED | DT_FLOAT, 12, 1.0 ),
|
||||
DEFINE_DELTA( lightlevel, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( sidemove, DT_SIGNED | DT_FLOAT, 12, 1.0 ),
|
||||
DEFINE_DELTA( upmove, DT_SIGNED | DT_FLOAT, 12, 1.0 ),
|
||||
DEFINE_DELTA( impulse, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( viewangles[2], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( impact_index, DT_INTEGER, 6, 1.0 ),
|
||||
DEFINE_DELTA( impact_position[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( impact_position[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( impact_position[2], DT_SIGNED | DT_FLOAT, 16, 8.0 )
|
||||
}
|
||||
|
||||
weapon_data_t none
|
||||
{
|
||||
DEFINE_DELTA( m_flTimeWeaponIdle, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
DEFINE_DELTA( m_flNextPrimaryAttack, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
DEFINE_DELTA( m_flNextReload, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
DEFINE_DELTA( m_fNextAimBonus, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
DEFINE_DELTA( m_flNextSecondaryAttack, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
DEFINE_DELTA( m_iClip, DT_SIGNED | DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( m_flPumpTime, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
DEFINE_DELTA( m_fInSpecialReload, DT_INTEGER, 2, 1.0 ),
|
||||
DEFINE_DELTA( m_fReloadTime, DT_FLOAT, 16, 100.0 ),
|
||||
DEFINE_DELTA( m_fInReload, DT_INTEGER, 1, 1.0 ),
|
||||
DEFINE_DELTA( m_fAimedDamage, DT_FLOAT, 6, 0.1 ),
|
||||
DEFINE_DELTA( m_fInZoom, DT_INTEGER, 1, 1.0 ),
|
||||
DEFINE_DELTA( m_iWeaponState, DT_INTEGER, 2, 1.0 ),
|
||||
DEFINE_DELTA( m_iId, DT_INTEGER, 5, 1.0 )
|
||||
}
|
||||
|
||||
event_t none
|
||||
{
|
||||
DEFINE_DELTA( entindex, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( bparam1, DT_INTEGER, 1, 1.0 ),
|
||||
DEFINE_DELTA( bparam2, DT_INTEGER, 1, 1.0 ),
|
||||
DEFINE_DELTA( origin[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( origin[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( origin[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( fparam1, DT_FLOAT | DT_SIGNED, 20, 100.0 ),
|
||||
DEFINE_DELTA( fparam2, DT_FLOAT | DT_SIGNED, 20, 100.0 ),
|
||||
DEFINE_DELTA( iparam1, DT_INTEGER | DT_SIGNED, 16, 1.0 ),
|
||||
DEFINE_DELTA( iparam2, DT_INTEGER | DT_SIGNED, 16, 1.0 ),
|
||||
DEFINE_DELTA( angles[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( angles[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( angles[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( ducking, DT_INTEGER, 1, 1.0 )
|
||||
}
|
141
cl_dll/MOTD.cpp
141
cl_dll/MOTD.cpp
@ -1,141 +0,0 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
//
|
||||
// MOTD.cpp
|
||||
//
|
||||
// for displaying a server-sent message of the day
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "parsemsg.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
DECLARE_MESSAGE( m_MOTD, MOTD );
|
||||
|
||||
int CHudMOTD::MOTD_DISPLAY_TIME;
|
||||
|
||||
int CHudMOTD :: Init( void )
|
||||
{
|
||||
gHUD.AddHudElem( this );
|
||||
|
||||
HOOK_MESSAGE( MOTD );
|
||||
|
||||
CVAR_CREATE( "motd_display_time", "6", 0 );
|
||||
|
||||
m_iFlags &= ~HUD_ACTIVE; // start out inactive
|
||||
m_szMOTD[0] = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CHudMOTD :: VidInit( void )
|
||||
{
|
||||
// Load sprites here
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CHudMOTD :: Reset( void )
|
||||
{
|
||||
m_iFlags &= ~HUD_ACTIVE; // start out inactive
|
||||
m_szMOTD[0] = 0;
|
||||
m_iLines = 0;
|
||||
m_flActiveTill = 0;
|
||||
}
|
||||
|
||||
#define LINE_HEIGHT 13
|
||||
|
||||
int CHudMOTD :: Draw( float fTime )
|
||||
{
|
||||
// Draw MOTD line-by-line
|
||||
|
||||
if ( m_flActiveTill < gHUD.m_flTime )
|
||||
{ // finished with MOTD, disable it
|
||||
m_szMOTD[0] = 0;
|
||||
m_iLines = 0;
|
||||
m_iFlags &= ~HUD_ACTIVE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// cap activetill time to the display time
|
||||
m_flActiveTill = min( gHUD.m_flTime + MOTD_DISPLAY_TIME, m_flActiveTill );
|
||||
|
||||
// find the top of where the MOTD should be drawn, so the whole thing is centered in the screen
|
||||
int ypos = max(((ScreenHeight - (m_iLines * LINE_HEIGHT)) / 2) - 40, 30 ); // shift it up slightly
|
||||
char *ch = m_szMOTD;
|
||||
while ( *ch )
|
||||
{
|
||||
int line_length = 0; // count the length of the current line
|
||||
for ( char *next_line = ch; *next_line != '\n' && *next_line != 0; next_line++ )
|
||||
line_length += gHUD.m_scrinfo.charWidths[ *next_line ];
|
||||
char *top = next_line;
|
||||
if ( *top == '\n' )
|
||||
*top = 0;
|
||||
else
|
||||
top = NULL;
|
||||
|
||||
// find where to start drawing the line
|
||||
int xpos = (ScreenWidth - line_length) / 2;
|
||||
|
||||
gHUD.DrawHudString( xpos, ypos, ScreenWidth, ch, 255, 180, 0 );
|
||||
|
||||
ypos += LINE_HEIGHT;
|
||||
|
||||
if ( top ) // restore
|
||||
*top = '\n';
|
||||
ch = next_line;
|
||||
if ( *ch == '\n' )
|
||||
ch++;
|
||||
|
||||
if ( ypos > (ScreenHeight - 20) )
|
||||
break; // don't let it draw too low
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CHudMOTD :: MsgFunc_MOTD( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
if ( m_iFlags & HUD_ACTIVE )
|
||||
{
|
||||
Reset(); // clear the current MOTD in prep for this one
|
||||
}
|
||||
|
||||
BEGIN_READ( pbuf, iSize );
|
||||
|
||||
int is_finished = READ_BYTE();
|
||||
strcat( m_szMOTD, READ_STRING() );
|
||||
|
||||
if ( is_finished )
|
||||
{
|
||||
m_iFlags |= HUD_ACTIVE;
|
||||
|
||||
MOTD_DISPLAY_TIME = CVAR_GET_FLOAT( "motd_display_time" );
|
||||
|
||||
m_flActiveTill = gHUD.m_flTime + MOTD_DISPLAY_TIME;
|
||||
|
||||
for ( char *sz = m_szMOTD; *sz != 0; sz++ ) // count the number of lines in the MOTD
|
||||
{
|
||||
if ( *sz == '\n' )
|
||||
m_iLines++;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -19,13 +19,14 @@
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include "parsemsg.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ammohistory.h"
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
|
||||
WEAPON *gpActiveSel; // NULL means off, 1 means just the menu bar, otherwise
|
||||
// this points to the active weapon menu item
|
||||
@ -35,6 +36,8 @@ client_sprite_t *GetSpriteList(client_sprite_t *pList, const char *psz, int iRes
|
||||
|
||||
WeaponsResource gWR;
|
||||
|
||||
int g_weaponselect = 0;
|
||||
|
||||
void WeaponsResource :: LoadAllWeaponSprites( void )
|
||||
{
|
||||
for (int i = 0; i < MAX_WEAPONS; i++)
|
||||
@ -372,7 +375,10 @@ void CHudAmmo::Think(void)
|
||||
if (gHUD.m_iKeyBits & IN_ATTACK)
|
||||
{
|
||||
if (gpActiveSel != (WEAPON *)1)
|
||||
{
|
||||
ServerCmd(gpActiveSel->szName);
|
||||
g_weaponselect = gpActiveSel->iId;
|
||||
}
|
||||
|
||||
gpLastSel = gpActiveSel;
|
||||
gpActiveSel = NULL;
|
||||
@ -430,13 +436,14 @@ void WeaponsResource :: SelectSlot( int iSlot, int fAdvance, int iDirection )
|
||||
return;
|
||||
|
||||
WEAPON *p = NULL;
|
||||
bool fastSwitch = CVAR_GET_FLOAT( "hud_fastswitch" ) != 0;
|
||||
|
||||
if ( (gpActiveSel == NULL) || (gpActiveSel == (WEAPON *)1) || (iSlot != gpActiveSel->iSlot) )
|
||||
{
|
||||
PlaySound( "common/wpn_hudon.wav", 1 );
|
||||
p = GetFirstPos( iSlot );
|
||||
|
||||
if ( p && CVAR_GET_FLOAT( "hud_fastswitch" ) > 0 ) // check for fast weapon switch mode
|
||||
if ( p && fastSwitch ) // check for fast weapon switch mode
|
||||
{
|
||||
// if fast weapon switch is on, then weapons can be selected in a single keypress
|
||||
// but only if there is only one item in the bucket
|
||||
@ -444,6 +451,7 @@ void WeaponsResource :: SelectSlot( int iSlot, int fAdvance, int iDirection )
|
||||
if ( !p2 )
|
||||
{ // only one active item in bucket, so change directly to weapon
|
||||
ServerCmd( p->szName );
|
||||
g_weaponselect = p->iId;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -458,13 +466,18 @@ void WeaponsResource :: SelectSlot( int iSlot, int fAdvance, int iDirection )
|
||||
}
|
||||
|
||||
|
||||
if ( !p ) // if no selection found, just display the weapon list
|
||||
gpActiveSel = (WEAPON *)1;
|
||||
if ( !p ) // no selection found
|
||||
{
|
||||
// just display the weapon list, unless fastswitch is on just ignore it
|
||||
if ( !fastSwitch )
|
||||
gpActiveSel = (WEAPON *)1;
|
||||
else
|
||||
gpActiveSel = NULL;
|
||||
}
|
||||
else
|
||||
gpActiveSel = p;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Message Handlers
|
||||
//------------------------------------------------------------------------
|
||||
@ -653,55 +666,64 @@ int CHudAmmo::MsgFunc_WeaponList(const char *pszName, int iSize, void *pbuf )
|
||||
//------------------------------------------------------------------------
|
||||
// Command Handlers
|
||||
//------------------------------------------------------------------------
|
||||
// Slot button pressed
|
||||
void CHudAmmo::SlotInput( int iSlot )
|
||||
{
|
||||
// Let the Viewport use it first, for menus
|
||||
if ( gViewPort && gViewPort->SlotInput( iSlot ) )
|
||||
return;
|
||||
|
||||
gWR.SelectSlot(iSlot, FALSE, 1);
|
||||
}
|
||||
|
||||
void CHudAmmo::UserCmd_Slot1(void)
|
||||
{
|
||||
gWR.SelectSlot(0, FALSE, 1);
|
||||
SlotInput( 0 );
|
||||
}
|
||||
|
||||
void CHudAmmo::UserCmd_Slot2(void)
|
||||
{
|
||||
gWR.SelectSlot(1, FALSE, 1);
|
||||
SlotInput( 1 );
|
||||
}
|
||||
|
||||
void CHudAmmo::UserCmd_Slot3(void)
|
||||
{
|
||||
gWR.SelectSlot(2, FALSE, 1);
|
||||
SlotInput( 2 );
|
||||
}
|
||||
|
||||
void CHudAmmo::UserCmd_Slot4(void)
|
||||
{
|
||||
gWR.SelectSlot(3, FALSE, 1);
|
||||
SlotInput( 3 );
|
||||
}
|
||||
|
||||
void CHudAmmo::UserCmd_Slot5(void)
|
||||
{
|
||||
gWR.SelectSlot(4, FALSE, 1);
|
||||
SlotInput( 4 );
|
||||
}
|
||||
|
||||
void CHudAmmo::UserCmd_Slot6(void)
|
||||
{
|
||||
gWR.SelectSlot(5, FALSE, 1);
|
||||
SlotInput( 5 );
|
||||
}
|
||||
|
||||
void CHudAmmo::UserCmd_Slot7(void)
|
||||
{
|
||||
gWR.SelectSlot(6, FALSE, 1);
|
||||
SlotInput( 6 );
|
||||
}
|
||||
|
||||
void CHudAmmo::UserCmd_Slot8(void)
|
||||
{
|
||||
gWR.SelectSlot(7, FALSE, 1);
|
||||
SlotInput( 7 );
|
||||
}
|
||||
|
||||
void CHudAmmo::UserCmd_Slot9(void)
|
||||
{
|
||||
gWR.SelectSlot(8, FALSE, 1);
|
||||
SlotInput( 8 );
|
||||
}
|
||||
|
||||
void CHudAmmo::UserCmd_Slot10(void)
|
||||
{
|
||||
gWR.SelectSlot(9, FALSE, 1);
|
||||
SlotInput( 9 );
|
||||
}
|
||||
|
||||
void CHudAmmo::UserCmd_Close(void)
|
||||
|
@ -19,7 +19,7 @@
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "parsemsg.h"
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include "parsemsg.h"
|
||||
|
||||
#include <string.h>
|
||||
|
@ -90,7 +90,6 @@ public:
|
||||
int CountAmmo( int iId );
|
||||
|
||||
HSPRITE* GetAmmoPicFromWeapon( int iAmmoId, wrect_t& rect );
|
||||
|
||||
};
|
||||
|
||||
extern WeaponsResource gWR;
|
||||
|
@ -19,7 +19,7 @@
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include "parsemsg.h"
|
||||
|
||||
#include <string.h>
|
||||
|
17
cl_dll/camera.h
Normal file
17
cl_dll/camera.h
Normal file
@ -0,0 +1,17 @@
|
||||
// Camera.h -- defines and such for a 3rd person camera
|
||||
// NOTE: must include quakedef.h first
|
||||
|
||||
#ifndef _CAMERA_H_
|
||||
#define _CAMEA_H_
|
||||
|
||||
// pitch, yaw, dist
|
||||
extern vec3_t cam_ofs;
|
||||
// Using third person camera
|
||||
extern int cam_thirdperson;
|
||||
|
||||
void CAM_Init( void );
|
||||
void CAM_ClearStates( void );
|
||||
void CAM_StartMouseMove(void);
|
||||
void CAM_EndMouseMove(void);
|
||||
|
||||
#endif // _CAMERA_H_
|
@ -19,14 +19,28 @@
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include "netadr.h"
|
||||
#include "vgui_schememanager.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "pm_shared.h"
|
||||
}
|
||||
|
||||
#include <string.h>
|
||||
#include "hud_servers.h"
|
||||
#include "vgui_int.h"
|
||||
|
||||
#define DLLEXPORT __declspec( dllexport )
|
||||
|
||||
cl_enginefunc_t gEngfuncs;
|
||||
CHud gHUD;
|
||||
TeamFortressViewport *gViewPort = NULL;
|
||||
|
||||
void InitInput (void);
|
||||
void EV_HookEvents( void );
|
||||
void IN_Commands( void );
|
||||
|
||||
/*
|
||||
==========================
|
||||
@ -43,8 +57,83 @@ int DLLEXPORT HUD_Init( void );
|
||||
int DLLEXPORT HUD_Redraw( float flTime, int intermission );
|
||||
int DLLEXPORT HUD_UpdateClientData( client_data_t *cdata, float flTime );
|
||||
int DLLEXPORT HUD_Reset ( void );
|
||||
void DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server );
|
||||
void DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove );
|
||||
char DLLEXPORT HUD_PlayerMoveTexture( char *name );
|
||||
int DLLEXPORT HUD_ConnectionlessPacket( struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size );
|
||||
int DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs );
|
||||
void DLLEXPORT HUD_Frame( double time );
|
||||
}
|
||||
|
||||
/*
|
||||
================================
|
||||
HUD_GetHullBounds
|
||||
|
||||
Engine calls this to enumerate player collision hulls, for prediction. Return 0 if the hullnumber doesn't exist.
|
||||
================================
|
||||
*/
|
||||
int DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs )
|
||||
{
|
||||
int iret = 0;
|
||||
|
||||
switch ( hullnumber )
|
||||
{
|
||||
case 0: // Normal player
|
||||
mins = Vector(-16, -16, -36);
|
||||
maxs = Vector(16, 16, 36);
|
||||
iret = 1;
|
||||
break;
|
||||
case 1: // Crouched player
|
||||
mins = Vector(-16, -16, -18 );
|
||||
maxs = Vector(16, 16, 18 );
|
||||
iret = 1;
|
||||
break;
|
||||
case 2: // Point based hull
|
||||
mins = Vector( 0, 0, 0 );
|
||||
maxs = Vector( 0, 0, 0 );
|
||||
iret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return iret;
|
||||
}
|
||||
|
||||
/*
|
||||
================================
|
||||
HUD_ConnectionlessPacket
|
||||
|
||||
Return 1 if the packet is valid. Set response_buffer_size if you want to send a response packet. Incoming, it holds the max
|
||||
size of the response_buffer, so you must zero it out if you choose not to respond.
|
||||
================================
|
||||
*/
|
||||
int DLLEXPORT HUD_ConnectionlessPacket( struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size )
|
||||
{
|
||||
// Parse stuff from args
|
||||
int max_buffer_size = *response_buffer_size;
|
||||
|
||||
// Zero it out since we aren't going to respond.
|
||||
// If we wanted to response, we'd write data into response_buffer
|
||||
*response_buffer_size = 0;
|
||||
|
||||
// Since we don't listen for anything here, just respond that it's a bogus message
|
||||
// If we didn't reject the message, we'd return 1 for success instead.
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove )
|
||||
{
|
||||
PM_Init( ppmove );
|
||||
}
|
||||
|
||||
char DLLEXPORT HUD_PlayerMoveTexture( char *name )
|
||||
{
|
||||
return PM_FindTextureType( name );
|
||||
}
|
||||
|
||||
void DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server )
|
||||
{
|
||||
PM_Move( ppmove, server );
|
||||
}
|
||||
|
||||
int DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion )
|
||||
{
|
||||
@ -59,6 +148,8 @@ int DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion )
|
||||
|
||||
memcpy(&gEngfuncs, pEnginefuncs, sizeof(cl_enginefunc_t));
|
||||
|
||||
EV_HookEvents();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -76,6 +167,9 @@ so the HUD can reinitialize itself.
|
||||
int DLLEXPORT HUD_VidInit( void )
|
||||
{
|
||||
gHUD.VidInit();
|
||||
|
||||
VGui_Startup();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -91,7 +185,9 @@ the hud variables.
|
||||
|
||||
int DLLEXPORT HUD_Init( void )
|
||||
{
|
||||
InitInput();
|
||||
gHUD.Init();
|
||||
Scheme_Init();
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -129,6 +225,8 @@ returns 1 if anything has been changed, 0 otherwise.
|
||||
|
||||
int DLLEXPORT HUD_UpdateClientData(client_data_t *pcldata, float flTime )
|
||||
{
|
||||
IN_Commands();
|
||||
|
||||
return gHUD.UpdateClientData(pcldata, flTime );
|
||||
}
|
||||
|
||||
@ -144,4 +242,17 @@ int DLLEXPORT HUD_Reset( void )
|
||||
{
|
||||
gHUD.VidInit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
==========================
|
||||
HUD_Frame
|
||||
|
||||
Called by engine every frame that client .dll is loaded
|
||||
==========================
|
||||
*/
|
||||
|
||||
void DLLEXPORT HUD_Frame( double time )
|
||||
{
|
||||
ServersThink( time );
|
||||
}
|
@ -40,9 +40,10 @@ RSC=rc.exe
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir ".\Release"
|
||||
# PROP Intermediate_Dir ".\Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\engine" /I "..\common" /I "..\pm_shared" /I "..\utils\vgui\include" /I "..\dlls" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
@ -52,14 +53,14 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib /nologo /subsystem:windows /dll /map /machine:I386 /out:".\Release\client.dll"
|
||||
# Begin Custom Build - Copying to \half-life\mp\cl_dlls
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib winmm.lib ../utils/vgui/lib/win32_vc6/vgui.lib wsock32.lib /nologo /subsystem:windows /dll /map /machine:I386 /out:".\Release\client.dll"
|
||||
# Begin Custom Build - Copying to \quiver\valve\cl_dlls
|
||||
TargetDir=.\Release
|
||||
InputPath=.\Release\client.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"\half-life\mp\cl_dlls\client.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\client.dll \half-life\mp\cl_dlls
|
||||
"\quiver\valve\cl_dlls\client.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\client.dll \quiver\valve\cl_dlls
|
||||
|
||||
# End Custom Build
|
||||
|
||||
@ -74,9 +75,10 @@ SOURCE="$(InputPath)"
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir ".\Debug"
|
||||
# PROP Intermediate_Dir ".\Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
|
||||
# ADD CPP /nologo /G5 /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /c
|
||||
# ADD CPP /nologo /G5 /MTd /W3 /Gm /GX /ZI /Od /I "..\engine" /I "..\common" /I "..\pm_shared" /I "..\utils\vgui\include" /I "..\dlls" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
@ -86,7 +88,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\client.dll"
|
||||
# ADD LINK32 oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib winmm.lib ../utils/vgui/lib/win32_vc6/vgui.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\client.dll"
|
||||
# Begin Custom Build - Copying to \half-life\mp\cl_dlls
|
||||
TargetDir=.\Debug
|
||||
InputPath=.\Debug\client.dll
|
||||
@ -106,6 +108,34 @@ SOURCE="$(InputPath)"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
|
||||
# Begin Group "hl"
|
||||
|
||||
# PROP Default_Filter "*.cpp"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ev_hldm.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hl\hl_baseentity.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hl\hl_events.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hl\hl_objects.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hl\hl_weapons.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\dlls\wpn_shared\hl_wpn_glock.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ammo.cpp
|
||||
@ -128,10 +158,30 @@ SOURCE=.\cdll_int.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\com_weapons.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\death.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\demo.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\entity.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ev_common.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\events.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\flashlight.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -156,10 +206,26 @@ SOURCE=.\hud_redraw.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hud_servers.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hud_update.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\in_camera.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\input.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\inputw32.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\menu.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -168,10 +234,6 @@ SOURCE=.\message.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MOTD.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\parsemsg.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -180,11 +242,19 @@ SOURCE=.\parsemsg.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\saytext.cpp
|
||||
SOURCE=..\pm_shared\pm_debug.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\scoreboard.cpp
|
||||
SOURCE=..\pm_shared\pm_math.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\pm_shared\pm_shared.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\saytext.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@ -204,8 +274,60 @@ SOURCE=.\train.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tri.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_ClassMenu.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_ConsolePanel.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_ControlConfigPanel.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_CustomObjects.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_int.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_MOTDWindow.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_SchemeManager.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_ScorePanel.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_ServerBrowser.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_TeamFortressViewport.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_teammenu.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\view.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
@ -220,10 +342,30 @@ SOURCE=.\ammohistory.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\camera.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cl_dll.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\com_weapons.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\demo.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ev_hldm.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\eventscripts.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\health.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -232,12 +374,92 @@ SOURCE=.\hud.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hud_iface.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hud_servers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\hud_servers_priv.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\in_defs.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\kbutton.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\pm_shared\pm_debug.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\pm_shared\pm_defs.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\pm_shared\pm_info.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\pm_shared\pm_materials.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\pm_shared\pm_movevars.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\pm_shared\pm_shared.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util_vector.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_ConsolePanel.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_ControlConfigPanel.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_int.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_SchemeManager.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_ScorePanel.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_ServerBrowser.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vgui_TeamFortressViewport.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\view.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\wrect.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
|
@ -8,7 +8,7 @@ Project: "cl_dll"=.\cl_dll.dsp - Package Owner=<4>
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
"$/GoldSrc/cl_dll", HGEBAAAA
|
||||
"$/HLStandardSDK/SourceCode/cl_dll", NUWHAAAA
|
||||
.
|
||||
end source code control
|
||||
}}}
|
||||
@ -23,10 +23,6 @@ Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
"$/GoldSrc/cl_dll", HGEBAAAA
|
||||
.
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
|
@ -13,12 +13,15 @@
|
||||
*
|
||||
****/
|
||||
//
|
||||
// util.h
|
||||
// cl_util.h
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include "cvardef.h"
|
||||
|
||||
#include "../engine/cvardef.h"
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
// Macros to hook function calls into the HUD object
|
||||
#define HOOK_MESSAGE(x) gEngfuncs.pfnHookUserMsg(#x, __MsgFunc_##x );
|
||||
@ -37,7 +40,7 @@
|
||||
|
||||
inline float CVAR_GET_FLOAT( const char *x ) { return gEngfuncs.pfnGetCvarFloat( (char*)x ); }
|
||||
inline char* CVAR_GET_STRING( const char *x ) { return gEngfuncs.pfnGetCvarString( (char*)x ); }
|
||||
inline void CVAR_CREATE( const char *cv, const char *val, const int flags ) { gEngfuncs.pfnRegisterVariable( (char*)cv, (char*)val, flags ); }
|
||||
inline struct cvar_s *CVAR_CREATE( const char *cv, const char *val, const int flags ) { return gEngfuncs.pfnRegisterVariable( (char*)cv, (char*)val, flags ); }
|
||||
|
||||
#define SPR_Load (*gEngfuncs.pfnSPR_Load)
|
||||
#define SPR_Set (*gEngfuncs.pfnSPR_Set)
|
||||
@ -125,6 +128,14 @@ void ScaleColors( int &r, int &g, int &b, int a );
|
||||
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
|
||||
#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}
|
||||
#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}
|
||||
#define VectorClear(a) { a[0]=0.0;a[1]=0.0;a[2]=0.0;}
|
||||
float Length(const float *v);
|
||||
void VectorMA (const float *veca, float scale, const float *vecb, float *vecc);
|
||||
void VectorScale (const float *in, float scale, float *out);
|
||||
float VectorNormalize (float *v);
|
||||
void VectorInverse ( float *v );
|
||||
|
||||
extern vec3_t vec3_origin;
|
||||
|
||||
// disable 'possible loss of data converting float to int' warning message
|
||||
#pragma warning( disable: 4244 )
|
277
cl_dll/com_weapons.cpp
Normal file
277
cl_dll/com_weapons.cpp
Normal file
@ -0,0 +1,277 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
|
||||
// Com_Weapons.cpp
|
||||
// Shared weapons common/shared functions
|
||||
#include <stdarg.h>
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "com_weapons.h"
|
||||
|
||||
#include "const.h"
|
||||
#include "entity_state.h"
|
||||
#include "r_efx.h"
|
||||
|
||||
// g_runfuncs is true if this is the first time we've "predicated" a particular movement/firing
|
||||
// command. If it is 1, then we should play events/sounds etc., otherwise, we just will be
|
||||
// updating state info, but not firing events
|
||||
int g_runfuncs = 0;
|
||||
|
||||
// During our weapon prediction processing, we'll need to reference some data that is part of
|
||||
// the final state passed into the postthink functionality. We'll set this pointer and then
|
||||
// reset it to NULL as appropriate
|
||||
struct local_state_s *g_finalstate = NULL;
|
||||
|
||||
/*
|
||||
====================
|
||||
COM_Log
|
||||
|
||||
Log debug messages to file ( appends )
|
||||
====================
|
||||
*/
|
||||
void COM_Log( char *pszFile, char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
FILE *fp;
|
||||
char *pfilename;
|
||||
|
||||
if ( !pszFile )
|
||||
{
|
||||
pfilename = "c:\\hllog.txt";
|
||||
}
|
||||
else
|
||||
{
|
||||
pfilename = pszFile;
|
||||
}
|
||||
|
||||
va_start (argptr,fmt);
|
||||
vsprintf (string, fmt,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
fp = fopen( pfilename, "a+t");
|
||||
if (fp)
|
||||
{
|
||||
fprintf(fp, "%s", string);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
// remember the current animation for the view model, in case we get out of sync with
|
||||
// server.
|
||||
static int g_currentanim;
|
||||
|
||||
/*
|
||||
=====================
|
||||
HUD_SendWeaponAnim
|
||||
|
||||
Change weapon model animation
|
||||
=====================
|
||||
*/
|
||||
void HUD_SendWeaponAnim( int iAnim, int body, int force )
|
||||
{
|
||||
// Don't actually change it.
|
||||
if ( !g_runfuncs && !force )
|
||||
return;
|
||||
|
||||
g_currentanim = iAnim;
|
||||
|
||||
// Tell animation system new info
|
||||
gEngfuncs.pfnWeaponAnim( iAnim, body );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
HUD_GetWeaponAnim
|
||||
|
||||
Retrieve current predicted weapon animation
|
||||
=====================
|
||||
*/
|
||||
int HUD_GetWeaponAnim( void )
|
||||
{
|
||||
return g_currentanim;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
HUD_PlaySound
|
||||
|
||||
Play a sound, if we are seeing this command for the first time
|
||||
=====================
|
||||
*/
|
||||
void HUD_PlaySound( char *sound, float volume )
|
||||
{
|
||||
if ( !g_runfuncs || !g_finalstate )
|
||||
return;
|
||||
|
||||
gEngfuncs.pfnPlaySoundByNameAtLocation( sound, volume, (float *)&g_finalstate->playerstate.origin );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
HUD_PlaybackEvent
|
||||
|
||||
Directly queue up an event on the client
|
||||
=====================
|
||||
*/
|
||||
void HUD_PlaybackEvent( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay,
|
||||
float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 )
|
||||
{
|
||||
vec3_t org;
|
||||
vec3_t ang;
|
||||
|
||||
if ( !g_runfuncs || !g_finalstate )
|
||||
return;
|
||||
|
||||
// Weapon prediction events are assumed to occur at the player's origin
|
||||
org = g_finalstate->playerstate.origin;
|
||||
ang = v_angles;
|
||||
gEngfuncs.pfnPlaybackEvent( flags, pInvoker, eventindex, delay, (float *)&org, (float *)&ang, fparam1, fparam2, iparam1, iparam2, bparam1, bparam2 );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
HUD_SetMaxSpeed
|
||||
|
||||
=====================
|
||||
*/
|
||||
void HUD_SetMaxSpeed( const edict_t *ed, float speed )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
UTIL_WeaponTimeBase
|
||||
|
||||
Always 0.0 on client, even if not predicting weapons ( won't get called
|
||||
in that case )
|
||||
=====================
|
||||
*/
|
||||
float UTIL_WeaponTimeBase( void )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static unsigned int glSeed = 0;
|
||||
|
||||
unsigned int seed_table[ 256 ] =
|
||||
{
|
||||
28985, 27138, 26457, 9451, 17764, 10909, 28790, 8716, 6361, 4853, 17798, 21977, 19643, 20662, 10834, 20103,
|
||||
27067, 28634, 18623, 25849, 8576, 26234, 23887, 18228, 32587, 4836, 3306, 1811, 3035, 24559, 18399, 315,
|
||||
26766, 907, 24102, 12370, 9674, 2972, 10472, 16492, 22683, 11529, 27968, 30406, 13213, 2319, 23620, 16823,
|
||||
10013, 23772, 21567, 1251, 19579, 20313, 18241, 30130, 8402, 20807, 27354, 7169, 21211, 17293, 5410, 19223,
|
||||
10255, 22480, 27388, 9946, 15628, 24389, 17308, 2370, 9530, 31683, 25927, 23567, 11694, 26397, 32602, 15031,
|
||||
18255, 17582, 1422, 28835, 23607, 12597, 20602, 10138, 5212, 1252, 10074, 23166, 19823, 31667, 5902, 24630,
|
||||
18948, 14330, 14950, 8939, 23540, 21311, 22428, 22391, 3583, 29004, 30498, 18714, 4278, 2437, 22430, 3439,
|
||||
28313, 23161, 25396, 13471, 19324, 15287, 2563, 18901, 13103, 16867, 9714, 14322, 15197, 26889, 19372, 26241,
|
||||
31925, 14640, 11497, 8941, 10056, 6451, 28656, 10737, 13874, 17356, 8281, 25937, 1661, 4850, 7448, 12744,
|
||||
21826, 5477, 10167, 16705, 26897, 8839, 30947, 27978, 27283, 24685, 32298, 3525, 12398, 28726, 9475, 10208,
|
||||
617, 13467, 22287, 2376, 6097, 26312, 2974, 9114, 21787, 28010, 4725, 15387, 3274, 10762, 31695, 17320,
|
||||
18324, 12441, 16801, 27376, 22464, 7500, 5666, 18144, 15314, 31914, 31627, 6495, 5226, 31203, 2331, 4668,
|
||||
12650, 18275, 351, 7268, 31319, 30119, 7600, 2905, 13826, 11343, 13053, 15583, 30055, 31093, 5067, 761,
|
||||
9685, 11070, 21369, 27155, 3663, 26542, 20169, 12161, 15411, 30401, 7580, 31784, 8985, 29367, 20989, 14203,
|
||||
29694, 21167, 10337, 1706, 28578, 887, 3373, 19477, 14382, 675, 7033, 15111, 26138, 12252, 30996, 21409,
|
||||
25678, 18555, 13256, 23316, 22407, 16727, 991, 9236, 5373, 29402, 6117, 15241, 27715, 19291, 19888, 19847
|
||||
};
|
||||
|
||||
unsigned int U_Random( void )
|
||||
{
|
||||
glSeed *= 69069;
|
||||
glSeed += seed_table[ glSeed & 0xff ];
|
||||
|
||||
return ( ++glSeed & 0x0fffffff );
|
||||
}
|
||||
|
||||
void U_Srand( unsigned int seed )
|
||||
{
|
||||
glSeed = seed_table[ seed & 0xff ];
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
UTIL_SharedRandomLong
|
||||
=====================
|
||||
*/
|
||||
int UTIL_SharedRandomLong( unsigned int seed, int low, int high )
|
||||
{
|
||||
unsigned int range;
|
||||
|
||||
U_Srand( (int)seed + low + high );
|
||||
|
||||
range = high - low + 1;
|
||||
if ( !(range - 1) )
|
||||
{
|
||||
return low;
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset;
|
||||
int rnum;
|
||||
|
||||
rnum = U_Random();
|
||||
|
||||
offset = rnum % range;
|
||||
|
||||
return (low + offset);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
UTIL_SharedRandomFloat
|
||||
=====================
|
||||
*/
|
||||
float UTIL_SharedRandomFloat( unsigned int seed, float low, float high )
|
||||
{
|
||||
//
|
||||
unsigned int range;
|
||||
|
||||
U_Srand( (int)seed + *(int *)&low + *(int *)&high );
|
||||
|
||||
U_Random();
|
||||
U_Random();
|
||||
|
||||
range = high - low;
|
||||
if ( !range )
|
||||
{
|
||||
return low;
|
||||
}
|
||||
else
|
||||
{
|
||||
int tensixrand;
|
||||
float offset;
|
||||
|
||||
tensixrand = U_Random() & 65535;
|
||||
|
||||
offset = (float)tensixrand / 65536.0;
|
||||
|
||||
return (low + offset * range );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
stub_*
|
||||
|
||||
stub functions for such things as precaching. So we don't have to modify weapons code that
|
||||
is compiled into both game and client .dlls.
|
||||
======================
|
||||
*/
|
||||
int stub_PrecacheModel ( char* s ) { return 0; }
|
||||
int stub_PrecacheSound ( char* s ) { return 0; }
|
||||
unsigned short stub_PrecacheEvent ( int type, const char *s ) { return 0; }
|
||||
const char *stub_NameForFunction ( unsigned long function ) { return "func"; }
|
||||
void stub_SetModel ( edict_t *e, const char *m ) {}
|
41
cl_dll/com_weapons.h
Normal file
41
cl_dll/com_weapons.h
Normal file
@ -0,0 +1,41 @@
|
||||
// com_weapons.h
|
||||
// Shared weapons common function prototypes
|
||||
#if !defined( COM_WEAPONSH )
|
||||
#define COM_WEAPONSH
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "hud_iface.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void _DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed );
|
||||
}
|
||||
|
||||
void COM_Log( char *pszFile, char *fmt, ...);
|
||||
int CL_IsDead( void );
|
||||
|
||||
float UTIL_SharedRandomFloat( unsigned int seed, float low, float high );
|
||||
int UTIL_SharedRandomLong( unsigned int seed, int low, int high );
|
||||
|
||||
int HUD_GetWeaponAnim( void );
|
||||
void HUD_SendWeaponAnim( int iAnim, int body, int force );
|
||||
void HUD_PlaySound( char *sound, float volume );
|
||||
void HUD_PlaybackEvent( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 );
|
||||
void HUD_SetMaxSpeed( const struct edict_s *ed, float speed );
|
||||
int stub_PrecacheModel( char* s );
|
||||
int stub_PrecacheSound( char* s );
|
||||
unsigned short stub_PrecacheEvent( int type, const char *s );
|
||||
const char *stub_NameForFunction ( unsigned long function );
|
||||
void stub_SetModel ( struct edict_s *e, const char *m );
|
||||
|
||||
|
||||
extern cvar_t *cl_lw;
|
||||
|
||||
extern int g_runfuncs;
|
||||
extern vec3_t v_angles;
|
||||
extern float g_lastFOV;
|
||||
extern struct local_state_s *g_finalstate;
|
||||
|
||||
#endif
|
221
cl_dll/death.cpp
221
cl_dll/death.cpp
@ -16,22 +16,26 @@
|
||||
// death notice
|
||||
//
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include "parsemsg.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
|
||||
DECLARE_MESSAGE( m_DeathNotice, DeathMsg );
|
||||
|
||||
struct DeathNoticeItem {
|
||||
char szKiller[MAX_PLAYER_NAME_LENGTH];
|
||||
char szVictim[MAX_PLAYER_NAME_LENGTH];
|
||||
char szKiller[MAX_PLAYER_NAME_LENGTH*2];
|
||||
char szVictim[MAX_PLAYER_NAME_LENGTH*2];
|
||||
int iId; // the index number of the associated sprite
|
||||
int iSuicide;
|
||||
int iTeamKill;
|
||||
int iNonPlayerKill;
|
||||
float flDisplayTime;
|
||||
float *KillerColor;
|
||||
float *VictimColor;
|
||||
};
|
||||
|
||||
#define MAX_DEATHNOTICES 4
|
||||
@ -41,6 +45,23 @@ static int DEATHNOTICE_DISPLAY_TIME = 6;
|
||||
|
||||
DeathNoticeItem rgDeathNoticeList[ MAX_DEATHNOTICES + 1 ];
|
||||
|
||||
float g_ColorBlue[3] = { 0.6, 0.8, 1.0 };
|
||||
float g_ColorRed[3] = { 1.0, 0.25, 0.25 };
|
||||
float g_ColorGreen[3] = { 0.6, 1.0, 0.6 };
|
||||
float g_ColorYellow[3] = { 1.0, 0.7, 0.0 };
|
||||
|
||||
float *GetClientColor( int clientIndex )
|
||||
{
|
||||
switch ( g_PlayerExtraInfo[clientIndex].teamnumber )
|
||||
{
|
||||
case 1: return g_ColorBlue;
|
||||
case 2: return g_ColorRed;
|
||||
case 3: return g_ColorYellow;
|
||||
case 4: return g_ColorGreen;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int CHudDeathNotice :: Init( void )
|
||||
{
|
||||
@ -86,35 +107,45 @@ int CHudDeathNotice :: Draw( float flTime )
|
||||
|
||||
rgDeathNoticeList[i].flDisplayTime = min( rgDeathNoticeList[i].flDisplayTime, gHUD.m_flTime + DEATHNOTICE_DISPLAY_TIME );
|
||||
|
||||
// Draw the death notice
|
||||
|
||||
y = DEATHNOTICE_TOP + (20 * i); //!!!
|
||||
|
||||
int id = (rgDeathNoticeList[i].iId == -1) ? m_HUD_d_skull : rgDeathNoticeList[i].iId;
|
||||
x = ScreenWidth - ConsoleStringLen(rgDeathNoticeList[i].szVictim) - (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left);
|
||||
|
||||
if ( !rgDeathNoticeList[i].iSuicide )
|
||||
// Only draw if the viewport will let me
|
||||
if ( gViewPort && gViewPort->AllowedToPrintText() )
|
||||
{
|
||||
x -= (5 + ConsoleStringLen( rgDeathNoticeList[i].szKiller ) );
|
||||
// Draw the death notice
|
||||
y = DEATHNOTICE_TOP + (20 * i); //!!!
|
||||
|
||||
// Draw killers name
|
||||
x = 5 + DrawConsoleString( x, y, rgDeathNoticeList[i].szKiller );
|
||||
int id = (rgDeathNoticeList[i].iId == -1) ? m_HUD_d_skull : rgDeathNoticeList[i].iId;
|
||||
x = ScreenWidth - ConsoleStringLen(rgDeathNoticeList[i].szVictim) - (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left);
|
||||
|
||||
if ( !rgDeathNoticeList[i].iSuicide )
|
||||
{
|
||||
x -= (5 + ConsoleStringLen( rgDeathNoticeList[i].szKiller ) );
|
||||
|
||||
// Draw killers name
|
||||
if ( rgDeathNoticeList[i].KillerColor )
|
||||
gEngfuncs.pfnDrawSetTextColor( rgDeathNoticeList[i].KillerColor[0], rgDeathNoticeList[i].KillerColor[1], rgDeathNoticeList[i].KillerColor[2] );
|
||||
x = 5 + DrawConsoleString( x, y, rgDeathNoticeList[i].szKiller );
|
||||
}
|
||||
|
||||
r = 255; g = 80; b = 0;
|
||||
if ( rgDeathNoticeList[i].iTeamKill )
|
||||
{
|
||||
r = 10; g = 240; b = 10; // display it in sickly green
|
||||
}
|
||||
|
||||
// Draw death weapon
|
||||
SPR_Set( gHUD.GetSprite(id), r, g, b );
|
||||
SPR_DrawAdditive( 0, x, y, &gHUD.GetSpriteRect(id) );
|
||||
|
||||
x += (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left);
|
||||
|
||||
// Draw victims name (if it was a player that was killed)
|
||||
if (rgDeathNoticeList[i].iNonPlayerKill == FALSE)
|
||||
{
|
||||
if ( rgDeathNoticeList[i].VictimColor )
|
||||
gEngfuncs.pfnDrawSetTextColor( rgDeathNoticeList[i].VictimColor[0], rgDeathNoticeList[i].VictimColor[1], rgDeathNoticeList[i].VictimColor[2] );
|
||||
x = DrawConsoleString( x, y, rgDeathNoticeList[i].szVictim );
|
||||
}
|
||||
}
|
||||
|
||||
r = 255; g = 80; b = 0;
|
||||
if ( rgDeathNoticeList[i].iTeamKill )
|
||||
{
|
||||
r = 10; g = 240; b = 10; // display it in sickly green
|
||||
}
|
||||
|
||||
// Draw death weapon
|
||||
SPR_Set( gHUD.GetSprite(id), r, g, b );
|
||||
SPR_DrawAdditive( 0, x, y, &gHUD.GetSpriteRect(id) );
|
||||
|
||||
x += (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left);
|
||||
|
||||
// Draw victims name
|
||||
x = DrawConsoleString( x, y, rgDeathNoticeList[i].szVictim );
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -134,7 +165,8 @@ int CHudDeathNotice :: MsgFunc_DeathMsg( const char *pszName, int iSize, void *p
|
||||
strcpy( killedwith, "d_" );
|
||||
strncat( killedwith, READ_STRING(), 32 );
|
||||
|
||||
gHUD.m_Scoreboard.DeathMsg( killer, victim );
|
||||
if (gViewPort)
|
||||
gViewPort->DeathMsg( killer, victim );
|
||||
|
||||
for ( int i = 0; i < MAX_DEATHNOTICES; i++ )
|
||||
{
|
||||
@ -147,23 +179,56 @@ int CHudDeathNotice :: MsgFunc_DeathMsg( const char *pszName, int iSize, void *p
|
||||
i = MAX_DEATHNOTICES - 1;
|
||||
}
|
||||
|
||||
gHUD.m_Scoreboard.GetAllPlayersInfo();
|
||||
if (gViewPort)
|
||||
gViewPort->GetAllPlayersInfo();
|
||||
|
||||
char *killer_name = gHUD.m_Scoreboard.m_PlayerInfoList[ killer ].name;
|
||||
char *victim_name = gHUD.m_Scoreboard.m_PlayerInfoList[ victim ].name;
|
||||
// Get the Killer's name
|
||||
char *killer_name = g_PlayerInfoList[ killer ].name;
|
||||
if ( !killer_name )
|
||||
{
|
||||
killer_name = "";
|
||||
rgDeathNoticeList[i].szKiller[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rgDeathNoticeList[i].KillerColor = GetClientColor( killer );
|
||||
strncpy( rgDeathNoticeList[i].szKiller, killer_name, MAX_PLAYER_NAME_LENGTH );
|
||||
rgDeathNoticeList[i].szKiller[MAX_PLAYER_NAME_LENGTH-1] = 0;
|
||||
}
|
||||
|
||||
// Get the Victim's name
|
||||
char *victim_name = NULL;
|
||||
// If victim is -1, the killer killed a specific, non-player object (like a sentrygun)
|
||||
if ( ((char)victim) != -1 )
|
||||
victim_name = g_PlayerInfoList[ victim ].name;
|
||||
if ( !victim_name )
|
||||
{
|
||||
victim_name = "";
|
||||
rgDeathNoticeList[i].szVictim[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rgDeathNoticeList[i].VictimColor = GetClientColor( victim );
|
||||
strncpy( rgDeathNoticeList[i].szVictim, victim_name, MAX_PLAYER_NAME_LENGTH );
|
||||
rgDeathNoticeList[i].szVictim[MAX_PLAYER_NAME_LENGTH-1] = 0;
|
||||
}
|
||||
|
||||
strncpy( rgDeathNoticeList[i].szKiller, killer_name, MAX_PLAYER_NAME_LENGTH );
|
||||
strncpy( rgDeathNoticeList[i].szVictim, victim_name, MAX_PLAYER_NAME_LENGTH );
|
||||
// Is it a non-player object kill?
|
||||
if ( ((char)victim) == -1 )
|
||||
{
|
||||
rgDeathNoticeList[i].iNonPlayerKill = TRUE;
|
||||
|
||||
if ( killer == victim || killer == 0 )
|
||||
rgDeathNoticeList[i].iSuicide = TRUE;
|
||||
// Store the object's name in the Victim slot (skip the d_ bit)
|
||||
strcpy( rgDeathNoticeList[i].szVictim, killedwith+2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( killer == victim || killer == 0 )
|
||||
rgDeathNoticeList[i].iSuicide = TRUE;
|
||||
|
||||
if ( !strcmp( killedwith, "d_teammate" ) )
|
||||
rgDeathNoticeList[i].iTeamKill = TRUE;
|
||||
if ( !strcmp( killedwith, "d_teammate" ) )
|
||||
rgDeathNoticeList[i].iTeamKill = TRUE;
|
||||
}
|
||||
|
||||
// Find the sprite in the list
|
||||
int spr = gHUD.GetSpriteIndex( killedwith );
|
||||
@ -173,48 +238,58 @@ int CHudDeathNotice :: MsgFunc_DeathMsg( const char *pszName, int iSize, void *p
|
||||
DEATHNOTICE_DISPLAY_TIME = CVAR_GET_FLOAT( "hud_deathnotice_time" );
|
||||
rgDeathNoticeList[i].flDisplayTime = gHUD.m_flTime + DEATHNOTICE_DISPLAY_TIME;
|
||||
|
||||
// record the death notice in the console
|
||||
if ( rgDeathNoticeList[i].iSuicide )
|
||||
{
|
||||
ConsolePrint( rgDeathNoticeList[i].szVictim );
|
||||
|
||||
if ( !strcmp( killedwith, "d_world" ) )
|
||||
{
|
||||
ConsolePrint( " died" );
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsolePrint( " killed self" );
|
||||
}
|
||||
}
|
||||
else if ( rgDeathNoticeList[i].iTeamKill )
|
||||
if (rgDeathNoticeList[i].iNonPlayerKill)
|
||||
{
|
||||
ConsolePrint( rgDeathNoticeList[i].szKiller );
|
||||
ConsolePrint( " killed his teammate " );
|
||||
ConsolePrint( " killed a " );
|
||||
ConsolePrint( rgDeathNoticeList[i].szVictim );
|
||||
ConsolePrint( "\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsolePrint( rgDeathNoticeList[i].szKiller );
|
||||
ConsolePrint( " killed " );
|
||||
ConsolePrint( rgDeathNoticeList[i].szVictim );
|
||||
// record the death notice in the console
|
||||
if ( rgDeathNoticeList[i].iSuicide )
|
||||
{
|
||||
ConsolePrint( rgDeathNoticeList[i].szVictim );
|
||||
|
||||
if ( !strcmp( killedwith, "d_world" ) )
|
||||
{
|
||||
ConsolePrint( " died" );
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsolePrint( " killed self" );
|
||||
}
|
||||
}
|
||||
else if ( rgDeathNoticeList[i].iTeamKill )
|
||||
{
|
||||
ConsolePrint( rgDeathNoticeList[i].szKiller );
|
||||
ConsolePrint( " killed his teammate " );
|
||||
ConsolePrint( rgDeathNoticeList[i].szVictim );
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsolePrint( rgDeathNoticeList[i].szKiller );
|
||||
ConsolePrint( " killed " );
|
||||
ConsolePrint( rgDeathNoticeList[i].szVictim );
|
||||
}
|
||||
|
||||
if ( killedwith && *killedwith && (*killedwith > 13 ) && strcmp( killedwith, "d_world" ) && !rgDeathNoticeList[i].iTeamKill )
|
||||
{
|
||||
ConsolePrint( " with " );
|
||||
|
||||
// replace the code names with the 'real' names
|
||||
if ( !strcmp( killedwith+2, "egon" ) )
|
||||
strcpy( killedwith, "d_gluon gun" );
|
||||
if ( !strcmp( killedwith+2, "gauss" ) )
|
||||
strcpy( killedwith, "d_tau cannon" );
|
||||
|
||||
ConsolePrint( killedwith+2 ); // skip over the "d_" part
|
||||
}
|
||||
|
||||
ConsolePrint( "\n" );
|
||||
}
|
||||
|
||||
if ( killedwith && *killedwith && (*killedwith > 13 ) && strcmp( killedwith, "d_world" ) && !rgDeathNoticeList[i].iTeamKill )
|
||||
{
|
||||
ConsolePrint( " with " );
|
||||
|
||||
// replace the code names with the 'real' names
|
||||
if ( !strcmp( killedwith+2, "egon" ) )
|
||||
strcpy( killedwith, "d_gluon gun" );
|
||||
if ( !strcmp( killedwith+2, "gauss" ) )
|
||||
strcpy( killedwith, "d_tau cannon" );
|
||||
|
||||
ConsolePrint( killedwith+2 ); // skip over the "d_" part
|
||||
}
|
||||
|
||||
ConsolePrint( "\n" );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
103
cl_dll/demo.cpp
Normal file
103
cl_dll/demo.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "demo.h"
|
||||
#include "demo_api.h"
|
||||
#include <memory.h>
|
||||
|
||||
#define DLLEXPORT __declspec( dllexport )
|
||||
|
||||
int g_demosniper = 0;
|
||||
int g_demosniperdamage = 0;
|
||||
float g_demosniperorg[3];
|
||||
float g_demosniperangles[3];
|
||||
float g_demozoom;
|
||||
|
||||
// FIXME: There should be buffer helper functions to avoid all of the *(int *)& crap.
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
Demo_WriteBuffer
|
||||
|
||||
Write some data to the demo stream
|
||||
=====================
|
||||
*/
|
||||
void Demo_WriteBuffer( int type, int size, unsigned char *buffer )
|
||||
{
|
||||
int pos = 0;
|
||||
unsigned char buf[ 32 * 1024 ];
|
||||
*( int * )&buf[pos] = type;
|
||||
pos+=sizeof( int );
|
||||
|
||||
memcpy( &buf[pos], buffer, size );
|
||||
|
||||
// Write full buffer out
|
||||
gEngfuncs.pDemoAPI->WriteBuffer( size + sizeof( int ), buf );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
Demo_ReadBuffer
|
||||
|
||||
Engine wants us to parse some data from the demo stream
|
||||
=====================
|
||||
*/
|
||||
void DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer )
|
||||
{
|
||||
int type;
|
||||
int i = 0;
|
||||
|
||||
type = *( int * )buffer;
|
||||
i += sizeof( int );
|
||||
switch ( type )
|
||||
{
|
||||
case TYPE_SNIPERDOT:
|
||||
g_demosniper = *(int * )&buffer[ i ];
|
||||
i += sizeof( int );
|
||||
|
||||
if ( g_demosniper )
|
||||
{
|
||||
g_demosniperdamage = *( int * )&buffer[ i ];
|
||||
i += sizeof( int );
|
||||
|
||||
g_demosniperangles[ 0 ] = *(float *)&buffer[i];
|
||||
i += sizeof( float );
|
||||
g_demosniperangles[ 1 ] = *(float *)&buffer[i];
|
||||
i += sizeof( float );
|
||||
g_demosniperangles[ 2 ] = *(float *)&buffer[i];
|
||||
i += sizeof( float );
|
||||
g_demosniperorg[ 0 ] = *(float *)&buffer[i];
|
||||
i += sizeof( float );
|
||||
g_demosniperorg[ 1 ] = *(float *)&buffer[i];
|
||||
i += sizeof( float );
|
||||
g_demosniperorg[ 2 ] = *(float *)&buffer[i];
|
||||
i += sizeof( float );
|
||||
}
|
||||
break;
|
||||
case TYPE_ZOOM:
|
||||
g_demozoom = *(float * )&buffer[ i ];
|
||||
i += sizeof( float );
|
||||
break;
|
||||
default:
|
||||
gEngfuncs.Con_DPrintf( "Unknown demo buffer type, skipping.\n" );
|
||||
break;
|
||||
}
|
||||
}
|
20
cl_dll/demo.h
Normal file
20
cl_dll/demo.h
Normal file
@ -0,0 +1,20 @@
|
||||
#if !defined( DEMOH )
|
||||
#define DEMOH
|
||||
#pragma once
|
||||
|
||||
// Types of demo messages we can write/parse
|
||||
enum
|
||||
{
|
||||
TYPE_SNIPERDOT = 0,
|
||||
TYPE_ZOOM
|
||||
};
|
||||
|
||||
void Demo_WriteBuffer( int type, int size, unsigned char *buffer );
|
||||
|
||||
extern int g_demosniper;
|
||||
extern int g_demosniperdamage;
|
||||
extern float g_demosniperorg[3];
|
||||
extern float g_demosniperangles[3];
|
||||
extern float g_demozoom;
|
||||
|
||||
#endif
|
914
cl_dll/entity.cpp
Normal file
914
cl_dll/entity.cpp
Normal file
@ -0,0 +1,914 @@
|
||||
// Client side entity management functions
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "const.h"
|
||||
#include "entity_types.h"
|
||||
#include "studio_event.h" // def. of mstudioevent_t
|
||||
#include "r_efx.h"
|
||||
#include "event_api.h"
|
||||
#include "pm_defs.h"
|
||||
#include "pmtrace.h"
|
||||
|
||||
#define DLLEXPORT __declspec( dllexport )
|
||||
|
||||
void Game_AddObjects( void );
|
||||
|
||||
extern vec3_t v_origin;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
int DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname );
|
||||
void DLLEXPORT HUD_CreateEntities( void );
|
||||
void DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity );
|
||||
void DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client );
|
||||
void DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src );
|
||||
void DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd );
|
||||
void DLLEXPORT HUD_TempEntUpdate( double frametime, double client_time, double cl_gravity, struct tempent_s **ppTempEntFree, struct tempent_s **ppTempEntActive, int ( *Callback_AddVisibleEntity )( struct cl_entity_s *pEntity ), void ( *Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ) );
|
||||
struct cl_entity_s DLLEXPORT *HUD_GetUserEntity( int index );
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
HUD_AddEntity
|
||||
Return 0 to filter entity from visible list for rendering
|
||||
========================
|
||||
*/
|
||||
int DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case ET_NORMAL:
|
||||
case ET_PLAYER:
|
||||
case ET_BEAM:
|
||||
case ET_TEMPENTITY:
|
||||
case ET_FRAGMENTED:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
=========================
|
||||
HUD_TxferLocalOverrides
|
||||
|
||||
The server sends us our origin with extra precision as part of the clientdata structure, not during the normal
|
||||
playerstate update in entity_state_t. In order for these overrides to eventually get to the appropriate playerstate
|
||||
structure, we need to copy them into the state structure at this point.
|
||||
=========================
|
||||
*/
|
||||
void DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client )
|
||||
{
|
||||
VectorCopy( client->origin, state->origin );
|
||||
|
||||
// Spectator
|
||||
state->iuser1 = client->iuser1;
|
||||
state->iuser2 = client->iuser2;
|
||||
}
|
||||
|
||||
/*
|
||||
=========================
|
||||
HUD_ProcessPlayerState
|
||||
|
||||
We have received entity_state_t for this player over the network. We need to copy appropriate fields to the
|
||||
playerstate structure
|
||||
=========================
|
||||
*/
|
||||
void DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src )
|
||||
{
|
||||
// Copy in network data
|
||||
VectorCopy( src->origin, dst->origin );
|
||||
VectorCopy( src->angles, dst->angles );
|
||||
|
||||
VectorCopy( src->velocity, dst->velocity );
|
||||
|
||||
dst->frame = src->frame;
|
||||
dst->modelindex = src->modelindex;
|
||||
dst->skin = src->skin;
|
||||
dst->effects = src->effects;
|
||||
dst->weaponmodel = src->weaponmodel;
|
||||
dst->movetype = src->movetype;
|
||||
dst->sequence = src->sequence;
|
||||
dst->animtime = src->animtime;
|
||||
|
||||
dst->solid = src->solid;
|
||||
|
||||
dst->rendermode = src->rendermode;
|
||||
dst->renderamt = src->renderamt;
|
||||
dst->rendercolor.r = src->rendercolor.r;
|
||||
dst->rendercolor.g = src->rendercolor.g;
|
||||
dst->rendercolor.b = src->rendercolor.b;
|
||||
dst->renderfx = src->renderfx;
|
||||
|
||||
dst->framerate = src->framerate;
|
||||
dst->body = src->body;
|
||||
|
||||
memcpy( &dst->controller[0], &src->controller[0], 4 * sizeof( byte ) );
|
||||
memcpy( &dst->blending[0], &src->blending[0], 2 * sizeof( byte ) );
|
||||
|
||||
VectorCopy( src->basevelocity, dst->basevelocity );
|
||||
|
||||
dst->friction = src->friction;
|
||||
dst->gravity = src->gravity;
|
||||
dst->gaitsequence = src->gaitsequence;
|
||||
dst->spectator = src->spectator;
|
||||
dst->usehull = src->usehull;
|
||||
dst->playerclass = src->playerclass;
|
||||
dst->team = src->team;
|
||||
dst->colormap = src->colormap;
|
||||
|
||||
// Save off some data so other areas of the Client DLL can get to it
|
||||
cl_entity_t *player = gEngfuncs.GetLocalPlayer(); // Get the local player's index
|
||||
if ( dst->number == player->index )
|
||||
{
|
||||
g_iPlayerClass = dst->playerclass;
|
||||
g_iTeamNumber = dst->team;
|
||||
g_iUser1 = src->iuser1;
|
||||
g_iUser2 = src->iuser2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=========================
|
||||
HUD_TxferPredictionData
|
||||
|
||||
Because we can predict an arbitrary number of frames before the server responds with an update, we need to be able to copy client side prediction data in
|
||||
from the state that the server ack'd receiving, which can be anywhere along the predicted frame path ( i.e., we could predict 20 frames into the future and the server ack's
|
||||
up through 10 of those frames, so we need to copy persistent client-side only state from the 10th predicted frame to the slot the server
|
||||
update is occupying.
|
||||
=========================
|
||||
*/
|
||||
void DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd )
|
||||
{
|
||||
ps->oldbuttons = pps->oldbuttons;
|
||||
ps->flFallVelocity = pps->flFallVelocity;
|
||||
ps->iStepLeft = pps->iStepLeft;
|
||||
ps->playerclass = pps->playerclass;
|
||||
|
||||
pcd->viewmodel = ppcd->viewmodel;
|
||||
pcd->m_iId = ppcd->m_iId;
|
||||
pcd->ammo_shells = ppcd->ammo_shells;
|
||||
pcd->ammo_nails = ppcd->ammo_nails;
|
||||
pcd->ammo_cells = ppcd->ammo_cells;
|
||||
pcd->ammo_rockets = ppcd->ammo_rockets;
|
||||
pcd->m_flNextAttack = ppcd->m_flNextAttack;
|
||||
pcd->fov = ppcd->fov;
|
||||
pcd->weaponanim = ppcd->weaponanim;
|
||||
pcd->tfstate = ppcd->tfstate;
|
||||
pcd->maxspeed = ppcd->maxspeed;
|
||||
|
||||
pcd->deadflag = ppcd->deadflag;
|
||||
|
||||
// Spectator
|
||||
pcd->iuser1 = ppcd->iuser1;
|
||||
pcd->iuser2 = ppcd->iuser2;
|
||||
|
||||
memcpy( wd, pwd, 32 * sizeof( weapon_data_t ) );
|
||||
}
|
||||
|
||||
/*
|
||||
//#define TEST_IT
|
||||
#if defined( TEST_IT )
|
||||
|
||||
cl_entity_t mymodel[9];
|
||||
|
||||
void MoveModel( void )
|
||||
{
|
||||
cl_entity_t *player;
|
||||
int i, j;
|
||||
int modelindex;
|
||||
struct model_s *mod;
|
||||
|
||||
// Load it up with some bogus data
|
||||
player = gEngfuncs.GetLocalPlayer();
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
mod = gEngfuncs.CL_LoadModel( "models/sentry3.mdl", &modelindex );
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
// Don't draw over ourself...
|
||||
if ( ( i == 1 ) && ( j == 1 ) )
|
||||
continue;
|
||||
|
||||
mymodel[ i * 3 + j ] = *player;
|
||||
|
||||
mymodel[ i * 3 + j ].player = 0;
|
||||
|
||||
mymodel[ i * 3 + j ].model = mod;
|
||||
mymodel[ i * 3 + j ].curstate.modelindex = modelindex;
|
||||
|
||||
// Move it out a bit
|
||||
mymodel[ i * 3 + j ].origin[0] = player->origin[0] + 50 * ( 1 - i );
|
||||
mymodel[ i * 3 + j ].origin[1] = player->origin[1] + 50 * ( 1 - j );
|
||||
|
||||
gEngfuncs.CL_CreateVisibleEntity( ET_NORMAL, &mymodel[i*3+j] );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//#define TRACE_TEST
|
||||
#if defined( TRACE_TEST )
|
||||
|
||||
extern int hitent;
|
||||
|
||||
cl_entity_t hit;
|
||||
|
||||
void TraceModel( void )
|
||||
{
|
||||
cl_entity_t *ent;
|
||||
|
||||
if ( hitent <= 0 )
|
||||
return;
|
||||
|
||||
// Load it up with some bogus data
|
||||
ent = gEngfuncs.GetEntityByIndex( hitent );
|
||||
if ( !ent )
|
||||
return;
|
||||
|
||||
hit = *ent;
|
||||
//hit.curstate.rendermode = kRenderTransTexture;
|
||||
//hit.curstate.renderfx = kRenderFxGlowShell;
|
||||
//hit.curstate.renderamt = 100;
|
||||
|
||||
hit.origin[2] += 40;
|
||||
|
||||
gEngfuncs.CL_CreateVisibleEntity( ET_NORMAL, &hit );
|
||||
}
|
||||
|
||||
#endif
|
||||
*/
|
||||
|
||||
/*
|
||||
void ParticleCallback( struct particle_s *particle, float frametime )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
particle->org[ i ] += particle->vel[ i ] * frametime;
|
||||
}
|
||||
}
|
||||
|
||||
cvar_t *color = NULL;
|
||||
void Particles( void )
|
||||
{
|
||||
static float lasttime;
|
||||
float curtime;
|
||||
|
||||
curtime = gEngfuncs.GetClientTime();
|
||||
|
||||
if ( ( curtime - lasttime ) < 2.0 )
|
||||
return;
|
||||
|
||||
if ( !color )
|
||||
{
|
||||
color = gEngfuncs.pfnRegisterVariable ( "color","255 0 0", 0 );
|
||||
}
|
||||
|
||||
lasttime = curtime;
|
||||
|
||||
// Create a few particles
|
||||
particle_t *p;
|
||||
int i, j;
|
||||
|
||||
for ( i = 0; i < 1000; i++ )
|
||||
{
|
||||
int r, g, b;
|
||||
p = gEngfuncs.pEfxAPI->R_AllocParticle( ParticleCallback );
|
||||
if ( !p )
|
||||
break;
|
||||
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
p->org[ j ] = v_origin[ j ] + gEngfuncs.pfnRandomFloat( -32.0, 32.0 );;
|
||||
p->vel[ j ] = gEngfuncs.pfnRandomFloat( -100.0, 100.0 );
|
||||
}
|
||||
|
||||
if ( color )
|
||||
{
|
||||
sscanf( color->string, "%i %i %i", &r, &g, &b );
|
||||
}
|
||||
else
|
||||
{
|
||||
r = 192;
|
||||
g = 0;
|
||||
b = 0;
|
||||
}
|
||||
|
||||
p->color = gEngfuncs.pEfxAPI->R_LookupColor( r, g, b );
|
||||
gEngfuncs.pEfxAPI->R_GetPackedColor( &p->packedColor, p->color );
|
||||
|
||||
// p->die is set to current time so all you have to do is add an additional time to it
|
||||
p->die += 3.0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
void TempEntCallback ( struct tempent_s *ent, float frametime, float currenttime )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
ent->entity.curstate.origin[ i ] += ent->entity.baseline.origin[ i ] * frametime;
|
||||
}
|
||||
}
|
||||
|
||||
void TempEnts( void )
|
||||
{
|
||||
static float lasttime;
|
||||
float curtime;
|
||||
|
||||
curtime = gEngfuncs.GetClientTime();
|
||||
|
||||
if ( ( curtime - lasttime ) < 10.0 )
|
||||
return;
|
||||
|
||||
lasttime = curtime;
|
||||
|
||||
TEMPENTITY *p;
|
||||
int i, j;
|
||||
struct model_s *mod;
|
||||
vec3_t origin;
|
||||
int index;
|
||||
|
||||
mod = gEngfuncs.CL_LoadModel( "sprites/laserdot.spr", &index );
|
||||
|
||||
for ( i = 0; i < 100; i++ )
|
||||
{
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
origin[ j ] = v_origin[ j ];
|
||||
if ( j != 2 )
|
||||
{
|
||||
origin[ j ] += 75;
|
||||
}
|
||||
}
|
||||
|
||||
p = gEngfuncs.pEfxAPI->CL_TentEntAllocCustom( (float *)&origin, mod, 0, TempEntCallback );
|
||||
if ( !p )
|
||||
break;
|
||||
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
p->entity.curstate.origin[ j ] = origin[ j ];
|
||||
|
||||
// Store velocity in baseline origin
|
||||
p->entity.baseline.origin[ j ] = gEngfuncs.pfnRandomFloat( -100, 100 );
|
||||
}
|
||||
|
||||
// p->die is set to current time so all you have to do is add an additional time to it
|
||||
p->die += 10.0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#if defined( BEAM_TEST )
|
||||
// Note can't index beam[ 0 ] in Beam callback, so don't use that index
|
||||
// Room for 1 beam ( 0 can't be used )
|
||||
static cl_entity_t beams[ 2 ];
|
||||
|
||||
void BeamEndModel( void )
|
||||
{
|
||||
cl_entity_t *player, *model;
|
||||
int modelindex;
|
||||
struct model_s *mod;
|
||||
|
||||
// Load it up with some bogus data
|
||||
player = gEngfuncs.GetLocalPlayer();
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
mod = gEngfuncs.CL_LoadModel( "models/sentry3.mdl", &modelindex );
|
||||
if ( !mod )
|
||||
return;
|
||||
|
||||
// Slot 1
|
||||
model = &beams[ 1 ];
|
||||
|
||||
*model = *player;
|
||||
model->player = 0;
|
||||
model->model = mod;
|
||||
model->curstate.modelindex = modelindex;
|
||||
|
||||
// Move it out a bit
|
||||
model->origin[0] = player->origin[0] - 100;
|
||||
model->origin[1] = player->origin[1];
|
||||
|
||||
model->attachment[0] = model->origin;
|
||||
model->attachment[1] = model->origin;
|
||||
model->attachment[2] = model->origin;
|
||||
model->attachment[3] = model->origin;
|
||||
|
||||
gEngfuncs.CL_CreateVisibleEntity( ET_NORMAL, model );
|
||||
}
|
||||
|
||||
void Beams( void )
|
||||
{
|
||||
static float lasttime;
|
||||
float curtime;
|
||||
struct model_s *mod;
|
||||
int index;
|
||||
|
||||
BeamEndModel();
|
||||
|
||||
curtime = gEngfuncs.GetClientTime();
|
||||
float end[ 3 ];
|
||||
|
||||
if ( ( curtime - lasttime ) < 10.0 )
|
||||
return;
|
||||
|
||||
mod = gEngfuncs.CL_LoadModel( "sprites/laserbeam.spr", &index );
|
||||
if ( !mod )
|
||||
return;
|
||||
|
||||
lasttime = curtime;
|
||||
|
||||
end [ 0 ] = v_origin.x + 100;
|
||||
end [ 1 ] = v_origin.y + 100;
|
||||
end [ 2 ] = v_origin.z;
|
||||
|
||||
BEAM *p1;
|
||||
p1 = gEngfuncs.pEfxAPI->R_BeamEntPoint( -1, end, index,
|
||||
10.0, 2.0, 0.3, 1.0, 5.0, 0.0, 1.0, 1.0, 1.0, 1.0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=========================
|
||||
HUD_CreateEntities
|
||||
|
||||
Gives us a chance to add additional entities to the render this frame
|
||||
=========================
|
||||
*/
|
||||
void DLLEXPORT HUD_CreateEntities( void )
|
||||
{
|
||||
// e.g., create a persistent cl_entity_t somewhere.
|
||||
// Load an appropriate model into it ( gEngfuncs.CL_LoadModel )
|
||||
// Call gEngfuncs.CL_CreateVisibleEntity to add it to the visedicts list
|
||||
/*
|
||||
#if defined( TEST_IT )
|
||||
MoveModel();
|
||||
#endif
|
||||
|
||||
#if defined( TRACE_TEST )
|
||||
TraceModel();
|
||||
#endif
|
||||
*/
|
||||
/*
|
||||
Particles();
|
||||
*/
|
||||
/*
|
||||
TempEnts();
|
||||
*/
|
||||
|
||||
#if defined( BEAM_TEST )
|
||||
Beams();
|
||||
#endif
|
||||
|
||||
// Add in any game specific objects
|
||||
Game_AddObjects();
|
||||
}
|
||||
|
||||
/*
|
||||
=========================
|
||||
HUD_StudioEvent
|
||||
|
||||
The entity's studio model description indicated an event was
|
||||
fired during this frame, handle the event by it's tag ( e.g., muzzleflash, sound )
|
||||
=========================
|
||||
*/
|
||||
void DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity )
|
||||
{
|
||||
switch( event->event )
|
||||
{
|
||||
case 5001:
|
||||
gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[0], atoi( event->options) );
|
||||
break;
|
||||
case 5011:
|
||||
gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[1], atoi( event->options) );
|
||||
break;
|
||||
case 5021:
|
||||
gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[2], atoi( event->options) );
|
||||
break;
|
||||
case 5031:
|
||||
gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[3], atoi( event->options) );
|
||||
break;
|
||||
case 5002:
|
||||
gEngfuncs.pEfxAPI->R_SparkEffect( (float *)&entity->attachment[0], atoi( event->options), -100, 100 );
|
||||
break;
|
||||
// Client side sound
|
||||
case 5004:
|
||||
gEngfuncs.pfnPlaySoundByNameAtLocation( (char *)event->options, 1.0, (float *)&entity->attachment[0] );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_UpdateTEnts
|
||||
|
||||
Simulation and cleanup of temporary entities
|
||||
=================
|
||||
*/
|
||||
void DLLEXPORT HUD_TempEntUpdate (
|
||||
double frametime, // Simulation time
|
||||
double client_time, // Absolute time on client
|
||||
double cl_gravity, // True gravity on client
|
||||
TEMPENTITY **ppTempEntFree, // List of freed temporary ents
|
||||
TEMPENTITY **ppTempEntActive, // List
|
||||
int ( *Callback_AddVisibleEntity )( cl_entity_t *pEntity ),
|
||||
void ( *Callback_TempEntPlaySound )( TEMPENTITY *pTemp, float damp ) )
|
||||
{
|
||||
static int gTempEntFrame = 0;
|
||||
int i;
|
||||
TEMPENTITY *pTemp, *pnext, *pprev;
|
||||
float freq, gravity, gravitySlow, life, fastFreq;
|
||||
|
||||
// Nothing to simulate
|
||||
if ( !*ppTempEntActive )
|
||||
return;
|
||||
|
||||
// in order to have tents collide with players, we have to run the player prediction code so
|
||||
// that the client has the player list. We run this code once when we detect any COLLIDEALL
|
||||
// tent, then set this BOOL to true so the code doesn't get run again if there's more than
|
||||
// one COLLIDEALL ent for this update. (often are).
|
||||
gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true );
|
||||
|
||||
// Store off the old count
|
||||
gEngfuncs.pEventAPI->EV_PushPMStates();
|
||||
|
||||
// Now add in all of the players.
|
||||
gEngfuncs.pEventAPI->EV_SetSolidPlayers ( -1 );
|
||||
|
||||
// !!!BUGBUG -- This needs to be time based
|
||||
gTempEntFrame = (gTempEntFrame+1) & 31;
|
||||
|
||||
pTemp = *ppTempEntActive;
|
||||
|
||||
// !!! Don't simulate while paused.... This is sort of a hack, revisit.
|
||||
if ( frametime <= 0 )
|
||||
{
|
||||
while ( pTemp )
|
||||
{
|
||||
if ( !(pTemp->flags & FTENT_NOMODEL ) )
|
||||
{
|
||||
Callback_AddVisibleEntity( &pTemp->entity );
|
||||
}
|
||||
pTemp = pTemp->next;
|
||||
}
|
||||
goto finish;
|
||||
}
|
||||
|
||||
pprev = NULL;
|
||||
freq = client_time * 0.01;
|
||||
fastFreq = client_time * 5.5;
|
||||
gravity = -frametime * cl_gravity;
|
||||
gravitySlow = gravity * 0.5;
|
||||
|
||||
while ( pTemp )
|
||||
{
|
||||
int active;
|
||||
|
||||
active = 1;
|
||||
|
||||
life = pTemp->die - client_time;
|
||||
pnext = pTemp->next;
|
||||
if ( life < 0 )
|
||||
{
|
||||
if ( pTemp->flags & FTENT_FADEOUT )
|
||||
{
|
||||
if (pTemp->entity.curstate.rendermode == kRenderNormal)
|
||||
pTemp->entity.curstate.rendermode = kRenderTransTexture;
|
||||
pTemp->entity.curstate.renderamt = pTemp->entity.baseline.renderamt * ( 1 + life * pTemp->fadeSpeed );
|
||||
if ( pTemp->entity.curstate.renderamt <= 0 )
|
||||
active = 0;
|
||||
|
||||
}
|
||||
else
|
||||
active = 0;
|
||||
}
|
||||
if ( !active ) // Kill it
|
||||
{
|
||||
pTemp->next = *ppTempEntFree;
|
||||
*ppTempEntFree = pTemp;
|
||||
if ( !pprev ) // Deleting at head of list
|
||||
*ppTempEntActive = pnext;
|
||||
else
|
||||
pprev->next = pnext;
|
||||
}
|
||||
else
|
||||
{
|
||||
pprev = pTemp;
|
||||
|
||||
VectorCopy( pTemp->entity.origin, pTemp->entity.prevstate.origin );
|
||||
|
||||
if ( pTemp->flags & FTENT_SPARKSHOWER )
|
||||
{
|
||||
// Adjust speed if it's time
|
||||
// Scale is next think time
|
||||
if ( client_time > pTemp->entity.baseline.scale )
|
||||
{
|
||||
// Show Sparks
|
||||
gEngfuncs.pEfxAPI->R_SparkEffect( pTemp->entity.origin, 8, -200, 200 );
|
||||
|
||||
// Reduce life
|
||||
pTemp->entity.baseline.framerate -= 0.1;
|
||||
|
||||
if ( pTemp->entity.baseline.framerate <= 0.0 )
|
||||
{
|
||||
pTemp->die = client_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
// So it will die no matter what
|
||||
pTemp->die = client_time + 0.5;
|
||||
|
||||
// Next think
|
||||
pTemp->entity.baseline.scale = client_time + 0.1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( pTemp->flags & FTENT_PLYRATTACHMENT )
|
||||
{
|
||||
cl_entity_t *pClient;
|
||||
|
||||
pClient = gEngfuncs.GetEntityByIndex( pTemp->clientIndex );
|
||||
|
||||
VectorAdd( pClient->origin, pTemp->tentOffset, pTemp->entity.origin );
|
||||
}
|
||||
else if ( pTemp->flags & FTENT_SINEWAVE )
|
||||
{
|
||||
pTemp->x += pTemp->entity.baseline.origin[0] * frametime;
|
||||
pTemp->y += pTemp->entity.baseline.origin[1] * frametime;
|
||||
|
||||
pTemp->entity.origin[0] = pTemp->x + sin( pTemp->entity.baseline.origin[2] + client_time * pTemp->entity.prevstate.frame ) * (10*pTemp->entity.curstate.framerate);
|
||||
pTemp->entity.origin[1] = pTemp->y + sin( pTemp->entity.baseline.origin[2] + fastFreq + 0.7 ) * (8*pTemp->entity.curstate.framerate);
|
||||
pTemp->entity.origin[2] += pTemp->entity.baseline.origin[2] * frametime;
|
||||
}
|
||||
else if ( pTemp->flags & FTENT_SPIRAL )
|
||||
{
|
||||
float s, c;
|
||||
s = sin( pTemp->entity.baseline.origin[2] + fastFreq );
|
||||
c = cos( pTemp->entity.baseline.origin[2] + fastFreq );
|
||||
|
||||
pTemp->entity.origin[0] += pTemp->entity.baseline.origin[0] * frametime + 8 * sin( client_time * 20 + (int)pTemp );
|
||||
pTemp->entity.origin[1] += pTemp->entity.baseline.origin[1] * frametime + 4 * sin( client_time * 30 + (int)pTemp );
|
||||
pTemp->entity.origin[2] += pTemp->entity.baseline.origin[2] * frametime;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < 3; i++ )
|
||||
pTemp->entity.origin[i] += pTemp->entity.baseline.origin[i] * frametime;
|
||||
}
|
||||
|
||||
if ( pTemp->flags & FTENT_SPRANIMATE )
|
||||
{
|
||||
pTemp->entity.curstate.frame += frametime * pTemp->entity.curstate.framerate;
|
||||
if ( pTemp->entity.curstate.frame >= pTemp->frameMax )
|
||||
{
|
||||
pTemp->entity.curstate.frame = pTemp->entity.curstate.frame - (int)(pTemp->entity.curstate.frame);
|
||||
|
||||
if ( !(pTemp->flags & FTENT_SPRANIMATELOOP) )
|
||||
{
|
||||
// this animating sprite isn't set to loop, so destroy it.
|
||||
pTemp->die = client_time;
|
||||
pTemp = pnext;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( pTemp->flags & FTENT_SPRCYCLE )
|
||||
{
|
||||
pTemp->entity.curstate.frame += frametime * 10;
|
||||
if ( pTemp->entity.curstate.frame >= pTemp->frameMax )
|
||||
{
|
||||
pTemp->entity.curstate.frame = pTemp->entity.curstate.frame - (int)(pTemp->entity.curstate.frame);
|
||||
}
|
||||
}
|
||||
// Experiment
|
||||
#if 0
|
||||
if ( pTemp->flags & FTENT_SCALE )
|
||||
pTemp->entity.curstate.framerate += 20.0 * (frametime / pTemp->entity.curstate.framerate);
|
||||
#endif
|
||||
|
||||
if ( pTemp->flags & FTENT_ROTATE )
|
||||
{
|
||||
pTemp->entity.angles[0] += pTemp->entity.baseline.angles[0] * frametime;
|
||||
pTemp->entity.angles[1] += pTemp->entity.baseline.angles[1] * frametime;
|
||||
pTemp->entity.angles[2] += pTemp->entity.baseline.angles[2] * frametime;
|
||||
|
||||
VectorCopy( pTemp->entity.angles, pTemp->entity.latched.prevangles );
|
||||
}
|
||||
|
||||
if ( pTemp->flags & (FTENT_COLLIDEALL | FTENT_COLLIDEWORLD) )
|
||||
{
|
||||
vec3_t traceNormal;
|
||||
float traceFraction = 1;
|
||||
|
||||
if ( pTemp->flags & FTENT_COLLIDEALL )
|
||||
{
|
||||
pmtrace_t pmtrace;
|
||||
physent_t *pe;
|
||||
|
||||
gEngfuncs.pEventAPI->EV_SetTraceHull( 2 );
|
||||
|
||||
gEngfuncs.pEventAPI->EV_PlayerTrace( pTemp->entity.prevstate.origin, pTemp->entity.origin, PM_STUDIO_BOX, -1, &pmtrace );
|
||||
|
||||
|
||||
if ( pmtrace.fraction != 1 )
|
||||
{
|
||||
pe = gEngfuncs.pEventAPI->EV_GetPhysent( pmtrace.ent );
|
||||
|
||||
if ( !pmtrace.ent || ( pe->info != pTemp->clientIndex ) )
|
||||
{
|
||||
traceFraction = pmtrace.fraction;
|
||||
VectorCopy( pmtrace.plane.normal, traceNormal );
|
||||
|
||||
if ( pTemp->hitcallback )
|
||||
{
|
||||
(*pTemp->hitcallback)( pTemp, &pmtrace );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( pTemp->flags & FTENT_COLLIDEWORLD )
|
||||
{
|
||||
pmtrace_t pmtrace;
|
||||
|
||||
gEngfuncs.pEventAPI->EV_SetTraceHull( 2 );
|
||||
|
||||
gEngfuncs.pEventAPI->EV_PlayerTrace( pTemp->entity.prevstate.origin, pTemp->entity.origin, PM_STUDIO_BOX | PM_WORLD_ONLY, -1, &pmtrace );
|
||||
|
||||
if ( pmtrace.fraction != 1 )
|
||||
{
|
||||
traceFraction = pmtrace.fraction;
|
||||
VectorCopy( pmtrace.plane.normal, traceNormal );
|
||||
|
||||
if ( pTemp->flags & FTENT_SPARKSHOWER )
|
||||
{
|
||||
// Chop spark speeds a bit more
|
||||
//
|
||||
VectorScale( pTemp->entity.baseline.origin, 0.6, pTemp->entity.baseline.origin );
|
||||
|
||||
if ( Length( pTemp->entity.baseline.origin ) < 10 )
|
||||
{
|
||||
pTemp->entity.baseline.framerate = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pTemp->hitcallback )
|
||||
{
|
||||
(*pTemp->hitcallback)( pTemp, &pmtrace );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( traceFraction != 1 ) // Decent collision now, and damping works
|
||||
{
|
||||
float proj, damp;
|
||||
|
||||
// Place at contact point
|
||||
VectorMA( pTemp->entity.prevstate.origin, traceFraction*frametime, pTemp->entity.baseline.origin, pTemp->entity.origin );
|
||||
// Damp velocity
|
||||
damp = pTemp->bounceFactor;
|
||||
if ( pTemp->flags & (FTENT_GRAVITY|FTENT_SLOWGRAVITY) )
|
||||
{
|
||||
damp *= 0.5;
|
||||
if ( traceNormal[2] > 0.9 ) // Hit floor?
|
||||
{
|
||||
if ( pTemp->entity.baseline.origin[2] <= 0 && pTemp->entity.baseline.origin[2] >= gravity*3 )
|
||||
{
|
||||
damp = 0; // Stop
|
||||
pTemp->flags &= ~(FTENT_ROTATE|FTENT_GRAVITY|FTENT_SLOWGRAVITY|FTENT_COLLIDEWORLD|FTENT_SMOKETRAIL);
|
||||
pTemp->entity.angles[0] = 0;
|
||||
pTemp->entity.angles[2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pTemp->hitSound)
|
||||
{
|
||||
Callback_TempEntPlaySound(pTemp, damp);
|
||||
}
|
||||
|
||||
if (pTemp->flags & FTENT_COLLIDEKILL)
|
||||
{
|
||||
// die on impact
|
||||
pTemp->flags &= ~FTENT_FADEOUT;
|
||||
pTemp->die = client_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reflect velocity
|
||||
if ( damp != 0 )
|
||||
{
|
||||
proj = DotProduct( pTemp->entity.baseline.origin, traceNormal );
|
||||
VectorMA( pTemp->entity.baseline.origin, -proj*2, traceNormal, pTemp->entity.baseline.origin );
|
||||
// Reflect rotation (fake)
|
||||
|
||||
pTemp->entity.angles[1] = -pTemp->entity.angles[1];
|
||||
}
|
||||
|
||||
if ( damp != 1 )
|
||||
{
|
||||
|
||||
VectorScale( pTemp->entity.baseline.origin, damp, pTemp->entity.baseline.origin );
|
||||
VectorScale( pTemp->entity.angles, 0.9, pTemp->entity.angles );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( (pTemp->flags & FTENT_FLICKER) && gTempEntFrame == pTemp->entity.curstate.effects )
|
||||
{
|
||||
dlight_t *dl = gEngfuncs.pEfxAPI->CL_AllocDlight (0);
|
||||
VectorCopy (pTemp->entity.origin, dl->origin);
|
||||
dl->radius = 60;
|
||||
dl->color.r = 255;
|
||||
dl->color.g = 120;
|
||||
dl->color.b = 0;
|
||||
dl->die = client_time + 0.01;
|
||||
}
|
||||
|
||||
if ( pTemp->flags & FTENT_SMOKETRAIL )
|
||||
{
|
||||
gEngfuncs.pEfxAPI->R_RocketTrail (pTemp->entity.prevstate.origin, pTemp->entity.origin, 1);
|
||||
}
|
||||
|
||||
if ( pTemp->flags & FTENT_GRAVITY )
|
||||
pTemp->entity.baseline.origin[2] += gravity;
|
||||
else if ( pTemp->flags & FTENT_SLOWGRAVITY )
|
||||
pTemp->entity.baseline.origin[2] += gravitySlow;
|
||||
|
||||
if ( pTemp->flags & FTENT_CLIENTCUSTOM )
|
||||
{
|
||||
if ( pTemp->callback )
|
||||
{
|
||||
( *pTemp->callback )( pTemp, frametime, client_time );
|
||||
}
|
||||
}
|
||||
|
||||
// Cull to PVS (not frustum cull, just PVS)
|
||||
if ( !(pTemp->flags & FTENT_NOMODEL ) )
|
||||
{
|
||||
if ( !Callback_AddVisibleEntity( &pTemp->entity ) )
|
||||
{
|
||||
if ( !(pTemp->flags & FTENT_PERSIST) )
|
||||
{
|
||||
pTemp->die = client_time; // If we can't draw it this frame, just dump it.
|
||||
pTemp->flags &= ~FTENT_FADEOUT; // Don't fade out, just die
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pTemp = pnext;
|
||||
}
|
||||
|
||||
finish:
|
||||
// Restore state info
|
||||
gEngfuncs.pEventAPI->EV_PopPMStates();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
HUD_GetUserEntity
|
||||
|
||||
If you specify negative numbers for beam start and end point entities, then
|
||||
the engine will call back into this function requesting a pointer to a cl_entity_t
|
||||
object that describes the entity to attach the beam onto.
|
||||
|
||||
Indices must start at 1, not zero.
|
||||
=================
|
||||
*/
|
||||
cl_entity_t DLLEXPORT *HUD_GetUserEntity( int index )
|
||||
{
|
||||
#if defined( BEAM_TEST )
|
||||
// None by default, you would return a valic pointer if you create a client side
|
||||
// beam and attach it to a client side entity.
|
||||
if ( index > 0 && index <= 1 )
|
||||
{
|
||||
return &beams[ index ];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
198
cl_dll/ev_common.cpp
Normal file
198
cl_dll/ev_common.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
// shared event functions
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "const.h"
|
||||
#include "entity_state.h"
|
||||
#include "cl_entity.h"
|
||||
|
||||
#include "r_efx.h"
|
||||
|
||||
#include "eventscripts.h"
|
||||
#include "event_api.h"
|
||||
|
||||
/*
|
||||
=================
|
||||
GetEntity
|
||||
|
||||
Return's the requested cl_entity_t
|
||||
=================
|
||||
*/
|
||||
struct cl_entity_s *GetEntity( int idx )
|
||||
{
|
||||
return gEngfuncs.GetEntityByIndex( idx );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
GetViewEntity
|
||||
|
||||
Return's the current weapon/view model
|
||||
=================
|
||||
*/
|
||||
struct cl_entity_s *GetViewEntity( void )
|
||||
{
|
||||
return gEngfuncs.GetViewModel();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
EV_CreateTracer
|
||||
|
||||
Creates a tracer effect
|
||||
=================
|
||||
*/
|
||||
void EV_CreateTracer( float *start, float *end )
|
||||
{
|
||||
gEngfuncs.pEfxAPI->R_TracerEffect( start, end );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
EV_IsPlayer
|
||||
|
||||
Is the entity's index in the player range?
|
||||
=================
|
||||
*/
|
||||
qboolean EV_IsPlayer( int idx )
|
||||
{
|
||||
if ( idx >= 1 && idx <= gEngfuncs.GetMaxClients() )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
EV_IsLocal
|
||||
|
||||
Is the entity == the local player
|
||||
=================
|
||||
*/
|
||||
qboolean EV_IsLocal( int idx )
|
||||
{
|
||||
return gEngfuncs.pEventAPI->EV_IsLocal( idx - 1 ) ? true : false;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
EV_GetGunPosition
|
||||
|
||||
Figure out the height of the gun
|
||||
=================
|
||||
*/
|
||||
void EV_GetGunPosition( event_args_t *args, float *pos, float *origin )
|
||||
{
|
||||
int idx;
|
||||
vec3_t view_ofs;
|
||||
|
||||
idx = args->entindex;
|
||||
|
||||
VectorClear( view_ofs );
|
||||
view_ofs[2] = DEFAULT_VIEWHEIGHT;
|
||||
|
||||
if ( EV_IsPlayer( idx ) )
|
||||
{
|
||||
if ( EV_IsLocal( idx ) )
|
||||
{
|
||||
// Grab predicted result for local player
|
||||
gEngfuncs.pEventAPI->EV_LocalPlayerViewheight( view_ofs );
|
||||
}
|
||||
else if ( args->ducking == 1 )
|
||||
{
|
||||
view_ofs[2] = VEC_DUCK_VIEW;
|
||||
}
|
||||
}
|
||||
|
||||
VectorAdd( origin, view_ofs, pos );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
EV_EjectBrass
|
||||
|
||||
Bullet shell casings
|
||||
=================
|
||||
*/
|
||||
void EV_EjectBrass( float *origin, float *velocity, float rotation, int model, int soundtype )
|
||||
{
|
||||
vec3_t endpos;
|
||||
VectorClear( endpos );
|
||||
endpos[1] = rotation;
|
||||
gEngfuncs.pEfxAPI->R_TempModel( origin, velocity, endpos, 2.5, model, soundtype );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
EV_GetDefaultShellInfo
|
||||
|
||||
Determine where to eject shells from
|
||||
=================
|
||||
*/
|
||||
void EV_GetDefaultShellInfo( event_args_t *args, float *origin, float *velocity, float *ShellVelocity, float *ShellOrigin, float *forward, float *right, float *up, float forwardScale, float upScale, float rightScale )
|
||||
{
|
||||
int i;
|
||||
vec3_t view_ofs;
|
||||
float fR, fU;
|
||||
|
||||
int idx;
|
||||
|
||||
idx = args->entindex;
|
||||
|
||||
VectorClear( view_ofs );
|
||||
view_ofs[2] = DEFAULT_VIEWHEIGHT;
|
||||
|
||||
if ( EV_IsPlayer( idx ) )
|
||||
{
|
||||
if ( EV_IsLocal( idx ) )
|
||||
{
|
||||
gEngfuncs.pEventAPI->EV_LocalPlayerViewheight( view_ofs );
|
||||
}
|
||||
else if ( args->ducking == 1 )
|
||||
{
|
||||
view_ofs[2] = VEC_DUCK_VIEW;
|
||||
}
|
||||
}
|
||||
|
||||
fR = gEngfuncs.pfnRandomFloat( 50, 70 );
|
||||
fU = gEngfuncs.pfnRandomFloat( 100, 150 );
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
ShellVelocity[i] = velocity[i] + right[i] * fR + up[i] * fU + forward[i] * 25;
|
||||
ShellOrigin[i] = origin[i] + view_ofs[i] + up[i] * upScale + forward[i] * forwardScale + right[i] * rightScale;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
EV_MuzzleFlash
|
||||
|
||||
Flag weapon/view model for muzzle flash
|
||||
=================
|
||||
*/
|
||||
void EV_MuzzleFlash( void )
|
||||
{
|
||||
// Add muzzle flash to current weapon model
|
||||
cl_entity_t *ent = GetViewEntity();
|
||||
if ( !ent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Or in the muzzle flash
|
||||
ent->curstate.effects |= EF_MUZZLEFLASH;
|
||||
}
|
1112
cl_dll/ev_hldm.cpp
Normal file
1112
cl_dll/ev_hldm.cpp
Normal file
File diff suppressed because it is too large
Load Diff
88
cl_dll/ev_hldm.h
Normal file
88
cl_dll/ev_hldm.h
Normal file
@ -0,0 +1,88 @@
|
||||
#if !defined ( EV_HLDMH )
|
||||
#define EV_HLDMH
|
||||
|
||||
// bullet types
|
||||
typedef enum
|
||||
{
|
||||
BULLET_NONE = 0,
|
||||
BULLET_PLAYER_9MM, // glock
|
||||
BULLET_PLAYER_MP5, // mp5
|
||||
BULLET_PLAYER_357, // python
|
||||
BULLET_PLAYER_BUCKSHOT, // shotgun
|
||||
BULLET_PLAYER_CROWBAR, // crowbar swipe
|
||||
|
||||
BULLET_MONSTER_9MM,
|
||||
BULLET_MONSTER_MP5,
|
||||
BULLET_MONSTER_12MM,
|
||||
} Bullet;
|
||||
|
||||
enum glock_e {
|
||||
GLOCK_IDLE1 = 0,
|
||||
GLOCK_IDLE2,
|
||||
GLOCK_IDLE3,
|
||||
GLOCK_SHOOT,
|
||||
GLOCK_SHOOT_EMPTY,
|
||||
GLOCK_RELOAD,
|
||||
GLOCK_RELOAD_NOT_EMPTY,
|
||||
GLOCK_DRAW,
|
||||
GLOCK_HOLSTER,
|
||||
GLOCK_ADD_SILENCER
|
||||
};
|
||||
|
||||
enum shotgun_e {
|
||||
SHOTGUN_IDLE = 0,
|
||||
SHOTGUN_FIRE,
|
||||
SHOTGUN_FIRE2,
|
||||
SHOTGUN_RELOAD,
|
||||
SHOTGUN_PUMP,
|
||||
SHOTGUN_START_RELOAD,
|
||||
SHOTGUN_DRAW,
|
||||
SHOTGUN_HOLSTER,
|
||||
SHOTGUN_IDLE4,
|
||||
SHOTGUN_IDLE_DEEP
|
||||
};
|
||||
|
||||
enum mp5_e
|
||||
{
|
||||
MP5_LONGIDLE = 0,
|
||||
MP5_IDLE1,
|
||||
MP5_LAUNCH,
|
||||
MP5_RELOAD,
|
||||
MP5_DEPLOY,
|
||||
MP5_FIRE1,
|
||||
MP5_FIRE2,
|
||||
MP5_FIRE3,
|
||||
};
|
||||
|
||||
enum python_e {
|
||||
PYTHON_IDLE1 = 0,
|
||||
PYTHON_FIDGET,
|
||||
PYTHON_FIRE1,
|
||||
PYTHON_RELOAD,
|
||||
PYTHON_HOLSTER,
|
||||
PYTHON_DRAW,
|
||||
PYTHON_IDLE2,
|
||||
PYTHON_IDLE3
|
||||
};
|
||||
|
||||
#define GAUSS_PRIMARY_CHARGE_VOLUME 256// how loud gauss is while charging
|
||||
#define GAUSS_PRIMARY_FIRE_VOLUME 450// how loud gauss is when discharged
|
||||
|
||||
enum gauss_e {
|
||||
GAUSS_IDLE = 0,
|
||||
GAUSS_IDLE2,
|
||||
GAUSS_FIDGET,
|
||||
GAUSS_SPINUP,
|
||||
GAUSS_SPIN,
|
||||
GAUSS_FIRE,
|
||||
GAUSS_FIRE2,
|
||||
GAUSS_HOLSTER,
|
||||
GAUSS_DRAW
|
||||
};
|
||||
|
||||
void EV_HLDM_GunshotDecalTrace( pmtrace_t *pTrace, char *decalName );
|
||||
void EV_HLDM_DecalGunshot( pmtrace_t *pTrace, int iBulletType );
|
||||
int EV_HLDM_CheckTracer( int idx, float *vecSrc, float *end, float *forward, float *right, int iBulletType, int iTracerFreq, int *tracerCount );
|
||||
void EV_HLDM_FireBullets( int idx, float *forward, float *right, float *up, int cShots, float *vecSrc, float *vecDirShooting, float *vecSpread, float flDistance, int iBulletType, int iTracerFreq, int *tracerCount );
|
||||
|
||||
#endif // EV_HLDMH
|
16
cl_dll/events.cpp
Normal file
16
cl_dll/events.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
|
||||
void Game_HookEvents( void );
|
||||
|
||||
/*
|
||||
===================
|
||||
EV_HookEvents
|
||||
|
||||
See if game specific code wants to hook any events.
|
||||
===================
|
||||
*/
|
||||
void EV_HookEvents( void )
|
||||
{
|
||||
Game_HookEvents();
|
||||
}
|
66
cl_dll/eventscripts.h
Normal file
66
cl_dll/eventscripts.h
Normal file
@ -0,0 +1,66 @@
|
||||
// eventscripts.h
|
||||
#if !defined ( EVENTSCRIPTSH )
|
||||
#define EVENTSCRIPTSH
|
||||
|
||||
// defaults for clientinfo messages
|
||||
#define DEFAULT_VIEWHEIGHT 28
|
||||
#define VEC_DUCK_VIEW 12
|
||||
|
||||
#define FTENT_FADEOUT 0x00000080
|
||||
|
||||
#define DMG_GENERIC 0 // generic damage was done
|
||||
#define DMG_CRUSH (1 << 0) // crushed by falling or moving object
|
||||
#define DMG_BULLET (1 << 1) // shot
|
||||
#define DMG_SLASH (1 << 2) // cut, clawed, stabbed
|
||||
#define DMG_BURN (1 << 3) // heat burned
|
||||
#define DMG_FREEZE (1 << 4) // frozen
|
||||
#define DMG_FALL (1 << 5) // fell too far
|
||||
#define DMG_BLAST (1 << 6) // explosive blast damage
|
||||
#define DMG_CLUB (1 << 7) // crowbar, punch, headbutt
|
||||
#define DMG_SHOCK (1 << 8) // electric shock
|
||||
#define DMG_SONIC (1 << 9) // sound pulse shockwave
|
||||
#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam
|
||||
#define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death
|
||||
#define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death.
|
||||
|
||||
// time-based damage
|
||||
//mask off TF-specific stuff too
|
||||
#define DMG_TIMEBASED (~(0xff003fff)) // mask for time-based damage
|
||||
|
||||
#define DMG_DROWN (1 << 14) // Drowning
|
||||
#define DMG_FIRSTTIMEBASED DMG_DROWN
|
||||
|
||||
#define DMG_PARALYZE (1 << 15) // slows affected creature down
|
||||
#define DMG_NERVEGAS (1 << 16) // nerve toxins, very bad
|
||||
#define DMG_POISON (1 << 17) // blood poisioning
|
||||
#define DMG_RADIATION (1 << 18) // radiation exposure
|
||||
#define DMG_DROWNRECOVER (1 << 19) // drowning recovery
|
||||
#define DMG_ACID (1 << 20) // toxic chemicals or acid burns
|
||||
#define DMG_SLOWBURN (1 << 21) // in an oven
|
||||
#define DMG_SLOWFREEZE (1 << 22) // in a subzero freezer
|
||||
#define DMG_MORTAR (1 << 23) // Hit by air raid (done to distinguish grenade from mortar)
|
||||
|
||||
//TF ADDITIONS
|
||||
#define DMG_IGNITE (1 << 24) // Players hit by this begin to burn
|
||||
#define DMG_RADIUS_MAX (1 << 25) // Radius damage with this flag doesn't decrease over distance
|
||||
#define DMG_RADIUS_QUAKE (1 << 26) // Radius damage is done like Quake. 1/2 damage at 1/2 radius.
|
||||
#define DMG_IGNOREARMOR (1 << 27) // Damage ignores target's armor
|
||||
#define DMG_AIMED (1 << 28) // Does Hit location damage
|
||||
#define DMG_WALLPIERCING (1 << 29) // Blast Damages ents through walls
|
||||
|
||||
#define DMG_CALTROP (1<<30)
|
||||
#define DMG_HALLUC (1<<31)
|
||||
|
||||
// Some of these are HL/TFC specific?
|
||||
void EV_EjectBrass( float *origin, float *velocity, float rotation, int model, int soundtype );
|
||||
void EV_GetGunPosition( struct event_args_s *args, float *pos, float *origin );
|
||||
void EV_GetDefaultShellInfo( struct event_args_s *args, float *origin, float *velocity, float *ShellVelocity, float *ShellOrigin, float *forward, float *right, float *up, float forwardScale, float upScale, float rightScale );
|
||||
qboolean EV_IsLocal( int idx );
|
||||
qboolean EV_IsPlayer( int idx );
|
||||
void EV_CreateTracer( float *start, float *end );
|
||||
|
||||
struct cl_entity_s *GetEntity( int idx );
|
||||
struct cl_entity_s *GetViewEntity( void );
|
||||
void EV_MuzzleFlash( void );
|
||||
|
||||
#endif // EVENTSCRIPTSH
|
@ -19,7 +19,7 @@
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include "parsemsg.h"
|
||||
|
||||
#include <string.h>
|
||||
|
@ -19,7 +19,7 @@
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "MATH.H"
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include "parsemsg.h"
|
||||
#include <string.h>
|
||||
|
||||
|
@ -110,6 +110,9 @@ public:
|
||||
int m_iHealth;
|
||||
int m_HUD_dmg_bio;
|
||||
int m_HUD_cross;
|
||||
float m_fAttackFront, m_fAttackRear, m_fAttackLeft, m_fAttackRight;
|
||||
void GetPainColor( int &r, int &g, int &b );
|
||||
float m_fFade;
|
||||
|
||||
private:
|
||||
HSPRITE m_hSprite;
|
||||
@ -117,11 +120,8 @@ private:
|
||||
|
||||
DAMAGE_IMAGE m_dmg[NUM_DMG_TYPES];
|
||||
int m_bitsDamage;
|
||||
float m_fFade;
|
||||
void GetPainColor( int &r, int &g, int &b );
|
||||
int DrawPain(float fTime);
|
||||
int DrawDamage(float fTime);
|
||||
float m_fAttackFront, m_fAttackRear, m_fAttackLeft, m_fAttackRight;
|
||||
void CalcDamageDirection(vec3_t vecFrom);
|
||||
void UpdateTiles(float fTime, long bits);
|
||||
};
|
||||
|
250
cl_dll/hl/hl_baseentity.cpp
Normal file
250
cl_dll/hl/hl_baseentity.cpp
Normal file
@ -0,0 +1,250 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
|
||||
/*
|
||||
==========================
|
||||
This file contains "stubs" of class member implementations so that we can predict certain
|
||||
weapons client side. From time to time you might find that you need to implement part of the
|
||||
these functions. If so, cut it from here, paste it in hl_weapons.cpp or somewhere else and
|
||||
add in the functionality you need.
|
||||
==========================
|
||||
*/
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "player.h"
|
||||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
|
||||
// Globals used by game logic
|
||||
const Vector g_vecZero = Vector( 0, 0, 0 );
|
||||
int gmsgWeapPickup = 0;
|
||||
enginefuncs_t g_engfuncs;
|
||||
globalvars_t *gpGlobals;
|
||||
|
||||
ItemInfo CBasePlayerItem::ItemInfoArray[MAX_WEAPONS];
|
||||
|
||||
void EMIT_SOUND_DYN(edict_t *entity, int channel, const char *sample, float volume, float attenuation, int flags, int pitch) { }
|
||||
|
||||
// CBaseEntity Stubs
|
||||
int CBaseEntity :: TakeHealth( float flHealth, int bitsDamageType ) { return 1; }
|
||||
int CBaseEntity :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) { return 1; }
|
||||
CBaseEntity *CBaseEntity::GetNextTarget( void ) { return NULL; }
|
||||
int CBaseEntity::Save( CSave &save ) { return 1; }
|
||||
int CBaseEntity::Restore( CRestore &restore ) { return 1; }
|
||||
void CBaseEntity::SetObjectCollisionBox( void ) { }
|
||||
int CBaseEntity :: Intersects( CBaseEntity *pOther ) { return 0; }
|
||||
void CBaseEntity :: MakeDormant( void ) { }
|
||||
int CBaseEntity :: IsDormant( void ) { return 0; }
|
||||
BOOL CBaseEntity :: IsInWorld( void ) { return TRUE; }
|
||||
int CBaseEntity::ShouldToggle( USE_TYPE useType, BOOL currentState ) { return 0; }
|
||||
int CBaseEntity :: DamageDecal( int bitsDamageType ) { return -1; }
|
||||
CBaseEntity * CBaseEntity::Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner ) { return NULL; }
|
||||
void CBaseEntity::SUB_Remove( void ) { }
|
||||
|
||||
// CBaseDelay Stubs
|
||||
void CBaseDelay :: KeyValue( struct KeyValueData_s * ) { }
|
||||
int CBaseDelay::Restore( class CRestore & ) { return 1; }
|
||||
int CBaseDelay::Save( class CSave & ) { return 1; }
|
||||
|
||||
// CBaseAnimating Stubs
|
||||
int CBaseAnimating::Restore( class CRestore & ) { return 1; }
|
||||
int CBaseAnimating::Save( class CSave & ) { return 1; }
|
||||
|
||||
// DEBUG Stubs
|
||||
edict_t *DBG_EntOfVars( const entvars_t *pev ) { return NULL; }
|
||||
void DBG_AssertFunction(BOOL fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage) { }
|
||||
|
||||
// UTIL_* Stubs
|
||||
void UTIL_PrecacheOther( const char *szClassname ) { }
|
||||
void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, int amount ) { }
|
||||
void UTIL_DecalTrace( TraceResult *pTrace, int decalNumber ) { }
|
||||
void UTIL_GunshotDecalTrace( TraceResult *pTrace, int decalNumber ) { }
|
||||
void UTIL_MakeVectors( const Vector &vecAngles ) { }
|
||||
BOOL UTIL_IsValidEntity( edict_t *pent ) { return TRUE; }
|
||||
void UTIL_SetOrigin( entvars_t *, const Vector &org ) { }
|
||||
BOOL UTIL_GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) { return TRUE; }
|
||||
void UTIL_LogPrintf(char *,...) { }
|
||||
void UTIL_ClientPrintAll( int,char const *,char const *,char const *,char const *,char const *) { }
|
||||
void ClientPrint( entvars_t *client, int msg_dest, const char *msg_name, const char *param1, const char *param2, const char *param3, const char *param4 ) { }
|
||||
|
||||
// CBaseToggle Stubs
|
||||
int CBaseToggle::Restore( class CRestore & ) { return 1; }
|
||||
int CBaseToggle::Save( class CSave & ) { return 1; }
|
||||
void CBaseToggle :: KeyValue( struct KeyValueData_s * ) { }
|
||||
|
||||
// CGrenade Stubs
|
||||
void CGrenade::BounceSound( void ) { }
|
||||
void CGrenade::Explode( Vector, Vector ) { }
|
||||
void CGrenade::Explode( TraceResult *, int ) { }
|
||||
void CGrenade::Killed( entvars_t *, int ) { }
|
||||
void CGrenade::Spawn( void ) { }
|
||||
|
||||
CBaseEntity* CBaseMonster :: CheckTraceHullAttack( float flDist, int iDamage, int iDmgType ) { return NULL; }
|
||||
void CBaseMonster :: Look ( int iDistance ) { }
|
||||
float CBaseAnimating :: StudioFrameAdvance ( float flInterval ) { return 0.0; }
|
||||
int CBaseMonster::IRelationship ( CBaseEntity *pTarget ) { return 0; }
|
||||
CBaseEntity *CBaseMonster :: BestVisibleEnemy ( void ) { return NULL; }
|
||||
BOOL CBaseMonster :: FInViewCone ( CBaseEntity *pEntity ) { return FALSE; }
|
||||
BOOL CBaseMonster :: FInViewCone ( Vector *pOrigin ) { return FALSE; }
|
||||
BOOL CBaseEntity :: FVisible ( CBaseEntity *pEntity ) { return FALSE; }
|
||||
BOOL CBaseEntity :: FVisible ( const Vector &vecOrigin ) { return FALSE; }
|
||||
void CBaseMonster :: MakeIdealYaw( Vector vecTarget ) { }
|
||||
float CBaseMonster::ChangeYaw ( int yawSpeed ) { return 0; }
|
||||
int CBaseAnimating :: LookupActivity ( int activity ) { return 0; }
|
||||
int CBaseAnimating :: LookupActivityHeaviest ( int activity ) { return 0; }
|
||||
int CBaseAnimating :: LookupSequence ( const char *label ) { return 0; }
|
||||
void CBaseAnimating :: ResetSequenceInfo ( ) { }
|
||||
BOOL CBaseAnimating :: GetSequenceFlags( ) { return FALSE; }
|
||||
void CBaseAnimating :: DispatchAnimEvents ( float flInterval ) { }
|
||||
float CBaseAnimating :: SetBoneController ( int iController, float flValue ) { return 0.0; }
|
||||
void CBaseAnimating :: InitBoneControllers ( void ) { }
|
||||
float CBaseAnimating :: SetBlending ( int iBlender, float flValue ) { return 0; }
|
||||
void CBaseAnimating :: GetBonePosition ( int iBone, Vector &origin, Vector &angles ) { }
|
||||
void CBaseAnimating :: GetAttachment ( int iAttachment, Vector &origin, Vector &angles ) { }
|
||||
int CBaseAnimating :: FindTransition( int iEndingSequence, int iGoalSequence, int *piDir ) { return -1; }
|
||||
void CBaseAnimating :: GetAutomovement( Vector &origin, Vector &angles, float flInterval ) { }
|
||||
void CBaseAnimating :: SetBodygroup( int iGroup, int iValue ) { }
|
||||
int CBaseAnimating :: GetBodygroup( int iGroup ) { return 0; }
|
||||
void CBaseEntity::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { }
|
||||
void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker ) { }
|
||||
void CBaseEntity :: TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ) { }
|
||||
void CBaseMonster :: MakeDamageBloodDecal ( int cCount, float flNoise, TraceResult *ptr, const Vector &vecDir ) { }
|
||||
void CBaseMonster::ReportAIState( void ) { }
|
||||
void CBaseMonster :: KeyValue( KeyValueData *pkvd ) { }
|
||||
BOOL CBaseMonster :: FCheckAITrigger ( void ) { return FALSE; }
|
||||
void CBaseMonster::CorpseFallThink( void ) { }
|
||||
void CBaseMonster :: MonsterInitDead( void ) { }
|
||||
void CBaseMonster :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { }
|
||||
BOOL CBaseMonster :: ShouldFadeOnDeath( void ) { return FALSE; }
|
||||
void CBaseMonster :: RadiusDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ) { }
|
||||
void CBaseMonster :: RadiusDamage( Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ) { }
|
||||
void CBaseMonster::FadeMonster( void ) { }
|
||||
void CBaseMonster :: GibMonster( void ) { }
|
||||
BOOL CBaseMonster :: HasHumanGibs( void ) { return FALSE; }
|
||||
BOOL CBaseMonster :: HasAlienGibs( void ) { return FALSE; }
|
||||
Activity CBaseMonster :: GetDeathActivity ( void ) { return ACT_DIE_HEADSHOT; }
|
||||
void CBaseMonster::BecomeDead( void ) {}
|
||||
void CBaseMonster :: Killed( entvars_t *pevAttacker, int iGib ) {}
|
||||
int CBaseMonster :: TakeHealth (float flHealth, int bitsDamageType) { return 0; }
|
||||
int CBaseMonster :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) { return 0; }
|
||||
|
||||
int TrainSpeed(int iSpeed, int iMax) { return 0; }
|
||||
void CBasePlayer :: DeathSound( void ) { }
|
||||
int CBasePlayer :: TakeHealth( float flHealth, int bitsDamageType ) { return 0; }
|
||||
void CBasePlayer :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { }
|
||||
int CBasePlayer :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) { return 0; }
|
||||
void CBasePlayer::RemoveAllItems( BOOL removeSuit ) { }
|
||||
void CBasePlayer::SetAnimation( PLAYER_ANIM playerAnim ) { }
|
||||
void CBasePlayer::WaterMove() { }
|
||||
BOOL CBasePlayer::IsOnLadder( void ) { return FALSE; }
|
||||
void CBasePlayer::PlayerDeathThink(void) { }
|
||||
void CBasePlayer::StartDeathCam( void ) { }
|
||||
void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) { }
|
||||
void CBasePlayer::PlayerUse ( void ) { }
|
||||
void CBasePlayer::Jump() { }
|
||||
void CBasePlayer::Duck( ) { }
|
||||
int CBasePlayer::Classify ( void ) { return 0; }
|
||||
void CBasePlayer :: PlayStepSound(int step, float fvol) { }
|
||||
void CBasePlayer :: UpdateStepSound( void ) { }
|
||||
void CBasePlayer::PreThink(void) { }
|
||||
void CBasePlayer::CheckTimeBasedDamage() { }
|
||||
void CBasePlayer :: UpdateGeigerCounter( void ) { }
|
||||
void CBasePlayer::CheckSuitUpdate() { }
|
||||
void CBasePlayer::SetSuitUpdate(char *name, int fgroup, int iNoRepeatTime) { }
|
||||
void CBasePlayer :: UpdatePlayerSound ( void ) { }
|
||||
void CBasePlayer::PostThink() { }
|
||||
void CBasePlayer :: Precache( void ) { }
|
||||
int CBasePlayer::Save( CSave &save ) { return 0; }
|
||||
void CBasePlayer::RenewItems(void) { }
|
||||
int CBasePlayer::Restore( CRestore &restore ) { return 0; }
|
||||
void CBasePlayer::SelectNextItem( int iItem ) { }
|
||||
BOOL CBasePlayer::HasWeapons( void ) { return FALSE; }
|
||||
void CBasePlayer::SelectPrevItem( int iItem ) { }
|
||||
CBaseEntity *FindEntityForward( CBaseEntity *pMe ) { return NULL; }
|
||||
BOOL CBasePlayer :: FlashlightIsOn( void ) { return FALSE; }
|
||||
void CBasePlayer :: FlashlightTurnOn( void ) { }
|
||||
void CBasePlayer :: FlashlightTurnOff( void ) { }
|
||||
void CBasePlayer :: ForceClientDllUpdate( void ) { }
|
||||
void CBasePlayer::ImpulseCommands( ) { }
|
||||
void CBasePlayer::CheatImpulseCommands( int iImpulse ) { }
|
||||
int CBasePlayer::AddPlayerItem( CBasePlayerItem *pItem ) { return FALSE; }
|
||||
int CBasePlayer::RemovePlayerItem( CBasePlayerItem *pItem ) { return FALSE; }
|
||||
void CBasePlayer::ItemPreFrame() { }
|
||||
void CBasePlayer::ItemPostFrame() { }
|
||||
int CBasePlayer::AmmoInventory( int iAmmoIndex ) { return -1; }
|
||||
int CBasePlayer::GetAmmoIndex(const char *psz) { return -1; }
|
||||
void CBasePlayer::SendAmmoUpdate(void) { }
|
||||
void CBasePlayer :: UpdateClientData( void ) { }
|
||||
BOOL CBasePlayer :: FBecomeProne ( void ) { return TRUE; }
|
||||
void CBasePlayer :: BarnacleVictimBitten ( entvars_t *pevBarnacle ) { }
|
||||
void CBasePlayer :: BarnacleVictimReleased ( void ) { }
|
||||
int CBasePlayer :: Illumination( void ) { return 0; }
|
||||
void CBasePlayer :: EnableControl(BOOL fControl) { }
|
||||
Vector CBasePlayer :: GetAutoaimVector( float flDelta ) { return g_vecZero; }
|
||||
Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flDelta ) { return g_vecZero; }
|
||||
void CBasePlayer :: ResetAutoaim( ) { }
|
||||
void CBasePlayer :: SetCustomDecalFrames( int nFrames ) { }
|
||||
int CBasePlayer :: GetCustomDecalFrames( void ) { return -1; }
|
||||
void CBasePlayer::DropPlayerItem ( char *pszItemName ) { }
|
||||
BOOL CBasePlayer::HasPlayerItem( CBasePlayerItem *pCheckItem ) { return FALSE; }
|
||||
BOOL CBasePlayer :: SwitchWeapon( CBasePlayerItem *pWeapon ) { return FALSE; }
|
||||
Vector CBasePlayer :: GetGunPosition( void ) { return g_vecZero; }
|
||||
const char *CBasePlayer::TeamID( void ) { return ""; }
|
||||
int CBasePlayer :: GiveAmmo( int iCount, char *szName, int iMax ) { return 0; }
|
||||
void CBasePlayer::AddPoints( int score, BOOL bAllowNegativeScore ) { }
|
||||
void CBasePlayer::AddPointsToTeam( int score, BOOL bAllowNegativeScore ) { }
|
||||
|
||||
void ClearMultiDamage(void) { }
|
||||
void ApplyMultiDamage(entvars_t *pevInflictor, entvars_t *pevAttacker ) { }
|
||||
void AddMultiDamage( entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType) { }
|
||||
void SpawnBlood(Vector vecSpot, int bloodColor, float flDamage) { }
|
||||
int DamageDecal( CBaseEntity *pEntity, int bitsDamageType ) { return 0; }
|
||||
void DecalGunshot( TraceResult *pTrace, int iBulletType ) { }
|
||||
void EjectBrass ( const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype ) { }
|
||||
void AddAmmoNameToAmmoRegistry( const char *szAmmoname ) { }
|
||||
int CBasePlayerItem::Restore( class CRestore & ) { return 1; }
|
||||
int CBasePlayerItem::Save( class CSave & ) { return 1; }
|
||||
int CBasePlayerWeapon::Restore( class CRestore & ) { return 1; }
|
||||
int CBasePlayerWeapon::Save( class CSave & ) { return 1; }
|
||||
void CBasePlayerItem :: SetObjectCollisionBox( void ) { }
|
||||
void CBasePlayerItem :: FallInit( void ) { }
|
||||
void CBasePlayerItem::FallThink ( void ) { }
|
||||
void CBasePlayerItem::Materialize( void ) { }
|
||||
void CBasePlayerItem::AttemptToMaterialize( void ) { }
|
||||
void CBasePlayerItem :: CheckRespawn ( void ) { }
|
||||
CBaseEntity* CBasePlayerItem::Respawn( void ) { return NULL; }
|
||||
void CBasePlayerItem::DefaultTouch( CBaseEntity *pOther ) { }
|
||||
void CBasePlayerItem::DestroyItem( void ) { }
|
||||
int CBasePlayerItem::AddToPlayer( CBasePlayer *pPlayer ) { return TRUE; }
|
||||
void CBasePlayerItem::Drop( void ) { }
|
||||
void CBasePlayerItem::Kill( void ) { }
|
||||
void CBasePlayerItem::Holster( int skiplocal ) { }
|
||||
void CBasePlayerItem::AttachToPlayer ( CBasePlayer *pPlayer ) { }
|
||||
int CBasePlayerWeapon::AddDuplicate( CBasePlayerItem *pOriginal ) { return 0; }
|
||||
int CBasePlayerWeapon::AddToPlayer( CBasePlayer *pPlayer ) { return FALSE; }
|
||||
int CBasePlayerWeapon::UpdateClientData( CBasePlayer *pPlayer ) { return 0; }
|
||||
BOOL CBasePlayerWeapon :: AddPrimaryAmmo( int iCount, char *szName, int iMaxClip, int iMaxCarry ) { return TRUE; }
|
||||
BOOL CBasePlayerWeapon :: AddSecondaryAmmo( int iCount, char *szName, int iMax ) { return TRUE; }
|
||||
BOOL CBasePlayerWeapon :: IsUseable( void ) { return TRUE; }
|
||||
int CBasePlayerWeapon::PrimaryAmmoIndex( void ) { return -1; }
|
||||
int CBasePlayerWeapon::SecondaryAmmoIndex( void ) { return -1; }
|
||||
void CBasePlayerAmmo::Spawn( void ) { }
|
||||
CBaseEntity* CBasePlayerAmmo::Respawn( void ) { return this; }
|
||||
void CBasePlayerAmmo::Materialize( void ) { }
|
||||
void CBasePlayerAmmo :: DefaultTouch( CBaseEntity *pOther ) { }
|
||||
int CBasePlayerWeapon::ExtractAmmo( CBasePlayerWeapon *pWeapon ) { return 0; }
|
||||
int CBasePlayerWeapon::ExtractClipAmmo( CBasePlayerWeapon *pWeapon ) { return 0; }
|
||||
void CBasePlayerWeapon::RetireWeapon( void ) { }
|
57
cl_dll/hl/hl_events.cpp
Normal file
57
cl_dll/hl/hl_events.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#include "../hud.h"
|
||||
#include "../cl_util.h"
|
||||
#include "event_api.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
// HLDM
|
||||
void EV_FireGlock1( struct event_args_s *args );
|
||||
void EV_FireGlock2( struct event_args_s *args );
|
||||
void EV_FireShotGunSingle( struct event_args_s *args );
|
||||
void EV_FireShotGunDouble( struct event_args_s *args );
|
||||
void EV_FireMP5( struct event_args_s *args );
|
||||
void EV_FirePython( struct event_args_s *args );
|
||||
void EV_FireGauss( struct event_args_s *args );
|
||||
void EV_SpinGauss( struct event_args_s *args );
|
||||
void EV_TrainPitchAdjust( struct event_args_s *args );
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
Game_HookEvents
|
||||
|
||||
Associate script file name with callback functions. Callback's must be extern "C" so
|
||||
the engine doesn't get confused about name mangling stuff. Note that the format is
|
||||
always the same. Of course, a clever mod team could actually embed parameters, behavior
|
||||
into the actual .sc files and create a .sc file parser and hook their functionality through
|
||||
that.. i.e., a scripting system.
|
||||
|
||||
That was what we were going to do, but we ran out of time...oh well.
|
||||
======================
|
||||
*/
|
||||
void Game_HookEvents( void )
|
||||
{
|
||||
gEngfuncs.pfnHookEvent( "events/glock1.sc", EV_FireGlock1 );
|
||||
gEngfuncs.pfnHookEvent( "events/glock2.sc", EV_FireGlock2 );
|
||||
gEngfuncs.pfnHookEvent( "events/shotgun1.sc", EV_FireShotGunSingle );
|
||||
gEngfuncs.pfnHookEvent( "events/shotgun2.sc", EV_FireShotGunDouble );
|
||||
gEngfuncs.pfnHookEvent( "events/mp5.sc", EV_FireMP5 );
|
||||
gEngfuncs.pfnHookEvent( "events/python.sc", EV_FirePython );
|
||||
gEngfuncs.pfnHookEvent( "events/gauss.sc", EV_FireGauss );
|
||||
gEngfuncs.pfnHookEvent( "events/gaussspin.sc", EV_SpinGauss );
|
||||
gEngfuncs.pfnHookEvent( "events/train.sc", EV_TrainPitchAdjust );
|
||||
}
|
28
cl_dll/hl/hl_objects.cpp
Normal file
28
cl_dll/hl/hl_objects.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#include "../hud.h"
|
||||
#include "../cl_util.h"
|
||||
#include "../demo.h"
|
||||
|
||||
/*
|
||||
=====================
|
||||
Game_AddObjects
|
||||
|
||||
Add game specific, client-side objects here
|
||||
=====================
|
||||
*/
|
||||
void Game_AddObjects( void )
|
||||
{
|
||||
}
|
822
cl_dll/hl/hl_weapons.cpp
Normal file
822
cl_dll/hl/hl_weapons.cpp
Normal file
@ -0,0 +1,822 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
#include "player.h"
|
||||
|
||||
#include "usercmd.h"
|
||||
#include "entity_state.h"
|
||||
#include "demo_api.h"
|
||||
#include "pm_defs.h"
|
||||
#include "event_api.h"
|
||||
#include "r_efx.h"
|
||||
|
||||
#include "../hud_iface.h"
|
||||
#include "../com_weapons.h"
|
||||
#include "../demo.h"
|
||||
|
||||
extern globalvars_t *gpGlobals;
|
||||
|
||||
// Pool of client side entities/entvars_t
|
||||
static entvars_t ev[ 32 ];
|
||||
static int num_ents = 0;
|
||||
|
||||
// The entity we'll use to represent the local client
|
||||
static CBasePlayer player;
|
||||
|
||||
// Local version of game .dll global variables ( time, etc. )
|
||||
static globalvars_t Globals;
|
||||
|
||||
static CBasePlayerWeapon *g_pWpns[ 32 ];
|
||||
|
||||
// HLDM Weapon placeholder entities.
|
||||
CGlock g_Glock;
|
||||
|
||||
/*
|
||||
======================
|
||||
AlertMessage
|
||||
|
||||
Print debug messages to console
|
||||
======================
|
||||
*/
|
||||
void AlertMessage( ALERT_TYPE atype, char *szFmt, ... )
|
||||
{
|
||||
va_list argptr;
|
||||
static char string[1024];
|
||||
|
||||
va_start (argptr, szFmt);
|
||||
vsprintf (string, szFmt,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
gEngfuncs.Con_Printf( "cl: " );
|
||||
gEngfuncs.Con_Printf( string );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
HUD_PrepEntity
|
||||
|
||||
Links the raw entity to an entvars_s holder. If a player is passed in as the owner, then
|
||||
we set up the m_pPlayer field.
|
||||
=====================
|
||||
*/
|
||||
void HUD_PrepEntity( CBaseEntity *pEntity, CBasePlayer *pWeaponOwner )
|
||||
{
|
||||
memset( &ev[ num_ents ], 0, sizeof( entvars_t ) );
|
||||
pEntity->pev = &ev[ num_ents++ ];
|
||||
|
||||
pEntity->Precache();
|
||||
pEntity->Spawn();
|
||||
|
||||
if ( pWeaponOwner )
|
||||
{
|
||||
ItemInfo info;
|
||||
|
||||
((CBasePlayerWeapon *)pEntity)->m_pPlayer = pWeaponOwner;
|
||||
|
||||
((CBasePlayerWeapon *)pEntity)->GetItemInfo( &info );
|
||||
|
||||
g_pWpns[ info.iId ] = (CBasePlayerWeapon *)pEntity;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBaseEntity :: Killed
|
||||
|
||||
If weapons code "kills" an entity, just set its effects to EF_NODRAW
|
||||
=====================
|
||||
*/
|
||||
void CBaseEntity :: Killed( entvars_t *pevAttacker, int iGib )
|
||||
{
|
||||
pev->effects |= EF_NODRAW;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBasePlayerWeapon :: DefaultReload
|
||||
=====================
|
||||
*/
|
||||
BOOL CBasePlayerWeapon :: DefaultReload( int iClipSize, int iAnim, float fDelay )
|
||||
{
|
||||
#if 0 // FIXME, need to know primary ammo to get this right
|
||||
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
|
||||
return FALSE;
|
||||
|
||||
int j = min(iClipSize - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]);
|
||||
|
||||
if (j == 0)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + fDelay;
|
||||
|
||||
//!!UNDONE -- reload sound goes here !!!
|
||||
SendWeaponAnim( iAnim );
|
||||
|
||||
m_fInReload = TRUE;
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 3;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBasePlayerWeapon :: CanDeploy
|
||||
=====================
|
||||
*/
|
||||
BOOL CBasePlayerWeapon :: CanDeploy( void )
|
||||
{
|
||||
BOOL bHasAmmo = 0;
|
||||
|
||||
if ( !pszAmmo1() )
|
||||
{
|
||||
// this weapon doesn't use ammo, can always deploy.
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( pszAmmo1() )
|
||||
{
|
||||
bHasAmmo |= (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] != 0);
|
||||
}
|
||||
if ( pszAmmo2() )
|
||||
{
|
||||
bHasAmmo |= (m_pPlayer->m_rgAmmo[m_iSecondaryAmmoType] != 0);
|
||||
}
|
||||
if (m_iClip > 0)
|
||||
{
|
||||
bHasAmmo |= 1;
|
||||
}
|
||||
if (!bHasAmmo)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBasePlayerWeapon :: DefaultDeploy
|
||||
|
||||
=====================
|
||||
*/
|
||||
BOOL CBasePlayerWeapon :: DefaultDeploy( char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal )
|
||||
{
|
||||
if ( !CanDeploy() )
|
||||
return FALSE;
|
||||
|
||||
gEngfuncs.CL_LoadModel( szViewModel, &m_pPlayer->pev->viewmodel );
|
||||
|
||||
SendWeaponAnim( iAnim );
|
||||
|
||||
m_pPlayer->m_flNextAttack = 0.5;
|
||||
m_flTimeWeaponIdle = 1.0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBasePlayerWeapon :: PlayEmptySound
|
||||
|
||||
=====================
|
||||
*/
|
||||
BOOL CBasePlayerWeapon :: PlayEmptySound( void )
|
||||
{
|
||||
if (m_iPlayEmptySound)
|
||||
{
|
||||
HUD_PlaySound( "weapons/357_cock1.wav", 0.8 );
|
||||
m_iPlayEmptySound = 0;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBasePlayerWeapon :: ResetEmptySound
|
||||
|
||||
=====================
|
||||
*/
|
||||
void CBasePlayerWeapon :: ResetEmptySound( void )
|
||||
{
|
||||
m_iPlayEmptySound = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBasePlayerWeapon::Holster
|
||||
|
||||
Put away weapon
|
||||
=====================
|
||||
*/
|
||||
void CBasePlayerWeapon::Holster( int skiplocal /* = 0 */ )
|
||||
{
|
||||
m_fInReload = FALSE; // cancel any reload in progress.
|
||||
m_pPlayer->pev->viewmodel = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBasePlayerWeapon::SendWeaponAnim
|
||||
|
||||
Animate weapon model
|
||||
=====================
|
||||
*/
|
||||
void CBasePlayerWeapon::SendWeaponAnim( int iAnim, int skiplocal )
|
||||
{
|
||||
m_pPlayer->pev->weaponanim = iAnim;
|
||||
|
||||
int body = 0;
|
||||
|
||||
HUD_SendWeaponAnim( iAnim, body, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBasePlayerWeapon::ItemPostFrame
|
||||
|
||||
Handles weapon firing, reloading, etc.
|
||||
=====================
|
||||
*/
|
||||
void CBasePlayerWeapon::ItemPostFrame( void )
|
||||
{
|
||||
if ((m_fInReload) && (m_pPlayer->m_flNextAttack <= 0.0))
|
||||
{
|
||||
#if 0 // FIXME, need ammo on client to make this work right
|
||||
// complete the reload.
|
||||
int j = min( iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]);
|
||||
|
||||
// Add them to the clip
|
||||
m_iClip += j;
|
||||
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= j;
|
||||
#else
|
||||
m_iClip += 10;
|
||||
#endif
|
||||
m_fInReload = FALSE;
|
||||
}
|
||||
|
||||
if ((m_pPlayer->pev->button & IN_ATTACK2) && (m_flNextSecondaryAttack <= 0.0))
|
||||
{
|
||||
if ( pszAmmo2() && !m_pPlayer->m_rgAmmo[SecondaryAmmoIndex()] )
|
||||
{
|
||||
m_fFireOnEmpty = TRUE;
|
||||
}
|
||||
|
||||
SecondaryAttack();
|
||||
m_pPlayer->pev->button &= ~IN_ATTACK2;
|
||||
}
|
||||
else if ((m_pPlayer->pev->button & IN_ATTACK) && (m_flNextPrimaryAttack <= 0.0))
|
||||
{
|
||||
if ( (m_iClip == 0 && pszAmmo1()) || (iMaxClip() == -1 && !m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()] ) )
|
||||
{
|
||||
m_fFireOnEmpty = TRUE;
|
||||
}
|
||||
|
||||
PrimaryAttack();
|
||||
}
|
||||
else if ( m_pPlayer->pev->button & IN_RELOAD && iMaxClip() != WEAPON_NOCLIP && !m_fInReload )
|
||||
{
|
||||
// reload when reload is pressed, or if no buttons are down and weapon is empty.
|
||||
Reload();
|
||||
}
|
||||
else if ( !(m_pPlayer->pev->button & (IN_ATTACK|IN_ATTACK2) ) )
|
||||
{
|
||||
// no fire buttons down
|
||||
|
||||
m_fFireOnEmpty = FALSE;
|
||||
|
||||
// weapon is useable. Reload if empty and weapon has waited as long as it has to after firing
|
||||
if ( m_iClip == 0 && !(iFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < 0.0 )
|
||||
{
|
||||
Reload();
|
||||
return;
|
||||
}
|
||||
|
||||
WeaponIdle( );
|
||||
return;
|
||||
}
|
||||
|
||||
// catch all
|
||||
if ( ShouldWeaponIdle() )
|
||||
{
|
||||
WeaponIdle();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBasePlayer::SelectItem
|
||||
|
||||
Switch weapons
|
||||
=====================
|
||||
*/
|
||||
void CBasePlayer::SelectItem(const char *pstr)
|
||||
{
|
||||
if (!pstr)
|
||||
return;
|
||||
|
||||
CBasePlayerItem *pItem = NULL;
|
||||
|
||||
if (!pItem)
|
||||
return;
|
||||
|
||||
|
||||
if (pItem == m_pActiveItem)
|
||||
return;
|
||||
|
||||
if (m_pActiveItem)
|
||||
m_pActiveItem->Holster( );
|
||||
|
||||
m_pLastItem = m_pActiveItem;
|
||||
m_pActiveItem = pItem;
|
||||
|
||||
if (m_pActiveItem)
|
||||
{
|
||||
m_pActiveItem->Deploy( );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBasePlayer::SelectLastItem
|
||||
|
||||
=====================
|
||||
*/
|
||||
void CBasePlayer::SelectLastItem(void)
|
||||
{
|
||||
if (!m_pLastItem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_pActiveItem && !m_pActiveItem->CanHolster() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pActiveItem)
|
||||
m_pActiveItem->Holster( );
|
||||
|
||||
CBasePlayerItem *pTemp = m_pActiveItem;
|
||||
m_pActiveItem = m_pLastItem;
|
||||
m_pLastItem = pTemp;
|
||||
m_pActiveItem->Deploy( );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBasePlayer::Killed
|
||||
|
||||
=====================
|
||||
*/
|
||||
void CBasePlayer::Killed( entvars_t *pevAttacker, int iGib )
|
||||
{
|
||||
// Holster weapon immediately, to allow it to cleanup
|
||||
if (m_pActiveItem)
|
||||
m_pActiveItem->Holster( );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBasePlayer::Spawn
|
||||
|
||||
=====================
|
||||
*/
|
||||
void CBasePlayer::Spawn( void )
|
||||
{
|
||||
if (m_pActiveItem)
|
||||
m_pActiveItem->Deploy( );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
UTIL_TraceLine
|
||||
|
||||
Don't actually trace, but act like the trace didn't hit anything.
|
||||
=====================
|
||||
*/
|
||||
void UTIL_TraceLine( const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, edict_t *pentIgnore, TraceResult *ptr )
|
||||
{
|
||||
memset( ptr, 0, sizeof( *ptr ) );
|
||||
ptr->flFraction = 1.0;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
UTIL_ParticleBox
|
||||
|
||||
For debugging, draw a box around a player made out of particles
|
||||
=====================
|
||||
*/
|
||||
void UTIL_ParticleBox( CBasePlayer *player, float *mins, float *maxs, float life, unsigned char r, unsigned char g, unsigned char b )
|
||||
{
|
||||
int i;
|
||||
vec3_t mmin, mmax;
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
mmin[ i ] = player->pev->origin[ i ] + mins[ i ];
|
||||
mmax[ i ] = player->pev->origin[ i ] + maxs[ i ];
|
||||
}
|
||||
|
||||
gEngfuncs.pEfxAPI->R_ParticleBox( (float *)&mmin, (float *)&mmax, 5.0, 0, 255, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
UTIL_ParticleBoxes
|
||||
|
||||
For debugging, draw boxes for other collidable players
|
||||
=====================
|
||||
*/
|
||||
void UTIL_ParticleBoxes( void )
|
||||
{
|
||||
int idx;
|
||||
physent_t *pe;
|
||||
cl_entity_t *player;
|
||||
vec3_t mins, maxs;
|
||||
|
||||
gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true );
|
||||
|
||||
// Store off the old count
|
||||
gEngfuncs.pEventAPI->EV_PushPMStates();
|
||||
|
||||
player = gEngfuncs.GetLocalPlayer();
|
||||
// Now add in all of the players.
|
||||
gEngfuncs.pEventAPI->EV_SetSolidPlayers ( player->index - 1 );
|
||||
|
||||
for ( idx = 1; idx < 100; idx++ )
|
||||
{
|
||||
pe = gEngfuncs.pEventAPI->EV_GetPhysent( idx );
|
||||
if ( !pe )
|
||||
break;
|
||||
|
||||
if ( pe->info >= 1 && pe->info <= gEngfuncs.GetMaxClients() )
|
||||
{
|
||||
mins = pe->origin + pe->mins;
|
||||
maxs = pe->origin + pe->maxs;
|
||||
|
||||
gEngfuncs.pEfxAPI->R_ParticleBox( (float *)&mins, (float *)&maxs, 0, 0, 255, 2.0 );
|
||||
}
|
||||
}
|
||||
|
||||
gEngfuncs.pEventAPI->EV_PopPMStates();
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
UTIL_ParticleLine
|
||||
|
||||
For debugging, draw a line made out of particles
|
||||
=====================
|
||||
*/
|
||||
void UTIL_ParticleLine( CBasePlayer *player, float *start, float *end, float life, unsigned char r, unsigned char g, unsigned char b )
|
||||
{
|
||||
gEngfuncs.pEfxAPI->R_ParticleLine( start, end, r, g, b, life );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CBasePlayerWeapon::PrintState
|
||||
|
||||
For debugging, print out state variables to log file
|
||||
=====================
|
||||
*/
|
||||
void CBasePlayerWeapon::PrintState( void )
|
||||
{
|
||||
COM_Log( "c:\\hl.log", "%.4f ", gpGlobals->time );
|
||||
COM_Log( "c:\\hl.log", "%.4f ", m_pPlayer->m_flNextAttack );
|
||||
COM_Log( "c:\\hl.log", "%.4f ", m_flNextPrimaryAttack );
|
||||
COM_Log( "c:\\hl.log", "%.4f ", m_flTimeWeaponIdle - gpGlobals->time);
|
||||
COM_Log( "c:\\hl.log", "%i ", m_iClip );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
HUD_InitClientWeapons
|
||||
|
||||
Set up weapons, player and functions needed to run weapons code client-side.
|
||||
=====================
|
||||
*/
|
||||
void HUD_InitClientWeapons( void )
|
||||
{
|
||||
static int initialized = 0;
|
||||
if ( initialized )
|
||||
return;
|
||||
|
||||
initialized = 1;
|
||||
|
||||
// Set up pointer ( dummy object )
|
||||
gpGlobals = &Globals;
|
||||
|
||||
// Fill in current time ( probably not needed )
|
||||
gpGlobals->time = gEngfuncs.GetClientTime();
|
||||
|
||||
// Fake functions
|
||||
g_engfuncs.pfnPrecacheModel = stub_PrecacheModel;
|
||||
g_engfuncs.pfnPrecacheSound = stub_PrecacheSound;
|
||||
g_engfuncs.pfnPrecacheEvent = stub_PrecacheEvent;
|
||||
g_engfuncs.pfnNameForFunction = stub_NameForFunction;
|
||||
g_engfuncs.pfnSetModel = stub_SetModel;
|
||||
g_engfuncs.pfnSetClientMaxspeed = HUD_SetMaxSpeed;
|
||||
|
||||
// Handled locally
|
||||
g_engfuncs.pfnPlaybackEvent = HUD_PlaybackEvent;
|
||||
g_engfuncs.pfnAlertMessage = AlertMessage;
|
||||
|
||||
// Pass through to engine
|
||||
g_engfuncs.pfnPrecacheEvent = gEngfuncs.pfnPrecacheEvent;
|
||||
g_engfuncs.pfnRandomFloat = gEngfuncs.pfnRandomFloat;
|
||||
g_engfuncs.pfnRandomLong = gEngfuncs.pfnRandomLong;
|
||||
|
||||
// Allocate a slot for the local player
|
||||
HUD_PrepEntity( &player , NULL );
|
||||
|
||||
// Allocate slot(s) for each weapon that we are going to be predicting
|
||||
HUD_PrepEntity( &g_Glock , &player );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
HUD_WeaponsPostThink
|
||||
|
||||
Run Weapon firing code on client
|
||||
=====================
|
||||
*/
|
||||
void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cmd, double time, unsigned int random_seed )
|
||||
{
|
||||
int i;
|
||||
int buttonsChanged;
|
||||
CBasePlayerWeapon *pWeapon = NULL;
|
||||
CBasePlayerWeapon *pCurrent;
|
||||
weapon_data_t nulldata, *pfrom, *pto;
|
||||
static int lasthealth;
|
||||
|
||||
memset( &nulldata, 0, sizeof( nulldata ) );
|
||||
|
||||
HUD_InitClientWeapons();
|
||||
|
||||
// Get current clock
|
||||
gpGlobals->time = time;
|
||||
|
||||
// Fill in data based on selected weapon
|
||||
// FIXME, make this a method in each weapon? where you pass in an entity_state_t *?
|
||||
switch ( from->client.m_iId )
|
||||
{
|
||||
case WEAPON_GLOCK:
|
||||
pWeapon = &g_Glock;
|
||||
break;
|
||||
}
|
||||
|
||||
// We are not predicting the current weapon, just bow out here.
|
||||
if ( !pWeapon )
|
||||
return;
|
||||
|
||||
for ( i = 0; i < 32; i++ )
|
||||
{
|
||||
pCurrent = g_pWpns[ i ];
|
||||
if ( !pCurrent )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
pfrom = &from->weapondata[ i ];
|
||||
|
||||
pCurrent->m_fInReload = pfrom->m_fInReload;
|
||||
pCurrent->m_iClip = pfrom->m_iClip;
|
||||
pCurrent->m_flNextPrimaryAttack = pfrom->m_flNextPrimaryAttack;
|
||||
pCurrent->m_flNextSecondaryAttack = pfrom->m_flNextSecondaryAttack;
|
||||
pCurrent->m_flTimeWeaponIdle = pfrom->m_flTimeWeaponIdle;
|
||||
}
|
||||
|
||||
// For random weapon events, use this seed to seed random # generator
|
||||
player.random_seed = random_seed;
|
||||
|
||||
// Get old buttons from previous state.
|
||||
player.m_afButtonLast = from->playerstate.oldbuttons;
|
||||
|
||||
// Which buttsons chave changed
|
||||
buttonsChanged = (player.m_afButtonLast ^ cmd->buttons); // These buttons have changed this frame
|
||||
|
||||
// Debounced button codes for pressed/released
|
||||
// The changed ones still down are "pressed"
|
||||
player.m_afButtonPressed = buttonsChanged & cmd->buttons;
|
||||
// The ones not down are "released"
|
||||
player.m_afButtonReleased = buttonsChanged & (~cmd->buttons);
|
||||
|
||||
// Set player variables that weapons code might check/alter
|
||||
player.pev->button = cmd->buttons;
|
||||
|
||||
player.pev->velocity = from->client.velocity;
|
||||
player.pev->flags = from->client.flags;
|
||||
|
||||
player.pev->deadflag = from->client.deadflag;
|
||||
player.pev->waterlevel = from->client.waterlevel;
|
||||
player.pev->maxspeed = from->client.maxspeed;
|
||||
player.pev->fov = from->client.fov;
|
||||
player.pev->weaponanim = from->client.weaponanim;
|
||||
player.pev->viewmodel = from->client.viewmodel;
|
||||
player.m_flNextAttack = from->client.m_flNextAttack;
|
||||
|
||||
// Point to current weapon object
|
||||
if ( from->client.m_iId )
|
||||
{
|
||||
player.m_pActiveItem = g_pWpns[ from->client.m_iId ];
|
||||
}
|
||||
|
||||
// Store pointer to our destination entity_state_t so we can get our origin, etc. from it
|
||||
// for setting up events on the client
|
||||
g_finalstate = to;
|
||||
|
||||
// Don't go firing anything if we have died.
|
||||
// Or if we don't have a weapon model deployed
|
||||
if ( ( player.pev->deadflag != ( DEAD_DISCARDBODY + 1 ) ) && !CL_IsDead() && player.pev->viewmodel )
|
||||
{
|
||||
if ( player.m_flNextAttack <= 0 )
|
||||
{
|
||||
pWeapon->ItemPostFrame();
|
||||
}
|
||||
}
|
||||
|
||||
// If we are running events/etc. go ahead and see if we
|
||||
// managed to die between last frame and this one
|
||||
// If so, run the appropriate player killed or spawn function
|
||||
if ( g_runfuncs )
|
||||
{
|
||||
if ( to->client.health <= 0 && lasthealth > 0 )
|
||||
{
|
||||
player.Killed( NULL, 0 );
|
||||
}
|
||||
else if ( to->client.health > 0 && lasthealth <= 0 )
|
||||
{
|
||||
player.Spawn();
|
||||
}
|
||||
|
||||
lasthealth = to->client.health;
|
||||
}
|
||||
|
||||
// Assume that we are not going to switch weapons
|
||||
to->client.m_iId = from->client.m_iId;
|
||||
|
||||
// Now see if we issued a changeweapon command ( and we're not dead )
|
||||
if ( cmd->weaponselect && ( player.pev->deadflag != ( DEAD_DISCARDBODY + 1 ) ) )
|
||||
{
|
||||
// Switched to a different weapon?
|
||||
if ( from->weapondata[ cmd->weaponselect ].m_iId == cmd->weaponselect )
|
||||
{
|
||||
CBasePlayerWeapon *pNew = g_pWpns[ cmd->weaponselect ];
|
||||
if ( pNew && ( pNew != pWeapon ) )
|
||||
{
|
||||
// Put away old weapon
|
||||
if (player.m_pActiveItem)
|
||||
player.m_pActiveItem->Holster( );
|
||||
|
||||
player.m_pLastItem = player.m_pActiveItem;
|
||||
player.m_pActiveItem = pNew;
|
||||
|
||||
// Deploy new weapon
|
||||
if (player.m_pActiveItem)
|
||||
{
|
||||
player.m_pActiveItem->Deploy( );
|
||||
}
|
||||
|
||||
// Update weapon id so we can predict things correctly.
|
||||
to->client.m_iId = cmd->weaponselect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy in results of predcition code
|
||||
to->client.viewmodel = player.pev->viewmodel;
|
||||
to->client.fov = player.pev->fov;
|
||||
to->client.weaponanim = player.pev->weaponanim;
|
||||
to->client.m_flNextAttack = player.m_flNextAttack;
|
||||
to->client.maxspeed = player.pev->maxspeed;
|
||||
|
||||
// Make sure that weapon animation matches what the game .dll is telling us
|
||||
// over the wire ( fixes some animation glitches )
|
||||
if ( g_runfuncs && ( HUD_GetWeaponAnim() != to->client.weaponanim ) )
|
||||
{
|
||||
int body = 2;
|
||||
// Force a fixed anim down to viewmodel
|
||||
HUD_SendWeaponAnim( to->client.weaponanim, body, 1 );
|
||||
}
|
||||
|
||||
for ( i = 0; i < 32; i++ )
|
||||
{
|
||||
pCurrent = g_pWpns[ i ];
|
||||
|
||||
pto = &to->weapondata[ i ];
|
||||
|
||||
if ( !pCurrent )
|
||||
{
|
||||
memset( pto, 0, sizeof( weapon_data_t ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
pto->m_fInReload = pCurrent->m_fInReload;
|
||||
pto->m_iClip = pCurrent->m_iClip;
|
||||
pto->m_flNextPrimaryAttack = pCurrent->m_flNextPrimaryAttack;
|
||||
pto->m_flNextSecondaryAttack = pCurrent->m_flNextSecondaryAttack;
|
||||
pto->m_flTimeWeaponIdle = pCurrent->m_flTimeWeaponIdle;
|
||||
|
||||
// Decrement weapon counters, server does this at same time ( during post think, after doing everything else )
|
||||
pto->m_flNextReload -= cmd->msec / 1000.0;
|
||||
pto->m_fNextAimBonus -= cmd->msec / 1000.0;
|
||||
pto->m_flNextPrimaryAttack -= cmd->msec / 1000.0;
|
||||
pto->m_flNextSecondaryAttack -= cmd->msec / 1000.0;
|
||||
pto->m_flTimeWeaponIdle -= cmd->msec / 1000.0;
|
||||
|
||||
if ( pto->m_flPumpTime != -9999 )
|
||||
{
|
||||
pto->m_flPumpTime -= cmd->msec / 1000.0;
|
||||
if ( pto->m_flPumpTime < -0.001 )
|
||||
pto->m_flPumpTime = -0.001;
|
||||
}
|
||||
|
||||
if ( pto->m_fNextAimBonus < -1.0 )
|
||||
{
|
||||
pto->m_fNextAimBonus = -1.0;
|
||||
}
|
||||
|
||||
if ( pto->m_flNextPrimaryAttack < -1.0 )
|
||||
{
|
||||
pto->m_flNextPrimaryAttack = -1.0;
|
||||
}
|
||||
|
||||
if ( pto->m_flNextSecondaryAttack < -0.001 )
|
||||
{
|
||||
pto->m_flNextSecondaryAttack = -0.001;
|
||||
}
|
||||
|
||||
if ( pto->m_flTimeWeaponIdle < -0.001 )
|
||||
{
|
||||
pto->m_flTimeWeaponIdle = -0.001;
|
||||
}
|
||||
|
||||
if ( pto->m_flNextReload < -0.001 )
|
||||
{
|
||||
pto->m_flNextReload = -0.001;
|
||||
}
|
||||
}
|
||||
|
||||
// m_flNextAttack is now part of the weapons, but is part of the player instead
|
||||
to->client.m_flNextAttack -= cmd->msec / 1000.0;
|
||||
if ( to->client.m_flNextAttack < -0.001 )
|
||||
{
|
||||
to->client.m_flNextAttack = -0.001;
|
||||
}
|
||||
|
||||
// Wipe it so we can't use it after this frame
|
||||
g_finalstate = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
HUD_PostRunCmd
|
||||
|
||||
Client calls this during prediction, after it has moved the player and updated any info changed into to->
|
||||
time is the current client clock based on prediction
|
||||
cmd is the command that caused the movement, etc
|
||||
runfuncs is 1 if this is the first time we've predicted this command. If so, sounds and effects should play, otherwise, they should
|
||||
be ignored
|
||||
=====================
|
||||
*/
|
||||
void _DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed )
|
||||
{
|
||||
g_runfuncs = runfuncs;
|
||||
|
||||
// Only run post think stuff for glock for the sample
|
||||
// implementation
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
if ( cl_lw && cl_lw->value &&
|
||||
from->client.m_iId == WEAPON_GLOCK )
|
||||
{
|
||||
HUD_WeaponsPostThink( from, to, cmd, time, random_seed );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
to->client.fov = g_lastFOV;
|
||||
}
|
||||
|
||||
// All games can use FOV state
|
||||
g_lastFOV = to->client.fov;
|
||||
}
|
312
cl_dll/hud.cpp
312
cl_dll/hud.cpp
@ -19,13 +19,23 @@
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "parsemsg.h"
|
||||
#include "hud_servers.h"
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
|
||||
#include "demo.h"
|
||||
#include "demo_api.h"
|
||||
|
||||
extern client_sprite_t *GetSpriteList(client_sprite_t *pList, const char *psz, int iRes, int iCount);
|
||||
|
||||
extern cvar_t *sensitivity;
|
||||
cvar_t *cl_lw = NULL;
|
||||
|
||||
void ShutdownInput (void);
|
||||
|
||||
//DECLARE_MESSAGE(m_Logo, Logo)
|
||||
int __MsgFunc_Logo(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
@ -59,7 +69,147 @@ int __MsgFunc_GameMode(const char *pszName, int iSize, void *pbuf )
|
||||
return gHUD.MsgFunc_GameMode( pszName, iSize, pbuf );
|
||||
}
|
||||
|
||||
// TFFree Command Menu
|
||||
void __CmdFunc_OpenCommandMenu(void)
|
||||
{
|
||||
if ( gViewPort )
|
||||
{
|
||||
gViewPort->ShowCommandMenu();
|
||||
}
|
||||
}
|
||||
|
||||
// TFC "special" command
|
||||
void __CmdFunc_InputPlayerSpecial(void)
|
||||
{
|
||||
if ( gViewPort )
|
||||
{
|
||||
gViewPort->InputPlayerSpecial();
|
||||
}
|
||||
}
|
||||
|
||||
void __CmdFunc_CloseCommandMenu(void)
|
||||
{
|
||||
if ( gViewPort )
|
||||
{
|
||||
gViewPort->InputSignalHideCommandMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void __CmdFunc_ForceCloseCommandMenu( void )
|
||||
{
|
||||
if ( gViewPort )
|
||||
{
|
||||
gViewPort->HideCommandMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void __CmdFunc_ToggleServerBrowser( void )
|
||||
{
|
||||
if ( gViewPort )
|
||||
{
|
||||
gViewPort->ToggleServerBrowser();
|
||||
}
|
||||
}
|
||||
|
||||
// TFFree Command Menu Message Handlers
|
||||
int __MsgFunc_ValClass(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_ValClass( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __MsgFunc_TeamNames(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_TeamNames( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __MsgFunc_Feign(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_Feign( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __MsgFunc_Detpack(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_Detpack( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __MsgFunc_VGUIMenu(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_VGUIMenu( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __MsgFunc_MOTD(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_MOTD( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __MsgFunc_BuildSt(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_BuildSt( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __MsgFunc_RandomPC(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_RandomPC( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __MsgFunc_ServerName(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_ServerName( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __MsgFunc_ScoreInfo(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_ScoreInfo( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __MsgFunc_TeamScore(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_TeamScore( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __MsgFunc_TeamInfo(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_TeamInfo( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __MsgFunc_Spectator(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_Spectator( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __MsgFunc_AllowSpec(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->MsgFunc_AllowSpec( pszName, iSize, pbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This is called every time the DLL is loaded
|
||||
void CHud :: Init( void )
|
||||
{
|
||||
@ -70,11 +220,39 @@ void CHud :: Init( void )
|
||||
HOOK_MESSAGE( SetFOV );
|
||||
HOOK_MESSAGE( Concuss );
|
||||
|
||||
// TFFree CommandMenu
|
||||
HOOK_COMMAND( "+commandmenu", OpenCommandMenu );
|
||||
HOOK_COMMAND( "-commandmenu", CloseCommandMenu );
|
||||
HOOK_COMMAND( "ForceCloseCommandMenu", ForceCloseCommandMenu );
|
||||
HOOK_COMMAND( "special", InputPlayerSpecial );
|
||||
HOOK_COMMAND( "togglebrowser", ToggleServerBrowser );
|
||||
|
||||
HOOK_MESSAGE( ValClass );
|
||||
HOOK_MESSAGE( TeamNames );
|
||||
HOOK_MESSAGE( Feign );
|
||||
HOOK_MESSAGE( Detpack );
|
||||
HOOK_MESSAGE( MOTD );
|
||||
HOOK_MESSAGE( BuildSt );
|
||||
HOOK_MESSAGE( RandomPC );
|
||||
HOOK_MESSAGE( ServerName );
|
||||
HOOK_MESSAGE( ScoreInfo );
|
||||
HOOK_MESSAGE( TeamScore );
|
||||
HOOK_MESSAGE( TeamInfo );
|
||||
|
||||
HOOK_MESSAGE( Spectator );
|
||||
HOOK_MESSAGE( AllowSpec );
|
||||
|
||||
// VGUI Menus
|
||||
HOOK_MESSAGE( VGUIMenu );
|
||||
|
||||
m_iLogo = 0;
|
||||
m_iFOV = 0;
|
||||
|
||||
CVAR_CREATE( "zoom_sensitivity_ratio", "1.2", 0 );
|
||||
CVAR_CREATE( "default_fov", "90", 0 );
|
||||
default_fov = CVAR_CREATE( "default_fov", "90", 0 );
|
||||
m_pCvarStealMouse = CVAR_CREATE( "hud_capturemouse", "1", FCVAR_ARCHIVE );
|
||||
|
||||
cl_lw = gEngfuncs.pfnGetCvarPointer( "cl_lw" );
|
||||
|
||||
m_pSpriteList = NULL;
|
||||
|
||||
@ -101,8 +279,6 @@ void CHud :: Init( void )
|
||||
m_Battery.Init();
|
||||
m_Flash.Init();
|
||||
m_Message.Init();
|
||||
m_Scoreboard.Init();
|
||||
m_MOTD.Init();
|
||||
m_StatusBar.Init();
|
||||
m_DeathNotice.Init();
|
||||
m_AmmoSecondary.Init();
|
||||
@ -111,6 +287,8 @@ void CHud :: Init( void )
|
||||
|
||||
m_SayText.Init();
|
||||
m_Menu.Init();
|
||||
|
||||
ServersInit();
|
||||
|
||||
MsgFunc_ResetHUD(0, 0, NULL );
|
||||
}
|
||||
@ -122,6 +300,20 @@ CHud :: ~CHud()
|
||||
delete [] m_rghSprites;
|
||||
delete [] m_rgrcRects;
|
||||
delete [] m_rgszSpriteNames;
|
||||
|
||||
if ( m_pHudList )
|
||||
{
|
||||
HUDLIST *pList;
|
||||
while ( m_pHudList )
|
||||
{
|
||||
pList = m_pHudList;
|
||||
m_pHudList = m_pHudList->pNext;
|
||||
free( pList );
|
||||
}
|
||||
m_pHudList = NULL;
|
||||
}
|
||||
|
||||
ServersShutdown();
|
||||
}
|
||||
|
||||
// GetSpriteIndex()
|
||||
@ -151,6 +343,7 @@ void CHud :: VidInit( void )
|
||||
// m_hsprFont = LoadSprite("sprites/%d_font.spr");
|
||||
|
||||
m_hsprLogo = 0;
|
||||
m_hsprCursor = 0;
|
||||
|
||||
if (ScreenWidth < 640)
|
||||
m_iRes = 320;
|
||||
@ -231,8 +424,6 @@ void CHud :: VidInit( void )
|
||||
m_Battery.VidInit();
|
||||
m_Flash.VidInit();
|
||||
m_Message.VidInit();
|
||||
m_Scoreboard.VidInit();
|
||||
m_MOTD.VidInit();
|
||||
m_StatusBar.VidInit();
|
||||
m_DeathNotice.VidInit();
|
||||
m_SayText.VidInit();
|
||||
@ -252,6 +443,100 @@ int CHud::MsgFunc_Logo(const char *pszName, int iSize, void *pbuf)
|
||||
return 1;
|
||||
}
|
||||
|
||||
float g_lastFOV = 0.0;
|
||||
|
||||
/*
|
||||
============
|
||||
COM_FileBase
|
||||
============
|
||||
*/
|
||||
// Extracts the base name of a file (no path, no extension, assumes '/' as path separator)
|
||||
void COM_FileBase ( const char *in, char *out)
|
||||
{
|
||||
int len, start, end;
|
||||
|
||||
len = strlen( in );
|
||||
|
||||
// scan backward for '.'
|
||||
end = len - 1;
|
||||
while ( end && in[end] != '.' && in[end] != '/' && in[end] != '\\' )
|
||||
end--;
|
||||
|
||||
if ( in[end] != '.' ) // no '.', copy to end
|
||||
end = len-1;
|
||||
else
|
||||
end--; // Found ',', copy to left of '.'
|
||||
|
||||
|
||||
// Scan backward for '/'
|
||||
start = len-1;
|
||||
while ( start >= 0 && in[start] != '/' && in[start] != '\\' )
|
||||
start--;
|
||||
|
||||
if ( in[start] != '/' && in[start] != '\\' )
|
||||
start = 0;
|
||||
else
|
||||
start++;
|
||||
|
||||
// Length of new sting
|
||||
len = end - start + 1;
|
||||
|
||||
// Copy partial string
|
||||
strncpy( out, &in[start], len );
|
||||
// Terminate it
|
||||
out[len] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
HUD_IsGame
|
||||
|
||||
=================
|
||||
*/
|
||||
int HUD_IsGame( const char *game )
|
||||
{
|
||||
const char *gamedir;
|
||||
char gd[ 1024 ];
|
||||
|
||||
gamedir = gEngfuncs.pfnGetGameDirectory();
|
||||
if ( gamedir && gamedir[0] )
|
||||
{
|
||||
COM_FileBase( gamedir, gd );
|
||||
if ( !stricmp( gd, game ) )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
HUD_GetFOV
|
||||
|
||||
Returns last FOV
|
||||
=====================
|
||||
*/
|
||||
float HUD_GetFOV( void )
|
||||
{
|
||||
if ( gEngfuncs.pDemoAPI->IsRecording() )
|
||||
{
|
||||
// Write it
|
||||
int i = 0;
|
||||
unsigned char buf[ 100 ];
|
||||
|
||||
// Active
|
||||
*( float * )&buf[ i ] = g_lastFOV;
|
||||
i += sizeof( float );
|
||||
|
||||
Demo_WriteBuffer( TYPE_ZOOM, i, buf );
|
||||
}
|
||||
|
||||
if ( gEngfuncs.pDemoAPI->IsPlayingback() )
|
||||
{
|
||||
g_lastFOV = g_demozoom;
|
||||
}
|
||||
return g_lastFOV;
|
||||
}
|
||||
|
||||
int CHud::MsgFunc_SetFOV(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
BEGIN_READ( pbuf, iSize );
|
||||
@ -259,6 +544,14 @@ int CHud::MsgFunc_SetFOV(const char *pszName, int iSize, void *pbuf)
|
||||
int newfov = READ_BYTE();
|
||||
int def_fov = CVAR_GET_FLOAT( "default_fov" );
|
||||
|
||||
int tfc = 0;
|
||||
tfc = HUD_IsGame( "tfc" );
|
||||
|
||||
if ( tfc && cl_lw && cl_lw->value )
|
||||
return 1;
|
||||
|
||||
g_lastFOV = newfov;
|
||||
|
||||
if ( newfov == 0 )
|
||||
{
|
||||
m_iFOV = def_fov;
|
||||
@ -279,7 +572,7 @@ int CHud::MsgFunc_SetFOV(const char *pszName, int iSize, void *pbuf)
|
||||
else
|
||||
{
|
||||
// set a new sensitivity that is proportional to the change from the FOV default
|
||||
m_flMouseSensitivity = CVAR_GET_FLOAT("sensitivity") * ((float)newfov / (float)def_fov) * CVAR_GET_FLOAT("zoom_sensitivity_ratio");
|
||||
m_flMouseSensitivity = sensitivity->value * ((float)newfov / (float)def_fov) * CVAR_GET_FLOAT("zoom_sensitivity_ratio");
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -316,4 +609,9 @@ void CHud::AddHudElem(CHudBase *phudelem)
|
||||
ptemp->pNext = pdl;
|
||||
}
|
||||
|
||||
float CHud::GetSensitivity( void )
|
||||
{
|
||||
return m_flMouseSensitivity;
|
||||
}
|
||||
|
||||
|
||||
|
112
cl_dll/hud.h
112
cl_dll/hud.h
@ -25,11 +25,7 @@
|
||||
#define RGB_REDISH 0x00FF1010 //255,160,0
|
||||
#define RGB_GREENISH 0x0000A000 //0,160,0
|
||||
|
||||
typedef struct rect_s
|
||||
{
|
||||
int left, right, top, bottom;
|
||||
} wrect_t;
|
||||
|
||||
#include "wrect.h"
|
||||
#include "cl_dll.h"
|
||||
#include "ammo.h"
|
||||
|
||||
@ -54,6 +50,8 @@ typedef struct {
|
||||
|
||||
#define MAX_PLAYER_NAME_LENGTH 32
|
||||
|
||||
#define MAX_MOTD_LENGTH 1024
|
||||
|
||||
//
|
||||
//-----------------------------------------------------
|
||||
//
|
||||
@ -98,6 +96,7 @@ public:
|
||||
int MsgFunc_ItemPickup( const char *pszName, int iSize, void *pbuf );
|
||||
int MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf );
|
||||
|
||||
void SlotInput( int iSlot );
|
||||
void _cdecl UserCmd_Slot1( void );
|
||||
void _cdecl UserCmd_Slot2( void );
|
||||
void _cdecl UserCmd_Slot3( void );
|
||||
@ -189,6 +188,9 @@ private:
|
||||
//
|
||||
//-----------------------------------------------------
|
||||
//
|
||||
// REMOVED: Vgui has replaced this.
|
||||
//
|
||||
/*
|
||||
class CHudMOTD : public CHudBase
|
||||
{
|
||||
public:
|
||||
@ -200,12 +202,12 @@ public:
|
||||
int MsgFunc_MOTD( const char *pszName, int iSize, void *pbuf );
|
||||
|
||||
protected:
|
||||
enum { MAX_MOTD_LENGTH = 241, };
|
||||
static int MOTD_DISPLAY_TIME;
|
||||
char m_szMOTD[ MAX_MOTD_LENGTH ];
|
||||
float m_flActiveTill;
|
||||
float m_flActiveRemaining;
|
||||
int m_iLines;
|
||||
};
|
||||
*/
|
||||
|
||||
//
|
||||
//-----------------------------------------------------
|
||||
@ -239,6 +241,9 @@ protected:
|
||||
//
|
||||
//-----------------------------------------------------
|
||||
//
|
||||
// REMOVED: Vgui has replaced this.
|
||||
//
|
||||
/*
|
||||
class CHudScoreboard: public CHudBase
|
||||
{
|
||||
public:
|
||||
@ -254,34 +259,6 @@ public:
|
||||
int MsgFunc_TeamScore( const char *pszName, int iSize, void *pbuf );
|
||||
void DeathMsg( int killer, int victim );
|
||||
|
||||
enum {
|
||||
MAX_PLAYERS = 64,
|
||||
MAX_TEAMS = 64,
|
||||
MAX_TEAM_NAME = 16,
|
||||
};
|
||||
|
||||
struct extra_player_info_t {
|
||||
short frags;
|
||||
short deaths;
|
||||
char teamname[MAX_TEAM_NAME];
|
||||
};
|
||||
|
||||
struct team_info_t {
|
||||
char name[MAX_TEAM_NAME];
|
||||
short frags;
|
||||
short deaths;
|
||||
short ping;
|
||||
short packetloss;
|
||||
short ownteam;
|
||||
short players;
|
||||
int already_drawn;
|
||||
int scores_overriden;
|
||||
};
|
||||
|
||||
hud_player_info_t m_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine
|
||||
extra_player_info_t m_PlayerExtraInfo[MAX_PLAYERS+1]; // additional player info sent directly to the client dll
|
||||
team_info_t m_TeamInfo[MAX_TEAMS+1];
|
||||
|
||||
int m_iNumTeams;
|
||||
|
||||
int m_iLastKilledBy;
|
||||
@ -290,7 +267,47 @@ public:
|
||||
int m_iShowscoresHeld;
|
||||
|
||||
void GetAllPlayersInfo( void );
|
||||
private:
|
||||
struct cvar_s *cl_showpacketloss;
|
||||
|
||||
};
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_PLAYERS = 64,
|
||||
MAX_TEAMS = 64,
|
||||
MAX_TEAM_NAME = 16,
|
||||
};
|
||||
|
||||
struct extra_player_info_t
|
||||
{
|
||||
short frags;
|
||||
short deaths;
|
||||
short playerclass;
|
||||
short teamnumber;
|
||||
char teamname[MAX_TEAM_NAME];
|
||||
};
|
||||
|
||||
struct team_info_t
|
||||
{
|
||||
char name[MAX_TEAM_NAME];
|
||||
short frags;
|
||||
short deaths;
|
||||
short ping;
|
||||
short packetloss;
|
||||
short ownteam;
|
||||
short players;
|
||||
int already_drawn;
|
||||
int scores_overriden;
|
||||
int teamnumber;
|
||||
};
|
||||
|
||||
extern hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine
|
||||
extern extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1]; // additional player info sent directly to the client dll
|
||||
extern team_info_t g_TeamInfo[MAX_TEAMS+1];
|
||||
extern int g_IsSpectator[MAX_PLAYERS+1];
|
||||
|
||||
|
||||
//
|
||||
//-----------------------------------------------------
|
||||
@ -340,7 +357,7 @@ public:
|
||||
int VidInit( void );
|
||||
int Draw( float flTime );
|
||||
int MsgFunc_SayText( const char *pszName, int iSize, void *pbuf );
|
||||
void SayTextPrint( const char *pszBuf, int iBufSize );
|
||||
void SayTextPrint( const char *pszBuf, int iBufSize, int clientIndex = -1 );
|
||||
void EnsureTextFitsInOneLineAndWrapIfHaveTo( int line );
|
||||
};
|
||||
|
||||
@ -422,8 +439,8 @@ class CHudTextMessage: public CHudBase
|
||||
{
|
||||
public:
|
||||
int Init( void );
|
||||
char *LocaliseTextString( const char *msg, char *dst_buffer, int buffer_size );
|
||||
char *BufferedLocaliseTextString( const char *msg );
|
||||
static char *LocaliseTextString( const char *msg, char *dst_buffer, int buffer_size );
|
||||
static char *BufferedLocaliseTextString( const char *msg );
|
||||
char *LookupString( const char *msg_name, int *msg_dest = NULL );
|
||||
int MsgFunc_TextMsg(const char *pszName, int iSize, void *pbuf);
|
||||
};
|
||||
@ -501,11 +518,12 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
//-----------------------------------------------------
|
||||
//
|
||||
|
||||
typedef struct cvar_s cvar_t;
|
||||
|
||||
class CHud
|
||||
{
|
||||
private:
|
||||
@ -520,6 +538,7 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
HSPRITE m_hsprCursor;
|
||||
float m_flTime; // the current client time
|
||||
float m_fOldTime; // the time at which the HUD was last redrawn
|
||||
double m_flTimeDelta; // the difference between flTime and fOldTime
|
||||
@ -530,6 +549,7 @@ public:
|
||||
int m_iFOV;
|
||||
int m_Teamplay;
|
||||
int m_iRes;
|
||||
cvar_t *m_pCvarStealMouse;
|
||||
|
||||
int m_iFontHeight;
|
||||
int DrawHudNumber(int x, int y, int iFlags, int iNumber, int r, int g, int b );
|
||||
@ -545,6 +565,7 @@ private:
|
||||
wrect_t *m_rgrcRects; /*[HUD_SPRITE_COUNT]*/
|
||||
char *m_rgszSpriteNames; /*[HUD_SPRITE_COUNT][MAX_SPRITE_NAME_LENGTH]*/
|
||||
|
||||
struct cvar_s *default_fov;
|
||||
public:
|
||||
HSPRITE GetSprite( int index )
|
||||
{
|
||||
@ -566,8 +587,6 @@ public:
|
||||
CHudTrain m_Train;
|
||||
CHudFlashlight m_Flash;
|
||||
CHudMessage m_Message;
|
||||
CHudScoreboard m_Scoreboard;
|
||||
CHudMOTD m_MOTD;
|
||||
CHudStatusBar m_StatusBar;
|
||||
CHudDeathNotice m_DeathNotice;
|
||||
CHudSayText m_SayText;
|
||||
@ -606,6 +625,17 @@ public:
|
||||
|
||||
void AddHudElem(CHudBase *p);
|
||||
|
||||
float GetSensitivity();
|
||||
|
||||
};
|
||||
|
||||
class TeamFortressViewport;
|
||||
|
||||
extern CHud gHUD;
|
||||
extern TeamFortressViewport *gViewPort;
|
||||
|
||||
extern int g_iPlayerClass;
|
||||
extern int g_iTeamNumber;
|
||||
extern int g_iUser1;
|
||||
extern int g_iUser2;
|
||||
|
||||
|
13
cl_dll/hud_iface.h
Normal file
13
cl_dll/hud_iface.h
Normal file
@ -0,0 +1,13 @@
|
||||
#if !defined( HUD_IFACEH )
|
||||
#define HUD_IFACEH
|
||||
#pragma once
|
||||
|
||||
#define EXPORT _declspec( dllexport )
|
||||
#define _DLLEXPORT __declspec( dllexport )
|
||||
|
||||
typedef int (*pfnUserMsgHook)(const char *pszName, int iSize, void *pbuf);
|
||||
#include "wrect.h"
|
||||
#include "../engine/cdll_int.h"
|
||||
extern cl_enginefunc_t gEngfuncs;
|
||||
|
||||
#endif
|
@ -17,7 +17,7 @@
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include "parsemsg.h"
|
||||
|
||||
/// USER-DEFINED SERVER MESSAGE HANDLERS
|
||||
|
@ -17,8 +17,9 @@
|
||||
//
|
||||
#include <math.h>
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
|
||||
#define MAX_LOGO_FRAMES 56
|
||||
|
||||
@ -30,10 +31,18 @@ int grgLogoFrame[MAX_LOGO_FRAMES] =
|
||||
};
|
||||
|
||||
|
||||
extern int g_iVisibleMouse;
|
||||
|
||||
float HUD_GetFOV( void );
|
||||
|
||||
extern cvar_t *sensitivity;
|
||||
|
||||
// Think
|
||||
void CHud::Think(void)
|
||||
{
|
||||
int newfov;
|
||||
HUDLIST *pList = m_pHudList;
|
||||
|
||||
while (pList)
|
||||
{
|
||||
if (pList->p->m_iFlags & HUD_ACTIVE)
|
||||
@ -41,10 +50,34 @@ void CHud::Think(void)
|
||||
pList = pList->pNext;
|
||||
}
|
||||
|
||||
newfov = HUD_GetFOV();
|
||||
if ( newfov == 0 )
|
||||
{
|
||||
m_iFOV = default_fov->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iFOV = newfov;
|
||||
}
|
||||
|
||||
// the clients fov is actually set in the client data update section of the hud
|
||||
|
||||
// Set a new sensitivity
|
||||
if ( m_iFOV == default_fov->value )
|
||||
{
|
||||
// reset to saved sensitivity
|
||||
m_flMouseSensitivity = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set a new sensitivity that is proportional to the change from the FOV default
|
||||
m_flMouseSensitivity = sensitivity->value * ((float)newfov / (float)default_fov->value) * CVAR_GET_FLOAT("zoom_sensitivity_ratio");
|
||||
}
|
||||
|
||||
// think about default fov
|
||||
if ( m_iFOV == 0 )
|
||||
{ // only let players adjust up in fov, and only if they are not overriden by something else
|
||||
m_iFOV = max( CVAR_GET_FLOAT( "default_fov" ), 90 );
|
||||
m_iFOV = max( default_fov->value, 90 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,11 +89,39 @@ int CHud :: Redraw( float flTime, int intermission )
|
||||
m_fOldTime = m_flTime; // save time of previous redraw
|
||||
m_flTime = flTime;
|
||||
m_flTimeDelta = (double)m_flTime - m_fOldTime;
|
||||
static m_flShotTime = 0;
|
||||
|
||||
// Clock was reset, reset delta
|
||||
if ( m_flTimeDelta < 0 )
|
||||
m_flTimeDelta = 0;
|
||||
|
||||
// Bring up the scoreboard during intermission
|
||||
if (gViewPort)
|
||||
{
|
||||
if ( m_iIntermission && !intermission )
|
||||
{
|
||||
// Have to do this here so the scoreboard goes away
|
||||
m_iIntermission = intermission;
|
||||
gViewPort->HideCommandMenu();
|
||||
gViewPort->HideScoreBoard();
|
||||
}
|
||||
else if ( !m_iIntermission && intermission )
|
||||
{
|
||||
gViewPort->HideCommandMenu();
|
||||
gViewPort->ShowScoreBoard();
|
||||
|
||||
// Take a screenshot if the client's got the cvar set
|
||||
if ( CVAR_GET_FLOAT( "hud_takesshots" ) != 0 )
|
||||
m_flShotTime = flTime + 1.0; // Take a screenshot in a second
|
||||
}
|
||||
}
|
||||
|
||||
if (m_flShotTime && m_flShotTime < flTime)
|
||||
{
|
||||
gEngfuncs.pfnClientCmd("snapshot\n");
|
||||
m_flShotTime = 0;
|
||||
}
|
||||
|
||||
m_iIntermission = intermission;
|
||||
|
||||
// if no redrawing is necessary
|
||||
@ -72,7 +133,7 @@ int CHud :: Redraw( float flTime, int intermission )
|
||||
{
|
||||
if ( !intermission )
|
||||
{
|
||||
if ((pList->p->m_iFlags & HUD_ACTIVE) && !(m_iHideHUDDisplay & HIDEHUD_ALL))
|
||||
if ( (pList->p->m_iFlags & HUD_ACTIVE) && !(m_iHideHUDDisplay & HIDEHUD_ALL) )
|
||||
pList->p->Draw(flTime);
|
||||
}
|
||||
else
|
||||
@ -105,6 +166,28 @@ int CHud :: Redraw( float flTime, int intermission )
|
||||
SPR_DrawAdditive(i, x, y, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
if ( g_iVisibleMouse )
|
||||
{
|
||||
void IN_GetMousePos( int *mx, int *my );
|
||||
int mx, my;
|
||||
|
||||
IN_GetMousePos( &mx, &my );
|
||||
|
||||
if (m_hsprCursor == 0)
|
||||
{
|
||||
char sz[256];
|
||||
sprintf( sz, "sprites/cursor.spr" );
|
||||
m_hsprCursor = SPR_Load( sz );
|
||||
}
|
||||
|
||||
SPR_Set(m_hsprCursor, 250, 250, 250 );
|
||||
|
||||
// Draw the logo at 20 fps
|
||||
SPR_DrawAdditive( 0, mx, my, NULL );
|
||||
}
|
||||
*/
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
1223
cl_dll/hud_servers.cpp
Normal file
1223
cl_dll/hud_servers.cpp
Normal file
File diff suppressed because it is too large
Load Diff
34
cl_dll/hud_servers.h
Normal file
34
cl_dll/hud_servers.h
Normal file
@ -0,0 +1,34 @@
|
||||
#if !defined( HUD_SERVERSH )
|
||||
#define HUD_SERVERSH
|
||||
#pragma once
|
||||
|
||||
#define NET_CALLBACK /* */
|
||||
|
||||
// Dispatchers
|
||||
void NET_CALLBACK ListResponse( struct net_response_s *response );
|
||||
void NET_CALLBACK ServerResponse( struct net_response_s *response );
|
||||
void NET_CALLBACK PingResponse( struct net_response_s *response );
|
||||
void NET_CALLBACK RulesResponse( struct net_response_s *response );
|
||||
void NET_CALLBACK PlayersResponse( struct net_response_s *response );
|
||||
|
||||
void ServersInit( void );
|
||||
void ServersShutdown( void );
|
||||
void ServersThink( double time );
|
||||
void ServersCancel( void );
|
||||
|
||||
// Get list and get server info from each
|
||||
void ServersList( void );
|
||||
|
||||
// Query for IP / IPX LAN servers
|
||||
void BroadcastServersList( int clearpending );
|
||||
|
||||
void ServerPing( int server );
|
||||
void ServerRules( int server );
|
||||
void ServerPlayers( int server );
|
||||
|
||||
int ServersGetCount( void );
|
||||
const char *ServersGetInfo( int server );
|
||||
int ServersIsQuerying( void );
|
||||
void SortServers( const char *fieldname );
|
||||
|
||||
#endif // HUD_SERVERSH
|
91
cl_dll/hud_servers_priv.h
Normal file
91
cl_dll/hud_servers_priv.h
Normal file
@ -0,0 +1,91 @@
|
||||
#if !defined( HUD_SERVERS_PRIVH )
|
||||
#define HUD_SERVERS_PRIVH
|
||||
#pragma once
|
||||
|
||||
#include "netadr.h"
|
||||
|
||||
class CHudServers
|
||||
{
|
||||
public:
|
||||
typedef struct request_s
|
||||
{
|
||||
struct request_s *next;
|
||||
netadr_t remote_address;
|
||||
int context;
|
||||
} request_t;
|
||||
|
||||
typedef struct server_s
|
||||
{
|
||||
struct server_s *next;
|
||||
netadr_t remote_address;
|
||||
char *info;
|
||||
int ping;
|
||||
} server_t;
|
||||
|
||||
CHudServers();
|
||||
~CHudServers();
|
||||
|
||||
void Think( double time );
|
||||
void QueryThink( void );
|
||||
int isQuerying( void );
|
||||
|
||||
int LoadMasterAddresses( int maxservers, int *count, netadr_t *padr );
|
||||
|
||||
void RequestList( void );
|
||||
void RequestBroadcastList( int clearpending );
|
||||
|
||||
void ServerPing( int server );
|
||||
void ServerRules( int server );
|
||||
void ServerPlayers( int server );
|
||||
|
||||
void CancelRequest( void );
|
||||
|
||||
int CompareServers( server_t *p1, server_t *p2 );
|
||||
|
||||
void ClearServerList( server_t **ppList );
|
||||
void ClearRequestList( request_t **ppList );
|
||||
|
||||
void AddServer( server_t **ppList, server_t *p );
|
||||
|
||||
void RemoveServerFromList( request_t **ppList, request_t *item );
|
||||
|
||||
request_t *FindRequest( int context, request_t *pList );
|
||||
|
||||
int ServerListSize( void );
|
||||
char *GetServerInfo( int server );
|
||||
int GetServerCount( void );
|
||||
void SortServers( const char *fieldname );
|
||||
|
||||
void ListResponse( struct net_response_s *response );
|
||||
void ServerResponse( struct net_response_s *response );
|
||||
void PingResponse( struct net_response_s *response );
|
||||
void RulesResponse( struct net_response_s *response );
|
||||
void PlayersResponse( struct net_response_s *response );
|
||||
private:
|
||||
|
||||
server_t *GetServer( int server );
|
||||
|
||||
//
|
||||
char m_szToken[ 1024 ];
|
||||
int m_nRequesting;
|
||||
int m_nDone;
|
||||
|
||||
double m_dStarted;
|
||||
|
||||
request_t *m_pServerList;
|
||||
request_t *m_pActiveList;
|
||||
|
||||
server_t *m_pServers;
|
||||
|
||||
int m_nServerCount;
|
||||
|
||||
int m_nActiveQueries;
|
||||
int m_nQuerying;
|
||||
double m_fElapsed;
|
||||
|
||||
request_t *m_pPingRequest;
|
||||
request_t *m_pRulesRequest;
|
||||
request_t *m_pPlayersRequest;
|
||||
};
|
||||
|
||||
#endif // HUD_SERVERS_PRIVH
|
@ -18,25 +18,34 @@
|
||||
|
||||
#include <math.h>
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
int CL_ButtonBits( int );
|
||||
void CL_ResetButtonBits( int bits );
|
||||
|
||||
extern float v_idlescale;
|
||||
float in_fov;
|
||||
extern void HUD_SetCmdBits( int bits );
|
||||
|
||||
int CHud::UpdateClientData(client_data_t *cdata, float time)
|
||||
{
|
||||
memcpy(m_vecOrigin, cdata->origin, sizeof(vec3_t));
|
||||
memcpy(m_vecAngles, cdata->viewangles, sizeof(vec3_t));
|
||||
m_iKeyBits = cdata->iKeyBits;
|
||||
|
||||
m_iKeyBits = CL_ButtonBits( 0 );
|
||||
m_iWeaponBits = cdata->iWeaponBits;
|
||||
gHUD.Think();
|
||||
|
||||
cdata->iKeyBits = m_iKeyBits;
|
||||
in_fov = cdata->fov;
|
||||
|
||||
Think();
|
||||
|
||||
cdata->fov = m_iFOV;
|
||||
cdata->view_idlescale = m_iConcussionEffect;
|
||||
|
||||
v_idlescale = m_iConcussionEffect;
|
||||
|
||||
if ( m_flMouseSensitivity )
|
||||
cdata->mouse_sensitivity = m_flMouseSensitivity;
|
||||
CL_ResetButtonBits( m_iKeyBits );
|
||||
|
||||
// return 1 if in anything in the client_data struct has been changed, 0 otherwise
|
||||
return 1;
|
||||
|
614
cl_dll/in_camera.cpp
Normal file
614
cl_dll/in_camera.cpp
Normal file
@ -0,0 +1,614 @@
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "camera.h"
|
||||
#include "kbutton.h"
|
||||
#include "cvardef.h"
|
||||
#include "usercmd.h"
|
||||
#include "const.h"
|
||||
#include "camera.h"
|
||||
#include "in_defs.h"
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
float CL_KeyState (kbutton_t *key);
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void DLLEXPORT CAM_Think( void );
|
||||
int DLLEXPORT CL_IsThirdPerson( void );
|
||||
void DLLEXPORT CL_CameraOffset( float *ofs );
|
||||
}
|
||||
|
||||
extern cl_enginefunc_t gEngfuncs;
|
||||
|
||||
//-------------------------------------------------- Constants
|
||||
|
||||
#define CAM_DIST_DELTA 1.0
|
||||
#define CAM_ANGLE_DELTA 2.5
|
||||
#define CAM_ANGLE_SPEED 2.5
|
||||
#define CAM_MIN_DIST 30.0
|
||||
#define CAM_ANGLE_MOVE .5
|
||||
#define MAX_ANGLE_DIFF 10.0
|
||||
#define PITCH_MAX 90.0
|
||||
#define PITCH_MIN 0
|
||||
#define YAW_MAX 135.0
|
||||
#define YAW_MIN -135.0
|
||||
|
||||
enum ECAM_Command
|
||||
{
|
||||
CAM_COMMAND_NONE = 0,
|
||||
CAM_COMMAND_TOTHIRDPERSON = 1,
|
||||
CAM_COMMAND_TOFIRSTPERSON = 2
|
||||
};
|
||||
|
||||
//-------------------------------------------------- Global Variables
|
||||
|
||||
cvar_t *cam_command;
|
||||
cvar_t *cam_snapto;
|
||||
cvar_t *cam_idealyaw;
|
||||
cvar_t *cam_idealpitch;
|
||||
cvar_t *cam_idealdist;
|
||||
cvar_t *cam_contain;
|
||||
|
||||
cvar_t *c_maxpitch;
|
||||
cvar_t *c_minpitch;
|
||||
cvar_t *c_maxyaw;
|
||||
cvar_t *c_minyaw;
|
||||
cvar_t *c_maxdistance;
|
||||
cvar_t *c_mindistance;
|
||||
|
||||
// pitch, yaw, dist
|
||||
vec3_t cam_ofs;
|
||||
|
||||
|
||||
// In third person
|
||||
int cam_thirdperson;
|
||||
int cam_mousemove; //true if we are moving the cam with the mouse, False if not
|
||||
int iMouseInUse=0;
|
||||
int cam_distancemove;
|
||||
extern int mouse_x, mouse_y; //used to determine what the current x and y values are
|
||||
int cam_old_mouse_x, cam_old_mouse_y; //holds the last ticks mouse movement
|
||||
POINT cam_mouse;
|
||||
//-------------------------------------------------- Local Variables
|
||||
|
||||
static kbutton_t cam_pitchup, cam_pitchdown, cam_yawleft, cam_yawright;
|
||||
static kbutton_t cam_in, cam_out, cam_move;
|
||||
|
||||
//-------------------------------------------------- Prototypes
|
||||
|
||||
void CAM_ToThirdPerson(void);
|
||||
void CAM_ToFirstPerson(void);
|
||||
void CAM_StartDistance(void);
|
||||
void CAM_EndDistance(void);
|
||||
|
||||
|
||||
//-------------------------------------------------- Local Functions
|
||||
|
||||
float MoveToward( float cur, float goal, float maxspeed )
|
||||
{
|
||||
if( cur != goal )
|
||||
{
|
||||
if( abs( cur - goal ) > 180.0 )
|
||||
{
|
||||
if( cur < goal )
|
||||
cur += 360.0;
|
||||
else
|
||||
cur -= 360.0;
|
||||
}
|
||||
|
||||
if( cur < goal )
|
||||
{
|
||||
if( cur < goal - 1.0 )
|
||||
cur += ( goal - cur ) / 4.0;
|
||||
else
|
||||
cur = goal;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( cur > goal + 1.0 )
|
||||
cur -= ( cur - goal ) / 4.0;
|
||||
else
|
||||
cur = goal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// bring cur back into range
|
||||
if( cur < 0 )
|
||||
cur += 360.0;
|
||||
else if( cur >= 360 )
|
||||
cur -= 360;
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------- Gobal Functions
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t boxmins, boxmaxs;// enclose the test object along entire move
|
||||
float *mins, *maxs; // size of the moving object
|
||||
vec3_t mins2, maxs2; // size when clipping against mosnters
|
||||
float *start, *end;
|
||||
trace_t trace;
|
||||
int type;
|
||||
edict_t *passedict;
|
||||
qboolean monsterclip;
|
||||
} moveclip_t;
|
||||
|
||||
extern trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end);
|
||||
|
||||
void DLLEXPORT CAM_Think( void )
|
||||
{
|
||||
vec3_t origin;
|
||||
vec3_t ext, pnt, camForward, camRight, camUp;
|
||||
moveclip_t clip;
|
||||
float dist;
|
||||
vec3_t camAngles;
|
||||
float flSensitivity;
|
||||
#ifdef LATER
|
||||
int i;
|
||||
#endif
|
||||
vec3_t viewangles;
|
||||
|
||||
switch( (int) cam_command->value )
|
||||
{
|
||||
case CAM_COMMAND_TOTHIRDPERSON:
|
||||
CAM_ToThirdPerson();
|
||||
break;
|
||||
|
||||
case CAM_COMMAND_TOFIRSTPERSON:
|
||||
CAM_ToFirstPerson();
|
||||
break;
|
||||
|
||||
case CAM_COMMAND_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( !cam_thirdperson )
|
||||
return;
|
||||
|
||||
#ifdef LATER
|
||||
if ( cam_contain->value )
|
||||
{
|
||||
gEngfuncs.GetClientOrigin( origin );
|
||||
ext[0] = ext[1] = ext[2] = 0.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
camAngles[ PITCH ] = cam_idealpitch->value;
|
||||
camAngles[ YAW ] = cam_idealyaw->value;
|
||||
dist = cam_idealdist->value;
|
||||
//
|
||||
//movement of the camera with the mouse
|
||||
//
|
||||
if (cam_mousemove)
|
||||
{
|
||||
//get windows cursor position
|
||||
GetCursorPos (&cam_mouse);
|
||||
//check for X delta values and adjust accordingly
|
||||
//eventually adjust YAW based on amount of movement
|
||||
//don't do any movement of the cam using YAW/PITCH if we are zooming in/out the camera
|
||||
if (!cam_distancemove)
|
||||
{
|
||||
|
||||
//keep the camera within certain limits around the player (ie avoid certain bad viewing angles)
|
||||
if (cam_mouse.x>gEngfuncs.GetWindowCenterX())
|
||||
{
|
||||
//if ((camAngles[YAW]>=225.0)||(camAngles[YAW]<135.0))
|
||||
if (camAngles[YAW]<c_maxyaw->value)
|
||||
{
|
||||
camAngles[ YAW ] += (CAM_ANGLE_MOVE)*((cam_mouse.x-gEngfuncs.GetWindowCenterX())/2);
|
||||
}
|
||||
if (camAngles[YAW]>c_maxyaw->value)
|
||||
{
|
||||
|
||||
camAngles[YAW]=c_maxyaw->value;
|
||||
}
|
||||
}
|
||||
else if (cam_mouse.x<gEngfuncs.GetWindowCenterX())
|
||||
{
|
||||
//if ((camAngles[YAW]<=135.0)||(camAngles[YAW]>225.0))
|
||||
if (camAngles[YAW]>c_minyaw->value)
|
||||
{
|
||||
camAngles[ YAW ] -= (CAM_ANGLE_MOVE)* ((gEngfuncs.GetWindowCenterX()-cam_mouse.x)/2);
|
||||
|
||||
}
|
||||
if (camAngles[YAW]<c_minyaw->value)
|
||||
{
|
||||
camAngles[YAW]=c_minyaw->value;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//check for y delta values and adjust accordingly
|
||||
//eventually adjust PITCH based on amount of movement
|
||||
//also make sure camera is within bounds
|
||||
if (cam_mouse.y>gEngfuncs.GetWindowCenterY())
|
||||
{
|
||||
if(camAngles[PITCH]<c_maxpitch->value)
|
||||
{
|
||||
camAngles[PITCH] +=(CAM_ANGLE_MOVE)* ((cam_mouse.y-gEngfuncs.GetWindowCenterY())/2);
|
||||
}
|
||||
if (camAngles[PITCH]>c_maxpitch->value)
|
||||
{
|
||||
camAngles[PITCH]=c_maxpitch->value;
|
||||
}
|
||||
}
|
||||
else if (cam_mouse.y<gEngfuncs.GetWindowCenterY())
|
||||
{
|
||||
if (camAngles[PITCH]>c_minpitch->value)
|
||||
{
|
||||
camAngles[PITCH] -= (CAM_ANGLE_MOVE)*((gEngfuncs.GetWindowCenterY()-cam_mouse.y)/2);
|
||||
}
|
||||
if (camAngles[PITCH]<c_minpitch->value)
|
||||
{
|
||||
camAngles[PITCH]=c_minpitch->value;
|
||||
}
|
||||
}
|
||||
|
||||
//set old mouse coordinates to current mouse coordinates
|
||||
//since we are done with the mouse
|
||||
|
||||
if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 )
|
||||
{
|
||||
cam_old_mouse_x=cam_mouse.x*flSensitivity;
|
||||
cam_old_mouse_y=cam_mouse.y*flSensitivity;
|
||||
}
|
||||
else
|
||||
{
|
||||
cam_old_mouse_x=cam_mouse.x;
|
||||
cam_old_mouse_y=cam_mouse.y;
|
||||
}
|
||||
SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY());
|
||||
}
|
||||
}
|
||||
|
||||
//Nathan code here
|
||||
if( CL_KeyState( &cam_pitchup ) )
|
||||
camAngles[ PITCH ] += CAM_ANGLE_DELTA;
|
||||
else if( CL_KeyState( &cam_pitchdown ) )
|
||||
camAngles[ PITCH ] -= CAM_ANGLE_DELTA;
|
||||
|
||||
if( CL_KeyState( &cam_yawleft ) )
|
||||
camAngles[ YAW ] -= CAM_ANGLE_DELTA;
|
||||
else if( CL_KeyState( &cam_yawright ) )
|
||||
camAngles[ YAW ] += CAM_ANGLE_DELTA;
|
||||
|
||||
if( CL_KeyState( &cam_in ) )
|
||||
{
|
||||
dist -= CAM_DIST_DELTA;
|
||||
if( dist < CAM_MIN_DIST )
|
||||
{
|
||||
// If we go back into first person, reset the angle
|
||||
camAngles[ PITCH ] = 0;
|
||||
camAngles[ YAW ] = 0;
|
||||
dist = CAM_MIN_DIST;
|
||||
}
|
||||
|
||||
}
|
||||
else if( CL_KeyState( &cam_out ) )
|
||||
dist += CAM_DIST_DELTA;
|
||||
|
||||
if (cam_distancemove)
|
||||
{
|
||||
if (cam_mouse.y>gEngfuncs.GetWindowCenterY())
|
||||
{
|
||||
if(dist<c_maxdistance->value)
|
||||
{
|
||||
dist +=CAM_DIST_DELTA * ((cam_mouse.y-gEngfuncs.GetWindowCenterY())/2);
|
||||
}
|
||||
if (dist>c_maxdistance->value)
|
||||
{
|
||||
dist=c_maxdistance->value;
|
||||
}
|
||||
}
|
||||
else if (cam_mouse.y<gEngfuncs.GetWindowCenterY())
|
||||
{
|
||||
if (dist>c_mindistance->value)
|
||||
{
|
||||
dist -= (CAM_DIST_DELTA)*((gEngfuncs.GetWindowCenterY()-cam_mouse.y)/2);
|
||||
}
|
||||
if (dist<c_mindistance->value)
|
||||
{
|
||||
dist=c_mindistance->value;
|
||||
}
|
||||
}
|
||||
//set old mouse coordinates to current mouse coordinates
|
||||
//since we are done with the mouse
|
||||
cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity();
|
||||
cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity();
|
||||
SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY());
|
||||
}
|
||||
#ifdef LATER
|
||||
if( cam_contain->value )
|
||||
{
|
||||
// check new ideal
|
||||
VectorCopy( origin, pnt );
|
||||
AngleVectors( camAngles, camForward, camRight, camUp );
|
||||
for (i=0 ; i<3 ; i++)
|
||||
pnt[i] += -dist*camForward[i];
|
||||
|
||||
// check line from r_refdef.vieworg to pnt
|
||||
memset ( &clip, 0, sizeof ( moveclip_t ) );
|
||||
clip.trace = SV_ClipMoveToEntity( sv.edicts, r_refdef.vieworg, ext, ext, pnt );
|
||||
if( clip.trace.fraction == 1.0 )
|
||||
{
|
||||
// update ideal
|
||||
cam_idealpitch->value = camAngles[ PITCH ];
|
||||
cam_idealyaw->value = camAngles[ YAW ];
|
||||
cam_idealdist->value = dist;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// update ideal
|
||||
cam_idealpitch->value = camAngles[ PITCH ];
|
||||
cam_idealyaw->value = camAngles[ YAW ];
|
||||
cam_idealdist->value = dist;
|
||||
}
|
||||
|
||||
// Move towards ideal
|
||||
VectorCopy( cam_ofs, camAngles );
|
||||
|
||||
gEngfuncs.GetViewAngles( (float *)viewangles );
|
||||
|
||||
if( cam_snapto->value )
|
||||
{
|
||||
camAngles[ YAW ] = cam_idealyaw->value + viewangles[ YAW ];
|
||||
camAngles[ PITCH ] = cam_idealpitch->value + viewangles[ PITCH ];
|
||||
camAngles[ 2 ] = cam_idealdist->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( camAngles[ YAW ] - viewangles[ YAW ] != cam_idealyaw->value )
|
||||
camAngles[ YAW ] = MoveToward( camAngles[ YAW ], cam_idealyaw->value + viewangles[ YAW ], CAM_ANGLE_SPEED );
|
||||
|
||||
if( camAngles[ PITCH ] - viewangles[ PITCH ] != cam_idealpitch->value )
|
||||
camAngles[ PITCH ] = MoveToward( camAngles[ PITCH ], cam_idealpitch->value + viewangles[ PITCH ], CAM_ANGLE_SPEED );
|
||||
|
||||
if( abs( camAngles[ 2 ] - cam_idealdist->value ) < 2.0 )
|
||||
camAngles[ 2 ] = cam_idealdist->value;
|
||||
else
|
||||
camAngles[ 2 ] += ( cam_idealdist->value - camAngles[ 2 ] ) / 4.0;
|
||||
}
|
||||
#ifdef LATER
|
||||
if( cam_contain->value )
|
||||
{
|
||||
// Test new position
|
||||
dist = camAngles[ ROLL ];
|
||||
camAngles[ ROLL ] = 0;
|
||||
|
||||
VectorCopy( origin, pnt );
|
||||
AngleVectors( camAngles, camForward, camRight, camUp );
|
||||
for (i=0 ; i<3 ; i++)
|
||||
pnt[i] += -dist*camForward[i];
|
||||
|
||||
// check line from r_refdef.vieworg to pnt
|
||||
memset ( &clip, 0, sizeof ( moveclip_t ) );
|
||||
ext[0] = ext[1] = ext[2] = 0.0;
|
||||
clip.trace = SV_ClipMoveToEntity( sv.edicts, r_refdef.vieworg, ext, ext, pnt );
|
||||
if( clip.trace.fraction != 1.0 )
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
cam_ofs[ 0 ] = camAngles[ 0 ];
|
||||
cam_ofs[ 1 ] = camAngles[ 1 ];
|
||||
cam_ofs[ 2 ] = dist;
|
||||
}
|
||||
|
||||
extern void KeyDown (kbutton_t *b); // HACK
|
||||
extern void KeyUp (kbutton_t *b); // HACK
|
||||
|
||||
void CAM_PitchUpDown(void) { KeyDown( &cam_pitchup ); }
|
||||
void CAM_PitchUpUp(void) { KeyUp( &cam_pitchup ); }
|
||||
void CAM_PitchDownDown(void) { KeyDown( &cam_pitchdown ); }
|
||||
void CAM_PitchDownUp(void) { KeyUp( &cam_pitchdown ); }
|
||||
void CAM_YawLeftDown(void) { KeyDown( &cam_yawleft ); }
|
||||
void CAM_YawLeftUp(void) { KeyUp( &cam_yawleft ); }
|
||||
void CAM_YawRightDown(void) { KeyDown( &cam_yawright ); }
|
||||
void CAM_YawRightUp(void) { KeyUp( &cam_yawright ); }
|
||||
void CAM_InDown(void) { KeyDown( &cam_in ); }
|
||||
void CAM_InUp(void) { KeyUp( &cam_in ); }
|
||||
void CAM_OutDown(void) { KeyDown( &cam_out ); }
|
||||
void CAM_OutUp(void) { KeyUp( &cam_out ); }
|
||||
|
||||
void CAM_ToThirdPerson(void)
|
||||
{
|
||||
vec3_t viewangles;
|
||||
|
||||
#if !defined( _DEBUG )
|
||||
if ( gEngfuncs.GetMaxClients() > 1 )
|
||||
{
|
||||
// no thirdperson in multiplayer.
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
gEngfuncs.GetViewAngles( (float *)viewangles );
|
||||
|
||||
if( !cam_thirdperson )
|
||||
{
|
||||
cam_thirdperson = 1;
|
||||
|
||||
cam_ofs[ YAW ] = viewangles[ YAW ];
|
||||
cam_ofs[ PITCH ] = viewangles[ PITCH ];
|
||||
cam_ofs[ 2 ] = CAM_MIN_DIST;
|
||||
}
|
||||
|
||||
gEngfuncs.Cvar_SetValue( "cam_command", 0 );
|
||||
}
|
||||
|
||||
void CAM_ToFirstPerson(void)
|
||||
{
|
||||
cam_thirdperson = 0;
|
||||
|
||||
gEngfuncs.Cvar_SetValue( "cam_command", 0 );
|
||||
}
|
||||
|
||||
void CAM_ToggleSnapto( void )
|
||||
{
|
||||
cam_snapto->value = !cam_snapto->value;
|
||||
}
|
||||
|
||||
void CAM_Init( void )
|
||||
{
|
||||
gEngfuncs.pfnAddCommand( "+campitchup", CAM_PitchUpDown );
|
||||
gEngfuncs.pfnAddCommand( "-campitchup", CAM_PitchUpUp );
|
||||
gEngfuncs.pfnAddCommand( "+campitchdown", CAM_PitchDownDown );
|
||||
gEngfuncs.pfnAddCommand( "-campitchdown", CAM_PitchDownUp );
|
||||
gEngfuncs.pfnAddCommand( "+camyawleft", CAM_YawLeftDown );
|
||||
gEngfuncs.pfnAddCommand( "-camyawleft", CAM_YawLeftUp );
|
||||
gEngfuncs.pfnAddCommand( "+camyawright", CAM_YawRightDown );
|
||||
gEngfuncs.pfnAddCommand( "-camyawright", CAM_YawRightUp );
|
||||
gEngfuncs.pfnAddCommand( "+camin", CAM_InDown );
|
||||
gEngfuncs.pfnAddCommand( "-camin", CAM_InUp );
|
||||
gEngfuncs.pfnAddCommand( "+camout", CAM_OutDown );
|
||||
gEngfuncs.pfnAddCommand( "-camout", CAM_OutUp );
|
||||
gEngfuncs.pfnAddCommand( "thirdperson", CAM_ToThirdPerson );
|
||||
gEngfuncs.pfnAddCommand( "firstperson", CAM_ToFirstPerson );
|
||||
gEngfuncs.pfnAddCommand( "+cammousemove",CAM_StartMouseMove);
|
||||
gEngfuncs.pfnAddCommand( "-cammousemove",CAM_EndMouseMove);
|
||||
gEngfuncs.pfnAddCommand( "+camdistance", CAM_StartDistance );
|
||||
gEngfuncs.pfnAddCommand( "-camdistance", CAM_EndDistance );
|
||||
gEngfuncs.pfnAddCommand( "snapto", CAM_ToggleSnapto );
|
||||
|
||||
cam_command = gEngfuncs.pfnRegisterVariable ( "cam_command", "0", 0 ); // tells camera to go to thirdperson
|
||||
cam_snapto = gEngfuncs.pfnRegisterVariable ( "cam_snapto", "0", 0 ); // snap to thirdperson view
|
||||
cam_idealyaw = gEngfuncs.pfnRegisterVariable ( "cam_idealyaw", "90", 0 ); // thirdperson yaw
|
||||
cam_idealpitch = gEngfuncs.pfnRegisterVariable ( "cam_idealpitch", "0", 0 ); // thirperson pitch
|
||||
cam_idealdist = gEngfuncs.pfnRegisterVariable ( "cam_idealdist", "64", 0 ); // thirdperson distance
|
||||
cam_contain = gEngfuncs.pfnRegisterVariable ( "cam_contain", "0", 0 ); // contain camera to world
|
||||
|
||||
c_maxpitch = gEngfuncs.pfnRegisterVariable ( "c_maxpitch", "90.0", 0 );
|
||||
c_minpitch = gEngfuncs.pfnRegisterVariable ( "c_minpitch", "0.0", 0 );
|
||||
c_maxyaw = gEngfuncs.pfnRegisterVariable ( "c_maxyaw", "135.0", 0 );
|
||||
c_minyaw = gEngfuncs.pfnRegisterVariable ( "c_minyaw", "-135.0", 0 );
|
||||
c_maxdistance = gEngfuncs.pfnRegisterVariable ( "c_maxdistance", "200.0", 0 );
|
||||
c_mindistance = gEngfuncs.pfnRegisterVariable ( "c_mindistance", "30.0", 0 );
|
||||
}
|
||||
|
||||
void CAM_ClearStates( void )
|
||||
{
|
||||
vec3_t viewangles;
|
||||
|
||||
gEngfuncs.GetViewAngles( (float *)viewangles );
|
||||
|
||||
cam_pitchup.state = 0;
|
||||
cam_pitchdown.state = 0;
|
||||
cam_yawleft.state = 0;
|
||||
cam_yawright.state = 0;
|
||||
cam_in.state = 0;
|
||||
cam_out.state = 0;
|
||||
|
||||
cam_thirdperson = 0;
|
||||
cam_command->value = 0;
|
||||
cam_mousemove=0;
|
||||
|
||||
cam_snapto->value = 0;
|
||||
cam_distancemove = 0;
|
||||
|
||||
cam_ofs[ 0 ] = 0.0;
|
||||
cam_ofs[ 1 ] = 0.0;
|
||||
cam_ofs[ 2 ] = CAM_MIN_DIST;
|
||||
|
||||
cam_idealpitch->value = viewangles[ PITCH ];
|
||||
cam_idealyaw->value = viewangles[ YAW ];
|
||||
cam_idealdist->value = CAM_MIN_DIST;
|
||||
}
|
||||
|
||||
void CAM_StartMouseMove(void)
|
||||
{
|
||||
float flSensitivity;
|
||||
|
||||
//only move the cam with mouse if we are in third person.
|
||||
if (cam_thirdperson)
|
||||
{
|
||||
//set appropriate flags and initialize the old mouse position
|
||||
//variables for mouse camera movement
|
||||
if (!cam_mousemove)
|
||||
{
|
||||
cam_mousemove=1;
|
||||
iMouseInUse=1;
|
||||
GetCursorPos (&cam_mouse);
|
||||
|
||||
if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 )
|
||||
{
|
||||
cam_old_mouse_x=cam_mouse.x*flSensitivity;
|
||||
cam_old_mouse_y=cam_mouse.y*flSensitivity;
|
||||
}
|
||||
else
|
||||
{
|
||||
cam_old_mouse_x=cam_mouse.x;
|
||||
cam_old_mouse_y=cam_mouse.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
//we are not in 3rd person view..therefore do not allow camera movement
|
||||
else
|
||||
{
|
||||
cam_mousemove=0;
|
||||
iMouseInUse=0;
|
||||
}
|
||||
}
|
||||
|
||||
//the key has been released for camera movement
|
||||
//tell the engine that mouse camera movement is off
|
||||
void CAM_EndMouseMove(void)
|
||||
{
|
||||
cam_mousemove=0;
|
||||
iMouseInUse=0;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
//routines to start the process of moving the cam in or out
|
||||
//using the mouse
|
||||
//----------------------------------------------------------
|
||||
void CAM_StartDistance(void)
|
||||
{
|
||||
//only move the cam with mouse if we are in third person.
|
||||
if (cam_thirdperson)
|
||||
{
|
||||
//set appropriate flags and initialize the old mouse position
|
||||
//variables for mouse camera movement
|
||||
if (!cam_distancemove)
|
||||
{
|
||||
cam_distancemove=1;
|
||||
cam_mousemove=1;
|
||||
iMouseInUse=1;
|
||||
GetCursorPos (&cam_mouse);
|
||||
cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity();
|
||||
cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity();
|
||||
}
|
||||
}
|
||||
//we are not in 3rd person view..therefore do not allow camera movement
|
||||
else
|
||||
{
|
||||
cam_distancemove=0;
|
||||
cam_mousemove=0;
|
||||
iMouseInUse=0;
|
||||
}
|
||||
}
|
||||
|
||||
//the key has been released for camera movement
|
||||
//tell the engine that mouse camera movement is off
|
||||
void CAM_EndDistance(void)
|
||||
{
|
||||
cam_distancemove=0;
|
||||
cam_mousemove=0;
|
||||
iMouseInUse=0;
|
||||
}
|
||||
|
||||
int DLLEXPORT CL_IsThirdPerson( void )
|
||||
{
|
||||
return cam_thirdperson ? 1 : 0;
|
||||
}
|
||||
|
||||
void DLLEXPORT CL_CameraOffset( float *ofs )
|
||||
{
|
||||
VectorCopy( cam_ofs, ofs );
|
||||
}
|
14
cl_dll/in_defs.h
Normal file
14
cl_dll/in_defs.h
Normal file
@ -0,0 +1,14 @@
|
||||
#if !defined( IN_DEFSH )
|
||||
#define IN_DEFSH
|
||||
#pragma once
|
||||
|
||||
// up / down
|
||||
#define PITCH 0
|
||||
// left / right
|
||||
#define YAW 1
|
||||
// fall over
|
||||
#define ROLL 2
|
||||
|
||||
#define DLLEXPORT __declspec( dllexport )
|
||||
|
||||
#endif
|
957
cl_dll/input.cpp
Normal file
957
cl_dll/input.cpp
Normal file
@ -0,0 +1,957 @@
|
||||
// cl.input.c -- builds an intended movement command to send to the server
|
||||
|
||||
//xxxxxx Move bob and pitch drifting code here and other stuff from view if needed
|
||||
|
||||
// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
|
||||
// rights reserved.
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "camera.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "kbutton.h"
|
||||
}
|
||||
#include "cvardef.h"
|
||||
#include "usercmd.h"
|
||||
#include "const.h"
|
||||
#include "camera.h"
|
||||
#include "in_defs.h"
|
||||
#include "view.h"
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
struct kbutton_s DLLEXPORT *KB_Find( const char *name );
|
||||
void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active );
|
||||
void DLLEXPORT HUD_Shutdown( void );
|
||||
int DLLEXPORT HUD_Key_Event( int eventcode, int keynum, const char *pszCurrentBinding );
|
||||
}
|
||||
|
||||
extern int g_weaponselect;
|
||||
extern cl_enginefunc_t gEngfuncs;
|
||||
|
||||
// Defined in pm_math.c
|
||||
extern "C" float anglemod( float a );
|
||||
|
||||
void IN_Init (void);
|
||||
void IN_Move ( float frametime, usercmd_t *cmd);
|
||||
void IN_Shutdown( void );
|
||||
void V_Init( void );
|
||||
void VectorAngles( const float *forward, float *angles );
|
||||
int CL_ButtonBits( int );
|
||||
|
||||
// xxx need client dll function to get and clear impuse
|
||||
extern cvar_t *in_joystick;
|
||||
|
||||
int in_impulse = 0;
|
||||
int in_cancel = 0;
|
||||
|
||||
cvar_t *m_pitch;
|
||||
cvar_t *m_yaw;
|
||||
cvar_t *m_forward;
|
||||
cvar_t *m_side;
|
||||
|
||||
cvar_t *lookstrafe;
|
||||
cvar_t *lookspring;
|
||||
cvar_t *cl_pitchup;
|
||||
cvar_t *cl_pitchdown;
|
||||
cvar_t *cl_upspeed;
|
||||
cvar_t *cl_forwardspeed;
|
||||
cvar_t *cl_backspeed;
|
||||
cvar_t *cl_sidespeed;
|
||||
cvar_t *cl_movespeedkey;
|
||||
cvar_t *cl_yawspeed;
|
||||
cvar_t *cl_pitchspeed;
|
||||
cvar_t *cl_anglespeedkey;
|
||||
cvar_t *cl_vsmoothing;
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
KEY BUTTONS
|
||||
|
||||
Continuous button event tracking is complicated by the fact that two different
|
||||
input sources (say, mouse button 1 and the control key) can both press the
|
||||
same button, but the button should only be released when both of the
|
||||
pressing key have been released.
|
||||
|
||||
When a key event issues a button command (+forward, +attack, etc), it appends
|
||||
its key number as a parameter to the command so it can be matched up with
|
||||
the release.
|
||||
|
||||
state bit 0 is the current state of the key
|
||||
state bit 1 is edge triggered on the up to down transition
|
||||
state bit 2 is edge triggered on the down to up transition
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
|
||||
kbutton_t in_mlook;
|
||||
kbutton_t in_klook;
|
||||
kbutton_t in_jlook;
|
||||
kbutton_t in_left;
|
||||
kbutton_t in_right;
|
||||
kbutton_t in_forward;
|
||||
kbutton_t in_back;
|
||||
kbutton_t in_lookup;
|
||||
kbutton_t in_lookdown;
|
||||
kbutton_t in_moveleft;
|
||||
kbutton_t in_moveright;
|
||||
kbutton_t in_strafe;
|
||||
kbutton_t in_speed;
|
||||
kbutton_t in_use;
|
||||
kbutton_t in_jump;
|
||||
kbutton_t in_attack;
|
||||
kbutton_t in_attack2;
|
||||
kbutton_t in_up;
|
||||
kbutton_t in_down;
|
||||
kbutton_t in_duck;
|
||||
kbutton_t in_reload;
|
||||
kbutton_t in_alt1;
|
||||
kbutton_t in_score;
|
||||
kbutton_t in_break;
|
||||
kbutton_t in_graph; // Display the netgraph
|
||||
|
||||
typedef struct kblist_s
|
||||
{
|
||||
struct kblist_s *next;
|
||||
kbutton_t *pkey;
|
||||
char name[32];
|
||||
} kblist_t;
|
||||
|
||||
kblist_t *g_kbkeys = NULL;
|
||||
|
||||
/*
|
||||
============
|
||||
KB_ConvertString
|
||||
|
||||
Removes references to +use and replaces them with the keyname in the output string. If
|
||||
a binding is unfound, then the original text is retained.
|
||||
NOTE: Only works for text with +word in it.
|
||||
============
|
||||
*/
|
||||
int KB_ConvertString( char *in, char **ppout )
|
||||
{
|
||||
char sz[ 4096 ];
|
||||
char binding[ 64 ];
|
||||
char *p;
|
||||
char *pOut;
|
||||
char *pEnd;
|
||||
const char *pBinding;
|
||||
|
||||
if ( !ppout )
|
||||
return 0;
|
||||
|
||||
*ppout = NULL;
|
||||
p = in;
|
||||
pOut = sz;
|
||||
while ( *p )
|
||||
{
|
||||
if ( *p == '+' )
|
||||
{
|
||||
pEnd = binding;
|
||||
while ( *p && ( isalnum( *p ) || ( pEnd == binding ) ) && ( ( pEnd - binding ) < 63 ) )
|
||||
{
|
||||
*pEnd++ = *p++;
|
||||
}
|
||||
|
||||
*pEnd = '\0';
|
||||
|
||||
pBinding = NULL;
|
||||
if ( strlen( binding + 1 ) > 0 )
|
||||
{
|
||||
// See if there is a binding for binding?
|
||||
pBinding = gEngfuncs.Key_LookupBinding( binding + 1 );
|
||||
}
|
||||
|
||||
if ( pBinding )
|
||||
{
|
||||
*pOut++ = '[';
|
||||
pEnd = (char *)pBinding;
|
||||
}
|
||||
else
|
||||
{
|
||||
pEnd = binding;
|
||||
}
|
||||
|
||||
while ( *pEnd )
|
||||
{
|
||||
*pOut++ = *pEnd++;
|
||||
}
|
||||
|
||||
if ( pBinding )
|
||||
{
|
||||
*pOut++ = ']';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pOut++ = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
*pOut = '\0';
|
||||
|
||||
pOut = ( char * )malloc( strlen( sz ) + 1 );
|
||||
strcpy( pOut, sz );
|
||||
*ppout = pOut;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
KB_Find
|
||||
|
||||
Allows the engine to get a kbutton_t directly ( so it can check +mlook state, etc ) for saving out to .cfg files
|
||||
============
|
||||
*/
|
||||
struct kbutton_s DLLEXPORT *KB_Find( const char *name )
|
||||
{
|
||||
kblist_t *p;
|
||||
p = g_kbkeys;
|
||||
while ( p )
|
||||
{
|
||||
if ( !stricmp( name, p->name ) )
|
||||
return p->pkey;
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
KB_Add
|
||||
|
||||
Add a kbutton_t * to the list of pointers the engine can retrieve via KB_Find
|
||||
============
|
||||
*/
|
||||
void KB_Add( const char *name, kbutton_t *pkb )
|
||||
{
|
||||
kblist_t *p;
|
||||
kbutton_t *kb;
|
||||
|
||||
kb = KB_Find( name );
|
||||
|
||||
if ( kb )
|
||||
return;
|
||||
|
||||
p = ( kblist_t * )malloc( sizeof( kblist_t ) );
|
||||
memset( p, 0, sizeof( *p ) );
|
||||
|
||||
strcpy( p->name, name );
|
||||
p->pkey = pkb;
|
||||
|
||||
p->next = g_kbkeys;
|
||||
g_kbkeys = p;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
KB_Init
|
||||
|
||||
Add kbutton_t definitions that the engine can query if needed
|
||||
============
|
||||
*/
|
||||
void KB_Init( void )
|
||||
{
|
||||
g_kbkeys = NULL;
|
||||
|
||||
KB_Add( "in_graph", &in_graph );
|
||||
KB_Add( "in_mlook", &in_mlook );
|
||||
KB_Add( "in_jlook", &in_jlook );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
KB_Shutdown
|
||||
|
||||
Clear kblist
|
||||
============
|
||||
*/
|
||||
void KB_Shutdown( void )
|
||||
{
|
||||
kblist_t *p, *n;
|
||||
p = g_kbkeys;
|
||||
while ( p )
|
||||
{
|
||||
n = p->next;
|
||||
free( p );
|
||||
p = n;
|
||||
}
|
||||
g_kbkeys = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
KeyDown
|
||||
============
|
||||
*/
|
||||
void KeyDown (kbutton_t *b)
|
||||
{
|
||||
int k;
|
||||
char *c;
|
||||
|
||||
c = gEngfuncs.Cmd_Argv(1);
|
||||
if (c[0])
|
||||
k = atoi(c);
|
||||
else
|
||||
k = -1; // typed manually at the console for continuous down
|
||||
|
||||
if (k == b->down[0] || k == b->down[1])
|
||||
return; // repeating key
|
||||
|
||||
if (!b->down[0])
|
||||
b->down[0] = k;
|
||||
else if (!b->down[1])
|
||||
b->down[1] = k;
|
||||
else
|
||||
{
|
||||
gEngfuncs.Con_DPrintf ("Three keys down for a button '%c' '%c' '%c'!\n", b->down[0], b->down[1], c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (b->state & 1)
|
||||
return; // still down
|
||||
b->state |= 1 + 2; // down + impulse down
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
KeyUp
|
||||
============
|
||||
*/
|
||||
void KeyUp (kbutton_t *b)
|
||||
{
|
||||
int k;
|
||||
char *c;
|
||||
|
||||
c = gEngfuncs.Cmd_Argv(1);
|
||||
if (c[0])
|
||||
k = atoi(c);
|
||||
else
|
||||
{ // typed manually at the console, assume for unsticking, so clear all
|
||||
b->down[0] = b->down[1] = 0;
|
||||
b->state = 4; // impulse up
|
||||
return;
|
||||
}
|
||||
|
||||
if (b->down[0] == k)
|
||||
b->down[0] = 0;
|
||||
else if (b->down[1] == k)
|
||||
b->down[1] = 0;
|
||||
else
|
||||
return; // key up without coresponding down (menu pass through)
|
||||
if (b->down[0] || b->down[1])
|
||||
{
|
||||
//Con_Printf ("Keys down for button: '%c' '%c' '%c' (%d,%d,%d)!\n", b->down[0], b->down[1], c, b->down[0], b->down[1], c);
|
||||
return; // some other key is still holding it down
|
||||
}
|
||||
|
||||
if (!(b->state & 1))
|
||||
return; // still up (this should not happen)
|
||||
|
||||
b->state &= ~1; // now up
|
||||
b->state |= 4; // impulse up
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
HUD_Key_Event
|
||||
|
||||
Return 1 to allow engine to process the key, otherwise, act on it as needed
|
||||
============
|
||||
*/
|
||||
int DLLEXPORT HUD_Key_Event( int down, int keynum, const char *pszCurrentBinding )
|
||||
{
|
||||
if (gViewPort)
|
||||
return gViewPort->KeyInput(down, keynum, pszCurrentBinding);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void IN_BreakDown( void ) { KeyDown( &in_break );};
|
||||
void IN_BreakUp( void ) { KeyUp( &in_break ); };
|
||||
void IN_KLookDown (void) {KeyDown(&in_klook);}
|
||||
void IN_KLookUp (void) {KeyUp(&in_klook);}
|
||||
void IN_JLookDown (void) {KeyDown(&in_jlook);}
|
||||
void IN_JLookUp (void) {KeyUp(&in_jlook);}
|
||||
void IN_MLookDown (void) {KeyDown(&in_mlook);}
|
||||
void IN_UpDown(void) {KeyDown(&in_up);}
|
||||
void IN_UpUp(void) {KeyUp(&in_up);}
|
||||
void IN_DownDown(void) {KeyDown(&in_down);}
|
||||
void IN_DownUp(void) {KeyUp(&in_down);}
|
||||
void IN_LeftDown(void) {KeyDown(&in_left);}
|
||||
void IN_LeftUp(void) {KeyUp(&in_left);}
|
||||
void IN_RightDown(void) {KeyDown(&in_right);}
|
||||
void IN_RightUp(void) {KeyUp(&in_right);}
|
||||
void IN_ForwardDown(void) {KeyDown(&in_forward);}
|
||||
void IN_ForwardUp(void) {KeyUp(&in_forward);}
|
||||
void IN_BackDown(void) {KeyDown(&in_back);}
|
||||
void IN_BackUp(void) {KeyUp(&in_back);}
|
||||
void IN_LookupDown(void) {KeyDown(&in_lookup);}
|
||||
void IN_LookupUp(void) {KeyUp(&in_lookup);}
|
||||
void IN_LookdownDown(void) {KeyDown(&in_lookdown);}
|
||||
void IN_LookdownUp(void) {KeyUp(&in_lookdown);}
|
||||
void IN_MoveleftDown(void) {KeyDown(&in_moveleft);}
|
||||
void IN_MoveleftUp(void) {KeyUp(&in_moveleft);}
|
||||
void IN_MoverightDown(void) {KeyDown(&in_moveright);}
|
||||
void IN_MoverightUp(void) {KeyUp(&in_moveright);}
|
||||
void IN_SpeedDown(void) {KeyDown(&in_speed);}
|
||||
void IN_SpeedUp(void) {KeyUp(&in_speed);}
|
||||
void IN_StrafeDown(void) {KeyDown(&in_strafe);}
|
||||
void IN_StrafeUp(void) {KeyUp(&in_strafe);}
|
||||
|
||||
// needs capture by hud/vgui also
|
||||
extern void __CmdFunc_InputPlayerSpecial(void);
|
||||
void IN_Attack2Down(void)
|
||||
{
|
||||
KeyDown(&in_attack2);
|
||||
__CmdFunc_InputPlayerSpecial();
|
||||
}
|
||||
|
||||
void IN_Attack2Up(void) {KeyUp(&in_attack2);}
|
||||
void IN_UseDown (void) {KeyDown(&in_use);}
|
||||
void IN_UseUp (void) {KeyUp(&in_use);}
|
||||
void IN_JumpDown (void) {KeyDown(&in_jump);}
|
||||
void IN_JumpUp (void) {KeyUp(&in_jump);}
|
||||
void IN_DuckDown(void) {KeyDown(&in_duck);}
|
||||
void IN_DuckUp(void) {KeyUp(&in_duck);}
|
||||
void IN_ReloadDown(void) {KeyDown(&in_reload);}
|
||||
void IN_ReloadUp(void) {KeyUp(&in_reload);}
|
||||
void IN_Alt1Down(void) {KeyDown(&in_alt1);}
|
||||
void IN_Alt1Up(void) {KeyUp(&in_alt1);}
|
||||
void IN_GraphDown(void) {KeyDown(&in_graph);}
|
||||
void IN_GraphUp(void) {KeyUp(&in_graph);}
|
||||
|
||||
void IN_AttackDown(void)
|
||||
{
|
||||
KeyDown( &in_attack );
|
||||
}
|
||||
|
||||
void IN_AttackUp(void)
|
||||
{
|
||||
KeyUp( &in_attack );
|
||||
in_cancel = 0;
|
||||
}
|
||||
|
||||
// Special handling
|
||||
void IN_Cancel(void)
|
||||
{
|
||||
in_cancel = 1;
|
||||
}
|
||||
|
||||
void IN_Impulse (void)
|
||||
{
|
||||
in_impulse = atoi( gEngfuncs.Cmd_Argv(1) );
|
||||
}
|
||||
|
||||
void IN_ScoreDown(void)
|
||||
{
|
||||
KeyDown(&in_score);
|
||||
if ( gViewPort )
|
||||
{
|
||||
gViewPort->ShowScoreBoard();
|
||||
}
|
||||
}
|
||||
|
||||
void IN_ScoreUp(void)
|
||||
{
|
||||
KeyUp(&in_score);
|
||||
if ( gViewPort )
|
||||
{
|
||||
gViewPort->HideScoreBoard();
|
||||
}
|
||||
}
|
||||
|
||||
void IN_MLookUp (void)
|
||||
{
|
||||
KeyUp( &in_mlook );
|
||||
if ( !( in_mlook.state & 1 ) && lookspring->value )
|
||||
{
|
||||
V_StartPitchDrift();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_KeyState
|
||||
|
||||
Returns 0.25 if a key was pressed and released during the frame,
|
||||
0.5 if it was pressed and held
|
||||
0 if held then released, and
|
||||
1.0 if held for the entire time
|
||||
===============
|
||||
*/
|
||||
float CL_KeyState (kbutton_t *key)
|
||||
{
|
||||
float val = 0.0;
|
||||
int impulsedown, impulseup, down;
|
||||
|
||||
impulsedown = key->state & 2;
|
||||
impulseup = key->state & 4;
|
||||
down = key->state & 1;
|
||||
|
||||
if ( impulsedown && !impulseup )
|
||||
{
|
||||
// pressed and held this frame?
|
||||
val = down ? 0.5 : 0.0;
|
||||
}
|
||||
|
||||
if ( impulseup && !impulsedown )
|
||||
{
|
||||
// released this frame?
|
||||
val = down ? 0.0 : 0.0;
|
||||
}
|
||||
|
||||
if ( !impulsedown && !impulseup )
|
||||
{
|
||||
// held the entire frame?
|
||||
val = down ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
if ( impulsedown && impulseup )
|
||||
{
|
||||
if ( down )
|
||||
{
|
||||
// released and re-pressed this frame
|
||||
val = 0.75;
|
||||
}
|
||||
else
|
||||
{
|
||||
// pressed and released this frame
|
||||
val = 0.25;
|
||||
}
|
||||
}
|
||||
|
||||
// clear impulses
|
||||
key->state &= 1;
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_AdjustAngles
|
||||
|
||||
Moves the local angle positions
|
||||
================
|
||||
*/
|
||||
void CL_AdjustAngles ( float frametime, float *viewangles )
|
||||
{
|
||||
float speed;
|
||||
float up, down;
|
||||
|
||||
if (in_speed.state & 1)
|
||||
{
|
||||
speed = frametime * cl_anglespeedkey->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
speed = frametime;
|
||||
}
|
||||
|
||||
if (!(in_strafe.state & 1))
|
||||
{
|
||||
viewangles[YAW] -= speed*cl_yawspeed->value*CL_KeyState (&in_right);
|
||||
viewangles[YAW] += speed*cl_yawspeed->value*CL_KeyState (&in_left);
|
||||
viewangles[YAW] = anglemod(viewangles[YAW]);
|
||||
}
|
||||
if (in_klook.state & 1)
|
||||
{
|
||||
V_StopPitchDrift ();
|
||||
viewangles[PITCH] -= speed*cl_pitchspeed->value * CL_KeyState (&in_forward);
|
||||
viewangles[PITCH] += speed*cl_pitchspeed->value * CL_KeyState (&in_back);
|
||||
}
|
||||
|
||||
up = CL_KeyState (&in_lookup);
|
||||
down = CL_KeyState(&in_lookdown);
|
||||
|
||||
viewangles[PITCH] -= speed*cl_pitchspeed->value * up;
|
||||
viewangles[PITCH] += speed*cl_pitchspeed->value * down;
|
||||
|
||||
if (up || down)
|
||||
V_StopPitchDrift ();
|
||||
|
||||
if (viewangles[PITCH] > cl_pitchdown->value)
|
||||
viewangles[PITCH] = cl_pitchdown->value;
|
||||
if (viewangles[PITCH] < -cl_pitchup->value)
|
||||
viewangles[PITCH] = -cl_pitchup->value;
|
||||
|
||||
if (viewangles[ROLL] > 50)
|
||||
viewangles[ROLL] = 50;
|
||||
if (viewangles[ROLL] < -50)
|
||||
viewangles[ROLL] = -50;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_CreateMove
|
||||
|
||||
Send the intended movement message to the server
|
||||
if active == 1 then we are 1) not playing back demos ( where our commands are ignored ) and
|
||||
2 ) we have finished signing on to server
|
||||
================
|
||||
*/
|
||||
void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active )
|
||||
{
|
||||
float spd;
|
||||
vec3_t viewangles;
|
||||
static vec3_t oldangles;
|
||||
|
||||
if ( active )
|
||||
{
|
||||
//memset( viewangles, 0, sizeof( vec3_t ) );
|
||||
//viewangles[ 0 ] = viewangles[ 1 ] = viewangles[ 2 ] = 0.0;
|
||||
gEngfuncs.GetViewAngles( (float *)viewangles );
|
||||
|
||||
CL_AdjustAngles ( frametime, viewangles );
|
||||
|
||||
memset (cmd, 0, sizeof(*cmd));
|
||||
|
||||
gEngfuncs.SetViewAngles( (float *)viewangles );
|
||||
|
||||
if ( in_strafe.state & 1 )
|
||||
{
|
||||
cmd->sidemove += cl_sidespeed->value * CL_KeyState (&in_right);
|
||||
cmd->sidemove -= cl_sidespeed->value * CL_KeyState (&in_left);
|
||||
}
|
||||
|
||||
cmd->sidemove += cl_sidespeed->value * CL_KeyState (&in_moveright);
|
||||
cmd->sidemove -= cl_sidespeed->value * CL_KeyState (&in_moveleft);
|
||||
|
||||
cmd->upmove += cl_upspeed->value * CL_KeyState (&in_up);
|
||||
cmd->upmove -= cl_upspeed->value * CL_KeyState (&in_down);
|
||||
|
||||
if ( !(in_klook.state & 1 ) )
|
||||
{
|
||||
cmd->forwardmove += cl_forwardspeed->value * CL_KeyState (&in_forward);
|
||||
cmd->forwardmove -= cl_backspeed->value * CL_KeyState (&in_back);
|
||||
}
|
||||
|
||||
// adjust for speed key
|
||||
if ( in_speed.state & 1 )
|
||||
{
|
||||
cmd->forwardmove *= cl_movespeedkey->value;
|
||||
cmd->sidemove *= cl_movespeedkey->value;
|
||||
cmd->upmove *= cl_movespeedkey->value;
|
||||
}
|
||||
|
||||
// clip to maxspeed
|
||||
spd = gEngfuncs.GetClientMaxspeed();
|
||||
if ( spd != 0.0 )
|
||||
{
|
||||
// scale the 3 speeds so that the total velocity is not > cl.maxspeed
|
||||
float fmov = sqrt( (cmd->forwardmove*cmd->forwardmove) + (cmd->sidemove*cmd->sidemove) + (cmd->upmove*cmd->upmove) );
|
||||
|
||||
if ( fmov > spd )
|
||||
{
|
||||
float fratio = spd / fmov;
|
||||
cmd->forwardmove *= fratio;
|
||||
cmd->sidemove *= fratio;
|
||||
cmd->upmove *= fratio;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow mice and other controllers to add their inputs
|
||||
IN_Move ( frametime, cmd );
|
||||
}
|
||||
|
||||
cmd->impulse = in_impulse;
|
||||
in_impulse = 0;
|
||||
|
||||
cmd->weaponselect = g_weaponselect;
|
||||
g_weaponselect = 0;
|
||||
//
|
||||
// set button and flag bits
|
||||
//
|
||||
cmd->buttons = CL_ButtonBits( 1 );
|
||||
|
||||
// Using joystick?
|
||||
if ( in_joystick->value )
|
||||
{
|
||||
if ( cmd->forwardmove > 0 )
|
||||
{
|
||||
cmd->buttons |= IN_FORWARD;
|
||||
}
|
||||
else if ( cmd->forwardmove < 0 )
|
||||
{
|
||||
cmd->buttons |= IN_BACK;
|
||||
}
|
||||
}
|
||||
|
||||
gEngfuncs.GetViewAngles( (float *)viewangles );
|
||||
// Set current view angles.
|
||||
|
||||
if ( gHUD.m_Health.m_iHealth > 0 )
|
||||
{
|
||||
VectorCopy( viewangles, cmd->viewangles );
|
||||
VectorCopy( viewangles, oldangles );
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy( oldangles, cmd->viewangles );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_IsDead
|
||||
|
||||
Returns 1 if health is <= 0
|
||||
============
|
||||
*/
|
||||
int CL_IsDead( void )
|
||||
{
|
||||
return ( gHUD.m_Health.m_iHealth <= 0 ) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_ButtonBits
|
||||
|
||||
Returns appropriate button info for keyboard and mouse state
|
||||
Set bResetState to 1 to clear old state info
|
||||
============
|
||||
*/
|
||||
int CL_ButtonBits( int bResetState )
|
||||
{
|
||||
int bits = 0;
|
||||
|
||||
if ( in_attack.state & 3 )
|
||||
{
|
||||
bits |= IN_ATTACK;
|
||||
}
|
||||
|
||||
if (in_duck.state & 3)
|
||||
{
|
||||
bits |= IN_DUCK;
|
||||
}
|
||||
|
||||
if (in_jump.state & 3)
|
||||
{
|
||||
bits |= IN_JUMP;
|
||||
}
|
||||
|
||||
if ( in_forward.state & 3 )
|
||||
{
|
||||
bits |= IN_FORWARD;
|
||||
}
|
||||
|
||||
if (in_back.state & 3)
|
||||
{
|
||||
bits |= IN_BACK;
|
||||
}
|
||||
|
||||
if (in_use.state & 3)
|
||||
{
|
||||
bits |= IN_USE;
|
||||
}
|
||||
|
||||
if (in_cancel)
|
||||
{
|
||||
bits |= IN_CANCEL;
|
||||
}
|
||||
|
||||
if ( in_left.state & 3 )
|
||||
{
|
||||
bits |= IN_LEFT;
|
||||
}
|
||||
|
||||
if (in_right.state & 3)
|
||||
{
|
||||
bits |= IN_RIGHT;
|
||||
}
|
||||
|
||||
if ( in_moveleft.state & 3 )
|
||||
{
|
||||
bits |= IN_MOVELEFT;
|
||||
}
|
||||
|
||||
if (in_moveright.state & 3)
|
||||
{
|
||||
bits |= IN_MOVERIGHT;
|
||||
}
|
||||
|
||||
if (in_attack2.state & 3)
|
||||
{
|
||||
bits |= IN_ATTACK2;
|
||||
}
|
||||
|
||||
if (in_reload.state & 3)
|
||||
{
|
||||
bits |= IN_RELOAD;
|
||||
}
|
||||
|
||||
if (in_alt1.state & 3)
|
||||
{
|
||||
bits |= IN_ALT1;
|
||||
}
|
||||
|
||||
if ( in_score.state & 3 )
|
||||
{
|
||||
bits |= IN_SCORE;
|
||||
}
|
||||
|
||||
// Dead or in intermission? Shore scoreboard, too
|
||||
if ( CL_IsDead() || gHUD.m_iIntermission )
|
||||
{
|
||||
bits |= IN_SCORE;
|
||||
}
|
||||
|
||||
if ( bResetState )
|
||||
{
|
||||
in_attack.state &= ~2;
|
||||
in_duck.state &= ~2;
|
||||
in_jump.state &= ~2;
|
||||
in_forward.state &= ~2;
|
||||
in_back.state &= ~2;
|
||||
in_use.state &= ~2;
|
||||
in_left.state &= ~2;
|
||||
in_right.state &= ~2;
|
||||
in_moveleft.state &= ~2;
|
||||
in_moveright.state &= ~2;
|
||||
in_attack2.state &= ~2;
|
||||
in_reload.state &= ~2;
|
||||
in_alt1.state &= ~2;
|
||||
in_score.state &= ~2;
|
||||
}
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_ResetButtonBits
|
||||
|
||||
============
|
||||
*/
|
||||
void CL_ResetButtonBits( int bits )
|
||||
{
|
||||
int bitsNew = CL_ButtonBits( 0 ) ^ bits;
|
||||
|
||||
// Has the attack button been changed
|
||||
if ( bitsNew & IN_ATTACK )
|
||||
{
|
||||
// Was it pressed? or let go?
|
||||
if ( bits & IN_ATTACK )
|
||||
{
|
||||
KeyDown( &in_attack );
|
||||
}
|
||||
else
|
||||
{
|
||||
// totally clear state
|
||||
in_attack.state &= ~7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
InitInput
|
||||
============
|
||||
*/
|
||||
void InitInput (void)
|
||||
{
|
||||
gEngfuncs.pfnAddCommand ("+moveup",IN_UpDown);
|
||||
gEngfuncs.pfnAddCommand ("-moveup",IN_UpUp);
|
||||
gEngfuncs.pfnAddCommand ("+movedown",IN_DownDown);
|
||||
gEngfuncs.pfnAddCommand ("-movedown",IN_DownUp);
|
||||
gEngfuncs.pfnAddCommand ("+left",IN_LeftDown);
|
||||
gEngfuncs.pfnAddCommand ("-left",IN_LeftUp);
|
||||
gEngfuncs.pfnAddCommand ("+right",IN_RightDown);
|
||||
gEngfuncs.pfnAddCommand ("-right",IN_RightUp);
|
||||
gEngfuncs.pfnAddCommand ("+forward",IN_ForwardDown);
|
||||
gEngfuncs.pfnAddCommand ("-forward",IN_ForwardUp);
|
||||
gEngfuncs.pfnAddCommand ("+back",IN_BackDown);
|
||||
gEngfuncs.pfnAddCommand ("-back",IN_BackUp);
|
||||
gEngfuncs.pfnAddCommand ("+lookup", IN_LookupDown);
|
||||
gEngfuncs.pfnAddCommand ("-lookup", IN_LookupUp);
|
||||
gEngfuncs.pfnAddCommand ("+lookdown", IN_LookdownDown);
|
||||
gEngfuncs.pfnAddCommand ("-lookdown", IN_LookdownUp);
|
||||
gEngfuncs.pfnAddCommand ("+strafe", IN_StrafeDown);
|
||||
gEngfuncs.pfnAddCommand ("-strafe", IN_StrafeUp);
|
||||
gEngfuncs.pfnAddCommand ("+moveleft", IN_MoveleftDown);
|
||||
gEngfuncs.pfnAddCommand ("-moveleft", IN_MoveleftUp);
|
||||
gEngfuncs.pfnAddCommand ("+moveright", IN_MoverightDown);
|
||||
gEngfuncs.pfnAddCommand ("-moveright", IN_MoverightUp);
|
||||
gEngfuncs.pfnAddCommand ("+speed", IN_SpeedDown);
|
||||
gEngfuncs.pfnAddCommand ("-speed", IN_SpeedUp);
|
||||
gEngfuncs.pfnAddCommand ("+attack", IN_AttackDown);
|
||||
gEngfuncs.pfnAddCommand ("-attack", IN_AttackUp);
|
||||
gEngfuncs.pfnAddCommand ("+attack2", IN_Attack2Down);
|
||||
gEngfuncs.pfnAddCommand ("-attack2", IN_Attack2Up);
|
||||
gEngfuncs.pfnAddCommand ("+use", IN_UseDown);
|
||||
gEngfuncs.pfnAddCommand ("-use", IN_UseUp);
|
||||
gEngfuncs.pfnAddCommand ("+jump", IN_JumpDown);
|
||||
gEngfuncs.pfnAddCommand ("-jump", IN_JumpUp);
|
||||
gEngfuncs.pfnAddCommand ("impulse", IN_Impulse);
|
||||
gEngfuncs.pfnAddCommand ("+klook", IN_KLookDown);
|
||||
gEngfuncs.pfnAddCommand ("-klook", IN_KLookUp);
|
||||
gEngfuncs.pfnAddCommand ("+mlook", IN_MLookDown);
|
||||
gEngfuncs.pfnAddCommand ("-mlook", IN_MLookUp);
|
||||
gEngfuncs.pfnAddCommand ("+jlook", IN_JLookDown);
|
||||
gEngfuncs.pfnAddCommand ("-jlook", IN_JLookUp);
|
||||
gEngfuncs.pfnAddCommand ("+duck", IN_DuckDown);
|
||||
gEngfuncs.pfnAddCommand ("-duck", IN_DuckUp);
|
||||
gEngfuncs.pfnAddCommand ("+reload", IN_ReloadDown);
|
||||
gEngfuncs.pfnAddCommand ("-reload", IN_ReloadUp);
|
||||
gEngfuncs.pfnAddCommand ("+alt1", IN_Alt1Down);
|
||||
gEngfuncs.pfnAddCommand ("-alt1", IN_Alt1Up);
|
||||
gEngfuncs.pfnAddCommand ("+score", IN_ScoreDown);
|
||||
gEngfuncs.pfnAddCommand ("-score", IN_ScoreUp);
|
||||
gEngfuncs.pfnAddCommand ("+showscores", IN_ScoreDown);
|
||||
gEngfuncs.pfnAddCommand ("-showscores", IN_ScoreUp);
|
||||
gEngfuncs.pfnAddCommand ("+graph", IN_GraphDown);
|
||||
gEngfuncs.pfnAddCommand ("-graph", IN_GraphUp);
|
||||
gEngfuncs.pfnAddCommand ("+break",IN_BreakDown);
|
||||
gEngfuncs.pfnAddCommand ("-break",IN_BreakUp);
|
||||
|
||||
lookstrafe = gEngfuncs.pfnRegisterVariable ( "lookstrafe", "0", FCVAR_ARCHIVE );
|
||||
lookspring = gEngfuncs.pfnRegisterVariable ( "lookspring", "0", FCVAR_ARCHIVE );
|
||||
cl_anglespeedkey = gEngfuncs.pfnRegisterVariable ( "cl_anglespeedkey", "0.67", 0 );
|
||||
cl_yawspeed = gEngfuncs.pfnRegisterVariable ( "cl_yawspeed", "210", 0 );
|
||||
cl_pitchspeed = gEngfuncs.pfnRegisterVariable ( "cl_pitchspeed", "225", 0 );
|
||||
cl_upspeed = gEngfuncs.pfnRegisterVariable ( "cl_upspeed", "320", 0 );
|
||||
cl_forwardspeed = gEngfuncs.pfnRegisterVariable ( "cl_forwardspeed", "400", FCVAR_ARCHIVE );
|
||||
cl_backspeed = gEngfuncs.pfnRegisterVariable ( "cl_backspeed", "400", FCVAR_ARCHIVE );
|
||||
cl_sidespeed = gEngfuncs.pfnRegisterVariable ( "cl_sidespeed", "400", 0 );
|
||||
cl_movespeedkey = gEngfuncs.pfnRegisterVariable ( "cl_movespeedkey", "0.3", 0 );
|
||||
cl_pitchup = gEngfuncs.pfnRegisterVariable ( "cl_pitchup", "89", 0 );
|
||||
cl_pitchdown = gEngfuncs.pfnRegisterVariable ( "cl_pitchdown", "89", 0 );
|
||||
|
||||
cl_vsmoothing = gEngfuncs.pfnRegisterVariable ( "cl_vsmoothing", "0.05", FCVAR_ARCHIVE );
|
||||
|
||||
m_pitch = gEngfuncs.pfnRegisterVariable ( "m_pitch","0.022", FCVAR_ARCHIVE );
|
||||
m_yaw = gEngfuncs.pfnRegisterVariable ( "m_yaw","0.022", FCVAR_ARCHIVE );
|
||||
m_forward = gEngfuncs.pfnRegisterVariable ( "m_forward","1", FCVAR_ARCHIVE );
|
||||
m_side = gEngfuncs.pfnRegisterVariable ( "m_side","0.8", FCVAR_ARCHIVE );
|
||||
|
||||
// Initialize third person camera controls.
|
||||
CAM_Init();
|
||||
// Initialize inputs
|
||||
IN_Init();
|
||||
// Initialize keyboard
|
||||
KB_Init();
|
||||
// Initialize view system
|
||||
V_Init();
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ShutdownInput
|
||||
============
|
||||
*/
|
||||
void ShutdownInput (void)
|
||||
{
|
||||
IN_Shutdown();
|
||||
KB_Shutdown();
|
||||
}
|
||||
|
||||
void DLLEXPORT HUD_Shutdown( void )
|
||||
{
|
||||
ShutdownInput();
|
||||
}
|
940
cl_dll/inputw32.cpp
Normal file
940
cl_dll/inputw32.cpp
Normal file
@ -0,0 +1,940 @@
|
||||
// in_win.c -- windows 95 mouse and joystick code
|
||||
// 02/21/97 JCB Added extended DirectInput code to support external controllers.
|
||||
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "camera.h"
|
||||
#include "kbutton.h"
|
||||
#include "cvardef.h"
|
||||
#include "usercmd.h"
|
||||
#include "const.h"
|
||||
#include "camera.h"
|
||||
#include "in_defs.h"
|
||||
#include "../engine/keydefs.h"
|
||||
#include "view.h"
|
||||
#include "windows.h"
|
||||
|
||||
#define MOUSE_BUTTON_COUNT 5
|
||||
|
||||
// Set this to 1 to show mouse cursor. Experimental
|
||||
int g_iVisibleMouse = 0;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void DLLEXPORT IN_ActivateMouse( void );
|
||||
void DLLEXPORT IN_DeactivateMouse( void );
|
||||
void DLLEXPORT IN_MouseEvent (int mstate);
|
||||
void DLLEXPORT IN_Accumulate (void);
|
||||
void DLLEXPORT IN_ClearStates (void);
|
||||
}
|
||||
|
||||
extern cl_enginefunc_t gEngfuncs;
|
||||
|
||||
extern int iMouseInUse;
|
||||
|
||||
extern kbutton_t in_strafe;
|
||||
extern kbutton_t in_mlook;
|
||||
extern kbutton_t in_speed;
|
||||
extern kbutton_t in_jlook;
|
||||
|
||||
extern cvar_t *m_pitch;
|
||||
extern cvar_t *m_yaw;
|
||||
extern cvar_t *m_forward;
|
||||
extern cvar_t *m_side;
|
||||
|
||||
extern cvar_t *lookstrafe;
|
||||
extern cvar_t *lookspring;
|
||||
extern cvar_t *cl_pitchdown;
|
||||
extern cvar_t *cl_pitchup;
|
||||
extern cvar_t *cl_yawspeed;
|
||||
extern cvar_t *cl_sidespeed;
|
||||
extern cvar_t *cl_forwardspeed;
|
||||
extern cvar_t *cl_pitchspeed;
|
||||
extern cvar_t *cl_movespeedkey;
|
||||
|
||||
// mouse variables
|
||||
cvar_t *m_filter;
|
||||
cvar_t *sensitivity;
|
||||
|
||||
int mouse_buttons;
|
||||
int mouse_oldbuttonstate;
|
||||
POINT current_pos;
|
||||
int mouse_x, mouse_y, old_mouse_x, old_mouse_y, mx_accum, my_accum;
|
||||
|
||||
static int restore_spi;
|
||||
static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1};
|
||||
static int mouseactive;
|
||||
int mouseinitialized;
|
||||
static int mouseparmsvalid;
|
||||
static int mouseshowtoggle = 1;
|
||||
|
||||
// joystick defines and variables
|
||||
// where should defines be moved?
|
||||
#define JOY_ABSOLUTE_AXIS 0x00000000 // control like a joystick
|
||||
#define JOY_RELATIVE_AXIS 0x00000010 // control like a mouse, spinner, trackball
|
||||
#define JOY_MAX_AXES 6 // X, Y, Z, R, U, V
|
||||
#define JOY_AXIS_X 0
|
||||
#define JOY_AXIS_Y 1
|
||||
#define JOY_AXIS_Z 2
|
||||
#define JOY_AXIS_R 3
|
||||
#define JOY_AXIS_U 4
|
||||
#define JOY_AXIS_V 5
|
||||
|
||||
enum _ControlList
|
||||
{
|
||||
AxisNada = 0,
|
||||
AxisForward,
|
||||
AxisLook,
|
||||
AxisSide,
|
||||
AxisTurn
|
||||
};
|
||||
|
||||
DWORD dwAxisFlags[JOY_MAX_AXES] =
|
||||
{
|
||||
JOY_RETURNX,
|
||||
JOY_RETURNY,
|
||||
JOY_RETURNZ,
|
||||
JOY_RETURNR,
|
||||
JOY_RETURNU,
|
||||
JOY_RETURNV
|
||||
};
|
||||
|
||||
DWORD dwAxisMap[ JOY_MAX_AXES ];
|
||||
DWORD dwControlMap[ JOY_MAX_AXES ];
|
||||
PDWORD pdwRawValue[ JOY_MAX_AXES ];
|
||||
|
||||
// none of these cvars are saved over a session
|
||||
// this means that advanced controller configuration needs to be executed
|
||||
// each time. this avoids any problems with getting back to a default usage
|
||||
// or when changing from one controller to another. this way at least something
|
||||
// works.
|
||||
cvar_t *in_joystick;
|
||||
cvar_t *joy_name;
|
||||
cvar_t *joy_advanced;
|
||||
cvar_t *joy_advaxisx;
|
||||
cvar_t *joy_advaxisy;
|
||||
cvar_t *joy_advaxisz;
|
||||
cvar_t *joy_advaxisr;
|
||||
cvar_t *joy_advaxisu;
|
||||
cvar_t *joy_advaxisv;
|
||||
cvar_t *joy_forwardthreshold;
|
||||
cvar_t *joy_sidethreshold;
|
||||
cvar_t *joy_pitchthreshold;
|
||||
cvar_t *joy_yawthreshold;
|
||||
cvar_t *joy_forwardsensitivity;
|
||||
cvar_t *joy_sidesensitivity;
|
||||
cvar_t *joy_pitchsensitivity;
|
||||
cvar_t *joy_yawsensitivity;
|
||||
cvar_t *joy_wwhack1;
|
||||
cvar_t *joy_wwhack2;
|
||||
|
||||
int joy_avail, joy_advancedinit, joy_haspov;
|
||||
DWORD joy_oldbuttonstate, joy_oldpovstate;
|
||||
|
||||
int joy_id;
|
||||
DWORD joy_flags;
|
||||
DWORD joy_numbuttons;
|
||||
|
||||
static JOYINFOEX ji;
|
||||
|
||||
/*
|
||||
===========
|
||||
Force_CenterView_f
|
||||
===========
|
||||
*/
|
||||
void Force_CenterView_f (void)
|
||||
{
|
||||
vec3_t viewangles;
|
||||
|
||||
if (!iMouseInUse)
|
||||
{
|
||||
gEngfuncs.GetViewAngles( (float *)viewangles );
|
||||
viewangles[PITCH] = 0;
|
||||
gEngfuncs.SetViewAngles( (float *)viewangles );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_ActivateMouse
|
||||
===========
|
||||
*/
|
||||
void DLLEXPORT IN_ActivateMouse (void)
|
||||
{
|
||||
if (mouseinitialized)
|
||||
{
|
||||
if (mouseparmsvalid)
|
||||
restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0);
|
||||
mouseactive = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_DeactivateMouse
|
||||
===========
|
||||
*/
|
||||
void DLLEXPORT IN_DeactivateMouse (void)
|
||||
{
|
||||
if (mouseinitialized)
|
||||
{
|
||||
if (restore_spi)
|
||||
SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0);
|
||||
|
||||
mouseactive = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_StartupMouse
|
||||
===========
|
||||
*/
|
||||
void IN_StartupMouse (void)
|
||||
{
|
||||
if ( gEngfuncs.CheckParm ("-nomouse", NULL ) )
|
||||
return;
|
||||
|
||||
mouseinitialized = 1;
|
||||
mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0);
|
||||
|
||||
if (mouseparmsvalid)
|
||||
{
|
||||
if ( gEngfuncs.CheckParm ("-noforcemspd", NULL ) )
|
||||
newmouseparms[2] = originalmouseparms[2];
|
||||
|
||||
if ( gEngfuncs.CheckParm ("-noforcemaccel", NULL ) )
|
||||
{
|
||||
newmouseparms[0] = originalmouseparms[0];
|
||||
newmouseparms[1] = originalmouseparms[1];
|
||||
}
|
||||
|
||||
if ( gEngfuncs.CheckParm ("-noforcemparms", NULL ) )
|
||||
{
|
||||
newmouseparms[0] = originalmouseparms[0];
|
||||
newmouseparms[1] = originalmouseparms[1];
|
||||
newmouseparms[2] = originalmouseparms[2];
|
||||
}
|
||||
}
|
||||
|
||||
mouse_buttons = MOUSE_BUTTON_COUNT;
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Shutdown
|
||||
===========
|
||||
*/
|
||||
void IN_Shutdown (void)
|
||||
{
|
||||
IN_DeactivateMouse ();
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_GetMousePos
|
||||
|
||||
Ask for mouse position from engine
|
||||
===========
|
||||
*/
|
||||
void IN_GetMousePos( int *mx, int *my )
|
||||
{
|
||||
gEngfuncs.GetMousePosition( mx, my );
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_ResetMouse
|
||||
|
||||
FIXME: Call through to engine?
|
||||
===========
|
||||
*/
|
||||
void IN_ResetMouse( void )
|
||||
{
|
||||
SetCursorPos ( gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY() );
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_MouseEvent
|
||||
===========
|
||||
*/
|
||||
void DLLEXPORT IN_MouseEvent (int mstate)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( iMouseInUse || g_iVisibleMouse )
|
||||
return;
|
||||
|
||||
// perform button actions
|
||||
for (i=0 ; i<mouse_buttons ; i++)
|
||||
{
|
||||
if ( (mstate & (1<<i)) &&
|
||||
!(mouse_oldbuttonstate & (1<<i)) )
|
||||
{
|
||||
gEngfuncs.Key_Event (K_MOUSE1 + i, 1);
|
||||
}
|
||||
|
||||
if ( !(mstate & (1<<i)) &&
|
||||
(mouse_oldbuttonstate & (1<<i)) )
|
||||
{
|
||||
gEngfuncs.Key_Event (K_MOUSE1 + i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
mouse_oldbuttonstate = mstate;
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_MouseMove
|
||||
===========
|
||||
*/
|
||||
void IN_MouseMove ( float frametime, usercmd_t *cmd)
|
||||
{
|
||||
int mx, my;
|
||||
vec3_t viewangles;
|
||||
|
||||
gEngfuncs.GetViewAngles( (float *)viewangles );
|
||||
|
||||
if ( in_mlook.state & 1)
|
||||
{
|
||||
V_StopPitchDrift ();
|
||||
}
|
||||
|
||||
//jjb - this disbles normal mouse control if the user is trying to
|
||||
// move the camera, or if the mouse cursor is visible or if we're in intermission
|
||||
if ( !iMouseInUse && !g_iVisibleMouse && !gHUD.m_iIntermission )
|
||||
{
|
||||
GetCursorPos (¤t_pos);
|
||||
|
||||
mx = current_pos.x - gEngfuncs.GetWindowCenterX() + mx_accum;
|
||||
my = current_pos.y - gEngfuncs.GetWindowCenterY() + my_accum;
|
||||
|
||||
mx_accum = 0;
|
||||
my_accum = 0;
|
||||
|
||||
if (m_filter->value)
|
||||
{
|
||||
mouse_x = (mx + old_mouse_x) * 0.5;
|
||||
mouse_y = (my + old_mouse_y) * 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse_x = mx;
|
||||
mouse_y = my;
|
||||
}
|
||||
|
||||
old_mouse_x = mx;
|
||||
old_mouse_y = my;
|
||||
|
||||
if ( gHUD.GetSensitivity() != 0 )
|
||||
{
|
||||
mouse_x *= gHUD.GetSensitivity();
|
||||
mouse_y *= gHUD.GetSensitivity();
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse_x *= sensitivity->value;
|
||||
mouse_y *= sensitivity->value;
|
||||
}
|
||||
|
||||
// add mouse X/Y movement to cmd
|
||||
if ( (in_strafe.state & 1) || (lookstrafe->value && (in_mlook.state & 1) ))
|
||||
cmd->sidemove += m_side->value * mouse_x;
|
||||
else
|
||||
viewangles[YAW] -= m_yaw->value * mouse_x;
|
||||
|
||||
if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
|
||||
{
|
||||
viewangles[PITCH] += m_pitch->value * mouse_y;
|
||||
if (viewangles[PITCH] > cl_pitchdown->value)
|
||||
viewangles[PITCH] = cl_pitchdown->value;
|
||||
if (viewangles[PITCH] < -cl_pitchup->value)
|
||||
viewangles[PITCH] = -cl_pitchup->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((in_strafe.state & 1) && gEngfuncs.IsNoClipping() )
|
||||
{
|
||||
cmd->upmove -= m_forward->value * mouse_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->forwardmove -= m_forward->value * mouse_y;
|
||||
}
|
||||
}
|
||||
|
||||
// if the mouse has moved, force it to the center, so there's room to move
|
||||
if ( mx || my )
|
||||
{
|
||||
IN_ResetMouse();
|
||||
}
|
||||
}
|
||||
|
||||
gEngfuncs.SetViewAngles( (float *)viewangles );
|
||||
|
||||
/*
|
||||
//#define TRACE_TEST
|
||||
#if defined( TRACE_TEST )
|
||||
{
|
||||
int mx, my;
|
||||
void V_Move( int mx, int my );
|
||||
IN_GetMousePos( &mx, &my );
|
||||
V_Move( mx, my );
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Accumulate
|
||||
===========
|
||||
*/
|
||||
void DLLEXPORT IN_Accumulate (void)
|
||||
{
|
||||
//only accumulate mouse if we are not moving the camera with the mouse
|
||||
if ( !iMouseInUse && !g_iVisibleMouse )
|
||||
{
|
||||
if (mouseactive)
|
||||
{
|
||||
GetCursorPos (¤t_pos);
|
||||
|
||||
mx_accum += current_pos.x - gEngfuncs.GetWindowCenterX();
|
||||
my_accum += current_pos.y - gEngfuncs.GetWindowCenterY();
|
||||
|
||||
// force the mouse to the center, so there's room to move
|
||||
IN_ResetMouse();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
IN_ClearStates
|
||||
===================
|
||||
*/
|
||||
void DLLEXPORT IN_ClearStates (void)
|
||||
{
|
||||
if ( !mouseactive )
|
||||
return;
|
||||
|
||||
mx_accum = 0;
|
||||
my_accum = 0;
|
||||
mouse_oldbuttonstate = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
IN_StartupJoystick
|
||||
===============
|
||||
*/
|
||||
void IN_StartupJoystick (void)
|
||||
{
|
||||
int numdevs;
|
||||
JOYCAPS jc;
|
||||
MMRESULT mmr;
|
||||
|
||||
// assume no joystick
|
||||
joy_avail = 0;
|
||||
|
||||
// abort startup if user requests no joystick
|
||||
if ( gEngfuncs.CheckParm ("-nojoy", NULL ) )
|
||||
return;
|
||||
|
||||
// verify joystick driver is present
|
||||
if ((numdevs = joyGetNumDevs ()) == 0)
|
||||
{
|
||||
gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// cycle through the joystick ids for the first valid one
|
||||
for (joy_id=0 ; joy_id<numdevs ; joy_id++)
|
||||
{
|
||||
memset (&ji, 0, sizeof(ji));
|
||||
ji.dwSize = sizeof(ji);
|
||||
ji.dwFlags = JOY_RETURNCENTERED;
|
||||
|
||||
if ((mmr = joyGetPosEx (joy_id, &ji)) == JOYERR_NOERROR)
|
||||
break;
|
||||
}
|
||||
|
||||
// abort startup if we didn't find a valid joystick
|
||||
if (mmr != JOYERR_NOERROR)
|
||||
{
|
||||
gEngfuncs.Con_DPrintf ("joystick not found -- no valid joysticks (%x)\n\n", mmr);
|
||||
return;
|
||||
}
|
||||
|
||||
// get the capabilities of the selected joystick
|
||||
// abort startup if command fails
|
||||
memset (&jc, 0, sizeof(jc));
|
||||
if ((mmr = joyGetDevCaps (joy_id, &jc, sizeof(jc))) != JOYERR_NOERROR)
|
||||
{
|
||||
gEngfuncs.Con_DPrintf ("joystick not found -- invalid joystick capabilities (%x)\n\n", mmr);
|
||||
return;
|
||||
}
|
||||
|
||||
// save the joystick's number of buttons and POV status
|
||||
joy_numbuttons = jc.wNumButtons;
|
||||
joy_haspov = jc.wCaps & JOYCAPS_HASPOV;
|
||||
|
||||
// old button and POV states default to no buttons pressed
|
||||
joy_oldbuttonstate = joy_oldpovstate = 0;
|
||||
|
||||
// mark the joystick as available and advanced initialization not completed
|
||||
// this is needed as cvars are not available during initialization
|
||||
gEngfuncs.Con_Printf ("joystick found\n\n", mmr);
|
||||
joy_avail = 1;
|
||||
joy_advancedinit = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
RawValuePointer
|
||||
===========
|
||||
*/
|
||||
PDWORD RawValuePointer (int axis)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case JOY_AXIS_X:
|
||||
return &ji.dwXpos;
|
||||
case JOY_AXIS_Y:
|
||||
return &ji.dwYpos;
|
||||
case JOY_AXIS_Z:
|
||||
return &ji.dwZpos;
|
||||
case JOY_AXIS_R:
|
||||
return &ji.dwRpos;
|
||||
case JOY_AXIS_U:
|
||||
return &ji.dwUpos;
|
||||
case JOY_AXIS_V:
|
||||
return &ji.dwVpos;
|
||||
}
|
||||
// FIX: need to do some kind of error
|
||||
return &ji.dwXpos;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
Joy_AdvancedUpdate_f
|
||||
===========
|
||||
*/
|
||||
void Joy_AdvancedUpdate_f (void)
|
||||
{
|
||||
|
||||
// called once by IN_ReadJoystick and by user whenever an update is needed
|
||||
// cvars are now available
|
||||
int i;
|
||||
DWORD dwTemp;
|
||||
|
||||
// initialize all the maps
|
||||
for (i = 0; i < JOY_MAX_AXES; i++)
|
||||
{
|
||||
dwAxisMap[i] = AxisNada;
|
||||
dwControlMap[i] = JOY_ABSOLUTE_AXIS;
|
||||
pdwRawValue[i] = RawValuePointer(i);
|
||||
}
|
||||
|
||||
if( joy_advanced->value == 0.0)
|
||||
{
|
||||
// default joystick initialization
|
||||
// 2 axes only with joystick control
|
||||
dwAxisMap[JOY_AXIS_X] = AxisTurn;
|
||||
// dwControlMap[JOY_AXIS_X] = JOY_ABSOLUTE_AXIS;
|
||||
dwAxisMap[JOY_AXIS_Y] = AxisForward;
|
||||
// dwControlMap[JOY_AXIS_Y] = JOY_ABSOLUTE_AXIS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( strcmp ( joy_name->string, "joystick") != 0 )
|
||||
{
|
||||
// notify user of advanced controller
|
||||
gEngfuncs.Con_Printf ("\n%s configured\n\n", joy_name->string);
|
||||
}
|
||||
|
||||
// advanced initialization here
|
||||
// data supplied by user via joy_axisn cvars
|
||||
dwTemp = (DWORD) joy_advaxisx->value;
|
||||
dwAxisMap[JOY_AXIS_X] = dwTemp & 0x0000000f;
|
||||
dwControlMap[JOY_AXIS_X] = dwTemp & JOY_RELATIVE_AXIS;
|
||||
dwTemp = (DWORD) joy_advaxisy->value;
|
||||
dwAxisMap[JOY_AXIS_Y] = dwTemp & 0x0000000f;
|
||||
dwControlMap[JOY_AXIS_Y] = dwTemp & JOY_RELATIVE_AXIS;
|
||||
dwTemp = (DWORD) joy_advaxisz->value;
|
||||
dwAxisMap[JOY_AXIS_Z] = dwTemp & 0x0000000f;
|
||||
dwControlMap[JOY_AXIS_Z] = dwTemp & JOY_RELATIVE_AXIS;
|
||||
dwTemp = (DWORD) joy_advaxisr->value;
|
||||
dwAxisMap[JOY_AXIS_R] = dwTemp & 0x0000000f;
|
||||
dwControlMap[JOY_AXIS_R] = dwTemp & JOY_RELATIVE_AXIS;
|
||||
dwTemp = (DWORD) joy_advaxisu->value;
|
||||
dwAxisMap[JOY_AXIS_U] = dwTemp & 0x0000000f;
|
||||
dwControlMap[JOY_AXIS_U] = dwTemp & JOY_RELATIVE_AXIS;
|
||||
dwTemp = (DWORD) joy_advaxisv->value;
|
||||
dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f;
|
||||
dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS;
|
||||
}
|
||||
|
||||
// compute the axes to collect from DirectInput
|
||||
joy_flags = JOY_RETURNCENTERED | JOY_RETURNBUTTONS | JOY_RETURNPOV;
|
||||
for (i = 0; i < JOY_MAX_AXES; i++)
|
||||
{
|
||||
if (dwAxisMap[i] != AxisNada)
|
||||
{
|
||||
joy_flags |= dwAxisFlags[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Commands
|
||||
===========
|
||||
*/
|
||||
void IN_Commands (void)
|
||||
{
|
||||
int i, key_index;
|
||||
DWORD buttonstate, povstate;
|
||||
|
||||
if (!joy_avail)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// loop through the joystick buttons
|
||||
// key a joystick event or auxillary event for higher number buttons for each state change
|
||||
buttonstate = ji.dwButtons;
|
||||
for (i=0 ; i < (int)joy_numbuttons ; i++)
|
||||
{
|
||||
if ( (buttonstate & (1<<i)) && !(joy_oldbuttonstate & (1<<i)) )
|
||||
{
|
||||
key_index = (i < 4) ? K_JOY1 : K_AUX1;
|
||||
gEngfuncs.Key_Event (key_index + i, 1);
|
||||
}
|
||||
|
||||
if ( !(buttonstate & (1<<i)) && (joy_oldbuttonstate & (1<<i)) )
|
||||
{
|
||||
key_index = (i < 4) ? K_JOY1 : K_AUX1;
|
||||
gEngfuncs.Key_Event (key_index + i, 0);
|
||||
}
|
||||
}
|
||||
joy_oldbuttonstate = buttonstate;
|
||||
|
||||
if (joy_haspov)
|
||||
{
|
||||
// convert POV information into 4 bits of state information
|
||||
// this avoids any potential problems related to moving from one
|
||||
// direction to another without going through the center position
|
||||
povstate = 0;
|
||||
if(ji.dwPOV != JOY_POVCENTERED)
|
||||
{
|
||||
if (ji.dwPOV == JOY_POVFORWARD)
|
||||
povstate |= 0x01;
|
||||
if (ji.dwPOV == JOY_POVRIGHT)
|
||||
povstate |= 0x02;
|
||||
if (ji.dwPOV == JOY_POVBACKWARD)
|
||||
povstate |= 0x04;
|
||||
if (ji.dwPOV == JOY_POVLEFT)
|
||||
povstate |= 0x08;
|
||||
}
|
||||
// determine which bits have changed and key an auxillary event for each change
|
||||
for (i=0 ; i < 4 ; i++)
|
||||
{
|
||||
if ( (povstate & (1<<i)) && !(joy_oldpovstate & (1<<i)) )
|
||||
{
|
||||
gEngfuncs.Key_Event (K_AUX29 + i, 1);
|
||||
}
|
||||
|
||||
if ( !(povstate & (1<<i)) && (joy_oldpovstate & (1<<i)) )
|
||||
{
|
||||
gEngfuncs.Key_Event (K_AUX29 + i, 0);
|
||||
}
|
||||
}
|
||||
joy_oldpovstate = povstate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
IN_ReadJoystick
|
||||
===============
|
||||
*/
|
||||
int IN_ReadJoystick (void)
|
||||
{
|
||||
|
||||
memset (&ji, 0, sizeof(ji));
|
||||
ji.dwSize = sizeof(ji);
|
||||
ji.dwFlags = joy_flags;
|
||||
|
||||
if (joyGetPosEx (joy_id, &ji) == JOYERR_NOERROR)
|
||||
{
|
||||
// this is a hack -- there is a bug in the Logitech WingMan Warrior DirectInput Driver
|
||||
// rather than having 32768 be the zero point, they have the zero point at 32668
|
||||
// go figure -- anyway, now we get the full resolution out of the device
|
||||
if (joy_wwhack1->value != 0.0)
|
||||
{
|
||||
ji.dwUpos += 100;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// read error occurred
|
||||
// turning off the joystick seems too harsh for 1 read error,\
|
||||
// but what should be done?
|
||||
// Con_Printf ("IN_ReadJoystick: no response\n");
|
||||
// joy_avail = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_JoyMove
|
||||
===========
|
||||
*/
|
||||
void IN_JoyMove ( float frametime, usercmd_t *cmd )
|
||||
{
|
||||
float speed, aspeed;
|
||||
float fAxisValue, fTemp;
|
||||
int i;
|
||||
vec3_t viewangles;
|
||||
|
||||
gEngfuncs.GetViewAngles( (float *)viewangles );
|
||||
|
||||
|
||||
// complete initialization if first time in
|
||||
// this is needed as cvars are not available at initialization time
|
||||
if( joy_advancedinit != 1 )
|
||||
{
|
||||
Joy_AdvancedUpdate_f();
|
||||
joy_advancedinit = 1;
|
||||
}
|
||||
|
||||
// verify joystick is available and that the user wants to use it
|
||||
if (!joy_avail || !in_joystick->value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// collect the joystick data, if possible
|
||||
if (IN_ReadJoystick () != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (in_speed.state & 1)
|
||||
speed = cl_movespeedkey->value;
|
||||
else
|
||||
speed = 1;
|
||||
|
||||
aspeed = speed * frametime;
|
||||
|
||||
// loop through the axes
|
||||
for (i = 0; i < JOY_MAX_AXES; i++)
|
||||
{
|
||||
// get the floating point zero-centered, potentially-inverted data for the current axis
|
||||
fAxisValue = (float) *pdwRawValue[i];
|
||||
// move centerpoint to zero
|
||||
fAxisValue -= 32768.0;
|
||||
|
||||
if (joy_wwhack2->value != 0.0)
|
||||
{
|
||||
if (dwAxisMap[i] == AxisTurn)
|
||||
{
|
||||
// this is a special formula for the Logitech WingMan Warrior
|
||||
// y=ax^b; where a = 300 and b = 1.3
|
||||
// also x values are in increments of 800 (so this is factored out)
|
||||
// then bounds check result to level out excessively high spin rates
|
||||
fTemp = 300.0 * pow(abs(fAxisValue) / 800.0, 1.3);
|
||||
if (fTemp > 14000.0)
|
||||
fTemp = 14000.0;
|
||||
// restore direction information
|
||||
fAxisValue = (fAxisValue > 0.0) ? fTemp : -fTemp;
|
||||
}
|
||||
}
|
||||
|
||||
// convert range from -32768..32767 to -1..1
|
||||
fAxisValue /= 32768.0;
|
||||
|
||||
switch (dwAxisMap[i])
|
||||
{
|
||||
case AxisForward:
|
||||
if ((joy_advanced->value == 0.0) && (in_jlook.state & 1))
|
||||
{
|
||||
// user wants forward control to become look control
|
||||
if (fabs(fAxisValue) > joy_pitchthreshold->value)
|
||||
{
|
||||
// if mouse invert is on, invert the joystick pitch value
|
||||
// only absolute control support here (joy_advanced is 0)
|
||||
if (m_pitch->value < 0.0)
|
||||
{
|
||||
viewangles[PITCH] -= (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value;
|
||||
}
|
||||
V_StopPitchDrift();
|
||||
}
|
||||
else
|
||||
{
|
||||
// no pitch movement
|
||||
// disable pitch return-to-center unless requested by user
|
||||
// *** this code can be removed when the lookspring bug is fixed
|
||||
// *** the bug always has the lookspring feature on
|
||||
if(lookspring->value == 0.0)
|
||||
{
|
||||
V_StopPitchDrift();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// user wants forward control to be forward control
|
||||
if (fabs(fAxisValue) > joy_forwardthreshold->value)
|
||||
{
|
||||
cmd->forwardmove += (fAxisValue * joy_forwardsensitivity->value) * speed * cl_forwardspeed->value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AxisSide:
|
||||
if (fabs(fAxisValue) > joy_sidethreshold->value)
|
||||
{
|
||||
cmd->sidemove += (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value;
|
||||
}
|
||||
break;
|
||||
|
||||
case AxisTurn:
|
||||
if ((in_strafe.state & 1) || (lookstrafe->value && (in_jlook.state & 1)))
|
||||
{
|
||||
// user wants turn control to become side control
|
||||
if (fabs(fAxisValue) > joy_sidethreshold->value)
|
||||
{
|
||||
cmd->sidemove -= (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// user wants turn control to be turn control
|
||||
if (fabs(fAxisValue) > joy_yawthreshold->value)
|
||||
{
|
||||
if(dwControlMap[i] == JOY_ABSOLUTE_AXIS)
|
||||
{
|
||||
viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * aspeed * cl_yawspeed->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * speed * 180.0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AxisLook:
|
||||
if (in_jlook.state & 1)
|
||||
{
|
||||
if (fabs(fAxisValue) > joy_pitchthreshold->value)
|
||||
{
|
||||
// pitch movement detected and pitch movement desired by user
|
||||
if(dwControlMap[i] == JOY_ABSOLUTE_AXIS)
|
||||
{
|
||||
viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * speed * 180.0;
|
||||
}
|
||||
V_StopPitchDrift();
|
||||
}
|
||||
else
|
||||
{
|
||||
// no pitch movement
|
||||
// disable pitch return-to-center unless requested by user
|
||||
// *** this code can be removed when the lookspring bug is fixed
|
||||
// *** the bug always has the lookspring feature on
|
||||
if( lookspring->value == 0.0 )
|
||||
{
|
||||
V_StopPitchDrift();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// bounds check pitch
|
||||
if (viewangles[PITCH] > cl_pitchdown->value)
|
||||
viewangles[PITCH] = cl_pitchdown->value;
|
||||
if (viewangles[PITCH] < -cl_pitchup->value)
|
||||
viewangles[PITCH] = -cl_pitchup->value;
|
||||
|
||||
gEngfuncs.SetViewAngles( (float *)viewangles );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Move
|
||||
===========
|
||||
*/
|
||||
void IN_Move ( float frametime, usercmd_t *cmd)
|
||||
{
|
||||
if ( !iMouseInUse && mouseactive )
|
||||
{
|
||||
IN_MouseMove ( frametime, cmd);
|
||||
}
|
||||
|
||||
IN_JoyMove ( frametime, cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Init
|
||||
===========
|
||||
*/
|
||||
void IN_Init (void)
|
||||
{
|
||||
m_filter = gEngfuncs.pfnRegisterVariable ( "m_filter","0", FCVAR_ARCHIVE );
|
||||
sensitivity = gEngfuncs.pfnRegisterVariable ( "sensitivity","3", FCVAR_ARCHIVE ); // user mouse sensitivity setting.
|
||||
|
||||
in_joystick = gEngfuncs.pfnRegisterVariable ( "joystick","0", FCVAR_ARCHIVE );
|
||||
joy_name = gEngfuncs.pfnRegisterVariable ( "joyname", "joystick", 0 );
|
||||
joy_advanced = gEngfuncs.pfnRegisterVariable ( "joyadvanced", "0", 0 );
|
||||
joy_advaxisx = gEngfuncs.pfnRegisterVariable ( "joyadvaxisx", "0", 0 );
|
||||
joy_advaxisy = gEngfuncs.pfnRegisterVariable ( "joyadvaxisy", "0", 0 );
|
||||
joy_advaxisz = gEngfuncs.pfnRegisterVariable ( "joyadvaxisz", "0", 0 );
|
||||
joy_advaxisr = gEngfuncs.pfnRegisterVariable ( "joyadvaxisr", "0", 0 );
|
||||
joy_advaxisu = gEngfuncs.pfnRegisterVariable ( "joyadvaxisu", "0", 0 );
|
||||
joy_advaxisv = gEngfuncs.pfnRegisterVariable ( "joyadvaxisv", "0", 0 );
|
||||
joy_forwardthreshold = gEngfuncs.pfnRegisterVariable ( "joyforwardthreshold", "0.15", 0 );
|
||||
joy_sidethreshold = gEngfuncs.pfnRegisterVariable ( "joysidethreshold", "0.15", 0 );
|
||||
joy_pitchthreshold = gEngfuncs.pfnRegisterVariable ( "joypitchthreshold", "0.15", 0 );
|
||||
joy_yawthreshold = gEngfuncs.pfnRegisterVariable ( "joyyawthreshold", "0.15", 0 );
|
||||
joy_forwardsensitivity = gEngfuncs.pfnRegisterVariable ( "joyforwardsensitivity", "-1.0", 0 );
|
||||
joy_sidesensitivity = gEngfuncs.pfnRegisterVariable ( "joysidesensitivity", "-1.0", 0 );
|
||||
joy_pitchsensitivity = gEngfuncs.pfnRegisterVariable ( "joypitchsensitivity", "1.0", 0 );
|
||||
joy_yawsensitivity = gEngfuncs.pfnRegisterVariable ( "joyyawsensitivity", "-1.0", 0 );
|
||||
joy_wwhack1 = gEngfuncs.pfnRegisterVariable ( "joywwhack1", "0.0", 0 );
|
||||
joy_wwhack2 = gEngfuncs.pfnRegisterVariable ( "joywwhack2", "0.0", 0 );
|
||||
|
||||
gEngfuncs.pfnAddCommand ("force_centerview", Force_CenterView_f);
|
||||
gEngfuncs.pfnAddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f);
|
||||
|
||||
IN_StartupMouse ();
|
||||
IN_StartupJoystick ();
|
||||
}
|
11
cl_dll/kbutton.h
Normal file
11
cl_dll/kbutton.h
Normal file
@ -0,0 +1,11 @@
|
||||
#if !defined( KBUTTONH )
|
||||
#define KBUTTONH
|
||||
#pragma once
|
||||
|
||||
typedef struct kbutton_s
|
||||
{
|
||||
int down[2]; // key nums holding it down
|
||||
int state; // low bit is down state
|
||||
} kbutton_t;
|
||||
|
||||
#endif // !KBUTTONH
|
@ -18,16 +18,20 @@
|
||||
// generic menu handler
|
||||
//
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include "parsemsg.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
|
||||
#define MAX_MENU_STRING 512
|
||||
char g_szMenuString[MAX_MENU_STRING];
|
||||
char g_szPrelocalisedMenuString[MAX_MENU_STRING];
|
||||
|
||||
int KB_ConvertString( char *in, char **ppout );
|
||||
|
||||
DECLARE_MESSAGE( m_Menu, ShowMenu );
|
||||
|
||||
int CHudMenu :: Init( void )
|
||||
@ -73,7 +77,7 @@ int CHudMenu :: Draw( float flTime )
|
||||
}
|
||||
|
||||
// don't draw the menu if the scoreboard is being shown
|
||||
if ( gHUD.m_Scoreboard.m_iShowscoresHeld )
|
||||
if ( gViewPort && gViewPort->IsScoreBoardVisible() )
|
||||
return 1;
|
||||
|
||||
// draw the menu, along the left-hand side of the screen
|
||||
@ -131,6 +135,8 @@ void CHudMenu :: SelectMenuItem( int menu_item )
|
||||
// if this message is never received, then scores will simply be the combined totals of the players.
|
||||
int CHudMenu :: MsgFunc_ShowMenu( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
char *temp = NULL;
|
||||
|
||||
BEGIN_READ( pbuf, iSize );
|
||||
|
||||
m_bitsValidSlots = READ_SHORT();
|
||||
@ -157,6 +163,13 @@ int CHudMenu :: MsgFunc_ShowMenu( const char *pszName, int iSize, void *pbuf )
|
||||
if ( !NeedMore )
|
||||
{ // we have the whole string, so we can localise it now
|
||||
strcpy( g_szMenuString, gHUD.m_TextMessage.BufferedLocaliseTextString( g_szPrelocalisedMenuString ) );
|
||||
|
||||
// Swap in characters
|
||||
if ( KB_ConvertString( g_szMenuString, &temp ) )
|
||||
{
|
||||
strcpy( g_szMenuString, temp );
|
||||
free( temp );
|
||||
}
|
||||
}
|
||||
|
||||
m_fMenuDisplayed = 1;
|
||||
|
@ -19,7 +19,7 @@
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "parsemsg.h"
|
||||
|
@ -1,4 +1,5 @@
|
||||
SCC = This is a Source Code Control file
|
||||
|
||||
[cl_dll.mak]
|
||||
SCC_Project_Name = "$/HLStandardSDK/SourceCode/cl_dll", NUWHAAAA
|
||||
SCC_Aux_Path = "\\Jeeves\VSSCODE\"
|
||||
SCC_Project_Name = "$/Sdk/Standard/cl_dll", UBZBAAAA
|
||||
|
@ -19,14 +19,18 @@
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include "parsemsg.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
|
||||
extern float *GetClientColor( int clientIndex );
|
||||
|
||||
#define MAX_LINES 5
|
||||
#define MAX_CHARS_PER_LINE 128 /* it can be less than this, depending on char size */
|
||||
#define MAX_CHARS_PER_LINE 256 /* it can be less than this, depending on char size */
|
||||
|
||||
// allow 20 pixels on either side of the text
|
||||
#define MAX_LINE_WIDTH ( ScreenWidth - 40 )
|
||||
@ -34,6 +38,8 @@
|
||||
static float SCROLL_SPEED = 5;
|
||||
|
||||
static char g_szLineBuffer[ MAX_LINES + 1 ][ MAX_CHARS_PER_LINE ];
|
||||
static float *g_pflNameColors[ MAX_LINES + 1 ];
|
||||
static int g_iNameLengths[ MAX_LINES + 1 ];
|
||||
static float flScrollTime = 0; // the time at which the lines next scroll up
|
||||
|
||||
static int Y_START = 0;
|
||||
@ -58,6 +64,8 @@ int CHudSayText :: Init( void )
|
||||
void CHudSayText :: InitHUDData( void )
|
||||
{
|
||||
memset( g_szLineBuffer, 0, sizeof g_szLineBuffer );
|
||||
memset( g_pflNameColors, 0, sizeof g_pflNameColors );
|
||||
memset( g_iNameLengths, 0, sizeof g_iNameLengths );
|
||||
}
|
||||
|
||||
int CHudSayText :: VidInit( void )
|
||||
@ -66,22 +74,31 @@ int CHudSayText :: VidInit( void )
|
||||
}
|
||||
|
||||
|
||||
void ScrollTextUp( void )
|
||||
int ScrollTextUp( void )
|
||||
{
|
||||
ConsolePrint( g_szLineBuffer[0] ); // move the first line into the console buffer
|
||||
g_szLineBuffer[MAX_LINES][0] = 0;
|
||||
memmove( g_szLineBuffer[0], g_szLineBuffer[1], sizeof(g_szLineBuffer) - sizeof(g_szLineBuffer[0]) ); // overwrite the first line
|
||||
memmove( &g_pflNameColors[0], &g_pflNameColors[1], sizeof(g_pflNameColors) - sizeof(g_pflNameColors[0]) );
|
||||
memmove( &g_iNameLengths[0], &g_iNameLengths[1], sizeof(g_iNameLengths) - sizeof(g_iNameLengths[0]) );
|
||||
g_szLineBuffer[MAX_LINES-1][0] = 0;
|
||||
|
||||
if ( g_szLineBuffer[0][0] == ' ' ) // also scroll up following lines
|
||||
{
|
||||
g_szLineBuffer[0][0] = 2;
|
||||
ScrollTextUp();
|
||||
return 1 + ScrollTextUp();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CHudSayText :: Draw( float flTime )
|
||||
{
|
||||
int y = Y_START;
|
||||
|
||||
if ( gViewPort && gViewPort->AllowedToPrintText() == FALSE )
|
||||
return 1;
|
||||
|
||||
// make sure the scrolltime is within reasonable bounds, to guard against the clock being reset
|
||||
flScrollTime = min( flScrollTime, flTime + SCROLL_SPEED );
|
||||
|
||||
@ -105,7 +122,27 @@ int CHudSayText :: Draw( float flTime )
|
||||
for ( int i = 0; i < MAX_LINES; i++ )
|
||||
{
|
||||
if ( *g_szLineBuffer[i] )
|
||||
DrawConsoleString( LINE_START, y, g_szLineBuffer[i] );
|
||||
{
|
||||
if ( *g_szLineBuffer[i] == 2 && g_pflNameColors[i] )
|
||||
{
|
||||
// it's a saytext string
|
||||
static char buf[MAX_PLAYER_NAME_LENGTH+32];
|
||||
|
||||
// draw the first x characters in the player color
|
||||
strncpy( buf, g_szLineBuffer[i], min(g_iNameLengths[i], MAX_PLAYER_NAME_LENGTH+32) );
|
||||
buf[ min(g_iNameLengths[i], MAX_PLAYER_NAME_LENGTH+31) ] = 0;
|
||||
gEngfuncs.pfnDrawSetTextColor( g_pflNameColors[i][0], g_pflNameColors[i][1], g_pflNameColors[i][2] );
|
||||
int x = DrawConsoleString( LINE_START, y, buf );
|
||||
|
||||
// color is reset after each string draw
|
||||
DrawConsoleString( x, y, g_szLineBuffer[i] + g_iNameLengths[i] );
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal draw
|
||||
DrawConsoleString( LINE_START, y, g_szLineBuffer[i] );
|
||||
}
|
||||
}
|
||||
|
||||
y += line_height;
|
||||
}
|
||||
@ -119,13 +156,16 @@ int CHudSayText :: MsgFunc_SayText( const char *pszName, int iSize, void *pbuf )
|
||||
BEGIN_READ( pbuf, iSize );
|
||||
|
||||
int client_index = READ_BYTE(); // the client who spoke the message
|
||||
SayTextPrint( READ_STRING(), iSize - 1 );
|
||||
SayTextPrint( READ_STRING(), iSize - 1, client_index );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize )
|
||||
void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIndex )
|
||||
{
|
||||
if ( gViewPort && gViewPort->AllowedToPrintText() == FALSE )
|
||||
return;
|
||||
|
||||
// find an empty string slot
|
||||
for ( int i = 0; i < MAX_LINES; i++ )
|
||||
{
|
||||
@ -139,6 +179,27 @@ void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize )
|
||||
i = MAX_LINES - 1;
|
||||
}
|
||||
|
||||
g_iNameLengths[i] = 0;
|
||||
g_pflNameColors[i] = NULL;
|
||||
|
||||
// if it's a say message, search for the players name in the string
|
||||
if ( *pszBuf == 2 && clientIndex > 0 )
|
||||
{
|
||||
GetPlayerInfo( clientIndex, &g_PlayerInfoList[clientIndex] );
|
||||
const char *pName = g_PlayerInfoList[clientIndex].name;
|
||||
|
||||
if ( pName )
|
||||
{
|
||||
const char *nameInString = strstr( pszBuf, pName );
|
||||
|
||||
if ( nameInString )
|
||||
{
|
||||
g_iNameLengths[i] = strlen( pName ) + (nameInString - pszBuf);
|
||||
g_pflNameColors[i] = GetClientColor( clientIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strncpy( g_szLineBuffer[i], pszBuf, max(iBufSize -1, MAX_CHARS_PER_LINE-1) );
|
||||
|
||||
// make sure the text fits in one line
|
||||
@ -155,9 +216,9 @@ void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize )
|
||||
PlaySound( "misc/talk.wav", 1 );
|
||||
|
||||
if ( ScreenHeight >= 480 )
|
||||
Y_START = ScreenHeight - 45;
|
||||
Y_START = ScreenHeight - 60;
|
||||
else
|
||||
Y_START = ScreenHeight - 35;
|
||||
Y_START = ScreenHeight - 45;
|
||||
Y_START -= (line_height * (MAX_LINES+1));
|
||||
|
||||
}
|
||||
@ -175,6 +236,21 @@ void CHudSayText :: EnsureTextFitsInOneLineAndWrapIfHaveTo( int line )
|
||||
char *last_break = NULL;
|
||||
for ( char *x = g_szLineBuffer[line]; *x != 0; x++ )
|
||||
{
|
||||
// check for a color change, if so skip past it
|
||||
if ( x[0] == '/' && x[1] == '(' )
|
||||
{
|
||||
x += 2;
|
||||
// skip forward until past mode specifier
|
||||
while ( *x != 0 && *x != ')' )
|
||||
x++;
|
||||
|
||||
if ( *x != 0 )
|
||||
x++;
|
||||
|
||||
if ( *x == 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
char buf[2];
|
||||
buf[1] = 0;
|
||||
|
||||
@ -193,15 +269,23 @@ void CHudSayText :: EnsureTextFitsInOneLineAndWrapIfHaveTo( int line )
|
||||
x = last_break;
|
||||
|
||||
// find an empty string slot
|
||||
for ( int j = 0; j < MAX_LINES; j++ )
|
||||
int j;
|
||||
do
|
||||
{
|
||||
if ( ! *g_szLineBuffer[j] )
|
||||
break;
|
||||
}
|
||||
if ( j == MAX_LINES )
|
||||
{
|
||||
j = MAX_LINES - 1;
|
||||
for ( j = 0; j < MAX_LINES; j++ )
|
||||
{
|
||||
if ( ! *g_szLineBuffer[j] )
|
||||
break;
|
||||
}
|
||||
if ( j == MAX_LINES )
|
||||
{
|
||||
// need to make more room to display text, scroll stuff up then fix the pointers
|
||||
int linesmoved = ScrollTextUp();
|
||||
line -= linesmoved;
|
||||
last_break = last_break - (sizeof(g_szLineBuffer[0]) * linesmoved);
|
||||
}
|
||||
}
|
||||
while ( j == MAX_LINES );
|
||||
|
||||
// copy remaining string into next buffer, making sure it starts with a space character
|
||||
if ( (char)*last_break == (char)' ' )
|
||||
|
@ -1,528 +0,0 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
//
|
||||
// Scoreboard.cpp
|
||||
//
|
||||
// implementation of CHudScoreboard class
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "parsemsg.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
DECLARE_COMMAND( m_Scoreboard, ShowScores );
|
||||
DECLARE_COMMAND( m_Scoreboard, HideScores );
|
||||
|
||||
DECLARE_MESSAGE( m_Scoreboard, ScoreInfo );
|
||||
DECLARE_MESSAGE( m_Scoreboard, TeamInfo );
|
||||
DECLARE_MESSAGE( m_Scoreboard, TeamScore );
|
||||
|
||||
int CHudScoreboard :: Init( void )
|
||||
{
|
||||
gHUD.AddHudElem( this );
|
||||
|
||||
// Hook messages & commands here
|
||||
HOOK_COMMAND( "+showscores", ShowScores );
|
||||
HOOK_COMMAND( "-showscores", HideScores );
|
||||
|
||||
HOOK_MESSAGE( ScoreInfo );
|
||||
HOOK_MESSAGE( TeamScore );
|
||||
HOOK_MESSAGE( TeamInfo );
|
||||
|
||||
InitHUDData();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int CHudScoreboard :: VidInit( void )
|
||||
{
|
||||
// Load sprites here
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CHudScoreboard :: InitHUDData( void )
|
||||
{
|
||||
memset( m_PlayerExtraInfo, 0, sizeof m_PlayerExtraInfo );
|
||||
m_iLastKilledBy = 0;
|
||||
m_fLastKillTime = 0;
|
||||
m_iPlayerNum = 0;
|
||||
m_iNumTeams = 0;
|
||||
memset( m_TeamInfo, 0, sizeof m_TeamInfo );
|
||||
|
||||
m_iFlags &= ~HUD_ACTIVE; // starts out inactive
|
||||
|
||||
m_iFlags |= HUD_INTERMISSION; // is always drawn during an intermission
|
||||
}
|
||||
|
||||
/* The scoreboard
|
||||
We have a minimum width of 1-320 - we could have the field widths scale with it?
|
||||
*/
|
||||
|
||||
// X positions
|
||||
// relative to the side of the scoreboard
|
||||
#define NAME_RANGE_MIN 20
|
||||
#define NAME_RANGE_MAX 145
|
||||
#define KILLS_RANGE_MIN 130
|
||||
#define KILLS_RANGE_MAX 170
|
||||
#define DIVIDER_POS 180
|
||||
#define DEATHS_RANGE_MIN 185
|
||||
#define DEATHS_RANGE_MAX 210
|
||||
#define PING_RANGE_MIN 245
|
||||
#define PING_RANGE_MAX 295
|
||||
|
||||
#define SCOREBOARD_WIDTH 320
|
||||
|
||||
|
||||
// Y positions
|
||||
#define ROW_GAP 13
|
||||
#define ROW_RANGE_MIN 15
|
||||
#define ROW_RANGE_MAX ( ScreenHeight - 50 )
|
||||
|
||||
int CHudScoreboard :: Draw( float fTime )
|
||||
{
|
||||
if ( !m_iShowscoresHeld && gHUD.m_Health.m_iHealth > 0 && !gHUD.m_iIntermission )
|
||||
return 1;
|
||||
|
||||
GetAllPlayersInfo();
|
||||
|
||||
// just sort the list on the fly
|
||||
// list is sorted first by frags, then by deaths
|
||||
float list_slot = 0;
|
||||
int xpos_rel = (ScreenWidth - SCOREBOARD_WIDTH) / 2;
|
||||
|
||||
// print the heading line
|
||||
int ypos = ROW_RANGE_MIN + (list_slot * ROW_GAP);
|
||||
int xpos = NAME_RANGE_MIN + xpos_rel;
|
||||
|
||||
if ( !gHUD.m_Teamplay )
|
||||
gHUD.DrawHudString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, "Player", 255, 140, 0 );
|
||||
else
|
||||
gHUD.DrawHudString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, "Teams", 255, 140, 0 );
|
||||
|
||||
gHUD.DrawHudStringReverse( KILLS_RANGE_MAX + xpos_rel, ypos, 0, "kills", 255, 140, 0 );
|
||||
gHUD.DrawHudString( DIVIDER_POS + xpos_rel, ypos, ScreenWidth, "/", 255, 140, 0 );
|
||||
gHUD.DrawHudString( DEATHS_RANGE_MIN + xpos_rel + 5, ypos, ScreenWidth, "deaths", 255, 140, 0 );
|
||||
gHUD.DrawHudString( PING_RANGE_MAX + xpos_rel - 35, ypos, ScreenWidth, "latency", 255, 140, 0 );
|
||||
|
||||
list_slot += 1.2;
|
||||
ypos = ROW_RANGE_MIN + (list_slot * ROW_GAP);
|
||||
xpos = NAME_RANGE_MIN + xpos_rel;
|
||||
FillRGBA( xpos - 5, ypos, PING_RANGE_MAX - 5, 1, 255, 140, 0, 255); // draw the seperator line
|
||||
|
||||
list_slot += 0.8;
|
||||
|
||||
if ( !gHUD.m_Teamplay )
|
||||
{
|
||||
// it's not teamplay, so just draw a simple player list
|
||||
DrawPlayers( xpos_rel, list_slot );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// clear out team scores
|
||||
for ( int i = 1; i <= m_iNumTeams; i++ )
|
||||
{
|
||||
if ( !m_TeamInfo[i].scores_overriden )
|
||||
m_TeamInfo[i].frags = m_TeamInfo[i].deaths = 0;
|
||||
m_TeamInfo[i].ping = m_TeamInfo[i].packetloss = 0;
|
||||
}
|
||||
|
||||
// recalc the team scores, then draw them
|
||||
for ( i = 1; i < MAX_PLAYERS; i++ )
|
||||
{
|
||||
if ( m_PlayerInfoList[i].name == NULL )
|
||||
continue; // empty player slot, skip
|
||||
|
||||
if ( m_PlayerExtraInfo[i].teamname[0] == 0 )
|
||||
continue; // skip over players who are not in a team
|
||||
|
||||
// find what team this player is in
|
||||
for ( int j = 1; j <= m_iNumTeams; j++ )
|
||||
{
|
||||
if ( !stricmp( m_PlayerExtraInfo[i].teamname, m_TeamInfo[j].name ) )
|
||||
break;
|
||||
}
|
||||
if ( j > m_iNumTeams ) // player is not in a team, skip to the next guy
|
||||
continue;
|
||||
|
||||
if ( !m_TeamInfo[j].scores_overriden )
|
||||
{
|
||||
m_TeamInfo[j].frags += m_PlayerExtraInfo[i].frags;
|
||||
m_TeamInfo[j].deaths += m_PlayerExtraInfo[i].deaths;
|
||||
}
|
||||
|
||||
m_TeamInfo[j].ping += m_PlayerInfoList[i].ping;
|
||||
m_TeamInfo[j].packetloss += m_PlayerInfoList[i].packetloss;
|
||||
|
||||
if ( m_PlayerInfoList[i].thisplayer )
|
||||
m_TeamInfo[j].ownteam = TRUE;
|
||||
else
|
||||
m_TeamInfo[j].ownteam = FALSE;
|
||||
}
|
||||
|
||||
// find team ping/packetloss averages
|
||||
for ( i = 1; i <= m_iNumTeams; i++ )
|
||||
{
|
||||
m_TeamInfo[i].already_drawn = FALSE;
|
||||
|
||||
if ( m_TeamInfo[i].players > 0 )
|
||||
{
|
||||
m_TeamInfo[i].ping /= m_TeamInfo[i].players; // use the average ping of all the players in the team as the teams ping
|
||||
m_TeamInfo[i].packetloss /= m_TeamInfo[i].players; // use the average ping of all the players in the team as the teams ping
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the teams
|
||||
while ( 1 )
|
||||
{
|
||||
int highest_frags = -99999; int lowest_deaths = 99999;
|
||||
int best_team = 0;
|
||||
|
||||
for ( i = 1; i <= m_iNumTeams; i++ )
|
||||
{
|
||||
if ( m_TeamInfo[i].players < 0 )
|
||||
continue;
|
||||
|
||||
if ( !m_TeamInfo[i].already_drawn && m_TeamInfo[i].frags >= highest_frags )
|
||||
{
|
||||
if ( m_TeamInfo[i].frags > highest_frags || m_TeamInfo[i].deaths < lowest_deaths )
|
||||
{
|
||||
best_team = i;
|
||||
lowest_deaths = m_TeamInfo[i].deaths;
|
||||
highest_frags = m_TeamInfo[i].frags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// draw the best team on the scoreboard
|
||||
if ( !best_team )
|
||||
break;
|
||||
|
||||
// draw out the best team
|
||||
team_info_t *team_info = &m_TeamInfo[best_team];
|
||||
|
||||
ypos = ROW_RANGE_MIN + (list_slot * ROW_GAP);
|
||||
|
||||
// check we haven't drawn too far down
|
||||
if ( ypos > ROW_RANGE_MAX ) // don't draw to close to the lower border
|
||||
break;
|
||||
|
||||
xpos = NAME_RANGE_MIN + xpos_rel;
|
||||
int r = 255, g = 225, b = 55; // draw the stuff kinda yellowish
|
||||
|
||||
if ( team_info->ownteam ) // if it is their team, draw the background different color
|
||||
{
|
||||
// overlay the background in blue, then draw the score text over it
|
||||
FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, PING_RANGE_MAX - 5, ROW_GAP, 0, 0, 255, 70 );
|
||||
}
|
||||
|
||||
// draw their name (left to right)
|
||||
gHUD.DrawHudString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, team_info->name, r, g, b );
|
||||
|
||||
// draw kills (right to left)
|
||||
xpos = KILLS_RANGE_MAX + xpos_rel;
|
||||
gHUD.DrawHudNumberString( xpos, ypos, KILLS_RANGE_MIN + xpos_rel, team_info->frags, r, g, b );
|
||||
|
||||
// draw divider
|
||||
xpos = DIVIDER_POS + xpos_rel;
|
||||
gHUD.DrawHudString( xpos, ypos, xpos + 20, "/", r, g, b );
|
||||
|
||||
// draw deaths
|
||||
xpos = DEATHS_RANGE_MAX + xpos_rel;
|
||||
gHUD.DrawHudNumberString( xpos, ypos, DEATHS_RANGE_MIN + xpos_rel, team_info->deaths, r, g, b );
|
||||
|
||||
// draw ping
|
||||
// draw ping & packetloss
|
||||
static char buf[64];
|
||||
sprintf( buf, "%d", team_info->ping );
|
||||
xpos = ((PING_RANGE_MAX - PING_RANGE_MIN) / 2) + PING_RANGE_MIN + xpos_rel + 25;
|
||||
UnpackRGB( r, g, b, RGB_YELLOWISH );
|
||||
gHUD.DrawHudStringReverse( xpos, ypos, xpos - 50, buf, r, g, b );
|
||||
|
||||
/* Packetloss removed on Kelly 'shipping nazi' Bailey's orders
|
||||
sprintf( buf, " %d", team_info->packetloss );
|
||||
gHUD.DrawHudString( xpos, ypos, xpos+50, buf, r, g, b );
|
||||
*/
|
||||
|
||||
team_info->already_drawn = TRUE; // set the already_drawn to be TRUE, so this team won't get drawn again
|
||||
list_slot++;
|
||||
|
||||
// draw all the players that belong to this team, indented slightly
|
||||
list_slot = DrawPlayers( xpos_rel, list_slot, 10, team_info->name );
|
||||
}
|
||||
|
||||
// draw all the players who are not in a team
|
||||
list_slot += 0.5;
|
||||
DrawPlayers( xpos_rel, list_slot, 0, "" );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// returns the ypos where it finishes drawing
|
||||
int CHudScoreboard :: DrawPlayers( int xpos_rel, float list_slot, int nameoffset, char *team )
|
||||
{
|
||||
// draw the players, in order, and restricted to team if set
|
||||
while ( 1 )
|
||||
{
|
||||
// Find the top ranking player
|
||||
int highest_frags = -99999; int lowest_deaths = 99999;
|
||||
int best_player = 0;
|
||||
|
||||
for ( int i = 1; i < MAX_PLAYERS; i++ )
|
||||
{
|
||||
if ( m_PlayerInfoList[i].name && m_PlayerExtraInfo[i].frags >= highest_frags )
|
||||
{
|
||||
if ( !(team && stricmp(m_PlayerExtraInfo[i].teamname, team)) ) // make sure it is the specified team
|
||||
{
|
||||
extra_player_info_t *pl_info = &m_PlayerExtraInfo[i];
|
||||
if ( pl_info->frags > highest_frags || pl_info->deaths < lowest_deaths )
|
||||
{
|
||||
best_player = i;
|
||||
lowest_deaths = pl_info->deaths;
|
||||
highest_frags = pl_info->frags;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !best_player )
|
||||
break;
|
||||
|
||||
// draw out the best player
|
||||
hud_player_info_t *pl_info = &m_PlayerInfoList[best_player];
|
||||
|
||||
int ypos = ROW_RANGE_MIN + (list_slot * ROW_GAP);
|
||||
|
||||
// check we haven't drawn too far down
|
||||
if ( ypos > ROW_RANGE_MAX ) // don't draw to close to the lower border
|
||||
break;
|
||||
|
||||
int xpos = NAME_RANGE_MIN + xpos_rel;
|
||||
int r = 255, g = 255, b = 255;
|
||||
if ( best_player == m_iLastKilledBy && m_fLastKillTime && m_fLastKillTime > gHUD.m_flTime )
|
||||
{
|
||||
if ( pl_info->thisplayer )
|
||||
{ // green is the suicide color? i wish this could do grey...
|
||||
FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, PING_RANGE_MAX - 5, ROW_GAP, 80, 155, 0, 70 );
|
||||
}
|
||||
else
|
||||
{ // Highlight the killers name - overlay the background in red, then draw the score text over it
|
||||
FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, PING_RANGE_MAX - 5, ROW_GAP, 255, 0, 0, ((float)15 * (float)(m_fLastKillTime - gHUD.m_flTime)) );
|
||||
}
|
||||
}
|
||||
else if ( pl_info->thisplayer ) // if it is their name, draw it a different color
|
||||
{
|
||||
// overlay the background in blue, then draw the score text over it
|
||||
FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, PING_RANGE_MAX - 5, ROW_GAP, 0, 0, 255, 70 );
|
||||
}
|
||||
|
||||
// draw their name (left to right)
|
||||
gHUD.DrawHudString( xpos + nameoffset, ypos, NAME_RANGE_MAX + xpos_rel, pl_info->name, r, g, b );
|
||||
|
||||
// draw kills (right to left)
|
||||
xpos = KILLS_RANGE_MAX + xpos_rel;
|
||||
gHUD.DrawHudNumberString( xpos, ypos, KILLS_RANGE_MIN + xpos_rel, m_PlayerExtraInfo[best_player].frags, r, g, b );
|
||||
|
||||
// draw divider
|
||||
xpos = DIVIDER_POS + xpos_rel;
|
||||
gHUD.DrawHudString( xpos, ypos, xpos + 20, "/", r, g, b );
|
||||
|
||||
// draw deaths
|
||||
xpos = DEATHS_RANGE_MAX + xpos_rel;
|
||||
gHUD.DrawHudNumberString( xpos, ypos, DEATHS_RANGE_MIN + xpos_rel, m_PlayerExtraInfo[best_player].deaths, r, g, b );
|
||||
|
||||
// draw ping & packetloss
|
||||
static char buf[64];
|
||||
sprintf( buf, "%d", m_PlayerInfoList[best_player].ping );
|
||||
xpos = ((PING_RANGE_MAX - PING_RANGE_MIN) / 2) + PING_RANGE_MIN + xpos_rel + 25;
|
||||
gHUD.DrawHudStringReverse( xpos, ypos, xpos - 50, buf, r, g, b );
|
||||
|
||||
/* Packetloss removed on Kelly 'shipping nazi' Bailey's orders
|
||||
if ( m_PlayerInfoList[best_player].packetloss >= 63 )
|
||||
{
|
||||
UnpackRGB( r, g, b, RGB_REDISH );
|
||||
sprintf( buf, " !!!!" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( buf, " %d", m_PlayerInfoList[best_player].packetloss );
|
||||
}
|
||||
|
||||
gHUD.DrawHudString( xpos, ypos, xpos+50, buf, r, g, b );
|
||||
*/
|
||||
|
||||
pl_info->name = NULL; // set the name to be NULL, so this client won't get drawn again
|
||||
list_slot++;
|
||||
}
|
||||
|
||||
return list_slot;
|
||||
}
|
||||
|
||||
|
||||
void CHudScoreboard :: GetAllPlayersInfo( void )
|
||||
{
|
||||
for ( int i = 1; i < MAX_PLAYERS; i++ )
|
||||
{
|
||||
GetPlayerInfo( i, &m_PlayerInfoList[i] );
|
||||
|
||||
if ( m_PlayerInfoList[i].thisplayer )
|
||||
m_iPlayerNum = i; // !!!HACK: this should be initialized elsewhere... maybe gotten from the engine
|
||||
}
|
||||
}
|
||||
|
||||
int CHudScoreboard :: MsgFunc_ScoreInfo( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
m_iFlags |= HUD_ACTIVE;
|
||||
|
||||
BEGIN_READ( pbuf, iSize );
|
||||
short cl = READ_BYTE();
|
||||
short frags = READ_SHORT();
|
||||
short deaths = READ_SHORT();
|
||||
|
||||
if ( cl > 0 && cl <= MAX_PLAYERS )
|
||||
{
|
||||
m_PlayerExtraInfo[cl].frags = frags;
|
||||
m_PlayerExtraInfo[cl].deaths = deaths;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Message handler for TeamInfo message
|
||||
// accepts two values:
|
||||
// byte: client number
|
||||
// string: client team name
|
||||
int CHudScoreboard :: MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
BEGIN_READ( pbuf, iSize );
|
||||
short cl = READ_BYTE();
|
||||
|
||||
if ( cl > 0 && cl <= MAX_PLAYERS )
|
||||
{ // set the players team
|
||||
strncpy( m_PlayerExtraInfo[cl].teamname, READ_STRING(), MAX_TEAM_NAME );
|
||||
}
|
||||
|
||||
// rebuild the list of teams
|
||||
|
||||
// clear out player counts from teams
|
||||
for ( int i = 1; i <= m_iNumTeams; i++ )
|
||||
{
|
||||
m_TeamInfo[i].players = 0;
|
||||
}
|
||||
|
||||
// rebuild the team list
|
||||
GetAllPlayersInfo();
|
||||
m_iNumTeams = 0;
|
||||
for ( i = 1; i < MAX_PLAYERS; i++ )
|
||||
{
|
||||
if ( m_PlayerInfoList[i].name == NULL )
|
||||
continue;
|
||||
|
||||
if ( m_PlayerExtraInfo[i].teamname[0] == 0 )
|
||||
continue; // skip over players who are not in a team
|
||||
|
||||
// is this player in an existing team?
|
||||
for ( int j = 1; j <= m_iNumTeams; j++ )
|
||||
{
|
||||
if ( m_TeamInfo[j].name[0] == '\0' )
|
||||
break;
|
||||
|
||||
if ( !stricmp( m_PlayerExtraInfo[i].teamname, m_TeamInfo[j].name ) )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( j > m_iNumTeams )
|
||||
{ // they aren't in a listed team, so make a new one
|
||||
// search through for an empty team slot
|
||||
for ( int j = 1; j <= m_iNumTeams; j++ )
|
||||
{
|
||||
if ( m_TeamInfo[j].name[0] == '\0' )
|
||||
break;
|
||||
}
|
||||
m_iNumTeams = max( j, m_iNumTeams );
|
||||
|
||||
strncpy( m_TeamInfo[j].name, m_PlayerExtraInfo[i].teamname, MAX_TEAM_NAME );
|
||||
m_TeamInfo[j].players = 0;
|
||||
}
|
||||
|
||||
m_TeamInfo[j].players++;
|
||||
}
|
||||
|
||||
// clear out any empty teams
|
||||
for ( i = 1; i <= m_iNumTeams; i++ )
|
||||
{
|
||||
if ( m_TeamInfo[i].players < 1 )
|
||||
memset( &m_TeamInfo[i], 0, sizeof(team_info_t) );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Message handler for TeamScore message
|
||||
// accepts three values:
|
||||
// string: team name
|
||||
// short: teams kills
|
||||
// short: teams deaths
|
||||
// if this message is never received, then scores will simply be the combined totals of the players.
|
||||
int CHudScoreboard :: MsgFunc_TeamScore( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
BEGIN_READ( pbuf, iSize );
|
||||
char *TeamName = READ_STRING();
|
||||
|
||||
// find the team matching the name
|
||||
for ( int i = 1; i <= m_iNumTeams; i++ )
|
||||
{
|
||||
if ( !stricmp( TeamName, m_TeamInfo[i].name ) )
|
||||
break;
|
||||
}
|
||||
if ( i > m_iNumTeams )
|
||||
return 1;
|
||||
|
||||
// use this new score data instead of combined player scores
|
||||
m_TeamInfo[i].scores_overriden = TRUE;
|
||||
m_TeamInfo[i].frags = READ_SHORT();
|
||||
m_TeamInfo[i].deaths = READ_SHORT();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CHudScoreboard :: DeathMsg( int killer, int victim )
|
||||
{
|
||||
// if we were the one killed, or the world killed us, set the scoreboard to indicate suicide
|
||||
if ( victim == m_iPlayerNum || killer == 0 )
|
||||
{
|
||||
m_iLastKilledBy = killer ? killer : m_iPlayerNum;
|
||||
m_fLastKillTime = gHUD.m_flTime + 10; // display who we were killed by for 10 seconds
|
||||
|
||||
if ( killer == m_iPlayerNum )
|
||||
m_iLastKilledBy = m_iPlayerNum;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CHudScoreboard :: UserCmd_ShowScores( void )
|
||||
{
|
||||
m_iShowscoresHeld = TRUE;
|
||||
}
|
||||
|
||||
void CHudScoreboard :: UserCmd_HideScores( void )
|
||||
{
|
||||
m_iShowscoresHeld = FALSE;
|
||||
}
|
@ -16,10 +16,14 @@
|
||||
// status_icons.cpp
|
||||
//
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include "const.h"
|
||||
#include "entity_state.h"
|
||||
#include "cl_entity.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "parsemsg.h"
|
||||
#include "event_api.h"
|
||||
|
||||
DECLARE_MESSAGE( m_StatusIcons, StatusIcon );
|
||||
|
||||
@ -132,6 +136,13 @@ void CHudStatusIcons::EnableIcon( char *pszIconName, unsigned char red, unsigned
|
||||
m_IconList[i].g = green;
|
||||
m_IconList[i].b = blue;
|
||||
strcpy( m_IconList[i].szSpriteName, pszIconName );
|
||||
|
||||
// Hack: Play Timer sound when a grenade icon is played (in 0.8 seconds)
|
||||
if ( strstr(m_IconList[i].szSpriteName, "grenade") )
|
||||
{
|
||||
cl_entity_t *pthisplayer = gEngfuncs.GetLocalPlayer();
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( pthisplayer->index, pthisplayer->origin, CHAN_STATIC, "weapons/timer.wav", 1.0, ATTN_NORM, 0, PITCH_NORM );
|
||||
}
|
||||
}
|
||||
|
||||
void CHudStatusIcons::DisableIcon( char *pszIconName )
|
||||
|
@ -20,7 +20,7 @@
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include "parsemsg.h"
|
||||
|
||||
#include <string.h>
|
||||
@ -129,10 +129,10 @@ void CHudStatusBar :: ParseStatusString( int line_num )
|
||||
switch ( valtype )
|
||||
{
|
||||
case 'p': // player name
|
||||
GetPlayerInfo( indexval, &gHUD.m_Scoreboard.m_PlayerInfoList[indexval] );
|
||||
if ( gHUD.m_Scoreboard.m_PlayerInfoList[indexval].name != NULL )
|
||||
GetPlayerInfo( indexval, &g_PlayerInfoList[indexval] );
|
||||
if ( g_PlayerInfoList[indexval].name != NULL )
|
||||
{
|
||||
strncpy( szRepString, gHUD.m_Scoreboard.m_PlayerInfoList[indexval].name, MAX_PLAYER_NAME_LENGTH );
|
||||
strncpy( szRepString, g_PlayerInfoList[indexval].name, MAX_PLAYER_NAME_LENGTH );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -178,9 +178,9 @@ int CHudStatusBar :: Draw( float fTime )
|
||||
|
||||
int Y_START;
|
||||
if ( ScreenHeight >= 480 )
|
||||
Y_START = ScreenHeight - 45;
|
||||
Y_START = ScreenHeight - 55;
|
||||
else
|
||||
Y_START = ScreenHeight - 35;
|
||||
Y_START = ScreenHeight - 45;
|
||||
|
||||
int x = 5;
|
||||
int y = Y_START - ( TextHeight * i ); // draw along bottom of screen
|
||||
|
@ -21,11 +21,13 @@
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "parsemsg.h"
|
||||
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
|
||||
DECLARE_MESSAGE( m_TextMessage, TextMsg );
|
||||
|
||||
int CHudTextMessage::Init(void)
|
||||
@ -52,7 +54,7 @@ char *CHudTextMessage::LocaliseTextString( const char *msg, char *dst_buffer, in
|
||||
// cut msg name out of string
|
||||
static char word_buf[255];
|
||||
char *wdst = word_buf, *word_start = src;
|
||||
for ( ++src ; *src >= 'A' && *src <= 'z'; wdst++, src++ )
|
||||
for ( ++src ; (*src >= 'A' && *src <= 'z') || (*src >= '0' && *src <= '9'); wdst++, src++ )
|
||||
{
|
||||
*wdst = *src;
|
||||
}
|
||||
@ -90,8 +92,9 @@ char *CHudTextMessage::LocaliseTextString( const char *msg, char *dst_buffer, in
|
||||
// As above, but with a local static buffer
|
||||
char *CHudTextMessage::BufferedLocaliseTextString( const char *msg )
|
||||
{
|
||||
char dst_buffer[1024];
|
||||
return LocaliseTextString( msg, dst_buffer, 1024 );
|
||||
static char dst_buffer[1024];
|
||||
LocaliseTextString( msg, dst_buffer, 1024 );
|
||||
return dst_buffer;
|
||||
}
|
||||
|
||||
// Simplified version of LocaliseTextString; assumes string is only one word
|
||||
@ -179,6 +182,9 @@ int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf
|
||||
StripEndNewlineFromString( sstr4 );
|
||||
char *psz = szBuf[5];
|
||||
|
||||
if ( gViewPort && gViewPort->AllowedToPrintText() == FALSE )
|
||||
return 1;
|
||||
|
||||
switch ( msg_dest )
|
||||
{
|
||||
case HUD_PRINTCENTER:
|
||||
|
1357
cl_dll/tf_defs.h
Normal file
1357
cl_dll/tf_defs.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,7 @@
|
||||
//
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "parsemsg.h"
|
||||
|
115
cl_dll/tri.cpp
Normal file
115
cl_dll/tri.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
// Triangle rendering, if any
|
||||
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
|
||||
// Triangle rendering apis are in gEngfuncs.pTriAPI
|
||||
|
||||
#include "const.h"
|
||||
#include "entity_state.h"
|
||||
#include "cl_entity.h"
|
||||
#include "triangleapi.h"
|
||||
|
||||
#define DLLEXPORT __declspec( dllexport )
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void DLLEXPORT HUD_DrawNormalTriangles( void );
|
||||
void DLLEXPORT HUD_DrawTransparentTriangles( void );
|
||||
};
|
||||
|
||||
//#define TEST_IT
|
||||
#if defined( TEST_IT )
|
||||
|
||||
/*
|
||||
=================
|
||||
Draw_Triangles
|
||||
|
||||
Example routine. Draws a sprite offset from the player origin.
|
||||
=================
|
||||
*/
|
||||
void Draw_Triangles( void )
|
||||
{
|
||||
cl_entity_t *player;
|
||||
vec3_t org;
|
||||
|
||||
// Load it up with some bogus data
|
||||
player = gEngfuncs.GetLocalPlayer();
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
org = player->origin;
|
||||
|
||||
org.x += 50;
|
||||
org.y += 50;
|
||||
|
||||
if (gHUD.m_hsprCursor == 0)
|
||||
{
|
||||
char sz[256];
|
||||
sprintf( sz, "sprites/cursor.spr" );
|
||||
gHUD.m_hsprCursor = SPR_Load( sz );
|
||||
}
|
||||
|
||||
if ( !gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *)gEngfuncs.GetSpritePointer( gHUD.m_hsprCursor ), 0 ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a triangle, sigh
|
||||
gEngfuncs.pTriAPI->RenderMode( kRenderNormal );
|
||||
gEngfuncs.pTriAPI->CullFace( TRI_NONE );
|
||||
gEngfuncs.pTriAPI->Begin( TRI_QUADS );
|
||||
// Overload p->color with index into tracer palette, p->packedColor with brightness
|
||||
gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, 1.0 );
|
||||
// UNDONE: This gouraud shading causes tracers to disappear on some cards (permedia2)
|
||||
gEngfuncs.pTriAPI->Brightness( 1 );
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 0, 0 );
|
||||
gEngfuncs.pTriAPI->Vertex3f( org.x, org.y, org.z );
|
||||
|
||||
gEngfuncs.pTriAPI->Brightness( 1 );
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 0, 1 );
|
||||
gEngfuncs.pTriAPI->Vertex3f( org.x, org.y + 50, org.z );
|
||||
|
||||
gEngfuncs.pTriAPI->Brightness( 1 );
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 1, 1 );
|
||||
gEngfuncs.pTriAPI->Vertex3f( org.x + 50, org.y + 50, org.z );
|
||||
|
||||
gEngfuncs.pTriAPI->Brightness( 1 );
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 1, 0 );
|
||||
gEngfuncs.pTriAPI->Vertex3f( org.x + 50, org.y, org.z );
|
||||
|
||||
gEngfuncs.pTriAPI->End();
|
||||
gEngfuncs.pTriAPI->RenderMode( kRenderNormal );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================
|
||||
HUD_DrawNormalTriangles
|
||||
|
||||
Non-transparent triangles-- add them here
|
||||
=================
|
||||
*/
|
||||
void DLLEXPORT HUD_DrawNormalTriangles( void )
|
||||
{
|
||||
|
||||
#if defined( TEST_IT )
|
||||
// Draw_Triangles();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
HUD_DrawTransparentTriangles
|
||||
|
||||
Render any triangles with transparent rendermode needs here
|
||||
=================
|
||||
*/
|
||||
void DLLEXPORT HUD_DrawTransparentTriangles( void )
|
||||
{
|
||||
|
||||
#if defined( TEST_IT )
|
||||
// Draw_Triangles();
|
||||
#endif
|
||||
}
|
@ -23,10 +23,98 @@
|
||||
#include "MATH.H"
|
||||
|
||||
#include "hud.h"
|
||||
#include "util.h"
|
||||
#include "cl_util.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
|
||||
#endif
|
||||
|
||||
vec3_t vec3_origin( 0, 0, 0 );
|
||||
|
||||
double sqrt(double x);
|
||||
|
||||
float Length(const float *v)
|
||||
{
|
||||
int i;
|
||||
float length;
|
||||
|
||||
length = 0;
|
||||
for (i=0 ; i< 3 ; i++)
|
||||
length += v[i]*v[i];
|
||||
length = sqrt (length); // FIXME
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
void VectorAngles( const float *forward, float *angles )
|
||||
{
|
||||
float tmp, yaw, pitch;
|
||||
|
||||
if (forward[1] == 0 && forward[0] == 0)
|
||||
{
|
||||
yaw = 0;
|
||||
if (forward[2] > 0)
|
||||
pitch = 90;
|
||||
else
|
||||
pitch = 270;
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw = (atan2(forward[1], forward[0]) * 180 / M_PI);
|
||||
if (yaw < 0)
|
||||
yaw += 360;
|
||||
|
||||
tmp = sqrt (forward[0]*forward[0] + forward[1]*forward[1]);
|
||||
pitch = (atan2(forward[2], tmp) * 180 / M_PI);
|
||||
if (pitch < 0)
|
||||
pitch += 360;
|
||||
}
|
||||
|
||||
angles[0] = pitch;
|
||||
angles[1] = yaw;
|
||||
angles[2] = 0;
|
||||
}
|
||||
|
||||
float VectorNormalize (float *v)
|
||||
{
|
||||
float length, ilength;
|
||||
|
||||
length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
|
||||
length = sqrt (length); // FIXME
|
||||
|
||||
if (length)
|
||||
{
|
||||
ilength = 1/length;
|
||||
v[0] *= ilength;
|
||||
v[1] *= ilength;
|
||||
v[2] *= ilength;
|
||||
}
|
||||
|
||||
return length;
|
||||
|
||||
}
|
||||
|
||||
void VectorInverse ( float *v )
|
||||
{
|
||||
v[0] = -v[0];
|
||||
v[1] = -v[1];
|
||||
v[2] = -v[2];
|
||||
}
|
||||
|
||||
void VectorScale (const float *in, float scale, float *out)
|
||||
{
|
||||
out[0] = in[0]*scale;
|
||||
out[1] = in[1]*scale;
|
||||
out[2] = in[2]*scale;
|
||||
}
|
||||
|
||||
void VectorMA (const float *veca, float scale, const float *vecb, float *vecc)
|
||||
{
|
||||
vecc[0] = veca[0] + scale*vecb[0];
|
||||
vecc[1] = veca[1] + scale*vecb[1];
|
||||
vecc[2] = veca[2] + scale*vecb[2];
|
||||
}
|
||||
|
||||
HSPRITE LoadSprite(const char *pszName)
|
||||
{
|
||||
|
426
cl_dll/vgui_ClassMenu.cpp
Normal file
426
cl_dll/vgui_ClassMenu.cpp
Normal file
@ -0,0 +1,426 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// Purpose: TFC Class Menu
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "VGUI_Font.h"
|
||||
#include <VGUI_TextImage.h>
|
||||
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "camera.h"
|
||||
#include "kbutton.h"
|
||||
#include "cvardef.h"
|
||||
#include "usercmd.h"
|
||||
#include "const.h"
|
||||
#include "camera.h"
|
||||
#include "in_defs.h"
|
||||
#include "parsemsg.h"
|
||||
|
||||
#include "vgui_int.h"
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
#include "vgui_ServerBrowser.h"
|
||||
|
||||
// Class Menu Dimensions
|
||||
#define CLASSMENU_TITLE_X XRES(40)
|
||||
#define CLASSMENU_TITLE_Y YRES(32)
|
||||
#define CLASSMENU_TOPLEFT_BUTTON_X XRES(40)
|
||||
#define CLASSMENU_TOPLEFT_BUTTON_Y YRES(80)
|
||||
#define CLASSMENU_BUTTON_SIZE_X XRES(124)
|
||||
#define CLASSMENU_BUTTON_SIZE_Y YRES(24)
|
||||
#define CLASSMENU_BUTTON_SPACER_Y YRES(8)
|
||||
#define CLASSMENU_WINDOW_X XRES(176)
|
||||
#define CLASSMENU_WINDOW_Y YRES(80)
|
||||
#define CLASSMENU_WINDOW_SIZE_X XRES(424)
|
||||
#define CLASSMENU_WINDOW_SIZE_Y YRES(312)
|
||||
#define CLASSMENU_WINDOW_TEXT_X XRES(150)
|
||||
#define CLASSMENU_WINDOW_TEXT_Y YRES(80)
|
||||
#define CLASSMENU_WINDOW_NAME_X XRES(150)
|
||||
#define CLASSMENU_WINDOW_NAME_Y YRES(8)
|
||||
#define CLASSMENU_WINDOW_PLAYERS_Y YRES(42)
|
||||
|
||||
// Creation
|
||||
CClassMenuPanel::CClassMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide,int tall) : CMenuPanel(iTrans, iRemoveMe, x,y,wide,tall)
|
||||
{
|
||||
// don't show class graphics at below 640x480 resolution
|
||||
bool bShowClassGraphic = true;
|
||||
if ( ScreenWidth < 640 )
|
||||
{
|
||||
bShowClassGraphic = false;
|
||||
}
|
||||
|
||||
memset( m_pClassImages, 0, sizeof(m_pClassImages) );
|
||||
|
||||
// Get the scheme used for the Titles
|
||||
CSchemeManager *pSchemes = gViewPort->GetSchemeManager();
|
||||
|
||||
// schemes
|
||||
SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "Title Font" );
|
||||
SchemeHandle_t hClassWindowText = pSchemes->getSchemeHandle( "Briefing Text" );
|
||||
|
||||
// color schemes
|
||||
int r, g, b, a;
|
||||
|
||||
// Create the title
|
||||
Label *pLabel = new Label( "", CLASSMENU_TITLE_X, CLASSMENU_TITLE_Y );
|
||||
pLabel->setParent( this );
|
||||
pLabel->setFont( pSchemes->getFont(hTitleScheme) );
|
||||
pSchemes->getFgColor( hTitleScheme, r, g, b, a );
|
||||
pLabel->setFgColor( r, g, b, a );
|
||||
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
|
||||
pLabel->setBgColor( r, g, b, a );
|
||||
pLabel->setContentAlignment( vgui::Label::a_west );
|
||||
pLabel->setText(gHUD.m_TextMessage.BufferedLocaliseTextString("#Title_SelectYourClass"));
|
||||
|
||||
// Create the Scroll panel
|
||||
m_pScrollPanel = new CTFScrollPanel( CLASSMENU_WINDOW_X, CLASSMENU_WINDOW_Y, CLASSMENU_WINDOW_SIZE_X, CLASSMENU_WINDOW_SIZE_Y );
|
||||
m_pScrollPanel->setParent(this);
|
||||
//force the scrollbars on, so after the validate clientClip will be smaller
|
||||
m_pScrollPanel->setScrollBarAutoVisible(false, false);
|
||||
m_pScrollPanel->setScrollBarVisible(true, true);
|
||||
m_pScrollPanel->setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0) ) );
|
||||
m_pScrollPanel->validate();
|
||||
|
||||
int clientWide=m_pScrollPanel->getClient()->getWide();
|
||||
|
||||
//turn scrollpanel back into auto show scrollbar mode and validate
|
||||
m_pScrollPanel->setScrollBarAutoVisible(false,true);
|
||||
m_pScrollPanel->setScrollBarVisible(false,false);
|
||||
m_pScrollPanel->validate();
|
||||
|
||||
// Create the Class buttons
|
||||
for (int i = 0; i <= PC_RANDOM; i++)
|
||||
{
|
||||
char sz[256];
|
||||
int iYPos = CLASSMENU_TOPLEFT_BUTTON_Y + ( (CLASSMENU_BUTTON_SIZE_Y + CLASSMENU_BUTTON_SPACER_Y) * i );
|
||||
|
||||
ActionSignal *pASignal = new CMenuHandler_StringCommandClassSelect( sTFClassSelection[i], true );
|
||||
|
||||
// Class button
|
||||
sprintf(sz, "%s", CHudTextMessage::BufferedLocaliseTextString( sLocalisedClasses[i] ) );
|
||||
m_pButtons[i] = new ClassButton( i, sz, CLASSMENU_TOPLEFT_BUTTON_X, iYPos, CLASSMENU_BUTTON_SIZE_X, CLASSMENU_BUTTON_SIZE_Y, true);
|
||||
// RandomPC uses '0'
|
||||
if ( i >= 1 && i <= 9 )
|
||||
{
|
||||
sprintf(sz,"%d",i);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(sz,"0");
|
||||
}
|
||||
m_pButtons[i]->setBoundKey( sz[0] );
|
||||
m_pButtons[i]->setContentAlignment( vgui::Label::a_west );
|
||||
m_pButtons[i]->addActionSignal( pASignal );
|
||||
m_pButtons[i]->addInputSignal( new CHandler_MenuButtonOver(this, i) );
|
||||
m_pButtons[i]->setParent( this );
|
||||
|
||||
// Create the Class Info Window
|
||||
//m_pClassInfoPanel[i] = new CTransparentPanel( 255, CLASSMENU_WINDOW_X, CLASSMENU_WINDOW_Y, CLASSMENU_WINDOW_SIZE_X, CLASSMENU_WINDOW_SIZE_Y );
|
||||
m_pClassInfoPanel[i] = new CTransparentPanel( 255, 0, 0, clientWide, CLASSMENU_WINDOW_SIZE_Y );
|
||||
m_pClassInfoPanel[i]->setParent( m_pScrollPanel->getClient() );
|
||||
//m_pClassInfoPanel[i]->setVisible( false );
|
||||
|
||||
// don't show class pic in lower resolutions
|
||||
int textOffs = XRES(8);
|
||||
|
||||
if ( bShowClassGraphic )
|
||||
{
|
||||
textOffs = CLASSMENU_WINDOW_NAME_X;
|
||||
}
|
||||
|
||||
// Create the Class Name Label
|
||||
sprintf(sz, "#Title_%s", sTFClassSelection[i]);
|
||||
char* localName=CHudTextMessage::BufferedLocaliseTextString( sz );
|
||||
Label *pNameLabel = new Label( "", textOffs, CLASSMENU_WINDOW_NAME_Y );
|
||||
pNameLabel->setFont( pSchemes->getFont(hTitleScheme) );
|
||||
pNameLabel->setParent( m_pClassInfoPanel[i] );
|
||||
pSchemes->getFgColor( hTitleScheme, r, g, b, a );
|
||||
pNameLabel->setFgColor( r, g, b, a );
|
||||
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
|
||||
pNameLabel->setBgColor( r, g, b, a );
|
||||
pNameLabel->setContentAlignment( vgui::Label::a_west );
|
||||
//pNameLabel->setBorder(new LineBorder());
|
||||
pNameLabel->setText(localName);
|
||||
|
||||
// Create the Class Image
|
||||
if ( bShowClassGraphic )
|
||||
{
|
||||
for ( int team = 0; team < 2; team++ )
|
||||
{
|
||||
if ( team == 1 )
|
||||
{
|
||||
sprintf( sz, "%sred", sTFClassSelection[i] );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( sz, "%sblue", sTFClassSelection[i] );
|
||||
}
|
||||
|
||||
m_pClassImages[team][i] = new CImageLabel( sz, 0, 0, CLASSMENU_WINDOW_TEXT_X, CLASSMENU_WINDOW_TEXT_Y );
|
||||
|
||||
CImageLabel *pLabel = m_pClassImages[team][i];
|
||||
pLabel->setParent( m_pClassInfoPanel[i] );
|
||||
//pLabel->setBorder(new LineBorder());
|
||||
|
||||
if ( team != 1 )
|
||||
{
|
||||
pLabel->setVisible( false );
|
||||
}
|
||||
|
||||
// Reposition it based upon it's size
|
||||
int xOut, yOut;
|
||||
pNameLabel->getTextSize( xOut, yOut );
|
||||
pLabel->setPos( (CLASSMENU_WINDOW_TEXT_X - pLabel->getWide()) / 2, yOut /2 );
|
||||
}
|
||||
}
|
||||
|
||||
// Create the Player count string
|
||||
gHUD.m_TextMessage.LocaliseTextString( "#Title_CurrentlyOnYourTeam", m_sPlayersOnTeamString, STRLENMAX_PLAYERSONTEAM );
|
||||
m_pPlayers[i] = new Label( "", textOffs, CLASSMENU_WINDOW_PLAYERS_Y );
|
||||
m_pPlayers[i]->setParent( m_pClassInfoPanel[i] );
|
||||
m_pPlayers[i]->setBgColor( 0, 0, 0, 255 );
|
||||
m_pPlayers[i]->setContentAlignment( vgui::Label::a_west );
|
||||
m_pPlayers[i]->setFont( pSchemes->getFont(hClassWindowText) );
|
||||
|
||||
// Open up the Class Briefing File
|
||||
sprintf(sz, "classes/short_%s.txt", sTFClassSelection[i]);
|
||||
char *cText = "Class Description not available.";
|
||||
char *pfile = (char*)gEngfuncs.COM_LoadFile( sz, 5, NULL );
|
||||
if (pfile)
|
||||
cText = pfile;
|
||||
|
||||
// Create the Text info window
|
||||
TextPanel *pTextWindow = new TextPanel(cText, textOffs, CLASSMENU_WINDOW_TEXT_Y, (CLASSMENU_WINDOW_SIZE_X - textOffs)-5, CLASSMENU_WINDOW_SIZE_Y - CLASSMENU_WINDOW_TEXT_Y);
|
||||
pTextWindow->setParent( m_pClassInfoPanel[i] );
|
||||
pTextWindow->setFont( pSchemes->getFont(hClassWindowText) );
|
||||
pSchemes->getFgColor( hClassWindowText, r, g, b, a );
|
||||
pTextWindow->setFgColor( r, g, b, a );
|
||||
pSchemes->getBgColor( hClassWindowText, r, g, b, a );
|
||||
pTextWindow->setBgColor( r, g, b, a );
|
||||
|
||||
// Resize the Info panel to fit it all
|
||||
int wide,tall;
|
||||
pTextWindow->getTextImage()->getTextSizeWrapped( wide,tall);
|
||||
pTextWindow->setSize(wide,tall);
|
||||
//pTextWindow->setBorder(new LineBorder());
|
||||
int xx,yy;
|
||||
pTextWindow->getPos(xx,yy);
|
||||
int maxX=xx+wide;
|
||||
int maxY=yy+tall;
|
||||
|
||||
//check to see if the image goes lower than the text
|
||||
//just use the red teams [0] images
|
||||
if(m_pClassImages[0][i]!=null)
|
||||
{
|
||||
m_pClassImages[0][i]->getPos(xx,yy);
|
||||
if((yy+m_pClassImages[0][i]->getTall())>maxY)
|
||||
{
|
||||
maxY=yy+m_pClassImages[0][i]->getTall();
|
||||
}
|
||||
}
|
||||
|
||||
m_pClassInfoPanel[i]->setSize( maxX , maxY );
|
||||
//m_pClassInfoPanel[i]->setBorder(new LineBorder());
|
||||
|
||||
}
|
||||
|
||||
// Create the Cancel button
|
||||
m_pCancelButton = new CommandButton( gHUD.m_TextMessage.BufferedLocaliseTextString( "#Menu_Cancel" ), CLASSMENU_TOPLEFT_BUTTON_X, 0, CLASSMENU_BUTTON_SIZE_X, CLASSMENU_BUTTON_SIZE_Y);
|
||||
m_pCancelButton->setParent( this );
|
||||
m_pCancelButton->addActionSignal( new CMenuHandler_TextWindow(HIDE_TEXTWINDOW) );
|
||||
|
||||
m_iCurrentInfo = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Update
|
||||
void CClassMenuPanel::Update()
|
||||
{
|
||||
// Don't allow the player to join a team if they're not in a team
|
||||
if (!g_iTeamNumber)
|
||||
return;
|
||||
|
||||
int iYPos = CLASSMENU_TOPLEFT_BUTTON_Y;
|
||||
|
||||
// Cycle through the rest of the buttons
|
||||
for (int i = 0; i <= PC_RANDOM; i++)
|
||||
{
|
||||
bool bCivilian = (gViewPort->GetValidClasses(g_iTeamNumber) == -1);
|
||||
|
||||
if ( bCivilian )
|
||||
{
|
||||
// If this team can only be civilians, only the civilian button's visible
|
||||
if (i == 0)
|
||||
{
|
||||
m_pButtons[0]->setVisible( true );
|
||||
SetActiveInfo( 0 );
|
||||
iYPos += CLASSMENU_BUTTON_SIZE_Y + CLASSMENU_BUTTON_SPACER_Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pButtons[i]->setVisible( false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_pButtons[i]->IsNotValid() || i == 0 )
|
||||
{
|
||||
m_pButtons[i]->setVisible( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pButtons[i]->setVisible( true );
|
||||
m_pButtons[i]->setPos( CLASSMENU_TOPLEFT_BUTTON_X, iYPos );
|
||||
iYPos += CLASSMENU_BUTTON_SIZE_Y + CLASSMENU_BUTTON_SPACER_Y;
|
||||
|
||||
// Start with the first option up
|
||||
if (!m_iCurrentInfo)
|
||||
SetActiveInfo( i );
|
||||
}
|
||||
}
|
||||
|
||||
// Now count the number of teammembers of this class
|
||||
int iTotal = 0;
|
||||
for ( int j = 1; j < MAX_PLAYERS; j++ )
|
||||
{
|
||||
if ( g_PlayerInfoList[j].name == NULL )
|
||||
continue; // empty player slot, skip
|
||||
if ( g_PlayerExtraInfo[j].teamname[0] == 0 )
|
||||
continue; // skip over players who are not in a team
|
||||
if ( g_PlayerInfoList[j].thisplayer )
|
||||
continue; // skip this player
|
||||
if ( g_PlayerExtraInfo[j].teamnumber != g_iTeamNumber )
|
||||
continue; // skip over players in other teams
|
||||
|
||||
// If this team is forced to be civilians, just count the number of teammates
|
||||
if ( g_PlayerExtraInfo[j].playerclass != i && !bCivilian )
|
||||
continue;
|
||||
|
||||
iTotal++;
|
||||
}
|
||||
|
||||
char sz[256];
|
||||
sprintf(sz, m_sPlayersOnTeamString, iTotal);
|
||||
m_pPlayers[i]->setText( sz );
|
||||
|
||||
// Set the text color to the teamcolor
|
||||
m_pPlayers[i]->setFgColor( iTeamColors[g_iTeamNumber][0], iTeamColors[g_iTeamNumber][1], iTeamColors[g_iTeamNumber][2], 0 );
|
||||
|
||||
// set the graphic to be the team pick
|
||||
for ( int team = 0; team < MAX_TEAMS; team++ )
|
||||
{
|
||||
// unset all the other images
|
||||
if ( m_pClassImages[team][i] )
|
||||
{
|
||||
m_pClassImages[team][i]->setVisible( false );
|
||||
}
|
||||
|
||||
// set the current team image
|
||||
if ( m_pClassImages[g_iTeamNumber-1][i] != NULL )
|
||||
{
|
||||
m_pClassImages[g_iTeamNumber-1][i]->setVisible( true );
|
||||
}
|
||||
else if ( m_pClassImages[0][i] )
|
||||
{
|
||||
m_pClassImages[0][i]->setVisible( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the player already has a class, make the cancel button visible
|
||||
if ( g_iPlayerClass )
|
||||
{
|
||||
m_pCancelButton->setPos( CLASSMENU_TOPLEFT_BUTTON_X, iYPos );
|
||||
m_pCancelButton->setVisible( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pCancelButton->setVisible( false );
|
||||
}
|
||||
}
|
||||
|
||||
//======================================
|
||||
// Key inputs for the Class Menu
|
||||
bool CClassMenuPanel::SlotInput( int iSlot )
|
||||
{
|
||||
if ( (iSlot < 0) || (iSlot > 9) )
|
||||
return false;
|
||||
if ( !m_pButtons[ iSlot ] )
|
||||
return false;
|
||||
|
||||
// Is the button pushable? (0 is special case)
|
||||
if (iSlot == 0)
|
||||
{
|
||||
// Selects Civilian and RandomPC
|
||||
if ( gViewPort->GetValidClasses(g_iTeamNumber) == -1 )
|
||||
{
|
||||
m_pButtons[ 0 ]->fireActionSignal();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Select RandomPC
|
||||
iSlot = 10;
|
||||
}
|
||||
|
||||
if ( !(m_pButtons[ iSlot ]->IsNotValid()) )
|
||||
{
|
||||
m_pButtons[ iSlot ]->fireActionSignal();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//======================================
|
||||
// Update the Class menu before opening it
|
||||
void CClassMenuPanel::Open( void )
|
||||
{
|
||||
Update();
|
||||
CMenuPanel::Open();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called each time a new level is started.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CClassMenuPanel::Initialize( void )
|
||||
{
|
||||
setVisible( false );
|
||||
m_pScrollPanel->setScrollValue( 0, 0 );
|
||||
}
|
||||
|
||||
//======================================
|
||||
// Mouse is over a class button, bring up the class info
|
||||
void CClassMenuPanel::SetActiveInfo( int iInput )
|
||||
{
|
||||
// Remove all the Info panels and bring up the specified one
|
||||
for (int i = 0; i <= PC_RANDOM; i++)
|
||||
{
|
||||
m_pButtons[i]->setArmed( false );
|
||||
m_pClassInfoPanel[i]->setVisible( false );
|
||||
}
|
||||
|
||||
if ( iInput > PC_RANDOM || iInput < 0 )
|
||||
iInput = 0;
|
||||
|
||||
m_pButtons[iInput]->setArmed( true );
|
||||
m_pClassInfoPanel[iInput]->setVisible( true );
|
||||
m_iCurrentInfo = iInput;
|
||||
|
||||
m_pScrollPanel->setScrollValue(0,0);
|
||||
m_pScrollPanel->validate();
|
||||
}
|
||||
|
95
cl_dll/vgui_ConsolePanel.cpp
Normal file
95
cl_dll/vgui_ConsolePanel.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
|
||||
#include"vgui_ConsolePanel.h"
|
||||
#include"hud.h"
|
||||
#include<VGUI_ActionSignal.h>
|
||||
#include<VGUI_TextGrid.h>
|
||||
#include<VGUI_TextEntry.h>
|
||||
#include<VGUI_EtchedBorder.h>
|
||||
#include<VGUI_LoweredBorder.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class Handler : public ActionSignal
|
||||
{
|
||||
private:
|
||||
|
||||
ConsolePanel* _consolePanel;
|
||||
|
||||
public:
|
||||
|
||||
Handler(ConsolePanel* consolePanel)
|
||||
{
|
||||
_consolePanel=consolePanel;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
virtual void actionPerformed(Panel* panel)
|
||||
{
|
||||
_consolePanel->doExecCommand();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
ConsolePanel::ConsolePanel(int x,int y,int wide,int tall) : Panel(x,y,wide,tall)
|
||||
{
|
||||
setBorder(new EtchedBorder());
|
||||
|
||||
_textGrid=new TextGrid(80,21,5,5,200,100);
|
||||
_textGrid->setBorder(new LoweredBorder());
|
||||
_textGrid->setParent(this);
|
||||
|
||||
_textEntry=new TextEntry("",5,5,200,20);
|
||||
_textEntry->setParent(this);
|
||||
_textEntry->addActionSignal(new Handler(this));
|
||||
}
|
||||
|
||||
int ConsolePanel::print(const char* text)
|
||||
{
|
||||
return _textGrid->printf("%s",text);
|
||||
}
|
||||
|
||||
int ConsolePanel::vprintf(const char* format,va_list argList)
|
||||
{
|
||||
return _textGrid->vprintf(format,argList);
|
||||
}
|
||||
|
||||
int ConsolePanel::printf(const char* format,...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList,format);
|
||||
int ret=vprintf(format,argList);
|
||||
va_end(argList);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ConsolePanel::doExecCommand()
|
||||
{
|
||||
char buf[2048];
|
||||
_textEntry->getText(0,buf,2048);
|
||||
_textEntry->setText(null,0);
|
||||
gEngfuncs.pfnClientCmd(buf);
|
||||
}
|
||||
|
||||
void ConsolePanel::setSize(int wide,int tall)
|
||||
{
|
||||
Panel::setSize(wide,tall);
|
||||
|
||||
getPaintSize(wide,tall);
|
||||
|
||||
_textGrid->setBounds(5,5,wide-10,tall-35);
|
||||
_textEntry->setBounds(5,tall-25,wide-10,20);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
32
cl_dll/vgui_ConsolePanel.h
Normal file
32
cl_dll/vgui_ConsolePanel.h
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
#ifndef CONSOLEPANEL_H
|
||||
#define CONSOLEPANEL_H
|
||||
|
||||
#include<stdarg.h>
|
||||
#include<VGUI_Panel.h>
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class TextGrid;
|
||||
class TextEntry;
|
||||
}
|
||||
|
||||
|
||||
class ConsolePanel : public vgui::Panel
|
||||
{
|
||||
private:
|
||||
vgui::TextGrid* _textGrid;
|
||||
vgui::TextEntry* _textEntry;
|
||||
public:
|
||||
ConsolePanel(int x,int y,int wide,int tall);
|
||||
public:
|
||||
virtual void setSize(int wide,int tall);
|
||||
virtual int print(const char* text);
|
||||
virtual int vprintf(const char* format,va_list argList);
|
||||
virtual int printf(const char* format,...);
|
||||
virtual void doExecCommand();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
206
cl_dll/vgui_ControlConfigPanel.cpp
Normal file
206
cl_dll/vgui_ControlConfigPanel.cpp
Normal file
@ -0,0 +1,206 @@
|
||||
|
||||
#include<stdio.h>
|
||||
#include"vgui_ControlConfigPanel.h"
|
||||
#include<VGUI_HeaderPanel.h>
|
||||
#include<VGUI_TablePanel.h>
|
||||
#include<VGUI_Label.h>
|
||||
#include<VGUI_ScrollPanel.h>
|
||||
#include<VGUI_Scheme.h>
|
||||
#include<VGUI_DataInputStream.h>
|
||||
#include<VGUI.h>
|
||||
#include<VGUI_TextEntry.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
namespace
|
||||
{
|
||||
class FooTablePanel : public TablePanel
|
||||
{
|
||||
private:
|
||||
Label* _label;
|
||||
TextEntry* _textEntry;
|
||||
ControlConfigPanel* _controlConfigPanel;
|
||||
public:
|
||||
FooTablePanel(ControlConfigPanel* controlConfigPanel,int x,int y,int wide,int tall,int columnCount) : TablePanel(x,y,wide,tall,columnCount)
|
||||
{
|
||||
_controlConfigPanel=controlConfigPanel;
|
||||
_label=new Label("You are a dumb monkey",0,0,100,20);
|
||||
_label->setBgColor(Scheme::sc_primary3);
|
||||
_label->setFgColor(Scheme::sc_primary1);
|
||||
_label->setFont(Scheme::sf_primary3);
|
||||
|
||||
_textEntry=new TextEntry("",0,0,100,20);
|
||||
//_textEntry->setFont(Scheme::sf_primary3);
|
||||
}
|
||||
public:
|
||||
virtual int getRowCount()
|
||||
{
|
||||
return _controlConfigPanel->GetCVarCount();
|
||||
}
|
||||
virtual int getCellTall(int row)
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
virtual Panel* getCellRenderer(int column,int row,bool columnSelected,bool rowSelected,bool cellSelected)
|
||||
{
|
||||
char cvar[128],desc[128],bind[128],bindAlt[128];
|
||||
_controlConfigPanel->GetCVar(row,cvar,128,desc,128);
|
||||
|
||||
if(cellSelected)
|
||||
{
|
||||
_label->setBgColor(Scheme::sc_primary1);
|
||||
_label->setFgColor(Scheme::sc_primary3);
|
||||
}
|
||||
else
|
||||
if(rowSelected)
|
||||
{
|
||||
_label->setBgColor(Scheme::sc_primary2);
|
||||
_label->setFgColor(Scheme::sc_primary1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_label->setBgColor(Scheme::sc_primary3);
|
||||
_label->setFgColor(Scheme::sc_primary1);
|
||||
}
|
||||
|
||||
switch(column)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
_label->setText(desc);
|
||||
_label->setContentAlignment(Label::a_west);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
_controlConfigPanel->GetCVarBind(cvar,bind,128,bindAlt,128);
|
||||
_label->setText(bind);
|
||||
_label->setContentAlignment(Label::a_center);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
_controlConfigPanel->GetCVarBind(cvar,bind,128,bindAlt,128);
|
||||
_label->setText(bindAlt);
|
||||
_label->setContentAlignment(Label::a_center);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_label->setText("");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return _label;
|
||||
}
|
||||
virtual Panel* startCellEditing(int column,int row)
|
||||
{
|
||||
_textEntry->setText("Goat",strlen("Goat"));
|
||||
_textEntry->requestFocus();
|
||||
return _textEntry;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ControlConfigPanel::ControlConfigPanel(int x,int y,int wide,int tall) : Panel(x,y,wide,tall)
|
||||
{
|
||||
setPaintBorderEnabled(false);
|
||||
setPaintBackgroundEnabled(false);
|
||||
setPaintEnabled(false);
|
||||
|
||||
_actionLabel=new Label("Action");
|
||||
_actionLabel->setBgColor(Scheme::sc_primary3);
|
||||
_actionLabel->setFgColor(Scheme::sc_primary3);
|
||||
|
||||
_keyButtonLabel=new Label("Key / Button");
|
||||
_keyButtonLabel->setBgColor(Scheme::sc_primary3);
|
||||
_keyButtonLabel->setFgColor(Scheme::sc_primary3);
|
||||
|
||||
_alternateLabel=new Label("Alternate");
|
||||
_alternateLabel->setBgColor(Scheme::sc_primary3);
|
||||
_alternateLabel->setFgColor(Scheme::sc_primary3);
|
||||
|
||||
_headerPanel=new HeaderPanel(0,0,wide,20);
|
||||
_headerPanel->setParent(this);
|
||||
|
||||
_headerPanel->addSectionPanel(_actionLabel);
|
||||
_headerPanel->addSectionPanel(_keyButtonLabel);
|
||||
_headerPanel->addSectionPanel(_alternateLabel);
|
||||
|
||||
_headerPanel->setSliderPos( 0, wide/2 );
|
||||
_headerPanel->setSliderPos( 1, (wide/2) + (wide/4) );
|
||||
_headerPanel->setSliderPos( 2, wide );
|
||||
|
||||
_scrollPanel=new ScrollPanel(0,20,wide,tall-20);
|
||||
_scrollPanel->setParent(this);
|
||||
_scrollPanel->setPaintBorderEnabled(false);
|
||||
_scrollPanel->setPaintBackgroundEnabled(false);
|
||||
_scrollPanel->setPaintEnabled(false);
|
||||
_scrollPanel->getClient()->setPaintBorderEnabled(false);
|
||||
_scrollPanel->getClient()->setPaintBackgroundEnabled(false);
|
||||
_scrollPanel->getClient()->setPaintEnabled(false);
|
||||
_scrollPanel->setScrollBarVisible(false,true);
|
||||
|
||||
_tablePanel=new FooTablePanel(this,0,0,_scrollPanel->getClient()->getWide(),800, 3);
|
||||
_tablePanel->setParent(_scrollPanel->getClient());
|
||||
_tablePanel->setHeaderPanel(_headerPanel);
|
||||
_tablePanel->setBgColor(Color(200,0,0,255));
|
||||
_tablePanel->setFgColor(Color(Scheme::sc_primary2));
|
||||
_tablePanel->setGridVisible(true,true);
|
||||
_tablePanel->setGridSize(1,1);
|
||||
}
|
||||
|
||||
void ControlConfigPanel::AddCVar(const char* cvar,const char* desc)
|
||||
{
|
||||
_cvarDar.addElement(vgui_strdup(cvar));
|
||||
_descDar.addElement(vgui_strdup(desc));
|
||||
}
|
||||
|
||||
int ControlConfigPanel::GetCVarCount()
|
||||
{
|
||||
return _cvarDar.getCount();
|
||||
}
|
||||
|
||||
void ControlConfigPanel::GetCVar(int index,char* cvar,int cvarLen,char* desc,int descLen)
|
||||
{
|
||||
vgui_strcpy(cvar,cvarLen,_cvarDar[index]);
|
||||
vgui_strcpy(desc,descLen,_descDar[index]);
|
||||
}
|
||||
|
||||
void ControlConfigPanel::AddCVarFromInputStream(InputStream* is)
|
||||
{
|
||||
if(is==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DataInputStream dis(is);
|
||||
|
||||
bool success;
|
||||
|
||||
while(1)
|
||||
{
|
||||
char buf[256],cvar[128],desc[128];
|
||||
dis.readLine(buf,256,success);
|
||||
if(!success)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(sscanf(buf,"\"%[^\"]\" \"%[^\"]\"",cvar,desc)==2)
|
||||
{
|
||||
AddCVar(cvar,desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ControlConfigPanel::GetCVarBind(const char* cvar,char* bind,int bindLen,char* bindAlt,int bindAltLen)
|
||||
{
|
||||
sprintf(bind,"%s : Bind",cvar);
|
||||
sprintf(bindAlt,"%s : BindAlt",cvar);
|
||||
}
|
||||
|
||||
void ControlConfigPanel::SetCVarBind(const char* cvar,const char* bind,const char* bindAlt)
|
||||
{
|
||||
}
|
||||
|
41
cl_dll/vgui_ControlConfigPanel.h
Normal file
41
cl_dll/vgui_ControlConfigPanel.h
Normal file
@ -0,0 +1,41 @@
|
||||
|
||||
#ifndef CONTROLCONFIGPANEL_H
|
||||
#define CONTROLCONFIGPANEL_H
|
||||
|
||||
#include<VGUI_Panel.h>
|
||||
#include<VGUI_Dar.h>
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class HeaderPanel;
|
||||
class TablePanel;
|
||||
class ScrollPanel;
|
||||
class InputStream;
|
||||
class Label;
|
||||
}
|
||||
|
||||
class ControlConfigPanel : public vgui::Panel
|
||||
{
|
||||
private:
|
||||
vgui::HeaderPanel* _headerPanel;
|
||||
vgui::TablePanel* _tablePanel;
|
||||
vgui::ScrollPanel* _scrollPanel;
|
||||
vgui::Dar<char*> _cvarDar;
|
||||
vgui::Dar<char*> _descDar;
|
||||
vgui::Label* _actionLabel;
|
||||
vgui::Label* _keyButtonLabel;
|
||||
vgui::Label* _alternateLabel;
|
||||
public:
|
||||
ControlConfigPanel(int x,int y,int wide,int tall);
|
||||
public:
|
||||
void AddCVar(const char* cvar,const char* desc);
|
||||
void AddCVarFromInputStream(vgui::InputStream* is);
|
||||
int GetCVarCount();
|
||||
void GetCVar(int index,char* cvar,int cvarLen,char* desc,int descLen);
|
||||
void GetCVarBind(const char* cvar,char* bind,int bindLen,char* bindAlt,int bindAltLen);
|
||||
void SetCVarBind(const char* cvar,const char* bind,const char* bindAlt);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
441
cl_dll/vgui_CustomObjects.cpp
Normal file
441
cl_dll/vgui_CustomObjects.cpp
Normal file
@ -0,0 +1,441 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// Purpose: Contains implementation of various VGUI-derived objects
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "VGUI_Font.h"
|
||||
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "camera.h"
|
||||
#include "kbutton.h"
|
||||
#include "cvardef.h"
|
||||
#include "usercmd.h"
|
||||
#include "const.h"
|
||||
#include "camera.h"
|
||||
#include "in_defs.h"
|
||||
#include "parsemsg.h"
|
||||
|
||||
#include "vgui_int.h"
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
#include "vgui_ServerBrowser.h"
|
||||
|
||||
// Arrow filenames
|
||||
char *sArrowFilenames[] =
|
||||
{
|
||||
"arrowup",
|
||||
"arrowdn",
|
||||
"arrowlt",
|
||||
"arrowrt",
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Loads a .tga file and returns a pointer to the VGUI tga object
|
||||
//-----------------------------------------------------------------------------
|
||||
BitmapTGA *LoadTGA( const char* pImageName )
|
||||
{
|
||||
BitmapTGA *pTGA;
|
||||
|
||||
char sz[256];
|
||||
sprintf(sz, "%%d_%s", pImageName);
|
||||
|
||||
// Load the Image
|
||||
FileInputStream* fis = new FileInputStream( GetVGUITGAName(sz), false );
|
||||
pTGA = new BitmapTGA(fis,true);
|
||||
fis->close();
|
||||
|
||||
return pTGA;
|
||||
}
|
||||
|
||||
//===========================================================
|
||||
// All TFC Hud buttons are derived from this one.
|
||||
CommandButton::CommandButton( const char* text,int x,int y,int wide,int tall, bool bNoHighlight) : Button("",x,y,wide,tall)
|
||||
{
|
||||
m_iPlayerClass = 0;
|
||||
m_bNoHighlight = bNoHighlight;
|
||||
Init();
|
||||
setText( text );
|
||||
}
|
||||
|
||||
CommandButton::CommandButton( int iPlayerClass, const char* text,int x,int y,int wide,int tall) : Button("",x,y,wide,tall)
|
||||
{
|
||||
m_iPlayerClass = iPlayerClass;
|
||||
m_bNoHighlight = false;
|
||||
Init();
|
||||
setText( text );
|
||||
}
|
||||
|
||||
void CommandButton::Init( void )
|
||||
{
|
||||
m_pSubMenu = NULL;
|
||||
m_pSubLabel = NULL;
|
||||
m_pParentMenu = NULL;
|
||||
|
||||
// Set text color to orange
|
||||
setFgColor(Scheme::sc_primary1);
|
||||
|
||||
// left align
|
||||
setContentAlignment( vgui::Label::a_west );
|
||||
|
||||
// Add the Highlight signal
|
||||
if (!m_bNoHighlight)
|
||||
addInputSignal( new CHandler_CommandButtonHighlight(this) );
|
||||
|
||||
// not bound to any button yet
|
||||
m_cBoundKey = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Prepends the button text with the current bound key
|
||||
// if no bound key, then a clear space ' ' instead
|
||||
//-----------------------------------------------------------------------------
|
||||
void CommandButton::RecalculateText( void )
|
||||
{
|
||||
char szBuf[128];
|
||||
|
||||
if ( m_cBoundKey != 0 )
|
||||
{
|
||||
sprintf( szBuf, " %c %s", m_cBoundKey, m_sMainText );
|
||||
szBuf[MAX_BUTTON_SIZE-1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// just draw a space if no key bound
|
||||
sprintf( szBuf, " %s", m_sMainText );
|
||||
szBuf[MAX_BUTTON_SIZE-1] = 0;
|
||||
}
|
||||
|
||||
Button::setText( szBuf );
|
||||
}
|
||||
|
||||
void CommandButton::setText( const char *text )
|
||||
{
|
||||
strncpy( m_sMainText, text, MAX_BUTTON_SIZE );
|
||||
m_sMainText[MAX_BUTTON_SIZE-1] = 0;
|
||||
|
||||
RecalculateText();
|
||||
}
|
||||
|
||||
void CommandButton::setBoundKey( char boundKey )
|
||||
{
|
||||
m_cBoundKey = boundKey;
|
||||
RecalculateText();
|
||||
}
|
||||
|
||||
char CommandButton::getBoundKey( void )
|
||||
{
|
||||
return m_cBoundKey;
|
||||
}
|
||||
|
||||
void CommandButton::AddSubMenu( CCommandMenu *pNewMenu )
|
||||
{
|
||||
m_pSubMenu = pNewMenu;
|
||||
|
||||
// Prevent this button from being pushed
|
||||
setMouseClickEnabled( MOUSE_LEFT, false );
|
||||
}
|
||||
|
||||
void CommandButton::UpdateSubMenus( int iAdjustment )
|
||||
{
|
||||
if ( m_pSubMenu )
|
||||
m_pSubMenu->RecalculatePositions( iAdjustment );
|
||||
}
|
||||
|
||||
void CommandButton::paint()
|
||||
{
|
||||
// Make the sub label paint the same as the button
|
||||
if ( m_pSubLabel )
|
||||
{
|
||||
if ( isSelected() )
|
||||
m_pSubLabel->PushDown();
|
||||
else
|
||||
m_pSubLabel->PushUp();
|
||||
}
|
||||
|
||||
// draw armed button text in white
|
||||
if ( isArmed() )
|
||||
{
|
||||
setFgColor( Scheme::sc_secondary2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
setFgColor( Scheme::sc_primary1 );
|
||||
}
|
||||
|
||||
Button::paint();
|
||||
}
|
||||
|
||||
void CommandButton::paintBackground()
|
||||
{
|
||||
if ( isArmed() )
|
||||
{
|
||||
// Orange highlight background
|
||||
drawSetColor( Scheme::sc_primary2 );
|
||||
drawFilledRect(0,0,_size[0],_size[1]);
|
||||
}
|
||||
|
||||
// Orange Border
|
||||
drawSetColor( Scheme::sc_secondary1 );
|
||||
drawOutlinedRect(0,0,_size[0],_size[1]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Highlights the current button, and all it's parent menus
|
||||
//-----------------------------------------------------------------------------
|
||||
void CommandButton::cursorEntered( void )
|
||||
{
|
||||
// unarm all the other buttons in this menu
|
||||
CCommandMenu *containingMenu = getParentMenu();
|
||||
if ( containingMenu )
|
||||
{
|
||||
containingMenu->ClearButtonsOfArmedState();
|
||||
|
||||
// make all our higher buttons armed
|
||||
CCommandMenu *pCParent = containingMenu->GetParentMenu();
|
||||
if ( pCParent )
|
||||
{
|
||||
CommandButton *pParentButton = pCParent->FindButtonWithSubmenu( containingMenu );
|
||||
|
||||
pParentButton->cursorEntered();
|
||||
}
|
||||
}
|
||||
|
||||
// arm ourselves
|
||||
setArmed( true );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CommandButton::cursorExited( void )
|
||||
{
|
||||
// only clear ourselves if we have do not have a containing menu
|
||||
// only stay armed if we have a sub menu
|
||||
// the buttons only unarm themselves when another button is armed instead
|
||||
if ( !getParentMenu() || !GetSubMenu() )
|
||||
{
|
||||
setArmed( false );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns the command menu that the button is part of, if any
|
||||
// Output : CCommandMenu *
|
||||
//-----------------------------------------------------------------------------
|
||||
CCommandMenu *CommandButton::getParentMenu( void )
|
||||
{
|
||||
return m_pParentMenu;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets the menu that contains this button
|
||||
// Input : *pParentMenu -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CommandButton::setParentMenu( CCommandMenu *pParentMenu )
|
||||
{
|
||||
m_pParentMenu = pParentMenu;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================
|
||||
int ClassButton::IsNotValid()
|
||||
{
|
||||
// If this is the main ChangeClass button, remove it if the player's only able to be civilians
|
||||
if ( m_iPlayerClass == -1 )
|
||||
{
|
||||
if (gViewPort->GetValidClasses(g_iTeamNumber) == -1)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is it an illegal class?
|
||||
if ((gViewPort->GetValidClasses(0) & sTFValidClassInts[ m_iPlayerClass ]) || (gViewPort->GetValidClasses(g_iTeamNumber) & sTFValidClassInts[ m_iPlayerClass ]))
|
||||
return true;
|
||||
|
||||
// Only check current class if they've got autokill on
|
||||
bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0;
|
||||
if ( bAutoKill )
|
||||
{
|
||||
// Is it the player's current class?
|
||||
if ( (gViewPort->IsRandomPC() && m_iPlayerClass == PC_RANDOM) || (!gViewPort->IsRandomPC() && (m_iPlayerClass == g_iPlayerClass)) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================
|
||||
// Button with Class image beneath it
|
||||
CImageLabel::CImageLabel( const char* pImageName,int x,int y ) : Label( "", x,y )
|
||||
{
|
||||
setContentFitted(true);
|
||||
m_pTGA = LoadTGA(pImageName);
|
||||
setImage( m_pTGA );
|
||||
}
|
||||
|
||||
CImageLabel::CImageLabel( const char* pImageName,int x,int y,int wide,int tall ) : Label( "", x,y,wide,tall )
|
||||
{
|
||||
setContentFitted(true);
|
||||
m_pTGA = LoadTGA(pImageName);
|
||||
setImage( m_pTGA );
|
||||
}
|
||||
|
||||
//===========================================================
|
||||
// Image size
|
||||
int CImageLabel::getImageWide( void )
|
||||
{
|
||||
int iXSize, iYSize;
|
||||
m_pTGA->getSize( iXSize, iYSize );
|
||||
return iXSize;
|
||||
}
|
||||
|
||||
int CImageLabel::getImageTall( void )
|
||||
{
|
||||
int iXSize, iYSize;
|
||||
m_pTGA->getSize( iXSize, iYSize );
|
||||
return iYSize;
|
||||
}
|
||||
|
||||
//===========================================================
|
||||
// Various overloaded paint functions for Custom VGUI objects
|
||||
void CCommandMenu::paintBackground()
|
||||
{
|
||||
// Transparent black background
|
||||
drawSetColor(Scheme::sc_primary3);
|
||||
drawFilledRect(0,0,_size[0],_size[1]);
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
// CUSTOM SCROLLPANEL
|
||||
//=================================================================================
|
||||
CTFScrollButton::CTFScrollButton(int iArrow, const char* text,int x,int y,int wide,int tall) : CommandButton(text,x,y,wide,tall)
|
||||
{
|
||||
// Set text color to orange
|
||||
setFgColor(Scheme::sc_primary1);
|
||||
|
||||
// Load in the arrow
|
||||
m_pTGA = LoadTGA( sArrowFilenames[iArrow] );
|
||||
setImage( m_pTGA );
|
||||
|
||||
// Highlight signal
|
||||
InputSignal *pISignal = new CHandler_CommandButtonHighlight(this);
|
||||
addInputSignal(pISignal);
|
||||
}
|
||||
|
||||
void CTFScrollButton::paint( void )
|
||||
{
|
||||
// draw armed button text in white
|
||||
if ( isArmed() )
|
||||
{
|
||||
m_pTGA->setColor( Color(255,255,255, 0) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pTGA->setColor( Color(255,255,255, 128) );
|
||||
}
|
||||
|
||||
m_pTGA->doPaint(this);
|
||||
}
|
||||
|
||||
void CTFScrollButton::paintBackground( void )
|
||||
{
|
||||
/*
|
||||
if ( isArmed() )
|
||||
{
|
||||
// Orange highlight background
|
||||
drawSetColor( Scheme::sc_primary2 );
|
||||
drawFilledRect(0,0,_size[0],_size[1]);
|
||||
}
|
||||
|
||||
// Orange Border
|
||||
drawSetColor( Scheme::sc_secondary1 );
|
||||
drawOutlinedRect(0,0,_size[0]-1,_size[1]);
|
||||
*/
|
||||
}
|
||||
|
||||
void CTFSlider::paintBackground( void )
|
||||
{
|
||||
int wide,tall,nobx,noby;
|
||||
getPaintSize(wide,tall);
|
||||
getNobPos(nobx,noby);
|
||||
|
||||
// Border
|
||||
drawSetColor( Scheme::sc_secondary1 );
|
||||
drawOutlinedRect( 0,0,wide,tall );
|
||||
|
||||
if( isVertical() )
|
||||
{
|
||||
// Nob Fill
|
||||
drawSetColor( Scheme::sc_primary2 );
|
||||
drawFilledRect( 0,nobx,wide,noby );
|
||||
|
||||
// Nob Outline
|
||||
drawSetColor( Scheme::sc_primary1 );
|
||||
drawOutlinedRect( 0,nobx,wide,noby );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nob Fill
|
||||
drawSetColor( Scheme::sc_primary2 );
|
||||
drawFilledRect( nobx,0,noby,tall );
|
||||
|
||||
// Nob Outline
|
||||
drawSetColor( Scheme::sc_primary1 );
|
||||
drawOutlinedRect( nobx,0,noby,tall );
|
||||
}
|
||||
}
|
||||
|
||||
CTFScrollPanel::CTFScrollPanel(int x,int y,int wide,int tall) : ScrollPanel(x,y,wide,tall)
|
||||
{
|
||||
ScrollBar *pScrollBar = getVerticalScrollBar();
|
||||
pScrollBar->setButton( new CTFScrollButton( ARROW_UP, "", 0,0,16,16 ), 0 );
|
||||
pScrollBar->setButton( new CTFScrollButton( ARROW_DOWN, "", 0,0,16,16 ), 1 );
|
||||
pScrollBar->setSlider( new CTFSlider(0,wide-1,wide,(tall-(wide*2))+2,true) );
|
||||
pScrollBar->setPaintBorderEnabled(false);
|
||||
pScrollBar->setPaintBackgroundEnabled(false);
|
||||
pScrollBar->setPaintEnabled(false);
|
||||
|
||||
pScrollBar = getHorizontalScrollBar();
|
||||
pScrollBar->setButton( new CTFScrollButton( ARROW_LEFT, "", 0,0,16,16 ), 0 );
|
||||
pScrollBar->setButton( new CTFScrollButton( ARROW_RIGHT, "", 0,0,16,16 ), 1 );
|
||||
pScrollBar->setSlider( new CTFSlider(tall,0,wide-(tall*2),tall,false) );
|
||||
pScrollBar->setPaintBorderEnabled(false);
|
||||
pScrollBar->setPaintBackgroundEnabled(false);
|
||||
pScrollBar->setPaintEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
//=================================================================================
|
||||
// CUSTOM HANDLERS
|
||||
//=================================================================================
|
||||
void CHandler_MenuButtonOver::cursorEntered(Panel *panel)
|
||||
{
|
||||
if ( gViewPort && m_pMenuPanel )
|
||||
{
|
||||
m_pMenuPanel->SetActiveInfo( m_iButton );
|
||||
}
|
||||
}
|
||||
|
||||
void CMenuHandler_StringCommandClassSelect::actionPerformed(Panel* panel)
|
||||
{
|
||||
CMenuHandler_StringCommand::actionPerformed( panel );
|
||||
|
||||
bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0;
|
||||
if ( bAutoKill && g_iPlayerClass != 0 )
|
||||
gEngfuncs.pfnClientCmd("kill");
|
||||
}
|
||||
|
147
cl_dll/vgui_MOTDWindow.cpp
Normal file
147
cl_dll/vgui_MOTDWindow.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "VGUI_Font.h"
|
||||
#include "VGUI_ScrollPanel.h"
|
||||
#include "VGUI_TextImage.h"
|
||||
|
||||
#include<VGUI_StackLayout.h>
|
||||
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "camera.h"
|
||||
#include "kbutton.h"
|
||||
#include "const.h"
|
||||
|
||||
#include "vgui_int.h"
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
#include "vgui_ServerBrowser.h"
|
||||
|
||||
#define MOTD_TITLE_X XRES(16)
|
||||
#define MOTD_TITLE_Y YRES(16)
|
||||
|
||||
#define MOTD_WINDOW_X XRES(112)
|
||||
#define MOTD_WINDOW_Y YRES(80)
|
||||
#define MOTD_WINDOW_SIZE_X XRES(424)
|
||||
#define MOTD_WINDOW_SIZE_Y YRES(312)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Displays the MOTD and basic server information
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMessageWindowPanel : public CMenuPanel
|
||||
{
|
||||
public:
|
||||
CMessageWindowPanel( const char *szMOTD, const char *szTitle, int iShadeFullScreen, int iRemoveMe, int x, int y, int wide, int tall );
|
||||
|
||||
private:
|
||||
CTransparentPanel *m_pBackgroundPanel;
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Creates a new CMessageWindowPanel
|
||||
// Output : CMenuPanel - interface to the panel
|
||||
//-----------------------------------------------------------------------------
|
||||
CMenuPanel *CMessageWindowPanel_Create( const char *szMOTD, const char *szTitle, int iShadeFullscreen, int iRemoveMe, int x, int y, int wide, int tall )
|
||||
{
|
||||
return new CMessageWindowPanel( szMOTD, szTitle, iShadeFullscreen, iRemoveMe, x, y, wide, tall );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructs a message panel
|
||||
//-----------------------------------------------------------------------------
|
||||
CMessageWindowPanel::CMessageWindowPanel( const char *szMOTD, const char *szTitle, int iShadeFullscreen, int iRemoveMe, int x, int y, int wide, int tall ) : CMenuPanel( iShadeFullscreen ? 100 : 255, iRemoveMe, x, y, wide, tall )
|
||||
{
|
||||
// Get the scheme used for the Titles
|
||||
CSchemeManager *pSchemes = gViewPort->GetSchemeManager();
|
||||
|
||||
// schemes
|
||||
SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "Title Font" );
|
||||
SchemeHandle_t hMOTDText = pSchemes->getSchemeHandle( "Briefing Text" );
|
||||
|
||||
// color schemes
|
||||
int r, g, b, a;
|
||||
|
||||
// Create the window
|
||||
m_pBackgroundPanel = new CTransparentPanel( iShadeFullscreen ? 255 : 100, MOTD_WINDOW_X, MOTD_WINDOW_Y, MOTD_WINDOW_SIZE_X, MOTD_WINDOW_SIZE_Y );
|
||||
m_pBackgroundPanel->setParent( this );
|
||||
m_pBackgroundPanel->setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0)) );
|
||||
m_pBackgroundPanel->setVisible( true );
|
||||
|
||||
int iXSize,iYSize,iXPos,iYPos;
|
||||
m_pBackgroundPanel->getPos( iXPos,iYPos );
|
||||
m_pBackgroundPanel->getSize( iXSize,iYSize );
|
||||
|
||||
// Create the title
|
||||
Label *pLabel = new Label( "", iXPos + MOTD_TITLE_X, iYPos + MOTD_TITLE_Y );
|
||||
pLabel->setParent( this );
|
||||
pLabel->setFont( pSchemes->getFont(hTitleScheme) );
|
||||
pLabel->setFont( Scheme::sf_primary1 );
|
||||
|
||||
pSchemes->getFgColor( hTitleScheme, r, g, b, a );
|
||||
pLabel->setFgColor( r, g, b, a );
|
||||
pLabel->setFgColor( Scheme::sc_primary1 );
|
||||
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
|
||||
pLabel->setBgColor( r, g, b, a );
|
||||
pLabel->setContentAlignment( vgui::Label::a_west );
|
||||
pLabel->setText(szTitle);
|
||||
|
||||
// Create the Scroll panel
|
||||
ScrollPanel *pScrollPanel = new CTFScrollPanel( iXPos + XRES(16), iYPos + MOTD_TITLE_Y*2 + YRES(16), iXSize - XRES(32), iYSize - (YRES(48) + BUTTON_SIZE_Y*2) );
|
||||
pScrollPanel->setParent(this);
|
||||
//force the scrollbars on so clientClip will take them in account after the validate
|
||||
pScrollPanel->setScrollBarAutoVisible(false, false);
|
||||
pScrollPanel->setScrollBarVisible(true, true);
|
||||
pScrollPanel->validate();
|
||||
|
||||
// Create the text panel
|
||||
TextPanel *pText = new TextPanel( "", 0,0, 64,64);
|
||||
pText->setParent( pScrollPanel->getClient() );
|
||||
|
||||
// get the font and colors from the scheme
|
||||
pText->setFont( pSchemes->getFont(hMOTDText) );
|
||||
pSchemes->getFgColor( hMOTDText, r, g, b, a );
|
||||
pText->setFgColor( r, g, b, a );
|
||||
pSchemes->getBgColor( hMOTDText, r, g, b, a );
|
||||
pText->setBgColor( r, g, b, a );
|
||||
pText->setText(szMOTD);
|
||||
pText->setSize(pScrollPanel->getClientClip()->getWide()-2, 5000);
|
||||
|
||||
// Get the total size of the MOTD text and resize the text panel
|
||||
int iScrollSizeX, iScrollSizeY;
|
||||
pText->getTextImage()->getTextSizeWrapped( iScrollSizeX, iScrollSizeY );
|
||||
pText->setSize( iScrollSizeX , iScrollSizeY );
|
||||
//pText->setBorder(new LineBorder());
|
||||
|
||||
//turn the scrollbars back into automode
|
||||
pScrollPanel->setScrollBarAutoVisible(true, true);
|
||||
pScrollPanel->setScrollBarVisible(false, false);
|
||||
|
||||
pScrollPanel->validate();
|
||||
|
||||
CommandButton *pButton = new CommandButton( CHudTextMessage::BufferedLocaliseTextString( "#Menu_OK" ), iXPos + XRES(16), iYPos + iYSize - YRES(16) - BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||||
pButton->addActionSignal(new CMenuHandler_TextWindow(HIDE_TEXTWINDOW));
|
||||
pButton->setParent(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
544
cl_dll/vgui_SchemeManager.cpp
Normal file
544
cl_dll/vgui_SchemeManager.cpp
Normal file
@ -0,0 +1,544 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "hud.h"
|
||||
#include "vgui_SchemeManager.h"
|
||||
#include "cvardef.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
cvar_t *g_CV_BitmapFonts;
|
||||
|
||||
|
||||
void Scheme_Init()
|
||||
{
|
||||
g_CV_BitmapFonts = gEngfuncs.pfnRegisterVariable("bitmapfonts", "1", 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Scheme managers data container
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSchemeManager::CScheme
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
SCHEME_NAME_LENGTH = 32,
|
||||
FONT_NAME_LENGTH = 48,
|
||||
FONT_FILENAME_LENGTH = 64,
|
||||
};
|
||||
|
||||
// name
|
||||
char schemeName[SCHEME_NAME_LENGTH];
|
||||
|
||||
// font
|
||||
char fontName[FONT_NAME_LENGTH];
|
||||
|
||||
int fontSize;
|
||||
int fontWeight;
|
||||
|
||||
vgui::Font *font;
|
||||
int ownFontPointer; // true if the font is ours to delete
|
||||
|
||||
// scheme
|
||||
byte fgColor[4];
|
||||
byte bgColor[4];
|
||||
byte armedFgColor[4];
|
||||
byte armedBgColor[4];
|
||||
byte mousedownFgColor[4];
|
||||
byte mousedownBgColor[4];
|
||||
byte borderColor[4];
|
||||
|
||||
// construction/destruction
|
||||
CScheme();
|
||||
~CScheme();
|
||||
};
|
||||
|
||||
CSchemeManager::CScheme::CScheme()
|
||||
{
|
||||
schemeName[0] = 0;
|
||||
fontName[0] = 0;
|
||||
fontSize = 0;
|
||||
fontWeight = 0;
|
||||
font = NULL;
|
||||
ownFontPointer = false;
|
||||
}
|
||||
|
||||
CSchemeManager::CScheme::~CScheme()
|
||||
{
|
||||
// only delete our font pointer if we own it
|
||||
if ( ownFontPointer )
|
||||
{
|
||||
delete font;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: resolution information
|
||||
// !! needs to be shared out
|
||||
//-----------------------------------------------------------------------------
|
||||
static int g_ResArray[] =
|
||||
{
|
||||
320,
|
||||
400,
|
||||
512,
|
||||
640,
|
||||
800,
|
||||
1024,
|
||||
1152,
|
||||
1280,
|
||||
1600
|
||||
};
|
||||
static int g_NumReses = sizeof(g_ResArray) / sizeof(int);
|
||||
|
||||
static byte *LoadFileByResolution( const char *filePrefix, int xRes, const char *filePostfix )
|
||||
{
|
||||
// find our resolution in the res array
|
||||
int resNum = g_NumReses - 1;
|
||||
while ( g_ResArray[resNum] > xRes )
|
||||
{
|
||||
resNum--;
|
||||
|
||||
if ( resNum < 0 )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// try open the file
|
||||
byte *pFile = NULL;
|
||||
while ( 1 )
|
||||
{
|
||||
|
||||
// try load
|
||||
char fname[256];
|
||||
sprintf( fname, "%s%d%s", filePrefix, g_ResArray[resNum], filePostfix );
|
||||
pFile = gEngfuncs.COM_LoadFile( fname, 5, NULL );
|
||||
|
||||
if ( pFile )
|
||||
break;
|
||||
|
||||
if ( resNum == 0 )
|
||||
return NULL;
|
||||
|
||||
resNum--;
|
||||
};
|
||||
|
||||
return pFile;
|
||||
}
|
||||
|
||||
static void ParseRGBAFromString( byte colorArray[4], const char *colorVector )
|
||||
{
|
||||
int r, g, b, a;
|
||||
sscanf( colorVector, "%d %d %d %d", &r, &g, &b, &a );
|
||||
colorArray[0] = r;
|
||||
colorArray[1] = g;
|
||||
colorArray[2] = b;
|
||||
colorArray[3] = a;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: initializes the scheme manager
|
||||
// loading the scheme files for the current resolution
|
||||
// Input : xRes -
|
||||
// yRes - dimensions of output window
|
||||
//-----------------------------------------------------------------------------
|
||||
CSchemeManager::CSchemeManager( int xRes, int yRes )
|
||||
{
|
||||
// basic setup
|
||||
m_pSchemeList = NULL;
|
||||
m_iNumSchemes = 0;
|
||||
|
||||
// find the closest matching scheme file to our resolution
|
||||
char token[1024];
|
||||
char *pFile = (char*)LoadFileByResolution( "", xRes, "_textscheme.txt" );
|
||||
m_xRes = xRes;
|
||||
|
||||
char *pFileStart = pFile;
|
||||
|
||||
byte *pFontData;
|
||||
int fontFileLength;
|
||||
char fontFilename[512];
|
||||
|
||||
//
|
||||
// Read the scheme descriptions from the text file, into a temporary array
|
||||
// format is simply:
|
||||
// <paramName name> = <paramValue>
|
||||
//
|
||||
// a <paramName name> of "SchemeName" signals a new scheme is being described
|
||||
//
|
||||
|
||||
const static int numTmpSchemes = 64;
|
||||
static CScheme tmpSchemes[numTmpSchemes];
|
||||
memset( tmpSchemes, 0, sizeof(tmpSchemes) );
|
||||
int currentScheme = -1;
|
||||
CScheme *pScheme = NULL;
|
||||
|
||||
if ( !pFile )
|
||||
{
|
||||
gEngfuncs.Con_DPrintf( "Unable to find *_textscheme.txt\n");
|
||||
goto buildDefaultFont;
|
||||
}
|
||||
|
||||
// record what has been entered so we can create defaults from the different values
|
||||
bool hasFgColor, hasBgColor, hasArmedFgColor, hasArmedBgColor, hasMouseDownFgColor, hasMouseDownBgColor;
|
||||
|
||||
pFile = gEngfuncs.COM_ParseFile( pFile, token );
|
||||
while ( strlen(token) > 0 && (currentScheme < numTmpSchemes) )
|
||||
{
|
||||
// get the paramName name
|
||||
static const int tokenSize = 64;
|
||||
char paramName[tokenSize], paramValue[tokenSize];
|
||||
|
||||
strncpy( paramName, token, tokenSize );
|
||||
paramName[tokenSize-1] = 0; // ensure null termination
|
||||
|
||||
// get the '=' character
|
||||
pFile = gEngfuncs.COM_ParseFile( pFile, token );
|
||||
if ( stricmp( token, "=" ) )
|
||||
{
|
||||
if ( currentScheme < 0 )
|
||||
{
|
||||
gEngfuncs.Con_Printf( "error parsing font scheme text file at file start - expected '=', found '%s''\n", token );
|
||||
}
|
||||
else
|
||||
{
|
||||
gEngfuncs.Con_Printf( "error parsing font scheme text file at scheme '%s' - expected '=', found '%s''\n", tmpSchemes[currentScheme].schemeName, token );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// get paramValue
|
||||
pFile = gEngfuncs.COM_ParseFile( pFile, token );
|
||||
strncpy( paramValue, token, tokenSize );
|
||||
paramValue[tokenSize-1] = 0; // ensure null termination
|
||||
|
||||
// is this a new scheme?
|
||||
if ( !stricmp(paramName, "SchemeName") )
|
||||
{
|
||||
// setup the defaults for the current scheme
|
||||
if ( pScheme )
|
||||
{
|
||||
// foreground color defaults (normal -> armed -> mouse down)
|
||||
if ( !hasFgColor )
|
||||
{
|
||||
pScheme->fgColor[0] = pScheme->fgColor[1] = pScheme->fgColor[2] = pScheme->fgColor[3] = 255;
|
||||
}
|
||||
if ( !hasArmedFgColor )
|
||||
{
|
||||
memcpy( pScheme->armedFgColor, pScheme->fgColor, sizeof(pScheme->armedFgColor) );
|
||||
}
|
||||
if ( !hasMouseDownFgColor )
|
||||
{
|
||||
memcpy( pScheme->mousedownFgColor, pScheme->armedFgColor, sizeof(pScheme->mousedownFgColor) );
|
||||
}
|
||||
|
||||
// background color (normal -> armed -> mouse down)
|
||||
if ( !hasBgColor )
|
||||
{
|
||||
pScheme->bgColor[0] = pScheme->bgColor[1] = pScheme->bgColor[2] = pScheme->bgColor[3] = 0;
|
||||
}
|
||||
if ( !hasArmedBgColor )
|
||||
{
|
||||
memcpy( pScheme->armedBgColor, pScheme->bgColor, sizeof(pScheme->armedBgColor) );
|
||||
}
|
||||
if ( !hasMouseDownBgColor )
|
||||
{
|
||||
memcpy( pScheme->mousedownBgColor, pScheme->armedBgColor, sizeof(pScheme->mousedownBgColor) );
|
||||
}
|
||||
|
||||
// font size
|
||||
if ( !pScheme->fontSize )
|
||||
{
|
||||
pScheme->fontSize = 17;
|
||||
}
|
||||
if ( !pScheme->fontName[0] )
|
||||
{
|
||||
strcpy( pScheme->fontName, "Arial" );
|
||||
}
|
||||
}
|
||||
|
||||
// create the new scheme
|
||||
currentScheme++;
|
||||
pScheme = &tmpSchemes[currentScheme];
|
||||
hasFgColor = hasBgColor = hasArmedFgColor = hasArmedBgColor = hasMouseDownFgColor = hasMouseDownBgColor = false;
|
||||
|
||||
strncpy( pScheme->schemeName, paramValue, CScheme::SCHEME_NAME_LENGTH );
|
||||
pScheme->schemeName[CScheme::SCHEME_NAME_LENGTH-1] = '\0'; // ensure null termination of string
|
||||
}
|
||||
|
||||
if ( !pScheme )
|
||||
{
|
||||
gEngfuncs.Con_Printf( "font scheme text file MUST start with a 'SchemeName'\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// pull the data out into the scheme
|
||||
if ( !stricmp(paramName, "FontName") )
|
||||
{
|
||||
strncpy( pScheme->fontName, paramValue, CScheme::FONT_NAME_LENGTH );
|
||||
pScheme->fontName[CScheme::FONT_NAME_LENGTH-1] = 0;
|
||||
}
|
||||
else if ( !stricmp(paramName, "FontSize") )
|
||||
{
|
||||
pScheme->fontSize = atoi( paramValue );
|
||||
}
|
||||
else if ( !stricmp(paramName, "FontWeight") )
|
||||
{
|
||||
pScheme->fontWeight = atoi( paramValue );
|
||||
}
|
||||
else if ( !stricmp(paramName, "FgColor") )
|
||||
{
|
||||
ParseRGBAFromString( pScheme->fgColor, paramValue );
|
||||
hasFgColor = true;
|
||||
}
|
||||
else if ( !stricmp(paramName, "BgColor") )
|
||||
{
|
||||
ParseRGBAFromString( pScheme->bgColor, paramValue );
|
||||
hasBgColor = true;
|
||||
}
|
||||
else if ( !stricmp(paramName, "FgColorArmed") )
|
||||
{
|
||||
ParseRGBAFromString( pScheme->armedFgColor, paramValue );
|
||||
hasArmedFgColor = true;
|
||||
}
|
||||
else if ( !stricmp(paramName, "BgColorArmed") )
|
||||
{
|
||||
ParseRGBAFromString( pScheme->armedBgColor, paramValue );
|
||||
hasArmedBgColor = true;
|
||||
}
|
||||
else if ( !stricmp(paramName, "FgColorMousedown") )
|
||||
{
|
||||
ParseRGBAFromString( pScheme->mousedownFgColor, paramValue );
|
||||
hasMouseDownFgColor = true;
|
||||
}
|
||||
else if ( !stricmp(paramName, "BgColorMousedown") )
|
||||
{
|
||||
ParseRGBAFromString( pScheme->mousedownBgColor, paramValue );
|
||||
hasMouseDownBgColor = true;
|
||||
}
|
||||
else if ( !stricmp(paramName, "BorderColor") )
|
||||
{
|
||||
ParseRGBAFromString( pScheme->borderColor, paramValue );
|
||||
hasMouseDownBgColor = true;
|
||||
}
|
||||
|
||||
// get the new token last, so we now if the loop needs to be continued or not
|
||||
pFile = gEngfuncs.COM_ParseFile( pFile, token );
|
||||
}
|
||||
|
||||
// free the file
|
||||
gEngfuncs.COM_FreeFile( pFileStart );
|
||||
|
||||
|
||||
buildDefaultFont:
|
||||
|
||||
// make sure we have at least 1 valid font
|
||||
if ( currentScheme < 0 )
|
||||
{
|
||||
currentScheme = 0;
|
||||
strcpy( tmpSchemes[0].schemeName, "Default Scheme" );
|
||||
strcpy( tmpSchemes[0].fontName, "Arial" );
|
||||
tmpSchemes[0].fontSize = 0;
|
||||
tmpSchemes[0].fgColor[0] = tmpSchemes[0].fgColor[1] = tmpSchemes[0].fgColor[2] = tmpSchemes[0].fgColor[3] = 255;
|
||||
tmpSchemes[0].armedFgColor[0] = tmpSchemes[0].armedFgColor[1] = tmpSchemes[0].armedFgColor[2] = tmpSchemes[0].armedFgColor[3] = 255;
|
||||
tmpSchemes[0].mousedownFgColor[0] = tmpSchemes[0].mousedownFgColor[1] = tmpSchemes[0].mousedownFgColor[2] = tmpSchemes[0].mousedownFgColor[3] = 255;
|
||||
}
|
||||
|
||||
// we have the full list of schemes in the tmpSchemes array
|
||||
// now allocate the correct sized list
|
||||
m_iNumSchemes = currentScheme + 1; // 0-based index
|
||||
m_pSchemeList = new CScheme[ m_iNumSchemes ];
|
||||
|
||||
// copy in the data
|
||||
memcpy( m_pSchemeList, tmpSchemes, sizeof(CScheme) * m_iNumSchemes );
|
||||
|
||||
// create the fonts
|
||||
for ( int i = 0; i < m_iNumSchemes; i++ )
|
||||
{
|
||||
m_pSchemeList[i].font = NULL;
|
||||
|
||||
// see if the current font values exist in a previously loaded font
|
||||
for ( int j = 0; j < i; j++ )
|
||||
{
|
||||
// check if the font name, size, and weight are the same
|
||||
if ( !stricmp(m_pSchemeList[i].fontName, m_pSchemeList[j].fontName)
|
||||
&& m_pSchemeList[i].fontSize == m_pSchemeList[j].fontSize
|
||||
&& m_pSchemeList[i].fontWeight == m_pSchemeList[j].fontWeight )
|
||||
{
|
||||
// copy the pointer, but mark i as not owning it
|
||||
m_pSchemeList[i].font = m_pSchemeList[j].font;
|
||||
m_pSchemeList[i].ownFontPointer = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we haven't found the font already, load it ourselves
|
||||
if ( !m_pSchemeList[i].font )
|
||||
{
|
||||
fontFileLength = -1;
|
||||
pFontData = NULL;
|
||||
|
||||
if(g_CV_BitmapFonts && g_CV_BitmapFonts->value)
|
||||
{
|
||||
sprintf(fontFilename, "gfx\\vgui\\fonts\\%d_%s.tga", m_xRes, m_pSchemeList[i].schemeName);
|
||||
pFontData = gEngfuncs.COM_LoadFile( fontFilename, 5, &fontFileLength );
|
||||
if(!pFontData)
|
||||
gEngfuncs.Con_Printf("Missing bitmap font: %s\n", fontFilename);
|
||||
}
|
||||
|
||||
m_pSchemeList[i].font = new vgui::Font(
|
||||
m_pSchemeList[i].fontName,
|
||||
pFontData,
|
||||
fontFileLength,
|
||||
m_pSchemeList[i].fontSize,
|
||||
0,
|
||||
0,
|
||||
m_pSchemeList[i].fontWeight,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false);
|
||||
|
||||
m_pSchemeList[i].ownFontPointer = true;
|
||||
}
|
||||
|
||||
// fix up alpha values; VGUI uses 1-A (A=0 being solid, A=255 transparent)
|
||||
m_pSchemeList[i].fgColor[3] = 255 - m_pSchemeList[i].fgColor[3];
|
||||
m_pSchemeList[i].bgColor[3] = 255 - m_pSchemeList[i].bgColor[3];
|
||||
m_pSchemeList[i].armedFgColor[3] = 255 - m_pSchemeList[i].armedFgColor[3];
|
||||
m_pSchemeList[i].armedBgColor[3] = 255 - m_pSchemeList[i].armedBgColor[3];
|
||||
m_pSchemeList[i].mousedownFgColor[3] = 255 - m_pSchemeList[i].mousedownFgColor[3];
|
||||
m_pSchemeList[i].mousedownBgColor[3] = 255 - m_pSchemeList[i].mousedownBgColor[3];
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: frees all the memory used by the scheme manager
|
||||
//-----------------------------------------------------------------------------
|
||||
CSchemeManager::~CSchemeManager()
|
||||
{
|
||||
delete [] m_pSchemeList;
|
||||
m_iNumSchemes = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Finds a scheme in the list, by name
|
||||
// Input : char *schemeName - string name of the scheme
|
||||
// Output : SchemeHandle_t handle to the scheme
|
||||
//-----------------------------------------------------------------------------
|
||||
SchemeHandle_t CSchemeManager::getSchemeHandle( const char *schemeName )
|
||||
{
|
||||
// iterate through the list
|
||||
for ( int i = 0; i < m_iNumSchemes; i++ )
|
||||
{
|
||||
if ( !stricmp(schemeName, m_pSchemeList[i].schemeName) )
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: always returns a valid scheme handle
|
||||
// Input : schemeHandle -
|
||||
// Output : CScheme
|
||||
//-----------------------------------------------------------------------------
|
||||
CSchemeManager::CScheme *CSchemeManager::getSafeScheme( SchemeHandle_t schemeHandle )
|
||||
{
|
||||
if ( schemeHandle < m_iNumSchemes )
|
||||
return m_pSchemeList + schemeHandle;
|
||||
|
||||
return m_pSchemeList;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns the schemes pointer to a font
|
||||
// Input : schemeHandle -
|
||||
// Output : vgui::Font
|
||||
//-----------------------------------------------------------------------------
|
||||
vgui::Font *CSchemeManager::getFont( SchemeHandle_t schemeHandle )
|
||||
{
|
||||
return getSafeScheme( schemeHandle )->font;
|
||||
}
|
||||
|
||||
void CSchemeManager::getFgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
|
||||
{
|
||||
CScheme *pScheme = getSafeScheme( schemeHandle );
|
||||
r = pScheme->fgColor[0];
|
||||
g = pScheme->fgColor[1];
|
||||
b = pScheme->fgColor[2];
|
||||
a = pScheme->fgColor[3];
|
||||
}
|
||||
|
||||
void CSchemeManager::getBgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
|
||||
{
|
||||
CScheme *pScheme = getSafeScheme( schemeHandle );
|
||||
r = pScheme->bgColor[0];
|
||||
g = pScheme->bgColor[1];
|
||||
b = pScheme->bgColor[2];
|
||||
a = pScheme->bgColor[3];
|
||||
}
|
||||
|
||||
void CSchemeManager::getFgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
|
||||
{
|
||||
CScheme *pScheme = getSafeScheme( schemeHandle );
|
||||
r = pScheme->armedFgColor[0];
|
||||
g = pScheme->armedFgColor[1];
|
||||
b = pScheme->armedFgColor[2];
|
||||
a = pScheme->armedFgColor[3];
|
||||
}
|
||||
|
||||
void CSchemeManager::getBgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
|
||||
{
|
||||
CScheme *pScheme = getSafeScheme( schemeHandle );
|
||||
r = pScheme->armedBgColor[0];
|
||||
g = pScheme->armedBgColor[1];
|
||||
b = pScheme->armedBgColor[2];
|
||||
a = pScheme->armedBgColor[3];
|
||||
}
|
||||
|
||||
void CSchemeManager::getFgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
|
||||
{
|
||||
CScheme *pScheme = getSafeScheme( schemeHandle );
|
||||
r = pScheme->mousedownFgColor[0];
|
||||
g = pScheme->mousedownFgColor[1];
|
||||
b = pScheme->mousedownFgColor[2];
|
||||
a = pScheme->mousedownFgColor[3];
|
||||
}
|
||||
|
||||
void CSchemeManager::getBgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
|
||||
{
|
||||
CScheme *pScheme = getSafeScheme( schemeHandle );
|
||||
r = pScheme->mousedownBgColor[0];
|
||||
g = pScheme->mousedownBgColor[1];
|
||||
b = pScheme->mousedownBgColor[2];
|
||||
a = pScheme->mousedownBgColor[3];
|
||||
}
|
||||
|
||||
void CSchemeManager::getBorderColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
|
||||
{
|
||||
CScheme *pScheme = getSafeScheme( schemeHandle );
|
||||
r = pScheme->borderColor[0];
|
||||
g = pScheme->borderColor[1];
|
||||
b = pScheme->borderColor[2];
|
||||
a = pScheme->borderColor[3];
|
||||
}
|
||||
|
||||
|
||||
|
47
cl_dll/vgui_SchemeManager.h
Normal file
47
cl_dll/vgui_SchemeManager.h
Normal file
@ -0,0 +1,47 @@
|
||||
#include <VGUI_Font.h>
|
||||
|
||||
|
||||
// handle to an individual scheme
|
||||
typedef int SchemeHandle_t;
|
||||
|
||||
|
||||
// Register console variables, etc..
|
||||
void Scheme_Init();
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handles the loading of text scheme description from disk
|
||||
// supports different font/color/size schemes at different resolutions
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSchemeManager
|
||||
{
|
||||
public:
|
||||
// initialization
|
||||
CSchemeManager( int xRes, int yRes );
|
||||
virtual ~CSchemeManager();
|
||||
|
||||
// scheme handling
|
||||
SchemeHandle_t getSchemeHandle( const char *schemeName );
|
||||
|
||||
// getting info from schemes
|
||||
vgui::Font *getFont( SchemeHandle_t schemeHandle );
|
||||
void getFgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
|
||||
void getBgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
|
||||
void getFgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
|
||||
void getBgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
|
||||
void getFgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
|
||||
void getBgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
|
||||
void getBorderColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
|
||||
|
||||
private:
|
||||
class CScheme;
|
||||
CScheme *m_pSchemeList;
|
||||
int m_iNumSchemes;
|
||||
|
||||
// Resolution we were initted at.
|
||||
int m_xRes;
|
||||
|
||||
CScheme *getSafeScheme( SchemeHandle_t schemeHandle );
|
||||
};
|
||||
|
||||
|
629
cl_dll/vgui_ScorePanel.cpp
Normal file
629
cl_dll/vgui_ScorePanel.cpp
Normal file
@ -0,0 +1,629 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// Purpose: VGUI scoreboard
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#include<VGUI_LineBorder.h>
|
||||
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "const.h"
|
||||
#include "entity_state.h"
|
||||
#include "cl_entity.h"
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
#include "vgui_ScorePanel.h"
|
||||
|
||||
hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine
|
||||
extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1]; // additional player info sent directly to the client dll
|
||||
team_info_t g_TeamInfo[MAX_TEAMS+1];
|
||||
int g_IsSpectator[MAX_PLAYERS+1];
|
||||
|
||||
int HUD_IsGame( const char *game );
|
||||
int EV_TFC_IsAllyTeam( int iTeam1, int iTeam2 );
|
||||
|
||||
// Scoreboard dimensions
|
||||
#define SBOARD_TITLE_SIZE_Y YRES(24)
|
||||
#define SBOARD_HEADER_SIZE_Y YRES(40)
|
||||
#define SBOARD_TABLE_X XRES(16)
|
||||
#define SBOARD_TABLE_Y (SBOARD_TITLE_SIZE_Y + SBOARD_HEADER_SIZE_Y)
|
||||
|
||||
#define SBOARD_TEAM_CELL_SIZE_Y YRES(20)
|
||||
#define SBOARD_CELL_SIZE_Y YRES(13)
|
||||
|
||||
// Column sizes
|
||||
#define CSIZE_NAME XRES(140)
|
||||
#define CSIZE_CLASS CSIZE_NAME + XRES(64)
|
||||
#define CSIZE_KILLS CSIZE_CLASS + XRES(60)
|
||||
#define CSIZE_DEATHS CSIZE_KILLS + XRES(64)
|
||||
|
||||
#define SMALL_CSIZE_NAME XRES(124)
|
||||
#define SMALL_CSIZE_CLASS SMALL_CSIZE_NAME + XRES(60)
|
||||
#define SMALL_CSIZE_KILLS SMALL_CSIZE_CLASS + XRES(64)
|
||||
#define SMALL_CSIZE_DEATHS SMALL_CSIZE_KILLS + XRES(70)
|
||||
|
||||
#define TEAM_NO 0
|
||||
#define TEAM_YES 1
|
||||
#define TEAM_UNASSIGNED 2
|
||||
#define TEAM_SPECTATORS 3
|
||||
|
||||
// Team Colors used in the scoreboard
|
||||
int ScoreColorsBG[5][3] =
|
||||
{
|
||||
{ 0, 0, 0 },
|
||||
{ 66, 114, 247 },
|
||||
{ 220, 51, 38 },
|
||||
{ 236, 212, 48 },
|
||||
{ 68, 199, 42 },
|
||||
};
|
||||
|
||||
int ScoreColorsFG[5][3] =
|
||||
{
|
||||
{ 255, 255, 255 },
|
||||
{ 170, 193, 251 },
|
||||
{ 215, 151, 146 },
|
||||
{ 227, 203, 46 },
|
||||
{ 143, 215, 142 },
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Set different cell heights for Teams and Players
|
||||
//-----------------------------------------------------------------------------
|
||||
int ScoreTablePanel::getCellTall(int row)
|
||||
{
|
||||
if ( m_iIsATeam[row] )
|
||||
return SBOARD_TEAM_CELL_SIZE_Y;
|
||||
|
||||
return SBOARD_CELL_SIZE_Y;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Render each of the cells in the Table
|
||||
//-----------------------------------------------------------------------------
|
||||
Panel* ScoreTablePanel::getCellRenderer(int column,int row,bool columnSelected,bool rowSelected,bool cellSelected)
|
||||
{
|
||||
char sz[128];
|
||||
hud_player_info_t *pl_info = NULL;
|
||||
team_info_t *team_info = NULL;
|
||||
|
||||
if ( m_iIsATeam[row] == TEAM_YES )
|
||||
{
|
||||
// Get the team's data
|
||||
team_info = &g_TeamInfo[ m_iSortedRows[row] ];
|
||||
|
||||
// White text for team names
|
||||
m_pLabel->setFgColor(Scheme::sc_white);
|
||||
|
||||
// Set background color
|
||||
m_pLabel->setBgColor( ScoreColorsBG[ team_info->teamnumber ][0], ScoreColorsBG[ team_info->teamnumber ][1], ScoreColorsBG[ team_info->teamnumber ][2], 128 );
|
||||
}
|
||||
else if ( m_iIsATeam[row] == TEAM_UNASSIGNED || m_iIsATeam[row] == TEAM_SPECTATORS )
|
||||
{
|
||||
// White text for team names
|
||||
m_pLabel->setFgColor(Scheme::sc_white);
|
||||
|
||||
// Set background color
|
||||
m_pLabel->setBgColor( 0,0,0, 255 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grey text for player names
|
||||
m_pLabel->setFgColor( ScoreColorsFG[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ][0], ScoreColorsFG[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ][1], ScoreColorsFG[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ][2], 128 );
|
||||
|
||||
// Get the player's data
|
||||
pl_info = &g_PlayerInfoList[ m_iSortedRows[row] ];
|
||||
|
||||
// Set background color
|
||||
if ( pl_info->thisplayer ) // if it is their name, draw it a different color
|
||||
{
|
||||
// Highlight this player
|
||||
m_pLabel->setFgColor(Scheme::sc_white);
|
||||
m_pLabel->setBgColor( ScoreColorsBG[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ][0], ScoreColorsBG[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ][1], ScoreColorsBG[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ][2], 196 );
|
||||
}
|
||||
else if ( m_iSortedRows[row] == m_iLastKilledBy && m_fLastKillTime && m_fLastKillTime > gHUD.m_flTime )
|
||||
{
|
||||
// Killer's name
|
||||
m_pLabel->setBgColor( 255,0,0, 255 - ((float)15 * (float)(m_fLastKillTime - gHUD.m_flTime)) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLabel->setBgColor( 0,0,0, 255 );
|
||||
}
|
||||
}
|
||||
|
||||
// Align
|
||||
if (column <= 1)
|
||||
{
|
||||
if ( m_iIsATeam[row] )
|
||||
m_pLabel->setContentAlignment( vgui::Label::a_southwest );
|
||||
else
|
||||
m_pLabel->setContentAlignment( vgui::Label::a_west );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_iIsATeam[row] )
|
||||
m_pLabel->setContentAlignment( vgui::Label::a_south );
|
||||
else
|
||||
m_pLabel->setContentAlignment( vgui::Label::a_center );
|
||||
}
|
||||
|
||||
// Fill out with the correct data
|
||||
if ( m_iIsATeam[row] )
|
||||
{
|
||||
int i;
|
||||
char sz2[128];
|
||||
strcpy(sz, "");
|
||||
|
||||
switch (column)
|
||||
{
|
||||
case 0:
|
||||
if ( m_iIsATeam[row] == TEAM_UNASSIGNED )
|
||||
{
|
||||
sprintf( sz2, CHudTextMessage::BufferedLocaliseTextString( "#Unassigned" ) );
|
||||
}
|
||||
else if ( m_iIsATeam[row] == TEAM_SPECTATORS )
|
||||
{
|
||||
sprintf( sz2, CHudTextMessage::BufferedLocaliseTextString( "#Spectators" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( sz2, CHudTextMessage::BufferedLocaliseTextString( team_info->name ) );
|
||||
}
|
||||
|
||||
// Uppercase it
|
||||
for (i = 0; i < (int)strlen(sz2); i++)
|
||||
{
|
||||
if ( *(sz2 + i) )
|
||||
sz[i] = toupper( *(sz2 + i) );
|
||||
}
|
||||
sz[i] = '\0';
|
||||
|
||||
// Append the number of players
|
||||
if ( m_iIsATeam[row] == TEAM_YES )
|
||||
{
|
||||
if (team_info->players == 1)
|
||||
sprintf(sz, "%s (1 player)", sz );
|
||||
else
|
||||
sprintf(sz, "%s (%d players)", sz, team_info->players );
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// No class for teams
|
||||
break;
|
||||
case 2:
|
||||
if ( m_iIsATeam[row] == TEAM_YES )
|
||||
sprintf(sz, "%d", team_info->frags );
|
||||
break;
|
||||
case 3:
|
||||
if ( m_iIsATeam[row] == TEAM_YES )
|
||||
sprintf(sz, "%d", team_info->deaths );
|
||||
break;
|
||||
case 4:
|
||||
if ( m_iIsATeam[row] == TEAM_YES )
|
||||
sprintf(sz, "%d", team_info->ping );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_pLabel->setText(sz);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bShowClass = false;
|
||||
|
||||
switch (column)
|
||||
{
|
||||
case 0:
|
||||
sprintf(sz, " %s", pl_info->name);
|
||||
break;
|
||||
case 1:
|
||||
// No class for other team's members (unless allied or spectator)
|
||||
if ( gViewPort && EV_TFC_IsAllyTeam( g_iTeamNumber, g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ) )
|
||||
bShowClass = true;
|
||||
// Don't show classes if this client hasnt picked a team yet
|
||||
if ( g_iTeamNumber == 0 )
|
||||
bShowClass = false;
|
||||
if ( g_iUser1 )
|
||||
bShowClass = true;
|
||||
|
||||
if (bShowClass)
|
||||
{
|
||||
// Only print Civilian if this team are all civilians
|
||||
bool bNoClass = false;
|
||||
if ( g_PlayerExtraInfo[ m_iSortedRows[row] ].playerclass == 0 )
|
||||
{
|
||||
if ( gViewPort->GetValidClasses( g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ) != -1 )
|
||||
bNoClass = true;
|
||||
}
|
||||
|
||||
if (bNoClass)
|
||||
sprintf(sz, "");
|
||||
else
|
||||
sprintf( sz, "%s", CHudTextMessage::BufferedLocaliseTextString( sLocalisedClasses[ g_PlayerExtraInfo[ m_iSortedRows[row] ].playerclass ] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(sz, "");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
sprintf(sz, "%d", g_PlayerExtraInfo[ m_iSortedRows[row] ].frags );
|
||||
break;
|
||||
case 3:
|
||||
sprintf(sz, "%d", g_PlayerExtraInfo[ m_iSortedRows[row] ].deaths );
|
||||
break;
|
||||
case 4:
|
||||
sprintf(sz, "%d", g_PlayerInfoList[ m_iSortedRows[row] ].ping );
|
||||
break;
|
||||
default:
|
||||
strcpy(sz, "");
|
||||
}
|
||||
|
||||
m_pLabel->setText(sz);
|
||||
}
|
||||
|
||||
return m_pLabel;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Create the ScoreBoard panel
|
||||
//-----------------------------------------------------------------------------
|
||||
ScorePanel::ScorePanel(int x,int y,int wide,int tall) : Panel(x,y,wide,tall)
|
||||
{
|
||||
setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0) ) );
|
||||
setBgColor( 0,0,0, 100 );
|
||||
|
||||
m_pTitleLabel = new Label( " SCORES", 0,0, wide, SBOARD_TITLE_SIZE_Y );
|
||||
m_pTitleLabel->setBgColor( Scheme::sc_primary2 );
|
||||
m_pTitleLabel->setFgColor( Scheme::sc_primary1 );
|
||||
m_pTitleLabel->setContentAlignment( vgui::Label::a_west );
|
||||
m_pTitleLabel->setParent(this);
|
||||
|
||||
_headerPanel = new HeaderPanel( SBOARD_TABLE_X, SBOARD_TITLE_SIZE_Y, wide - (SBOARD_TABLE_X * 2), SBOARD_HEADER_SIZE_Y);
|
||||
_headerPanel->setParent(this);
|
||||
|
||||
// BUGBUG: This isn't working. gHUD.m_Teamplay hasn't been initialized yet.
|
||||
if ( gHUD.m_Teamplay )
|
||||
_headerPanel->addSectionPanel( new CLabelHeader( CHudTextMessage::BufferedLocaliseTextString( "#TEAMS" ), true) );
|
||||
else
|
||||
_headerPanel->addSectionPanel( new CLabelHeader( CHudTextMessage::BufferedLocaliseTextString( "#PLAYERS" ), true) );
|
||||
|
||||
if ( HUD_IsGame( "tfc" ) )
|
||||
_headerPanel->addSectionPanel( new CLabelHeader( CHudTextMessage::BufferedLocaliseTextString( "#CLASS" ), true) );
|
||||
else
|
||||
_headerPanel->addSectionPanel( new CLabelHeader("", true) );
|
||||
|
||||
_headerPanel->addSectionPanel( new CLabelHeader( CHudTextMessage::BufferedLocaliseTextString( "#SCORE" )) );
|
||||
_headerPanel->addSectionPanel( new CLabelHeader( CHudTextMessage::BufferedLocaliseTextString( "#DEATHS")) );
|
||||
_headerPanel->addSectionPanel( new CLabelHeader( CHudTextMessage::BufferedLocaliseTextString( "#LATENCY")) );
|
||||
_headerPanel->setBgColor( 0,0,0, 255 );
|
||||
|
||||
// Need to special case 400x300, because the titles just wont fit otherwise
|
||||
if ( ScreenWidth == 400 )
|
||||
{
|
||||
_headerPanel->setSliderPos( 0, SMALL_CSIZE_NAME );
|
||||
_headerPanel->setSliderPos( 1, SMALL_CSIZE_CLASS );
|
||||
_headerPanel->setSliderPos( 2, SMALL_CSIZE_KILLS );
|
||||
_headerPanel->setSliderPos( 3, SMALL_CSIZE_DEATHS );
|
||||
_headerPanel->setSliderPos( 4, wide - (SBOARD_TABLE_X * 2) - 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
_headerPanel->setSliderPos( 0, CSIZE_NAME );
|
||||
_headerPanel->setSliderPos( 1, CSIZE_CLASS );
|
||||
_headerPanel->setSliderPos( 2, CSIZE_KILLS );
|
||||
_headerPanel->setSliderPos( 3, CSIZE_DEATHS );
|
||||
_headerPanel->setSliderPos( 4, wide - (SBOARD_TABLE_X * 2) - 1 );
|
||||
}
|
||||
|
||||
_tablePanel = new ScoreTablePanel(SBOARD_TABLE_X, SBOARD_TABLE_Y, wide - (SBOARD_TABLE_X * 2), tall - SBOARD_TABLE_Y, NUM_COLUMNS);
|
||||
_tablePanel->setParent(this);
|
||||
_tablePanel->setHeaderPanel(_headerPanel);
|
||||
_tablePanel->setBgColor( 0,0,0, 255 );
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called each time a new level is started.
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScorePanel::Initialize( void )
|
||||
{
|
||||
// Clear out scoreboard data
|
||||
_tablePanel->m_iLastKilledBy = 0;
|
||||
_tablePanel->m_fLastKillTime = 0;
|
||||
m_iPlayerNum = 0;
|
||||
m_iNumTeams = 0;
|
||||
memset( g_PlayerExtraInfo, 0, sizeof g_PlayerExtraInfo );
|
||||
memset( g_TeamInfo, 0, sizeof g_TeamInfo );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Set the size of the header and table when this panel's size changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScorePanel::setSize(int wide,int tall)
|
||||
{
|
||||
Panel::setSize(wide,tall);
|
||||
|
||||
_headerPanel->setBounds(0,0,wide,SBOARD_HEADER_SIZE_Y);
|
||||
_tablePanel->setBounds(0,20,wide,tall - SBOARD_HEADER_SIZE_Y);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Recalculate the internal scoreboard data
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScorePanel::Update()
|
||||
{
|
||||
// Set the title
|
||||
if (gViewPort->m_szServerName)
|
||||
{
|
||||
char sz[MAX_SERVERNAME_LENGTH + 16];
|
||||
sprintf(sz, " SCORES: %s", gViewPort->m_szServerName );
|
||||
m_pTitleLabel->setText(sz);
|
||||
}
|
||||
|
||||
_tablePanel->m_iRows = 0;
|
||||
gViewPort->GetAllPlayersInfo();
|
||||
|
||||
// Clear out sorts
|
||||
for (int i = 0; i < MAX_PLAYERS; i++)
|
||||
{
|
||||
_tablePanel->m_iSortedRows[i] = 0;
|
||||
_tablePanel->m_iIsATeam[i] = TEAM_NO;
|
||||
_tablePanel->m_bHasBeenSorted[i] = false;
|
||||
}
|
||||
|
||||
// If it's not teamplay, sort all the players. Otherwise, sort the teams.
|
||||
if ( !gHUD.m_Teamplay )
|
||||
SortPlayers( 0, NULL );
|
||||
else
|
||||
SortTeams();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sort all the teams
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScorePanel::SortTeams()
|
||||
{
|
||||
// clear out team scores
|
||||
for ( int i = 1; i <= m_iNumTeams; i++ )
|
||||
{
|
||||
if ( !g_TeamInfo[i].scores_overriden )
|
||||
g_TeamInfo[i].frags = g_TeamInfo[i].deaths = 0;
|
||||
g_TeamInfo[i].ping = g_TeamInfo[i].packetloss = 0;
|
||||
}
|
||||
|
||||
// recalc the team scores, then draw them
|
||||
for ( i = 1; i < MAX_PLAYERS; i++ )
|
||||
{
|
||||
if ( g_PlayerInfoList[i].name == NULL )
|
||||
continue; // empty player slot, skip
|
||||
|
||||
if ( g_PlayerExtraInfo[i].teamname[0] == 0 )
|
||||
continue; // skip over players who are not in a team
|
||||
|
||||
// find what team this player is in
|
||||
for ( int j = 1; j <= m_iNumTeams; j++ )
|
||||
{
|
||||
if ( !stricmp( g_PlayerExtraInfo[i].teamname, g_TeamInfo[j].name ) )
|
||||
break;
|
||||
}
|
||||
if ( j > m_iNumTeams ) // player is not in a team, skip to the next guy
|
||||
continue;
|
||||
|
||||
if ( !g_TeamInfo[j].scores_overriden )
|
||||
{
|
||||
g_TeamInfo[j].frags += g_PlayerExtraInfo[i].frags;
|
||||
g_TeamInfo[j].deaths += g_PlayerExtraInfo[i].deaths;
|
||||
}
|
||||
|
||||
g_TeamInfo[j].ping += g_PlayerInfoList[i].ping;
|
||||
g_TeamInfo[j].packetloss += g_PlayerInfoList[i].packetloss;
|
||||
|
||||
if ( g_PlayerInfoList[i].thisplayer )
|
||||
g_TeamInfo[j].ownteam = TRUE;
|
||||
else
|
||||
g_TeamInfo[j].ownteam = FALSE;
|
||||
|
||||
// Set the team's number (used for team colors)
|
||||
g_TeamInfo[j].teamnumber = g_PlayerExtraInfo[i].teamnumber;
|
||||
}
|
||||
|
||||
// find team ping/packetloss averages
|
||||
for ( i = 1; i <= m_iNumTeams; i++ )
|
||||
{
|
||||
g_TeamInfo[i].already_drawn = FALSE;
|
||||
|
||||
if ( g_TeamInfo[i].players > 0 )
|
||||
{
|
||||
g_TeamInfo[i].ping /= g_TeamInfo[i].players; // use the average ping of all the players in the team as the teams ping
|
||||
g_TeamInfo[i].packetloss /= g_TeamInfo[i].players; // use the average ping of all the players in the team as the teams ping
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the teams
|
||||
while ( 1 )
|
||||
{
|
||||
int highest_frags = -99999; int lowest_deaths = 99999;
|
||||
int best_team = 0;
|
||||
|
||||
for ( i = 1; i <= m_iNumTeams; i++ )
|
||||
{
|
||||
if ( g_TeamInfo[i].players < 1 )
|
||||
continue;
|
||||
|
||||
if ( !g_TeamInfo[i].already_drawn && g_TeamInfo[i].frags >= highest_frags )
|
||||
{
|
||||
if ( g_TeamInfo[i].frags > highest_frags || g_TeamInfo[i].deaths < lowest_deaths )
|
||||
{
|
||||
best_team = i;
|
||||
lowest_deaths = g_TeamInfo[i].deaths;
|
||||
highest_frags = g_TeamInfo[i].frags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// draw the best team on the scoreboard
|
||||
if ( !best_team )
|
||||
break;
|
||||
|
||||
// Put this team in the sorted list
|
||||
_tablePanel->m_iSortedRows[ _tablePanel->m_iRows ] = best_team;
|
||||
_tablePanel->m_iIsATeam[ _tablePanel->m_iRows ] = TEAM_YES;
|
||||
g_TeamInfo[best_team].already_drawn = TRUE; // set the already_drawn to be TRUE, so this team won't get sorted again
|
||||
_tablePanel->m_iRows++;
|
||||
|
||||
// Now sort all the players on this team
|
||||
SortPlayers( 0, g_TeamInfo[best_team].name );
|
||||
}
|
||||
|
||||
// Now add all the spectators
|
||||
SortPlayers( TEAM_SPECTATORS, NULL );
|
||||
|
||||
// Now add all the players who aren't in a team yet
|
||||
SortPlayers( TEAM_UNASSIGNED, NULL );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sort a list of players
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScorePanel::SortPlayers( int iTeam, char *team )
|
||||
{
|
||||
bool bCreatedTeam = false;
|
||||
|
||||
// draw the players, in order, and restricted to team if set
|
||||
while ( 1 )
|
||||
{
|
||||
// Find the top ranking player
|
||||
int highest_frags = -99999; int lowest_deaths = 99999;
|
||||
int best_player;
|
||||
best_player = 0;
|
||||
|
||||
for ( int i = 1; i < MAX_PLAYERS; i++ )
|
||||
{
|
||||
if ( _tablePanel->m_bHasBeenSorted[i] == false && g_PlayerInfoList[i].name && g_PlayerExtraInfo[i].frags >= highest_frags )
|
||||
{
|
||||
cl_entity_t *ent = gEngfuncs.GetEntityByIndex( i );
|
||||
|
||||
if ( ent && ((iTeam == TEAM_SPECTATORS && g_IsSpectator[i] != 0) || (iTeam != TEAM_SPECTATORS && !(team && stricmp(g_PlayerExtraInfo[i].teamname, team)))) )
|
||||
{
|
||||
extra_player_info_t *pl_info = &g_PlayerExtraInfo[i];
|
||||
if ( pl_info->frags > highest_frags || pl_info->deaths < lowest_deaths )
|
||||
{
|
||||
best_player = i;
|
||||
lowest_deaths = pl_info->deaths;
|
||||
highest_frags = pl_info->frags;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !best_player )
|
||||
break;
|
||||
|
||||
// If we haven't created the Team yet, do it first
|
||||
if (!bCreatedTeam && iTeam)
|
||||
{
|
||||
_tablePanel->m_iIsATeam[ _tablePanel->m_iRows ] = iTeam;
|
||||
_tablePanel->m_iRows++;
|
||||
|
||||
bCreatedTeam = true;
|
||||
}
|
||||
|
||||
// Put this player in the sorted list
|
||||
_tablePanel->m_iSortedRows[ _tablePanel->m_iRows ] = best_player;
|
||||
_tablePanel->m_bHasBeenSorted[ best_player ] = true;
|
||||
_tablePanel->m_iRows++;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Recalculate the existing teams in the match
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScorePanel::RebuildTeams()
|
||||
{
|
||||
// clear out player counts from teams
|
||||
for ( int i = 1; i <= m_iNumTeams; i++ )
|
||||
{
|
||||
g_TeamInfo[i].players = 0;
|
||||
}
|
||||
|
||||
// rebuild the team list
|
||||
gViewPort->GetAllPlayersInfo();
|
||||
m_iNumTeams = 0;
|
||||
for ( i = 1; i < MAX_PLAYERS; i++ )
|
||||
{
|
||||
if ( g_PlayerInfoList[i].name == NULL )
|
||||
continue;
|
||||
|
||||
if ( g_PlayerExtraInfo[i].teamname[0] == 0 )
|
||||
continue; // skip over players who are not in a team
|
||||
|
||||
// is this player in an existing team?
|
||||
for ( int j = 1; j <= m_iNumTeams; j++ )
|
||||
{
|
||||
if ( g_TeamInfo[j].name[0] == '\0' )
|
||||
break;
|
||||
|
||||
if ( !stricmp( g_PlayerExtraInfo[i].teamname, g_TeamInfo[j].name ) )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( j > m_iNumTeams )
|
||||
{ // they aren't in a listed team, so make a new one
|
||||
// search through for an empty team slot
|
||||
for ( int j = 1; j <= m_iNumTeams; j++ )
|
||||
{
|
||||
if ( g_TeamInfo[j].name[0] == '\0' )
|
||||
break;
|
||||
}
|
||||
m_iNumTeams = max( j, m_iNumTeams );
|
||||
|
||||
strncpy( g_TeamInfo[j].name, g_PlayerExtraInfo[i].teamname, MAX_TEAM_NAME );
|
||||
g_TeamInfo[j].players = 0;
|
||||
}
|
||||
|
||||
g_TeamInfo[j].players++;
|
||||
}
|
||||
|
||||
// clear out any empty teams
|
||||
for ( i = 1; i <= m_iNumTeams; i++ )
|
||||
{
|
||||
if ( g_TeamInfo[i].players < 1 )
|
||||
memset( &g_TeamInfo[i], 0, sizeof(team_info_t) );
|
||||
}
|
||||
|
||||
// Update the scoreboard
|
||||
Update();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Setup highlights for player names in scoreboard
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScorePanel::DeathMsg( int killer, int victim )
|
||||
{
|
||||
// if we were the one killed, or the world killed us, set the scoreboard to indicate suicide
|
||||
if ( victim == m_iPlayerNum || killer == 0 )
|
||||
{
|
||||
_tablePanel->m_iLastKilledBy = killer ? killer : m_iPlayerNum;
|
||||
_tablePanel->m_fLastKillTime = gHUD.m_flTime + 10; // display who we were killed by for 10 seconds
|
||||
|
||||
if ( killer == m_iPlayerNum )
|
||||
_tablePanel->m_iLastKilledBy = m_iPlayerNum;
|
||||
}
|
||||
}
|
||||
|
122
cl_dll/vgui_ScorePanel.h
Normal file
122
cl_dll/vgui_ScorePanel.h
Normal file
@ -0,0 +1,122 @@
|
||||
|
||||
#ifndef SCOREPANEL_H
|
||||
#define SCOREPANEL_H
|
||||
|
||||
#include<VGUI_Panel.h>
|
||||
#include<VGUI_TablePanel.h>
|
||||
#include<VGUI_HeaderPanel.h>
|
||||
#include<VGUI_TextGrid.h>
|
||||
#include<VGUI_Label.h>
|
||||
|
||||
#define MAX_SCORES 10
|
||||
|
||||
// Scoreboard cells
|
||||
#define NUM_COLUMNS 5
|
||||
#define NUM_ROWS (MAX_PLAYERS + MAX_TEAMS)
|
||||
|
||||
// Scoreboard positions
|
||||
#define SBOARD_INDENT_X XRES(104)
|
||||
#define SBOARD_INDENT_Y YRES(40)
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Custom label for cells in the Scoreboard's Table Header
|
||||
//-----------------------------------------------------------------------------
|
||||
class CLabelHeader : public Label
|
||||
{
|
||||
private:
|
||||
void Init( void )
|
||||
{
|
||||
setFont( Scheme::sf_primary1 );
|
||||
setFgColor( Scheme::sc_primary1 );
|
||||
setBgColor( 0,0,0, 255 );
|
||||
}
|
||||
public:
|
||||
|
||||
CLabelHeader(const char* text,int x,int y,int wide,int tall) : Label(text,x,y,wide,tall)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
CLabelHeader(const char* text, bool bAlignLeft = false) : Label(text)
|
||||
{
|
||||
Init();
|
||||
|
||||
if (bAlignLeft)
|
||||
setContentAlignment(Label::a_west);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Custom Table for the scoreboard
|
||||
//-----------------------------------------------------------------------------
|
||||
class ScoreTablePanel : public TablePanel
|
||||
{
|
||||
private:
|
||||
TextGrid *_textGrid;
|
||||
Label *m_pLabel;
|
||||
|
||||
public:
|
||||
int m_iRows;
|
||||
int m_iSortedRows[NUM_ROWS];
|
||||
int m_iIsATeam[NUM_ROWS];
|
||||
bool m_bHasBeenSorted[MAX_PLAYERS];
|
||||
int m_iLastKilledBy;
|
||||
int m_fLastKillTime;
|
||||
|
||||
public:
|
||||
ScoreTablePanel(int x,int y,int wide,int tall,int columnCount) : TablePanel(x,y,wide,tall,columnCount)
|
||||
{
|
||||
setCellEditingEnabled(false);
|
||||
|
||||
m_pLabel = new Label( "", 0, 0, wide, tall );
|
||||
m_pLabel->setFont( Scheme::sf_primary2 );
|
||||
}
|
||||
virtual int getRowCount()
|
||||
{
|
||||
return m_iRows;
|
||||
}
|
||||
virtual Panel* startCellEditing(int column,int row)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
virtual Panel* getCellRenderer(int column,int row,bool columnSelected,bool rowSelected,bool cellSelected);
|
||||
virtual int getCellTall(int row);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Scoreboard back panel
|
||||
//-----------------------------------------------------------------------------
|
||||
class ScorePanel : public Panel
|
||||
{
|
||||
private:
|
||||
HeaderPanel *_headerPanel;
|
||||
ScoreTablePanel *_tablePanel;
|
||||
Label *m_pTitleLabel;
|
||||
|
||||
public:
|
||||
int m_iNumTeams;
|
||||
int m_iPlayerNum;
|
||||
int m_iShowscoresHeld;
|
||||
|
||||
public:
|
||||
ScorePanel(int x,int y,int wide,int tall);
|
||||
virtual void setSize(int wide,int tall);
|
||||
|
||||
void Update( void );
|
||||
void SortTeams( void );
|
||||
void SortPlayers( int iTeam, char *team );
|
||||
void RebuildTeams( void );
|
||||
void DeathMsg( int killer, int victim );
|
||||
|
||||
void Initialize( void );
|
||||
|
||||
void Open( void )
|
||||
{
|
||||
RebuildTeams();
|
||||
setVisible(true);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
617
cl_dll/vgui_ServerBrowser.cpp
Normal file
617
cl_dll/vgui_ServerBrowser.cpp
Normal file
@ -0,0 +1,617 @@
|
||||
|
||||
#include<VGUI_HeaderPanel.h>
|
||||
#include<VGUI_TablePanel.h>
|
||||
#include<VGUI_LineBorder.h>
|
||||
#include<VGUI_Label.h>
|
||||
#include<VGUI_Button.h>
|
||||
#include<VGUI_ActionSignal.h>
|
||||
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "hud_servers.h"
|
||||
#include "net_api.h"
|
||||
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
#include "vgui_ServerBrowser.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
#define MAX_SB_ROWS 24
|
||||
|
||||
#define NUM_COLUMNS 5
|
||||
|
||||
#define HEADER_SIZE_Y YRES(18)
|
||||
|
||||
// Column sizes
|
||||
#define CSIZE_ADDRESS XRES(200)
|
||||
#define CSIZE_SERVER XRES(400)
|
||||
#define CSIZE_MAP XRES(500)
|
||||
#define CSIZE_CURRENT XRES(570)
|
||||
#define CSIZE_PING XRES(640)
|
||||
|
||||
#define CELL_HEIGHT YRES(15)
|
||||
|
||||
class ServerBrowserTablePanel;
|
||||
|
||||
class CBrowser_InputSignal : public InputSignal
|
||||
{
|
||||
private:
|
||||
ServerBrowserTablePanel *m_pBrowser;
|
||||
public:
|
||||
CBrowser_InputSignal( ServerBrowserTablePanel *pBrowser )
|
||||
{
|
||||
m_pBrowser = pBrowser;
|
||||
}
|
||||
|
||||
virtual void cursorMoved(int x,int y,Panel* panel) {};
|
||||
virtual void cursorEntered(Panel* panel){};
|
||||
virtual void cursorExited(Panel* Panel) {};
|
||||
|
||||
virtual void mousePressed(MouseCode code,Panel* panel);
|
||||
|
||||
virtual void mouseDoublePressed(MouseCode code,Panel* panel);
|
||||
virtual void mouseReleased(MouseCode code,Panel* panel) {};
|
||||
virtual void mouseWheeled(int delta,Panel* panel) {};
|
||||
virtual void keyPressed(KeyCode code,Panel* panel) {};
|
||||
virtual void keyTyped(KeyCode code,Panel* panel) {};
|
||||
virtual void keyReleased(KeyCode code,Panel* panel) {};
|
||||
virtual void keyFocusTicked(Panel* panel) {};
|
||||
};
|
||||
|
||||
class ServerBrowserTablePanel : public TablePanel
|
||||
{
|
||||
private:
|
||||
Label *m_pLabel;
|
||||
int m_nMouseOverRow;
|
||||
|
||||
public:
|
||||
|
||||
ServerBrowserTablePanel( int x,int y,int wide,int tall,int columnCount) : TablePanel( x,y,wide,tall,columnCount)
|
||||
{
|
||||
m_pLabel = new Label( "", 0, 0 /*,wide, tall*/ );
|
||||
|
||||
m_nMouseOverRow = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
void setMouseOverRow( int row )
|
||||
{
|
||||
m_nMouseOverRow = row;
|
||||
}
|
||||
|
||||
void DoSort( char *sortkey )
|
||||
{
|
||||
// Request server list and refresh servers...
|
||||
SortServers( sortkey );
|
||||
}
|
||||
|
||||
void DoRefresh( void )
|
||||
{
|
||||
// Request server list and refresh servers...
|
||||
ServersList();
|
||||
BroadcastServersList( 0 );
|
||||
}
|
||||
|
||||
void DoBroadcastRefresh( void )
|
||||
{
|
||||
// Request server list and refresh servers...
|
||||
BroadcastServersList( 1 );
|
||||
}
|
||||
|
||||
void DoStop( void )
|
||||
{
|
||||
// Stop requesting
|
||||
ServersCancel();
|
||||
}
|
||||
|
||||
void DoCancel( void )
|
||||
{
|
||||
ClientCmd( "togglebrowser\n" );
|
||||
}
|
||||
|
||||
void DoConnect( void )
|
||||
{
|
||||
const char *info;
|
||||
const char *address;
|
||||
char sz[ 256 ];
|
||||
|
||||
info = ServersGetInfo( m_nMouseOverRow );
|
||||
if ( !info )
|
||||
return;
|
||||
|
||||
address = gEngfuncs.pNetAPI->ValueForKey( info, "address" );
|
||||
//gEngfuncs.Con_Printf( "Connecting to %s\n", address );
|
||||
|
||||
sprintf( sz, "connect %s\n", address );
|
||||
|
||||
ClientCmd( sz );
|
||||
|
||||
DoCancel();
|
||||
}
|
||||
|
||||
void DoPing( void )
|
||||
{
|
||||
ServerPing( 0 );
|
||||
ServerRules( 0 );
|
||||
ServerPlayers( 0 );
|
||||
}
|
||||
|
||||
virtual int getRowCount()
|
||||
{
|
||||
int rowcount;
|
||||
int height, width;
|
||||
|
||||
getSize( width, height );
|
||||
|
||||
// Space for buttons
|
||||
height -= YRES(20);
|
||||
height = max( 0, height );
|
||||
|
||||
rowcount = height / CELL_HEIGHT;
|
||||
|
||||
return rowcount;
|
||||
}
|
||||
|
||||
virtual int getCellTall(int row)
|
||||
{
|
||||
return CELL_HEIGHT - 2;
|
||||
}
|
||||
|
||||
virtual Panel* getCellRenderer(int column,int row,bool columnSelected,bool rowSelected,bool cellSelected)
|
||||
{
|
||||
const char *info;
|
||||
const char *val, *val2;
|
||||
char sz[ 32 ];
|
||||
|
||||
info = ServersGetInfo( row );
|
||||
|
||||
if ( row == m_nMouseOverRow )
|
||||
{
|
||||
m_pLabel->setFgColor( 200, 240, 63, 100 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLabel->setFgColor( 255, 255, 255, 0 );
|
||||
}
|
||||
m_pLabel->setBgColor( 0, 0, 0, 200 );
|
||||
m_pLabel->setContentAlignment( vgui::Label::a_west );
|
||||
m_pLabel->setFont( Scheme::sf_primary2 );
|
||||
|
||||
if ( info )
|
||||
{
|
||||
// Fill out with the correct data
|
||||
switch ( column )
|
||||
{
|
||||
case 0:
|
||||
val = gEngfuncs.pNetAPI->ValueForKey( info, "address" );
|
||||
if ( val )
|
||||
{
|
||||
strncpy( sz, val, 31 );
|
||||
sz[ 31 ] = '\0';
|
||||
// Server Name;
|
||||
m_pLabel->setText( sz );
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
val = gEngfuncs.pNetAPI->ValueForKey( info, "hostname" );
|
||||
if ( val )
|
||||
{
|
||||
strncpy( sz, val, 31 );
|
||||
sz[ 31 ] = '\0';
|
||||
// Server Map;
|
||||
m_pLabel->setText( sz );
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
val = gEngfuncs.pNetAPI->ValueForKey( info, "map" );
|
||||
if ( val )
|
||||
{
|
||||
strncpy( sz, val, 31 );
|
||||
sz[ 31 ] = '\0';
|
||||
// Server Name;
|
||||
m_pLabel->setText( sz );
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
val = gEngfuncs.pNetAPI->ValueForKey( info, "current" );
|
||||
val2 = gEngfuncs.pNetAPI->ValueForKey( info, "max" );
|
||||
if ( val && val2 )
|
||||
{
|
||||
sprintf( sz, "%s/%s", val, val2 );
|
||||
sz[ 31 ] = '\0';
|
||||
// Server Map;
|
||||
m_pLabel->setText( sz );
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
val = gEngfuncs.pNetAPI->ValueForKey( info, "ping" );
|
||||
if ( val )
|
||||
{
|
||||
strncpy( sz, val, 31 );
|
||||
sz[ 31 ] = '\0';
|
||||
// Server Name;
|
||||
m_pLabel->setText( sz );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !row && !column )
|
||||
{
|
||||
if ( ServersIsQuerying() )
|
||||
{
|
||||
m_pLabel->setText( "Waiting for servers to respond..." );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLabel->setText( "Press 'Refresh' to search for servers..." );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLabel->setText( "" );
|
||||
}
|
||||
}
|
||||
|
||||
return m_pLabel;
|
||||
}
|
||||
|
||||
virtual Panel* startCellEditing(int column,int row)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class ConnectHandler : public ActionSignal
|
||||
{
|
||||
private:
|
||||
ServerBrowserTablePanel *m_pBrowser;
|
||||
|
||||
public:
|
||||
ConnectHandler( ServerBrowserTablePanel *browser )
|
||||
{
|
||||
m_pBrowser = browser;
|
||||
}
|
||||
|
||||
virtual void actionPerformed( Panel *panel )
|
||||
{
|
||||
m_pBrowser->DoConnect();
|
||||
}
|
||||
};
|
||||
|
||||
class RefreshHandler : public ActionSignal
|
||||
{
|
||||
private:
|
||||
ServerBrowserTablePanel *m_pBrowser;
|
||||
|
||||
public:
|
||||
RefreshHandler( ServerBrowserTablePanel *browser )
|
||||
{
|
||||
m_pBrowser = browser;
|
||||
}
|
||||
|
||||
virtual void actionPerformed( Panel *panel )
|
||||
{
|
||||
m_pBrowser->DoRefresh();
|
||||
}
|
||||
};
|
||||
|
||||
class BroadcastRefreshHandler : public ActionSignal
|
||||
{
|
||||
private:
|
||||
ServerBrowserTablePanel *m_pBrowser;
|
||||
|
||||
public:
|
||||
BroadcastRefreshHandler( ServerBrowserTablePanel *browser )
|
||||
{
|
||||
m_pBrowser = browser;
|
||||
}
|
||||
|
||||
virtual void actionPerformed( Panel *panel )
|
||||
{
|
||||
m_pBrowser->DoBroadcastRefresh();
|
||||
}
|
||||
};
|
||||
|
||||
class StopHandler : public ActionSignal
|
||||
{
|
||||
private:
|
||||
ServerBrowserTablePanel *m_pBrowser;
|
||||
|
||||
public:
|
||||
StopHandler( ServerBrowserTablePanel *browser )
|
||||
{
|
||||
m_pBrowser = browser;
|
||||
}
|
||||
|
||||
virtual void actionPerformed( Panel *panel )
|
||||
{
|
||||
m_pBrowser->DoStop();
|
||||
}
|
||||
};
|
||||
|
||||
class CancelHandler : public ActionSignal
|
||||
{
|
||||
private:
|
||||
ServerBrowserTablePanel *m_pBrowser;
|
||||
|
||||
public:
|
||||
CancelHandler( ServerBrowserTablePanel *browser )
|
||||
{
|
||||
m_pBrowser = browser;
|
||||
}
|
||||
|
||||
virtual void actionPerformed( Panel *panel )
|
||||
{
|
||||
m_pBrowser->DoCancel();
|
||||
}
|
||||
};
|
||||
|
||||
class PingHandler : public ActionSignal
|
||||
{
|
||||
private:
|
||||
ServerBrowserTablePanel *m_pBrowser;
|
||||
|
||||
public:
|
||||
PingHandler( ServerBrowserTablePanel *browser )
|
||||
{
|
||||
m_pBrowser = browser;
|
||||
}
|
||||
|
||||
virtual void actionPerformed( Panel *panel )
|
||||
{
|
||||
m_pBrowser->DoPing();
|
||||
}
|
||||
};
|
||||
|
||||
class SortHandler : public ActionSignal
|
||||
{
|
||||
private:
|
||||
ServerBrowserTablePanel *m_pBrowser;
|
||||
|
||||
public:
|
||||
SortHandler( ServerBrowserTablePanel *browser )
|
||||
{
|
||||
m_pBrowser = browser;
|
||||
}
|
||||
|
||||
virtual void actionPerformed( Panel *panel )
|
||||
{
|
||||
m_pBrowser->DoSort( "map" );
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class LabelSortInputHandler : public InputSignal
|
||||
{
|
||||
private:
|
||||
ServerBrowserTablePanel *m_pBrowser;
|
||||
char m_szSortKey[ 64 ];
|
||||
|
||||
public:
|
||||
LabelSortInputHandler( ServerBrowserTablePanel *pBrowser, char *name )
|
||||
{
|
||||
m_pBrowser = pBrowser;
|
||||
strcpy( m_szSortKey, name );
|
||||
}
|
||||
|
||||
virtual void cursorMoved(int x,int y,Panel* panel) {};
|
||||
virtual void cursorEntered(Panel* panel){};
|
||||
virtual void cursorExited(Panel* Panel) {};
|
||||
|
||||
virtual void mousePressed(MouseCode code,Panel* panel)
|
||||
{
|
||||
m_pBrowser->DoSort( m_szSortKey );
|
||||
}
|
||||
|
||||
virtual void mouseDoublePressed(MouseCode code,Panel* panel)
|
||||
{
|
||||
m_pBrowser->DoSort( m_szSortKey );
|
||||
}
|
||||
|
||||
virtual void mouseReleased(MouseCode code,Panel* panel) {};
|
||||
virtual void mouseWheeled(int delta,Panel* panel) {};
|
||||
virtual void keyPressed(KeyCode code,Panel* panel) {};
|
||||
virtual void keyTyped(KeyCode code,Panel* panel) {};
|
||||
virtual void keyReleased(KeyCode code,Panel* panel) {};
|
||||
virtual void keyFocusTicked(Panel* panel) {};
|
||||
};
|
||||
|
||||
class CSBLabel : public Label
|
||||
{
|
||||
|
||||
private:
|
||||
char m_szSortKey[ 64 ];
|
||||
ServerBrowserTablePanel *m_pBrowser;
|
||||
|
||||
public:
|
||||
CSBLabel( char *name, char *sortkey ) : Label( name )
|
||||
{
|
||||
m_pBrowser = NULL;
|
||||
|
||||
strcpy( m_szSortKey, sortkey );
|
||||
|
||||
int label_bg_r = 120,
|
||||
label_bg_g = 75,
|
||||
label_bg_b = 32,
|
||||
label_bg_a = 200;
|
||||
|
||||
int label_fg_r = 255,
|
||||
label_fg_g = 0,
|
||||
label_fg_b = 0,
|
||||
label_fg_a = 0;
|
||||
|
||||
setContentAlignment( vgui::Label::a_west );
|
||||
setFgColor( label_fg_r, label_fg_g, label_fg_b, label_fg_a );
|
||||
setBgColor( label_bg_r, label_bg_g, label_bg_b, label_bg_a );
|
||||
setFont( Scheme::sf_primary2 );
|
||||
|
||||
}
|
||||
|
||||
void setTable( ServerBrowserTablePanel *browser )
|
||||
{
|
||||
m_pBrowser = browser;
|
||||
|
||||
addInputSignal( new LabelSortInputHandler( (ServerBrowserTablePanel * )m_pBrowser, m_szSortKey ) );
|
||||
}
|
||||
};
|
||||
|
||||
ServerBrowser::ServerBrowser(int x,int y,int wide,int tall) : CTransparentPanel( 100, x,y,wide,tall )
|
||||
{
|
||||
int i;
|
||||
|
||||
_headerPanel = new HeaderPanel(0,0,wide,HEADER_SIZE_Y);
|
||||
_headerPanel->setParent(this);
|
||||
_headerPanel->setFgColor( 100,100,100, 100 );
|
||||
_headerPanel->setBgColor( 0, 0, 0, 100 );
|
||||
|
||||
CSBLabel *pLabel[5];
|
||||
|
||||
pLabel[0] = new CSBLabel( "Address", "address" );
|
||||
pLabel[1] = new CSBLabel( "Server", "hostname" );
|
||||
pLabel[2] = new CSBLabel( "Map", "map" );
|
||||
pLabel[3] = new CSBLabel( "Current", "current" );
|
||||
pLabel[4] = new CSBLabel( "Latency", "ping" );
|
||||
|
||||
for ( i = 0; i < 5; i++ )
|
||||
{
|
||||
_headerPanel->addSectionPanel( pLabel[i] );
|
||||
}
|
||||
|
||||
// _headerPanel->setFont( Scheme::sf_primary1 );
|
||||
|
||||
_headerPanel->setSliderPos( 0, CSIZE_ADDRESS );
|
||||
_headerPanel->setSliderPos( 1, CSIZE_SERVER );
|
||||
_headerPanel->setSliderPos( 2, CSIZE_MAP );
|
||||
_headerPanel->setSliderPos( 3, CSIZE_CURRENT );
|
||||
_headerPanel->setSliderPos( 4, CSIZE_PING );
|
||||
|
||||
_tablePanel = new ServerBrowserTablePanel( 0, HEADER_SIZE_Y, wide, tall - HEADER_SIZE_Y, NUM_COLUMNS );
|
||||
_tablePanel->setParent(this);
|
||||
_tablePanel->setHeaderPanel(_headerPanel);
|
||||
_tablePanel->setFgColor( 100,100,100, 100 );
|
||||
_tablePanel->setBgColor( 0, 0, 0, 100 );
|
||||
|
||||
_tablePanel->addInputSignal( new CBrowser_InputSignal( (ServerBrowserTablePanel *)_tablePanel ) );
|
||||
|
||||
for ( i = 0; i < 5; i++ )
|
||||
{
|
||||
pLabel[i]->setTable( (ServerBrowserTablePanel * )_tablePanel );
|
||||
}
|
||||
|
||||
int bw = 80, bh = 15;
|
||||
int by = tall - HEADER_SIZE_Y;
|
||||
|
||||
int btnx = 10;
|
||||
|
||||
_connectButton = new CommandButton( "Connect", btnx, by, bw, bh );
|
||||
_connectButton->setParent( this );
|
||||
_connectButton->addActionSignal( new ConnectHandler( (ServerBrowserTablePanel * )_tablePanel ) );
|
||||
|
||||
btnx += bw;
|
||||
|
||||
_refreshButton = new CommandButton( "Refresh", btnx, by, bw, bh );
|
||||
_refreshButton->setParent( this );
|
||||
_refreshButton->addActionSignal( new RefreshHandler( (ServerBrowserTablePanel * )_tablePanel ) );
|
||||
|
||||
/*
|
||||
btnx += bw;
|
||||
|
||||
_broadcastRefreshButton = new CommandButton( "LAN", btnx, by, bw, bh );
|
||||
_broadcastRefreshButton->setParent( this );
|
||||
_broadcastRefreshButton->addActionSignal( new BroadcastRefreshHandler( (ServerBrowserTablePanel * )_tablePanel ) );
|
||||
*/
|
||||
|
||||
btnx += bw;
|
||||
|
||||
_stopButton = new CommandButton( "Stop", btnx, by, bw, bh );
|
||||
_stopButton->setParent( this );
|
||||
_stopButton->addActionSignal( new StopHandler( (ServerBrowserTablePanel * )_tablePanel ) );
|
||||
|
||||
/*
|
||||
btnx += bw;
|
||||
|
||||
_pingButton = new CommandButton( "Test", btnx, by, bw, bh );
|
||||
_pingButton->setParent( this );
|
||||
_pingButton->addActionSignal( new PingHandler( (ServerBrowserTablePanel * )_tablePanel ) );
|
||||
|
||||
btnx += bw;
|
||||
|
||||
_sortButton = new CommandButton( "Sort", btnx, by, bw, bh );
|
||||
_sortButton->setParent( this );
|
||||
_sortButton->addActionSignal( new SortHandler( (ServerBrowserTablePanel * )_tablePanel ) );
|
||||
*/
|
||||
|
||||
btnx += bw;
|
||||
|
||||
_cancelButton = new CommandButton( "Close", btnx, by, bw, bh );
|
||||
_cancelButton->setParent( this );
|
||||
_cancelButton->addActionSignal( new CancelHandler( (ServerBrowserTablePanel * )_tablePanel ) );
|
||||
|
||||
setPaintBorderEnabled(false);
|
||||
setPaintBackgroundEnabled(false);
|
||||
setPaintEnabled(false);
|
||||
|
||||
}
|
||||
|
||||
void ServerBrowser::setSize(int wide,int tall)
|
||||
{
|
||||
Panel::setSize(wide,tall);
|
||||
|
||||
_headerPanel->setBounds(0,0,wide,HEADER_SIZE_Y);
|
||||
_tablePanel->setBounds(0,HEADER_SIZE_Y,wide,tall - HEADER_SIZE_Y);
|
||||
|
||||
_connectButton->setBounds( 5, tall - HEADER_SIZE_Y, 75, 15 );
|
||||
_refreshButton->setBounds( 85, tall - HEADER_SIZE_Y, 75, 15 );
|
||||
/*
|
||||
_broadcastRefreshButton->setBounds( 165, tall - HEADER_SIZE_Y, 75, 15 );
|
||||
*/
|
||||
_stopButton->setBounds( 165, tall - HEADER_SIZE_Y, 75, 15 );
|
||||
/*
|
||||
_pingButton->setBounds( 325, tall - HEADER_SIZE_Y, 75, 15 );
|
||||
*/
|
||||
_cancelButton->setBounds( 245, tall - HEADER_SIZE_Y, 75, 15 );
|
||||
}
|
||||
|
||||
void CBrowser_InputSignal::mousePressed(MouseCode code,Panel* panel)
|
||||
{
|
||||
int x, y;
|
||||
int therow = 2;
|
||||
|
||||
if ( code != MOUSE_LEFT )
|
||||
return;
|
||||
|
||||
panel->getApp()->getCursorPos(x,y);
|
||||
panel->screenToLocal( x, y );
|
||||
|
||||
therow = y / CELL_HEIGHT;
|
||||
|
||||
// Figure out which row it's on
|
||||
m_pBrowser->setMouseOverRow( therow );
|
||||
}
|
||||
|
||||
void CBrowser_InputSignal::mouseDoublePressed(MouseCode code,Panel* panel)
|
||||
{
|
||||
int x, y;
|
||||
int therow = 2;
|
||||
|
||||
if ( code != MOUSE_LEFT )
|
||||
return;
|
||||
|
||||
panel->getApp()->getCursorPos(x,y);
|
||||
panel->screenToLocal( x, y );
|
||||
|
||||
therow = y / CELL_HEIGHT;
|
||||
|
||||
// Figure out which row it's on
|
||||
m_pBrowser->setMouseOverRow( therow );
|
||||
m_pBrowser->DoConnect();
|
||||
}
|
44
cl_dll/vgui_ServerBrowser.h
Normal file
44
cl_dll/vgui_ServerBrowser.h
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
#ifndef ServerBrowser_H
|
||||
#define ServerBrowser_H
|
||||
|
||||
#include<VGUI_Panel.h>
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class Button;
|
||||
class TablePanel;
|
||||
class HeaderPanel;
|
||||
}
|
||||
|
||||
class CTransparentPanel;
|
||||
class CommandButton;
|
||||
|
||||
// Scoreboard positions
|
||||
#define SB_X_INDENT (20 * ((float)ScreenHeight / 640))
|
||||
#define SB_Y_INDENT (20 * ((float)ScreenHeight / 480))
|
||||
|
||||
class ServerBrowser : public CTransparentPanel
|
||||
{
|
||||
private:
|
||||
HeaderPanel * _headerPanel;
|
||||
TablePanel* _tablePanel;
|
||||
|
||||
CommandButton* _connectButton;
|
||||
CommandButton* _refreshButton;
|
||||
CommandButton* _broadcastRefreshButton;
|
||||
CommandButton* _stopButton;
|
||||
CommandButton* _sortButton;
|
||||
CommandButton* _cancelButton;
|
||||
|
||||
CommandButton* _pingButton;
|
||||
|
||||
public:
|
||||
ServerBrowser(int x,int y,int wide,int tall);
|
||||
public:
|
||||
virtual void setSize(int wide,int tall);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
2134
cl_dll/vgui_TeamFortressViewport.cpp
Normal file
2134
cl_dll/vgui_TeamFortressViewport.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1255
cl_dll/vgui_TeamFortressViewport.h
Normal file
1255
cl_dll/vgui_TeamFortressViewport.h
Normal file
File diff suppressed because it is too large
Load Diff
122
cl_dll/vgui_int.cpp
Normal file
122
cl_dll/vgui_int.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
|
||||
#include"vgui_int.h"
|
||||
#include<VGUI_Label.h>
|
||||
#include<VGUI_BorderLayout.h>
|
||||
#include<VGUI_LineBorder.h>
|
||||
#include<VGUI_SurfaceBase.h>
|
||||
#include<VGUI_TextEntry.h>
|
||||
#include<VGUI_ActionSignal.h>
|
||||
#include<string.h>
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "camera.h"
|
||||
#include "kbutton.h"
|
||||
#include "cvardef.h"
|
||||
#include "usercmd.h"
|
||||
#include "const.h"
|
||||
#include "camera.h"
|
||||
#include "in_defs.h"
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
#include "vgui_ControlConfigPanel.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class TexturePanel : public Panel , public ActionSignal
|
||||
{
|
||||
private:
|
||||
int _bindIndex;
|
||||
TextEntry* _textEntry;
|
||||
public:
|
||||
TexturePanel() : Panel(0,0,256,276)
|
||||
{
|
||||
_bindIndex=2700;
|
||||
_textEntry=new TextEntry("2700",0,0,128,20);
|
||||
_textEntry->setParent(this);
|
||||
_textEntry->addActionSignal(this);
|
||||
}
|
||||
public:
|
||||
virtual bool isWithin(int x,int y)
|
||||
{
|
||||
return _textEntry->isWithin(x,y);
|
||||
}
|
||||
public:
|
||||
virtual void actionPerformed(Panel* panel)
|
||||
{
|
||||
char buf[256];
|
||||
_textEntry->getText(0,buf,256);
|
||||
sscanf(buf,"%d",&_bindIndex);
|
||||
}
|
||||
protected:
|
||||
virtual void paintBackground()
|
||||
{
|
||||
Panel::paintBackground();
|
||||
|
||||
int wide,tall;
|
||||
getPaintSize(wide,tall);
|
||||
|
||||
drawSetColor(0,0,255,0);
|
||||
drawSetTexture(_bindIndex);
|
||||
drawTexturedRect(0,19,257,257);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
void VGui_ViewportPaintBackground(int extents[4])
|
||||
{
|
||||
gEngfuncs.VGui_ViewportPaintBackground(extents);
|
||||
}
|
||||
|
||||
void* VGui_GetPanel()
|
||||
{
|
||||
return (Panel*)gEngfuncs.VGui_GetPanel();
|
||||
}
|
||||
|
||||
void VGui_Startup()
|
||||
{
|
||||
Panel* root=(Panel*)VGui_GetPanel();
|
||||
root->setBgColor(128,128,0,0);
|
||||
//root->setNonPainted(false);
|
||||
//root->setBorder(new LineBorder());
|
||||
root->setLayout(new BorderLayout(0));
|
||||
|
||||
|
||||
//root->getSurfaceBase()->setEmulatedCursorVisible(true);
|
||||
|
||||
if (gViewPort != NULL)
|
||||
{
|
||||
// root->removeChild(gViewPort);
|
||||
|
||||
// free the memory
|
||||
// delete gViewPort;
|
||||
// gViewPort = NULL;
|
||||
|
||||
gViewPort->Initialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewPort = new TeamFortressViewport(0,0,root->getWide(),root->getTall());
|
||||
gViewPort->setParent(root);
|
||||
}
|
||||
|
||||
/*
|
||||
TexturePanel* texturePanel=new TexturePanel();
|
||||
texturePanel->setParent(gViewPort);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void VGui_Shutdown()
|
||||
{
|
||||
delete gViewPort;
|
||||
gViewPort = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
15
cl_dll/vgui_int.h
Normal file
15
cl_dll/vgui_int.h
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
#ifndef VGUI_INT_H
|
||||
#define VGUI_INT_H
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void VGui_Startup();
|
||||
void VGui_Shutdown();
|
||||
|
||||
//Only safe to call from inside subclass of Panel::paintBackground
|
||||
void VGui_ViewportPaintBackground(int extents[4]);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
389
cl_dll/vgui_teammenu.cpp
Normal file
389
cl_dll/vgui_teammenu.cpp
Normal file
@ -0,0 +1,389 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// Purpose: TFC Team Menu
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "vgui_int.h"
|
||||
#include "VGUI_Font.h"
|
||||
#include "VGUI_ScrollPanel.h"
|
||||
#include "VGUI_TextImage.h"
|
||||
|
||||
#include "hud.h"
|
||||
#include "cl_util.h"
|
||||
#include "vgui_TeamFortressViewport.h"
|
||||
|
||||
// Team Menu Dimensions
|
||||
#define TEAMMENU_TITLE_X XRES(40)
|
||||
#define TEAMMENU_TITLE_Y YRES(32)
|
||||
#define TEAMMENU_TOPLEFT_BUTTON_X XRES(40)
|
||||
#define TEAMMENU_TOPLEFT_BUTTON_Y YRES(80)
|
||||
#define TEAMMENU_BUTTON_SIZE_X XRES(124)
|
||||
#define TEAMMENU_BUTTON_SIZE_Y YRES(24)
|
||||
#define TEAMMENU_BUTTON_SPACER_Y YRES(8)
|
||||
#define TEAMMENU_WINDOW_X XRES(176)
|
||||
#define TEAMMENU_WINDOW_Y YRES(80)
|
||||
#define TEAMMENU_WINDOW_SIZE_X XRES(424)
|
||||
#define TEAMMENU_WINDOW_SIZE_Y YRES(312)
|
||||
#define TEAMMENU_WINDOW_TITLE_X XRES(16)
|
||||
#define TEAMMENU_WINDOW_TITLE_Y YRES(16)
|
||||
#define TEAMMENU_WINDOW_TEXT_X XRES(16)
|
||||
#define TEAMMENU_WINDOW_TEXT_Y YRES(48)
|
||||
#define TEAMMENU_WINDOW_TEXT_SIZE_Y YRES(178)
|
||||
#define TEAMMENU_WINDOW_INFO_X XRES(16)
|
||||
#define TEAMMENU_WINDOW_INFO_Y YRES(234)
|
||||
|
||||
// Creation
|
||||
CTeamMenuPanel::CTeamMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide,int tall) : CMenuPanel(iTrans, iRemoveMe, x,y,wide,tall)
|
||||
{
|
||||
// Get the scheme used for the Titles
|
||||
CSchemeManager *pSchemes = gViewPort->GetSchemeManager();
|
||||
|
||||
// schemes
|
||||
SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "Title Font" );
|
||||
SchemeHandle_t hTeamWindowText = pSchemes->getSchemeHandle( "Briefing Text" );
|
||||
SchemeHandle_t hTeamInfoText = pSchemes->getSchemeHandle( "Team Info Text" );
|
||||
|
||||
// get the Font used for the Titles
|
||||
Font *pTitleFont = pSchemes->getFont( hTitleScheme );
|
||||
int r, g, b, a;
|
||||
|
||||
// Create the title
|
||||
Label *pLabel = new Label( "", TEAMMENU_TITLE_X, TEAMMENU_TITLE_Y );
|
||||
pLabel->setParent( this );
|
||||
pLabel->setFont( pTitleFont );
|
||||
pSchemes->getFgColor( hTitleScheme, r, g, b, a );
|
||||
pLabel->setFgColor( r, g, b, a );
|
||||
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
|
||||
pLabel->setBgColor( r, g, b, a );
|
||||
pLabel->setContentAlignment( vgui::Label::a_west );
|
||||
pLabel->setText(gHUD.m_TextMessage.BufferedLocaliseTextString("#Title_SelectYourTeam"));
|
||||
|
||||
// Create the Info Window
|
||||
m_pTeamWindow = new CTransparentPanel( 255, TEAMMENU_WINDOW_X, TEAMMENU_WINDOW_Y, TEAMMENU_WINDOW_SIZE_X, TEAMMENU_WINDOW_SIZE_Y );
|
||||
m_pTeamWindow->setParent( this );
|
||||
m_pTeamWindow->setBorder( new LineBorder( Color(255*0.7,170*0.7,0,0 )) );
|
||||
|
||||
// Create the Map Name Label
|
||||
m_pMapTitle = new Label( "", TEAMMENU_WINDOW_TITLE_X, TEAMMENU_WINDOW_TITLE_Y );
|
||||
m_pMapTitle->setFont( pTitleFont );
|
||||
m_pMapTitle->setParent( m_pTeamWindow );
|
||||
pSchemes->getFgColor( hTitleScheme, r, g, b, a );
|
||||
m_pMapTitle->setFgColor( r, g, b, a );
|
||||
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
|
||||
m_pMapTitle->setBgColor( r, g, b, a );
|
||||
m_pMapTitle->setContentAlignment( vgui::Label::a_west );
|
||||
|
||||
// Create the Scroll panel
|
||||
m_pScrollPanel = new CTFScrollPanel( TEAMMENU_WINDOW_TEXT_X, TEAMMENU_WINDOW_TEXT_Y, TEAMMENU_WINDOW_SIZE_X - (TEAMMENU_WINDOW_TEXT_X * 2), TEAMMENU_WINDOW_TEXT_SIZE_Y );
|
||||
m_pScrollPanel->setParent(m_pTeamWindow);
|
||||
m_pScrollPanel->setScrollBarVisible(false, false);
|
||||
|
||||
// Create the Map Briefing panel
|
||||
m_pBriefing = new TextPanel("", 0,0, TEAMMENU_WINDOW_SIZE_X - TEAMMENU_WINDOW_TEXT_X, TEAMMENU_WINDOW_TEXT_SIZE_Y );
|
||||
m_pBriefing->setParent( m_pScrollPanel->getClient() );
|
||||
m_pBriefing->setFont( pSchemes->getFont(hTeamWindowText) );
|
||||
pSchemes->getFgColor( hTeamWindowText, r, g, b, a );
|
||||
m_pBriefing->setFgColor( r, g, b, a );
|
||||
pSchemes->getBgColor( hTeamWindowText, r, g, b, a );
|
||||
m_pBriefing->setBgColor( r, g, b, a );
|
||||
|
||||
m_pBriefing->setText("Map Description not available.");
|
||||
|
||||
// Team Menu buttons
|
||||
for (int i = 1; i <= 5; i++)
|
||||
{
|
||||
char sz[256];
|
||||
|
||||
int iYPos = TEAMMENU_TOPLEFT_BUTTON_Y + ( (TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y) * i );
|
||||
|
||||
// Team button
|
||||
m_pButtons[i] = new CommandButton( "", TEAMMENU_TOPLEFT_BUTTON_X, iYPos, TEAMMENU_BUTTON_SIZE_X, TEAMMENU_BUTTON_SIZE_Y, true);
|
||||
m_pButtons[i]->setParent( this );
|
||||
m_pButtons[i]->setContentAlignment( vgui::Label::a_west );
|
||||
m_pButtons[i]->setVisible( false );
|
||||
|
||||
// AutoAssign button uses special case
|
||||
if (i == 5)
|
||||
{
|
||||
m_pButtons[5]->setBoundKey( '5' );
|
||||
m_pButtons[5]->setText( gHUD.m_TextMessage.BufferedLocaliseTextString("#Team_AutoAssign") );
|
||||
m_pButtons[5]->setVisible( true );
|
||||
}
|
||||
|
||||
// Create the Signals
|
||||
sprintf(sz, "jointeam %d", i);
|
||||
m_pButtons[i]->addActionSignal( new CMenuHandler_StringCommandWatch( sz, true ) );
|
||||
m_pButtons[i]->addInputSignal( new CHandler_MenuButtonOver(this, i) );
|
||||
|
||||
// Create the Team Info panel
|
||||
m_pTeamInfoPanel[i] = new TextPanel("", TEAMMENU_WINDOW_INFO_X, TEAMMENU_WINDOW_INFO_Y, TEAMMENU_WINDOW_SIZE_X - TEAMMENU_WINDOW_INFO_X, TEAMMENU_WINDOW_SIZE_X - TEAMMENU_WINDOW_INFO_Y );
|
||||
m_pTeamInfoPanel[i]->setParent( m_pTeamWindow );
|
||||
m_pTeamInfoPanel[i]->setFont( pSchemes->getFont(hTeamInfoText) );
|
||||
m_pTeamInfoPanel[i]->setFgColor( iTeamColors[i][0], iTeamColors[i][1], iTeamColors[i][2], 0 );
|
||||
m_pTeamInfoPanel[i]->setBgColor( 0,0,0, 255 );
|
||||
}
|
||||
|
||||
// Create the Cancel button
|
||||
m_pCancelButton = new CommandButton( CHudTextMessage::BufferedLocaliseTextString( "#Menu_Cancel" ), TEAMMENU_TOPLEFT_BUTTON_X, 0, TEAMMENU_BUTTON_SIZE_X, TEAMMENU_BUTTON_SIZE_Y);
|
||||
m_pCancelButton->setParent( this );
|
||||
m_pCancelButton->addActionSignal( new CMenuHandler_TextWindow(HIDE_TEXTWINDOW) );
|
||||
|
||||
// Create the Spectate button
|
||||
m_pSpectateButton = new SpectateButton( CHudTextMessage::BufferedLocaliseTextString( "#Menu_Spectate" ), TEAMMENU_TOPLEFT_BUTTON_X, 0, TEAMMENU_BUTTON_SIZE_X, TEAMMENU_BUTTON_SIZE_Y, true);
|
||||
m_pSpectateButton->setParent( this );
|
||||
m_pSpectateButton->addActionSignal( new CMenuHandler_StringCommand( "spectate", true ) );
|
||||
m_pSpectateButton->setBoundKey( '6' );
|
||||
m_pSpectateButton->addInputSignal( new CHandler_MenuButtonOver(this, 6) );
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called each time a new level is started.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeamMenuPanel::Initialize( void )
|
||||
{
|
||||
m_bUpdatedMapName = false;
|
||||
m_iCurrentInfo = 0;
|
||||
m_pScrollPanel->setScrollValue( 0, 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called everytime the Team Menu is displayed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeamMenuPanel::Update( void )
|
||||
{
|
||||
int iYPos = TEAMMENU_TOPLEFT_BUTTON_Y;
|
||||
|
||||
// Set the team buttons
|
||||
for (int i = 1; i <= 4; i++)
|
||||
{
|
||||
if (m_pButtons[i])
|
||||
{
|
||||
if ( i <= gViewPort->GetNumberOfTeams() )
|
||||
{
|
||||
m_pButtons[i]->setText( gViewPort->GetTeamName(i) );
|
||||
|
||||
// bound key replacement
|
||||
char sz[32];
|
||||
sprintf( sz, "%d", i );
|
||||
m_pButtons[i]->setBoundKey( sz[0] );
|
||||
|
||||
m_pButtons[i]->setVisible( true );
|
||||
m_pButtons[i]->setPos( TEAMMENU_TOPLEFT_BUTTON_X, iYPos );
|
||||
iYPos += TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y;
|
||||
|
||||
// Start with the first option up
|
||||
if (!m_iCurrentInfo)
|
||||
SetActiveInfo( i );
|
||||
|
||||
char szPlayerList[ (MAX_PLAYER_NAME_LENGTH + 3) * 31 ]; // name + ", "
|
||||
strcpy(szPlayerList, "\n");
|
||||
// Update the Team Info
|
||||
// Now count the number of teammembers of this class
|
||||
int iTotal = 0;
|
||||
for ( int j = 1; j < MAX_PLAYERS; j++ )
|
||||
{
|
||||
if ( g_PlayerInfoList[j].name == NULL )
|
||||
continue; // empty player slot, skip
|
||||
if ( g_PlayerInfoList[j].thisplayer )
|
||||
continue; // skip this player
|
||||
if ( g_PlayerExtraInfo[j].teamnumber != i )
|
||||
continue; // skip over players in other teams
|
||||
|
||||
iTotal++;
|
||||
if (iTotal > 1)
|
||||
strncat( szPlayerList, ", ", sizeof(szPlayerList) - strlen(szPlayerList) );
|
||||
strncat( szPlayerList, g_PlayerInfoList[j].name, sizeof(szPlayerList) - strlen(szPlayerList) );
|
||||
szPlayerList[ sizeof(szPlayerList) - 1 ] = '\0';
|
||||
}
|
||||
|
||||
if (iTotal > 0)
|
||||
{
|
||||
// Set the text of the info Panel
|
||||
char szText[ ((MAX_PLAYER_NAME_LENGTH + 3) * 31) + 256 ];
|
||||
if (iTotal == 1)
|
||||
sprintf(szText, "%s: %d Player (%d points)", gViewPort->GetTeamName(i), iTotal, g_TeamInfo[i].frags );
|
||||
else
|
||||
sprintf(szText, "%s: %d Players (%d points)", gViewPort->GetTeamName(i), iTotal, g_TeamInfo[i].frags );
|
||||
strncat( szText, szPlayerList, sizeof(szText) - strlen(szText) );
|
||||
szText[ sizeof(szText) - 1 ] = '\0';
|
||||
|
||||
m_pTeamInfoPanel[i]->setText( szText );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pTeamInfoPanel[i]->setText( "" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hide the button (may be visible from previous maps)
|
||||
m_pButtons[i]->setVisible( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move the AutoAssign button into place
|
||||
m_pButtons[5]->setPos( TEAMMENU_TOPLEFT_BUTTON_X, iYPos );
|
||||
iYPos += TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y;
|
||||
|
||||
// Spectate button
|
||||
if (m_pSpectateButton->IsNotValid())
|
||||
{
|
||||
m_pSpectateButton->setVisible( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pSpectateButton->setPos( TEAMMENU_TOPLEFT_BUTTON_X, iYPos );
|
||||
m_pSpectateButton->setVisible( true );
|
||||
iYPos += TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y;
|
||||
}
|
||||
|
||||
// If the player is already in a team, make the cancel button visible
|
||||
if ( g_iTeamNumber )
|
||||
{
|
||||
m_pCancelButton->setPos( TEAMMENU_TOPLEFT_BUTTON_X, iYPos );
|
||||
iYPos += TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y;
|
||||
m_pCancelButton->setVisible( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pCancelButton->setVisible( false );
|
||||
}
|
||||
|
||||
// Set the Map Title
|
||||
if (!m_bUpdatedMapName)
|
||||
{
|
||||
const char *level = gEngfuncs.pfnGetLevelName();
|
||||
if (level && level[0])
|
||||
{
|
||||
char sz[256];
|
||||
char szTitle[256];
|
||||
char *ch;
|
||||
|
||||
// Update the level name
|
||||
strcpy( sz, level );
|
||||
ch = strchr( sz, '/' );
|
||||
if (!ch)
|
||||
ch = strchr( sz, '\\' );
|
||||
strcpy( szTitle, ch+1 );
|
||||
ch = strchr( szTitle, '.' );
|
||||
*ch = '\0';
|
||||
m_pMapTitle->setText( szTitle );
|
||||
*ch = '.';
|
||||
|
||||
// Update the map briefing
|
||||
strcpy( sz, level );
|
||||
ch = strchr( sz, '.' );
|
||||
*ch = '\0';
|
||||
strcat( sz, ".txt" );
|
||||
char *pfile = (char*)gEngfuncs.COM_LoadFile( sz, 5, NULL );
|
||||
if (pfile)
|
||||
{
|
||||
m_pBriefing->setText( pfile );
|
||||
|
||||
// Get the total size of the Briefing text and resize the text panel
|
||||
int iXSize, iYSize;
|
||||
m_pBriefing->getTextImage()->getTextSize( iXSize, iYSize );
|
||||
m_pBriefing->setSize( iXSize, iYSize );
|
||||
}
|
||||
|
||||
m_bUpdatedMapName = true;
|
||||
}
|
||||
}
|
||||
|
||||
m_pScrollPanel->validate();
|
||||
}
|
||||
|
||||
//=====================================
|
||||
// Key inputs
|
||||
bool CTeamMenuPanel::SlotInput( int iSlot )
|
||||
{
|
||||
// Check for AutoAssign
|
||||
if ( iSlot == 5)
|
||||
{
|
||||
m_pButtons[5]->fireActionSignal();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Spectate
|
||||
if ( iSlot == 6)
|
||||
{
|
||||
m_pSpectateButton->fireActionSignal();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, see if a particular team is selectable
|
||||
if ( (iSlot < 1) || (iSlot > gViewPort->GetNumberOfTeams()) )
|
||||
return false;
|
||||
if ( !m_pButtons[ iSlot ] )
|
||||
return false;
|
||||
|
||||
// Is the button pushable?
|
||||
if ( m_pButtons[ iSlot ]->isVisible() )
|
||||
{
|
||||
m_pButtons[ iSlot ]->fireActionSignal();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//======================================
|
||||
// Update the Team menu before opening it
|
||||
void CTeamMenuPanel::Open( void )
|
||||
{
|
||||
Update();
|
||||
CMenuPanel::Open();
|
||||
}
|
||||
|
||||
void CTeamMenuPanel::paintBackground()
|
||||
{
|
||||
// make sure we get the map briefing up
|
||||
if ( !m_bUpdatedMapName )
|
||||
Update();
|
||||
|
||||
CMenuPanel::paintBackground();
|
||||
}
|
||||
|
||||
//======================================
|
||||
// Mouse is over a team button, bring up the class info
|
||||
void CTeamMenuPanel::SetActiveInfo( int iInput )
|
||||
{
|
||||
// Remove all the Info panels and bring up the specified one
|
||||
m_pSpectateButton->setArmed( false );
|
||||
for (int i = 1; i <= 5; i++)
|
||||
{
|
||||
m_pButtons[i]->setArmed( false );
|
||||
m_pTeamInfoPanel[i]->setVisible( false );
|
||||
}
|
||||
|
||||
// 6 is Spectate
|
||||
if (iInput == 6)
|
||||
{
|
||||
m_pSpectateButton->setArmed( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pButtons[iInput]->setArmed( true );
|
||||
m_pTeamInfoPanel[iInput]->setVisible( true );
|
||||
}
|
||||
|
||||
m_iCurrentInfo = iInput;
|
||||
|
||||
m_pScrollPanel->validate();
|
||||
}
|
1023
cl_dll/view.cpp
Normal file
1023
cl_dll/view.cpp
Normal file
File diff suppressed because it is too large
Load Diff
8
cl_dll/view.h
Normal file
8
cl_dll/view.h
Normal file
@ -0,0 +1,8 @@
|
||||
#if !defined ( VIEWH )
|
||||
#define VIEWH
|
||||
#pragma once
|
||||
|
||||
void V_StartPitchDrift( void );
|
||||
void V_StopPitchDrift( void );
|
||||
|
||||
#endif // !VIEWH
|
9
cl_dll/wrect.h
Normal file
9
cl_dll/wrect.h
Normal file
@ -0,0 +1,9 @@
|
||||
#if !defined( WRECTH )
|
||||
#define WRECTH
|
||||
|
||||
typedef struct rect_s
|
||||
{
|
||||
int left, right, top, bottom;
|
||||
} wrect_t;
|
||||
|
||||
#endif
|
62
common/beamdef.h
Normal file
62
common/beamdef.h
Normal file
@ -0,0 +1,62 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#if !defined ( BEAMDEFH )
|
||||
#define BEAMDEFH
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define FBEAM_STARTENTITY 0x00000001
|
||||
#define FBEAM_ENDENTITY 0x00000002
|
||||
#define FBEAM_FADEIN 0x00000004
|
||||
#define FBEAM_FADEOUT 0x00000008
|
||||
#define FBEAM_SINENOISE 0x00000010
|
||||
#define FBEAM_SOLID 0x00000020
|
||||
#define FBEAM_SHADEIN 0x00000040
|
||||
#define FBEAM_SHADEOUT 0x00000080
|
||||
#define FBEAM_STARTVISIBLE 0x10000000 // Has this client actually seen this beam's start entity yet?
|
||||
#define FBEAM_ENDVISIBLE 0x20000000 // Has this client actually seen this beam's end entity yet?
|
||||
#define FBEAM_ISACTIVE 0x40000000
|
||||
#define FBEAM_FOREVER 0x80000000
|
||||
|
||||
typedef struct beam_s BEAM;
|
||||
struct beam_s
|
||||
{
|
||||
BEAM *next;
|
||||
int type;
|
||||
int flags;
|
||||
vec3_t source;
|
||||
vec3_t target;
|
||||
vec3_t delta;
|
||||
float t; // 0 .. 1 over lifetime of beam
|
||||
float freq;
|
||||
float die;
|
||||
float width;
|
||||
float amplitude;
|
||||
float r, g, b;
|
||||
float brightness;
|
||||
float speed;
|
||||
float frameRate;
|
||||
float frame;
|
||||
int segments;
|
||||
int startEntity;
|
||||
int endEntity;
|
||||
int modelIndex;
|
||||
int frameCount;
|
||||
struct model_s *pFollowModel;
|
||||
struct particle_s *particles;
|
||||
};
|
||||
|
||||
#endif
|
115
common/cl_entity.h
Normal file
115
common/cl_entity.h
Normal file
@ -0,0 +1,115 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
// cl_entity.h
|
||||
#if !defined( CL_ENTITYH )
|
||||
#define CL_ENTITYH
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
typedef struct efrag_s
|
||||
{
|
||||
struct mleaf_s *leaf;
|
||||
struct efrag_s *leafnext;
|
||||
struct cl_entity_s *entity;
|
||||
struct efrag_s *entnext;
|
||||
} efrag_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
byte mouthopen; // 0 = mouth closed, 255 = mouth agape
|
||||
byte sndcount; // counter for running average
|
||||
int sndavg; // running average
|
||||
} mouth_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float prevanimtime;
|
||||
float sequencetime;
|
||||
byte prevseqblending[2];
|
||||
vec3_t prevorigin;
|
||||
vec3_t prevangles;
|
||||
|
||||
int prevsequence;
|
||||
float prevframe;
|
||||
|
||||
byte prevcontroller[4];
|
||||
byte prevblending[2];
|
||||
} latchedvars_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Time stamp for this movement
|
||||
float animtime;
|
||||
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
} position_history_t;
|
||||
|
||||
typedef struct cl_entity_s cl_entity_t;
|
||||
|
||||
#define HISTORY_MAX 64 // Must be power of 2
|
||||
#define HISTORY_MASK ( HISTORY_MAX - 1 )
|
||||
|
||||
|
||||
#if !defined( ENTITY_STATEH )
|
||||
#include "entity_state.h"
|
||||
#endif
|
||||
|
||||
#if !defined( PROGS_H )
|
||||
#include "progs.h"
|
||||
#endif
|
||||
|
||||
struct cl_entity_s
|
||||
{
|
||||
int index; // Index into cl_entities ( should match actual slot, but not necessarily )
|
||||
|
||||
qboolean player; // True if this entity is a "player"
|
||||
|
||||
entity_state_t baseline; // The original state from which to delta during an uncompressed message
|
||||
entity_state_t prevstate; // The state information from the penultimate message received from the server
|
||||
entity_state_t curstate; // The state information from the last message received from server
|
||||
|
||||
int current_position; // Last received history update index
|
||||
position_history_t ph[ HISTORY_MAX ]; // History of position and angle updates for this player
|
||||
|
||||
mouth_t mouth; // For synchronizing mouth movements.
|
||||
|
||||
latchedvars_t latched; // Variables used by studio model rendering routines
|
||||
|
||||
// Information based on interplocation, extrapolation, prediction, or just copied from last msg received.
|
||||
//
|
||||
float lastmove;
|
||||
|
||||
// Actual render position and angles
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
|
||||
// Attachment points
|
||||
vec3_t attachment[4];
|
||||
|
||||
// Other entity local information
|
||||
int trivial_accept;
|
||||
|
||||
struct model_s *model; // cl.model_precache[ curstate.modelindes ]; all visible entities have a model
|
||||
struct efrag_s *efrag; // linked list of efrags
|
||||
struct mnode_s *topnode; // for bmodels, first world node that splits bmodel, or NULL if not split
|
||||
|
||||
float syncbase; // for client-side animations -- used by obsolete alias animation system, remove?
|
||||
int visframe; // last frame this entity was found in an active leaf
|
||||
colorVec cvFloorColor;
|
||||
};
|
||||
|
||||
#endif // !CL_ENTITYH
|
31
common/con_nprint.h
Normal file
31
common/con_nprint.h
Normal file
@ -0,0 +1,31 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#if !defined( CON_NPRINTH )
|
||||
#define CON_NPRINTH
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
typedef struct con_nprint_s
|
||||
{
|
||||
int index; // Row #
|
||||
float time_to_live; // # of seconds before it dissappears
|
||||
float color[ 3 ]; // RGB colors ( 0.0 -> 1.0 scale )
|
||||
} con_nprint_t;
|
||||
|
||||
void Con_NPrintf( int idx, char *fmt, ... );
|
||||
void Con_NXPrintf( struct con_nprint_s *info, char *fmt, ... );
|
||||
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, Valve LLC. All rights reserved.
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
@ -28,7 +28,7 @@
|
||||
#define FL_MONSTER (1<<5)
|
||||
#define FL_GODMODE (1<<6)
|
||||
#define FL_NOTARGET (1<<7)
|
||||
//#define FL_ITEM (1<<8) // NOT USED
|
||||
#define FL_SKIPLOCALHOST (1<<8) // Don't send entity to local host, it's predicting this entity itself
|
||||
#define FL_ONGROUND (1<<9) // At rest / on the ground
|
||||
#define FL_PARTIALGROUND (1<<10) // not all corners are valid
|
||||
#define FL_WATERJUMP (1<<11) // player jumping out of water
|
||||
@ -109,6 +109,9 @@
|
||||
#define EF_NOINTERP 32 // don't interpolate the next frame
|
||||
#define EF_LIGHT 64 // rocket flare glow sprite
|
||||
#define EF_NODRAW 128 // don't draw entity
|
||||
|
||||
// entity flags
|
||||
#define EFLAG_SLERP 1 // do studio interpolation of this entity
|
||||
|
||||
//
|
||||
// temp entity events
|
||||
@ -176,6 +179,7 @@
|
||||
// byte (life in 0.1's)
|
||||
// byte (width in 0.1's)
|
||||
// byte (amplitude in 0.01's)
|
||||
// short (sprite model index)
|
||||
|
||||
#define TE_BEAMENTS 8
|
||||
// short (start entity)
|
||||
@ -546,15 +550,15 @@
|
||||
// byte ( color ) this is an index into an array of color vectors in the engine. (0 - )
|
||||
// byte ( length * 10 )
|
||||
|
||||
#define MSG_BROADCAST 0 // unreliable to all
|
||||
#define MSG_ONE 1 // reliable to one (msg_entity)
|
||||
#define MSG_ALL 2 // reliable to all
|
||||
#define MSG_INIT 3 // write to the init string
|
||||
#define MSG_PVS 4 // Ents in PVS of org
|
||||
#define MSG_PAS 5 // Ents in PAS of org
|
||||
#define MSG_PVS_R 6 // Reliable to PVS
|
||||
#define MSG_PAS_R 7 // Reliable to PAS
|
||||
|
||||
#define MSG_BROADCAST 0 // unreliable to all
|
||||
#define MSG_ONE 1 // reliable to one (msg_entity)
|
||||
#define MSG_ALL 2 // reliable to all
|
||||
#define MSG_INIT 3 // write to the init string
|
||||
#define MSG_PVS 4 // Ents in PVS of org
|
||||
#define MSG_PAS 5 // Ents in PAS of org
|
||||
#define MSG_PVS_R 6 // Reliable to PVS
|
||||
#define MSG_PAS_R 7 // Reliable to PAS
|
||||
#define MSG_ONE_UNRELIABLE 8 // Send to one client, but don't put in reliable stream, put in unreliable datagram ( could be dropped )
|
||||
|
||||
// contents of a spot in the world
|
||||
#define CONTENTS_EMPTY -1
|
||||
@ -616,22 +620,9 @@
|
||||
#define SF_TRAIN_PASSABLE 8 // Train is not solid -- used to make water trains
|
||||
|
||||
// buttons
|
||||
#define IN_ATTACK (1 << 0)
|
||||
#define IN_JUMP (1 << 1)
|
||||
#define IN_DUCK (1 << 2)
|
||||
#define IN_FORWARD (1 << 3)
|
||||
#define IN_BACK (1 << 4)
|
||||
#define IN_USE (1 << 5)
|
||||
#define IN_CANCEL (1 << 6)
|
||||
#define IN_LEFT (1 << 7)
|
||||
#define IN_RIGHT (1 << 8)
|
||||
#define IN_MOVELEFT (1 << 9)
|
||||
#define IN_MOVERIGHT (1 << 10)
|
||||
#define IN_ATTACK2 (1 << 11)
|
||||
#define IN_RUN (1 << 12)
|
||||
#define IN_RELOAD (1 << 13)
|
||||
#define IN_ALT1 (1 << 14)
|
||||
#define IN_ALT2 (1 << 15)
|
||||
#ifndef IN_BUTTONS_H
|
||||
#include "in_buttons.h"
|
||||
#endif
|
||||
|
||||
// Break Model Defines
|
||||
|
||||
@ -725,13 +716,18 @@ typedef struct
|
||||
unsigned r, g, b, a;
|
||||
} colorVec;
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma pack(push,2)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short r, g, b, a;
|
||||
} PackedColorVec;
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
typedef struct link_s
|
||||
{
|
||||
struct link_s *prev, *next;
|
51
common/crc.h
Normal file
51
common/crc.h
Normal file
@ -0,0 +1,51 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
/* crc.h */
|
||||
#ifndef CRC_H
|
||||
#define CRC_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// MD5 Hash
|
||||
typedef struct
|
||||
{
|
||||
unsigned int buf[4];
|
||||
unsigned int bits[2];
|
||||
unsigned char in[64];
|
||||
} MD5Context_t;
|
||||
|
||||
|
||||
typedef unsigned long CRC32_t;
|
||||
void CRC32_Init(CRC32_t *pulCRC);
|
||||
CRC32_t CRC32_Final(CRC32_t pulCRC);
|
||||
void CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len);
|
||||
void CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch);
|
||||
int CRC_File(CRC32_t *crcvalue, char *pszFileName);
|
||||
unsigned char COM_BlockSequenceCRCByte(unsigned char *base, int length, int sequence);
|
||||
|
||||
void MD5Init(MD5Context_t *context);
|
||||
void MD5Update(MD5Context_t *context, unsigned char const *buf,
|
||||
unsigned int len);
|
||||
void MD5Final(unsigned char digest[16], MD5Context_t *context);
|
||||
void Transform(unsigned int buf[4], unsigned int const in[16]);
|
||||
|
||||
int MD5_Hash_File(unsigned char digest[16], char *pszFileName, int bUsefopen, int bSeed, unsigned int seed[4]);
|
||||
char *MD5_Print(unsigned char hash[16]);
|
||||
int MD5_Hash_CachedFile(unsigned char digest[16], unsigned char *pCache, int nFileSize, int bSeed, unsigned int seed[4]);
|
||||
|
||||
int CRC_MapFile(CRC32_t *crcvalue, char *pszFileName);
|
||||
|
||||
#endif
|
36
common/cvardef.h
Normal file
36
common/cvardef.h
Normal file
@ -0,0 +1,36 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#ifndef CVARDEF_H
|
||||
#define CVARDEF_H
|
||||
|
||||
#define FCVAR_ARCHIVE (1<<0) // set to cause it to be saved to vars.rc
|
||||
#define FCVAR_USERINFO (1<<1) // changes the client's info string
|
||||
#define FCVAR_SERVER (1<<2) // notifies players when changed
|
||||
#define FCVAR_EXTDLL (1<<3) // defined by external DLL
|
||||
#define FCVAR_CLIENTDLL (1<<4) // defined by the client dll
|
||||
#define FCVAR_PROTECTED (1<<5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value
|
||||
#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server.
|
||||
#define FCVAR_PRINTABLEONLY (1<<7) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
|
||||
#define FCVAR_UNLOGGED (1<<8) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
|
||||
|
||||
typedef struct cvar_s
|
||||
{
|
||||
char *name;
|
||||
char *string;
|
||||
int flags;
|
||||
float value;
|
||||
struct cvar_s *next;
|
||||
} cvar_t;
|
||||
#endif
|
31
common/demo_api.h
Normal file
31
common/demo_api.h
Normal file
@ -0,0 +1,31 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#if !defined ( DEMO_APIH )
|
||||
#define DEMO_APIH
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
typedef struct demo_api_s
|
||||
{
|
||||
int ( *IsRecording ) ( void );
|
||||
int ( *IsPlayingback ) ( void );
|
||||
int ( *IsTimeDemo ) ( void );
|
||||
void ( *WriteBuffer ) ( int size, unsigned char *buffer );
|
||||
} demo_api_t;
|
||||
|
||||
extern demo_api_t demoapi;
|
||||
|
||||
#endif
|
33
common/dlight.h
Normal file
33
common/dlight.h
Normal file
@ -0,0 +1,33 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#if !defined ( DLIGHTH )
|
||||
#define DLIGHTH
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t origin;
|
||||
float radius;
|
||||
color24 color;
|
||||
float die; // stop lighting after this time
|
||||
float decay; // drop this each second
|
||||
float minlight; // don't add when contributing less
|
||||
int key;
|
||||
qboolean dark; // subtracts light instead of adding
|
||||
} dlight_t;
|
||||
|
||||
#endif
|
15
common/dll_state.h
Normal file
15
common/dll_state.h
Normal file
@ -0,0 +1,15 @@
|
||||
//DLL State Flags
|
||||
|
||||
#define DLL_INACTIVE 0 // no dll
|
||||
#define DLL_ACTIVE 1 // dll is running
|
||||
#define DLL_PAUSED 2 // dll is paused
|
||||
#define DLL_CLOSE 3 // closing down dll
|
||||
#define DLL_TRANS 4 // Level Transition
|
||||
|
||||
// DLL Pause reasons
|
||||
|
||||
#define DLL_NORMAL 0 // User hit Esc or something.
|
||||
#define DLL_QUIT 4 // Quit now
|
||||
|
||||
// DLL Substate info ( not relevant )
|
||||
#define ENG_NORMAL (1<<0)
|
101
common/engine_launcher_api.h
Normal file
101
common/engine_launcher_api.h
Normal file
@ -0,0 +1,101 @@
|
||||
// engine/launcher interface
|
||||
#if !defined( ENGINE_LAUNCHER_APIH )
|
||||
#define ENGINE_LAUNCHER_APIH
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//typedef void ( *xcommand_t ) ( void );
|
||||
|
||||
#define RENDERTYPE_UNDEFINED 0
|
||||
#define RENDERTYPE_SOFTWARE 1
|
||||
#define RENDERTYPE_HARDWARE 2
|
||||
|
||||
#define ENGINE_LAUNCHER_API_VERSION 1
|
||||
|
||||
typedef struct engine_api_s
|
||||
{
|
||||
int version;
|
||||
int rendertype;
|
||||
int size;
|
||||
|
||||
// Functions
|
||||
int ( *GetEngineState ) ( void );
|
||||
void ( *Cbuf_AddText ) ( char *text ); // append cmd at end of buf
|
||||
void ( *Cbuf_InsertText ) ( char *text ); // insert cmd at start of buf
|
||||
void ( *Cmd_AddCommand ) ( char *cmd_name, void ( *funcname )( void ) );
|
||||
int ( *Cmd_Argc ) ( void );
|
||||
char *( *Cmd_Args ) ( void );
|
||||
char *( *Cmd_Argv ) ( int arg );
|
||||
void ( *Con_Printf ) ( char *, ... );
|
||||
void ( *Con_SafePrintf ) ( char *, ... );
|
||||
void ( *Cvar_Set ) ( char *var_name, char *value );
|
||||
void ( *Cvar_SetValue ) ( char *var_name, float value );
|
||||
int ( *Cvar_VariableInt ) ( char *var_name );
|
||||
char *( *Cvar_VariableString ) ( char *var_name );
|
||||
float ( *Cvar_VariableValue ) ( char *var_name );
|
||||
void ( *ForceReloadProfile ) ( void );
|
||||
int ( *GetGameInfo ) ( struct GameInfo_s *pGI, char *pszChannel );
|
||||
void ( *GameSetBackground ) ( int bBack );
|
||||
void ( *GameSetState ) ( int iState );
|
||||
void ( *GameSetSubState ) ( int iState );
|
||||
int ( *GetPauseState ) ( void );
|
||||
int ( *Host_Frame ) ( float time, int iState, int *stateInfo );
|
||||
void ( *Host_GetHostInfo ) ( float *fps, int *nActive, int *nSpectators, int *nMaxPlayers, char *pszMap );
|
||||
void ( *Host_Shutdown ) ( void );
|
||||
int ( *Game_Init ) ( char *lpCmdLine, unsigned char *pMem, int iSize, struct exefuncs_s *pef, void *, int );
|
||||
void ( *IN_ActivateMouse ) ( void );
|
||||
void ( *IN_ClearStates ) ( void );
|
||||
void ( *IN_DeactivateMouse ) ( void );
|
||||
void ( *IN_MouseEvent ) ( int mstate );
|
||||
void ( *Keyboard_ReturnToGame ) ( void );
|
||||
void ( *Key_ClearStates ) ( void );
|
||||
void ( *Key_Event ) ( int key, int down );
|
||||
int ( *LoadGame ) ( const char *pszSlot );
|
||||
void ( *S_BlockSound ) ( void );
|
||||
void ( *S_ClearBuffer ) ( void );
|
||||
void ( *S_GetDSPointer ) ( struct IDirectSound **lpDS, struct IDirectSoundBuffer **lpDSBuf );
|
||||
void *( *S_GetWAVPointer ) ( void );
|
||||
void ( *S_UnblockSound ) ( void );
|
||||
int ( *SaveGame ) ( const char *pszSlot, const char *pszComment );
|
||||
void ( *SetAuth ) ( void *pobj );
|
||||
void ( *SetMessagePumpDisableMode ) ( int bMode );
|
||||
void ( *SetPauseState ) ( int bPause );
|
||||
void ( *SetStartupMode ) ( int bMode );
|
||||
void ( *SNDDMA_Shutdown ) ( void );
|
||||
void ( *Snd_AcquireBuffer ) ( void );
|
||||
void ( *Snd_ReleaseBuffer ) ( void );
|
||||
void ( *StoreProfile ) ( void );
|
||||
double ( *Sys_FloatTime ) ( void );
|
||||
void ( *VID_UpdateWindowVars ) ( void *prc, int x, int y );
|
||||
void ( *VID_UpdateVID ) ( struct viddef_s *pvid );
|
||||
|
||||
// VGUI interfaces
|
||||
void ( *VGui_CallEngineSurfaceProc ) ( void* hwnd, unsigned int msg, unsigned int wparam, long lparam );
|
||||
|
||||
// notifications that the launcher is taking/giving focus to the engine
|
||||
void ( *EngineTakingFocus ) ( void );
|
||||
void ( *LauncherTakingFocus ) ( void );
|
||||
|
||||
#ifdef _WIN32
|
||||
// Only filled in by rendertype RENDERTYPE_HARDWARE
|
||||
void ( *GL_Init ) ( void );
|
||||
int ( *GL_SetMode ) ( HWND hwndGame, HDC *pmaindc, HGLRC *pbaseRC, int fD3D, const char *p, const char *pszCmdLine );
|
||||
void ( *GL_Shutdown ) ( HWND hwnd, HDC hdc, HGLRC hglrc );
|
||||
|
||||
void ( *QGL_D3DShared ) ( struct tagD3DGlobals *d3dGShared );
|
||||
|
||||
int ( WINAPI *glSwapBuffers ) ( HDC dc );
|
||||
#else
|
||||
// NOT USED IN LINUX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
void ( *GL_Init ) ( void );
|
||||
void ( *GL_SetMode ) ( void );
|
||||
void ( *GL_Shutdown ) ( void );
|
||||
void ( *QGL_D3DShared ) ( void );
|
||||
void ( *glSwapBuffers ) ( void );
|
||||
// LINUX
|
||||
#endif
|
||||
|
||||
} engine_api_t;
|
||||
|
||||
#endif // ENGINE_LAUNCHER_APIH
|
193
common/entity_state.h
Normal file
193
common/entity_state.h
Normal file
@ -0,0 +1,193 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#if !defined( ENTITY_STATEH )
|
||||
#define ENTITY_STATEH
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// For entityType below
|
||||
#define ENTITY_NORMAL (1<<0)
|
||||
#define ENTITY_BEAM (1<<1)
|
||||
|
||||
// Entity state is used for the baseline and for delta compression of a packet of
|
||||
// entities that is sent to a client.
|
||||
typedef struct entity_state_s entity_state_t;
|
||||
|
||||
struct entity_state_s
|
||||
{
|
||||
// Fields which are filled in by routines outside of delta compression
|
||||
int entityType;
|
||||
// Index into cl_entities array for this entity.
|
||||
int number;
|
||||
float msg_time;
|
||||
|
||||
// Message number last time the player/entity state was updated.
|
||||
int messagenum;
|
||||
|
||||
// Fields which can be transitted and reconstructed over the network stream
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
|
||||
int modelindex;
|
||||
int sequence;
|
||||
float frame;
|
||||
int colormap;
|
||||
short skin;
|
||||
short solid;
|
||||
int effects;
|
||||
float scale;
|
||||
|
||||
byte eflags;
|
||||
|
||||
// Render information
|
||||
int rendermode;
|
||||
int renderamt;
|
||||
color24 rendercolor;
|
||||
int renderfx;
|
||||
|
||||
int movetype;
|
||||
float animtime;
|
||||
float framerate;
|
||||
int body;
|
||||
byte controller[4];
|
||||
byte blending[4];
|
||||
vec3_t velocity;
|
||||
|
||||
// Send bbox down to client for use during prediction.
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
|
||||
int aiment;
|
||||
// If owned by a player, the index of that player ( for projectiles ).
|
||||
int owner;
|
||||
|
||||
// Friction, for prediction.
|
||||
float friction;
|
||||
// Gravity multiplier
|
||||
float gravity;
|
||||
|
||||
// PLAYER SPECIFIC
|
||||
int team;
|
||||
int playerclass;
|
||||
int health;
|
||||
qboolean spectator;
|
||||
int weaponmodel;
|
||||
int gaitsequence;
|
||||
// If standing on conveyor, e.g.
|
||||
vec3_t basevelocity;
|
||||
// Use the crouched hull, or the regular player hull.
|
||||
int usehull;
|
||||
// Latched buttons last time state updated.
|
||||
int oldbuttons;
|
||||
// -1 = in air, else pmove entity number
|
||||
int onground;
|
||||
int iStepLeft;
|
||||
// How fast we are falling
|
||||
float flFallVelocity;
|
||||
|
||||
float fov;
|
||||
int weaponanim;
|
||||
|
||||
// Parametric movement overrides
|
||||
vec3_t startpos;
|
||||
vec3_t endpos;
|
||||
float impacttime;
|
||||
float starttime;
|
||||
|
||||
// For mods
|
||||
int iuser1;
|
||||
int iuser2;
|
||||
int iuser3;
|
||||
int iuser4;
|
||||
float fuser1;
|
||||
float fuser2;
|
||||
float fuser3;
|
||||
float fuser4;
|
||||
vec3_t vuser1;
|
||||
vec3_t vuser2;
|
||||
vec3_t vuser3;
|
||||
vec3_t vuser4;
|
||||
};
|
||||
|
||||
#include "pm_info.h"
|
||||
|
||||
typedef struct clientdata_s
|
||||
{
|
||||
vec3_t origin;
|
||||
vec3_t velocity;
|
||||
|
||||
int viewmodel;
|
||||
vec3_t punchangle;
|
||||
int flags;
|
||||
int waterlevel;
|
||||
int watertype;
|
||||
vec3_t view_ofs;
|
||||
float health;
|
||||
|
||||
int bInDuck;
|
||||
|
||||
int weapons; // remove?
|
||||
|
||||
int flTimeStepSound;
|
||||
int flDuckTime;
|
||||
int flSwimTime;
|
||||
int waterjumptime;
|
||||
|
||||
float maxspeed;
|
||||
|
||||
float fov;
|
||||
int weaponanim;
|
||||
|
||||
int m_iId;
|
||||
int ammo_shells;
|
||||
int ammo_nails;
|
||||
int ammo_cells;
|
||||
int ammo_rockets;
|
||||
float m_flNextAttack;
|
||||
|
||||
int tfstate;
|
||||
|
||||
int pushmsec;
|
||||
|
||||
int deadflag;
|
||||
|
||||
char physinfo[ MAX_PHYSINFO_STRING ];
|
||||
|
||||
// For mods
|
||||
int iuser1;
|
||||
int iuser2;
|
||||
int iuser3;
|
||||
int iuser4;
|
||||
float fuser1;
|
||||
float fuser2;
|
||||
float fuser3;
|
||||
float fuser4;
|
||||
vec3_t vuser1;
|
||||
vec3_t vuser2;
|
||||
vec3_t vuser3;
|
||||
vec3_t vuser4;
|
||||
} clientdata_t;
|
||||
|
||||
#include "weaponinfo.h"
|
||||
|
||||
typedef struct local_state_s
|
||||
{
|
||||
entity_state_t playerstate;
|
||||
clientdata_t client;
|
||||
weapon_data_t weapondata[ 32 ];
|
||||
} local_state_t;
|
||||
|
||||
#endif // !ENTITY_STATEH
|
26
common/entity_types.h
Normal file
26
common/entity_types.h
Normal file
@ -0,0 +1,26 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
// entity_types.h
|
||||
#if !defined( ENTITY_TYPESH )
|
||||
#define ENTITY_TYPESH
|
||||
|
||||
#define ET_NORMAL 0
|
||||
#define ET_PLAYER 1
|
||||
#define ET_TEMPENTITY 2
|
||||
#define ET_BEAM 3
|
||||
// BMODEL or SPRITE that was split across BSP nodes
|
||||
#define ET_FRAGMENTED 4
|
||||
|
||||
#endif // !ENTITY_TYPESH
|
51
common/event_api.h
Normal file
51
common/event_api.h
Normal file
@ -0,0 +1,51 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#if !defined ( EVENT_APIH )
|
||||
#define EVENT_APIH
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define EVENT_API_VERSION 1
|
||||
|
||||
typedef struct event_api_s
|
||||
{
|
||||
int version;
|
||||
void ( *EV_PlaySound ) ( int ent, float *origin, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch );
|
||||
void ( *EV_StopSound ) ( int ent, int channel, const char *sample );
|
||||
int ( *EV_FindModelIndex )( const char *pmodel );
|
||||
int ( *EV_IsLocal ) ( int playernum );
|
||||
int ( *EV_LocalPlayerDucking ) ( void );
|
||||
void ( *EV_LocalPlayerViewheight ) ( float * );
|
||||
void ( *EV_LocalPlayerBounds ) ( int hull, float *mins, float *maxs );
|
||||
int ( *EV_IndexFromTrace) ( struct pmtrace_s *pTrace );
|
||||
struct physent_s *( *EV_GetPhysent ) ( int idx );
|
||||
void ( *EV_SetUpPlayerPrediction ) ( int dopred, int bIncludeLocalClient );
|
||||
void ( *EV_PushPMStates ) ( void );
|
||||
void ( *EV_PopPMStates ) ( void );
|
||||
void ( *EV_SetSolidPlayers ) (int playernum);
|
||||
void ( *EV_SetTraceHull ) ( int hull );
|
||||
void ( *EV_PlayerTrace ) ( float *start, float *end, int traceFlags, int ignore_pe, struct pmtrace_s *tr );
|
||||
void ( *EV_WeaponAnimation ) ( int sequence, int body );
|
||||
unsigned short ( *EV_PrecacheEvent ) ( int type, const char* psz );
|
||||
void ( *EV_PlaybackEvent ) ( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 );
|
||||
const char *( *EV_TraceTexture ) ( int ground, float *vstart, float *vend );
|
||||
void ( *EV_StopAllSounds ) ( int entnum, int entchannel );
|
||||
void ( *EV_KillEvents ) ( int entnum, const char *eventname );
|
||||
} event_api_t;
|
||||
|
||||
extern event_api_t eventapi;
|
||||
|
||||
#endif
|
51
common/event_args.h
Normal file
51
common/event_args.h
Normal file
@ -0,0 +1,51 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#if !defined( EVENT_ARGSH )
|
||||
#define EVENT_ARGSH
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// Event was invoked with stated origin
|
||||
#define FEVENT_ORIGIN ( 1<<0 )
|
||||
|
||||
// Event was invoked with stated angles
|
||||
#define FEVENT_ANGLES ( 1<<1 )
|
||||
|
||||
typedef struct event_args_s
|
||||
{
|
||||
int flags;
|
||||
|
||||
// Transmitted
|
||||
int entindex;
|
||||
|
||||
float origin[3];
|
||||
float angles[3];
|
||||
float velocity[3];
|
||||
|
||||
int ducking;
|
||||
|
||||
float fparam1;
|
||||
float fparam2;
|
||||
|
||||
int iparam1;
|
||||
int iparam2;
|
||||
|
||||
int bparam1;
|
||||
int bparam2;
|
||||
} event_args_t;
|
||||
|
||||
#endif
|
||||
|
47
common/event_flags.h
Normal file
47
common/event_flags.h
Normal file
@ -0,0 +1,47 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#if !defined( EVENT_FLAGSH )
|
||||
#define EVENT_FLAGSH
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// Skip local host for event send.
|
||||
#define FEV_NOTHOST (1<<0)
|
||||
|
||||
// Send the event reliably. You must specify the origin and angles and use
|
||||
// PLAYBACK_EVENT_FULL for this to work correctly on the server for anything
|
||||
// that depends on the event origin/angles. I.e., the origin/angles are not
|
||||
// taken from the invoking edict for reliable events.
|
||||
#define FEV_RELIABLE (1<<1)
|
||||
|
||||
// Don't restrict to PAS/PVS, send this event to _everybody_ on the server ( useful for stopping CHAN_STATIC
|
||||
// sounds started by client event when client is not in PVS anymore ( hwguy in TFC e.g. ).
|
||||
#define FEV_GLOBAL (1<<2)
|
||||
|
||||
// If this client already has one of these events in its queue, just update the event instead of sending it as a duplicate
|
||||
//
|
||||
#define FEV_UPDATE (1<<3)
|
||||
|
||||
// Only send to entity specified as the invoker
|
||||
#define FEV_HOSTONLY (1<<4)
|
||||
|
||||
// Only send if the event was created on the server.
|
||||
#define FEV_SERVER (1<<5)
|
||||
|
||||
// Only issue event client side ( from shared code )
|
||||
#define FEV_CLIENT (1<<6)
|
||||
|
||||
#endif
|
41
common/exefuncs.h
Normal file
41
common/exefuncs.h
Normal file
@ -0,0 +1,41 @@
|
||||
// exefuncs.h
|
||||
#ifndef EXEFUNCS_H
|
||||
#define EXEFUNCS_H
|
||||
|
||||
// Engine hands this to DLLs for functionality callbacks
|
||||
typedef struct exefuncs_s
|
||||
{
|
||||
int fMMX;
|
||||
int iCPUMhz;
|
||||
void (*unused1)(void);
|
||||
void (*unused2)(void);
|
||||
void (*unused3)(void);
|
||||
void (*unused4)(void);
|
||||
void (*VID_ForceLockState)(int lk);
|
||||
int (*VID_ForceUnlockedAndReturnState)(void);
|
||||
void (*unused5)(void);
|
||||
void (*unused6)(void);
|
||||
void (*unused7)(void);
|
||||
void (*unused8)(void);
|
||||
void (*unused9)(void);
|
||||
void (*unused10)(void);
|
||||
void (*unused11)(void);
|
||||
void (*unused12)(void);
|
||||
void (*unused13)(void);
|
||||
void (*unused14)(void);
|
||||
void (*unused15)(void);
|
||||
void (*ErrorMessage)(int nLevel, const char *pszErrorMessage);
|
||||
void (*unused16)(void);
|
||||
void (*Sys_Printf)(char *fmt, ...);
|
||||
void (*unused17)(void);
|
||||
void (*unused18)(void);
|
||||
void (*unused19)(void);
|
||||
void (*unused20)(void);
|
||||
void (*unused21)(void);
|
||||
void (*unused22)(void);
|
||||
void (*unused23)(void);
|
||||
void (*unused24)(void);
|
||||
void (*unused25)(void);
|
||||
} exefuncs_t;
|
||||
|
||||
#endif
|
38
common/in_buttons.h
Normal file
38
common/in_buttons.h
Normal file
@ -0,0 +1,38 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#ifndef IN_BUTTONS_H
|
||||
#define IN_BUTTONS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define IN_ATTACK (1 << 0)
|
||||
#define IN_JUMP (1 << 1)
|
||||
#define IN_DUCK (1 << 2)
|
||||
#define IN_FORWARD (1 << 3)
|
||||
#define IN_BACK (1 << 4)
|
||||
#define IN_USE (1 << 5)
|
||||
#define IN_CANCEL (1 << 6)
|
||||
#define IN_LEFT (1 << 7)
|
||||
#define IN_RIGHT (1 << 8)
|
||||
#define IN_MOVELEFT (1 << 9)
|
||||
#define IN_MOVERIGHT (1 << 10)
|
||||
#define IN_ATTACK2 (1 << 11)
|
||||
#define IN_RUN (1 << 12)
|
||||
#define IN_RELOAD (1 << 13)
|
||||
#define IN_ALT1 (1 << 14)
|
||||
#define IN_SCORE (1 << 15) // Used by client.dll for when scoreboard is held down
|
||||
|
||||
#endif // IN_BUTTONS_H
|
146
common/mathlib.h
Normal file
146
common/mathlib.h
Normal file
@ -0,0 +1,146 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
// mathlib.h
|
||||
|
||||
typedef float vec_t;
|
||||
typedef vec_t vec3_t[3];
|
||||
typedef vec_t vec4_t[4]; // x,y,z,w
|
||||
typedef vec_t vec5_t[5];
|
||||
|
||||
typedef short vec_s_t;
|
||||
typedef vec_s_t vec3s_t[3];
|
||||
typedef vec_s_t vec4s_t[4]; // x,y,z,w
|
||||
typedef vec_s_t vec5s_t[5];
|
||||
|
||||
typedef int fixed4_t;
|
||||
typedef int fixed8_t;
|
||||
typedef int fixed16_t;
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
|
||||
#endif
|
||||
|
||||
struct mplane_s;
|
||||
|
||||
extern vec3_t vec3_origin;
|
||||
extern int nanmask;
|
||||
|
||||
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
|
||||
|
||||
#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
|
||||
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
|
||||
#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}
|
||||
#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}
|
||||
#define VectorClear(a) {(a)[0]=0.0;(a)[1]=0.0;(a)[2]=0.0;}
|
||||
|
||||
void VectorMA (const vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc);
|
||||
|
||||
vec_t _DotProduct (vec3_t v1, vec3_t v2);
|
||||
void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out);
|
||||
void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out);
|
||||
void _VectorCopy (vec3_t in, vec3_t out);
|
||||
|
||||
int VectorCompare (const vec3_t v1, const vec3_t v2);
|
||||
float Length (const vec3_t v);
|
||||
void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross);
|
||||
float VectorNormalize (vec3_t v); // returns vector length
|
||||
void VectorInverse (vec3_t v);
|
||||
void VectorScale (const vec3_t in, vec_t scale, vec3_t out);
|
||||
int Q_log2(int val);
|
||||
|
||||
void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]);
|
||||
void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]);
|
||||
|
||||
// Here are some "manual" INLINE routines for doing floating point to integer conversions
|
||||
extern short new_cw, old_cw;
|
||||
|
||||
typedef union DLONG {
|
||||
int i[2];
|
||||
double d;
|
||||
float f;
|
||||
} DLONG;
|
||||
|
||||
extern DLONG dlong;
|
||||
|
||||
#ifdef _WIN32
|
||||
void __inline set_fpu_cw(void)
|
||||
{
|
||||
_asm
|
||||
{ wait
|
||||
fnstcw old_cw
|
||||
wait
|
||||
mov ax, word ptr old_cw
|
||||
or ah, 0xc
|
||||
mov word ptr new_cw,ax
|
||||
fldcw new_cw
|
||||
}
|
||||
}
|
||||
|
||||
int __inline quick_ftol(float f)
|
||||
{
|
||||
_asm {
|
||||
// Assumes that we are already in chop mode, and only need a 32-bit int
|
||||
fld DWORD PTR f
|
||||
fistp DWORD PTR dlong
|
||||
}
|
||||
return dlong.i[0];
|
||||
}
|
||||
|
||||
void __inline restore_fpu_cw(void)
|
||||
{
|
||||
_asm fldcw old_cw
|
||||
}
|
||||
#else
|
||||
#define set_fpu_cw() /* */
|
||||
#define quick_ftol(f) ftol(f)
|
||||
#define restore_fpu_cw() /* */
|
||||
#endif
|
||||
|
||||
void FloorDivMod (double numer, double denom, int *quotient,
|
||||
int *rem);
|
||||
fixed16_t Invert24To16(fixed16_t val);
|
||||
int GreatestCommonDivisor (int i1, int i2);
|
||||
|
||||
void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
|
||||
void AngleVectorsTranspose (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
|
||||
#define AngleIVectors AngleVectorsTranspose
|
||||
|
||||
void AngleMatrix (const vec3_t angles, float (*matrix)[4] );
|
||||
void AngleIMatrix (const vec3_t angles, float (*matrix)[4] );
|
||||
void VectorTransform (const vec3_t in1, float in2[3][4], vec3_t out);
|
||||
|
||||
void VectorMatrix( vec3_t forward, vec3_t right, vec3_t up);
|
||||
void VectorAngles( const vec3_t forward, vec3_t angles );
|
||||
|
||||
int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
|
||||
float anglemod(float a);
|
||||
|
||||
|
||||
|
||||
#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \
|
||||
(((p)->type < 3)? \
|
||||
( \
|
||||
((p)->dist <= (emins)[(p)->type])? \
|
||||
1 \
|
||||
: \
|
||||
( \
|
||||
((p)->dist >= (emaxs)[(p)->type])?\
|
||||
2 \
|
||||
: \
|
||||
3 \
|
||||
) \
|
||||
) \
|
||||
: \
|
||||
BoxOnPlaneSide( (emins), (emaxs), (p)))
|
92
common/net_api.h
Normal file
92
common/net_api.h
Normal file
@ -0,0 +1,92 @@
|
||||
#if !defined( NET_APIH )
|
||||
#define NET_APIH
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if !defined ( NETADRH )
|
||||
#include "netadr.h"
|
||||
#endif
|
||||
|
||||
#define NETAPI_REQUEST_SERVERLIST ( 0 ) // Doesn't need a remote address
|
||||
#define NETAPI_REQUEST_PING ( 1 )
|
||||
#define NETAPI_REQUEST_RULES ( 2 )
|
||||
#define NETAPI_REQUEST_PLAYERS ( 3 )
|
||||
#define NETAPI_REQUEST_DETAILS ( 4 )
|
||||
|
||||
// Set this flag for things like broadcast requests, etc. where the engine should not
|
||||
// kill the request hook after receiving the first response
|
||||
#define FNETAPI_MULTIPLE_RESPONSE ( 1<<0 )
|
||||
|
||||
typedef void ( *net_api_response_func_t ) ( struct net_response_s *response );
|
||||
|
||||
#define NET_SUCCESS ( 0 )
|
||||
#define NET_ERROR_TIMEOUT ( 1<<0 )
|
||||
#define NET_ERROR_PROTO_UNSUPPORTED ( 1<<1 )
|
||||
#define NET_ERROR_UNDEFINED ( 1<<2 )
|
||||
|
||||
typedef struct net_adrlist_s
|
||||
{
|
||||
struct net_adrlist_s *next;
|
||||
netadr_t remote_address;
|
||||
} net_adrlist_t;
|
||||
|
||||
typedef struct net_response_s
|
||||
{
|
||||
// NET_SUCCESS or an error code
|
||||
int error;
|
||||
|
||||
// Context ID
|
||||
int context;
|
||||
// Type
|
||||
int type;
|
||||
|
||||
// Server that is responding to the request
|
||||
netadr_t remote_address;
|
||||
|
||||
// Response RTT ping time
|
||||
double ping;
|
||||
// Key/Value pair string ( separated by backlash \ characters )
|
||||
// WARNING: You must copy this buffer in the callback function, because it is freed
|
||||
// by the engine right after the call!!!!
|
||||
// ALSO: For NETAPI_REQUEST_SERVERLIST requests, this will be a pointer to a linked list of net_adrlist_t's
|
||||
void *response;
|
||||
} net_response_t;
|
||||
|
||||
typedef struct net_status_s
|
||||
{
|
||||
// Connected to remote server? 1 == yes, 0 otherwise
|
||||
int connected;
|
||||
// Client's IP address
|
||||
netadr_t local_address;
|
||||
// Address of remote server
|
||||
netadr_t remote_address;
|
||||
// Packet Loss ( as a percentage )
|
||||
int packet_loss;
|
||||
// Latency, in seconds ( multiply by 1000.0 to get milliseconds )
|
||||
double latency;
|
||||
// Connection time, in seconds
|
||||
double connection_time;
|
||||
// Rate setting ( for incoming data )
|
||||
double rate;
|
||||
} net_status_t;
|
||||
|
||||
typedef struct net_api_s
|
||||
{
|
||||
// APIs
|
||||
void ( *InitNetworking )( void );
|
||||
void ( *Status ) ( struct net_status_s *status );
|
||||
void ( *SendRequest) ( int context, int request, int flags, double timeout, struct netadr_s *remote_address, net_api_response_func_t response );
|
||||
void ( *CancelRequest ) ( int context );
|
||||
void ( *CancelAllRequests ) ( void );
|
||||
char *( *AdrToString ) ( struct netadr_s *a );
|
||||
int ( *CompareAdr ) ( struct netadr_s *a, struct netadr_s *b );
|
||||
int ( *StringToAdr ) ( char *s, struct netadr_s *a );
|
||||
const char *( *ValueForKey ) ( const char *s, const char *key );
|
||||
void ( *RemoveKey ) ( char *s, const char *key );
|
||||
void ( *SetValueForKey ) (char *s, const char *key, const char *value, int maxsize );
|
||||
} net_api_t;
|
||||
|
||||
extern net_api_t netapi;
|
||||
|
||||
#endif // NET_APIH
|
40
common/netadr.h
Normal file
40
common/netadr.h
Normal file
@ -0,0 +1,40 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
// netadr.h
|
||||
#ifndef NETADR_H
|
||||
#define NETADR_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NA_UNUSED,
|
||||
NA_LOOPBACK,
|
||||
NA_BROADCAST,
|
||||
NA_IP,
|
||||
NA_IPX,
|
||||
NA_BROADCAST_IPX
|
||||
} netadrtype_t;
|
||||
|
||||
typedef struct netadr_s
|
||||
{
|
||||
netadrtype_t type;
|
||||
unsigned char ip[4];
|
||||
unsigned char ipx[10];
|
||||
unsigned short port;
|
||||
} netadr_t;
|
||||
|
||||
#endif // NETADR_H
|
57
common/particledef.h
Normal file
57
common/particledef.h
Normal file
@ -0,0 +1,57 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#if !defined( PARTICLEDEFH )
|
||||
#define PARTICLEDEFH
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
pt_static,
|
||||
pt_grav,
|
||||
pt_slowgrav,
|
||||
pt_fire,
|
||||
pt_explode,
|
||||
pt_explode2,
|
||||
pt_blob,
|
||||
pt_blob2,
|
||||
pt_vox_slowgrav,
|
||||
pt_vox_grav,
|
||||
pt_clientcustom // Must have callback function specified
|
||||
} ptype_t;
|
||||
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
typedef struct particle_s
|
||||
{
|
||||
// driver-usable fields
|
||||
vec3_t org;
|
||||
short color;
|
||||
short packedColor;
|
||||
// drivers never touch the following fields
|
||||
struct particle_s *next;
|
||||
vec3_t vel;
|
||||
float ramp;
|
||||
float die;
|
||||
ptype_t type;
|
||||
void (*deathfunc)( struct particle_s *particle );
|
||||
|
||||
// for pt_clientcusttom, we'll call this function each frame
|
||||
void (*callback)( struct particle_s *particle, float frametime );
|
||||
|
||||
// for deathfunc, etc.
|
||||
unsigned char context;
|
||||
} particle_t;
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user