Add some mutator hooks for regen & mob spawning
authorMario <mario.mario@y7mail.com>
Thu, 26 Dec 2013 06:05:03 +0000 (17:05 +1100)
committerMario <mario.mario@y7mail.com>
Thu, 26 Dec 2013 06:05:03 +0000 (17:05 +1100)
12 files changed:
gamemodes.cfg
monsters.cfg
qcsrc/menu/xonotic/dialog_multiplayer_create.c
qcsrc/menu/xonotic/util.qc
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/command/cmd.qc
qcsrc/server/mutators/base.qh
qcsrc/server/mutators/gamemode_ca.qc
qcsrc/server/mutators/gamemode_invasion.qc
qcsrc/server/mutators/gamemode_lms.qc
qcsrc/server/mutators/mutator_minstagib.qc

index d523c88..3fdc64f 100644 (file)
@@ -36,7 +36,7 @@ alias cl_hook_gamestart_nb
 alias cl_hook_gamestart_cts
 alias cl_hook_gamestart_ka
 alias cl_hook_gamestart_ft
-alias cl_hook_gamestart_invasion
+alias cl_hook_gamestart_inv
 alias cl_hook_gameend
 alias cl_hook_activeweapon
 
@@ -57,7 +57,7 @@ alias sv_hook_gamestart_nb
 alias sv_hook_gamestart_cts
 alias sv_hook_gamestart_ka
 alias sv_hook_gamestart_ft
-alias sv_hook_gamestart_invasion
+alias sv_hook_gamestart_inv
 alias sv_hook_gamerestart
 alias sv_hook_gameend
 
index 1448fa7..296d24b 100644 (file)
@@ -80,6 +80,7 @@ set g_monster_shambler_speed_walk 100
 
 // {{{ Misc
 set g_monsters 1
+set g_monsters_edit 0
 set g_monsters_think_delay 0.1
 set g_monsters_skill 1 "Monster skill (affecting some of their attributes). 1 - easy, 2 - medium, 3 - hard, 4 - insane, 5 - nightmare"
 set g_monsters_miniboss_chance 5
index 60f52e1..f3811f5 100644 (file)
@@ -159,6 +159,7 @@ void XonoticServerCreateTab_gameTypeChangeNotify(entity me)
                case MAPINFO_TYPE_ASSAULT:    GameType_ConfigureSliders(e, l, l2, _("Point limit:"),    50,  500, 10, "");                         break;
                case MAPINFO_TYPE_ONSLAUGHT:  GameType_ConfigureSliders(e, l, l2, _("Point limit:"),    50,  500, 10, "");                         break;
                case MAPINFO_TYPE_CTS:        GameType_ConfigureSliders(e, l, l2, _("Point limit:"),    50,  500, 10, "");                         break;
+               case MAPINFO_TYPE_INVASION:   GameType_ConfigureSliders(e, l, l2, _("Point limit:"),     5,    0,  5, "");                         break;
                default:                      GameType_ConfigureSliders(e, l, l2, _("Frag limit:"),      5,  100,  5, "fraglimit_override");       break;
        }
        me.mapListBox.refilter(me.mapListBox);
index 34f6739..40b1220 100644 (file)
@@ -654,6 +654,7 @@ float updateCompression()
        GAMETYPE(MAPINFO_TYPE_RACE) \
        GAMETYPE(MAPINFO_TYPE_CTS) \
        GAMETYPE(MAPINFO_TYPE_TEAM_DEATHMATCH) \
+       //GAMETYPE(MAPINFO_TYPE_INVASION) \
        /* nothing */
 
 float GameType_GetID(float cnt)
index e528bdf..56f6eee 100644 (file)
@@ -1223,6 +1223,7 @@ float autocvar_g_physical_items;
 float autocvar_g_physical_items_damageforcescale;
 float autocvar_g_physical_items_reset;
 float autocvar_g_monsters;
+float autocvar_g_monsters_edit;
 float autocvar_g_monsters_think_delay;
 float autocvar_g_monsters_max;
 float autocvar_g_monsters_max_perplayer;
index 19a1a2e..1497d0a 100644 (file)
@@ -1580,44 +1580,42 @@ float CalcRotRegen(float current, float regenstable, float regenfactor, float re
 
 void player_regen (void)
 {
-       float minh, mina, minf, maxh, maxa, maxf, limith, limita, limitf, max_mod, regen_mod, rot_mod, limit_mod;
-       maxh = autocvar_g_balance_health_rotstable;
-       maxa = autocvar_g_balance_armor_rotstable;
-       maxf = autocvar_g_balance_fuel_rotstable;
-       minh = autocvar_g_balance_health_regenstable;
-       mina = autocvar_g_balance_armor_regenstable;
-       minf = autocvar_g_balance_fuel_regenstable;
-       limith = autocvar_g_balance_health_limit;
-       limita = autocvar_g_balance_armor_limit;
-       limitf = autocvar_g_balance_fuel_limit;
-
-       max_mod = regen_mod = rot_mod = limit_mod = 1;
-
-       maxh = maxh * max_mod;
-       //maxa = maxa * max_mod;
-       //maxf = maxf * max_mod;
-       minh = minh * max_mod;
-       //mina = mina * max_mod;
-       //minf = minf * max_mod;
-       limith = limith * limit_mod;
-       limita = limita * limit_mod;
-       //limitf = limitf * limit_mod;
-
-       if(g_ca || g_invasion)
-               rot_mod = 0;
-
-       if (!g_minstagib && !g_ca && !g_invasion && (!g_lms || autocvar_g_lms_regenerate))
+       if(!MUTATOR_CALLHOOK(PlayerRegen))
        {
+               float minh, mina, maxh, maxa, limith, limita, max_mod, regen_mod, rot_mod, limit_mod;
+               maxh = autocvar_g_balance_health_rotstable;
+               maxa = autocvar_g_balance_armor_rotstable;
+               minh = autocvar_g_balance_health_regenstable;
+               mina = autocvar_g_balance_armor_regenstable;
+               limith = autocvar_g_balance_health_limit;
+               limita = autocvar_g_balance_armor_limit;
+
+               max_mod = regen_mod = rot_mod = limit_mod = 1;
+
+               maxh = maxh * max_mod;
+               minh = minh * max_mod;
+               limith = limith * limit_mod;
+               limita = limita * limit_mod;
+
                self.armorvalue = CalcRotRegen(self.armorvalue, mina, autocvar_g_balance_armor_regen, autocvar_g_balance_armor_regenlinear, regen_mod * frametime * (time > self.pauseregen_finished), maxa, autocvar_g_balance_armor_rot, autocvar_g_balance_armor_rotlinear, rot_mod * frametime * (time > self.pauserotarmor_finished), limita);
                self.health = CalcRotRegen(self.health, minh, autocvar_g_balance_health_regen, autocvar_g_balance_health_regenlinear, regen_mod * frametime * (time > self.pauseregen_finished), maxh, autocvar_g_balance_health_rot, autocvar_g_balance_health_rotlinear, rot_mod * frametime * (time > self.pauserothealth_finished), limith);
-
-               // if player rotted to death...  die!
-               if(self.health < 1)
-                       self.event_damage(self, self, 1, DEATH_ROT, self.origin, '0 0 0');
        }
 
+       // if player rotted to death...  die!
+       // check this outside above checks, as player may still be able to rot to death
+       if(self.health < 1)
+               self.event_damage(self, self, 1, DEATH_ROT, self.origin, '0 0 0');
+
        if (!(self.items & IT_UNLIMITED_WEAPON_AMMO))
-               self.ammo_fuel = CalcRotRegen(self.ammo_fuel, minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear, regen_mod * frametime * (time > self.pauseregen_finished) * ((self.items & IT_FUEL_REGEN) != 0), maxf, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, rot_mod * frametime * (time > self.pauserotfuel_finished), limitf);
+       {
+               float minf, maxf, limitf;
+
+               maxf = autocvar_g_balance_fuel_rotstable;
+               minf = autocvar_g_balance_fuel_regenstable;
+               limitf = autocvar_g_balance_fuel_limit;
+
+               self.ammo_fuel = CalcRotRegen(self.ammo_fuel, minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear, frametime * (time > self.pauseregen_finished) * ((self.items & IT_FUEL_REGEN) != 0), maxf, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, frametime * (time > self.pauserotfuel_finished), limitf);
+       }
 }
 
 float zoomstate_set;
index f5a3719..5264699 100644 (file)
@@ -193,6 +193,7 @@ void ClientCommand_mobedit(float request, float argc)
                                makevectors(self.v_angle);
                                WarpZone_TraceLine(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * 100, MOVE_NORMAL, self);
                                
+                               if(!autocvar_g_monsters_edit) { sprint(self, "Monster property editing is not enabled.\n"); }
                                if(!(trace_ent.flags & FL_MONSTER)) { sprint(self, "You need to aim at your monster to edit its properties.\n"); }
                                else if(trace_ent.realowner != self) { sprint(self, "That monster does not belong to you.\n"); }
                                else // all went well, continue
@@ -286,7 +287,7 @@ void ClientCommand_mobspawn(float request, float argc)
                        if(autocvar_g_monsters_max <= 0 || autocvar_g_monsters_max_perplayer <= 0) { sprint(self, "Monster spawning is disabled.\n"); }
                        else if(!IS_PLAYER(self)) { sprint(self, "You can't spawn monsters while spectating.\n"); }
                        else if(tospawn == "") { sprint(self, "No argument specified.\n"); }
-                       else if(g_invasion) { sprint(self, "You can't spawn monsters during an invasion!\n"); }
+                       else if(MUTATOR_CALLHOOK(AllowMobSpawning)) { sprint(self, "Monster spawning is currently disabled by a mutator.\n"); }
                        else if(!autocvar_g_monsters) { Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_MONSTERS_DISABLED); }
                        else if(self.vehicle) { sprint(self, "You can't spawn monsters while driving a vehicle.\n"); }
                        else if(autocvar_g_campaign) { sprint(self, "You can't spawn monsters in campaign mode.\n"); }
