]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge remote-tracking branch 'origin/master' into Mario/lms_updates
authorSamual Lenks <samual@xonotic.org>
Tue, 7 May 2013 05:37:55 +0000 (01:37 -0400)
committerSamual Lenks <samual@xonotic.org>
Tue, 7 May 2013 05:37:55 +0000 (01:37 -0400)
Conflicts:
qcsrc/server/arena.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_weapons.qc
qcsrc/server/scores.qc

17 files changed:
gamemodes.cfg
qcsrc/common/notifications.qh
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/cl_weapons.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/gamemode_lms.qc [new file with mode: 0644]
qcsrc/server/mutators/gamemode_lms.qh [new file with mode: 0644]
qcsrc/server/mutators/mutators.qh
qcsrc/server/progs.src
qcsrc/server/scores.qc
qcsrc/server/scores_rules.qc
qcsrc/server/t_items.qc
qcsrc/server/teamplay.qc

index 6913ac666c42bede94167a4d254d4b367888cee1..b7e65c8eb8fb9aa734bf0a11f2d7b688915ca5b1 100644 (file)
@@ -341,6 +341,7 @@ set g_keyhunt_teams 0
 // ===================
 set g_lms 0 "Last Man Standing: everyone starts with a certain amount of lives, and the survivor wins"
 set g_lms_lives_override -1
+set g_lms_extra_lives 0
 set g_lms_regenerate 0
 set g_lms_campcheck_interval 10
 set g_lms_campcheck_damage 100
index 171be6a72d9ccc401221bfc95a1970cfda4bf8fc..d1aeba001e5e2f6a4c36c5d03a8c1f2f8117febd 100644 (file)
@@ -496,6 +496,7 @@ void Send_Notification_WOVA(
        MSG_CENTER_NOTIF(1, CENTER_DEATH_TEAMKILL_FRAG,         1, 0, "s1",           NO_CPID,             "0 0", _("^K1Moron! You fragged ^BG%s^K1, a team mate!"), _("^K1Moron! You went against ^BG%s^K1, a team mate!")) \
        MSG_CENTER_NOTIF(1, CENTER_DEATH_TEAMKILL_FRAGGED,      1, 0, "s1",           NO_CPID,             "0 0", _("^K1You were fragged by ^BG%s^K1, a team mate"), _("^K1You were scored against by ^BG%s^K1, a team mate")) \
        MSG_CENTER_NOTIF(1, CENTER_DISCONNECT_IDLING,           0, 1, "",             CPID_IDLING,         "1 f1", _("^K1Stop idling!\n^BGDisconnecting in ^COUNT..."), "") \
+       MSG_CENTER_NOTIF(1, CENTER_EXTRALIVES,                          0, 0, "",             NO_CPID,             "0 0", _("^F2You picked up some extra lives"), "") \
        MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FREEZE,            1, 0, "s1",           NO_CPID,             "0 0", _("^K3You froze ^BG%s"), "") \
        MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FROZEN,            1, 0, "s1",           NO_CPID,             "0 0", _("^K1You were frozen by ^BG%s"), "") \
        MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVE,            1, 0, "s1",           NO_CPID,             "0 0", _("^K3You revived ^BG%s"), "") \
index ad8157a9df4a3e918a85cada0c69df40acea7b5b..bfc362caff91a1e9f630248669fce9d41bba8d50 100644 (file)
@@ -868,6 +868,7 @@ float autocvar_g_keyhunt_teams;
 float autocvar_g_keyhunt_teams_override;
 float autocvar_g_lms_campcheck_damage;
 float autocvar_g_lms_campcheck_distance;
+float autocvar_g_lms_extra_lives;
 float autocvar_g_lms_campcheck_interval;
 float autocvar_g_lms_join_anytime;
 float autocvar_g_lms_last_join;
index 5d29bf7e1537e4099fba46418a467cb2bde7cb57..2f9c0d8312fae7091b9570070db75e7b405a71c8 100644 (file)
@@ -424,13 +424,9 @@ void PutObserverInServer (void)
        if not(g_ca)  // don't reset teams when moving a ca player to the spectators
                self.team = -1;  // move this as it is needed to log the player spectating in eventlog
 
