summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cgame/cg_event.c49
-rw-r--r--src/game/bg_public.h25
-rw-r--r--src/game/g_active.c9
-rw-r--r--src/game/g_buildable.c69
-rw-r--r--src/game/g_client.c4
-rw-r--r--src/game/g_cmds.c18
-rw-r--r--src/game/g_local.h2
-rw-r--r--src/game/g_weapon.c4
8 files changed, 128 insertions, 52 deletions
diff --git a/src/cgame/cg_event.c b/src/cgame/cg_event.c
index d5766621..14ea9a74 100644
--- a/src/cgame/cg_event.c
+++ b/src/cgame/cg_event.c
@@ -410,11 +410,11 @@ void CG_Menu( int eventParm )
switch( eventParm )
{
- case MN_TEAM: trap_SendConsoleCommand( "menu tremulous_teamselect\n" ); break;
- case MN_D_CLASS: trap_SendConsoleCommand( "menu tremulous_alienclass\n" ); break;
- case MN_H_SPAWN: trap_SendConsoleCommand( "menu tremulous_humanitem\n" ); break;
- case MN_D_BUILD: trap_SendConsoleCommand( "menu tremulous_alienbuild\n" ); break;
- case MN_H_BUILD: trap_SendConsoleCommand( "menu tremulous_humanbuild\n" ); break;
+ case MN_TEAM: trap_SendConsoleCommand( "menu tremulous_teamselect\n" ); break;
+ case MN_A_CLASS: trap_SendConsoleCommand( "menu tremulous_alienclass\n" ); break;
+ case MN_H_SPAWN: trap_SendConsoleCommand( "menu tremulous_humanitem\n" ); break;
+ case MN_A_BUILD: trap_SendConsoleCommand( "menu tremulous_alienbuild\n" ); break;
+ case MN_H_BUILD: trap_SendConsoleCommand( "menu tremulous_humanbuild\n" ); break;
case MN_H_MCU:
for( i = WP_NONE +1; i < WP_NUM_WEAPONS; i++ )
{
@@ -431,28 +431,31 @@ void CG_Menu( int eventParm )
trap_Cvar_Set( "ui_carriage", carriageCvar );
trap_SendConsoleCommand( "menu tremulous_humanmcu\n" );
break;
- case MN_H_BANK: trap_SendConsoleCommand( "menu tremulous_humanbank\n" ); break;
- case MN_H_NOROOM: trap_SendConsoleCommand( "menu tremulous_human_no_room\n" ); break;
- case MN_H_NOPOWER: trap_SendConsoleCommand( "menu tremulous_human_no_power\n" ); break;
- case MN_D_NOROOM: trap_SendConsoleCommand( "menu tremulous_alien_no_room\n" ); break;
- case MN_D_NOCREEP: trap_SendConsoleCommand( "menu tremulous_alien_no_creep\n" ); break;
- case MN_D_NOHVMND: trap_SendConsoleCommand( "menu tremulous_alien_no_hivemind\n" ); break;
- case MN_D_HIVEMIND: trap_SendConsoleCommand( "menu tremulous_alien_one_hivemind\n" ); break;
- case MN_D_NOASSERT: trap_SendConsoleCommand( "menu tremulous_alien_no_assertion\n" ); break;
- case MN_D_SPWNWARN: trap_SendConsoleCommand( "menu tremulous_alien_egg_warning\n" ); break;
- case MN_D_NORMAL: trap_SendConsoleCommand( "menu tremulous_alien_surface\n" ); break;
- case MN_H_REACTOR: trap_SendConsoleCommand( "menu tremulous_human_one_reactor\n" ); break;
- case MN_H_REPEATER: trap_SendConsoleCommand( "menu tremulous_human_repeater\n" ); break;
- case MN_H_RPLWARN: trap_SendConsoleCommand( "menu tremulous_human_replicator_warning\n" ); break;
- case MN_H_RPTWARN: trap_SendConsoleCommand( "menu tremulous_human_repeater_warning\n" ); break;
- case MN_H_NOSLOTS: trap_SendConsoleCommand( "menu tremulous_human_no_slots\n" ); break;
- case MN_H_NOFUNDS: trap_SendConsoleCommand( "menu tremulous_human_no_funds\n" ); break;
- case MN_H_ITEMHELD: trap_SendConsoleCommand( "menu tremulous_human_item_held\n" ); break;
- case MN_D_INFEST:
+ case MN_H_BANK: trap_SendConsoleCommand( "menu tremulous_humanbank\n" ); break;
+ case MN_H_NOROOM: trap_SendConsoleCommand( "menu tremulous_human_no_room\n" ); break;
+ case MN_H_NOPOWER: trap_SendConsoleCommand( "menu tremulous_human_no_power\n" ); break;
+ case MN_A_NOROOM: trap_SendConsoleCommand( "menu tremulous_alien_no_room\n" ); break;
+ case MN_A_NOCREEP: trap_SendConsoleCommand( "menu tremulous_alien_no_creep\n" ); break;
+ case MN_A_NOHVMND: trap_SendConsoleCommand( "menu tremulous_alien_no_hivemind\n" ); break;
+ case MN_A_HIVEMIND: trap_SendConsoleCommand( "menu tremulous_alien_one_hivemind\n" ); break;
+ case MN_A_NOASSERT: trap_SendConsoleCommand( "menu tremulous_alien_no_assertion\n" ); break;
+ case MN_A_SPWNWARN: trap_SendConsoleCommand( "menu tremulous_alien_egg_warning\n" ); break;
+ case MN_A_NORMAL: trap_SendConsoleCommand( "menu tremulous_alien_surface\n" ); break;
+ case MN_H_REACTOR: trap_SendConsoleCommand( "menu tremulous_human_one_reactor\n" ); break;
+ case MN_H_REPEATER: trap_SendConsoleCommand( "menu tremulous_human_repeater\n" ); break;
+ case MN_H_RPLWARN: trap_SendConsoleCommand( "menu tremulous_human_replicator_warning\n" ); break;
+ case MN_H_RPTWARN: trap_SendConsoleCommand( "menu tremulous_human_repeater_warning\n" ); break;
+ case MN_H_NOSLOTS: trap_SendConsoleCommand( "menu tremulous_human_no_slots\n" ); break;
+ case MN_H_NOFUNDS: trap_SendConsoleCommand( "menu tremulous_human_no_funds\n" ); break;
+ case MN_H_ITEMHELD: trap_SendConsoleCommand( "menu tremulous_human_item_held\n" ); break;
+ case MN_A_INFEST:
trap_Cvar_Set( "ui_currentClass", va( "%d", cg.snap->ps.stats[ STAT_PCLASS ] ) );
trap_SendConsoleCommand( "menu tremulous_alienupgrade\n" );
break;
+ case MN_A_HOVEL_OCCUPIED: trap_SendConsoleCommand( "menu tremulous_alien_hovel_occupied\n" ); break;
+ case MN_A_HOVEL_BLOCKED: trap_SendConsoleCommand( "menu tremulous_alien_hovel_blocked\n" ); break;
+
default:
Com_Printf( "cgame: debug: no such menu %d\n", eventParm );
}
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 3be0a0a4..03b13f95 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -560,16 +560,20 @@ typedef enum {
typedef enum
{
MN_TEAM,
- MN_D_CLASS,
- MN_D_BUILD,
- MN_D_INFEST,
- MN_D_NOROOM,
- MN_D_NOCREEP,
- MN_D_NOHVMND,
- MN_D_HIVEMIND,
- MN_D_NOASSERT,
- MN_D_SPWNWARN,
- MN_D_NORMAL,
+
+ MN_A_CLASS,
+ MN_A_BUILD,
+ MN_A_INFEST,
+ MN_A_NOROOM,
+ MN_A_NOCREEP,
+ MN_A_NOHVMND,
+ MN_A_HIVEMIND,
+ MN_A_NOASSERT,
+ MN_A_SPWNWARN,
+ MN_A_NORMAL,
+ MN_A_HOVEL_OCCUPIED,
+ MN_A_HOVEL_BLOCKED,
+
MN_H_SPAWN,
MN_H_BUILD,
MN_H_MCU,
@@ -583,6 +587,7 @@ typedef enum
MN_H_NOSLOTS,
MN_H_NOFUNDS,
MN_H_ITEMHELD
+
} dynMenu_t;
// animations
diff --git a/src/game/g_active.c b/src/game/g_active.c
index 7982ecac..8885a87e 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -352,7 +352,7 @@ void SpectatorThink( gentity_t *ent, usercmd_t *ucmd ) {
if( client->pers.pteam == PTE_NONE )
G_AddPredictableEvent( ent, EV_MENU, MN_TEAM );
else if( client->pers.pteam == PTE_ALIENS )
- G_AddPredictableEvent( ent, EV_MENU, MN_D_CLASS );
+ G_AddPredictableEvent( ent, EV_MENU, MN_A_CLASS );
else if( client->pers.pteam == PTE_HUMANS )
G_AddPredictableEvent( ent, EV_MENU, MN_H_SPAWN );
}
@@ -1043,7 +1043,6 @@ void ClientThink_real( gentity_t *ent ) {
client->buttons = ucmd->buttons;
client->latched_buttons |= client->buttons & ~client->oldbuttons;
- //TA: look for MCU infront of player
if( ( client->buttons & BUTTON_GETFLAG ) && !( client->oldbuttons & BUTTON_GETFLAG ) )
{
trace_t trace;
@@ -1086,9 +1085,15 @@ void ClientThink_real( gentity_t *ent ) {
G_setBuildableAnim( hovel, BANIM_ATTACK1, qfalse );
hovel->active = qfalse;
}
+ else
+ {
+ //exit is blocked
+ G_AddPredictableEvent( ent, EV_MENU, MN_A_HOVEL_BLOCKED );
+ }
}
else
{
+ //TA: look for MCU infront of player
AngleVectors( client->ps.viewangles, view, NULL, NULL );
VectorMA( client->ps.origin, 200, view, point );
trap_Trace( &trace, client->ps.origin, NULL, NULL, point, ent->s.number, MASK_SHOT );
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index 41ed5d3f..a0ded01d 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -599,6 +599,7 @@ void AHovel_Use( gentity_t *self, gentity_t *other, gentity_t *activator )
if( self->active )
{
//this hovel is in use
+ G_AddPredictableEvent( activator, EV_MENU, MN_A_HOVEL_OCCUPIED );
}
else if( ( activator->client->ps.stats[ STAT_PCLASS ] == PCL_A_B_BASE ) ||
( activator->client->ps.stats[ STAT_PCLASS ] == PCL_A_B_LEV1 ) )
@@ -612,6 +613,7 @@ void AHovel_Use( gentity_t *self, gentity_t *other, gentity_t *activator )
activator->client->sess.sessionTeam = TEAM_FREE;
activator->client->ps.stats[ STAT_STATE ] |= SS_HOVELING;
activator->client->infestBody = self;
+ self->builder = activator;
VectorCopy( self->s.pos.trBase, hovelOrigin );
VectorMA( hovelOrigin, 128.0f, self->s.origin2, hovelOrigin );
@@ -646,6 +648,59 @@ void AHovel_Think( gentity_t *self )
self->nextthink = level.time + 200;
}
+/*
+================
+AHovel_Die
+
+Die for alien hovel
+================
+*/
+void AHovel_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod )
+{
+ vec3_t dir;
+
+ // we don't have a valid direction, so just point straight up
+ dir[0] = dir[1] = 0;
+ dir[2] = 1;
+
+ //do a bit of radius damage
+ G_SelectiveRadiusDamage( self->s.pos.trBase, self->parent, self->splashDamage,
+ self->splashRadius, self, self->splashMethodOfDeath, PTE_ALIENS );
+
+ //pretty events and item cleanup
+ self->s.modelindex = 0; //don't draw the model once its destroyed
+ G_AddEvent( self, EV_GIB_ALIEN, DirToByte( dir ) );
+ self->r.contents = CONTENTS_TRIGGER;
+ self->timestamp = level.time;
+ self->think = ASpawn_Melt;
+ self->nextthink = level.time + 500; //wait .5 seconds before damaging others
+
+ //if the hovel is occupied free the occupant
+ if( self->active )
+ {
+ gentity_t *builder = self->builder;
+ vec3_t newOrigin;
+ vec3_t newAngles;
+
+ VectorCopy( self->s.angles, newAngles );
+ newAngles[ ROLL ] = 0;
+
+ VectorCopy( self->s.origin, newOrigin );
+ VectorMA( newOrigin, 1.0f, self->s.origin2, newOrigin );
+
+ //prevent lerping
+ builder->client->ps.eFlags ^= EF_TELEPORT_BIT;
+
+ G_SetOrigin( builder, newOrigin );
+ VectorCopy( newOrigin, builder->client->ps.origin );
+ SetClientViewAngle( builder, newAngles );
+
+ //client leaves hovel
+ builder->client->ps.stats[ STAT_STATE ] &= ~SS_HOVELING;
+ }
+
+ trap_LinkEntity( self );
+}
//==================================================================================
@@ -1853,7 +1908,7 @@ gentity_t *G_buildItem( gentity_t *builder, buildable_t buildable, vec3_t origin
break;
case BA_A_HOVEL:
- built->die = ASpawn_Die;
+ built->die = AHovel_Die;
built->use = AHovel_Use;
built->think = AHovel_Think;
built->pain = ASpawn_Pain;
@@ -1977,19 +2032,19 @@ void G_ValidateBuild( gentity_t *ent, buildable_t buildable )
break;
case IBE_NOASSERT:
- G_AddPredictableEvent( ent, EV_MENU, MN_D_NOASSERT );
+ G_AddPredictableEvent( ent, EV_MENU, MN_A_NOASSERT );
break;
case IBE_NOHIVEMIND:
- G_AddPredictableEvent( ent, EV_MENU, MN_D_NOHVMND );
+ G_AddPredictableEvent( ent, EV_MENU, MN_A_NOHVMND );
break;
case IBE_HIVEMIND:
- G_AddPredictableEvent( ent, EV_MENU, MN_D_HIVEMIND );
+ G_AddPredictableEvent( ent, EV_MENU, MN_A_HIVEMIND );
break;
case IBE_NORMAL:
- G_AddPredictableEvent( ent, EV_MENU, MN_D_NORMAL );
+ G_AddPredictableEvent( ent, EV_MENU, MN_A_NORMAL );
break;
case IBE_REACTOR:
@@ -2004,7 +2059,7 @@ void G_ValidateBuild( gentity_t *ent, buildable_t buildable )
if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
G_AddPredictableEvent( ent, EV_MENU, MN_H_NOROOM );
else
- G_AddPredictableEvent( ent, EV_MENU, MN_D_NOROOM );
+ G_AddPredictableEvent( ent, EV_MENU, MN_A_NOROOM );
break;
case IBE_NOPOWER:
@@ -2012,7 +2067,7 @@ void G_ValidateBuild( gentity_t *ent, buildable_t buildable )
break;
case IBE_SPWNWARN:
- G_AddPredictableEvent( ent, EV_MENU, MN_D_SPWNWARN );
+ G_AddPredictableEvent( ent, EV_MENU, MN_A_SPWNWARN );
G_buildItem( ent, buildable, origin, ent->s.apos.trBase );
break;
diff --git a/src/game/g_client.c b/src/game/g_client.c
index 8a57de4c..597866c3 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -604,7 +604,7 @@ void useBody( gentity_t *self, gentity_t *other, gentity_t *activator )
if( self->killedBy > 0 && self->killedBy != activator->client->ps.clientNum )
return;
- G_AddPredictableEvent( activator, EV_MENU, MN_D_INFEST );
+ G_AddPredictableEvent( activator, EV_MENU, MN_A_INFEST );
}
else
{
@@ -1394,7 +1394,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn )
if( client->sess.sessionTeam == TEAM_SPECTATOR )
{
if( teamLocal == PTE_ALIENS )
- G_AddPredictableEvent( ent, EV_MENU, MN_D_CLASS );
+ G_AddPredictableEvent( ent, EV_MENU, MN_A_CLASS );
else if( teamLocal == PTE_HUMANS )
G_AddPredictableEvent( ent, EV_MENU, MN_H_SPAWN );
}
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index a79de6c8..d8239549 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -423,7 +423,10 @@ void Cmd_Kill_f( gentity_t *ent ) {
return;
if( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING )
+ {
+ trap_SendServerCommand( ent-g_entities, "print \"Leave the hovel first (use your destroy key)\n\"" );
return;
+ }
if (ent->health <= 0)
return;
@@ -599,7 +602,8 @@ void StopFollowing( gentity_t *ent ) {
Cmd_Team_f
=================
*/
-void Cmd_Team_f( gentity_t *ent ) {
+void Cmd_Team_f( gentity_t *ent )
+{
int oldTeam;
char s[MAX_TOKEN_CHARS];
@@ -1704,8 +1708,10 @@ void Cmd_Destroy_f( gentity_t *ent )
trace_t tr;
gentity_t *traceEnt;
- if( !( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) &&
- !( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING ) )
+ if( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING )
+ G_Damage( ent->client->infestBody, ent, ent, forward, ent->s.origin, 10000, 0, MOD_SUICIDE );
+
+ if( !( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) )
{
AngleVectors( ent->client->ps.viewangles, forward, NULL, NULL );
VectorMA( ent->client->ps.origin, 50, forward, end );
@@ -2149,15 +2155,15 @@ void Cmd_Build_f( gentity_t *ent )
break;
case IBE_NOASSERT:
- G_AddPredictableEvent( ent, EV_MENU, MN_D_NOASSERT );
+ G_AddPredictableEvent( ent, EV_MENU, MN_A_NOASSERT );
break;
case IBE_NOHIVEMIND:
- G_AddPredictableEvent( ent, EV_MENU, MN_D_NOHVMND );
+ G_AddPredictableEvent( ent, EV_MENU, MN_A_NOHVMND );
break;
case IBE_HIVEMIND:
- G_AddPredictableEvent( ent, EV_MENU, MN_D_HIVEMIND );
+ G_AddPredictableEvent( ent, EV_MENU, MN_A_HIVEMIND );
break;
case IBE_REACTOR:
diff --git a/src/game/g_local.h b/src/game/g_local.h
index 47acc355..e9d35984 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -186,6 +186,8 @@ struct gentity_s {
vec4_t animation; //TA: animated map objects
vec3_t turretAim; //TA: aim vector for turrets
+
+ gentity_t *builder; //TA: occupant of this hovel
};
typedef enum {
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index a347e513..00e07234 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -1170,10 +1170,10 @@ void FireWeapon( gentity_t *ent )
Weapon_Claw_Fire( ent );
break;
case WP_ABUILD:
- Weapon_Build_Fire( ent, MN_D_BUILD );
+ Weapon_Build_Fire( ent, MN_A_BUILD );
break;
case WP_ABUILD2:
- Weapon_Build_Fire( ent, MN_D_BUILD );
+ Weapon_Build_Fire( ent, MN_A_BUILD );
break;
case WP_HBUILD:
Weapon_Build_Fire( ent, MN_H_BUILD );