From 2b33210cdffbabebe9817c9f789b32529fc90d7d Mon Sep 17 00:00:00 2001 From: Lyuu17 Date: Sun, 30 Jun 2024 21:06:59 +0200 Subject: [PATCH] Refactor --- src/SWBF2/Core.cpp | 27 ++++++++++++------ src/SWBF2/Core.hpp | 8 ++++++ src/SWBF2/Level.cpp | 24 +++++++++++----- src/SWBF2/Level.hpp | 17 +++++++++-- src/SWBF2/Native/Chunks/LevelChunk.cpp | 26 +++++++++++------ src/SWBF2/Native/Models/Model.cpp | 2 -- src/SWBF2/Native/SWBF2.cpp | 39 ++++++++++++++++++++++---- src/SWBF2/Native/SWBF2.hpp | 26 +++++++++++++++-- src/SWBF2/Native/Texture/Texture.cpp | 2 -- 9 files changed, 133 insertions(+), 38 deletions(-) diff --git a/src/SWBF2/Core.cpp b/src/SWBF2/Core.cpp index c10de40..be1645b 100644 --- a/src/SWBF2/Core.cpp +++ b/src/SWBF2/Core.cpp @@ -1,16 +1,13 @@ #include +#include "Native/Chunks/ChunkProcessor.hpp" +#include "Native/SWBF2.hpp" + #include "Core.hpp" #include "Level.hpp" #include "Version.h" -#include "Native/Chunks/ChunkProcessor.hpp" - -#include -#include -#include - namespace SWBF2 { Core::Core() @@ -22,16 +19,30 @@ namespace SWBF2 set_name("Core"); godot::UtilityFunctions::print("hello world!"); + } + + void Core::LoadLevel(const godot::String &mapName) + { + m_curMapName = mapName; + + if (mapName.is_empty()) + { + remove_child(find_child("Level", false)); - // SWBF2::Native::UcfbChunk::ReadUcfbFile("data/_lvl_pc/common.lvl"); - // SWBF2::Native::UcfbChunk::ReadUcfbFile("data/_lvl_pc/core.lvl"); + SWBF2::Native::SWBF2::Reset(); + return; + } Level *lvl = memnew(Level); add_child(lvl); lvl->set_owner(this); + lvl->LoadLevel(mapName); } void Core::_bind_methods() { + godot::ClassDB::bind_method(godot::D_METHOD("get_mapname"), &Core::GetMapName); + godot::ClassDB::bind_method(godot::D_METHOD("load_level", "mapname"), &Core::LoadLevel); + godot::ClassDB::add_property("Core", godot::PropertyInfo(godot::Variant::STRING, "mapname", godot::PROPERTY_HINT_ENUM, "cor1"), "load_level", "get_mapname"); } } diff --git a/src/SWBF2/Core.hpp b/src/SWBF2/Core.hpp index 349f1b6..0a2ab64 100644 --- a/src/SWBF2/Core.hpp +++ b/src/SWBF2/Core.hpp @@ -7,10 +7,18 @@ namespace SWBF2 class Core : public godot::Node { GDCLASS(Core, godot::Node) + private: + godot::String m_curMapName; + public: Core(); ~Core() = default; + public: + const godot::String &GetMapName() { return m_curMapName; }; + void LoadLevel(const godot::String &mapName); + + public: void _ready() override; private: diff --git a/src/SWBF2/Level.cpp b/src/SWBF2/Level.cpp index c65f5a0..0cdc2d9 100644 --- a/src/SWBF2/Level.cpp +++ b/src/SWBF2/Level.cpp @@ -1,4 +1,5 @@ +#include #include #include #include @@ -22,13 +23,6 @@ namespace SWBF2 void Level::_ready() { set_name("Level"); - - if (!Native::SWBF2::LoadLevelWithGamemode("cor/cor1", "ctf")) - throw std::runtime_error{ "failed to load the game level" }; - - LoadLevelInstances(); - LoadWorldEnvironment(); - LoadLights(); } godot::MeshInstance3D *Level::LoadModel(const std::string &id) @@ -175,6 +169,22 @@ namespace SWBF2 } } + void Level::LoadLevel(const godot::String &mapName) + { + m_curMapName = mapName; + + if (!Native::SWBF2::LoadLevelFile(mapName.ascii().get_data())) + throw std::runtime_error{ "failed to load the game level" }; + + LoadLevelInstances(); + LoadWorldEnvironment(); + LoadLights(); + } + + void Level::LoadGamemode(const godot::String &gamemode) + { + } + void Level::_process(double delta_time) { } diff --git a/src/SWBF2/Level.hpp b/src/SWBF2/Level.hpp index 4fa77ca..6e07d7b 100644 --- a/src/SWBF2/Level.hpp +++ b/src/SWBF2/Level.hpp @@ -12,19 +12,32 @@ namespace SWBF2 class Level : public godot::Node3D { GDCLASS(Level, godot::Node3D) + private: + godot::String m_curMapName; + godot::String m_curGamemode; + public: Level() {} ~Level() = default; MaterialPools m_materialPool; - virtual void _ready() override; - godot::MeshInstance3D *LoadModel(const std::string &id); + + private: void LoadLevelInstances(); void LoadWorldEnvironment(); void LoadLights(); + public: + const godot::String &GetMapName() { return m_curMapName; }; + void LoadLevel(const godot::String &mapName); + + const godot::String &GetGamemode() { return m_curGamemode; }; + void LoadGamemode(const godot::String &gamemode); + public: + virtual void _ready() override; + void _process(double delta_time) override; void activate(bool active = true); diff --git a/src/SWBF2/Native/Chunks/LevelChunk.cpp b/src/SWBF2/Native/Chunks/LevelChunk.cpp index e90683e..6c52c0a 100644 --- a/src/SWBF2/Native/Chunks/LevelChunk.cpp +++ b/src/SWBF2/Native/Chunks/LevelChunk.cpp @@ -13,11 +13,9 @@ namespace SWBF2::Native { Level lvl{}; - uint32_t hash; + FNVHash hash; streamReader >> hash; - // std::string lvlName{ GameHashes.at(hash) }; - streamReader.SkipBytes(sizeof(uint32_t)); // lvl_ size left std::optional readerChild; @@ -41,10 +39,22 @@ namespace SWBF2::Native } } - /*const auto gamemodes = {"ctf", "conquest", "centerflag", "campaign", "tdm"}; - std::string type = lvlName.substr(lvlName.find_first_of('_') + 1); - - if (std::find(gamemodes.begin(), gamemodes.end(), type) != gamemodes.end()) - SWBF2::m_levels.insert_or_assign(type, lvl);*/ + const static std::unordered_map LevelGamemodesStr + { + { LevelGamemode::CTF, "ctf" }, + { LevelGamemode::CONQUEST, "conquest" }, + { LevelGamemode::CENTERFLAG, "centerflag" }, + { LevelGamemode::CAMPAIGN, "campaign" }, + { LevelGamemode::TDM, "tdm" } + }; + + for (const auto &[id, str] : LevelGamemodesStr) + { + if (FNVGenerateHash(std::format("{}_{}", SWBF2::m_curMapName, str)) == hash) + { + SWBF2::m_levels.insert_or_assign(id, lvl); + break; + } + } } } diff --git a/src/SWBF2/Native/Models/Model.cpp b/src/SWBF2/Native/Models/Model.cpp index 7a8bd8d..762d323 100644 --- a/src/SWBF2/Native/Models/Model.cpp +++ b/src/SWBF2/Native/Models/Model.cpp @@ -1,6 +1,4 @@ -#pragma once - #include "Model.hpp" namespace SWBF2::Native diff --git a/src/SWBF2/Native/SWBF2.cpp b/src/SWBF2/Native/SWBF2.cpp index 55c80cf..a83de4f 100644 --- a/src/SWBF2/Native/SWBF2.cpp +++ b/src/SWBF2/Native/SWBF2.cpp @@ -7,22 +7,49 @@ namespace SWBF2::Native { SkyDome SWBF2::m_skyDome; - std::string SWBF2::m_curLevel; + std::string SWBF2::m_curMapName; + LevelGamemode SWBF2::m_curLevel; - std::unordered_map SWBF2::m_levels; + std::unordered_map SWBF2::m_levels; std::unordered_map SWBF2::m_worlds; std::unordered_map SWBF2::m_lights; std::unordered_map SWBF2::m_models; std::unordered_map SWBF2::m_tex; std::unordered_map SWBF2::m_locl; - bool SWBF2::LoadLevelWithGamemode(const std::string &lvlfile, const std::string &lvl) + void SWBF2::Init() { - bool ret = UcfbChunk::ReadUcfbFile(std::format("data/_lvl_pc/{}.lvl", lvlfile)); + if (!UcfbChunk::ReadUcfbFile("data/_lvl_pc/core.lvl")) + throw std::runtime_error{ "failed to load core.lvl from game directory" }; - m_curLevel = lvl; + if (!UcfbChunk::ReadUcfbFile("data/_lvl_pc/common.lvl")) + throw std::runtime_error{ "failed to load common.lvl from game directory" }; + } - return ret; + void SWBF2::Reset() + { + m_skyDome = {}; + m_curMapName = {}; + m_curLevel = {}; + + m_levels.clear(); + m_worlds.clear(); + m_lights.clear(); + m_models.clear(); + m_tex.clear(); + m_locl.clear(); + } + + bool SWBF2::LoadLevelFile(const std::string &levelname) + { + m_curMapName = levelname; + + return UcfbChunk::ReadUcfbFile(std::format("data/_lvl_pc/{}.lvl", GameMaps.at(levelname))); + } + + void SWBF2::LoadGamemode(LevelGamemode gamemode) + { + m_curLevel = gamemode; } const Level &SWBF2::GetLevel() diff --git a/src/SWBF2/Native/SWBF2.hpp b/src/SWBF2/Native/SWBF2.hpp index 3a5556d..100ff92 100644 --- a/src/SWBF2/Native/SWBF2.hpp +++ b/src/SWBF2/Native/SWBF2.hpp @@ -9,13 +9,30 @@ namespace SWBF2::Native { + const static inline std::unordered_map GameMaps + { + // name, path + { "cor1", "cor/cor1" } + }; + + enum class LevelGamemode + { + NONE = 0, + CTF, + CONQUEST, + CENTERFLAG, + CAMPAIGN, + TDM + }; + class SWBF2 { public: static SkyDome m_skyDome; - static std::string m_curLevel; + static std::string m_curMapName; + static LevelGamemode m_curLevel; - static std::unordered_map m_levels; + static std::unordered_map m_levels; static std::unordered_map m_worlds; static std::unordered_map m_lights; static std::unordered_map m_models; @@ -24,7 +41,10 @@ namespace SWBF2::Native using LoclEntriesMap = std::unordered_map; static std::unordered_map m_locl; - static bool LoadLevelWithGamemode(const std::string &lvlfile, const std::string &gamemode); + static void Init(); + static void Reset(); + static bool LoadLevelFile(const std::string &levelname); + static void LoadGamemode(LevelGamemode gamemode); static const Level &GetLevel(); }; } diff --git a/src/SWBF2/Native/Texture/Texture.cpp b/src/SWBF2/Native/Texture/Texture.cpp index fbf133d..77ca14b 100644 --- a/src/SWBF2/Native/Texture/Texture.cpp +++ b/src/SWBF2/Native/Texture/Texture.cpp @@ -1,6 +1,4 @@ -#pragma once - #include "Texture.hpp" namespace SWBF2::Native