From 8508f94daeeb49b6ccf3ee1a346f1dc9f9c56802 Mon Sep 17 00:00:00 2001
From: Ben Longbons <b.r.longbons@gmail.com>
Date: Thu, 13 Feb 2014 23:30:32 -0800
Subject: Name and number mapflags better

---
 src/map/atcommand.cpp |   9 ---
 src/map/map.hpp       |  29 +-------
 src/map/mapflag.cpp   | 179 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/map/mapflag.hpp   |  98 +++++++++++++++++++++++++++
 src/map/npc.cpp       | 104 ++++-------------------------
 src/map/script.cpp    | 180 ++------------------------------------------------
 6 files changed, 298 insertions(+), 301 deletions(-)
 create mode 100644 src/map/mapflag.cpp
 create mode 100644 src/map/mapflag.hpp

diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp
index dca9b4e..ef94963 100644
--- a/src/map/atcommand.cpp
+++ b/src/map/atcommand.cpp
@@ -3443,12 +3443,6 @@ ATCE atcommand_mapinfo(Session *s, dumb_ptr<map_session_data> sd,
              (m_id->flag.pvp) ? "True" : "False",
              (m_id->flag.pvp_noparty) ? "True" : "False");
     clif_displaymessage(s, output);
-    output = STRPRINTF("No Dead Branch: %s",
-             (m_id->flag.nobranch) ? "True" : "False");
-    clif_displaymessage(s, output);
-    output = STRPRINTF("No Memo: %s",
-             (m_id->flag.nomemo) ? "True" : "False");
-    clif_displaymessage(s, output);
     output = STRPRINTF("No Penalty: %s",
              (m_id->flag.nopenalty) ? "True" : "False");
     clif_displaymessage(s, output);
