From 37ed615df1f7671c06074e0f3c4b9c6b3cc3e4cc Mon Sep 17 00:00:00 2001 From: rubidium Date: Mon, 13 May 2013 19:22:08 +0000 Subject: [PATCH] (svn r25241) [1.3] -Backport from trunk: - Fix: Crash when AI is executing a command as it is bankrupted (removed from the game) [FS#5547] (r25236) - Fix: Give bridges owned by noone (from bankrupt companies) to the first company which replaces the bridge. Everyone could have removed/rebuild the bridge anyway [FS#5541] (r25231, r25227) - Fix: [NewGRF] Revise when vehicle running sound effects 04, 07 and 08 are played; in depot or tunnel, or when crashed or stopped: No sound. Braking: Effect 08 instead of 07 [FS#5538] (r25226) - Fix: [NewGRF] Play vehicle sound effect also for planes (r25225) - Fix: [NewGRF] cur_speed is only valid for the front engine, so make other engines in the consist use the speed of the front [FS#5534] (r25224) --- src/ai/ai_instance.cpp | 13 ++++++++++-- src/tunnelbridge_cmd.cpp | 19 +++++++++++++---- src/vehicle.cpp | 46 ++++++++++++++++++++++++++++++++++------ 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp index 4d808e0558..f109a09260 100644 --- a/src/ai/ai_instance.cpp +++ b/src/ai/ai_instance.cpp @@ -238,8 +238,17 @@ ScriptInfo *AIInstance::FindLibrary(const char *library, int version) */ void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) { - Company::Get(_current_company)->ai_instance->DoCommandCallback(result, tile, p1, p2); - Company::Get(_current_company)->ai_instance->Continue(); + /* + * The company might not exist anymore. Check for this. + * The command checks are not useful since this callback + * is also called when the command fails, which is does + * when the company does not exist anymore. + */ + const Company *c = Company::GetIfValid(_current_company); + if (c == NULL || c->ai_instance == NULL) return; + + c->ai_instance->DoCommandCallback(result, tile, p1, p2); + c->ai_instance->Continue(); } CommandCallback *AIInstance::GetDoCommandCallback() diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 1abb0c1a7b..b0a4c6ad8c 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -295,6 +295,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u CommandCost cost(EXPENSES_CONSTRUCTION); Owner owner; + bool is_new_owner; if (IsBridgeTile(tile_start) && IsBridgeTile(tile_end) && GetOtherBridgeEnd(tile_start) == tile_end && GetTunnelBridgeTransportType(tile_start) == transport_type) { @@ -325,13 +326,17 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u } /* Do not allow replacing another company's bridges. */ - if (!IsTileOwner(tile_start, company) && !IsTileOwner(tile_start, OWNER_TOWN)) { + if (!IsTileOwner(tile_start, company) && !IsTileOwner(tile_start, OWNER_TOWN) && !IsTileOwner(tile_start, OWNER_NONE)) { return_cmd_error(STR_ERROR_AREA_IS_OWNED_BY_ANOTHER); } cost.AddCost((bridge_len + 1) * _price[PR_CLEAR_BRIDGE]); // The cost of clearing the current bridge. owner = GetTileOwner(tile_start); + /* If bridge belonged to bankrupt company, it has a new owner now */ + is_new_owner = (owner == OWNER_NONE); + if (is_new_owner) owner = company; + switch (transport_type) { case TRANSPORT_RAIL: /* Keep the reservation, the path stays valid. */ @@ -438,6 +443,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u } owner = company; + is_new_owner = true; } /* do the drill? */ @@ -447,8 +453,8 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u Company *c = Company::GetIfValid(owner); switch (transport_type) { case TRANSPORT_RAIL: - /* Add to company infrastructure count if building a new bridge. */ - if (!IsBridgeTile(tile_start) && c != NULL) c->infrastructure.rail[railtype] += (bridge_len + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR; + /* Add to company infrastructure count if required. */ + if (is_new_owner && c != NULL) c->infrastructure.rail[railtype] += (bridge_len + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR; MakeRailBridgeRamp(tile_start, owner, bridge_type, dir, railtype); MakeRailBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), railtype); SetTunnelBridgeReservation(tile_start, pbs_reservation); @@ -457,6 +463,11 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u case TRANSPORT_ROAD: { RoadTypes prev_roadtypes = IsBridgeTile(tile_start) ? GetRoadTypes(tile_start) : ROADTYPES_NONE; + if (is_new_owner) { + /* Also give unowned present roadtypes to new owner */ + if (HasBit(prev_roadtypes, ROADTYPE_ROAD) && GetRoadOwner(tile_start, ROADTYPE_ROAD) == OWNER_NONE) ClrBit(prev_roadtypes, ROADTYPE_ROAD); + if (HasBit(prev_roadtypes, ROADTYPE_TRAM) && GetRoadOwner(tile_start, ROADTYPE_TRAM) == OWNER_NONE) ClrBit(prev_roadtypes, ROADTYPE_TRAM); + } if (c != NULL) { /* Add all new road types to the company infrastructure counter. */ RoadType new_rt; @@ -475,7 +486,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u } case TRANSPORT_WATER: - if (!IsBridgeTile(tile_start) && c != NULL) c->infrastructure.water += (bridge_len + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR; + if (is_new_owner && c != NULL) c->infrastructure.water += (bridge_len + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR; MakeAqueductBridgeRamp(tile_start, owner, dir); MakeAqueductBridgeRamp(tile_end, owner, ReverseDiagDir(dir)); break; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 2f11421d65..6fc5c906ab 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -877,7 +877,9 @@ void CallVehicleTicks() case VEH_TRAIN: case VEH_ROAD: case VEH_AIRCRAFT: - case VEH_SHIP: + case VEH_SHIP: { + Vehicle *front = v->First(); + if (v->vcache.cached_cargo_age_period != 0) { v->cargo_age_counter = min(v->cargo_age_counter, v->vcache.cached_cargo_age_period); if (--v->cargo_age_counter == 0) { @@ -886,16 +888,46 @@ void CallVehicleTicks() } } - if (v->type == VEH_TRAIN && Train::From(v)->IsWagon()) continue; - if (v->type == VEH_AIRCRAFT && v->subtype != AIR_HELICOPTER) continue; - if (v->type == VEH_ROAD && !RoadVehicle::From(v)->IsFrontEngine()) continue; + /* Do not play any sound when crashed */ + if (front->vehstatus & VS_CRASHED) continue; - v->motion_counter += v->cur_speed; + /* Do not play any sound when in depot or tunnel */ + if (v->vehstatus & VS_HIDDEN) continue; + + /* Do not play any sound when stopped */ + if ((front->vehstatus & VS_STOPPED) && (front->type != VEH_TRAIN || front->cur_speed == 0)) continue; + + /* Check vehicle type specifics */ + switch (v->type) { + case VEH_TRAIN: + if (Train::From(v)->IsWagon()) continue; + break; + + case VEH_ROAD: + if (!RoadVehicle::From(v)->IsFrontEngine()) continue; + break; + + case VEH_AIRCRAFT: + if (!Aircraft::From(v)->IsNormalAircraft()) continue; + break; + + default: + break; + } + + v->motion_counter += front->cur_speed; /* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */ - if (GB(v->motion_counter, 0, 8) < v->cur_speed) PlayVehicleSound(v, VSE_RUNNING); + if (GB(v->motion_counter, 0, 8) < front->cur_speed) PlayVehicleSound(v, VSE_RUNNING); /* Play an alternating running sound every 16 ticks */ - if (GB(v->tick_counter, 0, 4) == 0) PlayVehicleSound(v, v->cur_speed > 0 ? VSE_RUNNING_16 : VSE_STOPPED_16); + if (GB(v->tick_counter, 0, 4) == 0) { + /* Play running sound when speed > 0 and not braking */ + bool running = (front->cur_speed > 0) && !(front->vehstatus & (VS_STOPPED | VS_TRAIN_SLOWING)); + PlayVehicleSound(v, running ? VSE_RUNNING_16 : VSE_STOPPED_16); + } + + break; + } } }