initial commit
This commit is contained in:
86
include/assets/asset_base.hpp
Normal file
86
include/assets/asset_base.hpp
Normal file
@@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <array>
|
||||
#include <string_view>
|
||||
#include <span>
|
||||
|
||||
#include <ryml.hpp>
|
||||
#include <ryml_std.hpp>
|
||||
#include <c4/format.hpp>
|
||||
|
||||
struct AssetBase
|
||||
{
|
||||
public:
|
||||
int64_t ID;
|
||||
};
|
||||
|
||||
struct AssetGUID
|
||||
{
|
||||
AssetGUID() = default;
|
||||
AssetGUID(const char* data) : AssetGUID(std::string_view(data, 32)) {};
|
||||
AssetGUID(std::string_view data)
|
||||
{
|
||||
for (size_t i = 0; i < 16; ++i) Data[0] = (Data[0] << 4) | hexToVal(data[i]);
|
||||
for (size_t i = 16; i < 32; ++i) Data[1] = (Data[1] << 4) | hexToVal(data[i]);
|
||||
}
|
||||
|
||||
static uint64_t hexToVal(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9') ? (c - '0') : (c - 'a' + 10);
|
||||
}
|
||||
|
||||
bool operator==(const AssetGUID& other) const
|
||||
{
|
||||
return Data[0] == other.Data[0] && Data[1] == other.Data[1];
|
||||
}
|
||||
|
||||
static constexpr uint64_t DefaultVal = 0xe000000000000000;
|
||||
|
||||
std::array<uint64_t, 2> Data{ 0, DefaultVal };
|
||||
};
|
||||
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<AssetGUID> {
|
||||
size_t operator()(const AssetGUID& v) const noexcept
|
||||
{
|
||||
auto h1 = std::hash<uint64_t>{}(v.Data[0]);
|
||||
auto h2 = std::hash<uint64_t>{}(v.Data[1]);
|
||||
return h1 ^ (h2 << 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* ParseAssetRef(const ryml::ConstNodeRef& node)
|
||||
{
|
||||
T* asset;
|
||||
node["fileID"] >> asset;
|
||||
return asset;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool LinkAssetRef(const std::unordered_map<int64_t, AssetBase*>& assetsMap, T*& asset)
|
||||
{
|
||||
auto it = assetsMap.find(reinterpret_cast<int64_t>(asset));
|
||||
if (it != assetsMap.end())
|
||||
{
|
||||
asset = reinterpret_cast<T*>(it->second);
|
||||
return true;
|
||||
}
|
||||
asset = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline AssetGUID ParseAssetGUID(const ryml::ConstNodeRef& node)
|
||||
{
|
||||
auto guidStringSpan2 = node["guid"].val();
|
||||
|
||||
assert(guidStringSpan2.size() == 32);
|
||||
|
||||
return AssetGUID{std::string_view(guidStringSpan2.data(), guidStringSpan2.size())};
|
||||
}
|
||||
21
include/assets/custom_assets.hpp
Normal file
21
include/assets/custom_assets.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "asset_base.hpp"
|
||||
|
||||
struct Drop
|
||||
{
|
||||
int itemId;
|
||||
int minAmount;
|
||||
int maxAmount;
|
||||
int dropChance;
|
||||
};
|
||||
|
||||
struct Interactable_Resource : public AssetBase
|
||||
{
|
||||
int maxHealth;
|
||||
int respawnTime;
|
||||
std::vector<Drop> drops;
|
||||
std::vector<int> requiredTools;
|
||||
int xp;
|
||||
int typeId;
|
||||
};
|
||||
54
include/assets/game_object.hpp
Normal file
54
include/assets/game_object.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <ryml_std.hpp>
|
||||
|
||||
#include "asset_base.hpp"
|
||||
#include "transform.hpp"
|
||||
|
||||
struct GameObjectAsset : public AssetBase
|
||||
{
|
||||
std::string name;
|
||||
uint8_t layer{ 0 };
|
||||
uint8_t namMeshLayer{ 0 };
|
||||
std::string tag;
|
||||
|
||||
TransformAsset* transform{ nullptr };
|
||||
std::vector<AssetBase*> Components;
|
||||
};
|
||||
|
||||
inline GameObjectAsset ParseGameObject(const ryml::ConstNodeRef& node)
|
||||
{
|
||||
GameObjectAsset gameObject;
|
||||
|
||||
node["m_Name"] >> gameObject.name;
|
||||
node["m_Layer"] >> gameObject.layer;
|
||||
node["m_TagString"] >> gameObject.tag;
|
||||
|
||||
auto components = node["m_Component"];
|
||||
auto it = components.begin();
|
||||
|
||||
gameObject.transform = ParseAssetRef<TransformAsset>((*it)["component"]);
|
||||
++it;
|
||||
for (; it != components.end(); ++it)
|
||||
{
|
||||
gameObject.Components.push_back(ParseAssetRef<AssetBase>((*it)["component"]));
|
||||
}
|
||||
|
||||
return gameObject;
|
||||
}
|
||||
|
||||
inline void LinkGameObject(const std::unordered_map<int64_t, AssetBase*>& assetsMap, GameObjectAsset& gameObject)
|
||||
{
|
||||
LinkAssetRef<TransformAsset>(assetsMap, gameObject.transform);
|
||||
for (int i = static_cast<int>(gameObject.Components.size()) - 1; i >= 0; i--)
|
||||
{
|
||||
if (!LinkAssetRef<AssetBase>(assetsMap, gameObject.Components[i]))
|
||||
{
|
||||
std::swap(gameObject.Components[i], gameObject.Components.back());
|
||||
gameObject.Components.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
29
include/assets/mesh_filter.hpp
Normal file
29
include/assets/mesh_filter.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "asset_base.hpp"
|
||||
|
||||
|
||||
struct GameObjectAsset;
|
||||
|
||||
struct MeshFilterAsset : AssetBase
|
||||
{
|
||||
AssetGUID Mesh;
|
||||
GameObjectAsset* GameObject{ nullptr };
|
||||
};
|
||||
|
||||
inline MeshFilterAsset ParseMeshFilter(const ryml::ConstNodeRef& node)
|
||||
{
|
||||
MeshFilterAsset meshFilter;
|
||||
|
||||
meshFilter.Mesh = ParseAssetGUID(node["m_Mesh"]);
|
||||
meshFilter.GameObject = ParseAssetRef<GameObjectAsset>(node["m_GameObject"]);
|
||||
|
||||
return meshFilter;
|
||||
}
|
||||
|
||||
inline void LinkMeshFilter(const std::unordered_map<int64_t, AssetBase*>& assetsMap, MeshFilterAsset& meshFilter)
|
||||
{
|
||||
LinkAssetRef<GameObjectAsset>(assetsMap, meshFilter.GameObject);
|
||||
}
|
||||
25
include/assets/prefab_instance.hpp
Normal file
25
include/assets/prefab_instance.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "asset_base.hpp"
|
||||
|
||||
//struct PrefabInstanceAsset : AssetBase
|
||||
//{
|
||||
// AssetGUID prefabGUID;
|
||||
// ryml::Tree Data{};
|
||||
//};
|
||||
|
||||
struct PrefabAsset
|
||||
{
|
||||
std::filesystem::path path;
|
||||
std::string name;
|
||||
|
||||
std::unordered_map<int64_t, ryml::Tree> Data;
|
||||
};
|
||||
|
||||
//inline PrefabInstanceAsset ParsePrefabInstance(const ryml::ConstNodeRef& node)
|
||||
//{
|
||||
// PrefabInstanceAsset prefabInstance;
|
||||
// prefabInstance.prefabGUID = ParseAssetGUID(node["m_SourcePrefab"]);
|
||||
// // prefabInstance.Data = node;
|
||||
// return prefabInstance;
|
||||
//}
|
||||
26
include/assets/scene.hpp
Normal file
26
include/assets/scene.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "game_object.hpp"
|
||||
#include "transform.hpp"
|
||||
#include "mesh_filter.hpp"
|
||||
#include "prefab_instance.hpp"
|
||||
|
||||
struct SceneAsset
|
||||
{
|
||||
public:
|
||||
std::filesystem::path path;
|
||||
std::string name;
|
||||
|
||||
std::vector<GameObjectAsset> gameObjects;
|
||||
std::vector<TransformAsset> transforms;
|
||||
std::vector<MeshFilterAsset> meshFilters;
|
||||
// std::vector<PrefabInstanceAsset> prefabInstances;
|
||||
|
||||
std::unordered_map<int64_t, void*> IDtoAsset;
|
||||
|
||||
|
||||
};
|
||||
75
include/assets/transform.hpp
Normal file
75
include/assets/transform.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include "asset_base.hpp"
|
||||
|
||||
struct GameObjectAsset;
|
||||
|
||||
struct TransformAsset : public AssetBase
|
||||
{
|
||||
glm::quat Rotation;
|
||||
glm::vec3 Position;
|
||||
glm::vec3 Scale;
|
||||
|
||||
glm::mat4 GlobalMatrix;
|
||||
|
||||
GameObjectAsset* GameObject{ nullptr };
|
||||
std::vector<TransformAsset*> Children;
|
||||
TransformAsset* Parent{ nullptr };
|
||||
};
|
||||
|
||||
inline glm::vec3 ParseVector3(const ryml::ConstNodeRef& node)
|
||||
{
|
||||
glm::vec3 vector;
|
||||
node["x"] >> vector.x;
|
||||
node["y"] >> vector.y;
|
||||
node["z"] >> vector.z;
|
||||
return vector;
|
||||
}
|
||||
|
||||
inline glm::quat ParseQuaternion(const ryml::ConstNodeRef& node)
|
||||
{
|
||||
glm::quat quaternion;
|
||||
node["x"] >> quaternion.x;
|
||||
node["y"] >> quaternion.y;
|
||||
node["z"] >> quaternion.z;
|
||||
node["w"] >> quaternion.w;
|
||||
return quaternion;
|
||||
}
|
||||
|
||||
inline TransformAsset ParseTransform(const ryml::ConstNodeRef& node)
|
||||
{
|
||||
TransformAsset transform;
|
||||
transform.Rotation = ParseQuaternion(node["m_LocalRotation"]);
|
||||
transform.Position = ParseVector3(node["m_LocalPosition"]);
|
||||
transform.Scale = ParseVector3(node["m_LocalScale"]);
|
||||
|
||||
transform.Parent = ParseAssetRef<TransformAsset>(node["m_Father"]);
|
||||
transform.GameObject = ParseAssetRef<GameObjectAsset>(node["m_GameObject"]);
|
||||
|
||||
auto children = node["m_Children"];
|
||||
for (const auto& child : children)
|
||||
{
|
||||
transform.Children.push_back(ParseAssetRef<TransformAsset>(child));
|
||||
}
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
inline void LinkTransform(const std::unordered_map<int64_t, AssetBase*>& assetsMap, TransformAsset& transform)
|
||||
{
|
||||
LinkAssetRef<TransformAsset>(assetsMap, transform.Parent);
|
||||
for (int i = static_cast<int>(transform.Children.size()) - 1; i >= 0; i--)
|
||||
{
|
||||
if (!LinkAssetRef<TransformAsset>(assetsMap, transform.Children[i]))
|
||||
{
|
||||
std::swap(transform.Children[i], transform.Children.back());
|
||||
transform.Children.pop_back();
|
||||
}
|
||||
}
|
||||
LinkAssetRef<GameObjectAsset>(assetsMap, transform.GameObject);
|
||||
}
|
||||
208
include/configs/constants.h
Normal file
208
include/configs/constants.h
Normal file
@@ -0,0 +1,208 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace cursebreaker {
|
||||
|
||||
enum class SkillType : uint8_t
|
||||
{
|
||||
woodcutting,
|
||||
fishing,
|
||||
swordsmanship,
|
||||
mining,
|
||||
archery,
|
||||
magic,
|
||||
defence,
|
||||
blacksmithy,
|
||||
tailoring,
|
||||
carpentry,
|
||||
alchemy,
|
||||
cooking,
|
||||
none,
|
||||
};
|
||||
|
||||
enum class WorkbenchType : uint8_t
|
||||
{
|
||||
none,
|
||||
anvil,
|
||||
oven,
|
||||
cooking,
|
||||
carpenter,
|
||||
tailor,
|
||||
forge,
|
||||
alchemist,
|
||||
mystic,
|
||||
};
|
||||
|
||||
enum class StatType : uint8_t
|
||||
{
|
||||
health,
|
||||
accuracyPhysical,
|
||||
accuracyMagical,
|
||||
accuracyRanged,
|
||||
damagePhysical,
|
||||
damageMagical,
|
||||
damageRanged,
|
||||
resistancePhysical,
|
||||
resistanceMagical,
|
||||
resistanceRanged,
|
||||
healing,
|
||||
movementSpeed,
|
||||
mana,
|
||||
manaregen,
|
||||
healthregen,
|
||||
power,
|
||||
critical,
|
||||
DamageVsUndead,
|
||||
DamageVsBeasts,
|
||||
CritterSlaying,
|
||||
none,
|
||||
harvestingSpeedWoodcutting
|
||||
};
|
||||
|
||||
enum class ItemType : uint8_t
|
||||
{
|
||||
weapon,
|
||||
shield,
|
||||
armor,
|
||||
head,
|
||||
resource,
|
||||
consumable,
|
||||
trinket,
|
||||
bracelet
|
||||
};
|
||||
|
||||
enum class ItemCategory : uint8_t
|
||||
{
|
||||
none,
|
||||
bone,
|
||||
bow,
|
||||
crossbow,
|
||||
constructable,
|
||||
torch,
|
||||
blacksmithhammer,
|
||||
questitem,
|
||||
heavyArmor,
|
||||
warhammer,
|
||||
shield,
|
||||
hatchet,
|
||||
blade,
|
||||
armor,
|
||||
pickaxe,
|
||||
fish,
|
||||
fishingrod,
|
||||
shears,
|
||||
hammer,
|
||||
battleaxe,
|
||||
morningstar,
|
||||
wand,
|
||||
staff,
|
||||
dagger
|
||||
};
|
||||
|
||||
enum class Tool : uint8_t
|
||||
{
|
||||
hatchet,
|
||||
pickaxe,
|
||||
broom,
|
||||
fishingrod,
|
||||
none
|
||||
};
|
||||
|
||||
enum class SpellBookType : uint8_t
|
||||
{
|
||||
none,
|
||||
spells,
|
||||
abilities
|
||||
};
|
||||
|
||||
enum class ActionType : uint8_t
|
||||
{
|
||||
NpcDeath,
|
||||
PlayerDeath,
|
||||
PlayerRespawn,
|
||||
NpcInteract,
|
||||
QuestUpdate,
|
||||
QuestTimerEnd,
|
||||
UseItemOnItem,
|
||||
UseItemOnNpc,
|
||||
ConsumeItem,
|
||||
NpcCombatInteract,
|
||||
none,
|
||||
NpcKilledByPlayer,
|
||||
EnterMap,
|
||||
VarUpdated,
|
||||
GrantAchievement,
|
||||
PlayerKilledByNpc,
|
||||
UseItem,
|
||||
CraftItem,
|
||||
HarvestItem,
|
||||
BuyItem,
|
||||
NpcTagKilledByPlayer,
|
||||
UseAbility,
|
||||
LootItem,
|
||||
UseItemCategoryOnItem,
|
||||
};
|
||||
|
||||
enum class Material : uint8_t
|
||||
{
|
||||
none,
|
||||
copper,
|
||||
iron,
|
||||
imbersteel,
|
||||
titanium,
|
||||
spruce,
|
||||
oak,
|
||||
evark,
|
||||
deadwood,
|
||||
sheep,
|
||||
troll,
|
||||
ogre,
|
||||
demon,
|
||||
wool,
|
||||
cotton,
|
||||
flax,
|
||||
jute,
|
||||
};
|
||||
|
||||
enum class GenstatType : uint8_t
|
||||
{
|
||||
none,
|
||||
dagger,
|
||||
broadsword,
|
||||
battleaxe,
|
||||
greatsword,
|
||||
morningstar,
|
||||
hammer,
|
||||
spear,
|
||||
bow,
|
||||
staff,
|
||||
wand,
|
||||
crossbow,
|
||||
woodenshield,
|
||||
wizardhat,
|
||||
wizardrobe,
|
||||
grandwizardhat,
|
||||
grandwizardrobe,
|
||||
leatherhood,
|
||||
leatherbracelet,
|
||||
leatherarmor,
|
||||
studdedleatherhood,
|
||||
studdedleatherbracelet,
|
||||
studdedleatherarmor,
|
||||
helmet,
|
||||
shield,
|
||||
armor,
|
||||
platehelmet,
|
||||
kiteshield,
|
||||
platearmor,
|
||||
};
|
||||
|
||||
struct StatValue
|
||||
{
|
||||
StatType type;
|
||||
uint8_t value;
|
||||
bool isPercentage;
|
||||
};
|
||||
|
||||
};
|
||||
103
include/configs/items.hpp
Normal file
103
include/configs/items.hpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <tinyxml2.h>
|
||||
|
||||
#include "constants.h"
|
||||
|
||||
namespace cursebreaker {
|
||||
|
||||
struct CraftingItemEntry
|
||||
{
|
||||
uint16_t itemId{};
|
||||
uint16_t amount{};
|
||||
};
|
||||
|
||||
// Struct for item crafting requirements
|
||||
struct ItemCrafting
|
||||
{
|
||||
WorkbenchType workbench;
|
||||
SkillType craftingskill;
|
||||
std::vector<CraftingItemEntry> craftingitems;
|
||||
std::string checks;
|
||||
|
||||
ItemCrafting() = default;
|
||||
};
|
||||
|
||||
// Main item struct
|
||||
struct Item {
|
||||
uint16_t id = 0;
|
||||
uint16_t price = 0;
|
||||
uint16_t abilityid = 0;
|
||||
uint16_t learnabilityid = 0;
|
||||
|
||||
SkillType skill = SkillType::none;
|
||||
ItemCategory category = ItemCategory::none;
|
||||
ItemType slot = ItemType::resource;
|
||||
Tool tool = Tool::none;
|
||||
GenstatType generation = GenstatType::none;
|
||||
uint8_t level = 0;
|
||||
uint8_t foodlevel = 0;
|
||||
uint8_t foodamount = 0;
|
||||
uint8_t foodfrequency = 0;
|
||||
uint8_t foodtime = 0;
|
||||
uint8_t maxstack = 0;
|
||||
uint8_t book = 0;
|
||||
|
||||
bool stackable : 1;
|
||||
bool twohanded : 1;
|
||||
bool undroppable : 1;
|
||||
bool hidemilestone : 1;
|
||||
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string comment;
|
||||
|
||||
std::vector<StatValue> stats;
|
||||
std::vector<ItemCrafting> craftings;
|
||||
|
||||
Item() = default;
|
||||
};
|
||||
|
||||
// Helper functions for enum conversions
|
||||
StatType stringToStatType(const std::string& str);
|
||||
ItemCategory stringToItemCategory(const std::string& str);
|
||||
ItemType stringToItemType(const std::string& str);
|
||||
Tool stringToTool(const std::string& str);
|
||||
SkillType stringToSkillType(const std::string& str);
|
||||
WorkbenchType stringToWorkbenchType(const std::string& str);
|
||||
GenstatType stringToGenstatType(const std::string& str);
|
||||
|
||||
// Items configuration manager
|
||||
class ItemsConfig {
|
||||
public:
|
||||
static ItemsConfig& getInstance() {
|
||||
static ItemsConfig instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool loadFromXML(const std::string& filepath);
|
||||
const Item* getItemById(int id) const;
|
||||
const std::unordered_map<int, Item>& getAllItems() const { return m_items; }
|
||||
|
||||
private:
|
||||
ItemsConfig() = default;
|
||||
~ItemsConfig() = default;
|
||||
ItemsConfig(const ItemsConfig&) = delete;
|
||||
ItemsConfig& operator=(const ItemsConfig&) = delete;
|
||||
|
||||
std::unordered_map<int, Item> m_items;
|
||||
|
||||
// Helper methods for parsing
|
||||
void parseItem(tinyxml2::XMLElement* itemElement);
|
||||
void parseStats(tinyxml2::XMLElement* itemElement, Item& item);
|
||||
void parseCraftings(tinyxml2::XMLElement* itemElement, Item& item);
|
||||
std::string getAttributeValue(tinyxml2::XMLElement* element, const char* attribute, const std::string& defaultValue = "");
|
||||
int getAttributeValueInt(tinyxml2::XMLElement* element, const char* attribute, int defaultValue = 0);
|
||||
bool getAttributeValueBool(tinyxml2::XMLElement* element, const char* attribute, bool defaultValue = false);
|
||||
};
|
||||
|
||||
} // namespace cursebreaker
|
||||
38
include/project_parser.h
Normal file
38
include/project_parser.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "assets/asset_base.hpp"
|
||||
#include "assets/scene.hpp"
|
||||
|
||||
struct AssetPath
|
||||
{
|
||||
std::filesystem::path path{};
|
||||
AssetGUID GUID{};
|
||||
};
|
||||
|
||||
struct ParsedProject
|
||||
{
|
||||
std::filesystem::path m_projectRoot;
|
||||
|
||||
std::vector<AssetPath> m_scriptFiles;
|
||||
std::vector<AssetPath> m_imageFiles;
|
||||
std::vector<AssetPath> m_meshFiles;
|
||||
std::vector<AssetPath> m_sceneFiles;
|
||||
std::vector<AssetPath> m_prefabFiles;
|
||||
|
||||
std::vector<PrefabAsset> m_prefabAssets;
|
||||
std::vector<SceneAsset> m_sceneAssets;
|
||||
|
||||
std::unordered_map<AssetGUID, PrefabAsset*> m_prefabsMap;
|
||||
std::unordered_map<AssetGUID, uint32_t> m_scriptToClassHash;
|
||||
|
||||
};
|
||||
|
||||
void ParseProject(const std::filesystem::path& projectRoot);
|
||||
|
||||
extern ParsedProject g_parsedProject;
|
||||
5
include/tree_builder.h
Normal file
5
include/tree_builder.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "assets/scene.hpp"
|
||||
|
||||
void BuildTree(SceneAsset& sceneAsset);
|
||||
Reference in New Issue
Block a user