This commit is contained in:
Connor
2026-02-20 18:24:20 +09:00
parent c081aa868f
commit fc3192cd1e
8 changed files with 449 additions and 567 deletions

View File

@@ -20,6 +20,12 @@ struct TilePosition
Vector2 Position; Vector2 Position;
}; };
struct Bounds
{
Vector2 Min;
Vector2 Max;
};
struct Level struct Level
{ {
Level() = default; Level() = default;
@@ -59,6 +65,10 @@ inline void Flecs_Misc(flecs::world& world)
world.component<TilePosition>() world.component<TilePosition>()
.member<Vector2>("Position"); .member<Vector2>("Position");
world.component<Bounds>()
.member<Vector2>("Min")
.member<Vector2>("Max");
world.component<Level>() world.component<Level>()
.member<uint8_t>("Val"); .member<uint8_t>("Val");
} }

View File

@@ -1,33 +0,0 @@
// #pragma once
// #include "core/object/ref_counted.h"
// struct Sync
// { };
// class FactoryEntity;
// struct NodePtr
// {
// NodePtr() = default;
// NodePtr(FactoryEntity* node) : Node{ node } {}
// template <typename T>
// T* AsNode() const
// {
// static_assert(std::is_base_of_v<FactoryEntity, T>);
// DEV_ASSERT(Object::cast_to<T>(Node));
// return static_cast<T*>(Node);
// }
// FactoryEntity* Node{};
// };
// class Archetype;
// struct ArchetypePtr
// {
// ArchetypePtr() = default;
// ArchetypePtr(Ref<Archetype>& archetpye) : Archetype{ archetpye } {}
// Ref<Archetype> Archetype;
// };

View File

