1
0
Fork 0
pull/12767/merge
Andriy 2024-06-23 18:28:52 +00:00 committed by GitHub
commit fb94aed8f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
36 changed files with 925 additions and 177 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
/.vs
/.cache/*
/build*
CMakeSettings.json
docs/aidocs/*

Binary file not shown.

View File

@ -12,6 +12,7 @@
#include "cargo_type.h"
#include "company_func.h"
#include "company_type.h"
#include "industry.h"
#include "town.h"
#include "core/overflowsafe_type.hpp"
@ -24,12 +25,12 @@ struct Station;
* - bits 0-15 town or industry number
* - bit 16 is set if it is an industry number (else it is a town number).
* - bits 19-23 Cargo type.
* - bits 24-31 %Company number.
* - bits 24 - 24 + COMPANY_BIT_SIZE %Company number.
*/
typedef uint32_t CargoMonitorID; ///< Type of the cargo monitor number.
/** Map type for storing and updating active cargo monitor numbers and their amounts. */
typedef std::map<CargoMonitorID, OverflowSafeInt32> CargoMonitorMap;
typedef std::map<CargoMonitorID, OverflowSafeInt64> CargoMonitorMap;
extern CargoMonitorMap _cargo_pickups;
extern CargoMonitorMap _cargo_deliveries;
@ -44,9 +45,11 @@ enum CargoCompanyBits {
CCB_CARGO_TYPE_START = 19, ///< Start bit of the cargo type field.
CCB_CARGO_TYPE_LENGTH = 6, ///< Number of bits of the cargo type field.
CCB_COMPANY_START = 25, ///< Start bit of the company field.
CCB_COMPANY_LENGTH = 4, ///< Number of bits of the company field.
CCB_COMPANY_LENGTH = COMPANY_SIZE_BITS, ///< Number of bits of the company field.
};
static_assert(CCB_COMPANY_LENGTH <= (1 << 8));
static_assert(NUM_CARGO <= (1 << CCB_CARGO_TYPE_LENGTH));
static_assert(MAX_COMPANIES <= (1 << CCB_COMPANY_LENGTH));
@ -63,7 +66,7 @@ inline CargoMonitorID EncodeCargoIndustryMonitor(CompanyID company, CargoID ctyp
assert(ctype < (1 << CCB_CARGO_TYPE_LENGTH));
assert(company < (1 << CCB_COMPANY_LENGTH));
uint32_t ret = 0;
uint64_t ret = 0;
SB(ret, CCB_TOWN_IND_NUMBER_START, CCB_TOWN_IND_NUMBER_LENGTH, ind);
SetBit(ret, CCB_IS_INDUSTRY_BIT);
SB(ret, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH, ctype);
@ -83,7 +86,7 @@ inline CargoMonitorID EncodeCargoTownMonitor(CompanyID company, CargoID ctype, T
assert(ctype < (1 << CCB_CARGO_TYPE_LENGTH));
assert(company < (1 << CCB_COMPANY_LENGTH));
uint32_t ret = 0;
uint64_t ret = 0;
SB(ret, CCB_TOWN_IND_NUMBER_START, CCB_TOWN_IND_NUMBER_LENGTH, town);
SB(ret, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH, ctype);
SB(ret, CCB_COMPANY_START, CCB_COMPANY_LENGTH, company);

View File

@ -260,7 +260,6 @@ inline void MakeClear(Tile t, ClearGround g, uint density)
{
SetTileType(t, MP_CLEAR);
t.m1() = 0;
SetTileOwner(t, OWNER_NONE);
t.m2() = 0;
t.m3() = 0;
t.m4() = 0 << 5 | 0 << 2;
@ -268,6 +267,8 @@ inline void MakeClear(Tile t, ClearGround g, uint density)
t.m6() = 0;
t.m7() = 0;
t.m8() = 0;
t.m9() = 0;
SetTileOwner(t, OWNER_NONE);
}
@ -281,7 +282,6 @@ inline void MakeField(Tile t, uint field_type, IndustryID industry)
{
SetTileType(t, MP_CLEAR);
t.m1() = 0;
SetTileOwner(t, OWNER_NONE);
t.m2() = industry;
t.m3() = field_type;
t.m4() = 0 << 5 | 0 << 2;
@ -289,6 +289,8 @@ inline void MakeField(Tile t, uint field_type, IndustryID industry)
SB(t.m6(), 2, 4, 0);
t.m7() = 0;
t.m8() = 0;
t.m9() = 0;
SetTileOwner(t, OWNER_NONE);
}
/**

View File

@ -96,6 +96,7 @@ struct CompanyProperties {
uint8_t months_empty = 0; ///< NOSAVE: Number of months this company has not had a client in multiplayer.
uint8_t months_of_bankruptcy; ///< Number of months that the company is unable to pay its debts
CompanyMask bankrupt_asked; ///< which companies were asked about buying it?
uint16_t old_bankrupt_asked;
int16_t 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;

View File

@ -7,6 +7,8 @@
/** @file company_cmd.cpp Handling of companies. */
#include "company_type.h"
#include "gfx_type.h"
#include "stdafx.h"
#include "company_base.h"
#include "company_func.h"
@ -448,27 +450,6 @@ bad_town_name:;
}
}
/** Sorting weights for the company colours. */
static const uint8_t _colour_sort[COLOUR_END] = {2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 2, 3, 1, 1, 1};
/** Similar colours, so we can try to prevent same coloured companies. */
static const Colours _similar_colour[COLOUR_END][2] = {
{ COLOUR_BLUE, COLOUR_LIGHT_BLUE }, // COLOUR_DARK_BLUE
{ COLOUR_GREEN, COLOUR_DARK_GREEN }, // COLOUR_PALE_GREEN
{ INVALID_COLOUR, INVALID_COLOUR }, // COLOUR_PINK
{ COLOUR_ORANGE, INVALID_COLOUR }, // COLOUR_YELLOW
{ INVALID_COLOUR, INVALID_COLOUR }, // COLOUR_RED
{ COLOUR_DARK_BLUE, COLOUR_BLUE }, // COLOUR_LIGHT_BLUE
{ COLOUR_PALE_GREEN, COLOUR_DARK_GREEN }, // COLOUR_GREEN
{ COLOUR_PALE_GREEN, COLOUR_GREEN }, // COLOUR_DARK_GREEN
{ COLOUR_DARK_BLUE, COLOUR_LIGHT_BLUE }, // COLOUR_BLUE
{ COLOUR_BROWN, COLOUR_ORANGE }, // COLOUR_CREAM
{ COLOUR_PURPLE, INVALID_COLOUR }, // COLOUR_MAUVE
{ COLOUR_MAUVE, INVALID_COLOUR }, // COLOUR_PURPLE
{ COLOUR_YELLOW, COLOUR_CREAM }, // COLOUR_ORANGE
{ COLOUR_CREAM, INVALID_COLOUR }, // COLOUR_BROWN
{ COLOUR_WHITE, INVALID_COLOUR }, // COLOUR_GREY
{ COLOUR_GREY, INVALID_COLOUR }, // COLOUR_WHITE
};
/**
* Generate a company colour.
@ -476,53 +457,13 @@ static const Colours _similar_colour[COLOUR_END][2] = {
*/
static Colours GenerateCompanyColour()
{
Colours colours[COLOUR_END];
int num_colours = COLOUR_END - COLOUR_BEGIN;
/* Initialize array */
for (uint i = 0; i < COLOUR_END; i++) colours[i] = static_cast<Colours>(i);
/* And randomize it */
for (uint i = 0; i < 100; i++) {
uint r = Random();
Swap(colours[GB(r, 0, 4)], colours[GB(r, 4, 4)]);
int companies = 0;
for (const Company *_ : Company::Iterate()) {
companies++;
}
/* Bubble sort it according to the values in table 1 */
for (uint i = 0; i < COLOUR_END; i++) {
for (uint j = 1; j < COLOUR_END; j++) {
if (_colour_sort[colours[j - 1]] < _colour_sort[colours[j]]) {
Swap(colours[j - 1], colours[j]);
}
}
}
/* Move the colours that look similar to each company's colour to the side */
for (const Company *c : Company::Iterate()) {
Colours pcolour = c->colour;
for (uint i = 0; i < COLOUR_END; i++) {
if (colours[i] == pcolour) {
colours[i] = INVALID_COLOUR;
break;
}
}
for (uint j = 0; j < 2; j++) {
Colours similar = _similar_colour[pcolour][j];
if (similar == INVALID_COLOUR) break;
for (uint i = 1; i < COLOUR_END; i++) {
if (colours[i - 1] == similar) Swap(colours[i - 1], colours[i]);
}
}
}
/* Return the first available colour */
for (uint i = 0; i < COLOUR_END; i++) {
if (colours[i] != INVALID_COLOUR) return colours[i];
}
NOT_REACHED();
return Colours(companies % num_colours);
}
/**

View File

@ -11,6 +11,7 @@
#define COMPANY_TYPE_H
#include "core/enum_type.hpp"
#include <bitset>
/**
* Enum for all companies/owners.
@ -18,22 +19,39 @@
enum Owner : uint8_t {
/* All companies below MAX_COMPANIES are playable
* companies, above, they are special, computer controlled 'companies' */
OWNER_BEGIN = 0x00, ///< First owner
COMPANY_FIRST = 0x00, ///< First company, same as owner
MAX_COMPANIES = 0x0F, ///< Maximum number of companies
OWNER_TOWN = 0x0F, ///< A town owns the tile, or a town is expanding
OWNER_NONE = 0x10, ///< The tile has no ownership
OWNER_WATER = 0x11, ///< The tile/execution is done by "water"
OWNER_DEITY = 0x12, ///< The object is owned by a superuser / goal script
OWNER_BEGIN = 0x00, ///< First owner
COMPANY_FIRST = 0x00, ///< First company, same as owner
MAX_COMPANIES = 0xF0, ///< Maximum number of companies
OLD_MAX_COMPANIES = 0x0F, ///< Maximum number of companies
OWNER_TOWN = 0xF1, ///< A town owns the tile, or a town is expanding
OLD_OWNER_TOWN = 0x0F,
OWNER_NONE = 0xF2, ///< The tile has no ownership
OLD_OWNER_NONE = 0x10, ///< The tile has no ownership
OWNER_WATER = 0xF3, ///< The tile/execution is done by "water"
OLD_OWNER_WATER = 0x11, ///< The tile/execution is done by "water"
OWNER_DEITY = 0xF4, ///< The object is owned by a superuser / goal script
OWNER_END, ///< Last + 1 owner
INVALID_OWNER = 0xFF, ///< An invalid owner
INVALID_COMPANY = 0xFF, ///< An invalid company
INVALID_OWNER = 0xFF, ///< An invalid owner
INVALID_COMPANY = 0xFF, ///< An invalid company
/* 'Fake' companies used for networks */
COMPANY_INACTIVE_CLIENT = 253, ///< The client is joining
COMPANY_NEW_COMPANY = 254, ///< The client wants a new company
COMPANY_SPECTATOR = 255, ///< The client is spectating
COMPANY_INACTIVE_CLIENT = 0xF7, ///< The client is joining
COMPANY_NEW_COMPANY = 0xF8, ///< The client wants a new company
COMPANY_SPECTATOR = 0xF9, ///< The client is spectating
};
const uint8_t COMPANY_SIZE_BITS = 8; /// Size of the company id in bits
static_assert(COMPANY_SIZE_BITS <= 10); /// 32bit m9 can only fit 3 owners of size 10
static_assert(MAX_COMPANIES <= (1U << COMPANY_SIZE_BITS) - 1); /// Checking that MAX_COMPANIES is in bounds
static_assert(OWNER_END <= (1U << COMPANY_SIZE_BITS) - 1);
static_assert(INVALID_OWNER <= (1U << COMPANY_SIZE_BITS) - 1);
static_assert(INVALID_COMPANY <= (1U << COMPANY_SIZE_BITS) - 1);
DECLARE_POSTFIX_INCREMENT(Owner)
DECLARE_ENUM_AS_ADDABLE(Owner)
@ -47,7 +65,7 @@ static const uint MAX_COMPETITORS_INTERVAL = 500; ///< The maximum interval (in
typedef Owner CompanyID;
typedef uint16_t CompanyMask;
typedef std::bitset<MAX_COMPANIES> CompanyMask;
struct Company;
typedef uint32_t CompanyManagerFace; ///< Company manager face bits, info see in company_manager_face.h

