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--------------------

Command Lines

-Creating temporary file "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP5D5.tmp" with contents +Creating temporary file "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP2BE.tmp" with contents [ /nologo /G5 /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "BUILDING_REF_GL" /D "DEBUG" /FR"c:\reactionoutput/" /Fp"c:\reactionoutput/game.pch" /YX /Fo"c:\reactionoutput/" /Fd"c:\reactionoutput/" /FD /c +"c:\reaction\game\ai_chat.c" +"c:\reaction\game\ai_cmd.c" +"c:\reaction\game\ai_dmnet.c" +"c:\reaction\game\ai_dmq3.c" +"c:\reaction\game\ai_main.c" +"c:\reaction\game\ai_team.c" +"c:\reaction\game\ai_vcmd.c" +"c:\reaction\game\bg_misc.c" "c:\reaction\game\bg_pmove.c" +"c:\reaction\game\bg_slidemove.c" +"c:\reaction\game\g_active.c" +"c:\reaction\game\g_arenas.c" +"c:\reaction\game\g_bot.c" +"c:\reaction\game\g_client.c" +"c:\reaction\game\g_cmds.c" +"c:\reaction\game\g_combat.c" +"c:\reaction\game\g_fileio.c" +"c:\reaction\game\g_items.c" +"c:\reaction\game\g_main.c" +"c:\reaction\game\g_mem.c" +"c:\reaction\game\g_misc.c" +"c:\reaction\game\g_missile.c" +"c:\reaction\game\g_mover.c" +"c:\reaction\game\g_session.c" +"c:\reaction\game\g_spawn.c" +"c:\reaction\game\g_svcmds.c" +"c:\reaction\game\g_syscalls.c" +"c:\reaction\game\g_target.c" +"c:\reaction\game\g_team.c" +"c:\reaction\game\g_trigger.c" +"c:\reaction\game\g_utils.c" +"c:\reaction\game\g_weapon.c" +"c:\reaction\game\q_math.c" +"c:\reaction\game\q_shared.c" +"c:\reaction\game\rxn_game.c" ] -Creating command line "cl.exe @C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP5D5.tmp" -Creating temporary file "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP5D6.tmp" with contents +Creating command line "cl.exe @C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP2BE.tmp" +Creating temporary file "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP2BF.tmp" with contents [ kernel32.lib user32.lib winmm.lib /nologo /base:"0x20000000" /subsystem:windows /dll /incremental:yes /pdb:"c:\reactionoutput/qagamex86.pdb" /map:"c:\reactionoutput/qagamex86.map" /debug /machine:I386 /def:".\game.def" /out:"..\Debug/qagamex86.dll" /implib:"c:\reactionoutput/qagamex86.lib" \reactionoutput\ai_chat.obj @@ -51,24 +85,52 @@ kernel32.lib user32.lib winmm.lib /nologo /base:"0x20000000" /subsystem:windows \reactionoutput\q_shared.obj \reactionoutput\rxn_game.obj ] -Creating command line "link.exe @C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP5D6.tmp" +Creating command line "link.exe @C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP2BF.tmp"

Output Window

Compiling... +ai_chat.c +ai_cmd.c +ai_dmnet.c +ai_dmq3.c +ai_main.c +ai_team.c +ai_vcmd.c +bg_misc.c bg_pmove.c +bg_slidemove.c +g_active.c +c:\reaction\game\g_active.c(25) : warning C4101: 'tent' : unreferenced local variable +g_arenas.c +g_bot.c +g_client.c +g_cmds.c +g_combat.c +g_fileio.c +g_items.c +g_main.c +g_mem.c +g_misc.c +g_missile.c +g_mover.c +g_session.c +g_spawn.c +g_svcmds.c +g_syscalls.c +g_target.c +g_team.c +g_trigger.c +g_utils.c +g_weapon.c +q_math.c +q_shared.c +rxn_game.c Linking... Creating library c:\reactionoutput/qagamex86.lib and object c:\reactionoutput/qagamex86.exp -g_active.obj : error LNK2001: unresolved external symbol _s_quadFactor -g_active.obj : error LNK2001: unresolved external symbol _muzzle -g_active.obj : error LNK2001: unresolved external symbol _forward -g_active.obj : error LNK2001: unresolved external symbol _right -g_active.obj : error LNK2001: unresolved external symbol _up -..\Debug/qagamex86.dll : fatal error LNK1120: 5 unresolved externals -Error executing link.exe.

