]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/events.qh
Merge branch 'sev/lumaIcons' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / events.qh
index 09e1cf70bd212497b69907be4ec13c31e97d33ca..a4cf9df8ef30cc5e6554f4403112a28723a07e84 100644 (file)
@@ -4,6 +4,9 @@
 
 // register all possible hooks here
 
+// to use a hook, first register your mutator using REGISTER_MUTATOR
+// then create your function using MUTATOR_HOOKFUNCTION
+
 /** called when a player becomes observer, after shared setup */
 #define EV_MakePlayerObserver(i, o) \
     /** player */ i(entity, MUTATOR_ARGV_0_entity) \
@@ -24,6 +27,18 @@ MUTATOR_HOOKABLE(PutClientInServer, EV_PutClientInServer);
     /**/
 MUTATOR_HOOKABLE(ForbidSpawn, EV_ForbidSpawn);
 
+/** returns true if client should be put as player on connection */
+#define EV_AutoJoinOnConnection(i, o) \
+    /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+    /**/
+MUTATOR_HOOKABLE(AutoJoinOnConnection, EV_AutoJoinOnConnection);
+
+/** called when player spawns to determine whether to give them random start weapons. Return true to forbid giving them. */
+#define EV_ForbidRandomStartWeapons(i, o) \
+       /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+    /**/
+MUTATOR_HOOKABLE(ForbidRandomStartWeapons, EV_ForbidRandomStartWeapons);
+
 /** 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) \
        /** player spawning */ i(entity, MUTATOR_ARGV_0_entity) \
@@ -31,6 +46,12 @@ MUTATOR_HOOKABLE(ForbidSpawn, EV_ForbidSpawn);
     /**/
 MUTATOR_HOOKABLE(PlayerSpawn, EV_PlayerSpawn);
 
+/** called after a player's weapon is chosen so it can be overriden here */
+#define EV_PlayerWeaponSelect(i, o) \
+       /** player spawning */ i(entity, MUTATOR_ARGV_0_entity) \
+    /**/
+MUTATOR_HOOKABLE(PlayerWeaponSelect, EV_PlayerWeaponSelect);
+
 /** called in reset_map */
 #define EV_reset_map_global(i, o) \
     /**/
@@ -58,11 +79,17 @@ MUTATOR_HOOKABLE(ClientDisconnect, EV_ClientDisconnect);
     /** attacker       */ i(entity, MUTATOR_ARGV_1_entity) \
     /** target                 */ i(entity, MUTATOR_ARGV_2_entity) \
     /** deathtype      */ i(float,  MUTATOR_ARGV_3_float) \
-    /** damage          */ i(float,  MUTATOR_ARGV_4_float) \
+    /** damage         */ i(float,  MUTATOR_ARGV_4_float) \
     /** damage                 */ o(float,  MUTATOR_ARGV_4_float) \
     /**/
 MUTATOR_HOOKABLE(PlayerDies, EV_PlayerDies);
 
+/** called after a player died. */
+#define EV_PlayerDied(i, o) \
+    /** player                 */ i(entity, MUTATOR_ARGV_0_entity) \
+    /**/
+MUTATOR_HOOKABLE(PlayerDied, EV_PlayerDied);
+
 /** allows overriding the frag centerprint messages */
 #define EV_FragCenterMessage(i, o) \
     /** attacker       */ i(entity, MUTATOR_ARGV_0_entity) \
@@ -80,14 +107,6 @@ MUTATOR_HOOKABLE(FragCenterMessage, EV_FragCenterMessage);
     /**/
 MUTATOR_HOOKABLE(PlayHitsound, EV_PlayHitsound);
 
-/** called when a weapon sound is about to be played, allows custom paths etc. */
-#define EV_WeaponSound(i, o) \
-    /** sound       */ i(string, MUTATOR_ARGV_0_string) \
-    /** output      */ i(string, MUTATOR_ARGV_1_string) \
-    /**/               o(string, MUTATOR_ARGV_1_string) \
-    /**/
-MUTATOR_HOOKABLE(WeaponSound, EV_WeaponSound);
-
 /** called when an item model is about to be set, allows custom paths etc. */
 #define EV_ItemModel(i, o) \
     /** model       */ i(string, MUTATOR_ARGV_0_string) \
