Large Refactor, half-finished, will not compile or run currently.
This commit is contained in:
@@ -13,7 +13,7 @@ if (PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
|
||||
message(FATAL_ERROR "In-source builds are not allowed")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
|
||||
# Set for profiling
|
||||
|
||||
|
@@ -82,7 +82,7 @@ namespace CaveGame::Client {
|
||||
|
||||
void UnloadHUD();
|
||||
|
||||
Core::TileID GetTileUnderMouse();
|
||||
uint16_t GetTileIDUnderMouse();
|
||||
|
||||
[[nodiscard]] JUI::Scene* HUD() const { return hud; }
|
||||
LocalWorld* World() const { return world;}
|
||||
|
@@ -285,7 +285,7 @@ void CaveGame::Client::GameSession::UnloadHUD() {
|
||||
delete hud;
|
||||
}
|
||||
|
||||
CaveGame::Core::TileID CaveGame::Client::GameSession::GetTileUnderMouse() {
|
||||
uint16_t CaveGame::Client::GameSession::GetTileIDUnderMouse() {
|
||||
auto ipos = InputService::GetMousePosition();
|
||||
Vector2 pos = Vector2(ipos.x, ipos.y);
|
||||
|
||||
|
@@ -1,17 +1,22 @@
|
||||
[
|
||||
{
|
||||
"mnemonic-id" : "void",
|
||||
"display-name" : "VOID",
|
||||
"mnemonic-id": "void",
|
||||
"display-name": "Void",
|
||||
"item-tooltip": "How did you even get this?",
|
||||
"solid": true,
|
||||
"does-random-ticc": false,
|
||||
"does-forced-ticc": false,
|
||||
"color": "#FFFFFF",
|
||||
"pallet": [],
|
||||
"hardcoded-id": 65536
|
||||
"hardcoded-id": 65536,
|
||||
"random-ticc-func": "spread-self",
|
||||
"spreads-to": "dirt",
|
||||
"decays-to": "",
|
||||
"draw-func": ""
|
||||
},
|
||||
{
|
||||
"mnemonic-id" : "air",
|
||||
"display-name" : "AIR",
|
||||
"display-name" : "Air",
|
||||
"solid": true,
|
||||
"does-random-ticc": false,
|
||||
"does-forced-ticc": false,
|
||||
@@ -21,7 +26,7 @@
|
||||
},
|
||||
{
|
||||
"mnemonic-id" : "stone",
|
||||
"display-name" : "",
|
||||
"display-name" : "Stone",
|
||||
"solid": true,
|
||||
"does-random-ticc": false,
|
||||
"does-forced-ticc": false,
|
||||
@@ -29,7 +34,43 @@
|
||||
"pallet": []
|
||||
},
|
||||
{
|
||||
"mnemonic-id" : "stone",
|
||||
"mnemonic-id" : "dirt",
|
||||
"display-name" : "Dirt",
|
||||
"solid": true,
|
||||
"does-random-ticc": false,
|
||||
"does-forced-ticc": false,
|
||||
"color": "#FFFFFF",
|
||||
"pallet": []
|
||||
},
|
||||
{
|
||||
"mnemonic-id" : "mud",
|
||||
"display-name" : "Mud",
|
||||
"solid": true,
|
||||
"does-random-ticc": false,
|
||||
"does-forced-ticc": false,
|
||||
"color": "#FFFFFF",
|
||||
"pallet": []
|
||||
},
|
||||
{
|
||||
"mnemonic-id" : "limestone",
|
||||
"display-name" : "Mud",
|
||||
"solid": true,
|
||||
"does-random-ticc": false,
|
||||
"does-forced-ticc": false,
|
||||
"color": "#FFFFFF",
|
||||
"pallet": []
|
||||
},
|
||||
{
|
||||
"mnemonic-id" : "basalt",
|
||||
"display-name" : "Mud",
|
||||
"solid": true,
|
||||
"does-random-ticc": false,
|
||||
"does-forced-ticc": false,
|
||||
"color": "#FFFFFF",
|
||||
"pallet": []
|
||||
},
|
||||
{
|
||||
"mnemonic-id" : "cobblestone",
|
||||
"display-name" : "",
|
||||
"solid": true,
|
||||
"does-random-ticc": false,
|
||||
@@ -41,7 +82,53 @@
|
||||
"drops" : null
|
||||
},
|
||||
{
|
||||
"mnemonic-id" : "stone",
|
||||
"mnemonic-id" : "red-moss",
|
||||
"display-name" : "Mud",
|
||||
"solid": true,
|
||||
"does-random-ticc": false,
|
||||
"does-forced-ticc": false,
|
||||
"color": "#FFFFFF",
|
||||
"pallet": []
|
||||
},
|
||||
|
||||
{
|
||||
"mnemonic-id" : "brown-moss",
|
||||
"display-name" : "",
|
||||
"solid": true,
|
||||
"does-random-ticc": false,
|
||||
"does-forced-ticc": false,
|
||||
"color": "#FFFFFF",
|
||||
"pallet": [],
|
||||
"random-ticc-func": "zzyyzz",
|
||||
"forced-ticc-func": "zzyyzz",
|
||||
"drops" : null
|
||||
},
|
||||
{
|
||||
"mnemonic-id" : "green-moss",
|
||||
"display-name" : "",
|
||||
"solid": true,
|
||||
"does-random-ticc": false,
|
||||
"does-forced-ticc": false,
|
||||
"color": "#FFFFFF",
|
||||
"pallet": [],
|
||||
"random-ticc-func": "zzyyzz",
|
||||
"forced-ticc-func": "zzyyzz",
|
||||
"drops" : null
|
||||
},
|
||||
{
|
||||
"mnemonic-id" : "lava-moss",
|
||||
"display-name" : "",
|
||||
"solid": true,
|
||||
"does-random-ticc": false,
|
||||
"does-forced-ticc": false,
|
||||
"color": "#FFFFFF",
|
||||
"pallet": [],
|
||||
"random-ticc-func": "zzyyzz",
|
||||
"forced-ticc-func": "zzyyzz",
|
||||
"drops" : null
|
||||
},
|
||||
{
|
||||
"mnemonic-id" : "granite",
|
||||
"display-name" : "",
|
||||
"solid": true,
|
||||
"does-random-ticc": false,
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include <Core/Player.hpp>
|
||||
#include <Core/Explosion.hpp>
|
||||
|
||||
|
||||
namespace CaveGame::ClientApp {
|
||||
|
||||
using CaveGame::Client::Scene;
|
||||
|
@@ -23,75 +23,9 @@
|
||||
#include <JGL/logger/logger.h>
|
||||
#include <JJX/JSON.hpp>
|
||||
|
||||
std::string read_file(const std::string& file_path)
|
||||
{
|
||||
std::ifstream file(file_path, std::ios::binary);
|
||||
if (!file)
|
||||
throw std::runtime_error("We couldn't find the file: " + file_path);
|
||||
|
||||
std::streamsize file_size;
|
||||
file.seekg(0, std::ios::end);
|
||||
file_size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
std::string file_content(file_size, '\0');
|
||||
file.read(&file_content[0], file_size);
|
||||
file.close();
|
||||
|
||||
return file_content;
|
||||
}
|
||||
|
||||
struct tile_meta
|
||||
{
|
||||
std::string mnemonic;
|
||||
std::optional<std::vector<Color4>> pallet;
|
||||
Color4 color;
|
||||
bool solid;
|
||||
bool does_random_ticc;
|
||||
bool does_forced_ticc;
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
std::vector<tile_meta> tile_dataset;
|
||||
|
||||
using namespace JJX;
|
||||
std::string content = read_file("assets/data/tiles/base_tiles.json");
|
||||
|
||||
auto [data, parse_error] = json::parse(content);
|
||||
|
||||
if (data.type == json::value_type::array)
|
||||
{
|
||||
auto arr_data = json::array_val(data);
|
||||
for (auto& t : arr_data.array.value()) {
|
||||
std::cout << (int)t.type << std::endl;
|
||||
|
||||
auto tile_meta_json = json::object_val(t);
|
||||
|
||||
tile_meta data;
|
||||
data.mnemonic = tile_meta_json["mnemonic-id"];
|
||||
json::value color_field = tile_meta_json["color"];
|
||||
|
||||
if (color_field.type == json::value_type::string)
|
||||
data.color = Color4::FromHexA(color_field.string.value());
|
||||
else if (color_field.type == json::value_type::array)
|
||||
{
|
||||
auto color_array = json::array_val(color_field);
|
||||
int r = color_array[0].number.value();
|
||||
int g = color_array[1].number.value();
|
||||
int b = color_array[2].number.value();
|
||||
int a = 255;
|
||||
if (color_array.array.value().size() == 4)
|
||||
a = color_array[3].number.value();
|
||||
data.color = Color4(r, g, b, a);
|
||||
}
|
||||
|
||||
|
||||
tile_dataset.push_back(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Hide logs from engine components so we can focus on CaveGame.
|
||||
JGL::Logger::Warning.EnableConsole(false);
|
||||
JGL::Logger::Debug.EnableConsole(false);
|
||||
|
@@ -8,11 +8,74 @@
|
||||
#include <ReWindow/InputService.h>
|
||||
#include <Core/Macros.hpp>
|
||||
#include <jstick.hpp>
|
||||
#include <Core/TileRegistry.hpp>
|
||||
#include <JJX/JSON.hpp>
|
||||
|
||||
namespace CaveGame::ClientApp
|
||||
{
|
||||
|
||||
std::string read_file(const std::string& file_path)
|
||||
{
|
||||
std::ifstream file(file_path, std::ios::binary);
|
||||
if (!file)
|
||||
throw std::runtime_error("We couldn't find the file: " + file_path);
|
||||
|
||||
std::streamsize file_size;
|
||||
file.seekg(0, std::ios::end);
|
||||
file_size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
std::string file_content(file_size, '\0');
|
||||
file.read(&file_content[0], file_size);
|
||||
file.close();
|
||||
|
||||
return file_content;
|
||||
}
|
||||
|
||||
void ReadTileDataAndRegister()
|
||||
{
|
||||
Core::Tile tile;
|
||||
|
||||
using namespace JJX;
|
||||
std::string content = read_file("assets/data/tiles/base_tiles.json");
|
||||
|
||||
auto [data, parse_error] = json::parse(content);
|
||||
|
||||
if (data.type == json::value_type::array)
|
||||
{
|
||||
auto arr_data = json::array_val(data);
|
||||
for (auto& t : arr_data.array.value()) {
|
||||
std::cout << (int)t.type << std::endl;
|
||||
|
||||
auto tile_meta_json = json::object_val(t);
|
||||
|
||||
tile.mnemonic_id = tile_meta_json["mnemonic-id"];
|
||||
json::value color_field = tile_meta_json["color"];
|
||||
|
||||
if (color_field.type == json::value_type::string)
|
||||
tile.color = Color4::FromHexA(color_field.string.value());
|
||||
else if (color_field.type == json::value_type::array)
|
||||
{
|
||||
auto color_array = json::array_val(color_field);
|
||||
int r = color_array[0].number.value();
|
||||
int g = color_array[1].number.value();
|
||||
int b = color_array[2].number.value();
|
||||
int a = 255;
|
||||
if (color_array.array.value().size() == 4)
|
||||
a = color_array[3].number.value();
|
||||
tile.color = Color4(r, g, b, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Core::Tiles().Register(tile);
|
||||
}
|
||||
|
||||
CaveGameWindow::CaveGameWindow(const std::string& title, int width, int height): ReWindow::OpenGLWindow(title, width, height, 2, 1)
|
||||
{
|
||||
Logs::Info("Parsing Tile Data.");
|
||||
ReadTileDataAndRegister();
|
||||
Logs::Info("Creating game window.");
|
||||
|
||||
CreateContexts();
|
||||
@@ -281,8 +344,8 @@ namespace CaveGame::ClientApp
|
||||
|
||||
|
||||
if (current_scene == GameSession()) {
|
||||
Core::TileID id = game_ctx->GetTileUnderMouse();
|
||||
Core::Tile* data = Core::GetByNumeric(id);
|
||||
Core::TileID id = game_ctx->GetTileIDUnderMouse();
|
||||
Core::Tile& data = Core::Tiles::GetInstance()->GetByNumericID(id);
|
||||
|
||||
debug_lines.push_back(std::format("tile: {} id: {}", data->MnemonicID(), (unsigned int)data->NumericID()));
|
||||
debug_lines.push_back(std::format("entities: {}", game_ctx->World()->GetCurrentEntityCount()));
|
||||
@@ -567,11 +630,12 @@ namespace CaveGame::ClientApp
|
||||
void CaveGameWindow::MarkReadyToClose(bool close) { wanna_die = close;}
|
||||
|
||||
bool CaveGameWindow::TileListCmd(const CommandArgs &args) {
|
||||
auto tile_list = Core::GetAllTiles();
|
||||
auto tile_list = Core::Tiles::GetInstance()->GetTileList();
|
||||
|
||||
for (const Core::Tile& tile : tile_list) {
|
||||
Log(std::format("ID: {}, Mnemonic: {}, DisplayName: {}", tile.numeric_id, tile.mnemonic_id, tile.display_name));
|
||||
//if (tile != nullptr)
|
||||
|
||||
for (Core::Tile* tile : tile_list) {
|
||||
if (tile != nullptr)
|
||||
Log(std::format("ID: {}, Mnemonic: {}, DisplayName: {}", (int)tile->NumericID(), tile->MnemonicID(), tile->Name()));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@@ -1,12 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <Core/TileRegistry.hpp>
|
||||
|
||||
namespace CaveGame::Core
|
||||
{
|
||||
// TODO: Consider implementing traits.
|
||||
|
||||
enum class TileID : std::uint16_t
|
||||
using TileID = uint16_t;
|
||||
|
||||
#define SYMBOL(NAME) Tile NAME() { return TileRegistry().GetByMnemonicID("NAME"); }
|
||||
|
||||
namespace MappedIDs
|
||||
{
|
||||
SYMBOL(Void);
|
||||
}
|
||||
|
||||
MappedIDs::Void();
|
||||
/*enum class TileID : std::uint16_t
|
||||
{
|
||||
//
|
||||
AIR = 0,
|
||||
@@ -151,6 +162,6 @@ namespace CaveGame::Core
|
||||
TORCH_EMBER = 256,
|
||||
VOID = 65535,
|
||||
|
||||
};
|
||||
};*/
|
||||
|
||||
}
|
@@ -7,11 +7,14 @@ namespace CaveGame::Core
|
||||
{
|
||||
using TileState = uint16_t;
|
||||
|
||||
|
||||
class ITileMap
|
||||
{
|
||||
public:
|
||||
[[nodiscard]] virtual TileID GetTile(int x, int y) const = 0;
|
||||
|
||||
virtual void SetTile(int x, int y, TileID tile, bool flag_update = true) = 0;
|
||||
virtual void SetTile(int x, int y, const std::string& tile_name, bool flag_update = true) = 0;
|
||||
virtual void SwapTile(int source_x, int source_y, int dest_x, int dest_y, bool flag_update = true) = 0;
|
||||
[[nodiscard]] virtual bool GetTileUpdateFlag(int x, int y) const = 0;
|
||||
virtual void SetTileUpdateFlag(int x, int y, bool flag = true) = 0;
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace CaveGame::Core
|
||||
{
|
||||
|
65
Core/include/Core/Singleton.hpp
Normal file
65
Core/include/Core/Singleton.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/// CaveGame - A procedural 2D platformer sandbox.
|
||||
/// Created by Josh O'Leary @ Redacted Software, 2020-2024
|
||||
/// Contact: josh@redacted.cc
|
||||
/// Contributors: william@redacted.cc maxi@redacted.cc
|
||||
/// This work is dedicated to the public domain.
|
||||
|
||||
/// @file Singleton.hpp
|
||||
/// @desc An abstract class template that creates a corruption-safe, thread-safe Singleton.
|
||||
/// @edit 3/20/2025
|
||||
/// @auth Josh O'Leary
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
|
||||
template <class T>
|
||||
class Singleton
|
||||
{
|
||||
protected:
|
||||
static std::mutex mutex;
|
||||
static T* instance;
|
||||
Singleton();
|
||||
public:
|
||||
/// Delete the copy constructor to prevent copies.
|
||||
Singleton(const Singleton& obj) = delete;
|
||||
|
||||
/// Static method to get the Singleton instance.
|
||||
static T* GetInstance();
|
||||
static T* Instance() { return GetInstance();}
|
||||
static T* operator()() { return GetInstance();}
|
||||
|
||||
T* operator->() { return instance;}
|
||||
const T* operator->() const { return instance;}
|
||||
T& operator*() { return *instance;}
|
||||
const T& operator*() const { return *instance; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
T *Singleton<T>::GetInstance() {
|
||||
if (instance == nullptr) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
instance = new T();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Singleton<T>::Singleton() {
|
||||
// Compile-time sanity check
|
||||
static_assert(std::is_base_of<Singleton, T>::value, "T not derived from Singleton");
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class ReferenceSingleton
|
||||
{
|
||||
protected:
|
||||
static std::mutex mutex;
|
||||
|
||||
public:
|
||||
static T& GetInstance()
|
||||
{
|
||||
static T& instance{};
|
||||
return instance;
|
||||
}
|
||||
};
|
@@ -9,9 +9,14 @@
|
||||
#include <Core/Interfaces.hpp>
|
||||
#include <J3ML/LinearAlgebra/Vector2i.hpp>
|
||||
|
||||
|
||||
namespace CaveGame::Core {
|
||||
using J3ML::LinearAlgebra::Vector2i;
|
||||
|
||||
using TileID = uint16_t;
|
||||
|
||||
struct Tile;
|
||||
|
||||
/*
|
||||
*
|
||||
* Tile and TileTrait example structure
|
||||
@@ -105,114 +110,52 @@ namespace CaveGame::Core {
|
||||
uint8_t g;
|
||||
};
|
||||
|
||||
class TestTile;
|
||||
|
||||
class TileTrait {
|
||||
public:
|
||||
virtual void Invoke(ITileMap* world, int x, int y) {};
|
||||
};
|
||||
|
||||
// Tile trait code to be fully implemented
|
||||
/*//////////////////////////////////////////////////////////////////////////////*/
|
||||
class TestTile
|
||||
{
|
||||
public:
|
||||
TileID numeric_id = TileID::VOID;
|
||||
std::string mnemonic_id;
|
||||
public:
|
||||
Color4 base_color;
|
||||
std::vector<Color4> color_pallet;
|
||||
//TileFlags flags = NonSolid;
|
||||
public:
|
||||
TestTile(TileID id, std::string mnemonic);
|
||||
TileID NumericID() { return numeric_id; }
|
||||
std::string MnemonicID() { return mnemonic_id; }
|
||||
/*
|
||||
bool HasTrait(TileTrait* tr) {
|
||||
Tile* d;
|
||||
if (Tile* d = dynamic_cast<Tile*>(tr); d != nullptr) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
//TileFlags Flags();
|
||||
//bool HasFlag(TileFlags f);
|
||||
virtual void InvokeTraits(ITileMap* world, int x, int y) {};
|
||||
};
|
||||
|
||||
class Ticker : public TileTrait {};
|
||||
class RandomTicker : public Ticker {};
|
||||
class ForcedTicker : public Ticker {};
|
||||
|
||||
class OnCondition : public TileTrait
|
||||
class OnCondition
|
||||
{
|
||||
public:
|
||||
OnCondition();
|
||||
virtual bool Condition(ITileMap* world, int x, int y) { return true; }
|
||||
virtual void Perform(ITileMap* world, int x, int y) {}
|
||||
virtual void Invoke(ITileMap* world, int x, int y) override {
|
||||
virtual void Invoke(ITileMap* world, int x, int y) {
|
||||
if (Condition(world, x, y))
|
||||
Perform(world, x, y);
|
||||
}
|
||||
};
|
||||
|
||||
class DecayTo : public OnCondition
|
||||
{
|
||||
public:
|
||||
TestTile* dt;
|
||||
public:
|
||||
DecayTo(TestTile* dt) : OnCondition(), dt(dt) {};
|
||||
virtual bool Condition(ITileMap* world, int x, int y) override { return true; }
|
||||
virtual void Perform(ITileMap* world, int x, int y) override {
|
||||
world->SetTile(x, y, dt->NumericID());
|
||||
}
|
||||
using ColorPallet = std::vector<Color4>;
|
||||
using TileTiccFunc = std::function<void(const Tile& data, ITileMap* world, int x, int y)>;
|
||||
|
||||
std::unordered_map<std::string, TileTiccFunc> tile_functions {
|
||||
{"check-spread", [](const Tile& data, ITileMap* world, int x, int y){
|
||||
|
||||
}},
|
||||
{"check-decay", [](const Tile& data, ITileMap* world, int x, int y){}},
|
||||
{"check-decay-spread", [](const Tile& data, ITileMap* world, int x, int y){}},
|
||||
{"sand-ticc", [](const Tile& data, ITileMap* world, int x, int y){}},
|
||||
{"water-ticc", [](const Tile& data, ITileMap* world, int x, int y){}},
|
||||
{"liquid-ticc", [](const Tile& data, ITileMap* world, int x, int y)
|
||||
{
|
||||
|
||||
}}
|
||||
};
|
||||
|
||||
class Spreader : public OnCondition
|
||||
{
|
||||
public:
|
||||
TestTile* st;
|
||||
public:
|
||||
Spreader(TestTile* st) : OnCondition(), st(st) {};
|
||||
virtual bool Condition(ITileMap* world, int x, int y) override {
|
||||
return (world->GetTile(x, y) == st->NumericID()) && world->HasAdjacentOrDiagonalAirBlock(x, y);
|
||||
}
|
||||
virtual void Perform(ITileMap* world, int x, int y) override {
|
||||
world->SetTile(x, y, st->NumericID());
|
||||
}
|
||||
struct Tile {
|
||||
std::string mnemonic_id;
|
||||
std::string display_name;
|
||||
std::optional<uint16_t> assigned_numeric_id;
|
||||
uint16_t numeric_id;
|
||||
std::optional<ColorPallet> pallet;
|
||||
bool solid = true;
|
||||
bool collides = false;
|
||||
bool does_random_ticc = false;
|
||||
bool does_forced_ticc = false;
|
||||
Color4 color;
|
||||
};
|
||||
|
||||
/*
|
||||
class Suffocator : public TileTrait
|
||||
{
|
||||
public:
|
||||
Suffocator() : TileTrait() {};
|
||||
public:
|
||||
virtual void Invoke(ITileMap* world, int x, int y) override {
|
||||
if (!world->HasAdjacentOrDiagonalAirBlock(x, y))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};*/
|
||||
/*//////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
class TileGroup {};
|
||||
|
||||
class Tile;
|
||||
|
||||
|
||||
void RegisterTile(Tile* data);
|
||||
|
||||
std::vector<Tile*> GetAllTiles();
|
||||
|
||||
Tile* GetByNumeric(TileID id);
|
||||
|
||||
Tile* GetByName(const std::string& name);
|
||||
|
||||
/// Tiles are instantiated as static members in the Tiles namespace.
|
||||
/// Chunks store tiles by their numeric ID, which can be used to retrieve the tile
|
||||
class Tile
|
||||
/*class Tile
|
||||
{
|
||||
protected:
|
||||
TileID numeric_id = TileID::VOID;
|
||||
@@ -249,15 +192,7 @@ namespace CaveGame::Core {
|
||||
virtual bool ShouldSuffocate(ITileMap* world, int x, int y) const;
|
||||
virtual bool DecayCheck(ITileMap* world, TileState state, int x, int y, TileID decays_to);
|
||||
virtual bool SpreadCheck(ITileMap* world, TileState state, int x, int y, TileID spreads_to) { return false;}
|
||||
};
|
||||
|
||||
class PalletTile : public Tile
|
||||
{
|
||||
void Draw(int wx, int wy, int tx, int ty) override
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
};*/
|
||||
|
||||
class LiquidTile : public Tile
|
||||
{
|
||||
@@ -522,7 +457,7 @@ namespace CaveGame::Core {
|
||||
#define TILE static const Tile
|
||||
|
||||
|
||||
namespace Tiles {
|
||||
/*namespace Tiles {
|
||||
using ID = Core::TileID;
|
||||
static const Tile Void {ID::VOID, "Void", Colors::Transparent};
|
||||
|
||||
@@ -676,6 +611,6 @@ namespace CaveGame::Core {
|
||||
|
||||
static const Tile Rope;
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
|
120
Core/include/Core/TileRegistry.hpp
Normal file
120
Core/include/Core/TileRegistry.hpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#pragma once
|
||||
#include "Singleton.hpp"
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include "Color4.hpp"
|
||||
#include <optional>
|
||||
#include <functional>
|
||||
#include <array>
|
||||
#include <Core/Tile.hpp>
|
||||
|
||||
namespace CaveGame::Core
|
||||
{
|
||||
class ITileMap;
|
||||
|
||||
using ColorPallet = std::vector<Color4>;
|
||||
using TileTiccFunc = std::function<void(const Tile& data, ITileMap* world, int x, int y)>;
|
||||
|
||||
/*std::unordered_map<std::string, TileTiccFunc> tile_functions {
|
||||
{"check-spread", [](const Tile& data, ITileMap* world, int x, int y){
|
||||
|
||||
}},
|
||||
{"check-decay"},
|
||||
{"check-decay-spread"},
|
||||
{"sand-ticc"},
|
||||
{"water-ticc"},
|
||||
};*/
|
||||
|
||||
//using TileID = uint16_t;
|
||||
|
||||
|
||||
class TileRegistry : public Singleton<TileRegistry> {
|
||||
|
||||
public:
|
||||
static constexpr int MaxTiles = 65535;
|
||||
|
||||
void Register(Tile data) {
|
||||
// If an ID is hardcoded to this tile, try to assign it.
|
||||
|
||||
if (data.assigned_numeric_id.has_value()) {
|
||||
// Jump our current_index to this point
|
||||
current_index = data.assigned_numeric_id.value();
|
||||
|
||||
// If this ID is consumed, scream an error.
|
||||
if (consumed_ids.at(current_index))
|
||||
throw std::runtime_error("ID is in use!!");
|
||||
|
||||
}
|
||||
|
||||
// If no ID is hardcoded, assign one from an increasing index.
|
||||
data.numeric_id = current_index;
|
||||
|
||||
registered_tiles[current_index] = data;
|
||||
|
||||
// We also cache LUTs for fast access of name and integer ID from each other
|
||||
id_to_name_mapping[current_index] = data.mnemonic_id;
|
||||
name_to_id_mapping[data.mnemonic_id] = current_index;
|
||||
consumed_ids[current_index] = true;
|
||||
|
||||
current_index++;
|
||||
|
||||
}
|
||||
|
||||
const Tile& Get(const std::string& mnemonic);
|
||||
const Tile& Get(uint16_t ID);
|
||||
|
||||
// TODO: Why convert to vector?
|
||||
std::vector<Tile> GetTileList() {
|
||||
return {std::begin(registered_tiles), std::end(registered_tiles)};
|
||||
}
|
||||
|
||||
const std::array<Tile, MaxTiles>& GetTileArray() { return registered_tiles; }
|
||||
bool Exists(const std::string& mnemonic);
|
||||
bool Exists(uint16_t ID);
|
||||
const Tile& GetByMnemonicID(const std::string& mnemonic)
|
||||
{
|
||||
return registered_tiles[MnemonicToNumeric(mnemonic)];
|
||||
}
|
||||
const Tile& GetByNumericID(uint16_t ID)
|
||||
{
|
||||
return registered_tiles[ID];
|
||||
}
|
||||
|
||||
uint16_t MnemonicToNumeric(const std::string& mnemonic);
|
||||
std::string NumericToMnemonic(uint16_t ID)
|
||||
{
|
||||
return id_to_name_mapping[ID];
|
||||
}
|
||||
const Tile& operator[](const std::string& mnemonic)
|
||||
{
|
||||
return GetByMnemonicID(mnemonic);
|
||||
}
|
||||
const Tile& operator[](uint16_t ID)
|
||||
{
|
||||
return GetByNumericID(ID);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
TileRegistry() {}
|
||||
|
||||
std::array<bool, MaxTiles> consumed_ids;
|
||||
std::array<Tile, MaxTiles> registered_tiles{};
|
||||
std::unordered_map<std::string, uint16_t> name_to_id_mapping;
|
||||
std::unordered_map<uint16_t, std::string> id_to_name_mapping;
|
||||
uint16_t current_index;
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
using Tiles = TileRegistry;
|
||||
|
||||
void use_test()
|
||||
{
|
||||
|
||||
//u16 id = TileRegistry::GetInstance()->GetByMnemonicID("stone");
|
||||
}
|
||||
}
|
@@ -39,7 +39,7 @@ namespace CaveGame::Core
|
||||
float rand = GetPrecomputedWhiteNoise2D(wx, wy)*(TopSoilDepth/2.f);
|
||||
|
||||
if (wy > 1000)
|
||||
return TileID::STONE;
|
||||
return TileRegistry::Get()["stone"].numeric_id;
|
||||
|
||||
if (depth < 0) { return TileID::AIR; }
|
||||
else if (depth < 2.5f) { return TileID::GRASS; }
|
||||
|
@@ -1,13 +1,19 @@
|
||||
#include <Core/Interfaces.hpp>
|
||||
#include <Core/TileRegistry.hpp>
|
||||
|
||||
namespace CaveGame::Core
|
||||
{
|
||||
bool ITileMap::IsNonSolidTile(int x, int y) const
|
||||
{
|
||||
TileID tile = GetTile(x, y);
|
||||
if (tile == TileID::AIR || tile == TileID::VINE || tile == TileID::WATER)
|
||||
|
||||
//if (tile == TileID::AIR || tile == TileID::VINE || tile == TileID::WATER)
|
||||
//return true;
|
||||
|
||||
if (tile == 0 || !Tiles::GetInstance()->GetByNumericID(tile).solid)
|
||||
return true;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -3,44 +3,7 @@
|
||||
#include <array>
|
||||
#include "Core/Item.hpp"
|
||||
|
||||
namespace CaveGame::Core
|
||||
{
|
||||
// TODO: Use unique_ptr?
|
||||
// TODO: Create singleton TileRegistry class
|
||||
std::array<Tile*, 65536> registered_tiles{};
|
||||
|
||||
std::vector<Tile*> GetAllTiles() {
|
||||
return {std::begin(registered_tiles), std::end(registered_tiles)};
|
||||
}
|
||||
|
||||
Tile *GetByNumeric(TileID id) {
|
||||
// TODO: Optimize with additional mapping!!
|
||||
//if (registered_tiles.at((uint16_t)id))
|
||||
return registered_tiles[(uint16_t)id];
|
||||
//for(auto& tile : registered_tiles)
|
||||
//if (tile->numeric_id == id)
|
||||
//return tile;
|
||||
//throw std::runtime_error("ID not in tile registry!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RegisterTile(Tile *data) {
|
||||
|
||||
if (data == nullptr)
|
||||
return;
|
||||
|
||||
uint16_t index = (uint16_t)data->NumericID();
|
||||
registered_tiles[index] = data;
|
||||
|
||||
|
||||
//std::string name = std::format("{}_tile", data->MnemonicID());
|
||||
|
||||
//Core::Item item_for_this_tile = Core::Item(name);
|
||||
//item_for_this_tile->mnemonic = name;
|
||||
//item_for_this_tile->display_name = std::format("{} Tile", data->MnemonicID());
|
||||
|
||||
//RegisterItem(name, item_for_this_tile);
|
||||
}
|
||||
namespace CaveGame::Core {
|
||||
|
||||
void Tile::DecayTo(ITileMap *world, TileState state, int x, int y, TileID TDecaysTo) {
|
||||
world->SetTile(x, y, TDecaysTo);
|
||||
|
8
Core/src/Core/TileRegistry.cpp
Normal file
8
Core/src/Core/TileRegistry.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <Core/TileRegistry.hpp>
|
||||
|
||||
namespace CaveGame::Core
|
||||
{
|
||||
uint16_t TileRegistry::MnemonicToNumeric(const std::string &mnemonic) {
|
||||
return name_to_id_mapping[mnemonic];
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user