Merge to 1.29h

This commit is contained in:
Scott Brooks 2001-08-01 19:52:17 +00:00
parent 00a4ce5710
commit f8729be656
40 changed files with 963 additions and 480 deletions

View file

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

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 ) {

View file

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

View file

@ -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 );
}

View file

@ -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 );

View file

@ -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];

View file

@ -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 ];

View file

@ -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 );

View file

@ -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;
}

View file

@ -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);

View file

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

View file

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

View file

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

View file

@ -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;
}

View file

@ -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;
*/

View file

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

View file

@ -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 );

View file

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

View file

@ -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;
}

View file

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

View file

@ -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;
}

View file

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

View file

@ -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 );
}

View file

@ -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++;

View file

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

View file

@ -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
/*
================

View file

@ -6,13 +6,47 @@
--------------------Configuration: game - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
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"
<h3>Output Window</h3>
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.
<h3>Results</h3>
qagamex86.dll - 6 error(s), 0 warning(s)
qagamex86.dll - 0 error(s), 1 warning(s)
</pre>
</body>
</html>

View file

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

View file

@ -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);
}
/*

View file

@ -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 <MacTypes.h>
#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

View file

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