diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index 4e03ae3f63..efa981086b 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -605,7 +605,7 @@ struct AIDebugWindow : public Window { virtual void OnPaint() { /* Check if the currently selected company is still active. */ - if (ai_debug_company == INVALID_COMPANY || !IsValidCompanyID(ai_debug_company)) { + if (ai_debug_company == INVALID_COMPANY || !IsValidCompanyID(ai_debug_company) || !GetCompany(ai_debug_company)->is_ai) { if (ai_debug_company != INVALID_COMPANY) { /* Raise and disable the widget for the previous selection. */ this->RaiseWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START); diff --git a/src/ai/api/ai_bridge.cpp b/src/ai/api/ai_bridge.cpp index f85be95d61..ce08052a0e 100644 --- a/src/ai/api/ai_bridge.cpp +++ b/src/ai/api/ai_bridge.cpp @@ -32,7 +32,6 @@ static void _DoCommandReturnBuildBridge2(class AIInstance *instance) { if (!AIBridge::_BuildBridgeRoad2()) { - AIObject::SetLastCommandRes(false); AIInstance::DoCommandReturn(instance); return; } @@ -45,7 +44,6 @@ static void _DoCommandReturnBuildBridge2(class AIInstance *instance) static void _DoCommandReturnBuildBridge1(class AIInstance *instance) { if (!AIBridge::_BuildBridgeRoad1()) { - AIObject::SetLastCommandRes(false); AIInstance::DoCommandReturn(instance); return; } @@ -67,7 +65,7 @@ static void _DoCommandReturnBuildBridge1(class AIInstance *instance) switch (vehicle_type) { case AIVehicle::VT_ROAD: type |= (TRANSPORT_ROAD << 15); - type |= (RoadTypeToRoadTypes((::RoadType)AIObject::GetRoadType()) << 8); + type |= (::RoadTypeToRoadTypes((::RoadType)AIObject::GetRoadType()) << 8); break; case AIVehicle::VT_RAIL: type |= (TRANSPORT_RAIL << 15); @@ -86,10 +84,7 @@ static void _DoCommandReturnBuildBridge1(class AIInstance *instance) AIObject::SetCallbackVariable(0, start); AIObject::SetCallbackVariable(1, end); - if (!AIObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE, NULL, &_DoCommandReturnBuildBridge1)) return false; - - /* In case of test-mode, test if we can build both road pieces */ - return _BuildBridgeRoad1(); + return AIObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE, NULL, &_DoCommandReturnBuildBridge1); } /* static */ bool AIBridge::_BuildBridgeRoad1() @@ -101,10 +96,7 @@ static void _DoCommandReturnBuildBridge1(class AIInstance *instance) DiagDirection dir_1 = (DiagDirection)((::TileX(start) == ::TileX(end)) ? (::TileY(start) < ::TileY(end) ? DIAGDIR_NW : DIAGDIR_SE) : (::TileX(start) < ::TileX(end) ? DIAGDIR_NE : DIAGDIR_SW)); DiagDirection dir_2 = ::ReverseDiagDir(dir_1); - if (!AIObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, NULL, &_DoCommandReturnBuildBridge2)) return false; - - /* In case of test-mode, test the other road piece too */ - return _BuildBridgeRoad2(); + return AIObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, NULL, &_DoCommandReturnBuildBridge2); } /* static */ bool AIBridge::_BuildBridgeRoad2() diff --git a/src/ai/api/ai_station.cpp b/src/ai/api/ai_station.cpp index 364b09538a..6d2080ce44 100644 --- a/src/ai/api/ai_station.cpp +++ b/src/ai/api/ai_station.cpp @@ -17,7 +17,8 @@ /* static */ bool AIStation::IsValidStation(StationID station_id) { - return ::IsValidStationID(station_id) && ::GetStation(station_id)->owner == _current_company; + const Station *st = ::IsValidStationID(station_id) ? GetStation(station_id) : NULL; + return st != NULL && (st->owner == _current_company || st->owner == OWNER_NONE); } /* static */ StationID AIStation::GetStationID(TileIndex tile) diff --git a/src/ai/api/ai_tile.cpp b/src/ai/api/ai_tile.cpp index 70bb1fb835..df44cac665 100644 --- a/src/ai/api/ai_tile.cpp +++ b/src/ai/api/ai_tile.cpp @@ -175,21 +175,21 @@ return ::TrackStatusToTrackdirBits(::GetTileTrackStatus(tile, (::TransportType)transport_type, UINT32_MAX)) != TRACKDIR_BIT_NONE; } -/* static */ int32 AITile::GetCargoAcceptance(TileIndex tile, CargoID cargo_type, uint width, uint height, uint radius) +/* static */ int32 AITile::GetCargoAcceptance(TileIndex tile, CargoID cargo_type, int width, int height, int radius) { - if (!::IsValidTile(tile)) return false; + if (!::IsValidTile(tile) || width <= 0 || height <= 0 || radius <= 0) return -1; AcceptedCargo accepts; - ::GetAcceptanceAroundTiles(accepts, tile, width, height, _settings_game.station.modified_catchment ? radius : (uint)CA_UNMODIFIED); + ::GetAcceptanceAroundTiles(accepts, tile, width, height, _settings_game.station.modified_catchment ? radius : (int)CA_UNMODIFIED); return accepts[cargo_type]; } -/* static */ int32 AITile::GetCargoProduction(TileIndex tile, CargoID cargo_type, uint width, uint height, uint radius) +/* static */ int32 AITile::GetCargoProduction(TileIndex tile, CargoID cargo_type, int width, int height, int radius) { - if (!::IsValidTile(tile)) return false; + if (!::IsValidTile(tile) || width <= 0 || height <= 0 || radius <= 0) return -1; AcceptedCargo produced; - ::GetProductionAroundTiles(produced, tile, width, height, _settings_game.station.modified_catchment ? radius : (uint)CA_UNMODIFIED); + ::GetProductionAroundTiles(produced, tile, width, height, _settings_game.station.modified_catchment ? radius : (int)CA_UNMODIFIED); return produced[cargo_type]; } diff --git a/src/ai/api/ai_tile.hpp b/src/ai/api/ai_tile.hpp index 7832384d81..c4942d3821 100644 --- a/src/ai/api/ai_tile.hpp +++ b/src/ai/api/ai_tile.hpp @@ -303,9 +303,12 @@ public: * @param height The height of the station. * @param radius The radius of the station. * @pre AIMap::IsValidTile(tile). + * @pre width > 0. + * @pre height > 0. + * @pre radius > 0. * @return Value below 8 means no acceptance; the more the better. */ - static int32 GetCargoAcceptance(TileIndex tile, CargoID cargo_type, uint width, uint height, uint radius); + static int32 GetCargoAcceptance(TileIndex tile, CargoID cargo_type, int width, int height, int radius); /** * Checks how many tiles in the radius produces this cargo. @@ -317,10 +320,13 @@ public: * @param height The height of the station. * @param radius The radius of the station. * @pre AIMap::IsValidTile(tile). + * @pre width > 0. + * @pre height > 0. + * @pre radius > 0. * @return The tiles that produce this cargo within radius of the tile. * @note Town(houses) are not included in the value. */ - static int32 GetCargoProduction(TileIndex tile, CargoID cargo_type, uint width, uint height, uint radius); + static int32 GetCargoProduction(TileIndex tile, CargoID cargo_type, int width, int height, int radius); /** * Get the manhattan distance from the tile to the tile. diff --git a/src/ai/api/ai_tilelist.cpp b/src/ai/api/ai_tilelist.cpp index d2fa8c4680..02209ca5c3 100644 --- a/src/ai/api/ai_tilelist.cpp +++ b/src/ai/api/ai_tilelist.cpp @@ -68,9 +68,9 @@ void AITileList::RemoveTile(TileIndex tile) this->RemoveItem(tile); } -AITileList_IndustryAccepting::AITileList_IndustryAccepting(IndustryID industry_id, uint radius) +AITileList_IndustryAccepting::AITileList_IndustryAccepting(IndustryID industry_id, int radius) { - if (!AIIndustry::IsValidIndustry(industry_id)) return; + if (!AIIndustry::IsValidIndustry(industry_id) || radius <= 0) return; const Industry *i = ::GetIndustry(industry_id); @@ -106,9 +106,9 @@ AITileList_IndustryAccepting::AITileList_IndustryAccepting(IndustryID industry_i } END_TILE_LOOP(cur_tile, i->width + radius * 2, i->height + radius * 2, i->xy - ::TileDiffXY(radius, radius)) } -AITileList_IndustryProducing::AITileList_IndustryProducing(IndustryID industry_id, uint radius) +AITileList_IndustryProducing::AITileList_IndustryProducing(IndustryID industry_id, int radius) { - if (!AIIndustry::IsValidIndustry(industry_id)) return; + if (!AIIndustry::IsValidIndustry(industry_id) || radius <= 0) return; const Industry *i = ::GetIndustry(industry_id); diff --git a/src/ai/api/ai_tilelist.hpp b/src/ai/api/ai_tilelist.hpp index f3d2f658d9..085dc756ac 100644 --- a/src/ai/api/ai_tilelist.hpp +++ b/src/ai/api/ai_tilelist.hpp @@ -71,8 +71,10 @@ public: /** * @param industry_id The industry to create the AITileList around. * @param radius The radius of the station you will be using. + * @pre AIIndustry::IsValidIndustry(industry_id). + * @pre radius > 0. */ - AITileList_IndustryAccepting(IndustryID industry_id, uint radius); + AITileList_IndustryAccepting(IndustryID industry_id, int radius); }; /** @@ -87,8 +89,10 @@ public: /** * @param industry_id The industry to create the AITileList around. * @param radius The radius of the station you will be using. + * @pre AIIndustry::IsValidIndustry(industry_id). + * @pre radius > 0. */ - AITileList_IndustryProducing(IndustryID industry_id, uint radius); + AITileList_IndustryProducing(IndustryID industry_id, int radius); }; /** diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 81e651dfb9..bcf70df147 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1791,7 +1791,8 @@ static void DrawTrackBits(TileInfo *ti, TrackBits track) /* PBS debugging, draw reserved tracks darker */ if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation) { - TrackBits pbs = GetTrackReservation(ti->tile); + /* Get reservation, but mask track on halftile slope */ + TrackBits pbs = GetTrackReservation(ti->tile) & track; if (pbs & TRACK_BIT_X) { if (ti->tileh == SLOPE_FLAT || ti->tileh == SLOPE_ELEVATED) { DrawGroundSprite(rti->base_sprites.single_y, PALETTE_CRASH); @@ -1806,10 +1807,10 @@ static void DrawTrackBits(TileInfo *ti, TrackBits track) DrawGroundSprite(_track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.single_sloped - 20, PALETTE_CRASH); } } - if (pbs & TRACK_BIT_UPPER) AddSortableSpriteToDraw(rti->base_sprites.single_n, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + (ti->tileh & SLOPE_N ? 8 : 0)); - if (pbs & TRACK_BIT_LOWER) AddSortableSpriteToDraw(rti->base_sprites.single_s, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + (ti->tileh & SLOPE_S ? 8 : 0)); - if (pbs & TRACK_BIT_LEFT) AddSortableSpriteToDraw(rti->base_sprites.single_w, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + (ti->tileh & SLOPE_W ? 8 : 0)); - if (pbs & TRACK_BIT_RIGHT) AddSortableSpriteToDraw(rti->base_sprites.single_e, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + (ti->tileh & SLOPE_E ? 8 : 0)); + if (pbs & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PALETTE_CRASH, NULL, 0, ti->tileh & SLOPE_N ? -TILE_HEIGHT : 0); + if (pbs & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PALETTE_CRASH, NULL, 0, ti->tileh & SLOPE_S ? -TILE_HEIGHT : 0); + if (pbs & TRACK_BIT_LEFT) DrawGroundSprite(rti->base_sprites.single_w, PALETTE_CRASH, NULL, 0, ti->tileh & SLOPE_W ? -TILE_HEIGHT : 0); + if (pbs & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e, PALETTE_CRASH, NULL, 0, ti->tileh & SLOPE_E ? -TILE_HEIGHT : 0); } if (IsValidCorner(halftile_corner)) { @@ -1827,9 +1828,9 @@ static void DrawTrackBits(TileInfo *ti, TrackBits track) } DrawGroundSprite(image, pal, &(_halftile_sub_sprite[halftile_corner])); - if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && IsSteepSlope(ti->tileh) && HasReservedTracks(ti->tile, CornerToTrackBits(halftile_corner))) { + if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasReservedTracks(ti->tile, CornerToTrackBits(halftile_corner))) { static const byte _corner_to_track_sprite[] = {3, 1, 2, 0}; - AddSortableSpriteToDraw(_corner_to_track_sprite[halftile_corner] + rti->base_sprites.single_n, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + 16); + DrawGroundSprite(_corner_to_track_sprite[halftile_corner] + rti->base_sprites.single_n, PALETTE_CRASH, NULL, 0, -TILE_HEIGHT); } } } diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 65c5552a2c..8dbddaede9 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -993,8 +993,8 @@ static void DrawTile_TunnelBridge(TileInfo *ti) /* draw ramp */ - /* Draw Trambits as SpriteCombine */ - if (transport_type == TRANSPORT_ROAD) StartSpriteCombine(); + /* Draw Trambits and PBS Reservation as SpriteCombine */ + if (transport_type == TRANSPORT_ROAD || transport_type == TRANSPORT_RAIL) StartSpriteCombine(); /* HACK set the height of the BB of a sloped ramp to 1 so a vehicle on * it doesn't disappear behind it @@ -1028,6 +1028,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti) } EndSpriteCombine(); } else if (transport_type == TRANSPORT_RAIL) { + EndSpriteCombine(); if (HasCatenaryDrawn(GetRailType(ti->tile))) { DrawCatenary(ti); } diff --git a/src/viewport.cpp b/src/viewport.cpp index 60cecb03cb..8f79226cb4 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -60,9 +60,8 @@ struct TileSpriteToDraw { SpriteID image; SpriteID pal; const SubSprite *sub; ///< only draw a rectangular part of the sprite - int32 x; - int32 y; - byte z; + int32 x; ///< screen X coordinate of sprite + int32 y; ///< screen Y coordinate of sprite }; struct ChildScreenSpriteToDraw { @@ -456,13 +455,15 @@ void HandleZoomMessage(Window *w, const ViewPort *vp, byte widget_zoom_in, byte * * @param image the image to draw. * @param pal the provided palette. - * @param x position x of the sprite. - * @param y position y of the sprite. - * @param z position z of the sprite. + * @param x position x (world coordinates) of the sprite. + * @param y position y (world coordinates) of the sprite. + * @param z position z (world coordinates) of the sprite. * @param sub Only draw a part of the sprite. + * @param extra_offs_x Pixel X offset for the sprite position. + * @param extra_offs_y Pixel Y offset for the sprite position. * */ -void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z, const SubSprite *sub) +void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z, const SubSprite *sub, int extra_offs_x, int extra_offs_y) { assert((image & SPRITE_MASK) < MAX_SPRITES); @@ -470,9 +471,9 @@ void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z, ts->image = image; ts->pal = pal; ts->sub = sub; - ts->x = x; - ts->y = y; - ts->z = z; + Point pt = RemapCoords(x, y, z); + ts->x = pt.x + extra_offs_x; + ts->y = pt.y + extra_offs_y; } /** @@ -510,16 +511,18 @@ static void AddChildSpriteToFoundation(SpriteID image, SpriteID pal, const SubSp * @param image the image to draw. * @param pal the provided palette. * @param sub Only draw a part of the sprite. + * @param extra_offs_x Pixel X offset for the sprite position. + * @param extra_offs_y Pixel Y offset for the sprite position. */ -void DrawGroundSprite(SpriteID image, SpriteID pal, const SubSprite *sub) +void DrawGroundSprite(SpriteID image, SpriteID pal, const SubSprite *sub, int extra_offs_x, int extra_offs_y) { /* Switch to first foundation part, if no foundation was drawn */ if (_vd.foundation_part == FOUNDATION_PART_NONE) _vd.foundation_part = FOUNDATION_PART_NORMAL; if (_vd.foundation[_vd.foundation_part] != -1) { - AddChildSpriteToFoundation(image, pal, sub, _vd.foundation_part, 0, 0); + AddChildSpriteToFoundation(image, pal, sub, _vd.foundation_part, extra_offs_x, extra_offs_y); } else { - DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z, sub); + DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z, sub, extra_offs_x, extra_offs_y); } } @@ -1300,8 +1303,7 @@ static void ViewportDrawTileSprites(const TileSpriteToDrawVector *tstdv) { const TileSpriteToDraw *tsend = tstdv->End(); for (const TileSpriteToDraw *ts = tstdv->Begin(); ts != tsend; ++ts) { - Point pt = RemapCoords(ts->x, ts->y, ts->z); - DrawSprite(ts->image, ts->pal, pt.x, pt.y, ts->sub); + DrawSprite(ts->image, ts->pal, ts->x, ts->y, ts->sub); } } diff --git a/src/viewport_func.h b/src/viewport_func.h index f5c9c9410c..601c5a574f 100644 --- a/src/viewport_func.h +++ b/src/viewport_func.h @@ -33,8 +33,8 @@ static inline void MaxZoomInOut(int how, Window *w) void OffsetGroundSprite(int x, int y); -void DrawGroundSprite(SpriteID image, SpriteID pal, const SubSprite *sub = NULL); -void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z, const SubSprite *sub = NULL); +void DrawGroundSprite(SpriteID image, SpriteID pal, const SubSprite *sub = NULL, int extra_offs_x = 0, int extra_offs_y = 0); +void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z, const SubSprite *sub = NULL, int extra_offs_x = 0, int extra_offs_y = 0); void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w, int h, int dz, int z, bool transparent = false, int bb_offset_x = 0, int bb_offset_y = 0, int bb_offset_z = 0, const SubSprite *sub = NULL); void AddStringToDraw(int x, int y, StringID string, uint64 params_1, uint64 params_2, uint16 colour = 0, uint16 width = 0); void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y, bool transparent = false, const SubSprite *sub = NULL);