@@ -110,6 +129,8 @@ MUTATOR_HOOKABLE(ItemSound, EV_ItemSound);
     /** target     */ i(entity, MUTATOR_ARGV_1_entity) \
     /** frag score */ i(float, MUTATOR_ARGV_2_float) \
     /**            */ o(float, MUTATOR_ARGV_2_float) \
+    /** deathtype  */ i(float, MUTATOR_ARGV_3_float) \
+    /** wep entity */ i(entity, MUTATOR_ARGV_4_entity) \
     /**/
 MUTATOR_HOOKABLE(GiveFragsForKill, EV_GiveFragsForKill);
 
@@ -122,9 +143,35 @@ MUTATOR_HOOKABLE(MatchEnd, EV_NO_ARGS);
     /**/                      o(float, MUTATOR_ARGV_0_float) \
     /** team entity name   */ i(string, MUTATOR_ARGV_1_string) \
     /**/                      o(string, MUTATOR_ARGV_1_string) \
+    /** player checked     */ i(entity, MUTATOR_ARGV_2_entity) \
     /**/
 MUTATOR_HOOKABLE(CheckAllowedTeams, EV_CheckAllowedTeams);
 
+/** return true to manually override team counts */
+MUTATOR_HOOKABLE(GetTeamCounts, EV_NO_ARGS);
+
+/** allow overriding of team counts */
+#define EV_GetTeamCount(i, o) \
+    /** team to count                   */ i(float, MUTATOR_ARGV_0_float) \
+    /** player to ignore                */ i(entity, MUTATOR_ARGV_1_entity) \
+    /** number of players in a team     */ i(float, MUTATOR_ARGV_2_float) \
+    /**/                                   o(float, MUTATOR_ARGV_2_float) \
+    /** number of bots in a team        */ i(float, MUTATOR_ARGV_3_float) \
+    /**/                                   o(float, MUTATOR_ARGV_3_float) \
+    /** lowest scoring human in a team  */ i(entity, MUTATOR_ARGV_4_entity) \
+    /**/                                   o(entity, MUTATOR_ARGV_4_entity) \
+    /** lowest scoring bot in a team    */ i(entity, MUTATOR_ARGV_5_entity) \
+    /**/                                   o(entity, MUTATOR_ARGV_5_entity) \
+    /**/
+MUTATOR_HOOKABLE(GetTeamCount, EV_GetTeamCount);
+
+/** allows overriding best teams */
+#define EV_FindBestTeams(i, o) \
+    /** player checked   */ i(entity, MUTATOR_ARGV_0_entity) \
+    /** bitmask of teams */ o(float, MUTATOR_ARGV_1_float) \
+    /**/
+MUTATOR_HOOKABLE(FindBestTeams, EV_FindBestTeams);
+
 /** copies variables for spectating "spectatee" to "this" */
 #define EV_SpectateCopy(i, o) \
     /** spectatee   */ i(entity, MUTATOR_ARGV_0_entity) \
@@ -153,12 +200,14 @@ MUTATOR_HOOKABLE(PreFormatMessage, EV_PreFormatMessage);
 /** returns true if throwing the current weapon shall not be allowed */
 #define EV_ForbidThrowCurrentWeapon(i, o) \
     /** player        */ i(entity, MUTATOR_ARGV_0_entity) \
+    /** weapon entity */ i(entity, MUTATOR_ARGV_1_entity) \
     /**/
 MUTATOR_HOOKABLE(ForbidThrowCurrentWeapon, EV_ForbidThrowCurrentWeapon);
 
 /** returns true if dropping the current weapon shall not be allowed at any time including death */
 #define EV_ForbidDropCurrentWeapon(i, o) \
