From 409e6051a48221cb2a02c182dc0d5e64f2eeb40f Mon Sep 17 00:00:00 2001 From: Tim Angus Date: Sun, 4 Jun 2006 22:17:32 +0000 Subject: * Added target_hurt * Various other map entity fixes/enhancements * Hovel exploit fixed * Fixed tesla trail disappearing at edge of range * Default player name now inherited from OS * Fixed spelling of Veda's surname :x --- misc/entities.def | 31 ++++++-- src/cgame/cg_ents.c | 3 +- src/client/cl_main.c | 14 +++- src/game/g_cmds.c | 4 ++ src/game/g_spawn.c | 10 ++- src/game/g_target.c | 33 +++++++++ src/game/g_trigger.c | 198 +++++++++++++++++++++++++++++++++++++-------------- ui/quitcredit.menu | 2 +- 8 files changed, 227 insertions(+), 68 deletions(-) diff --git a/misc/entities.def b/misc/entities.def index 1c406b2d..cc14f59a 100644 --- a/misc/entities.def +++ b/misc/entities.def @@ -1008,6 +1008,13 @@ TARGET_* ENTITIES //============================================================================= +/*QUAKED target_hurt (1 0 0) (-8 -8 -8) (8 8 8) +When triggered, this hurts the entity that caused the trigger. + +-------- KEYS -------- +damage: amount of damage to deal (default: 5) +*/ + /*QUAKED target_rumble (1 0 0) (-8 -8 -8) (8 8 8) When triggered, this initiates a level-wide rumble effect. All players are affected. @@ -1131,7 +1138,7 @@ PRIVATE: only the player that activates the target will see the message. //============================================================================= -/*QUAKED target_push (.5 .5 .5) (-8 -8 -8) (8 8 8) BOUNCEPAD +/*QUAKED target_push (.5 .5 .5) (-8 -8 -8) (8 8 8) BOUNCEPAD NOSOUND This can be used to create jump pads and launch ramps. The direction of push can be set by the "angles" key or pointing to a target_position or info_notnull entity. Unlike trigger_push, this is NOT client side predicted and must be activated by a trigger. -------- KEYS -------- @@ -1151,6 +1158,7 @@ notsingle: when set to 1, entity will not spawn in Single Player mode (bot play -------- SPAWNFLAGS -------- BOUNCEPAD: if set, trigger will play bounce noise instead of beep noise when activated (recommended). +NOSOUND: if set, no sound is played at all -------- NOTES -------- To make a jump pad or launch ramp, create a trigger_multiple where the jump must originate. Place the target_push directly above the trigger_multiple and place the target_position entity at the highest point of the jump. Target the trigger_multiple to the target_push and target the target_push to the target_position/info_notnull (or set the target_push's "angles" key). Note that the "angle" key also works. @@ -1435,10 +1443,15 @@ NOT THROUGHLY TESTED: please report whether or not this works for you. gravity: The gravity within this trigger (default 800). */ -/*QUAKED trigger_buildable (.5 .5 .5) ? +/*QUAKED trigger_buildable (.5 .5 .5) ? SPAWN_DISABLED NEGATE Triggered by a buildable or subset of buildables. If no buildables key is supplied every buildable will trigger this entity. +Targetting this entity toggles it. NOT THROUGHLY TESTED: please report whether or not this works for you. +-------- SPAWNFLAGS -------- +SPAWN_DISABLED: needs to be triggered (toggle) to activate. +NEGATE: negate the trigger condition. + -------- KEYS -------- target: this points to the entity to activate. @@ -1449,10 +1462,15 @@ wait: time in seconds until trigger becomes re-triggerable after it's been touch random: random time variance in seconds added or subtracted from "wait" delay (default 0 - see Notes). */ -/*QUAKED trigger_class (.5 .5 .5) ? +/*QUAKED trigger_class (.5 .5 .5) ? SPAWN_DISABLED NEGATE Triggered by a specific class or subset of classes. If no classes key is supplied every class will trigger this entity. +Targetting this entity toggles it. NOT THROUGHLY TESTED: please report whether or not this works for you. +-------- SPAWNFLAGS -------- +SPAWN_DISABLED: needs to be triggered (toggle) to activate. +NEGATE: negate the trigger condition. + -------- KEYS -------- target: this points to the entity to activate. @@ -1463,10 +1481,15 @@ wait: time in seconds until trigger becomes re-triggerable after it's been touch random: random time variance in seconds added or subtracted from "wait" delay (default 0 - see Notes). */ -/*QUAKED trigger_equipment (.5 .5 .5) ? +/*QUAKED trigger_equipment (.5 .5 .5) ? SPAWN_DISABLED NEGATE Triggered by a player carrying some item (weapon or upgrade) or subset of items. If no equipment key is supplied every human will trigger this entity. +Targetting this entity toggles it. NOT THROUGHLY TESTED: please report whether or not this works for you. +-------- SPAWNFLAGS -------- +SPAWN_DISABLED: needs to be triggered (toggle) to activate. +NEGATE: negate the trigger condition. + -------- KEYS -------- target: this points to the entity to activate. diff --git a/src/cgame/cg_ents.c b/src/cgame/cg_ents.c index 1c7d6a05..02972a51 100644 --- a/src/cgame/cg_ents.c +++ b/src/cgame/cg_ents.c @@ -251,6 +251,7 @@ static void CG_EntityEffects( centity_t *cent ) if( CG_IsTrailSystemValid( ¢->muzzleTS ) ) { + //FIXME hack to prevent tesla trails reaching too far if( cent->currentState.eType == ET_BUILDABLE ) { vec3_t front, back; @@ -258,7 +259,7 @@ static void CG_EntityEffects( centity_t *cent ) CG_AttachmentPoint( ¢->muzzleTS->frontAttachment, front ); CG_AttachmentPoint( ¢->muzzleTS->backAttachment, back ); - if( Distance( front, back ) > TESLAGEN_RANGE ) + if( Distance( front, back ) > ( TESLAGEN_RANGE * M_ROOT3 ) ) CG_DestroyTrailSystem( ¢->muzzleTS ); } diff --git a/src/client/cl_main.c b/src/client/cl_main.c index af8c1d76..6e0cdaff 100644 --- a/src/client/cl_main.c +++ b/src/client/cl_main.c @@ -2352,6 +2352,8 @@ CL_Init ==================== */ void CL_Init( void ) { + const char *playerName; + Com_Printf( "----- Client Initialization -----\n" ); Con_Init (); @@ -2436,7 +2438,17 @@ void CL_Init( void ) { // userinfo - Cvar_Get ("name", "UnnamedPlayer", CVAR_USERINFO | CVAR_ARCHIVE ); + playerName = getenv( "USER" ); // Unixy stuff + if( playerName == NULL ) + { + playerName = getenv( "USERNAME" ); // Windows + if( playerName == NULL ) + { + playerName = "Newbie"; // Default + } + } + Cvar_Get ("name", playerName, CVAR_USERINFO | CVAR_ARCHIVE ); + Cvar_Get ("rate", "25000", CVAR_USERINFO | CVAR_ARCHIVE ); Cvar_Get ("snaps", "20", CVAR_USERINFO | CVAR_ARCHIVE ); Cvar_Get ("model", "sarge", CVAR_USERINFO | CVAR_ARCHIVE ); diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index 5ad95fae..27329adb 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -1443,6 +1443,10 @@ void Cmd_Destroy_f( gentity_t *ent, qboolean deconstruct ) ( ( ent->client->ps.weapon >= WP_ABUILD ) && ( ent->client->ps.weapon <= WP_HBUILD ) ) ) { + // Don't allow destruction of hovel with granger inside + if( traceEnt->s.modelindex == BA_A_HOVEL && traceEnt->active ) + return; + // Don't allow destruction of buildables that cannot be rebuilt if( g_suddenDeathTime.integer && ( level.time - level.startTime >= g_suddenDeathTime.integer * 60000 ) && diff --git a/src/game/g_spawn.c b/src/game/g_spawn.c index a2b3b4b7..4c515d83 100644 --- a/src/game/g_spawn.c +++ b/src/game/g_spawn.c @@ -134,14 +134,12 @@ field_t fields[ ] = {"dmg", FOFS(damage), F_INT}, {"angles", FOFS(s.angles), F_VECTOR}, {"angle", FOFS(s.angles), F_ANGLEHACK}, - //TA {"bounce", FOFS(physicsBounce), F_FLOAT}, {"alpha", FOFS(pos1), F_VECTOR}, {"radius", FOFS(pos2), F_VECTOR}, {"acceleration", FOFS(acceleration), F_VECTOR}, {"animation", FOFS(animation), F_VECTOR4}, {"rotatorAngle", FOFS(rotatorAngle), F_FLOAT}, - //TA {"targetShaderName", FOFS(targetShaderName), F_LSTRING}, {"targetShaderNewName", FOFS(targetShaderNewName), F_LSTRING}, @@ -159,7 +157,6 @@ void SP_info_player_start( gentity_t *ent ); void SP_info_player_deathmatch( gentity_t *ent ); void SP_info_player_intermission( gentity_t *ent ); -//TA: extra bits void SP_info_alien_intermission( gentity_t *ent ); void SP_info_human_intermission( gentity_t *ent ); @@ -175,8 +172,8 @@ void SP_func_bobbing( gentity_t *ent ); void SP_func_pendulum( gentity_t *ent ); void SP_func_button( gentity_t *ent ); void SP_func_door( gentity_t *ent ); -void SP_func_door_rotating( gentity_t *ent ); //TA -void SP_func_door_model( gentity_t *ent ); //TA +void SP_func_door_rotating( gentity_t *ent ); +void SP_func_door_model( gentity_t *ent ); void SP_func_train( gentity_t *ent ); void SP_func_timer( gentity_t *self); @@ -208,6 +205,7 @@ void SP_target_push( gentity_t *ent ); void SP_target_rumble( gentity_t *ent ); void SP_target_alien_win( gentity_t *ent ); void SP_target_human_win( gentity_t *ent ); +void SP_target_hurt( gentity_t *ent ); void SP_light( gentity_t *self ); void SP_info_null( gentity_t *self ); @@ -224,7 +222,6 @@ void SP_shooter_rocket( gentity_t *ent ); void SP_shooter_plasma( gentity_t *ent ); void SP_shooter_grenade( gentity_t *ent ); -//TA: void SP_misc_particle_system( gentity_t *ent ); void SP_misc_anim_model( gentity_t *ent ); void SP_misc_light_flare( gentity_t *ent ); @@ -291,6 +288,7 @@ spawn_t spawns[ ] = { "target_rumble", SP_target_rumble }, { "target_alien_win", SP_target_alien_win }, { "target_human_win", SP_target_human_win }, + { "target_hurt", SP_target_hurt }, { "light", SP_light }, { "path_corner", SP_path_corner }, diff --git a/src/game/g_target.c b/src/game/g_target.c index 1a32ce77..dfb9c7e2 100644 --- a/src/game/g_target.c +++ b/src/game/g_target.c @@ -437,3 +437,36 @@ void SP_target_human_win( gentity_t *self ) { self->use = target_human_win_use; } + +/* +=============== +target_hurt_use +=============== +*/ +void target_hurt_use( gentity_t *self, gentity_t *other, gentity_t *activator ) +{ + // hurt the activator + if( !activator->takedamage ) + return; + + G_Damage( activator, self, self, NULL, NULL, self->damage, 0, MOD_TRIGGER_HURT ); +} + +/* +=============== +SP_target_hurt +=============== +*/ +void SP_target_hurt( gentity_t *self ) +{ + if( !self->targetname ) + { + G_Printf( S_COLOR_YELLOW "WARNING: untargeted %s at %s\n", self->classname, + vtos( self->s.origin ) ); + } + + if( !self->damage ) + self->damage = 5; + + self->use = target_hurt_use; +} diff --git a/src/game/g_trigger.c b/src/game/g_trigger.c index 0c86747f..a79c12fe 100644 --- a/src/game/g_trigger.c +++ b/src/game/g_trigger.c @@ -238,11 +238,14 @@ void Use_target_push( gentity_t *self, gentity_t *other, gentity_t *activator ) VectorCopy( self->s.origin2, activator->client->ps.velocity ); - // play fly sound every 1.5 seconds - if( activator->fly_sound_debounce_time < level.time ) + if( !( self->spawnflags & 2 ) ) { - activator->fly_sound_debounce_time = level.time + 1500; - G_Sound( activator, CHAN_AUTO, self->noise_index ); + // play fly sound every 1.5 seconds + if( activator->fly_sound_debounce_time < level.time ) + { + activator->fly_sound_debounce_time = level.time + 1500; + G_Sound( activator, CHAN_AUTO, self->noise_index ); + } } } @@ -551,33 +554,55 @@ void SP_trigger_win( gentity_t *self ) /* =============== -trigger_buildable_trigger +trigger_buildable_match =============== */ -void trigger_buildable_trigger( gentity_t *self, gentity_t *activator ) +qboolean trigger_buildable_match( gentity_t *self, gentity_t *activator ) { int i = 0; - self->activator = activator; - if( self->nextthink ) - return; // can't retrigger until the wait is over - //if there is no buildable list every buildable triggers if( self->bTriggers[ i ] == BA_NONE ) - G_UseTargets( self, activator ); + return qtrue; else { //otherwise check against the list for( i = 0; self->bTriggers[ i ] != BA_NONE; i++ ) { if( activator->s.modelindex == self->bTriggers[ i ] ) - { - G_UseTargets( self, activator ); - return; - } + return qtrue; } } + return qfalse; +} + +/* +=============== +trigger_buildable_trigger +=============== +*/ +void trigger_buildable_trigger( gentity_t *self, gentity_t *activator ) +{ + self->activator = activator; + + if( self->s.eFlags & EF_NODRAW ) + return; + + if( self->nextthink ) + return; // can't retrigger until the wait is over + + if( self->s.eFlags & EF_DEAD ) + { + if( !trigger_buildable_match( self, activator ) ) + G_UseTargets( self, activator ); + } + else + { + if( trigger_buildable_match( self, activator ) ) + G_UseTargets( self, activator ); + } + if( self->wait > 0 ) { self->think = multi_wait; @@ -614,7 +639,7 @@ trigger_buildable_use */ void trigger_buildable_use( gentity_t *ent, gentity_t *other, gentity_t *activator ) { - trigger_buildable_trigger( ent, activator ); + ent->s.eFlags ^= EF_NODRAW; } /* @@ -642,6 +667,14 @@ void SP_trigger_buildable( gentity_t *self ) self->touch = trigger_buildable_touch; self->use = trigger_buildable_use; + // SPAWN_DISABLED + if( self->spawnflags & 1 ) + self->s.eFlags |= EF_NODRAW; + + // NEGATE + if( self->spawnflags & 2 ) + self->s.eFlags |= EF_DEAD; + InitTrigger( self ); trap_LinkEntity( self ); } @@ -649,13 +682,36 @@ void SP_trigger_buildable( gentity_t *self ) /* =============== -trigger_class_trigger +trigger_class_match =============== */ -void trigger_class_trigger( gentity_t *self, gentity_t *activator ) +qboolean trigger_class_match( gentity_t *self, gentity_t *activator ) { int i = 0; + //if there is no class list every class triggers (stupid case) + if( self->cTriggers[ i ] == PCL_NONE ) + return qtrue; + else + { + //otherwise check against the list + for( i = 0; self->cTriggers[ i ] != PCL_NONE; i++ ) + { + if( activator->client->ps.stats[ STAT_PCLASS ] == self->cTriggers[ i ] ) + return qtrue; + } + } + + return qfalse; +} + +/* +=============== +trigger_class_trigger +=============== +*/ +void trigger_class_trigger( gentity_t *self, gentity_t *activator ) +{ //sanity check if( !activator->client ) return; @@ -663,24 +719,22 @@ void trigger_class_trigger( gentity_t *self, gentity_t *activator ) if( activator->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS ) return; + if( self->s.eFlags & EF_NODRAW ) + return; + self->activator = activator; if( self->nextthink ) return; // can't retrigger until the wait is over - //if there is no class list every class triggers (stupid case) - if( self->cTriggers[ i ] == PCL_NONE ) - G_UseTargets( self, activator ); + if( self->s.eFlags & EF_DEAD ) + { + if( !trigger_class_match( self, activator ) ) + G_UseTargets( self, activator ); + } else { - //otherwise check against the list - for( i = 0; self->cTriggers[ i ] != PCL_NONE; i++ ) - { - if( activator->client->ps.stats[ STAT_PCLASS ] == self->cTriggers[ i ] ) - { - G_UseTargets( self, activator ); - return; - } - } + if( trigger_class_match( self, activator ) ) + G_UseTargets( self, activator ); } if( self->wait > 0 ) @@ -719,7 +773,7 @@ trigger_class_use */ void trigger_class_use( gentity_t *ent, gentity_t *other, gentity_t *activator ) { - trigger_class_trigger( ent, activator ); + ent->s.eFlags ^= EF_NODRAW; } /* @@ -747,6 +801,14 @@ void SP_trigger_class( gentity_t *self ) self->touch = trigger_class_touch; self->use = trigger_class_use; + // SPAWN_DISABLED + if( self->spawnflags & 1 ) + self->s.eFlags |= EF_NODRAW; + + // NEGATE + if( self->spawnflags & 2 ) + self->s.eFlags |= EF_DEAD; + InitTrigger( self ); trap_LinkEntity( self ); } @@ -754,49 +816,67 @@ void SP_trigger_class( gentity_t *self ) /* =============== -trigger_equipment_trigger +trigger_equipment_match =============== */ -void trigger_equipment_trigger( gentity_t *self, gentity_t *activator ) +qboolean trigger_equipment_match( gentity_t *self, gentity_t *activator ) { int i = 0; - //sanity check - if( !activator->client ) - return; - - if( activator->client->ps.stats[ STAT_PTEAM ] != PTE_HUMANS ) - return; - - self->activator = activator; - if( self->nextthink ) - return; // can't retrigger until the wait is over - //if there is no equipment list all equipment triggers (stupid case) - if( self->wTriggers[ i ] == WP_NONE && self->wTriggers[ i ] == UP_NONE ) - G_UseTargets( self, activator ); + if( self->wTriggers[ i ] == WP_NONE && self->uTriggers[ i ] == UP_NONE ) + return qtrue; else { //otherwise check against the lists for( i = 0; self->wTriggers[ i ] != WP_NONE; i++ ) { if( BG_InventoryContainsWeapon( self->wTriggers[ i ], activator->client->ps.stats ) ) - { - G_UseTargets( self, activator ); - return; - } + return qtrue; } for( i = 0; self->uTriggers[ i ] != UP_NONE; i++ ) { if( BG_InventoryContainsUpgrade( self->uTriggers[ i ], activator->client->ps.stats ) ) - { - G_UseTargets( self, activator ); - return; - } + return qtrue; } } + return qfalse; +} + +/* +=============== +trigger_equipment_trigger +=============== +*/ +void trigger_equipment_trigger( gentity_t *self, gentity_t *activator ) +{ + //sanity check + if( !activator->client ) + return; + + if( activator->client->ps.stats[ STAT_PTEAM ] != PTE_HUMANS ) + return; + + if( self->s.eFlags & EF_NODRAW ) + return; + + self->activator = activator; + if( self->nextthink ) + return; // can't retrigger until the wait is over + + if( self->s.eFlags & EF_DEAD ) + { + if( !trigger_equipment_match( self, activator ) ) + G_UseTargets( self, activator ); + } + else + { + if( trigger_equipment_match( self, activator ) ) + G_UseTargets( self, activator ); + } + if( self->wait > 0 ) { self->think = multi_wait; @@ -833,7 +913,7 @@ trigger_equipment_use */ void trigger_equipment_use( gentity_t *ent, gentity_t *other, gentity_t *activator ) { - trigger_equipment_trigger( ent, activator ); + ent->s.eFlags ^= EF_NODRAW; } /* @@ -862,6 +942,14 @@ void SP_trigger_equipment( gentity_t *self ) self->touch = trigger_equipment_touch; self->use = trigger_equipment_use; + // SPAWN_DISABLED + if( self->spawnflags & 1 ) + self->s.eFlags |= EF_NODRAW; + + // NEGATE + if( self->spawnflags & 2 ) + self->s.eFlags |= EF_DEAD; + InitTrigger( self ); trap_LinkEntity( self ); } diff --git a/ui/quitcredit.menu b/ui/quitcredit.menu index e3798d0c..679d6a80 100644 --- a/ui/quitcredit.menu +++ b/ui/quitcredit.menu @@ -228,7 +228,7 @@ textaligny 10 textscale 0.50 textstyle ITEM_TEXTSTYLE_NORMAL - text "Mike 'Veda' McInnerney" + text "Mike 'Veda' McInerney" forecolor 1 1 1 1 backcolor 1 0 0 1 visible 1 -- cgit