ai.c
changeset 1245 768d9bc95aaa
parent 1224 09b0f5a1db97
child 1313 bba6afb8a995
equal deleted inserted replaced
1244:7c87de28da3c 1245:768d9bc95aaa
   460 		to_ind = GetIndustry(s->to);
   460 		to_ind = GetIndustry(s->to);
   461 		fr->to = to_ind;
   461 		fr->to = to_ind;
   462 		to_xy = to_ind->xy;
   462 		to_xy = to_ind->xy;
   463 	}
   463 	}
   464 
   464 
   465 	fr->distance = GetTileDist(from->xy, to_xy);
   465 	fr->distance = DistanceManhattan(from->xy, to_xy);
   466 }
   466 }
   467 
   467 
   468 static void AiFindSubsidyPassengerRoute(FoundRoute *fr)
   468 static void AiFindSubsidyPassengerRoute(FoundRoute *fr)
   469 {
   469 {
   470 	uint i;
   470 	uint i;
   491 
   491 
   492 	// They must be big enough
   492 	// They must be big enough
   493 	if (from->population < 400 || to->population < 400)
   493 	if (from->population < 400 || to->population < 400)
   494 		return;
   494 		return;
   495 
   495 
   496 	fr->distance = GetTileDist(from->xy, to->xy);
   496 	fr->distance = DistanceManhattan(from->xy, to->xy);
   497 }
   497 }
   498 
   498 
   499 static void AiFindRandomIndustryRoute(FoundRoute *fr)
   499 static void AiFindRandomIndustryRoute(FoundRoute *fr)
   500 {
   500 {
   501 	Industry *i,*i2;
   501 	Industry *i,*i2;
   529 		i2 = AiFindRandomIndustry();
   529 		i2 = AiFindRandomIndustry();
   530 		if (i2 == NULL || i == i2 || !(i2->accepts_cargo[0] == cargo || i2->accepts_cargo[1] == cargo || i2->accepts_cargo[2] == cargo))
   530 		if (i2 == NULL || i == i2 || !(i2->accepts_cargo[0] == cargo || i2->accepts_cargo[1] == cargo || i2->accepts_cargo[2] == cargo))
   531 			return;
   531 			return;
   532 
   532 
   533 		fr->to = i2;
   533 		fr->to = i2;
   534 		fr->distance = GetTileDist(i->xy, i2->xy);
   534 		fr->distance = DistanceManhattan(i->xy, i2->xy);
   535 	} else {
   535 	} else {
   536 		// pick a dest town, and see if it's big enough
   536 		// pick a dest town, and see if it's big enough
   537 		t = AiFindRandomTown();
   537 		t = AiFindRandomTown();
   538 		if (t == NULL || t->population < (uint32)(cargo == CT_FOOD ? 200 : 900))
   538 		if (t == NULL || t->population < (uint32)(cargo == CT_FOOD ? 200 : 900))
   539 			return;
   539 			return;
   540 
   540 
   541 		fr->to = t;
   541 		fr->to = t;
   542 		fr->distance = GetTileDist(i->xy, t->xy);
   542 		fr->distance = DistanceManhattan(i->xy, t->xy);
   543 	}
   543 	}
   544 }
   544 }
   545 
   545 
   546 static void AiFindRandomPassengerRoute(FoundRoute *fr)
   546 static void AiFindRandomPassengerRoute(FoundRoute *fr)
   547 {
   547 {
   559 
   559 
   560 	fr->to = dest = AiFindRandomTown();
   560 	fr->to = dest = AiFindRandomTown();
   561 	if (dest == NULL || source == dest || dest->population < 400)
   561 	if (dest == NULL || source == dest || dest->population < 400)
   562 		return;
   562 		return;
   563 
   563 
   564 	fr->distance = GetTileDist(source->xy, dest->xy);
   564 	fr->distance = DistanceManhattan(source->xy, dest->xy);
   565 }
   565 }
   566 
   566 
   567 // Warn: depends on 'xy' being the first element in both Town and Industry
   567 // Warn: depends on 'xy' being the first element in both Town and Industry
   568 #define GET_TOWN_OR_INDUSTRY_TILE(p) (((Town*)(p))->xy)
   568 #define GET_TOWN_OR_INDUSTRY_TILE(p) (((Town*)(p))->xy)
   569 
   569 
   578 	from_tile = GET_TOWN_OR_INDUSTRY_TILE(fr->from);
   578 	from_tile = GET_TOWN_OR_INDUSTRY_TILE(fr->from);
   579 	to_tile = GET_TOWN_OR_INDUSTRY_TILE(fr->to);
   579 	to_tile = GET_TOWN_OR_INDUSTRY_TILE(fr->to);
   580 
   580 
   581 	dist = 0xFFFF;
   581 	dist = 0xFFFF;
   582 	FOR_ALL_STATIONS(st) if (st->xy != 0 && st->owner == _current_player) {
   582 	FOR_ALL_STATIONS(st) if (st->xy != 0 && st->owner == _current_player) {
   583 		cur = GetTileDist1D(from_tile, st->xy);
   583 		cur = DistanceMax(from_tile, st->xy);
   584 		if (cur < dist) dist = cur;
   584 		if (cur < dist) dist = cur;
   585 		cur = GetTileDist1D(to_tile, st->xy);
   585 		cur = DistanceMax(to_tile, st->xy);
   586 		if (cur < dist) dist = cur;
   586 		if (cur < dist) dist = cur;
   587 		if (to_tile == from_tile && st->xy == to_tile)
   587 		if (to_tile == from_tile && st->xy == to_tile)
   588 		    same_station++;
   588 		    same_station++;
   589 	}
   589 	}
   590 
   590 
  1417 		t = AiFindRandomTown();
  1417 		t = AiFindRandomTown();
  1418 		if (t != NULL) {
  1418 		if (t != NULL) {
  1419 			// Find a random oil rig industry
  1419 			// Find a random oil rig industry
  1420 			in = GetIndustry(RandomRange(_total_industries));
  1420 			in = GetIndustry(RandomRange(_total_industries));
  1421 			if (in != NULL && in->type == IT_OIL_RIG) {
  1421 			if (in != NULL && in->type == IT_OIL_RIG) {
  1422 				if (GetTileDist(t->xy, in->xy) < 60)
  1422 				if (DistanceManhattan(t->xy, in->xy) < 60)
  1423 					break;
  1423 					break;
  1424 			}
  1424 			}
  1425 		}
  1425 		}
  1426 
  1426 
  1427 		// only test 60 times
  1427 		// only test 60 times
  1841 	if (length > 20 || tile == a->tile) {
  1841 	if (length > 20 || tile == a->tile) {
  1842 		a->flag = true;
  1842 		a->flag = true;
  1843 		return true;
  1843 		return true;
  1844 	}
  1844 	}
  1845 
  1845 
  1846 	if (GetTileDist1D(tile, a->tile2) < 4)
  1846 	if (DistanceMax(tile, a->tile2) < 4)
  1847 		a->count++;
  1847 		a->count++;
  1848 
  1848 
  1849 	return false;
  1849 	return false;
  1850 }
  1850 }
  1851 
  1851 
  2026 		return;
  2026 		return;
  2027 	}
  2027 	}
  2028 
  2028 
  2029 	// Depth too deep?
  2029 	// Depth too deep?
  2030 	if (arf->depth >= 4) {
  2030 	if (arf->depth >= 4) {
  2031 		uint dist = GetTileDist1Db(tile, arf->final_tile);
  2031 		uint dist = DistanceMaxPlusManhattan(tile, arf->final_tile);
  2032 		if (dist < arf->cur_best_dist) {
  2032 		if (dist < arf->cur_best_dist) {
  2033 			// Store the tile that is closest to the final position.
  2033 			// Store the tile that is closest to the final position.
  2034 			arf->cur_best_depth = arf->depth;
  2034 			arf->cur_best_depth = arf->depth;
  2035 			arf->cur_best_dist = dist;
  2035 			arf->cur_best_dist = dist;
  2036 			arf->cur_best_tile = tile;
  2036 			arf->cur_best_tile = tile;
  2618 	num = p->ai.num_build_rec;
  2618 	num = p->ai.num_build_rec;
  2619 	aib = &p->ai.src;
  2619 	aib = &p->ai.src;
  2620 
  2620 
  2621 	do {
  2621 	do {
  2622 		if (aib->cur_building_rule != 255) {
  2622 		if (aib->cur_building_rule != 255) {
  2623 			if (GetTileDist(aib->use_tile, tile) < 9)
  2623 			if (DistanceManhattan(aib->use_tile, tile) < 9)
  2624 				return false;
  2624 				return false;
  2625 		}
  2625 		}
  2626 	} while (++aib, --num);
  2626 	} while (++aib, --num);
  2627 
  2627 
  2628 	return true;
  2628 	return true;
  2766 }
  2766 }
  2767 
  2767 
  2768 
  2768 
  2769 static bool AiEnumFollowRoad(uint tile, AiRoadEnum *a, int track, uint length, byte *state)
  2769 static bool AiEnumFollowRoad(uint tile, AiRoadEnum *a, int track, uint length, byte *state)
  2770 {
  2770 {
  2771 	uint dist = GetTileDist(tile, a->dest);
  2771 	uint dist = DistanceManhattan(tile, a->dest);
  2772 	uint tile2;
  2772 	uint tile2;
  2773 
  2773 
  2774 	if (dist <= a->best_dist) {
  2774 	if (dist <= a->best_dist) {
  2775 		tile2 = TILE_MASK(tile + TileOffsByDir(_dir_by_track[track]));
  2775 		tile2 = TILE_MASK(tile + TileOffsByDir(_dir_by_track[track]));
  2776 		if (IsTileType(tile2, MP_STREET) &&
  2776 		if (IsTileType(tile2, MP_STREET) &&
  2811 
  2811 
  2812 	for_each_bit(i, bits) {
  2812 	for_each_bit(i, bits) {
  2813 		FollowTrack(tile, 0x3000 | TRANSPORT_ROAD, _dir_by_track[i], (TPFEnumProc*)AiEnumFollowRoad, NULL, &are);
  2813 		FollowTrack(tile, 0x3000 | TRANSPORT_ROAD, _dir_by_track[i], (TPFEnumProc*)AiEnumFollowRoad, NULL, &are);
  2814 	}
  2814 	}
  2815 
  2815 
  2816 	if (GetTileDist(tile, are.dest) <= are.best_dist)
  2816 	if (DistanceManhattan(tile, are.dest) <= are.best_dist)
  2817 		return false;
  2817 		return false;
  2818 
  2818 
  2819 	if (are.best_dist == 0)
  2819 	if (are.best_dist == 0)
  2820 		return true;
  2820 		return true;
  2821 
  2821 
  2911 		return;
  2911 		return;
  2912 	}
  2912 	}
  2913 
  2913 
  2914 	// Depth too deep?
  2914 	// Depth too deep?
  2915 	if (arf->depth >= 4) {
  2915 	if (arf->depth >= 4) {
  2916 		uint dist = GetTileDist1Db(tile, arf->final_tile);
  2916 		uint dist = DistanceMaxPlusManhattan(tile, arf->final_tile);
  2917 		if (dist < arf->cur_best_dist) {
  2917 		if (dist < arf->cur_best_dist) {
  2918 			// Store the tile that is closest to the final position.
  2918 			// Store the tile that is closest to the final position.
  2919 			arf->cur_best_dist = dist;
  2919 			arf->cur_best_dist = dist;
  2920 			arf->cur_best_tile = tile;
  2920 			arf->cur_best_tile = tile;
  2921 			arf->cur_best_dir = dir;
  2921 			arf->cur_best_dir = dir;
  3290 			// endpoint of an oilrig route.
  3290 			// endpoint of an oilrig route.
  3291 			if (acc_planes == AIRCRAFT_ONLY && (p->ai.build_kind == 1 && i == 0))
  3291 			if (acc_planes == AIRCRAFT_ONLY && (p->ai.build_kind == 1 && i == 0))
  3292 				continue;
  3292 				continue;
  3293 
  3293 
  3294 			// Dismiss airports too far away.
  3294 			// Dismiss airports too far away.
  3295 			if (GetTileDist1D(st->airport_tile, aib->spec_tile) > aib->rand_rng)
  3295 			if (DistanceMax(st->airport_tile, aib->spec_tile) > aib->rand_rng)
  3296 				continue;
  3296 				continue;
  3297 
  3297 
  3298 			// It's ideal airport, let's take it!
  3298 			// It's ideal airport, let's take it!
  3299 
  3299 
  3300 			/* XXX: This part is utterly broken - rule should
  3300 			/* XXX: This part is utterly broken - rule should