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 );
|
||||
}
|
||||
|
||||
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--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,14 +45,7 @@ void PlayerPostThink( void ) {
|
|||
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.model = 0;
|
||||
setsize (self, '-16 -16 -16', '16 16 16');
|
||||
|
||||
self.view_ofs = self.velocity = '0 0 0';
|
||||
self.classname = "spectator";
|
||||
Spawn_MakeSpectator();
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
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 ) {
|
||||
static void cycler_sprite_use( void ) {
|
||||
remove( self );
|
||||
}
|
||||
|
||||
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;
|
||||
eFind.rendermode = self.rendermode;
|
||||
eFind.rendercolor = self.rendercolor;
|
||||
|
||||
if ( !( self.spawnflags & SF_NORENDERMODE ) ) {
|
||||
eFind.rendermode = self.rendermode;
|
||||
}
|
||||
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;
|
||||
|
||||
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 );
|
||||
} 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 );
|
||||
entity eLastTSpawn;
|
||||
entity eLastCTSpawn;
|
||||
entity Spawn_FindSpawnPoint( int iTeam ) {
|
||||
entity eSpot, eLastSpawn;
|
||||
entity eThing;
|
||||
int iCount;
|
||||
string sClassname;
|
||||
|
||||
if ( iTeam == TEAM_T ) {
|
||||
sClassname = "info_player_deathmatch";
|
||||
eSpot = eLastSpawn = eLastTSpawn;
|
||||
} else {
|
||||
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
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
}
|
||||
|
||||
// Set the fields
|
||||
self.fMoney = cvar( "mp_startmoney" );
|
||||
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,44 +1,45 @@
|
|||
/*
|
||||
TRIGGER_MULTIPLE
|
||||
http://twhl.info/wiki.php?id=139
|
||||
|
||||
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.
|
||||
Delay before trigger (delay) - Usually the time in seconds before an entity should trigger its target (after being triggered itself). Under other SmartEdit names, delay might also be the time to wait before performing some other action.
|
||||
Kill target (killtarget) - Remove this entity from the game when triggered
|
||||
Target Path (netname)
|
||||
Sound style (sounds)
|
||||
Message (message)
|
||||
Delay before reset (wait) - Time in seconds before the entity is ready to be re-triggered.
|
||||
*/
|
||||
|
||||
// This is what they use...
|
||||
.string killtarget;
|
||||
.float wait;
|
||||
.float delay;
|
||||
|
||||
void trigger_multiple_trigger( void ) {
|
||||
Entities_UseTargets();
|
||||
|
||||
if ( self.killtarget ) {
|
||||
entity eFind = findchain( killtarget, self.target );
|
||||
while ( eFind ) {
|
||||
entity eRemoveMe = eFind;
|
||||
remove( eRemoveMe );
|
||||
eFind = eFind.chain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SPAWN: trigger_multiple
|
||||
trigger_multiple
|
||||
|
||||
Entry function for this nice trigger object.
|
||||
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.
|
||||
Delay before trigger (delay) - Usually the time in seconds before an entity should trigger its target (after being triggered itself). Under other SmartEdit names, delay might also be the time to wait before performing some other action.
|
||||
Kill target (killtarget) - Remove this entity from the game when triggered
|
||||
Target Path (netname)
|
||||
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.
|
||||
=================
|
||||
*/
|
||||
void trigger_multiple( void ) {
|
||||
static void trigger_multiple_trigger( void ) {
|
||||
Entities_UseTargets();
|
||||
|
||||
if ( self.killtarget ) {
|
||||
entity eFind = findchain( killtarget, self.target );
|
||||
while ( eFind ) {
|
||||
entity eRemoveMe = eFind;
|
||||
remove( eRemoveMe );
|
||||
eFind = eFind.chain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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