MISSIONPACK removal: game project.
This commit is contained in:
parent
1a7b937688
commit
ce736c68e2
|
|
@ -52,11 +52,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#include "syn.h" //synonyms
|
#include "syn.h" //synonyms
|
||||||
#include "match.h" //string matching types and vars
|
#include "match.h" //string matching types and vars
|
||||||
|
|
||||||
// for the voice chats
|
|
||||||
#ifdef MISSIONPACK // bk001205
|
|
||||||
#include "../../ui/menudef.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TIME_BETWEENCHATTING 25
|
#define TIME_BETWEENCHATTING 25
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -293,13 +288,6 @@ char *BotWeaponNameForMeansOfDeath(int mod) {
|
||||||
case MOD_LIGHTNING: return "Lightning Gun";
|
case MOD_LIGHTNING: return "Lightning Gun";
|
||||||
case MOD_BFG:
|
case MOD_BFG:
|
||||||
case MOD_BFG_SPLASH: return "BFG10K";
|
case MOD_BFG_SPLASH: return "BFG10K";
|
||||||
#ifdef MISSIONPACK
|
|
||||||
case MOD_NAIL: return "Nailgun";
|
|
||||||
case MOD_CHAINGUN: return "Chaingun";
|
|
||||||
case MOD_PROXIMITY_MINE: return "Proximity Launcher";
|
|
||||||
case MOD_KAMIKAZE: return "Kamikaze";
|
|
||||||
case MOD_JUICED: return "Prox mine";
|
|
||||||
#endif
|
|
||||||
case MOD_GRAPPLE: return "Grapple";
|
case MOD_GRAPPLE: return "Grapple";
|
||||||
default: return "[unknown weapon]";
|
default: return "[unknown weapon]";
|
||||||
}
|
}
|
||||||
|
|
@ -311,13 +299,8 @@ BotRandomWeaponName
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
char *BotRandomWeaponName(void) {
|
char *BotRandomWeaponName(void) {
|
||||||
int rnd;
|
int rnd = random() * 8.9;
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
rnd = random() * 11.9;
|
|
||||||
#else
|
|
||||||
rnd = random() * 8.9;
|
|
||||||
#endif
|
|
||||||
switch(rnd) {
|
switch(rnd) {
|
||||||
case 0: return "Gauntlet";
|
case 0: return "Gauntlet";
|
||||||
case 1: return "Shotgun";
|
case 1: return "Shotgun";
|
||||||
|
|
@ -327,11 +310,6 @@ char *BotRandomWeaponName(void) {
|
||||||
case 5: return "Plasmagun";
|
case 5: return "Plasmagun";
|
||||||
case 6: return "Railgun";
|
case 6: return "Railgun";
|
||||||
case 7: return "Lightning Gun";
|
case 7: return "Lightning Gun";
|
||||||
#ifdef MISSIONPACK
|
|
||||||
case 8: return "Nailgun";
|
|
||||||
case 9: return "Chaingun";
|
|
||||||
case 10: return "Proximity Launcher";
|
|
||||||
#endif
|
|
||||||
default: return "BFG10K";
|
default: return "BFG10K";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -620,10 +598,6 @@ int BotChat_Death(bot_state_t *bs) {
|
||||||
BotAI_BotInitialChat(bs, "death_suicide", BotRandomOpponentName(bs), NULL);
|
BotAI_BotInitialChat(bs, "death_suicide", BotRandomOpponentName(bs), NULL);
|
||||||
else if (bs->botdeathtype == MOD_TELEFRAG)
|
else if (bs->botdeathtype == MOD_TELEFRAG)
|
||||||
BotAI_BotInitialChat(bs, "death_telefrag", name, NULL);
|
BotAI_BotInitialChat(bs, "death_telefrag", name, NULL);
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (bs->botdeathtype == MOD_KAMIKAZE && trap_BotNumInitialChats(bs->cs, "death_kamikaze"))
|
|
||||||
BotAI_BotInitialChat(bs, "death_kamikaze", name, NULL);
|
|
||||||
#endif
|
|
||||||
else {
|
else {
|
||||||
if ((bs->botdeathtype == MOD_GAUNTLET ||
|
if ((bs->botdeathtype == MOD_GAUNTLET ||
|
||||||
bs->botdeathtype == MOD_RAILGUN ||
|
bs->botdeathtype == MOD_RAILGUN ||
|
||||||
|
|
@ -714,10 +688,6 @@ int BotChat_Kill(bot_state_t *bs) {
|
||||||
else if (bs->enemydeathtype == MOD_TELEFRAG) {
|
else if (bs->enemydeathtype == MOD_TELEFRAG) {
|
||||||
BotAI_BotInitialChat(bs, "kill_telefrag", name, NULL);
|
BotAI_BotInitialChat(bs, "kill_telefrag", name, NULL);
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (bs->botdeathtype == MOD_KAMIKAZE && trap_BotNumInitialChats(bs->cs, "kill_kamikaze"))
|
|
||||||
BotAI_BotInitialChat(bs, "kill_kamikaze", name, NULL);
|
|
||||||
#endif
|
|
||||||
//choose between insult and praise
|
//choose between insult and praise
|
||||||
else if (random() < trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_INSULT, 0, 1)) {
|
else if (random() < trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_INSULT, 0, 1)) {
|
||||||
BotAI_BotInitialChat(bs, "kill_insult", name, NULL);
|
BotAI_BotInitialChat(bs, "kill_insult", name, NULL);
|
||||||
|
|
|
||||||
|
|
@ -96,18 +96,6 @@ void BotPrintTeamGoal(bot_state_t *bs) {
|
||||||
BotAI_Print(PRT_MESSAGE, "%s: I'm gonna try to return the flag for %1.0f secs\n", netname, t);
|
BotAI_Print(PRT_MESSAGE, "%s: I'm gonna try to return the flag for %1.0f secs\n", netname, t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
case LTG_ATTACKENEMYBASE:
|
|
||||||
{
|
|
||||||
BotAI_Print(PRT_MESSAGE, "%s: I'm gonna attack the enemy base for %1.0f secs\n", netname, t);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LTG_HARVEST:
|
|
||||||
{
|
|
||||||
BotAI_Print(PRT_MESSAGE, "%s: I'm gonna harvest for %1.0f secs\n", netname, t);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case LTG_DEFENDKEYAREA:
|
case LTG_DEFENDKEYAREA:
|
||||||
{
|
{
|
||||||
BotAI_Print(PRT_MESSAGE, "%s: I'm gonna defend a key area for %1.0f secs\n", netname, t);
|
BotAI_Print(PRT_MESSAGE, "%s: I'm gonna defend a key area for %1.0f secs\n", netname, t);
|
||||||
|
|
@ -834,12 +822,6 @@ void BotMatch_GetFlag(bot_state_t *bs, bot_match_t *match) {
|
||||||
if (!ctf_redflag.areanum || !ctf_blueflag.areanum)
|
if (!ctf_redflag.areanum || !ctf_blueflag.areanum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (gametype == GT_1FCTF) {
|
|
||||||
if (!ctf_neutralflag.areanum || !ctf_redflag.areanum || !ctf_blueflag.areanum)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -885,12 +867,6 @@ void BotMatch_AttackEnemyBase(bot_state_t *bs, bot_match_t *match) {
|
||||||
if (gametype == GT_CTF) {
|
if (gametype == GT_CTF) {
|
||||||
BotMatch_GetFlag(bs, match);
|
BotMatch_GetFlag(bs, match);
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (gametype == GT_1FCTF || gametype == GT_OBELISK || gametype == GT_HARVESTER) {
|
|
||||||
if (!redobelisk.areanum || !blueobelisk.areanum)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -920,50 +896,6 @@ void BotMatch_AttackEnemyBase(bot_state_t *bs, bot_match_t *match) {
|
||||||
#endif //DEBUG
|
#endif //DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
BotMatch_Harvest
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
void BotMatch_Harvest(bot_state_t *bs, bot_match_t *match) {
|
|
||||||
char netname[MAX_MESSAGE_SIZE];
|
|
||||||
int client;
|
|
||||||
|
|
||||||
if (gametype == GT_HARVESTER) {
|
|
||||||
if (!neutralobelisk.areanum || !redobelisk.areanum || !blueobelisk.areanum)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//if not addressed to this bot
|
|
||||||
if (!BotAddressedToBot(bs, match)) return;
|
|
||||||
//
|
|
||||||
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
|
|
||||||
//
|
|
||||||
client = FindClientByName(netname);
|
|
||||||
//
|
|
||||||
bs->decisionmaker = client;
|
|
||||||
bs->ordered = qtrue;
|
|
||||||
bs->order_time = FloatTime();
|
|
||||||
//set the time to send a message to the team mates
|
|
||||||
bs->teammessage_time = FloatTime() + 2 * random();
|
|
||||||
//set the ltg type
|
|
||||||
bs->ltgtype = LTG_HARVEST;
|
|
||||||
//set the team goal time
|
|
||||||
bs->teamgoal_time = FloatTime() + TEAM_HARVEST_TIME;
|
|
||||||
bs->harvestaway_time = 0;
|
|
||||||
//
|
|
||||||
BotSetTeamStatus(bs);
|
|
||||||
// remember last ordered task
|
|
||||||
BotRememberLastOrderedTask(bs);
|
|
||||||
#ifdef DEBUG
|
|
||||||
BotPrintTeamGoal(bs);
|
|
||||||
#endif //DEBUG
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
BotMatch_RushBase
|
BotMatch_RushBase
|
||||||
|
|
@ -977,12 +909,6 @@ void BotMatch_RushBase(bot_state_t *bs, bot_match_t *match) {
|
||||||
if (!ctf_redflag.areanum || !ctf_blueflag.areanum)
|
if (!ctf_redflag.areanum || !ctf_blueflag.areanum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (gametype == GT_1FCTF || gametype == GT_HARVESTER) {
|
|
||||||
if (!redobelisk.areanum || !blueobelisk.areanum)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1069,9 +995,6 @@ void BotMatch_ReturnFlag(bot_state_t *bs, bot_match_t *match) {
|
||||||
//if not in CTF mode
|
//if not in CTF mode
|
||||||
if (
|
if (
|
||||||
gametype != GT_CTF
|
gametype != GT_CTF
|
||||||
#ifdef MISSIONPACK
|
|
||||||
&& gametype != GT_1FCTF
|
|
||||||
#endif
|
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
//if not addressed to this bot
|
//if not addressed to this bot
|
||||||
|
|
@ -1436,18 +1359,6 @@ void BotMatch_WhatAreYouDoing(bot_state_t *bs, bot_match_t *match) {
|
||||||
BotAI_BotInitialChat(bs, "returningflag", NULL);
|
BotAI_BotInitialChat(bs, "returningflag", NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
case LTG_ATTACKENEMYBASE:
|
|
||||||
{
|
|
||||||
BotAI_BotInitialChat(bs, "attackingenemybase", NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LTG_HARVEST:
|
|
||||||
{
|
|
||||||
BotAI_BotInitialChat(bs, "harvesting", NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
BotAI_BotInitialChat(bs, "roaming", NULL);
|
BotAI_BotInitialChat(bs, "roaming", NULL);
|
||||||
|
|
@ -1535,19 +1446,6 @@ void BotMatch_WhereAreYou(bot_state_t *bs, bot_match_t *match) {
|
||||||
"Heavy Armor",
|
"Heavy Armor",
|
||||||
"Red Flag",
|
"Red Flag",
|
||||||
"Blue Flag",
|
"Blue Flag",
|
||||||
#ifdef MISSIONPACK
|
|
||||||
"Nailgun",
|
|
||||||
"Prox Launcher",
|
|
||||||
"Chaingun",
|
|
||||||
"Scout",
|
|
||||||
"Guard",
|
|
||||||
"Doubler",
|
|
||||||
"Ammo Regen",
|
|
||||||
"Neutral Flag",
|
|
||||||
"Red Obelisk",
|
|
||||||
"Blue Obelisk",
|
|
||||||
"Neutral Obelisk",
|
|
||||||
#endif
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
|
|
@ -1568,9 +1466,6 @@ void BotMatch_WhereAreYou(bot_state_t *bs, bot_match_t *match) {
|
||||||
}
|
}
|
||||||
if (bestitem != -1) {
|
if (bestitem != -1) {
|
||||||
if (gametype == GT_CTF
|
if (gametype == GT_CTF
|
||||||
#ifdef MISSIONPACK
|
|
||||||
|| gametype == GT_1FCTF
|
|
||||||
#endif
|
|
||||||
) {
|
) {
|
||||||
redtt = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, ctf_redflag.areanum, TFL_DEFAULT);
|
redtt = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, ctf_redflag.areanum, TFL_DEFAULT);
|
||||||
bluett = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, ctf_blueflag.areanum, TFL_DEFAULT);
|
bluett = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, ctf_blueflag.areanum, TFL_DEFAULT);
|
||||||
|
|
@ -1584,21 +1479,6 @@ void BotMatch_WhereAreYou(bot_state_t *bs, bot_match_t *match) {
|
||||||
BotAI_BotInitialChat(bs, "location", nearbyitems[bestitem], NULL);
|
BotAI_BotInitialChat(bs, "location", nearbyitems[bestitem], NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (gametype == GT_OBELISK || gametype == GT_HARVESTER) {
|
|
||||||
redtt = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, redobelisk.areanum, TFL_DEFAULT);
|
|
||||||
bluett = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, blueobelisk.areanum, TFL_DEFAULT);
|
|
||||||
if (redtt < (redtt + bluett) * 0.4) {
|
|
||||||
BotAI_BotInitialChat(bs, "teamlocation", nearbyitems[bestitem], "red", NULL);
|
|
||||||
}
|
|
||||||
else if (bluett < (redtt + bluett) * 0.4) {
|
|
||||||
BotAI_BotInitialChat(bs, "teamlocation", nearbyitems[bestitem], "blue", NULL);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BotAI_BotInitialChat(bs, "location", nearbyitems[bestitem], NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
else {
|
||||||
BotAI_BotInitialChat(bs, "location", nearbyitems[bestitem], NULL);
|
BotAI_BotInitialChat(bs, "location", nearbyitems[bestitem], NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -1756,14 +1636,6 @@ void BotMatch_CTF(bot_state_t *bs, bot_match_t *match) {
|
||||||
bs->flagstatuschanged = 1;
|
bs->flagstatuschanged = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (gametype == GT_1FCTF) {
|
|
||||||
if (match->subtype & ST_1FCTFGOTFLAG) {
|
|
||||||
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
|
|
||||||
bs->flagcarrier = ClientFromName(netname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotMatch_EnterGame(bot_state_t *bs, bot_match_t *match) {
|
void BotMatch_EnterGame(bot_state_t *bs, bot_match_t *match) {
|
||||||
|
|
@ -1836,20 +1708,6 @@ int BotMatchMessage(bot_state_t *bs, char *message) {
|
||||||
BotMatch_GetFlag(bs, &match);
|
BotMatch_GetFlag(bs, &match);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
//CTF & 1FCTF & Obelisk & Harvester
|
|
||||||
case MSG_ATTACKENEMYBASE:
|
|
||||||
{
|
|
||||||
BotMatch_AttackEnemyBase(bs, &match);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//Harvester
|
|
||||||
case MSG_HARVEST:
|
|
||||||
{
|
|
||||||
BotMatch_Harvest(bs, &match);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//CTF & 1FCTF & Harvester
|
//CTF & 1FCTF & Harvester
|
||||||
case MSG_RUSHBASE: //ctf rush to the base
|
case MSG_RUSHBASE: //ctf rush to the base
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -833,203 +833,6 @@ int BotGetLongTermGoal(bot_state_t *bs, int tfl, int retreat, bot_goal_t *goal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif //CTF
|
#endif //CTF
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (gametype == GT_1FCTF) {
|
|
||||||
if (bs->ltgtype == LTG_GETFLAG) {
|
|
||||||
//check for bot typing status message
|
|
||||||
if (bs->teammessage_time && bs->teammessage_time < FloatTime()) {
|
|
||||||
BotAI_BotInitialChat(bs, "captureflag_start", NULL);
|
|
||||||
trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
|
|
||||||
BotVoiceChatOnly(bs, -1, VOICECHAT_ONGETFLAG);
|
|
||||||
bs->teammessage_time = 0;
|
|
||||||
}
|
|
||||||
memcpy(goal, &ctf_neutralflag, sizeof(bot_goal_t));
|
|
||||||
//if touching the flag
|
|
||||||
if (trap_BotTouchingGoal(bs->origin, goal)) {
|
|
||||||
bs->ltgtype = 0;
|
|
||||||
}
|
|
||||||
//stop after 3 minutes
|
|
||||||
if (bs->teamgoal_time < FloatTime()) {
|
|
||||||
bs->ltgtype = 0;
|
|
||||||
}
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
//if rushing to the base
|
|
||||||
if (bs->ltgtype == LTG_RUSHBASE) {
|
|
||||||
switch(BotTeam(bs)) {
|
|
||||||
case TEAM_RED: memcpy(goal, &ctf_blueflag, sizeof(bot_goal_t)); break;
|
|
||||||
case TEAM_BLUE: memcpy(goal, &ctf_redflag, sizeof(bot_goal_t)); break;
|
|
||||||
default: bs->ltgtype = 0; return qfalse;
|
|
||||||
}
|
|
||||||
//if not carrying the flag anymore
|
|
||||||
if (!Bot1FCTFCarryingFlag(bs)) {
|
|
||||||
bs->ltgtype = 0;
|
|
||||||
}
|
|
||||||
//quit rushing after 2 minutes
|
|
||||||
if (bs->teamgoal_time < FloatTime()) {
|
|
||||||
bs->ltgtype = 0;
|
|
||||||
}
|
|
||||||
//if touching the base flag the bot should loose the enemy flag
|
|
||||||
if (trap_BotTouchingGoal(bs->origin, goal)) {
|
|
||||||
bs->ltgtype = 0;
|
|
||||||
}
|
|
||||||
BotAlternateRoute(bs, goal);
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
//attack the enemy base
|
|
||||||
if (bs->ltgtype == LTG_ATTACKENEMYBASE &&
|
|
||||||
bs->attackaway_time < FloatTime()) {
|
|
||||||
//check for bot typing status message
|
|
||||||
if (bs->teammessage_time && bs->teammessage_time < FloatTime()) {
|
|
||||||
BotAI_BotInitialChat(bs, "attackenemybase_start", NULL);
|
|
||||||
trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
|
|
||||||
BotVoiceChatOnly(bs, -1, VOICECHAT_ONOFFENSE);
|
|
||||||
bs->teammessage_time = 0;
|
|
||||||
}
|
|
||||||
switch(BotTeam(bs)) {
|
|
||||||
case TEAM_RED: memcpy(goal, &ctf_blueflag, sizeof(bot_goal_t)); break;
|
|
||||||
case TEAM_BLUE: memcpy(goal, &ctf_redflag, sizeof(bot_goal_t)); break;
|
|
||||||
default: bs->ltgtype = 0; return qfalse;
|
|
||||||
}
|
|
||||||
//quit rushing after 2 minutes
|
|
||||||
if (bs->teamgoal_time < FloatTime()) {
|
|
||||||
bs->ltgtype = 0;
|
|
||||||
}
|
|
||||||
//if touching the base flag the bot should loose the enemy flag
|
|
||||||
if (trap_BotTouchingGoal(bs->origin, goal)) {
|
|
||||||
bs->attackaway_time = FloatTime() + 2 + 5 * random();
|
|
||||||
}
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
//returning flag
|
|
||||||
if (bs->ltgtype == LTG_RETURNFLAG) {
|
|
||||||
//check for bot typing status message
|
|
||||||
if (bs->teammessage_time && bs->teammessage_time < FloatTime()) {
|
|
||||||
BotAI_BotInitialChat(bs, "returnflag_start", NULL);
|
|
||||||
trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
|
|
||||||
BotVoiceChatOnly(bs, -1, VOICECHAT_ONRETURNFLAG);
|
|
||||||
bs->teammessage_time = 0;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if (bs->teamgoal_time < FloatTime()) {
|
|
||||||
bs->ltgtype = 0;
|
|
||||||
}
|
|
||||||
//just roam around
|
|
||||||
return BotGetItemLongTermGoal(bs, tfl, goal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (gametype == GT_OBELISK) {
|
|
||||||
if (bs->ltgtype == LTG_ATTACKENEMYBASE &&
|
|
||||||
bs->attackaway_time < FloatTime()) {
|
|
||||||
|
|
||||||
//check for bot typing status message
|
|
||||||
if (bs->teammessage_time && bs->teammessage_time < FloatTime()) {
|
|
||||||
BotAI_BotInitialChat(bs, "attackenemybase_start", NULL);
|
|
||||||
trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
|
|
||||||
BotVoiceChatOnly(bs, -1, VOICECHAT_ONOFFENSE);
|
|
||||||
bs->teammessage_time = 0;
|
|
||||||
}
|
|
||||||
switch(BotTeam(bs)) {
|
|
||||||
case TEAM_RED: memcpy(goal, &blueobelisk, sizeof(bot_goal_t)); break;
|
|
||||||
case TEAM_BLUE: memcpy(goal, &redobelisk, sizeof(bot_goal_t)); break;
|
|
||||||
default: bs->ltgtype = 0; return qfalse;
|
|
||||||
}
|
|
||||||
//if the bot no longer wants to attack the obelisk
|
|
||||||
if (BotFeelingBad(bs) > 50) {
|
|
||||||
return BotGetItemLongTermGoal(bs, tfl, goal);
|
|
||||||
}
|
|
||||||
//if touching the obelisk
|
|
||||||
if (trap_BotTouchingGoal(bs->origin, goal)) {
|
|
||||||
bs->attackaway_time = FloatTime() + 3 + 5 * random();
|
|
||||||
}
|
|
||||||
// or very close to the obelisk
|
|
||||||
VectorSubtract(bs->origin, goal->origin, dir);
|
|
||||||
if (VectorLengthSquared(dir) < Square(60)) {
|
|
||||||
bs->attackaway_time = FloatTime() + 3 + 5 * random();
|
|
||||||
}
|
|
||||||
//quit rushing after 2 minutes
|
|
||||||
if (bs->teamgoal_time < FloatTime()) {
|
|
||||||
bs->ltgtype = 0;
|
|
||||||
}
|
|
||||||
BotAlternateRoute(bs, goal);
|
|
||||||
//just move towards the obelisk
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (gametype == GT_HARVESTER) {
|
|
||||||
//if rushing to the base
|
|
||||||
if (bs->ltgtype == LTG_RUSHBASE) {
|
|
||||||
switch(BotTeam(bs)) {
|
|
||||||
case TEAM_RED: memcpy(goal, &blueobelisk, sizeof(bot_goal_t)); break;
|
|
||||||
case TEAM_BLUE: memcpy(goal, &redobelisk, sizeof(bot_goal_t)); break;
|
|
||||||
default: BotGoHarvest(bs); return qfalse;
|
|
||||||
}
|
|
||||||
//if not carrying any cubes
|
|
||||||
if (!BotHarvesterCarryingCubes(bs)) {
|
|
||||||
BotGoHarvest(bs);
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
//quit rushing after 2 minutes
|
|
||||||
if (bs->teamgoal_time < FloatTime()) {
|
|
||||||
BotGoHarvest(bs);
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
//if touching the base flag the bot should loose the enemy flag
|
|
||||||
if (trap_BotTouchingGoal(bs->origin, goal)) {
|
|
||||||
BotGoHarvest(bs);
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
BotAlternateRoute(bs, goal);
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
//attack the enemy base
|
|
||||||
if (bs->ltgtype == LTG_ATTACKENEMYBASE &&
|
|
||||||
bs->attackaway_time < FloatTime()) {
|
|
||||||
//check for bot typing status message
|
|
||||||
if (bs->teammessage_time && bs->teammessage_time < FloatTime()) {
|
|
||||||
BotAI_BotInitialChat(bs, "attackenemybase_start", NULL);
|
|
||||||
trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
|
|
||||||
BotVoiceChatOnly(bs, -1, VOICECHAT_ONOFFENSE);
|
|
||||||
bs->teammessage_time = 0;
|
|
||||||
}
|
|
||||||
switch(BotTeam(bs)) {
|
|
||||||
case TEAM_RED: memcpy(goal, &blueobelisk, sizeof(bot_goal_t)); break;
|
|
||||||
case TEAM_BLUE: memcpy(goal, &redobelisk, sizeof(bot_goal_t)); break;
|
|
||||||
default: bs->ltgtype = 0; return qfalse;
|
|
||||||
}
|
|
||||||
//quit rushing after 2 minutes
|
|
||||||
if (bs->teamgoal_time < FloatTime()) {
|
|
||||||
bs->ltgtype = 0;
|
|
||||||
}
|
|
||||||
//if touching the base flag the bot should loose the enemy flag
|
|
||||||
if (trap_BotTouchingGoal(bs->origin, goal)) {
|
|
||||||
bs->attackaway_time = FloatTime() + 2 + 5 * random();
|
|
||||||
}
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
//harvest cubes
|
|
||||||
if (bs->ltgtype == LTG_HARVEST &&
|
|
||||||
bs->harvestaway_time < FloatTime()) {
|
|
||||||
//check for bot typing status message
|
|
||||||
if (bs->teammessage_time && bs->teammessage_time < FloatTime()) {
|
|
||||||
BotAI_BotInitialChat(bs, "harvest_start", NULL);
|
|
||||||
trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
|
|
||||||
BotVoiceChatOnly(bs, -1, VOICECHAT_ONOFFENSE);
|
|
||||||
bs->teammessage_time = 0;
|
|
||||||
}
|
|
||||||
memcpy(goal, &neutralobelisk, sizeof(bot_goal_t));
|
|
||||||
//
|
|
||||||
if (bs->teamgoal_time < FloatTime()) {
|
|
||||||
bs->ltgtype = 0;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if (trap_BotTouchingGoal(bs->origin, goal)) {
|
|
||||||
bs->harvestaway_time = FloatTime() + 4 + 3 * random();
|
|
||||||
}
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//normal goal stuff
|
//normal goal stuff
|
||||||
return BotGetItemLongTermGoal(bs, tfl, goal);
|
return BotGetItemLongTermGoal(bs, tfl, goal);
|
||||||
}
|
}
|
||||||
|
|
@ -1300,12 +1103,6 @@ int BotSelectActivateWeapon(bot_state_t *bs) {
|
||||||
return WEAPONINDEX_PLASMAGUN;
|
return WEAPONINDEX_PLASMAGUN;
|
||||||
else if (bs->inventory[INVENTORY_LIGHTNING] > 0 && bs->inventory[INVENTORY_LIGHTNINGAMMO] > 0)
|
else if (bs->inventory[INVENTORY_LIGHTNING] > 0 && bs->inventory[INVENTORY_LIGHTNINGAMMO] > 0)
|
||||||
return WEAPONINDEX_LIGHTNING;
|
return WEAPONINDEX_LIGHTNING;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (bs->inventory[INVENTORY_CHAINGUN] > 0 && bs->inventory[INVENTORY_BELT] > 0)
|
|
||||||
return WEAPONINDEX_CHAINGUN;
|
|
||||||
else if (bs->inventory[INVENTORY_NAILGUN] > 0 && bs->inventory[INVENTORY_NAILS] > 0)
|
|
||||||
return WEAPONINDEX_NAILGUN;
|
|
||||||
#endif
|
|
||||||
else if (bs->inventory[INVENTORY_RAILGUN] > 0 && bs->inventory[INVENTORY_SLUGS] > 0)
|
else if (bs->inventory[INVENTORY_RAILGUN] > 0 && bs->inventory[INVENTORY_SLUGS] > 0)
|
||||||
return WEAPONINDEX_RAILGUN;
|
return WEAPONINDEX_RAILGUN;
|
||||||
else if (bs->inventory[INVENTORY_ROCKETLAUNCHER] > 0 && bs->inventory[INVENTORY_ROCKETS] > 0)
|
else if (bs->inventory[INVENTORY_ROCKETLAUNCHER] > 0 && bs->inventory[INVENTORY_ROCKETS] > 0)
|
||||||
|
|
@ -1878,16 +1675,6 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
||||||
range = 50;
|
range = 50;
|
||||||
}
|
}
|
||||||
#endif //CTF
|
#endif //CTF
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (gametype == GT_1FCTF) {
|
|
||||||
if (Bot1FCTFCarryingFlag(bs))
|
|
||||||
range = 50;
|
|
||||||
}
|
|
||||||
else if (gametype == GT_HARVESTER) {
|
|
||||||
if (BotHarvesterCarryingCubes(bs))
|
|
||||||
range = 80;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//
|
//
|
||||||
if (BotNearbyGoal(bs, bs->tfl, &goal, range)) {
|
if (BotNearbyGoal(bs, bs->tfl, &goal, range)) {
|
||||||
trap_BotResetLastAvoidReach(bs->ms);
|
trap_BotResetLastAvoidReach(bs->ms);
|
||||||
|
|
@ -2051,13 +1838,6 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
||||||
VectorCopy(entinfo.origin, target);
|
VectorCopy(entinfo.origin, target);
|
||||||
// if not a player enemy
|
// if not a player enemy
|
||||||
if (bs->enemy >= MAX_CLIENTS) {
|
if (bs->enemy >= MAX_CLIENTS) {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
// if attacking an obelisk
|
|
||||||
if ( bs->enemy == redobelisk.entitynum ||
|
|
||||||
bs->enemy == blueobelisk.entitynum ) {
|
|
||||||
target[2] += 16;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
//update the reachability area and origin if possible
|
//update the reachability area and origin if possible
|
||||||
areanum = BotPointAreaNum(target);
|
areanum = BotPointAreaNum(target);
|
||||||
|
|
@ -2349,13 +2129,6 @@ int AINode_Battle_Retreat(bot_state_t *bs) {
|
||||||
VectorCopy(entinfo.origin, target);
|
VectorCopy(entinfo.origin, target);
|
||||||
// if not a player enemy
|
// if not a player enemy
|
||||||
if (bs->enemy >= MAX_CLIENTS) {
|
if (bs->enemy >= MAX_CLIENTS) {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
// if attacking an obelisk
|
|
||||||
if ( bs->enemy == redobelisk.entitynum ||
|
|
||||||
bs->enemy == blueobelisk.entitynum ) {
|
|
||||||
target[2] += 16;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
//update the reachability area and origin if possible
|
//update the reachability area and origin if possible
|
||||||
areanum = BotPointAreaNum(target);
|
areanum = BotPointAreaNum(target);
|
||||||
|
|
@ -2397,16 +2170,6 @@ int AINode_Battle_Retreat(bot_state_t *bs) {
|
||||||
range = 50;
|
range = 50;
|
||||||
}
|
}
|
||||||
#endif //CTF
|
#endif //CTF
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (gametype == GT_1FCTF) {
|
|
||||||
if (Bot1FCTFCarryingFlag(bs))
|
|
||||||
range = 50;
|
|
||||||
}
|
|
||||||
else if (gametype == GT_HARVESTER) {
|
|
||||||
if (BotHarvesterCarryingCubes(bs))
|
|
||||||
range = 80;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//
|
//
|
||||||
if (BotNearbyGoal(bs, bs->tfl, &goal, range)) {
|
if (BotNearbyGoal(bs, bs->tfl, &goal, range)) {
|
||||||
trap_BotResetLastAvoidReach(bs->ms);
|
trap_BotResetLastAvoidReach(bs->ms);
|
||||||
|
|
@ -2526,13 +2289,6 @@ int AINode_Battle_NBG(bot_state_t *bs) {
|
||||||
VectorCopy(entinfo.origin, target);
|
VectorCopy(entinfo.origin, target);
|
||||||
// if not a player enemy
|
// if not a player enemy
|
||||||
if (bs->enemy >= MAX_CLIENTS) {
|
if (bs->enemy >= MAX_CLIENTS) {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
// if attacking an obelisk
|
|
||||||
if ( bs->enemy == redobelisk.entitynum ||
|
|
||||||
bs->enemy == blueobelisk.entitynum ) {
|
|
||||||
target[2] += 16;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
//update the reachability area and origin if possible
|
//update the reachability area and origin if possible
|
||||||
areanum = BotPointAreaNum(target);
|
areanum = BotPointAreaNum(target);
|
||||||
|
|
|
||||||
1402
code/game/ai_dmq3.c
1402
code/game/ai_dmq3.c
File diff suppressed because it is too large
Load Diff
|
|
@ -62,10 +62,6 @@ qboolean EntityIsDead(aas_entityinfo_t *entinfo);
|
||||||
qboolean EntityIsInvisible(aas_entityinfo_t *entinfo);
|
qboolean EntityIsInvisible(aas_entityinfo_t *entinfo);
|
||||||
//returns true if the entity is shooting
|
//returns true if the entity is shooting
|
||||||
qboolean EntityIsShooting(aas_entityinfo_t *entinfo);
|
qboolean EntityIsShooting(aas_entityinfo_t *entinfo);
|
||||||
#ifdef MISSIONPACK
|
|
||||||
//returns true if this entity has the kamikaze
|
|
||||||
qboolean EntityHasKamikaze(aas_entityinfo_t *entinfo);
|
|
||||||
#endif
|
|
||||||
// set a user info key/value pair
|
// set a user info key/value pair
|
||||||
void BotSetUserInfo(bot_state_t *bs, char *key, char *value);
|
void BotSetUserInfo(bot_state_t *bs, char *key, char *value);
|
||||||
// set the team status (offense, defense etc.)
|
// set the team status (offense, defense etc.)
|
||||||
|
|
@ -146,20 +142,6 @@ void BotRememberLastOrderedTask(bot_state_t *bs);
|
||||||
void BotCTFSeekGoals(bot_state_t *bs);
|
void BotCTFSeekGoals(bot_state_t *bs);
|
||||||
//set ctf goals (defend base, get enemy flag) during retreat
|
//set ctf goals (defend base, get enemy flag) during retreat
|
||||||
void BotCTFRetreatGoals(bot_state_t *bs);
|
void BotCTFRetreatGoals(bot_state_t *bs);
|
||||||
//
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
int Bot1FCTFCarryingFlag(bot_state_t *bs);
|
|
||||||
int BotHarvesterCarryingCubes(bot_state_t *bs);
|
|
||||||
void Bot1FCTFSeekGoals(bot_state_t *bs);
|
|
||||||
void Bot1FCTFRetreatGoals(bot_state_t *bs);
|
|
||||||
void BotObeliskSeekGoals(bot_state_t *bs);
|
|
||||||
void BotObeliskRetreatGoals(bot_state_t *bs);
|
|
||||||
void BotGoHarvest(bot_state_t *bs);
|
|
||||||
void BotHarvesterSeekGoals(bot_state_t *bs);
|
|
||||||
void BotHarvesterRetreatGoals(bot_state_t *bs);
|
|
||||||
int BotTeamCubeCarrierVisible(bot_state_t *bs);
|
|
||||||
int BotEnemyCubeCarrierVisible(bot_state_t *bs);
|
|
||||||
#endif
|
|
||||||
//get a random alternate route goal towards the given base
|
//get a random alternate route goal towards the given base
|
||||||
int BotGetAlternateRouteGoal(bot_state_t *bs, int base);
|
int BotGetAlternateRouteGoal(bot_state_t *bs, int base);
|
||||||
//returns either the alternate route goal or the given goal
|
//returns either the alternate route goal or the given goal
|
||||||
|
|
@ -198,9 +180,3 @@ extern vmCvar_t bot_challenge;
|
||||||
|
|
||||||
extern bot_goal_t ctf_redflag;
|
extern bot_goal_t ctf_redflag;
|
||||||
extern bot_goal_t ctf_blueflag;
|
extern bot_goal_t ctf_blueflag;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
extern bot_goal_t ctf_neutralflag;
|
|
||||||
extern bot_goal_t redobelisk;
|
|
||||||
extern bot_goal_t blueobelisk;
|
|
||||||
extern bot_goal_t neutralobelisk;
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|
|
@ -289,20 +289,6 @@ void BotReportStatus(bot_state_t *bs) {
|
||||||
else strcpy(flagstatus, S_COLOR_BLUE"F ");
|
else strcpy(flagstatus, S_COLOR_BLUE"F ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (gametype == GT_1FCTF) {
|
|
||||||
if (Bot1FCTFCarryingFlag(bs)) {
|
|
||||||
if (BotTeam(bs) == TEAM_RED) strcpy(flagstatus, S_COLOR_RED"F ");
|
|
||||||
else strcpy(flagstatus, S_COLOR_BLUE"F ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (gametype == GT_HARVESTER) {
|
|
||||||
if (BotHarvesterCarryingCubes(bs)) {
|
|
||||||
if (BotTeam(bs) == TEAM_RED) Com_sprintf(flagstatus, sizeof(flagstatus), S_COLOR_RED"%2d", bs->inventory[INVENTORY_REDCUBE]);
|
|
||||||
else Com_sprintf(flagstatus, sizeof(flagstatus), S_COLOR_BLUE"%2d", bs->inventory[INVENTORY_BLUECUBE]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch(bs->ltgtype) {
|
switch(bs->ltgtype) {
|
||||||
case LTG_TEAMHELP:
|
case LTG_TEAMHELP:
|
||||||
|
|
@ -438,19 +424,6 @@ void BotSetInfoConfigString(bot_state_t *bs) {
|
||||||
strcpy(carrying, "F ");
|
strcpy(carrying, "F ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (gametype == GT_1FCTF) {
|
|
||||||
if (Bot1FCTFCarryingFlag(bs)) {
|
|
||||||
strcpy(carrying, "F ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (gametype == GT_HARVESTER) {
|
|
||||||
if (BotHarvesterCarryingCubes(bs)) {
|
|
||||||
if (BotTeam(bs) == TEAM_RED) Com_sprintf(carrying, sizeof(carrying), "%2d", bs->inventory[INVENTORY_REDCUBE]);
|
|
||||||
else Com_sprintf(carrying, sizeof(carrying), "%2d", bs->inventory[INVENTORY_BLUECUBE]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch(bs->ltgtype) {
|
switch(bs->ltgtype) {
|
||||||
case LTG_TEAMHELP:
|
case LTG_TEAMHELP:
|
||||||
|
|
@ -1006,17 +979,6 @@ int BotAI(int client, float thinktime) {
|
||||||
args[strlen(args)-1] = '\0';
|
args[strlen(args)-1] = '\0';
|
||||||
trap_BotQueueConsoleMessage(bs->cs, CMS_CHAT, args);
|
trap_BotQueueConsoleMessage(bs->cs, CMS_CHAT, args);
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (!Q_stricmp(buf, "vchat")) {
|
|
||||||
BotVoiceChatCommand(bs, SAY_ALL, args);
|
|
||||||
}
|
|
||||||
else if (!Q_stricmp(buf, "vtchat")) {
|
|
||||||
BotVoiceChatCommand(bs, SAY_TEAM, args);
|
|
||||||
}
|
|
||||||
else if (!Q_stricmp(buf, "vtell")) {
|
|
||||||
BotVoiceChatCommand(bs, SAY_TELL, args);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else if (!Q_stricmp(buf, "scores"))
|
else if (!Q_stricmp(buf, "scores"))
|
||||||
{ /*FIXME: parse scores?*/ }
|
{ /*FIXME: parse scores?*/ }
|
||||||
else if (!Q_stricmp(buf, "clientLevelShot"))
|
else if (!Q_stricmp(buf, "clientLevelShot"))
|
||||||
|
|
@ -1365,10 +1327,6 @@ int BotAILoadMap( int restart ) {
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
void ProximityMine_Trigger( gentity_t *trigger, gentity_t *other, trace_t *trace );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
BotAIStartFrame
|
BotAIStartFrame
|
||||||
|
|
@ -1482,15 +1440,6 @@ int BotAIStartFrame(int time) {
|
||||||
trap_BotLibUpdateEntity(i, NULL);
|
trap_BotLibUpdateEntity(i, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
// never link prox mine triggers
|
|
||||||
if (ent->r.contents == CONTENTS_TRIGGER) {
|
|
||||||
if (ent->touch == ProximityMine_Trigger) {
|
|
||||||
trap_BotLibUpdateEntity(i, NULL);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//
|
//
|
||||||
memset(&state, 0, sizeof(bot_entitystate_t));
|
memset(&state, 0, sizeof(bot_entitystate_t));
|
||||||
//
|
//
|
||||||
|
|
@ -1626,10 +1575,6 @@ int BotInitLibrary(void) {
|
||||||
//cd directory
|
//cd directory
|
||||||
trap_Cvar_VariableStringBuffer("fs_cdpath", buf, sizeof(buf));
|
trap_Cvar_VariableStringBuffer("fs_cdpath", buf, sizeof(buf));
|
||||||
if (strlen(buf)) trap_BotLibVarSet("cddir", buf);
|
if (strlen(buf)) trap_BotLibVarSet("cddir", buf);
|
||||||
//
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
trap_BotLibDefine("MISSIONPACK");
|
|
||||||
#endif
|
|
||||||
//setup the bot library
|
//setup the bot library
|
||||||
return trap_BotLibSetup();
|
return trap_BotLibSetup();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1047
code/game/ai_team.c
1047
code/game/ai_team.c
File diff suppressed because it is too large
Load Diff
|
|
@ -75,12 +75,6 @@ void BotVoiceChat_GetFlag(bot_state_t *bs, int client, int mode) {
|
||||||
if (!ctf_redflag.areanum || !ctf_blueflag.areanum)
|
if (!ctf_redflag.areanum || !ctf_blueflag.areanum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if (gametype == GT_1FCTF) {
|
|
||||||
if (!ctf_neutralflag.areanum || !ctf_redflag.areanum || !ctf_blueflag.areanum)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -115,33 +109,10 @@ BotVoiceChat_Offense
|
||||||
*/
|
*/
|
||||||
void BotVoiceChat_Offense(bot_state_t *bs, int client, int mode) {
|
void BotVoiceChat_Offense(bot_state_t *bs, int client, int mode) {
|
||||||
if ( gametype == GT_CTF
|
if ( gametype == GT_CTF
|
||||||
#ifdef MISSIONPACK
|
|
||||||
|| gametype == GT_1FCTF
|
|
||||||
#endif
|
|
||||||
) {
|
) {
|
||||||
BotVoiceChat_GetFlag(bs, client, mode);
|
BotVoiceChat_GetFlag(bs, client, mode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if (gametype == GT_HARVESTER) {
|
|
||||||
//
|
|
||||||
bs->decisionmaker = client;
|
|
||||||
bs->ordered = qtrue;
|
|
||||||
bs->order_time = FloatTime();
|
|
||||||
//set the time to send a message to the team mates
|
|
||||||
bs->teammessage_time = FloatTime() + 2 * random();
|
|
||||||
//set the ltg type
|
|
||||||
bs->ltgtype = LTG_HARVEST;
|
|
||||||
//set the team goal time
|
|
||||||
bs->teamgoal_time = FloatTime() + TEAM_HARVEST_TIME;
|
|
||||||
bs->harvestaway_time = 0;
|
|
||||||
//
|
|
||||||
BotSetTeamStatus(bs);
|
|
||||||
// remember last ordered task
|
|
||||||
BotRememberLastOrderedTask(bs);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
bs->decisionmaker = client;
|
bs->decisionmaker = client;
|
||||||
|
|
@ -170,21 +141,7 @@ BotVoiceChat_Defend
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void BotVoiceChat_Defend(bot_state_t *bs, int client, int mode) {
|
void BotVoiceChat_Defend(bot_state_t *bs, int client, int mode) {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ( gametype == GT_OBELISK || gametype == GT_HARVESTER) {
|
|
||||||
//
|
|
||||||
switch(BotTeam(bs)) {
|
|
||||||
case TEAM_RED: memcpy(&bs->teamgoal, &redobelisk, sizeof(bot_goal_t)); break;
|
|
||||||
case TEAM_BLUE: memcpy(&bs->teamgoal, &blueobelisk, sizeof(bot_goal_t)); break;
|
|
||||||
default: return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if (gametype == GT_CTF
|
if (gametype == GT_CTF
|
||||||
#ifdef MISSIONPACK
|
|
||||||
|| gametype == GT_1FCTF
|
|
||||||
#endif
|
|
||||||
) {
|
) {
|
||||||
//
|
//
|
||||||
switch(BotTeam(bs)) {
|
switch(BotTeam(bs)) {
|
||||||
|
|
@ -384,9 +341,6 @@ void BotVoiceChat_ReturnFlag(bot_state_t *bs, int client, int mode) {
|
||||||
//if not in CTF mode
|
//if not in CTF mode
|
||||||
if (
|
if (
|
||||||
gametype != GT_CTF
|
gametype != GT_CTF
|
||||||
#ifdef MISSIONPACK
|
|
||||||
&& gametype != GT_1FCTF
|
|
||||||
#endif
|
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -654,268 +654,6 @@ Only in CTF games
|
||||||
/* sounds */ ""
|
/* sounds */ ""
|
||||||
},
|
},
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
/*QUAKED holdable_kamikaze (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"holdable_kamikaze",
|
|
||||||
"sound/items/holdable.wav",
|
|
||||||
{ "models/powerups/kamikazi.md3",
|
|
||||||
0, 0, 0},
|
|
||||||
/* icon */ "icons/kamikaze",
|
|
||||||
/* pickup */ "Kamikaze",
|
|
||||||
60,
|
|
||||||
IT_HOLDABLE,
|
|
||||||
HI_KAMIKAZE,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ "sound/items/kamikazerespawn.wav"
|
|
||||||
},
|
|
||||||
|
|
||||||
/*QUAKED holdable_portal (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"holdable_portal",
|
|
||||||
"sound/items/holdable.wav",
|
|
||||||
{ "models/powerups/holdable/porter.md3",
|
|
||||||
0, 0, 0},
|
|
||||||
/* icon */ "icons/portal",
|
|
||||||
/* pickup */ "Portal",
|
|
||||||
60,
|
|
||||||
IT_HOLDABLE,
|
|
||||||
HI_PORTAL,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ ""
|
|
||||||
},
|
|
||||||
|
|
||||||
/*QUAKED holdable_invulnerability (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"holdable_invulnerability",
|
|
||||||
"sound/items/holdable.wav",
|
|
||||||
{ "models/powerups/holdable/invulnerability.md3",
|
|
||||||
0, 0, 0},
|
|
||||||
/* icon */ "icons/invulnerability",
|
|
||||||
/* pickup */ "Invulnerability",
|
|
||||||
60,
|
|
||||||
IT_HOLDABLE,
|
|
||||||
HI_INVULNERABILITY,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ ""
|
|
||||||
},
|
|
||||||
|
|
||||||
/*QUAKED ammo_nails (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"ammo_nails",
|
|
||||||
"sound/misc/am_pkup.wav",
|
|
||||||
{ "models/powerups/ammo/nailgunam.md3",
|
|
||||||
0, 0, 0},
|
|
||||||
/* icon */ "icons/icona_nailgun",
|
|
||||||
/* pickup */ "Nails",
|
|
||||||
20,
|
|
||||||
IT_AMMO,
|
|
||||||
WP_NAILGUN,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ ""
|
|
||||||
},
|
|
||||||
|
|
||||||
/*QUAKED ammo_mines (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"ammo_mines",
|
|
||||||
"sound/misc/am_pkup.wav",
|
|
||||||
{ "models/powerups/ammo/proxmineam.md3",
|
|
||||||
0, 0, 0},
|
|
||||||
/* icon */ "icons/icona_proxlauncher",
|
|
||||||
/* pickup */ "Proximity Mines",
|
|
||||||
10,
|
|
||||||
IT_AMMO,
|
|
||||||
WP_PROX_LAUNCHER,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ ""
|
|
||||||
},
|
|
||||||
|
|
||||||
/*QUAKED ammo_belt (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"ammo_belt",
|
|
||||||
"sound/misc/am_pkup.wav",
|
|
||||||
{ "models/powerups/ammo/chaingunam.md3",
|
|
||||||
0, 0, 0},
|
|
||||||
/* icon */ "icons/icona_chaingun",
|
|
||||||
/* pickup */ "Chaingun Belt",
|
|
||||||
100,
|
|
||||||
IT_AMMO,
|
|
||||||
WP_CHAINGUN,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ ""
|
|
||||||
},
|
|
||||||
|
|
||||||
//
|
|
||||||
// PERSISTANT POWERUP ITEMS
|
|
||||||
//
|
|
||||||
/*QUAKED item_scout (.3 .3 1) (-16 -16 -16) (16 16 16) suspended redTeam blueTeam
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"item_scout",
|
|
||||||
"sound/items/scout.wav",
|
|
||||||
{ "models/powerups/scout.md3",
|
|
||||||
0, 0, 0 },
|
|
||||||
/* icon */ "icons/scout",
|
|
||||||
/* pickup */ "Scout",
|
|
||||||
30,
|
|
||||||
IT_PERSISTANT_POWERUP,
|
|
||||||
PW_SCOUT,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ ""
|
|
||||||
},
|
|
||||||
|
|
||||||
/*QUAKED item_guard (.3 .3 1) (-16 -16 -16) (16 16 16) suspended redTeam blueTeam
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"item_guard",
|
|
||||||
"sound/items/guard.wav",
|
|
||||||
{ "models/powerups/guard.md3",
|
|
||||||
0, 0, 0 },
|
|
||||||
/* icon */ "icons/guard",
|
|
||||||
/* pickup */ "Guard",
|
|
||||||
30,
|
|
||||||
IT_PERSISTANT_POWERUP,
|
|
||||||
PW_GUARD,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ ""
|
|
||||||
},
|
|
||||||
|
|
||||||
/*QUAKED item_doubler (.3 .3 1) (-16 -16 -16) (16 16 16) suspended redTeam blueTeam
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"item_doubler",
|
|
||||||
"sound/items/doubler.wav",
|
|
||||||
{ "models/powerups/doubler.md3",
|
|
||||||
0, 0, 0 },
|
|
||||||
/* icon */ "icons/doubler",
|
|
||||||
/* pickup */ "Doubler",
|
|
||||||
30,
|
|
||||||
IT_PERSISTANT_POWERUP,
|
|
||||||
PW_DOUBLER,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ ""
|
|
||||||
},
|
|
||||||
|
|
||||||
/*QUAKED item_doubler (.3 .3 1) (-16 -16 -16) (16 16 16) suspended redTeam blueTeam
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"item_ammoregen",
|
|
||||||
"sound/items/ammoregen.wav",
|
|
||||||
{ "models/powerups/ammo.md3",
|
|
||||||
0, 0, 0 },
|
|
||||||
/* icon */ "icons/ammo_regen",
|
|
||||||
/* pickup */ "Ammo Regen",
|
|
||||||
30,
|
|
||||||
IT_PERSISTANT_POWERUP,
|
|
||||||
PW_AMMOREGEN,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ ""
|
|
||||||
},
|
|
||||||
|
|
||||||
/*QUAKED team_CTF_neutralflag (0 0 1) (-16 -16 -16) (16 16 16)
|
|
||||||
Only in One Flag CTF games
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"team_CTF_neutralflag",
|
|
||||||
NULL,
|
|
||||||
{ "models/flags/n_flag.md3",
|
|
||||||
0, 0, 0 },
|
|
||||||
/* icon */ "icons/iconf_neutral1",
|
|
||||||
/* pickup */ "Neutral Flag",
|
|
||||||
0,
|
|
||||||
IT_TEAM,
|
|
||||||
PW_NEUTRALFLAG,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ ""
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"item_redcube",
|
|
||||||
"sound/misc/am_pkup.wav",
|
|
||||||
{ "models/powerups/orb/r_orb.md3",
|
|
||||||
0, 0, 0 },
|
|
||||||
/* icon */ "icons/iconh_rorb",
|
|
||||||
/* pickup */ "Red Cube",
|
|
||||||
0,
|
|
||||||
IT_TEAM,
|
|
||||||
0,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ ""
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"item_bluecube",
|
|
||||||
"sound/misc/am_pkup.wav",
|
|
||||||
{ "models/powerups/orb/b_orb.md3",
|
|
||||||
0, 0, 0 },
|
|
||||||
/* icon */ "icons/iconh_borb",
|
|
||||||
/* pickup */ "Blue Cube",
|
|
||||||
0,
|
|
||||||
IT_TEAM,
|
|
||||||
0,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ ""
|
|
||||||
},
|
|
||||||
/*QUAKED weapon_nailgun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"weapon_nailgun",
|
|
||||||
"sound/misc/w_pkup.wav",
|
|
||||||
{ "models/weapons/nailgun/nailgun.md3",
|
|
||||||
0, 0, 0},
|
|
||||||
/* icon */ "icons/iconw_nailgun",
|
|
||||||
/* pickup */ "Nailgun",
|
|
||||||
10,
|
|
||||||
IT_WEAPON,
|
|
||||||
WP_NAILGUN,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ ""
|
|
||||||
},
|
|
||||||
|
|
||||||
/*QUAKED weapon_prox_launcher (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"weapon_prox_launcher",
|
|
||||||
"sound/misc/w_pkup.wav",
|
|
||||||
{ "models/weapons/proxmine/proxmine.md3",
|
|
||||||
0, 0, 0},
|
|
||||||
/* icon */ "icons/iconw_proxlauncher",
|
|
||||||
/* pickup */ "Prox Launcher",
|
|
||||||
5,
|
|
||||||
IT_WEAPON,
|
|
||||||
WP_PROX_LAUNCHER,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ "sound/weapons/proxmine/wstbtick.wav "
|
|
||||||
"sound/weapons/proxmine/wstbactv.wav "
|
|
||||||
"sound/weapons/proxmine/wstbimpl.wav "
|
|
||||||
"sound/weapons/proxmine/wstbimpm.wav "
|
|
||||||
"sound/weapons/proxmine/wstbimpd.wav "
|
|
||||||
"sound/weapons/proxmine/wstbactv.wav"
|
|
||||||
},
|
|
||||||
|
|
||||||
/*QUAKED weapon_chaingun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"weapon_chaingun",
|
|
||||||
"sound/misc/w_pkup.wav",
|
|
||||||
{ "models/weapons/vulcan/vulcan.md3",
|
|
||||||
0, 0, 0},
|
|
||||||
/* icon */ "icons/iconw_chaingun",
|
|
||||||
/* pickup */ "Chaingun",
|
|
||||||
80,
|
|
||||||
IT_WEAPON,
|
|
||||||
WP_CHAINGUN,
|
|
||||||
/* precache */ "",
|
|
||||||
/* sounds */ "sound/weapons/vulcan/wvulwind.wav"
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// end of list marker
|
// end of list marker
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
@ -1038,9 +776,6 @@ This needs to be the same for client side prediction and server use.
|
||||||
*/
|
*/
|
||||||
qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const playerState_t *ps ) {
|
qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const playerState_t *ps ) {
|
||||||
gitem_t *item;
|
gitem_t *item;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
int upperBound;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( ent->modelindex < 1 || ent->modelindex >= bg_numItems ) {
|
if ( ent->modelindex < 1 || ent->modelindex >= bg_numItems ) {
|
||||||
Com_Error( ERR_DROP, "BG_CanItemBeGrabbed: index out of range" );
|
Com_Error( ERR_DROP, "BG_CanItemBeGrabbed: index out of range" );
|
||||||
|
|
@ -1059,38 +794,14 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play
|
||||||
return qtrue;
|
return qtrue;
|
||||||
|
|
||||||
case IT_ARMOR:
|
case IT_ARMOR:
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( bg_itemlist[ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_SCOUT ) {
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we also clamp armor to the maxhealth for handicapping
|
|
||||||
if( bg_itemlist[ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
|
|
||||||
upperBound = ps->stats[STAT_MAX_HEALTH];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
upperBound = ps->stats[STAT_MAX_HEALTH] * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ps->stats[STAT_ARMOR] >= upperBound ) {
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if ( ps->stats[STAT_ARMOR] >= ps->stats[STAT_MAX_HEALTH] * 2 ) {
|
if ( ps->stats[STAT_ARMOR] >= ps->stats[STAT_MAX_HEALTH] * 2 ) {
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return qtrue;
|
return qtrue;
|
||||||
|
|
||||||
case IT_HEALTH:
|
case IT_HEALTH:
|
||||||
// small and mega healths will go over the max, otherwise
|
// small and mega healths will go over the max, otherwise
|
||||||
// don't pick up if already at max
|
// don't pick up if already at max
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( bg_itemlist[ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
|
|
||||||
upperBound = ps->stats[STAT_MAX_HEALTH];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if ( item->quantity == 5 || item->quantity == 100 ) {
|
if ( item->quantity == 5 || item->quantity == 100 ) {
|
||||||
if ( ps->stats[STAT_HEALTH] >= ps->stats[STAT_MAX_HEALTH] * 2 ) {
|
if ( ps->stats[STAT_HEALTH] >= ps->stats[STAT_MAX_HEALTH] * 2 ) {
|
||||||
return qfalse;
|
return qfalse;
|
||||||
|
|
@ -1106,42 +817,7 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play
|
||||||
case IT_POWERUP:
|
case IT_POWERUP:
|
||||||
return qtrue; // powerups are always picked up
|
return qtrue; // powerups are always picked up
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
case IT_PERSISTANT_POWERUP:
|
|
||||||
// can only hold one item at a time
|
|
||||||
if ( ps->stats[STAT_PERSISTANT_POWERUP] ) {
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check team only
|
|
||||||
if( ( ent->generic1 & 2 ) && ( ps->persistant[PERS_TEAM] != TEAM_RED ) ) {
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
if( ( ent->generic1 & 4 ) && ( ps->persistant[PERS_TEAM] != TEAM_BLUE ) ) {
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
return qtrue;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case IT_TEAM: // team items, such as flags
|
case IT_TEAM: // team items, such as flags
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( gametype == GT_1FCTF ) {
|
|
||||||
// neutral flag can always be picked up
|
|
||||||
if( item->giTag == PW_NEUTRALFLAG ) {
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
if (ps->persistant[PERS_TEAM] == TEAM_RED) {
|
|
||||||
if (item->giTag == PW_BLUEFLAG && ps->powerups[PW_NEUTRALFLAG] ) {
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
} else if (ps->persistant[PERS_TEAM] == TEAM_BLUE) {
|
|
||||||
if (item->giTag == PW_REDFLAG && ps->powerups[PW_NEUTRALFLAG] ) {
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if( gametype == GT_CTF ) {
|
if( gametype == GT_CTF ) {
|
||||||
// ent->modelindex2 is non-zero on items if they are dropped
|
// ent->modelindex2 is non-zero on items if they are dropped
|
||||||
// we need to know this because we can pick up our dropped flag (and return it)
|
// we need to know this because we can pick up our dropped flag (and return it)
|
||||||
|
|
@ -1159,11 +835,6 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( gametype == GT_HARVESTER ) {
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return qfalse;
|
return qfalse;
|
||||||
|
|
||||||
case IT_HOLDABLE:
|
case IT_HOLDABLE:
|
||||||
|
|
@ -1361,16 +1032,6 @@ char *eventnames[] = {
|
||||||
"EV_GIB_PLAYER", // gib a previously living player
|
"EV_GIB_PLAYER", // gib a previously living player
|
||||||
"EV_SCOREPLUM", // score plum
|
"EV_SCOREPLUM", // score plum
|
||||||
|
|
||||||
//#ifdef MISSIONPACK
|
|
||||||
"EV_PROXIMITY_MINE_STICK",
|
|
||||||
"EV_PROXIMITY_MINE_TRIGGER",
|
|
||||||
"EV_KAMIKAZE", // kamikaze explodes
|
|
||||||
"EV_OBELISKEXPLODE", // obelisk explodes
|
|
||||||
"EV_INVUL_IMPACT", // invulnerability sphere impact
|
|
||||||
"EV_JUICED", // invulnerability juiced effect
|
|
||||||
"EV_LIGHTNINGBOLT", // lightning bolt bounced of invulnerability sphere
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
"EV_DEBUG_LINE",
|
"EV_DEBUG_LINE",
|
||||||
"EV_STOPLOOPINGSOUND",
|
"EV_STOPLOOPINGSOUND",
|
||||||
"EV_TAUNT"
|
"EV_TAUNT"
|
||||||
|
|
|
||||||
|
|
@ -534,22 +534,6 @@ static void PM_WaterMove( void ) {
|
||||||
PM_SlideMove( qfalse );
|
PM_SlideMove( qfalse );
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
/*
|
|
||||||
===================
|
|
||||||
PM_InvulnerabilityMove
|
|
||||||
|
|
||||||
Only with the invulnerability powerup
|
|
||||||
===================
|
|
||||||
*/
|
|
||||||
static void PM_InvulnerabilityMove( void ) {
|
|
||||||
pm->cmd.forwardmove = 0;
|
|
||||||
pm->cmd.rightmove = 0;
|
|
||||||
pm->cmd.upmove = 0;
|
|
||||||
VectorClear(pm->ps->velocity);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===================
|
===================
|
||||||
PM_FlyMove
|
PM_FlyMove
|
||||||
|
|
@ -1675,29 +1659,8 @@ static void PM_Weapon( void ) {
|
||||||
case WP_GRAPPLING_HOOK:
|
case WP_GRAPPLING_HOOK:
|
||||||
addTime = 400;
|
addTime = 400;
|
||||||
break;
|
break;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
case WP_NAILGUN:
|
|
||||||
addTime = 1000;
|
|
||||||
break;
|
|
||||||
case WP_PROX_LAUNCHER:
|
|
||||||
addTime = 800;
|
|
||||||
break;
|
|
||||||
case WP_CHAINGUN:
|
|
||||||
addTime = 30;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( bg_itemlist[pm->ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_SCOUT ) {
|
|
||||||
addTime /= 1.5;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( bg_itemlist[pm->ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_AMMOREGEN ) {
|
|
||||||
addTime /= 1.3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if ( pm->ps->powerups[PW_HASTE] ) {
|
if ( pm->ps->powerups[PW_HASTE] ) {
|
||||||
addTime /= 1.3;
|
addTime /= 1.3;
|
||||||
}
|
}
|
||||||
|
|
@ -1718,38 +1681,6 @@ static void PM_Animate( void ) {
|
||||||
pm->ps->torsoTimer = TIMER_GESTURE;
|
pm->ps->torsoTimer = TIMER_GESTURE;
|
||||||
PM_AddEvent( EV_TAUNT );
|
PM_AddEvent( EV_TAUNT );
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
} else if ( pm->cmd.buttons & BUTTON_GETFLAG ) {
|
|
||||||
if ( pm->ps->torsoTimer == 0 ) {
|
|
||||||
PM_StartTorsoAnim( TORSO_GETFLAG );
|
|
||||||
pm->ps->torsoTimer = 600; //TIMER_GESTURE;
|
|
||||||
}
|
|
||||||
} else if ( pm->cmd.buttons & BUTTON_GUARDBASE ) {
|
|
||||||
if ( pm->ps->torsoTimer == 0 ) {
|
|
||||||
PM_StartTorsoAnim( TORSO_GUARDBASE );
|
|
||||||
pm->ps->torsoTimer = 600; //TIMER_GESTURE;
|
|
||||||
}
|
|
||||||
} else if ( pm->cmd.buttons & BUTTON_PATROL ) {
|
|
||||||
if ( pm->ps->torsoTimer == 0 ) {
|
|
||||||
PM_StartTorsoAnim( TORSO_PATROL );
|
|
||||||
pm->ps->torsoTimer = 600; //TIMER_GESTURE;
|
|
||||||
}
|
|
||||||
} else if ( pm->cmd.buttons & BUTTON_FOLLOWME ) {
|
|
||||||
if ( pm->ps->torsoTimer == 0 ) {
|
|
||||||
PM_StartTorsoAnim( TORSO_FOLLOWME );
|
|
||||||
pm->ps->torsoTimer = 600; //TIMER_GESTURE;
|
|
||||||
}
|
|
||||||
} else if ( pm->cmd.buttons & BUTTON_AFFIRMATIVE ) {
|
|
||||||
if ( pm->ps->torsoTimer == 0 ) {
|
|
||||||
PM_StartTorsoAnim( TORSO_AFFIRMATIVE);
|
|
||||||
pm->ps->torsoTimer = 600; //TIMER_GESTURE;
|
|
||||||
}
|
|
||||||
} else if ( pm->cmd.buttons & BUTTON_NEGATIVE ) {
|
|
||||||
if ( pm->ps->torsoTimer == 0 ) {
|
|
||||||
PM_StartTorsoAnim( TORSO_NEGATIVE );
|
|
||||||
pm->ps->torsoTimer = 600; //TIMER_GESTURE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1968,11 +1899,6 @@ void PmoveSingle (pmove_t *pmove) {
|
||||||
|
|
||||||
PM_DropTimers();
|
PM_DropTimers();
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ( pm->ps->powerups[PW_INVULNERABILITY] ) {
|
|
||||||
PM_InvulnerabilityMove();
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
if ( pm->ps->powerups[PW_FLIGHT] ) {
|
if ( pm->ps->powerups[PW_FLIGHT] ) {
|
||||||
// flight powerup doesn't allow jump and has different friction
|
// flight powerup doesn't allow jump and has different friction
|
||||||
PM_FlyMove();
|
PM_FlyMove();
|
||||||
|
|
|
||||||
|
|
@ -203,9 +203,6 @@ void Pmove (pmove_t *pmove);
|
||||||
typedef enum {
|
typedef enum {
|
||||||
STAT_HEALTH,
|
STAT_HEALTH,
|
||||||
STAT_HOLDABLE_ITEM,
|
STAT_HOLDABLE_ITEM,
|
||||||
#ifdef MISSIONPACK
|
|
||||||
STAT_PERSISTANT_POWERUP,
|
|
||||||
#endif
|
|
||||||
STAT_WEAPONS, // 16 bit fields
|
STAT_WEAPONS, // 16 bit fields
|
||||||
STAT_ARMOR,
|
STAT_ARMOR,
|
||||||
STAT_DEAD_YAW, // look this direction when dead (FIXME: get rid of?)
|
STAT_DEAD_YAW, // look this direction when dead (FIXME: get rid of?)
|
||||||
|
|
@ -240,9 +237,6 @@ typedef enum {
|
||||||
|
|
||||||
// entityState_t->eFlags
|
// entityState_t->eFlags
|
||||||
#define EF_DEAD 0x00000001 // don't draw a foe marker over players with EF_DEAD
|
#define EF_DEAD 0x00000001 // don't draw a foe marker over players with EF_DEAD
|
||||||
#ifdef MISSIONPACK
|
|
||||||
#define EF_TICKING 0x00000002 // used to make players play the prox mine ticking sound
|
|
||||||
#endif
|
|
||||||
#define EF_TELEPORT_BIT 0x00000004 // toggled every time the origin abruptly changes
|
#define EF_TELEPORT_BIT 0x00000004 // toggled every time the origin abruptly changes
|
||||||
#define EF_AWARD_EXCELLENT 0x00000008 // draw an excellent sprite
|
#define EF_AWARD_EXCELLENT 0x00000008 // draw an excellent sprite
|
||||||
#define EF_PLAYER_EVENT 0x00000010
|
#define EF_PLAYER_EVENT 0x00000010
|
||||||
|
|
@ -314,11 +308,6 @@ typedef enum {
|
||||||
WP_PLASMAGUN,
|
WP_PLASMAGUN,
|
||||||
WP_BFG,
|
WP_BFG,
|
||||||
WP_GRAPPLING_HOOK,
|
WP_GRAPPLING_HOOK,
|
||||||
#ifdef MISSIONPACK
|
|
||||||
WP_NAILGUN,
|
|
||||||
WP_PROX_LAUNCHER,
|
|
||||||
WP_CHAINGUN,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WP_NUM_WEAPONS
|
WP_NUM_WEAPONS
|
||||||
} weapon_t;
|
} weapon_t;
|
||||||
|
|
@ -428,17 +417,6 @@ typedef enum {
|
||||||
EV_GIB_PLAYER, // gib a previously living player
|
EV_GIB_PLAYER, // gib a previously living player
|
||||||
EV_SCOREPLUM, // score plum
|
EV_SCOREPLUM, // score plum
|
||||||
|
|
||||||
//#ifdef MISSIONPACK
|
|
||||||
EV_PROXIMITY_MINE_STICK,
|
|
||||||
EV_PROXIMITY_MINE_TRIGGER,
|
|
||||||
EV_KAMIKAZE, // kamikaze explodes
|
|
||||||
EV_OBELISKEXPLODE, // obelisk explodes
|
|
||||||
EV_OBELISKPAIN, // obelisk is in pain
|
|
||||||
EV_INVUL_IMPACT, // invulnerability sphere impact
|
|
||||||
EV_JUICED, // invulnerability juiced effect
|
|
||||||
EV_LIGHTNINGBOLT, // lightning bolt bounced of invulnerability sphere
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
EV_DEBUG_LINE,
|
EV_DEBUG_LINE,
|
||||||
EV_STOPLOOPINGSOUND,
|
EV_STOPLOOPINGSOUND,
|
||||||
EV_TAUNT,
|
EV_TAUNT,
|
||||||
|
|
@ -593,13 +571,6 @@ typedef enum {
|
||||||
MOD_SUICIDE,
|
MOD_SUICIDE,
|
||||||
MOD_TARGET_LASER,
|
MOD_TARGET_LASER,
|
||||||
MOD_TRIGGER_HURT,
|
MOD_TRIGGER_HURT,
|
||||||
#ifdef MISSIONPACK
|
|
||||||
MOD_NAIL,
|
|
||||||
MOD_CHAINGUN,
|
|
||||||
MOD_PROXIMITY_MINE,
|
|
||||||
MOD_KAMIKAZE,
|
|
||||||
MOD_JUICED,
|
|
||||||
#endif
|
|
||||||
MOD_GRAPPLE
|
MOD_GRAPPLE
|
||||||
} meansOfDeath_t;
|
} meansOfDeath_t;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -182,12 +182,6 @@ G_SetClientSound
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
void G_SetClientSound( gentity_t *ent ) {
|
void G_SetClientSound( gentity_t *ent ) {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( ent->s.eFlags & EF_TICKING ) {
|
|
||||||
ent->client->ps.loopSound = G_SoundIndex( "sound/weapons/proxmine/wstbtick.wav");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if (ent->waterlevel && (ent->watertype&(CONTENTS_LAVA|CONTENTS_SLIME)) ) {
|
if (ent->waterlevel && (ent->watertype&(CONTENTS_LAVA|CONTENTS_SLIME)) ) {
|
||||||
ent->client->ps.loopSound = level.snd_fry;
|
ent->client->ps.loopSound = level.snd_fry;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -402,9 +396,6 @@ Actions that happen once a second
|
||||||
*/
|
*/
|
||||||
void ClientTimerActions( gentity_t *ent, int msec ) {
|
void ClientTimerActions( gentity_t *ent, int msec ) {
|
||||||
gclient_t *client;
|
gclient_t *client;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
int maxHealth;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
client = ent->client;
|
client = ent->client;
|
||||||
client->timeResidual += msec;
|
client->timeResidual += msec;
|
||||||
|
|
@ -413,31 +404,6 @@ void ClientTimerActions( gentity_t *ent, int msec ) {
|
||||||
client->timeResidual -= 1000;
|
client->timeResidual -= 1000;
|
||||||
|
|
||||||
// regenerate
|
// regenerate
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( bg_itemlist[client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
|
|
||||||
maxHealth = client->ps.stats[STAT_MAX_HEALTH] / 2;
|
|
||||||
}
|
|
||||||
else if ( client->ps.powerups[PW_REGEN] ) {
|
|
||||||
maxHealth = client->ps.stats[STAT_MAX_HEALTH];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
maxHealth = 0;
|
|
||||||
}
|
|
||||||
if( maxHealth ) {
|
|
||||||
if ( ent->health < maxHealth ) {
|
|
||||||
ent->health += 15;
|
|
||||||
if ( ent->health > maxHealth * 1.1 ) {
|
|
||||||
ent->health = maxHealth * 1.1;
|
|
||||||
}
|
|
||||||
G_AddEvent( ent, EV_POWERUP_REGEN, 0 );
|
|
||||||
} else if ( ent->health < maxHealth * 2) {
|
|
||||||
ent->health += 5;
|
|
||||||
if ( ent->health > maxHealth * 2 ) {
|
|
||||||
ent->health = maxHealth * 2;
|
|
||||||
}
|
|
||||||
G_AddEvent( ent, EV_POWERUP_REGEN, 0 );
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if ( client->ps.powerups[PW_REGEN] ) {
|
if ( client->ps.powerups[PW_REGEN] ) {
|
||||||
if ( ent->health < client->ps.stats[STAT_MAX_HEALTH]) {
|
if ( ent->health < client->ps.stats[STAT_MAX_HEALTH]) {
|
||||||
ent->health += 15;
|
ent->health += 15;
|
||||||
|
|
@ -452,7 +418,6 @@ void ClientTimerActions( gentity_t *ent, int msec ) {
|
||||||
}
|
}
|
||||||
G_AddEvent( ent, EV_POWERUP_REGEN, 0 );
|
G_AddEvent( ent, EV_POWERUP_REGEN, 0 );
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
// count down health when over max
|
// count down health when over max
|
||||||
if ( ent->health > client->ps.stats[STAT_MAX_HEALTH] ) {
|
if ( ent->health > client->ps.stats[STAT_MAX_HEALTH] ) {
|
||||||
|
|
@ -465,44 +430,6 @@ void ClientTimerActions( gentity_t *ent, int msec ) {
|
||||||
client->ps.stats[STAT_ARMOR]--;
|
client->ps.stats[STAT_ARMOR]--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( bg_itemlist[client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_AMMOREGEN ) {
|
|
||||||
int w, max, inc, t, i;
|
|
||||||
int weapList[]={WP_MACHINEGUN,WP_SHOTGUN,WP_GRENADE_LAUNCHER,WP_ROCKET_LAUNCHER,WP_LIGHTNING,WP_RAILGUN,WP_PLASMAGUN,WP_BFG,WP_NAILGUN,WP_PROX_LAUNCHER,WP_CHAINGUN};
|
|
||||||
int weapCount = sizeof(weapList) / sizeof(int);
|
|
||||||
//
|
|
||||||
for (i = 0; i < weapCount; i++) {
|
|
||||||
w = weapList[i];
|
|
||||||
|
|
||||||
switch(w) {
|
|
||||||
case WP_MACHINEGUN: max = 50; inc = 4; t = 1000; break;
|
|
||||||
case WP_SHOTGUN: max = 10; inc = 1; t = 1500; break;
|
|
||||||
case WP_GRENADE_LAUNCHER: max = 10; inc = 1; t = 2000; break;
|
|
||||||
case WP_ROCKET_LAUNCHER: max = 10; inc = 1; t = 1750; break;
|
|
||||||
case WP_LIGHTNING: max = 50; inc = 5; t = 1500; break;
|
|
||||||
case WP_RAILGUN: max = 10; inc = 1; t = 1750; break;
|
|
||||||
case WP_PLASMAGUN: max = 50; inc = 5; t = 1500; break;
|
|
||||||
case WP_BFG: max = 10; inc = 1; t = 4000; break;
|
|
||||||
case WP_NAILGUN: max = 10; inc = 1; t = 1250; break;
|
|
||||||
case WP_PROX_LAUNCHER: max = 5; inc = 1; t = 2000; break;
|
|
||||||
case WP_CHAINGUN: max = 100; inc = 5; t = 1000; break;
|
|
||||||
default: max = 0; inc = 0; t = 1000; break;
|
|
||||||
}
|
|
||||||
client->ammoTimes[w] += msec;
|
|
||||||
if ( client->ps.ammo[w] >= max ) {
|
|
||||||
client->ammoTimes[w] = 0;
|
|
||||||
}
|
|
||||||
if ( client->ammoTimes[w] >= t ) {
|
|
||||||
while ( client->ammoTimes[w] >= t )
|
|
||||||
client->ammoTimes[w] -= t;
|
|
||||||
client->ps.ammo[w] += inc;
|
|
||||||
if ( client->ps.ammo[w] > max ) {
|
|
||||||
client->ps.ammo[w] = max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -603,28 +530,6 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) {
|
||||||
ent->client->ps.powerups[ j ] = 0;
|
ent->client->ps.powerups[ j ] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ( g_gametype.integer == GT_HARVESTER ) {
|
|
||||||
if ( ent->client->ps.generic1 > 0 ) {
|
|
||||||
if ( ent->client->sess.sessionTeam == TEAM_RED ) {
|
|
||||||
item = BG_FindItem( "Blue Cube" );
|
|
||||||
} else {
|
|
||||||
item = BG_FindItem( "Red Cube" );
|
|
||||||
}
|
|
||||||
if ( item ) {
|
|
||||||
for ( j = 0; j < ent->client->ps.generic1; j++ ) {
|
|
||||||
drop = Drop_Item( ent, item, 0 );
|
|
||||||
if ( ent->client->sess.sessionTeam == TEAM_RED ) {
|
|
||||||
drop->spawnflags = TEAM_BLUE;
|
|
||||||
} else {
|
|
||||||
drop->spawnflags = TEAM_RED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ent->client->ps.generic1 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
SelectSpawnPoint( ent->client->ps.origin, origin, angles );
|
SelectSpawnPoint( ent->client->ps.origin, origin, angles );
|
||||||
TeleportPlayer( ent, origin, angles );
|
TeleportPlayer( ent, origin, angles );
|
||||||
break;
|
break;
|
||||||
|
|
@ -634,27 +539,6 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
case EV_USE_ITEM3: // kamikaze
|
|
||||||
// make sure the invulnerability is off
|
|
||||||
ent->client->invulnerabilityTime = 0;
|
|
||||||
// start the kamikze
|
|
||||||
G_StartKamikaze( ent );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_USE_ITEM4: // portal
|
|
||||||
if( ent->client->portalID ) {
|
|
||||||
DropPortalSource( ent );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DropPortalDestination( ent );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EV_USE_ITEM5: // invulnerability
|
|
||||||
ent->client->invulnerabilityTime = level.time + 10000;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -662,49 +546,6 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
/*
|
|
||||||
==============
|
|
||||||
StuckInOtherClient
|
|
||||||
==============
|
|
||||||
*/
|
|
||||||
static int StuckInOtherClient(gentity_t *ent) {
|
|
||||||
int i;
|
|
||||||
gentity_t *ent2;
|
|
||||||
|
|
||||||
ent2 = &g_entities[0];
|
|
||||||
for ( i = 0; i < MAX_CLIENTS; i++, ent2++ ) {
|
|
||||||
if ( ent2 == ent ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( !ent2->inuse ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( !ent2->client ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( ent2->health <= 0 ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if (ent2->r.absmin[0] > ent->r.absmax[0])
|
|
||||||
continue;
|
|
||||||
if (ent2->r.absmin[1] > ent->r.absmax[1])
|
|
||||||
continue;
|
|
||||||
if (ent2->r.absmin[2] > ent->r.absmax[2])
|
|
||||||
continue;
|
|
||||||
if (ent2->r.absmax[0] < ent->r.absmin[0])
|
|
||||||
continue;
|
|
||||||
if (ent2->r.absmax[1] < ent->r.absmin[1])
|
|
||||||
continue;
|
|
||||||
if (ent2->r.absmax[2] < ent->r.absmin[2])
|
|
||||||
continue;
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void BotTestSolid(vec3_t origin);
|
void BotTestSolid(vec3_t origin);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -842,12 +683,6 @@ void ClientThink_real( gentity_t *ent ) {
|
||||||
// set speed
|
// set speed
|
||||||
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 ) {
|
|
||||||
client->ps.speed *= 1.5;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if ( client->ps.powerups[PW_HASTE] ) {
|
if ( client->ps.powerups[PW_HASTE] ) {
|
||||||
client->ps.speed *= 1.3;
|
client->ps.speed *= 1.3;
|
||||||
}
|
}
|
||||||
|
|
@ -875,33 +710,6 @@ void ClientThink_real( gentity_t *ent ) {
|
||||||
ent->client->pers.cmd.buttons |= BUTTON_GESTURE;
|
ent->client->pers.cmd.buttons |= BUTTON_GESTURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
// check for invulnerability expansion before doing the Pmove
|
|
||||||
if (client->ps.powerups[PW_INVULNERABILITY] ) {
|
|
||||||
if ( !(client->ps.pm_flags & PMF_INVULEXPAND) ) {
|
|
||||||
vec3_t mins = { -42, -42, -42 };
|
|
||||||
vec3_t maxs = { 42, 42, 42 };
|
|
||||||
vec3_t oldmins, oldmaxs;
|
|
||||||
|
|
||||||
VectorCopy (ent->r.mins, oldmins);
|
|
||||||
VectorCopy (ent->r.maxs, oldmaxs);
|
|
||||||
// expand
|
|
||||||
VectorCopy (mins, ent->r.mins);
|
|
||||||
VectorCopy (maxs, ent->r.maxs);
|
|
||||||
trap_LinkEntity(ent);
|
|
||||||
// check if this would get anyone stuck in this player
|
|
||||||
if ( !StuckInOtherClient(ent) ) {
|
|
||||||
// set flag so the expanded size will be set in PM_CheckDuck
|
|
||||||
client->ps.pm_flags |= PMF_INVULEXPAND;
|
|
||||||
}
|
|
||||||
// set back
|
|
||||||
VectorCopy (oldmins, ent->r.mins);
|
|
||||||
VectorCopy (oldmaxs, ent->r.maxs);
|
|
||||||
trap_LinkEntity(ent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pm.ps = &client->ps;
|
pm.ps = &client->ps;
|
||||||
pm.cmd = *ucmd;
|
pm.cmd = *ucmd;
|
||||||
if ( pm.ps->pm_type == PM_DEAD ) {
|
if ( pm.ps->pm_type == PM_DEAD ) {
|
||||||
|
|
@ -923,23 +731,7 @@ void ClientThink_real( gentity_t *ent ) {
|
||||||
|
|
||||||
VectorCopy( client->ps.origin, client->oldOrigin );
|
VectorCopy( client->ps.origin, client->oldOrigin );
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if (level.intermissionQueued != 0 && g_singlePlayer.integer) {
|
|
||||||
if ( level.time - level.intermissionQueued >= 1000 ) {
|
|
||||||
pm.cmd.buttons = 0;
|
|
||||||
pm.cmd.forwardmove = 0;
|
|
||||||
pm.cmd.rightmove = 0;
|
|
||||||
pm.cmd.upmove = 0;
|
|
||||||
if ( level.time - level.intermissionQueued >= 2000 && level.time - level.intermissionQueued <= 2500 ) {
|
|
||||||
trap_SendConsoleCommand( EXEC_APPEND, "centerview\n");
|
|
||||||
}
|
|
||||||
ent->client->ps.pm_type = PM_SPINTERMISSION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Pmove (&pm);
|
Pmove (&pm);
|
||||||
#else
|
|
||||||
Pmove (&pm);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// save results of pmove
|
// save results of pmove
|
||||||
if ( ent->client->ps.eventSequence != oldEventSequence ) {
|
if ( ent->client->ps.eventSequence != oldEventSequence ) {
|
||||||
|
|
@ -1122,25 +914,6 @@ void ClientEndFrame( gentity_t *ent ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
// set powerup for player animation
|
|
||||||
if( bg_itemlist[ent->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
|
|
||||||
ent->client->ps.powerups[PW_GUARD] = level.time;
|
|
||||||
}
|
|
||||||
if( bg_itemlist[ent->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_SCOUT ) {
|
|
||||||
ent->client->ps.powerups[PW_SCOUT] = level.time;
|
|
||||||
}
|
|
||||||
if( bg_itemlist[ent->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_DOUBLER ) {
|
|
||||||
ent->client->ps.powerups[PW_DOUBLER] = level.time;
|
|
||||||
}
|
|
||||||
if( bg_itemlist[ent->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_AMMOREGEN ) {
|
|
||||||
ent->client->ps.powerups[PW_AMMOREGEN] = level.time;
|
|
||||||
}
|
|
||||||
if ( ent->client->invulnerabilityTime > level.time ) {
|
|
||||||
ent->client->ps.powerups[PW_INVULNERABILITY] = level.time;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// save network bandwidth
|
// save network bandwidth
|
||||||
#if 0
|
#if 0
|
||||||
if ( !g_synchronousClients->integer && ent->client->ps.pm_type == PM_NORMAL ) {
|
if ( !g_synchronousClients->integer && ent->client->ps.pm_type == PM_NORMAL ) {
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,6 @@ void UpdateTournamentInfo( void ) {
|
||||||
int playerClientNum;
|
int playerClientNum;
|
||||||
int n, accuracy, perfect, msglen;
|
int n, accuracy, perfect, msglen;
|
||||||
int buflen;
|
int buflen;
|
||||||
#ifdef MISSIONPACK // bk001205
|
|
||||||
int score1, score2;
|
|
||||||
qboolean won;
|
|
||||||
#endif
|
|
||||||
char buf[32];
|
char buf[32];
|
||||||
char msg[MAX_STRING_CHARS];
|
char msg[MAX_STRING_CHARS];
|
||||||
|
|
||||||
|
|
@ -70,11 +66,7 @@ void UpdateTournamentInfo( void ) {
|
||||||
CalculateRanks();
|
CalculateRanks();
|
||||||
|
|
||||||
if ( level.clients[playerClientNum].sess.sessionTeam == TEAM_SPECTATOR ) {
|
if ( level.clients[playerClientNum].sess.sessionTeam == TEAM_SPECTATOR ) {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
Com_sprintf( msg, sizeof(msg), "postgame %i %i 0 0 0 0 0 0 0 0 0 0 0", level.numNonSpectatorClients, playerClientNum );
|
|
||||||
#else
|
|
||||||
Com_sprintf( msg, sizeof(msg), "postgame %i %i 0 0 0 0 0 0", level.numNonSpectatorClients, playerClientNum );
|
Com_sprintf( msg, sizeof(msg), "postgame %i %i 0 0 0 0 0 0", level.numNonSpectatorClients, playerClientNum );
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( player->client->accuracy_shots ) {
|
if( player->client->accuracy_shots ) {
|
||||||
|
|
@ -83,43 +75,12 @@ void UpdateTournamentInfo( void ) {
|
||||||
else {
|
else {
|
||||||
accuracy = 0;
|
accuracy = 0;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
won = qfalse;
|
|
||||||
if (g_gametype.integer >= GT_CTF) {
|
|
||||||
score1 = level.teamScores[TEAM_RED];
|
|
||||||
score2 = level.teamScores[TEAM_BLUE];
|
|
||||||
if (level.clients[playerClientNum].sess.sessionTeam == TEAM_RED) {
|
|
||||||
won = (level.teamScores[TEAM_RED] > level.teamScores[TEAM_BLUE]);
|
|
||||||
} else {
|
|
||||||
won = (level.teamScores[TEAM_BLUE] > level.teamScores[TEAM_RED]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (&level.clients[playerClientNum] == &level.clients[ level.sortedClients[0] ]) {
|
|
||||||
won = qtrue;
|
|
||||||
score1 = level.clients[ level.sortedClients[0] ].ps.persistant[PERS_SCORE];
|
|
||||||
score2 = level.clients[ level.sortedClients[1] ].ps.persistant[PERS_SCORE];
|
|
||||||
} else {
|
|
||||||
score2 = level.clients[ level.sortedClients[0] ].ps.persistant[PERS_SCORE];
|
|
||||||
score1 = level.clients[ level.sortedClients[1] ].ps.persistant[PERS_SCORE];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (won && player->client->ps.persistant[PERS_KILLED] == 0) {
|
|
||||||
perfect = 1;
|
|
||||||
} else {
|
|
||||||
perfect = 0;
|
|
||||||
}
|
|
||||||
Com_sprintf( msg, sizeof(msg), "postgame %i %i %i %i %i %i %i %i %i %i %i %i %i %i", level.numNonSpectatorClients, playerClientNum, accuracy,
|
|
||||||
player->client->ps.persistant[PERS_IMPRESSIVE_COUNT], player->client->ps.persistant[PERS_EXCELLENT_COUNT],player->client->ps.persistant[PERS_DEFEND_COUNT],
|
|
||||||
player->client->ps.persistant[PERS_ASSIST_COUNT], player->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT], player->client->ps.persistant[PERS_SCORE],
|
|
||||||
perfect, score1, score2, level.time, player->client->ps.persistant[PERS_CAPTURES] );
|
|
||||||
|
|
||||||
#else
|
|
||||||
perfect = ( level.clients[playerClientNum].ps.persistant[PERS_RANK] == 0 && player->client->ps.persistant[PERS_KILLED] == 0 ) ? 1 : 0;
|
perfect = ( level.clients[playerClientNum].ps.persistant[PERS_RANK] == 0 && player->client->ps.persistant[PERS_KILLED] == 0 ) ? 1 : 0;
|
||||||
Com_sprintf( msg, sizeof(msg), "postgame %i %i %i %i %i %i %i %i", level.numNonSpectatorClients, playerClientNum, accuracy,
|
Com_sprintf( msg, sizeof(msg), "postgame %i %i %i %i %i %i %i %i", level.numNonSpectatorClients, playerClientNum, accuracy,
|
||||||
player->client->ps.persistant[PERS_IMPRESSIVE_COUNT], player->client->ps.persistant[PERS_EXCELLENT_COUNT],
|
player->client->ps.persistant[PERS_IMPRESSIVE_COUNT], player->client->ps.persistant[PERS_EXCELLENT_COUNT],
|
||||||
player->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT], player->client->ps.persistant[PERS_SCORE],
|
player->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT], player->client->ps.persistant[PERS_SCORE],
|
||||||
perfect );
|
perfect );
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
msglen = (int)strlen( msg );
|
msglen = (int)strlen( msg );
|
||||||
|
|
|
||||||
|
|
@ -367,10 +367,6 @@ just like the existing corpse to leave behind.
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
void CopyToBodyQue( gentity_t *ent ) {
|
void CopyToBodyQue( gentity_t *ent ) {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
gentity_t *e;
|
|
||||||
int i;
|
|
||||||
#endif
|
|
||||||
gentity_t *body;
|
gentity_t *body;
|
||||||
int contents;
|
int contents;
|
||||||
|
|
||||||
|
|
@ -390,24 +386,6 @@ void CopyToBodyQue( gentity_t *ent ) {
|
||||||
|
|
||||||
body->s = ent->s;
|
body->s = ent->s;
|
||||||
body->s.eFlags = EF_DEAD; // clear EF_TALK, etc
|
body->s.eFlags = EF_DEAD; // clear EF_TALK, etc
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ( ent->s.eFlags & EF_KAMIKAZE ) {
|
|
||||||
body->s.eFlags |= EF_KAMIKAZE;
|
|
||||||
|
|
||||||
// check if there is a kamikaze timer around for this owner
|
|
||||||
for (i = 0; i < MAX_GENTITIES; i++) {
|
|
||||||
e = &g_entities[i];
|
|
||||||
if (!e->inuse)
|
|
||||||
continue;
|
|
||||||
if (e->activator != ent)
|
|
||||||
continue;
|
|
||||||
if (strcmp(e->classname, "kamikaze timer"))
|
|
||||||
continue;
|
|
||||||
e->activator = body;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
body->s.powerups = 0; // clear powerups
|
body->s.powerups = 0; // clear powerups
|
||||||
body->s.loopSound = 0; // clear lava burning
|
body->s.loopSound = 0; // clear lava burning
|
||||||
body->s.number = body - g_entities;
|
body->s.number = body - g_entities;
|
||||||
|
|
@ -753,23 +731,11 @@ void ClientUserinfoChanged( int clientNum ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set max health
|
// set max health
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if (client->ps.powerups[PW_GUARD]) {
|
|
||||||
client->pers.maxHealth = 200;
|
|
||||||
} else {
|
|
||||||
health = atoi( Info_ValueForKey( userinfo, "handicap" ) );
|
health = atoi( Info_ValueForKey( userinfo, "handicap" ) );
|
||||||
client->pers.maxHealth = health;
|
client->pers.maxHealth = health;
|
||||||
if ( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 ) {
|
if ( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 ) {
|
||||||
client->pers.maxHealth = 100;
|
client->pers.maxHealth = 100;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#else
|
|
||||||
health = atoi( Info_ValueForKey( userinfo, "handicap" ) );
|
|
||||||
client->pers.maxHealth = health;
|
|
||||||
if ( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 ) {
|
|
||||||
client->pers.maxHealth = 100;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;
|
client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;
|
||||||
|
|
||||||
// set model
|
// set model
|
||||||
|
|
@ -818,18 +784,6 @@ void ClientUserinfoChanged( int clientNum ) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if (g_gametype.integer >= GT_TEAM) {
|
|
||||||
client->pers.teamInfo = qtrue;
|
|
||||||
} else {
|
|
||||||
s = Info_ValueForKey( userinfo, "teamoverlay" );
|
|
||||||
if ( ! *s || atoi( s ) != 0 ) {
|
|
||||||
client->pers.teamInfo = qtrue;
|
|
||||||
} else {
|
|
||||||
client->pers.teamInfo = qfalse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// teamInfo
|
// teamInfo
|
||||||
s = Info_ValueForKey( userinfo, "teamoverlay" );
|
s = Info_ValueForKey( userinfo, "teamoverlay" );
|
||||||
if ( ! *s || atoi( s ) != 0 ) {
|
if ( ! *s || atoi( s ) != 0 ) {
|
||||||
|
|
@ -837,7 +791,6 @@ void ClientUserinfoChanged( int clientNum ) {
|
||||||
} else {
|
} else {
|
||||||
client->pers.teamInfo = qfalse;
|
client->pers.teamInfo = qfalse;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
s = Info_ValueForKey( userinfo, "cg_pmove_fixed" );
|
s = Info_ValueForKey( userinfo, "cg_pmove_fixed" );
|
||||||
if ( !*s || atoi( s ) == 0 ) {
|
if ( !*s || atoi( s ) == 0 ) {
|
||||||
|
|
@ -1305,13 +1258,6 @@ void ClientDisconnect( int clientNum ) {
|
||||||
// They don't get to take powerups with them!
|
// They don't get to take powerups with them!
|
||||||
// Especially important for stuff like CTF flags
|
// Especially important for stuff like CTF flags
|
||||||
TossClientItems( ent );
|
TossClientItems( ent );
|
||||||
#ifdef MISSIONPACK
|
|
||||||
TossClientPersistantPowerups( ent );
|
|
||||||
if( g_gametype.integer == GT_HARVESTER ) {
|
|
||||||
TossClientCubes( ent );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
G_LogPrintf( "ClientDisconnect: %i\n", clientNum );
|
G_LogPrintf( "ClientDisconnect: %i\n", clientNum );
|
||||||
|
|
|
||||||
|
|
@ -126,89 +126,6 @@ void TossClientItems( gentity_t *self ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
TossClientCubes
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
extern gentity_t *neutralObelisk;
|
|
||||||
|
|
||||||
void TossClientCubes( gentity_t *self ) {
|
|
||||||
gitem_t *item;
|
|
||||||
gentity_t *drop;
|
|
||||||
vec3_t velocity;
|
|
||||||
vec3_t angles;
|
|
||||||
vec3_t origin;
|
|
||||||
|
|
||||||
self->client->ps.generic1 = 0;
|
|
||||||
|
|
||||||
// this should never happen but we should never
|
|
||||||
// get the server to crash due to skull being spawned in
|
|
||||||
if (!G_EntitiesFree()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( self->client->sess.sessionTeam == TEAM_RED ) {
|
|
||||||
item = BG_FindItem( "Red Cube" );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
item = BG_FindItem( "Blue Cube" );
|
|
||||||
}
|
|
||||||
|
|
||||||
angles[YAW] = (float)(level.time % 360);
|
|
||||||
angles[PITCH] = 0; // always forward
|
|
||||||
angles[ROLL] = 0;
|
|
||||||
|
|
||||||
AngleVectors( angles, velocity, NULL, NULL );
|
|
||||||
VectorScale( velocity, 150, velocity );
|
|
||||||
velocity[2] += 200 + crandom() * 50;
|
|
||||||
|
|
||||||
if( neutralObelisk ) {
|
|
||||||
VectorCopy( neutralObelisk->s.pos.trBase, origin );
|
|
||||||
origin[2] += 44;
|
|
||||||
} else {
|
|
||||||
VectorClear( origin ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
drop = LaunchItem( item, origin, velocity );
|
|
||||||
|
|
||||||
drop->nextthink = level.time + g_cubeTimeout.integer * 1000;
|
|
||||||
drop->think = G_FreeEntity;
|
|
||||||
drop->spawnflags = self->client->sess.sessionTeam;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
TossClientPersistantPowerups
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
void TossClientPersistantPowerups( gentity_t *ent ) {
|
|
||||||
gentity_t *powerup;
|
|
||||||
|
|
||||||
if( !ent->client ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !ent->client->persistantPowerup ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
powerup = ent->client->persistantPowerup;
|
|
||||||
|
|
||||||
powerup->r.svFlags &= ~SVF_NOCLIENT;
|
|
||||||
powerup->s.eFlags &= ~EF_NODRAW;
|
|
||||||
powerup->r.contents = CONTENTS_TRIGGER;
|
|
||||||
trap_LinkEntity( powerup );
|
|
||||||
|
|
||||||
ent->client->ps.stats[STAT_PERSISTANT_POWERUP] = 0;
|
|
||||||
ent->client->persistantPowerup = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
LookAtKiller
|
LookAtKiller
|
||||||
|
|
@ -307,47 +224,9 @@ char *modNames[] = {
|
||||||
"MOD_SUICIDE",
|
"MOD_SUICIDE",
|
||||||
"MOD_TARGET_LASER",
|
"MOD_TARGET_LASER",
|
||||||
"MOD_TRIGGER_HURT",
|
"MOD_TRIGGER_HURT",
|
||||||
#ifdef MISSIONPACK
|
|
||||||
"MOD_NAIL",
|
|
||||||
"MOD_CHAINGUN",
|
|
||||||
"MOD_PROXIMITY_MINE",
|
|
||||||
"MOD_KAMIKAZE",
|
|
||||||
"MOD_JUICED",
|
|
||||||
#endif
|
|
||||||
"MOD_GRAPPLE"
|
"MOD_GRAPPLE"
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
Kamikaze_DeathActivate
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
void Kamikaze_DeathActivate( gentity_t *ent ) {
|
|
||||||
G_StartKamikaze(ent);
|
|
||||||
G_FreeEntity(ent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
Kamikaze_DeathTimer
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
void Kamikaze_DeathTimer( gentity_t *self ) {
|
|
||||||
gentity_t *ent;
|
|
||||||
|
|
||||||
ent = G_Spawn();
|
|
||||||
ent->classname = "kamikaze timer";
|
|
||||||
VectorCopy(self->s.pos.trBase, ent->s.pos.trBase);
|
|
||||||
ent->r.svFlags |= SVF_NOCLIENT;
|
|
||||||
ent->think = Kamikaze_DeathActivate;
|
|
||||||
ent->nextthink = level.time + 5 * 1000;
|
|
||||||
|
|
||||||
ent->activator = self;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
CheckAlmostCapture
|
CheckAlmostCapture
|
||||||
|
|
@ -460,13 +339,6 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
|
||||||
if (self->client && self->client->hook) {
|
if (self->client && self->client->hook) {
|
||||||
Weapon_HookFree(self->client->hook);
|
Weapon_HookFree(self->client->hook);
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ((self->client->ps.eFlags & EF_TICKING) && self->activator) {
|
|
||||||
self->client->ps.eFlags &= ~EF_TICKING;
|
|
||||||
self->activator->think = G_FreeEntity;
|
|
||||||
self->activator->nextthink = level.time;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
self->client->ps.pm_type = PM_DEAD;
|
self->client->ps.pm_type = PM_DEAD;
|
||||||
|
|
||||||
if ( attacker ) {
|
if ( attacker ) {
|
||||||
|
|
@ -582,12 +454,6 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
|
||||||
Team_ReturnFlag( TEAM_BLUE );
|
Team_ReturnFlag( TEAM_BLUE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
TossClientPersistantPowerups( self );
|
|
||||||
if( g_gametype.integer == GT_HARVESTER ) {
|
|
||||||
TossClientCubes( self );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Cmd_Score_f( self ); // show scores
|
Cmd_Score_f( self ); // show scores
|
||||||
// send updated scores to any clients that are following this one,
|
// send updated scores to any clients that are following this one,
|
||||||
|
|
@ -670,11 +536,6 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
|
||||||
// globally cycle through the different death animations
|
// globally cycle through the different death animations
|
||||||
i = ( i + 1 ) % 3;
|
i = ( i + 1 ) % 3;
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if (self->s.eFlags & EF_KAMIKAZE) {
|
|
||||||
Kamikaze_DeathTimer( self );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trap_LinkEntity (self);
|
trap_LinkEntity (self);
|
||||||
|
|
@ -755,45 +616,6 @@ int RaySphereIntersections( vec3_t origin, float radius, vec3_t point, vec3_t di
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
G_InvulnerabilityEffect
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
int G_InvulnerabilityEffect( gentity_t *targ, vec3_t dir, vec3_t point, vec3_t impactpoint, vec3_t bouncedir ) {
|
|
||||||
gentity_t *impact;
|
|
||||||
vec3_t intersections[2], vec;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
if ( !targ->client ) {
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
VectorCopy(dir, vec);
|
|
||||||
VectorInverse(vec);
|
|
||||||
// sphere model radius = 42 units
|
|
||||||
n = RaySphereIntersections( targ->client->ps.origin, 42, point, vec, intersections);
|
|
||||||
if (n > 0) {
|
|
||||||
impact = G_TempEntity( targ->client->ps.origin, EV_INVUL_IMPACT );
|
|
||||||
VectorSubtract(intersections[0], targ->client->ps.origin, vec);
|
|
||||||
vectoangles(vec, impact->s.angles);
|
|
||||||
impact->s.angles[0] += 90;
|
|
||||||
if (impact->s.angles[0] > 360)
|
|
||||||
impact->s.angles[0] -= 360;
|
|
||||||
if ( impactpoint ) {
|
|
||||||
VectorCopy( intersections[0], impactpoint );
|
|
||||||
}
|
|
||||||
if ( bouncedir ) {
|
|
||||||
VectorCopy( vec, bouncedir );
|
|
||||||
VectorNormalize( bouncedir );
|
|
||||||
}
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
============
|
============
|
||||||
T_Damage
|
T_Damage
|
||||||
|
|
@ -826,9 +648,6 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
||||||
int asave;
|
int asave;
|
||||||
int knockback;
|
int knockback;
|
||||||
int max;
|
int max;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
vec3_t bouncedir, impactpoint;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!targ->takedamage) {
|
if (!targ->takedamage) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -839,16 +658,6 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
||||||
if ( level.intermissionQueued ) {
|
if ( level.intermissionQueued ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ( targ->client && mod != MOD_JUICED) {
|
|
||||||
if ( targ->client->invulnerabilityTime > level.time) {
|
|
||||||
if ( dir && point ) {
|
|
||||||
G_InvulnerabilityEffect( targ, dir, point, impactpoint, bouncedir );
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if ( !inflictor ) {
|
if ( !inflictor ) {
|
||||||
inflictor = &g_entities[ENTITYNUM_WORLD];
|
inflictor = &g_entities[ENTITYNUM_WORLD];
|
||||||
}
|
}
|
||||||
|
|
@ -863,20 +672,10 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( g_gametype.integer == GT_OBELISK && CheckObeliskAttack( targ, attacker ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// reduce damage by the attacker's handicap value
|
// reduce damage by the attacker's handicap value
|
||||||
// unless they are rocket jumping
|
// unless they are rocket jumping
|
||||||
if ( attacker->client && attacker != targ ) {
|
if ( attacker->client && attacker != targ ) {
|
||||||
max = attacker->client->ps.stats[STAT_MAX_HEALTH];
|
max = attacker->client->ps.stats[STAT_MAX_HEALTH];
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( bg_itemlist[attacker->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
|
|
||||||
max /= 2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
damage = damage * max / 100;
|
damage = damage * max / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -937,25 +736,11 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
||||||
|
|
||||||
// if TF_NO_FRIENDLY_FIRE is set, don't do damage to the target
|
// if TF_NO_FRIENDLY_FIRE is set, don't do damage to the target
|
||||||
// if the attacker was on the same team
|
// if the attacker was on the same team
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ( mod != MOD_JUICED && targ != attacker && !(dflags & DAMAGE_NO_TEAM_PROTECTION) && OnSameTeam (targ, attacker) ) {
|
|
||||||
#else
|
|
||||||
if ( targ != attacker && OnSameTeam (targ, attacker) ) {
|
if ( targ != attacker && OnSameTeam (targ, attacker) ) {
|
||||||
#endif
|
|
||||||
if ( !g_friendlyFire.integer ) {
|
if ( !g_friendlyFire.integer ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if (mod == MOD_PROXIMITY_MINE) {
|
|
||||||
if (inflictor && inflictor->parent && OnSameTeam(targ, inflictor->parent)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (targ == attacker) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// check for godmode
|
// check for godmode
|
||||||
if ( targ->flags & FL_GODMODE ) {
|
if ( targ->flags & FL_GODMODE ) {
|
||||||
|
|
@ -1028,11 +813,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if it's the player hurting the emeny flag carrier
|
// See if it's the player hurting the emeny flag carrier
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( g_gametype.integer == GT_CTF || g_gametype.integer == GT_1FCTF ) {
|
|
||||||
#else
|
|
||||||
if( g_gametype.integer == GT_CTF) {
|
if( g_gametype.integer == GT_CTF) {
|
||||||
#endif
|
|
||||||
Team_CheckHurtCarrier(targ, attacker);
|
Team_CheckHurtCarrier(targ, attacker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,82 +116,6 @@ int Pickup_Powerup( gentity_t *ent, gentity_t *other ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) {
|
|
||||||
int clientNum;
|
|
||||||
char userinfo[MAX_INFO_STRING];
|
|
||||||
float handicap;
|
|
||||||
int max;
|
|
||||||
|
|
||||||
other->client->ps.stats[STAT_PERSISTANT_POWERUP] = ent->item - bg_itemlist;
|
|
||||||
other->client->persistantPowerup = ent;
|
|
||||||
|
|
||||||
switch( ent->item->giTag ) {
|
|
||||||
case PW_GUARD:
|
|
||||||
clientNum = other->client->ps.clientNum;
|
|
||||||
trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) );
|
|
||||||
handicap = atof( Info_ValueForKey( userinfo, "handicap" ) );
|
|
||||||
if( handicap<=0.0f || handicap>100.0f) {
|
|
||||||
handicap = 100.0f;
|
|
||||||
}
|
|
||||||
max = (int)(2 * handicap);
|
|
||||||
|
|
||||||
other->health = max;
|
|
||||||
other->client->ps.stats[STAT_HEALTH] = max;
|
|
||||||
other->client->ps.stats[STAT_MAX_HEALTH] = max;
|
|
||||||
other->client->ps.stats[STAT_ARMOR] = max;
|
|
||||||
other->client->pers.maxHealth = max;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PW_SCOUT:
|
|
||||||
clientNum = other->client->ps.clientNum;
|
|
||||||
trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) );
|
|
||||||
handicap = atof( Info_ValueForKey( userinfo, "handicap" ) );
|
|
||||||
if( handicap<=0.0f || handicap>100.0f) {
|
|
||||||
handicap = 100.0f;
|
|
||||||
}
|
|
||||||
other->client->pers.maxHealth = handicap;
|
|
||||||
other->client->ps.stats[STAT_ARMOR] = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PW_DOUBLER:
|
|
||||||
clientNum = other->client->ps.clientNum;
|
|
||||||
trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) );
|
|
||||||
handicap = atof( Info_ValueForKey( userinfo, "handicap" ) );
|
|
||||||
if( handicap<=0.0f || handicap>100.0f) {
|
|
||||||
handicap = 100.0f;
|
|
||||||
}
|
|
||||||
other->client->pers.maxHealth = handicap;
|
|
||||||
break;
|
|
||||||
case PW_AMMOREGEN:
|
|
||||||
clientNum = other->client->ps.clientNum;
|
|
||||||
trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) );
|
|
||||||
handicap = atof( Info_ValueForKey( userinfo, "handicap" ) );
|
|
||||||
if( handicap<=0.0f || handicap>100.0f) {
|
|
||||||
handicap = 100.0f;
|
|
||||||
}
|
|
||||||
other->client->pers.maxHealth = handicap;
|
|
||||||
memset(other->client->ammoTimes, 0, sizeof(other->client->ammoTimes));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
clientNum = other->client->ps.clientNum;
|
|
||||||
trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) );
|
|
||||||
handicap = atof( Info_ValueForKey( userinfo, "handicap" ) );
|
|
||||||
if( handicap<=0.0f || handicap>100.0f) {
|
|
||||||
handicap = 100.0f;
|
|
||||||
}
|
|
||||||
other->client->pers.maxHealth = handicap;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//======================================================================
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int Pickup_Holdable( gentity_t *ent, gentity_t *other ) {
|
int Pickup_Holdable( gentity_t *ent, gentity_t *other ) {
|
||||||
|
|
||||||
other->client->ps.stats[STAT_HOLDABLE_ITEM] = ent->item - bg_itemlist;
|
other->client->ps.stats[STAT_HOLDABLE_ITEM] = ent->item - bg_itemlist;
|
||||||
|
|
@ -280,12 +204,6 @@ int Pickup_Health (gentity_t *ent, gentity_t *other) {
|
||||||
int quantity;
|
int quantity;
|
||||||
|
|
||||||
// small and mega healths will go over the max
|
// small and mega healths will go over the max
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( other->client && bg_itemlist[other->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
|
|
||||||
max = other->client->ps.stats[STAT_MAX_HEALTH];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if ( ent->item->quantity != 5 && ent->item->quantity != 100 ) {
|
if ( ent->item->quantity != 5 && ent->item->quantity != 100 ) {
|
||||||
max = other->client->ps.stats[STAT_MAX_HEALTH];
|
max = other->client->ps.stats[STAT_MAX_HEALTH];
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -315,28 +233,10 @@ int Pickup_Health (gentity_t *ent, gentity_t *other) {
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
int Pickup_Armor( gentity_t *ent, gentity_t *other ) {
|
int Pickup_Armor( gentity_t *ent, gentity_t *other ) {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
int upperBound;
|
|
||||||
|
|
||||||
other->client->ps.stats[STAT_ARMOR] += ent->item->quantity;
|
|
||||||
|
|
||||||
if( other->client && bg_itemlist[other->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
|
|
||||||
upperBound = other->client->ps.stats[STAT_MAX_HEALTH];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
upperBound = other->client->ps.stats[STAT_MAX_HEALTH] * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( other->client->ps.stats[STAT_ARMOR] > upperBound ) {
|
|
||||||
other->client->ps.stats[STAT_ARMOR] = upperBound;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
other->client->ps.stats[STAT_ARMOR] += ent->item->quantity;
|
other->client->ps.stats[STAT_ARMOR] += ent->item->quantity;
|
||||||
if ( other->client->ps.stats[STAT_ARMOR] > other->client->ps.stats[STAT_MAX_HEALTH] * 2 ) {
|
if ( other->client->ps.stats[STAT_ARMOR] > other->client->ps.stats[STAT_MAX_HEALTH] * 2 ) {
|
||||||
other->client->ps.stats[STAT_ARMOR] = other->client->ps.stats[STAT_MAX_HEALTH] * 2;
|
other->client->ps.stats[STAT_ARMOR] = other->client->ps.stats[STAT_MAX_HEALTH] * 2;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return RESPAWN_ARMOR;
|
return RESPAWN_ARMOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -453,11 +353,6 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
||||||
respawn = Pickup_Powerup(ent, other);
|
respawn = Pickup_Powerup(ent, other);
|
||||||
predict = qfalse;
|
predict = qfalse;
|
||||||
break;
|
break;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
case IT_PERSISTANT_POWERUP:
|
|
||||||
respawn = Pickup_PersistantPowerup(ent, other);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case IT_TEAM:
|
case IT_TEAM:
|
||||||
respawn = Pickup_Team(ent, other);
|
respawn = Pickup_Team(ent, other);
|
||||||
break;
|
break;
|
||||||
|
|
@ -583,11 +478,7 @@ gentity_t *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity ) {
|
||||||
VectorCopy( velocity, dropped->s.pos.trDelta );
|
VectorCopy( velocity, dropped->s.pos.trDelta );
|
||||||
|
|
||||||
dropped->s.eFlags |= EF_BOUNCE_HALF;
|
dropped->s.eFlags |= EF_BOUNCE_HALF;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ((g_gametype.integer == GT_CTF || g_gametype.integer == GT_1FCTF) && item->giType == IT_TEAM) { // Special case for CTF flags
|
|
||||||
#else
|
|
||||||
if (g_gametype.integer == GT_CTF && item->giType == IT_TEAM) { // Special case for CTF flags
|
if (g_gametype.integer == GT_CTF && item->giType == IT_TEAM) { // Special case for CTF flags
|
||||||
#endif
|
|
||||||
dropped->think = Team_DroppedFlagThink;
|
dropped->think = Team_DroppedFlagThink;
|
||||||
dropped->nextthink = level.time + 30000;
|
dropped->nextthink = level.time + 30000;
|
||||||
Team_CheckDroppedItem( dropped );
|
Team_CheckDroppedItem( dropped );
|
||||||
|
|
@ -731,65 +622,6 @@ void G_CheckTeamItems( void ) {
|
||||||
G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map" );
|
G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( g_gametype.integer == GT_1FCTF ) {
|
|
||||||
gitem_t *item;
|
|
||||||
|
|
||||||
// check for all three flags
|
|
||||||
item = BG_FindItem( "Red Flag" );
|
|
||||||
if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
|
|
||||||
G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_redflag in map" );
|
|
||||||
}
|
|
||||||
item = BG_FindItem( "Blue Flag" );
|
|
||||||
if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
|
|
||||||
G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map" );
|
|
||||||
}
|
|
||||||
item = BG_FindItem( "Neutral Flag" );
|
|
||||||
if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
|
|
||||||
G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_neutralflag in map" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( g_gametype.integer == GT_OBELISK ) {
|
|
||||||
gentity_t *ent;
|
|
||||||
|
|
||||||
// check for the two obelisks
|
|
||||||
ent = NULL;
|
|
||||||
ent = G_Find( ent, FOFS(classname), "team_redobelisk" );
|
|
||||||
if( !ent ) {
|
|
||||||
G_Printf( S_COLOR_YELLOW "WARNING: No team_redobelisk in map" );
|
|
||||||
}
|
|
||||||
|
|
||||||
ent = NULL;
|
|
||||||
ent = G_Find( ent, FOFS(classname), "team_blueobelisk" );
|
|
||||||
if( !ent ) {
|
|
||||||
G_Printf( S_COLOR_YELLOW "WARNING: No team_blueobelisk in map" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( g_gametype.integer == GT_HARVESTER ) {
|
|
||||||
gentity_t *ent;
|
|
||||||
|
|
||||||
// check for all three obelisks
|
|
||||||
ent = NULL;
|
|
||||||
ent = G_Find( ent, FOFS(classname), "team_redobelisk" );
|
|
||||||
if( !ent ) {
|
|
||||||
G_Printf( S_COLOR_YELLOW "WARNING: No team_redobelisk in map" );
|
|
||||||
}
|
|
||||||
|
|
||||||
ent = NULL;
|
|
||||||
ent = G_Find( ent, FOFS(classname), "team_blueobelisk" );
|
|
||||||
if( !ent ) {
|
|
||||||
G_Printf( S_COLOR_YELLOW "WARNING: No team_blueobelisk in map" );
|
|
||||||
}
|
|
||||||
|
|
||||||
ent = NULL;
|
|
||||||
ent = G_Find( ent, FOFS(classname), "team_neutralobelisk" );
|
|
||||||
if( !ent ) {
|
|
||||||
G_Printf( S_COLOR_YELLOW "WARNING: No team_neutralobelisk in map" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -803,12 +635,6 @@ void ClearRegisteredItems( void ) {
|
||||||
// players always start with the base weapon
|
// players always start with the base weapon
|
||||||
RegisterItem( BG_FindItemForWeapon( WP_MACHINEGUN ) );
|
RegisterItem( BG_FindItemForWeapon( WP_MACHINEGUN ) );
|
||||||
RegisterItem( BG_FindItemForWeapon( WP_GAUNTLET ) );
|
RegisterItem( BG_FindItemForWeapon( WP_GAUNTLET ) );
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( g_gametype.integer == GT_HARVESTER ) {
|
|
||||||
RegisterItem( BG_FindItem( "Red Cube" ) );
|
|
||||||
RegisterItem( BG_FindItem( "Blue Cube" ) );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -897,12 +723,6 @@ void G_SpawnItem (gentity_t *ent, gitem_t *item) {
|
||||||
G_SoundIndex( "sound/items/poweruprespawn.wav" );
|
G_SoundIndex( "sound/items/poweruprespawn.wav" );
|
||||||
G_SpawnFloat( "noglobalsound", "0", &ent->speed);
|
G_SpawnFloat( "noglobalsound", "0", &ent->speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ( item->giType == IT_PERSISTANT_POWERUP ) {
|
|
||||||
ent->s.generic1 = ent->spawnflags;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -160,11 +160,6 @@ struct gentity_s {
|
||||||
gentity_t *teamchain; // next entity in team
|
gentity_t *teamchain; // next entity in team
|
||||||
gentity_t *teammaster; // master of the team
|
gentity_t *teammaster; // master of the team
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
int kamikazeTime;
|
|
||||||
int kamikazeShockTime;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int watertype;
|
int watertype;
|
||||||
int waterlevel;
|
int waterlevel;
|
||||||
|
|
||||||
|
|
@ -315,13 +310,6 @@ struct gclient_s {
|
||||||
// like health / armor countdowns and regeneration
|
// like health / armor countdowns and regeneration
|
||||||
int timeResidual;
|
int timeResidual;
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
gentity_t *persistantPowerup;
|
|
||||||
int portalID;
|
|
||||||
int ammoTimes[WP_NUM_WEAPONS];
|
|
||||||
int invulnerabilityTime;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *areabits;
|
char *areabits;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -410,9 +398,6 @@ typedef struct {
|
||||||
gentity_t *locationHead; // head of the location list
|
gentity_t *locationHead; // head of the location list
|
||||||
int bodyQueIndex; // dead bodies
|
int bodyQueIndex; // dead bodies
|
||||||
gentity_t *bodyQue[BODY_QUEUE_SIZE];
|
gentity_t *bodyQue[BODY_QUEUE_SIZE];
|
||||||
#ifdef MISSIONPACK
|
|
||||||
int portalSequence;
|
|
||||||
#endif
|
|
||||||
} level_locals_t;
|
} level_locals_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -501,9 +486,6 @@ qboolean G_RadiusDamage (vec3_t origin, gentity_t *attacker, float damage, float
|
||||||
int G_InvulnerabilityEffect( gentity_t *targ, vec3_t dir, vec3_t point, vec3_t impactpoint, vec3_t bouncedir );
|
int G_InvulnerabilityEffect( gentity_t *targ, vec3_t dir, vec3_t point, vec3_t impactpoint, vec3_t bouncedir );
|
||||||
void body_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath );
|
void body_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath );
|
||||||
void TossClientItems( gentity_t *self );
|
void TossClientItems( gentity_t *self );
|
||||||
#ifdef MISSIONPACK
|
|
||||||
void TossClientPersistantPowerups( gentity_t *self );
|
|
||||||
#endif
|
|
||||||
void TossClientCubes( gentity_t *self );
|
void TossClientCubes( gentity_t *self );
|
||||||
|
|
||||||
// damage flags
|
// damage flags
|
||||||
|
|
@ -511,9 +493,6 @@ void TossClientCubes( gentity_t *self );
|
||||||
#define DAMAGE_NO_ARMOR 0x00000002 // armour does not protect from this damage
|
#define DAMAGE_NO_ARMOR 0x00000002 // armour does not protect from this damage
|
||||||
#define DAMAGE_NO_KNOCKBACK 0x00000004 // do not affect velocity, just view angles
|
#define DAMAGE_NO_KNOCKBACK 0x00000004 // do not affect velocity, just view angles
|
||||||
#define DAMAGE_NO_PROTECTION 0x00000008 // armor, shields, invulnerability, and godmode have no effect
|
#define DAMAGE_NO_PROTECTION 0x00000008 // armor, shields, invulnerability, and godmode have no effect
|
||||||
#ifdef MISSIONPACK
|
|
||||||
#define DAMAGE_NO_TEAM_PROTECTION 0x00000010 // armor, shields, invulnerability, and godmode have no effect
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// g_missile.c
|
// g_missile.c
|
||||||
|
|
@ -526,10 +505,6 @@ gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t aimdir);
|
||||||
gentity_t *fire_rocket (gentity_t *self, vec3_t start, vec3_t dir);
|
gentity_t *fire_rocket (gentity_t *self, vec3_t start, vec3_t dir);
|
||||||
gentity_t *fire_bfg (gentity_t *self, vec3_t start, vec3_t dir);
|
gentity_t *fire_bfg (gentity_t *self, vec3_t start, vec3_t dir);
|
||||||
gentity_t *fire_grapple (gentity_t *self, vec3_t start, vec3_t dir);
|
gentity_t *fire_grapple (gentity_t *self, vec3_t start, vec3_t dir);
|
||||||
#ifdef MISSIONPACK
|
|
||||||
gentity_t *fire_nail( gentity_t *self, vec3_t start, vec3_t forward, vec3_t right, vec3_t up );
|
|
||||||
gentity_t *fire_prox( gentity_t *self, vec3_t start, vec3_t aimdir );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -548,10 +523,6 @@ void trigger_teleporter_touch (gentity_t *self, gentity_t *other, trace_t *trace
|
||||||
// g_misc.c
|
// g_misc.c
|
||||||
//
|
//
|
||||||
void TeleportPlayer( gentity_t *player, vec3_t origin, vec3_t angles );
|
void TeleportPlayer( gentity_t *player, vec3_t origin, vec3_t angles );
|
||||||
#ifdef MISSIONPACK
|
|
||||||
void DropPortalSource( gentity_t *ent );
|
|
||||||
void DropPortalDestination( gentity_t *ent );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -596,9 +567,6 @@ qboolean G_FilterPacket (char *from);
|
||||||
// g_weapon.c
|
// g_weapon.c
|
||||||
//
|
//
|
||||||
void FireWeapon( gentity_t *ent );
|
void FireWeapon( gentity_t *ent );
|
||||||
#ifdef MISSIONPACK
|
|
||||||
void G_StartKamikaze( gentity_t *ent );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// p_hud.c
|
// p_hud.c
|
||||||
|
|
|
||||||
|
|
@ -81,19 +81,6 @@ vmCvar_t pmove_fixed;
|
||||||
vmCvar_t pmove_msec;
|
vmCvar_t pmove_msec;
|
||||||
vmCvar_t g_rankings;
|
vmCvar_t g_rankings;
|
||||||
vmCvar_t g_listEntity;
|
vmCvar_t g_listEntity;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
vmCvar_t g_obeliskHealth;
|
|
||||||
vmCvar_t g_obeliskRegenPeriod;
|
|
||||||
vmCvar_t g_obeliskRegenAmount;
|
|
||||||
vmCvar_t g_obeliskRespawnDelay;
|
|
||||||
vmCvar_t g_cubeTimeout;
|
|
||||||
vmCvar_t g_redteam;
|
|
||||||
vmCvar_t g_blueteam;
|
|
||||||
vmCvar_t g_singlePlayer;
|
|
||||||
vmCvar_t g_enableDust;
|
|
||||||
vmCvar_t g_enableBreath;
|
|
||||||
vmCvar_t g_proxMineTimeout;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// bk001129 - made static to avoid aliasing
|
// bk001129 - made static to avoid aliasing
|
||||||
static cvarTable_t gameCvarTable[] = {
|
static cvarTable_t gameCvarTable[] = {
|
||||||
|
|
@ -159,21 +146,6 @@ static cvarTable_t gameCvarTable[] = {
|
||||||
{ &g_allowVote, "g_allowVote", "1", CVAR_ARCHIVE, 0, qfalse },
|
{ &g_allowVote, "g_allowVote", "1", CVAR_ARCHIVE, 0, qfalse },
|
||||||
{ &g_listEntity, "g_listEntity", "0", 0, 0, qfalse },
|
{ &g_listEntity, "g_listEntity", "0", 0, 0, qfalse },
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
{ &g_obeliskHealth, "g_obeliskHealth", "2500", 0, 0, qfalse },
|
|
||||||
{ &g_obeliskRegenPeriod, "g_obeliskRegenPeriod", "1", 0, 0, qfalse },
|
|
||||||
{ &g_obeliskRegenAmount, "g_obeliskRegenAmount", "15", 0, 0, qfalse },
|
|
||||||
{ &g_obeliskRespawnDelay, "g_obeliskRespawnDelay", "10", CVAR_SERVERINFO, 0, qfalse },
|
|
||||||
|
|
||||||
{ &g_cubeTimeout, "g_cubeTimeout", "30", 0, 0, qfalse },
|
|
||||||
{ &g_redteam, "g_redteam", "Stroggs", CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_USERINFO , 0, qtrue, qtrue },
|
|
||||||
{ &g_blueteam, "g_blueteam", "Pagans", CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_USERINFO , 0, qtrue, qtrue },
|
|
||||||
{ &g_singlePlayer, "ui_singlePlayerActive", "", 0, 0, qfalse, qfalse },
|
|
||||||
|
|
||||||
{ &g_enableDust, "g_enableDust", "0", CVAR_SERVERINFO, 0, qtrue, qfalse },
|
|
||||||
{ &g_enableBreath, "g_enableBreath", "0", CVAR_SERVERINFO, 0, qtrue, qfalse },
|
|
||||||
{ &g_proxMineTimeout, "g_proxMineTimeout", "20000", 0, 0, qfalse },
|
|
||||||
#endif
|
|
||||||
{ &g_smoothClients, "g_smoothClients", "1", 0, 0, qfalse},
|
{ &g_smoothClients, "g_smoothClients", "1", 0, 0, qfalse},
|
||||||
{ &pmove_fixed, "pmove_fixed", "0", CVAR_SYSTEMINFO, 0, qfalse},
|
{ &pmove_fixed, "pmove_fixed", "0", CVAR_SYSTEMINFO, 0, qfalse},
|
||||||
{ &pmove_msec, "pmove_msec", "8", CVAR_SYSTEMINFO, 0, qfalse},
|
{ &pmove_msec, "pmove_msec", "8", CVAR_SYSTEMINFO, 0, qfalse},
|
||||||
|
|
@ -317,17 +289,6 @@ void G_FindTeams( void ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void G_RemapTeamShaders() {
|
void G_RemapTeamShaders() {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
char string[1024];
|
|
||||||
float f = level.time * 0.001;
|
|
||||||
Com_sprintf( string, sizeof(string), "team_icon/%s_red", g_redteam.string );
|
|
||||||
AddRemap("textures/ctf2/redteam01", string, f);
|
|
||||||
AddRemap("textures/ctf2/redteam02", string, f);
|
|
||||||
Com_sprintf( string, sizeof(string), "team_icon/%s_blue", g_blueteam.string );
|
|
||||||
AddRemap("textures/ctf2/blueteam01", string, f);
|
|
||||||
AddRemap("textures/ctf2/blueteam02", string, f);
|
|
||||||
trap_SetConfigstring(CS_SHADERSTATE, BuildShaderStateConfig());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -978,18 +939,11 @@ void BeginIntermission( void ) {
|
||||||
level.intermissiontime = level.time;
|
level.intermissiontime = level.time;
|
||||||
FindIntermissionPoint();
|
FindIntermissionPoint();
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if (g_singlePlayer.integer) {
|
|
||||||
trap_Cvar_Set("ui_singlePlayerActive", "0");
|
|
||||||
UpdateTournamentInfo();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// if single player game
|
// if single player game
|
||||||
if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
|
if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
|
||||||
UpdateTournamentInfo();
|
UpdateTournamentInfo();
|
||||||
SpawnModelsOnVictoryPads();
|
SpawnModelsOnVictoryPads();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// move all clients to the intermission point
|
// move all clients to the intermission point
|
||||||
for (i=0 ; i< level.maxclients ; i++) {
|
for (i=0 ; i< level.maxclients ; i++) {
|
||||||
|
|
@ -1113,9 +1067,7 @@ Append information about this game to the log file
|
||||||
void LogExit( const char *string ) {
|
void LogExit( const char *string ) {
|
||||||
int i, numSorted;
|
int i, numSorted;
|
||||||
gclient_t *cl;
|
gclient_t *cl;
|
||||||
#ifdef MISSIONPACK // bk001205
|
|
||||||
qboolean won = qtrue;
|
|
||||||
#endif
|
|
||||||
G_LogPrintf( "Exit: %s\n", string );
|
G_LogPrintf( "Exit: %s\n", string );
|
||||||
|
|
||||||
level.intermissionQueued = level.time;
|
level.intermissionQueued = level.time;
|
||||||
|
|
@ -1150,26 +1102,7 @@ void LogExit( const char *string ) {
|
||||||
ping = cl->ps.ping < 999 ? cl->ps.ping : 999;
|
ping = cl->ps.ping < 999 ? cl->ps.ping : 999;
|
||||||
|
|
||||||
G_LogPrintf( "score: %i ping: %i client: %i %s\n", cl->ps.persistant[PERS_SCORE], ping, level.sortedClients[i], cl->pers.netname );
|
G_LogPrintf( "score: %i ping: %i client: %i %s\n", cl->ps.persistant[PERS_SCORE], ping, level.sortedClients[i], cl->pers.netname );
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if (g_singlePlayer.integer && g_gametype.integer == GT_TOURNAMENT) {
|
|
||||||
if (g_entities[cl - level.clients].r.svFlags & SVF_BOT && cl->ps.persistant[PERS_RANK] == 0) {
|
|
||||||
won = qfalse;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if (g_singlePlayer.integer) {
|
|
||||||
if (g_gametype.integer >= GT_CTF) {
|
|
||||||
won = level.teamScores[TEAM_RED] > level.teamScores[TEAM_BLUE];
|
|
||||||
}
|
|
||||||
trap_SendConsoleCommand( EXEC_APPEND, (won) ? "spWin\n" : "spLose\n" );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1300,18 +1233,10 @@ void CheckExitRules( void ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( level.intermissionQueued ) {
|
if ( level.intermissionQueued ) {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
int time = (g_singlePlayer.integer) ? SP_INTERMISSION_DELAY_TIME : INTERMISSION_DELAY_TIME;
|
|
||||||
if ( level.time - level.intermissionQueued >= time ) {
|
|
||||||
level.intermissionQueued = 0;
|
|
||||||
BeginIntermission();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if ( level.time - level.intermissionQueued >= INTERMISSION_DELAY_TIME ) {
|
if ( level.time - level.intermissionQueued >= INTERMISSION_DELAY_TIME ) {
|
||||||
level.intermissionQueued = 0;
|
level.intermissionQueued = 0;
|
||||||
BeginIntermission();
|
BeginIntermission();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -335,148 +335,3 @@ Fires at either the target or the current direction.
|
||||||
void SP_shooter_grenade( gentity_t *ent ) {
|
void SP_shooter_grenade( gentity_t *ent ) {
|
||||||
InitShooter( ent, WP_GRENADE_LAUNCHER);
|
InitShooter( ent, WP_GRENADE_LAUNCHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
static void PortalDie (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod) {
|
|
||||||
G_FreeEntity( self );
|
|
||||||
//FIXME do something more interesting
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DropPortalDestination( gentity_t *player ) {
|
|
||||||
gentity_t *ent;
|
|
||||||
vec3_t snapped;
|
|
||||||
|
|
||||||
// create the portal destination
|
|
||||||
ent = G_Spawn();
|
|
||||||
ent->s.modelindex = G_ModelIndex( "models/powerups/teleporter/tele_exit.md3" );
|
|
||||||
|
|
||||||
VectorCopy( player->s.pos.trBase, snapped );
|
|
||||||
SnapVector( snapped );
|
|
||||||
G_SetOrigin( ent, snapped );
|
|
||||||
VectorCopy( player->r.mins, ent->r.mins );
|
|
||||||
VectorCopy( player->r.maxs, ent->r.maxs );
|
|
||||||
|
|
||||||
ent->classname = "hi_portal destination";
|
|
||||||
ent->s.pos.trType = TR_STATIONARY;
|
|
||||||
|
|
||||||
ent->r.contents = CONTENTS_CORPSE;
|
|
||||||
ent->takedamage = qtrue;
|
|
||||||
ent->health = 200;
|
|
||||||
ent->die = PortalDie;
|
|
||||||
|
|
||||||
VectorCopy( player->s.apos.trBase, ent->s.angles );
|
|
||||||
|
|
||||||
ent->think = G_FreeEntity;
|
|
||||||
ent->nextthink = level.time + 2 * 60 * 1000;
|
|
||||||
|
|
||||||
trap_LinkEntity( ent );
|
|
||||||
|
|
||||||
player->client->portalID = ++level.portalSequence;
|
|
||||||
ent->count = player->client->portalID;
|
|
||||||
|
|
||||||
// give the item back so they can drop the source now
|
|
||||||
player->client->ps.stats[STAT_HOLDABLE_ITEM] = BG_FindItem( "Portal" ) - bg_itemlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void PortalTouch( gentity_t *self, gentity_t *other, trace_t *trace) {
|
|
||||||
gentity_t *destination;
|
|
||||||
|
|
||||||
// see if we will even let other try to use it
|
|
||||||
if( other->health <= 0 ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if( !other->client ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// if( other->client->ps.persistant[PERS_TEAM] != self->spawnflags ) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if ( other->client->ps.powerups[PW_NEUTRALFLAG] ) { // only happens in One Flag CTF
|
|
||||||
Drop_Item( other, BG_FindItemForPowerup( PW_NEUTRALFLAG ), 0 );
|
|
||||||
other->client->ps.powerups[PW_NEUTRALFLAG] = 0;
|
|
||||||
}
|
|
||||||
else if ( other->client->ps.powerups[PW_REDFLAG] ) { // only happens in standard CTF
|
|
||||||
Drop_Item( other, BG_FindItemForPowerup( PW_REDFLAG ), 0 );
|
|
||||||
other->client->ps.powerups[PW_REDFLAG] = 0;
|
|
||||||
}
|
|
||||||
else if ( other->client->ps.powerups[PW_BLUEFLAG] ) { // only happens in standard CTF
|
|
||||||
Drop_Item( other, BG_FindItemForPowerup( PW_BLUEFLAG ), 0 );
|
|
||||||
other->client->ps.powerups[PW_BLUEFLAG] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the destination
|
|
||||||
destination = NULL;
|
|
||||||
while( (destination = G_Find(destination, FOFS(classname), "hi_portal destination")) != NULL ) {
|
|
||||||
if( destination->count == self->count ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if there is not one, die!
|
|
||||||
if( !destination ) {
|
|
||||||
if( self->pos1[0] || self->pos1[1] || self->pos1[2] ) {
|
|
||||||
TeleportPlayer( other, self->pos1, self->s.angles );
|
|
||||||
}
|
|
||||||
G_Damage( other, other, other, NULL, NULL, 100000, DAMAGE_NO_PROTECTION, MOD_TELEFRAG );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TeleportPlayer( other, destination->s.pos.trBase, destination->s.angles );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void PortalEnable( gentity_t *self ) {
|
|
||||||
self->touch = PortalTouch;
|
|
||||||
self->think = G_FreeEntity;
|
|
||||||
self->nextthink = level.time + 2 * 60 * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DropPortalSource( gentity_t *player ) {
|
|
||||||
gentity_t *ent;
|
|
||||||
gentity_t *destination;
|
|
||||||
vec3_t snapped;
|
|
||||||
|
|
||||||
// create the portal source
|
|
||||||
ent = G_Spawn();
|
|
||||||
ent->s.modelindex = G_ModelIndex( "models/powerups/teleporter/tele_enter.md3" );
|
|
||||||
|
|
||||||
VectorCopy( player->s.pos.trBase, snapped );
|
|
||||||
SnapVector( snapped );
|
|
||||||
G_SetOrigin( ent, snapped );
|
|
||||||
VectorCopy( player->r.mins, ent->r.mins );
|
|
||||||
VectorCopy( player->r.maxs, ent->r.maxs );
|
|
||||||
|
|
||||||
ent->classname = "hi_portal source";
|
|
||||||
ent->s.pos.trType = TR_STATIONARY;
|
|
||||||
|
|
||||||
ent->r.contents = CONTENTS_CORPSE | CONTENTS_TRIGGER;
|
|
||||||
ent->takedamage = qtrue;
|
|
||||||
ent->health = 200;
|
|
||||||
ent->die = PortalDie;
|
|
||||||
|
|
||||||
trap_LinkEntity( ent );
|
|
||||||
|
|
||||||
ent->count = player->client->portalID;
|
|
||||||
player->client->portalID = 0;
|
|
||||||
|
|
||||||
// ent->spawnflags = player->client->ps.persistant[PERS_TEAM];
|
|
||||||
|
|
||||||
ent->nextthink = level.time + 1000;
|
|
||||||
ent->think = PortalEnable;
|
|
||||||
|
|
||||||
// find the destination
|
|
||||||
destination = NULL;
|
|
||||||
while( (destination = G_Find(destination, FOFS(classname), "hi_portal destination")) != NULL ) {
|
|
||||||
if( destination->count == ent->count ) {
|
|
||||||
VectorCopy( destination->s.pos.trBase, ent->pos1 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|
|
@ -91,176 +91,6 @@ void G_ExplodeMissile( gentity_t *ent ) {
|
||||||
trap_LinkEntity( ent );
|
trap_LinkEntity( ent );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
ProximityMine_Explode
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
static void ProximityMine_Explode( gentity_t *mine ) {
|
|
||||||
G_ExplodeMissile( mine );
|
|
||||||
// if the prox mine has a trigger free it
|
|
||||||
if (mine->activator) {
|
|
||||||
G_FreeEntity(mine->activator);
|
|
||||||
mine->activator = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
ProximityMine_Die
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
static void ProximityMine_Die( gentity_t *ent, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ) {
|
|
||||||
ent->think = ProximityMine_Explode;
|
|
||||||
ent->nextthink = level.time + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
ProximityMine_Trigger
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
void ProximityMine_Trigger( gentity_t *trigger, gentity_t *other, trace_t *trace ) {
|
|
||||||
vec3_t v;
|
|
||||||
gentity_t *mine;
|
|
||||||
|
|
||||||
if( !other->client ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trigger is a cube, do a distance test now to act as if it's a sphere
|
|
||||||
VectorSubtract( trigger->s.pos.trBase, other->s.pos.trBase, v );
|
|
||||||
if( VectorLength( v ) > trigger->parent->splashRadius ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ( g_gametype.integer >= GT_TEAM ) {
|
|
||||||
// don't trigger same team mines
|
|
||||||
if (trigger->parent->s.generic1 == other->client->sess.sessionTeam) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ok, now check for ability to damage so we don't get triggered thru walls, closed doors, etc...
|
|
||||||
if( !CanDamage( other, trigger->s.pos.trBase ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trigger the mine!
|
|
||||||
mine = trigger->parent;
|
|
||||||
mine->s.loopSound = 0;
|
|
||||||
G_AddEvent( mine, EV_PROXIMITY_MINE_TRIGGER, 0 );
|
|
||||||
mine->nextthink = level.time + 500;
|
|
||||||
|
|
||||||
G_FreeEntity( trigger );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
ProximityMine_Activate
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
static void ProximityMine_Activate( gentity_t *ent ) {
|
|
||||||
gentity_t *trigger;
|
|
||||||
float r;
|
|
||||||
|
|
||||||
ent->think = ProximityMine_Explode;
|
|
||||||
ent->nextthink = level.time + g_proxMineTimeout.integer;
|
|
||||||
|
|
||||||
ent->takedamage = qtrue;
|
|
||||||
ent->health = 1;
|
|
||||||
ent->die = ProximityMine_Die;
|
|
||||||
|
|
||||||
ent->s.loopSound = G_SoundIndex( "sound/weapons/proxmine/wstbtick.wav" );
|
|
||||||
|
|
||||||
// build the proximity trigger
|
|
||||||
trigger = G_Spawn ();
|
|
||||||
|
|
||||||
trigger->classname = "proxmine_trigger";
|
|
||||||
|
|
||||||
r = ent->splashRadius;
|
|
||||||
VectorSet( trigger->r.mins, -r, -r, -r );
|
|
||||||
VectorSet( trigger->r.maxs, r, r, r );
|
|
||||||
|
|
||||||
G_SetOrigin( trigger, ent->s.pos.trBase );
|
|
||||||
|
|
||||||
trigger->parent = ent;
|
|
||||||
trigger->r.contents = CONTENTS_TRIGGER;
|
|
||||||
trigger->touch = ProximityMine_Trigger;
|
|
||||||
|
|
||||||
trap_LinkEntity (trigger);
|
|
||||||
|
|
||||||
// set pointer to trigger so the entity can be freed when the mine explodes
|
|
||||||
ent->activator = trigger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
ProximityMine_ExplodeOnPlayer
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
static void ProximityMine_ExplodeOnPlayer( gentity_t *mine ) {
|
|
||||||
gentity_t *player;
|
|
||||||
|
|
||||||
player = mine->enemy;
|
|
||||||
player->client->ps.eFlags &= ~EF_TICKING;
|
|
||||||
|
|
||||||
if ( player->client->invulnerabilityTime > level.time ) {
|
|
||||||
G_Damage( player, mine->parent, mine->parent, vec3_origin, mine->s.origin, 1000, DAMAGE_NO_KNOCKBACK, MOD_JUICED );
|
|
||||||
player->client->invulnerabilityTime = 0;
|
|
||||||
G_TempEntity( player->client->ps.origin, EV_JUICED );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
G_SetOrigin( mine, player->s.pos.trBase );
|
|
||||||
// make sure the explosion gets to the client
|
|
||||||
mine->r.svFlags &= ~SVF_NOCLIENT;
|
|
||||||
mine->splashMethodOfDeath = MOD_PROXIMITY_MINE;
|
|
||||||
G_ExplodeMissile( mine );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
ProximityMine_Player
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
static void ProximityMine_Player( gentity_t *mine, gentity_t *player ) {
|
|
||||||
if( mine->s.eFlags & EF_NODRAW ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_AddEvent( mine, EV_PROXIMITY_MINE_STICK, 0 );
|
|
||||||
|
|
||||||
if( player->s.eFlags & EF_TICKING ) {
|
|
||||||
player->activator->splashDamage += mine->splashDamage;
|
|
||||||
player->activator->splashRadius *= 1.50;
|
|
||||||
mine->think = G_FreeEntity;
|
|
||||||
mine->nextthink = level.time;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
player->client->ps.eFlags |= EF_TICKING;
|
|
||||||
player->activator = mine;
|
|
||||||
|
|
||||||
mine->s.eFlags |= EF_NODRAW;
|
|
||||||
mine->r.svFlags |= SVF_NOCLIENT;
|
|
||||||
mine->s.pos.trType = TR_LINEAR;
|
|
||||||
VectorClear( mine->s.pos.trDelta );
|
|
||||||
|
|
||||||
mine->enemy = player;
|
|
||||||
mine->think = ProximityMine_ExplodeOnPlayer;
|
|
||||||
if ( player->client->invulnerabilityTime > level.time ) {
|
|
||||||
mine->nextthink = level.time + 2 * 1000;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mine->nextthink = level.time + 10 * 1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
G_MissileImpact
|
G_MissileImpact
|
||||||
|
|
@ -269,10 +99,7 @@ G_MissileImpact
|
||||||
void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
|
void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
|
||||||
gentity_t *other;
|
gentity_t *other;
|
||||||
qboolean hitClient = qfalse;
|
qboolean hitClient = qfalse;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
vec3_t forward, impactpoint, bouncedir;
|
|
||||||
int eFlags;
|
|
||||||
#endif
|
|
||||||
other = &g_entities[trace->entityNum];
|
other = &g_entities[trace->entityNum];
|
||||||
|
|
||||||
// check for bounce
|
// check for bounce
|
||||||
|
|
@ -283,26 +110,6 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ( other->takedamage ) {
|
|
||||||
if ( ent->s.weapon != WP_PROX_LAUNCHER ) {
|
|
||||||
if ( other->client && other->client->invulnerabilityTime > level.time ) {
|
|
||||||
//
|
|
||||||
VectorCopy( ent->s.pos.trDelta, forward );
|
|
||||||
VectorNormalize( forward );
|
|
||||||
if (G_InvulnerabilityEffect( other, forward, ent->s.pos.trBase, impactpoint, bouncedir )) {
|
|
||||||
VectorCopy( bouncedir, trace->plane.normal );
|
|
||||||
eFlags = ent->s.eFlags & EF_BOUNCE_HALF;
|
|
||||||
ent->s.eFlags &= ~EF_BOUNCE_HALF;
|
|
||||||
G_BounceMissile( ent, trace );
|
|
||||||
ent->s.eFlags |= eFlags;
|
|
||||||
}
|
|
||||||
ent->target_ent = other;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// impact damage
|
// impact damage
|
||||||
if (other->takedamage) {
|
if (other->takedamage) {
|
||||||
// FIXME: wrong damage direction?
|
// FIXME: wrong damage direction?
|
||||||
|
|
@ -323,43 +130,6 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( ent->s.weapon == WP_PROX_LAUNCHER ) {
|
|
||||||
if( ent->s.pos.trType != TR_GRAVITY ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if it's a player, stick it on to them (flag them and remove this entity)
|
|
||||||
if( other->s.eType == ET_PLAYER && other->health > 0 ) {
|
|
||||||
ProximityMine_Player( ent, other );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SnapVectorTowards( trace->endpos, ent->s.pos.trBase );
|
|
||||||
G_SetOrigin( ent, trace->endpos );
|
|
||||||
ent->s.pos.trType = TR_STATIONARY;
|
|
||||||
VectorClear( ent->s.pos.trDelta );
|
|
||||||
|
|
||||||
G_AddEvent( ent, EV_PROXIMITY_MINE_STICK, trace->surfaceFlags );
|
|
||||||
|
|
||||||
ent->think = ProximityMine_Activate;
|
|
||||||
ent->nextthink = level.time + 2000;
|
|
||||||
|
|
||||||
vectoangles( trace->plane.normal, ent->s.angles );
|
|
||||||
ent->s.angles[0] += 90;
|
|
||||||
|
|
||||||
// link the prox mine to the other entity
|
|
||||||
ent->enemy = other;
|
|
||||||
ent->die = ProximityMine_Die;
|
|
||||||
VectorCopy(trace->plane.normal, ent->movedir);
|
|
||||||
VectorSet(ent->r.mins, -4, -4, -4);
|
|
||||||
VectorSet(ent->r.maxs, 4, 4, 4);
|
|
||||||
trap_LinkEntity(ent);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!strcmp(ent->classname, "hook")) {
|
if (!strcmp(ent->classname, "hook")) {
|
||||||
gentity_t *nent;
|
gentity_t *nent;
|
||||||
vec3_t v;
|
vec3_t v;
|
||||||
|
|
@ -456,12 +226,6 @@ void G_RunMissile( gentity_t *ent ) {
|
||||||
if ( ent->target_ent ) {
|
if ( ent->target_ent ) {
|
||||||
passent = ent->target_ent->s.number;
|
passent = ent->target_ent->s.number;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
// prox mines that left the owner bbox will attach to anything, even the owner
|
|
||||||
else if (ent->s.weapon == WP_PROX_LAUNCHER && ent->count) {
|
|
||||||
passent = ENTITYNUM_NONE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
else {
|
||||||
// ignore interactions with the missile owner
|
// ignore interactions with the missile owner
|
||||||
passent = ent->r.ownerNum;
|
passent = ent->r.ownerNum;
|
||||||
|
|
@ -495,16 +259,6 @@ void G_RunMissile( gentity_t *ent ) {
|
||||||
return; // exploded
|
return; // exploded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
// if the prox mine wasn't yet outside the player body
|
|
||||||
if (ent->s.weapon == WP_PROX_LAUNCHER && !ent->count) {
|
|
||||||
// check if the prox mine is outside the owner bbox
|
|
||||||
trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, ent->r.currentOrigin, ENTITYNUM_NONE, ent->clipmask );
|
|
||||||
if (!tr.startsolid || tr.entityNum != ent->r.ownerNum) {
|
|
||||||
ent->count = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// check think function after bouncing
|
// check think function after bouncing
|
||||||
G_RunThink( ent );
|
G_RunThink( ent );
|
||||||
}
|
}
|
||||||
|
|
@ -708,101 +462,3 @@ gentity_t *fire_grapple (gentity_t *self, vec3_t start, vec3_t dir) {
|
||||||
|
|
||||||
return hook;
|
return hook;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
fire_nail
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
#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;
|
|
||||||
vec3_t dir;
|
|
||||||
vec3_t end;
|
|
||||||
float r, u, scale;
|
|
||||||
|
|
||||||
bolt = G_Spawn();
|
|
||||||
bolt->classname = "nail";
|
|
||||||
bolt->nextthink = level.time + 10000;
|
|
||||||
bolt->think = G_ExplodeMissile;
|
|
||||||
bolt->s.eType = ET_MISSILE;
|
|
||||||
bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
|
|
||||||
bolt->s.weapon = WP_NAILGUN;
|
|
||||||
bolt->r.ownerNum = self->s.number;
|
|
||||||
bolt->parent = self;
|
|
||||||
bolt->damage = 20;
|
|
||||||
bolt->methodOfDeath = MOD_NAIL;
|
|
||||||
bolt->clipmask = MASK_SHOT;
|
|
||||||
bolt->target_ent = NULL;
|
|
||||||
|
|
||||||
bolt->s.pos.trType = TR_LINEAR;
|
|
||||||
bolt->s.pos.trTime = level.time;
|
|
||||||
VectorCopy( start, bolt->s.pos.trBase );
|
|
||||||
|
|
||||||
r = random() * M_PI * 2.0f;
|
|
||||||
u = sin(r) * crandom() * NAILGUN_SPREAD * 16;
|
|
||||||
r = cos(r) * crandom() * NAILGUN_SPREAD * 16;
|
|
||||||
VectorMA( start, 8192 * 16, forward, end);
|
|
||||||
VectorMA (end, r, right, end);
|
|
||||||
VectorMA (end, u, up, end);
|
|
||||||
VectorSubtract( end, start, dir );
|
|
||||||
VectorNormalize( dir );
|
|
||||||
|
|
||||||
scale = 555 + random() * 1800;
|
|
||||||
VectorScale( dir, scale, bolt->s.pos.trDelta );
|
|
||||||
SnapVector( bolt->s.pos.trDelta );
|
|
||||||
|
|
||||||
VectorCopy( start, bolt->r.currentOrigin );
|
|
||||||
|
|
||||||
return bolt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
fire_prox
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
gentity_t *fire_prox( gentity_t *self, vec3_t start, vec3_t dir ) {
|
|
||||||
gentity_t *bolt;
|
|
||||||
|
|
||||||
VectorNormalize (dir);
|
|
||||||
|
|
||||||
bolt = G_Spawn();
|
|
||||||
bolt->classname = "prox mine";
|
|
||||||
bolt->nextthink = level.time + 3000;
|
|
||||||
bolt->think = G_ExplodeMissile;
|
|
||||||
bolt->s.eType = ET_MISSILE;
|
|
||||||
bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
|
|
||||||
bolt->s.weapon = WP_PROX_LAUNCHER;
|
|
||||||
bolt->s.eFlags = 0;
|
|
||||||
bolt->r.ownerNum = self->s.number;
|
|
||||||
bolt->parent = self;
|
|
||||||
bolt->damage = 0;
|
|
||||||
bolt->splashDamage = 100;
|
|
||||||
bolt->splashRadius = 150;
|
|
||||||
bolt->methodOfDeath = MOD_PROXIMITY_MINE;
|
|
||||||
bolt->splashMethodOfDeath = MOD_PROXIMITY_MINE;
|
|
||||||
bolt->clipmask = MASK_SHOT;
|
|
||||||
bolt->target_ent = NULL;
|
|
||||||
// count is used to check if the prox mine left the player bbox
|
|
||||||
// if count == 1 then the prox mine left the player bbox and can attack to it
|
|
||||||
bolt->count = 0;
|
|
||||||
|
|
||||||
//FIXME: we prolly wanna abuse another field
|
|
||||||
bolt->s.generic1 = self->client->sess.sessionTeam;
|
|
||||||
|
|
||||||
bolt->s.pos.trType = TR_GRAVITY;
|
|
||||||
bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame
|
|
||||||
VectorCopy( start, bolt->s.pos.trBase );
|
|
||||||
VectorScale( dir, 700, bolt->s.pos.trDelta );
|
|
||||||
SnapVector( bolt->s.pos.trDelta ); // save net bandwidth
|
|
||||||
|
|
||||||
VectorCopy (start, bolt->r.currentOrigin);
|
|
||||||
|
|
||||||
return bolt;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|
|
@ -319,42 +319,6 @@ qboolean G_MoverPush( gentity_t *pusher, vec3_t move, vec3_t amove, gentity_t **
|
||||||
for ( e = 0 ; e < listedEntities ; e++ ) {
|
for ( e = 0 ; e < listedEntities ; e++ ) {
|
||||||
check = &g_entities[ entityList[ e ] ];
|
check = &g_entities[ entityList[ e ] ];
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ( check->s.eType == ET_MISSILE ) {
|
|
||||||
// if it is a prox mine
|
|
||||||
if ( !strcmp(check->classname, "prox mine") ) {
|
|
||||||
// if this prox mine is attached to this mover try to move it with the pusher
|
|
||||||
if ( check->enemy == pusher ) {
|
|
||||||
if (!G_TryPushingProxMine( check, pusher, move, amove )) {
|
|
||||||
//explode
|
|
||||||
check->s.loopSound = 0;
|
|
||||||
G_AddEvent( check, EV_PROXIMITY_MINE_TRIGGER, 0 );
|
|
||||||
G_ExplodeMissile(check);
|
|
||||||
if (check->activator) {
|
|
||||||
G_FreeEntity(check->activator);
|
|
||||||
check->activator = NULL;
|
|
||||||
}
|
|
||||||
//G_Printf("prox mine explodes\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//check if the prox mine is crushed by the mover
|
|
||||||
if (!G_CheckProxMinePosition( check )) {
|
|
||||||
//explode
|
|
||||||
check->s.loopSound = 0;
|
|
||||||
G_AddEvent( check, EV_PROXIMITY_MINE_TRIGGER, 0 );
|
|
||||||
G_ExplodeMissile(check);
|
|
||||||
if (check->activator) {
|
|
||||||
G_FreeEntity(check->activator);
|
|
||||||
check->activator = NULL;
|
|
||||||
}
|
|
||||||
//G_Printf("prox mine explodes\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// only push items and players
|
// only push items and players
|
||||||
if ( check->s.eType != ET_ITEM && check->s.eType != ET_PLAYER && !check->physicsObject ) {
|
if ( check->s.eType != ET_ITEM && check->s.eType != ET_PLAYER && !check->physicsObject ) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -186,11 +186,6 @@ void SP_team_CTF_blueplayer( gentity_t *ent );
|
||||||
void SP_team_CTF_redspawn( gentity_t *ent );
|
void SP_team_CTF_redspawn( gentity_t *ent );
|
||||||
void SP_team_CTF_bluespawn( gentity_t *ent );
|
void SP_team_CTF_bluespawn( gentity_t *ent );
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
void SP_team_blueobelisk( gentity_t *ent );
|
|
||||||
void SP_team_redobelisk( gentity_t *ent );
|
|
||||||
void SP_team_neutralobelisk( gentity_t *ent );
|
|
||||||
#endif
|
|
||||||
void SP_item_botroam( gentity_t *ent ) {};
|
void SP_item_botroam( gentity_t *ent ) {};
|
||||||
|
|
||||||
spawn_t spawns[] = {
|
spawn_t spawns[] = {
|
||||||
|
|
@ -259,11 +254,6 @@ spawn_t spawns[] = {
|
||||||
{"team_CTF_redspawn", SP_team_CTF_redspawn},
|
{"team_CTF_redspawn", SP_team_CTF_redspawn},
|
||||||
{"team_CTF_bluespawn", SP_team_CTF_bluespawn},
|
{"team_CTF_bluespawn", SP_team_CTF_bluespawn},
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
{"team_redobelisk", SP_team_redobelisk},
|
|
||||||
{"team_blueobelisk", SP_team_blueobelisk},
|
|
||||||
{"team_neutralobelisk", SP_team_neutralobelisk},
|
|
||||||
#endif
|
|
||||||
{"item_botroam", SP_item_botroam},
|
{"item_botroam", SP_item_botroam},
|
||||||
|
|
||||||
{0, 0}
|
{0, 0}
|
||||||
|
|
@ -441,19 +431,11 @@ void G_SpawnGEntityFromSpawnVars( void ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
G_SpawnInt( "notta", "0", &i );
|
|
||||||
if ( i ) {
|
|
||||||
G_FreeEntity( ent );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
G_SpawnInt( "notq3a", "0", &i );
|
G_SpawnInt( "notq3a", "0", &i );
|
||||||
if ( i ) {
|
if ( i ) {
|
||||||
G_FreeEntity( ent );
|
G_FreeEntity( ent );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if( G_SpawnString( "gametype", NULL, &value ) ) {
|
if( G_SpawnString( "gametype", NULL, &value ) ) {
|
||||||
if( g_gametype.integer >= GT_FFA && g_gametype.integer < GT_MAX_GAME_TYPE ) {
|
if( g_gametype.integer >= GT_FFA && g_gametype.integer < GT_MAX_GAME_TYPE ) {
|
||||||
|
|
|
||||||
|
|
@ -51,12 +51,6 @@ void Team_InitGame( void ) {
|
||||||
Team_SetFlagStatus( TEAM_RED, FLAG_ATBASE );
|
Team_SetFlagStatus( TEAM_RED, FLAG_ATBASE );
|
||||||
Team_SetFlagStatus( TEAM_BLUE, FLAG_ATBASE );
|
Team_SetFlagStatus( TEAM_BLUE, FLAG_ATBASE );
|
||||||
break;
|
break;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
case GT_1FCTF:
|
|
||||||
teamgame.flagStatus = -1; // Invalid to force update
|
|
||||||
Team_SetFlagStatus( TEAM_FREE, FLAG_ATBASE );
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -313,11 +307,6 @@ void Team_FragBonuses(gentity_t *targ, gentity_t *inflictor, gentity_t *attacker
|
||||||
|
|
||||||
// did the attacker frag the flag carrier?
|
// did the attacker frag the flag carrier?
|
||||||
tokens = 0;
|
tokens = 0;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( g_gametype.integer == GT_HARVESTER ) {
|
|
||||||
tokens = targ->client->ps.generic1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (targ->client->ps.powerups[enemy_flag_pw]) {
|
if (targ->client->ps.powerups[enemy_flag_pw]) {
|
||||||
attacker->client->pers.teamState.lastfraggedcarrier = level.time;
|
attacker->client->pers.teamState.lastfraggedcarrier = level.time;
|
||||||
AddScore(attacker, targ->r.currentOrigin, CTF_FRAG_CARRIER_BONUS);
|
AddScore(attacker, targ->r.currentOrigin, CTF_FRAG_CARRIER_BONUS);
|
||||||
|
|
@ -395,25 +384,6 @@ void Team_FragBonuses(gentity_t *targ, gentity_t *inflictor, gentity_t *attacker
|
||||||
|
|
||||||
// we have to find the flag and carrier entities
|
// we have to find the flag and carrier entities
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( g_gametype.integer == GT_OBELISK ) {
|
|
||||||
// find the team obelisk
|
|
||||||
switch (attacker->client->sess.sessionTeam) {
|
|
||||||
case TEAM_RED:
|
|
||||||
c = "team_redobelisk";
|
|
||||||
break;
|
|
||||||
case TEAM_BLUE:
|
|
||||||
c = "team_blueobelisk";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (g_gametype.integer == GT_HARVESTER ) {
|
|
||||||
// find the center obelisk
|
|
||||||
c = "team_neutralobelisk";
|
|
||||||
} else {
|
|
||||||
#endif
|
|
||||||
// find the flag
|
// find the flag
|
||||||
switch (attacker->client->sess.sessionTeam) {
|
switch (attacker->client->sess.sessionTeam) {
|
||||||
case TEAM_RED:
|
case TEAM_RED:
|
||||||
|
|
@ -432,9 +402,6 @@ void Team_FragBonuses(gentity_t *targ, gentity_t *inflictor, gentity_t *attacker
|
||||||
break;
|
break;
|
||||||
carrier = NULL;
|
carrier = NULL;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
flag = NULL;
|
flag = NULL;
|
||||||
while ((flag = G_Find (flag, FOFS(classname), c)) != NULL) {
|
while ((flag = G_Find (flag, FOFS(classname), c)) != NULL) {
|
||||||
if (!(flag->flags & FL_DROPPED_ITEM))
|
if (!(flag->flags & FL_DROPPED_ITEM))
|
||||||
|
|
@ -562,11 +529,6 @@ void Team_ResetFlags( void ) {
|
||||||
Team_ResetFlag( TEAM_RED );
|
Team_ResetFlag( TEAM_RED );
|
||||||
Team_ResetFlag( TEAM_BLUE );
|
Team_ResetFlag( TEAM_BLUE );
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if( g_gametype.integer == GT_1FCTF ) {
|
|
||||||
Team_ResetFlag( TEAM_FREE );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Team_ReturnFlagSound( gentity_t *ent, int team ) {
|
void Team_ReturnFlagSound( gentity_t *ent, int team ) {
|
||||||
|
|
@ -703,12 +665,6 @@ int Team_TouchOurFlag( gentity_t *ent, gentity_t *other, int team ) {
|
||||||
gclient_t *cl = other->client;
|
gclient_t *cl = other->client;
|
||||||
int enemy_flag;
|
int enemy_flag;
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( g_gametype.integer == GT_1FCTF ) {
|
|
||||||
enemy_flag = PW_NEUTRALFLAG;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#endif
|
|
||||||
if (cl->sess.sessionTeam == TEAM_RED) {
|
if (cl->sess.sessionTeam == TEAM_RED) {
|
||||||
enemy_flag = PW_BLUEFLAG;
|
enemy_flag = PW_BLUEFLAG;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -726,24 +682,12 @@ int Team_TouchOurFlag( gentity_t *ent, gentity_t *other, int team ) {
|
||||||
Team_ReturnFlagSound(Team_ResetFlag(team), team);
|
Team_ReturnFlagSound(Team_ResetFlag(team), team);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// the flag is at home base. if the player has the enemy
|
// the flag is at home base. if the player has the enemy
|
||||||
// flag, he's just won!
|
// flag, he's just won!
|
||||||
if (!cl->ps.powerups[enemy_flag])
|
if (!cl->ps.powerups[enemy_flag])
|
||||||
return 0; // We don't have the flag
|
return 0; // We don't have the flag
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( g_gametype.integer == GT_1FCTF ) {
|
|
||||||
PrintMsg( NULL, "%s" S_COLOR_WHITE " captured the flag!\n", cl->pers.netname );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#endif
|
|
||||||
PrintMsg( NULL, "%s" S_COLOR_WHITE " captured the %s flag!\n", cl->pers.netname, TeamName(OtherTeam(team)));
|
PrintMsg( NULL, "%s" S_COLOR_WHITE " captured the %s flag!\n", cl->pers.netname, TeamName(OtherTeam(team)));
|
||||||
#ifdef MISSIONPACK
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cl->ps.powerups[enemy_flag] = 0;
|
cl->ps.powerups[enemy_flag] = 0;
|
||||||
|
|
||||||
|
|
@ -813,21 +757,6 @@ int Team_TouchOurFlag( gentity_t *ent, gentity_t *other, int team ) {
|
||||||
int Team_TouchEnemyFlag( gentity_t *ent, gentity_t *other, int team ) {
|
int Team_TouchEnemyFlag( gentity_t *ent, gentity_t *other, int team ) {
|
||||||
gclient_t *cl = other->client;
|
gclient_t *cl = other->client;
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( g_gametype.integer == GT_1FCTF ) {
|
|
||||||
PrintMsg (NULL, "%s" S_COLOR_WHITE " got the flag!\n", other->client->pers.netname );
|
|
||||||
|
|
||||||
cl->ps.powerups[PW_NEUTRALFLAG] = INT_MAX; // flags never expire
|
|
||||||
|
|
||||||
if( team == TEAM_RED ) {
|
|
||||||
Team_SetFlagStatus( TEAM_FREE, FLAG_TAKEN_RED );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Team_SetFlagStatus( TEAM_FREE, FLAG_TAKEN_BLUE );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
#endif
|
|
||||||
PrintMsg (NULL, "%s" S_COLOR_WHITE " got the %s flag!\n",
|
PrintMsg (NULL, "%s" S_COLOR_WHITE " got the %s flag!\n",
|
||||||
other->client->pers.netname, TeamName(team));
|
other->client->pers.netname, TeamName(team));
|
||||||
|
|
||||||
|
|
@ -837,9 +766,6 @@ int Team_TouchEnemyFlag( gentity_t *ent, gentity_t *other, int team ) {
|
||||||
cl->ps.powerups[PW_BLUEFLAG] = INT_MAX; // flags never expire
|
cl->ps.powerups[PW_BLUEFLAG] = INT_MAX; // flags never expire
|
||||||
|
|
||||||
Team_SetFlagStatus( team, FLAG_TAKEN );
|
Team_SetFlagStatus( team, FLAG_TAKEN );
|
||||||
#ifdef MISSIONPACK
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AddScore(other, ent->r.currentOrigin, CTF_FLAG_BONUS);
|
AddScore(other, ent->r.currentOrigin, CTF_FLAG_BONUS);
|
||||||
cl->pers.teamState.flagsince = level.time;
|
cl->pers.teamState.flagsince = level.time;
|
||||||
|
|
@ -852,22 +778,6 @@ int Pickup_Team( gentity_t *ent, gentity_t *other ) {
|
||||||
int team;
|
int team;
|
||||||
gclient_t *cl = other->client;
|
gclient_t *cl = other->client;
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( g_gametype.integer == GT_OBELISK ) {
|
|
||||||
// there are no team items that can be picked up in obelisk
|
|
||||||
G_FreeEntity( ent );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( g_gametype.integer == GT_HARVESTER ) {
|
|
||||||
// the only team items that can be picked up in harvester are the cubes
|
|
||||||
if( ent->spawnflags != cl->sess.sessionTeam ) {
|
|
||||||
cl->ps.generic1 += 1;
|
|
||||||
}
|
|
||||||
G_FreeEntity( ent );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// figure out what team this flag is
|
// figure out what team this flag is
|
||||||
if( strcmp(ent->classname, "team_CTF_redflag") == 0 ) {
|
if( strcmp(ent->classname, "team_CTF_redflag") == 0 ) {
|
||||||
team = TEAM_RED;
|
team = TEAM_RED;
|
||||||
|
|
@ -875,26 +785,10 @@ int Pickup_Team( gentity_t *ent, gentity_t *other ) {
|
||||||
else if( strcmp(ent->classname, "team_CTF_blueflag") == 0 ) {
|
else if( strcmp(ent->classname, "team_CTF_blueflag") == 0 ) {
|
||||||
team = TEAM_BLUE;
|
team = TEAM_BLUE;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
else if( strcmp(ent->classname, "team_CTF_neutralflag") == 0 ) {
|
|
||||||
team = TEAM_FREE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
else {
|
||||||
PrintMsg ( other, "Don't know what team the flag is on.\n");
|
PrintMsg ( other, "Don't know what team the flag is on.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( g_gametype.integer == GT_1FCTF ) {
|
|
||||||
if( team == TEAM_FREE ) {
|
|
||||||
return Team_TouchEnemyFlag( ent, other, cl->sess.sessionTeam );
|
|
||||||
}
|
|
||||||
if( team != cl->sess.sessionTeam) {
|
|
||||||
return Team_TouchOurFlag( ent, other, cl->sess.sessionTeam );
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// GT_CTF
|
// GT_CTF
|
||||||
if( team == cl->sess.sessionTeam) {
|
if( team == cl->sess.sessionTeam) {
|
||||||
return Team_TouchOurFlag( ent, other, team );
|
return Team_TouchOurFlag( ent, other, team );
|
||||||
|
|
@ -1187,297 +1081,3 @@ Targets will be fired when someone spawns in on them.
|
||||||
*/
|
*/
|
||||||
void SP_team_CTF_bluespawn(gentity_t *ent) {
|
void SP_team_CTF_bluespawn(gentity_t *ent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
Obelisks
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void ObeliskRegen( gentity_t *self ) {
|
|
||||||
self->nextthink = level.time + g_obeliskRegenPeriod.integer * 1000;
|
|
||||||
if( self->health >= g_obeliskHealth.integer ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_AddEvent( self, EV_POWERUP_REGEN, 0 );
|
|
||||||
self->health += g_obeliskRegenAmount.integer;
|
|
||||||
if ( self->health > g_obeliskHealth.integer ) {
|
|
||||||
self->health = g_obeliskHealth.integer;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->activator->s.modelindex2 = self->health * 0xff / g_obeliskHealth.integer;
|
|
||||||
self->activator->s.frame = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ObeliskRespawn( gentity_t *self ) {
|
|
||||||
self->takedamage = qtrue;
|
|
||||||
self->health = g_obeliskHealth.integer;
|
|
||||||
|
|
||||||
self->think = ObeliskRegen;
|
|
||||||
self->nextthink = level.time + g_obeliskRegenPeriod.integer * 1000;
|
|
||||||
|
|
||||||
self->activator->s.frame = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ObeliskDie( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ) {
|
|
||||||
int otherTeam;
|
|
||||||
|
|
||||||
otherTeam = OtherTeam( self->spawnflags );
|
|
||||||
AddTeamScore(self->s.pos.trBase, otherTeam, 1);
|
|
||||||
Team_ForceGesture(otherTeam);
|
|
||||||
|
|
||||||
CalculateRanks();
|
|
||||||
|
|
||||||
self->takedamage = qfalse;
|
|
||||||
self->think = ObeliskRespawn;
|
|
||||||
self->nextthink = level.time + g_obeliskRespawnDelay.integer * 1000;
|
|
||||||
|
|
||||||
self->activator->s.modelindex2 = 0xff;
|
|
||||||
self->activator->s.frame = 2;
|
|
||||||
|
|
||||||
G_AddEvent( self->activator, EV_OBELISKEXPLODE, 0 );
|
|
||||||
|
|
||||||
AddScore(attacker, self->r.currentOrigin, CTF_CAPTURE_BONUS);
|
|
||||||
|
|
||||||
// add the sprite over the player's head
|
|
||||||
attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
|
|
||||||
attacker->client->ps.eFlags |= EF_AWARD_CAP;
|
|
||||||
attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME;
|
|
||||||
attacker->client->ps.persistant[PERS_CAPTURES]++;
|
|
||||||
|
|
||||||
teamgame.redObeliskAttackedTime = 0;
|
|
||||||
teamgame.blueObeliskAttackedTime = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ObeliskTouch( gentity_t *self, gentity_t *other, trace_t *trace ) {
|
|
||||||
int tokens;
|
|
||||||
|
|
||||||
if ( !other->client ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( OtherTeam(other->client->sess.sessionTeam) != self->spawnflags ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tokens = other->client->ps.generic1;
|
|
||||||
if( tokens <= 0 ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintMsg(NULL, "%s" S_COLOR_WHITE " brought in %i skull%s.\n",
|
|
||||||
other->client->pers.netname, tokens, tokens ? "s" : "" );
|
|
||||||
|
|
||||||
AddTeamScore(self->s.pos.trBase, other->client->sess.sessionTeam, tokens);
|
|
||||||
Team_ForceGesture(other->client->sess.sessionTeam);
|
|
||||||
|
|
||||||
AddScore(other, self->r.currentOrigin, CTF_CAPTURE_BONUS*tokens);
|
|
||||||
|
|
||||||
// add the sprite over the player's head
|
|
||||||
other->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
|
|
||||||
other->client->ps.eFlags |= EF_AWARD_CAP;
|
|
||||||
other->client->rewardTime = level.time + REWARD_SPRITE_TIME;
|
|
||||||
other->client->ps.persistant[PERS_CAPTURES] += tokens;
|
|
||||||
|
|
||||||
other->client->ps.generic1 = 0;
|
|
||||||
CalculateRanks();
|
|
||||||
|
|
||||||
Team_CaptureFlagSound( self, self->spawnflags );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ObeliskPain( gentity_t *self, gentity_t *attacker, int damage ) {
|
|
||||||
int actualDamage = damage / 10;
|
|
||||||
if (actualDamage <= 0) {
|
|
||||||
actualDamage = 1;
|
|
||||||
}
|
|
||||||
self->activator->s.modelindex2 = self->health * 0xff / g_obeliskHealth.integer;
|
|
||||||
if (!self->activator->s.frame) {
|
|
||||||
G_AddEvent(self, EV_OBELISKPAIN, 0);
|
|
||||||
}
|
|
||||||
self->activator->s.frame = 1;
|
|
||||||
AddScore(attacker, self->r.currentOrigin, actualDamage);
|
|
||||||
}
|
|
||||||
|
|
||||||
gentity_t *SpawnObelisk( vec3_t origin, int team, int spawnflags) {
|
|
||||||
trace_t tr;
|
|
||||||
vec3_t dest;
|
|
||||||
gentity_t *ent;
|
|
||||||
|
|
||||||
ent = G_Spawn();
|
|
||||||
|
|
||||||
VectorCopy( origin, ent->s.origin );
|
|
||||||
VectorCopy( origin, ent->s.pos.trBase );
|
|
||||||
VectorCopy( origin, ent->r.currentOrigin );
|
|
||||||
|
|
||||||
VectorSet( ent->r.mins, -15, -15, 0 );
|
|
||||||
VectorSet( ent->r.maxs, 15, 15, 87 );
|
|
||||||
|
|
||||||
ent->s.eType = ET_GENERAL;
|
|
||||||
ent->flags = FL_NO_KNOCKBACK;
|
|
||||||
|
|
||||||
if( g_gametype.integer == GT_OBELISK ) {
|
|
||||||
ent->r.contents = CONTENTS_SOLID;
|
|
||||||
ent->takedamage = qtrue;
|
|
||||||
ent->health = g_obeliskHealth.integer;
|
|
||||||
ent->die = ObeliskDie;
|
|
||||||
ent->pain = ObeliskPain;
|
|
||||||
ent->think = ObeliskRegen;
|
|
||||||
ent->nextthink = level.time + g_obeliskRegenPeriod.integer * 1000;
|
|
||||||
}
|
|
||||||
if( g_gametype.integer == GT_HARVESTER ) {
|
|
||||||
ent->r.contents = CONTENTS_TRIGGER;
|
|
||||||
ent->touch = ObeliskTouch;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( spawnflags & 1 ) {
|
|
||||||
// suspended
|
|
||||||
G_SetOrigin( ent, ent->s.origin );
|
|
||||||
} else {
|
|
||||||
// mappers like to put them exactly on the floor, but being coplanar
|
|
||||||
// will sometimes show up as starting in solid, so lif it up one pixel
|
|
||||||
ent->s.origin[2] += 1;
|
|
||||||
|
|
||||||
// drop to floor
|
|
||||||
VectorSet( dest, ent->s.origin[0], ent->s.origin[1], ent->s.origin[2] - 4096 );
|
|
||||||
trap_Trace( &tr, ent->s.origin, ent->r.mins, ent->r.maxs, dest, ent->s.number, MASK_SOLID );
|
|
||||||
if ( tr.startsolid ) {
|
|
||||||
ent->s.origin[2] -= 1;
|
|
||||||
G_Printf( "SpawnObelisk: %s startsolid at %s\n", ent->classname, vtos(ent->s.origin) );
|
|
||||||
|
|
||||||
ent->s.groundEntityNum = ENTITYNUM_NONE;
|
|
||||||
G_SetOrigin( ent, ent->s.origin );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// allow to ride movers
|
|
||||||
ent->s.groundEntityNum = tr.entityNum;
|
|
||||||
G_SetOrigin( ent, tr.endpos );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ent->spawnflags = team;
|
|
||||||
|
|
||||||
trap_LinkEntity( ent );
|
|
||||||
|
|
||||||
return ent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*QUAKED team_redobelisk (1 0 0) (-16 -16 0) (16 16 8)
|
|
||||||
*/
|
|
||||||
void SP_team_redobelisk( gentity_t *ent ) {
|
|
||||||
gentity_t *obelisk;
|
|
||||||
|
|
||||||
if ( g_gametype.integer <= GT_TEAM ) {
|
|
||||||
G_FreeEntity(ent);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ent->s.eType = ET_TEAM;
|
|
||||||
if ( g_gametype.integer == GT_OBELISK ) {
|
|
||||||
obelisk = SpawnObelisk( ent->s.origin, TEAM_RED, ent->spawnflags );
|
|
||||||
obelisk->activator = ent;
|
|
||||||
// initial obelisk health value
|
|
||||||
ent->s.modelindex2 = 0xff;
|
|
||||||
ent->s.frame = 0;
|
|
||||||
}
|
|
||||||
if ( g_gametype.integer == GT_HARVESTER ) {
|
|
||||||
obelisk = SpawnObelisk( ent->s.origin, TEAM_RED, ent->spawnflags );
|
|
||||||
obelisk->activator = ent;
|
|
||||||
}
|
|
||||||
ent->s.modelindex = TEAM_RED;
|
|
||||||
trap_LinkEntity(ent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*QUAKED team_blueobelisk (0 0 1) (-16 -16 0) (16 16 88)
|
|
||||||
*/
|
|
||||||
void SP_team_blueobelisk( gentity_t *ent ) {
|
|
||||||
gentity_t *obelisk;
|
|
||||||
|
|
||||||
if ( g_gametype.integer <= GT_TEAM ) {
|
|
||||||
G_FreeEntity(ent);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ent->s.eType = ET_TEAM;
|
|
||||||
if ( g_gametype.integer == GT_OBELISK ) {
|
|
||||||
obelisk = SpawnObelisk( ent->s.origin, TEAM_BLUE, ent->spawnflags );
|
|
||||||
obelisk->activator = ent;
|
|
||||||
// initial obelisk health value
|
|
||||||
ent->s.modelindex2 = 0xff;
|
|
||||||
ent->s.frame = 0;
|
|
||||||
}
|
|
||||||
if ( g_gametype.integer == GT_HARVESTER ) {
|
|
||||||
obelisk = SpawnObelisk( ent->s.origin, TEAM_BLUE, ent->spawnflags );
|
|
||||||
obelisk->activator = ent;
|
|
||||||
}
|
|
||||||
ent->s.modelindex = TEAM_BLUE;
|
|
||||||
trap_LinkEntity(ent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*QUAKED team_neutralobelisk (0 0 1) (-16 -16 0) (16 16 88)
|
|
||||||
*/
|
|
||||||
void SP_team_neutralobelisk( gentity_t *ent ) {
|
|
||||||
if ( g_gametype.integer != GT_1FCTF && g_gametype.integer != GT_HARVESTER ) {
|
|
||||||
G_FreeEntity(ent);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ent->s.eType = ET_TEAM;
|
|
||||||
if ( g_gametype.integer == GT_HARVESTER) {
|
|
||||||
neutralObelisk = SpawnObelisk( ent->s.origin, TEAM_FREE, ent->spawnflags);
|
|
||||||
neutralObelisk->spawnflags = TEAM_FREE;
|
|
||||||
}
|
|
||||||
ent->s.modelindex = TEAM_FREE;
|
|
||||||
trap_LinkEntity(ent);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
CheckObeliskAttack
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
qboolean CheckObeliskAttack( gentity_t *obelisk, gentity_t *attacker ) {
|
|
||||||
gentity_t *te;
|
|
||||||
|
|
||||||
// if this really is an obelisk
|
|
||||||
if( obelisk->die != ObeliskDie ) {
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the attacker is a client
|
|
||||||
if( !attacker->client ) {
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the obelisk is on the same team as the attacker then don't hurt it
|
|
||||||
if( obelisk->spawnflags == attacker->client->sess.sessionTeam ) {
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// obelisk may be hurt
|
|
||||||
|
|
||||||
// if not played any sounds recently
|
|
||||||
if ((obelisk->spawnflags == TEAM_RED &&
|
|
||||||
teamgame.redObeliskAttackedTime < level.time - OVERLOAD_ATTACK_BASE_SOUND_TIME) ||
|
|
||||||
(obelisk->spawnflags == TEAM_BLUE &&
|
|
||||||
teamgame.blueObeliskAttackedTime < level.time - OVERLOAD_ATTACK_BASE_SOUND_TIME) ) {
|
|
||||||
|
|
||||||
// tell which obelisk is under attack
|
|
||||||
te = G_TempEntity( obelisk->s.pos.trBase, EV_GLOBAL_TEAM_SOUND );
|
|
||||||
if( obelisk->spawnflags == TEAM_RED ) {
|
|
||||||
te->s.eventParm = GTS_REDOBELISK_ATTACKED;
|
|
||||||
teamgame.redObeliskAttackedTime = level.time;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
te->s.eventParm = GTS_BLUEOBELISK_ATTACKED;
|
|
||||||
teamgame.blueObeliskAttackedTime = level.time;
|
|
||||||
}
|
|
||||||
te->r.svFlags |= SVF_BROADCAST;
|
|
||||||
}
|
|
||||||
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|
|
@ -21,23 +21,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
|
|
||||||
#define CTF_CAPTURE_BONUS 100 // what you get for capture
|
|
||||||
#define CTF_TEAM_BONUS 25 // what your team gets for capture
|
|
||||||
#define CTF_RECOVERY_BONUS 10 // what you get for recovery
|
|
||||||
#define CTF_FLAG_BONUS 10 // what you get for picking up enemy flag
|
|
||||||
#define CTF_FRAG_CARRIER_BONUS 20 // what you get for fragging enemy flag carrier
|
|
||||||
#define CTF_FLAG_RETURN_TIME 40000 // seconds until auto return
|
|
||||||
|
|
||||||
#define CTF_CARRIER_DANGER_PROTECT_BONUS 5 // bonus for fraggin someone who has recently hurt your flag carrier
|
|
||||||
#define CTF_CARRIER_PROTECT_BONUS 2 // bonus for fraggin someone while either you or your target are near your flag carrier
|
|
||||||
#define CTF_FLAG_DEFENSE_BONUS 10 // bonus for fraggin someone while either you or your target are near your flag
|
|
||||||
#define CTF_RETURN_FLAG_ASSIST_BONUS 10 // awarded for returning a flag that causes a capture to happen almost immediately
|
|
||||||
#define CTF_FRAG_CARRIER_ASSIST_BONUS 10 // award for fragging a flag carrier if a capture happens almost immediately
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define CTF_CAPTURE_BONUS 5 // what you get for capture
|
#define CTF_CAPTURE_BONUS 5 // what you get for capture
|
||||||
#define CTF_TEAM_BONUS 0 // what your team gets for capture
|
#define CTF_TEAM_BONUS 0 // what your team gets for capture
|
||||||
#define CTF_RECOVERY_BONUS 1 // what you get for recovery
|
#define CTF_RECOVERY_BONUS 1 // what you get for recovery
|
||||||
|
|
@ -51,8 +34,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#define CTF_RETURN_FLAG_ASSIST_BONUS 1 // awarded for returning a flag that causes a capture to happen almost immediately
|
#define CTF_RETURN_FLAG_ASSIST_BONUS 1 // awarded for returning a flag that causes a capture to happen almost immediately
|
||||||
#define CTF_FRAG_CARRIER_ASSIST_BONUS 2 // award for fragging a flag carrier if a capture happens almost immediately
|
#define CTF_FRAG_CARRIER_ASSIST_BONUS 2 // award for fragging a flag carrier if a capture happens almost immediately
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CTF_TARGET_PROTECT_RADIUS 1000 // the radius around an object being defended where a target will be worth extra frags
|
#define CTF_TARGET_PROTECT_RADIUS 1000 // the radius around an object being defended where a target will be worth extra frags
|
||||||
#define CTF_ATTACKER_PROTECT_RADIUS 1000 // the radius around an object being defended where an attacker will get extra frags when making kills
|
#define CTF_ATTACKER_PROTECT_RADIUS 1000 // the radius around an object being defended where an attacker will get extra frags when making kills
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,11 +105,6 @@ qboolean CheckGauntletAttack( gentity_t *ent ) {
|
||||||
} else {
|
} else {
|
||||||
s_quadFactor = 1;
|
s_quadFactor = 1;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( ent->client->persistantPowerup && ent->client->persistantPowerup->item && ent->client->persistantPowerup->item->giTag == PW_DOUBLER ) {
|
|
||||||
s_quadFactor *= 2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
damage = 50 * s_quadFactor;
|
damage = 50 * s_quadFactor;
|
||||||
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
|
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
|
||||||
|
|
@ -149,9 +144,6 @@ void SnapVectorTowards( vec3_t v, vec3_t to ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
#define CHAINGUN_SPREAD 600
|
|
||||||
#endif
|
|
||||||
#define MACHINEGUN_SPREAD 200
|
#define MACHINEGUN_SPREAD 200
|
||||||
#define MACHINEGUN_DAMAGE 7
|
#define MACHINEGUN_DAMAGE 7
|
||||||
#define MACHINEGUN_TEAM_DAMAGE 5 // wimpier MG in teamplay
|
#define MACHINEGUN_TEAM_DAMAGE 5 // wimpier MG in teamplay
|
||||||
|
|
@ -159,9 +151,6 @@ void SnapVectorTowards( vec3_t v, vec3_t to ) {
|
||||||
void Bullet_Fire (gentity_t *ent, float spread, int damage ) {
|
void Bullet_Fire (gentity_t *ent, float spread, int damage ) {
|
||||||
trace_t tr;
|
trace_t tr;
|
||||||
vec3_t end;
|
vec3_t end;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
vec3_t impactpoint, bouncedir;
|
|
||||||
#endif
|
|
||||||
float r;
|
float r;
|
||||||
float u;
|
float u;
|
||||||
gentity_t *tent;
|
gentity_t *tent;
|
||||||
|
|
@ -204,27 +193,8 @@ void Bullet_Fire (gentity_t *ent, float spread, int damage ) {
|
||||||
tent->s.otherEntityNum = ent->s.number;
|
tent->s.otherEntityNum = ent->s.number;
|
||||||
|
|
||||||
if ( traceEnt->takedamage) {
|
if ( traceEnt->takedamage) {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ( traceEnt->client && traceEnt->client->invulnerabilityTime > level.time ) {
|
|
||||||
if (G_InvulnerabilityEffect( traceEnt, forward, tr.endpos, impactpoint, bouncedir )) {
|
|
||||||
G_BounceProjectile( muzzle, impactpoint, bouncedir, end );
|
|
||||||
VectorCopy( impactpoint, muzzle );
|
|
||||||
// the player can hit him/herself with the bounced rail
|
|
||||||
passent = ENTITYNUM_NONE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
VectorCopy( tr.endpos, muzzle );
|
|
||||||
passent = traceEnt->s.number;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#endif
|
|
||||||
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
|
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
|
||||||
damage, 0, MOD_MACHINEGUN);
|
damage, 0, MOD_MACHINEGUN);
|
||||||
#ifdef MISSIONPACK
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -266,9 +236,6 @@ qboolean ShotgunPellet( vec3_t start, vec3_t end, gentity_t *ent ) {
|
||||||
trace_t tr;
|
trace_t tr;
|
||||||
int damage, i, passent;
|
int damage, i, passent;
|
||||||
gentity_t *traceEnt;
|
gentity_t *traceEnt;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
vec3_t impactpoint, bouncedir;
|
|
||||||
#endif
|
|
||||||
vec3_t tr_start, tr_end;
|
vec3_t tr_start, tr_end;
|
||||||
|
|
||||||
passent = ent->s.number;
|
passent = ent->s.number;
|
||||||
|
|
@ -285,33 +252,10 @@ qboolean ShotgunPellet( vec3_t start, vec3_t end, gentity_t *ent ) {
|
||||||
|
|
||||||
if ( traceEnt->takedamage) {
|
if ( traceEnt->takedamage) {
|
||||||
damage = DEFAULT_SHOTGUN_DAMAGE * s_quadFactor;
|
damage = DEFAULT_SHOTGUN_DAMAGE * s_quadFactor;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ( traceEnt->client && traceEnt->client->invulnerabilityTime > level.time ) {
|
|
||||||
if (G_InvulnerabilityEffect( traceEnt, forward, tr.endpos, impactpoint, bouncedir )) {
|
|
||||||
G_BounceProjectile( tr_start, impactpoint, bouncedir, tr_end );
|
|
||||||
VectorCopy( impactpoint, tr_start );
|
|
||||||
// the player can hit him/herself with the bounced rail
|
|
||||||
passent = ENTITYNUM_NONE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
VectorCopy( tr.endpos, tr_start );
|
|
||||||
passent = traceEnt->s.number;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
|
|
||||||
damage, 0, MOD_SHOTGUN);
|
|
||||||
if( LogAccuracyHit( traceEnt, ent ) ) {
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, 0, MOD_SHOTGUN);
|
G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, 0, MOD_SHOTGUN);
|
||||||
if( LogAccuracyHit( traceEnt, ent ) ) {
|
if( LogAccuracyHit( traceEnt, ent ) ) {
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
|
@ -440,9 +384,6 @@ weapon_railgun_fire
|
||||||
#define MAX_RAIL_HITS 4
|
#define MAX_RAIL_HITS 4
|
||||||
void weapon_railgun_fire (gentity_t *ent) {
|
void weapon_railgun_fire (gentity_t *ent) {
|
||||||
vec3_t end;
|
vec3_t end;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
vec3_t impactpoint, bouncedir;
|
|
||||||
#endif
|
|
||||||
trace_t trace;
|
trace_t trace;
|
||||||
gentity_t *tent;
|
gentity_t *tent;
|
||||||
gentity_t *traceEnt;
|
gentity_t *traceEnt;
|
||||||
|
|
@ -468,40 +409,11 @@ void weapon_railgun_fire (gentity_t *ent) {
|
||||||
}
|
}
|
||||||
traceEnt = &g_entities[ trace.entityNum ];
|
traceEnt = &g_entities[ trace.entityNum ];
|
||||||
if ( traceEnt->takedamage ) {
|
if ( traceEnt->takedamage ) {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ( traceEnt->client && traceEnt->client->invulnerabilityTime > level.time ) {
|
|
||||||
if ( G_InvulnerabilityEffect( traceEnt, forward, trace.endpos, impactpoint, bouncedir ) ) {
|
|
||||||
G_BounceProjectile( muzzle, impactpoint, bouncedir, end );
|
|
||||||
// snap the endpos to integers to save net bandwidth, but nudged towards the line
|
|
||||||
SnapVectorTowards( trace.endpos, muzzle );
|
|
||||||
// send railgun beam effect
|
|
||||||
tent = G_TempEntity( trace.endpos, EV_RAILTRAIL );
|
|
||||||
// set player number for custom colors on the railtrail
|
|
||||||
tent->s.clientNum = ent->s.clientNum;
|
|
||||||
VectorCopy( muzzle, tent->s.origin2 );
|
|
||||||
// move origin a bit to come closer to the drawn gun muzzle
|
|
||||||
VectorMA( tent->s.origin2, 4, right, tent->s.origin2 );
|
|
||||||
VectorMA( tent->s.origin2, -1, up, tent->s.origin2 );
|
|
||||||
tent->s.eventParm = 255; // don't make the explosion at the end
|
|
||||||
//
|
|
||||||
VectorCopy( impactpoint, muzzle );
|
|
||||||
// the player can hit him/herself with the bounced rail
|
|
||||||
passent = ENTITYNUM_NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if( LogAccuracyHit( traceEnt, ent ) ) {
|
if( LogAccuracyHit( traceEnt, ent ) ) {
|
||||||
hits++;
|
hits++;
|
||||||
}
|
}
|
||||||
G_Damage (traceEnt, ent, ent, forward, trace.endpos, damage, 0, MOD_RAILGUN);
|
G_Damage (traceEnt, ent, ent, forward, trace.endpos, damage, 0, MOD_RAILGUN);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if( LogAccuracyHit( traceEnt, ent ) ) {
|
|
||||||
hits++;
|
|
||||||
}
|
|
||||||
G_Damage (traceEnt, ent, ent, forward, trace.endpos, damage, 0, MOD_RAILGUN);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if ( trace.contents & CONTENTS_SOLID ) {
|
if ( trace.contents & CONTENTS_SOLID ) {
|
||||||
break; // we hit something solid enough to stop the beam
|
break; // we hit something solid enough to stop the beam
|
||||||
}
|
}
|
||||||
|
|
@ -612,9 +524,6 @@ LIGHTNING GUN
|
||||||
void Weapon_LightningFire( gentity_t *ent ) {
|
void Weapon_LightningFire( gentity_t *ent ) {
|
||||||
trace_t tr;
|
trace_t tr;
|
||||||
vec3_t end;
|
vec3_t end;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
vec3_t impactpoint, bouncedir;
|
|
||||||
#endif
|
|
||||||
gentity_t *traceEnt, *tent;
|
gentity_t *traceEnt, *tent;
|
||||||
int damage, i, passent;
|
int damage, i, passent;
|
||||||
|
|
||||||
|
|
@ -626,18 +535,6 @@ void Weapon_LightningFire( gentity_t *ent ) {
|
||||||
|
|
||||||
trap_Trace( &tr, muzzle, NULL, NULL, end, passent, MASK_SHOT );
|
trap_Trace( &tr, muzzle, NULL, NULL, end, passent, MASK_SHOT );
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
// if not the first trace (the lightning bounced of an invulnerability sphere)
|
|
||||||
if (i) {
|
|
||||||
// add bounced off lightning bolt temp entity
|
|
||||||
// the first lightning bolt is a cgame only visual
|
|
||||||
//
|
|
||||||
tent = G_TempEntity( muzzle, EV_LIGHTNINGBOLT );
|
|
||||||
VectorCopy( tr.endpos, end );
|
|
||||||
SnapVector( end );
|
|
||||||
VectorCopy( end, tent->s.origin2 );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if ( tr.entityNum == ENTITYNUM_NONE ) {
|
if ( tr.entityNum == ENTITYNUM_NONE ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -645,31 +542,9 @@ void Weapon_LightningFire( gentity_t *ent ) {
|
||||||
traceEnt = &g_entities[ tr.entityNum ];
|
traceEnt = &g_entities[ tr.entityNum ];
|
||||||
|
|
||||||
if ( traceEnt->takedamage) {
|
if ( traceEnt->takedamage) {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if ( traceEnt->client && traceEnt->client->invulnerabilityTime > level.time ) {
|
|
||||||
if (G_InvulnerabilityEffect( traceEnt, forward, tr.endpos, impactpoint, bouncedir )) {
|
|
||||||
G_BounceProjectile( muzzle, impactpoint, bouncedir, end );
|
|
||||||
VectorCopy( impactpoint, muzzle );
|
|
||||||
VectorSubtract( end, impactpoint, forward );
|
|
||||||
VectorNormalize(forward);
|
|
||||||
// the player can hit him/herself with the bounced lightning
|
|
||||||
passent = ENTITYNUM_NONE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
VectorCopy( tr.endpos, muzzle );
|
|
||||||
passent = traceEnt->s.number;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
|
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
|
||||||
damage, 0, MOD_LIGHTNING);
|
damage, 0, MOD_LIGHTNING);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
|
|
||||||
damage, 0, MOD_LIGHTNING);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( traceEnt->takedamage && traceEnt->client ) {
|
if ( traceEnt->takedamage && traceEnt->client ) {
|
||||||
tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT );
|
tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT );
|
||||||
|
|
@ -688,53 +563,6 @@ void Weapon_LightningFire( gentity_t *ent ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
/*
|
|
||||||
======================================================================
|
|
||||||
|
|
||||||
NAILGUN
|
|
||||||
|
|
||||||
======================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Weapon_Nailgun_Fire (gentity_t *ent) {
|
|
||||||
gentity_t *m;
|
|
||||||
int count;
|
|
||||||
|
|
||||||
for( count = 0; count < NUM_NAILSHOTS; count++ ) {
|
|
||||||
m = fire_nail (ent, muzzle, forward, right, up );
|
|
||||||
m->damage *= s_quadFactor;
|
|
||||||
m->splashDamage *= s_quadFactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta ); // "real" physics
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
======================================================================
|
|
||||||
|
|
||||||
PROXIMITY MINE LAUNCHER
|
|
||||||
|
|
||||||
======================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
void weapon_proxlauncher_fire (gentity_t *ent) {
|
|
||||||
gentity_t *m;
|
|
||||||
|
|
||||||
// extra vertical velocity
|
|
||||||
forward[2] += 0.2f;
|
|
||||||
VectorNormalize( forward );
|
|
||||||
|
|
||||||
m = fire_prox (ent, muzzle, forward);
|
|
||||||
m->damage *= s_quadFactor;
|
|
||||||
m->splashDamage *= s_quadFactor;
|
|
||||||
|
|
||||||
// VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta ); // "real" physics
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -815,24 +643,11 @@ void FireWeapon( gentity_t *ent ) {
|
||||||
} else {
|
} else {
|
||||||
s_quadFactor = 1;
|
s_quadFactor = 1;
|
||||||
}
|
}
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( ent->client->persistantPowerup && ent->client->persistantPowerup->item && ent->client->persistantPowerup->item->giTag == PW_DOUBLER ) {
|
|
||||||
s_quadFactor *= 2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// track shots taken for accuracy tracking. Grapple is not a weapon and gauntet is just not tracked
|
// track shots taken for accuracy tracking. Grapple is not a weapon and gauntet is just not tracked
|
||||||
if( ent->s.weapon != WP_GRAPPLING_HOOK && ent->s.weapon != WP_GAUNTLET ) {
|
if( ent->s.weapon != WP_GRAPPLING_HOOK && ent->s.weapon != WP_GAUNTLET ) {
|
||||||
#ifdef MISSIONPACK
|
|
||||||
if( ent->s.weapon == WP_NAILGUN ) {
|
|
||||||
ent->client->accuracy_shots += NUM_NAILSHOTS;
|
|
||||||
} else {
|
|
||||||
ent->client->accuracy_shots++;
|
ent->client->accuracy_shots++;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
ent->client->accuracy_shots++;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// set aiming directions
|
// set aiming directions
|
||||||
AngleVectors (ent->client->ps.viewangles, forward, right, up);
|
AngleVectors (ent->client->ps.viewangles, forward, right, up);
|
||||||
|
|
@ -875,271 +690,8 @@ void FireWeapon( gentity_t *ent ) {
|
||||||
case WP_GRAPPLING_HOOK:
|
case WP_GRAPPLING_HOOK:
|
||||||
Weapon_GrapplingHook_Fire( ent );
|
Weapon_GrapplingHook_Fire( ent );
|
||||||
break;
|
break;
|
||||||
#ifdef MISSIONPACK
|
|
||||||
case WP_NAILGUN:
|
|
||||||
Weapon_Nailgun_Fire( ent );
|
|
||||||
break;
|
|
||||||
case WP_PROX_LAUNCHER:
|
|
||||||
weapon_proxlauncher_fire( ent );
|
|
||||||
break;
|
|
||||||
case WP_CHAINGUN:
|
|
||||||
Bullet_Fire( ent, CHAINGUN_SPREAD, MACHINEGUN_DAMAGE );
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
// FIXME G_Error( "Bad ent->s.weapon" );
|
// FIXME G_Error( "Bad ent->s.weapon" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
|
|
||||||
/*
|
|
||||||
===============
|
|
||||||
KamikazeRadiusDamage
|
|
||||||
===============
|
|
||||||
*/
|
|
||||||
static void KamikazeRadiusDamage( vec3_t origin, gentity_t *attacker, float damage, float radius ) {
|
|
||||||
float dist;
|
|
||||||
gentity_t *ent;
|
|
||||||
int entityList[MAX_GENTITIES];
|
|
||||||
int numListedEntities;
|
|
||||||
vec3_t mins, maxs;
|
|
||||||
vec3_t v;
|
|
||||||
vec3_t dir;
|
|
||||||
int i, e;
|
|
||||||
|
|
||||||
if ( radius < 1 ) {
|
|
||||||
radius = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = 0 ; i < 3 ; i++ ) {
|
|
||||||
mins[i] = origin[i] - radius;
|
|
||||||
maxs[i] = origin[i] + radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
|
|
||||||
|
|
||||||
for ( e = 0 ; e < numListedEntities ; e++ ) {
|
|
||||||
ent = &g_entities[entityList[ e ]];
|
|
||||||
|
|
||||||
if (!ent->takedamage) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// dont hit things we have already hit
|
|
||||||
if( ent->kamikazeTime > level.time ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the distance from the edge of the bounding box
|
|
||||||
for ( i = 0 ; i < 3 ; i++ ) {
|
|
||||||
if ( origin[i] < ent->r.absmin[i] ) {
|
|
||||||
v[i] = ent->r.absmin[i] - origin[i];
|
|
||||||
} else if ( origin[i] > ent->r.absmax[i] ) {
|
|
||||||
v[i] = origin[i] - ent->r.absmax[i];
|
|
||||||
} else {
|
|
||||||
v[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dist = VectorLength( v );
|
|
||||||
if ( dist >= radius ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if( CanDamage (ent, origin) ) {
|
|
||||||
VectorSubtract (ent->r.currentOrigin, origin, dir);
|
|
||||||
// push the center of mass higher than the origin so players
|
|
||||||
// get knocked into the air more
|
|
||||||
dir[2] += 24;
|
|
||||||
G_Damage( ent, NULL, attacker, dir, origin, damage, DAMAGE_RADIUS|DAMAGE_NO_TEAM_PROTECTION, MOD_KAMIKAZE );
|
|
||||||
ent->kamikazeTime = level.time + 3000;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
===============
|
|
||||||
KamikazeShockWave
|
|
||||||
===============
|
|
||||||
*/
|
|
||||||
static void KamikazeShockWave( vec3_t origin, gentity_t *attacker, float damage, float push, float radius ) {
|
|
||||||
float dist;
|
|
||||||
gentity_t *ent;
|
|
||||||
int entityList[MAX_GENTITIES];
|
|
||||||
int numListedEntities;
|
|
||||||
vec3_t mins, maxs;
|
|
||||||
vec3_t v;
|
|
||||||
vec3_t dir;
|
|
||||||
int i, e;
|
|
||||||
|
|
||||||
if ( radius < 1 )
|
|
||||||
radius = 1;
|
|
||||||
|
|
||||||
for ( i = 0 ; i < 3 ; i++ ) {
|
|
||||||
mins[i] = origin[i] - radius;
|
|
||||||
maxs[i] = origin[i] + radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
|
|
||||||
|
|
||||||
for ( e = 0 ; e < numListedEntities ; e++ ) {
|
|
||||||
ent = &g_entities[entityList[ e ]];
|
|
||||||
|
|
||||||
// dont hit things we have already hit
|
|
||||||
if( ent->kamikazeShockTime > level.time ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the distance from the edge of the bounding box
|
|
||||||
for ( i = 0 ; i < 3 ; i++ ) {
|
|
||||||
if ( origin[i] < ent->r.absmin[i] ) {
|
|
||||||
v[i] = ent->r.absmin[i] - origin[i];
|
|
||||||
} else if ( origin[i] > ent->r.absmax[i] ) {
|
|
||||||
v[i] = origin[i] - ent->r.absmax[i];
|
|
||||||
} else {
|
|
||||||
v[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dist = VectorLength( v );
|
|
||||||
if ( dist >= radius ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if( CanDamage (ent, origin) ) {
|
|
||||||
VectorSubtract (ent->r.currentOrigin, origin, dir);
|
|
||||||
dir[2] += 24;
|
|
||||||
G_Damage( ent, NULL, attacker, dir, origin, damage, DAMAGE_RADIUS|DAMAGE_NO_TEAM_PROTECTION, MOD_KAMIKAZE );
|
|
||||||
//
|
|
||||||
dir[2] = 0;
|
|
||||||
VectorNormalize(dir);
|
|
||||||
if ( ent->client ) {
|
|
||||||
ent->client->ps.velocity[0] = dir[0] * push;
|
|
||||||
ent->client->ps.velocity[1] = dir[1] * push;
|
|
||||||
ent->client->ps.velocity[2] = 100;
|
|
||||||
}
|
|
||||||
ent->kamikazeShockTime = level.time + 3000;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
===============
|
|
||||||
KamikazeDamage
|
|
||||||
===============
|
|
||||||
*/
|
|
||||||
static void KamikazeDamage( gentity_t *self ) {
|
|
||||||
int i;
|
|
||||||
float t;
|
|
||||||
gentity_t *ent;
|
|
||||||
vec3_t newangles;
|
|
||||||
|
|
||||||
self->count += 100;
|
|
||||||
|
|
||||||
if (self->count >= KAMI_SHOCKWAVE_STARTTIME) {
|
|
||||||
// shockwave push back
|
|
||||||
t = self->count - KAMI_SHOCKWAVE_STARTTIME;
|
|
||||||
KamikazeShockWave(self->s.pos.trBase, self->activator, 25, 400, (int) (float) t * KAMI_SHOCKWAVE_MAXRADIUS / (KAMI_SHOCKWAVE_ENDTIME - KAMI_SHOCKWAVE_STARTTIME) );
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if (self->count >= KAMI_EXPLODE_STARTTIME) {
|
|
||||||
// do our damage
|
|
||||||
t = self->count - KAMI_EXPLODE_STARTTIME;
|
|
||||||
KamikazeRadiusDamage( self->s.pos.trBase, self->activator, 400, (int) (float) t * KAMI_BOOMSPHERE_MAXRADIUS / (KAMI_IMPLODE_STARTTIME - KAMI_EXPLODE_STARTTIME) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// either cycle or kill self
|
|
||||||
if( self->count >= KAMI_SHOCKWAVE_ENDTIME ) {
|
|
||||||
G_FreeEntity( self );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
self->nextthink = level.time + 100;
|
|
||||||
|
|
||||||
// add earth quake effect
|
|
||||||
newangles[0] = crandom() * 2;
|
|
||||||
newangles[1] = crandom() * 2;
|
|
||||||
newangles[2] = 0;
|
|
||||||
for (i = 0; i < MAX_CLIENTS; i++)
|
|
||||||
{
|
|
||||||
ent = &g_entities[i];
|
|
||||||
if (!ent->inuse)
|
|
||||||
continue;
|
|
||||||
if (!ent->client)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (ent->client->ps.groundEntityNum != ENTITYNUM_NONE) {
|
|
||||||
ent->client->ps.velocity[0] += crandom() * 120;
|
|
||||||
ent->client->ps.velocity[1] += crandom() * 120;
|
|
||||||
ent->client->ps.velocity[2] = 30 + random() * 25;
|
|
||||||
}
|
|
||||||
|
|
||||||
ent->client->ps.delta_angles[0] += ANGLE2SHORT(newangles[0] - self->movedir[0]);
|
|
||||||
ent->client->ps.delta_angles[1] += ANGLE2SHORT(newangles[1] - self->movedir[1]);
|
|
||||||
ent->client->ps.delta_angles[2] += ANGLE2SHORT(newangles[2] - self->movedir[2]);
|
|
||||||
}
|
|
||||||
VectorCopy(newangles, self->movedir);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
===============
|
|
||||||
G_StartKamikaze
|
|
||||||
===============
|
|
||||||
*/
|
|
||||||
void G_StartKamikaze( gentity_t *ent ) {
|
|
||||||
gentity_t *explosion;
|
|
||||||
gentity_t *te;
|
|
||||||
vec3_t snapped;
|
|
||||||
|
|
||||||
// start up the explosion logic
|
|
||||||
explosion = G_Spawn();
|
|
||||||
|
|
||||||
explosion->s.eType = ET_EVENTS + EV_KAMIKAZE;
|
|
||||||
explosion->eventTime = level.time;
|
|
||||||
|
|
||||||
if ( ent->client ) {
|
|
||||||
VectorCopy( ent->s.pos.trBase, snapped );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
VectorCopy( ent->activator->s.pos.trBase, snapped );
|
|
||||||
}
|
|
||||||
SnapVector( snapped ); // save network bandwidth
|
|
||||||
G_SetOrigin( explosion, snapped );
|
|
||||||
|
|
||||||
explosion->classname = "kamikaze";
|
|
||||||
explosion->s.pos.trType = TR_STATIONARY;
|
|
||||||
|
|
||||||
explosion->kamikazeTime = level.time;
|
|
||||||
|
|
||||||
explosion->think = KamikazeDamage;
|
|
||||||
explosion->nextthink = level.time + 100;
|
|
||||||
explosion->count = 0;
|
|
||||||
VectorClear(explosion->movedir);
|
|
||||||
|
|
||||||
trap_LinkEntity( explosion );
|
|
||||||
|
|
||||||
if (ent->client) {
|
|
||||||
//
|
|
||||||
explosion->activator = ent;
|
|
||||||
//
|
|
||||||
ent->s.eFlags &= ~EF_KAMIKAZE;
|
|
||||||
// nuke the guy that used it
|
|
||||||
G_Damage( ent, ent, ent, NULL, NULL, 100000, DAMAGE_NO_PROTECTION, MOD_KAMIKAZE );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( !strcmp(ent->activator->classname, "bodyque") ) {
|
|
||||||
explosion->activator = &g_entities[ent->activator->r.ownerNum];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
explosion->activator = ent->activator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// play global sound at all clients
|
|
||||||
te = G_TempEntity(snapped, EV_GLOBAL_TEAM_SOUND );
|
|
||||||
te->r.svFlags |= SVF_BROADCAST;
|
|
||||||
te->s.eventParm = GTS_KAMIKAZE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|
|
@ -78,13 +78,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#define NUM_VISIBLE_ENEMIES 202
|
#define NUM_VISIBLE_ENEMIES 202
|
||||||
#define NUM_VISIBLE_TEAMMATES 203
|
#define NUM_VISIBLE_TEAMMATES 203
|
||||||
|
|
||||||
// if running the mission pack
|
|
||||||
#ifdef MISSIONPACK
|
|
||||||
|
|
||||||
//#error "running mission pack"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//item numbers (make sure they are in sync with bg_itemlist in bg_misc.c)
|
//item numbers (make sure they are in sync with bg_itemlist in bg_misc.c)
|
||||||
#define MODELINDEX_ARMORSHARD 1
|
#define MODELINDEX_ARMORSHARD 1
|
||||||
#define MODELINDEX_ARMORCOMBAT 2
|
#define MODELINDEX_ARMORCOMBAT 2
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user