-    /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+    /** player */        i(entity, MUTATOR_ARGV_0_entity) \
+    /** weapon id */     i(int, MUTATOR_ARGV_1_int) \
     /**/
 MUTATOR_HOOKABLE(ForbidDropCurrentWeapon, EV_ForbidDropCurrentWeapon);
 
@@ -191,8 +240,16 @@ MUTATOR_HOOKABLE(SetStartItems, EV_NO_ARGS);
     /**/
 MUTATOR_HOOKABLE(CustomizeWaypoint, EV_CustomizeWaypoint);
 
+/** Check if items having the given definition are allowed to spawn.
+ *  Return true to disallow spawning.
+ */
+#define EV_FilterItemDefinition(i, o) \
+    /** item        */ i(entity, MUTATOR_ARGV_0_entity) \
+    /**/
+MUTATOR_HOOKABLE(FilterItemDefinition, EV_FilterItemDefinition);
+
 /**
- * checks if the current item may be spawned (.items and .weapons may be read and written to, as well as the ammo_ fields)
+ * checks if the current item may be spawned (.items may be read and written to, as well as the ammo_ fields)
  * return error to request removal
  */
 #define EV_FilterItem(i, o) \
@@ -286,7 +343,7 @@ MUTATOR_HOOKABLE(MonsterRespawn, EV_MonsterRespawn);
     /**/                                   o(entity, MUTATOR_ARGV_1_entity) \
     /* attacker */                         i(entity, MUTATOR_ARGV_2_entity) \
     /**/
-.void(entity this) monster_loot;
+.entity monster_loot;
 MUTATOR_HOOKABLE(MonsterDropItem, EV_MonsterDropItem);
 
 /**
@@ -300,6 +357,7 @@ MUTATOR_HOOKABLE(MonsterDropItem, EV_MonsterDropItem);
     /** walk speed */    i(float, MUTATOR_ARGV_2_float) \
     /**/                 o(float, MUTATOR_ARGV_2_float) \
     /** move target */   i(entity, MUTATOR_ARGV_3_entity) \
+    /**/                 o(entity, MUTATOR_ARGV_3_entity) \
     /**/
 MUTATOR_HOOKABLE(MonsterMove, EV_MonsterMove);
 
@@ -351,7 +409,7 @@ 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) \
+#define EV_Damage_Calculate(i, o) \
     /** inflictor              */ i(entity, MUTATOR_ARGV_0_entity) \
     /** attacker       */ i(entity, MUTATOR_ARGV_1_entity) \
     /** target                 */ i(entity, MUTATOR_ARGV_2_entity) \
