Terraform2: Clear and Water tools (#1081)

* Implement terraform clear area tool update

* Implement terraform water update

* Implement missing function, fix compile issue

* Fix rebase issues
This commit is contained in:
Duncan 2021-08-05 18:52:39 +01:00 committed by GitHub
parent b756c2e440
commit da39ecf082
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 117 additions and 60 deletions

View File

@ -1076,7 +1076,7 @@ namespace OpenLoco::GameCommands
}
// Clear Land
inline void do_66(Map::Pos2 centre, Map::Pos2 pointA, Map::Pos2 pointB, uint8_t flags)
inline uint32_t do_66(Map::Pos2 centre, Map::Pos2 pointA, Map::Pos2 pointB, uint8_t flags)
{
registers regs;
regs.ax = centre.x;
@ -1084,7 +1084,7 @@ namespace OpenLoco::GameCommands
regs.edx = pointB.x << 16 | pointA.x;
regs.ebp = pointB.y << 16 | pointA.y;
regs.bl = flags;
doCommand(GameCommand::clearLand, regs);
return doCommand(GameCommand::clearLand, regs);
}
// Load multiplayer map

View File

@ -342,17 +342,10 @@ namespace OpenLoco::Map::TileManager
}
// TODO: Return std::optional
uint16_t setMapSelectionTiles(int16_t x, int16_t y)
uint16_t setMapSelectionTiles(const Map::Pos2& loc, const uint8_t selectionType)
{
auto res = Ui::ViewportInteraction::getSurfaceLocFromUi({ x, y });
if (!res)
{
return 0x8000;
}
uint16_t xPos = res->first.x;
uint16_t yPos = res->first.y;
uint16_t xPos = loc.x;
uint16_t yPos = loc.y;
uint8_t count = 0;
if (!Input::hasMapSelectionFlag(Input::MapSelectionFlags::enable))
@ -361,9 +354,9 @@ namespace OpenLoco::Map::TileManager
count++;
}
if (_word_F2448E != 4)
if (_word_F2448E != selectionType)
{
_word_F2448E = 4;
_word_F2448E = selectionType;
count++;
}
@ -414,17 +407,11 @@ namespace OpenLoco::Map::TileManager
return count;
}
uint16_t setMapSelectionSingleTile(int16_t x, int16_t y, bool setQuadrant)
uint16_t setMapSelectionSingleTile(const Map::Pos2& loc, bool setQuadrant)
{
auto res = Ui::ViewportInteraction::getSurfaceLocFromUi({ x, y });
if (!res)
{
return 0x8000;
}
uint16_t xPos = res->first.x & 0xFFE0;
uint16_t yPos = res->first.y & 0xFFE0;
uint16_t cursorQuadrant = Ui::ViewportInteraction::getQuadrantOrCentreFromPos(res->first);
uint16_t xPos = loc.x & 0xFFE0;
uint16_t yPos = loc.y & 0xFFE0;
uint16_t cursorQuadrant = Ui::ViewportInteraction::getQuadrantOrCentreFromPos(loc);
auto count = 0;
if (!Input::hasMapSelectionFlag(Input::MapSelectionFlags::enable))

View File

@ -20,8 +20,8 @@ namespace OpenLoco::Map::TileManager
TileHeight getHeight(const Pos2& pos);
void updateTilePointers();
void reorganise();
uint16_t setMapSelectionTiles(int16_t x, int16_t y);
uint16_t setMapSelectionSingleTile(int16_t x, int16_t y, bool setQuadrant = false);
uint16_t setMapSelectionTiles(const Map::Pos2& loc, const uint8_t selectionType);
uint16_t setMapSelectionSingleTile(const Map::Pos2& loc, bool setQuadrant = false);
void mapInvalidateSelectionRect();
void mapInvalidateTileFull(Map::Pos2 pos);
void mapInvalidateMapSelectionTiles();

View File

@ -1102,12 +1102,27 @@ namespace OpenLoco::Ui::Windows::Terraform
// 0x004BC677
static void onToolUpdate(Window& self, const WidgetIndex_t widgetIndex, const int16_t x, const int16_t y)
{
registers regs;
regs.esi = X86Pointer(&self);
regs.dx = widgetIndex;
regs.ax = x;
regs.bx = y;
call(0x004BC677, regs);
Map::TileManager::mapInvalidateSelectionRect();
Input::resetMapSelectionFlag(Input::MapSelectionFlags::enable);
uint32_t cost = 0x80000000;
auto res = Ui::ViewportInteraction::getSurfaceLocFromUi({ x, y });
if (res)
{
if (Map::TileManager::setMapSelectionTiles(res->first, 4) == 0)
{
return;
}
const auto [pointA, pointB] = Map::TileManager::getMapSelectionArea();
const Pos2 centre = (pointA + pointB) / 2;
cost = GameCommands::do_66(centre, pointA, pointB, GameCommands::Flags::flag_2 | GameCommands::Flags::flag_6);
}
if (cost != _raiseLandCost)
{
_raiseLandCost = cost;
WindowManager::invalidate(WindowType::terraform);
}
}
static void clearLand(uint8_t flags)
@ -1423,25 +1438,27 @@ namespace OpenLoco::Ui::Windows::Terraform
if (Ui::getToolCursor() != CursorId::upDownArrow)
{
Input::resetMapSelectionFlag(Input::MapSelectionFlags::enable);
if (_adjustLandToolSize != 1)
auto res = Ui::ViewportInteraction::getSurfaceLocFromUi({ x, y });
if (res)
{
auto count = TileManager::setMapSelectionTiles(x, y);
if (_adjustLandToolSize != 1)
{
auto count = TileManager::setMapSelectionTiles(res->first, 4);
if (count == 0x8000)
xPos = 0x8000;
if (!count)
return;
}
else
{
auto count = TileManager::setMapSelectionSingleTile(res->first, true);
if (!count)
return;
if (!count)
return;
}
}
else
{
auto count = TileManager::setMapSelectionSingleTile(x, y, true);
if (count == 0x8000)
xPos = 0x8000;
if (!count)
return;
xPos = 0x8000;
}
}
else
@ -1694,26 +1711,72 @@ namespace OpenLoco::Ui::Windows::Terraform
}
}
static void setAdjustCost(uint32_t raiseCost, uint32_t lowerCost)
{
if (_raiseWaterCost == raiseCost)
{
if (_lowerWaterCost == lowerCost)
return;
}
_raiseWaterCost = raiseCost;
_lowerWaterCost = lowerCost;
WindowManager::invalidate(WindowType::terraform);
}
// 0x004BCDB4
static void onToolUpdate(Window& self, const WidgetIndex_t widgetIndex, const int16_t x, const int16_t y)
{
registers regs;
regs.esi = X86Pointer(&self);
regs.dx = widgetIndex;
regs.ax = x;
regs.bx = y;
call(0x004BCDB4, regs);
if (widgetIndex != Common::widx::panel)
return;
TileManager::mapInvalidateSelectionRect();
if (Ui::getToolCursor() != CursorId::upDownArrow)
{
Input::resetMapSelectionFlag(Input::MapSelectionFlags::enable);
auto res = ViewportInteraction::getMapCoordinatesFromPos(x, y, ~(ViewportInteraction::InteractionItemFlags::surface | ViewportInteraction::InteractionItemFlags::water));
auto& interaction = res.first;
if (interaction.type == ViewportInteraction::InteractionItem::noInteraction)
{
setAdjustCost(0x80000000, 0x80000000);
return;
}
if (!TileManager::setMapSelectionTiles(interaction.pos + Map::Pos2(16, 16), 5))
{
//no change in selection
return;
}
}
else
{
if (!Input::hasMapSelectionFlag(Input::MapSelectionFlags::enable))
return;
}
if (isEditorMode())
{
setAdjustCost(0x80000000, 0x80000000);
}
else
{
auto [pointA, pointB] = Map::TileManager::getMapSelectionArea();
auto lowerCost = GameCommands::do_29(pointA, pointB, 0);
auto raiseCost = GameCommands::do_28(pointA, pointB, 0);
setAdjustCost(raiseCost, lowerCost);
}
}
// 0x004BCDCA
static void onToolDown(Window& self, const WidgetIndex_t widgetIndex, const int16_t x, const int16_t y)
{
registers regs;
regs.esi = X86Pointer(&self);
regs.dx = widgetIndex;
regs.ax = x;
regs.bx = y;
call(0x004BCDCA, regs);
if (widgetIndex != Common::widx::panel)
return;
if (!Input::hasMapSelectionFlag(Input::MapSelectionFlags::enable))
return;
Ui::setToolCursor(CursorId::upDownArrow);
}
static void raiseWater(uint8_t flags)
@ -2543,8 +2606,11 @@ namespace OpenLoco::Ui::Windows::Terraform
// 0x004A69DD
static void sub_4A69DD()
{
registers regs;
call(0x004A69DD, regs);
auto* window = WindowManager::find(WindowType::construction);
if (window != nullptr)
{
Ui::Windows::Construction::sub_49FEC7();
}
}
static void initEvents()

View File

@ -463,7 +463,11 @@ namespace OpenLoco::Ui::Windows::TileInspector
TileManager::mapInvalidateSelectionRect();
Input::resetMapSelectionFlag(Input::MapSelectionFlags::enable);
TileManager::setMapSelectionSingleTile(x, y);
auto res = Ui::ViewportInteraction::getSurfaceLocFromUi({ x, y });
if (res)
{
TileManager::setMapSelectionSingleTile(res->first);
}
}
static void onToolDown(Window& self, const WidgetIndex_t widgetIndex, const int16_t x, const int16_t y)