]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/mutators/base.qh
tuba: fix #1621
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mutators / base.qh
index ce98cd508e90a9fe0314e70d1baaa09a0cecc8e8..6e06e5590943b0c5a7619b96d46a5fcfa8876181 100644 (file)
@@ -154,8 +154,53 @@ CLASS(Mutator, Object)
     }
 ENDCLASS(Mutator)
 
-REGISTRY(Mutators, BITS(6))
+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)
 {
@@ -174,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");
@@ -200,6 +249,10 @@ 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 REGISTER_MUTATOR(id, dependence) \
@@ -209,7 +262,7 @@ void Mutator_Remove(Mutator mut)
         bool ret = MUTATORFUNCTION_##id##_hooks(mode); if (ret) return ret; \
     } \
     bool MUTATOR_##id##_check() { return dependence; } \
-    REGISTER(RegisterMutators, MUTATOR, Mutators, 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)
 
@@ -247,7 +300,7 @@ 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");           \
@@ -257,7 +310,7 @@ STATIC_INIT_LATE(Mutators) {
     MUTATOR_ONROLLBACK_OR_REMOVE {                                      \
         CallbackChain_Remove(HOOK_##cb, CALLBACK_##func);               \
     }                                                                   \
-} while (0)
+} MACRO_END
 
 #include "events.qh"