From ab0e38612f0185a6523dca5fe6c612ad620d1280 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hannes=20J=C3=A4mtner?= <hanja189@student.liu.se>
Date: Thu, 23 Jul 2020 12:24:54 +0200
Subject: [PATCH] Fixed bugs in Building placer

---
 src/BuildingPlacer.cpp | 56 ++++++++++++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 16 deletions(-)

diff --git a/src/BuildingPlacer.cpp b/src/BuildingPlacer.cpp
index a4840f076..e5d85337f 100644
--- a/src/BuildingPlacer.cpp
+++ b/src/BuildingPlacer.cpp
@@ -27,10 +27,15 @@ bool BuildingPlacer::canBuildHere(int bx, int by, const UnitType & type) const
         return false;
     }
 
+	int width = type.tileWidth();
+	int height = type.tileHeight();
+	int xdelta = (int)std::ceil((width - 1.0) / 2);
+	int ydelta = (int)std::ceil((height - 1.0) / 2);
+
     // check the reserve map
-    for (int x = bx; x < bx + type.tileWidth(); x++)
+    for (int x = bx - xdelta; x < bx + width - xdelta; x++)
     {
-        for (int y = by; y < by + type.tileHeight(); y++)
+        for (int y = by - ydelta; y < by + height - ydelta; y++)
         {
             if (!m_bot.Map().isValidTile(x, y) || m_reserveMap[x][y])
             {
@@ -60,23 +65,31 @@ bool BuildingPlacer::canBuildHereWithSpace(int bx, int by, const UnitType & type
     // height and width of the building
     int width  = type.tileWidth();
     int height = type.tileHeight();
+	int xdelta = (int)std::ceil((width - 1.0) / 2);
+	int ydelta = (int)std::ceil((height - 1.0) / 2);
 
     // TODO: make sure we leave space for add-ons. These types of units can have addons:
 
     // define the rectangle of the building spot
-    int startx = bx - buildDist;
-    int starty = by - buildDist;
-    int endx   = bx + width + buildDist - 1;
-    int endy   = by + height + buildDist - 1;
+    int startx = bx - buildDist - xdelta;
+    int starty = by - buildDist - ydelta;
+    int endx   = bx + width + buildDist - xdelta;
+    int endy   = by + height + buildDist - ydelta;
 
     // TODO: recalculate start and end positions for addons
 
     // if this rectangle doesn't fit on the map we can't build here
-    if (startx < 0 || starty < 0 || endx > m_bot.Map().width() || endx < bx + width - 1 || endy > m_bot.Map().height() - 1)
+    if (startx < 0 || starty < 0 || endx > m_bot.Map().width() || endx < bx + width - xdelta || endy > m_bot.Map().height() || endy < bx + height - ydelta)
     {
         return false;
     }
 
+	if (!m_bot.Map().canBuildTypeAtPosition(bx, by, type))
+	{
+		return false;
+	}
+
+
     // if we can't build here, or space is reserved, or it's in the resource box, we can't build here
     for (int x = startx; x < endx; x++)
     {
@@ -137,10 +150,14 @@ bool BuildingPlacer::tileOverlapsBaseLocation(int x, int y, UnitType type) const
     }
 
     // dimensions of the proposed location
-    int tx1 = x;
-    int ty1 = y;
-    int tx2 = tx1 + type.tileWidth();
-    int ty2 = ty1 + type.tileHeight();
+
+	int xdelta = (int)std::ceil((type.tileWidth() - 1.0) / 2);
+	int ydelta = (int)std::ceil((type.tileHeight() - 1.0) / 2);
+
+    int tx1 = x - xdelta;
+    int ty1 = y - ydelta;
+    int tx2 = tx1 + type.tileWidth() - xdelta;
+    int ty2 = ty1 + type.tileHeight() - ydelta;
 
     // for each base location
     for (const BaseLocation * base : m_bot.Bases().getBaseLocations())
@@ -168,7 +185,7 @@ bool BuildingPlacer::tileOverlapsBaseLocation(int x, int y, UnitType type) const
 bool BuildingPlacer::buildable(const UnitType & type, int x, int y) const
 {
     // TODO: does this take units on the map into account?
-    if (!m_bot.Map().isValidTile(x, y) || !m_bot.Map().canBuildTypeAtPosition(x, y, type))
+    if (!m_bot.Map().isValidTile(x, y))
     {
         return false;
     }
@@ -182,9 +199,13 @@ void BuildingPlacer::reserveTiles(int bx, int by, int width, int height)
 {
     int rwidth = (int)m_reserveMap.size();
     int rheight = (int)m_reserveMap[0].size();
-    for (int x = bx; x < bx + width && x < rwidth; x++)
+
+	int xdelta = (int)std::ceil((width - 1.0) / 2);
+	int ydelta = (int)std::ceil((height - 1.0) / 2);
+
+    for (int x = bx - xdelta; x < bx + width - xdelta && x < rwidth; x++)
     {
-        for (int y = by; y < by + height && y < rheight; y++)
+        for (int y = by - ydelta; y < by + height - ydelta && y < rheight; y++)
         {
             m_reserveMap[x][y] = true;
         }
@@ -215,9 +236,12 @@ void BuildingPlacer::freeTiles(int bx, int by, int width, int height)
     int rwidth = (int)m_reserveMap.size();
     int rheight = (int)m_reserveMap[0].size();
 
-    for (int x = bx; x < bx + width && x < rwidth; x++)
+	int xdelta = (int)std::ceil((width - 1.0) / 2);
+	int ydelta = (int)std::ceil((height - 1.0) / 2);
+
+    for (int x = bx - xdelta; x < bx + width - xdelta && x < rwidth; x++)
     {
-        for (int y = by; y < by + height && y < rheight; y++)
+        for (int y = by - ydelta; y < by + height - ydelta && y < rheight; y++)
         {
             m_reserveMap[x][y] = false;
         }
-- 
GitLab