From 2b092c150e1226decc48160316070fc44d5fbba0 Mon Sep 17 00:00:00 2001
From: Ben Longbons <b.r.longbons@gmail.com>
Date: Thu, 20 Dec 2012 18:32:32 -0800
Subject: Enumify option, opt1, opt2, and opt3

---
 src/char/char.cpp      |   6 +-
 src/common/mmo.hpp     |   6 +-
 src/common/utils2.hpp  |  40 ++++++++++
 src/map/atcommand.cpp  |  63 +++++++++-------
 src/map/battle.cpp     |  13 ++--
 src/map/battle.hpp     |   9 ++-
 src/map/chrif.cpp      |   2 +-
 src/map/clif.cpp       | 127 ++++++++++++++++---------------
 src/map/magic-expr.cpp |   4 +-
 src/map/magic.cpp      |   2 +-
 src/map/map.hpp        |  32 ++++----
 src/map/map.t.hpp      |  91 +++++++++++++++++++++++
 src/map/mob.cpp        |  55 ++++++++------
 src/map/npc.cpp        |  28 +++----
 src/map/pc.cpp         |  61 +++++++--------
 src/map/pc.hpp         |  85 ++++++++++++++++-----
 src/map/script.cpp     |  14 ++--
 src/map/skill.cpp      | 197 +++++++++++++++++++++++++++----------------------
 18 files changed, 531 insertions(+), 304 deletions(-)
 create mode 100644 src/map/map.t.hpp

(limited to 'src')

diff --git a/src/char/char.cpp b/src/char/char.cpp
index 4091b7d..899461a 100644
--- a/src/char/char.cpp
+++ b/src/char/char.cpp
@@ -360,7 +360,7 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p)
     p->luk = tmp_int[18];
     p->status_point = tmp_int[19];
     p->skill_point = tmp_int[20];
-    p->option = tmp_int[21];
+    p->option = Option(tmp_int[21]);
     p->karma = tmp_int[22];
     p->manner = tmp_int[23];
     p->party_id = tmp_int[24];
@@ -966,7 +966,7 @@ int make_new_char(int fd, unsigned char *dat)
     char_dat[i].sp = char_dat[i].max_sp;
     char_dat[i].status_point = 0;
     char_dat[i].skill_point = 0;
-    char_dat[i].option = 0;
+    char_dat[i].option = Option(0x0000);
     char_dat[i].karma = 0;
     char_dat[i].manner = 0;
     char_dat[i].party_id = 0;
@@ -1577,7 +1577,7 @@ int mmo_char_send006b(int fd, struct char_session_data *sd)
         WFIFOW(fd, j + 22) = find_equip_view(p, 0x0004);  // 10: gloves
         WFIFOW(fd, j + 24) = find_equip_view(p, 0x0008);  // 11: cape
         WFIFOW(fd, j + 26) = find_equip_view(p, 0x0010);  // 12: misc1
-        WFIFOL(fd, j + 28) = p->option;
+        WFIFOL(fd, j + 28) = uint16_t(p->option);
 
         WFIFOL(fd, j + 32) = p->karma;
         WFIFOL(fd, j + 36) = p->manner;
diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp
index 178247c..8489ef1 100644
--- a/src/common/mmo.hpp
+++ b/src/common/mmo.hpp
@@ -82,6 +82,9 @@ struct global_reg
     int value;
 };
 
+// Option and Opt1..3 in map.hpp
+enum class Option : uint16_t;
+
 struct mmo_charstatus
 {
     int char_id;
@@ -93,7 +96,8 @@ struct mmo_charstatus
     short pc_class;
     short status_point, skill_point;
     int hp, max_hp, sp, max_sp;
-    short option, karma, manner;
+    Option option;
+    short karma, manner;
     short hair, hair_color, clothes_color;
     int party_id;
 
diff --git a/src/common/utils2.hpp b/src/common/utils2.hpp
index c92fdae..326b12f 100644
--- a/src/common/utils2.hpp
+++ b/src/common/utils2.hpp
@@ -93,6 +93,46 @@ struct underlying_type
     >::type type;
 };
 
