float 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_Add(entity cb, float() func, float order);
float CallbackChain_Remove(entity cb, float() func);
// a callback function is like this:
// float mycallback(entity me)
#define MUTATOR_REMOVING 0
#define MUTATOR_ADDING 1
+#define MUTATOR_ROLLING_BACK 2
typedef float(float) mutatorfunc_t;
float Mutator_Add(mutatorfunc_t func, string name);
void Mutator_Remove(mutatorfunc_t func, string name); // calls error() on fail
#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) { if(HOOK_##cb) CallbackChain_Remove(HOOK_##cb,HOOKFUNCTION_##func); } } while(0)
+#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)
// return error to request removal
// INPUT: self - turret
+MUTATOR_HOOKABLE(TurretDies);
+ // called when a turret dies
+
+MUTATOR_HOOKABLE(TurretValidateTarget);
+ // return target score
+ // INPUT:
+ entity turret_target;
+ entity turret;
+ float turret_flags;
+
MUTATOR_HOOKABLE(OnEntityPreSpawn);
// return error to prevent entity spawn, or modify the entity
// 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:
+ string monster_dropitem;
+ string monster_dropsize;
+
+MUTATOR_HOOKABLE(MonsterMove);
+ // called when a monster moves
+ // 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(PlayerDamage_SplitHealthArmor);
// called when a player gets damaged to e.g. remove stuff he was carrying.
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
// INPUT
entity self; // the player who pressed impulse 33
+MUTATOR_HOOKABLE(VehicleSpawn);
+ // called when a vehicle spawns
+
MUTATOR_HOOKABLE(VehicleEnter);
// called when a player enters a vehicle
// allows mutators to set special settings in this event
MUTATOR_HOOKABLE(ClientConnect);
// called at when a player connect
entity self; // player
+
+MUTATOR_HOOKABLE(HavocBot_ChooseRule);
+ entity self;