1
0
Fork 0

(svn r1749) Move the functions which calculate distances to map.[ch] and give the more meaningful names

release/0.4.5
tron 2005-01-31 07:23:15 +00:00
parent e1c19367f0
commit 7bbcf5875c
18 changed files with 122 additions and 102 deletions

30
ai.c
View File

@ -462,7 +462,7 @@ static void AiFindSubsidyIndustryRoute(FoundRoute *fr)
to_xy = to_ind->xy; to_xy = to_ind->xy;
} }
fr->distance = GetTileDist(from->xy, to_xy); fr->distance = DistanceManhattan(from->xy, to_xy);
} }
static void AiFindSubsidyPassengerRoute(FoundRoute *fr) static void AiFindSubsidyPassengerRoute(FoundRoute *fr)
@ -493,7 +493,7 @@ static void AiFindSubsidyPassengerRoute(FoundRoute *fr)
if (from->population < 400 || to->population < 400) if (from->population < 400 || to->population < 400)
return; return;
fr->distance = GetTileDist(from->xy, to->xy); fr->distance = DistanceManhattan(from->xy, to->xy);
} }
static void AiFindRandomIndustryRoute(FoundRoute *fr) static void AiFindRandomIndustryRoute(FoundRoute *fr)
@ -531,7 +531,7 @@ static void AiFindRandomIndustryRoute(FoundRoute *fr)
return; return;
fr->to = i2; fr->to = i2;
fr->distance = GetTileDist(i->xy, i2->xy); fr->distance = DistanceManhattan(i->xy, i2->xy);
} else { } else {
// pick a dest town, and see if it's big enough // pick a dest town, and see if it's big enough
t = AiFindRandomTown(); t = AiFindRandomTown();
@ -539,7 +539,7 @@ static void AiFindRandomIndustryRoute(FoundRoute *fr)
return; return;
fr->to = t; fr->to = t;
fr->distance = GetTileDist(i->xy, t->xy); fr->distance = DistanceManhattan(i->xy, t->xy);
} }
} }
@ -561,7 +561,7 @@ static void AiFindRandomPassengerRoute(FoundRoute *fr)
if (dest == NULL || source == dest || dest->population < 400) if (dest == NULL || source == dest || dest->population < 400)
return; return;
fr->distance = GetTileDist(source->xy, dest->xy); fr->distance = DistanceManhattan(source->xy, dest->xy);
} }
// Warn: depends on 'xy' being the first element in both Town and Industry // Warn: depends on 'xy' being the first element in both Town and Industry
@ -580,9 +580,9 @@ static bool AiCheckIfRouteIsGood(Player *p, FoundRoute *fr, byte bitmask)
dist = 0xFFFF; dist = 0xFFFF;
FOR_ALL_STATIONS(st) if (st->xy != 0 && st->owner == _current_player) { FOR_ALL_STATIONS(st) if (st->xy != 0 && st->owner == _current_player) {
cur = GetTileDist1D(from_tile, st->xy); cur = DistanceMax(from_tile, st->xy);
if (cur < dist) dist = cur; if (cur < dist) dist = cur;
cur = GetTileDist1D(to_tile, st->xy); cur = DistanceMax(to_tile, st->xy);
if (cur < dist) dist = cur; if (cur < dist) dist = cur;
if (to_tile == from_tile && st->xy == to_tile) if (to_tile == from_tile && st->xy == to_tile)
same_station++; same_station++;
@ -1419,7 +1419,7 @@ static void AiWantOilRigAircraftRoute(Player *p)
// Find a random oil rig industry // Find a random oil rig industry
in = GetIndustry(RandomRange(_total_industries)); in = GetIndustry(RandomRange(_total_industries));
if (in != NULL && in->type == IT_OIL_RIG) { if (in != NULL && in->type == IT_OIL_RIG) {
if (GetTileDist(t->xy, in->xy) < 60) if (DistanceManhattan(t->xy, in->xy) < 60)
break; break;
} }
} }
@ -1843,7 +1843,7 @@ static bool AiEnumFollowTrack(uint tile, AiRailPathFindData *a, int track, uint
return true; return true;
} }
if (GetTileDist1D(tile, a->tile2) < 4) if (DistanceMax(tile, a->tile2) < 4)
a->count++; a->count++;
return false; return false;
@ -2028,7 +2028,7 @@ static void AiBuildRailRecursive(AiRailFinder *arf, TileIndex tile, int dir)
// Depth too deep? // Depth too deep?
if (arf->depth >= 4) { if (arf->depth >= 4) {
uint dist = GetTileDist1Db(tile, arf->final_tile); uint dist = DistanceMaxPlusManhattan(tile, arf->final_tile);
if (dist < arf->cur_best_dist) { if (dist < arf->cur_best_dist) {
// Store the tile that is closest to the final position. // Store the tile that is closest to the final position.
arf->cur_best_depth = arf->depth; arf->cur_best_depth = arf->depth;
@ -2620,7 +2620,7 @@ static bool AiCheckBlockDistances(Player *p, TileIndex tile)
do { do {
if (aib->cur_building_rule != 255) { if (aib->cur_building_rule != 255) {
if (GetTileDist(aib->use_tile, tile) < 9) if (DistanceManhattan(aib->use_tile, tile) < 9)
return false; return false;
} }
} while (++aib, --num); } while (++aib, --num);
@ -2768,7 +2768,7 @@ static bool AiCheckRoadPathBetter(AiRoadFinder *arf, const byte *p)
static bool AiEnumFollowRoad(uint tile, AiRoadEnum *a, int track, uint length, byte *state) static bool AiEnumFollowRoad(uint tile, AiRoadEnum *a, int track, uint length, byte *state)
{ {
uint dist = GetTileDist(tile, a->dest); uint dist = DistanceManhattan(tile, a->dest);
uint tile2; uint tile2;
if (dist <= a->best_dist) { if (dist <= a->best_dist) {
@ -2813,7 +2813,7 @@ static bool AiCheckRoadFinished(Player *p)
FollowTrack(tile, 0x3000 | TRANSPORT_ROAD, _dir_by_track[i], (TPFEnumProc*)AiEnumFollowRoad, NULL, &are); FollowTrack(tile, 0x3000 | TRANSPORT_ROAD, _dir_by_track[i], (TPFEnumProc*)AiEnumFollowRoad, NULL, &are);
} }
if (GetTileDist(tile, are.dest) <= are.best_dist) if (DistanceManhattan(tile, are.dest) <= are.best_dist)
return false; return false;
if (are.best_dist == 0) if (are.best_dist == 0)
@ -2913,7 +2913,7 @@ static void AiBuildRoadRecursive(AiRoadFinder *arf, TileIndex tile, int dir)
// Depth too deep? // Depth too deep?
if (arf->depth >= 4) { if (arf->depth >= 4) {
uint dist = GetTileDist1Db(tile, arf->final_tile); uint dist = DistanceMaxPlusManhattan(tile, arf->final_tile);
if (dist < arf->cur_best_dist) { if (dist < arf->cur_best_dist) {
// Store the tile that is closest to the final position. // Store the tile that is closest to the final position.
arf->cur_best_dist = dist; arf->cur_best_dist = dist;
@ -3292,7 +3292,7 @@ static void AiStateAirportStuff(Player *p)
continue; continue;
// Dismiss airports too far away. // Dismiss airports too far away.
if (GetTileDist1D(st->airport_tile, aib->spec_tile) > aib->rand_rng) if (DistanceMax(st->airport_tile, aib->spec_tile) > aib->rand_rng)
continue; continue;
// It's ideal airport, let's take it! // It's ideal airport, let's take it!

View File

@ -224,7 +224,7 @@ static bool AiNew_Check_City_or_Industry(Player *p, int ic, byte type) {
// to build there // to build there
if (!st->goods[CT_PASSENGERS].last_speed) continue; if (!st->goods[CT_PASSENGERS].last_speed) continue;
// Is it around our city // Is it around our city
if (GetTileDist(st->xy, t->xy) > 10) continue; if (DistanceManhattan(st->xy, t->xy) > 10) continue;
// It does take this cargo.. what is his rating? // It does take this cargo.. what is his rating?
if (st->goods[CT_PASSENGERS].rating < AI_CHECKCITY_CARGO_RATING) continue; if (st->goods[CT_PASSENGERS].rating < AI_CHECKCITY_CARGO_RATING) continue;
j++; j++;
@ -287,7 +287,7 @@ static bool AiNew_Check_City_or_Industry(Player *p, int ic, byte type) {
// It does not take this cargo // It does not take this cargo
if (!st->goods[i->produced_cargo[0]].last_speed) continue; if (!st->goods[i->produced_cargo[0]].last_speed) continue;
// Is it around our industry // Is it around our industry
if (GetTileDist(st->xy, i->xy) > 5) continue; if (DistanceManhattan(st->xy, i->xy) > 5) continue;
// It does take this cargo.. what is his rating? // It does take this cargo.. what is his rating?
if (st->goods[i->produced_cargo[0]].rating < AI_CHECKCITY_CARGO_RATING) continue; if (st->goods[i->produced_cargo[0]].rating < AI_CHECKCITY_CARGO_RATING) continue;
j++; j++;
@ -410,12 +410,17 @@ static void AiNew_State_LocateRoute(Player *p) {
max_cargo -= GetTown(p->ainew.from_ic)->act_pass + GetTown(p->ainew.temp)->act_pass; max_cargo -= GetTown(p->ainew.from_ic)->act_pass + GetTown(p->ainew.temp)->act_pass;
// max_cargo is now the amount of cargo we can move between the two cities // max_cargo is now the amount of cargo we can move between the two cities
// If it is more than the distance, we allow it // If it is more than the distance, we allow it
if (GetTileDist(GetTown(p->ainew.from_ic)->xy, GetTown(p->ainew.temp)->xy) <= max_cargo * AI_LOCATEROUTE_BUS_CARGO_DISTANCE) { if (DistanceManhattan(GetTown(p->ainew.from_ic)->xy, GetTown(p->ainew.temp)->xy) <= max_cargo * AI_LOCATEROUTE_BUS_CARGO_DISTANCE) {
// We found a good city/industry, save the data of it // We found a good city/industry, save the data of it
p->ainew.to_ic = p->ainew.temp; p->ainew.to_ic = p->ainew.temp;
p->ainew.state = AI_STATE_FIND_STATION; p->ainew.state = AI_STATE_FIND_STATION;
DEBUG(ai,1)("[AiNew - LocateRoute] Found bus-route of %d tiles long (from %d to %d)",GetTileDist(GetTown(p->ainew.from_ic)->xy, GetTown(p->ainew.temp)->xy), p->ainew.from_ic, p->ainew.temp); DEBUG(ai,1)(
"[AiNew - LocateRoute] Found bus-route of %d tiles long (from %d to %d)",
DistanceManhattan(GetTown(p->ainew.from_ic)->xy, GetTown(p->ainew.temp)->xy),
p->ainew.from_ic,
p->ainew.temp
);
p->ainew.from_tile = 0; p->ainew.from_tile = 0;
p->ainew.to_tile = 0; p->ainew.to_tile = 0;
@ -458,8 +463,8 @@ static void AiNew_State_LocateRoute(Player *p) {
if (found) { if (found) {
// Yeah, they are compatible!!! // Yeah, they are compatible!!!
// Check the length against the amount of goods // Check the length against the amount of goods
if (GetTileDist(GetIndustry(p->ainew.from_ic)->xy, GetIndustry(p->ainew.temp)->xy) > AI_LOCATEROUTE_TRUCK_MIN_DISTANCE && if (DistanceManhattan(GetIndustry(p->ainew.from_ic)->xy, GetIndustry(p->ainew.temp)->xy) > AI_LOCATEROUTE_TRUCK_MIN_DISTANCE &&
GetTileDist(GetIndustry(p->ainew.from_ic)->xy, GetIndustry(p->ainew.temp)->xy) <= max_cargo * AI_LOCATEROUTE_TRUCK_CARGO_DISTANCE) { DistanceManhattan(GetIndustry(p->ainew.from_ic)->xy, GetIndustry(p->ainew.temp)->xy) <= max_cargo * AI_LOCATEROUTE_TRUCK_CARGO_DISTANCE) {
p->ainew.to_ic = p->ainew.temp; p->ainew.to_ic = p->ainew.temp;
if (p->ainew.from_deliver) { if (p->ainew.from_deliver) {
p->ainew.cargo = GetIndustry(p->ainew.from_ic)->produced_cargo[0]; p->ainew.cargo = GetIndustry(p->ainew.from_ic)->produced_cargo[0];
@ -468,7 +473,12 @@ static void AiNew_State_LocateRoute(Player *p) {
} }
p->ainew.state = AI_STATE_FIND_STATION; p->ainew.state = AI_STATE_FIND_STATION;
DEBUG(ai,1)("[AiNew - LocateRoute] Found truck-route of %d tiles long (from %d to %d)",GetTileDist(GetIndustry(p->ainew.from_ic)->xy, GetIndustry(p->ainew.temp)->xy), p->ainew.from_ic, p->ainew.temp); DEBUG(ai,1)(
"[AiNew - LocateRoute] Found truck-route of %d tiles long (from %d to %d)",
DistanceManhattan(GetIndustry(p->ainew.from_ic)->xy, GetIndustry(p->ainew.temp)->xy),
p->ainew.from_ic,
p->ainew.temp
);
p->ainew.from_tile = 0; p->ainew.from_tile = 0;
p->ainew.to_tile = 0; p->ainew.to_tile = 0;
@ -637,7 +647,7 @@ static void AiNew_State_FindStation(Player *p) {
for (x=0;x<i;x++) { for (x=0;x<i;x++) {
if (found_best[x] > best || if (found_best[x] > best ||
(found_best[x] == best && GetTileDist(tile, new_tile) > GetTileDist(tile, found_spot[x]))) { (found_best[x] == best && DistanceManhattan(tile, new_tile) > DistanceManhattan(tile, found_spot[x]))) {
new_tile = found_spot[x]; new_tile = found_spot[x];
best = found_best[x]; best = found_best[x];
} }

View File

@ -153,12 +153,12 @@ static int32 AyStar_AiPathFinder_CalculateH(AyStar *aystar, AyStarNode *current,
int r, r2; int r, r2;
if (PathFinderInfo->end_direction != AI_PATHFINDER_NO_DIRECTION) { if (PathFinderInfo->end_direction != AI_PATHFINDER_NO_DIRECTION) {
// The station is pointing to a direction, add a tile towards that direction, so the H-value is more accurate // The station is pointing to a direction, add a tile towards that direction, so the H-value is more accurate
r = GetTileDist(current->tile, PathFinderInfo->end_tile_tl + TileOffsByDir(PathFinderInfo->end_direction)); r = DistanceManhattan(current->tile, PathFinderInfo->end_tile_tl + TileOffsByDir(PathFinderInfo->end_direction));
r2 = GetTileDist(current->tile, PathFinderInfo->end_tile_br + TileOffsByDir(PathFinderInfo->end_direction)); r2 = DistanceManhattan(current->tile, PathFinderInfo->end_tile_br + TileOffsByDir(PathFinderInfo->end_direction));
} else { } else {
// No direction, so just get the fastest route to the station // No direction, so just get the fastest route to the station
r = GetTileDist(current->tile, PathFinderInfo->end_tile_tl); r = DistanceManhattan(current->tile, PathFinderInfo->end_tile_tl);
r2 = GetTileDist(current->tile, PathFinderInfo->end_tile_br); r2 = DistanceManhattan(current->tile, PathFinderInfo->end_tile_br);
} }
// See if the bottomright is faster than the topleft.. // See if the bottomright is faster than the topleft..
if (r2 < r) r = r2; if (r2 < r) r = r2;

View File

@ -48,7 +48,7 @@ static uint32 FindNearestHangar(Vehicle *v)
// don't crash the planes if we know they can't land at the airport // don't crash the planes if we know they can't land at the airport
if (HASBIT(v->subtype,1) && st->airport_type == AT_SMALL && !_cheats.no_jetcrash.value) continue; if (HASBIT(v->subtype,1) && st->airport_type == AT_SMALL && !_cheats.no_jetcrash.value) continue;
temp_distance = GetTileDistAdv(v->tile, st->airport_tile); temp_distance = DistanceSquare(v->tile, st->airport_tile);
if (temp_distance < distance) { if (temp_distance < distance) {
distance = temp_distance; distance = temp_distance;
index_to_target = st->index; index_to_target = st->index;

View File

@ -896,7 +896,7 @@ static void FindSubsidyPassengerRoute(FoundRoute *fr)
if (from==to || to->xy == 0 || to->population < 400 || to->pct_pass_transported > 42) if (from==to || to->xy == 0 || to->population < 400 || to->pct_pass_transported > 42)
return; return;
fr->distance = GetTileDist(from->xy, to->xy); fr->distance = DistanceManhattan(from->xy, to->xy);
} }
static void FindSubsidyCargoRoute(FoundRoute *fr) static void FindSubsidyCargoRoute(FoundRoute *fr)
@ -937,7 +937,7 @@ static void FindSubsidyCargoRoute(FoundRoute *fr)
// Only want big towns // Only want big towns
if (t->xy == 0 || t->population < 900) if (t->xy == 0 || t->population < 900)
return; return;
fr->distance = GetTileDist(i->xy, t->xy); fr->distance = DistanceManhattan(i->xy, t->xy);
fr->to = t; fr->to = t;
} else { } else {
// The destination is an industry // The destination is an industry
@ -949,7 +949,7 @@ static void FindSubsidyCargoRoute(FoundRoute *fr)
cargo != i2->accepts_cargo[1] && cargo != i2->accepts_cargo[1] &&
cargo != i2->accepts_cargo[2])) cargo != i2->accepts_cargo[2]))
return; return;
fr->distance = GetTileDist(i->xy, i2->xy); fr->distance = DistanceManhattan(i->xy, i2->xy);
fr->to = i2; fr->to = i2;
} }
} }
@ -1132,7 +1132,7 @@ static void DeliverGoodsToIndustry(TileIndex xy, byte cargo_type, int num_pieces
== ind->accepts_cargo[1] || cargo_type == ind->accepts_cargo[2]) && == ind->accepts_cargo[1] || cargo_type == ind->accepts_cargo[2]) &&
ind->produced_cargo[0] != 0xFF && ind->produced_cargo[0] != 0xFF &&
ind->produced_cargo[0] != cargo_type && ind->produced_cargo[0] != cargo_type &&
(t=GetTileDist(ind->xy, xy)) < u) { (t = DistanceManhattan(ind->xy, xy)) < u) {
u = t; u = t;
best = ind; best = ind;
} }
@ -1171,7 +1171,7 @@ static bool CheckSubsidised(Station *from, Station *to, byte cargo_type)
} else { } else {
xy = (GetIndustry(s->from))->xy; xy = (GetIndustry(s->from))->xy;
} }
if (GetTileDist1D(xy, from->xy) > 9) if (DistanceMax(xy, from->xy) > 9)
continue; continue;
/* Check distance from dest */ /* Check distance from dest */
@ -1181,7 +1181,7 @@ static bool CheckSubsidised(Station *from, Station *to, byte cargo_type)
xy = (GetIndustry(s->to))->xy; xy = (GetIndustry(s->to))->xy;
} }
if (GetTileDist1D(xy, to->xy) > 9) if (DistanceMax(xy, to->xy) > 9)
continue; continue;
/* Found a subsidy, change the values to indicate that it's in use */ /* Found a subsidy, change the values to indicate that it's in use */
@ -1242,7 +1242,7 @@ static int32 DeliverGoods(int num_pieces, byte cargo_type, byte source, byte des
// Determine profit // Determine profit
{ {
int t = GetTileDist(s_from->xy, s_to->xy); int t = DistanceManhattan(s_from->xy, s_to->xy);
int r = num_pieces; int r = num_pieces;
profit = 0; profit = 0;
do { do {

View File

@ -169,12 +169,6 @@ void NetworkSend_Command(uint32 tile, uint32 p1, uint32 p2, uint32 cmd, CommandC
/* misc_cmd.c */ /* misc_cmd.c */
void PlaceTreesRandomly(void); void PlaceTreesRandomly(void);
uint GetTileDist(TileIndex xy1, TileIndex xy2);
uint GetTileDist1D(TileIndex xy1, TileIndex xy2);
uint GetTileDist1Db(TileIndex xy1, TileIndex xy2);
uint GetTileDistAdv(TileIndex xy1, TileIndex xy2);
bool CheckDistanceFromEdge(TileIndex tile, uint distance);
void InitializeLandscapeVariables(bool only_constants); void InitializeLandscapeVariables(bool only_constants);
/* misc.c */ /* misc.c */

View File

@ -1346,7 +1346,7 @@ static bool CheckIfIndustryTilesAreFree(uint tile, const IndustryTileTable *it,
return false; return false;
} }
} else if (type == IT_TOY_SHOP) { } else if (type == IT_TOY_SHOP) {
if (GetTileDist1D(t->xy, cur_tile) > 9) if (DistanceMax(t->xy, cur_tile) > 9)
return false; return false;
if (ti.type != MP_HOUSE) goto do_clear; if (ti.type != MP_HOUSE) goto do_clear;
} else if (type == IT_WATER_TOWER) { } else if (type == IT_WATER_TOWER) {
@ -1379,7 +1379,7 @@ static bool CheckIfTooCloseToIndustry(uint tile, int type)
FOR_ALL_INDUSTRIES(i) { FOR_ALL_INDUSTRIES(i) {
// check if an industry that accepts the same goods is nearby // check if an industry that accepts the same goods is nearby
if (i->xy != 0 && if (i->xy != 0 &&
(GetTileDist1D(tile, i->xy) <= 14) && (DistanceMax(tile, i->xy) <= 14) &&
spec->accepts_cargo[0] != 0xFF && spec->accepts_cargo[0] != 0xFF &&
spec->accepts_cargo[0] == i->accepts_cargo[0] && spec->accepts_cargo[0] == i->accepts_cargo[0] &&
!(_game_mode == GM_EDITOR && !(_game_mode == GM_EDITOR &&
@ -1392,7 +1392,7 @@ static bool CheckIfTooCloseToIndustry(uint tile, int type)
// check "not close to" field. // check "not close to" field.
if (i->xy != 0 && if (i->xy != 0 &&
(i->type == spec->a || i->type == spec->b || i->type == spec->c) && (i->type == spec->a || i->type == spec->b || i->type == spec->c) &&
GetTileDist1D(tile, i->xy) <= 14) { DistanceMax(tile, i->xy) <= 14) {
_error_message = STR_INDUSTRY_TOO_CLOSE; _error_message = STR_INDUSTRY_TOO_CLOSE;
return false; return false;
} }

44
map.c
View File

@ -108,6 +108,50 @@ uint ScaleByMapSize1D(uint n)
} }
uint DistanceManhattan(TileIndex t0, TileIndex t1)
{
return
abs(TileX(t0) - TileX(t1)) +
abs(TileY(t0) - TileY(t1));
}
uint DistanceSquare(TileIndex t0, TileIndex t1)
{
const int x = TileX(t0) - TileX(t1);
const int y = TileY(t0) - TileY(t1);
return x * x + y * y;
}
uint DistanceMax(TileIndex t0, TileIndex t1)
{
const uint x = abs(TileX(t0) - TileX(t1));
const uint y = abs(TileY(t0) - TileY(t1));
return x > y ? x : y;
}
uint DistanceMaxPlusManhattan(TileIndex t0, TileIndex t1)
{
const uint x = abs(TileX(t0) - TileX(t1));
const uint y = abs(TileY(t0) - TileY(t1));
return x > y ? 2 * x + y : 2 * y + x;
}
uint DistanceFromEdge(TileIndex tile)
{
const uint xl = TileX(tile);
const uint yl = TileY(tile);
const uint xh = MapSizeX() - 1 - xl;
const uint yh = MapSizeY() - 1 - yl;
const uint minl = xl < yl ? xl : yl;
const uint minh = xh < yh ? xh : yh;
return minl < minh ? minl : minh;
}
const TileIndexDiffC _tileoffs_by_dir[] = { const TileIndexDiffC _tileoffs_by_dir[] = {
{-1, 0}, {-1, 0},
{ 0, 1}, { 0, 1},

8
map.h
View File

@ -72,6 +72,14 @@ static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
#define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TILE_XY(x, y)) #define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TILE_XY(x, y))
// Functions to calculate distances
uint DistanceManhattan(TileIndex, TileIndex); // also known as L1-Norm
uint DistanceSquare(TileIndex, TileIndex); // euclidian- or L2-Norm squared
uint DistanceMax(TileIndex, TileIndex); // also known as L-Infinity-Norm
uint DistanceMaxPlusManhattan(TileIndex, TileIndex); // Max + Manhattan
uint DistanceFromEdge(TileIndex); // shortest distance from any edge of the map
static inline TileIndexDiff TileOffsByDir(uint dir) static inline TileIndexDiff TileOffsByDir(uint dir)
{ {
extern const TileIndexDiffC _tileoffs_by_dir[4]; extern const TileIndexDiffC _tileoffs_by_dir[4];

37
misc.c
View File

@ -533,43 +533,6 @@ void InitializeLandscapeVariables(bool only_constants)
} }
} }
// distance in Manhattan metric
uint GetTileDist(TileIndex xy1, TileIndex xy2)
{
return myabs(TileX(xy1) - TileX(xy2)) +
myabs(TileY(xy1) - TileY(xy2));
}
// maximum distance in x _or_ y
uint GetTileDist1D(TileIndex xy1, TileIndex xy2)
{
return max(myabs(TileX(xy1) - TileX(xy2)),
myabs(TileY(xy1) - TileY(xy2)));
}
uint GetTileDist1Db(TileIndex xy1, TileIndex xy2)
{
int a = myabs(TileX(xy1) - TileX(xy2));
int b = myabs(TileY(xy1) - TileY(xy2));
if (a > b)
return a*2+b;
else
return b*2+a;
}
uint GetTileDistAdv(TileIndex xy1, TileIndex xy2)
{
uint a = myabs(TileX(xy1) - TileX(xy2));
uint b = myabs(TileY(xy1) - TileY(xy2));
return a*a+b*b;
}
bool CheckDistanceFromEdge(TileIndex tile, uint distance)
{
return IS_INT_INSIDE(TileX(tile), distance, MapSizeX() - distance) &&
IS_INT_INSIDE(TileY(tile), distance, MapSizeY() - distance);
}
void OnNewDay_Train(Vehicle *v); void OnNewDay_Train(Vehicle *v);
void OnNewDay_RoadVeh(Vehicle *v); void OnNewDay_RoadVeh(Vehicle *v);

View File

@ -140,7 +140,7 @@ int32 CmdInsertOrder(int x, int y, uint32 flags, uint32 veh_sel, uint32 packed_o
if (v->type == VEH_Ship && IS_HUMAN_PLAYER(v->owner) && if (v->type == VEH_Ship && IS_HUMAN_PLAYER(v->owner) &&
sel != 0 && GetVehicleOrder(v, sel - 1)->type == OT_GOTO_STATION) { sel != 0 && GetVehicleOrder(v, sel - 1)->type == OT_GOTO_STATION) {
int dist = GetTileDist( int dist = DistanceManhattan(
GetStation(GetVehicleOrder(v, sel - 1)->station)->xy, GetStation(GetVehicleOrder(v, sel - 1)->station)->xy,
GetStation(new_order.station)->xy GetStation(new_order.station)->xy
); );

View File

@ -701,7 +701,7 @@ static Waypoint *FindDeletedWaypointCloseTo(uint tile)
for(cp = _waypoints; cp != endof(_waypoints); cp++) { for(cp = _waypoints; cp != endof(_waypoints); cp++) {
if (cp->deleted && cp->xy) { if (cp->deleted && cp->xy) {
cur_dist = GetTileDist(tile, cp->xy); cur_dist = DistanceManhattan(tile, cp->xy);
if (cur_dist < thres) { if (cur_dist < thres) {
thres = cur_dist; thres = cur_dist;
best = cp; best = cp;

View File

@ -973,7 +973,7 @@ static void TileLoop_Road(uint tile)
// Show an animation to indicate road work // Show an animation to indicate road work
if (t->road_build_months != 0 && if (t->road_build_months != 0 &&
!(GetTileDist(t->xy, tile) >= 8 && grp==0) && !(DistanceManhattan(t->xy, tile) >= 8 && grp == 0) &&
(_map5[tile]==5 || _map5[tile]==10)) { (_map5[tile]==5 || _map5[tile]==10)) {
if (GetTileSlope(tile, NULL) == 0 && EnsureNoVehicle(tile) && CHANCE16(1,20)) { if (GetTileSlope(tile, NULL) == 0 && EnsureNoVehicle(tile) && CHANCE16(1,20)) {
_map2[tile] = ((_map2[tile]&7) <= 1) ? 6 : 7; _map2[tile] = ((_map2[tile]&7) <= 1) ? 6 : 7;

View File

@ -651,7 +651,7 @@ static void ProcessRoadVehOrder(Vehicle *v)
dist = malloc(num * sizeof(int32)); dist = malloc(num * sizeof(int32));
do { do {
*dist = GetTileDistAdv(v->tile, rs->xy); *dist = DistanceSquare(v->tile, rs->xy);
if (*dist < mindist) { if (*dist < mindist) {
v->dest_tile = rs->xy; v->dest_tile = rs->xy;
} }
@ -999,7 +999,7 @@ typedef struct {
static bool EnumRoadTrackFindDist(uint tile, FindRoadToChooseData *frd, int track, uint length, byte *state) static bool EnumRoadTrackFindDist(uint tile, FindRoadToChooseData *frd, int track, uint length, byte *state)
{ {
uint dist = GetTileDist(tile, frd->dest); uint dist = DistanceManhattan(tile, frd->dest);
if (dist <= frd->mindist) { if (dist <= frd->mindist) {
if (dist != frd->mindist || length < frd->maxtracklen) { if (dist != frd->mindist || length < frd->maxtracklen) {
frd->maxtracklen = length; frd->maxtracklen = length;
@ -1577,9 +1577,9 @@ static void CheckIfRoadVehNeedsService(Vehicle *v)
i = FindClosestRoadDepot(v); i = FindClosestRoadDepot(v);
if (i < 0 || GetTileDist(v->tile, (&_depots[i])->xy) > 12) { if (i < 0 || DistanceManhattan(v->tile, (&_depots[i])->xy) > 12) {
if (v->current_order.type == OT_GOTO_DEPOT && !( if (v->current_order.type == OT_GOTO_DEPOT && !(
GetTileDist(v->tile, v->dest_tile) > 25 && v->set_for_replacement)) { DistanceManhattan(v->tile, v->dest_tile) > 25 && v->set_for_replacement)) {
/* a vehicle needs a greater distance to a depot to loose it than to find it since /* a vehicle needs a greater distance to a depot to loose it than to find it since
they can circle forever othervise if they are in a loop with an unlucky distance */ they can circle forever othervise if they are in a loop with an unlucky distance */
v->current_order.type = OT_DUMMY; v->current_order.type = OT_DUMMY;

View File

@ -73,7 +73,7 @@ static int FindClosestShipDepot(Vehicle *v)
for(i=0; i!=lengthof(_depots); i++) { for(i=0; i!=lengthof(_depots); i++) {
tile = _depots[i].xy; tile = _depots[i].xy;
if (IsTileType(tile, MP_WATER) && _map_owner[tile] == owner) { if (IsTileType(tile, MP_WATER) && _map_owner[tile] == owner) {
dist = GetTileDist(tile, tile2); dist = DistanceManhattan(tile, tile2);
if (dist < best_dist) { if (dist < best_dist) {
best_dist = dist; best_dist = dist;
best_depot = i; best_depot = i;
@ -106,7 +106,7 @@ static void CheckIfShipNeedsService(Vehicle *v)
i = FindClosestShipDepot(v); i = FindClosestShipDepot(v);
if (i < 0 || GetTileDist(v->tile, (&_depots[i])->xy) > 12) { if (i < 0 || DistanceManhattan(v->tile, (&_depots[i])->xy) > 12) {
if (v->current_order.type == OT_GOTO_DEPOT) { if (v->current_order.type == OT_GOTO_DEPOT) {
v->current_order.type = OT_DUMMY; v->current_order.type = OT_DUMMY;
v->current_order.flags = 0; v->current_order.flags = 0;
@ -499,7 +499,7 @@ static bool ShipTrackFollower(uint tile, PathFindShip *pfs, int track, uint leng
// Skip this tile in the calculation // Skip this tile in the calculation
if (tile != pfs->skiptile) { if (tile != pfs->skiptile) {
pfs->best_bird_dist = minu(pfs->best_bird_dist, GetTileDist1Db(pfs->dest_coords, tile)); pfs->best_bird_dist = minu(pfs->best_bird_dist, DistanceMaxPlusManhattan(pfs->dest_coords, tile));
} }
return false; return false;

View File

@ -318,7 +318,7 @@ static bool GenerateStationName(Station *st, uint tile, int flag)
} }
/* check close enough to town to get central as name? */ /* check close enough to town to get central as name? */
if (GetTileDist1D(tile,t->xy) < 8) { if (DistanceMax(tile,t->xy) < 8) {
found = M(STR_SV_STNAME); found = M(STR_SV_STNAME);
if (HASBIT(free_names, M(STR_SV_STNAME))) goto done; if (HASBIT(free_names, M(STR_SV_STNAME))) goto done;
@ -328,7 +328,7 @@ static bool GenerateStationName(Station *st, uint tile, int flag)
/* Check lakeside */ /* Check lakeside */
if (HASBIT(free_names, M(STR_SV_STNAME_LAKESIDE)) && if (HASBIT(free_names, M(STR_SV_STNAME_LAKESIDE)) &&
!CheckDistanceFromEdge(tile, 20) && DistanceFromEdge(tile) < 20 &&
CountMapSquareAround(tile, MP_WATER, 0, 0) >= 5) { CountMapSquareAround(tile, MP_WATER, 0, 0) >= 5) {
found = M(STR_SV_STNAME_LAKESIDE); found = M(STR_SV_STNAME_LAKESIDE);
goto done; goto done;
@ -386,7 +386,7 @@ static Station *GetClosestStationFromTile(uint tile, uint threshold, byte owner)
uint cur_dist; uint cur_dist;
FOR_ALL_STATIONS(st) { FOR_ALL_STATIONS(st) {
cur_dist = GetTileDist(tile, st->xy); cur_dist = DistanceManhattan(tile, st->xy);
if (cur_dist < threshold && (owner == 0xFF || st->owner == owner) && (st->xy != 0)) { if (cur_dist < threshold && (owner == 0xFF || st->owner == owner) && (st->xy != 0)) {
threshold = cur_dist; threshold = cur_dist;
best_station = st; best_station = st;
@ -2591,7 +2591,8 @@ void ModifyStationRatingAround(TileIndex tile, byte owner, int amount, uint radi
int i; int i;
FOR_ALL_STATIONS(st) { FOR_ALL_STATIONS(st) {
if (st->xy != 0 && st->owner == owner && GetTileDist(tile, st->xy) <= radius) { if (st->xy != 0 && st->owner == owner &&
DistanceManhattan(tile, st->xy) <= radius) {
ge = st->goods; ge = st->goods;
for(i=0; i!=NUM_CARGO; i++,ge++) { for(i=0; i!=NUM_CARGO; i++,ge++) {
if (ge->enroute_from != 0xFF) { if (ge->enroute_from != 0xFF) {

View File

@ -166,7 +166,7 @@ static bool IsCloseToTown(uint tile, uint dist)
Town *t; Town *t;
FOR_ALL_TOWNS(t) { FOR_ALL_TOWNS(t) {
if (t->xy != 0 && GetTileDist(tile, t->xy) < dist) if (t->xy != 0 && DistanceManhattan(tile, t->xy) < dist)
return true; return true;
} }
return false; return false;
@ -970,7 +970,7 @@ int32 CmdBuildTown(int x, int y, uint32 flags, uint32 p1, uint32 p2)
SET_EXPENSES_TYPE(EXPENSES_OTHER); SET_EXPENSES_TYPE(EXPENSES_OTHER);
// Check if too close to the edge of map // Check if too close to the edge of map
if (!CheckDistanceFromEdge(tile, 12)) if (DistanceFromEdge(tile) < 12)
return_cmd_error(STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP); return_cmd_error(STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP);
// Can only build on clear flat areas. // Can only build on clear flat areas.
@ -1008,7 +1008,7 @@ Town *CreateRandomTown(void)
do { do {
// Generate a tile index not too close from the edge // Generate a tile index not too close from the edge
tile = TILE_MASK(Random()); tile = TILE_MASK(Random());
if (!CheckDistanceFromEdge(tile, 20)) if (DistanceFromEdge(tile) < 20)
continue; continue;
// Make sure the tile is plain // Make sure the tile is plain
@ -1074,7 +1074,7 @@ int GetTownRadiusGroup(Town *t, uint tile)
uint dist; uint dist;
int i,smallest; int i,smallest;
dist = GetTileDistAdv(tile, t->xy); dist = DistanceSquare(tile, t->xy);
if (t->fund_buildings_months && dist <= 25) if (t->fund_buildings_months && dist <= 25)
return 4; return 4;
@ -1637,7 +1637,7 @@ static void UpdateTownGrowRate(Town *t)
n = 0; n = 0;
FOR_ALL_STATIONS(st) { FOR_ALL_STATIONS(st) {
if (GetTileDistAdv(st->xy, t->xy) <= t->radius[0]) { if (DistanceSquare(st->xy, t->xy) <= t->radius[0]) {
if (st->time_since_load <= 20 || st->time_since_unload <= 20) { if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
n++; n++;
if (st->owner < MAX_PLAYERS && t->ratings[st->owner] <= 1000-12) if (st->owner < MAX_PLAYERS && t->ratings[st->owner] <= 1000-12)
@ -1740,7 +1740,7 @@ Town *ClosestTownFromTile(uint tile, uint threshold)
FOR_ALL_TOWNS(t) { FOR_ALL_TOWNS(t) {
if (t->xy != 0) { if (t->xy != 0) {
dist = GetTileDist(tile, t->xy); dist = DistanceManhattan(tile, t->xy);
if (dist < best) { if (dist < best) {
best = dist; best = dist;
best_town = t; best_town = t;

View File

@ -1598,7 +1598,7 @@ static bool TrainTrackFollower(uint tile, TrainTrackFollowerData *ttfd, int trac
return length >= ttfd->best_track_dist; return length >= ttfd->best_track_dist;
// didn't find station // didn't find station
dist = GetTileDist(tile, ttfd->dest_coords); dist = DistanceManhattan(tile, ttfd->dest_coords);
if (dist < ttfd->best_bird_dist) { if (dist < ttfd->best_bird_dist) {
ttfd->best_bird_dist = dist; ttfd->best_bird_dist = dist;
ttfd->best_track = state[1]; ttfd->best_track = state[1];