X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fmutators%2Fgamemode_lms.qc;h=65c85f73a6e8eb372dda1cffbda290688522b29e;hb=9dd7ac97faf9fc1548cc3d416cedaeef803e7528;hp=13b77305a25429c78dd95768701167057b7a699e;hpb=37903827937b44f174275a75d2dab5301b8ab53e;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/mutators/gamemode_lms.qc b/qcsrc/server/mutators/gamemode_lms.qc index 13b77305a..65c85f73a 100644 --- a/qcsrc/server/mutators/gamemode_lms.qc +++ b/qcsrc/server/mutators/gamemode_lms.qc @@ -1,3 +1,16 @@ +#include "gamemode_lms.qh" + +#include "gamemode.qh" + +#include "../campaign.qh" +#include "../command/cmd.qh" + +int autocvar_g_lms_extra_lives; +bool autocvar_g_lms_join_anytime; +int autocvar_g_lms_last_join; +#define autocvar_g_lms_lives_override cvar("g_lms_lives_override") +bool autocvar_g_lms_regenerate; + // main functions float LMS_NewPlayerLives() { @@ -18,7 +31,7 @@ float LMS_NewPlayerLives() } // mutator hooks -MUTATOR_HOOKFUNCTION(lms_ResetMap) +MUTATOR_HOOKFUNCTION(lms, reset_map_global) { lms_lowest_lives = 999; lms_next_place = player_count; @@ -26,52 +39,68 @@ MUTATOR_HOOKFUNCTION(lms_ResetMap) return false; } -MUTATOR_HOOKFUNCTION(lms_ResetPlayers) -{ +MUTATOR_HOOKFUNCTION(lms, reset_map_players) +{SELFPARAM(); + entity e; if(restart_mapalreadyrestarted || (time < game_starttime)) - FOR_EACH_CLIENT(self) - if(IS_PLAYER(self)) - PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives()); + FOR_EACH_CLIENT(e) + if(IS_PLAYER(e)) + { + WITH(entity, self, e, PlayerScore_Add(e, SP_LMS_LIVES, LMS_NewPlayerLives())); + } return false; } -MUTATOR_HOOKFUNCTION(lms_PlayerPreSpawn) -{ +MUTATOR_HOOKFUNCTION(lms, PutClientInServer) +{SELFPARAM(); // 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"; + Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_LMS_NOLIVES); + } return false; } -MUTATOR_HOOKFUNCTION(lms_PlayerDies) -{ +MUTATOR_HOOKFUNCTION(lms, PlayerDies) +{SELFPARAM(); self.respawn_flags |= RESPAWN_FORCE; return false; } -MUTATOR_HOOKFUNCTION(lms_RemovePlayer) +void lms_RemovePlayer(entity player) { // Only if the player cannot play at all - if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666) - self.frags = FRAGS_SPECTATOR; + if(PlayerScore_Add(player, SP_LMS_RANK, 0) == 666) + player.frags = FRAGS_SPECTATOR; else - self.frags = FRAGS_LMS_LOSER; + player.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); + if(player.killcount != -666) + if(PlayerScore_Add(player, SP_LMS_RANK, 0) > 0 && player.lms_spectate_warning != 2) + Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_NOLIVES, player.netname); else - Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_FORFEIT, self.netname); + Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_FORFEIT, player.netname); +} +MUTATOR_HOOKFUNCTION(lms, ClientDisconnect) +{SELFPARAM(); + lms_RemovePlayer(self); return false; } -MUTATOR_HOOKFUNCTION(lms_ClientConnect) -{ +MUTATOR_HOOKFUNCTION(lms, MakePlayerObserver) +{SELFPARAM(); + lms_RemovePlayer(self); + return false; +} + +MUTATOR_HOOKFUNCTION(lms, ClientConnect) +{SELFPARAM(); self.classname = "player"; campaign_bots_may_start = 1; @@ -84,28 +113,28 @@ MUTATOR_HOOKFUNCTION(lms_ClientConnect) return false; } -MUTATOR_HOOKFUNCTION(lms_PlayerThink) -{ +MUTATOR_HOOKFUNCTION(lms, PlayerPreThink) +{SELFPARAM(); if(self.deadflag == DEAD_DYING) self.deadflag = DEAD_RESPAWNING; return false; } -MUTATOR_HOOKFUNCTION(lms_PlayerRegen) +MUTATOR_HOOKFUNCTION(lms, PlayerRegen) { if(autocvar_g_lms_regenerate) return false; return true; } -MUTATOR_HOOKFUNCTION(lms_ForbidThrowing) +MUTATOR_HOOKFUNCTION(lms, ForbidThrowCurrentWeapon) { // forbode! return true; } -MUTATOR_HOOKFUNCTION(lms_GiveFragsForKill) +MUTATOR_HOOKFUNCTION(lms, GiveFragsForKill) { // remove a life float tl; @@ -126,7 +155,7 @@ MUTATOR_HOOKFUNCTION(lms_GiveFragsForKill) return true; } -MUTATOR_HOOKFUNCTION(lms_SetStartItems) +MUTATOR_HOOKFUNCTION(lms, SetStartItems) { start_items &= ~IT_UNLIMITED_AMMO; start_health = warmup_start_health = cvar("g_lms_start_health"); @@ -141,16 +170,16 @@ MUTATOR_HOOKFUNCTION(lms_SetStartItems) return false; } -MUTATOR_HOOKFUNCTION(lms_KeepScore) +MUTATOR_HOOKFUNCTION(lms, ForbidPlayerScore_Clear) { // don't clear player score return true; } -MUTATOR_HOOKFUNCTION(lms_FilterItem) -{ +MUTATOR_HOOKFUNCTION(lms, FilterItem) +{SELFPARAM(); if(autocvar_g_lms_extra_lives) - if(self.classname == "item_health_mega") + if(self.itemdef == ITEM_HealthMega) { self.max_health = 1; return false; @@ -159,10 +188,10 @@ MUTATOR_HOOKFUNCTION(lms_FilterItem) return true; } -MUTATOR_HOOKFUNCTION(lms_ItemTouch) -{ +MUTATOR_HOOKFUNCTION(lms, ItemTouch) +{SELFPARAM(); // give extra lives for mega health - if(self.items & IT_HEALTH) + if (self.items & ITEM_HealthMega.m_itemid) { Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_EXTRALIVES); PlayerScore_Add(other, SP_LMS_LIVES, autocvar_g_lms_extra_lives); @@ -171,6 +200,61 @@ MUTATOR_HOOKFUNCTION(lms_ItemTouch) return MUT_ITEMTOUCH_CONTINUE; } +MUTATOR_HOOKFUNCTION(lms, Bot_FixCount, CBC_ORDER_EXCLUSIVE) +{ + entity head; + FOR_EACH_REALCLIENT(head) + { + ++bot_activerealplayers; + ++bot_realplayers; + } + + return true; +} + +MUTATOR_HOOKFUNCTION(lms, ClientCommand_Spectate) +{ + if(self.lms_spectate_warning) + { + // for the forfeit message... + self.lms_spectate_warning = 2; + // mark player as spectator + PlayerScore_Add(self, SP_LMS_RANK, 666 - PlayerScore_Add(self, SP_LMS_RANK, 0)); + } + else + { + self.lms_spectate_warning = 1; + sprint(self, "WARNING: you won't be able to enter the game again after spectating in LMS. Use the same command again to spectate anyway.\n"); + return MUT_SPECCMD_RETURN; + } + return MUT_SPECCMD_CONTINUE; +} + +MUTATOR_HOOKFUNCTION(lms, CheckRules_World) +{ + ret_float = WinningCondition_LMS(); + return true; +} + +MUTATOR_HOOKFUNCTION(lms, WantWeapon) +{ + want_allguns = true; + return false; +} + +MUTATOR_HOOKFUNCTION(lms, GetPlayerStatus) +{ + return true; +} + +MUTATOR_HOOKFUNCTION(lms, AddPlayerScore) +{ + if(gameover) + if(score_field == SP_LMS_RANK) + return true; // allow writing to this field in intermission as it is needed for newly joining players + return false; +} + // scoreboard stuff void lms_ScoreRules() { @@ -188,22 +272,9 @@ void lms_Initialize() lms_ScoreRules(); } -MUTATOR_DEFINITION(gamemode_lms) +REGISTER_MUTATOR(lms, IS_GAMETYPE(LMS)) { - MUTATOR_HOOK(reset_map_global, lms_ResetMap, CBC_ORDER_ANY); - MUTATOR_HOOK(reset_map_players, lms_ResetPlayers, CBC_ORDER_ANY); - MUTATOR_HOOK(PutClientInServer, lms_PlayerPreSpawn, CBC_ORDER_ANY); - MUTATOR_HOOK(PlayerDies, lms_PlayerDies, 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(PlayerRegen, lms_PlayerRegen, 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); + SetLimits(((!autocvar_g_lms_lives_override) ? -1 : autocvar_g_lms_lives_override), 0, -1, -1); MUTATOR_ONADD { @@ -221,7 +292,7 @@ MUTATOR_DEFINITION(gamemode_lms) MUTATOR_ONREMOVE { - print("This is a game type and it cannot be removed at runtime."); + LOG_INFO("This is a game type and it cannot be removed at runtime."); return -1; }