44 this.cbc_order = order;
74 node.cbc_next = this.cbc_next;
101 prev.cbc_next = node;
103 this.cbc_next = node;
110 int n = 0, order = 0;
120 this.cbc_next =
next;
132 for (
Callback it = this.cbc_next; it; it = it.cbc_next)
135 r |= it.cbc.cbc_func();
143#define MUTATOR_TYPE_ARRAY(type, limit) noref type MUTATOR_ARGV_##type[limit]
150#undef MUTATOR_TYPE_ARRAY
153#define M_ARGV(idx, type) MUTATOR_ARGV_##type[idx]
155#define _MUTATOR_HANDLE_NOP(type, idx)
156#define _MUTATOR_HANDLE_PARAMS(type, idx) , type in_MUTATOR_ARGV_##type##_##idx
157#define _MUTATOR_HANDLE_PREPARE(type, idx) MUTATOR_ARGV_##type[idx] = in_MUTATOR_ARGV_##type##_##idx;
158#define _MUTATOR_HANDLE_PUSHTMP(type, idx) type tmp_MUTATOR_ARGV_##type##_##idx = MUTATOR_ARGV_##type[idx];
159#define _MUTATOR_HANDLE_PUSHOUT(type, idx) type out_MUTATOR_ARGV_##type##_##idx = MUTATOR_ARGV_##type[idx];
160#define _MUTATOR_HANDLE_POPTMP(type, idx) MUTATOR_ARGV_##type[idx] = tmp_MUTATOR_ARGV_##type##_##idx;
161#define _MUTATOR_HANDLE_POPOUT(type, idx) MUTATOR_ARGV_##type[idx] = out_MUTATOR_ARGV_##type##_##idx;
163#define EV_NO_ARGS(i, o)
168#define MUTATOR_HOOKABLE(name, params) _MUTATOR_HOOKABLE(name, params)
169#define _MUTATOR_HOOKABLE(name, params) \
170 CallbackChain HOOK_##name; \
171 bool __Mutator_Send_##name(int params(_MUTATOR_HANDLE_PARAMS, _MUTATOR_HANDLE_NOP)) \
173 params(_MUTATOR_HANDLE_PUSHTMP, _MUTATOR_HANDLE_NOP) \
174 params(_MUTATOR_HANDLE_PREPARE, _MUTATOR_HANDLE_NOP) \
175 bool ret = CallbackChain_Call(HOOK_##name); \
176 params(_MUTATOR_HANDLE_NOP, _MUTATOR_HANDLE_PUSHOUT) \
177 params(_MUTATOR_HANDLE_POPTMP, _MUTATOR_HANDLE_NOP) \
178 params(_MUTATOR_HANDLE_NOP, _MUTATOR_HANDLE_POPOUT) \
181 ACCUMULATE void RegisterHooks() \
183 HOOK_##name = NEW(CallbackChain, #name); \
186#define MUTATOR_CALLHOOK(name, ...) _MUTATOR_CALLHOOK(name, __VA_ARGS__)
188 #define _MUTATOR_CALLHOOK(name, ...) APPLY(__Mutator_Send_##name, 0 P99_IF_EMPTY(__VA_ARGS__)()(, __VA_ARGS__))
190 #define _MUTATOR_CALLHOOK(name, ...) APPLY(__Mutator_Send_##name, 0, ##__VA_ARGS__)
236#define _MUTATOR_IS_ENABLED(this) this.mutatorcheck()
237#define MUTATOR_IS_ENABLED(this) _MUTATOR_IS_ENABLED(MUTATOR_##this)
272 LOG_WARNF(
"Added more than one mutator for %s", s);
296 backtrace(
"WARNING: when adding mutator: adding failed, rolling back\n");
299 error(
"WARNING: when adding mutator: rolling back failed");
308 backtrace(
"WARNING: removing not-added mutator\n");
316 error(
"Mutator_Remove: removing mutator failed");
319 LOG_TRACEF(
"Mutator: removed %s", mut.m_name);
325#define _REGISTER_MUTATOR(id, dependence, cname) \
326 bool MUTATORFUNC_##id##_hooks(int mode) \
330 bool MUTATORFUNC_##id(int mode) \
333 bool ret = MUTATORFUNC_##id##_hooks(mode); \
337 bool MUTATOR_##id##_check() \
341 REGISTER(Mutators, MUTATOR, id, m_id, NEW(cname)) \
344 this.mutatorfunc = MUTATORFUNC_##id; \
345 this.mutatorcheck = MUTATOR_##id##_check; \
347 ACCUMULATE bool MUTATORFUNC_##id(int mode)
349#define REGISTER_MUTATOR(...) EVAL(OVERLOAD(REGISTER_MUTATOR, __VA_ARGS__))
350#define REGISTER_MUTATOR_2(id, dependence) _REGISTER_MUTATOR(id, dependence, Mutator)
351#define REGISTER_MUTATOR_3(id, dependence, cname) _REGISTER_MUTATOR(id, dependence, cname)
365#define MUTATOR_ONADD if (mode == MUTATOR_ADDING)
366#define MUTATOR_ONREMOVE if (mode == MUTATOR_REMOVING)
367#define MUTATOR_ONROLLBACK_OR_REMOVE if (mode == MUTATOR_REMOVING || mode == MUTATOR_ROLLING_BACK)
369#define MUTATOR_STATIC() MACRO_BEGIN \
373 error("This is a gametype and it cannot be added at runtime."); \
377 LOG_INFO("This is a gametype and it cannot be removed at runtime."); \
382#define MUTATOR_ADD(name) Mutator_Add(MUTATOR_##name)
383#define MUTATOR_REMOVE(name) Mutator_Remove(MUTATOR_##name)
384#define MUTATOR_RETURNVALUE CallbackChain_ReturnValue
386#define _MUTATOR_CALLBACK(name, func) \
387 Callback CB_##name; \
389 ACCUMULATE void RegisterCallbacks() \
391 CB_##name = NEW(Callback, func); \
394#define MUTATOR_HOOKFUNCTION(...) \
395 EVAL_MUTATOR_HOOKFUNCTION(OVERLOAD(MUTATOR_HOOKFUNCTION, __VA_ARGS__))
396#define EVAL_MUTATOR_HOOKFUNCTION(...) __VA_ARGS__
398#define MUTATOR_HOOKFUNCTION_2(mut, cb) \
399 MUTATOR_HOOKFUNCTION_3(mut, cb, CBC_ORDER_ANY)
401#define MUTATOR_HOOKFUNCTION_3(mut, cb, order) \
402 _MUTATOR_CALLBACK(mut##_##cb, mut##_##cb) \
403 ACCUMULATE bool MUTATORFUNC_##mut##_hooks(int mode) \
405 MUTATOR_HOOK(cb, mut##_##cb, order); \
411 ACCUMULATE bool mut##_##cb()
416 LOG_INFO(
"HOOK FAILED: ", cb,
":", func);
419#define MUTATOR_HOOK(cb, func, order) MACRO_BEGIN \
422 if (!CallbackChain_Add(HOOK_##cb, CB_##func, order)) \
424 _mutPrintFail(#cb, #func); \
428 MUTATOR_ONROLLBACK_OR_REMOVE \
430 CallbackChain_Remove(HOOK_##cb, CB_##func); \
#define MUTATOR_TYPE_ARRAY(type, limit)
void Mutator_Remove(Mutator mut)
const int CBC_ORDER_FIRST
bool Mutator_SendEntity(entity this, entity to, int sf)
#define _MUTATOR_IS_ENABLED(this)
const int CBC_ORDER_EXCLUSIVE
void _mutPrintFail(string cb, string func)
void NET_Mutator_Remove(entity this)
bool CallbackChain_ReturnValue
read-only field of the current return value
bool Mutator_Add(Mutator mut)
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
CallbackNode::CallbackNode(Callback it, int order)
ATTRIB(CallbackNode, cbc, Callback)
bool CallbackChain_Call(CallbackChain this)
bool CallbackChain_Add(CallbackChain this, Callback cb, int order)
int CallbackChain_Remove(CallbackChain this, Callback cb)
ATTRIB(CallbackChain, cbc_next, CallbackNode)
CallbackChain(string _name)
ATTRIB(Callback, cbc_func, bool())
a callback function is like this: bool mycallback() { do something return false; }
ATTRIB(Mutator, message, string)
string icon_path_from_menuskin(string theIcon)
Returns icon path from the current menu skin (MENU only).
WriteString(chan, ent.netname)
#define FOREACH(list, cond, body)
#define NET_HANDLE(id, param)
void Net_UnlinkEntity(entity e)
#define WriteHeader(to, id)
#define REGISTER_NET_LINKED(id)
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
#define WITH(type, name, value, block)
#define make_pure(e)
direct use is
#define METHOD(cname, name, prototype)
#define CONSTRUCTOR(cname,...)
#define CONSTRUCT(cname,...)
string registered_id
Registered item identifier.
#define REGISTRY(id, max)
Declares a new registry.
#define REGISTRY_DEFINE_GET(id, null)
#define STATIC_INIT_LATE(func)
directly after STATIC_INIT
#define STATIC_INIT(func)
during worldspawn