src/ai/default/default.cpp
changeset 7813 49fbe41f8a04
parent 7486 d130c10f4dab
child 7866 e19fda04e8d3
equal deleted inserted replaced
7812:9e652ca4827b 7813:49fbe41f8a04
  1772 	5,  6, 2,  8,
  1772 	5,  6, 2,  8,
  1773 	9, 10, 1, 12,
  1773 	9, 10, 1, 12,
  1774 	8,  4
  1774 	8,  4
  1775 };
  1775 };
  1776 
  1776 
  1777 static void AiDoTerraformLand(TileIndex tile, int dir, int unk, int mode)
  1777 static void AiDoTerraformLand(TileIndex tile, DiagDirection dir, int unk, int mode)
  1778 {
  1778 {
  1779 	PlayerID old_player;
  1779 	PlayerID old_player;
  1780 	uint32 r;
  1780 	uint32 r;
  1781 	Slope slope;
  1781 	Slope slope;
  1782 	uint h;
  1782 	uint h;
  1791 	do {
  1791 	do {
  1792 		tile = TILE_MASK(tile + TileOffsByDiagDir(dir));
  1792 		tile = TILE_MASK(tile + TileOffsByDiagDir(dir));
  1793 
  1793 
  1794 		r >>= 2;
  1794 		r >>= 2;
  1795 		if (r & 2) {
  1795 		if (r & 2) {
  1796 			dir++;
  1796 			dir = ChangeDiagDir(dir, (r & 1) ? DIAGDIRDIFF_90LEFT : DIAGDIRDIFF_90RIGHT);
  1797 			if (r & 1) dir -= 2;
  1797 		}
  1798 		}
       
  1799 		dir &= 3;
       
  1800 	} while (--unk >= 0);
  1798 	} while (--unk >= 0);
  1801 
  1799 
  1802 	slope = GetTileSlope(tile, &h);
  1800 	slope = GetTileSlope(tile, &h);
  1803 
  1801 
  1804 	if (slope != SLOPE_FLAT) {
  1802 	if (slope != SLOPE_FLAT) {
  1853 			);
  1851 			);
  1854 
  1852 
  1855 			if (rule == -1) {
  1853 			if (rule == -1) {
  1856 				// cannot build, terraform after a while
  1854 				// cannot build, terraform after a while
  1857 				if (p->ai.state_counter >= 600) {
  1855 				if (p->ai.state_counter >= 600) {
  1858 					AiDoTerraformLand(aib->use_tile, Random() & 3, 3, (int8)p->ai.state_mode);
  1856 					AiDoTerraformLand(aib->use_tile, (DiagDirection)(Random() & 3), 3, (int8)p->ai.state_mode);
  1859 				}
  1857 				}
  1860 				// also try the other terraform direction
  1858 				// also try the other terraform direction
  1861 				if (++p->ai.state_counter >= 1000) {
  1859 				if (++p->ai.state_counter >= 1000) {
  1862 					p->ai.state_counter = 0;
  1860 					p->ai.state_counter = 0;
  1863 					p->ai.state_mode = -p->ai.state_mode;
  1861 					p->ai.state_mode = -p->ai.state_mode;
  1886 	// yep, all are done. switch state to the rail building state.
  1884 	// yep, all are done. switch state to the rail building state.
  1887 	p->ai.state = AIS_BUILD_RAIL;
  1885 	p->ai.state = AIS_BUILD_RAIL;
  1888 	p->ai.state_mode = 255;
  1886 	p->ai.state_mode = 255;
  1889 }
  1887 }
  1890 
  1888 
  1891 static TileIndex AiGetEdgeOfDefaultRailBlock(byte rule, TileIndex tile, byte cmd, int *dir)
  1889 static TileIndex AiGetEdgeOfDefaultRailBlock(byte rule, TileIndex tile, byte cmd, DiagDirection *dir)
  1892 {
  1890 {
  1893 	const AiDefaultBlockData *p = _default_rail_track_data[rule]->data;
  1891 	const AiDefaultBlockData *p = _default_rail_track_data[rule]->data;
  1894 
  1892 
  1895 	while (p->mode != 3 || !((--cmd) & 0x80)) p++;
  1893 	while (p->mode != 3 || !((--cmd) & 0x80)) p++;
  1896 
  1894 
  1924 
  1922 
  1925 	arpfd.tile = p->ai.start_tile_a;
  1923 	arpfd.tile = p->ai.start_tile_a;
  1926 	arpfd.tile2 = p->ai.cur_tile_a;
  1924 	arpfd.tile2 = p->ai.cur_tile_a;
  1927 	arpfd.flag = false;
  1925 	arpfd.flag = false;
  1928 	arpfd.count = 0;
  1926 	arpfd.count = 0;
  1929 	FollowTrack(p->ai.cur_tile_a + TileOffsByDiagDir(p->ai.cur_dir_a), 0x2000 | TRANSPORT_RAIL, 0, (DiagDirection)(p->ai.cur_dir_a ^ 2),
  1927 	FollowTrack(p->ai.cur_tile_a + TileOffsByDiagDir(p->ai.cur_dir_a), 0x2000 | TRANSPORT_RAIL, 0, ReverseDiagDir(p->ai.cur_dir_a),
  1930 		(TPFEnumProc*)AiEnumFollowTrack, NULL, &arpfd);
  1928 		(TPFEnumProc*)AiEnumFollowTrack, NULL, &arpfd);
  1931 	return arpfd.count > 8;
  1929 	return arpfd.count > 8;
  1932 }
  1930 }
  1933 
  1931 
  1934 struct AiRailFinder {
  1932 struct AiRailFinder {
  1935 	TileIndex final_tile;
  1933 	TileIndex final_tile;
  1936 	byte final_dir;
  1934 	DiagDirection final_dir;
  1937 	byte depth;
  1935 	byte depth;
  1938 	byte recursive_mode;
  1936 	byte recursive_mode;
  1939 	byte cur_best_dir;
  1937 	DiagDirection cur_best_dir;
  1940 	byte best_dir;
  1938 	DiagDirection best_dir;
  1941 	byte cur_best_depth;
  1939 	byte cur_best_depth;
  1942 	byte best_depth;
  1940 	byte best_depth;
  1943 	uint cur_best_dist;
  1941 	uint cur_best_dist;
  1944 	const byte *best_ptr;
  1942 	const byte *best_ptr;
  1945 	uint best_dist;
  1943 	uint best_dist;
  1986 	if (p->ai.banned_tile_count != lengthof(p->ai.banned_tiles)) {
  1984 	if (p->ai.banned_tile_count != lengthof(p->ai.banned_tiles)) {
  1987 		p->ai.banned_tile_count++;
  1985 		p->ai.banned_tile_count++;
  1988 	}
  1986 	}
  1989 }
  1987 }
  1990 
  1988 
  1991 static void AiBuildRailRecursive(AiRailFinder *arf, TileIndex tile, int dir);
  1989 static void AiBuildRailRecursive(AiRailFinder *arf, TileIndex tile, DiagDirection dir);
  1992 
  1990 
  1993 static bool AiCheckRailPathBetter(AiRailFinder *arf, const byte *p)
  1991 static bool AiCheckRailPathBetter(AiRailFinder *arf, const byte *p)
  1994 {
  1992 {
  1995 	bool better = false;
  1993 	bool better = false;
  1996 
  1994 
  2025 {
  2023 {
  2026 	Slope tileh;
  2024 	Slope tileh;
  2027 	uint z;
  2025 	uint z;
  2028 	bool flag;
  2026 	bool flag;
  2029 
  2027 
  2030 	int dir2 = p[0] & 3;
  2028 	DiagDirection dir2 = (DiagDirection)(p[0] & 3);
  2031 
  2029 
  2032 	tileh = GetTileSlope(tile, &z);
  2030 	tileh = GetTileSlope(tile, &z);
  2033 	if (tileh == _dir_table_1[dir2] || (tileh == SLOPE_FLAT && z != 0)) {
  2031 	if (tileh == _dir_table_1[dir2] || (tileh == SLOPE_FLAT && z != 0)) {
  2034 		TileIndex tile_new = tile;
  2032 		TileIndex tile_new = tile;
  2035 
  2033 
  2069 
  2067 
  2070 	if (GetTileSlope(tile, &z) == _dir_table_2[p[0] & 3] && z != 0) {
  2068 	if (GetTileSlope(tile, &z) == _dir_table_2[p[0] & 3] && z != 0) {
  2071 		CommandCost cost = DoCommand(tile, arf->player->ai.railtype_to_use, 0, DC_AUTO, CMD_BUILD_TUNNEL);
  2069 		CommandCost cost = DoCommand(tile, arf->player->ai.railtype_to_use, 0, DC_AUTO, CMD_BUILD_TUNNEL);
  2072 
  2070 
  2073 		if (CmdSucceeded(cost) && cost.GetCost() <= (arf->player->player_money >> 4)) {
  2071 		if (CmdSucceeded(cost) && cost.GetCost() <= (arf->player->player_money >> 4)) {
  2074 			AiBuildRailRecursive(arf, _build_tunnel_endtile, p[0] & 3);
  2072 			AiBuildRailRecursive(arf, _build_tunnel_endtile, (DiagDirection)(p[0] & 3));
  2075 			if (arf->depth == 1) AiCheckRailPathBetter(arf, p);
  2073 			if (arf->depth == 1) AiCheckRailPathBetter(arf, p);
  2076 		}
  2074 		}
  2077 	}
  2075 	}
  2078 }
  2076 }
  2079 
  2077 
  2080 
  2078 
  2081 static void AiBuildRailRecursive(AiRailFinder *arf, TileIndex tile, int dir)
  2079 static void AiBuildRailRecursive(AiRailFinder *arf, TileIndex tile, DiagDirection dir)
  2082 {
  2080 {
  2083 	const byte *p;
  2081 	const byte *p;
  2084 
  2082 
  2085 	tile = TILE_MASK(tile + TileOffsByDiagDir(dir));
  2083 	tile = TILE_MASK(tile + TileOffsByDiagDir(dir));
  2086 
  2084 
  2087 	// Reached destination?
  2085 	// Reached destination?
  2088 	if (tile == arf->final_tile) {
  2086 	if (tile == arf->final_tile) {
  2089 		if (arf->final_dir != (dir ^ 2)) {
  2087 		if (arf->final_dir != ReverseDiagDir(dir)) {
  2090 			if (arf->recursive_mode != 2) arf->recursive_mode = 1;
  2088 			if (arf->recursive_mode != 2) arf->recursive_mode = 1;
  2091 		} else if (arf->recursive_mode != 2) {
  2089 		} else if (arf->recursive_mode != 2) {
  2092 			arf->recursive_mode = 2;
  2090 			arf->recursive_mode = 2;
  2093 			arf->cur_best_depth = arf->depth;
  2091 			arf->cur_best_depth = arf->depth;
  2094 		} else {
  2092 		} else {
  2123 	} else {
  2121 	} else {
  2124 		do {
  2122 		do {
  2125 			// Make sure the tile is not in the list of banned tiles and that a rail can be built here.
  2123 			// Make sure the tile is not in the list of banned tiles and that a rail can be built here.
  2126 			if (!AiIsTileBanned(arf->player, tile, p[0]) &&
  2124 			if (!AiIsTileBanned(arf->player, tile, p[0]) &&
  2127 					CmdSucceeded(DoCommand(tile, arf->player->ai.railtype_to_use, p[0], DC_AUTO | DC_NO_WATER | DC_NO_RAIL_OVERLAP, CMD_BUILD_SINGLE_RAIL))) {
  2125 					CmdSucceeded(DoCommand(tile, arf->player->ai.railtype_to_use, p[0], DC_AUTO | DC_NO_WATER | DC_NO_RAIL_OVERLAP, CMD_BUILD_SINGLE_RAIL))) {
  2128 				AiBuildRailRecursive(arf, tile, p[1]);
  2126 				AiBuildRailRecursive(arf, tile, (DiagDirection)p[1]);
  2129 			}
  2127 			}
  2130 
  2128 
  2131 			// At the bottom depth?
  2129 			// At the bottom depth?
  2132 			if (arf->depth == 1) AiCheckRailPathBetter(arf, p);
  2130 			if (arf->depth == 1) AiCheckRailPathBetter(arf, p);
  2133 
  2131 
  2226 		DoCommand(p->ai.cur_tile_a, p->ai.railtype_to_use, 0, DC_AUTO | DC_EXEC, CMD_BUILD_TUNNEL);
  2224 		DoCommand(p->ai.cur_tile_a, p->ai.railtype_to_use, 0, DC_AUTO | DC_EXEC, CMD_BUILD_TUNNEL);
  2227 		p->ai.cur_tile_a = _build_tunnel_endtile;
  2225 		p->ai.cur_tile_a = _build_tunnel_endtile;
  2228 		p->ai.state_counter = 0;
  2226 		p->ai.state_counter = 0;
  2229 	} else {
  2227 	} else {
  2230 		// rail
  2228 		// rail
  2231 		p->ai.cur_dir_a = arf.best_ptr[1];
  2229 		p->ai.cur_dir_a = (DiagDirection)(arf.best_ptr[1] & 3);
  2232 		DoCommand(p->ai.cur_tile_a, p->ai.railtype_to_use, arf.best_ptr[0],
  2230 		DoCommand(p->ai.cur_tile_a, p->ai.railtype_to_use, arf.best_ptr[0],
  2233 			DC_EXEC | DC_AUTO | DC_NO_WATER | DC_NO_RAIL_OVERLAP, CMD_BUILD_SINGLE_RAIL);
  2231 			DC_EXEC | DC_AUTO | DC_NO_WATER | DC_NO_RAIL_OVERLAP, CMD_BUILD_SINGLE_RAIL);
  2234 		p->ai.state_counter = 0;
  2232 		p->ai.state_counter = 0;
  2235 	}
  2233 	}
  2236 
  2234 
  2288 	// And also remove the rail.
  2286 	// And also remove the rail.
  2289 	if (CmdFailed(DoCommand(tile, 0, bit, DC_EXEC, CMD_REMOVE_SINGLE_RAIL)))
  2287 	if (CmdFailed(DoCommand(tile, 0, bit, DC_EXEC, CMD_REMOVE_SINGLE_RAIL)))
  2290 		return false;
  2288 		return false;
  2291 
  2289 
  2292 	// Find the direction at the other edge of the rail.
  2290 	// Find the direction at the other edge of the rail.
  2293 	ptr = _ai_table_15[p->ai.cur_dir_a ^ 2];
  2291 	ptr = _ai_table_15[ReverseDiagDir(p->ai.cur_dir_a)];
  2294 	while (ptr[0] != bit) ptr += 2;
  2292 	while (ptr[0] != bit) ptr += 2;
  2295 	p->ai.cur_dir_a = ptr[1] ^ 2;
  2293 	p->ai.cur_dir_a = ReverseDiagDir((DiagDirection)ptr[1]);
  2296 
  2294 
  2297 	// And then also switch tile.
  2295 	// And then also switch tile.
  2298 	p->ai.cur_tile_a = TILE_MASK(p->ai.cur_tile_a - TileOffsByDiagDir(p->ai.cur_dir_a));
  2296 	p->ai.cur_tile_a = TILE_MASK(p->ai.cur_tile_a - TileOffsByDiagDir(p->ai.cur_dir_a));
  2299 
  2297 
  2300 	return true;
  2298 	return true;
  2349 {
  2347 {
  2350 	int num;
  2348 	int num;
  2351 	AiBuildRec *aib;
  2349 	AiBuildRec *aib;
  2352 	byte cmd;
  2350 	byte cmd;
  2353 	TileIndex tile;
  2351 	TileIndex tile;
  2354 	int dir;
  2352 	DiagDirection dir;
  2355 
  2353 
  2356 	// time out?
  2354 	// time out?
  2357 	if (++p->ai.timeout_counter == 1388) {
  2355 	if (++p->ai.timeout_counter == 1388) {
  2358 		p->ai.state = AIS_DELETE_RAIL_BLOCKS;
  2356 		p->ai.state = AIS_DELETE_RAIL_BLOCKS;
  2359 		return;
  2357 		return;
  2749 			);
  2747 			);
  2750 
  2748 
  2751 			if (rule == -1) {
  2749 			if (rule == -1) {
  2752 				// cannot build, terraform after a while
  2750 				// cannot build, terraform after a while
  2753 				if (p->ai.state_counter >= 600) {
  2751 				if (p->ai.state_counter >= 600) {
  2754 					AiDoTerraformLand(aib->use_tile, Random() & 3, 3, (int8)p->ai.state_mode);
  2752 					AiDoTerraformLand(aib->use_tile, (DiagDirection)(Random() & 3), 3, (int8)p->ai.state_mode);
  2755 				}
  2753 				}
  2756 				// also try the other terraform direction
  2754 				// also try the other terraform direction
  2757 				if (++p->ai.state_counter >= 1000) {
  2755 				if (++p->ai.state_counter >= 1000) {
  2758 					p->ai.state_counter = 0;
  2756 					p->ai.state_counter = 0;
  2759 					p->ai.state_mode = -p->ai.state_mode;
  2757 					p->ai.state_mode = -p->ai.state_mode;
  2786 	p->ai.state_mode = 255;
  2784 	p->ai.state_mode = 255;
  2787 }
  2785 }
  2788 
  2786 
  2789 struct AiRoadFinder {
  2787 struct AiRoadFinder {
  2790 	TileIndex final_tile;
  2788 	TileIndex final_tile;
  2791 	byte final_dir;
  2789 	DiagDirection final_dir;
  2792 	byte depth;
  2790 	byte depth;
  2793 	byte recursive_mode;
  2791 	byte recursive_mode;
  2794 	byte cur_best_dir;
  2792 	DiagDirection cur_best_dir;
  2795 	byte best_dir;
  2793 	DiagDirection best_dir;
  2796 	byte cur_best_depth;
  2794 	byte cur_best_depth;
  2797 	byte best_depth;
  2795 	byte best_depth;
  2798 	uint cur_best_dist;
  2796 	uint cur_best_dist;
  2799 	const byte *best_ptr;
  2797 	const byte *best_ptr;
  2800 	uint best_dist;
  2798 	uint best_dist;
  2808 	TileIndex best_tile;
  2806 	TileIndex best_tile;
  2809 	int best_track;
  2807 	int best_track;
  2810 	uint best_dist;
  2808 	uint best_dist;
  2811 };
  2809 };
  2812 
  2810 
  2813 static const byte _dir_by_track[] = {
  2811 static const DiagDirection _dir_by_track[] = {
  2814 	0, 1, 0, 1, 2, 1,
  2812 	DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE,
  2815 	0, 0,
  2813 	DIAGDIR_NE, DIAGDIR_NE,
  2816 	2, 3, 3, 2, 3, 0,
  2814 	DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE,
  2817 };
  2815 };
  2818 
  2816 
  2819 static void AiBuildRoadRecursive(AiRoadFinder *arf, TileIndex tile, int dir);
  2817 static void AiBuildRoadRecursive(AiRoadFinder *arf, TileIndex tile, DiagDirection dir);
  2820 
  2818 
  2821 static bool AiCheckRoadPathBetter(AiRoadFinder *arf, const byte *p)
  2819 static bool AiCheckRoadPathBetter(AiRoadFinder *arf, const byte *p)
  2822 {
  2820 {
  2823 	bool better = false;
  2821 	bool better = false;
  2824 
  2822 
  2878 
  2876 
  2879 static bool AiCheckRoadFinished(Player *p)
  2877 static bool AiCheckRoadFinished(Player *p)
  2880 {
  2878 {
  2881 	AiRoadEnum are;
  2879 	AiRoadEnum are;
  2882 	TileIndex tile;
  2880 	TileIndex tile;
  2883 	int dir = p->ai.cur_dir_a;
  2881 	DiagDirection dir = p->ai.cur_dir_a;
  2884 	uint32 bits;
  2882 	uint32 bits;
  2885 	int i;
  2883 	int i;
  2886 
  2884 
  2887 	are.dest = p->ai.cur_tile_b;
  2885 	are.dest = p->ai.cur_tile_b;
  2888 	tile = TILE_MASK(p->ai.cur_tile_a + TileOffsByDiagDir(dir));
  2886 	tile = TILE_MASK(p->ai.cur_tile_a + TileOffsByDiagDir(dir));
  2924 {
  2922 {
  2925 	Slope tileh;
  2923 	Slope tileh;
  2926 	uint z;
  2924 	uint z;
  2927 	bool flag;
  2925 	bool flag;
  2928 
  2926 
  2929 	int dir2 = p[0] & 3;
  2927 	DiagDirection dir2 = (DiagDirection)(p[0] & 3);
  2930 
  2928 
  2931 	tileh = GetTileSlope(tile, &z);
  2929 	tileh = GetTileSlope(tile, &z);
  2932 	if (tileh == _dir_table_1[dir2] || (tileh == SLOPE_FLAT && z != 0)) {
  2930 	if (tileh == _dir_table_1[dir2] || (tileh == SLOPE_FLAT && z != 0)) {
  2933 		TileIndex tile_new = tile;
  2931 		TileIndex tile_new = tile;
  2934 
  2932 
  2969 
  2967 
  2970 	if (GetTileSlope(tile, &z) == _dir_table_2[p[0] & 3] && z != 0) {
  2968 	if (GetTileSlope(tile, &z) == _dir_table_2[p[0] & 3] && z != 0) {
  2971 		CommandCost cost = DoCommand(tile, 0x200, 0, DC_AUTO, CMD_BUILD_TUNNEL);
  2969 		CommandCost cost = DoCommand(tile, 0x200, 0, DC_AUTO, CMD_BUILD_TUNNEL);
  2972 
  2970 
  2973 		if (CmdSucceeded(cost) && cost.GetCost() <= (arf->player->player_money >> 4)) {
  2971 		if (CmdSucceeded(cost) && cost.GetCost() <= (arf->player->player_money >> 4)) {
  2974 			AiBuildRoadRecursive(arf, _build_tunnel_endtile, p[0] & 3);
  2972 			AiBuildRoadRecursive(arf, _build_tunnel_endtile, (DiagDirection)(p[0] & 3));
  2975 			if (arf->depth == 1)  AiCheckRoadPathBetter(arf, p);
  2973 			if (arf->depth == 1)  AiCheckRoadPathBetter(arf, p);
  2976 		}
  2974 		}
  2977 	}
  2975 	}
  2978 }
  2976 }
  2979 
  2977 
  2980 
  2978 
  2981 
  2979 
  2982 static void AiBuildRoadRecursive(AiRoadFinder *arf, TileIndex tile, int dir)
  2980 static void AiBuildRoadRecursive(AiRoadFinder *arf, TileIndex tile, DiagDirection dir)
  2983 {
  2981 {
  2984 	const byte *p;
  2982 	const byte *p;
  2985 
  2983 
  2986 	tile = TILE_MASK(tile + TileOffsByDiagDir(dir));
  2984 	tile = TILE_MASK(tile + TileOffsByDiagDir(dir));
  2987 
  2985 
  2988 	// Reached destination?
  2986 	// Reached destination?
  2989 	if (tile == arf->final_tile) {
  2987 	if (tile == arf->final_tile) {
  2990 		if ((arf->final_dir ^ 2) == dir) {
  2988 		if (ReverseDiagDir(arf->final_dir) == dir) {
  2991 			arf->recursive_mode = 2;
  2989 			arf->recursive_mode = 2;
  2992 			arf->cur_best_depth = arf->depth;
  2990 			arf->cur_best_depth = arf->depth;
  2993 		}
  2991 		}
  2994 		return;
  2992 		return;
  2995 	}
  2993 	}
  3018 		p += 6;
  3016 		p += 6;
  3019 	} else {
  3017 	} else {
  3020 		do {
  3018 		do {
  3021 			// Make sure that a road can be built here.
  3019 			// Make sure that a road can be built here.
  3022 			if (AiBuildRoadHelper(tile, DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, p[0])) {
  3020 			if (AiBuildRoadHelper(tile, DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, p[0])) {
  3023 				AiBuildRoadRecursive(arf, tile, p[1]);
  3021 				AiBuildRoadRecursive(arf, tile, (DiagDirection)p[1]);
  3024 			}
  3022 			}
  3025 
  3023 
  3026 			// At the bottom depth?
  3024 			// At the bottom depth?
  3027 			if (arf->depth == 1) AiCheckRoadPathBetter(arf, p);
  3025 			if (arf->depth == 1) AiCheckRoadPathBetter(arf, p);
  3028 
  3026 
  3079 
  3077 
  3080 		if (++p->ai.state_counter == 21) {
  3078 		if (++p->ai.state_counter == 21) {
  3081 			p->ai.state_mode = 1;
  3079 			p->ai.state_mode = 1;
  3082 
  3080 
  3083 			p->ai.cur_tile_a = TILE_MASK(p->ai.cur_tile_a + TileOffsByDiagDir(p->ai.cur_dir_a));
  3081 			p->ai.cur_tile_a = TILE_MASK(p->ai.cur_tile_a + TileOffsByDiagDir(p->ai.cur_dir_a));
  3084 			p->ai.cur_dir_a ^= 2;
  3082 			p->ai.cur_dir_a = ReverseDiagDir(p->ai.cur_dir_a);
  3085 			p->ai.state_counter = 0;
  3083 			p->ai.state_counter = 0;
  3086 		}
  3084 		}
  3087 		return;
  3085 		return;
  3088 	}
  3086 	}
  3089 
  3087 
  3119 	} else {
  3117 	} else {
  3120 		// road
  3118 		// road
  3121 		if (!AiBuildRoadHelper(tile, DC_EXEC | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, arf.best_ptr[0]))
  3119 		if (!AiBuildRoadHelper(tile, DC_EXEC | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, arf.best_ptr[0]))
  3122 			goto do_some_terraform;
  3120 			goto do_some_terraform;
  3123 
  3121 
  3124 		p->ai.cur_dir_a = arf.best_ptr[1];
  3122 		p->ai.cur_dir_a = (DiagDirection)(arf.best_ptr[1] & 3);
  3125 		p->ai.cur_tile_a = tile;
  3123 		p->ai.cur_tile_a = tile;
  3126 		p->ai.state_counter = 0;
  3124 		p->ai.state_counter = 0;
  3127 	}
  3125 	}
  3128 
  3126 
  3129 	if (arf.best_tile != 0) {
  3127 	if (arf.best_tile != 0) {
  3155 			p->ai.state_mode = 0;
  3153 			p->ai.state_mode = 0;
  3156 		}
  3154 		}
  3157 	}
  3155 	}
  3158 }
  3156 }
  3159 
  3157 
  3160 static TileIndex AiGetRoadBlockEdge(byte rule, TileIndex tile, int *dir)
  3158 static TileIndex AiGetRoadBlockEdge(byte rule, TileIndex tile, DiagDirection *dir)
  3161 {
  3159 {
  3162 	const AiDefaultBlockData *p = _road_default_block_data[rule]->data;
  3160 	const AiDefaultBlockData *p = _road_default_block_data[rule]->data;
  3163 	while (p->mode != 1) p++;
  3161 	while (p->mode != 1) p++;
  3164 	*dir = p->attr;
  3162 	*dir = p->attr;
  3165 	return TILE_ADD(tile, ToTileIndexDiff(p->tileoffs));
  3163 	return TILE_ADD(tile, ToTileIndexDiff(p->tileoffs));
  3170 {
  3168 {
  3171 	int num;
  3169 	int num;
  3172 	AiBuildRec *aib;
  3170 	AiBuildRec *aib;
  3173 	byte cmd;
  3171 	byte cmd;
  3174 	TileIndex tile;
  3172 	TileIndex tile;
  3175 	int dir;
  3173 	DiagDirection dir;
  3176 
  3174 
  3177 	// time out?
  3175 	// time out?
  3178 	if (++p->ai.timeout_counter == 1388) {
  3176 	if (++p->ai.timeout_counter == 1388) {
  3179 		p->ai.state = AIS_DELETE_ROAD_BLOCKS;
  3177 		p->ai.state = AIS_DELETE_ROAD_BLOCKS;
  3180 		return;
  3178 		return;
  3475 //			SetRedErrorSquare(aib->use_tile);
  3473 //			SetRedErrorSquare(aib->use_tile);
  3476 
  3474 
  3477 			if (rule == -1) {
  3475 			if (rule == -1) {
  3478 				// cannot build, terraform after a while
  3476 				// cannot build, terraform after a while
  3479 				if (p->ai.state_counter >= 600) {
  3477 				if (p->ai.state_counter >= 600) {
  3480 					AiDoTerraformLand(aib->use_tile, Random() & 3, 3, (int8)p->ai.state_mode);
  3478 					AiDoTerraformLand(aib->use_tile, (DiagDirection)(Random() & 3), 3, (int8)p->ai.state_mode);
  3481 				}
  3479 				}
  3482 				// also try the other terraform direction
  3480 				// also try the other terraform direction
  3483 				if (++p->ai.state_counter >= 1000) {
  3481 				if (++p->ai.state_counter >= 1000) {
  3484 					p->ai.state_counter = 0;
  3482 					p->ai.state_counter = 0;
  3485 					p->ai.state_mode = -p->ai.state_mode;
  3483 					p->ai.state_mode = -p->ai.state_mode;
  3680 			if (rails == TRACK_BIT_HORZ || rails == TRACK_BIT_VERT) return;
  3678 			if (rails == TRACK_BIT_HORZ || rails == TRACK_BIT_VERT) return;
  3681 
  3679 
  3682 			if (rails & TRACK_BIT_3WAY_NE) {
  3680 			if (rails & TRACK_BIT_3WAY_NE) {
  3683 pos_0:
  3681 pos_0:
  3684 				if ((GetRailTrackStatus(TILE_MASK(tile - TileDiffXY(1, 0))) & TRACK_BIT_3WAY_SW) == 0) {
  3682 				if ((GetRailTrackStatus(TILE_MASK(tile - TileDiffXY(1, 0))) & TRACK_BIT_3WAY_SW) == 0) {
  3685 					p->ai.cur_dir_a = 0;
  3683 					p->ai.cur_dir_a = DIAGDIR_NE;
  3686 					p->ai.cur_tile_a = tile;
  3684 					p->ai.cur_tile_a = tile;
  3687 					p->ai.state = AIS_REMOVE_SINGLE_RAIL_TILE;
  3685 					p->ai.state = AIS_REMOVE_SINGLE_RAIL_TILE;
  3688 					return;
  3686 					return;
  3689 				}
  3687 				}
  3690 			}
  3688 			}
  3691 
  3689 
  3692 			if (rails & TRACK_BIT_3WAY_SE) {
  3690 			if (rails & TRACK_BIT_3WAY_SE) {
  3693 pos_1:
  3691 pos_1:
  3694 				if ((GetRailTrackStatus(TILE_MASK(tile + TileDiffXY(0, 1))) & TRACK_BIT_3WAY_NW) == 0) {
  3692 				if ((GetRailTrackStatus(TILE_MASK(tile + TileDiffXY(0, 1))) & TRACK_BIT_3WAY_NW) == 0) {
  3695 					p->ai.cur_dir_a = 1;
  3693 					p->ai.cur_dir_a = DIAGDIR_SE;
  3696 					p->ai.cur_tile_a = tile;
  3694 					p->ai.cur_tile_a = tile;
  3697 					p->ai.state = AIS_REMOVE_SINGLE_RAIL_TILE;
  3695 					p->ai.state = AIS_REMOVE_SINGLE_RAIL_TILE;
  3698 					return;
  3696 					return;
  3699 				}
  3697 				}
  3700 			}
  3698 			}
  3701 
  3699 
  3702 			if (rails & TRACK_BIT_3WAY_SW) {
  3700 			if (rails & TRACK_BIT_3WAY_SW) {
  3703 pos_2:
  3701 pos_2:
  3704 				if ((GetRailTrackStatus(TILE_MASK(tile + TileDiffXY(1, 0))) & TRACK_BIT_3WAY_NE) == 0) {
  3702 				if ((GetRailTrackStatus(TILE_MASK(tile + TileDiffXY(1, 0))) & TRACK_BIT_3WAY_NE) == 0) {
  3705 					p->ai.cur_dir_a = 2;
  3703 					p->ai.cur_dir_a = DIAGDIR_SW;
  3706 					p->ai.cur_tile_a = tile;
  3704 					p->ai.cur_tile_a = tile;
  3707 					p->ai.state = AIS_REMOVE_SINGLE_RAIL_TILE;
  3705 					p->ai.state = AIS_REMOVE_SINGLE_RAIL_TILE;
  3708 					return;
  3706 					return;
  3709 				}
  3707 				}
  3710 			}
  3708 			}
  3711 
  3709 
  3712 			if (rails & TRACK_BIT_3WAY_NW) {
  3710 			if (rails & TRACK_BIT_3WAY_NW) {
  3713 pos_3:
  3711 pos_3:
  3714 				if ((GetRailTrackStatus(TILE_MASK(tile - TileDiffXY(0, 1))) & TRACK_BIT_3WAY_SE) == 0) {
  3712 				if ((GetRailTrackStatus(TILE_MASK(tile - TileDiffXY(0, 1))) & TRACK_BIT_3WAY_SE) == 0) {
  3715 					p->ai.cur_dir_a = 3;
  3713 					p->ai.cur_dir_a = DIAGDIR_NW;
  3716 					p->ai.cur_tile_a = tile;
  3714 					p->ai.cur_tile_a = tile;
  3717 					p->ai.state = AIS_REMOVE_SINGLE_RAIL_TILE;
  3715 					p->ai.state = AIS_REMOVE_SINGLE_RAIL_TILE;
  3718 					return;
  3716 					return;
  3719 				}
  3717 				}
  3720 			}
  3718 			}