+Weapon Weapons_fromstr(string s)
+{
+ FOREACH(Weapons, it != WEP_Null && it.netname == s, return it);
+ return NULL;
+}
+
+
+// legacy w_prop mappings
+#define X(fld, T) .T fld; .T wepvar_##fld = fld;
+X(switchdelay_drop, float)
+X(switchdelay_raise, float)
+X(weaponreplace, string)
+X(weaponstartoverride, float)
+X(weaponstart, float)
+X(weaponthrowable, float)
+X(reload_ammo, float)
+.float reloading_ammo = reload_ammo;
+X(reload_time, float)
+.float reloading_time = reload_time;
+#undef X
+
+
+
+#define W_PROPS(L, class, prefix) \
+ L(W_PROP_BEGIN, W_PROP, W_PROP_END, class, prefix) \
+ L(W_CONFIG_BEGIN, W_CONFIG, W_CONFIG_END, class, prefix) \
+ L(W_UPDATE_BEGIN, W_UPDATE, W_UPDATE_END, class, prefix) \
+ L(W_NET_BEGIN, W_NET, W_NET_END, class, prefix) \
+ /**/ \
+
+
+ #define W_PROP(class, wepname, fld, T, m) W_PROP_##m(class, fld, T, wepname)
+ #define W_PROP_NONE(class, fld, T, wepname) _W_PROP(class, fld, T, wepname)
+ #define W_PROP_PRI(class, fld, T, wepname) _W_PROP(class, primary_##fld, T, wepname)
+ #define W_PROP_SEC(class, fld, T, wepname) _W_PROP(class, secondary_##fld, T, wepname)
+ #define W_PROP_BOTH(class, fld, T, wepname) \
+ W_PROP_PRI(class, fld, T, wepname) \
+ W_PROP_SEC(class, fld, T, wepname)
+ #define W_PROP_BEGIN(class)
+ #define _W_PROP(class, fld, T, wepname) \
+ /* static */ T _W_PROP_CVAR(wepname, fld); \
+ ATTRIB(class, wepvar_##fld, T, _W_PROP_CVAR(wepname, fld));
+ #define _W_PROP_CVAR(wepname, fld) autocvar_g_balance_##wepname##_##fld
+ #define W_PROP_END()
+
+
+
+ #define W_CONFIG(class, wepname, fld, T, m) W_CONFIG_##m(class, fld, T, wepname)
+ #define W_CONFIG_NONE(class, fld, T, wepname) _W_CONFIG(class, fld, T, wepname)
+ #define W_CONFIG_PRI(class, fld, T, wepname) _W_CONFIG(class, primary_##fld, T, wepname)
+ #define W_CONFIG_SEC(class, fld, T, wepname) _W_CONFIG(class, secondary_##fld, T, wepname)
+ #define W_CONFIG_BOTH(class, fld, T, wepname) \
+ W_CONFIG_PRI(class, fld, T, wepname) \
+ W_CONFIG_SEC(class, fld, T, wepname)
+ #define W_CONFIG_BEGIN(class) METHOD(class, wr_config, void(class this)) {
+ #ifdef SVQC
+ #define _W_CONFIG(class, fld, T, wepname) if (#wepname == this.netname) WEP_CONFIG_WRITE_CVARS(wepname, fld, T);
+ #else
+ #define _W_CONFIG(class, fld, T, wepname)
+ #endif
+ #define W_CONFIG_END() }
+
+
+ #define W_UPDATE(class, wepname, fld, T, m) W_UPDATE_##m(class, fld, T, wepname)
+ #define W_UPDATE_NONE(class, fld, T, wepname) _W_UPDATE(class, fld, T, wepname)
+ #define W_UPDATE_PRI(class, fld, T, wepname) _W_UPDATE(class, primary_##fld, T, wepname)
+ #define W_UPDATE_SEC(class, fld, T, wepname) _W_UPDATE(class, secondary_##fld, T, wepname)
+ #define W_UPDATE_BOTH(class, fld, T, wepname) \
+ W_UPDATE_PRI(class, fld, T, wepname) \
+ W_UPDATE_SEC(class, fld, T, wepname)
+ .entity baseline, baseline_target;
+ #define W_UPDATE_BEGIN(class) \
+ METHOD(class, wr_update, void(class this)) \
+ { \
+ noref entity b = this.baseline; \
+ if (!b) \
+ { \
+ b = this.baseline = new_pure(baseline); \
+ b.baseline_target = this; \
+ }
+ #ifdef SVQC
+ #define _W_UPDATE(class, fld, T, wepname) \
+ { \
+ T it = _W_PROP_CVAR(wepname, fld); \
+ b.wepvar_##fld = this.wepvar_##fld; \
+ this.wepvar_##fld = it; \
+ }
+ #else
+ #define _W_UPDATE(class, fld, T, wepname)
+ #endif
+ #define W_UPDATE_END() }
+
+
+ #define W_NET(class, wepname, fld, T, m) W_NET_##m(class, fld, T, wepname)
+ #define W_NET_NONE(class, fld, T, wepname) _W_NET(class, fld, T, wepname)
+ #define W_NET_PRI(class, fld, T, wepname) _W_NET(class, primary_##fld, T, wepname)
+ #define W_NET_SEC(class, fld, T, wepname) _W_NET(class, secondary_##fld, T, wepname)
+ #define W_NET_BOTH(class, fld, T, wepname) \
+ W_NET_PRI(class, fld, T, wepname) \
+ W_NET_SEC(class, fld, T, wepname)
+ REGISTER_NET_TEMP(WeaponUpdate)
+ #if defined(CSQC)
+ #define W_NET_BEGIN(class) METHOD(class, wr_net, void(class this, int i)) { int n = 0;
+ #define _W_NET(class, fld, T, wepname) \
+ { \
+ if (++n == i) this.wepvar_##fld = Read_##T(); \
+ }
+ .void(Weapon this, int i) wr_net;
+ NET_HANDLE(WeaponUpdate, bool isnew)
+ {
+ Weapon w = Weapons_from(ReadByte());
+ for (int i; (i = ReadByte()); )
+ {
+ w.wr_net(w, i);
+ }
+ return true;
+ }
+ #define W_NET_END() }
+ #elif defined(SVQC)
+ #define W_NET_BEGIN(class) \
+ METHOD(class, wr_net, void(class this, int chan)) \
+ { \
+ bool commit = false; \
+ int i = 0;
+ #define _W_NET(class, fld, T, wepname) \
+ { \
+ ++i; \
+ T it = this.wepvar_##fld; \
+ if (chan == MSG_ONE || it != this.baseline.wepvar_##fld) \
+ { \
+ if (!commit) { commit = true; WriteHeader(chan, WeaponUpdate); WriteByte(chan, this.m_id); } \
+ WriteByte(chan, i); Write_##T(chan, it); \
+ } \
+ }
+ #define W_NET_END() \
+ if (commit) WriteByte(chan, 0); \
+ }
+ #else
+ #define W_NET_BEGIN(class)
+ #define _W_NET(class, fld, T, wepname)
+ #define W_NET_END()
+ #endif