X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fmutators%2Fbase.qh;h=d4a9526191c3bd35852d731b398210b25b936e18;hb=1c150959db3e5e576600b080b5880ccd66598b78;hp=6fa77a858a21a2bceb2169d603c5b1a577111797;hpb=5607e279fe7b0dc9f92e15556ed6dc33f17f549c;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/mutators/base.qh b/qcsrc/common/mutators/base.qh index 6fa77a858..d4a952619 100644 --- a/qcsrc/common/mutators/base.qh +++ b/qcsrc/common/mutators/base.qh @@ -119,7 +119,6 @@ ENDCLASS(CallbackChain) void RegisterHooks() {}; void RegisterCallbacks() {}; -void RegisterMutators() {}; #define _MUTATOR_HOOKABLE(id, ...) CallbackChain HOOK_##id; bool __Mutator_Send_##id(__VA_ARGS__) #define MUTATOR_HOOKABLE(id, params) \ @@ -145,23 +144,68 @@ typedef bool(int) mutatorfunc_t; CLASS(Mutator, Object) ATTRIB(Mutator, m_id, int, 0) - ATTRIB(Mutator, mutatorname, string, string_null) + ATTRIB(Mutator, m_name, string, string_null) ATTRIB(Mutator, mutatorfunc, mutatorfunc_t, func_null) ATTRIB(Mutator, mutatorcheck, bool(), func_null) CONSTRUCTOR(Mutator, string _name, mutatorfunc_t func) { CONSTRUCT(Mutator); - this.mutatorname = _name; + this.m_name = _name; this.mutatorfunc = func; } ENDCLASS(Mutator) -const int MAX_MUTATORS = 20; -Mutator loaded_mutators[MAX_MUTATORS]; +REGISTRY(Mutators, BITS(7)) +#define Mutators_from(i) _Mutators_from(i, NULL) +Mutator loaded_mutators[Mutators_MAX]; +bool Mutator_Add(Mutator mut); +void Mutator_Remove(Mutator mut); +bool mutator_log = false; + +#ifndef MENUQC +REGISTER_NET_LINKED(Mutator) + +#ifdef SVQC +bool Mutator_SendEntity(entity this, entity to, int sf) +{ + int chan = MSG_ENTITY; + WriteHeader(chan, Mutator); + WriteString(chan, this.registered_id); + return true; +} +#endif + +#ifdef CSQC +void NET_Mutator_Remove() +{ + SELFPARAM(); + string s = this.netname; + WITH(bool, mutator_log, true, LAMBDA( + FOREACH(Mutators, it.registered_id == s, LAMBDA(Mutator_Remove(it))); + )); +} +NET_HANDLE(Mutator, bool isNew) +{ + string s = this.netname = ReadString(); + return = true; + if (isNew) + { + make_pure(this); + this.entremove = NET_Mutator_Remove; + int added = 0; + WITH(bool, mutator_log, true, LAMBDA( + FOREACH(Mutators, it.registered_id == s, LAMBDA(Mutator_Add(it); ++added)); + )); + if (added > 1) LOG_WARNINGF("Added more than one mutator for %s\n", s); + } +} +#endif + +#endif bool Mutator_Add(Mutator mut) { int j = -1; - for (int i = 0; i < MAX_MUTATORS; ++i) { + for (int i = 0; i < Mutators_MAX; ++i) { if (loaded_mutators[i] == mut) return true; // already added if (!(loaded_mutators[i])) @@ -175,6 +219,10 @@ bool Mutator_Add(Mutator mut) mutatorfunc_t func = mut.mutatorfunc; if (!func(MUTATOR_ADDING)) { // good + if (mutator_log) LOG_TRACEF("Mutator: added %s\n", mut.m_name); +#ifdef SVQC + Net_LinkEntity(mut, false, 0, Mutator_SendEntity); +#endif return true; } backtrace("WARNING: when adding mutator: adding failed, rolling back\n"); @@ -188,10 +236,10 @@ bool Mutator_Add(Mutator mut) void Mutator_Remove(Mutator mut) { int i; - for (i = 0; i < MAX_MUTATORS; ++i) + for (i = 0; i < Mutators_MAX; ++i) if (loaded_mutators[i] == mut) break; - if (i >= MAX_MUTATORS) { + if (i >= Mutators_MAX) { backtrace("WARNING: removing not-added mutator\n"); return; } @@ -201,18 +249,12 @@ void Mutator_Remove(Mutator mut) // baaaaad error("Mutator_Remove: removing mutator failed"); } + if (mutator_log) LOG_TRACEF("Mutator: removed %s\n", mut.m_name); +#ifdef SVQC + Net_UnlinkEntity(mut); +#endif } -#define MUTATOR_DECLARATION(name) \ - Mutator MUTATOR_##name -#define MUTATOR_DEFINITION(name) \ - bool MUTATORFUNCTION_##name(int mode); \ - [[accumulate]] void RegisterMutators() { MUTATOR_##name = NEW(Mutator, #name, MUTATORFUNCTION_##name); } \ - [[last]] bool MUTATORFUNCTION_##name(int mode) - -const int MUTATORS_MAX = MAX_MUTATORS; -noref entity MUTATORS[MUTATORS_MAX], MUTATORS_first, MUTATORS_last; -noref int MUTATORS_COUNT; #define REGISTER_MUTATOR(id, dependence) \ bool MUTATORFUNCTION_##id##_hooks(int mode) { return = false; } \ bool MUTATORFUNCTION_##id(int mode) { \ @@ -220,7 +262,7 @@ noref int MUTATORS_COUNT; bool ret = MUTATORFUNCTION_##id##_hooks(mode); if (ret) return ret; \ } \ bool MUTATOR_##id##_check() { return dependence; } \ - REGISTER(RegisterMutators, MUTATOR, MUTATORS, MUTATORS_COUNT, id, m_id, NEW(Mutator, #id, MUTATORFUNCTION_##id)) \ + REGISTER(Mutators, MUTATOR, id, m_id, NEW(Mutator, #id, MUTATORFUNCTION_##id)) \ { this.mutatorcheck = MUTATOR_##id##_check; } \ [[accumulate]] bool MUTATORFUNCTION_##id(int mode) @@ -231,7 +273,7 @@ STATIC_INIT(Mutators) { } STATIC_INIT_LATE(Mutators) { - FOREACH(MUTATORS, it.mutatorcheck(), LAMBDA(Mutator_Add(it))); + FOREACH(Mutators, it.mutatorcheck(), LAMBDA(Mutator_Add(it))); } #define MUTATOR_ONADD if (mode == MUTATOR_ADDING) @@ -247,11 +289,8 @@ STATIC_INIT_LATE(Mutators) { [[accumulate]] void RegisterCallbacks() { CALLBACK_##name = NEW(Callback, func); } #define MUTATOR_HOOKFUNCTION(...) \ - EVAL(OVERLOAD(MUTATOR_HOOKFUNCTION, __VA_ARGS__)) - -#define MUTATOR_HOOKFUNCTION_1(name) \ - _MUTATOR_CALLBACK(name, HOOKFUNCTION_##name) \ - bool HOOKFUNCTION_##name() + EVAL_MUTATOR_HOOKFUNCTION(OVERLOAD(MUTATOR_HOOKFUNCTION, __VA_ARGS__)) +#define EVAL_MUTATOR_HOOKFUNCTION(...) __VA_ARGS__ #define MUTATOR_HOOKFUNCTION_2(mut, cb) \ MUTATOR_HOOKFUNCTION_3(mut, cb, CBC_ORDER_ANY) @@ -262,17 +301,17 @@ STATIC_INIT_LATE(Mutators) { bool mut##_##cb() { return = false; } \ [[accumulate]] bool mut##_##cb() -#define MUTATOR_HOOK(cb, func, order) do { \ +#define MUTATOR_HOOK(cb, func, order) MACRO_BEGIN { \ MUTATOR_ONADD { \ if (!CallbackChain_Add(HOOK_##cb, CALLBACK_##func, order)) { \ - LOG_INFO("HOOK FAILED: ", #cb, ":", #func, "\n"); \ + LOG_INFO("HOOK FAILED: ", #cb, ":", #func, "\n"); \ return true; \ } \ } \ MUTATOR_ONROLLBACK_OR_REMOVE { \ CallbackChain_Remove(HOOK_##cb, CALLBACK_##func); \ } \ -} while (0) +} MACRO_END #include "events.qh"