From 15770672613b85c54aac229da433d9c6e4b5e900 Mon Sep 17 00:00:00 2001 From: Joris <Joris.dauphin@gmail.com> Date: Thu, 11 Nov 2010 16:54:28 +0100 Subject: [PATCH] Still some use of Vec2i --- src/action/action_attack.cpp | 7 +- src/action/action_build.cpp | 7 +- src/action/action_still.cpp | 2 +- src/action/action_upgradeto.cpp | 4 +- src/action/command.cpp | 11 ++- src/ai/ai_building.cpp | 23 ++--- src/ai/ai_plan.cpp | 106 +++++++++-------------- src/editor/editloop.cpp | 6 +- src/editor/edmap.cpp | 31 +++---- src/include/map.h | 106 ++++++++++------------- src/map/map.cpp | 148 +++++++++++++------------------- src/map/map_fog.cpp | 118 ++++++++++++------------- src/map/map_wall.cpp | 81 ++++++++--------- src/map/script_map.cpp | 22 ++--- src/pathfinder/pathfinder.cpp | 5 +- src/stratagus/missile.cpp | 18 ++-- src/stratagus/player.cpp | 2 +- src/stratagus/spells.cpp | 42 ++++----- src/ui/mouse.cpp | 33 ++----- src/unit/build.cpp | 12 ++- src/unit/script_unit.cpp | 33 +++---- src/unit/unit.cpp | 40 +++++---- src/unit/unit_cache.cpp | 93 +++++++++----------- src/video/cursor.cpp | 2 +- 24 files changed, 408 insertions(+), 544 deletions(-) diff --git a/src/action/action_attack.cpp b/src/action/action_attack.cpp index 80034663a..42c847c02 100644 --- a/src/action/action_attack.cpp +++ b/src/action/action_attack.cpp @@ -151,7 +151,7 @@ static int CheckForTargetInRange(CUnit &unit) // if (!order->HasGoal() && order->Action != UnitActionAttackGround && - !Map.WallOnMap(order->goalPos.x, order->goalPos.y)) { + !Map.WallOnMap(order->goalPos)) { CUnit *goal = AttackUnitsInReactRange(unit); if (goal) { #ifdef DEBUG @@ -243,7 +243,7 @@ static void MoveToTarget(CUnit &unit) // // Attacking wall or ground. // - if (!goal && (Map.WallOnMap(order->goalPos.x, order->goalPos.y) || + if (!goal && (Map.WallOnMap(order->goalPos) || order->Action == UnitActionAttackGround) && unit.MapDistanceTo(order->goalPos.x, order->goalPos.y) <= unit.Stats->Variables[ATTACKRANGE_INDEX].Max) { @@ -301,8 +301,7 @@ static void AttackTarget(CUnit &unit) // Goal is "weak" or a wall. // COrderPtr order = unit.CurrentOrder(); - if (!order->HasGoal() && (order->Action == UnitActionAttackGround || - Map.WallOnMap(order->goalPos.x, order->goalPos.y))) { + if (!order->HasGoal() && (order->Action == UnitActionAttackGround || Map.WallOnMap(order->goalPos))) { return; } diff --git a/src/action/action_build.cpp b/src/action/action_build.cpp index e82e71844..1fbc61dd8 100644 --- a/src/action/action_build.cpp +++ b/src/action/action_build.cpp @@ -182,7 +182,7 @@ static CUnit *CheckCanBuild(CUnit &unit) * ebabled/disable via game lua scripting */ if ((ontop = - AlreadyBuildingFinder(unit, type).Find(Map.Field(pos.x, pos.y)) + AlreadyBuildingFinder(unit, type).Find(Map.Field(pos)) ) != NULL) { DebugPrint("%d: Worker [%d] is helping build: %s [%d]\n" _C_ unit.Player->Index _C_ unit.Slot @@ -571,9 +571,8 @@ void HandleActionBuilt(CUnit &unit) // FIXME: Vladi: this is just a hack to test wall fixing, // FIXME: also not sure if the right place... // FIXME: Johns: hardcoded unit-type wall / more races! - if (unit.Type == UnitTypeOrcWall || - unit.Type == UnitTypeHumanWall) { - Map.SetWall(unit.tilePos.x, unit.tilePos.y, unit.Type == UnitTypeHumanWall); + if (unit.Type == UnitTypeOrcWall || unit.Type == UnitTypeHumanWall) { + Map.SetWall(unit.tilePos, unit.Type == UnitTypeHumanWall); unit.Remove(NULL); UnitLost(unit); UnitClearOrders(unit); diff --git a/src/action/action_still.cpp b/src/action/action_still.cpp index bb880b28d..d4b5f150d 100644 --- a/src/action/action_still.cpp +++ b/src/action/action_still.cpp @@ -165,7 +165,7 @@ static bool MoveRandomly(CUnit &unit) // move if possible if (pos != unit.tilePos) { UnmarkUnitFieldFlags(unit); - if (UnitCanBeAt(unit, pos.x, pos.y)) { + if (UnitCanBeAt(unit, pos)) { COrderPtr order = unit.CurrentOrder(); // FIXME: Don't use pathfinder for this, costs too much cpu. order->Action = UnitActionMove; diff --git a/src/action/action_upgradeto.cpp b/src/action/action_upgradeto.cpp index 2b3757eaf..2aa8b8257 100644 --- a/src/action/action_upgradeto.cpp +++ b/src/action/action_upgradeto.cpp @@ -68,7 +68,7 @@ int TransformUnitIntoType(CUnit &unit, CUnitType *newtype) if (oldtype == newtype) { // nothing to do return 1; } - Vec2i pos = unit.tilePos + oldtype->GetHalfTileSize() - newtype->GetHalfTileSize(); + const Vec2i pos = unit.tilePos + oldtype->GetHalfTileSize() - newtype->GetHalfTileSize(); CUnit *container = unit.Container; if (container) { @@ -76,7 +76,7 @@ int TransformUnitIntoType(CUnit &unit, CUnitType *newtype) } else { SaveSelection(); unit.Remove(NULL); - if (!UnitTypeCanBeAt(newtype, pos.x, pos.y)) { + if (!UnitTypeCanBeAt(newtype, pos)) { unit.Place(unit.tilePos.x, unit.tilePos.y); RestoreSelection(); // FIXME unit is not modified, try later ? diff --git a/src/action/command.cpp b/src/action/command.cpp index 1466a67da..aeca6f79a 100644 --- a/src/action/command.cpp +++ b/src/action/command.cpp @@ -386,8 +386,9 @@ void CommandAutoRepair(CUnit &unit, int on) void CommandAttack(CUnit &unit, int x, int y, CUnit *attack, int flush) { COrderPtr order; + const Vec2i pos = {x, y}; - Assert(Map.Info.IsPointOnMap(x, y)); + Assert(Map.Info.IsPointOnMap(pos)); // // Check if unit is still valid? (NETWORK!) @@ -417,15 +418,13 @@ void CommandAttack(CUnit &unit, int x, int y, CUnit *attack, int flush) order->Range = unit.Stats->Variables[ATTACKRANGE_INDEX].Max; order->MinRange = unit.Type->MinAttackRange; } - } else if (Map.WallOnMap(x,y)) { + } else if (Map.WallOnMap(pos)) { // FIXME: look into action_attack.c about this ugly problem - order->goalPos.x = x; - order->goalPos.y = y; + order->goalPos = pos; order->Range = unit.Stats->Variables[ATTACKRANGE_INDEX].Max; order->MinRange = unit.Type->MinAttackRange; } else { - order->goalPos.x = x; - order->goalPos.y = y; + order->goalPos = pos; } } ClearSavedAction(unit); diff --git a/src/ai/ai_building.cpp b/src/ai/ai_building.cpp index 66d7606ab..7a124825e 100644 --- a/src/ai/ai_building.cpp +++ b/src/ai/ai_building.cpp @@ -239,7 +239,7 @@ static int AiFindBuildingPlace2(const CUnit &worker, const CUnitType *type, } } - if (CanMoveToMask(pos.x, pos.y, mask)) { // reachable + if (CanMoveToMask(pos, mask)) { // reachable *m = 1; points[wp] = pos; // push the point if (++wp >= size) { // round about @@ -353,10 +353,6 @@ static int AiFindHallPlace(const CUnit &worker, if ((mine = ResourceOnMap(pos.x, pos.y, resource))) { int buildings; int j; - int minx; - int maxx; - int miny; - int maxy; int nunits; CUnit *units[UnitMax]; @@ -365,12 +361,11 @@ static int AiFindHallPlace(const CUnit &worker, // // Check units around mine // - minx = mine->tilePos.x - 5; - miny = mine->tilePos.y - 5; - maxx = mine->tilePos.x + mine->Type->TileWidth + 5; - maxy = mine->tilePos.y + mine->Type->TileHeight + 5; - Map.FixSelectionArea(minx, miny, maxx, maxy); - nunits = Map.SelectFixed(minx, miny, maxx, maxy, units); + Vec2i minpos = {mine->tilePos.x - 5, mine->tilePos.y - 5}; + Vec2i maxpos = {mine->tilePos.x + mine->Type->TileWidth + 5, + mine->tilePos.y + mine->Type->TileHeight + 5}; + Map.FixSelectionArea(minpos, maxpos); + nunits = Map.SelectFixed(minpos, maxpos, units); for (j = 0; j < nunits; ++j) { // Enemy near mine if (AiPlayer->Player->Enemy & @@ -400,7 +395,7 @@ static int AiFindHallPlace(const CUnit &worker, } } - if (CanMoveToMask(pos.x, pos.y, mask)) { // reachable + if (CanMoveToMask(pos, mask)) { // reachable *m = 1; points[wp] = pos; // push the point if (++wp >= size) { // round about @@ -503,7 +498,7 @@ static int AiFindLumberMillPlace(const CUnit &worker, const CUnitType *type, } } - if (CanMoveToMask(pos.x, pos.y, mask)) { // reachable + if (CanMoveToMask(pos, mask)) { // reachable *m = 1; points[wp] = pos; // push the point if (++wp >= size) { // round about @@ -597,7 +592,7 @@ static int AiFindMiningPlace(const CUnit &worker, return 1; } - if (CanMoveToMask(pos.x, pos.y, mask)) { // reachable + if (CanMoveToMask(pos, mask)) { // reachable *m = 1; points[wp] = pos; // push the point if (++wp >= size) { // round about diff --git a/src/ai/ai_plan.cpp b/src/ai/ai_plan.cpp index fc826a9cf..809f24d9b 100644 --- a/src/ai/ai_plan.cpp +++ b/src/ai/ai_plan.cpp @@ -101,7 +101,7 @@ struct _EnemyOnMapTile { static CUnit *EnemyOnMapTile(const CUnit &source, const Vec2i& pos) { _EnemyOnMapTile filter(source, pos); - Map.Field(pos.x, pos.y)->UnitCache.for_each(filter); + Map.Field(pos)->UnitCache.for_each(filter); return filter.best; } @@ -115,17 +115,11 @@ static CUnit *EnemyOnMapTile(const CUnit &source, const Vec2i& pos) */ static void AiMarkWaterTransporter(const CUnit &unit, unsigned char *matrix) { - static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 }; - static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 }; - struct p { - unsigned short X; - unsigned short Y; - } *points; + const Vec2i offset[] = {{0, -1}, {-1, 0}, {1, 0}, {0, 1}, {-1, -1}, {1, -1}, {-1, 1}, {1, 1}}; + Vec2i *points; int size; - int x; - int y; - int rx; - int ry; + Vec2i pos; + Vec2i rpos; int mask; int wp; int rp; @@ -134,17 +128,16 @@ static void AiMarkWaterTransporter(const CUnit &unit, unsigned char *matrix) int w; unsigned char *m; - x = unit.tilePos.x; - y = unit.tilePos.y; + pos = unit.tilePos; w = Map.Info.MapWidth + 2; matrix += w + w + 2; - if (matrix[x + y * w]) { // already marked + if (matrix[pos.x + pos.y * w]) { // already marked DebugPrint("Done\n"); return; } size = Map.Info.MapWidth * Map.Info.MapHeight / 4; - points = new p[size]; + points = new Vec2i[size]; // // Make movement matrix. @@ -153,10 +146,9 @@ static void AiMarkWaterTransporter(const CUnit &unit, unsigned char *matrix) // Ignore all possible mobile units. mask &= ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit); - points[0].X = x; - points[0].Y = y; + points[0] = pos; rp = 0; - matrix[x + y * w] = 66; // mark start point + matrix[pos.x + pos.y * w] = 66; // mark start point ep = wp = 1; // start with one point // @@ -164,20 +156,17 @@ static void AiMarkWaterTransporter(const CUnit &unit, unsigned char *matrix) // for (;;) { while (rp != ep) { - rx = points[rp].X; - ry = points[rp].Y; + rpos = points[rp]; for (i = 0; i < 8; ++i) { // mark all neighbors - x = rx + xoffset[i]; - y = ry + yoffset[i]; - m = matrix + x + y * w; + pos = rpos + offset[i]; + m = matrix + pos.x + pos.y * w; if (*m) { // already checked continue; } - if (CanMoveToMask(x, y, mask)) { // reachable + if (CanMoveToMask(pos, mask)) { // reachable *m = 66; - points[wp].X = x; // push the point - points[wp].Y = y; + points[wp] = pos; // push the point if (++wp >= size) { // round about wp = 0; } @@ -292,7 +281,7 @@ static bool AiFindTarget(const CUnit &unit, return 1; } - if (CanMoveToMask(pos.x, pos.y, mask)) { // reachable + if (CanMoveToMask(pos, mask)) { // reachable *m = 1; points[wp].pos = pos; // push the point @@ -315,7 +304,7 @@ static bool AiFindTarget(const CUnit &unit, } continue; } - if (CanMoveToMask(pos.x, pos.y, mask)) { // reachable + if (CanMoveToMask(pos, mask)) { // reachable DebugPrint("->Land\n"); *m = 1; points[wp].pos = pos; // push the point @@ -355,17 +344,11 @@ static bool AiFindTarget(const CUnit &unit, */ int AiFindWall(AiForce *force) { - static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 }; - static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 }; - struct p { - unsigned short X; - unsigned short Y; - } *points; + const Vec2i offset[] = {{0, -1}, {-1, 1}, {1, 0}, {0, 1}, {-1, -1}, {1, -1}, {-1, 1}, {1, 1}}; + Vec2i *points; int size; - int x; - int y; - int rx; - int ry; + Vec2i pos; + Vec2i rpos; int mask; int wp; int rp; @@ -373,8 +356,7 @@ int AiFindWall(AiForce *force) int w; unsigned char *m; unsigned char *matrix; - int destx; - int desty; + Vec2i dest = {-1, -1}; CUnit *unit; // Find a unit to use. Best choice is a land unit with range 1. @@ -390,22 +372,17 @@ int AiFindWall(AiForce *force) } } - x = unit->tilePos.x; - y = unit->tilePos.y; + pos = unit->tilePos; size = Map.Info.MapWidth * Map.Info.MapHeight / 4; - points = new p[size]; - - destx = -1; - desty = -1; + points = new Vec2i[size]; matrix = CreateMatrix(); w = Map.Info.MapWidth + 2; matrix += w + w + 2; - points[0].X = x; - points[0].Y = y; + points[0] = pos; rp = 0; - matrix[x + y * w] = 1; // mark start point + matrix[pos.x + pos.y * w] = 1; // mark start point ep = wp = 1; // start with one point mask = unit->Type->MovementMask; @@ -413,31 +390,27 @@ int AiFindWall(AiForce *force) // // Pop a point from stack, push all neighbors which could be entered. // - for (; destx == -1;) { - while (rp != ep && destx == -1) { - rx = points[rp].X; - ry = points[rp].Y; + for (; dest.x == -1;) { + while (rp != ep && dest.x == -1) { + rpos = points[rp]; for (int i = 0; i < 8; ++i) { // mark all neighbors - x = rx + xoffset[i]; - y = ry + yoffset[i]; - m = matrix + x + y * w; + pos = rpos + offset[i]; + m = matrix + pos.x + pos.y * w; if (*m) { continue; } // // Check for a wall // - if (Map.WallOnMap(x, y)) { - DebugPrint("Wall found %d,%d\n" _C_ x _C_ y); - destx = x; - desty = y; + if (Map.WallOnMap(pos)) { + DebugPrint("Wall found %d,%d\n" _C_ pos.x _C_ pos.y); + dest = pos; break; } - if (CanMoveToMask(x, y, mask)) { // reachable + if (CanMoveToMask(pos, mask)) { // reachable *m = 1; - points[wp].X = x; // push the point - points[wp].Y = y; + points[wp] = pos; // push the point if (++wp >= size) { // round about wp = 0; } @@ -460,19 +433,18 @@ int AiFindWall(AiForce *force) } delete[] points; - if (destx != -1) { + if (dest.x != -1) { force->State = AI_FORCE_STATE_WAITING; for (unsigned int i = 0; i < force->Units.size(); ++i) { CUnit &aiunit = *force->Units[i]; if (aiunit.Type->CanAttack) { - CommandAttack(aiunit, destx, desty, NULL, FlushCommands); + CommandAttack(aiunit, dest.x, dest.y, NULL, FlushCommands); } else { - CommandMove(aiunit, destx, desty, FlushCommands); + CommandMove(aiunit, dest.x, dest.y, FlushCommands); } } return 1; } - return 0; } diff --git a/src/editor/editloop.cpp b/src/editor/editloop.cpp index d2429d436..00adde3ad 100644 --- a/src/editor/editloop.cpp +++ b/src/editor/editloop.cpp @@ -342,12 +342,13 @@ void EditTiles(int x, int y, int tile, int size) */ static void EditorActionPlaceUnit(int x, int y, CUnitType *type, CPlayer *player) { + const Vec2i pos = {x, y}; if (type->Neutral) { player = &Players[PlayerNumNeutral]; } // FIXME: vladi: should check place when mirror editing is enabled...? - CUnit *unit = MakeUnitAndPlace(x, y, type, player); + CUnit *unit = MakeUnitAndPlace(pos.x, pos.y, type, player); if (unit == NoUnitP) { DebugPrint("Unable to allocate Unit"); return; @@ -355,11 +356,10 @@ static void EditorActionPlaceUnit(int x, int y, CUnitType *type, CPlayer *player CBuildRestrictionOnTop *b = OnTopDetails(*unit, NULL); if (b && b->ReplaceOnBuild) { - int n; CUnit *table[UnitMax]; //FIXME: rb: use tile functor find here. - n = Map.Select(x, y, table); + int n = Map.Select(pos, table); while (n--) { if (table[n]->Type == b->Parent) { unit->ResourcesHeld = table[n]->ResourcesHeld; // We capture the value of what is beneath. diff --git a/src/editor/edmap.cpp b/src/editor/edmap.cpp index 04fd8727d..b998913f6 100644 --- a/src/editor/edmap.cpp +++ b/src/editor/edmap.cpp @@ -471,13 +471,14 @@ static void EditorChangeTile(int x, int y, int tile, int d) */ static void EditorTileChanged2(int x, int y, int d) { + const Vec2i pos = {x, y}; unsigned quad; unsigned q2; unsigned u; int tile; CMapField *mf; - quad = QuadFromTile(x, y); + quad = QuadFromTile(pos.x, pos.y); // // Change the surrounding @@ -486,9 +487,9 @@ static void EditorTileChanged2(int x, int y, int d) // // Special case 1) Walls. // - mf = Map.Field(x, y); + mf = Map.Field(pos); if (mf->Flags & MapFieldWall) { - Map.SetWall(x, y, mf->Flags & MapFieldHuman); + Map.SetWall(pos, mf->Flags & MapFieldHuman); return; } @@ -498,48 +499,48 @@ static void EditorTileChanged2(int x, int y, int d) // check if the margin matches. otherwise, call // EditorChangeTile again. // - if (d & DIR_UP && y) { + if (d & DIR_UP && pos.y) { // // Insert into the bottom the new tile. // - q2 = QuadFromTile(x, y - 1); + q2 = QuadFromTile(pos.x, pos.y - 1); u = (q2 & TH_QUAD_M) | ((quad >> 16) & BH_QUAD_M); if (u != q2) { tile = TileFromQuad(u & BH_QUAD_M, u); - EditorChangeTile(x, y - 1, tile, d&~DIR_DOWN); + EditorChangeTile(pos.x, pos.y - 1, tile, d & ~DIR_DOWN); } } - if (d & DIR_DOWN && y < Map.Info.MapHeight - 1) { + if (d & DIR_DOWN && pos.y < Map.Info.MapHeight - 1) { // // Insert into the top the new tile. // - q2 = QuadFromTile(x, y + 1); + q2 = QuadFromTile(pos.x, pos.y + 1); u = (q2 & BH_QUAD_M) | ((quad << 16) & TH_QUAD_M); if (u != q2) { tile = TileFromQuad(u & TH_QUAD_M, u); - EditorChangeTile(x, y + 1, tile, d&~DIR_UP); + EditorChangeTile(pos.x, pos.y + 1, tile, d & ~DIR_UP); } } - if (d & DIR_LEFT && x) { + if (d & DIR_LEFT && pos.x) { // // Insert into the left the new tile. // - q2 = QuadFromTile(x - 1, y); + q2 = QuadFromTile(pos.x - 1, pos.y); u = (q2 & LH_QUAD_M) | ((quad >> 8) & RH_QUAD_M); if (u != q2) { tile = TileFromQuad(u & RH_QUAD_M, u); - EditorChangeTile(x - 1, y, tile, d&~DIR_RIGHT); + EditorChangeTile(pos.x - 1, pos.y, tile, d & ~DIR_RIGHT); } } - if (d & DIR_RIGHT && x < Map.Info.MapWidth - 1) { + if (d & DIR_RIGHT && pos.x < Map.Info.MapWidth - 1) { // // Insert into the right the new tile. // - q2 = QuadFromTile(x + 1, y); + q2 = QuadFromTile(pos.x + 1, pos.y); u = (q2 & RH_QUAD_M) | ((quad << 8) & LH_QUAD_M); if (u != q2) { tile = TileFromQuad(u & LH_QUAD_M, u); - EditorChangeTile(x + 1, y, tile, d&~DIR_LEFT); + EditorChangeTile(pos.x + 1, pos.y, tile, d & ~DIR_LEFT); } } } diff --git a/src/include/map.h b/src/include/map.h index 4324f444c..d3f83330b 100644 --- a/src/include/map.h +++ b/src/include/map.h @@ -195,11 +195,11 @@ public: /// Alocate and initialise map table. void Create(); /// Build tables for map - void Init(void); + void Init(); /// Clean the map void Clean(); /// Cleanup memory for fog of war tables - void CleanFogOfWar(void); + void CleanFogOfWar(); /// Remove wood/rock from the map. void ClearTile(unsigned short type, const Vec2i &pos); @@ -319,18 +319,18 @@ public: // Wall // /// Wall is hit. - void HitWall(unsigned x, unsigned y, unsigned damage); + void HitWall(const Vec2i &pos, unsigned damage); /// Set wall on field. - void RemoveWall(unsigned x, unsigned y); + void RemoveWall(const Vec2i &pos); /// Set wall on field. - void SetWall(unsigned x, unsigned y, int humanwall); + void SetWall(const Vec2i &pos, int humanwall); /// Returns true, if wall on the map tile field - bool WallOnMap(int x, int y) const; + bool WallOnMap(const Vec2i &pos) const; /// Returns true, if human wall on the map tile field - bool HumanWallOnMap(int x, int y) const; + bool HumanWallOnMap(const Vec2i &pos) const; /// Returns true, if orc wall on the map tile field - bool OrcWallOnMap(int x, int y) const; + bool OrcWallOnMap(const Vec2i &pos) const; // @@ -418,50 +418,40 @@ public: //UnitCache /// Insert new unit into cache - void Insert(CUnit *unit); + void Insert(CUnit &unit); /// Remove unit from cache - void Remove(CUnit *unit); + void Remove(CUnit &unit); //Warning: we expect typical usage as xmin = x - range - void FixSelectionArea(int &xmin, int &ymin, int &xmax, int &ymax) + void FixSelectionArea(Vec2i &minpos, Vec2i &maxpos) { - if (xmin < 0) { - xmin = 0; - } - if (xmax > Info.MapWidth - 1) { - xmax = Info.MapWidth - 1; - } - if (ymin < 0) { - ymin = 0; - } - if (ymax > Info.MapHeight - 1) { - ymax = Info.MapHeight - 1; - } + minpos.x = std::max<short>(0, minpos.x); + minpos.y = std::max<short>(0, minpos.y); + + maxpos.x = std::min<short>(maxpos.x, Info.MapWidth - 1); + maxpos.y = std::min<short>(maxpos.y, Info.MapHeight - 1); } /// Select units in rectange range int Select(int x1, int y1, int x2, int y2, CUnit *table[], const int tablesize = UnitMax); - int SelectFixed(int x1, int y1, int x2, int y2, CUnit*table[], + int SelectFixed(const Vec2i <pos, const Vec2i &rbpos, CUnit*table[], const int tablesize = UnitMax); // Select units on map tile. - helper funtion. don't use directly - int Select(int x, int y, CUnit *table[], - const int tablesize = UnitMax); + int Select(const Vec2i &pos, CUnit *table[], const int tablesize = UnitMax); private: /// Build tables for fog of war - void InitFogOfWar(void); + void InitFogOfWar(); - /// Check if the seen tile-type is wood - bool IsSeenTile(unsigned short type, int x, int y) const; /// Correct the surrounding seen wood fields - void FixNeighbors(unsigned short type, int seen, int x, int y); + void FixNeighbors(unsigned short type, int seen, const Vec2i &pos); /// Correct the seen wood field, depending on the surrounding - void FixTile(unsigned short type, int seen, int x, int y); + void FixTile(unsigned short type, int seen, const Vec2i &pos); public: CMapField *Fields; /// fields on map @@ -509,13 +499,13 @@ extern int ReplayRevealMap; // /// Function to (un)mark the vision table. #ifndef MARKER_ON_INDEX -typedef void MapMarkerFunc(const CPlayer *player, int x, int y); +typedef void MapMarkerFunc(const CPlayer *player, const Vec2i &pos); #else typedef void MapMarkerFunc(const CPlayer *player, const unsigned int index); #endif /// Filter map flags through fog -extern int MapFogFilterFlags(CPlayer *player, int x, int y, int mask); +extern int MapFogFilterFlags(CPlayer *player, const Vec2i &pos, int mask); /// Mark a tile for normal sight extern MapMarkerFunc MapMarkTileSight; /// Unmark a tile for normal sight @@ -528,57 +518,48 @@ extern MapMarkerFunc MapUnmarkTileDetectCloak; /// Mark sight changes extern void MapSight(const CPlayer *player, int x, int y, int w, int h, int range, MapMarkerFunc *marker); - /// Mark tiles with fog of war to be redrawn -extern void MapUpdateFogOfWar(int x, int y); /// Update fog of war -extern void UpdateFogOfWarChange(void); +extern void UpdateFogOfWarChange(); /// Builds Vision and Goal Tables -extern void InitVisionTable(void); +extern void InitVisionTable(); /// Cleans up Vision and Goal Tables -extern void FreeVisionTable(void); +extern void FreeVisionTable(); // // in map_radar.c // - /// Check if a tile is visible on radar -extern unsigned char -IsTileRadarVisible(const CPlayer *pradar, const CPlayer *punit, int x, int y); /// Mark a tile as radar visible, or incrase radar vision -extern void MapMarkTileRadar(const CPlayer *player, int x, int y); -extern void -MapMarkTileRadar(const CPlayer *player, const unsigned int index); +extern MapMarkerFunc MapMarkTileRadar; + /// Unmark a tile as radar visible, decrease is visible by other radar -extern void MapUnmarkTileRadar(const CPlayer *player, int x, int y); -extern void -MapUnmarkTileRadar(const CPlayer *player, const unsigned int index); +extern MapMarkerFunc MapUnmarkTileRadar; + /// Mark a tile as radar jammed, or incrase radar jamming'ness -extern void MapMarkTileRadarJammer(const CPlayer *player, int x, int y); -extern void -MapMarkTileRadarJammer(const CPlayer *player, const unsigned int index); +extern MapMarkerFunc MapMarkTileRadarJammer; + /// Unmark a tile as jammed, decrease is jamming'ness -extern void MapUnmarkTileRadarJammer(const CPlayer *player, int x, int y); -extern void -MapUnmarkTileRadarJammer(const CPlayer *player, const unsigned int index); +extern MapMarkerFunc MapUnmarkTileRadarJammer; + // // in map_wall.c // /// Correct the seen wall field, depending on the surrounding -extern void MapFixSeenWallTile(int x, int y); +extern void MapFixSeenWallTile(const Vec2i &pos); /// Correct the surrounding seen wall fields -extern void MapFixSeenWallNeighbors(int x, int y); +extern void MapFixSeenWallNeighbors(const Vec2i &pos); /// Correct the real wall field, depending on the surrounding -extern void MapFixWallTile(int x, int y); +extern void MapFixWallTile(const Vec2i &pos); // // in script_map.c // /// Set a tile -extern void SetTile(int tile, int w, int h, int value = 0); +extern void SetTile(int tile, int x, int y, int value = 0); /// register ccl features -extern void MapCclRegister(void); +extern void MapCclRegister(); // // mixed sources @@ -595,12 +576,12 @@ extern void FreeMapInfo(CMapInfo *info); /// Returns true, if the unit-type(mask can enter field with bounds check extern bool CheckedCanMoveToMask(const Vec2i &pos, int mask); /// Returns true, if the unit-type can enter the field -extern bool UnitTypeCanBeAt(const CUnitType *type, int x, int y); +extern bool UnitTypeCanBeAt(const CUnitType *type, const Vec2i &pos); /// Returns true, if the unit can enter the field -extern bool UnitCanBeAt(const CUnit &unit, int x, int y); +extern bool UnitCanBeAt(const CUnit &unit, const Vec2i &pos); /// Preprocess map, for internal use. -extern void PreprocessMap(void); +extern void PreprocessMap(); // in unit.c @@ -614,8 +595,7 @@ void MapUnmarkUnitSight(CUnit &unit); ----------------------------------------------------------------------------*/ /// Can a unit with 'mask' enter the field -inline bool CanMoveToMask(int x, int y, int mask) { - const Vec2i pos = {x, y}; +inline bool CanMoveToMask(const Vec2i &pos, int mask) { return !Map.CheckMask(pos, mask); } diff --git a/src/map/map.cpp b/src/map/map.cpp index d883158b2..ab339fe27 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -73,15 +73,14 @@ char CurrentMapPath[1024]; /// Path of the current map */ void CMap::MarkSeenTile(const unsigned int index) { - int tile; - int seentile; - CMapField *mf; + CMapField *mf = this->Field(index); + int tile = mf->Tile; + int seentile = mf->SeenTile; - mf = this->Field(index); // // Nothing changed? Seeing already the correct tile. // - if ((tile = mf->Tile) == (seentile = mf->SeenTile)) { + if (tile == seentile) { return; } mf->SeenTile = tile; @@ -90,6 +89,7 @@ void CMap::MarkSeenTile(const unsigned int index) //rb - GRRRRRRRRRRRR int y = index / Info.MapWidth; int x = index - (y * Info.MapWidth); + const Vec2i pos = {x, y} #endif if (this->Tileset.TileTypeTable) { @@ -97,42 +97,39 @@ void CMap::MarkSeenTile(const unsigned int index) //rb - GRRRRRRRRRRRR int y = index / Info.MapWidth; int x = index - (y * Info.MapWidth); + const Vec2i pos = {x, y}; #endif // Handle wood changes. FIXME: check if for growing wood correct? - if (seentile != this->Tileset.RemovedTree && - tile == this->Tileset.RemovedTree) { - FixNeighbors(MapFieldForest, 1, x, y); - } else if (seentile == this->Tileset.RemovedTree && - tile != this->Tileset.RemovedTree) { - FixTile(MapFieldForest, 1, x, y); + if (seentile != this->Tileset.RemovedTree && tile == this->Tileset.RemovedTree) { + FixNeighbors(MapFieldForest, 1, pos); + } else if (seentile == this->Tileset.RemovedTree && tile != this->Tileset.RemovedTree) { + FixTile(MapFieldForest, 1, pos); } else if (ForestOnMap(index)) { - FixTile(MapFieldForest, 1, x, y); - FixNeighbors(MapFieldForest, 1, x, y); + FixTile(MapFieldForest, 1, pos); + FixNeighbors(MapFieldForest, 1, pos); // Handle rock changes. - } else if (seentile != this->Tileset.RemovedRock && - tile == Map.Tileset.RemovedRock) { - FixNeighbors(MapFieldRocks, 1, x, y); - } else if (seentile == this->Tileset.RemovedRock && - tile != Map.Tileset.RemovedRock) { - FixTile(MapFieldRocks, 1, x, y); + } else if (seentile != this->Tileset.RemovedRock && tile == Map.Tileset.RemovedRock) { + FixNeighbors(MapFieldRocks, 1, pos); + } else if (seentile == this->Tileset.RemovedRock && tile != Map.Tileset.RemovedRock) { + FixTile(MapFieldRocks, 1, pos); } else if (RockOnMap(index)) { - FixTile(MapFieldRocks, 1, x, y); - FixNeighbors(MapFieldRocks, 1, x, y); + FixTile(MapFieldRocks, 1, pos); + FixNeighbors(MapFieldRocks, 1, pos); // Handle Walls changes. } else if (this->Tileset.TileTypeTable[tile] == TileTypeHumanWall || this->Tileset.TileTypeTable[tile] == TileTypeOrcWall || this->Tileset.TileTypeTable[seentile] == TileTypeHumanWall || this->Tileset.TileTypeTable[seentile] == TileTypeOrcWall) { - MapFixSeenWallTile(x, y); - MapFixSeenWallNeighbors(x, y); + MapFixSeenWallTile(pos); + MapFixSeenWallNeighbors(pos); } } #ifdef MINIMAP_UPDATE - UI.Minimap.UpdateXY(x, y); + UI.Minimap.UpdateXY(pos.x, pos.y); #endif } @@ -184,46 +181,41 @@ void CMap::Reveal() /** ** Wall on map tile. ** -** @param tx X map tile position. -** @param ty Y map tile position. +** @param pos map tile position. ** ** @return True if wall, false otherwise. */ -bool CMap::WallOnMap(int tx, int ty) const +bool CMap::WallOnMap(const Vec2i &pos) const { - Assert(Map.Info.IsPointOnMap(tx, ty)); - return (Fields[tx + ty * Info.MapWidth].Flags & MapFieldWall) != 0; + Assert(Map.Info.IsPointOnMap(pos)); + return (Field(pos)->Flags & MapFieldWall) != 0; } /** ** Human wall on map tile. ** -** @param tx X map tile position. -** @param ty Y map tile position. +** @param pos map tile position. ** ** @return True if human wall, false otherwise. */ -bool CMap::HumanWallOnMap(int tx, int ty) const +bool CMap::HumanWallOnMap(const Vec2i &pos) const { - Assert(Map.Info.IsPointOnMap(tx, ty)); - return (Fields[tx + ty * Info.MapWidth].Flags & - (MapFieldWall | MapFieldHuman)) == (MapFieldWall | MapFieldHuman); + Assert(Map.Info.IsPointOnMap(pos)); + return (Field(pos)->Flags & (MapFieldWall | MapFieldHuman)) == (MapFieldWall | MapFieldHuman); } /** ** Orc wall on map tile. ** -** @param tx X map tile position. -** @param ty Y map tile position. +** @param pos map tile position. ** ** @return True if orcish wall, false otherwise. */ -bool CMap::OrcWallOnMap(int tx, int ty) const +bool CMap::OrcWallOnMap(const Vec2i &pos) const { - Assert(Map.Info.IsPointOnMap(tx, ty)); - return (Fields[tx + ty * Info.MapWidth].Flags & - (MapFieldWall | MapFieldHuman)) == MapFieldWall; + Assert(Map.Info.IsPointOnMap(pos)); + return (Field(pos)->Flags & (MapFieldWall | MapFieldHuman)) == MapFieldWall; } /** @@ -243,12 +235,11 @@ bool CheckedCanMoveToMask(const Vec2i &pos, int mask) ** Can a unit of unit-type be placed at this point. ** ** @param type unit-type to be checked. -** @param x X map tile position. -** @param y Y map tile position. +** @param pos map tile position. ** ** @return True if could be entered, false otherwise. */ -bool UnitTypeCanBeAt(const CUnitType *type, int x, int y) +bool UnitTypeCanBeAt(const CUnitType *type, const Vec2i &pos) { int addx; // iterator int addy; // iterator @@ -256,11 +247,11 @@ bool UnitTypeCanBeAt(const CUnitType *type, int x, int y) Assert(type); mask = type->MovementMask; - unsigned int index = y * Map.Info.MapWidth; + unsigned int index = pos.y * Map.Info.MapWidth; for (addy = 0; addy < type->TileHeight; ++addy) { for (addx = 0; addx < type->TileWidth; ++addx) { - if (!(Map.Info.IsPointOnMap(x + addx, y + addy) && - !Map.CheckMask(x + addx + index, mask))) { + if (!(Map.Info.IsPointOnMap(pos.x + addx, pos.y + addy) && + !Map.CheckMask(pos.x + addx + index, mask))) { return false; } } @@ -273,14 +264,13 @@ bool UnitTypeCanBeAt(const CUnitType *type, int x, int y) ** Can a unit be placed to this point. ** ** @param unit unit to be checked. -** @param x X map tile position. -** @param y Y map tile position. +** @param pos map tile position. ** ** @return True if could be placeded, false otherwise. */ -bool UnitCanBeAt(const CUnit &unit, int x, int y) +bool UnitCanBeAt(const CUnit &unit, const Vec2i &pos) { - return UnitTypeCanBeAt(unit.Type, x, y); + return UnitTypeCanBeAt(unit.Type, pos); } /** @@ -288,13 +278,11 @@ bool UnitCanBeAt(const CUnit &unit, int x, int y) */ void PreprocessMap() { - int ix; - int iy; CMapField *mf; #ifdef _MSC_VER - for (ix = 0; ix < Map.Info.MapWidth; ++ix) { - for (iy = 0; iy < Map.Info.MapHeight; ++iy) { + for (int ix = 0; ix < Map.Info.MapWidth; ++ix) { + for (int iy = 0; iy < Map.Info.MapHeight; ++iy) { mf = Map.Field(ix, iy); mf->SeenTile = mf->Tile; } @@ -320,10 +308,11 @@ void PreprocessMap() // it is required for fixing the wood that all tiles are marked as seen! if (Map.Tileset.TileTypeTable) { - for (ix = 0; ix < Map.Info.MapWidth; ++ix) { - for (iy = 0; iy < Map.Info.MapHeight; ++iy) { - MapFixWallTile(ix, iy); - MapFixSeenWallTile(ix, iy); + Vec2i pos; + for (pos.x = 0; pos.x < Map.Info.MapWidth; ++pos.x) { + for (pos.y = 0; pos.y < Map.Info.MapHeight; ++pos.y) { + MapFixWallTile(pos); + MapFixSeenWallTile(pos); } } } @@ -387,29 +376,15 @@ void CMap::Clean(void) -- Map Tile Update Functions ----------------------------------------------------------------------------*/ -/** -** Check if the seen tile-type is wood or rock. -** -** @param type Tile type -** @param x Map X tile-position. -** @param y Map Y tile-position. -*/ -bool CMap::IsSeenTile(unsigned short type, int x, int y) const -{ - return this->Tileset.IsSeenTile(type, Map.Field(x,y)->SeenTile); -} - /** ** Correct the seen wood field, depending on the surrounding. ** ** @param type type fo tile to update ** @param seen 1 if updating seen value, 0 for real -** @param x Map X tile-position. -** @param y Map Y tile-position. +** @param pos Map tile-position. */ -void CMap::FixTile(unsigned short type, int seen, int x, int y) +void CMap::FixTile(unsigned short type, int seen, const Vec2i &pos) { - const Vec2i pos = {x, y}; int tile; int ttup; int ttdown; @@ -537,7 +512,7 @@ void CMap::FixTile(unsigned short type, int seen, int x, int y) if (tile == -1) { // No valid wood remove it. if (seen) { mf->SeenTile = removedtile; - this->FixNeighbors(type, seen, pos.x, pos.y); + this->FixNeighbors(type, seen, pos); } else { mf->Tile = removedtile; mf->Flags &= ~flags; @@ -569,19 +544,16 @@ void CMap::FixTile(unsigned short type, int seen, int x, int y) ** ** @param type Tiletype of tile to adjust ** @param seen 1 if updating seen value, 0 for real -** @param x Map X tile-position. -** @param y Map Y tile-position. +** @param pos Map tile-position. */ -void CMap::FixNeighbors(unsigned short type, int seen, int x, int y) +void CMap::FixNeighbors(unsigned short type, int seen, const Vec2i &pos) { - FixTile(type, seen, x + 1, y); // side neighbors - FixTile(type, seen, x - 1, y); - FixTile(type, seen, x, y + 1); - FixTile(type, seen, x, y - 1); - FixTile(type, seen, x + 1, y - 1); // side neighbors - FixTile(type, seen, x - 1, y - 1); - FixTile(type, seen, x - 1, y + 1); - FixTile(type, seen, x + 1, y + 1); + const Vec2i offset[] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}}; + + for (unsigned int i = 0; i < sizeof (offset) / sizeof (*offset); ++i) + { + FixTile(type, seen, pos + offset[i]); + } } /** @@ -617,7 +589,7 @@ void CMap::ClearTile(unsigned short type, const Vec2i &pos) mf->Value = 0; UI.Minimap.UpdateXY(pos.x, pos.y); - FixNeighbors(type, 0, pos.x, pos.y); + FixNeighbors(type, 0, pos); //maybe isExplored if (IsTileVisible(ThisPlayer, index) > 0) { diff --git a/src/map/map_fog.cpp b/src/map/map_fog.cpp index ab97bc9dd..480b83484 100644 --- a/src/map/map_fog.cpp +++ b/src/map/map_fog.cpp @@ -114,11 +114,11 @@ int MapFogFilterFlags(CPlayer *player, const unsigned int index, int mask) } -int MapFogFilterFlags(CPlayer *player, int x, int y, int mask) +int MapFogFilterFlags(CPlayer *player, const Vec2i &pos, int mask) { - if(Map.Info.IsPointOnMap(x,y)) + if (Map.Info.IsPointOnMap(pos)) { - return MapFogFilterFlags(player, Map.getIndex(x,y), mask); + return MapFogFilterFlags(player, Map.getIndex(pos), mask); } return mask; } @@ -149,10 +149,10 @@ void MapMarkTileSight(const CPlayer *player, const unsigned int index) ++*v; } -void MapMarkTileSight(const CPlayer *player, int x, int y) +void MapMarkTileSight(const CPlayer *player, const Vec2i &pos) { - Assert(Map.Info.IsPointOnMap(x, y)); - MapMarkTileSight(player, Map.getIndex(x,y)); + Assert(Map.Info.IsPointOnMap(pos)); + MapMarkTileSight(player, Map.getIndex(pos)); } @@ -187,9 +187,8 @@ void MapUnmarkTileSight(const CPlayer *player, const unsigned int index) } } -void MapUnmarkTileSight(const CPlayer *player, int x, int y) +void MapUnmarkTileSight(const CPlayer *player, const Vec2i &pos) { - const Vec2i pos = {x, y}; Assert(Map.Info.IsPointOnMap(pos)); MapUnmarkTileSight(player, Map.getIndex(pos)); } @@ -212,9 +211,9 @@ void MapMarkTileDetectCloak(const CPlayer *player, const unsigned int index) ++*v; } -void MapMarkTileDetectCloak(const CPlayer *player, int x, int y) +void MapMarkTileDetectCloak(const CPlayer *player, const Vec2i &pos) { - MapMarkTileDetectCloak(player, Map.getIndex(x,y)); + MapMarkTileDetectCloak(player, Map.getIndex(pos)); } @@ -236,9 +235,9 @@ MapUnmarkTileDetectCloak(const CPlayer *player, const unsigned int index) --*v; } -void MapUnmarkTileDetectCloak(const CPlayer *player, int x, int y) +void MapUnmarkTileDetectCloak(const CPlayer *player, const Vec2i &pos) { - MapUnmarkTileDetectCloak(player, Map.getIndex(x,y)); + MapUnmarkTileDetectCloak(player, Map.getIndex(pos)); } /** @@ -252,13 +251,10 @@ void MapUnmarkTileDetectCloak(const CPlayer *player, int x, int y) ** @param range Radius to mark. ** @param marker Function to mark or unmark sight */ -void MapSight(const CPlayer *player, int x, int y, int w, int h, int range, - MapMarkerFunc *marker) +void MapSight(const CPlayer *player, int x, int y, int w, int h, int range, MapMarkerFunc *marker) { - int mx; - int my; - int cx[4]; - int cy[4]; + Vec2i mpos; + Vec2i c[4]; int steps; int cycle; @@ -270,13 +266,13 @@ void MapSight(const CPlayer *player, int x, int y, int w, int h, int range, #ifdef MARKER_ON_INDEX unsigned int index = y * Map.Info.MapWidth; #endif - for (my = y; my < y + h; ++my) { - for (mx = x - range; mx < x + range + w; ++mx) { - if (mx >= 0 && mx < Map.Info.MapWidth) { + for (mpos.y = y; mpos.y < y + h; ++mpos.y) { + for (mpos.x = x - range; mpos.x < x + range + w; ++mpos.x) { + if (mpos.x >= 0 && mpos.x < Map.Info.MapWidth) { #ifdef MARKER_ON_INDEX - marker(player, mx + index); + marker(player, mpos.x + index); #else - marker(player, mx, my); + marker(player, mpos); #endif } } @@ -289,13 +285,13 @@ void MapSight(const CPlayer *player, int x, int y, int w, int h, int range, #ifdef MARKER_ON_INDEX index = (y - range) * Map.Info.MapWidth; #endif - for (my = y - range; my < y; ++my) { - if (my >= 0 && my < Map.Info.MapHeight) { - for (mx = x; mx < x + w; ++mx) { + for (mpos.y = y - range; mpos.y < y; ++mpos.y) { + if (mpos.y >= 0 && mpos.y < Map.Info.MapHeight) { + for (mpos.x = x; mpos.x < x + w; ++mpos.x) { #ifdef MARKER_ON_INDEX - marker(player, mx + index); + marker(player, mpos.x + index); #else - marker(player, mx, my); + marker(player, mpos); #endif } } @@ -308,13 +304,13 @@ void MapSight(const CPlayer *player, int x, int y, int w, int h, int range, #ifdef MARKER_ON_INDEX index = (y + h) * Map.Info.MapWidth; #endif - for (my = y + h; my < y + range + h; ++my) { - if (my >= 0 && my < Map.Info.MapHeight) { - for (mx = x; mx < x + w; ++mx) { + for (mpos.y = y + h; mpos.y < y + range + h; ++mpos.y) { + if (mpos.y >= 0 && mpos.y < Map.Info.MapHeight) { + for (mpos.x = x; mpos.x < x + w; ++mpos.x) { #ifdef MARKER_ON_INDEX - marker(player, mx + index); + marker(player, mpos.x + index); #else - marker(player, mx, my); + marker(player, mpos); #endif } } @@ -327,57 +323,57 @@ void MapSight(const CPlayer *player, int x, int y, int w, int h, int range, steps = 0; while (VisionTable[0][steps] <= range) { // 0 - Top right Quadrant - cx[0] = x + w - 1; - cy[0] = y - VisionTable[0][steps]; + c[0].x = x + w - 1; + c[0].y = y - VisionTable[0][steps]; // 1 - Top left Quadrant - cx[1] = x; - cy[1] = y - VisionTable[0][steps]; + c[1].x = x; + c[1].y = y - VisionTable[0][steps]; // 2 - Bottom Left Quadrant - cx[2] = x; - cy[2] = y + VisionTable[0][steps] + h - 1; + c[2].x = x; + c[2].y = y + VisionTable[0][steps] + h - 1; // 3 - Bottom Right Quadrant - cx[3] = x + w - 1; - cy[3] = y + VisionTable[0][steps] + h - 1; + c[3].x = x + w - 1; + c[3].y = y + VisionTable[0][steps] + h - 1; // loop for steps ++steps; // Increment past info pointer while (VisionTable[1][steps] != 0 || VisionTable[2][steps] != 0) { // Loop through for repeat cycle cycle = 0; while (cycle++ < VisionTable[0][steps]) { - cx[0] += VisionTable[1][steps]; - cy[0] += VisionTable[2][steps]; - cx[1] -= VisionTable[1][steps]; - cy[1] += VisionTable[2][steps]; - cx[2] -= VisionTable[1][steps]; - cy[2] -= VisionTable[2][steps]; - cx[3] += VisionTable[1][steps]; - cy[3] -= VisionTable[2][steps]; - if (cx[0] < Map.Info.MapWidth && cy[0] >= 0) { + c[0].x += VisionTable[1][steps]; + c[0].y += VisionTable[2][steps]; + c[1].x -= VisionTable[1][steps]; + c[1].y += VisionTable[2][steps]; + c[2].x -= VisionTable[1][steps]; + c[2].y -= VisionTable[2][steps]; + c[3].x += VisionTable[1][steps]; + c[3].y -= VisionTable[2][steps]; + if (c[0].x < Map.Info.MapWidth && c[0].y >= 0) { #ifdef MARKER_ON_INDEX - marker(player, Map.getIndex(cx[0], cy[0])); + marker(player, Map.getIndex(c[0])); #else - marker(player, cx[0], cy[0]); + marker(player, c[0]); #endif } - if (cx[1] >= 0 && cy[1] >= 0) { + if (c[1].x >= 0 && c[1].y >= 0) { #ifdef MARKER_ON_INDEX - marker(player, Map.getIndex(cx[1], cy[1])); + marker(player, Map.getIndex(c[1])); #else - marker(player, cx[1], cy[1]); + marker(player, c[1]); #endif } - if (cx[2] >= 0 && cy[2] < Map.Info.MapHeight) { + if (c[2].x >= 0 && c[2].y < Map.Info.MapHeight) { #ifdef MARKER_ON_INDEX - marker(player, Map.getIndex(cx[2], cy[2])); + marker(player, Map.getIndex(c[2])); #else - marker(player, cx[2], cy[2]); + marker(player, c[2]); #endif } - if (cx[3] < Map.Info.MapWidth && cy[3] < Map.Info.MapHeight) { + if (c[3].x < Map.Info.MapWidth && c[3].y < Map.Info.MapHeight) { #ifdef MARKER_ON_INDEX - marker(player, Map.getIndex(cx[3], cy[3])); + marker(player, Map.getIndex(c[3])); #else - marker(player, cx[3], cy[3]); + marker(player, c[3]); #endif } } diff --git a/src/map/map_wall.cpp b/src/map/map_wall.cpp index 270dab056..9572eb11e 100644 --- a/src/map/map_wall.cpp +++ b/src/map/map_wall.cpp @@ -93,9 +93,8 @@ static int MapIsSeenTileWall(int x, int y, int walltype) ** @param x Map X tile-position. ** @param y Map Y tile-position. */ -void MapFixSeenWallTile(int x, int y) +void MapFixSeenWallTile(const Vec2i &pos) { - const Vec2i pos = {x, y}; int t; int tile; CMapField *mf; @@ -117,7 +116,7 @@ void MapFixSeenWallTile(int x, int y) if ((pos.y - 1) < 0 || MapIsSeenTileWall(pos.x, pos.y - 1, t)) { tile |= 1 << 0; } - if ((pos.x + 1) >= Map.Info.MapWidth || MapIsSeenTileWall(pos.x + 1, y, t)) { + if ((pos.x + 1) >= Map.Info.MapWidth || MapIsSeenTileWall(pos.x + 1, pos.y, t)) { tile |= 1 << 1; } if ((pos.y + 1) >= Map.Info.MapHeight || MapIsSeenTileWall(pos.x, pos.y + 1, t)) { @@ -171,15 +170,16 @@ void MapFixSeenWallTile(int x, int y) /** ** Correct the surrounding seen wall fields. ** -** @param x Map X tile-position. -** @param y Map Y tile-position. +** @param pos Map tile-position. */ -void MapFixSeenWallNeighbors(int x, int y) +void MapFixSeenWallNeighbors(const Vec2i &pos) { - MapFixSeenWallTile(x + 1, y); // side neighbors - MapFixSeenWallTile(x - 1, y); - MapFixSeenWallTile(x, y + 1); - MapFixSeenWallTile(x, y - 1); + const Vec2i offset[] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; + + for (unsigned int i = 0; i < 4; ++i) + { + MapFixSeenWallTile(pos + offset[i]); + } } /** @@ -188,27 +188,22 @@ void MapFixSeenWallNeighbors(int x, int y) ** @param x Map X tile-position. ** @param y Map Y tile-position. */ -void MapFixWallTile(int x, int y) +void MapFixWallTile(const Vec2i &pos) { - const Vec2i pos = {x, y}; - int tile; - CMapField *mf; - int t; - // Outside of map or no wall. if (!Map.Info.IsPointOnMap(pos)) { return; } - mf = Map.Field(pos); + CMapField *mf = Map.Field(pos); if (!(mf->Flags & MapFieldWall)) { return; } - t = mf->Flags & (MapFieldHuman | MapFieldWall); + int t = mf->Flags & (MapFieldHuman | MapFieldWall); // // Calculate the correct tile. Depends on the surrounding. // - tile = 0; + int tile = 0; if ((pos.y - 1) < 0 || (Map.Field(pos.x, (pos.y - 1))-> Flags & (MapFieldHuman | MapFieldWall)) == t) { tile |= 1 << 0; @@ -271,26 +266,25 @@ void MapFixWallTile(int x, int y) /** ** Correct the surrounding real wall fields. ** -** @param x Map X tile-position. -** @param y Map Y tile-position. +** @param pos Map tile-position. */ -static void MapFixWallNeighbors(int x, int y) +static void MapFixWallNeighbors(const Vec2i &pos) { - MapFixWallTile(x + 1, y); // side neighbors - MapFixWallTile(x - 1, y); - MapFixWallTile(x, y + 1); - MapFixWallTile(x, y - 1); + const Vec2i offset[] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; + + for (unsigned int i = 0; i < sizeof (offset) / sizeof (*offset); ++i) + { + MapFixWallTile(pos + offset[i]); + } } /** ** Remove wall from the map. ** -** @param x Map X position. -** @param y Map Y position. +** @param pos Map position. */ -void CMap::RemoveWall(unsigned x, unsigned y) +void CMap::RemoveWall(const Vec2i &pos) { - const Vec2i pos = {x, y}; CMapField *mf = Field(pos); mf->Value = 0; @@ -298,8 +292,8 @@ void CMap::RemoveWall(unsigned x, unsigned y) mf->Flags &= ~(MapFieldHuman | MapFieldWall | MapFieldUnpassable); UI.Minimap.UpdateXY(pos.x, pos.y); - MapFixWallTile(pos.x, pos.y); - MapFixWallNeighbors(pos.x, pos.y); + MapFixWallTile(pos); + MapFixWallNeighbors(pos); if (Map.IsFieldVisible(ThisPlayer, pos)) { UI.Minimap.UpdateSeenXY(pos.x, pos.y); @@ -310,15 +304,13 @@ void CMap::RemoveWall(unsigned x, unsigned y) /** ** Set wall onto the map. ** -** @param x Map X position. -** @param y Map Y position. +** @param pos Map position. ** @param humanwall Flag, if true set a human wall. ** ** @todo FIXME: support for more races. */ -void CMap::SetWall(unsigned x, unsigned y, int humanwall) +void CMap::SetWall(const Vec2i &pos, int humanwall) { - const Vec2i pos = {x, y}; CMapField *mf = Field(pos); // FIXME: support more walls of different races. @@ -335,8 +327,8 @@ void CMap::SetWall(unsigned x, unsigned y, int humanwall) } UI.Minimap.UpdateXY(pos.x, pos.y); - MapFixWallTile(pos.x, pos.y); - MapFixWallNeighbors(pos.x, pos.y); + MapFixWallTile(pos); + MapFixWallNeighbors(pos); if (Map.IsFieldVisible(ThisPlayer, pos)) { UI.Minimap.UpdateSeenXY(pos.x, pos.y); @@ -347,20 +339,19 @@ void CMap::SetWall(unsigned x, unsigned y, int humanwall) /** ** Wall is hit with damage. ** -** @param x Map X tile-position of wall. -** @param y Map Y tile-position of wall. +** @param pos Map tile-position of wall. ** @param damage Damage done to wall. */ -void CMap::HitWall(unsigned x, unsigned y, unsigned damage) +void CMap::HitWall(const Vec2i &pos, unsigned damage) { unsigned v; - v = this->Fields[x + y * this->Info.MapWidth].Value; + v = this->Field(pos)->Value; if (v <= damage) { - RemoveWall(x, y); + RemoveWall(pos); } else { - this->Fields[x + y * this->Info.MapWidth].Value = v - damage; - MapFixWallTile(x, y); + this->Field(pos)->Value = v - damage; + MapFixWallTile(pos); } } diff --git a/src/map/script_map.cpp b/src/map/script_map.cpp index ec372b241..374a46943 100644 --- a/src/map/script_map.cpp +++ b/src/map/script_map.cpp @@ -448,10 +448,12 @@ static int CclSetFogOfWarGraphics(lua_State *l) ** @param h Y coordinate ** @param value Value of the tile */ -void SetTile(int tile, int w, int h, int value) +void SetTile(int tile, int x, int y, int value) { - if (!Map.Info.IsPointOnMap(w, h)) { - fprintf(stderr, "Invalid map coordonate : (%d, %d)\n", w, h); + const Vec2i pos = {x, y}; + + if (!Map.Info.IsPointOnMap(pos)) { + fprintf(stderr, "Invalid map coordonate : (%d, %d)\n", pos.x, pos.y); return; } if (tile < 0 || tile >= Map.Tileset.NumTiles) { @@ -464,14 +466,14 @@ void SetTile(int tile, int w, int h, int value) } if (Map.Fields) { - unsigned int index = w + h * Map.Info.MapWidth; - Map.Fields[index].Tile = Map.Tileset.Table[tile]; - Map.Fields[index].Value = value; - Map.Fields[index].Flags = Map.Tileset.FlagsTable[tile]; - Map.Fields[index].Cost = - 1 << (Map.Tileset.FlagsTable[tile] & MapFieldSpeedMask); + CMapField &mf = *Map.Field(pos); + + mf.Tile = Map.Tileset.Table[tile]; + mf.Value = value; + mf.Flags = Map.Tileset.FlagsTable[tile]; + mf.Cost = 1 << (Map.Tileset.FlagsTable[tile] & MapFieldSpeedMask); #ifdef DEBUG - Map.Fields[index].TilesetTile = tile; + mf.TilesetTile = tile; #endif } } diff --git a/src/pathfinder/pathfinder.cpp b/src/pathfinder/pathfinder.cpp index bc4dd1f88..826db48a2 100644 --- a/src/pathfinder/pathfinder.cpp +++ b/src/pathfinder/pathfinder.cpp @@ -329,9 +329,10 @@ int NextPathElement(CUnit &unit, short int *pxd, short int *pyd) *pxd = Heading2X[(int)unit.Data.Move.Path[(int)unit.Data.Move.Length - 1]]; *pyd = Heading2Y[(int)unit.Data.Move.Path[(int)unit.Data.Move.Length - 1]]; + const Vec2i dir = {*pxd, *pyd}; result = unit.Data.Move.Length; unit.Data.Move.Length--; - if (!UnitCanBeAt(unit, *pxd + unit.tilePos.x, *pyd + unit.tilePos.y)) { + if (!UnitCanBeAt(unit, unit.tilePos + dir)) { // If obstructing unit is moving, wait for a bit. if (unit.Data.Move.Fast) { unit.Data.Move.Fast--; @@ -348,7 +349,7 @@ int NextPathElement(CUnit &unit, short int *pxd, short int *pyd) if (result > 0) { *pxd = Heading2X[(int)unit.Data.Move.Path[(int)unit.Data.Move.Length - 1]]; *pyd = Heading2Y[(int)unit.Data.Move.Path[(int)unit.Data.Move.Length - 1]]; - if (!UnitCanBeAt(unit, *pxd + unit.tilePos.x, *pyd + unit.tilePos.y)) { + if (!UnitCanBeAt(unit, unit.tilePos + dir)) { // There may be unit in the way, Astar may allow you to walk onto it. result = PF_UNREACHABLE; *pxd = 0; diff --git a/src/stratagus/missile.cpp b/src/stratagus/missile.cpp index 76c8059b2..11d4133fb 100644 --- a/src/stratagus/missile.cpp +++ b/src/stratagus/missile.cpp @@ -389,13 +389,13 @@ void FireMissile(CUnit &unit) if (!goal) { const Vec2i& goalPos = unit.CurrentOrder()->goalPos; - if (Map.WallOnMap(goalPos.x, goalPos.y)) { - if (Map.HumanWallOnMap(goalPos.x, goalPos.y)) { - Map.HitWall(goalPos.x, goalPos.y, + if (Map.WallOnMap(goalPos)) { + if (Map.HumanWallOnMap(goalPos)) { + Map.HitWall(goalPos, CalculateDamageStats(*unit.Stats, *UnitTypeHumanWall->Stats, unit.Variable[BLOODLUST_INDEX].Value)); } else { - Map.HitWall(goalPos.x, goalPos.y, + Map.HitWall(goalPos, CalculateDamageStats(*unit.Stats, *UnitTypeOrcWall->Stats, unit.Variable[BLOODLUST_INDEX].Value)); } @@ -847,22 +847,22 @@ static void MissileHitsWall(const Missile &missile, const Vec2i &tilePos, int sp { CUnitStats *stats; // stat of the wall. - if (!Map.WallOnMap(tilePos.x, tilePos.y)) { + if (!Map.WallOnMap(tilePos)) { return; } if (missile.Damage) { // direct damage, spells mostly - Map.HitWall(tilePos.x, tilePos.y, missile.Damage / splash); + Map.HitWall(tilePos, missile.Damage / splash); return; } Assert(missile.SourceUnit != NULL); - if (Map.HumanWallOnMap(tilePos.x, tilePos.y)) { + if (Map.HumanWallOnMap(tilePos)) { stats = UnitTypeHumanWall->Stats; } else { - Assert(Map.OrcWallOnMap(tilePos.x, tilePos.y)); + Assert(Map.OrcWallOnMap(tilePos)); stats = UnitTypeOrcWall->Stats; } - Map.HitWall(tilePos.x, tilePos.y, CalculateDamageStats(*missile.SourceUnit->Stats, *stats, 0) / splash); + Map.HitWall(tilePos, CalculateDamageStats(*missile.SourceUnit->Stats, *stats, 0) / splash); } /** diff --git a/src/stratagus/player.cpp b/src/stratagus/player.cpp index c5b41b8c0..46aae7819 100644 --- a/src/stratagus/player.cpp +++ b/src/stratagus/player.cpp @@ -299,7 +299,7 @@ void SavePlayers(CFile *file) //Additional security if (!aatarget.IsAliveOnMap() || - Map.Field(aatarget.tilePos.x, aatarget.tilePos.y)->Guard[i] == 0) { + Map.Field(aatarget.tilePos)->Guard[i] == 0) { autoatacktargets.Units.erase(autoatacktargets.Units.begin() + k); aatarget.RefsDecrease(); continue; diff --git a/src/stratagus/spells.cpp b/src/stratagus/spells.cpp index f4a414735..dd72e7cba 100644 --- a/src/stratagus/spells.cpp +++ b/src/stratagus/spells.cpp @@ -93,33 +93,24 @@ std::vector<SpellType*> SpellTypeTable; */ int Demolish::Cast(CUnit &caster, const SpellType *, CUnit *, int x, int y) { - int xmin; - int ymin; - int xmax; - int ymax; - - // // Allow error margins. (Lame, I know) - // - xmin = x - this->Range - 2; - ymin = y - this->Range - 2; - xmax = x + this->Range + 2; - ymax = y + this->Range + 2; + Vec2i minpos = {x - this->Range - 2, y - this->Range - 2}; + Vec2i maxpos = {x + this->Range + 2, y + this->Range + 2}; - Map.FixSelectionArea(xmin, ymin, xmax, ymax); + Map.FixSelectionArea(minpos, maxpos); // // Terrain effect of the explosion // Vec2i ipos; - for (ipos.x = xmin; ipos.x <= xmax; ++ipos.x) { - for (ipos.y = ymin; ipos.y <= ymax; ++ipos.y) { + for (ipos.x = minpos.x; ipos.x <= maxpos.x; ++ipos.x) { + for (ipos.y = minpos.y; ipos.y <= maxpos.y; ++ipos.y) { const int flag = Map.Field(ipos)->Flags; if (MapDistance(ipos.x, ipos.y, x, y) > this->Range) { // Not in circle range continue; } else if (flag & MapFieldWall) { - Map.RemoveWall(ipos.x, ipos.y); + Map.RemoveWall(ipos); } else if (flag & MapFieldRocks) { Map.ClearTile(MapFieldRocks, ipos); } else if (flag & MapFieldForest) { @@ -133,7 +124,7 @@ int Demolish::Cast(CUnit &caster, const SpellType *, CUnit *, int x, int y) // if (this->Damage) { CUnit* table[UnitMax]; - const int n = Map.SelectFixed(xmin, ymin, xmax + 1, ymax + 1, table); + const int n = Map.SelectFixed(minpos, maxpos, table); for (int i = 0; i < n; ++i) { CUnit &unit = *table[i]; if (unit.Type->UnitType != UnitTypeFly && unit.IsAlive() && @@ -526,19 +517,15 @@ int AdjustVitals::Cast(CUnit &caster, const SpellType *spell, CUnit *target, int */ int Polymorph::Cast(CUnit &caster, const SpellType *spell, CUnit *target, int x, int y) { - int i; - int j; - CUnitType *type; - if (!target) { return 0; } - type = this->NewForm; + CUnitType *type = this->NewForm; x = x - type->TileWidth / 2; y = y - type->TileHeight / 2; - + const Vec2i pos = {x, y}; caster.Player->Score += target->Type->Points; if (caster.IsEnemy(*target)) { if (target->Type->Building) { @@ -559,9 +546,10 @@ int Polymorph::Cast(CUnit &caster, const SpellType *spell, CUnit *target, int x, // as said somewhere else -- no corpses :) target->Remove(NULL); - for (i = 0; i < type->TileWidth; ++i) { - for (j = 0; j < type->TileHeight; ++j) { - if (!UnitTypeCanBeAt(type, x + i, y + j)) { + Vec2i offset; + for (offset.x = 0; offset.x < type->TileWidth; ++offset.x) { + for (offset.y = 0; offset.y < type->TileHeight; ++offset.y) { + if (!UnitTypeCanBeAt(type, pos + offset)) { target->Place(target->tilePos.x, target->tilePos.y); return 0; } @@ -569,9 +557,9 @@ int Polymorph::Cast(CUnit &caster, const SpellType *spell, CUnit *target, int x, } caster.Variable[MANA_INDEX].Value -= spell->ManaCost; if (this->PlayerNeutral) { - MakeUnitAndPlace(x, y, type, Players + PlayerNumNeutral); + MakeUnitAndPlace(pos.x, pos.y, type, Players + PlayerNumNeutral); } else { - MakeUnitAndPlace(x, y, type, target->Player); + MakeUnitAndPlace(pos.x, pos.y, type, target->Player); } UnitLost(*target); UnitClearOrders(*target); diff --git a/src/ui/mouse.cpp b/src/ui/mouse.cpp index c3e1191f3..cc84b2728 100644 --- a/src/ui/mouse.cpp +++ b/src/ui/mouse.cpp @@ -380,14 +380,12 @@ void DoRightButton(int sx, int sy) continue; } } - if (Map.WallOnMap(pos.x, pos.y)) { - if (unit->Player->Race == PlayerRaceHuman && - Map.OrcWallOnMap(pos.x, pos.y)) { + if (Map.WallOnMap(pos)) { + if (unit->Player->Race == PlayerRaceHuman && Map.OrcWallOnMap(pos)) { SendCommandAttack(*unit, pos.x, pos.y, NoUnitP, flush); continue; } - if (unit->Player->Race == PlayerRaceOrc && - Map.HumanWallOnMap(pos.x, pos.y)) { + if (unit->Player->Race == PlayerRaceOrc && Map.HumanWallOnMap(pos)) { SendCommandAttack(*unit, pos.x, pos.y, NoUnitP, flush); continue; } @@ -1880,31 +1878,18 @@ void UIHandleButtonUp(unsigned button) // if (CursorStartX < CursorX - 1 || CursorStartX > CursorX + 1 || CursorStartY < CursorY - 1 || CursorStartY > CursorY + 1) { - int x0; - int y0; - int x1; - int y1; - - x0 = CursorStartScrMapX; - y0 = CursorStartScrMapY; - x1 = CursorX - UI.MouseViewport->X + + int x0 = CursorStartScrMapX; + int y0 = CursorStartScrMapY; + int x1 = CursorX - UI.MouseViewport->X + UI.MouseViewport->MapX * TileSizeX + UI.MouseViewport->OffsetX; - y1 = CursorY - UI.MouseViewport->Y + + int y1 = CursorY - UI.MouseViewport->Y + UI.MouseViewport->MapY * TileSizeY + UI.MouseViewport->OffsetY; if (x0 > x1) { - int swap; - - swap = x0; - x0 = x1; - x1 = swap; + std::swap(x0, x1); } if (y0 > y1) { - int swap; - - swap = y0; - y0 = y1; - y1 = swap; + std::swap(y0, y1); } if (KeyModifiers & ModifierShift) { if (KeyModifiers & ModifierAlt) { diff --git a/src/unit/build.cpp b/src/unit/build.cpp index bdf559b32..041888f11 100644 --- a/src/unit/build.cpp +++ b/src/unit/build.cpp @@ -218,16 +218,14 @@ inline bool CBuildRestrictionOnTop::functor::operator() (CUnit *const unit) bool CBuildRestrictionOnTop::Check(const CUnitType *, int x, int y, CUnit *&ontoptarget) const { CUnit *table[UnitMax]; - int n; - int i; + const Vec2i pos = {x, y}; ontoptarget = NULL; - n = Map.Select(x, y, table, UnitMax); - for (i = 0; i < n; ++i) { - if (table[i]->tilePos.x == x && table[i]->tilePos.y == y && !table[i]->Destroyed && + int n = Map.Select(pos, table, UnitMax); + for (int i = 0; i < n; ++i) { + if (table[i]->tilePos == pos && !table[i]->Destroyed && table[i]->CurrentAction() != UnitActionDie) { - if (table[i]->Type == this->Parent && - table[i]->CurrentAction() != UnitActionBuilt) { + if (table[i]->Type == this->Parent && table[i]->CurrentAction() != UnitActionBuilt) { // Available to build on ontoptarget = table[i]; } diff --git a/src/unit/script_unit.cpp b/src/unit/script_unit.cpp index e37807cf8..78283318d 100644 --- a/src/unit/script_unit.cpp +++ b/src/unit/script_unit.cpp @@ -944,8 +944,7 @@ static int CclMoveUnit(lua_State *l) { CUnit *unit; int heading; - int ix; - int iy; + Vec2i ipos; LuaCheckArgs(l, 2); @@ -954,22 +953,20 @@ static int CclMoveUnit(lua_State *l) lua_pop(l, 1); lua_rawgeti(l, 2, 1); - ix = LuaToNumber(l, -1); + ipos.x = LuaToNumber(l, -1); lua_pop(l, 1); lua_rawgeti(l, 2, 2); - iy = LuaToNumber(l, -1); + ipos.y = LuaToNumber(l, -1); lua_pop(l, 1); heading = SyncRand() % 256; - if (UnitCanBeAt(*unit, ix, iy)) { - unit->Place(ix, iy); + if (UnitCanBeAt(*unit, ipos)) { + unit->Place(ipos.x, ipos.y); } else { - unit->tilePos.x = ix; - unit->tilePos.y = iy; + unit->tilePos = ipos; DropOutOnSide(*unit, heading, 1, 1); } - -// PlaceUnit(unit, ix, iy); +// PlaceUnit(unit, ipos.x, ipos.y); lua_pushvalue(l, 1); return 1; } @@ -987,8 +984,7 @@ static int CclCreateUnit(lua_State *l) CUnit *unit; int heading; int playerno; - int ix; - int iy; + Vec2i ipos; LuaCheckArgs(l, 3); @@ -999,10 +995,10 @@ static int CclCreateUnit(lua_State *l) LuaError(l, "incorrect argument !!"); } lua_rawgeti(l, 3, 1); - ix = LuaToNumber(l, -1); + ipos.x = LuaToNumber(l, -1); lua_pop(l, 1); lua_rawgeti(l, 3, 2); - iy = LuaToNumber(l, -1); + ipos.y = LuaToNumber(l, -1); lua_pop(l, 1); heading = SyncRand() % 256; @@ -1025,12 +1021,11 @@ static int CclCreateUnit(lua_State *l) DebugPrint("Unable to allocate unit"); return 0; } else { - if (UnitCanBeAt(*unit, ix, iy) || - (unit->Type->Building && CanBuildUnitType(NULL, unit->Type, ix, iy, 0))) { - unit->Place(ix, iy); + if (UnitCanBeAt(*unit, ipos) || + (unit->Type->Building && CanBuildUnitType(NULL, unit->Type, ipos.x, ipos.y, 0))) { + unit->Place(ipos.x, ipos.y); } else { - unit->tilePos.x = ix; - unit->tilePos.y = iy; + unit->tilePos = ipos; DropOutOnSide(*unit, heading, 1, 1); } UpdateForNewUnit(*unit, 0); diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp index 132d778e7..970c6a09f 100644 --- a/src/unit/unit.cpp +++ b/src/unit/unit.cpp @@ -777,15 +777,17 @@ static void UnitInXY(CUnit &unit, int x, int y) */ void CUnit::MoveToXY(int x, int y) { + const Vec2i pos = {x, y}; + MapUnmarkUnitSight(*this); - Map.Remove(this); + Map.Remove(*this); UnmarkUnitFieldFlags(*this); - Assert(UnitCanBeAt(*this, x, y)); + Assert(UnitCanBeAt(*this, pos)); // Move the unit. - UnitInXY(*this, x, y); + UnitInXY(*this, pos.x, pos.y); - Map.Insert(this); + Map.Insert(*this); MarkUnitFieldFlags(*this); // Recalculate the seen count. UnitCountSeen(*this); @@ -815,7 +817,7 @@ void CUnit::Place(int x, int y) // Pathfinding info. MarkUnitFieldFlags(*this); // Tha cache list. - Map.Insert(this); + Map.Insert(*this); // Calculate the seen count. UnitCountSeen(*this); // Vision @@ -859,7 +861,7 @@ void CUnit::Remove(CUnit *host) return; } - Map.Remove(this); + Map.Remove(*this); MapUnmarkUnitSight(*this); UnmarkUnitFieldFlags(*this); MapUnmarkUnitGuard(*this); @@ -1866,28 +1868,28 @@ void DropOutOnSide(CUnit &unit, int heading, int addx, int addy) for (;;) { startw: for (i = addy; i--; ++pos.y) { - if (UnitCanBeAt(unit, pos.x, pos.y)) { + if (UnitCanBeAt(unit, pos)) { goto found; } } ++addx; starts: for (i = addx; i--; ++pos.x) { - if (UnitCanBeAt(unit, pos.x, pos.y)) { + if (UnitCanBeAt(unit, pos)) { goto found; } } ++addy; starte: for (i = addy; i--; --pos.y) { - if (UnitCanBeAt(unit, pos.x, pos.y)) { + if (UnitCanBeAt(unit, pos)) { goto found; } } ++addx; startn: for (i = addx; i--; --pos.x) { - if (UnitCanBeAt(unit, pos.x, pos.y)) { + if (UnitCanBeAt(unit, pos)) { goto found; } } @@ -1924,7 +1926,7 @@ void DropOutNearest(CUnit &unit, const Vec2i &goalPos, int addx, int addy) --pos.x; for (;;) { for (int i = addy; i--; ++pos.y) { // go down - if (UnitCanBeAt(unit, pos.x, pos.y)) { + if (UnitCanBeAt(unit, pos)) { const int n = MapDistance(goalPos.x, goalPos.y, pos.x, pos.y); if (n < bestd) { @@ -1935,7 +1937,7 @@ void DropOutNearest(CUnit &unit, const Vec2i &goalPos, int addx, int addy) } ++addx; for (int i = addx; i--; ++pos.x) { // go right - if (UnitCanBeAt(unit, pos.x, pos.y)) { + if (UnitCanBeAt(unit, pos)) { const int n = MapDistance(goalPos.x, goalPos.y, pos.x, pos.y); if (n < bestd) { @@ -1946,7 +1948,7 @@ void DropOutNearest(CUnit &unit, const Vec2i &goalPos, int addx, int addy) } ++addy; for (int i = addy; i--; --pos.y) { // go up - if (UnitCanBeAt(unit, pos.x, pos.y)) { + if (UnitCanBeAt(unit, pos)) { const int n = MapDistance(goalPos.x, goalPos.y, pos.x, pos.y); if (n < bestd) { @@ -1957,7 +1959,7 @@ void DropOutNearest(CUnit &unit, const Vec2i &goalPos, int addx, int addy) } ++addx; for (int i = addx; i--; --pos.x) { // go left - if (UnitCanBeAt(unit, pos.x, pos.y)) { + if (UnitCanBeAt(unit, pos)) { const int n = MapDistance(goalPos.x, goalPos.y, pos.x, pos.y); if (n < bestd) { @@ -2088,13 +2090,13 @@ int FindTerrainType(int movemask, int resmask, int rvresult, int range, continue; } // Look if found what was required. - bool can_move_to = CanMoveToMask(pos.x, pos.y, resmask); + bool can_move_to = CanMoveToMask(pos, resmask); if ((rvresult ? can_move_to : !can_move_to)) { *terrainPos = pos; delete[] points; return 1; } - if (CanMoveToMask(pos.x, pos.y, movemask)) { // reachable + if (CanMoveToMask(pos, movemask)) { // reachable *m = 1; points[wp] = pos; // push the point if (++wp >= size) { // round about @@ -2424,7 +2426,7 @@ CUnit *UnitFindResource(const CUnit &unit, int x, int y, int range, int resource } } - if (CanMoveToMask(pos.x, pos.y, mask)) { // reachable + if (CanMoveToMask(pos, mask)) { // reachable *m = 1; points[wp] = pos; // push the point if (++wp >= size) { // round about @@ -2563,7 +2565,7 @@ CUnit *UnitFindMiningArea(const CUnit &unit, int x, int y, int range, int resou } } - if (CanMoveToMask(pos.x, pos.y, mask)) { // reachable + if (CanMoveToMask(pos, mask)) { // reachable *m = 1; points[wp] = pos; // push the point if (++wp >= size) { // round about @@ -2859,7 +2861,7 @@ void LetUnitDie(CUnit &unit) // This enables us to be tracked. Possibly for spells (eg raise dead) if (type->CorpseType || (type->Animations && type->Animations->Death)) { unit.Removed = 0; - Map.Insert(&unit); + Map.Insert(unit); // FIXME: rb: Maybe we need this here because corpse of cloaked units // may crash Sign code diff --git a/src/unit/unit_cache.cpp b/src/unit/unit_cache.cpp index 07618d46f..8d54b8e86 100644 --- a/src/unit/unit_cache.cpp +++ b/src/unit/unit_cache.cpp @@ -49,23 +49,23 @@ ** ** @param unit Unit pointer to place in cache. */ -void CMap::Insert(CUnit *unit) +void CMap::Insert(CUnit &unit) { - Assert(!unit->Removed); - unsigned int index = unit->Offset; - const int w = unit->Type->TileWidth; - const int h = unit->Type->TileHeight; + Assert(!unit.Removed); + unsigned int index = unit.Offset; + const int w = unit.Type->TileWidth; + const int h = unit.Type->TileHeight; int j,i = h; - CMapField *mf; + do { - mf = Field(index); + CMapField *mf = Field(index); j = w; do { - mf->UnitCache.Insert(unit); + mf->UnitCache.Insert(&unit); ++mf; - } while( --j && unit->tilePos.x + (j - w) < Info.MapWidth); + } while( --j && unit.tilePos.x + (j - w) < Info.MapWidth); index += Info.MapWidth; - } while( --i && unit->tilePos.y + (i - h) < Info.MapHeight); + } while( --i && unit.tilePos.y + (i - h) < Info.MapHeight); } /** @@ -73,40 +73,38 @@ void CMap::Insert(CUnit *unit) ** ** @param unit Unit pointer to remove from cache. */ -void CMap::Remove(CUnit *unit) +void CMap::Remove(CUnit &unit) { - Assert(!unit->Removed); - unsigned int index = unit->Offset; - const int w = unit->Type->TileWidth; - const int h = unit->Type->TileHeight; + Assert(!unit.Removed); + unsigned int index = unit.Offset; + const int w = unit.Type->TileWidth; + const int h = unit.Type->TileHeight; int j,i = h; - CMapField *mf; + do { - mf = Field(index); + CMapField *mf = Field(index); j = w; do { - mf->UnitCache.Remove(unit); + mf->UnitCache.Remove(&unit); ++mf; - } while( --j && unit->tilePos.x + (j - w) < Info.MapWidth); + } while( --j && unit.tilePos.x + (j - w) < Info.MapWidth); index += Info.MapWidth; - } while( --i && unit->tilePos.y + (i - h) < Info.MapHeight); + } while( --i && unit.tilePos.y + (i - h) < Info.MapHeight); } /** ** Select units on map tile. ** -** @param x Map X tile position -** @param y Map Y tile position +** @param pos Map tile position ** @param table All units in the selection rectangle ** @param tablesize Size of table array ** ** @return Returns the number of units found */ -int CMap::Select(int x, int y, CUnit *table[], - const int tablesize) +int CMap::Select(const Vec2i &pos, CUnit *table[], const int tablesize) { int n = 0; - CUnitCache &cache = Field(x,y)->UnitCache; + CUnitCache &cache = Field(pos)->UnitCache; const size_t size = cache.size(); for(unsigned int i = 0; n < tablesize && i < size; ++i) { CUnit *unit = cache.Units[i]; @@ -119,38 +117,36 @@ int CMap::Select(int x, int y, CUnit *table[], /** ** Select units in rectangle range. ** -** @param x1 Left column of selection rectangle -** @param y1 Top row of selection rectangle -** @param x2 Right column of selection rectangle -** @param y2 Bottom row of selection rectangle +** @param ltpos Left Top position of selection rectangle +** @param rbpos Right Bottom position of selection rectangle ** @param table All units in the selection rectangle ** @param tablesize Size of table array ** ** @return Returns the number of units found */ -int CMap::SelectFixed(int x1, int y1, - int x2, int y2, CUnit *table[], const int tablesize) +int CMap::SelectFixed(const Vec2i <pos, const Vec2i &rbpos, CUnit *table[], const int tablesize) { + Assert(Info.IsPointOnMap(ltpos)); + Assert(Info.IsPointOnMap(rbpos)); // Optimize small searches. - if (x1 >= x2 - 1 && y1 >= y2 - 1) { - return Select(x1, y1, table, tablesize); + if (ltpos == rbpos) { + return Select(ltpos, table, tablesize); } int i; int n = 0; CUnit *unit; - const CMapField *mf; - unsigned int index = getIndex(x1, y1); - int j = y2 - y1 + 1; + unsigned int index = getIndex(ltpos); + int j = rbpos.y - ltpos.y + 1; do { - mf = Field(index); - i = x2 - x1 + 1; + const CMapField *mf = Field(index); + i = rbpos.x - ltpos.x + 1; do { #if __GNUC__ > 3 //GCC version only, since std::vector::data() is not in STL size_t count = mf->UnitCache.size(); - if(count) { + if (count) { CUnit **cache = (CUnit **)mf->UnitCache.Units.data(); do { unit = *cache; @@ -169,7 +165,7 @@ int CMap::SelectFixed(int x1, int y1, } #else const size_t count = mf->UnitCache.size(); - if(count) { + if (count) { unsigned int k = 0; const CUnitCache &cache = mf->UnitCache; do { @@ -192,7 +188,8 @@ int CMap::SelectFixed(int x1, int y1, index += Info.MapWidth; } while(--j && n < tablesize); - if(!n) return 0; + if (!n) + return 0; // // Clean the cache locks, restore to original situation. @@ -212,25 +209,17 @@ int CMap::SelectFixed(int x1, int y1, case 1: table[i++]->CacheLock = 0; } while ( --j > 0 ); } - #endif - - return n; } int CMap::Select(int x1, int y1, int x2, int y2, CUnit *table[], const int tablesize) { - - // // Reduce to map limits. - // - x1 = std::max<int>(x1, 0); - y1 = std::max<int>(y1, 0); - x2 = std::min<int>(x2, Info.MapWidth - 1); - y2 = std::min<int>(y2, Info.MapHeight - 1); + Vec2i ltpos = {std::max<int>(x1, 0), std::max<int>(y1, 0)}; + Vec2i rbpos = {std::min<int>(x2, Info.MapWidth - 1), std::min<int>(y2, Info.MapHeight - 1)}; - return SelectFixed(x1,y1,x2,y2,table, tablesize); + return SelectFixed(ltpos, rbpos, table, tablesize); } diff --git a/src/video/cursor.cpp b/src/video/cursor.cpp index 91a280f95..d097451ff 100644 --- a/src/video/cursor.cpp +++ b/src/video/cursor.cpp @@ -268,7 +268,7 @@ static void DrawBuildingCursor(void) while (w--) { const Vec2i posIt = {mpos.x + w, mpos.y + h}; if (f && (ontop || - CanBuildOn(posIt, MapFogFilterFlags(ThisPlayer, posIt.x, posIt.y, + CanBuildOn(posIt, MapFogFilterFlags(ThisPlayer, posIt, mask & ((NumSelected && Selected[0]->tilePos == posIt) ? ~(MapFieldLandUnit | MapFieldSeaUnit) : -1)))) && Map.IsFieldExplored(ThisPlayer, posIt)) {