diff options
author | Tim Angus <tim@ngus.net> | 2005-06-05 22:16:54 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2005-06-05 22:16:54 +0000 |
commit | fb6006e34c1fe83acfb7976e50cb2f498e9c70b6 (patch) | |
tree | b8b3f26b52c3b2e71b51d40ff84e86b5bfb9d52d /src | |
parent | 47221c9c78f4a027211a041eb2ad527339b4d54b (diff) |
* Added flashing alien icon if already at maximum class
* Improved scanner render and refactored scanner code
* Added animated projectiles
* Grenade
* Changed model names to be human name agnostic
* Added sounds for lev1 grab and lev4 charge
* Added sound for failed evolution
* Added battery pack rendering code
* Added functionality to particle system to allow attachment of particle systems to particles (for nice explosions)
* Implemented CG_FileExists
* Added some code to gracefully handle missing sounds (easier than making the sounds :D)
* cg_drawBBOX now draws player BBOXen
* Renamed the alien classes (now done in class override scripts)
* Implemented Vector4Add
* The usual assorted bug fixes
Diffstat (limited to 'src')
-rw-r--r-- | src/cgame/cg_draw.c | 56 | ||||
-rw-r--r-- | src/cgame/cg_ents.c | 121 | ||||
-rw-r--r-- | src/cgame/cg_event.c | 92 | ||||
-rw-r--r-- | src/cgame/cg_local.h | 41 | ||||
-rw-r--r-- | src/cgame/cg_main.c | 38 | ||||
-rw-r--r-- | src/cgame/cg_particles.c | 251 | ||||
-rw-r--r-- | src/cgame/cg_players.c | 57 | ||||
-rw-r--r-- | src/cgame/cg_scanner.c | 177 | ||||
-rw-r--r-- | src/cgame/cg_view.c | 24 | ||||
-rw-r--r-- | src/cgame/cg_weapons.c | 32 | ||||
-rw-r--r-- | src/game/bg_misc.c | 236 | ||||
-rw-r--r-- | src/game/bg_pmove.c | 41 | ||||
-rw-r--r-- | src/game/bg_public.h | 75 | ||||
-rw-r--r-- | src/game/g_active.c | 115 | ||||
-rw-r--r-- | src/game/g_buildable.c | 16 | ||||
-rw-r--r-- | src/game/g_client.c | 50 | ||||
-rw-r--r-- | src/game/g_cmds.c | 34 | ||||
-rw-r--r-- | src/game/g_combat.c | 32 | ||||
-rw-r--r-- | src/game/g_local.h | 3 | ||||
-rw-r--r-- | src/game/g_missile.c | 67 | ||||
-rw-r--r-- | src/game/g_weapon.c | 239 | ||||
-rw-r--r-- | src/game/q_shared.h | 1 | ||||
-rw-r--r-- | src/game/tremulous.h | 212 | ||||
-rw-r--r-- | src/ui/ui_main.c | 14 |
24 files changed, 1397 insertions, 627 deletions
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c index 88e1ffc0..a2b2186f 100644 --- a/src/cgame/cg_draw.c +++ b/src/cgame/cg_draw.c @@ -533,6 +533,35 @@ void CG_SetPrintString( int type, const char *p ) } } +/* +=============== +CG_AtHighestClass + +Is the local client at the highest class possible? +=============== +*/ +static qboolean CG_AtHighestClass( void ) +{ + int i; + qboolean superiorClasses = qfalse; + + for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ ) + { + if( BG_ClassCanEvolveFromTo( + cg.predictedPlayerState.stats[ STAT_PCLASS ], i, + ALIEN_MAX_KILLS, 0 ) >= 0 && + BG_FindStagesForClass( i, cgs.alienStage ) ) + { + superiorClasses = qtrue; + break; + } + } + + return !superiorClasses; +} + +#define NO_CREDITS_TIME 2000 + static void CG_DrawPlayerCreditsValue( rectDef_t *rect, vec4_t color, qboolean padding ) { int value; @@ -550,6 +579,16 @@ static void CG_DrawPlayerCreditsValue( rectDef_t *rect, vec4_t color, qboolean p value = ps->persistant[ PERS_CREDIT ]; if( value > -1 ) { + if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS && + !CG_AtHighestClass( ) ) + { + if( cg.time - cg.lastEvolveAttempt <= NO_CREDITS_TIME ) + { + if( ( ( cg.time - cg.lastEvolveAttempt ) / 300 ) % 2 ) + color[ 3 ] = 0.0f; + } + } + trap_R_SetColor( color ); if( padding ) @@ -975,10 +1014,10 @@ static void CG_DrawAlienSense( rectDef_t *rect ) CG_DrawHumanScanner ============== */ -static void CG_DrawHumanScanner( rectDef_t *rect, qhandle_t shader ) +static void CG_DrawHumanScanner( rectDef_t *rect, qhandle_t shader, vec4_t color ) { if( BG_InventoryContainsUpgrade( UP_HELMET, cg.snap->ps.stats ) ) - CG_Scanner( rect, shader ); + CG_Scanner( rect, shader, color ); } @@ -1065,7 +1104,7 @@ static void CG_DrawPlayerBuildTimer( rectDef_t *rect, vec4_t color ) if( cg.time - cg.lastBuildAttempt <= BUILD_DELAY_TIME ) { - if( ( cg.time / 300 ) % 2 ) + if( ( ( cg.time - cg.lastBuildAttempt ) / 300 ) % 2 ) { color[ 0 ] = 1.0f; color[ 1 ] = color[ 2 ] = 0.0f; @@ -2192,6 +2231,15 @@ void CG_DrawWeaponIcon( rectDef_t *rect, vec4_t color ) } } + if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_ALIENS && CG_AtHighestClass( ) ) + { + if( cg.time - cg.lastEvolveAttempt <= NO_CREDITS_TIME ) + { + if( ( ( cg.time - cg.lastEvolveAttempt ) / 300 ) % 2 ) + color[ 3 ] = 0.0f; + } + } + trap_R_SetColor( color ); CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cg_weapons[ cent->currentState.weapon ].weaponIcon ); trap_R_SetColor( NULL ); @@ -2426,7 +2474,7 @@ void CG_OwnerDraw( float x, float y, float w, float h, float text_x, CG_DrawAlienSense( &rect ); break; case CG_PLAYER_HUMAN_SCANNER: - CG_DrawHumanScanner( &rect, shader ); + CG_DrawHumanScanner( &rect, shader, color ); break; case CG_PLAYER_USABLE_BUILDABLE: CG_DrawUsableBuildable( &rect, shader, color ); diff --git a/src/cgame/cg_ents.c b/src/cgame/cg_ents.c index 01314df0..1b4a1639 100644 --- a/src/cgame/cg_ents.c +++ b/src/cgame/cg_ents.c @@ -347,14 +347,15 @@ CG_Missile */ static void CG_Missile( centity_t *cent ) { - refEntity_t ent; - entityState_t *es; - const weaponInfo_t *wi; - vec3_t up; - float fraction; - int index; - weapon_t weapon; - weaponMode_t weaponMode; + refEntity_t ent; + entityState_t *es; + const weaponInfo_t *wi; + vec3_t up; + float fraction; + int index; + weapon_t weapon; + weaponMode_t weaponMode; + const weaponInfoMode_t *wim; es = ¢->currentState; @@ -365,26 +366,28 @@ static void CG_Missile( centity_t *cent ) wi = &cg_weapons[ weapon ]; weaponMode = es->generic1; + wim = &wi->wim[ weaponMode ]; + // calculate the axis VectorCopy( es->angles, cent->lerpAngles ); // add dynamic light - if( wi->wim[ weaponMode ].missileDlight ) + if( wim->missileDlight ) { - trap_R_AddLightToScene( cent->lerpOrigin, wi->wim[ weaponMode ].missileDlight, - wi->wim[ weaponMode ].missileDlightColor[ 0 ], - wi->wim[ weaponMode ].missileDlightColor[ 1 ], - wi->wim[ weaponMode ].missileDlightColor[ 2 ] ); + trap_R_AddLightToScene( cent->lerpOrigin, wim->missileDlight, + wim->missileDlightColor[ 0 ], + wim->missileDlightColor[ 1 ], + wim->missileDlightColor[ 2 ] ); } // add missile sound - if( wi->wim[ weaponMode ].missileSound ) + if( wim->missileSound ) { vec3_t velocity; BG_EvaluateTrajectoryDelta( ¢->currentState.pos, cg.time, velocity ); - trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, velocity, wi->wim[ weaponMode ].missileSound ); + trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, velocity, wim->missileSound ); } // create the render entity @@ -392,12 +395,12 @@ static void CG_Missile( centity_t *cent ) VectorCopy( cent->lerpOrigin, ent.origin ); VectorCopy( cent->lerpOrigin, ent.oldorigin ); - if( wi->wim[ weaponMode ].usesSpriteMissle ) + if( wim->usesSpriteMissle ) { ent.reType = RT_SPRITE; - ent.radius = wi->wim[ weaponMode ].missileSpriteSize; + ent.radius = wim->missileSpriteSize; ent.rotation = 0; - ent.customShader = wi->wim[ weaponMode ].missileSprite; + ent.customShader = wim->missileSprite; ent.shaderRGBA[ 0 ] = 0xFF; ent.shaderRGBA[ 1 ] = 0xFF; ent.shaderRGBA[ 2 ] = 0xFF; @@ -405,22 +408,42 @@ static void CG_Missile( centity_t *cent ) } else { - ent.hModel = wi->wim[ weaponMode ].missileModel; - ent.renderfx = wi->wim[ weaponMode ].missileRenderfx | RF_NOSHADOW; + ent.hModel = wim->missileModel; + ent.renderfx = wim->missileRenderfx | RF_NOSHADOW; // convert direction of travel into axis if( VectorNormalize2( es->pos.trDelta, ent.axis[ 0 ] ) == 0 ) ent.axis[ 0 ][ 2 ] = 1; // spin as it moves - if( es->pos.trType != TR_STATIONARY && wi->wim[ weaponMode ].missileRotates ) + if( es->pos.trType != TR_STATIONARY && wim->missileRotates ) RotateAroundDirection( ent.axis, cg.time / 4 ); else RotateAroundDirection( ent.axis, es->time ); + + if( wim->missileAnimates ) + { + int timeSinceStart = cg.time - es->time; + + if( wim->missileAnimLooping ) + { + ent.frame = wim->missileAnimStartFrame + + (int)( ( timeSinceStart / 1000.0f ) * wim->missileAnimFrameRate ) % + wim->missileAnimNumFrames; + } + else + { + ent.frame = wim->missileAnimStartFrame + + (int)( ( timeSinceStart / 1000.0f ) * wim->missileAnimFrameRate ); + + if( ent.frame > ( wim->missileAnimStartFrame + wim->missileAnimNumFrames ) ) + ent.frame = wim->missileAnimStartFrame + wim->missileAnimNumFrames; + } + } } //only refresh if there is something to display - if( wi->wim[ weaponMode ].missileSprite || wi->wim[ weaponMode ].missileModel ) + if( wim->missileSprite || wim->missileModel ) trap_R_AddRefEntityToScene( &ent ); } @@ -1045,57 +1068,8 @@ void CG_AddPacketEntities( void ) // lerp the non-predicted value for lightning gun origins CG_CalcEntityLerpPositions( &cg_entities[ cg.snap->ps.clientNum ] ); - //TA: "empty" item position arrays - cg.ep.numAlienBuildables = 0; - cg.ep.numHumanBuildables = 0; - cg.ep.numAlienClients = 0; - cg.ep.numHumanClients = 0; - - for( num = 0; num < cg.snap->numEntities; num++ ) - { - cent = &cg_entities[ cg.snap->entities[ num ].number ]; - - if( cent->currentState.eType == ET_BUILDABLE ) - { - //TA: add to list of item positions (for creep) - if( cent->currentState.modelindex2 == BIT_ALIENS ) - { - VectorCopy( cent->lerpOrigin, cg.ep.alienBuildablePos[ cg.ep.numAlienBuildables ] ); - cg.ep.alienBuildableTimes[ cg.ep.numAlienBuildables ] = cent->miscTime; - - if( cg.ep.numAlienBuildables < MAX_GENTITIES ) - cg.ep.numAlienBuildables++; - } - else if( cent->currentState.modelindex2 == BIT_HUMANS ) - { - VectorCopy( cent->lerpOrigin, cg.ep.humanBuildablePos[ cg.ep.numHumanBuildables ] ); - - if( cg.ep.numHumanBuildables < MAX_GENTITIES ) - cg.ep.numHumanBuildables++; - } - } - else if( cent->currentState.eType == ET_PLAYER ) - { - int team = cent->currentState.powerups & 0x00FF; - - if( team == PTE_ALIENS ) - { - VectorCopy( cent->lerpOrigin, cg.ep.alienClientPos[ cg.ep.numAlienClients ] ); - - if( cg.ep.numAlienClients < MAX_CLIENTS ) - cg.ep.numAlienClients++; - } - else if( team == PTE_HUMANS ) - { - VectorCopy( cent->lerpOrigin, cg.ep.humanClientPos[ cg.ep.numHumanClients ] ); - - if( cg.ep.numHumanClients < MAX_CLIENTS ) - cg.ep.numHumanClients++; - } - } - } - - //Com_Printf( "%d %d\n", cgIP.numAlienClients, cgIP.numHumanClients ); + // scanner + CG_UpdateEntityPositions( ); for( num = 0; num < MAX_GENTITIES; num++ ) cg_entities[ num ].valid = qfalse; @@ -1140,7 +1114,6 @@ void CG_AddPacketEntities( void ) switch( es->eType ) { - case ET_PLAYER: case ET_BUILDABLE: case ET_MISSILE: case ET_CORPSE: diff --git a/src/cgame/cg_event.c b/src/cgame/cg_event.c index 9b60df70..3a1138e6 100644 --- a/src/cgame/cg_event.c +++ b/src/cgame/cg_event.c @@ -32,6 +32,7 @@ static void CG_Obituary( entityState_t *ent ) const char *attackerInfo; char targetName[ 32 ]; char attackerName[ 32 ]; + char className[ 64 ]; gender_t gender; clientInfo_t *ci; @@ -57,7 +58,7 @@ static void CG_Obituary( entityState_t *ent ) if( !targetInfo ) return; - Q_strncpyz( targetName, Info_ValueForKey( targetInfo, "n" ), sizeof( targetName ) - 2); + Q_strncpyz( targetName, Info_ValueForKey( targetInfo, "n" ), sizeof( targetName ) - 2 ); strcat( targetName, S_COLOR_WHITE ); message2 = ""; @@ -145,6 +146,15 @@ static void CG_Obituary( entityState_t *ent ) message = "irradiated himself"; break; + case MOD_GRENADE: + if( gender == GENDER_FEMALE ) + message = "blew herself up"; + else if( gender == GENDER_NEUTER ) + message = "blew itself up"; + else + message = "blew himself up"; + break; + default: if( gender == GENDER_FEMALE ) message = "killed herself"; @@ -221,50 +231,70 @@ static void CG_Obituary( entityState_t *ent ) message = "was caught in the fallout of"; message2 = "'s lucifer cannon"; break; + case MOD_GRENADE: + message = "couldn't escape"; + message2 = "'s grenade"; + break; case MOD_ABUILDER_CLAW: message = "should leave"; message2 = "'s buildings alone"; break; - case MOD_SOLDIER_BITE: + case MOD_LEVEL0_BITE: message = "was bitten by"; break; - case MOD_HYDRA_CLAW: + case MOD_LEVEL1_CLAW: message = "was swiped by"; - message2 = "'s hydra"; + Com_sprintf( className, 64, "'s %s", + BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL1 ) ); + message2 = className; break; - case MOD_DRAGOON_CLAW: + case MOD_LEVEL3_CLAW: message = "was clawed by"; - message2 = "'s dragoon"; + Com_sprintf( className, 64, "'s %s", + BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL3 ) ); + message2 = className; break; - case MOD_DRAGOON_POUNCE: + case MOD_LEVEL3_POUNCE: message = "was pounced upon by"; - message2 = "'s dragoon"; + Com_sprintf( className, 64, "'s %s", + BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL3 ) ); + message2 = className; break; - case MOD_CHIMERA_CLAW: + case MOD_LEVEL2_CLAW: message = "was clawed by"; - message2 = "'s chimera"; + Com_sprintf( className, 64, "'s %s", + BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL3 ) ); + message2 = className; break; - case MOD_CHIMERA_ZAP: + case MOD_LEVEL2_ZAP: message = "was zapped by"; - message2 = "'s chimera"; + Com_sprintf( className, 64, "'s %s", + BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL3 ) ); + message2 = className; break; - case MOD_BMOFO_CLAW: + case MOD_LEVEL4_CLAW: message = "was mauled by"; - message2 = "'s big mofo"; + Com_sprintf( className, 64, "'s %s", + BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL4 ) ); + message2 = className; break; - case MOD_BMOFO_CHARGE: + case MOD_LEVEL4_CHARGE: message = "should have gotten out of the way of"; - message2 = "'s big mofo"; + Com_sprintf( className, 64, "'s %s", + BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL4 ) ); + message2 = className; break; case MOD_POISON: message = "should have used antitox against"; message2 = "'s poison"; break; - case MOD_HYDRA_PCLOUD: + case MOD_LEVEL1_PCLOUD: message = "was gassed by"; - message2 = "'s hydra"; + Com_sprintf( className, 64, "'s %s", + BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL1 ) ); + message2 = className; break; @@ -580,6 +610,22 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) break; + case EV_LEV1_GRAB: + DEBUGNAME( "EV_LEV1_GRAB" ); + trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL1Grab ); + break; + + case EV_LEV4_CHARGE_PREPARE: + DEBUGNAME( "EV_LEV4_CHARGE_PREPARE" ); + trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL4ChargePrepare ); + break; + + case EV_LEV4_CHARGE_START: + DEBUGNAME( "EV_LEV4_CHARGE_START" ); + //FIXME: stop cgs.media.alienL4ChargePrepare playing here + trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL4ChargeStart ); + break; + case EV_TAUNT: DEBUGNAME( "EV_TAUNT" ); trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*taunt.wav" ) ); @@ -882,6 +928,16 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) cg.spawnTime = cg.time; break; + case EV_ALIEN_EVOLVE_FAILED: + DEBUGNAME( "EV_ALIEN_EVOLVE_FAILED" ); + if( clientNum == cg.predictedPlayerState.clientNum ) + { + //FIXME: change to "negative" sound + trap_S_StartLocalSound( cgs.media.buildableRepairedSound, CHAN_LOCAL_SOUND ); + cg.lastEvolveAttempt = cg.time; + } + break; + case EV_ALIEN_ACIDTUBE: DEBUGNAME( "EV_ALIEN_ACIDTUBE" ); { diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index 1d22e308..6b93f142 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -219,6 +219,12 @@ typedef struct baseParticle_s pLerpValues_t alpha; pLerpValues_t rotation; + char childSystemName[ MAX_QPATH ]; + qhandle_t childSystemHandle; + + char onDeathSystemName[ MAX_QPATH ]; + qhandle_t onDeathSystemHandle; + //particle invariant stuff char shaderNames[ MAX_QPATH ][ MAX_SHADER_FRAMES ]; qhandle_t shaders[ MAX_SHADER_FRAMES ]; @@ -267,7 +273,8 @@ typedef enum { PSA_STATIC, PSA_TAG, - PSA_CENT_ORIGIN + PSA_CENT_ORIGIN, + PSA_PARTICLE } psAttachmentType_t; @@ -277,6 +284,7 @@ typedef struct psAttachment_s qboolean tagValid; qboolean centValid; qboolean normalValid; + qboolean particleValid; //PMT_STATIC vec3_t origin; @@ -342,6 +350,8 @@ typedef struct particle_s int lastEvalTime; + int nextChildTime; + pLerpValues_t radius; pLerpValues_t alpha; pLerpValues_t rotation; @@ -349,6 +359,8 @@ typedef struct particle_s qboolean valid; int sortKey; + + particleSystem_t *childSystem; } particle_t; @@ -692,6 +704,11 @@ typedef struct weaponInfoMode_s int missileSpriteSize; qhandle_t missileParticleSystem; qboolean missileRotates; + qboolean missileAnimates; + int missileAnimStartFrame; + int missileAnimNumFrames; + int missileAnimFrameRate; + int missileAnimLooping; sfxHandle_t firingSound; qboolean loopFireSound; @@ -785,6 +802,10 @@ typedef struct vec3_t humanClientPos[ MAX_CLIENTS ]; int numHumanClients; + + int lastUpdateTime; + vec3_t origin; + vec3_t vangles; } entityPos_t; typedef struct @@ -1013,9 +1034,8 @@ typedef struct float mediaFraction; float buildablesFraction; - entityPos_t ep; - int lastBuildAttempt; + int lastEvolveAttempt; char consoleText[ MAX_CONSOLE_TEXT ]; consoleLine_t consoleLines[ MAX_CONSOLE_LINES ]; @@ -1194,6 +1214,10 @@ typedef struct sfxHandle_t humanBuildablePrebuild; sfxHandle_t humanBuildableDamage[ 4 ]; + sfxHandle_t alienL1Grab; + sfxHandle_t alienL4ChargePrepare; + sfxHandle_t alienL4ChargeStart; + qhandle_t cursor; qhandle_t selectCursor; qhandle_t sizeCursor; @@ -1210,6 +1234,7 @@ typedef struct qhandle_t jetpackModel; qhandle_t jetpackFlashModel; + qhandle_t battpackModel; sfxHandle_t repeaterUseSound; @@ -1443,6 +1468,7 @@ extern vmCvar_t cg_lightFlare; extern vmCvar_t cg_debugParticles; extern vmCvar_t cg_debugPVS; extern vmCvar_t cg_disableBuildWarnings; +extern vmCvar_t cg_disableScannerPlane; //TA: hack to get class an carriage through to UI module extern vmCvar_t ui_currentClass; @@ -1479,6 +1505,8 @@ void CG_EventHandling( int type ); void CG_SetScoreSelection( void *menu ); void CG_BuildSpectatorString( ); +qboolean CG_FileExists( char *filename ); + // // cg_view.c @@ -1656,7 +1684,8 @@ void CG_DrawItemSelectText( rectDef_t *rect, float scale, int textStyle ) // // cg_scanner.c // -void CG_Scanner( rectDef_t *rect, qhandle_t shader ); +void CG_UpdateEntityPositions( void ); +void CG_Scanner( rectDef_t *rect, qhandle_t shader, vec4_t color ); void CG_AlienSense( rectDef_t *rect ); // @@ -1781,8 +1810,10 @@ void CG_AttachParticleSystemToCent( particleSystem_t *ps ); void CG_SetParticleSystemTag( particleSystem_t *ps, refEntity_t parent, qhandle_t model, char *tagName ); void CG_AttachParticleSystemToTag( particleSystem_t *ps ); void CG_SetParticleSystemOrigin( particleSystem_t *ps, vec3_t origin ); -void CG_AttachParticleSystemOrigin( particleSystem_t *ps ); +void CG_AttachParticleSystemToOrigin( particleSystem_t *ps ); void CG_SetParticleSystemNormal( particleSystem_t *ps, vec3_t normal ); +void CG_AttachParticleSystemToParticle( particleSystem_t *ps ); +void CG_SetParticleSystemParentParticle( particleSystem_t *ps, particle_t *p ); void CG_AddParticles( void ); diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c index 782db516..1ca58707 100644 --- a/src/cgame/cg_main.c +++ b/src/cgame/cg_main.c @@ -201,6 +201,7 @@ vmCvar_t cg_lightFlare; vmCvar_t cg_debugParticles; vmCvar_t cg_debugPVS; vmCvar_t cg_disableBuildWarnings; +vmCvar_t cg_disableScannerPlane; //TA: hack to get class and carriage through to UI module vmCvar_t ui_currentClass; @@ -305,6 +306,7 @@ static cvarTable_t cvarTable[ ] = { &cg_debugParticles, "cg_debugParticles", "0", CVAR_CHEAT }, { &cg_debugPVS, "cg_debugPVS", "0", CVAR_CHEAT }, { &cg_disableBuildWarnings, "cg_disableBuildWarnings", "0", CVAR_ARCHIVE }, + { &cg_disableScannerPlane, "cg_disableScannerPlane", "0", CVAR_ARCHIVE }, { &cg_hudFiles, "cg_hudFiles", "ui/hud.txt", CVAR_ARCHIVE}, { &ui_currentClass, "ui_currentClass", "0", 0 }, @@ -569,6 +571,28 @@ const char *CG_Argv( int arg ) /* ================= +CG_FileExists + +Test if a specific file exists or not +================= +*/ +qboolean CG_FileExists( char *filename ) +{ + fileHandle_t f; + + if( trap_FS_FOpenFile( filename, &f, FS_READ ) > 0 ) + { + //file exists so close it + trap_FS_FCloseFile( f ); + + return qtrue; + } + else + return qfalse; +} + +/* +================= CG_RegisterSounds called during a precache command @@ -587,6 +611,10 @@ static void CG_RegisterSounds( void ) cgs.media.alienOvermindDying = trap_S_RegisterSound( "sound/announcements/overminddying.wav", qtrue ); cgs.media.alienOvermindSpawns = trap_S_RegisterSound( "sound/announcements/overmindspawns.wav", qtrue ); + cgs.media.alienL1Grab = trap_S_RegisterSound( "sound/player/level1/grab.wav", qtrue ); + cgs.media.alienL4ChargePrepare = trap_S_RegisterSound( "sound/player/level4/charge_prepare.wav", qtrue ); + cgs.media.alienL4ChargeStart = trap_S_RegisterSound( "sound/player/level4/charge_start.wav", qtrue ); + cgs.media.tracerSound = trap_S_RegisterSound( "sound/weapons/machinegun/buletby1.wav", qfalse ); cgs.media.selectSound = trap_S_RegisterSound( "sound/weapons/change.wav", qfalse ); cgs.media.wearOffSound = trap_S_RegisterSound( "sound/items/wearoff.wav", qfalse ); @@ -749,8 +777,7 @@ static void CG_RegisterGraphics( void ) cgs.media.creepShader = trap_R_RegisterShader( "creep" ); cgs.media.scannerBlipShader = trap_R_RegisterShader( "gfx/2d/blip" ); - cgs.media.scannerLineShader = trap_R_RegisterShader( "white" ); - /*cgs.media.scannerShader = trap_R_RegisterShader( "gfx/2d/scanner" );*/ + cgs.media.scannerLineShader = trap_R_RegisterShader( "gfx/2d/stalk" ); cgs.media.waterBubbleShader = trap_R_RegisterShader( "waterBubble" ); @@ -958,12 +985,13 @@ static void CG_RegisterClients( void ) trap_UpdateScreen( ); } - cgs.media.larmourHeadSkin = trap_R_RegisterSkin( "models/players/trooper/head_light.skin" ); - cgs.media.larmourLegsSkin = trap_R_RegisterSkin( "models/players/trooper/lower_light.skin" ); - cgs.media.larmourTorsoSkin = trap_R_RegisterSkin( "models/players/trooper/upper_light.skin" ); + cgs.media.larmourHeadSkin = trap_R_RegisterSkin( "models/players/human_base/head_light.skin" ); + cgs.media.larmourLegsSkin = trap_R_RegisterSkin( "models/players/human_base/lower_light.skin" ); + cgs.media.larmourTorsoSkin = trap_R_RegisterSkin( "models/players/human_base/upper_light.skin" ); cgs.media.jetpackModel = trap_R_RegisterModel( "models/players/human_base/jetpack.md3" ); cgs.media.jetpackFlashModel = trap_R_RegisterModel( "models/players/human_base/jetpack_flash.md3" ); + cgs.media.battpackModel = trap_R_RegisterModel( "models/players/human_base/battpack.md3" ); cg.charModelFraction = 1.0f; trap_UpdateScreen( ); diff --git a/src/cgame/cg_particles.c b/src/cgame/cg_particles.c index 9b37382a..7f4ac64c 100644 --- a/src/cgame/cg_particles.c +++ b/src/cgame/cg_particles.c @@ -80,6 +80,33 @@ static void CG_SpreadVector( vec3_t v, float spread ) /* =============== +CG_DestroyParticle + +Destroy an individual particle +=============== +*/ +static void CG_DestroyParticle( particle_t *p ) +{ + //this particle has an onDeath particle system attached + if( p->class->onDeathSystemName[ 0 ] != '\0' ) + { + particleSystem_t *ps; + + ps = CG_SpawnNewParticleSystem( p->class->childSystemHandle ); + + if( CG_IsParticleSystemValid( &ps ) ) + { + CG_SetParticleSystemOrigin( ps, p->origin ); + CG_SetParticleSystemNormal( ps, p->velocity ); + CG_AttachParticleSystemToOrigin( ps ); + } + } + + p->valid = qfalse; +} + +/* +=============== CG_SpawnNewParticle Introduce a new particle into the world @@ -146,6 +173,32 @@ static particle_t *CG_SpawnNewParticle( baseParticle_t *bp, particleEjector_t *p VectorCopy( cent->lerpOrigin, p->origin ); break; + + case PSA_PARTICLE: + if( !ps->attachment.particleValid ) + return NULL; + + //find a particle which has ps as a child + for( j = 0; j < MAX_PARTICLES; j++ ) + { + particle_t *parentParticle = &particles[ j ]; + + if( parentParticle->valid && parentParticle->childSystem == ps ) + { + VectorCopy( parentParticle->origin, p->origin ); + break; + } + } + + if( j == MAX_PARTICLES ) + { + //didn't find the parent, so it's probably died already + + //prevent further (expensive) attempts at particle creation + ps->attachment.particleValid = qfalse; + return NULL; + } + break; } VectorAdd( p->origin, bp->displacement, p->origin ); @@ -191,18 +244,18 @@ static particle_t *CG_SpawnNewParticle( baseParticle_t *bp, particleEjector_t *p break; - case PMT_NORMAL: - - if( !ps->attachment.normalValid ) - return NULL; - - VectorCopy( ps->attachment.normal, p->velocity ); + case PMT_NORMAL: + + if( !ps->attachment.normalValid ) + return NULL; + + VectorCopy( ps->attachment.normal, p->velocity ); - //normal displacement - VectorNormalize( p->velocity ); - VectorMA( p->origin, bp->normalDisplacement, p->velocity, p->origin ); - - break; + //normal displacement + VectorNormalize( p->velocity ); + VectorMA( p->origin, bp->normalDisplacement, p->velocity, p->origin ); + + break; } VectorNormalize( p->velocity ); @@ -222,6 +275,21 @@ static particle_t *CG_SpawnNewParticle( baseParticle_t *bp, particleEjector_t *p p->valid = qtrue; + //this particle has a child particle system attached + if( bp->childSystemName[ 0 ] != '\0' ) + { + particleSystem_t *ps; + + ps = CG_SpawnNewParticleSystem( bp->childSystemHandle ); + + if( CG_IsParticleSystemValid( &ps ) ) + { + CG_SetParticleSystemParentParticle( ps, p ); + CG_SetParticleSystemNormal( ps, p->velocity ); + CG_AttachParticleSystemToParticle( ps ); + } + } + break; } } @@ -418,6 +486,10 @@ qhandle_t CG_RegisterParticleSystem( char *name ) if( !strcmp( bps->name, name ) ) { + //already registered + if( bps->registered ) + return i + 1; + for( j = 0; j < bps->numEjectors; j++ ) { bpe = bps->ejectors[ j ]; @@ -428,6 +500,21 @@ qhandle_t CG_RegisterParticleSystem( char *name ) for( k = 0; k < bp->numFrames; k++ ) bp->shaders[ k ] = trap_R_RegisterShader( bp->shaderNames[ k ] ); + + //recursively register any children + if( bp->childSystemName[ 0 ] != '\0' ) + { + //don't care about a handle for children since + //the system deals with it + CG_RegisterParticleSystem( bp->childSystemName ); + } + + if( bp->onDeathSystemName[ 0 ] != '\0' ) + { + //don't care about a handle for children since + //the system deals with it + CG_RegisterParticleSystem( bp->onDeathSystemName ); + } } } @@ -980,6 +1067,26 @@ static qboolean CG_ParseParticle( baseParticle_t *bp, char **text_p ) continue; } + else if( !Q_stricmp( token, "childSystem" ) ) + { + token = COM_Parse( text_p ); + if( !token ) + break; + + Q_strncpyz( bp->childSystemName, token, MAX_QPATH ); + + continue; + } + else if( !Q_stricmp( token, "onDeathSystem" ) ) + { + token = COM_Parse( text_p ); + if( !token ) + break; + + Q_strncpyz( bp->onDeathSystemName, token, MAX_QPATH ); + + continue; + } else if( !Q_stricmp( token, "}" ) ) return qtrue; //reached the end of this particle else @@ -1306,13 +1413,34 @@ Load particle systems from .particle files */ void CG_LoadParticleSystems( void ) { - int i; + int i, j; const char *s[ MAX_PARTICLE_FILES ]; + //clear out the old numBaseParticleSystems = 0; numBaseParticleEjectors = 0; numBaseParticles = 0; + for( i = 0; i < MAX_BASEPARTICLE_SYSTEMS; i++ ) + { + baseParticleSystem_t *bps = &baseParticleSystems[ i ]; + memset( bps, 0, sizeof( baseParticleSystem_t ) ); + } + + for( i = 0; i < MAX_BASEPARTICLE_EJECTORS; i++ ) + { + baseParticleEjector_t *bpe = &baseParticleEjectors[ i ]; + memset( bpe, 0, sizeof( baseParticleEjector_t ) ); + } + + for( i = 0; i < MAX_BASEPARTICLES; i++ ) + { + baseParticle_t *bp = &baseParticles[ i ]; + memset( bp, 0, sizeof( baseParticle_t ) ); + } + + + //and bring in the new for( i = 0; i < MAX_PARTICLE_FILES; i++ ) { s[ i ] = CG_ConfigString( CS_PARTICLE_FILES + i ); @@ -1325,6 +1453,62 @@ void CG_LoadParticleSystems( void ) else break; } + + //connect any child systems to their psHandle + for( i = 0; i < numBaseParticles; i++ ) + { + baseParticle_t *bp = &baseParticles[ i ]; + + if( bp->childSystemName[ 0 ] ) + { + //particle class has a child, resolve the name + for( j = 0; j < numBaseParticleSystems; j++ ) + { + baseParticleSystem_t *bps = &baseParticleSystems[ j ]; + + if( !Q_stricmp( bps->name, bp->childSystemName ) ) + { + //FIXME: add checks for cycles and infinite children + + bp->childSystemHandle = j + 1; + + break; + } + } + + if( j == numBaseParticleSystems ) + { + //couldn't find named particle system + CG_Printf( S_COLOR_YELLOW "WARNING: failed to find child %s\n", bp->childSystemName ); + bp->childSystemName[ 0 ] = '\0'; + } + } + + if( bp->onDeathSystemName[ 0 ] ) + { + //particle class has a child, resolve the name + for( j = 0; j < numBaseParticleSystems; j++ ) + { + baseParticleSystem_t *bps = &baseParticleSystems[ j ]; + + if( !Q_stricmp( bps->name, bp->onDeathSystemName ) ) + { + //FIXME: add checks for cycles and infinite children + + bp->onDeathSystemHandle = j + 1; + + break; + } + } + + if( j == numBaseParticleSystems ) + { + //couldn't find named particle system + CG_Printf( S_COLOR_YELLOW "WARNING: failed to find onDeath system %s\n", bp->onDeathSystemName ); + bp->onDeathSystemName[ 0 ] = '\0'; + } + } + } } @@ -1447,6 +1631,44 @@ void CG_SetParticleSystemOrigin( particleSystem_t *ps, vec3_t origin ) /* =============== +CG_AttachParticleSystemToParticle + +Attach a particle system to a particle +=============== +*/ +void CG_AttachParticleSystemToParticle( particleSystem_t *ps ) +{ + if( ps == NULL || !ps->valid ) + { + CG_Printf( S_COLOR_YELLOW "WARNING: tried to modify a NULL particle system\n" ); + return; + } + + ps->attachType = PSA_PARTICLE; + ps->attached = qtrue; +} + +/* +=============== +CG_SetParticleSystemParentParticle + +Set a particle system attachment means +=============== +*/ +void CG_SetParticleSystemParentParticle( particleSystem_t *ps, particle_t *p ) +{ + if( ps == NULL || !ps->valid ) + { + CG_Printf( S_COLOR_YELLOW "WARNING: tried to modify a NULL particle system\n" ); + return; + } + + ps->attachment.particleValid = qtrue; + p->childSystem = ps; +} + +/* +=============== CG_SetParticleSystemNormal Set a particle system attachment means @@ -1462,6 +1684,7 @@ void CG_SetParticleSystemNormal( particleSystem_t *ps, vec3_t normal ) ps->attachment.normalValid = qtrue; VectorCopy( normal, ps->attachment.normal ); + VectorNormalize( ps->attachment.normal ); } @@ -1760,7 +1983,7 @@ static void CG_EvaluateParticlePhysics( particle_t *p ) if( ( trap_CM_PointContents( trace.endpos, 0 ) & CONTENTS_NODROP ) || ( bp->cullOnStartSolid && trace.startsolid ) || bp->bounceCull ) { - p->valid = qfalse; + CG_DestroyParticle( p ); return; } @@ -1979,7 +2202,7 @@ void CG_AddParticles( void ) CG_RenderParticle( p ); } else - p->valid = qfalse; + CG_DestroyParticle( p ); } } diff --git a/src/cgame/cg_players.c b/src/cgame/cg_players.c index 2a1ca0f4..0dadbb8f 100644 --- a/src/cgame/cg_players.c +++ b/src/cgame/cg_players.c @@ -557,9 +557,33 @@ static void CG_LoadClientInfo( clientInfo_t *ci ) if( !s ) break; - ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", dir, s + 1 ), qfalse ); - if( !ci->sounds[ i ] ) - ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", fallback, s + 1 ), qfalse ); + // fanny about a bit with sounds that are missing + if( !CG_FileExists( va( "sound/player/%s/%s", dir, s + 1 ) ) ) + { + //file doesn't exist + + if( i == 11 || i == 8 ) //fall or falling + { + ci->sounds[ i ] = trap_S_RegisterSound( "sound/null.wav", qfalse ); + } + else + { + if( i == 9 ) //gasp + s = cg_customSoundNames[ 7 ]; //pain100_1 + else if( i == 10 ) //drown + s = cg_customSoundNames[ 0 ]; //death1 + + ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", dir, s + 1 ), qfalse ); + if( !ci->sounds[ i ] ) + ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", fallback, s + 1 ), qfalse ); + } + } + else + { + ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", dir, s + 1 ), qfalse ); + if( !ci->sounds[ i ] ) + ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", fallback, s + 1 ), qfalse ); + } } if( ci->footsteps == FOOTSTEP_CUSTOM ) @@ -1526,6 +1550,7 @@ static void CG_PlayerUpgrades( centity_t *cent, refEntity_t *torso ) { int held, active; refEntity_t jetpack; + refEntity_t battpack; refEntity_t flash; entityState_t *es = ¢->currentState; @@ -1627,6 +1652,24 @@ static void CG_PlayerUpgrades( centity_t *cent, refEntity_t *torso ) cent->jetPackState = JPS_OFF; } + if( held & ( 1 << UP_BATTPACK ) ) + { + memset( &battpack, 0, sizeof( battpack ) ); + VectorCopy( torso->lightingOrigin, battpack.lightingOrigin ); + battpack.shadowPlane = torso->shadowPlane; + battpack.renderfx = torso->renderfx; + + battpack.hModel = cgs.media.battpackModel; + + //identity matrix + AxisCopy( axisDefault, battpack.axis ); + + //FIXME: change to tag_back when it exists + CG_PositionRotatedEntityOnTag( &battpack, torso, torso->hModel, "tag_head" ); + + trap_R_AddRefEntityToScene( &battpack ); + } + if( es->eFlags & EF_BLOBLOCKED ) { vec3_t temp, origin, up = { 0.0f, 0.0f, 1.0f }; @@ -2044,6 +2087,14 @@ void CG_Player( centity_t *cent ) return; } + if( cg_drawBBOX.integer ) + { + vec3_t mins, maxs; + + BG_FindBBoxForClass( class, mins, maxs, NULL, NULL, NULL ); + CG_DrawBoundingBox( cent->lerpOrigin, mins, maxs ); + } + memset( &legs, 0, sizeof( legs ) ); memset( &torso, 0, sizeof( torso ) ); memset( &head, 0, sizeof( head ) ); diff --git a/src/cgame/cg_scanner.c b/src/cgame/cg_scanner.c index 2c410f20..16e79a51 100644 --- a/src/cgame/cg_scanner.c +++ b/src/cgame/cg_scanner.c @@ -13,20 +13,121 @@ #include "cg_local.h" +static entityPos_t entityPositions; + +#define HUMAN_SCANNER_UPDATE_PERIOD 300 + +/* +============= +CG_UpdateEntityPositions + +Update this client's perception of entity positions +============= +*/ +void CG_UpdateEntityPositions( void ) +{ + centity_t *cent = NULL; + int i; + + if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS ) + { + if( entityPositions.lastUpdateTime + HUMAN_SCANNER_UPDATE_PERIOD > cg.time ) + return; + } + + VectorCopy( cg.refdef.vieworg, entityPositions.origin ); + VectorCopy( cg.refdefViewAngles, entityPositions.vangles ); + entityPositions.lastUpdateTime = cg.time; + + entityPositions.numAlienBuildables = 0; + entityPositions.numHumanBuildables = 0; + entityPositions.numAlienClients = 0; + entityPositions.numHumanClients = 0; + + for( i = 0; i < cg.snap->numEntities; i++ ) + { + cent = &cg_entities[ cg.snap->entities[ i ].number ]; + + if( cent->currentState.eType == ET_BUILDABLE ) + { + //TA: add to list of item positions (for creep) + if( cent->currentState.modelindex2 == BIT_ALIENS ) + { + VectorCopy( cent->lerpOrigin, entityPositions.alienBuildablePos[ + entityPositions.numAlienBuildables ] ); + entityPositions.alienBuildableTimes[ + entityPositions.numAlienBuildables ] = cent->miscTime; + + if( entityPositions.numAlienBuildables < MAX_GENTITIES ) + entityPositions.numAlienBuildables++; + } + else if( cent->currentState.modelindex2 == BIT_HUMANS ) + { + VectorCopy( cent->lerpOrigin, entityPositions.humanBuildablePos[ + entityPositions.numHumanBuildables ] ); + + if( entityPositions.numHumanBuildables < MAX_GENTITIES ) + entityPositions.numHumanBuildables++; + } + } + else if( cent->currentState.eType == ET_PLAYER ) + { + int team = cent->currentState.powerups & 0x00FF; + + if( team == PTE_ALIENS ) + { + VectorCopy( cent->lerpOrigin, entityPositions.alienClientPos[ + entityPositions.numAlienClients ] ); + + if( entityPositions.numAlienClients < MAX_CLIENTS ) + entityPositions.numAlienClients++; + } + else if( team == PTE_HUMANS ) + { + VectorCopy( cent->lerpOrigin, entityPositions.humanClientPos[ + entityPositions.numHumanClients ] ); + + if( entityPositions.numHumanClients < MAX_CLIENTS ) + entityPositions.numHumanClients++; + } + } + } +} + #define STALKWIDTH 2.0f #define BLIPX 16.0f #define BLIPY 8.0f +#define FAR_ALPHA 0.8f +#define NEAR_ALPHA 1.2f + +/* +============= +CG_DrawBlips +Draw blips and stalks for the human scanner +============= +*/ static void CG_DrawBlips( rectDef_t *rect, vec3_t origin, vec4_t colour ) { vec3_t drawOrigin; vec3_t up = { 0, 0, 1 }; + float alphaMod = 1.0f; - RotatePointAroundVector( drawOrigin, up, origin, -cg.refdefViewAngles[ 1 ] - 90 ); + RotatePointAroundVector( drawOrigin, up, origin, -entityPositions.vangles[ 1 ] - 90 ); drawOrigin[ 0 ] /= ( 2 * HELMET_RANGE / rect->w ); drawOrigin[ 1 ] /= ( 2 * HELMET_RANGE / rect->h ); drawOrigin[ 2 ] /= ( 2 * HELMET_RANGE / rect->w ); + alphaMod = FAR_ALPHA + + ( ( drawOrigin[ 1 ] + ( rect->h / 2.0f ) ) / rect->h ) * ( NEAR_ALPHA - FAR_ALPHA ); + + colour[ 3 ] *= alphaMod; + + if( colour[ 3 ] > 1.0f ) + colour[ 3 ] = 1.0f; + else if( colour[ 3 ] < 0.0f ) + colour[ 3 ] = 0.0f; + trap_R_SetColor( colour ); if( drawOrigin[ 2 ] > 0 ) @@ -47,6 +148,13 @@ static void CG_DrawBlips( rectDef_t *rect, vec3_t origin, vec4_t colour ) #define BLIPX2 24.0f #define BLIPY2 24.0f +/* +============= +CG_DrawDir + +Draw dot marking the direction to an enemy +============= +*/ static void CG_DrawDir( rectDef_t *rect, vec3_t origin, vec4_t colour ) { vec3_t drawOrigin; @@ -68,7 +176,7 @@ static void CG_DrawDir( rectDef_t *rect, vec3_t origin, vec4_t colour ) else VectorSet( normal, 0.0f, 0.0f, 1.0f ); - AngleVectors( cg.refdefViewAngles, view, NULL, NULL ); + AngleVectors( entityPositions.vangles, view, NULL, NULL ); ProjectPointOnPlane( noZOrigin, origin, normal ); ProjectPointOnPlane( noZview, view, normal ); @@ -107,23 +215,23 @@ void CG_AlienSense( rectDef_t *rect ) vec4_t buildable = { 1.0f, 0.0f, 0.0f, 0.7f }; vec4_t client = { 0.0f, 0.0f, 1.0f, 0.7f }; - VectorCopy( cg.refdef.vieworg, origin ); + VectorCopy( entityPositions.origin, origin ); //draw human buildables - for( i = 0; i < cg.ep.numHumanBuildables; i++ ) + for( i = 0; i < entityPositions.numHumanBuildables; i++ ) { VectorClear( relOrigin ); - VectorSubtract( cg.ep.humanBuildablePos[ i ], origin, relOrigin ); + VectorSubtract( entityPositions.humanBuildablePos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < ALIENSENSE_RANGE ) CG_DrawDir( rect, relOrigin, buildable ); } //draw human clients - for( i = 0; i < cg.ep.numHumanClients; i++ ) + for( i = 0; i < entityPositions.numHumanClients; i++ ) { VectorClear( relOrigin ); - VectorSubtract( cg.ep.humanClientPos[ i ], origin, relOrigin ); + VectorSubtract( entityPositions.humanClientPos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < ALIENSENSE_RANGE ) CG_DrawDir( rect, relOrigin, client ); @@ -135,95 +243,104 @@ void CG_AlienSense( rectDef_t *rect ) CG_Scanner ============= */ -void CG_Scanner( rectDef_t *rect, qhandle_t shader ) +void CG_Scanner( rectDef_t *rect, qhandle_t shader, vec4_t color ) { int i; vec3_t origin; vec3_t relOrigin; - vec4_t hIabove = { 0.0f, 1.0f, 0.0f, 1.0f }; - vec4_t hIbelow = { 0.0f, 0.5f, 0.0f, 1.0f }; - vec4_t aIabove = { 1.0f, 0.0f, 0.0f, 1.0f }; - vec4_t aIbelow = { 0.5f, 0.0f, 0.0f, 1.0f }; + vec4_t hIabove; + vec4_t hIbelow; + vec4_t aIabove = { 1.0f, 0.0f, 0.0f, 0.75f }; + vec4_t aIbelow = { 1.0f, 0.0f, 0.0f, 0.5f }; + + Vector4Copy( color, hIabove ); + hIabove[ 3 ] *= 1.5f; + Vector4Copy( color, hIbelow ); - VectorCopy( cg.refdef.vieworg, origin ); + VectorCopy( entityPositions.origin, origin ); //draw human buildables below scanner plane - for( i = 0; i < cg.ep.numHumanBuildables; i++ ) + for( i = 0; i < entityPositions.numHumanBuildables; i++ ) { VectorClear( relOrigin ); - VectorSubtract( cg.ep.humanBuildablePos[ i ], origin, relOrigin ); + VectorSubtract( entityPositions.humanBuildablePos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] < 0 ) ) CG_DrawBlips( rect, relOrigin, hIbelow ); } //draw alien buildables below scanner plane - for( i = 0; i < cg.ep.numAlienBuildables; i++ ) + for( i = 0; i < entityPositions.numAlienBuildables; i++ ) { VectorClear( relOrigin ); - VectorSubtract( cg.ep.alienBuildablePos[ i ], origin, relOrigin ); + VectorSubtract( entityPositions.alienBuildablePos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] < 0 ) ) CG_DrawBlips( rect, relOrigin, aIbelow ); } //draw human clients below scanner plane - for( i = 0; i < cg.ep.numHumanClients; i++ ) + for( i = 0; i < entityPositions.numHumanClients; i++ ) { VectorClear( relOrigin ); - VectorSubtract( cg.ep.humanClientPos[ i ], origin, relOrigin ); + VectorSubtract( entityPositions.humanClientPos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] < 0 ) ) CG_DrawBlips( rect, relOrigin, hIbelow ); } //draw alien buildables below scanner plane - for( i = 0; i < cg.ep.numAlienClients; i++ ) + for( i = 0; i < entityPositions.numAlienClients; i++ ) { VectorClear( relOrigin ); - VectorSubtract( cg.ep.alienClientPos[ i ], origin, relOrigin ); + VectorSubtract( entityPositions.alienClientPos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] < 0 ) ) CG_DrawBlips( rect, relOrigin, aIbelow ); } - CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); + if( !cg_disableScannerPlane.integer ) + { + trap_R_SetColor( color ); + CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); + trap_R_SetColor( NULL ); + } //draw human buildables above scanner plane - for( i = 0; i < cg.ep.numHumanBuildables; i++ ) + for( i = 0; i < entityPositions.numHumanBuildables; i++ ) { VectorClear( relOrigin ); - VectorSubtract( cg.ep.humanBuildablePos[ i ], origin, relOrigin ); + VectorSubtract( entityPositions.humanBuildablePos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] > 0 ) ) CG_DrawBlips( rect, relOrigin, hIabove ); } //draw alien buildables above scanner plane - for( i = 0; i < cg.ep.numAlienBuildables; i++ ) + for( i = 0; i < entityPositions.numAlienBuildables; i++ ) { VectorClear( relOrigin ); - VectorSubtract( cg.ep.alienBuildablePos[ i ], origin, relOrigin ); + VectorSubtract( entityPositions.alienBuildablePos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] > 0 ) ) CG_DrawBlips( rect, relOrigin, aIabove ); } //draw human clients above scanner plane - for( i = 0; i < cg.ep.numHumanClients; i++ ) + for( i = 0; i < entityPositions.numHumanClients; i++ ) { VectorClear( relOrigin ); - VectorSubtract( cg.ep.humanClientPos[ i ], origin, relOrigin ); + VectorSubtract( entityPositions.humanClientPos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] > 0 ) ) CG_DrawBlips( rect, relOrigin, hIabove ); } //draw alien clients above scanner plane - for( i = 0; i < cg.ep.numAlienClients; i++ ) + for( i = 0; i < entityPositions.numAlienClients; i++ ) { VectorClear( relOrigin ); - VectorSubtract( cg.ep.alienClientPos[ i ], origin, relOrigin ); + VectorSubtract( entityPositions.alienClientPos[ i ], origin, relOrigin ); if( VectorLength( relOrigin ) < HELMET_RANGE && ( relOrigin[ 2 ] > 0 ) ) CG_DrawBlips( rect, relOrigin, aIabove ); diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c index bb0816d9..d3173024 100644 --- a/src/cgame/cg_view.c +++ b/src/cgame/cg_view.c @@ -463,19 +463,19 @@ static void CG_OffsetFirstPersonView( void ) bob2 = BG_FindBobForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] ); -#define BMOFO_FEEDBACK 10.0f +#define LEVEL4_FEEDBACK 10.0f //give a charging player some feedback - if( ps->weapon == WP_BIGMOFO ) + if( ps->weapon == WP_ALEVEL4 ) { if( ps->stats[ STAT_MISC ] > 0 ) { - float fraction = (float)ps->stats[ STAT_MISC ] / (float)BMOFO_CHARGE_TIME; + float fraction = (float)ps->stats[ STAT_MISC ] / (float)LEVEL4_CHARGE_TIME; if( fraction > 1.0f ) fraction = 1.0f; - bob2 *= ( 1.0f + fraction * BMOFO_FEEDBACK ); + bob2 *= ( 1.0f + fraction * LEVEL4_FEEDBACK ); } } @@ -499,11 +499,11 @@ static void CG_OffsetFirstPersonView( void ) angles[ ROLL ] += delta; } -#define DRAGOON_FEEDBACK 20.0f +#define LEVEL3_FEEDBACK 20.0f //provide some feedback for pouncing - if( cg.predictedPlayerState.weapon == WP_DRAGOON || - cg.predictedPlayerState.weapon == WP_DRAGOON_UPG ) + if( cg.predictedPlayerState.weapon == WP_ALEVEL3 || + cg.predictedPlayerState.weapon == WP_ALEVEL3_UPG ) { if( cg.predictedPlayerState.stats[ STAT_MISC ] > 0 ) { @@ -513,14 +513,14 @@ static void CG_OffsetFirstPersonView( void ) AngleVectors( angles, forward, NULL, NULL ); VectorNormalize( forward ); - fraction1 = (float)( cg.time - cg.weapon2Time ) / (float)DRAGOON_POUNCE_TIME; + fraction1 = (float)( cg.time - cg.weapon2Time ) / (float)LEVEL3_POUNCE_TIME; if( fraction1 > 1.0f ) fraction1 = 1.0f; fraction2 = -sin( fraction1 * M_PI / 2 ); - VectorMA( origin, DRAGOON_FEEDBACK * fraction2, forward, origin ); + VectorMA( origin, LEVEL3_FEEDBACK * fraction2, forward, origin ); } } @@ -583,8 +583,8 @@ static void CG_OffsetFirstPersonView( void ) float fraction = sin( ( (float)cg.time / 1000.0f ) * M_PI * 2 * PCLOUD_ROLL_FREQUENCY ); float pitchFraction = sin( ( (float)cg.time / 1000.0f ) * M_PI * 5 * PCLOUD_ROLL_FREQUENCY ); - fraction *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)HYDRA_PCLOUD_TIME ); - pitchFraction *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)HYDRA_PCLOUD_TIME ); + fraction *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)LEVEL1_PCLOUD_TIME ); + pitchFraction *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)LEVEL1_PCLOUD_TIME ); angles[ ROLL ] += fraction * PCLOUD_ROLL_AMPLITUDE; angles[ YAW ] += fraction * PCLOUD_ROLL_AMPLITUDE; @@ -795,7 +795,7 @@ static int CG_CalcFov( void ) { phase = cg.time / 1000.0 * PCLOUD_ZOOM_FREQUENCY * M_PI * 2; v = PCLOUD_ZOOM_AMPLITUDE * sin( phase ); - v *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)HYDRA_PCLOUD_TIME ); + v *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)LEVEL1_PCLOUD_TIME ); fov_x += v; fov_y += v; } diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c index 02427daa..3c4e1d3e 100644 --- a/src/cgame/cg_weapons.c +++ b/src/cgame/cg_weapons.c @@ -210,7 +210,7 @@ void CG_AlienZap( vec3_t start, vec3_t end, int srcENum, int destENum ) le->destENum = destENum; le->vOffset = 6.0f; - le->maxRange = CHIMERA_AREAZAP_RANGE * M_ROOT3; + le->maxRange = LEVEL2_AREAZAP_RANGE * M_ROOT3; VectorCopy( start, re->origin ); VectorCopy( end, re->oldorigin ); @@ -338,6 +338,36 @@ static qboolean CG_ParseWeaponModeSection( weaponInfoMode_t *wim, char **text_p continue; } + else if( !Q_stricmp( token, "missileAnimates" ) ) + { + wim->missileAnimates = qtrue; + + token = COM_Parse( text_p ); + if( !token ) + break; + + wim->missileAnimStartFrame = atoi( token ); + + token = COM_Parse( text_p ); + if( !token ) + break; + + wim->missileAnimNumFrames = atoi( token ); + + token = COM_Parse( text_p ); + if( !token ) + break; + + wim->missileAnimFrameRate = atoi( token ); + + token = COM_Parse( text_p ); + if( !token ) + break; + + wim->missileAnimLooping = atoi( token ); + + continue; + } else if( !Q_stricmp( token, "missileParticleSystem" ) ) { token = COM_Parse( text_p ); diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c index 807b8a3a..9c756e54 100644 --- a/src/game/bg_misc.c +++ b/src/game/bg_misc.c @@ -1429,7 +1429,7 @@ classAttributes_t bg_classList[ ] = 0 //int value; }, { - PCL_A_B_BASE, //int classnum; + PCL_ALIEN_BUILDER0, //int classnum; "builder", //char *className; "Builder", //char *humanName; "builder", //char *modelname; @@ -1462,12 +1462,12 @@ classAttributes_t bg_classList[ ] = 100.0f, //float stopSpeed; 130.0f, //float jumpMagnitude; 1.0f, //float knockbackScale; - { PCL_A_B_LEV1, PCL_A_O_BASE, PCL_NONE }, //int children[ 3 ]; + { PCL_ALIEN_BUILDER0_UPG, PCL_ALIEN_LEVEL0, PCL_NONE }, //int children[ 3 ]; ABUILDER_COST, //int cost; ABUILDER_VALUE //int value; }, { - PCL_A_B_LEV1, //int classnum; + PCL_ALIEN_BUILDER0_UPG, //int classnum; "builderupg", //char *classname; "Advanced Builder", //char *humanname; "builder", //char *modelname; @@ -1500,13 +1500,13 @@ classAttributes_t bg_classList[ ] = 100.0f, //float stopSpeed; 270.0f, //float jumpMagnitude; 1.0f, //float knockbackScale; - { PCL_A_O_BASE, PCL_NONE, PCL_NONE }, //int children[ 3 ]; + { PCL_ALIEN_LEVEL0, PCL_NONE, PCL_NONE }, //int children[ 3 ]; ABUILDER_UPG_COST, //int cost; ABUILDER_UPG_VALUE //int value; }, { - PCL_A_O_BASE, //int classnum; - "soldier", //char *classname; + PCL_ALIEN_LEVEL0, //int classnum; + "level0", //char *classname; "Soldier", //char *humanname; "jumper", //char *modelname; 0.2f, //float modelScale; @@ -1521,31 +1521,31 @@ classAttributes_t bg_classList[ ] = { 15, 15, 4 }, //vec3_t deadmaxs; -8.0f, //float zOffset 0, 0, //int viewheight, crouchviewheight; - SOLDIER_HEALTH, //int health; + LEVEL0_HEALTH, //int health; 0.0f, //float fallDamage; - SOLDIER_REGEN, //int regenRate; + LEVEL0_REGEN, //int regenRate; SCA_WALLCLIMBER|SCA_NOWEAPONDRIFT| SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; - WP_SOLDIER, //weapon_t startWeapon + WP_ALEVEL0, //weapon_t startWeapon 0.0f, //float buildDist; 140, //int fov; 0.0f, //float bob; 2.5f, //float bobCycle; 25, //int steptime; - SOLDIER_SPEED, //float speed; + LEVEL0_SPEED, //float speed; 10.0f, //float acceleration; 1.0f, //float airAcceleration; 6.0f, //float friction; 400.0f, //float stopSpeed; 250.0f, //float jumpMagnitude; 2.0f, //float knockbackScale; - { PCL_A_O_LEV1, PCL_NONE, PCL_NONE }, //int children[ 3 ]; - SOLDIER_COST, //int cost; - SOLDIER_VALUE //int value; + { PCL_ALIEN_LEVEL1, PCL_NONE, PCL_NONE }, //int children[ 3 ]; + LEVEL0_COST, //int cost; + LEVEL0_VALUE //int value; }, { - PCL_A_O_LEV1, //int classnum; - "hydra", //char *classname; + PCL_ALIEN_LEVEL1, //int classnum; + "level1", //char *classname; "Hydra", //char *humanname; "spitter", //char *modelname; 0.6f, //float modelScale; @@ -1560,31 +1560,31 @@ classAttributes_t bg_classList[ ] = { 18, 18, 4 }, //vec3_t deadmaxs; 0.0f, //float zOffset 0, 0, //int viewheight, crouchviewheight; - HYDRA_HEALTH, //int health; + LEVEL1_HEALTH, //int health; 0.0f, //float fallDamage; - HYDRA_REGEN, //int regenRate; + LEVEL1_REGEN, //int regenRate; SCA_NOWEAPONDRIFT| SCA_FOVWARPS|SCA_WALLCLIMBER|SCA_ALIENSENSE, //int abilities; - WP_HYDRA, //weapon_t startWeapon + WP_ALEVEL1, //weapon_t startWeapon 0.0f, //float buildDist; 120, //int fov; 0.001f, //float bob; 1.8f, //float bobCycle; 25, //int steptime; - HYDRA_SPEED, //float speed; + LEVEL1_SPEED, //float speed; 10.0f, //float acceleration; 1.0f, //float airAcceleration; 6.0f, //float friction; 300.0f, //float stopSpeed; 270.0f, //float jumpMagnitude; 1.2f, //float knockbackScale; - { PCL_A_O_LEV2, PCL_A_O_LEV1_UPG, PCL_NONE }, //int children[ 3 ]; - HYDRA_COST, //int cost; - HYDRA_VALUE //int value; + { PCL_ALIEN_LEVEL2, PCL_ALIEN_LEVEL1_UPG, PCL_NONE }, //int children[ 3 ]; + LEVEL1_COST, //int cost; + LEVEL1_VALUE //int value; }, { - PCL_A_O_LEV1_UPG, //int classnum; - "hydraupg", //char *classname; + PCL_ALIEN_LEVEL1_UPG, //int classnum; + "level1upg", //char *classname; "Hydra Upgrade", //char *humanname; "spitter", //char *modelname; 0.7f, //float modelScale; @@ -1599,31 +1599,31 @@ classAttributes_t bg_classList[ ] = { 20, 20, 4 }, //vec3_t deadmaxs; 0.0f, //float zOffset 0, 0, //int viewheight, crouchviewheight; - HYDRA_UPG_HEALTH, //int health; + LEVEL1_UPG_HEALTH, //int health; 0.0f, //float fallDamage; - HYDRA_UPG_REGEN, //int regenRate; + LEVEL1_UPG_REGEN, //int regenRate; SCA_NOWEAPONDRIFT|SCA_FOVWARPS| SCA_WALLCLIMBER|SCA_ALIENSENSE, //int abilities; - WP_HYDRA_UPG, //weapon_t startWeapon + WP_ALEVEL1_UPG, //weapon_t startWeapon 0.0f, //float buildDist; 120, //int fov; 0.001f, //float bob; 1.8f, //float bobCycle; 25, //int steptime; - HYDRA_UPG_SPEED, //float speed; + LEVEL1_UPG_SPEED, //float speed; 10.0f, //float acceleration; 1.0f, //float airAcceleration; 6.0f, //float friction; 300.0f, //float stopSpeed; 270.0f, //float jumpMagnitude; 1.1f, //float knockbackScale; - { PCL_A_O_LEV2, PCL_NONE, PCL_NONE }, //int children[ 3 ]; - HYDRA_UPG_COST, //int cost; - HYDRA_UPG_VALUE //int value; + { PCL_ALIEN_LEVEL2, PCL_NONE, PCL_NONE }, //int children[ 3 ]; + LEVEL1_UPG_COST, //int cost; + LEVEL1_UPG_VALUE //int value; }, { - PCL_A_O_LEV2, //int classnum; - "chimera", //char *classname; + PCL_ALIEN_LEVEL2, //int classnum; + "level2", //char *classname; "Chimera", //char *humanname; "tarantula", //char *modelname; 0.75f, //float modelScale; @@ -1638,31 +1638,31 @@ classAttributes_t bg_classList[ ] = { 22, 22, 4 }, //vec3_t deadmaxs; 0.0f, //float zOffset 10, 10, //int viewheight, crouchviewheight; - CHIMERA_HEALTH, //int health; + LEVEL2_HEALTH, //int health; 0.0f, //float fallDamage; - CHIMERA_REGEN, //int regenRate; + LEVEL2_REGEN, //int regenRate; SCA_NOWEAPONDRIFT|SCA_WALLJUMPER| SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; - WP_CHIMERA, //weapon_t startWeapon + WP_ALEVEL2, //weapon_t startWeapon 0.0f, //float buildDist; 90, //int fov; 0.001f, //float bob; 1.5f, //float bobCycle; 60, //int steptime; - CHIMERA_SPEED, //float speed; + LEVEL2_SPEED, //float speed; 10.0f, //float acceleration; 2.0f, //float airAcceleration; 6.0f, //float friction; 100.0f, //float stopSpeed; 400.0f, //float jumpMagnitude; 0.8f, //float knockbackScale; - { PCL_A_O_LEV3, PCL_A_O_LEV2_UPG, PCL_NONE }, //int children[ 3 ]; - CHIMERA_COST, //int cost; - CHIMERA_VALUE //int value; + { PCL_ALIEN_LEVEL3, PCL_ALIEN_LEVEL2_UPG, PCL_NONE }, //int children[ 3 ]; + LEVEL2_COST, //int cost; + LEVEL2_VALUE //int value; }, { - PCL_A_O_LEV2_UPG, //int classnum; - "chimeraupg", //char *classname; + PCL_ALIEN_LEVEL2_UPG, //int classnum; + "level2upg", //char *classname; "Chimera Upgrade", //char *humanname; "tarantula", //char *modelname; 0.9f, //float modelScale; @@ -1677,31 +1677,31 @@ classAttributes_t bg_classList[ ] = { 24, 24, 4 }, //vec3_t deadmaxs; 0.0f, //float zOffset 12, 12, //int viewheight, crouchviewheight; - CHIMERA_UPG_HEALTH, //int health; + LEVEL2_UPG_HEALTH, //int health; 0.0f, //float fallDamage; - CHIMERA_UPG_REGEN, //int regenRate; + LEVEL2_UPG_REGEN, //int regenRate; SCA_NOWEAPONDRIFT|SCA_WALLJUMPER| SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; - WP_CHIMERA_UPG, //weapon_t startWeapon + WP_ALEVEL2_UPG, //weapon_t startWeapon 0.0f, //float buildDist; 90, //int fov; 0.001f, //float bob; 1.5f, //float bobCycle; 60, //int steptime; - CHIMERA_UPG_SPEED, //float speed; + LEVEL2_UPG_SPEED, //float speed; 10.0f, //float acceleration; 2.0f, //float airAcceleration; 6.0f, //float friction; 100.0f, //float stopSpeed; 400.0f, //float jumpMagnitude; 0.7f, //float knockbackScale; - { PCL_A_O_LEV3, PCL_NONE, PCL_NONE }, //int children[ 3 ]; - CHIMERA_UPG_COST, //int cost; - CHIMERA_UPG_VALUE //int value; + { PCL_ALIEN_LEVEL3, PCL_NONE, PCL_NONE }, //int children[ 3 ]; + LEVEL2_UPG_COST, //int cost; + LEVEL2_UPG_VALUE //int value; }, { - PCL_A_O_LEV3, //int classnum; - "dragoon", //char *classname; + PCL_ALIEN_LEVEL3, //int classnum; + "level3", //char *classname; "Dragoon", //char *humanname; "prowl", //char *modelname; 1.0f, //float modelScale; @@ -1716,31 +1716,31 @@ classAttributes_t bg_classList[ ] = { 32, 32, 4 }, //vec3_t deadmaxs; 0.0f, //float zOffset 24, 24, //int viewheight, crouchviewheight; - DRAGOON_HEALTH, //int health; + LEVEL3_HEALTH, //int health; 0.0f, //float fallDamage; - DRAGOON_REGEN, //int regenRate; + LEVEL3_REGEN, //int regenRate; SCA_NOWEAPONDRIFT| SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; - WP_DRAGOON, //weapon_t startWeapon + WP_ALEVEL3, //weapon_t startWeapon 0.0f, //float buildDist; 110, //int fov; 0.0005f, //float bob; 1.3f, //float bobCycle; 25, //int steptime; - DRAGOON_SPEED, //float speed; + LEVEL3_SPEED, //float speed; 10.0f, //float acceleration; 1.0f, //float airAcceleration; 6.0f, //float friction; 200.0f, //float stopSpeed; 270.0f, //float jumpMagnitude; 0.5f, //float knockbackScale; - { PCL_A_O_LEV4, PCL_A_O_LEV3_UPG, PCL_NONE }, //int children[ 3 ]; - DRAGOON_COST, //int cost; - DRAGOON_VALUE //int value; + { PCL_ALIEN_LEVEL4, PCL_ALIEN_LEVEL3_UPG, PCL_NONE }, //int children[ 3 ]; + LEVEL3_COST, //int cost; + LEVEL3_VALUE //int value; }, { - PCL_A_O_LEV3_UPG, //int classnum; - "dragoonupg", //char *classname; + PCL_ALIEN_LEVEL3_UPG, //int classnum; + "level3upg", //char *classname; "Dragoon Upgrade", //char *humanname; "prowl", //char *modelname; 1.0f, //float modelScale; @@ -1755,31 +1755,31 @@ classAttributes_t bg_classList[ ] = { 32, 32, 4 }, //vec3_t deadmaxs; 0.0f, //float zOffset 27, 27, //int viewheight, crouchviewheight; - DRAGOON_UPG_HEALTH, //int health; + LEVEL3_UPG_HEALTH, //int health; 0.0f, //float fallDamage; - DRAGOON_UPG_REGEN, //int regenRate; + LEVEL3_UPG_REGEN, //int regenRate; SCA_NOWEAPONDRIFT| SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; - WP_DRAGOON_UPG, //weapon_t startWeapon + WP_ALEVEL3_UPG, //weapon_t startWeapon 0.0f, //float buildDist; 110, //int fov; 0.0005f, //float bob; 1.3f, //float bobCycle; 25, //int steptime; - DRAGOON_UPG_SPEED, //float speed; + LEVEL3_UPG_SPEED, //float speed; 10.0f, //float acceleration; 1.0f, //float airAcceleration; 6.0f, //float friction; 200.0f, //float stopSpeed; 270.0f, //float jumpMagnitude; 0.4f, //float knockbackScale; - { PCL_A_O_LEV4, PCL_NONE, PCL_NONE }, //int children[ 3 ]; - DRAGOON_UPG_COST, //int cost; - DRAGOON_UPG_VALUE //int value; + { PCL_ALIEN_LEVEL4, PCL_NONE, PCL_NONE }, //int children[ 3 ]; + LEVEL3_UPG_COST, //int cost; + LEVEL3_UPG_VALUE //int value; }, { - PCL_A_O_LEV4, //int classnum; - "bigmofo", //char *classname; + PCL_ALIEN_LEVEL4, //int classnum; + "level4", //char *classname; "Big Mofo", //char *humanname; "mofo", //char *modelname; 1.0f, //float modelScale; @@ -1794,18 +1794,18 @@ classAttributes_t bg_classList[ ] = { 15, 15, 4 }, //vec3_t deadmaxs; 0.0f, //float zOffset 35, 35, //int viewheight, crouchviewheight; - BMOFO_HEALTH, //int health; + LEVEL4_HEALTH, //int health; 0.0f, //float fallDamage; - BMOFO_REGEN, //int regenRate; + LEVEL4_REGEN, //int regenRate; SCA_NOWEAPONDRIFT| SCA_FOVWARPS|SCA_ALIENSENSE, //int abilities; - WP_BIGMOFO, //weapon_t startWeapon + WP_ALEVEL4, //weapon_t startWeapon 0.0f, //float buildDist; 90, //int fov; 0.001f, //float bob; 1.1f, //float bobCycle; 60, //int steptime; - BMOFO_SPEED, //float speed; + LEVEL4_SPEED, //float speed; 10.0f, //float acceleration; 1.0f, //float airAcceleration; 6.0f, //float friction; @@ -1813,12 +1813,12 @@ classAttributes_t bg_classList[ ] = 170.0f, //float jumpMagnitude; 0.1f, //float knockbackScale; { PCL_NONE, PCL_NONE, PCL_NONE }, //int children[ 3 ]; - BMOFO_COST, //int cost; - BMOFO_VALUE //int value; + LEVEL4_COST, //int cost; + LEVEL4_VALUE //int value; }, { - PCL_H_BASE, //int classnum; - "human", //char *classname; + PCL_HUMAN, //int classnum; + "human_base", //char *classname; "Human", //char *humanname; "sarge", //char *modelname; 1.0f, //float modelScale; @@ -1858,7 +1858,7 @@ classAttributes_t bg_classList[ ] = { //this isn't a real class, but a dummy to force the client to precache the model //FIXME: one day do this in a less hacky fashion - PCL_H_BSUIT, "bsuit", "bsuit", + PCL_HUMAN_BSUIT, "human_bsuit", "bsuit", "keel", 1.0f, @@ -1924,6 +1924,9 @@ char *BG_FindHumanNameForClassNum( int pclass ) { int i; + if( bg_classOverrideList[ pclass ].humanName[ 0 ] != 0 ) + return bg_classOverrideList[ pclass ].humanName; + for( i = 0; i < bg_numPclasses; i++ ) { if( bg_classList[ i ].classNum == pclass ) @@ -2841,6 +2844,16 @@ static qboolean BG_ParseClassFile( const char *filename, classAttributeOverrides continue; } + else if( !Q_stricmp( token, "name" ) ) + { + token = COM_Parse( &text_p ); + if( !token ) + break; + + Q_strncpyz( cao->humanName, token, sizeof( cao->humanName ) ); + + continue; + } Com_Printf( S_COLOR_RED "ERROR: unknown token '%s'\n", token ); @@ -3115,6 +3128,30 @@ weaponAttributes_t bg_weapons[ ] = WUT_HUMANS //WUTeam_t team; }, { + WP_GRENADE, //int weaponNum; + GRENADE_PRICE, //int price; + ( 1 << S2 )|( 1 << S3 ), //int stages + SLOT_NONE, //int slots; + "grenade", //char *weaponName; + "Grenade", //char *weaponHumanName; + 1, //int quan; + 0, //int clips; + 0, //int maxClips; + qfalse, //int infiniteAmmo; + qfalse, //int usesEnergy; + GRENADE_REPEAT, //int repeatRate1; + 0, //int repeatRate2; + 0, //int repeatRate3; + 0, //int reloadTime; + qfalse, //qboolean hasAltMode; + qfalse, //qboolean hasThirdMode; + qfalse, //qboolean canZoom; + 90.0f, //float zoomFov; + qtrue, //qboolean purchasable; + 0, //int buildDelay; + WUT_HUMANS //WUTeam_t team; + }, + { WP_HBUILD, //int weaponNum; HBUILD_PRICE, //int price; ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages @@ -3211,7 +3248,7 @@ weaponAttributes_t bg_weapons[ ] = WUT_ALIENS //WUTeam_t team; }, { - WP_SOLDIER, //int weaponNum; + WP_ALEVEL0, //int weaponNum; 0, //int price; ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages SLOT_WEAPON, //int slots; @@ -3222,7 +3259,7 @@ weaponAttributes_t bg_weapons[ ] = 0, //int maxClips; qtrue, //int infiniteAmmo; qfalse, //int usesEnergy; - SOLDIER_BITE_REPEAT, //int repeatRate1; + LEVEL0_BITE_REPEAT, //int repeatRate1; 0, //int repeatRate2; 0, //int repeatRate3; 0, //int reloadTime; @@ -3235,7 +3272,7 @@ weaponAttributes_t bg_weapons[ ] = WUT_ALIENS //WUTeam_t team; }, { - WP_DRAGOON, //int weaponNum; + WP_ALEVEL3, //int weaponNum; 0, //int price; ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages SLOT_WEAPON, //int slots; @@ -3246,7 +3283,7 @@ weaponAttributes_t bg_weapons[ ] = 0, //int maxClips; qtrue, //int infiniteAmmo; qfalse, //int usesEnergy; - DRAGOON_CLAW_REPEAT, //int repeatRate1; + LEVEL3_CLAW_REPEAT, //int repeatRate1; 0, //int repeatRate2; 0, //int repeatRate3; 0, //int reloadTime; @@ -3259,7 +3296,7 @@ weaponAttributes_t bg_weapons[ ] = WUT_ALIENS //WUTeam_t team; }, { - WP_DRAGOON_UPG, //int weaponNum; + WP_ALEVEL3_UPG, //int weaponNum; 0, //int price; ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages SLOT_WEAPON, //int slots; @@ -3270,9 +3307,9 @@ weaponAttributes_t bg_weapons[ ] = 0, //int maxClips; qtrue, //int infiniteAmmo; qfalse, //int usesEnergy; - DRAGOON_CLAW_U_REPEAT,//int repeatRate1; + LEVEL3_CLAW_U_REPEAT,//int repeatRate1; 0, //int repeatRate2; - DRAGOON_BOUNCEBALL_REPEAT,//int repeatRate3; + LEVEL3_BOUNCEBALL_REPEAT,//int repeatRate3; 0, //int reloadTime; qfalse, //qboolean hasAltMode; qtrue, //qboolean hasThirdMode; @@ -3283,7 +3320,7 @@ weaponAttributes_t bg_weapons[ ] = WUT_ALIENS //WUTeam_t team; }, { - WP_HYDRA, //int weaponNum; + WP_ALEVEL1, //int weaponNum; 0, //int price; ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages SLOT_WEAPON, //int slots; @@ -3294,7 +3331,7 @@ weaponAttributes_t bg_weapons[ ] = 0, //int maxClips; qtrue, //int infiniteAmmo; qfalse, //int usesEnergy; - HYDRA_CLAW_REPEAT, //int repeatRate1; + LEVEL1_CLAW_REPEAT, //int repeatRate1; 0, //int repeatRate2; 0, //int repeatRate3; 0, //int reloadTime; @@ -3307,7 +3344,7 @@ weaponAttributes_t bg_weapons[ ] = WUT_ALIENS //WUTeam_t team; }, { - WP_HYDRA_UPG, //int weaponNum; + WP_ALEVEL1_UPG, //int weaponNum; 0, //int price; ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages SLOT_WEAPON, //int slots; @@ -3318,8 +3355,8 @@ weaponAttributes_t bg_weapons[ ] = 0, //int maxClips; qtrue, //int infiniteAmmo; qfalse, //int usesEnergy; - HYDRA_CLAW_U_REPEAT, //int repeatRate1; - HYDRA_PCLOUD_REPEAT, //int repeatRate2; + LEVEL1_CLAW_U_REPEAT, //int repeatRate1; + LEVEL1_PCLOUD_REPEAT, //int repeatRate2; 0, //int repeatRate3; 0, //int reloadTime; qtrue, //qboolean hasAltMode; @@ -3331,7 +3368,7 @@ weaponAttributes_t bg_weapons[ ] = WUT_ALIENS //WUTeam_t team; }, { - WP_CHIMERA, //int weaponNum; + WP_ALEVEL2, //int weaponNum; 0, //int price; ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages SLOT_WEAPON, //int slots; @@ -3342,7 +3379,7 @@ weaponAttributes_t bg_weapons[ ] = 0, //int maxClips; qtrue, //int infiniteAmmo; qfalse, //int usesEnergy; - CHIMERA_CLAW_REPEAT, //int repeatRate1; + LEVEL2_CLAW_REPEAT, //int repeatRate1; 0, //int repeatRate2; 0, //int repeatRate3; 0, //int reloadTime; @@ -3355,7 +3392,7 @@ weaponAttributes_t bg_weapons[ ] = WUT_ALIENS //WUTeam_t team; }, { - WP_CHIMERA_UPG, //int weaponNum; + WP_ALEVEL2_UPG, //int weaponNum; 0, //int price; ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages SLOT_WEAPON, //int slots; @@ -3366,8 +3403,8 @@ weaponAttributes_t bg_weapons[ ] = 0, //int maxClips; qtrue, //int infiniteAmmo; qfalse, //int usesEnergy; - CHIMERA_CLAW_U_REPEAT,//int repeatRate1; - CHIMERA_AREAZAP_REPEAT,//int repeatRate2; + LEVEL2_CLAW_U_REPEAT,//int repeatRate1; + LEVEL2_AREAZAP_REPEAT,//int repeatRate2; 0, //int repeatRate3; 0, //int reloadTime; qtrue, //qboolean hasAltMode; @@ -3379,7 +3416,7 @@ weaponAttributes_t bg_weapons[ ] = WUT_ALIENS //WUTeam_t team; }, { - WP_BIGMOFO, //int weaponNum; + WP_ALEVEL4, //int weaponNum; 0, //int price; ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages SLOT_WEAPON, //int slots; @@ -3390,7 +3427,7 @@ weaponAttributes_t bg_weapons[ ] = 0, //int maxClips; qtrue, //int infiniteAmmo; qfalse, //int usesEnergy; - BMOFO_CLAW_REPEAT, //int repeatRate1; + LEVEL4_CLAW_REPEAT, //int repeatRate1; 0, //int repeatRate2; 0, //int repeatRate3; 0, //int reloadTime; @@ -4318,6 +4355,10 @@ char *eventnames[ ] = "EV_ALIENZAP", "EV_BULLET", // otherEntity is the shooter + "EV_LEV1_GRAB", + "EV_LEV4_CHARGE_PREPARE", + "EV_LEV4_CHARGE_START", + "EV_PAIN", "EV_DEATH1", "EV_DEATH2", @@ -4338,6 +4379,7 @@ char *eventnames[ ] = "EV_ALIEN_BUILDABLE_DAMAGE", "EV_ALIEN_EVOLVE", + "EV_ALIEN_EVOLVE_FAILED", "EV_DEBUG_LINE", "EV_STOPLOOPINGSOUND", diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c index c1afd750..b2606c23 100644 --- a/src/game/bg_pmove.c +++ b/src/game/bg_pmove.c @@ -382,8 +382,9 @@ static float PM_CmdScale( usercmd_t *cmd ) } } - if( pm->ps->weapon == WP_BIGMOFO && pm->ps->pm_flags & PMF_CHARGE ) - modifier *= ( 1.0f + ( pm->ps->stats[ STAT_MISC ] / (float)BMOFO_CHARGE_TIME ) * ( BMOFO_CHARGE_SPEED - 1.0f ) ); + if( pm->ps->weapon == WP_ALEVEL4 && pm->ps->pm_flags & PMF_CHARGE ) + modifier *= ( 1.0f + ( pm->ps->stats[ STAT_MISC ] / (float)LEVEL4_CHARGE_TIME ) * + ( LEVEL4_CHARGE_SPEED - 1.0f ) ); if( pm->ps->pm_type == PM_GRABBED ) modifier = 0.0f; @@ -466,7 +467,7 @@ PM_CheckCharge */ static void PM_CheckCharge( void ) { - if( pm->ps->weapon != WP_BIGMOFO ) + if( pm->ps->weapon != WP_ALEVEL4 ) return; if( pm->cmd.buttons & BUTTON_ATTACK2 ) @@ -488,8 +489,8 @@ PM_CheckPounce */ static qboolean PM_CheckPounce( void ) { - if( pm->ps->weapon != WP_DRAGOON && - pm->ps->weapon != WP_DRAGOON_UPG ) + if( pm->ps->weapon != WP_ALEVEL3 && + pm->ps->weapon != WP_ALEVEL3_UPG ) return qfalse; if( pm->cmd.buttons & BUTTON_ATTACK2 ) @@ -600,10 +601,10 @@ static qboolean PM_CheckWallJump( void ) dir, pm->ps->velocity ); //for a long run of wall jumps the velocity can get pretty large, this caps it - if( VectorLength( pm->ps->velocity ) > CHIMERA_WALLJUMP_MAXSPEED ) + if( VectorLength( pm->ps->velocity ) > LEVEL2_WALLJUMP_MAXSPEED ) { VectorNormalize( pm->ps->velocity ); - VectorScale( pm->ps->velocity, CHIMERA_WALLJUMP_MAXSPEED, pm->ps->velocity ); + VectorScale( pm->ps->velocity, LEVEL2_WALLJUMP_MAXSPEED, pm->ps->velocity ); } PM_AddEvent( EV_JUMP ); @@ -644,13 +645,13 @@ static qboolean PM_CheckJump( void ) return PM_CheckWallJump( ); //can't jump and pounce at the same time - if( ( pm->ps->weapon == WP_DRAGOON || - pm->ps->weapon == WP_DRAGOON_UPG ) && + if( ( pm->ps->weapon == WP_ALEVEL3 || + pm->ps->weapon == WP_ALEVEL3_UPG ) && pm->ps->stats[ STAT_MISC ] > 0 ) return qfalse; //can't jump and charge at the same time - if( ( pm->ps->weapon == WP_BIGMOFO ) && + if( ( pm->ps->weapon == WP_ALEVEL4 ) && pm->ps->stats[ STAT_MISC ] > 0 ) return qfalse; @@ -2426,7 +2427,7 @@ static void PM_Footsteps( void ) { bobmove = 0.4f; // faster speeds bob faster - if( pm->ps->weapon == WP_BIGMOFO && pm->ps->pm_flags & PMF_CHARGE ) + if( pm->ps->weapon == WP_ALEVEL4 && pm->ps->pm_flags & PMF_CHARGE ) PM_ContinueLegsAnim( NSPA_CHARGE ); else if( pm->ps->pm_flags & PMF_BACKWARDS_RUN ) { @@ -2797,7 +2798,7 @@ static void PM_Weapon( void ) //check if non-auto primary/secondary attacks are permited switch( pm->ps->weapon ) { - case WP_SOLDIER: + case WP_ALEVEL0: //venom is only autohit attack1 = attack2 = attack3 = qfalse; @@ -2809,8 +2810,8 @@ static void PM_Weapon( void ) } break; - case WP_DRAGOON: - case WP_DRAGOON_UPG: + case WP_ALEVEL3: + case WP_ALEVEL3_UPG: //pouncing has primary secondary AND autohit procedures attack1 = pm->cmd.buttons & BUTTON_ATTACK; attack2 = pm->cmd.buttons & BUTTON_ATTACK2; @@ -2867,7 +2868,7 @@ static void PM_Weapon( void ) if( BG_WeaponHasThirdMode( pm->ps->weapon ) ) { //hacky special case for slowblob - if( pm->ps->weapon == WP_DRAGOON_UPG && !ammo ) + if( pm->ps->weapon == WP_ALEVEL3_UPG && !ammo ) { PM_AddEvent( EV_NOAMMO ); pm->ps->weaponTime += 200; @@ -2912,14 +2913,14 @@ static void PM_Weapon( void ) { switch( pm->ps->weapon ) { - case WP_SOLDIER: + case WP_ALEVEL0: pm->ps->generic1 = WPM_PRIMARY; PM_AddEvent( EV_FIRE_WEAPON ); addTime = BG_FindRepeatRate1ForWeapon( pm->ps->weapon ); break; - case WP_DRAGOON: - case WP_DRAGOON_UPG: + case WP_ALEVEL3: + case WP_ALEVEL3_UPG: pm->ps->generic1 = WPM_SECONDARY; PM_AddEvent( EV_FIRE_WEAPON2 ); addTime = BG_FindRepeatRate2ForWeapon( pm->ps->weapon ); @@ -2953,7 +2954,7 @@ static void PM_Weapon( void ) } else { - if( pm->ps->weapon == WP_BIGMOFO ) + if( pm->ps->weapon == WP_ALEVEL4 ) { //hack to get random attack animations //FIXME: does pm->ps->weaponTime cycle enough? @@ -2998,7 +2999,7 @@ static void PM_Weapon( void ) BG_PackAmmoArray( pm->ps->weapon, pm->ps->ammo, pm->ps->powerups, ammo, clips, maxclips ); } - else if( pm->ps->weapon == WP_DRAGOON_UPG && attack3 ) + else if( pm->ps->weapon == WP_ALEVEL3_UPG && attack3 ) { //special case for slowblob ammo--; diff --git a/src/game/bg_public.h b/src/game/bg_public.h index d8c6053f..a90bf0cc 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -328,14 +328,14 @@ typedef enum { WP_NONE, - WP_SOLDIER, - WP_HYDRA, - WP_HYDRA_UPG, - WP_CHIMERA, - WP_CHIMERA_UPG, - WP_DRAGOON, - WP_DRAGOON_UPG, - WP_BIGMOFO, + WP_ALEVEL0, + WP_ALEVEL1, + WP_ALEVEL1_UPG, + WP_ALEVEL2, + WP_ALEVEL2_UPG, + WP_ALEVEL3, + WP_ALEVEL3_UPG, + WP_ALEVEL4, WP_BLASTER, WP_MACHINEGUN, @@ -347,6 +347,7 @@ typedef enum WP_PULSE_RIFLE, WP_FLAMER, WP_LUCIFER_CANNON, + WP_GRENADE, WP_LOCKBLOB_LAUNCHER, WP_HIVE, @@ -529,6 +530,10 @@ typedef enum EV_ALIENZAP, EV_BULLET, // otherEntity is the shooter + EV_LEV1_GRAB, + EV_LEV4_CHARGE_PREPARE, + EV_LEV4_CHARGE_START, + EV_PAIN, EV_DEATH1, EV_DEATH2, @@ -549,6 +554,7 @@ typedef enum EV_ALIEN_BUILDABLE_DAMAGE, EV_ALIEN_EVOLVE, + EV_ALIEN_EVOLVE_FAILED, EV_DEBUG_LINE, EV_STOPLOOPINGSOUND, @@ -778,22 +784,22 @@ typedef enum PCL_NONE, //builder classes - PCL_A_B_BASE, - PCL_A_B_LEV1, + PCL_ALIEN_BUILDER0, + PCL_ALIEN_BUILDER0_UPG, //offensive classes - PCL_A_O_BASE, - PCL_A_O_LEV1, - PCL_A_O_LEV1_UPG, - PCL_A_O_LEV2, - PCL_A_O_LEV2_UPG, - PCL_A_O_LEV3, - PCL_A_O_LEV3_UPG, - PCL_A_O_LEV4, + PCL_ALIEN_LEVEL0, + PCL_ALIEN_LEVEL1, + PCL_ALIEN_LEVEL1_UPG, + PCL_ALIEN_LEVEL2, + PCL_ALIEN_LEVEL2_UPG, + PCL_ALIEN_LEVEL3, + PCL_ALIEN_LEVEL3_UPG, + PCL_ALIEN_LEVEL4, //human class - PCL_H_BASE, - PCL_H_BSUIT, + PCL_HUMAN, + PCL_HUMAN_BSUIT, PCL_NUM_CLASSES } pClass_t; @@ -826,6 +832,7 @@ typedef enum MOD_LCANNON_SPLASH, MOD_FLAMER, MOD_FLAMER_SPLASH, + MOD_GRENADE, MOD_WATER, MOD_SLIME, MOD_LAVA, @@ -837,16 +844,16 @@ typedef enum MOD_TRIGGER_HURT, MOD_ABUILDER_CLAW, - MOD_SOLDIER_BITE, - MOD_HYDRA_CLAW, - MOD_HYDRA_PCLOUD, - MOD_DRAGOON_CLAW, - MOD_DRAGOON_POUNCE, - MOD_DRAGOON_BOUNCEBALL, - MOD_CHIMERA_CLAW, - MOD_CHIMERA_ZAP, - MOD_BMOFO_CLAW, - MOD_BMOFO_CHARGE, + MOD_LEVEL0_BITE, + MOD_LEVEL1_CLAW, + MOD_LEVEL1_PCLOUD, + MOD_LEVEL3_CLAW, + MOD_LEVEL3_POUNCE, + MOD_LEVEL3_BOUNCEBALL, + MOD_LEVEL2_CLAW, + MOD_LEVEL2_ZAP, + MOD_LEVEL4_CLAW, + MOD_LEVEL4_CHARGE, MOD_SLOWBLOB, MOD_POISON, @@ -927,6 +934,7 @@ typedef struct char skinName[ MAX_QPATH ]; float shadowScale; char hudName[ MAX_QPATH ]; + char humanName[ MAX_STRING_CHARS ]; vec3_t mins; vec3_t maxs; @@ -1264,6 +1272,13 @@ void ProjectPointOntoVector( vec3_t point, vec3_t vStart, float VectorDistance( vec3_t v1, vec3_t v2 ); // done. +//call roundf in place of round on non VM platforms +#ifdef Q3_VM +#define roundf round +#else +#define round roundf +#endif + #define M_ROOT3 1.732050808f float VectorMinComponent( vec3_t v ); float VectorMaxComponent( vec3_t v ); diff --git a/src/game/g_active.c b/src/game/g_active.c index 836ae90c..820586d9 100644 --- a/src/game/g_active.c +++ b/src/game/g_active.c @@ -214,7 +214,7 @@ void ClientImpacts( gentity_t *ent, pmove_t *pm ) ent->touch( ent, other, &trace ); //charge attack - if( ent->client->ps.weapon == WP_BIGMOFO && + if( ent->client->ps.weapon == WP_ALEVEL4 && ent->client->ps.stats[ STAT_MISC ] > 0 && ent->client->charging ) ChargeAttack( ent, other ); @@ -505,17 +505,17 @@ void ClientTimerActions( gentity_t *ent, int msec ) } //client is charging up for a pounce - if( client->ps.weapon == WP_DRAGOON || client->ps.weapon == WP_DRAGOON_UPG ) + if( client->ps.weapon == WP_ALEVEL3 || client->ps.weapon == WP_ALEVEL3_UPG ) { int pounceSpeed; - if( client->ps.weapon == WP_DRAGOON ) - pounceSpeed = DRAGOON_POUNCE_SPEED; - else if( client->ps.weapon == WP_DRAGOON_UPG ) - pounceSpeed = DRAGOON_POUNCE_UPG_SPEED; + if( client->ps.weapon == WP_ALEVEL3 ) + pounceSpeed = LEVEL3_POUNCE_SPEED; + else if( client->ps.weapon == WP_ALEVEL3_UPG ) + pounceSpeed = LEVEL3_POUNCE_UPG_SPEED; if( client->ps.stats[ STAT_MISC ] < pounceSpeed && ucmd->buttons & BUTTON_ATTACK2 ) - client->ps.stats[ STAT_MISC ] += ( 100.0f / (float)DRAGOON_POUNCE_TIME ) * pounceSpeed; + client->ps.stats[ STAT_MISC ] += ( 100.0f / (float)LEVEL3_POUNCE_TIME ) * pounceSpeed; if( !( ucmd->buttons & BUTTON_ATTACK2 ) ) { @@ -533,24 +533,32 @@ void ClientTimerActions( gentity_t *ent, int msec ) } //client is charging up for a... charge - if( client->ps.weapon == WP_BIGMOFO ) + if( client->ps.weapon == WP_ALEVEL4 ) { - if( client->ps.stats[ STAT_MISC ] < BMOFO_CHARGE_TIME && ucmd->buttons & BUTTON_ATTACK2 && - ( ucmd->forwardmove > 0 ) ) + if( client->ps.stats[ STAT_MISC ] < LEVEL4_CHARGE_TIME && ucmd->buttons & BUTTON_ATTACK2 && + ( ucmd->forwardmove > 0 ) && !client->charging ) { client->charging = qfalse; //should already be off, just making sure - client->ps.stats[ STAT_MISC ] += (int)( 100 * (float)BMOFO_CHARGE_CHARGE_RATIO ); + //trigger charge sound + if( client->ps.stats[ STAT_MISC ] <= 0 ) + G_AddEvent( ent, EV_LEV4_CHARGE_PREPARE, 0 ); + + client->ps.stats[ STAT_MISC ] += (int)( 100 * (float)LEVEL4_CHARGE_CHARGE_RATIO ); - if( client->ps.stats[ STAT_MISC ] > BMOFO_CHARGE_TIME ) - client->ps.stats[ STAT_MISC ] = BMOFO_CHARGE_TIME; + if( client->ps.stats[ STAT_MISC ] > LEVEL4_CHARGE_TIME ) + client->ps.stats[ STAT_MISC ] = LEVEL4_CHARGE_TIME; } - if( !( ucmd->buttons & BUTTON_ATTACK2 ) ) + if( !( ucmd->buttons & BUTTON_ATTACK2 ) || client->charging ) { if( client->ps.stats[ STAT_MISC ] > 0 ) { client->ps.stats[ STAT_MISC ] -= 100; + + if( client->charging == qfalse ) + G_AddEvent( ent, EV_LEV4_CHARGE_START, 0 ); + client->charging = qtrue; //if the charger has stopped moving take a chunk of charge away @@ -623,10 +631,10 @@ void ClientTimerActions( gentity_t *ent, int msec ) { client->time1000 -= 1000; - //client is hydra poisoned + //client is poison clouded if( client->ps.stats[ STAT_STATE ] & SS_POISONCLOUDED ) G_Damage( ent, client->lastPoisonCloudedClient, client->lastPoisonCloudedClient, NULL, NULL, - HYDRA_PCLOUD_DMG, 0, MOD_HYDRA_PCLOUD ); + LEVEL1_PCLOUD_DMG, 0, MOD_LEVEL1_PCLOUD ); //client is poisoned if( client->ps.stats[ STAT_STATE ] & SS_POISONED ) @@ -653,7 +661,7 @@ void ClientTimerActions( gentity_t *ent, int msec ) if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) { int entityList[ MAX_GENTITIES ]; - vec3_t range = { BMOFO_REGEN_RANGE, BMOFO_REGEN_RANGE, BMOFO_REGEN_RANGE }; + vec3_t range = { LEVEL4_REGEN_RANGE, LEVEL4_REGEN_RANGE, LEVEL4_REGEN_RANGE }; vec3_t mins, maxs, dir; int i, num; gentity_t *alienPlayer; @@ -668,9 +676,9 @@ void ClientTimerActions( gentity_t *ent, int msec ) alienPlayer = &g_entities[ entityList[ i ] ]; if( alienPlayer->client && alienPlayer->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS && - alienPlayer->client->ps.stats[ STAT_PCLASS ] == PCL_A_O_LEV4 ) + alienPlayer->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_LEVEL4 ) { - modifier = BMOFO_REGEN_MOD; + modifier = LEVEL4_REGEN_MOD; break; } } @@ -688,17 +696,17 @@ void ClientTimerActions( gentity_t *ent, int msec ) { client->time10000 -= 10000; - if( client->ps.weapon == WP_DRAGOON_UPG ) + if( client->ps.weapon == WP_ALEVEL3_UPG ) { int ammo, maxAmmo; - BG_FindAmmoForWeapon( WP_DRAGOON_UPG, &maxAmmo, NULL, NULL ); - BG_UnpackAmmoArray( WP_DRAGOON_UPG, client->ps.ammo, client->ps.powerups, &ammo, NULL, NULL ); + BG_FindAmmoForWeapon( WP_ALEVEL3_UPG, &maxAmmo, NULL, NULL ); + BG_UnpackAmmoArray( WP_ALEVEL3_UPG, client->ps.ammo, client->ps.powerups, &ammo, NULL, NULL ); if( ammo < maxAmmo ) { ammo++; - BG_PackAmmoArray( WP_DRAGOON_UPG, client->ps.ammo, client->ps.powerups, ammo, 0, 0 ); + BG_PackAmmoArray( WP_ALEVEL3_UPG, client->ps.ammo, client->ps.powerups, ammo, 0, 0 ); } } } @@ -794,6 +802,40 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) FireWeapon3( ent ); break; + case EV_NOAMMO: + //if we just ran out of grenades, remove the inventory item + if( ent->s.weapon == WP_GRENADE ) + { + int j; + + BG_RemoveWeaponFromInventory( ent->s.weapon, ent->client->ps.stats ); + + //force a weapon change + ent->client->ps.pm_flags |= PMF_WEAPON_SWITCH; + + //switch to the first non blaster weapon + for( j = WP_NONE + 1; j < WP_NUM_WEAPONS; j++ ) + { + if( j == WP_BLASTER ) + continue; + + if( BG_InventoryContainsWeapon( j, ent->client->ps.stats ) ) + { + trap_SendServerCommand( ent - g_entities, va( "weaponswitch %d", j ) ); + break; + } + } + + //only got the blaster to switch to + if( j == WP_NUM_WEAPONS ) + trap_SendServerCommand( ent - g_entities, va( "weaponswitch %d", WP_BLASTER ) ); + + //update ClientInfo + ClientUserinfoChanged( ent->client->ps.clientNum ); + } + + break; + default: break; } @@ -992,7 +1034,7 @@ void ClientThink_real( gentity_t *ent ) client->ps.pm_type = PM_NORMAL; if( client->ps.stats[ STAT_STATE ] & SS_GRABBED && - client->lastGrabTime + HYDRA_GRAB_TIME < level.time ) + client->lastGrabTime + LEVEL1_GRAB_TIME < level.time ) client->ps.stats[ STAT_STATE ] &= ~SS_GRABBED; if( client->ps.stats[ STAT_STATE ] & SS_BLOBLOCKED && @@ -1010,7 +1052,7 @@ void ClientThink_real( gentity_t *ent ) client->ps.stats[ STAT_STATE ] &= ~SS_BOOSTED; if( client->ps.stats[ STAT_STATE ] & SS_POISONCLOUDED && - client->lastPoisonCloudedTime + HYDRA_PCLOUD_TIME < level.time ) + client->lastPoisonCloudedTime + LEVEL1_PCLOUD_TIME < level.time ) client->ps.stats[ STAT_STATE ] &= ~SS_POISONCLOUDED; if( client->ps.stats[ STAT_STATE ] & SS_POISONED && @@ -1035,9 +1077,9 @@ void ClientThink_real( gentity_t *ent ) client->ps.speed = g_speed.value * BG_FindSpeedForClass( client->ps.stats[ STAT_PCLASS ] ); //TA: slow player if charging up for a pounce - if( ( client->ps.weapon == WP_DRAGOON || client->ps.weapon == WP_DRAGOON_UPG ) && + if( ( client->ps.weapon == WP_ALEVEL3 || client->ps.weapon == WP_ALEVEL3_UPG ) && ucmd->buttons & BUTTON_ATTACK2 ) - client->ps.speed *= DRAGOON_POUNCE_SPEED_MOD; + client->ps.speed *= LEVEL3_POUNCE_SPEED_MOD; //TA: slow the player if slow locked if( client->ps.stats[ STAT_STATE ] & SS_SLOWLOCKED ) @@ -1070,18 +1112,18 @@ void ClientThink_real( gentity_t *ent ) { switch( client->ps.weapon ) { - case WP_SOLDIER: + case WP_ALEVEL0: if( client->ps.weaponTime <= 0 ) pm.autoWeaponHit[ client->ps.weapon ] = CheckVenomAttack( ent ); break; - case WP_HYDRA: - case WP_HYDRA_UPG: + case WP_ALEVEL1: + case WP_ALEVEL1_UPG: CheckGrabAttack( ent ); break; - case WP_DRAGOON: - case WP_DRAGOON_UPG: + case WP_ALEVEL3: + case WP_ALEVEL3_UPG: if( client->ps.weaponTime <= 0 ) pm.autoWeaponHit[ client->ps.weapon ] = CheckPounceAttack( ent ); break; @@ -1261,6 +1303,11 @@ void ClientThink_real( gentity_t *ent ) //no nearby objects and alien - show class menu G_TriggerMenu( ent->client->ps.clientNum, MN_A_INFEST ); } + else + { + //flash frags + G_AddEvent( ent, EV_ALIEN_EVOLVE_FAILED, 0 ); + } } } } @@ -1310,11 +1357,11 @@ void ClientThink_real( gentity_t *ent ) { if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) { - G_AddCreditToClient( ent->client, FREEKILL_ALIEN ); + G_AddCreditToClient( ent->client, FREEKILL_ALIEN, qtrue ); } else if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) { - G_AddCreditToClient( ent->client, FREEKILL_HUMAN ); + G_AddCreditToClient( ent->client, FREEKILL_HUMAN, qtrue ); } ent->client->lastKillTime = level.time; diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index a959e087..f74715ba 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -83,7 +83,7 @@ gentity_t *G_CheckSpawnPoint( vec3_t origin, vec3_t normal, buildable_t spawn, v } else if( spawn == BA_H_SPAWN ) { - BG_FindBBoxForClass( PCL_H_BASE, cmins, cmaxs, NULL, NULL, NULL ); + BG_FindBBoxForClass( PCL_HUMAN, cmins, cmaxs, NULL, NULL, NULL ); VectorCopy( origin, localOrigin ); localOrigin[ 2 ] += maxs[ 2 ] + fabs( cmins[ 2 ] ) + 1.0f; @@ -581,9 +581,9 @@ void ASpawn_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int if( attacker && attacker->client && attacker->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) { if( self->s.modelindex == BA_A_OVERMIND ) - G_AddCreditToClient( attacker->client, OVERMIND_VALUE ); + G_AddCreditToClient( attacker->client, OVERMIND_VALUE, qtrue ); else if( self->s.modelindex == BA_A_SPAWN ) - G_AddCreditToClient( attacker->client, ASPAWN_VALUE ); + G_AddCreditToClient( attacker->client, ASPAWN_VALUE, qtrue ); } } @@ -1086,8 +1086,8 @@ void AHovel_Use( gentity_t *self, gentity_t *other, gentity_t *activator ) //this hovel is in use G_TriggerMenu( activator->client->ps.clientNum, 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 ) ) && + else if( ( ( activator->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_BUILDER0 ) || + ( activator->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_BUILDER0_UPG ) ) && activator->health > 0 && self->health > 0 ) { if( AHovel_Blocked( self, activator, qfalse ) ) @@ -2144,9 +2144,9 @@ void HSpawn_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int if( attacker && attacker->client && attacker->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) { if( self->s.modelindex == BA_H_REACTOR ) - G_AddCreditToClient( attacker->client, REACTOR_VALUE ); + G_AddCreditToClient( attacker->client, REACTOR_VALUE, qtrue ); else if( self->s.modelindex == BA_H_SPAWN ) - G_AddCreditToClient( attacker->client, HSPAWN_VALUE ); + G_AddCreditToClient( attacker->client, HSPAWN_VALUE, qtrue ); } } @@ -2421,7 +2421,7 @@ itemBuildError_t G_itemFits( gentity_t *ent, buildable_t buildable, int distance vec3_t builderMins, builderMaxs; //this assumes the adv builder is the biggest thing that'll use the hovel - BG_FindBBoxForClass( PCL_A_B_LEV1, builderMins, builderMaxs, NULL, NULL, NULL ); + BG_FindBBoxForClass( PCL_ALIEN_BUILDER0_UPG, builderMins, builderMaxs, NULL, NULL, NULL ); if( APropHovel_Blocked( angles, origin, normal, ent ) ) reason = IBE_HOVELEXIT; diff --git a/src/game/g_client.c b/src/game/g_client.c index 83d3e8e6..7e3cebb3 100644 --- a/src/game/g_client.c +++ b/src/game/g_client.c @@ -77,22 +77,42 @@ void SP_info_human_intermission( gentity_t *ent ) G_AddCreditToClient =============== */ -void G_AddCreditToClient( gclient_t *client, short credit ) +void G_AddCreditToClient( gclient_t *client, short credit, qboolean cap ) { if( !client ) return; - client->ps.persistant[ PERS_CREDIT ] += credit; - - if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) + //if we're already at the max and trying to add credit then stop + if( cap ) { - if( client->ps.persistant[ PERS_CREDIT ] > ALIEN_MAX_KILLS ) - client->ps.persistant[ PERS_CREDIT ] = ALIEN_MAX_KILLS; + if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) + { + if( client->ps.persistant[ PERS_CREDIT ] >= ALIEN_MAX_KILLS && + credit > 0 ) + return; + } + else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) + { + if( client->ps.persistant[ PERS_CREDIT ] >= HUMAN_MAX_CREDITS && + credit > 0 ) + return; + } } - else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) + + client->ps.persistant[ PERS_CREDIT ] += credit; + + if( cap ) { - if( client->ps.persistant[ PERS_CREDIT ] > HUMAN_MAX_CREDITS ) - client->ps.persistant[ PERS_CREDIT ] = HUMAN_MAX_CREDITS; + if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) + { + if( client->ps.persistant[ PERS_CREDIT ] > ALIEN_MAX_KILLS ) + client->ps.persistant[ PERS_CREDIT ] = ALIEN_MAX_KILLS; + } + else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) + { + if( client->ps.persistant[ PERS_CREDIT ] > HUMAN_MAX_CREDITS ) + client->ps.persistant[ PERS_CREDIT ] = HUMAN_MAX_CREDITS; + } } if( client->ps.persistant[ PERS_CREDIT ] < 0 ) @@ -996,10 +1016,10 @@ void ClientUserinfoChanged( int clientNum ) client->pers.maxHealth = 0; // set model - if( client->ps.stats[ STAT_PCLASS ] == PCL_H_BASE && BG_InventoryContainsUpgrade( UP_BATTLESUIT, client->ps.stats ) ) + if( client->ps.stats[ STAT_PCLASS ] == PCL_HUMAN && BG_InventoryContainsUpgrade( UP_BATTLESUIT, client->ps.stats ) ) { - Com_sprintf( buffer, MAX_QPATH, "%s/%s", BG_FindModelNameForClass( PCL_H_BSUIT ), - BG_FindSkinNameForClass( PCL_H_BSUIT ) ); + Com_sprintf( buffer, MAX_QPATH, "%s/%s", BG_FindModelNameForClass( PCL_HUMAN_BSUIT ), + BG_FindSkinNameForClass( PCL_HUMAN_BSUIT ) ); } else if( client->pers.classSelection == PCL_NONE ) { @@ -1007,8 +1027,8 @@ void ClientUserinfoChanged( int clientNum ) //model details to that of the spawning class or the info change will not be //registered and an axis appears instead of the player model. There is zero chance //the player can spawn with the battlesuit, hence this choice. - Com_sprintf( buffer, MAX_QPATH, "%s/%s", BG_FindModelNameForClass( PCL_H_BSUIT ), - BG_FindSkinNameForClass( PCL_H_BSUIT ) ); + Com_sprintf( buffer, MAX_QPATH, "%s/%s", BG_FindModelNameForClass( PCL_HUMAN_BSUIT ), + BG_FindSkinNameForClass( PCL_HUMAN_BSUIT ) ); } else { @@ -1366,7 +1386,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles client->pers.maxHealth = client->ps.stats[ STAT_MAX_HEALTH ] = 100; // clear entity values - if( ent->client->pers.classSelection == PCL_H_BASE ) + if( ent->client->pers.classSelection == PCL_HUMAN ) { BG_AddWeaponToInventory( WP_BLASTER, client->ps.stats ); weapon = client->pers.humanItemSelection; diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index 7d6e6a92..0e67824f 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -280,9 +280,9 @@ void Cmd_Give_f( gentity_t *ent ) int credits = atoi( name + 6 ); if( !credits ) - G_AddCreditToClient( ent->client, 1 ); + G_AddCreditToClient( ent->client, 1, qtrue ); else - G_AddCreditToClient( ent->client, credits ); + G_AddCreditToClient( ent->client, credits, qtrue ); if( !give_all ) return; @@ -1109,17 +1109,17 @@ void Cmd_Class_f( gentity_t *ent ) clientNum = ent->client - level.clients; trap_Argv( 1, s, sizeof( s ) ); - if( BG_FindStagesForClass( PCL_A_B_LEV1, g_alienStage.integer ) ) + if( BG_FindStagesForClass( PCL_ALIEN_BUILDER0_UPG, g_alienStage.integer ) ) { - allowedClasses[ 0 ] = PCL_A_B_BASE; - allowedClasses[ 1 ] = PCL_A_B_LEV1; - allowedClasses[ 2 ] = PCL_A_O_BASE; + allowedClasses[ 0 ] = PCL_ALIEN_BUILDER0; + allowedClasses[ 1 ] = PCL_ALIEN_BUILDER0_UPG; + allowedClasses[ 2 ] = PCL_ALIEN_LEVEL0; numClasses = 3; } else { - allowedClasses[ 0 ] = PCL_A_B_BASE; - allowedClasses[ 1 ] = PCL_A_O_BASE; + allowedClasses[ 0 ] = PCL_ALIEN_BUILDER0; + allowedClasses[ 1 ] = PCL_ALIEN_LEVEL0; numClasses = 2; } @@ -1200,7 +1200,7 @@ void Cmd_Class_f( gentity_t *ent ) if( numLevels >= 0 && BG_FindStagesForClass( ent->client->pers.classSelection, g_alienStage.integer ) ) { //remove credit - G_AddCreditToClient( ent->client, -(short)numLevels ); + G_AddCreditToClient( ent->client, -(short)numLevels, qtrue ); ClientUserinfoChanged( clientNum ); VectorCopy( infestOrigin, ent->s.pos.trBase ); @@ -1260,7 +1260,7 @@ void Cmd_Class_f( gentity_t *ent ) } ent->client->pers.classSelection = - ent->client->ps.stats[ STAT_PCLASS ] = PCL_H_BASE; + ent->client->ps.stats[ STAT_PCLASS ] = PCL_HUMAN; //set the item to spawn with if( !Q_stricmp( s, BG_FindNameForWeapon( WP_MACHINEGUN ) ) ) @@ -1569,7 +1569,7 @@ void Cmd_Buy_f( gentity_t *ent ) ent->client->ps.stats[ STAT_MISC ] = 0; //subtract from funds - G_AddCreditToClient( ent->client, -(short)BG_FindPriceForWeapon( weapon ) ); + G_AddCreditToClient( ent->client, -(short)BG_FindPriceForWeapon( weapon ), qfalse ); } else if( upgrade != UP_NONE ) { @@ -1654,7 +1654,7 @@ void Cmd_Buy_f( gentity_t *ent ) } //subtract from funds - G_AddCreditToClient( ent->client, -(short)BG_FindPriceForUpgrade( upgrade ) ); + G_AddCreditToClient( ent->client, -(short)BG_FindPriceForUpgrade( upgrade ), qfalse ); } else { @@ -1730,7 +1730,7 @@ void Cmd_Sell_f( gentity_t *ent ) BG_RemoveWeaponFromInventory( weapon, ent->client->ps.stats ); //add to funds - G_AddCreditToClient( ent->client, (short)BG_FindPriceForWeapon( weapon ) ); + G_AddCreditToClient( ent->client, (short)BG_FindPriceForWeapon( weapon ), qfalse ); } //if we have this weapon selected, force a new selection @@ -1765,7 +1765,7 @@ void Cmd_Sell_f( gentity_t *ent ) } //add to funds - G_AddCreditToClient( ent->client, (short)BG_FindPriceForUpgrade( upgrade ) ); + G_AddCreditToClient( ent->client, (short)BG_FindPriceForUpgrade( upgrade ), qfalse ); } //if we have this upgrade selected, force a new selection @@ -1781,7 +1781,7 @@ void Cmd_Sell_f( gentity_t *ent ) BG_RemoveWeaponFromInventory( i, ent->client->ps.stats ); //add to funds - G_AddCreditToClient( ent->client, (short)BG_FindPriceForWeapon( i ) ); + G_AddCreditToClient( ent->client, (short)BG_FindPriceForWeapon( i ), qfalse ); } //if we have this weapon selected, force a new selection @@ -1819,7 +1819,7 @@ void Cmd_Sell_f( gentity_t *ent ) } //add to funds - G_AddCreditToClient( ent->client, (short)BG_FindPriceForUpgrade( i ) ); + G_AddCreditToClient( ent->client, (short)BG_FindPriceForUpgrade( i ), qfalse ); } //if we have this upgrade selected, force a new selection @@ -2210,7 +2210,7 @@ void Cmd_PTRCRestore_f( gentity_t *ent ) // set the correct credit ent->client->ps.persistant[ PERS_CREDIT ] = 0; - G_AddCreditToClient( ent->client, connection->clientCredit ); + G_AddCreditToClient( ent->client, connection->clientCredit, qtrue ); } } } diff --git a/src/game/g_combat.c b/src/game/g_combat.c index 96708979..d89adadc 100644 --- a/src/game/g_combat.c +++ b/src/game/g_combat.c @@ -115,16 +115,16 @@ char *modNames[ ] = "MOD_TRIGGER_HURT", "MOD_ABUILDER_CLAW", - "MOD_SOLDIER_BITE", - "MOD_HYDRA_CLAW", - "MOD_HYDRA_PCLOUD", - "MOD_DRAGOON_CLAW", - "MOD_DRAGOON_POUNCE", - "MOD_DRAGOON_BOUNCEBALL", - "MOD_CHIMERA_CLAW", - "MOD_CHIMERA_ZAP", - "MOD_BMOFO_CLAW", - "MOD_BMOFO_CHARGE", + "MOD_LEVEL0_BITE", + "MOD_LEVEL1_CLAW", + "MOD_LEVEL1_PCLOUD", + "MOD_LEVEL3_CLAW", + "MOD_LEVEL3_POUNCE", + "MOD_LEVEL3_BOUNCEBALL", + "MOD_LEVEL2_CLAW", + "MOD_LEVEL2_ZAP", + "MOD_LEVEL4_CLAW", + "MOD_LEVEL4_CHARGE", "MOD_SLOWBLOB", "MOD_POISON", @@ -223,9 +223,9 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int //punish team kills and suicides if( attacker->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) - G_AddCreditToClient( attacker->client, -1 ); + G_AddCreditToClient( attacker->client, -1, qtrue ); else if( attacker->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) - G_AddCreditToClient( attacker->client, -ASPAWN_VALUE ); + G_AddCreditToClient( attacker->client, -ASPAWN_VALUE, qtrue ); } else { @@ -269,7 +269,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int //add credit G_AddCreditToClient( player->client, - (int)( classValue * ( (float)self->credits[ i ] / totalDamage ) ) ); + (int)( classValue * ( (float)self->credits[ i ] / totalDamage ) ), qtrue ); } } else if( self->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) @@ -302,7 +302,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int if( frags > 0 ) { //add kills - G_AddCreditToClient( player->client, frags ); + G_AddCreditToClient( player->client, frags, qtrue ); //can't revist this account later self->credits[ i ] = 0; @@ -343,7 +343,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int player = g_entities + topClient; //add kills - G_AddCreditToClient( player->client, 1 ); + G_AddCreditToClient( player->client, 1, qtrue ); //can't revist this account again self->credits[ topClient ] = 0; @@ -1065,7 +1065,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, { if( !( targ->client->ps.stats[ STAT_STATE ] & SS_POISONED ) && !BG_InventoryContainsUpgrade( UP_BATTLESUIT, targ->client->ps.stats ) && - mod != MOD_CHIMERA_ZAP ) + mod != MOD_LEVEL2_ZAP ) { targ->client->ps.stats[ STAT_STATE ] |= SS_POISONED; targ->client->lastPoisonTime = level.time; diff --git a/src/game/g_local.h b/src/game/g_local.h index 2885da8b..b974cf7d 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -732,6 +732,7 @@ gentity_t *fire_paraLockBlob( gentity_t *self, vec3_t start, vec3_t dir ); gentity_t *fire_slowBlob( gentity_t *self, vec3_t start, vec3_t dir ); gentity_t *fire_bounceBall( gentity_t *self, vec3_t start, vec3_t dir ); gentity_t *fire_hive( gentity_t *self, vec3_t start, vec3_t dir ); +gentity_t *launch_grenade( gentity_t *self, vec3_t start, vec3_t dir ); // @@ -767,7 +768,7 @@ void ChargeAttack( gentity_t *ent, gentity_t *victim ); // // g_client.c // -void G_AddCreditToClient( gclient_t *client, short credit ); +void G_AddCreditToClient( gclient_t *client, short credit, qboolean cap ); team_t TeamCount( int ignoreClientNum, int team ); void SetClientViewAngle( gentity_t *ent, vec3_t angle ); gentity_t *SelectTremulousSpawnPoint( pTeam_t team, vec3_t origin, vec3_t angles ); diff --git a/src/game/g_missile.c b/src/game/g_missile.c index 9efbd3e1..a1070cad 100644 --- a/src/game/g_missile.c +++ b/src/game/g_missile.c @@ -120,7 +120,18 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) return; } - if( !strcmp( ent->classname, "lockblob" ) ) + if( !strcmp( ent->classname, "grenade" ) ) + { + //grenade doesn't explode on impact + G_BounceMissile( ent, trace ); + + //only play a sound if requested + if( !( ent->s.eFlags & EF_NO_BOUNCE_SOUND ) ) + G_AddEvent( ent, EV_GRENADE_BOUNCE, 0 ); + + return; + } + else if( !strcmp( ent->classname, "lockblob" ) ) { if( other->client && other->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) { @@ -455,6 +466,50 @@ gentity_t *fire_luciferCannon( gentity_t *self, vec3_t start, vec3_t dir, int da return bolt; } +/* +================= +launch_grenade + +================= +*/ +gentity_t *launch_grenade( gentity_t *self, vec3_t start, vec3_t dir ) +{ + gentity_t *bolt; + + VectorNormalize( dir ); + + bolt = G_Spawn( ); + bolt->classname = "grenade"; + bolt->nextthink = level.time + 5000; + bolt->think = G_ExplodeMissile; + bolt->s.eType = ET_MISSILE; + bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; + bolt->s.weapon = WP_GRENADE; + bolt->s.eFlags = EF_BOUNCE_HALF; + bolt->s.generic1 = self->s.generic1; //weaponMode + bolt->r.ownerNum = self->s.number; + bolt->parent = self; + bolt->damage = GRENADE_DAMAGE; + bolt->splashDamage = GRENADE_DAMAGE; + bolt->splashRadius = GRENADE_RANGE; + bolt->methodOfDeath = MOD_GRENADE; + bolt->splashMethodOfDeath = MOD_GRENADE; + bolt->clipmask = MASK_SHOT; + bolt->target_ent = NULL; + bolt->r.mins[ 0 ] = bolt->r.mins[ 1 ] = bolt->r.mins[ 2 ] = -3.0f; + bolt->r.maxs[ 0 ] = bolt->r.maxs[ 1 ] = bolt->r.maxs[ 2 ] = 3.0f; + bolt->s.time = level.time; + + bolt->s.pos.trType = TR_GRAVITY; + bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame + VectorCopy( start, bolt->s.pos.trBase ); + VectorScale( dir, GRENADE_SPEED, bolt->s.pos.trDelta ); + SnapVector( bolt->s.pos.trDelta ); // save net bandwidth + + VectorCopy( start, bolt->r.currentOrigin ); + + return bolt; +} //============================================================================= /* @@ -719,22 +774,22 @@ gentity_t *fire_bounceBall( gentity_t *self, vec3_t start, vec3_t dir ) bolt->think = G_ExplodeMissile; bolt->s.eType = ET_MISSILE; bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; - bolt->s.weapon = WP_DRAGOON_UPG; + bolt->s.weapon = WP_ALEVEL3_UPG; bolt->s.generic1 = self->s.generic1; //weaponMode bolt->r.ownerNum = self->s.number; bolt->parent = self; - bolt->damage = DRAGOON_BOUNCEBALL_DMG; + bolt->damage = LEVEL3_BOUNCEBALL_DMG; bolt->splashDamage = 0; bolt->splashRadius = 0; - bolt->methodOfDeath = MOD_DRAGOON_BOUNCEBALL; - bolt->splashMethodOfDeath = MOD_DRAGOON_BOUNCEBALL; + bolt->methodOfDeath = MOD_LEVEL3_BOUNCEBALL; + bolt->splashMethodOfDeath = MOD_LEVEL3_BOUNCEBALL; bolt->clipmask = MASK_SHOT; bolt->target_ent = NULL; bolt->s.pos.trType = TR_LINEAR; bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame VectorCopy( start, bolt->s.pos.trBase ); - VectorScale( dir, DRAGOON_BOUNCEBALL_SPEED, bolt->s.pos.trDelta ); + VectorScale( dir, LEVEL3_BOUNCEBALL_SPEED, bolt->s.pos.trDelta ); SnapVector( bolt->s.pos.trDelta ); // save net bandwidth VectorCopy( start, bolt->r.currentOrigin ); /*bolt->s.eFlags |= EF_BOUNCE;*/ diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c index 26454f59..ddb5e0a7 100644 --- a/src/game/g_weapon.c +++ b/src/game/g_weapon.c @@ -356,6 +356,21 @@ void flamerFire( gentity_t *ent ) /* ====================================================================== +GRENADE + +====================================================================== +*/ + +void throwGrenade( gentity_t *ent ) +{ + gentity_t *m; + + m = launch_grenade( ent, muzzle, forward ); +} + +/* +====================================================================== + LAS GUN ====================================================================== @@ -665,7 +680,7 @@ void slowBlobFire( gentity_t *ent ) /* ====================================================================== -SOLDIER +LEVEL0 ====================================================================== */ @@ -684,15 +699,15 @@ qboolean CheckVenomAttack( gentity_t *ent ) int damage; vec3_t mins, maxs; - VectorSet( mins, -SOLDIER_BITE_WIDTH, -SOLDIER_BITE_WIDTH, -SOLDIER_BITE_WIDTH ); - VectorSet( maxs, SOLDIER_BITE_WIDTH, SOLDIER_BITE_WIDTH, SOLDIER_BITE_WIDTH ); + VectorSet( mins, -LEVEL0_BITE_WIDTH, -LEVEL0_BITE_WIDTH, -LEVEL0_BITE_WIDTH ); + VectorSet( maxs, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH ); // set aiming directions AngleVectors( ent->client->ps.viewangles, forward, right, up ); CalcMuzzlePoint( ent, forward, right, up, muzzle ); - VectorMA( muzzle, SOLDIER_BITE_RANGE, forward, end ); + VectorMA( muzzle, LEVEL0_BITE_RANGE, forward, end ); trap_Trace( &tr, muzzle, mins, maxs, end, ent->s.number, MASK_SHOT ); @@ -720,7 +735,7 @@ qboolean CheckVenomAttack( gentity_t *ent ) tent->s.generic1 = ent->s.generic1; //weaponMode } - G_Damage( traceEnt, ent, ent, forward, tr.endpos, SOLDIER_BITE_DMG, DAMAGE_NO_KNOCKBACK, MOD_SOLDIER_BITE ); + G_Damage( traceEnt, ent, ent, forward, tr.endpos, LEVEL0_BITE_DMG, DAMAGE_NO_KNOCKBACK, MOD_LEVEL0_BITE ); return qtrue; } @@ -728,7 +743,7 @@ qboolean CheckVenomAttack( gentity_t *ent ) /* ====================================================================== -HYDRA +LEVEL1 ====================================================================== */ @@ -749,7 +764,7 @@ void CheckGrabAttack( gentity_t *ent ) CalcMuzzlePoint( ent, forward, right, up, muzzle ); - VectorMA( muzzle, HYDRA_GRAB_RANGE, forward, end ); + VectorMA( muzzle, LEVEL1_GRAB_RANGE, forward, end ); trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); if( tr.surfaceFlags & SURF_NOIMPACT ) @@ -775,10 +790,14 @@ void CheckGrabAttack( gentity_t *ent ) traceEnt->client->ps.stats[ STAT_VIEWLOCK ] = DirToByte( dir ); } + if( !( traceEnt->client->ps.stats[ STAT_STATE ] & SS_GRABBED ) ) + { + //event for client side grab effect + G_AddPredictableEvent( ent, EV_LEV1_GRAB, 0 ); + } + traceEnt->client->ps.stats[ STAT_STATE ] |= SS_GRABBED; traceEnt->client->lastGrabTime = level.time; - - //FIXME: event for some client side grab effect? } /* @@ -789,7 +808,7 @@ poisonCloud void poisonCloud( gentity_t *ent ) { int entityList[ MAX_GENTITIES ]; - vec3_t range = { HYDRA_PCLOUD_RANGE, HYDRA_PCLOUD_RANGE, HYDRA_PCLOUD_RANGE }; + vec3_t range = { LEVEL1_PCLOUD_RANGE, LEVEL1_PCLOUD_RANGE, LEVEL1_PCLOUD_RANGE }; vec3_t mins, maxs, dir; int i, num; gentity_t *humanPlayer; @@ -828,10 +847,84 @@ void poisonCloud( gentity_t *ent ) } } + /* ====================================================================== -DRAGOON +LEVEL2 + +====================================================================== +*/ + +/* +=============== +areaZapFire +=============== +*/ +void areaZapFire( gentity_t *ent ) +{ + int entityList[ MAX_GENTITIES ]; + int targetList[ MAX_GENTITIES ]; + vec3_t range = { LEVEL2_AREAZAP_RANGE, LEVEL2_AREAZAP_RANGE, LEVEL2_AREAZAP_RANGE }; + vec3_t mins, maxs, dir; + int i, num, numTargets = 0; + gentity_t *enemy; + gentity_t *tent; + trace_t tr; + int damage; + + VectorAdd( ent->client->ps.origin, range, maxs ); + VectorSubtract( ent->client->ps.origin, range, mins ); + + num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); + + for( i = 0; i < num; i++ ) + { + enemy = &g_entities[ entityList[ i ] ]; + + if( ( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) || + ( enemy->s.eType == ET_BUILDABLE && BG_FindTeamForBuildable( enemy->s.modelindex ) == BIT_HUMANS ) ) + { + trap_Trace( &tr, muzzle, NULL, NULL, enemy->s.origin, ent->s.number, MASK_SHOT ); + + //can't see target from here + if( tr.entityNum == ENTITYNUM_WORLD ) + continue; + + targetList[ numTargets++ ] = entityList[ i ]; + } + } + + damage = (int)( (float)LEVEL2_AREAZAP_DMG / (float)numTargets ); + for( i = 0; i < numTargets; i++ ) + { + enemy = &g_entities[ targetList[ i ] ]; + + VectorSubtract( enemy->s.origin, muzzle, dir ); + VectorNormalize( dir ); + + //do some damage + G_Damage( enemy, ent, ent, dir, tr.endpos, + damage, DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE, MOD_LEVEL2_ZAP ); + + // snap the endpos to integers to save net bandwidth, but nudged towards the line + SnapVectorTowards( tr.endpos, muzzle ); + + // send arc effect + tent = G_TempEntity( enemy->s.pos.trBase, EV_ALIENZAP ); + + VectorCopy( ent->client->ps.origin, tent->s.origin2 ); + + tent->s.generic1 = ent->s.number; //src + tent->s.clientNum = enemy->s.number; //dest + } +} + + +/* +====================================================================== + +LEVEL3 ====================================================================== */ @@ -850,8 +943,8 @@ qboolean CheckPounceAttack( gentity_t *ent ) int damage; vec3_t mins, maxs; - VectorSet( mins, -DRAGOON_POUNCE_WIDTH, -DRAGOON_POUNCE_WIDTH, -DRAGOON_POUNCE_WIDTH ); - VectorSet( maxs, DRAGOON_POUNCE_WIDTH, DRAGOON_POUNCE_WIDTH, DRAGOON_POUNCE_WIDTH ); + VectorSet( mins, -LEVEL3_POUNCE_WIDTH, -LEVEL3_POUNCE_WIDTH, -LEVEL3_POUNCE_WIDTH ); + VectorSet( maxs, LEVEL3_POUNCE_WIDTH, LEVEL3_POUNCE_WIDTH, LEVEL3_POUNCE_WIDTH ); if( !ent->client->allowedToPounce ) return qfalse; @@ -867,7 +960,7 @@ qboolean CheckPounceAttack( gentity_t *ent ) CalcMuzzlePoint( ent, forward, right, up, muzzle ); - VectorMA( muzzle, DRAGOON_POUNCE_RANGE, forward, end ); + VectorMA( muzzle, LEVEL3_POUNCE_RANGE, forward, end ); trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); @@ -893,9 +986,9 @@ qboolean CheckPounceAttack( gentity_t *ent ) if( !traceEnt->takedamage ) return qfalse; - damage = (int)( ( (float)ent->client->pouncePayload / (float)DRAGOON_POUNCE_SPEED ) * DRAGOON_POUNCE_DMG ); + damage = (int)( ( (float)ent->client->pouncePayload / (float)LEVEL3_POUNCE_SPEED ) * LEVEL3_POUNCE_DMG ); - G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, MOD_DRAGOON_POUNCE ); + G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, MOD_LEVEL3_POUNCE ); ent->client->allowedToPounce = qfalse; @@ -911,84 +1004,11 @@ void bounceBallFire( gentity_t *ent ) // VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta ); // "real" physics } -/* -====================================================================== - -CHIMERA - -====================================================================== -*/ - -/* -=============== -areaZapFire -=============== -*/ -void areaZapFire( gentity_t *ent ) -{ - int entityList[ MAX_GENTITIES ]; - int targetList[ MAX_GENTITIES ]; - vec3_t range = { CHIMERA_AREAZAP_RANGE, CHIMERA_AREAZAP_RANGE, CHIMERA_AREAZAP_RANGE }; - vec3_t mins, maxs, dir; - int i, num, numTargets = 0; - gentity_t *enemy; - gentity_t *tent; - trace_t tr; - int damage; - - VectorAdd( ent->client->ps.origin, range, maxs ); - VectorSubtract( ent->client->ps.origin, range, mins ); - - num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); - - for( i = 0; i < num; i++ ) - { - enemy = &g_entities[ entityList[ i ] ]; - - if( ( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) || - ( enemy->s.eType == ET_BUILDABLE && BG_FindTeamForBuildable( enemy->s.modelindex ) == BIT_HUMANS ) ) - { - trap_Trace( &tr, muzzle, NULL, NULL, enemy->s.origin, ent->s.number, MASK_SHOT ); - - //can't see target from here - if( tr.entityNum == ENTITYNUM_WORLD ) - continue; - - targetList[ numTargets++ ] = entityList[ i ]; - } - } - - damage = (int)( (float)CHIMERA_AREAZAP_DMG / (float)numTargets ); - for( i = 0; i < numTargets; i++ ) - { - enemy = &g_entities[ targetList[ i ] ]; - - VectorSubtract( enemy->s.origin, muzzle, dir ); - VectorNormalize( dir ); - - //do some damage - G_Damage( enemy, ent, ent, dir, tr.endpos, - damage, DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE, MOD_CHIMERA_ZAP ); - - // snap the endpos to integers to save net bandwidth, but nudged towards the line - SnapVectorTowards( tr.endpos, muzzle ); - - // send arc effect - tent = G_TempEntity( enemy->s.pos.trBase, EV_ALIENZAP ); - - VectorCopy( ent->client->ps.origin, tent->s.origin2 ); - - tent->s.generic1 = ent->s.number; //src - tent->s.clientNum = enemy->s.number; //dest - } -} - - /* ====================================================================== -BIG MOFO +LEVEL4 ====================================================================== */ @@ -1007,7 +1027,7 @@ void ChargeAttack( gentity_t *ent, gentity_t *victim ) if( level.time < victim->chargeRepeat ) return; - victim->chargeRepeat = level.time + BMOFO_CHARGE_REPEAT; + victim->chargeRepeat = level.time + LEVEL4_CHARGE_REPEAT; VectorSubtract( victim->s.origin, ent->s.origin, forward ); VectorNormalize( forward ); @@ -1025,9 +1045,9 @@ void ChargeAttack( gentity_t *ent, gentity_t *victim ) if( !victim->takedamage ) return; - damage = (int)( ( (float)ent->client->ps.stats[ STAT_MISC ] / (float)BMOFO_CHARGE_TIME ) * BMOFO_CHARGE_DMG ); + damage = (int)( ( (float)ent->client->ps.stats[ STAT_MISC ] / (float)LEVEL4_CHARGE_TIME ) * LEVEL4_CHARGE_DMG ); - G_Damage( victim, ent, ent, forward, victim->s.origin, damage, 0, MOD_BMOFO_CHARGE ); + G_Damage( victim, ent, ent, forward, victim->s.origin, damage, 0, MOD_LEVEL4_CHARGE ); } //====================================================================== @@ -1071,7 +1091,7 @@ void FireWeapon3( gentity_t *ent ) // fire the specific weapon switch( ent->s.weapon ) { - case WP_DRAGOON_UPG: + case WP_ALEVEL3_UPG: bounceBallFire( ent ); break; @@ -1106,10 +1126,10 @@ void FireWeapon2( gentity_t *ent ) // fire the specific weapon switch( ent->s.weapon ) { - case WP_HYDRA_UPG: + case WP_ALEVEL1_UPG: poisonCloud( ent ); break; - case WP_CHIMERA_UPG: + case WP_ALEVEL2_UPG: areaZapFire( ent ); break; @@ -1150,22 +1170,22 @@ void FireWeapon( gentity_t *ent ) // fire the specific weapon switch( ent->s.weapon ) { - case WP_HYDRA: - case WP_HYDRA_UPG: - meleeAttack( ent, HYDRA_CLAW_RANGE, HYDRA_CLAW_WIDTH, HYDRA_CLAW_DMG, MOD_HYDRA_CLAW ); + case WP_ALEVEL1: + case WP_ALEVEL1_UPG: + meleeAttack( ent, LEVEL1_CLAW_RANGE, LEVEL1_CLAW_WIDTH, LEVEL1_CLAW_DMG, MOD_LEVEL1_CLAW ); break; - case WP_DRAGOON: - case WP_DRAGOON_UPG: - meleeAttack( ent, DRAGOON_CLAW_RANGE, DRAGOON_CLAW_WIDTH, DRAGOON_CLAW_DMG, MOD_DRAGOON_CLAW ); + case WP_ALEVEL3: + case WP_ALEVEL3_UPG: + meleeAttack( ent, LEVEL3_CLAW_RANGE, LEVEL3_CLAW_WIDTH, LEVEL3_CLAW_DMG, MOD_LEVEL3_CLAW ); break; - case WP_CHIMERA: - meleeAttack( ent, CHIMERA_CLAW_RANGE, CHIMERA_CLAW_WIDTH, CHIMERA_CLAW_DMG, MOD_CHIMERA_CLAW ); + case WP_ALEVEL2: + meleeAttack( ent, LEVEL2_CLAW_RANGE, LEVEL2_CLAW_WIDTH, LEVEL2_CLAW_DMG, MOD_LEVEL2_CLAW ); break; - case WP_CHIMERA_UPG: - meleeAttack( ent, CHIMERA_CLAW_RANGE, CHIMERA_CLAW_WIDTH, CHIMERA_CLAW_DMG, MOD_CHIMERA_CLAW ); + case WP_ALEVEL2_UPG: + meleeAttack( ent, LEVEL2_CLAW_RANGE, LEVEL2_CLAW_WIDTH, LEVEL2_CLAW_DMG, MOD_LEVEL2_CLAW ); break; - case WP_BIGMOFO: - meleeAttack( ent, BMOFO_CLAW_RANGE, BMOFO_CLAW_WIDTH, BMOFO_CLAW_DMG, MOD_BMOFO_CLAW ); + case WP_ALEVEL4: + meleeAttack( ent, LEVEL4_CLAW_RANGE, LEVEL4_CLAW_WIDTH, LEVEL4_CLAW_DMG, MOD_LEVEL4_CLAW ); break; case WP_BLASTER: @@ -1198,6 +1218,9 @@ void FireWeapon( gentity_t *ent ) case WP_PAIN_SAW: painSawFire( ent ); break; + case WP_GRENADE: + throwGrenade( ent ); + break; case WP_LOCKBLOB_LAUNCHER: lockBlobLauncherFire( ent ); diff --git a/src/game/q_shared.h b/src/game/q_shared.h index 64ef9f30..69496267 100644 --- a/src/game/q_shared.h +++ b/src/game/q_shared.h @@ -634,6 +634,7 @@ typedef struct { #define VectorNegate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2]) #define VectorSet(v, x, y, z) ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z)) #define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) +#define Vector4Add(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2],(c)[3]=(a)[3]+(b)[3]) #define SnapVector(v) {v[0]=((int)(v[0]));v[1]=((int)(v[1]));v[2]=((int)(v[2]));} // just in case you do't want to use the macros diff --git a/src/game/tremulous.h b/src/game/tremulous.h index 7e723ecc..53e07a0b 100644 --- a/src/game/tremulous.h +++ b/src/game/tremulous.h @@ -38,61 +38,61 @@ #define ABUILDER_BLOB_SPEED_MOD 0.5f #define ABUILDER_BLOB_TIME 5000 -#define SOLDIER_BITE_DMG ADM(60) -#define SOLDIER_BITE_RANGE 64.0f -#define SOLDIER_BITE_WIDTH 6.0f -#define SOLDIER_BITE_REPEAT 500 - -#define HYDRA_CLAW_DMG ADM(40) -#define HYDRA_CLAW_RANGE 96.0f -#define HYDRA_CLAW_WIDTH 10.0f -#define HYDRA_CLAW_REPEAT 600 -#define HYDRA_CLAW_U_REPEAT 500 -#define HYDRA_GRAB_RANGE 64.0f -#define HYDRA_GRAB_TIME 1000 -#define HYDRA_PCLOUD_DMG ADM(5) -#define HYDRA_PCLOUD_RANGE 200.0f -#define HYDRA_PCLOUD_REPEAT 2000 -#define HYDRA_PCLOUD_TIME 10000 - -#define CHIMERA_CLAW_DMG ADM(50) -#define CHIMERA_CLAW_RANGE 96.0f -#define CHIMERA_CLAW_WIDTH 12.0f -#define CHIMERA_CLAW_REPEAT 500 -#define CHIMERA_CLAW_U_REPEAT 400 -#define CHIMERA_AREAZAP_DMG ADM(100) -#define CHIMERA_AREAZAP_RANGE 200.0f -#define CHIMERA_AREAZAP_REPEAT 3000 -#define CHIMERA_WALLJUMP_MAXSPEED 1000.0f - -#define DRAGOON_CLAW_DMG ADM(100) -#define DRAGOON_CLAW_RANGE 96.0f -#define DRAGOON_CLAW_WIDTH 16.0f -#define DRAGOON_CLAW_REPEAT 700 -#define DRAGOON_CLAW_U_REPEAT 600 -#define DRAGOON_POUNCE_DMG ADM(200) -#define DRAGOON_POUNCE_RANGE 96.0f -#define DRAGOON_POUNCE_WIDTH 16.0f -#define DRAGOON_POUNCE_SPEED 700 -#define DRAGOON_POUNCE_UPG_SPEED 800 -#define DRAGOON_POUNCE_SPEED_MOD 0.75f -#define DRAGOON_POUNCE_TIME 700 -#define DRAGOON_BOUNCEBALL_DMG ADM(150) -#define DRAGOON_BOUNCEBALL_REPEAT 1000 -#define DRAGOON_BOUNCEBALL_SPEED 1000.0f - -#define BMOFO_CLAW_DMG ADM(150) -#define BMOFO_CLAW_RANGE 128.0f -#define BMOFO_CLAW_WIDTH 20.0f -#define BMOFO_CLAW_REPEAT 750 -#define BMOFO_REGEN_RANGE 200.0f -#define BMOFO_REGEN_MOD 2.0f -#define BMOFO_CHARGE_SPEED 2.0f -#define BMOFO_CHARGE_TIME 3000 -#define BMOFO_CHARGE_CHARGE_TIME 1000 -#define BMOFO_CHARGE_CHARGE_RATIO (BMOFO_CHARGE_TIME/BMOFO_CHARGE_CHARGE_TIME) -#define BMOFO_CHARGE_REPEAT 500 -#define BMOFO_CHARGE_DMG ADM(200) +#define LEVEL0_BITE_DMG ADM(60) +#define LEVEL0_BITE_RANGE 64.0f +#define LEVEL0_BITE_WIDTH 6.0f +#define LEVEL0_BITE_REPEAT 500 + +#define LEVEL1_CLAW_DMG ADM(40) +#define LEVEL1_CLAW_RANGE 96.0f +#define LEVEL1_CLAW_WIDTH 10.0f +#define LEVEL1_CLAW_REPEAT 600 +#define LEVEL1_CLAW_U_REPEAT 500 +#define LEVEL1_GRAB_RANGE 64.0f +#define LEVEL1_GRAB_TIME 1000 +#define LEVEL1_PCLOUD_DMG ADM(5) +#define LEVEL1_PCLOUD_RANGE 200.0f +#define LEVEL1_PCLOUD_REPEAT 2000 +#define LEVEL1_PCLOUD_TIME 10000 + +#define LEVEL2_CLAW_DMG ADM(50) +#define LEVEL2_CLAW_RANGE 96.0f +#define LEVEL2_CLAW_WIDTH 12.0f +#define LEVEL2_CLAW_REPEAT 500 +#define LEVEL2_CLAW_U_REPEAT 400 +#define LEVEL2_AREAZAP_DMG ADM(100) +#define LEVEL2_AREAZAP_RANGE 200.0f +#define LEVEL2_AREAZAP_REPEAT 3000 +#define LEVEL2_WALLJUMP_MAXSPEED 1000.0f + +#define LEVEL3_CLAW_DMG ADM(100) +#define LEVEL3_CLAW_RANGE 96.0f +#define LEVEL3_CLAW_WIDTH 16.0f +#define LEVEL3_CLAW_REPEAT 700 +#define LEVEL3_CLAW_U_REPEAT 600 +#define LEVEL3_POUNCE_DMG ADM(200) +#define LEVEL3_POUNCE_RANGE 96.0f +#define LEVEL3_POUNCE_WIDTH 16.0f +#define LEVEL3_POUNCE_SPEED 700 +#define LEVEL3_POUNCE_UPG_SPEED 800 +#define LEVEL3_POUNCE_SPEED_MOD 0.75f +#define LEVEL3_POUNCE_TIME 700 +#define LEVEL3_BOUNCEBALL_DMG ADM(150) +#define LEVEL3_BOUNCEBALL_REPEAT 1000 +#define LEVEL3_BOUNCEBALL_SPEED 1000.0f + +#define LEVEL4_CLAW_DMG ADM(150) +#define LEVEL4_CLAW_RANGE 128.0f +#define LEVEL4_CLAW_WIDTH 20.0f +#define LEVEL4_CLAW_REPEAT 750 +#define LEVEL4_REGEN_RANGE 200.0f +#define LEVEL4_REGEN_MOD 2.0f +#define LEVEL4_CHARGE_SPEED 2.0f +#define LEVEL4_CHARGE_TIME 3000 +#define LEVEL4_CHARGE_CHARGE_TIME 1000 +#define LEVEL4_CHARGE_CHARGE_RATIO (LEVEL4_CHARGE_TIME/LEVEL4_CHARGE_CHARGE_TIME) +#define LEVEL4_CHARGE_REPEAT 500 +#define LEVEL4_CHARGE_DMG ADM(200) @@ -124,53 +124,53 @@ #define ABUILDER_UPG_REGEN 3 #define ABUILDER_UPG_COST 0 -#define SOLDIER_SPEED 1.3f -#define SOLDIER_VALUE AVM(175) -#define SOLDIER_HEALTH AHM(25) -#define SOLDIER_REGEN 1 -#define SOLDIER_COST 0 - -#define HYDRA_SPEED 1.25f -#define HYDRA_VALUE AVM(225) -#define HYDRA_HEALTH AHM(75) -#define HYDRA_REGEN 2 -#define HYDRA_COST 1 - -#define HYDRA_UPG_SPEED 1.25f -#define HYDRA_UPG_VALUE AVM(275) -#define HYDRA_UPG_HEALTH AHM(100) -#define HYDRA_UPG_REGEN 2 -#define HYDRA_UPG_COST 1 - -#define CHIMERA_SPEED 1.2f -#define CHIMERA_VALUE AVM(350) -#define CHIMERA_HEALTH AHM(150) -#define CHIMERA_REGEN 3 -#define CHIMERA_COST 1 - -#define CHIMERA_UPG_SPEED 1.2f -#define CHIMERA_UPG_VALUE AVM(450) -#define CHIMERA_UPG_HEALTH AHM(175) -#define CHIMERA_UPG_REGEN 4 -#define CHIMERA_UPG_COST 1 - -#define DRAGOON_SPEED 1.1f -#define DRAGOON_VALUE AVM(500) -#define DRAGOON_HEALTH AHM(200) -#define DRAGOON_REGEN 5 -#define DRAGOON_COST 1 - -#define DRAGOON_UPG_SPEED 1.1f -#define DRAGOON_UPG_VALUE AVM(600) -#define DRAGOON_UPG_HEALTH AHM(250) -#define DRAGOON_UPG_REGEN 6 -#define DRAGOON_UPG_COST 1 - -#define BMOFO_SPEED 1.2f -#define BMOFO_VALUE AVM(800) -#define BMOFO_HEALTH AHM(400) -#define BMOFO_REGEN 7 -#define BMOFO_COST 2 +#define LEVEL0_SPEED 1.3f +#define LEVEL0_VALUE AVM(175) +#define LEVEL0_HEALTH AHM(25) +#define LEVEL0_REGEN 1 +#define LEVEL0_COST 0 + +#define LEVEL1_SPEED 1.25f +#define LEVEL1_VALUE AVM(225) +#define LEVEL1_HEALTH AHM(75) +#define LEVEL1_REGEN 2 +#define LEVEL1_COST 1 + +#define LEVEL1_UPG_SPEED 1.25f +#define LEVEL1_UPG_VALUE AVM(275) +#define LEVEL1_UPG_HEALTH AHM(100) +#define LEVEL1_UPG_REGEN 2 +#define LEVEL1_UPG_COST 1 + +#define LEVEL2_SPEED 1.2f +#define LEVEL2_VALUE AVM(350) +#define LEVEL2_HEALTH AHM(150) +#define LEVEL2_REGEN 3 +#define LEVEL2_COST 1 + +#define LEVEL2_UPG_SPEED 1.2f +#define LEVEL2_UPG_VALUE AVM(450) +#define LEVEL2_UPG_HEALTH AHM(175) +#define LEVEL2_UPG_REGEN 4 +#define LEVEL2_UPG_COST 1 + +#define LEVEL3_SPEED 1.1f +#define LEVEL3_VALUE AVM(500) +#define LEVEL3_HEALTH AHM(200) +#define LEVEL3_REGEN 5 +#define LEVEL3_COST 1 + +#define LEVEL3_UPG_SPEED 1.1f +#define LEVEL3_UPG_VALUE AVM(600) +#define LEVEL3_UPG_HEALTH AHM(250) +#define LEVEL3_UPG_REGEN 6 +#define LEVEL3_UPG_COST 1 + +#define LEVEL4_SPEED 1.2f +#define LEVEL4_VALUE AVM(800) +#define LEVEL4_HEALTH AHM(400) +#define LEVEL4_REGEN 7 +#define LEVEL4_COST 2 @@ -329,6 +329,12 @@ #define PAINSAW_DAMAGE HDM(20) #define PAINSAW_RANGE 48.0f +#define GRENADE_PRICE 300 +#define GRENADE_REPEAT 0 +#define GRENADE_DAMAGE HDM(350) +#define GRENADE_RANGE 192.0f +#define GRENADE_SPEED 400.0f + #define SHOTGUN_PRICE 150 #define SHOTGUN_SHELLS 8 #define SHOTGUN_PELLETS 8 //used to sync server and client side @@ -549,4 +555,4 @@ #define FREEKILL_PERIOD 180000 //msec #define FREEKILL_ALIEN 1 -#define FREEKILL_HUMAN SOLDIER_VALUE +#define FREEKILL_HUMAN LEVEL0_VALUE diff --git a/src/ui/ui_main.c b/src/ui/ui_main.c index 4389074c..60480b90 100644 --- a/src/ui/ui_main.c +++ b/src/ui/ui_main.c @@ -3349,16 +3349,16 @@ static void UI_LoadTremAlienClasses( void ) uiInfo.tremAlienClassCount = 2; uiInfo.tremAlienClassList[ 0 ].text = - String_Alloc( BG_FindHumanNameForClassNum( PCL_A_O_BASE ) ); + String_Alloc( BG_FindHumanNameForClassNum( PCL_ALIEN_LEVEL0 ) ); uiInfo.tremAlienClassList[ 0 ].cmd = - String_Alloc( va( "cmd class %s\n", BG_FindNameForClassNum( PCL_A_O_BASE ) ) ); + String_Alloc( va( "cmd class %s\n", BG_FindNameForClassNum( PCL_ALIEN_LEVEL0 ) ) ); uiInfo.tremAlienClassList[ 0 ].infopane = - UI_FindInfoPaneByName( va( "%sclass", BG_FindNameForClassNum( PCL_A_O_BASE ) ) ); + UI_FindInfoPaneByName( va( "%sclass", BG_FindNameForClassNum( PCL_ALIEN_LEVEL0 ) ) ); - if( BG_FindStagesForClass( PCL_A_B_LEV1, UI_GetCurrentAlienStage( ) ) ) - bClass = PCL_A_B_LEV1; + if( BG_FindStagesForClass( PCL_ALIEN_BUILDER0_UPG, UI_GetCurrentAlienStage( ) ) ) + bClass = PCL_ALIEN_BUILDER0_UPG; else - bClass = PCL_A_B_BASE; + bClass = PCL_ALIEN_BUILDER0; uiInfo.tremAlienClassList[ 1 ].text = String_Alloc( BG_FindHumanNameForClassNum( bClass ) ); @@ -6042,6 +6042,8 @@ void _UI_Init( qboolean inGameLoad ) { const char *menuSet; int start; + BG_InitClassOverrides( ); + //uiInfo.inGameLoad = inGameLoad; UI_RegisterCvars(); |