/* * ===================================================================================== * * OpenMiner * * Copyright (C) 2018-2020 Unarelith, Quentin Bazin * Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md) * * This file is part of OpenMiner. * * OpenMiner is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * OpenMiner is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with OpenMiner; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * ===================================================================================== */ #include #include "AnimationComponent.hpp" #include "DrawableDef.hpp" #include "LuaCallbackComponent.hpp" #include "LuaEntityLoader.hpp" #include "LuaMod.hpp" #include "NetworkComponent.hpp" #include "PositionComponent.hpp" #include "Registry.hpp" #include "RotationComponent.hpp" void LuaEntityLoader::loadEntity(const sol::table &table) const { std::string stringID = m_mod.id() + ":" + table["id"].get(); entt::registry ®istry = Registry::getInstance().entityRegistry(); entt::entity entity = Registry::getInstance().registerEntity(stringID); sol::optional onCollision = table["on_collision"]; if (onCollision != sol::nullopt) { auto &luaCallbackComponent = registry.emplace(entity); luaCallbackComponent.collisionCallback = onCollision.value(); } sol::optional properties = table["properties"]; if (properties != sol::nullopt) { sol::optional visual = properties.value()["visual"]; if (visual != sol::nullopt) { std::string type = visual.value()["type"]; if (type == "inventorycube") { auto &drawable = registry.emplace(entity); auto &cube = drawable.addInventoryCube(); cube.size = visual.value()["size"].get_or(1.0f); sol::optional origin = visual.value()["origin"]; if (origin != sol::nullopt) { cube.origin = {origin.value()[1], origin.value()[2], origin.value()[3]}; } } else gkError() << "For entity '" + stringID + "': Visual type '" + type + "' unknown"; } bool isRotatable = properties.value()["is_rotatable"].get_or(false); if (isRotatable) registry.emplace(entity); sol::optional animation = properties.value()["animation"]; if (animation != sol::nullopt) { auto &animationComponent = registry.emplace(entity); for (auto &it : animation.value()) { sol::table anim = it.second.as(); std::string type = anim["type"]; if (type == "rotation") { sol::table axis = anim["axis"]; animationComponent.addRotation(axis[1], axis[2], axis[3], anim["angle"]); } else if (type == "translation") { sol::table delta = anim["delta"]; animationComponent.addTranslation(delta[1], delta[2], delta[3], anim["min"], anim["max"], anim["loop"].get_or(true)); } else gkError() << "For entity '" + stringID + "': Animation type '" + type + "' unknown"; } } sol::optional hitboxTable = properties.value()["hitbox"]; if (hitboxTable != sol::nullopt) { registry.emplace(entity, hitboxTable.value()[1], hitboxTable.value()[2], hitboxTable.value()[3], hitboxTable.value()[4], hitboxTable.value()[5], hitboxTable.value()[6] ); } } } #include "WorldController.hpp" void LuaEntityLoader::spawnEntity(const std::string &entityID, const sol::table &table) const { gk::Vector3f pos; u16 dim; sol::optional position = table["position"]; sol::optional dimension = table["dimension"]; if (position != sol::nullopt && dimension != sol::nullopt) { pos = {position.value()[1], position.value()[2], position.value()[3]}; dim = dimension.value(); } else { gkError() << "In mod '" + m_mod.id() + "': Cannot spawn entity '" + entityID + "' without a position and a dimension"; return; } ItemStack stack; sol::optional itemStack = table["itemstack"]; if (itemStack != sol::nullopt) { stack.setItem(itemStack.value()[1]); stack.setAmount(itemStack.value()[2].get_or(1)); } // Create entity copy here entt::registry ®istry = Registry::getInstance().entityRegistry(); entt::entity entityModel = Registry::getInstance().getEntityFromStringID(entityID); if (entityModel != entt::null) { ServerWorld &world = m_worldController.getWorld(dim); entt::registry &sceneRegistry = world.scene().registry(); entt::entity entity = sceneRegistry.create(); sceneRegistry.emplace(entity, pos.x, pos.y, pos.z, dim); sceneRegistry.emplace(entity, entity); if (registry.has(entityModel)) sceneRegistry.emplace(entity); auto *luaCallbackComponent = registry.try_get(entityModel); if (luaCallbackComponent) sceneRegistry.emplace(entity, *luaCallbackComponent); auto *drawable = registry.try_get(entityModel); if (drawable) { auto &drawableDef = sceneRegistry.emplace(entity, *drawable); if (stack.amount()) { auto &cube = drawableDef.getInventoryCubeDef(); cube.blockID = stack.item().stringID(); } } auto *animation = registry.try_get(entityModel); if (animation) sceneRegistry.emplace(entity, *animation); auto *hitbox = registry.try_get(entityModel); if (hitbox) sceneRegistry.emplace(entity, *hitbox); if (stack.amount()) sceneRegistry.emplace(entity, stack); } else gkError() << "In mod '" + m_mod.id() + "': Cannot find entity with id '" + entityID + "'"; }