Merge branch 'master' into Mario/monsters
authorMario <mario.mario@y7mail.com>
Sun, 15 Sep 2013 07:14:33 +0000 (17:14 +1000)
committerMario <mario.mario@y7mail.com>
Sun, 15 Sep 2013 07:14:33 +0000 (17:14 +1000)
22 files changed:
1  2 
defaultXonotic.cfg
qcsrc/client/scoreboard.qc
qcsrc/common/command/generic.qc
qcsrc/common/monsters/monster/cerberus.qc
qcsrc/common/monsters/monster/mage.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/notifications.qh
qcsrc/server/accuracy.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_player.qc
qcsrc/server/command/cmd.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/gamemode_ctf.qc
qcsrc/server/mutators/gamemode_freezetag.qc
qcsrc/server/mutators/gamemode_onslaught.qc
qcsrc/server/mutators/mutator_minstagib.qc
qcsrc/server/sv_main.qc
qcsrc/server/tturrets/units/unit_fusionreactor.qc
qcsrc/server/w_electro.qc

Simple merge
Simple merge
Simple merge
index bbd353a,0000000..fabaa5a
mode 100644,000000..100644
--- /dev/null
@@@ -1,186 -1,0 +1,186 @@@
-       if(!IsDifferentTeam(head, self))
 +#ifdef REGISTER_MONSTER
 +REGISTER_MONSTER(
 +/* MON_##id   */ CERBERUS,
 +/* function   */ m_cerberus,
 +/* spawnflags */ MON_FLAG_MELEE,
 +/* mins,maxs  */ '-16 -16 -24', '16 16 12',
 +/* model      */ "dog.dpm",
 +/* netname    */ "cerberus",
 +/* fullname   */ _("Cerberus")
 +);
 +
 +#define CERBERUS_SETTINGS(monster) \
 +      MON_ADD_CVAR(monster, health) \
 +      MON_ADD_CVAR(monster, attack_bite_damage) \
 +      MON_ADD_CVAR(monster, attack_jump_damage) \
 +      MON_ADD_CVAR(monster, speed_stop) \
 +      MON_ADD_CVAR(monster, speed_run) \
 +      MON_ADD_CVAR(monster, speed_walk) 
 +
 +#ifdef SVQC
 +CERBERUS_SETTINGS(cerberus)
 +#endif // SVQC
 +#else
 +#ifdef SVQC
 +const float cerberus_anim_idle                = 0;
 +const float cerberus_anim_walk                = 1;
 +const float cerberus_anim_run         = 2;
 +const float cerberus_anim_attack      = 3;
 +const float cerberus_anim_die         = 4;
 +const float cerberus_anim_pain                = 5;
 +
 +.float cerberus_last_trace;
 +
 +void cerberus_findowner()
 +{
 +      if(time < self.cerberus_last_trace || self.monster_owner)
 +              return;
 +              
 +      entity head;
 +      
 +      FOR_EACH_MONSTER(head)
 +      if(head.health > 0)
 +      if(head.monsterid == MON_BRUISER)
 +      if(findentity(world, monster_owner, head) == world)
 +      if(vlen(head.origin - self.origin) < self.target_range)
-       if(IsDifferentTeam(self.monster_owner, self))
++      if(SAME_TEAM(head, self))
 +      if(head.enemy == world)
 +      {
 +              self.monster_owner = head;
 +              break;
 +      }
 +              
 +      self.cerberus_last_trace = time + 3;
 +}
 +
 +void cerberus_checkowner()
 +{
 +      if(time < self.cerberus_last_trace)
 +              return;
 +      if(IS_PLAYER(self.monster_owner))
 +              return; // don't check player masters
 +
 +      if(vlen(self.origin - self.monster_owner.origin) > self.target_range)
 +              self.monster_owner = world;
 +      if(self.monster_owner.health < 1)
 +              self.monster_owner = world;
++      if(DIFF_TEAM(self.monster_owner, self))
 +              self.monster_owner = world;
 +              
 +      self.cerberus_last_trace = time + 3;
 +}
 +
 +void cerberus_touch_jump()
 +{
 +      if (other.takedamage)
 +      if (vlen(self.velocity) > 300)
 +      {
 +              Damage(self.enemy, self, self, MON_CVAR(cerberus, attack_jump_damage) * monster_skill, DEATH_MONSTER_CERBERUS_JUMP, self.enemy.origin, normalize(self.enemy.origin - self.origin));
 +              self.touch = MonsterTouch;
 +      }
 +
 +      if(trace_dphitcontents)
 +              self.touch = MonsterTouch;
 +}
 +
 +float cerberus_attack(float attack_type)
 +{
 +      switch(attack_type)
 +      {
 +              case MONSTER_ATTACK_MELEE:
 +              {
 +                      return monster_melee(self.enemy, MON_CVAR(cerberus, attack_bite_damage), cerberus_anim_attack, self.attack_range, 0.7, DEATH_MONSTER_CERBERUS_BITE, TRUE);
 +              }
 +              case MONSTER_ATTACK_RANGED:
 +              {
 +                      makevectors(self.angles);
 +                      return monster_leap(cerberus_anim_attack, cerberus_touch_jump, v_forward * 300 + '0 0 200', 0.8);
 +              }
 +      }
 +      
 +      return FALSE;
 +}
 +
 +void spawnfunc_monster_cerberus()
 +{
 +      self.classname = "monster_cerberus";
 +      
 +      self.monster_spawnfunc = spawnfunc_monster_cerberus;
 +      
 +      if(Monster_CheckAppearFlags(self))
 +              return;
 +      
 +      if not(monster_initialize(MON_CERBERUS, FALSE)) { remove(self); return; }
 +}
 +
 +// compatibility with old spawns
 +void spawnfunc_monster_dog() { spawnfunc_monster_cerberus(); }
 +
 +float m_cerberus(float req)
 +{
 +      switch(req)
 +      {
 +              case MR_THINK:
 +              {
 +                      if(self.monster_owner)
 +                              cerberus_checkowner();
 +                      else
 +                              cerberus_findowner();
 +                      monster_move(MON_CVAR(cerberus, speed_run), MON_CVAR(cerberus, speed_walk), MON_CVAR(cerberus, speed_stop), cerberus_anim_run, cerberus_anim_walk, cerberus_anim_idle);
 +                      return TRUE;
 +              }
 +              case MR_DEATH:
 +              {
 +                      if(self.monster_owner.flags & FL_MONSTER)
 +                              self.monster_owner = world;
 +                      monsters_setframe(cerberus_anim_die);
 +                      return TRUE;
 +              }
 +              case MR_SETUP:
 +              {
 +                      if not(self.health) self.health = MON_CVAR(cerberus, health);
 +                      
 +                      self.monster_loot = spawnfunc_item_health_small;
 +                      self.monster_attackfunc = cerberus_attack;
 +                      monsters_setframe(cerberus_anim_idle);
 +                      
 +                      return TRUE;
 +              }
 +              case MR_INIT:
 +              {
 +                      // nothing
 +                      return TRUE;
 +              }
 +              case MR_CONFIG:
 +              {
 +                      MON_CONFIG_SETTINGS(CERBERUS_SETTINGS(cerberus))
 +                      return TRUE;
 +              }
 +      }
 +      
 +      return TRUE;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float m_cerberus(float req)
 +{
 +      switch(req)
 +      {
 +              case MR_DEATH:
 +              {
 +                      // nothing
 +                      return TRUE;
 +              }
 +              case MR_INIT:
 +              {
 +                      precache_model ("models/monsters/dog.dpm");
 +                      return TRUE;
 +              }
 +      }
 +      
 +      return TRUE;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_MONSTER
index 9b527b7,0000000..fdba5c0
mode 100644,000000..100644
--- /dev/null
@@@ -1,488 -1,0 +1,488 @@@
-       if(IsDifferentTeam(e, self))
 +#ifdef REGISTER_MONSTER
 +REGISTER_MONSTER(
 +/* MON_##id   */ MAGE,
 +/* function   */ m_mage,
 +/* spawnflags */ MON_FLAG_MELEE | MON_FLAG_RANGED,
 +/* mins,maxs  */ '-36 -36 -24', '36 36 50',
 +/* model      */ "mage.dpm",
 +/* netname    */ "mage",
 +/* fullname   */ _("Mage")
 +);
 +
 +#define MAGE_SETTINGS(monster) \
 +      MON_ADD_CVAR(monster, health) \
 +      MON_ADD_CVAR(monster, attack_spike_damage) \
 +      MON_ADD_CVAR(monster, attack_spike_radius) \
 +      MON_ADD_CVAR(monster, attack_spike_delay) \
 +      MON_ADD_CVAR(monster, attack_spike_accel) \
 +      MON_ADD_CVAR(monster, attack_spike_decel) \
 +      MON_ADD_CVAR(monster, attack_spike_turnrate) \
 +      MON_ADD_CVAR(monster, attack_spike_speed_max) \
 +      MON_ADD_CVAR(monster, attack_spike_smart) \
 +      MON_ADD_CVAR(monster, attack_spike_smart_trace_min) \
 +      MON_ADD_CVAR(monster, attack_spike_smart_trace_max) \
 +      MON_ADD_CVAR(monster, attack_spike_smart_mindist) \
 +      MON_ADD_CVAR(monster, attack_melee_damage) \
 +      MON_ADD_CVAR(monster, attack_melee_delay) \
 +      MON_ADD_CVAR(monster, attack_grenade_damage) \
 +      MON_ADD_CVAR(monster, attack_grenade_edgedamage) \
 +      MON_ADD_CVAR(monster, attack_grenade_force) \
 +      MON_ADD_CVAR(monster, attack_grenade_radius) \
 +      MON_ADD_CVAR(monster, attack_grenade_lifetime) \
 +      MON_ADD_CVAR(monster, attack_grenade_chance) \
 +      MON_ADD_CVAR(monster, attack_grenade_speed) \
 +      MON_ADD_CVAR(monster, attack_grenade_speed_up) \
 +      MON_ADD_CVAR(monster, heal_self) \
 +      MON_ADD_CVAR(monster, heal_allies) \
 +      MON_ADD_CVAR(monster, heal_minhealth) \
 +      MON_ADD_CVAR(monster, heal_range) \
 +      MON_ADD_CVAR(monster, heal_delay) \
 +      MON_ADD_CVAR(monster, shield_time) \
 +      MON_ADD_CVAR(monster, shield_delay) \
 +      MON_ADD_CVAR(monster, shield_blockpercent) \
 +      MON_ADD_CVAR(monster, speed_stop) \
 +      MON_ADD_CVAR(monster, speed_run) \
 +      MON_ADD_CVAR(monster, speed_walk) 
 +
 +#ifdef SVQC
 +MAGE_SETTINGS(mage)
 +#endif // SVQC
 +#else
 +#ifdef SVQC
 +const float mage_anim_idle            = 0;
 +const float mage_anim_walk            = 1;
 +const float mage_anim_attack  = 2;
 +const float mage_anim_pain            = 3;
 +const float mage_anim_death   = 4;
 +const float mage_anim_run             = 5;
 +
 +void() mage_heal;
 +void() mage_shield;
 +
 +float friend_needshelp(entity e)
 +{
 +      if(e == world)
 +              return FALSE;
 +      if(e.health <= 0)
 +              return FALSE;
 +      if(vlen(e.origin - self.origin) > MON_CVAR(mage, heal_range))
 +              return FALSE;
++      if(DIFF_TEAM(e, self))
 +              return FALSE;
 +      if(e.frozen)
 +              return FALSE;
 +      if(!IS_PLAYER(e))
 +              return (e.health < e.max_health);
 +      if(e.items & IT_INVINCIBLE)
 +              return FALSE;
 +
 +      switch(self.skin)
 +      {
 +              case 0: return (e.health < autocvar_g_balance_health_regenstable);
 +              case 1: return ((e.ammo_cells && e.ammo_cells < g_pickup_cells_max) || (e.ammo_rockets && e.ammo_rockets < g_pickup_rockets_max) || (e.ammo_nails && e.ammo_nails < g_pickup_nails_max) || (e.ammo_shells && e.ammo_shells < g_pickup_shells_max));
 +              case 2: return (e.armorvalue < autocvar_g_balance_armor_regenstable);
 +              case 3: return (e.health > 0);
 +      }
 +      
 +      return FALSE;
 +}
 +
 +void mageattack_melee()
 +{
 +      monster_melee(self.enemy, MON_CVAR(mage, attack_melee_damage), mage_anim_attack, self.attack_range, MON_CVAR(mage, attack_melee_delay) - 0.2, DEATH_MONSTER_MAGE, TRUE);
 +}
 +
 +void mage_grenade_explode()
 +{
 +      pointparticles(particleeffectnum("explosion_small"), self.origin, '0 0 0', 1);
 +      
 +      sound(self, CH_SHOTS, "weapons/grenade_impact.wav", VOL_BASE, ATTEN_NORM);
 +      RadiusDamage (self, self.realowner, MON_CVAR(mage, attack_grenade_damage), MON_CVAR(mage, attack_grenade_edgedamage), MON_CVAR(mage, attack_grenade_radius), world, MON_CVAR(mage, attack_grenade_force), DEATH_MONSTER_MAGE, other);
 +      remove(self);
 +}
 +
 +void mage_grenade_touch()
 +{
 +      if(IS_PLAYER(other))
 +      {
 +              PROJECTILE_TOUCH;
 +              mage_grenade_explode();
 +              return;
 +      }
 +}
 +
 +void mage_throw_itemgrenade()
 +{
 +      makevectors(self.angles);
 +      
 +      entity gren = spawn ();
 +      gren.owner = gren.realowner = self;
 +      gren.classname = "grenade";
 +      gren.bot_dodge = FALSE;
 +      gren.movetype = MOVETYPE_BOUNCE;
 +      gren.solid = SOLID_TRIGGER;
 +      gren.projectiledeathtype = DEATH_MONSTER_MAGE;
 +      setorigin(gren, CENTER_OR_VIEWOFS(self));
 +      setsize(gren, '-64 -64 -64', '64 64 64');
 +
 +      gren.nextthink = time + MON_CVAR(mage, attack_grenade_lifetime);
 +      gren.think = mage_grenade_explode;
 +      gren.use = mage_grenade_explode;
 +      gren.touch = mage_grenade_touch;
 +
 +      gren.missile_flags = MIF_SPLASH | MIF_ARC;
 +      W_SetupProjectileVelocityEx(gren, v_forward, v_up, MON_CVAR(mage, attack_grenade_speed), MON_CVAR(mage, attack_grenade_speed_up), 0, 0, FALSE);
 +      
 +      gren.flags = FL_PROJECTILE;
 +      
 +      setmodel(gren, "models/items/g_h50.md3");
 +      
 +      self.attack_finished_single = time + 1.5;
 +}
 +
 +void mage_spike_explode()
 +{
 +      self.event_damage = func_null;
 +      
 +      sound(self, CH_SHOTS, "weapons/grenade_impact.wav", VOL_BASE, ATTEN_NORM);
 +      
 +      pointparticles(particleeffectnum("explosion_small"), self.origin, '0 0 0', 1);
 +      RadiusDamage (self, self.realowner, MON_CVAR(mage, attack_spike_damage), MON_CVAR(mage, attack_spike_damage) * 0.5, MON_CVAR(mage, attack_spike_radius), world, 0, DEATH_MONSTER_MAGE, other);
 +
 +      remove (self);
 +}
 +
 +void mage_spike_touch()
 +{
 +      PROJECTILE_TOUCH;
 +
 +      mage_spike_explode();
 +}
 +
 +// copied from W_Seeker_Think
 +void mage_spike_think()
 +{
 +      entity e;
 +      vector desireddir, olddir, newdir, eorg;
 +      float turnrate;
 +      float dist;
 +      float spd;
 +
 +      if (time > self.ltime || self.enemy.health <= 0 || self.owner.health <= 0)
 +      {
 +              self.projectiledeathtype |= HITTYPE_SPLASH;
 +              mage_spike_explode();
 +      }
 +
 +      spd = vlen(self.velocity);
 +      spd = bound(
 +              spd - MON_CVAR(mage, attack_spike_decel) * frametime,
 +              MON_CVAR(mage, attack_spike_speed_max),
 +              spd + MON_CVAR(mage, attack_spike_accel) * frametime
 +      );
 +
 +      if (self.enemy != world)
 +              if (self.enemy.takedamage != DAMAGE_AIM || self.enemy.deadflag != DEAD_NO)
 +                      self.enemy = world;
 +
 +      if (self.enemy != world)
 +      {
 +              e               = self.enemy;
 +              eorg            = 0.5 * (e.absmin + e.absmax);
 +              turnrate        = MON_CVAR(mage, attack_spike_turnrate); // how fast to turn
 +              desireddir      = normalize(eorg - self.origin);
 +              olddir          = normalize(self.velocity); // get my current direction
 +              dist            = vlen(eorg - self.origin);
 +
 +              // Do evasive maneuvers for world objects? ( this should be a cpu hog. :P )
 +              if (MON_CVAR(mage, attack_spike_smart) && (dist > MON_CVAR(mage, attack_spike_smart_mindist)))
 +              {
 +                      // Is it a better idea (shorter distance) to trace to the target itself?
 +                      if ( vlen(self.origin + olddir * self.wait) < dist)
 +                              traceline(self.origin, self.origin + olddir * self.wait, FALSE, self);
 +                      else
 +                              traceline(self.origin, eorg, FALSE, self);
 +
 +                      // Setup adaptive tracelength
 +                      self.wait = bound(MON_CVAR(mage, attack_spike_smart_trace_min), vlen(self.origin - trace_endpos), self.wait = MON_CVAR(mage, attack_spike_smart_trace_max));
 +
 +                      // Calc how important it is that we turn and add this to the desierd (enemy) dir.
 +                      desireddir  = normalize(((trace_plane_normal * (1 - trace_fraction)) + (desireddir * trace_fraction)) * 0.5);
 +              }
 +              
 +              newdir = normalize(olddir + desireddir * turnrate); // take the average of the 2 directions; not the best method but simple & easy
 +              self.velocity = newdir * spd; // make me fly in the new direction at my flight speed
 +      }
 +      else
 +              dist = 0;
 +              
 +      ///////////////
 +
 +      //self.angles = vectoangles(self.velocity);                     // turn model in the new flight direction
 +      self.nextthink = time;// + 0.05; // csqc projectiles
 +      UpdateCSQCProjectile(self);
 +}
 +
 +void mage_spike()
 +{
 +      entity missile;
 +      vector dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
 +
 +      makevectors(self.angles);
 +
 +      missile = spawn ();
 +      missile.owner = missile.realowner = self;
 +      missile.think = mage_spike_think;
 +      missile.ltime = time + 7;
 +      missile.nextthink = time;
 +      missile.solid = SOLID_BBOX;
 +      missile.movetype = MOVETYPE_FLYMISSILE;
 +      missile.flags = FL_PROJECTILE;
 +      setorigin(missile, self.origin + v_forward * 14 + '0 0 30' + v_right * -14);
 +      setsize (missile, '0 0 0', '0 0 0');    
 +      missile.velocity = dir * 400;
 +      missile.avelocity = '300 300 300';
 +      missile.enemy = self.enemy;
 +      missile.touch = mage_spike_touch;
 +      
 +      CSQCProjectile(missile, TRUE, PROJECTILE_MAGE_SPIKE, TRUE);
 +}
 +
 +void mage_heal()
 +{
 +      entity head;
 +      float washealed = FALSE;
 +      
 +      for(head = world; (head = findfloat(head, monster_attack, TRUE)); ) if(friend_needshelp(head))
 +      {
 +              washealed = TRUE;
 +              string fx = "";
 +              if(IS_PLAYER(head))
 +              {
 +                      switch(self.skin)
 +                      {
 +                              case 0:
 +                                      if(head.health < autocvar_g_balance_health_regenstable) head.health = bound(0, head.health + MON_CVAR(mage, heal_allies), autocvar_g_balance_health_regenstable);
 +                                      fx = "healing_fx";
 +                                      break;
 +                              case 1:
 +                                      if(head.ammo_cells) head.ammo_cells = bound(head.ammo_cells, head.ammo_cells + 1, g_pickup_cells_max);
 +                                      if(head.ammo_rockets) head.ammo_rockets = bound(head.ammo_rockets, head.ammo_rockets + 1, g_pickup_rockets_max);
 +                                      if(head.ammo_shells) head.ammo_shells = bound(head.ammo_shells, head.ammo_shells + 2, g_pickup_shells_max);
 +                                      if(head.ammo_nails) head.ammo_nails = bound(head.ammo_nails, head.ammo_nails + 5, g_pickup_nails_max);
 +                                      fx = "ammoregen_fx";
 +                                      break;
 +                              case 2:
 +                                      if(head.armorvalue < autocvar_g_balance_armor_regenstable)
 +                                      {
 +                                              head.armorvalue = bound(0, head.armorvalue + MON_CVAR(mage, heal_allies), autocvar_g_balance_armor_regenstable);
 +                                              fx = "armorrepair_fx";
 +                                      }
 +                                      break;
 +                              case 3:
 +                                      head.health = bound(0, head.health - ((head == self)  ? MON_CVAR(mage, heal_self) : MON_CVAR(mage, heal_allies)), autocvar_g_balance_health_regenstable);
 +                                      fx = "rage";
 +                                      break;
 +                      }
 +                      
 +                      pointparticles(particleeffectnum(fx), head.origin, '0 0 0', 1);
 +              }
 +              else
 +              {
 +                      pointparticles(particleeffectnum("healing_fx"), head.origin, '0 0 0', 1);
 +                      head.health = bound(0, head.health + MON_CVAR(mage, heal_allies), head.max_health);
 +                      head.SendFlags |= MSF_STATUS;
 +              }
 +      }
 +      
 +      if(washealed)
 +      {
 +              monsters_setframe(mage_anim_attack);
 +              self.attack_finished_single = time + MON_CVAR(mage, heal_delay);
 +      }
 +}
 +
 +void mage_shield_think()
 +{
 +      self.nextthink = time;
 +
 +      if(time >= self.ltime || self.owner.health <= 0)
 +      {
 +              self.owner.armorvalue = 0;
 +              self.owner.m_armor_blockpercent = autocvar_g_monsters_armor_blockpercent;
 +              remove(self);
 +              return;
 +      }
 +}
 +
 +void mage_shield()
 +{
 +      if(self.weaponentity)
 +              return; // already have a shield
 +              
 +      entity shield = spawn();
 +
 +      shield.owner = self;
 +      shield.team = self.team;
 +      shield.ltime = time + MON_CVAR(mage, shield_time);
 +      shield.classname = "shield";
 +      shield.effects = EF_ADDITIVE;
 +      shield.movetype = MOVETYPE_NOCLIP;
 +      shield.solid = SOLID_TRIGGER;
 +      shield.avelocity = '7 0 11';
 +      shield.scale = self.scale * 0.6;
 +      shield.think = mage_shield_think;
 +      shield.nextthink = time;
 +      
 +      setattachment(shield, self, "");
 +      setmodel(shield, "models/ctf/shield.md3");
 +      setsize(shield, shield.scale * shield.mins, shield.scale * shield.maxs);
 +      
 +      self.lastshielded = time + MON_CVAR(mage, shield_delay);
 +      
 +      monsters_setframe(mage_anim_attack);
 +      self.attack_finished_single = time + 1;
 +      
 +      self.m_armor_blockpercent = MON_CVAR(mage, shield_blockpercent);
 +      self.armorvalue = self.health;
 +}
 +
 +float mage_attack(float attack_type)
 +{
 +      switch(attack_type)
 +      {
 +              case MONSTER_ATTACK_MELEE:
 +              {
 +                      monsters_setframe(mage_anim_attack);
 +                      self.attack_finished_single = time + MON_CVAR(mage, attack_melee_delay);
 +                      defer(0.2, mageattack_melee);
 +                      
 +                      return TRUE;
 +              }
 +              case MONSTER_ATTACK_RANGED:
 +              {
 +                      if(random() < MON_CVAR(mage, attack_grenade_chance) / 100)
 +                      {
 +                              mage_throw_itemgrenade();
 +                              return TRUE;
 +                      }
 +      
 +                      monsters_setframe(mage_anim_attack);
 +                      self.attack_finished_single = time + MON_CVAR(mage, attack_spike_delay);
 +                      defer(0.2, mage_spike);
 +                      
 +                      return TRUE;
 +              }
 +      }
 +      
 +      return FALSE;
 +}
 +
 +void spawnfunc_monster_mage()
 +{
 +      self.classname = "monster_mage";
 +      
 +      self.monster_spawnfunc = spawnfunc_monster_mage;
 +      
 +      if(Monster_CheckAppearFlags(self))
 +              return;
 +      
 +      if not(monster_initialize(MON_MAGE, FALSE)) { remove(self); return; }
 +}
 +
 +// compatibility with old spawns
 +void spawnfunc_monster_shalrath() { spawnfunc_monster_mage(); }
 +
 +float m_mage(float req)
 +{
 +      switch(req)
 +      {
 +              case MR_THINK:
 +              {
 +                      entity head;
 +                      float need_help = FALSE;
 +                      
 +                      FOR_EACH_PLAYER(head)
 +                      if(friend_needshelp(head))
 +                      {
 +                              need_help = TRUE;
 +                              break; // found 1 player near us who is low on health
 +                      }
 +                      if(!need_help)
 +                      FOR_EACH_MONSTER(head)
 +                      if(head != self)
 +                      if(friend_needshelp(head))
 +                      {
 +                              need_help = TRUE;
 +                              break; // found 1 player near us who is low on health
 +                      }
 +                              
 +                      if(self.health < MON_CVAR(mage, heal_minhealth) || need_help)
 +                      if(time >= self.attack_finished_single)
 +                      if(random() < 0.5)
 +                              mage_heal();
 +                              
 +                      if(self.enemy)
 +                      if(self.health < self.max_health)
 +                      if(time >= self.lastshielded)
 +                      if(random() < 0.5)
 +                              mage_shield();
 +                      
 +                      monster_move(MON_CVAR(mage, speed_run), MON_CVAR(mage, speed_walk), MON_CVAR(mage, speed_stop), mage_anim_walk, mage_anim_run, mage_anim_idle);
 +                      return TRUE;
 +              }
 +              case MR_DEATH:
 +              {
 +                      monsters_setframe(mage_anim_death);
 +                      return TRUE;
 +              }
 +              case MR_SETUP:
 +              {
 +                      if not(self.health) self.health = MON_CVAR(mage, health);
 +                      
 +                      self.monster_loot = spawnfunc_item_health_large;
 +                      self.monster_attackfunc = mage_attack;
 +                      monsters_setframe(mage_anim_walk);
 +                      
 +                      return TRUE;
 +              }
 +              case MR_INIT:
 +              {
 +                      precache_model ("models/items/g_h50.md3");
 +                      precache_model ("models/ctf/shield.md3");
 +                      precache_sound ("weapons/grenade_impact.wav");
 +                      return TRUE;
 +              }
 +              case MR_CONFIG:
 +              {
 +                      MON_CONFIG_SETTINGS(MAGE_SETTINGS(mage))
 +                      return TRUE;
 +              }
 +      }
 +      
 +      return TRUE;
 +}
 +
 +#endif // SVQC
 +#ifdef CSQC
 +float m_mage(float req)
 +{
 +      switch(req)
 +      {
 +              case MR_DEATH:
 +              {
 +                      // nothing
 +                      return TRUE;
 +              }
 +              case MR_INIT:
 +              {
 +                      precache_model ("models/monsters/mage.dpm");
 +                      return TRUE;
 +              }
 +      }
 +      
 +      return TRUE;
 +}
 +
 +#endif // CSQC
 +#endif // REGISTER_MONSTER
index 3bb91e1,0000000..f6856ed
mode 100644,000000..100644
--- /dev/null
@@@ -1,1128 -1,0 +1,1128 @@@
-       if not(IsDifferentTeam(targ, ent))
 +// =========================
 +//  SVQC Monster Properties
 +// =========================
 +
 +
 +void monster_item_spawn()
 +{
 +      if(self.monster_loot)
 +              self.monster_loot();
 +
 +      self.gravity = 1;
 +      self.velocity = randomvec() * 175 + '0 0 325';
 +      self.classname = "droppedweapon"; // hax
 +
 +      SUB_SetFade(self, time + autocvar_g_monsters_drop_time, 1);
 +}
 +
 +void monster_dropitem()
 +{
 +      if(!self.candrop || !self.monster_loot)
 +              return;
 +
 +      vector org = self.origin + ((self.mins + self.maxs) * 0.5);
 +      entity e = spawn();
 +
 +      setorigin(e, org);
 +
 +      e.monster_loot = self.monster_loot;
 +
 +      other = e;
 +      MUTATOR_CALLHOOK(MonsterDropItem);
 +      e = other;
 +
 +      if(e)
 +      {
 +              e.think = monster_item_spawn;
 +              e.nextthink = time + 0.3;
 +      }
 +}
 +
 +void monsters_setframe(float _frame)
 +{
 +      if(self.frame == _frame)
 +              return;
 +
 +      self.anim_start_time = time;
 +      self.frame = _frame;
 +      self.SendFlags |= MSF_ANIM;
 +}
 +
 +float monster_isvalidtarget (entity targ, entity ent)
 +{
 +      if(!targ || !ent)
 +              return FALSE; // someone doesn't exist
 +
 +      if(targ == ent)
 +              return FALSE; // don't attack ourselves
 +
 +      traceline(ent.origin, targ.origin, MOVE_NORMAL, ent);
 +
 +      if(trace_ent != targ)
 +              return FALSE;
 +
 +      if(targ.vehicle_flags & VHF_ISVEHICLE)
 +      if not((get_monsterinfo(ent.monsterid)).spawnflags & MON_FLAG_RANGED)
 +              return FALSE; // melee attacks are useless against vehicles
 +
 +      if(time < game_starttime)
 +              return FALSE; // monsters do nothing before the match has started
 +
 +      if(vlen(targ.origin - ent.origin) >= ent.target_range)
 +              return FALSE; // enemy is too far away
 +
 +      if(targ.takedamage == DAMAGE_NO)
 +              return FALSE; // enemy can't be damaged
 +
 +      if(targ.items & IT_INVISIBILITY)
 +              return FALSE; // enemy is invisible
 +
 +      if(substring(targ.classname, 0, 10) == "onslaught_")
 +              return FALSE; // don't attack onslaught targets
 +
 +      if(IS_SPEC(targ) || IS_OBSERVER(targ))
 +              return FALSE; // enemy is a spectator
 +
 +      if not(targ.vehicle_flags & VHF_ISVEHICLE)
 +      if(targ.deadflag != DEAD_NO || ent.deadflag != DEAD_NO || targ.health <= 0 || ent.health <= 0)
 +              return FALSE; // enemy/self is dead
 +
 +      if(ent.monster_owner == targ)
 +              return FALSE; // don't attack our master
 +
 +      if(targ.monster_owner == ent)
 +              return FALSE; // don't attack our pet
 +
 +      if not(targ.vehicle_flags & VHF_ISVEHICLE)
 +      if(targ.flags & FL_NOTARGET)
 +              return FALSE; // enemy can't be targeted
 +
 +      if not(autocvar_g_monsters_typefrag)
 +      if(targ.BUTTON_CHAT)
 +              return FALSE; // no typefragging!
 +
-       if(IsDifferentTeam(self.monster_owner, self))
++      if(SAME_TEAM(targ, ent))
 +              return FALSE; // enemy is on our team
 +
 +      if(autocvar_g_monsters_target_infront || ent.spawnflags & MONSTERFLAG_INFRONT)
 +      if(ent.enemy != targ)
 +      {
 +              float dot;
 +
 +              makevectors (ent.angles);
 +              dot = normalize (targ.origin - ent.origin) * v_forward;
 +
 +              if(dot <= 0.3)
 +                      return FALSE;
 +      }
 +
 +      return TRUE;
 +}
 +
 +entity FindTarget (entity ent)
 +{
 +      if(MUTATOR_CALLHOOK(MonsterFindTarget)) { return ent.enemy; } // Handled by a mutator
 +
 +      entity head, closest_target = world;
 +      head = findradius(ent.origin, ent.target_range);
 +
 +      while(head) // find the closest acceptable target to pass to
 +      {
 +              if(head.monster_attack)
 +              if(monster_isvalidtarget(head, ent))
 +              {
 +                      // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc)
 +                      vector head_center = CENTER_OR_VIEWOFS(head);
 +                      vector ent_center = CENTER_OR_VIEWOFS(ent);
 +
 +                      //if(ctf_CheckPassDirection(head_center, ent_center, ent.v_angle, head.WarpZone_findradius_nearest))
 +                      if(closest_target)
 +                      {
 +                              vector closest_target_center = CENTER_OR_VIEWOFS(closest_target);
 +                              if(vlen(ent_center - head_center) < vlen(ent_center - closest_target_center))
 +                                      { closest_target = head; }
 +                      }
 +                      else { closest_target = head; }
 +              }
 +
 +              head = head.chain;
 +      }
 +
 +      return closest_target;
 +}
 +
 +void MonsterTouch ()
 +{
 +      if(other == world)
 +              return;
 +
 +      if(self.enemy != other)
 +      if not(other.flags & FL_MONSTER)
 +      if(monster_isvalidtarget(other, self))
 +              self.enemy = other;
 +}
 +
 +string get_monster_model_datafilename(string m, float sk, string fil)
 +{
 +      if(m)
 +              m = strcat(m, "_");
 +      else
 +              m = "models/monsters/*_";
 +      if(sk >= 0)
 +              m = strcat(m, ftos(sk));
 +      else
 +              m = strcat(m, "*");
 +      return strcat(m, ".", fil);
 +}
 +
 +void PrecacheMonsterSounds(string f)
 +{
 +      float fh;
 +      string s;
 +      fh = fopen(f, FILE_READ);
 +      if(fh < 0)
 +              return;
 +      while((s = fgets(fh)))
 +      {
 +              if(tokenize_console(s) != 3)
 +              {
 +                      dprint("Invalid sound info line: ", s, "\n");
 +                      continue;
 +              }
 +              PrecacheGlobalSound(strcat(argv(1), " ", argv(2)));
 +      }
 +      fclose(fh);
 +}
 +
 +void precache_monstersounds()
 +{
 +      string m = (get_monsterinfo(self.monsterid)).model;
 +      float globhandle, n, i;
 +      string f;
 +
 +      globhandle = search_begin(strcat(m, "_*.sounds"), TRUE, FALSE);
 +      if (globhandle < 0)
 +              return;
 +      n = search_getsize(globhandle);
 +      for (i = 0; i < n; ++i)
 +      {
 +              //print(search_getfilename(globhandle, i), "\n");
 +              f = search_getfilename(globhandle, i);
 +              PrecacheMonsterSounds(f);
 +      }
 +      search_end(globhandle);
 +}
 +
 +void ClearMonsterSounds()
 +{
 +#define _MSOUND(m) if(self.monstersound_##m) { strunzone(self.monstersound_##m); self.monstersound_##m = string_null; }
 +      ALLMONSTERSOUNDS
 +#undef _MSOUND
 +}
 +
 +.string GetMonsterSoundSampleField(string type)
 +{
 +      GetMonsterSoundSampleField_notFound = 0;
 +      switch(type)
 +      {
 +#define _MSOUND(m) case #m: return monstersound_##m;
 +              ALLMONSTERSOUNDS
 +#undef _MSOUND
 +      }
 +      GetMonsterSoundSampleField_notFound = 1;
 +      return string_null;
 +}
 +
 +float LoadMonsterSounds(string f, float first)
 +{
 +      float fh;
 +      string s;
 +      var .string field;
 +      fh = fopen(f, FILE_READ);
 +      if(fh < 0)
 +      {
 +              dprint("Monster sound file not found: ", f, "\n");
 +              return 0;
 +      }
 +      while((s = fgets(fh)))
 +      {
 +              if(tokenize_console(s) != 3)
 +                      continue;
 +              field = GetMonsterSoundSampleField(argv(0));
 +              if(GetMonsterSoundSampleField_notFound)
 +                      continue;
 +              if(self.field)
 +                      strunzone(self.field);
 +              self.field = strzone(strcat(argv(1), " ", argv(2)));
 +      }
 +      fclose(fh);
 +      return 1;
 +}
 +
 +.float skin_for_monstersound;
 +void UpdateMonsterSounds()
 +{
 +      entity mon = get_monsterinfo(self.monsterid);
 +
 +      if(self.skin == self.skin_for_monstersound)
 +              return;
 +      self.skin_for_monstersound = self.skin;
 +      ClearMonsterSounds();
 +      //LoadMonsterSounds("sound/monsters/default.sounds", 1);
 +      if(!autocvar_g_debug_defaultsounds)
 +      if(!LoadMonsterSounds(get_monster_model_datafilename(mon.model, self.skin, "sounds"), 0))
 +              LoadMonsterSounds(get_monster_model_datafilename(mon.model, 0, "sounds"), 0);
 +}
 +
 +void MonsterSound(.string samplefield, float sound_delay, float delaytoo, float chan)
 +{
 +      if(delaytoo && time < self.msound_delay)
 +              return; // too early
 +      GlobalSound(self.samplefield, chan, VOICETYPE_PLAYERSOUND);
 +
 +      self.msound_delay = time + sound_delay;
 +}
 +
 +void monster_makevectors(entity e)
 +{
 +      vector v;
 +
 +      v = CENTER_OR_VIEWOFS(e);
 +      self.v_angle = vectoangles(v - (self.origin + self.view_ofs));
 +      self.v_angle_x = -self.v_angle_x;
 +
 +      makevectors(self.v_angle);
 +}
 +
 +float monster_melee(entity targ, float damg, float anim, float er, float anim_finished, float deathtype, float dostop)
 +{
 +      float rdmg = damg * random();
 +
 +      if (self.health <= 0)
 +              return FALSE; // attacking while dead?!
 +
 +      if(dostop)
 +      {
 +              self.velocity_x = 0;
 +              self.velocity_y = 0;
 +              self.state = MONSTER_STATE_ATTACK_MELEE;
 +              self.SendFlags |= MSF_MOVE;
 +      }
 +
 +      monsters_setframe(anim);
 +
 +      if(anim_finished != 0)
 +              self.attack_finished_single = time + anim_finished;
 +
 +      monster_makevectors(targ);
 +
 +      traceline(self.origin + self.view_ofs, self.origin + v_forward * er, 0, self);
 +
 +      if(trace_ent.takedamage)
 +              Damage(trace_ent, self, self, rdmg * monster_skill, deathtype, trace_ent.origin, normalize(trace_ent.origin - self.origin));
 +
 +      return TRUE;
 +}
 +
 +void Monster_CheckMinibossFlag ()
 +{
 +      if(MUTATOR_CALLHOOK(MonsterCheckBossFlag))
 +              return;
 +
 +      float chance = random() * 100;
 +
 +      // g_monsters_miniboss_chance cvar or spawnflags 64 causes a monster to be a miniboss
 +      if ((self.spawnflags & MONSTERFLAG_MINIBOSS) || (chance < autocvar_g_monsters_miniboss_chance))
 +      {
 +              self.health += autocvar_g_monsters_miniboss_healthboost;
 +              if not(self.weapon)
 +                      self.weapon = WEP_NEX;
 +      }
 +}
 +
 +float Monster_CanRespawn(entity ent)
 +{
 +      other = ent;
 +      if(MUTATOR_CALLHOOK(MonsterRespawn))
 +              return TRUE; // enabled by a mutator
 +
 +      if(ent.spawnflags & MONSTERFLAG_NORESPAWN)
 +              return FALSE;
 +
 +      if not(autocvar_g_monsters_respawn)
 +              return FALSE;
 +
 +      return TRUE;
 +}
 +
 +void Monster_Fade ()
 +{
 +      if(Monster_CanRespawn(self))
 +      {
 +              self.monster_respawned = TRUE;
 +              self.think = self.monster_spawnfunc;
 +              self.nextthink = time + self.respawntime;
 +              self.deadflag = DEAD_RESPAWNING;
 +              if(self.spawnflags & MONSTER_RESPAWN_DEATHPOINT)
 +              {
 +                      self.pos1 = self.origin;
 +                      self.pos2 = self.angles;
 +              }
 +              self.event_damage = func_null;
 +              self.takedamage = DAMAGE_NO;
 +              setorigin(self, self.pos1);
 +              self.angles = self.pos2;
 +              self.health = self.max_health;
 +
 +              self.SendFlags |= MSF_MOVE;
 +              self.SendFlags |= MSF_STATUS;
 +      }
 +      else
 +              SUB_SetFade(self, time + 3, 1);
 +}
 +
 +float Monster_CanJump (vector vel)
 +{
 +      if(self.state)
 +              return FALSE; // already attacking
 +      if not(self.flags & FL_ONGROUND)
 +              return FALSE; // not on the ground
 +      if(self.health <= 0)
 +              return FALSE; // called when dead?
 +      if(time < self.attack_finished_single)
 +              return FALSE; // still attacking
 +
 +      vector old = self.velocity;
 +
 +      self.velocity = vel;
 +      tracetoss(self, self);
 +      self.velocity = old;
 +      if (trace_ent != self.enemy)
 +              return FALSE;
 +
 +      return TRUE;
 +}
 +
 +float monster_leap (float anm, void() touchfunc, vector vel, float anim_finished)
 +{
 +      if(!Monster_CanJump(vel))
 +              return FALSE;
 +
 +      monsters_setframe(anm);
 +      self.state = MONSTER_STATE_ATTACK_LEAP;
 +      self.touch = touchfunc;
 +      self.origin_z += 1;
 +      self.velocity = vel;
 +      self.flags &= ~FL_ONGROUND;
 +
 +      self.attack_finished_single = time + anim_finished;
 +
 +      return TRUE;
 +}
 +
 +void monster_checkattack(entity e, entity targ)
 +{
 +      if(e == world)
 +              return;
 +      if(targ == world)
 +              return;
 +
 +      if not(e.monster_attackfunc)
 +              return;
 +
 +      if(time < e.attack_finished_single)
 +              return;
 +
 +      if(vlen(targ.origin - e.origin) <= e.attack_range)
 +      if(e.monster_attackfunc(MONSTER_ATTACK_MELEE))
 +      {
 +              MonsterSound(monstersound_melee, 0, FALSE, CH_VOICE);
 +              return;
 +      }
 +
 +      if(vlen(targ.origin - e.origin) > e.attack_range)
 +      if(e.monster_attackfunc(MONSTER_ATTACK_RANGED))
 +      {
 +              MonsterSound(monstersound_ranged, 0, FALSE, CH_VOICE);
 +              return;
 +      }
 +}
 +
 +void monster_use ()
 +{
 +      if not(self.enemy)
 +      if(self.health > 0)
 +      if(monster_isvalidtarget(activator, self))
 +              self.enemy = activator;
 +}
 +
 +.float last_trace;
 +.float last_enemycheck; // for checking enemy
 +vector monster_pickmovetarget(entity targ)
 +{
 +      // enemy is always preferred target
 +      if(self.enemy)
 +      {
 +              makevectors(self.angles);
 +              self.monster_movestate = MONSTER_MOVE_ENEMY;
 +              self.last_trace = time + 1.2;
 +              return self.enemy.origin;
 +      }
 +
 +      switch(self.monster_moveflags)
 +      {
 +              case MONSTER_MOVE_OWNER:
 +              {
 +                      self.monster_movestate = MONSTER_MOVE_OWNER;
 +                      self.last_trace = time + 0.3;
 +                      return (self.monster_owner) ? self.monster_owner.origin : self.origin;
 +              }
 +              case MONSTER_MOVE_SPAWNLOC:
 +              {
 +                      self.monster_movestate = MONSTER_MOVE_SPAWNLOC;
 +                      self.last_trace = time + 2;
 +                      return self.pos1;
 +              }
 +              case MONSTER_MOVE_NOMOVE:
 +              {
 +                      self.monster_movestate = MONSTER_MOVE_NOMOVE;
 +                      self.last_trace = time + 2;
 +                      return self.origin;
 +              }
 +              default:
 +              case MONSTER_MOVE_WANDER:
 +              {
 +                      vector pos;
 +                      self.monster_movestate = MONSTER_MOVE_WANDER;
 +                      self.last_trace = time + 2;
 +
 +                      self.angles_y = rint(random() * 500);
 +                      makevectors(self.angles);
 +                      pos = self.origin + v_forward * 600;
 +
 +                      if(self.flags & FL_FLY || self.flags & FL_SWIM)
 +                      if(self.spawnflags & MONSTERFLAG_FLY_VERTICAL)
 +                      {
 +                              pos_z = random() * 200;
 +                              if(random() >= 0.5)
 +                                      pos_z *= -1;
 +                      }
 +
 +                      if(targ)
 +                      {
 +                              self.last_trace = time + 0.5;
 +                              pos = targ.origin;
 +                      }
 +
 +                      return pos;
 +              }
 +      }
 +}
 +
 +void monster_move(float runspeed, float walkspeed, float stopspeed, float manim_run, float manim_walk, float manim_idle)
 +{
 +      fixedmakevectors(self.angles);
 +
 +      if(self.target2)
 +              self.goalentity = find(world, targetname, self.target2);
 +
 +      entity targ;
 +
 +      if(self.frozen)
 +      {
 +              self.revive_progress = bound(0, self.revive_progress + frametime * self.revive_speed, 1);
 +              self.health = max(1, self.max_health * self.revive_progress);
 +
 +              self.SendFlags |= MSF_STATUS;
 +
 +              movelib_beak_simple(stopspeed);
 +
 +              self.velocity = '0 0 0';
 +              self.enemy = world;
 +              self.nextthink = time + 0.1;
 +
 +              if(self.revive_progress >= 1)
 +                      Unfreeze(self); // wait for next think before attacking
 +
 +              // don't bother updating angles here?
 +              if(self.origin != self.oldorigin)
 +              {
 +                      self.oldorigin = self.origin;
 +                      self.SendFlags |= MSF_MOVE;
 +              }
 +
 +              return; // no moving while frozen
 +      }
 +
 +      if(self.flags & FL_SWIM)
 +      {
 +              if(self.waterlevel < WATERLEVEL_WETFEET)
 +              {
 +                      if(time >= self.last_trace)
 +                      {
 +                              self.fish_wasdrowning = TRUE;
 +                              self.last_trace = time + 0.4;
 +
 +                              Damage (self, world, world, 2, DEATH_DROWN, self.origin, '0 0 0');
 +                              self.angles = '90 90 0';
 +                              if(random() < 0.5)
 +                              {
 +                                      self.velocity_y += random() * 50;
 +                                      self.velocity_x -= random() * 50;
 +                              }
 +                              else
 +                              {
 +                                      self.velocity_y -= random() * 50;
 +                                      self.velocity_x += random() * 50;
 +                              }
 +                              self.velocity_z += random() * 150;
 +                      }
 +
 +
 +                      self.movetype = MOVETYPE_BOUNCE;
 +                      //self.velocity_z = -200;
 +
 +                      self.SendFlags |= MSF_MOVE | MSF_ANG;
 +
 +                      return;
 +              }
 +              else if(self.fish_wasdrowning)
 +              {
 +                      self.fish_wasdrowning = FALSE;
 +                      self.angles_x = 0;
 +                      self.movetype = MOVETYPE_WALK;
 +              }
 +      }
 +
 +      targ = self.goalentity;
 +
 +      monster_target = targ;
 +      monster_speed_run = runspeed;
 +      monster_speed_walk = walkspeed;
 +
 +      if(MUTATOR_CALLHOOK(MonsterMove) || gameover || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || time < game_starttime || (autocvar_g_campaign && !campaign_bots_may_start) || time < self.spawn_time)
 +      {
 +              runspeed = walkspeed = 0;
 +              if(time >= self.spawn_time)
 +                      monsters_setframe(manim_idle);
 +              movelib_beak_simple(stopspeed);
 +              if(self.oldorigin != self.origin)
 +              {
 +                      self.oldorigin = self.origin;
 +                      self.SendFlags |= MSF_MOVE;
 +              }
 +              return;
 +      }
 +
 +      targ = monster_target;
 +      runspeed = monster_speed_run;
 +      walkspeed = monster_speed_walk;
 +
 +      if(teamplay)
 +      if(autocvar_g_monsters_teams)
++      if(DIFF_TEAM(self.monster_owner, self))
 +              self.monster_owner = world;
 +
 +      if(self.enemy && self.enemy.health < 1)
 +              self.enemy = world; // enough!
 +
 +      if(time >= self.last_enemycheck)
 +      {
 +              if not(monster_isvalidtarget(self.enemy, self))
 +                      self.enemy = world;
 +
 +              if not(self.enemy)
 +              {
 +                      self.enemy = FindTarget(self);
 +                      if(self.enemy)
 +                              MonsterSound(monstersound_sight, 0, FALSE, CH_VOICE);
 +              }
 +
 +              self.last_enemycheck = time + 0.5;
 +      }
 +
 +      if(self.state == MONSTER_STATE_ATTACK_MELEE && time >= self.attack_finished_single)
 +              self.state = 0;
 +
 +      if(self.state != MONSTER_STATE_ATTACK_MELEE) // don't move if set
 +      if(time >= self.last_trace || self.enemy) // update enemy instantly
 +              self.moveto = monster_pickmovetarget(targ);
 +
 +      if not(self.enemy)
 +              MonsterSound(monstersound_idle, 5, TRUE, CH_VOICE);
 +
 +      if(self.state != MONSTER_STATE_ATTACK_LEAP && self.state != MONSTER_STATE_ATTACK_MELEE)
 +              self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
 +
 +      if(self.state == MONSTER_STATE_ATTACK_LEAP && (self.flags & FL_ONGROUND))
 +      {
 +              self.state = 0;
 +              self.touch = MonsterTouch;
 +      }
 +
 +      //self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
 +
 +      float turny = 0;
 +      vector real_angle = vectoangles(self.steerto) - self.angles;
 +
 +      if(self.state != MONSTER_STATE_ATTACK_LEAP && self.state != MONSTER_STATE_ATTACK_MELEE)
 +              turny = 20;
 +
 +      if(self.flags & FL_SWIM)
 +              turny = vlen(self.angles - self.moveto);
 +
 +      if(turny)
 +      {
 +              turny = bound(turny * -1, shortangle_f(real_angle_y, self.angles_y), turny);
 +              self.angles_y += turny;
 +      }
 +
 +      if(self.state == MONSTER_STATE_ATTACK_MELEE)
 +              self.moveto = self.origin;
 +
 +      if(self.enemy && self.enemy.vehicle)
 +              runspeed = 0;
 +
 +      if(((self.flags & FL_FLY) || (self.flags & FL_SWIM)) && self.spawnflags & MONSTERFLAG_FLY_VERTICAL)
 +              v_forward = normalize(self.moveto - self.origin);
 +      else
 +              self.moveto_z = self.origin_z;
 +
 +      if(vlen(self.origin - self.moveto) > 64)
 +      {
 +              if(self.flags & FL_FLY || self.flags & FL_SWIM)
 +                      movelib_move_simple(v_forward, ((self.enemy) ? runspeed : walkspeed), 0.6);
 +              else
 +                      movelib_move_simple_gravity(v_forward, ((self.enemy) ? runspeed : walkspeed), 0.6);
 +
 +              if(time > self.pain_finished)
 +              if(time > self.attack_finished_single)
 +              if(vlen(self.velocity) > 10)
 +                      monsters_setframe((self.enemy) ? manim_run : manim_walk);
 +              else
 +                      monsters_setframe(manim_idle);
 +      }
 +      else
 +      {
 +              entity e = find(world, targetname, self.target2);
 +              if(e.target2)
 +                      self.target2 = e.target2;
 +              else if(e.target)
 +                      self.target2 = e.target;
 +
 +              movelib_beak_simple(stopspeed);
 +              if(time > self.attack_finished_single)
 +              if(time > self.pain_finished)
 +              if (vlen(self.velocity) <= 30)
 +                      monsters_setframe(manim_idle);
 +      }
 +
 +      monster_checkattack(self, self.enemy);
 +
 +      if(self.angles != self.oldangles)
 +      {
 +              self.oldangles = self.angles;
 +              self.SendFlags |= MSF_ANG;
 +      }
 +
 +      if(self.origin != self.oldorigin)
 +      {
 +              self.oldorigin = self.origin;
 +              self.SendFlags |= MSF_MOVE;
 +      }
 +}
 +
 +void monster_dead_think()
 +{
 +      self.think = monster_dead_think;
 +      self.nextthink = time + self.ticrate;
 +
 +      self.deadflag = DEAD_DEAD;
 +
 +      if(self.ltime != 0)
 +      if(time >= self.ltime)
 +      {
 +              Monster_Fade();
 +              return;
 +      }
 +
 +      if(self.oldorigin != self.origin)
 +      {
 +              self.oldorigin = self.origin;
 +              self.SendFlags |= MSF_MOVE;
 +      }
 +}
 +
 +void monsters_setstatus()
 +{
 +      self.stat_monsters_total = monsters_total;
 +      self.stat_monsters_killed = monsters_killed;
 +}
 +
 +void Monster_Appear()
 +{
 +      self.enemy = activator;
 +      self.spawnflags &= ~MONSTERFLAG_APPEAR;
 +      self.monster_spawnfunc();
 +}
 +
 +float Monster_CheckAppearFlags(entity ent)
 +{
 +      if not(ent.spawnflags & MONSTERFLAG_APPEAR)
 +              return FALSE;
 +
 +      ent.think = func_null;
 +      ent.nextthink = 0;
 +      ent.use = Monster_Appear;
 +      ent.flags = FL_MONSTER; // set so this monster can get butchered
 +
 +      return TRUE;
 +}
 +
 +void monsters_reset()
 +{
 +      setorigin(self, self.pos1);
 +      self.angles = self.pos2;
 +
 +      self.health = self.max_health;
 +      self.velocity = '0 0 0';
 +      self.enemy = world;
 +      self.goalentity = world;
 +      self.attack_finished_single = 0;
 +      self.moveto = self.origin;
 +
 +      self.SendFlags |= MSF_STATUS;
 +}
 +
 +float monster_send(entity to, float sf)
 +{
 +      WriteByte(MSG_ENTITY, ENT_CLIENT_MONSTER);
 +      WriteByte(MSG_ENTITY, sf);
 +      if(sf & MSF_SETUP)
 +      {
 +              WriteByte(MSG_ENTITY, self.monsterid);
 +
 +              WriteCoord(MSG_ENTITY, self.origin_x);
 +              WriteCoord(MSG_ENTITY, self.origin_y);
 +              WriteCoord(MSG_ENTITY, self.origin_z);
 +
 +              WriteAngle(MSG_ENTITY, self.angles_x);
 +              WriteAngle(MSG_ENTITY, self.angles_y);
 +
 +              WriteByte(MSG_ENTITY, self.skin);
 +              WriteByte(MSG_ENTITY, self.team);
 +      }
 +
 +      if(sf & MSF_ANG)
 +      {
 +              WriteShort(MSG_ENTITY, rint(self.angles_x));
 +              WriteShort(MSG_ENTITY, rint(self.angles_y));
 +      }
 +
 +      if(sf & MSF_MOVE)
 +      {
 +              WriteShort(MSG_ENTITY, rint(self.origin_x));
 +              WriteShort(MSG_ENTITY, rint(self.origin_y));
 +              WriteShort(MSG_ENTITY, rint(self.origin_z));
 +
 +              WriteShort(MSG_ENTITY, rint(self.velocity_x));
 +              WriteShort(MSG_ENTITY, rint(self.velocity_y));
 +              WriteShort(MSG_ENTITY, rint(self.velocity_z));
 +
 +              WriteShort(MSG_ENTITY, rint(self.angles_y));
 +      }
 +
 +      if(sf & MSF_ANIM)
 +      {
 +              WriteCoord(MSG_ENTITY, self.anim_start_time);
 +              WriteByte(MSG_ENTITY, self.frame);
 +      }
 +
 +      if(sf & MSF_STATUS)
 +      {
 +              WriteByte(MSG_ENTITY, self.skin);
 +
 +              WriteByte(MSG_ENTITY, self.team);
 +
 +              WriteByte(MSG_ENTITY, self.deadflag);
 +
 +              if(self.health <= 0)
 +                      WriteByte(MSG_ENTITY, 0);
 +              else
 +                      WriteByte(MSG_ENTITY, ceil((self.health / self.max_health) * 255));
 +      }
 +
 +      return TRUE;
 +}
 +
 +void monster_link(void() spawnproc)
 +{
 +      Net_LinkEntity(self, TRUE, 0, monster_send);
 +      self.think        = spawnproc;
 +      self.nextthink  = time;
 +}
 +
 +void monsters_corpse_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 +{
 +      self.health -= damage;
 +
 +      Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, self, attacker);
 +
 +      if(self.health <= -100) // 100 health until gone?
 +      {
 +              Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, self, attacker);
 +
 +              self.think = SUB_Remove;
 +              self.nextthink = time + 0.1;
 +      }
 +}
 +
 +void monster_die()
 +{
 +      self.think = monster_dead_think;
 +      self.nextthink = self.ticrate;
 +      self.ltime = time + 5;
 +
 +      monster_dropitem();
 +
 +      MonsterSound(monstersound_death, 0, FALSE, CH_VOICE);
 +
 +      if(!(self.spawnflags & MONSTERFLAG_SPAWNED) && !self.monster_respawned)
 +              monsters_killed += 1;
 +
 +      if(self.candrop && self.weapon)
 +              W_ThrowNewWeapon(self, self.weapon, 0, self.origin, randomvec() * 150 + '0 0 325');
 +
 +      if(IS_CLIENT(self.realowner))
 +      if not(self.monster_respawned)
 +              self.realowner.monstercount -= 1;
 +
 +      self.event_damage       = monsters_corpse_damage;
 +      self.solid                      = SOLID_CORPSE;
 +      self.takedamage         = DAMAGE_AIM;
 +      self.enemy                      = world;
 +      self.movetype           = MOVETYPE_TOSS;
 +      self.moveto                     = self.origin;
 +      self.touch                      = MonsterTouch; // reset incase monster was pouncing
 +      self.reset                      = func_null;
 +      self.state                      = 0;
 +      self.attack_finished_single = 0;
 +
 +      if not(self.flags & FL_FLY)
 +              self.velocity = '0 0 0';
 +
 +      self.SendFlags |= MSF_MOVE;
 +
 +      // number of monsters spawned with mobspawn command
 +      totalspawned -= 1;
 +
 +      MON_ACTION(self.monsterid, MR_DEATH);
 +}
 +
 +void monsters_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 +{
 +      if(self.frozen && deathtype != DEATH_KILL)
 +              return;
 +
 +      if(time < self.pain_finished && deathtype != DEATH_KILL)
 +              return;
 +
 +      if(time < self.spawnshieldtime)
 +              return;
 +
 +      vector v;
 +      float take, save;
 +
 +      v = healtharmor_applydamage(self.armorvalue, self.m_armor_blockpercent, damage);
 +      take = v_x;
 +      save = v_y;
 +
 +      self.health -= take;
 +
 +      self.dmg_time = time;
 +
 +      if(sound_allowed(MSG_BROADCAST, attacker) && deathtype != DEATH_DROWN)
 +              spamsound (self, CH_PAIN, "misc/bodyimpact1.wav", VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
 +
 +      self.velocity += force * self.damageforcescale;
 +
 +      if(deathtype != DEATH_DROWN)
 +      {
 +              Violence_GibSplash_At(hitloc, force, 2, bound(0, take, 200) / 16, self, attacker);
 +              if (take > 50)
 +                      Violence_GibSplash_At(hitloc, force * -0.1, 3, 1, self, attacker);
 +              if (take > 100)
 +                      Violence_GibSplash_At(hitloc, force * -0.2, 3, 1, self, attacker);
 +      }
 +
 +      if(self.health <= 0)
 +      {
 +              if(deathtype == DEATH_KILL)
 +                      self.candrop = FALSE; // killed by mobkill command
 +
 +              // TODO: fix this?
 +              activator = attacker;
 +              other = self.enemy;
 +              SUB_UseTargets();
 +              self.target2 = self.oldtarget2; // reset to original target on death, incase we respawn
 +
 +              monster_die();
 +
 +              frag_attacker = attacker;
 +              frag_target = self;
 +              MUTATOR_CALLHOOK(MonsterDies);
 +
 +              if(self.health <= -100) // check if we're already gibbed
 +              {
 +                      Violence_GibSplash(self, 1, 0.5, attacker);
 +
 +                      self.think = SUB_Remove;
 +                      self.nextthink = time + 0.1;
 +              }
 +      }
 +
 +      self.SendFlags |= MSF_STATUS;
 +}
 +
 +void monster_think()
 +{
 +      self.think = monster_think;
 +      self.nextthink = self.ticrate;
 +
 +      MON_ACTION(self.monsterid, MR_THINK);
 +}
 +
 +void monster_spawn()
 +{
 +      MON_ACTION(self.monsterid, MR_SETUP);
 +
 +      if not(self.monster_respawned)
 +              Monster_CheckMinibossFlag();
 +
 +      self.max_health = self.health;
 +      self.pain_finished = self.nextthink;
 +      self.anim_start_time = time;
 +
 +      if not(self.noalign)
 +      {
 +              setorigin(self, self.origin + '0 0 20');
 +              tracebox(self.origin + '0 0 100', self.mins, self.maxs, self.origin - '0 0 10000', MOVE_WORLDONLY, self);
 +              setorigin(self, trace_endpos);
 +      }
 +
 +      if not(self.monster_respawned)
 +      if not(self.skin)
 +              self.skin = rint(random() * 4);
 +
 +      if not(self.attack_range)
 +              self.attack_range = autocvar_g_monsters_attack_range;
 +
 +      self.pos1 = self.origin;
 +
 +      //monster_setupsounds(self.netname);
 +      precache_monstersounds();
 +      UpdateMonsterSounds();
 +      //monster_precachesounds(self);
 +
 +      if(teamplay)
 +              self.monster_attack = TRUE; // we can have monster enemies in team games
 +              
 +      MonsterSound(monstersound_spawn, 0, FALSE, CH_VOICE);
 +
 +      self.think = monster_think;
 +      self.nextthink = time + self.ticrate;
 +
 +      self.SendFlags |= MSF_SETUP;
 +
 +      MUTATOR_CALLHOOK(MonsterSpawn);
 +}
 +
 +float monster_initialize(float mon_id, float nodrop)
 +{
 +      if not(autocvar_g_monsters)
 +              return FALSE;
 +
 +      entity mon = get_monsterinfo(mon_id);
 +
 +      // support for quake style removing monsters based on skill
 +      switch(monster_skill)
 +      {
 +              case 0:
 +              case 1: if(self.spawnflags & MONSTERSKILL_NOTEASY)              return FALSE; break;
 +              case 2: if(self.spawnflags & MONSTERSKILL_NOTMEDIUM)    return FALSE; break;
 +              default:
 +              case 3: if(self.spawnflags & MONSTERSKILL_NOTHARD)              return FALSE; break;
 +      }
 +
 +      if(self.team && !teamplay)
 +              self.team = 0;
 +
 +      if not(self.spawnflags & MONSTERFLAG_SPAWNED) // naturally spawned monster
 +      if not(self.monster_respawned)
 +              monsters_total += 1;
 +
 +      setsize(self, mon.mins, mon.maxs);
 +      self.flags                              = FL_MONSTER;
 +      self.takedamage                 = DAMAGE_AIM;
 +      self.bot_attack                 = TRUE;
 +      self.iscreature                 = TRUE;
 +      self.teleportable               = TRUE;
 +      self.damagedbycontents  = TRUE;
 +      self.monsterid                  = mon_id;
 +      self.damageforcescale   = 0;
 +      self.event_damage               = monsters_damage;
 +      self.touch                              = MonsterTouch;
 +      self.use                                = monster_use;
 +      self.solid                              = SOLID_BBOX;
 +      self.movetype                   = MOVETYPE_WALK;
 +      self.spawnshieldtime    = time + autocvar_g_monsters_spawnshieldtime;
 +      self.enemy                              = world;
 +      self.velocity                   = '0 0 0';
 +      self.moveto                             = self.origin;
 +      self.pos2                               = self.angles;
 +      self.reset                              = monsters_reset;
 +      self.netname                    = mon.netname;
 +      self.monster_name               = M_NAME(mon_id);
 +      self.candrop                    = TRUE;
 +      self.view_ofs                   = '0 0 1' * (self.maxs_z * 0.5);
 +      self.oldtarget2                 = self.target2;
 +      self.deadflag                   = DEAD_NO;
 +      self.scale                              = 1;
 +      self.noalign                    = nodrop;
 +      self.spawn_time                 = time;
 +      self.gravity                    = 1;
 +      self.dphitcontentsmask  = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_BOTCLIP | DPCONTENTS_MONSTERCLIP;
 +
 +      if(mon.spawnflags & MONSTER_TYPE_SWIM)
 +              self.flags |= FL_SWIM;
 +
 +      if(mon.spawnflags & MONSTER_TYPE_FLY)
 +      {
 +              self.flags |= FL_FLY;
 +              self.movetype = MOVETYPE_FLY;
 +      }
 +
 +      if(mon.spawnflags & MONSTER_SIZE_BROKEN)
 +              self.scale = 1.3;
 +
 +      if not(self.ticrate)
 +              self.ticrate = autocvar_g_monsters_think_delay;
 +
 +      self.ticrate = bound(sys_frametime, self.ticrate, 60);
 +
 +      if not(self.m_armor_blockpercent)
 +              self.m_armor_blockpercent = 0.5;
 +
 +      if not(self.target_range)
 +              self.target_range = autocvar_g_monsters_target_range;
 +
 +      if not(self.respawntime)
 +              self.respawntime = autocvar_g_monsters_respawn_delay;
 +
 +      if not(self.monster_moveflags)
 +              self.monster_moveflags = MONSTER_MOVE_WANDER;
 +
 +      monster_link(monster_spawn);
 +
 +      return TRUE;
 +}
@@@ -245,208 -327,183 +327,208 @@@ void Send_Notification_WOCOVA
                MSG_INFO_NOTIF(default, prefix##PINK, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_4)), TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) \
        #endif
  #define MSG_INFO_NOTIFICATIONS \
-       MULTITEAM_INFO(1, INFO_CTF_CAPTURE_, 2,                1, 0, "s1", "s1",                        "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag\n"), "") \
-       MULTITEAM_INFO(1, INFO_CTF_CAPTURE_BROKEN_, 2,         2, 2, "s1 f1p2dec s2 f2p2dec", "s1",     "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds, breaking ^BG%s^BG's previous record of ^F2%s^BG seconds\n"), "") \
-       MULTITEAM_INFO(1, INFO_CTF_CAPTURE_TIME_, 2,           1, 1, "s1 f1p2dec", "s1",                "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds\n"), "") \
-       MULTITEAM_INFO(1, INFO_CTF_CAPTURE_UNBROKEN_, 2,       2, 2, "s1 f1p2dec s2 f2p2dec", "s1",     "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag in ^F2%s^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%s^BG seconds\n"), "") \
-       MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_ABORTRUN_, 2,    0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag was returned to base by its owner\n"), "") \
-       MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DAMAGED_, 2,     0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag was destroyed and returned to base\n"), "") \
-       MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DROPPED_, 2,     0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself\n"), "") \
-       MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_NEEDKILL_, 2,    0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base\n"), "") \
-       MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_SPEEDRUN_, 2,    0, 1, "f1p2dec", "",                     "",                     _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself\n"), "") \
-       MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_TIMEOUT_, 2,     0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag has returned to the base\n"), "") \
-       MULTITEAM_INFO(1, INFO_CTF_LOST_, 2,                   1, 0, "s1", "s1",                        "notify_%s_lost",       _("^BG%s^BG lost the ^TC^TT^BG flag\n"), "") \
-       MULTITEAM_INFO(1, INFO_CTF_PICKUP_, 2,                 1, 0, "s1", "s1",                        "notify_%s_taken",      _("^BG%s^BG got the ^TC^TT^BG flag\n"), "") \
-       MULTITEAM_INFO(1, INFO_CTF_RETURN_, 2,                 1, 0, "s1", "s1",                        "notify_%s_returned",   _("^BG%s^BG returned the ^TC^TT^BG flag\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_CHEAT,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was unfairly eliminated by ^BG%s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_DROWN,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_water",         _("^BG%s%s^K1 was drowned by ^BG%s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FALL,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_fall",          _("^BG%s%s^K1 was grounded by ^BG%s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FIRE,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was burnt up into a crisp by ^BG%s^K1%s%s\n"), _("^BG%s%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s%s\n")) \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_LAVA,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_lava",          _("^BG%s%s^K1 was cooked by ^BG%s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_MONSTER,           3, 2, "spree_inf s1 s2 s3loc spree_end", "",       "",                             _("^BG%s%s^K1 was pushed infront of a monster by ^BG%s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SHOOTING_STAR,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_shootingstar",  _("^BG%s%s^K1 was shot into space by ^BG%s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SLIME,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_slime",         _("^BG%s%s^K1 was slimed by ^BG%s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SWAMP,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_slime",         _("^BG%s%s^K1 was preserved by ^BG%s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_TELEFRAG,          3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_telefrag",      _("^BG%s%s^K1 was telefragged by ^BG%s^K1%s%s\n"), _("^BG%s%s^K1 tried to occupy ^BG%s^K1's teleport destination space%s%s\n")) \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_TOUCHEXPLODE,      3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 died in an accident with ^BG%s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_BUMB_DEATH,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Bumblebee exploded%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_BUMB_GUN,       3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 saw the pretty lights of ^BG%s^K1's Bumblebee gun%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_CRUSH,          3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was crushed by ^BG%s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_BOMB,      3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was cluster bombed by ^BG%s^K1's Raptor%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_CANNON,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 couldn't resist ^BG%s^K1's purple blobs%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_DEATH,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Raptor exploded%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_DEATH,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Spiderbot exploded%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_MINIGUN,   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got shredded by ^BG%s^K1's Spiderbot%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_ROCKET,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was blasted to bits by ^BG%s^K1's Spiderbot%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_DEATH,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Racer exploded%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_GUN,       3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was bolted down by ^BG%s^K1's Racer%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_ROCKET,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 couldn't find shelter from ^BG%s^K1's Racer%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VOID,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_void",          _("^BG%s%s^K1 was thrown into a world of hurt by ^BG%s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_AUTOTEAMCHANGE,      2, 1, "s1 s2loc death_team", "",         "",                     _("^BG%s^K1 was moved into the %s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_BETRAYAL,            2, 1, "s1 s2loc spree_lost", "s1",       "notify_teamkill_red",  _("^BG%s^K1 became enemies with the Lord of Teamplay%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CAMP,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_camping",       _("^BG%s^K1 thought they found a nice camping ground%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CHEAT,               2, 1, "s1 s2loc spree_lost", "s1",       "notify_selfkill",      _("^BG%s^K1 unfairly eliminated themself%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CUSTOM,              3, 1, "s1 s2 s3loc spree_lost", "s1",    "notify_void",          _("^BG%s^K1 %s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_DROWN,               2, 1, "s1 s2loc spree_lost", "s1",       "notify_water",         _("^BG%s^K1 couldn't catch their breath%s%s\n"), _("^BG%s^K1 was in the water for too long%s%s\n")) \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_FALL,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_fall",          _("^BG%s^K1 hit the ground with a crunch%s%s\n"), _("^BG%s^K1 hit the ground with a bit too much force%s%s\n")) \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_FIRE,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 became a bit too crispy%s%s\n"), _("^BG%s^K1 felt a little hot%s%s\n")) \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_GENERIC,             2, 1, "s1 s2loc spree_lost", "s1",       "notify_selfkill",      _("^BG%s^K1 died%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_LAVA,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_lava",          _("^BG%s^K1 turned into hot slag%s%s\n"), _("^BG%s^K1 found a hot place%s%s\n")) \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_CERBERUS_BITE,   2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was mauled by a Cerberus%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_CERBERUS_JUMP,   2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 didn't see the pouncing Cerberus%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ANIMUS,          2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was eviscerated by an Animus%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_STINGRAY,        2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was fatally wounded by a Stingray%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_KNIGHT_CRUSH,    2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was crushed by a pouncing Knight%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_KNIGHT_FBALL,    2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was turned to ash by a Knight%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_KNIGHT_INFERNO,  2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was burned to death by a Knight%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_KNIGHT_MELEE,    2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was slain by a Knight%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_KNIGHT_SPIKE,    2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was cursed by a Knight%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_BRUISER,             2, 1, "s1 s2loc spree_lost", "s1",           "notify_death",                 _("^BG%s^K1 was beaten in a fistfight by a Bruiser%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_BRUTE_BLADE,     2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was cut down by a Brute%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_BRUTE_GRENADE,   2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 almost dodged a Brute's grenade%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_BRUTE_UZI,           2, 1, "s1 s2loc spree_lost", "s1",           "notify_death",                 _("^BG%s^K1 was nailed by a Brute%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_MAGE,                2, 1, "s1 s2loc spree_lost", "s1",           "notify_death",                 _("^BG%s^K1 was exploded by a Mage%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_CLAW,   2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1's innards became outwards by a Shambler%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_SMASH,  2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was smashed by a Shambler%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_ZAP,    2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was zapped to death by a Shambler%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SPIDER,              2, 1, "s1 s2loc spree_lost", "s1",           "notify_death",                 _("^BG%s^K1 was bitten by a Spider%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SPIDER_FIRE,     2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was incinerated by a Spider%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SLIME,           2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was blown up by a Slime%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_WYVERN,          2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was fireballed by a Wyvern%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_JUMP,     2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 joins the Zombies%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_MELEE,    2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was given kung fu lessons by a Zombie%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 mastered the art of self-nading%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NOAMMO,              2, 1, "s1 s2loc spree_lost", "s1",       "notify_outofammo",     _("^BG%s^K1 died%s%s. What's the point of living without ammo?\n"), _("^BG%s^K1 ran out of ammo%s%s\n")) \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_ROT,                 2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 rotted away%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SHOOTING_STAR,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_shootingstar",  _("^BG%s^K1 became a shooting star%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SLIME,               2, 1, "s1 s2loc spree_lost", "s1",       "notify_slime",         _("^BG%s^K1 was slimed%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SUICIDE,             2, 1, "s1 s2loc spree_lost", "s1",       "notify_selfkill",      _("^BG%s^K1 couldn't take it anymore%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SWAMP,               2, 1, "s1 s2loc spree_lost", "s1",       "notify_slime",         _("^BG%s^K1 is now preserved for centuries to come%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TEAMCHANGE,          2, 1, "s1 s2loc death_team", "",         "",                     _("^BG%s^K1 switched to the %s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TOUCHEXPLODE,        2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 died in an accident%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET,              2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 ran into a turret%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_EWHEEL,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was blasted away by an eWheel turret%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_FLAC,         2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught up in the FLAC turret fire%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_HELLION,      2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was blasted away by a Hellion turret%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_HK,           2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 could not hide from the Hunter turret%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_MACHINEGUN,   2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was riddled full of holes by a Machinegun turret%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_MLRS,         2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got turned into smoldering gibs by an MLRS turret%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_PHASER,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was phased out by a turret%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_PLASMA,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got served some superheated plasma from a turret%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_TESLA,        2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was electrocuted by a Tesla turret%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_GUN,     2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got served a lead enrichment by a Walker turret%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_MEELE,   2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was impaled by a Walker turret%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_ROCKET,  2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was blasted away by a Walker turret%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_BUMB_DEATH,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught in the blast of a Bumblebee explosion%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_CRUSH,            2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was crushed by a vehicle%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_RAPT_BOMB,        2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was caught in a Raptor cluster bomb%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_RAPT_DEATH,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught in the blast of a Raptor explosion%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_SPID_DEATH,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught in the blast of a Spiderbot explosion%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_SPID_ROCKET,      2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was blasted to bits by a Spiderbot rocket%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_WAKI_DEATH,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught in the blast of a Racer explosion%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_WAKI_ROCKET,      2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 couldn't find shelter from a Racer rocket%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VOID,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_void",          _("^BG%s^K1 was in the wrong place%s%s\n"), "") \
-       MULTITEAM_INFO(1, INFO_DEATH_TEAMKILL_, 4,             3, 1, "s1 s2 s3loc spree_end", "s2 s1",  "notify_teamkill_%s",   _("^BG%s^K1 was betrayed by ^BG%s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_FREEZETAG_FREEZE,               2, 0, "s1 s2", "",                       "",                     _("^BG%s^K1 was frozen by ^BG%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVED,              2, 0, "s1 s2", "",                       "",                     _("^BG%s^K3 was revived by ^BG%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVED_FALL,         1, 0, "s1", "",                          "",                     _("^BG%s^K3 was revived by falling\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_FREEZETAG_AUTO_REVIVED,         1, 1, "s1 f1", "",                       "",                     _("^BG%s^K3 was automatically revived after %s second(s)\n"), "") \
-       MULTITEAM_INFO(1, INFO_ROUND_TEAM_WIN_, 4,             0, 0, "", "",                            "",                     _("^TC^TT^BG team wins the round\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_ROUND_PLAYER_WIN,               1, 0, "s1", "",                          "",                     _("^BG%s^BG wins the round\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_ROUND_TIED,                     0, 0, "", "",                            "",                     _("^BGRound tied\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_ROUND_OVER,                     0, 0, "", "",                            "",                     _("^BGRound over, there's no winner\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_FREEZETAG_SELF,                 1, 0, "s1", "",                          "",                     _("^BG%s^K1 froze themself\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_GODMODE_OFF,                    0, 1, "f1", "",                          "",                     _("^BGGodmode saved you %s units of damage, cheater!\n"), "") \
-       MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_DONTHAVE,           0, 1, "item_wepname", "",                      "",               _("^BGYou do not have the ^F1%s\n"), "") \
-       MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_DROP,               1, 1, "item_wepname item_wepammo", "",         "",               _("^BGYou dropped the ^F1%s^BG%s\n"), "") \
-       MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_GOT,                0, 1, "item_wepname", "",                      "",               _("^BGYou got the ^F1%s\n"), "") \
-       MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_NOAMMO,             0, 1, "item_wepname", "",                      "",               _("^BGYou don't have enough ammo for the ^F1%s\n"), "") \
-       MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_PRIMORSEC,          0, 3, "item_wepname f2primsec f3primsec", "",  "",               _("^F1%s %s^BG is unable to fire, but its ^F1%s^BG can\n"), "") \
-       MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_UNAVAILABLE,        0, 1, "item_wepname", "",                      "",               _("^F1%s^BG is ^F4not available^BG on this map\n"), "") \
-       MSG_INFO_NOTIF(2, INFO_JOIN_CONNECT,                   1, 0, "s1", "",                          "",                     _("^BG%s^F3 connected%s\n"), "") \
-       MULTITEAM_INFO(2, INFO_JOIN_CONNECT_TEAM_, 4,          1, 0, "s1", "",                          "",                     _("^BG%s^F3 connected and joined the ^TC^TT team\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_JOIN_PLAY,                      1, 0, "s1", "",                          "",                     _("^BG%s^F3 is now playing\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_KEEPAWAY_DROPPED,               1, 0, "s1", "s1",                        "notify_balldropped",   _("^BG%s^BG has dropped the ball!\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_KEEPAWAY_PICKUP,                1, 0, "s1", "s1",                        "notify_ballpickedup",  _("^BG%s^BG has picked up the ball!\n"), "") \
-       MULTITEAM_INFO(1, INFO_KEYHUNT_CAPTURE_, 4,            1, 0, "s1", "",                          "",                     _("^BG%s^BG captured the keys for the ^TC^TT team\n"), "") \
-       MULTITEAM_INFO(1, INFO_KEYHUNT_DROP_, 4,               1, 0, "s1", "",                          "",                     _("^BG%s^BG dropped the ^TC^TT Key\n"), "") \
-       MULTITEAM_INFO(1, INFO_KEYHUNT_LOST_, 4,               1, 0, "s1", "",                          "",                     _("^BG%s^BG lost the ^TC^TT Key\n"), "") \
-       MULTITEAM_INFO(1, INFO_KEYHUNT_PICKUP_, 4,             1, 0, "s1", "",                          "",                     _("^BG%s^BG picked up the ^TC^TT Key\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_LMS_FORFEIT,                    1, 0, "s1", "",                          "",                     _("^BG%s^F3 forfeited\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_LMS_NOLIVES,                    1, 0, "s1", "",                          "",                     _("^BG%s^F3 has no more lives left\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_MONSTERS_DISABLED,                  0, 0, "", "",                            "",                     _("^BGMonsters are currently disabled\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_POWERUP_INVISIBILITY,           1, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up Invisibility\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_POWERUP_SHIELD,                 1, 0, "s1", "s1",                        "shield",               _("^BG%s^K1 picked up Shield\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_POWERUP_SPEED,                  1, 0, "s1", "s1",                        "shield",               _("^BG%s^K1 picked up Speed\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_POWERUP_STRENGTH,               1, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up Strength\n"), "") \
-       MSG_INFO_NOTIF(2, INFO_QUIT_DISCONNECT,                1, 0, "s1", "",                          "",                     _("^BG%s^F3 disconnected\n"), "") \
-       MSG_INFO_NOTIF(2, INFO_QUIT_KICK_IDLING,               1, 0, "s1", "",                          "",                     _("^BG%s^F3 was kicked for idling\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_QUIT_KICK_SPECTATING,           0, 0, "", "",                            "",                     _("^F2You were kicked from the server because you are a spectator and spectators aren't allowed at the moment.\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_QUIT_SPECTATE,                  1, 0, "s1", "",                          "",                     _("^BG%s^F3 is now spectating\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_RACE_ABANDONED,                 1, 0, "s1", "",                                                        "",                      _("^BG%s^BG has abandoned the race\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_RACE_FAIL_RANKED,               1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1",        "race_newfail",          _("^BG%s^BG couldn't break their %s%s^BG place record of %s%s %s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_RACE_FAIL_UNRANKED,             1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1",        "race_newfail",          _("^BG%s^BG couldn't break the %s%s^BG place record of %s%s %s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_RACE_FINISHED,                  1, 0, "s1", "",                                                        "",                      _("^BG%s^BG has finished the race\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_RACE_NEW_BROKEN,                2, 3, "s1 s2 race_col f1ord race_col f2race_time race_diff", "s1 s2",  "race_newrankyellow",    _("^BG%s^BG broke %s^BG's %s%s^BG place record with %s%s %s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_RACE_NEW_IMPROVED,              1, 3, "s1 race_col f1ord race_col f2race_time race_diff", "s1",        "race_newtime",          _("^BG%s^BG improved their %s%s^BG place record with %s%s %s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_RACE_NEW_MISSING_UID,           1, 1, "s1 f1race_time", "s1",                                          "race_newfail",          _("^BG%s^BG scored a new record with ^F2%s^BG, but unfortunately lacks a UID and will be lost.\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_RACE_NEW_SET,                   1, 2, "s1 race_col f1ord race_col f2race_time", "s1",                  "race_newrecordserver",  _("^BG%s^BG set the %s%s^BG place record with %s%s\n"), "") \
-       MULTITEAM_INFO(1, INFO_SCORES_, 4,                     0, 0, "", "",                            "",                     _("^TC^TT ^BGteam scores!\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_SPECTATE_WARNING,               0, 1, "f1secs", "",                      "",                     _("^F2You have to become a player within the next %s, otherwise you will be kicked, because spectating isn't allowed at this time!\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_PICKUP,             1, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up a Superweapon\n"), "") \
-       MSG_INFO_NOTIF(2, INFO_VERSION_BETA,                   2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have ^F2Xonotic %s\n"), "") \
-       MSG_INFO_NOTIF(2, INFO_VERSION_OLD,                    2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s\n"), "") \
-       MSG_INFO_NOTIF(2, INFO_VERSION_OUTDATED,               2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get the update from ^F3http://www.xonotic.org/^BG!\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WATERMARK,                      1, 0, "s1", "",                          "",                     _("^F3SVQC Build information: ^F4%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_ACCORDEON_MURDER,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapontuba",             _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Accordeon%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_ACCORDEON_SUICIDE,             2, 1, "s1 s2loc spree_lost", "s1",                 "weapontuba",             _("^BG%s^K1 hurt their own ears with the @!#%%'n Accordeon%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_CRYLINK_MURDER,                3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponcrylink",          _("^BG%s%s^K1 felt the strong pull of ^BG%s^K1's Crylink%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_CRYLINK_SUICIDE,               2, 1, "s1 s2loc spree_lost", "s1",                 "weaponcrylink",          _("^BG%s^K1 felt the strong pull of their Crylink%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_BOLT,           3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponelectro",          _("^BG%s%s^K1 was blasted by ^BG%s^K1's Electro bolt%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_COMBO,          3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponelectro",          _("^BG%s%s^K1 felt the electrifying air of ^BG%s^K1's Electro combo%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_ORBS,           3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponelectro",          _("^BG%s%s^K1 got too close to ^BG%s^K1's Electro plasma%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_SUICIDE_BOLT,          2, 1, "s1 s2loc spree_lost", "s1",                 "weaponelectro",          _("^BG%s^K1 played with Electro plasma%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_SUICIDE_ORBS,          2, 1, "s1 s2loc spree_lost", "s1",                 "weaponelectro",          _("^BG%s^K1 could not remember where they put their Electro plasma%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_MURDER_BLAST,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponfireball",         _("^BG%s%s^K1 got too close to ^BG%s^K1's fireball%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_MURDER_FIREMINE,      3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponfireball",         _("^BG%s%s^K1 got burnt by ^BG%s^K1's firemine%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_SUICIDE_BLAST,        2, 1, "s1 s2loc spree_lost", "s1",                 "weaponfireball",         _("^BG%s^K1 should have used a smaller gun%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE,     2, 1, "s1 s2loc spree_lost", "s1",                 "weaponfireball",         _("^BG%s^K1 forgot about their firemine%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_MURDER_BURST,            3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponhagar",            _("^BG%s%s^K1 was pummeled by a burst of ^BG%s^K1's Hagar rockets%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_MURDER_SPRAY,            3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponhagar",            _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Hagar rockets%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_SUICIDE,                 2, 1, "s1 s2loc spree_lost", "s1",                 "weaponhagar",            _("^BG%s^K1 played with tiny Hagar rockets%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_HLAC_MURDER,                   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponhlac",             _("^BG%s%s^K1 was cut down with ^BG%s^K1's HLAC%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_HLAC_SUICIDE,                  2, 1, "s1 s2loc spree_lost", "s1",                 "weaponhlac",             _("^BG%s^K1 got a little jumpy with their HLAC%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_HOOK_MURDER,                   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponhook",             _("^BG%s%s^K1 was caught in ^BG%s^K1's Hook gravity bomb%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_KLEINBOTTLE_MURDER,            3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapontuba",             _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Klein Bottle%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_KLEINBOTTLE_SUICIDE,           2, 1, "s1 s2loc spree_lost", "s1",                 "weapontuba",             _("^BG%s^K1 hurt their own ears with the @!#%%'n Klein Bottle%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_LASER_MURDER,                  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponlaser",            _("^BG%s%s^K1 was shot to death by ^BG%s^K1's Laser%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_LASER_SUICIDE,                 2, 1, "s1 s2loc spree_lost", "s1",                 "weaponlaser",            _("^BG%s^K1 shot themself to hell with their Laser%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_MINELAYER_MURDER,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponminelayer",        _("^BG%s%s^K1 got too close to ^BG%s^K1's mine%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_MINELAYER_SUICIDE,             2, 1, "s1 s2loc spree_lost", "s1",                 "weaponminelayer",        _("^BG%s^K1 forgot about their mine%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_MINSTANEX_MURDER,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponminstanex",        _("^BG%s%s^K1 has been vaporized by ^BG%s^K1's Minstanex%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_MURDER_BOUNCE,          3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapongrenadelauncher",  _("^BG%s%s^K1 got too close to ^BG%s^K1's Mortar grenade%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_MURDER_EXPLODE,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapongrenadelauncher",  _("^BG%s%s^K1 ate ^BG%s^K1's Mortar grenade%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_SUICIDE_BOUNCE,         2, 1, "s1 s2loc spree_lost", "s1",                 "weapongrenadelauncher",  _("^BG%s^K1 didn't see their own Mortar grenade%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_SUICIDE_EXPLODE,        2, 1, "s1 s2loc spree_lost", "s1",                 "weapongrenadelauncher",  _("^BG%s^K1 blew themself up with their own Mortar%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_NEX_MURDER,                    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponnex",              _("^BG%s%s^K1 has been vaporized by ^BG%s^K1's Nex%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER,                  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 was sniped with a Rifle by ^BG%s^K1%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HAIL,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 died in ^BG%s^K1's Rifle bullet hail%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle bullet hail%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_PIERCING,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrocketlauncher",   _("^BG%s%s^K1 ate ^BG%s^K1's rocket%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrocketlauncher",   _("^BG%s%s^K1 got too close ^BG%s^K1's rocket%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_SUICIDE,        2, 1, "s1 s2loc spree_lost", "s1",                 "weaponrocketlauncher",   _("^BG%s^K1 blew themself up with their Rocketlauncher%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_MURDER_SPRAY,           3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponseeker",           _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Seeker rockets%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_MURDER_TAG,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponseeker",           _("^BG%s%s^K1 was tagged by ^BG%s^K1's Seeker%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_SUICIDE,                2, 1, "s1 s2loc spree_lost", "s1",                 "weaponseeker",           _("^BG%s^K1 played with tiny Seeker rockets%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_SHOTGUN_MURDER,                3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponshotgun",          _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shotgun%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_SHOTGUN_MURDER_SLAP,           3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1",  "notify_melee_shotgun",   _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shotgun%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_THINKING_WITH_PORTALS,         2, 1, "s1 s2loc spree_lost", "s1",                 "notify_selfkill",        _("^BG%s^K1 is now thinking with portals%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_TUBA_MURDER,                   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapontuba",             _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Tuba%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_TUBA_SUICIDE,                  2, 1, "s1 s2loc spree_lost", "s1",                 "weapontuba",             _("^BG%s^K1 hurt their own ears with the @!#%%'n Tuba%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_UZI_MURDER_SNIPE,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponuzi",              _("^BG%s%s^K1 was sniped by ^BG%s^K1's Machine Gun%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_UZI_MURDER_SPRAY,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponuzi",              _("^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s%s\n"), "") 
+       MULTITEAM_INFO(1, INFO_CTF_CAPTURE_, 2,                1, 0, "s1", "s1",                        "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag"), "") \
+       MULTITEAM_INFO(1, INFO_CTF_CAPTURE_BROKEN_, 2,         2, 2, "s1 f1p2dec s2 f2p2dec", "s1",     "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds, breaking ^BG%s^BG's previous record of ^F2%s^BG seconds"), "") \
+       MULTITEAM_INFO(1, INFO_CTF_CAPTURE_TIME_, 2,           1, 1, "s1 f1p2dec", "s1",                "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"), "") \
+       MULTITEAM_INFO(1, INFO_CTF_CAPTURE_UNBROKEN_, 2,       2, 2, "s1 f1p2dec s2 f2p2dec", "s1",     "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag in ^F2%s^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%s^BG seconds"), "") \
+       MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_ABORTRUN_, 2,    0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag was returned to base by its owner"), "") \
+       MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DAMAGED_, 2,     0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag was destroyed and returned to base"), "") \
+       MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DROPPED_, 2,     0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself"), "") \
+       MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_NEEDKILL_, 2,    0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base"), "") \
+       MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_SPEEDRUN_, 2,    0, 1, "f1p2dec", "",                     "",                     _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") \
+       MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_TIMEOUT_, 2,     0, 0, "", "",                            "",                     _("^BGThe ^TC^TT^BG flag has returned to the base"), "") \
+       MULTITEAM_INFO(1, INFO_CTF_LOST_, 2,                   1, 0, "s1", "s1",                        "notify_%s_lost",       _("^BG%s^BG lost the ^TC^TT^BG flag"), "") \
+       MULTITEAM_INFO(1, INFO_CTF_PICKUP_, 2,                 1, 0, "s1", "s1",                        "notify_%s_taken",      _("^BG%s^BG got the ^TC^TT^BG flag"), "") \
+       MULTITEAM_INFO(1, INFO_CTF_RETURN_, 2,                 1, 0, "s1", "s1",                        "notify_%s_returned",   _("^BG%s^BG returned the ^TC^TT^BG flag"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_CHEAT,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was unfairly eliminated by ^BG%s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_DROWN,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_water",         _("^BG%s%s^K1 was drowned by ^BG%s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FALL,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_fall",          _("^BG%s%s^K1 was grounded by ^BG%s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FIRE,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was burnt up into a crisp by ^BG%s^K1%s%s"), _("^BG%s%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s%s")) \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_LAVA,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_lava",          _("^BG%s%s^K1 was cooked by ^BG%s^K1%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_MONSTER,           3, 2, "spree_inf s1 s2 s3loc spree_end", "",       "",                             _("^BG%s%s^K1 was pushed infront of a monster by ^BG%s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SHOOTING_STAR,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_shootingstar",  _("^BG%s%s^K1 was shot into space by ^BG%s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SLIME,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_slime",         _("^BG%s%s^K1 was slimed by ^BG%s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SWAMP,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_slime",         _("^BG%s%s^K1 was preserved by ^BG%s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_TELEFRAG,          3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_telefrag",      _("^BG%s%s^K1 was telefragged by ^BG%s^K1%s%s"), _("^BG%s%s^K1 tried to occupy ^BG%s^K1's teleport destination space%s%s")) \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_TOUCHEXPLODE,      3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 died in an accident with ^BG%s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_BUMB_DEATH,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Bumblebee exploded%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_BUMB_GUN,       3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 saw the pretty lights of ^BG%s^K1's Bumblebee gun%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_CRUSH,          3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was crushed by ^BG%s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_BOMB,      3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was cluster bombed by ^BG%s^K1's Raptor%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_CANNON,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 couldn't resist ^BG%s^K1's purple blobs%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_DEATH,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Raptor exploded%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_DEATH,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Spiderbot exploded%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_MINIGUN,   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got shredded by ^BG%s^K1's Spiderbot%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_ROCKET,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was blasted to bits by ^BG%s^K1's Spiderbot%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_DEATH,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Racer exploded%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_GUN,       3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was bolted down by ^BG%s^K1's Racer%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_ROCKET,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 couldn't find shelter from ^BG%s^K1's Racer%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VOID,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_void",          _("^BG%s%s^K1 was thrown into a world of hurt by ^BG%s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_AUTOTEAMCHANGE,      2, 1, "s1 s2loc death_team", "",         "",                     _("^BG%s^K1 was moved into the %s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_BETRAYAL,            2, 1, "s1 s2loc spree_lost", "s1",       "notify_teamkill_red",  _("^BG%s^K1 became enemies with the Lord of Teamplay%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CAMP,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_camping",       _("^BG%s^K1 thought they found a nice camping ground%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CHEAT,               2, 1, "s1 s2loc spree_lost", "s1",       "notify_selfkill",      _("^BG%s^K1 unfairly eliminated themself%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CUSTOM,              3, 1, "s1 s2 s3loc spree_lost", "s1",    "notify_void",          _("^BG%s^K1 %s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_DROWN,               2, 1, "s1 s2loc spree_lost", "s1",       "notify_water",         _("^BG%s^K1 couldn't catch their breath%s%s"), _("^BG%s^K1 was in the water for too long%s%s")) \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_FALL,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_fall",          _("^BG%s^K1 hit the ground with a crunch%s%s"), _("^BG%s^K1 hit the ground with a bit too much force%s%s")) \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_FIRE,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 became a bit too crispy%s%s"), _("^BG%s^K1 felt a little hot%s%s")) \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_GENERIC,             2, 1, "s1 s2loc spree_lost", "s1",       "notify_selfkill",      _("^BG%s^K1 died%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_LAVA,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_lava",          _("^BG%s^K1 turned into hot slag%s%s"), _("^BG%s^K1 found a hot place%s%s")) \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 mastered the art of self-nading%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_CERBERUS_BITE,   2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was mauled by a Cerberus%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_CERBERUS_JUMP,   2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 didn't see the pouncing Cerberus%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ANIMUS,          2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was eviscerated by an Animus%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_STINGRAY,        2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was fatally wounded by a Stingray%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_KNIGHT_CRUSH,    2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was crushed by a pouncing Knight%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_KNIGHT_FBALL,    2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was turned to ash by a Knight%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_KNIGHT_INFERNO,  2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was burned to death by a Knight%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_KNIGHT_MELEE,    2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was slain by a Knight%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_KNIGHT_SPIKE,    2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was cursed by a Knight%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_BRUISER,             2, 1, "s1 s2loc spree_lost", "s1",           "notify_death",                 _("^BG%s^K1 was beaten in a fistfight by a Bruiser%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_BRUTE_BLADE,     2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was cut down by a Brute%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_BRUTE_GRENADE,   2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 almost dodged a Brute's grenade%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_BRUTE_UZI,           2, 1, "s1 s2loc spree_lost", "s1",           "notify_death",                 _("^BG%s^K1 was nailed by a Brute%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_MAGE,                2, 1, "s1 s2loc spree_lost", "s1",           "notify_death",                 _("^BG%s^K1 was exploded by a Mage%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_CLAW,   2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1's innards became outwards by a Shambler%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_SMASH,  2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was smashed by a Shambler%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_ZAP,    2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was zapped to death by a Shambler%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SPIDER,              2, 1, "s1 s2loc spree_lost", "s1",           "notify_death",                 _("^BG%s^K1 was bitten by a Spider%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SPIDER_FIRE,     2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was incinerated by a Spider%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SLIME,           2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was blown up by a Slime%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_WYVERN,          2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was fireballed by a Wyvern%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_JUMP,     2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 joins the Zombies%s%s"), "") \
++      MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_MELEE,    2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was given kung fu lessons by a Zombie%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NOAMMO,              2, 1, "s1 s2loc spree_lost", "s1",       "notify_outofammo",     _("^BG%s^K1 died%s%s. What's the point of living without ammo?"), _("^BG%s^K1 ran out of ammo%s%s")) \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_ROT,                 2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 rotted away%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SHOOTING_STAR,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_shootingstar",  _("^BG%s^K1 became a shooting star%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SLIME,               2, 1, "s1 s2loc spree_lost", "s1",       "notify_slime",         _("^BG%s^K1 was slimed%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SUICIDE,             2, 1, "s1 s2loc spree_lost", "s1",       "notify_selfkill",      _("^BG%s^K1 couldn't take it anymore%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SWAMP,               2, 1, "s1 s2loc spree_lost", "s1",       "notify_slime",         _("^BG%s^K1 is now preserved for centuries to come%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TEAMCHANGE,          2, 1, "s1 s2loc death_team", "",         "",                     _("^BG%s^K1 switched to the %s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TOUCHEXPLODE,        2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 died in an accident%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET,              2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 ran into a turret%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_EWHEEL,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was blasted away by an eWheel turret%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_FLAC,         2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught up in the FLAC turret fire%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_HELLION,      2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was blasted away by a Hellion turret%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_HK,           2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 could not hide from the Hunter turret%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_MACHINEGUN,   2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was riddled full of holes by a Machinegun turret%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_MLRS,         2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got turned into smoldering gibs by an MLRS turret%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_PHASER,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was phased out by a turret%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_PLASMA,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got served some superheated plasma from a turret%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_TESLA,        2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was electrocuted by a Tesla turret%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_GUN,     2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got served a lead enrichment by a Walker turret%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_MEELE,   2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was impaled by a Walker turret%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_ROCKET,  2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was blasted away by a Walker turret%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_BUMB_DEATH,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught in the blast of a Bumblebee explosion%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_CRUSH,            2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was crushed by a vehicle%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_RAPT_BOMB,        2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was caught in a Raptor cluster bomb%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_RAPT_DEATH,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught in the blast of a Raptor explosion%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_SPID_DEATH,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught in the blast of a Spiderbot explosion%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_SPID_ROCKET,      2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 was blasted to bits by a Spiderbot rocket%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_WAKI_DEATH,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught in the blast of a Racer explosion%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_WAKI_ROCKET,      2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 couldn't find shelter from a Racer rocket%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VOID,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_void",          _("^BG%s^K1 was in the wrong place%s%s"), "") \
+       MULTITEAM_INFO(1, INFO_DEATH_TEAMKILL_, 4,             3, 1, "s1 s2 s3loc spree_end", "s2 s1",  "notify_teamkill_%s",   _("^BG%s^K1 was betrayed by ^BG%s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_FREEZETAG_FREEZE,               2, 0, "s1 s2", "",                       "",                     _("^BG%s^K1 was frozen by ^BG%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVED,              2, 0, "s1 s2", "",                       "",                     _("^BG%s^K3 was revived by ^BG%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVED_FALL,         1, 0, "s1", "",                          "",                     _("^BG%s^K3 was revived by falling"), "") \
+       MSG_INFO_NOTIF(1, INFO_FREEZETAG_AUTO_REVIVED,         1, 1, "s1 f1", "",                       "",                     _("^BG%s^K3 was automatically revived after %s second(s)"), "") \
+       MULTITEAM_INFO(1, INFO_ROUND_TEAM_WIN_, 4,             0, 0, "", "",                            "",                     _("^TC^TT^BG team wins the round"), "") \
+       MSG_INFO_NOTIF(1, INFO_ROUND_PLAYER_WIN,               1, 0, "s1", "",                          "",                     _("^BG%s^BG wins the round"), "") \
+       MSG_INFO_NOTIF(1, INFO_ROUND_TIED,                     0, 0, "", "",                            "",                     _("^BGRound tied"), "") \
+       MSG_INFO_NOTIF(1, INFO_ROUND_OVER,                     0, 0, "", "",                            "",                     _("^BGRound over, there's no winner"), "") \
+       MSG_INFO_NOTIF(1, INFO_FREEZETAG_SELF,                 1, 0, "s1", "",                          "",                     _("^BG%s^K1 froze themself"), "") \
+       MSG_INFO_NOTIF(1, INFO_GODMODE_OFF,                    0, 1, "f1", "",                          "",                     _("^BGGodmode saved you %s units of damage, cheater!"), "") \
+       MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_DONTHAVE,           0, 1, "item_wepname", "",                      "",               _("^BGYou do not have the ^F1%s"), "") \
+       MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_DROP,               1, 1, "item_wepname item_wepammo", "",         "",               _("^BGYou dropped the ^F1%s^BG%s"), "") \
+       MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_GOT,                0, 1, "item_wepname", "",                      "",               _("^BGYou got the ^F1%s"), "") \
+       MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_NOAMMO,             0, 1, "item_wepname", "",                      "",               _("^BGYou don't have enough ammo for the ^F1%s"), "") \
+       MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_PRIMORSEC,          0, 3, "item_wepname f2primsec f3primsec", "",  "",               _("^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"), "") \
+       MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_UNAVAILABLE,        0, 1, "item_wepname", "",                      "",               _("^F1%s^BG is ^F4not available^BG on this map"), "") \
+       MSG_INFO_NOTIF(2, INFO_JOIN_CONNECT,                   1, 0, "s1", "",                          "",                     _("^BG%s^F3 connected%s"), "") \
+       MULTITEAM_INFO(2, INFO_JOIN_CONNECT_TEAM_, 4,          1, 0, "s1", "",                          "",                     _("^BG%s^F3 connected and joined the ^TC^TT team"), "") \
+       MSG_INFO_NOTIF(1, INFO_JOIN_PLAY,                      1, 0, "s1", "",                          "",                     _("^BG%s^F3 is now playing"), "") \
+       MSG_INFO_NOTIF(1, INFO_KEEPAWAY_DROPPED,               1, 0, "s1", "s1",                        "notify_balldropped",   _("^BG%s^BG has dropped the ball!"), "") \
+       MSG_INFO_NOTIF(1, INFO_KEEPAWAY_PICKUP,                1, 0, "s1", "s1",                        "notify_ballpickedup",  _("^BG%s^BG has picked up the ball!"), "") \
+       MULTITEAM_INFO(1, INFO_KEYHUNT_CAPTURE_, 4,            1, 0, "s1", "",                          "",                     _("^BG%s^BG captured the keys for the ^TC^TT team"), "") \
+       MULTITEAM_INFO(1, INFO_KEYHUNT_DROP_, 4,               1, 0, "s1", "",                          "",                     _("^BG%s^BG dropped the ^TC^TT Key"), "") \
+       MULTITEAM_INFO(1, INFO_KEYHUNT_LOST_, 4,               1, 0, "s1", "",                          "",                     _("^BG%s^BG lost the ^TC^TT Key"), "") \
+       MULTITEAM_INFO(1, INFO_KEYHUNT_PICKUP_, 4,             1, 0, "s1", "",                          "",                     _("^BG%s^BG picked up the ^TC^TT Key"), "") \
+       MSG_INFO_NOTIF(1, INFO_LMS_FORFEIT,                    1, 0, "s1", "",                          "",                     _("^BG%s^F3 forfeited"), "") \
+       MSG_INFO_NOTIF(1, INFO_LMS_NOLIVES,                    1, 0, "s1", "",                          "",                     _("^BG%s^F3 has no more lives left"), "") \
++      MSG_INFO_NOTIF(1, INFO_MONSTERS_DISABLED,                  0, 0, "", "",                            "",                     _("^BGMonsters are currently disabled"), "") \
+       MSG_INFO_NOTIF(1, INFO_POWERUP_INVISIBILITY,           1, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up Invisibility"), "") \
+       MSG_INFO_NOTIF(1, INFO_POWERUP_SHIELD,                 1, 0, "s1", "s1",                        "shield",               _("^BG%s^K1 picked up Shield"), "") \
+       MSG_INFO_NOTIF(1, INFO_POWERUP_SPEED,                  1, 0, "s1", "s1",                        "shield",               _("^BG%s^K1 picked up Speed"), "") \
+       MSG_INFO_NOTIF(1, INFO_POWERUP_STRENGTH,               1, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up Strength"), "") \
+       MSG_INFO_NOTIF(2, INFO_QUIT_DISCONNECT,                1, 0, "s1", "",                          "",                     _("^BG%s^F3 disconnected"), "") \
+       MSG_INFO_NOTIF(2, INFO_QUIT_KICK_IDLING,               1, 0, "s1", "",                          "",                     _("^BG%s^F3 was kicked for idling"), "") \
+       MSG_INFO_NOTIF(1, INFO_QUIT_KICK_SPECTATING,           0, 0, "", "",                            "",                     _("^F2You were kicked from the server because you are a spectator and spectators aren't allowed at the moment."), "") \
+       MSG_INFO_NOTIF(1, INFO_QUIT_SPECTATE,                  1, 0, "s1", "",                          "",                     _("^BG%s^F3 is now spectating"), "") \
+       MSG_INFO_NOTIF(1, INFO_RACE_ABANDONED,                 1, 0, "s1", "",                                                        "",                      _("^BG%s^BG has abandoned the race"), "") \
+       MSG_INFO_NOTIF(1, INFO_RACE_FAIL_RANKED,               1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1",        "race_newfail",          _("^BG%s^BG couldn't break their %s%s^BG place record of %s%s %s"), "") \
+       MSG_INFO_NOTIF(1, INFO_RACE_FAIL_UNRANKED,             1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1",        "race_newfail",          _("^BG%s^BG couldn't break the %s%s^BG place record of %s%s %s"), "") \
+       MSG_INFO_NOTIF(1, INFO_RACE_FINISHED,                  1, 0, "s1", "",                                                        "",                      _("^BG%s^BG has finished the race"), "") \
+       MSG_INFO_NOTIF(1, INFO_RACE_NEW_BROKEN,                2, 3, "s1 s2 race_col f1ord race_col f2race_time race_diff", "s1 s2",  "race_newrankyellow",    _("^BG%s^BG broke %s^BG's %s%s^BG place record with %s%s %s"), "") \
+       MSG_INFO_NOTIF(1, INFO_RACE_NEW_IMPROVED,              1, 3, "s1 race_col f1ord race_col f2race_time race_diff", "s1",        "race_newtime",          _("^BG%s^BG improved their %s%s^BG place record with %s%s %s"), "") \
+       MSG_INFO_NOTIF(1, INFO_RACE_NEW_MISSING_UID,           1, 1, "s1 f1race_time", "s1",                                          "race_newfail",          _("^BG%s^BG scored a new record with ^F2%s^BG, but unfortunately lacks a UID and will be lost."), "") \
+       MSG_INFO_NOTIF(1, INFO_RACE_NEW_SET,                   1, 2, "s1 race_col f1ord race_col f2race_time", "s1",                  "race_newrecordserver",  _("^BG%s^BG set the %s%s^BG place record with %s%s"), "") \
+       MULTITEAM_INFO(1, INFO_SCORES_, 4,                     0, 0, "", "",                            "",                     _("^TC^TT ^BGteam scores!"), "") \
+       MSG_INFO_NOTIF(1, INFO_SPECTATE_WARNING,               0, 1, "f1secs", "",                      "",                     _("^F2You have to become a player within the next %s, otherwise you will be kicked, because spectating isn't allowed at this time!"), "") \
+       MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_PICKUP,             1, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up a Superweapon"), "") \
+       MSG_INFO_NOTIF(2, INFO_VERSION_BETA,                   2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have ^F2Xonotic %s"), "") \
+       MSG_INFO_NOTIF(2, INFO_VERSION_OLD,                    2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s"), "") \
+       MSG_INFO_NOTIF(2, INFO_VERSION_OUTDATED,               2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get the update from ^F3http://www.xonotic.org/^BG!"), "") \
+       MSG_INFO_NOTIF(1, INFO_WATERMARK,                      1, 0, "s1", "",                          "",                     _("^F3SVQC Build information: ^F4%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_ACCORDEON_MURDER,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapontuba",             _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Accordeon%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_ACCORDEON_SUICIDE,             2, 1, "s1 s2loc spree_lost", "s1",                 "weapontuba",             _("^BG%s^K1 hurt their own ears with the @!#%%'n Accordeon%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_CRYLINK_MURDER,                3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponcrylink",          _("^BG%s%s^K1 felt the strong pull of ^BG%s^K1's Crylink%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_CRYLINK_SUICIDE,               2, 1, "s1 s2loc spree_lost", "s1",                 "weaponcrylink",          _("^BG%s^K1 felt the strong pull of their Crylink%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_BOLT,           3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponelectro",          _("^BG%s%s^K1 was blasted by ^BG%s^K1's Electro bolt%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_COMBO,          3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponelectro",          _("^BG%s%s^K1 felt the electrifying air of ^BG%s^K1's Electro combo%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_ORBS,           3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponelectro",          _("^BG%s%s^K1 got too close to ^BG%s^K1's Electro plasma%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_SUICIDE_BOLT,          2, 1, "s1 s2loc spree_lost", "s1",                 "weaponelectro",          _("^BG%s^K1 played with Electro plasma%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_SUICIDE_ORBS,          2, 1, "s1 s2loc spree_lost", "s1",                 "weaponelectro",          _("^BG%s^K1 could not remember where they put their Electro plasma%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_MURDER_BLAST,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponfireball",         _("^BG%s%s^K1 got too close to ^BG%s^K1's fireball%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_MURDER_FIREMINE,      3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponfireball",         _("^BG%s%s^K1 got burnt by ^BG%s^K1's firemine%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_SUICIDE_BLAST,        2, 1, "s1 s2loc spree_lost", "s1",                 "weaponfireball",         _("^BG%s^K1 should have used a smaller gun%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE,     2, 1, "s1 s2loc spree_lost", "s1",                 "weaponfireball",         _("^BG%s^K1 forgot about their firemine%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_MURDER_BURST,            3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponhagar",            _("^BG%s%s^K1 was pummeled by a burst of ^BG%s^K1's Hagar rockets%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_MURDER_SPRAY,            3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponhagar",            _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Hagar rockets%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_SUICIDE,                 2, 1, "s1 s2loc spree_lost", "s1",                 "weaponhagar",            _("^BG%s^K1 played with tiny Hagar rockets%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_HLAC_MURDER,                   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponhlac",             _("^BG%s%s^K1 was cut down with ^BG%s^K1's HLAC%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_HLAC_SUICIDE,                  2, 1, "s1 s2loc spree_lost", "s1",                 "weaponhlac",             _("^BG%s^K1 got a little jumpy with their HLAC%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_HOOK_MURDER,                   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponhook",             _("^BG%s%s^K1 was caught in ^BG%s^K1's Hook gravity bomb%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_KLEINBOTTLE_MURDER,            3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapontuba",             _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Klein Bottle%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_KLEINBOTTLE_SUICIDE,           2, 1, "s1 s2loc spree_lost", "s1",                 "weapontuba",             _("^BG%s^K1 hurt their own ears with the @!#%%'n Klein Bottle%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_LASER_MURDER,                  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponlaser",            _("^BG%s%s^K1 was shot to death by ^BG%s^K1's Laser%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_LASER_SUICIDE,                 2, 1, "s1 s2loc spree_lost", "s1",                 "weaponlaser",            _("^BG%s^K1 shot themself to hell with their Laser%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_MINELAYER_MURDER,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponminelayer",        _("^BG%s%s^K1 got too close to ^BG%s^K1's mine%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_MINELAYER_SUICIDE,             2, 1, "s1 s2loc spree_lost", "s1",                 "weaponminelayer",        _("^BG%s^K1 forgot about their mine%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_MINSTANEX_MURDER,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponminstanex",        _("^BG%s%s^K1 has been vaporized by ^BG%s^K1's Minstanex%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_MURDER_BOUNCE,          3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapongrenadelauncher",  _("^BG%s%s^K1 got too close to ^BG%s^K1's Mortar grenade%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_MURDER_EXPLODE,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapongrenadelauncher",  _("^BG%s%s^K1 ate ^BG%s^K1's Mortar grenade%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_SUICIDE_BOUNCE,         2, 1, "s1 s2loc spree_lost", "s1",                 "weapongrenadelauncher",  _("^BG%s^K1 didn't see their own Mortar grenade%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_SUICIDE_EXPLODE,        2, 1, "s1 s2loc spree_lost", "s1",                 "weapongrenadelauncher",  _("^BG%s^K1 blew themself up with their own Mortar%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_NEX_MURDER,                    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponnex",              _("^BG%s%s^K1 has been vaporized by ^BG%s^K1's Nex%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER,                  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 was sniped with a Rifle by ^BG%s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HAIL,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 died in ^BG%s^K1's Rifle bullet hail%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle bullet hail%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_PIERCING,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrocketlauncher",   _("^BG%s%s^K1 ate ^BG%s^K1's rocket%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrocketlauncher",   _("^BG%s%s^K1 got too close ^BG%s^K1's rocket%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_SUICIDE,        2, 1, "s1 s2loc spree_lost", "s1",                 "weaponrocketlauncher",   _("^BG%s^K1 blew themself up with their Rocketlauncher%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_MURDER_SPRAY,           3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponseeker",           _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Seeker rockets%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_MURDER_TAG,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponseeker",           _("^BG%s%s^K1 was tagged by ^BG%s^K1's Seeker%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_SUICIDE,                2, 1, "s1 s2loc spree_lost", "s1",                 "weaponseeker",           _("^BG%s^K1 played with tiny Seeker rockets%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_SHOTGUN_MURDER,                3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponshotgun",          _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shotgun%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_SHOTGUN_MURDER_SLAP,           3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1",  "notify_melee_shotgun",   _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shotgun%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_THINKING_WITH_PORTALS,         2, 1, "s1 s2loc spree_lost", "s1",                 "notify_selfkill",        _("^BG%s^K1 is now thinking with portals%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_TUBA_MURDER,                   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weapontuba",             _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Tuba%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_TUBA_SUICIDE,                  2, 1, "s1 s2loc spree_lost", "s1",                 "weapontuba",             _("^BG%s^K1 hurt their own ears with the @!#%%'n Tuba%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_UZI_MURDER_SNIPE,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponuzi",              _("^BG%s%s^K1 was sniped by ^BG%s^K1's Machine Gun%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_WEAPON_UZI_MURDER_SPRAY,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponuzi",              _("^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s%s"), "") 
  
  #define MULTITEAM_CENTER(default,prefix,teams,strnum,flnum,args,cpid,durcnt,normal,gentle) \
        MSG_CENTER_NOTIF(default, prefix##RED, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_FALL,                    NO_MSG,        INFO_DEATH_MURDER_FALL,                    NO_MSG) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_FIRE,                    NO_MSG,        INFO_DEATH_MURDER_FIRE,                    NO_MSG) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_LAVA,                    NO_MSG,        INFO_DEATH_MURDER_LAVA,                    NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE,                    NO_MSG,        INFO_DEATH_MURDER_NADE,                   NO_MSG) \
 +      MSG_MULTI_NOTIF(1, DEATH_MURDER_MONSTER,                 NO_MSG,        INFO_DEATH_MURDER_MONSTER,                 CENTER_DEATH_SELF_MONSTER) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE,                    NO_MSG,        INFO_DEATH_MURDER_NADE,                    NO_MSG) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_SHOOTING_STAR,           NO_MSG,        INFO_DEATH_MURDER_SHOOTING_STAR,           NO_MSG) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_SLIME,                   NO_MSG,        INFO_DEATH_MURDER_SLIME,                   NO_MSG) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_SWAMP,                   NO_MSG,        INFO_DEATH_MURDER_SWAMP,                   NO_MSG) \
@@@ -109,13 -109,10 +109,14 @@@ void accuracy_add(entity e, float w, fl
  
  float accuracy_isgooddamage(entity attacker, entity targ)
  {
-       if(!inWarmupStage)
 +      float targ_isvalid = ((g_invasion) ? targ.flags & FL_MONSTER : IS_CLIENT(targ));
 +
+       if(!warmup_stage)
 +      if(targ_isvalid)
 +      if not(attacker.flags & FL_MONSTER) // no accuracy for monsters
+       if(IS_CLIENT(targ))
        if(targ.deadflag == DEAD_NO)
-       if(IsDifferentTeam(attacker, targ))
+       if(DIFF_TEAM(attacker, targ))
                return TRUE;
        return FALSE;
  }
@@@ -168,11 -168,9 +168,11 @@@ void PutObserverInServer (void
  
        Portal_ClearAll(self);
        
 +      Unfreeze(self);
 +      
        if(self.alivetime)
        {
-               if(!inWarmupStage)
+               if(!warmup_stage)
                        PlayerStats_Event(self, PLAYERSTATS_ALIVETIME, time - self.alivetime);
                self.alivetime = 0;
        }
Simple merge
Simple merge
Simple merge
@@@ -800,9 -732,9 +809,9 @@@ void Damage (entity targ, entity inflic
                        else
                                victim = targ;
  
 -                      if(IS_PLAYER(victim) || victim.turrcaps_flags & TFL_TURRCAPS_ISTURRET)
 +                      if(IS_PLAYER(victim) || victim.turrcaps_flags & TFL_TURRCAPS_ISTURRET || victim.flags & FL_MONSTER)
                        {
-                               if(IsDifferentTeam(victim, attacker))
+                               if(DIFF_TEAM(victim, attacker))
                                {
                                        if(damage > 0)
                                        {
Simple merge
Simple merge
@@@ -852,18 -803,18 +814,18 @@@ void ctf_FlagTouch(
        {       
                case FLAG_BASE:
                {
-                       if(!IsDifferentTeam(toucher, self) && (toucher.flagcarried) && IsDifferentTeam(toucher.flagcarried, self) && !(toucher.flags & FL_MONSTER))
 -                      if(SAME_TEAM(toucher, self) && (toucher.flagcarried) && DIFF_TEAM(toucher.flagcarried, self))
++                      if(SAME_TEAM(toucher, self) && (toucher.flagcarried) && DIFF_TEAM(toucher.flagcarried, self) && !(toucher.flags & FL_MONSTER))
                                ctf_Handle_Capture(self, toucher, CAPTURE_NORMAL); // toucher just captured the enemies flag to his base
-                       else if(IsDifferentTeam(toucher, self) && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (time > toucher.next_take_time) && !(toucher.flags & FL_MONSTER))
 -                      else if(DIFF_TEAM(toucher, self) && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (time > toucher.next_take_time))
++                      else if(DIFF_TEAM(toucher, self) && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (time > toucher.next_take_time) && !(toucher.flags & FL_MONSTER))
                                ctf_Handle_Pickup(self, toucher, PICKUP_BASE); // toucher just stole the enemies flag
                        break;
                }
                
                case FLAG_DROPPED:
                {
-                       if(!IsDifferentTeam(toucher, self))
+                       if(SAME_TEAM(toucher, self))
                                ctf_Handle_Return(self, toucher); // toucher just returned his own flag
 -                      else if((!toucher.flagcarried) && ((toucher != self.ctf_dropper) || (time > self.ctf_droptime + autocvar_g_ctf_flag_collect_delay)))
 +                      else if(!(toucher.flags & FL_MONSTER) && (!toucher.flagcarried) && ((toucher != self.ctf_dropper) || (time > self.ctf_droptime + autocvar_g_ctf_flag_collect_delay)))
                                ctf_Handle_Pickup(self, toucher, PICKUP_DROPPED); // toucher just picked up a dropped enemy flag
                        break;
                }
@@@ -406,9 -448,9 +406,9 @@@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPr
                n = 0;
                FOR_EACH_PLAYER(other) if(self != other)
                {
 -                      if(other.freezetag_frozen == 0)
 +                      if(other.frozen == 0)
                        {
-                               if(!IsDifferentTeam(other, self))
 -                              if(other.team == self.team)
++                              if(SAME_TEAM(other, self))
                                {
                                        if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
                                        {
Simple merge
@@@ -38,15 -38,15 +38,15 @@@ float turret_fusionreactor_firecheck(
                return 0;
  
        if (self.ammo < self.shot_dmg)
 -              return 0;
 -
 -      if (self.enemy.ammo >= self.enemy.ammo_max)
 -              return 0;
 +              return 0;       
        
        if (vlen(self.enemy.origin - self.origin) > self.target_range)
 -              return 0;                               
 +              return 0;       
 +      
 +      if (self.enemy.ammo >= self.enemy.ammo_max)
 +              return 0;
        
-       if(IsDifferentTeam(self, self.enemy))
 -      if(self.team != self.enemy.team)
++      if(DIFF_TEAM(self, self.enemy))
                return 0;
        
        if not (self.enemy.ammo_flags & TFL_AMMO_ENERGY)
Simple merge