mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-10 07:12:07 +00:00
Merge generic parts of ctf/ with baseq2/. This should have any impact on
the baseq2/ source path.
This commit is contained in:
parent
0bd9096f7f
commit
56b41dd705
14 changed files with 881 additions and 6 deletions
|
@ -103,11 +103,24 @@ SelectNextItem(edict_t *ent, int itflags)
|
|||
|
||||
cl = ent->client;
|
||||
|
||||
#ifdef CTF
|
||||
if (cl->menu)
|
||||
{
|
||||
PMenu_Next(ent);
|
||||
return;
|
||||
}
|
||||
else if (cl->chase_target)
|
||||
{
|
||||
ChaseNext(ent);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (cl->chase_target)
|
||||
{
|
||||
ChaseNext(ent);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* scan for the next valid one */
|
||||
for (i = 1; i <= MAX_ITEMS; i++)
|
||||
|
@ -152,11 +165,24 @@ SelectPrevItem(edict_t *ent, int itflags)
|
|||
|
||||
cl = ent->client;
|
||||
|
||||
#ifdef CTF
|
||||
if (cl->menu)
|
||||
{
|
||||
PMenu_Prev(ent);
|
||||
return;
|
||||
}
|
||||
else if (cl->chase_target)
|
||||
{
|
||||
ChasePrev(ent);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (cl->chase_target)
|
||||
{
|
||||
ChasePrev(ent);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* scan for the next valid one */
|
||||
for (i = 1; i <= MAX_ITEMS; i++)
|
||||
|
@ -578,6 +604,16 @@ Cmd_Drop_f(edict_t *ent)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
/* Special case for the
|
||||
tech powerup */
|
||||
if (Q_stricmp(gi.args(), "tech") == 0 && (it = CTFWhat_Tech(ent)) != NULL)
|
||||
{
|
||||
it->drop (ent, it);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
s = gi.args();
|
||||
it = FindItem(s);
|
||||
|
||||
|
@ -620,12 +656,28 @@ Cmd_Inven_f(edict_t *ent)
|
|||
cl->showscores = false;
|
||||
cl->showhelp = false;
|
||||
|
||||
#ifdef CTF
|
||||
if (ent->client->menu)
|
||||
{
|
||||
PMenu_Close(ent);
|
||||
ent->client->update_chase = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cl->showinventory)
|
||||
{
|
||||
cl->showinventory = false;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
if (ctf->value && cl->resp.ctf_team == CTF_NOTEAM)
|
||||
{
|
||||
CTFOpenJoinMenu(ent);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
cl->showinventory = true;
|
||||
|
||||
gi.WriteByte(svc_inventory);
|
||||
|
@ -648,6 +700,14 @@ Cmd_InvUse_f(edict_t *ent)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
if (ent->client->menu)
|
||||
{
|
||||
PMenu_Select(ent);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
ValidateSelectedItem(ent);
|
||||
|
||||
if (ent->client->pers.selected_item == -1)
|
||||
|
@ -667,6 +727,30 @@ Cmd_InvUse_f(edict_t *ent)
|
|||
it->use(ent, it);
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
|
||||
void
|
||||
Cmd_LastWeap_f (edict_t *ent)
|
||||
{
|
||||
gclient_t *cl;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cl = ent->client;
|
||||
|
||||
if (!cl->pers.weapon || !cl->pers.lastweapon)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cl->pers.lastweapon->use (ent, cl->pers.lastweapon);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
Cmd_WeapPrev_f(edict_t *ent)
|
||||
{
|
||||
|
@ -851,6 +935,13 @@ Cmd_Kill_f(edict_t *ent)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
if (ent->solid == SOLID_NOT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (((level.time - ent->client->respawn_time) < 5) ||
|
||||
(ent->client->resp.spectator))
|
||||
{
|
||||
|
@ -874,6 +965,15 @@ Cmd_PutAway_f(edict_t *ent)
|
|||
ent->client->showscores = false;
|
||||
ent->client->showhelp = false;
|
||||
ent->client->showinventory = false;
|
||||
|
||||
#ifdef CTF
|
||||
if (ent->client->menu)
|
||||
{
|
||||
PMenu_Close(ent);
|
||||
}
|
||||
|
||||
ent->client->update_chase = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1319,6 +1419,60 @@ ClientCommand(edict_t *ent)
|
|||
{
|
||||
Cmd_PlayerList_f(ent);
|
||||
}
|
||||
#ifdef CTF
|
||||
else if (Q_stricmp (cmd, "team") == 0)
|
||||
{
|
||||
CTFTeam_f (ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "id") == 0)
|
||||
{
|
||||
CTFID_f (ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "yes") == 0)
|
||||
{
|
||||
CTFVoteYes(ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "no") == 0)
|
||||
{
|
||||
CTFVoteNo(ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "ready") == 0)
|
||||
{
|
||||
CTFReady(ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "notready") == 0)
|
||||
{
|
||||
CTFNotReady(ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "ghost") == 0)
|
||||
{
|
||||
CTFGhost(ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "admin") == 0)
|
||||
{
|
||||
CTFAdmin(ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "stats") == 0)
|
||||
{
|
||||
CTFStats(ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "warp") == 0)
|
||||
{
|
||||
CTFWarp(ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "boot") == 0)
|
||||
{
|
||||
CTFBoot(ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "playerlist") == 0)
|
||||
{
|
||||
CTFPlayerList(ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "observer") == 0)
|
||||
{
|
||||
CTFObserver(ent);
|
||||
}
|
||||
#endif
|
||||
else /* anything that doesn't match a command will be a chat */
|
||||
{
|
||||
Cmd_Say_f(ent, false, true);
|
||||
|
|
|
@ -506,6 +506,29 @@ M_ReactToDamage(edict_t *targ, edict_t *attacker)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
qboolean
|
||||
CheckTeamDamage (edict_t *targ, edict_t *attacker)
|
||||
{
|
||||
if (!targ || !attacker)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
if (ctf->value && targ->client && attacker->client)
|
||||
{
|
||||
if (targ->client->resp.ctf_team ==
|
||||
attacker->client->resp.ctf_team && targ != attacker)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker,
|
||||
vec3_t dir, vec3_t point, vec3_t normal, int damage,
|
||||
|
@ -581,6 +604,11 @@ T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker,
|
|||
damage *= 2;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
/* strength tech */
|
||||
damage = CTFApplyStrength(attacker, damage);
|
||||
#endif
|
||||
|
||||
if (targ->flags & FL_NO_KNOCKBACK)
|
||||
{
|
||||
knockback = 0;
|
||||
|
@ -646,21 +674,48 @@ T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker,
|
|||
save = damage;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
/* team armor protect */
|
||||
if (ctf->value && targ->client && attacker->client &&
|
||||
targ->client->resp.ctf_team == attacker->client->resp.ctf_team &&
|
||||
targ != attacker && ((int)dmflags->value & DF_ARMOR_PROTECT))
|
||||
{
|
||||
psave = asave = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
psave = CheckPowerArmor (targ, point, normal, take, dflags);
|
||||
take -= psave;
|
||||
|
||||
asave = CheckArmor (targ, point, normal, take, te_sparks, dflags);
|
||||
take -= asave;
|
||||
}
|
||||
#else
|
||||
psave = CheckPowerArmor(targ, point, normal, take, dflags);
|
||||
take -= psave;
|
||||
|
||||
asave = CheckArmor(targ, point, normal, take, te_sparks, dflags);
|
||||
take -= asave;
|
||||
#endif
|
||||
|
||||
/* treat cheat/powerup savings the same as armor */
|
||||
asave += save;
|
||||
|
||||
#ifdef CTF
|
||||
/* Resistance tech */
|
||||
take = CTFApplyResistance(targ, take);
|
||||
#endif
|
||||
|
||||
/* team damage avoidance */
|
||||
if ((dflags & DAMAGE_NO_PROTECTION))
|
||||
if (!(dflags & DAMAGE_NO_PROTECTION) && CheckTeamDamage (targ, attacker))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
CTFCheckHurtCarrier(targ, attacker);
|
||||
#endif
|
||||
|
||||
/* do the damage */
|
||||
if (take)
|
||||
{
|
||||
|
|
|
@ -147,6 +147,16 @@ DoRespawn(edict_t *ent)
|
|||
|
||||
master = ent->teammaster;
|
||||
|
||||
#ifdef CTF
|
||||
/* in ctf, when we are weapons stay, only the
|
||||
master of a team of weapons is spawned */
|
||||
if (ctf->value && ((int)dmflags->value & DF_WEAPONS_STAY) &&
|
||||
master->item && (master->item->flags & IT_WEAPON))
|
||||
{
|
||||
ent = master;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (count = 0, ent = master; ent; ent = ent->chain, count++)
|
||||
{
|
||||
}
|
||||
|
@ -157,6 +167,18 @@ DoRespawn(edict_t *ent)
|
|||
{
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (count = 0, ent = master; ent; ent = ent->chain, count++)
|
||||
{
|
||||
}
|
||||
|
||||
choice = rand() % count;
|
||||
|
||||
for (count = 0, ent = master; count < choice; ent = ent->chain, count++)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ent->svflags &= ~SVF_NOCLIENT;
|
||||
ent->solid = SOLID_TRIGGER;
|
||||
|
@ -824,7 +846,11 @@ MegaHealth_think(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
if (self->owner->health > self->owner->max_health)
|
||||
if (self->owner->health > self->owner->max_health
|
||||
#ifdef CTF
|
||||
&& !CTFHasRegeneration(self->owner)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
self->nextthink = level.time + 1;
|
||||
self->owner->health -= 1;
|
||||
|
@ -857,8 +883,22 @@ Pickup_Health(edict_t *ent, edict_t *other)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
if (other->health >= 250 && ent->count > 25)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
other->health += ent->count;
|
||||
|
||||
#ifdef CTF
|
||||
if (other->health > 250 && ent->count > 25)
|
||||
{
|
||||
other->health = 250;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(ent->style & HEALTH_IGNORE_MAX))
|
||||
{
|
||||
if (other->health > other->max_health)
|
||||
|
@ -867,7 +907,11 @@ Pickup_Health(edict_t *ent, edict_t *other)
|
|||
}
|
||||
}
|
||||
|
||||
if (ent->style & HEALTH_TIMED)
|
||||
if ((ent->style & HEALTH_TIMED)
|
||||
#ifdef CTF
|
||||
&& !CTFHasRegeneration(other)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
ent->think = MegaHealth_think;
|
||||
ent->nextthink = level.time + 5;
|
||||
|
@ -1641,6 +1685,16 @@ SpawnItem(edict_t *ent, gitem_t *item)
|
|||
item->drop = NULL;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
/* Don't spawn the flags unless enabled */
|
||||
if (!ctf->value && (strcmp(ent->classname, "item_flag_team1") == 0 ||
|
||||
strcmp(ent->classname, "item_flag_team2") == 0))
|
||||
{
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
ent->item = item;
|
||||
ent->nextthink = level.time + 2 * FRAMETIME; /* items start after other solids */
|
||||
ent->think = droptofloor;
|
||||
|
@ -1651,6 +1705,15 @@ SpawnItem(edict_t *ent, gitem_t *item)
|
|||
{
|
||||
gi.modelindex(ent->model);
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
/* flags are server animated */
|
||||
if (strcmp(ent->classname, "item_flag_team1") == 0 ||
|
||||
strcmp(ent->classname, "item_flag_team2") == 0)
|
||||
{
|
||||
ent->think = CTFFlagSetup;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ====================================================================== */
|
||||
|
@ -2572,6 +2635,140 @@ gitem_t itemlist[] = {
|
|||
"items/s_health.wav items/n_health.wav items/l_health.wav items/m_health.wav"
|
||||
},
|
||||
|
||||
#ifdef CTF
|
||||
/* QUAKED item_flag_team1 (1 0.2 0) (-16 -16 -24) (16 16 32) */
|
||||
{
|
||||
"item_flag_team1",
|
||||
CTFPickup_Flag,
|
||||
NULL,
|
||||
CTFDrop_Flag,
|
||||
NULL,
|
||||
"ctf/flagtk.wav",
|
||||
"players/male/flag1.md2", EF_FLAG1,
|
||||
NULL,
|
||||
"i_ctf1",
|
||||
"Red Flag",
|
||||
2,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
"ctf/flagcap.wav"
|
||||
},
|
||||
|
||||
/* QUAKED item_flag_team2 (1 0.2 0) (-16 -16 -24) (16 16 32) */
|
||||
{
|
||||
"item_flag_team2",
|
||||
CTFPickup_Flag,
|
||||
NULL,
|
||||
CTFDrop_Flag,
|
||||
NULL,
|
||||
"ctf/flagtk.wav",
|
||||
"players/male/flag2.md2", EF_FLAG2,
|
||||
NULL,
|
||||
"i_ctf2",
|
||||
"Blue Flag",
|
||||
2,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
"ctf/flagcap.wav"
|
||||
},
|
||||
|
||||
/* Resistance Tech */
|
||||
{
|
||||
"item_tech1",
|
||||
CTFPickup_Tech,
|
||||
NULL,
|
||||
CTFDrop_Tech,
|
||||
NULL,
|
||||
"items/pkup.wav",
|
||||
"models/ctf/resistance/tris.md2", EF_ROTATE,
|
||||
NULL,
|
||||
"tech1",
|
||||
"Disruptor Shield",
|
||||
2,
|
||||
0,
|
||||
NULL,
|
||||
IT_TECH,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
"ctf/tech1.wav"
|
||||
},
|
||||
|
||||
/* Strength Tech */
|
||||
{
|
||||
"item_tech2",
|
||||
CTFPickup_Tech,
|
||||
NULL,
|
||||
CTFDrop_Tech,
|
||||
NULL,
|
||||
"items/pkup.wav",
|
||||
"models/ctf/strength/tris.md2", EF_ROTATE,
|
||||
NULL,
|
||||
"tech2",
|
||||
"Power Amplifier",
|
||||
2,
|
||||
0,
|
||||
NULL,
|
||||
IT_TECH,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
"ctf/tech2.wav ctf/tech2x.wav"
|
||||
},
|
||||
|
||||
/* Haste Tech */
|
||||
{
|
||||
"item_tech3",
|
||||
CTFPickup_Tech,
|
||||
NULL,
|
||||
CTFDrop_Tech,
|
||||
NULL,
|
||||
"items/pkup.wav",
|
||||
"models/ctf/haste/tris.md2", EF_ROTATE,
|
||||
NULL,
|
||||
"tech3",
|
||||
"Time Accel",
|
||||
2,
|
||||
0,
|
||||
NULL,
|
||||
IT_TECH,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
"ctf/tech3.wav"
|
||||
},
|
||||
|
||||
/* Regeneration Tech */
|
||||
{
|
||||
"item_tech4",
|
||||
CTFPickup_Tech,
|
||||
NULL,
|
||||
CTFDrop_Tech,
|
||||
NULL,
|
||||
"items/pkup.wav",
|
||||
"models/ctf/regeneration/tris.md2", EF_ROTATE,
|
||||
NULL,
|
||||
"tech4",
|
||||
"AutoDoc",
|
||||
2,
|
||||
0,
|
||||
NULL,
|
||||
IT_TECH,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
"ctf/tech4.wav"
|
||||
},
|
||||
#endif
|
||||
|
||||
/* end of list marker */
|
||||
{NULL}
|
||||
};
|
||||
|
|
|
@ -32,8 +32,16 @@
|
|||
#define GAME_INCLUDE
|
||||
#include "game.h"
|
||||
|
||||
#ifdef CTF
|
||||
#include "p_menu.h"
|
||||
#endif
|
||||
|
||||
/* the "gameversion" client command will print this plus compile date */
|
||||
#define GAMEVERSION "baseq2"
|
||||
#ifdef CTF
|
||||
#define GAMEVERSION "ctf"
|
||||
#else
|
||||
#define GAMEVERSION "baseq2"
|
||||
#endif
|
||||
|
||||
/* protocol bytes that can be directly added to messages */
|
||||
#define svc_muzzleflash 1
|
||||
|
@ -208,6 +216,9 @@ typedef struct
|
|||
#define IT_STAY_COOP 8
|
||||
#define IT_KEY 16
|
||||
#define IT_POWERUP 32
|
||||
#ifdef CTF
|
||||
#define IT_TECH 64
|
||||
#endif
|
||||
|
||||
/* gitem_t->weapmodel for weapons indicates model index */
|
||||
#define WEAP_BLASTER 1
|
||||
|
@ -221,6 +232,9 @@ typedef struct
|
|||
#define WEAP_HYPERBLASTER 9
|
||||
#define WEAP_RAILGUN 10
|
||||
#define WEAP_BFG 11
|
||||
#ifdef CTF
|
||||
#define WEAP_GRAPPLE 12
|
||||
#endif
|
||||
|
||||
typedef struct gitem_s
|
||||
{
|
||||
|
@ -494,6 +508,12 @@ extern cvar_t *dmflags;
|
|||
extern cvar_t *skill;
|
||||
extern cvar_t *fraglimit;
|
||||
extern cvar_t *timelimit;
|
||||
|
||||
#ifdef CTF
|
||||
extern cvar_t *capturelimit;
|
||||
extern cvar_t *instantweap;
|
||||
#endif
|
||||
|
||||
extern cvar_t *password;
|
||||
extern cvar_t *spectator_password;
|
||||
extern cvar_t *needpass;
|
||||
|
@ -828,6 +848,22 @@ typedef struct
|
|||
client_persistant_t coop_respawn; /* what to set client->pers to on a respawn */
|
||||
int enterframe; /* level.framenum the client entered the game */
|
||||
int score; /* frags, etc */
|
||||
|
||||
#ifdef CTF
|
||||
int ctf_team; /*CTF team */
|
||||
int ctf_state;
|
||||
float ctf_lasthurtcarrier;
|
||||
float ctf_lastreturnedflag;
|
||||
float ctf_flagsince;
|
||||
float ctf_lastfraggedcarrier;
|
||||
qboolean id_state;
|
||||
float lastidtime;
|
||||
qboolean voted; /* for elections */
|
||||
qboolean ready;
|
||||
qboolean admin;
|
||||
struct ghost_s *ghost;
|
||||
#endif
|
||||
|
||||
vec3_t cmd_angles; /* angles sent over in the last command */
|
||||
|
||||
qboolean spectator; /* client is a spectator */
|
||||
|
@ -847,6 +883,11 @@ struct gclient_s
|
|||
pmove_state_t old_pmove; /* for detecting out-of-pmove changes */
|
||||
|
||||
qboolean showscores; /* set layout stat */
|
||||
|
||||
#ifdef CTF
|
||||
qboolean inmenu; /* in menu */
|
||||
pmenuhnd_t *menu; /* current menu */
|
||||
#endif
|
||||
qboolean showinventory; /* set layout stat */
|
||||
qboolean showhelp;
|
||||
qboolean showhelpicon;
|
||||
|
@ -915,6 +956,19 @@ struct gclient_s
|
|||
|
||||
float respawn_time; /* can respawn when time > this */
|
||||
|
||||
#ifdef CTF
|
||||
void *ctf_grapple; /* entity of grapple */
|
||||
int ctf_grapplestate; /* true if pulling */
|
||||
float ctf_grapplereleasetime; /* time of grapple release */
|
||||
float ctf_regentime; /* regen tech */
|
||||
float ctf_techsndtime;
|
||||
float ctf_lasttechmsg;
|
||||
edict_t *chase_target;
|
||||
qboolean update_chase;
|
||||
float menutime; /* time to update menu */
|
||||
qboolean menudirty;
|
||||
#endif
|
||||
|
||||
edict_t *chase_target; /* player we are chasing */
|
||||
qboolean update_chase; /* need to update chase info? */
|
||||
};
|
||||
|
@ -1066,3 +1120,7 @@ struct edict_s
|
|||
monsterinfo_t monsterinfo;
|
||||
};
|
||||
|
||||
#ifdef CTF
|
||||
#include "g_ctf.h"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -44,6 +44,12 @@ cvar_t *dmflags;
|
|||
cvar_t *skill;
|
||||
cvar_t *fraglimit;
|
||||
cvar_t *timelimit;
|
||||
|
||||
#ifdef CTF
|
||||
cvar_t *capturelimit;
|
||||
cvar_t *instantweap;
|
||||
#endif
|
||||
|
||||
cvar_t *password;
|
||||
cvar_t *spectator_password;
|
||||
cvar_t *needpass;
|
||||
|
@ -336,6 +342,19 @@ CheckDMRules(void)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
if (ctf->value && CTFCheckRules())
|
||||
{
|
||||
EndDMLevel ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (CTFInMatch())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (timelimit->value)
|
||||
{
|
||||
if (level.time >= timelimit->value * 60)
|
||||
|
|
|
@ -421,6 +421,32 @@ BecomeExplosion1(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
/* Flags are important! */
|
||||
if (strcmp(self->classname, "item_flag_team1") == 0)
|
||||
{
|
||||
CTFResetFlag(CTF_TEAM1);
|
||||
gi.bprintf(PRINT_HIGH, "The %s flag has returned!\n",
|
||||
CTFTeamName(CTF_TEAM1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(self->classname, "item_flag_team2") == 0)
|
||||
{
|
||||
CTFResetFlag(CTF_TEAM2);
|
||||
gi.bprintf(PRINT_HIGH, "The %s flag has returned!\n",
|
||||
CTFTeamName(CTF_TEAM1));
|
||||
return;
|
||||
}
|
||||
|
||||
/* techs are important too */
|
||||
if (self->item && (self->item->flags & IT_TECH))
|
||||
{
|
||||
CTFRespawnTech(self);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(TE_EXPLOSION1);
|
||||
gi.WritePosition(self->s.origin);
|
||||
|
@ -2584,6 +2610,10 @@ teleporter_touch(edict_t *self, edict_t *other, cplane_t *plane /* unused */,
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
CTFPlayerResetGrapple(other);
|
||||
#endif
|
||||
|
||||
/* unlink to make sure it can't possibly interfere with KillBox */
|
||||
gi.unlinkentity(other);
|
||||
|
||||
|
|
|
@ -160,6 +160,11 @@ spawn_t spawns[] = {
|
|||
{"info_player_coop", SP_info_player_coop},
|
||||
{"info_player_intermission", SP_info_player_intermission},
|
||||
|
||||
#ifdef CTF
|
||||
{"info_player_team1", SP_info_player_team1},
|
||||
{"info_player_team2", SP_info_player_team2},
|
||||
#endif
|
||||
|
||||
{"func_plat", SP_func_plat},
|
||||
{"func_button", SP_func_button},
|
||||
{"func_door", SP_func_door},
|
||||
|
@ -222,6 +227,10 @@ spawn_t spawns[] = {
|
|||
|
||||
{"misc_explobox", SP_misc_explobox},
|
||||
{"misc_banner", SP_misc_banner},
|
||||
#ifdef CTF
|
||||
{"misc_ctf_banner", SP_misc_ctf_banner},
|
||||
{"misc_ctf_small_banner", SP_misc_ctf_small_banner},
|
||||
#endif
|
||||
{"misc_satellite_dish", SP_misc_satellite_dish},
|
||||
{"misc_actor", SP_misc_actor},
|
||||
{"misc_gib_arm", SP_misc_gib_arm},
|
||||
|
@ -235,11 +244,16 @@ spawn_t spawns[] = {
|
|||
{"misc_strogg_ship", SP_misc_strogg_ship},
|
||||
{"misc_teleporter", SP_misc_teleporter},
|
||||
{"misc_teleporter_dest", SP_misc_teleporter_dest},
|
||||
#ifdef CTF
|
||||
{"trigger_teleport", SP_trigger_teleport},
|
||||
{"info_teleport_destination", SP_info_teleport_destination},
|
||||
#endif
|
||||
{"misc_blackhole", SP_misc_blackhole},
|
||||
{"misc_eastertank", SP_misc_eastertank},
|
||||
{"misc_easterchick", SP_misc_easterchick},
|
||||
{"misc_easterchick2", SP_misc_easterchick2},
|
||||
|
||||
#ifndef CTF
|
||||
{"monster_berserk", SP_monster_berserk},
|
||||
{"monster_gladiator", SP_monster_gladiator},
|
||||
{"monster_gunner", SP_monster_gunner},
|
||||
|
@ -268,6 +282,7 @@ spawn_t spawns[] = {
|
|||
{"turret_breach", SP_turret_breach},
|
||||
{"turret_base", SP_turret_base},
|
||||
{"turret_driver", SP_turret_driver},
|
||||
#endif
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -707,6 +722,10 @@ SpawnEntities(const char *mapname, char *entities, const char *spawnpoint)
|
|||
G_FindTeams();
|
||||
|
||||
PlayerTrail_Init();
|
||||
|
||||
#ifdef CTF
|
||||
CTFSpawn();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* =================================================================== */
|
||||
|
@ -917,7 +936,19 @@ SP_worldspawn(edict_t *ent)
|
|||
/* status bar program */
|
||||
if (deathmatch->value)
|
||||
{
|
||||
#ifdef CTF
|
||||
if (ctf->value)
|
||||
{
|
||||
gi.configstring (CS_STATUSBAR, ctf_statusbar);
|
||||
CTFPrecache();
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.configstring (CS_STATUSBAR, dm_statusbar);
|
||||
}
|
||||
#else
|
||||
gi.configstring(CS_STATUSBAR, dm_statusbar);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1103,6 +1103,16 @@ bfg_think(edict_t *self)
|
|||
continue;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
/* Don't target players in CTF */
|
||||
if (ctf->value && ent->client &&
|
||||
self->owner->client &&
|
||||
ent->client->resp.ctf_team == self->owner->client->resp.ctf_team)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
VectorMA(ent->absmin, 0.5, ent->size, point);
|
||||
|
||||
VectorSubtract(point, self->s.origin, dir);
|
||||
|
|
|
@ -40,6 +40,10 @@
|
|||
#define SVF_DEADMONSTER 0x00000002 /* treat as CONTENTS_DEADMONSTER for collision */
|
||||
#define SVF_MONSTER 0x00000004 /* treat as CONTENTS_MONSTER for collision */
|
||||
|
||||
#ifdef CTF
|
||||
#define SVF_PROJECTILE 0x00000008
|
||||
#endif
|
||||
|
||||
#define MAX_ENT_CLUSTERS 16
|
||||
|
||||
typedef enum
|
||||
|
|
|
@ -520,6 +520,12 @@ ClientObituary(edict_t *self, edict_t *inflictor /* unused */,
|
|||
message = "tried to invade";
|
||||
message2 = "'s personal space";
|
||||
break;
|
||||
#ifdef CTF
|
||||
case MOD_GRAPPLE:
|
||||
message = "was caught by";
|
||||
message2 = "'s grapple";
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (message)
|
||||
|
@ -691,6 +697,10 @@ player_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
|
|||
|
||||
self->s.modelindex2 = 0; /* remove linked weapon model */
|
||||
|
||||
#ifdef CTF
|
||||
self->s.modelindex3 = 0;
|
||||
#endif
|
||||
|
||||
self->s.angles[0] = 0;
|
||||
self->s.angles[2] = 0;
|
||||
|
||||
|
@ -707,8 +717,28 @@ player_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
|
|||
LookAtKiller(self, inflictor, attacker);
|
||||
self->client->ps.pmove.pm_type = PM_DEAD;
|
||||
ClientObituary(self, inflictor, attacker);
|
||||
|
||||
#ifdef CTF
|
||||
/* if at start and same team, clear */
|
||||
if (ctf->value && meansOfDeath == MOD_TELEFRAG &&
|
||||
self->client->resp.ctf_state < 2 &&
|
||||
self->client->resp.ctf_team == attacker->client->resp.ctf_team)
|
||||
{
|
||||
attacker->client->resp.score--;
|
||||
self->client->resp.ctf_state = 0;
|
||||
}
|
||||
|
||||
CTFFragBonuses(self, inflictor, attacker);
|
||||
#endif
|
||||
|
||||
TossClientWeapon(self);
|
||||
|
||||
#ifdef CTF
|
||||
CTFPlayerResetGrapple(self);
|
||||
CTFDeadDropFlag(self);
|
||||
CTFDeadDropTech(self);
|
||||
#endif
|
||||
|
||||
if (deathmatch->value)
|
||||
{
|
||||
Cmd_Help_f(self); /* show scores */
|
||||
|
@ -749,6 +779,11 @@ player_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
|
|||
|
||||
ThrowClientHead(self, damage);
|
||||
|
||||
#ifdef CTF
|
||||
self->client->anim_priority = ANIM_DEATH;
|
||||
self->client->anim_end = 0;
|
||||
#endif
|
||||
|
||||
self->takedamage = DAMAGE_NO;
|
||||
}
|
||||
else
|
||||
|
@ -822,6 +857,13 @@ InitClientPersistant(gclient_t *client)
|
|||
|
||||
client->pers.weapon = item;
|
||||
|
||||
#ifdef CTF
|
||||
client->pers.lastweapon = item;
|
||||
|
||||
item = FindItem("Grapple");
|
||||
client->pers.inventory[ITEM_INDEX(item)] = 1;
|
||||
#endif
|
||||
|
||||
client->pers.health = 100;
|
||||
client->pers.max_health = 100;
|
||||
|
||||
|
@ -843,9 +885,27 @@ InitClientResp(gclient_t *client)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
int ctf_team = client->resp.ctf_team;
|
||||
qboolean id_state = client->resp.id_state;
|
||||
#endif
|
||||
|
||||
memset(&client->resp, 0, sizeof(client->resp));
|
||||
|
||||
#ifdef CTF
|
||||
client->resp.ctf_team = ctf_team;
|
||||
client->resp.id_state = id_state;
|
||||
#endif
|
||||
|
||||
client->resp.enterframe = level.framenum;
|
||||
client->resp.coop_respawn = client->pers;
|
||||
|
||||
#ifdef CTF
|
||||
if (ctf->value && client->resp.ctf_team < CTF_TEAM1)
|
||||
{
|
||||
CTFAssignTeam(client);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1139,7 +1199,18 @@ SelectSpawnPoint(edict_t *ent, vec3_t origin, vec3_t angles)
|
|||
|
||||
if (deathmatch->value)
|
||||
{
|
||||
#ifdef CTF
|
||||
if (ctf->value)
|
||||
{
|
||||
spot = SelectCTFSpawnPoint(ent);
|
||||
}
|
||||
else
|
||||
{
|
||||
spot = SelectDeathmatchSpawnPoint ();
|
||||
}
|
||||
#else
|
||||
spot = SelectDeathmatchSpawnPoint();
|
||||
#endif
|
||||
}
|
||||
else if (coop->value)
|
||||
{
|
||||
|
@ -1523,6 +1594,10 @@ PutClientInServer(edict_t *ent)
|
|||
client->ps.pmove.origin[1] = spawn_origin[1] * 8;
|
||||
client->ps.pmove.origin[2] = spawn_origin[2] * 8;
|
||||
|
||||
#ifdef CTF
|
||||
client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION;
|
||||
#endif
|
||||
|
||||
if (deathmatch->value && ((int)dmflags->value & DF_FIXED_FOV))
|
||||
{
|
||||
client->ps.fov = 90;
|
||||
|
@ -1589,6 +1664,13 @@ PutClientInServer(edict_t *ent)
|
|||
client->resp.spectator = false;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
if (CTFStartClient(ent))
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!KillBox(ent))
|
||||
{
|
||||
/* could't spawn in? */
|
||||
|
@ -1755,8 +1837,23 @@ ClientUserinfoChanged(edict_t *ent, char *userinfo)
|
|||
playernum = ent - g_edicts - 1;
|
||||
|
||||
/* combine name and skin into a configstring */
|
||||
#ifdef CTF
|
||||
if (ctf->value)
|
||||
{
|
||||
CTFAssignSkin(ent, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.configstring (CS_PLAYERSKINS+playernum,
|
||||
va("%s\\%s", ent->client->pers.netname, s) );
|
||||
|
||||
}
|
||||
/* set player name field (used in id_state view) */
|
||||
gi.configstring (CS_GENERAL+playernum, ent->client->pers.netname);
|
||||
#else
|
||||
gi.configstring(CS_PLAYERSKINS + playernum,
|
||||
va("%s\\%s", ent->client->pers.netname, s));
|
||||
#endif
|
||||
|
||||
/* fov */
|
||||
if (deathmatch->value && ((int)dmflags->value & DF_FIXED_FOV))
|
||||
|
@ -1870,6 +1967,12 @@ ClientConnect(edict_t *ent, char *userinfo)
|
|||
if (ent->inuse == false)
|
||||
{
|
||||
/* clear the respawning variables */
|
||||
#ifdef CTF
|
||||
/* Force team join */
|
||||
ent->client->resp.ctf_team = -1;
|
||||
ent->client->resp.id_state = true;
|
||||
#endif
|
||||
|
||||
InitClientResp(ent->client);
|
||||
|
||||
if (!game.autosaved || !ent->client->pers.weapon)
|
||||
|
@ -1911,6 +2014,11 @@ ClientDisconnect(edict_t *ent)
|
|||
|
||||
gi.bprintf(PRINT_HIGH, "%s disconnected\n", ent->client->pers.netname);
|
||||
|
||||
#ifdef CTF
|
||||
CTFDeadDropFlag(ent);
|
||||
CTFDeadDropTech(ent);
|
||||
#endif
|
||||
|
||||
/* send effect */
|
||||
gi.WriteByte(svc_muzzleflash);
|
||||
gi.WriteShort(ent - g_edicts);
|
||||
|
@ -2117,6 +2225,13 @@ ClientThink(edict_t *ent, usercmd_t *ucmd)
|
|||
VectorCopy(pm.viewangles, client->ps.viewangles);
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
if (client->ctf_grapple)
|
||||
{
|
||||
CTFGrapplePull(client->ctf_grapple);
|
||||
}
|
||||
#endif
|
||||
|
||||
gi.linkentity(ent);
|
||||
|
||||
if (ent->movetype != MOVETYPE_NOCLIP)
|
||||
|
@ -2160,7 +2275,11 @@ ClientThink(edict_t *ent, usercmd_t *ucmd)
|
|||
ent->light_level = ucmd->lightlevel;
|
||||
|
||||
/* fire weapon from final position if needed */
|
||||
if (client->latched_buttons & BUTTON_ATTACK)
|
||||
if (client->latched_buttons & BUTTON_ATTACK
|
||||
#ifdef CTF
|
||||
&& ent->movetype != MOVETYPE_NOCLIP
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (client->resp.spectator)
|
||||
{
|
||||
|
@ -2183,6 +2302,29 @@ ClientThink(edict_t *ent, usercmd_t *ucmd)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
/* Regen tech */
|
||||
CTFApplyRegeneration(ent);
|
||||
|
||||
for (i = 1; i <= maxclients->value; i++)
|
||||
{
|
||||
other = g_edicts + i;
|
||||
|
||||
if (other->inuse && other->client->chase_target == ent)
|
||||
{
|
||||
UpdateChaseCam(other);
|
||||
}
|
||||
}
|
||||
|
||||
if (client->menudirty && client->menutime <= level.time)
|
||||
{
|
||||
PMenu_Do_Update(ent);
|
||||
gi.unicast (ent, true);
|
||||
client->menutime = level.time;
|
||||
client->menudirty = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (client->resp.spectator)
|
||||
{
|
||||
if (ucmd->upmove >= 10)
|
||||
|
@ -2251,7 +2393,11 @@ ClientBeginServerFrame(edict_t *ent)
|
|||
}
|
||||
|
||||
/* run weapon animations if it hasn't been done by a ucmd_t */
|
||||
if (!client->weapon_thunk && !client->resp.spectator)
|
||||
if (!client->weapon_thunk && !client->resp.spectator
|
||||
#ifdef CTF
|
||||
&& ent->movetype != MOVETYPE_NOCLIP
|
||||
#endif
|
||||
)
|
||||
{
|
||||
Think_Weapon(ent);
|
||||
}
|
||||
|
|
|
@ -90,6 +90,13 @@ BeginIntermission(edict_t *targ)
|
|||
return; /* already activated */
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
if (deathmatch->value && ctf->value)
|
||||
{
|
||||
CTFCalcScores();
|
||||
}
|
||||
#endif
|
||||
|
||||
game.autosaved = false;
|
||||
|
||||
/* respawn any dead clients */
|
||||
|
@ -213,6 +220,14 @@ DeathmatchScoreboardMessage(edict_t *ent, edict_t *killer)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
if (ctf->value)
|
||||
{
|
||||
CTFScoreboardMessage (ent, killer);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* sort the clients by score */
|
||||
total = 0;
|
||||
|
||||
|
@ -346,6 +361,13 @@ Cmd_Score_f(edict_t *ent)
|
|||
ent->client->showinventory = false;
|
||||
ent->client->showhelp = false;
|
||||
|
||||
#ifdef CTF
|
||||
if (ent->client->menu)
|
||||
{
|
||||
PMenu_Close(ent);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!deathmatch->value && !coop->value)
|
||||
{
|
||||
return;
|
||||
|
@ -698,5 +720,9 @@ G_SetSpectatorStats(edict_t *ent)
|
|||
{
|
||||
cl->ps.stats[STAT_CHASE] = 0;
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
SetCTFStats(ent);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -670,6 +670,16 @@ P_FallingDamage(edict_t *ent)
|
|||
|
||||
delta = delta * delta * 0.0001;
|
||||
|
||||
#ifdef CTF
|
||||
/* never take damage if just release grapple or on grapple */
|
||||
if (level.time - ent->client->ctf_grapplereleasetime <= FRAMETIME * 2 ||
|
||||
(ent->client->ctf_grapple &&
|
||||
ent->client->ctf_grapplestate > CTF_GRAPPLE_STATE_FLY))
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* never take falling damage if completely underwater */
|
||||
if (ent->waterlevel == 3)
|
||||
{
|
||||
|
@ -985,6 +995,10 @@ G_SetClientEffects(edict_t *ent)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
CTFEffects(ent);
|
||||
#endif
|
||||
|
||||
if (ent->client->quad_framenum > level.framenum)
|
||||
{
|
||||
remaining = ent->client->quad_framenum - level.framenum;
|
||||
|
@ -1185,6 +1199,23 @@ newanim:
|
|||
|
||||
if (!ent->groundentity)
|
||||
{
|
||||
#ifdef CTF
|
||||
if (client->ctf_grapple)
|
||||
{
|
||||
ent->s.frame = FRAME_stand01;
|
||||
client->anim_end = FRAME_stand40;
|
||||
}
|
||||
else
|
||||
{
|
||||
client->anim_priority = ANIM_JUMP;
|
||||
|
||||
if (ent->s.frame != FRAME_jump2)
|
||||
{
|
||||
ent->s.frame = FRAME_jump1;
|
||||
}
|
||||
client->anim_end = FRAME_jump2;
|
||||
}
|
||||
#else
|
||||
client->anim_priority = ANIM_JUMP;
|
||||
|
||||
if (ent->s.frame != FRAME_jump2)
|
||||
|
@ -1193,6 +1224,7 @@ newanim:
|
|||
}
|
||||
|
||||
client->anim_end = FRAME_jump2;
|
||||
#endif
|
||||
}
|
||||
else if (run)
|
||||
{
|
||||
|
@ -1338,6 +1370,28 @@ ClientEndServerFrame(edict_t *ent)
|
|||
can be accurately determined */
|
||||
SV_CalcBlend(ent);
|
||||
|
||||
#ifdef CTF
|
||||
if (!ent->client->chase_target)
|
||||
{
|
||||
G_SetStats (ent);
|
||||
}
|
||||
|
||||
/* update chasecam follower stats */
|
||||
for (i = 1; i <= maxclients->value; i++)
|
||||
{
|
||||
edict_t *e = g_edicts + i;
|
||||
|
||||
if (!e->inuse || e->client->chase_target != ent)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(e->client->ps.stats, ent->client->ps.stats,
|
||||
sizeof(ent->client->ps.stats));
|
||||
e->client->ps.stats[STAT_LAYOUTS] = 1;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
/* chase cam stuff */
|
||||
if (ent->client->resp.spectator)
|
||||
{
|
||||
|
@ -1350,6 +1404,8 @@ ClientEndServerFrame(edict_t *ent)
|
|||
|
||||
G_CheckChaseStats(ent);
|
||||
|
||||
#endif
|
||||
|
||||
G_SetClientEvent(ent);
|
||||
|
||||
G_SetClientEffects(ent);
|
||||
|
@ -1368,7 +1424,20 @@ ClientEndServerFrame(edict_t *ent)
|
|||
/* if the scoreboard is up, update it */
|
||||
if (ent->client->showscores && !(level.framenum & 31))
|
||||
{
|
||||
#ifdef CTF
|
||||
if (ent->client->menu)
|
||||
{
|
||||
PMenu_Do_Update(ent);
|
||||
ent->client->menudirty = false;
|
||||
ent->client->menutime = level.time;
|
||||
}
|
||||
else
|
||||
{
|
||||
DeathmatchScoreboardMessage (ent, ent->enemy);
|
||||
}
|
||||
#else
|
||||
DeathmatchScoreboardMessage(ent, ent->enemy);
|
||||
#endif
|
||||
gi.unicast(ent, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -451,10 +451,17 @@ Drop_Weapon(edict_t *ent, gitem_t *item)
|
|||
* A generic function to handle
|
||||
* the basics of weapon thinking
|
||||
*/
|
||||
#ifdef CTF
|
||||
void
|
||||
Weapon_Generic2(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST,
|
||||
int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames,
|
||||
int *fire_frames, void (*fire)(edict_t *ent))
|
||||
#else
|
||||
void
|
||||
Weapon_Generic(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST,
|
||||
int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames,
|
||||
int *fire_frames, void (*fire)(edict_t *ent))
|
||||
#endif
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -605,11 +612,23 @@ Weapon_Generic(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST,
|
|||
{
|
||||
if (ent->client->ps.gunframe == fire_frames[n])
|
||||
{
|
||||
#ifdef CTF
|
||||
if (!CTFApplyStrengthSound(ent))
|
||||
{
|
||||
if (ent->client->quad_framenum > level.framenum)
|
||||
{
|
||||
gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage3.wav"), 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
CTFApplyHasteSound(ent);
|
||||
#else
|
||||
if (ent->client->quad_framenum > level.framenum)
|
||||
{
|
||||
gi.sound(ent, CHAN_ITEM, gi.soundindex(
|
||||
"items/damage3.wav"), 1, ATTN_NORM, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
fire(ent);
|
||||
break;
|
||||
|
@ -628,6 +647,39 @@ Weapon_Generic(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CTF
|
||||
void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST,
|
||||
int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames,
|
||||
int *fire_frames, void (*fire)(edict_t *ent))
|
||||
{
|
||||
int oldstate = ent->client->weaponstate;
|
||||
|
||||
if (!ent || !fire_frames || !fire)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Weapon_Generic2 (ent, FRAME_ACTIVATE_LAST, FRAME_FIRE_LAST,
|
||||
FRAME_IDLE_LAST, FRAME_DEACTIVATE_LAST, pause_frames,
|
||||
fire_frames, fire);
|
||||
|
||||
/* run the weapon frame again if hasted */
|
||||
if (Q_stricmp(ent->client->pers.weapon->pickup_name, "Grapple") == 0 &&
|
||||
ent->client->weaponstate == WEAPON_FIRING)
|
||||
return;
|
||||
|
||||
if ((CTFApplyHaste(ent) ||
|
||||
(Q_stricmp(ent->client->pers.weapon->pickup_name, "Grapple") == 0 &&
|
||||
ent->client->weaponstate != WEAPON_FIRING))
|
||||
&& oldstate == ent->client->weaponstate)
|
||||
{
|
||||
Weapon_Generic2 (ent, FRAME_ACTIVATE_LAST, FRAME_FIRE_LAST,
|
||||
FRAME_IDLE_LAST, FRAME_DEACTIVATE_LAST, pause_frames,
|
||||
fire_frames, fire);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ====================================================================== */
|
||||
|
||||
/* GRENADE */
|
||||
|
|
|
@ -215,10 +215,30 @@ InitGame(void)
|
|||
skill = gi.cvar("skill", "1", CVAR_LATCH);
|
||||
maxentities = gi.cvar("maxentities", "1024", CVAR_LATCH);
|
||||
|
||||
#ifdef CTF
|
||||
/* This game.so only supports deathmatch */
|
||||
if (!deathmatch->value)
|
||||
{
|
||||
gi.dprintf("Forcing deathmatch.\n");
|
||||
gi.cvar_set("deathmatch", "1");
|
||||
}
|
||||
|
||||
if (coop->value)
|
||||
{
|
||||
gi.cvar_set("coop", "0");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* change anytime vars */
|
||||
dmflags = gi.cvar("dmflags", "0", CVAR_SERVERINFO);
|
||||
fraglimit = gi.cvar("fraglimit", "0", CVAR_SERVERINFO);
|
||||
timelimit = gi.cvar("timelimit", "0", CVAR_SERVERINFO);
|
||||
|
||||
#ifdef CTF
|
||||
capturelimit = gi.cvar ("capturelimit", "0", CVAR_SERVERINFO);
|
||||
instantweap = gi.cvar ("instantweap", "0", CVAR_SERVERINFO);
|
||||
#endif
|
||||
|
||||
password = gi.cvar("password", "", CVAR_USERINFO);
|
||||
spectator_password = gi.cvar("spectator_password", "", CVAR_USERINFO);
|
||||
needpass = gi.cvar("needpass", "0", CVAR_SERVERINFO);
|
||||
|
@ -254,6 +274,10 @@ InitGame(void)
|
|||
game.maxclients = maxclients->value;
|
||||
game.clients = gi.TagMalloc(game.maxclients * sizeof(game.clients[0]), TAG_GAME);
|
||||
globals.num_edicts = game.maxclients + 1;
|
||||
|
||||
#ifdef CTF
|
||||
CTFInit();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ========================================================= */
|
||||
|
|
Loading…
Reference in a new issue