mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-22 12:41:21 +00:00
game: Add g_ctf to game
This commit is contained in:
parent
fb5216ffcf
commit
675ce35e75
9 changed files with 264 additions and 220 deletions
7
Makefile
7
Makefile
|
@ -853,6 +853,7 @@ GAME_OBJS_ = \
|
|||
src/game/g_ai.o \
|
||||
src/game/g_chase.o \
|
||||
src/game/g_cmds.o \
|
||||
src/game/g_ctf.o \
|
||||
src/game/g_combat.o \
|
||||
src/game/g_func.o \
|
||||
src/game/g_items.o \
|
||||
|
@ -876,6 +877,7 @@ GAME_OBJS_ = \
|
|||
src/game/g_weapon.o \
|
||||
src/game/dm/ball.o \
|
||||
src/game/dm/tag.o \
|
||||
src/game/menu/menu.o \
|
||||
src/game/monster/berserker/berserker.o \
|
||||
src/game/monster/boss2/boss2.o \
|
||||
src/game/monster/boss3/boss3.o \
|
||||
|
@ -1466,11 +1468,12 @@ CTF_OBJS_ = \
|
|||
src/common/shared/rand.o \
|
||||
src/common/shared/shared.o \
|
||||
src/game/g_newai.o \
|
||||
src/game/g_newtrig.o \
|
||||
src/ctf/g_ai.o \
|
||||
src/ctf/g_chase.o \
|
||||
src/ctf/g_cmds.o \
|
||||
src/ctf/g_combat.o \
|
||||
src/ctf/g_ctf.o \
|
||||
src/game/g_ctf.o \
|
||||
src/ctf/g_func.o \
|
||||
src/ctf/g_items.o \
|
||||
src/ctf/g_main.o \
|
||||
|
@ -1484,7 +1487,7 @@ CTF_OBJS_ = \
|
|||
src/ctf/g_trigger.o \
|
||||
src/ctf/g_utils.o \
|
||||
src/ctf/g_weapon.o \
|
||||
src/ctf/menu/menu.o \
|
||||
src/game/menu/menu.o \
|
||||
src/game/monster/misc/move.o \
|
||||
src/ctf/player/client.o \
|
||||
src/ctf/player/hud.o \
|
||||
|
|
124
src/ctf/g_cmds.c
124
src/ctf/g_cmds.c
|
@ -498,9 +498,9 @@ Cmd_Notarget_f(edict_t *ent)
|
|||
return;
|
||||
}
|
||||
|
||||
if (deathmatch->value && !sv_cheats->value)
|
||||
if ((deathmatch->value || coop->value) && !sv_cheats->value)
|
||||
{
|
||||
gi.cprintf( ent, PRINT_HIGH,
|
||||
gi.cprintf(ent, PRINT_HIGH,
|
||||
"You must run the server with '+set cheats 1' to enable this command.\n");
|
||||
return;
|
||||
}
|
||||
|
@ -527,9 +527,14 @@ Cmd_Noclip_f(edict_t *ent)
|
|||
{
|
||||
char *msg;
|
||||
|
||||
if (deathmatch->value && !sv_cheats->value)
|
||||
if (!ent)
|
||||
{
|
||||
gi.cprintf( ent, PRINT_HIGH,
|
||||
return;
|
||||
}
|
||||
|
||||
if ((deathmatch->value || coop->value) && !sv_cheats->value)
|
||||
{
|
||||
gi.cprintf(ent, PRINT_HIGH,
|
||||
"You must run the server with '+set cheats 1' to enable this command.\n");
|
||||
return;
|
||||
}
|
||||
|
@ -558,6 +563,11 @@ Cmd_Use_f(edict_t *ent)
|
|||
gitem_t *it;
|
||||
char *s;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s = gi.args();
|
||||
it = FindItem(s);
|
||||
|
||||
|
@ -594,6 +604,11 @@ Cmd_Drop_f(edict_t *ent)
|
|||
gitem_t *it;
|
||||
char *s;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((Q_stricmp(gi.args(), "tech") == 0) && ((it = CTFWhat_Tech(ent)) != NULL))
|
||||
{
|
||||
it->drop(ent, it);
|
||||
|
@ -626,12 +641,81 @@ Cmd_Drop_f(edict_t *ent)
|
|||
it->drop(ent, it);
|
||||
}
|
||||
|
||||
/*
|
||||
* Display the scoreboard
|
||||
*/
|
||||
void
|
||||
Cmd_Score_f(edict_t *ent)
|
||||
{
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ent->client->showinventory = false;
|
||||
ent->client->showhelp = false;
|
||||
|
||||
if (ent->client->menu)
|
||||
{
|
||||
PMenu_Close(ent);
|
||||
}
|
||||
|
||||
if (!deathmatch->value && !coop->value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->client->showscores)
|
||||
{
|
||||
ent->client->showscores = false;
|
||||
ent->client->update_chase = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ent->client->showscores = true;
|
||||
DeathmatchScoreboardMessage(ent, ent->enemy);
|
||||
gi.unicast(ent, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Display the current help message
|
||||
*/
|
||||
void
|
||||
Cmd_Help_f(edict_t *ent)
|
||||
{
|
||||
/* this is for backwards compatability */
|
||||
if (deathmatch->value)
|
||||
{
|
||||
Cmd_Score_f(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
ent->client->showinventory = false;
|
||||
ent->client->showscores = false;
|
||||
|
||||
if (ent->client->showhelp &&
|
||||
(ent->client->resp.game_helpchanged == game.helpchanged))
|
||||
{
|
||||
ent->client->showhelp = false;
|
||||
return;
|
||||
}
|
||||
|
||||
ent->client->showhelp = true;
|
||||
ent->client->resp.helpchanged = 0;
|
||||
HelpComputerMessage(ent);
|
||||
}
|
||||
|
||||
void
|
||||
Cmd_Inven_f(edict_t *ent)
|
||||
{
|
||||
int i;
|
||||
gclient_t *cl;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cl = ent->client;
|
||||
|
||||
cl->showscores = false;
|
||||
|
@ -769,6 +853,11 @@ Cmd_WeapNext_f(edict_t *ent)
|
|||
gitem_t *it;
|
||||
int selected_weapon;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cl = ent->client;
|
||||
|
||||
if (!cl->pers.weapon)
|
||||
|
@ -816,6 +905,11 @@ Cmd_WeapLast_f(edict_t *ent)
|
|||
int index;
|
||||
gitem_t *it;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cl = ent->client;
|
||||
|
||||
if (!cl->pers.weapon || !cl->pers.lastweapon)
|
||||
|
@ -850,6 +944,11 @@ Cmd_InvDrop_f(edict_t *ent)
|
|||
{
|
||||
gitem_t *it;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ValidateSelectedItem(ent);
|
||||
|
||||
if (ent->client->pers.selected_item == -1)
|
||||
|
@ -908,6 +1007,11 @@ PlayerSort(void const *a, void const *b)
|
|||
{
|
||||
int anum, bnum;
|
||||
|
||||
if (!a || !b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
anum = *(int *)a;
|
||||
bnum = *(int *)b;
|
||||
|
||||
|
@ -936,6 +1040,11 @@ Cmd_Players_f(edict_t *ent)
|
|||
char large[1280];
|
||||
int index[256];
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
|
||||
for (i = 0; i < maxclients->value; i++)
|
||||
|
@ -977,7 +1086,12 @@ Cmd_Wave_f(edict_t *ent)
|
|||
{
|
||||
int i;
|
||||
|
||||
i = atoi(gi.argv(1));
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
i = (int)strtol(gi.argv(1), (char **)NULL, 10);
|
||||
|
||||
/* can't wave when ducked */
|
||||
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
* Copyright (C) 2011 Knightmare
|
||||
* Copyright (C) 2011 Yamagi Burmeister
|
||||
* Copyright (c) ZeniMax Media Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -206,8 +209,13 @@ InitGame(void)
|
|||
/* dm map list */
|
||||
sv_maplist = gi.cvar("sv_maplist", "", 0);
|
||||
|
||||
/* disruptor availability */
|
||||
g_disruptor = gi.cvar("g_disruptor", "0", 0);
|
||||
|
||||
/* others */
|
||||
aimfix = gi.cvar("aimfix", "0", CVAR_ARCHIVE);
|
||||
g_machinegun_norecoil = gi.cvar("g_machinegun_norecoil", "0", CVAR_ARCHIVE);
|
||||
g_swap_speed = gi.cvar("g_swap_speed", "1", 0);
|
||||
|
||||
/* items */
|
||||
InitItems();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
* Copyright (c) ZeniMax Media Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -37,6 +38,11 @@
|
|||
void
|
||||
MoveClientToIntermission(edict_t *ent)
|
||||
{
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (deathmatch->value || coop->value)
|
||||
{
|
||||
ent->client->showscores = true;
|
||||
|
@ -59,6 +65,15 @@ MoveClientToIntermission(edict_t *ent)
|
|||
ent->client->enviro_framenum = 0;
|
||||
ent->client->grenade_blew_up = false;
|
||||
ent->client->grenade_time = 0;
|
||||
ent->client->quadfire_framenum = 0;
|
||||
ent->client->trap_blew_up = false;
|
||||
ent->client->trap_time = 0;
|
||||
ent->client->ir_framenum = 0;
|
||||
ent->client->nuke_framenum = 0;
|
||||
ent->client->double_framenum = 0;
|
||||
|
||||
ent->client->ps.rdflags &= ~RDF_IRGOGGLES;
|
||||
|
||||
|
||||
ent->viewheight = 0;
|
||||
ent->s.modelindex = 0;
|
||||
|
@ -69,8 +84,9 @@ MoveClientToIntermission(edict_t *ent)
|
|||
ent->s.sound = 0;
|
||||
ent->solid = SOLID_NOT;
|
||||
|
||||
/* add the layout */
|
||||
gi.linkentity(ent);
|
||||
|
||||
/* add the layout */
|
||||
if (deathmatch->value || coop->value)
|
||||
{
|
||||
DeathmatchScoreboardMessage(ent, NULL);
|
||||
|
@ -81,8 +97,8 @@ MoveClientToIntermission(edict_t *ent)
|
|||
void
|
||||
BeginIntermission(edict_t *targ)
|
||||
{
|
||||
int i, n;
|
||||
edict_t *ent, *client;
|
||||
int i;
|
||||
edict_t *ent;
|
||||
|
||||
if (level.intermissiontime)
|
||||
{
|
||||
|
@ -99,6 +115,8 @@ BeginIntermission(edict_t *targ)
|
|||
/* respawn any dead clients */
|
||||
for (i = 0; i < maxclients->value; i++)
|
||||
{
|
||||
edict_t *client;
|
||||
|
||||
client = g_edicts + 1 + i;
|
||||
|
||||
if (!client->inuse)
|
||||
|
@ -121,6 +139,9 @@ BeginIntermission(edict_t *targ)
|
|||
{
|
||||
for (i = 0; i < maxclients->value; i++)
|
||||
{
|
||||
int n;
|
||||
edict_t *client;
|
||||
|
||||
client = g_edicts + 1 + i;
|
||||
|
||||
if (!client->inuse)
|
||||
|
@ -166,7 +187,7 @@ BeginIntermission(edict_t *targ)
|
|||
else
|
||||
{
|
||||
/* chose one of four spots */
|
||||
i = rand() & 3;
|
||||
i = randk() & 3;
|
||||
|
||||
while (i--)
|
||||
{
|
||||
|
@ -185,6 +206,8 @@ BeginIntermission(edict_t *targ)
|
|||
/* move all clients to the intermission point */
|
||||
for (i = 0; i < maxclients->value; i++)
|
||||
{
|
||||
edict_t *client;
|
||||
|
||||
client = g_edicts + 1 + i;
|
||||
|
||||
if (!client->inuse)
|
||||
|
@ -211,6 +234,12 @@ DeathmatchScoreboardMessage(edict_t *ent, edict_t *killer)
|
|||
edict_t *cl_ent;
|
||||
char *tag;
|
||||
|
||||
|
||||
if (!ent) /* killer can be NULL */
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctf->value)
|
||||
{
|
||||
CTFScoreboardMessage(ent, killer);
|
||||
|
@ -299,7 +328,8 @@ DeathmatchScoreboardMessage(edict_t *ent, edict_t *killer)
|
|||
}
|
||||
|
||||
/* send the layout */
|
||||
Com_sprintf(entry, sizeof(entry), "client %i %i %i %i %i %i ",
|
||||
Com_sprintf(entry, sizeof(entry),
|
||||
"client %i %i %i %i %i %i ",
|
||||
x, y, sorted[i], cl->resp.score, cl->ping,
|
||||
(level.framenum - cl->resp.enterframe) / 600);
|
||||
j = strlen(entry);
|
||||
|
@ -329,55 +359,29 @@ DeathmatchScoreboard(edict_t *ent)
|
|||
gi.unicast(ent, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Display the scoreboard
|
||||
*/
|
||||
void
|
||||
Cmd_Score_f(edict_t *ent)
|
||||
{
|
||||
ent->client->showinventory = false;
|
||||
ent->client->showhelp = false;
|
||||
|
||||
if (ent->client->menu)
|
||||
{
|
||||
PMenu_Close(ent);
|
||||
}
|
||||
|
||||
if (!deathmatch->value && !coop->value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->client->showscores)
|
||||
{
|
||||
ent->client->showscores = false;
|
||||
ent->client->update_chase = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ent->client->showscores = true;
|
||||
|
||||
DeathmatchScoreboard(ent);
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw help computer.
|
||||
*/
|
||||
static void
|
||||
HelpComputer(edict_t *ent)
|
||||
void
|
||||
HelpComputerMessage(edict_t *ent)
|
||||
{
|
||||
char string[1024];
|
||||
char *sk;
|
||||
|
||||
if (skill->value == 0)
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (skill->value == SKILL_EASY)
|
||||
{
|
||||
sk = "easy";
|
||||
}
|
||||
else if (skill->value == 1)
|
||||
else if (skill->value == SKILL_MEDIUM)
|
||||
{
|
||||
sk = "medium";
|
||||
}
|
||||
else if (skill->value == 2)
|
||||
else if (skill->value == SKILL_HARD)
|
||||
{
|
||||
sk = "hard";
|
||||
}
|
||||
|
@ -412,28 +416,21 @@ HelpComputer(edict_t *ent)
|
|||
* Display the current help message
|
||||
*/
|
||||
void
|
||||
Cmd_Help_f(edict_t *ent)
|
||||
InventoryMessage(edict_t *ent)
|
||||
{
|
||||
/* this is for backwards compatability */
|
||||
if (deathmatch->value)
|
||||
int i;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
Cmd_Score_f(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
ent->client->showinventory = false;
|
||||
ent->client->showscores = false;
|
||||
gi.WriteByte(svc_inventory);
|
||||
|
||||
if (ent->client->showhelp &&
|
||||
(ent->client->resp.game_helpchanged == game.helpchanged))
|
||||
for (i = 0; i < MAX_ITEMS; i++)
|
||||
{
|
||||
ent->client->showhelp = false;
|
||||
return;
|
||||
gi.WriteShort(ent->client->pers.inventory[i]);
|
||||
}
|
||||
|
||||
ent->client->showhelp = true;
|
||||
ent->client->resp.helpchanged = 0;
|
||||
HelpComputer(ent);
|
||||
}
|
||||
|
||||
/* ======================================================================= */
|
||||
|
@ -442,13 +439,17 @@ void
|
|||
G_SetStats(edict_t *ent)
|
||||
{
|
||||
gitem_t *item;
|
||||
int index, cells;
|
||||
int index, cells = 0;
|
||||
int power_armor_type;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* health */
|
||||
ent->client->ps.stats[STAT_HEALTH_ICON] = level.pic_health;
|
||||
ent->client->ps.stats[STAT_HEALTH] = ent->health;
|
||||
ent->client->ps.stats[STAT_HEALTH] = (ent->health < -99) ? -99 : ent->health;
|
||||
|
||||
/* ammo */
|
||||
if (!ent->client->ammo_index)
|
||||
|
|
|
@ -673,6 +673,9 @@ Cmd_Drop_f(edict_t *ent)
|
|||
it->drop(ent, it);
|
||||
}
|
||||
|
||||
/*
|
||||
* Display the scoreboard
|
||||
*/
|
||||
void
|
||||
Cmd_Score_f(edict_t *ent)
|
||||
{
|
||||
|
@ -684,6 +687,11 @@ Cmd_Score_f(edict_t *ent)
|
|||
ent->client->showinventory = false;
|
||||
ent->client->showhelp = false;
|
||||
|
||||
if (ent->client->menu)
|
||||
{
|
||||
PMenu_Close(ent);
|
||||
}
|
||||
|
||||
if (!deathmatch->value && !coop->value)
|
||||
{
|
||||
return;
|
||||
|
@ -808,7 +816,7 @@ Cmd_WeapPrev_f(edict_t *ent)
|
|||
|
||||
selected_weapon = ITEM_INDEX(cl->pers.weapon);
|
||||
|
||||
/* scan for the next valid one */
|
||||
/* scan for the next valid one */
|
||||
for (i = 1; i <= MAX_ITEMS; i++)
|
||||
{
|
||||
/* prevent scrolling through ALL weapons */
|
||||
|
@ -1147,8 +1155,8 @@ Cmd_Wave_f(edict_t *ent)
|
|||
}
|
||||
}
|
||||
|
||||
static qboolean
|
||||
flooded(edict_t *ent)
|
||||
qboolean
|
||||
CheckFlood(edict_t *ent)
|
||||
{
|
||||
gclient_t *cl;
|
||||
int i;
|
||||
|
@ -1233,7 +1241,7 @@ Cmd_Say_f(edict_t *ent, qboolean team, qboolean arg0)
|
|||
return;
|
||||
}
|
||||
|
||||
if (flooded(ent))
|
||||
if (CheckFlood(ent))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ cvar_t *warp_list;
|
|||
cvar_t *warn_unbalanced;
|
||||
|
||||
/* Index for various CTF pics, this saves us
|
||||
* from calling gi.imageindex all the time
|
||||
* from calling gi.imageindex all the time
|
||||
* and saves a few CPU cycles since we don't
|
||||
* have to do a bunch of string compares all
|
||||
* the time. * These are set in CTFPrecache()
|
||||
|
@ -250,7 +250,7 @@ stuffcmd(edict_t *ent, char *s)
|
|||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Returns entities that have
|
||||
* Returns entities that have
|
||||
* origins within a spherical area
|
||||
*/
|
||||
static edict_t *
|
||||
|
@ -641,7 +641,7 @@ SelectCTFSpawnPoint(edict_t *ent)
|
|||
/*
|
||||
* Calculate the bonuses for flag defense,
|
||||
* flag carrier defense, etc. Note that b
|
||||
* onuses are not cumaltive. You get one,
|
||||
* onuses are not cumaltive. You get one,
|
||||
* they are in importance order.
|
||||
*/
|
||||
void
|
||||
|
@ -706,7 +706,7 @@ CTFFragBonuses(edict_t *targ, edict_t *inflictor, edict_t *attacker)
|
|||
CTF_FRAG_CARRIER_BONUS);
|
||||
|
||||
/* the target had the flag, clear
|
||||
the hurt carrier field on the
|
||||
the hurt carrier field on the
|
||||
other team */
|
||||
for (i = 1; i <= maxclients->value; i++)
|
||||
{
|
||||
|
@ -726,8 +726,8 @@ CTFFragBonuses(edict_t *targ, edict_t *inflictor, edict_t *attacker)
|
|||
CTF_CARRIER_DANGER_PROTECT_TIMEOUT) &&
|
||||
!attacker->client->pers.inventory[ITEM_INDEX(flag_item)])
|
||||
{
|
||||
/* attacker is on the same team
|
||||
as the flag carrier and
|
||||
/* attacker is on the same team
|
||||
as the flag carrier and
|
||||
fragged a guy who hurt our
|
||||
flag carrier */
|
||||
attacker->client->resp.score += CTF_CARRIER_DANGER_PROTECT_BONUS;
|
||||
|
@ -744,8 +744,8 @@ CTFFragBonuses(edict_t *targ, edict_t *inflictor, edict_t *attacker)
|
|||
return;
|
||||
}
|
||||
|
||||
/* flag and flag carrier area defense bonuses
|
||||
we have to find the flag and carrier entities
|
||||
/* flag and flag carrier area defense bonuses
|
||||
we have to find the flag and carrier entities
|
||||
find the flag */
|
||||
switch (attacker->client->resp.ctf_team)
|
||||
{
|
||||
|
@ -941,7 +941,7 @@ CTFPickup_Flag(edict_t *ent, edict_t *other)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* same team, if the flag at base,
|
||||
/* same team, if the flag at base,
|
||||
check to he has the enemy flag */
|
||||
if (ctf_team == CTF_TEAM1)
|
||||
{
|
||||
|
@ -1059,9 +1059,9 @@ CTFPickup_Flag(edict_t *ent, edict_t *other)
|
|||
other->client->pers.inventory[ITEM_INDEX(flag_item)] = 1;
|
||||
other->client->resp.ctf_flagsince = level.time;
|
||||
|
||||
/* pick up the flag
|
||||
if it's not a dropped flag,
|
||||
we just make is disappear
|
||||
/* pick up the flag
|
||||
if it's not a dropped flag,
|
||||
we just make is disappear
|
||||
if it's dropped, it will be
|
||||
removed by the pickup caller */
|
||||
if (!(ent->spawnflags & DROPPED_ITEM))
|
||||
|
@ -1091,8 +1091,8 @@ CTFDropFlagTouch(edict_t *ent, edict_t *other,
|
|||
static void
|
||||
CTFDropFlagThink(edict_t *ent)
|
||||
{
|
||||
/* auto return the flag
|
||||
reset flag will remove
|
||||
/* auto return the flag
|
||||
reset flag will remove
|
||||
ourselves */
|
||||
if (strcmp(ent->classname, "item_flag_team1") == 0)
|
||||
{
|
||||
|
@ -1108,7 +1108,7 @@ CTFDropFlagThink(edict_t *ent)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Called from PlayerDie, to drop
|
||||
* the flag from a dying player
|
||||
*/
|
||||
|
@ -1242,8 +1242,8 @@ CTFEffects(edict_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when we enter the intermission
|
||||
/*
|
||||
* Called when we enter the intermission
|
||||
*/
|
||||
void
|
||||
CTFCalcScores(void)
|
||||
|
@ -1407,7 +1407,7 @@ SetCTFStats(edict_t *ent)
|
|||
/* if during intermission, we must blink
|
||||
the team header of the winning team */
|
||||
if (level.intermissiontime && (level.framenum & 8)) /* blink 1/8th second */
|
||||
{
|
||||
{
|
||||
/* note that ctfgame.total[12] is
|
||||
set when we go to intermission */
|
||||
if (ctfgame.team1 > ctfgame.team2)
|
||||
|
@ -1450,9 +1450,9 @@ SetCTFStats(edict_t *ent)
|
|||
}
|
||||
|
||||
/* figure out what icon to display for team logos
|
||||
three states:
|
||||
three states:
|
||||
flag at base
|
||||
flag taken
|
||||
flag taken
|
||||
flag dropped */
|
||||
p1 = imageindex_i_ctf1;
|
||||
e = G_Find(NULL, FOFS(classname), "item_flag_team1");
|
||||
|
@ -1463,7 +1463,7 @@ SetCTFStats(edict_t *ent)
|
|||
{
|
||||
int i;
|
||||
|
||||
/* not at base
|
||||
/* not at base
|
||||
check if on player */
|
||||
p1 = imageindex_i_ctf1d; /* default to dropped */
|
||||
|
||||
|
@ -1493,7 +1493,7 @@ SetCTFStats(edict_t *ent)
|
|||
{
|
||||
int i;
|
||||
|
||||
/* not at base
|
||||
/* not at base
|
||||
check if on player */
|
||||
p2 = imageindex_i_ctf2d; /* default to dropped */
|
||||
|
||||
|
@ -1707,8 +1707,8 @@ CTFGrappleTouch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf
|
|||
gi.multicast(self->s.origin, MULTICAST_PVS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw beam between grapple and self
|
||||
/*
|
||||
* Draw beam between grapple and self
|
||||
*/
|
||||
void
|
||||
CTFGrappleDrawCable(edict_t *self)
|
||||
|
@ -1746,8 +1746,8 @@ CTFGrappleDrawCable(edict_t *self)
|
|||
|
||||
void SV_AddGravity(edict_t *ent);
|
||||
|
||||
/*
|
||||
* pull the player toward the grapple
|
||||
/*
|
||||
* pull the player toward the grapple
|
||||
*/
|
||||
void
|
||||
CTFGrapplePull(edict_t *self)
|
||||
|
@ -1812,10 +1812,10 @@ CTFGrapplePull(edict_t *self)
|
|||
|
||||
if (self->owner->client->ctf_grapplestate > CTF_GRAPPLE_STATE_FLY)
|
||||
{
|
||||
/* pull player toward grapple
|
||||
/* pull player toward grapple
|
||||
this causes icky stuff with prediction, we need to extend/
|
||||
the prediction layer to include two new fields in the player/
|
||||
move stuff: a point and a velocity. The client should add
|
||||
move stuff: a point and a velocity. The client should add
|
||||
that velociy in the direction of the point */
|
||||
vec3_t forward, up;
|
||||
|
||||
|
@ -2041,7 +2041,7 @@ CTFTeam_f(edict_t *ent)
|
|||
|
||||
/* add a teleportation effect */
|
||||
ent->s.event = EV_PLAYER_TELEPORT;
|
||||
|
||||
|
||||
/* hold in place briefly */
|
||||
ent->client->ps.pmove.pm_flags = PMF_TIME_TELEPORT;
|
||||
ent->client->ps.pmove.pm_time = 14;
|
||||
|
@ -2128,7 +2128,7 @@ CTFScoreboardMessage(edict_t *ent, edict_t *killer)
|
|||
total[team]++;
|
||||
}
|
||||
|
||||
/* print level name and exit rules
|
||||
/* print level name and exit rules
|
||||
add the clients in sorted order */
|
||||
*string = 0;
|
||||
len = 0;
|
||||
|
@ -2483,8 +2483,8 @@ SpawnTechs(edict_t *ent)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* frees the passed edict!
|
||||
/*
|
||||
* frees the passed edict!
|
||||
*/
|
||||
void
|
||||
CTFRespawnTech(edict_t *ent)
|
||||
|
@ -2764,10 +2764,10 @@ CTFHasRegeneration(edict_t *ent)
|
|||
* ======================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* This array is in 'importance order',
|
||||
* it indicates what items are more
|
||||
* important when reporting their names.
|
||||
* it indicates what items are more
|
||||
* important when reporting their names.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
|
@ -2876,7 +2876,7 @@ CTFSay_Team_Location(edict_t *who, char *buf)
|
|||
}
|
||||
|
||||
/* we now have the closest item
|
||||
see if there's more than one
|
||||
see if there's more than one
|
||||
in the map, if so we need to
|
||||
determine what team is closest */
|
||||
what = NULL;
|
||||
|
@ -2888,8 +2888,8 @@ CTFSay_Team_Location(edict_t *who, char *buf)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* if we are here, there is more
|
||||
than one, find out if hot is
|
||||
/* if we are here, there is more
|
||||
than one, find out if hot is
|
||||
closer to red flag or blue flag */
|
||||
if (((flag1 = G_Find(NULL, FOFS(classname), "item_flag_team1")) != NULL) &&
|
||||
((flag2 = G_Find(NULL, FOFS(classname), "item_flag_team2")) != NULL))
|
||||
|
@ -3969,7 +3969,7 @@ CTFJoinTeam(edict_t *ent, int desired_team)
|
|||
|
||||
/* add a teleportation effect */
|
||||
ent->s.event = EV_PLAYER_TELEPORT;
|
||||
|
||||
|
||||
/* hold in place briefly */
|
||||
ent->client->ps.pmove.pm_flags = PMF_TIME_TELEPORT;
|
||||
ent->client->ps.pmove.pm_time = 14;
|
||||
|
@ -4509,119 +4509,6 @@ CTFCheckRules(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* just here to help old map conversions
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
old_teleporter_touch(edict_t *self, edict_t *other, cplane_t *plane,
|
||||
csurface_t *surf)
|
||||
{
|
||||
edict_t *dest;
|
||||
int i;
|
||||
vec3_t forward;
|
||||
|
||||
if (!other->client)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dest = G_Find(NULL, FOFS(targetname), self->target);
|
||||
|
||||
if (!dest)
|
||||
{
|
||||
gi.dprintf("Couldn't find destination\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CTFPlayerResetGrapple(other);
|
||||
|
||||
/* unlink to make sure it can't possibly interfere with KillBox */
|
||||
gi.unlinkentity(other);
|
||||
|
||||
VectorCopy(dest->s.origin, other->s.origin);
|
||||
VectorCopy(dest->s.origin, other->s.old_origin);
|
||||
|
||||
/* clear the velocity and hold them in place briefly */
|
||||
VectorClear(other->velocity);
|
||||
other->client->ps.pmove.pm_time = 160 >> 3; /* hold time */
|
||||
other->client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT;
|
||||
|
||||
/* draw the teleport splash at source and on the player */
|
||||
self->enemy->s.event = EV_PLAYER_TELEPORT;
|
||||
other->s.event = EV_PLAYER_TELEPORT;
|
||||
|
||||
/* set angles */
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
other->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(
|
||||
dest->s.angles[i] - other->client->resp.cmd_angles[i]);
|
||||
}
|
||||
|
||||
other->s.angles[PITCH] = 0;
|
||||
other->s.angles[YAW] = dest->s.angles[YAW];
|
||||
other->s.angles[ROLL] = 0;
|
||||
VectorCopy(dest->s.angles, other->client->ps.viewangles);
|
||||
VectorCopy(dest->s.angles, other->client->v_angle);
|
||||
|
||||
/* give a little forward velocity */
|
||||
AngleVectors(other->client->v_angle, forward, NULL, NULL);
|
||||
VectorScale(forward, 200, other->velocity);
|
||||
|
||||
/* kill anything at the destination */
|
||||
if (!KillBox(other))
|
||||
{
|
||||
}
|
||||
|
||||
gi.linkentity(other);
|
||||
}
|
||||
|
||||
/*
|
||||
* QUAKED trigger_teleport (0.5 0.5 0.5) ?
|
||||
* Players touching this will be teleported
|
||||
*/
|
||||
void
|
||||
SP_trigger_teleport(edict_t *ent)
|
||||
{
|
||||
edict_t *s;
|
||||
int i;
|
||||
|
||||
if (!ent->target)
|
||||
{
|
||||
gi.dprintf("teleporter without a target.\n");
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
ent->svflags |= SVF_NOCLIENT;
|
||||
ent->solid = SOLID_TRIGGER;
|
||||
ent->touch = old_teleporter_touch;
|
||||
gi.setmodel(ent, ent->model);
|
||||
gi.linkentity(ent);
|
||||
|
||||
/* noise maker and splash effect dude */
|
||||
s = G_Spawn();
|
||||
ent->enemy = s;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
s->s.origin[i] = ent->mins[i] + (ent->maxs[i] - ent->mins[i]) / 2;
|
||||
}
|
||||
|
||||
s->s.sound = gi.soundindex("world/hum1.wav");
|
||||
gi.linkentity(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* QUAKED info_teleport_destination (0.5 0.5 0.5) (-16 -16 -24) (16 16 32)
|
||||
* Point trigger_teleports at these.
|
||||
*/
|
||||
void
|
||||
SP_info_teleport_destination(edict_t *ent)
|
||||
{
|
||||
ent->s.origin[2] += 16;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* ADMIN */
|
||||
|
|
@ -27,6 +27,14 @@
|
|||
|
||||
#include "../header/local.h"
|
||||
|
||||
/*
|
||||
* ======================================================================
|
||||
*
|
||||
* INTERMISSION
|
||||
*
|
||||
* ======================================================================
|
||||
*/
|
||||
|
||||
void
|
||||
MoveClientToIntermission(edict_t *ent)
|
||||
{
|
||||
|
@ -357,6 +365,18 @@ DeathmatchScoreboardMessage(edict_t *ent, edict_t *killer)
|
|||
gi.WriteString(string);
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw instead of help message.
|
||||
* Note that it isn't that hard to
|
||||
* overflow the 1400 byte message limit!
|
||||
*/
|
||||
void
|
||||
DeathmatchScoreboard(edict_t *ent)
|
||||
{
|
||||
DeathmatchScoreboardMessage(ent, ent->enemy);
|
||||
gi.unicast(ent, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw help computer.
|
||||
*/
|
||||
|
@ -407,6 +427,7 @@ HelpComputerMessage(edict_t *ent)
|
|||
|
||||
gi.WriteByte(svc_layout);
|
||||
gi.WriteString(string);
|
||||
gi.unicast(ent, true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -284,6 +284,8 @@ InitGame(void)
|
|||
{
|
||||
InitGameRules();
|
||||
}
|
||||
|
||||
CTFInit();
|
||||
}
|
||||
|
||||
/* ========================================================= */
|
||||
|
|
Loading…
Reference in a new issue