Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hoe #254

Merged
merged 4 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions cubic-server/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "items/UsableItem.hpp"
#include "items/foodItems.hpp"
#include "items/toolsDamage.hpp"
#include "items/usable-items/FlintAndSteel.hpp"
#include "items/usable-items/Hoe.hpp"
#include "logging/logging.hpp"
#include "nbt.h"
#include "protocol/ClientPackets.hpp"
Expand Down Expand Up @@ -83,11 +83,11 @@ Player::Player(std::weak_ptr<Client> cli, std::shared_ptr<Dimension> dim, u128 u
nbt_set_tag_name(display, DISPLAY_TAG.data(), DISPLAY_TAG.size());
nbt_tag_compound_append(display, name);
nbt_tag_compound_append(root, display);
Items::FlintAndSteel flint;
auto flintRoot = flint.setNbtTag();
Items::Hoe hoe = Items::Hoe("minecraft:wooden_hoe", 756, Items::ItemMaxDurabilityByType::WoodenItem, false, Items::UsabilityType::BothMouseClicksUsable);
auto hoeRoot = hoe.setNbtTag();

this->_inventory->playerInventory().at(14) = protocol::Slot(true, 1, 12, root);
this->_inventory->playerInventory().at(16) = protocol::Slot(true, flint._numeralId, 1, flintRoot);
this->_inventory->playerInventory().at(16) = protocol::Slot(true, hoe._numeralId, 1, hoeRoot);
this->_inventory->playerInventory().at(17) = protocol::Slot(true, ITEM_CONVERTER.fromItemToProtocolId("minecraft:wooden_sword"), 1);
PEXP(incrementPlayerCountGlobal);
}
Expand Down Expand Up @@ -1032,6 +1032,15 @@ void Player::_onPlayerAction(protocol::PlayerAction &pck)
Event::cancelBlockDestroy(this, this->getDimension()->getLevel().getChunkColumnFromBlockPos(pck.location.x, pck.location.z).getBlock(pck.location), pck.location);
return;
}
auto item = this->_inventory->hotbar().at(this->_heldItem).getUsableItemFromSlot();
Copy link
Member

@Trompettesib Trompettesib Dec 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be improved to handle multiple items.

