2012-08-04 10:54:37 +00:00
// Copyright (C) 1999-2000 Id Software, Inc.
2012-01-22 21:34:33 +00:00
//
# include "g_local.h"
2012-08-04 10:54:37 +00:00
# include "list.h"
//#include <windows.h> //TiM : WTF?
2012-01-22 21:34:33 +00:00
//==========================================================
/*QUAKED target_give (1 0 0) (-8 -8 -8) (8 8 8)
2012-11-15 05:41:12 +00:00
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
Gives all the weapons specified here in the list .
2012-11-15 05:41:12 +00:00
- - - - - SPAWNFLAGS - - - - -
none
- - - - - KEYS - - - - -
2012-08-04 10:54:37 +00:00
" items " - separated by ' | ' , specify the items
EG " WP_5 | WP_14 " etc
( Don ' t forget the spaces ! )
2012-01-22 21:34:33 +00:00
*/
void Use_Target_Give ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
2012-08-04 10:54:37 +00:00
int i ;
playerState_t * ps = & activator - > client - > ps ;
2012-01-22 21:34:33 +00:00
2012-08-04 10:54:37 +00:00
if ( ! activator | | ! activator - > client ) {
2012-01-22 21:34:33 +00:00
return ;
}
2012-08-04 10:54:37 +00:00
for ( i = 0 ; i < MAX_WEAPONS ; i + + )
{
if ( ( unsigned int ) ( ent - > s . time ) & ( 1 < < i ) )
{
ps - > stats [ STAT_WEAPONS ] ^ = ( 1 < < i ) ;
2012-01-22 21:34:33 +00:00
2012-08-04 10:54:37 +00:00
if ( ps - > stats [ STAT_WEAPONS ] & ( 1 < < i ) )
ps - > ammo [ i ] = 1 ;
else
ps - > ammo [ i ] = 0 ;
2012-01-22 21:34:33 +00:00
continue ;
}
}
}
2012-08-04 10:54:37 +00:00
//FIXME: Make the text parsed on load time. saves on resources!!
void SP_target_give ( gentity_t * ent )
{
char * items ;
char * textPtr ;
char * token ;
int weapon ;
G_SpawnString ( " items " , " " , & items ) ;
if ( ! items [ 0 ] & & ent - > target ) // spawnTEnt
items = G_NewString ( ent - > target ) ;
textPtr = items ;
COM_BeginParseSession ( ) ;
while ( 1 )
{
token = COM_Parse ( & textPtr ) ;
if ( ! token [ 0 ] )
break ;
if ( ! Q_stricmpn ( token , " | " , 1 ) )
continue ;
if ( ! Q_stricmpn ( token , " WP_ " , 3 ) )
{
weapon = GetIDForString ( WeaponTable , token ) ;
if ( weapon > = 0 )
{
ent - > s . time | = ( 1 < < weapon ) ;
}
}
}
//TiM - remove items per server discretion
if ( rpg_mapGiveFlags . integer > 0 )
ent - > s . time & = rpg_mapGiveFlags . integer ;
2012-01-22 21:34:33 +00:00
ent - > use = Use_Target_Give ;
2012-08-04 10:54:37 +00:00
// don't need to send this to clients
ent - > r . svFlags & = SVF_NOCLIENT ;
trap_LinkEntity ( ent ) ;
2012-01-22 21:34:33 +00:00
}
//==========================================================
/*QUAKED target_remove_powerups (1 0 0) (-8 -8 -8) (8 8 8)
2012-11-15 05:41:12 +00:00
- - - - - DESCRIPTION - - - - -
2012-01-22 21:34:33 +00:00
takes away all the activators powerups .
Used to drop flight powerups into death puts .
2012-11-15 05:41:12 +00:00
- - - - - SPAWNFLAGS - - - - -
none
- - - - - KEYS - - - - -
none
2012-01-22 21:34:33 +00:00
*/
2012-11-27 21:57:55 +00:00
//hmmm... maybe remove this, not sure.
2012-01-22 21:34:33 +00:00
void Use_target_remove_powerups ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
2012-08-04 10:54:37 +00:00
if ( ! activator | | ! activator - > client ) {
2012-01-22 21:34:33 +00:00
return ;
}
memset ( activator - > client - > ps . powerups , 0 , sizeof ( activator - > client - > ps . powerups ) ) ;
}
void SP_target_remove_powerups ( gentity_t * ent ) {
ent - > use = Use_target_remove_powerups ;
}
//==========================================================
2012-08-04 10:54:37 +00:00
/*QUAKED target_delay (1 0 0) (-8 -8 -8) (8 8 8) SELF
2012-11-15 05:41:12 +00:00
- - - - - DESCRIPTION - - - - -
When used fires it ' d target after a delay of ' wait ' seconds
2012-08-04 10:54:37 +00:00
2012-11-15 05:41:12 +00:00
- - - - - SPAWNFLAGS - - - - -
2012-11-27 21:57:55 +00:00
1 : SELF - use the entity as activator instead of it ' s own activator when using it ' s targets ( use this flag for targets that are not called by their targetname ( e . g . swapname ) )
2012-11-15 05:41:12 +00:00
- - - - - KEYS - - - - -
2012-11-27 21:57:55 +00:00
" wait " - seconds to pause before firing targets .
" random " - delay variance , total delay = delay + / - random seconds
" luaUse " - lua function to call at the beginning of the delay
luaThink - lua function to call at end of delay
2012-01-22 21:34:33 +00:00
*/
void Think_Target_Delay ( gentity_t * ent ) {
2012-08-04 10:54:37 +00:00
# ifdef G_LUA
if ( ent - > luaTrigger )
{
if ( ent - > activator )
{
LuaHook_G_EntityTrigger ( ent - > luaTrigger , ent - > s . number , ent - > activator - > s . number ) ;
}
else
{
LuaHook_G_EntityTrigger ( ent - > luaTrigger , ent - > s . number , ENTITYNUM_WORLD ) ;
}
}
# endif
if ( ent - > spawnflags & 1 )
G_UseTargets ( ent , ent ) ;
else
G_UseTargets ( ent , ent - > activator ) ;
2012-01-22 21:34:33 +00:00
}
void Use_Target_Delay ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
ent - > nextthink = level . time + ( ent - > wait + ent - > random * crandom ( ) ) * 1000 ;
ent - > think = Think_Target_Delay ;
ent - > activator = activator ;
}
void SP_target_delay ( gentity_t * ent ) {
if ( ! ent - > wait ) {
2012-08-04 10:54:37 +00:00
G_SpawnFloat ( " delay " , " 0 " , & ent - > wait ) ;
if ( ! ent - > wait )
ent - > wait = 1 ;
2012-01-22 21:34:33 +00:00
}
2012-08-04 10:54:37 +00:00
ent - > count = ( int ) ent - > wait ;
2012-01-22 21:34:33 +00:00
ent - > use = Use_Target_Delay ;
2012-08-04 10:54:37 +00:00
// don't need to send this to clients
ent - > r . svFlags & = SVF_NOCLIENT ;
trap_LinkEntity ( ent ) ;
2012-01-22 21:34:33 +00:00
}
//==========================================================
/*QUAKED target_print (1 0 0) (-8 -8 -8) (8 8 8) redteam blueteam private
2012-11-15 05:41:12 +00:00
- - - - - DESCRIPTION - - - - -
This will display the ' message ' in the lower right corner for all reciepients .
By default every client get ' s the message however this can be limited via spawnflags .
- - - - - SPAWNFLAGS - - - - -
1 : redteam - everyone on the red team gets the message
2 : blueteam - everyone on the blue team gets the message
4 : private - only the activator gets the message
- - - - - KEYS - - - - -
2012-01-22 21:34:33 +00:00
" message " text to print
*/
void Use_Target_Print ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
2012-08-04 10:54:37 +00:00
if ( activator & & activator - > client & & ( ent - > spawnflags & 4 ) ) {
trap_SendServerCommand ( activator - g_entities , va ( " servermsg %s " , ent - > message ) ) ;
2012-01-22 21:34:33 +00:00
return ;
}
if ( ent - > spawnflags & 3 ) {
if ( ent - > spawnflags & 1 ) {
2012-08-04 10:54:37 +00:00
G_TeamCommand ( TEAM_RED , va ( " servermsg %s " , ent - > message ) ) ;
2012-01-22 21:34:33 +00:00
}
if ( ent - > spawnflags & 2 ) {
2012-08-04 10:54:37 +00:00
G_TeamCommand ( TEAM_BLUE , va ( " servermsg %s " , ent - > message ) ) ;
2012-01-22 21:34:33 +00:00
}
return ;
}
2012-08-04 10:54:37 +00:00
trap_SendServerCommand ( - 1 , va ( " servermsg %s " , ent - > message ) ) ;
2012-01-22 21:34:33 +00:00
}
void SP_target_print ( gentity_t * ent ) {
ent - > use = Use_Target_Print ;
}
//==========================================================
2012-11-15 05:41:12 +00:00
/*QUAKED target_speaker (1 0 0) (-8 -8 -8) (8 8 8) LOOPED_ON LOOPED_OFF GLOBAL ACTIVATOR
- - - - - DESCRIPTION - - - - -
A sound - file to play .
By default this will be played once locally .
The specifics on how to play are set via spawnflags .
2012-01-22 21:34:33 +00:00
2012-11-15 05:41:12 +00:00
Looping Sounds may not be combined with GLOBAL or ACTIVATOR
2012-01-22 21:34:33 +00:00
Multiple identical looping sounds will just increase volume without any speed cost .
2012-11-15 05:41:12 +00:00
Using a looping target_speaker will toggle it ' s sound on or off .
Using a target_speaker designed to play it ' s sound once will play that sound .
- - - - - SPAWNFLAGS - - - - -
1 : LOOPED_ON - this Speaker will loop it ' s sound and will be active at spawn .
2 : LOOPED_OFF - this Speaker will loop it ' s sound and will be inactive at spawn .
4 : GLOBAL - the sound will be played once globally so every client will hear it .
8 : ACTIVATOR - The sound will be played once for the activator only to hear .
- - - - - KEYS - - - - -
" noise " - file to play
" wait " - Seconds between auto triggerings , default = 0 = don ' t auto trigger
" random " - wait variance , default is 0 , delay would be wait + / - random
2012-01-22 21:34:33 +00:00
*/
void Use_Target_Speaker ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
if ( ent - > spawnflags & 3 ) { // looping sound toggles
if ( ent - > s . loopSound )
ent - > s . loopSound = 0 ; // turn it off
else
ent - > s . loopSound = ent - > noise_index ; // start it
} else { // normal sound
2012-08-04 10:54:37 +00:00
if ( activator & & ( ent - > spawnflags & 8 ) ) {
2012-01-22 21:34:33 +00:00
G_AddEvent ( activator , EV_GENERAL_SOUND , ent - > noise_index ) ;
} else if ( ent - > spawnflags & 4 ) {
G_AddEvent ( ent , EV_GLOBAL_SOUND , ent - > noise_index ) ;
} else {
G_AddEvent ( ent , EV_GENERAL_SOUND , ent - > noise_index ) ;
}
}
}
void SP_target_speaker ( gentity_t * ent ) {
char buffer [ MAX_QPATH ] ;
char * s ;
G_SpawnFloat ( " wait " , " 0 " , & ent - > wait ) ;
G_SpawnFloat ( " random " , " 0 " , & ent - > random ) ;
2012-08-04 10:54:37 +00:00
if ( ! G_SpawnString ( " noise " , " NOSOUND " , & s ) & & ! ent - > count ) { // if ent->count then it is a spawned sound, either by spawnEnt or *.spawn
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] target_speaker without a noise key at %s " , vtos ( ent - > s . origin ) ) ; ) ;
G_FreeEntity ( ent ) ; //let's not error out so that we can use SP maps with their funky speakers.
return ;
2012-01-22 21:34:33 +00:00
}
2012-08-04 10:54:37 +00:00
if ( ! ent - > count ) { // not by spawnTEnt/*.spawn
// force all client reletive sounds to be "activator" speakers that
// play on the entity that activates it
if ( s [ 0 ] = = ' * ' ) {
ent - > spawnflags | = 8 ;
}
memset ( buffer , 0 , sizeof ( buffer ) ) ;
2012-01-22 21:34:33 +00:00
Q_strncpyz ( buffer , s , sizeof ( buffer ) ) ;
2012-08-04 10:54:37 +00:00
COM_DefaultExtension ( buffer , sizeof ( buffer ) , " .wav " ) ;
ent - > noise_index = G_SoundIndex ( buffer ) ;
} else { // by spawnTEnt or *.spawn file
ent - > noise_index = ent - > count ;
2012-01-22 21:34:33 +00:00
}
// a repeating speaker can be done completely client side
ent - > s . eType = ET_SPEAKER ;
ent - > s . eventParm = ent - > noise_index ;
ent - > s . frame = ent - > wait * 10 ;
ent - > s . clientNum = ent - > random * 10 ;
// check for prestarted looping sound
if ( ent - > spawnflags & 1 ) {
ent - > s . loopSound = ent - > noise_index ;
}
ent - > use = Use_Target_Speaker ;
if ( ent - > spawnflags & 4 ) {
ent - > r . svFlags | = SVF_BROADCAST ;
}
VectorCopy ( ent - > s . origin , ent - > s . pos . trBase ) ;
// must link the entity so we get areas and clusters so
// the server can determine who to send updates to
trap_LinkEntity ( ent ) ;
}
//==========================================================
/*QUAKED target_laser (0 .5 .8) (-8 -8 -8) (8 8 8) START_ON
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-01-22 21:34:33 +00:00
When triggered , fires a laser . You can either set a target or a direction .
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
1 : START_ON - will be on at spawn
- - - - - KEYS - - - - -
" targetname " - when used will toggle on / off
" target " - point to fire laser at
2012-01-22 21:34:33 +00:00
*/
void target_laser_think ( gentity_t * self ) {
vec3_t end ;
trace_t tr ;
vec3_t point ;
// if pointed at another entity, set movedir to point at it
if ( self - > enemy ) {
VectorMA ( self - > enemy - > s . origin , 0.5 , self - > enemy - > r . mins , point ) ;
VectorMA ( point , 0.5 , self - > enemy - > r . maxs , point ) ;
VectorSubtract ( point , self - > s . origin , self - > movedir ) ;
VectorNormalize ( self - > movedir ) ;
}
// fire forward and see what we hit
VectorMA ( self - > s . origin , 2048 , self - > movedir , end ) ;
trap_Trace ( & tr , self - > s . origin , NULL , NULL , end , self - > s . number , CONTENTS_SOLID | CONTENTS_BODY | CONTENTS_CORPSE ) ;
if ( tr . entityNum ) {
// hurt it if we can
G_Damage ( & g_entities [ tr . entityNum ] , self , self - > activator , self - > movedir ,
tr . endpos , self - > damage , DAMAGE_NO_KNOCKBACK , MOD_TARGET_LASER ) ;
}
VectorCopy ( tr . endpos , self - > s . origin2 ) ;
trap_LinkEntity ( self ) ;
self - > nextthink = level . time + FRAMETIME ;
}
void target_laser_on ( gentity_t * self )
{
if ( ! self - > activator )
self - > activator = self ;
target_laser_think ( self ) ;
}
void target_laser_off ( gentity_t * self )
{
trap_UnlinkEntity ( self ) ;
self - > nextthink = 0 ;
}
void target_laser_use ( gentity_t * self , gentity_t * other , gentity_t * activator )
{
2012-08-04 10:54:37 +00:00
if ( activator )
self - > activator = activator ;
2012-01-22 21:34:33 +00:00
if ( self - > nextthink > 0 )
target_laser_off ( self ) ;
else
target_laser_on ( self ) ;
}
void target_laser_start ( gentity_t * self )
{
gentity_t * ent ;
self - > s . eType = ET_BEAM ;
if ( self - > target ) {
ent = G_Find ( NULL , FOFS ( targetname ) , self - > target ) ;
if ( ! ent ) {
2012-08-04 10:54:37 +00:00
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] %s at %s: %s is a bad target \n " , self - > classname , vtos ( self - > s . origin ) , self - > target ) ; ) ;
G_FreeEntity ( self ) ;
return ;
2012-01-22 21:34:33 +00:00
}
self - > enemy = ent ;
} else {
G_SetMovedir ( self - > s . angles , self - > movedir ) ;
}
self - > use = target_laser_use ;
self - > think = target_laser_think ;
if ( ! self - > damage ) {
self - > damage = 1 ;
}
if ( self - > spawnflags & 1 )
target_laser_on ( self ) ;
else
target_laser_off ( self ) ;
}
void SP_target_laser ( gentity_t * self )
{
// let everything else get spawned before we start firing
self - > think = target_laser_start ;
self - > nextthink = level . time + FRAMETIME ;
}
//==========================================================
void target_teleporter_use ( gentity_t * self , gentity_t * other , gentity_t * activator ) {
gentity_t * dest ;
2012-08-04 10:54:37 +00:00
vec3_t destPoint ;
vec3_t tracePoint ;
trace_t tr ;
2012-01-22 21:34:33 +00:00
2012-08-04 10:54:37 +00:00
if ( ! Q_stricmp ( self - > swapname , activator - > target ) ) {
self - > flags ^ = FL_LOCKED ;
return ;
}
if ( self - > flags & FL_LOCKED )
return ;
if ( ! activator | | ! activator - > client )
2012-01-22 21:34:33 +00:00
return ;
dest = G_PickTarget ( self - > target ) ;
if ( ! dest ) {
2012-08-04 10:54:37 +00:00
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] Couldn't find teleporter destination \n " ) ; ) ;
G_FreeEntity ( self ) ;
2012-01-22 21:34:33 +00:00
return ;
}
2012-08-04 10:54:37 +00:00
VectorCopy ( dest - > s . origin , destPoint ) ;
if ( self - > spawnflags & 2 )
{
destPoint [ 2 ] + = dest - > r . mins [ 2 ] ;
destPoint [ 2 ] - = other - > r . mins [ 2 ] ;
destPoint [ 2 ] + = 1 ;
}
else
{
VectorCopy ( dest - > s . origin , tracePoint ) ;
tracePoint [ 2 ] - = 4096 ;
trap_Trace ( & tr , dest - > s . origin , dest - > r . mins , dest - > r . maxs , tracePoint , dest - > s . number , MASK_PLAYERSOLID ) ;
VectorCopy ( tr . endpos , destPoint ) ;
//offset the player's bounding box.
2012-11-12 21:02:07 +00:00
destPoint [ 2 ] - = activator - > r . mins [ 2 ] ;
2012-08-04 10:54:37 +00:00
//add 1 to ensure non-direct collision
destPoint [ 2 ] + = 1 ;
}
if ( self - > spawnflags & 1 ) {
if ( TransDat [ activator - > client - > ps . clientNum ] . beamTime = = 0 ) {
G_InitTransport ( activator - > client - > ps . clientNum , destPoint , dest - > s . angles ) ;
}
}
else {
TeleportPlayer ( activator , destPoint , dest - > s . angles , TP_NORMAL ) ;
}
2012-01-22 21:34:33 +00:00
}
2012-08-04 10:54:37 +00:00
/*QUAKED target_teleporter (1 0 0) (-8 -8 -8) (8 8 8) VISUAL_FX SUSPENDED DEACTIVATED
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
The activator will be instantly teleported away .
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
1 : VISUAL_FX - Instead of instant teleportation with no FX , entity will play the Star Trek style
transporter effect and teleport over the course of an 8 second cycle .
NB - If using the transporter VISUAL_FX , place the target entity so it ' s right on top of
the surface you want the player to appear on . It ' s been hardcoded to take this offset into
account only when the VISUAL_FX flag is on
2 : SUSPENDED - Unless this is checked , the player will materialise on top of the first solid surface underneath the entity
4 : DEACTIVATED - Teleporter will be deactiavted at spawn
2012-08-04 10:54:37 +00:00
2012-11-27 21:57:55 +00:00
- - - - - KEYS - - - - -
" targetname " - Any entities targeting this will activate it when used .
" target " - Name of one or more info_notnull entities that the player teleport to .
" swapname " - Activate / Deactivate ( Using entity needs SELF / NOACTIVATOR )
2012-01-22 21:34:33 +00:00
*/
void SP_target_teleporter ( gentity_t * self ) {
2012-08-04 10:54:37 +00:00
if ( ! self - > targetname ) {
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] untargeted %s at %s \n " , self - > classname , vtos ( self - > s . origin ) ) ; ) ;
}
if ( self - > spawnflags & 4 )
self - > flags ^ = FL_LOCKED ;
2012-01-22 21:34:33 +00:00
self - > use = target_teleporter_use ;
}
//==========================================================
2012-08-04 10:54:37 +00:00
/*QUAKED target_relay (.5 .5 .5) (-8 -8 -8) (8 8 8) RED_ONLY BLUE_ONLY RANDOM SELF
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-01-22 21:34:33 +00:00
This doesn ' t perform any actions except fire its targets .
2012-11-27 21:57:55 +00:00
It is also a nice function - caller via luaUse .
- - - - - SPAWNFLAGS - - - - -
1 : RED_ONLY - Only members from the red team can use this
2 : BLUE_ONLY - Only members from the blue team can use this
4 : RANDOM - only one of the entities with matching targetname will be fired , not all of them
8 : SELF - use the entity as activator instead of it ' s own activator when using it ' s targets ( use this flag for targets that are not called by their targetname ( e . g . swapname ) )
2012-08-04 10:54:37 +00:00
2012-11-27 21:57:55 +00:00
- - - - - KEYS - - - - -
" targetname " - calling this will fire the entity
" target " - targetname of entities to fire
" luaUse " - lua function to call on use
2012-01-22 21:34:33 +00:00
*/
2012-08-04 10:54:37 +00:00
2012-01-22 21:34:33 +00:00
void target_relay_use ( gentity_t * self , gentity_t * other , gentity_t * activator ) {
2012-08-04 10:54:37 +00:00
if ( ( self - > spawnflags & 1 ) & & activator & & activator - > client
2012-01-22 21:34:33 +00:00
& & activator - > client - > sess . sessionTeam ! = TEAM_RED ) {
2012-08-04 10:54:37 +00:00
return ;
2012-01-22 21:34:33 +00:00
}
2012-08-04 10:54:37 +00:00
if ( ( self - > spawnflags & 2 ) & & activator & & activator - > client
2012-01-22 21:34:33 +00:00
& & activator - > client - > sess . sessionTeam ! = TEAM_BLUE ) {
2012-08-04 10:54:37 +00:00
return ;
2012-01-22 21:34:33 +00:00
}
2012-08-04 10:54:37 +00:00
if ( ! activator ) return ;
2012-01-22 21:34:33 +00:00
if ( self - > spawnflags & 4 ) {
gentity_t * ent ;
ent = G_PickTarget ( self - > target ) ;
if ( ent & & ent - > use ) {
2012-08-04 10:54:37 +00:00
if ( self - > spawnflags & 8 ) {
ent - > use ( ent , self , self ) ;
# ifdef G_LUA
if ( ent - > luaUse )
LuaHook_G_EntityUse ( self - > luaUse , self - > s . number , other - > s . number , activator - > s . number ) ;
# endif
}
else {
ent - > use ( ent , self , activator ) ;
# ifdef G_LUA
if ( ent - > luaUse )
LuaHook_G_EntityUse ( self - > luaUse , self - > s . number , other - > s . number , self - > s . number ) ;
# endif
}
2012-01-22 21:34:33 +00:00
}
return ;
}
2012-08-04 10:54:37 +00:00
if ( self - > spawnflags & 8 )
G_UseTargets ( self , self ) ;
else
G_UseTargets ( self , activator ) ;
2012-01-22 21:34:33 +00:00
}
void SP_target_relay ( gentity_t * self ) {
self - > use = target_relay_use ;
}
//==========================================================
/*QUAKED target_kill (.5 .5 .5) (-8 -8 -8) (8 8 8)
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-01-22 21:34:33 +00:00
Kills the activator .
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
none
- - - - - KEYS - - - - -
" targetanme " - the activator calling this will be telefragged if client
2012-01-22 21:34:33 +00:00
*/
void target_kill_use ( gentity_t * self , gentity_t * other , gentity_t * activator ) {
2012-08-04 10:54:37 +00:00
if ( activator )
G_Damage ( activator , NULL , NULL , NULL , NULL , 100000 , DAMAGE_NO_PROTECTION , MOD_TELEFRAG ) ;
2012-01-22 21:34:33 +00:00
}
void SP_target_kill ( gentity_t * self ) {
self - > use = target_kill_use ;
2012-08-04 10:54:37 +00:00
// don't need to send this to clients
self - > r . svFlags & = SVF_NOCLIENT ;
trap_LinkEntity ( self ) ;
2012-01-22 21:34:33 +00:00
}
static void target_location_linkup ( gentity_t * ent )
{
int i ;
int n ;
2012-08-04 10:54:37 +00:00
//gentity_t *tent;
2012-01-22 21:34:33 +00:00
if ( level . locationLinked )
return ;
level . locationLinked = qtrue ;
level . locationHead = NULL ;
trap_SetConfigstring ( CS_LOCATIONS , " unknown " ) ;
for ( i = 0 , ent = g_entities , n = 1 ;
2012-08-04 10:54:37 +00:00
i < level . num_entities ;
i + + , ent + + ) {
if ( ent - > classname & & ! Q_stricmp ( ent - > classname , " target_location " ) ) {
// lets overload some variables!
ent - > health = n ; // use for location marking
trap_SetConfigstring ( CS_LOCATIONS + n , ent - > message ) ;
n + + ;
ent - > nextTrain = level . locationHead ;
level . locationHead = ent ;
}
2012-01-22 21:34:33 +00:00
}
// All linked together now
}
/*QUAKED target_location (0 0.5 0) (-8 -8 -8) (8 8 8)
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
Location to display in the player - list ( usually Tab )
Closest target_location in sight used for the location , if nonein sight , closest in distance
2012-01-22 21:34:33 +00:00
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
none
- - - - - KEYS - - - - -
" message " - location name to display . Can be colorized using ' ^ X ' where X is one of the following numbers
0 : white 1 : red 2 : green 3 : yellow 4 : blue 5 : cyan 6 : magenta 7 : white
- - - - - LocEdit - - - - -
target_locations can also be spawned by a < mapname > . locations - file .
While creating this was hard work for many years , a new command makes it quite easy : LocEdit
There are a few basic commands :
/ locedit start < type >
This will open the file .
For type set 1 if you ' d like to restrict a location so only admins can autorise transportation there .
Else set 0.
For Type = 0 : / locedit add " <location-name> "
For Type = 1 : / locedit add < protected > " <location-name> "
this will add a new location to the list .
It will grab your current position as well as your yaw - angle ( around the Z - Axis ) and dump them to the file with the parameters .
If you set protected 1 only admins can authorise transportation there .
location - name can be colorized as stated above . You need to put it in " " .
/ locedit nl
this will simply add an empty line . If you have to manually edit the file at a later date this will help you get oriented .
/ locedit stop
this will close the file .
2012-01-22 21:34:33 +00:00
*/
void SP_target_location ( gentity_t * self ) {
self - > think = target_location_linkup ;
self - > nextthink = level . time + 200 ; // Let them all spawn first
G_SetOrigin ( self , self - > s . origin ) ;
}
2012-11-27 21:57:55 +00:00
/*QUAKED target_counter (1.0 0 0) (-4 -4 -4) (4 4 4)
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
Acts as an intermediary for an action that takes multiple inputs .
2012-11-27 21:57:55 +00:00
After the counter has been triggered " count " times it will fire all of it ' s targets and remove itself .
- - - - - SPAWNFLAGS - - - - -
none
2012-08-04 10:54:37 +00:00
2012-11-27 21:57:55 +00:00
- - - - - KEYS - - - - -
" count " - number of usages required before targets are fired . Default is 2
" targetname " - Will reduce count by one .
" target " will be fired once count hit ' s 0
2012-08-04 10:54:37 +00:00
*/
void target_counter_use ( gentity_t * self , gentity_t * other , gentity_t * activator )
{
if ( self - > count = = 0 )
{
return ;
}
self - > count - - ;
if ( self - > count )
{
return ;
}
if ( activator )
self - > activator = activator ;
else
self - > activator = self ;
G_UseTargets ( self , activator ) ;
}
void SP_target_counter ( gentity_t * self )
{
self - > wait = - 1 ;
if ( ! self - > count )
{
self - > count = 2 ;
}
self - > use = target_counter_use ;
// don't need to send this to clients
self - > r . svFlags & = SVF_NOCLIENT ;
trap_LinkEntity ( self ) ;
}
/*QUAKED target_objective (1.0 0 0) (-4 -4 -4) (4 4 4)
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
When used , the objective in the < mapname > . efo with this objective ' s " count " will be marked as completed
2012-11-27 21:57:55 +00:00
NOTE : the objective with the lowest " count " will be considered the current objective
- - - - - SPAWNFLAGS - - - - -
none
2012-08-04 10:54:37 +00:00
2012-11-27 21:57:55 +00:00
- - - - - KEYS - - - - -
" count " - number of objective ( as listed in the maps ' < mapname > . efo )
" targetname " - when fired marks objective as complete
2012-08-04 10:54:37 +00:00
*/
2012-11-27 21:57:55 +00:00
// Remove this?
2012-08-04 10:54:37 +00:00
void target_objective_use ( gentity_t * self , gentity_t * other , gentity_t * activator )
{
gentity_t * tent ;
tent = G_TempEntity ( self - > r . currentOrigin , EV_OBJECTIVE_COMPLETE ) ;
if ( ! tent ) return ; // uh ohhhh
//Be sure to send the event to everyone
tent - > r . svFlags | = SVF_BROADCAST ;
tent - > s . eventParm = self - > count ;
}
void SP_target_objective ( gentity_t * self )
{
if ( self - > count < = 0 )
{
//FIXME: error msg
G_FreeEntity ( self ) ;
return ;
}
if ( self - > targetname )
{
self - > use = target_objective_use ;
}
level . numObjectives + + ;
}
/*================
RPG - X Modification
Phenix
13 / 06 / 2004
= = = = = = = = = = = = = = = = */
/*QUAKED target_boolean (.5 .5 .5) (-8 -8 -8) (8 8 8) START_TRUE SWAP_FIRE SELF
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
Acts as an if statement . When fired normaly if true it fires one target , if false it fires another .
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
1 : START_TRUE - the boolean starts true .
2 : SWAP_FIRE - when the swap command is issued it will also fire the new target .
4 : SELF - use the entity as activator instead of it ' s own activator when using it ' s targets ( use this flag for targets that are not called by their targetanme )
- - - - - KEYS - - - - -
" targetname " - this when fired will fire the target according to which state the boolean is in
" swapname " - this when fired will swap the boolean from one state to the opposite
" truename " - this when fired will swap the boolean ' s state to true
" falsename " - this when fired will sawp the boolean ' s state to false
" truetarget " - this will be fired if the boolean is true then the targetname is recieved
" falsetarget " - this will be fired if the boolean is false then the targetname is recieved
2012-08-04 10:54:37 +00:00
*/
void target_boolean_use ( gentity_t * self , gentity_t * other , gentity_t * activator ) {
if ( ( ! self ) | | ( ! other ) | | ( ! activator ) )
{
return ;
}
if ( Q_stricmp ( self - > truetarget , " (NULL) " ) = = 0 )
{
G_SpawnString ( " truetarget " , " DEFAULTTARGET " , & self - > truetarget ) ;
}
if ( Q_stricmp ( other - > target , self - > targetname ) = = 0 ) {
if ( self - > booleanstate = = qtrue ) {
if ( self - > spawnflags & 4 ) {
self - > target = self - > truetarget ;
G_UseTargets2 ( self , self , self - > truetarget ) ;
} else {
G_UseTargets2 ( self , activator , self - > truetarget ) ;
}
return ;
} else {
if ( self - > spawnflags & 4 ) {
self - > target = self - > falsetarget ;
G_UseTargets2 ( self , self , self - > falsetarget ) ;
} else {
G_UseTargets2 ( self , activator , self - > falsetarget ) ;
}
return ;
}
} else if ( Q_stricmp ( other - > target , self - > truename ) = = 0 ) {
self - > booleanstate = qtrue ; //Make the boolean true
return ;
} else if ( Q_stricmp ( other - > target , self - > falsename ) = = 0 ) {
self - > booleanstate = qfalse ; //Make the boolean false
return ;
} else if ( Q_stricmp ( other - > target , self - > swapname ) = = 0 ) {
if ( self - > booleanstate = = qtrue ) { //If the boolean is true then swap to false
self - > booleanstate = qfalse ;
if ( self - > spawnflags & 2 ) {
if ( self - > spawnflags & 4 ) {
self - > target = self - > falsetarget ;
G_UseTargets2 ( self , self , self - > falsetarget ) ;
} else {
G_UseTargets2 ( self , activator , self - > falsetarget ) ;
}
}
} else {
self - > booleanstate = qtrue ;
if ( self - > spawnflags & 2 ) {
if ( self - > spawnflags & 4 ) {
self - > target = self - > truetarget ;
G_UseTargets2 ( self , self , self - > truetarget ) ;
} else {
G_UseTargets2 ( self , activator , self - > truetarget ) ;
}
}
}
return ;
}
}
void SP_target_boolean ( gentity_t * self ) {
if ( ! self - > booleanstate & & self - > spawnflags & 1 ) {
self - > booleanstate = qtrue ;
} else if ( ! self - > booleanstate ) {
self - > booleanstate = qfalse ;
}
self - > use = target_boolean_use ;
// don't need to send this to clients
self - > r . svFlags & = SVF_NOCLIENT ;
trap_LinkEntity ( self ) ;
}
/*QUAKED target_gravity (.5 .5 .5) (-8 -8 -8) (8 8 8) PLAYER_ONLY MAP_GRAV
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
This changes the servers gravity to the ammount set .
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
1 : PLAYER_ONLY - If select this will only change the gravity for teh actiator . TiM : an actiator eh ?
2 : MAP_GRAV - Will reset player to the current global gravity .
- - - - - KEYS - - - - -
" gravity " - gravity value ( default = g_gravity default = 800 )
2012-08-04 10:54:37 +00:00
*/
void target_gravity_use ( gentity_t * self , gentity_t * other , gentity_t * activator )
{
//CIf spawn flag 1 is set, change gravity to specific user
if ( ( self - > spawnflags & 1 ) & & activator & & activator - > client )
{
activator - > client - > ps . gravity = atoi ( self - > targetname2 ) ;
activator - > client - > SpecialGrav = qtrue ;
}
//resyncing players grav to map grav.
else if ( ( self - > spawnflags & 2 ) & & activator & & activator - > client )
{
activator - > client - > ps . gravity = g_gravity . integer ;
activator - > client - > SpecialGrav = qfalse ;
}
//Else change gravity for all clients
else
{
trap_Cvar_Set ( " g_gravity " , self - > targetname2 ) ;
}
}
void SP_target_gravity ( gentity_t * self ) {
char * temp ;
if ( ! self - > tmpEntity ) { // check for spawnTEnt
G_SpawnString ( " gravity " , " 800 " , & temp ) ;
self - > targetname2 = G_NewString ( temp ) ;
}
if ( self - > count ) // support for SP
self - > targetname2 = G_NewString ( va ( " %i " , self - > count ) ) ;
self - > use = target_gravity_use ;
// don't need to send this to clients
self - > r . svFlags & = SVF_NOCLIENT ;
trap_LinkEntity ( self ) ;
}
/*QUAKED target_shake (.5 .5 .5) (-8 -8 -8) (8 8 8)
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
When fired every clients monitor will shake as if in an explosion
- - - - - SPAWNFLAGS - - - - -
none
2012-08-04 10:54:37 +00:00
2012-11-27 21:57:55 +00:00
- - - - - KEYS - - - - -
" wait " - Time that the shaking lasts for in seconds
" intensity " - Strength of shake
2012-08-04 10:54:37 +00:00
*/
2012-11-27 21:57:55 +00:00
//move this to FX and do a redirect in spawn?
2012-08-04 10:54:37 +00:00
void target_shake_use ( gentity_t * self , gentity_t * other , gentity_t * activator )
{
trap_SetConfigstring ( CS_CAMERA_SHAKE , va ( " %f %i " , self - > distance /*was self->intensity*/ , ( ( int ) ( level . time - level . startTime ) + ( int ) ( self - > wait * 1000 ) ) ) ) ;
}
void SP_target_shake ( gentity_t * self ) {
//TiM: Phenix, you're a n00b. You should always put default values in. ;P
G_SpawnFloat ( " intensity " , " 5 " , & self - > distance /*was &self->intensity*/ ) ;
G_SpawnFloat ( " wait " , " 5 " , & self - > wait ) ;
self - > use = target_shake_use ;
}
/*QUAKED target_evosuit (.5 .5 .5) (-8 -8 -8) (8 8 8)
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
Grants activating clent the EVA - Suit - Flag with all sideeffects associated .
- - - - - SPAWNFLAGS - - - - -
none
- - - - - KEYS - - - - -
" targetanme " - entity needs to be used
2012-08-04 10:54:37 +00:00
*/
void target_evosuit_use ( gentity_t * self , gentity_t * other , gentity_t * activator )
{
if ( ! activator | | ! activator - > client ) return ;
activator - > flags ^ = FL_EVOSUIT ;
if ( ! ( activator - > flags & FL_EVOSUIT ) )
{
G_PrintfClient ( activator , " %s \n " , " You have taken an EVA Suit off \n " ) ;
activator - > client - > ps . powerups [ PW_EVOSUIT ] = 0 ;
}
else
{
G_PrintfClient ( activator , " %s \n " , " You have put an EVA Suit on \n " ) ;
activator - > client - > ps . powerups [ PW_EVOSUIT ] = level . time + 1000000000 ;
}
}
void SP_target_evosuit ( gentity_t * self ) {
self - > use = target_evosuit_use ;
// don't need to send this to clients
self - > r . svFlags & = SVF_NOCLIENT ;
trap_LinkEntity ( self ) ;
}
//==================================================================================
//
//TiM - Turbolift Ent
//Multiple phases are broken up into multiple think functions
//
//==================================================================================
static void target_turbolift_unlock ( gentity_t * ent )
{
gentity_t * otherLift ;
//get target deck number lift entity
otherLift = & g_entities [ ent - > count ] ;
//last phase - unlock turbolift doors
{
gentity_t * door = NULL ;
while ( ( door = G_Find ( door , FOFS ( targetname ) , ent - > target ) ) ! = NULL )
{
if ( ! Q_stricmp ( door - > classname , " func_door " ) )
{
door - > flags & = ~ FL_CLAMPED ;
}
}
door = NULL ;
if ( otherLift )
{
while ( ( door = G_Find ( door , FOFS ( targetname ) , otherLift - > target ) ) ! = NULL )
{
if ( ! Q_stricmp ( door - > classname , " func_door " ) )
{
door - > flags & = ~ FL_CLAMPED ;
}
}
}
}
//reset lifts
if ( otherLift )
otherLift - > count = 0 ;
ent - > s . time2 = 0 ;
if ( otherLift )
otherLift - > s . time2 = 0 ;
ent - > count = 0 ;
ent - > nextthink = 0 ;
ent - > think = 0 ;
}
static void target_turbolift_endMove ( gentity_t * ent )
{
gentity_t * lights = NULL ;
gentity_t * otherLift = NULL ;
float f = 0 ;
otherLift = & g_entities [ ent - > count ] ;
if ( ! otherLift )
{
target_turbolift_unlock ( ent ) ;
return ;
}
//unplay move sound
ent - > r . svFlags | = SVF_NOCLIENT ;
otherLift - > r . svFlags | = SVF_NOCLIENT ;
//play end sound
G_Sound ( ent , ent - > s . otherEntityNum2 ) ;
G_Sound ( otherLift , otherLift - > s . otherEntityNum2 ) ;
//unshow flashy bits
//find any usables parented to the lift ent, and use them
{
while ( ( lights = G_Find ( lights , FOFS ( targetname ) , ent - > target ) ) ! = NULL )
{
if ( ! Q_stricmp ( lights - > classname , " func_usable " ) )
{
if ( ! rpg_calcLiftTravelDuration . integer ) {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
else {
if ( ent - > s . eventParm < 0 & & lights - > targetname2 ) {
if ( ! Q_stricmp ( lights - > targetname2 , va ( " %s_dn " , ent - > target ) ) ) {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
} else if ( ent - > s . eventParm > 0 & & lights - > targetname2 ) {
if ( ! Q_stricmp ( lights - > targetname2 , va ( " %s_up " , ent - > target ) ) ) {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
} else {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
}
}
}
lights = NULL ;
while ( ( lights = G_Find ( lights , FOFS ( targetname ) , otherLift - > target ) ) ! = NULL )
{
if ( ! Q_stricmp ( lights - > classname , " func_usable " ) )
{
if ( ! rpg_calcLiftTravelDuration . integer ) {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
else {
if ( ent - > s . eventParm < 0 & & lights - > targetname2 ) {
if ( ! Q_stricmp ( lights - > targetname2 , va ( " %s_dn " , otherLift - > target ) ) ) {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
} else if ( ent - > s . eventParm & & lights - > targetname2 ) {
if ( ! Q_stricmp ( lights - > targetname2 , va ( " %s_up " , otherLift - > target ) ) ) {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
} else {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
}
}
}
}
// check for shader remaps
2012-12-14 19:47:08 +00:00
if ( rpg_calcLiftTravelDuration . integer | | level . overrideCalcLiftTravelDuration ) {
2012-08-04 10:54:37 +00:00
if ( ( ent - > truename & & otherLift - > truename ) | | ( ent - > falsename & & otherLift - > falsename ) ) {
f = level . time * 0.001 ;
AddRemap ( ent - > targetShaderName , ent - > targetShaderName , f ) ;
AddRemap ( otherLift - > targetShaderName , otherLift - > targetShaderName , f ) ;
}
trap_SetConfigstring ( CS_SHADERSTATE , BuildShaderStateConfig ( ) ) ;
}
//next phase, teleport player
ent - > nextthink = level . time + ent - > sound1to2 ;
ent - > think = target_turbolift_unlock ;
}
//TiM - we'll have two sets of teleports, so let's re-use this
static void TeleportPlayers ( gentity_t * ent , gentity_t * targetLift , int numEnts , int * touch )
{
int i = 0 ;
gentity_t * player = NULL ;
float dist ;
vec3_t temp ;
vec3_t angles ;
vec3_t newOrigin ;
vec3_t viewAng ;
if ( numEnts < = 0 )
return ;
for ( i = 0 ; i < numEnts ; i + + )
{
player = & g_entities [ touch [ i ] ] ;
if ( ! player - > client )
continue ;
//to teleport them, we need two things. Their distance and angle from the origin
VectorSubtract ( player - > client - > ps . origin , ent - > s . origin , temp ) ;
//distance + angles
dist = VectorLength ( temp ) ;
VectorNormalize ( temp ) ;
vectoangles ( temp , angles ) ;
angles [ YAW ] = AngleNormalize360 ( angles [ YAW ] - ent - > s . angles [ YAW ] ) ;
//now... calc their new origin and view angles
angles [ YAW ] = AngleNormalize360 ( angles [ YAW ] + targetLift - > s . angles [ YAW ] ) ;
AngleVectors ( angles , temp , NULL , NULL ) ;
VectorMA ( targetLift - > s . origin , dist , temp , newOrigin ) ;
VectorCopy ( player - > client - > ps . viewangles , viewAng ) ;
viewAng [ YAW ] = AngleNormalize360 ( viewAng [ YAW ] + ( targetLift - > s . angles [ YAW ] - ent - > s . angles [ YAW ] ) ) ;
TeleportPlayer ( player , newOrigin , viewAng , TP_TURBO ) ;
}
}
static void target_turbolift_TeleportPlayers ( gentity_t * ent )
{
gentity_t * targetLift ;
vec3_t mins , maxs ;
float time ;
//store both sets of data so they can be swapped at the same time
int * liftTouch ;
int * targetLiftTouch ;
int liftNumEnts ;
int targetLiftNumEnts ;
//teleport the players
targetLift = & g_entities [ ent - > count ] ;
if ( ! targetLift ) {
target_turbolift_unlock ( ent ) ;
return ;
}
liftTouch = ( int * ) malloc ( MAX_GENTITIES * sizeof ( int ) ) ;
if ( ! liftTouch ) {
target_turbolift_unlock ( ent ) ;
return ;
}
//scan the turbo region for players
//in the current lift
{
if ( ! ent - > tmpEntity ) {
VectorCopy ( ent - > r . maxs , maxs ) ;
VectorCopy ( ent - > r . mins , mins ) ;
} else {
VectorAdd ( ent - > r . maxs , ent - > s . origin , maxs ) ;
VectorAdd ( ent - > r . mins , ent - > s . origin , mins ) ;
}
liftNumEnts = trap_EntitiesInBox ( mins , maxs , liftTouch , MAX_GENTITIES ) ;
}
targetLiftTouch = ( int * ) malloc ( MAX_GENTITIES * sizeof ( int ) ) ;
if ( ! targetLiftTouch ) {
target_turbolift_unlock ( ent ) ;
free ( liftTouch ) ;
return ;
}
//the target lift
{
if ( ! targetLift - > tmpEntity ) {
VectorCopy ( targetLift - > r . maxs , maxs ) ;
VectorCopy ( targetLift - > r . mins , mins ) ;
} else {
VectorAdd ( targetLift - > r . maxs , targetLift - > s . origin , maxs ) ;
VectorAdd ( targetLift - > r . mins , targetLift - > s . origin , mins ) ;
}
targetLiftNumEnts = trap_EntitiesInBox ( mins , maxs , targetLiftTouch , MAX_GENTITIES ) ;
}
//TiM - Teleport the players from the other target to this one
TeleportPlayers ( targetLift , ent , targetLiftNumEnts , targetLiftTouch ) ;
//TiM - Teleport the main players
TeleportPlayers ( ent , targetLift , liftNumEnts , liftTouch ) ;
if ( rpg_calcLiftTravelDuration . integer ) {
time = targetLift - > health - ent - > health ;
if ( time < 0 )
time * = - 1 ;
time * = rpg_liftDurationModifier . value ;
time * = 1000 ;
ent - > think = target_turbolift_endMove ;
ent - > nextthink = level . time + ( time * 0.5f ) ;
} else {
//first thing's first
ent - > think = target_turbolift_endMove ;
ent - > nextthink = level . time + ( ent - > wait * 0.5f ) ;
}
free ( liftTouch ) ;
free ( targetLiftTouch ) ;
}
static void target_turbolift_startSoundEnd ( gentity_t * ent ) {
ent - > nextthink = - 1 ;
ent - > parent - > r . svFlags & = ~ SVF_NOCLIENT ;
ent - > touched - > r . svFlags & = ~ SVF_NOCLIENT ;
}
static void target_turbolift_startMove ( gentity_t * ent )
{
gentity_t * lights = NULL ;
gentity_t * otherLift = NULL ;
gentity_t * tent = NULL ;
float time = 0 , time2 = 0 ;
float f = 0 ;
otherLift = & g_entities [ ent - > count ] ;
if ( ! otherLift )
{
target_turbolift_unlock ( ent ) ;
return ;
}
//play move sound
if ( rpg_calcLiftTravelDuration . integer ) {
time = time2 = ent - > health - otherLift - > health ;
if ( time < 0 )
time * = - 1 ;
if ( ent - > sound2to1 ) {
if ( rpg_liftDurationModifier . value * 1000 * time > = ent - > distance * 1000 ) {
tent = G_Spawn ( ) ;
tent - > think = target_turbolift_startSoundEnd ;
tent - > nextthink = level . time + ( ent - > distance * 1000 ) ;
tent - > parent = ent ;
tent - > touched = otherLift ;
G_AddEvent ( ent , EV_GENERAL_SOUND , ent - > sound2to1 ) ;
}
} else {
ent - > r . svFlags & = ~ SVF_NOCLIENT ;
otherLift - > r . svFlags & = ~ SVF_NOCLIENT ;
}
} else {
ent - > r . svFlags & = ~ SVF_NOCLIENT ;
otherLift - > r . svFlags & = ~ SVF_NOCLIENT ;
}
//show flashy bits
//find any usables parented to the lift ent, and use them
{
while ( ( lights = G_Find ( lights , FOFS ( targetname ) , ent - > target ) ) ! = NULL )
{
if ( ! Q_stricmp ( lights - > classname , " func_usable " ) )
{
if ( ! rpg_calcLiftTravelDuration . integer ) {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
else {
if ( time2 < 0 & & lights - > targetname2 ) {
if ( ! Q_stricmp ( lights - > targetname2 , va ( " %s_dn " , ent - > target ) ) ) {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
} else if ( time2 > 0 & & lights - > targetname2 ) {
if ( ! Q_stricmp ( lights - > targetname2 , va ( " %s_up " , ent - > target ) ) ) {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
} else {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
}
}
}
lights = NULL ;
while ( ( lights = G_Find ( lights , FOFS ( targetname ) , otherLift - > target ) ) ! = NULL )
{
if ( ! Q_stricmp ( lights - > classname , " func_usable " ) )
{
if ( ! rpg_calcLiftTravelDuration . integer ) {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
else {
if ( time2 < 0 & & lights - > targetname2 ) {
if ( ! Q_stricmp ( lights - > targetname2 , va ( " %s_dn " , otherLift - > target ) ) ) {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse ) ;
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
} else if ( time2 > 0 & & lights - > targetname2 ) {
if ( ! Q_stricmp ( lights - > targetname2 , va ( " %s_up " , otherLift - > target ) ) ) {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
} else {
lights - > use ( lights , lights , ent ) ;
# ifdef G_LUA
if ( lights - > luaUse )
LuaHook_G_EntityUse ( lights - > luaUse , lights - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
}
}
}
}
}
// check for shader remaps
2012-12-14 19:47:08 +00:00
if ( rpg_calcLiftTravelDuration . integer | | level . overrideCalcLiftTravelDuration ) {
2012-08-04 10:54:37 +00:00
if ( time2 < 0 & & ent - > truename & & otherLift - > truename ) {
f = level . time * 0.001 ;
AddRemap ( ent - > targetShaderName , ent - > truename , f ) ;
AddRemap ( otherLift - > targetShaderName , otherLift - > truename , f ) ;
} else if ( time2 > 0 & & ent - > falsename & & otherLift - > falsename ) {
f = level . time * 0.001 ;
AddRemap ( ent - > targetShaderName , ent - > falsename , f ) ;
AddRemap ( otherLift - > targetShaderName , otherLift - > falsename , f ) ;
}
trap_SetConfigstring ( CS_SHADERSTATE , BuildShaderStateConfig ( ) ) ;
}
if ( rpg_calcLiftTravelDuration . integer ) {
ent - > s . eventParm = time2 ;
time * = rpg_liftDurationModifier . value ;
time * = 1000 ;
ent - > s . time2 = level . time + time ;
otherLift - > s . time2 = level . time + time ;
ent - > nextthink = level . time + ( time * 0.5f ) ;
ent - > think = target_turbolift_TeleportPlayers ;
} else {
//sent to the client for client-side rotation
ent - > s . time2 = level . time + ent - > wait ;
otherLift - > s . time2 = level . time + ent - > wait ;
//next phase, teleport player
ent - > nextthink = level . time + ( ent - > wait * 0.5f ) ;
ent - > think = target_turbolift_TeleportPlayers ;
}
}
static void target_turbolift_shutDoors ( gentity_t * ent )
{
gentity_t * door = NULL ;
gentity_t * otherLift = NULL ;
otherLift = & g_entities [ ent - > count ] ;
if ( ! otherLift )
{
target_turbolift_unlock ( ent ) ;
return ;
}
while ( ( door = G_Find ( door , FOFS ( targetname ) , ent - > target ) ) ! = NULL )
{
if ( ! Q_stricmp ( door - > classname , " func_door " ) )
{
if ( door - > moverState ! = MOVER_POS1 ) {
ent - > nextthink = level . time + 500 ;
return ;
}
}
}
door = NULL ;
while ( ( door = G_Find ( door , FOFS ( targetname ) , otherLift - > target ) ) ! = NULL )
{
if ( ! Q_stricmp ( door - > classname , " func_door " ) )
{
if ( door - > moverState ! = MOVER_POS1 ) {
ent - > nextthink = level . time + 500 ;
return ;
}
}
}
//start phase 3
ent - > think = target_turbolift_startMove ;
ent - > nextthink = level . time + FRAMETIME ;
}
void target_turbolift_start ( gentity_t * self )
{
gentity_t * otherLift ;
//get target deck number lift entity
otherLift = & g_entities [ self - > count ] ;
if ( ! otherLift )
{
target_turbolift_unlock ( self ) ;
return ;
}
//phase 1 - lock turbolift doors
//lock the doors on both lifts
{
gentity_t * door = NULL ;
while ( ( door = G_Find ( door , FOFS ( targetname ) , self - > target ) ) ! = NULL )
{
if ( ! Q_stricmp ( door - > classname , " func_door " ) )
{
door - > flags | = FL_CLAMPED ;
if ( door - > moverState ! = MOVER_POS1 )
{
door - > nextthink = level . time ;
}
}
}
door = NULL ;
while ( ( door = G_Find ( door , FOFS ( targetname ) , otherLift - > target ) ) ! = NULL )
{
if ( ! Q_stricmp ( door - > classname , " func_door " ) )
{
door - > flags | = FL_CLAMPED ;
if ( door - > moverState ! = MOVER_POS1 )
{
door - > nextthink = level . time ;
}
}
}
}
//phase 2 - wait until both doors are shut
self - > think = target_turbolift_shutDoors ;
self - > nextthink = level . time + 500 ;
}
static void target_turbolift_use ( gentity_t * self , gentity_t * other , gentity_t * activator )
{
if ( ! Q_stricmp ( self - > swapname , activator - > target ) ) {
if ( self - > soundPos1 )
G_AddEvent ( self , EV_GENERAL_SOUND , self - > soundPos1 ) ;
self - > flags ^ = FL_LOCKED ;
}
if ( self - > flags & FL_LOCKED ) return ;
if ( self - > count > 0 )
{
trap_SendServerCommand ( activator - g_entities , " print \" Unable to comply. The lift is currently in use. \n \" " ) ;
return ;
}
2012-12-12 15:19:02 +00:00
trap_SendServerCommand ( activator - g_entities , va ( " lift %d " , self - > health ) ) ;
2012-08-04 10:54:37 +00:00
}
extern void BG_LanguageFilename ( char * baseName , char * baseExtension , char * finalName ) ;
/*
QUAKED target_turbolift ( .5 .5 .5 ) ? x x x x x x x x OFFLINE
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
Turbolifts are delayed teleporters that send players between
each other , maintaining their view and position so the transition is seamless .
If you target this entity with a func_usable , upon activating that useable ,
a menu will appear to select decks . If you target any useables with this
entity , they ' ll be triggered when the sequence starts ( ie scrolling light texture brushes ) .
If rpg_calcLiftTravelDuration is set to one it is possible to have two usables targeted , one for the
up and one for the down driection in order to use this set targetname2 of those to
< targetname > _up and < targetname > _dn .
If you target any doors with this entity , they will shut and lock for this sequence .
For the angles , the entity ' s angle must be aimed at the main set of doors to the lift area .
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
1 - 128 : X - Unknown , do not use .
256 : OFFLINE - Turbolift is offline at start
- - - - - KEYS - - - - -
" deck " - which deck number this is ( You can have multiple lifts of the same deck . Entity fails spawn if not specified )
" deckName " - name of the main features on this deck ( Appears in the deck menu , defaults to ' Unknown ' )
use either this or a < mapname > . turbolift - file to store the strings , not both simultainously
" wait " - number of seconds to wait until teleporting the players ( 1000 = 1 second , default 3000 )
" soundLoop " - looping sound that plays in the wait period ( Defaults to EF SP ' s sound . ' * ' for none )
" soundEnd " - sound that plays as the wait period ends . ( Defaults to EF SP ' s sound . ' * ' for none )
" soundStart - sound that plays when the lift starts moving
" soundStartLength " - how long the start sound is in seconds
" soundDeactivate " - sound to play if player tries to use an deactivated turbolift
" waitEnd " - how long to wait from the lift stopping to the doors opening ( default 1000 )
" swapname " - toggles turbolift on / off
" targetShaderName " - lights off shader
" falsename " - lights up
" truename " - lights down
2012-12-13 15:31:11 +00:00
" override " - if set to 1 overrides rpg_calcLiftTravelDuration
2012-11-27 21:57:55 +00:00
- - - - - LUA - - - - -
Retrofit :
Turbolifts are a good thing to retrofit , however they have 2 requirements :
- a Transporter based turbolift ( seamless transportation , does not work wit func_train )
- at least 1 usable at any turbolift location
If those are fuffilled you can use the following code at level init to set up the turbolift .
( this is from enterprise - e - v2 and uses the outdated SetKeyValue - Command . Use Set < key > instead )
game . Print ( " --Deck 1 ... " ) ;
game . Print ( " ---redirecting usables ... " ) ;
ent = entity . FindBModel ( 90 ) ;
ent : SetKeyValue ( " target " , " tld1 " ) ;
ent : SetKeyValue ( " luaUse " , " turbosound " ) ;
ent = entity . FindBModel ( 86 ) ;
ent : SetKeyValue ( " target " , " tld1 " ) ;
ent : SetKeyValue ( " luaUse " , " turbosound " ) ;
ent = entity . FindBModel ( 87 ) ;
ent : SetKeyValue ( " target " , " tld1 " ) ;
ent : SetKeyValue ( " luaUse " , " turbosound " ) ;
ent = entity . FindBModel ( 167 ) ;
ent : SetKeyValue ( " target " , " tld1 " ) ;
ent : SetKeyValue ( " luaUse " , " turbosound " ) ;
ent = entity . FindBModel ( 88 ) ;
ent : SetKeyValue ( " target " , " tld1 " ) ;
ent : SetKeyValue ( " luaUse " , " turbosound " ) ;
ent = entity . FindBModel ( 89 ) ;
ent : SetKeyValue ( " target " , " tld1 " ) ;
ent : SetKeyValue ( " luaUse " , " turbosound " ) ;
game . Print ( " ---renaming doors ... " ) ;
ent = entity . FindBModel ( 7 ) ;
ent : SetKeyValue ( " targetname " , " tld1doors " ) ;
ent = entity . FindBModel ( 8 ) ;
ent : SetKeyValue ( " targetname " , " tld1doors " ) ;
game . Print ( " ---Adding turbolift ... " ) ;
ent = entity . Spawn ( ) ;
ent . SetupTrigger ( ent , 144 , 100 , 98 ) ;
ent : SetKeyValue ( " classname " , " target_turbolift " ) ;
ent : SetKeyValue ( " targetname " , " tld1 " ) ;
ent : SetKeyValue ( " target " , " tld1doors " ) ;
ent : SetKeyValue ( " health " , " 1 " ) ;
ent : SetKeyValue ( " wait " , 3000 ) ;
entity . CallSpawn ( ent ) ;
mover . SetPosition ( ent , - 2976 , 8028 , 887 ) ;
mover . SetAngles ( ent , 0 , 270 , 0 ) ;
Turbolift descriptions have to be added in via < mapname > . turbolift - file .
You may also add in a sound to the usable opening the UI . This is described in func_usable .
2012-08-04 10:54:37 +00:00
*/
void SP_target_turbolift ( gentity_t * self )
{
int i ;
char * loopSound ;
char * endSound ;
char * idleSound ;
char * startSound ;
char * deactSound ;
int len ;
fileHandle_t f ;
char fileRoute [ MAX_QPATH ] ;
char mapRoute [ MAX_QPATH ] ;
char serverInfo [ MAX_TOKEN_CHARS ] ;
2013-04-12 23:34:37 +00:00
if ( self = = NULL ) {
return ;
}
2012-08-04 10:54:37 +00:00
//cache the moving sounds
G_SpawnString ( " soundLoop " , " sound/movers/plats/turbomove.wav " , & loopSound ) ;
G_SpawnString ( " soundEnd " , " sound/movers/plats/turbostop.wav " , & endSound ) ;
G_SpawnString ( " soundIdle " , " 100 " , & idleSound ) ;
G_SpawnString ( " soundStart " , " 100 " , & startSound ) ;
G_SpawnFloat ( " soundStartLength " , " 100 " , & self - > distance ) ;
G_SpawnString ( " soundDeactivate " , " 100 " , & deactSound ) ;
self - > s . loopSound = G_SoundIndex ( loopSound ) ; //looping sound
self - > s . otherEntityNum2 = G_SoundIndex ( endSound ) ; //End Phase sound
self - > n00bCount = G_SoundIndex ( idleSound ) ;
self - > sound2to1 = G_SoundIndex ( startSound ) ;
self - > soundPos1 = G_SoundIndex ( deactSound ) ;
if ( self - > spawnflags & 512 )
self - > flags ^ = FL_LOCKED ;
//get deck num
G_SpawnInt ( " deck " , " 0 " , & i ) ;
//kill the ent if it isn't valid
if ( i < = 0 & & ! ( self - > tmpEntity ) )
{
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] A turbolift entity does not have a valid deck number! \n " ) ; ) ;
G_FreeEntity ( self ) ;
return ;
}
if ( ! self - > tmpEntity )
self - > health = i ;
self - > count = 0 ; //target/targetted lift
G_SpawnFloat ( " wait " , " 3000 " , & self - > wait ) ;
G_SpawnInt ( " waitEnd " , " 1000 " , & self - > sound1to2 ) ;
2012-12-13 15:31:11 +00:00
G_SpawnInt ( " override " , " 0 " , & i ) ;
if ( i ) {
level . overrideCalcLiftTravelDuration = i ;
}
2012-08-04 10:54:37 +00:00
if ( ! self - > tmpEntity )
trap_SetBrushModel ( self , self - > model ) ;
self - > r . contents = CONTENTS_TRIGGER ; // replaces the -1 from trap_SetBrushModel
self - > r . svFlags = SVF_NOCLIENT ;
self - > s . eType = ET_TURBOLIFT ; //TiM - Client-side sound FX
trap_LinkEntity ( self ) ;
VectorCopy ( self - > r . mins , self - > s . angles2 ) ;
VectorCopy ( self - > r . maxs , self - > s . origin2 ) ;
VectorAverage ( self - > r . mins , self - > r . maxs , self - > s . origin ) ;
G_SetOrigin ( self , self - > s . origin ) ;
//insert code to worry about deck name later
self - > use = target_turbolift_use ;
if ( level . numDecks > = MAX_DECKS )
return ;
//get the map name out of the server data
trap_GetServerinfo ( serverInfo , sizeof ( serverInfo ) ) ;
//TiM - Configure the deck number and description into a config string
Com_sprintf ( mapRoute , sizeof ( mapRoute ) , " maps/%s " , Info_ValueForKey ( serverInfo , " mapname " ) ) ;
BG_LanguageFilename ( mapRoute , " turbolift " , fileRoute ) ;
//Check for a turbolift cfg
len = trap_FS_FOpenFile ( fileRoute , & f , FS_READ ) ;
trap_FS_FCloseFile ( f ) ;
//if no file was found, resort to the string system.
//BUT! we shouldn't rely on this system if we can
if ( len < = 0 )
{
char infoString [ MAX_TOKEN_CHARS ] ;
char * deckNamePtr ;
char deckName [ 57 ] ;
gentity_t * prevDeck = NULL ;
qboolean deckFound = qfalse ;
while ( ( prevDeck = G_Find ( prevDeck , FOFS ( classname ) , " target_turbolift " ) ) ! = NULL )
{
if ( prevDeck ! = self & & prevDeck - > health = = self - > health )
{
deckFound = qtrue ;
break ;
}
}
//this deck number hasn't been registered b4
if ( ! deckFound )
{
G_SpawnString ( " deckName " , " Unknown " , & deckNamePtr ) ;
Q_strncpyz ( deckName , deckNamePtr , sizeof ( deckName ) ) ;
trap_GetConfigstring ( CS_TURBOLIFT_DATA , infoString , sizeof ( infoString ) ) ;
if ( ! infoString [ 0 ] )
{
Com_sprintf ( infoString , sizeof ( infoString ) , " d%i \\ %i \\ n%i \\ %s \\ " , level . numDecks , self - > health , level . numDecks , deckName ) ;
}
else
{
Com_sprintf ( infoString , sizeof ( infoString ) , " %sd%i \\ %i \\ n%i \\ %s \\ " , infoString , level . numDecks , self - > health , level . numDecks , deckName ) ;
}
trap_SetConfigstring ( CS_TURBOLIFT_DATA , infoString ) ;
level . numDecks + + ;
}
}
level . numBrushEnts + + ;
}
/* ==============
END MODIFICATION
= = = = = = = = = = = = = = = */
//RPG-X | GSIO01 | 08/05/2009
/*QUAKED target_doorlock (1 0 0) (-8 -8 -8) (8 8 8) PRIVATE
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
Locks / Unlocks a door .
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
1 : PRIVATE - if set , lockMsg / unlockMsg are only printed for activator
2012-08-04 10:54:37 +00:00
2012-11-27 21:57:55 +00:00
- - - - - KEYS - - - - -
" target " - breakable to repair ( either it ' s targetname or it ' s targetname2 )
" lockMsg " - message printed if door gets locked
" unlockMsg " - message printed if door gets unlocked
2012-08-04 10:54:37 +00:00
*/
void target_doorLock_use ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
gentity_t * target = NULL ;
target = G_Find ( NULL , FOFS ( targetname2 ) , ent - > target ) ;
if ( ! target )
return ;
if ( ! ( target - > flags & FL_LOCKED ) ) {
if ( ent - > swapname ) {
if ( ( ent - > spawnflags & 1 ) & & activator & & activator - > client )
trap_SendServerCommand ( activator - g_entities , va ( " servermsg %s " , ent - > swapname ) ) ;
else
trap_SendServerCommand ( - 1 , va ( " servermsg %s " , ent - > swapname ) ) ;
}
}
else
{
if ( ent - > truename ) {
if ( ( ent - > spawnflags & 1 ) & & activator & & activator - > client )
trap_SendServerCommand ( activator - g_entities , va ( " servermsg %s " , ent - > truename ) ) ;
else
trap_SendServerCommand ( - 1 , va ( " servermsg %s " , ent - > truename ) ) ;
}
}
if ( ! Q_stricmp ( target - > classname , " func_door " ) | | ! Q_stricmp ( target - > classname , " func_door_rotating " ) ) {
target - > flags ^ = FL_LOCKED ;
} else {
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] Target %s of target_doorlock at %s is not a door! \n " , ent - > target , vtos ( ent - > s . origin ) ) ; ) ;
return ;
}
}
void SP_target_doorLock ( gentity_t * ent ) {
char * temp ;
if ( ! ent - > target ) {
2012-09-10 10:55:24 +00:00
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] target_doorlock at %s without target! \n " , vtos ( ent - > s . origin ) ) ; ) ;
2012-08-04 10:54:37 +00:00
G_FreeEntity ( ent ) ;
return ;
}
G_SpawnString ( " lockMsg " , " " , & temp ) ;
ent - > swapname = G_NewString ( temp ) ; // ent->swapnmae = temp or strcpy(...) screws everthing up
G_SpawnString ( " unlockMsg " , " " , & temp ) ;
ent - > truename = G_NewString ( temp ) ;
ent - > use = target_doorLock_use ;
// don't need to send this to clients
ent - > r . svFlags & = SVF_NOCLIENT ;
trap_LinkEntity ( ent ) ;
}
//RPG-X | GSIO01 | 11/05/2009 | MOD START
/*QUAKED target_alert (1 0 0) (-8 -8 -8) (8 8 8) SOUND_TOGGLE SOUND_OFF
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
This entity acts like 3 - Alert - Conditions scripts .
Any of the func_usables that are used as buttons must have the NO_ACTIVATOR spawnflag .
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
1 : SOUND_TOGGLE - if set the alert sound can be toggled on / off by using the alerts trigger again .
2 : SOUND_OFF - if SOUND_TOGGLE is set , the alert will be silent at beginning
- - - - - KEYS - - - - -
" greenname " - the trigger for green alert should target this
" yellowname " - the trigger for yellow alert should target this
" redname " - the trigger for red alert should target this
" bluename " - the trigger for blue alert should target this
" greentarget " - anything that should be toggled when activating green alert
" yellowtarget " - anything that should be toggled when activating yellow alert
" redtarget " - anything that should be toggled when activating red alert
" bluetarget " - anything that should be toggled when activating blue alert
" greensnd " - targetname of target_speaker with sound for green alert
" yellowsnd " - targetname of target_speaker with sound for yellow alert
" redsnd " - targetname of target_speaker with sound for red alert
" bluesnd " - targetname of target_speaker with sound for blue alert
shader remapping :
" greenshader " - shadername of condition green
" yellowshader " - shadername of condition yellow
" redshader " - shadername of condition red
" blueshader " - shadername of condition blue
2012-08-04 10:54:37 +00:00
You can remap multiple shaders by separating them with \ n .
Example : " greenshader " " textures/alert/green1 \n textures/alert/green2 "
*/
2012-12-14 19:47:08 +00:00
target_alert_Shaders_s alertShaders ;
2012-08-04 10:54:37 +00:00
void target_alert_remapShaders ( int target_condition ) {
float f = 0 ;
int i ;
switch ( target_condition ) {
case 1 : // yellow
for ( i = 0 ; i < alertShaders . numShaders ; i + + ) {
f = level . time * 0.001 ;
if ( ! alertShaders . greenShaders [ i ] | | ! alertShaders . yellowShaders [ i ] ) break ;
AddRemap ( alertShaders . greenShaders [ i ] , alertShaders . yellowShaders [ i ] , f ) ;
}
trap_SetConfigstring ( CS_SHADERSTATE , BuildShaderStateConfig ( ) ) ;
break ;
case 2 : // red
for ( i = 0 ; i < alertShaders . numShaders ; i + + ) {
f = level . time * 0.001 ;
if ( ! alertShaders . greenShaders [ i ] | | ! alertShaders . redShaders [ i ] ) break ;
AddRemap ( alertShaders . greenShaders [ i ] , alertShaders . redShaders [ i ] , f ) ;
}
trap_SetConfigstring ( CS_SHADERSTATE , BuildShaderStateConfig ( ) ) ;
break ;
case 3 : // blue
for ( i = 0 ; i < alertShaders . numShaders ; i + + ) {
f = level . time * 0.001 ;
if ( ! alertShaders . greenShaders [ i ] | | ! alertShaders . blueShaders [ i ] ) break ;
AddRemap ( alertShaders . greenShaders [ i ] , alertShaders . blueShaders [ i ] , f ) ;
}
trap_SetConfigstring ( CS_SHADERSTATE , BuildShaderStateConfig ( ) ) ;
break ;
case 0 : // green
default :
for ( i = 0 ; i < alertShaders . numShaders ; i + + ) {
f = level . time * 0.001 ;
if ( ! alertShaders . greenShaders [ i ] ) break ;
AddRemap ( alertShaders . greenShaders [ i ] , alertShaders . greenShaders [ i ] , f ) ;
}
trap_SetConfigstring ( CS_SHADERSTATE , BuildShaderStateConfig ( ) ) ;
break ;
}
}
void target_alert_use ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
2012-10-15 11:05:45 +00:00
gentity_t * healthEnt ;
2012-08-04 10:54:37 +00:00
if ( ! activator ) {
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] target_alert_use called with NULL activator. \n " ) ; ) ;
return ;
}
if ( ! Q_stricmp ( activator - > target , ent - > swapname ) ) {
if ( ent - > damage = = 0 ) {
if ( ent - > spawnflags & 1 ) {
ent - > health = ! ent - > health ;
ent - > target = ent - > greensound ;
G_UseTargets ( ent , ent ) ;
}
} else {
switch ( ent - > damage ) {
case 1 : // yellow
if ( ent - > health ) {
ent - > target = ent - > yellowsound ;
G_UseTargets ( ent , ent ) ;
ent - > health = ! ent - > health ;
}
ent - > target = ent - > falsetarget ;
G_UseTargets ( ent , ent ) ;
break ;
case 2 : // red
if ( ent - > health ) {
ent - > target = ent - > redsound ;
G_UseTargets ( ent , ent ) ;
ent - > health = ! ent - > health ;
}
ent - > target = ent - > paintarget ;
G_UseTargets ( ent , ent ) ;
break ;
case 3 : // blue
if ( ent - > health ) {
ent - > target = ent - > bluesound ;
G_UseTargets ( ent , ent ) ;
ent - > health = ! ent - > health ;
}
ent - > target = ent - > targetname2 ;
G_UseTargets ( ent , ent ) ;
break ;
}
if ( ! ent - > spawnflags ) {
ent - > target = ent - > greensound ;
G_UseTargets ( ent , ent ) ;
} else if ( ent - > spawnflags & 2 ) {
ent - > health = 0 ;
} else {
if ( ent - > spawnflags ) {
ent - > target = ent - > greensound ;
G_UseTargets ( ent , ent ) ;
ent - > health = 1 ;
}
}
target_alert_remapShaders ( 0 ) ;
ent - > target = ent - > truetarget ;
G_UseTargets ( ent , ent ) ;
ent - > damage = 0 ;
}
} else if ( ! Q_stricmp ( activator - > target , ent - > truename ) ) {
if ( ent - > damage = = 1 ) {
if ( ent - > spawnflags & 1 ) {
ent - > health = ! ent - > health ;
ent - > target = ent - > yellowsound ;
G_UseTargets ( ent , ent ) ;
}
} else {
switch ( ent - > damage ) {
case 0 : // green
if ( ent - > health ) {
ent - > target = ent - > greensound ;
G_UseTargets ( ent , ent ) ;
ent - > health = ! ent - > health ;
}
ent - > target = ent - > truetarget ;
G_UseTargets ( ent , ent ) ;
break ;
case 2 : // red
if ( ent - > health ) {
ent - > target = ent - > redsound ;
G_UseTargets ( ent , ent ) ;
ent - > health = ! ent - > health ;
}
ent - > target = ent - > paintarget ;
G_UseTargets ( ent , ent ) ;
break ;
case 3 : // blue
if ( ent - > health ) {
ent - > target = ent - > bluesound ;
G_UseTargets ( ent , ent ) ;
ent - > health = ! ent - > health ;
}
ent - > target = ent - > targetname2 ;
G_UseTargets ( ent , ent ) ;
break ;
}
if ( ! ent - > spawnflags ) {
ent - > target = ent - > yellowsound ;
G_UseTargets ( ent , ent ) ;
} else if ( ent - > spawnflags & 2 ) {
ent - > health = 0 ;
} else {
if ( ent - > spawnflags ) {
ent - > target = ent - > yellowsound ;
G_UseTargets ( ent , ent ) ;
ent - > health = 1 ;
}
}
target_alert_remapShaders ( 1 ) ;
ent - > target = ent - > falsetarget ;
G_UseTargets ( ent , ent ) ;
ent - > damage = 1 ;
}
} else if ( ! Q_stricmp ( activator - > target , ent - > falsename ) ) {
if ( ent - > damage = = 2 ) {
if ( ent - > spawnflags & 1 ) {
ent - > health = ! ent - > health ;
ent - > target = ent - > redsound ;
G_UseTargets ( ent , ent ) ;
}
} else {
switch ( ent - > damage ) {
case 0 : // green
if ( ent - > health ) {
ent - > target = ent - > greensound ;
G_UseTargets ( ent , ent ) ;
ent - > health = ! ent - > health ;
}
ent - > target = ent - > truetarget ;
G_UseTargets ( ent , ent ) ;
break ;
case 1 : // ryellow
if ( ent - > health ) {
ent - > target = ent - > yellowsound ;
G_UseTargets ( ent , ent ) ;
ent - > health = ! ent - > health ;
}
ent - > target = ent - > falsetarget ;
G_UseTargets ( ent , ent ) ;
break ;
case 3 : // blue
if ( ent - > health ) {
ent - > target = ent - > bluesound ;
G_UseTargets ( ent , ent ) ;
ent - > health = ! ent - > health ;
}
ent - > target = ent - > targetname2 ;
G_UseTargets ( ent , ent ) ;
break ;
}
if ( ! ent - > spawnflags ) {
ent - > target = ent - > redsound ;
G_UseTargets ( ent , ent ) ;
} else if ( ent - > spawnflags & 2 ) {
ent - > health = 0 ;
} else {
if ( ent - > spawnflags ) {
ent - > target = ent - > redsound ;
G_UseTargets ( ent , ent ) ;
ent - > health = 1 ;
}
}
target_alert_remapShaders ( 2 ) ;
ent - > target = ent - > paintarget ;
G_UseTargets ( ent , ent ) ;
ent - > damage = 2 ;
}
} if ( ! Q_stricmp ( activator - > target , ent - > bluename ) ) {
if ( ent - > damage = = 3 ) {
if ( ent - > spawnflags & 1 ) {
ent - > health = ! ent - > health ;
ent - > target = ent - > bluesound ;
G_UseTargets ( ent , ent ) ;
}
} else {
switch ( ent - > damage ) {
case 0 : // green
if ( ent - > health ) {
ent - > target = ent - > greensound ;
G_UseTargets ( ent , ent ) ;
ent - > health = ! ent - > health ;
}
ent - > target = ent - > truetarget ;
G_UseTargets ( ent , ent ) ;
break ;
case 1 : // yellow
if ( ent - > health ) {
ent - > target = ent - > yellowsound ;
G_UseTargets ( ent , ent ) ;
ent - > health = ! ent - > health ;
}
ent - > target = ent - > falsetarget ;
G_UseTargets ( ent , ent ) ;
break ;
case 2 : // red
if ( ent - > health ) {
ent - > target = ent - > redsound ;
G_UseTargets ( ent , ent ) ;
ent - > health = ! ent - > health ;
}
ent - > target = ent - > paintarget ;
G_UseTargets ( ent , ent ) ;
break ;
}
if ( ! ent - > spawnflags ) {
ent - > target = ent - > bluesound ;
G_UseTargets ( ent , ent ) ;
} else if ( ent - > spawnflags & 2 ) {
ent - > health = 0 ;
} else {
if ( ent - > spawnflags ) {
ent - > target = ent - > bluesound ;
G_UseTargets ( ent , ent ) ;
ent - > health = 1 ;
}
}
target_alert_remapShaders ( 3 ) ;
ent - > target = ent - > targetname2 ;
G_UseTargets ( ent , ent ) ;
ent - > damage = 3 ;
}
}
2012-10-15 11:05:45 +00:00
//Refresh health ent if it has interconnectivity with target_alert
healthEnt = G_Find ( NULL , FOFS ( classname ) , " target_shiphealth " ) ;
if ( healthEnt ) {
if ( ! Q_stricmp ( healthEnt - > falsename , ent - > falsename ) ) {
if ( healthEnt - > splashDamage = = 0 | | healthEnt - > splashDamage = = 1 ) {
if ( ent - > damage = = 0 )
healthEnt - > splashDamage = 0 ;
else
healthEnt - > splashDamage = 1 ;
}
}
}
2012-08-04 10:54:37 +00:00
// Free activator if no classname <-- alert command
if ( ! activator - > classname )
G_FreeEntity ( activator ) ;
}
void target_alert_parseShaders ( gentity_t * ent ) {
char buffer [ BIG_INFO_STRING ] ;
char * txtPtr ;
char * token ;
int currentNum = 0 ;
alertShaders . numShaders = 0 ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
// condition green shaders
if ( ! ent - > message ) return ;
Q_strncpyz ( buffer , ent - > message , strlen ( ent - > message ) ) ;
txtPtr = buffer ;
token = COM_Parse ( & txtPtr ) ;
while ( 1 ) {
if ( ! token [ 0 ] ) break ;
alertShaders . greenShaders [ alertShaders . numShaders ] = G_NewString ( token ) ;
alertShaders . numShaders + + ;
if ( alertShaders . numShaders > 9 ) break ;
token = COM_Parse ( & txtPtr ) ;
}
// condition red shaders
if ( ent - > model ) {
Q_strncpyz ( buffer , ent - > model , strlen ( ent - > model ) ) ;
txtPtr = buffer ;
token = COM_Parse ( & txtPtr ) ;
while ( 1 ) {
if ( ! token [ 0 ] ) break ;
alertShaders . redShaders [ currentNum ] = G_NewString ( token ) ;
currentNum + + ;
if ( currentNum > 9 ) break ;
token = COM_Parse ( & txtPtr ) ;
}
if ( currentNum < alertShaders . numShaders | | currentNum > alertShaders . numShaders ) {
G_Printf ( S_COLOR_RED " ERROR - target_alert: number of red shaders(%i) does not equal number of green shaders(%i)! \n " , currentNum , alertShaders . numShaders ) ;
}
currentNum = 0 ;
}
// condition blue shaders
if ( ent - > model2 ) {
Q_strncpyz ( buffer , ent - > model2 , strlen ( ent - > model2 ) ) ;
txtPtr = buffer ;
token = COM_Parse ( & txtPtr ) ;
while ( 1 ) {
if ( ! token [ 0 ] ) break ;
alertShaders . blueShaders [ currentNum ] = G_NewString ( token ) ;
currentNum + + ;
if ( currentNum > 9 ) break ;
token = COM_Parse ( & txtPtr ) ;
}
if ( currentNum < alertShaders . numShaders | | currentNum > alertShaders . numShaders ) {
G_Printf ( S_COLOR_RED " ERROR - target_alert: number of blue shaders(%i) does not equal number of green shaders(%i)! \n " , currentNum , alertShaders . numShaders ) ;
}
currentNum = 0 ;
}
// condition yellow shaders
if ( ent - > team ) {
Q_strncpyz ( buffer , ent - > team , strlen ( ent - > team ) ) ;
txtPtr = buffer ;
token = COM_Parse ( & txtPtr ) ;
while ( 1 ) {
if ( ! token [ 0 ] ) break ;
alertShaders . yellowShaders [ currentNum ] = G_NewString ( token ) ;
currentNum + + ;
if ( currentNum > 9 ) break ;
token = COM_Parse ( & txtPtr ) ;
}
if ( currentNum < alertShaders . numShaders | | currentNum > alertShaders . numShaders ) {
G_Printf ( S_COLOR_RED " ERROR - target_alert: number of yellow shaders(%i) does not equal number of green shaders(%i)! \n " , currentNum , alertShaders . numShaders ) ;
}
}
}
void SP_target_alert ( gentity_t * ent ) {
char * temp ;
2012-11-12 21:02:07 +00:00
2012-08-04 10:54:37 +00:00
G_SpawnString ( " greenname " , " " , & temp ) ;
ent - > swapname = G_NewString ( temp ) ;
G_SpawnString ( " yellowname " , " " , & temp ) ;
ent - > truename = G_NewString ( temp ) ;
G_SpawnString ( " redname " , " " , & temp ) ;
ent - > falsename = G_NewString ( temp ) ;
G_SpawnString ( " greentarget " , " " , & temp ) ;
ent - > truetarget = G_NewString ( temp ) ;
G_SpawnString ( " yellowtarget " , " " , & temp ) ;
ent - > falsetarget = G_NewString ( temp ) ;
G_SpawnString ( " redtarget " , " " , & temp ) ;
ent - > paintarget = G_NewString ( temp ) ;
G_SpawnString ( " bluetarget " , " " , & temp ) ;
ent - > targetname2 = G_NewString ( temp ) ;
if ( G_SpawnString ( " greenshader " , " " , & temp ) )
ent - > message = G_NewString ( temp ) ;
if ( G_SpawnString ( " yellowshader " , " " , & temp ) )
ent - > team = G_NewString ( temp ) ;
if ( G_SpawnString ( " redshader " , " " , & temp ) )
ent - > model = G_NewString ( temp ) ;
if ( G_SpawnString ( " blueshader " , " " , & temp ) )
ent - > model2 = G_NewString ( temp ) ;
target_alert_parseShaders ( ent ) ;
if ( ! ent - > swapname | | ! ent - > truename | | ! ent - > falsename | | ! ent - > bluename | |
! ent - > truetarget | | ! ent - > falsetarget | | ! ent - > paintarget | | ! ent - > targetname2 ) {
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] One or more needed keys for target_alert at %s where not set. \n " , vtos ( ent - > s . origin ) ) ; ) ;
return ;
}
if ( ! ent - > wait )
ent - > wait = 1000 ;
else
ent - > wait * = 1000 ;
ent - > use = target_alert_use ;
ent - > damage = 0 ;
ent - > health = ! ( ent - > spawnflags & 2 ) ;
// don't need to send this to clients
ent - > r . svFlags & = SVF_NOCLIENT ;
trap_LinkEntity ( ent ) ;
}
//RPG-X | GSIO01 | 11/05/2009 | MOD END
//RPG-X | GSIO01 | 19/05/2009 | MOD START
/*QUAKED target_warp (1 0 0) (-8 -8 -8) (8 8 8) START_ON START_EJECTED START_WARP SELF
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
An entity that manages warp and warpcore .
Any func_usable using this must have NO_ACTIVATOR flag .
Any target_relay , target_delay , or target_boolean using this must have SELF flag .
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
1 : START_ON - If set , warpcore is on at start
2 : START_EJECTED - If set , core is ejected at start
4 : START_WARP - ship is on warp at start
8 : SELF - use this for any entity that is called by sth . other than it ' s targetname ( e . g . swapmname )
- - - - - KEYS - - - - -
" swapWarp " - targetname to toggle warp
" swapCoreState " - targetname to toggle core on / off state
" swapCoreEject " - targetname to toggle core ejected state
" warpTarget " - target to fire when going to warp
" core " - target core ( func_train )
" coreSwap " - target for visibility swap ( need SELF - flag for this )
" wait " - time before warp can be toggled again after retrieving the core ( seconds )
" greensnd " - target_speaker with warp in sound
" yellowsnd " - target_speaker with warp out sound
" redsnd " - target_speaker with core off sound
" bluesnd " - target_speaker with core on sound
" soundDeactivate " - sound to play if going to warp but core is deactivated / ejected
2012-08-04 10:54:37 +00:00
*/
void target_warp_use ( gentity_t * ent , gentity_t * other , gentity_t * activator ) ;
void target_warp_reactivate ( gentity_t * ent ) {
ent - > use = target_warp_use ;
ent - > nextthink = - 1 ;
}
void target_warp_use ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
int i ;
qboolean first = qtrue ;
gentity_t * target ;
if ( ! activator ) {
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] target_warp_use called with NULL activator! \n " ) ; ) ;
return ;
}
// swapWarp
if ( ! Q_stricmp ( activator - > target , ent - > truename ) ) {
if ( ent - > n00bCount ) {
ent - > target = ent - > truetarget ;
G_UseTargets ( ent , activator ) ;
ent - > n00bCount = 0 ;
ent - > target = ent - > yellowsound ;
G_UseTargets ( ent , activator ) ;
}
for ( i = 0 ; i < MAX_GENTITIES ; i + + ) {
if ( ! & g_entities [ i ] ) continue ;
if ( Q_stricmp ( g_entities [ i ] . classname , " func_train " ) & & ! Q_stricmp ( g_entities [ i ] . swapname , ent - > bluename ) ) {
target = & g_entities [ i ] ;
if ( ! target ) continue ;
if ( ent - > spawnflags & 4 ) {
target - > use ( target , ent , ent ) ;
# ifdef G_LUA
if ( target - > luaUse )
LuaHook_G_EntityUse ( target - > luaUse , target - g_entities , ent - g_entities , ent - g_entities ) ;
# endif
} else {
target - > use ( target , ent , activator ) ;
# ifdef G_LUA
if ( target - > luaUse )
LuaHook_G_EntityUse ( target - > luaUse , target - g_entities , ent - g_entities , activator - g_entities ) ;
# endif
}
} else if ( ! Q_stricmp ( g_entities [ i ] . classname , " func_train " ) & & ! Q_stricmp ( g_entities [ i ] . swapname , ent - > bluename ) ) {
target = & g_entities [ i ] ;
if ( ! target ) continue ;
if ( target - > count = = 1 ) {
target - > s . solid = 0 ;
target - > r . contents = 0 ;
target - > clipmask = 0 ;
target - > r . svFlags | = SVF_NOCLIENT ;
target - > s . eFlags | = EF_NODRAW ;
target - > count = 0 ;
if ( first ) {
ent - > target = ent - > redsound ;
G_UseTargets ( ent , activator ) ;
first = qfalse ;
}
} else {
target - > clipmask = CONTENTS_BODY ;
trap_SetBrushModel ( target , target - > model ) ;
target - > r . svFlags & = ~ SVF_NOCLIENT ;
target - > s . eFlags & = ~ EF_NODRAW ;
target - > clipmask = 0 ;
target - > count = 1 ;
if ( first ) {
ent - > target = ent - > bluesound ;
G_UseTargets ( ent , activator ) ;
first = qfalse ;
}
}
}
}
ent - > sound1to2 = ! ent - > sound1to2 ;
} else if ( ! Q_stricmp ( activator - > target , ent - > falsename ) ) { //eject
if ( ent - > n00bCount ) {
ent - > target = ent - > truetarget ;
G_UseTargets ( ent , activator ) ;
ent - > n00bCount = 0 ;
ent - > target = ent - > yellowsound ;
G_UseTargets ( ent , activator ) ;
}
if ( ent - > sound2to1 ) {
ent - > use = 0 ;
ent - > think = target_warp_reactivate ;
ent - > nextthink = level . time + ( ent - > wait * 1000 ) ;
}
ent - > target = ent - > falsetarget ;
G_UseTargets ( ent , activator ) ;
ent - > sound2to1 = ! ent - > sound2to1 ;
} else if ( ! Q_stricmp ( activator - > target , ent - > swapname ) ) { // toggle warp
if ( ent - > sound1to2 & & ( ent - > sound2to1 = = 0 ) ) {
ent - > target = ent - > truetarget ;
G_UseTargets ( ent , activator ) ;
if ( ent - > n00bCount )
ent - > target = ent - > yellowsound ;
else
ent - > target = ent - > greensound ;
G_UseTargets ( ent , activator ) ;
ent - > n00bCount = ! ent - > n00bCount ;
} else {
if ( ent - > soundPos1 )
G_AddEvent ( ent , EV_GENERAL_SOUND , ent - > soundPos1 ) ;
}
}
}
void SP_target_warp ( gentity_t * ent ) {
char * temp ;
G_SpawnString ( " swapWarp " , " " , & temp ) ;
ent - > swapname = G_NewString ( temp ) ;
G_SpawnString ( " swapCoreState " , " " , & temp ) ;
ent - > truename = G_NewString ( temp ) ;
G_SpawnString ( " swapCoreEject " , " " , & temp ) ;
ent - > falsename = G_NewString ( temp ) ;
G_SpawnString ( " warpTarget " , " " , & temp ) ;
ent - > truetarget = G_NewString ( temp ) ;
G_SpawnString ( " core " , " " , & temp ) ;
ent - > falsetarget = G_NewString ( temp ) ;
G_SpawnString ( " coreSwap " , " " , & temp ) ;
ent - > bluename = G_NewString ( temp ) ;
G_SpawnString ( " soundDeactivate " , " 100 " , & temp ) ;
ent - > soundPos1 = G_SoundIndex ( temp ) ;
//set corestate
ent - > sound1to2 = ( ent - > spawnflags & 1 ) ;
//set ejected state
ent - > sound2to1 = ( ent - > spawnflags & 2 ) ;
//set warpstate
ent - > n00bCount = ( ent - > spawnflags & 4 ) ;
ent - > use = target_warp_use ;
// don't need to send this to clients
ent - > r . svFlags & = SVF_NOCLIENT ;
trap_LinkEntity ( ent ) ;
}
//RPG-X | GSIO01 | 19/05/2009 | MOD END
/*QUAKED target_deactivate (1 0 0) (-8 -8 -8) (8 8 8)
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
This entity can be used to de / activate all func_usables with " target " as targetname2 .
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
none
- - - - - KEYS - - - - -
" target " - func_usable to de / activate ( targetname2 ) .
2012-08-04 10:54:37 +00:00
*/
void target_deactivate_use ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
gentity_t * target = NULL ;
while ( ( target = G_Find ( target , FOFS ( targetname2 ) , ent - > target ) ) ! = NULL ) {
if ( ! Q_stricmp ( target - > classname , " func_usable " ) ) {
target - > flags ^ = FL_LOCKED ;
}
}
}
void SP_target_deactivate ( gentity_t * ent ) {
if ( ! ent - > target ) {
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] target_deactivate at %s without target! \n " , vtos ( ent - > r . currentOrigin ) ) ; ) ;
return ;
}
ent - > use = target_deactivate_use ;
// don't need to send this to clients
ent - > r . svFlags & = SVF_NOCLIENT ;
trap_LinkEntity ( ent ) ;
}
/*QUAKED target_serverchange (1 0 0) (-8 -8 -8) (8 8 8) START_ON
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
This will make any client inside it connect to a different server .
Can be toggled by an usable if the usable has NO_ACTIVATOR spawnflag .
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
1 : START_ON - will allow transfer form spawn on .
- - - - - KEYS - - - - -
" serverNum " - server to connect to ( rpg_server < serverNum > cvar )
2012-08-04 10:54:37 +00:00
*/
void target_serverchange_think ( gentity_t * ent ) {
if ( ! ent - > touched | | ! ent - > touched - > client ) return ;
trap_SendServerCommand ( ent - > touched - > client - > ps . clientNum , va ( " cg_connect \" %s \" \n " , ent - > targetname2 ) ) ;
ent - > nextthink = - 1 ;
}
void target_serverchange_use ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
if ( ! activator | | ! activator - > client ) {
ent - > s . time2 = ! ent - > s . time2 ;
return ;
}
if ( activator - > flags & FL_LOCKED )
return ;
activator - > flags ^ = FL_LOCKED ;
if ( rpg_serverchange . integer & & ent - > s . time2 ) {
ent - > think = target_serverchange_think ;
ent - > nextthink = level . time + 3000 ;
TransDat [ ent - > client - > ps . clientNum ] . beamTime = level . time + 8000 ;
activator - > client - > ps . powerups [ PW_BEAM_OUT ] = level . time + 8000 ;
ent - > touched = activator ;
2013-02-25 11:15:33 +00:00
ent - > targetname2 = level . srvChangeData . ip [ ent - > count ] ;
2012-08-04 10:54:37 +00:00
}
}
void SP_target_serverchange ( gentity_t * ent ) {
int serverNum ;
G_SpawnInt ( " serverNum " , " 1 " , & serverNum ) ;
ent - > count = serverNum ;
if ( ! ent - > count )
ent - > count = 1 ;
if ( ent - > spawnflags & 1 )
ent - > s . time2 = 1 ;
ent - > use = target_serverchange_use ;
trap_LinkEntity ( ent ) ;
}
/*QUAKED target_levelchange (1 0 0) (-8 -8 -8) (8 8 8)
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
This will change the map if rpg_allowSPLevelChange is set to 1.
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
none
- - - - - KEYS - - - - -
" target " - map to load ( for example : borg2 )
" wait " - time to wait before levelchange ( whole numbers only , - 1 for instant levelchange , 0 for default = 5 )
2012-08-04 10:54:37 +00:00
*/
void target_levelchange_think ( gentity_t * ent ) {
if ( ent - > count > 0 ) {
ent - > count - - ;
trap_SendServerCommand ( - 1 , va ( " servercprint \" Mapchange in %i ... \" " , ent - > count ) ) ;
} else {
trap_SendConsoleCommand ( EXEC_APPEND , va ( " devmap \" %s \" " , ent - > target ) ) ;
ent - > nextthink = - 1 ;
return ;
}
ent - > nextthink = level . time + 1000 ;
}
void target_levelchange_use ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
if ( rpg_allowSPLevelChange . integer ) {
ent - > think = target_levelchange_think ;
ent - > nextthink = level . time + 1000 ;
2012-10-15 11:05:45 +00:00
if ( ent - > count > 0 ) //This is anoying if there's no delay so let's do this only if there is
trap_SendServerCommand ( - 1 , va ( " servercprint \" Mapchange in %i ... \" " , ent - > count ) ) ;
2012-08-04 10:54:37 +00:00
}
}
void SP_target_levelchange ( gentity_t * ent ) {
if ( ! ent - > target ) {
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] target_levelchange without target at %s! \n " , vtos ( ent - > s . origin ) ) ; ) ;
G_FreeEntity ( ent ) ;
return ;
}
if ( ! ent - > wait )
ent - > count = 5 ;
else if ( ent - > wait < - 1 )
ent - > count = - 1 ;
else
ent - > count = ( int ) ent - > wait ;
ent - > use = target_levelchange_use ;
}
/*QUAKED target_holodeck (1 0 0) (-8 -8 -8) (8 8 8)
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
CURRENTLY DISABLED
target for ui_holodeck
2012-08-04 10:54:37 +00:00
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
none
- - - - - KEYS - - - - -
none
2012-08-04 10:54:37 +00:00
*/
void SP_target_holodeck ( gentity_t * ent ) {
G_FreeEntity ( ent ) ;
return ;
// don't need to send this to clients
ent - > r . svFlags & = SVF_NOCLIENT ;
trap_LinkEntity ( ent ) ;
}
//RPG-X | Harry Young | 15/10/2011 | MOD START
/*QUAKED target_shaderremap (1 0 0) (-8 -8 -8) (8 8 8)
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2012-08-04 10:54:37 +00:00
This will remap the shader " falsename " with shader " truename " and vice versa .
It will save you some vfx - usables .
This Entity only works on RPGXEF
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
none
- - - - - - KEYS - - - - -
" targetname " - when used will toggle the shaders
" falsename " - shader taht is ingame at spawn
" truename " - shader that will replace it
2012-08-04 10:54:37 +00:00
*/
void target_shaderremap_think ( gentity_t * ent ) {
float f = 0 ;
if ( ! ent - > spawnflags ) {
f = level . time * 0.001 ;
AddRemap ( ent - > falsename , ent - > truename , f ) ;
ent - > spawnflags = 1 ;
ent - > nextthink = - 1 ;
} else {
f = level . time * 0.001 ;
AddRemap ( ent - > falsename , ent - > falsename , f ) ;
ent - > spawnflags = 0 ;
ent - > nextthink = - 1 ;
}
trap_SetConfigstring ( CS_SHADERSTATE , BuildShaderStateConfig ( ) ) ;
}
void target_shaderremap_use ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
ent - > think = target_shaderremap_think ;
ent - > nextthink = level . time + 50 ; /* level.time + one frame */
}
void SP_target_shaderremap ( gentity_t * ent ) {
if ( ! ent - > falsename ) {
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] target_shaderremap without falsename-shader at %s! \n " , vtos ( ent - > s . origin ) ) ; ) ;
G_FreeEntity ( ent ) ;
return ;
}
if ( ! ent - > truename ) {
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] target_shaderremap without truename-shader at %s! \n " , vtos ( ent - > s . origin ) ) ; ) ;
G_FreeEntity ( ent ) ;
return ;
}
ent - > use = target_shaderremap_use ;
}
//RPG-X | Harry Young | 15/10/2011 | MOD END
2013-02-09 23:31:04 +00:00
//RPG-X | Harry Young | 25/07/2012 | MOD START
/*QUAKED target_selfdestruct (1 0 0) (-8 -8 -8) (8 8 8) AUDIO_ON
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
DO NOT USE ! This just sits here purely for documantation .
2012-08-04 10:54:37 +00:00
This entity manages the self destruct .
For now this should only be used via the selfdestruct console command , however it might be usable from within the radiant at a later date .
2013-02-09 23:31:04 +00:00
Should this thing hit 0 the killing part for everyone outside a target_zone configured as safezone will be done automatically .
2012-08-04 10:54:37 +00:00
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
2013-01-08 12:54:13 +00:00
1 : AUDIO_ON - tells the script to display the countdown
2012-11-27 21:57:55 +00:00
- - - - - KEYS - - - - -
" wait " - total Countdown - Time in secs
" flags " - are audio warnings 1 or 0 ?
2013-02-09 23:31:04 +00:00
" bluename " - target_zone this thing affects ( multi - ship - maps only ) will switch it unsafe at T - 50 ms
2012-11-27 21:57:55 +00:00
" target " - Things like fx to fire once the countdown hits 0
" damage " - leveltime of countdowns end
2012-08-04 10:54:37 +00:00
*/
2013-03-12 05:11:54 +00:00
void target_selfdestruct_end ( gentity_t * ent ) {
G_FreeEntity ( ent ) ;
return ;
}
2012-08-04 10:54:37 +00:00
void target_selfdestruct_use ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
2013-02-09 23:31:04 +00:00
if ( ent - > damage - level . time > 50 ) { //I'm still sceptical about a few things here, so I'll leave this in place
2012-08-04 10:54:37 +00:00
//with the use-function we're going to init aborts in a fairly simple manner: Fire warning notes...
2012-12-06 23:10:15 +00:00
trap_SendServerCommand ( - 1 , va ( " servermsg \" Self Destruct sequence aborted. \" " ) ) ;
2012-11-06 18:47:11 +00:00
G_AddEvent ( ent , EV_GLOBAL_SOUND , G_SoundIndex ( " sound/voice/selfdestruct/abort.mp3 " ) ) ;
2013-03-12 05:11:54 +00:00
trap_SendServerCommand ( - 1 , va ( " selfdestructupdate %i " , - 1 ) ) ;
//...and arrange for a thnk to and in 50 ms
ent - > think = target_selfdestruct_end ;
2013-01-08 12:54:13 +00:00
ent - > nextthink = level . time + 50 ;
2012-11-06 18:47:11 +00:00
}
2012-08-04 10:54:37 +00:00
return ;
}
void target_selfdestruct_think ( gentity_t * ent ) {
2013-02-09 23:31:04 +00:00
gentity_t * client = NULL ;
2012-10-31 19:54:37 +00:00
gentity_t * healthEnt , * safezone = NULL ;
2013-02-09 23:31:04 +00:00
int entlist [ MAX_GENTITIES ] ;
int n = 0 , num ;
2012-08-04 10:54:37 +00:00
2012-10-15 11:05:45 +00:00
//I've reconsidered. Selfdestruct will fire it's death mode no matter what. Targets are for FX-Stuff.
healthEnt = G_Find ( NULL , FOFS ( classname ) , " target_shiphealth " ) ;
2012-11-06 18:47:11 +00:00
if ( healthEnt & & G_Find ( healthEnt , FOFS ( classname ) , " target_shiphealth " ) = = NULL ) {
healthEnt - > damage = healthEnt - > health + healthEnt - > splashRadius ; //let's use the healthent killfunc if we have just one. makes a lot of stuff easier.
2012-10-15 11:05:45 +00:00
healthEnt - > use ( healthEnt , NULL , NULL ) ;
} else {
2013-02-11 05:21:55 +00:00
while ( ( safezone = G_Find ( safezone , FOFS ( classname ) , " target_zone " ) ) ! = NULL ) {
2013-02-21 20:51:34 +00:00
if ( ! Q_stricmp ( safezone - > targetname , ent - > bluename ) )
2013-02-11 05:21:55 +00:00
safezone - > n00bCount = 0 ;
}
safezone = NULL ;
2013-02-09 23:31:04 +00:00
while ( ( safezone = G_Find ( safezone , FOFS ( classname ) , " target_zone " ) ) ! = NULL ) {
// go through all safe zones and tag all safe players
if ( safezone - > count = = 1 & & safezone - > n00bCount = = 1 & & Q_stricmp ( safezone - > targetname , ent - > bluename ) ) {
num = trap_EntitiesInBox ( safezone - > r . mins , safezone - > r . maxs , entlist , MAX_GENTITIES ) ;
for ( n = 0 ; n < num ; n + + ) {
if ( entlist [ n ] < g_maxclients . integer & & g_entities [ entlist [ n ] ] . client ) {
while ( ( client = G_Find ( client , FOFS ( classname ) , " player " ) ) ! = NULL ) {
if ( client - > s . number = = entlist [ n ] )
client - > client - > nokilli = 1 ;
trap_SendServerCommand ( - 1 , va ( " print \" SETTING: %i = %i \n \" " , client - > s . number , client - > client - > nokilli ) ) ;
}
}
}
}
}
2012-08-04 10:54:37 +00:00
2013-02-09 23:31:04 +00:00
client = NULL ;
2012-08-04 10:54:37 +00:00
//Loop trough all clients on the server.
2013-02-09 23:31:04 +00:00
while ( ( client = G_Find ( client , FOFS ( classname ) , " player " ) ) ! = NULL ) {
if ( client - > client - > nokilli ! = 1 )
G_Damage ( client , ent , ent , 0 , 0 , 999999 , 0 , MOD_TRIGGER_HURT ) ; //maybe a new message ala "[Charname] did not abandon ship."
}
//we may go this way once more so clear clients back.
client = NULL ;
while ( ( client = G_Find ( client , FOFS ( classname ) , " player " ) ) ) {
client - > client - > nokilli = 0 ;
2012-08-04 10:54:37 +00:00
}
//let's hear it
G_AddEvent ( ent , EV_GLOBAL_SOUND , G_SoundIndex ( " sound/weapons/explosions/explode2.wav " ) ) ;
//let's be shakey for a sec... I hope lol ^^
trap_SetConfigstring ( CS_CAMERA_SHAKE , va ( " %i %i " , 9999 , ( 1000 + ( level . time - level . startTime ) ) ) ) ;
2012-10-15 11:05:45 +00:00
}
if ( ent - > target )
G_UseTargets ( ent , ent ) ;
2013-02-09 23:31:04 +00:00
trap_SendServerCommand ( - 1 , va ( " selfdestructupdate %i " , - 1 ) ) ;
2012-12-06 23:10:15 +00:00
G_FreeEntity ( ent ) ;
2013-02-11 05:21:55 +00:00
return ;
2012-11-06 18:47:11 +00:00
}
2012-08-04 10:54:37 +00:00
void SP_target_selfdestruct ( gentity_t * ent ) {
double ETAmin , ETAsec ;
float temp ;
2012-11-27 21:57:55 +00:00
if ( level . time < 1000 ) { //failsafe in case someone spawned this in the radiant
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] target_selfdestruct spawned by level. Removing entity. " ) ; ) ;
G_FreeEntity ( ent ) ;
return ;
}
//There is also a failsafe for lua spawning in lua_entity.c ->callspawn
2012-08-04 10:54:37 +00:00
//There's a little bit of math to do here so let's do that.
//convert all times from secs to millisecs if that hasn't been done in an earlier pass.
if ( ! ent - > splashRadius ) {
temp = ent - > wait * 1000 ;
ent - > wait = temp ;
temp = ent - > count * 1000 ;
ent - > count = temp ;
temp = ent - > n00bCount * 1000 ;
ent - > n00bCount = temp ;
temp = ent - > health * 1000 ;
ent - > health = temp ;
ent - > splashRadius = 1 ;
}
2012-12-06 23:10:15 +00:00
//we' may need the total for something so back it up...
2012-08-04 10:54:37 +00:00
ent - > splashDamage = ent - > wait ;
//let's find out when this thing will hit hard
ent - > damage = ent - > wait + level . time ;
//time's set so let's let everyone know that we're counting. I'll need to do a language switch here sometime...
2012-12-21 10:16:30 +00:00
ETAsec = floor ( modf ( ( ent - > wait / 60000 ) , & ETAmin ) * 60 ) ;
2013-01-08 12:54:13 +00:00
if ( ent - > spawnflags = = 1 )
if ( ETAsec / 10 < 1 ) //get leading 0 for secs
trap_SendServerCommand ( - 1 , va ( " servermsg \" ^1Self Destruct in %.0f:0%.0f \" " , ETAmin , ETAsec ) ) ;
else
2013-01-09 18:27:36 +00:00
trap_SendServerCommand ( - 1 , va ( " servermsg \" ^1Self Destruct in %.0f:%.0f \" " , ETAmin , ETAsec ) ) ;
2012-12-21 10:16:30 +00:00
else
2013-01-08 12:54:13 +00:00
if ( ETAsec / 10 < 1 ) //get leading 0 for secs
trap_SendServerCommand ( - 1 , va ( " servermsg \" ^1Self Destruct in %.0f:0%.0f; There will be no ^1further audio warnings. \" " , ETAmin , ETAsec ) ) ;
else
trap_SendServerCommand ( - 1 , va ( " servermsg \" ^1Self Destruct in %.0f:%.0f; There will be no ^1further audio warnings. \" " , ETAmin , ETAsec ) ) ;
2012-08-04 10:54:37 +00:00
ent - > r . svFlags | = SVF_BROADCAST ;
trap_LinkEntity ( ent ) ;
//Additionally we have some audio files ready to go in english with automatic german counterparts. Play them as well.
if ( ent - > wait = = 1200000 ) {
G_AddEvent ( ent , EV_GLOBAL_SOUND , G_SoundIndex ( " sound/voice/selfdestruct/20-a1.mp3 " ) ) ;
} else if ( ent - > wait = = 900000 ) {
2013-01-08 12:54:13 +00:00
if ( ent - > spawnflags = = 1 )
2012-08-04 10:54:37 +00:00
G_AddEvent ( ent , EV_GLOBAL_SOUND , G_SoundIndex ( " sound/voice/selfdestruct/15-a1.mp3 " ) ) ;
else
G_AddEvent ( ent , EV_GLOBAL_SOUND , G_SoundIndex ( " sound/voice/selfdestruct/15-a0.mp3 " ) ) ;
} else if ( ent - > wait = = 600000 ) {
G_AddEvent ( ent , EV_GLOBAL_SOUND , G_SoundIndex ( " sound/voice/selfdestruct/10-a1.mp3 " ) ) ;
} else if ( ent - > wait = = 300000 ) {
2013-01-08 12:54:13 +00:00
if ( ent - > spawnflags = = 1 )
2012-08-04 10:54:37 +00:00
G_AddEvent ( ent , EV_GLOBAL_SOUND , G_SoundIndex ( " sound/voice/selfdestruct/5-a1.mp3 " ) ) ;
else
G_AddEvent ( ent , EV_GLOBAL_SOUND , G_SoundIndex ( " sound/voice/selfdestruct/5-a0.mp3 " ) ) ;
} else {
2013-01-08 12:54:13 +00:00
if ( ent - > spawnflags = = 1 )
2012-08-04 10:54:37 +00:00
G_AddEvent ( ent , EV_GLOBAL_SOUND , G_SoundIndex ( " sound/voice/selfdestruct/X-a1.mp3 " ) ) ;
else
G_AddEvent ( ent , EV_GLOBAL_SOUND , G_SoundIndex ( " sound/voice/selfdestruct/X-a0.mp3 " ) ) ;
}
// Now all that's left is to plan the next think.
ent - > use = target_selfdestruct_use ;
2012-12-06 23:10:15 +00:00
ent - > think = target_selfdestruct_think ;
2013-02-09 23:31:04 +00:00
ent - > nextthink = ent - > damage ;
2012-08-04 10:54:37 +00:00
2013-01-08 12:54:13 +00:00
if ( ent - > spawnflags = = 1 )
2013-02-09 23:31:04 +00:00
trap_SendServerCommand ( - 1 , va ( " selfdestructupdate %.0f " , ent - > wait ) ) ;
2012-08-04 10:54:37 +00:00
2013-02-09 23:31:04 +00:00
ent - > wait = 0 ;
2012-10-26 12:19:36 +00:00
2012-08-04 10:54:37 +00:00
trap_LinkEntity ( ent ) ;
}
2013-02-09 23:31:04 +00:00
/*QUAKED target_zone (1 0 0) ? SPAWN_SAFE SHIP
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
2013-02-09 23:31:04 +00:00
A generic zone used for entities that need a generic pointer in the world . It needs to be specialized by the team - value .
2012-10-31 19:54:37 +00:00
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
2013-02-09 23:31:04 +00:00
Note : Spawnflags will only work with the system they are attached to
1 : SPAWN_SAFE - For safezone only : Entity is spawned in it ' s safe configurartion
2 : SHIP - For safezone only : will mark this safezone as a ship safezone
2012-11-27 21:57:55 +00:00
- - - - - KEYS - - - - -
2013-02-09 23:31:04 +00:00
" targetname " - used to link with , some types require this for toggling
" count " - specifies this zone ' s type :
0 - none , will free entity
1 - safezone for target_selfdestruct and target_shiphealth
2 - display zone for target_shiphealth ( HUD overlay )
2012-10-31 19:54:37 +00:00
2012-11-27 21:57:55 +00:00
- - - - - USAGE - - - - -
2013-02-09 23:31:04 +00:00
As safezone :
2012-10-31 19:54:37 +00:00
Usage for Escape Pods and similar :
Fill your escape pod Interior with this trigger and have it targeted by a func_usable / target_relay / target_delay to toggle it between safe and unsafe states .
Usage for multiple ships ( and stations ) like on rpg_runabout :
Surround your entire ship with this trigger ( or it ' s seperate elements with one each ) and set it to STARTON and SHIP ( spawnflags = 3 ) .
2012-11-27 21:57:55 +00:00
Have it ' s targetname match the targetname of it ' s target_shiphealth - counterpart exactly ( case - dependent ) to automatically switch this safezone to unsafe should it be about to die .
2012-10-31 19:54:37 +00:00
In case of a selfdestruct you will need to enter the targetname to automatically switch it to unsafe 50 ms prior to the countdowns end .
2012-11-27 21:57:55 +00:00
To get the correct one use the / safezonelist - command
2012-08-04 10:54:37 +00:00
*/
2012-10-26 12:19:36 +00:00
2012-10-31 19:54:37 +00:00
void target_safezone_use ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
2013-02-09 23:31:04 +00:00
//a client used this, so let's set this thing to active
if ( ent - > n00bCount = = 1 )
ent - > n00bCount = 0 ;
else
ent - > n00bCount = 1 ;
2012-10-26 12:19:36 +00:00
}
2013-02-09 23:31:04 +00:00
void SP_target_zone ( gentity_t * ent ) {
2012-08-04 10:54:37 +00:00
2013-02-09 23:31:04 +00:00
if ( ! ent - > targetname | | ! ent - > targetname [ 0 ] ) {
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] target_zone without targetname at %s, removing entity. \n " , vtos ( ent - > s . origin ) ) ; ) ;
G_FreeEntity ( ent ) ;
2012-08-04 10:54:37 +00:00
return ;
}
2013-02-21 20:51:34 +00:00
if ( Q_stricmp ( ent - > classname , " target_zone " ) ) {
2013-02-09 23:31:04 +00:00
ent - > count = 1 ;
ent - > classname = G_NewString ( " target_zone " ) ;
2012-08-04 10:54:37 +00:00
}
2013-02-09 23:31:04 +00:00
if ( ent - > count = = 0 ) {
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] target_zone without specified class by it's count-value at %s, removing entity. \n " , vtos ( ent - > s . origin ) ) ; ) ;
2012-10-31 19:54:37 +00:00
G_FreeEntity ( ent ) ;
2012-08-04 10:54:37 +00:00
return ;
}
2013-02-09 23:31:04 +00:00
if ( strcmp ( ent - > classname , " target_zone " ) ) {
ent - > count = 1 ;
//ent->classname = G_NewString("target_zone");
strcpy ( ent - > classname , " target_zone " ) ;
2012-08-04 10:54:37 +00:00
}
if ( ! ent - > luaEntity ) {
trap_SetBrushModel ( ent , ent - > model ) ;
}
2013-02-09 23:31:04 +00:00
if ( ent - > count = = 1 )
ent - > use = target_safezone_use ;
if ( ent - > count = = 1 & & ent - > spawnflags & 1 )
ent - > n00bCount = 1 ;
2012-08-04 10:54:37 +00:00
ent - > r . contents = CONTENTS_NONE ;
ent - > r . svFlags | = SVF_NOCLIENT ;
trap_LinkEntity ( ent ) ;
}
/*QUAKED target_shiphealth (1 0 0) (-8 -8 -8) (8 8 8)
2012-11-27 21:57:55 +00:00
- - - - - DESCRIPTION - - - - -
This Entity manages a ships health . Ship Health is reduced via administrative / delegable console command " /shipdamage [damage] "
2012-08-04 10:54:37 +00:00
Repairing is based on a % per minute basis for both shields and hull .
The entity features interconnectivity with other systems such as warpdrive or turbolift with a random yet incresing chance to turn them off whenever hulldamage occurs . This includes Shields .
Further more the entity will automatically toggle red alert should it be any other and will activate shields if alert is set to any but green .
2012-10-31 19:54:37 +00:00
If hull health hit ' s 0 it will kill any client outside an active safezone .
2012-08-04 10:54:37 +00:00
2012-11-27 21:57:55 +00:00
- - - - - SPAWNFLAGS - - - - -
none
- - - - - KEYS - - - - -
2012-10-31 19:54:37 +00:00
Required Keys ( If any of them are not given the entity will be removed at spawn ) :
2013-02-11 05:21:55 +00:00
targetname : Name of the Ship / Station this entity represents . See target_zone for additional use of this key .
2012-08-04 10:54:37 +00:00
health : Total Hull strength
splashRadius : total shield strenght
angle : Hull repair in % per minute
speed : Shield repair in % per minute ( only active if shield ' s aren ' t fried )
greensound : Things to fire every time damage occurs ( like FX )
2012-10-15 11:05:45 +00:00
falsetarget : truename / swapCoreState for target_warp
2012-08-04 10:54:37 +00:00
bluename : swapname for target_turbolift
bluesound : swapname for ui_transporter
2012-11-22 23:12:50 +00:00
falsename : falsename / redname for target_alert
2013-02-09 23:31:04 +00:00
paintarget : target_zones configured as MSD - Display - Zones this thing shoud communicate with
2012-11-22 23:12:50 +00:00
" model " - path to a shader with a MSD - Display ( ship ) to show . Default will be the Daedalus Class
We ' re sponsoring a varayity , which were created by Alexander Richardson .
2012-11-23 21:56:39 +00:00
The shaders for these are stowed in scripts / msd . shader in the pakX . pk3 .
It contains two versions : One for Texturing in Level design ( like a display ) and opne for the UI .
To retrieve such an image simply look for the MSD - Folder in your radiants texture browser
2012-11-22 23:12:50 +00:00
For personalized MSD ' s see segment below .
2012-11-23 21:56:39 +00:00
Ship - Classname | | Online Source | | Shader - Name ( for < type > insert gfx for UI - Shader and textures for texture shader )
2012-11-27 21:57:55 +00:00
Constellation Class | | http : //lcarsgfx.wordpress.com/2012/09/12/constellation-sisyphus/ || <type>/msd/constellation
Danube Runabout | | http : //lcarsgfx.wordpress.com/2012/06/30/the-blue-danube/ || <type>/msd/runabout
Nova Class | | http : //lcarsgfx.wordpress.com/2012/06/13/can-you-tell-what-it-is-yet-2/ || <type>/msd/nova
Galaxy Class | | http : //lcarsgfx.wordpress.com/2012/06/10/galaxy-class-redux-an-update/ || <type>/msd/galaxy
Daedalus Class | | http : //lcarsgfx.wordpress.com/2011/12/10/daedalus-father-of-icarus/ || <type>/msd/daedalus
Nebula Class | | http : //lcarsgfx.wordpress.com/2011/12/08/entering-the-nebula-part-2/ || <type>/msd/nebula
Intrepid Class | | http : //lcarsgfx.wordpress.com/2011/05/16/an-intrepid-undertaking/ || <type>/msd/intrepid
2013-02-24 13:20:59 +00:00
USCM ( Alien ) | | http : //lcarsgfx.wordpress.com/2010/08/10/in-space-no-one-can-hear-you-scream/ || <type>/msd/conestoga
2012-11-27 21:57:55 +00:00
Olympic Class | | http : //lcarsgfx.wordpress.com/2010/09/11/the-olympic-class/ || <type>/msd/olympic
2013-02-24 13:20:59 +00:00
Steamrunner Class | | http : //lcarsgfx.wordpress.com/2010/08/15/full-steam-ahead/ || <type>/msd/steamrunner
2012-11-27 21:57:55 +00:00
Oberth Class | | http : //lcarsgfx.wordpress.com/2010/08/12/im-a-doctor-not-a-science-vessel/ || <type>/msd/oberth
Soverign Class | | http : //lcarsgfx.wordpress.com/2010/03/01/sovereign-of-the-stars/ || <type>/msd/soverign
Excelsior Class ( Retro Design ) | | http : //lcarsgfx.wordpress.com/2010/01/01/retro-excelsior/ || <type>/msd/excelsior-retro
Excelsior Class | | http : //lcarsgfx.wordpress.com/2009/12/28/excelsior-class/ || <type>/msd/excelsior
Springfield Class | | http : //lcarsgfx.wordpress.com/2009/12/25/not-the-springfield-from-the-simpsons/ || <type>/msd/springfield
Defiant Class ( 8 Decks ) | | http : //lcarsgfx.wordpress.com/2009/12/10/scaling-the-defiant/ || <type>/msd/defiant8
Defiant Class ( 4 Decks ) | | http : //lcarsgfx.wordpress.com/2009/12/06/the-face-of-defiance/ || <type>/msd/defiant4
Miranda Class | | http : //lcarsgfx.wordpress.com/2009/12/05/miranda/ || <type>/msd/miranda
Centaur Class | | http : //lcarsgfx.wordpress.com/2009/12/05/centaur-comes-galloping/ || <type>/msd/centaur
Constitution Class | | http : //lcarsgfx.wordpress.com/2009/11/28/its-a-constitution/ || <type>/msd/constitution
Ambassador Class | | http : //lcarsgfx.wordpress.com/2009/11/27/having-the-ambassador-round-for-dinner/ || <type>/msd/ambassador
Cern Class | | http : //lcarsgfx.wordpress.com/2009/11/23/cern-class-by-john-eaves/ || <type>/msd/cern
Akira Class | | http : //lcarsgfx.wordpress.com/2009/11/21/akira-ra-ra-ra/ || <type>/msd/akira
Norway Class | | http : //lcarsgfx.wordpress.com/2009/11/21/norway-or-no-way/ || <type>/msd/norway
New Orleans Class | | http : //lcarsgfx.wordpress.com/2009/11/16/the-new-orleans/ || <type>/msd/neworleans
Cheyenne Class | | http : //lcarsgfx.wordpress.com/2009/11/16/cheyenne-class-msd/ || <type>/msd/cheyenne
Sabre Class | | http : //lcarsgfx.wordpress.com/2009/11/07/sabre-rattling/ || <type>/msd/sabre
2012-11-22 23:12:50 +00:00
- - - - - Personalized MSD ' s - - - - -
Alexander is doing personalized variations og his MSD ' s in terms of Ship - Names and Registry - Numbers
( as long as they do not have suffix - letters ) . If you ' d like one you may contact him via E - Mail and request such a modification .
In that request please also ask hom for a resulution of 2000 px across ( long side ) as the game requires
images to be displayed as MSD ' s to be roughly 2 : 1 and 2000 px is near the upper limit of what the game can handle .
Also please ask him to give you the image as an * . jpg - file .
Once you have the file put it in a subfolder ( e . g . gfx ) in either baseEF or RPG - X2 .
After that create a scripts / msd_shipname_registry . shader file ( registry is optional ,
however it is useful in avoiding collitions with ships of similar names )
In that file add the following short script :
2012-11-23 21:56:39 +00:00
gfx / msd / akira //this will be the path to the image for the UI
2012-11-22 23:12:50 +00:00
{
{
2012-11-23 21:56:39 +00:00
map textures / msd / akira . jpg //this will be the image you will use
2012-11-22 23:12:50 +00:00
blendFunc add //this will remove the black background. I might find a better solution...
}
}
2012-11-23 21:56:39 +00:00
textures / msd / akira //this will be the image you will use for texturing
{
surfaceparm nolightmap
surfaceparm nomarks
{
map textures / msd / akira . jpg //this will be the image you will use
}
{
map textures / engineering / glass1 . tga //this segment creates the glass effect to make it look like a display
blendfunc gl_one gl_one_minus_src_color
rgbGen identity
tcMod scale 3 3
tcGen environment
}
}
2012-11-22 23:12:50 +00:00
For distribution put both files ( including their relative paths ) in a * . pk3 file .
2012-08-04 10:54:37 +00:00
*/
2013-02-09 23:31:04 +00:00
void target_shiphealth_die ( gentity_t * ent ) {
//we're dying
int n = 0 , num ;
int entlist [ MAX_GENTITIES ] ;
gentity_t * client = NULL , * safezone = NULL ;
2013-02-11 05:21:55 +00:00
while ( ( safezone = G_Find ( safezone , FOFS ( classname ) , " target_zone " ) ) ! = NULL ) {
2013-02-21 20:51:34 +00:00
if ( ! Q_stricmp ( safezone - > targetname , ent - > targetname ) )
2013-02-11 05:21:55 +00:00
safezone - > n00bCount = 0 ;
}
safezone = NULL ;
2013-02-09 23:31:04 +00:00
while ( ( safezone = G_Find ( safezone , FOFS ( classname ) , " target_zone " ) ) ! = NULL ) {
// go through all safe zones and tag all safe players
if ( safezone - > count = = 1 & & safezone - > n00bCount = = 1 & & Q_stricmp ( safezone - > targetname , ent - > bluename ) ) {
num = trap_EntitiesInBox ( safezone - > r . mins , safezone - > r . maxs , entlist , MAX_GENTITIES ) ;
2012-08-04 10:54:37 +00:00
for ( n = 0 ; n < num ; n + + ) {
if ( entlist [ n ] < g_maxclients . integer & & g_entities [ entlist [ n ] ] . client ) {
2013-02-09 23:31:04 +00:00
while ( ( client = G_Find ( client , FOFS ( classname ) , " player " ) ) ! = NULL ) {
if ( client - > s . number = = entlist [ n ] )
client - > client - > nokilli = 1 ;
}
2012-08-04 10:54:37 +00:00
}
}
}
}
2013-02-09 23:31:04 +00:00
client = NULL ;
2012-10-26 12:19:36 +00:00
//Loop trough all clients on the server.
2013-02-09 23:31:04 +00:00
while ( ( client = G_Find ( client , FOFS ( classname ) , " player " ) ) ! = NULL ) {
if ( client - > client - > nokilli ! = 1 )
G_Damage ( client , ent , ent , 0 , 0 , 999999 , 0 , MOD_TRIGGER_HURT ) ; //maybe a new message ala "[Charname] did not abandon ship."
}
//we may go this way once more so clear clients back.
client = NULL ;
while ( ( client = G_Find ( client , FOFS ( classname ) , " player " ) ) ) {
client - > client - > nokilli = 0 ;
2012-10-26 12:19:36 +00:00
}
//let's hear it
G_AddEvent ( ent , EV_GLOBAL_SOUND , G_SoundIndex ( " sound/weapons/explosions/explode2.wav " ) ) ;
//let's be shakey for a sec... I hope lol ^^
trap_SetConfigstring ( CS_CAMERA_SHAKE , va ( " %i %i " , 9999 , ( 1000 + ( level . time - level . startTime ) ) ) ) ;
ent - > count = 0 ;
ent - > nextthink = - 1 ;
}
void target_shiphealth_use ( gentity_t * ent , gentity_t * other , gentity_t * activator ) {
2012-10-15 11:05:45 +00:00
double NSS , NHS , SD , HD , BT ;
2013-02-09 23:31:04 +00:00
int n = 0 , num ;
int entlist [ MAX_GENTITIES ] ;
gentity_t * alertEnt , * warpEnt , * turboEnt , * transEnt , * msdzone = NULL , * client = NULL ;
2012-08-04 10:54:37 +00:00
2012-10-15 11:05:45 +00:00
if ( ent - > damage < = 0 ) { //failsave
return ;
} else {
if ( ent - > splashDamage = = 1 ) { //shields are active so we're just bleeding trough on the hull
BT = ( ( 1 - ( ent - > count * pow ( ent - > health , - 1 ) ) ) / 10 ) ;
SD = ( ent - > damage - ceil ( ent - > damage * BT ) ) ;
if ( SD > ent - > n00bCount ) { //we're draining the shields...
HD = ( ent - > damage - ent - > n00bCount ) ;
NHS = ( ent - > count - HD ) ;
ent - > n00bCount = 0 ;
ent - > splashDamage = - 2 ;
} else { //shields will survive so let's just bleed trough
HD = floor ( ent - > damage * BT ) ;
NHS = ( ent - > count - HD ) ;
NSS = ( ent - > n00bCount - SD ) ;
ent - > n00bCount = NSS ;
}
} else { //shields are off, guess where the blow goes...
NHS = ( ent - > count - ent - > damage ) ;
2012-08-04 10:54:37 +00:00
}
2012-10-15 11:05:45 +00:00
ent - > count = NHS ;
ent - > damage = 0 ;
2012-08-04 10:54:37 +00:00
}
//enough math, let's trigger things
2012-10-15 11:05:45 +00:00
//go to red alert if we are not, this will also activate the shields
2012-08-04 10:54:37 +00:00
if ( ent - > falsename ) {
alertEnt = G_Find ( NULL , FOFS ( falsename ) , ent - > falsename ) ;
2012-10-15 11:05:45 +00:00
if ( alertEnt - > damage ! = 2 ) {
2012-08-04 10:54:37 +00:00
ent - > target = ent - > falsename ;
G_UseTargets ( ent , ent ) ;
}
2012-10-15 11:05:45 +00:00
} else {
if ( ent - > splashDamage = = 0 )
ent - > splashDamage = 1 ;
2012-08-04 10:54:37 +00:00
}
//time to fire the FX
ent - > target = ent - > greensound ;
G_UseTargets ( ent , ent ) ;
//disable UI_Transporter if need be.
if ( ent - > bluesound ) {
transEnt = G_Find ( NULL , FOFS ( swapname ) , ent - > bluesound ) ;
2012-10-15 11:05:45 +00:00
if ( ! ( transEnt - > flags & FL_LOCKED ) ) {
if ( ( ent - > count * pow ( ent - > health , - 1 ) ) < flrandom ( 0.1 , 0.4 ) ) {
2012-08-04 10:54:37 +00:00
ent - > target = ent - > bluesound ;
G_UseTargets ( ent , ent ) ;
}
}
}
//disable target_turbolift if need be.
if ( ent - > bluename ) {
turboEnt = G_Find ( NULL , FOFS ( swapname ) , ent - > bluename ) ;
2012-10-15 11:05:45 +00:00
if ( ! ( turboEnt - > flags & FL_LOCKED ) ) {
if ( ( ent - > count * pow ( ent - > health , - 1 ) ) < flrandom ( 0.1 , 0.4 ) ) {
2012-08-04 10:54:37 +00:00
ent - > target = ent - > bluename ;
G_UseTargets ( ent , ent ) ;
}
}
}
//disable target_warp if need be.
if ( ent - > falsetarget ) {
2012-10-15 11:05:45 +00:00
warpEnt = G_Find ( NULL , FOFS ( truename ) , ent - > falsetarget ) ;
if ( ( warpEnt - > sound1to2 ) & & ( warpEnt - > sound2to1 = = 0 ) ) {
if ( ( ent - > count * pow ( ent - > health , - 1 ) ) < flrandom ( 0.1 , 0.4 ) ) {
2012-08-04 10:54:37 +00:00
ent - > target = ent - > falsetarget ;
G_UseTargets ( ent , ent ) ;
}
}
}
//disable shield-subsystem if need be.
2012-10-15 11:05:45 +00:00
if ( ( ent - > count * pow ( ent - > health , - 1 ) ) < flrandom ( 0.1 , 0.4 ) ) {
2012-08-04 10:54:37 +00:00
ent - > n00bCount = 0 ;
ent - > splashDamage = - 1 ;
}
2012-10-26 12:19:36 +00:00
//let's reset the repair-timer
ent - > nextthink = level . time + 60000 ;
2012-08-04 10:54:37 +00:00
2013-02-09 23:31:04 +00:00
//refresh clients HUD Display
//first zero out all clients that are connected to this one
while ( ( client = G_Find ( client , FOFS ( classname ) , " player " ) ) ! = NULL ) {
if ( client - > client - > myship = = ent - > s . number )
trap_SendServerCommand ( client - > s . number , va ( " shiphealthupdate 0 0 0 " ) ) ;
}
2012-08-04 10:54:37 +00:00
2013-02-09 23:31:04 +00:00
client = NULL ;
//now let's loop trough our zones and find the clients to send the info to
while ( ( msdzone = G_Find ( msdzone , FOFS ( classname ) , " target_zone " ) ) ! = NULL ) {
// go through all safe zones and tag all safe players
if ( msdzone - > count = = 2 & & Q_stricmp ( msdzone - > targetname , ent - > paintarget ) ) {
num = trap_EntitiesInBox ( msdzone - > r . mins , msdzone - > r . maxs , entlist , MAX_GENTITIES ) ;
for ( n = 0 ; n < num ; n + + ) {
if ( entlist [ n ] < g_maxclients . integer & & g_entities [ entlist [ n ] ] . client ) {
while ( ( client = G_Find ( client , FOFS ( classname ) , " player " ) ) ! = NULL ) {
if ( client - > s . number = = entlist [ n ] ) {
trap_SendServerCommand ( client - > s . number , va ( " shiphealthupdate %.0f %.0f %i " , floor ( ent - > count / ent - > health ) , floor ( ent - > n00bCount / ent - > splashRadius ) , ent - > splashDamage ) ) ;
client - > client - > myship = ent - > s . number ;
}
}
}
}
2012-08-04 10:54:37 +00:00
}
2013-02-09 23:31:04 +00:00
}
//if we hit 0 blow in 50 ms
if ( ent - > count < = 0 ) {
2012-10-26 12:19:36 +00:00
ent - > think = target_shiphealth_die ;
ent - > nextthink = level . time + 50 ;
2012-08-04 10:54:37 +00:00
}
2012-10-15 11:05:45 +00:00
return ;
2012-08-04 10:54:37 +00:00
}
void target_shiphealth_think ( gentity_t * ent ) {
//this will do the healing each minute
int NSS , NHS ;
2013-02-09 23:31:04 +00:00
int n = 0 , num ;
int entlist [ MAX_GENTITIES ] ;
2012-08-04 10:54:37 +00:00
gentity_t * alertEnt ;
2013-02-09 23:31:04 +00:00
gentity_t * msdzone = NULL , * client = NULL ;
2012-08-04 10:54:37 +00:00
//We have interconnectivity with target_alert here in that at condition green we regenerate twice as fast
//so let's find the entity
if ( ent - > falsename )
alertEnt = G_Find ( NULL , FOFS ( falsename ) , ent - > falsename ) ;
else
alertEnt = G_Find ( NULL , FOFS ( classname ) , " target_alert " ) ;
if ( ! alertEnt ) { //failsave in case we don't have a target_alert present
alertEnt = G_Spawn ( ) ;
alertEnt - > damage = 0 ;
}
// Hull Repair
if ( ent - > count < ent - > health ) {
if ( alertEnt - > damage = = 0 ) //condition green
NHS = ( ent - > count + ( ent - > health * ent - > angle / 100 ) ) ;
else
NHS = ( ent - > count + ( ent - > health * ent - > angle / 200 ) ) ;
if ( NHS > ent - > health )
ent - > count = ent - > health ;
else
ent - > count = NHS ;
}
// Shield Repair
if ( ent - > splashDamage ! = - 1 ) { //skip if shields are toast
if ( ent - > n00bCount < ent - > splashRadius ) {
2012-10-15 11:05:45 +00:00
if ( alertEnt - > damage = = 0 ) { //condition green
2012-08-04 10:54:37 +00:00
NSS = ( ent - > n00bCount + ( ent - > splashRadius * ent - > speed / 100 ) ) ;
2012-10-15 11:05:45 +00:00
ent - > splashDamage = 0 ;
} else {
2012-08-04 10:54:37 +00:00
NSS = ( ent - > n00bCount + ( ent - > splashRadius * ent - > speed / 200 ) ) ;
2012-10-15 11:05:45 +00:00
ent - > splashDamage = 1 ;
}
2012-08-04 10:54:37 +00:00
if ( NSS > ent - > splashRadius )
ent - > n00bCount = ent - > splashRadius ;
else
ent - > n00bCount = NSS ;
}
}
//shield reenstatement
if ( ent - > splashDamage = = - 1 ) { //else we don't need to run this
2012-10-15 11:05:45 +00:00
if ( ( ent - > count * pow ( ent - > health , - 1 ) ) > 0.5 ) {
if ( alertEnt - > damage = = 0 & & ! Q_stricmp ( alertEnt - > classname , " target_alert " ) )
2012-08-04 10:54:37 +00:00
ent - > splashDamage = 0 ;
else
ent - > splashDamage = 1 ;
} else {
2012-10-15 11:05:45 +00:00
if ( ( ent - > count * pow ( ent - > health , - 1 ) * flrandom ( 0 , 1 ) ) > 0.75 ) {
if ( alertEnt - > damage = = 0 & & ! Q_stricmp ( alertEnt - > classname , " target_alert " ) )
2012-08-04 10:54:37 +00:00
ent - > splashDamage = 0 ;
else
ent - > splashDamage = 1 ;
}
}
}
ent - > nextthink = level . time + 60000 ;
2012-10-15 11:05:45 +00:00
2013-02-09 23:31:04 +00:00
//refresh clients HUD Display
//first zero out all clients that are connected to this one
while ( ( client = G_Find ( client , FOFS ( classname ) , " player " ) ) ! = NULL ) {
if ( client - > client - > myship = = ent - > s . number )
trap_SendServerCommand ( client - > s . number , va ( " shiphealthupdate 0 0 0 " ) ) ;
}
client = NULL ;
//now let's loop trough our zones and find the clients to send the info to
while ( ( msdzone = G_Find ( msdzone , FOFS ( classname ) , " target_zone " ) ) ! = NULL ) {
// go through all safe zones and tag all safe players
if ( msdzone - > count = = 2 & & Q_stricmp ( msdzone - > targetname , ent - > paintarget ) ) {
num = trap_EntitiesInBox ( msdzone - > r . mins , msdzone - > r . maxs , entlist , MAX_GENTITIES ) ;
for ( n = 0 ; n < num ; n + + ) {
if ( entlist [ n ] < g_maxclients . integer & & g_entities [ entlist [ n ] ] . client ) {
while ( ( client = G_Find ( client , FOFS ( classname ) , " player " ) ) ! = NULL ) {
if ( client - > s . number = = entlist [ n ] ) {
trap_SendServerCommand ( client - > s . number , va ( " shiphealthupdate %.0f %.0f %i " , floor ( ent - > count / ent - > health ) , floor ( ent - > n00bCount / ent - > splashRadius ) , ent - > splashDamage ) ) ;
client - > client - > myship = ent - > s . number ;
}
}
}
}
}
}
2012-10-15 11:05:45 +00:00
return ;
2012-08-04 10:54:37 +00:00
}
void SP_target_shiphealth ( gentity_t * ent ) {
2012-10-31 19:54:37 +00:00
if ( ! ent - > targetname | | ! ent - > health | | ! ent - > splashRadius | | ! ent - > angle | | ! ent - > speed ) {
DEVELOPER ( G_Printf ( S_COLOR_YELLOW " [Entity-Error] target_shiphealth at %s is missing one or more parameters, removing entity. \n " , vtos ( ent - > s . origin ) ) ; ) ;
2012-11-02 21:44:12 +00:00
G_FreeEntity ( ent ) ;
2012-10-31 19:54:37 +00:00
return ;
}
2012-08-04 10:54:37 +00:00
//we need to put the total health in for the current
ent - > count = ent - > health ;
ent - > n00bCount = ent - > splashRadius ;
//now for the shieldindicator I need to know if we have an alertEnt available
if ( G_Find ( NULL , FOFS ( classname ) , " target_alert " ) )
ent - > splashDamage = 0 ;
else
ent - > splashDamage = 1 ;
2012-11-23 21:56:39 +00:00
//let's make sure we have something to return as model
if ( ! ent - > model )
ent - > model = " gfx/msd/daedalus " ;
2012-08-04 10:54:37 +00:00
ent - > think = target_shiphealth_think ;
ent - > use = target_shiphealth_use ;
ent - > nextthink = level . time + 60000 ;
trap_LinkEntity ( ent ) ;
}