diff --git a/code/botlib/be_ai_move.c b/code/botlib/be_ai_move.c index 43e9a337..e633ebcc 100644 --- a/code/botlib/be_ai_move.c +++ b/code/botlib/be_ai_move.c @@ -3187,7 +3187,7 @@ void BotMoveToGoal(bot_moveresult_t *result, int movestate, bot_goal_t *goal, in else if ((reach.traveltype & TRAVELTYPE_MASK) == TRAVEL_ELEVATOR || (reach.traveltype & TRAVELTYPE_MASK) == TRAVEL_FUNCBOB) { - if ((result->flags & MOVERESULT_ONTOPOF_FUNCBOB) || + if ((result->flags & MOVERESULT_ONTOPOF_ELEVATOR) || (result->flags & MOVERESULT_ONTOPOF_FUNCBOB)) { ms->reachability_time = AAS_Time() + 5; diff --git a/code/cgame/cg_draw.c b/code/cgame/cg_draw.c index 50fcb717..96660831 100644 --- a/code/cgame/cg_draw.c +++ b/code/cgame/cg_draw.c @@ -2123,9 +2123,9 @@ static void CG_DrawTeamVote(void) { char *s; int sec, cs_offset; - if ( cgs.clientinfo->team == TEAM_RED ) + if ( cgs.clientinfo[cg.clientNum].team == TEAM_RED ) cs_offset = 0; - else if ( cgs.clientinfo->team == TEAM_BLUE ) + else if ( cgs.clientinfo[cg.clientNum].team == TEAM_BLUE ) cs_offset = 1; else return; diff --git a/code/cgame/cg_event.c b/code/cgame/cg_event.c index ebb28520..5be58384 100644 --- a/code/cgame/cg_event.c +++ b/code/cgame/cg_event.c @@ -418,6 +418,51 @@ static void CG_ItemPickup( int itemNum ) { } +/* +================ +CG_WaterLevel + +Returns waterlevel for entity origin +================ +*/ +int CG_WaterLevel(centity_t *cent) { + vec3_t point; + int contents, sample1, sample2, anim, waterlevel; + + // get waterlevel, accounting for ducking + waterlevel = 0; + VectorCopy(cent->lerpOrigin, point); + point[2] += MINS_Z + 1; + anim = cent->currentState.legsAnim & ~ANIM_TOGGLEBIT; + + if (anim == LEGS_WALKCR || anim == LEGS_IDLECR) { + point[2] += CROUCH_VIEWHEIGHT; + } else { + point[2] += DEFAULT_VIEWHEIGHT; + } + + contents = CG_PointContents(point, -1); + + if (contents & MASK_WATER) { + sample2 = point[2] - MINS_Z; + sample1 = sample2 / 2; + waterlevel = 1; + point[2] = cent->lerpOrigin[2] + MINS_Z + sample1; + contents = CG_PointContents(point, -1); + + if (contents & MASK_WATER) { + waterlevel = 2; + point[2] = cent->lerpOrigin[2] + MINS_Z + sample2; + contents = CG_PointContents(point, -1); + + if (contents & MASK_WATER) { + waterlevel = 3; + } + } + } + + return waterlevel; +} /* ================ @@ -443,9 +488,16 @@ void CG_PainEvent( centity_t *cent, int health ) { } else { snd = "*pain100_1.wav"; } - trap_S_StartSound( NULL, cent->currentState.number, CHAN_VOICE, - CG_CustomSound( cent->currentState.number, snd ) ); - + // play a gurp sound instead of a normal pain sound + if (CG_WaterLevel(cent) >= 1) { + if (rand()&1) { + trap_S_StartSound(NULL, cent->currentState.number, CHAN_VOICE, CG_CustomSound(cent->currentState.number, "sound/player/gurp1.wav")); + } else { + trap_S_StartSound(NULL, cent->currentState.number, CHAN_VOICE, CG_CustomSound(cent->currentState.number, "sound/player/gurp2.wav")); + } + } else { + trap_S_StartSound(NULL, cent->currentState.number, CHAN_VOICE, CG_CustomSound(cent->currentState.number, snd)); + } // save pain time for programitic twitch animation cent->pe.painTime = cg.time; cent->pe.painDirection ^= 1; @@ -1105,8 +1157,13 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { case EV_DEATH2: case EV_DEATH3: DEBUGNAME("EV_DEATHx"); - trap_S_StartSound( NULL, es->number, CHAN_VOICE, - CG_CustomSound( es->number, va("*death%i.wav", event - EV_DEATH1 + 1) ) ); + + if (CG_WaterLevel(cent) >= 1) { + trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, "*drown.wav")); + } else { + trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, va("*death%i.wav", event - EV_DEATH1 + 1))); + } + break; diff --git a/code/cgame/cg_main.c b/code/cgame/cg_main.c index 6aaec5ce..6bed3da2 100644 --- a/code/cgame/cg_main.c +++ b/code/cgame/cg_main.c @@ -920,6 +920,7 @@ static void CG_RegisterGraphics( void ) { } if ( cgs.gametype == GT_OBELISK || cg_buildScript.integer ) { + cgs.media.rocketExplosionShader = trap_R_RegisterShader("rocketExplosion"); cgs.media.overloadBaseModel = trap_R_RegisterModel( "models/powerups/overload_base.md3" ); cgs.media.overloadTargetModel = trap_R_RegisterModel( "models/powerups/overload_target.md3" ); cgs.media.overloadLightsModel = trap_R_RegisterModel( "models/powerups/overload_lights.md3" ); @@ -1189,7 +1190,7 @@ char *CG_GetMenuBuffer(const char *filename) { return NULL; } if ( len >= MAX_MENUFILE ) { - trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, MAX_MENUFILE ) ); + trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i\n", filename, len, MAX_MENUFILE ) ); trap_FS_FCloseFile( f ); return NULL; } @@ -1446,7 +1447,7 @@ void CG_LoadMenus(const char *menuFile) { } if ( len >= MAX_MENUDEFFILE ) { - trap_Error( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", menuFile, len, MAX_MENUDEFFILE ) ); + trap_Error( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i\n", menuFile, len, MAX_MENUDEFFILE ) ); trap_FS_FCloseFile( f ); return; } diff --git a/code/cgame/cg_players.c b/code/cgame/cg_players.c index 174c4986..e5cf2f09 100644 --- a/code/cgame/cg_players.c +++ b/code/cgame/cg_players.c @@ -247,7 +247,7 @@ static qboolean CG_ParseAnimationFile( const char *filename, clientInfo_t *ci ) } if ( i != MAX_ANIMATIONS ) { - CG_Printf( "Error parsing animation file: %s", filename ); + CG_Printf( "Error parsing animation file: %s\n", filename ); return qfalse; } @@ -1048,7 +1048,7 @@ void CG_NewClientInfo( int clientNum ) { CG_SetDeferredClientInfo( clientNum, &newInfo ); // if we are low on memory, leave them with this model if ( forceDefer ) { - CG_Printf( "Memory is low. Using deferred model.\n" ); + CG_Printf( "Memory is low. Using deferred model.\n" ); newInfo.deferred = qfalse; } } else { @@ -1081,7 +1081,7 @@ void CG_LoadDeferredPlayers( void ) { if ( ci->infoValid && ci->deferred ) { // if we are low on memory, leave it deferred if ( trap_MemoryRemaining() < 4000000 ) { - CG_Printf( "Memory is low. Using deferred model.\n" ); + CG_Printf( "Memory is low. Using deferred model.\n" ); ci->deferred = qfalse; continue; } @@ -1399,7 +1399,8 @@ static void CG_PlayerAngles( centity_t *cent, vec3_t legs[3], vec3_t torso[3], v // allow yaw to drift a bit if ( ( cent->currentState.legsAnim & ~ANIM_TOGGLEBIT ) != LEGS_IDLE - || ( cent->currentState.torsoAnim & ~ANIM_TOGGLEBIT ) != TORSO_STAND ) { + || ((cent->currentState.torsoAnim & ~ANIM_TOGGLEBIT) != TORSO_STAND + && (cent->currentState.torsoAnim & ~ANIM_TOGGLEBIT) != TORSO_STAND2)) { // if not standing still, always point all in the same direction cent->pe.torso.yawing = qtrue; // always center cent->pe.torso.pitching = qtrue; // always center diff --git a/code/cgame/cg_playerstate.c b/code/cgame/cg_playerstate.c index 007b3bfe..066e24a1 100644 --- a/code/cgame/cg_playerstate.c +++ b/code/cgame/cg_playerstate.c @@ -415,7 +415,7 @@ void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) { } // check for flag pickup - if ( cgs.gametype >= GT_TEAM ) { + if ( cgs.gametype > GT_TEAM ) { if ((ps->powerups[PW_REDFLAG] != ops->powerups[PW_REDFLAG] && ps->powerups[PW_REDFLAG]) || (ps->powerups[PW_BLUEFLAG] != ops->powerups[PW_BLUEFLAG] && ps->powerups[PW_BLUEFLAG]) || (ps->powerups[PW_NEUTRALFLAG] != ops->powerups[PW_NEUTRALFLAG] && ps->powerups[PW_NEUTRALFLAG]) ) @@ -465,6 +465,11 @@ void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) { // fraglimit warnings if ( cgs.fraglimit > 0 && cgs.gametype < GT_CTF) { highScore = cgs.scores1; + + if (cgs.gametype == GT_TEAM && cgs.scores2 > highScore) { + highScore = cgs.scores2; + } + if ( !( cg.fraglimitWarnings & 4 ) && highScore == (cgs.fraglimit - 1) ) { cg.fraglimitWarnings |= 1 | 2 | 4; CG_AddBufferedSound(cgs.media.oneFragSound); diff --git a/code/cgame/cg_predict.c b/code/cgame/cg_predict.c index 2da4e034..b7a69532 100644 --- a/code/cgame/cg_predict.c +++ b/code/cgame/cg_predict.c @@ -287,10 +287,8 @@ static void CG_TouchItem( centity_t *cent ) { return; } } - if( cgs.gametype == GT_CTF || cgs.gametype == GT_HARVESTER ) { -#else - if( cgs.gametype == GT_CTF ) { #endif + if( cgs.gametype == GT_CTF ) { if (cg.predictedPlayerState.persistant[PERS_TEAM] == TEAM_RED && item->giTag == PW_REDFLAG) return; diff --git a/code/cgame/cg_servercmds.c b/code/cgame/cg_servercmds.c index 2c7a0747..28147c64 100644 --- a/code/cgame/cg_servercmds.c +++ b/code/cgame/cg_servercmds.c @@ -545,7 +545,7 @@ int CG_ParseVoiceChats( const char *filename, voiceChatList_t *voiceChatList, in return qfalse; } if ( len >= MAX_VOICEFILESIZE ) { - trap_Print( va( S_COLOR_RED "voice chat file too large: %s is %i, max allowed is %i", filename, len, MAX_VOICEFILESIZE ) ); + trap_Print( va( S_COLOR_RED "voice chat file too large: %s is %i, max allowed is %i\n", filename, len, MAX_VOICEFILESIZE ) ); trap_FS_FCloseFile( f ); return qfalse; } @@ -658,7 +658,7 @@ int CG_HeadModelVoiceChats( char *filename ) { return -1; } if ( len >= MAX_VOICEFILESIZE ) { - trap_Print( va( S_COLOR_RED "voice chat file too large: %s is %i, max allowed is %i", filename, len, MAX_VOICEFILESIZE ) ); + trap_Print( va( S_COLOR_RED "voice chat file too large: %s is %i, max allowed is %i\n", filename, len, MAX_VOICEFILESIZE ) ); trap_FS_FCloseFile( f ); return -1; } diff --git a/code/client/cl_main.c b/code/client/cl_main.c index 2e17c970..7c8c2102 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -2598,7 +2598,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { if (clc.state != CA_CONNECTING) { - Com_DPrintf("Unwanted challenge response received. Ignored.\n"); + Com_DPrintf("Unwanted challenge response received. Ignored.\n"); return; } @@ -2677,7 +2677,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { // server connection if ( !Q_stricmp(c, "connectResponse") ) { if ( clc.state >= CA_CONNECTED ) { - Com_Printf ("Dup connect received. Ignored.\n"); + Com_Printf ("Dup connect received. Ignored.\n"); return; } if ( clc.state != CA_CHALLENGING ) { diff --git a/code/game/ai_chat.c b/code/game/ai_chat.c index 373eb5e9..3a5928b5 100644 --- a/code/game/ai_chat.c +++ b/code/game/ai_chat.c @@ -381,6 +381,7 @@ int BotValidChatPosition(bot_state_t *bs) { if (BotIsDead(bs)) return qtrue; //never start chatting with a powerup if (bs->inventory[INVENTORY_QUAD] || + bs->inventory[INVENTORY_ENVIRONMENTSUIT] || bs->inventory[INVENTORY_HASTE] || bs->inventory[INVENTORY_INVISIBILITY] || bs->inventory[INVENTORY_REGEN] || diff --git a/code/game/ai_dmnet.c b/code/game/ai_dmnet.c index 9983a9e6..e8f461db 100644 --- a/code/game/ai_dmnet.c +++ b/code/game/ai_dmnet.c @@ -193,8 +193,12 @@ int BotNearbyGoal(bot_state_t *bs, int tfl, bot_goal_t *ltg, float range) { //check if the bot should go for air if (BotGoForAir(bs, tfl, ltg, range)) return qtrue; - //if the bot is carrying the enemy flag - if (BotCTFCarryingFlag(bs)) { + // if the bot is carrying a flag or cubes + if (BotCTFCarryingFlag(bs) +#ifdef MISSIONPACK + || Bot1FCTFCarryingFlag(bs) || BotHarvesterCarryingCubes(bs) +#endif + ) { //if the bot is just a few secs away from the base if (trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, bs->teamgoal.areanum, TFL_DEFAULT) < 300) { @@ -1303,7 +1307,11 @@ int BotSelectActivateWeapon(bot_state_t *bs) { return WEAPONINDEX_CHAINGUN; else if (bs->inventory[INVENTORY_NAILGUN] > 0 && bs->inventory[INVENTORY_NAILS] > 0) return WEAPONINDEX_NAILGUN; + else if (bs->inventory[INVENTORY_PROXLAUNCHER] > 0 && bs->inventory[INVENTORY_MINES] > 0) + return WEAPONINDEX_PROXLAUNCHER; #endif + else if (bs->inventory[INVENTORY_GRENADELAUNCHER] > 0 && bs->inventory[INVENTORY_GRENADES] > 0) + return WEAPONINDEX_GRENADE_LAUNCHER; else if (bs->inventory[INVENTORY_RAILGUN] > 0 && bs->inventory[INVENTORY_SLUGS] > 0) return WEAPONINDEX_RAILGUN; else if (bs->inventory[INVENTORY_ROCKETLAUNCHER] > 0 && bs->inventory[INVENTORY_ROCKETS] > 0) @@ -1962,11 +1970,12 @@ void AIEnter_Battle_Fight(bot_state_t *bs, char *s) { BotRecordNodeSwitch(bs, "battle fight", "", s); trap_BotResetLastAvoidReach(bs->ms); bs->ainode = AINode_Battle_Fight; + bs->flags &= ~BFL_FIGHTSUICIDAL; } /* ================== -AIEnter_Battle_Fight +AIEnter_Battle_SuicidalFight ================== */ void AIEnter_Battle_SuicidalFight(bot_state_t *bs, char *s) { @@ -2083,6 +2092,12 @@ int AINode_Battle_Fight(bot_state_t *bs) { } //if the enemy is not visible if (!BotEntityVisible(bs->entitynum, bs->eye, bs->viewangles, 360, bs->enemy)) { +#ifdef MISSIONPACK + if (bs->enemy == redobelisk.entitynum || bs->enemy == blueobelisk.entitynum) { + AIEnter_Battle_Chase(bs, "battle fight: obelisk out of sight"); + return qfalse; + } +#endif if (BotWantsToChase(bs)) { AIEnter_Battle_Chase(bs, "battle fight: enemy out of sight"); return qfalse; diff --git a/code/game/ai_dmq3.c b/code/game/ai_dmq3.c index 722a9908..ada5b5d6 100644 --- a/code/game/ai_dmq3.c +++ b/code/game/ai_dmq3.c @@ -141,16 +141,17 @@ BotTeam ================== */ int BotTeam(bot_state_t *bs) { - char info[1024]; if (bs->client < 0 || bs->client >= MAX_CLIENTS) { - //BotAI_Print(PRT_ERROR, "BotCTFTeam: client out of range\n"); return qfalse; } - trap_GetConfigstring(CS_PLAYERS+bs->client, info, sizeof(info)); - // - if (atoi(Info_ValueForKey(info, "t")) == TEAM_RED) return TEAM_RED; - else if (atoi(Info_ValueForKey(info, "t")) == TEAM_BLUE) return TEAM_BLUE; + + if (level.clients[bs->client].sess.sessionTeam == TEAM_RED) { + return TEAM_RED; + } else if (level.clients[bs->client].sess.sessionTeam == TEAM_BLUE) { + return TEAM_BLUE; + } + return TEAM_FREE; } @@ -1677,8 +1678,8 @@ void BotCheckItemPickup(bot_state_t *bs, int *oldinventory) { //trap_BotEnterChat(bs->cs, leader, CHAT_TELL); } } - bs->teamtaskpreference |= TEAMTP_ATTACKER; } + bs->teamtaskpreference |= TEAMTP_ATTACKER; } bs->teamtaskpreference &= ~TEAMTP_DEFENDER; } @@ -2283,7 +2284,7 @@ int BotWantsToRetreat(bot_state_t *bs) { else if (gametype == GT_OBELISK) { //the bots should be dedicated to attacking the enemy obelisk if (bs->ltgtype == LTG_ATTACKENEMYBASE) { - if (bs->enemy != redobelisk.entitynum || + if (bs->enemy != redobelisk.entitynum && bs->enemy != blueobelisk.entitynum) { return qtrue; } @@ -2302,8 +2303,12 @@ int BotWantsToRetreat(bot_state_t *bs) { if (bs->enemy >= 0) { //if the enemy is carrying a flag BotEntityInfo(bs->enemy, &entinfo); - if (EntityCarriesFlag(&entinfo)) - return qfalse; + // if the enemy is carrying a flag + if (EntityCarriesFlag(&entinfo)) return qfalse; +#ifdef MISSIONPACK + // if the enemy is carrying cubes + if (EntityCarriesCubes(&entinfo)) return qfalse; +#endif } //if the bot is getting the flag if (bs->ltgtype == LTG_GETFLAG) @@ -2344,7 +2349,7 @@ int BotWantsToChase(bot_state_t *bs) { else if (gametype == GT_OBELISK) { //the bots should be dedicated to attacking the enemy obelisk if (bs->ltgtype == LTG_ATTACKENEMYBASE) { - if (bs->enemy != redobelisk.entitynum || + if (bs->enemy != redobelisk.entitynum && bs->enemy != blueobelisk.entitynum) { return qfalse; } @@ -2352,8 +2357,11 @@ int BotWantsToChase(bot_state_t *bs) { } else if (gametype == GT_HARVESTER) { //never chase if carrying cubes - if (BotHarvesterCarryingCubes(bs)) - return qfalse; + if (BotHarvesterCarryingCubes(bs)) return qfalse; + + BotEntityInfo(bs->enemy, &entinfo); + // always chase if the enemy is carrying cubes + if (EntityCarriesCubes(&entinfo)) return qtrue; } #endif //if the bot is getting the flag @@ -2767,22 +2775,19 @@ BotSameTeam ================== */ int BotSameTeam(bot_state_t *bs, int entnum) { - char info1[1024], info2[1024]; if (bs->client < 0 || bs->client >= MAX_CLIENTS) { - //BotAI_Print(PRT_ERROR, "BotSameTeam: client out of range\n"); return qfalse; } + if (entnum < 0 || entnum >= MAX_CLIENTS) { - //BotAI_Print(PRT_ERROR, "BotSameTeam: client out of range\n"); return qfalse; } - if ( gametype >= GT_TEAM ) { - trap_GetConfigstring(CS_PLAYERS+bs->client, info1, sizeof(info1)); - trap_GetConfigstring(CS_PLAYERS+entnum, info2, sizeof(info2)); - // - if (atoi(Info_ValueForKey(info1, "t")) == atoi(Info_ValueForKey(info2, "t"))) return qtrue; + + if (gametype >= GT_TEAM) { + if (level.clients[bs->client].sess.sessionTeam == level.clients[entnum].sess.sessionTeam) return qtrue; } + return qfalse; } @@ -3636,7 +3641,7 @@ void BotCheckAttack(bot_state_t *bs) { VectorMA(start, -12, forward, start); BotAI_Trace(&trace, start, mins, maxs, end, bs->entitynum, MASK_SHOT); //if the entity is a client - if (trace.ent > 0 && trace.ent <= MAX_CLIENTS) { + if (trace.ent >= 0 && trace.ent < MAX_CLIENTS) { if (trace.ent != attackentity) { //if a teammate is hit if (BotSameTeam(bs, trace.ent)) @@ -5133,7 +5138,7 @@ void BotSetupAlternativeRouteGoals(void) { #ifdef MISSIONPACK if (gametype == GT_CTF) { if (trap_BotGetLevelItemGoal(-1, "Neutral Flag", &ctf_neutralflag) < 0) - BotAI_Print(PRT_WARNING, "no alt routes without Neutral Flag\n"); + BotAI_Print(PRT_WARNING, "No alt routes without Neutral Flag\n"); if (ctf_neutralflag.areanum) { // red_numaltroutegoals = trap_AAS_AlternativeRouteGoals( @@ -5151,7 +5156,8 @@ void BotSetupAlternativeRouteGoals(void) { } } else if (gametype == GT_1FCTF) { - // + if (trap_BotGetLevelItemGoal(-1, "Neutral Obelisk", &neutralobelisk) < 0) + BotAI_Print(PRT_WARNING, "One Flag CTF without Neutral Obelisk\n"); red_numaltroutegoals = trap_AAS_AlternativeRouteGoals( ctf_neutralflag.origin, ctf_neutralflag.areanum, ctf_redflag.origin, ctf_redflag.areanum, TFL_DEFAULT, @@ -5167,7 +5173,7 @@ void BotSetupAlternativeRouteGoals(void) { } else if (gametype == GT_OBELISK) { if (trap_BotGetLevelItemGoal(-1, "Neutral Obelisk", &neutralobelisk) < 0) - BotAI_Print(PRT_WARNING, "Harvester without neutral obelisk\n"); + BotAI_Print(PRT_WARNING, "No alt routes without Neutral Obelisk\n"); // red_numaltroutegoals = trap_AAS_AlternativeRouteGoals( neutralobelisk.origin, neutralobelisk.areanum, @@ -5183,7 +5189,8 @@ void BotSetupAlternativeRouteGoals(void) { ALTROUTEGOAL_VIEWPORTALS); } else if (gametype == GT_HARVESTER) { - // + if (trap_BotGetLevelItemGoal(-1, "Neutral Obelisk", &neutralobelisk) < 0) + BotAI_Print(PRT_WARNING, "Harvester without Neutral Obelisk\n"); red_numaltroutegoals = trap_AAS_AlternativeRouteGoals( neutralobelisk.origin, neutralobelisk.areanum, redobelisk.origin, redobelisk.areanum, TFL_DEFAULT, @@ -5414,27 +5421,27 @@ void BotSetupDeathmatchAI(void) { if (trap_BotGetLevelItemGoal(-1, "Neutral Flag", &ctf_neutralflag) < 0) BotAI_Print(PRT_WARNING, "One Flag CTF without Neutral Flag\n"); if (trap_BotGetLevelItemGoal(-1, "Red Flag", &ctf_redflag) < 0) - BotAI_Print(PRT_WARNING, "CTF without Red Flag\n"); + BotAI_Print(PRT_WARNING, "One Flag CTF without Red Flag\n"); if (trap_BotGetLevelItemGoal(-1, "Blue Flag", &ctf_blueflag) < 0) - BotAI_Print(PRT_WARNING, "CTF without Blue Flag\n"); + BotAI_Print(PRT_WARNING, "One Flag CTF without Blue Flag\n"); } else if (gametype == GT_OBELISK) { if (trap_BotGetLevelItemGoal(-1, "Red Obelisk", &redobelisk) < 0) - BotAI_Print(PRT_WARNING, "Obelisk without red obelisk\n"); + BotAI_Print(PRT_WARNING, "Overload without Red Obelisk\n"); BotSetEntityNumForGoal(&redobelisk, "team_redobelisk"); if (trap_BotGetLevelItemGoal(-1, "Blue Obelisk", &blueobelisk) < 0) - BotAI_Print(PRT_WARNING, "Obelisk without blue obelisk\n"); + BotAI_Print(PRT_WARNING, "Overload without Blue Obelisk\n"); BotSetEntityNumForGoal(&blueobelisk, "team_blueobelisk"); } else if (gametype == GT_HARVESTER) { if (trap_BotGetLevelItemGoal(-1, "Red Obelisk", &redobelisk) < 0) - BotAI_Print(PRT_WARNING, "Harvester without red obelisk\n"); + BotAI_Print(PRT_WARNING, "Harvester without Red Obelisk\n"); BotSetEntityNumForGoal(&redobelisk, "team_redobelisk"); if (trap_BotGetLevelItemGoal(-1, "Blue Obelisk", &blueobelisk) < 0) - BotAI_Print(PRT_WARNING, "Harvester without blue obelisk\n"); + BotAI_Print(PRT_WARNING, "Harvester without Blue Obelisk\n"); BotSetEntityNumForGoal(&blueobelisk, "team_blueobelisk"); if (trap_BotGetLevelItemGoal(-1, "Neutral Obelisk", &neutralobelisk) < 0) - BotAI_Print(PRT_WARNING, "Harvester without neutral obelisk\n"); + BotAI_Print(PRT_WARNING, "Harvester without Neutral Obelisk\n"); BotSetEntityNumForGoal(&neutralobelisk, "team_neutralobelisk"); } #endif diff --git a/code/game/ai_main.c b/code/game/ai_main.c index fb37c283..bbf5fd57 100644 --- a/code/game/ai_main.c +++ b/code/game/ai_main.c @@ -821,11 +821,10 @@ void BotInputToUserCommand(bot_input_t *bi, usercmd_t *ucmd, int delta_angles[3] vec3_t angles, forward, right; short temp; int j; + float f, r, u, m; //clear the whole structure memset(ucmd, 0, sizeof(usercmd_t)); - // - //Com_Printf("dir = %f %f %f speed = %f\n", bi->dir[0], bi->dir[1], bi->dir[2], bi->speed); //the duration for the user command in milli seconds ucmd->serverTime = time; // @@ -876,21 +875,37 @@ void BotInputToUserCommand(bot_input_t *bi, usercmd_t *ucmd, int delta_angles[3] //bot input speed is in the range [0, 400] bi->speed = bi->speed * 127 / 400; //set the view independent movement - ucmd->forwardmove = DotProduct(forward, bi->dir) * bi->speed; - ucmd->rightmove = DotProduct(right, bi->dir) * bi->speed; - ucmd->upmove = abs(forward[2]) * bi->dir[2] * bi->speed; - //normal keyboard movement - if (bi->actionflags & ACTION_MOVEFORWARD) ucmd->forwardmove += 127; - if (bi->actionflags & ACTION_MOVEBACK) ucmd->forwardmove -= 127; - if (bi->actionflags & ACTION_MOVELEFT) ucmd->rightmove -= 127; - if (bi->actionflags & ACTION_MOVERIGHT) ucmd->rightmove += 127; + f = DotProduct(forward, bi->dir); + r = DotProduct(right, bi->dir); + u = abs(forward[2]) * bi->dir[2]; + m = fabs(f); + + if (fabs(r) > m) { + m = fabs(r); + } + + if (fabs(u) > m) { + m = fabs(u); + } + + if (m > 0) { + f *= bi->speed / m; + r *= bi->speed / m; + u *= bi->speed / m; + } + + ucmd->forwardmove = f; + ucmd->rightmove = r; + ucmd->upmove = u; + + if (bi->actionflags & ACTION_MOVEFORWARD) ucmd->forwardmove = 127; + if (bi->actionflags & ACTION_MOVEBACK) ucmd->forwardmove = -127; + if (bi->actionflags & ACTION_MOVELEFT) ucmd->rightmove = -127; + if (bi->actionflags & ACTION_MOVERIGHT) ucmd->rightmove = 127; //jump/moveup - if (bi->actionflags & ACTION_JUMP) ucmd->upmove += 127; + if (bi->actionflags & ACTION_JUMP) ucmd->upmove = 127; //crouch/movedown - if (bi->actionflags & ACTION_CROUCH) ucmd->upmove -= 127; - // - //Com_Printf("forward = %d right = %d up = %d\n", ucmd.forwardmove, ucmd.rightmove, ucmd.upmove); - //Com_Printf("ucmd->serverTime = %d\n", ucmd->serverTime); + if (bi->actionflags & ACTION_CROUCH) ucmd->upmove = -127; } /* diff --git a/code/game/ai_team.c b/code/game/ai_team.c index 858c16cd..2abcce16 100644 --- a/code/game/ai_team.c +++ b/code/game/ai_team.c @@ -458,11 +458,11 @@ void BotCTFOrders_FlagNotAtBase(bot_state_t *bs) { case 1: break; case 2: { - //both will go for the enemy flag + // keep one near the base for when the flag is returned ClientName(teammates[0], name, sizeof(name)); BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL); BotSayTeamOrder(bs, teammates[0]); - BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_GETFLAG); + BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND); // ClientName(teammates[1], name, sizeof(name)); BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL); @@ -494,7 +494,7 @@ void BotCTFOrders_FlagNotAtBase(bot_state_t *bs) { //keep some people near the base for when the flag is returned defenders = (int) (float) numteammates * 0.3 + 0.5; if (defenders > 3) defenders = 3; - attackers = (int) (float) numteammates * 0.7 + 0.5; + attackers = (int) (float) numteammates * 0.6 + 0.5; if (attackers > 6) attackers = 6; for (i = 0; i < defenders; i++) { // @@ -537,7 +537,7 @@ void BotCTFOrders_FlagNotAtBase(bot_state_t *bs) { { //everyone go for the flag ClientName(teammates[0], name, sizeof(name)); - BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL); + BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL); BotSayTeamOrder(bs, teammates[0]); BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_GETFLAG); // @@ -1349,7 +1349,7 @@ void Bot1FCTFOrders_EnemyHasFlag(bot_state_t *bs) { if (defenders > 8) defenders = 8; //10% will try to return the flag attackers = (int) (float) numteammates * 0.1 + 0.5; - if (attackers > 2) attackers = 2; + if (attackers > 1) attackers = 1; for (i = 0; i < defenders; i++) { // ClientName(teammates[i], name, sizeof(name)); @@ -1410,7 +1410,7 @@ void Bot1FCTFOrders_EnemyHasFlag(bot_state_t *bs) { { //70% defend the base defenders = (int) (float) numteammates * 0.7 + 0.5; - if (defenders > 8) defenders = 8; + if (defenders > 7) defenders = 7; //20% try to return the flag attackers = (int) (float) numteammates * 0.2 + 0.5; if (attackers > 2) attackers = 2; @@ -1573,7 +1573,7 @@ void Bot1FCTFOrders_EnemyDroppedFlag(bot_state_t *bs) { ClientName(teammates[numteammates - i - 1], name, sizeof(name)); BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL); BotSayTeamOrder(bs, teammates[numteammates - i - 1]); - BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_DEFEND); + BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG); } // break; diff --git a/code/game/bg_pmove.c b/code/game/bg_pmove.c index 799a3851..7485a4f4 100644 --- a/code/game/bg_pmove.c +++ b/code/game/bg_pmove.c @@ -424,7 +424,7 @@ static qboolean PM_CheckWaterJump( void ) { spot[2] += 16; cont = pm->pointcontents (spot, pm->ps->clientNum ); - if ( cont ) { + if ( cont & (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_BODY) ) { return qfalse; } @@ -1862,7 +1862,7 @@ void PmoveSingle (pmove_t *pmove) { } // set the firing flag for continuous beam weapons - if ( !(pm->ps->pm_flags & PMF_RESPAWNED) && pm->ps->pm_type != PM_INTERMISSION + if ( !(pm->ps->pm_flags & PMF_RESPAWNED) && pm->ps->pm_type != PM_INTERMISSION && (!pm->ps->pm_type == PM_NOCLIP) && ( pm->cmd.buttons & BUTTON_ATTACK ) && pm->ps->ammo[ pm->ps->weapon ] ) { pm->ps->eFlags |= EF_FIRING; } else { diff --git a/code/game/g_active.c b/code/game/g_active.c index 136e1bae..df56efd8 100644 --- a/code/game/g_active.c +++ b/code/game/g_active.c @@ -128,15 +128,6 @@ void P_WorldEffects( gentity_t *ent ) { if (ent->damage > 15) ent->damage = 15; - // play a gurp sound instead of a normal pain sound - if (ent->health <= ent->damage) { - G_Sound(ent, CHAN_VOICE, G_SoundIndex("*drown.wav")); - } else if (rand()&1) { - G_Sound(ent, CHAN_VOICE, G_SoundIndex("sound/player/gurp1.wav")); - } else { - G_Sound(ent, CHAN_VOICE, G_SoundIndex("sound/player/gurp2.wav")); - } - // don't play a normal pain sound ent->pain_debounce_time = level.time + 200; @@ -999,13 +990,13 @@ void ClientThink_real( gentity_t *ent ) { // forcerespawn is to prevent users from waiting out powerups if ( g_forcerespawn.integer > 0 && ( level.time - client->respawnTime ) > g_forcerespawn.integer * 1000 ) { - respawn( ent ); + ClientRespawn( ent ); return; } // pressing attack or use is the normal respawn method if ( ucmd->buttons & ( BUTTON_ATTACK | BUTTON_USE_HOLDABLE ) ) { - respawn( ent ); + ClientRespawn( ent ); } } return; diff --git a/code/game/g_bot.c b/code/game/g_bot.c index cecf40c8..db495d10 100644 --- a/code/game/g_bot.c +++ b/code/game/g_bot.c @@ -132,7 +132,7 @@ static void G_LoadArenasFromFile( char *filename ) { return; } if ( len >= MAX_ARENAS_TEXT ) { - trap_Printf( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_ARENAS_TEXT ) ); + trap_Printf( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i\n", filename, len, MAX_ARENAS_TEXT ) ); trap_FS_FCloseFile( f ); return; } @@ -651,7 +651,7 @@ static void G_AddBot( const char *name, float skill, const char *team, int delay // have the server allocate a client slot clientNum = trap_BotAllocateClient(); if ( clientNum == -1 ) { - G_Printf( S_COLOR_RED "Unable to add bot. All player slots are in use.\n" ); + G_Printf( S_COLOR_RED "Unable to add bot. All player slots are in use.\n" ); G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" ); return; } @@ -863,7 +863,7 @@ static void G_LoadBotsFromFile( char *filename ) { return; } if ( len >= MAX_BOTS_TEXT ) { - trap_Printf( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_BOTS_TEXT ) ); + trap_Printf( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i\n", filename, len, MAX_BOTS_TEXT ) ); trap_FS_FCloseFile( f ); return; } diff --git a/code/game/g_client.c b/code/game/g_client.c index 441030bd..60e243f8 100644 --- a/code/game/g_client.c +++ b/code/game/g_client.c @@ -419,8 +419,6 @@ void CopyToBodyQue( gentity_t *ent ) { body = level.bodyQue[ level.bodyQueIndex ]; level.bodyQueIndex = (level.bodyQueIndex + 1) % BODY_QUEUE_SIZE; - trap_UnlinkEntity (body); - body->s = ent->s; body->s.eFlags = EF_DEAD; // clear EF_TALK, etc #ifdef MISSIONPACK @@ -526,18 +524,13 @@ void SetClientViewAngle( gentity_t *ent, vec3_t angle ) { /* ================ -respawn +ClientRespawn ================ */ -void respawn( gentity_t *ent ) { - gentity_t *tent; +void ClientRespawn( gentity_t *ent ) { CopyToBodyQue (ent); ClientSpawn(ent); - - // add a teleportation effect - tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_IN ); - tent->s.clientNum = ent->s.clientNum; } /* @@ -1007,7 +1000,6 @@ and on transition between teams, but doesn't happen on respawns void ClientBegin( int clientNum ) { gentity_t *ent; gclient_t *client; - gentity_t *tent; int flags; ent = g_entities + clientNum; @@ -1039,10 +1031,6 @@ void ClientBegin( int clientNum ) { ClientSpawn( ent ); if ( client->sess.sessionTeam != TEAM_SPECTATOR ) { - // send event - tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_IN ); - tent->s.clientNum = ent->s.clientNum; - if ( g_gametype.integer != GT_TOURNAMENT ) { trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " entered the game\n\"", client->pers.netname) ); } @@ -1071,6 +1059,7 @@ void ClientSpawn(gentity_t *ent) { clientSession_t savedSess; int persistant[MAX_PERSISTANT]; gentity_t *spawnPoint; + gentity_t *tent; int flags; int savedPing; // char *savedAreaBits; @@ -1206,19 +1195,6 @@ void ClientSpawn(gentity_t *ent) { trap_GetUsercmd( client - level.clients, &ent->client->pers.cmd ); SetClientViewAngle( ent, spawn_angles ); - - if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) { - - } else { - G_KillBox( ent ); - trap_LinkEntity (ent); - - // force the base weapon up - client->ps.weapon = WP_MACHINEGUN; - client->ps.weaponstate = WEAPON_READY; - - } - // don't allow full run speed for a bit client->ps.pm_flags |= PMF_TIME_KNOCKBACK; client->ps.pm_time = 100; @@ -1231,36 +1207,40 @@ void ClientSpawn(gentity_t *ent) { client->ps.torsoAnim = TORSO_STAND; client->ps.legsAnim = LEGS_IDLE; - if ( level.intermissiontime ) { - MoveClientToIntermission( ent ); - } else { - // fire the targets of the spawn point - G_UseTargets( spawnPoint, ent ); + if (!level.intermissiontime) { + if (ent->client->sess.sessionTeam != TEAM_SPECTATOR) { + G_KillBox(ent); + // force the base weapon up + client->ps.weapon = WP_MACHINEGUN; + client->ps.weaponstate = WEAPON_READY; + // fire the targets of the spawn point + G_UseTargets(spawnPoint, ent); + // select the highest weapon number available, after any spawn given items have fired + client->ps.weapon = 1; - // select the highest weapon number available, after any - // spawn given items have fired - client->ps.weapon = 1; - for ( i = WP_NUM_WEAPONS - 1 ; i > 0 ; i-- ) { - if ( client->ps.stats[STAT_WEAPONS] & ( 1 << i ) ) { - client->ps.weapon = i; - break; + for (i = WP_NUM_WEAPONS - 1 ; i > 0 ; i--) { + if (client->ps.stats[STAT_WEAPONS] & (1 << i)) { + client->ps.weapon = i; + break; + } } - } - } + // positively link the client, even if the command times are weird + VectorCopy(ent->client->ps.origin, ent->r.currentOrigin); + tent = G_TempEntity(ent->client->ps.origin, EV_PLAYER_TELEPORT_IN); + tent->s.clientNum = ent->s.clientNum; + + trap_LinkEntity (ent); + } + } else { + // move players to intermission + MoveClientToIntermission(ent); + } // run a client frame to drop exactly to the floor, // initialize animations and other things client->ps.commandTime = level.time - 100; ent->client->pers.cmd.serverTime = level.time; ClientThink( ent-g_entities ); - - // positively link the client, even if the command times are weird - if ( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) { - BG_PlayerStateToEntityState( &client->ps, &ent->s, qtrue ); - VectorCopy( ent->client->ps.origin, ent->r.currentOrigin ); - trap_LinkEntity( ent ); - } - // run the presend to set anything else ClientEndFrame( ent ); diff --git a/code/game/g_cmds.c b/code/game/g_cmds.c index 02469b30..2b86b66c 100644 --- a/code/game/g_cmds.c +++ b/code/game/g_cmds.c @@ -1171,7 +1171,7 @@ Cmd_Where_f ================== */ void Cmd_Where_f( gentity_t *ent ) { - trap_SendServerCommand( ent-g_entities, va("print \"%s\n\"", vtos( ent->s.origin ) ) ); + trap_SendServerCommand( ent-g_entities, va("print \"%s\n\"", vtos(ent->r.currentOrigin) ) ); } static const char *gameNames[] = { diff --git a/code/game/g_combat.c b/code/game/g_combat.c index 37095632..388407c7 100644 --- a/code/game/g_combat.c +++ b/code/game/g_combat.c @@ -561,22 +561,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int } } - // if client is in a nodrop area, don't drop anything (but return CTF flags!) - contents = trap_PointContents( self->r.currentOrigin, -1 ); - if ( !( contents & CONTENTS_NODROP )) { - TossClientItems( self ); - } - else { - if ( self->client->ps.powerups[PW_NEUTRALFLAG] ) { // only happens in One Flag CTF - Team_ReturnFlag( TEAM_FREE ); - } - else if ( self->client->ps.powerups[PW_REDFLAG] ) { // only happens in standard CTF - Team_ReturnFlag( TEAM_RED ); - } - else if ( self->client->ps.powerups[PW_BLUEFLAG] ) { // only happens in standard CTF - Team_ReturnFlag( TEAM_BLUE ); - } - } + TossClientItems( self ); #ifdef MISSIONPACK TossClientPersistantPowerups( self ); if( g_gametype.integer == GT_HARVESTER ) { @@ -626,6 +611,8 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int memset( self->client->ps.powerups, 0, sizeof(self->client->ps.powerups) ); // never gib in a nodrop + contents = trap_PointContents( self->r.currentOrigin, -1 ); + if ( (self->health <= GIB_HEALTH && !(contents & CONTENTS_NODROP) && g_blood.integer) || meansOfDeath == MOD_SUICIDE) { // gib death GibEntity( self, killer ); diff --git a/code/game/g_items.c b/code/game/g_items.c index 8eff46f5..26439830 100644 --- a/code/game/g_items.c +++ b/code/game/g_items.c @@ -724,11 +724,11 @@ void G_CheckTeamItems( void ) { // check for the two flags item = BG_FindItem( "Red Flag" ); if ( !item || !itemRegistered[ item - bg_itemlist ] ) { - G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_redflag in map" ); + G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_redflag in map\n" ); } item = BG_FindItem( "Blue Flag" ); if ( !item || !itemRegistered[ item - bg_itemlist ] ) { - G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map" ); + G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map\n" ); } } #ifdef MISSIONPACK @@ -738,15 +738,15 @@ void G_CheckTeamItems( void ) { // check for all three flags item = BG_FindItem( "Red Flag" ); if ( !item || !itemRegistered[ item - bg_itemlist ] ) { - G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_redflag in map" ); + G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_redflag in map\n" ); } item = BG_FindItem( "Blue Flag" ); if ( !item || !itemRegistered[ item - bg_itemlist ] ) { - G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map" ); + G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map\n" ); } item = BG_FindItem( "Neutral Flag" ); if ( !item || !itemRegistered[ item - bg_itemlist ] ) { - G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_neutralflag in map" ); + G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_neutralflag in map\n" ); } } @@ -757,13 +757,13 @@ void G_CheckTeamItems( void ) { ent = NULL; ent = G_Find( ent, FOFS(classname), "team_redobelisk" ); if( !ent ) { - G_Printf( S_COLOR_YELLOW "WARNING: No team_redobelisk in map" ); + G_Printf( S_COLOR_YELLOW "WARNING: No team_redobelisk in map\n" ); } ent = NULL; ent = G_Find( ent, FOFS(classname), "team_blueobelisk" ); if( !ent ) { - G_Printf( S_COLOR_YELLOW "WARNING: No team_blueobelisk in map" ); + G_Printf( S_COLOR_YELLOW "WARNING: No team_blueobelisk in map\n" ); } } @@ -774,19 +774,19 @@ void G_CheckTeamItems( void ) { ent = NULL; ent = G_Find( ent, FOFS(classname), "team_redobelisk" ); if( !ent ) { - G_Printf( S_COLOR_YELLOW "WARNING: No team_redobelisk in map" ); + G_Printf( S_COLOR_YELLOW "WARNING: No team_redobelisk in map\n" ); } ent = NULL; ent = G_Find( ent, FOFS(classname), "team_blueobelisk" ); if( !ent ) { - G_Printf( S_COLOR_YELLOW "WARNING: No team_blueobelisk in map" ); + G_Printf( S_COLOR_YELLOW "WARNING: No team_blueobelisk in map\n" ); } ent = NULL; ent = G_Find( ent, FOFS(classname), "team_neutralobelisk" ); if( !ent ) { - G_Printf( S_COLOR_YELLOW "WARNING: No team_neutralobelisk in map" ); + G_Printf( S_COLOR_YELLOW "WARNING: No team_neutralobelisk in map\n" ); } } #endif diff --git a/code/game/g_local.h b/code/game/g_local.h index 2d9e3a93..f7f24ce3 100644 --- a/code/game/g_local.h +++ b/code/game/g_local.h @@ -573,7 +573,7 @@ team_t PickTeam( int ignoreClientNum ); void SetClientViewAngle( gentity_t *ent, vec3_t angle ); gentity_t *SelectSpawnPoint (vec3_t avoidPoint, vec3_t origin, vec3_t angles, qboolean isbot); void CopyToBodyQue( gentity_t *ent ); -void respawn (gentity_t *ent); +void ClientRespawn(gentity_t *ent); void BeginIntermission (void); void InitClientPersistant (gclient_t *client); void InitClientResp (gclient_t *client); diff --git a/code/game/g_main.c b/code/game/g_main.c index 61fa107f..be150026 100644 --- a/code/game/g_main.c +++ b/code/game/g_main.c @@ -496,8 +496,6 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) { if( g_gametype.integer == GT_SINGLE_PLAYER || trap_Cvar_VariableIntegerValue( "com_buildScript" ) ) { G_ModelIndex( SP_PODIUM_MODEL ); - G_SoundIndex( "sound/player/gurp1.wav" ); - G_SoundIndex( "sound/player/gurp2.wav" ); } if ( trap_Cvar_VariableIntegerValue( "bot_enable" ) ) { @@ -933,7 +931,7 @@ void MoveClientToIntermission( gentity_t *ent ) { StopFollowing( ent ); } - + FindIntermissionPoint(); // move to the spot VectorCopy( level.intermission_origin, ent->s.origin ); VectorCopy( level.intermission_origin, ent->client->ps.origin ); @@ -1001,8 +999,17 @@ void BeginIntermission( void ) { } level.intermissiontime = level.time; - FindIntermissionPoint(); - + // move all clients to the intermission point + for (i=0 ; i< level.maxclients ; i++) { + client = g_entities + i; + if (!client->inuse) + continue; + // respawn if dead + if (client->health <= 0) { + ClientRespawn(client); + } + MoveClientToIntermission( client ); + } #ifdef MISSIONPACK if (g_singlePlayer.integer) { trap_Cvar_Set("ui_singlePlayerActive", "0"); @@ -1015,19 +1022,6 @@ void BeginIntermission( void ) { SpawnModelsOnVictoryPads(); } #endif - - // move all clients to the intermission point - for (i=0 ; i< level.maxclients ; i++) { - client = g_entities + i; - if (!client->inuse) - continue; - // respawn if dead - if (client->health <= 0) { - respawn(client); - } - MoveClientToIntermission( client ); - } - // send the current scoring to all clients SendScoreboardMessageToAllClients(); diff --git a/code/game/g_misc.c b/code/game/g_misc.c index b736cfd5..4a16d33f 100644 --- a/code/game/g_misc.c +++ b/code/game/g_misc.c @@ -78,7 +78,9 @@ TELEPORTERS void TeleportPlayer( gentity_t *player, vec3_t origin, vec3_t angles ) { gentity_t *tent; + qboolean noAngles; + noAngles = (angles[0] > 999999.0); // use temp events at source and destination to prevent the effect // from getting dropped by a second player event if ( player->client->sess.sessionTeam != TEAM_SPECTATOR ) { @@ -94,19 +96,17 @@ void TeleportPlayer( gentity_t *player, vec3_t origin, vec3_t angles ) { VectorCopy ( origin, player->client->ps.origin ); player->client->ps.origin[2] += 1; - + if (!noAngles) { // spit the player out AngleVectors( angles, player->client->ps.velocity, NULL, NULL ); VectorScale( player->client->ps.velocity, 400, player->client->ps.velocity ); player->client->ps.pm_time = 160; // hold time player->client->ps.pm_flags |= PMF_TIME_KNOCKBACK; - + // set angles + SetClientViewAngle(player, angles); + } // toggle the teleport bit so the client knows to not lerp player->client->ps.eFlags ^= EF_TELEPORT_BIT; - - // set angles - SetClientViewAngle( player, angles ); - // kill anything at the destination if ( player->client->sess.sessionTeam != TEAM_SPECTATOR ) { G_KillBox (player); diff --git a/code/game/g_mover.c b/code/game/g_mover.c index 8cc46f12..e124e2d4 100644 --- a/code/game/g_mover.c +++ b/code/game/g_mover.c @@ -829,26 +829,26 @@ Touch_DoorTriggerSpectator ================ */ static void Touch_DoorTriggerSpectator( gentity_t *ent, gentity_t *other, trace_t *trace ) { - int i, axis; - vec3_t origin, dir, angles; + int axis; + float doorMin, doorMax; + vec3_t origin; axis = ent->count; - VectorClear(dir); - if (fabs(other->s.origin[axis] - ent->r.absmax[axis]) < - fabs(other->s.origin[axis] - ent->r.absmin[axis])) { - origin[axis] = ent->r.absmin[axis] - 10; - dir[axis] = -1; + // the constants below relate to constants in Think_SpawnNewDoorTrigger() + doorMin = ent->r.absmin[axis] + 100; + doorMax = ent->r.absmax[axis] - 100; + + VectorCopy(other->client->ps.origin, origin); + + if (origin[axis] < doorMin || origin[axis] > doorMax) return; + + if (fabs(origin[axis] - doorMax) < fabs(origin[axis] - doorMin)) { + origin[axis] = doorMin - 10; + } else { + origin[axis] = doorMax + 10; } - else { - origin[axis] = ent->r.absmax[axis] + 10; - dir[axis] = 1; - } - for (i = 0; i < 3; i++) { - if (i == axis) continue; - origin[i] = (ent->r.absmin[i] + ent->r.absmax[i]) * 0.5; - } - vectoangles(dir, angles); - TeleportPlayer(other, origin, angles ); + + TeleportPlayer(other, origin, tv(10000000.0, 0, 0)); } /* diff --git a/code/game/g_spawn.c b/code/game/g_spawn.c index d6370fd5..9d05cc5e 100644 --- a/code/game/g_spawn.c +++ b/code/game/g_spawn.c @@ -485,7 +485,7 @@ char *G_AddSpawnVarToken( const char *string ) { l = strlen( string ); if ( level.numSpawnVarChars + l + 1 > MAX_SPAWN_VARS_CHARS ) { - G_Error( "G_AddSpawnVarToken: MAX_SPAWN_CHARS" ); + G_Error( "G_AddSpawnVarToken: MAX_SPAWN_VARS" ); } dest = level.spawnVarChars + level.numSpawnVarChars; diff --git a/code/game/g_team.c b/code/game/g_team.c index 9abcc740..c68263ea 100644 --- a/code/game/g_team.c +++ b/code/game/g_team.c @@ -782,7 +782,8 @@ int Team_TouchOurFlag( gentity_t *ent, gentity_t *other, int team ) { player->client->ps.eFlags |= EF_AWARD_ASSIST; player->client->rewardTime = level.time + REWARD_SPRITE_TIME; - } else if (player->client->pers.teamState.lastfraggedcarrier + + } + if (player->client->pers.teamState.lastfraggedcarrier + CTF_FRAG_CARRIER_ASSIST_TIMEOUT > level.time) { AddScore(player, ent->r.currentOrigin, CTF_FRAG_CARRIER_ASSIST_BONUS); other->client->pers.teamState.assists++; diff --git a/code/game/g_weapon.c b/code/game/g_weapon.c index 6913adf7..458a9697 100644 --- a/code/game/g_weapon.c +++ b/code/game/g_weapon.c @@ -85,8 +85,15 @@ qboolean CheckGauntletAttack( gentity_t *ent ) { return qfalse; } + if ( ent->client->noclip ) { + return qfalse; + } + traceEnt = &g_entities[ tr.entityNum ]; + if ( traceEnt->client->noclip ) { + return qfalse; + } // send blood impact if ( traceEnt->takedamage && traceEnt->client ) { tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT ); @@ -142,9 +149,9 @@ void SnapVectorTowards( vec3_t v, vec3_t to ) { for ( i = 0 ; i < 3 ; i++ ) { if ( to[i] <= v[i] ) { - v[i] = (int)v[i]; + v[i] = floor(v[i]); } else { - v[i] = (int)v[i] + 1; + v[i] = ceil(v[i]); } } } diff --git a/code/q3_ui/ui_gameinfo.c b/code/q3_ui/ui_gameinfo.c index d9deacd7..493d1721 100644 --- a/code/q3_ui/ui_gameinfo.c +++ b/code/q3_ui/ui_gameinfo.c @@ -148,7 +148,7 @@ static void UI_LoadArenasFromFile( char *filename ) { return; } if ( len >= MAX_ARENAS_TEXT ) { - trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_ARENAS_TEXT ) ); + trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i\n", filename, len, MAX_ARENAS_TEXT ) ); trap_FS_FCloseFile( f ); return; } @@ -337,7 +337,7 @@ static void UI_LoadBotsFromFile( char *filename ) { return; } if ( len >= MAX_BOTS_TEXT ) { - trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_BOTS_TEXT ) ); + trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i\n", filename, len, MAX_BOTS_TEXT ) ); trap_FS_FCloseFile( f ); return; } diff --git a/code/q3_ui/ui_players.c b/code/q3_ui/ui_players.c index a21d906d..28a58ccd 100644 --- a/code/q3_ui/ui_players.c +++ b/code/q3_ui/ui_players.c @@ -1045,7 +1045,7 @@ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animat } if ( i != MAX_ANIMATIONS ) { - Com_Printf( "Error parsing animation file: %s", filename ); + Com_Printf( "Error parsing animation file: %s\n", filename ); return qfalse; } diff --git a/code/q3_ui/ui_startserver.c b/code/q3_ui/ui_startserver.c index ce9080c7..e8fe7d6f 100644 --- a/code/q3_ui/ui_startserver.c +++ b/code/q3_ui/ui_startserver.c @@ -1355,7 +1355,7 @@ static void ServerOptions_MenuInit( qboolean multiplayer ) { y = 80; s_serveroptions.botSkill.generic.type = MTYPE_SPINCONTROL; s_serveroptions.botSkill.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.botSkill.generic.name = "Bot Skill: "; + s_serveroptions.botSkill.generic.name = "Bot Skill:"; s_serveroptions.botSkill.generic.x = 32 + (strlen(s_serveroptions.botSkill.generic.name) + 2 ) * SMALLCHAR_WIDTH; s_serveroptions.botSkill.generic.y = y; s_serveroptions.botSkill.itemnames = botSkill_list; diff --git a/code/ui/ui_gameinfo.c b/code/ui/ui_gameinfo.c index bcb2622e..b4c5cfff 100644 --- a/code/ui/ui_gameinfo.c +++ b/code/ui/ui_gameinfo.c @@ -115,7 +115,7 @@ static void UI_LoadArenasFromFile( char *filename ) { return; } if ( len >= MAX_ARENAS_TEXT ) { - trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_ARENAS_TEXT ) ); + trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i\n", filename, len, MAX_ARENAS_TEXT ) ); trap_FS_FCloseFile( f ); return; } @@ -226,7 +226,7 @@ static void UI_LoadBotsFromFile( char *filename ) { return; } if ( len >= MAX_BOTS_TEXT ) { - trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_BOTS_TEXT ) ); + trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i\n", filename, len, MAX_BOTS_TEXT ) ); trap_FS_FCloseFile( f ); return; } diff --git a/code/ui/ui_main.c b/code/ui/ui_main.c index a1c69627..26adcc75 100644 --- a/code/ui/ui_main.c +++ b/code/ui/ui_main.c @@ -655,7 +655,7 @@ char *GetMenuBuffer(const char *filename) { return defaultMenu; } if ( len >= MAX_MENUFILE ) { - trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, MAX_MENUFILE ) ); + trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i\n", filename, len, MAX_MENUFILE ) ); trap_FS_FCloseFile( f ); return defaultMenu; } diff --git a/code/ui/ui_players.c b/code/ui/ui_players.c index 59a339c2..0f11c5ae 100644 --- a/code/ui/ui_players.c +++ b/code/ui/ui_players.c @@ -1132,7 +1132,7 @@ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animat } if ( i != MAX_ANIMATIONS ) { - Com_Printf( "Error parsing animation file: %s", filename ); + Com_Printf( "Error parsing animation file: %s\n", filename ); return qfalse; }