[LuaMod] Added helpers to despawn an entity and add an item stack to a player's inventory.
This commit is contained in:
parent
f9dcc6c016
commit
17af1861b5
@ -174,11 +174,9 @@ mod:entity {
|
||||
hitbox = {0, 0, 0, 0.25, 0.25, 0.25},
|
||||
},
|
||||
|
||||
on_collision = function(item_stack, entity, entity_net_id, player, registry, server)
|
||||
player:inventory():add_stack(item_stack:item():string_id(), item_stack:amount())
|
||||
server:send_player_inv_update(player:client_id(), player:client());
|
||||
server:send_entity_despawn(entity_net_id, nil)
|
||||
registry:destroy(entity)
|
||||
on_collision = function(entity, player, server)
|
||||
mods["default"]:give_item_stack(player, entity:item_stack());
|
||||
mods["default"]:despawn_entity(entity)
|
||||
end,
|
||||
}
|
||||
|
||||
@ -188,11 +186,10 @@ openminer:add_listener(EventType.OnBlockDigged, function(pos, block, player, wor
|
||||
position = {pos.x + 0.5, pos.y + 0.5, pos.z + 0.5},
|
||||
dimension = world:dimension():id(),
|
||||
|
||||
itemstack = {block:get_item_drop():item():string_id(), block:get_item_drop():amount()}
|
||||
item_stack = {block:get_item_drop():item():string_id(), block:get_item_drop():amount()}
|
||||
})
|
||||
else
|
||||
player:inventory():add_stack(block:get_item_drop():item():string_id(), block:get_item_drop():amount());
|
||||
server:send_player_inv_update(player:client_id(), player:client());
|
||||
mods["default"]:give_item_stack(player, block:get_item_drop())
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -73,7 +73,7 @@ class ServerApplication {
|
||||
PlayerList m_players;
|
||||
|
||||
ScriptEngine m_scriptEngine;
|
||||
ServerModLoader m_modLoader{m_scriptEngine, m_registry, m_worldController};
|
||||
ServerModLoader m_modLoader{m_scriptEngine, m_registry, m_worldController, m_players};
|
||||
|
||||
Server m_server;
|
||||
ServerCommandHandler m_serverCommandHandler{m_scriptEngine, m_server, m_worldController, m_players, m_registry};
|
||||
|
@ -25,10 +25,14 @@
|
||||
* =====================================================================================
|
||||
*/
|
||||
#include "Biome.hpp"
|
||||
#include "EntityWrapper.hpp"
|
||||
#include "LuaMod.hpp"
|
||||
#include "PlacementEntry.hpp"
|
||||
#include "Registry.hpp"
|
||||
#include "ServerCommandHandler.hpp"
|
||||
#include "ServerPlayer.hpp"
|
||||
#include "Tree.hpp"
|
||||
#include "WorldController.hpp"
|
||||
|
||||
void LuaMod::commit() {
|
||||
while (!m_defs.empty()) {
|
||||
@ -61,6 +65,9 @@ void LuaMod::initUsertype(sol::state &lua) {
|
||||
"path", &LuaMod::path,
|
||||
|
||||
"spawn_entity", &LuaMod::spawnEntity,
|
||||
"despawn_entity", &LuaMod::despawnEntity,
|
||||
|
||||
"give_item_stack", &LuaMod::giveItemStack,
|
||||
|
||||
"block", DEF_FUNC(DefinitionType::Block),
|
||||
"item", DEF_FUNC(DefinitionType::Item),
|
||||
@ -78,3 +85,24 @@ void LuaMod::spawnEntity(const std::string &entityID, const sol::table &table) {
|
||||
m_entityLoader.spawnEntity(entityID, table);
|
||||
}
|
||||
|
||||
void LuaMod::despawnEntity(EntityWrapper &entity) {
|
||||
PositionComponent *position = entity.getPositionComponent();
|
||||
NetworkComponent *network = entity.getNetworkComponent();
|
||||
if (position && network) {
|
||||
m_worldController.server()->sendEntityDespawn(network->entityID);
|
||||
m_worldController.getWorld(position->dimension).scene().registry().destroy(entity.id());
|
||||
}
|
||||
else
|
||||
// FIXME: Maybe improve this message with the type of entity that caused the error
|
||||
gkError() << "In mod '" + m_id + "': Failed to despawn entity: Missing position and network components";
|
||||
}
|
||||
|
||||
void LuaMod::giveItemStack(ServerPlayer &player, ItemStack *itemStack) {
|
||||
if (itemStack) {
|
||||
player.inventory().addStack(itemStack->item().stringID(), itemStack->amount());
|
||||
m_worldController.server()->sendPlayerInvUpdate(player.clientID(), &player.client());
|
||||
}
|
||||
else
|
||||
gkError() << "In mod '" + m_id + "': Failed to add stack to player";
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,10 @@
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include <gk/core/IntTypes.hpp>
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
#include "LuaBiomeLoader.hpp"
|
||||
#include "LuaBlockLoader.hpp"
|
||||
#include "LuaDimensionLoader.hpp"
|
||||
@ -37,14 +41,18 @@
|
||||
#include "LuaRecipeLoader.hpp"
|
||||
#include "LuaSkyLoader.hpp"
|
||||
|
||||
class EntityWrapper;
|
||||
class ItemStack;
|
||||
class PlayerList;
|
||||
class Registry;
|
||||
class ServerPlayer;
|
||||
class WorldController;
|
||||
|
||||
// This class is meant to be used ONLY in Lua
|
||||
class LuaMod {
|
||||
public:
|
||||
LuaMod(const std::string &id, Registry ®istry, WorldController &worldController)
|
||||
: m_id(id), m_registry(registry), m_worldController(worldController) {}
|
||||
LuaMod(const std::string &id, Registry ®istry, WorldController &worldController, PlayerList &players)
|
||||
: m_id(id), m_registry(registry), m_worldController(worldController), m_players(players) {}
|
||||
|
||||
void commit();
|
||||
|
||||
@ -56,6 +64,9 @@ class LuaMod {
|
||||
|
||||
private:
|
||||
void spawnEntity(const std::string &entityID, const sol::table &table);
|
||||
void despawnEntity(EntityWrapper &entity);
|
||||
|
||||
void giveItemStack(ServerPlayer &player, ItemStack *itemStack);
|
||||
|
||||
enum class DefinitionType {
|
||||
Block,
|
||||
@ -76,6 +87,7 @@ class LuaMod {
|
||||
// TODO: Add registry instance to loaders in order to avoid using singleton
|
||||
Registry &m_registry;
|
||||
WorldController &m_worldController;
|
||||
PlayerList &m_players;
|
||||
|
||||
LuaBlockLoader m_blockLoader{*this};
|
||||
LuaItemLoader m_itemLoader{*this};
|
||||
|
@ -25,6 +25,7 @@
|
||||
* =====================================================================================
|
||||
*/
|
||||
#include "BlockMetadata.hpp"
|
||||
#include "EntityWrapper.hpp"
|
||||
#include "LuaCore.hpp"
|
||||
#include "LuaGUI.hpp"
|
||||
#include "LuaMod.hpp"
|
||||
@ -55,6 +56,14 @@ void ScriptEngine::initUsertypes() {
|
||||
"destroy", static_cast<void (entt::registry::*)(const entt::entity)>(&entt::registry::destroy)
|
||||
);
|
||||
|
||||
m_lua.new_usertype<EntityWrapper>("EntityWrapper",
|
||||
"id", &EntityWrapper::id,
|
||||
|
||||
"position", &EntityWrapper::getPositionComponent,
|
||||
"network", &EntityWrapper::getNetworkComponent,
|
||||
"item_stack", &EntityWrapper::getItemStack
|
||||
);
|
||||
|
||||
m_lua.new_usertype<Registry>("Registry",
|
||||
"get_block", &Registry::getBlock,
|
||||
"get_item", &Registry::getItem,
|
||||
|
@ -80,7 +80,7 @@ LuaMod &ServerModLoader::registerMod(const std::string &name) {
|
||||
m_mods.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(name),
|
||||
std::forward_as_tuple(name, m_registry, m_worldController)
|
||||
std::forward_as_tuple(name, m_registry, m_worldController, m_players)
|
||||
);
|
||||
|
||||
return m_mods.at(name);
|
||||
|
@ -32,14 +32,15 @@
|
||||
|
||||
#include "LuaMod.hpp"
|
||||
|
||||
class PlayerList;
|
||||
class Registry;
|
||||
class ScriptEngine;
|
||||
class WorldController;
|
||||
|
||||
class ServerModLoader {
|
||||
public:
|
||||
ServerModLoader(ScriptEngine &scriptEngine, Registry ®istry, WorldController &worldController)
|
||||
: m_scriptEngine(scriptEngine), m_registry(registry), m_worldController(worldController) {}
|
||||
ServerModLoader(ScriptEngine &scriptEngine, Registry ®istry, WorldController &worldController, PlayerList &players)
|
||||
: m_scriptEngine(scriptEngine), m_registry(registry), m_worldController(worldController), m_players(players) {}
|
||||
|
||||
void loadMods();
|
||||
|
||||
@ -49,6 +50,7 @@ class ServerModLoader {
|
||||
ScriptEngine &m_scriptEngine;
|
||||
Registry &m_registry;
|
||||
WorldController &m_worldController;
|
||||
PlayerList &m_players;
|
||||
|
||||
std::unordered_map<std::string, LuaMod> m_mods;
|
||||
};
|
||||
|
@ -119,7 +119,7 @@ void LuaEntityLoader::spawnEntity(const std::string &entityID, const sol::table
|
||||
}
|
||||
|
||||
ItemStack stack;
|
||||
sol::optional<sol::table> itemStack = table["itemstack"];
|
||||
sol::optional<sol::table> itemStack = table["item_stack"];
|
||||
if (itemStack != sol::nullopt) {
|
||||
stack.setItem(itemStack.value()[1]);
|
||||
stack.setAmount(itemStack.value()[2].get_or(1));
|
||||
|
53
source/server/scene/EntityWrapper.hpp
Normal file
53
source/server/scene/EntityWrapper.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* OpenMiner
|
||||
*
|
||||
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
|
||||
* 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
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
#ifndef ENTITYWRAPPER_HPP_
|
||||
#define ENTITYWRAPPER_HPP_
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
#include "ItemStack.hpp"
|
||||
#include "NetworkComponent.hpp"
|
||||
#include "PositionComponent.hpp"
|
||||
|
||||
// This class is meant to be used ONLY in Lua or Lua-related C++ classes
|
||||
class EntityWrapper {
|
||||
public:
|
||||
EntityWrapper(entt::entity id, entt::registry ®istry)
|
||||
: m_id(id), m_registry(registry) {}
|
||||
|
||||
entt::entity id() const { return m_id; }
|
||||
|
||||
PositionComponent *getPositionComponent() const { return m_registry.try_get<PositionComponent>(m_id); }
|
||||
NetworkComponent *getNetworkComponent() const { return m_registry.try_get<NetworkComponent>(m_id); }
|
||||
ItemStack *getItemStack() const { return m_registry.try_get<ItemStack>(m_id); }
|
||||
|
||||
private:
|
||||
entt::entity m_id;
|
||||
entt::registry &m_registry;
|
||||
};
|
||||
|
||||
#endif // ENTITYWRAPPER_HPP_
|
@ -27,6 +27,7 @@
|
||||
#include <gk/core/Debug.hpp>
|
||||
|
||||
#include "CollisionController.hpp"
|
||||
#include "EntityWrapper.hpp"
|
||||
#include "ItemStack.hpp"
|
||||
#include "LuaCallbackComponent.hpp"
|
||||
#include "NetworkComponent.hpp"
|
||||
@ -35,13 +36,14 @@
|
||||
#include "ServerCommandHandler.hpp"
|
||||
|
||||
void CollisionController::update(entt::registry ®istry) {
|
||||
registry.view<PositionComponent, gk::DoubleBox, ItemStack, NetworkComponent, LuaCallbackComponent>().each([&](auto entity, auto &position, auto &box, auto &itemStack, auto &network, auto &luaCallbackComponent) {
|
||||
registry.view<PositionComponent, gk::DoubleBox, LuaCallbackComponent>().each([&](auto id, auto &position, auto &box, auto &luaCallbackComponent) {
|
||||
for (auto &it : m_players) {
|
||||
if (it.second.dimension() == position.dimension) {
|
||||
gk::DoubleBox hitbox = box + gk::Vector3d{position.x, position.y, position.z};
|
||||
gk::DoubleBox playerHitbox = it.second.hitbox() + gk::Vector3d{it.second.x(), it.second.y(), it.second.z()};
|
||||
if (hitbox.intersects(playerHitbox)) {
|
||||
luaCallbackComponent.collisionCallback(itemStack, entity, network.entityID, it.second, registry, *m_server);
|
||||
EntityWrapper entity{id, registry};
|
||||
luaCallbackComponent.collisionCallback(entity, it.second, *m_server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ class WorldController {
|
||||
|
||||
ServerWorld &getWorld(u16 dimension) { return m_worldList.at(dimension); }
|
||||
|
||||
const ServerCommandHandler *server() const { return m_server; }
|
||||
void setServer(ServerCommandHandler &server) { m_server = &server; }
|
||||
|
||||
private:
|
||||
|
Loading…
x
Reference in New Issue
Block a user