@@ -361,9 +419,10 @@ MUTATOR_HOOKABLE(PlayerDamage_SplitHealthArmor, EV_PlayerDamage_SplitHealthArmor
     /** mirrordamage    */ i(float,  MUTATOR_ARGV_5_float) \
     /** mirrordamage   */ o(float,  MUTATOR_ARGV_5_float) \
     /** force           */ i(vector, MUTATOR_ARGV_6_vector) \
-    /** force                  */ o(vector, MUTATOR_ARGV_6_vector) \
+    /** force           */ o(vector, MUTATOR_ARGV_6_vector) \
+    /** weapon entity  */ i(entity, MUTATOR_ARGV_7_entity) \
     /**/
-MUTATOR_HOOKABLE(PlayerDamage_Calculate, EV_PlayerDamage_Calculate);
+MUTATOR_HOOKABLE(Damage_Calculate, EV_Damage_Calculate);
 
 /**
  * Called when a player is damaged
@@ -383,7 +442,10 @@ MUTATOR_HOOKABLE(PlayerDamaged, EV_PlayerDamaged);
  * Called by W_DecreaseAmmo
  */
 #define EV_W_DecreaseAmmo(i, o) \
-    /** actor */ i(entity, MUTATOR_ARGV_0_entity) \
+    /** actor */            i(entity, MUTATOR_ARGV_0_entity) \
+    /** weapon entity */    i(entity, MUTATOR_ARGV_1_entity) \
+    /** ammo to take */     i(float, MUTATOR_ARGV_2_float) \
+    /**/                    o(float, MUTATOR_ARGV_2_float) \
     /**/
 MUTATOR_HOOKABLE(W_DecreaseAmmo, EV_W_DecreaseAmmo);
 
@@ -521,10 +583,7 @@ MUTATOR_HOOKABLE(SetWeaponreplace, EV_SetWeaponreplace);
 
 /** called when an item is about to respawn */
 #define EV_Item_RespawnCountdown(i, o) \
-    /** item name */   i(string, MUTATOR_ARGV_0_string) \
-    /**/               o(string, MUTATOR_ARGV_0_string) \
-    /** item colour */ i(vector, MUTATOR_ARGV_1_vector) \
-    /**/               o(vector, MUTATOR_ARGV_1_vector) \
+    /** item */   i(entity, MUTATOR_ARGV_0_entity) \
     /**/
 MUTATOR_HOOKABLE(Item_RespawnCountdown, EV_Item_RespawnCountdown);
 
@@ -614,6 +673,102 @@ enum {
        MUT_ITEMTOUCH_PICKUP // return this flag to have the item "picked up" and taken even after mutator handled it
 };
 
+/** called after the item has been touched. */
+#define EV_ItemTouched(i, o) \
+    /** item */    i(entity, MUTATOR_ARGV_0_entity) \
+    /** toucher */ i(entity, MUTATOR_ARGV_1_entity) \
+    /**/
+MUTATOR_HOOKABLE(ItemTouched, EV_ItemTouched);
+
+/** Called when the amount of entity resources changes. Can be used to override
+resource limit. */
+#define EV_GetResourceLimit(i, o) \
+       /** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
+       /** resource type */  i(int, MUTATOR_ARGV_1_int) \
+       /** limit */          i(float, MUTATOR_ARGV_2_float) \
+       /**/                  o(float, MUTATOR_ARGV_2_float) \
+       /**/
+MUTATOR_HOOKABLE(GetResourceLimit, EV_GetResourceLimit);
+
+/** Called when the amount of resource of an entity changes. See RESOURCE_*
+constants for resource types. Return true to forbid the change. */
+#define EV_SetResourceAmount(i, o) \
+       /** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
+       /** resource type */  i(int, MUTATOR_ARGV_1_int) \
+       /**/                  o(int, MUTATOR_ARGV_1_int) \
+       /** amount */         i(float, MUTATOR_ARGV_2_float) \
+       /**/                  o(float, MUTATOR_ARGV_2_float) \
+       /**/
+MUTATOR_HOOKABLE(SetResourceAmount, EV_SetResourceAmount);
+
+/** Called after the amount of resource of an entity has changed. See RESOURCE_*
+constants for resource types. Amount wasted is the amount of resource that is
+above resource limit so it was not given. */
+#define EV_ResourceAmountChanged(i, o) \
+       /** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
+       /** resource type */  i(int, MUTATOR_ARGV_1_int) \
+       /** amount */         i(float, MUTATOR_ARGV_2_float) \
+       /**/
+MUTATOR_HOOKABLE(ResourceAmountChanged, EV_ResourceAmountChanged);
+
+/** Called when there was an attempt to set entity resources higher than their
+limit. See RESOURCE_* constants for resource types. Amount wasted is the amount
+of resource that is above resource limit so it was not given. */
+#define EV_ResourceWasted(i, o) \
+       /** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
+       /** resource type */  i(int, MUTATOR_ARGV_1_int) \
+       /** amount wasted */  i(float, MUTATOR_ARGV_2_float) \
+       /**/
+MUTATOR_HOOKABLE(ResourceWasted, EV_ResourceWasted);
+
+/** Called when entity is being given some resource. See RESOURCE_* constants
+for resource types. Return true to forbid giving. */
+#define EV_GiveResource(i, o) \
+       /** receiver */      i(entity, MUTATOR_ARGV_0_entity) \
+       /** resource type */ i(int, MUTATOR_ARGV_1_int) \
+       /**/                 o(int, MUTATOR_ARGV_1_int) \
+       /** amount */        i(float, MUTATOR_ARGV_2_float) \
+       /**/                 o(float, MUTATOR_ARGV_2_float) \
+       /**/
+MUTATOR_HOOKABLE(GiveResource, EV_GiveResource);
+
+/** Called when entity is being given some resource with specified limit. See
+RESOURCE_* constants for resource types. Return true to forbid giving. */
+#define EV_GiveResourceWithLimit(i, o) \
+       /** receiver */      i(entity, MUTATOR_ARGV_0_entity) \
+       /** resource type */ i(int, MUTATOR_ARGV_1_int) \
+       /**/                 o(int, MUTATOR_ARGV_1_int) \
+       /** amount */        i(float, MUTATOR_ARGV_2_float) \
+       /**/                 o(float, MUTATOR_ARGV_2_float) \
+       /** limit */         i(float, MUTATOR_ARGV_3_float) \
+       /**/                 o(float, MUTATOR_ARGV_3_float) \
+       /**/
+MUTATOR_HOOKABLE(GiveResourceWithLimit, EV_GiveResourceWithLimit);
+
+/** Called when some resource is being taken from an entity. See RESOURCE_* constants
+for resource types. Return true to forbid giving. */
+#define EV_TakeResource(i, o) \
+    /** receiver */      i(entity, MUTATOR_ARGV_0_entity) \
+    /** resource type */ i(int, MUTATOR_ARGV_1_int) \
+    /**/                 o(int, MUTATOR_ARGV_1_int) \
+    /** amount */        i(float, MUTATOR_ARGV_2_float) \
+    /**/                 o(float, MUTATOR_ARGV_2_float) \
+    /**/
+MUTATOR_HOOKABLE(TakeResource, EV_TakeResource);
+
+/** Called when some resource is being taken from an entity, with a limit. See
+RESOURCE_* constants for resource types. Return true to forbid giving. */
+#define EV_TakeResourceWithLimit(i, o) \
+    /** receiver */      i(entity, MUTATOR_ARGV_0_entity) \
+    /** resource type */ i(int, MUTATOR_ARGV_1_int) \
+    /**/                 o(int, MUTATOR_ARGV_1_int) \
+    /** amount */        i(float, MUTATOR_ARGV_2_float) \
+    /**/                 o(float, MUTATOR_ARGV_2_float) \
+    /** limit */         i(float, MUTATOR_ARGV_3_float) \
+    /**/                 o(float, MUTATOR_ARGV_3_float) \
+    /**/
+MUTATOR_HOOKABLE(TakeResourceWithLimit, EV_TakeResourceWithLimit);
+
 /** called at when a player connect */
 #define EV_ClientConnect(i, o) \
     /** player */ i(entity, MUTATOR_ARGV_0_entity) \
@@ -655,6 +810,7 @@ MUTATOR_HOOKABLE(GetModelParams, EV_GetModelParams);
     /** end pos */      i(vector, MUTATOR_ARGV_3_vector) \
     /** damage */       i(float, MUTATOR_ARGV_4_float) \
     /**/                o(float, MUTATOR_ARGV_4_float) \
+    /** wep entity */   i(entity, MUTATOR_ARGV_5_entity) \
     /**/
 MUTATOR_HOOKABLE(FireBullet_Hit, EV_FireBullet_Hit);
 
@@ -721,6 +877,12 @@ MUTATOR_HOOKABLE(Race_FinalCheckpoint, EV_Race_FinalCheckpoint);
     /**/
 MUTATOR_HOOKABLE(ClientKill, EV_ClientKill);
 
+/** called when player is about to be killed during kill command or changing teams */
+#define EV_ClientKill_Now(i, o) \
+    /** player */        i(entity, MUTATOR_ARGV_0_entity) \
+    /**/
+MUTATOR_HOOKABLE(ClientKill_Now, EV_ClientKill_Now);
+
 #define EV_FixClientCvars(i, o) \
     /** player */        i(entity, MUTATOR_ARGV_0_entity) \
     /**/
@@ -794,13 +956,20 @@ MUTATOR_HOOKABLE(CheckRules_World, EV_CheckRules_World);
 MUTATOR_HOOKABLE(WantWeapon, EV_WantWeapon);
 
 #define EV_AddPlayerScore(i, o) \
-    /** score field */  i(PlayerScoreField, MUTATOR_ARGV_0_entity) \
+    /** score field */  i(entity, MUTATOR_ARGV_0_entity) \
     /** score */        i(float, MUTATOR_ARGV_1_float) \
     /**/                o(float, MUTATOR_ARGV_1_float) \
     /** player */       i(entity, MUTATOR_ARGV_2_entity) \
     /**/
 MUTATOR_HOOKABLE(AddPlayerScore, EV_AddPlayerScore);
 
+#define EV_AddedPlayerScore(i, o) \
+    /** score field */  i(entity, MUTATOR_ARGV_0_entity) \
+    /** score */        i(float, MUTATOR_ARGV_1_float) \
+    /** player */       i(entity, MUTATOR_ARGV_2_entity) \
+    /**/
+MUTATOR_HOOKABLE(AddedPlayerScore, EV_AddPlayerScore);
+
 #define EV_GetPlayerStatus(i, o) \
     /** player */    i(entity, MUTATOR_ARGV_0_entity) \
     /**/
@@ -868,7 +1037,9 @@ MUTATOR_HOOKABLE(PrepareExplosionByDamage, EV_PrepareExplosionByDamage);
     /**/
 MUTATOR_HOOKABLE(MonsterModel, EV_MonsterModel);
 
-/**/
+/**
+ * Called before player changes their team. Return true to block team change.
+ */
 #define EV_Player_ChangeTeam(i, o) \
     /** player */         i(entity, MUTATOR_ARGV_0_entity) \
        /** current team */   i(float, MUTATOR_ARGV_1_float) \
@@ -876,6 +1047,24 @@ MUTATOR_HOOKABLE(MonsterModel, EV_MonsterModel);
     /**/
 MUTATOR_HOOKABLE(Player_ChangeTeam, EV_Player_ChangeTeam);
 
+/**
+ * Called after player has changed their team.
+ */
+#define EV_Player_ChangedTeam(i, o) \
+    /** player */         i(entity, MUTATOR_ARGV_0_entity) \
+       /** old team */       i(float, MUTATOR_ARGV_1_float) \
+       /** current team */   i(float, MUTATOR_ARGV_2_float) \
+    /**/
+MUTATOR_HOOKABLE(Player_ChangedTeam, EV_Player_ChangedTeam);
+
+/**
+ * Called when player is about to be killed when changing teams. Return true to block killing.
+ */
+#define EV_Player_ChangeTeamKill(i, o) \
+    /** player */    i(entity, MUTATOR_ARGV_0_entity) \
+    /**/
+MUTATOR_HOOKABLE(Player_ChangeTeamKill, EV_Player_ChangeTeamKill);
+
 /**/
 #define EV_URI_GetCallback(i, o) \
        /** id */       i(float, MUTATOR_ARGV_0_float) \
@@ -917,3 +1106,89 @@ MUTATOR_HOOKABLE(ChatMessageTo, EV_ChatMessageTo);
 
 /** return true to just restart the match, for modes that don't support readyrestart */
 MUTATOR_HOOKABLE(ReadyRestart_Deny, EV_NO_ARGS);
+
+/** called when a fusion reactor is validating its target */
+#define EV_FusionReactor_ValidTarget(i, o) \
+    /** turret */    i(entity, MUTATOR_ARGV_0_entity) \
+    /** target */    i(entity, MUTATOR_ARGV_1_entity) \
+    /**/
+MUTATOR_HOOKABLE(FusionReactor_ValidTarget, EV_FusionReactor_ValidTarget);
+
+enum {
+    MUT_FUSREAC_TARG_CONTINUE, // return this flag to make the function continue as normal
+    MUT_FUSREAC_TARG_VALID, // return this flag to make the function return true (valid target)
+    MUT_FUSREAC_TARG_INVALID // return this flag to make the function return false (invalid target)
+};
+
+/** return true to hide the 'teamnumbers are imbalanced' message */
+#define EV_HideTeamNagger(i, o) \
+    /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+    /**/
+MUTATOR_HOOKABLE(HideTeamNagger, EV_HideTeamNagger);
+
+/** return true to show a waypoint while the item is spawning */
+#define EV_Item_ScheduleRespawn(i, o) \
+    /** item */             i(entity, MUTATOR_ARGV_0_entity) \
+    /** respawn time */     i(float, MUTATOR_ARGV_1_float) \
+    /**/
+MUTATOR_HOOKABLE(Item_ScheduleRespawn, EV_Item_ScheduleRespawn);
+
+/** called before physics stats are set on a player, allows limited early customization */
+#define EV_PlayerPhysics_UpdateStats(i, o) \
+    /** player */             i(entity, MUTATOR_ARGV_0_entity) \
+    /**/
+MUTATOR_HOOKABLE(PlayerPhysics_UpdateStats, EV_PlayerPhysics_UpdateStats);
+
+/** called after physics stats are set on a player, allows post-initialization modifications */
+#define EV_PlayerPhysics_PostUpdateStats(i, o) \
+    /** player */             i(entity, MUTATOR_ARGV_0_entity) \
+    /** maxspeed_mod */       i(float, MUTATOR_ARGV_1_float) \
+    /**/
+MUTATOR_HOOKABLE(PlayerPhysics_PostUpdateStats, EV_PlayerPhysics_PostUpdateStats);
+
+/** return true to use your own aim target (or none at all) */
+#define EV_HavocBot_Aim(i, o) \
+    /** bot */ i(entity, MUTATOR_ARGV_0_entity) \
+    /**/
+MUTATOR_HOOKABLE(HavocBot_Aim, EV_HavocBot_Aim);
+
+/** return true to skip respawn time calculations */
+#define EV_CalculateRespawnTime(i, o) \
+    /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+    /**/
+MUTATOR_HOOKABLE(CalculateRespawnTime, EV_CalculateRespawnTime);
+
+/** called when parsing a vote command. */
+#define EV_VoteCommand_Parse(i, o) \
+    /** caller */                           i(entity, MUTATOR_ARGV_0_entity) \
+    /** first command */                    i(string, MUTATOR_ARGV_1_string) \
+    /** vote command */                     i(string, MUTATOR_ARGV_2_string) \
+    /** start position of vote command */   i(float, MUTATOR_ARGV_3_float) \
+    /** argument count */                   i(float, MUTATOR_ARGV_4_float) \
+    /**/
+MUTATOR_HOOKABLE(VoteCommand_Parse, EV_VoteCommand_Parse);
+
+enum {
+    MUT_VOTEPARSE_CONTINUE, // return this flag to make the function continue as normal
+    MUT_VOTEPARSE_SUCCESS, // return 1 (vote parsed)
+    MUT_VOTEPARSE_INVALID, // return -1 (vote parsed but counted as invalid, no action or vote)
+    MUT_VOTEPARSE_UNACCEPTABLE // return 0 (vote parameter counted as unacceptable, warns caller)
+};
+
+/**
+ * Called when freezing an entity (monster or player), return true to force showing a waypoint
+ */
+#define EV_Freeze(i, o) \
+    /** targ */             i(entity, MUTATOR_ARGV_0_entity) \
+    /** revive speed */     i(float, MUTATOR_ARGV_1_float) \
+    /** frozen type */      i(int, MUTATOR_ARGV_2_int) \
+    /**/
+MUTATOR_HOOKABLE(Freeze, EV_Freeze);
+
+/**
+ * Called when an entity (monster or player) is defrosted
+ */
+#define EV_Unfreeze(i, o) \
+    /** targ */             i(entity, MUTATOR_ARGV_0_entity) \
+    /**/
+MUTATOR_HOOKABLE(Unfreeze, EV_Unfreeze);