-       if(self.killcount != -666) {
-               if(g_lms) {
-                       if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0 && self.lms_spectate_warning != 2)
-                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_NOLIVES, self.netname);
-                       else
-                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_FORFEIT, self.netname);
-               } else { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_SPECTATE, self.netname); }
+       if(self.killcount != -666)
+       {
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_SPECTATE, self.netname);
 
                if(self.just_joined == FALSE) {
                        LogTeamchange(self.playerid, -1, 4);
@@ -1363,7 +1359,7 @@ void ClientConnect (void)
 
        JoinBestTeam(self, FALSE, FALSE); // if the team number is valid, keep it
 
-       if((autocvar_sv_spectate == 1 && !g_lms) || autocvar_g_campaign || self.team_forced < 0) {
+       if((autocvar_sv_spectate == 1) || autocvar_g_campaign || self.team_forced < 0) {
                self.classname = "observer";
        } else {
                if(teamplay)
@@ -1458,15 +1454,6 @@ void ClientConnect (void)
                        stuffcmd(self, "cl_cmd settemp chase_active 1\n");
        }
 
-       if(g_lms)
-       {
-               if(PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives()) <= 0)
-               {
-                       PlayerScore_Add(self, SP_LMS_RANK, 666);
-                       self.frags = FRAGS_SPECTATOR;
-               }
-       }
-
        if(!sv_foginterval && world.fog != "")
                stuffcmd(self, strcat("\nfog ", world.fog, "\nr_fog_exp2 0\nr_drawfog 1\n"));
 
@@ -2583,7 +2570,7 @@ void PlayerPreThink (void)
                                if(frametime)
                                        player_anim();
                                button_pressed = (self.BUTTON_ATCK || self.BUTTON_JUMP || self.BUTTON_ATCK2 || self.BUTTON_HOOK || self.BUTTON_USE);
-
+                               
                                if (self.deadflag == DEAD_DYING)
                                {
                                        if(self.respawn_flags & RESPAWN_FORCE)
@@ -2625,39 +2612,6 @@ void PlayerPreThink (void)
                        return;
                }
 
-               if(g_lms && !self.deadflag && autocvar_g_lms_campcheck_interval)
-               {
-                       vector dist;
-
-                       // calculate player movement (in 2 dimensions only, so jumping on one spot doesn't count as movement)
-                       dist = self.prevorigin - self.origin;
-                       dist_z = 0;
-                       self.lms_traveled_distance += fabs(vlen(dist));
-
-                       if((autocvar_g_campaign && !campaign_bots_may_start) || (time < game_starttime))
-                       {
-                               self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval*2;
-                               self.lms_traveled_distance = 0;
-                       }
-
-                       if(time > self.lms_nextcheck)
-                       {
-                               //sprint(self, "distance: ", ftos(self.lms_traveled_distance), "\n");
-                               if(self.lms_traveled_distance < autocvar_g_lms_campcheck_distance)
-                               {
-                                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_LMS_CAMPCHECK);
-                                       // FIXME KadaverJack: gibbing player here causes playermodel to bounce around, instead of eye.md3
-                                       // I wasn't able to find out WHY that happens, so I put a workaround in place that shall prevent players from being gibbed :(
-                                       if(self.vehicle)
-                                               Damage(self.vehicle, self, self, autocvar_g_lms_campcheck_damage * 2, DEATH_CAMP, self.vehicle.origin, '0 0 0');
-                                       else
-                                               Damage(self, self, self, bound(0, autocvar_g_lms_campcheck_damage, self.health + self.armorvalue * autocvar_g_balance_armor_blockpercent + 5), DEATH_CAMP, self.origin, '0 0 0');
-                               }
-                               self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval;
-                               self.lms_traveled_distance = 0;
-                       }
-               }
-
                self.prevorigin = self.origin;
 
                float do_crouch = self.BUTTON_CROUCH;
index 57b1cf4f4d19b08d54563271ba5d6257ae7aaebf..0014e9182d4f4c864559af9f5982902dbc37efcb 100644 (file)
@@ -301,8 +301,6 @@ float W_IsWeaponThrowable(float w)
                return 0;
        if (g_weaponarena)
                return 0;
-       if (g_lms)
-               return 0;
        if (g_cts)
                return 0;
        if (g_nexball && w == WEP_GRENADE_LAUNCHER)
index c5720daf3a8358d90aa1c26a7f09e3375930bf80..fb93b7c7876b3d133d4f5b30b2daa872b56e4aa8 100644 (file)
@@ -46,9 +46,6 @@ entity        activator;
 float player_count;
 float currentbots;
 float bots_would_leave;
-float lms_lowest_lives;
-float lms_next_place;
-float LMS_NewPlayerLives();
 
 void UpdateFrags(entity player, float f);
 .float totalfrags;
index 16a6a04afa6d22fa659a1eda9ff030fcd42a8787..6687f18ebc24064cf023faaa1c9a6b766cdb9396 100644 (file)
@@ -182,24 +182,6 @@ void GiveFrags (entity attacker, entity targ, float f, float deathtype)
        else
        {
                self = oldself;
-               if(g_lms)
-               {
-                       // remove a life
-                       float tl;
-                       tl = PlayerScore_Add(targ, SP_LMS_LIVES, -1);
-                       if(tl < lms_lowest_lives)
-                               lms_lowest_lives = tl;
-                       if(tl <= 0)
-                       {
-                               if(!lms_next_place)
-                                       lms_next_place = player_count;
-                               else
-                                       lms_next_place = min(lms_next_place, player_count);
-                               PlayerScore_Add(targ, SP_LMS_RANK, lms_next_place); // won't ever spawn again
-                               --lms_next_place;
-                       }
-                       f = 0;
-               }
        }
 
        attacker.totalfrags += f;
@@ -695,14 +677,6 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                        }
                }
 
-               if(targ.classname == "player")
-               if(attacker.classname == "player")
-               if(attacker != targ)
-               {
-                       targ.lms_traveled_distance = autocvar_g_lms_campcheck_distance;
-                       attacker.lms_traveled_distance = autocvar_g_lms_campcheck_distance;
-               }
-
                if(targ.classname == "player")
                if (g_minstagib)
                {
index d8ce88cf3ce082f631dde1a28b08e76e75e5d28b..1af52b13209eea54f3d915f1a1992a1c0b12cc6f 100644 (file)
@@ -1758,24 +1758,6 @@ float WinningCondition_Onslaught()
        return WINNING_NO;
 }
 
-float LMS_NewPlayerLives()
-{
-       float fl;
-       fl = autocvar_fraglimit;
-       if(fl == 0)
-               fl = 999;
-
-       // first player has left the game for dying too much? Nobody else can get in.
-       if(lms_lowest_lives < 1)
-               return 0;
-
-       if(!autocvar_g_lms_join_anytime)
-               if(lms_lowest_lives < fl - autocvar_g_lms_last_join)
-                       return 0;
-
-       return bound(1, lms_lowest_lives, fl);
-}
-
 // Assault winning condition: If the attackers triggered a round end (by fulfilling all objectives)
 // they win. Otherwise the defending team wins once the timelimit passes.
 void assault_new_round();
index fa8be67fe04bdcae11117eec41683166b2a74ae0..13eb647dbdeb36d83aeebb371d88a44e4bcef1f4 100644 (file)
@@ -750,7 +750,7 @@ void readplayerstartcvars()
        s = cvar_string("g_weaponarena");
        if (s == "0" || s == "")
        {
-               if(g_lms || g_ca)
+               if(g_ca)
                        s = "most";
        }
 
@@ -828,7 +828,7 @@ void readplayerstartcvars()
                g_pinata = 0; // incompatible
                g_weapon_stay = 0; // incompatible
                WEPSET_COPY_AA(start_weapons, g_weaponarena_weapons);
-               if(!(g_lms || g_ca))
+               if(!g_ca)
                        start_items |= IT_UNLIMITED_AMMO;
        }
        else if (g_minstagib)
@@ -881,7 +881,7 @@ void readplayerstartcvars()
        }
        else
        {
-               if(g_lms || g_ca)
+               if(g_ca)
                {
                        start_ammo_shells = cvar("g_lms_start_ammo_shells");
                        start_ammo_nails = cvar("g_lms_start_ammo_nails");
@@ -899,7 +899,7 @@ void readplayerstartcvars()
                }
        }
 
-       if (g_lms || g_ca)
+       if (g_ca)
        {
                start_health = cvar("g_lms_start_health");
                start_armorvalue = cvar("g_lms_start_armor");
diff --git a/qcsrc/server/mutators/gamemode_lms.qc b/qcsrc/server/mutators/gamemode_lms.qc
new file mode 100644 (file)
index 0000000..681a1d4
--- /dev/null
@@ -0,0 +1,249 @@
+// main functions
+float LMS_NewPlayerLives()
+{
+       float fl;
+       fl = autocvar_fraglimit;
+       if(fl == 0)
+               fl = 999;
+
+       // first player has left the game for dying too much? Nobody else can get in.
+       if(lms_lowest_lives < 1)
+               return 0;
+
+       if(!autocvar_g_lms_join_anytime)
+               if(lms_lowest_lives < fl - autocvar_g_lms_last_join)
+                       return 0;
+
+       return bound(1, lms_lowest_lives, fl);
+}
+
+// mutator hooks
+MUTATOR_HOOKFUNCTION(lms_PlayerSpawn)
+{
+       if(IS_PLAYER(self))
+       if(restart_mapalreadyrestarted || (time < game_starttime))
+               PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives());
+               
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_RemovePlayer)
+{
+       // Only if the player cannot play at all
+       if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666)
+               self.frags = FRAGS_SPECTATOR;
+       else
+               self.frags = FRAGS_LMS_LOSER;
+               
+       if(self.killcount != -666)
+               if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0 && self.lms_spectate_warning != 2)
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_NOLIVES, self.netname);
+               else
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_FORFEIT, self.netname);
+               
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_ClientConnect)
+{
+       self.classname = "player";
+       campaign_bots_may_start = 1;
+       
+       if(PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives()) <= 0)
+       {
+               PlayerScore_Add(self, SP_LMS_RANK, 666);
+               self.frags = FRAGS_SPECTATOR;
+       }
+                       
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_PlayerThink)
+{
+       if(self.deadflag == DEAD_DYING)
+               self.deadflag = DEAD_RESPAWNING;
+               
+       if not(self.deadflag)
+       if(autocvar_g_lms_campcheck_interval)
+       {
+               vector dist;
+
+               // calculate player movement (in 2 dimensions only, so jumping on one spot doesn't count as movement)
+               dist = self.prevorigin - self.origin;
+               dist_z = 0;
+               self.lms_traveled_distance += fabs(vlen(dist));
+
+               if((autocvar_g_campaign && !campaign_bots_may_start) || (time < game_starttime))
+               {
+                       self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval*2;
+                       self.lms_traveled_distance = 0;
+               }
+
+               if(time > self.lms_nextcheck)
+               {
+                       if(self.lms_traveled_distance < autocvar_g_lms_campcheck_distance)
+                       {
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_LMS_CAMPCHECK);
+                               if(self.vehicle)
+                                       Damage(self.vehicle, self, self, autocvar_g_lms_campcheck_damage * 2, DEATH_CAMP, self.vehicle.origin, '0 0 0');
+                               else
+                                       Damage(self, self, self, bound(0, autocvar_g_lms_campcheck_damage, self.health + self.armorvalue * autocvar_g_balance_armor_blockpercent + 5), DEATH_CAMP, self.origin, '0 0 0');
+                       }
+                       self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval;
+                       self.lms_traveled_distance = 0;
+               }
+       }
+               
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_PlayerDamage)
+{
+       if(IS_PLAYER(frag_target))
+       if(IS_PLAYER(frag_attacker))
+       if(frag_attacker != frag_target)
+       {
+               frag_target.lms_traveled_distance = autocvar_g_lms_campcheck_distance;
+               frag_attacker.lms_traveled_distance = autocvar_g_lms_campcheck_distance;
+       }
+               
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_ForbidThrowing)
+{
+       // forbode!
+       return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_GiveFragsForKill)
+{
+       // remove a life
+       float tl;
+       tl = PlayerScore_Add(frag_target, SP_LMS_LIVES, -1);
+       if(tl < lms_lowest_lives)
+               lms_lowest_lives = tl;
+       if(tl <= 0)
+       {
+               if(!lms_next_place)
+                       lms_next_place = player_count;
+               else
+                       lms_next_place = min(lms_next_place, player_count);
+               PlayerScore_Add(frag_target, SP_LMS_RANK, lms_next_place); // won't ever spawn again
+               --lms_next_place;
+       }
+       frag_score = 0;
+               
+       return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_SetStartItems)
+{
+       start_items &~= IT_UNLIMITED_AMMO;
+       start_ammo_shells = cvar("g_lms_start_ammo_shells");
+       start_ammo_nails = cvar("g_lms_start_ammo_nails");
+       start_ammo_rockets = cvar("g_lms_start_ammo_rockets");
+       start_ammo_cells = cvar("g_lms_start_ammo_cells");
+       start_ammo_fuel = cvar("g_lms_start_ammo_fuel");
+       start_health = cvar("g_lms_start_health");
+       start_armorvalue = cvar("g_lms_start_armor");
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_KeepScore)
+{
+       // don't clear player score
+       return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_FilterItem)
+{
+       if(autocvar_g_lms_extra_lives)
+       if(self.classname == "item_health_mega")
+       {
+               self.max_health = 1;
+               return FALSE;
+       }
+       
+       return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_ItemTouch)
+{
+       // give extra lives for mega health
+       if(self.items & IT_HEALTH)
+       {
+               Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_EXTRALIVES);
+               PlayerScore_Add(other, SP_LMS_LIVES, autocvar_g_lms_extra_lives);
+       }
+       
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_BotSpawn)
+{
+       // temporary hack to give bots lives
+       if(PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives()) <= 0)
+       {
+               PlayerScore_Add(self, SP_LMS_RANK, 666);
+               self.frags = FRAGS_SPECTATOR;
+       }
+       
+       return FALSE;
+}
+
+// scoreboard stuff
+void lms_ScoreRules()
+{
+       ScoreRules_basics(0, 0, 0, FALSE);
+       ScoreInfo_SetLabel_PlayerScore(SP_LMS_LIVES,    "lives",     SFL_SORT_PRIO_SECONDARY);
+       ScoreInfo_SetLabel_PlayerScore(SP_LMS_RANK,     "rank",      SFL_LOWER_IS_BETTER | SFL_RANK | SFL_SORT_PRIO_PRIMARY | SFL_ALLOW_HIDE);
+       ScoreRules_basics_end();
+}
+
+void lms_Initialize()
+{
+       lms_lowest_lives = 9999;
+       lms_next_place = 0;
+       
+       lms_ScoreRules();
+}
+
+MUTATOR_DEFINITION(gamemode_lms)
+{
+       MUTATOR_HOOK(PlayerSpawn, lms_PlayerSpawn, CBC_ORDER_ANY);
+       MUTATOR_HOOK(MakePlayerObserver, lms_RemovePlayer, CBC_ORDER_ANY);
+       MUTATOR_HOOK(ClientConnect, lms_ClientConnect, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerPreThink, lms_PlayerThink, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerDamage_Calculate, lms_PlayerDamage, CBC_ORDER_ANY);
+       MUTATOR_HOOK(ForbidThrowCurrentWeapon, lms_ForbidThrowing, CBC_ORDER_ANY);
+       MUTATOR_HOOK(GiveFragsForKill, lms_GiveFragsForKill, CBC_ORDER_ANY);
+       MUTATOR_HOOK(SetStartItems, lms_SetStartItems, CBC_ORDER_ANY);
+       MUTATOR_HOOK(ForbidPlayerScore_Clear, lms_KeepScore, CBC_ORDER_ANY);
+       MUTATOR_HOOK(FilterItem, lms_FilterItem, CBC_ORDER_ANY);
+       MUTATOR_HOOK(ItemTouch, lms_ItemTouch, CBC_ORDER_ANY);
+       MUTATOR_HOOK(HavocBot_ChooseRule, lms_BotSpawn, CBC_ORDER_ANY);
+
+       MUTATOR_ONADD
+       {
+               if(time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               lms_Initialize();
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back lms_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               print("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
diff --git a/qcsrc/server/mutators/gamemode_lms.qh b/qcsrc/server/mutators/gamemode_lms.qh
new file mode 100644 (file)
index 0000000..16fda61
--- /dev/null
@@ -0,0 +1,8 @@
+// scoreboard stuff
+#define SP_LMS_LIVES 4
+#define SP_LMS_RANK 5
+
+// lives related defs
+float lms_lowest_lives;
+float lms_next_place;
+float LMS_NewPlayerLives();
\ No newline at end of file
index 7665cc873d86a63cb67e1854145203ba3c9231b0..9c139f0e97d5042acdc076b7c03409fb135b2034 100644 (file)
@@ -7,6 +7,7 @@ MUTATOR_DECLARATION(gamemode_ctf);
 MUTATOR_DECLARATION(gamemode_nexball);
 MUTATOR_DECLARATION(gamemode_onslaught);
 MUTATOR_DECLARATION(gamemode_domination);
+MUTATOR_DECLARATION(gamemode_lms);
 
 MUTATOR_DECLARATION(mutator_dodging);
 MUTATOR_DECLARATION(mutator_invincibleprojectiles);
index edef590d0d7600585852576fea42923efe8f7e98..28736e6cdb279f2ff0ee8762b8520f18cc7018ba 100644 (file)
@@ -42,6 +42,7 @@ mutators/gamemode_domination.qh
 mutators/gamemode_keyhunt.qh // TODO fix this
 mutators/gamemode_keepaway.qh
 mutators/gamemode_nexball.qh 
+mutators/gamemode_lms.qh
 mutators/mutator_dodging.qh
 
 //// tZork Turrets ////
@@ -228,6 +229,7 @@ mutators/gamemode_keyhunt.qc
 mutators/gamemode_keepaway.qc
 mutators/gamemode_nexball.qc
 mutators/gamemode_onslaught.qc
+mutators/gamemode_lms.qc
 mutators/mutator_invincibleproj.qc
 mutators/mutator_new_toys.qc
 mutators/mutator_nix.qc
index 4c75c9850a510948077c5ad018336c13535ebee7..ad10fa5d53accf9baa0e4791a96215acc0bf691c 100644 (file)
@@ -257,7 +257,7 @@ float PlayerScore_Clear(entity player)
                return 0;
 
        if(MUTATOR_CALLHOOK(ForbidPlayerScore_Clear)) return 0;
-       if(g_lms) return 0;
+
        if(g_cts) return 0; // in CTS, you don't lose score by observing
        if(g_race && g_race_qualifying) return 0; // in qualifying, you don't lose score by observing
 
index 13fd49f29bf58e72a57ca3514b2f19103fc0d0bf..3f39f455c56c6f70d0813564e229b9d8d83c87aa 100644 (file)
@@ -44,17 +44,6 @@ void ScoreRules_generic()
        ScoreRules_basics_end();
 }
 
-// LMS stuff
-#define SP_LMS_LIVES 4
-#define SP_LMS_RANK 5
-void ScoreRules_lms()
-{
-       ScoreRules_basics(0, 0, 0, FALSE);
-       ScoreInfo_SetLabel_PlayerScore(SP_LMS_LIVES,    "lives",     SFL_SORT_PRIO_SECONDARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_LMS_RANK,     "rank",      SFL_LOWER_IS_BETTER | SFL_RANK | SFL_SORT_PRIO_PRIMARY | SFL_ALLOW_HIDE);
-       ScoreRules_basics_end();
-}
-
 // Key hunt stuff
 #define ST_KH_CAPS 1
 #define SP_KH_CAPS 4
index 392c05ce14f3e9b9ac0671b662e510adf34393fd..40abd18b135fe920265d197357927a458308f990 100644 (file)
@@ -282,8 +282,6 @@ float have_pickup_item(void)
                        return TRUE;
                if(autocvar_g_powerups == 0)
                        return FALSE;
-               if(g_lms)
-                       return FALSE;
                if(g_ca)
                        return FALSE;
                if(g_arena)
@@ -295,8 +293,6 @@ float have_pickup_item(void)
                        return TRUE;
                if(autocvar_g_pickup_items == 0)
                        return FALSE;
-               if(g_lms)
-                       return FALSE;
                if(g_ca)
                        return FALSE;
                if(g_weaponarena)
@@ -657,7 +653,7 @@ float Item_GiveTo(entity item, entity player)
                        // sound not available
                        // AnnounceTo(player, "_lives");
                        player.armorvalue = bound(player.armorvalue, 999, player.armorvalue + autocvar_g_minstagib_extralives);
-                       sprint(player, "^3You picked up some extra lives\n");
+                       Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_EXTRALIVES);
                }
 
                // invis powerup
index e307489909d2605e5184d2f7545a68ae84bd9241..3d7970297fd6f010923d73b020bb4fa13220fa1d 100644 (file)
@@ -112,9 +112,7 @@ void InitGameplayMode()
                leadlimit_override = 0; // not supported by LMS
                if(fraglimit_override == 0)
                        fraglimit_override = -1;
-               lms_lowest_lives = 9999;
-               lms_next_place = 0;
-               ScoreRules_lms();
+               MUTATOR_ADD(gamemode_lms);
        }
 
        if(g_arena)