View File

@ -940,7 +940,7 @@ static IntervalTimer<TimerGameCalendar> _calendar_engines_daily({TimerGameCalend
CloseWindowById(WC_ENGINE_PREVIEW, i);
e->preview_company = INVALID_COMPANY;
}
} else if (CountBits(e->preview_asked) < MAX_COMPANIES) {
} else if (e->preview_asked.count() < MAX_COMPANIES) {
e->preview_company = GetPreviewCompany(e);
if (e->preview_company == INVALID_COMPANY) {
@ -969,7 +969,7 @@ static IntervalTimer<TimerGameCalendar> _calendar_engines_daily({TimerGameCalend
void ClearEnginesHiddenFlagOfCompany(CompanyID cid)
{
for (Engine *e : Engine::Iterate()) {
SB(e->company_hidden, cid, 1, 0);
e->company_hidden.reset(cid);
}
}
@ -987,7 +987,7 @@ CommandCost CmdSetVehicleVisibility(DoCommandFlag flags, EngineID engine_id, boo
if (!IsEngineBuildable(e->index, e->type, _current_company)) return CMD_ERROR;
if ((flags & DC_EXEC) != 0) {
SB(e->company_hidden, _current_company, 1, hide ? 1 : 0);
e->company_hidden.set(_current_company, hide ? 1 : 0);
AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type);
}

View File

@ -15,6 +15,7 @@
#include "core/pool_type.hpp"
#include "newgrf_commons.h"
#include "timer/timer_game_calendar.h"
#include <cstdint>
struct WagonOverride {
std::vector<EngineID> engines;
@ -47,11 +48,19 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> {
uint16_t duration_phase_2; ///< Second reliability phase in months, keeping #reliability_max.
uint16_t duration_phase_3; ///< Third reliability phase in months, decaying to #reliability_final.
uint8_t flags; ///< Flags of the engine. @see EngineFlags
CompanyMask preview_asked; ///< Bit for each company which has already been offered a preview.
uint16_t old_preview_asked;
CompanyID preview_company; ///< Company which is currently being offered a preview \c INVALID_COMPANY means no company.
uint8_t preview_wait; ///< Daily countdown timer for timeout of offering the engine to the #preview_company company.
CompanyMask company_avail; ///< Bit for each company whether the engine is available for that company.
uint16_t old_company_avail;
CompanyMask company_hidden; ///< Bit for each company whether the engine is normally hidden in the build gui for that company.
uint16_t old_company_hidden;
uint8_t original_image_index; ///< Original vehicle image index, thus the image index of the overridden vehicle
VehicleType type; ///< %Vehicle type, ie #VEH_ROAD, #VEH_TRAIN, etc.

View File

@ -217,7 +217,232 @@ namespace {
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1), // PFE_AI14
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1),
PerformanceData(1), // PFE_AI239
};
}

View File

@ -75,8 +75,234 @@ enum PerformanceElement {
PFE_AI12, ///< AI execution for player slot 13
PFE_AI13, ///< AI execution for player slot 14
PFE_AI14, ///< AI execution for player slot 15
PFE_AI15, ///< AI execution for player slot 16
PFE_AI16, ///< AI execution for player slot 17
PFE_AI17, ///< AI execution for player slot 18
PFE_AI18, ///< AI execution for player slot 19
PFE_AI19, ///< AI execution for player slot 20
PFE_AI20, ///< AI execution for player slot 21
PFE_AI21, ///< AI execution for player slot 22
PFE_AI22, ///< AI execution for player slot 23
PFE_AI23, ///< AI execution for player slot 24
PFE_AI24, ///< AI execution for player slot 25
PFE_AI25, ///< AI execution for player slot 26
PFE_AI26, ///< AI execution for player slot 27
PFE_AI27, ///< AI execution for player slot 28
PFE_AI28, ///< AI execution for player slot 29
PFE_AI29, ///< AI execution for player slot 30
PFE_AI30, ///< AI execution for player slot 31
PFE_AI31, ///< AI execution for player slot 32
PFE_AI32, ///< AI execution for player slot 33
PFE_AI33, ///< AI execution for player slot 34
PFE_AI34, ///< AI execution for player slot 35
PFE_AI35, ///< AI execution for player slot 36
PFE_AI36, ///< AI execution for player slot 37
PFE_AI37, ///< AI execution for player slot 38
PFE_AI38, ///< AI execution for player slot 39
PFE_AI39, ///< AI execution for player slot 40
PFE_AI40, ///< AI execution for player slot 41
PFE_AI41, ///< AI execution for player slot 42
PFE_AI42, ///< AI execution for player slot 43
PFE_AI43, ///< AI execution for player slot 44
PFE_AI44, ///< AI execution for player slot 45
PFE_AI45, ///< AI execution for player slot 46
PFE_AI46, ///< AI execution for player slot 47
PFE_AI47, ///< AI execution for player slot 48
PFE_AI48, ///< AI execution for player slot 49
PFE_AI49, ///< AI execution for player slot 50
PFE_AI50, ///< AI execution for player slot 51
PFE_AI51, ///< AI execution for player slot 52
PFE_AI52, ///< AI execution for player slot 53
PFE_AI53, ///< AI execution for player slot 54
PFE_AI54, ///< AI execution for player slot 55
PFE_AI55, ///< AI execution for player slot 56
PFE_AI56, ///< AI execution for player slot 57
PFE_AI57, ///< AI execution for player slot 58
PFE_AI58, ///< AI execution for player slot 59
PFE_AI59, ///< AI execution for player slot 60
PFE_AI60, ///< AI execution for player slot 61
PFE_AI61, ///< AI execution for player slot 62
PFE_AI62, ///< AI execution for player slot 63
PFE_AI63, ///< AI execution for player slot 64
PFE_AI64, ///< AI execution for player slot 65
PFE_AI65, ///< AI execution for player slot 66
PFE_AI66, ///< AI execution for player slot 67
PFE_AI67, ///< AI execution for player slot 68
PFE_AI68, ///< AI execution for player slot 69
PFE_AI69, ///< AI execution for player slot 70
PFE_AI70, ///< AI execution for player slot 71
PFE_AI71, ///< AI execution for player slot 72
PFE_AI72, ///< AI execution for player slot 73
PFE_AI73, ///< AI execution for player slot 74
PFE_AI74, ///< AI execution for player slot 75
PFE_AI75, ///< AI execution for player slot 76
PFE_AI76, ///< AI execution for player slot 77
PFE_AI77, ///< AI execution for player slot 78
PFE_AI78, ///< AI execution for player slot 79
PFE_AI79, ///< AI execution for player slot 80
PFE_AI80, ///< AI execution for player slot 81
PFE_AI81, ///< AI execution for player slot 82
PFE_AI82, ///< AI execution for player slot 83
PFE_AI83, ///< AI execution for player slot 84
PFE_AI84, ///< AI execution for player slot 85
PFE_AI85, ///< AI execution for player slot 86
PFE_AI86, ///< AI execution for player slot 87
PFE_AI87, ///< AI execution for player slot 88
PFE_AI88, ///< AI execution for player slot 89
PFE_AI89, ///< AI execution for player slot 90
PFE_AI90, ///< AI execution for player slot 91
PFE_AI91, ///< AI execution for player slot 92
PFE_AI92, ///< AI execution for player slot 93
PFE_AI93, ///< AI execution for player slot 94
PFE_AI94, ///< AI execution for player slot 95
PFE_AI95, ///< AI execution for player slot 96
PFE_AI96, ///< AI execution for player slot 97
PFE_AI97, ///< AI execution for player slot 98
PFE_AI98, ///< AI execution for player slot 99
PFE_AI99, ///< AI execution for player slot 100
PFE_AI100, ///< AI execution for player slot 101
PFE_AI101, ///< AI execution for player slot 102
PFE_AI102, ///< AI execution for player slot 103
PFE_AI103, ///< AI execution for player slot 104
PFE_AI104, ///< AI execution for player slot 105
PFE_AI105, ///< AI execution for player slot 106
PFE_AI106, ///< AI execution for player slot 107
PFE_AI107, ///< AI execution for player slot 108
PFE_AI108, ///< AI execution for player slot 109
PFE_AI109, ///< AI execution for player slot 110
PFE_AI110, ///< AI execution for player slot 111
PFE_AI111, ///< AI execution for player slot 112
PFE_AI112, ///< AI execution for player slot 113
PFE_AI113, ///< AI execution for player slot 114
PFE_AI114, ///< AI execution for player slot 115
PFE_AI115, ///< AI execution for player slot 116
PFE_AI116, ///< AI execution for player slot 117
PFE_AI117, ///< AI execution for player slot 118
PFE_AI118, ///< AI execution for player slot 119
PFE_AI119, ///< AI execution for player slot 120
PFE_AI120, ///< AI execution for player slot 121
PFE_AI121, ///< AI execution for player slot 122
PFE_AI122, ///< AI execution for player slot 123
PFE_AI123, ///< AI execution for player slot 124
PFE_AI124, ///< AI execution for player slot 125
PFE_AI125, ///< AI execution for player slot 126
PFE_AI126, ///< AI execution for player slot 127
PFE_AI127, ///< AI execution for player slot 128
PFE_AI128, ///< AI execution for player slot 129
PFE_AI129, ///< AI execution for player slot 130
PFE_AI130, ///< AI execution for player slot 131
PFE_AI131, ///< AI execution for player slot 132
PFE_AI132, ///< AI execution for player slot 133
PFE_AI133, ///< AI execution for player slot 134
PFE_AI134, ///< AI execution for player slot 135
PFE_AI135, ///< AI execution for player slot 136
PFE_AI136, ///< AI execution for player slot 137
PFE_AI137, ///< AI execution for player slot 138
PFE_AI138, ///< AI execution for player slot 139
PFE_AI139, ///< AI execution for player slot 140
PFE_AI140, ///< AI execution for player slot 141
PFE_AI141, ///< AI execution for player slot 142
PFE_AI142, ///< AI execution for player slot 143
PFE_AI143, ///< AI execution for player slot 144
PFE_AI144, ///< AI execution for player slot 145
PFE_AI145, ///< AI execution for player slot 146
PFE_AI146, ///< AI execution for player slot 147
PFE_AI147, ///< AI execution for player slot 148
PFE_AI148, ///< AI execution for player slot 149
PFE_AI149, ///< AI execution for player slot 150
PFE_AI150, ///< AI execution for player slot 151
PFE_AI151, ///< AI execution for player slot 152
PFE_AI152, ///< AI execution for player slot 153
PFE_AI153, ///< AI execution for player slot 154
PFE_AI154, ///< AI execution for player slot 155
PFE_AI155, ///< AI execution for player slot 156
PFE_AI156, ///< AI execution for player slot 157
PFE_AI157, ///< AI execution for player slot 158
PFE_AI158, ///< AI execution for player slot 159
PFE_AI159, ///< AI execution for player slot 160
PFE_AI160, ///< AI execution for player slot 161
PFE_AI161, ///< AI execution for player slot 162
PFE_AI162, ///< AI execution for player slot 163
PFE_AI163, ///< AI execution for player slot 164
PFE_AI164, ///< AI execution for player slot 165
PFE_AI165, ///< AI execution for player slot 166
PFE_AI166, ///< AI execution for player slot 167
PFE_AI167, ///< AI execution for player slot 168
PFE_AI168, ///< AI execution for player slot 169
PFE_AI169, ///< AI execution for player slot 170
PFE_AI170, ///< AI execution for player slot 171
PFE_AI171, ///< AI execution for player slot 172
PFE_AI172, ///< AI execution for player slot 173
PFE_AI173, ///< AI execution for player slot 174
PFE_AI174, ///< AI execution for player slot 175
PFE_AI175, ///< AI execution for player slot 176
PFE_AI176, ///< AI execution for player slot 177
PFE_AI177, ///< AI execution for player slot 178
PFE_AI178, ///< AI execution for player slot 179
PFE_AI179, ///< AI execution for player slot 180
PFE_AI180, ///< AI execution for player slot 181
PFE_AI181, ///< AI execution for player slot 182
PFE_AI182, ///< AI execution for player slot 183
PFE_AI183, ///< AI execution for player slot 184
PFE_AI184, ///< AI execution for player slot 185
PFE_AI185, ///< AI execution for player slot 186
PFE_AI186, ///< AI execution for player slot 187
PFE_AI187, ///< AI execution for player slot 188
PFE_AI188, ///< AI execution for player slot 189
PFE_AI189, ///< AI execution for player slot 190
PFE_AI190, ///< AI execution for player slot 191
PFE_AI191, ///< AI execution for player slot 192
PFE_AI192, ///< AI execution for player slot 193
PFE_AI193, ///< AI execution for player slot 194
PFE_AI194, ///< AI execution for player slot 195
PFE_AI195, ///< AI execution for player slot 196
PFE_AI196, ///< AI execution for player slot 197
PFE_AI197, ///< AI execution for player slot 198
PFE_AI198, ///< AI execution for player slot 199
PFE_AI199, ///< AI execution for player slot 200
PFE_AI200, ///< AI execution for player slot 201
PFE_AI201, ///< AI execution for player slot 202
PFE_AI202, ///< AI execution for player slot 203
PFE_AI203, ///< AI execution for player slot 204
PFE_AI204, ///< AI execution for player slot 205
PFE_AI205, ///< AI execution for player slot 206
PFE_AI206, ///< AI execution for player slot 207
PFE_AI207, ///< AI execution for player slot 208
PFE_AI208, ///< AI execution for player slot 209
PFE_AI209, ///< AI execution for player slot 210
PFE_AI210, ///< AI execution for player slot 211
PFE_AI211, ///< AI execution for player slot 212
PFE_AI212, ///< AI execution for player slot 213
PFE_AI213, ///< AI execution for player slot 214
PFE_AI214, ///< AI execution for player slot 215
PFE_AI215, ///< AI execution for player slot 216
PFE_AI216, ///< AI execution for player slot 217
PFE_AI217, ///< AI execution for player slot 218
PFE_AI218, ///< AI execution for player slot 219
PFE_AI219, ///< AI execution for player slot 220
PFE_AI220, ///< AI execution for player slot 221
PFE_AI221, ///< AI execution for player slot 222
PFE_AI222, ///< AI execution for player slot 223
PFE_AI223, ///< AI execution for player slot 224
PFE_AI224, ///< AI execution for player slot 225
PFE_AI225, ///< AI execution for player slot 226
PFE_AI226, ///< AI execution for player slot 227
PFE_AI227, ///< AI execution for player slot 228
PFE_AI228, ///< AI execution for player slot 229
PFE_AI229, ///< AI execution for player slot 230
PFE_AI230, ///< AI execution for player slot 231
PFE_AI231, ///< AI execution for player slot 232
PFE_AI232, ///< AI execution for player slot 233
PFE_AI233, ///< AI execution for player slot 234
PFE_AI234, ///< AI execution for player slot 235
PFE_AI235, ///< AI execution for player slot 236
PFE_AI236, ///< AI execution for player slot 237
PFE_AI237, ///< AI execution for player slot 238
PFE_AI238, ///< AI execution for player slot 239
PFE_AI239, ///< AI execution for player slot 240
PFE_MAX, ///< End of enum, must be last.
};
DECLARE_POSTFIX_INCREMENT(PerformanceElement)
/** Type used to hold a performance timing measurement */

View File

@ -7,6 +7,7 @@
/** @file graph_gui.cpp GUI that shows performance graphs. */
#include "company_type.h"
#include "stdafx.h"
#include "graph_gui.h"
#include "window_gui.h"
@ -166,7 +167,7 @@ struct ValuesInterval {
struct BaseGraphWindow : Window {
protected:
static const int GRAPH_MAX_DATASETS = 64;
static const int GRAPH_MAX_DATASETS = 300;
static const int GRAPH_BASE_COLOUR = GREY_SCALE(2);
static const int GRAPH_GRID_COLOUR = GREY_SCALE(3);
static const int GRAPH_AXIS_LINE_COLOUR = GREY_SCALE(1);
@ -182,7 +183,7 @@ protected:
static const int MIN_GRAPH_NUM_LINES_Y = 9; ///< Minimal number of horizontal lines to draw.
static const int MIN_GRID_PIXEL_SIZE = 20; ///< Minimum distance between graph lines.
uint64_t excluded_data; ///< bitmask of the datasets that shouldn't be displayed.
CompanyMask excluded_data; ///< bitmask of the datasets that shouldn't be displayed.
uint8_t num_dataset;
uint8_t num_on_x_axis;
uint8_t num_vert_lines;

View File

@ -10,7 +10,9 @@
#ifndef INDUSTRY_MAP_H
#define INDUSTRY_MAP_H
#include "company_type.h"
#include "industrytype.h"
#include "tile_map.h"
#include "water_map.h"
@ -100,7 +102,7 @@ inline void SetIndustryCompleted(Tile tile)
inline uint8_t GetIndustryConstructionStage(Tile tile)
{
assert(IsTileType(tile, MP_INDUSTRY));
return IsIndustryCompleted(tile) ? (uint8_t)INDUSTRY_COMPLETED : GB(tile.m1(), 0, 2);
return IsIndustryCompleted(tile) ? (uint8_t)INDUSTRY_COMPLETED : GB(tile.m1(), 0, 2); // MYTODO: Figure this out, seams like it would read bits of the owner
}
/**
@ -286,6 +288,8 @@ inline void MakeIndustry(Tile t, IndustryID index, IndustryGfx gfx, uint8_t rand
SetIndustryTriggers(t, 0); // rest of m6
SetWaterClass(t, wc);
t.m7() = 0;
t.m8() = 0;
t.m9() = 0;
}
#endif /* INDUSTRY_MAP_H */

View File

@ -10,6 +10,8 @@
#ifndef MAP_FUNC_H
#define MAP_FUNC_H
#include "company_type.h"
#include "core/bitmath_func.hpp"
#include "core/math_func.hpp"
#include "tile_type.h"
#include "map_type.h"
@ -33,7 +35,7 @@ private:
uint8_t type; ///< The type (bits 4..7), bridges (2..3), rainforest/desert (0..1)
uint8_t height; ///< The height of the northern corner.
uint16_t m2; ///< Primarily used for indices to towns, industries and stations
uint8_t m1; ///< Primarily used for ownership information
uint8_t m1; ///< Primarily used for ownership information (In old versions)
uint8_t m3; ///< General purpose
uint8_t m4; ///< General purpose
uint8_t m5; ///< General purpose
@ -49,6 +51,7 @@ private:
uint8_t m6; ///< General purpose
uint8_t m7; ///< Primarily used for newgrf support
uint16_t m8; ///< General purpose
uint32_t m9; ///< Stores the actuall ownership information
};
static TileBase *base_tiles; ///< Pointer to the tile-array.
@ -198,6 +201,18 @@ public:
{
return extended_tiles[tile.base()].m8;
}
/**
* Primarily used for ownership information
* TODO: Add more docs
* Look at docs/landscape.html for the exact meaning of the data.
* @param tile The tile to get the data for.
* @return reference to the byte holding the data.
*/
debug_inline uint32_t &m9()
{
return extended_tiles[tile.base()].m9;
}
};
/**

View File

@ -130,6 +130,7 @@ public:
Debug(misc, LANDINFOD_LEVEL, "m6 = 0x{:x}", tile.m6());
Debug(misc, LANDINFOD_LEVEL, "m7 = 0x{:x}", tile.m7());
Debug(misc, LANDINFOD_LEVEL, "m8 = 0x{:x}", tile.m8());
Debug(misc, LANDINFOD_LEVEL, "m9 = 0x{:x}", tile.m9());
PrintWaterRegionDebugInfo(tile);
#undef LANDINFOD_LEVEL

View File

@ -83,8 +83,9 @@
case 0xAB: return GB(this->t->ratings[6], 8, 8);
case 0xAC: return this->t->ratings[7];
case 0xAD: return GB(this->t->ratings[7], 8, 8);
case 0xAE: return this->t->have_ratings;
case 0xB2: return this->t->statues;
// MYTODO: Fix this crap later
//case 0xAE: return this->t->have_ratings;
//case 0xB2: return this->t->statues;
case 0xB6: return ClampTo<uint16_t>(this->t->cache.num_houses);
case 0xB9: return this->t->growth_rate / Ticks::TOWN_GROWTH_TICKS;
case 0xBA: cid = GetCargoIDByLabel(CT_PASSENGERS); return IsValidCargoID(cid) ? ClampTo<uint16_t>(this->t->supplied[cid].new_max) : 0;

View File

@ -552,8 +552,9 @@ inline void SetRailDepotExitDirection(Tile tile, DiagDirection dir)
inline void MakeRailDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirection dir, RailType rail_type)
{
SetTileType(tile, MP_RAILWAY);
SetTileOwner(tile, owner);
SetDockingTile(tile, false);
SetTileOwner(tile, owner);
tile.m1() = 0;
tile.m2() = depot_id;
tile.m3() = 0;
tile.m4() = 0;

View File

@ -10,6 +10,7 @@
#ifndef ROAD_MAP_H
#define ROAD_MAP_H
#include "company_type.h"
#include "track_func.h"
#include "depot_type.h"
#include "rail_type.h"
@ -231,7 +232,7 @@ inline bool HasTileAnyRoadType(Tile t, RoadTypes rts)
* @param rtt RoadTramType.
* @return Owner of the given road type.
*/
inline Owner GetRoadOwner(Tile t, RoadTramType rtt)
inline Owner OldGetRoadOwner(Tile t, RoadTramType rtt)
{
assert(MayHaveRoad(t));
if (rtt == RTT_ROAD) return (Owner)GB(IsNormalRoadTile(t) ? t.m1() : t.m7(), 0, 5);
@ -239,6 +240,21 @@ inline Owner GetRoadOwner(Tile t, RoadTramType rtt)
/* Trams don't need OWNER_TOWN, and remapping OWNER_NONE
* to OWNER_TOWN makes it use one bit less */
Owner o = (Owner)GB(t.m3(), 4, 4);
return o == OLD_OWNER_TOWN ? OLD_OWNER_NONE : o;
}
/**
* Get the owner of a specific road type.
* @param t The tile to query.
* @param rtt RoadTramType.
* @return Owner of the given road type.
*/
inline Owner GetRoadOwner(Tile t, RoadTramType rtt)
{
assert(MayHaveRoad(t));
if (rtt == RTT_ROAD) return (Owner)GB(t.m9(), IsNormalRoadTile(t) ? 0 : COMPANY_SIZE_BITS * 2, COMPANY_SIZE_BITS);
Owner o = (Owner)GB(t.m9(), COMPANY_SIZE_BITS, COMPANY_SIZE_BITS);
return o == OWNER_TOWN ? OWNER_NONE : o;
}
@ -249,11 +265,26 @@ inline Owner GetRoadOwner(Tile t, RoadTramType rtt)
* @param o New owner of the given road type.
*/
inline void SetRoadOwner(Tile t, RoadTramType rtt, Owner o)
{
if (rtt == RTT_ROAD) {
SB(t.m9(), IsNormalRoadTile(t) ? 0 : COMPANY_SIZE_BITS * 2, COMPANY_SIZE_BITS, o);
} else {
SB(t.m9(), COMPANY_SIZE_BITS, COMPANY_SIZE_BITS, o==OWNER_NONE ? OWNER_TOWN : o);
}
}
/**
* Set the owner of a specific road type.
* @param t The tile to change.
* @param rtt RoadTramType.
* @param o New owner of the given road type.
*/
inline void OldSetRoadOwner(Tile t, RoadTramType rtt, Owner o)
{
if (rtt == RTT_ROAD) {
SB(IsNormalRoadTile(t) ? t.m1() : t.m7(), 0, 5, o);
} else {
SB(t.m3(), 4, 4, o == OWNER_NONE ? OWNER_TOWN : o);
SB(t.m3(), 4, 4, o == OLD_OWNER_NONE ? OLD_OWNER_TOWN : o);
}
}

View File

@ -63,11 +63,16 @@
#include "../timer/timer_game_economy.h"
#include "../timer/timer_game_tick.h"
#include "company_type.h"
#include "road_map.h"
#include "saveload/saveload.h"
#include "saveload_internal.h"
#include <signal.h>
#include "../safeguards.h"
#include "tile_map.h"
#include "tile_type.h"
extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY);
@ -163,7 +168,7 @@ static void ConvertTownOwner()
[[fallthrough]];
case MP_TUNNELBRIDGE:
if (tile.m1() & 0x80) SetTileOwner(tile, OWNER_TOWN);
if (tile.m1() & 0x80) OldSetTileOwner(tile, OWNER_TOWN);
break;
default: break;
@ -421,7 +426,7 @@ static void CDECL HandleSavegameLoadCrash(int signum)
*/
static void FixOwnerOfRailTrack(Tile t)
{
assert(!Company::IsValidID(GetTileOwner(t)) && (IsLevelCrossingTile(t) || IsPlainRailTile(t)));
assert(!Company::IsValidID(OldGetTileOwner(t)) && (IsLevelCrossingTile(t) || IsPlainRailTile(t)));
/* remove leftover rail piece from crossing (from very old savegames) */
Train *v = nullptr;
@ -434,7 +439,7 @@ static void FixOwnerOfRailTrack(Tile t)
if (v != nullptr) {
/* when there is a train on crossing (it could happen in TTD), set owner of crossing to train owner */
SetTileOwner(t, v->owner);
OldSetTileOwner(t, v->owner);
return;
}
@ -443,27 +448,27 @@ static void FixOwnerOfRailTrack(Tile t)
TileIndex tt = t + TileOffsByDiagDir(dd);
if (GetTileTrackStatus(t, TRANSPORT_RAIL, 0, dd) != 0 &&
GetTileTrackStatus(tt, TRANSPORT_RAIL, 0, ReverseDiagDir(dd)) != 0 &&
Company::IsValidID(GetTileOwner(tt))) {
SetTileOwner(t, GetTileOwner(tt));
Company::IsValidID(OldGetTileOwner(tt))) {
OldSetTileOwner(t, OldGetTileOwner(tt));
return;
}
}
if (IsLevelCrossingTile(t)) {
/* else change the crossing to normal road (road vehicles won't care) */
Owner road = GetRoadOwner(t, RTT_ROAD);
Owner tram = GetRoadOwner(t, RTT_TRAM);
Owner road = OldGetRoadOwner(t, RTT_ROAD);
Owner tram = OldGetRoadOwner(t, RTT_TRAM);
RoadBits bits = GetCrossingRoadBits(t);
bool hasroad = HasBit(t.m7(), 6);
bool hastram = HasBit(t.m7(), 7);
/* MakeRoadNormal */
SetTileType(t, MP_ROAD);
SetTileOwner(t, road);
OldSetTileOwner(t, road);
t.m3() = (hasroad ? bits : 0);
t.m5() = (hastram ? bits : 0) | ROAD_TILE_NORMAL << 6;
SB(t.m6(), 2, 4, 0);
SetRoadOwner(t, RTT_TRAM, tram);
OldSetRoadOwner(t, RTT_TRAM, tram);
return;
}
@ -471,6 +476,7 @@ static void FixOwnerOfRailTrack(Tile t)
MakeClear(t, CLEAR_GRASS, 0);
}
/**
* Fixes inclination of a vehicle. Older OpenTTD versions didn't update the bits correctly.
* @param v vehicle
@ -656,8 +662,8 @@ bool AfterLoadGame()
* walk through the whole map.. */
if (IsSavegameVersionBefore(SLV_4, 3)) {
for (auto t : Map::Iterate()) {
if (IsTileType(t, MP_WATER) && GetTileOwner(t) >= MAX_COMPANIES) {
SetTileOwner(t, OWNER_WATER);
if (IsTileType(t, MP_WATER) && OldGetTileOwner(t) >= OLD_MAX_COMPANIES) {
OldSetTileOwner(t, OWNER_WATER);
}
}
}
@ -858,7 +864,7 @@ bool AfterLoadGame()
default: break;
case MP_WATER:
if (GetWaterTileType(t) == WATER_TILE_LOCK && GetTileOwner(t) == OWNER_WATER) SetTileOwner(t, OWNER_NONE);
if (GetWaterTileType(t) == WATER_TILE_LOCK && OldGetTileOwner(t) == OWNER_WATER) OldSetTileOwner(t, OWNER_NONE);
break;
case MP_STATION: {
@ -913,7 +919,7 @@ bool AfterLoadGame()
BaseStation *bst = BaseStation::GetByTile(t);
/* Sanity check */
if (!IsBuoy(t) && bst->owner != GetTileOwner(t)) SlErrorCorrupt("Wrong owner for station tile");
if (!IsBuoy(t) && bst->owner != OldGetTileOwner(t)) SlErrorCorrupt("Wrong owner for station tile");
/* Set up station spread */
bst->rect.BeforeAddTile(t, StationRect::ADD_FORCE);
@ -986,7 +992,7 @@ bool AfterLoadGame()
case MP_ROAD:
t.m4() |= (t.m2() << 4);
if ((GB(t.m5(), 4, 2) == ROAD_TILE_CROSSING ? (Owner)t.m3() : GetTileOwner(t)) == OWNER_TOWN) {
if ((GB(t.m5(), 4, 2) == ROAD_TILE_CROSSING ? (Owner)t.m3() : OldGetTileOwner(t)) == OLD_OWNER_TOWN) {
SetTownIndex(t, CalcClosestTownFromTile(t)->index);
} else {
SetTownIndex(t, 0);
@ -1139,7 +1145,7 @@ bool AfterLoadGame()
if (!IsRoadStop(t)) break;
if (fix_roadtypes) SB(t.m7(), 6, 2, (RoadTypes)GB(t.m3(), 0, 3));
SB(t.m7(), 0, 5, HasBit(t.m6(), 2) ? OWNER_TOWN : GetTileOwner(t));
SB(t.m7(), 0, 5, HasBit(t.m6(), 2) ? OWNER_TOWN : OldGetTileOwner(t));
SB(t.m3(), 4, 4, t.m1());
t.m4() = 0;
break;
@ -1149,9 +1155,9 @@ bool AfterLoadGame()
if (((old_bridge && IsBridge(t)) ? (TransportType)GB(t.m5(), 1, 2) : GetTunnelBridgeTransportType(t)) == TRANSPORT_ROAD) {
if (fix_roadtypes) SB(t.m7(), 6, 2, (RoadTypes)GB(t.m3(), 0, 3));
Owner o = GetTileOwner(t);
Owner o = OldGetTileOwner(t);
SB(t.m7(), 0, 5, o); // road owner
SB(t.m3(), 4, 4, o == OWNER_NONE ? OWNER_TOWN : o); // tram owner
SB(t.m3(), 4, 4, o == OLD_OWNER_NONE ? OWNER_TOWN : o); // tram owner
}
SB(t.m6(), 2, 4, GB(t.m2(), 4, 4)); // bridge type
SB(t.m7(), 5, 1, GB(t.m4(), 7, 1)); // snow/desert
@ -1208,12 +1214,12 @@ bool AfterLoadGame()
if (GB(t.m5(), 3, 2) == TRANSPORT_RAIL) {
MakeRailNormal(
t,
GetTileOwner(t),
OldGetTileOwner(t),
axis == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X,
GetRailType(t)
);
} else {
TownID town = IsTileOwner(t, OWNER_TOWN) ? ClosestTownFromTile(t, UINT_MAX)->index : 0;
TownID town = IsTileOwner(t, OLD_OWNER_TOWN) ? ClosestTownFromTile(t, UINT_MAX)->index : 0;
/* MakeRoadNormal */
SetTileType(t, MP_ROAD);
@ -1222,7 +1228,7 @@ bool AfterLoadGame()
t.m5() = (axis == AXIS_X ? ROAD_Y : ROAD_X) | ROAD_TILE_NORMAL << 6;
SB(t.m6(), 2, 4, 0);
t.m7() = 1 << 6;
SetRoadOwner(t, RTT_TRAM, OWNER_NONE);
OldSetRoadOwner(t, RTT_TRAM, OWNER_NONE);
}
} else {
if (GB(t.m5(), 3, 2) == 0) {
@ -1231,10 +1237,10 @@ bool AfterLoadGame()
if (!IsTileFlat(t)) {
MakeShore(t);
} else {
if (GetTileOwner(t) == OWNER_WATER) {
if (OldGetTileOwner(t) == OWNER_WATER) {
MakeSea(t);
} else {
MakeCanal(t, GetTileOwner(t), Random());
MakeCanal(t, OldGetTileOwner(t), Random());
}
}
}
@ -1568,7 +1574,7 @@ bool AfterLoadGame()
* be OWNER_NONE. So replace OWNER_NONE with OWNER_WATER. */
if (IsSavegameVersionBefore(SLV_46)) {
for (Waypoint *wp : Waypoint::Iterate()) {
if ((wp->facilities & FACIL_DOCK) != 0 && IsTileOwner(wp->xy, OWNER_NONE) && TileHeight(wp->xy) == 0) SetTileOwner(wp->xy, OWNER_WATER);
if ((wp->facilities & FACIL_DOCK) != 0 && IsTileOwner(wp->xy, OLD_OWNER_NONE) && TileHeight(wp->xy) == 0) OldSetTileOwner(wp->xy, OWNER_WATER);
}
}
@ -1678,9 +1684,9 @@ bool AfterLoadGame()
for (auto t : Map::Iterate()) {
if (IsTileType(t, MP_WATER) &&
GetWaterTileType(t) == WATER_TILE_CLEAR &&
GetTileOwner(t) == OWNER_WATER &&
OldGetTileOwner(t) == OWNER_WATER &&
TileHeight(t) != 0) {
SetTileOwner(t, OWNER_NONE);
OldSetTileOwner(t, OWNER_NONE);
}
}
}
@ -1828,7 +1834,7 @@ bool AfterLoadGame()
if (IsTileType(t, MP_WATER)) {
if (GetWaterClass(t) != WATER_CLASS_RIVER) {
if (IsWater(t)) {
Owner o = GetTileOwner(t);
Owner o = OldGetTileOwner(t);
if (o == OWNER_WATER) {
MakeSea(t);
} else {
@ -1864,8 +1870,8 @@ bool AfterLoadGame()
}
if (IsBuoyTile(t) || IsDriveThroughStopTile(t) || IsTileType(t, MP_WATER)) {
Owner o = GetTileOwner(t);
if (o < MAX_COMPANIES && !Company::IsValidID(o)) {
Owner o = OldGetTileOwner(t);
if (o < OLD_MAX_COMPANIES && !Company::IsValidID(o)) {
Backup<CompanyID> cur_company(_current_company, o);
ChangeTileOwner(t, o, INVALID_OWNER);
cur_company.Restore();
@ -1879,14 +1885,14 @@ bool AfterLoadGame()
/* works for all RoadTileType */
for (RoadTramType rtt : _roadtramtypes) {
/* update even non-existing road types to update tile owner too */
Owner o = GetRoadOwner(t, rtt);
if (o < MAX_COMPANIES && !Company::IsValidID(o)) SetRoadOwner(t, rtt, OWNER_NONE);
Owner o = OldGetRoadOwner(t, rtt);
if (o < OLD_MAX_COMPANIES && !Company::IsValidID(o)) OldSetRoadOwner(t, rtt, OWNER_NONE);
}
if (IsLevelCrossing(t)) {
if (!Company::IsValidID(GetTileOwner(t))) FixOwnerOfRailTrack(t);
if (!Company::IsValidID(OldGetTileOwner(t))) FixOwnerOfRailTrack(t);
}
} else if (IsPlainRailTile(t)) {
if (!Company::IsValidID(GetTileOwner(t))) FixOwnerOfRailTrack(t);
if (!Company::IsValidID(OldGetTileOwner(t))) FixOwnerOfRailTrack(t);
}
}
}
@ -1996,7 +2002,7 @@ bool AfterLoadGame()
/* signs with invalid owner left from older savegames */
for (Sign *si : Sign::Iterate()) {
if (si->owner != OWNER_NONE && !Company::IsValidID(si->owner)) si->owner = OWNER_NONE;
if (si->owner != OLD_OWNER_NONE && !Company::IsValidID(si->owner)) si->owner = OWNER_NONE;
}
/* Station can get named based on an industry type, but the current ones
@ -2025,7 +2031,7 @@ bool AfterLoadGame()
for (Town *t : Town::Iterate()) {
if (t->have_ratings == 0xFF) t->have_ratings = MAX_UVALUE(CompanyMask);
for (uint i = 8; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
for (uint i = 8; i != OLD_MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
}
}
@ -2407,7 +2413,6 @@ bool AfterLoadGame()
/* We need to properly number/name the depots.
* The first step is making sure none of the depots uses the
* 'default' names, after that we can assign the names. */
for (Depot *d : Depot::Iterate()) d->town_cn = UINT16_MAX;
for (Depot *d : Depot::Iterate()) MakeDefaultName(d);
}
@ -2473,8 +2478,8 @@ bool AfterLoadGame()
/* Add (random) colour to all objects. */
if (IsSavegameVersionBefore(SLV_148)) {
for (Object *o : Object::Iterate()) {
Owner owner = GetTileOwner(o->location.tile);
o->colour = (owner == OWNER_NONE) ? static_cast<Colours>(GB(Random(), 0, 4)) : Company::Get(owner)->livery->colour1;
Owner owner = OldGetTileOwner(o->location.tile);
o->colour = (owner == OLD_OWNER_NONE) ? static_cast<Colours>(GB(Random(), 0, 4)) : Company::Get(owner)->livery->colour1;
}
}
@ -2841,9 +2846,9 @@ bool AfterLoadGame()
if (IsSavegameVersionBefore(SLV_172)) {
for (auto t : Map::Iterate()) {
if (!IsBayRoadStopTile(t)) continue;
Owner o = GetTileOwner(t);
SetRoadOwner(t, RTT_ROAD, o);
SetRoadOwner(t, RTT_TRAM, o);
Owner o = OldGetTileOwner(t);
OldSetRoadOwner(t, RTT_ROAD, o);
OldSetRoadOwner(t, RTT_TRAM, o);
}
}
@ -3262,6 +3267,27 @@ bool AfterLoadGame()
if (IsSavegameVersionBefore(SLV_SCRIPT_RANDOMIZER)) {
ScriptObject::InitializeRandomizers();
}
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
for (auto t : Map::Iterate()) {
//SB(t.m9(), 0, COMPANY_SIZE_BITS, OWNER_NONE);
if (!IsValidTile(t)) {
continue;
}
if (!IsTileType(t, MP_HOUSE)
&& !IsTileType(t, MP_INDUSTRY)) {
Owner o =OldGetTileOwner(t) ;
o = ParseOldOwner(o);
SetTileOwner(t, o);
}
if (MayHaveRoad(t)) {
for (RoadTramType rtt : _roadtramtypes) {
Owner o = OldGetRoadOwner(t, rtt);
o = ParseOldOwner(o);
SetRoadOwner(t, rtt, o);
}
}
}
}
for (Company *c : Company::Iterate()) {
UpdateCompanyLiveries(c);

View File

@ -475,9 +475,11 @@ static const SaveLoad _company_desc[] = {
SLE_CONDVAR(CompanyProperties, num_valid_stat_ent, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH),
SLE_VAR(CompanyProperties, months_of_bankruptcy, SLE_UINT8),
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, months_of_bankruptcy, SLE_UINT8),
SLE_CONDVARNAME(CompanyProperties, old_bankrupt_asked, "bankrupt_asked", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVARNAME(CompanyProperties, old_bankrupt_asked, "bankrupt_asked", SLE_UINT16, SLV_104, SLV_MORE_COMPANIES),
SLE_CONDCOMPMASK(CompanyProperties, bankrupt_asked, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
SLE_VAR(CompanyProperties, bankrupt_timeout, SLE_INT16),
SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SLV_65),
SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_INT64, SLV_65, SL_MAX_VERSION),
@ -520,6 +522,9 @@ struct PLYRChunkHandler : ChunkHandler {
Company *c = new (index) Company();
SlObject(c, slt);
_company_colours[index] = c->colour;
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
c->bankrupt_asked = ParseOldCompMask(c->old_bankrupt_asked);
}
}
}

View File

@ -9,6 +9,7 @@
#include "../stdafx.h"
#include "company_type.h"
#include "saveload.h"
#include "compat/engine_sl_compat.h"
@ -19,25 +20,32 @@
#include "../safeguards.h"
static const SaveLoad _engine_desc[] = {
SLE_CONDVAR(Engine, intro_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Engine, intro_date, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_CONDVAR(Engine, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Engine, age, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_VAR(Engine, reliability, SLE_UINT16),
SLE_VAR(Engine, reliability_spd_dec, SLE_UINT16),
SLE_VAR(Engine, reliability_start, SLE_UINT16),
SLE_VAR(Engine, reliability_max, SLE_UINT16),
SLE_VAR(Engine, reliability_final, SLE_UINT16),
SLE_VAR(Engine, duration_phase_1, SLE_UINT16),
SLE_VAR(Engine, duration_phase_2, SLE_UINT16),
SLE_VAR(Engine, duration_phase_3, SLE_UINT16),
SLE_VAR(Engine, flags, SLE_UINT8),
SLE_CONDVAR(Engine, preview_asked, SLE_UINT16, SLV_179, SL_MAX_VERSION),
SLE_CONDVAR(Engine, preview_company, SLE_UINT8, SLV_179, SL_MAX_VERSION),
SLE_VAR(Engine, preview_wait, SLE_UINT8),
SLE_CONDVAR(Engine, company_avail, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVAR(Engine, company_avail, SLE_UINT16, SLV_104, SL_MAX_VERSION),
SLE_CONDVAR(Engine, company_hidden, SLE_UINT16, SLV_193, SL_MAX_VERSION),
SLE_CONDVAR(Engine, intro_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Engine, intro_date, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_CONDVAR(Engine, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Engine, age, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_VAR(Engine, reliability, SLE_UINT16),
SLE_VAR(Engine, reliability_spd_dec, SLE_UINT16),
SLE_VAR(Engine, reliability_start, SLE_UINT16),
SLE_VAR(Engine, reliability_max, SLE_UINT16),
SLE_VAR(Engine, reliability_final, SLE_UINT16),
SLE_VAR(Engine, duration_phase_1, SLE_UINT16),
SLE_VAR(Engine, duration_phase_2, SLE_UINT16),
SLE_VAR(Engine, duration_phase_3, SLE_UINT16),
SLE_VAR(Engine, flags, SLE_UINT8),
SLE_CONDVARNAME(Engine, old_preview_asked, "preview_asked", SLE_UINT16, SLV_179, SLV_MORE_COMPANIES),
SLE_CONDCOMPMASK(Engine, preview_asked, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
SLE_CONDVAR(Engine, preview_company, SLE_UINT8, SLV_179, SL_MAX_VERSION),
SLE_VAR(Engine, preview_wait, SLE_UINT8),
SLE_CONDVARNAME(Engine, old_company_avail, "company_avail", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVARNAME(Engine, old_company_avail, "company_avail", SLE_UINT16, SLV_104, SLV_MORE_COMPANIES),
SLE_CONDCOMPMASK(Engine, company_avail, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
SLE_CONDCOMPMASK(Engine, company_hidden, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
SLE_CONDVARNAME(Engine, old_company_hidden, "company_hidden", SLE_UINT16, SLV_193, SLV_MORE_COMPANIES),
SLE_CONDSSTR(Engine, name, SLE_STR, SLV_84, SL_MAX_VERSION),
};
@ -111,6 +119,11 @@ struct ENGNChunkHandler : ChunkHandler {
e->preview_company = INVALID_COMPANY;
e->preview_asked = MAX_UVALUE(CompanyMask);
}
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
e->preview_asked = ParseOldCompMask(e->old_preview_asked);
e->company_avail = ParseOldCompMask(e->old_company_avail);
e->company_hidden = ParseOldCompMask(e->old_company_hidden);
}
}
}
};

View File

@ -54,6 +54,9 @@ struct GRPSChunkHandler : ChunkHandler {
SlObject(g, slt);
if (IsSavegameVersionBefore(SLV_189)) g->parent = INVALID_GROUP;
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
g->owner = ParseOldOwner(g->owner);
}
}
}
};

View File

@ -9,6 +9,7 @@
#include "../stdafx.h"
#include "company_type.h"
#include "saveload.h"
#include "compat/industry_sl_compat.h"
@ -265,6 +266,12 @@ struct INDYChunkHandler : ChunkHandler {
} else if (IsSavegameVersionBefore(SLV_INDUSTRY_CARGO_REORGANISE)) {
LoadMoveAcceptsProduced(i, INDUSTRY_NUM_INPUTS, INDUSTRY_NUM_OUTPUTS);
}
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
i->owner = ParseOldOwner(i-> owner);
i->founder = ParseOldOwner(i-> founder);
i->exclusive_supplier = ParseOldOwner(i-> exclusive_supplier);
i->exclusive_consumer = ParseOldOwner(i-> exclusive_consumer);
}
Industry::IncIndustryTypeCount(i->type);
}
}

View File

@ -17,6 +17,7 @@
#include "../fios.h"
#include "../safeguards.h"
#include <iostream>
static uint32_t _map_dim_x;
static uint32_t _map_dim_y;
@ -128,10 +129,10 @@ struct MAPOChunkHandler : ChunkHandler {
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
uint size = Map::Size();
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m1() = buf[j];
}
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m1() = buf[j];
}
}
void Save() const override
@ -352,6 +353,34 @@ struct MAP8ChunkHandler : ChunkHandler {
}
};
struct MAP9ChunkHandler : ChunkHandler {
MAP9ChunkHandler() : ChunkHandler('MAP9', CH_RIFF) {}
void Load() const override
{
std::array<uint32_t, MAP_SL_BUF_SIZE> buf;
uint size = Map::Size();
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT32);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m9() = buf[j];
}
}
void Save() const override
{
std::array<uint32_t, MAP_SL_BUF_SIZE> buf;
uint size = Map::Size();
std::cout<< "loading m9" << std::endl;
SlSetLength(static_cast<uint32_t>(size) * sizeof(uint32_t));
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m9();
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT32);
}
}
};
static const MAPSChunkHandler MAPS;
static const MAPTChunkHandler MAPT;
static const MAPHChunkHandler MAPH;
@ -363,6 +392,7 @@ static const MAP5ChunkHandler MAP5;
static const MAPEChunkHandler MAPE;
static const MAP7ChunkHandler MAP7;
static const MAP8ChunkHandler MAP8;
static const MAP9ChunkHandler MAP9;
static const ChunkHandlerRef map_chunk_handlers[] = {
MAPS,
MAPT,
@ -375,6 +405,7 @@ static const ChunkHandlerRef map_chunk_handlers[] = {
MAPE,
MAP7,
MAP8,
MAP9,
};
extern const ChunkHandlerTable _map_chunk_handlers(map_chunk_handlers);

View File

@ -253,6 +253,7 @@ static bool FixTTOMapArray()
break;
case 1: // ROAD_TILE_CROSSING (there aren't monorail crossings in TTO)
tile.m3() = tile.m1(); // set owner of road = owner of rail
// TODO: Fix this
break;
case 2: // ROAD_TILE_DEPOT
break;

View File

@ -20,6 +20,7 @@
* </ol>
*/
#include "saveload/saveload.h"
#include "../stdafx.h"
#include "../debug.h"
#include "../station_base.h"
@ -42,7 +43,13 @@
#include "../string_func.h"
#include "../fios.h"
#include "../error.h"
#include "company_type.h"
#include "core/bitmath_func.hpp"
#include <atomic>
#include <bitset>
#include <cassert>
#include <cstdint>
#include <vector>
#ifdef __EMSCRIPTEN__
# include <emscripten.h>
#endif
@ -53,6 +60,7 @@
#include "saveload_filter.h"
#include "../safeguards.h"
#include <iostream>
extern const SaveLoadVersion SAVEGAME_VERSION = (SaveLoadVersion)(SL_MAX_VERSION - 1); ///< Current savegame version of OpenTTD.
@ -558,6 +566,7 @@ static uint8_t GetSavegameFileType(const SaveLoad &sld)
case SL_STDSTR:
case SL_ARR:
case SL_VECTOR:
case SL_COMPANY_MASK:
case SL_DEQUE:
return GetVarFileType(sld.conv) | SLE_FILE_HAS_LENGTH_FIELD; break;
@ -1075,6 +1084,7 @@ static void SlArray(void *array, size_t length, VarType conv)
/* If the SLE_ARR changes size, a savegame bump is required
* and the developer should have written conversion lines.
* Error out to make this more visible. */
std::cout << "Corrupted array!!" << std::endl;
SlErrorCorrupt("Fixed-length array is of wrong length");
}
}
@ -1092,6 +1102,82 @@ static void SlArray(void *array, size_t length, VarType conv)
}
}
// MYTODO: Put this somewhere it belongs
std::vector<uint8_t> bitset_to_bytes(const CompanyMask& mask)
{
std::vector<unsigned char> result((MAX_COMPANIES + 7) >> 3);
for (int j = 0; j < MAX_COMPANIES; j++)
result[j>>3] |= (mask[j] << (j & 7));
return result;
}
CompanyMask bitset_from_bytes(const std::vector<uint8_t>& buf) {
CompanyMask result;
for (int j=0; j < MAX_COMPANIES; j++)
result[j] = ((buf[j>>3] >> (j & 7)) & 1);
return result;
}
CompanyMask ParseOldCompMask(uint16_t old_owner) {
CompanyMask result;
for (int i = 0; i < 16; i++) {
result[i] = GB(old_owner, i, 1) & 1;
}
return result;
}
Owner ParseOldOwner(Owner old) {
if (old == OLD_OWNER_NONE) {
old = OWNER_NONE;
} else if (old == OLD_OWNER_TOWN){
old = OWNER_TOWN;
} else if (old == OLD_OWNER_WATER) {
old = OWNER_WATER;
}
return old;
}
/**
* Save/Load the length of the bitset followed by the array of SL_VAR bits.
* @param array The array being manipulated
* @param length The length of the bitset in bytes,
*/
static void SlCompanyMask(void *array, size_t byte_length, VarType conv)
{
switch (_sl.action) {
case SLA_SAVE: {
CompanyMask *bs = static_cast<CompanyMask *>(array);
std::vector<uint8_t> bytes = bitset_to_bytes(*bs);
uint8_t *bytes_arr = &bytes[0];
SlArray(bytes_arr, bytes.size(), conv);
return;
}
case SLA_LOAD_CHECK:
case SLA_LOAD: {
assert(byte_length == (MAX_COMPANIES + 7) >> 3);
std::vector<uint8_t> buff((MAX_COMPANIES + 7) >> 3);
SlArray(&buff[0], byte_length, conv);
CompanyMask *bs = static_cast<CompanyMask *>(array);
*bs = bitset_from_bytes(buff); // we don't want to write direc
return;
}
case SLA_PTRS:
case SLA_NULL:
return;
default:
NOT_REACHED();
}
}
/**
* Pointers cannot be saved to a savegame, so this functions gets
* the index of the item, and if not available, it hussles with
@ -1500,6 +1586,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld)
case SL_VAR: return SlCalcConvFileLen(sld.conv);
case SL_REF: return SlCalcRefLen();
case SL_ARR: return SlCalcArrayLen(sld.length, sld.conv);
case SL_COMPANY_MASK: return SlCalcArrayLen(sld.length, sld.conv);
case SL_REFLIST: return SlCalcRefListLen(GetVariableAddress(object, sld), sld.conv);
case SL_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld.conv);
case SL_VECTOR: return SlCalcVectorLen(GetVariableAddress(object, sld), sld.conv);
@ -1538,6 +1625,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld)
static bool SlObjectMember(void *object, const SaveLoad &sld)
{
std::cout <<"Object: "<< sld.name << std::endl;
if (!SlIsObjectValidInSavegame(sld)) return false;
VarType conv = GB(sld.conv, 0, 8);
@ -1548,6 +1636,7 @@ static bool SlObjectMember(void *object, const SaveLoad &sld)
case SL_REFLIST:
case SL_DEQUE:
case SL_VECTOR:
case SL_COMPANY_MASK:
case SL_STDSTR: {
void *ptr = GetVariableAddress(object, sld);
@ -1555,6 +1644,7 @@ static bool SlObjectMember(void *object, const SaveLoad &sld)
case SL_VAR: SlSaveLoadConv(ptr, conv); break;
case SL_REF: SlSaveLoadRef(ptr, conv); break;
case SL_ARR: SlArray(ptr, sld.length, conv); break;
case SL_COMPANY_MASK: SlCompanyMask(ptr, sld.length, conv); break;
case SL_REFLIST: SlRefList(ptr, conv); break;
case SL_DEQUE: SlDeque(ptr, conv); break;
case SL_VECTOR: SlVector(ptr, conv); break;
@ -2156,10 +2246,12 @@ static void SlLoadCheckChunks()
const ChunkHandler *ch;
for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
Debug(sl, 2, "Loading chunk {:c}{:c}{:c}{:c}", id >> 24, id >> 16, id >> 8, id);
Debug(sl, 2, "Loading chunk (for checking) {:c}{:c}{:c}{:c}", id >> 24, id >> 16, id >> 8, id);
ch = SlFindChunkHandler(id);
if (ch == nullptr) SlErrorCorrupt("Unknown chunk type");
if (ch == nullptr) {
SlErrorCorrupt("Unknown chunk type");
}
SlLoadCheckChunk(*ch);
}
}

View File

@ -381,6 +381,7 @@ enum SaveLoadVersion : uint16_t {
SLV_COMPANY_ALLOW_LIST, ///< 335 PR#12337 Saving of list of client keys that are allowed to join this company.
SLV_GROUP_NUMBERS, ///< 336 PR#12297 Add per-company group numbers.
SLV_MORE_COMPANIES, /// Added more companies MYTODO: Fix this comment
SL_MAX_VERSION, ///< Highest possible saveload version
};
@ -690,9 +691,10 @@ enum SaveLoadType : uint8_t {
SL_VECTOR = 7, ///< Save/load a vector of #SL_VAR elements.
SL_REFLIST = 8, ///< Save/load a list of #SL_REF elements.
SL_STRUCTLIST = 9, ///< Save/load a list of structs.
SL_COMPANY_MASK = 10, ///< Save/load a fixed-size bitset of #SL_VAR bits.
SL_SAVEBYTE = 10, ///< Save (but not load) a byte.
SL_NULL = 11, ///< Save null-bytes and load to nowhere.
SL_SAVEBYTE = 11, ///< Save (but not load) a byte.
SL_NULL = 12, ///< Save null-bytes and load to nowhere.
};
typedef void *SaveLoadAddrProc(void *base, size_t extra);
@ -799,6 +801,7 @@ inline constexpr bool SlCheckVarSize(SaveLoadType cmd, VarType type, size_t leng
case SL_REF: return sizeof(void *) == size;
case SL_STDSTR: return SlVarSize(type) == size;
case SL_ARR: return SlVarSize(type) * length <= size; // Partial load of array is permitted.
case SL_COMPANY_MASK: return SlVarSize(type) * length <= size; // Partial load of array is permitted.
case SL_DEQUE: return sizeof(std::deque<void *>) == size;
case SL_VECTOR: return sizeof(std::vector<void *>) == size;
case SL_REFLIST: return sizeof(std::list<void *>) == size;
@ -1001,6 +1004,17 @@ inline constexpr bool SlCheckVarSize(SaveLoadType cmd, VarType type, size_t leng
*/
#define SLE_ARRNAME(base, variable, name, type, length) SLE_CONDARRNAME(base, variable, name, type, length, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a company mask bitset of #MAX_COMPANIES bits in some savegame versions.
* @param base Name of the class or struct containing the company mask.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param bit_length Number of bits in the serialized form.
* @param from First savegame version that has the array.
* @param to Last savegame version that has the array.
*/
#define SLE_CONDCOMPMASK(base, variable, bit_length, from, to) SLE_GENERAL(SL_COMPANY_MASK, base, variable, SLE_CHAR, (bit_length + 7) >> 3, from, to, 0)
/**
* Storage of a \c std::string in every savegame version.
* @param base Name of the class or struct containing the string.
@ -1300,6 +1314,8 @@ void SlCopy(void *object, size_t length, VarType conv);
std::vector<SaveLoad> SlTableHeader(const SaveLoadTable &slt);
std::vector<SaveLoad> SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct);
void SlObject(void *object, const SaveLoadTable &slt);
CompanyMask ParseOldCompMask(uint16_t old_owner);
Owner ParseOldOwner(Owner old);
bool SaveloadCrashWithMissingNewGRFs();

View File

@ -9,6 +9,7 @@
#include "../stdafx.h"
#include "company_type.h"
#include "saveload.h"
#include "compat/signs_sl_compat.h"
@ -62,9 +63,12 @@ struct SIGNChunkHandler : ChunkHandler {
}
/* Signs placed in scenario editor shall now be OWNER_DEITY */
if (IsSavegameVersionBefore(SLV_171) && si->owner == OWNER_NONE && _file_to_saveload.abstract_ftype == FT_SCENARIO) {
if (IsSavegameVersionBefore(SLV_171) && si->owner == OLD_OWNER_NONE && _file_to_saveload.abstract_ftype == FT_SCENARIO) {
si->owner = OWNER_DEITY;
}
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
si->owner = ParseOldOwner(si->owner);
}
}
}
};

