Still some use of Vec2i

This commit is contained in:
Joris 2010-11-11 16:54:28 +01:00
parent c0bfa31f89
commit 1577067261
24 changed files with 408 additions and 544 deletions

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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 ?

View file

@ -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);

View file

@ -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

View file

@ -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;
}

View file

@ -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.

View file

@ -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);
}
}
}

View file

@ -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 &ltpos, 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);
}

View file

@ -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) {

View file

@ -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
}
}

View file

@ -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);
}
}

View file

@ -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
}
}

View file

@ -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;

View file

@ -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);
}
/**

View file

@ -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;

View file

@ -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);

View file

@ -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) {

View file

@ -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];
}

View file

@ -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);

View file

@ -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

View file

@ -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 &ltpos, 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);
}

View file

@ -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)) {