From 4a4b80bef3d262fe710bfafc97d197e5c937e9c5 Mon Sep 17 00:00:00 2001 From: DanielProl1xy Date: Tue, 30 Jan 2024 23:44:07 +0300 Subject: [PATCH] Spawn different objects withing level --- src/interfaces/Serializable.h | 5 ++--- src/logic/LevelController.cpp | 14 ++++++++++++++ src/logic/PlayerController.cpp | 2 +- src/objects/Object.h | 30 ++++++++++++++++++++++++++++++ src/objects/Player.cpp | 2 +- src/objects/Player.h | 5 +++-- src/world/Level.cpp | 27 +++++++++++++++++++++++++-- src/world/Level.h | 7 ++++++- src/world/World.cpp | 11 +++-------- 9 files changed, 85 insertions(+), 18 deletions(-) create mode 100644 src/objects/Object.h diff --git a/src/interfaces/Serializable.h b/src/interfaces/Serializable.h index a1c0d4e2..ee75498b 100644 --- a/src/interfaces/Serializable.h +++ b/src/interfaces/Serializable.h @@ -4,12 +4,11 @@ #include #include "../coders/json.h" -class Serializable -{ +class Serializable { public: virtual ~Serializable() { } virtual std::unique_ptr serialize() const = 0; virtual void deserialize(dynamic::Map* src) = 0; }; -#endif \ No newline at end of file +#endif /* SERIALIZABLE_H */ \ No newline at end of file diff --git a/src/logic/LevelController.cpp b/src/logic/LevelController.cpp index 84b9ad27..138046d6 100644 --- a/src/logic/LevelController.cpp +++ b/src/logic/LevelController.cpp @@ -6,6 +6,7 @@ #include "ChunksController.h" #include "scripting/scripting.h" +#include "../objects/Object.h" LevelController::LevelController(EngineSettings& settings, Level* level) : settings(settings), level(level) { @@ -24,6 +25,19 @@ void LevelController::update(float delta, bool input, bool pause) { level->update(); chunks->update(settings.chunks.loadSpeed); blocks->update(delta); + + // erease null pointers + level->objects.remove_if([](Object* obj) { return obj == nullptr; }); + + // update all objects that needed + for(Object *obj : level->objects) + { + if(obj) { + if(obj->shouldUpdate) { + obj->update(delta); + } + } + } } void LevelController::onWorldSave() { diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 14d6d06c..7a953f15 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -202,7 +202,7 @@ void PlayerController::resetKeyboard() { } void PlayerController::updateControls(float delta){ - player->update(level, input, delta); + player->updateInput(level, input, delta); } void PlayerController::updateInteraction(){ diff --git a/src/objects/Object.h b/src/objects/Object.h new file mode 100644 index 00000000..47be7165 --- /dev/null +++ b/src/objects/Object.h @@ -0,0 +1,30 @@ +#ifndef OBJECT_H +#define OBJECT_H + +#include "stdlib.h" +#include + +class Level; + +class Object { +private: + Level* level; + +public: + int64_t objectUID; + bool shouldUpdate = true; + +public: + virtual ~Object() { destroyed(); } + +public: + virtual void spawned() { } + virtual void update(float delta) { } + virtual void destroyed() { } + +public: + Level* getLevel() { return level; } + void setLevel(Level* lvl) { level = lvl; } +}; + +#endif /* OBJECT_H */ \ No newline at end of file diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index 3a5299fa..2a84f8b8 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -33,7 +33,7 @@ Player::Player(glm::vec3 position, float speed) : Player::~Player() { } -void Player::update( +void Player::updateInput( Level* level, PlayerInput& input, float delta) { diff --git a/src/objects/Player.h b/src/objects/Player.h index 390a2147..27bc3e1c 100644 --- a/src/objects/Player.h +++ b/src/objects/Player.h @@ -8,6 +8,7 @@ #include "../voxels/voxel.h" #include "../settings.h" #include "../interfaces/Serializable.h" +#include "../objects/Object.h" class Camera; class Hitbox; @@ -32,7 +33,7 @@ struct PlayerInput { bool flight; }; -class Player : Serializable { +class Player : Object, Serializable { float speed; int chosenSlot; glm::vec3 spawnpoint {}; @@ -52,7 +53,7 @@ public: ~Player(); void teleport(glm::vec3 position); - void update(Level* level, PlayerInput& input, float delta); + void updateInput(Level* level, PlayerInput& input, float delta); void attemptToFindSpawnpoint(Level* level); diff --git a/src/world/Level.cpp b/src/world/Level.cpp index f49d4ad6..acd550fb 100644 --- a/src/world/Level.cpp +++ b/src/world/Level.cpp @@ -8,17 +8,24 @@ #include "../voxels/ChunksStorage.h" #include "../physics/Hitbox.h" #include "../physics/PhysicsSolver.h" +#include "../objects/Object.h" #include "../objects/Player.h" -Level::Level(World* world, const Content* content, Player* player, EngineSettings& settings) + +const float DEF_PLAYER_Y = 100.0f; +const float DEF_PLAYER_SPEED = 4.0f; + +Level::Level(World* world, const Content* content, EngineSettings& settings) : world(world), content(content), - player(player), chunksStorage(new ChunksStorage(this)), events(new LevelEvents()) , settings(settings) { physics = new PhysicsSolver(glm::vec3(0, -22.6f, 0)); + player = spawnObjectOfClass(glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED); + + uint matrixSize = (settings.chunks.loadDistance+ settings.chunks.padding) * 2; chunks = new Chunks(matrixSize, matrixSize, 0, 0, @@ -53,3 +60,19 @@ void Level::update() { World* Level::getWorld() { return world.get(); } + +// Spawns object of class T and returns pointer to it. +// @param T class that derives the Object class +// @param args pass arguments needed for T class constructor +template +T* Level::spawnObjectOfClass(Args&&... args) +{ + static_assert(std::is_base_of::value, "T must be a derived of Object class"); + T* tObj = new T(args...); + Object* obj = reinterpret_cast(tObj); + objects.push_back(obj); + obj->objectUID = std::rand(); + obj->setLevel(this); + obj->spawned(); + return tObj; +} diff --git a/src/world/Level.h b/src/world/Level.h index 0e2df5cc..7550005c 100644 --- a/src/world/Level.h +++ b/src/world/Level.h @@ -5,10 +5,12 @@ #include "../typedefs.h" #include "../settings.h" +#include class Content; class World; class Player; +class Object; class Chunks; class LevelEvents; class Lighting; @@ -19,6 +21,7 @@ class Level { public: std::unique_ptr world; const Content* const content; + std::list objects; Player* player; Chunks* chunks; ChunksStorage* chunksStorage; @@ -31,13 +34,15 @@ public: Level(World* world, const Content* content, - Player* player, EngineSettings& settings); ~Level(); void update(); World* getWorld(); + + template + T* spawnObjectOfClass(Args&&... args); }; #endif /* WORLD_LEVEL_H_ */ diff --git a/src/world/World.cpp b/src/world/World.cpp index 29997e61..1e0520c0 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -62,9 +62,6 @@ void World::write(Level* level) { wfile->writePlayer(level->player); } -const float DEF_PLAYER_Y = 100.0f; -const float DEF_PLAYER_SPEED = 4.0f; - Level* World::create(std::string name, fs::path directory, uint64_t seed, @@ -72,8 +69,7 @@ Level* World::create(std::string name, const Content* content, const std::vector& packs) { World* world = new World(name, directory, seed, settings, content, packs); - Player* player = new Player(glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED); - return new Level(world, content, player, settings); + return new Level(world, content, settings); } ContentLUT* World::checkIndices(const fs::path& directory, @@ -98,9 +94,8 @@ Level* World::load(fs::path directory, throw world_load_error("could not to find world.json"); } - Player* player = new Player(glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED); - Level* level = new Level(world.get(), content, player, settings); - wfile->readPlayer(player); + Level* level = new Level(world.get(), content, settings); + wfile->readPlayer(level->player); world.release(); return level;