@@ -3464,9 +3458,6 @@ ATCE atcommand_mapinfo(Session *s, dumb_ptr<map_session_data> sd,
     output = STRPRINTF("No Monster Teleport: %s",
              (m_id->flag.monster_noteleport) ? "True" : "False");
     clif_displaymessage(s, output);
-    output = STRPRINTF("No Zeny Penalty: %s",
-             (m_id->flag.nozenypenalty) ? "True" : "False");
-    clif_displaymessage(s, output);
 
     switch (list)
     {
diff --git a/src/map/map.hpp b/src/map/map.hpp
index 092fd80..685feed 100644
--- a/src/map/map.hpp
+++ b/src/map/map.hpp
@@ -22,6 +22,7 @@
 
 # include "battle.t.hpp"
 # include "magic-interpreter.t.hpp"
+# include "mapflag.hpp"
 # include "mob.t.hpp"
 # include "script.hpp"   // change to script.t.hpp
 # include "skill.t.hpp"
@@ -514,33 +515,7 @@ struct map_local : map_abstract
     short xs, ys;
     int npc_num;
     int users;
-    struct
-    {
-        unsigned alias:1;
-        unsigned nomemo:1;
-        unsigned noteleport:1;
-        unsigned noreturn:1;
-        unsigned monster_noteleport:1;
-        unsigned nosave:1;
-        unsigned nobranch:1;
-        unsigned nopenalty:1;
-        unsigned pvp:1;
-        unsigned pvp_noparty:1;
-        unsigned pvp_nocalcrank:1;
-        unsigned nozenypenalty:1;
-        unsigned notrade:1;
-        unsigned nowarp:1;
-        unsigned nowarpto:1;
-        unsigned nopvp:1;       // [Valaris]
-        unsigned noicewall:1;   // [Valaris]
-        unsigned snow:1;        // [Valaris]
-        unsigned fog:1;         // [Valaris]
-        unsigned sakura:1;      // [Valaris]
-        unsigned leaves:1;      // [Valaris]
-        unsigned rain:1;        // [Valaris]
-        unsigned no_player_drops:1; // [Jaxad0127]
-        unsigned town:1;        // [remoitnane]
-    } flag;
+    MapFlags flag;
     struct point save;
     dumb_ptr<npc_data> npc[MAX_NPC_PER_MAP];
     struct
diff --git a/src/map/mapflag.cpp b/src/map/mapflag.cpp
new file mode 100644
index 0000000..4b7b305
--- /dev/null
+++ b/src/map/mapflag.cpp
@@ -0,0 +1,179 @@
+#include "mapflag.hpp"
+//    mapflag.cpp - Implementation of map flag settings
+//
+//    Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
+//
+//    This file is part of The Mana World (Athena server)
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#include "../poison.hpp"
+
+// because bitfields, that's why
+
+bool MapFlags::get(MapFlag mf) const
+{
+    switch (mf)
+    {
+    case MapFlag::NOTELEPORT:
+        return noteleport;
+    case MapFlag::NORETURN:
+        return noreturn;
+    case MapFlag::MONSTER_NOTELEPORT:
+        return monster_noteleport;
+    case MapFlag::NOSAVE:
+        return nosave;
+    case MapFlag::NOPENALTY:
+        return nopenalty;
+    case MapFlag::PVP:
+        return pvp;
+    case MapFlag::PVP_NOPARTY:
+        return pvp_noparty;
+    case MapFlag::PVP_NOCALCRANK:
+        return pvp_nocalcrank;
+    case MapFlag::NOWARP:
+        return nowarp;
+    case MapFlag::NOWARPTO:
+        return nowarpto;
+    case MapFlag::NOPVP:
+        return nopvp;
+    case MapFlag::SNOW:
+        return snow;
+    case MapFlag::FOG:
+        return fog;
+    case MapFlag::SAKURA:
+        return sakura;
+    case MapFlag::LEAVES:
+        return leaves;
+    case MapFlag::RAIN:
+        return rain;
+    case MapFlag::NO_PLAYER_DROPS:
+        return no_player_drops;
+    case MapFlag::TOWN:
+        return town;
+    default:
+        return false;
+    }
+}
+
+void MapFlags::set(MapFlag mf, bool val)
+{
+    switch (mf)
+    {
+    case MapFlag::NOTELEPORT:
+        noteleport = val;
+        break;
+    case MapFlag::NORETURN:
+        noreturn = val;
+        break;
+    case MapFlag::MONSTER_NOTELEPORT:
+        monster_noteleport = val;
+        break;
+    case MapFlag::NOSAVE:
+        nosave = val;
+        break;
+    case MapFlag::NOPENALTY:
+        nopenalty = val;
+        break;
+    case MapFlag::PVP:
+        pvp = val;
+        break;
+    case MapFlag::PVP_NOPARTY:
+        pvp_noparty = val;
+        break;
+    case MapFlag::PVP_NOCALCRANK:
+        pvp_nocalcrank = val;
+        break;
+    case MapFlag::NOWARP:
+        nowarp = val;
+        break;
+    case MapFlag::NOWARPTO:
+        nowarpto = val;
+        break;
+    case MapFlag::NOPVP:
+        nopvp = val;
+        break;
+    case MapFlag::SNOW:
+        snow = val;
+        break;
+    case MapFlag::FOG:
+        fog = val;
+        break;
+    case MapFlag::SAKURA:
+        sakura = val;
+        break;
+    case MapFlag::LEAVES:
+        leaves = val;
+        break;
+    case MapFlag::RAIN:
+        rain = val;
+        break;
+    case MapFlag::NO_PLAYER_DROPS:
+        no_player_drops = val;
+        break;
+    case MapFlag::TOWN:
+        town = val;
+        break;
+    default:
+        break;
+    }
+}
+
+template<>
+bool extract<MapFlag, void, void>(XString str, MapFlag *mf)
+{
+    const struct
+    {
+        char str[32];
+        MapFlag id;
+    } flags[] =
+    {
+        //{"alias", MapFlag::ALIAS},
+        //{"nomemo", MapFlag::NOMEMO},
+        {"noteleport", MapFlag::NOTELEPORT},
+        {"noreturn", MapFlag::NORETURN},
+        {"monster_noteleport", MapFlag::MONSTER_NOTELEPORT},
+        {"nosave", MapFlag::NOSAVE},
+        //{"nobranch", MapFlag::NOBRANCH},
+        {"nopenalty", MapFlag::NOPENALTY},
+        {"pvp", MapFlag::PVP},
+        {"pvp_noparty", MapFlag::PVP_NOPARTY},
+        //{"pvp_noguild", MapFlag::PVP_NOGUILD},
+        //{"pvp_nightmaredrop", MapFlag::PVP_NIGHTMAREDROP},
+        {"pvp_nocalcrank", MapFlag::PVP_NOCALCRANK},
+        //{"gvg", MapFlag::GVG},
+        //{"gvg_noparty", MapFlag::GVG_NOPARTY},
+        //{"nozenypenalty", MapFlag::NOZENYPENALTY},
+        //{"notrade", MapFlag::NOTRADE},
+        //{"noskill", MapFlag::NOSKILL},
+        {"nowarp", MapFlag::NOWARP},
+        {"nowarpto", MapFlag::NOWARPTO},
+        {"nopvp", MapFlag::NOPVP},
+        //{"noicewall", MapFlag::NOICEWALL},
+        {"snow", MapFlag::SNOW},
+        {"fog", MapFlag::FOG},
+        {"sakura", MapFlag::SAKURA},
+        {"leaves", MapFlag::LEAVES},
+        {"rain", MapFlag::RAIN},
+        {"no_player_drops", MapFlag::NO_PLAYER_DROPS},
+        {"town", MapFlag::TOWN},
+    };
+    for (auto& pair : flags)
+        if (str == pair.str)
+        {
+            *mf = pair.id;
+            return true;
+        }
+    return false;
+}
diff --git a/src/map/mapflag.hpp b/src/map/mapflag.hpp
new file mode 100644
index 0000000..0905492
--- /dev/null
+++ b/src/map/mapflag.hpp
@@ -0,0 +1,98 @@
+#ifndef TMWA_MAP_MAPFLAG_HPP
+#define TMWA_MAP_MAPFLAG_HPP
+//    mapflag.hpp - booleans that apply to an entire map
+//
+//    Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
+//
+//    This file is part of The Mana World (Athena server)
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# include "../sanity.hpp"
+
+# include "../common/extract.hpp" // TODO remove this (requires specializing the *other* half)
+
+# include "../strings/xstring.hpp"
+
+// originally from script.cpp
+// These are part of the script API, so they can't change ever,
+// even though they are silly.
+// Hm, I guess if I did them builtin instead of loading from const.txt ...
+enum class MapFlag
+{
+    //ALIAS = 21,
+    //NOMEMO = 0,
+    NOTELEPORT = 1,
+    NORETURN = 22,
+    MONSTER_NOTELEPORT = 23,
+    NOSAVE = 2,
+    //NOBRANCH = 3,
+    NOPENALTY = 4,
+    PVP = 6,
+    PVP_NOPARTY = 7,
+    //PVP_NOGUILD = 8,
+    //PVP_NIGHTMAREDROP = 24,
+    PVP_NOCALCRANK = 25,
+    //GVG = 9,
+    //GVG_NOPARTY = 10,
+    //NOZENYPENALTY = 5,
+    //NOTRADE = 11,
+    //NOSKILL = 12,
+    NOWARP = 13,
+    NOWARPTO = 26,
+    NOPVP = 14,
+    //NOICEWALL = 15,
+    SNOW = 16,
+    FOG = 17,
+    SAKURA = 18,
+    LEAVES = 19,
+    RAIN = 20,
+    NO_PLAYER_DROPS = 27,
+    TOWN = 28,
+
+    COUNT = 29,
+};
+
+
+class MapFlags
+{
+public:
+    unsigned noteleport:1;
+    unsigned noreturn:1;
+    unsigned monster_noteleport:1;
+    unsigned nosave:1;
+    unsigned nopenalty:1;
+    unsigned pvp:1;
+    unsigned pvp_noparty:1;
+    unsigned pvp_nocalcrank:1;
+    unsigned nowarp:1;
+    unsigned nowarpto:1;
+    unsigned nopvp:1;       // [Valaris]
+    unsigned snow:1;        // [Valaris]
+    unsigned fog:1;         // [Valaris]
+    unsigned sakura:1;      // [Valaris]
+    unsigned leaves:1;      // [Valaris]
+    unsigned rain:1;        // [Valaris]
+    unsigned no_player_drops:1; // [Jaxad0127]
+    unsigned town:1;        // [remoitnane]
+public:
+    bool get(MapFlag) const;
+    void set(MapFlag, bool);
+};
+
+template<>
+bool extract<MapFlag, void, void>(XString str, MapFlag *mf);
+
+#endif // TMWA_MAP_MAPFLAG_HPP
+
diff --git a/src/map/npc.cpp b/src/map/npc.cpp
index 788d785..a939c74 100644
--- a/src/map/npc.cpp
+++ b/src/map/npc.cpp
@@ -1526,7 +1526,18 @@ int npc_parse_mapflag(XString w1, XString, XString w3, ZString w4)
     if (m == nullptr)
         return 1;
 
-    if (w3 == "nosave")
+    MapFlag mf;
+    if (!extract(w3, &mf))
+        return 1;
+
+    if (battle_config.pk_mode && mf == MapFlag::NOPVP)
+    {
+        m->flag.nopvp = 1;
+        m->flag.pvp = 0;
+        return 0;
+    }
+
+    if (mf == MapFlag::NOSAVE)
     {
         if (w4 == "SavePoint")
         {
@@ -1540,97 +1551,8 @@ int npc_parse_mapflag(XString w1, XString, XString w3, ZString w4)
             m->save.x = savex;
             m->save.y = savey;
         }
-        m->flag.nosave = 1;
-    }
-    else if (w3 == "nomemo")
-    {
-        m->flag.nomemo = 1;
-    }
-    else if (w3 == "noteleport")
-    {
-        m->flag.noteleport = 1;
-    }
-    else if (w3 == "nowarp")
-    {
-        m->flag.nowarp = 1;
-    }
-    else if (w3 == "nowarpto")
-    {
-        m->flag.nowarpto = 1;
-    }
-    else if (w3 == "noreturn")
-    {
-        m->flag.noreturn = 1;
-    }
-    else if (w3 == "monster_noteleport")
-    {
-        m->flag.monster_noteleport = 1;
-    }
-    else if (w3 == "nobranch")
-    {
-        m->flag.nobranch = 1;
-    }
-    else if (w3 == "nopenalty")
-    {
-        m->flag.nopenalty = 1;
-    }
-    else if (w3 == "pvp")
-    {
-        m->flag.pvp = 1;
-    }
-    else if (w3 == "pvp_noparty")
-    {
-        m->flag.pvp_noparty = 1;
-    }
-    else if (w3 == "pvp_nocalcrank")
-    {
-        m->flag.pvp_nocalcrank = 1;
-    }
-    else if (w3 == "nozenypenalty")
-    {
-        m->flag.nozenypenalty = 1;
-    }
-    else if (w3 == "notrade")
-    {
-        m->flag.notrade = 1;
-    }
-    else if (battle_config.pk_mode && w3 == "nopvp")
-    {                           // nopvp for pk mode [Valaris]
-        m->flag.nopvp = 1;
-        m->flag.pvp = 0;
-    }
-    else if (w3 == "noicewall")
-    {                           // noicewall [Valaris]
-        m->flag.noicewall = 1;
-    }
-    else if (w3 == "snow")
-    {                           // snow [Valaris]
-        m->flag.snow = 1;
-    }
-    else if (w3 == "fog")
-    {                           // fog [Valaris]
-        m->flag.fog = 1;
-    }
-    else if (w3 == "sakura")
-    {                           // sakura [Valaris]
-        m->flag.sakura = 1;
-    }
-    else if (w3 == "leaves")
-    {                           // leaves [Valaris]
-        m->flag.leaves = 1;
-    }
-    else if (w3 == "rain")
-    {                           // rain [Valaris]
-        m->flag.rain = 1;
-    }
-    else if (w3 == "no_player_drops")
-    {                           // no player drops [Jaxad0127]
-        m->flag.no_player_drops = 1;
-    }
-    else if (w3 == "town")
-    {                           // town/safe zone [remoitnane]
-        m->flag.town = 1;
     }
+    m->flag.set(mf, true);
 
     return 0;
 }
diff --git a/src/map/script.cpp b/src/map/script.cpp
index 36ceb8c..74f437a 100644
--- a/src/map/script.cpp
+++ b/src/map/script.cpp
@@ -3145,93 +3145,17 @@ void builtin_isloggedin(ScriptState *st)
                           &AARGO2(2))) != NULL);
 }
 
