diff --git a/3rdParty/magic_enum/CMakeLists.txt b/3rdParty/magic_enum/CMakeLists.txt new file mode 100644 index 000000000..ba6e51ddf --- /dev/null +++ b/3rdParty/magic_enum/CMakeLists.txt @@ -0,0 +1,8 @@ +include(functions/FetchContent_ExcludeFromAll_backport) +include(FetchContent) + +FetchContent_Declare_ExcludeFromAll(magic_enum + URL https://github.com/Neargye/magic_enum/archive/refs/tags/v0.9.7.tar.gz + URL_HASH MD5=5afd218c48c3f7cf094889a182842a50 +) +FetchContent_MakeAvailable_ExcludeFromAll(magic_enum) diff --git a/Brewfile b/Brewfile index e83c1a1f3..d2b950ad7 100644 --- a/Brewfile +++ b/Brewfile @@ -5,3 +5,4 @@ brew "libsodium" brew "pkg-config" brew "googletest" brew "google-benchmark" +brew "magic_enum" diff --git a/CMake/Dependencies.cmake b/CMake/Dependencies.cmake index 004f8059e..788bcc6c0 100644 --- a/CMake/Dependencies.cmake +++ b/CMake/Dependencies.cmake @@ -236,6 +236,22 @@ else() add_subdirectory(3rdParty/unordered_dense) endif() +if(NOT DEFINED DEVILUTIONX_SYSTEM_MAGIC_ENUM) + find_package(magic_enum 0.9.7 QUIET) + if(magic_enum_FOUND) + message("-- Found magic_enum ${magic_enum_VERSION}") + else() + message("-- Suitable system magic_enum package not found, will use magic_enum from source") + set(DEVILUTIONX_SYSTEM_MAGIC_ENUM OFF) + endif() +endif() +dependency_options("magic_enum" DEVILUTIONX_SYSTEM_MAGIC_ENUM ON DEVILUTIONX_STATIC_MAGIC_ENUM) +if(DEVILUTIONX_SYSTEM_MAGIC_ENUM) + find_package(magic_enum REQUIRED) +else() + add_subdirectory(3rdParty/magic_enum) +endif() + if(SUPPORTS_MPQ OR NOT NONET) add_subdirectory(3rdParty/PKWare) endif() diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index ed72d6168..bc3a1a594 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -526,6 +526,7 @@ add_devilutionx_object_library(libdevilutionx_monster target_link_dependencies(libdevilutionx_monster PUBLIC DevilutionX::SDL + magic_enum::magic_enum sol2::sol2 tl libdevilutionx_game_mode @@ -854,6 +855,7 @@ target_link_dependencies(libdevilutionx PUBLIC fmt::fmt libsmackerdec ${LUA_LIBRARIES} + magic_enum::magic_enum sol2::sol2 tl unordered_dense::unordered_dense diff --git a/Source/monstdat.cpp b/Source/monstdat.cpp index 58a65767d..74af6b458 100644 --- a/Source/monstdat.cpp +++ b/Source/monstdat.cpp @@ -8,6 +8,7 @@ #include #include +#include #include "cursor.h" #include "data/file.hpp" @@ -18,6 +19,12 @@ #include "textdat.h" #include "utils/language.h" +template <> +struct magic_enum::customize::enum_range { + static constexpr int min = devilution::MT_INVALID; + static constexpr int max = devilution::NUM_MTYPES; +}; + namespace devilution { namespace { @@ -208,163 +215,10 @@ const _monster_id MonstConvTbl[] = { tl::expected<_monster_id, std::string> ParseMonsterId(std::string_view value) { - if (value == "MT_NZOMBIE") return MT_NZOMBIE; - if (value == "MT_BZOMBIE") return MT_BZOMBIE; - if (value == "MT_GZOMBIE") return MT_GZOMBIE; - if (value == "MT_YZOMBIE") return MT_YZOMBIE; - if (value == "MT_RFALLSP") return MT_RFALLSP; - if (value == "MT_DFALLSP") return MT_DFALLSP; - if (value == "MT_YFALLSP") return MT_YFALLSP; - if (value == "MT_BFALLSP") return MT_BFALLSP; - if (value == "MT_WSKELAX") return MT_WSKELAX; - if (value == "MT_TSKELAX") return MT_TSKELAX; - if (value == "MT_RSKELAX") return MT_RSKELAX; - if (value == "MT_XSKELAX") return MT_XSKELAX; - if (value == "MT_RFALLSD") return MT_RFALLSD; - if (value == "MT_DFALLSD") return MT_DFALLSD; - if (value == "MT_YFALLSD") return MT_YFALLSD; - if (value == "MT_BFALLSD") return MT_BFALLSD; - if (value == "MT_NSCAV") return MT_NSCAV; - if (value == "MT_BSCAV") return MT_BSCAV; - if (value == "MT_WSCAV") return MT_WSCAV; - if (value == "MT_YSCAV") return MT_YSCAV; - if (value == "MT_WSKELBW") return MT_WSKELBW; - if (value == "MT_TSKELBW") return MT_TSKELBW; - if (value == "MT_RSKELBW") return MT_RSKELBW; - if (value == "MT_XSKELBW") return MT_XSKELBW; - if (value == "MT_WSKELSD") return MT_WSKELSD; - if (value == "MT_TSKELSD") return MT_TSKELSD; - if (value == "MT_RSKELSD") return MT_RSKELSD; - if (value == "MT_XSKELSD") return MT_XSKELSD; - if (value == "MT_SNEAK") return MT_SNEAK; - if (value == "MT_STALKER") return MT_STALKER; - if (value == "MT_UNSEEN") return MT_UNSEEN; - if (value == "MT_ILLWEAV") return MT_ILLWEAV; - if (value == "MT_NGOATMC") return MT_NGOATMC; - if (value == "MT_BGOATMC") return MT_BGOATMC; - if (value == "MT_RGOATMC") return MT_RGOATMC; - if (value == "MT_GGOATMC") return MT_GGOATMC; - if (value == "MT_FIEND") return MT_FIEND; - if (value == "MT_GLOOM") return MT_GLOOM; - if (value == "MT_BLINK") return MT_BLINK; - if (value == "MT_FAMILIAR") return MT_FAMILIAR; - if (value == "MT_NGOATBW") return MT_NGOATBW; - if (value == "MT_BGOATBW") return MT_BGOATBW; - if (value == "MT_RGOATBW") return MT_RGOATBW; - if (value == "MT_GGOATBW") return MT_GGOATBW; - if (value == "MT_NACID") return MT_NACID; - if (value == "MT_RACID") return MT_RACID; - if (value == "MT_BACID") return MT_BACID; - if (value == "MT_XACID") return MT_XACID; - if (value == "MT_SKING") return MT_SKING; - if (value == "MT_FAT") return MT_FAT; - if (value == "MT_MUDMAN") return MT_MUDMAN; - if (value == "MT_TOAD") return MT_TOAD; - if (value == "MT_FLAYED") return MT_FLAYED; - if (value == "MT_WYRM") return MT_WYRM; - if (value == "MT_CAVSLUG") return MT_CAVSLUG; - if (value == "MT_DEVOUR") return MT_DEVOUR; - if (value == "MT_DVLWYRM") return MT_DVLWYRM; - if (value == "MT_NMAGMA") return MT_NMAGMA; - if (value == "MT_YMAGMA") return MT_YMAGMA; - if (value == "MT_BMAGMA") return MT_BMAGMA; - if (value == "MT_WMAGMA") return MT_WMAGMA; - if (value == "MT_HORNED") return MT_HORNED; - if (value == "MT_MUDRUN") return MT_MUDRUN; - if (value == "MT_FROSTC") return MT_FROSTC; - if (value == "MT_OBLORD") return MT_OBLORD; - if (value == "MT_BONEDMN") return MT_BONEDMN; - if (value == "MT_REDDTH") return MT_REDDTH; - if (value == "MT_LTCHDMN") return MT_LTCHDMN; - if (value == "MT_UDEDBLRG") return MT_UDEDBLRG; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INCIN") return MT_INCIN; - if (value == "MT_FLAMLRD") return MT_FLAMLRD; - if (value == "MT_DOOMFIRE") return MT_DOOMFIRE; - if (value == "MT_HELLBURN") return MT_HELLBURN; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_RSTORM") return MT_RSTORM; - if (value == "MT_STORM") return MT_STORM; - if (value == "MT_STORML") return MT_STORML; - if (value == "MT_MAEL") return MT_MAEL; - if (value == "MT_WINGED") return MT_WINGED; - if (value == "MT_GARGOYLE") return MT_GARGOYLE; - if (value == "MT_BLOODCLW") return MT_BLOODCLW; - if (value == "MT_DEATHW") return MT_DEATHW; - if (value == "MT_MEGA") return MT_MEGA; - if (value == "MT_GUARD") return MT_GUARD; - if (value == "MT_VTEXLRD") return MT_VTEXLRD; - if (value == "MT_BALROG") return MT_BALROG; - if (value == "MT_NSNAKE") return MT_NSNAKE; - if (value == "MT_RSNAKE") return MT_RSNAKE; - if (value == "MT_GSNAKE") return MT_GSNAKE; - if (value == "MT_BSNAKE") return MT_BSNAKE; - if (value == "MT_NBLACK") return MT_NBLACK; - if (value == "MT_RTBLACK") return MT_RTBLACK; - if (value == "MT_BTBLACK") return MT_BTBLACK; - if (value == "MT_RBLACK") return MT_RBLACK; - if (value == "MT_UNRAV") return MT_UNRAV; - if (value == "MT_HOLOWONE") return MT_HOLOWONE; - if (value == "MT_PAINMSTR") return MT_PAINMSTR; - if (value == "MT_REALWEAV") return MT_REALWEAV; - if (value == "MT_SUCCUBUS") return MT_SUCCUBUS; - if (value == "MT_SNOWWICH") return MT_SNOWWICH; - if (value == "MT_HLSPWN") return MT_HLSPWN; - if (value == "MT_SOLBRNR") return MT_SOLBRNR; - if (value == "MT_COUNSLR") return MT_COUNSLR; - if (value == "MT_MAGISTR") return MT_MAGISTR; - if (value == "MT_CABALIST") return MT_CABALIST; - if (value == "MT_ADVOCATE") return MT_ADVOCATE; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_DIABLO") return MT_DIABLO; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_GOLEM") return MT_GOLEM; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_INVALID") return MT_INVALID; - if (value == "MT_BIGFALL") return MT_BIGFALL; - if (value == "MT_DARKMAGE") return MT_DARKMAGE; - if (value == "MT_HELLBOAR") return MT_HELLBOAR; - if (value == "MT_STINGER") return MT_STINGER; - if (value == "MT_PSYCHORB") return MT_PSYCHORB; - if (value == "MT_ARACHNON") return MT_ARACHNON; - if (value == "MT_FELLTWIN") return MT_FELLTWIN; - if (value == "MT_HORKSPWN") return MT_HORKSPWN; - if (value == "MT_VENMTAIL") return MT_VENMTAIL; - if (value == "MT_NECRMORB") return MT_NECRMORB; - if (value == "MT_SPIDLORD") return MT_SPIDLORD; - if (value == "MT_LASHWORM") return MT_LASHWORM; - if (value == "MT_TORCHANT") return MT_TORCHANT; - if (value == "MT_HORKDMN") return MT_HORKDMN; - if (value == "MT_DEFILER") return MT_DEFILER; - if (value == "MT_GRAVEDIG") return MT_GRAVEDIG; - if (value == "MT_TOMBRAT") return MT_TOMBRAT; - if (value == "MT_FIREBAT") return MT_FIREBAT; - if (value == "MT_SKLWING") return MT_SKLWING; - if (value == "MT_LICH") return MT_LICH; - if (value == "MT_CRYPTDMN") return MT_CRYPTDMN; - if (value == "MT_HELLBAT") return MT_HELLBAT; - if (value == "MT_BONEDEMN") return MT_BONEDEMN; - if (value == "MT_LICH") return MT_LICH; - if (value == "MT_BICLOPS") return MT_BICLOPS; - if (value == "MT_FLESTHNG") return MT_FLESTHNG; - if (value == "MT_REAPER") return MT_REAPER; - if (value == "MT_NAKRUL") return MT_NAKRUL; - if (value == "MT_CLEAVER") return MT_CLEAVER; - if (value == "MT_INVILORD") return MT_INVILORD; - if (value == "MT_LRDSAYTR") return MT_LRDSAYTR; + const std::optional<_monster_id> enumValueOpt = magic_enum::enum_cast<_monster_id>(value); + if (enumValueOpt.has_value()) { + return enumValueOpt.value(); + } return tl::make_unexpected("Unknown enum value"); } diff --git a/tools/make_src_dist.py b/tools/make_src_dist.py index 0c2051afc..bcadf5a49 100755 --- a/tools/make_src_dist.py +++ b/tools/make_src_dist.py @@ -40,6 +40,7 @@ _DEPS = [ "libmpq", "libsmackerdec", "libzt", + "magic_enum", "sdl_audiolib", "sheenbidi", "unordered_dense", diff --git a/vcpkg.json b/vcpkg.json index 1532beaa0..073a47f55 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -4,7 +4,8 @@ "dependencies": [ "fmt", "bzip2", - "lua" + "lua", + "magic-enum" ], "builtin-baseline": "b91c3336aee7f32412508f7dd351ae2cabdb8819", "features": {