entity nade_type = Nade_FromProjectile(proj.cnt);
if (nade_type == NADE_TYPE_Null) return;
- if(STAT(NADES_SMALL, NULL))
+ if(STAT(NADES_SMALL))
{
proj.mins = '-8 -8 -8';
proj.maxs = '8 8 8';
#define SET_ONSLICK(s) ((s).flags |= FL_ONSLICK)
#define UNSET_ONSLICK(s) ((s).flags &= ~FL_ONSLICK)
-#define GAMEPLAYFIX_DOWNTRACEONGROUND(s) STAT(GAMEPLAYFIX_DOWNTRACEONGROUND, NULL)
-#define GAMEPLAYFIX_EASIERWATERJUMP(s) STAT(GAMEPLAYFIX_EASIERWATERJUMP, NULL)
-#define GAMEPLAYFIX_STEPDOWN(s) STAT(GAMEPLAYFIX_STEPDOWN, NULL)
-#define GAMEPLAYFIX_STEPMULTIPLETIMES(s) STAT(GAMEPLAYFIX_STEPMULTIPLETIMES, NULL)
-#define GAMEPLAYFIX_UNSTICKPLAYERS(s) STAT(GAMEPLAYFIX_UNSTICKPLAYERS, NULL)
-#define GAMEPLAYFIX_WATERTRANSITION(s) STAT(GAMEPLAYFIX_WATERTRANSITION, NULL)
-#define UPWARD_VELOCITY_CLEARS_ONGROUND(s) STAT(GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND, NULL)
-
-#define PHYS_STEPHEIGHT(s) STAT(MOVEVARS_STEPHEIGHT, NULL)
-#define PHYS_NOSTEP(s) STAT(NOSTEP, NULL)
-#define PHYS_JUMPSTEP(s) STAT(MOVEVARS_JUMPSTEP, NULL)
-#define PHYS_WALLFRICTION(s) STAT(MOVEVARS_WALLFRICTION, NULL)
+#define GAMEPLAYFIX_DOWNTRACEONGROUND(s) STAT(GAMEPLAYFIX_DOWNTRACEONGROUND)
+#define GAMEPLAYFIX_EASIERWATERJUMP(s) STAT(GAMEPLAYFIX_EASIERWATERJUMP)
+#define GAMEPLAYFIX_STEPDOWN(s) STAT(GAMEPLAYFIX_STEPDOWN)
+#define GAMEPLAYFIX_STEPMULTIPLETIMES(s) STAT(GAMEPLAYFIX_STEPMULTIPLETIMES)
+#define GAMEPLAYFIX_UNSTICKPLAYERS(s) STAT(GAMEPLAYFIX_UNSTICKPLAYERS)
+#define GAMEPLAYFIX_WATERTRANSITION(s) STAT(GAMEPLAYFIX_WATERTRANSITION)
+#define UPWARD_VELOCITY_CLEARS_ONGROUND(s) STAT(GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND)
+
+#define PHYS_STEPHEIGHT(s) STAT(MOVEVARS_STEPHEIGHT)
+#define PHYS_NOSTEP(s) STAT(NOSTEP)
+#define PHYS_JUMPSTEP(s) STAT(MOVEVARS_JUMPSTEP)
+#define PHYS_WALLFRICTION(s) STAT(MOVEVARS_WALLFRICTION)
#ifdef CSQC
.float bouncestop;
#define PHYS_JETPACK_MAXSPEED_UP(s) STAT(JETPACK_MAXSPEED_UP, s)
#define PHYS_JETPACK_REVERSE_THRUST(s) STAT(JETPACK_REVERSE_THRUST, s)
-#define PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS(s) STAT(MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS, NULL)
+#define PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS(s) STAT(MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS)
#define PHYS_JUMPVELOCITY(s) STAT(MOVEVARS_JUMPVELOCITY, s)
#define PHYS_MAXAIRSPEED(s) STAT(MOVEVARS_MAXAIRSPEED, s)
#define PHYS_WARSOWBUNNY_TOPSPEED(s) STAT(MOVEVARS_WARSOWBUNNY_TOPSPEED, s)
#define PHYS_WARSOWBUNNY_TURNACCEL(s) STAT(MOVEVARS_WARSOWBUNNY_TURNACCEL, s)
-#define PHYS_SLICK_APPLYGRAVITY(s) STAT(SLICK_APPLYGRAVITY, NULL)
+#define PHYS_SLICK_APPLYGRAVITY(s) STAT(SLICK_APPLYGRAVITY)
#define PHYS_INPUT_BUTTON_ATCK(s) PHYS_INPUT_BUTTON_BUTTON1(s)
#define PHYS_INPUT_BUTTON_JUMP(s) PHYS_INPUT_BUTTON_BUTTON2(s)
#undef setcolor
#ifdef MENUQC
- #define NULL (0, null_entity)
+ #define NULL (RVALUE, null_entity)
#define world NULL
#else
- #define NULL (0, world)
+ #define NULL (RVALUE, world)
#endif
#define MACRO_END } while (0)
#endif
+/** Marker for use in (RVALUE, (expr)) */
+#define RVALUE 0
+
#define _CAT(a, b) a ## b
#define CAT(a, b) _CAT(a, b)
#include "p99.qh"
#define OVERLOAD(F, ...) P99_IF_EMPTY(__VA_ARGS__)(P99_PASTE2(F, _00)())(P99_PASTE3(F, _, P00_NARG(__VA_ARGS__))(__VA_ARGS__))
+ /** for use within a macro */
#define OVERLOAD_(F, ...) P99_IF_EMPTY(__VA_ARGS__)(P99_PASTE2(F, _00)())(P99_PASTE3(F, _, P00_NARG(__VA_ARGS__))(__VA_ARGS__))
#else
#define EVAL(...) __VA_ARGS__
#pragma once
+#include "macro.qh"
+
// Transition from global 'self' to local 'this'
// Step 1: auto oldself
// Step 2: const self
#if 1
- #define self (0, self)
+ #define self (RVALUE, self)
[[alias("self")]] entity __self;
#define setself(s) (__self = s)
- #define WITHSELF(value, block) WITH(entity, __self, value, (0, block))
+ #define WITHSELF(value, block) WITH(entity, __self, value, (RVALUE, block))
#endif
// Step 3: propagate SELFPARAM()
// Step 5: this should work
#if 1
#undef self
- #define self (0, this)
+ #define self (RVALUE, this)
#endif
// Step 6: remove SELFPARAM, add parameters
#define SELFWRAP_SET(T, e, f) \
(_selftemp = (e), _selftemp.__##T = ((f) ? T##_self : func_null), _selftemp.self##T = (f))
#define SELFWRAP_GET(T, e) \
- (0, (e).self##T)
+ (RVALUE, (e).self##T)
#define _SELFWRAP_SET(T, e, f) \
((e).__##T = (f))
#define _SELFWRAP_GET(T, e) \
- (0, (e).__##T)
+ (RVALUE, (e).__##T)
SELFWRAP(think, void, (), (entity this), (this))
#define setthink(e, f) SELFWRAP_SET(think, e, f)
void stats_get() {}
#define STAT(...) EVAL_STAT(OVERLOAD(STAT, __VA_ARGS__))
#define EVAL_STAT(...) __VA_ARGS__
- #define STAT_1(id) STAT_2(id, NULL)
- #define STAT_2(id, cl) (0, _STAT(id))
+ #define STAT_1(id) (RVALUE, _STAT(id))
+ #define STAT_2(id, cl) STAT_1(id)
#define getstat_int(id) getstati(id, 0, 24)
#define getstat_bool(id) boolean(getstati(id))
}
#define REGISTER_STAT_3(x, T, expr) REGISTER_STAT_2(x, T)
#elif defined(SVQC)
+ /** Internal use only */
+ entity STATS;
/** Add all registered stats, access with `STAT(ID, player)` or `.type stat = _STAT(ID); player.stat` */
void stats_add() {}
- #define STAT(id, cl) (cl)._STAT(id)
+ #define STAT(...) EVAL_STAT(OVERLOAD_(STAT, __VA_ARGS__))
+ #define EVAL_STAT(...) __VA_ARGS__
+ #define STAT_1(id) (RVALUE, STAT_2(id, STATS))
+ #define STAT_2(id, cl) (cl)._STAT(id)
#define addstat_int(id, fld) addstat(id, AS_INT, fld)
#define addstat_bool(id, fld) addstat(id, AS_INT, fld)
const int AS_FLOAT = 8;
.int __stat_null;
- /** Prevent engine stats being sent */
- STATIC_INIT(stats_clear)
+ STATIC_INIT(stats)
{
+ STATS = new(stats);
+ // Prevent engine stats being sent
int r = STATS_ENGINE_RESERVE;
for (int i = 0, n = 256 - r; i < n; ++i) {
#define X(_, name, id) if (i == id) continue;
addstat_##T(STAT_##id.m_id, fld); \
}
void GlobalStats_update(entity this) {}
+ /** TODO: do we want the global copy to update? */
#define REGISTER_STAT_3(id, T, expr) \
REGISTER_STAT_2(id, T); \
[[accumulate]] void GlobalStats_update(entity this) { STAT(id, this) = (expr); } \
- STATIC_INIT(worldstat_##id) { entity this = NULL; STAT(id, this) = (expr); }
+ STATIC_INIT(worldstat_##id) { entity this = STATS; STAT(id, this) = (expr); }
#else
#define REGISTER_STAT_2(id, type)
#define REGISTER_STAT_3(id, T, expr)
o.y += random() * (world.maxs.y - world.mins.y);
o.z += random() * (world.maxs.z - world.mins.z);
- tracebox(o, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), o - '0 0 32768', MOVE_WORLDONLY, NULL);
+ tracebox(o, STAT(PL_MIN), STAT(PL_MAX), o - '0 0 32768', MOVE_WORLDONLY, NULL);
if(trace_fraction == 1)
continue;