View File

@ -502,6 +502,9 @@ struct STNSChunkHandler : ChunkHandler {
_waiting_acceptance = 0;
SlObject(st, slt);
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
st->owner = ParseOldOwner(st->owner);
}
}
}

View File

@ -215,15 +215,21 @@ static const SaveLoad _town_desc[] = {
SLE_CONDSSTR(Town, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION),
SLE_VAR(Town, flags, SLE_UINT8),
SLE_CONDVAR(Town, statues, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVAR(Town, statues, SLE_UINT16, SLV_104, SL_MAX_VERSION),
SLE_CONDVARNAME(Town, old_statues, "statues", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVARNAME(Town, old_statues, "statues", SLE_UINT16, SLV_104, SLV_MORE_COMPANIES),
SLE_CONDCOMPMASK(Town, statues, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
SLE_CONDCOMPMASK(Town, have_ratings, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
SLE_CONDVARNAME(Town, old_have_ratings, "have_ratings", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVARNAME(Town, old_have_ratings, "have_ratings", SLE_UINT16, SLV_104, SLV_MORE_COMPANIES),
SLE_CONDVAR(Town, have_ratings, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVAR(Town, have_ratings, SLE_UINT16, SLV_104, SL_MAX_VERSION),
SLE_CONDARR(Town, ratings, SLE_INT16, 8, SL_MIN_VERSION, SLV_104),
SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, SLV_104, SL_MAX_VERSION),
SLE_CONDARR(Town, ratings, SLE_INT16, 15, SLV_104, SLV_MORE_COMPANIES),
SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
SLE_CONDARR(Town, unwanted, SLE_INT8, 8, SLV_4, SLV_104),
SLE_CONDARR(Town, unwanted, SLE_INT8, MAX_COMPANIES, SLV_104, SL_MAX_VERSION),
SLE_CONDARR(Town, unwanted, SLE_INT8, 15, SLV_104, SLV_MORE_COMPANIES),
SLE_CONDARR(Town, unwanted, SLE_INT8, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
/* Slots 0 and 2 are passengers and mail respectively for old saves. */
SLE_CONDVARNAME(Town, supplied[0].old_max, "supplied[CT_PASSENGERS].old_max", SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
@ -306,6 +312,10 @@ struct CITYChunkHandler : ChunkHandler {
if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GetStringTab(t->townnametype) != TEXT_TAB_OLD_CUSTOM) {
SlErrorCorrupt("Invalid town name generator");
}
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
t->statues = ParseOldCompMask(t->old_statues);
t->have_ratings = ParseOldCompMask(t->old_have_ratings);
}
}
}

View File

@ -405,6 +405,11 @@ void AfterLoadVehicles(bool part_of_load)
v->economy_age = v->age.base();
}
}
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
for (Vehicle *v : Vehicle::Iterate()) {
v->owner = ParseOldOwner(v->owner);
}
}
}
CheckValidVehicles();

View File

@ -16,6 +16,7 @@
#include "../newgrf.h"
#include "../timer/timer_game_calendar.h"
#include "saveload/saveload.h"
#include "table/strings.h"
#include "saveload_internal.h"
@ -200,6 +201,9 @@ struct CHKPChunkHandler : ChunkHandler {
wp->index = index;
SlObject(wp, _old_waypoint_desc);
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
wp->owner = ParseOldOwner(wp->owner);
}
}
}

View File

@ -10,6 +10,7 @@
#ifndef TILE_MAP_H
#define TILE_MAP_H
#include "company_type.h"
#include "slope_type.h"
#include "map_func.h"
#include "core/bitmath_func.hpp"
@ -181,6 +182,27 @@ inline Owner GetTileOwner(Tile tile)
assert(!IsTileType(tile, MP_HOUSE));
assert(!IsTileType(tile, MP_INDUSTRY));
return (Owner)GB(tile.m9(), 0, COMPANY_SIZE_BITS);
}
/**
* Returns the owner of a tile. Only used for legacy code
*
* This function returns the owner of a tile. This cannot used
* for tiles which type is one of MP_HOUSE, MP_VOID and MP_INDUSTRY
* as no company owned any of these buildings.
*
* @param tile The tile to check
* @return The owner of the tile
* @pre IsValidTile(tile)
* @pre The type of the tile must not be MP_HOUSE and MP_INDUSTRY
*/
inline Owner OldGetTileOwner(Tile tile)
{
assert(IsValidTile(tile));
assert(!IsTileType(tile, MP_HOUSE));
assert(!IsTileType(tile, MP_INDUSTRY));
return (Owner)GB(tile.m1(), 0, 5);
}
@ -201,9 +223,30 @@ inline void SetTileOwner(Tile tile, Owner owner)
assert(!IsTileType(tile, MP_HOUSE));
assert(!IsTileType(tile, MP_INDUSTRY));
SB(tile.m9(), 0, COMPANY_SIZE_BITS, owner);
}
/**
* Sets the owner of a tile (Only for old formats)
*
* This function sets the owner status of a tile. Note that you cannot
* set a owner for tiles of type MP_HOUSE, MP_VOID and MP_INDUSTRY.
*
* @param tile The tile to change the owner status.
* @param owner The new owner.
* @pre IsValidTile(tile)
* @pre The type of the tile must not be MP_HOUSE and MP_INDUSTRY
*/
inline void OldSetTileOwner(Tile tile, Owner owner)
{
assert(IsValidTile(tile));
assert(!IsTileType(tile, MP_HOUSE));
assert(!IsTileType(tile, MP_INDUSTRY));
SB(tile.m1(), 0, 5, owner);
}
/**
* Checks if a tile belongs to the given owner
*

View File

@ -16,6 +16,7 @@
#include "subsidy_type.h"
#include "newgrf_storage.h"
#include "cargotype.h"
#include <cstdint>
template <typename T>
struct BuildingCounts {
@ -68,9 +69,11 @@ struct Town : TownPool::PoolItem<&_town_pool> {
uint16_t noise_reached; ///< level of noise that all the airports are generating
CompanyMask statues; ///< which companies have a statue?
uint16_t old_statues;
/* Company ratings. */
CompanyMask have_ratings; ///< which companies have a rating
uint16_t old_have_ratings;
uint8_t unwanted[MAX_COMPANIES]; ///< how many months companies aren't wanted by towns (bribe)
CompanyID exclusivity; ///< which company has exclusivity
uint8_t exclusive_counter; ///< months till the exclusivity expires

View File

@ -7,6 +7,7 @@
/** @file vehiclelist.cpp Lists of vehicles. */
#include "cargomonitor.h"
#include "stdafx.h"
#include "train.h"
#include "vehicle_func.h"
@ -23,7 +24,6 @@
uint32_t VehicleListIdentifier::Pack() const
{
uint8_t c = this->company == OWNER_NONE ? 0xF : (uint8_t)this->company;
assert(c < (1 << 4));
assert(this->vtype < (1 << 2));
assert(this->index < (1 << 20));
assert(this->type < VLT_END);

View File

@ -27,6 +27,8 @@ inline void MakeVoid(Tile t)
t.m5() = 0;
t.m6() = 0;
t.m7() = 0;
t.m8() = 0;
t.m9() = 0;
}
#endif /* VOID_MAP_H */