-/*==========================================
- *
- *------------------------------------------
- */
-enum
-{
-    MF_NOMEMO = 0,
-    MF_NOTELEPORT = 1,
-    MF_NOSAVE = 2,
-    MF_NOBRANCH = 3,
-    MF_NOPENALTY = 4,
-    MF_NOZENYPENALTY = 5,
-    MF_PVP = 6,
-    MF_PVP_NOPARTY = 7,
-    //MF_PVP_NOGUILD = 8,
-    //MF_GVG = 9,
-    //MF_GVG_NOPARTY = 10,
-    MF_NOTRADE = 11,
-    //MF_NOSKILL = 12,
-    MF_NOWARP = 13,
-    MF_NOPVP = 14,
-    MF_NOICEWALL = 15,
-    MF_SNOW = 16,
-    MF_FOG = 17,
-    MF_SAKURA = 18,
-    MF_LEAVES = 19,
-    MF_RAIN = 20,
-};
-
 static
 void builtin_setmapflag(ScriptState *st)
 {
     MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2))));
     int i = conv_num(st, &AARGO2(3));
+    MapFlag mf = static_cast<MapFlag>(i);
     map_local *m = map_mapname2mapid(str);
     if (m != nullptr)
     {
-        switch (i)
-        {
-            case MF_NOMEMO:
-                m->flag.nomemo = 1;
-                break;
-            case MF_NOTELEPORT:
-                m->flag.noteleport = 1;
-                break;
-            case MF_NOBRANCH:
-                m->flag.nobranch = 1;
-                break;
-            case MF_NOPENALTY:
-                m->flag.nopenalty = 1;
-                break;
-            case MF_PVP_NOPARTY:
-                m->flag.pvp_noparty = 1;
-                break;
-            case MF_NOZENYPENALTY:
-                m->flag.nozenypenalty = 1;
-                break;
-            case MF_NOTRADE:
-                m->flag.notrade = 1;
-                break;
-            case MF_NOWARP:
-                m->flag.nowarp = 1;
-                break;
-            case MF_NOPVP:
-                m->flag.nopvp = 1;
-                break;
-            case MF_NOICEWALL: // [Valaris]
-                m->flag.noicewall = 1;
-                break;
-            case MF_SNOW:      // [Valaris]
-                m->flag.snow = 1;
-                break;
-            case MF_FOG:       // [Valaris]
-                m->flag.fog = 1;
-                break;
-            case MF_SAKURA:    // [Valaris]
-                m->flag.sakura = 1;
-                break;
-            case MF_LEAVES:    // [Valaris]
-                m->flag.leaves = 1;
-                break;
-            case MF_RAIN:      // [Valaris]
-                m->flag.rain = 1;
-                break;
-        }
+        m->flag.set(mf, 1);
     }