@@ -1,9 +1,16 @@
#pragma once #pragma once
#include "modules/factory/include/Data/Tile.h" #include <stdint.h>
#include "core/math/vector2i.h"
#include <array> #include <array>
#include <memory>
#include <vector> #include <vector>
#include <unordered_map>
#include "Util/Span.h"
#include "config.h"
#include "Types/Tile.h"
#include "Components/Misc.hpp"
struct Chunk struct Chunk
{ {
@@ -23,22 +30,22 @@ public:
static void Assert(int x, int y) { DEV_ASSERT(x < ChunkSize && x >= 0 && y < ChunkSize && y >= 0); } static void Assert(int x, int y) { DEV_ASSERT(x < ChunkSize && x >= 0 && y < ChunkSize && y >= 0); }
public: public:
Tile GetTile(int x, int y) const { Assert(x, y); return Tiles[y * ChunkSize + x]; } Tile GetTile(int x, int y) const { Assert(x, y); return Tiles[y * ChunkSize + x]; }
Tile GetTile(Vector2i pos) const { return GetTile(pos.x, pos.y); } Tile GetTile(Vector2 pos) const { return GetTile(pos.X, pos.Y); }
const Tile& GetTileRef(int x, int y) const { Assert(x, y); return Tiles[y * ChunkSize + x]; } const Tile& GetTileRef(int x, int y) const { Assert(x, y); return Tiles[y * ChunkSize + x]; }
Tile& GetTile(int x, int y) { Assert(x, y); return Tiles[y * ChunkSize + x]; } Tile& GetTile(int x, int y) { Assert(x, y); return Tiles[y * ChunkSize + x]; }
Tile& GetTile(Vector2i pos) { return GetTile(pos.x, pos.y); } Tile& GetTile(Vector2 pos) { return GetTile(pos.X, pos.Y); }
}; };
struct ChunkCoordinate struct ChunkCoordinate
{ {
ChunkCoordinate() = default; ChunkCoordinate() = default;
ChunkCoordinate(int x, int y) : X{ static_cast<uint8_t>(x) }, Y{ static_cast<uint8_t>(y) } { DEV_ASSERT(x >= 0 && x < Chunk::ChunkSize && y >= 0 && y < Chunk::ChunkSize); } ChunkCoordinate(int x, int y) : X{ static_cast<uint8_t>(x) }, Y{ static_cast<uint8_t>(y) } { DEV_ASSERT(x >= 0 && x < Chunk::ChunkSize && y >= 0 && y < Chunk::ChunkSize); }
ChunkCoordinate(Vector2i pos) : ChunkCoordinate{pos.x, pos.y} {} ChunkCoordinate(Vector2 pos) : ChunkCoordinate{pos.X, pos.Y} {}
uint8_t X{}; uint8_t X{};
uint8_t Y{}; uint8_t Y{};
operator Vector2i() const { return Vector2i(X, Y); } operator Vector2() const { return Vector2(X, Y); }
}; };
static_assert(sizeof(ChunkCoordinate) / 2 >= Chunk::ChunkSizePowerOfTwo / 8); static_assert(sizeof(ChunkCoordinate) / 2 >= Chunk::ChunkSizePowerOfTwo / 8);
@@ -47,14 +54,14 @@ struct EntityTile final
{ {
public: public:
EntityTile() = default; EntityTile() = default;
EntityTile(entt::entity entity, int worldX, int worldY) EntityTile(flecs::entity entity, int worldX, int worldY)
: Entity{ entity } : Entity{ entity }
, ChunkX{ Chunk::WorldToLocal(worldX) } , ChunkX{ Chunk::WorldToLocal(worldX) }
, ChunkY{ Chunk::WorldToLocal(worldY) } , ChunkY{ Chunk::WorldToLocal(worldY) }
{} {}
public: public:
entt::entity Entity{}; flecs::entity Entity{};
Chunk::CoordinateType ChunkX{}; Chunk::CoordinateType ChunkX{};
Chunk::CoordinateType ChunkY{}; Chunk::CoordinateType ChunkY{};
}; };
@@ -77,7 +84,7 @@ public:
uint32_t hash() const { return static_cast<uint32_t>(hash64()); } uint32_t hash() const { return static_cast<uint32_t>(hash64()); }
static uint32_t hash(ChunkKey key) { return key.hash(); } static uint32_t hash(ChunkKey key) { return key.hash(); }
Rect2i GetBounds() const { return Rect2i{ChunkToWorld(X), ChunkToWorld(Y), 1 << Chunk::ChunkSizePowerOfTwo, 1 << Chunk::ChunkSizePowerOfTwo}; } Bounds SetBounds() const { return Bounds{Vector2{ChunkToWorld(X), ChunkToWorld(Y)}, Vector2{ChunkToWorld(X + 1), ChunkToWorld(Y + 1)}}; }
public: public:
bool operator==(const ChunkKey& rhs) const { return hash() == rhs.hash(); } bool operator==(const ChunkKey& rhs) const { return hash() == rhs.hash(); }
@@ -88,8 +95,8 @@ static_assert(sizeof(ChunkKey) == 4);
struct ChunkData struct ChunkData
{ {
public: public:
void MarkAsPersistant(entt::entity entity); void MarkAsPersistant(flecs::entity entity);
void RemovePersistance(entt::entity entity); void RemovePersistance(flecs::entity entity);
void Clear() void Clear()
{ {
Chunk = {}; Chunk = {};
@@ -114,17 +121,17 @@ public:
Tile GetTile(int x, int y); Tile GetTile(int x, int y);
Tile const* TryGetTile(int x, int y) const; Tile const* TryGetTile(int x, int y) const;
entt::entity GetEntity(int x, int y) const; flecs::entity GetEntity(int x, int y) const;
void SetChunkTiles(int x, int y, std::unique_ptr<Chunk>&& chunk); void SetChunkTiles(int x, int y, std::unique_ptr<Chunk>&& chunk);
void SetChunkTiles(ChunkKey key, std::unique_ptr<Chunk>&& chunk); void SetChunkTiles(ChunkKey key, std::unique_ptr<Chunk>&& chunk);
void AddEntity(entt::entity entity, const Vector<Vector2i>& claimedPositions); void AddEntity(flecs::entity entity, tcb::span<Vector2> claimedPositions);
void AddPersistantEntity(entt::entity entity, const Vector<Vector2i>& claimedPositions); void AddPersistantEntity(flecs::entity entity, tcb::span<Vector2> claimedPositions);
void MarkAsPersistant(entt::entity entity); void MarkAsPersistant(flecs::entity entity);
void RemovePersistance(entt::entity entity); void RemovePersistance(flecs::entity entity);
void RemoveEntity(entt::entity entity); void RemoveEntity(flecs::entity entity);
void RemoveChunk(int x, int y); void RemoveChunk(int x, int y);
void RemoveChunk(ChunkKey key); void RemoveChunk(ChunkKey key);
@@ -143,7 +150,7 @@ private:
private: private:
std::vector<ChunkData> ChunkDatas; std::vector<ChunkData> ChunkDatas;
HashMap<ChunkKey, int, ChunkKey> ChunkMap{}; std::unordered_map<ChunkKey, int, ChunkKey> ChunkMap{};
ChunkKey CachedChunkKey{}; ChunkKey CachedChunkKey{};
int CachedChunk{-1}; int CachedChunk{-1};
}; };

View File

@@ -1,197 +1,197 @@
#pragma once // #pragma once
#include "Util/StackAllocator.h" // #include "Util/StackAllocator.h"
#include "Util/Span.h" // #include "Util/Span.h"
#include "EnTT/entity/registry.hpp" // #include "EnTT/entity/registry.hpp"
#include <functional> // #include <functional>
#include <mutex> // #include <mutex>
#include "Components/Sync.h" // #include "Components/Sync.h"
#include "Core/FactoryWorld.h" // #include "Core/FactoryWorld.h"
struct FactoryCommand // struct FactoryCommand
{ // {
void* Data; // void* Data;
entt::entity Entity; // entt::entity Entity;
void(*Command)(FactoryWorld& world, entt::entity entity, void* data); // void(*Command)(FactoryWorld& world, entt::entity entity, void* data);
}; // };
class FactoryCommandQueue final // class FactoryCommandQueue final
{ // {
static constexpr int DefaultAllocatorSize = 1024 * 1024; // static constexpr int DefaultAllocatorSize = 1024 * 1024;
public: // public:
FactoryCommandQueue(size_t memorySize) // FactoryCommandQueue(size_t memorySize)
: Allocator{ memorySize } // : Allocator{ memorySize }
{} // {}
FactoryCommandQueue() // FactoryCommandQueue()
: Allocator{ DefaultAllocatorSize } // : Allocator{ DefaultAllocatorSize }
{} // {}
public: // public:
public: // public:
template <typename T> // template <typename T>
void SetComponentData(entt::entity entity, const T& component); // void SetComponentData(entt::entity entity, const T& component);
template <typename T> // template <typename T>
void SetOrAddComponentData(entt::entity entity, const T& component); // void SetOrAddComponentData(entt::entity entity, const T& component);
template <typename T> // template <typename T>
void AddIfNone(entt::entity entity, const T& component); // void AddIfNone(entt::entity entity, const T& component);
template <typename T> // template <typename T>
void AddComponent(entt::entity entity, const T& component); // void AddComponent(entt::entity entity, const T& component);
template <typename T> // template <typename T>
void AddComponent(entt::entity entity); // void AddComponent(entt::entity entity);
template <typename T> // template <typename T>
void RemoveComponent(entt::entity entity); // void RemoveComponent(entt::entity entity);
//void RemoveEntity(entt::entity entity); // //void RemoveEntity(entt::entity entity);
void SyncEntity(entt::entity entity) { AddComponent<Sync>(entity); } // void SyncEntity(entt::entity entity) { AddComponent<Sync>(entity); }
void StopSyncingEntity(entt::entity entity) { RemoveComponent<Sync>(entity); } // void StopSyncingEntity(entt::entity entity) { RemoveComponent<Sync>(entity); }
void ExecuteAll(FactoryWorld& world); // void ExecuteAll(FactoryWorld& world);
void Clear(); // void Clear();
template <typename T> // template <typename T>
T* AllocateData() // T* AllocateData()
{ // {
static_assert(std::is_trivially_copyable_v<T>); // static_assert(std::is_trivially_copyable_v<T>);
return Allocator.allocate<T>(1); // return Allocator.allocate<T>(1);
} // }
template <typename T, typename ... Args> // template <typename T, typename ... Args>
T* AllocateData(Args... arguments) // T* AllocateData(Args... arguments)
{ // {
static_assert(std::is_trivially_copyable_v<T>); // static_assert(std::is_trivially_copyable_v<T>);
T* data = AllocateData<T>(); // T* data = AllocateData<T>();
new (data) T(arguments...); // new (data) T(arguments...);
return data; // return data;
} // }
template <typename T> // template <typename T>
tcb::span<T>* AllocateBuffer(uint32_t size) // tcb::span<T>* AllocateBuffer(uint32_t size)
{ // {
static_assert(std::is_trivially_copyable_v<T>); // static_assert(std::is_trivially_copyable_v<T>);
auto spanData = Allocator.allocate<tcb::span<T>>(); // auto spanData = Allocator.allocate<tcb::span<T>>();
auto data = Allocator.allocate<T>(size); // auto data = Allocator.allocate<T>(size);
for (uint32_t i{}; i < size; ++i) // for (uint32_t i{}; i < size; ++i)
data[i] = {}; // data[i] = {};
*spanData = tcb::span<T>(data, size); // *spanData = tcb::span<T>(data, size);
return spanData; // return spanData;
} // }
private: // private:
void ClearUnsafe() // void ClearUnsafe()
{ // {
Commands.clear(); // Commands.clear();
Allocator.reset(); // Allocator.reset();
} // }
private: // private:
StackAllocator Allocator; // StackAllocator Allocator;
std::mutex Mutex; // std::mutex Mutex;
std::vector<FactoryCommand> Commands; // std::vector<FactoryCommand> Commands;
}; // };
template<typename T> // template<typename T>
inline void FactoryCommandQueue::SetComponentData(entt::entity entity, const T& component) // inline void FactoryCommandQueue::SetComponentData(entt::entity entity, const T& component)
{ // {
FactoryCommand command; // FactoryCommand command;
command.Entity = entity; // command.Entity = entity;
command.Data = AllocateData<T>(component); // command.Data = AllocateData<T>(component);
command.Command = [](entt::registry& registry, entt::entity entity, void* data) // command.Command = [](entt::registry& registry, entt::entity entity, void* data)
{ // {
registry.get<T>(entity) = *static_cast<T*>(data); // registry.get<T>(entity) = *static_cast<T*>(data);
}; // };
std::scoped_lock lock(Mutex); // std::scoped_lock lock(Mutex);
Commands.push_back(command); // Commands.push_back(command);
} // }
template<typename T> // template<typename T>
inline void FactoryCommandQueue::SetOrAddComponentData(entt::entity entity, const T& component) // inline void FactoryCommandQueue::SetOrAddComponentData(entt::entity entity, const T& component)
{ // {
FactoryCommand command; // FactoryCommand command;
command.Entity = entity; // command.Entity = entity;
command.Data = AllocateData<T>(component); // command.Data = AllocateData<T>(component);
command.Command = [](entt::registry& registry, entt::entity entity, void* data) // command.Command = [](entt::registry& registry, entt::entity entity, void* data)
{ // {
registry.emplace_or_replace<T>(entity, *static_cast<T*>(data)); // registry.emplace_or_replace<T>(entity, *static_cast<T*>(data));
}; // };
std::scoped_lock lock(Mutex); // std::scoped_lock lock(Mutex);
Commands.push_back(command); // Commands.push_back(command);
} // }
template<typename T> // template<typename T>
inline void FactoryCommandQueue::AddIfNone(entt::entity entity, const T& component) // inline void FactoryCommandQueue::AddIfNone(entt::entity entity, const T& component)
{ // {
FactoryCommand command; // FactoryCommand command;
command.Entity = entity; // command.Entity = entity;
command.Data = AllocateData<T>(component); // command.Data = AllocateData<T>(component);
command.Command = [](entt::registry& registry, entt::entity entity, void* data) // command.Command = [](entt::registry& registry, entt::entity entity, void* data)
{ // {
if (!registry.all_of<T>(entity)) // if (!registry.all_of<T>(entity))
registry.emplace<T>(entity, *static_cast<T*>(data)); // registry.emplace<T>(entity, *static_cast<T*>(data));
}; // };
std::scoped_lock lock(Mutex); // std::scoped_lock lock(Mutex);
Commands.push_back(command); // Commands.push_back(command);
} // }
template<typename T> // template<typename T>
inline void FactoryCommandQueue::AddComponent(entt::entity entity, const T& component) // inline void FactoryCommandQueue::AddComponent(entt::entity entity, const T& component)
{ // {
FactoryCommand command; // FactoryCommand command;
command.Entity = entity; // command.Entity = entity;
command.Data = AllocateData<T>(component); // command.Data = AllocateData<T>(component);
command.Command = [](entt::registry& registry, entt::entity entity, void* data) // command.Command = [](entt::registry& registry, entt::entity entity, void* data)
{ // {
registry.emplace<T>(entity, *static_cast<T*>(data)); // registry.emplace<T>(entity, *static_cast<T*>(data));
}; // };
std::scoped_lock lock(Mutex); // std::scoped_lock lock(Mutex);
Commands.push_back(command); // Commands.push_back(command);
} // }
template<typename T> // template<typename T>
inline void FactoryCommandQueue::AddComponent(entt::entity entity) // inline void FactoryCommandQueue::AddComponent(entt::entity entity)
{
FactoryCommand command;
command.Entity = entity;
command.Data = nullptr;
command.Command = [](entt::registry& registry, entt::entity entity, void* data)
{
registry.emplace<T>(entity);
};
std::scoped_lock lock(Mutex);
Commands.push_back(command);
}
template<typename T>
inline void FactoryCommandQueue::RemoveComponent(entt::entity entity)
{
FactoryCommand command;
command.Entity = entity;
command.Data = nullptr;
command.Command = [](entt::registry& registry, entt::entity entity, void* data)
{
registry.remove<T>(entity);
};
std::scoped_lock lock(Mutex);
Commands.push_back(command);
}
// inline void FactoryCommandQueue::RemoveEntity(entt::entity entity)
// { // {
// FactoryCommand command; // FactoryCommand command;
// command.Entity = entity; // command.Entity = entity;
// command.Data = nullptr; // command.Data = nullptr;
// command.Command = [](entt::registry& registry, entt::entity entity, void* data) // command.Command = [](entt::registry& registry, entt::entity entity, void* data)
// { // {
// registry.destroy(entity); // registry.emplace<T>(entity);
// }; // };
// std::scoped_lock lock(Mutex); // std::scoped_lock lock(Mutex);
// Commands.push_back(command); // Commands.push_back(command);
// } // }
// template<typename T>
// inline void FactoryCommandQueue::RemoveComponent(entt::entity entity)
// {
// FactoryCommand command;
// command.Entity = entity;
// command.Data = nullptr;
// command.Command = [](entt::registry& registry, entt::entity entity, void* data)
// {
// registry.remove<T>(entity);
// };
// std::scoped_lock lock(Mutex);
// Commands.push_back(command);
// }
// // inline void FactoryCommandQueue::RemoveEntity(entt::entity entity)
// // {
// // FactoryCommand command;
// // command.Entity = entity;
// // command.Data = nullptr;
// // command.Command = [](entt::registry& registry, entt::entity entity, void* data)
// // {
// // registry.destroy(entity);
// // };
// // std::scoped_lock lock(Mutex);
// // Commands.push_back(command);
// // }

View File

@@ -1,159 +1,159 @@
#pragma once // #pragma once
#include <array> // #include <array>
#include "core/templates/vector.h" // #include "core/templates/vector.h"
#include "core/templates/hash_map.h" // #include "core/templates/hash_map.h"
#include "core/object/ref_counted.h" // #include "core/object/ref_counted.h"
#include "modules/noise/fastnoise_lite.h" // #include "modules/noise/fastnoise_lite.h"
#include "core/io/resource.h" // #include "core/io/resource.h"
#include "scene/2d/tile_map_layer.h" // #include "scene/2d/tile_map_layer.h"
#include "core/os/mutex.h" // #include "core/os/mutex.h"
#include "core/templates/hash_set.h" // #include "core/templates/hash_set.h"
#include "core/math/vector2i.h" // #include "core/math/vector2i.h"
#include "Components/Position.h" // #include "Components/Position.h"
#include "Components/Inventory.h" // #include "Components/Inventory.h"
#include "Components/Support.h" // #include "Components/Support.h"
#include "Data/Tile.h" // #include "Data/Tile.h"
#include "Util/ResourceAccess.h" // #include "Util/ResourceAccess.h"
#include "Chunk.h" // #include "Chunk.h"
#include "SystemBase.h" // #include "SystemBase.h"
#include "Data/WorldSettings.h" // #include "Data/WorldSettings.h"
#include "FactoryCommandQueue.h" // #include "FactoryCommandQueue.h"
#include "WorldThreadData.h" // #include "WorldThreadData.h"
class FactoryWorld; // class FactoryWorld;
class FactoryWorldInterface; // class FactoryWorldInterface;
// typedef ResourceAccess<FactoryWorld, Mutex> FactoryWorldAccess; // // typedef ResourceAccess<FactoryWorld, Mutex> FactoryWorldAccess;
enum FactoryError // enum FactoryError
{ // {
FACTORY_ERROR_NONE = 0, // FACTORY_ERROR_NONE = 0,
FACTORY_ERROR_NOT_ENTITY, // FACTORY_ERROR_NOT_ENTITY,
FACTORY_ERROR_CANT_UPGRADE, // FACTORY_ERROR_CANT_UPGRADE,
FACTORY_ERROR_FULLY_UPGRADED, // FACTORY_ERROR_FULLY_UPGRADED,
FACTORY_ERROR_NOT_ENOUGH_ITEMS, // FACTORY_ERROR_NOT_ENOUGH_ITEMS,
FACTORY_ERROR_NO_SPACE, // FACTORY_ERROR_NO_SPACE,
FACTORY_ERROR_REQUIRES_SUPPORT, // FACTORY_ERROR_REQUIRES_SUPPORT,
FACTORY_ERROR_PATH_TOO_LONG, // FACTORY_ERROR_PATH_TOO_LONG,
FACTORY_ERROR_INVALID_PATH, // FACTORY_ERROR_INVALID_PATH,
FACTORY_ERROR_INVALID_POS, // FACTORY_ERROR_INVALID_POS,
FACTORY_ERROR_MISC_ERROR, // FACTORY_ERROR_MISC_ERROR,
}; // };
struct ChunkUnlock final // struct ChunkUnlock final
{ // {
ChunkKey ChunkID{}; // ChunkKey ChunkID{};
Vector<ItemAmount64> Items{}; // Vector<ItemAmount64> Items{};
}; // };
class FactoryWorld final // class FactoryWorld final
{ // {
friend class WorldSerializer; // friend class WorldSerializer;
friend class WorldLoader; // friend class WorldLoader;
public: // public:
FactoryWorld() = default; // FactoryWorld() = default;
~FactoryWorld() = default; // ~FactoryWorld() = default;
public: // public:
void Tick(int amount = 1); // void Tick(int amount = 1);
void Initialize(FactoryWorldInterface* worldInterface); // void Initialize(FactoryWorldInterface* worldInterface);
void Save(); // void Save();
public: // public:
int32_t GetSeed() const { return Seed; } // int32_t GetSeed() const { return Seed; }
FactoryError CanPlaceEntity(int x, int y, Ref<Archetype> archetype); // FactoryError CanPlaceEntity(int x, int y, Ref<Archetype> archetype);
FactoryError AddEntity(int x, int y, Ref<Archetype> archetype); // FactoryError AddEntity(int x, int y, Ref<Archetype> archetype);
void RemoveEntity(FactoryEntity* node); // void RemoveEntity(FactoryEntity* node);
void RemoveEntity(int x, int y); // void RemoveEntity(int x, int y);
void RemoveEntity(entt::entity entity); // void RemoveEntity(entt::entity entity);
// FactoryWorldAccess GetAccess() { return FactoryWorldAccess{ *this, WorldAccessMutex }; } // // FactoryWorldAccess GetAccess() { return FactoryWorldAccess{ *this, WorldAccessMutex }; }
entt::registry& GetRegistry() { return Registry; }; // entt::registry& GetRegistry() { return Registry; };
const entt::registry& GetRegistry() const { return Registry; }; // const entt::registry& GetRegistry() const { return Registry; };
auto& GetChunks() { return Chunks; } // auto& GetChunks() { return Chunks; }
const auto& GetChunks() const { return Chunks; } // const auto& GetChunks() const { return Chunks; }
auto& GetSettings() const { return WorldSettings; } // auto& GetSettings() const { return WorldSettings; }
bool IsValidCameraPos(Rect2i viewport) const; // bool IsValidCameraPos(Rect2i viewport) const;
public: // Chunks // public: // Chunks
FactoryError TryUnlockChunk(ChunkKey chunk); // FactoryError TryUnlockChunk(ChunkKey chunk);
private: // private:
void RefreshUnlockedChunks(); // void RefreshUnlockedChunks();
private: // private:
entt::entity CreateEntity(); // entt::entity CreateEntity();
FactoryError AddEntity(int x, int y, Ref<Archetype> archetype, entt::entity entityID); // FactoryError AddEntity(int x, int y, Ref<Archetype> archetype, entt::entity entityID);
void InvalidateCachedChunk(); // void InvalidateCachedChunk();
public: // UPGRADING // public: // UPGRADING
FactoryError TryUpgradeEntity(FactoryEntity* entity); // FactoryError TryUpgradeEntity(FactoryEntity* entity);
FactoryError TryUpgradeEntity(entt::entity entity); // FactoryError TryUpgradeEntity(entt::entity entity);
FactoryError TryUpgradeEntity(const Vector2i& position); // FactoryError TryUpgradeEntity(const Vector2i& position);
FactoryError CanUpgradeEntity(entt::entity entity) const; // FactoryError CanUpgradeEntity(entt::entity entity) const;
FactoryError CanUpgradeEntity(FactoryEntity* entity) const; // FactoryError CanUpgradeEntity(FactoryEntity* entity) const;
FactoryError CanUpgradeEntity(const Vector2i& position); // FactoryError CanUpgradeEntity(const Vector2i& position);
private: // private:
void UpgradeEntity(entt::entity entity); // void UpgradeEntity(entt::entity entity);
void UpgradeEntity(entt::entity entity, Ref<Archetype> archetype); // void UpgradeEntity(entt::entity entity, Ref<Archetype> archetype);
void SetEntityLevel(entt::entity entity, uint8_t level); // void SetEntityLevel(entt::entity entity, uint8_t level);
void SetEntityLevel(entt::entity entity, Ref<Archetype> archetype, uint8_t level); // void SetEntityLevel(entt::entity entity, Ref<Archetype> archetype, uint8_t level);
public: // QUERY // public: // QUERY
void HighlightUpgradableEntities(TileMapLayer* tilemap) const; // void HighlightUpgradableEntities(TileMapLayer* tilemap) const;
FactoryError FindChutePath(Vector<Vector2i>& path, Vector2i startPos, Vector2i endPos) const; // FactoryError FindChutePath(Vector<Vector2i>& path, Vector2i startPos, Vector2i endPos) const;
Tile const* Raycast(Vector2i startPos, Vector2i endPos) const; // Tile const* Raycast(Vector2i startPos, Vector2i endPos) const;
bool IsSupport(int x, int y) const; // bool IsSupport(int x, int y) const;
bool IsSupport(entt::entity entity) const; // bool IsSupport(entt::entity entity) const;
public: // INVENTORY // public: // INVENTORY
void SetInventory(const Vector<Ref<ItemConfig>>& items); // void SetInventory(const Vector<Ref<ItemConfig>>& items);
Inventory& GetInventory() { return WorldInventory; } // Inventory& GetInventory() { return WorldInventory; }
const Inventory& GetInventory() const { return WorldInventory; } // const Inventory& GetInventory() const { return WorldInventory; }
Inventory GetWorldInventory(Vector2 position) const; // Inventory GetWorldInventory(Vector2 position) const;
Inventory GetWorldInventory(entt::entity entity) const; // Inventory GetWorldInventory(entt::entity entity) const;
public: // DATA // public: // DATA
const Recipe& GetRecipe(Ref<RecipeConfig> config) { return WorldInstanceData.GetRecipe(config); } // const Recipe& GetRecipe(Ref<RecipeConfig> config) { return WorldInstanceData.GetRecipe(config); }
public: // SUPPORT // public: // SUPPORT
// FactoryError CanPlaceSupport(int x, int y) const; // // FactoryError CanPlaceSupport(int x, int y) const;
// FactoryError CanRemoveSupport(int x, int y) const; // // FactoryError CanRemoveSupport(int x, int y) const;
// void RegisterSupport(int x, int y, Support& support); // // void RegisterSupport(int x, int y, Support& support);
// void RemoveSupport(int x, int y); // // void RemoveSupport(int x, int y);
private: // private:
bool SupportCheckerHelper(entt::entity entity) const; // bool SupportCheckerHelper(entt::entity entity) const;
uint8_t SupportValueHelper(entt::entity entity) const; // uint8_t SupportValueHelper(entt::entity entity) const;
uint8_t GetSupportValue(int x, int y) const; // uint8_t GetSupportValue(int x, int y) const;
bool CheckIfSupportHelper(entt::entity entity, Support& support) const; // bool CheckIfSupportHelper(entt::entity entity, Support& support) const;
void ConnectSupports(Vector2i pos, Support& support, Vector2i direction); // void ConnectSupports(Vector2i pos, Support& support, Vector2i direction);
private: // private:
Mutex WorldAccessMutex; // Mutex WorldAccessMutex;
// std::shared_ptr<FactoryCommandQueue> CommandQueue = std::make_shared<FactoryCommandQueue>(); // // std::shared_ptr<FactoryCommandQueue> CommandQueue = std::make_shared<FactoryCommandQueue>();
// FactoryWorldInterface* Interface; // // FactoryWorldInterface* Interface;
ChunkCollection Chunks{}; // ChunkCollection Chunks{};
entt::registry Registry{}; // entt::registry Registry{};
Ref<FactoryWorldSettings> WorldSettings{}; // Ref<FactoryWorldSettings> WorldSettings{};
int32_t Seed{}; // int32_t Seed{};
int32_t LastDrawnFrame{}; // int32_t LastDrawnFrame{};
Inventory64 WorldInventory; // Inventory64 WorldInventory;
WorldData WorldInstanceData; // WorldData WorldInstanceData;
Vector<ChunkKey> UnlockedChunks{ ChunkKey{} }; // Vector<ChunkKey> UnlockedChunks{ ChunkKey{} };
Vector<ChunkUnlock> UnlockableChunks{}; // Vector<ChunkUnlock> UnlockableChunks{};
}; // };

View File

@@ -1,95 +1,95 @@
#pragma once // #pragma once
#include "Data/WorldSettings.h" // #include "Data/WorldSettings.h"
#include "Chunk.h" // #include "Chunk.h"
class FactoryWorld; // class FactoryWorld;
// class WorldGenerator final // // class WorldGenerator final
// // {
// // public:
// // public:
// // WorldGenerator() = default;
// // WorldGenerator(Ref<FactoryWorldSettings> settings, int32_t seed);
// // public:
// // // bool GenerateChunk(ChunkKey chunkKey, Chunk& chunk) const;
// // // bool GenerateChunk(ChunkKey chunkKey, Chunk& chunk, Ref<LayerConfig> layer, Ref<LayerConfig> nextLayer = {}) const;
// // // Vector<SpawnedEntities> SpawnEntities(ChunkKey chunkKey, Chunk& chunk, const std::vector<EntityTile>& persistantEntities = {}) const;
// // // Vector<SpawnedEntities> SpawnEntities(ChunkKey chunkKey, Chunk& chunk, Ref<LayerConfig> layer, Ref<LayerConfig> nextLayer = {}, const std::vector<EntityTile>& persistantEntities = {}) const;
// // // std::unique_ptr<CreatedVisualsChunk> CreateChunkVisuals(ChunkKey chunkKey, Chunk& chunk);
// // public:
// // void ThreadedGenerateChunk(ChunkKey chunkKey, std::function<void(ChunkData&&)> callback, const std::vector<EntityTile>& persistantEntities = {});
// // private:
// // public:
// // Ref<FactoryWorldSettings> Settings{};
// // WorldGraph Graph{};
// // int32_t Seed{};
// // };
// class ChunkGenerator final
// { // {
// public: // public:
// struct SpawnedEntities
// {
// public: // Ref<Archetype> Archetype{};
// WorldGenerator() = default; // Vector2i SpawnPosition{};
// WorldGenerator(Ref<FactoryWorldSettings> settings, int32_t seed); // Vector<Vector2i> ClaimedPositions{};
// public:
// // bool GenerateChunk(ChunkKey chunkKey, Chunk& chunk) const;
// // bool GenerateChunk(ChunkKey chunkKey, Chunk& chunk, Ref<LayerConfig> layer, Ref<LayerConfig> nextLayer = {}) const;
// // Vector<SpawnedEntities> SpawnEntities(ChunkKey chunkKey, Chunk& chunk, const std::vector<EntityTile>& persistantEntities = {}) const;
// // Vector<SpawnedEntities> SpawnEntities(ChunkKey chunkKey, Chunk& chunk, Ref<LayerConfig> layer, Ref<LayerConfig> nextLayer = {}, const std::vector<EntityTile>& persistantEntities = {}) const;
// // std::unique_ptr<CreatedVisualsChunk> CreateChunkVisuals(ChunkKey chunkKey, Chunk& chunk);
// public:
// void ThreadedGenerateChunk(ChunkKey chunkKey, std::function<void(ChunkData&&)> callback, const std::vector<EntityTile>& persistantEntities = {});
// private:
// public:
// Ref<FactoryWorldSettings> Settings{};
// WorldGraph Graph{};
// int32_t Seed{};
// }; // };
class ChunkGenerator final // struct CreatedVisualsTile
{ // {
public: // CreatedVisualsTile() = default;
struct SpawnedEntities // CreatedVisualsTile(uint16_t atlasCoordinateX, uint16_t atlasCoordinateY, uint16_t atlasIndex) : AtlasCoordinateX{ atlasCoordinateX }, AtlasCoordinateY{ atlasCoordinateY }, AtlasIndex{ atlasIndex } {};
{
Ref<Archetype> Archetype{};
Vector2i SpawnPosition{};
Vector<Vector2i> ClaimedPositions{};
};
struct CreatedVisualsTile // uint16_t AtlasCoordinateX{};
{ // uint16_t AtlasCoordinateY{};
CreatedVisualsTile() = default; // uint16_t AtlasIndex{};
CreatedVisualsTile(uint16_t atlasCoordinateX, uint16_t atlasCoordinateY, uint16_t atlasIndex) : AtlasCoordinateX{ atlasCoordinateX }, AtlasCoordinateY{ atlasCoordinateY }, AtlasIndex{ atlasIndex } {}; // };
uint16_t AtlasCoordinateX{};
uint16_t AtlasCoordinateY{};
uint16_t AtlasIndex{};
};
typedef std::array<CreatedVisualsTile, Chunk::TotalChunkTiles> CreatedVisualsChunk; // typedef std::array<CreatedVisualsTile, Chunk::TotalChunkTiles> CreatedVisualsChunk;
typedef std::array<int8_t, Chunk::TotalChunkTiles> ChunkShadowValues; // typedef std::array<int8_t, Chunk::TotalChunkTiles> ChunkShadowValues;
typedef std::function<void(std::unique_ptr<Chunk>&&)> CreatedChunkCallback; // typedef std::function<void(std::unique_ptr<Chunk>&&)> CreatedChunkCallback;
typedef std::function<void(const Vector<SpawnedEntities>&)> SpawnedEntitiesCallback; // typedef std::function<void(const Vector<SpawnedEntities>&)> SpawnedEntitiesCallback;
typedef std::function<void(CreatedVisualsChunk*)> VisualizedChunkCallback; // typedef std::function<void(CreatedVisualsChunk*)> VisualizedChunkCallback;
typedef std::function<void(ChunkShadowValues*)> ShadowsCallback; // typedef std::function<void(ChunkShadowValues*)> ShadowsCallback;
ChunkGenerator() = default; // ChunkGenerator() = default;
private: // private:
ChunkGenerator(Ref<FactoryWorldSettings> settings, ChunkKey chunk, int32_t seed) : Settings{ settings }, ChunkInfo{ chunk }, Seed{ seed } {}; // ChunkGenerator(Ref<FactoryWorldSettings> settings, ChunkKey chunk, int32_t seed) : Settings{ settings }, ChunkInfo{ chunk }, Seed{ seed } {};
public: // public:
static void GenerateChunk(Ref<FactoryWorldSettings> settings, ChunkKey chunkInfo, int seed, CreatedChunkCallback chunkCallback, SpawnedEntitiesCallback entitiesCallback = {}, VisualizedChunkCallback visualsCallback = {}, ShadowsCallback shadowsCallback = {}); // static void GenerateChunk(Ref<FactoryWorldSettings> settings, ChunkKey chunkInfo, int seed, CreatedChunkCallback chunkCallback, SpawnedEntitiesCallback entitiesCallback = {}, VisualizedChunkCallback visualsCallback = {}, ShadowsCallback shadowsCallback = {});
std::unique_ptr<Chunk> GenerateChunk(); // std::unique_ptr<Chunk> GenerateChunk();
private: // private:
static void GenerateChunk(void* pData); // static void GenerateChunk(void* pData);
void GenerateChunkInternal(CreatedChunkCallback chunkCallback, SpawnedEntitiesCallback entitiesCallback, VisualizedChunkCallback visualsCallback, ShadowsCallback shadowsCallback); // void GenerateChunkInternal(CreatedChunkCallback chunkCallback, SpawnedEntitiesCallback entitiesCallback, VisualizedChunkCallback visualsCallback, ShadowsCallback shadowsCallback);
void GenerateChunkTiles() const; // void GenerateChunkTiles() const;
Vector<SpawnedEntities> SpawnEntities(const std::vector<EntityTile>& persistantEntities = {}) const; // Vector<SpawnedEntities> SpawnEntities(const std::vector<EntityTile>& persistantEntities = {}) const;
std::unique_ptr<CreatedVisualsChunk> CreateVisuals(); // std::unique_ptr<CreatedVisualsChunk> CreateVisuals();
std::unique_ptr<ChunkShadowValues> CascadeShadows(); // std::unique_ptr<ChunkShadowValues> CascadeShadows();
Pair<Ref<LayerConfig>, Ref<LayerConfig>> GetLayers() const; // Pair<Ref<LayerConfig>, Ref<LayerConfig>> GetLayers() const;
void FillChunkCollection(int relativeX, int relativeY, ChunkCollection& collection) const; // void FillChunkCollection(int relativeX, int relativeY, ChunkCollection& collection) const;
void CascadeShadows_Recursive(std::array<int8_t, WorldNodeParameters::PaddedChunkSize>& values, int posX, int posY, int value); // void CascadeShadows_Recursive(std::array<int8_t, WorldNodeParameters::PaddedChunkSize>& values, int posX, int posY, int value);
Tile GetTile(int x, int y) const; // Tile GetTile(int x, int y) const;
bool InBounds(int x, int y) const; // bool InBounds(int x, int y) const;
private: // private:
Ref<FactoryWorldSettings> Settings{}; // Ref<FactoryWorldSettings> Settings{};
ChunkKey ChunkInfo{}; // ChunkKey ChunkInfo{};
int32_t Seed{}; // int32_t Seed{};
std::unique_ptr<WorldNodeParameters::TileArray> TileArray{}; // std::unique_ptr<WorldNodeParameters::TileArray> TileArray{};
}; // };

View File

@@ -2,19 +2,19 @@
#include "Item.hpp" #include "Item.hpp"
struct alignas(4) ItemFilter final // struct alignas(4) ItemFilter final
{ // {
uint16_t FilterItem0; // uint16_t FilterItem0;
uint16_t FilterItem1; // uint16_t FilterItem1;
uint16_t FilterItem2; // uint16_t FilterItem2;
//Item::ItemFlags FilterFlags; // //Item::ItemFlags FilterFlags;
public: // public:
inline bool ApplyFilter(Item item) // inline bool ApplyFilter(Item item)
{ // {
return //(item.Flags & FilterFlags) && // return //(item.Flags & FilterFlags) &&
(FilterItem0 == 0 || FilterItem0 == item.ItemID) && // (FilterItem0 == 0 || FilterItem0 == item.ItemID) &&
(FilterItem1 == 0 || FilterItem1 == item.ItemID) && // (FilterItem1 == 0 || FilterItem1 == item.ItemID) &&
(FilterItem2 == 0 || FilterItem2 == item.ItemID); // (FilterItem2 == 0 || FilterItem2 == item.ItemID);
} // }
}; // };

View File

@@ -1,60 +1,21 @@
#pragma once #pragma once
#include "core/string/string_name.h" #include <stdint.h>
#include "core/io/resource.h"
#include "scene/resources/texture.h"
#include "modules/factory/thirdParty/EnTT/entity/entity.hpp"
#include "modules/factory/include/Util/Helpers.h"
// If tile data uses all 4 bytes, it is an entity, enum class TileType : uint8_t
// if it uses only 2 bytes it is a tile
// if it is 0, it is air
// struct Tile final
// {
// private:
// union TileData
// {
// uint32_t Data;
// entt::entity Entity;
// uint16_t TileID;
// };
// static_assert(sizeof(TileData) == sizeof(uint32_t));
// TileData Data{};
// static constexpr uint32_t TileMask = 0x80000000;
// public:
// Tile() = default;
// Tile(uint16_t id) { Data.Data = id | TileMask; }
// Tile(entt::entity entity) { DEV_ASSERT(IsValidEntity(entity)); Data.Entity = entity; }
// public:
// constexpr bool IsAir() const { return Data.Data == 0; }
// constexpr bool IsTile() const { return (Data.Data & TileMask) != 0; }
// constexpr bool IsEntity() const { return !IsAir() && !IsTile(); }
// static constexpr bool IsValidEntity(entt::entity entity) { return (((uint32_t)entity) & TileMask) == 0; }
// public:
// entt::entity GetEntity() const { DEV_ASSERT(IsEntity()); return Data.Entity; }
// uint16_t GetTileID() const { DEV_ASSERT(IsTile()); return Data.TileID; }
// };
enum TILE_TYPE : uint8_t
{ {
TILE_AIR, Air,
TILE_FILLER, Filler,
TILE_LIQUID, Liquid,
TILE_ORE, Ore,
TILE_NPC, NPC,
TILE_PLANT, Plant,
TILE_MAX, MAX,
TILE_NONE = 0b111, NONE = 0b111,
}; };
VARIANT_ENUM_CAST(TILE_TYPE); static_assert(static_cast<uint8_t>(TileType::MAX) <= static_cast<uint8_t>(TileType::NONE));
static_assert(TILE_MAX <= TILE_NONE);
const char* TileTypeEnumString = "Air,Filler,Liquid,Ore,Npc,Plant,,None";
struct Tile final struct Tile final
{ {
@@ -80,25 +41,25 @@ public:
constexpr bool HasEntity() const { return Data & MaskEntity; } constexpr bool HasEntity() const { return Data & MaskEntity; }
constexpr uint16_t GetID() const { return Data & MaskID; } constexpr uint16_t GetID() const { return Data & MaskID; }
constexpr bool IsAir() const { return GetType() == TILE_AIR; } constexpr bool IsAir() const { return GetType() == TileType::Air; }
constexpr bool IsFiller() const { return GetType() == TILE_FILLER; } constexpr bool IsFiller() const { return GetType() == TileType::Filler; }
constexpr bool IsLiquid() const { return GetType() == TILE_LIQUID; } constexpr bool IsLiquid() const { return GetType() == TileType::Liquid; }
constexpr bool IsOre() const { return GetType() == TILE_ORE; } constexpr bool IsOre() const { return GetType() == TileType::Ore; }
constexpr bool IsPlant() const { return GetType() == TILE_PLANT; } constexpr bool IsPlant() const { return GetType() == TileType::Plant; }
constexpr bool IsNPC() const { return GetType() == TILE_NPC; } constexpr bool IsNPC() const { return GetType() == TileType::NPC; }
constexpr TILE_TYPE GetType() const { return static_cast<TILE_TYPE>((Data & MaskType) >> BytesID); } constexpr TileType GetType() const { return static_cast<TileType>((Data & MaskType) >> BytesID); }
constexpr bool IsType(TILE_TYPE type) const { return GetType() == type; } constexpr bool IsType(TileType type) const { return GetType() == type; }
void SetID(uint16_t id) { Data = (Data & ~MaskID) | (id & MaskID); } void SetID(uint16_t id) { Data = (Data & ~MaskID) | (id & MaskID); }
void SetAir() { SetType(TILE_AIR); } void SetAir() { SetType(TileType::Air); }
void SetFiller() { SetType(TILE_FILLER); } void SetFiller() { SetType(TileType::Filler); }
void SetLiquid() { SetType(TILE_LIQUID); } void SetLiquid() { SetType(TileType::Liquid); }
void SetOre() { SetType(TILE_ORE); } void SetOre() { SetType(TileType::Ore); }
void SetPlant() { SetType(TILE_PLANT); } void SetPlant() { SetType(TileType::Plant); }
void SetNPC() { SetType(TILE_NPC); } void SetNPC() { SetType(TileType::NPC); }
void SetType(TILE_TYPE type) { Data = (Data & ~MaskType) | (type << BytesID); } void SetType(TileType type) { Data = (Data & ~MaskType) | (static_cast<uint16_t>(type) << BytesID); }
constexpr uint16_t AsInt() const { return Data; } constexpr uint16_t AsInt() const { return Data; }
constexpr bool IsValid() const { return Data == MaskID; } constexpr bool IsValid() const { return Data == MaskID; }
@@ -111,66 +72,3 @@ inline constexpr bool operator==(Tile lhs, Tile rhs) { return lhs.AsInt() == rhs
inline constexpr bool operator!=(Tile lhs, Tile rhs) { return lhs.AsInt() != rhs.AsInt(); } inline constexpr bool operator!=(Tile lhs, Tile rhs) { return lhs.AsInt() != rhs.AsInt(); }
static_assert(sizeof(Tile) == 2); static_assert(sizeof(Tile) == 2);
class TextureWeight final : public Resource
{
GDCLASS(TextureWeight, Resource);
static void _bind_methods();
public:
Ref<Texture2D> GetTexture() const { return Texture; }
uint16_t GetWeight() const { return Weight; }
void SetTexture(Ref<Texture2D> texture) { Texture = texture; }
void SetWeight(uint16_t weight) { Weight = weight; }
public:
Ref<Texture2D> Texture{};
uint16_t Weight{1};
uint16_t AtlasIndex{};
uint16_t AtlasX{};
uint16_t AtlasY{};
};
class TileConfig;
class TileTransitionConfig final : public Resource
{
GDCLASS(TileTransitionConfig, Resource);
static void _bind_methods();
public:
auto GetNeighbor() const { return Neighbor; }
auto GetPossibleTextures() const { return VectorToTypedArray(PossibleTextures); }
void SetNeighbor(Ref<TileConfig> neighbor) { Neighbor = neighbor; }
void SetPossibleTextures(TypedArray<TextureWeight> textures) { PossibleTextures = TypedArrayToVector(textures); }
public:
Ref<TileConfig> Neighbor;
Vector<Ref<TextureWeight>> PossibleTextures;
};
class TileConfig final : public Resource
{
GDCLASS(TileConfig, Resource);
public:
static void _bind_methods();
public:
uint16_t GetID() const { return TileData.GetID(); }
TILE_TYPE GetType() const { return TileData.GetType(); }
auto GetTextures() const { return VectorToTypedArray(PossibleTextures); }
auto GetTransitions() const { return VectorToTypedArray(NeighborTransitions); }
auto GetLightResistance() const { return VectorToTypedArray(NeighborTransitions); }
void SetID(uint16_t id) { TileData.SetID(id); }
void SetTextures(TypedArray<TextureWeight> val) { PossibleTextures = TypedArrayToVector(val); }
void SetTransitions(TypedArray<TileTransitionConfig> val) { NeighborTransitions = TypedArrayToVector(val); }
void SetType(TILE_TYPE type) { TileData.SetType(type); }
void SetLightResistance(int resistance) { LightResistance = resistance; }
public:
Tile TileData{};
// Vector<Ref<TextureWeight>> PossibleTextures;
// Vector<Ref<TileTransitionConfig>> NeighborTransitions;
int LightResistance{};
};