--- /dev/null
+#include "sv_respawntime.qh"
+
+AUTOCVAR(g_killers_spawn_faster, bool, false, "Killers spawn faster: a mutator that penalizes dying, and rewards killing, by adjusting time to respawn");
+AUTOCVAR(g_killers_spawn_faster_frag_modifier, float, -0.2, "Killers spawn faster: respawntime factor change when fragging someone");
+AUTOCVAR(g_killers_spawn_faster_death_modifier, float, 0.5, "Killers spawn faster: respawntime factor change when dying");
+REGISTER_MUTATOR(mutator_killers_spawn_faster, autocvar_g_killers_spawn_faster);
+
+float killers_spawn_faster_adjust(float base, float adj) {
+ if (adj < 0) {
+ adj *= base;
+ }
+ return base + adj;
+}
+
+MUTATOR_HOOKFUNCTION(mutator_killers_spawn_faster, BuildMutatorsString) {
+ M_ARGV(0, string) = strcat(M_ARGV(0, string), ":KillersSpawnFaster");
+}
+
+MUTATOR_HOOKFUNCTION(mutator_killers_spawn_faster, BuildMutatorsPrettyString) {
+ M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Killers spawn faster");
+}
+
+MUTATOR_HOOKFUNCTION(mutator_killers_spawn_faster, ClientConnect) {
+ entity player = M_ARGV(0, entity);
+ player.killers_spawn_faster_factor = 1;
+ LOG_DEBUGF("Newly spawned player %i with respawntime factor %f", player, player.killers_spawn_faster_factor);
+}
+
+MUTATOR_HOOKFUNCTION(mutator_killers_spawn_faster, PlayerDies) {
+ // Note: this runs BEFORE CalculateRespawnTime.
+ entity attacker = M_ARGV(1, entity);
+ entity target = M_ARGV(2, entity);
+ if (target.classname == "body") {
+ error("WAT");
+ return false;
+ }
+ attacker.killers_spawn_faster_factor = killers_spawn_faster_adjust(
+ attacker.killers_spawn_faster_factor,
+ autocvar_g_killers_spawn_faster_frag_modifier);
+ LOG_DEBUGF("Killer player %i now has respawntime factor %f", attacker, attacker.killers_spawn_faster_factor);
+}
+
+MUTATOR_HOOKFUNCTION(mutator_killers_spawn_faster, CalculateRespawnTime) {
+ entity player = M_ARGV(0, entity);
+ float sdelay = M_ARGV(1, float);
+ sdelay *= player.killers_spawn_faster_factor;
+ LOG_DEBUGF("Adjusted player %i respawntime to %f", player, sdelay);
+ M_ARGV(1, float) = sdelay;
+}
+
+MUTATOR_HOOKFUNCTION(mutator_killers_spawn_faster, PlayerDied) {
+ // Note: this runs AFTER CalculateRespawnTime.
+ entity player = M_ARGV(0, entity);
+ if (player.classname == "body") {
+ error("WAT");
+ return false;
+ }
+ player.killers_spawn_faster_factor = killers_spawn_faster_adjust(
+ player.killers_spawn_faster_factor,
+ autocvar_g_killers_spawn_faster_death_modifier);
+ LOG_DEBUGF("Dying player %i now has respawntime factor %f", player, player.killers_spawn_faster_factor);
+}
+
+MUTATOR_HOOKFUNCTION(mutator_killers_spawn_faster, PlayerScore_Clear) {
+ entity player = M_ARGV(0, entity);
+ player.killers_spawn_faster_factor = 1;
+ LOG_DEBUGF("Restarted player %i now has respawntime factor %f", player, player.killers_spawn_faster_factor);
+}
void calculate_player_respawn_time(entity this)
{
- if(MUTATOR_CALLHOOK(CalculateRespawnTime, this))
- return;
-
float gametype_setting_tmp;
float sdelay_max = GAMETYPE_DEFAULTED_SETTING(respawn_delay_max);
float sdelay_small = GAMETYPE_DEFAULTED_SETTING(respawn_delay_small);
else // NOTE: this case implies sdelay_large_count > sdelay_small_count.
sdelay = sdelay_small + (sdelay_large - sdelay_small) * (pcount - sdelay_small_count) / (sdelay_large_count - sdelay_small_count);
+ if(MUTATOR_CALLHOOK(CalculateRespawnTime, this, sdelay))
+ return;
+ sdelay = M_ARGV(1, float);
+
if(waves)
this.respawn_time = ceil((time + sdelay) / waves) * waves;
else
/**/
MUTATOR_HOOKABLE(reset_map_players, EV_reset_map_players);
+/** called when entering play after observing, or switching teams */
+#define EV_PlayerScore_Clear(i, o) \
+ /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+ /**/
+MUTATOR_HOOKABLE(PlayerScore_Clear, EV_PlayerScore_Clear);
+
/** returns 1 if clearing player score shall not be allowed */
#define EV_ForbidPlayerScore_Clear(i, o) \
/**/
/** return true to skip respawn time calculations */
#define EV_CalculateRespawnTime(i, o) \
- /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** spawn delay */ i(float, MUTATOR_ARGV_1_float) \
+ /** spawn delay */ o(float, MUTATOR_ARGV_1_float) \
/**/
MUTATOR_HOOKABLE(CalculateRespawnTime, EV_CalculateRespawnTime);