extract BuildModeController, fixing a silent blueprint exit
This commit is contained in:
261
src/lib/core/BuildModeController.cpp
Normal file
261
src/lib/core/BuildModeController.cpp
Normal file
@@ -0,0 +1,261 @@
|
||||
#include "BuildModeController.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#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<BuilderModeExitedEvent>());
|
||||
break;
|
||||
case BuildMode::Blueprint:
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<BlueprintModeExitedEvent>());
|
||||
break;
|
||||
case BuildMode::Deconstruct:
|
||||
m_deconstructHoverBuildingId.reset();
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<DeconstructModeChangedEvent>(false));
|
||||
break;
|
||||
case BuildMode::None:
|
||||
break;
|
||||
}
|
||||
|
||||
m_mode = mode;
|
||||
|
||||
if (mode == BuildMode::Deconstruct)
|
||||
{
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<DeconstructModeChangedEvent>(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<QPoint>& BuildModeController::getTunnelPartnerTile() const
|
||||
{
|
||||
return m_tunnelPartnerTile;
|
||||
}
|
||||
|
||||
void BuildModeController::setTunnelGhost(BuildingType resolvedType,
|
||||
std::optional<QPoint> 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<BeltPathTile>& BuildModeController::getBeltDragPath() const
|
||||
{
|
||||
return m_beltDragPath;
|
||||
}
|
||||
|
||||
void BuildModeController::beginBeltDrag(QPoint anchorTile)
|
||||
{
|
||||
m_draggingBelt = true;
|
||||
m_beltDragAnchor = anchorTile;
|
||||
}
|
||||
|
||||
void BuildModeController::setBeltDragPath(std::vector<BeltPathTile> 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;
|
||||
}
|
||||
|
||||
const std::optional<BuildingId>&
|
||||
BuildModeController::getDeconstructHoverBuildingId() const
|
||||
{
|
||||
return m_deconstructHoverBuildingId;
|
||||
}
|
||||
|
||||
void BuildModeController::setDeconstructHoverBuildingId(std::optional<BuildingId> id)
|
||||
{
|
||||
m_deconstructHoverBuildingId = std::move(id);
|
||||
}
|
||||
Reference in New Issue
Block a user