From: Mario Date: Thu, 26 Dec 2013 06:05:03 +0000 (+1100) Subject: Add some mutator hooks for regen & mob spawning X-Git-Tag: xonotic-v0.8.0~241^2^2~12 X-Git-Url: https://de.git.xonotic.org/?a=commitdiff_plain;h=a645a7ec4f9bbd8b46a2b5cc351eec004bc83773;p=xonotic%2Fxonotic-data.pk3dir.git Add some mutator hooks for regen & mob spawning --- diff --git a/gamemodes.cfg b/gamemodes.cfg index d523c88ee..3fdc64fb4 100644 --- a/gamemodes.cfg +++ b/gamemodes.cfg @@ -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 diff --git a/monsters.cfg b/monsters.cfg index 1448fa7ed..296d24b19 100644 --- a/monsters.cfg +++ b/monsters.cfg @@ -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 diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create.c b/qcsrc/menu/xonotic/dialog_multiplayer_create.c index 60f52e1fa..f3811f5b9 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_create.c +++ b/qcsrc/menu/xonotic/dialog_multiplayer_create.c @@ -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); diff --git a/qcsrc/menu/xonotic/util.qc b/qcsrc/menu/xonotic/util.qc index 34f67397e..40b1220da 100644 --- a/qcsrc/menu/xonotic/util.qc +++ b/qcsrc/menu/xonotic/util.qc @@ -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) diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index e528bdfdb..56f6eee12 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -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; diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 19a1a2e85..1497d0ab1 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -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; diff --git a/qcsrc/server/command/cmd.qc b/qcsrc/server/command/cmd.qc index f5a37191d..5264699a1 100644 --- a/qcsrc/server/command/cmd.qc +++ b/qcsrc/server/command/cmd.qc @@ -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"); } diff --git a/qcsrc/server/mutators/base.qh b/qcsrc/server/mutators/base.qh index db15e6bae..0d2d7c96a 100644 --- a/qcsrc/server/mutators/base.qh +++ b/qcsrc/server/mutators/base.qh @@ -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 diff --git a/qcsrc/server/mutators/gamemode_ca.qc b/qcsrc/server/mutators/gamemode_ca.qc index 9fbd483ca..74a7fd38a 100644 --- a/qcsrc/server/mutators/gamemode_ca.qc +++ b/qcsrc/server/mutators/gamemode_ca.qc @@ -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 { diff --git a/qcsrc/server/mutators/gamemode_invasion.qc b/qcsrc/server/mutators/gamemode_invasion.qc index 593b17fd3..494afc48b 100644 --- a/qcsrc/server/mutators/gamemode_invasion.qc +++ b/qcsrc/server/mutators/gamemode_invasion.qc @@ -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 { diff --git a/qcsrc/server/mutators/gamemode_lms.qc b/qcsrc/server/mutators/gamemode_lms.qc index 928c78b34..6092d52b9 100644 --- a/qcsrc/server/mutators/gamemode_lms.qc +++ b/qcsrc/server/mutators/gamemode_lms.qc @@ -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); diff --git a/qcsrc/server/mutators/mutator_minstagib.qc b/qcsrc/server/mutators/mutator_minstagib.qc index 1b7e03be3..6cce15211 100644 --- a/qcsrc/server/mutators/mutator_minstagib.qc +++ b/qcsrc/server/mutators/mutator_minstagib.qc @@ -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);