]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Objectify buffs
authorTimePath <andrew.hardaker1995@gmail.com>
Fri, 14 Aug 2015 00:30:33 +0000 (10:30 +1000)
committerTimePath <andrew.hardaker1995@gmail.com>
Fri, 14 Aug 2015 00:30:33 +0000 (10:30 +1000)
19 files changed:
qcsrc/client/hud.qc
qcsrc/client/main.qc
qcsrc/client/waypointsprites.qc
qcsrc/common/buffs.qc
qcsrc/common/buffs.qh
qcsrc/common/items/all.inc
qcsrc/common/items/all.qc
qcsrc/common/items/all.qh
qcsrc/common/items/inventory.qh
qcsrc/common/items/item/buff.qc [deleted file]
qcsrc/common/items/item/buff.qh [deleted file]
qcsrc/common/notifications.qh
qcsrc/common/physics.qc
qcsrc/common/physics.qh
qcsrc/common/registry.qh
qcsrc/common/util-pre.qh
qcsrc/server/g_world.qc
qcsrc/server/mutators/mutator_buffs.qc
qcsrc/server/mutators/mutator_instagib.qc

index 1626901db43ac8a6743464b184bea2031cd6ca3d..bd687c538f6763e8f79d3fdefba874c6f729bb3c 100644 (file)
@@ -1403,10 +1403,12 @@ void HUD_Powerups(void)
        if(superTime)
                addPowerupItem("Superweapons", "superweapons", autocvar_hud_progressbar_superweapons_color, superTime, 30);
 
-       entity item;
-       for(item = Buff_Type_first; item; item = item.enemy)
-               if(allBuffs & item.items)
-                       addPowerupItem(item.message, strcat("buff_", item.netname), item.colormod, bound(0, getstatf(STAT_BUFF_TIME) - time, 99), 60);
+       FOREACH(BUFFS, 0, BUFFS_COUNT,
+               it.m_itemid & allBuffs,
+               LAMBDA(
+                       addPowerupItem(it.m_prettyName, strcat("buff_", it.m_name), it.m_color, bound(0, getstatf(STAT_BUFF_TIME) - time, 99), 60);
+               )
+       );
 
        if(!powerupItemsCount)
                return;
@@ -1474,7 +1476,7 @@ void HUD_Powerups(void)
        int row = 0;
 
        draw_beginBoldFont();