if (Items::Hoe *usedItem = std::get_if<Items::Hoe>(&item)) {
if (usedItem->_usabilityType == Items::UsabilityType::LeftMouseClickUsable || usedItem->_usabilityType == Items::UsabilityType::BothMouseClicksUsable) {
usedItem->onUse(this->getDimension(), pck.location, Items::UsabilityType::LeftMouseClickUsable, 1);
if (usedItem->canUpdateDamage) {
this->_inventory->hotbar().at(this->_heldItem).updateDamage();
}
}
}
int id = ITEM_CONVERTER.fromItemToProtocolId(GLOBAL_PALETTE.fromProtocolIdToBlock(this->getDimension()->getBlock(pck.location)).name);
this->getDimension()->updateBlock(pck.location, 0);
_foodExhaustionLevel += 0.005;
Expand Down Expand Up @@ -1163,10 +1172,12 @@ void Player::_onUseItemOn(protocol::UseItemOn &pck)
break;
}
auto item = this->_inventory->hotbar().at(this->_heldItem).getUsableItemFromSlot();
if (const Items::FlintAndSteel *usedItem = std::get_if<Items::FlintAndSteel>(&item)) {
if (usedItem->_usabilityType == Items::UsabilityType::RightMouseClickUsable) {
usedItem->onUse(this->getDimension(), pck.location);
this->_inventory->hotbar().at(this->_heldItem).updateDamage();
if (Items::Hoe *usedItem = std::get_if<Items::Hoe>(&item)) {
Copy link
Member

@Trompettesib Trompettesib Dec 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be improved to handle multiple items.

if (usedItem->_usabilityType == Items::UsabilityType::RightMouseClickUsable || usedItem->_usabilityType == Items::UsabilityType::BothMouseClicksUsable) {
usedItem->onUse(this->getDimension(), pck.location, Items::UsabilityType::RightMouseClickUsable, (int32_t) pck.face);
if (usedItem->canUpdateDamage) {
this->_inventory->hotbar().at(this->_heldItem).updateDamage();
}
this->sendSetContainerSlot({this->_inventory, static_cast<int16_t>(this->_heldItem + HOTBAR_OFFSET)});
}
return;
Expand Down
13 changes: 7 additions & 6 deletions cubic-server/items/UsableItem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ struct UsableItem {
*
* @param dim The current dimension the player is in (facultative)
* @param pos The position on which the item was used (facultative)
* @param usage Determining with which mouse click the item is used (for items that are used with both clicks)
*/
virtual void onUse(UNUSED std::shared_ptr<Dimension> dim, UNUSED Position &pos) const {};
virtual void onUse(UNUSED std::shared_ptr<Dimension> dim, UNUSED Position &pos, UNUSED UsabilityType usage, UNUSED int32_t face) {};

/**
* @brief Set the NBT Tag of the item
Expand Down Expand Up @@ -109,27 +110,27 @@ const std::array<UsableItem, 41> usableItems {
UsableItem("minecraft:wooden_shovel", 753, ItemMaxDurabilityByType::WoodenItem, false, UsabilityType::BothMouseClicksUsable),
UsableItem("minecraft:wooden_pickaxe", 754, ItemMaxDurabilityByType::WoodenItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:wooden_axe", 755, ItemMaxDurabilityByType::WoodenItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:wooden_hoe", 756, ItemMaxDurabilityByType::WoodenItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:wooden_hoe", 756, ItemMaxDurabilityByType::WoodenItem, false, UsabilityType::BothMouseClicksUsable),
UsableItem("minecraft:stone_sword", 757, ItemMaxDurabilityByType::StoneItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:stone_shovel", 758, ItemMaxDurabilityByType::StoneItem, false, UsabilityType::BothMouseClicksUsable),
UsableItem("minecraft:stone_pickaxe", 759, ItemMaxDurabilityByType::StoneItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:stone_axe", 760, ItemMaxDurabilityByType::StoneItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:stone_hoe", 761, ItemMaxDurabilityByType::StoneItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:stone_hoe", 761, ItemMaxDurabilityByType::StoneItem, false, UsabilityType::BothMouseClicksUsable),
UsableItem("minecraft:iron_sword", 767, ItemMaxDurabilityByType::IronItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:iron_shovel", 768, ItemMaxDurabilityByType::IronItem, false, UsabilityType::BothMouseClicksUsable),
UsableItem("minecraft:iron_pickaxe", 769, ItemMaxDurabilityByType::IronItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:iron_axe", 770, ItemMaxDurabilityByType::IronItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:iron_hoe", 771, ItemMaxDurabilityByType::IronItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:iron_hoe", 771, ItemMaxDurabilityByType::IronItem, false, UsabilityType::BothMouseClicksUsable),
UsableItem("minecraft:diamond_sword", 772, ItemMaxDurabilityByType::DiamondItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:diamond_shovel", 773, ItemMaxDurabilityByType::DiamondItem, false, UsabilityType::BothMouseClicksUsable),
UsableItem("minecraft:diamond_pickaxe", 774, ItemMaxDurabilityByType::DiamondItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:diamond_axe", 775, ItemMaxDurabilityByType::DiamondItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:diamond_hoe", 776, ItemMaxDurabilityByType::DiamondItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:diamond_hoe", 776, ItemMaxDurabilityByType::DiamondItem, false, UsabilityType::BothMouseClicksUsable),
UsableItem("minecraft:netherite_sword", 777, ItemMaxDurabilityByType::NetheriteItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:netherite_shovel", 778, ItemMaxDurabilityByType::NetheriteItem, false, UsabilityType::BothMouseClicksUsable),
UsableItem("minecraft:netherite_pickaxe", 779, ItemMaxDurabilityByType::NetheriteItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:netherite_axe", 780, ItemMaxDurabilityByType::NetheriteItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:netherite_hoe", 781, ItemMaxDurabilityByType::NetheriteItem, false, UsabilityType::LeftMouseClickUsable),
UsableItem("minecraft:netherite_hoe", 781, ItemMaxDurabilityByType::NetheriteItem, false, UsabilityType::BothMouseClicksUsable),
UsableItem("cubic:unusable", -1, ItemMaxDurabilityByType::ResetDefault, true, UsabilityType::NoneClickUsable) /**< For items that are not usable/broken */
};

Expand Down
2 changes: 2 additions & 0 deletions cubic-server/items/usable-items/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
target_sources (${CMAKE_PROJECT_NAME} PRIVATE
FlintAndSteel.cpp
FlintAndSteel.hpp
Hoe.cpp
Hoe.hpp
)
2 changes: 1 addition & 1 deletion cubic-server/items/usable-items/FlintAndSteel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ nbt_tag_t *Items::FlintAndSteel::setNbtTag()
return root;
}

void Items::FlintAndSteel::onUse(UNUSED std::shared_ptr<Dimension> dim, UNUSED Position &pos) const
void Items::FlintAndSteel::onUse(std::shared_ptr<Dimension> dim, Position &pos, UNUSED UsabilityType usage, UNUSED int32_t face)
{
dim->updateBlock(
pos,
Expand Down
2 changes: 1 addition & 1 deletion cubic-server/items/usable-items/FlintAndSteel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct FlintAndSteel : public UsableItem {
* @note See Item::UsableItem::onUse() for more info
*
*/
void onUse(std::shared_ptr<Dimension> dim, Position &pos) const override;
void onUse(std::shared_ptr<Dimension> dim, Position &pos, UNUSED UsabilityType usage, UNUSED int32_t face) override;

/**
* @note See Item::UsableItem::setNbtTag() for more info
Expand Down
87 changes: 87 additions & 0 deletions cubic-server/items/usable-items/Hoe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include "Hoe.hpp"
#include "Dimension.hpp"
#include "Server.hpp"
#include "blocks.hpp"
#include "entities/Item.hpp"
#include "items/UsableItem.hpp"
#include <exception>

nbt_tag_t *Items::Hoe::setNbtTag()
{
int32_t DAMAGE = 0;
int32_t UNBREAKABLE = this->_isUnbreakable;
std::string_view DAMAGE_TAG = "Damage";
std::string_view UNBREAKABLE_TAG = "Breakable";
auto root = nbt_new_tag_compound();
auto damage = nbt_new_tag_int(DAMAGE);
auto breakable = nbt_new_tag_int(UNBREAKABLE);
nbt_set_tag_name(damage, DAMAGE_TAG.data(), DAMAGE_TAG.size());
nbt_set_tag_name(breakable, UNBREAKABLE_TAG.data(), UNBREAKABLE_TAG.size());
nbt_tag_compound_append(root, damage);
nbt_tag_compound_append(root, breakable);

return root;
}

void Items::Hoe::onUse(std::shared_ptr<Dimension> dim, Position &pos, UsabilityType usage, int32_t face)
{
auto blockPos = pos;

switch (face) {
case 0: /**< protocol::UseItemOn::Face::Bottom */
blockPos.y++;
break;
case 1: /**< protocol::UseItemOn::Face::Top */
blockPos.y--;
break;
case 2: /**< protocol::UseItemOn::Face::North */
blockPos.z++;
break;
case 3: /**< protocol::UseItemOn::Face::South */
blockPos.z--;
break;
case 4: /**< protocol::UseItemOn::Face::East */
blockPos.x++;
break;
case 5: /**< protocol::UseItemOn::Face::West */
blockPos.x--;
break;
}

try {
Copy link
Member

@Trompettesib Trompettesib Dec 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be removed when the generation offset is fixed.

auto Topblock = dim->getBlock(pos);
auto block = dim->getBlock(blockPos);
if (usage == UsabilityType::RightMouseClickUsable) {
if (Topblock == Blocks::Air::toProtocol() &&
(block == Blocks::Dirt::toProtocol() || block == Blocks::GrassBlock::toProtocol(Blocks::GrassBlock::Properties::Snowy::FALSE) ||
block == Blocks::DirtPath::toProtocol())) {
dim->updateBlock(blockPos, Blocks::Farmland::toProtocol(Blocks::Farmland::Properties::Moisture::ZERO));
canUpdateDamage = true;
return;
} else if (Topblock == Blocks::Air::toProtocol() && block == Blocks::CoarseDirt::toProtocol()) {
dim->updateBlock(blockPos, Blocks::Dirt::toProtocol());
canUpdateDamage = true;
return;
} else if (Topblock == Blocks::Air::toProtocol() && block == Blocks::RootedDirt::toProtocol()) {
dim->updateBlock(blockPos, Blocks::Dirt::toProtocol());
dim->makeEntity<Item>(protocol::Slot {true, 214, 1})
->dropItem({static_cast<double>(pos.x) + 0.5, static_cast<double>(pos.y), static_cast<double>(pos.z) + 0.5}); // hanging roots
canUpdateDamage = true;
return;
}
} else if (usage == UsabilityType::LeftMouseClickUsable) {
if (BLOCK_DATA_CONVERTER.fromBlockIdToBlockData(dim->getBlock(pos)).hardness != 0) {
canUpdateDamage = true;
return;
}
for (int i = 0; i <= (int) breakableWithHoe.size(); i++) {
if (GLOBAL_PALETTE.fromBlockToProtocolId(breakableWithHoe[i])) {
// TODO: handle breaking blocks speed
}
}
}
} catch (std::exception &e) {
LERROR("Error in getting block");
}
canUpdateDamage = false;
}
61 changes: 61 additions & 0 deletions cubic-server/items/usable-items/Hoe.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#ifndef CUBICSERVER_ITEMS_USABLE_ITEMS_HOE
#define CUBICSERVER_ITEMS_USABLE_ITEMS_HOE

#include "items/UsableItem.hpp"
#include "types.hpp"
#include <array>
#include <string>

namespace Items {

/**
* @brief The 'Hoe' is an item used to transform dirt blocs into other types, such as farmland
*
*/
struct Hoe : public UsableItem {
Hoe(const std::string_view stringId, const int32_t numeralId, const ItemMaxDurabilityByType maxDurability, bool isUnbreakable, const UsabilityType usabilityType):
UsableItem(stringId, numeralId, maxDurability, isUnbreakable, usabilityType)
{
}

Hoe(const UsableItem &other):
UsableItem(other)
{
}

/**
* @note See Item::UsableItem::onUse() for more info
*
*/
void onUse(std::shared_ptr<Dimension> dim, Position &pos, UsabilityType usage, int32_t face) override;

/**
* @note See Item::UsableItem::setNbtTag() for more info
*
*/
nbt_tag_t *setNbtTag() override;

bool canUpdateDamage = false;
};

const std::array<std::string, 16> breakableWithHoe {
"minecraft:sculk_catalyst",
"minecraft:sculk_shrieker",
"minecraft:sculk_sensor",
"minecraft:calibrated_sculk_sensor",
"minecraft:nether_wart_block",
"minecraft:warped_wart_block",
"minecraft:shroomlight",
"minecraft:hay_bale",
"minecraft:target",
"minecraft:dried_kelp_block",
"minecraft:sponge",
"minecraft:wet_sponge",
"minecraft:leaves",
"minecraft:sculk",
"minecraft:sculk_vein",
"minecraft:moss_block"};

} // namespace Items

#endif // CUBICSERVER_ITEMS_USABLE_ITEMS_HOE
3 changes: 3 additions & 0 deletions cubic-server/protocol/Structures.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "Structures.hpp"
#include "items/UsableItem.hpp"
#include "items/usable-items/FlintAndSteel.hpp"
#include "items/usable-items/Hoe.hpp"
#include "logging/logging.hpp"

const protocol::ItemType protocol::Slot::getUsableItemFromSlot()
Expand All @@ -13,6 +14,8 @@ const protocol::ItemType protocol::Slot::getUsableItemFromSlot()
}
if (item->_stringId == "minecraft:flint_and_steel")
return Items::FlintAndSteel();
if (item->_stringId.find("_hoe"))
return Items::Hoe(*item);
return *item;
}

Expand Down
4 changes: 3 additions & 1 deletion cubic-server/protocol/Structures.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "items/UsableItem.hpp"
#include "items/usable-items/FlintAndSteel.hpp"
#include "items/usable-items/Hoe.hpp"
#include "nbt.h"
#include "nbt.hpp"

Expand All @@ -32,7 +33,8 @@ namespace protocol {

#define SET_VALUE_INT(dst, src, root) SET_VALUE(NBT_TYPE_INT, tag_int, dst, src, root)

typedef std::variant<Items::UsableItem, Items::FlintAndSteel> ItemType; /**< Used to get the right type of Usable item, to be able to use the right functions afterwards */
typedef std::variant<Items::UsableItem, Items::FlintAndSteel, Items::Hoe>
ItemType; /**< Used to get the right type of Usable item, to be able to use the right functions afterwards */
struct Slot {
constexpr ~Slot()
{
Expand Down