From 71a5abd42b56fbbefbdddb253fbc746a54fdcb57 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 12 Oct 2021 20:19:53 +0100 Subject: [PATCH 01/30] Fix aircraft shadows being drawn facing the wrong direction --- src/aircraft.h | 1 + src/aircraft_cmd.cpp | 24 +++++++++++++++++++----- src/vehicle_base.h | 2 +- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/aircraft.h b/src/aircraft.h index c44d02f041..9e9d3106ed 100644 --- a/src/aircraft.h +++ b/src/aircraft.h @@ -96,6 +96,7 @@ struct Aircraft FINAL : public SpecializedVehicle { ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_AIRCRAFT_INC : EXPENSES_AIRCRAFT_RUN; } bool IsPrimaryVehicle() const { return this->IsNormalAircraft(); } void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const; + Direction GetMapImageDirection() const { return this->First()->direction; } int GetDisplaySpeed() const { return this->cur_speed; } int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed; } int GetSpeedOldUnits() const { return this->vcache.cached_max_speed * 10 / 128; } diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index f0167ae0d2..583ad7acc3 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -172,6 +172,22 @@ static StationID FindNearestHangar(const Aircraft *v) void Aircraft::GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const { + if (this->subtype == AIR_SHADOW) { + Aircraft *first = this->First(); + if (first->cur_image_valid_dir != direction || HasBit(first->vcache.cached_veh_flags, VCF_IMAGE_REFRESH)) { + VehicleSpriteSeq seq; + first->UpdateImageState(direction, seq); + if (first->sprite_seq != seq) { + first->sprite_seq = seq; + first->UpdateSpriteSeqBound(); + first->Vehicle::UpdateViewport(true); + } + } + + result->CopyWithoutPalette(first->sprite_seq); // the shadow is never coloured + return; + } + uint8 spritenum = this->spritenum; if (is_custom_sprite(spritenum)) { @@ -552,10 +568,8 @@ void SetAircraftPosition(Aircraft *v, int x, int y, int z) safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE); u->z_pos = GetSlopePixelZ(safe_x, safe_y); - u->sprite_seq.CopyWithoutPalette(v->sprite_seq); // the shadow is never coloured - u->sprite_seq_bounds = v->sprite_seq_bounds; - - u->UpdatePositionAndViewport(); + u->UpdatePosition(); + u->UpdateViewport(true, false); u = u->Next(); if (u != nullptr) { @@ -1364,7 +1378,7 @@ TileIndex Aircraft::GetOrderStationLocation(StationID station) void Aircraft::MarkDirty() { this->colourmap = PAL_NONE; - this->InvalidateImageCache(); + this->InvalidateImageCacheOfChain(); this->UpdateViewport(true, false); if (this->subtype == AIR_HELICOPTER) { Aircraft *rotor = this->Next()->Next(); diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 68012e51ac..c033ef56c9 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -1387,7 +1387,7 @@ public: inline void UpdateImageStateUsingMapDirection(VehicleSpriteSeq &seq) { - this->UpdateImageState(this->GetMapImageDirection(), seq); + this->UpdateImageState(((T *)this)->GetMapImageDirection(), seq); } private: From c64f48f2bd72e3b685212cb3af64ba3df8531928 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 12 Oct 2021 20:26:13 +0100 Subject: [PATCH 02/30] Debug: Add direction and spritenum info to vehicle debug window --- src/table/newgrf_debug_data.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index 5fa8c129e5..d7f2410dd6 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.h @@ -112,8 +112,9 @@ class NIHVehicle : public NIHelper { seprintf(buffer, lastof(buffer), " VirtXYTile: %X (%u x %u)", vtile, TileX(vtile), TileY(vtile)); print(buffer); } - b = buffer + seprintf(buffer, lastof(buffer), " Position: %X, %X, %X", v->x_pos, v->y_pos, v->z_pos); + b = buffer + seprintf(buffer, lastof(buffer), " Position: %X, %X, %X, Direction: %d", v->x_pos, v->y_pos, v->z_pos, v->direction); if (v->type == VEH_TRAIN) seprintf(b, lastof(buffer), ", tile margin: %d", GetTileMarginInFrontOfTrain(Train::From(v))); + if (v->type == VEH_SHIP) seprintf(b, lastof(buffer), ", rotation: %d", Ship::From(v)->rotation); print(buffer); if (v->IsPrimaryVehicle()) { @@ -353,7 +354,8 @@ class NIHVehicle : public NIHelper { } } - seprintf(buffer, lastof(buffer), " Current image cacheable: %s", v->cur_image_valid_dir != INVALID_DIR ? "yes" : "no"); + seprintf(buffer, lastof(buffer), " Current image cacheable: %s (%X), spritenum: %X", + v->cur_image_valid_dir != INVALID_DIR ? "yes" : "no", v->cur_image_valid_dir, v->spritenum); print(buffer); } From 9254be5b3c72136f1c66b9d4577ee4cb86361648 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 12 Oct 2021 20:35:07 +0100 Subject: [PATCH 03/30] Debug: Show info of all aircraft parts in vehicle debug window --- src/table/newgrf_debug_data.h | 122 +++++++++++++++++++--------------- 1 file changed, 70 insertions(+), 52 deletions(-) diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index d7f2410dd6..510b87ed41 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.h @@ -92,10 +92,26 @@ class NIHVehicle : public NIHelper { /* virtual */ void ExtraInfo(uint index, std::function print) const override { - char buffer[1024]; + Vehicle *v = Vehicle::Get(index); print("Debug Info:"); - seprintf(buffer, lastof(buffer), " Index: %u", index); + this->VehicleInfo(v, print, true); + if (v->type == VEH_AIRCRAFT) { + print(""); + print("Shadow:"); + this->VehicleInfo(v->Next(), print, false); + if (v->Next()->Next() != nullptr) { + print(""); + print("Rotor:"); + this->VehicleInfo(v->Next()->Next(), print, false); + } + } + } + + void VehicleInfo(Vehicle *v, std::function print, bool show_engine) const + { + char buffer[1024]; + seprintf(buffer, lastof(buffer), " Index: %u", v->index); print(buffer); char *b = buffer; b += seprintf(b, lastof(buffer), " Flags: "); @@ -297,60 +313,62 @@ class NIHVehicle : public NIHelper { } } - seprintf(buffer, lastof(buffer), " Engine: %u", v->engine_type); - print(buffer); - const Engine *e = Engine::GetIfValid(v->engine_type); - if (e != nullptr) { - seprintf(buffer, lastof(buffer), " Callbacks: 0x%X, CB36 Properties: 0x" OTTD_PRINTFHEX64, - e->callbacks_used, e->cb36_properties_used); + if (show_engine) { + seprintf(buffer, lastof(buffer), " Engine: %u", v->engine_type); print(buffer); - uint64 cb36_properties = e->cb36_properties_used; - if (!e->sprite_group_cb36_properties_used.empty()) { - const SpriteGroup *root_spritegroup = nullptr; - if (v->IsGroundVehicle()) root_spritegroup = GetWagonOverrideSpriteSet(v->engine_type, v->cargo_type, v->GetGroundVehicleCache()->first_engine); - if (root_spritegroup == nullptr) { - CargoID cargo = v->cargo_type; - assert(cargo < lengthof(e->grf_prop.spritegroup)); - root_spritegroup = e->grf_prop.spritegroup[cargo] != nullptr ? e->grf_prop.spritegroup[cargo] : e->grf_prop.spritegroup[CT_DEFAULT]; - } - auto iter = e->sprite_group_cb36_properties_used.find(root_spritegroup); - if (iter != e->sprite_group_cb36_properties_used.end()) { - cb36_properties = iter->second; - seprintf(buffer, lastof(buffer), " Current sprite group: CB36 Properties: 0x" OTTD_PRINTFHEX64, iter->second); - print(buffer); - } - } - if (cb36_properties != UINT64_MAX) { - uint64 props = cb36_properties; - while (props) { - PropertyID prop = (PropertyID)FindFirstBit64(props); - props = KillFirstBit(props); - uint16 res = GetVehicleProperty(v, prop, CALLBACK_FAILED); - if (res == CALLBACK_FAILED) { - seprintf(buffer, lastof(buffer), " CB36: 0x%X --> FAILED", prop); - } else { - seprintf(buffer, lastof(buffer), " CB36: 0x%X --> 0x%X", prop, res); + const Engine *e = Engine::GetIfValid(v->engine_type); + if (e != nullptr) { + seprintf(buffer, lastof(buffer), " Callbacks: 0x%X, CB36 Properties: 0x" OTTD_PRINTFHEX64, + e->callbacks_used, e->cb36_properties_used); + print(buffer); + uint64 cb36_properties = e->cb36_properties_used; + if (!e->sprite_group_cb36_properties_used.empty()) { + const SpriteGroup *root_spritegroup = nullptr; + if (v->IsGroundVehicle()) root_spritegroup = GetWagonOverrideSpriteSet(v->engine_type, v->cargo_type, v->GetGroundVehicleCache()->first_engine); + if (root_spritegroup == nullptr) { + CargoID cargo = v->cargo_type; + assert(cargo < lengthof(e->grf_prop.spritegroup)); + root_spritegroup = e->grf_prop.spritegroup[cargo] != nullptr ? e->grf_prop.spritegroup[cargo] : e->grf_prop.spritegroup[CT_DEFAULT]; } + auto iter = e->sprite_group_cb36_properties_used.find(root_spritegroup); + if (iter != e->sprite_group_cb36_properties_used.end()) { + cb36_properties = iter->second; + seprintf(buffer, lastof(buffer), " Current sprite group: CB36 Properties: 0x" OTTD_PRINTFHEX64, iter->second); + print(buffer); + } + } + if (cb36_properties != UINT64_MAX) { + uint64 props = cb36_properties; + while (props) { + PropertyID prop = (PropertyID)FindFirstBit64(props); + props = KillFirstBit(props); + uint16 res = GetVehicleProperty(v, prop, CALLBACK_FAILED); + if (res == CALLBACK_FAILED) { + seprintf(buffer, lastof(buffer), " CB36: 0x%X --> FAILED", prop); + } else { + seprintf(buffer, lastof(buffer), " CB36: 0x%X --> 0x%X", prop, res); + } + print(buffer); + } + } + YearMonthDay ymd; + ConvertDateToYMD(e->intro_date, &ymd); + seprintf(buffer, lastof(buffer), " Intro: %4i-%02i-%02i, Age: %u, Base life: %u, Durations: %u %u %u (sum: %u)", + ymd.year, ymd.month + 1, ymd.day, e->age, e->info.base_life, e->duration_phase_1, e->duration_phase_2, e->duration_phase_3, + e->duration_phase_1 + e->duration_phase_2 + e->duration_phase_3); + print(buffer); + if (e->type == VEH_TRAIN) { + const RailtypeInfo *rti = GetRailTypeInfo(e->u.rail.railtype); + seprintf(buffer, lastof(buffer), " Railtype: %u (0x" OTTD_PRINTFHEX64 "), Compatible: 0x" OTTD_PRINTFHEX64 ", Powered: 0x" OTTD_PRINTFHEX64 ", All compatible: 0x" OTTD_PRINTFHEX64, + e->u.rail.railtype, (static_cast(1) << e->u.rail.railtype), rti->compatible_railtypes, rti->powered_railtypes, rti->all_compatible_railtypes); + print(buffer); + } + if (e->type == VEH_ROAD) { + const RoadTypeInfo* rti = GetRoadTypeInfo(e->u.road.roadtype); + seprintf(buffer, lastof(buffer), " Roadtype: %u (0x" OTTD_PRINTFHEX64 "), Powered: 0x" OTTD_PRINTFHEX64, + e->u.road.roadtype, (static_cast(1) << e->u.road.roadtype), rti->powered_roadtypes); print(buffer); } - } - YearMonthDay ymd; - ConvertDateToYMD(e->intro_date, &ymd); - seprintf(buffer, lastof(buffer), " Intro: %4i-%02i-%02i, Age: %u, Base life: %u, Durations: %u %u %u (sum: %u)", - ymd.year, ymd.month + 1, ymd.day, e->age, e->info.base_life, e->duration_phase_1, e->duration_phase_2, e->duration_phase_3, - e->duration_phase_1 + e->duration_phase_2 + e->duration_phase_3); - print(buffer); - if (e->type == VEH_TRAIN) { - const RailtypeInfo *rti = GetRailTypeInfo(e->u.rail.railtype); - seprintf(buffer, lastof(buffer), " Railtype: %u (0x" OTTD_PRINTFHEX64 "), Compatible: 0x" OTTD_PRINTFHEX64 ", Powered: 0x" OTTD_PRINTFHEX64 ", All compatible: 0x" OTTD_PRINTFHEX64, - e->u.rail.railtype, (static_cast(1) << e->u.rail.railtype), rti->compatible_railtypes, rti->powered_railtypes, rti->all_compatible_railtypes); - print(buffer); - } - if (e->type == VEH_ROAD) { - const RoadTypeInfo* rti = GetRoadTypeInfo(e->u.road.roadtype); - seprintf(buffer, lastof(buffer), " Roadtype: %u (0x" OTTD_PRINTFHEX64 "), Powered: 0x" OTTD_PRINTFHEX64, - e->u.road.roadtype, (static_cast(1) << e->u.road.roadtype), rti->powered_roadtypes); - print(buffer); } } From 900b9fdf3b9a7fee6e454753c8b5a3d28419916c Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 16 Oct 2021 19:59:43 +0100 Subject: [PATCH 04/30] Fix crash with wrong-way running on signalled tunnel/bridge When using the ignore signals buttons, and exiting the bridge/tunnel in some cases --- src/train_cmd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index e17d75bd46..bfbf822238 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -3398,7 +3398,7 @@ static void UpdateAspectFromBridgeMiddleSignalChange(TileIndex entrance, TileInd static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDirection dir, bool free) { - if (IsBridge(end) && _m[end].m2 != 0) { + if (IsBridge(end) && _m[end].m2 != 0 && IsTunnelBridgeSignalSimulationEntrance(end)) { /* Clearing last bridge signal. */ int signal_offset = GetAndClearLastBridgeEntranceSetSignalIndex(end); if (signal_offset) { @@ -3424,7 +3424,7 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir if (IsTunnelBridgeSignalSimulationEntrance(end)) SetTunnelBridgeEntranceSignalGreen(end); if (IsTunnelBridgeSignalSimulationEntrance(tile)) SetTunnelBridgeEntranceSignalGreen(tile); - } else if (IsTunnel(end) && _extra_aspects > 0) { + } else if (IsTunnel(end) && _extra_aspects > 0 && IsTunnelBridgeSignalSimulationEntrance(end)) { uint signal_count = GetTunnelBridgeLength(tile, end) / GetTunnelBridgeSignalSimulationSpacing(end); if (signal_count > 0) UpdateEntranceAspectFromMiddleSignalChange(end, signal_count - 1); } From 4a1e347f8e19c89d31e56aac45b33497d1300ac7 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 19 Oct 2021 00:38:57 +0100 Subject: [PATCH 05/30] Fix desync when using "perfect" tree placement mode in arctic climate --- src/tree_cmd.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index 0d1888480f..fff8c8370a 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -357,6 +357,7 @@ int MaxTreeCount(const TileIndex tile) int max_trees_snow_line_based = 4; if (_settings_game.game_creation.landscape == LT_ARCTIC) { + if (_settings_game.construction.trees_around_snow_line_range != _previous_trees_around_snow_line_range) RecalculateArcticTreeOccuranceArray(); const uint height_above_snow_line = std::max(0, tile_z - _settings_game.game_creation.snow_line_height); max_trees_snow_line_based = (height_above_snow_line < _arctic_tree_occurance.size()) ? (1 + (_arctic_tree_occurance[height_above_snow_line] * 4) / 255) : From b58ff65c5c31359bbfadf7d13859a4155b5a954c Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 19 Oct 2021 00:39:41 +0100 Subject: [PATCH 06/30] Debug: Fix company money state checksum being logged with wrong company --- src/openttd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openttd.cpp b/src/openttd.cpp index 4317694d96..e3c15e0839 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1890,12 +1890,12 @@ void StateGameLoop() CallWindowGameTickEvent(); NewsLoop(); - cur_company.Restore(); for (Company *c : Company::Iterate()) { DEBUG_UPDATESTATECHECKSUM("Company: %u, Money: " OTTD_PRINTF64, c->index, (int64)c->money); UpdateStateChecksum(c->money); } + cur_company.Restore(); } if (_extra_aspects > 0) FlushDeferredAspectUpdates(); From a9c2c7288ad529a6d524391a1f5c9b854d2890bf Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 19 Oct 2021 00:50:05 +0100 Subject: [PATCH 07/30] Fix compilation when ENABLE_NETWORK_SYNC_EVERY_FRAME is defined This is set by RANDOM_DEBUG See also: https://github.com/OpenTTD/OpenTTD/issues/9624 --- src/network/network_client.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 1e76424559..0bb519e349 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -1051,7 +1051,11 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_FRAME(Packet *p #ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME /* Test if the server supports this option * and if we are at the frame the server is */ - if (p->pos + 1 < p->size) { +#ifdef NETWORK_SEND_DOUBLE_SEED + if (p->CanReadFromPacket(4 + 4 + 8)) { +#else + if (p->CanReadFromPacket(4 + 8)) { +#endif _sync_frame = _frame_counter_server; _sync_seed_1 = p->Recv_uint32(); #ifdef NETWORK_SEND_DOUBLE_SEED From ec8512e2ea915c9c15e6ba97a78ca5bc4e121de7 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 24 Oct 2021 00:07:54 +0100 Subject: [PATCH 08/30] When declining to buy a company, ask the next company immediately --- src/command.cpp | 4 +++- src/command_type.h | 1 + src/company_base.h | 3 ++- src/company_cmd.cpp | 1 + src/company_gui.cpp | 8 ++++++++ src/economy.cpp | 27 +++++++++++++++++++++++++++ src/saveload/company_sl.cpp | 1 + src/saveload/extended_ver_sl.cpp | 1 + src/saveload/extended_ver_sl.h | 1 + 9 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index b63b416141..2f4cca0b33 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -144,6 +144,7 @@ CommandProc CmdPause; CommandProc CmdBuyShareInCompany; CommandProc CmdSellShareInCompany; CommandProc CmdBuyCompany; +CommandProc CmdDeclineBuyCompany; CommandProc CmdFoundTown; CommandProc CmdRenameTown; @@ -380,7 +381,8 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdBuyShareInCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_BUY_SHARE_IN_COMPANY DEF_CMD(CmdSellShareInCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_SELL_SHARE_IN_COMPANY - DEF_CMD(CmdBuyCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_BUY_COMANY + DEF_CMD(CmdBuyCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_BUY_COMPANY + DEF_CMD(CmdDeclineBuyCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_DECLINE_BUY_COMPANY DEF_CMD(CmdFoundTown, CMD_DEITY | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_FOUND_TOWN; founding random town can fail only in exec run DEF_CMD(CmdRenameTown, CMD_DEITY | CMD_SERVER, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_TOWN diff --git a/src/command_type.h b/src/command_type.h index b7b29cde0a..073888428b 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -322,6 +322,7 @@ enum Commands { CMD_BUY_SHARE_IN_COMPANY, ///< buy a share from a company CMD_SELL_SHARE_IN_COMPANY, ///< sell a share from a company CMD_BUY_COMPANY, ///< buy a company which is bankrupt + CMD_DECLINE_BUY_COMPANY, ///< decline to buy a company which is bankrupt CMD_FOUND_TOWN, ///< found a town CMD_RENAME_TOWN, ///< rename a town diff --git a/src/company_base.h b/src/company_base.h index 0d2e0621b8..dc046eb907 100644 --- a/src/company_base.h +++ b/src/company_base.h @@ -81,6 +81,7 @@ struct CompanyProperties { Year inaugurated_year; ///< Year of starting the company. byte months_of_bankruptcy; ///< Number of months that the company is unable to pay its debts + CompanyID bankrupt_last_asked; ///< Which company was most recently asked about buying it? CompanyMask bankrupt_asked; ///< which companies were asked about buying it? int16 bankrupt_timeout; ///< If bigger than \c 0, amount of time to wait for an answer on an offer to buy this company. Money bankrupt_value; @@ -107,7 +108,7 @@ struct CompanyProperties { : name_2(0), name_1(0), president_name_1(0), president_name_2(0), face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0), location_of_HQ(0), last_build_coordinate(0), share_owners(), inaugurated_year(0), - months_of_bankruptcy(0), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0), + months_of_bankruptcy(0), bankrupt_last_asked(INVALID_COMPANY), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0), terraform_limit(0), clear_limit(0), tree_limit(0), purchase_land_limit(0), build_object_limit(0), is_ai(false) {} }; diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 900ccb739b..eba6cfa968 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -707,6 +707,7 @@ static void HandleBankruptcyTakeover(Company *c) } SetBit(c->bankrupt_asked, best->index); + c->bankrupt_last_asked = best->index; c->bankrupt_timeout = TAKE_OVER_TIMEOUT; if (best->is_ai) { diff --git a/src/company_gui.cpp b/src/company_gui.cpp index bac4d59a3d..ad514b06e2 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -2791,6 +2791,14 @@ struct BuyCompanyWindow : Window { this->InitNested(window_number); } + ~BuyCompanyWindow() + { + const Company *c = Company::GetIfValid((CompanyID)this->window_number); + if (c != nullptr && HasBit(c->bankrupt_asked, _current_company)) { + DoCommandP(0, this->window_number, 0, CMD_DECLINE_BUY_COMPANY); + } + } + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { diff --git a/src/economy.cpp b/src/economy.cpp index dcdc7e5932..5d7639649c 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -2285,6 +2285,8 @@ static void DoAcquireCompany(Company *c) if (c->is_ai) AI::Stop(c->index); + c->bankrupt_asked = 0; + DeleteCompanyWindows(ci); InvalidateWindowClassesData(WC_TRAINS_LIST, 0); InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS, 0); @@ -2429,6 +2431,31 @@ CommandCost CmdBuyCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 return cost; } +/** + * Decline to buy up another company. + * When a competing company is gone bankrupt you get the chance to purchase + * that company, actively decline the offer. + * @param tile unused + * @param flags type of operation + * @param p1 company to buy up + * @param p2 unused + * @param text unused + * @return the cost of this operation or an error + */ +CommandCost CmdDeclineBuyCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + CompanyID target_company = (CompanyID)p1; + Company *c = Company::GetIfValid(target_company); + if (c == nullptr) return CommandCost(); + + if (flags & DC_EXEC) { + if (c->bankrupt_last_asked == _current_company) { + c->bankrupt_timeout = 0; + } + } + return CommandCost(); +} + uint ScaleQuantity(uint amount, int scale_factor) { scale_factor += 200; // ensure factor is positive diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 041af087ea..21fbb7894b 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -274,6 +274,7 @@ static const SaveLoad _company_desc[] = { SLE_VAR(CompanyProperties, num_valid_stat_ent, SLE_UINT8), SLE_VAR(CompanyProperties, months_of_bankruptcy, SLE_UINT8), + SLE_CONDVAR_X(CompanyProperties, bankrupt_last_asked, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_BANKRUPTCY_EXTRA)), SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_UINT16, SLV_104, SL_MAX_VERSION), SLE_VAR(CompanyProperties, bankrupt_timeout, SLE_INT16), diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 863d80c960..edb314f3b2 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -156,6 +156,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_EXTRA_STATION_NAMES, XSCF_NULL, 1, 1, "extra_station_names", nullptr, nullptr, nullptr }, { XSLFI_DEPOT_ORDER_EXTRA_FLAGS,XSCF_IGNORABLE_UNKNOWN, 1, 1, "depot_order_extra_flags", nullptr, nullptr, nullptr }, { XSLFI_EXTRA_SIGNAL_TYPES, XSCF_NULL, 1, 1, "extra_signal_types", nullptr, nullptr, nullptr }, + { XSLFI_BANKRUPTCY_EXTRA, XSCF_NULL, 1, 1, "bankruptcy_extra", nullptr, nullptr, nullptr }, { XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker }; diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index d42986dcce..200f668e20 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -110,6 +110,7 @@ enum SlXvFeatureIndex { XSLFI_EXTRA_STATION_NAMES, ///< Extra station names XSLFI_DEPOT_ORDER_EXTRA_FLAGS, ///< Depot order extra flags XSLFI_EXTRA_SIGNAL_TYPES, ///< Extra signal types + XSLFI_BANKRUPTCY_EXTRA, ///< Extra company bankruptcy fields XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk From 296987153b51c3583a1a1b85375d4f07126d9ec3 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 24 Oct 2021 00:11:51 +0100 Subject: [PATCH 09/30] Add console command to offer a company for sale --- src/company_cmd.cpp | 12 ++++++++++++ src/company_type.h | 1 + src/console_cmds.cpp | 25 +++++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index eba6cfa968..29824ff1ca 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -943,6 +943,18 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 break; } + case CCA_SALE: { + Company *c = Company::GetIfValid(company_id); + if (c == nullptr) return CMD_ERROR; + + if (!(flags & DC_EXEC)) return CommandCost(); + + c->bankrupt_value = CalculateCompanyValue(c, false); + c->bankrupt_asked = 1 << c->index; // Don't ask the owner + c->bankrupt_timeout = 0; + break; + } + default: return CMD_ERROR; } diff --git a/src/company_type.h b/src/company_type.h index de2556b914..740663a4cf 100644 --- a/src/company_type.h +++ b/src/company_type.h @@ -65,6 +65,7 @@ enum CompanyCtrlAction { CCA_NEW, ///< Create a new company. CCA_NEW_AI, ///< Create a new AI company. CCA_DELETE, ///< Delete a company. + CCA_SALE, ///< Offer a company for sale. CCA_END, ///< Sentinel for end. }; diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 27635eae96..f84db5a177 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -962,6 +962,30 @@ DEF_CONSOLE_CMD(ConResetCompany) return true; } +DEF_CONSOLE_CMD(ConOfferCompanySale) +{ + if (argc == 0) { + IConsoleHelp("Offer a company for sale. Usage: 'offer_company_sale '"); + IConsoleHelp("For company-id's, see the list of companies from the dropdown menu. Company 1 is 1, etc."); + return true; + } + + if (argc != 2) return false; + + CompanyID index = (CompanyID)(atoi(argv[1]) - 1); + + /* Check valid range */ + if (!Company::IsValidID(index)) { + IConsolePrintF(CC_ERROR, "Company does not exist. Company-id must be between 1 and %d.", MAX_COMPANIES); + return true; + } + + DoCommandP(0, CCA_SALE | index << 16, 0, CMD_COMPANY_CTRL); + IConsolePrint(CC_DEFAULT, "Company offered for sale."); + + return true; +} + DEF_CONSOLE_CMD(ConNetworkClients) { if (argc == 0) { @@ -3447,6 +3471,7 @@ void IConsoleStdLibRegister() IConsole::CmdRegister("move", ConMoveClient, ConHookServerOnly); IConsole::CmdRegister("reset_company", ConResetCompany, ConHookServerOnly); IConsole::AliasRegister("clean_company", "reset_company %A"); + IConsole::CmdRegister("offer_company_sale", ConOfferCompanySale, ConHookServerOrNoNetwork); IConsole::CmdRegister("client_name", ConClientNickChange, ConHookServerOnly); IConsole::CmdRegister("kick", ConKick, ConHookServerOnly); IConsole::CmdRegister("ban", ConBan, ConHookServerOnly); From 28fd5498083c58a973dbe39c3c7e8b4cf2be980c Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 24 Oct 2021 12:23:52 +0100 Subject: [PATCH 10/30] Decline company takeover offer on company's behalf if company has no client --- src/company_cmd.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 29824ff1ca..1a49022071 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -37,6 +37,7 @@ #include "zoning.h" #include "tbtr_template_vehicle_func.h" #include "widgets/statusbar_widget.h" +#include "core/backup_type.hpp" #include "debug_desync.h" #include "table/strings.h" @@ -714,6 +715,11 @@ static void HandleBankruptcyTakeover(Company *c) AI::NewEvent(best->index, new ScriptEventCompanyAskMerger(c->index, ClampToI32(c->bankrupt_value))); } else if (IsInteractiveCompany(best->index)) { ShowBuyCompanyDialog(c->index); + } else if (!_networking || (_network_server && !NetworkCompanyHasClients(best->index))) { + /* This company can never accept the offer as there are no clients connected, decline the offer on the company's behalf */ + Backup cur_company(_current_company, best->index, FILE_LINE); + DoCommandP(0, c->index, 0, CMD_DECLINE_BUY_COMPANY); + cur_company.Restore(); } } From 8b5b96af77fb12db53d4871951e7080d9df49211 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 24 Oct 2021 13:33:02 +0100 Subject: [PATCH 11/30] Fix typos in PostProcessNetworks --- src/road.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/road.cpp b/src/road.cpp index a7f0f804dd..ac6c025a41 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -941,18 +941,18 @@ void PostProcessNetworks(const std::vector>& town_n } std::vector towns(network->towns); - + for (auto town_a : network->towns) { std::sort(towns.begin(), towns.end(), [&](const TileIndex& a, const TileIndex& b) { return DistanceManhattan(a, town_a) < DistanceManhattan(b, town_a); }); - const auto second_clostest_town = *(towns.begin() + 2); - const auto third_clostest_town = *(towns.begin() + 3); + const auto second_closest_town = *(towns.begin() + 2); + const auto third_closest_town = *(towns.begin() + 3); AyStar finder {}; { - FindPath(finder, town_a, second_clostest_town); + FindPath(finder, town_a, second_closest_town); finder.Clear(); - FindPath(finder, town_a, third_clostest_town); + FindPath(finder, town_a, third_closest_town); } finder.Free(); From 55620ff1625c6e93ca318bf137d9cb7da42b88e6 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Mon, 25 Oct 2021 00:29:51 +0100 Subject: [PATCH 12/30] Add general function for checking size of contiguous tile area --- src/map.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/map_func.h | 2 ++ 2 files changed, 55 insertions(+) diff --git a/src/map.cpp b/src/map.cpp index 49b16b642f..4778fd9c5a 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -16,6 +16,7 @@ #include "tunnelbridge_map.h" #include "3rdparty/cpp-btree/btree_map.h" #include +#include #include "safeguards.h" @@ -370,6 +371,58 @@ bool CircularTileSearch(TileIndex *tile, uint radius, uint w, uint h, TestTileOn return false; } +/** + * Generalized contiguous matching tile area size threshold function. + * Contiguous means directly adjacent by DiagDirection directions. + * + * @param tile to start the search from. + * @param threshold minimum number of matching tiles for success, searching is halted when this is reached. + * @param proc callback testing function pointer. + * @param user_data to be passed to the callback function. Depends on the implementation + * @return whether the contiguous tile area size is >= threshold + * @pre proc != nullptr + */ +bool EnoughContiguousTilesMatchingCondition(TileIndex tile, uint threshold, TestTileOnSearchProc proc, void *user_data) +{ + assert(proc != nullptr); + if (threshold == 0) return true; + + static_assert(MAX_MAP_TILES_BITS <= 30); + + btree::btree_set processed_tiles; + std::deque candidates; + uint matching_count = 0; + + auto process_tile = [&](TileIndex t, DiagDirection exclude_onward_dir) { + auto iter = processed_tiles.lower_bound(t); + if (iter != processed_tiles.end() && *iter == t) { + /* done this tile already */ + } else { + if (proc(t, user_data)) { + matching_count++; + for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) { + if (dir == exclude_onward_dir) continue; + TileIndex neighbour_tile = AddTileIndexDiffCWrap(t, TileIndexDiffCByDiagDir(dir)); + if (IsValidTile(neighbour_tile)) { + candidates.push_back(neighbour_tile | (ReverseDiagDir(dir) << 30)); + } + } + } + processed_tiles.insert(iter, t); + } + }; + process_tile(tile, INVALID_DIAGDIR); + + while (matching_count < threshold && !candidates.empty()) { + uint32 next = candidates.front(); + candidates.pop_front(); + TileIndex t = GB(next, 0, 30); + DiagDirection exclude_onward_dir = (DiagDirection)GB(next, 30, 2); + process_tile(t, exclude_onward_dir); + } + return matching_count >= threshold; +} + /** * Finds the distance for the closest tile with water/land given a tile * @param tile the tile to find the distance too diff --git a/src/map_func.h b/src/map_func.h index eebd21fb67..616c972f03 100644 --- a/src/map_func.h +++ b/src/map_func.h @@ -438,6 +438,8 @@ typedef bool TestTileOnSearchProc(TileIndex tile, void *user_data); bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data); bool CircularTileSearch(TileIndex *tile, uint radius, uint w, uint h, TestTileOnSearchProc proc, void *user_data); +bool EnoughContiguousTilesMatchingCondition(TileIndex tile, uint threshold, TestTileOnSearchProc proc, void *user_data); + /** * Get a random tile out of a given seed. * @param r the random 'seed' From 944f090b46cbd37a306d2cfd1743eb3629b508d4 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Mon, 25 Oct 2021 00:30:25 +0100 Subject: [PATCH 13/30] Add settings for minimum contiguous landmass size for town/city placement --- src/lang/english.txt | 6 ++++++ src/settings_gui.cpp | 2 ++ src/settings_type.h | 2 ++ src/table/settings.ini | 30 ++++++++++++++++++++++++++++++ src/town_cmd.cpp | 17 ++++++++++++++--- 5 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 36f75ff67e..92253d00b5 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1935,6 +1935,12 @@ STR_CONFIG_SETTING_INDUSTRY_CARGO_FACTOR :Industry cargo STR_CONFIG_SETTING_INDUSTRY_CARGO_FACTOR_HELPTEXT :Primary industry cargo production is scaled by approximately 2^factor (exponential). This excludes tree-cutting industries.{}This is not guaranteed to be fully compatible with all industry NewGRFs. STR_CONFIG_SETTING_TOWN_ABOVE_HEIGHT :No towns above height level: {STRING2} STR_CONFIG_SETTING_TOWN_ABOVE_HEIGHT_HELPTEXT :No towns above the specified height level are built during map creation. +STR_CONFIG_SETTING_MIN_TOWN_LAND_AREA :Minimum contiguous land area for towns: {STRING2} +STR_CONFIG_SETTING_MIN_TOWN_LAND_AREA_HELPTEXT :Towns can only be placed on contiguous landmasses of at least this many tiles. +STR_CONFIG_SETTING_MIN_CITY_LAND_AREA :Minimum contiguous land area for cities: {STRING2} +STR_CONFIG_SETTING_MIN_CITY_LAND_AREA_HELPTEXT :Cities can only be placed on contiguous landmasses of at least this many tiles. +STR_CONFIG_SETTING_MIN_LAND_AREA_VALUE :{NUM} +STR_CONFIG_SETTING_MIN_LAND_AREA_ZERO :Off STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :In game placement of trees: {STRING2} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Control random appearance of trees during the game. This might affect industries which rely on tree growth, for example lumber mills diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 248f9216c1..56518e716e 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -2067,6 +2067,8 @@ static SettingsContainer &GetSettingsTree() genworld->Add(new SettingEntry("economy.town_layout")); genworld->Add(new SettingEntry("economy.town_min_distance")); genworld->Add(new SettingEntry("economy.max_town_heightlevel")); + genworld->Add(new SettingEntry("economy.min_town_land_area")); + genworld->Add(new SettingEntry("economy.min_city_land_area")); genworld->Add(new SettingEntry("game_creation.build_public_roads")); genworld->Add(new SettingEntry("difficulty.industry_density")); genworld->Add(new SettingEntry("gui.pause_on_newgame")); diff --git a/src/settings_type.h b/src/settings_type.h index 5cb9cfd3f7..57bad87e0b 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -638,6 +638,8 @@ struct EconomySettings { bool allow_town_roads; ///< towns are allowed to build roads (always allowed when generating world / in SE) uint16 town_min_distance; ///< minimum distance between towns uint8 max_town_heightlevel; ///< maximum height level for towns + uint16 min_town_land_area; ///< minimum contiguous lang area for towns. + uint16 min_city_land_area; ///< minimum contiguous lang area for cities. TownFounding found_town; ///< town founding. bool station_noise_level; ///< build new airports when the town noise level is still within accepted limits uint16 town_noise_population[3]; ///< population to base decision on noise evaluation (@see town_council_tolerance) diff --git a/src/table/settings.ini b/src/table/settings.ini index 13c19b490d..1abaee37d5 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -961,6 +961,36 @@ strval = STR_JUST_INT cat = SC_BASIC patxname = ""max_town_heightlevel.economy.max_town_heightlevel"" +[SDT_VAR] +base = GameSettings +var = economy.min_town_land_area +type = SLE_UINT16 +guiflags = SGF_0ISDISABLED +def = 0 +min = 0 +max = 400 +interval = 5 +str = STR_CONFIG_SETTING_MIN_TOWN_LAND_AREA +strhelp = STR_CONFIG_SETTING_MIN_TOWN_LAND_AREA_HELPTEXT +strval = STR_CONFIG_SETTING_MIN_LAND_AREA_VALUE +cat = SC_BASIC +patxname = ""max_town_heightlevel.economy.min_town_land_area"" + +[SDT_VAR] +base = GameSettings +var = economy.min_city_land_area +type = SLE_UINT16 +guiflags = SGF_0ISDISABLED +def = 75 +min = 0 +max = 400 +interval = 5 +str = STR_CONFIG_SETTING_MIN_CITY_LAND_AREA +strhelp = STR_CONFIG_SETTING_MIN_CITY_LAND_AREA_HELPTEXT +strval = STR_CONFIG_SETTING_MIN_LAND_AREA_VALUE +cat = SC_BASIC +patxname = ""max_town_heightlevel.economy.min_city_land_area"" + ; link graph [SDT_VAR] diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 07f80a9c5b..c7c7927265 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -2108,7 +2108,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize * @param tile tile to check * @return error value or zero cost */ -static CommandCost TownCanBePlacedHere(TileIndex tile) +static CommandCost TownCanBePlacedHere(TileIndex tile, bool city) { /* Check if too close to the edge of map */ if (DistanceFromEdge(tile) < 12) { @@ -2130,6 +2130,17 @@ static CommandCost TownCanBePlacedHere(TileIndex tile) return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } + uint min_land_area = city ? _settings_game.economy.min_city_land_area : _settings_game.economy.min_town_land_area; + if (min_land_area > 0) { + if (!EnoughContiguousTilesMatchingCondition(tile, min_land_area, [](TileIndex t, void *data) -> bool { + if (!HasTileWaterClass(t) || GetWaterClass(t) == WATER_CLASS_INVALID) return true; + if (IsCoastTile(t) && !IsSlopeWithOneCornerRaised(GetTileSlope(t))) return true; + return false; + }, nullptr)) { + return_cmd_error(STR_ERROR_SITE_UNSUITABLE); + } + } + return CommandCost(EXPENSES_OTHER); } @@ -2197,7 +2208,7 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (!Town::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_TOWNS); if (!random) { - CommandCost ret = TownCanBePlacedHere(tile); + CommandCost ret = TownCanBePlacedHere(tile, city); if (ret.Failed()) return ret; } @@ -2408,7 +2419,7 @@ static Town *CreateRandomTown(uint attempts, uint32 townnameparts, TownSize size } /* Make sure town can be placed here */ - if (TownCanBePlacedHere(tile).Failed()) continue; + if (TownCanBePlacedHere(tile, city).Failed()) continue; /* Allocate a town struct */ Town *t = new Town(tile); From 53139c24052052ed928b571d21f708bec03bd118 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 26 Oct 2021 23:39:40 +0100 Subject: [PATCH 14/30] Add current day/month to tracerestrict and conditional order conditionals --- src/lang/english.txt | 6 ++++++ src/order_gui.cpp | 5 +++-- src/saveload/extended_ver_sl.cpp | 4 ++-- src/tracerestrict.cpp | 6 ++++++ src/tracerestrict.h | 4 +++- src/tracerestrict_gui.cpp | 7 +++++-- 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 92253d00b5..bb4778ab7e 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -3075,12 +3075,18 @@ STR_TRACE_RESTRICT_NO_PBS_BACK_PENALTY_CANCEL_SHORT :Cancel no PBS b STR_TRACE_RESTRICT_TIME_MINUTE :current minute (0 - 59) STR_TRACE_RESTRICT_TIME_HOUR :current hour (0 - 23) STR_TRACE_RESTRICT_TIME_HOUR_MINUTE :current hour and minute (0 - 2359) +STR_TRACE_RESTRICT_TIME_DAY :current day (1 - 31) +STR_TRACE_RESTRICT_TIME_MONTH :current month (1 - 12) STR_TRACE_RESTRICT_TIME_MINUTE_ITEM :current minute STR_TRACE_RESTRICT_TIME_HOUR_ITEM :current hour STR_TRACE_RESTRICT_TIME_HOUR_MINUTE_ITEM :current hour and minute +STR_TRACE_RESTRICT_TIME_DAY_ITEM :current day +STR_TRACE_RESTRICT_TIME_MONTH_ITEM :current month STR_TRACE_RESTRICT_TIME_MINUTE_SHORT :minute STR_TRACE_RESTRICT_TIME_HOUR_SHORT :hour STR_TRACE_RESTRICT_TIME_HOUR_MINUTE_SHORT :hour and minute +STR_TRACE_RESTRICT_TIME_DAY_ITEM_SHORT :day +STR_TRACE_RESTRICT_TIME_MONTH_ITEM_SHORT :month STR_TRACE_RESTRICT_TIMETABLE_LATENESS :lateness STR_TRACE_RESTRICT_TIMETABLE_EARLINESS :earliness STR_TRACE_RESTRICT_VALUE_CAPTION :{WHITE}Value diff --git a/src/order_gui.cpp b/src/order_gui.cpp index c8c446df81..ec0a17ad5c 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -757,6 +757,8 @@ static const StringID _order_time_date_dropdown[] = { STR_TRACE_RESTRICT_TIME_MINUTE, STR_TRACE_RESTRICT_TIME_HOUR, STR_TRACE_RESTRICT_TIME_HOUR_MINUTE, + STR_TRACE_RESTRICT_TIME_DAY, + STR_TRACE_RESTRICT_TIME_MONTH, INVALID_STRING_ID }; @@ -2421,7 +2423,7 @@ public: case WID_O_COND_TIME_DATE: { ShowDropDownMenu(this, _order_time_date_dropdown, this->vehicle->GetOrder(this->OrderGetSel())->GetConditionValue(), - WID_O_COND_TIME_DATE, 0, 0, UINT_MAX); + WID_O_COND_TIME_DATE, _settings_game.game_time.time_in_minutes ? 0 : 7, 0, UINT_MAX); break; } @@ -2481,7 +2483,6 @@ public: _order_conditional_variable[i] == OCV_COUNTER_VALUE) && !_settings_client.gui.show_adv_tracerestrict_features) { continue; } - if (_order_conditional_variable[i] == OCV_TIME_DATE && !_settings_game.game_time.time_in_minutes) continue; } list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + _order_conditional_variable[i], _order_conditional_variable[i], false)); } diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index edb314f3b2..de0126b876 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -75,7 +75,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_TRACE_RESTRICT_REVERSE, XSCF_NULL, 1, 1, "tracerestrict_reverse", nullptr, nullptr, nullptr }, { XSLFI_TRACE_RESTRICT_NEWSCTRL,XSCF_NULL, 1, 1, "tracerestrict_newsctrl", nullptr, nullptr, nullptr }, { XSLFI_TRACE_RESTRICT_COUNTER, XSCF_NULL, 1, 1, "tracerestrict_counter", nullptr, nullptr, "TRRC" }, - { XSLFI_TRACE_RESTRICT_TIMEDATE,XSCF_NULL, 1, 1, "tracerestrict_timedate", nullptr, nullptr, nullptr }, + { XSLFI_TRACE_RESTRICT_TIMEDATE,XSCF_NULL, 2, 2, "tracerestrict_timedate", nullptr, nullptr, nullptr }, { XSLFI_TRACE_RESTRICT_BRKCND, XSCF_NULL, 2, 2, "tracerestrict_braking_cond",nullptr, nullptr, nullptr }, { XSLFI_TRACE_RESTRICT_CTGRYCND,XSCF_NULL, 1, 1, "tracerestrict_ctgry_cond", nullptr, nullptr, nullptr }, { XSLFI_TRACE_RESTRICT_PENCTRL, XSCF_NULL, 1, 1, "tracerestrict_pfpenctrl", nullptr, nullptr, nullptr }, @@ -95,7 +95,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_INFRA_SHARING, XSCF_NULL, 2, 2, "infra_sharing", nullptr, nullptr, "CPDP" }, { XSLFI_VARIABLE_DAY_LENGTH, XSCF_NULL, 2, 2, "variable_day_length", nullptr, nullptr, nullptr }, { XSLFI_ORDER_OCCUPANCY, XSCF_NULL, 2, 2, "order_occupancy", nullptr, nullptr, nullptr }, - { XSLFI_MORE_COND_ORDERS, XSCF_NULL, 10, 10, "more_cond_orders", nullptr, nullptr, nullptr }, + { XSLFI_MORE_COND_ORDERS, XSCF_NULL, 11, 11, "more_cond_orders", nullptr, nullptr, nullptr }, { XSLFI_EXTRA_LARGE_MAP, XSCF_NULL, 0, 1, "extra_large_map", nullptr, nullptr, nullptr }, { XSLFI_REVERSE_AT_WAYPOINT, XSCF_NULL, 1, 1, "reverse_at_waypoint", nullptr, nullptr, nullptr }, { XSLFI_VEH_LIFETIME_PROFIT, XSCF_NULL, 1, 1, "veh_lifetime_profit", nullptr, nullptr, nullptr }, diff --git a/src/tracerestrict.cpp b/src/tracerestrict.cpp index 08bf306e48..44c19e179c 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -1713,6 +1713,12 @@ int GetTraceRestrictTimeDateValue(TraceRestrictTimeDateValueField type) case TRTDVF_HOUR_MINUTE: return (MINUTES_HOUR(minutes) * 100) + MINUTES_MINUTE(minutes); + case TRTDVF_DAY: + return _cur_date_ymd.day; + + case TRTDVF_MONTH: + return _cur_date_ymd.month + 1; + default: return 0; } diff --git a/src/tracerestrict.h b/src/tracerestrict.h index dc9d2b8ce4..a11b57a09a 100644 --- a/src/tracerestrict.h +++ b/src/tracerestrict.h @@ -313,7 +313,9 @@ enum TraceRestrictTimeDateValueField { TRTDVF_MINUTE = 0, ///< Minute TRTDVF_HOUR = 1, ///< Hour TRTDVF_HOUR_MINUTE = 2, ///< Hour and minute - TRTDVF_END = 3, ///< End tag + TRTDVF_DAY = 3, ///< Day + TRTDVF_MONTH = 4, ///< Month + TRTDVF_END = 5, ///< End tag }; /** diff --git a/src/tracerestrict_gui.cpp b/src/tracerestrict_gui.cpp index f58ba4ca1b..0378aac3fa 100644 --- a/src/tracerestrict_gui.cpp +++ b/src/tracerestrict_gui.cpp @@ -346,12 +346,16 @@ static const StringID _time_date_value_str[] = { STR_TRACE_RESTRICT_TIME_MINUTE, STR_TRACE_RESTRICT_TIME_HOUR, STR_TRACE_RESTRICT_TIME_HOUR_MINUTE, + STR_TRACE_RESTRICT_TIME_DAY, + STR_TRACE_RESTRICT_TIME_MONTH, INVALID_STRING_ID }; static const uint _time_date_value_val[] = { TRTDVF_MINUTE, TRTDVF_HOUR, TRTDVF_HOUR_MINUTE, + TRTDVF_DAY, + TRTDVF_MONTH, }; /** value drop down list for time/date types strings and values */ @@ -543,7 +547,6 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG } else { *hide_mask = is_conditional ? 0x1FE0000 : 0x6F0; } - if (is_conditional && !_settings_game.game_time.time_in_minutes) *hide_mask |= 0x800000; if (is_conditional && _settings_game.vehicle.train_braking_model != TBM_REALISTIC) *hide_mask |= 0x1040000; } return is_conditional ? &set_cond : &set_action; @@ -1858,7 +1861,7 @@ public: } case TRVT_TIME_DATE_INT: { - this->ShowDropDownListWithValue(&_time_date_value, GetTraceRestrictValue(item), false, TR_WIDGET_LEFT_AUX_DROPDOWN, 0, 0, UINT_MAX); + this->ShowDropDownListWithValue(&_time_date_value, GetTraceRestrictValue(item), false, TR_WIDGET_LEFT_AUX_DROPDOWN, _settings_game.game_time.time_in_minutes ? 0 : 7, 0, UINT_MAX); break; } From aff6dbec2d3331b7409119b1ceb9c53ae2fcef9b Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Wed, 27 Oct 2021 00:24:26 +0100 Subject: [PATCH 15/30] Show timetabled 0 wait times for stations/depots in timetable window --- src/order_gui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/order_gui.cpp b/src/order_gui.cpp index ec0a17ad5c..e74187a25e 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -839,7 +839,7 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int if (timetable) { SetDParam(3, STR_EMPTY); - if (order->GetWaitTime() > 0) { + if (order->GetWaitTime() > 0 || order->IsWaitTimetabled()) { SetDParam(7, order->IsWaitTimetabled() ? STR_TIMETABLE_STAY_FOR : STR_TIMETABLE_STAY_FOR_ESTIMATED); SetTimetableParams(8, order->GetWaitTime()); } @@ -892,7 +892,7 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int } if (timetable) { - if (order->GetWaitTime() > 0) { + if (order->GetWaitTime() > 0 || order->IsWaitTimetabled()) { SetDParam(7, order->IsWaitTimetabled() ? STR_TIMETABLE_STAY_FOR : STR_TIMETABLE_STAY_FOR_ESTIMATED); SetTimetableParams(8, order->GetWaitTime()); } From 7b12d23e4f47e2575cc699f1cf907261d864cf9a Mon Sep 17 00:00:00 2001 From: TELK Date: Wed, 22 Sep 2021 16:52:52 +0900 Subject: [PATCH 16/30] Update: Korean translation --- src/lang/korean.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 264a6f2231..041b03772e 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -306,12 +306,13 @@ STR_SORT_BY_LENGTH :길이 STR_SORT_BY_LIFE_TIME :남은 수명 STR_SORT_BY_TIMETABLE_DELAY :시간표 지연 STR_SORT_BY_AVG_ORDER_OCCUPANCY :평균 경로 사용률 +STR_SORT_BY_MAX_SPEED_LOADED :최대 속력 (가득) STR_SORT_BY_FACILITY :역 종류 STR_SORT_BY_WAITING_TOTAL :전체 대기 화물량 STR_SORT_BY_WAITING_AVAILABLE :사용 가능한 대기 화물량 STR_SORT_BY_RATING_MAX :높은 화물 등급 STR_SORT_BY_RATING_MIN :낮은 화물 등급 -STR_SORT_BY_VEHICLES_CALLING :호출 차량 수 +STR_SORT_BY_VEHICLES_CALLING :정차 차량 수 STR_SORT_BY_ENGINE_ID :차량ID (기본 정렬) STR_SORT_BY_COST :가격 STR_SORT_BY_POWER :힘 @@ -614,7 +615,7 @@ STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}화물 STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}이 화물에 대한 그래프 켜기/끄기 STR_GRAPH_CARGO_PAYMENT_CARGO :{TINY_FONT}{BLACK}{STRING} -STR_GRAPH_STATION_CARGO_CAPTION :{WHITE}{STATION} - 대기 화물량 내력 +STR_GRAPH_STATION_CARGO_CAPTION :{WHITE}{STATION} - 대기 화물량 이력 STR_GRAPH_STATION_CARGO_X_LABEL :{TINY_FONT}{BLACK}{NUM}일 동안의 변동 사항 STR_GRAPH_STATION_CARGO_TITLE :{TINY_FONT}{BLACK}역에서 있던 화물량 @@ -4199,8 +4200,8 @@ STR_STATION_VIEW_GROUP_D_V_S :도착-경유- STR_STATION_VIEW_DEPARTURES_BUTTON :{BLACK}출발/도착 정보 STR_STATION_VIEW_DEPARTURES_TOOLTIP :{BLACK}출발/도착 정보를 보여줍니다 -STR_STATION_VIEW_HISTORY_BUTTON :{BLACK}화물량 내력 -STR_STATION_VIEW_HISTORY_TOOLTIP :{BLACK}대기 화물량 내력을 보여줍니다 +STR_STATION_VIEW_HISTORY_BUTTON :{BLACK}화물량 이력 +STR_STATION_VIEW_HISTORY_TOOLTIP :{BLACK}대기 화물량 이력을 보여줍니다 ############ range for rating starts STR_CARGO_RATING_APPALLING :형편없음 @@ -6592,7 +6593,7 @@ STR_ZONING_OUTER_INFO :{BLACK}바깥 STR_ZONING_INNER_INFO :{BLACK}안쪽 타일 테두리를 표시할 기준을 선택하세요. STR_ZONING_NO_ZONING :표시 안함 -STR_ZONING_AUTHORITY :권한 +STR_ZONING_AUTHORITY :당국 STR_ZONING_CAN_BUILD :건설 불가 지역 STR_ZONING_STA_CATCH :역세권 STR_ZONING_STA_CATCH_OPEN :역세권 (창이 열린 역만) From ed1c0c70ea27a656b2845efa87ff3c7032e18aab Mon Sep 17 00:00:00 2001 From: TELK Date: Sat, 16 Oct 2021 10:02:50 +0900 Subject: [PATCH 17/30] Update: Korean translation up to 9254be5 --- src/lang/korean.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 041b03772e..514eeac5aa 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -2061,6 +2061,7 @@ STR_CONFIG_SETTING_DISTRIBUTION_PER_CARGO :이 화물에 STR_CONFIG_SETTING_DISTRIBUTION_PER_CARGO_PARAM :{STRING}에 대한 화물 분배 형식 덮어쓰기: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PER_CARGO_HELPTEXT :"(기본)"은 이 화물 종류에 대한 기본 화물 분배 형식을 따른다는 뜻입니다. "대칭"은 대체로 A역에서 B역으로 가려는 화물의 수가 B에서 A로 가려는 화물의 수와 대체로 같다는 뜻입니다. "비대칭"은 아무 방향이나 임의의 양만큼 가게 됨을 뜻합니다. "수동"은 자동적인 화물 분배가 일어나지 않고 기존 방식을 사용하겠음을 뜻합니다. STR_CONFIG_SETTING_DISTRIBUTION_PER_CARGO_DEFAULT :(기본) +STR_CONFIG_SETTING_DISTRIBUTION_HELPTEXT_EXTRA :{STRING}{}"비대칭 (동일 분포)"는 화물을 받는 각 역이 전체적으로 거의 비슷한 양의 화물을 받도록 분배된다는 뜻입니다. "비대칭 (최근접)"은 그 화물을 받을 수 있는 가장 가까운 역으로 화물을 분배한다는 뜻입니다. STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :분배 정확도: {STRING} STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :값이 높으면 높을수록 CPU가 연결 상태를 계산하는 시간이 더 오래 걸립니다. 만약 이 시간이 너무 오래 걸리면 게임이 버벅일 것입니다. 하지만, 낮은 값으로 설정하면 분배가 부정확하게 일어나서, 화물이 원하는 곳으로 분배되지 않을 수 있습니다. STR_CONFIG_SETTING_DEMAND_DISTANCE :거리에 따른 수요 효과: {STRING} From afe78242703e394865f09117ccb9f162a892d4af Mon Sep 17 00:00:00 2001 From: TELK Date: Fri, 29 Oct 2021 19:16:05 +0900 Subject: [PATCH 18/30] Update: Korean translation up to aff6dbec2d3331b7409119b1ceb9c53ae2fcef9b --- src/lang/korean.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 514eeac5aa..5e4ec7c68e 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -1935,6 +1935,12 @@ STR_CONFIG_SETTING_INDUSTRY_CARGO_FACTOR :산업시설 STR_CONFIG_SETTING_INDUSTRY_CARGO_FACTOR_HELPTEXT :1차 산업시설이 생산하는 화물의 양을 2^(생성 계수)에 근접하게 조절합니다. 나무를 베는 산업시설에는 적용되지 않습니다.{}모든 산업시설 관련 NewGRF와 모두 호환되지는 않을 수 있습니다. STR_CONFIG_SETTING_TOWN_ABOVE_HEIGHT :이 고도 위에는 도시를 생성하지 않음: {STRING} STR_CONFIG_SETTING_TOWN_ABOVE_HEIGHT_HELPTEXT :지도를 생성할 때 특정 고도 위에는 도시를 만들지 않도록 만듭니다. +STR_CONFIG_SETTING_MIN_TOWN_LAND_AREA :도시에 필요한 최소 평지 영역: {STRING} +STR_CONFIG_SETTING_MIN_TOWN_LAND_AREA_HELPTEXT :도시를 배치하려면 최소한 이만큼의 평지가 필요합니다. +STR_CONFIG_SETTING_MIN_CITY_LAND_AREA :대도시에 필요한 최소 평지 영역: {STRING} +STR_CONFIG_SETTING_MIN_CITY_LAND_AREA_HELPTEXT :대도시를 배치하려면 최소한 이만큼의 평지가 필요합니다. +STR_CONFIG_SETTING_MIN_LAND_AREA_VALUE :{NUM} +STR_CONFIG_SETTING_MIN_LAND_AREA_ZERO :끄기 STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :나무의 성장과 확장: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :게임 플레이 중 나무의 성장과 확장 여부를 조절합니다. 이 설정을 조정하면, 아열대 기후의 벌목소처럼 나무의 성장에 의존하는 산업시설에 영향을 끼칠 수 있습니다. @@ -3069,12 +3075,18 @@ STR_TRACE_RESTRICT_NO_PBS_BACK_PENALTY_CANCEL_SHORT :(취소) 후방 STR_TRACE_RESTRICT_TIME_MINUTE :현재 분(0 - 59) STR_TRACE_RESTRICT_TIME_HOUR :현재 시(0 - 23) STR_TRACE_RESTRICT_TIME_HOUR_MINUTE :현재 시&분(0 - 2359) +STR_TRACE_RESTRICT_TIME_DAY :현재 일(1 - 31) +STR_TRACE_RESTRICT_TIME_MONTH :현재 월(1 - 12) STR_TRACE_RESTRICT_TIME_MINUTE_ITEM :현재 분 STR_TRACE_RESTRICT_TIME_HOUR_ITEM :현재 시 STR_TRACE_RESTRICT_TIME_HOUR_MINUTE_ITEM :현재 시&분 +STR_TRACE_RESTRICT_TIME_DAY_ITEM :현재 일 +STR_TRACE_RESTRICT_TIME_MONTH_ITEM :현재 월 STR_TRACE_RESTRICT_TIME_MINUTE_SHORT :분 STR_TRACE_RESTRICT_TIME_HOUR_SHORT :시 STR_TRACE_RESTRICT_TIME_HOUR_MINUTE_SHORT :시분 +STR_TRACE_RESTRICT_TIME_DAY_ITEM_SHORT :일 +STR_TRACE_RESTRICT_TIME_MONTH_ITEM_SHORT :월 STR_TRACE_RESTRICT_TIMETABLE_LATENESS :지연 STR_TRACE_RESTRICT_TIMETABLE_EARLINESS :조착 STR_TRACE_RESTRICT_VALUE_CAPTION :{WHITE}값 From 23497dea35e4172d42072eecd00813bf22ca83aa Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 29 Oct 2021 19:51:27 +0100 Subject: [PATCH 19/30] Github: Enable blank issues, remove contact links section --- .github/ISSUE_TEMPLATE/config.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 2fd749087a..0086358db1 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1 @@ -blank_issues_enabled: false -contact_links: -- name: Suggestions and ideas? - url: https://www.tt-forums.net/viewforum.php?f=32 - about: Have a suggestion or an idea for a cool new feature? Post them on our forum! +blank_issues_enabled: true From 8a7cb108131247a20520f1f07995896894c23016 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 29 Oct 2021 20:03:29 +0100 Subject: [PATCH 20/30] Fix incorrect cast/colour operation in screenshot GetIndustryValue See: #307 --- src/screenshot.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screenshot.cpp b/src/screenshot.cpp index da024d21c8..72a7f3b87f 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -1240,7 +1240,7 @@ static byte GetIndustryValue(TileIndex tile) case MP_INDUSTRY: { const IndustryType industry_type = Industry::GetByTile(tile)->type; - return GetIndustrySpec(industry_type)->map_colour * static_cast(0x01010101); + return GetIndustrySpec(industry_type)->map_colour; } default: return MKCOLOUR(GREY_SCALE(2)); From 08426216538b91697c6fdc33e1a071a3b9ddfe99 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 29 Oct 2021 20:05:16 +0100 Subject: [PATCH 21/30] Remove unused _network_udp_mutex See: #307 --- src/network/network_udp.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 47c194a588..e104687ad8 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -41,9 +41,6 @@ extern const uint8 _out_of_band_grf_md5[16] { 0x00, 0xB0, 0xC0, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xC0, 0xDE, 0x00, 0x00, 0x00, 0x00 }; static const uint32 FIND_SERVER_EXTENDED_TOKEN = 0x2A49582A; -/** Mutex for all out threaded udp resolution and such. */ -static std::mutex _network_udp_mutex; - /** Session key to register ourselves to the master server */ static uint64 _session_key = 0; From 86e1f58bc0053d34639975e37f4668b4fab5f92d Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 29 Oct 2021 20:10:39 +0100 Subject: [PATCH 22/30] Avoid unused variable warning when not using threads See: #307 --- src/os/unix/unix.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp index 0f53fb1727..10914e32c8 100644 --- a/src/os/unix/unix.cpp +++ b/src/os/unix/unix.cpp @@ -337,8 +337,10 @@ int GetCurrentThreadName(char *str, const char *last) return 0; } +#if !defined(NO_THREADS) static pthread_t main_thread; static pthread_t game_thread; +#endif void SetSelfAsMainThread() { From d2e757db9ac532b2956cb6acabf25df082db2d47 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 29 Oct 2021 20:11:01 +0100 Subject: [PATCH 23/30] Set field size for PropertyID enum --- src/newgrf_properties.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/newgrf_properties.h b/src/newgrf_properties.h index 835a873847..94dde722e7 100644 --- a/src/newgrf_properties.h +++ b/src/newgrf_properties.h @@ -15,7 +15,7 @@ * Names are formatted as PROP__ * @todo Currently the list only contains properties which are used more than once in the code. I.e. they are available for callback 0x36. */ -enum PropertyID { +enum PropertyID : byte { PROP_VEHICLE_LOAD_AMOUNT = 0x07, ///< Loading speed PROP_TRAIN_SPEED = 0x09, ///< Max. speed: 1 unit = 1/1.6 mph = 1 km-ish/h From 1d89fe3820b5b3fb68377df2fb5d28618158530b Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 29 Oct 2021 20:27:12 +0100 Subject: [PATCH 24/30] Add casts around engine property checks in GetEngineProperty --- src/newgrf_engine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index a374264859..0e803a45a5 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -1371,10 +1371,10 @@ uint GetVehicleProperty(const Vehicle *v, PropertyID property, uint orig_value) uint GetEngineProperty(EngineID engine, PropertyID property, uint orig_value, const Vehicle *v) { const Engine *e = Engine::Get(engine); - if (property < 64 && !HasBit(e->cb36_properties_used, property)) return orig_value; + if (static_cast(property) < 64 && !HasBit(e->cb36_properties_used, property)) return orig_value; VehicleResolverObject object(engine, v, VehicleResolverObject::WO_UNCACHED, false, CBID_VEHICLE_MODIFY_PROPERTY, property, 0); - if (property < 64 && !e->sprite_group_cb36_properties_used.empty()) { + if (static_cast(property) < 64 && !e->sprite_group_cb36_properties_used.empty()) { auto iter = e->sprite_group_cb36_properties_used.find(object.root_spritegroup); if (iter != e->sprite_group_cb36_properties_used.end()) { if (!HasBit(iter->second, property)) return orig_value; From 6ba53a9a6834c980b00c3f11d71c0133b8e52fdc Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 29 Oct 2021 20:27:41 +0100 Subject: [PATCH 25/30] Add ifdef around 32 bit length limit check in SlSetLength --- src/saveload/saveload.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 3351e5c193..8ca8427cb2 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -796,7 +796,9 @@ void SlSetLength(size_t length) * * If we have more than 28 bits, use an extra uint32 and * signal this using the extended chunk header */ +#ifdef _SQ64 assert(length < (1LL << 32)); +#endif if (length >= (1 << 28)) { /* write out extended chunk header */ SlWriteByte(CH_EXT_HDR); From 4a576251832a6dbf0e5623d8bdfbba2c170520d7 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 29 Oct 2021 20:31:28 +0100 Subject: [PATCH 26/30] Avoid cast warnings in network packet handling See: #307 --- src/network/core/packet.cpp | 2 +- src/network/core/udp.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/core/packet.cpp b/src/network/core/packet.cpp index c3016f6a0f..747343d899 100644 --- a/src/network/core/packet.cpp +++ b/src/network/core/packet.cpp @@ -425,7 +425,7 @@ void Packet::Recv_string(std::string &buffer, StringValidationSettings settings) size_t length = ttd_strnlen((const char *)(this->buffer.data() + this->pos), this->Size() - this->pos - 1); buffer.assign((const char *)(this->buffer.data() + this->pos), length); - this->pos += (uint)length + 1; + this->pos += (PacketSize)length + 1; str_validate_inplace(buffer, settings); } diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index 198cfc1279..5e9a66322e 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.cpp @@ -217,7 +217,7 @@ void NetworkUDPSocketHandler::SendNetworkGameInfo(Packet *p, const NetworkGameIn for (c = info->grfconfig; c != nullptr; c = c->next) { if (!HasBit(c->flags, GCF_STATIC)) count++; } - p->Send_uint8(std::min(count, NETWORK_MAX_GRF_COUNT)); // Send number of GRFs + p->Send_uint8(static_cast(std::min(count, NETWORK_MAX_GRF_COUNT))); // Send number of GRFs /* Send actual GRF Identifications */ uint index = 0; From 9540d424277584685db1c4a5e700eaec83afd950 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 29 Oct 2021 20:36:15 +0100 Subject: [PATCH 27/30] Fix cast warning in GUIHouseList See: #307 --- src/town_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 65ae8e0a95..f86749b9d6 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -1390,7 +1390,7 @@ public: } } /* put a terminator on the list to make counting easier */ - this->house_sets.push_back((uint)this->size()); + this->house_sets.push_back((uint16)this->size()); } }; From 5586d1a20a3330095263fdee61ebb749c4aa8a14 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 29 Oct 2021 21:12:16 +0100 Subject: [PATCH 28/30] Remove use of deprecated allocator rebind in cpp-btree --- src/3rdparty/cpp-btree/btree.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/3rdparty/cpp-btree/btree.h b/src/3rdparty/cpp-btree/btree.h index ddea9e0282..2be24691d0 100644 --- a/src/3rdparty/cpp-btree/btree.h +++ b/src/3rdparty/cpp-btree/btree.h @@ -917,8 +917,7 @@ class btree : public Params::key_compare { typedef std::reverse_iterator reverse_iterator; typedef typename Params::allocator_type allocator_type; - typedef typename allocator_type::template rebind::other - internal_allocator_type; + using internal_allocator_type = typename std::allocator_traits::template rebind_alloc; public: // Default constructor. From 6bc3481931dabe2b72a2781e985922c6fecd7763 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 29 Oct 2021 21:18:19 +0100 Subject: [PATCH 29/30] Fix MinGW compilation issues --- src/thread.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/thread.h b/src/thread.h index 55b13ee5d5..d4d341de9e 100644 --- a/src/thread.h +++ b/src/thread.h @@ -17,6 +17,7 @@ #include #if defined(__MINGW32__) #include "3rdparty/mingw-std-threads/mingw.thread.h" +#include "3rdparty/mingw-std-threads/mingw.mutex.h" #endif /** From e34cc229d163599df578a23def613cc3f038a78c Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 29 Oct 2021 21:19:36 +0100 Subject: [PATCH 30/30] Version: Committing version data for tag: jgrpp-0.43.2 --- .ottdrev-vc | 4 ++-- README.md | 2 +- jgrpp-changelog.md | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.ottdrev-vc b/.ottdrev-vc index b5f76052e1..646fc638c7 100644 --- a/.ottdrev-vc +++ b/.ottdrev-vc @@ -1,2 +1,2 @@ -jgrpp-0.43.1 20211004 0 fe8da3ae3a190cff0a9dcc552fe0825ca28c5850 1 0 2021 -fbeb6b45e2e75ab56dd72ed06410f90827a489b5cf6b3236f3605b51c5747bdc - +jgrpp-0.43.2 20211029 0 6bc3481931dabe2b72a2781e985922c6fecd7763 1 0 2021 +3a352dd8343555b193b112845a82173b65aee14cc6764c51dfe1f6bc8fd25d7b - diff --git a/README.md b/README.md index 56a74337ce..71d549bcc2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## JGR's Patchpack version 0.43.1 +## JGR's Patchpack version 0.43.2 This is a collection of patches applied to [OpenTTD](http://www.openttd.org/) diff --git a/jgrpp-changelog.md b/jgrpp-changelog.md index 27ba1d612c..bccccfb2ed 100644 --- a/jgrpp-changelog.md +++ b/jgrpp-changelog.md @@ -2,6 +2,20 @@ * * * +### v0.43.2 (2021-10-29) +* Fix crash when using the ignore signals button to sent a train the wrong-way on a signalled tunnel or bridge. +* Fix multiplayer desync when using "perfect" tree placement mode in arctic climate. +* Fix aircraft shadows being drawn facing the wrong direction. +* Fix timetabled 0 wait times not being shown for stations/depots in the timetable window. +* Add settings for minimum contiguous landmass size for town and city placement. +* Add current day and current month routing restriction conditionals. +* Add current day and current month conditional orders. +* Company bankruptcy: + * When declining to buy a company, ask the next company immediately instead of after the time period expires. + * Do not wait for companies which have no connected clients to buy a company. + * Add console command to offer a company for sale. +* Add Korean translations by TELK. + ### v0.43.1 (2021-10-04) * Fix multi-aspect signal graphics not being immediately enabled for newly generated maps. * Fix premature PBS reservations with using reverse at waypoint orders with timetabled wait times.