#include "BuildModeController.h" #include #include #include "BlueprintModeExitedEvent.h" #include "BuilderModeExitedEvent.h" #include "DeconstructModeChangedEvent.h" #include "EventManager.h" namespace { Rotation rotateClockwise(Rotation rotation) { switch (rotation) { case Rotation::North: return Rotation::East; case Rotation::East: return Rotation::South; case Rotation::South: return Rotation::West; case Rotation::West: return Rotation::North; } return Rotation::East; } Rotation rotateCounterClockwise(Rotation rotation) { switch (rotation) { case Rotation::North: return Rotation::West; case Rotation::East: return Rotation::North; case Rotation::South: return Rotation::East; case Rotation::West: return Rotation::South; } return Rotation::East; } } // namespace BuildMode BuildModeController::getMode() const { return m_mode; } bool BuildModeController::isBuilderMode() const { return m_mode == BuildMode::Builder; } bool BuildModeController::isBlueprintMode() const { return m_mode == BuildMode::Blueprint; } bool BuildModeController::isDeconstructMode() const { return m_mode == BuildMode::Deconstruct; } void BuildModeController::enterMode(BuildMode mode) { if (m_mode == mode) { return; } // Leave the current mode properly, so its widget hears about it however the // player left. Each exit clears only its own state. switch (m_mode) { case BuildMode::Builder: m_draggingBelt = false; m_beltDragPath.clear(); EventManager::getInstance()->sendEventImmediately( std::make_shared()); break; case BuildMode::Blueprint: m_hoveredGhostIsTransfer = false; EventManager::getInstance()->sendEventImmediately( std::make_shared()); break; case BuildMode::Deconstruct: m_deconstructHoverBuildingId.reset(); EventManager::getInstance()->sendEventImmediately( std::make_shared(false)); break; case BuildMode::None: break; } m_mode = mode; if (mode == BuildMode::Deconstruct) { EventManager::getInstance()->sendEventImmediately( std::make_shared(true)); } } void BuildModeController::enterBuilderMode(BuildingType type) { enterMode(BuildMode::Builder); m_builderType = type; m_ghostRotation = Rotation::East; m_ghostValid = false; m_tunnelGhostType = BuildingType::TunnelEntry; m_tunnelPartnerTile.reset(); } void BuildModeController::enterBlueprintMode(Blueprint blueprint) { enterMode(BuildMode::Blueprint); // The layout starts where the builder ghost last was, so switching from a // building to a blueprint does not jump the preview across the world. m_blueprintGhostTile = m_ghostTile; m_blueprint = std::move(blueprint); } void BuildModeController::toggleDeconstructMode() { enterMode(isDeconstructMode() ? BuildMode::None : BuildMode::Deconstruct); } void BuildModeController::exitBuilderMode() { if (!isBuilderMode()) { return; } enterMode(BuildMode::None); } void BuildModeController::exitBlueprintMode() { if (!isBlueprintMode()) { return; } enterMode(BuildMode::None); } void BuildModeController::exitCurrentMode() { enterMode(BuildMode::None); } BuildingType BuildModeController::getBuilderType() const { return m_builderType; } bool BuildModeController::isTunnelMode() const { return isBuilderMode() && m_builderType == BuildingType::TunnelEntry; } BuildingType BuildModeController::getEffectiveBuilderType() const { return isTunnelMode() ? m_tunnelGhostType : m_builderType; } QPoint BuildModeController::getGhostTile() const { return m_ghostTile; } Rotation BuildModeController::getGhostRotation() const { return m_ghostRotation; } bool BuildModeController::isGhostValid() const { return m_ghostValid; } void BuildModeController::setGhostTile(QPoint tile) { m_ghostTile = tile; } void BuildModeController::setGhostValidity(bool valid) { m_ghostValid = valid; } void BuildModeController::rotateGhost(bool clockwise) { m_ghostRotation = clockwise ? rotateClockwise(m_ghostRotation) : rotateCounterClockwise(m_ghostRotation); } BuildingType BuildModeController::getTunnelGhostType() const { return m_tunnelGhostType; } const std::optional& BuildModeController::getTunnelPartnerTile() const { return m_tunnelPartnerTile; } void BuildModeController::setTunnelGhost(BuildingType resolvedType, std::optional partnerTile) { m_tunnelGhostType = resolvedType; m_tunnelPartnerTile = std::move(partnerTile); } bool BuildModeController::isDraggingBelt() const { return m_draggingBelt; } QPoint BuildModeController::getBeltDragAnchor() const { return m_beltDragAnchor; } const std::vector& BuildModeController::getBeltDragPath() const { return m_beltDragPath; } void BuildModeController::beginBeltDrag(QPoint anchorTile) { m_draggingBelt = true; m_beltDragAnchor = anchorTile; } void BuildModeController::setBeltDragPath(std::vector path) { m_beltDragPath = std::move(path); } void BuildModeController::cancelBeltDrag() { m_draggingBelt = false; m_beltDragPath.clear(); } const Blueprint& BuildModeController::getBlueprint() const { return m_blueprint; } Blueprint& BuildModeController::getMutableBlueprint() { return m_blueprint; } QPoint BuildModeController::getBlueprintGhostTile() const { return m_blueprintGhostTile; } void BuildModeController::setBlueprintGhostTile(QPoint tile) { m_blueprintGhostTile = tile; } bool BuildModeController::isHoveredGhostTransfer() const { return m_hoveredGhostIsTransfer; } void BuildModeController::setHoveredGhostTransfer(bool transfer) { m_hoveredGhostIsTransfer = transfer; } const std::optional& BuildModeController::getDeconstructHoverBuildingId() const { return m_deconstructHoverBuildingId; } void BuildModeController::setDeconstructHoverBuildingId(std::optional id) { m_deconstructHoverBuildingId = std::move(id); }