+#define ENUM_BITWISE_OPERATORS(E)               \
+inline                                          \
+E operator & (E l, E r)                         \
+{                                               \
+    typedef typename underlying_type<E>::type U;\
+    return E(U(l) & U(r));                      \
+}                                               \
+inline                                          \
+E operator | (E l, E r)                         \
+{                                               \
+    typedef typename underlying_type<E>::type U;\
+    return E(U(l) | U(r));                      \
+}                                               \
+inline                                          \
+E operator ^ (E l, E r)                         \
+{                                               \
+    typedef typename underlying_type<E>::type U;\
+    return E(U(l) ^ U(r));                      \
+}                                               \
+inline                                          \
+E& operator &= (E& l, E r)                      \
+{                                               \
+    return l = l & r;                           \
+}                                               \
+inline                                          \
+E& operator |= (E& l, E r)                      \
+{                                               \
+    return l = l | r;                           \
+}                                               \
+inline                                          \
+E& operator ^= (E& l, E r)                      \
+{                                               \
+    return l = l ^ r;                           \
+}                                               \
+inline                                          \
+E operator ~ (E r)                              \
+{                                               \
+    return E(-1) ^ r;                           \
+}
+
 template<class E>
 class EnumValueIterator
 {
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp
index 67cc51d..f38c62a 100644
--- a/src/map/atcommand.cpp
+++ b/src/map/atcommand.cpp
@@ -37,8 +37,6 @@
 #include "tmw.hpp"
 #include "trade.hpp"
 
-#define STATE_BLIND 0x10
-
 static
 char command_symbol = '@';   // first char of the commands (by [Yor])
 
@@ -1041,7 +1039,7 @@ int atcommand_where(const int fd, struct map_session_data *sd,
 
     if ((pl_sd = map_nick2sd(character)) != NULL &&
         !((battle_config.hide_GM_session
-           || (pl_sd->status.option & OPTION_HIDE))
+           || bool(pl_sd->status.option & Option::HIDE))
           && (pc_isGM(pl_sd) > pc_isGM(sd))))
     {                           // you can look only lower or same level
         sprintf(output, "%s: %s (%d,%d)", pl_sd->status.name, pl_sd->mapname,
@@ -1187,7 +1185,7 @@ int atcommand_who(const int fd, struct map_session_data *sd,
             pl_GM_level = pc_isGM(pl_sd);
             if (!
                 ((battle_config.hide_GM_session
-                  || (pl_sd->status.option & OPTION_HIDE))
+                  || bool(pl_sd->status.option & Option::HIDE))
                  && (pl_GM_level > GM_level)))
             {                   // you can look only lower or same level
                 memcpy(player_name, pl_sd->status.name, 24);
@@ -1262,7 +1260,7 @@ int atcommand_whogroup(const int fd, struct map_session_data *sd,
             pl_GM_level = pc_isGM(pl_sd);
             if (!
                 ((battle_config.hide_GM_session
-                  || (pl_sd->status.option & OPTION_HIDE))
+                  || bool(pl_sd->status.option & Option::HIDE))
                  && (pl_GM_level > GM_level)))
             {                   // you can look only lower or same level
                 memcpy(player_name, pl_sd->status.name, 24);
@@ -1341,7 +1339,7 @@ int atcommand_whomap(const int fd, struct map_session_data *sd,
             pl_GM_level = pc_isGM(pl_sd);
             if (!
                 ((battle_config.hide_GM_session
-                  || (pl_sd->status.option & OPTION_HIDE))
+                  || bool(pl_sd->status.option & Option::HIDE))
                  && (pl_GM_level > GM_level)))
             {                   // you can look only lower or same level
                 if (pl_sd->bl.m == map_id)
@@ -1416,7 +1414,7 @@ int atcommand_whomapgroup(const int fd, struct map_session_data *sd,
             pl_GM_level = pc_isGM(pl_sd);
             if (!
                 ((battle_config.hide_GM_session
-                  || (pl_sd->status.option & OPTION_HIDE))
+                  || bool(pl_sd->status.option & Option::HIDE))
                  && (pl_GM_level > GM_level)))
             {
                 // you can look only lower or same level
@@ -1493,7 +1491,7 @@ int atcommand_whogm(const int fd, struct map_session_data *sd,
             {
                 if (!
                     ((battle_config.hide_GM_session
-                      || (pl_sd->status.option & OPTION_HIDE))
+                      || bool(pl_sd->status.option & Option::HIDE))
                      && (pl_GM_level > GM_level)))
                 {               // you can look only lower or same level
                     memcpy(player_name, pl_sd->status.name, 24);
@@ -1666,21 +1664,26 @@ int atcommand_storage(const int fd, struct map_session_data *sd,
 int atcommand_option(const int fd, struct map_session_data *sd,
                       const char *, const char *message)
 {
-    int param1 = 0, param2 = 0, param3 = 0;
+    int param1_ = 0, param2_ = 0, param3_ = 0;
     nullpo_retr(-1, sd);
 
     if (!message || !*message
-        || sscanf(message, "%d %d %d", &param1, &param2, &param3) < 1
-        || param1 < 0 || param2 < 0 || param3 < 0)
+        || sscanf(message, "%d %d %d", &param1_, &param2_, &param3_) < 1
+        || param1_ < 0 || param2_ < 0 || param3_ < 0)
     {
         clif_displaymessage(fd,
                              "Please, enter at least a option (usage: @option <param1:0+> <param2:0+> <param3:0+>).");
         return -1;
     }
 
+    Opt1 param1 = Opt1(param1_);
+    Opt2 param2 = Opt2(param2_);
+    Option param3 = Option(param3_);
+
     sd->opt1 = param1;
     sd->opt2 = param2;
-    if (!(sd->status.option & CART_MASK) && param3 & CART_MASK)
+    if (!bool(sd->status.option & Option::CART_MASK)
+        && bool(param3 & Option::CART_MASK))
     {
         clif_cart_itemlist(sd);
         clif_cart_equiplist(sd);
@@ -1709,7 +1712,7 @@ int atcommand_option(const int fd, struct map_session_data *sd,
         {                       // sd have the new value...
             if (sd->disguise > 0)
             {                   // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] (code added by [Yor])
-                sd->status.option &= ~0x0020;
+                sd->status.option &= ~Option::RIDING;
             }
             else
             {
@@ -1722,7 +1725,7 @@ int atcommand_option(const int fd, struct map_session_data *sd,
                 else if (sd->status.pc_class == 4015)
                     sd->status.pc_class = sd->view_class = 4022;
                 else
-                    sd->status.option &= ~0x0020;
+                    sd->status.option &= ~Option::RIDING;
             }
         }
     }
@@ -1741,14 +1744,14 @@ int atcommand_option(const int fd, struct map_session_data *sd,
 int atcommand_hide(const int fd, struct map_session_data *sd,
                     const char *, const char *)
 {
-    if (sd->status.option & OPTION_HIDE)
+    if (bool(sd->status.option & Option::HIDE))
     {
-        sd->status.option &= ~OPTION_HIDE;
+        sd->status.option &= ~Option::HIDE;
         clif_displaymessage(fd, "Invisible: Off.");    // Invisible: Off
     }
     else
     {
-        sd->status.option |= OPTION_HIDE;
+        sd->status.option |= Option::HIDE;
         clif_displaymessage(fd, "Invisible: On.");    // Invisible: On
     }
     clif_changeoption(&sd->bl);
@@ -3572,20 +3575,24 @@ int atcommand_character_option(const int fd, struct map_session_data *sd,
                                 const char *, const char *message)
 {
     char character[100];
-    int opt1 = 0, opt2 = 0, opt3 = 0;
+    int opt1_ = 0, opt2_ = 0, opt3_ = 0;
     struct map_session_data *pl_sd;
 
     memset(character, '\0', sizeof(character));
 
     if (!message || !*message
-        || sscanf(message, "%d %d %d %99[^\n]", &opt1, &opt2, &opt3,
-                   character) < 4 || opt1 < 0 || opt2 < 0 || opt3 < 0)
+        || sscanf(message, "%d %d %d %99[^\n]", &opt1_, &opt2_, &opt3_,
+                   character) < 4 || opt1_ < 0 || opt2_ < 0 || opt3_ < 0)
     {
         clif_displaymessage(fd,
                              "Please, enter valid options and a player name (usage: @charoption <param1> <param2> <param3> <charname>).");
         return -1;
     }
 
+    Opt1 opt1 = Opt1(opt1_);
+    Opt2 opt2 = Opt2(opt2_);
+    Option opt3 = Option(opt3_);
+
     if ((pl_sd = map_nick2sd(character)) != NULL)
     {
         if (pc_isGM(sd) >= pc_isGM(pl_sd))
@@ -3615,7 +3622,7 @@ int atcommand_character_option(const int fd, struct map_session_data *sd,
                 {               // pl_sd have the new value...
                     if (pl_sd->disguise > 0)
                     {           // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris] (code added by [Yor])
-                        pl_sd->status.option &= ~0x0020;
+                        pl_sd->status.option &= ~Option::RIDING;
                     }
                     else
                     {
@@ -3628,7 +3635,7 @@ int atcommand_character_option(const int fd, struct map_session_data *sd,
                         else if (pl_sd->status.pc_class == 4015)
                             pl_sd->status.pc_class = pl_sd->view_class = 4022;
                         else
-                            pl_sd->status.option &= ~0x0020;
+                            pl_sd->status.option &= ~Option::RIDING;
                     }
                 }
             }
@@ -4003,7 +4010,7 @@ int atcommand_night(const int fd, struct map_session_data *,
             if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
                 && pl_sd->state.auth)
             {
-                pl_sd->opt2 |= STATE_BLIND;
+                pl_sd->opt2 |= Opt2::BLIND;
                 clif_changeoption(&pl_sd->bl);
                 clif_displaymessage(pl_sd->fd, "Night has fallen.");
             }
@@ -4036,7 +4043,7 @@ int atcommand_day(const int fd, struct map_session_data *,
             if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
                 && pl_sd->state.auth)
             {
-                pl_sd->opt2 &= ~STATE_BLIND;
+                pl_sd->opt2 &= ~Opt2::BLIND;
                 clif_changeoption(&pl_sd->bl);
                 clif_displaymessage(pl_sd->fd, "Day has arrived.");
             }
@@ -5591,7 +5598,7 @@ int atcommand_mount_peco(const int fd, struct map_session_data *sd,
                 sd->status.pc_class = sd->view_class = 4014;
             else if (sd->status.pc_class == 4015)
                 sd->status.pc_class = sd->view_class = 4022;
-            pc_setoption(sd, sd->status.option | 0x0020);
+            pc_setoption(sd, sd->status.option | Option::RIDING);
             clif_displaymessage(fd, "Mounted Peco.");
         }
         else
@@ -5610,7 +5617,7 @@ int atcommand_mount_peco(const int fd, struct map_session_data *sd,
             sd->status.pc_class = sd->view_class = 4008;
         else if (sd->status.pc_class == 4022)
             sd->status.pc_class = sd->view_class = 4015;
-        pc_setoption(sd, sd->status.option & ~0x0020);
+        pc_setoption(sd, sd->status.option & ~Option::RIDING);
         clif_displaymessage(fd, "Unmounted Peco.");
     }
 
@@ -5657,7 +5664,7 @@ int atcommand_char_mount_peco(const int fd, struct map_session_data *,
                     pl_sd->status.pc_class = pl_sd->view_class = 4014;
                 else if (pl_sd->status.pc_class == 4015)
                     pl_sd->status.pc_class = pl_sd->view_class = 4022;
-                pc_setoption(pl_sd, pl_sd->status.option | 0x0020);
+                pc_setoption(pl_sd, pl_sd->status.option | Option::RIDING);
                 clif_displaymessage(fd, "Now, this player mounts a peco.");
             }
             else
@@ -5676,7 +5683,7 @@ int atcommand_char_mount_peco(const int fd, struct map_session_data *,
                 pl_sd->status.pc_class = pl_sd->view_class = 4008;
             else if (pl_sd->status.pc_class == 4022)
                 pl_sd->status.pc_class = pl_sd->view_class = 4015;
-            pc_setoption(pl_sd, pl_sd->status.option & ~0x0020);
+            pc_setoption(pl_sd, pl_sd->status.option & ~Option::RIDING);
             clif_displaymessage(fd, "Now, this player has not more peco.");
         }
     }
diff --git a/src/map/battle.cpp b/src/map/battle.cpp
index 14ef933..d76abd5 100644
--- a/src/map/battle.cpp
+++ b/src/map/battle.cpp
@@ -1361,7 +1361,7 @@ short *battle_get_sc_count(struct block_list *bl)
     return NULL;
 }
 
-short *battle_get_opt1(struct block_list *bl)
+Opt1 *battle_get_opt1(struct block_list *bl)
 {
     nullpo_retr(0, bl);
     if (bl->type == BL_MOB && (struct mob_data *) bl)
@@ -1373,7 +1373,7 @@ short *battle_get_opt1(struct block_list *bl)
     return 0;
 }
 
-short *battle_get_opt2(struct block_list *bl)
+Opt2 *battle_get_opt2(struct block_list *bl)
 {
     nullpo_retr(0, bl);
     if (bl->type == BL_MOB && (struct mob_data *) bl)
@@ -1385,7 +1385,7 @@ short *battle_get_opt2(struct block_list *bl)
     return 0;
 }
 
-short *battle_get_opt3(struct block_list *bl)
+Opt3 *battle_get_opt3(struct block_list *bl)
 {
     nullpo_retr(0, bl);
     if (bl->type == BL_MOB && (struct mob_data *) bl)
@@ -1397,7 +1397,7 @@ short *battle_get_opt3(struct block_list *bl)
     return 0;
 }
 
-short *battle_get_option(struct block_list *bl)
+Option *battle_get_option(struct block_list *bl)
 {
     nullpo_retr(0, bl);
     if (bl->type == BL_MOB && (struct mob_data *) bl)
@@ -4633,7 +4633,6 @@ int battle_weapon_attack(struct block_list *src, struct block_list *target,
     struct map_session_data *sd = NULL;
     eptr<struct status_change, StatusChange> sc_data = battle_get_sc_data(src);
     eptr<struct status_change, StatusChange> t_sc_data = battle_get_sc_data(target);
-    short *opt1;
     int race = 7, ele = 0;
     int damage, rdamage = 0;
     struct Damage wd;
@@ -4652,8 +4651,8 @@ int battle_weapon_attack(struct block_list *src, struct block_list *target,
         && pc_isdead((struct map_session_data *) target))
         return 0;
 
-    opt1 = battle_get_opt1(src);
-    if (opt1 && *opt1 > 0)
+    Opt1 *opt1 = battle_get_opt1(src);
+    if (opt1 != NULL && bool(*opt1))
     {
         battle_stopattack(src);
         return 0;
diff --git a/src/map/battle.hpp b/src/map/battle.hpp
index aa4dd91..b268616 100644
--- a/src/map/battle.hpp
+++ b/src/map/battle.hpp
@@ -3,6 +3,7 @@
 
 #include "../common/utils.hpp"
 
+#include "map.t.hpp"
 #include "skill.t.hpp"
 
 // ダメージ
@@ -119,10 +120,10 @@ int battle_get_stat(int stat_id /* SP_VIT or similar */ ,
 
 eptr<struct status_change, StatusChange> battle_get_sc_data(struct block_list *bl);
 short *battle_get_sc_count(struct block_list *bl);
-short *battle_get_opt1(struct block_list *bl);
-short *battle_get_opt2(struct block_list *bl);
-short *battle_get_opt3(struct block_list *bl);
-short *battle_get_option(struct block_list *bl);
+Opt1 *battle_get_opt1(struct block_list *bl);
+Opt2 *battle_get_opt2(struct block_list *bl);
+Opt3 *battle_get_opt3(struct block_list *bl);
+Option *battle_get_option(struct block_list *bl);
 
 enum
 {
diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp
index 6f5278e..ba295c3 100644
--- a/src/map/chrif.cpp
+++ b/src/map/chrif.cpp
@@ -1269,7 +1269,7 @@ void send_users_tochar(timer_id, tick_t, custom_id_t, custom_data_t)
         if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) && sd->state.auth &&
             !((battle_config.hide_GM_session
                || sd->state.shroud_active
-               || (sd->status.option & OPTION_HIDE)) && pc_isGM(sd)))
+               || bool(sd->status.option & Option::HIDE)) && pc_isGM(sd)))
         {
             WFIFOL(char_fd, 6 + 4 * users) = sd->status.char_id;
             users++;
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index a5d756a..4a065fa 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -8,7 +8,6 @@
 #include <unistd.h>
 
 #include <cctype>
-#include <stdarg.h> // needs justification for <cstdarg>
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
@@ -41,7 +40,6 @@
 
 #define DUMP_UNKNOWN_PACKET     1
 
-#define STATE_BLIND 0x10
 #define EMOTE_IGNORED 0x0e
 
 static
@@ -298,7 +296,7 @@ int clif_send(const uint8_t *buf, int len, struct block_list *bl, int type)
         if (bl->type == BL_PC)
         {
             struct map_session_data *sd2 = (struct map_session_data *) bl;
-            if (sd2->status.option & OPTION_INVISIBILITY)
+            if (bool(sd2->status.option & Option::INVISIBILITY))
             {
                 // Obscure hidden GMs
 
@@ -707,9 +705,9 @@ int clif_set0078(struct map_session_data *sd, unsigned char *buf)
         WBUFW(buf, 0) = 0x78;
         WBUFL(buf, 2) = sd->bl.id;
         WBUFW(buf, 6) = battle_get_speed(&sd->bl);
-        WBUFW(buf, 8) = sd->opt1;
-        WBUFW(buf, 10) = sd->opt2;
-        WBUFW(buf, 12) = sd->status.option;
+        WBUFW(buf, 8) = uint16_t(sd->opt1);
+        WBUFW(buf, 10) = uint16_t(sd->opt2);
+        WBUFW(buf, 12) = uint16_t(sd->status.option);
         WBUFW(buf, 14) = sd->disguise;
         WBUFW(buf, 42) = 0;
         WBUFB(buf, 44) = 0;
@@ -729,9 +727,9 @@ int clif_set0078(struct map_session_data *sd, unsigned char *buf)
     WBUFW(buf, 0) = 0x1d8;
     WBUFL(buf, 2) = sd->bl.id;
     WBUFW(buf, 6) = sd->speed;
-    WBUFW(buf, 8) = sd->opt1;
-    WBUFW(buf, 10) = sd->opt2;
-    WBUFW(buf, 12) = sd->status.option;
+    WBUFW(buf, 8) = uint16_t(sd->opt1);
+    WBUFW(buf, 10) = uint16_t(sd->opt2);
+    WBUFW(buf, 12) = uint16_t(sd->status.option);
     WBUFW(buf, 14) = sd->view_class;
     WBUFW(buf, 16) = sd->status.hair;
     if (sd->attack_spell_override)
@@ -770,7 +768,7 @@ int clif_set0078(struct map_session_data *sd, unsigned char *buf)
     WBUFL(buf, 34) = 0 /*guild_id*/;
     WBUFW(buf, 38) = 0 /*guild_emblem_id*/;
     WBUFW(buf, 40) = sd->status.manner;
-    WBUFW(buf, 42) = sd->opt3;
+    WBUFW(buf, 42) = uint16_t(sd->opt3);
     WBUFB(buf, 44) = sd->status.karma;
     WBUFB(buf, 45) = sd->sex;
     WBUFPOS(buf, 46, sd->bl.x, sd->bl.y);
@@ -797,9 +795,9 @@ int clif_set007b(struct map_session_data *sd, unsigned char *buf)
         WBUFW(buf, 0) = 0x7b;
         WBUFL(buf, 2) = sd->bl.id;
         WBUFW(buf, 6) = battle_get_speed(&sd->bl);
-        WBUFW(buf, 8) = sd->opt1;
-        WBUFW(buf, 10) = sd->opt2;
-        WBUFW(buf, 12) = sd->status.option;
+        WBUFW(buf, 8) = uint16_t(sd->opt1);
+        WBUFW(buf, 10) = uint16_t(sd->opt2);
+        WBUFW(buf, 12) = uint16_t(sd->status.option);
         WBUFW(buf, 14) = sd->disguise;
         WBUFL(buf, 22) = gettick();
         WBUFW(buf, 46) = 0;
@@ -819,9 +817,9 @@ int clif_set007b(struct map_session_data *sd, unsigned char *buf)
     WBUFW(buf, 0) = 0x1da;
     WBUFL(buf, 2) = sd->bl.id;
     WBUFW(buf, 6) = sd->speed;
-    WBUFW(buf, 8) = sd->opt1;
-    WBUFW(buf, 10) = sd->opt2;
-    WBUFW(buf, 12) = sd->status.option;
+    WBUFW(buf, 8) = uint16_t(sd->opt1);
+    WBUFW(buf, 10) = uint16_t(sd->opt2);
+    WBUFW(buf, 12) = uint16_t(sd->status.option);
     WBUFW(buf, 14) = sd->view_class;
     WBUFW(buf, 16) = sd->status.hair;
     if (sd->equip_index[9] >= 0 && sd->inventory_data[sd->equip_index[9]]
@@ -854,7 +852,7 @@ int clif_set007b(struct map_session_data *sd, unsigned char *buf)
     WBUFL(buf, 38) = 0/*guild_id*/;
     WBUFW(buf, 42) = 0/*guild_emblem_id*/;
     WBUFW(buf, 44) = sd->status.manner;
-    WBUFW(buf, 46) = sd->opt3;
+    WBUFW(buf, 46) = uint16_t(sd->opt3);
     WBUFB(buf, 48) = sd->status.karma;
     WBUFB(buf, 49) = sd->sex;
     WBUFPOS2(buf, 50, sd->bl.x, sd->bl.y, sd->to_x, sd->to_y);
@@ -946,9 +944,9 @@ int clif_mob0078(struct mob_data *md, unsigned char *buf)
     WBUFW(buf, 0) = 0x78;
     WBUFL(buf, 2) = md->bl.id;
     WBUFW(buf, 6) = battle_get_speed(&md->bl);
-    WBUFW(buf, 8) = md->opt1;
-    WBUFW(buf, 10) = md->opt2;
-    WBUFW(buf, 12) = md->option;
+    WBUFW(buf, 8) = uint16_t(md->opt1);
+    WBUFW(buf, 10) = uint16_t(md->opt2);
+    WBUFW(buf, 12) = uint16_t(md->option);
     WBUFW(buf, 14) = mob_get_viewclass(md->mob_class);
     if ((mob_get_viewclass(md->mob_class) <= 23)
         || (mob_get_viewclass(md->mob_class) == 812)
@@ -994,9 +992,9 @@ int clif_mob007b(struct mob_data *md, unsigned char *buf)
     WBUFW(buf, 0) = 0x7b;
     WBUFL(buf, 2) = md->bl.id;
     WBUFW(buf, 6) = battle_get_speed(&md->bl);
-    WBUFW(buf, 8) = md->opt1;
-    WBUFW(buf, 10) = md->opt2;
-    WBUFW(buf, 12) = md->option;
+    WBUFW(buf, 8) = uint16_t(md->opt1);
+    WBUFW(buf, 10) = uint16_t(md->opt2);
+    WBUFW(buf, 12) = uint16_t(md->option);
     WBUFW(buf, 14) = mob_get_viewclass(md->mob_class);
     if ((mob_get_viewclass(md->mob_class) < 24)
         || (mob_get_viewclass(md->mob_class) > 4000))
@@ -1132,9 +1130,9 @@ int clif_spawnpc(struct map_session_data *sd)
         WBUFW(buf, 0) = 0x7c;
         WBUFL(buf, 2) = sd->bl.id;
         WBUFW(buf, 6) = sd->speed;
-        WBUFW(buf, 8) = sd->opt1;
-        WBUFW(buf, 10) = sd->opt2;
-        WBUFW(buf, 12) = sd->status.option;
+        WBUFW(buf, 8) = uint16_t(sd->opt1);
+        WBUFW(buf, 10) = uint16_t(sd->opt2);
+        WBUFW(buf, 12) = uint16_t(sd->status.option);
         WBUFW(buf, 20) = sd->disguise;
         WBUFPOS(buf, 36, sd->bl.x, sd->bl.y);
         clif_send(buf, packet_len_table[0x7c], &sd->bl, AREA);
@@ -1151,7 +1149,7 @@ int clif_spawnpc(struct map_session_data *sd)
 
     if (sd->status.pc_class == 13 || sd->status.pc_class == 21
         || sd->status.pc_class == 4014 || sd->status.pc_class == 4022)
-        pc_setoption(sd, sd->status.option | 0x0020);  // [Valaris]
+        pc_setoption(sd, sd->status.option | Option::RIDING);  // [Valaris]
 
     if ((pc_isriding(sd) && pc_checkskill(sd, KN_RIDING) > 0)
         && (sd->status.pc_class == 7 || sd->status.pc_class == 14
@@ -1259,9 +1257,9 @@ int clif_spawnmob(struct mob_data *md)
         WBUFW(buf, 0) = 0x7c;
         WBUFL(buf, 2) = md->bl.id;
         WBUFW(buf, 6) = md->stats[MOB_SPEED];
-        WBUFW(buf, 8) = md->opt1;
-        WBUFW(buf, 10) = md->opt2;
-        WBUFW(buf, 12) = md->option;
+        WBUFW(buf, 8) = uint16_t(md->opt1);
+        WBUFW(buf, 10) = uint16_t(md->opt2);
+        WBUFW(buf, 12) = uint16_t(md->option);
         WBUFW(buf, 20) = mob_get_viewclass(md->mob_class);
         WBUFPOS(buf, 36, md->bl.x, md->bl.y);
         clif_send(buf, packet_len_table[0x7c], &md->bl, AREA);
@@ -2313,7 +2311,7 @@ int clif_changelook_towards(struct block_list *bl, int type, int val,
     if (sd && sd->disguise > 23 && sd->disguise < 4001) // mob disguises [Valaris]
         return 0;
 
-    if (sd && sd->status.option & OPTION_INVISIBILITY)
+    if (sd && bool(sd->status.option & Option::INVISIBILITY))
         return 0;
 
     if (sd
@@ -2586,22 +2584,21 @@ int clif_misceffect(struct block_list *bl, int type)
 int clif_changeoption(struct block_list *bl)
 {
     uint8_t buf[32];
-    short option;
     eptr<struct status_change, StatusChange> sc_data;
-    static const int omask[] = { 0x10, 0x20 };
+    static const Option omask[] = { Option::FALCON, Option::RIDING };
     static const StatusChange scnum[] = { SC_FALCON, SC_RIDING };
     int i;
 
     nullpo_retr(0, bl);
 
-    option = *battle_get_option(bl);
+    Option option = *battle_get_option(bl);
     sc_data = battle_get_sc_data(bl);
 
     WBUFW(buf, 0) = 0x119;
     WBUFL(buf, 2) = bl->id;
-    WBUFW(buf, 6) = *battle_get_opt1(bl);
-    WBUFW(buf, 8) = *battle_get_opt2(bl);
-    WBUFW(buf, 10) = option;
+    WBUFW(buf, 6) = uint16_t(*battle_get_opt1(bl));
+    WBUFW(buf, 8) = uint16_t(*battle_get_opt2(bl));
+    WBUFW(buf, 10) = uint16_t(option);
     WBUFB(buf, 12) = 0;        // ??
 
     if (bl->type == BL_PC)
@@ -2621,7 +2618,7 @@ int clif_changeoption(struct block_list *bl)
     // アイコンの表示
     for (i = 0; i < sizeof(omask) / sizeof(omask[0]); i++)
     {
-        if (option & omask[i])
+        if (bool(option & omask[i]))
         {
             if (sc_data[scnum[i]].timer == -1)
                 skill_status_change_start(bl, scnum[i], 0, 0, 0, 0, 0, 0);
@@ -3217,7 +3214,7 @@ void clif_getareachar_pc(struct map_session_data *sd,
 {
     int len;
 
-    if (dstsd->status.option & OPTION_INVISIBILITY)
+    if (bool(dstsd->status.option & Option::INVISIBILITY))
         return;
 
     nullpo_retv(sd);
@@ -4333,7 +4330,7 @@ int clif_pvpset(struct map_session_data *sd, int pvprank, int pvpnum,
 
         WBUFW(buf, 0) = 0x19a;
         WBUFL(buf, 2) = sd->bl.id;
-        if (sd->status.option & 0x46)
+        if (bool(sd->status.option & Option::REAL_ANY_HIDE))
             WBUFL(buf, 6) = -1;
         else if (pvprank <= 0)
             pc_calc_pvprank(sd);
@@ -5529,7 +5526,8 @@ int clif_GM_kick(struct map_session_data *sd, struct map_session_data *tsd,
 
     if (type)
         clif_GM_kickack(sd, tsd->status.account_id);
-    tsd->opt1 = tsd->opt2 = 0;
+    tsd->opt1 = Opt1::ZERO;
+    tsd->opt2 = Opt2::ZERO;
     clif_parse_QuitGame(tsd->fd, tsd);
 
     return 0;
@@ -5828,14 +5826,15 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd)
         return;
 
     // ステータス異常やハイディング中(トンネルドライブ無)で動けない
-    if ((sd->opt1 > 0 && sd->opt1 != 6) || sd->sc_data[SC_ANKLE].timer != -1 || //アンクルスネア
+    if ((bool(sd->opt1) && sd->opt1 != (Opt1::_stone6)) ||
+        sd->sc_data[SC_ANKLE].timer != -1 || //アンクルスネア
         sd->sc_data[SC_AUTOCOUNTER].timer != -1 ||  //オートカウンター
         sd->sc_data[SC_TRICKDEAD].timer != -1 ||    //死んだふり
         sd->sc_data[SC_BLADESTOP].timer != -1 ||    //白刃取り
         sd->sc_data[SC_SPIDERWEB].timer != -1 ||    //スパイダーウェッブ
         (sd->sc_data[SC_DANCING].timer != -1 && sd->sc_data[SC_DANCING].val4))  //合奏スキル演奏中は動けない
         return;
-    if ((sd->status.option & 2) && pc_checkskill(sd, RG_TUNNELDRIVE) <= 0)
+    if (bool(sd->status.option & Option::HIDE2) && pc_checkskill(sd, RG_TUNNELDRIVE) <= 0)
         return;
 
     if (sd->invincible_timer != -1)
@@ -5862,8 +5861,9 @@ void clif_parse_QuitGame(int fd, struct map_session_data *sd)
 
     WFIFOW(fd, 0) = 0x18b;
     if ((!pc_isdead(sd)
-         && (sd->opt1
-             || (sd->opt2 && !(night_flag == 1 && sd->opt2 == STATE_BLIND))))
+         && (sd->opt1 != Opt1::ZERO
+             || (sd->opt2 != Opt2::ZERO
+                 && !(night_flag == 1 && sd->opt2 == Opt2::BLIND))))
         || sd->skilltimer != -1 || (DIFF_TICK(tick, sd->canact_tick) < 0)
         || (sd->sc_data[SC_DANCING].timer != -1
             && sd->sc_data[SC_DANCING].val4
@@ -6190,8 +6190,11 @@ void clif_parse_ActionRequest(int fd, struct map_session_data *sd)
         clif_clearchar_area(&sd->bl, 1);
         return;
     }
-    if (sd->npc_id != 0 || sd->opt1 > 0 || sd->status.option & 2 || sd->state.storage_open ||
-            ((sd->sc_data[SC_AUTOCOUNTER].timer != -1 ||   //オートカウンター
+    if (sd->npc_id != 0
+        || bool(sd->opt1)
+        || bool(sd->status.option & Option::HIDE2)
+        || sd->state.storage_open
+        || ((sd->sc_data[SC_AUTOCOUNTER].timer != -1 ||   //オートカウンター
             sd->sc_data[SC_BLADESTOP].timer != -1 || //白刃取り
             sd->sc_data[SC_DANCING].timer != -1)))
         return;
@@ -6209,7 +6212,7 @@ void clif_parse_ActionRequest(int fd, struct map_session_data *sd)
         case 0x00:             // once attack
         case 0x07:             // continuous attack
             if (sd->sc_data[SC_WEDDING].timer != -1 || sd->view_class == 22
-                || sd->status.option & OPTION_HIDE)
+                || bool(sd->status.option & Option::HIDE))
                 return;
             if (!battle_config.sdelay_attack_enable
                 && pc_checkskill(sd, SA_FREECAST) <= 0)
@@ -6265,7 +6268,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd)
             }
             break;
         case 0x01:
-            /*if (!pc_isdead(sd) && (sd->opt1 || (sd->opt2 && !(night_flag == 1 && sd->opt2 == STATE_BLIND))))
+            /*if (!pc_isdead(sd) && (sd->opt1 || (sd->opt2 && !(night_flag == 1 && sd->opt2 == Opt2::BLIND))))
              * return; */
 
             /*  Rovert's Prevent logout option - Fixed [Valaris]    */
@@ -6426,7 +6429,9 @@ void clif_parse_TakeItem(int fd, struct map_session_data *sd)
         return;
     }
 
-    if (sd->npc_id != 0 || sd->opt1 > 0 || (
+    if (sd->npc_id != 0
+        || sd->opt1 != Opt1::ZERO
+        || (
             (sd->sc_data[SC_TRICKDEAD].timer != -1 ||    //死んだふり
             sd->sc_data[SC_BLADESTOP].timer != -1 ||    //白刃取り
             sd->sc_data[SC_BERSERK].timer != -1 ||  //バーサーク
@@ -6467,8 +6472,9 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd)
         clif_displaymessage(sd->fd, "Can't drop items here.");
         return;
     }
-    if (sd->npc_id != 0 || sd->opt1 > 0 ||
-            ((sd->sc_data[SC_AUTOCOUNTER].timer != -1 ||    //オートカウンター
+    if (sd->npc_id != 0
+        || sd->opt1 != Opt1::ZERO
+        || ((sd->sc_data[SC_AUTOCOUNTER].timer != -1 ||    //オートカウンター
             sd->sc_data[SC_BLADESTOP].timer != -1 ||  //白刃取り
             sd->sc_data[SC_BERSERK].timer != -1)))    //バーサーク
     {
@@ -6496,7 +6502,9 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd)
         clif_clearchar_area(&sd->bl, 1);
         return;
     }
-    if (sd->npc_id != 0 || sd->opt1 > 0 || (
+    if (sd->npc_id != 0
+        || sd->opt1 != Opt1::ZERO
+        || (
             (sd->sc_data[SC_TRICKDEAD].timer != -1 ||    //死んだふり
             sd->sc_data[SC_BLADESTOP].timer != -1 ||    //白刃取り
             sd->sc_data[SC_BERSERK].timer != -1 ||  //バーサーク
@@ -6574,7 +6582,8 @@ void clif_parse_UnequipItem(int fd, struct map_session_data *sd)
             || sd->sc_data[SC_BERSERK].timer != -1))
         return;
 
-    if (sd->npc_id != 0 || sd->opt1 > 0)
+    if (sd->npc_id != 0
+        || sd->opt1 != Opt1::ZERO)
         return;
     pc_unequipitem(sd, index, 0);
 }
@@ -6842,7 +6851,7 @@ void clif_parse_RemoveOption(int, struct map_session_data *sd)
             sd->status.pc_class = sd->view_class = 4015;
     }
 
-    pc_setoption(sd, 0);
+    pc_setoption(sd, Option::ZERO);
 }
 
 /*==========================================
@@ -7628,14 +7637,14 @@ void clif_parse_GMHide(int fd, struct map_session_data *sd)
         (pc_isGM(sd) >= get_atcommand_level(AtCommand_Hide)))
     {
         log_atcommand(sd, "@hide");
-        if (sd->status.option & OPTION_HIDE)
-        {                       // OPTION_HIDE = 0x40
-            sd->status.option &= ~OPTION_HIDE;  // OPTION_HIDE = 0x40
+        if (bool(sd->status.option & Option::HIDE))
+        {                       // Option::HIDE = 0x40
+            sd->status.option &= ~Option::HIDE;  // Option::HIDE = 0x40
             clif_displaymessage(fd, "Invisible: Off.");
         }
         else
         {
-            sd->status.option |= OPTION_HIDE;   // OPTION_HIDE = 0x40
+            sd->status.option |= Option::HIDE;   // Option::HIDE = 0x40
             clif_displaymessage(fd, "Invisible: On.");
         }
         clif_changeoption(&sd->bl);
diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp
index ef1ddb1..bb93670 100644
--- a/src/map/magic-expr.cpp
+++ b/src/map/magic-expr.cpp
@@ -1030,8 +1030,8 @@ static
 int fun_status_option(env_t *, int, val_t *result, val_t *args)
 {
     RESULTINT =
-        ((((struct map_session_data *) ARGENTITY(0))->
-          status.option & ARGINT(0)) != 0);
+        (bool(((struct map_session_data *) ARGENTITY(0))->
+          status.option & Option(ARGINT(0))));
     return 0;
 }
 
diff --git a/src/map/magic.cpp b/src/map/magic.cpp
index a310273..20155aa 100644
--- a/src/map/magic.cpp
+++ b/src/map/magic.cpp
@@ -98,7 +98,7 @@ int magic_message(character_t *caster, char *spell_, size_t)
         fprintf(stderr, "Found spell `%s', triggered = %d\n", spell_,
                  effects != NULL);
 #endif
-        if (caster->status.option & OPTION_HIDE)
+        if (bool(caster->status.option & Option::HIDE))
             return 0;           // No spellcasting while hidden
 
         MAP_LOG_PC(caster, "CAST %s %s",
diff --git a/src/map/map.hpp b/src/map/map.hpp
index 27e574a..dce3b76 100644
--- a/src/map/map.hpp
+++ b/src/map/map.hpp
@@ -1,6 +1,8 @@
 #ifndef MAP_HPP
 #define MAP_HPP
 
+#include "map.t.hpp"
+
 #include <netinet/in.h>
 #include <sys/time.h>
 
@@ -50,22 +52,6 @@
 
 #define DEFAULT_AUTOSAVE_INTERVAL 60*1000
 
-// [Fate] status.option properties.  These are persistent status changes.
-// IDs that are not listed are not used in the code (to the best of my knowledge)
-#define OPTION_HIDE2            0x0002  // apparently some weaker non-GM hide
-#define OPTION_CLOAK            0x0004
-#define OPTION_10               0x0010
-#define OPTION_20               0x0020
-#define OPTION_HIDE             0x0040  // [Fate] This is the GM `@hide' flag
-#define OPTION_800              0x0800
-#define OPTION_INVISIBILITY     0x1000  // [Fate] Complete invisibility to other clients
-#define OPTION_SCRIBE           0x2000  // [Fate] Auto-logging of nearby comments
-#define OPTION_CHASEWALK        0x4000
-
-enum
-{ BL_NUL, BL_PC, BL_NPC, BL_MOB, BL_ITEM, BL_CHAT, BL_SKILL, BL_SPELL };
-enum
-{ WARP, SHOP, SCRIPT, MONS, MESSAGE };
 struct block_list
 {
     struct block_list *next, *prev;
@@ -215,7 +201,9 @@ struct map_session_data
     int fd, new_fd;
     short to_x, to_y;
     short speed, prev_speed;
-    short opt1, opt2, opt3;
+    Opt1 opt1;
+    Opt2 opt2;
+    Opt3 opt3;
     char dir, head_dir;
     unsigned int client_tick, server_tick;
     struct walkpath_data walkpath;
@@ -434,7 +422,10 @@ struct npc_data
     char name[24];
     char exname[24];
     int chat_id;
-    short opt1, opt2, opt3, option;
+    Opt1 opt1;
+    Opt2 opt2;
+    Opt3 opt3;
+    Option option;
     short flag;
     union
     {
@@ -529,7 +520,10 @@ struct mob_data
 
     earray<struct status_change, StatusChange, MAX_STATUSCHANGE> sc_data;
     short sc_count;
-    short opt1, opt2, opt3, option;
+    Opt1 opt1;
+    Opt2 opt2;
+    Opt3 opt3;
+    Option option;
     short min_chase;
     short sg_count;
     int deletetimer;
diff --git a/src/map/map.t.hpp b/src/map/map.t.hpp
new file mode 100644
index 0000000..50110e9
--- /dev/null
+++ b/src/map/map.t.hpp
@@ -0,0 +1,91 @@
+#ifndef MAP_T_HPP
+#define MAP_T_HPP
+
+#include "../common/utils.hpp"
+
+// [Fate] status.option properties.  These are persistent status changes.
+// IDs that are not listed are not used in the code (to the best of my knowledge)
+enum class Option : uint16_t
+{
+    ZERO            = 0x0000,
+
+    SIGHT           = 0x0001,
+    // apparently some weaker non-GM hide
+    HIDE2           = 0x0002,
+    CLOAK           = 0x0004,
+    CART1           = 0x0008,
+    FALCON          = 0x0010,
+    RIDING          = 0x0020,
+    // [Fate] This is the GM `@hide' flag
+    HIDE            = 0x0040,
+    CART2           = 0x0080,
+    CART3           = 0x0100,
+    CART4           = 0x0200,
+    CART5           = 0x0400,
+    ORC_HEAD        = 0x0800,
+    // [Fate] Complete invisibility to other clients
+    INVISIBILITY    = 0x1000,
+    _wedding        = 0x1000,
+    // [Fate] Auto-logging of nearby comments
+    SCRIBE          = 0x2000,
+    _ruwach         = 0x2000,
+    CHASEWALK       = 0x4000,
+    sign            = 0x8000,
+
+
+    // ?
+    REAL_ANY_HIDE   = HIDE | CLOAK | HIDE2,
+    OLD_ANY_HIDE    = CHASEWALK | CLOAK | HIDE2,
+    CART_MASK       = CART1 | CART2 | CART3 | CART4 | CART5,
+    MASK            = sign | CHASEWALK | _wedding | CART_MASK | RIDING | FALCON,
+};
+enum class Opt1 : uint16_t
+{
+    ZERO            = 0,
+    _stone1         = 1,
+    _freeze         = 2,
+    _stan           = 3,
+    _sleep          = 4,
+    _stone6         = 6,
+};
+enum class Opt2 : uint16_t
+{
+    ZERO            = 0x0000,
+    _poison         = 0x0001,
+    _curse          = 0x0002,
+    _silence        = 0x0004,
+    BLIND           = 0x0010,
+    _speedpotion0   = 0x0020,
+    _signumcrucis   = 0x0040,
+    _atkpot         = 0x0080,
+    _heal           = 0x0100,
+    _slowpoison     = 0x0200,
+    sign            = 0x8000,
+};
+enum class Opt3 : uint16_t
+{
+    ZERO            = 0x0000,
+    _concentration  = 0x0001,
+    _overthrust     = 0x0002,
+    _energycoat     = 0x0004,
+    _explosionspirits = 0x0008,
+    _steelbody      = 0x0010,
+    _bladestop      = 0x0020,
+    _berserk        = 0x0080,
+
+    _marionette     = 0x0400,
+    _assumptio      = 0x0800,
+
+    sign            = 0x8000,
+};
+
+ENUM_BITWISE_OPERATORS(Option)
+ENUM_BITWISE_OPERATORS(Opt2)
+ENUM_BITWISE_OPERATORS(Opt3)
+
+
+enum
+{ BL_NUL, BL_PC, BL_NPC, BL_MOB, BL_ITEM, BL_CHAT, BL_SKILL, BL_SPELL };
+enum
+{ WARP, SHOP, SCRIPT, MONS, MESSAGE };
+#endif // MAP_T_HPP
diff --git a/src/map/mob.cpp b/src/map/mob.cpp
index cb7ef89..de3cb5c 100644
--- a/src/map/mob.cpp
+++ b/src/map/mob.cpp
@@ -1,7 +1,6 @@
 #include "mob.hpp"
 
 #include <cmath>
-#include <stdarg.h> // requires justification for <cstdarg>
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
@@ -614,8 +613,9 @@ int mob_can_move(struct mob_data *md)
 {
     nullpo_retr(0, md);
 
-    if (md->canmove_tick > gettick() || (md->opt1 > 0 && md->opt1 != 6)
-        || md->option & 2)
+    if (md->canmove_tick > gettick()
+        || (bool(md->opt1) && md->opt1 != Opt1::_stone6)
+        || bool(md->option & Option::HIDE2))
         return 0;
     // アンクル中で動けないとか
     if (md->sc_data[SC_ANKLE].timer != -1 ||    //アンクルスネア
@@ -728,7 +728,7 @@ int mob_walk(struct mob_data *md, unsigned int tick, int data)
                 -dx, -dy, BL_PC);
         md->state.state = MS_IDLE;
 
-        if (md->option & 4)
+        if (bool(md->option & Option::CLOAK))
             skill_check_cloaking(&md->bl);
 
         skill_unit_move(&md->bl, tick, 1); // Inspection of a skill unit
@@ -770,7 +770,8 @@ int mob_check_attack(struct mob_data *md)
     if (md->skilltimer != -1)
         return 0;
 
-    if (md->opt1 > 0 || md->option & 2)
+    if (bool(md->opt1)
+        || bool(md->option & Option::HIDE2))
         return 0;
 
     if (md->sc_data[SC_AUTOCOUNTER].timer != -1)
@@ -1271,7 +1272,10 @@ int mob_spawn(int id)
             md->sc_data[i].val4 = 0;
     }
     md->sc_count = 0;
-    md->opt1 = md->opt2 = md->opt3 = md->option = 0;
+    md->opt1 = Opt1::ZERO;
+    md->opt2 = Opt2::ZERO;
+    md->opt3 = Opt3::ZERO;
+    md->option = Option::ZERO;
 
     memset(md->skillunit, 0, sizeof(md->skillunit));
     memset(md->skillunittick, 0, sizeof(md->skillunittick));
@@ -1428,14 +1432,13 @@ int mob_target(struct mob_data *md, struct block_list *bl, int dist)
 {
     struct map_session_data *sd;
     eptr<struct status_change, StatusChange> sc_data;
-    short *option;
     int mode, race;
 
     nullpo_retr(0, md);
     nullpo_retr(0, bl);
 
     sc_data = battle_get_sc_data(bl);
-    option = battle_get_option(bl);
+    Option *option = battle_get_option(bl);
     race = mob_db[md->mob_class].race;
 
     if (!md->mode)
@@ -1456,9 +1459,12 @@ int mob_target(struct mob_data *md, struct block_list *bl, int dist)
         && (!(mode & 0x04) || MRAND(100) > 25))
         return 0;
 
-    if (mode & 0x20 ||          // Coercion is exerted if it is MVPMOB.
-        (sc_data && sc_data[SC_TRICKDEAD].timer == -1 &&
-         ((option && !(*option & 0x06)) || race == 4 || race == 6)))
+    // Coercion is exerted if it is MVPMOB.
+    if (mode & 0x20
+        || (sc_data && sc_data[SC_TRICKDEAD].timer == -1
+            && ((option != NULL && !bool(*option & (Option::CLOAK | Option::HIDE2)))
+                || race == 4
+                || race == 6)))
     {
         if (bl->type == BL_PC)
         {
@@ -1893,7 +1899,8 @@ void mob_ai_sub_hard(struct block_list *bl, unsigned int tick)
     race = mob_db[md->mob_class].race;
 
     // Abnormalities
-    if ((md->opt1 > 0 && md->opt1 != 6) || md->state.state == MS_DELAY
+    if ((bool(md->opt1) && md->opt1 != Opt1::_stone6)
+        || md->state.state == MS_DELAY
         || md->sc_data[SC_BLADESTOP].timer != -1)
         return;
 
@@ -2629,9 +2636,9 @@ int mob_damage(struct block_list *src, struct mob_data *md, int damage,
 
     md->hp -= damage;
 
-    if (md->option & 2)
+    if (bool(md->option & Option::HIDE2))
         skill_status_change_end(&md->bl, SC_HIDING, -1);
-    if (md->option & 4)
+    if (bool(md->option & Option::CLOAK))
         skill_status_change_end(&md->bl, SC_CLOAKING, -1);
 
     if (md->state.special_mob_ai == 2)
@@ -3397,7 +3404,8 @@ void mobskill_castend_id(timer_id tid, tick_t tick, custom_id_t id, custom_data_
 
     md->skilltimer = -1;
 
-    if (md->opt1 > 0 || md->sc_data[SC_DIVINA].timer != -1
+    if (bool(md->opt1)
+        || md->sc_data[SC_DIVINA].timer != -1
         || md->sc_data[SC_ROKISWEIL].timer != -1
         || md->sc_data[SC_STEELBODY].timer != -1)
         return;
@@ -3500,7 +3508,8 @@ void mobskill_castend_pos(timer_id tid, tick_t tick, custom_id_t id, custom_data
 
     md->skilltimer = -1;
 
-    if (md->opt1 > 0 || md->sc_data[SC_DIVINA].timer != -1
+    if (bool(md->opt1)
+        || md->sc_data[SC_DIVINA].timer != -1
         || md->sc_data[SC_ROKISWEIL].timer != -1
         || md->sc_data[SC_STEELBODY].timer != -1)
         return;
@@ -3631,7 +3640,8 @@ int mobskill_use_id(struct mob_data *md, struct block_list *target,
     skill_id = ms->skill_id;
     skill_lv = ms->skill_lv;
 
-    if (md->opt1 > 0 || md->sc_data[SC_DIVINA].timer != -1
+    if (bool(md->opt1)
+        || md->sc_data[SC_DIVINA].timer != -1
         || md->sc_data[SC_ROKISWEIL].timer != -1
         || md->sc_data[SC_STEELBODY].timer != -1)
         return 0;
@@ -3642,9 +3652,11 @@ int mobskill_use_id(struct mob_data *md, struct block_list *target,
     if (md->sc_data[SC_BERSERK].timer != -1)    //バーサーク
         return 0;
 
-    if (md->option & 4 && skill_id == TF_HIDING)
+    if (bool(md->option & Option::CLOAK)
+        && skill_id == TF_HIDING)
         return 0;
-    if (md->option & 2 && skill_id != TF_HIDING && skill_id != AS_GRIMTOOTH
+    if (bool(md->option & Option::HIDE2)
+        && skill_id != TF_HIDING && skill_id != AS_GRIMTOOTH
         && skill_id != RG_BACKSTAP && skill_id != RG_RAID)
         return 0;
 
@@ -3756,7 +3768,8 @@ int mobskill_use_pos(struct mob_data *md,
     SkillID skill_id = ms->skill_id;
     skill_lv = ms->skill_lv;
 
-    if (md->opt1 > 0 || md->sc_data[SC_DIVINA].timer != -1
+    if (bool(md->opt1)
+        || md->sc_data[SC_DIVINA].timer != -1
         || md->sc_data[SC_ROKISWEIL].timer != -1
         || md->sc_data[SC_STEELBODY].timer != -1)
         return 0;
@@ -3767,7 +3780,7 @@ int mobskill_use_pos(struct mob_data *md,
     if (md->sc_data[SC_BERSERK].timer != -1)    //バーサーク
         return 0;
 
-    if (md->option & 2)
+    if (bool(md->option & Option::HIDE2))
         return 0;
 
     // 射程と障害物チェック
diff --git a/src/map/npc.cpp b/src/map/npc.cpp
index 2f84951..e22110e 100644
--- a/src/map/npc.cpp
+++ b/src/map/npc.cpp
@@ -97,13 +97,13 @@ int npc_enable(const char *name, int flag)
     else if (flag & 2)
     {
         nd->flag &= ~1;
-        nd->option = 0x0000;
+        nd->option = Option::ZERO;
         clif_changeoption(&nd->bl);
     }
     else if (flag & 4)
     {
         nd->flag |= 1;
-        nd->option = 0x0002;
+        nd->option = Option::HIDE2;
         clif_changeoption(&nd->bl);
     }
     else
@@ -1147,10 +1147,10 @@ int npc_parse_warp(const char *w1, const char *, const char *w3, const char *w4)
     else
         nd->npc_class = WARP_DEBUG_CLASS;
     nd->speed = 200;
-    nd->option = 0;
-    nd->opt1 = 0;
-    nd->opt2 = 0;
-    nd->opt3 = 0;
+    nd->option = Option::ZERO;
+    nd->opt1 = Opt1::ZERO;
+    nd->opt2 = Opt2::ZERO;
+    nd->opt3 = Opt3::ZERO;
     memcpy(nd->u.warp.name, to_mapname, 16);
     xs += 2;
     ys += 2;
@@ -1262,10 +1262,10 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4)
     nd->npc_class = atoi(w4);
     nd->speed = 200;
     nd->chat_id = 0;
-    nd->option = 0;
-    nd->opt1 = 0;
-    nd->opt2 = 0;
-    nd->opt3 = 0;
+    nd->option = Option::ZERO;
+    nd->opt1 = Opt1::ZERO;
+    nd->opt2 = Opt2::ZERO;
+    nd->opt3 = Opt3::ZERO;
 
     nd = (struct npc_data *)
         realloc(nd, sizeof(struct npc_data) + sizeof(nd->u.shop_item[0]) * pos);
@@ -1509,10 +1509,10 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4,
     nd->u.scr.script = script;
     nd->u.scr.src_id = src_id;
     nd->chat_id = 0;
-    nd->option = 0;
-    nd->opt1 = 0;
-    nd->opt2 = 0;
-    nd->opt3 = 0;
+    nd->option = Option::ZERO;
+    nd->opt1 = Opt1::ZERO;
+    nd->opt2 = Opt2::ZERO;
+    nd->opt3 = Opt3::ZERO;
 
     //printf("script npc %s %d %d read done\n",mapname,nd->bl.id,nd->class);
     npc_script++;
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index 258af27..b780fd4 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -33,8 +33,6 @@
 //define it here, since the ifdef only occurs in this file
 #define USE_ASTRAL_SOUL_SKILL
 
-#define STATE_BLIND 0x10
-
 #ifdef USE_ASTRAL_SOUL_SKILL
 #define MAGIC_SKILL_THRESHOLD 200   // [fate] At this threshold, the Astral Soul skill kicks in
 #endif
@@ -863,9 +861,9 @@ int pc_authok(int id, int login_id2, time_t connect_until_time,
     sd->sc_count = 0;
     if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
         (pc_isGM(sd) >= get_atcommand_level(AtCommand_Hide)))
-        sd->status.option &= (OPTION_MASK | OPTION_HIDE);
+        sd->status.option &= (Option::MASK | Option::HIDE);
     else
-        sd->status.option &= OPTION_MASK;
+        sd->status.option &= Option::MASK;
 
     // スキルユニット関係の初期化
     memset(sd->skillunit, 0, sizeof(sd->skillunit));
@@ -916,7 +914,7 @@ int pc_authok(int id, int login_id2, time_t connect_until_time,
         strcpy(tmpstr, "Actually, it's the night...");
         clif_wis_message(sd->fd, wisp_server_name, tmpstr,
                           strlen(tmpstr) + 1);
-        sd->opt2 |= STATE_BLIND;
+        sd->opt2 |= Opt2::BLIND;
     }
 
     // ステータス初期計算など
@@ -1903,7 +1901,8 @@ int pc_calcstatus(struct map_session_data *sd, int first)
 
     if ((skill = pc_checkskill(sd, BS_WEAPONRESEARCH)) > 0)    // 武器研究の命中率増加
         sd->hit += skill * 2;
-    if (sd->status.option & 2 && (skill = pc_checkskill(sd, RG_TUNNELDRIVE)) > 0)  // トンネルドライブ
+    if (bool(sd->status.option & Option::HIDE2)
+        && (skill = pc_checkskill(sd, RG_TUNNELDRIVE)) > 0)  // トンネルドライブ
         sd->speed += (1.2 * DEFAULT_WALK_SPEED - skill * 9);
     if (pc_iscarton(sd) && (skill = pc_checkskill(sd, MC_PUSHCART)) > 0)  // カートによる速度低下
         sd->speed += (10 - skill) * (DEFAULT_WALK_SPEED * 0.1);
@@ -4097,11 +4096,11 @@ int pc_setpos(struct map_session_data *sd, const char *mapname_org, int x, int y
 
     if (sd->sc_data[SC_TRICKDEAD].timer != -1)
         skill_status_change_end(&sd->bl, SC_TRICKDEAD, -1);
-    if (sd->status.option & 2)
+    if (bool(sd->status.option & Option::HIDE2))
         skill_status_change_end(&sd->bl, SC_HIDING, -1);
-    if (sd->status.option & 4)
+    if (bool(sd->status.option & Option::CLOAK))
         skill_status_change_end(&sd->bl, SC_CLOAKING, -1);
-    if (sd->status.option & 16386)
+    if (bool(sd->status.option & (Option::CHASEWALK | Option::HIDE2)))
         skill_status_change_end(&sd->bl, SC_CHASEWALK, -1);
     if (sd->sc_data[SC_BLADESTOP].timer != -1)
         skill_status_change_end(&sd->bl, SC_BLADESTOP, -1);
@@ -4445,7 +4444,8 @@ void pc_walk(timer_id tid, tick_t tick, custom_id_t id, custom_data_t data)
                     sd->party_hp = -1;
             }
         }
-        if (sd->status.option & 4)  // クローキングの消滅検査
+        // クローキングの消滅検査
+        if (bool(sd->status.option & Option::CLOAK))
             skill_check_cloaking(&sd->bl);
         // ディボーション検査
         for (i = 0; i < 5; i++)
@@ -4632,7 +4632,8 @@ int pc_movepos(struct map_session_data *sd, int dst_x, int dst_y)
         }
     }
 
-    if (sd->status.option & 4)  // クローキングの消滅検査
+    // クローキングの消滅検査
+    if (bool(sd->status.option & Option::CLOAK))
         skill_check_cloaking(&sd->bl);
 
     skill_unit_move(&sd->bl, gettick(), dist + 7);    // スキルユニットの検査
@@ -4811,7 +4812,6 @@ void pc_attack_timer(timer_id tid, tick_t tick, custom_id_t id, custom_data_t)
     struct map_session_data *sd;
     struct block_list *bl;
     eptr<struct status_change, StatusChange> sc_data;
-    short *opt;
     int dist, skill, range;
     int attack_spell_delay;
 
@@ -4841,7 +4841,9 @@ void pc_attack_timer(timer_id tid, tick_t tick, custom_id_t id, custom_data_t)
     if (sd->bl.m != bl->m || pc_isdead(sd))
         return;
 
-    if (sd->opt1 > 0 || sd->status.option & 2 || sd->status.option & 16388) // 異常などで攻撃できない
+    // 異常などで攻撃できない
+    if (sd->opt1 != Opt1::ZERO
+        || bool(sd->status.option & (Option::OLD_ANY_HIDE)))
         return;
 
     if (sd->sc_data[SC_AUTOCOUNTER].timer != -1)
@@ -4849,7 +4851,8 @@ void pc_attack_timer(timer_id tid, tick_t tick, custom_id_t id, custom_data_t)
     if (sd->sc_data[SC_BLADESTOP].timer != -1)
         return;
 
-    if ((opt = battle_get_option(bl)) != NULL && *opt & 0x46)
+    Option *opt = battle_get_option(bl);
+    if (opt != NULL && bool(*opt & Option::REAL_ANY_HIDE))
         return;
     if (((sc_data = battle_get_sc_data(bl))
          && sc_data[SC_TRICKDEAD].timer != -1)
@@ -5680,8 +5683,7 @@ int pc_resetlvl(struct map_session_data *sd, int type)
         sd->status.job_level = 1;
         sd->status.base_exp = 0;
         sd->status.job_exp = 0;
-        if (sd->status.option != 0)
-            sd->status.option = 0;
+        sd->status.option = Option::ZERO;
 
         sd->status.str = 1;
         sd->status.agi = 1;
@@ -5881,11 +5883,11 @@ int pc_damage(struct block_list *src, struct map_session_data *sd,
 
     if (sd->sc_data[SC_TRICKDEAD].timer != -1)
         skill_status_change_end(&sd->bl, SC_TRICKDEAD, -1);
-    if (sd->status.option & 2)
+    if (bool(sd->status.option & Option::HIDE2))
         skill_status_change_end(&sd->bl, SC_HIDING, -1);
-    if (sd->status.option & 4)
+    if (bool(sd->status.option & Option::CLOAK))
         skill_status_change_end(&sd->bl, SC_CLOAKING, -1);
-    if (sd->status.option & 16386)
+    if (bool(sd->status.option & Option::CHASEWALK))
         skill_status_change_end(&sd->bl, SC_CHASEWALK, -1);
 
     if (sd->status.hp > 0)
@@ -6704,7 +6706,7 @@ int pc_jobchange(struct map_session_data *sd, int job, int upper)
     if (pc_isriding(sd))
     {                           // remove peco status if changing into invalid class [Valaris]
         if (!(pc_checkskill(sd, KN_RIDING)))
-            pc_setoption(sd, sd->status.option | -0x0000);
+            pc_setoption(sd, sd->status.option);
         if (pc_checkskill(sd, KN_RIDING) > 0)
             pc_setriding(sd);
     }
@@ -6777,7 +6779,7 @@ int pc_changelook(struct map_session_data *sd, int type, int val)
  * 付属品(鷹,ペコ,カート)設定
  *------------------------------------------
  */
-int pc_setoption(struct map_session_data *sd, int type)
+int pc_setoption(struct map_session_data *sd, Option type)
 {
     nullpo_retr(0, sd);
 
@@ -6794,7 +6796,8 @@ int pc_setoption(struct map_session_data *sd, int type)
  */
 int pc_setcart(struct map_session_data *sd, int type)
 {
-    int cart[6] = { 0x0000, 0x0008, 0x0080, 0x0100, 0x0200, 0x0400 };
+    Option cart[6] = {Option::ZERO, Option::CART1, Option::CART2,
+        Option::CART3, Option::CART4, Option::CART5};
 
     nullpo_retr(0, sd);
 
@@ -6825,7 +6828,7 @@ int pc_setfalcon(struct map_session_data *sd)
 {
     if (pc_checkskill(sd, HT_FALCON) > 0)
     {                           // ファルコンマスタリースキル所持
-        pc_setoption(sd, sd->status.option | 0x0010);
+        pc_setoption(sd, sd->status.option | Option::FALCON);
     }
 
     return 0;
@@ -6846,7 +6849,7 @@ int pc_setriding(struct map_session_data *sd)
 
     if ((pc_checkskill(sd, KN_RIDING) > 0))
     {                           // ライディングスキル所持
-        pc_setoption(sd, sd->status.option | 0x0020);
+        pc_setoption(sd, sd->status.option | Option::RIDING);
 
         if (sd->status.pc_class == 7)
             sd->status.pc_class = sd->view_class = 13;
@@ -8451,7 +8454,7 @@ void map_day_timer(timer_id, tick_t, custom_id_t, custom_data_t)
                 if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
                     && pl_sd->state.auth)
                 {
-                    pl_sd->opt2 &= ~STATE_BLIND;
+                    pl_sd->opt2 &= ~Opt2::BLIND;
                     clif_changeoption(&pl_sd->bl);
                     clif_wis_message(pl_sd->fd, wisp_server_name, tmpstr,
                                       strlen(tmpstr) + 1);
@@ -8483,7 +8486,7 @@ void map_night_timer(timer_id, tick_t, custom_id_t, custom_data_t)
                 if (session[i] && (pl_sd = (struct map_session_data *)session[i]->session_data)
                     && pl_sd->state.auth)
                 {
-                    pl_sd->opt2 |= STATE_BLIND;
+                    pl_sd->opt2 |= Opt2::BLIND;
                     clif_changeoption(&pl_sd->bl);
                     clif_wis_message(pl_sd->fd, wisp_server_name, tmpstr,
                                       strlen(tmpstr) + 1);
@@ -8949,15 +8952,15 @@ void pc_cleanup(struct map_session_data *sd)
 
 void pc_invisibility(struct map_session_data *sd, int enabled)
 {
-    if (enabled && !(sd->status.option & OPTION_INVISIBILITY))
+    if (enabled && !bool(sd->status.option & Option::INVISIBILITY))
     {
         clif_clearchar_area(&sd->bl, 3);
-        sd->status.option |= OPTION_INVISIBILITY;
+        sd->status.option |= Option::INVISIBILITY;
         clif_status_change(&sd->bl, CLIF_OPTION_SC_INVISIBILITY, 1);
     }
     else if (!enabled)
     {
-        sd->status.option &= ~OPTION_INVISIBILITY;
+        sd->status.option &= ~Option::INVISIBILITY;
         clif_status_change(&sd->bl, CLIF_OPTION_SC_INVISIBILITY, 0);
         pc_setpos(sd, map[sd->bl.m].name, sd->bl.x, sd->bl.y, 3);
     }
diff --git a/src/map/pc.hpp b/src/map/pc.hpp
index 505cf78..91ad633 100644
--- a/src/map/pc.hpp
+++ b/src/map/pc.hpp
@@ -3,23 +3,72 @@
 
 #include "map.hpp"
 
-#define OPTION_MASK 0xd7b8
-#define CART_MASK 0x788
-
-#define pc_setdead(sd) ((sd)->state.dead_sit = 1)
-#define pc_setsit(sd) ((sd)->state.dead_sit = 2)
-//#define pc_setstand(sd) ((sd)->state.dead_sit = 0)
-#define pc_isdead(sd) ((sd)->state.dead_sit == 1)
-#define pc_issit(sd) ((sd)->state.dead_sit == 2)
-#define pc_setdir(sd,b) ((sd)->dir = (b))
-#define pc_setchatid(sd,n) ((sd)->chatID = n)
-#define pc_ishiding(sd) ((sd)->status.option&0x4006)
-#define pc_iscarton(sd) ((sd)->status.option&CART_MASK)
-#define pc_isfalcon(sd) ((sd)->status.option&0x0010)
-#define pc_isriding(sd) ((sd)->status.option&0x0020)
-#define pc_isinvisible(sd) ((sd)->status.option&0x0040)
-#define pc_is50overweight(sd) (sd->weight*2 >= sd->max_weight)
-#define pc_is90overweight(sd) (sd->weight*10 >= sd->max_weight*9)
+inline
+void pc_setdead(struct map_session_data *sd)
+{
+    sd->state.dead_sit = 1;
+}
+inline
+void pc_setsit(struct map_session_data *sd)
+{
+    sd->state.dead_sit = 2;
+}
+//pc_setstand(struct map_session_data *sd) is a normal function
+inline
+bool pc_isdead(struct map_session_data *sd)
+{
+    return sd->state.dead_sit == 1;
+}
+inline
+bool pc_issit(struct map_session_data *sd)
+{
+    return sd->state.dead_sit == 2;
+}
+inline
+void pc_setdir(struct map_session_data *sd, int b)
+{
+    sd->dir = (b);
+}
+inline
+void pc_setchatid(struct map_session_data *sd, int n)
+{
+    sd->chatID = n;
+}
+inline
+bool pc_ishiding(struct map_session_data *sd)
+{
+    return bool(sd->status.option & Option::OLD_ANY_HIDE);
+}
+inline
+bool pc_iscarton(struct map_session_data *sd)
+{
+    return bool(sd->status.option & Option::CART_MASK);
+}
+inline
+bool pc_isfalcon(struct map_session_data *sd)
+{
+    return bool(sd->status.option & Option::FALCON);
+}
+inline
+bool pc_isriding(struct map_session_data *sd)
+{
+    return bool(sd->status.option & Option::RIDING);
+}
+inline
+bool pc_isinvisible(struct map_session_data *sd)
+{
+    return bool(sd->status.option & Option::HIDE);
+}
+inline
+bool pc_is50overweight(struct map_session_data *sd)
+{
+    return sd->weight*2 >= sd->max_weight;
+}
+inline
+bool pc_is90overweight(struct map_session_data *sd)
+{
+    return sd->weight*10 >= sd->max_weight*9;
+}
 
 void pc_touch_all_relevant_npcs(struct map_session_data *sd);  /* Checks all npcs/warps at the same location to see whether they
                                                                  ** should do something with the specified player. */
@@ -137,7 +186,7 @@ int pc_heal(struct map_session_data *, int, int);
 int pc_itemheal(struct map_session_data *sd, int hp, int sp);
 int pc_percentheal(struct map_session_data *sd, int, int);
 int pc_jobchange(struct map_session_data *, int, int);
-int pc_setoption(struct map_session_data *, int);
+int pc_setoption(struct map_session_data *, Option);
 int pc_setcart(struct map_session_data *sd, int type);
 int pc_setfalcon(struct map_session_data *sd);
 int pc_setriding(struct map_session_data *sd);
diff --git a/src/map/script.cpp b/src/map/script.cpp
index bf633aa..647f7fd 100644
--- a/src/map/script.cpp
+++ b/src/map/script.cpp
@@ -298,7 +298,6 @@ void builtin_gety(ScriptState *st);  // [Kage]
 void builtin_getmap(ScriptState *st);
 
 
-void push_val(struct script_stack *stack, int type, int val);
 void run_func(ScriptState *st);
 
 void mapreg_setreg(int num, int val);
@@ -3475,7 +3474,7 @@ void builtin_getopt2(ScriptState *st)
 
     sd = script_rid2sd(st);
 
-    push_val(st->stack, ScriptCode::INT, sd->opt2);
+    push_val(st->stack, ScriptCode::INT, uint16_t(sd->opt2));
 
 }
 
@@ -3486,10 +3485,9 @@ void builtin_getopt2(ScriptState *st)
 
 void builtin_setopt2(ScriptState *st)
 {
-    int new_opt2;
     struct map_session_data *sd;
 
-    new_opt2 = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+    Opt2 new_opt2 = Opt2(conv_num(st, &(st->stack->stack_data[st->start + 2])));
     sd = script_rid2sd(st);
     if (new_opt2 == sd->opt2)
         return;
@@ -3505,13 +3503,12 @@ void builtin_setopt2(ScriptState *st)
  */
 void builtin_checkoption(ScriptState *st)
 {
-    int type;
     struct map_session_data *sd;
 
-    type = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+    Option type = Option(conv_num(st, &(st->stack->stack_data[st->start + 2])));
     sd = script_rid2sd(st);
 
-    if (sd->status.option & type)
+    if (bool(sd->status.option & type))
     {
         push_val(st->stack, ScriptCode::INT, 1);
     }
@@ -3528,10 +3525,9 @@ void builtin_checkoption(ScriptState *st)
  */
 void builtin_setoption(ScriptState *st)
 {
-    int type;
     struct map_session_data *sd;
 
-    type = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+    Option type = Option(conv_num(st, &(st->stack->stack_data[st->start + 2])));
     sd = script_rid2sd(st);
     pc_setoption(sd, type);
 
diff --git a/src/map/skill.cpp b/src/map/skill.cpp
index c090102..a283073 100644
--- a/src/map/skill.cpp
+++ b/src/map/skill.cpp
@@ -23,8 +23,6 @@
 
 #define SKILLUNITTIMER_INVERVAL 100
 
-#define STATE_BLIND 0x10
-
 // This table appears to be wrong
 /* スキル番号=>ステータス異常番号変換テーブル */
 earray<StatusChange, SkillID, MAX_SKILL_DB> SkillStatusChangeTable =
@@ -3642,7 +3640,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl,
         case SA_REVERSEORCISH:
             clif_skill_nodamage(src, bl, skillid, skilllv, 1);
             if (dstsd)
-                pc_setoption(dstsd, dstsd->status.option | 0x0800);
+                pc_setoption(dstsd, dstsd->status.option | Option::ORC_HEAD);
             break;
         case SA_FORTUNE:
             clif_skill_nodamage(src, bl, skillid, skilllv, 1);
@@ -5689,7 +5687,8 @@ int skill_castend_map(struct map_session_data *sd, SkillID skill_num,
     if (sd->bl.prev == NULL || pc_isdead(sd))
         return 0;
 
-    if (sd->opt1 > 0 || sd->status.option & 2)
+    if (bool(sd->opt1)
+        || bool(sd->status.option & Option::HIDE2))
         return 0;
 
     if (sd->sc_data[SC_DIVINA].timer != -1
@@ -7494,7 +7493,7 @@ int skill_check_condition(struct map_session_data *sd, int type)
         return 1;
     }
 
-    if (sd->opt1 > 0)
+    if (bool(sd->opt1))
     {
         clif_skill_fail(sd, sd->skillid, 0, 0);
         sd->skillitem = SkillID::NEGATIVE;
@@ -7529,7 +7528,7 @@ int skill_check_condition(struct map_session_data *sd, int type)
         }
         return 1;
     }
-    if (sd->opt1 > 0)
+    if (bool(sd->opt1))
     {
         clif_skill_fail(sd, sd->skillid, 0, 0);
         return 0;
@@ -7781,14 +7780,14 @@ int skill_check_condition(struct map_session_data *sd, int type)
     switch (state)
     {
         case ST_HIDING:
-            if (!(sd->status.option & 2))
+            if (!bool(sd->status.option & Option::HIDE2))
             {
                 clif_skill_fail(sd, skill, 0, 0);
                 return 0;
             }
             break;
         case ST_CLOAKING:
-            if (!(sd->status.option & 4))
+            if (!bool(sd->status.option & Option::CLOAK))
             {
                 clif_skill_fail(sd, skill, 0, 0);
                 return 0;
@@ -8076,7 +8075,7 @@ int skill_use_id(struct map_session_data *sd, int target_id,
     sc_data = sd->sc_data;
 
     /* 沈黙や異常(ただし、グリムなどの判定をする) */
-    if (sd->opt1 > 0)
+    if (bool(sd->opt1))
         return 0;
 
     if (sc_data[SC_CHASEWALK].timer != -1)
@@ -8122,10 +8121,13 @@ int skill_use_id(struct map_session_data *sd, int target_id,
             return 0;
     }
 
-    if (sd->status.option & 4 && skill_num == TF_HIDING)
+    if (bool(sd->status.option & Option::CLOAK)
+        && skill_num == TF_HIDING)
         return 0;
-    if (sd->status.option & 2 && skill_num != TF_HIDING
-        && skill_num != AS_GRIMTOOTH && skill_num != RG_BACKSTAP
+    if (bool(sd->status.option & Option::HIDE2)
+        && skill_num != TF_HIDING
+        && skill_num != AS_GRIMTOOTH
+        && skill_num != RG_BACKSTAP
         && skill_num != RG_RAID)
         return 0;
 
@@ -8419,7 +8421,7 @@ int skill_use_pos(struct map_session_data *sd,
 
     sc_data = sd->sc_data;
 
-    if (sd->opt1 > 0)
+    if (bool(sd->opt1))
         return 0;
     if (sc_data)
     {
@@ -8432,7 +8434,7 @@ int skill_use_pos(struct map_session_data *sd,
             return 0;           /* 状態異常や沈黙など */
     }
 
-    if (sd->status.option & 2)
+    if (bool(sd->status.option & Option::HIDE2))
         return 0;
 
     sd->skillid = skill_num;
@@ -9150,14 +9152,14 @@ void skill_status_change_timer_sub(struct block_list *bl,
     {
         case SC_SIGHT:         /* サイト */
         case SC_CONCENTRATE:
-            if ((*battle_get_option(bl)) & 6)
+            if (bool((*battle_get_option(bl)) & (Option::HIDE2 | Option::CLOAK)))
             {
                 skill_status_change_end(bl, SC_HIDING, -1);
                 skill_status_change_end(bl, SC_CLOAKING, -1);
             }
             break;
         case SC_RUWACH:        /* ルアフ */
-            if ((*battle_get_option(bl)) & 6)
+            if (bool((*battle_get_option(bl)) & (Option::HIDE2 | Option::CLOAK)))
             {
                 skill_status_change_end(bl, SC_HIDING, -1);
                 skill_status_change_end(bl, SC_CLOAKING, -1);
@@ -9199,7 +9201,11 @@ int skill_status_change_end(struct block_list *bl, StatusChange type, int tid)
 {
     eptr<struct status_change, StatusChange> sc_data;
     int opt_flag = 0, calc_flag = 0;
-    short *sc_count, *option, *opt1, *opt2, *opt3;
+    short *sc_count;
+    Option *option;
+    Opt1 *opt1;
+    Opt2 *opt2;
+    Opt3 *opt3;
 
     nullpo_retr(0, bl);
     if (bl->type != BL_PC && bl->type != BL_MOB)
@@ -9393,73 +9399,77 @@ int skill_status_change_end(struct block_list *bl, StatusChange type, int tid)
             case SC_FREEZE:
             case SC_STAN:
             case SC_SLEEP:
-                *opt1 = 0;
+                *opt1 = Opt1::ZERO;
                 opt_flag = 1;
                 break;
 
             case SC_POISON:
-                *opt2 &= ~0x0001;
+                *opt2 &= ~Opt2::_poison;
                 opt_flag = 1;
                 break;
 
             case SC_CURSE:
-                *opt2 &= ~0x0002;
+                *opt2 &= ~Opt2::_curse;
                 opt_flag = 1;
                 break;
 
             case SC_SILENCE:
-                *opt2 &= ~0x0004;
+                *opt2 &= ~Opt2::_silence;
                 opt_flag = 1;
                 break;
 
             case SC_BLIND:
-                *opt2 &= ~0x0010;
+                *opt2 &= ~Opt2::BLIND;
                 opt_flag = 1;
                 break;
 
             case SC_SLOWPOISON:
                 if (sc_data[SC_POISON].timer != -1)
-                    *opt2 |= 0x1;
-                *opt2 &= ~0x200;
+                    *opt2 |= Opt2::_poison;
+                *opt2 &= ~Opt2::_slowpoison;
                 opt_flag = 1;
                 break;
 
             case SC_SIGNUMCRUCIS:
-                *opt2 &= ~0x40;
+                *opt2 &= ~Opt2::_signumcrucis;
                 opt_flag = 1;
                 break;
 
             case SC_SPEEDPOTION0:
-                *opt2 &= ~0x20;
+                *opt2 &= ~Opt2::_speedpotion0;
                 opt_flag = 1;
                 break;
 
             case SC_ATKPOT:
-                *opt2 &= ~0x80;
+                *opt2 &= ~Opt2::_atkpot;
                 opt_flag = 1;
                 break;
 
             case SC_HIDING:
+                *option &= ~Option::HIDE2;
+                opt_flag = 1;
+                break;
+
             case SC_CLOAKING:
-                *option &= ~((type == SC_HIDING) ? 2 : 4);
+                *option &= ~Option::CLOAK;
                 opt_flag = 1;
                 break;
 
             case SC_CHASEWALK:
-                *option &= ~16388;
+                *option &= ~Option::CHASEWALK;
                 opt_flag = 1;
                 break;
 
             case SC_SIGHT:
-                *option &= ~1;
+                *option &= ~Option::SIGHT;
                 opt_flag = 1;
                 break;
             case SC_WEDDING:   //結婚用(結婚衣裳になって歩くのが遅いとか)
-                *option &= ~4096;
+                *option &= ~Option::_wedding;
                 opt_flag = 1;
                 break;
             case SC_RUWACH:
-                *option &= ~8192;
+                *option &= ~Option::_ruwach;
                 opt_flag = 1;
                 break;
 
@@ -9467,38 +9477,39 @@ int skill_status_change_end(struct block_list *bl, StatusChange type, int tid)
             case SC_TWOHANDQUICKEN:    /* 2HQ */
             case SC_SPEARSQUICKEN: /* スピアクイッケン */
             case SC_CONCENTRATION: /* コンセントレーション */
-                *opt3 &= ~1;
+                *opt3 &= ~Opt3::_concentration;
                 break;
             case SC_OVERTHRUST:    /* オーバースラスト */
-                *opt3 &= ~2;
+                *opt3 &= ~Opt3::_overthrust;
                 break;
             case SC_ENERGYCOAT:    /* エナジーコート */
-                *opt3 &= ~4;
+                *opt3 &= ~Opt3::_energycoat;
                 break;
             case SC_EXPLOSIONSPIRITS:  // 爆裂波動
-                *opt3 &= ~8;
+                *opt3 &= ~Opt3::_explosionspirits;
                 break;
             case SC_STEELBODY: // 金剛
-                *opt3 &= ~16;
+                *opt3 &= ~Opt3::_steelbody;
                 break;
             case SC_BLADESTOP: /* 白刃取り */
-                *opt3 &= ~32;
+                *opt3 &= ~Opt3::_bladestop;
                 break;
             case SC_BERSERK:   /* バーサーク */
-                *opt3 &= ~128;
+                *opt3 &= ~Opt3::_berserk;
                 break;
             case SC_MARIONETTE:    /* マリオネットコントロール */
-                *opt3 &= ~1024;
+                *opt3 &= ~Opt3::_marionette;
                 break;
             case SC_ASSUMPTIO: /* アスムプティオ */
-                *opt3 &= ~2048;
+                *opt3 &= ~Opt3::_assumptio;
                 break;
         }
 
-        if (night_flag == 1 && (*opt2 & STATE_BLIND) == 0
+        if (night_flag == 1
+            && !bool(*opt2 & Opt2::BLIND)
             && bl->type == BL_PC)
         {                       // by [Yor]
-            *opt2 |= STATE_BLIND;
+            *opt2 |= Opt2::BLIND;
             opt_flag = 1;
         }
 
@@ -9514,15 +9525,13 @@ int skill_status_change_end(struct block_list *bl, StatusChange type, int tid)
 
 int skill_update_heal_animation(struct map_session_data *sd)
 {
-    const int mask = 0x100;
-    int was_active;
-    int is_active;
+    const Opt2 mask = Opt2::_heal;
 
     nullpo_retr(0, sd);
-    was_active = sd->opt2 & mask;
-    is_active = sd->quick_regeneration_hp.amount > 0;
+    bool was_active = bool(sd->opt2 & mask);
+    bool is_active = sd->quick_regeneration_hp.amount > 0;
 
-    if ((was_active && is_active) || (!was_active && !is_active))
+    if (was_active == is_active)
         return 0;               // no update
 
     if (is_active)
@@ -9744,13 +9753,13 @@ void skill_status_change_timer(timer_id tid, tick_t tick, custom_id_t id, custom
         case SC_STONE:
             if (sc_data[type].val2 != 0)
             {
-                short *opt1 = battle_get_opt1(bl);
+                Opt1 *opt1 = battle_get_opt1(bl);
                 sc_data[type].val2 = 0;
                 sc_data[type].val4 = 0;
                 battle_stopwalking(bl, 1);
                 if (opt1)
                 {
-                    *opt1 = 1;
+                    *opt1 = Opt1::_stone1;
                     clif_changeoption(bl);
                 }
                 sc_data[type].timer =
@@ -10034,7 +10043,11 @@ int skill_status_effect(struct block_list *bl, StatusChange type,
 {
     struct map_session_data *sd = NULL;
     eptr<struct status_change, StatusChange> sc_data;
-    short *sc_count, *option, *opt1, *opt2, *opt3;
+    short *sc_count;
+    Option *option;
+    Opt1 *opt1;
+    Opt2 *opt2;
+    Opt3 *opt3;
     int opt_flag = 0, calc_flag = 0, updateflag =
         0, race, mode, elem, undead_flag;
     int scdef = 0;
@@ -10212,7 +10225,7 @@ int skill_status_effect(struct block_list *bl, StatusChange type,
                 return 0;
             break;
         case SC_TWOHANDQUICKEN:    /* 2HQ */
-            *opt3 |= 1;
+            *opt3 |= Opt3::_concentration;
             calc_flag = 1;
             break;
         case SC_ADRENALINE:    /* アドレナリンラッシュ */
@@ -10223,7 +10236,7 @@ int skill_status_effect(struct block_list *bl, StatusChange type,
                 tick /= 5;
             break;
         case SC_OVERTHRUST:    /* オーバースラスト */
-            *opt3 |= 2;
+            *opt3 |= Opt3::_overthrust;
             if (battle_config.party_skill_penaly && !val2)
                 tick /= 10;
             break;
@@ -10252,7 +10265,7 @@ int skill_status_effect(struct block_list *bl, StatusChange type,
         case SC_AETERNA:       /* エーテルナ */
             break;
         case SC_ENERGYCOAT:    /* エナジーコート */
-            *opt3 |= 4;
+            *opt3 |= Opt3::_energycoat;
             break;
         case SC_MAGICROD:
             val2 = val1 * 20;
@@ -10364,7 +10377,7 @@ int skill_status_effect(struct block_list *bl, StatusChange type,
         case SC_SPEARSQUICKEN: /* スピアクイッケン */
             calc_flag = 1;
             val2 = 20 + val1;
-            *opt3 |= 1;
+            *opt3 |= Opt3::_concentration;
             break;
         case SC_COMBO:
             break;
@@ -10374,7 +10387,7 @@ int skill_status_effect(struct block_list *bl, StatusChange type,
             if (val2 == 2)
                 clif_bladestop((struct block_list *) val3,
                                 (struct block_list *) val4, 1);
-            *opt3 |= 32;
+            *opt3 |= Opt3::_bladestop;
             break;
 
         case SC_LULLABY:       /* 子守唄 */
@@ -10458,11 +10471,11 @@ int skill_status_effect(struct block_list *bl, StatusChange type,
         case SC_EXPLOSIONSPIRITS:  // 爆裂波動
             calc_flag = 1;
             val2 = 75 + 25 * val1;
-            *opt3 |= 8;
+            *opt3 |= Opt3::_explosionspirits;
             break;
         case SC_STEELBODY:     // 金剛
             calc_flag = 1;
-            *opt3 |= 16;
+            *opt3 |= Opt3::_steelbody;
             break;
         case SC_EXTREMITYFIST: /* 阿修羅覇凰拳 */
             break;
@@ -10471,7 +10484,7 @@ int skill_status_effect(struct block_list *bl, StatusChange type,
             break;
 
         case SC_SPEEDPOTION0:  /* 増速ポーション */
-            *opt2 |= 0x20;
+            *opt2 |= Opt2::_speedpotion0;
         case SC_SPEEDPOTION1:
         case SC_SPEEDPOTION2:
             calc_flag = 1;
@@ -10481,7 +10494,7 @@ int skill_status_effect(struct block_list *bl, StatusChange type,
 
             /* atk & matk potions [Valaris] */
         case SC_ATKPOT:
-            *opt2 |= 0x80;
+            *opt2 |= Opt2::_atkpot;
         case SC_MATKPOT:
             calc_flag = 1;
             tick = 1000 * tick;
@@ -10668,7 +10681,7 @@ int skill_status_effect(struct block_list *bl, StatusChange type,
         case SC_HALLUCINATION:
             break;
         case SC_CONCENTRATION: /* コンセントレーション */
-            *opt3 |= 1;
+            *opt3 |= Opt3::_concentration;
             calc_flag = 1;
             break;
         case SC_TENSIONRELAX:  /* テンションリラックス */
@@ -10724,15 +10737,15 @@ int skill_status_effect(struct block_list *bl, StatusChange type,
                 clif_updatestatus(sd, SP_SP);
                 clif_status_change(bl, SC_INCREASEAGI, 1); /* アイコン表示 */
             }
-            *opt3 |= 128;
+            *opt3 |= Opt3::_berserk;
             tick = 1000;
             calc_flag = 1;
             break;
         case SC_ASSUMPTIO:     /* アスムプティオ */
-            *opt3 |= 2048;
+            *opt3 |= Opt3::_assumptio;
             break;
         case SC_MARIONETTE:    /* マリオネットコントロール */
-            *opt3 |= 1024;
+            *opt3 |= Opt3::_marionette;
             break;
         case SC_MELTDOWN:      /* メルトダウン */
         case SC_CARTBOOST:     /* カートブースト */
@@ -10797,64 +10810,68 @@ int skill_status_effect(struct block_list *bl, StatusChange type,
             }
             switch (type)
             {
-            case SC_STONE:  *opt1 = 6; break;
-            case SC_FREEZE: *opt1 = 2; break;
-            case SC_STAN:   *opt1 = 3; break;
-            case SC_SLEEP:  *opt1 = 4; break;
+            case SC_STONE:  *opt1 = Opt1::_stone6; break;
+            case SC_FREEZE: *opt1 = Opt1::_freeze; break;
+            case SC_STAN:   *opt1 = Opt1::_stan; break;
+            case SC_SLEEP:  *opt1 = Opt1::_sleep; break;
             }
             opt_flag = 1;
             break;
         case SC_POISON:
             if (sc_data[SC_SLOWPOISON].timer == -1)
             {
-                *opt2 |= 0x1;
+                *opt2 |= Opt2::_poison;
                 opt_flag = 1;
             }
             break;
 
         case SC_CURSE:
-            *opt2 |= 0x0002;
+            *opt2 |= Opt2::_curse;
             opt_flag = 1;
             break;
         case SC_SILENCE:
-            *opt2 |= 0x0004;
+            *opt2 |= Opt2::_silence;
             opt_flag = 1;
             break;
         case SC_BLIND:
-            *opt2 |= 0x0010;
+            *opt2 |= Opt2::BLIND;
             opt_flag = 1;
             break;
 
         case SC_SLOWPOISON:
-            *opt2 &= ~0x1;
-            *opt2 |= 0x200;
+            *opt2 &= ~Opt2::_poison;
+            *opt2 |= Opt2::_slowpoison;
             opt_flag = 1;
             break;
         case SC_SIGNUMCRUCIS:
-            *opt2 |= 0x40;
+            *opt2 |= Opt2::_signumcrucis;
             opt_flag = 1;
             break;
         case SC_HIDING:
+            battle_stopattack(bl); /* 攻撃停止 */
+            *option |= Option::HIDE2;
+            opt_flag = 1;
+            break;
         case SC_CLOAKING:
             battle_stopattack(bl); /* 攻撃停止 */
-            *option |= ((type == SC_HIDING) ? 2 : 4);
+            *option |= Option::CLOAK;
             opt_flag = 1;
             break;
         case SC_CHASEWALK:
             battle_stopattack(bl); /* 攻撃停止 */
-            *option |= 16388;
+            *option |= Option::CHASEWALK | Option::CLOAK;
             opt_flag = 1;
             break;
         case SC_SIGHT:
-            *option |= 1;
+            *option |= Option::SIGHT;
             opt_flag = 1;
             break;
         case SC_RUWACH:
-            *option |= 8192;
+            *option |= Option::_ruwach;
             opt_flag = 1;
             break;
         case SC_WEDDING:
-            *option |= 4096;
+            *option |= Option::_wedding;
             opt_flag = 1;
     }
 
@@ -10894,7 +10911,11 @@ int skill_status_effect(struct block_list *bl, StatusChange type,
 int skill_status_change_clear(struct block_list *bl, int type)
 {
     eptr<struct status_change, StatusChange> sc_data;
-    short *sc_count, *option, *opt1, *opt2, *opt3;
+    short *sc_count;
+    Option *option;
+    Opt1 *opt1;
+    Opt2 *opt2;
+    Opt3 *opt3;
 
     nullpo_retr(0, bl);
     sc_data = battle_get_sc_data(bl);
@@ -10924,13 +10945,13 @@ int skill_status_change_clear(struct block_list *bl, int type)
         }
     }
     *sc_count = 0;
-    *opt1 = 0;
-    *opt2 = 0;
-    *opt3 = 0;
-    *option &= OPTION_MASK;
+    *opt1 = Opt1::ZERO;
+    *opt2 = Opt2::ZERO;
+    *opt3 = Opt3::ZERO;
+    *option &= Option::MASK;
 
     if (night_flag == 1 && type == BL_PC)   // by [Yor]
-        *opt2 |= STATE_BLIND;
+        *opt2 |= Opt2::BLIND;
 
     if (!type || type & 2)
         clif_changeoption(bl);
@@ -10963,7 +10984,7 @@ int skill_check_cloaking(struct block_list *bl)
     if (end)
     {
         skill_status_change_end(bl, SC_CLOAKING, -1);
-        *battle_get_option(bl) &= ~4;  /* 念のための処理 */
+        *battle_get_option(bl) &= ~Option::CLOAK;  /* 念のための処理 */
     }
     return end;
 }
-- 
cgit v1.2.3-70-g09d2