From eb2be5e8b6a0c590c5ea59eec1a1905e4191f5f9 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 28 Jun 2024 12:16:31 +0300 Subject: [PATCH] add entity events: on_spawn, on_despawn --- res/content/base/scripts/drop.lua | 7 +++++++ src/content/ContentLoader.cpp | 5 +++++ src/logic/scripting/scripting.cpp | 26 ++++++++++++++++++++++++++ src/logic/scripting/scripting.hpp | 25 +++++++++++++++++++++++-- src/objects/Entities.cpp | 21 +++++++++++++++++++-- src/objects/Entities.hpp | 24 ++++++++++++++++++------ src/objects/EntityDef.hpp | 7 +++++++ src/objects/Player.cpp | 6 +++--- src/objects/Player.hpp | 2 +- src/physics/Hitbox.cpp | 2 +- src/physics/Hitbox.hpp | 5 ++--- src/physics/PhysicsSolver.cpp | 6 +++--- src/physics/PhysicsSolver.hpp | 2 +- 13 files changed, 116 insertions(+), 22 deletions(-) create mode 100644 res/content/base/scripts/drop.lua diff --git a/res/content/base/scripts/drop.lua b/res/content/base/scripts/drop.lua new file mode 100644 index 00000000..9a691298 --- /dev/null +++ b/res/content/base/scripts/drop.lua @@ -0,0 +1,7 @@ +function on_spawn(eid) + print("spawn", eid) +end + +function on_despawn(eid) + print("despawn", eid) +end diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index f966c633..ad4f7072 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -321,6 +321,11 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& full, const st auto folder = pack->folder; auto configFile = folder/fs::path("entities/"+name+".json"); if (fs::exists(configFile)) loadEntity(def, full, configFile); + + auto scriptfile = folder/fs::path("scripts/"+def.scriptName+".lua"); + if (fs::is_regular_file(scriptfile)) { + scripting::load_entity_script(env, full, scriptfile, def.rt.funcsset); + } } void ContentLoader::loadBlock(Block& def, const std::string& full, const std::string& name) { diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 7572faa2..8d017d5b 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -13,6 +13,8 @@ #include "../../logic/BlocksController.hpp" #include "../../logic/LevelController.hpp" #include "../../objects/Player.hpp" +#include "../../objects/EntityDef.hpp" +#include "../../objects/Entities.hpp" #include "../../util/stringutil.hpp" #include "../../util/timeutil.hpp" #include "../../util/timeutil.hpp" @@ -225,6 +227,22 @@ bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x, }); } +bool scripting::on_entity_spawn(const EntityDef& def, entityid_t eid) { + std::string name = def.name + ".spawn"; + return lua::emit_event(lua::get_main_thread(), name, [eid] (auto L) { + lua::pushinteger(L, eid); + return 1; + }); +} + +bool scripting::on_entity_despawn(const EntityDef& def, entityid_t eid) { + std::string name = def.name + ".despawn"; + return lua::emit_event(lua::get_main_thread(), name, [eid] (auto L) { + lua::pushinteger(L, eid); + return 1; + }); +} + void scripting::on_ui_open( UiDocument* layout, std::vector args @@ -308,6 +326,14 @@ void scripting::load_item_script(const scriptenv& senv, const std::string& prefi funcsset.on_block_break_by = register_event(env, "on_block_break_by", prefix+".blockbreakby"); } +void scripting::load_entity_script(const scriptenv& senv, const std::string& prefix, const fs::path& file, entity_funcs_set& funcsset) { + int env = *senv; + load_script(env, "entity", file); + funcsset.init = register_event(env, "init", prefix+".init"); + funcsset.on_spawn = register_event(env, "on_spawn", prefix+".spawn"); + funcsset.on_despawn = register_event(env, "on_despawn", prefix+".despawn"); +} + void scripting::load_world_script(const scriptenv& senv, const std::string& prefix, const fs::path& file) { int env = *senv; load_script(env, "world", file); diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 3082420c..6ad140c8 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -27,9 +27,12 @@ class Inventory; class UiDocument; struct block_funcs_set; struct item_funcs_set; +struct entity_funcs_set; struct uidocscript; class BlocksController; class LevelController; +class Entity; +struct EntityDef; namespace scripting { extern Engine* engine; @@ -73,6 +76,10 @@ namespace scripting { /// @return true if prevents default action bool on_item_break_block(Player* player, const ItemDef* item, int x, int y, int z); + bool on_entity_spawn(const EntityDef& def, entityid_t eid); + + bool on_entity_despawn(const EntityDef& def, entityid_t eid); + /// @brief Called on UI view show void on_ui_open( UiDocument* layout, @@ -89,14 +96,28 @@ namespace scripting { /// @param prefix pack id /// @param file item script file /// @param funcsset block callbacks set - void load_block_script(const scriptenv& env, const std::string& prefix, const fs::path& file, block_funcs_set& funcsset); + void load_block_script( + const scriptenv& env, + const std::string& prefix, + const fs::path& file, + block_funcs_set& funcsset); /// @brief Load script associated with an Item /// @param env environment /// @param prefix pack id /// @param file item script file /// @param funcsset item callbacks set - void load_item_script(const scriptenv& env, const std::string& prefix, const fs::path& file, item_funcs_set& funcsset); + void load_item_script( + const scriptenv& env, + const std::string& prefix, + const fs::path& file, + item_funcs_set& funcsset); + + void load_entity_script( + const scriptenv& env, + const std::string& prefix, + const fs::path& file, + entity_funcs_set& funcsset); /// @brief Load package-specific world script /// @param env environment diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 291ac1fd..a6915b67 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -9,6 +9,7 @@ #include "../graphics/core/Model.hpp" #include "../maths/FrustumCulling.hpp" #include "../objects/EntityDef.hpp" +#include "../logic/scripting/scripting.hpp" #include @@ -19,6 +20,12 @@ void Transform::refresh() { combined = combined * glm::mat4(rot); } +void Entity::destroy() { + if (isValid()){ + entities.despawn(id); + } +} + Entities::Entities(Level* level) : level(level) { } @@ -26,13 +33,23 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { auto entity = registry.create(); glm::vec3 size(1); auto id = nextID++; - registry.emplace(entity, static_cast(id)); + registry.emplace(entity, static_cast(id), def); registry.emplace(entity, pos, size/4.0f, glm::mat3(1.0f)); registry.emplace(entity, true, Hitbox {pos, def.hitbox}); entities[id] = entity; + if (def.rt.funcsset.on_spawn) { + scripting::on_entity_spawn(def, id); + } return id; } +void Entities::despawn(entityid_t id) { + if (auto entity = get(id)) { + scripting::on_entity_despawn(entity->getDef(), id); + registry.destroy(get(id)->getHandler()); + } +} + void Entities::clean() { for (auto it = entities.begin(); it != entities.end();) { if (registry.valid(it->second)) { @@ -60,7 +77,7 @@ void Entities::updatePhysics(float delta){ 1.0f, true ); - hitbox.linear_damping = hitbox.grounded * 12; + hitbox.linearDamping = hitbox.grounded * 12; transform.pos = hitbox.position; //transform.rot = glm::rotate(glm::mat4(transform.rot), delta, glm::vec3(0, 1, 0)); if (hitbox.grounded) { diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index c4845e00..ed4427cb 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -9,8 +9,11 @@ #include #include +struct EntityDef; + struct EntityId { entityid_t uid; + const EntityDef& def; }; struct Transform { @@ -33,15 +36,16 @@ class LineBatch; class ModelBatch; class Frustum; class Rig; -struct EntityDef; +class Entities; class Entity { + Entities& entities; entityid_t id; entt::registry& registry; const entt::entity entity; public: - Entity(entityid_t id, entt::registry& registry, const entt::entity entity) - : id(id), registry(registry), entity(entity) {} + Entity(Entities& entities, entityid_t id, entt::registry& registry, const entt::entity entity) + : entities(entities), id(id), registry(registry), entity(entity) {} entityid_t getID() const { return id; @@ -51,6 +55,10 @@ public: return registry.valid(entity); } + const EntityDef& getDef() const { + return registry.get(entity).def; + } + Transform& getTransform() const { return registry.get(entity); } @@ -63,9 +71,11 @@ public: return registry.get(entity).uid; } - void destroy() { - registry.destroy(entity); + entt::entity getHandler() const { + return entity; } + + void destroy(); }; class Entities { @@ -86,11 +96,13 @@ public: std::optional get(entityid_t id) { const auto& found = entities.find(id); if (found != entities.end() && registry.valid(found->second)) { - return Entity(id, registry, found->second); + return Entity(*this, id, registry, found->second); } return std::nullopt; } + void despawn(entityid_t id); + inline size_t size() const { return entities.size(); } diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index e001bdbe..b5dbdc80 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -6,6 +6,12 @@ #include "../typedefs.hpp" +struct entity_funcs_set { + bool init : 1; + bool on_spawn : 1; + bool on_despawn : 1; +}; + struct EntityDef { /// @brief Entity string id (with prefix included) std::string const name; @@ -15,6 +21,7 @@ struct EntityDef { struct { entityid_t id; + entity_funcs_set funcsset; } rt; EntityDef(const std::string& name) : name(name) {} diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index fe81a5c7..7d295819 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -110,9 +110,9 @@ void Player::updateInput( noclip = !noclip; } - hitbox->linear_damping = PLAYER_GROUND_DAMPING; + hitbox->linearDamping = PLAYER_GROUND_DAMPING; if (flight){ - hitbox->linear_damping = PLAYER_AIR_DAMPING; + hitbox->linearDamping = PLAYER_AIR_DAMPING; hitbox->velocity.y *= 1.0f - delta * 9; if (input.jump){ hitbox->velocity.y += speed * delta * 9; @@ -122,7 +122,7 @@ void Player::updateInput( } } if (!hitbox->grounded) { - hitbox->linear_damping = PLAYER_AIR_DAMPING; + hitbox->linearDamping = PLAYER_AIR_DAMPING; } input.noclip = false; diff --git a/src/objects/Player.hpp b/src/objects/Player.hpp index fdae39b5..4d8a10af 100644 --- a/src/objects/Player.hpp +++ b/src/objects/Player.hpp @@ -11,10 +11,10 @@ #include class Camera; -class Hitbox; class Inventory; class ContentLUT; class Level; +struct Hitbox; struct EngineSettings; struct PlayerInput { diff --git a/src/physics/Hitbox.cpp b/src/physics/Hitbox.cpp index df94d9f6..8cd127e4 100644 --- a/src/physics/Hitbox.cpp +++ b/src/physics/Hitbox.cpp @@ -4,5 +4,5 @@ Hitbox::Hitbox(glm::vec3 position, glm::vec3 halfsize) : position(position), halfsize(halfsize), velocity(0.0f,0.0f,0.0f), - linear_damping(0.1f) + linearDamping(0.1f) {} diff --git a/src/physics/Hitbox.hpp b/src/physics/Hitbox.hpp index a32b0ada..718a8a0d 100644 --- a/src/physics/Hitbox.hpp +++ b/src/physics/Hitbox.hpp @@ -3,12 +3,11 @@ #include -class Hitbox { -public: +struct Hitbox { glm::vec3 position; glm::vec3 halfsize; glm::vec3 velocity; - float linear_damping; + float linearDamping; bool grounded = false; Hitbox(glm::vec3 position, glm::vec3 halfsize); diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index 28c82312..5e03a04f 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -22,7 +22,7 @@ void PhysicsSolver::step( bool collisions ) { float dt = delta / static_cast(substeps); - float linear_damping = hitbox->linear_damping; + float linearDamping = hitbox->linearDamping; float s = 2.0f/BLOCK_AABB_GRID; const glm::vec3& half = hitbox->halfsize; @@ -41,8 +41,8 @@ void PhysicsSolver::step( colisionCalc(chunks, hitbox, vel, pos, half, (prevGrounded && gravityScale > 0.0f) ? 0.5f : 0.0f); } - vel.x *= glm::max(0.0f, 1.0f - dt * linear_damping); - vel.z *= glm::max(0.0f, 1.0f - dt * linear_damping); + vel.x *= glm::max(0.0f, 1.0f - dt * linearDamping); + vel.z *= glm::max(0.0f, 1.0f - dt * linearDamping); pos += vel * dt + gravity * gravityScale * dt * dt * 0.5f; if (hitbox->grounded && pos.y < py) { diff --git a/src/physics/PhysicsSolver.hpp b/src/physics/PhysicsSolver.hpp index 6e940f99..a9807af4 100644 --- a/src/physics/PhysicsSolver.hpp +++ b/src/physics/PhysicsSolver.hpp @@ -7,8 +7,8 @@ #include class Block; -class Hitbox; class Chunks; +struct Hitbox; class PhysicsSolver { glm::vec3 gravity;