-       for(item = powerupItems; item.count; item = item.chain)
+       for(entity item = powerupItems; item.count; item = item.chain)
        {
                itemPos = eX * (pos.x + column * itemSize.x) + eY * (pos.y + row * itemSize.y);
 
index a544e4fbd5ba3cd3e1ee3d3afc042602911047fe..276b5e32bd663e233068e2a067d1a57127768a93 100644 (file)
@@ -147,7 +147,6 @@ void CSQC_Init(void)
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
        CALL_ACCUMULATED_FUNCTION(RegisterHUD_Panels);
-       CALL_ACCUMULATED_FUNCTION(RegisterBuffs);
 
        WaypointSprite_Load();
 
index 9de48dff5261d72f482d7334f20fb53b461809df..de4e84d9e3c46a2bf1f04d0c04c0fd04a5df99f2 100644 (file)
@@ -204,7 +204,18 @@ vector spritelookupcolor(string s, vector def)
 string spritelookuptext(string s)
 {
        if(substring(s, 0, 4) == "wpn-") { return (get_weaponinfo(stof(substring(s, 4, strlen(s)))).message); }
-       if(substring(s, 0, 5) == "buff-") { return Buff_PrettyName(Buff_Type_FromSprite(s)); }
+       if (substring(s, 0, 5) == "buff-")
+       {
+               entity buff = BUFF_NULL;
+               FOREACH(BUFFS, 0, BUFFS_COUNT,
+                       it.m_sprite == s,
+                       LAMBDA({
+                               buff = it;
+                               break;
+                       })
+               );
+               return buff.m_prettyName;
+       }
 
        switch(s)
        {
index 9348e119a6842968f00257c98d49c4a30fa6b581..612255dbb59588aa0b4351f79c73222946f0c8d4 100644 (file)
@@ -1,82 +1,10 @@
 #if defined(CSQC)
        #include "../dpdefs/csprogsdefs.qh"
        #include "../client/defs.qh"
-       #include "buffs.qh"
 #elif defined(MENUQC)
 #elif defined(SVQC)
        #include "../dpdefs/progsdefs.qh"
     #include "../dpdefs/dpextensions.qh"
-    #include "buffs.qh"
 #endif
+#include "buffs.qh"
 
-vector Buff_Color(int buff_id)
-{
-       entity e;
-       for(e = Buff_Type_first; e; e = e.enemy)
-               if(buff_id == e.items)
-                       return e.colormod;
-       return '1 1 1';
-}
-
-string Buff_PrettyName(int buff_id)
-{
-       entity e;
-       for(e = Buff_Type_first; e; e = e.enemy)
-               if(buff_id == e.items)
-                       return e.message;
-       return "";
-}
-
-string Buff_Name(int buff_id)
-{
-       entity e;
-       for(e = Buff_Type_first; e; e = e.enemy)
-               if(buff_id == e.items)
-                       return e.netname;
-       return "";
-}
-
-int Buff_Type_FromName(string buff_name)
-{
-       entity e;
-       for(e = Buff_Type_first; e; e = e.enemy)
-               if(buff_name == e.netname)
-                       return e.items;
-       return 0;
-}
-
-int Buff_Type_FromSprite(string buff_sprite)
-{
-       entity e;
-       for(e = Buff_Type_first; e; e = e.enemy)
-               if(buff_sprite == e.model2)
-                       return e.items;
-       return 0;
-}
-
-int Buff_Skin(int buff_id)
-{
-       entity e;
-       for(e = Buff_Type_first; e; e = e.enemy)
-               if(buff_id == e.items)
-                       return e.skin;
-       return 0;
-}
-
-string Buff_Sprite(int buff_id)
-{
-       entity e;
-       for(e = Buff_Type_first; e; e = e.enemy)
-               if(buff_id == e.items)
-                       return e.model2;
-       return "";
-}
-
-float Buff_Timer(int buff_id)
-{
-       entity e;
-       for(e = Buff_Type_first; e; e = e.enemy)
-               if(buff_id == e.items)
-                       return e.buff_time;
-       return 0;
-}
index 0cd32e0b357b6ec2b0f98ebac3a403062f14a891..7396f974c2bc5eb1ebacdbfdc31bb7a9586d3479 100644 (file)
 #include "teams.qh"
 #include "util.qh"
 
-entity Buff_Type_first;
-entity Buff_Type_last;
-.entity enemy; // internal next pointer
-
-int BUFF_LAST = 1;
-int BUFF_ALL;
-
-.int items; // buff ID
-.string netname; // buff name
-.string message; // human readable name
-.vector colormod; // buff color
-.string model2; // buff sprite
-.int skin; // buff skin
-.float buff_time;
-
-// hacky function to return the cvar value only to server - TODO: do this properly!
-float sv_cvar(string cvarname)
-{
+#include "registry.qh"
+
+void RegisterBuffs();
+const int BUFFS_MAX = 16;
+entity BUFFS[BUFFS_MAX];
+int BUFFS_COUNT;
+#define REGISTER_BUFF(id) \
+    REGISTER(RegisterBuffs, BUFF, BUFFS, BUFFS_COUNT, id, Buff, m_id); \
+    REGISTER_INIT_POST(BUFF, id) { \
+        this.netname = this.m_name; \
+        this.m_itemid = BIT(this.m_id - 1); \
+        this.m_sprite = strzone(strcat("buff-", this.m_name)); \
+    } \
+    REGISTER_INIT(BUFF, id)
+REGISTER_REGISTRY(RegisterBuffs)
+
+#include "items/item/pickup.qh"
+CLASS(Buff, Pickup)
+       /** bit index */
+       ATTRIB(Buff, m_itemid, int, 0)
+       ATTRIB(Buff, m_name, string, "buff")
+       ATTRIB(Buff, m_color, vector, '1 1 1')
+       ATTRIB(Buff, m_prettyName, string, "Buff")
+       ATTRIB(Buff, m_skin, int, 0)
+       ATTRIB(Buff, m_sprite, string, "")
 #ifdef SVQC
-       return cvar(cvarname);
-#else
-       return 0;
+       METHOD(Buff, m_time, float(entity))
+       float Buff_m_time(entity this) { return cvar(strcat("g_buffs_", this.netname, "_time")); }
 #endif
+ENDCLASS(Buff)
+
+REGISTER_BUFF(NULL);
+
+REGISTER_BUFF(AMMO) {
+       this.m_prettyName = _("Ammo");
+       this.m_name = "ammo";
+       this.m_skin = 3;
+       this.m_color = '0.76 1 0.1';
+}
+
+REGISTER_BUFF(RESISTANCE) {
+       this.m_prettyName = _("Resistance");
+       this.m_name = "resistance";
+       this.m_skin = 0;
+       this.m_color = '0.36 1 0.07';
+}
+
+REGISTER_BUFF(SPEED) {
+       this.m_prettyName = _("Speed");
+       this.m_name = "speed";
+       this.m_skin = 9;
+       this.m_color = '0.1 1 0.84';
+}
+
+REGISTER_BUFF(MEDIC) {
+       this.m_prettyName = _("Medic");
+       this.m_name = "medic";
+       this.m_skin = 1;
+       this.m_color = '1 0.12 0';
+}
+
+REGISTER_BUFF(BASH) {
+       this.m_prettyName = _("Bash");
+       this.m_name = "bash";
+       this.m_skin = 5;
+       this.m_color = '1 0.39 0';
+}
+
+REGISTER_BUFF(VAMPIRE) {
+       this.m_prettyName = _("Vampire");
+       this.m_name = "vampire";
+       this.m_skin = 2;
+       this.m_color = '1 0 0.24';
+}
+
+REGISTER_BUFF(DISABILITY) {
+       this.m_prettyName = _("Disability");
+       this.m_name = "disability";
+       this.m_skin = 7;
+       this.m_color = '0.94 0.3 1';
+}
+
+REGISTER_BUFF(VENGEANCE) {
+       this.m_prettyName = _("Vengeance");
+       this.m_name = "vengeance";
+       this.m_skin = 15;
+       this.m_color = '1 0.23 0.61';
+}
+
+REGISTER_BUFF(JUMP) {
+       this.m_prettyName = _("Jump");
+       this.m_name = "jump";
+       this.m_skin = 10;
+       this.m_color = '0.24 0.78 1';
+}
+
+REGISTER_BUFF(FLIGHT) {
+       this.m_prettyName = _("Flight");
+       this.m_name = "flight";
+       this.m_skin = 11;
+       this.m_color = '0.33 0.56 1';
 }
 
-#define REGISTER_BUFF(hname,sname,NAME,bskin,bcolor) \
-       int BUFF_##NAME; \
-       entity Buff_Type##sname; \
-       void RegisterBuffs_##sname() \
-       { \
-               BUFF_##NAME = BUFF_LAST * 2; \
-               BUFF_LAST = BUFF_##NAME; \
-               BUFF_ALL |= BUFF_##NAME; \
-               Buff_Type##sname = spawn(); \
-               Buff_Type##sname.items = BUFF_##NAME; \
-               Buff_Type##sname.netname = #sname; \
-               Buff_Type##sname.message = hname; \
-               Buff_Type##sname.skin = bskin; \
-               Buff_Type##sname.colormod = bcolor; \
-               Buff_Type##sname.buff_time = sv_cvar(strcat("g_buffs_", #sname, "_time")); \
-               Buff_Type##sname.model2 = strzone(strcat("buff-", #sname)); \
-               if(!Buff_Type_first) \
-                       Buff_Type_first = Buff_Type##sname; \
-               if(Buff_Type_last) \
-                       Buff_Type_last.enemy = Buff_Type##sname; \
-               Buff_Type_last = Buff_Type##sname; \
-       } \
-       ACCUMULATE_FUNCTION(RegisterBuffs, RegisterBuffs_##sname)
-
-REGISTER_BUFF(_("Ammo"),ammo,AMMO,3,'0.76 1 0.1');
-REGISTER_BUFF(_("Resistance"),resistance,RESISTANCE,0,'0.36 1 0.07');
-REGISTER_BUFF(_("Speed"),speed,SPEED,9,'0.1 1 0.84');
-REGISTER_BUFF(_("Medic"),medic,MEDIC,1,'1 0.12 0');
-REGISTER_BUFF(_("Bash"),bash,BASH,5,'1 0.39 0');
-REGISTER_BUFF(_("Vampire"),vampire,VAMPIRE,2,'1 0 0.24');
-REGISTER_BUFF(_("Disability"),disability,DISABILITY,7,'0.94 0.3 1');
-REGISTER_BUFF(_("Vengeance"),vengeance,VENGEANCE,15,'1 0.23 0.61');
-REGISTER_BUFF(_("Jump"),jump,JUMP,10,'0.24 0.78 1');
-REGISTER_BUFF(_("Flight"),flight,FLIGHT,11,'0.33 0.56 1');
-REGISTER_BUFF(_("Invisible"),invisible,INVISIBLE,12,'0.5 0.5 1');
-REGISTER_BUFF(_("Inferno"),inferno,INFERNO,16,'1 0.62 0');
-REGISTER_BUFF(_("Swapper"),swapper,SWAPPER,17,'0.63 0.36 1');
-REGISTER_BUFF(_("Magnet"),magnet,MAGNET,18,'1 0.95 0.18');
-#undef REGISTER_BUFF
+REGISTER_BUFF(INVISIBLE) {
+       this.m_prettyName = _("Invisible");
+       this.m_name = "invisible";
+       this.m_skin = 12;
+       this.m_color = '0.5 0.5 1';
+}
+
+REGISTER_BUFF(INFERNO) {
+       this.m_prettyName = _("Inferno");
+       this.m_name = "inferno";
+       this.m_skin = 16;
+       this.m_color = '1 0.62 0';
+}
+
+REGISTER_BUFF(SWAPPER) {
+       this.m_prettyName = _("Swapper");
+       this.m_name = "swapper";
+       this.m_skin = 17;
+       this.m_color = '0.63 0.36 1';
+}
+
+REGISTER_BUFF(MAGNET) {
+       this.m_prettyName = _("Magnet");
+       this.m_name = "magnet";
+       this.m_skin = 18;
+       this.m_color = '1 0.95 0.18';
+}
 
 #ifdef SVQC
 .int buffs;
 void buff_Init(entity ent);
-void buff_Init_Compat(entity ent, int replacement);
+void buff_Init_Compat(entity ent, entity replacement);
 
-#define BUFF_SPAWNFUNC(e,b,t) void spawnfunc_item_buff_##e() { self.buffs = b; self.team = t; buff_Init(self); }
-#define BUFF_SPAWNFUNC_Q3TA_COMPAT(o,r) void spawnfunc_item_##o() { buff_Init_Compat(self,r); }
-#define BUFF_SPAWNFUNCS(e,b)                         \
-        BUFF_SPAWNFUNC(e,           b,  0)           \
-        BUFF_SPAWNFUNC(e##_team1,   b,  NUM_TEAM_1) \
-        BUFF_SPAWNFUNC(e##_team2,   b,  NUM_TEAM_2) \
-        BUFF_SPAWNFUNC(e##_team3,   b,  NUM_TEAM_3) \
-        BUFF_SPAWNFUNC(e##_team4,   b,  NUM_TEAM_4)
+#define BUFF_SPAWNFUNC(e, b, t) void spawnfunc_item_buff_##e() { \
+       self.buffs = b.m_itemid; \
+       self.team = t; \
+       buff_Init(self); \
+}
+#define BUFF_SPAWNFUNCS(e, b)                       \
+               BUFF_SPAWNFUNC(e,           b,  0)          \
+               BUFF_SPAWNFUNC(e##_team1,   b,  NUM_TEAM_1) \
+               BUFF_SPAWNFUNC(e##_team2,   b,  NUM_TEAM_2) \
+               BUFF_SPAWNFUNC(e##_team3,   b,  NUM_TEAM_3) \
+               BUFF_SPAWNFUNC(e##_team4,   b,  NUM_TEAM_4)
+#define BUFF_SPAWNFUNC_Q3TA_COMPAT(o, r) void spawnfunc_item_##o() { buff_Init_Compat(self, r); }
 
 BUFF_SPAWNFUNCS(resistance,            BUFF_RESISTANCE)
 BUFF_SPAWNFUNCS(ammo,                  BUFF_AMMO)
@@ -101,7 +171,7 @@ BUFF_SPAWNFUNCS(invisible,          BUFF_INVISIBLE)
 BUFF_SPAWNFUNCS(inferno,               BUFF_INFERNO)
 BUFF_SPAWNFUNCS(swapper,               BUFF_SWAPPER)
 BUFF_SPAWNFUNCS(magnet,                        BUFF_MAGNET)
-BUFF_SPAWNFUNCS(random,                        0)
+BUFF_SPAWNFUNCS(random,                        BUFF_NULL)
 
 BUFF_SPAWNFUNC_Q3TA_COMPAT(doubler,    BUFF_MEDIC)
 BUFF_SPAWNFUNC_Q3TA_COMPAT(resistance, BUFF_RESISTANCE)
@@ -118,12 +188,4 @@ BUFF_SPAWNFUNC_Q3TA_COMPAT(medic,  BUFF_MEDIC)
 #undef BUFF_SPAWNFUNCS
 #endif
 
-vector Buff_Color(int buff_id);
-string Buff_PrettyName(int buff_id);
-string Buff_Name(int buff_id);
-int Buff_Type_FromName(string buff_name);
-int Buff_Type_FromSprite(string buff_sprite);
-int Buff_Skin(int buff_id);
-string Buff_Sprite(int buff_id);
-float Buff_Timer(int buff_id);
 #endif
index 93901a1d1b4b6f92cb71c8c60b3d1525be2e6e5c..d322db4b7991e21162974526aef6e1175c155780 100644 (file)
@@ -1,7 +1,6 @@
 /** If you register a new item, make sure to add it to this list */
 #include "item/ammo.qc"
 #include "item/armor.qc"
-#include "item/buff.qc"
 #include "item/health.qc"
 #include "item/jetpack.qc"
 #include "item/pickup.qc"
index 2de5afb4ca4869dbe75ee6d10c91ec31e4a94497..f221ab2d3f6a6bf1cb367540422bc35c2b43c9a1 100644 (file)
@@ -6,7 +6,7 @@
 
 void Dump_Items()
 {
-    ITEMS_FOREACH(true, LAMBDA({
+    FOREACH(ITEMS, 0, ITEM_COUNT, true, LAMBDA({
         ITEM_HANDLE(Show, it);
     }));
 }
index c42139e25f6a1b4f4c12cba0e350e8ec2daac506..372e3ff69c1a02dd9f0967ab8a82f69ea84d1eaa 100644 (file)
@@ -11,13 +11,6 @@ int ITEM_COUNT;
 #define REGISTER_ITEM(id, class) REGISTER(RegisterItems, ITEM, ITEMS, ITEM_COUNT, id, class, m_id)
 REGISTER_REGISTRY(RegisterItems)
 
-#define ITEMS_FOREACH(pred, body) do {      \
-    for (int i = 0; i < ITEM_COUNT; i++) {  \
-        const noref entity it = ITEMS[i];   \
-        if (pred) { body }                  \
-    }                                       \
-} while(0)
-
 void Dump_Items();
 
 #endif
index 89abc97cff2a82f252cca4730061a367b741c354..25590ea43cd45713a44bd1e6095e716bb22575b5 100644 (file)
@@ -15,7 +15,7 @@ class(Inventory) .int inv_items[MAX_ITEMS];
 void Inventory_Read(Inventory data)
 {
     const int bits = ReadInt24_t();
-    ITEMS_FOREACH(bits & BIT(i), LAMBDA({
+    FOREACH(ITEMS, 0, ITEM_COUNT, bits & BIT(i), LAMBDA({
         .int fld = inv_items[i];
         int prev = data.(fld);
         int next = data.(fld) = ReadByte();
@@ -28,12 +28,12 @@ void Inventory_Read(Inventory data)
 void Inventory_Write(Inventory data)
 {
     int bits = 0;
-    ITEMS_FOREACH(true, LAMBDA({
+    FOREACH(ITEMS, 0, ITEM_COUNT, true, LAMBDA({
         .int fld = inv_items[i];
         bits = BITSET(bits, BIT(i), data.inventory.(fld) != (data.inventory.(fld) = data.(fld)));
     }));
     WriteInt24_t(MSG_ENTITY, bits);
-    ITEMS_FOREACH(bits & BIT(i), LAMBDA({
+    FOREACH(ITEMS, 0, ITEM_COUNT, bits & BIT(i), LAMBDA({
         WriteByte(MSG_ENTITY, data.inv_items[i]);
     }));
 }
diff --git a/qcsrc/common/items/item/buff.qc b/qcsrc/common/items/item/buff.qc
deleted file mode 100644 (file)
index 1cad2f2..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "buff.qh"
-
-REGISTER_ITEM(DefaultBuff, Buff);
diff --git a/qcsrc/common/items/item/buff.qh b/qcsrc/common/items/item/buff.qh
deleted file mode 100644 (file)
index 4ad93cb..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef BUFF_H
-#define BUFF_H
-#include "pickup.qh"
-CLASS(Buff, Pickup)
-    ATTRIB(Buff, m_name, string, "Buff")
-ENDCLASS(Buff)
-#endif
index eecdc229360add35a08b9aaa8e7825ce9543eb1d..f7afcc60fe5b30389c9b22d19e194593dbad3c6b 100644 (file)
@@ -1094,8 +1094,8 @@ const float ARG_DC = 6; // unique result to durcnt/centerprint
     ARG_CASE(ARG_CS_SV,     "spree_end",     (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \
     ARG_CASE(ARG_CS_SV,     "spree_lost",    (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \
     ARG_CASE(ARG_CS_SV,     "item_wepname",  WEP_NAME(f1)) \
-    ARG_CASE(ARG_CS_SV,     "item_buffname", sprintf("%s%s", rgb_to_hexcolor(Buff_Color(f1)), Buff_PrettyName(f1))) \
-    ARG_CASE(ARG_CS_SV,     "f3buffname",    sprintf("%s%s", rgb_to_hexcolor(Buff_Color(f3)), Buff_PrettyName(f3))) \
+    ARG_CASE(ARG_CS_SV,     "item_buffname", sprintf("%s%s", rgb_to_hexcolor(BUFFS[f1].m_color), BUFFS[f1].m_prettyName)) \
+    ARG_CASE(ARG_CS_SV,     "f3buffname",    sprintf("%s%s", rgb_to_hexcolor(BUFFS[f3].m_color), BUFFS[f3].m_prettyName)) \
     ARG_CASE(ARG_CS_SV,     "item_wepammo",  (s1 != "" ? sprintf(_(" with %s"), s1) : "")) \
     ARG_CASE(ARG_DC,        "item_centime",  ftos(autocvar_notification_item_centerprinttime)) \
     ARG_CASE(ARG_SV,        "death_team",    Team_ColoredFullName(f1)) \
index 4143ad3b11a71e651fba7b32e129f132692ea702..6153d80ae7f3efb2b750979c6758741b63d5194a 100644 (file)
@@ -1885,7 +1885,7 @@ void PM_Main()
                RaceCarPhysics();
 #endif
 
-       else if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY || self.movetype == MOVETYPE_FLY_WORLDONLY || (BUFFS(self) & BUFF_FLIGHT))
+       else if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY || self.movetype == MOVETYPE_FLY_WORLDONLY || (BUFFS_STAT(self) & BUFF_FLIGHT.m_itemid))
                PM_fly(maxspeed_mod);
 
        else if (self.waterlevel >= WATERLEVEL_SWIMMING)
index 25d476b10dad4fd35a9ca5ebaf884c2476a5ff4b..d4e5fdd389b9e86dc33f8881c05403cbcff9f404 100644 (file)
@@ -95,7 +95,7 @@ bool IsFlying(entity a);
        #define WAS_ONGROUND(s)                                         !!(s.lastflags & FL_ONGROUND)
 
        #define ITEMS_STAT(s)                                           (s).items
-       #define BUFFS(s)                                                        getstati(STAT_BUFFS)
+       #define BUFFS_STAT(s)                                           getstati(STAT_BUFFS)
 
        #define PHYS_AMMO_FUEL(s)                                       getstati(STAT_FUEL)
 
@@ -295,7 +295,7 @@ bool IsFlying(entity a);
        #define WAS_ONGROUND(s)                                         !!((s).lastflags & FL_ONGROUND)
 
        #define ITEMS_STAT(s)                                           s.items
-       #define BUFFS(s)                                                        (s).buffs
+       #define BUFFS_STAT(s)                                           (s).buffs
 
        #define PHYS_AMMO_FUEL(s)                                       s.ammo_fuel
 
index 4c24b491d9b33661bf562a333009dc1d89db5f30..3bf8f40992325a8c90873b5fe64c9ac20518eadc 100644 (file)
@@ -1,17 +1,22 @@
 #ifndef REGISTRY_H
 #define REGISTRY_H
 
+#include "oo.qh"
+
 #define REGISTER_INIT(ns, id) [[accumulate]] void Register_##ns##_##id##_init(entity this)
+#define REGISTER_INIT_POST(ns, id) [[accumulate]] void Register_##ns##_##id##_init_post(entity this)
 
 #define REGISTER(initfunc, ns, array, counter, id, class, fld)  \
     entity ns##_##id;                                           \
     REGISTER_INIT(ns, id) { }                                   \
+    REGISTER_INIT_POST(ns, id) { }                              \
     void Register_##ns##_##id() {                               \
         entity this = NEW(class);                               \
         ns##_##id = this;                                       \
         this.fld = counter;                                     \
         array[counter++] = this;                                \
         Register_##ns##_##id##_init(this);                      \
+        Register_##ns##_##id##_init_post(this);                 \
     }                                                           \
     ACCUMULATE_FUNCTION(initfunc, Register_##ns##_##id)         \
     REGISTER_INIT(ns, id)
index 9d60ae0a9ae2797bfdaedea9632237e81554f564..cb2ef8f80e93bd43036e4f21ff6fe053f1bf7b5e 100644 (file)
 [[deprecated("use true")]] [[alias("true")]] const bool TRUE;
 [[deprecated("use false")]] [[alias("false")]] const bool FALSE;
 
+#define FOREACH(arr, start, end, cond, body) do { \
+    for (int i = start; i < end; ++i) {     \
+        const noref entity it = arr[i];     \
+        if (cond) { body }                  \
+    }                                       \
+} while(0)
+
 #ifdef GMQCC
     #define OVERLOAD(F, ...) F##_##__VA_COUNT__(__VA_ARGS__)
 #else
index 1c88f0472fe97d21a2b4f4ee437dfb95b2d6ef8a..27db2b4fd90d7b3ad7d0c4c2c81f7be658763056 100644 (file)
@@ -565,7 +565,6 @@ void spawnfunc___init_dedicated_server(void)
        CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
-       CALL_ACCUMULATED_FUNCTION(RegisterBuffs);
 
        MapInfo_Enumerate();
        MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
@@ -616,7 +615,6 @@ void spawnfunc_worldspawn (void)
        CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
-       CALL_ACCUMULATED_FUNCTION(RegisterBuffs);
 
        ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
 
index 3debf921c6bbb863ac4b56d4ae5c5b90b40982c1..877bca9f6bfa85aa0ad0dd22e851e1f149a859a9 100644 (file)
@@ -6,6 +6,20 @@
 
 #include "../../common/buffs.qh"
 
+entity buff_FirstFromFlags(int _buffs)
+{
+       if (flags)
+       {
+               FOREACH(BUFFS, 0, BUFFS_COUNT,
+                       it.m_itemid & _buffs,
+                       LAMBDA({
+                               return it;
+                       })
+               );
+       }
+       return BUFF_NULL;
+}
+
 float buffs_BuffModel_Customize()
 {
        entity player, myowner;
@@ -49,7 +63,7 @@ void buffs_BuffModel_Spawn(entity player)
 vector buff_GlowColor(entity buff)
 {
        //if(buff.team) { return Team_ColorRGB(buff.team); }
-       return buff.color;
+       return buff.m_color;
 }
 
 void buff_Effect(entity player, string eff)
@@ -66,28 +80,23 @@ void buff_Effect(entity player, string eff)
 // buff item
 float buff_Waypoint_visible_for_player(entity plr)
 {
-    if(!self.owner.buff_active && !self.owner.buff_activetime)
-        return false;
+       if(!self.owner.buff_active && !self.owner.buff_activetime)
+               return false;
 
-       if(plr.buffs)
+       if (plr.buffs)
        {
-               if(plr.cvar_cl_buffs_autoreplace)
-               {
-                       if(plr.buffs == self.owner.buffs)
-                               return false;
-               }
-               else
-                       return false;
+               return plr.cvar_cl_buffs_autoreplace == false || plr.buffs != self.owner.buffs;
        }
 
-    return WaypointSprite_visible_for_player(plr);
+       return WaypointSprite_visible_for_player(plr);
 }
 
 void buff_Waypoint_Spawn(entity e)
 {
-    WaypointSprite_Spawn(Buff_Sprite(e.buffs), 0, autocvar_g_buffs_waypoint_distance, e, '0 0 1' * e.maxs.z, world, e.team, e, buff_waypoint, true, RADARICON_POWERUP, e.glowmod);
-    WaypointSprite_UpdateTeamRadar(e.buff_waypoint, RADARICON_POWERUP, e.glowmod);
-    e.buff_waypoint.waypointsprite_visible_for_player = buff_Waypoint_visible_for_player;
+       entity buff = buff_FirstFromFlags(e.buffs);
+       WaypointSprite_Spawn(buff.m_sprite, 0, autocvar_g_buffs_waypoint_distance, e, '0 0 1' * e.maxs.z, world, e.team, e, buff_waypoint, true, RADARICON_POWERUP, e.glowmod);
+       WaypointSprite_UpdateTeamRadar(e.buff_waypoint, RADARICON_POWERUP, e.glowmod);
+       e.buff_waypoint.waypointsprite_visible_for_player = buff_Waypoint_visible_for_player;
 }
 
 void buff_SetCooldown(float cd)
@@ -156,12 +165,13 @@ void buff_Touch()
                return;
        }
 
-       if(other.buffs)
+       if (other.buffs)
        {
-               if(other.cvar_cl_buffs_autoreplace && other.buffs != self.buffs)
+               if (other.cvar_cl_buffs_autoreplace && other.buffs != self.buffs)
                {
+                       int buffid = buff_FirstFromFlags(other.buffs).m_id;
                        //Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_BUFF_DROP, other.buffs);
-                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ITEM_BUFF_LOST, other.netname, other.buffs);
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ITEM_BUFF_LOST, other.netname, buffid);
 
                        other.buffs = 0;
                        //sound(other, CH_TRIGGER, "relics/relic_effect.wav", VOL_BASE, ATTN_NORM);
@@ -172,39 +182,39 @@ void buff_Touch()
        self.owner = other;
        self.buff_active = false;
        self.lifetime = 0;
-
-       Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_BUFF_GOT, self.buffs);
-       Send_Notification(NOTIF_ALL_EXCEPT, other, MSG_INFO, INFO_ITEM_BUFF, other.netname, self.buffs);
+       int buffid = buff_FirstFromFlags(self.buffs).m_id;
+       Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_BUFF_GOT, buffid);
+       Send_Notification(NOTIF_ALL_EXCEPT, other, MSG_INFO, INFO_ITEM_BUFF, other.netname, buffid);
 
        pointparticles(particleeffectnum("item_pickup"), CENTER_OR_VIEWOFS(self), '0 0 0', 1);
        sound(other, CH_TRIGGER, "misc/shield_respawn.wav", VOL_BASE, ATTN_NORM);
        other.buffs |= (self.buffs);
 }
 
-float buff_Available(float buffid)
+float buff_Available(entity buff)
 {
-       if(buffid == BUFF_AMMO && ((start_items & IT_UNLIMITED_WEAPON_AMMO) || (start_items & IT_UNLIMITED_AMMO) || (cvar("g_melee_only"))))
+       if (buff == BUFF_NULL)
                return false;
-
-       if(buffid == BUFF_VAMPIRE && cvar("g_vampire"))
+       if (buff == BUFF_AMMO && ((start_items & IT_UNLIMITED_WEAPON_AMMO) || (start_items & IT_UNLIMITED_AMMO) || (cvar("g_melee_only"))))
                return false;
-
-       if(!cvar(strcat("g_buffs_", Buff_Name(buffid))))
+       if (buff == BUFF_VAMPIRE && cvar("g_vampire"))
                return false;
-
-       return true;
+       return cvar(strcat("g_buffs_", buff.m_name));
 }
 
+.int buff_seencount;
+
 void buff_NewType(entity ent, float cb)
 {
-       entity e;
        RandomSelection_Init();
-       for(e = Buff_Type_first; e; e = e.enemy)
-       if(buff_Available(e.items))
-       {
-               RandomSelection_Add(world, e.items, string_null, 1, max(0.2, 1 / e.count)); // if it's already been chosen, give it a lower priority
-               e.count += 1;
-       }
+       FOREACH(BUFFS, 0, BUFFS_COUNT,
+               buff_Available(it),
+               LAMBDA({
+                       it.buff_seencount += 1;
+                       // if it's already been chosen, give it a lower priority
+                       RandomSelection_Add(world, it.m_itemid, string_null, 1, max(0.2, 1 / it.buff_seencount));
+               })
+       );
        ent.buffs = RandomSelection_chosen_float;
 }
 
@@ -212,9 +222,10 @@ void buff_Think()
 {
        if(self.buffs != self.oldbuffs)
        {
-               self.color = Buff_Color(self.buffs);
-               self.glowmod = buff_GlowColor(self);
-               self.skin = Buff_Skin(self.buffs);
+               entity buff = buff_FirstFromFlags(self.buffs);
+               self.color = buff.m_color;
+               self.glowmod = buff_GlowColor(buff);
+               self.skin = buff.m_skin;
 
                setmodel(self, BUFF_MODEL);
 
@@ -236,7 +247,7 @@ void buff_Think()
        {
                buff_SetCooldown(self.buff_activetime);
                self.buff_activetime_updated = true;
-    }
+       }
 
        if(!self.buff_active && !self.buff_activetime)
        if(!self.owner || self.owner.frozen || self.owner.deadflag != DEAD_NO || !self.owner.iscreature || !(self.owner.buffs & self.buffs))
@@ -323,9 +334,11 @@ void buff_Init(entity ent)
 
        if(!teamplay && ent.team) { ent.team = 0; }
 
+       entity buff = buff_FirstFromFlags(self.buffs);
+
        entity oldself = self;
        self = ent;
-       if(!self.buffs || buff_Available(self.buffs))
+       if(!self.buffs || buff_Available(buff))
                buff_NewType(self, 0);
 
        self.classname = "item_buff";
@@ -338,12 +351,12 @@ void buff_Init(entity ent)
        self.gravity = 1;
        self.movetype = MOVETYPE_TOSS;
        self.scale = 1;
-       self.skin = Buff_Skin(self.buffs);
+       self.skin = buff.m_skin;
        self.effects = EF_FULLBRIGHT | EF_STARDUST | EF_NOSHADOW;
        self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
        self.customizeentityforclient = buff_Customize;
        //self.gravity = 100;
-       self.color = Buff_Color(self.buffs);
+       self.color = buff.m_color;
        self.glowmod = buff_GlowColor(self);
        buff_SetCooldown(autocvar_g_buffs_cooldown_activate + game_starttime);
        self.buff_active = !self.buff_activetime;
@@ -364,14 +377,14 @@ void buff_Init(entity ent)
        self = oldself;
 }
 
-void buff_Init_Compat(entity ent, float replacement)
+void buff_Init_Compat(entity ent, entity replacement)
 {
-       if(ent.spawnflags & 2)
+       if (ent.spawnflags & 2)
                ent.team = NUM_TEAM_1;
-       else if(ent.spawnflags & 4)
+       else if (ent.spawnflags & 4)
                ent.team = NUM_TEAM_2;
 
-       ent.buffs = replacement;
+       ent.buffs = replacement.m_itemid;
 
        buff_Init(ent);
 }
@@ -404,7 +417,7 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_SplitHealthArmor)
 {
        if(frag_deathtype == DEATH_BUFF) { return false; }
 
-       if(frag_target.buffs & BUFF_RESISTANCE)
+       if(frag_target.buffs & BUFF_RESISTANCE.m_itemid)
        {
                vector v = healtharmor_applydamage(50, autocvar_g_buffs_resistance_blockpercent, frag_deathtype, frag_damage);
                damage_take = v.x;
@@ -418,22 +431,22 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_Calculate)
 {
        if(frag_deathtype == DEATH_BUFF) { return false; }
 
-       if(frag_target.buffs & BUFF_SPEED)
+       if(frag_target.buffs & BUFF_SPEED.m_itemid)
        if(frag_target != frag_attacker)
                frag_damage *= autocvar_g_buffs_speed_damage_take;
 
-       if(frag_target.buffs & BUFF_MEDIC)
+       if(frag_target.buffs & BUFF_MEDIC.m_itemid)
        if((frag_target.health - frag_damage) <= 0)
        if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
        if(frag_attacker)
        if(random() <= autocvar_g_buffs_medic_survive_chance)
                frag_damage = max(5, frag_target.health - autocvar_g_buffs_medic_survive_health);
 
-       if(frag_target.buffs & BUFF_JUMP)
+       if(frag_target.buffs & BUFF_JUMP.m_itemid)
        if(frag_deathtype == DEATH_FALL)
                frag_damage = 0;
 
-       if(frag_target.buffs & BUFF_VENGEANCE)
+       if(frag_target.buffs & BUFF_VENGEANCE.m_itemid)
        if(frag_attacker)
        if(frag_attacker != frag_target)
        if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
@@ -447,23 +460,23 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_Calculate)
                dmgent.nextthink = time + 0.1;
        }
 
-       if(frag_target.buffs & BUFF_BASH)
+       if(frag_target.buffs & BUFF_BASH.m_itemid)
        if(frag_attacker != frag_target)
        if(vlen(frag_force))
                frag_force = '0 0 0';
 
-       if(frag_attacker.buffs & BUFF_BASH)
+       if(frag_attacker.buffs & BUFF_BASH.m_itemid)
        if(vlen(frag_force))
        if(frag_attacker == frag_target)
                frag_force *= autocvar_g_buffs_bash_force_self;
        else
                frag_force *= autocvar_g_buffs_bash_force;
 
-       if(frag_attacker.buffs & BUFF_DISABILITY)
+       if(frag_attacker.buffs & BUFF_DISABILITY.m_itemid)
        if(frag_target != frag_attacker)
                frag_target.buff_disability_time = time + autocvar_g_buffs_disability_slowtime;
 
-       if(frag_attacker.buffs & BUFF_MEDIC)
+       if(frag_attacker.buffs & BUFF_MEDIC.m_itemid)
        if(DEATH_WEAPONOF(frag_deathtype) != WEP_ARC)
        if(SAME_TEAM(frag_attacker, frag_target))
        if(frag_attacker != frag_target)
@@ -472,7 +485,7 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_Calculate)
                frag_damage = 0;
        }
 
-       if(frag_attacker.buffs & BUFF_INFERNO)
+       if(frag_attacker.buffs & BUFF_INFERNO.m_itemid)
        if(frag_target != frag_attacker) {
                float time = buff_Inferno_CalculateTime(
                        frag_damage,
@@ -486,7 +499,7 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_Calculate)
        }
 
        // this... is ridiculous (TODO: fix!)
-       if(frag_attacker.buffs & BUFF_VAMPIRE)
+       if(frag_attacker.buffs & BUFF_VAMPIRE.m_itemid)
        if(!frag_target.vehicle)
        if(DEATH_WEAPONOF(frag_deathtype) != WEP_ARC)
        if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
@@ -516,7 +529,7 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerSpawn)
 
 MUTATOR_HOOKFUNCTION(buffs_PlayerPhysics)
 {
-       if(self.buffs & BUFF_SPEED)
+       if(self.buffs & BUFF_SPEED.m_itemid)
        {
                self.stat_sv_maxspeed *= autocvar_g_buffs_speed_speed;
                self.stat_sv_airspeedlimit_nonqw *= autocvar_g_buffs_speed_speed;
@@ -528,7 +541,7 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerPhysics)
                self.stat_sv_airspeedlimit_nonqw *= autocvar_g_buffs_disability_speed;
        }
 
-       if(self.buffs & BUFF_JUMP)
+       if(self.buffs & BUFF_JUMP.m_itemid)
        {
                // automatically reset, no need to worry
                self.stat_sv_jumpvelocity = autocvar_g_buffs_jump_height;
@@ -539,7 +552,7 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerPhysics)
 
 MUTATOR_HOOKFUNCTION(buffs_PlayerJump)
 {
-       if(self.buffs & BUFF_JUMP)
+       if(self.buffs & BUFF_JUMP.m_itemid)
                player_jumpheight = autocvar_g_buffs_jump_height;
 
        return false;
@@ -560,7 +573,8 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerDies)
 {
        if(self.buffs)
        {
-               Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, self.buffs);
+               int buffid = buff_FirstFromFlags(self.buffs).m_id;
+               Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, buffid);
                self.buffs = 0;
 
                if(self.buff_model)
@@ -577,8 +591,9 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerUseKey)
        if(MUTATOR_RETURNVALUE || gameover) { return false; }
        if(self.buffs)
        {
-               Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_BUFF_DROP, self.buffs);
-               Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, self.buffs);
+               int buffid = buff_FirstFromFlags(self.buffs).m_id;
+               Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_BUFF_DROP, buffid);
+               Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, buffid);
 
                self.buffs = 0;
                sound(self, CH_TRIGGER, "relics/relic_effect.wav", VOL_BASE, ATTN_NORM);
@@ -591,7 +606,7 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerThrowKey)
 {
        if(MUTATOR_RETURNVALUE || gameover) { return false; }
 
-       if(self.buffs & BUFF_SWAPPER)
+       if(self.buffs & BUFF_SWAPPER.m_itemid)
        {
                float best_distance = autocvar_g_buffs_swapper_range;
                entity closest = world;
@@ -678,7 +693,7 @@ MUTATOR_HOOKFUNCTION(buffs_CustomizeWaypoint)
 
        // if you have the invisibility powerup, sprites ALWAYS are restricted to your team
        // but only apply this to real players, not to spectators
-       if((self.owner.flags & FL_CLIENT) && (self.owner.buffs & BUFF_INVISIBLE) && (e == other))
+       if((self.owner.flags & FL_CLIENT) && (self.owner.buffs & BUFF_INVISIBLE.m_itemid) && (e == other))
        if(DIFF_TEAM(self.owner, e))
                return true;
 
@@ -703,7 +718,7 @@ MUTATOR_HOOKFUNCTION(buffs_OnEntityPreSpawn)
 
 MUTATOR_HOOKFUNCTION(buffs_WeaponRate)
 {
-       if(self.buffs & BUFF_SPEED)
+       if(self.buffs & BUFF_SPEED.m_itemid)
                weapon_rate *= autocvar_g_buffs_speed_rate;
 
        if(time < self.buff_disability_time)
@@ -714,7 +729,7 @@ MUTATOR_HOOKFUNCTION(buffs_WeaponRate)
 
 MUTATOR_HOOKFUNCTION(buffs_WeaponSpeed)
 {
-       if(self.buffs & BUFF_SPEED)
+       if(self.buffs & BUFF_SPEED.m_itemid)
                ret_float *= autocvar_g_buffs_speed_weaponspeed;
 
        if(time < self.buff_disability_time)
@@ -723,6 +738,8 @@ MUTATOR_HOOKFUNCTION(buffs_WeaponSpeed)
        return false;
 }
 
+.float buff_time;
+
 MUTATOR_HOOKFUNCTION(buffs_PlayerThink)
 {
        if(gameover || self.deadflag != DEAD_NO) { return false; }
@@ -749,17 +766,18 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerThink)
        {
                if(self.buffs)
                {
-                       Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, self.buffs);
+                       int buffid = buff_FirstFromFlags(self.buffs).m_id;
+                       Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, buffid);
                        if(buff_lost >= 2)
                        {
-                               Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_BUFF_DROP, self.buffs); // TODO: special timeout message?
+                               Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_BUFF_DROP, buffid); // TODO: special timeout message?
                                sound(self, CH_TRIGGER, "relics/relic_effect.wav", VOL_BASE, ATTN_NORM);
                        }
                        self.buffs = 0;
                }
        }
 
-       if(self.buffs & BUFF_MAGNET)
+       if(self.buffs & BUFF_MAGNET.m_itemid)
        {
                vector pickup_size = '1 1 1' * autocvar_g_buffs_magnet_range_item;
                for(other = world; (other = findflags(other, flags, FL_ITEM)); )
@@ -775,23 +793,22 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerThink)
                }
        }
 
-       if(self.buffs & BUFF_AMMO)
+       if(self.buffs & BUFF_AMMO.m_itemid)
        if(self.clip_size)
                self.clip_load = self.(weapon_load[self.switchweapon]) = self.clip_size;
 
-       if((self.buffs & BUFF_INVISIBLE) && (self.oldbuffs & BUFF_INVISIBLE))
+       if((self.buffs & BUFF_INVISIBLE.m_itemid) && (self.oldbuffs & BUFF_INVISIBLE.m_itemid))
        if(self.alpha != autocvar_g_buffs_invisible_alpha)
                self.alpha = autocvar_g_buffs_invisible_alpha; // powerups reset alpha, so we must enforce this (TODO)
 
-#define BUFF_ONADD(b) if((self.buffs & (b)) && !(self.oldbuffs & (b)))
-#define BUFF_ONREM(b) if(!(self.buffs & (b)) && (self.oldbuffs & (b)))
+#define BUFF_ONADD(b) if ( (self.buffs & (b).m_itemid) && !(self.oldbuffs & (b).m_itemid))
+#define BUFF_ONREM(b) if (!(self.buffs & (b).m_itemid) &&  (self.oldbuffs & (b).m_itemid))
 
        if(self.buffs != self.oldbuffs)
        {
-               if(self.buffs && Buff_Timer(self.buffs))
-                       self.buff_time = time + Buff_Timer(self.buffs);
-               else
-                       self.buff_time = 0;
+               entity buff = buff_FirstFromFlags(self.buffs);
+               float bufftime = buff != BUFF_NULL ? buff.m_time(buff) : 0;
+               self.buff_time = (bufftime) ? time + bufftime : 0;
 
                BUFF_ONADD(BUFF_AMMO)
                {
@@ -841,9 +858,9 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerThink)
                        if(!self.buff_model)
                                buffs_BuffModel_Spawn(self);
 
-                       self.buff_model.color = Buff_Color(self.buffs);
+                       self.buff_model.color = buff.m_color;
                        self.buff_model.glowmod = buff_GlowColor(self.buff_model);
-                       self.buff_model.skin = Buff_Skin(self.buffs);
+                       self.buff_model.skin = buff.m_skin;
 
                        self.effects |= EF_NOSHADOW;
                }
@@ -892,14 +909,14 @@ MUTATOR_HOOKFUNCTION(buffs_VehicleExit)
 
 MUTATOR_HOOKFUNCTION(buffs_PlayerRegen)
 {
-       if(self.buffs & BUFF_MEDIC)
+       if(self.buffs & BUFF_MEDIC.m_itemid)
        {
                regen_mod_rot = autocvar_g_buffs_medic_rot;
                regen_mod_limit = regen_mod_max = autocvar_g_buffs_medic_max;
                regen_mod_regen = autocvar_g_buffs_medic_regen;
        }
 
-       if(self.buffs & BUFF_SPEED)
+       if(self.buffs & BUFF_SPEED.m_itemid)
                regen_mod_regen = autocvar_g_buffs_speed_regen;
 
        return false;
index 9e4727d8d1f1ae39fd0af4d58a6f0e6cbee62948..b2d9ee26937c68a56229ff65d6b0500db855287e 100644 (file)
@@ -290,7 +290,7 @@ MUTATOR_HOOKFUNCTION(instagib_PlayerDamage)
                frag_mirrordamage = 0;
        }
 
-       if((frag_target.buffs & BUFF_INVISIBLE) || (frag_target.items & IT_STRENGTH))
+       if((frag_target.buffs & BUFF_INVISIBLE.m_itemid) || (frag_target.items & IT_STRENGTH))
                yoda = 1;
 
        return false;