Progress on match logic, respawning, spectating, triggers...
This commit is contained in:
parent
dac1623b0d
commit
3bd3b7c95f
22 changed files with 629 additions and 135 deletions
|
@ -18,6 +18,13 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
=================
|
||||
CSQC_UpdateView
|
||||
|
||||
Entry point for drawing on the client
|
||||
=================
|
||||
*/
|
||||
void CSQC_UpdateView( float fWinWidth, float fWinHeight, float fGameFocus ) {
|
||||
vVideoResolution_x = fWinWidth;
|
||||
vVideoResolution_y = fWinHeight;
|
||||
|
@ -37,6 +44,13 @@ void CSQC_UpdateView( float fWinWidth, float fWinHeight, float fGameFocus ) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CSQC_UpdateViewLoading
|
||||
|
||||
Doesn't really do anything useful yet
|
||||
=================
|
||||
*/
|
||||
void CSQC_UpdateViewLoading( float fWinWidth, float fWinHeight, float fGameFocus ) {
|
||||
|
||||
}
|
||||
|
|
|
@ -18,10 +18,24 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
void CSQC_Ent_Update( float isnew ) {
|
||||
/*
|
||||
=================
|
||||
CSQC_Ent_Update
|
||||
|
||||
Called whenever an entity is sent manually via .SendFlags and so on
|
||||
=================
|
||||
*/
|
||||
void CSQC_Ent_Update( float fIsNew ) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CSQC_Ent_Remove
|
||||
|
||||
Self explanatory
|
||||
=================
|
||||
*/
|
||||
void CSQC_Ent_Remove( void ) {
|
||||
|
||||
}
|
||||
|
|
|
@ -18,21 +18,42 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
=================
|
||||
CSQC_ConsoleCommand_Init
|
||||
|
||||
Init all the cmds in one place
|
||||
=================
|
||||
*/
|
||||
void CSQC_ConsoleCommand_Init( void ) {
|
||||
registercommand( "vgui_buymenu" );
|
||||
registercommand( "vgui_teammenu" );
|
||||
registercommand( "use" );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CSQC_ConsoleCommand
|
||||
|
||||
Can interject cmds and create new ones
|
||||
=================
|
||||
*/
|
||||
float CSQC_ConsoleCommand( string sCMD ) {
|
||||
tokenize( sCMD );
|
||||
switch ( argv(0) )
|
||||
{
|
||||
case "vgui_buymenu":
|
||||
if( getstatf( 34 ) == TRUE ) {
|
||||
if( getstatf( STAT_BUYZONE ) == TRUE ) {
|
||||
fVGUI_Display = VGUI_BM_MAIN;
|
||||
}
|
||||
return TRUE;
|
||||
break;
|
||||
case "vgui_teammenu":
|
||||
if( getstatf( STAT_TEAM ) == 0 ) {
|
||||
fVGUI_Display = VGUI_TEAMSELECT;
|
||||
}
|
||||
return TRUE;
|
||||
break;
|
||||
case "use":
|
||||
sendevent( "PlayerUse", "" );
|
||||
return TRUE;
|
||||
|
@ -42,6 +63,13 @@ float CSQC_ConsoleCommand( string sCMD ) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CSQC_Parse_Event
|
||||
|
||||
Whenever we call a SVC_CGAMEPACKET on the SSQC, this is being run
|
||||
=================
|
||||
*/
|
||||
void CSQC_Parse_Event( void ) {
|
||||
float fHeader = readbyte();
|
||||
|
||||
|
@ -69,6 +97,13 @@ void CSQC_Parse_Event( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CSQC_InputEvent
|
||||
|
||||
Updates all our input related globals for use in other functions
|
||||
=================
|
||||
*/
|
||||
float CSQC_InputEvent( float fEventType, float fKey, float fCharacter, float fDeviceID ) {
|
||||
if ( fEventType == IE_KEYDOWN ) {
|
||||
if ( fKey == K_MOUSE1 ) {
|
||||
|
@ -95,9 +130,16 @@ float CSQC_InputEvent( float fEventType, float fKey, float fCharacter, float fDe
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CSQC_Input_Frame
|
||||
|
||||
Hijacks and controls what input globals are being sent to the server
|
||||
=================
|
||||
*/
|
||||
void CSQC_Input_Frame( void ) {
|
||||
// If we are inside a VGUI, don't let the client do stuff outside
|
||||
if ( fVGUI_Display != VGUI_NONE ) {
|
||||
if ( ( fVGUI_Display != VGUI_NONE ) ) {
|
||||
input_angles = '0 0 0';
|
||||
input_movevalues = '0 0 0';
|
||||
input_buttons = 0;
|
||||
|
|
|
@ -21,9 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define HUD_NUMFILE "sprites/640hud7.spr" // We'll precache this
|
||||
#define HUD_NUMFILE_LAYER "sprites/640hud7.spr_0.tga" // And only use the first frame for drawing (needs precache)
|
||||
|
||||
// Sigh
|
||||
#define NUMSIZE_X 0.09375
|
||||
#define NUMSIZE_Y 0.09765625
|
||||
|
||||
// Instead of calculating them on demand, just read the offsets here
|
||||
float vHUDNumPos[10] = {
|
||||
0,
|
||||
0.09375,
|
||||
|
@ -37,6 +39,7 @@ float vHUDNumPos[10] = {
|
|||
0.84375,
|
||||
};
|
||||
|
||||
// Ditto
|
||||
vector vHUDCalPos[10] = {
|
||||
'0 0 0',
|
||||
'0.09375 0.28125 0', // 50AE
|
||||
|
@ -50,17 +53,35 @@ vector vHUDCalPos[10] = {
|
|||
'0.46875 0.375 0', // 57MM
|
||||
};
|
||||
|
||||
// Wrapper that draws an individual number
|
||||
/*
|
||||
=================
|
||||
HUD_DrawRedNumber
|
||||
|
||||
Draws a normal number
|
||||
=================
|
||||
*/
|
||||
void HUD_DrawNumber( int iNumber, vector vPos, float fAlpha ) {
|
||||
drawsubpic( vPos, '24 25 0', HUD_NUMFILE_LAYER, [ vHUDNumPos[ iNumber ], 0], [ NUMSIZE_X, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, fAlpha, DRAWFLAG_ADDITIVE );
|
||||
}
|
||||
|
||||
// Draws a red number
|
||||
/*
|
||||
=================
|
||||
HUD_DrawRedNumber
|
||||
|
||||
Draws a red number
|
||||
=================
|
||||
*/
|
||||
void HUD_DrawRedNumber( int iNumber, vector vPos, float fAlpha ) {
|
||||
drawsubpic( vPos, '24 25 0', HUD_NUMFILE_LAYER, [ vHUDNumPos[ iNumber ], 0], [ NUMSIZE_X, NUMSIZE_Y ], '1 0 0', fAlpha, DRAWFLAG_ADDITIVE );
|
||||
}
|
||||
|
||||
// Draws numerals quickly with a maximum length of 3 - e.g. for health, armor etc.
|
||||
/*
|
||||
=================
|
||||
HUD_DrawNums
|
||||
|
||||
Draws numerals quickly for health, armor etc.
|
||||
=================
|
||||
*/
|
||||
void HUD_DrawNums( float fNumber, vector vPos ) {
|
||||
int iNumber = fNumber;
|
||||
if ( iNumber > 0 ) {
|
||||
|
@ -74,22 +95,43 @@ void HUD_DrawNums( float fNumber, vector vPos ) {
|
|||
}
|
||||
}
|
||||
|
||||
// Called every frame
|
||||
void HUD_Draw( void ) {
|
||||
if( getplayerkeyvalue( player_localnum, "*spectator" ) == "1" ) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
=================
|
||||
HUD_DrawHealth
|
||||
|
||||
Draw the current amount of health
|
||||
=================
|
||||
*/
|
||||
void HUD_DrawHealth( void ) {
|
||||
|
||||
// Health
|
||||
vector vHealthPos = [ 16, vVideoResolution_y - 42 ];
|
||||
drawsubpic( vHealthPos, '24 24 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 2, NUMSIZE_Y], [ NUMSIZE_X, NUMSIZE_X ], VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE );
|
||||
HUD_DrawNums( getstatf( STAT_HEALTH ), vHealthPos + '72 0' );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
HUD_DrawArmor
|
||||
|
||||
Draw the current amount of Kevlar
|
||||
=================
|
||||
*/
|
||||
void HUD_DrawArmor( void ) {
|
||||
|
||||
// Armor
|
||||
vector vArmorPos = [ 112, vVideoResolution_y - 42 ];
|
||||
drawsubpic( vArmorPos, '24 24 0', HUD_NUMFILE_LAYER, [ 0, NUMSIZE_Y], [ NUMSIZE_X, NUMSIZE_X ], VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE );
|
||||
HUD_DrawNums( getstatf( STAT_ARMOR ), vArmorPos + '72 0' );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
HUD_DrawIcons
|
||||
|
||||
Draw icons such as hostage, bomb and buyzones
|
||||
=================
|
||||
*/
|
||||
void HUD_DrawIcons( void ) {
|
||||
// BuyZone Icon
|
||||
if( getstatf( STAT_BUYZONE ) == TRUE ) {
|
||||
vector vBuyIconPos = [ 16, ( vVideoResolution_y / 2 ) - 12 ];
|
||||
|
@ -107,8 +149,16 @@ void HUD_Draw( void ) {
|
|||
vector vBIconPos = [ 16, ( vVideoResolution_y / 2 ) + 48 ];
|
||||
drawsubpic( vBIconPos, '32 32 0', HUD_NUMFILE_LAYER, [ 0, 0.125 * 5 - 0.046875], [ 0.125, 0.125 ], '0 1 0', 1, DRAWFLAG_ADDITIVE );
|
||||
}
|
||||
}
|
||||
|
||||
// The Timer
|
||||
/*
|
||||
=================
|
||||
HUD_DrawTimer
|
||||
|
||||
Draws the roundtime at the bottom of the screen (always visible)
|
||||
=================
|
||||
*/
|
||||
void HUD_DrawTimer( void ) {
|
||||
int iMinutes, iSeconds, iTens, iUnits;
|
||||
vector vTimePos = [ ( vVideoResolution_x / 2 ) - 60, vVideoResolution_y - 42 ];
|
||||
|
||||
|
@ -129,7 +179,7 @@ void HUD_Draw( void ) {
|
|||
iUnits = iSeconds - 10*iTens;
|
||||
}
|
||||
|
||||
// Timer: Flashing red numbers
|
||||
// Flashing red numbers
|
||||
if ( ( iMinutes == 0 ) && ( iTens <= 1 ) ) {
|
||||
float fAlpha = fabs( sin( time * 20 ) );
|
||||
HUD_DrawRedNumber( iMinutes, vTimePos + '48 0 0', fAlpha);
|
||||
|
@ -147,14 +197,30 @@ void HUD_Draw( void ) {
|
|||
HUD_DrawNumber( iUnits, vTimePos + '94 0 0', 1);
|
||||
drawsubpic( vTimePos, '24 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 6, NUMSIZE_Y * 3], [ NUMSIZE_X, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE );
|
||||
}
|
||||
}
|
||||
|
||||
// The money
|
||||
/*
|
||||
=================
|
||||
HUD_DrawMoney
|
||||
|
||||
Draws the amount of money (0-16000) with an icon to the screen
|
||||
=================
|
||||
*/
|
||||
void HUD_DrawMoney( void ) {
|
||||
vector vMoneyPos = [ vVideoResolution_x - 160, vVideoResolution_y - 72 ];
|
||||
drawsubpic( vMoneyPos, '18 25 0', HUD_NUMFILE_LAYER, [ NUMSIZE_X * 8, NUMSIZE_Y * 1], [ NUMSIZE_X * 0.75, NUMSIZE_Y ], VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE );
|
||||
vMoneyPos_x += ( 24 * 5 );
|
||||
HUD_DrawNums( getstatf( STAT_MONEY ), vMoneyPos );
|
||||
}
|
||||
|
||||
// Ammo
|
||||
/*
|
||||
=================
|
||||
HUD_DrawAmmo
|
||||
|
||||
Draws the current clip, the amount of ammo for the caliber and a matching caliber icon
|
||||
=================
|
||||
*/
|
||||
void HUD_DrawAmmo( void ) {
|
||||
vector vAmmoClipPos = [ vVideoResolution_x - 136, vVideoResolution_y - 42 ];
|
||||
HUD_DrawNums( getstatf( STAT_CURRENT_CLIP ), vAmmoClipPos );
|
||||
vector vAmmoCalPos = [ vVideoResolution_x - 64, vVideoResolution_y - 42 ];
|
||||
|
@ -163,3 +229,25 @@ void HUD_Draw( void ) {
|
|||
// Caliber icon
|
||||
drawsubpic( vVideoResolution - '42 42 0', '24 24 0', HUD_NUMFILE_LAYER, vHUDCalPos[ wptTable[ getstatf( STAT_ACTIVEWEAPON ) ].iCaliber ], [ NUMSIZE_X, NUMSIZE_X ], VGUI_WINDOW_FGCOLOR, 1, DRAWFLAG_ADDITIVE );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
HUD_Draw
|
||||
|
||||
Called every frame in Draw.c
|
||||
=================
|
||||
*/
|
||||
void HUD_Draw( void ) {
|
||||
|
||||
HUD_DrawTimer();
|
||||
|
||||
if( getplayerkeyvalue( player_localnum, "*spectator" ) == "1" ) {
|
||||
return;
|
||||
}
|
||||
|
||||
HUD_DrawHealth();
|
||||
HUD_DrawArmor();
|
||||
HUD_DrawIcons();
|
||||
HUD_DrawMoney();
|
||||
HUD_DrawAmmo();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,13 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
=================
|
||||
CSQC_Init
|
||||
|
||||
Comparable to worldspawn in SSQC in that it's mostly used for precaches
|
||||
=================
|
||||
*/
|
||||
void CSQC_Init(float apilevel, string enginename, float engineversion) {
|
||||
precache_model( HUD_NUMFILE );
|
||||
|
||||
|
@ -29,10 +36,24 @@ void CSQC_Init(float apilevel, string enginename, float engineversion) {
|
|||
CSQC_VGUI_Init();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CSQC_WorldLoaded
|
||||
|
||||
Whenever the world is fully initialized...
|
||||
=================
|
||||
*/
|
||||
void CSQC_WorldLoaded( void ) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CSQC_Shutdown
|
||||
|
||||
Incase you need to free something
|
||||
=================
|
||||
*/
|
||||
void CSQC_Shutdown( void ) {
|
||||
|
||||
}
|
||||
|
|
|
@ -18,10 +18,17 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
float CSQC_Event_Sound( float entnum, float channel, string soundname, float vol, float attenuation, vector pos, float pitchmod, float flags ) {
|
||||
/*float CSQC_Event_Sound( float entnum, float channel, string soundname, float vol, float attenuation, vector pos, float pitchmod, float flags ) {
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
/*
|
||||
=================
|
||||
Sound_Delayed
|
||||
|
||||
Now you can call sounds in advance
|
||||
=================
|
||||
*/
|
||||
void Sound_Delayed( string sSample, float fVol, float fDelay ) {
|
||||
static void Sound_Delayed_PlayBack( void ) {
|
||||
print( sprintf( "[SOUND] Playing Event %s\n", self.sSoundSample ) );
|
||||
|
|
|
@ -35,7 +35,14 @@ vguiwindow_t vguiMenus[11] = {
|
|||
{ "Equipment", VGUI_BuyMenu_Equipment }
|
||||
};
|
||||
|
||||
// Called every frame
|
||||
/*
|
||||
=================
|
||||
CSQC_VGUI_Draw
|
||||
|
||||
This is the entry point for OpenCS own VGUI implementation
|
||||
Run every frame
|
||||
=================
|
||||
*/
|
||||
void CSQC_VGUI_Draw( void ) {
|
||||
if ( fVGUI_Display == VGUI_NONE ) {
|
||||
setcursormode( FALSE );
|
||||
|
@ -53,10 +60,14 @@ void CSQC_VGUI_Draw( void ) {
|
|||
vguiMenus[ fVGUI_Display - 1 ].vDraw( vVGUIWindowPos );
|
||||
}
|
||||
|
||||
// Called by CSQC_Init
|
||||
/*
|
||||
=================
|
||||
CSQC_VGUI_Init
|
||||
|
||||
Initialize all there is
|
||||
=================
|
||||
*/
|
||||
void CSQC_VGUI_Init( void ) {
|
||||
// We start on the MOTD, always
|
||||
fVGUI_Display = VGUI_MOTD;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
// Stuff that applies to all codebases
|
||||
enum {
|
||||
TEAM_T = 1,
|
||||
TEAM_CT
|
||||
TEAM_CT,
|
||||
TEAM_VIP
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -36,7 +37,9 @@ enum {
|
|||
STAT_SLOT_GRENADE,
|
||||
STAT_CURRENT_CLIP,
|
||||
STAT_CURRENT_CALIBER,
|
||||
STAT_TEAM
|
||||
STAT_TEAM,
|
||||
STAT_WON_T,
|
||||
STAT_WON_CT
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
|
@ -18,12 +18,35 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
void ambient_generic_use( void ) {
|
||||
sound( self, CHAN_VOICE, self.message, 1, self.style );
|
||||
/*
|
||||
ambient_generic
|
||||
|
||||
The ambient_generic allows you to play a specific sound.
|
||||
|
||||
Attributes:
|
||||
Name (targetname) - Property used to identify entities.
|
||||
WAV name (message) - This is the path/filename of the .wav file.
|
||||
Volume (health) - Volume of the sound. Range: 0-10.
|
||||
Dynamic Presets (preset) - Various effects that can be applied to the sound:
|
||||
|
||||
Flags:
|
||||
Play Everywhere (1) - Sound will be heard in the entire level.
|
||||
Small Radius (2) - Sound range is about 800 units at max volume.
|
||||
Medium Radius (4) - Sound range is about 1250 units at max volume.
|
||||
Large Radius (8) - Sound range is about 2000 units at max volume.
|
||||
Start Silent (16) - Checking this means the entity must be triggered to work.
|
||||
Not Toggled (32) - Older FGDs show this as Not Looped.
|
||||
Makes the entity interpret each call as "turn on" instead of "toggle state".
|
||||
Must be left unchecked for looping sound files.
|
||||
Note that actual looping depends purely on cue points defined in the .wav file (see notes).
|
||||
*/
|
||||
void ambient_generic( void ) {
|
||||
static void ambient_generic_use( void ) {
|
||||
sound( self, CHAN_VOICE, self.message, self.health, self.style );
|
||||
}
|
||||
|
||||
void ambient_generic( void ) {
|
||||
precache_sound( self.message );
|
||||
self.health = self.health / 10;
|
||||
|
||||
if ( self.spawnflags & 1 ) {
|
||||
self.style = ATTN_NONE;
|
||||
|
@ -38,9 +61,9 @@ void ambient_generic( void ) {
|
|||
}
|
||||
|
||||
if ( self.spawnflags & 32 ) {
|
||||
sound( self, CHAN_VOICE, self.message, 1, self.style );
|
||||
sound( self, CHAN_VOICE, self.message, self.health, self.style );
|
||||
} else {
|
||||
ambientsound( self.origin, self.message, 1, self.style );
|
||||
ambientsound( self.origin, self.message, self.health, self.style );
|
||||
}
|
||||
|
||||
self.vUse = ambient_generic_use;
|
||||
|
|
|
@ -25,8 +25,12 @@ void ClientConnect( void ) {}
|
|||
|
||||
void ClientDisconnect( void ) {
|
||||
// We were part of the session
|
||||
if( self.fInGame == TRUE ) {
|
||||
fInGamePlayers--;
|
||||
if( self.iInGame == TRUE ) {
|
||||
if ( self.team == TEAM_T ) {
|
||||
iInGamePlayers_T--;
|
||||
} else if ( self.team == TEAM_CT ) {
|
||||
iInGamePlayers_CT--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,13 +46,6 @@ void PutClientInServer( void ) {
|
|||
entity eSpawn;
|
||||
eSpawn = find (world, classname, "trigger_camera");
|
||||
|
||||
self.classname = "spectator";
|
||||
self.health = self.max_health = 999;
|
||||
self.takedamage = DAMAGE_NO;
|
||||
self.solid = SOLID_NOT;
|
||||
self.movetype = MOVETYPE_FLY;
|
||||
self.flags = FL_CLIENT;
|
||||
|
||||
self.origin = eSpawn.origin + '0 0 1';
|
||||
|
||||
// Rotate camera towards a target
|
||||
|
@ -61,13 +58,11 @@ void PutClientInServer( void ) {
|
|||
}
|
||||
|
||||
self.fixangle = TRUE;
|
||||
self.classname = "spectator";
|
||||
Spawn_MakeSpectator();
|
||||
|
||||
self.model = 0;
|
||||
setsize (self, '-16 -16 -16', '16 16 16');
|
||||
|
||||
self.view_ofs = self.velocity = '0 0 0';
|
||||
|
||||
forceinfokey( self, "*spectator", "1" ); // Make sure we are known as a spectator
|
||||
// Because we don't want to reset these when we die
|
||||
self.fMoney = cvar( "mp_startmoney" );
|
||||
}
|
||||
|
||||
void SV_RunClientCommand( void ) {
|
||||
|
@ -77,7 +72,7 @@ void SV_RunClientCommand( void ) {
|
|||
self.fInBuyZone = FALSE;
|
||||
self.fInHostageZone = FALSE;
|
||||
|
||||
if( fGameState != GAME_ACTIVE ) {
|
||||
if( fGameState == GAME_FREEZE && self.team != 0 ) {
|
||||
input_movevalues = '0 0 0';
|
||||
input_buttons = 0;
|
||||
input_impulse = 0;
|
||||
|
|
|
@ -31,10 +31,16 @@ float EFFECT_BLOOD;
|
|||
.float fInBombZone;
|
||||
.float fMoney;
|
||||
.float fStepTime;
|
||||
.int iInGame;
|
||||
|
||||
// Match specific fields
|
||||
int iWon_T;
|
||||
int iWon_CT;
|
||||
int iInGamePlayers_T;
|
||||
int iInGamePlayers_CT;
|
||||
int fOldInGamePlayers;
|
||||
|
||||
|
||||
.float fInGame;
|
||||
float fInGamePlayers;
|
||||
float fOldInGamePlayers;
|
||||
float fGameState;
|
||||
float fGameTime;
|
||||
|
||||
|
@ -51,6 +57,8 @@ float fGameTime;
|
|||
int iHostagesMax;
|
||||
int iHostagesRescued;
|
||||
|
||||
int iBombZones;
|
||||
|
||||
// Generic entity fields
|
||||
.int iUsable;
|
||||
.int iBleeds;
|
||||
|
@ -80,6 +88,10 @@ string sCSPlayers[9] = {
|
|||
"models/player/gign/gign.mdl"
|
||||
};
|
||||
|
||||
void Timer_Begin( float fTime, float fMode);
|
||||
void Spawn_RespawnClient( int iTeam );
|
||||
void Spawn_CreateClient( int iTeam );
|
||||
void Spawn_MakeSpectator( void );
|
||||
void Client_SendEvent( entity eClient, float fEVType );
|
||||
|
||||
void OpenCSGunBase_AccuracyCalc( void );
|
||||
|
|
|
@ -43,6 +43,8 @@ void Entities_RenderSetup( void ) {
|
|||
// GoldSrc-Rendermode support
|
||||
if ( self.rendermode != RENDERMODE_NORMAL ) {
|
||||
self.alpha = ( self.renderamt / 255 );
|
||||
self.colormod = self.rendercolor;
|
||||
|
||||
if( self.alpha == 0 ) {
|
||||
self.alpha = 0.0001;
|
||||
}
|
||||
|
|
|
@ -18,31 +18,78 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
void cycler_sprite( void ) {
|
||||
static void cycler_sprite_use( void ) {
|
||||
remove( self );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
cycler_sprite
|
||||
|
||||
This entity lets you display and cycle through the animation of a sprite (or a model, engine doesn't care).
|
||||
|
||||
Attributes:
|
||||
Name (targetname) - Property used to identify entities.
|
||||
Pitch Yaw Roll (angles) - Sets the pitch (up / down), yaw (left / right) and roll (bank) respectively. The compass in WorldCraft / Hammer corresponds to Yaw. The settings are not always (or not all) used.
|
||||
Sprite (model) - A sprite must be specified here (sprites/spritename.spr).
|
||||
Frames per second (framerate) - Framerate the sprite will run at if animated.
|
||||
=================
|
||||
*/
|
||||
void cycler_sprite( void ) {
|
||||
precache_model( self.model );
|
||||
setmodel( self, self.model );
|
||||
self.vUse = cycler_sprite_use;
|
||||
|
||||
Entities_RenderSetup();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
env_render
|
||||
|
||||
This entity allows you to change the rendering properties
|
||||
of most of the visible entities in the game (monsters, func_walls etc.), while the map is running.
|
||||
The four render properties of the env_render will be copied to its target.
|
||||
|
||||
Attributes:
|
||||
Name (targetname) - Property used to identify entities.
|
||||
Target (target) - When an entity is activated, it triggers the entity with the name specified by Target.
|
||||
|
||||
Flags:
|
||||
No Renderfx (1) - Render FX will not be copied.
|
||||
No Renderamt (2) - Render Amount will not be copied.
|
||||
No Rendermode (4) - Render Mode will not be copied.
|
||||
No Rendercolor (8) - Render Color will not be copied.
|
||||
|
||||
Notes:
|
||||
Use this entity to fake situations that would be impossible for the game engine,
|
||||
such as apparently binding multiple entities together (e.g. a moving doorhandle on a rotating door).
|
||||
With a bit of careful setup, it is possible to let the the doorhandle move first,
|
||||
then become invisible, then let the door move (with a static doorhandle attached).
|
||||
=================
|
||||
*/
|
||||
|
||||
#define SF_NORENDERFX 1
|
||||
#define SF_NORENDERAMT 2
|
||||
#define SF_NORENDERMODE 4
|
||||
#define SF_NORENDERCOLOR 8
|
||||
|
||||
void env_render( void ) {
|
||||
static void env_render_use( void ) {
|
||||
entity eFind = findchain( targetname, self.target );
|
||||
|
||||
while ( eFind ) {
|
||||
entity eOldSelf = self;
|
||||
|
||||
if ( !( self.spawnflags & SF_NORENDERMODE ) ) {
|
||||
eFind.rendermode = self.rendermode;
|
||||
eFind.rendercolor = self.rendercolor;
|
||||
}
|
||||
if ( !( self.spawnflags & SF_NORENDERCOLOR ) ) {
|
||||
eFind.colormod = self.colormod;
|
||||
}
|
||||
eFind.alpha = self.alpha;
|
||||
eFind = eFind.chain;
|
||||
}
|
||||
}
|
||||
|
||||
self.colormod = self.rendercolor;
|
||||
|
||||
Entities_RenderSetup();
|
||||
self.vUse = env_render_use;
|
||||
}
|
||||
|
|
|
@ -43,4 +43,6 @@ void func_bomb_target( void ) {
|
|||
setmodel( self, self.model );
|
||||
self.model = 0;
|
||||
self.touch = func_bomb_target_touch;
|
||||
|
||||
iBombZones++;
|
||||
}
|
||||
|
|
|
@ -22,28 +22,29 @@ void main( void ) {}
|
|||
void SetNewParms( void ) {}
|
||||
void SetChangeParms( void ) {}
|
||||
|
||||
|
||||
// Run every frame... by world?
|
||||
void StartFrame( void ) {
|
||||
// See if the player count has changed noticeably
|
||||
if ( fInGamePlayers > fOldInGamePlayers ) {
|
||||
// bprint( "Starting OpenCS Match...\n" );
|
||||
|
||||
// Global amount of players etc.
|
||||
int iInGamePlayers = ( iInGamePlayers_T + iInGamePlayers_CT );
|
||||
|
||||
// See if the player count has changed
|
||||
if ( iInGamePlayers > fOldInGamePlayers && fGameState == GAME_INACTIVE ) {
|
||||
bprint( "Starting Match...\n" );
|
||||
Timer_Begin( cvar( "mp_freezetime" ), GAME_FREEZE );
|
||||
|
||||
fOldInGamePlayers = fInGamePlayers;
|
||||
fOldInGamePlayers = iInGamePlayers;
|
||||
} else {
|
||||
// No players? Don't bother updating the Timer
|
||||
if ( fInGamePlayers == 0 ) {
|
||||
if ( iInGamePlayers == 0 ) {
|
||||
fGameState = GAME_INACTIVE;
|
||||
fGameTime = 0;
|
||||
} else {
|
||||
Timer_Update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// The map... entity.
|
||||
void worldspawn( void ) {
|
||||
precache_model (sCSPlayers[1]);
|
||||
precache_model (sCSPlayers[2]);
|
||||
|
@ -62,6 +63,9 @@ void worldspawn( void ) {
|
|||
precache_sound( "radio/locknload.wav" );
|
||||
precache_sound( "radio/rescued.wav" );
|
||||
precache_sound( "radio/hosdown.wav" );
|
||||
precache_sound( "radio/terwin.wav" );
|
||||
precache_sound( "radio/ctwin.wav" );
|
||||
precache_sound( "radio/rounddraw.wav" );
|
||||
|
||||
precache_sound( "hostage/hos1.wav" );
|
||||
precache_sound( "hostage/hos2.wav" );
|
||||
|
@ -227,10 +231,11 @@ void worldspawn( void ) {
|
|||
precache_sound( "weapons/xm1014-1.wav" );
|
||||
precache_sound( "weapons/zoom.wav" );
|
||||
|
||||
// TODO: Merge these into a single field
|
||||
// TODO: Merge these into a single field?
|
||||
clientstat( STAT_BUYZONE, EV_FLOAT, fInBuyZone );
|
||||
clientstat( STAT_HOSTAGEZONE, EV_FLOAT, fInHostageZone );
|
||||
clientstat( STAT_BOMBZONE, EV_FLOAT, fInBombZone );
|
||||
|
||||
clientstat( STAT_MONEY, EV_FLOAT, fMoney );
|
||||
clientstat( STAT_SLOT_MELEE, EV_INTEGER, iSlotMelee );
|
||||
clientstat( STAT_SLOT_PRIMARY, EV_INTEGER, iSlotPrimary );
|
||||
|
@ -240,5 +245,7 @@ void worldspawn( void ) {
|
|||
clientstat( STAT_CURRENT_CALIBER, EV_INTEGER, iCurrentCaliber );
|
||||
clientstat( STAT_TEAM, EV_INTEGER, team );
|
||||
pointerstat( STAT_GAMETIME, EV_FLOAT, &fGameTime );
|
||||
pointerstat( STAT_WON_T, EV_INTEGER, &iWon_T );
|
||||
pointerstat( STAT_WON_CT, EV_INTEGER, &iWon_CT );
|
||||
}
|
||||
|
||||
|
|
51
Source/Server/Player.c
Normal file
51
Source/Server/Player.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
OpenCS Project
|
||||
Copyright (C) 2015 Marco "eukara" Hladik
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
void Player_Pain( void ) {
|
||||
|
||||
}
|
||||
|
||||
void Player_Death( void ) {
|
||||
|
||||
// Drop a corpse
|
||||
entity eCorpse = spawn();
|
||||
setorigin( eCorpse, self.origin );
|
||||
setmodel( eCorpse, self.model );
|
||||
eCorpse.angles = self.angles;
|
||||
eCorpse.frame = 93; // TODO: Pick the right frame
|
||||
|
||||
Spawn_MakeSpectator();
|
||||
|
||||
if ( self.team == TEAM_T ) {
|
||||
iInGamePlayers_T--;
|
||||
|
||||
if ( iInGamePlayers_T == 0 ) {
|
||||
Rules_RoundOver( TEAM_CT );
|
||||
}
|
||||
} else if ( self.team == TEAM_CT ) {
|
||||
iInGamePlayers_CT--;
|
||||
|
||||
if ( iInGamePlayers_CT == 0 ) {
|
||||
Rules_RoundOver( TEAM_T );
|
||||
}
|
||||
} else if ( self.team == TEAM_VIP ) {
|
||||
// TODO: Finish me
|
||||
}
|
||||
}
|
68
Source/Server/Rules.c
Normal file
68
Source/Server/Rules.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
OpenCS Project
|
||||
Copyright (C) 2015 Marco "eukara" Hladik
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// Loop through all players and respawn them
|
||||
void Rules_Restart( void ) {
|
||||
//localcmd( "restart_ents" );
|
||||
|
||||
entity eFind = findchain( classname, "player" );
|
||||
|
||||
while ( eFind ) {
|
||||
entity eOldSelf = self;
|
||||
self = eFind;
|
||||
|
||||
if ( self.health > 0 ) {
|
||||
Spawn_RespawnClient( self.team );
|
||||
} else {
|
||||
Spawn_CreateClient( self.team );
|
||||
}
|
||||
|
||||
self = eOldSelf;
|
||||
eFind = eFind.chain;
|
||||
}
|
||||
|
||||
Timer_Begin( cvar( "mp_freezetime" ), GAME_FREEZE );
|
||||
}
|
||||
|
||||
// This can happen whenever an objective is complete or time is up
|
||||
void Rules_RoundOver( int iTeamWon ) {
|
||||
if ( iTeamWon == TEAM_T ) {
|
||||
sound( world, CHAN_VOICE, "radio/terwin.wav", 1.0, ATTN_NONE );
|
||||
iWon_T++;
|
||||
} else if ( iTeamWon == TEAM_CT ) {
|
||||
sound( world, CHAN_VOICE, "radio/ctwin.wav", 1.0, ATTN_NONE );
|
||||
iWon_CT++;
|
||||
} else {
|
||||
sound( world, CHAN_VOICE, "radio/rounddraw.wav", 1.0, ATTN_NONE );
|
||||
}
|
||||
|
||||
Timer_Begin( 5, GAME_END); // Round is over, 5 seconds til a new round starts
|
||||
}
|
||||
|
||||
// Whenever mp_roundtime was being counted down to 0
|
||||
void Rules_TimeOver( void ) {
|
||||
if ( iBombZones > 0 ) {
|
||||
Rules_RoundOver( TEAM_CT );
|
||||
} else if ( iHostagesMax > 0 ) {
|
||||
Rules_RoundOver( TEAM_T );
|
||||
} else {
|
||||
Rules_RoundOver( 0 );
|
||||
}
|
||||
}
|
|
@ -18,65 +18,127 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
void Spawn_GameClient( float fTeam ) {
|
||||
entity eSpawn;
|
||||
entity eLastTSpawn;
|
||||
entity eLastCTSpawn;
|
||||
entity Spawn_FindSpawnPoint( int iTeam ) {
|
||||
entity eSpot, eLastSpawn;
|
||||
entity eThing;
|
||||
int iCount;
|
||||
string sClassname;
|
||||
|
||||
if( self.fInGame == FALSE ) {
|
||||
self.fInGame = TRUE;
|
||||
fInGamePlayers++;
|
||||
}
|
||||
|
||||
// What team are we on - 0= Spectator, < 5 Terrorists
|
||||
if( fTeam == 0 ) {
|
||||
PutClientInServer();
|
||||
return;
|
||||
} else if( fTeam < 5 ) {
|
||||
eSpawn = find ( world, classname, "info_player_deathmatch" );
|
||||
self.team = TEAM_T;
|
||||
|
||||
// TODO: Move this away from here
|
||||
Weapon_AddItem( WEAPON_GLOCK18 );
|
||||
Weapon_GiveAmmo( WEAPON_GLOCK18, 40 );
|
||||
if ( iTeam == TEAM_T ) {
|
||||
sClassname = "info_player_deathmatch";
|
||||
eSpot = eLastSpawn = eLastTSpawn;
|
||||
} else {
|
||||
eSpawn = find ( world, classname, "info_player_start" );
|
||||
self.team = TEAM_CT;
|
||||
|
||||
// TODO: Move this away from here
|
||||
Weapon_AddItem( WEAPON_USP45 );
|
||||
Weapon_GiveAmmo( WEAPON_USP45, 24 );
|
||||
|
||||
sClassname = "info_player_start";
|
||||
eSpot = eLastSpawn = eLastCTSpawn;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
eSpot = find(eSpot, classname, sClassname);
|
||||
|
||||
if (eSpot != world) {
|
||||
if (eSpot == eLastSpawn)
|
||||
return eLastSpawn;
|
||||
iCount = 0;
|
||||
eThing = findradius(eSpot.origin, 32);
|
||||
while(eThing) {
|
||||
if (eThing.classname == "player")
|
||||
iCount++;
|
||||
eThing = eThing.chain;
|
||||
}
|
||||
if (iCount == 0) {
|
||||
eLastSpawn = eSpot;
|
||||
return eSpot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return eSpot;
|
||||
}
|
||||
|
||||
void Spawn_RespawnClient( int iTeam ) {
|
||||
entity eSpawn;
|
||||
forceinfokey( self, "*spectator", "0" ); // Make sure we are known as a spectator
|
||||
eSpawn = Spawn_FindSpawnPoint( self.team );
|
||||
|
||||
self.classname = "player";
|
||||
self.health = self.max_health = 100;
|
||||
self.takedamage = DAMAGE_AIM;
|
||||
self.takedamage = DAMAGE_YES;
|
||||
self.solid = SOLID_SLIDEBOX;
|
||||
self.movetype = MOVETYPE_WALK;
|
||||
self.flags = FL_CLIENT;
|
||||
self.vPain = Player_Pain;
|
||||
self.vDeath = Player_Death;
|
||||
|
||||
self.origin = eSpawn.origin;
|
||||
self.angles = eSpawn.angles;
|
||||
self.fixangle = TRUE;
|
||||
|
||||
// Get the player-model from Defs.h's list
|
||||
setmodel( self, sCSPlayers[ fTeam ] );
|
||||
setmodel( self, sCSPlayers[ iTeam ] );
|
||||
setsize( self, VEC_HULL_MIN, VEC_HULL_MAX );
|
||||
|
||||
self.view_ofs = '0 0 24';
|
||||
self.velocity = '0 0 0';
|
||||
|
||||
self.frame = 1; // Idle frame
|
||||
}
|
||||
|
||||
// Set the fields
|
||||
self.fMoney = cvar( "mp_startmoney" );
|
||||
void Spawn_CreateClient( int iTeam ) {
|
||||
// What team are we on - 0= Spectator, < 5 Terrorists, CT rest
|
||||
if( iTeam == 0 ) {
|
||||
PutClientInServer();
|
||||
return;
|
||||
} else if( iTeam < 5 ) {
|
||||
self.team = TEAM_T;
|
||||
iInGamePlayers_T++;
|
||||
|
||||
Weapon_AddItem( WEAPON_GLOCK18 );
|
||||
Weapon_GiveAmmo( WEAPON_GLOCK18, 40 );
|
||||
} else {
|
||||
self.team = TEAM_CT;
|
||||
iInGamePlayers_CT++;
|
||||
|
||||
Weapon_AddItem( WEAPON_USP45 );
|
||||
Weapon_GiveAmmo( WEAPON_USP45, 24 );
|
||||
|
||||
}
|
||||
|
||||
if( self.iInGame == FALSE ) {
|
||||
self.iInGame = TRUE;
|
||||
}
|
||||
|
||||
Spawn_RespawnClient( self.team );
|
||||
self.fAttackFinished = time + 1;
|
||||
}
|
||||
|
||||
// This is called on connect and whenever a player dies
|
||||
void Spawn_MakeSpectator( void ) {
|
||||
self.health = 0;
|
||||
self.takedamage = DAMAGE_NO;
|
||||
self.solid = SOLID_NOT;
|
||||
self.movetype = MOVETYPE_NOCLIP;
|
||||
self.flags = FL_CLIENT;
|
||||
self.weapon = 0;
|
||||
|
||||
self.model = 0;
|
||||
setsize (self, '-16 -16 -16', '16 16 16');
|
||||
|
||||
self.view_ofs = self.velocity = '0 0 0';
|
||||
|
||||
forceinfokey( self, "*spectator", "1" ); // Make sure we are known as a spectator
|
||||
|
||||
// Clear all the ammo stuff
|
||||
for ( int i = 0; i < CS_WEAPON_COUNT; i++ ) {
|
||||
self.(wptTable[ i ].iClipfld) = 0;
|
||||
self.(wptTable[ i ].iCaliberfld) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Event Handling, called by the Client codebase via 'sendevent'
|
||||
void CSEv_GamePlayerSpawn_f( float fTeam ) {
|
||||
Spawn_GameClient( fTeam );
|
||||
Spawn_CreateClient( fTeam );
|
||||
}
|
||||
|
||||
// Counter-Terrorist Spawnpoints
|
||||
|
|
|
@ -44,6 +44,7 @@ void Timer_Update( void ) {
|
|||
if ( ( fGameState == GAME_ACTIVE ) || ( fGameState == GAME_FREEZE ) ) {
|
||||
if ( fGameTime <= 0 ) {
|
||||
if ( fGameState == GAME_ACTIVE ) {
|
||||
Rules_TimeOver();
|
||||
Timer_Begin( 5, GAME_END); // Round is over, 5 seconds til a new round starts
|
||||
} else {
|
||||
Timer_Begin( cvar( "mp_roundtime" ) * 60, GAME_ACTIVE ); // Unfreeze
|
||||
|
@ -60,7 +61,7 @@ void Timer_Update( void ) {
|
|||
}
|
||||
} else if ( fGameState == GAME_END ) {
|
||||
if ( fGameTime <= 0 ) {
|
||||
// Restart round
|
||||
Rules_Restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
/*
|
||||
TRIGGER_MULTIPLE
|
||||
http://twhl.info/wiki.php?id=139
|
||||
// This is what they use...
|
||||
.string killtarget;
|
||||
.float wait;
|
||||
.float delay;
|
||||
|
||||
/*
|
||||
=================
|
||||
trigger_multiple
|
||||
|
||||
This entity triggers a specified target every time its area is entered by players, monsters or pushables.
|
||||
|
||||
Attributes:
|
||||
Target (target) - When an entity is activated, it triggers the entity with the name specified by Target.
|
||||
Name (targetname) - Property used to identify entities.
|
||||
Master (master) - The name of a multisource (or game_team_master) entity. A master must usually be active in order for the entity to work. Thus they act almost like an on/off switch, in their simplest form, and like an AND gate in the case of the multisource.
|
||||
|
@ -11,14 +19,15 @@
|
|||
Sound style (sounds)
|
||||
Message (message)
|
||||
Delay before reset (wait) - Time in seconds before the entity is ready to be re-triggered.
|
||||
|
||||
Flags:
|
||||
Monsters (1) - Allow monsters to activate this entity.
|
||||
No Clients (2) - Players cannot activate this entity.
|
||||
Pushables (4) - Allow pushable objects to activate this entity.
|
||||
=================
|
||||
*/
|
||||
|
||||
// This is what they use...
|
||||
.string killtarget;
|
||||
.float wait;
|
||||
.float delay;
|
||||
|
||||
void trigger_multiple_trigger( void ) {
|
||||
void trigger_multiple( void ) {
|
||||
static void trigger_multiple_trigger( void ) {
|
||||
Entities_UseTargets();
|
||||
|
||||
if ( self.killtarget ) {
|
||||
|
@ -31,14 +40,6 @@ void trigger_multiple_trigger( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SPAWN: trigger_multiple
|
||||
|
||||
Entry function for this nice trigger object.
|
||||
=================
|
||||
*/
|
||||
void trigger_multiple( void ) {
|
||||
static void trigger_multiple_use( void ) {
|
||||
if ( self.delay ) {
|
||||
self.think = trigger_multiple_trigger;
|
||||
|
@ -69,10 +70,31 @@ void trigger_multiple( void ) {
|
|||
self.touch = trigger_multiple_touch;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
multi_manager
|
||||
|
||||
This entity can activate several different events (including itself) at specific times.
|
||||
|
||||
Attributes:
|
||||
Name (targetname) - Property used to identify entities.
|
||||
|
||||
Flags:
|
||||
Multithreaded (1) - See notes below for an explanation.
|
||||
|
||||
Notes:
|
||||
There were better ways to do this, but someone thought it was viable to use custom, user defined fields
|
||||
which cannot normally be read by something like QC for targetnames. FTE allows us to read the fields
|
||||
via the __fullspawndata global at least.
|
||||
|
||||
TODO: Try to find out what garbled mess __fullspawndata is trying to give us
|
||||
=================
|
||||
*/
|
||||
void multi_manager( void ) {
|
||||
static void multi_manager_use( void ) {
|
||||
eprint( self );
|
||||
}
|
||||
|
||||
self.message = __fullspawndata;
|
||||
self.think = multi_manager_use;
|
||||
self.nextthink = self.ltime + 5;
|
||||
|
|
|
@ -36,6 +36,7 @@ Defs.h
|
|||
../Shared/Effects.c
|
||||
Damage.c
|
||||
TraceAttack.c
|
||||
Rules.c
|
||||
Timer.c
|
||||
Main.c
|
||||
EntHostage.c
|
||||
|
@ -48,6 +49,7 @@ FuncLadder.c
|
|||
FuncHostageRescue.c
|
||||
FuncBombTarget.c
|
||||
FuncBuyZone.c
|
||||
Player.c
|
||||
Spawn.c
|
||||
Footsteps.c
|
||||
Input.c
|
||||
|
|
|
@ -51,7 +51,7 @@ void Effect_BreakModel( vector vMins, vector vMaxs, vector vVel, float fStyle )
|
|||
sModel = "models/metalplategibs.mdl";
|
||||
break;
|
||||
case MATERIAL_FLESH:
|
||||
sModel = "models/fleshgibs.mdl";;
|
||||
sModel = "models/fleshgibs.mdl";
|
||||
break;
|
||||
case MATERIAL_CINDER:
|
||||
sModel = "models/cindergibs.mdl";
|
||||
|
|
Loading…
Reference in a new issue