src/rail_cmd.cpp
changeset 7703 6178606d419a
parent 7642 535e5d93ffb1
child 7730 4293ba29ce21
equal deleted inserted replaced
7702:f963cd54d4d5 7703:6178606d419a
   148 		return true;
   148 		return true;
   149 	}
   149 	}
   150 }
   150 }
   151 
   151 
   152 
   152 
   153 static const TrackBits _valid_tileh_slopes[][15] = {
   153 /** Valid TrackBits on a specific (non-steep)-slope without foundation */
   154 
   154 static const TrackBits _valid_tracks_without_foundation[15] = {
   155 /* set of normal ones */
       
   156 {
       
   157 	TRACK_BIT_ALL,
   155 	TRACK_BIT_ALL,
   158 	TRACK_BIT_RIGHT,
   156 	TRACK_BIT_RIGHT,
   159 	TRACK_BIT_UPPER,
   157 	TRACK_BIT_UPPER,
   160 	TRACK_BIT_X,
   158 	TRACK_BIT_X,
   161 
   159 
   170 	TRACK_BIT_LEFT,
   168 	TRACK_BIT_LEFT,
   171 
   169 
   172 	TRACK_BIT_X,
   170 	TRACK_BIT_X,
   173 	TRACK_BIT_UPPER,
   171 	TRACK_BIT_UPPER,
   174 	TRACK_BIT_RIGHT,
   172 	TRACK_BIT_RIGHT,
   175 },
   173 };
   176 
   174 
   177 /* allowed rail for an evenly raised platform */
   175 /** Valid TrackBits on a specific (non-steep)-slope with leveled foundation */
   178 {
   176 static const TrackBits _valid_tracks_on_leveled_foundation[15] = {
   179 	TRACK_BIT_NONE,
   177 	TRACK_BIT_NONE,
   180 	TRACK_BIT_LEFT,
   178 	TRACK_BIT_LEFT,
   181 	TRACK_BIT_LOWER,
   179 	TRACK_BIT_LOWER,
   182 	TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_LEFT,
   180 	TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_LEFT,
   183 
   181 
   192 	TRACK_BIT_ALL,
   190 	TRACK_BIT_ALL,
   193 
   191 
   194 	TRACK_BIT_Y | TRACK_BIT_UPPER | TRACK_BIT_RIGHT,
   192 	TRACK_BIT_Y | TRACK_BIT_UPPER | TRACK_BIT_RIGHT,
   195 	TRACK_BIT_ALL,
   193 	TRACK_BIT_ALL,
   196 	TRACK_BIT_ALL
   194 	TRACK_BIT_ALL
   197 }
       
   198 };
   195 };
   199 
   196 
       
   197 /**
       
   198  * Checks if a track combination is valid on a specific slope and returns the needed foundation.
       
   199  *
       
   200  * @param tileh Tile slope.
       
   201  * @param bits  Trackbits.
       
   202  * @return Needed foundation or FOUNDATION_INVALID if track/slope combination is not allowed.
       
   203  */
   200 Foundation GetRailFoundation(Slope tileh, TrackBits bits)
   204 Foundation GetRailFoundation(Slope tileh, TrackBits bits)
   201 {
   205 {
   202 	if (!IsSteepSlope(tileh)) {
   206 	if (bits == TRACK_BIT_NONE) return FOUNDATION_NONE;
   203 		if ((~_valid_tileh_slopes[0][tileh] & bits) == 0) return FOUNDATION_NONE;
   207 
   204 		if ((~_valid_tileh_slopes[1][tileh] & bits) == 0) return FOUNDATION_LEVELED;
   208 	if (IsSteepSlope(tileh)) {
   205 	}
   209 		/* Test for inclined foundations */
   206 
   210 		if (bits == TRACK_BIT_X) return FOUNDATION_INCLINED_X;
   207 	switch (bits) {
   211 		if (bits == TRACK_BIT_Y) return FOUNDATION_INCLINED_Y;
   208 		default: NOT_REACHED();
   212 
   209 		case TRACK_BIT_X:     return FOUNDATION_INCLINED_X;
   213 		/* Get higher track */
   210 		case TRACK_BIT_Y:     return FOUNDATION_INCLINED_Y;
   214 		Corner highest_corner = GetHighestSlopeCorner(tileh);
   211 		case TRACK_BIT_LEFT:  return (tileh == SLOPE_STEEP_W ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER);
   215 		TrackBits higher_track = CornerToTrackBits(highest_corner);
   212 		case TRACK_BIT_LOWER: return (tileh == SLOPE_STEEP_S ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER);
   216 
   213 		case TRACK_BIT_RIGHT: return (tileh == SLOPE_STEEP_E ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER);
   217 		/* Only higher track? */
   214 		case TRACK_BIT_UPPER: return (tileh == SLOPE_STEEP_N ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER);
   218 		if (bits == higher_track) return FOUNDATION_STEEP_HIGHER;
   215 	}
   219 
   216 }
   220 		/* Overlap with higher track? */
   217 
   221 		if (TracksOverlap(bits | higher_track)) return FOUNDATION_INVALID;
   218 
   222 
       
   223 		/* either lower track or both higher and lower track */
       
   224 		return ((bits & higher_track) != 0 ? FOUNDATION_INVALID : FOUNDATION_STEEP_LOWER);
       
   225 	} else {
       
   226 		if ((~_valid_tracks_without_foundation[tileh] & bits) == 0) return FOUNDATION_NONE;
       
   227 
       
   228 		bool valid_on_leveled = ((~_valid_tracks_on_leveled_foundation[tileh] & bits) == 0);
       
   229 
       
   230 		switch (bits) {
       
   231 			case TRACK_BIT_X:
       
   232 				if (HasSlopeHighestCorner(tileh)) return FOUNDATION_INCLINED_X;
       
   233 				return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
       
   234 
       
   235 			case TRACK_BIT_Y:
       
   236 				if (HasSlopeHighestCorner(tileh)) return FOUNDATION_INCLINED_Y;
       
   237 				return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
       
   238 
       
   239 			default:
       
   240 				return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
       
   241 		}
       
   242 	}
       
   243 }
       
   244 
       
   245 
       
   246 /**
       
   247  * Tests if a track can be build on a tile.
       
   248  *
       
   249  * @param tileh Tile slope.
       
   250  * @param rail_bits Tracks to build.
       
   251  * @param existing Tracks already built.
       
   252  * @param tile Tile (used for water test)
       
   253  * @return Error message or cost for foundation building.
       
   254  */
   219 static CommandCost CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
   255 static CommandCost CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
   220 {
   256 {
   221 	if (IsSteepSlope(tileh)) {
   257 	/* don't allow building on the lower side of a coast */
   222 		if (_patches.build_on_slopes && existing == 0) {
   258 	if (IsTileType(tile, MP_WATER)) {
   223 			/* There may only be one track on steep slopes. (Autoslope calls with multiple bits in rail_bits) */
   259 		if (!IsSteepSlope(tileh) && ((~_valid_tracks_on_leveled_foundation[tileh] & (rail_bits | existing)) != 0)) return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
   224 			if (KILL_FIRST_BIT(rail_bits & TRACK_BIT_MASK) == 0) {
   260 	}
   225 				TrackBits valid = TRACK_BIT_CROSS | (HASBIT(1 << SLOPE_STEEP_W | 1 << SLOPE_STEEP_E, tileh) ? TRACK_BIT_VERT : TRACK_BIT_HORZ);
   261 
   226 				if (valid & rail_bits) return _price.terraform;
   262 	Foundation f_new = GetRailFoundation(tileh, rail_bits | existing);
   227 			}
   263 
   228 		}
   264 	/* check track/slope combination */
   229 	} else {
   265 	if ((f_new == FOUNDATION_INVALID) ||
   230 		rail_bits |= existing;
   266 	    ((f_new != FOUNDATION_NONE) && (!_patches.build_on_slopes || _is_old_ai_player))
   231 
   267 	   ) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   232 		/* don't allow building on the lower side of a coast */
   268 
   233 		if (IsTileType(tile, MP_WATER) &&
   269 	Foundation f_old = GetRailFoundation(tileh, existing);
   234 				~_valid_tileh_slopes[1][tileh] & rail_bits) {
   270 	return CommandCost(f_new != f_old ? _price.terraform : 0);
   235 			return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
       
   236 		}
       
   237 
       
   238 		/* no special foundation */
       
   239 		if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0) {
       
   240 			return CommandCost();
       
   241 		} else if (!_patches.build_on_slopes || _is_old_ai_player) {
       
   242 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
       
   243 		}
       
   244 
       
   245 		if ((~_valid_tileh_slopes[1][tileh] & rail_bits) == 0 || ( // whole tile is leveled up
       
   246 					(rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) &&
       
   247 					(tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)
       
   248 				)) { // partly up
       
   249 			return CommandCost((existing != 0) ? 0 : _price.terraform);
       
   250 		}
       
   251 	}
       
   252 	return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
       
   253 }
   271 }
   254 
   272 
   255 /* Validate functions for rail building */
   273 /* Validate functions for rail building */
   256 static inline bool ValParamTrackOrientation(Track track) {return IsValidTrack(track);}
   274 static inline bool ValParamTrackOrientation(Track track) {return IsValidTrack(track);}
   257 
   275