From: Mario Date: Tue, 18 Aug 2015 09:28:11 +0000 (+0000) Subject: Merge branch 'TimePath/mutator_cleanup' into 'master' X-Git-Tag: xonotic-v0.8.2~2071 X-Git-Url: http://de.git.xonotic.org/?a=commitdiff_plain;h=27719a18947959c32a559ed39842f46263749c34;hp=4a1190b6273d8909b799314abb4f7b665b220176;p=xonotic%2Fxonotic-data.pk3dir.git Merge branch 'TimePath/mutator_cleanup' into 'master' Encapsulate mutator globals See merge request !135 --- diff --git a/qcsrc/common/monsters/sv_monsters.qc b/qcsrc/common/monsters/sv_monsters.qc index 239f8fe9a..07547f4fc 100644 --- a/qcsrc/common/monsters/sv_monsters.qc +++ b/qcsrc/common/monsters/sv_monsters.qc @@ -40,8 +40,7 @@ void monster_dropitem() e.monster_loot = self.monster_loot; - other = e; - MUTATOR_CALLHOOK(MonsterDropItem); + MUTATOR_CALLHOOK(MonsterDropItem, e); e = other; if(e && e.monster_loot) @@ -370,7 +369,7 @@ float Monster_CanRespawn(entity ent) { other = ent; if(ent.deadflag == DEAD_DEAD) // don't call when monster isn't dead - if(MUTATOR_CALLHOOK(MonsterRespawn)) + if(MUTATOR_CALLHOOK(MonsterRespawn, ent)) return true; // enabled by a mutator if(ent.spawnflags & MONSTERFLAG_NORESPAWN) @@ -716,11 +715,13 @@ void monster_move(float runspeed, float walkspeed, float stopspeed, float manim_ targ = self.goalentity; - monster_target = targ; - monster_speed_run = runspeed; - monster_speed_walk = walkspeed; - - if(MUTATOR_CALLHOOK(MonsterMove) || gameover || self.draggedby != world || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || time < game_starttime || (autocvar_g_campaign && !campaign_bots_may_start) || time < self.spawn_time) + if (MUTATOR_CALLHOOK(MonsterMove, runspeed, walkspeed, targ) + || gameover + || self.draggedby != world + || (round_handler_IsActive() && !round_handler_IsRoundStarted()) + || time < game_starttime + || (autocvar_g_campaign && !campaign_bots_may_start) + || time < self.spawn_time) { runspeed = walkspeed = 0; if(time >= self.spawn_time) @@ -729,7 +730,6 @@ void monster_move(float runspeed, float walkspeed, float stopspeed, float manim_ return; } - targ = monster_target; runspeed = bound(0, monster_speed_run * Monster_SkillModifier(), runspeed * 2); // limit maxspeed to prevent craziness walkspeed = bound(0, monster_speed_walk * Monster_SkillModifier(), walkspeed * 2); // limit maxspeed to prevent craziness @@ -1039,9 +1039,8 @@ void monsters_damage (entity inflictor, entity attacker, float damage, int death WaypointSprite_Kill(self.sprite); - frag_attacker = attacker; frag_target = self; - MUTATOR_CALLHOOK(MonsterDies); + MUTATOR_CALLHOOK(MonsterDies, attacker); if(self.health <= -100 || deathtype == DEATH_KILL) // check if we're already gibbed { diff --git a/qcsrc/common/physics.qc b/qcsrc/common/physics.qc index 6153d80ae..0cac08bb0 100644 --- a/qcsrc/common/physics.qc +++ b/qcsrc/common/physics.qc @@ -553,12 +553,12 @@ bool PlayerJump (void) bool doublejump = false; float mjumpheight = PHYS_JUMPVELOCITY; - player_multijump = doublejump; - player_jumpheight = mjumpheight; #ifdef SVQC - if (MUTATOR_CALLHOOK(PlayerJump)) + if (MUTATOR_CALLHOOK(PlayerJump, doublejump, mjumpheight)) #elif defined(CSQC) - if(PM_multijump_checkjump()) + player_multijump = doublejump; + player_jumpheight = mjumpheight; + if (PM_multijump_checkjump()) #endif return true; diff --git a/qcsrc/common/weapons/w_blaster.qc b/qcsrc/common/weapons/w_blaster.qc index a776edbf4..1e41f9df8 100644 --- a/qcsrc/common/weapons/w_blaster.qc +++ b/qcsrc/common/weapons/w_blaster.qc @@ -136,7 +136,7 @@ void W_Blaster_Attack( missile.think = W_Blaster_Think; missile.nextthink = time + atk_delay; - other = missile; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, missile); if(time >= missile.nextthink) { diff --git a/qcsrc/common/weapons/w_crylink.qc b/qcsrc/common/weapons/w_crylink.qc index 4d4430206..0825103d4 100644 --- a/qcsrc/common/weapons/w_crylink.qc +++ b/qcsrc/common/weapons/w_crylink.qc @@ -437,7 +437,7 @@ void W_Crylink_Attack(void) CSQCProjectile(proj, true, (proj.cnt ? PROJECTILE_CRYLINK_BOUNCING : PROJECTILE_CRYLINK), true); - other = proj; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, proj); } if(WEP_CVAR_PRI(crylink, joinspread) != 0) { @@ -553,7 +553,7 @@ void W_Crylink_Attack2(void) CSQCProjectile(proj, true, (proj.cnt ? PROJECTILE_CRYLINK_BOUNCING : PROJECTILE_CRYLINK), true); - other = proj; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, proj); } if(WEP_CVAR_SEC(crylink, joinspread) != 0) { diff --git a/qcsrc/common/weapons/w_devastator.qc b/qcsrc/common/weapons/w_devastator.qc index e9e0467e2..0dd8f80f7 100644 --- a/qcsrc/common/weapons/w_devastator.qc +++ b/qcsrc/common/weapons/w_devastator.qc @@ -388,7 +388,7 @@ void W_Devastator_Attack(void) W_AttachToShotorg(flash, '5 0 0'); // common properties - other = missile; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, missile); } bool W_Devastator(int req) diff --git a/qcsrc/common/weapons/w_electro.qc b/qcsrc/common/weapons/w_electro.qc index e3b809296..0a219392e 100644 --- a/qcsrc/common/weapons/w_electro.qc +++ b/qcsrc/common/weapons/w_electro.qc @@ -284,7 +284,7 @@ void W_Electro_Attack_Bolt(void) CSQCProjectile(proj, true, PROJECTILE_ELECTRO_BEAM, true); - other = proj; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, proj); } void W_Electro_Orb_Touch(void) @@ -400,7 +400,7 @@ void W_Electro_Attack_Orb(void) CSQCProjectile(proj, true, PROJECTILE_ELECTRO, false); // no culling, it has sound - other = proj; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, proj); } void W_Electro_CheckAttack(void) diff --git a/qcsrc/common/weapons/w_fireball.qc b/qcsrc/common/weapons/w_fireball.qc index 7bb5ccb66..112b6524e 100644 --- a/qcsrc/common/weapons/w_fireball.qc +++ b/qcsrc/common/weapons/w_fireball.qc @@ -213,7 +213,7 @@ void W_Fireball_Attack1(void) CSQCProjectile(proj, true, PROJECTILE_FIREBALL, true); - other = proj; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, proj); } void W_Fireball_AttackEffect(float i, vector f_diff) @@ -344,7 +344,7 @@ void W_Fireball_Attack2(void) CSQCProjectile(proj, true, PROJECTILE_FIREMINE, true); - other = proj; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, proj); } bool W_Fireball(int req) diff --git a/qcsrc/common/weapons/w_hagar.qc b/qcsrc/common/weapons/w_hagar.qc index 4c9f66498..808d7733a 100644 --- a/qcsrc/common/weapons/w_hagar.qc +++ b/qcsrc/common/weapons/w_hagar.qc @@ -160,7 +160,7 @@ void W_Hagar_Attack(void) CSQCProjectile(missile, true, PROJECTILE_HAGAR, true); - other = missile; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, missile); } void W_Hagar_Attack2(void) @@ -204,7 +204,7 @@ void W_Hagar_Attack2(void) CSQCProjectile(missile, true, PROJECTILE_HAGAR_BOUNCING, true); - other = missile; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, missile); } .float hagar_loadstep, hagar_loadblock, hagar_loadbeep, hagar_warning; @@ -280,7 +280,7 @@ void W_Hagar_Attack2_Load_Release(void) CSQCProjectile(missile, true, PROJECTILE_HAGAR, true); - other = missile; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, missile); } weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(hagar, load_animtime), w_ready); diff --git a/qcsrc/common/weapons/w_hlac.qc b/qcsrc/common/weapons/w_hlac.qc index 7f7d7a27b..e9c7ffee4 100644 --- a/qcsrc/common/weapons/w_hlac.qc +++ b/qcsrc/common/weapons/w_hlac.qc @@ -110,7 +110,7 @@ void W_HLAC_Attack(void) CSQCProjectile(missile, true, PROJECTILE_HLAC, true); - other = missile; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, missile); } void W_HLAC_Attack2(void) @@ -154,7 +154,7 @@ void W_HLAC_Attack2(void) CSQCProjectile(missile, true, PROJECTILE_HLAC, true); - other = missile; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, missile); } // weapon frames diff --git a/qcsrc/common/weapons/w_hook.qc b/qcsrc/common/weapons/w_hook.qc index 1c05c23d6..0c002bfc7 100644 --- a/qcsrc/common/weapons/w_hook.qc +++ b/qcsrc/common/weapons/w_hook.qc @@ -170,7 +170,7 @@ void W_Hook_Attack2(void) CSQCProjectile(gren, true, PROJECTILE_HOOKBOMB, true); - other = gren; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, gren); } bool W_Hook(int req) diff --git a/qcsrc/common/weapons/w_minelayer.qc b/qcsrc/common/weapons/w_minelayer.qc index d4ef95547..32d999612 100644 --- a/qcsrc/common/weapons/w_minelayer.qc +++ b/qcsrc/common/weapons/w_minelayer.qc @@ -374,7 +374,7 @@ void W_MineLayer_Attack(void) // common properties - other = mine; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, mine); self.minelayer_mines = W_MineLayer_Count(self); } diff --git a/qcsrc/common/weapons/w_mortar.qc b/qcsrc/common/weapons/w_mortar.qc index c958372af..a8c6a2c59 100644 --- a/qcsrc/common/weapons/w_mortar.qc +++ b/qcsrc/common/weapons/w_mortar.qc @@ -267,7 +267,7 @@ void W_Mortar_Attack(void) else CSQCProjectile(gren, true, PROJECTILE_GRENADE_BOUNCING, true); - other = gren; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, gren); } void W_Mortar_Attack2(void) @@ -315,7 +315,7 @@ void W_Mortar_Attack2(void) else CSQCProjectile(gren, true, PROJECTILE_GRENADE_BOUNCING, true); - other = gren; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, gren); } .float bot_secondary_grenademooth; diff --git a/qcsrc/common/weapons/w_porto.qc b/qcsrc/common/weapons/w_porto.qc index 82baf07bd..40964891d 100644 --- a/qcsrc/common/weapons/w_porto.qc +++ b/qcsrc/common/weapons/w_porto.qc @@ -283,7 +283,7 @@ void W_Porto_Attack(float type) else CSQCProjectile(gren, true, PROJECTILE_PORTO_RED, true); - other = gren; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, gren); } bool w_nexball_weapon(int req); // WEAPONTODO diff --git a/qcsrc/common/weapons/w_rpc.qc b/qcsrc/common/weapons/w_rpc.qc index d641572c3..b7f7a4f87 100644 --- a/qcsrc/common/weapons/w_rpc.qc +++ b/qcsrc/common/weapons/w_rpc.qc @@ -143,7 +143,7 @@ void W_RocketPropelledChainsaw_Attack (void) W_AttachToShotorg(flash, '5 0 0'); missile.pos1 = missile.velocity; - other = missile; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, missile); } bool W_RocketPropelledChainsaw(int req) diff --git a/qcsrc/common/weapons/w_seeker.qc b/qcsrc/common/weapons/w_seeker.qc index f338ed7ea..2dce3165b 100644 --- a/qcsrc/common/weapons/w_seeker.qc +++ b/qcsrc/common/weapons/w_seeker.qc @@ -293,7 +293,7 @@ void W_Seeker_Fire_Missile(vector f_diff, entity m_target) CSQCProjectile(missile, false, PROJECTILE_SEEKER, true); - other = missile; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, missile); } // ============================ @@ -371,7 +371,7 @@ void W_Seeker_Fire_Flac(void) W_SetupProjVelocity_UP_PRE(missile, seeker, flac_); CSQCProjectile(missile, true, PROJECTILE_FLAC, true); - other = missile; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, missile); } // ============================ @@ -589,7 +589,7 @@ void W_Seeker_Fire_Tag(void) CSQCProjectile(missile, true, PROJECTILE_TAG, false); // has sound - other = missile; MUTATOR_CALLHOOK(EditProjectile); + MUTATOR_CALLHOOK(EditProjectile, self, missile); } // ============================ diff --git a/qcsrc/server/bot/aim.qc b/qcsrc/server/bot/aim.qc index c889a2f9a..e0dbdae26 100644 --- a/qcsrc/server/bot/aim.qc +++ b/qcsrc/server/bot/aim.qc @@ -143,8 +143,7 @@ float bot_shouldattack(entity e) if(e.flags & FL_NOTARGET) return false; - checkentity = e; - if(MUTATOR_CALLHOOK(BotShouldAttack)) + if(MUTATOR_CALLHOOK(BotShouldAttack, e)) return false; return true; diff --git a/qcsrc/server/bot/havocbot/roles.qc b/qcsrc/server/bot/havocbot/roles.qc index 65ea2a809..df6b8de91 100644 --- a/qcsrc/server/bot/havocbot/roles.qc +++ b/qcsrc/server/bot/havocbot/roles.qc @@ -242,7 +242,7 @@ void havocbot_chooserole() { dprint("choosing a role...\n"); self.bot_strategytime = 0; - if (MUTATOR_CALLHOOK(HavocBot_ChooseRole)) + if (MUTATOR_CALLHOOK(HavocBot_ChooseRole, self)) return; else if (g_keyhunt) havocbot_chooserole_kh(); diff --git a/qcsrc/server/cheats.qc b/qcsrc/server/cheats.qc index 0c6fc7f39..eb5538319 100644 --- a/qcsrc/server/cheats.qc +++ b/qcsrc/server/cheats.qc @@ -212,7 +212,7 @@ float CheatImpulse(float i) self.angles = self.personal.v_angle; self.fixangle = true; - MUTATOR_CALLHOOK(AbortSpeedrun); + MUTATOR_CALLHOOK(AbortSpeedrun, self); } self.ammo_rockets = self.personal.ammo_rockets; diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 6d3d786ae..aa02de5b0 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -422,7 +422,7 @@ void PutClientInServer (void) // reset player keys self.itemkeys = 0; - MUTATOR_CALLHOOK(PutClientInServer); + MUTATOR_CALLHOOK(PutClientInServer, self); if(gameover) self.classname = "observer"; @@ -644,8 +644,7 @@ void PutClientInServer (void) Unfreeze(self); - spawn_spot = spot; - MUTATOR_CALLHOOK(PlayerSpawn); + MUTATOR_CALLHOOK(PlayerSpawn, spot); if(autocvar_spawn_debug) { @@ -1280,7 +1279,7 @@ void ClientConnect (void) self = oldself; } - MUTATOR_CALLHOOK(ClientConnect); + MUTATOR_CALLHOOK(ClientConnect, self); } /* ============= @@ -1463,7 +1462,7 @@ void play_countdown(float finished, string samp) void player_powerups (void) { // add a way to see what the items were BEFORE all of these checks for the mutator hook - olditems = self.items; + int items_prev = self.items; if((self.items & IT_USING_JETPACK) && !self.deadflag && !gameover) self.modelflags |= MF_ROCKET; @@ -1575,7 +1574,7 @@ void player_powerups (void) if (time < self.spawnshieldtime) self.effects = self.effects | (EF_ADDITIVE | EF_FULLBRIGHT); - MUTATOR_CALLHOOK(PlayerPowerups); + MUTATOR_CALLHOOK(PlayerPowerups, self, items_prev); } float CalcRegen(float current, float stable, float regenfactor, float regenframetime) @@ -1627,11 +1626,7 @@ void player_regen (void) { float max_mod, regen_mod, rot_mod, limit_mod; max_mod = regen_mod = rot_mod = limit_mod = 1; - regen_mod_max = max_mod; - regen_mod_regen = regen_mod; - regen_mod_rot = rot_mod; - regen_mod_limit = limit_mod; - if(!MUTATOR_CALLHOOK(PlayerRegen)) + if(!MUTATOR_CALLHOOK(PlayerRegen, max_mod, regen_mod, rot_mod, limit_mod)) if(!self.frozen) { float minh, mina, maxh, maxa, limith, limita; @@ -1706,8 +1701,7 @@ spectate mode routines */ void SpectateCopy(entity spectatee) { - other = spectatee; - MUTATOR_CALLHOOK(SpectateCopy); + MUTATOR_CALLHOOK(SpectateCopy, spectatee, self); self.armortype = spectatee.armortype; self.armorvalue = spectatee.armorvalue; self.ammo_cells = spectatee.ammo_cells; diff --git a/qcsrc/server/cl_impulse.qc b/qcsrc/server/cl_impulse.qc index bb4c171c8..f37e8a462 100644 --- a/qcsrc/server/cl_impulse.qc +++ b/qcsrc/server/cl_impulse.qc @@ -186,7 +186,7 @@ void ImpulseCommands (void) case 33: if(self.deadflag == DEAD_NO && teamplay) { - if (!MUTATOR_CALLHOOK(HelpMePing)) + if (!MUTATOR_CALLHOOK(HelpMePing, self)) { wp = WaypointSprite_Attach("helpme", true, RADARICON_HELPME, '1 0.5 0'); if(!wp) diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index aae39ea66..41b74a0df 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -385,14 +385,8 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp self.istypefrag = 0; } - frag_inflictor = inflictor; - frag_attacker = attacker; - frag_target = self; frag_damage = damage; - damage_take = take; - damage_save = save; - damage_force = force; - MUTATOR_CALLHOOK(PlayerDamage_SplitHealthArmor); + MUTATOR_CALLHOOK(PlayerDamage_SplitHealthArmor, inflictor, attacker, self, force, take, save); take = bound(0, damage_take, self.health); save = bound(0, damage_save, self.armorvalue); excess = max(0, damage - take - save); @@ -549,11 +543,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp if(accuracy_isgooddamage(attacker, self)) attacker.accuracy.(accuracy_frags[w-1]) += 1; - frag_attacker = attacker; - frag_inflictor = inflictor; - frag_target = self; - frag_deathtype = deathtype; - MUTATOR_CALLHOOK(PlayerDies); + MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, self, deathtype); WEP_ACTION(self.weapon, WR_PLAYERDEATH); diff --git a/qcsrc/server/command/cmd.qc b/qcsrc/server/command/cmd.qc index eec507f07..cc8e19673 100644 --- a/qcsrc/server/command/cmd.qc +++ b/qcsrc/server/command/cmd.qc @@ -888,11 +888,6 @@ void SV_ParseClientCommand(string command) float argc = tokenize_console(command); - // for the mutator hook system - cmd_name = strtolower(argv(0)); - cmd_argc = argc; - cmd_string = command; - // Guide for working with argc arguments by example: // argc: 1 - 2 - 3 - 4 // argv: 0 - 1 - 2 - 3 @@ -941,7 +936,7 @@ void SV_ParseClientCommand(string command) return; } } - else if(MUTATOR_CALLHOOK(SV_ParseClientCommand)) + else if(MUTATOR_CALLHOOK(SV_ParseClientCommand, strtolower(argv(0)), argc, command)) { return; // handled by a mutator } diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index c5bbfcab5..a20d35220 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -147,10 +147,7 @@ void GiveFrags (entity attacker, entity targ, float f, int deathtype) entity oldself; oldself = self; self = attacker; - frag_attacker = attacker; - frag_target = targ; - frag_score = f; - if(MUTATOR_CALLHOOK(GiveFragsForKill)) + if(MUTATOR_CALLHOOK(GiveFragsForKill, attacker, targ, f)) { f = frag_score; self = oldself; @@ -749,13 +746,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d } // should this be changed at all? If so, in what way? - frag_attacker = attacker; - frag_target = targ; - frag_damage = damage; - frag_force = force; - frag_deathtype = deathtype; - frag_mirrordamage = mirrordamage; - MUTATOR_CALLHOOK(PlayerDamage_Calculate); + MUTATOR_CALLHOOK(PlayerDamage_Calculate, attacker, targ, deathtype, damage, mirrordamage, force); damage = frag_damage; mirrordamage = frag_mirrordamage; force = frag_force; diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 881f8f071..de29c9a25 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -692,8 +692,7 @@ void spawnfunc_worldspawn (void) GameLogEcho(strcat(":gamestart:", GetGametype(), "_", GetMapname(), ":", s)); s = ":gameinfo:mutators:LIST"; - ret_string = s; - MUTATOR_CALLHOOK(BuildMutatorsString); + MUTATOR_CALLHOOK(BuildMutatorsString, s); s = ret_string; // simple, probably not good in the mutator system diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 2354e128e..4975b86f0 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -427,7 +427,6 @@ void GetCvars(float f) get_cvars_f = f; get_cvars_s = s; - MUTATOR_CALLHOOK(GetCvars); Notification_GetCvars(); diff --git a/qcsrc/server/mutators/base.qc b/qcsrc/server/mutators/base.qc index f642a3bdf..2f78ec182 100644 --- a/qcsrc/server/mutators/base.qc +++ b/qcsrc/server/mutators/base.qc @@ -1,75 +1,60 @@ #include "base.qh" #include "../_all.qh" -.float() cbc_func; +.bool() cbc_func; .entity cbc_next; -.float cbc_order; +.int cbc_order; entity CallbackChain_New(string name) { - entity e; - e = spawn(); + entity e = spawn(); e.classname = "callbackchain"; e.netname = name; return e; } -float CallbackChain_Add(entity cb, float() func, float order) +bool CallbackChain_Add(entity cb, bool() func, int order) { - entity e; - if(order & CBC_ORDER_FIRST) - { - if(order & CBC_ORDER_LAST) - if(cb.cbc_order & CBC_ORDER_ANY) - return 0; - if(cb.cbc_order & CBC_ORDER_FIRST) - return 0; + if (order & CBC_ORDER_FIRST) { + if (order & CBC_ORDER_LAST) + if (cb.cbc_order & CBC_ORDER_ANY) + return false; + if (cb.cbc_order & CBC_ORDER_FIRST) + return false; + } else if (order & CBC_ORDER_LAST) { + if (cb.cbc_order & CBC_ORDER_LAST) + return false; } - else if(order & CBC_ORDER_LAST) - { - if(cb.cbc_order & CBC_ORDER_LAST) - return 0; - } - entity thiscb; - thiscb = spawn(); + entity thiscb = spawn(); thiscb.classname = "callback"; thiscb.cbc_func = func; thiscb.cbc_order = order; - if(order & CBC_ORDER_FIRST) - { + if (order & CBC_ORDER_FIRST) { thiscb.cbc_next = cb.cbc_next; cb.cbc_next = thiscb; - } - else if(order & CBC_ORDER_LAST) - { - for(e = cb; e.cbc_next; e = e.cbc_next); + } else if (order & CBC_ORDER_LAST) { + entity e = cb; + while (e.cbc_next) e = e.cbc_next; e.cbc_next = thiscb; - } - else - { + } else { // by default we execute last, but before a possible CBC_ORDER_LAST callback - for(e = cb; e.cbc_next && !(e.cbc_next.cbc_order & CBC_ORDER_LAST); e = e.cbc_next); // we must make sure that we insert BEFORE an CBC_ORDER_LAST mutator! + entity e = cb; + // we must make sure that we insert BEFORE an CBC_ORDER_LAST mutator! + while (e.cbc_next && !(e.cbc_next.cbc_order & CBC_ORDER_LAST)) e = e.cbc_next; thiscb.cbc_next = e.cbc_next; e.cbc_next = thiscb; } cb.cbc_order |= (order | CBC_ORDER_ANY); - return 1; + return true; } -float CallbackChain_Remove(entity cb, float() func) +int CallbackChain_Remove(entity cb, bool() func) { - float order; - entity e; - float n; - n = 0; - order = 0; - for(e = cb; e.cbc_next; e = e.cbc_next) - { - while(e.cbc_next.cbc_func == func) - { + int n = 0, order = 0; + for (entity e = cb; e.cbc_next; e = e.cbc_next) { + while (e.cbc_next.cbc_func == func) { // remove e.cbc_next from the chain - entity e2; - e2 = e.cbc_next.cbc_next; + entity e2 = e.cbc_next.cbc_next; remove(e.cbc_next); e.cbc_next = e2; ++n; @@ -81,69 +66,59 @@ float CallbackChain_Remove(entity cb, float() func) return n; } -float CallbackChain_Call(entity cb) +bool CallbackChain_Call(entity cb) { - float r; - entity e; - r = 0; - for(e = cb; e.cbc_next; e = e.cbc_next) - { + bool r = false; + for (entity e = cb; e.cbc_next; e = e.cbc_next) { CallbackChain_ReturnValue = r; r |= e.cbc_next.cbc_func(); } return r; // callbacks return an error status, so 0 is default return value } -const float MAX_MUTATORS = 15; +const int MAX_MUTATORS = 15; string loaded_mutators[MAX_MUTATORS]; -float Mutator_Add(mutatorfunc_t func, string name) +bool Mutator_Add(mutatorfunc_t func, string name) { - int i, j; - j = -1; - for(i = 0; i < MAX_MUTATORS; ++i) - { - if(name == loaded_mutators[i]) - return 1; // already added + int j = -1; + for (int i = 0; i < MAX_MUTATORS; ++i) { + if (name == loaded_mutators[i]) + return true; // already added if (!(loaded_mutators[i])) j = i; } - if(j < 0) - { + if (j < 0) { backtrace("WARNING: too many mutators, cannot add any more\n"); - return 0; + return false; } loaded_mutators[j] = name; - if(func(MUTATOR_ADDING) == 0) - { + if (!func(MUTATOR_ADDING)) { // good - return 1; + return true; } backtrace("WARNING: when adding mutator: adding failed, rolling back\n"); - if(func(MUTATOR_ROLLING_BACK) != 0) - { + if (func(MUTATOR_ROLLING_BACK)) { // baaaaad error("WARNING: when adding mutator: rolling back failed"); } - return 0; + return false; } -void Mutator_Remove(float(float) func, string name) +void Mutator_Remove(mutatorfunc_t func, string name) { int i; - for(i = 0; i < MAX_MUTATORS; ++i) - if(name == loaded_mutators[i]) + for (i = 0; i < MAX_MUTATORS; ++i) + if (name == loaded_mutators[i]) break; - if(i >= MAX_MUTATORS) - { + if (i >= MAX_MUTATORS) { backtrace("WARNING: removing not-added mutator\n"); return; } loaded_mutators[i] = string_null; - if(func(MUTATOR_REMOVING) != 0) - { + if (func(MUTATOR_REMOVING) != 0) { // baaaaad error("Mutator_Remove: removing mutator failed"); } diff --git a/qcsrc/server/mutators/base.qh b/qcsrc/server/mutators/base.qh index 199cb62fb..c12050caf 100644 --- a/qcsrc/server/mutators/base.qh +++ b/qcsrc/server/mutators/base.qh @@ -1,385 +1,569 @@ #ifndef MUTATORS_BASE_H #define MUTATORS_BASE_H -const float CBC_ORDER_EXCLUSIVE = 3; -const float CBC_ORDER_FIRST = 1; -const float CBC_ORDER_LAST = 2; -const float CBC_ORDER_ANY = 4; +const int CBC_ORDER_FIRST = 1; +const int CBC_ORDER_LAST = 2; +const int CBC_ORDER_EXCLUSIVE = 3; +const int CBC_ORDER_ANY = 4; -float CallbackChain_ReturnValue; // read-only field of the current return value +bool CallbackChain_ReturnValue; // read-only field of the current return value entity CallbackChain_New(string name); -float CallbackChain_Add(entity cb, float() func, float order); -float CallbackChain_Remove(entity cb, float() func); +bool CallbackChain_Add(entity cb, bool() func, int order); +int CallbackChain_Remove(entity cb, bool() func); // a callback function is like this: -// float mycallback(entity me) +// bool mycallback(entity me) // { // do something -// return r; +// return false; // } -float CallbackChain_Call(entity cb); - -const float MUTATOR_REMOVING = 0; -const float MUTATOR_ADDING = 1; -const float MUTATOR_ROLLING_BACK = 2; -typedef float(float) mutatorfunc_t; -float Mutator_Add(mutatorfunc_t func, string name); +bool CallbackChain_Call(entity cb); + +enum { + MUTATOR_REMOVING, + MUTATOR_ADDING, + MUTATOR_ROLLING_BACK +}; +typedef bool(int) mutatorfunc_t; +bool Mutator_Add(mutatorfunc_t func, string name); void Mutator_Remove(mutatorfunc_t func, string name); // calls error() on fail #define MUTATOR_ADD(name) Mutator_Add(MUTATOR_##name, #name) #define MUTATOR_REMOVE(name) Mutator_Remove(MUTATOR_##name, #name) -#define MUTATOR_DEFINITION(name) float MUTATOR_##name(float mode) -#define MUTATOR_DECLARATION(name) float MUTATOR_##name(float mode) -#define MUTATOR_HOOKFUNCTION(name) float HOOKFUNCTION_##name() -#define MUTATOR_HOOK(cb,func,order) do { if(mode == MUTATOR_ADDING) { if(!HOOK_##cb) HOOK_##cb = CallbackChain_New(#cb); if(!CallbackChain_Add(HOOK_##cb,HOOKFUNCTION_##func,order)) { print("HOOK FAILED: ", #func, "\n"); return 1; } } else if(mode == MUTATOR_REMOVING || mode == MUTATOR_ROLLING_BACK) { if(HOOK_##cb) CallbackChain_Remove(HOOK_##cb,HOOKFUNCTION_##func); } } while(0) -#define MUTATOR_ONADD if(mode == MUTATOR_ADDING) -#define MUTATOR_ONREMOVE if(mode == MUTATOR_REMOVING) -#define MUTATOR_ONROLLBACK_OR_REMOVE if(mode == MUTATOR_REMOVING || mode == MUTATOR_ROLLING_BACK) - -#define MUTATOR_HOOKABLE(cb) entity HOOK_##cb -#define MUTATOR_CALLHOOK(cb) CallbackChain_Call(HOOK_##cb) +#define MUTATOR_DEFINITION(name) bool MUTATOR_##name(int mode) +#define MUTATOR_DECLARATION(name) bool MUTATOR_##name(int mode) +#define MUTATOR_HOOKFUNCTION(name) bool HOOKFUNCTION_##name() +#define MUTATOR_HOOK(cb, func, order) do { \ + MUTATOR_ONADD { \ + if (!HOOK_##cb) HOOK_##cb = CallbackChain_New(#cb); \ + if (!CallbackChain_Add(HOOK_##cb, HOOKFUNCTION_##func, order)) { \ + print("HOOK FAILED: ", #func, "\n"); \ + return true; \ + } \ + } \ + MUTATOR_ONROLLBACK_OR_REMOVE { \ + if (HOOK_##cb) CallbackChain_Remove(HOOK_##cb, HOOKFUNCTION_##func); \ + } \ +} while(0) +#define MUTATOR_ONADD if (mode == MUTATOR_ADDING) +#define MUTATOR_ONREMOVE if (mode == MUTATOR_REMOVING) +#define MUTATOR_ONROLLBACK_OR_REMOVE if (mode == MUTATOR_REMOVING || mode == MUTATOR_ROLLING_BACK) + +#define _MUTATOR_HOOKABLE(id, ...) entity HOOK_##id; bool __Mutator_Send_##id(__VA_ARGS__) +#define MUTATOR_CALLHOOK(id, ...) APPLY(__Mutator_Send_##id, 0, ##__VA_ARGS__) #define MUTATOR_RETURNVALUE CallbackChain_ReturnValue +#define HANDLE_NOP(type, id) +#define HANDLE_PARAMS(type, id) , type in_##id +#define HANDLE_PREPARE(type, id) id = in_##id; +#define HANDLE_PUSHTMP(type, id) type tmp_##id = id; +#define HANDLE_PUSHOUT(type, id) type out_##id = id; +#define HANDLE_POPTMP(type, id) id = tmp_##id; +#define HANDLE_POPOUT(type, id) id = out_##id; + +#define MUTATOR_HOOKABLE(id, params) \ + _MUTATOR_HOOKABLE(id, int params(HANDLE_PARAMS, HANDLE_NOP)) { \ + params(HANDLE_PUSHTMP, HANDLE_NOP) \ + params(HANDLE_PREPARE, HANDLE_NOP) \ + bool ret = CallbackChain_Call(HOOK_##id); \ + params(HANDLE_NOP, HANDLE_PUSHOUT) \ + params(HANDLE_POPTMP, HANDLE_NOP) \ + params(HANDLE_NOP, HANDLE_POPOUT) \ + return ret; \ + } // register all possible hooks here // some parameters are commented to avoid duplicate declarations -MUTATOR_HOOKABLE(MakePlayerObserver); - // called when a player becomes observer, after shared setup - -MUTATOR_HOOKABLE(PutClientInServer); -// entity self; // client wanting to spawn - -MUTATOR_HOOKABLE(PlayerSpawn); - entity spawn_spot; // spot that was used, or world - // called when a player spawns as player, after shared setup, before his weapon is chosen (so items may be changed in here) - -MUTATOR_HOOKABLE(reset_map_global); - // called in reset_map - -MUTATOR_HOOKABLE(reset_map_players); - // called in reset_map - -MUTATOR_HOOKABLE(ForbidPlayerScore_Clear); - // returns 1 if clearing player score shall not be allowed - -MUTATOR_HOOKABLE(ClientDisconnect); - // called when a player disconnects - -MUTATOR_HOOKABLE(PlayerDies); - // called when a player dies to e.g. remove stuff he was carrying. - // INPUT: - entity frag_inflictor; - entity frag_attacker; - entity frag_target; // same as self - float frag_deathtype; - -MUTATOR_HOOKABLE(PlayerJump); - // called when a player presses the jump key - // INPUT, OUTPUT: - float player_multijump; - float player_jumpheight; - -MUTATOR_HOOKABLE(GiveFragsForKill); - // called when someone was fragged by "self", and is expected to change frag_score to adjust scoring for the kill - // INPUT: -// entity frag_attacker; // same as self -// entity frag_target; - // INPUT, OUTPUT: - float frag_score; - -MUTATOR_HOOKABLE(MatchEnd); - // called when the match ends - -MUTATOR_HOOKABLE(GetTeamCount); - // should adjust ret_float to contain the team count - // INPUT, OUTPUT: - float ret_float; - -MUTATOR_HOOKABLE(SpectateCopy); - // copies variables for spectating "other" to "self" - // INPUT: -// entity other; - -MUTATOR_HOOKABLE(ForbidThrowCurrentWeapon); - // returns 1 if throwing the current weapon shall not be allowed - -MUTATOR_HOOKABLE(WeaponRateFactor); - // allows changing attack rate - // INPUT, OUTPUT: - float weapon_rate; - -MUTATOR_HOOKABLE(WeaponSpeedFactor); - // allows changing weapon speed (projectiles mostly) - // INPUT, OUTPUT: - //float ret_float; - -MUTATOR_HOOKABLE(SetStartItems); - // adjusts {warmup_}start_{items,weapons,ammo_{cells,plasma,rockets,nails,shells,fuel}} - -MUTATOR_HOOKABLE(BuildMutatorsString); - // appends ":mutatorname" to ret_string for logging - // INPUT, OUTPUT: - string ret_string; - -MUTATOR_HOOKABLE(BuildMutatorsPrettyString); - // appends ", Mutator name" to ret_string for display - // INPUT, OUTPUT: -// string ret_string; - -MUTATOR_HOOKABLE(CustomizeWaypoint); - // called every frame - // customizes the waypoint for spectators - // INPUT: self = waypoint, other = player, other.enemy = spectator - -MUTATOR_HOOKABLE(FilterItem); - // checks if the current item may be spawned (self.items and self.weapons may be read and written to, as well as the ammo_ fields) - // return error to request removal - -MUTATOR_HOOKABLE(TurretSpawn); - // return error to request removal - // INPUT: self - turret - -MUTATOR_HOOKABLE(OnEntityPreSpawn); - // return error to prevent entity spawn, or modify the entity - -MUTATOR_HOOKABLE(PlayerPreThink); - // runs in the event loop for players; is called for ALL player entities, also bots, also the dead, or spectators - -MUTATOR_HOOKABLE(GetPressedKeys); - // TODO change this into a general PlayerPostThink hook? - -MUTATOR_HOOKABLE(PlayerPhysics); - // called before any player physics, may adjust variables for movement, - // is run AFTER bot code and idle checking - -MUTATOR_HOOKABLE(GetCvars); - // is meant to call GetCvars_handle*(get_cvars_s, get_cvars_f, cvarfield, "cvarname") for cvars this mutator needs from the client - // INPUT: - float get_cvars_f; - string get_cvars_s; - -MUTATOR_HOOKABLE(EditProjectile); - // can edit any "just fired" projectile - // INPUT: -// entity self; -// entity other; - -MUTATOR_HOOKABLE(MonsterSpawn); - // called when a monster spawns - -MUTATOR_HOOKABLE(MonsterDies); - // called when a monster dies - // INPUT: -// entity frag_attacker; - -MUTATOR_HOOKABLE(MonsterRespawn); - // called when a monster wants to respawn - // INPUT: -// entity other; - -MUTATOR_HOOKABLE(MonsterDropItem); - // called when a monster is dropping loot - // INPUT, OUTPUT: - .void() monster_loot; -// entity other; - -MUTATOR_HOOKABLE(MonsterMove); - // called when a monster moves - // returning true makes the monster stop - // INPUT: - float monster_speed_run; - float monster_speed_walk; - entity monster_target; - -MUTATOR_HOOKABLE(MonsterFindTarget); - // called when a monster looks for another target - -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 frag_inflictor; -// entity frag_attacker; -// entity frag_target; // same as self - vector damage_force; // NOTE: this force already HAS been applied - // INPUT, OUTPUT: - float damage_take; - float damage_save; - -MUTATOR_HOOKABLE(PlayerDamage_Calculate); - // called to adjust damage and force values which are applied to the player, used for e.g. strength damage/force multiplier - // i'm not sure if I should change this around slightly (Naming of the entities, and also how they're done in g_damage). - // INPUT: -// entity frag_attacker; -// entity frag_target; -// float frag_deathtype; - // INPUT, OUTPUT: - float frag_damage; - float frag_mirrordamage; - vector frag_force; - -MUTATOR_HOOKABLE(PlayerPowerups); - // called at the end of player_powerups() in cl_client.qc, used for manipulating the values which are set by powerup items. - // 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 - // INPUT, OUTPUT: - float regen_mod_max; - float regen_mod_regen; - float regen_mod_rot; - float regen_mod_limit; - -MUTATOR_HOOKABLE(PlayerUseKey); - // called when the use key is pressed - // if MUTATOR_RETURNVALUE is 1, don't do anything - // return 1 if the use key actually did something - -MUTATOR_HOOKABLE(SV_ParseClientCommand); - // called when a client command is parsed - // NOTE: hooks MUST start with if(MUTATOR_RETURNVALUE) return 0; - // NOTE: return 1 if you handled the command, return 0 to continue handling - // NOTE: THESE HOOKS MUST NEVER EVER CALL tokenize() - // INPUT - string cmd_name; // command name - float cmd_argc; // also, argv() can be used - string cmd_string; // whole command, use only if you really have to - /* - // example: - MUTATOR_HOOKFUNCTION(foo_SV_ParseClientCommand) - { - if(MUTATOR_RETURNVALUE) // command was already handled? - return 0; - if(cmd_name == "echocvar" && cmd_argc >= 2) - { - print(cvar_string(argv(1)), "\n"); - return 1; - } - if(cmd_name == "echostring" && cmd_argc >= 2) - { - print(substring(cmd_string, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)), "\n"); - return 1; - } - return 0; - } - */ - -MUTATOR_HOOKABLE(Spawn_Score); - // called when a spawnpoint is being evaluated - // return 1 to make the spawnpoint unusable - // INPUT -// entity self; // player wanting to spawn -// entity spawn_spot; // spot to be evaluated - // IN+OUT - vector spawn_score; // _x is priority, _y is "distance" - -MUTATOR_HOOKABLE(SV_StartFrame); - // runs globally each server frame - -MUTATOR_HOOKABLE(SetModname); - // OUT -// string modname; // name of the mutator/mod if it warrants showing as such in the server browser - -MUTATOR_HOOKABLE(Item_Spawn); - // called for each item being spawned on a map, including dropped weapons - // return 1 to remove an item - // INPUT -// entity self; // the item - -MUTATOR_HOOKABLE(SetWeaponreplace); - // IN -// entity self; // map entity -// entity other; // weapon info - // IN+OUT -// string ret_string; - -MUTATOR_HOOKABLE(Item_RespawnCountdown); - // called when an item is about to respawn - // INPUT+OUTPUT: - string item_name; - vector item_color; - -MUTATOR_HOOKABLE(BotShouldAttack); - // called when a bot checks a target to attack - // INPUT - entity checkentity; - -MUTATOR_HOOKABLE(PortalTeleport); - // called whenever a player goes through a portal gun teleport - // allows you to strip a player of an item if they go through the teleporter to help prevent cheating - // INPUT -// entity self; - -MUTATOR_HOOKABLE(HelpMePing); - // called whenever a player uses impulse 33 (help me) in cl_impulse.qc - // normally help me ping uses self.waypointsprite_attachedforcarrier, - // but if your mutator uses something different then you can handle it - // in a special manner using this hook - // INPUT -// entity self; // the player who pressed impulse 33 - -MUTATOR_HOOKABLE(VehicleSpawn); - // called when a vehicle initializes - // return true to remove the vehicle - -MUTATOR_HOOKABLE(VehicleEnter); - // called when a player enters a vehicle - // allows mutators to set special settings in this event - // INPUT - entity vh_player; // player - entity vh_vehicle; // vehicle - -MUTATOR_HOOKABLE(VehicleTouch); - // called when a player touches a vehicle - // return true to stop player from entering the vehicle - // INPUT -// entity self; // vehicle -// entity other; // player - -MUTATOR_HOOKABLE(VehicleExit); - // called when a player exits a vehicle - // allows mutators to set special settings in this event - // INPUT -// entity vh_player; // player -// entity vh_vehicle; // vehicle - -MUTATOR_HOOKABLE(AbortSpeedrun); - // called when a speedrun is aborted and the player is teleported back to start position - // INPUT -// entity self; // player - -MUTATOR_HOOKABLE(ItemTouch); - // called at when a item is touched. Called early, can edit item properties. -// entity self; // item -// entity other; // player - const float MUT_ITEMTOUCH_CONTINUE = 0; // return this flag to make the function continue as normal - const float MUT_ITEMTOUCH_RETURN = 1; // return this flag to make the function return (handled entirely by mutator) - const float MUT_ITEMTOUCH_PICKUP = 2; // return this flag to have the item "picked up" and taken even after mutator handled it - -MUTATOR_HOOKABLE(ClientConnect); - // called at when a player connect -// entity self; // player - -MUTATOR_HOOKABLE(HavocBot_ChooseRole); -// entity self; - -MUTATOR_HOOKABLE(AccuracyTargetValid); - // called when a target is checked for accuracy -// entity frag_attacker; // attacker -// entity frag_target; // target - const float MUT_ACCADD_VALID = 0; // return this flag to make the function continue if target is a client - const float MUT_ACCADD_INVALID = 1; // return this flag to make the function always continue - const float MUT_ACCADD_INDIFFERENT = 2; // return this flag to make the function always return +#define EV_NO_ARGS(i, o) + +/** called when a player becomes observer, after shared setup */ +#define EV_MakePlayerObserver(i, o) \ + /**/ +MUTATOR_HOOKABLE(MakePlayerObserver, EV_MakePlayerObserver) + +/** */ +#define EV_PutClientInServer(i, o) \ + /** client wanting to spawn */ i(entity, self) \ + /**/ +MUTATOR_HOOKABLE(PutClientInServer, EV_PutClientInServer); + +/** called when a player spawns as player, after shared setup, before his weapon is chosen (so items may be changed in here) */ +#define EV_PlayerSpawn(i, o) \ + /** spot that was used, or world */ i(entity, spawn_spot) \ + /**/ +entity spawn_spot; +MUTATOR_HOOKABLE(PlayerSpawn, EV_PlayerSpawn); + +/** called in reset_map */ +#define EV_reset_map_global(i, o) \ + /**/ +MUTATOR_HOOKABLE(reset_map_global, EV_reset_map_global); + +/** called in reset_map */ +#define EV_reset_map_players(i, o) \ + /**/ +MUTATOR_HOOKABLE(reset_map_players, EV_reset_map_players); + +/** returns 1 if clearing player score shall not be allowed */ +#define EV_ForbidPlayerScore_Clear(i, o) \ + /**/ +MUTATOR_HOOKABLE(ForbidPlayerScore_Clear, EV_ForbidPlayerScore_Clear); + +/** called when a player disconnects */ +#define EV_ClientDisconnect(i, o) \ + /**/ +MUTATOR_HOOKABLE(ClientDisconnect, EV_ClientDisconnect); + +/** called when a player dies to e.g. remove stuff he was carrying. */ +#define EV_PlayerDies(i, o) \ + /**/ i(entity, frag_inflictor) \ + /**/ i(entity, frag_attacker) \ + /** same as self */ i(entity, frag_target) \ + /**/ i(int, frag_deathtype) \ + /**/ +entity frag_inflictor; +entity frag_attacker; +entity frag_target; +int frag_deathtype; +MUTATOR_HOOKABLE(PlayerDies, EV_PlayerDies); + +/** called when a player presses the jump key */ +#define EV_PlayerJump(i, o) \ + /**/ i(float, player_multijump) \ + /**/ i(float, player_jumpheight) \ + /**/ o(float, player_multijump) \ + /**/ o(float, player_jumpheight) \ + /**/ +float player_multijump; +float player_jumpheight; +MUTATOR_HOOKABLE(PlayerJump, EV_PlayerJump); + +/** called when someone was fragged by "self", and is expected to change frag_score to adjust scoring for the kill */ +#define EV_GiveFragsForKill(i, o) \ + /** same as self */ i(entity, frag_attacker) \ + /**/ i(entity, frag_target) \ + /**/ i(float, frag_score) \ + /**/ o(float, frag_score) \ + /**/ +float frag_score; +MUTATOR_HOOKABLE(GiveFragsForKill, EV_GiveFragsForKill); + +/** called when the match ends */ +MUTATOR_HOOKABLE(MatchEnd, EV_NO_ARGS); + +/** should adjust ret_float to contain the team count */ +#define EV_GetTeamCount(i, o) \ + /**/ i(float, ret_float) \ + /**/ o(float, ret_float) \ + /**/ +float ret_float; +MUTATOR_HOOKABLE(GetTeamCount, EV_GetTeamCount); + +/** copies variables for spectating "other" to "self" */ +#define EV_SpectateCopy(i, o) \ + /**/ i(entity, other) \ + /**/ i(entity, self) \ + /**/ +MUTATOR_HOOKABLE(SpectateCopy, EV_SpectateCopy); + +/** returns 1 if throwing the current weapon shall not be allowed */ +MUTATOR_HOOKABLE(ForbidThrowCurrentWeapon, EV_NO_ARGS); + +/** allows changing attack rate */ +#define EV_WeaponRateFactor(i, o) \ + /**/ i(float, weapon_rate) \ + /**/ o(float, weapon_rate) \ + /**/ +float weapon_rate; +MUTATOR_HOOKABLE(WeaponRateFactor, EV_WeaponRateFactor); + +/** allows changing weapon speed (projectiles mostly) */ +#define EV_WeaponSpeedFactor(i, o) \ + /**/ i(float, ret_float) \ + /**/ o(float, ret_float) \ + /**/ +MUTATOR_HOOKABLE(WeaponSpeedFactor, EV_WeaponSpeedFactor); + +/** adjusts {warmup_}start_{items,weapons,ammo_{cells,plasma,rockets,nails,shells,fuel}} */ +MUTATOR_HOOKABLE(SetStartItems, EV_NO_ARGS); + +/** appends ":mutatorname" to ret_string for logging */ +#define EV_BuildMutatorsString(i, o) \ + /**/ i(string, ret_string) \ + /**/ o(string, ret_string) \ + /**/ +string ret_string; +MUTATOR_HOOKABLE(BuildMutatorsString, EV_BuildMutatorsString); + +/** appends ", Mutator name" to ret_string for display */ +#define EV_BuildMutatorsPrettyString(i, o) \ + /**/ i(string, ret_string) \ + /**/ o(string, ret_string) \ + /**/ +MUTATOR_HOOKABLE(BuildMutatorsPrettyString, EV_BuildMutatorsPrettyString); + +/** called every frame. customizes the waypoint for spectators */ +#define EV_CustomizeWaypoint(i, o) \ + /** waypoint */ i(entity, self) \ + /** player; other.enemy = spectator */ i(entity, other) \ + /**/ +MUTATOR_HOOKABLE(CustomizeWaypoint, EV_CustomizeWaypoint); + +/** + * checks if the current item may be spawned (self.items and self.weapons may be read and written to, as well as the ammo_ fields) + * return error to request removal + */ +MUTATOR_HOOKABLE(FilterItem, EV_NO_ARGS); + +/** return error to request removal */ +#define EV_TurretSpawn(i, o) \ + /** turret */ i(entity, self) \ + /**/ +MUTATOR_HOOKABLE(TurretSpawn, EV_TurretSpawn); + +/** return error to prevent entity spawn, or modify the entity */ +MUTATOR_HOOKABLE(OnEntityPreSpawn, EV_NO_ARGS); + +/** runs in the event loop for players; is called for ALL player entities, also bots, also the dead, or spectators */ +MUTATOR_HOOKABLE(PlayerPreThink, EV_NO_ARGS); + +/** TODO change this into a general PlayerPostThink hook? */ +MUTATOR_HOOKABLE(GetPressedKeys, EV_NO_ARGS); + +/** + * called before any player physics, may adjust variables for movement, + * is run AFTER bot code and idle checking + */ +MUTATOR_HOOKABLE(PlayerPhysics, EV_NO_ARGS); + +/** is meant to call GetCvars_handle*(get_cvars_s, get_cvars_f, cvarfield, "cvarname") for cvars this mutator needs from the client */ +#define EV_GetCvars(i, o) \ + /**/ i(float, get_cvars_f) \ + /**/ i(string, get_cvars_s) \ + /**/ +float get_cvars_f; +string get_cvars_s; +MUTATOR_HOOKABLE(GetCvars, EV_NO_ARGS); // NOTE: Can't use EV_GetCvars because of `SZ_GetSpace: overflow` + +/** can edit any "just fired" projectile */ +#define EV_EditProjectile(i, o) \ + /**/ i(entity, self) \ + /**/ i(entity, other) \ + /**/ +MUTATOR_HOOKABLE(EditProjectile, EV_EditProjectile); + +/** called when a monster spawns */ +MUTATOR_HOOKABLE(MonsterSpawn, EV_NO_ARGS); + +/** called when a monster dies */ +#define EV_MonsterDies(i, o) \ + /**/ i(entity, frag_attacker) \ + /**/ +MUTATOR_HOOKABLE(MonsterDies, EV_MonsterDies); + +/** called when a monster wants to respawn */ +#define EV_MonsterRespawn(i, o) \ + /**/ i(entity, other) \ + /**/ +MUTATOR_HOOKABLE(MonsterRespawn, EV_MonsterRespawn); + +/** called when a monster is dropping loot */ +#define EV_MonsterDropItem(i, o) \ + /**/ i(entity, other) \ + /**/ o(entity, other) \ + /**/ +.void() monster_loot; +MUTATOR_HOOKABLE(MonsterDropItem, EV_MonsterDropItem); + +/** + * called when a monster moves + * returning true makes the monster stop + */ +#define EV_MonsterMove(i, o) \ + /**/ i(float, monster_speed_run) \ + /**/ o(float, monster_speed_run) \ + /**/ i(float, monster_speed_walk) \ + /**/ o(float, monster_speed_walk) \ + /**/ i(entity, monster_target) \ + /**/ +float monster_speed_run; +float monster_speed_walk; +entity monster_target; +MUTATOR_HOOKABLE(MonsterMove, EV_MonsterMove); + +/** called when a monster looks for another target */ +MUTATOR_HOOKABLE(MonsterFindTarget, EV_NO_ARGS); + +/** called to change a random monster to a miniboss */ +MUTATOR_HOOKABLE(MonsterCheckBossFlag, EV_NO_ARGS); + +/** + * called when a player tries to spawn a monster + * return 1 to prevent spawning + */ +MUTATOR_HOOKABLE(AllowMobSpawning, EV_NO_ARGS); + +/** called when a player gets damaged to e.g. remove stuff he was carrying. */ +#define EV_PlayerDamage_SplitHealthArmor(i, o) \ + /**/ i(entity, frag_inflictor) \ + /**/ i(entity, frag_attacker) \ + /** same as self */ i(entity, frag_target) \ + /** NOTE: this force already HAS been applied */ i(vector, damage_force) \ + /**/ i(float, damage_take) \ + /**/ o(float, damage_take) \ + /**/ i(float, damage_save) \ + /**/ o(float, damage_save) \ + /**/ +vector damage_force; +float damage_take; +float damage_save; +MUTATOR_HOOKABLE(PlayerDamage_SplitHealthArmor, EV_PlayerDamage_SplitHealthArmor); + +/** + * called to adjust damage and force values which are applied to the player, used for e.g. strength damage/force multiplier + * i'm not sure if I should change this around slightly (Naming of the entities, and also how they're done in g_damage). + */ +#define EV_PlayerDamage_Calculate(i, o) \ + /**/ i(entity, frag_attacker) \ + /**/ i(entity, frag_target) \ + /**/ i(float, frag_deathtype) \ + /**/ i(float, frag_damage) \ + /**/ o(float, frag_damage) \ + /**/ i(float, frag_mirrordamage) \ + /**/ o(float, frag_mirrordamage) \ + /**/ i(vector, frag_force) \ + /**/ o(vector, frag_force) \ + /**/ +float frag_damage; +float frag_mirrordamage; +vector frag_force; +MUTATOR_HOOKABLE(PlayerDamage_Calculate, EV_PlayerDamage_Calculate); + +/** called at the end of player_powerups() in cl_client.qc, used for manipulating the values which are set by powerup items. */ +#define EV_PlayerPowerups(i, o) \ + /**/ i(entity, self) \ + /**/ i(int, olditems) \ + /**/ +int olditems; +MUTATOR_HOOKABLE(PlayerPowerups, EV_PlayerPowerups); + +/** + * called every player think frame + * return 1 to disable regen + */ +#define EV_PlayerRegen(i, o) \ + /**/ i(float, regen_mod_max) \ + /**/ o(float, regen_mod_max) \ + /**/ i(float, regen_mod_regen) \ + /**/ o(float, regen_mod_regen) \ + /**/ i(float, regen_mod_rot) \ + /**/ o(float, regen_mod_rot) \ + /**/ i(float, regen_mod_limit) \ + /**/ o(float, regen_mod_limit) \ + /**/ +float regen_mod_max; +float regen_mod_regen; +float regen_mod_rot; +float regen_mod_limit; +MUTATOR_HOOKABLE(PlayerRegen, EV_PlayerRegen); + +/** + * called when the use key is pressed + * if MUTATOR_RETURNVALUE is 1, don't do anything + * return 1 if the use key actually did something + */ +MUTATOR_HOOKABLE(PlayerUseKey, EV_NO_ARGS); + +/** + * called when a client command is parsed + * NOTE: hooks MUST start with if(MUTATOR_RETURNVALUE) return 0; + * NOTE: return 1 if you handled the command, return 0 to continue handling + * NOTE: THESE HOOKS MUST NEVER EVER CALL tokenize() + * // example: + * MUTATOR_HOOKFUNCTION(foo_SV_ParseClientCommand) + * { + * if (MUTATOR_RETURNVALUE) // command was already handled? + * return false; + * if (cmd_name == "echocvar" && cmd_argc >= 2) + * { + * print(cvar_string(argv(1)), "\n"); + * return true; + * } + * if (cmd_name == "echostring" && cmd_argc >= 2) + * { + * print(substring(cmd_string, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)), "\n"); + * return true; + * } + * return false; + * } + */ +#define EV_SV_ParseClientCommand(i, o) \ + /** command name */ i(string, cmd_name) \ + /** also, argv() can be used */ i(int, cmd_argc) \ + /** whole command, use only if you really have to */ i(string, cmd_string) \ + /**/ +string cmd_name; +int cmd_argc; +string cmd_string; +MUTATOR_HOOKABLE(SV_ParseClientCommand, EV_SV_ParseClientCommand); + +/** + * called when a spawnpoint is being evaluated + * return 1 to make the spawnpoint unusable + */ +#define EV_Spawn_Score(i, o) \ + /** player wanting to spawn */ i(entity, self) \ + /** spot to be evaluated */ i(entity, spawn_spot) \ + /** _x is priority, _y is "distance" */ i(vector, spawn_score) \ + /**/ o(vector, spawn_score) \ + /**/ +vector spawn_score; +MUTATOR_HOOKABLE(Spawn_Score, EV_Spawn_Score); + +/** runs globally each server frame */ +MUTATOR_HOOKABLE(SV_StartFrame, EV_NO_ARGS); + +#define EV_SetModname(i, o) \ + /** name of the mutator/mod if it warrants showing as such in the server browser */ \ + o(string, modname) \ + /**/ +MUTATOR_HOOKABLE(SetModname, EV_SetModname); + +/** + * called for each item being spawned on a map, including dropped weapons + * return 1 to remove an item + */ +#define EV_Item_Spawn(i, o) \ + /** the item */ i(entity, self) \ + /**/ +MUTATOR_HOOKABLE(Item_Spawn, EV_Item_Spawn); + +#define EV_SetWeaponreplace(i, o) \ + /** map entity */ i(entity, self) \ + /** weapon info */ i(entity, other) \ + /**/ i(string, ret_string) \ + /**/ o(string, ret_string) \ + /**/ +MUTATOR_HOOKABLE(SetWeaponreplace, EV_SetWeaponreplace); + +/** called when an item is about to respawn */ +#define EV_Item_RespawnCountdown(i, o) \ + /**/ i(string, item_name) \ + /**/ o(string, item_name) \ + /**/ i(vector, item_color) \ + /**/ o(vector, item_color) \ + /**/ +string item_name; +vector item_color; +MUTATOR_HOOKABLE(Item_RespawnCountdown, EV_Item_RespawnCountdown); + +/** called when a bot checks a target to attack */ +#define EV_BotShouldAttack(i, o) \ + /**/ i(entity, checkentity) \ + /**/ +entity checkentity; +MUTATOR_HOOKABLE(BotShouldAttack, EV_BotShouldAttack); + +/** + * called whenever a player goes through a portal gun teleport + * allows you to strip a player of an item if they go through the teleporter to help prevent cheating + */ +#define EV_PortalTeleport(i, o) \ + /**/ i(entity, self) \ + /**/ +MUTATOR_HOOKABLE(PortalTeleport, EV_PortalTeleport); + +/** + * called whenever a player uses impulse 33 (help me) in cl_impulse.qc + * normally help me ping uses self.waypointsprite_attachedforcarrier, + * but if your mutator uses something different then you can handle it + * in a special manner using this hook + */ +#define EV_HelpMePing(i, o) \ + /** the player who pressed impulse 33 */ i(entity, self) \ + /**/ +MUTATOR_HOOKABLE(HelpMePing, EV_HelpMePing); + +/** + * called when a vehicle initializes + * return true to remove the vehicle + */ +MUTATOR_HOOKABLE(VehicleSpawn, EV_NO_ARGS); + +/** + * called when a player enters a vehicle + * allows mutators to set special settings in this event + */ +#define EV_VehicleEnter(i, o) \ + /** player */ i(entity, vh_player) \ + /** vehicle */ i(entity, vh_vehicle) \ + /**/ +entity vh_player; +entity vh_vehicle; +MUTATOR_HOOKABLE(VehicleEnter, EV_VehicleEnter); + +/** + * called when a player touches a vehicle + * return true to stop player from entering the vehicle + */ +#define EV_VehicleTouch(i, o) \ + /** vehicle */ i(entity, self) \ + /** player */ i(entity, other) \ + /**/ +MUTATOR_HOOKABLE(VehicleTouch, EV_VehicleTouch); + +/** + * called when a player exits a vehicle + * allows mutators to set special settings in this event + */ +#define EV_VehicleExit(i, o) \ + /** player */ i(entity, vh_player) \ + /** vehicle */ i(entity, vh_vehicle) \ + /**/ +MUTATOR_HOOKABLE(VehicleExit, EV_VehicleExit); + +/** called when a speedrun is aborted and the player is teleported back to start position */ +#define EV_AbortSpeedrun(i, o) \ + /** player */ i(entity, self) \ + /**/ +MUTATOR_HOOKABLE(AbortSpeedrun, EV_AbortSpeedrun); + +/** called at when a item is touched. Called early, can edit item properties. */ +#define EV_ItemTouch(i, o) \ + /** item */ i(entity, self) \ + /** player */ i(entity, other) \ + /**/ +MUTATOR_HOOKABLE(ItemTouch, EV_ItemTouch); + +enum { + MUT_ITEMTOUCH_CONTINUE, // return this flag to make the function continue as normal + MUT_ITEMTOUCH_RETURN, // return this flag to make the function return (handled entirely by mutator) + MUT_ITEMTOUCH_PICKUP // return this flag to have the item "picked up" and taken even after mutator handled it +}; + +/** called at when a player connect */ +#define EV_ClientConnect(i, o) \ + /** player */ i(entity, self) \ + /**/ +MUTATOR_HOOKABLE(ClientConnect, EV_ClientConnect); + +#define EV_HavocBot_ChooseRole(i, o) \ + /**/ i(entity, self) \ + /**/ +MUTATOR_HOOKABLE(HavocBot_ChooseRole, EV_HavocBot_ChooseRole); + +/** called when a target is checked for accuracy */ +#define EV_AccuracyTargetValid(i, o) \ + /** attacker */ i(entity, frag_attacker) \ + /** target */ i(entity, frag_target) \ + /**/ +MUTATOR_HOOKABLE(AccuracyTargetValid, EV_AccuracyTargetValid); +enum { + MUT_ACCADD_VALID, // return this flag to make the function continue if target is a client + MUT_ACCADD_INVALID, // return this flag to make the function always continue + MUT_ACCADD_INDIFFERENT // return this flag to make the function always return +}; #endif diff --git a/qcsrc/server/mutators/mutator_buffs.qc b/qcsrc/server/mutators/mutator_buffs.qc index 170f59874..b582e1686 100644 --- a/qcsrc/server/mutators/mutator_buffs.qc +++ b/qcsrc/server/mutators/mutator_buffs.qc @@ -629,7 +629,7 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerThrowKey) if(closest.flagcarried) { ctf_Handle_Throw(closest, world, DROP_THROW); } if(closest.nade) { toss_nade(closest, '0 0 0', time + 0.05); } - MUTATOR_CALLHOOK(PortalTeleport); // initiate flag dropper + MUTATOR_CALLHOOK(PortalTeleport, self); // initiate flag dropper setorigin(self, their_org); setorigin(closest, my_org); diff --git a/qcsrc/server/mutators/mutator_nades.qc b/qcsrc/server/mutators/mutator_nades.qc index f4267716e..40f4f7247 100644 --- a/qcsrc/server/mutators/mutator_nades.qc +++ b/qcsrc/server/mutators/mutator_nades.qc @@ -360,11 +360,7 @@ void nade_translocate_boom() makevectors(self.realowner.angles); - entity oldself = self; - self = self.realowner; - MUTATOR_CALLHOOK(PortalTeleport); - self.realowner = self; - self = oldself; + MUTATOR_CALLHOOK(PortalTeleport, self.realowner); TeleportPlayer(self, self.realowner, locout, self.realowner.angles, v_forward * vlen(self.realowner.velocity), '0 0 0', '0 0 0', TELEPORT_FLAGS_TELEPORTER); } diff --git a/qcsrc/server/portals.qc b/qcsrc/server/portals.qc index ad8aea50c..438ff00d3 100644 --- a/qcsrc/server/portals.qc +++ b/qcsrc/server/portals.qc @@ -170,11 +170,7 @@ float Portal_TeleportPlayer(entity teleporter, entity player) // factor -1 allows chaining portals, but may be weird player.right_vector = -1 * AnglesTransform_Apply(transform, player.right_vector); - entity oldself = self; - self = player; - MUTATOR_CALLHOOK(PortalTeleport); - player = self; - self = oldself; + MUTATOR_CALLHOOK(PortalTeleport, player); if (!teleporter.enemy) { diff --git a/qcsrc/server/spawnpoints.qc b/qcsrc/server/spawnpoints.qc index b86da6b54..bc191f74f 100644 --- a/qcsrc/server/spawnpoints.qc +++ b/qcsrc/server/spawnpoints.qc @@ -228,7 +228,7 @@ vector Spawn_Score(entity spot, float mindist, float teamcheck) } } - MUTATOR_CALLHOOK(Spawn_Score); + MUTATOR_CALLHOOK(Spawn_Score, self, spawn_spot, spawn_score); return spawn_score; } diff --git a/qcsrc/server/t_items.qc b/qcsrc/server/t_items.qc index 873f7a53c..37af9ee86 100644 --- a/qcsrc/server/t_items.qc +++ b/qcsrc/server/t_items.qc @@ -644,9 +644,7 @@ void Item_RespawnCountdown (void) {name = "item_armor_large"; rgb = '0 1 0';} break; } - item_name = name; - item_color = rgb; - MUTATOR_CALLHOOK(Item_RespawnCountdown); + MUTATOR_CALLHOOK(Item_RespawnCountdown, name, rgb); name = item_name; rgb = item_color; if(self.flags & FL_WEAPON) @@ -903,7 +901,7 @@ void Item_Touch (void) if (time < self.item_spawnshieldtime) return; - switch(MUTATOR_CALLHOOK(ItemTouch)) + switch(MUTATOR_CALLHOOK(ItemTouch, self, other)) { case MUT_ITEMTOUCH_RETURN: { return; } case MUT_ITEMTOUCH_PICKUP: { goto pickup; } @@ -1358,7 +1356,7 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime, self.SendFlags |= ISF_ANGLES; // call this hook after everything else has been done - if(MUTATOR_CALLHOOK(Item_Spawn)) + if(MUTATOR_CALLHOOK(Item_Spawn, self)) { startitem_failed = true; remove(self); diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index ec6f5afc3..b19597cde 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -283,8 +283,7 @@ string getwelcomemessage(void) { string s, modifications, motd; - ret_string = ""; - MUTATOR_CALLHOOK(BuildMutatorsPrettyString); + MUTATOR_CALLHOOK(BuildMutatorsPrettyString, ""); modifications = ret_string; if(g_weaponarena) @@ -432,8 +431,7 @@ void CheckAllowedTeams (entity for_whom) // cover anything else by treating it like tdm with no teams spawned dm = 2; - ret_float = dm; - MUTATOR_CALLHOOK(GetTeamCount); + MUTATOR_CALLHOOK(GetTeamCount, dm); dm = ret_float; if(dm >= 4) diff --git a/qcsrc/server/tturrets/system/system_main.qc b/qcsrc/server/tturrets/system/system_main.qc index 694ff5d45..7e843142b 100644 --- a/qcsrc/server/tturrets/system/system_main.qc +++ b/qcsrc/server/tturrets/system/system_main.qc @@ -1271,7 +1271,7 @@ float turret_stdproc_init (string cvar_base_name, string base, string head, floa self.health = 150; // Game hooks - if(MUTATOR_CALLHOOK(TurretSpawn)) + if(MUTATOR_CALLHOOK(TurretSpawn, self)) return 0; // End of default & sanety checks, start building the turret. diff --git a/qcsrc/server/vehicles/bumblebee.qc b/qcsrc/server/vehicles/bumblebee.qc index 79eac74bb..5f124ff3b 100644 --- a/qcsrc/server/vehicles/bumblebee.qc +++ b/qcsrc/server/vehicles/bumblebee.qc @@ -162,11 +162,7 @@ void bumb_gunner_exit(float _exitflag) self.hud = HUD_NORMAL; self.switchweapon = self.vehicle.switchweapon; - vh_player = self; - vh_vehicle = self.vehicle; - MUTATOR_CALLHOOK(VehicleExit); - self = vh_player; - self.vehicle = vh_vehicle; + MUTATOR_CALLHOOK(VehicleExit, self, self.vehicle); self.vehicle.vehicle_hudmodel.viewmodelforclient = self.vehicle; @@ -250,11 +246,7 @@ float bumb_gunner_enter() CSQCVehicleSetup(other, other.hud); - vh_player = other; - vh_vehicle = _gun; - MUTATOR_CALLHOOK(VehicleEnter); - other = vh_player; - _gun = vh_vehicle; + MUTATOR_CALLHOOK(VehicleEnter, other, _gun); return true; } diff --git a/qcsrc/server/vehicles/vehicle.qc b/qcsrc/server/vehicles/vehicle.qc index e6a0f9c0e..50f355d73 100644 --- a/qcsrc/server/vehicles/vehicle.qc +++ b/qcsrc/server/vehicles/vehicle.qc @@ -550,7 +550,7 @@ void vehicles_impact(float _minspeed, float _speedfac, float _maxpain) void vehicles_touch() { - if(MUTATOR_CALLHOOK(VehicleTouch)) + if(MUTATOR_CALLHOOK(VehicleTouch, self, other)) return; // Vehicle currently in use @@ -683,11 +683,7 @@ void vehicles_enter() CSQCVehicleSetup(self.owner, self.hud); - vh_player = other; - vh_vehicle = self; - MUTATOR_CALLHOOK(VehicleEnter); - other = vh_player; - self = vh_vehicle; + MUTATOR_CALLHOOK(VehicleEnter, other, self); self.vehicle_enter(); antilag_clear(other); @@ -823,11 +819,7 @@ void vehicles_exit(float eject) if(!teamplay) _vehicle.team = 0; - vh_player = _player; - vh_vehicle = _vehicle; - MUTATOR_CALLHOOK(VehicleExit); - _player = vh_player; - _vehicle = vh_vehicle; + MUTATOR_CALLHOOK(VehicleExit, _player, _vehicle); _vehicle.team = _vehicle.tur_head.team; diff --git a/qcsrc/server/waypointsprites.qc b/qcsrc/server/waypointsprites.qc index b0c8cb122..6130b6165 100644 --- a/qcsrc/server/waypointsprites.qc +++ b/qcsrc/server/waypointsprites.qc @@ -248,10 +248,9 @@ float WaypointSprite_Customize() // this is not in SendEntity because it shall run every frame, not just every update // make spectators see what the player would see - entity e; - e = WaypointSprite_getviewentity(other); + entity e = WaypointSprite_getviewentity(other); - if(MUTATOR_CALLHOOK(CustomizeWaypoint)) + if(MUTATOR_CALLHOOK(CustomizeWaypoint, self, other)) return false; return self.waypointsprite_visible_for_player(e); diff --git a/qcsrc/server/weapons/accuracy.qc b/qcsrc/server/weapons/accuracy.qc index 1ef81a409..d0dda35af 100644 --- a/qcsrc/server/weapons/accuracy.qc +++ b/qcsrc/server/weapons/accuracy.qc @@ -113,9 +113,7 @@ void accuracy_add(entity e, int w, float fired, float hit) float accuracy_isgooddamage(entity attacker, entity targ) { - frag_attacker = attacker; - frag_target = targ; - float mutator_check = MUTATOR_CALLHOOK(AccuracyTargetValid); + float mutator_check = MUTATOR_CALLHOOK(AccuracyTargetValid, attacker, targ); if(!warmup_stage) if(targ.deadflag == DEAD_NO) diff --git a/qcsrc/server/weapons/spawning.qc b/qcsrc/server/weapons/spawning.qc index 9096b2f9c..8e7810bbb 100644 --- a/qcsrc/server/weapons/spawning.qc +++ b/qcsrc/server/weapons/spawning.qc @@ -55,9 +55,7 @@ void weapon_defaultspawnfunc(float wpn) } s = W_Apply_Weaponreplace(e.netname); - ret_string = s; - other = e; - MUTATOR_CALLHOOK(SetWeaponreplace); + MUTATOR_CALLHOOK(SetWeaponreplace, self, e, s); s = ret_string; if(s == "") { diff --git a/qcsrc/server/weapons/weaponsystem.qc b/qcsrc/server/weapons/weaponsystem.qc index 4f072c4c0..d06d11cd9 100644 --- a/qcsrc/server/weapons/weaponsystem.qc +++ b/qcsrc/server/weapons/weaponsystem.qc @@ -28,11 +28,9 @@ float W_WeaponRateFactor() { - float t; - t = 1.0 / g_weaponratefactor; + float t = 1.0 / g_weaponratefactor; - weapon_rate = t; - MUTATOR_CALLHOOK(WeaponRateFactor); + MUTATOR_CALLHOOK(WeaponRateFactor, t); t = weapon_rate; return t; @@ -40,11 +38,9 @@ float W_WeaponRateFactor() float W_WeaponSpeedFactor() { - float t; - t = 1.0 * g_weaponspeedfactor; + float t = 1.0 * g_weaponspeedfactor; - ret_float = t; - MUTATOR_CALLHOOK(WeaponSpeedFactor); + MUTATOR_CALLHOOK(WeaponSpeedFactor, t); t = ret_float; return t;