From 8800940bb4b94f6dab7dcf80bf0abc3e3b09e35f Mon Sep 17 00:00:00 2001
From: Andrei Karas <akaras@inbox.ru>
Date: Mon, 21 Mar 2016 19:37:01 +0300
Subject: Add support for using fields from status effects: option, opt1, opt2,
 opt3.

---
 src/being/actorsprite.cpp           | 80 +++++++++++++++++++++++++++----------
 src/being/actorsprite.h             | 16 ++++----
 src/resources/db/statuseffectdb.cpp | 43 +++++++++++++++++---
 src/resources/db/statuseffectdb.h   | 12 ++++++
 src/settings.h                      |  4 +-
 5 files changed, 120 insertions(+), 35 deletions(-)

diff --git a/src/being/actorsprite.cpp b/src/being/actorsprite.cpp
index 40b3ef992..df8f14fdf 100644
--- a/src/being/actorsprite.cpp
+++ b/src/being/actorsprite.cpp
@@ -22,6 +22,7 @@
 #include "being/actorsprite.h"
 
 #include "configuration.h"
+#include "settings.h"
 #include "statuseffect.h"
 
 #include "being/localplayer.h"
@@ -214,42 +215,79 @@ void ActorSprite::setStatusEffectBlock(const int offset,
     }
 }
 
+static void applyEffectByOption(ActorSprite *const actor,
+                                const uint32_t option,
+                                const OptionsMap& options)
+{
+    FOR_EACH (OptionsMapCIter, it, options)
+    {
+        const int opt = (*it).first;
+        const int id = (*it).second;
+        const Enable enable = (opt & option) != 0 ? Enable_true : Enable_false;
+        actor->setStatusEffect(id, enable);
+    }
+}
+
 void ActorSprite::setStatusEffectOpitons(const uint32_t option,
                                          const uint32_t opt1,
                                          const uint32_t opt2,
                                          const uint32_t opt3)
 {
-    uint32_t statusEffects = opt2;
-    statusEffects |= option << 16;
-
-    setStunMode(opt1);
-    setStatusEffectBlock(0,
-        CAST_U16((statusEffects >> 16) & 0xffffU));
-    setStatusEffectBlock(16,
-        CAST_U16(statusEffects & 0xffffU));
-    setStatusEffectBlock(32,
-        opt3);
+    if (settings.legacyEffects == false)
+    {
+        applyEffectByOption(this, option, StatusEffectDB::getOptionMap());
+        applyEffectByOption(this, opt1, StatusEffectDB::getOpt1Map());
+        applyEffectByOption(this, opt2, StatusEffectDB::getOpt2Map());
+        applyEffectByOption(this, opt3, StatusEffectDB::getOpt3Map());
+    }
+    else
+    {
+        uint32_t statusEffects = opt2;
+        statusEffects |= option << 16;
+        setStunMode(opt1);
+        setStatusEffectBlock(0,
+            CAST_U16((statusEffects >> 16) & 0xffffU));
+        setStatusEffectBlock(16,
+            CAST_U16(statusEffects & 0xffffU));
+        setStatusEffectBlock(32,
+            opt3);
+    }
 }
 
 void ActorSprite::setStatusEffectOpitons(const uint32_t option,
                                          const uint32_t opt1,
                                          const uint32_t opt2)
 {
-    uint32_t statusEffects = opt2;
-    statusEffects |= option << 16;
-
-    setStunMode(opt1);
-    setStatusEffectBlock(0,
-        CAST_U16((statusEffects >> 16) & 0xffffU));
-    setStatusEffectBlock(16,
-        CAST_U16(statusEffects & 0xffffU));
+    if (settings.legacyEffects == false)
+    {
+        applyEffectByOption(this, option, StatusEffectDB::getOptionMap());
+        applyEffectByOption(this, opt1, StatusEffectDB::getOpt1Map());
+        applyEffectByOption(this, opt2, StatusEffectDB::getOpt2Map());
+    }
+    else
+    {
+        uint32_t statusEffects = opt2;
+        statusEffects |= option << 16;
+        setStunMode(opt1);
+        setStatusEffectBlock(0,
+            CAST_U16((statusEffects >> 16) & 0xffffU));
+        setStatusEffectBlock(16,
+            CAST_U16(statusEffects & 0xffffU));
+    }
 }
 
 void ActorSprite::setStatusEffectOpiton0(const uint32_t option)
 {
-    const uint32_t statusEffects = option << 16;
-    setStatusEffectBlock(0,
-        CAST_U16((statusEffects >> 16) & 0xffff));
+    if (settings.legacyEffects == false)
+    {
+        applyEffectByOption(this, option, StatusEffectDB::getOptionMap());
+    }
+    else
+    {
+        const uint32_t statusEffects = option << 16;
+        setStatusEffectBlock(0,
+            CAST_U16((statusEffects >> 16) & 0xffff));
+    }
 }
 
 void ActorSprite::updateStunMode(const int oldMode, const int newMode)
diff --git a/src/being/actorsprite.h b/src/being/actorsprite.h
index 5c5f5a80d..0bc6eff00 100644
--- a/src/being/actorsprite.h
+++ b/src/being/actorsprite.h
@@ -131,14 +131,6 @@ class ActorSprite notfinal : public CompoundSprite, public Actor
 
         void setStatusEffectOpiton0(const uint32_t option);
 
