[BlockParam] Added (see #139).

This commit is contained in:
Quentin Bazin 2020-07-09 22:24:19 +02:00
parent 02b9f8b283
commit 2b210d697a
8 changed files with 203 additions and 5 deletions

View File

@ -11,6 +11,7 @@
- `string mod_name()` - `string mod_name()`
- `bool is_opaque()` - `bool is_opaque()`
- `ItemStack get_item_drop()` - `ItemStack get_item_drop()`
- `BlockParam param()`
## BlockData ## BlockData

View File

@ -49,7 +49,8 @@ std::array<std::size_t, ChunkBuilder::layers> ChunkBuilder::buildChunk(const Cli
const gk::FloatBox &boundingBox = block.boundingBox(); const gk::FloatBox &boundingBox = block.boundingBox();
u8f orientation = block.isRotatable() ? chunk.getData(x, y, z) & 0x1F : 0; u8f orientation = block.isRotatable()
? block.param().getParam(BlockParam::Rotation, chunk.getData(x, y, z)) : 0;
const glm::mat3 &orientMatrix = orientMatrices[orientation]; const glm::mat3 &orientMatrix = orientMatrices[orientation];
if (block.drawType() == BlockDrawType::Solid if (block.drawType() == BlockDrawType::Solid

View File

@ -45,7 +45,7 @@ void Block::serialize(sf::Packet &packet) const {
<< m_hardness << m_harvestRequirements << m_itemDrop << m_itemDropAmount << m_tiles << m_hardness << m_harvestRequirements << m_itemDrop << m_itemDropAmount << m_tiles
<< m_boundingBox << m_isOpaque << m_isLightSource << m_canUpdate << m_canBeActivated << m_boundingBox << m_isOpaque << m_isLightSource << m_canUpdate << m_canBeActivated
<< m_colorMultiplier << m_isRotatable << m_inventoryImage << m_groups << m_colorMultiplier << m_isRotatable << m_inventoryImage << m_groups
<< m_fogDepth << m_fogColor; << m_fogDepth << m_fogColor << m_param;
} }
void Block::deserialize(sf::Packet &packet) { void Block::deserialize(sf::Packet &packet) {
@ -56,7 +56,7 @@ void Block::deserialize(sf::Packet &packet) {
>> m_hardness >> m_harvestRequirements >> m_itemDrop >> m_itemDropAmount >> m_tiles >> m_hardness >> m_harvestRequirements >> m_itemDrop >> m_itemDropAmount >> m_tiles
>> m_boundingBox >> m_isOpaque >> m_isLightSource >> m_canUpdate >> m_canBeActivated >> m_boundingBox >> m_isOpaque >> m_isLightSource >> m_canUpdate >> m_canBeActivated
>> m_colorMultiplier >> m_isRotatable >> m_inventoryImage >> m_groups >> m_colorMultiplier >> m_isRotatable >> m_inventoryImage >> m_groups
>> m_fogDepth >> m_fogColor; >> m_fogDepth >> m_fogColor >> m_param;
m_id = id; m_id = id;
m_drawType = BlockDrawType(drawType); m_drawType = BlockDrawType(drawType);
@ -71,7 +71,8 @@ void Block::initUsertype(sol::state &lua) {
"label", &Block::label, "label", &Block::label,
"mod_name", &Block::modName, "mod_name", &Block::modName,
"is_opaque", &Block::isOpaque, "is_opaque", &Block::isOpaque,
"get_item_drop", &Block::getItemDrop "get_item_drop", &Block::getItemDrop,
"param", (const BlockParam &(Block::*)() const)&Block::param
); );
} }

View File

@ -36,6 +36,7 @@
#include <gk/core/ISerializable.hpp> #include <gk/core/ISerializable.hpp>
#include <gk/graphics/Color.hpp> #include <gk/graphics/Color.hpp>
#include "BlockParam.hpp"
#include "ItemStack.hpp" #include "ItemStack.hpp"
#include "TilesDef.hpp" #include "TilesDef.hpp"
@ -126,6 +127,9 @@ class Block : public gk::ISerializable {
const gk::Color &fogColor() const { return m_fogColor; } const gk::Color &fogColor() const { return m_fogColor; }
void setFogColor(const gk::Color &fogColor) { m_fogColor = fogColor; } void setFogColor(const gk::Color &fogColor) { m_fogColor = fogColor; }
const BlockParam &param() const { return m_param; }
BlockParam &param() { return m_param; }
static void initUsertype(sol::state &lua); static void initUsertype(sol::state &lua);
protected: protected:
@ -165,6 +169,8 @@ class Block : public gk::ISerializable {
float m_fogDepth = 0; float m_fogDepth = 0;
gk::Color m_fogColor = gk::Color::White; gk::Color m_fogColor = gk::Color::White;
BlockParam m_param{*this};
}; };
#endif // BLOCK_HPP_ #endif // BLOCK_HPP_

View File

@ -0,0 +1,100 @@
/*
* =====================================================================================
*
* 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 <sol/sol.hpp>
#include "Block.hpp"
#include "BlockParam.hpp"
void BlockParam::serialize(sf::Packet &packet) const {
packet << m_totalSize << m_allocatedBits;
}
void BlockParam::deserialize(sf::Packet &packet) {
packet >> m_totalSize >> m_allocatedBits;
}
void BlockParam::allocateBits(u8 type, u8 size) {
auto it = m_allocatedBits.find(type);
if (it != m_allocatedBits.end()) {
gkWarning() << "Can't allocate param type" << getTypeName(type) << "twice in block" << m_block.stringID();
}
else if (m_totalSize + size <= 16) {
m_allocatedBits.emplace(type, Param{m_totalSize, size});
m_totalSize += size;
// gkDebug() << "Allocated" << (int)size << "bits for type" << getTypeName(type) << "in block" << m_block.stringID();
}
else {
gkError() << "Failed to allocate bits for param" << getTypeName(type) << "in block" << m_block.stringID();
gkError() << "Reason: Can't allocate more than 16 bits. Allocated bits:";
for (auto &it : m_allocatedBits) {
gkError() << "\t-" << getTypeName(it.first) << "=" << (int)it.second.size;
}
}
}
u16 BlockParam::getParam(u8 type, u16 data) const {
auto it = m_allocatedBits.find(type);
if (it == m_allocatedBits.end()) {
gkWarning() << "Failed to get param" << getTypeName(type) << "in block" << m_block.stringID();
return 0;
}
return (data >> it->second.offset) & ~(~0u << it->second.size);
}
u16 BlockParam::setParam(u8 type, u16 data, u16 param) {
auto it = m_allocatedBits.find(type);
if (it == m_allocatedBits.end()) {
gkWarning() << "Failed to set param" << getTypeName(type) << "in block" << m_block.stringID();
return 0;
}
u16 mask = ~(~0u << it->second.size) << it->second.offset;
param <<= it->second.offset;
if ((param & ~mask) != 0)
gkWarning() << "Block param overflow for type" << getTypeName(type) << "in block" << m_block.stringID();
return (data & ~mask) | (param & mask);
}
std::string BlockParam::getTypeName(u8 type) {
std::array<std::string, Type::Count> names = {
"Rotation",
};
return names[type];
}
// Please update 'docs/lua-api-cpp.md' if you change this
void BlockParam::initUsertype(sol::state &lua) {
lua.new_usertype<BlockParam>("BlockParam");
}

View File

@ -0,0 +1,82 @@
/*
* =====================================================================================
*
* 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 BLOCKPARAM_HPP_
#define BLOCKPARAM_HPP_
#include <string>
#include <unordered_map>
#include <gk/core/IntTypes.hpp>
#include <gk/core/ISerializable.hpp>
#include "NetworkUtils.hpp"
namespace sol { class state; }
class Block;
class BlockParam : public gk::ISerializable {
public:
BlockParam(Block &block) : m_block(block) {}
void serialize(sf::Packet &packet) const override;
void deserialize(sf::Packet &packet) override;
enum Type {
Rotation,
Count
};
void allocateBits(u8 type, u8 size);
u16 getParam(u8 type, u16 data) const;
u16 setParam(u8 type, u16 data, u16 param);
static std::string getTypeName(u8 type);
static void initUsertype(sol::state &lua);
private:
Block &m_block;
u8 m_totalSize = 0;
struct Param : public gk::ISerializable {
Param() = default;
Param(u8 _offset, u8 _size) : offset(_offset), size(_size) {}
void serialize(sf::Packet &packet) const override { packet << offset << size; }
void deserialize(sf::Packet &packet) override { packet >> offset >> size; }
u8 offset;
u8 size;
};
std::unordered_map<u8, Param> m_allocatedBits;
};
#endif // BLOCKPARAM_HPP_

View File

@ -57,6 +57,8 @@ void LuaBlockLoader::loadBlock(const sol::table &table) const {
item->setIsBlock(true); item->setIsBlock(true);
loadGroups(block, *item, table); loadGroups(block, *item, table);
loadParams(block);
} }
inline void LuaBlockLoader::loadProperties(ServerBlock &block, const sol::table &table) const { inline void LuaBlockLoader::loadProperties(ServerBlock &block, const sol::table &table) const {
@ -164,3 +166,8 @@ inline void LuaBlockLoader::loadGroups(ServerBlock &block, Item &item, const sol
} }
} }
void LuaBlockLoader::loadParams(ServerBlock &block) const {
if (block.isRotatable())
block.param().allocateBits(BlockParam::Type::Rotation, 5);
}

View File

@ -45,8 +45,8 @@ class LuaBlockLoader {
void loadDrawType(ServerBlock &block, const sol::table &table) const; void loadDrawType(ServerBlock &block, const sol::table &table) const;
void loadItemDrop(ServerBlock &block, const sol::table &table) const; void loadItemDrop(ServerBlock &block, const sol::table &table) const;
void loadColorMultiplier(ServerBlock &block, const sol::table &table) const; void loadColorMultiplier(ServerBlock &block, const sol::table &table) const;
void loadGroups(ServerBlock &block, Item &item, const sol::table &table) const; void loadGroups(ServerBlock &block, Item &item, const sol::table &table) const;
void loadParams(ServerBlock &block) const;
LuaMod &m_mod; LuaMod &m_mod;
}; };