Added 'Farmland' block, which is possible to create with any hoe.

This commit is contained in:
Quentin Bazin 2020-07-05 20:55:23 +02:00
parent 3a325c74ff
commit 7497b6b2a8
31 changed files with 307 additions and 67 deletions

View File

@ -38,6 +38,7 @@ Possible events:
- `BlockPlaced`: `funcion(pos, block, player, world, client, server)`
- `BlockDigged`: `funcion(pos, block, player, world, client, server)`
- `BlockActivated`: `function(pos, block, player, world, client, server)`
- `ItemActivated`: `function(pos, block, player, world, client, server)`
- `PlayerConnected`: `function(pos, player, client, server)`
### `openminer:get_config(name)`

View File

@ -138,4 +138,6 @@
- `void set_data(int x, int y, int z, u16 data)`
- `BlockData *add_block_data(int x, int y, int z, int inventoryWidth, int inventoryHeight)`
- `BlockData *get_block_data(int x, int y, int z)`
- `const Block &get_block_def(int x, int y, int z)`
- `void set_block_from_str(int x, int y, int z, string block_id)`

View File

@ -81,3 +81,19 @@ The textures will be loaded from `mods/<your-mod>/textures/items`
**Note:** Currently, you can only use textures of the exact same size (16x16, 32x32) than the other block/item textures in the game.
## Functions
### `on_item_activated`
Parameters:
- `pos` (`ivec3`): position of the targeted block
- `block` (`Block`): definition of the targeted block
- `player` (`Player`): player that activated the item
- `world` (`World`): instance of the `ServerWorld`
- `client` (`Client`): client that activated the item
- `server` (`Server`): current server
- `screen_width` (`u16`): width of the screen
- `screen_height` (`u16`): height of the screen
- `gui_scale` (`u8`): current scaling setting

View File

@ -271,6 +271,17 @@ _This packet has no field._
| Block Z | s32 | Block Z coordinate |
| Inventory | Inventory | Block inventory |
#### ItemActivated
| Field name | Field type | Notes |
| ------------- | ----------- | ---------------------------------------------------- |
| Block X | s32 | Selected block X coordinate |
| Block Y | s32 | Selected block Y coordinate |
| Block Z | s32 | Selected block Z coordinate |
| Screen width | u16 | Client screen width |
| Screen height | u16 | Client screen height |
| GUI scale | u8 | Client GUI scale |
#### ChatMessage (serverbound)
| Field name | Field type | Notes |

View File

@ -333,6 +333,16 @@ mod:block {
end
}
mod:block {
id = "farmland",
name = "Farmland",
tiles = {"farmland_dry.png", "dirt.png", "dirt.png"},
alt_tiles = {"farmland_wet.png", "dirt.png", "dirt.png"},
draw_type = "boundingbox",
bounding_box = {0, 0, 0, 1, 1, 15 / 16},
}
dofile("blocks/workbench.lua")
dofile("blocks/furnace.lua")
dofile("blocks/door.lua")

View File