-        /**
-         * A status effect block is a 16 bit mask of status effects. We assign
-         * each such flag a block ID of offset + bitnr.
-         *
-         * These are NOT the same as the status effect indices.
-         */
-        void setStatusEffectBlock(const int offset, const uint16_t flags);
-
         void setAlpha(const float alpha) override final
         { CompoundSprite::setAlpha(alpha); }
 
@@ -199,6 +191,14 @@ class ActorSprite notfinal : public CompoundSprite, public Actor
         { }
 
     protected:
+        /**
+         * A status effect block is a 16 bit mask of status effects. We assign
+         * each such flag a block ID of offset + bitnr.
+         *
+         * These are NOT the same as the status effect indices.
+         */
+        void setStatusEffectBlock(const int offset, const uint16_t flags);
+
         /**
          * Notify self that the stun mode has been updated. Invoked by
          * setStunMode if something changed.
diff --git a/src/resources/db/statuseffectdb.cpp b/src/resources/db/statuseffectdb.cpp
index 4390f79fe..cd7267fe2 100644
--- a/src/resources/db/statuseffectdb.cpp
+++ b/src/resources/db/statuseffectdb.cpp
@@ -23,6 +23,7 @@
 #include "resources/db/statuseffectdb.h"
 
 #include "configuration.h"
+#include "settings.h"
 #include "soundmanager.h"
 #include "statuseffect.h"
 
@@ -45,12 +46,12 @@ namespace
     typedef std::map<int, StatusEffect *> IdToEffectMap[2];
     bool mLoaded = false;
     IdToEffectMap statusEffects;
-    std::map<int, int> optionToIdMap;
-    std::map<int, int> opt1ToIdMap;
-    std::map<int, int> opt2ToIdMap;
-    std::map<int, int> opt3ToIdMap;
+    OptionsMap optionToIdMap;
+    OptionsMap opt1ToIdMap;
+    OptionsMap opt2ToIdMap;
+    OptionsMap opt3ToIdMap;
 
-    std::map<int, int> blockIdToIdMap;
+    OptionsMap blockIdToIdMap;
 }  // namespace
 
 int StatusEffectDB::blockIdToId(const int blockIndex)
@@ -126,13 +127,25 @@ void StatusEffectDB::loadXmlFile(const std::string &fileName)
         const int opt2 = XML::getProperty(node, "opt2", 0);
         const int opt3 = XML::getProperty(node, "opt3", 0);
         if (option != 0)
+        {
             optionToIdMap[option] = id;
+            settings.legacyEffects = false;
+        }
         if (opt1 != 0)
+        {
             opt1ToIdMap[opt1] = id;
+            settings.legacyEffects = false;
+        }
         if (opt2 != 0)
+        {
             opt2ToIdMap[opt2] = id;
+            settings.legacyEffects = false;
+        }
         if (opt3 != 0)
+        {
             opt3ToIdMap[opt3] = id;
+            settings.legacyEffects = false;
+        }
 
         StatusEffect *startEffect = statusEffects[1][id];
         StatusEffect *endEffect = statusEffects[0][id];
@@ -208,3 +221,23 @@ void StatusEffectDB::unload()
 
     mLoaded = false;
 }
+
+const OptionsMap& StatusEffectDB::getOptionMap()
+{
+    return optionToIdMap;
+}
+
+const OptionsMap& StatusEffectDB::getOpt1Map()
+{
+    return opt1ToIdMap;
+}
+
+const OptionsMap& StatusEffectDB::getOpt2Map()
+{
+    return opt2ToIdMap;
+}
+
+const OptionsMap& StatusEffectDB::getOpt3Map()
+{
+    return opt3ToIdMap;
+}
diff --git a/src/resources/db/statuseffectdb.h b/src/resources/db/statuseffectdb.h
index 6e39c9053..64dca44b2 100644
--- a/src/resources/db/statuseffectdb.h
+++ b/src/resources/db/statuseffectdb.h
@@ -25,12 +25,16 @@
 
 #include "enums/simpletypes/enable.h"
 
+#include <map>
 #include <string>
 
 #include "localconsts.h"
 
 class StatusEffect;
 
+typedef std::map<int, int> OptionsMap;
+typedef OptionsMap::const_iterator OptionsMapCIter;
+
 namespace StatusEffectDB
 {
     /**
@@ -57,6 +61,14 @@ namespace StatusEffectDB
     void loadXmlFile(const std::string &fileName);
 
     void unload();
+
+    const OptionsMap& getOptionMap();
+
+    const OptionsMap& getOpt1Map();
+
+    const OptionsMap& getOpt2Map();
+
+    const OptionsMap& getOpt3Map();
 }  // namespace StatusEffectDB
 
 #endif  // RESOURCES_DB_STATUSEFFECTDB_H
diff --git a/src/settings.h b/src/settings.h
index 21b5f2e1d..81e01e2ae 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -79,7 +79,8 @@ class Settings final
             awayMode(false),
             pseudoAwayMode(false),
             fixDeadAnimation(true),
-            disableLoggingInGame(false)
+            disableLoggingInGame(false),
+            legacyEffects(true)
         { }
 
         std::string updateHost;
@@ -129,6 +130,7 @@ class Settings final
         bool pseudoAwayMode;
         bool fixDeadAnimation;
         bool disableLoggingInGame;
+        bool legacyEffects;
 };
 
 extern Settings settings;
-- 
cgit v1.2.3-70-g09d2