Still some use of Vec2i
This commit is contained in:
parent
c0bfa31f89
commit
1577067261
24 changed files with 408 additions and 544 deletions
src
action
ai
editor
include
map
pathfinder
stratagus
ui
unit
video
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ?
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
148
src/map/map.cpp
148
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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue