#ifndef MAP_T_HPP #define MAP_T_HPP #include "../common/mmo.hpp" #include "../common/utils2.hpp" namespace e { // [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, // [Fate] This is the GM `@hide' flag HIDE = 0x0040, // [Fate] Complete invisibility to other clients INVISIBILITY = 0x1000, // ? REAL_ANY_HIDE = HIDE, }; 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, }; enum class Opt3 : uint16_t { ZERO = 0x0000, _concentration = 0x0001, _overthrust = 0x0002, _energycoat = 0x0004, _explosionspirits = 0x0008, _steelbody = 0x0010, _berserk = 0x0080, _marionette = 0x0400, _assumptio = 0x0800, }; ENUM_BITWISE_OPERATORS(Option) ENUM_BITWISE_OPERATORS(Opt2) ENUM_BITWISE_OPERATORS(Opt3) } using e::Option; using e::Opt1; using e::Opt2; using e::Opt3; enum class BL : uint8_t { NUL, #define BL_NUL BL::NUL PC, #define BL_PC BL::PC NPC, #define BL_NPC BL::NPC MOB, #define BL_MOB BL::MOB ITEM, #define BL_ITEM BL::ITEM CHAT, #define BL_CHAT BL::CHAT SPELL, #define BL_SPELL BL::SPELL }; enum class NpcSubtype : uint8_t { WARP, #define WARP NpcSubtype::WARP SHOP, #define SHOP NpcSubtype::SHOP SCRIPT, #define SCRIPT NpcSubtype::SCRIPT MONS, #define MONS NpcSubtype::MONS MESSAGE, #define MESSAGE NpcSubtype::MESSAGE }; enum class mob_stat { LV, #define MOB_LV mob_stat::LV MAX_HP, #define MOB_MAX_HP mob_stat::MAX_HP STR, #define MOB_STR mob_stat::STR AGI, #define MOB_AGI mob_stat::AGI VIT, #define MOB_VIT mob_stat::VIT INT, #define MOB_INT mob_stat::INT DEX, #define MOB_DEX mob_stat::DEX LUK, #define MOB_LUK mob_stat::LUK // low and high attacks ATK1, #define MOB_ATK1 mob_stat::ATK1 ATK2, #define MOB_ATK2 mob_stat::ATK2 // attack delay ADELAY, #define MOB_ADELAY mob_stat::ADELAY DEF, #define MOB_DEF mob_stat::DEF MDEF, #define MOB_MDEF mob_stat::MDEF SPEED, #define MOB_SPEED mob_stat::SPEED // These must come last: // [Fate] Encoded as base to 1024: 1024 means 100% XP_BONUS, #define MOB_XP_BONUS mob_stat::XP_BONUS LAST, #define MOB_LAST mob_stat::LAST }; enum class MS : uint8_t { IDLE, #define MS_IDLE MS::IDLE WALK, #define MS_WALK MS::WALK ATTACK, #define MS_ATTACK MS::ATTACK DEAD, #define MS_DEAD MS::DEAD DELAY, #define MS_DELAY MS::DELAY }; enum class ATK { ZERO = 0, LUCKY, #define ATK_LUCKY ATK::LUCKY FLEE, #define ATK_FLEE ATK::FLEE DEF, #define ATK_DEF ATK::DEF }; enum class SP : uint16_t { // sent to client SPEED = 0, #define SP_SPEED SP::SPEED // when used as "no stat" ZERO = 0, // sent to client BASEEXP = 1, #define SP_BASEEXP SP::BASEEXP // sent to client JOBEXP = 2, #define SP_JOBEXP SP::JOBEXP #if 0 KARMA = 3, #define SP_KARMA SP::KARMA #endif // sent to client HP = 5, #define SP_HP SP::HP // sent to client MAXHP = 6, #define SP_MAXHP SP::MAXHP // sent to client SP = 7, #define SP_SP SP::SP // sent to client MAXSP = 8, #define SP_MAXSP SP::MAXSP // sent to client STATUSPOINT = 9, #define SP_STATUSPOINT SP::STATUSPOINT // sent to client BASELEVEL = 11, #define SP_BASELEVEL SP::BASELEVEL // sent to client SKILLPOINT = 12, #define SP_SKILLPOINT SP::SKILLPOINT // sent to client STR = 13, #define SP_STR SP::STR // sent to client AGI = 14, #define SP_AGI SP::AGI // sent to client VIT = 15, #define SP_VIT SP::VIT // sent to client INT = 16, #define SP_INT SP::INT // sent to client DEX = 17, #define SP_DEX SP::DEX // sent to client LUK = 18, #define SP_LUK SP::LUK CLASS = 19, #define SP_CLASS SP::CLASS // sent to client ZENY = 20, #define SP_ZENY SP::ZENY SEX = 21, #define SP_SEX SP::SEX // sent to client NEXTBASEEXP = 22, #define SP_NEXTBASEEXP SP::NEXTBASEEXP // sent to client NEXTJOBEXP = 23, #define SP_NEXTJOBEXP SP::NEXTJOBEXP // sent to client WEIGHT = 24, #define SP_WEIGHT SP::WEIGHT // sent to client MAXWEIGHT = 25, #define SP_MAXWEIGHT SP::MAXWEIGHT // sent to client USTR = 32, #define SP_USTR SP::USTR // sent to client UAGI = 33, #define SP_UAGI SP::UAGI // sent to client UVIT = 34, #define SP_UVIT SP::UVIT // sent to client UINT = 35, #define SP_UINT SP::UINT // sent to client UDEX = 36, #define SP_UDEX SP::UDEX // sent to client ULUK = 37, #define SP_ULUK SP::ULUK // sent to client ATK1 = 41, #define SP_ATK1 SP::ATK1 // sent to client ATK2 = 42, #define SP_ATK2 SP::ATK2 // sent to client MATK1 = 43, #define SP_MATK1 SP::MATK1 // sent to client MATK2 = 44, #define SP_MATK2 SP::MATK2 // sent to client DEF1 = 45, #define SP_DEF1 SP::DEF1 // sent to client DEF2 = 46, #define SP_DEF2 SP::DEF2 // sent to client MDEF1 = 47, #define SP_MDEF1 SP::MDEF1 // sent to client MDEF2 = 48, #define SP_MDEF2 SP::MDEF2 // sent to client HIT = 49, #define SP_HIT SP::HIT // sent to client FLEE1 = 50, #define SP_FLEE1 SP::FLEE1 // sent to client FLEE2 = 51, #define SP_FLEE2 SP::FLEE2 // sent to client CRITICAL = 52, #define SP_CRITICAL SP::CRITICAL // sent to client ASPD = 53, #define SP_ASPD SP::ASPD // sent to client JOBLEVEL = 55, #define SP_JOBLEVEL SP::JOBLEVEL #if 0 PARTNER = 57, #define SP_PARTNER SP::PARTNER CART = 58, #define SP_CART SP::CART FAME = 59, #define SP_FAME SP::FAME UNBREAKABLE = 60, #define SP_UNBREAKABLE SP::UNBREAKABLE #endif DEAF = 70, #define SP_DEAF SP::DEAF // sent to client GM = 500, #define SP_GM SP::GM // sent to client ATTACKRANGE = 1000, #define SP_ATTACKRANGE SP::ATTACKRANGE #if 0 ATKELE = 1001, #define SP_ATKELE SP::ATKELE #endif #if 0 DEFELE = 1002, #define SP_DEFELE SP::DEFELE #endif #if 0 CASTRATE = 1003, #define SP_CASTRATE SP::CASTRATE #endif MAXHPRATE = 1004, #define SP_MAXHPRATE SP::MAXHPRATE #if 0 MAXSPRATE = 1005, #define SP_MAXSPRATE SP::MAXSPRATE #endif #if 0 SPRATE = 1006, #define SP_SPRATE SP::SPRATE #endif #if 0 ADDEFF = 1012, #define SP_ADDEFF SP::ADDEFF #endif #if 0 RESEFF = 1013, #define SP_RESEFF SP::RESEFF #endif BASE_ATK = 1014, #define SP_BASE_ATK SP::BASE_ATK ASPD_RATE = 1015, #define SP_ASPD_RATE SP::ASPD_RATE HP_RECOV_RATE = 1016, #define SP_HP_RECOV_RATE SP::HP_RECOV_RATE #if 0 SP_RECOV_RATE = 1017, #define SP_SP_RECOV_RATE SP::SP_RECOV_RATE #endif #if 0 SPEED_RATE = 1018, #define SP_SPEED_RATE SP::SPEED_RATE #endif #if 0 CRITICAL_DEF = 1019, #define SP_CRITICAL_DEF SP::CRITICAL_DEF #endif #if 0 NEAR_ATK_DEF = 1020, #define SP_NEAR_ATK_DEF SP::NEAR_ATK_DEF #endif #if 0 LONG_ATK_DEF = 1021, #define SP_LONG_ATK_DEF SP::LONG_ATK_DEF #endif #if 0 DOUBLE_RATE = 1022, #define SP_DOUBLE_RATE SP::DOUBLE_RATE #endif DOUBLE_ADD_RATE = 1023, #define SP_DOUBLE_ADD_RATE SP::DOUBLE_ADD_RATE #if 0 MATK = 1024, #define SP_MATK SP::MATK #endif #if 0 MATK_RATE = 1025, #define SP_MATK_RATE SP::MATK_RATE #endif #if 0 IGNORE_DEF_ELE = 1026, #define SP_IGNORE_DEF_ELE SP::IGNORE_DEF_ELE #endif #if 0 IGNORE_DEF_RACE = 1027, #define SP_IGNORE_DEF_RACE SP::IGNORE_DEF_RACE #endif #if 0 ATK_RATE = 1028, #define SP_ATK_RATE SP::ATK_RATE #endif SPEED_ADDRATE = 1029, #define SP_SPEED_ADDRATE SP::SPEED_ADDRATE #if 0 ASPD_ADDRATE = 1030, #define SP_ASPD_ADDRATE SP::ASPD_ADDRATE #endif #if 0 MAGIC_ATK_DEF = 1031, #define SP_MAGIC_ATK_DEF SP::MAGIC_ATK_DEF #endif #if 0 MISC_ATK_DEF = 1032, #define SP_MISC_ATK_DEF SP::MISC_ATK_DEF #endif #if 0 IGNORE_MDEF_ELE = 1033, #define SP_IGNORE_MDEF_ELE SP::IGNORE_MDEF_ELE #endif #if 0 IGNORE_MDEF_RACE = 1034, #define SP_IGNORE_MDEF_RACE SP::IGNORE_MDEF_RACE #endif #if 0 PERFECT_HIT_RATE = 1038, #define SP_PERFECT_HIT_RATE SP::PERFECT_HIT_RATE #endif #if 0 PERFECT_HIT_ADD_RATE = 1039, #define SP_PERFECT_HIT_ADD_RATE SP::PERFECT_HIT_ADD_RATE #endif #if 0 CRITICAL_RATE = 1040, #define SP_CRITICAL_RATE SP::CRITICAL_RATE #endif #if 0 GET_ZENY_NUM = 1041, #define SP_GET_ZENY_NUM SP::GET_ZENY_NUM #endif #if 0 ADD_GET_ZENY_NUM = 1042, #define SP_ADD_GET_ZENY_NUM SP::ADD_GET_ZENY_NUM #endif #if 0 ADD_MONSTER_DROP_ITEM = 1047, #define SP_ADD_MONSTER_DROP_ITEM SP::ADD_MONSTER_DROP_ITEM #endif #if 0 DEF_RATIO_ATK_ELE = 1048, #define SP_DEF_RATIO_ATK_ELE SP::DEF_RATIO_ATK_ELE #endif #if 0 DEF_RATIO_ATK_RACE = 1049, #define SP_DEF_RATIO_ATK_RACE SP::DEF_RATIO_ATK_RACE #endif #if 0 ADD_SPEED = 1050, #define SP_ADD_SPEED SP::ADD_SPEED #endif #if 0 HIT_RATE = 1051, #define SP_HIT_RATE SP::HIT_RATE #endif #if 0 FLEE_RATE = 1052, #define SP_FLEE_RATE SP::FLEE_RATE #endif #if 0 FLEE2_RATE = 1053, #define SP_FLEE2_RATE SP::FLEE2_RATE #endif DEF_RATE = 1054, #define SP_DEF_RATE SP::DEF_RATE DEF2_RATE = 1055, #define SP_DEF2_RATE SP::DEF2_RATE #if 0 MDEF_RATE = 1056, #define SP_MDEF_RATE SP::MDEF_RATE #endif #if 0 MDEF2_RATE = 1057, #define SP_MDEF2_RATE SP::MDEF2_RATE #endif #if 0 SPLASH_RANGE = 1058, #define SP_SPLASH_RANGE SP::SPLASH_RANGE #endif #if 0 SPLASH_ADD_RANGE = 1059, #define SP_SPLASH_ADD_RANGE SP::SPLASH_ADD_RANGE #endif HP_DRAIN_RATE = 1061, #define SP_HP_DRAIN_RATE SP::HP_DRAIN_RATE #if 0 SP_DRAIN_RATE = 1062, #define SP_SP_DRAIN_RATE SP::SP_DRAIN_RATE #endif #if 0 SHORT_WEAPON_DAMAGE_RETURN = 1063, #define SP_SHORT_WEAPON_DAMAGE_RETURN SP::SHORT_WEAPON_DAMAGE_RETURN #endif #if 0 LONG_WEAPON_DAMAGE_RETURN = 1064, #define SP_LONG_WEAPON_DAMAGE_RETURN SP::LONG_WEAPON_DAMAGE_RETURN #endif #if 0 ADDEFF2 = 1067, #define SP_ADDEFF2 SP::ADDEFF2 #endif BREAK_WEAPON_RATE = 1068, #define SP_BREAK_WEAPON_RATE SP::BREAK_WEAPON_RATE BREAK_ARMOR_RATE = 1069, #define SP_BREAK_ARMOR_RATE SP::BREAK_ARMOR_RATE ADD_STEAL_RATE = 1070, #define SP_ADD_STEAL_RATE SP::ADD_STEAL_RATE MAGIC_DAMAGE_RETURN = 1071, #define SP_MAGIC_DAMAGE_RETURN SP::MAGIC_DAMAGE_RETURN #if 0 RANDOM_ATTACK_INCREASE = 1072, #define SP_RANDOM_ATTACK_INCREASE SP::RANDOM_ATTACK_INCREASE #endif }; constexpr SP attr_to_sp(ATTR attr) { return SP(uint16_t(attr) + uint16_t(SP::STR)); } constexpr ATTR sp_to_attr(SP sp) { return ATTR(uint16_t(sp) - uint16_t(SP::STR)); } constexpr SP attr_to_usp(ATTR attr) { return SP(uint16_t(attr) + uint16_t(SP::USTR)); } constexpr ATTR usp_to_attr(SP sp) { return ATTR(uint16_t(sp) - uint16_t(SP::USTR)); } constexpr SP sp_to_usp(SP sp) { return attr_to_usp(sp_to_attr(sp)); } constexpr SP usp_to_sp(SP sp) { return attr_to_sp(usp_to_attr(sp)); } enum class LOOK : uint8_t { BASE = 0, #define LOOK_BASE LOOK::BASE HAIR = 1, #define LOOK_HAIR LOOK::HAIR WEAPON = 2, #define LOOK_WEAPON LOOK::WEAPON HEAD_BOTTOM = 3, #define LOOK_HEAD_BOTTOM LOOK::HEAD_BOTTOM HEAD_TOP = 4, #define LOOK_HEAD_TOP LOOK::HEAD_TOP HEAD_MID = 5, #define LOOK_HEAD_MID LOOK::HEAD_MID HAIR_COLOR = 6, #define LOOK_HAIR_COLOR LOOK::HAIR_COLOR CLOTHES_COLOR = 7, #define LOOK_CLOTHES_COLOR LOOK::CLOTHES_COLOR SHIELD = 8, #define LOOK_SHIELD LOOK::SHIELD SHOES = 9, #define LOOK_SHOES LOOK::SHOES GLOVES = 10, #define LOOK_GLOVES LOOK::GLOVES CAPE = 11, #define LOOK_CAPE LOOK::CAPE MISC1 = 12, #define LOOK_MISC1 LOOK::MISC1 MISC2 = 13, #define LOOK_MISC2 LOOK::MISC2 COUNT, }; enum class EQUIP { NONE = -1, MISC2 = 0, CAPE = 1, SHOES = 2, GLOVES = 3, LEGS = 4, // also called "head bottom" TORSO = 5, // also called "head middle" HAT = 6, // also called "head top" MISC1 = 7, SHIELD = 8, #define EQUIP_SHIELD EQUIP::SHIELD WEAPON = 9, #define EQUIP_WEAPON EQUIP::WEAPON ARROW = 10, COUNT = 11, }; constexpr EQUIP EQUIPs[] = { EQUIP::MISC2, EQUIP::CAPE, EQUIP::SHOES, EQUIP::GLOVES, EQUIP::LEGS, EQUIP::TORSO, EQUIP::HAT, EQUIP::MISC1, EQUIP::SHIELD, EQUIP::WEAPON, EQUIP::ARROW, }; constexpr EQUIP EQUIPs_noarrow[] = { EQUIP::MISC2, EQUIP::CAPE, EQUIP::SHOES, EQUIP::GLOVES, EQUIP::LEGS, EQUIP::TORSO, EQUIP::HAT, EQUIP::MISC1, EQUIP::SHIELD, EQUIP::WEAPON, }; enum class ItemType : uint8_t { USE = 0, // in eA, healing only _1 = 1, // unused _2 = 2, // in eA, other usable items JUNK = 3, // "useless" items (e.g. quests) WEAPON = 4, // all weapons ARMOR = 5, // all other equipment _6 = 6, // in eA, card _7 = 7, // in eA, pet egg _8 = 8, // in eA, pet equipment _9 = 9, // unused ARROW = 10, // ammo _11 = 11, // in eA, delayed use (special script) }; namespace e { enum class MobMode : uint16_t { ZERO = 0x0000, CAN_MOVE = 0x0001, LOOTER = 0x0002, AGGRESSIVE = 0x0004, ASSIST = 0x0008, CAST_SENSOR = 0x0010, BOSS = 0x0020, // sometimes also called "robust" PLANT = 0x0040, CAN_ATTACK = 0x0080, DETECTOR = 0x0100, CHANGE_TARGET = 0x0200, war = CAN_MOVE | AGGRESSIVE | CAN_ATTACK, SUMMONED = 0x1000, #define MOB_MODE_SUMMONED MobMode::SUMMONED TURNS_AGAINST_BAD_MASTER = 0x2000, #define MOB_MODE_TURNS_AGAINST_BAD_MASTER MobMode::TURNS_AGAINST_BAD_MASTER // mob mode flags that Fate actually understood SENSIBLE_MASK = 0xf000, #define MOB_SENSIBLE_MASK MobMode::SENSIBLE_MASK }; ENUM_BITWISE_OPERATORS(MobMode) } using e::MobMode; #endif // MAP_T_HPP