index db15e6b..0d2d7c9 100644 (file)
@@ -186,6 +186,10 @@ MUTATOR_HOOKABLE(MonsterFindTarget);
 MUTATOR_HOOKABLE(MonsterCheckBossFlag);
     // called to change a random monster to a miniboss
 
+MUTATOR_HOOKABLE(AllowMobSpawning);
+       // called when a player tries to spawn a monster
+       // return 1 to prevent spawning
+
 MUTATOR_HOOKABLE(PlayerDamage_SplitHealthArmor);
        // called when a player gets damaged to e.g. remove stuff he was carrying.
        // INPUT:
@@ -215,6 +219,10 @@ MUTATOR_HOOKABLE(PlayerPowerups);
        entity self;
        float olditems; // also technically output, but since it is at the end of the function it's useless for that :P
 
+MUTATOR_HOOKABLE(PlayerRegen);
+       // called every player think frame
+       // return 1 to disable regen
+
 MUTATOR_HOOKABLE(PlayerUseKey);
        // called when the use key is pressed
        // if MUTATOR_RETURNVALUE is 1, don't do anything
index 9fbd483..74a7fd3 100644 (file)
@@ -272,6 +272,12 @@ MUTATOR_HOOKFUNCTION(ca_PlayerDamage_SplitHealthArmor)
        return FALSE;
 }
 
