From 05a4d3a3cc3437585dbbeecbb0f3e897853fb519 Mon Sep 17 00:00:00 2001 From: TimePath Date: Fri, 15 May 2015 13:28:11 +1000 Subject: [PATCH] Cleanup mutators --- qcsrc/server/mutators/base.qc | 121 ++++++++++++++-------------------- qcsrc/server/mutators/base.qh | 81 ++++++++++++++--------- 2 files changed, 97 insertions(+), 105 deletions(-) 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..f4d0292d2 100644 --- a/qcsrc/server/mutators/base.qh +++ b/qcsrc/server/mutators/base.qh @@ -1,39 +1,52 @@ #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_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(cb) entity HOOK_##cb #define MUTATOR_CALLHOOK(cb) CallbackChain_Call(HOOK_##cb) @@ -74,7 +87,7 @@ MUTATOR_HOOKABLE(PlayerDies); entity frag_inflictor; entity frag_attacker; entity frag_target; // same as self - float frag_deathtype; + int frag_deathtype; MUTATOR_HOOKABLE(PlayerJump); // called when a player presses the jump key @@ -231,7 +244,7 @@ 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 + int 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 @@ -254,7 +267,7 @@ MUTATOR_HOOKABLE(SV_ParseClientCommand); // NOTE: THESE HOOKS MUST NEVER EVER CALL tokenize() // INPUT string cmd_name; // command name - float cmd_argc; // also, argv() can be used + int cmd_argc; // also, argv() can be used string cmd_string; // whole command, use only if you really have to /* // example: @@ -364,9 +377,11 @@ 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 +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 +}; MUTATOR_HOOKABLE(ClientConnect); // called at when a player connect @@ -379,7 +394,9 @@ 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 +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 -- 2.39.2