@ -42,7 +42,13 @@ mod:item {
mod:item {
id = "stone_hoe",
name = "Stone Hoe",
tiles = "stone_hoe.png"
tiles = "stone_hoe.png",
on_item_activated = function(pos, block, player, world, client, server, screen_width, screen_height, gui_scale)
if block:string_id() == "default:grass" then
world:set_block_from_str(pos.x, pos.y, pos.z, "default:farmland")
end
end
}
mod:item {
@ -105,6 +111,12 @@ mod:item {
id = "wooden_hoe",
name = "Wooden Hoe",
tiles = "wooden_hoe.png",
on_item_activated = function(pos, block, player, world, client, server, screen_width, screen_height, gui_scale)
if block:string_id() == "default:grass" then
world:set_block_from_str(pos.x, pos.y, pos.z, "default:farmland")
end
end
}
mod:item {
@ -178,7 +190,13 @@ mod:item {
mod:item {
id = "iron_hoe",
name = "Iron Hoe",
tiles = "iron_hoe.png"
tiles = "iron_hoe.png",
on_item_activated = function(pos, block, player, world, client, server, screen_width, screen_height, gui_scale)
if block:string_id() == "default:grass" then
world:set_block_from_str(pos.x, pos.y, pos.z, "default:farmland")
end
end
}
mod:item {
@ -214,7 +232,13 @@ mod:item {
mod:item {
id = "diamond_hoe",
name = "Diamond Hoe",
tiles = "diamond_hoe.png"
tiles = "diamond_hoe.png",
on_item_activated = function(pos, block, player, world, client, server, screen_width, screen_height, gui_scale)
if block:string_id() == "default:grass" then
world:set_block_from_str(pos.x, pos.y, pos.z, "default:farmland")
end
end
}
mod:item {
@ -250,7 +274,13 @@ mod:item {
mod:item {
id = "golden_hoe",
name = "Golden Hoe",
tiles = "golden_hoe.png"
tiles = "golden_hoe.png",
on_item_activated = function(pos, block, player, world, client, server, screen_width, screen_height, gui_scale)
if block:string_id() == "default:grass" then
world:set_block_from_str(pos.x, pos.y, pos.z, "default:farmland")
end
end
}
mod:item {

View File

@ -43,19 +43,19 @@ openminer:add_listener(Event.PlayerConnected, function(pos, player, client, serv
local starting_items = {
{"default:workbench", 1},
{"default:dirt", 64},
{"default:grass", 64},
{"default:stone", 64},
{"default:glass", 64},
{"default:glowstone", 64},
{"default:furnace", 1},
{"default:stone_pickaxe", 1},
{"default:stone_axe", 1},
{"default:stone_hoe", 1},
{"default:oak_wood", 64},
{"default:oak_planks", 64},
{"default:grass", 64},
{"default:cobblestone", 64},
{"default:stick", 64},
{"default:stone_hoe", 1},
{"default:stone_shovel", 1},
{"default:iron_ore", 64},
{"default:coal", 64},

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

View File

@ -120,14 +120,14 @@ void TextureAtlas::loadFromRegistry(const std::string &texturePack) {
}
for (auto &item : Registry::getInstance().items()) {
if (!item.isBlock() || !item.tiles().textureFilenames().empty()) {
if (!item->isBlock() || !item->tiles().textureFilenames().empty()) {
std::string path;
if (texturePack.empty())
path = "mods/" + item.modName() + "/textures/items/";
path = "mods/" + item->modName() + "/textures/items/";
else
path = "texturepacks/" + texturePack + "/items/";
const TilesDef &tiles = item.tiles();
const TilesDef &tiles = item->tiles();
for (auto &textureFilename : tiles.textureFilenames())
addFile(path, textureFilename);
for (auto &textureFilename : tiles.altTextureFilenames())

View File

@ -61,13 +61,25 @@ void BlockCursor::onEvent(const sf::Event &event, const Hotbar &hotbar) {
const Block &block = Registry::getInstance().getBlock(blockId);
const Item &item = hotbar.currentItem();
bool itemActivationSent = false;
bool sneakedItemActivation = false;
if (item.id() && item.canBeActivated()) {
if (!gk::GamePad::isKeyPressed(GameKey::Sneak)) {
m_client.sendItemActivated(m_selectedBlock);
itemActivationSent = true;
}
else
sneakedItemActivation = true;
}
bool blockActivationSent = false;
if (block.id() && block.canBeActivated() && !gk::GamePad::isKeyPressed(GameKey::Sneak)) {
if (!itemActivationSent && block.id() && block.canBeActivated()
&& (!gk::GamePad::isKeyPressed(GameKey::Sneak) || sneakedItemActivation)) {
m_client.sendBlockActivated(m_selectedBlock);
blockActivationSent = true;
}
if (block.id() && !blockActivationSent && hotbar.currentItem().id() && item.isBlock()) {
if (block.id() && !itemActivationSent && !blockActivationSent && hotbar.currentItem().id() && item.isBlock()) {
s8 face = m_selectedBlock.w;
s32 x = m_selectedBlock.x;

View File

@ -107,6 +107,16 @@ void ClientCommandHandler::sendBlockInvUpdate(Inventory &inventory) {
m_client.send(packet);
}
void ClientCommandHandler::sendItemActivated(const glm::ivec4 &selectedBlock) {
Network::Packet packet;
packet << Network::Command::ItemActivated
<< s32(selectedBlock.x)
<< s32(selectedBlock.y)
<< s32(selectedBlock.z)
<< u16(Config::screenWidth) << u16(Config::screenHeight) << u8(Config::guiScale);
m_client.send(packet);
}
void ClientCommandHandler::sendChunkRequest(s32 chunkX, s32 chunkY, s32 chunkZ) {
Network::Packet packet;
packet << Network::Command::ChunkRequest;

View File

@ -54,6 +54,7 @@ class ClientCommandHandler {
void sendPlayerHeldItemChanged(u8 hotbarSlot, u16 itemID);
void sendBlockActivated(const glm::ivec4 &selectedBlock);
void sendBlockInvUpdate(Inventory &inventory);
void sendItemActivated(const glm::ivec4 &selectedBlock);
void sendChunkRequest(s32 chunkX, s32 chunkY, s32 chunkZ);
void sendChatMessage(const std::string &message);
void sendKeyPressed(u16 keyID);

View File

@ -33,23 +33,6 @@
Registry *Registry::s_instance = nullptr;
Item &Registry::registerItem(const TilesDef &tiles, const std::string &stringID, const std::string &label) {
u32 id = m_items.size();
m_itemsID.emplace(stringID, id);
m_items.emplace_back(id, tiles, stringID, label);
return m_items.back();
}
Item &Registry::registerSerializedItem(sf::Packet &packet) {
m_items.emplace_back();
m_items.back().deserialize(packet);
u32 id = m_items.size() - 1;
m_itemsID.emplace(m_items.back().stringID(), id);
return m_items.back();
}
Sky &Registry::registerSky(const std::string &stringID) {
size_t id = m_skies.size();
m_skiesID.emplace(stringID, id);
@ -233,14 +216,14 @@ EntityCallbackContainer &Registry::getEntityCallbackContainer(const std::string
}
void Registry::serialize(sf::Packet &packet) const {
for (auto &it : m_items) {
packet << u8(DataType::Item) << it;
}
for (auto &it : m_blocks) {
packet << u8(DataType::Block) << *it;
}
for (auto &it : m_items) {
packet << u8(DataType::Item) << *it;
}
for (auto &it : m_recipes) {
packet << u8((it->type() == "craft") ? DataType::CraftingRecipe : DataType::SmeltingRecipe)
<< *it;
@ -275,7 +258,7 @@ void Registry::deserialize(sf::Packet &packet) {
registerSerializedBlock<Block>(packet);
}
else if (type == u8(DataType::Item)) {
registerSerializedItem(packet);
registerSerializedItem<Item>(packet);
}
else if (type == u8(DataType::CraftingRecipe)) {
registerRecipe<CraftingRecipe>()->deserialize(packet);

View File

@ -65,8 +65,24 @@ class Registry : public gk::ISerializable {
return *static_cast<T*>(m_blocks.back().get());
}
Item &registerItem(const TilesDef &tiles, const std::string &stringID, const std::string &name);
Item &registerSerializedItem(sf::Packet &packet);
template<typename T>
auto registerItem(const TilesDef &tiles, const std::string &stringID, const std::string &label) -> typename std::enable_if<std::is_base_of<Item, T>::value, T&>::type {
u32 id = m_items.size();
m_itemsID.emplace(stringID, id);
m_items.emplace_back(std::make_unique<T>(id, tiles, stringID, label));
return *static_cast<T*>(m_items.back().get());
}
template<typename T>
auto registerSerializedItem(sf::Packet &packet) -> typename std::enable_if<std::is_base_of<Item, T>::value, T&>::type {
m_items.emplace_back(std::make_unique<T>());
m_items.back()->deserialize(packet);
u32 id = m_items.size() - 1;
m_itemsID.emplace(m_items.back()->stringID(), id);
return *static_cast<T*>(m_items.back().get());
}
template<typename T, typename... Args>
auto registerRecipe(Args &&...args) -> typename std::enable_if<std::is_base_of<Recipe, T>::value, Recipe*>::type {
@ -93,7 +109,7 @@ class Registry : public gk::ISerializable {
entt::entity registerEntity(const std::string &stringID);
const Block &getBlock(u16 id) const { return *m_blocks.at(id).get(); }
const Item &getItem(u16 id) const { return m_items.at(id); }
const Item &getItem(u16 id) const { return *m_items.at(id).get(); }
const Sky &getSky(u16 id) const { return m_skies.at(id); }
const Tree &getTree(u16 id) const { return m_trees.at(id); }
const Biome &getBiome(u16 id) const { return m_biomes.at(id); }
@ -120,7 +136,7 @@ class Registry : public gk::ISerializable {
static void initUsertype(sol::state &lua);
const std::vector<std::unique_ptr<Block>> &blocks() const { return m_blocks; }
const std::vector<Item> &items() const { return m_items; }
const std::vector<std::unique_ptr<Item>> &items() const { return m_items; }
const std::vector<Tree> &trees() const { return m_trees; }
const std::vector<Biome> &biomes() const { return m_biomes; }
const std::vector<Dimension> &dimensions() const { return m_dimensions; }
@ -133,7 +149,7 @@ class Registry : public gk::ISerializable {
static Registry *s_instance;
std::vector<std::unique_ptr<Block>> m_blocks;
std::vector<Item> m_items;
std::vector<std::unique_ptr<Item>> m_items;
std::vector<std::unique_ptr<Recipe>> m_recipes;
std::vector<Sky> m_skies;
std::vector<Tree> m_trees;

View File

@ -37,12 +37,12 @@ Item::Item(u32 id, const TilesDef &tiles, const std::string &stringID, const std
void Item::serialize(sf::Packet &packet) const {
packet << m_id << m_tiles << m_stringID << m_label << m_isBlock
<< m_miningSpeed << m_harvestCapability << m_groups;
<< m_miningSpeed << m_harvestCapability << m_groups << m_canBeActivated;
}
void Item::deserialize(sf::Packet &packet) {
packet >> m_id >> m_tiles >> m_stringID >> m_label >> m_isBlock
>> m_miningSpeed >> m_harvestCapability >> m_groups;
>> m_miningSpeed >> m_harvestCapability >> m_groups >> m_canBeActivated;
}
// Please update 'docs/lua-api-cpp.md' if you change this

View File

@ -71,11 +71,15 @@ class Item : public gk::ISerializable {
return it->second;
}
bool canBeActivated() const { return m_canBeActivated; }
static void initUsertype(sol::state &lua);
protected:
bool m_isBlock = false;
bool m_canBeActivated = false;
private:
u32 m_id = 0;
TilesDef m_tiles;

View File

@ -57,6 +57,8 @@ std::string Network::commandToString(Network::Command command) {
{Network::Command::BlockInvUpdate, "BlockInvUpdate"},
{Network::Command::BlockDataUpdate, "BlockDataUpdate"},
{Network::Command::ItemActivated, "ItemActivated"},
{Network::Command::RegistryData, "RegistryData"},
{Network::Command::ChatMessage, "ChatMessage"},

View File

@ -40,14 +40,11 @@ namespace Network {
ClientOk = 0x02,
ClientRefused = 0x03,
// Server commands
ServerClosed = 0x04,
// Chunk commands
ChunkData = 0x05,
ChunkRequest = 0x06,
// Player commands
PlayerPlaceBlock = 0x07,
PlayerDigBlock = 0x08,
PlayerInvUpdate = 0x09,
@ -57,29 +54,26 @@ namespace Network {
PlayerChangeDimension = 0x0d,
PlayerHeldItemChanged = 0x0e,
// Block commands
BlockUpdate = 0x0f,
BlockActivated = 0x10,
BlockGUIData = 0x11,
BlockInvUpdate = 0x12,
BlockDataUpdate = 0x13,
// Registry commands
RegistryData = 0x14,
ItemActivated = 0x14,
// Chat commands
ChatMessage = 0x15,
RegistryData = 0x15,
// Entity commands
EntitySpawn = 0x16,
EntityDespawn = 0x17,
EntityPosition = 0x18,
EntityRotation = 0x19,
EntityAnimation = 0x1a,
EntityDrawableDef = 0x1b,
ChatMessage = 0x16,
// Key commands
KeyPressed = 0x1c,
EntitySpawn = 0x17,
EntityDespawn = 0x18,
EntityPosition = 0x19,
EntityRotation = 0x1a,
EntityAnimation = 0x1b,
EntityDrawableDef = 0x1c,
KeyPressed = 0x1d,
};
std::string commandToString(Command command);

View File

@ -29,6 +29,7 @@
#include <gk/resource/ResourceHandler.hpp>
#include "EngineConfig.hpp"
#include "Registry.hpp"
#include "World.hpp"
bool World::isReloadRequested = false;
@ -95,7 +96,15 @@ void World::initUsertype(sol::state &lua) {
"set_data", &World::setData,
"get_block_data", &World::getBlockData,
"add_block_data", &World::addBlockData
"add_block_data", &World::addBlockData,
"get_block_def", [&](World &self, int x, int y, int z) {
return Registry::getInstance().getBlock(self.getBlock(x, y, z));
},
"set_block_from_str", [&](World &self, int x, int y, int z, const std::string &id) {
self.setBlock(x, y, z, Registry::getInstance().getBlockFromStringID(id).id());
}
);
}

View File

@ -118,7 +118,7 @@ bool ServerApplication::init() {
// The id "_:air" is used in CraftingRecipe, update it there if it changes
m_registry.registerBlock<ServerBlock>({}, "_:air", "Air");
m_registry.registerItem({}, "_:air", "Air").setIsBlock(true);
m_registry.registerItem<Item>({}, "_:air", "Air").setIsBlock(true);
m_modLoader.loadMods();

View File

@ -40,6 +40,8 @@ void LuaCore::initUsertype(sol::state &lua) {
"BlockDigged", LuaEventType::BlockDigged,
"BlockActivated", LuaEventType::BlockActivated,
"ItemActivated", LuaEventType::ItemActivated,
"PlayerConnected", LuaEventType::PlayerConnected
);

View File

@ -42,6 +42,8 @@ enum class LuaEventType {
BlockDigged,
BlockActivated,
ItemActivated,
PlayerConnected,
};

View File

@ -48,10 +48,10 @@ void LuaBlockLoader::loadBlock(const sol::table &table) const {
Item *item = nullptr;
if (!block.inventoryImage().empty()) {
item = &Registry::getInstance().registerItem(TilesDef{block.inventoryImage()}, stringID, label);
item = &Registry::getInstance().registerItem<Item>(TilesDef{block.inventoryImage()}, stringID, label);
}
else {
item = &Registry::getInstance().registerItem(block.tiles(), stringID, label);
item = &Registry::getInstance().registerItem<Item>(block.tiles(), stringID, label);
}
item->setIsBlock(true);

View File

@ -29,6 +29,7 @@
#include "LuaItemLoader.hpp"
#include "LuaMod.hpp"
#include "Registry.hpp"
#include "ServerItem.hpp"
void LuaItemLoader::loadItem(const sol::table &table) const {
TilesDef tiles;
@ -37,9 +38,10 @@ void LuaItemLoader::loadItem(const sol::table &table) const {
std::string stringID = m_mod.id() + ":" + table["id"].get<std::string>();
std::string label = table["name"].get<std::string>();
Item &item = Registry::getInstance().registerItem(tiles, stringID, label);
ServerItem &item = Registry::getInstance().registerItem<ServerItem>(tiles, stringID, label);
item.setHarvestCapability(table["harvest_capability"].get_or(0));
item.setMiningSpeed(table["mining_speed"].get_or(1));
item.setOnItemActivated(table["on_item_activated"]);
sol::object groupsObject = table["groups"];
if (groupsObject.valid()) {

View File

@ -34,6 +34,7 @@
#include "Server.hpp"
#include "ServerBlock.hpp"
#include "ServerCommandHandler.hpp"
#include "ServerItem.hpp"
#include "WorldController.hpp"
void ServerCommandHandler::sendServerClosed(const std::string &message, const ClientInfo *client) const {
@ -336,7 +337,7 @@ void ServerCommandHandler::setupCallbacks() {
m_scriptEngine.luaCore().onEvent(LuaEventType::BlockActivated, glm::ivec3{x, y, z}, block, *player, world, client, *this);
}
else
gkError() << ("Failed to activate block using player " + std::to_string(client.id) + ": Player not found").c_str();
gkError() << ("Failed to activate block using player '" + client.playerName + "': Player not found").c_str();
});
m_server.setCommandCallback(Network::Command::BlockInvUpdate, [this](ClientInfo &client, Network::Packet &packet) {
@ -360,6 +361,31 @@ void ServerCommandHandler::setupCallbacks() {
}
});
m_server.setCommandCallback(Network::Command::ItemActivated, [this](ClientInfo &client, Network::Packet &packet) {
ServerPlayer *player = m_players.getPlayerFromClientID(client.id);
if (player) {
s32 x, y, z;
u16 screenWidth, screenHeight;
u8 guiScale;
packet >> x >> y >> z >> screenWidth >> screenHeight >> guiScale;
ServerWorld &world = getWorldForClient(client.id);
u16 id = world.getBlock(x, y, z);
ServerBlock &block = (ServerBlock &)(m_registry.getBlock(id));
ServerItem &item = (ServerItem &)player->heldItemStack().item();
if (item.canBeActivated()) {
bool hasBeenActivated = item.onItemActivated({x, y, z}, block, *player, world, client, *this, screenWidth, screenHeight, guiScale);
if (hasBeenActivated)
m_scriptEngine.luaCore().onEvent(LuaEventType::ItemActivated, glm::ivec3{x, y, z}, block, *player, world, client, *this);
}
}
else
gkError() << ("Failed to activate item using player '" + client.playerName + "': Player not found").c_str();
});
m_server.setCommandCallback(Network::Command::ChatMessage, [this](ClientInfo &client, Network::Packet &packet) {
std::string message;
packet >> message;

View File

@ -53,10 +53,10 @@ class ServerBlock : public Block {
static void initUsertype(sol::state &lua);
private:
sol::protected_function m_onBlockActivated;
sol::protected_function m_onTick;
sol::protected_function m_onBlockPlaced;
sol::protected_function m_onBlockDestroyed;
sol::unsafe_function m_onBlockActivated;
sol::unsafe_function m_onTick;
sol::unsafe_function m_onBlockPlaced;
sol::unsafe_function m_onBlockDestroyed;
mutable bool m_onTickEnabled = true;
};

View File

@ -0,0 +1,54 @@
/*
* =====================================================================================
*
* 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
*
* =====================================================================================
*/
#include <gk/core/Debug.hpp>
#include "Chunk.hpp"
#include "Player.hpp"
#include "ServerCommandHandler.hpp"
#include "ServerItem.hpp"
#include "ServerPlayer.hpp"
#include "World.hpp"
bool ServerItem::onItemActivated(const glm::ivec3 &pos, Block &block, Player &player, World &world, ClientInfo &client, ServerCommandHandler &server, u16 screenWidth, u16 screenHeight, u8 guiScale) const {
try {
if (m_onItemActivated) {
m_onItemActivated(pos, block, player, world, client, server, screenWidth, screenHeight, guiScale);
return true;
}
}
catch (const sol::error &e) {
gkError() << e.what();
}
return false;
}
void ServerItem::setOnItemActivated(const sol::protected_function &function) {
m_onItemActivated = function;
m_canBeActivated = m_onItemActivated.valid();
}

View 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 SERVERITEM_HPP_
#define SERVERITEM_HPP_
#include <glm/vec3.hpp>
#include "Item.hpp"
class Block;
class ClientInfo;
class Player;
class ServerCommandHandler;
class World;
class ServerItem : public Item {
public:
ServerItem(u32 id, const TilesDef &tiles, const std::string &stringID, const std::string &label)
: Item(id, tiles, stringID, label) {}
bool onItemActivated(const glm::ivec3 &pos, Block &block, Player &player, World &world, ClientInfo &client, ServerCommandHandler &server, u16 screenWidth, u16 screenHeight, u8 guiScale) const;
void setOnItemActivated(const sol::protected_function &function);
private:
sol::unsafe_function m_onItemActivated;
};
#endif // SERVERITEM_HPP_

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B