+MUTATOR_HOOKFUNCTION(ca_PlayerRegen)
+{
+       // no regeneration in CA
+       return TRUE;
+}
+
 // scoreboard setup
 void ca_ScoreRules()
 {
@@ -317,6 +323,7 @@ MUTATOR_DEFINITION(gamemode_ca)
        MUTATOR_HOOK(PlayerDamage_Calculate, ca_PlayerDamage, CBC_ORDER_ANY);
        MUTATOR_HOOK(FilterItem, ca_FilterItem, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, ca_PlayerDamage_SplitHealthArmor, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerRegen, ca_PlayerRegen, CBC_ORDER_ANY);
 
        MUTATOR_ONADD
        {
index 593b17f..494afc4 100644 (file)
@@ -230,6 +230,12 @@ MUTATOR_HOOKFUNCTION(invasion_PlayerThink)
        return FALSE;
 }
 
+MUTATOR_HOOKFUNCTION(invasion_PlayerRegen)
+{
+       // no regeneration in invasion
+       return TRUE;
+}
+
 MUTATOR_HOOKFUNCTION(invasion_PlayerSpawn)
 {
        self.bot_attack = FALSE;
@@ -283,6 +289,12 @@ MUTATOR_HOOKFUNCTION(invasion_AccuracyTargetValid)
        return MUT_ACCADD_INDIFFERENT;
 }
 
+MUTATOR_HOOKFUNCTION(invasion_AllowMobSpawning)
+{
+       // monster spawning disabled during an invasion
+       return TRUE;
+}
+
 void invasion_ScoreRules()
 {
        ScoreRules_basics(0, 0, 0, FALSE);
@@ -311,11 +323,13 @@ MUTATOR_DEFINITION(gamemode_invasion)
        MUTATOR_HOOK(MonsterDies, invasion_MonsterDies, CBC_ORDER_ANY);
        MUTATOR_HOOK(MonsterSpawn, invasion_MonsterSpawn, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerPreThink, invasion_PlayerThink, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerRegen, invasion_PlayerRegen, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerSpawn, invasion_PlayerSpawn, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerDamage_Calculate, invasion_PlayerDamage, CBC_ORDER_ANY);
        MUTATOR_HOOK(SV_ParseClientCommand, invasion_PlayerCommand, CBC_ORDER_ANY);
        MUTATOR_HOOK(SetStartItems, invasion_SetStartItems, CBC_ORDER_ANY);
        MUTATOR_HOOK(AccuracyTargetValid, invasion_AccuracyTargetValid, CBC_ORDER_ANY);
+       MUTATOR_HOOK(AllowMobSpawning, invasion_AllowMobSpawning, CBC_ORDER_ANY);
 
        MUTATOR_ONADD
        {
index 928c78b..6092d52 100644 (file)
@@ -92,6 +92,13 @@ MUTATOR_HOOKFUNCTION(lms_PlayerThink)
        return FALSE;
 }
 
+MUTATOR_HOOKFUNCTION(lms_PlayerRegen)
+{
+       if(autocvar_g_lms_regenerate)
+               return FALSE;
+       return TRUE;
+}
+
 MUTATOR_HOOKFUNCTION(lms_ForbidThrowing)
 {
        // forbode!
@@ -189,6 +196,7 @@ MUTATOR_DEFINITION(gamemode_lms)
        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);
index 1b7e03b..6cce152 100644 (file)
@@ -151,6 +151,12 @@ MUTATOR_HOOKFUNCTION(minstagib_PlayerPreThink)
        return FALSE;
 }
 
+MUTATOR_HOOKFUNCTION(minstagib_PlayerRegen)
+{
+       // no regeneration in minstagib
+       return TRUE;
+}
+
 MUTATOR_HOOKFUNCTION(minstagib_PlayerPowerups)
 {
        if (!(self.effects & EF_FULLBRIGHT))
@@ -446,6 +452,7 @@ MUTATOR_DEFINITION(mutator_minstagib)
        MUTATOR_HOOK(PlayerPowerups, minstagib_PlayerPowerups, CBC_ORDER_ANY);
        MUTATOR_HOOK(ForbidThrowCurrentWeapon, minstagib_ForbidThrowing, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerPreThink, minstagib_PlayerPreThink, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerRegen, minstagib_PlayerRegen, CBC_ORDER_ANY);
        MUTATOR_HOOK(OnEntityPreSpawn, minstagib_OnEntityPreSpawn, CBC_ORDER_ANY);
        MUTATOR_HOOK(BuildMutatorsString, minstagib_BuildMutatorsString, CBC_ORDER_ANY);
        MUTATOR_HOOK(BuildMutatorsPrettyString, minstagib_BuildMutatorsPrettyString, CBC_ORDER_ANY);