diff --git a/reaction/game/ai_chat.c b/reaction/game/ai_chat.c index d162e848..8b805e20 100644 --- a/reaction/game/ai_chat.c +++ b/reaction/game/ai_chat.c @@ -37,9 +37,9 @@ #include "match.h" //string matching types and vars // for the voice chats - -//Blaze: was there a extra ../ here? -#include "../ui/menudef.h" +#ifdef MISSIONPACK // bk001205 +#include "../../ui/menudef.h" +#endif #define TIME_BETWEENCHATTING 25 diff --git a/reaction/game/ai_dmnet.c b/reaction/game/ai_dmnet.c index 084426f1..e1a17c9d 100644 --- a/reaction/game/ai_dmnet.c +++ b/reaction/game/ai_dmnet.c @@ -83,11 +83,11 @@ void BotDumpNodeSwitches(bot_state_t *bs) { BotRecordNodeSwitch ================== */ -void BotRecordNodeSwitch(bot_state_t *bs, char *node, char *str) { +void BotRecordNodeSwitch(bot_state_t *bs, char *node, char *str, char *s) { char netname[MAX_NETNAME]; ClientName(bs->client, netname, sizeof(netname)); - Com_sprintf(nodeswitch[numnodeswitches], 144, "%s at %2.1f entered %s: %s\n", netname, FloatTime(), node, str); + Com_sprintf(nodeswitch[numnodeswitches], 144, "%s at %2.1f entered %s: %s from %s\n", netname, FloatTime(), node, str, s); #ifdef DEBUG if (0) { BotAI_Print(PRT_MESSAGE, nodeswitch[numnodeswitches]); @@ -201,7 +201,7 @@ int BotNearbyGoal(bot_state_t *bs, int tfl, bot_goal_t *ltg, float range) { trap_BotGoalName(goal.number, buf, sizeof(buf)); BotAI_Print(PRT_MESSAGE, "%1.1f: new nearby goal %s\n", FloatTime(), buf); } - //*/ + */ return ret; } @@ -288,7 +288,7 @@ int BotGetItemLongTermGoal(bot_state_t *bs, int tfl, bot_goal_t *goal) { trap_BotGetTopGoal(bs->gs, goal); trap_BotGoalName(goal->number, buf, sizeof(buf)); BotAI_Print(PRT_MESSAGE, "%1.1f: new long term goal %s\n", FloatTime(), buf); - //*/ + */ bs->ltg_time = FloatTime() + 20; } else {//the bot gets sorta stuck with all the avoid timings, shouldn't happen though @@ -474,7 +474,7 @@ int BotGetLongTermGoal(bot_state_t *bs, int tfl, int retreat, bot_goal_t *goal) //BotAI_Print(PRT_MESSAGE, "new nearby goal %s\n", buf); //time the bot gets to pick up the nearby goal item bs->nbg_time = FloatTime() + 8; - AIEnter_Seek_NBG(bs); + AIEnter_Seek_NBG(bs, "BotLongTermGoal: go for air"); return qfalse; } // @@ -1115,8 +1115,8 @@ int BotLongTermGoal(bot_state_t *bs, int tfl, int retreat, bot_goal_t *goal) { AIEnter_Intermission ================== */ -void AIEnter_Intermission(bot_state_t *bs) { - BotRecordNodeSwitch(bs, "intermission", ""); +void AIEnter_Intermission(bot_state_t *bs, char *s) { + BotRecordNodeSwitch(bs, "intermission", "", s); //reset the bot state BotResetState(bs); //check for end level chat @@ -1140,7 +1140,7 @@ int AINode_Intermission(bot_state_t *bs) { else { bs->stand_time = FloatTime() + 2; } - AIEnter_Stand(bs); + AIEnter_Stand(bs, "intermission: chat"); } return qtrue; } @@ -1150,8 +1150,8 @@ int AINode_Intermission(bot_state_t *bs) { AIEnter_Observer ================== */ -void AIEnter_Observer(bot_state_t *bs) { - BotRecordNodeSwitch(bs, "observer", ""); +void AIEnter_Observer(bot_state_t *bs, char *s) { + BotRecordNodeSwitch(bs, "observer", "", s); //reset the bot state BotResetState(bs); bs->ainode = AINode_Observer; @@ -1165,7 +1165,7 @@ AINode_Observer int AINode_Observer(bot_state_t *bs) { //if the bot left observer mode if (!BotIsObserver(bs)) { - AIEnter_Stand(bs); + AIEnter_Stand(bs, "observer: left observer"); } return qtrue; } @@ -1175,8 +1175,8 @@ int AINode_Observer(bot_state_t *bs) { AIEnter_Stand ================== */ -void AIEnter_Stand(bot_state_t *bs) { - BotRecordNodeSwitch(bs, "stand", ""); +void AIEnter_Stand(bot_state_t *bs, char *s) { + BotRecordNodeSwitch(bs, "stand", "", s); bs->standfindenemy_time = FloatTime() + 1; bs->ainode = AINode_Stand; } @@ -1197,7 +1197,7 @@ int AINode_Stand(bot_state_t *bs) { } if (bs->standfindenemy_time < FloatTime()) { if (BotFindEnemy(bs, -1)) { - AIEnter_Battle_Fight(bs); + AIEnter_Battle_Fight(bs, "stand: found enemy"); return qfalse; } bs->standfindenemy_time = FloatTime() + 1; @@ -1207,7 +1207,7 @@ int AINode_Stand(bot_state_t *bs) { // when done standing if (bs->stand_time < FloatTime()) { trap_BotEnterChat(bs->cs, 0, bs->chatto); - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "stand: time out"); return qfalse; } // @@ -1219,8 +1219,8 @@ int AINode_Stand(bot_state_t *bs) { AIEnter_Respawn ================== */ -void AIEnter_Respawn(bot_state_t *bs) { - BotRecordNodeSwitch(bs, "respawn", ""); +void AIEnter_Respawn(bot_state_t *bs, char *s) { + BotRecordNodeSwitch(bs, "respawn", "", s); //reset some states trap_BotResetMoveState(bs->ms); trap_BotResetGoalState(bs->gs); @@ -1249,7 +1249,7 @@ int AINode_Respawn(bot_state_t *bs) { // if waiting for the actual respawn if (bs->respawn_wait) { if (!BotIsDead(bs)) { - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "respawn: respawned"); } else { trap_EA_Respawn(bs->client); @@ -1418,8 +1418,8 @@ void BotClearPath(bot_state_t *bs, bot_moveresult_t *moveresult) { AIEnter_Seek_ActivateEntity ================== */ -void AIEnter_Seek_ActivateEntity(bot_state_t *bs) { - BotRecordNodeSwitch(bs, "activate entity", ""); +void AIEnter_Seek_ActivateEntity(bot_state_t *bs, char *s) { + BotRecordNodeSwitch(bs, "activate entity", "", s); bs->ainode = AINode_Seek_ActivateEntity; } @@ -1438,19 +1438,19 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) { if (BotIsObserver(bs)) { BotClearActivateGoalStack(bs); - AIEnter_Observer(bs); + AIEnter_Observer(bs, "active entity: observer"); return qfalse; } //if in the intermission if (BotIntermission(bs)) { BotClearActivateGoalStack(bs); - AIEnter_Intermission(bs); + AIEnter_Intermission(bs, "activate entity: intermission"); return qfalse; } //respawn if dead if (BotIsDead(bs)) { BotClearActivateGoalStack(bs); - AIEnter_Respawn(bs); + AIEnter_Respawn(bs, "activate entity: bot dead"); return qfalse; } // @@ -1465,7 +1465,7 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) { // if the bot has no activate goal if (!bs->activatestack) { BotClearActivateGoalStack(bs); - AIEnter_Seek_NBG(bs); + AIEnter_Seek_NBG(bs, "activate entity: no goal"); return qfalse; } // @@ -1509,7 +1509,7 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) { bs->activatestack->time = FloatTime() + 10; return qfalse; } - AIEnter_Seek_NBG(bs); + AIEnter_Seek_NBG(bs, "activate entity: time out"); return qfalse; } memset(&moveresult, 0, sizeof(bot_moveresult_t)); @@ -1537,7 +1537,7 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) { bs->activatestack->time = FloatTime() + 10; return qfalse; } - AIEnter_Seek_NBG(bs); + AIEnter_Seek_NBG(bs, "activate entity: activated"); return qfalse; } //predict obstacles @@ -1609,14 +1609,14 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) { if (BotFindEnemy(bs, -1)) { if (BotWantsToRetreat(bs)) { //keep the current long term goal and retreat - AIEnter_Battle_NBG(bs); + AIEnter_Battle_NBG(bs, "activate entity: found enemy"); } else { trap_BotResetLastAvoidReach(bs->ms); //empty the goal stack trap_BotEmptyGoalStack(bs->gs); //go fight - AIEnter_Battle_Fight(bs); + AIEnter_Battle_Fight(bs, "activate entity: found enemy"); } BotClearActivateGoalStack(bs); } @@ -1628,16 +1628,16 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) { AIEnter_Seek_NBG ================== */ -void AIEnter_Seek_NBG(bot_state_t *bs) { +void AIEnter_Seek_NBG(bot_state_t *bs, char *s) { bot_goal_t goal; char buf[144]; if (trap_BotGetTopGoal(bs->gs, &goal)) { trap_BotGoalName(goal.number, buf, 144); - BotRecordNodeSwitch(bs, "seek NBG", buf); + BotRecordNodeSwitch(bs, "seek NBG", buf, s); } else { - BotRecordNodeSwitch(bs, "seek NBG", "no goal"); + BotRecordNodeSwitch(bs, "seek NBG", "no goal", s); } bs->ainode = AINode_Seek_NBG; } @@ -1653,17 +1653,17 @@ int AINode_Seek_NBG(bot_state_t *bs) { bot_moveresult_t moveresult; if (BotIsObserver(bs)) { - AIEnter_Observer(bs); + AIEnter_Observer(bs, "seek nbg: observer"); return qfalse; } //if in the intermission if (BotIntermission(bs)) { - AIEnter_Intermission(bs); + AIEnter_Intermission(bs, "seek nbg: intermision"); return qfalse; } //respawn if dead if (BotIsDead(bs)) { - AIEnter_Respawn(bs); + AIEnter_Respawn(bs, "seek nbg: bot dead"); return qfalse; } // @@ -1694,7 +1694,7 @@ int AINode_Seek_NBG(bot_state_t *bs) { //NOTE: we canNOT reset the check_time to zero because it would create an endless loop of node switches bs->check_time = FloatTime() + 0.05; //go back to seek ltg - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "seek nbg: time out"); return qfalse; } //predict obstacles @@ -1743,14 +1743,14 @@ int AINode_Seek_NBG(bot_state_t *bs) { if (BotFindEnemy(bs, -1)) { if (BotWantsToRetreat(bs)) { //keep the current long term goal and retreat - AIEnter_Battle_NBG(bs); + AIEnter_Battle_NBG(bs, "seek nbg: found enemy"); } else { trap_BotResetLastAvoidReach(bs->ms); //empty the goal stack trap_BotEmptyGoalStack(bs->gs); //go fight - AIEnter_Battle_Fight(bs); + AIEnter_Battle_Fight(bs, "seek nbg: found enemy"); } } return qtrue; @@ -1761,16 +1761,16 @@ int AINode_Seek_NBG(bot_state_t *bs) { AIEnter_Seek_LTG ================== */ -void AIEnter_Seek_LTG(bot_state_t *bs) { +void AIEnter_Seek_LTG(bot_state_t *bs, char *s) { bot_goal_t goal; char buf[144]; if (trap_BotGetTopGoal(bs->gs, &goal)) { trap_BotGoalName(goal.number, buf, 144); - BotRecordNodeSwitch(bs, "seek LTG", buf); + BotRecordNodeSwitch(bs, "seek LTG", buf, s); } else { - BotRecordNodeSwitch(bs, "seek LTG", "no goal"); + BotRecordNodeSwitch(bs, "seek LTG", "no goal", s); } bs->ainode = AINode_Seek_LTG; } @@ -1790,23 +1790,23 @@ int AINode_Seek_LTG(bot_state_t *bs) //bot_goal_t tmpgoal; if (BotIsObserver(bs)) { - AIEnter_Observer(bs); + AIEnter_Observer(bs, "seek ltg: observer"); return qfalse; } //if in the intermission if (BotIntermission(bs)) { - AIEnter_Intermission(bs); + AIEnter_Intermission(bs, "seek ltg: intermission"); return qfalse; } //respawn if dead if (BotIsDead(bs)) { - AIEnter_Respawn(bs); + AIEnter_Respawn(bs, "seek ltg: bot dead"); return qfalse; } // if (BotChat_Random(bs)) { bs->stand_time = FloatTime() + BotChatTime(bs); - AIEnter_Stand(bs); + AIEnter_Stand(bs, "seek ltg: random chat"); return qfalse; } // @@ -1832,7 +1832,7 @@ int AINode_Seek_LTG(bot_state_t *bs) if (BotFindEnemy(bs, -1)) { if (BotWantsToRetreat(bs)) { //keep the current long term goal and retreat - AIEnter_Battle_Retreat(bs); + AIEnter_Battle_Retreat(bs, "seek ltg: found enemy"); return qfalse; } else { @@ -1840,7 +1840,7 @@ int AINode_Seek_LTG(bot_state_t *bs) //empty the goal stack trap_BotEmptyGoalStack(bs->gs); //go fight - AIEnter_Battle_Fight(bs); + AIEnter_Battle_Fight(bs, "seek ltg: found enemy"); return qfalse; } } @@ -1885,7 +1885,7 @@ int AINode_Seek_LTG(bot_state_t *bs) //BotAI_Print(PRT_MESSAGE, "new nearby goal %s\n", buf); //time the bot gets to pick up the nearby goal item bs->nbg_time = FloatTime() + 4 + range * 0.01; - AIEnter_Seek_NBG(bs); + AIEnter_Seek_NBG(bs, "ltg seek: nbg"); return qfalse; } } @@ -1948,8 +1948,8 @@ int AINode_Seek_LTG(bot_state_t *bs) AIEnter_Battle_Fight ================== */ -void AIEnter_Battle_Fight(bot_state_t *bs) { - BotRecordNodeSwitch(bs, "battle fight", ""); +void AIEnter_Battle_Fight(bot_state_t *bs, char *s) { + BotRecordNodeSwitch(bs, "battle fight", "", s); trap_BotResetLastAvoidReach(bs->ms); bs->ainode = AINode_Battle_Fight; } @@ -1959,8 +1959,8 @@ void AIEnter_Battle_Fight(bot_state_t *bs) { AIEnter_Battle_Fight ================== */ -void AIEnter_Battle_SuicidalFight(bot_state_t *bs) { - BotRecordNodeSwitch(bs, "battle fight", ""); +void AIEnter_Battle_SuicidalFight(bot_state_t *bs, char *s) { + BotRecordNodeSwitch(bs, "battle fight", "", s); trap_BotResetLastAvoidReach(bs->ms); bs->ainode = AINode_Battle_Fight; bs->flags |= BFL_FIGHTSUICIDAL; @@ -1978,18 +1978,18 @@ int AINode_Battle_Fight(bot_state_t *bs) { bot_moveresult_t moveresult; if (BotIsObserver(bs)) { - AIEnter_Observer(bs); + AIEnter_Observer(bs, "battle fight: observer"); return qfalse; } //if in the intermission if (BotIntermission(bs)) { - AIEnter_Intermission(bs); + AIEnter_Intermission(bs, "battle fight: intermission"); return qfalse; } //respawn if dead if (BotIsDead(bs)) { - AIEnter_Respawn(bs); + AIEnter_Respawn(bs, "battle fight: bot dead"); return qfalse; } //if there is another better enemy @@ -2000,7 +2000,7 @@ int AINode_Battle_Fight(bot_state_t *bs) { } //if no enemy if (bs->enemy < 0) { - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "battle fight: no enemy"); return qfalse; } // @@ -2014,11 +2014,11 @@ int AINode_Battle_Fight(bot_state_t *bs) { } if (bs->lastkilledplayer == bs->enemy && BotChat_Kill(bs)) { bs->stand_time = FloatTime() + BotChatTime(bs); - AIEnter_Stand(bs); + AIEnter_Stand(bs, "battle fight: enemy dead"); } else { bs->ltg_time = 0; - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "battle fight: enemy dead"); } return qfalse; } @@ -2031,7 +2031,7 @@ int AINode_Battle_Fight(bot_state_t *bs) { //if the enemy is invisible and not shooting the bot looses track easily if (EntityIsInvisible(&entinfo) && !EntityIsShooting(&entinfo)) { if (random() < 0.2) { - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "battle fight: invisible"); return qfalse; } } @@ -2059,7 +2059,7 @@ int AINode_Battle_Fight(bot_state_t *bs) { if (bs->lastframe_health > bs->inventory[INVENTORY_HEALTH]) { if (BotChat_HitNoDeath(bs)) { bs->stand_time = FloatTime() + BotChatTime(bs); - AIEnter_Stand(bs); + AIEnter_Stand(bs, "battle fight: chat health decreased"); return qfalse; } } @@ -2067,18 +2067,18 @@ int AINode_Battle_Fight(bot_state_t *bs) { if (bs->cur_ps.persistant[PERS_HITS] > bs->lasthitcount) { if (BotChat_HitNoKill(bs)) { bs->stand_time = FloatTime() + BotChatTime(bs); - AIEnter_Stand(bs); + AIEnter_Stand(bs, "battle fight: chat hit someone"); return qfalse; } } //if the enemy is not visible if (!BotEntityVisible(bs->entitynum, bs->eye, bs->viewangles, 360, bs->enemy)) { if (BotWantsToChase(bs)) { - AIEnter_Battle_Chase(bs); + AIEnter_Battle_Chase(bs, "battle fight: enemy out of sight"); return qfalse; } else { - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "battle fight: enemy out of sight"); return qfalse; } } @@ -2113,7 +2113,7 @@ int AINode_Battle_Fight(bot_state_t *bs) { //if the bot wants to retreat if (!(bs->flags & BFL_FIGHTSUICIDAL)) { if (BotWantsToRetreat(bs)) { - AIEnter_Battle_Retreat(bs); + AIEnter_Battle_Retreat(bs, "battle fight: wants to retreat"); return qtrue; } } @@ -2125,8 +2125,8 @@ int AINode_Battle_Fight(bot_state_t *bs) { AIEnter_Battle_Chase ================== */ -void AIEnter_Battle_Chase(bot_state_t *bs) { - BotRecordNodeSwitch(bs, "battle chase", ""); +void AIEnter_Battle_Chase(bot_state_t *bs, char *s) { + BotRecordNodeSwitch(bs, "battle chase", "", s); bs->chase_time = FloatTime(); bs->ainode = AINode_Battle_Chase; } @@ -2144,37 +2144,37 @@ int AINode_Battle_Chase(bot_state_t *bs) float range; if (BotIsObserver(bs)) { - AIEnter_Observer(bs); + AIEnter_Observer(bs, "battle chase: observer"); return qfalse; } //if in the intermission if (BotIntermission(bs)) { - AIEnter_Intermission(bs); + AIEnter_Intermission(bs, "battle chase: intermission"); return qfalse; } //respawn if dead if (BotIsDead(bs)) { - AIEnter_Respawn(bs); + AIEnter_Respawn(bs, "battle chase: bot dead"); return qfalse; } //if no enemy if (bs->enemy < 0) { - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "battle chase: no enemy"); return qfalse; } //if the enemy is visible if (BotEntityVisible(bs->entitynum, bs->eye, bs->viewangles, 360, bs->enemy)) { - AIEnter_Battle_Fight(bs); + AIEnter_Battle_Fight(bs, "battle chase"); return qfalse; } //if there is another enemy if (BotFindEnemy(bs, -1)) { - AIEnter_Battle_Fight(bs); + AIEnter_Battle_Fight(bs, "battle chase: better enemy"); return qfalse; } //there is no last enemy area if (!bs->lastenemyareanum) { - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "battle chase: no enemy area"); return qfalse; } // @@ -2198,7 +2198,7 @@ int AINode_Battle_Chase(bot_state_t *bs) if (trap_BotTouchingGoal(bs->origin, &goal)) bs->chase_time = 0; //if there's no chase time left if (!bs->chase_time || bs->chase_time < FloatTime() - 10) { - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "battle chase: time out"); return qfalse; } //check for nearby goals periodicly @@ -2210,7 +2210,7 @@ int AINode_Battle_Chase(bot_state_t *bs) //the bot gets 5 seconds to pick up the nearby goal item bs->nbg_time = FloatTime() + 0.1 * range + 1; trap_BotResetLastAvoidReach(bs->ms); - AIEnter_Battle_NBG(bs); + AIEnter_Battle_NBG(bs, "battle chase: nbg"); return qfalse; } } @@ -2254,7 +2254,7 @@ int AINode_Battle_Chase(bot_state_t *bs) if (bs->areanum == bs->lastenemyareanum) bs->chase_time = 0; //if the bot wants to retreat (the bot could have been damage during the chase) if (BotWantsToRetreat(bs)) { - AIEnter_Battle_Retreat(bs); + AIEnter_Battle_Retreat(bs, "battle chase: wants to retreat"); return qtrue; } return qtrue; @@ -2265,8 +2265,8 @@ int AINode_Battle_Chase(bot_state_t *bs) AIEnter_Battle_Retreat ================== */ -void AIEnter_Battle_Retreat(bot_state_t *bs) { - BotRecordNodeSwitch(bs, "battle retreat", ""); +void AIEnter_Battle_Retreat(bot_state_t *bs, char *s) { + BotRecordNodeSwitch(bs, "battle retreat", "", s); bs->ainode = AINode_Battle_Retreat; } @@ -2284,28 +2284,28 @@ int AINode_Battle_Retreat(bot_state_t *bs) { int areanum; if (BotIsObserver(bs)) { - AIEnter_Observer(bs); + AIEnter_Observer(bs, "battle retreat: observer"); return qfalse; } //if in the intermission if (BotIntermission(bs)) { - AIEnter_Intermission(bs); + AIEnter_Intermission(bs, "battle retreat: intermission"); return qfalse; } //respawn if dead if (BotIsDead(bs)) { - AIEnter_Respawn(bs); + AIEnter_Respawn(bs, "battle retreat: bot dead"); return qfalse; } //if no enemy if (bs->enemy < 0) { - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "battle retreat: no enemy"); return qfalse; } // BotEntityInfo(bs->enemy, &entinfo); if (EntityIsDead(&entinfo)) { - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "battle retreat: enemy dead"); return qfalse; } //if there is another better enemy @@ -2328,7 +2328,7 @@ int AINode_Battle_Retreat(bot_state_t *bs) { //empty the goal stack, when chasing, only the enemy is the goal trap_BotEmptyGoalStack(bs->gs); //go chase the enemy - AIEnter_Battle_Chase(bs); + AIEnter_Battle_Chase(bs, "battle retreat: wants to chase"); return qfalse; } //update the last time the enemy was visible @@ -2354,14 +2354,14 @@ int AINode_Battle_Retreat(bot_state_t *bs) { } //if the enemy is NOT visible for 4 seconds if (bs->enemyvisible_time < FloatTime() - 4) { - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "battle retreat: lost enemy"); return qfalse; } //else if the enemy is NOT visible else if (bs->enemyvisible_time < FloatTime()) { //if there is another enemy if (BotFindEnemy(bs, -1)) { - AIEnter_Battle_Fight(bs); + AIEnter_Battle_Fight(bs, "battle retreat: another enemy"); return qfalse; } } @@ -2371,7 +2371,7 @@ int AINode_Battle_Retreat(bot_state_t *bs) { BotBattleUseItems(bs); //get the current long term goal while retreating if (!BotLongTermGoal(bs, bs->tfl, qtrue, &goal)) { - AIEnter_Battle_SuicidalFight(bs); + AIEnter_Battle_SuicidalFight(bs, "battle retreat: no way out"); return qfalse; } //check for nearby goals periodicly @@ -2400,7 +2400,7 @@ int AINode_Battle_Retreat(bot_state_t *bs) { trap_BotResetLastAvoidReach(bs->ms); //time the bot gets to pick up the nearby goal item bs->nbg_time = FloatTime() + range / 100 + 1; - AIEnter_Battle_NBG(bs); + AIEnter_Battle_NBG(bs, "battle retreat: nbg"); return qfalse; } } @@ -2454,8 +2454,8 @@ int AINode_Battle_Retreat(bot_state_t *bs) { AIEnter_Battle_NBG ================== */ -void AIEnter_Battle_NBG(bot_state_t *bs) { - BotRecordNodeSwitch(bs, "battle NBG", ""); +void AIEnter_Battle_NBG(bot_state_t *bs, char *s) { + BotRecordNodeSwitch(bs, "battle NBG", "", s); bs->ainode = AINode_Battle_NBG; } @@ -2473,28 +2473,28 @@ int AINode_Battle_NBG(bot_state_t *bs) { vec3_t target, dir; if (BotIsObserver(bs)) { - AIEnter_Observer(bs); + AIEnter_Observer(bs, "battle nbg: observer"); return qfalse; } //if in the intermission if (BotIntermission(bs)) { - AIEnter_Intermission(bs); + AIEnter_Intermission(bs, "battle nbg: intermission"); return qfalse; } //respawn if dead if (BotIsDead(bs)) { - AIEnter_Respawn(bs); + AIEnter_Respawn(bs, "battle nbg: bot dead"); return qfalse; } //if no enemy if (bs->enemy < 0) { - AIEnter_Seek_NBG(bs); + AIEnter_Seek_NBG(bs, "battle nbg: no enemy"); return qfalse; } // BotEntityInfo(bs->enemy, &entinfo); if (EntityIsDead(&entinfo)) { - AIEnter_Seek_NBG(bs); + AIEnter_Seek_NBG(bs, "battle nbg: enemy dead"); return qfalse; } // @@ -2541,8 +2541,10 @@ int AINode_Battle_NBG(bot_state_t *bs) { //pop the current goal from the stack trap_BotPopGoal(bs->gs); //if the bot still has a goal - if (trap_BotGetTopGoal(bs->gs, &goal)) AIEnter_Battle_Retreat(bs); - else AIEnter_Battle_Fight(bs); + if (trap_BotGetTopGoal(bs->gs, &goal)) + AIEnter_Battle_Retreat(bs, "battle nbg: time out"); + else + AIEnter_Battle_Fight(bs, "battle nbg: time out"); // return qfalse; } diff --git a/reaction/game/ai_dmnet.h b/reaction/game/ai_dmnet.h index 587d52d9..c4b68313 100644 --- a/reaction/game/ai_dmnet.h +++ b/reaction/game/ai_dmnet.h @@ -16,18 +16,18 @@ #define MAX_NODESWITCHES 50 -void AIEnter_Intermission(bot_state_t *bs); -void AIEnter_Observer(bot_state_t *bs); -void AIEnter_Respawn(bot_state_t *bs); -void AIEnter_Stand(bot_state_t *bs); -void AIEnter_Seek_ActivateEntity(bot_state_t *bs); -void AIEnter_Seek_NBG(bot_state_t *bs); -void AIEnter_Seek_LTG(bot_state_t *bs); -void AIEnter_Seek_Camp(bot_state_t *bs); -void AIEnter_Battle_Fight(bot_state_t *bs); -void AIEnter_Battle_Chase(bot_state_t *bs); -void AIEnter_Battle_Retreat(bot_state_t *bs); -void AIEnter_Battle_NBG(bot_state_t *bs); +void AIEnter_Intermission(bot_state_t *bs, char *s); +void AIEnter_Observer(bot_state_t *bs, char *s); +void AIEnter_Respawn(bot_state_t *bs, char *s); +void AIEnter_Stand(bot_state_t *bs, char *s); +void AIEnter_Seek_ActivateEntity(bot_state_t *bs, char *s); +void AIEnter_Seek_NBG(bot_state_t *bs, char *s); +void AIEnter_Seek_LTG(bot_state_t *bs, char *s); +void AIEnter_Seek_Camp(bot_state_t *bs, char *s); +void AIEnter_Battle_Fight(bot_state_t *bs, char *s); +void AIEnter_Battle_Chase(bot_state_t *bs, char *s); +void AIEnter_Battle_Retreat(bot_state_t *bs, char *s); +void AIEnter_Battle_NBG(bot_state_t *bs, char *s); int AINode_Intermission(bot_state_t *bs); int AINode_Observer(bot_state_t *bs); int AINode_Respawn(bot_state_t *bs); diff --git a/reaction/game/ai_dmq3.c b/reaction/game/ai_dmq3.c index 05b1a9d9..f9a2142b 100644 --- a/reaction/game/ai_dmq3.c +++ b/reaction/game/ai_dmq3.c @@ -198,18 +198,6 @@ qboolean EntityIsDead(aas_entityinfo_t *entinfo) { return qfalse; } -/* -================== -EntityIsInvisible -================== -*/ -qboolean EntityIsInvisible(aas_entityinfo_t *entinfo) { - if (entinfo->powerups & (1 << PW_INVIS)) { - return qtrue; - } - return qfalse; -} - /* ================== EntityCarriesFlag @@ -227,6 +215,22 @@ qboolean EntityCarriesFlag(aas_entityinfo_t *entinfo) { return qfalse; } +/* +================== +EntityIsInvisible +================== +*/ +qboolean EntityIsInvisible(aas_entityinfo_t *entinfo) { + // the flag is always visible + if (EntityCarriesFlag(entinfo)) { + return qfalse; + } + if (entinfo->powerups & (1 << PW_INVIS)) { + return qtrue; + } + return qfalse; +} + /* ================== EntityIsShooting @@ -1572,7 +1576,7 @@ void BotSetupForMovement(bot_state_t *bs) { memset(&initmove, 0, sizeof(bot_initmove_t)); VectorCopy(bs->cur_ps.origin, initmove.origin); VectorCopy(bs->cur_ps.velocity, initmove.velocity); - VectorCopy(bs->cur_ps.origin, initmove.viewoffset); + VectorClear(initmove.viewoffset); initmove.viewoffset[2] += bs->cur_ps.viewheight; initmove.entitynum = bs->entitynum; initmove.client = bs->client; @@ -2953,6 +2957,7 @@ int BotFindEnemy(bot_state_t *bs, int curenemy) { bs->enemysight_time = FloatTime(); bs->enemysuicide = qfalse; bs->enemydeath_time = 0; + bs->enemyvisible_time = FloatTime(); return qtrue; } } @@ -3021,6 +3026,7 @@ int BotFindEnemy(bot_state_t *bs, int curenemy) { else bs->enemysight_time = FloatTime(); bs->enemysuicide = qfalse; bs->enemydeath_time = 0; + bs->enemyvisible_time = FloatTime(); return qtrue; } return qfalse; @@ -3593,14 +3599,14 @@ void BotCheckAttack(bot_state_t *bs) { } } // + // + VectorSubtract(bs->aimtarget, bs->eye, dir); + // if (bs->weaponnum == WP_KNIFE) { if (VectorLengthSquared(dir) > Square(60)) { return; } } - // - VectorSubtract(bs->aimtarget, bs->eye, dir); - // if (VectorLengthSquared(dir) < Square(100)) fov = 120; else @@ -3744,10 +3750,11 @@ void BotMapScripts(bot_state_t *bs) { BotSetMovedir ================== */ -vec3_t VEC_UP = {0, -1, 0}; -vec3_t MOVEDIR_UP = {0, 0, 1}; -vec3_t VEC_DOWN = {0, -2, 0}; -vec3_t MOVEDIR_DOWN = {0, 0, -1}; +// bk001205 - made these static +static vec3_t VEC_UP = {0, -1, 0}; +static vec3_t MOVEDIR_UP = {0, 0, 1}; +static vec3_t VEC_DOWN = {0, -2, 0}; +static vec3_t MOVEDIR_DOWN = {0, 0, -1}; void BotSetMovedir(vec3_t angles, vec3_t movedir) { if (VectorCompare(angles, VEC_UP)) { @@ -4147,7 +4154,7 @@ BotGetActivateGoal //#define OBSTACLEDEBUG int BotGetActivateGoal(bot_state_t *bs, int entitynum, bot_activategoal_t *activategoal) { - int i, ent, cur_entities[10], spawnflags, modelindex, areas[10], numareas, t; + int i, ent, cur_entities[10], spawnflags, modelindex, areas[MAX_ACTIVATEAREAS*2], numareas, t; char model[MAX_INFO_STRING], tmpmodel[128]; char target[128], classname[128]; float health; @@ -4201,13 +4208,29 @@ int BotGetActivateGoal(bot_state_t *bs, int entitynum, bot_activategoal_t *activ VectorClear(angles); BotModelMinsMaxs(modelindex, ET_MOVER, 0, absmins, absmaxs); // - numareas = trap_AAS_BBoxAreas(absmins, absmaxs, areas, 10); + numareas = trap_AAS_BBoxAreas(absmins, absmaxs, areas, MAX_ACTIVATEAREAS*2); + // store the areas with reachabilities first for (i = 0; i < numareas; i++) { + if (activategoal->numareas >= MAX_ACTIVATEAREAS) + break; + if ( !trap_AAS_AreaReachability(areas[i]) ) { + continue; + } trap_AAS_AreaInfo(areas[i], &areainfo); if (areainfo.contents & AREACONTENTS_MOVER) { activategoal->areas[activategoal->numareas++] = areas[i]; + } + } + // store any remaining areas + for (i = 0; i < numareas; i++) { if (activategoal->numareas >= MAX_ACTIVATEAREAS) break; + if ( trap_AAS_AreaReachability(areas[i]) ) { + continue; + } + trap_AAS_AreaInfo(areas[i], &areainfo); + if (areainfo.contents & AREACONTENTS_MOVER) { + activategoal->areas[activategoal->numareas++] = areas[i]; } } } @@ -4217,33 +4240,7 @@ int BotGetActivateGoal(bot_state_t *bs, int entitynum, bot_activategoal_t *activ if (!strcmp(classname, "func_breakable")) { return ent; } - //Blaze: This code is for bots, we will need to fix it later -/* - else if (!strcmp(classname, "func_breakable")) { - //shoot at the shootable door - trap_AAS_ValueForBSPEpairKey(ent, "model", model, sizeof(model)); - modelindex = atoi(model+1); - //if the model is not loaded - if (!modelindex) return; - VectorClear(angles); - BotModelMinsMaxs(modelindex, ET_BREAKABLE, mins, maxs); - //door origin - VectorAdd(mins, maxs, origin); - VectorScale(origin, 0.5, origin); - // - VectorSubtract(origin, bs->eye, movedir); - vectoangles(movedir, moveresult->ideal_viewangles); - moveresult->flags |= MOVERESULT_MOVEMENTVIEW; - moveresult->flags |= MOVERESULT_MOVEMENTWEAPON; - //select the machinegun and shoot - trap_EA_SelectWeapon(bs->client, WEAPONINDEX_MACHINEGUN); - if (bs->cur_ps.weapon == WEAPONINDEX_MACHINEGUN) { - trap_EA_Attack(bs->client); - } - return; - } -*/ - // if the bot is blocked by or standing on top of a button + // if the bot is blocked by or standing on top of a button if (!strcmp(classname, "func_button")) { return 0; } @@ -4362,7 +4359,7 @@ int BotGoForActivateGoal(bot_state_t *bs, bot_activategoal_t *activategoal) { // if (BotPushOntoActivateGoalStack(bs, activategoal)) { // enter the activate entity AI node - AIEnter_Seek_ActivateEntity(bs); + AIEnter_Seek_ActivateEntity(bs, "BotGoForActivateGoal"); return qtrue; } else { @@ -4693,7 +4690,7 @@ void BotCheckConsoleMessages(bot_state_t *bs) { //remove the console message trap_BotRemoveConsoleMessage(bs->cs, handle); bs->stand_time = FloatTime() + BotChatTime(bs); - AIEnter_Stand(bs); + AIEnter_Stand(bs, "BotCheckConsoleMessages: reply chat"); //EA_Say(bs->client, bs->cs.chatmessage); break; } @@ -4713,8 +4710,7 @@ BotCheckEvents */ void BotCheckForGrenades(bot_state_t *bs, entityState_t *state) { // if this is not a grenade - if (state->eType != ET_MISSILE || state->weapon != WP_GRENADE) - return; + if (state->eType != ET_MISSILE || state->weapon != WP_GRENADE) return; // try to avoid the grenade trap_BotAddAvoidSpot(bs->ms, state->pos.trBase, 160, AVOID_ALWAYS); } @@ -5268,13 +5264,13 @@ void BotDeathmatchAI(bot_state_t *bs, float thinktime) { } //if the bot has no ai node if (!bs->ainode) { - AIEnter_Seek_LTG(bs); + AIEnter_Seek_LTG(bs, "BotDeathmatchAI: no ai node"); } //if the bot entered the game less than 8 seconds ago if (!bs->entergamechat && bs->entergame_time > FloatTime() - 8) { if (BotChat_EnterGame(bs)) { bs->stand_time = FloatTime() + BotChatTime(bs); - AIEnter_Stand(bs); + AIEnter_Stand(bs, "BotDeathmatchAI: chat enter game"); } bs->entergamechat = qtrue; } diff --git a/reaction/game/ai_main.c b/reaction/game/ai_main.c index 29e1db3d..71d5d9f0 100644 --- a/reaction/game/ai_main.c +++ b/reaction/game/ai_main.c @@ -1626,11 +1626,6 @@ BotAISetup int BotAISetup( int restart ) { int errnum; -#ifdef RANDOMIZE - srand((unsigned)time(NULL)); -#endif //RANDOMIZE - - trap_Cvar_Register(&bot_thinktime, "bot_thinktime", "100", CVAR_CHEAT); trap_Cvar_Register(&bot_memorydump, "bot_memorydump", "0", CVAR_CHEAT); trap_Cvar_Register(&bot_saveroutingcache, "bot_saveroutingcache", "0", CVAR_CHEAT); diff --git a/reaction/game/ai_team.c b/reaction/game/ai_team.c index 332962b1..e14bfcbe 100644 --- a/reaction/game/ai_team.c +++ b/reaction/game/ai_team.c @@ -115,7 +115,7 @@ int BotSortTeamMatesByBaseTravelTime(bot_state_t *bs, int *teammates, int maxtea char buf[MAX_INFO_STRING]; static int maxclients; int traveltimes[MAX_CLIENTS]; - bot_goal_t *goal; + bot_goal_t *goal = NULL; if (gametype == GT_CTF || gametype == GT_1FCTF) { if (BotTeam(bs) == TEAM_RED) diff --git a/reaction/game/be_aas.h b/reaction/game/be_aas.h index 05d27d0a..ac78c592 100644 --- a/reaction/game/be_aas.h +++ b/reaction/game/be_aas.h @@ -100,7 +100,8 @@ typedef struct bsp_trace_s int contents; // contents on other side of surface hit int ent; // number of entity hit } bsp_trace_t; -//*/ +// +*/ //entity info typedef struct aas_entityinfo_s diff --git a/reaction/game/be_ai_move.h b/reaction/game/be_ai_move.h index ee63ecb6..2899b8c0 100644 --- a/reaction/game/be_ai_move.h +++ b/reaction/game/be_ai_move.h @@ -84,6 +84,15 @@ typedef struct bot_moveresult_s vec3_t ideal_viewangles; //ideal viewangles for the movement } bot_moveresult_t; +// bk001204: from code/botlib/be_ai_move.c +// TTimo 04/12/2001 was moved here to avoid dup defines +typedef struct bot_avoidspot_s +{ + vec3_t origin; + float radius; + int type; +} bot_avoidspot_t; + //resets the whole movestate void BotResetMoveState(int movestate); //moves the bot to the given goal diff --git a/reaction/game/bg_lib.c b/reaction/game/bg_lib.c index 4fd0a614..afc0192f 100644 --- a/reaction/game/bg_lib.c +++ b/reaction/game/bg_lib.c @@ -48,7 +48,11 @@ static const char rcsid[] = "$Id$"; #endif /* LIBC_SCCS and not lint */ -//typedef int cmp_t(const void *, const void *); +// bk001127 - needed for DLL's +#if !defined( Q3_VM ) +typedef int cmp_t(const void *, const void *); +#endif + static char* med3(char *, char *, char *, cmp_t *); static void swapfunc(char *, char *, int, int); @@ -191,6 +195,9 @@ loop: SWAPINIT(a, es); // this file is excluded from release builds because of intrinsics +// bk001211 - gcc errors on compiling strcpy: parse error before `__extension__' +#if defined ( Q3_VM ) + size_t strlen( const char *string ) { const char *s; @@ -263,9 +270,12 @@ char *strstr( const char *string, const char *strCharSet ) { } return (char *)0; } +#endif // bk001211 -#if !defined ( _MSC_VER ) && ! defined ( __linux__ ) - +// bk001120 - presumably needed for Mac +//#if !defined(_MSC_VER) && !defined(__linux__) +// bk001127 - undid undo +#if defined ( Q3_VM ) int tolower( int c ) { if ( c >= 'A' && c <= 'Z' ) { c += 'a' - 'A'; @@ -751,9 +761,13 @@ double atan2( double y, double x ) { #endif +#ifdef Q3_VM +// bk001127 - guarded this tan replacement +// ld: undefined versioned symbol name tan@@GLIBC_2.0 double tan( double x ) { return sin(x) / cos(x); } +#endif static int randSeed = 0; @@ -838,7 +852,7 @@ double _atof( const char **stringPtr ) { const char *string; float sign; float value; - int c; + int c = '0'; // bk001211 - uninitialized use possible string = *stringPtr; @@ -903,8 +917,11 @@ double _atof( const char **stringPtr ) { } -#if !defined( _MSC_VER ) && !defined( __linux__ ) +// bk001120 - presumably needed for Mac +//#if !defined ( _MSC_VER ) && ! defined ( __linux__ ) +// bk001127 - undid undo +#if defined ( Q3_VM ) int atoi( const char *string ) { int sign; int value; diff --git a/reaction/game/bg_misc.c b/reaction/game/bg_misc.c index b6531fbe..815d41b1 100644 --- a/reaction/game/bg_misc.c +++ b/reaction/game/bg_misc.c @@ -1171,6 +1171,13 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play case IT_BAD: Com_Error( ERR_DROP, "BG_CanItemBeGrabbed: IT_BAD" ); + default: +#ifndef Q3_VM +#ifndef NDEBUG // bk0001204 + Com_Printf("BG_CanItemBeGrabbed: unknown enum %d\n", item->giType ); +#endif +#endif + break; } return qfalse; @@ -1505,18 +1512,16 @@ void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean if ( ps->externalEvent ) { s->event = ps->externalEvent; s->eventParm = ps->externalEventParm; - } else { + } else if ( ps->entityEventSequence < ps->eventSequence ) { int seq; if ( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS) { ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS; } - seq = (ps->entityEventSequence-1) & (MAX_PS_EVENTS-1); + seq = ps->entityEventSequence & (MAX_PS_EVENTS-1); s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 ); s->eventParm = ps->eventParms[ seq ]; - if ( ps->entityEventSequence < ps->eventSequence ) { - ps->entityEventSequence++; - } + ps->entityEventSequence++; } s->weapon = ps->weapon; @@ -1587,18 +1592,16 @@ void BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s if ( ps->externalEvent ) { s->event = ps->externalEvent; s->eventParm = ps->externalEventParm; - } else { + } else if ( ps->entityEventSequence < ps->eventSequence ) { int seq; if ( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS) { ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS; } - seq = (ps->entityEventSequence-1) & (MAX_PS_EVENTS-1); + seq = ps->entityEventSequence & (MAX_PS_EVENTS-1); s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 ); s->eventParm = ps->eventParms[ seq ]; - if ( ps->entityEventSequence < ps->eventSequence ) { - ps->entityEventSequence++; - } + ps->entityEventSequence++; } s->weapon = ps->weapon; diff --git a/reaction/game/bg_pmove.c b/reaction/game/bg_pmove.c index 954daf33..aa8cd780 100644 --- a/reaction/game/bg_pmove.c +++ b/reaction/game/bg_pmove.c @@ -202,6 +202,7 @@ void PM_ClipVelocity( vec3_t in, vec3_t normal, vec3_t out, float overbounce ) { float backoff; float change; int i; + backoff = DotProduct (in, normal); if ( backoff < 0 ) { diff --git a/reaction/game/bg_public.h b/reaction/game/bg_public.h index 2223f54b..7b61a12e 100644 --- a/reaction/game/bg_public.h +++ b/reaction/game/bg_public.h @@ -321,8 +321,9 @@ typedef enum { #define CS_SOUNDS (CS_MODELS+MAX_MODELS) #define CS_PLAYERS (CS_SOUNDS+MAX_SOUNDS) #define CS_LOCATIONS (CS_PLAYERS+MAX_CLIENTS) +#define CS_PARTICLES (CS_LOCATIONS+MAX_LOCATIONS) -#define CS_MAX (CS_LOCATIONS+MAX_LOCATIONS) +#define CS_MAX (CS_PARTICLES+MAX_LOCATIONS) #if (CS_MAX) > MAX_CONFIGSTRINGS #error overflow: (CS_MAX) > MAX_CONFIGSTRINGS @@ -434,7 +435,9 @@ typedef struct { // callbacks to test the world // these will be different functions during game and cgame + //void (*trace)( trace_t *results, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, int passEntityNum, int contentMask ); void (*trace)( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentMask ); + int (*pointcontents)( const vec3_t point, int passEntityNum ); } pmove_t; @@ -521,6 +524,7 @@ typedef enum { #endif #define EF_TELEPORT_BIT 0x00000004 // toggled every time the origin abruptly changes #define EF_AWARD_EXCELLENT 0x00000008 // draw an excellent sprite +#define EF_PLAYER_EVENT 0x00000010 #define EF_BOUNCE 0x00000010 // for missiles #define EF_BOUNCE_HALF 0x00000020 // for missiles #define EF_AWARD_GAUNTLET 0x00000040 // draw a gauntlet sprite @@ -632,6 +636,8 @@ int ClipAmountForAmmo( int w ); #define EV_EVENT_BIT2 0x00000200 #define EV_EVENT_BITS (EV_EVENT_BIT1|EV_EVENT_BIT2) +#define EVENT_VALID_MSEC 300 + typedef enum { EV_NONE, @@ -813,14 +819,12 @@ typedef enum { //Blaze: Weapon reload animation // WEAPON_RELOAD, -#ifdef NEW_ANIMS TORSO_GETFLAG, TORSO_GUARDBASE, TORSO_PATROL, TORSO_FOLLOWME, TORSO_AFFIRMATIVE, TORSO_NEGATIVE, -#endif MAX_ANIMATIONS, diff --git a/reaction/game/bg_slidemove.c b/reaction/game/bg_slidemove.c index 26002b1b..dcd080ba 100644 --- a/reaction/game/bg_slidemove.c +++ b/reaction/game/bg_slidemove.c @@ -223,6 +223,7 @@ void PM_StepSlideMove( qboolean gravity ) { // float down_dist, up_dist; // vec3_t delta, delta2; vec3_t up, down; + float stepSize; VectorCopy (pm->ps->origin, start_o); VectorCopy (pm->ps->velocity, start_v); @@ -252,7 +253,7 @@ void PM_StepSlideMove( qboolean gravity ) { up[2] += STEPSIZE; // test the player position if they were a stepheight higher - pm->trace (&trace, up, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask); + pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask); if ( trace.allsolid ) { if ( pm->debugLevel ) { Com_Printf("%i:bend can't step\n", c_pmove); @@ -260,21 +261,21 @@ void PM_StepSlideMove( qboolean gravity ) { return; // can't step up } + stepSize = trace.endpos[2] - start_o[2]; // try slidemove from this position - VectorCopy (up, pm->ps->origin); + VectorCopy (trace.endpos, pm->ps->origin); VectorCopy (start_v, pm->ps->velocity); PM_SlideMove( gravity ); // push down the final amount VectorCopy (pm->ps->origin, down); - down[2] -= STEPSIZE; + down[2] -= stepSize; pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask); if ( !trace.allsolid ) { VectorCopy (trace.endpos, pm->ps->origin); } if ( trace.fraction < 1.0 ) { -//Blaze: Ramp jump test PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP ); } diff --git a/reaction/game/g_active.c b/reaction/game/g_active.c index e9ecfde6..7771eaab 100644 --- a/reaction/game/g_active.c +++ b/reaction/game/g_active.c @@ -807,6 +807,7 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) { } +#ifdef MISSIONPACK /* ============== StuckInOtherClient @@ -847,7 +848,9 @@ static int StuckInOtherClient(gentity_t *ent) { } return qfalse; } +#endif +void BotTestSolid(vec3_t origin); /* ============= ThrowWeapon @@ -918,7 +921,7 @@ void ThrowWeapon( gentity_t *ent ) } /* -============= +============== ThrowItem Used to toss an item much like weapons except a bit leaner @@ -965,7 +968,42 @@ void ThrowItem( gentity_t *ent ) //Elder: wtf? -void BotTestSolid(vec3_t origin); + + +/* +============== +SendPendingPredictableEvents +============== +*/ +void SendPendingPredictableEvents( playerState_t *ps ) { + gentity_t *t; + int event, seq; + int extEvent, number; + + // if there are still events pending + if ( ps->entityEventSequence < ps->eventSequence ) { + // create a temporary entity for this event which is sent to everyone + // except the client who generated the event + seq = ps->entityEventSequence & (MAX_PS_EVENTS-1); + event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 ); + // set external event to zero before calling BG_PlayerStateToEntityState + extEvent = ps->externalEvent; + ps->externalEvent = 0; + // create temporary entity for event + t = G_TempEntity( ps->origin, event ); + number = t->s.number; + BG_PlayerStateToEntityState( ps, &t->s, qtrue ); + t->s.number = number; + t->s.eType = ET_EVENTS + event; + t->s.eFlags |= EF_PLAYER_EVENT; + t->s.otherEntityNum = ps->clientNum; + // send to everyone except the client who generated the event + t->r.svFlags |= SVF_NOTSINGLECLIENT; + t->r.singleClient = ps->clientNum; + // set back external event + ps->externalEvent = extEvent; + } +} /* ============== @@ -1066,11 +1104,7 @@ void ClientThink_real( gentity_t *ent ) { client->ps.gravity = g_gravity.value; // set speed -//Blaze: Where did this come from -/* if(client->legDamage < g_speed.value) - client->ps.speed = g_speed.value - client->legDamage; - else*/ - client->ps.speed = g_speed.value; + client->ps.speed = g_speed.value; #ifdef MISSIONPACK if( bg_itemlist[client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_SCOUT ) { @@ -1082,7 +1116,6 @@ void ClientThink_real( gentity_t *ent ) { client->ps.speed *= 1.3; } - // Let go of the hook if we aren't firing //Blaze: No Hook in reaction /* @@ -1242,6 +1275,8 @@ void ClientThink_real( gentity_t *ent ) { else { BG_PlayerStateToEntityState( &ent->client->ps, &ent->s, qtrue ); } + SendPendingPredictableEvents( &ent->client->ps ); + if ( !( ent->client->ps.eFlags & EF_FIRING ) ) { client->fireHeld = qfalse; // for grapple } @@ -1371,6 +1406,7 @@ void ClientThink_real( gentity_t *ent ) { return; } + // perform once-a-second actions ClientTimerActions( ent, msec ); } @@ -1464,9 +1500,7 @@ while a slow client may have multiple ClientEndFrame between ClientThink. void ClientEndFrame( gentity_t *ent ) { int i; clientPersistant_t *pers; -// gitem_t *rq3_item; -// gentity_t *rq3_temp; - //vec3_t spawn_origin, spawn_angles; + if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) { SpectatorClientEndFrame( ent ); return; @@ -1591,6 +1625,7 @@ void ClientEndFrame( gentity_t *ent ) { else { BG_PlayerStateToEntityState( &ent->client->ps, &ent->s, qtrue ); } + SendPendingPredictableEvents( &ent->client->ps ); // set the bit for the reachability area the client is currently in // i = trap_AAS_PointReachabilityAreaIndex( ent->client->ps.origin ); diff --git a/reaction/game/g_arenas.c b/reaction/game/g_arenas.c index c4ee7ddd..dd7c80e3 100644 --- a/reaction/game/g_arenas.c +++ b/reaction/game/g_arenas.c @@ -23,6 +23,10 @@ void UpdateTournamentInfo( void ) { int playerClientNum; int n, accuracy, perfect, msglen; int buflen; +#ifdef MISSIONPACK // bk001205 + int score1, score2; + qboolean won; +#endif char buf[32]; char msg[MAX_STRING_CHARS]; diff --git a/reaction/game/g_bot.c b/reaction/game/g_bot.c index 2c9e4469..6c085791 100644 --- a/reaction/game/g_bot.c +++ b/reaction/game/g_bot.c @@ -23,7 +23,7 @@ typedef struct { int spawnTime; } botSpawnQueue_t; -static int botBeginDelay; +//static int botBeginDelay = 0; // bk001206 - unused, init static botSpawnQueue_t botSpawnQueue[BOT_SPAWN_QUEUE_DEPTH]; vmCvar_t bot_minplayers; @@ -612,13 +612,20 @@ static void G_AddBot( const char *name, float skill, const char *team, int delay } Info_SetValueForKey( userinfo, "sex", s ); - key = "color"; + key = "color1"; s = Info_ValueForKey( botinfo, key ); if ( !*s ) { s = "4"; } Info_SetValueForKey( userinfo, key, s ); + key = "color2"; + s = Info_ValueForKey( botinfo, key ); + if ( !*s ) { + s = "5"; + } + Info_SetValueForKey( userinfo, key, s ); + s = Info_ValueForKey(botinfo, "aifile"); if (!*s ) { trap_Printf( S_COLOR_RED "Error: bot has no aifile specified\n" ); @@ -648,7 +655,7 @@ static void G_AddBot( const char *name, float skill, const char *team, int delay } } Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) ); - Info_SetValueForKey( userinfo, "skill", va( "%f", skill ) ); + Info_SetValueForKey( userinfo, "skill", va( "%5.2f", skill ) ); Info_SetValueForKey( userinfo, "team", team ); bot = &g_entities[ clientNum ]; diff --git a/reaction/game/g_client.c b/reaction/game/g_client.c index 1e66a64b..8324b16f 100644 --- a/reaction/game/g_client.c +++ b/reaction/game/g_client.c @@ -572,6 +572,7 @@ ForceClientSkin Forces a client's skin (for teamplay) =========== */ +/* static void ForceClientSkin( gclient_t *client, char *model, const char *skin ) { char *p; @@ -582,7 +583,7 @@ static void ForceClientSkin( gclient_t *client, char *model, const char *skin ) Q_strcat(model, MAX_QPATH, "/"); Q_strcat(model, MAX_QPATH, skin); } - +*/ /* =========== @@ -688,6 +689,7 @@ void ClientUserinfoChanged( int clientNum ) { char oldname[MAX_STRING_CHARS]; gclient_t *client; char c1[MAX_INFO_STRING]; + char c2[MAX_INFO_STRING]; char redTeam[MAX_INFO_STRING]; char blueTeam[MAX_INFO_STRING]; char userinfo[MAX_INFO_STRING]; @@ -779,23 +781,26 @@ void ClientUserinfoChanged( int clientNum ) { team = client->sess.sessionTeam; } +/* NOTE: all client side now + // team switch( team ) { case TEAM_RED: ForceClientSkin(client, model, "red"); - ForceClientSkin(client, headModel, "red"); +// ForceClientSkin(client, headModel, "red"); break; case TEAM_BLUE: ForceClientSkin(client, model, "blue"); - ForceClientSkin(client, headModel, "blue"); +// ForceClientSkin(client, headModel, "blue"); break; } // don't ever use a default skin in teamplay, it would just waste memory // however bots will always join a team but they spawn in as spectator if ( g_gametype.integer >= GT_TEAM && team == TEAM_SPECTATOR) { ForceClientSkin(client, model, "red"); - ForceClientSkin(client, headModel, "red"); +// ForceClientSkin(client, headModel, "red"); } +*/ #ifdef MISSIONPACK if (g_gametype.integer >= GT_TEAM) { @@ -833,20 +838,22 @@ void ClientUserinfoChanged( int clientNum ) { teamLeader = client->sess.teamLeader; // colors - strcpy(c1, Info_ValueForKey( userinfo, "color" )); + strcpy(c1, Info_ValueForKey( userinfo, "color1" )); + strcpy(c2, Info_ValueForKey( userinfo, "color2" )); + strcpy(redTeam, Info_ValueForKey( userinfo, "g_redteam" )); strcpy(blueTeam, Info_ValueForKey( userinfo, "g_blueteam" )); // send over a subset of the userinfo keys so other clients can // print scoreboards, display models, and play custom sounds if ( ent->r.svFlags & SVF_BOT ) { - s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tt\\%d\\tl\\%d", - client->pers.netname, client->sess.sessionTeam, model, headModel, c1, + s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tt\\%d\\tl\\%d", + client->pers.netname, team, model, headModel, c1, c2, client->pers.maxHealth, client->sess.wins, client->sess.losses, Info_ValueForKey( userinfo, "skill" ), teamTask, teamLeader ); } else { - s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\g_redteam\\%s\\g_blueteam\\%s\\c1\\%s\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d", - client->pers.netname, client->sess.sessionTeam, model, headModel, redTeam, blueTeam, c1, + s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\g_redteam\\%s\\g_blueteam\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d", + client->pers.netname, client->sess.sessionTeam, model, headModel, redTeam, blueTeam, c1, c2, client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask, teamLeader); } @@ -893,11 +900,13 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) { return "Banned."; } - // check for a password - value = Info_ValueForKey (userinfo, "password"); - if ( g_password.string[0] && Q_stricmp( g_password.string, "none" ) && - strcmp( g_password.string, value) != 0) { - return "Invalid password"; + if ( !( ent->r.svFlags & SVF_BOT ) ) { + // check for a password + value = Info_ValueForKey (userinfo, "password"); + if ( g_password.string[0] && Q_stricmp( g_password.string, "none" ) && + strcmp( g_password.string, value) != 0) { + return "Invalid password"; + } } // they can connect @@ -1037,13 +1046,9 @@ void ClientSpawn(gentity_t *ent) { int savedPing; // char *savedAreaBits; int accuracy_hits, accuracy_shots; - int savedEvents[MAX_PS_EVENTS]; int eventSequence; char userinfo[MAX_INFO_STRING]; - //To save the ammo stuff - //qboolean hadUniqueWeapon[MAX_WEAPONS]; - index = ent - g_entities; client = ent->client; @@ -1104,22 +1109,12 @@ void ClientSpawn(gentity_t *ent) { // savedAreaBits = client->areabits; accuracy_hits = client->accuracy_hits; accuracy_shots = client->accuracy_shots; - - //Elder: save unique weapon info - //for ( i = 0 ; i < MAX_WEAPONS ; i++ ) { - //hadUniqueWeapon[i] = client->hadUniqueWeapon[i]; - //} - for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) { persistant[i] = client->ps.persistant[i]; } - // also save the predictable events otherwise we might get double or dropped events - for (i = 0; i < MAX_PS_EVENTS; i++) { - savedEvents[i] = client->ps.events[i]; - } eventSequence = client->ps.eventSequence; - memset (client, 0, sizeof(*client)); + memset (client, 0, sizeof(*client)); // bk FIXME: Com_Memset? client->pers = saved; client->sess = savedSess; @@ -1129,17 +1124,9 @@ void ClientSpawn(gentity_t *ent) { client->accuracy_shots = accuracy_shots; client->lastkilled_client = -1; - //Elder: restore unique weapon info - //for ( i = 0 ; i < MAX_WEAPONS ; i++ ) { - //client->hadUniqueWeapon[i] = hadUniqueWeapon[i]; - //} - for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) { client->ps.persistant[i] = persistant[i]; } - for (i = 0; i < MAX_PS_EVENTS; i++) { - client->ps.events[i] = savedEvents[i]; - } client->ps.eventSequence = eventSequence; // increment the spawncount so the client will detect the respawn client->ps.persistant[PERS_SPAWN_COUNT]++; @@ -1169,8 +1156,6 @@ void ClientSpawn(gentity_t *ent) { ent->watertype = 0; ent->flags = 0; - - VectorCopy (playerMins, ent->r.mins); VectorCopy (playerMaxs, ent->r.maxs); @@ -1241,17 +1226,6 @@ void ClientSpawn(gentity_t *ent) { client->inactivityTime = level.time + g_inactivity.integer * 1000; client->latched_buttons = 0; - // Hawkins reset zoomed flag - //Elder: using new stat - it's cleared anyways below - //client->zoomed=0; - - //Elder: knife reset/initialize - //Elder: removed - set in ClientBegin - //client->ps.persistant[PERS_WEAPONMODES] &= !RQ3_KNIFEMODE; - - //Elder: reset isBandaging flag - //client->isBandaging = qfalse; - //Elder: reset all RQ3 non-persistent stats ent->client->ps.stats[STAT_RQ3] = 0; @@ -1299,9 +1273,6 @@ void ClientSpawn(gentity_t *ent) { trap_LinkEntity( ent ); } - //Elder: debug - //G_Printf("Just after respawn- PERS_WEAPONMODES: %d\n", ent->client->ps.persistant[PERS_WEAPONMODES]); - // run the presend to set anything else ClientEndFrame( ent ); diff --git a/reaction/game/g_cmds.c b/reaction/game/g_cmds.c index b9ca1856..d016a8e7 100644 --- a/reaction/game/g_cmds.c +++ b/reaction/game/g_cmds.c @@ -581,7 +581,7 @@ void SetTeam( gentity_t *ent, char *s ) { } if ( team == TEAM_BLUE && counts[TEAM_BLUE] - counts[TEAM_RED] > 1 ) { trap_SendServerCommand( ent->client->ps.clientNum, - "cp \"Red team has too many players.\n\"" ); + "cp \"Blue team has too many players.\n\"" ); return; // ignore the request } @@ -839,6 +839,9 @@ static void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, cons if (!other->client) { return; } + if ( other->client->pers.connected != CON_CONNECTED ) { + return; + } if ( mode == SAY_TEAM && !OnSameTeam(ent, other) ) { return; } diff --git a/reaction/game/g_combat.c b/reaction/game/g_combat.c index 3f32deaf..27c23751 100644 --- a/reaction/game/g_combat.c +++ b/reaction/game/g_combat.c @@ -1640,7 +1640,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, //Setup headshot spray and sound //Only do if not knife or SSG -- SSG has its own trail of blood - if (mod != MOD_SNIPER && mod != MOD_KNIFE && mode != MOD_KNIFE_THROWN) + if (mod != MOD_SNIPER && mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN) { VectorAdd(targ->s.pos.trBase, line, line); tent = G_TempEntity(line, EV_HEADSHOT); diff --git a/reaction/game/g_items.c b/reaction/game/g_items.c index 1169c798..bd735564 100644 --- a/reaction/game/g_items.c +++ b/reaction/game/g_items.c @@ -114,7 +114,7 @@ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) { clientNum = other->client->ps.clientNum; trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) ); handicap = atof( Info_ValueForKey( userinfo, "handicap" ) ); - if( !handicap ) { + if( handicap<=0.0f || handicap>100.0f) { handicap = 100.0f; } max = (int)(2 * handicap); @@ -131,7 +131,7 @@ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) { clientNum = other->client->ps.clientNum; trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) ); handicap = atof( Info_ValueForKey( userinfo, "handicap" ) ); - if( !handicap ) { + if( handicap<=0.0f || handicap>100.0f) { handicap = 100.0f; } other->client->pers.maxHealth = handicap; @@ -142,7 +142,7 @@ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) { clientNum = other->client->ps.clientNum; trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) ); handicap = atof( Info_ValueForKey( userinfo, "handicap" ) ); - if( !handicap ) { + if( handicap<=0.0f || handicap>100.0f) { handicap = 100.0f; } other->client->pers.maxHealth = handicap; @@ -151,7 +151,7 @@ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) { clientNum = other->client->ps.clientNum; trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) ); handicap = atof( Info_ValueForKey( userinfo, "handicap" ) ); - if( !handicap ) { + if( handicap<=0.0f || handicap>100.0f) { handicap = 100.0f; } other->client->pers.maxHealth = handicap; @@ -161,7 +161,7 @@ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) { clientNum = other->client->ps.clientNum; trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) ); handicap = atof( Info_ValueForKey( userinfo, "handicap" ) ); - if( !handicap ) { + if( handicap<=0.0f || handicap>100.0f) { handicap = 100.0f; } other->client->pers.maxHealth = handicap; diff --git a/reaction/game/g_local.h b/reaction/game/g_local.h index 927fc1a0..b3bd4b8b 100644 --- a/reaction/game/g_local.h +++ b/reaction/game/g_local.h @@ -27,7 +27,6 @@ #define INFINITE 1000000 #define FRAMETIME 100 // msec -#define EVENT_VALID_MSEC 300 #define CARNAGE_REWARD_TIME 3000 #define REWARD_SPRITE_TIME 2000 @@ -398,7 +397,7 @@ struct gclient_s { // this structure is cleared as each map is entered // #define MAX_SPAWN_VARS 64 -#define MAX_SPAWN_VARS_CHARS 2048 +#define MAX_SPAWN_VARS_CHARS 4096 typedef struct { struct gclient_s *clients; // [maxclients] @@ -481,7 +480,6 @@ typedef struct { #ifdef MISSIONPACK int portalSequence; #endif - } level_locals_t; // // rxn_game.c diff --git a/reaction/game/g_main.c b/reaction/game/g_main.c index ecdec59e..e1e22bf7 100644 --- a/reaction/game/g_main.c +++ b/reaction/game/g_main.c @@ -78,7 +78,8 @@ vmCvar_t g_enableBreath; vmCvar_t g_proxMineTimeout; #endif -cvarTable_t gameCvarTable[] = { +// bk001129 - made static to avoid aliasing +static cvarTable_t gameCvarTable[] = { // don't override the cheat state set by the system { &g_cheats, "sv_cheats", "", 0, 0, qfalse }, @@ -89,7 +90,7 @@ cvarTable_t gameCvarTable[] = { { NULL, "sv_mapname", "", CVAR_SERVERINFO | CVAR_ROM, 0, qfalse }, // latched vars - { &g_gametype, "g_gametype", "0", CVAR_SERVERINFO | CVAR_LATCH, 0, qfalse }, + { &g_gametype, "g_gametype", "0", CVAR_SERVERINFO | CVAR_USERINFO | CVAR_LATCH, 0, qfalse }, { &g_maxclients, "sv_maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH | CVAR_ARCHIVE, 0, qfalse }, { &g_maxGameClients, "g_maxGameClients", "0", CVAR_SERVERINFO | CVAR_LATCH | CVAR_ARCHIVE, 0, qfalse }, @@ -166,7 +167,8 @@ cvarTable_t gameCvarTable[] = { }; -int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[0] ); +// bk001129 - made static to avoid aliasing +static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[0] ); void G_InitGame( int levelTime, int randomSeed, int restart ); @@ -1099,8 +1101,9 @@ Append information about this game to the log file void LogExit( const char *string ) { int i, numSorted; gclient_t *cl; -// qboolean won = qtrue; - +#ifdef MISSIONPACK // bk001205 + qboolean won = qtrue; +#endif G_LogPrintf( "Exit: %s\n", string ); level.intermissionQueued = level.time; diff --git a/reaction/game/g_mem.c b/reaction/game/g_mem.c index ad6c0594..d80d8027 100644 --- a/reaction/game/g_mem.c +++ b/reaction/game/g_mem.c @@ -21,7 +21,7 @@ void *G_Alloc( int size ) { } if ( allocPoint + size > POOLSIZE ) { - G_Error( "G_Alloc: failed on allocation of %u bytes\n", size ); + G_Error( "G_Alloc: failed on allocation of %i bytes\n", size ); // bk010103 - was %u, but is signed return NULL; } diff --git a/reaction/game/g_misc.c b/reaction/game/g_misc.c index 6d532b89..f3332f48 100644 --- a/reaction/game/g_misc.c +++ b/reaction/game/g_misc.c @@ -155,8 +155,14 @@ void locateCamera( gentity_t *ent ) { ent->s.frame = 75; } - // set to 0 for no rotation at all - ent->s.powerups = 1; + // swing camera ? + if ( owner->spawnflags & 4 ) { + // set to 0 for no rotation at all + ent->s.powerups = 0; + } + else { + ent->s.powerups = 1; + } // clientNum holds the rotate offset ent->s.clientNum = owner->s.clientNum; @@ -195,7 +201,7 @@ void SP_misc_portal_surface(gentity_t *ent) { } } -/*QUAKED misc_portal_camera (0 0 1) (-8 -8 -8) (8 8 8) slowrotate fastrotate +/*QUAKED misc_portal_camera (0 0 1) (-8 -8 -8) (8 8 8) slowrotate fastrotate noswing The target for a misc_portal_director. You can set either angles or target another entity to determine the direction of view. "roll" an angle modifier to orient the camera around the target vector; */ diff --git a/reaction/game/g_missile.c b/reaction/game/g_missile.c index 7fdb508f..3dc10b00 100644 --- a/reaction/game/g_missile.c +++ b/reaction/game/g_missile.c @@ -918,7 +918,7 @@ gentity_t *fire_grapple (gentity_t *self, vec3_t start, vec3_t dir) { fire_nail ================= */ -#define NAILGUN_SPREAD 1000 +#define NAILGUN_SPREAD 500 gentity_t *fire_nail( gentity_t *self, vec3_t start, vec3_t forward, vec3_t right, vec3_t up ) { gentity_t *bolt; diff --git a/reaction/game/g_mover.c b/reaction/game/g_mover.c index 4467809a..dcd3295d 100644 --- a/reaction/game/g_mover.c +++ b/reaction/game/g_mover.c @@ -51,6 +51,43 @@ gentity_t *G_TestEntityPosition( gentity_t *ent ) { return NULL; } +/* +================ +G_CreateRotationMatrix +================ +*/ +void G_CreateRotationMatrix(vec3_t angles, vec3_t matrix[3]) { + AngleVectors(angles, matrix[0], matrix[1], matrix[2]); + VectorInverse(matrix[1]); +} + +/* +================ +G_TransposeMatrix +================ +*/ +void G_TransposeMatrix(vec3_t matrix[3], vec3_t transpose[3]) { + int i, j; + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + transpose[i][j] = matrix[j][i]; + } + } +} + +/* +================ +G_RotatePoint +================ +*/ +void G_RotatePoint(vec3_t point, vec3_t matrix[3]) { + vec3_t tvec; + + VectorCopy(point, tvec); + point[0] = DotProduct(matrix[0], tvec); + point[1] = DotProduct(matrix[1], tvec); + point[2] = DotProduct(matrix[2], tvec); +} /* ================== @@ -60,7 +97,7 @@ Returns qfalse if the move is blocked ================== */ qboolean G_TryPushingEntity( gentity_t *check, gentity_t *pusher, vec3_t move, vec3_t amove ) { - vec3_t forward, right, up; + vec3_t matrix[3], transpose[3]; vec3_t org, org2, move2; gentity_t *block; @@ -84,27 +121,27 @@ qboolean G_TryPushingEntity( gentity_t *check, gentity_t *pusher, vec3_t move, v } pushed_p++; - // we need this for pushing things later - VectorSubtract (vec3_origin, amove, org); - AngleVectors (org, forward, right, up); - // try moving the contacted entity - VectorAdd (check->s.pos.trBase, move, check->s.pos.trBase); - if (check->client) { - // make sure the client's view rotates when on a rotating mover - check->client->ps.delta_angles[YAW] += ANGLE2SHORT(amove[YAW]); - } - // figure movement due to the pusher's amove - VectorSubtract (check->s.pos.trBase, pusher->r.currentOrigin, org); - org2[0] = DotProduct (org, forward); - org2[1] = -DotProduct (org, right); - org2[2] = DotProduct (org, up); + G_CreateRotationMatrix( amove, transpose ); + G_TransposeMatrix( transpose, matrix ); + if (check->client) { + VectorSubtract (check->client->ps.origin, pusher->r.currentOrigin, org); + } + else { + VectorSubtract (check->s.pos.trBase, pusher->r.currentOrigin, org); + } + VectorCopy( org, org2 ); + G_RotatePoint( org2, matrix ); VectorSubtract (org2, org, move2); + // add movement + VectorAdd (check->s.pos.trBase, move, check->s.pos.trBase); VectorAdd (check->s.pos.trBase, move2, check->s.pos.trBase); if ( check->client ) { VectorAdd (check->client->ps.origin, move, check->client->ps.origin); VectorAdd (check->client->ps.origin, move2, check->client->ps.origin); + // make sure the client's view rotates when on a rotating mover + check->client->ps.delta_angles[YAW] += ANGLE2SHORT(amove[YAW]); } // may have pushed them off an edge @@ -114,7 +151,6 @@ qboolean G_TryPushingEntity( gentity_t *check, gentity_t *pusher, vec3_t move, v block = G_TestEntityPosition( check ); if (!block) { - //G_Printf("G_TryPushingEntity: Push Ok\n"); // pushed ok if ( check->client ) { VectorCopy( check->client->ps.origin, check->r.currentOrigin ); diff --git a/reaction/game/g_public.h b/reaction/game/g_public.h index 3105aab2..1e2bafe8 100644 --- a/reaction/game/g_public.h +++ b/reaction/game/g_public.h @@ -15,7 +15,13 @@ #define SVF_PORTAL 0x00000040 // merge a second pvs at origin2 into snapshots #define SVF_USE_CURRENT_ORIGIN 0x00000080 // entity->r.currentOrigin instead of entity->s.origin // for link position (missiles and movers) -#define SVF_SINGLECLIENT 0x00000100 // only send to a single client +#define SVF_SINGLECLIENT 0x00000100 // only send to a single client (entityShared_t->singleClient) +#define SVF_NOSERVERINFO 0x00000200 // don't send CS_SERVERINFO updates to this client + // so that it can be updated for ping tools without + // lagging clients +#define SVF_CAPSULE 0x00000400 // use capsule for collision detection instead of bbox +#define SVF_NOTSINGLECLIENT 0x00000800 // send entity to everyone but one client + // (entityShared_t->singleClient) //=============================================================== @@ -187,6 +193,9 @@ typedef enum { G_REAL_TIME, G_SNAPVECTOR, + G_TRACECAPSULE, // ( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask ); + G_ENTITY_CONTACTCAPSULE, // ( const vec3_t mins, const vec3_t maxs, const gentity_t *ent ); + BOTLIB_SETUP = 200, // ( void ); BOTLIB_SHUTDOWN, // ( void ); BOTLIB_LIBVAR_SET, diff --git a/reaction/game/g_session.c b/reaction/game/g_session.c index 860d4853..9e3692f9 100644 --- a/reaction/game/g_session.c +++ b/reaction/game/g_session.c @@ -50,18 +50,28 @@ void G_ReadSessionData( gclient_t *client ) { char s[MAX_STRING_CHARS]; const char *var; + // bk001205 - format + int teamLeader; + int spectatorState; + int sessionTeam; + var = va( "session%i", client - level.clients ); trap_Cvar_VariableStringBuffer( var, s, sizeof(s) ); sscanf( s, "%i %i %i %i %i %i %i", - &client->sess.sessionTeam, + &sessionTeam, // bk010221 - format &client->sess.spectatorTime, - &client->sess.spectatorState, + &spectatorState, // bk010221 - format &client->sess.spectatorClient, &client->sess.wins, &client->sess.losses, - &client->sess.teamLeader + &teamLeader // bk010221 - format ); + + // bk001205 - format issues + client->sess.sessionTeam = (team_t)sessionTeam; + client->sess.spectatorState = (spectatorState_t)spectatorState; + client->sess.teamLeader = (qboolean)teamLeader; } diff --git a/reaction/game/g_spawn.c b/reaction/game/g_spawn.c index 94b7bf55..f3ae7282 100644 --- a/reaction/game/g_spawn.c +++ b/reaction/game/g_spawn.c @@ -467,6 +467,20 @@ void G_SpawnGEntityFromSpawnVars( void ) { } } +#ifdef MISSIONPACK + G_SpawnInt( "notta", "0", &i ); + if ( i ) { + G_FreeEntity( ent ); + return; + } +#else + G_SpawnInt( "notq3a", "0", &i ); + if ( i ) { + G_FreeEntity( ent ); + return; + } +#endif + if( G_SpawnString( "gametype", NULL, &value ) ) { if( g_gametype.integer >= GT_FFA && g_gametype.integer < GT_MAX_GAME_TYPE ) { gametypeName = gametypeNames[g_gametype.integer]; @@ -502,7 +516,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_VARS" ); + G_Error( "G_AddSpawnVarToken: MAX_SPAWN_CHARS" ); } dest = level.spawnVarChars + level.numSpawnVarChars; diff --git a/reaction/game/g_svcmds.c b/reaction/game/g_svcmds.c index a5f54324..614467b0 100644 --- a/reaction/game/g_svcmds.c +++ b/reaction/game/g_svcmds.c @@ -441,7 +441,7 @@ qboolean ConsoleCommand( void ) { } if (Q_stricmp (cmd, "listip") == 0) { - trap_SendConsoleCommand( EXEC_INSERT, "g_banIPs\n" ); + trap_SendConsoleCommand( EXEC_NOW, "g_banIPs\n" ); return qtrue; } diff --git a/reaction/game/g_syscalls.asm b/reaction/game/g_syscalls.asm index b2303958..79f8dfd5 100644 --- a/reaction/game/g_syscalls.asm +++ b/reaction/game/g_syscalls.asm @@ -43,7 +43,8 @@ equ trap_DebugPolygonCreate -40 equ trap_DebugPolygonDelete -41 equ trap_RealTime -42 equ trap_SnapVector -43 - +equ trap_TraceCapsule -44 +equ trap_EntityContactCapsule -45 equ memset -101 equ memcpy -102 @@ -216,3 +217,8 @@ equ trap_AAS_AlternativeRouteGoals -576 equ trap_AAS_PredictRoute -577 equ trap_AAS_PointReachabilityAreaIndex -578 +equ trap_BotLibLoadSource -579 +equ trap_BotLibFreeSource -580 +equ trap_BotLibReadToken -581 +equ trap_BotLibSourceFileAndLine -582 + diff --git a/reaction/game/g_syscalls.c b/reaction/game/g_syscalls.c index 979152e4..7062fc6f 100644 --- a/reaction/game/g_syscalls.c +++ b/reaction/game/g_syscalls.c @@ -123,6 +123,10 @@ void trap_Trace( trace_t *results, const vec3_t start, const vec3_t mins, const syscall( G_TRACE, results, start, mins, maxs, end, passEntityNum, contentmask ); } +void trap_TraceCapsule( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask ) { + syscall( G_TRACECAPSULE, results, start, mins, maxs, end, passEntityNum, contentmask ); +} + int trap_PointContents( const vec3_t point, int passEntityNum ) { return syscall( G_POINT_CONTENTS, point, passEntityNum ); } @@ -152,7 +156,6 @@ void trap_UnlinkEntity( gentity_t *ent ) { syscall( G_UNLINKENTITY, ent ); } - int trap_EntitiesInBox( const vec3_t mins, const vec3_t maxs, int *list, int maxcount ) { return syscall( G_ENTITIES_IN_BOX, mins, maxs, list, maxcount ); } @@ -161,6 +164,10 @@ qboolean trap_EntityContact( const vec3_t mins, const vec3_t maxs, const gentity return syscall( G_ENTITY_CONTACT, mins, maxs, ent ); } +qboolean trap_EntityContactCapsule( const vec3_t mins, const vec3_t maxs, const gentity_t *ent ) { + return syscall( G_ENTITY_CONTACTCAPSULE, mins, maxs, ent ); +} + int trap_BotAllocateClient( void ) { return syscall( G_BOT_ALLOCATE_CLIENT ); } @@ -739,3 +746,18 @@ int trap_GeneticParentsAndChildSelection(int numranks, float *ranks, int *parent return syscall( BOTLIB_AI_GENETIC_PARENTS_AND_CHILD_SELECTION, numranks, ranks, parent1, parent2, child ); } +int trap_PC_LoadSource( const char *filename ) { + return syscall( BOTLIB_PC_LOAD_SOURCE, filename ); +} + +int trap_PC_FreeSource( int handle ) { + return syscall( BOTLIB_PC_FREE_SOURCE, handle ); +} + +int trap_PC_ReadToken( int handle, pc_token_t *pc_token ) { + return syscall( BOTLIB_PC_READ_TOKEN, handle, pc_token ); +} + +int trap_PC_SourceFileAndLine( int handle, char *filename, int *line ) { + return syscall( BOTLIB_PC_SOURCE_FILE_AND_LINE, handle, filename, line ); +} diff --git a/reaction/game/g_team.c b/reaction/game/g_team.c index d92f26b0..2b4d846a 100644 --- a/reaction/game/g_team.c +++ b/reaction/game/g_team.c @@ -777,8 +777,7 @@ 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; - } - if (player->client->pers.teamState.lastfraggedcarrier + + } else 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/reaction/game/g_utils.c b/reaction/game/g_utils.c index 5674b682..2d33d8d3 100644 --- a/reaction/game/g_utils.c +++ b/reaction/game/g_utils.c @@ -35,7 +35,7 @@ void AddRemap(const char *oldShader, const char *newShader, float timeOffset) { } const char *BuildShaderStateConfig() { - static char buff[MAX_STRING_CHARS]; + static char buff[MAX_STRING_CHARS*4]; char out[(MAX_QPATH * 2) + 5]; int i; diff --git a/reaction/game/g_weapon.c b/reaction/game/g_weapon.c index ed0cf7f1..293a84c2 100644 --- a/reaction/game/g_weapon.c +++ b/reaction/game/g_weapon.c @@ -5,10 +5,6 @@ #include "g_local.h" -//Blaze: reaction weapon damage ratings & weapon spreads -//Elder: moved to bg_public.h with the rest of the constants - - static float s_quadFactor; static vec3_t forward, right, up; static vec3_t muzzle; @@ -16,7 +12,7 @@ static vec3_t muzzle; //Elder: used for shell damage - we have no more malloc function so make it static? int tookShellHit[MAX_CLIENTS]; -#define NUM_NAILSHOTS 10 +#define NUM_NAILSHOTS 15 /* ================ diff --git a/reaction/game/game.plg b/reaction/game/game.plg index 7b57db01..fd6a62a9 100644 --- a/reaction/game/game.plg +++ b/reaction/game/game.plg @@ -6,13 +6,47 @@ --------------------Configuration: game - Win32 Debug--------------------