-
 }
 
 static
@@ -3239,57 +3163,11 @@ void builtin_removemapflag(ScriptState *st)
 {
     MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2))));
     int i = conv_num(st, &AARGO2(3));
+    MapFlag mf = static_cast<MapFlag>(i);
     map_local *m = map_mapname2mapid(str);
     if (m != nullptr)
     {
-        switch (i)
-        {
-            case MF_NOMEMO:
-                m->flag.nomemo = 0;
-                break;
-            case MF_NOTELEPORT:
-                m->flag.noteleport = 0;
-                break;
-            case MF_NOSAVE:
-                m->flag.nosave = 0;
-                break;
-            case MF_NOBRANCH:
-                m->flag.nobranch = 0;
-                break;
-            case MF_NOPENALTY:
-                m->flag.nopenalty = 0;
-                break;
-            case MF_PVP_NOPARTY:
-                m->flag.pvp_noparty = 0;
-                break;
-            case MF_NOZENYPENALTY:
-                m->flag.nozenypenalty = 0;
-                break;
-            case MF_NOWARP:
-                m->flag.nowarp = 0;
-                break;
-            case MF_NOPVP:
-                m->flag.nopvp = 0;
-                break;
-            case MF_NOICEWALL: // [Valaris]
-                m->flag.noicewall = 0;
-                break;
-            case MF_SNOW:      // [Valaris]
-                m->flag.snow = 0;
-                break;
-            case MF_FOG:       // [Valaris]
-                m->flag.fog = 0;
-                break;
-            case MF_SAKURA:    // [Valaris]
-                m->flag.sakura = 0;
-                break;
-            case MF_LEAVES:    // [Valaris]
-                m->flag.leaves = 0;
-                break;
-            case MF_RAIN:      // [Valaris]
-                m->flag.rain = 0;
-                break;
-        }
+        m->flag.set(mf, 0);
     }
 }
 
