remove(self);
return;
}
- self.team = COLOR_TEAM1; // red, gets swapped every round
+ self.team = NUM_TEAM_1; // red, gets swapped every round
spawnfunc_info_player_deathmatch();
}
remove(self);
return;
}
- self.team = COLOR_TEAM2; // blue, gets swapped every round
+ self.team = NUM_TEAM_2; // blue, gets swapped every round
spawnfunc_info_player_deathmatch();
}
}
self.spawnflags = 3;
self.classname = "func_assault_destructible";
- if(assault_attacker_team == COLOR_TEAM1) {
- self.team = COLOR_TEAM2;
+ if(assault_attacker_team == NUM_TEAM_1) {
+ self.team = NUM_TEAM_2;
} else {
- self.team = COLOR_TEAM1;
+ self.team = NUM_TEAM_1;
}
spawnfunc_func_breakable();
}
ent = find(world, classname, "turret_main");
while(ent) {
// Swap turret teams
- if(ent.team == COLOR_TEAM1)
- ent.team = COLOR_TEAM2;
+ if(ent.team == NUM_TEAM_1)
+ ent.team = NUM_TEAM_2;
else
- ent.team = COLOR_TEAM1;
+ ent.team = NUM_TEAM_1;
self = ent;
remove(self);
return;
}
- assault_attacker_team = COLOR_TEAM1;
+ assault_attacker_team = NUM_TEAM_1;
self.classname = "target_assault_roundstart";
self.use = assault_roundstart_use;
self.reset2 = assault_roundstart_use;
self.winning = self.winning + 1;
// swap attacker/defender roles
- if(assault_attacker_team == COLOR_TEAM1) {
- assault_attacker_team = COLOR_TEAM2;
+ if(assault_attacker_team == NUM_TEAM_1) {
+ assault_attacker_team = NUM_TEAM_2;
} else {
- assault_attacker_team = COLOR_TEAM1;
+ assault_attacker_team = NUM_TEAM_1;
}
entity ent;
for(ent = world; (ent = nextent(ent)); )
{
- if(clienttype(ent) == CLIENTTYPE_NOTACLIENT)
+ if(IS_NOT_A_CLIENT(ent))
{
- if(ent.team_saved == COLOR_TEAM1)
- ent.team_saved = COLOR_TEAM2;
- else if(ent.team_saved == COLOR_TEAM2)
- ent.team_saved = COLOR_TEAM1;
+ if(ent.team_saved == NUM_TEAM_1)
+ ent.team_saved = NUM_TEAM_2;
+ else if(ent.team_saved == NUM_TEAM_2)
+ ent.team_saved = NUM_TEAM_1;
}
}
--- /dev/null
- if(self.owner.classname != "player" || time < game_starttime)
+ float rune_numspawns;
+
+ float RUNE_FIRST = 1;
+ float RUNE_STRENGTH = 1;
+ float RUNE_DEFENSE = 2;
+ float RUNE_REGEN = 4;
+ float RUNE_SPEED = 8;
+ float RUNE_VAMPIRE = 16;
+ float RUNE_LAST = 16;
+
+ float CURSE_FIRST = 8192;
+ float CURSE_WEAK = 8192;
+ float CURSE_VULNER = 16384;
+ float CURSE_VENOM = 32768;
+ float CURSE_SLOW = 65536;
+ float CURSE_EMPATHY = 131072;
+ float CURSE_LAST = 131072;
+
+ float RUNE_COUNT = 5;
+
+ /* rune ideas:
+
+ Doom/Death
+ Rune: When you damage enemies, you have a slight chance of instant-killing them (porportional to damage dealt / their health)
+ Curse: When you are damaged, you have a chance of being instant-killed
+
+ Vengence/Slothful
+ Rune: The lower your health below 100, the more damage you deal (does not decrease your damage if you're above 100)
+ Curse: The higher your health (up to 100), the less damage you deal (at 100 hp deal 1/5th damage)
+
+ */
+
+ /*QUAKED spawnfunc_runematch_spawn_point (1 0 0) (-16 -16 -24) (16 16 24)
+ spawn point for runes in runematch
+ */
+
+ void spawnfunc_runematch_spawn_point()
+ {
+ if(!g_runematch || !autocvar_g_runematch_fixedspawns)
+ {
+ remove(self);
+ return;
+ }
+
+ setsize(self, '0 0 -35', '0 0 0');
+ droptofloor();
+ ++rune_numspawns;
+ }
+
+ // only used if using rune spawns at all
+ entity rune_find_spawnpoint()
+ {
+ entity e;
+
+ if(rune_numspawns < RUNE_COUNT)
+ return world;
+
+ RandomSelection_Init();
+
+ for(e = world; (e = find(e, classname, "runematch_spawn_point")); )
+ if(e.owner == world)
+ RandomSelection_Add(e, 0, string_null, e.cnt, 0);
+
+ return RandomSelection_chosen_ent;
+ }
+
+ float rune_spawn_somewhere(entity e)
+ {
+ entity spot;
+ spot = rune_find_spawnpoint();
+ if(spot)
+ {
+ spot.owner = e;
+ setorigin(e, spot.origin);
+
+ e.owner = spot;
+ spot.owner = e;
+
+ return TRUE;
+ }
+ else
+ {
+ if(MoveToRandomMapLocation(e, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, 10, 1024, 256))
+ {
+ // great
+ makevectors(self.angles),
+ self.velocity = v_forward * 250;
+ self.angles = '0 0 0';
+ return TRUE;
+ }
+ else
+ {
+ // sorry, can't spawn, better luck next frame
+ return FALSE;
+ }
+ }
+ }
+
+ void rune_unmark_spot(entity e)
+ {
+ if(e.owner.classname == "runematch_spawn_point")
+ {
+ e.owner.owner = world;
+ e.owner = world;
+ }
+ }
+
+ string RuneName(float r)
+ {
+ if(r == RUNE_STRENGTH)
+ return "^1Strength^7";
+ if(r == RUNE_DEFENSE)
+ return "^4Defense^7";
+ if(r == RUNE_REGEN)
+ return "^2Vitality^7";
+ if(r == RUNE_SPEED)
+ return "^3Speed^7";
+ if(r == RUNE_VAMPIRE)
+ return "^6Vampire^7";
+
+ if(r == CURSE_WEAK)
+ return "^1Weakness^7";
+ if(r == CURSE_VULNER)
+ return "^4Vulnerability^7";
+ if(r == CURSE_VENOM)
+ return "^2Venom^7";
+ if(r == CURSE_SLOW)
+ return "^3Slow^7";
+ if(r == CURSE_EMPATHY)
+ return "^6Empathy^7";
+ return strcat("^8[unnamed", ftos(r), "]^7");
+ }
+
+ vector RuneColormod(float r)
+ {
+ vector _color = '255 0 255';
+
+ if(r == RUNE_STRENGTH)
+ _color = '255 0 0';
+ if(r == RUNE_DEFENSE)
+ _color = '0 0 255';//'0 102 255';//
+ if(r == RUNE_REGEN)
+ _color = '0 204 0';//'0 255 0';
+ if(r == RUNE_SPEED)
+ _color = 0.35*'185 185 0';//255 230 0';//'255 255 0';
+ if(r == RUNE_VAMPIRE)
+ _color = '64 0 128';//'108 0 217';//'128 0 255';//'179 0 204';//
+
+ if(r == CURSE_WEAK)
+ _color = '255 0 0';
+ if(r == CURSE_VULNER)
+ _color = '0 0 255';//'0 102 255';//
+ if(r == CURSE_VENOM)
+ _color = '0 204 0';//'0 255 0';
+ if(r == CURSE_SLOW)
+ _color = 0.5*'185 185 0';//'255 255 0';
+ if(r == CURSE_EMPATHY)
+ _color = '179 0 204';//'128 0 255';
+
+ return _color * (1 / 255) * autocvar_g_runematch_rune_color_strength;
+ }
+
+ void rune_respawn();
+
+ void RuneCarriedThink()
+ {
+ float rcount, rnum;
+ vector ang = '0 0 0';
+ entity rune;
+
- if(other.classname != "player" || other.health < 1)
++ if(!IS_PLAYER(self.owner) || time < game_starttime)
+ {
+ rune_respawn();
+ return;
+ }
+
+ self.nextthink = time + 0.1;
+
+ // count runes my owner holds
+ rcount = 0;
+ rune = find(world, classname, "rune");
+ rnum = -1;
+ while(rune)
+ {
+ if(rune.owner == self.owner)
+ rcount = rcount + 1;
+ if(rune == self)
+ rnum = rcount;
+ rune = find(rune, classname, "rune");
+ }
+
+ ang_y = rnum*(360 / rcount) + mod(time, 360)*45;//180;
+
+ makevectors(ang);
+
+ setorigin(self, v_forward*32);
+ }
+
+ void rune_touch()
+ {
+ if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
+ {
+ self.think = rune_respawn;
+ self.nextthink = time;
+ return;
+ }
+
- if(rune.owner.classname == "player")
++ if(!IS_PLAYER(other) || other.health < 1)
+ return;
+ if(self.wait > time)
+ return; // "notouch" time isn't finished
+
+ // detach from the spawn point you're on
+ rune_unmark_spot(self);
+
+ self.owner = other;
+ self.enemy.owner = other;
+ setattachment(self, other, "");
+
+ other.runes = other.runes | self.runes | self.enemy.runes;
+
+ //self.think = func_null;
+ //self.nextthink = 0;
+ self.think = RuneCarriedThink;
+ self.nextthink = time;
+ self.touch = func_null;
+
+ self.solid = SOLID_NOT;
+ setorigin(self, self.origin);
+
+ //sprint(other, strcat("^3You have picked up ",
+ // RuneName(self.runes & (RUNE_LAST*2-1)), " and "));
+ //sprint(other, strcat(RuneName(self.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n"));
+
+ bprint("^3", other.netname, "^7 has picked up ",
+ RuneName(self.runes & (RUNE_LAST*2-1)), "^7 and ");
+ bprint(RuneName(self.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n");
+ }
+
+ void rune_respawn()
+ {
+ rune_unmark_spot(self);
+ if(rune_spawn_somewhere(self))
+ {
+ self.solid = SOLID_TRIGGER;
+ self.touch = rune_touch;
+ self.think = rune_respawn;
+ self.nextthink = time + autocvar_g_runematch_shuffletime;//30 + random()*5; // fixme: cvar
+ }
+ else
+ {
+ // try again later
+ self.think = rune_respawn;
+ self.nextthink = time;
+ }
+ }
+
+ entity FindRune(entity own, string clname, float r)
+ {
+ entity rune;
+ float _count, c;
+
+ c = _count = 0;
+ rune = world;
+
+ do
+ {
+ rune = find(rune, classname, clname);
+ if(!rune)
+ rune = find(rune, classname, clname);
+ if(!rune)
+ break;
+ if(rune.owner == own)
+ {
+ _count = _count + 1;
+ if(_count >= r)
+ return rune;
+ if(r <= 1)
+ return rune;
+ }
+ c = c + 1;
+ }while(c < 30);
+ return world;
+ }
+
+
+ void DropRune(entity pl, entity e)
+ {
+ //entity pl;
+
+ //pl = e.owner;
+ // detach from player
+ setattachment(e, world, "");
+ e.owner = world;
+ e.enemy.owner = world;
+ // don't instantly touch player again
+ e.wait = time + 1; // "notouch" time
+ e.movetype = MOVETYPE_TOSS;
+ e.solid = SOLID_TRIGGER;
+ // reposition itself if not picked up soon
+ e.think = rune_respawn;
+ e.nextthink = time + autocvar_g_runematch_respawntime;//15 + random()*5; // fixme: cvar
+ e.touch = rune_touch;
+
+ pl.runes = pl.runes - (pl.runes & (e.runes | e.enemy.runes));
+
+ // toss from player
+ setorigin(e, pl.origin + '0 0 10');
+ e.velocity = '0 0 200' + '0 100 0'*crandom() + '100 0 0'*crandom();
+
+
+ bprint("^3", pl.netname, "^7 has lost ",
+ RuneName(e.runes & (RUNE_LAST*2-1)), "^7 and ");
+ bprint(RuneName(e.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n");
+ }
+
+ float RuneMatchesCurse(float r, float c)
+ {
+ float cr;
+ if(r & RUNE_STRENGTH)
+ cr = CURSE_WEAK;
+ else if(r & RUNE_DEFENSE)
+ cr = CURSE_VULNER;
+ else if(r & RUNE_REGEN)
+ cr = CURSE_VENOM;
+ else if(r & RUNE_SPEED)
+ cr = CURSE_SLOW;
+ else if(r & RUNE_VAMPIRE)
+ cr = CURSE_EMPATHY;
+ else return FALSE; // fixme: error?
+
+ if(c & cr)
+ return TRUE;
+ return FALSE;
+ }
+
+ // player died, drop runes
+ // each rune should pair up with a random curse and then be tossed from the player
+ void DropAllRunes(entity pl)
+ {
+ entity rune, curse;
+ float rcount, ccount, r, c, rand, prevent_same, numtodrop, tries;
+
+ entity curse1, rune1, curse2, rune2;
+
+ rcount = ccount = r = c = 0;
+ rune = find(world, classname, "rune");
+ while(rune)
+ {
+ if(rune.owner == pl)
+ rcount = rcount + 1;
+ rune = find(rune, classname, "rune");
+ }
+ curse = find(world, classname, "curse");
+ while(curse)
+ {
+ if(curse.owner == pl)
+ ccount = ccount + 1;
+ curse = find(curse, classname, "curse");
+ }
+
+ numtodrop = autocvar_g_runematch_drop_runes_max;
+ prevent_same = !autocvar_g_runematch_allow_same;
+
+ do
+ {
+ rune = find(rune, classname, "rune");
+ if(!rune)
+ break;
+ if(rune.owner != pl)
+ continue;
+
+
+ // find a random curse
+ tries = 15;
+ if(ccount > 1 && prevent_same)
+ {
+ // avoid pairing runes and curses that match each other
+ do{
+ rand = floor(random()*ccount) + 1;
+ curse = FindRune(pl, "curse", rand);
+ tries = tries - 1;
+ }while(RuneMatchesCurse(rune.runes, curse.runes) && tries > 0);
+ if(tries <= 0)
+ {
+ bprint("warning: couldn't prevent same rune\n");
+ }
+ }
+ else
+ {
+ rand = floor(random()*ccount) + 1;
+ curse = FindRune(pl, "curse", rand);
+ }
+
+ if(!curse)
+ error("Couldn't fine curse to bind rune to\n");
+
+ // pair rune and curse
+
+ rune1 = rune;
+ curse1 = curse;
+ rune2 = curse1.enemy;
+ curse2 = rune1.enemy;
+
+ if(rune1 != rune2) // not already attached to each other
+ {
+ rune1.enemy = curse1;
+ curse1.enemy = rune1;
+ setattachment(curse1, rune1, "");
+ rune2.enemy = curse2;
+ curse2.enemy = rune2;
+ setattachment(curse2, rune2, "");
+ //DropRune(pl, rune2);
+ //ccount = ccount - 1;
+ //rcount = rcount - 1;
+ }
+ DropRune(pl, rune1);
+
+ if(numtodrop <=0)
+ {
+ rune1.think = rune_respawn;
+ rune1.nextthink = time;
+ }
+
+ numtodrop = numtodrop - 1;
+
+ ccount = ccount - 1;
+ rcount = rcount - 1;
+
+ }while(rune);
+ }
+
+ void rune_reset()
+ {
+ if(self.owner)
+ if(self.owner.classname != "runematch_spawn_point")
+ DropAllRunes(self.owner);
+ rune_respawn();
+ }
+
+ void spawn_runes()
+ {
+ float rn, cs, runes_used, curses_used, prevent_same, numrunes;
+ entity e;
+
+ if(self)
+ remove(self);
+
+ // fixme: instead of placing them all now, why not
+ // simply create them all and let them call rune_respawn() as their think?
+
+ runes_used = 0;
+ curses_used = 0;
+
+ prevent_same = !autocvar_g_runematch_allow_same;
+ numrunes = RUNE_COUNT;
+
+ while(numrunes > 0)
+ {
+ RandomSelection_Init();
+ for(rn = RUNE_FIRST; rn <= RUNE_LAST; rn *= 2)
+ if not(runes_used & rn)
+ RandomSelection_Add(world, rn, string_null, 1, 1);
+ rn = RandomSelection_chosen_float;
+
+ RandomSelection_Init();
+ for(cs = CURSE_FIRST; cs <= CURSE_LAST; cs *= 2)
+ if not(curses_used & cs)
+ if not(prevent_same && cs == RuneMatchesCurse(rn, cs))
+ RandomSelection_Add(world, cs, string_null, 1, 1);
+ cs = RandomSelection_chosen_float;
+
+ if(!rn || !cs)
+ error("No rune/curse left");
+
+ runes_used |= rn;
+ curses_used |= cs;
+
+ e = spawn();
+ e.runes = rn;
+ e.classname = "rune";
+ e.touch = rune_touch;
+ e.think = rune_respawn;
+ e.nextthink = time;
+ e.movetype = MOVETYPE_TOSS;
+ e.solid = SOLID_TRIGGER;
+ e.flags = FL_ITEM;
+ e.reset = rune_reset;
+ setmodel(e, "models/runematch/rune.mdl"); // precision set below
+ setsize(e, '0 0 -35', '0 0 0');
+
+ e.enemy = spawn();
+ e.enemy.enemy = e;
+ e.enemy.classname = "curse";
+ e.enemy.runes = cs;
+ //e.enemy.avelocity = '300 500 200';
+ setmodel(e.enemy, "models/runematch/curse.mdl"); // precision set below
+ setorigin(e, '0 0 0');
+ setattachment(e.enemy, e, "");
+
+ e.colormod = RuneColormod(rn);
+ e.enemy.colormod = RuneColormod(cs);
+
+ e.alpha = e.enemy.alpha = autocvar_g_runematch_rune_alpha;//0.78;
+ e.effects = e.enemy.effects = autocvar_g_runematch_rune_effects | EF_LOWPRECISION;//EF_ADDITIVE;// | EF_FULLBRIGHT;
+
+ //e.glow_size = e.enemy.glow_size = cvar("g_runematch_rune_glow_size");
+ //e.glow_color = e.enemy.glow_color = cvar("g_runematch_rune_glow_color");
+
+ //rn = RUNE_FIRST;
+ //cs = CURSE_FIRST;
+
+ numrunes = numrunes - 1;
+ }
+ }
+
+ void runematch_init()
+ {
+ if(!g_runematch)
+ return;
+
+ entity e;
+ e = spawn();
+ e.think = spawn_runes;
+ e.nextthink = time + 0.1;
+ }
+
+
+ float runematch_point_time;
+
+ // give points to players who are holding runes
+ void RuneMatchGivePoints()
+ {
+ entity rune;
+
+ if(!g_runematch || !autocvar_g_runematch_pointamt)
+ return;
+
+ if(gameover)
+ return;
+
+ if(runematch_point_time > time)
+ return;
+
+ runematch_point_time = time + autocvar_g_runematch_pointrate;
+
+ rune = world;
+ do
+ {
+ rune = find(rune, classname, "rune");
+ if(!rune)
+ return;
+
++ if(IS_PLAYER(rune.owner))
+ {
+ UpdateFrags(rune.owner, autocvar_g_runematch_pointamt);
+ }
+ }while(rune);
+ }
+
+ float RunematchHandleFrags(entity attacker, entity targ, float f)
+ {
+ entity head;
+ float arunes, trunes, newfrags;
+
+ if(f <= 0)
+ return f;
+ if(attacker == targ)
+ return f;
+
+ arunes = trunes = 0;
+
+ head = find(world, classname, "rune");
+ while(head)
+ {
+ if(head.owner == attacker)
+ {
+ arunes = arunes + 1;
+ }
+ else if(head.owner == targ)
+ {
+ trunes = trunes + 1;
+ }
+
+ head = find(head, classname, "rune");
+ }
+
+ if(!arunes && !trunes)
+ return f - 1 + autocvar_g_runematch_frags_norune; // don't give points to players when no runes are involved.
+
+ newfrags = 0;
+ if(arunes)
+ { // got a kill while holding runes
+ newfrags = newfrags + autocvar_g_runematch_frags_killedby_runeholder;//5;
+ }
+ if(trunes)
+ { // killed an enemy holding runes
+ newfrags = newfrags + autocvar_g_runematch_frags_killed_runeholder;//5;
+ }
+ if(newfrags)
+ f = f - 1 + newfrags;
+
+ return f;
+ }
return FALSE;
}
- if(g_freezetag)
- if(e.freezetag_frozen)
- return FALSE;
+ if(e.freezetag_frozen)
+ return FALSE;
// If neither player has ball then don't attack unless the ball is on the
// ground.
return FALSE;
}
else if(bot_ignore_bots)
- if(clienttype(e) == CLIENTTYPE_BOT)
+ if(IS_BOT_CLIENT(e))
return FALSE;
if (!e.takedamage)
prio = 1;
FOR_EACH_CLIENT(p)
{
- if(clienttype(p) == CLIENTTYPE_BOT)
+ if(IS_BOT_CLIENT(p))
if(s == p.cleanname)
{
prio = 0;
i = 0;
FOR_EACH_CLIENT(p)
{
- if(clienttype(p) == CLIENTTYPE_BOT)
+ if(IS_BOT_CLIENT(p))
if(p.cleanname == name)
++i;
}
{
player_count = player_count + 1;
e.nextplayer = e.chain;
- if (clienttype(e) == CLIENTTYPE_BOT)
+ if (IS_BOT_CLIENT(e))
{
if (prevbot)
prevbot.nextbot = e;
void bot_clientdisconnect()
{
- if (clienttype(self) != CLIENTTYPE_BOT)
+ if not(IS_BOT_CLIENT(self))
return;
bot_clearqueue(self);
if(self.cleanname)
void bot_clientconnect()
{
- if (clienttype(self) != CLIENTTYPE_BOT)
+ if not(IS_BOT_CLIENT(self))
return;
self.bot_preferredcolors = self.clientcolors;
self.bot_nextthink = time - random();
bot_setnameandstuff();
if(self.bot_forced_team==1)
- self.team = COLOR_TEAM1;
+ self.team = NUM_TEAM_1;
else if(self.bot_forced_team==2)
- self.team = COLOR_TEAM2;
+ self.team = NUM_TEAM_2;
else if(self.bot_forced_team==3)
- self.team = COLOR_TEAM3;
+ self.team = NUM_TEAM_3;
else if(self.bot_forced_team==4)
- self.team = COLOR_TEAM4;
+ self.team = NUM_TEAM_4;
else
JoinBestTeam(self, FALSE, TRUE);
bestcount = 0;
while (head)
{
- if(head.team == COLOR_TEAM1)
+ if(head.team == NUM_TEAM_1)
thiscount = c1;
- else if(head.team == COLOR_TEAM2)
+ else if(head.team == NUM_TEAM_2)
thiscount = c2;
- else if(head.team == COLOR_TEAM3)
+ else if(head.team == NUM_TEAM_3)
thiscount = c3;
- else if(head.team == COLOR_TEAM4)
+ else if(head.team == NUM_TEAM_4)
thiscount = c4;
else
thiscount = 0;
bestplayer = -1;
FOR_EACH_PLAYER(head)
{
- if(clienttype(head) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(head))
bestplayer = max(bestplayer, head.totalfrags - head.totalfrags_lastcheck);
else
bestbot = max(bestbot, head.totalfrags - head.totalfrags_lastcheck);
FOR_EACH_REALCLIENT(head)
{
- if(IS_PLAYER(head) || g_lms || g_arena || g_ca)
- if(head.classname == "player" || g_lms || g_arena || head.caplayer == 1)
++ if(IS_PLAYER(head) || g_lms || g_arena || head.caplayer == 1)
++activerealplayers;
++realplayers;
}
WriteByte(MSG_BROADCAST, TE_CSQC_TEAMNAGGER);
}
- void Announce(string snd) {
- WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte(MSG_BROADCAST, TE_CSQC_ANNOUNCE);
- WriteString(MSG_BROADCAST, snd);
- }
-
- void AnnounceTo(entity e, string snd) {
- if (IS_REAL_CLIENT(e))
- {
- msg_entity = e;
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_ANNOUNCE);
- WriteString(MSG_ONE, snd);
- }
- }
-
float ClientData_Send(entity to, float sf)
{
if(to != self.owner)
entity e;
e = to;
- if(to.classname == "spectator")
+ if(IS_SPEC(to))
e = to.enemy;
sf = 0;
FOR_EACH_REALCLIENT(e2)
{
if(e2 != e)
- if(e2.classname == "spectator")
+ if(IS_SPEC(e2))
if(e2.enemy == e)
e2.clientdata.SendFlags = 1;
}
if(spot.target == "")
return '-1 0 0';
- if(clienttype(self) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(self))
{
if(spot.restriction == 1)
return '-1 0 0';
else
{
float mindist;
- if (arena_roundbased && !g_ca)
+ if (g_arena && arena_roundbased)
mindist = 800;
else
mindist = 100;
error("No spawnpoints for observers?!?\n");
RemoveGrapplingHook(self); // Wazat's Grappling Hook
- if(clienttype(self) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(self))
{
msg_entity = self;
WriteByte(MSG_ONE, SVC_SETVIEW);
WriteEntity(MSG_ONE, self);
}
- DropAllRunes(self);
+ if(g_lms)
+ {
+ // Only if the player cannot play at all
+ if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666)
+ self.frags = FRAGS_SPECTATOR;
+ else
+ self.frags = FRAGS_LMS_LOSER;
+ }
+ else if((g_race && g_race_qualifying) || g_cts)
+ {
+ if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
+ self.frags = FRAGS_LMS_LOSER;
+ else
+ self.frags = FRAGS_SPECTATOR;
+ }
+ else
+ self.frags = FRAGS_SPECTATOR;
+
MUTATOR_CALLHOOK(MakePlayerObserver);
minstagib_stop_countdown(self);
if(self.killcount != -666) {
if(g_lms) {
- if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0)
- bprint ("^4", self.netname, "^4 has no more lives left\n");
+ if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0 && self.lms_spectate_warning != 2)
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_NOLIVES, self.netname);
else
- bprint ("^4", self.netname, "^4 is spectating now\n"); // TODO turn this into a proper forfeit?
- } else
- bprint ("^4", self.netname, "^4 is spectating now\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_FORFEIT, self.netname);
+ } else { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_SPECTATE, self.netname); }
if(self.just_joined == FALSE) {
LogTeamchange(self.playerid, -1, 4);
self.pauseregen_finished = 0;
self.damageforcescale = 0;
self.death_time = 0;
+ self.respawn_flags = 0;
self.respawn_time = 0;
+ self.stat_respawn_time = 0;
self.alpha = 0;
self.scale = 0;
self.fade_time = 0;
self.think = func_null;
self.nextthink = 0;
self.hook_time = 0;
- self.runes = 0;
self.deadflag = DEAD_NO;
self.angles = spot.angles;
self.angles_z = 0;
self.punchvector = '0 0 0';
self.oldvelocity = self.velocity;
self.fire_endtime = -1;
-
- if(g_arena)
- {
- if(self.version_mismatch)
- {
- self.frags = FRAGS_SPECTATOR;
- Spawnqueue_Unmark(self);
- Spawnqueue_Remove(self);
- }
- else
- {
- self.frags = FRAGS_LMS_LOSER;
- Spawnqueue_Insert(self);
- }
- }
- else if(g_lms)
- {
- // Only if the player cannot play at all
- if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666)
- self.frags = FRAGS_SPECTATOR;
- else
- self.frags = FRAGS_LMS_LOSER;
- }
- else if(g_ca)
- {
- if(self.caplayer)
- self.frags = FRAGS_LMS_LOSER;
- else
- self.frags = FRAGS_SPECTATOR;
- }
- else if((g_race && g_race_qualifying) || g_cts)
- {
- if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
- self.frags = FRAGS_LMS_LOSER;
- else
- self.frags = FRAGS_SPECTATOR;
- }
- else
- self.frags = FRAGS_SPECTATOR;
}
.float model_randomizer;
if(teamplay)
{
string s;
- s = Team_ColorNameLowerCase(self.team);
+ s = Team_ColorName_Lower(self.team);
if(s != "neutral")
{
defaultmodel = cvar_string(strcat("sv_defaultplayermodel_", s));
setcolor(self, stof(autocvar_sv_defaultplayercolors));
}
- void PlayerTouchExplode(entity p1, entity p2)
- {
- vector org;
- org = (p1.origin + p2.origin) * 0.5;
- org_z += (p1.mins_z + p2.mins_z) * 0.5;
-
- te_explosion(org);
-
- entity e;
- e = spawn();
- setorigin(e, org);
- RadiusDamage(e, world, g_touchexplode_damage, g_touchexplode_edgedamage, g_touchexplode_radius, world, g_touchexplode_force, DEATH_TOUCHEXPLODE, world);
- remove(e);
- }
-
/*
=============
PutClientInServer
void PutClientInServer (void)
{
- if(IS_BOT_CLIENT(self))
- {
+ if(clienttype(self) == CLIENTTYPE_BOT)
self.classname = "player";
- if(g_ca)
- self.caplayer = 1;
- }
- else if(IS_REAL_CLIENT(self))
+ else if(clienttype(self) == CLIENTTYPE_REAL)
{
msg_entity = self;
WriteByte(MSG_ONE, SVC_SETVIEW);
self.classname = "observer";
}
- if((g_arena && !self.spawned) || (g_ca && !allowed_to_spawn))
- self.classname = "observer";
+ MUTATOR_CALLHOOK(PutClientInServer);
if(gameover)
self.classname = "observer";
- if(IS_PLAYER(self) && (!g_ca || (g_ca && allowed_to_spawn))) {
- if(self.classname == "player") {
++ if(IS_PLAYER(self))
++ {
entity spot, oldself;
float j;
spot = SelectSpawnPoint (FALSE);
if(!spot)
{
- centerprint(self, "Sorry, no spawnpoints available!\nHope your team can fix it...");
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_JOIN_NOSPAWNS);
return; // spawn failed
}
self.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID;
if(autocvar_g_playerclip_collisions)
self.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP;
- if(clienttype(self) == CLIENTTYPE_BOT && autocvar_g_botclip_collisions)
+ if(IS_BOT_CLIENT(self) && autocvar_g_botclip_collisions)
self.dphitcontentsmask |= DPCONTENTS_BOTCLIP;
self.frags = FRAGS_PLAYER;
if(INDEPENDENT_PLAYERS)
}
self.damageforcescale = 2;
self.death_time = 0;
+ self.respawn_flags = 0;
self.respawn_time = 0;
+ self.stat_respawn_time = 0;
self.scale = 0;
self.fade_time = 0;
self.pain_frame = 0;
self.metertime = 0;
- self.runes = 0;
-
self.deadflag = DEAD_NO;
self.angles = spot.angles;
self.lastteleporttime = time; // prevent insane speeds due to changing origin
self.hud = HUD_NORMAL;
- if(g_arena)
- {
- Spawnqueue_Remove(self);
- Spawnqueue_Mark(self);
- }
- else if(g_ca)
- self.caplayer = 1;
-
self.event_damage = PlayerDamage;
self.bot_attack = TRUE;
if(g_assault) {
if(self.team == assault_attacker_team)
- centerprint(self, "You are attacking!");
+ Send_Notification(NOTIF_TEAM, self, MSG_CENTER, CENTER_ASSAULT_ATTACKING);
else
- centerprint(self, "You are defending!");
+ Send_Notification(NOTIF_TEAM, self, MSG_CENTER, CENTER_ASSAULT_DEFENDING);
}
target_voicescript_clear(self);
if (autocvar_g_spawnsound)
soundat(world, self.origin, CH_TRIGGER, "misc/spawn.wav", VOL_BASE, ATTN_NORM);
- } else if(self.classname == "observer") {
+ } else if(IS_OBSERVER(self)) {
PutObserverInServer ();
}
}
}
else if(self.killindicator_teamchange == -2)
{
- if(g_ca)
- self.caplayer = 0;
if(blockSpectators)
- sprint(self, strcat("^7You have to become a player within the next ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
PutObserverInServer();
}
else
SV_ChangeTeam(self.killindicator_teamchange - 1);
+ self.killindicator_teamchange = 0;
}
void ClientKill_Now()
{
if(self.cnt <= 10)
setmodel(self, strcat("models/sprites/", ftos(self.cnt), ".spr32"));
- if(clienttype(self.owner) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(self.owner))
{
if(self.cnt <= 10)
- AnnounceTo(self.owner, strcat(ftos(self.cnt), ""));
+ { Send_Notification(NOTIF_ONE, self.owner, MSG_ANNCE, Announcer_PickNumber(self.cnt)); }
}
self.nextthink = time + 1;
self.cnt -= 1;
self.clientkill_nexttime = time + killtime + autocvar_g_balance_kill_antispam;
}
- if(killtime <= 0 || self.classname != "player" || self.deadflag != DEAD_NO)
+ if(killtime <= 0 || !IS_PLAYER(self) || self.deadflag != DEAD_NO)
{
ClientKill_Now();
}
if(targetteam == 0) // just die
{
self.killindicator.colormod = '0 0 0';
- if(clienttype(self) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(self))
if(self.killindicator.cnt > 0)
- Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "^1Suicide in %d seconds", 1, self.killindicator.cnt);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_SUICIDE, self.killindicator.cnt);
}
else if(targetteam == -1) // auto
{
self.killindicator.colormod = '0 1 0';
- if(clienttype(self) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(self))
if(self.killindicator.cnt > 0)
- Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "Changing team in %d seconds", 1, self.killindicator.cnt);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_AUTO, self.killindicator.cnt);
}
else if(targetteam == -2) // spectate
{
self.killindicator.colormod = '0.5 0.5 0.5';
- if(clienttype(self) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(self))
if(self.killindicator.cnt > 0)
- Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "Spectating in %d seconds", 1, self.killindicator.cnt);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_SPECTATE, self.killindicator.cnt);
}
else
{
- self.killindicator.colormod = TeamColor(targetteam);
+ self.killindicator.colormod = Team_ColorRGB(targetteam);
- if(clienttype(self) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(self))
if(self.killindicator.cnt > 0)
- Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, strcat("Changing to ", ColoredTeamName(targetteam), " in %d seconds"), 1, self.killindicator.cnt);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, APP_TEAM_NUM_4(targetteam, CENTER_TEAMCHANGE_), self.killindicator.cnt);
}
}
void ClientKill (void)
{
- if (gameover)
- return;
-
- if((g_arena || g_ca) && ((champion && IS_PLAYER(champion) && player_count > 1) || player_count == 1)) // don't allow a kill in this case either
- {
- // do nothing
- }
- else if(self.freezetag_frozen)
- {
- // do nothing
- }
- else
- ClientKill_TeamChange(0);
+ if(gameover) return;
+ if(self.player_blocked) return;
+ if(self.freezetag_frozen) return;
-
++
+ ClientKill_TeamChange(0);
}
void CTS_ClientKill (entity e) // silent version of ClientKill, used when player finishes a CTS run. Useful to prevent cheating by running back to the start line and starting out with more speed
stuffcmd(e, "cl_cmd settemp cl_movecliptokeyboard 2\n");
if(autocvar_g_antilag == 3) // client side hitscan
stuffcmd(e, "cl_cmd settemp cl_prydoncursor_notrace 0\n");
- if(sv_gentle)
+ if(autocvar_sv_gentle)
stuffcmd(e, "cl_cmd settemp cl_gentle 1\n");
/*
* we no longer need to stuff this. Remove this comment block if you feel
Called when a client connects to the server
=============
*/
- string ColoredTeamName(float t);
void DecodeLevelParms (void);
//void dom_player_join_team(entity pl);
void set_dom_state(entity e);
{
float t;
- if(self.flags & FL_CLIENT)
+ if(IS_CLIENT(self))
{
print("Warning: ClientConnect, but already connected!\n");
return;
DecodeLevelParms();
#ifdef WATERMARK
- sprint(self, strcat("^4SVQC Build information: ^1", WATERMARK, "\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_WATERMARK, WATERMARK);
#endif
self.classname = "player_joining";
// identify the right forced team
if(autocvar_g_campaign)
{
- if(clienttype(self) == CLIENTTYPE_REAL) // only players, not bots
+ if(IS_REAL_CLIENT(self)) // only players, not bots
{
switch(autocvar_g_campaign_forceteam)
{
- case 1: self.team_forced = COLOR_TEAM1; break;
- case 2: self.team_forced = COLOR_TEAM2; break;
- case 3: self.team_forced = COLOR_TEAM3; break;
- case 4: self.team_forced = COLOR_TEAM4; break;
+ case 1: self.team_forced = NUM_TEAM_1; break;
+ case 2: self.team_forced = NUM_TEAM_2; break;
+ case 3: self.team_forced = NUM_TEAM_3; break;
+ case 4: self.team_forced = NUM_TEAM_4; break;
default: self.team_forced = 0;
}
}
}
else if(PlayerInIDList(self, autocvar_g_forced_team_red))
- self.team_forced = COLOR_TEAM1;
+ self.team_forced = NUM_TEAM_1;
else if(PlayerInIDList(self, autocvar_g_forced_team_blue))
- self.team_forced = COLOR_TEAM2;
+ self.team_forced = NUM_TEAM_2;
else if(PlayerInIDList(self, autocvar_g_forced_team_yellow))
- self.team_forced = COLOR_TEAM3;
+ self.team_forced = NUM_TEAM_3;
else if(PlayerInIDList(self, autocvar_g_forced_team_pink))
- self.team_forced = COLOR_TEAM4;
+ self.team_forced = NUM_TEAM_4;
else if(autocvar_g_forced_team_otherwise == "red")
- self.team_forced = COLOR_TEAM1;
+ self.team_forced = NUM_TEAM_1;
else if(autocvar_g_forced_team_otherwise == "blue")
- self.team_forced = COLOR_TEAM2;
+ self.team_forced = NUM_TEAM_2;
else if(autocvar_g_forced_team_otherwise == "yellow")
- self.team_forced = COLOR_TEAM3;
+ self.team_forced = NUM_TEAM_3;
else if(autocvar_g_forced_team_otherwise == "pink")
- self.team_forced = COLOR_TEAM4;
+ self.team_forced = NUM_TEAM_4;
else if(autocvar_g_forced_team_otherwise == "spectate")
self.team_forced = -1;
else if(autocvar_g_forced_team_otherwise == "spectator")
PlayerStats_AddEvent(sprintf("kills-%d", self.playerid));
- if(clienttype(self) == CLIENTTYPE_BOT)
+ if(IS_BOT_CLIENT(self))
PlayerStats_AddPlayer(self);
if(autocvar_sv_eventlog)
- GameLogEcho(strcat(":join:", ftos(self.playerid), ":", ftos(num_for_edict(self)), ":", ((clienttype(self) == CLIENTTYPE_REAL) ? self.netaddress : "bot"), ":", self.netname));
+ GameLogEcho(strcat(":join:", ftos(self.playerid), ":", ftos(num_for_edict(self)), ":", ((IS_REAL_CLIENT(self)) ? self.netaddress : "bot"), ":", self.netname));
LogTeamchange(self.playerid, self.team, 1);
self.netname_previous = strzone(self.netname);
- bprint("^4", self.netname, "^4 connected");
-
- if(!IS_OBSERVER(self) && (g_domination || g_ctf))
- bprint(" and joined the ", ColoredTeamName(self.team));
-
- bprint("\n");
- if((self.classname == STR_PLAYER && teamplay))
++ if(IS_PLAYER(self) && teamplay)
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(self, INFO_JOIN_CONNECT_TEAM_), self.netname);
+ else
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_CONNECT, self.netname);
stuffcmd(self, strcat(clientstuff, "\n"));
stuffcmd(self, "cl_particles_reloadeffects\n"); // TODO do we still need this?
else
stuffcmd(self, "set _teams_available 0\n");
- if(g_arena || g_ca)
- {
- self.classname = "observer";
- if(g_arena)
- Spawnqueue_Insert(self);
- }
-
attach_entcs();
bot_relinkplayerlist();
self.spectatortime = time;
if(blockSpectators)
{
- sprint(self, strcat("^7You have to become a player within the next ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
}
self.jointime = time;
self.allowed_timeouts = autocvar_sv_timeout_number;
- if(clienttype(self) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(self))
{
+ if(!autocvar_g_campaign)
+ {
+ self.motd_actived_time = -1;
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage());
+ }
+
if(autocvar_g_bugrigs || WEPSET_EQ_AW(g_weaponarena_weapons, WEP_TUBA))
stuffcmd(self, "cl_cmd settemp chase_active 1\n");
}
CheatInitClient();
- if(!autocvar_g_campaign)
- Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), autocvar_welcome_message_time, 0);
-
CSQCMODEL_AUTOINIT();
self.model_randomizer = random();
-
- if not(IS_REAL_CLIENT(self))
- return;
-
- sv_notice_join();
-
- MUTATOR_CALLHOOK(ClientConnect);
+
- if(clienttype(self) == CLIENTTYPE_REAL)
++ if(IS_REAL_CLIENT(self))
+ sv_notice_join();
+
+ MUTATOR_CALLHOOK(ClientConnect);
}
/*
=============
if(self.vehicle)
vehicles_exit(VHEF_RELESE);
- if not(self.flags & FL_CLIENT)
+ if not(IS_CLIENT(self))
{
print("Warning: ClientDisconnect without ClientConnect\n");
return;
if(autocvar_sv_eventlog)
GameLogEcho(strcat(":part:", ftos(self.playerid)));
- bprint ("^4",self.netname);
- bprint ("^4 disconnected\n");
+
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_DISCONNECT, self.netname);
- DropAllRunes(self);
MUTATOR_CALLHOOK(ClientDisconnect);
Portal_ClearAll(self);
bot_relinkplayerlist();
- if(g_arena)
- {
- Spawnqueue_Unmark(self);
- Spawnqueue_Remove(self);
- }
-
accuracy_free(self);
ClientData_Detach();
PlayerScore_Detach(self);
void play_countdown(float finished, string samp)
{
- if(clienttype(self) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(self))
if(floor(finished - time - frametime) != floor(finished - time))
if(finished - time < 6)
sound (self, CH_INFO, samp, VOL_BASE, ATTN_NORM);
self.alpha = default_player_alpha;
self.exteriorweaponentity.alpha = default_weapon_alpha;
self.items &~= IT_STRENGTH;
- sprint(self, "^3Invisibility has worn off\n");
+ //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_INVISIBILITY, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_INVISIBILITY);
}
}
else
self.alpha = g_minstagib_invis_alpha;
self.exteriorweaponentity.alpha = g_minstagib_invis_alpha;
self.items |= IT_STRENGTH;
- sprint(self, "^3You are invisible\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_INVISIBILITY, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_INVISIBILITY);
}
}
if (time > self.invincible_finished)
{
self.items = self.items - (self.items & IT_INVINCIBLE);
- sprint(self, "^3Speed has worn off\n");
+ //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_SPEED, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SPEED);
}
}
else
if (time < self.invincible_finished)
{
self.items = self.items | IT_INVINCIBLE;
- sprint(self, "^3You are on speed\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SPEED, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SPEED);
}
}
}
if (time > self.strength_finished)
{
self.items = self.items - (self.items & IT_STRENGTH);
- sprint(self, "^3Strength has worn off\n");
+ //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_STRENGTH, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_STRENGTH);
}
}
else
if (time < self.strength_finished)
{
self.items = self.items | IT_STRENGTH;
- sprint(self, "^3Strength infuses your weapons with devastating power\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_STRENGTH, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_STRENGTH);
}
}
if (self.items & IT_INVINCIBLE)
if (time > self.invincible_finished)
{
self.items = self.items - (self.items & IT_INVINCIBLE);
- sprint(self, "^3Shield has worn off\n");
+ //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_SHIELD, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SHIELD);
}
}
else
if (time < self.invincible_finished)
{
self.items = self.items | IT_INVINCIBLE;
- sprint(self, "^3Shield surrounds you\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SHIELD, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SHIELD);
}
}
if (self.items & IT_SUPERWEAPON)
{
self.superweapons_finished = 0;
self.items = self.items - (self.items & IT_SUPERWEAPON);
- sprint(self, "^3Superweapons have been lost\n");
+ //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_SUPERWEAPON_LOST, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_SUPERWEAPON_LOST);
}
else if (self.items & IT_UNLIMITED_SUPERWEAPONS)
{
{
self.items = self.items - (self.items & IT_SUPERWEAPON);
WEPSET_ANDNOT_EA(self, WEPBIT_SUPERWEAPONS);
- sprint(self, "^3Superweapons have broken down\n");
+ //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_SUPERWEAPON_BROKEN, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_SUPERWEAPON_BROKEN);
}
}
}
if (time < self.superweapons_finished || (self.items & IT_UNLIMITED_SUPERWEAPONS))
{
self.items = self.items | IT_SUPERWEAPON;
- sprint(self, "^3You now have a superweapon\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_SUPERWEAPON_PICKUP, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_SUPERWEAPON_PICKUP);
}
else
{
max_mod = regen_mod = rot_mod = limit_mod = 1;
- if (self.runes & RUNE_REGEN)
- {
- if (self.runes & CURSE_VENOM) // do we have both rune/curse?
- {
- regen_mod = autocvar_g_balance_rune_regen_combo_regenrate;
- max_mod = autocvar_g_balance_rune_regen_combo_hpmod;
- limit_mod = autocvar_g_balance_rune_regen_combo_limitmod;
- }
- else
- {
- regen_mod = autocvar_g_balance_rune_regen_regenrate;
- max_mod = autocvar_g_balance_rune_regen_hpmod;
- limit_mod = autocvar_g_balance_rune_regen_limitmod;
- }
- }
- else if (self.runes & CURSE_VENOM)
- {
- max_mod = autocvar_g_balance_curse_venom_hpmod;
- if (self.runes & RUNE_REGEN) // do we have both rune/curse?
- rot_mod = autocvar_g_balance_rune_regen_combo_rotrate;
- else
- rot_mod = autocvar_g_balance_curse_venom_rotrate;
- limit_mod = autocvar_g_balance_curse_venom_limitmod;
- //if (!self.runes & RUNE_REGEN)
- // rot_mod = autocvar_g_balance_curse_venom_rotrate;
- }
maxh = maxh * max_mod;
//maxa = maxa * max_mod;
//maxf = maxf * max_mod;
limita = limita * limit_mod;
//limitf = limitf * limit_mod;
- if(g_lms && g_ca)
+ if(g_ca)
rot_mod = 0;
if (!g_minstagib && !g_ca && (!g_lms || autocvar_g_lms_regenerate))
self.dmg_inflictor = spectatee.dmg_inflictor;
self.v_angle = spectatee.v_angle;
self.angles = spectatee.v_angle;
- self.stat_respawn_time = spectatee.stat_respawn_time;
if(!self.BUTTON_USE)
self.fixangle = TRUE;
setorigin(self, spectatee.origin);
if (self == self.enemy)
return 0;
- if(self.enemy.classname != "player")
+ if not(IS_PLAYER(self.enemy))
return 0;
SpectateCopy(self.enemy);
if (other)
self.enemy = other;
- if(self.enemy.classname == "player") {
+ if(IS_PLAYER(self.enemy)) {
/*if(self.enemy.vehicle)
{
{
self.respawn_countdown = number - 1;
if(ceil(self.respawn_time - (time + 0.5)) == number) // only say it if it is the same number even in 0.5s; to prevent overlapping sounds
- AnnounceTo(self, strcat(ftos(number), ""));
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, Announcer_PickNumber(number));
}
}
}
- .float prevent_join_msgtime;
void LeaveSpectatorMode()
{
- if(nJoinAllowed(self)) {
- if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) {
+ if(self.caplayer)
+ return;
+ if(nJoinAllowed(self))
+ {
+ if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0)
+ {
self.classname = "player";
if(autocvar_g_campaign || autocvar_g_balance_teams)
- JoinBestTeam(self, FALSE, TRUE);
+ { JoinBestTeam(self, FALSE, TRUE); }
if(autocvar_g_campaign)
- campaign_bots_may_start = 1;
+ { campaign_bots_may_start = 1; }
- PutClientInServer();
-
- if(IS_PLAYER(self))
- bprint ("^4", self.netname, "^4 is playing now\n");
-
- if(!autocvar_g_campaign)
- if (time < self.jointime + autocvar_welcome_message_time)
- Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD); // clear MOTD
+ Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_PREVENT_JOIN);
- if (self.prevent_join_msgtime)
- {
- Send_CSQC_Centerprint_Generic_Expire(self, CPID_PREVENT_JOIN);
- self.prevent_join_msgtime = 0;
- }
+ PutClientInServer();
- return;
- } else {
- if (g_ca && self.caplayer) {
- } // do nothing
- else
- stuffcmd(self,"menu_showteamselect\n");
- return;
+ if(IS_PLAYER(self)) { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_PLAY, self.netname); }
}
+ else
+ stuffcmd(self, "menu_showteamselect\n");
}
- else {
- //player may not join because of g_maxplayers is set
- if (time - self.prevent_join_msgtime > 2)
- {
- Send_CSQC_Centerprint_Generic(self, CPID_PREVENT_JOIN, PREVENT_JOIN_TEXT, 0, 0);
- self.prevent_join_msgtime = time;
- }
+ else
+ {
+ // Player may not join because g_maxplayers is set
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_JOIN_PREVENT);
}
}
return maxclients - totalClients;
float currentlyPlaying = 0;
- FOR_EACH_REALPLAYER(e)
- currentlyPlaying += 1;
+ FOR_EACH_REALCLIENT(e)
- if(e.classname == "player" || e.caplayer == 1)
++ if(IS_PLAYER(e) || e.caplayer == 1)
+ currentlyPlaying += 1;
if(currentlyPlaying < autocvar_g_maxplayers)
return min(maxclients - totalClients, autocvar_g_maxplayers - currentlyPlaying);
* g_maxplayers_spectator_blocktime seconds
*/
void checkSpectatorBlock() {
- if(self.classname == "spectator" || self.classname == "observer") {
+ if(IS_SPEC(self) || IS_OBSERVER(self)) {
if( time > (self.spectatortime + autocvar_g_maxplayers_spectator_blocktime) ) {
- sprint(self, "^7You were kicked from the server because you are spectator and spectators aren't allowed at the moment.\n");
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_QUIT_KICK_SPECTATING);
dropclient(self);
}
}
}
- .float motd_actived_time; // used for both motd and campaign_message
void PrintWelcomeMessage()
{
- if (self.motd_actived_time == 0) { // is there already a message showing?
+ if(self.motd_actived_time == 0)
+ {
if (autocvar_g_campaign) {
- if ((self.classname == "player" && self.BUTTON_INFO) || (self.classname != "player")) {
+ if ((IS_PLAYER(self) && self.BUTTON_INFO) || (!IS_PLAYER(self))) {
self.motd_actived_time = time;
- Send_CSQC_Centerprint_Generic(self, CPID_MOTD, campaign_message, -1, 0);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, campaign_message);
}
} else {
- if ((time - self.jointime > autocvar_welcome_message_time) && self.BUTTON_INFO) {
+ if (self.BUTTON_INFO) {
self.motd_actived_time = time;
- Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), -1, 0);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage());
}
}
- } else { // showing MOTD or campaign message
+ }
+ else if(self.motd_actived_time > 0) // showing MOTD or campaign message
+ {
if (autocvar_g_campaign) {
if (self.BUTTON_INFO)
self.motd_actived_time = time;
- else if ((time - self.motd_actived_time > 2) && self.classname == "player") { // hide it some seconds after BUTTON_INFO has been released
+ else if ((time - self.motd_actived_time > 2) && IS_PLAYER(self)) { // hide it some seconds after BUTTON_INFO has been released
self.motd_actived_time = 0;
- Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD);
+ Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD);
}
} else {
- if ((time - self.jointime) > autocvar_welcome_message_time) {
- if (self.BUTTON_INFO)
- self.motd_actived_time = time;
- else if (time - self.motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
- self.motd_actived_time = 0;
- Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD);
- }
+ if (self.BUTTON_INFO)
+ self.motd_actived_time = time;
+ else if (time - self.motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
+ self.motd_actived_time = 0;
+ Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD);
}
}
}
+ else //if(self.motd_actived_time < 0) // just connected, motd is active
+ {
+ if(self.BUTTON_INFO) // BUTTON_INFO hides initial MOTD
+ self.motd_actived_time = -2; // wait until BUTTON_INFO gets released
+ else if(self.motd_actived_time == -2 || IS_PLAYER(self) || time - self.jointime > autocvar_welcome_message_time)
+ {
+ // instanctly hide MOTD
+ self.motd_actived_time = 0;
+ Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD);
+ }
+ }
}
void ObserverThink()
}
}
}
-
- PrintWelcomeMessage();
}
void SpectatorThink()
PutObserverInServer();
}
- PrintWelcomeMessage();
self.flags |= FL_CLIENT | FL_NOTARGET;
}
void PlayerUseKey()
{
- if(self.classname != "player")
+ if not(IS_PLAYER(self))
return;
if(self.vehicle)
MUTATOR_CALLHOOK(PlayerUseKey);
}
- .float touchexplode_time;
-
/*
=============
PlayerPreThink
WarpZone_PlayerPhysics_FixVAngle();
self.stat_game_starttime = game_starttime;
+ self.stat_round_starttime = round_starttime;
self.stat_allow_oldnexbeam = autocvar_g_allow_oldnexbeam;
self.stat_leadlimit = autocvar_leadlimit;
- if(g_arena || (g_ca && !allowed_to_spawn))
- self.stat_respawn_time = 0;
- else
- self.stat_respawn_time = self.respawn_time;
-
if(frametime)
{
// physics frames: update anticheat stuff
{
// notify release users if connecting to git
dprint("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n");
- sprint(self, strcat("\{1}^1NOTE: ^7the server is running ^3Xonotic ", autocvar_g_xonoticversion, " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_BETA, autocvar_g_xonoticversion, self.cvar_g_xonoticversion);
}
else
{
{
// give users new version
dprint("^1NOTE^7 to ", self.netname, "^7 - ^3Xonotic ", autocvar_g_xonoticversion, "^7 is out, and you still have ^3Xonotic ", self.cvar_g_xonoticversion, "^1 - get the update from ^4http://www.xonotic.org/^1!\n");
- sprint(self, strcat("\{1}^1NOTE: ^3Xonotic ", autocvar_g_xonoticversion, "^7 is out, and you still have ^3Xonotic ", self.cvar_g_xonoticversion, "^1 - get the update from ^4http://www.xonotic.org/^1!\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_OUTDATED, autocvar_g_xonoticversion, self.cvar_g_xonoticversion);
}
else if(r > 0)
{
// notify users about old server version
print("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n");
- sprint(self, strcat("\{1}^1NOTE: ^7the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_OLD, autocvar_g_xonoticversion, self.cvar_g_xonoticversion);
}
}
}
// GOD MODE info
if(!(self.flags & FL_GODMODE)) if(self.max_armorvalue)
{
- sprint(self, strcat("godmode saved you ", ftos(self.max_armorvalue), " units of damage, cheater!\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_GODMODE_OFF, self.max_armorvalue);
self.max_armorvalue = 0;
}
self.usekeypressed = self.BUTTON_USE;
}
- PrintWelcomeMessage();
- if(clienttype(self) == CLIENTTYPE_REAL)
++ if(IS_REAL_CLIENT(self))
+ PrintWelcomeMessage();
- if(IS_PLAYER(self)) {
- // if(self.netname == "Wazat")
- // bprint(self.classname, "\n");
- if(self.classname == "player") {
++ if(IS_PLAYER(self))
++ {
CheckRules_Player();
if (self.deadflag != DEAD_NO)
{
- float button_pressed, force_respawn;
if(self.personal && g_race_qualifying)
{
if(time > self.respawn_time)
{
self.respawn_time = time + 1; // only retry once a second
+ self.stat_respawn_time = self.respawn_time;
respawn();
self.impulse = 141;
}
}
else
{
+ float button_pressed;
if(frametime)
player_anim();
button_pressed = (self.BUTTON_ATCK || self.BUTTON_JUMP || self.BUTTON_ATCK2 || self.BUTTON_HOOK || self.BUTTON_USE);
- force_respawn = (g_lms || g_ca || g_cts || autocvar_g_forced_respawn);
+
if (self.deadflag == DEAD_DYING)
{
- if(force_respawn)
+ if(self.respawn_flags & RESPAWN_FORCE)
self.deadflag = DEAD_RESPAWNING;
else if(!button_pressed)
self.deadflag = DEAD_DEAD;
respawn();
}
}
+
ShowRespawnCountdown();
+
+ if(self.respawn_flags & RESPAWN_SILENT)
+ self.stat_respawn_time = 0;
+ else
+ self.stat_respawn_time = self.respawn_time;
}
// if respawning, invert stat_respawn_time to indicate this, the client translates it
return;
}
- // FIXME from now on self.deadflag is always 0 (and self.health is never < 1)
- // so (self.deadflag == DEAD_NO) is always true in the code below
-
- if(g_touchexplode)
- if(time > self.touchexplode_time)
- if(IS_PLAYER(self))
- if(self.deadflag == DEAD_NO)
- if not(IS_INDEPENDENT_PLAYER(self))
- FOR_EACH_PLAYER(other) if(self != other)
- {
- if(time > other.touchexplode_time)
- if(other.deadflag == DEAD_NO)
- if not(IS_INDEPENDENT_PLAYER(other))
- if(boxesoverlap(self.absmin, self.absmax, other.absmin, other.absmax))
- {
- PlayerTouchExplode(self, other);
- self.touchexplode_time = other.touchexplode_time = time + 0.2;
- }
- }
if(g_lms && !self.deadflag && autocvar_g_lms_campcheck_interval)
{
//sprint(self, "distance: ", ftos(self.lms_traveled_distance), "\n");
if(self.lms_traveled_distance < autocvar_g_lms_campcheck_distance)
{
- centerprint(self, autocvar_g_lms_campcheck_message);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_LMS_CAMPCHECK);
// FIXME KadaverJack: gibbing player here causes playermodel to bounce around, instead of eye.md3
// I wasn't able to find out WHY that happens, so I put a workaround in place that shall prevent players from being gibbed :(
- Damage(self, self, self, bound(0, autocvar_g_lms_campcheck_damage, self.health + self.armorvalue * autocvar_g_balance_armor_blockpercent + 5), DEATH_CAMP, self.origin, '0 0 0');
+ if(self.vehicle)
+ Damage(self.vehicle, self, self, autocvar_g_lms_campcheck_damage * 2, DEATH_CAMP, self.vehicle.origin, '0 0 0');
+ else
+ Damage(self, self, self, bound(0, autocvar_g_lms_campcheck_damage, self.health + self.armorvalue * autocvar_g_balance_armor_blockpercent + 5), DEATH_CAMP, self.origin, '0 0 0');
}
self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval;
self.lms_traveled_distance = 0;
if (intermission_running)
IntermissionThink (); // otherwise a button could be missed between
return;
- } else if(self.classname == "observer") {
+ } else if(IS_OBSERVER(self)) {
ObserverThink();
- } else if(self.classname == "spectator") {
+ } else if(IS_SPEC(self)) {
SpectatorThink();
}
float oldspectatee_status;
oldspectatee_status = self.spectatee_status;
- if(self.classname == "spectator")
+ if(IS_SPEC(self))
self.spectatee_status = num_for_edict(self.enemy);
- else if(self.classname == "observer")
+ else if(IS_OBSERVER(self))
self.spectatee_status = num_for_edict(self);
else
self.spectatee_status = 0;
{
if (time - self.parm_idlesince < 1) // instead of (time == self.parm_idlesince) to support sv_maxidle <= 10
{
- if(self.idlekick_lasttimeleft)
- {
- Send_CSQC_Centerprint_Generic_Expire(self, CPID_DISCONNECT_IDLING);
- self.idlekick_lasttimeleft = 0;
- }
+ if(self.idlekick_lasttimeleft) { self.idlekick_lasttimeleft = 0; }
}
else
{
if(timeleft == min(10, sv_maxidle - 1)) // - 1 to support sv_maxidle <= 10
{
if(!self.idlekick_lasttimeleft)
- Send_CSQC_Centerprint_Generic(self, CPID_DISCONNECT_IDLING, "^3Stop idling!\n^3Disconnecting in %d seconds...", 1, timeleft);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_DISCONNECT_IDLING, timeleft);
}
if(timeleft <= 0)
{
- bprint("^3", self.netname, "^3 was kicked for idling.\n");
- AnnounceTo(self, "terminated");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_KICK_IDLING, self.netname);
dropclient(self);
return;
}
else if(timeleft <= 10)
{
if(timeleft != self.idlekick_lasttimeleft)
- AnnounceTo(self, ftos(timeleft));
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, Announcer_PickNumber(timeleft));
self.idlekick_lasttimeleft = timeleft;
}
}
//CheckPlayerJump();
- if(self.classname == "player") {
+ if(IS_PLAYER(self)) {
CheckRules_Player();
UpdateChatBubble();
if (self.impulse)
rigvel_z -= frametime * autocvar_sv_gravity; // 4x gravity plays better
rigvel_xy = vec2(rigvel);
- if(g_bugrigs_planar_movement_car_jumping && !g_touchexplode) // touchexplode is a better way to handle collisions
+ if(g_bugrigs_planar_movement_car_jumping)
mt = MOVE_NORMAL;
else
mt = MOVE_NOMONSTERS;
else if(g_keepaway)
maxspd_mod *= autocvar_g_keepaway_ballcarrier_highspeed;
- if(g_runematch)
- {
- if(self.runes & RUNE_SPEED)
- {
- if(self.runes & CURSE_SLOW)
- maxspd_mod *= autocvar_g_balance_rune_speed_combo_highspeed;
- else
- maxspd_mod *= autocvar_g_balance_rune_speed_highspeed;
- }
- else if(self.runes & CURSE_SLOW)
- {
- maxspd_mod *= autocvar_g_balance_curse_slow_highspeed;
- }
- }
maxspd_mod *= autocvar_g_movement_highspeed;
// fix physics stats for g_movement_highspeed
self.punchvector = '0 0 0';
}
- if (clienttype(self) == CLIENTTYPE_BOT)
+ if (IS_BOT_CLIENT(self))
{
if(playerdemo_read())
return;
self.items &~= IT_USING_JETPACK;
- if(self.classname == "player")
+ if(IS_PLAYER(self))
{
if(self.race_penalty)
if(time > self.race_penalty)
if(self.conveyor.state)
self.velocity -= self.conveyor.movedir;
- if(self.classname != "player")
+ if not(IS_PLAYER(self))
{
maxspd_mod = autocvar_sv_spectator_speed_multiplier;
if(!self.spectatorspeed)
}
if(self.flags & FL_ONGROUND)
- if(self.classname == "player") // no fall sounds for observers thank you very much
+ if(IS_PLAYER(self)) // no fall sounds for observers thank you very much
if(self.wasFlying)
{
self.wasFlying = 0;
if(IsFlying(self))
self.wasFlying = 1;
- if(self.classname == "player")
+ if(IS_PLAYER(self))
CheckPlayerJump();
if (self.flags & FL_WATERJUMP )
self.teleport_time = 0;
}
}
- else if (g_bugrigs && self.classname == "player")
+ else if (g_bugrigs && IS_PLAYER(self))
{
RaceCarPhysics();
}
}
}
- if((g_cts || g_race) && self.classname != "observer") {
+ if((g_cts || g_race) && !IS_OBSERVER(self)) {
if(vlen(self.velocity - self.velocity_z * '0 0 1') > speedaward_speed) {
speedaward_speed = vlen(self.velocity - self.velocity_z * '0 0 1');
speedaward_holder = self.netname;
}
void ClientKill_Now_TeamChange();
- void freezetag_CheckWinner();
void PlayerDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
{
float valid_damage_for_weaponstats;
float excess;
- if((g_arena && numspawned < 2) || (g_ca && allowed_to_spawn) && !inWarmupStage)
- return;
-
dh = max(self.health, 0);
da = max(self.armorvalue, 0);
//self.pushltime = 0;
self.istypefrag = 0;
}
- else if(attacker.classname == "player")
+ else if(IS_PLAYER(attacker))
{
self.pusher = attacker;
self.pushltime = time + autocvar_g_maxpushtime;
{
self.pain_finished = time + 0.5; //Supajoe
- if(sv_gentle < 1) {
+ if(autocvar_sv_gentle < 1) {
if(self.classname != "body") // pain anim is BORKED on our ZYMs, FIXME remove this once we have good models
{
if (!self.animstate_override)
self.dmg_take = self.dmg_take + take;//max(take - 10, 0);
self.dmg_inflictor = inflictor;
- if(g_ca && self != attacker && attacker.classname == "player")
+ if(g_ca && self != attacker && IS_PLAYER(attacker))
PlayerScore_Add(attacker, SP_SCORE, (damage - excess) * autocvar_g_ca_damage2score_multiplier);
float abot, vbot, awep;
- abot = (clienttype(attacker) == CLIENTTYPE_BOT);
- vbot = (clienttype(self) == CLIENTTYPE_BOT);
+ abot = (IS_BOT_CLIENT(attacker));
+ vbot = (IS_BOT_CLIENT(self));
valid_damage_for_weaponstats = 0;
awep = 0;
- if(vbot || clienttype(self) == CLIENTTYPE_REAL)
- if(abot || clienttype(attacker) == CLIENTTYPE_REAL)
+ if(vbot || IS_REAL_CLIENT(self))
+ if(abot || IS_REAL_CLIENT(attacker))
if(attacker && self != attacker)
if(IsDifferentTeam(self, attacker))
{
if(valid_damage_for_weaponstats)
WeaponStats_LogKill(awep, abot, self.weapon, vbot);
- if(sv_gentle < 1) // TODO make a "gentle" version?
+ if(autocvar_sv_gentle < 1) // TODO make a "gentle" version?
if(sound_allowed(MSG_BROADCAST, attacker))
{
if(deathtype == DEATH_DROWN)
}
}
- if(!g_freezetag)
- {
- // become fully visible
- self.alpha = default_player_alpha;
- // throw a weapon
- SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon);
- }
-
// print an obituary message
Obituary (attacker, inflictor, self, deathtype);
race_PreDie();
- DropAllRunes(self);
// increment frag counter for used weapon type
float w;
if(accuracy_isgooddamage(attacker, self))
attacker.accuracy.(accuracy_frags[w-1]) += 1;
- if(deathtype == DEATH_HURTTRIGGER && g_freezetag)
- {
- PutClientInServer();
- count_alive_players(); // re-count players
- freezetag_CheckWinner();
- return;
- }
-
frag_attacker = attacker;
frag_inflictor = inflictor;
frag_target = self;
+ frag_deathtype = deathtype;
MUTATOR_CALLHOOK(PlayerDies);
+
weapon_action(self.weapon, WR_PLAYERDEATH);
RemoveGrapplingHook(self);
Portal_ClearAllLater(self);
- if(clienttype(self) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(self))
{
- stuffcmd(self, "-zoom\n");
self.fixangle = TRUE;
//msg_entity = self;
//WriteByte (MSG_ONE, SVC_SETANGLE);
//WriteAngle (MSG_ONE, 80);
}
- if(defer_ClientKill_Now_TeamChange) // TODO does this work with FreezeTag?
- ClientKill_Now_TeamChange();
-
- if(g_arena)
- Spawnqueue_Unmark(self);
+ if(defer_ClientKill_Now_TeamChange)
+ ClientKill_Now_TeamChange(); // can turn player into spectator
- if(g_freezetag)
+ // player could have been miraculously resuscitated ;)
+ // e.g. players in freezetag get frozen, they don't really die
- if(self.health >= 1 || self.classname != "player")
++ if(self.health >= 1 || !IS_PLAYER(self))
return;
// when we get here, player actually dies
- // clear waypoints (do this AFTER FreezeTag)
+
+ // clear waypoints
WaypointSprite_PlayerDead();
+ // throw a weapon
+ SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon);
+ // become fully visible
+ self.alpha = default_player_alpha;
// make the corpse upright (not tilted)
self.angles_x = 0;
self.angles_z = 0;
self.respawn_countdown = 10; // first number to count down from is 10
else
self.respawn_countdown = -1; // do not count down
+
+ if(g_lms || g_cts || autocvar_g_forced_respawn)
+ self.respawn_flags = self.respawn_flags | RESPAWN_FORCE;
+
self.death_time = time;
if (random() < 0.5)
animdecide_setstate(self, self.anim_state | ANIMSTATE_DEAD1, TRUE);
// set up to fade out later
SUB_SetFade (self, time + 6 + random (), 1);
- if(sv_gentle > 0 || autocvar_ekg) {
+ if(autocvar_sv_gentle > 0 || autocvar_ekg) {
// remove corpse
PlayerCorpseDamage (inflictor, attacker, autocvar_sv_gibhealth+1.0, deathtype, hitloc, force);
}
msgin = formatmessage(msgin);
- if(source.classname != "player")
+ if not(IS_PLAYER(source))
colorstr = "^0"; // black for spectators
else if(teamplay)
colorstr = Team_ColorCode(source.team);
}
if(!privatesay)
- if(source.classname != "player")
+ if not(IS_PLAYER(source))
{
if not(intermission_running)
if(teamsay || (autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !(inWarmupStage || gameover)))
if(sourcecmsgstr != "" && !privatesay)
centerprint(source, sourcecmsgstr);
}
- else if(privatesay) // private message, between 2 people only, not sent to server console
+ else if(privatesay) // private message, between 2 people only
{
sprint(source, sourcemsgstr);
sprint(privatesay, msgstr);
+ if not(autocvar_g_chat_tellprivacy) { dedicated_print(msgstr); } // send to server console too if "tellprivacy" is disabled
if(cmsgstr != "")
centerprint(privatesay, cmsgstr);
}
else if(teamsay > 0) // team message, only sent to team mates
{
sprint(source, sourcemsgstr);
- //print(msgstr); // send to server console too
+ dedicated_print(msgstr); // send to server console too
if(sourcecmsgstr != "")
centerprint(source, sourcecmsgstr);
FOR_EACH_REALPLAYER(head) if(head.team == source.team)
else if(teamsay < 0) // spectator message, only sent to spectators
{
sprint(source, sourcemsgstr);
- //print(msgstr); // send to server console too
+ dedicated_print(msgstr); // send to server console too
- FOR_EACH_REALCLIENT(head) if(head.classname != "player")
+ FOR_EACH_REALCLIENT(head) if not(IS_PLAYER(head))
if(head != source)
sprint(head, msgstr);
}
else if(sourcemsgstr != msgstr) // trimmed/server fixed message, sent to all players
{
sprint(source, sourcemsgstr);
- //print(msgstr); // send to server console too
+ dedicated_print(msgstr); // send to server console too
FOR_EACH_REALCLIENT(head)
if(head != source)
sprint(head, msgstr);
if(self.pusher)
{
msg_entity = self;
- if(clienttype(msg_entity) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(msg_entity))
soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTN_NONE);
}
break;
break;
if(!sv_taunt)
break;
- if(sv_gentle)
+ if(autocvar_sv_gentle)
break;
tauntrand = random();
msg_entity = self;
}
break;
case VOICETYPE_TAUNT:
- if(self.classname == "player")
+ if(IS_PLAYER(self))
if(self.deadflag == DEAD_NO)
animdecide_setaction(self, ANIMACTION_TAUNT, TRUE);
if(!sv_taunt)
break;
- if(sv_gentle)
+ if(autocvar_sv_gentle)
break;
msg_entity = self;
if (msg_entity.cvar_cl_voice_directional >= 1)
if(self.pusher)
{
msg_entity = self.pusher;
- if(clienttype(msg_entity) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(msg_entity))
{
if(msg_entity.cvar_cl_voice_directional == 1)
soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_MIN);
if(self.pusher)
{
msg_entity = self.pusher;
- if(clienttype(msg_entity) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(msg_entity))
{
if(msg_entity.cvar_cl_voice_directional == 1)
soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_MIN);
soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE);
}
msg_entity = self;
- if(clienttype(msg_entity) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(msg_entity))
soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTN_NONE);
}
break;
break;
if(!sv_taunt)
break;
- if(sv_gentle)
+ if(autocvar_sv_gentle)
break;
tauntrand = random();
FOR_EACH_REALCLIENT(msg_entity)
}
break;
case VOICETYPE_TAUNT:
- if(self.classname == "player")
+ if(IS_PLAYER(self))
if(self.deadflag == DEAD_NO)
animdecide_setaction(self, ANIMACTION_TAUNT, TRUE);
if(!sv_taunt)
break;
- if(sv_gentle)
+ if(autocvar_sv_gentle)
break;
FOR_EACH_REALCLIENT(msg_entity)
{
FakeGlobalSound(self.sample, CH_VOICE, voicetype);
}
- void MoveToTeam(entity client, float team_colour, float type, float show_message)
+ void MoveToTeam(entity client, float team_colour, float type)
{
- // show_message
- // 0 (00) automove centerprint, admin message
- // 1 (01) automove centerprint, no admin message
- // 2 (10) no centerprint, admin message
- // 3 (11) no centerprint, no admin message
-
float lockteams_backup;
lockteams_backup = lockteams; // backup any team lock
TeamchangeFrags(client); // move the players frags
SetPlayerColors(client, team_colour - 1); // set the players colour
- Damage(client, client, client, 100000, ((show_message & 2) ? DEATH_QUIET : DEATH_AUTOTEAMCHANGE), client.origin, '0 0 0'); // kill the player
+ Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE, client.origin, '0 0 0'); // kill the player
lockteams = lockteams_backup; // restore the team lock
LogTeamchange(client.playerid, client.team, type);
-
- if not(show_message & 1) // admin message
- sprint(client, strcat("\{1}\{13}^3", admin_name(), "^7: You have been moved to the ", Team_ColorNameLowerCase(team_colour), " team\n")); // send a chat message
-
- bprint(strcat(client.netname, " joined the ", ColoredTeamName(client.team), "\n"));
}
float t;
t = 1.0 / g_weaponratefactor;
- if(g_runematch)
- {
- if(self.runes & RUNE_SPEED)
- {
- if(self.runes & CURSE_SLOW)
- t = t * autocvar_g_balance_rune_speed_combo_atkrate;
- else
- t = t * autocvar_g_balance_rune_speed_atkrate;
- }
- else if(self.runes & CURSE_SLOW)
- {
- t = t * autocvar_g_balance_curse_slow_atkrate;
- }
- }
-
return t;
}
lag = ANTILAG_LATENCY(player);
if(lag < 0.001)
lag = 0;
- if(clienttype(player) != CLIENTTYPE_REAL)
+ if not(IS_REAL_CLIENT(player))
lag = 0; // only antilag for clients
org = player.origin + player.view_ofs;
traceline_antilag_force(player, org, org + screenforward * MAX_SHOT_DISTANCE, MOVE_NORMAL, player, lag);
- if(trace_ent.flags & FL_CLIENT)
+ if(IS_CLIENT(trace_ent))
{
antilag_takeback(trace_ent, time - lag);
hitplot = W_HitPlotNormalizedUntransform(org, trace_ent, screenforward, screenright, screenup, trace_endpos);
if (!trace_ent.takedamage)
{
traceline_antilag_force (ent, w_shotorg, w_shotorg + w_shotdir * range, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
- if (trace_ent.takedamage && trace_ent.classname == "player")
+ if (trace_ent.takedamage && IS_PLAYER(trace_ent))
{
entity e;
e = trace_ent;
if (ent.cursor_trace_ent) // client was aiming at someone
if (ent.cursor_trace_ent != ent) // just to make sure
if (ent.cursor_trace_ent.takedamage) // and that person is killable
- if (ent.cursor_trace_ent.classname == "player") // and actually a player
+ if (IS_PLAYER(ent.cursor_trace_ent)) // and actually a player
{
// verify that the shot would miss without antilag
// (avoids an issue where guns would always shoot at their origin)
float CL_Weaponentity_CustomizeEntityForClient()
{
self.viewmodelforclient = self.owner;
- if(other.classname == "spectator")
+ if(IS_SPEC(other))
if(other.enemy == self.owner)
self.viewmodelforclient = other;
return TRUE;
if (!f)
{
if (complain)
- if(clienttype(cl) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(cl))
{
play2(cl, "weapons/unavailable.wav");
- sprint(cl, strcat("You don't have any ammo for the ^2", W_Name(wpn), "\n"));
Send_WeaponComplain (cl, wpn, W_Name(wpn), 0);
}
return FALSE;
// Report Proper Weapon Status / Modified Weapon Ownership Message
if (WEPSET_CONTAINS_AW(weaponsInMap, wpn))
{
- sprint(cl, strcat("You do not have the ^2", W_Name(wpn), "\n") );
- Send_WeaponComplain (cl, wpn, W_Name(wpn), 1);
+ Send_WeaponComplain(cl, wpn, W_Name(wpn), 1);
if(autocvar_g_showweaponspawns)
{
else
{
Send_WeaponComplain (cl, wpn, W_Name(wpn), 2);
- sprint(cl, strcat("The ^2", W_Name(wpn), "^7 is ^1NOT AVAILABLE^7 in this map\n") );
}
play2(cl, "weapons/unavailable.wav");
W_SwitchWeapon_Force(pl, ww);
}
- string PrimaryOrSecondary(float secondary)
- {
- if(secondary)
- return "secondary";
- else
- return "primary";
- }
-
.float prevdryfire;
.float prevwarntime;
float weapon_prepareattack_checkammo(float secondary)
{
if(time - self.prevwarntime > 1)
{
- sprint(self, strcat("^2", W_Name(self.weapon), " ", PrimaryOrSecondary(secondary), "^7 is unable to fire, but its ^2", PrimaryOrSecondary(1 - secondary), "^7 can.\n"));
+ Send_Notification(
+ NOTIF_ONE,
+ self,
+ MSG_MULTI,
+ ITEM_WEAPON_PRIMORSEC,
+ self.weapon,
+ secondary,
+ (1 - secondary)
+ );
}
self.prevwarntime = time;
}
if(!self.(self.current_ammo) && self.reload_ammo_min)
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
{
- if(clienttype(self) == CLIENTTYPE_REAL && self.reload_complain < time)
+ if(IS_REAL_CLIENT(self) && self.reload_complain < time)
{
play2(self, "weapons/unavailable.wav");
sprint(self, strcat("You don't have enough ammo to reload the ^2", W_Name(self.weapon), "\n"));
{
if(argv(1) != "")
{
- if(self.flags & FL_CLIENT)
+ if(IS_CLIENT(self))
{
self.version = ((argv(1) == "$gameversion") ? 1 : stof(argv(1)));
{
case CMD_REQUEST_COMMAND:
{
- if(self.flags & FL_CLIENT)
+ if(IS_CLIENT(self))
{
- if(self.classname != "player" && !lockteams && !g_arena)
+ if(!IS_PLAYER(self) && !lockteams && !g_arena)
{
if(nJoinAllowed(self))
{
- if(g_ca) { self.caplayer = 1; }
if(autocvar_g_campaign) { campaign_bots_may_start = 1; }
-
+
self.classname = "player";
PlayerScore_Clear(self);
- bprint ("^4", self.netname, "^4 is playing now\n");
+ Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_PREVENT_JOIN);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_PLAY, self.netname);
PutClientInServer();
}
else
{
//player may not join because of g_maxplayers is set
- centerprint(self, PREVENT_JOIN_TEXT);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_JOIN_PREVENT);
}
}
}
{
case CMD_REQUEST_COMMAND:
{
- if(self.flags & FL_CLIENT)
+ if(IS_CLIENT(self))
{
if(inWarmupStage || autocvar_sv_ready_restart || g_race_qualifying == 2)
{
if(!readyrestart_happened || autocvar_sv_ready_restart_repeatable)
{
+ if(time < game_starttime) // game is already restarting
+ return;
if (self.ready) // toggle
{
self.ready = FALSE;
{
if(argv(1) != "")
{
- if(self.flags & FL_CLIENT)
+ if(IS_CLIENT(self))
{
if(teamplay)
if not(self.team_forced > 0)
switch(argv(1))
{
- case "red": selection = COLOR_TEAM1; break;
- case "blue": selection = COLOR_TEAM2; break;
- case "yellow": selection = COLOR_TEAM3; break;
- case "pink": selection = COLOR_TEAM4; break;
+ case "red": selection = NUM_TEAM_1; break;
+ case "blue": selection = NUM_TEAM_2; break;
+ case "yellow": selection = NUM_TEAM_3; break;
+ case "pink": selection = NUM_TEAM_4; break;
case "auto": selection = (-1); break;
default: selection = 0; break;
{
case CMD_REQUEST_COMMAND:
{
- if(self.flags & FL_CLIENT)
+ if(IS_CLIENT(self))
{
if(g_arena) { return; }
if(g_lms)
{
if(self.lms_spectate_warning)
{
+ // for the forfeit message...
+ self.lms_spectate_warning = 2;
// mark player as spectator
PlayerScore_Add(self, SP_LMS_RANK, 666 - PlayerScore_Add(self, SP_LMS_RANK, 0));
}
}
}
- if(self.classname == "player" && autocvar_sv_spectate == 1)
+ if(IS_PLAYER(self) && autocvar_sv_spectate == 1)
ClientKill_TeamChange(-2); // observe
-
+
// in CA, allow a dead player to move to spectators (without that, caplayer!=0 will be moved back to the player list)
// note: if arena game mode is ever done properly, this needs to be removed.
- if(g_ca && self.caplayer && (IS_SPEC(self) || IS_OBSERVER(self)))
- if(self.caplayer && (self.classname == "spectator" || self.classname == "observer"))
++ if(self.caplayer && (IS_SPEC(self) || IS_OBSERVER(self)))
{
sprint(self, "WARNING: you will spectate in the next round.\n");
self.caplayer = 0;
// verify that the client provided is acceptable for use
float VerifyClientEntity(entity client, float must_be_real, float must_be_bots)
{
- if not(client.flags & FL_CLIENT)
+ if not(IS_CLIENT(client))
return CLIENT_DOESNT_EXIST;
- else if(must_be_real && (clienttype(client) != CLIENTTYPE_REAL))
+ else if(must_be_real && !IS_REAL_CLIENT(client))
return CLIENT_NOT_REAL;
- else if(must_be_bots && (clienttype(client) != CLIENTTYPE_BOT))
+ else if(must_be_bots && !IS_BOT_CLIENT(client))
return CLIENT_NOT_BOT;
return CLIENT_ACCEPTABLE;
// used by CommonCommand_timeout() and CommonCommand_timein() to handle game pausing and messaging and such.
void timeout_handler_reset()
{
- entity tmp_player;
-
timeout_caller = world;
timeout_time = 0;
timeout_leadtime = 0;
-
- FOR_EACH_REALPLAYER(tmp_player)
- Send_CSQC_Centerprint_Generic_Expire(tmp_player, CPID_TIMEOUT_COUNTDOWN);
remove(self);
}
{
if(timeout_time > 0) // countdown is still going
{
- FOR_EACH_REALPLAYER(tmp_player)
- Send_CSQC_Centerprint_Generic(tmp_player, CPID_TIMEOUT_COUNTDOWN, "Timeout ends in %d seconds!", 1, timeout_time);
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_TIMEOUT_ENDING, timeout_time);
if(timeout_time == autocvar_sv_timeout_resumetime) // play a warning sound when only <sv_timeout_resumetime> seconds are left
- Announce("prepareforbattle");
+ Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_PREPARE);
self.nextthink = time + TIMEOUT_SLOWMO_VALUE; // think again in one second
timeout_time -= 1; // decrease the time counter
{
if(timeout_leadtime > 0) // countdown is still going
{
- // centerprint the information to every player
- FOR_EACH_REALPLAYER(tmp_player)
- Send_CSQC_Centerprint_Generic(tmp_player, CPID_TIMEOUT_COUNTDOWN, "Timeout begins in %d seconds!", 1, timeout_leadtime);
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_TIMEOUT_BEGINNING, timeout_leadtime);
self.nextthink = time + 1; // think again in one second
timeout_leadtime -= 1; // decrease the time counter
else if(inWarmupStage && !g_warmup_allow_timeout) { print_to(caller, "^7Error: You can not call a timeout in warmup-stage."); }
else if(time < game_starttime) { print_to(caller, "^7Error: You can not call a timeout while the map is being restarted."); }
else if(caller && (caller.allowed_timeouts < 1)) { print_to(caller, "^7Error: You already used all your timeout calls for this map."); }
- else if(caller && (caller.classname != "player")) { print_to(caller, "^7Error: You must be a player to call a timeout."); }
+ else if(caller && !IS_PLAYER(caller)) { print_to(caller, "^7Error: You must be a player to call a timeout."); }
else if((autocvar_timelimit) && (last_possible_timeout < time - game_starttime)) { print_to(caller, "^7Error: It is too late to call a timeout now!"); }
else // everything should be okay, proceed with starting the timeout
timeout_handler.think = timeout_handler_think;
timeout_handler.nextthink = time; // always let the entity think asap
- Announce("timeoutcalled");
+ Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_TIMEOUT);
}
}
else { print_to(caller, "^1Timeouts are not allowed to be called, enable them with sv_timeout 1.\n"); }
{
case CMD_REQUEST_COMMAND:
{
- float total_listed_players, tmp_hours, tmp_minutes, tmp_seconds, is_bot;
+ float total_listed_players, is_bot;
entity tmp_player;
float privacy = (caller && autocvar_sv_status_privacy);
total_listed_players = 0;
FOR_EACH_CLIENT(tmp_player)
{
- is_bot = (clienttype(tmp_player) == CLIENTTYPE_BOT);
+ is_bot = (IS_BOT_CLIENT(tmp_player));
if(is_bot)
{
tmp_netaddress = tmp_player.netaddress;
tmp_crypto_idfp = tmp_player.crypto_idfp;
}
-
- tmp_hours = tmp_minutes = tmp_seconds = 0;
-
- tmp_seconds = floor(time - tmp_player.jointime);
- tmp_minutes = floor(tmp_seconds / 60);
- tmp_hours = floor(tmp_minutes / 60);
-
- if(tmp_minutes) { tmp_seconds -= (tmp_minutes * 60); }
- if(tmp_hours) { tmp_minutes -= (tmp_hours * 60); }
print_to(caller, sprintf(strreplace(" ", separator, " #%-3d %-20.20s %-5d %-3d %-9s %-16s %s "),
num_for_edict(tmp_player),
tmp_player.netname,
tmp_player.ping,
tmp_player.ping_packetloss,
- sprintf("%02d:%02d:%02d", tmp_hours, tmp_minutes, tmp_seconds),
+ process_time(1, time - tmp_player.jointime),
tmp_netaddress,
tmp_crypto_idfp));
string targets = strreplace(",", " ", argv(1));
string original_targets = strreplace(" ", ", ", targets);
string destination = argv(2);
- string notify = argv(3);
string successful, t;
successful = string_null;
// Where are we putting this player?
if(destination == "spec" || destination == "spectator")
{
- if(client.classname != "spectator" && client.classname != "observer")
+ if(!IS_SPEC(client) && !IS_OBSERVER(client))
{
self = client;
PutObserverInServer();
}
else
{
- if(client.classname != "spectator" && client.classname != "observer")
+ if(!IS_SPEC(client) && !IS_OBSERVER(client))
{
if(teamplay)
{
// set up
- float team_color;
+ float team_id;
float save = client.team_forced;
client.team_forced = 0;
// find the team to move the player to
- team_color = ColourToNumber(destination);
- if(team_color == client.team) // already on the destination team
+ team_id = Team_ColorToTeam(destination);
+ if(team_id == client.team) // already on the destination team
{
// keep the forcing undone
- print("Player ", ftos(GetFilteredNumber(t)), " (", client.netname, ") is already on the ", ColoredTeamName(client.team), (targets ? ", skipping to next player.\n" : ".\n"));
+ print("Player ", ftos(GetFilteredNumber(t)), " (", client.netname, ") is already on the ", Team_ColoredFullName(client.team), (targets ? "^7, skipping to next player.\n" : "^7.\n"));
continue;
}
- else if(team_color == 0) // auto team
+ else if(team_id == 0) // auto team
{
- team_color = NumberToTeamNumber(FindSmallestTeam(client, FALSE));
+ team_id = Team_NumberToTeam(FindSmallestTeam(client, FALSE));
}
else
{
client.team_forced = save;
// Check to see if the destination team is even available
- switch(team_color)
+ switch(team_id)
{
- case COLOR_TEAM1: if(c1 == -1) { print("Sorry, can't move player to red team if it doesn't exist.\n"); return; } break;
- case COLOR_TEAM2: if(c2 == -1) { print("Sorry, can't move player to blue team if it doesn't exist.\n"); return; } break;
- case COLOR_TEAM3: if(c3 == -1) { print("Sorry, can't move player to yellow team if it doesn't exist.\n"); return; } break;
- case COLOR_TEAM4: if(c4 == -1) { print("Sorry, can't move player to pink team if it doesn't exist.\n"); return; } break;
+ case NUM_TEAM_1: if(c1 == -1) { print("Sorry, can't move player to red team if it doesn't exist.\n"); return; } break;
+ case NUM_TEAM_2: if(c2 == -1) { print("Sorry, can't move player to blue team if it doesn't exist.\n"); return; } break;
+ case NUM_TEAM_3: if(c3 == -1) { print("Sorry, can't move player to yellow team if it doesn't exist.\n"); return; } break;
+ case NUM_TEAM_4: if(c4 == -1) { print("Sorry, can't move player to pink team if it doesn't exist.\n"); return; } break;
default: print("Sorry, can't move player here if team ", destination, " doesn't exist.\n"); return;
}
// If so, lets continue and finally move the player
client.team_forced = 0;
- MoveToTeam(client, team_color, 6, stof(notify));
+ MoveToTeam(client, team_id, 6);
successful = strcat(successful, (successful ? ", " : ""), client.netname);
- print("Player ", ftos(GetFilteredNumber(t)), " (", client.netname, ") has been moved to the ", ColoredTeamName(team_color), ".\n");
+ print("Player ", ftos(GetFilteredNumber(t)), " (", client.netname, ") has been moved to the ", Team_ColoredFullName(team_id), "^7.\n");
continue;
}
else
print("Incorrect parameters for ^2moveplayer^7\n");
case CMD_REQUEST_USAGE:
{
- print("\nUsage:^3 sv_cmd moveplayer clients destination [notify]\n");
+ print("\nUsage:^3 sv_cmd moveplayer clients destination\n");
print(" 'clients' is a list (separated by commas) of player entity ID's or nicknames\n");
print(" 'destination' is what to send the player to, be it team or spectating\n");
print(" Full list of destinations here: \"spec, spectator, red, blue, yellow, pink, auto.\"\n");
- print(" 'notify' is whether or not to send messages notifying of the move. Detail below.\n");
- print(" 0 (00) automove centerprint, admin message; 1 (01) automove centerprint, no admin message\n");
- print(" 2 (10) no centerprint, admin message; 3 (11) no centerprint, no admin message\n");
print("Examples: sv_cmd moveplayer 1,3,5 red 3\n");
print(" sv_cmd moveplayer 2 spec \n");
print("See also: ^2allspec, shuffleteams^7\n");
entity plr;
FOR_EACH_CLIENT(plr) //give every spectator <g_maxplayers_spectator_blocktime> seconds time to become a player
{
- if(plr.classname == "spectator" || plr.classname == "observer")
+ if(IS_SPEC(plr) || IS_OBSERVER(plr))
{
plr.spectatortime = time;
- sprint(plr, strcat("^7You have to become a player within the next ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n"));
+ Send_Notification(NOTIF_ONE_ONLY, plr, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
}
}
bprint(strcat("^7All spectators will be automatically kicked when not joining the game after ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds!\n"));
x = (t_players / t_teams);
x = ((i == 1) ? ceil(x) : floor(x));
- team_color = NumberToTeamNumber(i);
+ team_color = Team_NumberToTeam(i);
// sort through the random list of players made earlier
for(z = 1; z <= maxclients; ++z)
self = edict_num(shuffleteams_players[z]);
if(self.team != team_color)
- MoveToTeam(self, team_color, 6, 0);
+ MoveToTeam(self, team_color, 6);
shuffleteams_players[z] = 0;
shuffleteams_teams[i] = shuffleteams_teams[i] + 1;
// This... is a fairly dangerous and powerful command... - It allows any arguments to be sent to a client via rcon.
// Because of this, it is disabled by default and must be enabled by the server owner when doing compilation. That way,
// we can be certain they understand the risks of it... So to enable, compile server with -DSTUFFTO_ENABLED argument.
-
+
#ifdef STUFFTO_ENABLED
#message "stuffto command enabled"
switch(request)
for(i = 1; i <= maxclients; i += 8)
{
for(f = 0, e = edict_num(i), b = 1; b < 256; b *= 2, e = nextent(e))
- if(clienttype(e) != CLIENTTYPE_REAL || e.ready)
+ if(!IS_REAL_CLIENT(e) || e.ready)
f |= b;
WriteByte(MSG_ENTITY, f);
}
if(vote_caller) { vote_caller.vote_waittime = 0; } // people like your votes, you don't need to wait to vote again
VoteReset();
- Announce("voteaccept");
+ Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_VOTE_ACCEPT);
}
void VoteReject()
{
bprint("\{1}^2* ^3", GetCallerName(vote_caller), "^2's vote for ", vote_called_display, "^2 was rejected\n");
VoteReset();
- Announce("votefail");
+ Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_VOTE_FAIL);
}
void VoteTimeout()
{
bprint("\{1}^2* ^3", GetCallerName(vote_caller), "^2's vote for ", vote_called_display, "^2 timed out\n");
VoteReset();
- Announce("votefail");
+ Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_VOTE_FAIL);
}
void VoteSpam(float notvoters, float mincount, string result)
|| ((autocvar_sv_vote_nospectators == 1) && (inWarmupStage || gameover))
|| (autocvar_sv_vote_nospectators == 0));
- float vote_player_count = 0, is_player, notvoters = 0;
+ float vote_player_count = 0, notvoters = 0;
float vote_real_player_count = 0, vote_real_accept_count = 0;
float vote_real_reject_count = 0, vote_real_abstain_count = 0;
float vote_needed_of_voted, final_needed_votes;
// add up all the votes from each connected client
FOR_EACH_REALCLIENT(tmp_player)
{
- is_player = (tmp_player.classname == "player");
-
++vote_player_count;
- if(is_player) { ++vote_real_player_count; }
+ if(IS_PLAYER(tmp_player)) { ++vote_real_player_count; }
switch(tmp_player.vote_selection)
{
- case VOTE_SELECT_REJECT: { ++vote_reject_count; { if(is_player) ++vote_real_reject_count; } break; }
- case VOTE_SELECT_ACCEPT: { ++vote_accept_count; { if(is_player) ++vote_real_reject_count; } break; }
- case VOTE_SELECT_ABSTAIN: { ++vote_abstain_count; { if(is_player) ++vote_real_abstain_count; } break; }
+ case VOTE_SELECT_REJECT: { ++vote_reject_count; { if(IS_PLAYER(tmp_player)) ++vote_real_reject_count; } break; }
+ case VOTE_SELECT_ACCEPT: { ++vote_accept_count; { if(IS_PLAYER(tmp_player)) ++vote_real_reject_count; } break; }
+ case VOTE_SELECT_ABSTAIN: { ++vote_abstain_count; { if(IS_PLAYER(tmp_player)) ++vote_real_abstain_count; } break; }
default: break;
}
}
// Game logic for warmup
// =======================
+ // Resets the state of all clients, items, weapons, waypoints, ... of the map.
+ void reset_map(float dorespawn)
+ {
+ entity oldself;
+ oldself = self;
+
+ if(time <= game_starttime && round_handler_IsActive())
+ round_handler_Reset(game_starttime);
+
+ if(g_race || g_cts)
+ race_ReadyRestart();
+ else MUTATOR_CALLHOOK(reset_map_global);
+
+ lms_lowest_lives = 999;
+ lms_next_place = player_count;
+
+ for(self = world; (self = nextent(self)); )
+ if(clienttype(self) == CLIENTTYPE_NOTACLIENT)
+ {
+ if(self.reset)
+ {
+ self.reset();
+ continue;
+ }
+
+ if(self.team_saved)
+ self.team = self.team_saved;
+
+ if(self.flags & FL_PROJECTILE) // remove any projectiles left
+ remove(self);
+ }
+
+ // Waypoints and assault start come LAST
+ for(self = world; (self = nextent(self)); )
+ if(clienttype(self) == CLIENTTYPE_NOTACLIENT)
+ {
+ if(self.reset2)
+ {
+ self.reset2();
+ continue;
+ }
+ }
+
+ // Moving the player reset code here since the player-reset depends
+ // on spawnpoint entities which have to be reset first --blub
+ if(dorespawn)
+ if(!MUTATOR_CALLHOOK(reset_map_players))
+ FOR_EACH_CLIENT(self) // reset all players
+ {
+ /*
+ only reset players if a restart countdown is active
+ this can either be due to cvar sv_ready_restart_after_countdown having set
+ restart_mapalreadyrestarted to 1 after the countdown ended or when
+ sv_ready_restart_after_countdown is not used and countdown is still running
+ */
+ if (restart_mapalreadyrestarted || (time < game_starttime))
+ {
+ //NEW: changed behaviour so that it prevents that previous spectators/observers suddenly spawn as players
+ if (IS_PLAYER(self)) {
+ //PlayerScore_Clear(self);
+ if(g_lms)
+ PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives());
+ self.killcount = 0;
+ //stop the player from moving so that he stands still once he gets respawned
+ self.velocity = '0 0 0';
+ self.avelocity = '0 0 0';
+ self.movement = '0 0 0';
+ PutClientInServer();
+ }
+ }
+ }
+
+ if(g_keyhunt)
+ kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round + (game_starttime - time), kh_StartRound);
+
+ self = oldself;
+ }
+
// Restarts the map after the countdown is over (and cvar sv_ready_restart_after_countdown is set)
void ReadyRestart_think()
{
checkrules_suddendeathend = checkrules_overtimesadded = checkrules_suddendeathwarning = 0;
readyrestart_happened = 1;
- game_starttime = time;
- if(!g_ca && !g_arena) { game_starttime += RESTART_COUNTDOWN; }
+ game_starttime = time + RESTART_COUNTDOWN;
- // clear alivetime
+ // clear player attributes
FOR_EACH_CLIENT(tmp_player)
{
tmp_player.alivetime = 0;
+ tmp_player.killcount = 0;
PlayerStats_Event(tmp_player, PLAYERSTATS_ALIVETIME, -PlayerStats_Event(tmp_player, PLAYERSTATS_ALIVETIME, 0));
}
inWarmupStage = 0; // once the game is restarted the game is in match stage
// reset the .ready status of all players (also spectators)
- FOR_EACH_CLIENTSLOT(tmp_player) { tmp_player.ready = 0; }
+ FOR_EACH_REALCLIENT(tmp_player) { tmp_player.ready = 0; }
readycount = 0;
Nagger_ReadyCounted(); // NOTE: this causes a resend of that entity, and will also turn off warmup state on the client
// lock teams with lockonrestart
- if(autocvar_teamplay_lockonrestart && teamplay)
+ if(autocvar_teamplay_lockonrestart && teamplay)
{
lockteams = 1;
bprint("^1The teams are now locked.\n");
}
//initiate the restart-countdown-announcer entity
- if(autocvar_sv_ready_restart_after_countdown && !g_ca && !g_arena)
+ if(autocvar_sv_ready_restart_after_countdown)
{
restart_timer = spawn();
restart_timer.think = ReadyRestart_think;
float ready_needed_factor, ready_needed_count;
float t_ready = 0, t_players = 0;
- FOR_EACH_REALPLAYER(tmp_player)
+ FOR_EACH_REALCLIENT(tmp_player)
{
- ++t_players;
- if(tmp_player.ready) { ++t_ready; }
+ if(IS_PLAYER(tmp_player) || tmp_player.caplayer == 1)
+ {
+ ++t_players;
+ if(tmp_player.ready) { ++t_ready; }
+ }
}
readycount = t_ready;
if(accepted > 0)
{
- string reason = ((argc > next_token) ? substring(vote_command, argv_start_index(next_token), argv_end_index(-1) - argv_start_index(next_token)) : "No reason provided");
+ string reason = ((argc > next_token) ? substring(vote_command, argv_start_index(next_token), strlen(vote_command) - argv_start_index(next_token)) : "No reason provided");
string command_arguments;
if(first_command == "kickban")
if not(autocvar_sv_vote_call || !caller) { print_to(caller, "^1Vote calling is not allowed."); }
else if(!autocvar_sv_vote_gamestart && time < game_starttime) { print_to(caller, "^1Vote calling is not allowed before the match has started."); }
else if(vote_called) { print_to(caller, "^1There is already a vote called."); }
- else if(!spectators_allowed && (caller && (caller.classname != "player"))) { print_to(caller, "^1Only players can call a vote."); }
+ else if(!spectators_allowed && (caller && !IS_PLAYER(caller))) { print_to(caller, "^1Only players can call a vote."); }
else if(timeout_status) { print_to(caller, "^1You can not call a vote while a timeout is active."); }
else if(caller && (time < caller.vote_waittime)) { print_to(caller, strcat("^1You have to wait ^2", ftos(ceil(caller.vote_waittime - time)), "^1 seconds before you can again call a vote.")); }
else if not(VoteCommand_checknasty(vote_command)) { print_to(caller, "^1Syntax error in command, see 'vhelp' for more info."); }
}
FOR_EACH_REALCLIENT(tmp_player) { ++tmp_playercount; }
- if(tmp_playercount > 1) { Announce("votecall"); } // don't announce a "vote now" sound if player is alone
+ if(tmp_playercount > 1) { Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_VOTE_CALL); } // don't announce a "vote now" sound if player is alone
bprint("\{1}^2* ^3", GetCallerName(vote_caller), "^2 calls a vote for ", vote_called_display, "\n");
if(autocvar_sv_eventlog) { GameLogEcho(strcat(":vote:vcall:", ftos(vote_caller.playerid), ":", vote_called_display)); }
if not(autocvar_sv_vote_master_callable) { print_to(caller, "^1Vote to become vote master is not allowed."); }
else if(vote_called) { print_to(caller, "^1There is already a vote called."); }
- else if(!spectators_allowed && (caller && (caller.classname != "player"))) { print_to(caller, "^1Only players can call a vote."); }
+ else if(!spectators_allowed && (caller && !IS_PLAYER(caller))) { print_to(caller, "^1Only players can call a vote."); }
else if(timeout_status) { print_to(caller, "^1You can not call a vote while a timeout is active."); }
else // everything went okay, continue with creating vote
PlayerScore_Add(targ, SP_DEATHS, 1);
- if(g_arena || g_ca)
- if(autocvar_g_arena_roundbased)
- return;
-
if(targ != attacker) // not for suicides
if(g_weaponarena_random)
{
else
{
self = oldself;
- if(g_runematch)
- {
- f = RunematchHandleFrags(attacker, targ, f);
- }
- else if(g_lms)
+ if(g_lms)
{
// remove a life
float tl;
UpdateFrags(attacker, f);
}
- string Obituary_ExtraFragInfo(entity player) // Extra fragmessage information
- {
- string health_output = string_null;
- string ping_output = string_null;
- string handicap_output = string_null;
- string output = string_null;
-
- if(autocvar_sv_fraginfo && ((autocvar_sv_fraginfo == 2) || inWarmupStage))
- {
- // health/armor of attacker (person who killed you)
- if(autocvar_sv_fraginfo_stats && (player.health >= 1))
- health_output = strcat("^7(Health ^1", ftos(rint(player.health)), "^7 / Armor ^2", ftos(rint(player.armorvalue)), "^7)");
-
- // ping display
- if(autocvar_sv_fraginfo_ping)
- ping_output = ((IS_BOT_CLIENT(player)) ? "^2Bot" : strcat("Ping ", ((player.ping >= 150) ? "^1" : "^2"), ftos(rint(player.ping)), "ms"));
-
- // handicap display
- if(autocvar_sv_fraginfo_handicap)
- {
- if(autocvar_sv_fraginfo_handicap == 2)
- handicap_output = strcat(output, strcat("Handicap ^2", ((player.cvar_cl_handicap <= 1) ? "Off" : ftos(rint(player.cvar_cl_handicap)))));
- else if(player.cvar_cl_handicap) // with _handicap 1, only show this if there actually is a handicap enabled.
- handicap_output = strcat("Handicap ^2", ftos(rint(player.cvar_cl_handicap)));
- }
-
- // format the string
- output = strcat(health_output, (health_output ? ((ping_output || handicap_output) ? " ^7(" : "") : ((ping_output || handicap_output) ? "^7(" : "")),
- ping_output, (handicap_output ? "^7 / " : ""),
- handicap_output, ((ping_output || handicap_output) ? "^7)" : ""));
-
- // add new line to the beginning if there is a message
- if(output) { output = strcat("\n", output); }
- }
-
- return output;
- }
-
string AppendItemcodes(string s, entity player)
{
float w;
s = strcat(s, "T");
if(player.kh_next)
s = strcat(s, "K");
- if(player.runes)
- s = strcat(s, "|", ftos(player.runes));
return s;
}
s = strcat(":kill:", mode);
s = strcat(s, ":", ftos(killer.playerid));
s = strcat(s, ":", ftos(killed.playerid));
- s = strcat(s, ":type=", ftos(deathtype));
+ s = strcat(s, ":type=", Deathtype_Name(deathtype));
s = strcat(s, ":items=");
s = AppendItemcodes(s, killer);
if(killed != killer)
GameLogEcho(s);
}
- void Send_KillNotification (string s1, string s2, string s3, float msg, float type)
+ void Obituary_SpecialDeath(
+ entity notif_target,
+ float murder,
+ float deathtype,
+ string s1, string s2, string s3,
+ float f1, float f2, float f3)
{
- WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte(MSG_BROADCAST, TE_CSQC_KILLNOTIFY);
- WriteString(MSG_BROADCAST, s1);
- WriteString(MSG_BROADCAST, s2);
- WriteString(MSG_BROADCAST, s3);
- WriteShort(MSG_BROADCAST, msg);
- WriteByte(MSG_BROADCAST, type);
+ if(DEATH_ISSPECIAL(deathtype))
+ {
+ entity deathent = deathtypes[(deathtype - DT_FIRST) - 1];
+ if not(deathent) { backtrace("Obituary_SpecialDeath: Could not find deathtype entity!\n"); return; }
+
+ if(murder)
+ {
+ if(deathent.death_msgmurder)
+ {
+ Send_Notification_WOVA(
+ NOTIF_ONE,
+ notif_target,
+ MSG_MULTI,
+ deathent.death_msgmurder.nent_id,
+ s1, s2, s3, "",
+ f1, f2, f3, 0
+ );
+ Send_Notification_WOVA(
+ NOTIF_ALL_EXCEPT,
+ notif_target,
+ MSG_INFO,
+ deathent.death_msgmurder.nent_msginfo.nent_id,
+ s1, s2, s3, "",
+ f1, f2, f3, 0
+ );
+ }
+ }
+ else
+ {
+ if(deathent.death_msgself)
+ {
+ Send_Notification_WOVA(
+ NOTIF_ONE,
+ notif_target,
+ MSG_MULTI,
+ deathent.death_msgself.nent_id,
+ s1, s2, s3, "",
+ f1, f2, f3, 0
+ );
+ Send_Notification_WOVA(
+ NOTIF_ALL_EXCEPT,
+ notif_target,
+ MSG_INFO,
+ deathent.death_msgself.nent_msginfo.nent_id,
+ s1, s2, s3, "",
+ f1, f2, f3, 0
+ );
+ }
+ }
+ }
+ else { backtrace("Obituary_SpecialDeath called without a special deathtype?\n"); return; }
}
- // Function is used to send a generic centerprint whose content CSQC gets to decide (gentle version or not in the below cases)
- void Send_CSQC_KillCenterprint(entity e, string s1, string s2, float msg, float type)
+ float w_deathtype;
+ float Obituary_WeaponDeath(
+ entity notif_target,
+ float murder,
+ float deathtype,
+ string s1, string s2, string s3,
+ float f1, float f2)
{
- if (IS_REAL_CLIENT(e))
+ float death_weapon = DEATH_WEAPONOF(deathtype);
+ if(death_weapon)
{
- msg_entity = e;
- WRITESPECTATABLE_MSG_ONE({
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_KILLCENTERPRINT);
- WriteString(MSG_ONE, s1);
- WriteString(MSG_ONE, s2);
- WriteShort(MSG_ONE, msg);
- WriteByte(MSG_ONE, type);
- });
+ w_deathtype = deathtype;
+ float death_message = weapon_action(death_weapon, ((murder) ? WR_KILLMESSAGE : WR_SUICIDEMESSAGE));
+ w_deathtype = FALSE;
+
+ if(death_message)
+ {
+ Send_Notification_WOVA(
+ NOTIF_ONE,
+ notif_target,
+ MSG_MULTI,
+ death_message,
+ s1, s2, s3, "",
+ f1, f2, 0, 0
+ );
+ Send_Notification_WOVA(
+ NOTIF_ALL_EXCEPT,
+ notif_target,
+ MSG_INFO,
+ msg_multi_notifs[death_message - 1].nent_msginfo.nent_id,
+ s1, s2, s3, "",
+ f1, f2, 0, 0
+ );
+ }
+ else
+ {
+ dprint(sprintf(
+ "Obituary_WeaponDeath(): ^1Deathtype ^7(%d)^1 has no notification for weapon %d!\n",
+ deathtype,
+ death_weapon
+ ));
+ }
+
+ return TRUE;
}
+ return FALSE;
}
- void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
+ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype)
{
- string s, a, msg;
- float type;
-
- if (IS_PLAYER(targ))
+ // Sanity check
+ if not(IS_PLAYER(targ)) { backtrace("Obituary called on non-player?!\n"); return; }
+
+ // Declarations
+ float notif_firstblood = FALSE;
+ float kill_count_to_attacker, kill_count_to_target;
+
+ // Set final information for the death
+ targ.death_origin = targ.origin;
+ if(targ != attacker) { targ.killer_origin = attacker.origin; }
+ string deathlocation = (autocvar_notification_server_allows_location ? NearestLocation(targ.death_origin) : "");
+
+ #ifdef NOTIFICATIONS_DEBUG
+ Debug_Notification(
+ sprintf(
+ "Obituary(%s, %s, %s, %s = %d);\n",
+ attacker.netname,
+ inflictor.netname,
+ targ.netname,
+ Deathtype_Name(deathtype),
+ deathtype
+ )
+ );
+ #endif
+
+ // =======
+ // SUICIDE
+ // =======
+ if(targ == attacker)
{
- s = targ.netname;
- a = attacker.netname;
-
- if (targ == attacker) // suicides
+ if(DEATH_ISSPECIAL(deathtype))
{
- if (deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
- msg = ColoredTeamName(targ.team); // TODO: check if needed?
- else
- msg = "";
- if(!g_cts) // no "killed your own dumb self" message in CTS
- Send_CSQC_KillCenterprint(targ, msg, "", deathtype, MSG_SUICIDE);
-
- if(deathtype != DEATH_TEAMCHANGE && deathtype != DEATH_QUIET)
+ if(deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
{
- LogDeath("suicide", deathtype, targ, targ);
- GiveFrags(attacker, targ, -1, deathtype);
+ Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.team, 0, 0);
}
-
- if (targ.killcount > 2)
- msg = ftos(targ.killcount);
else
- msg = "";
- if(teamplay && deathtype == DEATH_MIRRORDAMAGE)
{
- if(attacker.team == COLOR_TEAM1)
- deathtype = KILL_TEAM_RED;
- else
- deathtype = KILL_TEAM_BLUE;
+ switch(deathtype)
+ {
+ case DEATH_MIRRORDAMAGE:
+ {
+ Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
+ break;
+ }
+
+ default:
+ {
+ Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
+ break;
+ }
+ }
}
-
- Send_KillNotification(s, msg, "", deathtype, MSG_SUICIDE);
}
- else if (IS_PLAYER(attacker))
+ else if not(Obituary_WeaponDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0))
{
- if(!IsDifferentTeam(attacker, targ))
- {
- if(attacker.team == COLOR_TEAM1)
- type = KILL_TEAM_RED;
- else
- type = KILL_TEAM_BLUE;
-
- GiveFrags(attacker, targ, -1, deathtype);
+ backtrace("SUICIDE: what the hell happened here?\n");
+ return;
+ }
+ LogDeath("suicide", deathtype, targ, targ);
+ GiveFrags(attacker, targ, -1, deathtype);
+ }
- Send_CSQC_KillCenterprint(attacker, s, "", type, MSG_KILL);
+ // ======
+ // MURDER
+ // ======
+ else if(IS_PLAYER(attacker))
+ {
+ if(!IsDifferentTeam(attacker, targ))
+ {
+ LogDeath("tk", deathtype, attacker, targ);
+ GiveFrags(attacker, targ, -1, deathtype);
- if (targ.killcount > 2)
- msg = ftos(targ.killcount);
- else
- msg = "";
+ attacker.killcount = 0;
+
+ Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAG, targ.netname);
+ Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAGGED, attacker.netname);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(targ.team, INFO_DEATH_TEAMKILL_), targ.netname, attacker.netname, deathlocation, targ.killcount);
- if (attacker.killcount > 2) {
- msg = ftos(attacker.killcount);
- type = KILL_TEAM_SPREE;
+ // In this case, the death message will ALWAYS be "foo was betrayed by bar"
+ // No need for specific death/weapon messages...
+ }
+ else
+ {
+ LogDeath("frag", deathtype, attacker, targ);
+ GiveFrags(attacker, targ, 1, deathtype);
+
+ attacker.taunt_soundtime = time + 1;
+ attacker.killcount = attacker.killcount + 1;
+
+ #define SPREE_ITEM(counta,countb,center,normal,gentle) \
+ case counta: \
+ { \
+ Send_Notification(NOTIF_ONE, attacker, MSG_ANNCE, ANNCE_KILLSTREAK_##countb); \
+ PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
+ break; \
}
- Send_KillNotification(a, s, msg, type, MSG_KILL);
-
- attacker.killcount = 0;
+ switch(attacker.killcount)
+ {
+ KILL_SPREE_LIST
+ default: break;
+ }
+ #undef SPREE_ITEM
- LogDeath("tk", deathtype, attacker, targ);
+ if(!checkrules_firstblood)
+ {
+ checkrules_firstblood = TRUE;
+ notif_firstblood = TRUE; // modify the current messages so that they too show firstblood information
+ PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
+ PlayerStats_Event(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
+
+ // tell spree_inf and spree_cen that this is a first-blood and first-victim event
+ kill_count_to_attacker = -1;
+ kill_count_to_target = -2;
}
else
{
- if (!checkrules_firstblood)
- {
- checkrules_firstblood = TRUE;
- Send_KillNotification(a, "", "", KILL_FIRST_BLOOD, MSG_KILL);
- // TODO: make these print a newline if they dont
- Send_CSQC_KillCenterprint(attacker, "", "", KILL_FIRST_BLOOD, MSG_KILL);
- Send_CSQC_KillCenterprint(targ, "", "", KILL_FIRST_VICTIM, MSG_KILL);
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
- PlayerStats_Event(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
- }
-
- if(targ.istypefrag) {
- Send_CSQC_KillCenterprint(attacker, s, Obituary_ExtraFragInfo(targ), KILL_TYPEFRAG, MSG_KILL);
- Send_CSQC_KillCenterprint(targ, a, Obituary_ExtraFragInfo(attacker), KILL_TYPEFRAGGED, MSG_KILL);
- } else {
- Send_CSQC_KillCenterprint(attacker, s, Obituary_ExtraFragInfo(targ), KILL_FRAG, MSG_KILL);
- Send_CSQC_KillCenterprint(targ, a, Obituary_ExtraFragInfo(attacker), KILL_FRAGGED, MSG_KILL);
- }
-
- attacker.taunt_soundtime = time + 1;
+ kill_count_to_attacker = attacker.killcount;
+ kill_count_to_target = 0;
+ }
- if (deathtype == DEATH_HURTTRIGGER && inflictor.message2 != "")
- msg = inflictor.message2;
- else if (deathtype == DEATH_CUSTOM)
- msg = deathmessage;
+ float verbose_allowed = (autocvar_notification_server_allows_frag_verbose && ((autocvar_notification_server_allows_frag_verbose == 2) || inWarmupStage));
+ if(targ.istypefrag)
+ {
+ if(attacker.FRAG_VERBOSE && verbose_allowed)
+ Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE, targ.netname, kill_count_to_attacker, (IS_BOT_CLIENT(targ) ? NO_MSG : targ.ping));
else
- msg = "";
+ Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAG, targ.netname, kill_count_to_attacker);
- if(strstrofs(msg, "%", 0) < 0)
- msg = strcat("%s ", msg, " by %s");
-
- Send_KillNotification(a, s, msg, deathtype, MSG_KILL);
+ if(targ.FRAG_VERBOSE && verbose_allowed)
+ Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE, attacker.netname, kill_count_to_target, attacker.health, attacker.armorvalue, (IS_BOT_CLIENT(attacker) ? NO_MSG : attacker.ping));
+ else
+ Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAGGED, attacker.netname, kill_count_to_target);
+ }
+ else
+ {
+ if(attacker.FRAG_VERBOSE && verbose_allowed)
+ Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_MURDER_FRAG_VERBOSE, targ.netname, kill_count_to_attacker, (IS_BOT_CLIENT(targ) ? NO_MSG : targ.ping));
+ else
+ Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_MURDER_FRAG, targ.netname, kill_count_to_attacker);
- GiveFrags(attacker, targ, 1, deathtype);
+ if(targ.FRAG_VERBOSE && verbose_allowed)
+ Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_MURDER_FRAGGED_VERBOSE, attacker.netname, kill_count_to_target, attacker.health, attacker.armorvalue, (IS_BOT_CLIENT(attacker) ? NO_MSG : attacker.ping));
+ else
+ Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_MURDER_FRAGGED, attacker.netname, kill_count_to_target);
+ }
- if (targ.killcount > 2) {
- Send_KillNotification(s, ftos(targ.killcount), a, KILL_END_SPREE, MSG_SPREE);
- }
+ if not(Obituary_WeaponDeath(targ, TRUE, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker))
+ Obituary_SpecialDeath(targ, TRUE, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker, 0);
+ }
+ }
- attacker.killcount = attacker.killcount + 1;
+ // =============
+ // ACCIDENT/TRAP
+ // =============
+ else
+ {
+ switch(deathtype)
+ {
+ // For now, we're just forcing HURTTRIGGER to behave as "DEATH_VOID" and giving it no special options...
+ // Later on you will only be able to make custom messages using DEATH_CUSTOM,
+ // and there will be a REAL DEATH_VOID implementation which mappers will use.
+ /*case DEATH_HURTTRIGGER:
+ {
+ s1 = targ.netname;
+ s2 = inflictor.message;
+ if(strstrofs(s2, "%", 0) < 0) { s2 = strcat("%s ", s2); }
+ break;
+ }*/
- if (attacker.killcount == 3)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_3, MSG_SPREE);
- AnnounceTo(attacker, "03kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_3, 1);
- }
- else if (attacker.killcount == 5)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_5, MSG_SPREE);
- AnnounceTo(attacker, "05kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_5, 1);
- }
- else if (attacker.killcount == 10)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_10, MSG_SPREE);
- AnnounceTo(attacker, "10kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_10, 1);
- }
- else if (attacker.killcount == 15)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_15, MSG_SPREE);
- AnnounceTo(attacker, "15kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_15, 1);
- }
- else if (attacker.killcount == 20)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_20, MSG_SPREE);
- AnnounceTo(attacker, "20kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_20, 1);
- }
- else if (attacker.killcount == 25)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_25, MSG_SPREE);
- AnnounceTo(attacker, "25kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_25, 1);
- }
- else if (attacker.killcount == 30)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_30, MSG_SPREE);
- AnnounceTo(attacker, "30kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_30, 1);
- }
- else if (attacker.killcount > 2) {
- Send_KillNotification(a, ftos(attacker.killcount), "", KILL_SPREE, MSG_SPREE);
- }
- LogDeath("frag", deathtype, attacker, targ);
+ case DEATH_CUSTOM:
+ {
+ Obituary_SpecialDeath(targ, FALSE, deathtype,
+ targ.netname,
+ ((strstrofs(deathmessage, "%", 0) < 0) ? strcat("%s ", deathmessage) : deathmessage),
+ deathlocation,
+ targ.killcount,
+ 0,
+ 0);
+ break;
}
- }
- else
- {
- Send_CSQC_KillCenterprint(targ, "", "", deathtype, MSG_KILL_ACTION);
- if (deathtype == DEATH_HURTTRIGGER && inflictor.message != "")
- msg = inflictor.message;
- else if (deathtype == DEATH_CUSTOM)
- msg = deathmessage;
- else
- msg = "";
- if(strstrofs(msg, "%", 0) < 0)
- msg = strcat("%s ", msg);
-
- GiveFrags(targ, targ, -1, deathtype);
- if(PlayerScore_Add(targ, SP_SCORE, 0) == -5) {
- AnnounceTo(targ, "botlike");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, 1);
+
+ default:
+ {
+ Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
+ break;
}
- Send_KillNotification(s, msg, "", deathtype, MSG_KILL_ACTION);
-
- if (targ.killcount > 2)
- Send_KillNotification(s, ftos(targ.killcount), "", 0, MSG_KILL_ACTION_SPREE);
-
- LogDeath("accident", deathtype, targ, targ);
}
- targ.death_origin = targ.origin;
- if(targ != attacker)
- targ.killer_origin = attacker.origin;
+ LogDeath("accident", deathtype, targ, targ);
+ GiveFrags(targ, targ, -1, deathtype);
- // FIXME: this should go in PutClientInServer
- if (targ.killcount)
- targ.killcount = 0;
+ if(PlayerScore_Add(targ, SP_SCORE, 0) == -5)
+ {
+ Send_Notification(NOTIF_ONE, targ, MSG_ANNCE, ANNCE_ACHIEVEMENT_BOTLIKE);
+ PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, 1);
+ }
}
+
+ // reset target kill count
+ if(targ.killcount) { targ.killcount = 0; }
}
// these are updated by each Damage call for use in button triggering and such
damage_attacker = attacker;
attacker_save = attacker;
- if(targ.classname == "player")
+ if(IS_PLAYER(targ))
if(targ.hook)
if(targ.hook.aiment)
if(targ.hook.aiment == attacker)
// special rule: gravity bomb does not hit team mates (other than for disconnecting the hook)
if(DEATH_ISWEAPON(deathtype, WEP_HOOK) || DEATH_ISWEAPON(deathtype, WEP_TUBA))
{
- if(targ.classname == "player")
+ if(IS_PLAYER(targ))
if not(IsDifferentTeam(targ, attacker))
{
self = oldself;
}
}
- if(deathtype == DEATH_KILL || deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE || deathtype == DEATH_QUIET)
+ if(deathtype == DEATH_KILL || deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
{
// These are ALWAYS lethal
// No damage modification here
}
else
{
- /*
- skill based bot damage? gtfo. (tZork)
- if (targ.classname == "player")
- if (attacker.classname == "player")
- if (!targ.isbot)
- if (attacker.isbot)
- damage = damage * bound(0.1, (skill + 5) * 0.1, 1);
- */
-
// nullify damage if teamplay is on
if(deathtype != DEATH_TELEFRAG)
- if(attacker.classname == "player")
+ if(IS_PLAYER(attacker))
{
- if(targ.classname == "player" && targ != attacker && (IS_INDEPENDENT_PLAYER(attacker) || IS_INDEPENDENT_PLAYER(targ)))
+ if(IS_PLAYER(targ) && targ != attacker && (IS_INDEPENDENT_PLAYER(attacker) || IS_INDEPENDENT_PLAYER(targ)))
{
damage = 0;
force = '0 0 0';
damage = 0;
else if(autocvar_teamplay_mode == 4)
{
- if(targ.classname == "player" && targ.deadflag == DEAD_NO)
+ if(IS_PLAYER(targ) && targ.deadflag == DEAD_NO)
{
attacker.dmg_team = attacker.dmg_team + damage;
complainteamdamage = attacker.dmg_team - autocvar_g_teamdamage_threshold;
}
}
- if(targ.classname == "player")
- if(attacker.classname == "player")
+ if(IS_PLAYER(targ))
+ if(IS_PLAYER(attacker))
if(attacker != targ)
{
targ.lms_traveled_distance = autocvar_g_lms_campcheck_distance;
attacker.lms_traveled_distance = autocvar_g_lms_campcheck_distance;
}
- if(targ.classname == "player")
+ if(IS_PLAYER(targ))
if (g_minstagib)
{
if ((deathtype == DEATH_FALL) ||
complainteamdamage = 0;
if (targ != attacker)
{
- if ((targ.health >= 1) && (targ.classname == "player"))
+ if ((targ.health >= 1) && (IS_PLAYER(targ)))
centerprint(attacker, "Secondary fire inflicts no damage!");
force = '0 0 0';
// keep mirrorforce
damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself
}
- if(g_runematch)
- {
- // apply strength rune
- if (attacker.runes & RUNE_STRENGTH)
- {
- if(attacker.runes & CURSE_WEAK) // have both curse & rune
- {
- damage = damage * autocvar_g_balance_rune_strength_combo_damage;
- force = force * autocvar_g_balance_rune_strength_combo_force;
- }
- else
- {
- damage = damage * autocvar_g_balance_rune_strength_damage;
- force = force * autocvar_g_balance_rune_strength_force;
- }
- }
- else if (attacker.runes & CURSE_WEAK)
- {
- damage = damage * autocvar_g_balance_curse_weak_damage;
- force = force * autocvar_g_balance_curse_weak_force;
- }
-
- // apply defense rune
- if (targ.runes & RUNE_DEFENSE)
- {
- if (targ.runes & CURSE_VULNER) // have both curse & rune
- damage = damage * autocvar_g_balance_rune_defense_combo_takedamage;
- else
- damage = damage * autocvar_g_balance_rune_defense_takedamage;
- }
- else if (targ.runes & CURSE_VULNER)
- damage = damage * autocvar_g_balance_curse_vulner_takedamage;
- }
-
// count the damage
if(attacker)
if(!targ.deadflag)
else
victim = targ;
- if(victim.classname == "player" || victim.turrcaps_flags & TFL_TURRCAPS_ISTURRET)
+ if(IS_PLAYER(victim) || victim.turrcaps_flags & TFL_TURRCAPS_ISTURRET)
{
if(IsDifferentTeam(victim, attacker))
{
if not(DEATH_ISSPECIAL(deathtype))
{
- if(targ.classname == "player") // don't do this for vehicles
+ if(IS_PLAYER(targ)) // don't do this for vehicles
if(!g_minstagib)
if(IsFlying(victim))
yoda = 1;
// apply push
if (self.damageforcescale)
if (vlen(force))
- if (self.classname != "player" || time >= self.spawnshieldtime || g_midair)
+ if (!IS_PLAYER(self) || time >= self.spawnshieldtime || g_midair)
{
vector farce = damage_explosion_calcpush(self.damageforcescale * force, self.velocity, autocvar_g_balance_damagepush_speedfactor);
if(self.movetype == MOVETYPE_PHYSICS)
self.event_damage (inflictor, attacker, damage, deathtype, hitloc, force);
self = oldself;
- if(IS_PLAYER(targ) && IS_PLAYER(attacker) && attacker != targ && attacker.health > 2)
- {
- if(g_runematch)
- {
- if (attacker.runes & RUNE_VAMPIRE)
- {
- // apply vampire rune
- if (attacker.runes & CURSE_EMPATHY) // have the curse too
- {
- //attacker.health = attacker.health + damage * autocvar_g_balance_rune_vampire_combo_absorb;
- attacker.health = bound(
- autocvar_g_balance_curse_empathy_minhealth, // LA: was 3, now 40
- attacker.health + damage * autocvar_g_balance_rune_vampire_combo_absorb,
- autocvar_g_balance_rune_vampire_maxhealth); // LA: was 1000, now 500
- }
- else
- {
- //attacker.health = attacker.health + damage * autocvar_g_balance_rune_vampire_absorb;
- attacker.health = bound(
- attacker.health, // LA: was 3, but changed so that you can't lose health
- // empathy won't let you gain health in the same way...
- attacker.health + damage * autocvar_g_balance_rune_vampire_absorb,
- autocvar_g_balance_rune_vampire_maxhealth); // LA: was 1000, now 500
- }
- }
- // apply empathy curse
- else if (attacker.runes & CURSE_EMPATHY)
- {
- attacker.health = bound(
- autocvar_g_balance_curse_empathy_minhealth, // LA: was 3, now 20
- attacker.health + damage * autocvar_g_balance_curse_empathy_takedamage,
- attacker.health);
- }
- }
- }
-
// apply mirror damage if any
if(mirrordamage > 0 || mirrorforce > 0)
{
if(autocvar_g_throughfloor_debug)
print(sprintf(" steps=%f", total));
- if (targ.classname == "player")
+ if (IS_PLAYER(targ))
total = ceil(bound(autocvar_g_throughfloor_min_steps_player, total, autocvar_g_throughfloor_max_steps_player));
else
total = ceil(bound(autocvar_g_throughfloor_min_steps_other, total, autocvar_g_throughfloor_max_steps_other));
float dps;
float maxtime, mintime, maxdamage, mindamage, maxdps, mindps, totaldamage, totaltime;
- if(e.classname == "player")
+ if(IS_PLAYER(e))
{
if(e.deadflag)
return -1;
return;
for(t = 0, o = e.owner; o.owner && t < 16; o = o.owner, ++t);
- if(clienttype(o) == CLIENTTYPE_NOTACLIENT)
+ if(IS_NOT_A_CLIENT(o))
o = e.fire_owner;
// water and slime stop fire
if not(IS_INDEPENDENT_PLAYER(e))
FOR_EACH_PLAYER(other) if(e != other)
{
- if(other.classname == "player")
+ if(IS_PLAYER(other))
if(other.deadflag == DEAD_NO)
if not(IS_INDEPENDENT_PLAYER(other))
if(boxesoverlap(e.absmin, e.absmax, other.absmin, other.absmax))
//
// print the message
//
- if (activator.classname == "player" && self.message != "")
+ if (IS_PLAYER(activator) && self.message != "")
{
- if(clienttype(activator) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(activator))
{
centerprint (activator, self.message);
if (self.noise == "")
if (self.classname == "trigger_secret")
{
- if (self.enemy.classname != "player")
+ if not(IS_PLAYER(self.enemy))
return;
found_secrets = found_secrets + 1;
WriteByte (MSG_ALL, SVC_FOUNDSECRET);
if (self.count != 0)
{
- if (activator.classname == "player"
+ if (IS_PLAYER(activator)
&& (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
{
if (self.count >= 4)
return;
}
- if (activator.classname == "player"
+ if (IS_PLAYER(activator)
&& (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
centerprint(activator, "Sequence completed!");
self.enemy = activator;
void trigger_hurt_use()
{
- if(activator.classname == "player")
+ if(IS_PLAYER(activator))
self.enemy = activator;
else
self.enemy = world; // let's just destroy it, if taking over is too much work
entity own;
own = self.enemy;
- if(own.classname != "player")
+ if not(IS_PLAYER(own))
{
own = self;
self.enemy = world; // I still hate you all
Damage(other, self, self, self.dmg, DEATH_HURTTRIGGER, other.origin, '0 0 0');
}
}
- else
- {
- if (!other.owner)
- {
- if (other.classname == "rune") // reset runes
- {
- EXACTTRIGGER_TOUCH;
- other.nextthink = min(other.nextthink, time + 1);
- }
- }
- }
return;
}
void target_speaker_use_off();
void target_speaker_use_activator()
{
- if(clienttype(activator) != CLIENTTYPE_REAL)
+ if not(IS_REAL_CLIENT(activator))
return;
string snd;
if(substring(self.noise, 0, 1) == "*")
return;
if(vs.message == "")
return;
- if(pl.classname != "player")
+ if not(IS_PLAYER(pl))
return;
if(gameover)
return;
magicear_matched = FALSE;
- dotrigger = ((source.classname == "player") && (source.deadflag == DEAD_NO) && ((ear.radius == 0) || (vlen(source.origin - ear.origin) <= ear.radius)));
+ dotrigger = ((IS_PLAYER(source)) && (source.deadflag == DEAD_NO) && ((ear.radius == 0) || (vlen(source.origin - ear.origin) <= ear.radius)));
domatch = ((ear.spawnflags & 32) || dotrigger);
if not(domatch)
self.nextthink = time + delta;
e = edict_num(self.cnt + 1);
- if(clienttype(e) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(e))
{
WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte(MSG_BROADCAST, TE_CSQC_PINGPLREPORT);
BADCVAR("g_arena");
BADCVAR("g_assault");
BADCVAR("g_ca");
+ BADCVAR("g_ca_teams");
BADCVAR("g_ctf");
BADCVAR("g_cts");
BADCVAR("g_dm");
BADCVAR("g_domination");
BADCVAR("g_domination_default_teams");
BADCVAR("g_freezetag");
+ BADCVAR("g_freezetag_teams");
BADCVAR("g_keepaway");
BADCVAR("g_keyhunt");
BADCVAR("g_keyhunt_teams");
- BADCVAR("g_keyhunt_teams");
BADCVAR("g_lms");
BADCVAR("g_nexball");
BADCVAR("g_onslaught");
BADCVAR("g_race");
BADCVAR("g_race_qualifying_timelimit");
- BADCVAR("g_runematch");
BADCVAR("g_tdm");
BADCVAR("g_tdm_teams");
BADCVAR("leadlimit");
BADCVAR("g_keyhunt_point_leadlimit");
BADPREFIX("g_mod_");
BADCVAR("g_nexball_goalleadlimit");
- BADCVAR("g_runematch_point_leadlimit");
BADCVAR("leadlimit_and_fraglimit");
BADCVAR("leadlimit_override");
BADCVAR("pausable");
BADCVAR("g_balance_teams_scorefactor");
BADCVAR("g_ban_sync_trusted_servers");
BADCVAR("g_ban_sync_uri");
+ BADCVAR("g_ca_teams_override");
BADCVAR("g_ctf_ignore_frags");
BADCVAR("g_domination_point_limit");
+ BADCVAR("g_freezetag_teams_override");
BADCVAR("g_friendlyfire");
BADCVAR("g_fullbrightitems");
BADCVAR("g_fullbrightplayers");
BADCVAR("g_mirrordamage");
BADCVAR("g_nexball_goallimit");
BADCVAR("g_powerups");
- BADCVAR("g_runematch_point_limit");
BADCVAR("g_start_delay");
BADCVAR("g_warmup");
BADCVAR("g_weapon_stay"); BADPRESUFFIX("g_", "_weapon_stay");
// needs to be done so early because of the constants they create
CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
+ CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
+ CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
MapInfo_Enumerate();
MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
compressShortVector_init();
- allowed_to_spawn = TRUE;
-
entity head;
head = nextent(world);
maxclients = 0;
head = nextent(head);
}
+ server_is_dedicated = (stof(cvar_defstring("is_dedicated")) ? TRUE : FALSE);
+
// needs to be done so early because of the constants they create
CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
+ CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
+ CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
addstat(STAT_SWITCHWEAPON, AS_INT, switchweapon);
addstat(STAT_SWITCHINGWEAPON, AS_INT, switchingweapon);
addstat(STAT_GAMESTARTTIME, AS_FLOAT, stat_game_starttime);
+ addstat(STAT_ROUNDSTARTTIME, AS_FLOAT, stat_round_starttime);
addstat(STAT_ALLOW_OLDNEXBEAM, AS_INT, stat_allow_oldnexbeam);
Nagger_Init();
addstat(STAT_HAGAR_LOAD, AS_INT, hagar_load);
- if(g_ca || g_freezetag)
- {
- addstat(STAT_REDALIVE, AS_INT, redalive_stat);
- addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
- addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
- addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
- }
- if(g_freezetag)
- {
- addstat(STAT_FROZEN, AS_INT, freezetag_frozen);
- addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, freezetag_revive_progress);
- }
-
// g_movementspeed hack
addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw);
addstat(STAT_MOVEVARS_MAXSPEED, AS_FLOAT, stat_sv_maxspeed);
&& ((self.autoscreenshot > 0) && (time > self.autoscreenshot)) )
{
self.autoscreenshot = -1;
- if(IS_REAL_CLIENT(self)) { stuffcmd(self, sprintf("\nscreenshot screenshots/autoscreenshot/%s-%s.jpg; echo \"^5A screenshot has been taken at request of the server.\"", GetMapname(), strftime(FALSE, "%s"))); }
- if(clienttype(self) == CLIENTTYPE_REAL) { stuffcmd(self, sprintf("\nscreenshot screenshots/autoscreenshot/%s-%s.jpg; echo \"^5A screenshot has been taken at request of the server.\"\n", GetMapname(), strftime(FALSE, "%s"))); }
++ if(IS_REAL_CLIENT(self)) { stuffcmd(self, sprintf("\nscreenshot screenshots/autoscreenshot/%s-%s.jpg; echo \"^5A screenshot has been taken at request of the server.\"\n", GetMapname(), strftime(FALSE, "%s"))); }
return;
}
FOR_EACH_CLIENT(other)
{
- if ((clienttype(other) == CLIENTTYPE_REAL) || (clienttype(other) == CLIENTTYPE_BOT && autocvar_sv_logscores_bots))
+ if ((IS_REAL_CLIENT(other)) || (IS_BOT_CLIENT(other) && autocvar_sv_logscores_bots))
{
s = strcat(":player:see-labels:", GetPlayerScoreString(other, 0), ":");
s = strcat(s, ftos(rint(time - other.jointime)), ":");
- if(IS_PLAYER(other) || g_arena || g_ca || g_lms)
- if(other.classname == "player" || g_arena || other.caplayer == 1 || g_lms)
++ if(IS_PLAYER(other) || g_arena || other.caplayer == 1 || g_lms)
s = strcat(s, ftos(other.team), ":");
else
s = strcat(s, "spectator:");
if (e.weaponentity.weaponentity)
e.weaponentity.weaponentity.effects = EF_NODRAW;
}
- if(clienttype(e) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(e))
{
stuffcmd(e, "\nscr_printspeed 1000000\n");
s = autocvar_sv_intermission_cdtrack;
PlayerStats_AddGlobalInfo(e);
PlayerStats_Shutdown();
WeaponStats_Shutdown();
+
+ Kill_Notification(NOTIF_ALL, world, MSG_CENTER, 0); // kill all centerprints now
if(autocvar_sv_eventlog)
GameLogEcho(":gameover");
tl = autocvar_timelimit;
tl += autocvar_timelimit_overtime;
cvar_set("timelimit", ftos(tl));
- string minutesPlural;
- if (autocvar_timelimit_overtime == 1)
- minutesPlural = " ^3minute";
- else
- minutesPlural = " ^3minutes";
-
- bcenterprint(
- strcat(
- "^3Now playing ^1OVERTIME^3!\n\n^3Added ^1",
- ftos(autocvar_timelimit_overtime),
- minutesPlural,
- " to the game!"
- )
- );
+
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_OVERTIME_TIME, autocvar_timelimit_overtime * 60);
}
float GetWinningCode(float fraglimitreached, float equality)
{
if (head.health > 0)
{
- if (head.team == COLOR_TEAM1) t1 = 1;
- if (head.team == COLOR_TEAM2) t2 = 1;
- if (head.team == COLOR_TEAM3) t3 = 1;
- if (head.team == COLOR_TEAM4) t4 = 1;
+ if (head.team == NUM_TEAM_1) t1 = 1;
+ if (head.team == NUM_TEAM_2) t2 = 1;
+ if (head.team == NUM_TEAM_3) t3 = 1;
+ if (head.team == NUM_TEAM_4) t4 = 1;
}
head = find(head, classname, "onslaught_generator");
}
{
// game over, only one team remains (or none)
ClearWinners();
- if (t1) SetWinners(team, COLOR_TEAM1);
- if (t2) SetWinners(team, COLOR_TEAM2);
- if (t3) SetWinners(team, COLOR_TEAM3);
- if (t4) SetWinners(team, COLOR_TEAM4);
+ if (t1) SetWinners(team, NUM_TEAM_1);
+ if (t2) SetWinners(team, NUM_TEAM_2);
+ if (t3) SetWinners(team, NUM_TEAM_3);
+ if (t4) SetWinners(team, NUM_TEAM_4);
dprint("Have a winner, ending game.\n");
return WINNING_YES;
}
status = WINNING_NO;
// as the timelimit has not yet passed just assume the defending team will win
- if(assault_attacker_team == COLOR_TEAM1)
+ if(assault_attacker_team == NUM_TEAM_1)
{
- SetWinners(team, COLOR_TEAM2);
+ SetWinners(team, NUM_TEAM_2);
}
else
{
- SetWinners(team, COLOR_TEAM1);
+ SetWinners(team, NUM_TEAM_1);
}
entity ent;
if(teamplay)
{
- team1_score = TeamScore_GetCompareValue(COLOR_TEAM1);
- team2_score = TeamScore_GetCompareValue(COLOR_TEAM2);
- team3_score = TeamScore_GetCompareValue(COLOR_TEAM3);
- team4_score = TeamScore_GetCompareValue(COLOR_TEAM4);
+ team1_score = TeamScore_GetCompareValue(NUM_TEAM_1);
+ team2_score = TeamScore_GetCompareValue(NUM_TEAM_2);
+ team3_score = TeamScore_GetCompareValue(NUM_TEAM_3);
+ team4_score = TeamScore_GetCompareValue(NUM_TEAM_4);
}
ClearWinners();
if (limit)
if (leaderfrags == limit - 1)
- Announce("1fragleft");
+ Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_REMAINING_FRAG_1);
else if (leaderfrags == limit - 2)
- Announce("2fragsleft");
+ Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_REMAINING_FRAG_2);
else if (leaderfrags == limit - 3)
- Announce("3fragsleft");
+ Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_REMAINING_FRAG_3);
}
}
FOR_EACH_PLAYER(head) if(head.deadflag == DEAD_NO)
{
- if(head.team == COLOR_TEAM1)
+ if(head.team == NUM_TEAM_1)
team1_score = 1;
- else if(head.team == COLOR_TEAM2)
+ else if(head.team == NUM_TEAM_2)
team2_score = 1;
- else if(head.team == COLOR_TEAM3)
+ else if(head.team == NUM_TEAM_3)
team3_score = 1;
- else if(head.team == COLOR_TEAM4)
+ else if(head.team == NUM_TEAM_4)
team4_score = 1;
}
for(head = world; (head = find(head, classname, "info_player_deathmatch")) != world; )
{
- if(head.team == COLOR_TEAM1)
+ if(head.team == NUM_TEAM_1)
team1_score = 1;
- else if(head.team == COLOR_TEAM2)
+ else if(head.team == NUM_TEAM_2)
team2_score = 1;
- else if(head.team == COLOR_TEAM3)
+ else if(head.team == NUM_TEAM_3)
team3_score = 1;
- else if(head.team == COLOR_TEAM4)
+ else if(head.team == NUM_TEAM_4)
team4_score = 1;
}
{
float t, i;
if(team1_score)
- t = COLOR_TEAM1;
+ t = NUM_TEAM_1;
else if(team2_score)
- t = COLOR_TEAM2;
+ t = NUM_TEAM_2;
else if(team3_score)
- t = COLOR_TEAM3;
+ t = NUM_TEAM_3;
else // if(team4_score)
- t = COLOR_TEAM4;
+ t = NUM_TEAM_4;
CheckAllowedTeams(world);
for(i = 0; i < MAX_TEAMSCORE; ++i)
{
- if(t != COLOR_TEAM1) if(c1 >= 0) TeamScore_AddToTeam(COLOR_TEAM1, i, -1000);
- if(t != COLOR_TEAM2) if(c2 >= 0) TeamScore_AddToTeam(COLOR_TEAM2, i, -1000);
- if(t != COLOR_TEAM3) if(c3 >= 0) TeamScore_AddToTeam(COLOR_TEAM3, i, -1000);
- if(t != COLOR_TEAM4) if(c4 >= 0) TeamScore_AddToTeam(COLOR_TEAM4, i, -1000);
+ if(t != NUM_TEAM_1) if(c1 >= 0) TeamScore_AddToTeam(NUM_TEAM_1, i, -1000);
+ if(t != NUM_TEAM_2) if(c2 >= 0) TeamScore_AddToTeam(NUM_TEAM_2, i, -1000);
+ if(t != NUM_TEAM_3) if(c3 >= 0) TeamScore_AddToTeam(NUM_TEAM_3, i, -1000);
+ if(t != NUM_TEAM_4) if(c4 >= 0) TeamScore_AddToTeam(NUM_TEAM_4, i, -1000);
}
AddWinners(team, t);
{
checkrules_suddendeathwarning = TRUE;
if(g_race && !g_race_qualifying)
- bcenterprint("^3Everyone, finish your lap! The race is over!");
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_RACE_FINISHLAP);
else
- bcenterprint("^3Now playing ^1OVERTIME^3!\n\n^3Keep fragging until we have a ^1winner^3!");
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_OVERTIME_FRAG);
}
}
else
{
other.health = 2342;
other.impulse = 0;
- if(clienttype(other) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(other))
{
msg_entity = other;
WriteByte(MSG_ONE, SVC_FINALE);
float altime;
FOR_EACH_REALCLIENT(self)
{
- if(self.classname == "spectator")
+ if(IS_SPEC(self))
{
if(self.enemy.typehitsound)
self.typehit_time = time;
void() spawnfunc_info_player_deathmatch; // needed for the other spawnpoints
void() spawnpoint_use;
string GetMapname();
- string ColoredTeamName(float t);
string admin_name(void)
{
#define move_out_of_solid(e) WarpZoneLib_MoveOutOfSolid(e)
-
string STR_PLAYER = "player";
string STR_SPECTATOR = "spectator";
string STR_OBSERVER = "observer";
float logfile_open;
float logfile;
- void bcenterprint(string s)
- {
- // TODO replace by MSG_ALL (would show it to spectators too, though)?
- entity head;
- FOR_EACH_PLAYER(head)
- if (IS_REAL_CLIENT(head))
- centerprint(head, s);
- }
-
void GameLogEcho(string s)
{
string fn;
get_cvars_f = f;
get_cvars_s = s;
+
MUTATOR_CALLHOOK(GetCvars);
+
+ Notification_GetCvars();
+
GetCvars_handleFloat(s, f, autoswitch, "cl_autoswitch");
GetCvars_handleFloat(s, f, cvar_cl_autoscreenshot, "cl_autoscreenshot");
GetCvars_handleString(s, f, cvar_g_xonoticversion, "g_xonoticversion");
}
}
- void backtrace(string msg)
- {
- float dev, war;
- dev = autocvar_developer;
- war = autocvar_prvm_backtraceforwarnings;
- cvar_set("developer", "1");
- cvar_set("prvm_backtraceforwarnings", "1");
- print("\n");
- print("--- CUT HERE ---\nWARNING: ");
- print(msg);
- print("\n");
- remove(world); // isn't there any better way to cause a backtrace?
- print("\n--- CUT UNTIL HERE ---\n");
- cvar_set("developer", ftos(dev));
- cvar_set("prvm_backtraceforwarnings", ftos(war));
- }
-
- string Team_ColorCode(float teamid)
- {
- if (teamid == COLOR_TEAM1)
- return "^1";
- else if (teamid == COLOR_TEAM2)
- return "^4";
- else if (teamid == COLOR_TEAM3)
- return "^3";
- else if (teamid == COLOR_TEAM4)
- return "^6";
- else
- return "^7";
- }
-
- string Team_ColorName(float t)
- {
- // fixme: Search for team entities and get their .netname's!
- if (t == COLOR_TEAM1)
- return "Red";
- if (t == COLOR_TEAM2)
- return "Blue";
- if (t == COLOR_TEAM3)
- return "Yellow";
- if (t == COLOR_TEAM4)
- return "Pink";
- return "Neutral";
- }
-
- string Team_ColorNameLowerCase(float t)
- {
- // fixme: Search for team entities and get their .netname's!
- if (t == COLOR_TEAM1)
- return "red";
- if (t == COLOR_TEAM2)
- return "blue";
- if (t == COLOR_TEAM3)
- return "yellow";
- if (t == COLOR_TEAM4)
- return "pink";
- return "neutral";
- }
-
- float ColourToNumber(string team_colour)
- {
- if (team_colour == "red")
- return COLOR_TEAM1;
-
- if (team_colour == "blue")
- return COLOR_TEAM2;
-
- if (team_colour == "yellow")
- return COLOR_TEAM3;
-
- if (team_colour == "pink")
- return COLOR_TEAM4;
-
- if (team_colour == "auto")
- return 0;
-
- return -1;
- }
-
- float NumberToTeamNumber(float number)
- {
- if (number == 1)
- return COLOR_TEAM1;
-
- if (number == 2)
- return COLOR_TEAM2;
-
- if (number == 3)
- return COLOR_TEAM3;
-
- if (number == 4)
- return COLOR_TEAM4;
-
- return -1;
- }
-
// decolorizes and team colors the player name when needed
string playername(entity p)
{
string t;
- if (teamplay && !intermission_running && p.classname == "player")
+ if (teamplay && !intermission_running && IS_PLAYER(p))
{
t = Team_ColorCode(p.team);
return strcat(t, strdecolorize(p.netname));
float g_bugrigs_speed_pow;
float g_bugrigs_steer;
- float g_touchexplode;
- float g_touchexplode_radius;
- float g_touchexplode_damage;
- float g_touchexplode_edgedamage;
- float g_touchexplode_force;
-
float sv_autotaunt;
float sv_taunt;
MUTATOR_ADD(mutator_spawn_near_teammate);
if(cvar("g_physical_items"))
MUTATOR_ADD(mutator_physical_items);
+ if(cvar("g_touchexplode"))
+ MUTATOR_ADD(mutator_touchexplode);
if(!g_minstagib)
{
if(cvar("g_invincible_projectiles"))
g_bugrigs_speed_pow = cvar("g_bugrigs_speed_pow");
g_bugrigs_steer = cvar("g_bugrigs_steer");
- g_touchexplode = cvar("g_touchexplode");
- g_touchexplode_radius = cvar("g_touchexplode_radius");
- g_touchexplode_damage = cvar("g_touchexplode_damage");
- g_touchexplode_edgedamage = cvar("g_touchexplode_edgedamage");
- g_touchexplode_force = cvar("g_touchexplode_force");
-
sv_clones = cvar("sv_clones");
- sv_gentle = cvar("sv_gentle");
sv_foginterval = cvar("sv_foginterval");
g_cloaked = cvar("g_cloaked");
if(g_cts)
g_warmup_allguns = cvar("g_warmup_allguns");
g_warmup_allow_timeout = cvar("g_warmup_allow_timeout");
- if ((g_race && g_race_qualifying == 2) || g_runematch || g_arena || g_assault || cvar("g_campaign"))
+ if ((g_race && g_race_qualifying == 2) || g_arena || g_assault || cvar("g_campaign"))
inWarmupStage = 0; // these modes cannot work together, sorry
g_pickup_respawntime_weapon = cvar("g_pickup_respawntime_weapon");
if(!g_weapon_stay)
g_weapon_stay = cvar("g_weapon_stay");
- if not(inWarmupStage && !g_ca)
- game_starttime = cvar("g_start_delay");
+ if not(inWarmupStage)
+ game_starttime = time + cvar("g_start_delay");
readplayerstartcvars();
}
return TRUE;
// sounds by players can be removed
if (autocvar_bot_sound_monopoly)
- if (clienttype(e) == CLIENTTYPE_REAL)
+ if (IS_REAL_CLIENT(e))
return FALSE;
// anything else may pass
return TRUE;
{
// gamemode related things
precache_model ("models/misc/chatbubble.spr");
- if (g_runematch)
- {
- precache_model ("models/runematch/curse.mdl");
- precache_model ("models/runematch/rune.mdl");
- }
#ifdef TTURRETS_ENABLED
if (autocvar_g_turrets)
#endif
}
- // sorry, but using \ in macros breaks line numbers
- #define WRITESPECTATABLE_MSG_ONE_VARNAME(varname,statement) entity varname; varname = msg_entity; FOR_EACH_REALCLIENT(msg_entity) if(msg_entity == varname || (IS_SPEC(msg_entity) && msg_entity.enemy == varname)) statement msg_entity = varname
- #define WRITESPECTATABLE_MSG_ONE(statement) WRITESPECTATABLE_MSG_ONE_VARNAME(oldmsg_entity, statement)
- #define WRITESPECTATABLE(msg,statement) if(msg == MSG_ONE) { WRITESPECTATABLE_MSG_ONE(statement); } else statement float WRITESPECTATABLE_workaround = 0
-
-
- void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num)
- {
- if (IS_REAL_CLIENT(e) && IS_CLIENT(e))
- {
- msg_entity = e;
- WRITESPECTATABLE_MSG_ONE({
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_CENTERPRINT_GENERIC);
- WriteByte(MSG_ONE, id);
- WriteString(MSG_ONE, s);
- if (id != 0 && s != "")
- {
- WriteByte(MSG_ONE, duration);
- WriteByte(MSG_ONE, countdown_num);
- }
- });
- }
- }
- void Send_CSQC_Centerprint_Generic_Expire(entity e, float id)
- {
- Send_CSQC_Centerprint_Generic(e, id, "", 1, 0);
- }
// WARNING: this kills the trace globals
#define EXACTTRIGGER_TOUCH if(WarpZoneLib_ExactTrigger_Touch()) return
#define EXACTTRIGGER_INIT WarpZoneLib_ExactTrigger_Init()
return uid2name(db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos))));
}
- string race_placeName(float pos) {
- if(floor((mod(pos, 100))/10) * 10 != 10) // examples: 12th, 111th, 213th will not execute this block
- {
- if(mod(pos, 10) == 1)
- return strcat(ftos(pos), "st");
- else if(mod(pos, 10) == 2)
- return strcat(ftos(pos), "nd");
- else if(mod(pos, 10) == 3)
- return strcat(ftos(pos), "rd");
- else
- return strcat(ftos(pos), "th");
- }
- else
- return strcat(ftos(pos), "th");
- }
-
float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance)
{
float m, i;
GameLogEcho(strcat(":ctf:", mode, ":", ftos(flagteam), ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
}
- string ctf_CaptureRecord(entity flag, entity player)
+ void ctf_CaptureRecord(entity flag, entity player)
{
- float cap_time, cap_record, success;
- string cap_message = string_null, refername;
+ entity tmp_entity;
+ float cap_record = ctf_captimerecord;
+ float cap_time = (time - flag.ctf_pickuptime);
+ string refername = db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"));
- if((autocvar_g_ctf_captimerecord_always) || (player_count - currentbots))
+ // notify about shit
+ FOR_EACH_REALCLIENT(tmp_entity)
{
- cap_record = ctf_captimerecord;
- cap_time = (time - flag.ctf_pickuptime);
-
- refername = db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"));
- refername = ((refername == player.netname) ? "their" : strcat(refername, "^7's"));
-
- if(!ctf_captimerecord)
- { cap_message = strcat(" in ", ftos_decimals(cap_time, 2), " seconds"); success = TRUE; }
- else if(cap_time < cap_record)
- { cap_message = strcat(" in ", ftos_decimals(cap_time, 2), " seconds, breaking ", refername, " previous record of ", ftos_decimals(cap_record, 2), " seconds"); success = TRUE; }
- else
- { cap_message = strcat(" in ", ftos_decimals(cap_time, 2), " seconds, failing to break ", refername, " record of ", ftos_decimals(cap_record, 2), " seconds"); success = FALSE; }
+ if(tmp_entity.CAPTURE_VERBOSE)
+ {
+ if(!ctf_captimerecord) { Send_Notification(NOTIF_ONE_ONLY, tmp_entity, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_CAPTURE_TIME_), player.netname, (cap_time * 100)); }
+ else if(cap_time < cap_record) { Send_Notification(NOTIF_ONE_ONLY, tmp_entity, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_CAPTURE_BROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
+ else { Send_Notification(NOTIF_ONE_ONLY, tmp_entity, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_CAPTURE_UNBROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
+ }
+ else { Send_Notification(NOTIF_ONE_ONLY, tmp_entity, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_CAPTURE_), player.netname); }
+ }
- if(success)
+ // the previous notification broadcast is only sent to real clients, this will notify server log too
+ if(server_is_dedicated)
+ {
+ if(autocvar_notification_ctf_capture_verbose)
{
- ctf_captimerecord = cap_time;
- db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time"), ftos(cap_time));
- db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"), player.netname);
- write_recordmarker(player, (time - cap_time), cap_time);
- }
+ if(!ctf_captimerecord) { Local_Notification(MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_CAPTURE_TIME_), player.netname, (cap_time * 100)); }
+ else if(cap_time < cap_record) { Local_Notification(MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_CAPTURE_BROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
+ else { Local_Notification(MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_CAPTURE_UNBROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
+ }
+ else { Local_Notification(MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_CAPTURE_), player.netname); }
}
- return cap_message;
+ // write that shit in the database
+ if((!ctf_captimerecord) || (cap_time < cap_record))
+ {
+ ctf_captimerecord = cap_time;
+ db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time"), ftos(cap_time));
+ db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"), player.netname);
+ write_recordmarker(player, (time - cap_time), cap_time);
+ }
}
void ctf_FlagcarrierWaypoints(entity player)
float updated_status = ctf_CaptureShield_CheckStatus(player);
if((wanted_status == player.ctf_captureshielded) && (updated_status != wanted_status)) // 0: shield only, 1: unshield only
{
- if(updated_status) // TODO csqc notifier for this // Samual: How?
- Send_CSQC_Centerprint_Generic(player, CPID_CTF_CAPTURESHIELD, "^3You are now ^4shielded^3 from the flag\n^3for ^1too many unsuccessful attempts^3 to capture.\n\n^3Make some defensive scores before trying again.", 5, 0);
- else
- Send_CSQC_Centerprint_Generic(player, CPID_CTF_CAPTURESHIELD, "^3You are now free.\n\n^3Feel free to ^1try to capture^3 the flag again\n^3if you think you will succeed.", 5, 0);
-
+ Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((updated_status) ? CENTER_CTF_CAPTURESHIELD_SHIELDED : CENTER_CTF_CAPTURESHIELD_FREE));
player.ctf_captureshielded = updated_status;
}
}
vector othermid = (other.absmin + other.absmax) * 0.5;
Damage(other, self, self, 0, DEATH_HURTTRIGGER, mymid, normalize(othermid - mymid) * ctf_captureshield_force);
- Send_CSQC_Centerprint_Generic(other, CPID_CTF_CAPTURESHIELD, "^3You are ^4shielded^3 from the flag\n^3for ^1too many unsuccessful attempts^3 to capture.\n\n^3Get some defensive scores before trying again.", 5, 0);
+ Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED);
}
void ctf_CaptureShield_Spawn(entity flag)
flag.ctf_status = FLAG_DROPPED;
// messages and sounds
- Send_KillNotification(player.netname, flag.netname, "", INFO_LOSTFLAG, MSG_INFO);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_LOST_), player.netname);
sound(flag, CH_TRIGGER, flag.snd_flag_dropped, VOL_BASE, ATTN_NONE);
ctf_EventLog("dropped", player.team, player);
FOR_EACH_REALPLAYER(tmp_player)
{
if(tmp_player == sender)
- centerprint(tmp_player, strcat("You passed the ", flag.netname, " to ", player.netname));
+ Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PASS_SENT_), player.netname);
else if(tmp_player == player)
- centerprint(tmp_player, strcat("You received the ", flag.netname, " from ", sender.netname));
+ Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PASS_RECEIVED_), sender.netname);
else if(!IsDifferentTeam(tmp_player, sender))
- centerprint(tmp_player, strcat(sender.netname, " passed the ", flag.netname, " to ", player.netname));
+ Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PASS_OTHER_), sender.netname, player.netname);
}
// create new waypoint
if not(player) { return; } // without someone to give the reward to, we can't possibly cap
// messages and sounds
- Send_KillNotification(player.netname, enemy_flag.netname, ctf_CaptureRecord(enemy_flag, player), INFO_CAPTUREFLAG, MSG_INFO);
+ Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_2(enemy_flag, CENTER_CTF_CAPTURE_));
+ ctf_CaptureRecord(enemy_flag, player);
sound(player, CH_TRIGGER, flag.snd_flag_capture, VOL_BASE, ATTN_NONE);
switch(capturetype)
void ctf_Handle_Return(entity flag, entity player)
{
// messages and sounds
- //centerprint(player, strcat("You returned the ", flag.netname));
- Send_KillNotification(player.netname, flag.netname, "", INFO_RETURNFLAG, MSG_INFO);
+ Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_RETURN_));
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_RETURN_), player.netname);
sound(player, CH_TRIGGER, flag.snd_flag_returned, VOL_BASE, ATTN_NONE);
ctf_EventLog("return", flag.team, player);
{
// declarations
entity tmp_player; // temporary entity which the FOR_EACH_PLAYER loop uses to scan players
- string verbosename; // holds the name of the player OR no name at all for printing in the centerprints
float pickup_dropped_score; // used to calculate dropped pickup score
// attach the flag to the player
}
// messages and sounds
- Send_KillNotification (player.netname, flag.netname, "", INFO_GOTFLAG, MSG_INFO);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_PICKUP_), player.netname);
sound(player, CH_TRIGGER, flag.snd_flag_taken, VOL_BASE, ATTN_NONE);
- verbosename = ((autocvar_g_ctf_flag_pickup_verbosename) ? strcat(Team_ColorCode(player.team), "(^7", player.netname, Team_ColorCode(player.team), ") ") : "");
-
+
FOR_EACH_REALPLAYER(tmp_player)
{
if(tmp_player == player)
{
- centerprint(tmp_player, strcat("You got the ", flag.netname, "!"));
- //if(ctf_stalemate) { centerprint(tmp_player, "Stalemate! Enemies can see you on radar!"); }
+ Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PICKUP_));
+ if(ctf_stalemate) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_STALEMATE_CARRIER); }
+ }
+ else if(!IsDifferentTeam(tmp_player, player) && tmp_player != player)
+ {
+ if(tmp_player.PICKUP_TEAM_VERBOSE)
+ Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, CENTER_CTF_PICKUP_TEAM_VERBOSE, Team_ColorCode(player.team), player.netname);
+ else
+ Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, CENTER_CTF_PICKUP_TEAM, Team_ColorCode(player.team));
+ }
+ else if(IsDifferentTeam(tmp_player, player))
+ {
+ if(tmp_player.PICKUP_ENEMY_VERBOSE)
+ Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY_VERBOSE, Team_ColorCode(player.team), player.netname);
+ else
+ Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY, Team_ColorCode(player.team));
}
- //else if(!IsDifferentTeam(tmp_player, player))
- // centerprint(tmp_player, strcat("Your ", Team_ColorCode(player.team), "team mate ", verbosename, "^7got the flag! Protect them!"));
- else if(!IsDifferentTeam(tmp_player, flag))
- centerprint(tmp_player, strcat("The ", Team_ColorCode(player.team), "enemy ", verbosename, "^7got your flag! Retrieve it!"));
}
// scoring
{
switch(returntype)
{
- case RETURN_DROPPED: bprint("The ", flag.netname, " was dropped in the base and returned itself\n"); break;
- case RETURN_DAMAGE: bprint("The ", flag.netname, " was destroyed and returned to base\n"); break;
- case RETURN_SPEEDRUN: bprint("The ", flag.netname, " became impatient after ", ftos_decimals(ctf_captimerecord, 2), " seconds and returned itself\n"); break;
- case RETURN_NEEDKILL: bprint("The ", flag.netname, " fell somewhere it couldn't be reached and returned to base\n"); break;
+ case RETURN_DROPPED: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_DROPPED_)); break;
+ case RETURN_DAMAGE: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_DAMAGED_)); break;
+ case RETURN_SPEEDRUN: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_SPEEDRUN_), ctf_captimerecord); break;
+ case RETURN_NEEDKILL: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_NEEDKILL_)); break;
default:
case RETURN_TIMEOUT:
- { bprint("The ", flag.netname, " has returned to base\n"); break; }
+ { Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_TIMEOUT_)); break; }
}
sound(flag, CH_TRIGGER, flag.snd_flag_respawn, VOL_BASE, ATTN_NONE);
ctf_EventLog("returned", flag.team, world);
switch(tmp_entity.team)
{
- case COLOR_TEAM1: ++stale_red_flags; break;
- case COLOR_TEAM2: ++stale_blue_flags; break;
+ case NUM_TEAM_1: ++stale_red_flags; break;
+ case NUM_TEAM_2: ++stale_blue_flags; break;
}
}
}
if not(wpforenemy_announced)
{
FOR_EACH_REALPLAYER(tmp_entity)
- if(tmp_entity.flagcarried)
- centerprint(tmp_entity, "Stalemate! Enemies can now see you on radar!");
- else
- centerprint(tmp_entity, "Stalemate! Flag carriers can now be seen by enemies on radar!");
+ Send_Notification(NOTIF_ONE, tmp_entity, MSG_CENTER, ((tmp_entity.flagcarried) ? CENTER_CTF_STALEMATE_CARRIER : CENTER_CTF_STALEMATE_OTHER));
wpforenemy_announced = TRUE;
}
else
return; // do nothing
}
- else if(toucher.classname != "player") // The flag just touched an object, most likely the world
+ else if not(IS_PLAYER(toucher)) // The flag just touched an object, most likely the world
{
if(time > self.wait) // if we haven't in a while, play a sound/effect
{
case FLAG_PASSING:
{
- if((toucher.classname == "player") && (toucher.deadflag == DEAD_NO) && (toucher != self.pass_sender))
+ if((IS_PLAYER(toucher)) && (toucher.deadflag == DEAD_NO) && (toucher != self.pass_sender))
{
if(IsDifferentTeam(toucher, self.pass_sender))
ctf_Handle_Return(self, toucher);
void ctf_Reset()
{
if(self.owner)
- if(self.owner.classname == "player")
+ if(IS_PLAYER(self.owner))
ctf_Handle_Throw(self.owner, world, DROP_RESET);
ctf_RespawnFlag(self);
self.bot_basewaypoint = self.nearestwaypoint;
// waypointsprites
- WaypointSprite_SpawnFixed(((self.team == COLOR_TEAM1) ? "redbase" : "bluebase"), self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, FALSE));
+ WaypointSprite_SpawnFixed(((self.team == NUM_TEAM_1) ? "redbase" : "bluebase"), self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, FALSE));
WaypointSprite_UpdateTeamRadar(self.wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, FALSE));
// captureshield setup
flag.ctf_worldflagnext = ctf_worldflaglist; // link flag into ctf_worldflaglist
ctf_worldflaglist = flag;
- setattachment(flag, world, "");
+ setattachment(flag, world, "");
- flag.netname = ((teamnumber) ? "^1RED^7 flag" : "^4BLUE^7 flag");
- flag.team = ((teamnumber) ? COLOR_TEAM1 : COLOR_TEAM2); // COLOR_TEAM1: color 4 team (red) - COLOR_TEAM2: color 13 team (blue)
+ flag.netname = ((teamnumber) ? "^1REPLACETHIS^7" : "^4REPLACETHIS^7"); // ((teamnumber) ? "^1RED^7 flag" : "^4BLUE^7 flag");
+ flag.team = ((teamnumber) ? NUM_TEAM_1 : NUM_TEAM_2); // NUM_TEAM_1: color 4 team (red) - NUM_TEAM_2: color 13 team (blue)
flag.items = ((teamnumber) ? IT_KEY2 : IT_KEY1); // IT_KEY2: gold key (redish enough) - IT_KEY1: silver key (bluish enough)
flag.classname = "item_flag_team";
flag.target = "###item###"; // wut?
frag_target.wps_helpme_time = time;
WaypointSprite_HelpMePing(frag_target.wps_flagcarrier);
}
+ // todo: add notification for when flag carrier needs help?
}
return FALSE;
}
MUTATOR_HOOKFUNCTION(ctf_PlayerDies)
{
- if((frag_attacker != frag_target) && (frag_attacker.classname == "player") && (frag_target.flagcarried))
+ if((frag_attacker != frag_target) && (IS_PLAYER(frag_target)) && (frag_target.flagcarried))
{
PlayerTeamScore_AddScore(frag_attacker, autocvar_g_ctf_score_kill);
PlayerScore_Add(frag_attacker, SP_CTF_FCKILLS, 1);
while(head) // find the closest acceptable target to pass to
{
- if(head.classname == "player" && head.deadflag == DEAD_NO)
+ if(IS_PLAYER(head) && head.deadflag == DEAD_NO)
if(head != player && !IsDifferentTeam(head, player))
if(!head.speedrunning && !head.vehicle)
{
{
if(autocvar_g_ctf_pass_request && !player.flagcarried && head.flagcarried)
{
- if(clienttype(head) == CLIENTTYPE_BOT)
+ if(IS_BOT_CLIENT(head))
{
- centerprint(player, strcat("Requesting ", head.netname, " to pass you the ", head.flagcarried.netname));
+ Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PASS_REQUESTING, head.netname);
ctf_Handle_Throw(head, player, DROP_PASS);
}
else
{
- centerprint(head, strcat(player.netname, " requests you to pass the ", head.flagcarried.netname));
- centerprint(player, strcat("Requesting ", head.netname, " to pass you the ", head.flagcarried.netname));
+ Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_CTF_PASS_REQUESTED, player.netname);
+ Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PASS_REQUESTING, head.netname);
}
player.throw_antispam = time + autocvar_g_ctf_pass_wait;
return TRUE;
}
else
{
- centerprint(player, strcat("Too many flag throws, throwing disabled for ", ftos(rint((player.throw_prevtime + autocvar_g_ctf_throw_punish_delay) - time)), " seconds."));
+ Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_FLAG_THROW_PUNISH, rint((player.throw_prevtime + autocvar_g_ctf_throw_punish_delay) - time));
return FALSE;
}
}
{
if(self.flagcarried)
{
- bprint("The ", self.flagcarried.netname, " was returned to base by its carrier\n");
- ctf_RespawnFlag(self);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(self.flagcarried, INFO_CTF_FLAGRETURN_ABORTRUN_));
+ ctf_RespawnFlag(self.flagcarried);
return TRUE;
}
return TRUE;
}
+ MUTATOR_HOOKFUNCTION(ctf_GetCvars)
+ {
+ GetCvars_handleFloat(get_cvars_s, get_cvars_f, CAPTURE_VERBOSE, "notification_ctf_capture_verbose");
+ GetCvars_handleFloat(get_cvars_s, get_cvars_f, PICKUP_TEAM_VERBOSE, "notification_ctf_pickup_team_verbose");
+ GetCvars_handleFloat(get_cvars_s, get_cvars_f, PICKUP_ENEMY_VERBOSE, "notification_ctf_pickup_enemy_verbose");
+ return TRUE;
+ }
+
// ==========
// Spawnfuncs
{
if(g_assault) { remove(self); return; }
- self.team = COLOR_TEAM1; // red
+ self.team = NUM_TEAM_1; // red
spawnfunc_info_player_deathmatch();
}
{
if(g_assault) { remove(self); return; }
- self.team = COLOR_TEAM2; // blue
+ self.team = NUM_TEAM_2; // blue
spawnfunc_info_player_deathmatch();
}
{
if(g_assault) { remove(self); return; }
- self.team = COLOR_TEAM3; // yellow
+ self.team = NUM_TEAM_3; // yellow
spawnfunc_info_player_deathmatch();
}
{
if(g_assault) { remove(self); return; }
- self.team = COLOR_TEAM4; // purple
+ self.team = NUM_TEAM_4; // purple
spawnfunc_info_player_deathmatch();
}
if(find(world, classname, "ctf_team") == world)
{
print("No ""ctf_team"" entities found on this map, creating them anyway.\n");
- ctf_SpawnTeam("Red", COLOR_TEAM1 - 1);
- ctf_SpawnTeam("Blue", COLOR_TEAM2 - 1);
+ ctf_SpawnTeam("Red", NUM_TEAM_1 - 1);
+ ctf_SpawnTeam("Blue", NUM_TEAM_2 - 1);
}
ctf_ScoreRules();
MUTATOR_HOOK(VehicleExit, ctf_VehicleExit, CBC_ORDER_ANY);
MUTATOR_HOOK(AbortSpeedrun, ctf_AbortSpeedrun, CBC_ORDER_ANY);
MUTATOR_HOOK(HavocBot_ChooseRule, ctf_BotRoles, CBC_ORDER_ANY);
+ MUTATOR_HOOK(GetCvars, ctf_GetCvars, CBC_ORDER_ANY);
MUTATOR_ONADD
{
{
entity head;
float old_delay, old_team, real_team;
+ string msg = "dom-neut";
// now that the delay has expired, switch to the latest team to lay claim to this point
head = self.owner;
SUB_UseTargets ();
self.delay = old_delay;
self.team = old_team;
-
- switch(self.goalentity.team)
+
+ switch(self.team)
{
- case COLOR_TEAM1:
- WaypointSprite_UpdateSprites(self.sprite, "dom-red", "", "");
- break;
- case COLOR_TEAM2:
- WaypointSprite_UpdateSprites(self.sprite, "dom-blue", "", "");
- break;
- case COLOR_TEAM3:
- WaypointSprite_UpdateSprites(self.sprite, "dom-yellow", "", "");
- break;
- case COLOR_TEAM4:
- WaypointSprite_UpdateSprites(self.sprite, "dom-pink", "", "");
+ case NUM_TEAM_1: msg = "dom-red"; break;
+ case NUM_TEAM_2: msg = "dom-blue"; break;
+ case NUM_TEAM_3: msg = "dom-yellow"; break;
+ case NUM_TEAM_4: msg = "dom-pink"; break;
}
+ WaypointSprite_UpdateSprites(self.sprite, msg, "", "");
+
total_pps = 0, pps_red = 0, pps_blue = 0, pps_yellow = 0, pps_pink = 0;
for(head = world; (head = find(head, classname, "dom_controlpoint")) != world; )
{
wait_time = head.wait;
switch(head.goalentity.team)
{
- case COLOR_TEAM1:
+ case NUM_TEAM_1:
pps_red += points/wait_time;
break;
- case COLOR_TEAM2:
+ case NUM_TEAM_2:
pps_blue += points/wait_time;
break;
- case COLOR_TEAM3:
+ case NUM_TEAM_3:
pps_yellow += points/wait_time;
break;
- case COLOR_TEAM4:
+ case NUM_TEAM_4:
pps_pink += points/wait_time;
}
total_pps += points/wait_time;
void dompointtouch()
{
entity head;
- if (other.classname != "player")
+ if not(IS_PLAYER(other))
return;
if (other.health < 1)
return;
{
float numteams = ((autocvar_g_domination_teams_override < 2) ? autocvar_g_domination_default_teams : autocvar_g_domination_teams_override);
- dom_spawnteam("Red", COLOR_TEAM1-1, "models/domination/dom_red.md3", 0, "domination/claim.wav", "", "Red team has captured a control point");
- dom_spawnteam("Blue", COLOR_TEAM2-1, "models/domination/dom_blue.md3", 0, "domination/claim.wav", "", "Blue team has captured a control point");
+ dom_spawnteam("Red", NUM_TEAM_1-1, "models/domination/dom_red.md3", 0, "domination/claim.wav", "", "Red team has captured a control point");
+ dom_spawnteam("Blue", NUM_TEAM_2-1, "models/domination/dom_blue.md3", 0, "domination/claim.wav", "", "Blue team has captured a control point");
if(numteams > 2)
- dom_spawnteam("Yellow", COLOR_TEAM3-1, "models/domination/dom_yellow.md3", 0, "domination/claim.wav", "", "Yellow team has captured a control point");
+ dom_spawnteam("Yellow", NUM_TEAM_3-1, "models/domination/dom_yellow.md3", 0, "domination/claim.wav", "", "Yellow team has captured a control point");
if(numteams > 3)
- dom_spawnteam("Pink", COLOR_TEAM4-1, "models/domination/dom_pink.md3", 0, "domination/claim.wav", "", "Pink team has captured a control point");
+ dom_spawnteam("Pink", NUM_TEAM_4-1, "models/domination/dom_pink.md3", 0, "domination/claim.wav", "", "Pink team has captured a control point");
dom_spawnteam("", 0, "models/domination/dom_unclaimed.md3", 0, "", "", "");
}
- void freezetag_Initialize()
+ .float freezetag_frozen_time;
+ .float freezetag_frozen_timeout;
+ .float freezetag_revive_progress;
+ .entity freezetag_ice;
+ #define ICE_MAX_ALPHA 1
+ #define ICE_MIN_ALPHA 0.1
+ float freezetag_teams;
+
+ void freezetag_count_alive_players()
{
- precache_model("models/ice/ice.md3");
- warmup = time + autocvar_g_start_delay + autocvar_g_freezetag_warmup;
- ScoreRules_freezetag();
+ entity e;
+ total_players = redalive = bluealive = yellowalive = pinkalive = 0;
+ FOR_EACH_PLAYER(e) {
+ if(e.team == NUM_TEAM_1 && e.health >= 1)
+ {
+ ++total_players;
+ if (!e.freezetag_frozen) ++redalive;
+ }
+ else if(e.team == NUM_TEAM_2 && e.health >= 1)
+ {
+ ++total_players;
+ if (!e.freezetag_frozen) ++bluealive;
+ }
+ else if(e.team == NUM_TEAM_3 && e.health >= 1)
+ {
+ ++total_players;
+ if (!e.freezetag_frozen) ++yellowalive;
+ }
+ else if(e.team == NUM_TEAM_4 && e.health >= 1)
+ {
+ ++total_players;
+ if (!e.freezetag_frozen) ++pinkalive;
+ }
+ }
+ FOR_EACH_REALCLIENT(e) {
+ e.redalive_stat = redalive;
+ e.bluealive_stat = bluealive;
+ e.yellowalive_stat = yellowalive;
+ e.pinkalive_stat = pinkalive;
+ }
}
+ #define FREEZETAG_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0))
+ #define FREEZETAG_ALIVE_TEAMS_OK() (FREEZETAG_ALIVE_TEAMS() == freezetag_teams)
- void freezetag_CheckWinner()
+ float prev_total_players;
+ float freezetag_CheckTeams()
{
- if(time <= game_starttime) // game didn't even start yet! nobody can win in that case.
- return;
+ if(FREEZETAG_ALIVE_TEAMS_OK())
+ {
+ if(prev_total_players > 0)
+ Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
+ prev_total_players = -1;
+ return 1;
+ }
+ if(prev_total_players != total_players)
+ {
+ float p1 = 0, p2 = 0, p3 = 0, p4 = 0;
+ if(!redalive) p1 = NUM_TEAM_1;
+ if(!bluealive) p2 = NUM_TEAM_2;
+ if(freezetag_teams >= 3)
+ if(!yellowalive) p3 = NUM_TEAM_3;
+ if(freezetag_teams >= 4)
+ if(!pinkalive) p4 = NUM_TEAM_4;
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, p1, p2, p3, p4);
+ prev_total_players = total_players;
+ }
+ return 0;
+ }
- if(next_round || (time > warmup - autocvar_g_freezetag_warmup && time < warmup))
- return; // already waiting for next round to start
+ float freezetag_getWinnerTeam()
+ {
+ float winner_team = 0;
+ if(redalive >= 1)
+ winner_team = NUM_TEAM_1;
+ if(bluealive >= 1)
+ {
+ if(winner_team) return 0;
+ winner_team = NUM_TEAM_2;
+ }
+ if(yellowalive >= 1)
+ {
+ if(winner_team) return 0;
+ winner_team = NUM_TEAM_3;
+ }
+ if(pinkalive >= 1)
+ {
+ if(winner_team) return 0;
+ winner_team = NUM_TEAM_4;
+ }
+ if(winner_team)
+ return winner_team;
+ return -1; // no player left
+ }
- if((redalive >= 1 && bluealive >= 1)
- || (redalive >= 1 && yellowalive >= 1)
- || (redalive >= 1 && pinkalive >= 1)
- || (bluealive >= 1 && yellowalive >= 1)
- || (bluealive >= 1 && pinkalive >= 1)
- || (yellowalive >= 1 && pinkalive >= 1))
- return; // we still have active players on two or more teams, nobody won yet
+ float freezetag_CheckWinner()
+ {
+ entity e;
+ if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
+ {
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_OVER);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_OVER);
+ FOR_EACH_PLAYER(e)
+ e.freezetag_frozen_timeout = 0;
+ round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
+ return 1;
+ }
- entity e, winner;
- string teamname;
- winner = world;
+ if(FREEZETAG_ALIVE_TEAMS() > 1)
+ return 0;
- FOR_EACH_PLAYER(e)
+ float winner_team;
+ winner_team = freezetag_getWinnerTeam();
+ if(winner_team > 0)
{
- if(e.freezetag_frozen == 0 && e.health >= 1) // here's one player from the winning team... good
- {
- winner = e;
- break; // break, we found the winner
- }
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM_4(winner_team, CENTER_ROUND_TEAM_WIN_));
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(winner_team, INFO_ROUND_TEAM_WIN_));
+ TeamScore_AddToTeam(winner_team, ST_SCORE, +1);
}
-
- if(winner != world) // just in case a winner wasn't found
+ else if(winner_team == -1)
{
- if(winner.team == COLOR_TEAM1)
- teamname = "^1Red Team";
- else if(winner.team == COLOR_TEAM2)
- teamname = "^4Blue Team";
- else if(winner.team == COLOR_TEAM3)
- teamname = "^3Yellow Team";
- else
- teamname = "^6Pink Team";
- FOR_EACH_PLAYER(e) {
- centerprint(e, strcat(teamname, "^5 wins the round, all other teams were frozen.\n"));
- }
- bprint(teamname, "^5 wins the round since all the other teams were frozen.\n");
- TeamScore_AddToTeam(winner.team, ST_SCORE, +1);
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_TIED);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_TIED);
}
- next_round = time + 5;
+ FOR_EACH_PLAYER(e)
+ e.freezetag_frozen_timeout = 0;
+ round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
+ return 1;
}
// this is needed to allow the player to turn his view around (fixangle can't
self.nextthink = time;
}
+ void freezetag_Add_Score(entity attacker)
+ {
+ if(attacker == self)
+ {
+ // you froze your own dumb self
+ // counted as "suicide" already
+ PlayerScore_Add(self, SP_SCORE, -1);
+ }
+ else if(IS_PLAYER(attacker))
+ {
+ // got frozen by an enemy
+ // counted as "kill" and "death" already
+ PlayerScore_Add(self, SP_SCORE, -1);
+ PlayerScore_Add(attacker, SP_SCORE, +1);
+ }
+ // else nothing - got frozen by the game type rules themselves
+ }
+
void freezetag_Freeze(entity attacker)
{
if(self.freezetag_frozen)
return;
self.freezetag_frozen = 1;
+ self.freezetag_frozen_time = time;
self.freezetag_revive_progress = 0;
self.health = 1;
+ if(autocvar_g_freezetag_frozen_maxtime > 0)
+ self.freezetag_frozen_timeout = time + autocvar_g_freezetag_frozen_maxtime;
+
+ freezetag_count_alive_players();
entity ice;
ice = spawn();
ice.think = freezetag_Ice_Think;
ice.nextthink = time;
ice.frame = floor(random() * 21); // ice model has 20 different looking frames
+ ice.alpha = ICE_MAX_ALPHA;
+ ice.colormod = Team_ColorRGB(self.team);
+ ice.glowmod = ice.colormod;
setmodel(ice, "models/ice/ice.md3");
- entity oldself;
- oldself = self;
- self = ice;
- freezetag_Ice_Think();
- self = oldself;
+ self.freezetag_ice = ice;
RemoveGrapplingHook(self);
// add waypoint
WaypointSprite_Spawn("freezetag_frozen", 0, 0, self, '0 0 64', world, self.team, self, waypointsprite_attached, TRUE, RADARICON_WAYPOINT, '0.25 0.90 1');
- if(attacker == self)
- {
- // you froze your own dumb self
- // counted as "suicide" already
- PlayerScore_Add(self, SP_SCORE, -1);
- }
- else if(IS_PLAYER(attacker))
- {
- // got frozen by an enemy
- // counted as "kill" and "death" already
- PlayerScore_Add(self, SP_SCORE, -1);
- PlayerScore_Add(attacker, SP_SCORE, +1);
- }
- else
- {
- // nothing - got frozen by the game type rules themselves
- }
+ freezetag_Add_Score(attacker);
}
void freezetag_Unfreeze(entity attacker)
{
self.freezetag_frozen = 0;
+ self.freezetag_frozen_time = 0;
+ self.freezetag_frozen_timeout = 0;
self.freezetag_revive_progress = 0;
- self.health = autocvar_g_balance_health_start;
- // remove the ice block
- entity ice;
- for(ice = world; (ice = find(ice, classname, "freezetag_ice")); ) if(ice.owner == self)
- {
- remove(ice);
- break;
- }
+ remove(self.freezetag_ice);
+ self.freezetag_ice = world;
- // remove waypoint
if(self.waypointsprite_attached)
WaypointSprite_Kill(self.waypointsprite_attached);
}
MUTATOR_HOOKFUNCTION(freezetag_RemovePlayer)
{
- if(self.freezetag_frozen == 0 && self.health >= 1)
- {
- if(self.team == COLOR_TEAM1)
- --redalive;
- else if(self.team == COLOR_TEAM2)
- --bluealive;
- else if(self.team == COLOR_TEAM3)
- --yellowalive;
- else if(self.team == COLOR_TEAM4)
- --pinkalive;
- --totalalive;
- }
-
- if(total_players > 2) // only check for winners if we had more than two players (one of them left, don't let the other player win just because of that)
- freezetag_CheckWinner();
-
+ self.health = 0; // neccessary to update correctly alive stats
freezetag_Unfreeze(world);
-
+ freezetag_count_alive_players();
return 1;
}
MUTATOR_HOOKFUNCTION(freezetag_PlayerDies)
{
- if(self.freezetag_frozen == 0)
+ if(round_handler_IsActive())
+ if(round_handler_CountdownRunning())
{
- if(self.team == COLOR_TEAM1)
- --redalive;
- else if(self.team == COLOR_TEAM2)
- --bluealive;
- else if(self.team == COLOR_TEAM3)
- --yellowalive;
- else if(self.team == COLOR_TEAM4)
- --pinkalive;
- --totalalive;
+ if(self.freezetag_frozen)
+ freezetag_Unfreeze(world);
+ freezetag_count_alive_players();
+ return 1; // let the player die so that he can respawn whenever he wants
+ }
- freezetag_Freeze(frag_attacker);
+ // Cases DEATH_TEAMCHANGE and DEATH_AUTOTEAMCHANGE are needed to fix a bug whe
+ // you succeed changing team through the menu: you both really die (gibbing) and get frozen
+ if(ITEM_DAMAGE_NEEDKILL(frag_deathtype)
+ || frag_deathtype == DEATH_TEAMCHANGE || frag_deathtype == DEATH_AUTOTEAMCHANGE)
+ {
+ // let the player die, he will be automatically frozen when he respawns
+ if(!self.freezetag_frozen)
+ {
+ freezetag_Add_Score(frag_attacker);
+ freezetag_count_alive_players();
+ }
+ else
+ freezetag_Unfreeze(world); // remove ice
+ self.freezetag_frozen_timeout = -2; // freeze on respawn
+ return 1;
}
+ if(self.freezetag_frozen)
+ return 1;
+
+ freezetag_Freeze(frag_attacker);
+
if(frag_attacker == frag_target || frag_attacker == world)
{
- if(frag_target.classname == STR_PLAYER)
+ if(IS_PLAYER(frag_target))
- centerprint(frag_target, "^1You froze yourself.\n");
- bprint("^7", frag_target.netname, "^1 froze himself.\n");
+ Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_SELF);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_SELF, frag_target.netname);
}
else
{
- if(frag_target.classname == STR_PLAYER)
+ if(IS_PLAYER(frag_target))
- centerprint(frag_target, strcat("^1You were frozen by ^7", frag_attacker.netname, ".\n"));
+ Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_FROZEN, frag_attacker.netname);
- if(frag_attacker.classname == STR_PLAYER)
+ if(IS_PLAYER(frag_attacker))
- centerprint(frag_attacker, strcat("^2You froze ^7", frag_target.netname, ".\n"));
- bprint("^7", frag_target.netname, "^1 was frozen by ^7", frag_attacker.netname, ".\n");
+ Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_FREEZETAG_FREEZE, frag_target.netname);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_FREEZE, frag_target.netname, frag_attacker.netname);
}
frag_target.health = 1; // "respawn" the player :P
- freezetag_CheckWinner();
-
return 1;
}
MUTATOR_HOOKFUNCTION(freezetag_PlayerSpawn)
{
- freezetag_Unfreeze(world); // start by making sure that all ice blocks are removed
+ if(self.freezetag_frozen_timeout == -1) // if PlayerSpawn is called by reset_map_players
+ return 1; // do nothing, round is starting right now
- if(total_players == 1 && time > game_starttime) // only one player active on server, start a new match immediately
- if(!next_round && warmup && (time < warmup - autocvar_g_freezetag_warmup || time > warmup)) // not awaiting next round
+ if(self.freezetag_frozen_timeout == -2) // player was dead
{
- next_round = time;
+ freezetag_Freeze(world);
return 1;
}
- if(warmup && time > warmup) // spawn too late, freeze player
+
+ freezetag_count_alive_players();
+
+ if(round_handler_IsActive())
+ if(round_handler_IsRoundStarted())
{
- centerprint(self, "^1You spawned after the round started, you'll spawn as frozen.\n");
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_SPAWN_LATE);
freezetag_Freeze(world);
}
return 1;
}
+ MUTATOR_HOOKFUNCTION(freezetag_reset_map_players)
+ {
+ FOR_EACH_PLAYER(self)
+ {
+ if (self.freezetag_frozen)
+ freezetag_Unfreeze(world);
+ self.freezetag_frozen_timeout = -1;
+ PutClientInServer();
+ self.freezetag_frozen_timeout = 0;
+ }
+ freezetag_count_alive_players();
+ return 1;
+ }
+
MUTATOR_HOOKFUNCTION(freezetag_GiveFragsForKill)
{
frag_score = 0; // no frags counted in Freeze Tag
return 1;
}
+ .float reviving; // temp var
MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
{
float n;
- vector revive_extra_size;
- revive_extra_size = '1 1 1' * autocvar_g_freezetag_revive_extra_size;
+ if(gameover)
+ return 1;
+
+ if(self.freezetag_frozen)
+ {
+ // keep health = 1
+ self.pauseregen_finished = time + autocvar_g_balance_pause_health_regen;
+ }
+
+ if(round_handler_IsActive())
+ if(!round_handler_IsRoundStarted())
+ return 1;
entity o;
o = world;
- n = 0;
- FOR_EACH_PLAYER(other) if(self != other)
+ if(self.freezetag_frozen_timeout > 0 && time < self.freezetag_frozen_timeout)
+ self.freezetag_ice.alpha = ICE_MIN_ALPHA + (ICE_MAX_ALPHA - ICE_MIN_ALPHA) * (self.freezetag_frozen_timeout - time) / (self.freezetag_frozen_timeout - self.freezetag_frozen_time);
+
+ if(self.freezetag_frozen_timeout > 0 && time >= self.freezetag_frozen_timeout)
+ n = -1;
+ else
{
- if(other.freezetag_frozen == 0)
+ vector revive_extra_size = '1 1 1' * autocvar_g_freezetag_revive_extra_size;
+ n = 0;
+ FOR_EACH_PLAYER(other) if(self != other)
{
- if(other.team == self.team)
+ if(other.freezetag_frozen == 0)
{
- if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
+ if(other.team == self.team)
{
- if(!o)
- o = other;
- ++n;
+ if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
+ {
+ if(!o)
+ o = other;
+ if(self.freezetag_frozen)
+ other.reviving = TRUE;
+ ++n;
+ }
}
}
}
if(n && self.freezetag_frozen) // OK, there is at least one teammate reviving us
{
- self.freezetag_revive_progress = bound(0, self.freezetag_revive_progress + frametime * autocvar_g_freezetag_revive_speed, 1);
+ self.freezetag_revive_progress = bound(0, self.freezetag_revive_progress + frametime * max(1/60, autocvar_g_freezetag_revive_speed), 1);
self.health = max(1, self.freezetag_revive_progress * autocvar_g_balance_health_start);
if(self.freezetag_revive_progress >= 1)
{
freezetag_Unfreeze(self);
+ freezetag_count_alive_players();
+
+ if(n == -1)
+ {
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_AUTO_REVIVED, autocvar_g_freezetag_frozen_maxtime);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_AUTO_REVIVED, self.netname, autocvar_g_freezetag_frozen_maxtime);
+ return 1;
+ }
// EVERY team mate nearby gets a point (even if multiple!)
- FOR_EACH_PLAYER(other) if(self != other)
+ FOR_EACH_PLAYER(other)
{
- if(other.freezetag_frozen == 0)
+ if(other.reviving)
{
- if(other.team == self.team)
- {
- if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
- {
- PlayerScore_Add(other, SP_FREEZETAG_REVIVALS, +1);
- PlayerScore_Add(other, SP_SCORE, +1);
- }
- }
+ PlayerScore_Add(other, SP_FREEZETAG_REVIVALS, +1);
+ PlayerScore_Add(other, SP_SCORE, +1);
}
}
- if(n > 1)
- centerprint(self, strcat("^5You were revived by ^7", o.netname, "^5 et al.\n"));
- else
- centerprint(self, strcat("^5You were revived by ^7", o.netname, "^5.\n"));
- centerprint(o, strcat("^5You revived ^7", self.netname, "^5.\n"));
- if(n > 1)
- bprint("^7", o.netname, "^5 et al revived ^7", self.netname, "^5.\n");
- else
- bprint("^7", o.netname, "^5 revived ^7", self.netname, "^5.\n");
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_REVIVED, o.netname);
+ Send_Notification(NOTIF_ONE, o, MSG_CENTER, CENTER_FREEZETAG_REVIVE, self.netname);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVED, self.netname, o.netname);
}
- // now find EVERY teammate within reviving radius, set their revive_progress values correct
- FOR_EACH_PLAYER(other) if(self != other)
+ FOR_EACH_PLAYER(other)
{
- if(other.freezetag_frozen == 0)
+ if(other.reviving)
{
- if(other.team == self.team)
- {
- if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
- other.freezetag_revive_progress = self.freezetag_revive_progress;
- }
+ other.freezetag_revive_progress = self.freezetag_revive_progress;
+ other.reviving = FALSE;
}
}
}
MUTATOR_HOOKFUNCTION(freezetag_PlayerDamage_Calculate)
{
- if(g_freezetag)
- {
- if(frag_target.freezetag_frozen == 1 && frag_deathtype != DEATH_HURTTRIGGER)
- {
- frag_damage = 0;
- frag_force = frag_force * autocvar_g_freezetag_frozen_force;
- }
- }
- return 1;
+ if(frag_target.freezetag_frozen && frag_deathtype != DEATH_HURTTRIGGER)
+ {
+ frag_damage = 0;
+ frag_force = frag_force * autocvar_g_freezetag_frozen_force;
+ }
+ return 1;
}
MUTATOR_HOOKFUNCTION(freezetag_ForbidThrowCurrentWeapon)
return 0;
}
+ MUTATOR_HOOKFUNCTION(freezetag_ItemTouch)
+ {
+ if (other.freezetag_frozen)
+ return 1;
+ return 0;
+ }
+
MUTATOR_HOOKFUNCTION(freezetag_BotRoles)
{
if not(self.deadflag)
else
self.havocbot_role = havocbot_role_ft_offense;
}
-
+
return TRUE;
}
+ MUTATOR_HOOKFUNCTION(freezetag_SpectateCopy)
+ {
+ self.freezetag_frozen = other.freezetag_frozen;
+ self.freezetag_revive_progress = other.freezetag_revive_progress;
+ return 0;
+ }
+
+ MUTATOR_HOOKFUNCTION(freezetag_GetTeamCount)
+ {
+ freezetag_teams = autocvar_g_freezetag_teams_override;
+ if(freezetag_teams < 2)
+ freezetag_teams = autocvar_g_freezetag_teams;
+ freezetag_teams = bound(2, freezetag_teams, 4);
+ ret_float = freezetag_teams;
+ return 0;
+ }
+
+ void freezetag_Initialize()
+ {
+ precache_model("models/ice/ice.md3");
+ ScoreRules_freezetag();
+
+ round_handler_Spawn(freezetag_CheckTeams, freezetag_CheckWinner, func_null);
+ round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
+
+ addstat(STAT_REDALIVE, AS_INT, redalive_stat);
+ addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
+ addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
+ addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
+
+ addstat(STAT_FROZEN, AS_INT, freezetag_frozen);
+ addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, freezetag_revive_progress);
+ }
+
MUTATOR_DEFINITION(gamemode_freezetag)
{
MUTATOR_HOOK(MakePlayerObserver, freezetag_RemovePlayer, CBC_ORDER_ANY);
MUTATOR_HOOK(ClientDisconnect, freezetag_RemovePlayer, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerDies, freezetag_PlayerDies, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerSpawn, freezetag_PlayerSpawn, CBC_ORDER_ANY);
+ MUTATOR_HOOK(reset_map_players, freezetag_reset_map_players, CBC_ORDER_ANY);
MUTATOR_HOOK(GiveFragsForKill, freezetag_GiveFragsForKill, CBC_ORDER_FIRST);
MUTATOR_HOOK(PlayerPreThink, freezetag_PlayerPreThink, CBC_ORDER_FIRST);
MUTATOR_HOOK(PlayerPhysics, freezetag_PlayerPhysics, CBC_ORDER_FIRST);
MUTATOR_HOOK(PlayerDamage_Calculate, freezetag_PlayerDamage_Calculate, CBC_ORDER_ANY);
- MUTATOR_HOOK(ForbidThrowCurrentWeapon, freezetag_ForbidThrowCurrentWeapon, CBC_ORDER_FIRST); //first, last or any? dunno.
+ MUTATOR_HOOK(ForbidThrowCurrentWeapon, freezetag_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
+ MUTATOR_HOOK(ItemTouch, freezetag_ItemTouch, CBC_ORDER_ANY);
MUTATOR_HOOK(HavocBot_ChooseRule, freezetag_BotRoles, CBC_ORDER_ANY);
+ MUTATOR_HOOK(SpectateCopy, freezetag_SpectateCopy, CBC_ORDER_ANY);
+ MUTATOR_HOOK(GetTeamCount, freezetag_GetTeamCount, CBC_ORDER_EXCLUSIVE);
MUTATOR_ONADD
{
float ka_ballcarrier_waypointsprite_visible_for_player(entity e) // runs on waypoints which are attached to ballcarriers, updates once per frame
{
if(e.ballcarried)
- if(other.classname == "spectator")
+ if(IS_SPEC(other))
return FALSE; // we don't want spectators of the ballcarrier to see the attached waypoint on the top of their screen
// TODO: Make the ballcarrier lack a waypointsprite whenever they have the invisibility powerup
return;
}
if(other.deadflag != DEAD_NO) { return; }
- if(other.classname != "player")
+ if not(IS_PLAYER(other))
{ // The ball just touched an object, most likely the world
pointparticles(particleeffectnum("kaball_sparks"), self.origin, '0 0 0', 1);
sound(self, CH_TRIGGER, "keepaway/touch.wav", VOL_BASE, ATTN_NORM);
// messages and sounds
ka_EventLog("pickup", other);
- Send_KillNotification(other.netname, "", "", KA_PICKUPBALL, MSG_KA);
- WriteByte(MSG_BROADCAST, SVC_CENTERPRINT);
- WriteString(MSG_BROADCAST, strcat(other.netname, "^7 has picked up the ball!"));
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_KEEPAWAY_PICKUP, other.netname);
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEEPAWAY_PICKUP, other.netname);
sound(self.owner, CH_TRIGGER, "keepaway/pickedup.wav", VOL_BASE, ATTN_NONE); // ATTN_NONE (it's a sound intended to be heard anywhere)
// scoring
// messages and sounds
ka_EventLog("dropped", plyr);
- Send_KillNotification(plyr.netname, "", "", KA_DROPBALL, MSG_KA);
- WriteByte(MSG_BROADCAST, SVC_CENTERPRINT);
- WriteString(MSG_BROADCAST, strcat(plyr.netname, "^7 has dropped the ball!"));
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_KEEPAWAY_DROPPED, plyr.netname);
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEEPAWAY_DROPPED, plyr.netname);
sound(other, CH_TRIGGER, "keepaway/dropped.wav", VOL_BASE, ATTN_NONE); // ATTN_NONE (it's a sound intended to be heard anywhere)
// scoring
void ka_Reset() // used to clear the ballcarrier whenever the match switches from warmup to normal
{
- if((self.owner) && (self.owner.classname == "player"))
+ if((self.owner) && (IS_PLAYER(self.owner)))
ka_DropEvent(self.owner);
ka_RespawnBall();
MUTATOR_HOOKFUNCTION(ka_Scoring)
{
- if((frag_attacker != frag_target) && (frag_attacker.classname == "player"))
+ if((frag_attacker != frag_target) && (IS_PLAYER(frag_attacker)))
{
if(frag_target.ballcarried) { // add to amount of times killing carrier
PlayerScore_Add(frag_attacker, SP_KEEPAWAY_CARRIERKILLS, 1);
}
else if(!frag_attacker.ballcarried)
if(autocvar_g_keepaway_noncarrier_warn)
- centerprint(frag_attacker, "Killing people while you don't have the ball gives no points!");
+ Send_Notification(NOTIF_ONE_ONLY, frag_attacker, MSG_CENTER, CENTER_KEEPAWAY_WARN);
if(frag_attacker.ballcarried) // add to amount of kills while ballcarrier
PlayerScore_Add(frag_attacker, SP_SCORE, autocvar_g_keepaway_score_killac);
vector KH_KEY_MAX = '10 10 3';
float KH_KEY_BRIGHTNESS = 2;
- string kh_Controller_Waitmsg;
float kh_no_radar_circles;
// kh_state
float kh_Team_ByID(float t)
{
- if(t == 0) return COLOR_TEAM1;
- if(t == 1) return COLOR_TEAM2;
- if(t == 2) return COLOR_TEAM3;
- if(t == 3) return COLOR_TEAM4;
+ if(t == 0) return NUM_TEAM_1;
+ if(t == 1) return NUM_TEAM_2;
+ if(t == 2) return NUM_TEAM_3;
+ if(t == 3) return NUM_TEAM_4;
return 0;
}
float kh_KeyCarrier_waypointsprite_visible_for_player(entity e) // runs all the time
{
- if(e.classname != "player" || self.team != e.team)
+ if(!IS_PLAYER(e) || self.team != e.team)
if(!kh_tracking_enabled)
return FALSE;
var kh_Think_t kh_Controller_Thinkfunc;
- void kh_Controller_SetThink(float t, string msg, float centerprint_duration, kh_Think_t func) // runs occasionaly
+ void kh_Controller_SetThink(float t, kh_Think_t func) // runs occasionaly
{
kh_Controller_Thinkfunc = func;
kh_controller.cnt = ceil(t);
- if(kh_Controller_Waitmsg != "")
- strunzone(kh_Controller_Waitmsg);
- if(msg == "")
- kh_Controller_Waitmsg = "";
- else
- {
- kh_controller.kh_cp_duration = centerprint_duration;
- kh_Controller_Waitmsg = strzone(msg);
- }
if(t == 0)
kh_controller.nextthink = time; // force
}
- void kh_Controller_SetThink_NoMsg(float t, kh_Think_t func) // runs occasionaly
- {
- kh_Controller_SetThink(t, "", 0, func);
- }
-
+ void kh_WaitForPlayers();
void kh_Controller_Think() // called a lot
{
- entity e;
if(intermission_running)
return;
if(self.cnt > 0)
- {
- if(kh_Controller_Waitmsg != "")
- {
- string s;
- if(substring(kh_Controller_Waitmsg, strlen(kh_Controller_Waitmsg)-1, 1) == " ")
- s = strcat(kh_Controller_Waitmsg, ftos(self.cnt));
- else
- s = kh_Controller_Waitmsg;
-
- //dprint(s, "\n");
-
- FOR_EACH_PLAYER(e)
- if(IS_REAL_CLIENT(e))
- Send_CSQC_Centerprint_Generic(e, CPID_KH_MSG, s, self.kh_cp_duration, 0);
- }
- self.cnt -= 1;
- }
+ { if(self.think != kh_WaitForPlayers) { self.cnt -= 1; } }
else if(self.cnt == 0)
{
self.cnt -= 1;
WaypointSprite_AttachCarrier("", player, RADARICON_FLAGCARRIER, colormapPaletteColor(player.team - 1, 0));
player.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = kh_KeyCarrier_waypointsprite_visible_for_player;
WaypointSprite_UpdateRule(player.waypointsprite_attachedforcarrier, player.team, SPRITERULE_TEAMPLAY);
- if(player.team == COLOR_TEAM1)
+ if(player.team == NUM_TEAM_1)
WaypointSprite_UpdateSprites(player.waypointsprite_attachedforcarrier, "keycarrier-red", "keycarrier-friend", "keycarrier-red");
- else if(player.team == COLOR_TEAM2)
+ else if(player.team == NUM_TEAM_2)
WaypointSprite_UpdateSprites(player.waypointsprite_attachedforcarrier, "keycarrier-blue", "keycarrier-friend", "keycarrier-blue");
- else if(player.team == COLOR_TEAM3)
+ else if(player.team == NUM_TEAM_3)
WaypointSprite_UpdateSprites(player.waypointsprite_attachedforcarrier, "keycarrier-yellow", "keycarrier-friend", "keycarrier-yellow");
- else if(player.team == COLOR_TEAM4)
+ else if(player.team == NUM_TEAM_4)
WaypointSprite_UpdateSprites(player.waypointsprite_attachedforcarrier, "keycarrier-pink", "keycarrier-friend", "keycarrier-pink");
if(!kh_no_radar_circles)
WaypointSprite_Ping(player.waypointsprite_attachedforcarrier);
if(vlen(force) <= 0)
return;
if(time > self.pushltime)
- if(attacker.classname == "player")
+ if(IS_PLAYER(attacker))
self.team = attacker.team;
}
PlayerScore_Add(player, SP_KH_PICKUPS, 1);
}
key.kh_dropperteam = 0;
- bprint(player.netname, "^7 picked up the ", key.netname, "\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(key, INFO_KEYHUNT_PICKUP_), player.netname);
kh_Key_AssignTo(key, player); // this also updates .kh_state
}
// maybe start a shorter countdown?
}
- if(other.classname != "player")
+ if not(IS_PLAYER(other))
return;
if(other.deadflag != DEAD_NO)
return;
kh_Key_Remove(key);
kh_no_radar_circles = FALSE;
- kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, "Round starts in ", 1, kh_StartRound);
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_ROUNDSTART, autocvar_g_balance_keyhunt_delay_round);
+ kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, kh_StartRound);
}
- void kh_WinnerTeam(float teem) // runs when a team wins
+ void kh_WinnerTeam(float teem) // runs when a team wins // Samual: Teem?.... TEEM?!?! what the fuck is wrong with you people
{
// all key carriers get some points
vector firstorigin, lastorigin, midpoint;
}
first = TRUE;
+ string keyowner = "";
FOR_EACH_KH_KEY(key)
if(key.owner.kh_next == key)
{
if(!first)
- bprint("^7, ");
- bprint(key.owner.netname);
+ keyowner = strcat(keyowner, ", ");
+ keyowner = key.owner.netname;
first = FALSE;
}
- bprint("^7 captured the keys for the ", ColoredTeamName(teem), "\n");
+
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(teem, INFO_KEYHUNT_CAPTURE_), keyowner);
first = TRUE;
midpoint = '0 0 0';
te_lightning2(world, lastorigin, firstorigin);
}
midpoint = midpoint * (1 / kh_teams);
- te_customflash(midpoint, 1000, 1, TeamColor(teem) * 0.5 + '0.5 0.5 0.5'); // make the color >=0.5 in each component
+ te_customflash(midpoint, 1000, 1, Team_ColorRGB(teem) * 0.5 + '0.5 0.5 0.5'); // make the color >=0.5 in each component
play2all(kh_sound_capture);
kh_FinishRound();
attacker = world;
if(lostkey.pusher)
if(lostkey.pusher.team != teem)
- if(lostkey.pusher.classname == "player")
+ if(IS_PLAYER(lostkey.pusher))
attacker = lostkey.pusher;
players = keys = 0;
// don't actually GIVE him the -nn points, just log
kh_Scores_Event(attacker, world, "push", autocvar_g_balance_keyhunt_score_push, 0);
PlayerScore_Add(attacker, SP_KH_PUSHES, 1);
- centerprint(attacker, "Your push is the best!");
- bprint("The ", ColoredTeamName(teem), "^7 could not take care of the ", lostkey.netname, "^7 when ", attacker.netname, "^7 came\n");
+ //centerprint(attacker, "Your push is the best!"); // does this really need to exist?
}
else
{
--j;
}
-
- bprint("The ", ColoredTeamName(teem), "^7 could not take care of the ", lostkey.netname, "\n");
}
+
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(lostkey, INFO_KEYHUNT_LOST_), lostkey.kh_previous_owner.netname);
+
play2all(kh_sound_destroy);
te_tarexplosion(lostkey.origin);
{
if(head.team == kh_interferemsg_team)
if(head.kh_next)
- Send_CSQC_Centerprint_Generic(head, CPID_KH_MSG, "All keys are in your team's hands!\n\nMeet the other key carriers ^1NOW^7!", 0, 0);
+ Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_KEYHUNT_MEET);
else
- Send_CSQC_Centerprint_Generic(head, CPID_KH_MSG, "All keys are in your team's hands!\n\nHelp the key carriers to meet!", 0, 0);
+ Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_KEYHUNT_HELP);
else
- Send_CSQC_Centerprint_Generic(head, CPID_KH_MSG, strcat("All keys are in the ", ColoredTeamName(kh_interferemsg_team), "^7's hands!\n\nInterfere ^1NOW^7!"), 0, 0);
+ Send_Notification(NOTIF_ONE, head, MSG_CENTER, APP_TEAM_NUM_4(kh_interferemsg_team, CENTER_KEYHUNT_INTERFERE_));
}
}
key.kh_dropperteam = 0;
key.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
setsize(key, KH_KEY_MIN, KH_KEY_MAX);
- key.colormod = TeamColor(initial_owner.team) * KH_KEY_BRIGHTNESS;
+ key.colormod = Team_ColorRGB(initial_owner.team) * KH_KEY_BRIGHTNESS;
key.reset = key_reset;
switch(initial_owner.team)
{
- case COLOR_TEAM1:
+ case NUM_TEAM_1:
key.netname = "^1red key";
break;
- case COLOR_TEAM2:
+ case NUM_TEAM_2:
key.netname = "^4blue key";
break;
- case COLOR_TEAM3:
+ case NUM_TEAM_3:
key.netname = "^3yellow key";
break;
- case COLOR_TEAM4:
+ case NUM_TEAM_4:
key.netname = "^6pink key";
break;
default:
key.kh_worldkeynext = kh_worldkeylist;
kh_worldkeylist = key;
- centerprint(initial_owner, strcat("You are starting with the ", key.netname, "\n")); // message to player at start of round
+ Send_Notification(NOTIF_ONE, initial_owner, MSG_CENTER, APP_TEAM_NUM_4(initial_owner.team, CENTER_KEYHUNT_START_));
WaypointSprite_Spawn("key-dropped", 0, 0, key, '0 0 1' * KH_KEY_WP_ZSHIFT, world, key.team, key, waypointsprite_attachedforcarrier, FALSE, RADARICON_FLAG, '0 1 1');
key.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = kh_Key_waypointsprite_visible_for_player;
kh_Scores_Event(player, key, "dropkey", 0, 0);
PlayerScore_Add(player, SP_KH_LOSSES, 1);
- bprint(player.netname, "^7 dropped the ", key.netname, "\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(key, INFO_KEYHUNT_DROP_), player.netname);
+
kh_Key_AssignTo(key, world);
makevectors(player.v_angle);
key.velocity = W_CalculateProjectileVelocity(player.velocity, autocvar_g_balance_keyhunt_throwvelocity * v_forward, FALSE);
{
kh_Scores_Event(player, key, "losekey", 0, 0);
PlayerScore_Add(player, SP_KH_LOSSES, 1);
- bprint(player.netname, "^7 died and lost the ", key.netname, "\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(key, INFO_KEYHUNT_LOST_), player.netname);
kh_Key_AssignTo(key, world);
makevectors('-1 0 0' * (45 + 45 * random()) + '0 360 0' * random());
key.velocity = W_CalculateProjectileVelocity(player.velocity, autocvar_g_balance_keyhunt_dropvelocity * v_forward, FALSE);
}
}
- string kh_CheckEnoughPlayers() // checks enough player are present, runs after every completed round
+ float kh_CheckPlayers(float num)
{
- float i, players, teem;
- entity player;
- string result;
- result = "";
-
- // find a random player per team
- for(i = 0; i < kh_teams; ++i)
- {
- teem = kh_Team_ByID(i);
- players = 0;
- FOR_EACH_PLAYER(player)
- if(player.deadflag == DEAD_NO)
- if(!player.BUTTON_CHAT)
- if(player.team == teem)
+ if(num < kh_teams)
+ {
+ float t_team = kh_Team_ByID(num);
+ float players = 0;
+ entity tmp_player;
+ FOR_EACH_PLAYER(tmp_player)
+ if(tmp_player.deadflag == DEAD_NO)
+ if(!tmp_player.BUTTON_CHAT)
+ if(tmp_player.team == t_team)
++players;
- if(players == 0)
- {
- if(result != "")
- result = strcat(result, ", ");
- result = strcat(result, ColoredTeamName(teem));
- }
+
+ if not(players) { return t_team; }
}
- return result;
+ return 0;
}
void kh_WaitForPlayers() // delay start of the round until enough players are present
{
- string teams_missing;
-
if(time < game_starttime)
{
- kh_Controller_SetThink_NoMsg(game_starttime - time + 0.1, kh_WaitForPlayers);
+ kh_Controller_SetThink(game_starttime - time + 0.1, kh_WaitForPlayers);
return;
}
- teams_missing = kh_CheckEnoughPlayers();
- if(teams_missing == "")
- kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, "Round starts in ", 1, kh_StartRound);
+ float p1 = kh_CheckPlayers(0), p2 = kh_CheckPlayers(1), p3 = kh_CheckPlayers(2), p4 = kh_CheckPlayers(3);
+ if not(p1 || p2 || p3 || p4)
+ {
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_ROUNDSTART, autocvar_g_balance_keyhunt_delay_round);
+ kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, kh_StartRound);
+ }
else
- kh_Controller_SetThink(1, strcat("Waiting for players to join...\n\nNeed active players for: ", teams_missing), -1, kh_WaitForPlayers);
+ {
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_WAIT, p1, p2, p3, p4);
+ kh_Controller_SetThink(1, kh_WaitForPlayers);
+ }
}
void kh_EnableTrackingDevice() // runs after each round
{
- entity player;
-
- FOR_EACH_PLAYER(player)
- if(IS_REAL_CLIENT(player))
- Send_CSQC_Centerprint_Generic_Expire(player, CPID_KH_MSG);
+ Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT);
+ Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT_OTHER);
kh_tracking_enabled = TRUE;
}
void kh_StartRound() // runs at the start of each round
{
- string teams_missing;
float i, players, teem;
entity player;
if(time < game_starttime)
{
- kh_Controller_SetThink_NoMsg(game_starttime - time + 0.1, kh_WaitForPlayers);
+ kh_Controller_SetThink(game_starttime - time + 0.1, kh_WaitForPlayers);
return;
}
- teams_missing = kh_CheckEnoughPlayers();
- if(teams_missing != "")
+ float p1 = kh_CheckPlayers(0), p2 = kh_CheckPlayers(1), p3 = kh_CheckPlayers(2), p4 = kh_CheckPlayers(3);
+ if(p1 || p2 || p3 || p4)
{
- kh_Controller_SetThink(1, strcat("Waiting for players to join...\n\nNeed active players for: ", teams_missing), -1, kh_WaitForPlayers);
+ kh_Controller_SetThink(1, kh_WaitForPlayers);
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_WAIT, p1, p2, p3, p4);
return;
}
-
- FOR_EACH_PLAYER(player)
- if(IS_REAL_CLIENT(player))
- Send_CSQC_Centerprint_Generic_Expire(player, CPID_KH_MSG);
+
+ Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT);
+ Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT_OTHER);
for(i = 0; i < kh_teams; ++i)
{
}
kh_tracking_enabled = FALSE;
- kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_tracking, "Scanning frequency range...", -1, kh_EnableTrackingDevice);
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_SCAN, autocvar_g_balance_keyhunt_delay_tracking);
+ kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_tracking, kh_EnableTrackingDevice);
}
float kh_HandleFrags(entity attacker, entity targ, float f) // adds to the player score
// make a KH entity for controlling the game
kh_controller = spawn();
kh_controller.think = kh_Controller_Think;
- kh_Controller_SetThink_NoMsg(0, kh_WaitForPlayers);
+ kh_Controller_SetThink(0, kh_WaitForPlayers);
setmodel(kh_controller, "models/keyhunt/key.md3");
kh_key_dropped = kh_controller.modelindex;
{
if(self == other)
kh_Key_DropAll(self, TRUE);
- else if(other.classname == "player")
+ else if(IS_PLAYER(other))
kh_Key_DropAll(self, FALSE);
else
kh_Key_DropAll(self, TRUE);
{
if(self.ballcarried.teamtime && (self.ballcarried.teamtime < time))
{
- bprint("The ", ColoredTeamName(self.team), " held the ball for too long.\n");
+ bprint("The ", Team_ColoredFullName(self.team), " held the ball for too long.\n");
oldself = self;
self = self.ballcarried;
DropBall(self, self.owner.origin, '0 0 0');
if(self.cnt < 2) // step 1
{
if(time == self.teamtime)
- bprint("The ", ColoredTeamName(self.team), " held the ball for too long.\n");
+ bprint("The ", Team_ColoredFullName(self.team), " held the ball for too long.\n");
+
self.touch = func_null;
self.movetype = MOVETYPE_NOCLIP;
self.velocity = '0 0 0'; // just in case?
self.nextthink = time + autocvar_g_nexball_delay_idle;
return;
}
- if(other.classname != "player")
+ if not(IS_PLAYER(other))
return;
if(other.health < 1)
return;
football_touch();
return;
}
- if(!self.cnt && other.classname == "player" && (other != self.nb_dropper || time > self.nb_droptime + autocvar_g_nexball_delay_collect))
+ if(!self.cnt && IS_PLAYER(other) && (other != self.nb_dropper || time > self.nb_droptime + autocvar_g_nexball_delay_collect))
{
if(other.health <= 0)
return;
else
otherteam = 0;
- if((isclient = ball.pusher.flags & FL_CLIENT))
+ if((isclient = IS_CLIENT(ball.pusher)))
pname = ball.pusher.netname;
else
pname = "Someone (?)";
{
LogNB("fault", ball.pusher);
if(nb_teams == 2)
- bprint(ColoredTeamName(otherteam), " gets a point due to ", pname, "^7's silliness.\n");
+ bprint(Team_ColoredFullName(otherteam), " gets a point due to ", pname, "^7's silliness.\n");
else
- bprint(ColoredTeamName(ball.team), " loses a point due to ", pname, "^7's silliness.\n");
+ bprint(Team_ColoredFullName(ball.team), " loses a point due to ", pname, "^7's silliness.\n");
pscore = -1;
}
else if(self.team == GOAL_OUT)
else //score
{
LogNB(strcat("goal:", ftos(self.team)), ball.pusher);
- bprint("Goaaaaal! ", pname, "^7 scored a point for the ", ColoredTeamName(ball.team), ".\n");
+ bprint("Goaaaaal! ", pname, "^7 scored a point for the ", Team_ColoredFullName(ball.team), ".\n");
pscore = 1;
}
{
switch(e.team)
{
- case COLOR_TEAM1:
+ case NUM_TEAM_1:
if(!t_r)
{
nb_spawnteam("Red", e.team-1) ;
t_r = 1;
}
break;
- case COLOR_TEAM2:
+ case NUM_TEAM_2:
if(!t_b)
{
nb_spawnteam("Blue", e.team-1) ;
t_b = 1;
}
break;
- case COLOR_TEAM3:
+ case NUM_TEAM_3:
if(!t_y)
{
nb_spawnteam("Yellow", e.team-1);
t_y = 1;
}
break;
- case COLOR_TEAM4:
+ case NUM_TEAM_4:
if(!t_p)
{
nb_spawnteam("Pink", e.team-1) ;
void spawnfunc_nexball_redgoal(void)
{
- self.team = COLOR_TEAM1;
+ self.team = NUM_TEAM_1;
SpawnGoal();
}
void spawnfunc_nexball_bluegoal(void)
{
- self.team = COLOR_TEAM2;
+ self.team = NUM_TEAM_2;
SpawnGoal();
}
void spawnfunc_nexball_yellowgoal(void)
{
- self.team = COLOR_TEAM3;
+ self.team = NUM_TEAM_3;
SpawnGoal();
}
void spawnfunc_nexball_pinkgoal(void)
{
- self.team = COLOR_TEAM4;
+ self.team = NUM_TEAM_4;
SpawnGoal();
}
PROJECTILE_TOUCH;
if(attacker.team != other.team || autocvar_g_nexball_basketball_teamsteal)
- if((ball = other.ballcarried) && (attacker.classname == "player"))
+ if((ball = other.ballcarried) && (IS_PLAYER(attacker)))
{
other.velocity = other.velocity + normalize(self.velocity) * other.damageforcescale * autocvar_g_balance_nexball_secondary_force;
other.flags &~= FL_ONGROUND;
precache_sound("misc/typehit.wav");
}
else if(req == WR_SETUP)
- weapon_setup(WEP_PORTO);
- else if(req == WR_SUICIDEMESSAGE)
{
- w_deathtypestring = "is a weirdo";
- }
- else if(req == WR_KILLMESSAGE)
- {
- w_deathtypestring = "got killed by #'s black magic";
+ weapon_setup(WEP_PORTO);
}
// No need to check WR_CHECKAMMO* or WR_AIM, it should always return TRUE
return TRUE;
//tracebox(self.origin + self.view_ofs, '-2 -2 -2', '2 2 2', self.origin + self.view_ofs + v_forward * autocvar_g_nexball_safepass_maxdist);
crosshair_trace(self);
if( trace_ent &&
- trace_ent.flags & FL_CLIENT &&
+ IS_CLIENT(trace_ent) &&
trace_ent.deadflag == DEAD_NO &&
trace_ent.team == self.team &&
vlen(trace_ent.origin - self.origin) <= autocvar_g_nexball_safepass_maxdist )
float autocvar_g_onslaught_spawn_at_controlpoints;
float autocvar_g_onslaught_spawn_at_generator;
- float autocvar_g_onslaught_controlpoints_proxycap;
- float autocvar_g_onslaught_controlpoints_proxycap_distance = 512;
- float autocvar_g_onslaught_controlpoints_proxycap_dps = 100;
+ float autocvar_g_onslaught_cp_proxydecap;
+ var float autocvar_g_onslaught_cp_proxydecap_distance = 512;
+ var float autocvar_g_onslaught_cp_proxydecap_dps = 100;
void onslaught_generator_updatesprite(entity e);
void onslaught_controlpoint_updatesprite(entity e);
.float lastshielded;
.float lastcaptured;
- .string model1, model2, model3;
-
entity ons_red_generator;
entity ons_blue_generator;
}
if(l.goalentity.classname == "onslaught_generator")
{
- if(l.goalentity.team == COLOR_TEAM1)
+ if(l.goalentity.team == NUM_TEAM_1)
l.enemy.isgenneighbor_red = TRUE;
- else if(l.goalentity.team == COLOR_TEAM2)
+ else if(l.goalentity.team == NUM_TEAM_2)
l.enemy.isgenneighbor_blue = TRUE;
}
else
{
- if(l.goalentity.team == COLOR_TEAM1)
+ if(l.goalentity.team == NUM_TEAM_1)
l.enemy.iscpneighbor_red = TRUE;
- else if(l.goalentity.team == COLOR_TEAM2)
+ else if(l.goalentity.team == NUM_TEAM_2)
l.enemy.iscpneighbor_blue = TRUE;
}
}
}
if(l.enemy.classname == "onslaught_generator")
{
- if(l.enemy.team == COLOR_TEAM1)
+ if(l.enemy.team == NUM_TEAM_1)
l.goalentity.isgenneighbor_red = TRUE;
- else if(l.enemy.team == COLOR_TEAM2)
+ else if(l.enemy.team == NUM_TEAM_2)
l.goalentity.isgenneighbor_blue = TRUE;
}
else
{
- if(l.enemy.team == COLOR_TEAM1)
+ if(l.enemy.team == NUM_TEAM_1)
l.goalentity.iscpneighbor_red = TRUE;
- else if(l.enemy.team == COLOR_TEAM2)
+ else if(l.enemy.team == NUM_TEAM_2)
l.goalentity.iscpneighbor_blue = TRUE;
}
}
{
if (l.iscaptured)
{
- if (l.team == COLOR_TEAM1) t1 = 1;
- if (l.team == COLOR_TEAM2) t2 = 1;
- if (l.team == COLOR_TEAM3) t3 = 1;
- if (l.team == COLOR_TEAM4) t4 = 1;
+ if (l.team == NUM_TEAM_1) t1 = 1;
+ if (l.team == NUM_TEAM_2) t2 = 1;
+ if (l.team == NUM_TEAM_3) t3 = 1;
+ if (l.team == NUM_TEAM_4) t4 = 1;
}
onslaught_generator_updatesprite(l);
l = l.chain;
float onslaught_controlpoint_can_be_linked(entity cp, float t)
{
- if(t == COLOR_TEAM1)
+ if(t == NUM_TEAM_1)
{
if(cp.isgenneighbor_red)
return 2;
if(cp.iscpneighbor_red)
return 1;
}
- else if(t == COLOR_TEAM2)
+ else if(t == NUM_TEAM_2)
{
if(cp.isgenneighbor_blue)
return 2;
// if there's already an icon built, nothing happens
if(cp.team == t)
{
- a = onslaught_controlpoint_can_be_linked(cp, COLOR_TEAM1 + COLOR_TEAM2 - t);
+ a = onslaught_controlpoint_can_be_linked(cp, NUM_TEAM_1 + NUM_TEAM_2 - t);
if(a) // attackable by enemy?
return -2; // EMERGENCY!
return -1;
// free point
if(onslaught_controlpoint_can_be_linked(cp, t))
{
- a = onslaught_controlpoint_can_be_linked(cp, COLOR_TEAM1 + COLOR_TEAM2 - t);
+ a = onslaught_controlpoint_can_be_linked(cp, NUM_TEAM_1 + NUM_TEAM_2 - t);
if(a == 2)
return 4; // GET THIS ONE NOW!
else
}
else if (overtime_msg_time)
overtime_msg_time = 0;
-
+
if(!self.isshielded && self.wait < time)
{
self.wait = time + 5;
- FOR_EACH_PLAYER(e)
+ FOR_EACH_REALPLAYER(e)
{
if(e.team == self.team)
{
centerprint(e, "^1Your generator is NOT shielded!\n^7Re-capture controlpoints to shield it!");
soundto(MSG_ONE, e, CHAN_AUTO, "kh/alarm.wav", VOL_BASE, ATTN_NONE); // FIXME: Uniqe sound?
- }
- }
- }
+ }
+ }
+ }
}
}
{
// this is protected by a shield, so ignore the damage
if (time > self.pain_finished)
- if (attacker.classname == "player")
+ if (IS_PLAYER(attacker))
{
play2(attacker, "onslaught/damageblockedbyshield.wav");
self.pain_finished = time + 1;
if (time > self.pain_finished)
{
self.pain_finished = time + 10;
- bprint(ColoredTeamName(self.team), " generator under attack!\n");
+ bprint(Team_ColoredFullName(self.team), " generator under attack!\n");
play2team(self.team, "onslaught/generator_underattack.wav");
}
}
lh = ceil(self.lasthealth / 100) * 100;
h = ceil(self.health / 100) * 100;
if(lh != h)
- bprint(ColoredTeamName(self.team), " generator has less than ", ftos(h), " health remaining\n");
+ bprint(Team_ColoredFullName(self.team), " generator has less than ", ftos(h), " health remaining\n");
#endif
self.lasthealth = self.health;
}
else if not(inWarmupStage)
{
if (attacker == self)
- bprint(ColoredTeamName(self.team), " generator spontaneously exploded due to overtime!\n");
+ bprint(Team_ColoredFullName(self.team), " generator spontaneously exploded due to overtime!\n");
else
{
string t;
- t = ColoredTeamName(attacker.team);
- bprint(ColoredTeamName(self.team), " generator destroyed by ", t, "!\n");
+ t = Team_ColoredFullName(attacker.team);
+ bprint(Team_ColoredFullName(self.team), " generator destroyed by ", t, "!\n");
}
self.iscaptured = FALSE;
self.islinked = FALSE;
{
if(t == e.team)
{
- if(e.team == COLOR_TEAM1)
+ if(e.team == NUM_TEAM_1)
return "ons-gen-red";
- else if(e.team == COLOR_TEAM2)
+ else if(e.team == NUM_TEAM_2)
return "ons-gen-blue";
}
if(e.isshielded)
return "ons-gen-shielded";
- if(e.team == COLOR_TEAM1)
+ if(e.team == NUM_TEAM_1)
return "ons-gen-red";
- else if(e.team == COLOR_TEAM2)
+ else if(e.team == NUM_TEAM_2)
return "ons-gen-blue";
return "";
}
void onslaught_generator_updatesprite(entity e)
{
string s1, s2, s3;
- s1 = onslaught_generator_waypointsprite_for_team(e, COLOR_TEAM1);
- s2 = onslaught_generator_waypointsprite_for_team(e, COLOR_TEAM2);
+ s1 = onslaught_generator_waypointsprite_for_team(e, NUM_TEAM_1);
+ s2 = onslaught_generator_waypointsprite_for_team(e, NUM_TEAM_2);
s3 = onslaught_generator_waypointsprite_for_team(e, -1);
WaypointSprite_UpdateSprites(e.sprite, s1, s2, s3);
e.lastshielded = e.isshielded;
if(e.lastshielded)
{
- if(e.team == COLOR_TEAM1 || e.team == COLOR_TEAM2)
+ if(e.team == NUM_TEAM_1 || e.team == NUM_TEAM_2)
WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, 0.5 * colormapPaletteColor(e.team - 1, FALSE));
else
WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, '0.5 0.5 0.5');
}
else
{
- if(e.team == COLOR_TEAM1 || e.team == COLOR_TEAM2)
+ if(e.team == NUM_TEAM_1 || e.team == NUM_TEAM_2)
WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, colormapPaletteColor(e.team - 1, FALSE));
else
WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, '0.75 0.75 0.75');
a = onslaught_controlpoint_attackable(e, t);
if(a == 3 || a == 4) // ATTACK/TOUCH THIS ONE NOW
{
- if(e.team == COLOR_TEAM1)
+ if(e.team == NUM_TEAM_1)
return "ons-cp-atck-red";
- else if(e.team == COLOR_TEAM2)
+ else if(e.team == NUM_TEAM_2)
return "ons-cp-atck-blue";
else
return "ons-cp-atck-neut";
}
else if(a == -2) // DEFEND THIS ONE NOW
{
- if(e.team == COLOR_TEAM1)
+ if(e.team == NUM_TEAM_1)
return "ons-cp-dfnd-red";
- else if(e.team == COLOR_TEAM2)
+ else if(e.team == NUM_TEAM_2)
return "ons-cp-dfnd-blue";
}
else if(e.team == t || a == -1 || a == 1) // own point, or fire at it
{
- if(e.team == COLOR_TEAM1)
+ if(e.team == NUM_TEAM_1)
return "ons-cp-red";
- else if(e.team == COLOR_TEAM2)
+ else if(e.team == NUM_TEAM_2)
return "ons-cp-blue";
}
else if(a == 2) // touch it
}
else
{
- if(e.team == COLOR_TEAM1)
+ if(e.team == NUM_TEAM_1)
return "ons-cp-red";
- else if(e.team == COLOR_TEAM2)
+ else if(e.team == NUM_TEAM_2)
return "ons-cp-blue";
else
return "ons-cp-neut";
void onslaught_controlpoint_updatesprite(entity e)
{
string s1, s2, s3;
- s1 = onslaught_controlpoint_waypointsprite_for_team(e, COLOR_TEAM1);
- s2 = onslaught_controlpoint_waypointsprite_for_team(e, COLOR_TEAM2);
+ s1 = onslaught_controlpoint_waypointsprite_for_team(e, NUM_TEAM_1);
+ s2 = onslaught_controlpoint_waypointsprite_for_team(e, NUM_TEAM_2);
s3 = onslaught_controlpoint_waypointsprite_for_team(e, -1);
WaypointSprite_UpdateSprites(e.sprite, s1, s2, s3);
float sh;
- sh = !(onslaught_controlpoint_can_be_linked(e, COLOR_TEAM1) || onslaught_controlpoint_can_be_linked(e, COLOR_TEAM2));
+ sh = !(onslaught_controlpoint_can_be_linked(e, NUM_TEAM_1) || onslaught_controlpoint_can_be_linked(e, NUM_TEAM_2));
if(e.lastteam != e.team + 2 || e.lastshielded != sh || e.iscaptured != e.lastcaptured)
{
}
if(e.lastshielded)
{
- if(e.team == COLOR_TEAM1 || e.team == COLOR_TEAM2)
+ if(e.team == NUM_TEAM_1 || e.team == NUM_TEAM_2)
WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, 0.5 * colormapPaletteColor(e.team - 1, FALSE));
else
WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, '0.5 0.5 0.5');
}
else
{
- if(e.team == COLOR_TEAM1 || e.team == COLOR_TEAM2)
+ if(e.team == NUM_TEAM_1 || e.team == NUM_TEAM_2)
WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, colormapPaletteColor(e.team - 1, FALSE));
else
WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, '0.75 0.75 0.75');
setmodel(self, "models/onslaught/generator.md3");
setsize(self, '-52 -52 -14', '52 52 75');
- if (!self.noalign)
- droptofloor();
+ if(!self.noalign)
+ {
+ setorigin(self, self.origin + '0 0 20');
+ droptofloor();
+ }
WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health);
WaypointSprite_UpdateHealth(self.sprite, self.health);
if (!self.team)
objerror("team must be set");
- if(self.team == COLOR_TEAM1)
+ if(self.team == NUM_TEAM_1)
ons_red_generator = self;
- if(self.team == COLOR_TEAM2)
+ if(self.team == NUM_TEAM_2)
ons_blue_generator = self;
self.team_saved = self.team;
InitializeEntity(self, onslaught_generator_delayed, INITPRIO_LAST);
WaypointSprite_SpawnFixed(string_null, self.origin + '0 0 128', self, sprite, RADARICON_NONE, '0 0 0');
- WaypointSprite_UpdateRule(self.sprite, COLOR_TEAM2, SPRITERULE_TEAMPLAY);
+ WaypointSprite_UpdateRule(self.sprite, NUM_TEAM_2, SPRITERULE_TEAMPLAY);
WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health);
WaypointSprite_UpdateHealth(self.sprite, self.health);
{
// this is protected by a shield, so ignore the damage
if (time > self.pain_finished)
- if (attacker.classname == "player")
+ if (IS_PLAYER(attacker))
{
play2(attacker, "onslaught/damageblockedbyshield.wav");
self.pain_finished = time + 1;
return;
}
- if (attacker.classname == "player")
+ if (IS_PLAYER(attacker))
{
nag = FALSE;
- if(self.team == COLOR_TEAM1)
+ if(self.team == NUM_TEAM_1)
{
if(time - ons_notification_time_team1 > 10)
{
ons_notification_time_team1 = time;
}
}
- else if(self.team == COLOR_TEAM2)
+ else if(self.team == NUM_TEAM_2)
{
if(time - ons_notification_time_team2 > 10)
{
pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
{
string t;
- t = ColoredTeamName(attacker.team);
- bprint(ColoredTeamName(self.team), " ", self.message, " control point destroyed by ", t, "\n");
+ t = Team_ColoredFullName(attacker.team);
+ bprint(Team_ColoredFullName(self.team), " ", self.message, " control point destroyed by ", t, "\n");
ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 25, "models/onslaught/controlpoint_icon_gib1.md3", 3, FALSE);
ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 45, "models/onslaught/controlpoint_icon_gib2.md3", 3, FALSE);
ons_throwgib(self.origin, (2 * randomvec() - '1 1 1') * 45, "models/onslaught/controlpoint_icon_gib2.md3", 3, FALSE);
{
entity oself;
self.nextthink = time + sys_frametime;
-
- if(autocvar_g_onslaught_controlpoints_proxycap)
- {
+
+ if(autocvar_g_onslaught_cp_proxydecap)
+ {
float _enemy_count = 0;
float _friendly_count = 0;
float _dist;
if(!_player.deadflag)
{
_dist = vlen(_player.origin - self.origin);
- if(_dist < autocvar_g_onslaught_controlpoints_proxycap_distance)
+ if(_dist < autocvar_g_onslaught_cp_proxydecap_distance)
{
if(_player.team == self.team)
++_friendly_count;
}
}
- _friendly_count = _friendly_count * (autocvar_g_onslaught_controlpoints_proxycap_dps * sys_frametime);
- _enemy_count = _enemy_count * (autocvar_g_onslaught_controlpoints_proxycap_dps * sys_frametime);
-
+ _friendly_count = _friendly_count * (autocvar_g_onslaught_cp_proxydecap_dps * sys_frametime);
+ _enemy_count = _enemy_count * (autocvar_g_onslaught_cp_proxydecap_dps * sys_frametime);
+
self.health = bound(0, self.health + (_friendly_count - _enemy_count), self.max_health);
if(self.health <= 0)
{
return;
}
}
-
+
if (time > self.pain_finished + 5)
{
if(self.health < self.max_health)
self.count = autocvar_g_onslaught_cp_regen * sys_frametime; // slow repair rate from now on
self.think = onslaught_controlpoint_icon_think;
sound(self, CH_TRIGGER, "onslaught/controlpoint_built.wav", VOL_BASE, ATTN_NORM);
- bprint(ColoredTeamName(self.team), " captured ", self.owner.message, " control point\n");
+ bprint(Team_ColoredFullName(self.team), " captured ", self.owner.message, " control point\n");
self.owner.iscaptured = TRUE;
WaypointSprite_UpdateMaxHealth(self.owner.sprite, self.max_health);
{
entity e;
float a;
- if (other.classname != "player")
+ if not(IS_PLAYER(other))
return;
a = onslaught_controlpoint_attackable(self, other.team);
if(a != 2 && a != 4)
"target" - target any entities that are tied to this control point, such as vehicles and buildable structure entities.
"message" - name of this control point (should reflect the location in the map, such as "center bridge", "north tower", etc)
*/
-
- /*
- void onslaught_controlpoint_think()
- {
- self.nextthink = time;
- //if(autocvar_g_onslaught_controlpoints_proxycap)
-
- float _enemy_count;
- float _friendly_count;
- float _dist;
- entity _player;
-
- FOR_EACH_PLAYER(_player)
- {
- if(!_player.deadflag)
- {
- _dist = vlen(_player.origin - self.origin);
- if(_dist < autocvar_g_onslaught_controlpoints_proxycap_distance)
- {
- if(_player.team == self.team)
- ++_friendly_count;
- else
- ++_enemy_count;
- }
- }
- }
-
- _friendly_count = _friendly_count * (autocvar_g_onslaught_controlpoints_proxycap_dps * sys_frametime);
- _enemy_count = _enemy_count * (autocvar_g_onslaught_controlpoints_proxycap_dps * sys_frametime);
-
- self.health = bound(0, self.health + (_friendly_count - _enemy_count), self.max_health);
- if(self.health <= 0)
- {
- onslaught_controlpoint_icon_damage(self, self, 1, 0, self.origin, '0 0 0');
- return;
- }
-
- if(self.health == max_health)
- {
-
- }
- }
- */
void spawnfunc_onslaught_controlpoint()
{
precache_sound("onslaught/controlpoint_underattack.wav");
precache_sound("onslaught/ons_spark1.wav");
precache_sound("onslaught/ons_spark2.wav");
+
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_NONE;
setmodel(self, "models/onslaught/controlpoint_pad.md3");
//setsize(self, '-32 -32 0', '32 32 8');
- if (!self.noalign)
- droptofloor();
-
- setorigin(self, self.origin);
+ if(!self.noalign)
+ {
+ setorigin(self, self.origin + '0 0 20');
+ droptofloor();
+ }
self.touch = onslaught_controlpoint_touch;
self.team = 0;
self.colormap = 1024;
self.iscaptured = FALSE;
self.islinked = FALSE;
self.isshielded = TRUE;
+
// spawn shield model which indicates whether this can be damaged
self.enemy = spawn();
self.enemy.classname = "onslaught_controlpoint_shield";
self.enemy.movetype = MOVETYPE_NONE;
self.enemy.effects = EF_ADDITIVE;
setmodel(self.enemy , "models/onslaught/controlpoint_shield.md3");
-
+
setattachment(self.enemy , self, "");
//setsize(e, '-32 -32 0', '32 32 128');
waypoint_spawnforitem(self);
WaypointSprite_SpawnFixed(string_null, self.origin + '0 0 128', self, sprite, RADARICON_NONE, '0 0 0');
- WaypointSprite_UpdateRule(self.sprite, COLOR_TEAM2, SPRITERULE_TEAMPLAY);
+ WaypointSprite_UpdateRule(self.sprite, NUM_TEAM_2, SPRITERULE_TEAMPLAY);
onslaught_updatelinks();
-
+
self.reset = onslaught_controlpoint_reset;
}
redpower = bluepower = 0;
if(self.goalentity.islinked)
{
- if(self.goalentity.team == COLOR_TEAM1)
+ if(self.goalentity.team == NUM_TEAM_1)
redpower = 1;
- else if(self.goalentity.team == COLOR_TEAM2)
+ else if(self.goalentity.team == NUM_TEAM_2)
bluepower = 1;
}
if(self.enemy.islinked)
{
- if(self.enemy.team == COLOR_TEAM1)
+ if(self.enemy.team == NUM_TEAM_1)
redpower = 2;
- else if(self.enemy.team == COLOR_TEAM2)
+ else if(self.enemy.team == NUM_TEAM_2)
bluepower = 2;
}
float cc;
if(redpower == 1 && bluepower == 2)
- cc = (COLOR_TEAM1 - 1) * 0x01 + (COLOR_TEAM2 - 1) * 0x10;
+ cc = (NUM_TEAM_1 - 1) * 0x01 + (NUM_TEAM_2 - 1) * 0x10;
else if(redpower == 2 && bluepower == 1)
- cc = (COLOR_TEAM1 - 1) * 0x10 + (COLOR_TEAM2 - 1) * 0x01;
+ cc = (NUM_TEAM_1 - 1) * 0x10 + (NUM_TEAM_2 - 1) * 0x01;
else if(redpower)
- cc = (COLOR_TEAM1 - 1) * 0x11;
+ cc = (NUM_TEAM_1 - 1) * 0x11;
else if(bluepower)
- cc = (COLOR_TEAM2 - 1) * 0x11;
+ cc = (NUM_TEAM_2 - 1) * 0x11;
else
cc = 0;
MUTATOR_HOOKFUNCTION(ons_BuildMutatorsPrettyString)
{
- ret_string = strcat(ret_string, ", Onslught");
+ ret_string = strcat(ret_string, ", Onslaught");
return 0;
}
RandomSelection_Init();
- if(self.team == COLOR_TEAM1)
+ if(self.team == NUM_TEAM_1)
RandomSelection_Add(ons_red_generator, 0, string_null, 1, 1);
- if(self.team == COLOR_TEAM2)
+ if(self.team == NUM_TEAM_2)
RandomSelection_Add(ons_blue_generator, 0, string_null, 1, 1);
entity _cp = findchain(classname, "onslaught_controlpoint"):
RandomSelection_Init();
- if(self.team == COLOR_TEAM1)
+ if(self.team == NUM_TEAM_1)
{
if(!_close_to_home)
_trg_gen = ons_blue_generator;
_trg_gen = ons_red_generator;
}
- if(self.team == COLOR_TEAM2)
+ if(self.team == NUM_TEAM_2)
{
if(_close_to_home)
_trg_gen = ons_blue_generator;
if(!autocvar_g_onslaught_spawn_at_generator)
return 0;
- _trg_gen = ((self.team == COLOR_TEAM1) ? ons_red_generator : ons_blue_generator);
+ _trg_gen = ((self.team == NUM_TEAM_1) ? ons_red_generator : ons_blue_generator);
for(i = 0; i < 10; ++i)
{
MUTATOR_DEFINITION(gamemode_onslaught)
{
- //MUTATOR_HOOK(PlayerDies, nexball_BallDrop, CBC_ORDER_ANY);
- //MUTATOR_HOOK(MakePlayerObserver, nexball_BallDrop, CBC_ORDER_ANY);
- //MUTATOR_HOOK(ClientDisconnect, nexball_BallDrop, CBC_ORDER_ANY);
- //MUTATOR_HOOK(PlayerPreThink, nexball_PlayerPreThink, CBC_ORDER_ANY);
MUTATOR_HOOK(BuildMutatorsPrettyString, ons_BuildMutatorsPrettyString, CBC_ORDER_ANY);
MUTATOR_HOOK(BuildMutatorsString, ons_BuildMutatorsString, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerSpawn, ons_PlayerSpawn, CBC_ORDER_ANY);
//MUTATOR_HOOK(Spawn_Score, ons_Spawn_Score, CBC_ORDER_ANY);
-
+
MUTATOR_ONADD
{
if(time > 1) // game loads at time 1
if(dt >= 1 && dt <= 5)
self.nix_lastinfotime = -42;
else
- Send_CSQC_Centerprint_Generic(self, CPID_NIX_WPNCHANGE, strcat("^2Active weapon: ^3", W_Name(nix_weapon)), 0, 0);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_NIX_NEWWEAPON, nix_weapon);
weapon_action(nix_weapon, WR_RESETPLAYER);
{
self.nix_lastinfotime = dt; // initial value 0 should count as "not seen"
if(dt >= 1 && dt <= 5)
- Send_CSQC_Centerprint_Generic(self, CPID_NIX_WPNCHANGE, strcat("^3%d^2 seconds until weapon change...\n\nNext weapon: ^3", W_Name(nix_nextweapon)), 1, dt);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_NIX_COUNTDOWN, nix_nextweapon, dt);
}
if(!(self.items & IT_UNLIMITED_WEAPON_AMMO) && time > self.nix_nextincr)
{
if(!intermission_running)
if(self.deadflag == DEAD_NO)
- if(self.classname == "player")
+ if(IS_PLAYER(self))
NIX_GiveCurrentWeapon();
return 0;
}
(self.autospec_flags& ASF_FLAG_GRAB && _item.classname == "item_flag_team"))
{
- if((self.enemy != other) || self.classname == "observer")
+ if((self.enemy != other) || IS_OBSERVER(self))
{
- if(self.autospec_flags & ASF_OBSERVER_ONLY && self.classname != "observer")
+ if(self.autospec_flags & ASF_OBSERVER_ONLY && !IS_OBSERVER(self))
{
if(self.superspec_flags & SSF_VERBOSE)
superspec_msg("", "", self, sprintf("^8Ignored that %s^8 grabbed %s^8 since the observer_only option is ON\n", other.netname, _item.netname), 2);
if(MUTATOR_RETURNVALUE) // command was already handled?
return FALSE;
- if(self.classname == "player")
+ if(IS_PLAYER(self))
return FALSE;
if(cmd_name == "superspec_itemfilter")
if(cmd_argc == 2)
{
if(argv(1) == "red")
- _team = COLOR_TEAM1;
+ _team = NUM_TEAM_1;
else
- _team = COLOR_TEAM2;
+ _team = NUM_TEAM_2;
}
FOR_EACH_PLAYER(_player)
MUTATOR_HOOKFUNCTION(superspec_ClientConnect)
{
+ if(clienttype(self) != CLIENTTYPE_REAL)
+ return FALSE;
+
string fn = "superspec-local.options";
float fh;
//print(vtos(to), "\n");
// ang_x stuff works around weird quake angles
- if(player.classname == "player")
+ if(IS_PLAYER(player))
ang = Portal_ApplyTransformToPlayerAngle(transform, player.v_angle);
else
ang = AnglesTransform_ApplyToAngles(transform, player.angles);
{
// telefrag within 1 second of portal creation = amazing
if(time < teleporter.teleport_time + 1)
- AnnounceTo(player, "amazing");
+ Send_Notification(NOTIF_ONE, player, MSG_ANNCE, ANNCE_ACHIEVEMENT_AMAZING);
}
if not(teleporter.enemy)
if(self.solid != SOLID_TRIGGER)
return; // possibly engine bug
- if(other.classname == "player")
+ if(IS_PLAYER(other))
return; // handled by think
#endif
return;
}
if(other != self.aiment)
- if(other.classname == "player")
+ if(IS_PLAYER(other))
if(IS_INDEPENDENT_PLAYER(other) || IS_INDEPENDENT_PLAYER(self.aiment))
return; // cannot go through someone else's portal
if(other.aiment != self.aiment)
- if(other.aiment.classname == "player")
+ if(IS_PLAYER(other.aiment))
if(IS_INDEPENDENT_PLAYER(other.aiment) || IS_INDEPENDENT_PLAYER(self.aiment))
return; // cannot go through someone else's portal
fixedmakevectors(self.mangle);
float Portal_Customize()
{
- if(other.classname == "spectator")
+ if(IS_SPEC(other))
other = other.enemy;
if(other == self.aiment)
{
}
float oldrec;
- string recorddifference, oldrec_holder;
+ string oldrec_holder;
if (player_prevpos && (player_prevpos < newpos || !newpos))
{
oldrec = race_readTime(GetMapname(), player_prevpos);
- recorddifference = strcat(" ^1[+", TIME_ENCODED_TOSTRING(t - oldrec), "]");
- bprint(mynetname, "^7 couldn't break their ", race_placeName(player_prevpos), " place record of ", TIME_ENCODED_TOSTRING(oldrec), recorddifference, "\n");
race_SendStatus(0, e); // "fail"
- Send_KillNotification(e.netname, TIME_ENCODED_TOSTRING(t), "", RACE_FAIL, MSG_RACE);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_RACE_FAIL_RANKED, mynetname, player_prevpos, t, oldrec);
return;
} else if (!newpos) { // no ranking, time worse than the worst ranked
- recorddifference = strcat(" ^1[+", TIME_ENCODED_TOSTRING(t - race_readTime(GetMapname(), RANKINGS_CNT)), "]");
- bprint(mynetname, "^7 couldn't break the ", race_placeName(RANKINGS_CNT), " place record of ", TIME_ENCODED_TOSTRING(race_readTime(GetMapname(), RANKINGS_CNT)), recorddifference, "\n");
+ oldrec = race_readTime(GetMapname(), RANKINGS_CNT);
race_SendStatus(0, e); // "fail"
- Send_KillNotification(e.netname, TIME_ENCODED_TOSTRING(t), "", RACE_FAIL, MSG_RACE);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_RACE_FAIL_UNRANKED, mynetname, RANKINGS_CNT, t, oldrec);
return;
}
// if the player does not have a UID we can unfortunately not store the record, as the rankings system relies on UIDs
if(myuid == "")
{
- bprint(mynetname, "^1 scored a new record with ^7", TIME_ENCODED_TOSTRING(t), "^1, but lacks a UID, so the record will unfortunately be lost.\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_RACE_NEW_MISSING_UID, mynetname, t);
return;
}
if(rankings_reply)
strunzone(rankings_reply);
rankings_reply = strzone(getrankings());
- if(newpos == 1) {
- if(newpos == player_prevpos) {
- recorddifference = strcat(" ^2[-", TIME_ENCODED_TOSTRING(oldrec - t), "]");
- bprint(mynetname, "^1 improved their 1st place record with ", TIME_ENCODED_TOSTRING(t), recorddifference, "\n");
- } else if (oldrec == 0) {
- bprint(mynetname, "^1 set the 1st place record with ", TIME_ENCODED_TOSTRING(t), "\n");
- } else {
- recorddifference = strcat(" ^2[-", TIME_ENCODED_TOSTRING(oldrec - t), "]");
- bprint(mynetname, "^1 broke ", oldrec_holder, "^1's 1st place record with ", strcat(TIME_ENCODED_TOSTRING(t), recorddifference, "\n"));
- }
- race_SendStatus(3, e); // "new server record"
- Send_KillNotification(e.netname, TIME_ENCODED_TOSTRING(t), "", RACE_SERVER_RECORD, MSG_RACE);
- } else {
- if(newpos == player_prevpos) {
- recorddifference = strcat(" ^2[-", TIME_ENCODED_TOSTRING(oldrec - t), "]");
- bprint(mynetname, "^5 improved their ", race_placeName(newpos), " ^5place record with ", TIME_ENCODED_TOSTRING(t), recorddifference, "\n");
- race_SendStatus(1, e); // "new time"
- Send_KillNotification(e.netname, TIME_ENCODED_TOSTRING(t), "", RACE_NEW_TIME, MSG_RACE);
- } else if (oldrec == 0) {
- bprint(mynetname, "^2 set the ", race_placeName(newpos), " ^2place record with ", TIME_ENCODED_TOSTRING(t), "\n");
- race_SendStatus(2, e); // "new rank"
- Send_KillNotification(e.netname, TIME_ENCODED_TOSTRING(t), "", RACE_NEW_RANK, MSG_RACE);
- } else {
- recorddifference = strcat(" ^2[-", TIME_ENCODED_TOSTRING(oldrec - t), "]");
- bprint(mynetname, "^2 broke ", oldrec_holder, "^2's ", race_placeName(newpos), " ^2place record with ", strcat(TIME_ENCODED_TOSTRING(t), recorddifference, "\n"));
- race_SendStatus(2, e); // "new rank"
- Send_KillNotification(e.netname, TIME_ENCODED_TOSTRING(t), "", RACE_NEW_TIME, MSG_RACE);
- }
+
+ if(newpos == player_prevpos)
+ {
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_RACE_NEW_IMPROVED, mynetname, newpos, t, oldrec);
+ if(newpos == 1) { race_SendStatus(3, e); } // "new server record"
+ else { race_SendStatus(1, e); } // "new time"
+ }
+ else if(oldrec == 0)
+ {
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_RACE_NEW_SET, mynetname, newpos, t);
+ if(newpos == 1) { race_SendStatus(3, e); } // "new server record"
+ else { race_SendStatus(2, e); } // "new rank"
+ }
+ else
+ {
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_RACE_NEW_BROKEN, mynetname, oldrec_holder, newpos, t, oldrec);
+ if(newpos == 1) { race_SendStatus(3, e); } // "new server record"
+ else { race_SendStatus(2, e); } // "new rank"
}
}
{
e.race_completed = 1;
MAKE_INDEPENDENT_PLAYER(e);
- bprint(e.netname, "^7 has finished the race.\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_RACE_FINISHED, e.netname);
ClientData_Touch(e);
}
}
/*
* Trigger targets
*/
- if not((self.spawnflags & 2) && (other.classname == "player"))
+ if not((self.spawnflags & 2) && (IS_PLAYER(other)))
{
activator = other;
oldmsg = self.message;
self.message = oldmsg;
}
- if(other.classname != "player")
+ if not(IS_PLAYER(other))
return;
/*
{
p.race_completed = 1;
MAKE_INDEPENDENT_PLAYER(p);
- bprint(p.netname, "^7 has abandoned the race.\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_RACE_ABANDONED, p.netname);
ClientData_Touch(p);
}
}
Net_LinkEntity(scores_initialized, FALSE, 0, ScoreInfo_SendEntity);
}
if(teams >= 1)
- TeamScore_Spawn(COLOR_TEAM1, "Red");
+ TeamScore_Spawn(NUM_TEAM_1, "Red");
if(teams >= 2)
- TeamScore_Spawn(COLOR_TEAM2, "Blue");
+ TeamScore_Spawn(NUM_TEAM_2, "Blue");
if(teams >= 3)
- TeamScore_Spawn(COLOR_TEAM3, "Yellow");
+ TeamScore_Spawn(NUM_TEAM_3, "Yellow");
if(teams >= 4)
- TeamScore_Spawn(COLOR_TEAM4, "Pink");
+ TeamScore_Spawn(NUM_TEAM_4, "Pink");
}
/*
if(teamscores_entities_count)
return 0;
+ if(MUTATOR_CALLHOOK(ForbidPlayerScore_Clear)) return 0;
if(g_lms) return 0;
- if(g_arena || g_ca) return 0;
if(g_cts) return 0; // in CTS, you don't lose score by observing
if(g_race && g_race_qualifying) return 0; // in qualifying, you don't lose score by observing
// so to match pure, match for :P0:
// to match full, match for :S0:
+ fullstatus = autocvar_g_full_getstatus_responses;
+
s = GetGametype();
s = strcat(s, ":", autocvar_g_xonoticversion);
s = strcat(s, ":P", ftos(cvar_purechanges_count));
s = strcat(s, ":S", ftos(nJoinAllowed(world)));
s = strcat(s, ":F", ftos(serverflags));
s = strcat(s, ":M", modname);
- s = strcat(s, "::", GetPlayerScoreString(world, 1)); // make this 1 once we can, note: this doesn't contain any :<letter>
-
- fullstatus = autocvar_g_full_getstatus_responses;
+ s = strcat(s, "::", GetPlayerScoreString(world, (fullstatus ? 1 : 2)));
if(teamscores_entities_count)
{
if(fullstatus)
{
s = GetPlayerScoreString(p, 1);
- if(clienttype(p) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(p))
s = strcat(s, ":human");
else
s = strcat(s, ":bot");
- if(!IS_PLAYER(p) && !g_arena && !g_ca && !g_lms)
- if(p.classname != "player" && !g_arena && p.caplayer != 1 && !g_lms)
++ if(!IS_PLAYER(p) && !g_arena && p.caplayer != 1 && !g_lms)
s = strcat(s, ":spectator");
}
else
{
- if(IS_PLAYER(p) || g_arena || g_ca || g_lms)
- if(p.classname == "player" || g_arena || p.caplayer == 1 || g_lms)
++ if(IS_PLAYER(p) || g_arena || p.caplayer == 1 || g_lms)
s = GetPlayerScoreString(p, 2);
else
s = "-666";
if(tm == 0)
{
// label
- for(i = 0; i < MAX_SCORE; ++i)
+ for(i = 0; i < MAX_TEAMSCORE; ++i)
if(teamscores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_PRIMARY)
{
f = teamscores_flags[i];
out = strcat(out, GetScoreLogLabel(l, f), ",");
}
if(shortString < 2)
- for(i = 0; i < MAX_SCORE; ++i)
+ for(i = 0; i < MAX_TEAMSCORE; ++i)
if(teamscores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_SECONDARY)
{
f = teamscores_flags[i];
out = strcat(out, GetScoreLogLabel(l, f), ",");
}
if(shortString < 1)
- for(i = 0; i < MAX_SCORE; ++i)
+ for(i = 0; i < MAX_TEAMSCORE; ++i)
if(teamscores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_PRIMARY)
if(teamscores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_SECONDARY)
{
sk = teamscorekeepers[t - 1];
if(sk)
{
- s = strcat(s, ColoredTeamName(t));
+ s = strcat(s, Team_ColoredFullName(t));
for(i = 0; i < MAX_TEAMSCORE; ++i)
if(teamscores_label[i] != "")
{
t = 0;
FOR_EACH_CLIENT(p)
- if(p.classname != "player")
+ if not(IS_PLAYER(p))
{
if not(t)
Score_NicePrint_Spectators(to);
float game_delay;
float game_delay_last;
- void RuneMatchGivePoints();
float RedirectionThink();
entity SelectSpawnPoint (float anypoint);
void StartFrame (void)
c_seen = 0;
FOR_EACH_CLIENT(cl)
{
- if(clienttype(cl) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(cl))
++c_seeing;
- if(cl.classname == "player")
+ if(IS_PLAYER(cl))
++c_seen;
}
print("CEFC calls per second: ", ftos(c_seeing * (c_seen - 1) / t), "; ");
skill = autocvar_skill;
- count_players();
- if(g_ca || g_freezetag)
- count_alive_players();
- Arena_Warmup();
- Spawnqueue_Check();
-
// detect when the pre-game countdown (if any) has ended and the game has started
game_delay = (time < game_starttime) ? TRUE : FALSE;
if(game_delay_last == TRUE)
if(game_delay == FALSE)
if(autocvar_sv_eventlog)
- GameLogEcho(":startdelay_ended");
+ GameLogEcho(":startdelay_ended");
game_delay_last = game_delay;
CreatureFrame ();
CheckRules_World ();
- RuneMatchGivePoints();
bot_serverframe();
FOR_EACH_PLAYER(self)
_switchweapon = TRUE;
// play some cool sounds ;)
- if (clienttype(player) == CLIENTTYPE_REAL)
+ if (IS_REAL_CLIENT(player))
{
if(player.health <= 5)
- AnnounceTo(player, "lastsecond");
+ Send_Notification(NOTIF_ONE, player, MSG_ANNCE, ANNCE_MINSTAGIB_LASTSECOND);
else if(player.health < 50)
- AnnounceTo(player, "narrowly");
+ Send_Notification(NOTIF_ONE, player, MSG_ANNCE, ANNCE_MINSTAGIB_NARROWLY);
}
// sound not available
// else if(item.items == IT_CELLS)
// AnnounceTo(player, "ammo");
if (WEPSET_CONTAINS_EW(item, WEP_MINSTANEX))
- W_GiveWeapon (player, WEP_MINSTANEX, item.netname);
+ W_GiveWeapon (player, WEP_MINSTANEX);
player.health = 100;
}
pickedup = TRUE;
for(i = WEP_FIRST; i <= WEP_LAST; ++i)
if(WEPSET_CONTAINS_AW(it, i))
- W_GiveWeapon (player, i, item.netname);
+ W_GiveWeapon(player, i);
}
}
}
}
- if (other.classname != "player")
+ if not(IS_PLAYER(other))
return;
if (other.deadflag)
return;
return;
}
- if(activator.classname != "player")
+ if not(IS_PLAYER(activator))
return;
if(activator.deadflag != DEAD_NO)
return;
torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5;
grav = autocvar_sv_gravity;
+ if(other.gravity)
+ grav *= other.gravity;
zdist = torg_z - org_z;
sdist = vlen(torg - org - zdist * '0 0 1');
other.flags &~= FL_ONGROUND;
- if (other.classname == "player")
+ if (IS_PLAYER(other))
{
// reset tracking of oldvelocity for impact damage (sudden velocity changes)
other.oldvelocity = other.velocity;
sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTN_NORM);
self.pushltime = time + 0.2;
}
- float ct;
- ct = clienttype(other);
- if( ct == CLIENTTYPE_REAL || ct == CLIENTTYPE_BOT)
+ if(IS_REAL_CLIENT(other) || IS_BOT_CLIENT(other))
{
float i;
float found;
other.jumppadcount = other.jumppadcount + 1;
}
- if(ct == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(other))
{
if(self.message)
centerprint(other, self.message);
PlayerScore_Clear(e);
}
- vector TeamColor(float teem)
- {
- switch(teem)
- {
- case COLOR_TEAM1:
- return '1 0.0625 0.0625';
- case COLOR_TEAM2:
- return '0.0625 0.0625 1';
- case COLOR_TEAM3:
- return '1 1 0.0625';
- case COLOR_TEAM4:
- return '1 0.0625 1';
- default:
- return '1 1 1';
- }
- }
-
- string TeamName(float t)
- {
- return strcat(Team_ColorName(t), " Team");
- }
- string ColoredTeamName(float t)
- {
- return strcat(Team_ColorCode(t), Team_ColorName(t), " Team^7");
- }
- string TeamNoName(float t)
- {
- // fixme: Search for team entities and get their .netname's!
- if(t == 1)
- return "Red Team";
- if(t == 2)
- return "Blue Team";
- if(t == 3)
- return "Yellow Team";
- if(t == 4)
- return "Pink Team";
- return "Neutral Team";
- }
-
- void runematch_init();
void tdm_init();
void entcs_init();
have_team_spawns = -1; // request team spawns
}
- if(g_runematch)
- {
- // ActivateTeamplay();
- fraglimit_override = autocvar_g_runematch_point_limit;
- leadlimit_override = autocvar_g_runematch_point_leadlimit;
- runematch_init();
- }
-
if(g_lms)
{
fraglimit_override = autocvar_g_lms_lives_override;
{
fraglimit_override = autocvar_g_arena_point_limit;
leadlimit_override = autocvar_g_arena_point_leadlimit;
- maxspawned = autocvar_g_arena_maxspawned;
- if(maxspawned < 2)
- maxspawned = 2;
- arena_roundbased = autocvar_g_arena_roundbased;
+ MUTATOR_ADD(gamemode_arena);
}
if(g_ca)
ActivateTeamplay();
fraglimit_override = autocvar_g_ca_point_limit;
leadlimit_override = autocvar_g_ca_point_leadlimit;
- precache_sound("ctf/red_capture.wav");
- precache_sound("ctf/blue_capture.wav");
+ MUTATOR_ADD(gamemode_ca);
}
+
if(g_keyhunt)
{
ActivateTeamplay();
float _color;
if(t == 4)
- _color = COLOR_TEAM4 - 1;
+ _color = NUM_TEAM_4 - 1;
else if(t == 3)
- _color = COLOR_TEAM3 - 1;
+ _color = NUM_TEAM_3 - 1;
else if(t == 2)
- _color = COLOR_TEAM2 - 1;
+ _color = NUM_TEAM_2 - 1;
else
- _color = COLOR_TEAM1 - 1;
+ _color = NUM_TEAM_1 - 1;
SetPlayerColors(pl,_color);
LogTeamchange(pl.playerid, pl.team, 3); // log manual team join
if(!noprint)
- bprint(pl.netname, "^7 has changed from ", TeamNoName(s), " to ", TeamNoName(t), "\n");
+ bprint(pl.netname, "^7 has changed from ", Team_NumberToColoredFullName(s), "^7 to ", Team_NumberToColoredFullName(t), "\n");
}
}
head = findchain(classname, "onslaught_generator");
while (head)
{
- if (head.team == COLOR_TEAM1) c1 = 0;
- if (head.team == COLOR_TEAM2) c2 = 0;
- if (head.team == COLOR_TEAM3) c3 = 0;
- if (head.team == COLOR_TEAM4) c4 = 0;
+ if (head.team == NUM_TEAM_1) c1 = 0;
+ if (head.team == NUM_TEAM_2) c2 = 0;
+ if (head.team == NUM_TEAM_3) c3 = 0;
+ if (head.team == NUM_TEAM_4) c4 = 0;
head = head.chain;
}
}
{
if(!(g_domination && head.netname == ""))
{
- if(head.team == COLOR_TEAM1)
+ if(head.team == NUM_TEAM_1)
c1 = 0;
- else if(head.team == COLOR_TEAM2)
+ else if(head.team == NUM_TEAM_2)
c2 = 0;
- else if(head.team == COLOR_TEAM3)
+ else if(head.team == NUM_TEAM_3)
c3 = 0;
- else if(head.team == COLOR_TEAM4)
+ else if(head.team == NUM_TEAM_4)
c4 = 0;
}
head = find(head, classname, teament_name);
if(autocvar_bot_vs_human > 0)
{
// bots are all blue
- if(clienttype(for_whom) == CLIENTTYPE_BOT)
+ if(IS_BOT_CLIENT(for_whom))
c1 = c3 = c4 = -1;
else
c2 = -1;
else
{
// bots are all red
- if(clienttype(for_whom) == CLIENTTYPE_BOT)
+ if(IS_BOT_CLIENT(for_whom))
c2 = c3 = c4 = -1;
else
c1 = -1;
}
// if player has a forced team, ONLY allow that one
- if(self.team_forced == COLOR_TEAM1 && c1 >= 0)
+ if(self.team_forced == NUM_TEAM_1 && c1 >= 0)
c2 = c3 = c4 = -1;
- else if(self.team_forced == COLOR_TEAM2 && c2 >= 0)
+ else if(self.team_forced == NUM_TEAM_2 && c2 >= 0)
c1 = c3 = c4 = -1;
- else if(self.team_forced == COLOR_TEAM3 && c3 >= 0)
+ else if(self.team_forced == NUM_TEAM_3 && c3 >= 0)
c1 = c2 = c4 = -1;
- else if(self.team_forced == COLOR_TEAM4 && c4 >= 0)
+ else if(self.team_forced == NUM_TEAM_4 && c4 >= 0)
c1 = c2 = c3 = -1;
}
FOR_EACH_CLIENT(head)
{
float t;
- if(head.classname == "player")
+ if(IS_PLAYER(head))
t = head.team;
else if(head.team_forced > 0)
t = head.team_forced; // reserve the spot
if(head != ignore)// && head.netname != "")
{
value = PlayerValue(head);
- if(clienttype(head) == CLIENTTYPE_BOT)
+ if(IS_BOT_CLIENT(head))
bvalue = value;
else
bvalue = 0;
- if(t == COLOR_TEAM1)
+ if(t == NUM_TEAM_1)
{
if(c1 >= 0)
{
cb1 = cb1 + bvalue;
}
}
- if(t == COLOR_TEAM2)
+ if(t == NUM_TEAM_2)
{
if(c2 >= 0)
{
cb2 = cb2 + bvalue;
}
}
- if(t == COLOR_TEAM3)
+ if(t == NUM_TEAM_3)
{
if(c3 >= 0)
{
cb3 = cb3 + bvalue;
}
}
- if(t == COLOR_TEAM4)
+ if(t == NUM_TEAM_4)
{
if(c4 >= 0)
{
if(ta == tb)
return TRUE;
- if(clienttype(e) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(e))
{
if(bots_would_leave)
{
if(totalteams <= 1)
{
- if(autocvar_g_campaign && pl && clienttype(pl) == CLIENTTYPE_REAL)
+ if(autocvar_g_campaign && pl && IS_REAL_CLIENT(pl))
return 1; // special case for campaign and player joining
else if(g_domination)
error("Too few teams available for domination\n");
// if he's not on a valid team, then let other code put him on the smallest team
if(!forcebestteam)
{
- if( c1 >= 0 && pl.team == COLOR_TEAM1)
+ if( c1 >= 0 && pl.team == NUM_TEAM_1)
selectedteam = pl.team;
- else if(c2 >= 0 && pl.team == COLOR_TEAM2)
+ else if(c2 >= 0 && pl.team == NUM_TEAM_2)
selectedteam = pl.team;
- else if(c3 >= 0 && pl.team == COLOR_TEAM3)
+ else if(c3 >= 0 && pl.team == NUM_TEAM_3)
selectedteam = pl.team;
- else if(c4 >= 0 && pl.team == COLOR_TEAM4)
+ else if(c4 >= 0 && pl.team == NUM_TEAM_4)
selectedteam = pl.team;
else
selectedteam = -1;
TeamchangeFrags(self);
if(smallest == 1)
{
- SetPlayerColors(pl, COLOR_TEAM1 - 1);
+ SetPlayerColors(pl, NUM_TEAM_1 - 1);
}
else if(smallest == 2)
{
- SetPlayerColors(pl, COLOR_TEAM2 - 1);
+ SetPlayerColors(pl, NUM_TEAM_2 - 1);
}
else if(smallest == 3)
{
- SetPlayerColors(pl, COLOR_TEAM3 - 1);
+ SetPlayerColors(pl, NUM_TEAM_3 - 1);
}
else if(smallest == 4)
{
- SetPlayerColors(pl, COLOR_TEAM4 - 1);
+ SetPlayerColors(pl, NUM_TEAM_4 - 1);
}
else
{
scolor = self.clientcolors & 0x0F;
dcolor = _color & 0x0F;
- if(scolor == COLOR_TEAM1 - 1)
+ if(scolor == NUM_TEAM_1 - 1)
steam = 1;
- else if(scolor == COLOR_TEAM2 - 1)
+ else if(scolor == NUM_TEAM_2 - 1)
steam = 2;
- else if(scolor == COLOR_TEAM3 - 1)
+ else if(scolor == NUM_TEAM_3 - 1)
steam = 3;
- else // if(scolor == COLOR_TEAM4 - 1)
+ else // if(scolor == NUM_TEAM_4 - 1)
steam = 4;
- if(dcolor == COLOR_TEAM1 - 1)
+ if(dcolor == NUM_TEAM_1 - 1)
dteam = 1;
- else if(dcolor == COLOR_TEAM2 - 1)
+ else if(dcolor == NUM_TEAM_2 - 1)
dteam = 2;
- else if(dcolor == COLOR_TEAM3 - 1)
+ else if(dcolor == NUM_TEAM_3 - 1)
dteam = 3;
- else // if(dcolor == COLOR_TEAM4 - 1)
+ else // if(dcolor == NUM_TEAM_4 - 1)
dteam = 4;
CheckAllowedTeams(self);
// bprint("allow change teams from ", ftos(steam), " to ", ftos(dteam), "\n");
- if(self.classname == "player" && steam != dteam)
+ if(IS_PLAYER(self) && steam != dteam)
{
// reduce frags during a team change
TeamchangeFrags(self);
SetPlayerTeam(self, dteam, steam, FALSE);
- if(self.classname == "player" && steam != dteam)
+ if(IS_PLAYER(self) && steam != dteam)
{
// kill player when changing teams
if(self.deadflag == DEAD_NO)
}
if(source_team == 1)
- steam = COLOR_TEAM1;
+ steam = NUM_TEAM_1;
else if(source_team == 2)
- steam = COLOR_TEAM2;
+ steam = NUM_TEAM_2;
else if(source_team == 3)
- steam = COLOR_TEAM3;
+ steam = NUM_TEAM_3;
else // if(source_team == 4)
- steam = COLOR_TEAM4;
+ steam = NUM_TEAM_4;
lowest_bot = world;
lowest_bot_score = 999999999;
if(selected.deadflag == DEAD_NO)
Damage(selected, selected, selected, 100000, DEATH_AUTOTEAMCHANGE, selected.origin, '0 0 0');
- centerprint(selected, strcat("You have been moved into a different team to improve team balance\nYou are now on: ", ColoredTeamName(selected.team)));
+ centerprint(selected, strcat("You have been moved into a different team to improve team balance\nYou are now on: ", Team_ColoredFullName(selected.team)));
}
// code from here on is just to support maps that don't have team entities
numteams = autocvar_g_tdm_teams;
numteams = bound(2, numteams, 4);
- tdm_spawnteam("Red", COLOR_TEAM1-1);
- tdm_spawnteam("Blue", COLOR_TEAM2-1);
+ tdm_spawnteam("Red", NUM_TEAM_1-1);
+ tdm_spawnteam("Blue", NUM_TEAM_2-1);
if(numteams >= 3)
- tdm_spawnteam("Yellow", COLOR_TEAM3-1);
+ tdm_spawnteam("Yellow", NUM_TEAM_3-1);
if(numteams >= 4)
- tdm_spawnteam("Pink", COLOR_TEAM4-1);
+ tdm_spawnteam("Pink", NUM_TEAM_4-1);
}
void tdm_delayedinit()
vehicles_projectile("bigplasma_muzzleflash", "weapons/flacexp3.wav",
v, normalize(v_forward + randomvec() * autocvar_g_vehicle_bumblebee_cannon_spread) * autocvar_g_vehicle_bumblebee_cannon_speed,
autocvar_g_vehicle_bumblebee_cannon_damage, autocvar_g_vehicle_bumblebee_cannon_radius, autocvar_g_vehicle_bumblebee_cannon_force, 0,
- DEATH_BUMB_GUN, PROJECTILE_BUMBLE_GUN, 0, TRUE, TRUE, _owner);
+ DEATH_VH_BUMB_GUN, PROJECTILE_BUMBLE_GUN, 0, TRUE, TRUE, _owner);
}
float bumb_gunner_frame()
void bumb_gunner_exit(float _exitflag)
{
-
-
- if(clienttype(self) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(self))
{
msg_entity = self;
WriteByte(MSG_ONE, SVC_SETVIEWPORT);
float vehicles_valid_pilot()
{
- if(other.classname != "player")
+ if not(IS_PLAYER(other))
return FALSE;
if(other.deadflag != DEAD_NO)
if(other.vehicle != world)
return FALSE;
- if(clienttype(other) != CLIENTTYPE_REAL)
+ if not(IS_REAL_CLIENT(other))
if(!autocvar_g_vehicles_allow_bots)
return FALSE;
if(autocvar_g_vehicle_bumblebee_healgun_hps)
trace_ent.vehicle_health = min(trace_ent.vehicle_health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, trace_ent.tur_health);
}
- else if(trace_ent.flags & FL_CLIENT)
+ else if(IS_CLIENT(trace_ent))
{
if(trace_ent.health <= autocvar_g_vehicle_bumblebee_healgun_hmax && autocvar_g_vehicle_bumblebee_healgun_hps)
trace_ent.health = min(trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, autocvar_g_vehicle_bumblebee_healgun_hmax);
autocvar_g_vehicle_bumblebee_blowup_edgedamage,
autocvar_g_vehicle_bumblebee_blowup_radius, self,
autocvar_g_vehicle_bumblebee_blowup_forceintensity,
- DEATH_WAKIBLOWUP, world);
+ DEATH_VH_BUMB_DEATH, world);
sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
pointparticles(particleeffectnum("explosion_large"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1);
void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, float axh_id)
{
- if (clienttype(own) != CLIENTTYPE_REAL)
+ if not(IS_REAL_CLIENT(own))
return;
entity axh;
**/
void CSQCVehicleSetup(entity own, float vehicle_id)
{
- if (clienttype(own) != CLIENTTYPE_REAL)
+ if not(IS_REAL_CLIENT(own))
return;
msg_entity = own;
// Better way of determening whats crushable needed! (fl_crushable?)
float vehicles_crushable(entity e)
{
- if(e.classname == "player")
+ if(IS_PLAYER(e))
return TRUE;
- if(e.classname == "monster_zombie")
- return TRUE;
+ if(e.flags & FL_MONSTER)
+ return TRUE; // more bitflags for everyone!
return FALSE;
}
if(vehicles_crushable(other))
{
if(vlen(self.velocity) != 0)
- Damage(other, self, self.owner, autocvar_g_vehicles_crush_dmg, DEATH_VHCRUSH, '0 0 0', normalize(other.origin - self.origin) * autocvar_g_vehicles_crush_force);
+ Damage(other, self, self.owner, autocvar_g_vehicles_crush_dmg, DEATH_VH_CRUSH, '0 0 0', normalize(other.origin - self.origin) * autocvar_g_vehicles_crush_force);
return; // Dont do selfdamage when hitting "soft targets".
}
return;
}
- if(other.classname != "player")
+ if not(IS_PLAYER(other))
return;
if(other.deadflag != DEAD_NO)
{
// Remove this when bots know how to use vehicles
- if (clienttype(other) == CLIENTTYPE_BOT)
+ if (IS_BOT_CLIENT(other))
if (autocvar_g_vehicles_allow_bots)
dprint("Bot enters vehicle\n"); // This is where we need to disconnect (some, all?) normal bot AI and hand over to vehicle's _aiframe()
else
self.team = self.owner.team;
self.flags -= FL_NOTARGET;
- if (clienttype(other) == CLIENTTYPE_REAL)
+ if (IS_REAL_CLIENT(other))
{
msg_entity = other;
WriteByte (MSG_ONE, SVC_SETVIEWPORT);
}
vehicles_exit_running = TRUE;
- if(self.flags & FL_CLIENT)
+ if(IS_CLIENT(self))
{
_vehicle = self.vehicle;
if (_player)
{
- if (clienttype(_player) == CLIENTTYPE_REAL)
+ if (IS_REAL_CLIENT(_player))
{
msg_entity = _player;
WriteByte (MSG_ONE, SVC_SETVIEWPORT);
}
if(teamplay && self.team)
- rgb = TeamColor(self.team);
+ rgb = Team_ColorRGB(self.team);
else
rgb = '1 1 1';
WaypointSprite_Spawn("vehicle", 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, TRUE, RADARICON_POWERUP, rgb);
self.vehicle_exit = exitfunc;
self.vehicle_enter = enterproc;
self.PlayerPhysplug = physproc;
- self.event_damage = vehicles_damage;
+ self.event_damage = func_null;
self.touch = vehicles_touch;
self.think = vehicles_spawn;
self.nextthink = time;
- void W_GiveWeapon (entity e, float wep, string name)
+ void W_GiveWeapon (entity e, float wep)
{
entity oldself;
oldself = self;
self = e;
-- if not(g_minstagib)
- if (IS_PLAYER(other))
- {
- sprint (other, "You got the ^2");
- sprint (other, name);
- sprint (other, "\n");
- }
- if(other.classname == "player")
++ if(IS_PLAYER(other))
+ { Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_WEAPON_GOT, wep); }
self = oldself;
}
// Find all non-hit players the beam passed close by
if(deathtype == WEP_MINSTANEX || deathtype == WEP_NEX)
{
- FOR_EACH_REALCLIENT(msg_entity) if(msg_entity != self) if(!msg_entity.railgunhit) if not(msg_entity.classname == "spectator" && msg_entity.enemy == self) // we use realclient, so spectators can hear the whoosh too
+ FOR_EACH_REALCLIENT(msg_entity) if(msg_entity != self) if(!msg_entity.railgunhit) if not(IS_SPEC(msg_entity) && msg_entity.enemy == self) // we use realclient, so spectators can hear the whoosh too
{
// nearest point on the beam
beampos = start + dir * bound(0, (msg_entity.origin - start) * dir, length);
.float dmg_force;
.float dmg_radius;
.float dmg_total;
+ //.float last_yoda;
void W_BallisticBullet_Hit (void)
{
float f, q, g;
g = accuracy_isgooddamage(self.realowner, other);
Damage(other, self, self.realowner, self.dmg * f, self.projectiledeathtype, self.origin, self.dmg_force * normalize(self.velocity) * f);
- if(yoda)
- AnnounceTo(self.realowner, "awesome");
+ /*if(yoda && (time > (self.last_yoda + 5)))
+ {
+ Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA);
+ self.last_yoda = time;
+ }*/
// calculate hits for ballistic weapons
if(g)
lag = ANTILAG_LATENCY(self);
if(lag < 0.001)
lag = 0;
- if(clienttype(self) != CLIENTTYPE_REAL)
+ if not(IS_REAL_CLIENT(self))
lag = 0;
if(autocvar_g_antilag == 0 || self.cvar_cl_noantilag)
lag = 0; // only do hitscan, but no antilag
self.takedamage = DAMAGE_NO;
self.event_damage = func_null;
- if((attacker.flags & FL_CLIENT) && !autocvar_g_projectiles_keep_owner)
+ if(IS_CLIENT(attacker) && !autocvar_g_projectiles_keep_owner)
{
self.owner = attacker;
self.realowner = attacker;
void W_Plasma_Explode (void)
{
if(other.takedamage == DAMAGE_AIM)
- if(other.classname == "player")
+ if(IS_PLAYER(other))
if(IsDifferentTeam(self.realowner, other))
if(other.deadflag == DEAD_NO)
if(IsFlying(other))
- AnnounceTo(self.realowner, "electrobitch");
+ Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_ELECTROBITCH);
self.event_damage = func_null;
self.takedamage = DAMAGE_NO;
{
W_Reload(min(autocvar_g_balance_electro_primary_ammo, autocvar_g_balance_electro_secondary_ammo), autocvar_g_balance_electro_reload_ammo, autocvar_g_balance_electro_reload_time, "weapons/reload.wav");
}
+ else if (req == WR_SUICIDEMESSAGE)
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_ELECTRO_SUICIDE_ORBS;
+ else
+ return WEAPON_ELECTRO_SUICIDE_BOLT;
+ }
+ else if (req == WR_KILLMESSAGE)
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ {
+ return WEAPON_ELECTRO_MURDER_ORBS;
+ }
+ else
+ {
+ if(w_deathtype & HITTYPE_BOUNCE)
+ return WEAPON_ELECTRO_MURDER_COMBO;
+ else
+ return WEAPON_ELECTRO_MURDER_BOLT;
+ }
+ }
return TRUE;
}
#endif
precache_sound("weapons/electro_impact.wav");
precache_sound("weapons/electro_impact_combo.wav");
}
- else if (req == WR_SUICIDEMESSAGE)
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- w_deathtypestring = _("%s could not remember where they put their electro plasma");
- else
- w_deathtypestring = _("%s played with electro plasma");
- }
- else if (req == WR_KILLMESSAGE)
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- {
- if(w_deathtype & HITTYPE_SPLASH) // unchecked: BOUNCE
- w_deathtypestring = _("%s just noticed %s's electro plasma");
- else // unchecked: BOUNCE
- w_deathtypestring = _("%s got in touch with %s's electro plasma");
- }
- else
- {
- if(w_deathtype & HITTYPE_BOUNCE) // combo
- w_deathtypestring = _("%s felt the electrifying air of %s's electro combo");
- else if(w_deathtype & HITTYPE_SPLASH)
- w_deathtypestring = _("%s got too close to %s's blue electro bolt");
- else
- w_deathtypestring = _("%s was blasted by %s's blue electro bolt");
- }
- }
return TRUE;
}
#endif
// 2. bfg effect
// NOTE: this cannot be made warpzone aware by design. So, better intentionally ignore warpzones here.
for(e = findradius(self.origin, autocvar_g_balance_fireball_primary_bfgradius); e; e = e.chain)
- if(e != self.realowner) if(e.takedamage == DAMAGE_AIM) if(e.classname != "player" || !self.realowner || IsDifferentTeam(e, self))
+ if(e != self.realowner) if(e.takedamage == DAMAGE_AIM) if(!IS_PLAYER(e) || !self.realowner || IsDifferentTeam(e, self))
{
// can we see fireball?
traceline(e.origin + e.view_ofs, self.origin, MOVE_NORMAL, e);
RandomSelection_Init();
for(e = WarpZone_FindRadius(self.origin, dist, TRUE); e; e = e.chain)
- if(e != self.realowner) if(e.takedamage == DAMAGE_AIM) if(e.classname != "player" || !self.realowner || IsDifferentTeam(e, self))
+ if(e != self.realowner) if(e.takedamage == DAMAGE_AIM) if(!IS_PLAYER(e) || !self.realowner || IsDifferentTeam(e, self))
{
p = e.origin;
p_x += e.mins_x + random() * (e.maxs_x - e.mins_x);
{
self.fireball_primarytime = time;
}
+ else if (req == WR_SUICIDEMESSAGE)
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_FIREBALL_SUICIDE_FIREMINE;
+ else
+ return WEAPON_FIREBALL_SUICIDE_BLAST;
+ }
+ else if (req == WR_KILLMESSAGE)
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ {
+ return WEAPON_FIREBALL_MURDER_FIREMINE;
+ }
+ else
+ {
+ return WEAPON_FIREBALL_MURDER_BLAST;
+ }
+ }
return TRUE;
}
#endif
{
precache_sound("weapons/fireball_impact2.wav");
}
- else if (req == WR_SUICIDEMESSAGE)
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- w_deathtypestring = _("%s forgot about some firemine");
- else
- w_deathtypestring = _("%s should have used a smaller gun");
- }
- else if (req == WR_KILLMESSAGE)
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- {
- w_deathtypestring = _("%s fatefully ignored %s's firemine");
- }
- else
- {
- if(w_deathtype & HITTYPE_BOUNCE)
- {
- if(w_deathtype & HITTYPE_SPLASH) // BFG effect
- w_deathtypestring = _("%s could not hide from %s's fireball");
- else // laser
- w_deathtypestring = _("%s saw the pretty lights of %s's fireball");
- }
- else if(w_deathtype & HITTYPE_SPLASH)
- w_deathtypestring = _("%s got too close to %s's fireball");
- else
- w_deathtypestring = _("%s tasted %s's fireball");
- }
- }
+
return TRUE;
}
#endif
void W_Grenade_Explode (void)
{
if(other.takedamage == DAMAGE_AIM)
- if(other.classname == "player")
+ if(IS_PLAYER(other))
if(IsDifferentTeam(self.realowner, other))
if(other.deadflag == DEAD_NO)
if(IsFlying(other))
- AnnounceTo(self.realowner, "airshot");
+ Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
self.event_damage = func_null;
self.takedamage = DAMAGE_NO;
void W_Grenade_Explode2 (void)
{
if(other.takedamage == DAMAGE_AIM)
- if(other.classname == "player")
+ if(IS_PLAYER(other))
if(IsDifferentTeam(self.realowner, other))
if(other.deadflag == DEAD_NO)
if(IsFlying(other))
- AnnounceTo(self.realowner, "airshot");
+ Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
self.event_damage = func_null;
self.takedamage = DAMAGE_NO;
{
W_Reload(min(autocvar_g_balance_grenadelauncher_primary_ammo, autocvar_g_balance_grenadelauncher_secondary_ammo), autocvar_g_balance_grenadelauncher_reload_ammo, autocvar_g_balance_grenadelauncher_reload_time, "weapons/reload.wav");
}
+ else if (req == WR_SUICIDEMESSAGE)
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_MORTAR_SUICIDE_BOUNCE;
+ else
+ return WEAPON_MORTAR_SUICIDE_EXPLODE;
+ }
+ else if (req == WR_KILLMESSAGE)
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_MORTAR_MURDER_BOUNCE;
+ else
+ return WEAPON_MORTAR_MURDER_EXPLODE;
+ }
return TRUE;
}
#endif
{
precache_sound("weapons/grenade_impact.wav");
}
- else if (req == WR_SUICIDEMESSAGE)
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- w_deathtypestring = _("%s didn't see their own grenade");
- else
- w_deathtypestring = _("%s blew themself up with their grenadelauncher");
- }
- else if (req == WR_KILLMESSAGE)
- {
- if(w_deathtype & HITTYPE_SPLASH)
- if(w_deathtype & HITTYPE_BOUNCE) // (must be secondary then)
- w_deathtypestring = _("%s didn't see %s's grenade");
- else // unchecked: SECONDARY
- w_deathtypestring = _("%s almost dodged %s's grenade");
- else // unchecked: SECONDARY, BOUNCE
- w_deathtypestring = _("%s ate %s's grenade");
- }
return TRUE;
}
#endif
void W_Mine_Think (void);
.float minelayer_detonate, mine_explodeanyway;
.float mine_time;
+ .vector mine_orientation;
void spawnfunc_weapon_minelayer (void)
{
setmodel(newmine, "models/mine.md3");
newmine.angles = vectoangles(-trace_plane_normal); // face against the surface
- newmine.oldvelocity = self.velocity;
+ newmine.mine_orientation = -trace_plane_normal;
newmine.takedamage = self.takedamage;
newmine.damageforcescale = self.damageforcescale;
void W_Mine_Explode ()
{
if(other.takedamage == DAMAGE_AIM)
- if(other.classname == "player")
+ if(IS_PLAYER(other))
if(IsDifferentTeam(self.realowner, other))
if(other.deadflag == DEAD_NO)
if(IsFlying(other))
- AnnounceTo(self.realowner, "airshot");
+ Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
self.event_damage = func_null;
self.takedamage = DAMAGE_NO;
self.takedamage = DAMAGE_NO;
if(self.movetype == MOVETYPE_NONE || self.movetype == MOVETYPE_FOLLOW)
- self.velocity = self.oldvelocity;
+ self.velocity = self.mine_orientation; // particle fx and decals need .velocity
RadiusDamage (self, self.realowner, autocvar_g_balance_minelayer_remote_damage, autocvar_g_balance_minelayer_remote_edgedamage, autocvar_g_balance_minelayer_remote_radius, world, autocvar_g_balance_minelayer_remote_force, self.projectiledeathtype | HITTYPE_BOUNCE, world);
entity mine;
for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.realowner == e)
minecount += 1;
-
+
return minecount;
}
// a player's mines shall explode if he disconnects or dies
// TODO: Do this on team change too -- Samual: But isn't a player killed when they switch teams?
- if(self.realowner.classname != "player" || self.realowner.deadflag != DEAD_NO)
+ if(!IS_PLAYER(self.realowner) || self.realowner.deadflag != DEAD_NO)
{
other = world;
self.projectiledeathtype |= HITTYPE_BOUNCE;
head = findradius(self.origin, autocvar_g_balance_minelayer_proximityradius);
while(head)
{
- if(head.classname == "player" && head.deadflag == DEAD_NO)
+ if(IS_PLAYER(head) && head.deadflag == DEAD_NO)
if(head != self.realowner && IsDifferentTeam(head, self.realowner)) // don't trigger for team mates
if(!self.mine_time)
{
if(self.movetype == MOVETYPE_NONE || self.movetype == MOVETYPE_FOLLOW)
return; // we're already a stuck mine, why do we get called? TODO does this even happen?
- PROJECTILE_TOUCH;
+ if(WarpZone_Projectile_Touch())
+ {
+ if(wasfreed(self))
+ self.realowner.minelayer_mines -= 1;
+ return;
+ }
- if(other && other.classname == "player" && other.deadflag == DEAD_NO)
+ if(other && IS_PLAYER(other) && other.deadflag == DEAD_NO)
{
// hit a player
// don't stick
// scan how many mines we placed, and return if we reached our limit
if(autocvar_g_balance_minelayer_limit)
{
-
- if(W_Mine_Count(self) >= autocvar_g_balance_minelayer_limit)
+ if(self.minelayer_mines >= autocvar_g_balance_minelayer_limit)
{
// the refire delay keeps this message from being spammed
sprint(self, strcat("minelayer: You cannot place more than ^2", ftos(autocvar_g_balance_minelayer_limit), " ^7mines at a time\n") );
if (req == WR_AIM)
{
// aim and decide to fire if appropriate
- self.BUTTON_ATCK = bot_aim(autocvar_g_balance_minelayer_speed, 0, autocvar_g_balance_minelayer_lifetime, FALSE);
+ if(self.minelayer_mines >= autocvar_g_balance_minelayer_limit)
+ self.BUTTON_ATCK = FALSE;
+ else
+ self.BUTTON_ATCK = bot_aim(autocvar_g_balance_minelayer_speed, 0, autocvar_g_balance_minelayer_lifetime, FALSE);
if(skill >= 2) // skill 0 and 1 bots won't detonate mines!
{
// decide whether to detonate mines
//As the distance gets larger, a correct detonation gets near imposible
//Bots are assumed to use the mine spawnfunc_light to see if the mine gets near a player
if(v_forward * normalize(mine.origin - self.enemy.origin)< 0.1)
- if(self.enemy.classname == "player")
+ if(IS_PLAYER(self.enemy))
if(desirabledamage >= 0.1*coredamage)
if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1))
self.BUTTON_ATCK2 = TRUE;
else
return FALSE;
}
+ else if (req == WR_RESETPLAYER)
+ {
+ self.minelayer_mines = 0;
+ }
else if (req == WR_RELOAD)
{
W_Reload(autocvar_g_balance_minelayer_ammo, autocvar_g_balance_minelayer_reload_ammo, autocvar_g_balance_minelayer_reload_time, "weapons/reload.wav");
}
+ else if (req == WR_SUICIDEMESSAGE)
+ {
+ return WEAPON_MINELAYER_SUICIDE;
+ }
+ else if (req == WR_KILLMESSAGE)
+ {
+ return WEAPON_MINELAYER_MURDER;
+ }
return TRUE;
}
#endif
{
precache_sound("weapons/mine_exp.wav");
}
- else if (req == WR_SUICIDEMESSAGE)
- if(w_deathtype & HITTYPE_BOUNCE) // (remote detonation)
- w_deathtypestring = _("%s blew themself up with their minelayer");
- else
- w_deathtypestring = _("%s forgot about their mine");
- else if (req == WR_KILLMESSAGE)
- {
- if(w_deathtype & HITTYPE_BOUNCE) // (remote detonation)
- w_deathtypestring = _("%s got too close to %s's mine");
- else if(w_deathtype & HITTYPE_SPLASH)
- w_deathtypestring = _("%s almost dodged %s's mine");
- else
- w_deathtypestring = _("%s stepped on %s's mine");
- }
return TRUE;
}
#endif
W_Rocket_Unregister();
if(other.takedamage == DAMAGE_AIM)
- if(other.classname == "player")
+ if(IS_PLAYER(other))
if(IsDifferentTeam(self.realowner, other))
if(other.deadflag == DEAD_NO)
if(IsFlying(other))
- AnnounceTo(self.realowner, "airshot");
+ Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
self.event_damage = func_null;
self.takedamage = DAMAGE_NO;
//As the distance gets larger, a correct detonation gets near imposible
//Bots are assumed to use the rocket spawnfunc_light to see if the rocket gets near a player
if(v_forward * normalize(missile.origin - self.enemy.origin)< 0.1)
- if(self.enemy.classname == "player")
+ if(IS_PLAYER(self.enemy))
if(desirabledamage >= 0.1*coredamage)
if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1))
self.BUTTON_ATCK2 = TRUE;
{
W_Reload(autocvar_g_balance_rocketlauncher_ammo, autocvar_g_balance_rocketlauncher_reload_ammo, autocvar_g_balance_rocketlauncher_reload_time, "weapons/reload.wav");
}
+ else if (req == WR_SUICIDEMESSAGE)
+ {
+ return WEAPON_ROCKETLAUNCHER_SUICIDE;
+ }
+ else if (req == WR_KILLMESSAGE)
+ {
+ if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH))
+ return WEAPON_ROCKETLAUNCHER_MURDER_SPLASH;
+ else
+ return WEAPON_ROCKETLAUNCHER_MURDER_DIRECT;
+ }
return TRUE;
}
#endif
{
precache_sound("weapons/rocket_impact.wav");
}
- else if (req == WR_SUICIDEMESSAGE)
- w_deathtypestring = _("%s blew themself up with their rocketlauncher");
- else if (req == WR_KILLMESSAGE)
- {
- if(w_deathtype & HITTYPE_BOUNCE) // (remote detonation)
- w_deathtypestring = _("%s got too close to %s's rocket");
- else if(w_deathtype & HITTYPE_SPLASH)
- w_deathtypestring = _("%s almost dodged %s's rocket");
- else
- w_deathtypestring = _("%s ate %s's rocket");
- }
return TRUE;
}
#endif
//te_lightning2(world, targpos, self.realowner.origin + self.realowner.view_ofs + v_forward * 5 - v_up * 5);
//te_customflash(targpos, 40, 2, '1 1 1');
- is_player = (trace_ent.classname == "player" || trace_ent.classname == "body");
+ is_player = (IS_PLAYER(trace_ent) || trace_ent.classname == "body");
if((trace_fraction < 1) // if trace is good, apply the damage and remove self
&& (trace_ent.takedamage == DAMAGE_AIM)
{
W_Reload(autocvar_g_balance_shotgun_primary_ammo, autocvar_g_balance_shotgun_reload_ammo, autocvar_g_balance_shotgun_reload_time, "weapons/reload.wav");
}
+ else if (req == WR_SUICIDEMESSAGE)
+ {
+ return WEAPON_THINKING_WITH_PORTALS;
+ }
+ else if (req == WR_KILLMESSAGE)
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ return WEAPON_SHOTGUN_MURDER_SLAP;
+ else
+ return WEAPON_SHOTGUN_MURDER;
+ }
return TRUE;
}
#endif
precache_sound("weapons/ric2.wav");
precache_sound("weapons/ric3.wav");
}
- else if (req == WR_SUICIDEMESSAGE)
- w_deathtypestring = _("%s is now thinking with portals");
- else if (req == WR_KILLMESSAGE)
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- w_deathtypestring = _("%2$s slapped %1$s around a bit with a large shotgun");
- else
- w_deathtypestring = _("%s was gunned down with a shotgun by %s");
- }
return TRUE;
}
#endif