📄 g_ctf.c
字号:
i++;
}
if (ent)
G_FreeEdict(ent);
}
// frees the passed edict!
void CTFRespawnTech(edict_t *ent)
{
edict_t *spot;
if ((spot = FindTechSpawn()) != NULL)
SpawnTech(ent->item, spot);
G_FreeEdict(ent);
}
void CTFSetupTechSpawn(void)
{
edict_t *ent;
if (((int)dmflags->value & DF_CTF_NO_TECH))
return;
ent = G_Spawn();
ent->nextthink = level.time + 2;
ent->think = SpawnTechs;
}
void CTFResetTech(void)
{
edict_t *ent;
int i;
for (ent = g_edicts + 1, i = 1; i < globals.num_edicts; i++, ent++) {
if (ent->inuse)
if (ent->item && (ent->item->flags & IT_TECH))
G_FreeEdict(ent);
}
SpawnTechs(NULL);
}
int CTFApplyResistance(edict_t *ent, int dmg)
{
static gitem_t *tech = NULL;
float volume = 1.0;
if (ent->client && ent->client->silencer_shots)
volume = 0.2;
if (!tech)
tech = FindItemByClassname("item_tech1");
if (dmg && tech && ent->client && ent->client->pers.inventory[ITEM_INDEX(tech)]) {
// make noise
gi.sound(ent, CHAN_VOICE, gi.soundindex("ctf/tech1.wav"), volume, ATTN_NORM, 0);
return dmg / 2;
}
return dmg;
}
int CTFApplyStrength(edict_t *ent, int dmg)
{
static gitem_t *tech = NULL;
if (!tech)
tech = FindItemByClassname("item_tech2");
if (dmg && tech && ent->client && ent->client->pers.inventory[ITEM_INDEX(tech)]) {
return dmg * 2;
}
return dmg;
}
qboolean CTFApplyStrengthSound(edict_t *ent)
{
static gitem_t *tech = NULL;
float volume = 1.0;
if (ent->client && ent->client->silencer_shots)
volume = 0.2;
if (!tech)
tech = FindItemByClassname("item_tech2");
if (tech && ent->client &&
ent->client->pers.inventory[ITEM_INDEX(tech)]) {
if (ent->client->ctf_techsndtime < level.time) {
ent->client->ctf_techsndtime = level.time + 1;
if (ent->client->quad_framenum > level.framenum)
gi.sound(ent, CHAN_VOICE, gi.soundindex("ctf/tech2x.wav"), volume, ATTN_NORM, 0);
else
gi.sound(ent, CHAN_VOICE, gi.soundindex("ctf/tech2.wav"), volume, ATTN_NORM, 0);
}
return true;
}
return false;
}
qboolean CTFApplyHaste(edict_t *ent)
{
static gitem_t *tech = NULL;
if (!tech)
tech = FindItemByClassname("item_tech3");
if (tech && ent->client &&
ent->client->pers.inventory[ITEM_INDEX(tech)])
return true;
return false;
}
void CTFApplyHasteSound(edict_t *ent)
{
static gitem_t *tech = NULL;
float volume = 1.0;
if (ent->client && ent->client->silencer_shots)
volume = 0.2;
if (!tech)
tech = FindItemByClassname("item_tech3");
if (tech && ent->client &&
ent->client->pers.inventory[ITEM_INDEX(tech)] &&
ent->client->ctf_techsndtime < level.time) {
ent->client->ctf_techsndtime = level.time + 1;
gi.sound(ent, CHAN_VOICE, gi.soundindex("ctf/tech3.wav"), volume, ATTN_NORM, 0);
}
}
void CTFApplyRegeneration(edict_t *ent)
{
static gitem_t *tech = NULL;
qboolean noise = false;
gclient_t *client;
int index;
float volume = 1.0;
client = ent->client;
if (!client)
return;
if (ent->client->silencer_shots)
volume = 0.2;
if (!tech)
tech = FindItemByClassname("item_tech4");
if (tech && client->pers.inventory[ITEM_INDEX(tech)]) {
if (client->ctf_regentime < level.time) {
client->ctf_regentime = level.time;
if (ent->health < 150) {
ent->health += 5;
if (ent->health > 150)
ent->health = 150;
client->ctf_regentime += 0.5;
noise = true;
}
index = ArmorIndex (ent);
if (index && client->pers.inventory[index] < 150) {
client->pers.inventory[index] += 5;
if (client->pers.inventory[index] > 150)
client->pers.inventory[index] = 150;
client->ctf_regentime += 0.5;
noise = true;
}
}
if (noise && ent->client->ctf_techsndtime < level.time) {
ent->client->ctf_techsndtime = level.time + 1;
gi.sound(ent, CHAN_VOICE, gi.soundindex("ctf/tech4.wav"), volume, ATTN_NORM, 0);
}
}
}
qboolean CTFHasRegeneration(edict_t *ent)
{
static gitem_t *tech = NULL;
if (!tech)
tech = FindItemByClassname("item_tech4");
if (tech && ent->client &&
ent->client->pers.inventory[ITEM_INDEX(tech)])
return true;
return false;
}
/*
======================================================================
SAY_TEAM
======================================================================
*/
// This array is in 'importance order', it indicates what items are
// more important when reporting their names.
struct {
char *classname;
int priority;
} loc_names[] =
{
{ "item_flag_team1", 1 },
{ "item_flag_team2", 1 },
{ "item_quad", 2 },
{ "item_invulnerability", 2 },
{ "weapon_bfg", 3 },
{ "weapon_railgun", 4 },
{ "weapon_rocketlauncher", 4 },
{ "weapon_hyperblaster", 4 },
{ "weapon_chaingun", 4 },
{ "weapon_grenadelauncher", 4 },
{ "weapon_machinegun", 4 },
{ "weapon_supershotgun", 4 },
{ "weapon_shotgun", 4 },
{ "item_power_screen", 5 },
{ "item_power_shield", 5 },
{ "item_armor_body", 6 },
{ "item_armor_combat", 6 },
{ "item_armor_jacket", 6 },
{ "item_silencer", 7 },
{ "item_breather", 7 },
{ "item_enviro", 7 },
{ "item_adrenaline", 7 },
{ "item_bandolier", 8 },
{ "item_pack", 8 },
{ NULL, 0 }
};
static void CTFSay_Team_Location(edict_t *who, char *buf)
{
edict_t *what = NULL;
edict_t *hot = NULL;
float hotdist = 999999, newdist;
vec3_t v;
int hotindex = 999;
int i;
gitem_t *item;
int nearteam = -1;
edict_t *flag1, *flag2;
qboolean hotsee = false;
qboolean cansee;
while ((what = loc_findradius(what, who->s.origin, 1024)) != NULL) {
// find what in loc_classnames
for (i = 0; loc_names[i].classname; i++)
if (strcmp(what->classname, loc_names[i].classname) == 0)
break;
if (!loc_names[i].classname)
continue;
// something we can see get priority over something we can't
cansee = loc_CanSee(what, who);
if (cansee && !hotsee) {
hotsee = true;
hotindex = loc_names[i].priority;
hot = what;
VectorSubtract(what->s.origin, who->s.origin, v);
hotdist = VectorLength(v);
continue;
}
// if we can't see this, but we have something we can see, skip it
if (hotsee && !cansee)
continue;
if (hotsee && hotindex < loc_names[i].priority)
continue;
VectorSubtract(what->s.origin, who->s.origin, v);
newdist = VectorLength(v);
if (newdist < hotdist ||
(cansee && loc_names[i].priority < hotindex)) {
hot = what;
hotdist = newdist;
hotindex = i;
hotsee = loc_CanSee(hot, who);
}
}
if (!hot) {
strcpy(buf, "nowhere");
return;
}
// we now have the closest item
// see if there's more than one in the map, if so
// we need to determine what team is closest
what = NULL;
while ((what = G_Find(what, FOFS(classname), hot->classname)) != NULL) {
if (what == hot)
continue;
// 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) {
VectorSubtract(hot->s.origin, flag1->s.origin, v);
hotdist = VectorLength(v);
VectorSubtract(hot->s.origin, flag2->s.origin, v);
newdist = VectorLength(v);
if (hotdist < newdist)
nearteam = CTF_TEAM1;
else if (hotdist > newdist)
nearteam = CTF_TEAM2;
}
break;
}
if ((item = FindItemByClassname(hot->classname)) == NULL) {
strcpy(buf, "nowhere");
return;
}
// in water?
if (who->waterlevel)
strcpy(buf, "in the water ");
else
*buf = 0;
// near or above
VectorSubtract(who->s.origin, hot->s.origin, v);
if (fabs(v[2]) > fabs(v[0]) && fabs(v[2]) > fabs(v[1]))
if (v[2] > 0)
strcat(buf, "above ");
else
strcat(buf, "below ");
else
strcat(buf, "near ");
if (nearteam == CTF_TEAM1)
strcat(buf, "the red ");
else if (nearteam == CTF_TEAM2)
strcat(buf, "the blue ");
else
strcat(buf, "the ");
strcat(buf, item->pickup_name);
}
static void CTFSay_Team_Armor(edict_t *who, char *buf)
{
gitem_t *item;
int index, cells;
int power_armor_type;
*buf = 0;
power_armor_type = PowerArmorType (who);
if (power_armor_type)
{
cells = who->client->pers.inventory[ITEM_INDEX(FindItem ("cells"))];
if (cells)
sprintf(buf+strlen(buf), "%s with %i cells ",
(power_armor_type == POWER_ARMOR_SCREEN) ?
"Power Screen" : "Power Shield", cells);
}
index = ArmorIndex (who);
if (index)
{
item = GetItemByIndex (index);
if (item) {
if (*buf)
strcat(buf, "and ");
sprintf(buf+strlen(buf), "%i units of %s",
who->client->pers.inventory[index], item->pickup_name);
}
}
if (!*buf)
strcpy(buf, "no armor");
}
static void CTFSay_Team_Health(edict_t *who, char *buf)
{
if (who->health <= 0)
strcpy(buf, "dead");
else
sprintf(buf, "%i health", who->health);
}
static void CTFSay_Team_Tech(edict_t *who, char *buf)
{
gitem_t *tech;
int i;
// see if the player has a tech powerup
i = 0;
while (tnames[i]) {
if ((tech = FindItemByClassname(tnames[i])) != NULL &&
who->client->pers.inventory[ITEM_INDEX(tech)]) {
sprintf(buf, "the %s", tech->pickup_name);
return;
}
i++;
}
strcpy(buf, "no powerup");
}
static void CTFSay_Team_Weapon(edict_t *who, char *buf)
{
if (who->client->pers.weapon)
strcpy(buf, who->client->pers.weapon->pickup_name);
else
strcpy(buf, "none");
}
static void CTFSay_Team_Sight(edict_t *who, char *buf)
{
int i;
edict_t *targ;
int n = 0;
char s[1024];
char s2[1024];
*s = *s2 = 0;
for (i = 1; i <= maxclients->value; i++) {
targ = g_edicts + i;
if (!targ->inuse ||
targ == who ||
!loc_CanSee(targ, who))
continue;
if (*s2) {
if (strlen(s) + strlen(s2) + 3 < sizeof(s)) {
if (n)
strcat(s, ", ");
strcat(s, s2);
*s2 = 0;
}
n++;
}
strcpy(s2, targ->client->pers.netname);
}
if (*s2) {
if (strlen(s) + strlen(s2) + 6 < sizeof(s)) {
if (n)
strcat(s, " and ");
strcat(s, s2);
}
strcpy(buf, s);
} else
strcpy(buf, "no one");
}
void CTFSay_Team(edict_t *who, char *msg)
{
char outmsg[256];
char buf[256];
int i;
char *p;
edict_t *cl_ent;
if (CheckFlood(who))
return;
outmsg[0] = 0;
if (*msg == '\"') {
msg[strlen(msg) - 1] = 0;
msg++;
}
for (p = outmsg; *msg && (p - outmsg) < sizeof(outmsg) - 2; msg++) {
if (*msg == '%') {
switch (*++msg) {
case 'l' :
case 'L' :
CTFSay_Team_Location(who, buf);
if (strlen(buf) + (p - outmsg) < sizeof(outmsg) - 2) {
strcpy(p, buf);
p += strlen(buf);
}
break;
case 'a' :
case 'A' :
CTFSay_Team_Armor(who, buf);
if (strlen(buf) + (p - outmsg) < sizeof(outmsg) - 2) {
strcpy(p, buf);
p += strlen(buf);
}
break;
case 'h' :
case 'H' :
CTFSay_Team_Health(who, buf);
if (strlen(buf) + (p - outmsg) < sizeof(outmsg) - 2) {
strcpy(p, buf);
p += strlen(buf);
}
break;
case 't' :
case 'T' :
CTFSay_Team_Tech(who, buf);
if (strlen(buf) + (p - outmsg) < sizeof(outmsg) - 2) {
strcpy(p, buf);
p += strlen(buf);
}
break;
case 'w' :
case 'W' :
CTFSay_Team_Weapon(who, buf);
if (strlen(buf) + (p - outmsg) < sizeof(outmsg) - 2) {
strcpy(p, buf);
p += strlen(buf);
}
break;
case 'n' :
case 'N' :
CTFSay_Team_Sight(who, buf);
if (strlen(buf) + (p - outmsg) < sizeof(outmsg) - 2) {
strcpy(p, buf);
p
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -