From: Mario Date: Wed, 6 Feb 2013 23:12:58 +0000 (+1100) Subject: Begin moving LMS to a mutator X-Git-Tag: xonotic-v0.7.0~60^2~12 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=8e4077b8b021cca330c56126f34f412af9d8a476;p=xonotic%2Fxonotic-data.pk3dir.git Begin moving LMS to a mutator --- diff --git a/qcsrc/server/arena.qc b/qcsrc/server/arena.qc index ef81fd92b..a2298c6fb 100644 --- a/qcsrc/server/arena.qc +++ b/qcsrc/server/arena.qc @@ -108,8 +108,6 @@ void reset_map(float dorespawn) //NEW: changed behaviour so that it prevents that previous spectators/observers suddenly spawn as players if (self.classname == "player") { //PlayerScore_Clear(self); - if(g_lms) - PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives()); self.killcount = 0; //stop the player from moving so that he stands still once he gets respawned self.velocity = '0 0 0'; diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index a6bc87f9f..c66e4acef 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -522,14 +522,6 @@ void PutObserverInServer (void) Spawnqueue_Insert(self); } } - else if(g_lms) - { - // Only if the player cannot play at all - if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666) - self.frags = FRAGS_SPECTATOR; - else - self.frags = FRAGS_LMS_LOSER; - } else if(g_ca) { if(self.caplayer) @@ -668,14 +660,6 @@ void PutClientInServer (void) // reset player keys self.itemkeys = 0; - // player is dead and becomes observer - // FIXME fix LMS scoring for new system - if(g_lms) - { - if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0) - self.classname = "observer"; - } - if((g_arena && !self.spawned) || (g_ca && !allowed_to_spawn)) self.classname = "observer"; @@ -1436,7 +1420,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_g_campaign || self.team_forced < 0) { self.classname = "observer"; } else { if(teamplay) @@ -1534,15 +1518,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")); @@ -2703,7 +2678,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); - force_respawn = (g_lms || g_ca || g_cts || autocvar_g_forced_respawn); + force_respawn = (g_ca || g_cts || autocvar_g_forced_respawn); if (self.deadflag == DEAD_DYING) { if(force_respawn) diff --git a/qcsrc/server/cl_weapons.qc b/qcsrc/server/cl_weapons.qc index 4df59a09a..d3d4e0172 100644 --- a/qcsrc/server/cl_weapons.qc +++ b/qcsrc/server/cl_weapons.qc @@ -311,8 +311,6 @@ float W_IsWeaponThrowable(float w) return 0; if (g_weaponarena) return 0; - if (g_lms) - return 0; if (g_ca) return 0; if (g_cts) diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index f77725413..bc049fd79 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -47,9 +47,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; diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index a3eeefb73..faf21c5bc 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -201,24 +201,6 @@ void GiveFrags (entity attacker, entity targ, float f, float deathtype) { f = RunematchHandleFrags(attacker, targ, f); } - else 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; diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 7912b2081..1664e5886 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -1781,24 +1781,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(); diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 7f8931bff..0ac56c001 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -933,7 +933,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) @@ -986,7 +986,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"); @@ -1004,7 +1004,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/base.qh b/qcsrc/server/mutators/base.qh index d90d564b5..21b34c8c9 100644 --- a/qcsrc/server/mutators/base.qh +++ b/qcsrc/server/mutators/base.qh @@ -67,6 +67,10 @@ MUTATOR_HOOKABLE(GiveFragsForKill); entity frag_target; // INPUT, OUTPUT: float frag_score; + +MUTATOR_HOOKABLE(PlayerClearScore); + // called when a player's scores are going to be cleared + // returning TRUE prevents score clearing MUTATOR_HOOKABLE(MatchEnd); // called when the match ends diff --git a/qcsrc/server/mutators/gamemode_lms.qc b/qcsrc/server/mutators/gamemode_lms.qc new file mode 100644 index 000000000..8d336e60e --- /dev/null +++ b/qcsrc/server/mutators/gamemode_lms.qc @@ -0,0 +1,169 @@ +// 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_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; + + return FALSE; +} + +MUTATOR_HOOKFUNCTION(lms_PlayerSpawn) +{ + PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives()); + + // player is dead and becomes observer + // FIXME fix LMS scoring for new system + if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0) + self.classname = "observer"; + + 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; + + 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) +{ + // no items in LMS + return TRUE; +} + +// 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(MakePlayerObserver, lms_RemovePlayer, CBC_ORDER_ANY); + MUTATOR_HOOK(PlayerSpawn, lms_PlayerSpawn, CBC_ORDER_ANY); + MUTATOR_HOOK(ClientConnect, lms_ClientConnect, CBC_ORDER_ANY); + MUTATOR_HOOK(PlayerPreThink, lms_PlayerThink, 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(PlayerClearScore, lms_KeepScore, CBC_ORDER_ANY); + MUTATOR_HOOK(FilterItem, lms_FilterItem, 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 index 000000000..16fda6155 --- /dev/null +++ b/qcsrc/server/mutators/gamemode_lms.qh @@ -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 diff --git a/qcsrc/server/mutators/mutators.qh b/qcsrc/server/mutators/mutators.qh index 4bdcbb282..5dd8037c2 100644 --- a/qcsrc/server/mutators/mutators.qh +++ b/qcsrc/server/mutators/mutators.qh @@ -5,6 +5,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); diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src index f1bdb2443..07bd046fc 100644 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@ -34,6 +34,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 //// @@ -215,6 +216,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 diff --git a/qcsrc/server/scores.qc b/qcsrc/server/scores.qc index 0df5b69af..8f5e3fead 100644 --- a/qcsrc/server/scores.qc +++ b/qcsrc/server/scores.qc @@ -256,7 +256,7 @@ float PlayerScore_Clear(entity player) if(teamscores_entities_count) return 0; - if(g_lms) return 0; + if(MUTATOR_CALLHOOK(PlayerClearScore)) return 0; if(g_arena || g_ca) return 0; if(g_cts) return 0; // in CTS, you don't lose score by observing if(g_race && g_race_qualifying) return 0; // in qualifying, you don't lose score by observing diff --git a/qcsrc/server/scores_rules.qc b/qcsrc/server/scores_rules.qc index 13fd49f29..3f39f455c 100644 --- a/qcsrc/server/scores_rules.qc +++ b/qcsrc/server/scores_rules.qc @@ -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 diff --git a/qcsrc/server/t_items.qc b/qcsrc/server/t_items.qc index bf70da028..1b32596f5 100644 --- a/qcsrc/server/t_items.qc +++ b/qcsrc/server/t_items.qc @@ -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) diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index 1ed2f533b..e473ba1b5 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -160,9 +160,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)