diff --git a/cubic-server/generation/player_constructions/NetherPortal.cpp b/cubic-server/generation/player_constructions/NetherPortal.cpp index ac17a0872..52bfbf6ef 100644 --- a/cubic-server/generation/player_constructions/NetherPortal.cpp +++ b/cubic-server/generation/player_constructions/NetherPortal.cpp @@ -6,128 +6,244 @@ #include "types.hpp" #include -bool NetherPortal::checkLayers(Position pos, int axis) +void NetherPortal::setIgnitedBlock() { - auto block = _dim->getBlock(pos); - for (int y = 0; y < FRAME_HEIGHT; y++) { - for (int x = 0; x < FRAME_WIDTH; x++) { - if (axis == AXIS_X) { - block = _dim->getBlock({pos.x + x, pos.y + y, pos.z}); - } else if (axis == AXIS_Z) { - block = _dim->getBlock({pos.x, pos.y + y, pos.z + x}); - } else { - return false; + std::vector blocksArray; + + // blockArray[0] & blockArray[1] - {-1;0;0}, {1;0;0} - LEFT or RIGHT + for (int x = -1; x <= 1; x++) { + if (x != 0) + continue; + auto lateralBlock = {_pos.x + x, _pos.y, _pos.z}; + blocksArray.push_back(_dim->getBlock(lateralBlock)); + } + // blockArray[2] & blockArray[3] - {0;-1;0}, {0;1;0} - TOP or BOTTOM + for (int y = -1; y <= 1; y++) { + if (y != 0) + continue; + auto lateralBlock = {_pos.x, _pos.y + y, _pos.z}; + blocksArray.push_back(_dim->getBlock(lateralBlock)); + } + // blockArray[4] & blockArray[5] - {0;0;-1}, {0;0;1} - LEFT or RIGHT + for (int z = -1; z <= 1; z++) { + if (z != 0) + continue; + auto lateralBlock = {_pos.x, _pos.y, _pos.z + z}; + blocksArray.push_back(_dim->getBlock(lateralBlock)); + } + + if (blocksArray[4] == Blocks::Obsidian::toProtocol() && blocksArray[5] != Blocks::Obsidian::toProtocol()) { + if ((blocksArray[0] == Blocks::Obsidian::toProtocol() && blocksArray[1] != Blocks::Obsidian::toProtocol()) || + (blocksArray[2] == Blocks::Obsidian::toProtocol() && blocksArray[3] != Blocks::Obsidian::toProtocol())) { + _ignitedBlock = PortalIgnition::PORTAL_TOP_LEFT_CORNER; + return; + } else if ((blocksArray[1] == Blocks::Obsidian::toProtocol() && blocksArray[0] != Blocks::Obsidian::toProtocol()) || (blocksArray[3] == Blocks::Obsidian::toProtocol() && + blocksArray[2] != Blocks::Obsidian::toProtocol())) { + _ignitedBlock = PortalIgnition::PORTAL_TOP_RIGHT_CORNER; + return; + } else { + _ignitedBlock = PortalIgnition::PORTAL_TOP_CENTER; + return; + } + } else if (blocksArray[4] != Blocks::Obsidian::toProtocol() && blocksArray[5] == Blocks::Obsidian::toProtocol()) { + if ((blocksArray[0] == Blocks::Obsidian::toProtocol() && blocksArray[1] != Blocks::Obsidian::toProtocol()) || + (blocksArray[2] == Blocks::Obsidian::toProtocol() && blocksArray[3] != Blocks::Obsidian::toProtocol())) { + _ignitedBlock = PortalIgnition::PORTAL_BOTTOM_LEFT_CORNER; + return; + } else if ((blocksArray[1] == Blocks::Obsidian::toProtocol() && blocksArray[0] != Blocks::Obsidian::toProtocol()) || (blocksArray[3] == Blocks::Obsidian::toProtocol() && + blocksArray[2] != Blocks::Obsidian::toProtocol())) { + _ignitedBlock = PortalIgnition::PORTAL_BOTTOM_RIGHT_CORNER; + return; + } else { + _ignitedBlock = PortalIgnition::PORTAL_BOTTOM_CENTER; + return; + } + } else { + if ((blocksArray[0] == Blocks::Obsidian::toProtocol() && blocksArray[1] != Blocks::Obsidian::toProtocol()) || + (blocksArray[2] == Blocks::Obsidian::toProtocol() && blocksArray[3] != Blocks::Obsidian::toProtocol())) { + _ignitedBlock = PortalIgnition::PORTAL_LEFT_CENTER; + return; + } else if ((blocksArray[1] == Blocks::Obsidian::toProtocol() && blocksArray[0] != Blocks::Obsidian::toProtocol()) || (blocksArray[3] == Blocks::Obsidian::toProtocol() && + blocksArray[2] != Blocks::Obsidian::toProtocol())) { + _ignitedBlock = PortalIgnition::PORTAL_RIGHT_CENTER; + return; + } else { + _ignitedBlock = PortalIgnition::PORTAL_NONE; + return; + } + } + + _ignitedBlock = PortalIgnition::PORTAL_NONE; +} + +void NetherPortal::setBottomLeftCorner() +{ + if (_ignitedBlock == PortalIgnition::PORTAL_BOTTOM_LEFT_CORNER) { + _bottomLeftCorner = {_pos.x, _pos.y - 1, _pos.z}; + return; + } else if (_ignitedBlock == PortalIgnition::PORTAL_NONE) { + return; + } else if (_ignitedBlock == PortalIgnition::PORTAL_TOP_LEFT_CORNER || _ignitedBlock == PortalIgnition::PORTAL_LEFT_CENTER) { + for (int count = 1; count < PortalBoundary::PORTAL_MAX_HEIGHT - PortalBoundary::PORTAL_MIN_HEIGHT - PortalBoundary::PORTAL_NO_CORNERS; count++) { + if (_dim->getBlock({_pos.x, _pos.y - count, _pos.z}) == Blocks::Obsidian::toProtocol()) { + _bottomLeftCorner = {_pos.x, _pos.y - count, _pos.z}; + return; } - if ((y == 0 || y == FRAME_HEIGHT - 1) && (x == 0 || x == FRAME_WIDTH - 1)) { - if (block != Blocks::Obsidian::toProtocol()) { - return false; - } - } else if (x != 0 && x < FRAME_WIDTH - 1 && y == 1) { - if (block == Blocks::Air::toProtocol() || - block == - Blocks::Fire::toProtocol( - Blocks::Fire::Properties::Age::ZERO, Blocks::Fire::Properties::East::FALSE, Blocks::Fire::Properties::North::FALSE, - Blocks::Fire::Properties::South::FALSE, Blocks::Fire::Properties::Up::FALSE, Blocks::Fire::Properties::West::FALSE - )) { - continue; - } else { - return false; - } - } else if (x > 1 && x < FRAME_WIDTH - 1 && y != 0 && y < FRAME_HEIGHT - 1) { - if (block != Blocks::Air::toProtocol()) { - return false; + } + } else if (_ignitedBlock == PortalIgnition::PORTAL_BOTTOM_RIGHT_CORNER || _ignitedBlock == PortalIgnition::PORTAL_BOTTOM_CENTER) { + for (int count = 1; count < PortalBoundary::PORTAL_MAX_WIDTH - PortalBoundary::PORTAL_MIN_WIDTH - PortalBoundary::PORTAL_NO_CORNERS; count++) { + if (_dim->getBlock({_pos.x - count, _pos.y, _pos.z}) == Blocks::Obsidian::toProtocol() && count > 1) { + _bottomLeftCorner = {_pos.x - count, _pos.y - 1, _pos.z}; + _direction = PortalDirection::PORTAL_X_AXIS; + return; + } else if (_dim->getBlock({_pos.x, _pos.y, _pos.z - count}) == Blocks::Obsidian::toProtocol() && count > 1) { + _bottomLeftCorner = {_pos.x, _pos.y - 1, _pos.z - count}; + _direction = PortalDirection::PORTAL_Z_AXIS; + return; + } + } + } else { + for (int countY = 1; countY < PortalBoundary::PORTAL_MAX_HEIGHT - PortalBoundary::PORTAL_MIN_HEIGHT - PortalBoundary::PORTAL_NO_CORNERS; countY++) { + for (int count = 1; count < PortalBoundary::PORTAL_MAX_WIDTH - PortalBoundary::PORTAL_MIN_WIDTH - PortalBoundary::PORTAL_NO_CORNERS; count++) { + if (_dim->getBlock({_pos.x, _pos.y - countY, _pos.z}) == Blocks::Obsidian::toProtocol() && + _dim->getBlock({_pos.x - count, _pos.y, _pos.z}) == Blocks::Obsidian::toProtocol() && count > 1) { + _bottomLeftCorner = {_pos.x - count, _pos.y - countY, _pos.z}; + _direction = PortalDirection::PORTAL_X_AXIS; + return; + } else if (_dim->getBlock({_pos.x, _pos.y - countY, _pos.z}) == Blocks::Obsidian::toProtocol() && + _dim->getBlock({_pos.x, _pos.y, _pos.z - count}) == Blocks::Obsidian::toProtocol() && count > 1) { + _bottomLeftCorner = {_pos.x, _pos.y - countY, _pos.z - count}; + _direction = PortalDirection::PORTAL_Z_AXIS; + return; } } } } - return true; + _bottomLeftCorner = _pos; + _direction = PortalDirection::PORTAL_WRONG_DIRECTION; } -Frame NetherPortal::getFrame(Position pos) +void NetherPortal::setDirection() { - auto nextBlockX = _dim->getBlock({(pos.x + 1), pos.y, pos.z}); - auto nextBlockZ = _dim->getBlock({pos.x, pos.y, (pos.z + 1)}); - auto topNextBlockX = _dim->getBlock({(pos.x + 1), pos.y + 1, pos.z}); - auto topNextBlockZ = _dim->getBlock({pos.x, pos.y + 1, (pos.z + 1)}); + if (_ignitedBlock == PortalIgnition::PORTAL_NONE || _direction == PortalDirection::PORTAL_WRONG_DIRECTION || _direction == PortalDirection::PORTAL_X_AXIS || + _direction == PortalDirection::PORTAL_Z_AXIS) + return; - if (nextBlockX == Blocks::Obsidian::toProtocol() && topNextBlockX == Blocks::Air::toProtocol() && nextBlockZ != Blocks::Obsidian::toProtocol()) { - LDEBUG("Axis X"); - if (checkLayers({pos.x - 1, pos.y, pos.z}, AXIS_X)) - return {AXIS_X, POSITIVE_POS}; - } else if (nextBlockX == Blocks::Obsidian::toProtocol() && topNextBlockX == Blocks::Obsidian::toProtocol() && topNextBlockZ != Blocks::Obsidian::toProtocol()) { - LDEBUG("Axis X"); - if (checkLayers({pos.x - 2, pos.y, pos.z}, AXIS_X)) - return {AXIS_X, NEGATIVE_POS}; - } - if (nextBlockZ == Blocks::Obsidian::toProtocol() && topNextBlockZ == Blocks::Air::toProtocol() && nextBlockX != Blocks::Obsidian::toProtocol()) { - LDEBUG("Axis Z"); - if (checkLayers({pos.x, pos.y, pos.z - 1}, AXIS_Z)) - return {AXIS_Z, POSITIVE_POS}; - } else if (nextBlockZ == Blocks::Obsidian::toProtocol() && topNextBlockZ == Blocks::Obsidian::toProtocol() && topNextBlockX != Blocks::Obsidian::toProtocol()) { - LDEBUG("Axis Z"); - if (checkLayers({pos.x, pos.y, pos.z - 2}, AXIS_Z)) - return {AXIS_Z, NEGATIVE_POS}; + if (_dim->getBlock({_bottomLeftCorner.x - 1, _bottomLeftCorner.y + 1, _bottomLeftCorner.z}) == Blocks::Obsidian::toProtocol() && + _dim->getBlock({_bottomLeftCorner.x + 1, _bottomLeftCorner.y, _bottomLeftCorner.z}) == Blocks::Obsidian::toProtocol() && + (_dim->getBlock({_bottomLeftCorner.x + 2, _bottomLeftCorner.y, _bottomLeftCorner.z}) == Blocks::Obsidian::toProtocol() || + _dim->getBlock({_bottomLeftCorner.x + 2, _bottomLeftCorner.y + 1, _bottomLeftCorner.z}) == Blocks::Obsidian::toProtocol())) { + _direction = PortalDirection::PORTAL_X_AXIS; + return; + } else if (_dim->getBlock({_bottomLeftCorner.x, _bottomLeftCorner.y + 1, _bottomLeftCorner.z - 1}) == Blocks::Obsidian::toProtocol() && + _dim->getBlock({_bottomLeftCorner.x, _bottomLeftCorner.y, _bottomLeftCorner.z + 1}) == Blocks::Obsidian::toProtocol() && + (_dim->getBlock({_bottomLeftCorner.x, _bottomLeftCorner.y, _bottomLeftCorner.z + 2}) == Blocks::Obsidian::toProtocol() || + _dim->getBlock({_bottomLeftCorner.x, _bottomLeftCorner.y + 1, _bottomLeftCorner.z + 2}) == Blocks::Obsidian::toProtocol())) { + _direction = PortalDirection::PORTAL_Z_AXIS; + return; } - LWARN("No frame"); - return {AXIS_UNDEFINED, UNDEFINED_POS}; + + _direction = PortalDirection::PORTAL_WRONG_DIRECTION; +} + +void NetherPortal::setSize() +{ + if (_ignitedBlock == PortalIgnition::PORTAL_NONE) + return; + + if (_direction == PortalDirection::PORTAL_X_AXIS) { + for (int countWidth = 1; countWidth < (PortalBoundary::PORTAL_MAX_WIDTH - PortalBoundary::PORTAL_NO_CORNERS); countWidth++) { + if (_dim->getBlock({_bottomLeftCorner.x + (countWidth - 1), _bottomLeftCorner.y, _bottomLeftCorner.z}) == Blocks::Obsidian::toProtocol() && + _dim->getBlock({_bottomLeftCorner.x + countWidth, _bottomLeftCorner.y + 1, _bottomLeftCorner.z}) == Blocks::Obsidian::toProtocol() && + countWidth >= (PortalBoundary::PORTAL_MIN_WIDTH - PortalBoundary::PORTAL_NO_CORNERS)) { + _size.x = countWidth - 1; + } + } + for (int countHeight = 1; countHeight < (PortalBoundary::PORTAL_MAX_HEIGHT - PortalBoundary::PORTAL_NO_CORNERS); countHeight++) { + if (_dim->getBlock({_bottomLeftCorner.x - 1, _bottomLeftCorner.y + (countHeight - 1), _bottomLeftCorner.z}) == Blocks::Obsidian::toProtocol() && + _dim->getBlock({_bottomLeftCorner.x, _bottomLeftCorner.y + countHeight, _bottomLeftCorner.z}) == Blocks::Obsidian::toProtocol() && + countHeight > (PortalBoundary::PORTAL_MIN_HEIGHT - PortalBoundary::PORTAL_NO_CORNERS)) { + _size.z = countHeight - 1; + } + } + } else if (_direction == PortalDirection::PORTAL_Z_AXIS) { + for (int countWidth = 1; countWidth < (PortalBoundary::PORTAL_MAX_WIDTH - PortalBoundary::PORTAL_NO_CORNERS); countWidth++) { + if (_dim->getBlock({_bottomLeftCorner.x, _bottomLeftCorner.y, _bottomLeftCorner.z + (countWidth - 1)}) == Blocks::Obsidian::toProtocol() && + _dim->getBlock({_bottomLeftCorner.x, _bottomLeftCorner.y + 1, _bottomLeftCorner.z + countWidth}) == Blocks::Obsidian::toProtocol() && + countWidth >= (PortalBoundary::PORTAL_MIN_WIDTH - PortalBoundary::PORTAL_NO_CORNERS)) { + _size.x = countWidth - 1; + } + } + for (int countHeight = 1; countHeight < (PortalBoundary::PORTAL_MAX_HEIGHT - PortalBoundary::PORTAL_NO_CORNERS); countHeight++) { + if (_dim->getBlock({_bottomLeftCorner.x, _bottomLeftCorner.y + (countHeight - 1), _bottomLeftCorner.z - 1}) == Blocks::Obsidian::toProtocol() && + _dim->getBlock({_bottomLeftCorner.x, _bottomLeftCorner.y + countHeight, _bottomLeftCorner.z}) == Blocks::Obsidian::toProtocol() && + countHeight > (PortalBoundary::PORTAL_MIN_HEIGHT - PortalBoundary::PORTAL_NO_CORNERS)) { + _size.z = countHeight - 1; + } + } + } else + _size = {PortalError::PORTAL_BAD_PORTAL, _direction}; + + _size = {PortalError::PORTAL_BAD_PORTAL, PortalError::PORTAL_WRONG_SIZE}; } -void NetherPortal::buildPortal(Position pos) +void NetherPortal::openPortal() { - auto frame = getFrame(pos); std::vector> blocksArray; - auto block = _dim->getBlock(pos); - for (int y = 0; y < FRAME_HEIGHT - 1; y++) { - for (int x = 0; x < FRAME_WIDTH - 1; x++) { - if (frame.direction == POSITIVE_POS && frame.axis == AXIS_X) { - block = _dim->getBlock({pos.x - 1 + x, pos.y + y, pos.z}); - if (block == Blocks::Air::toProtocol() || - block == - Blocks::Fire::toProtocol( - Blocks::Fire::Properties::Age::ZERO, Blocks::Fire::Properties::East::FALSE, Blocks::Fire::Properties::North::FALSE, - Blocks::Fire::Properties::South::FALSE, Blocks::Fire::Properties::Up::FALSE, Blocks::Fire::Properties::West::FALSE - )) { - blocksArray.push_back({{pos.x - 1 + x, pos.y + y, pos.z}, Blocks::NetherPortal::toProtocol(Blocks::NetherPortal::Properties::Axis::X)}); - } - } else if (frame.direction == POSITIVE_POS && frame.axis == AXIS_Z) { - block = _dim->getBlock({pos.x, pos.y + y, pos.z - 1 + x}); - if (block == Blocks::Air::toProtocol() || - block == - Blocks::Fire::toProtocol( - Blocks::Fire::Properties::Age::ZERO, Blocks::Fire::Properties::East::FALSE, Blocks::Fire::Properties::North::FALSE, - Blocks::Fire::Properties::South::FALSE, Blocks::Fire::Properties::Up::FALSE, Blocks::Fire::Properties::West::FALSE - )) { - blocksArray.push_back({{pos.x, pos.y + y, pos.z - 1 + x}, Blocks::NetherPortal::toProtocol(Blocks::NetherPortal::Properties::Axis::Z)}); - } - } else if (frame.direction == NEGATIVE_POS && frame.axis == AXIS_X) { - block = _dim->getBlock({pos.x - 2 + x, pos.y + y, pos.z}); - if (block == Blocks::Air::toProtocol() || - block == - Blocks::Fire::toProtocol( - Blocks::Fire::Properties::Age::ZERO, Blocks::Fire::Properties::East::FALSE, Blocks::Fire::Properties::North::FALSE, - Blocks::Fire::Properties::South::FALSE, Blocks::Fire::Properties::Up::FALSE, Blocks::Fire::Properties::West::FALSE - )) { - blocksArray.push_back({{pos.x - 2 + x, pos.y + y, pos.z}, Blocks::NetherPortal::toProtocol(Blocks::NetherPortal::Properties::Axis::X)}); - } - } else if (frame.direction == NEGATIVE_POS && frame.axis == AXIS_Z) { - block = _dim->getBlock({pos.x, pos.y + y, pos.z - 2 + x}); - if (block == Blocks::Air::toProtocol() || - block == - Blocks::Fire::toProtocol( - Blocks::Fire::Properties::Age::ZERO, Blocks::Fire::Properties::East::FALSE, Blocks::Fire::Properties::North::FALSE, - Blocks::Fire::Properties::South::FALSE, Blocks::Fire::Properties::Up::FALSE, Blocks::Fire::Properties::West::FALSE - )) { - blocksArray.push_back({{pos.x, pos.y + y, pos.z - 2 + x}, Blocks::NetherPortal::toProtocol(Blocks::NetherPortal::Properties::Axis::Z)}); + + if (_ignitedBlock == PortalIgnition::PORTAL_NONE) + return; + + if (_direction == PortalDirection::PORTAL_X_AXIS) { + for (int x = 0; x <= _size.x; x++) { + for (int y = 1; y <= _size.z; y++) { + auto position = {_bottomLeftCorner.x + x, _bottomLeftCorner.y + y, _bottomLeftCorner.z}; + auto blockId = _dim->getBlock(position); + blocksArray.push_back({position, blockId}); + } + } + for (auto [position, id] : blocksArray) { + if (id != Blocks::Air::toProtocol() && + id != + Blocks::Fire::toProtocol( + Blocks::Fire::Properties::Age::ZERO, Blocks::Fire::Properties::East::FALSE, Blocks::Fire::Properties::North::FALSE, Blocks::Fire::Properties::South::FALSE, + Blocks::Fire::Properties::Up::FALSE, Blocks::Fire::Properties::West::FALSE + )) { + LDEBUG("Obstruction within the frame at position {}: PORTAL_BAD_PORTAL ({})", position, PortalError::PORTAL_BAD_PORTAL); + return; + } else { + _dim->updateBlock(position, Blocks::NetherPortal::toProtocol(Blocks::NetherPortal::Properties::Axis::X)); + for (auto player : _dim->getPlayers()) { + player->sendBlockUpdate({position, Blocks::NetherPortal::toProtocol(Blocks::NetherPortal::Properties::Axis::X}); } } } - } - for (auto [position, id] : blocksArray) { - _dim->updateBlock(position, id); - for (auto player : _dim->getPlayers()) { - player->sendBlockUpdate({pos, _dim->getBlock(pos)}); - player->sendBlockUpdate({position, id}); - // player->sendUpdateSectionBlock({position,chunk, true, blocksArray}); + } else if (_direction == PortalDirection::PORTAL_Z_AXIS) { + for (int z = 0; z <= _size.x; z++) { + for (int y = 1; y <= _size.z; y++) { + auto position = {_bottomLeftCorner.x, _bottomLeftCorner.y + y, _bottomLeftCorner.z + z}; + auto blockId = _dim->getBlock(position); + blocksArray.push_back({position, blockId}); + } + } + for (auto [position, id] : blocksArray) { + if (id != Blocks::Air::toProtocol() && + id != + Blocks::Fire::toProtocol( + Blocks::Fire::Properties::Age::ZERO, Blocks::Fire::Properties::East::FALSE, Blocks::Fire::Properties::North::FALSE, Blocks::Fire::Properties::South::FALSE, + Blocks::Fire::Properties::Up::FALSE, Blocks::Fire::Properties::West::FALSE + )) { + LDEBUG("Obstruction within the frame at position {}: PORTAL_BAD_PORTAL ({})", position, PortalError::PORTAL_BAD_PORTAL); + return; + } else { + _dim->updateBlock(position, Blocks::NetherPortal::toProtocol(Blocks::NetherPortal::Properties::Axis::Z)); + for (auto player : _dim->getPlayers()) { + player->sendBlockUpdate({position, Blocks::NetherPortal::toProtocol(Blocks::NetherPortal::Properties::Axis::Z}); + } + } } + } else { + LDEBUG("No portal at pos {}: PORTAL_NONE ({})", _pos, PortalError::PORTAL_NONE); + return; } } diff --git a/cubic-server/generation/player_constructions/NetherPortal.hpp b/cubic-server/generation/player_constructions/NetherPortal.hpp index 11007aedd..d72d7d1e5 100644 --- a/cubic-server/generation/player_constructions/NetherPortal.hpp +++ b/cubic-server/generation/player_constructions/NetherPortal.hpp @@ -3,24 +3,57 @@ #include "blocks.hpp" #include "generation/generator.hpp" +#include "math/Vector2.hpp" #include "types.hpp" #include "world_storage/ChunkColumn.hpp" #include +#include -#define AXIS_UNDEFINED -1 -#define AXIS_X 0 -#define AXIS_Z 1 -#define UNDEFINED_POS -1 -#define NEGATIVE_POS 0 -#define POSITIVE_POS 1 +/* Error codes */ +enum class PortalError { + PORTAL_OUT_OF_BOUNDARIES = -1, + PORTAL_WRONG_DIRECTION = -2, + PORTAL_WRONG_SIZE = -3, + PORTAL_WRONG_BLOCK = -4, + PORTAL_BAD_PORTAL = -42, + PORTAL_NONE = -84 +}; + +/* The minimum & maximum sizes of the portal */ +enum class PortalBoundary { + PORTAL_MIN_WIDTH = 4, + PORTAL_MIN_HEIGHT = 5, + PORTAL_MAX_WIDTH = 23, + PORTAL_MAX_HEIGHT = 23, + PORTAL_OUT_OF_BOUNDARIES = static_cast(PortalError::PORTAL_OUT_OF_BOUNDARIES) +}; -#define FRAME_WIDTH 4 -#define FRAME_HEIGHT 5 +/* The 2 dimensions defining the portal */ +enum class PortalSize { + PORTAL_WIDTH, + PORTAL_HEIGHT, + PORTAL_WRONG_SIZE = static_cast(PortalError::PORTAL_WRONG_SIZE) +}; -struct Frame { - int axis; - int direction; +/* The horizontal direction of the portal (on the X or Z axis) */ +enum class PortalDirection { + PORTAL_X_AXIS, + PORTAL_Z_AXIS, + PORTAL_WRONG_DIRECTION = static_cast(PortalError::PORTAL_WRONG_DIRECTION) +}; + +/* The location of ignition of the portal (see schema on PR) */ +enum class PortalIgnition { + PORTAL_TOP_CENTER, + PORTAL_LEFT_CENTER, + PORTAL_RIGHT_CENTER, + PORTAL_BOTTOM_CENTER, + PORTAL_TOP_RIGHT_CORNER, + PORTAL_TOP_LEFT_CORNER, + PORTAL_BOTTOM_RIGHT_CORNER, + PORTAL_BOTTOM_LEFT_CORNER, + PORTAL_NONE = static_cast(PortalError::PORTAL_NONE) }; /** @@ -40,41 +73,56 @@ struct Frame { */ class NetherPortal { public: - NetherPortal(std::shared_ptr dim): - _dim(dim) + NetherPortal(std::shared_ptr dim, Position pos): + _dim(dim), + _pos(pos) { + setIgnitedBlock(); + setBottomLeftCorner(); + setDirection(); + setSize(); } /** - * @brief Get the axis on which the frame is built (x or z) + * @brief Sets _ignitedBlock to (TOP_CENTER, LEFT_CENTER, RIGHT_CENTER, BOTTOM_CENTER, TOP_RIGHT_CORNER, TOP_LEFT_CORNER, BOTTOM_RIGHT_CORNER, BOTTOM_LEFT_CORNER, NONE) + * depending on which side of the alleged frame the ignited block is located * - * @param pos The position of the frame - * @return Frame The axis and direction of the frame */ - Frame getFrame(Position pos); + void setIgnitedBlock(); /** - * @brief Build the portal within the already built frame + * @brief Sets _bottomLeftCorner to the position of the leftmost obsidian block on the bottom side of the portal, from the inner part of the portal + * (the corner block, if obsidian, isn't taken into account) * - * @param pos The position of the frame */ - void buildPortal(Position pos); + void setBottomLeftCorner(); /** - * @brief Checks every layer of the alleged frame + * @brief Sets _direction to the horizontal direction of the portal, meaning if the portal is positionned on the X or Z axis * - * @param pos The position of the bottom-left corner of the frame - * @param axis The axis of the frame (x or z) - * @return true There is a frame - * @return false There isn't a frame */ - bool checkLayers(Position pos, int axis); + void setDirection(); -private: /** - * The dimension where the portal is in + * @brief Sets _size to the two dimentional sizes of the portal (atm, only works when lighting a bottom block) + * */ - std::shared_ptr _dim; + void setSize(); + + /** + * @brief Open the portal within the frame + * + * @param pos The position of the fire block created by the Flint&Steel + */ + void openPortal(); + +private: + std::shared_ptr _dim; /**< The dimension where the portal is in */ + Position _pos; /**< The position of the fire block created by the Flint&Steel */ + PortalIgnition _ignitedBlock; /**< The side of the alleged frame the ignited block is located */ + Position _bottomLeftCorner; /**< The position of the bottom-left block under the inner frame (used for calculations) */ + PortalDirection _direction; /**< The horizontal direction of the portal (X or Z) */ + Vector2 _size; /**< The size of the inner part of the portal {PORTAL_WIDTH, PORTAL_HEIGHT} */ }; #endif // CUBICSERVER_GENERATION_PLAYER_CONSTRUCTIONS_NETHER_PORTAL_HPP diff --git a/cubic-server/items/usable-items/FlintAndSteel.cpp b/cubic-server/items/usable-items/FlintAndSteel.cpp index 525295dfa..1f8eda34c 100644 --- a/cubic-server/items/usable-items/FlintAndSteel.cpp +++ b/cubic-server/items/usable-items/FlintAndSteel.cpp @@ -23,7 +23,7 @@ nbt_tag_t *Items::FlintAndSteel::setNbtTag() void Items::FlintAndSteel::onUseOn(std::shared_ptr dim, Position &pos, UNUSED UsabilityType usage, UNUSED int32_t face, UNUSED Entity &user) { - auto portal = NetherPortal(dim); + auto portal = NetherPortal(dim, pos); dim->updateBlock( pos, Blocks::Fire::toProtocol( @@ -40,5 +40,5 @@ void Items::FlintAndSteel::onUseOn(std::shared_ptr dim, Position &pos )} ); } - portal.buildPortal({pos.x, pos.y - 1, pos.z}); + portal.openPortal(); }