Core/Util: Redesign SmartEnum to properly work for large enums (>64 entries) and play nice with IDEs (PR #22768)

This commit is contained in:
Treeston
2018-11-11 17:52:41 +01:00
committed by GitHub
parent be47254a4f
commit c16d461e16
15 changed files with 1897 additions and 1060 deletions

View File

@@ -45,145 +45,6 @@ EndScriptData */
#include <boost/core/demangle.hpp>
#include <typeinfo>
template<typename E, typename T = char const*>
struct EnumName
{
E Value;
T Name;
};
#define CREATE_NAMED_ENUM(VALUE) { VALUE, STRINGIZE(VALUE) }
EnumName<NPCFlags, int32> const npcFlagTexts[] =
{
{ UNIT_NPC_FLAG_AUCTIONEER, LANG_NPCINFO_AUCTIONEER },
{ UNIT_NPC_FLAG_BANKER, LANG_NPCINFO_BANKER },
{ UNIT_NPC_FLAG_BATTLEMASTER, LANG_NPCINFO_BATTLEMASTER },
{ UNIT_NPC_FLAG_FLIGHTMASTER, LANG_NPCINFO_FLIGHTMASTER },
{ UNIT_NPC_FLAG_GOSSIP, LANG_NPCINFO_GOSSIP },
{ UNIT_NPC_FLAG_GUILD_BANKER, LANG_NPCINFO_GUILD_BANKER },
{ UNIT_NPC_FLAG_INNKEEPER, LANG_NPCINFO_INNKEEPER },
{ UNIT_NPC_FLAG_PETITIONER, LANG_NPCINFO_PETITIONER },
{ UNIT_NPC_FLAG_PLAYER_VEHICLE, LANG_NPCINFO_PLAYER_VEHICLE },
{ UNIT_NPC_FLAG_QUESTGIVER, LANG_NPCINFO_QUESTGIVER },
{ UNIT_NPC_FLAG_REPAIR, LANG_NPCINFO_REPAIR },
{ UNIT_NPC_FLAG_SPELLCLICK, LANG_NPCINFO_SPELLCLICK },
{ UNIT_NPC_FLAG_SPIRITGUIDE, LANG_NPCINFO_SPIRITGUIDE },
{ UNIT_NPC_FLAG_SPIRITHEALER, LANG_NPCINFO_SPIRITHEALER },
{ UNIT_NPC_FLAG_STABLEMASTER, LANG_NPCINFO_STABLEMASTER },
{ UNIT_NPC_FLAG_TABARDDESIGNER, LANG_NPCINFO_TABARDDESIGNER },
{ UNIT_NPC_FLAG_TRAINER, LANG_NPCINFO_TRAINER },
{ UNIT_NPC_FLAG_TRAINER_CLASS, LANG_NPCINFO_TRAINER_CLASS },
{ UNIT_NPC_FLAG_TRAINER_PROFESSION, LANG_NPCINFO_TRAINER_PROFESSION },
{ UNIT_NPC_FLAG_VENDOR, LANG_NPCINFO_VENDOR },
{ UNIT_NPC_FLAG_VENDOR_AMMO, LANG_NPCINFO_VENDOR_AMMO },
{ UNIT_NPC_FLAG_VENDOR_FOOD, LANG_NPCINFO_VENDOR_FOOD },
{ UNIT_NPC_FLAG_VENDOR_POISON, LANG_NPCINFO_VENDOR_POISON },
{ UNIT_NPC_FLAG_VENDOR_REAGENT, LANG_NPCINFO_VENDOR_REAGENT }
};
uint32 const NPCFLAG_COUNT = std::extent<decltype(npcFlagTexts)>::value;
EnumName<Mechanics> const mechanicImmunes[MAX_MECHANIC] =
{
CREATE_NAMED_ENUM(MECHANIC_NONE),
CREATE_NAMED_ENUM(MECHANIC_CHARM),
CREATE_NAMED_ENUM(MECHANIC_DISORIENTED),
CREATE_NAMED_ENUM(MECHANIC_DISARM),
CREATE_NAMED_ENUM(MECHANIC_DISTRACT),
CREATE_NAMED_ENUM(MECHANIC_FEAR),
CREATE_NAMED_ENUM(MECHANIC_GRIP),
CREATE_NAMED_ENUM(MECHANIC_ROOT),
CREATE_NAMED_ENUM(MECHANIC_SLOW_ATTACK),
CREATE_NAMED_ENUM(MECHANIC_SILENCE),
CREATE_NAMED_ENUM(MECHANIC_SLEEP),
CREATE_NAMED_ENUM(MECHANIC_SNARE),
CREATE_NAMED_ENUM(MECHANIC_STUN),
CREATE_NAMED_ENUM(MECHANIC_FREEZE),
CREATE_NAMED_ENUM(MECHANIC_KNOCKOUT),
CREATE_NAMED_ENUM(MECHANIC_BLEED),
CREATE_NAMED_ENUM(MECHANIC_BANDAGE),
CREATE_NAMED_ENUM(MECHANIC_POLYMORPH),
CREATE_NAMED_ENUM(MECHANIC_BANISH),
CREATE_NAMED_ENUM(MECHANIC_SHIELD),
CREATE_NAMED_ENUM(MECHANIC_SHACKLE),
CREATE_NAMED_ENUM(MECHANIC_MOUNT),
CREATE_NAMED_ENUM(MECHANIC_INFECTED),
CREATE_NAMED_ENUM(MECHANIC_TURN),
CREATE_NAMED_ENUM(MECHANIC_HORROR),
CREATE_NAMED_ENUM(MECHANIC_INVULNERABILITY),
CREATE_NAMED_ENUM(MECHANIC_INTERRUPT),
CREATE_NAMED_ENUM(MECHANIC_DAZE),
CREATE_NAMED_ENUM(MECHANIC_DISCOVERY),
CREATE_NAMED_ENUM(MECHANIC_IMMUNE_SHIELD),
CREATE_NAMED_ENUM(MECHANIC_SAPPED),
CREATE_NAMED_ENUM(MECHANIC_ENRAGED)
};
EnumName<UnitFlags> const unitFlags[MAX_UNIT_FLAGS] =
{
CREATE_NAMED_ENUM(UNIT_FLAG_SERVER_CONTROLLED),
CREATE_NAMED_ENUM(UNIT_FLAG_NON_ATTACKABLE),
CREATE_NAMED_ENUM(UNIT_FLAG_REMOVE_CLIENT_CONTROL),
CREATE_NAMED_ENUM(UNIT_FLAG_PLAYER_CONTROLLED),
CREATE_NAMED_ENUM(UNIT_FLAG_RENAME),
CREATE_NAMED_ENUM(UNIT_FLAG_PREPARATION),
CREATE_NAMED_ENUM(UNIT_FLAG_UNK_6),
CREATE_NAMED_ENUM(UNIT_FLAG_NOT_ATTACKABLE_1),
CREATE_NAMED_ENUM(UNIT_FLAG_IMMUNE_TO_PC),
CREATE_NAMED_ENUM(UNIT_FLAG_IMMUNE_TO_NPC),
CREATE_NAMED_ENUM(UNIT_FLAG_LOOTING),
CREATE_NAMED_ENUM(UNIT_FLAG_PET_IN_COMBAT),
CREATE_NAMED_ENUM(UNIT_FLAG_PVP),
CREATE_NAMED_ENUM(UNIT_FLAG_SILENCED),
CREATE_NAMED_ENUM(UNIT_FLAG_CANNOT_SWIM),
CREATE_NAMED_ENUM(UNIT_FLAG_UNK_15),
CREATE_NAMED_ENUM(UNIT_FLAG_NON_ATTACKABLE_2),
CREATE_NAMED_ENUM(UNIT_FLAG_PACIFIED),
CREATE_NAMED_ENUM(UNIT_FLAG_STUNNED),
CREATE_NAMED_ENUM(UNIT_FLAG_IN_COMBAT),
CREATE_NAMED_ENUM(UNIT_FLAG_TAXI_FLIGHT),
CREATE_NAMED_ENUM(UNIT_FLAG_DISARMED),
CREATE_NAMED_ENUM(UNIT_FLAG_CONFUSED),
CREATE_NAMED_ENUM(UNIT_FLAG_FLEEING),
CREATE_NAMED_ENUM(UNIT_FLAG_POSSESSED),
CREATE_NAMED_ENUM(UNIT_FLAG_NOT_SELECTABLE),
CREATE_NAMED_ENUM(UNIT_FLAG_SKINNABLE),
CREATE_NAMED_ENUM(UNIT_FLAG_MOUNT),
CREATE_NAMED_ENUM(UNIT_FLAG_UNK_28),
CREATE_NAMED_ENUM(UNIT_FLAG_UNK_29),
CREATE_NAMED_ENUM(UNIT_FLAG_SHEATHE),
CREATE_NAMED_ENUM(UNIT_FLAG_UNK_31)
};
EnumName<CreatureFlagsExtra> const flagsExtra[] =
{
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_INSTANCE_BIND),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_CIVILIAN),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_PARRY),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_PARRY_HASTEN),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_BLOCK),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_CRUSH),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_XP_AT_KILL),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_TRIGGER),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_TAUNT),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_SELL_VENDOR),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_WORLDEVENT),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_GUARD),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_CRIT),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_SKILLGAIN),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_TAUNT_DIMINISH),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_ALL_DIMINISH),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_DUNGEON_BOSS),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK),
CREATE_NAMED_ENUM(CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK)
};
uint32 const FLAGS_EXTRA_COUNT = std::extent<decltype(flagsExtra)>::value;
bool HandleNpcSpawnGroup(ChatHandler* handler, char const* args)
{
if (!*args)
@@ -801,9 +662,9 @@ public:
handler->PSendSysMessage(LANG_NPCINFO_MOVEMENT_DATA, target->GetMovementTemplate().ToString().c_str());
handler->PSendSysMessage(LANG_NPCINFO_UNIT_FIELD_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS));
for (uint8 i = 0; i < MAX_UNIT_FLAGS; ++i)
if (target->GetUInt32Value(UNIT_FIELD_FLAGS) & unitFlags[i].Value)
handler->PSendSysMessage("%s (0x%X)", unitFlags[i].Name, unitFlags[i].Value);
for (UnitFlags flag : EnumUtils::Iterate<UnitFlags>())
if (target->GetUInt32Value(UNIT_FIELD_FLAGS) & flag)
handler->PSendSysMessage("* %s (0x%X)", EnumUtils::ToTitle(flag), flag);
handler->PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS_2), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->GetFaction());
handler->PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(), curRespawnDelayStr.c_str());
@@ -817,18 +678,18 @@ public:
if (CreatureAI const* ai = target->AI())
handler->PSendSysMessage(LANG_OBJECTINFO_AITYPE, boost::core::demangle(typeid(*ai).name()).c_str());
handler->PSendSysMessage(LANG_NPCINFO_FLAGS_EXTRA, cInfo->flags_extra);
for (uint8 i = 0; i < FLAGS_EXTRA_COUNT; ++i)
if (cInfo->flags_extra & flagsExtra[i].Value)
handler->PSendSysMessage("%s (0x%X)", flagsExtra[i].Name, flagsExtra[i].Value);
for (CreatureFlagsExtra flag : EnumUtils::Iterate<CreatureFlagsExtra>())
if (cInfo->flags_extra & flag)
handler->PSendSysMessage("* %s (0x%X)", EnumUtils::ToTitle(flag), flag);
for (uint8 i = 0; i < NPCFLAG_COUNT; i++)
if (npcflags & npcFlagTexts[i].Value)
handler->PSendSysMessage(npcFlagTexts[i].Name, npcFlagTexts[i].Value);
for (NPCFlags flag : EnumUtils::Iterate<NPCFlags>())
if (npcflags & flag)
handler->PSendSysMessage("* %s (0x%X)", EnumUtils::ToTitle(flag), flag);
handler->PSendSysMessage(LANG_NPCINFO_MECHANIC_IMMUNE, mechanicImmuneMask);
for (uint8 i = 1; i < MAX_MECHANIC; ++i)
if (mechanicImmuneMask & (1 << (mechanicImmunes[i].Value - 1)))
handler->PSendSysMessage("%s (0x%X)", mechanicImmunes[i].Name, mechanicImmunes[i].Value);
for (Mechanics m : EnumUtils::Iterate<Mechanics>())
if (m && (mechanicImmuneMask & (1 << (m-1))))
handler->PSendSysMessage("* %s (0x%X)", EnumUtils::ToTitle(m), m);
return true;
}