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
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
// {{{ 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
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);
GAMETYPE(MAPINFO_TYPE_RACE) \
GAMETYPE(MAPINFO_TYPE_CTS) \
GAMETYPE(MAPINFO_TYPE_TEAM_DEATHMATCH) \
+ //GAMETYPE(MAPINFO_TYPE_INVASION) \
/* nothing */
float GameType_GetID(float cnt)
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;
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;
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
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"); }
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:
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
return FALSE;
}
+MUTATOR_HOOKFUNCTION(ca_PlayerRegen)
+{
+ // no regeneration in CA
+ return TRUE;
+}
+
// scoreboard setup
void ca_ScoreRules()
{
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
{
return FALSE;
}
+MUTATOR_HOOKFUNCTION(invasion_PlayerRegen)
+{
+ // no regeneration in invasion
+ return TRUE;
+}
+
MUTATOR_HOOKFUNCTION(invasion_PlayerSpawn)
{
self.bot_attack = FALSE;
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);
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
{
return FALSE;
}
+MUTATOR_HOOKFUNCTION(lms_PlayerRegen)
+{
+ if(autocvar_g_lms_regenerate)
+ return FALSE;
+ return TRUE;
+}
+
MUTATOR_HOOKFUNCTION(lms_ForbidThrowing)
{
// forbode!
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);
return FALSE;
}
+MUTATOR_HOOKFUNCTION(minstagib_PlayerRegen)
+{
+ // no regeneration in minstagib
+ return TRUE;
+}
+
MUTATOR_HOOKFUNCTION(minstagib_PlayerPowerups)
{
if (!(self.effects & EF_FULLBRIGHT))
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);