diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index a68fb463..f22e1ad2 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -12,6 +12,11 @@ local rotation = mat4.rotate({ math.random(), math.random(), math.random() }, 360) +function on_save() + SAVED_DATA.test = 5 + print("SAVE ENTITY") +end + do -- setup visuals local matrix = mat4.idt() local icon = item.icon(dropitem.id) diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 9d9a8146..8c5c16d3 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -263,6 +263,15 @@ bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x, }); } +dynamic::Value scripting::get_component_value(const scriptenv& env, const std::string& name) { + auto L = lua::get_main_thread(); + lua::pushenv(L, *env); + if (lua::getfield(L, name)) { + return lua::tovalue(L, -1); + } + return dynamic::NONE; +} + void scripting::on_entity_spawn( const EntityDef& def, entityid_t eid, @@ -279,12 +288,17 @@ void scripting::on_entity_spawn( lua::pushvalue(L, -1); } for (auto& component : components) { - auto compenv = create_component_environment( - get_root_environment(), -1, component->name); + auto compenv = create_component_environment(get_root_environment(), -1, + component->name); lua::get_from(L, lua::CHUNKS_TABLE, component->name, true); lua::pushenv(L, *compenv); + lua::pushvalue(L, args); lua::setfield(L, "ARGS"); + + lua::createtable(L, 0, 0); + lua::setfield(L, "SAVED_DATA"); + lua::setfenv(L); lua::call_nothrow(L, 0, 0); @@ -379,7 +393,6 @@ void scripting::on_trigger_enter(const Entity& entity, size_t index, entityid_t } } - void scripting::on_trigger_exit(const Entity& entity, size_t index, entityid_t oid) { const auto& script = entity.getScripting(); for (auto& component : script.components) { diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index cb063acc..328068f2 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -76,6 +76,7 @@ namespace scripting { /// @return true if prevents default action bool on_item_break_block(Player* player, const ItemDef* item, int x, int y, int z); + dynamic::Value get_component_value(const scriptenv& env, const std::string& name); void on_entity_spawn( const EntityDef& def, entityid_t eid, diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 2b18a46b..38d21585 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -112,6 +112,10 @@ void Entities::despawn(entityid_t id) { } } +void Entities::onSave(const Entity& entity) { + scripting::on_entity_save(entity); +} + dynamic::Value Entities::serialize(const Entity& entity) { auto root = dynamic::create_map(); auto& eid = entity.getID(); @@ -140,7 +144,6 @@ dynamic::Value Entities::serialize(const Entity& entity) { if (rig.config->getName() != def.rigName) { root->put("rig", rig.config->getName()); } - if (def.save.rig.pose || def.save.rig.textures) { auto& rigmap = root->putMap("rig"); if (def.save.rig.textures) { @@ -156,6 +159,14 @@ dynamic::Value Entities::serialize(const Entity& entity) { } } } + auto& scripts = entity.getScripting(); + if (!scripts.components.empty()) { + auto& compsMap = root->putMap("comps"); + for (auto& comp : scripts.components) { + auto data = scripting::get_component_value(comp->env, "SAVED_DATA"); + compsMap.put(comp->name, data); + } + } return root; } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 3c0c3c95..51bfe0db 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -183,6 +183,7 @@ public: return std::nullopt; } + void onSave(const Entity& entity); std::vector getAllInside(AABB aabb); void despawn(entityid_t id); dynamic::Value serialize(const Entity& entity); diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 2b02b974..ca35c798 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -713,6 +713,7 @@ void Chunks::save(Chunk* chunk) { auto root = dynamic::create_map(); auto& list = root->putList("data"); for (auto& entity : entities) { + level->entities->onSave(entity); list.put(level->entities->serialize(entity)); } if (!entities.empty()) {