Results

-qagamex86.dll - 6 error(s), 0 warning(s) +qagamex86.dll - 0 error(s), 1 warning(s) diff --git a/reaction/game/q_math.c b/reaction/game/q_math.c index c1795144..4a852f7f 100644 --- a/reaction/game/q_math.c +++ b/reaction/game/q_math.c @@ -133,6 +133,62 @@ float Q_crandom( int *seed ) { return 2.0 * ( Q_random( seed ) - 0.5 ); } +#ifdef __LCC__ + +int VectorCompare( const vec3_t v1, const vec3_t v2 ) { + if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) { + return 0; + } + return 1; +} + +vec_t VectorLength( const vec3_t v ) { + return (vec_t)sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); +} + +vec_t VectorLengthSquared( const vec3_t v ) { + return (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); +} + +vec_t Distance( const vec3_t p1, const vec3_t p2 ) { + vec3_t v; + + VectorSubtract (p2, p1, v); + return VectorLength( v ); +} + +vec_t DistanceSquared( const vec3_t p1, const vec3_t p2 ) { + vec3_t v; + + VectorSubtract (p2, p1, v); + return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; +} + +// fast vector normalize routine that does not check to make sure +// that length != 0, nor does it return length, uses rsqrt approximation +void VectorNormalizeFast( vec3_t v ) +{ + float ilength; + + ilength = Q_rsqrt( DotProduct( v, v ) ); + + v[0] *= ilength; + v[1] *= ilength; + v[2] *= ilength; +} + +void VectorInverse( vec3_t v ){ + v[0] = -v[0]; + v[1] = -v[1]; + v[2] = -v[2]; +} + +void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross ) { + cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; + cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; + cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; +} +#endif //======================================================= @@ -419,7 +475,11 @@ void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal ) vec3_t n; float inv_denom; - inv_denom = 1.0F / DotProduct( normal, normal ); + inv_denom = DotProduct( normal, normal ); +#ifndef Q3_VM + assert( Q_fabs(inv_denom) != 0.0f ); // bk010122 - zero vectors get here +#endif + inv_denom = 1.0f / inv_denom; d = DotProduct( normal, p ) * inv_denom; @@ -465,6 +525,7 @@ void VectorRotate( vec3_t in, vec3_t matrix[3], vec3_t out ) //============================================================================ +#if !idppc /* ** float q_rsqrt( float number ) */ @@ -482,6 +543,11 @@ float Q_rsqrt( float number ) y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration // y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed +#ifndef Q3_VM +#ifdef __linux__ + assert( !isnan(y) ); // bk010122 - FPE? +#endif +#endif return y; } @@ -490,6 +556,7 @@ float Q_fabs( float f ) { tmp &= 0x7FFFFFFF; return * ( float * ) &tmp; } +#endif //============================================================ @@ -650,8 +717,9 @@ int BoxOnPlaneSide2 (vec3_t emins, vec3_t emaxs, struct cplane_s *p) ================== */ -#if !(defined __linux__ && defined __i386__ && !defined C_ONLY) -#if defined __LCC__ || defined C_ONLY || !id386 +#if !( (defined __linux__ || __FreeBSD__) && (defined __i386__) && (!defined C_ONLY)) // rb010123 + +#if defined __LCC__ || defined C_ONLY || !id386 || defined __VECTORC int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p) { @@ -1002,15 +1070,6 @@ void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs ) { } -int VectorCompare( const vec3_t v1, const vec3_t v2 ) { - if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) { - return 0; - } - - return 1; -} - - vec_t VectorNormalize( vec3_t v ) { float length, ilength; @@ -1027,21 +1086,6 @@ vec_t VectorNormalize( vec3_t v ) { return length; } -// -// fast vector normalize routine that does not check to make sure -// that length != 0, nor does it return length -// -void VectorNormalizeFast( vec3_t v ) -{ - float ilength; - - ilength = Q_rsqrt( DotProduct( v, v ) ); - - v[0] *= ilength; - v[1] *= ilength; - v[2] *= ilength; -} - vec_t VectorNormalize2( const vec3_t v, vec3_t out) { float length, ilength; @@ -1050,11 +1094,17 @@ vec_t VectorNormalize2( const vec3_t v, vec3_t out) { if (length) { +#ifndef Q3_VM // bk0101022 - FPE related +// assert( ((Q_fabs(v[0])!=0.0f) || (Q_fabs(v[1])!=0.0f) || (Q_fabs(v[2])!=0.0f)) ); +#endif ilength = 1/length; out[0] = v[0]*ilength; out[1] = v[1]*ilength; out[2] = v[2]*ilength; } else { +#ifndef Q3_VM // bk0101022 - FPE related +// assert( ((Q_fabs(v[0])==0.0f) && (Q_fabs(v[1])==0.0f) && (Q_fabs(v[2])==0.0f)) ); +#endif VectorClear( out ); } @@ -1097,41 +1147,6 @@ void _VectorScale( const vec3_t in, vec_t scale, vec3_t out ) { out[2] = in[2]*scale; } -void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross ) { - cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; - cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; - cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; -} - -vec_t VectorLength( const vec3_t v ) { - return sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); -} - -vec_t VectorLengthSquared( const vec3_t v ) { - return (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); -} - -vec_t Distance( const vec3_t p1, const vec3_t p2 ) { - vec3_t v; - - VectorSubtract (p2, p1, v); - return VectorLength( v ); -} - -vec_t DistanceSquared( const vec3_t p1, const vec3_t p2 ) { - vec3_t v; - - VectorSubtract (p2, p1, v); - return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; -} - - -void VectorInverse( vec3_t v ){ - v[0] = -v[0]; - v[1] = -v[1]; - v[2] = -v[2]; -} - void Vector4Scale( const vec4_t in, vec_t scale, vec4_t out ) { out[0] = in[0]*scale; out[1] = in[1]*scale; diff --git a/reaction/game/q_shared.c b/reaction/game/q_shared.c index 2b4b3cd3..15939e2e 100644 --- a/reaction/game/q_shared.c +++ b/reaction/game/q_shared.c @@ -79,7 +79,7 @@ void COM_DefaultExtension (char *path, int maxSize, const char *extension ) { ============================================================================ */ - +/* // can't just use function pointers, or dll linkage can // mess up when qcommon is included in multiple places static short (*_BigShort) (short l); @@ -88,8 +88,8 @@ static int (*_BigLong) (int l); static int (*_LittleLong) (int l); static qint64 (*_BigLong64) (qint64 l); static qint64 (*_LittleLong64) (qint64 l); -static float (*_BigFloat) (float l); -static float (*_LittleFloat) (float l); +static float (*_BigFloat) (const float *l); +static float (*_LittleFloat) (const float *l); short BigShort(short l){return _BigShort(l);} short LittleShort(short l) {return _LittleShort(l);} @@ -97,8 +97,9 @@ int BigLong (int l) {return _BigLong(l);} int LittleLong (int l) {return _LittleLong(l);} qint64 BigLong64 (qint64 l) {return _BigLong64(l);} qint64 LittleLong64 (qint64 l) {return _LittleLong64(l);} -float BigFloat (float l) {return _BigFloat(l);} -float LittleFloat (float l) {return _LittleFloat(l);} +float BigFloat (const float *l) {return _BigFloat(l);} +float LittleFloat (const float *l) {return _LittleFloat(l);} +*/ short ShortSwap (short l) { @@ -153,26 +154,24 @@ qint64 Long64NoSwap (qint64 ll) return ll; } -float FloatSwap (float f) -{ - union - { +typedef union { float f; - byte b[4]; - } dat1, dat2; + unsigned int i; +} _FloatByteUnion; +float FloatSwap (const float *f) { + const _FloatByteUnion *in; + _FloatByteUnion out; - dat1.f = f; - dat2.b[0] = dat1.b[3]; - dat2.b[1] = dat1.b[2]; - dat2.b[2] = dat1.b[1]; - dat2.b[3] = dat1.b[0]; - return dat2.f; + in = (_FloatByteUnion *)f; + out.i = LongSwap(in->i); + + return out.f; } -float FloatNoSwap (float f) +float FloatNoSwap (const float *f) { - return f; + return *f; } /* @@ -180,6 +179,7 @@ float FloatNoSwap (float f) Swap_Init ================ */ +/* void Swap_Init (void) { byte swaptest[2] = {1,0}; @@ -209,7 +209,7 @@ void Swap_Init (void) } } - +*/ /* ============================================================================ @@ -293,55 +293,71 @@ static char *SkipWhitespace( char *data, qboolean *hasNewLines ) { } int COM_Compress( char *data_p ) { - char *datai, *datao; - int c, pc, size; - qboolean ws = qfalse; + char *in, *out; + int c; + qboolean newline = qfalse, whitespace = qfalse; - size = 0; - pc = 0; - datai = datao = data_p; - if (datai) { - while ((c = *datai) != 0) { - if (c == 13 || c == 10) { - *datao = c; - datao++; - ws = qfalse; - pc = c; - datai++; - size++; + in = out = data_p; + if (in) { + while ((c = *in) != 0) { // skip double slash comments - } else if ( c == '/' && datai[1] == '/' ) { - while (*datai && *datai != '\n') { - datai++; + if ( c == '/' && in[1] == '/' ) { + while (*in && *in != '\n') { + in++; } - ws = qfalse; // skip /* */ comments - } else if ( c=='/' && datai[1] == '*' ) { - while ( *datai && ( *datai != '*' || datai[1] != '/' ) ) - { - datai++; - } - if ( *datai ) - { - datai += 2; - } - ws = qfalse; + } else if ( c == '/' && in[1] == '*' ) { + while ( *in && ( *in != '*' || in[1] != '/' ) ) + in++; + if ( *in ) + in += 2; + // record when we hit a newline + } else if ( c == '\n' || c == '\r' ) { + newline = qtrue; + in++; + // record when we hit whitespace + } else if ( c == ' ' || c == '\t') { + whitespace = qtrue; + in++; + // an actual token } else { - if (ws) { - *datao = ' '; - datao++; + // if we have a pending newline, emit it (and it counts as whitespace) + if (newline) { + *out++ = '\n'; + newline = qfalse; + whitespace = qfalse; + } if (whitespace) { + *out++ = ' '; + whitespace = qfalse; + } + + // copy quoted strings unmolested + if (c == '"') { + *out++ = c; + in++; + while (1) { + c = *in; + if (c && c != '"') { + *out++ = c; + in++; + } else { + break; + } + } + if (c == '"') { + *out++ = c; + in++; + } + } else { + *out = c; + out++; + in++; } - *datao = c; - datao++; - datai++; - ws = qfalse; - pc = c; - size++; } } } - *datao = 0; - return size; + *out = 0; + return out - data_p; } char *COM_ParseExt( char **data_p, qboolean allowLineBreaks ) @@ -673,6 +689,10 @@ Safe strncpy that ensures a trailing zero ============= */ void Q_strncpyz( char *dest, const char *src, int destsize ) { + // bk001129 - also NULL dest + if ( !dest ) { + Com_Error( ERR_FATAL, "Q_strncpyz: NULL dest" ); + } if ( !src ) { Com_Error( ERR_FATAL, "Q_strncpyz: NULL src" ); } @@ -687,6 +707,18 @@ void Q_strncpyz( char *dest, const char *src, int destsize ) { int Q_stricmpn (const char *s1, const char *s2, int n) { int c1, c2; + // bk001129 - moved in 1.17 fix not in id codebase + if ( s1 == NULL ) { + if ( s2 == NULL ) + return 0; + else + return -1; + } + else if ( s2==NULL ) + return 1; + + + do { c1 = *s1++; c2 = *s2++; @@ -828,6 +860,11 @@ void QDECL Com_sprintf( char *dest, int size, const char *fmt, ...) { } if (len >= size) { Com_Printf ("Com_sprintf: overflow of %i in %i\n", len, size); +#ifdef _DEBUG + __asm { + int 3; + } +#endif } Q_strncpyz (dest, bigbuffer, size ); } @@ -1142,7 +1179,8 @@ void Info_SetValueForKey( char *s, const char *key, const char *value ) { return; } - strcat (s, newi); + strcat (newi, s); + strcpy (s, newi); } /* diff --git a/reaction/game/q_shared.h b/reaction/game/q_shared.h index 57aaf670..785ab5a3 100644 --- a/reaction/game/q_shared.h +++ b/reaction/game/q_shared.h @@ -6,10 +6,9 @@ // q_shared.h -- included first by ALL program modules. // A user mod should never modify this file -#define Q3_VERSION "Q3 1.27g" +#define Q3_VERSION "Q3 1.29h" -#define NEW_ANIMS #define MAX_TEAMNAME 32 #ifdef _WIN32 @@ -37,10 +36,6 @@ #pragma warning(disable : 4220) // varargs matches remaining parameters #endif -#if defined(ppc) || defined(__ppc) || defined(__ppc__) || defined(__POWERPC__) -#define idppc 1 -#endif - /********************************************************************** VM Considerations @@ -89,10 +84,20 @@ #define id386 0 #endif +#if (defined(powerc) || defined(powerpc) || defined(ppc) || defined(__ppc) || defined(__ppc__)) && !defined(C_ONLY) +#define idppc 1 +#else +#define idppc 0 +#endif + // for windows fastcall option #define QDECL +short ShortSwap (short l); +int LongSwap (int l); +float FloatSwap (const float *f); + //======================= WIN32 DEFINES ================================= #ifdef WIN32 @@ -117,31 +122,70 @@ #endif #endif +#define ID_INLINE __inline + +static ID_INLINE short BigShort( short l) { return ShortSwap(l); } +#define LittleShort +static ID_INLINE int BigLong(int l) { LongSwap(l); } +#define LittleLong +static ID_INLINE float BigFloat(const float *l) { FloatSwap(l); } +#define LittleFloat #define PATH_SEP '\\' #endif -//======================= MAC OS X SERVER DEFINES ===================== +//======================= MAC OS X DEFINES ===================== -#if defined(__MACH__) && defined(__APPLE__) +#if defined(MACOS_X) #define MAC_STATIC +#define __cdecl +#define __declspec(x) +#define stricmp strcasecmp +#define ID_INLINE inline #ifdef __ppc__ -#define CPUSTRING "MacOSXS-ppc" +#define CPUSTRING "MacOSX-ppc" #elif defined __i386__ -#define CPUSTRING "MacOSXS-i386" +#define CPUSTRING "MacOSX-i386" #else -#define CPUSTRING "MacOSXS-other" +#define CPUSTRING "MacOSX-other" #endif #define PATH_SEP '/' -#define GAME_HARD_LINKED -#define CGAME_HARD_LINKED -#define UI_HARD_LINKED -#define BOTLIB_HARD_LINKED +#define __rlwimi(out, in, shift, maskBegin, maskEnd) asm("rlwimi %0,%1,%2,%3,%4" : "=r" (out) : "r" (in), "i" (shift), "i" (maskBegin), "i" (maskEnd)) +#define __dcbt(addr, offset) asm("dcbt %0,%1" : : "b" (addr), "r" (offset)) + +static inline unsigned int __lwbrx(register void *addr, register int offset) { + register unsigned int word; + + asm("lwbrx %0,%2,%1" : "=r" (word) : "r" (addr), "b" (offset)); + return word; +} + +static inline unsigned short __lhbrx(register void *addr, register int offset) { + register unsigned short halfword; + + asm("lhbrx %0,%2,%1" : "=r" (halfword) : "r" (addr), "b" (offset)); + return halfword; +} + +static inline float __fctiw(register float f) { + register float fi; + + asm("fctiw %0,%1" : "=f" (fi) : "f" (f)); + + return fi; +} + +#define BigShort +static inline short LittleShort(short l) { return ShortSwap(l); } +#define BigLong +static inline int LittleLong (int l) { return LongSwap(l); } +#define BigFloat +static inline float LittleFloat (const float l) { return FloatSwap(&l); } #endif @@ -150,19 +194,22 @@ #ifdef __MACOS__ #include -#define MAC_STATIC static +#define MAC_STATIC +#define ID_INLINE inline #define CPUSTRING "MacOS-PPC" #define PATH_SEP ':' -#define GAME_HARD_LINKED -#define CGAME_HARD_LINKED -#define UI_HARD_LINKED -#define BOTLIB_HARD_LINKED - void Sys_PumpEvents( void ); +#define BigShort +static inline short LittleShort(short l) { return ShortSwap(l); } +#define BigLong +static inline int LittleLong (int l) { return LongSwap(l); } +#define BigFloat +static inline float LittleFloat (const float l) { return FloatSwap(&l); } + #endif //======================= LINUX DEFINES ================================= @@ -171,7 +218,11 @@ void Sys_PumpEvents( void ); // just waste space and make big arrays static... #ifdef __linux__ -#define MAC_STATIC +// bk001205 - from Makefile +#define stricmp strcasecmp + +#define MAC_STATIC // bk: FIXME +#define ID_INLINE inline #ifdef __i386__ #define CPUSTRING "linux-i386" @@ -183,11 +234,72 @@ void Sys_PumpEvents( void ); #define PATH_SEP '/' +// bk001205 - try +#ifdef Q3_STATIC +#define GAME_HARD_LINKED +#define CGAME_HARD_LINKED +#define UI_HARD_LINKED +#define BOTLIB_HARD_LINKED +#endif + +#if !idppc +inline static short BigShort( short l) { return ShortSwap(l); } +#define LittleShort +inline static int BigLong(int l) { return LongSwap(l); } +#define LittleLong +inline static float BigFloat(const float *l) { return FloatSwap(l); } +#define LittleFloat +#else +#define BigShort +inline static short LittleShort(short l) { return ShortSwap(l); } +#define BigLong +inline static int LittleLong (int l) { return LongSwap(l); } +#define BigFloat +inline static float LittleFloat (const float *l) { return FloatSwap(l); } +#endif + +#endif + +//======================= FreeBSD DEFINES ===================== +#ifdef __FreeBSD__ // rb010123 + +#define stricmp strcasecmp + +#define MAC_STATIC +#define ID_INLINE inline + +#ifdef __i386__ +#define CPUSTRING "freebsd-i386" +#elif defined __axp__ +#define CPUSTRING "freebsd-alpha" +#else +#define CPUSTRING "freebsd-other" +#endif + +#define PATH_SEP '/' + +// bk010116 - omitted Q3STATIC (see Linux above), broken target + +#if !idppc +static short BigShort( short l) { return ShortSwap(l); } +#define LittleShort +static int BigLong(int l) { LongSwap(l); } +#define LittleLong +static float BigFloat(const float *l) { FloatSwap(l); } +#define LittleFloat +#else +#define BigShort +static short LittleShort(short l) { return ShortSwap(l); } +#define BigLong +static int LittleLong (int l) { return LongSwap(l); } +#define BigFloat +static float LittleFloat (const float *l) { return FloatSwap(l); } +#endif + #endif //============================================================= - typedef unsigned char byte; typedef enum {qfalse, qtrue} qboolean; @@ -214,7 +326,7 @@ typedef int clipHandle_t; // the game guarantees that no string from the network will ever // exceed MAX_STRING_CHARS #define MAX_STRING_CHARS 1024 // max length of a string passed to Cmd_TokenizeString -#define MAX_STRING_TOKENS 256 // max tokens resulting from Cmd_TokenizeString +#define MAX_STRING_TOKENS 1024 // max tokens resulting from Cmd_TokenizeString #define MAX_TOKEN_CHARS 1024 // max length of an individual token #define MAX_INFO_STRING 1024 @@ -227,7 +339,11 @@ typedef int clipHandle_t; #define MAX_QPATH 64 // max length of a quake game pathname +#ifdef PATH_MAX +#define MAX_OSPATH PATH_MAX +#else #define MAX_OSPATH 256 // max length of a filesystem pathname +#endif #define MAX_NAME_LENGTH 32 // max length of a client name @@ -311,8 +427,13 @@ void *Hunk_AllocDebug( int size, ha_pref preference, char *label, char *file, in void *Hunk_Alloc( int size, ha_pref preference ); #endif +#if !( defined __VECTORC ) void Com_Memset (void* dest, const int val, const size_t count); void Com_Memcpy (void* dest, const void* src, const size_t count); +#else +#define Com_Memset memset +#define Com_Memcpy memcpy +#endif #define CIN_system 1 #define CIN_loop 2 @@ -414,10 +535,36 @@ extern vec3_t axisDefault[3]; #define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) +#if idppc + +static inline float Q_rsqrt( float number ) { + float x = 0.5f * number; + float y; +#ifdef __GNUC__ + asm("frsqrte %0,%1" : "=f" (y) : "f" (number)); +#else + y = __frsqrte( number ); +#endif + return y * (1.5f - (x * y * y)); + } + +#ifdef __GNUC__ +static inline float Q_fabs(float x) { + float abs_x; + + asm("fabs %0,%1" : "=f" (abs_x) : "f" (x)); + return abs_x; +} +#else +#define Q_fabs __fabsf +#endif + +#else float Q_fabs( float f ); float Q_rsqrt( float f ); // reciprocal square root +#endif -#define SQRTFAST( x ) ( 1.0f / Q_rsqrt( x ) ) +#define SQRTFAST( x ) ( (x) * Q_rsqrt( x ) ) signed char ClampChar( int i ); signed short ClampShort( int i ); @@ -454,6 +601,7 @@ typedef struct { float v[3]; } vec3struct_t; #define VectorCopy(a,b) *(vec3struct_t *)b=*(vec3struct_t *)a; +#define ID_INLINE static #endif #endif @@ -479,16 +627,83 @@ float NormalizeColor( const vec3_t in, vec3_t out ); float RadiusFromBounds( const vec3_t mins, const vec3_t maxs ); void ClearBounds( vec3_t mins, vec3_t maxs ); void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs ); + +#ifndef __LCC__ +static ID_INLINE int VectorCompare( const vec3_t v1, const vec3_t v2 ) { + if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) { + return 0; + } + return 1; +} + +static ID_INLINE vec_t VectorLength( const vec3_t v ) { + return (vec_t)sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); +} + +static ID_INLINE vec_t VectorLengthSquared( const vec3_t v ) { + return (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); +} + +static ID_INLINE vec_t Distance( const vec3_t p1, const vec3_t p2 ) { + vec3_t v; + + VectorSubtract (p2, p1, v); + return VectorLength( v ); +} + +static ID_INLINE vec_t DistanceSquared( const vec3_t p1, const vec3_t p2 ) { + vec3_t v; + + VectorSubtract (p2, p1, v); + return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; +} + +// fast vector normalize routine that does not check to make sure +// that length != 0, nor does it return length, uses rsqrt approximation +static ID_INLINE void VectorNormalizeFast( vec3_t v ) +{ + float ilength; + + ilength = Q_rsqrt( DotProduct( v, v ) ); + + v[0] *= ilength; + v[1] *= ilength; + v[2] *= ilength; +} + +static ID_INLINE void VectorInverse( vec3_t v ){ + v[0] = -v[0]; + v[1] = -v[1]; + v[2] = -v[2]; +} + +static ID_INLINE void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross ) { + cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; + cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; + cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; +} + +#else int VectorCompare( const vec3_t v1, const vec3_t v2 ); + vec_t VectorLength( const vec3_t v ); + vec_t VectorLengthSquared( const vec3_t v ); + vec_t Distance( const vec3_t p1, const vec3_t p2 ); + vec_t DistanceSquared( const vec3_t p1, const vec3_t p2 ); + +void VectorNormalizeFast( vec3_t v ); + +void VectorInverse( vec3_t v ); + void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross ); + +#endif + vec_t VectorNormalize (vec3_t v); // returns vector length -void VectorNormalizeFast(vec3_t v); // does NOT return vector length, uses rsqrt approximation vec_t VectorNormalize2( const vec3_t v, vec3_t out ); -void VectorInverse (vec3_t v); void Vector4Scale( const vec4_t in, vec_t scale, vec4_t out ); void VectorRotate( vec3_t in, vec3_t matrix[3], vec3_t out ); int Q_log2(int val); @@ -640,17 +855,18 @@ typedef struct } qint64; //============================================= - +/* short BigShort(short l); short LittleShort(short l); int BigLong (int l); int LittleLong (int l); qint64 BigLong64 (qint64 l); qint64 LittleLong64 (qint64 l); -float BigFloat (float l); -float LittleFloat (float l); +float BigFloat (const float *l); +float LittleFloat (const float *l); void Swap_Init (void); +*/ char * QDECL va(char *format, ...); //============================================= @@ -1168,7 +1384,7 @@ typedef enum _flag_status { #define MAX_GLOBAL_SERVERS 2048 #define MAX_OTHER_SERVERS 128 -#define MAX_PINGREQUESTS 16 +#define MAX_PINGREQUESTS 32 #define MAX_SERVERSTATUSREQUESTS 16 #define SAY_ALL 0 diff --git a/reaction/game/surfaceflags.h b/reaction/game/surfaceflags.h index 9b660e26..0e01898a 100644 --- a/reaction/game/surfaceflags.h +++ b/reaction/game/surfaceflags.h @@ -13,6 +13,10 @@ #define CONTENTS_WATER 32 #define CONTENTS_FOG 64 +#define CONTENTS_NOTTEAM1 0x0080 +#define CONTENTS_NOTTEAM2 0x0100 +#define CONTENTS_NOBOTCLIP 0x0200 + #define CONTENTS_AREAPORTAL 0x8000 #define CONTENTS_PLAYERCLIP 0x10000