@@ -3300,57 +3178,11 @@ void builtin_getmapflag(ScriptState *st)
 
     MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2))));
     int i = conv_num(st, &AARGO2(3));
+    MapFlag mf = static_cast<MapFlag>(i);
     map_local *m = map_mapname2mapid(str);
     if (m != nullptr)
     {
-        switch (i)
-        {
-            case MF_NOMEMO:
-                r = m->flag.nomemo;
-                break;
-            case MF_NOTELEPORT:
-                r = m->flag.noteleport;
-                break;
-            case MF_NOSAVE:
-                r = m->flag.nosave;
-                break;
-            case MF_NOBRANCH:
-                r = m->flag.nobranch;
-                break;
-            case MF_NOPENALTY:
-                r = m->flag.nopenalty;
-                break;
-            case MF_PVP_NOPARTY:
-                r = m->flag.pvp_noparty;
-                break;
-            case MF_NOZENYPENALTY:
-                r = m->flag.nozenypenalty;
-                break;
-            case MF_NOWARP:
-                r = m->flag.nowarp;
-                break;
-            case MF_NOPVP:
-                r = m->flag.nopvp;
-                break;
-            case MF_NOICEWALL: // [Valaris]
-                r = m->flag.noicewall;
-                break;
-            case MF_SNOW:      // [Valaris]
-                r = m->flag.snow;
-                break;
-            case MF_FOG:       // [Valaris]
-                r = m->flag.fog;
-                break;
-            case MF_SAKURA:    // [Valaris]
-                r = m->flag.sakura;
-                break;
-            case MF_LEAVES:    // [Valaris]
-                r = m->flag.leaves;
-                break;
-            case MF_RAIN:      // [Valaris]
-                r = m->flag.rain;
-                break;
-        }
+        r = m->flag.get(mf);
     }
 
     push_int(st->stack, ByteCode::INT, r);
-- 
cgit v1.2.3-70-g09d2