mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-10-31 15:20:10 +00:00
Merge branch 'master' into jgrpp
# Conflicts: # src/3rdparty/fmt/core.h # src/command_type.h # src/console_cmds.cpp # src/core/overflowsafe_type.hpp # src/landscape.cpp # src/network/network.cpp # src/newgrf_object.h # src/object_cmd.cpp # src/order_gui.cpp # src/saveload/vehicle_sl.cpp # src/script/api/script_industrytype.cpp # src/script/api/script_object.hpp # src/script/api/script_town.cpp # src/table/object_land.h # src/timetable_cmd.cpp # src/tree_cmd.cpp # src/vehicle_gui.cpp # src/window.cpp
This commit is contained in:
commit
1bfd96c7f2
10
.github/codeql/codeql-config.yml
vendored
Normal file
10
.github/codeql/codeql-config.yml
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
name: openttd
|
||||
queries:
|
||||
- uses: security-and-quality
|
||||
query-filters:
|
||||
- exclude:
|
||||
id:
|
||||
# Only feasible way is to move away from fopen; fopen_s is optional C11 and not implemented on most platforms.
|
||||
- cpp/world-writable-file-creation
|
||||
# Basically OpenTTD's coding style for adding things like ..._INVALID to enumerations
|
||||
- cpp/irregular-enum-init
|
78
.github/workflows/codeql.yml
vendored
Normal file
78
.github/workflows/codeql.yml
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
name: CodeQL
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
echo "::group::Update apt"
|
||||
sudo apt-get update
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Install dependencies"
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
liballegro4-dev \
|
||||
libfontconfig-dev \
|
||||
libicu-dev \
|
||||
liblzma-dev \
|
||||
liblzo2-dev \
|
||||
libsdl2-dev \
|
||||
zlib1g-dev \
|
||||
# EOF
|
||||
echo "::endgroup::"
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
- name: Set number of make jobs
|
||||
run: |
|
||||
echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: cpp
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: /language:cpp
|
||||
upload: False
|
||||
output: sarif-results
|
||||
|
||||
- name: Filter out table & generated code
|
||||
uses: advanced-security/filter-sarif@v1
|
||||
with:
|
||||
patterns: |
|
||||
+**/*.*
|
||||
-**/table/*.*
|
||||
-**/generated/**/*.*
|
||||
input: sarif-results/cpp.sarif
|
||||
output: sarif-results/cpp.sarif
|
||||
|
||||
- name: Upload results
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: sarif-results/cpp.sarif
|
@ -88,24 +88,24 @@
|
||||
abs( 21): 21
|
||||
|
||||
--AIBase--
|
||||
Rand(): -54346916
|
||||
Rand(): -937374575
|
||||
Rand(): 823953997
|
||||
Rand(): -2062310602
|
||||
Rand(): -1780331126
|
||||
Rand(): -397928569
|
||||
RandRange(0): 0
|
||||
RandRange(0): 0
|
||||
RandRange(0): 0
|
||||
RandRange(1): 0
|
||||
RandRange(1): 0
|
||||
RandRange(1): 0
|
||||
RandRange(2): 1
|
||||
RandRange(2): 1
|
||||
RandRange(2): 1
|
||||
RandRange(1000000): 966676
|
||||
RandRange(1000000): 289525
|
||||
RandRange(1000000): 170283
|
||||
Chance(1, 2): false
|
||||
RandRange(2): 0
|
||||
RandRange(2): 0
|
||||
RandRange(2): 0
|
||||
RandRange(1000000): 666804
|
||||
RandRange(1000000): 624059
|
||||
RandRange(1000000): 697029
|
||||
Chance(1, 2): true
|
||||
Chance(1, 2): false
|
||||
Chance(1, 2): true
|
||||
|
||||
--List--
|
||||
IsEmpty(): true
|
||||
@ -420,144 +420,144 @@
|
||||
1098 => 46116
|
||||
1099 => 46158
|
||||
Randomize ListDump:
|
||||
1 => -200078348
|
||||
2 => -29799264
|
||||
1000 => 1630721656
|
||||
1001 => 959306175
|
||||
1002 => 1527421791
|
||||
1003 => 1259692483
|
||||
1004 => -1289244298
|
||||
1005 => -1572996668
|
||||
1006 => -2069479746
|
||||
1007 => -1819131606
|
||||
1008 => -1007163964
|
||||
1009 => -1185394870
|
||||
1010 => -1471365065
|
||||
1011 => 364354366
|
||||
1012 => -1478084253
|
||||
1013 => 405281367
|
||||
1014 => -11170062
|
||||
1015 => 156767750
|
||||
1016 => 1288924796
|
||||
1017 => 1796884876
|
||||
1018 => -1947073702
|
||||
1019 => -1999614238
|
||||
1020 => -231292809
|
||||
1021 => 966621566
|
||||
1022 => -606766557
|
||||
1023 => -1138727825
|
||||
1024 => -749544262
|
||||
1025 => 2004771271
|
||||
1026 => 686734186
|
||||
1027 => 923274744
|
||||
1028 => -1672035149
|
||||
1029 => -1642064950
|
||||
1030 => 1363389551
|
||||
1031 => -559500928
|
||||
1032 => 1656196991
|
||||
1033 => 1655354425
|
||||
1034 => -1027156689
|
||||
1035 => 1952644328
|
||||
1036 => 1217870217
|
||||
1037 => 242274100
|
||||
1038 => 201816080
|
||||
1039 => 2127464758
|
||||
1040 => 446043650
|
||||
1041 => -319728455
|
||||
1042 => 204701002
|
||||
1043 => -571265398
|
||||
1044 => -1422217131
|
||||
1045 => -391208397
|
||||
1046 => -1822628371
|
||||
1047 => -1499755350
|
||||
1048 => -1422137641
|
||||
1049 => 1621693134
|
||||
1051 => -1428728134
|
||||
1052 => -147587573
|
||||
1053 => 681719500
|
||||
1054 => 1172011190
|
||||
1055 => -1834344882
|
||||
1056 => 1157634586
|
||||
1057 => 1902133676
|
||||
1058 => -1967780161
|
||||
1059 => -1618025531
|
||||
1060 => -810220453
|
||||
1061 => 1582854921
|
||||
1062 => -410004643
|
||||
1063 => 1159917159
|
||||
1064 => -1377804984
|
||||
1065 => -738843914
|
||||
1066 => -1578756103
|
||||
1067 => -464090986
|
||||
1068 => 1711504679
|
||||
1069 => 545330655
|
||||
1070 => 379462570
|
||||
1071 => 514511099
|
||||
1072 => -1813251176
|
||||
1073 => 1424958266
|
||||
1074 => -825255131
|
||||
1075 => 539054595
|
||||
1076 => -1764192010
|
||||
1077 => -1243277769
|
||||
1078 => 2017874281
|
||||
1079 => -1972353607
|
||||
1080 => 1879761467
|
||||
1081 => 1638986560
|
||||
1082 => -1832287507
|
||||
1083 => -492411882
|
||||
1084 => 658940812
|
||||
1085 => -1044199400
|
||||
1086 => 1586504918
|
||||
1087 => -125492611
|
||||
1088 => -1562883174
|
||||
1089 => -1013778441
|
||||
1090 => 1560228607
|
||||
1091 => -550265689
|
||||
1092 => 524767105
|
||||
1093 => -713387661
|
||||
1094 => 1425927738
|
||||
1095 => 942653932
|
||||
1096 => 1233220698
|
||||
1097 => 1313602368
|
||||
1098 => -140318584
|
||||
1099 => 1199179892
|
||||
1 => 688298322
|
||||
2 => -1709546982
|
||||
1000 => 1701392078
|
||||
1001 => -1630848421
|
||||
1002 => -886500935
|
||||
1003 => -196324972
|
||||
1004 => -436037402
|
||||
1005 => -520341784
|
||||
1006 => -1485224804
|
||||
1007 => -311036236
|
||||
1008 => -1503442439
|
||||
1009 => -110945695
|
||||
1010 => -82825175
|
||||
1011 => 46859773
|
||||
1012 => -1199223018
|
||||
1013 => -1190555925
|
||||
1014 => 326384434
|
||||
1015 => 1486817960
|
||||
1016 => -1411425597
|
||||
1017 => -508426854
|
||||
1018 => 820019294
|
||||
1019 => 710762995
|
||||
1020 => -760867032
|
||||
1021 => -709611146
|
||||
1022 => 732190215
|
||||
1023 => 236336673
|
||||
1024 => 740596257
|
||||
1025 => 1135321785
|
||||
1026 => 2067474156
|
||||
1027 => -1395683607
|
||||
1028 => -240528699
|
||||
1029 => 928616892
|
||||
1030 => 1712486685
|
||||
1031 => 1994118287
|
||||
1032 => 1333321243
|
||||
1033 => 194124284
|
||||
1034 => 615083294
|
||||
1035 => 628086450
|
||||
1036 => 498957825
|
||||
1037 => 1359697121
|
||||
1038 => 1888433963
|
||||
1039 => 941623020
|
||||
1040 => -1925663292
|
||||
1041 => -771540264
|
||||
1042 => -1058341359
|
||||
1043 => 182127597
|
||||
1044 => 646955927
|
||||
1045 => -1424621714
|
||||
1046 => 623062612
|
||||
1047 => -1986955586
|
||||
1048 => -1268826980
|
||||
1049 => -456776220
|
||||
1051 => -1112555329
|
||||
1052 => -1532134052
|
||||
1053 => 1960404034
|
||||
1054 => 1573325453
|
||||
1055 => -316619303
|
||||
1056 => 699712177
|
||||
1057 => 863274966
|
||||
1058 => 1728276475
|
||||
1059 => -246695889
|
||||
1060 => 1919485436
|
||||
1061 => 111273464
|
||||
1062 => 125435213
|
||||
1063 => 155132602
|
||||
1064 => -171674076
|
||||
1065 => 655046914
|
||||
1066 => 1577399562
|
||||
1067 => 1028818150
|
||||
1068 => 447058239
|
||||
1069 => -1057920269
|
||||
1070 => -1326215323
|
||||
1071 => -198688588
|
||||
1072 => 1523643051
|
||||
1073 => 231373233
|
||||
1074 => 1121759962
|
||||
1075 => 1449439846
|
||||
1076 => -1615270753
|
||||
1077 => -1509293864
|
||||
1078 => 2116903943
|
||||
1079 => 672822173
|
||||
1080 => -969573911
|
||||
1081 => 1589904755
|
||||
1082 => 1148782015
|
||||
1083 => 663503316
|
||||
1084 => 933352745
|
||||
1085 => 577717039
|
||||
1086 => 402172048
|
||||
1087 => 1812250453
|
||||
1088 => 667300501
|
||||
1089 => -1838825777
|
||||
1090 => -856474776
|
||||
1091 => 420696035
|
||||
1092 => 2131427774
|
||||
1093 => -435303548
|
||||
1094 => -160883878
|
||||
1095 => 1969629634
|
||||
1096 => -555794155
|
||||
1097 => -835119691
|
||||
1098 => -1460907909
|
||||
1099 => -1146924084
|
||||
KeepTop(10):
|
||||
1 => -200078348
|
||||
2 => -29799264
|
||||
1000 => 1630721656
|
||||
1001 => 959306175
|
||||
1002 => 1527421791
|
||||
1003 => 1259692483
|
||||
1004 => -1289244298
|
||||
1005 => -1572996668
|
||||
1006 => -2069479746
|
||||
1007 => -1819131606
|
||||
1 => 688298322
|
||||
2 => -1709546982
|
||||
1000 => 1701392078
|
||||
1001 => -1630848421
|
||||
1002 => -886500935
|
||||
1003 => -196324972
|
||||
1004 => -436037402
|
||||
1005 => -520341784
|
||||
1006 => -1485224804
|
||||
1007 => -311036236
|
||||
KeepBottom(8):
|
||||
1000 => 1630721656
|
||||
1001 => 959306175
|
||||
1002 => 1527421791
|
||||
1003 => 1259692483
|
||||
1004 => -1289244298
|
||||
1005 => -1572996668
|
||||
1006 => -2069479746
|
||||
1007 => -1819131606
|
||||
1000 => 1701392078
|
||||
1001 => -1630848421
|
||||
1002 => -886500935
|
||||
1003 => -196324972
|
||||
1004 => -436037402
|
||||
1005 => -520341784
|
||||
1006 => -1485224804
|
||||
1007 => -311036236
|
||||
RemoveBottom(2):
|
||||
1000 => 1630721656
|
||||
1001 => 959306175
|
||||
1002 => 1527421791
|
||||
1003 => 1259692483
|
||||
1004 => -1289244298
|
||||
1005 => -1572996668
|
||||
1000 => 1701392078
|
||||
1001 => -1630848421
|
||||
1002 => -886500935
|
||||
1003 => -196324972
|
||||
1004 => -436037402
|
||||
1005 => -520341784
|
||||
RemoveTop(2):
|
||||
1002 => 1527421791
|
||||
1003 => 1259692483
|
||||
1004 => -1289244298
|
||||
1005 => -1572996668
|
||||
1002 => -886500935
|
||||
1003 => -196324972
|
||||
1004 => -436037402
|
||||
1005 => -520341784
|
||||
RemoveList({1003, 1004}):
|
||||
1002 => 1527421791
|
||||
1005 => -1572996668
|
||||
1002 => -886500935
|
||||
1005 => -520341784
|
||||
KeepList({1003, 1004, 1005}):
|
||||
1005 => -1572996668
|
||||
1005 => -520341784
|
||||
AddList({1005, 4000, 4001, 4002}):
|
||||
1005 => 1005
|
||||
4000 => 8000
|
||||
|
1
src/3rdparty/squirrel/squirrel/sqclass.h
vendored
1
src/3rdparty/squirrel/squirrel/sqclass.h
vendored
@ -10,6 +10,7 @@ struct SQClassMember {
|
||||
val = o.val;
|
||||
attrs = o.attrs;
|
||||
}
|
||||
SQClassMember& operator=(SQClassMember &o) = delete;
|
||||
SQObjectPtr val;
|
||||
SQObjectPtr attrs;
|
||||
};
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "../core/random_func.hpp"
|
||||
|
||||
#include "../script/squirrel_class.hpp"
|
||||
#include "../script/api/script_object.hpp"
|
||||
#include "ai_info.hpp"
|
||||
#include "ai_scanner.hpp"
|
||||
|
||||
@ -77,12 +78,7 @@ AIInfo *AIScannerInfo::SelectRandomAI() const
|
||||
}
|
||||
|
||||
/* Find a random AI */
|
||||
uint pos;
|
||||
if (_networking) {
|
||||
pos = InteractiveRandomRange(num_random_ais);
|
||||
} else {
|
||||
pos = RandomRange(num_random_ais);
|
||||
}
|
||||
uint pos = ScriptObject::GetRandomizer(OWNER_NONE).Next(num_random_ais);
|
||||
|
||||
/* Find the Nth item from the array */
|
||||
ScriptInfoList::const_iterator it = this->info_single_list.begin();
|
||||
|
@ -1068,6 +1068,7 @@ static uint ShowAdditionalText(int left, int right, int y, EngineID engine)
|
||||
uint16 callback = GetVehicleCallback(CBID_VEHICLE_ADDITIONAL_TEXT, 0, 0, engine, nullptr);
|
||||
if (callback == CALLBACK_FAILED || callback == 0x400) return y;
|
||||
const GRFFile *grffile = Engine::Get(engine)->GetGRF();
|
||||
assert(grffile != nullptr);
|
||||
if (callback > 0x400) {
|
||||
ErrorUnknownCallbackResult(grffile->grfid, CBID_VEHICLE_ADDITIONAL_TEXT, callback);
|
||||
return y;
|
||||
|
@ -596,7 +596,7 @@ Company *DoStartupNewCompany(DoStartupNewCompanyFlag flags, CompanyID company)
|
||||
if (_company_manager_face != 0 && !is_ai && !_networking) {
|
||||
c->face = _company_manager_face;
|
||||
} else {
|
||||
RandomCompanyManagerFaceBits(c->face, (GenderEthnicity)Random(), false, false);
|
||||
RandomCompanyManagerFaceBits(c->face, (GenderEthnicity)Random(), false, _random);
|
||||
}
|
||||
|
||||
SetDefaultCompanySettings(c->index);
|
||||
|
@ -1751,7 +1751,7 @@ public:
|
||||
|
||||
/* Randomize face button */
|
||||
case WID_SCMF_RANDOM_NEW_FACE:
|
||||
RandomCompanyManagerFaceBits(this->face, this->ge, this->advanced);
|
||||
RandomCompanyManagerFaceBits(this->face, this->ge, this->advanced, _interactive_random);
|
||||
this->UpdateData();
|
||||
this->SetDirty();
|
||||
break;
|
||||
|
@ -199,15 +199,13 @@ static inline void ScaleAllCompanyManagerFaceBits(CompanyManagerFace &cmf)
|
||||
* @param cmf the company manager's face to write the bits to
|
||||
* @param ge the gender and ethnicity of the old company manager's face
|
||||
* @param adv if it for the advanced company manager's face window
|
||||
* @param interactive is the call from within the user interface?
|
||||
* @param randomizer the source of random to use for creating the manager face
|
||||
*
|
||||
* @pre scale 'ge' to a valid gender/ethnicity combination
|
||||
*/
|
||||
static inline void RandomCompanyManagerFaceBits(CompanyManagerFace &cmf, GenderEthnicity ge, bool adv, bool interactive = true)
|
||||
static inline void RandomCompanyManagerFaceBits(CompanyManagerFace &cmf, GenderEthnicity ge, bool adv, Randomizer &randomizer)
|
||||
{
|
||||
/* This method is called from a command when not interactive and
|
||||
* then we must use Random to get the same result on all clients. */
|
||||
cmf = interactive ? InteractiveRandom() : Random(); // random all company manager's face bits
|
||||
cmf = randomizer.Next(); // random all company manager's face bits
|
||||
|
||||
/* scale ge: 0 == GE_WM, 1 == GE_WF, 2 == GE_BM, 3 == GE_BF (and maybe in future: ...) */
|
||||
ge = (GenderEthnicity)((uint)ge % GE_END);
|
||||
|
@ -313,7 +313,11 @@ DEF_CONSOLE_CMD(ConZoomToLevel)
|
||||
case 2: {
|
||||
uint32 level;
|
||||
if (GetArgumentInteger(&level, argv[1])) {
|
||||
if (level < ZOOM_LVL_MIN) {
|
||||
/* In case ZOOM_LVL_MIN is more than 0, the next if statement needs to be amended.
|
||||
* A simple check for less than ZOOM_LVL_MIN does not work here because we are
|
||||
* reading an unsigned integer from the console, so just check for a '-' char. */
|
||||
static_assert(ZOOM_LVL_MIN == 0);
|
||||
if (argv[1][0] == '-') {
|
||||
IConsolePrintF(CC_ERROR, "Zoom-in levels below %u are not supported.", ZOOM_LVL_MIN);
|
||||
} else if (level < _settings_client.gui.zoom_min) {
|
||||
IConsolePrintF(CC_ERROR, "Current client settings do not allow zooming in below level %u.", _settings_client.gui.zoom_min);
|
||||
@ -322,7 +326,7 @@ DEF_CONSOLE_CMD(ConZoomToLevel)
|
||||
} else if (level > _settings_client.gui.zoom_max) {
|
||||
IConsolePrintF(CC_ERROR, "Current client settings do not allow zooming out beyond level %u.", _settings_client.gui.zoom_max);
|
||||
} else {
|
||||
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
Window *w = GetMainWindow();
|
||||
Viewport *vp = w->viewport;
|
||||
while (vp->zoom > level) DoZoomInOutWindow(ZOOM_IN, w);
|
||||
while (vp->zoom < level) DoZoomInOutWindow(ZOOM_OUT, w);
|
||||
@ -529,7 +533,7 @@ DEF_CONSOLE_CMD(ConRemove)
|
||||
_console_file_list.ValidateFileList();
|
||||
const FiosItem *item = _console_file_list.FindItem(file);
|
||||
if (item != nullptr) {
|
||||
if (!FiosDelete(item->name)) {
|
||||
if (unlink(item->name) != 0) {
|
||||
IConsolePrintF(CC_ERROR, "%s: Failed to delete file", file);
|
||||
}
|
||||
} else {
|
||||
@ -1031,6 +1035,7 @@ DEF_CONSOLE_CMD(ConResetCompany)
|
||||
return false;
|
||||
}
|
||||
const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
|
||||
assert(ci != nullptr);
|
||||
if (ci->client_playas == index) {
|
||||
IConsoleError("Cannot remove company: the server is connected to that company.");
|
||||
return true;
|
||||
@ -2240,18 +2245,15 @@ DEF_CONSOLE_CMD(ConFont)
|
||||
bool aa = setting->aa;
|
||||
|
||||
byte arg_index = 2;
|
||||
|
||||
if (argc > arg_index) {
|
||||
/* We may encounter "aa" or "noaa" but it must be the last argument. */
|
||||
if (strcasecmp(argv[arg_index], "aa") == 0 || strcasecmp(argv[arg_index], "noaa") == 0) {
|
||||
aa = strncasecmp(argv[arg_index++], "no", 2) != 0;
|
||||
if (argc > arg_index) return false;
|
||||
} else {
|
||||
/* For <name> we want a string. */
|
||||
uint v;
|
||||
if (!GetArgumentInteger(&v, argv[arg_index])) {
|
||||
font = argv[arg_index++];
|
||||
}
|
||||
/* We may encounter "aa" or "noaa" but it must be the last argument. */
|
||||
if (strcasecmp(argv[arg_index], "aa") == 0 || strcasecmp(argv[arg_index], "noaa") == 0) {
|
||||
aa = strncasecmp(argv[arg_index++], "no", 2) != 0;
|
||||
if (argc > arg_index) return false;
|
||||
} else {
|
||||
/* For <name> we want a string. */
|
||||
uint v;
|
||||
if (!GetArgumentInteger(&v, argv[arg_index])) {
|
||||
font = argv[arg_index++];
|
||||
}
|
||||
}
|
||||
|
||||
@ -2282,7 +2284,7 @@ DEF_CONSOLE_CMD(ConFont)
|
||||
InitFontCache(fs == FS_MONO);
|
||||
fc = FontCache::Get(fs);
|
||||
}
|
||||
IConsolePrintF(CC_DEFAULT, "%s: \"%s\" %d %s [\"%s\" %d %s]", FontSizeToName(fs), fc->GetFontName(), fc->GetFontSize(), GetFontAAState(fs) ? "true" : "false", setting->font.c_str(), setting->size, setting->aa ? "true" : "false");
|
||||
IConsolePrintF(CC_DEFAULT, "%s: \"%s\" %d %s [\"%s\" %d %s]", FontSizeToName(fs), fc->GetFontName(), fc->GetFontSize(), GetFontAAState(fs) ? "aa" : "noaa", setting->font.c_str(), setting->size, setting->aa ? "aa" : "noaa");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -172,7 +172,10 @@ public:
|
||||
inline constexpr bool operator < (const int other) const { return !(*this >= other); }
|
||||
inline constexpr bool operator <= (const int other) const { return !(*this > other); }
|
||||
|
||||
inline constexpr operator int64 () const { return this->m_value; }
|
||||
inline constexpr operator T () const { return this->m_value; }
|
||||
|
||||
static inline constexpr OverflowSafeInt<T> max() { return T_MAX; }
|
||||
static inline constexpr OverflowSafeInt<T> min() { return T_MIN; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -239,7 +239,7 @@ public:
|
||||
int scr_bot = GetMainViewBottom() - 20;
|
||||
|
||||
Point pt = RemapCoords(this->position.x, this->position.y, GetSlopePixelZOutsideMap(this->position.x, this->position.y));
|
||||
const Viewport *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
|
||||
const Viewport *vp = GetMainWindow()->viewport;
|
||||
if (this->face == INVALID_COMPANY) {
|
||||
/* move x pos to opposite corner */
|
||||
pt.x = UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left;
|
||||
|
@ -225,6 +225,7 @@ public:
|
||||
GameStrings *LoadTranslations()
|
||||
{
|
||||
const GameInfo *info = Game::GetInfo();
|
||||
assert(info != nullptr);
|
||||
std::string basename(info->GetMainScript());
|
||||
auto e = basename.rfind(PATHSEPCHAR);
|
||||
if (e == std::string::npos) return nullptr;
|
||||
|
@ -104,6 +104,7 @@ static void _GenerateWorld()
|
||||
|
||||
SetGeneratingWorldProgress(GWP_MAP_INIT, 2);
|
||||
SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
|
||||
ScriptObject::InitializeRandomizers();
|
||||
|
||||
BasePersistentStorageArray::SwitchMode(PSM_ENTER_GAMELOOP);
|
||||
|
||||
@ -337,9 +338,7 @@ void GenerateWorld(GenWorldMode mode, uint size_x, uint size_y, bool reset_setti
|
||||
ShowGenerateWorldProgress();
|
||||
|
||||
/* Centre the view on the map */
|
||||
if (FindWindowById(WC_MAIN_WINDOW, 0) != nullptr) {
|
||||
ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / 2), true);
|
||||
}
|
||||
ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / 2), true);
|
||||
|
||||
_GenerateWorld();
|
||||
}
|
||||
|
@ -552,8 +552,6 @@ std::unique_ptr<const ParagraphLayouter::Line> FallbackParagraphLayout::NextLine
|
||||
|
||||
next_run = this->buffer_begin + iter->first;
|
||||
begin = this->buffer;
|
||||
|
||||
last_space = nullptr;
|
||||
}
|
||||
|
||||
if (IsWhitespace(c)) last_space = this->buffer;
|
||||
@ -591,7 +589,7 @@ std::unique_ptr<const ParagraphLayouter::Line> FallbackParagraphLayout::NextLine
|
||||
this->buffer++;
|
||||
}
|
||||
|
||||
if (l->size() == 0 || last_char - begin != 0) {
|
||||
if (l->size() == 0 || last_char - begin > 0) {
|
||||
int w = l->GetWidth();
|
||||
l->emplace_back(iter->second, begin, last_char - begin, w);
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ struct SelectGameWindow : public Window {
|
||||
}
|
||||
|
||||
IntroGameViewportCommand &vc = intro_viewport_commands[this->cur_viewport_command_index];
|
||||
Window *mw = FindWindowByClass(WC_MAIN_WINDOW);
|
||||
Window *mw = GetMainWindow();
|
||||
Viewport *vp = mw->viewport;
|
||||
|
||||
/* Early exit if the current command hasn't elapsed and isn't animated. */
|
||||
|
@ -2076,6 +2076,7 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Vise tav
|
||||
STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Vis innstillinger
|
||||
STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Vis NewGRF-instillinger
|
||||
STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Se etter nytt og oppdatert innhold for nedlasting
|
||||
STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Vis KI innstillinger
|
||||
STR_INTRO_TOOLTIP_QUIT :{BLACK}Avslutt 'OpenTTD'
|
||||
|
||||
STR_INTRO_BASESET :{BLACK}Det valgte innebygde grafikksettet mangler {NUM} sprite{P "" r}. Se etter oppdateringer for settet.
|
||||
|
@ -721,7 +721,7 @@ LinkGraphLegendWindow::LinkGraphLegendWindow(WindowDesc *desc, int window_number
|
||||
{
|
||||
this->InitNested(window_number);
|
||||
this->InvalidateData(0);
|
||||
this->SetOverlay(FindWindowById(WC_MAIN_WINDOW, 0)->viewport->overlay);
|
||||
this->SetOverlay(GetMainWindow()->viewport->overlay);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -182,7 +182,7 @@ void FixTitleGameZoom(int zoom_adjust)
|
||||
{
|
||||
if (_game_mode != GM_MENU) return;
|
||||
|
||||
Viewport *vp = FindWindowByClass(WC_MAIN_WINDOW)->viewport;
|
||||
Viewport *vp = GetMainWindow()->viewport;
|
||||
|
||||
/* Adjust the zoom in/out.
|
||||
* Can't simply add, since operator+ is not defined on the ZoomLevel type. */
|
||||
|
@ -67,8 +67,10 @@ CommandCost CmdIncreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
|
||||
break;
|
||||
}
|
||||
|
||||
/* Overflow protection */
|
||||
if (c->money + c->current_loan + loan < c->money) return CMD_ERROR;
|
||||
/* In case adding the loan triggers the overflow protection of Money,
|
||||
* we would essentially be losing money as taking and repaying the loan
|
||||
* immediately would not get us back to the same bank balance anymore. */
|
||||
if (c->money > Money::max() - loan) return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
c->money += loan;
|
||||
|
@ -1340,7 +1340,7 @@ static WindowDesc _query_desc(
|
||||
*/
|
||||
void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallbackProc *callback)
|
||||
{
|
||||
if (parent == nullptr) parent = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
if (parent == nullptr) parent = GetMainWindow();
|
||||
|
||||
for (const Window *w : Window::IterateFromBack()) {
|
||||
if (w->window_class != WC_CONFIRM_POPUP_QUERY) continue;
|
||||
|
@ -358,14 +358,14 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfo
|
||||
}
|
||||
|
||||
case 4: {
|
||||
GRFConfig **dst = &info->grfconfig;
|
||||
uint i;
|
||||
/* Ensure that the maximum number of NewGRFs and the field in the network
|
||||
* protocol are matched to eachother. If that is not the case anymore a
|
||||
* check must be added to ensure the received data is still valid. */
|
||||
static_assert(std::numeric_limits<uint8>::max() == NETWORK_MAX_GRF_COUNT);
|
||||
uint num_grfs = p->Recv_uint8();
|
||||
|
||||
/* Broken/bad data. It cannot have that many NewGRFs. */
|
||||
if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
|
||||
|
||||
for (i = 0; i < num_grfs; i++) {
|
||||
GRFConfig **dst = &info->grfconfig;
|
||||
for (uint i = 0; i < num_grfs; i++) {
|
||||
NamedGRFIdentifier grf;
|
||||
switch (newgrf_serialisation) {
|
||||
case NST_GRFID_MD5:
|
||||
|
@ -649,6 +649,7 @@ void NetworkClose(bool close_admins)
|
||||
delete[] _network_company_states;
|
||||
_network_company_states = nullptr;
|
||||
_network_company_server_id.clear();
|
||||
_network_company_passworded = 0;
|
||||
|
||||
InitializeNetworkPools(close_admins);
|
||||
|
||||
|
@ -2531,6 +2531,6 @@ void ShowNetworkAskRelay(const std::string &server_connection_string, const std:
|
||||
{
|
||||
DeleteWindowByClass(WC_NETWORK_ASK_RELAY);
|
||||
|
||||
Window *parent = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
Window *parent = GetMainWindow();
|
||||
new NetworkAskRelayWindow(&_network_ask_relay_desc, parent, server_connection_string, relay_connection_string, token);
|
||||
}
|
||||
|
@ -1744,6 +1744,7 @@ static void NetworkAutoCleanCompanies()
|
||||
|
||||
if (!_network_dedicated) {
|
||||
const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
|
||||
assert(ci != nullptr);
|
||||
if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true;
|
||||
}
|
||||
|
||||
@ -2135,6 +2136,7 @@ void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
|
||||
if (client_id == CLIENT_ID_SERVER && _network_dedicated) return;
|
||||
|
||||
NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
|
||||
assert(ci != nullptr);
|
||||
|
||||
/* No need to waste network resources if the client is in the company already! */
|
||||
if (ci->client_playas == company_id) return;
|
||||
|
@ -4306,7 +4306,6 @@ static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, const G
|
||||
/* Swap classid because we read it in BE. */
|
||||
uint32 classid = buf->ReadDWord();
|
||||
(*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
|
||||
(*ospec)->enabled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -10857,7 +10856,7 @@ static void FinaliseObjectsArray()
|
||||
ObjectSpec **&objectspec = file->objectspec;
|
||||
if (objectspec != nullptr) {
|
||||
for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
|
||||
if (objectspec[i] != nullptr && objectspec[i]->grf_prop.grffile != nullptr && objectspec[i]->enabled) {
|
||||
if (objectspec[i] != nullptr && objectspec[i]->grf_prop.grffile != nullptr && objectspec[i]->IsEnabled()) {
|
||||
_object_mngr.SetEntitySpec(objectspec[i]);
|
||||
}
|
||||
}
|
||||
|
@ -658,6 +658,7 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object,
|
||||
|
||||
{
|
||||
const Vehicle *w = v->Next();
|
||||
assert(w != nullptr);
|
||||
uint16 altitude = ClampToU16(v->z_pos - w->z_pos); // Aircraft height - shadow height
|
||||
byte airporttype = ATP_TTDP_LARGE;
|
||||
|
||||
|
@ -1468,6 +1468,9 @@ private:
|
||||
this->avails.push_back(c);
|
||||
} else {
|
||||
const GRFConfig *best = FindGRFConfig(c->ident.grfid, HasBit(c->flags, GCF_INVALID) ? FGCM_NEWEST : FGCM_NEWEST_VALID);
|
||||
/* Never triggers; FindGRFConfig returns either c, or a newer version of c. */
|
||||
assert(best != nullptr);
|
||||
|
||||
/*
|
||||
* If the best version is 0, then all NewGRF with this GRF ID
|
||||
* have version 0, so for backward compatibility reasons we
|
||||
|
@ -60,7 +60,7 @@ ObjectSpec _object_specs[NUM_OBJECTS];
|
||||
*/
|
||||
bool ObjectSpec::IsEverAvailable() const
|
||||
{
|
||||
return this->enabled && HasBit(this->climate, _settings_game.game_creation.landscape) &&
|
||||
return this->IsEnabled() && HasBit(this->climate, _settings_game.game_creation.landscape) &&
|
||||
(this->flags & ((_game_mode != GM_EDITOR && !_generating_world) ? OBJECT_FLAG_ONLY_IN_SCENEDIT : OBJECT_FLAG_ONLY_IN_GAME)) == 0;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "newgrf_commons.h"
|
||||
|
||||
/** Various object behaviours. */
|
||||
enum ObjectFlags {
|
||||
enum ObjectFlags : uint16 {
|
||||
OBJECT_FLAG_NONE = 0, ///< Just nothing.
|
||||
OBJECT_FLAG_ONLY_IN_SCENEDIT = 1 << 0, ///< Object can only be constructed in the scenario editor.
|
||||
OBJECT_FLAG_CANNOT_REMOVE = 1 << 1, ///< Object can not be removed.
|
||||
@ -62,7 +62,7 @@ static const uint8 OBJECT_SIZE_1X1 = 0x11; ///< The value of a NewGRF's size pro
|
||||
void ResetObjects();
|
||||
|
||||
/** Class IDs for objects. */
|
||||
enum ObjectClassID {
|
||||
enum ObjectClassID : uint16 {
|
||||
OBJECT_CLASS_BEGIN = 0, ///< The lowest valid value
|
||||
OBJECT_CLASS_MAX = 0xFFFF, ///< Maximum number of classes.
|
||||
INVALID_OBJECT_CLASS = 0xFFFF, ///< Class for the less fortunate.
|
||||
@ -91,6 +91,7 @@ enum ObjectViewportMapType {
|
||||
struct ObjectSpec {
|
||||
/* 2 because of the "normal" and "buy" sprite stacks. */
|
||||
GRFFilePropsBase<2> grf_prop; ///< Properties related the the grf file
|
||||
AnimationInfo animation; ///< Information about the animation.
|
||||
ObjectClassID cls_id; ///< The class to which this spec belongs.
|
||||
StringID name; ///< The name for this object.
|
||||
|
||||
@ -103,15 +104,19 @@ struct ObjectSpec {
|
||||
ObjectFlags flags; ///< Flags/settings related to the object.
|
||||
ObjectCtrlFlags ctrl_flags; ///< Extra control flags.
|
||||
uint8 edge_foundation[4]; ///< Edge foundation flags
|
||||
AnimationInfo animation; ///< Information about the animation.
|
||||
uint16 callback_mask; ///< Bitmask of requested/allowed callbacks.
|
||||
uint8 height; ///< The height of this structure, in heightlevels; max MAX_TILE_HEIGHT.
|
||||
uint8 views; ///< The number of views.
|
||||
uint8 generate_amount; ///< Number of objects which are attempted to be generated per 256^2 map during world generation.
|
||||
bool enabled; ///< Is this spec enabled?
|
||||
ObjectViewportMapType vport_map_type; ///< Viewport map type
|
||||
uint16 vport_map_subtype; ///< Viewport map subtype
|
||||
|
||||
/**
|
||||
* Test if this object is enabled.
|
||||
* @return True iif this object is enabled.
|
||||
*/
|
||||
bool IsEnabled() const { return this->views > 0; }
|
||||
|
||||
/**
|
||||
* Get the cost for building a structure of this type.
|
||||
* @return The cost for building.
|
||||
|
@ -578,7 +578,7 @@ static void DrawTile_Object(TileInfo *ti, DrawTileProcParams params)
|
||||
int building_z_offset = 0;
|
||||
|
||||
/* Fall back for when the object doesn't exist anymore. */
|
||||
if (!spec->enabled) {
|
||||
if (!spec->IsEnabled()) {
|
||||
type = OBJECT_TRANSMITTER;
|
||||
} else if ((spec->flags & OBJECT_FLAG_HAS_NO_FOUNDATION) == 0) {
|
||||
if (spec->ctrl_flags & OBJECT_CTRL_FLAG_EDGE_FOUNDATION) {
|
||||
@ -1222,7 +1222,7 @@ static CommandCost TerraformTile_Object(TileIndex tile, DoCommandFlag flags, int
|
||||
pre_success_checks();
|
||||
return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
|
||||
}
|
||||
} else if (spec->enabled) {
|
||||
} else if (spec->IsEnabled()) {
|
||||
/* allow autoslope */
|
||||
pre_success_checks();
|
||||
return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
|
||||
|
@ -1778,6 +1778,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
if (sel_ord >= v->GetNumOrders()) return CMD_ERROR;
|
||||
|
||||
Order *order = v->GetOrder(sel_ord);
|
||||
assert(order != nullptr);
|
||||
switch (order->GetType()) {
|
||||
case OT_GOTO_STATION:
|
||||
if (mof != MOF_NON_STOP && mof != MOF_STOP_LOCATION && mof != MOF_UNLOAD && mof != MOF_LOAD && mof != MOF_CARGO_TYPE_UNLOAD && mof != MOF_CARGO_TYPE_LOAD && mof != MOF_RV_TRAVEL_DIR) return CMD_ERROR;
|
||||
|
@ -233,46 +233,21 @@ err1:
|
||||
}
|
||||
#endif /* WITH_FREETYPE */
|
||||
|
||||
class FontList {
|
||||
protected:
|
||||
wchar_t **fonts;
|
||||
uint items;
|
||||
uint capacity;
|
||||
|
||||
public:
|
||||
FontList() : fonts(nullptr), items(0), capacity(0) { };
|
||||
|
||||
~FontList() {
|
||||
if (this->fonts == nullptr) return;
|
||||
|
||||
for (uint i = 0; i < this->items; i++) {
|
||||
free(this->fonts[i]);
|
||||
}
|
||||
|
||||
free(this->fonts);
|
||||
}
|
||||
|
||||
bool Add(const wchar_t *font) {
|
||||
for (uint i = 0; i < this->items; i++) {
|
||||
if (wcscmp(this->fonts[i], font) == 0) return false;
|
||||
}
|
||||
|
||||
if (this->items == this->capacity) {
|
||||
this->capacity += 10;
|
||||
this->fonts = ReallocT(this->fonts, this->capacity);
|
||||
}
|
||||
|
||||
this->fonts[this->items++] = wcsdup(font);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct EFCParam {
|
||||
FontCacheSettings *settings;
|
||||
LOCALESIGNATURE locale;
|
||||
MissingGlyphSearcher *callback;
|
||||
FontList fonts;
|
||||
std::vector<std::wstring> fonts;
|
||||
|
||||
bool Add(const std::wstring_view &font) {
|
||||
for (const auto &entry : this->fonts) {
|
||||
if (font.compare(entry) == 0) return false;
|
||||
}
|
||||
|
||||
this->fonts.emplace_back(font);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXTMETRICEX *metric, DWORD type, LPARAM lParam)
|
||||
@ -280,7 +255,7 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT
|
||||
EFCParam *info = (EFCParam *)lParam;
|
||||
|
||||
/* Skip duplicates */
|
||||
if (!info->fonts.Add((const wchar_t *)logfont->elfFullName)) return 1;
|
||||
if (!info->Add(logfont->elfFullName)) return 1;
|
||||
/* Only use TrueType fonts */
|
||||
if (!(type & TRUETYPE_FONTTYPE)) return 1;
|
||||
/* Don't use SYMBOL fonts */
|
||||
@ -463,22 +438,9 @@ void Win32FontCache::ClearFontCache()
|
||||
GLYPHMETRICS gm;
|
||||
MAT2 mat = { {0, 1}, {0, 0}, {0, 0}, {0, 1} };
|
||||
|
||||
/* Make a guess for the needed memory size. */
|
||||
DWORD size = this->glyph_size.cy * Align(aa ? this->glyph_size.cx : std::max(this->glyph_size.cx / 8l, 1l), 4); // Bitmap data is DWORD-aligned rows.
|
||||
byte *bmp = AllocaM(byte, size);
|
||||
size = GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, size, bmp, &mat);
|
||||
|
||||
if (size == GDI_ERROR) {
|
||||
/* No dice with the guess. First query size of needed glyph memory, then allocate the
|
||||
* memory and query again. This dance is necessary as some glyphs will only render with
|
||||
* the exact matching size; e.g. the space glyph has no pixels and must be requested
|
||||
* with size == 0, anything else fails. Unfortunately, a failed call doesn't return any
|
||||
* info about the size and thus the triple GetGlyphOutline()-call. */
|
||||
size = GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, 0, nullptr, &mat);
|
||||
if (size == GDI_ERROR) usererror("Unable to render font glyph");
|
||||
bmp = AllocaM(byte, size);
|
||||
GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, size, bmp, &mat);
|
||||
}
|
||||
/* Call GetGlyphOutline with zero size initially to get required memory size. */
|
||||
DWORD size = GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, 0, nullptr, &mat);
|
||||
if (size == GDI_ERROR) usererror("Unable to render font glyph");
|
||||
|
||||
/* Add 1 scaled pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel. */
|
||||
uint shadow = (this->fs == FS_NORMAL) ? ScaleGUITrad(1) : 0;
|
||||
@ -488,6 +450,10 @@ void Win32FontCache::ClearFontCache()
|
||||
/* Limit glyph size to prevent overflows later on. */
|
||||
if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) usererror("Font glyph is too large");
|
||||
|
||||
/* Call GetGlyphOutline again with size to actually render the glyph. */
|
||||
byte *bmp = AllocaM(byte, size);
|
||||
GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, size, bmp, &mat);
|
||||
|
||||
/* GDI has rendered the glyph, now we allocate a sprite and copy the image into it. */
|
||||
SpriteLoader::Sprite sprite;
|
||||
sprite.AllocateData(ZOOM_LVL_NORMAL, width * height);
|
||||
|
@ -266,6 +266,8 @@ static void InitializeWindowsAndCaches()
|
||||
UpdateAllVirtCoords();
|
||||
ResetViewportAfterLoadGame();
|
||||
|
||||
ScriptObject::InitializeRandomizers();
|
||||
|
||||
for (Company *c : Company::Iterate()) {
|
||||
/* For each company, verify (while loading a scenario) that the inauguration date is the current year and set it
|
||||
* accordingly if it is not the case. No need to set it on companies that are not been used already,
|
||||
|
@ -36,18 +36,16 @@ ZoomLevel _saved_scrollpos_zoom;
|
||||
|
||||
void SaveViewportBeforeSaveGame()
|
||||
{
|
||||
const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
const Window *w = GetMainWindow();
|
||||
|
||||
if (w != nullptr) {
|
||||
_saved_scrollpos_x = w->viewport->scrollpos_x;
|
||||
_saved_scrollpos_y = w->viewport->scrollpos_y;
|
||||
_saved_scrollpos_zoom = w->viewport->zoom;
|
||||
}
|
||||
_saved_scrollpos_x = w->viewport->scrollpos_x;
|
||||
_saved_scrollpos_y = w->viewport->scrollpos_y;
|
||||
_saved_scrollpos_zoom = w->viewport->zoom;
|
||||
}
|
||||
|
||||
void ResetViewportAfterLoadGame()
|
||||
{
|
||||
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
Window *w = GetMainWindow();
|
||||
|
||||
w->viewport->scrollpos_x = _saved_scrollpos_x;
|
||||
w->viewport->scrollpos_y = _saved_scrollpos_y;
|
||||
|
@ -497,14 +497,16 @@ void AfterLoadVehicles(bool part_of_load)
|
||||
v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_seq);
|
||||
v->UpdateSpriteSeqBound();
|
||||
|
||||
/* The plane's shadow will have the same image as the plane, but no colour */
|
||||
/* The aircraft's shadow will have the same image as the aircraft, but no colour */
|
||||
Vehicle *shadow = v->Next();
|
||||
if (shadow == nullptr) SlErrorCorrupt("Missing shadow for aircraft");
|
||||
shadow->sprite_seq.CopyWithoutPalette(v->sprite_seq);
|
||||
shadow->sprite_seq_bounds = v->sprite_seq_bounds;
|
||||
|
||||
/* In the case of a helicopter we will update the rotor sprites */
|
||||
if (v->subtype == AIR_HELICOPTER) {
|
||||
Vehicle *rotor = shadow->Next();
|
||||
if (rotor == nullptr) SlErrorCorrupt("Missing rotor for helicopter");
|
||||
GetRotorImage(Aircraft::From(v), EIT_ON_MAP, &rotor->sprite_seq);
|
||||
rotor->UpdateSpriteSeqBound();
|
||||
}
|
||||
|
@ -759,7 +759,7 @@ void SetupScreenshotViewport(ScreenshotType t, Viewport *vp, uint32 width, uint3
|
||||
case SC_CRASHLOG: {
|
||||
assert(width == 0 && height == 0);
|
||||
|
||||
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
Window *w = GetMainWindow();
|
||||
vp->virtual_left = w->viewport->virtual_left;
|
||||
vp->virtual_top = w->viewport->virtual_top;
|
||||
vp->virtual_width = w->viewport->virtual_width;
|
||||
@ -810,7 +810,7 @@ void SetupScreenshotViewport(ScreenshotType t, Viewport *vp, uint32 width, uint3
|
||||
default: {
|
||||
vp->zoom = (t == SC_ZOOMEDIN) ? _settings_client.gui.zoom_min : ZOOM_LVL_VIEWPORT;
|
||||
|
||||
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
Window *w = GetMainWindow();
|
||||
vp->virtual_left = w->viewport->virtual_left;
|
||||
vp->virtual_top = w->viewport->virtual_top;
|
||||
|
||||
|
@ -10,17 +10,12 @@
|
||||
#include "../../stdafx.h"
|
||||
#include "script_base.hpp"
|
||||
#include "script_error.hpp"
|
||||
#include "../../network/network.h"
|
||||
#include "../../core/random_func.hpp"
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* static */ uint32 ScriptBase::Rand()
|
||||
{
|
||||
/* We pick RandomRange if we are in SP (so when saved, we do the same over and over)
|
||||
* but we pick InteractiveRandomRange if we are a network_server or network-client. */
|
||||
if (_networking) return ::InteractiveRandom();
|
||||
return ::Random();
|
||||
return ScriptObject::GetRandomizer().Next();
|
||||
}
|
||||
|
||||
/* static */ uint32 ScriptBase::RandItem(int unused_param)
|
||||
@ -30,10 +25,7 @@
|
||||
|
||||
/* static */ uint ScriptBase::RandRange(uint max)
|
||||
{
|
||||
/* We pick RandomRange if we are in SP (so when saved, we do the same over and over)
|
||||
* but we pick InteractiveRandomRange if we are a network_server or network-client. */
|
||||
if (_networking) return ::InteractiveRandomRange(max);
|
||||
return ::RandomRange(max);
|
||||
return ScriptObject::GetRandomizer().Next(max);
|
||||
}
|
||||
|
||||
/* static */ uint32 ScriptBase::RandRangeItem(int unused_param, uint max)
|
||||
|
@ -18,9 +18,6 @@
|
||||
*
|
||||
* @note The random functions are not called Random and RandomRange, because
|
||||
* RANDOM_DEBUG does some tricky stuff, which messes with those names.
|
||||
* @note In MP we cannot use Random because that will cause desyncs (scripts are
|
||||
* ran on the server only, not on all clients). This means that
|
||||
* we use InteractiveRandom in MP. Rand() takes care of this for you.
|
||||
*/
|
||||
class ScriptBase : public ScriptObject {
|
||||
public:
|
||||
|
@ -93,9 +93,10 @@
|
||||
EnforcePrecondition(false, gender == GENDER_MALE || gender == GENDER_FEMALE);
|
||||
EnforcePrecondition(false, GetPresidentGender(ScriptCompany::COMPANY_SELF) != gender);
|
||||
|
||||
Randomizer &randomizer = ScriptObject::GetRandomizer();
|
||||
CompanyManagerFace cmf;
|
||||
GenderEthnicity ge = (GenderEthnicity)((gender == GENDER_FEMALE ? (1 << ::GENDER_FEMALE) : 0) | (::InteractiveRandom() & (1 << ETHNICITY_BLACK)));
|
||||
RandomCompanyManagerFaceBits(cmf, ge, false);
|
||||
GenderEthnicity ge = (GenderEthnicity)((gender == GENDER_FEMALE ? (1 << ::GENDER_FEMALE) : 0) | (randomizer.Next() & (1 << ETHNICITY_BLACK)));
|
||||
RandomCompanyManagerFaceBits(cmf, ge, false, randomizer);
|
||||
|
||||
return ScriptObject::DoCommand(0, 0, cmf, CMD_SET_COMPANY_MANAGER_FACE);
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
if (!IsValid(setting)) return -1;
|
||||
|
||||
const SettingDesc *sd = GetSettingFromName(setting);
|
||||
assert(sd != nullptr);
|
||||
return sd->AsIntSetting()->Read(&_settings_game);
|
||||
}
|
||||
|
||||
@ -34,6 +35,7 @@
|
||||
if (!IsValid(setting)) return false;
|
||||
|
||||
const SettingDesc *sd = GetSettingFromName(setting);
|
||||
assert(sd != nullptr);
|
||||
|
||||
if ((sd->flags & SF_NO_NETWORK_SYNC) != 0) return false;
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#include "script_industrytype.hpp"
|
||||
#include "script_base.hpp"
|
||||
#include "script_map.hpp"
|
||||
#include "script_error.hpp"
|
||||
#include "../../strings_func.h"
|
||||
@ -120,8 +121,8 @@
|
||||
EnforcePrecondition(false, CanBuildIndustry(industry_type));
|
||||
EnforcePrecondition(false, ScriptMap::IsValidTile(tile));
|
||||
|
||||
uint32 seed = ::InteractiveRandom();
|
||||
uint32 layout_index = ::InteractiveRandomRange((uint32)::GetIndustrySpec(industry_type)->layouts.size());
|
||||
uint32 seed = ScriptBase::Rand();
|
||||
uint32 layout_index = ScriptBase::RandRange((uint32)::GetIndustrySpec(industry_type)->layouts.size());
|
||||
return ScriptObject::DoCommand(tile, (1 << 16) | (layout_index << 8) | industry_type, seed, CMD_BUILD_INDUSTRY);
|
||||
}
|
||||
|
||||
@ -129,7 +130,7 @@
|
||||
{
|
||||
EnforcePrecondition(false, CanProspectIndustry(industry_type));
|
||||
|
||||
uint32 seed = ::InteractiveRandom();
|
||||
uint32 seed = ScriptBase::Rand();
|
||||
return ScriptObject::DoCommand(0, industry_type, seed, CMD_BUILD_INDUSTRY);
|
||||
}
|
||||
|
||||
|
@ -395,3 +395,19 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
||||
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
|
||||
/* static */ Randomizer ScriptObject::random_states[OWNER_END];
|
||||
|
||||
Randomizer &ScriptObject::GetRandomizer(Owner owner)
|
||||
{
|
||||
return ScriptObject::random_states[owner];
|
||||
}
|
||||
|
||||
void ScriptObject::InitializeRandomizers()
|
||||
{
|
||||
Randomizer random = _random;
|
||||
for (Owner owner = OWNER_BEGIN; owner < OWNER_END; owner++) {
|
||||
ScriptObject::GetRandomizer(owner).SetSeed(random.Next());
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "../../misc/countedptr.hpp"
|
||||
#include "../../road_type.h"
|
||||
#include "../../rail_type.h"
|
||||
#include "../../core/random_func.hpp"
|
||||
|
||||
#include "script_types.hpp"
|
||||
#include "../script_suspend.hpp"
|
||||
@ -67,6 +68,18 @@ public:
|
||||
*/
|
||||
static class ScriptInstance *GetActiveInstance();
|
||||
|
||||
/**
|
||||
* Get a reference of the randomizer that brings this script random values.
|
||||
* @param owner The owner/script to get the randomizer for. This defaults to ScriptObject::GetRootCompany()
|
||||
*/
|
||||
static Randomizer &GetRandomizer(Owner owner = ScriptObject::GetRootCompany());
|
||||
|
||||
/**
|
||||
* Initialize/reset the script random states. The state of the scripts are
|
||||
* based on the current _random seed, but _random does not get changed.
|
||||
*/
|
||||
static void InitializeRandomizers();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Executes a raw DoCommand for the script.
|
||||
@ -315,6 +328,8 @@ private:
|
||||
* @param story_page_id The new StoryPageID.
|
||||
*/
|
||||
static void SetNewStoryPageElementID(StoryPageElementID story_page_element_id);
|
||||
|
||||
static Randomizer random_states[OWNER_END]; ///< Random states for each of the scripts (game script uses OWNER_DEITY)
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_OBJECT_HPP */
|
||||
|
@ -67,6 +67,7 @@ static const Order *ResolveOrder(VehicleID vehicle_id, ScriptOrder::OrderPositio
|
||||
if (order_position == ScriptOrder::ORDER_INVALID) return nullptr;
|
||||
}
|
||||
const Order *order = v->GetFirstOrder();
|
||||
assert(order != nullptr);
|
||||
while (order->GetType() == OT_IMPLICIT) order = order->next;
|
||||
while (order_position > 0) {
|
||||
order_position = (ScriptOrder::OrderPosition)(order_position - 1);
|
||||
@ -91,6 +92,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
|
||||
int res = (int)order_position;
|
||||
const Order *order = v->orders->GetFirstOrder();
|
||||
assert(order != nullptr);
|
||||
for (; order->GetType() == OT_IMPLICIT; order = order->next) res++;
|
||||
while (order_position > 0) {
|
||||
order_position = (ScriptOrder::OrderPosition)(order_position - 1);
|
||||
@ -136,6 +138,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
if (!IsValidVehicleOrder(vehicle_id, order_position)) return false;
|
||||
|
||||
const Order *order = ::Vehicle::Get(vehicle_id)->GetOrder(ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position));
|
||||
assert(order != nullptr);
|
||||
return order->GetType() == OT_CONDITIONAL;
|
||||
}
|
||||
|
||||
@ -145,6 +148,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
if (!IsValidVehicleOrder(vehicle_id, order_position)) return false;
|
||||
|
||||
const Order *order = ::ResolveOrder(vehicle_id, order_position);
|
||||
assert(order != nullptr);
|
||||
return order->GetType() == OT_DUMMY;
|
||||
}
|
||||
|
||||
@ -176,6 +180,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr
|
||||
if (order_position == ORDER_CURRENT) {
|
||||
int cur_order_pos = ::Vehicle::Get(vehicle_id)->cur_real_order_index;
|
||||
const Order *order = ::Vehicle::Get(vehicle_id)->GetFirstOrder();
|
||||
assert(order != nullptr);
|
||||
int num_implicit_orders = 0;
|
||||
for (int i = 0; i < cur_order_pos; i++) {
|
||||
if (order->GetType() == OT_IMPLICIT) num_implicit_orders++;
|
||||
|
@ -303,7 +303,7 @@
|
||||
EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_TOWN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG);
|
||||
}
|
||||
uint32 townnameparts;
|
||||
if (!GenerateTownName(&townnameparts)) {
|
||||
if (!GenerateTownName(ScriptObject::GetRandomizer(), &townnameparts)) {
|
||||
ScriptController::DecreaseOps(50000);
|
||||
ScriptObject::SetLastError(ScriptError::ERR_NAME_IS_NOT_UNIQUE);
|
||||
return false;
|
||||
|
@ -46,6 +46,7 @@
|
||||
if (colour != TC_INVALID && (::TextColour)colour >= ::TC_END) return;
|
||||
|
||||
Window *w = FindWindowById((::WindowClass)window, number);
|
||||
assert(w != nullptr);
|
||||
|
||||
if (widget == WIDGET_ALL) {
|
||||
if (colour != TC_INVALID) return;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "../settings_type.h"
|
||||
#include "../core/random_func.hpp"
|
||||
#include "script_info.hpp"
|
||||
#include "api/script_object.hpp"
|
||||
#include "../textfile_gui.h"
|
||||
#include "../string_func.h"
|
||||
|
||||
@ -35,7 +36,7 @@ void ScriptConfig::Change(const char *name, int version, bool force_exact_match,
|
||||
* for the Script that have the random flag to a random value. */
|
||||
for (const auto &item : *this->info->GetConfigList()) {
|
||||
if (item.flags & SCRIPTCONFIG_RANDOM) {
|
||||
this->SetSetting(item.name, InteractiveRandomRange(item.max_value + 1 - item.min_value) + item.min_value);
|
||||
this->SetSetting(item.name, ScriptObject::GetRandomizer(OWNER_NONE).Next(item.max_value + 1 - item.min_value) + item.min_value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,7 +158,7 @@ void ScriptConfig::AddRandomDeviation()
|
||||
{
|
||||
for (const auto &item : *this->GetConfigList()) {
|
||||
if (item.random_deviation != 0) {
|
||||
this->SetSetting(item.name, InteractiveRandomRange(item.random_deviation * 2 + 1) - item.random_deviation + this->GetSetting(item.name));
|
||||
this->SetSetting(item.name, ScriptObject::GetRandomizer(OWNER_NONE).Next(item.random_deviation * 2 + 1) - item.random_deviation + this->GetSetting(item.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -969,7 +969,7 @@ void SmallMapWindow::DrawTowns(const DrawPixelInfo *dpi) const
|
||||
void SmallMapWindow::DrawMapIndicators() const
|
||||
{
|
||||
/* Find main viewport. */
|
||||
const Viewport *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
|
||||
const Viewport *vp = GetMainWindow()->viewport;
|
||||
|
||||
Point upper_left_smallmap_coord = InverseRemapCoords2(vp->virtual_left, vp->virtual_top);
|
||||
Point lower_right_smallmap_coord = InverseRemapCoords2(vp->virtual_left + vp->virtual_width - 1, vp->virtual_top + vp->virtual_height - 1);
|
||||
@ -1461,7 +1461,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
|
||||
if (click_count > 0) this->mouse_capture_widget = widget;
|
||||
|
||||
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP);
|
||||
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
Window *w = GetMainWindow();
|
||||
int sub;
|
||||
pt = this->PixelToTile(pt.x - wid->pos_x, pt.y - wid->pos_y, &sub);
|
||||
ScrollWindowTo(this->scroll_x + pt.x * TILE_SIZE, this->scroll_y + pt.y * TILE_SIZE, -1, w);
|
||||
@ -1732,7 +1732,7 @@ void SmallMapWindow::SetNewScroll(int sx, int sy, int sub)
|
||||
*/
|
||||
void SmallMapWindow::SmallMapCenterOnCurrentPos()
|
||||
{
|
||||
const Viewport *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
|
||||
const Viewport *vp = GetMainWindow()->viewport;
|
||||
Point viewport_center = InverseRemapCoords2(vp->virtual_left + vp->virtual_width / 2, vp->virtual_top + vp->virtual_height / 2);
|
||||
|
||||
int sub;
|
||||
@ -2024,7 +2024,7 @@ void ShowSmallMap()
|
||||
*/
|
||||
bool ScrollMainWindowTo(int x, int y, int z, bool instant)
|
||||
{
|
||||
bool res = ScrollWindowTo(x, y, z, FindWindowById(WC_MAIN_WINDOW, 0), instant);
|
||||
bool res = ScrollWindowTo(x, y, z, GetMainWindow(), instant);
|
||||
|
||||
/* If a user scrolls to a tile (via what way what so ever) and already is on
|
||||
* that tile (e.g.: pressed twice), move the smallmap to that location,
|
||||
|
@ -121,7 +121,7 @@ static const DrawTileSprites _object_hq[] = {
|
||||
|
||||
#undef TILE_SPRITE_LINE
|
||||
|
||||
#define M(name, size, build_cost_multiplier, clear_cost_multiplier, height, climate, gen_amount, flags) { GRFFilePropsBase<2>(), INVALID_OBJECT_CLASS, name, climate, size, build_cost_multiplier, clear_cost_multiplier, 0, MAX_DAY + 1, flags, OBJECT_CTRL_FLAG_NONE, {0, 0, 0, 0}, {0, 0, 0, 0}, 0, height, 1, gen_amount, true, OVMT_DEFAULT, 0 }
|
||||
#define M(name, size, build_cost_multiplier, clear_cost_multiplier, height, climate, gen_amount, flags) { GRFFilePropsBase<2>(), {0, 0, 0, 0}, INVALID_OBJECT_CLASS, name, climate, size, build_cost_multiplier, clear_cost_multiplier, 0, MAX_DAY + 1, flags, OBJECT_CTRL_FLAG_NONE, {0, 0, 0, 0}, 0, height, 1, gen_amount, OVMT_DEFAULT, 0 }
|
||||
|
||||
/* Climates
|
||||
* T = Temperate
|
||||
|
@ -36,6 +36,7 @@
|
||||
static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint32 val, ModifyTimetableFlags mtf, bool timetabled, bool ignore_lock = false)
|
||||
{
|
||||
Order *order = v->GetOrder(order_number);
|
||||
assert(order != nullptr);
|
||||
int total_delta = 0;
|
||||
int timetable_delta = 0;
|
||||
|
||||
|
@ -904,7 +904,7 @@ static CallBackFunction MenuClickShowAir(int index)
|
||||
|
||||
static CallBackFunction ToolbarZoomInClick(Window *w)
|
||||
{
|
||||
if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
|
||||
if (DoZoomInOutWindow(ZOOM_IN, GetMainWindow())) {
|
||||
w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)WID_TE_ZOOM_IN : (byte)WID_TN_ZOOM_IN);
|
||||
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
|
||||
}
|
||||
@ -915,7 +915,7 @@ static CallBackFunction ToolbarZoomInClick(Window *w)
|
||||
|
||||
static CallBackFunction ToolbarZoomOutClick(Window *w)
|
||||
{
|
||||
if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) {
|
||||
if (DoZoomInOutWindow(ZOOM_OUT, GetMainWindow())) {
|
||||
w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)WID_TE_ZOOM_OUT : (byte)WID_TN_ZOOM_OUT);
|
||||
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
|
||||
}
|
||||
@ -2196,7 +2196,7 @@ struct MainToolbarWindow : Window {
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
if (!gui_scope) return;
|
||||
if (FindWindowById(WC_MAIN_WINDOW, 0) != nullptr) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT);
|
||||
HandleZoomMessage(this, GetMainWindow()->viewport, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT);
|
||||
}
|
||||
|
||||
static HotkeyList hotkeys;
|
||||
@ -2577,7 +2577,7 @@ struct ScenarioEditorToolbarWindow : Window {
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
if (!gui_scope) return;
|
||||
if (FindWindowById(WC_MAIN_WINDOW, 0) != nullptr) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT);
|
||||
HandleZoomMessage(this, GetMainWindow()->viewport, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT);
|
||||
}
|
||||
|
||||
void OnQueryTextFinished(char *str) override
|
||||
|
@ -2546,7 +2546,7 @@ bool GenerateTowns(TownLayout layout)
|
||||
bool city = (_settings_game.economy.larger_towns != 0 && Chance16(1, _settings_game.economy.larger_towns));
|
||||
IncreaseGeneratingWorldProgress(GWP_TOWN);
|
||||
/* Get a unique name for the town. */
|
||||
if (!GenerateTownName(&townnameparts, &town_names)) continue;
|
||||
if (!GenerateTownName(_random, &townnameparts, &town_names)) continue;
|
||||
/* try 20 times to create a random-sized town for the first loop. */
|
||||
if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != nullptr) current_number++; // If creation was successful, raise a flag.
|
||||
} while (--total);
|
||||
@ -2560,7 +2560,7 @@ bool GenerateTowns(TownLayout layout)
|
||||
|
||||
/* If current_number is still zero at this point, it means that not a single town has been created.
|
||||
* So give it a last try, but now more aggressive */
|
||||
if (GenerateTownName(&townnameparts) &&
|
||||
if (GenerateTownName(_random, &townnameparts) &&
|
||||
CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1323,7 +1323,7 @@ public:
|
||||
|
||||
void RandomTownName()
|
||||
{
|
||||
this->townnamevalid = GenerateTownName(&this->townnameparts);
|
||||
this->townnamevalid = GenerateTownName(_interactive_random, &this->townnameparts);
|
||||
|
||||
if (!this->townnamevalid) {
|
||||
this->townname_editbox.text.DeleteAll();
|
||||
|
@ -112,11 +112,12 @@ bool VerifyTownName(uint32 r, const TownNameParams *par, TownNames *town_names)
|
||||
|
||||
/**
|
||||
* Generates valid town name.
|
||||
* @param randomizer the source of random data for generating the name
|
||||
* @param townnameparts if a name is generated, it's stored there
|
||||
* @param town_names if a name is generated, check its uniqueness with the set
|
||||
* @return true iff a name was generated
|
||||
*/
|
||||
bool GenerateTownName(uint32 *townnameparts, TownNames *town_names)
|
||||
bool GenerateTownName(Randomizer &randomizer, uint32 *townnameparts, TownNames *town_names)
|
||||
{
|
||||
TownNameParams par(_settings_game.game_creation.town_name);
|
||||
|
||||
@ -130,7 +131,7 @@ bool GenerateTownName(uint32 *townnameparts, TownNames *town_names)
|
||||
* the other towns may take considerable amount of time (10000 is
|
||||
* too much). */
|
||||
for (int i = 1000; i != 0; i--) {
|
||||
uint32 r = _generating_world ? Random() : InteractiveRandom();
|
||||
uint32 r = randomizer.Next();
|
||||
if (!VerifyTownName(r, &par, town_names)) continue;
|
||||
|
||||
*townnameparts = r;
|
||||
|
@ -10,12 +10,13 @@
|
||||
#ifndef TOWNNAME_FUNC_H
|
||||
#define TOWNNAME_FUNC_H
|
||||
|
||||
#include "core/random_func.hpp"
|
||||
#include "townname_type.h"
|
||||
|
||||
char *GenerateTownNameString(char *buf, const char *last, size_t lang, uint32 seed);
|
||||
char *GetTownName(char *buff, const TownNameParams *par, uint32 townnameparts, const char *last);
|
||||
char *GetTownName(char *buff, const Town *t, const char *last);
|
||||
bool VerifyTownName(uint32 r, const TownNameParams *par, TownNames *town_names = nullptr);
|
||||
bool GenerateTownName(uint32 *townnameparts, TownNames *town_names = nullptr);
|
||||
bool GenerateTownName(Randomizer &randomizer, uint32 *townnameparts, TownNames *town_names = nullptr);
|
||||
|
||||
#endif /* TOWNNAME_FUNC_H */
|
||||
|
@ -457,6 +457,7 @@ void RemoveAllTrees()
|
||||
*/
|
||||
uint PlaceTreeGroupAroundTile(TileIndex tile, TreeType treetype, uint radius, uint count, bool set_zone)
|
||||
{
|
||||
dbg_assert(_game_mode == GM_EDITOR); // Due to InteractiveRandom being used in this function
|
||||
dbg_assert(treetype < TREE_TOYLAND + TREE_COUNT_TOYLAND);
|
||||
const bool allow_desert = treetype == TREE_CACTUS;
|
||||
uint planted = 0;
|
||||
|
@ -479,6 +479,7 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles,
|
||||
u->cargo_subtype = result.subtype;
|
||||
if (u->type == VEH_AIRCRAFT) {
|
||||
Vehicle *w = u->Next();
|
||||
assert(w != nullptr);
|
||||
w->refit_cap = std::min<uint16>(w->refit_cap, result.mail_capacity);
|
||||
w->cargo_cap = result.mail_capacity;
|
||||
if (w->cargo.TotalCount() > w->refit_cap) w->cargo.Truncate(w->cargo.TotalCount() - w->refit_cap);
|
||||
|
@ -3878,7 +3878,7 @@ public:
|
||||
if (_ctrl_pressed) {
|
||||
ShowExtraViewportWindow(TileVirtXY(v->x_pos, v->y_pos));
|
||||
} else {
|
||||
const Window *mainwindow = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
const Window *mainwindow = GetMainWindow();
|
||||
if (click_count > 1 && mainwindow->viewport->zoom < ZOOM_LVL_DRAW_MAP) {
|
||||
/* main window 'follows' vehicle */
|
||||
mainwindow->viewport->follow_vehicle = v->index;
|
||||
@ -3949,8 +3949,8 @@ public:
|
||||
{
|
||||
/* If the hotkey is not for any widget in the UI (i.e. for honking) */
|
||||
if (hotkey == WID_VV_HONK_HORN) {
|
||||
const Window* mainwindow = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
const Vehicle* v = Vehicle::Get(window_number);
|
||||
const Window *mainwindow = GetMainWindow();
|
||||
const Vehicle *v = Vehicle::Get(window_number);
|
||||
/* Only play the sound if we're following this vehicle */
|
||||
if (mainwindow->viewport->follow_vehicle == v->index) {
|
||||
v->PlayLeaveStationSound(true);
|
||||
@ -4185,8 +4185,8 @@ bool VehicleClicked(const GUIVehicleGroup &vehgroup)
|
||||
|
||||
void StopGlobalFollowVehicle(const Vehicle *v)
|
||||
{
|
||||
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
if (w != nullptr && w->viewport->follow_vehicle == v->index) {
|
||||
Window *w = GetMainWindow();
|
||||
if (w->viewport->follow_vehicle == v->index) {
|
||||
ScrollMainWindowTo(v->x_pos, v->y_pos, v->z_pos, true); // lock the main view on the vehicle's last position
|
||||
w->viewport->follow_vehicle = INVALID_VEHICLE;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
Point pt;
|
||||
if (tile == INVALID_TILE) {
|
||||
/* No tile? Use center of main viewport. */
|
||||
const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
const Window *w = GetMainWindow();
|
||||
|
||||
/* center on same place as main window (zoom is maximum, no adjustment needed) */
|
||||
pt.x = w->viewport->scrollpos_x + w->viewport->virtual_width / 2;
|
||||
@ -101,7 +101,7 @@ public:
|
||||
case WID_EV_ZOOM_OUT: DoZoomInOutWindow(ZOOM_OUT, this); break;
|
||||
|
||||
case WID_EV_MAIN_TO_VIEW: { // location button (move main view to same spot as this view) 'Paste Location'
|
||||
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
Window *w = GetMainWindow();
|
||||
int x = this->viewport->scrollpos_x; // Where is the main looking at
|
||||
int y = this->viewport->scrollpos_y;
|
||||
|
||||
@ -113,7 +113,7 @@ public:
|
||||
}
|
||||
|
||||
case WID_EV_VIEW_TO_MAIN: { // inverse location button (move this view to same spot as main view) 'Copy Location'
|
||||
const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
const Window *w = GetMainWindow();
|
||||
int x = w->viewport->scrollpos_x;
|
||||
int y = w->viewport->scrollpos_y;
|
||||
|
||||
|
@ -40,6 +40,7 @@ void MakeWaterKeepingClass(TileIndex tile, Owner o);
|
||||
void CheckForDockingTile(TileIndex t);
|
||||
|
||||
bool RiverModifyDesertZone(TileIndex tile, void *data);
|
||||
void MakeRiverAndModifyDesertZoneAround(TileIndex tile);
|
||||
static const uint RIVER_OFFSET_DESERT_DISTANCE = 5; ///< Circular tile search radius to create non-desert around a river tile.
|
||||
|
||||
bool IsWateredTile(TileIndex tile, Direction from);
|
||||
|
@ -446,6 +446,18 @@ bool RiverModifyDesertZone(TileIndex tile, void *)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a river tile and remove desert directly around it.
|
||||
* @param tile The tile to change into river and create non-desert around
|
||||
*/
|
||||
void MakeRiverAndModifyDesertZoneAround(TileIndex tile) {
|
||||
MakeRiver(tile, Random());
|
||||
MarkTileDirtyByTile(tile);
|
||||
|
||||
/* Remove desert directly around the river tile. */
|
||||
CircularTileSearch(&tile, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a piece of canal.
|
||||
* @param tile end tile of stretch-dragging
|
||||
|
@ -1191,6 +1191,18 @@ Window *FindWindowByClass(WindowClass cls)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the main window, i.e. FindWindowById(WC_MAIN_WINDOW, 0).
|
||||
* If the main window is not available, this function will trigger an assert.
|
||||
* @return Pointer to the main window.
|
||||
*/
|
||||
Window *GetMainWindow()
|
||||
{
|
||||
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
assert(w != nullptr);
|
||||
return w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a window by its class and window number (if it is open).
|
||||
* @param cls Window class
|
||||
@ -2550,7 +2562,7 @@ static EventState HandleViewportScroll()
|
||||
return ES_NOT_HANDLED;
|
||||
}
|
||||
|
||||
if (_last_scroll_window == FindWindowById(WC_MAIN_WINDOW, 0) && _last_scroll_window->viewport->follow_vehicle != INVALID_VEHICLE) {
|
||||
if (_last_scroll_window == GetMainWindow() && _last_scroll_window->viewport->follow_vehicle != INVALID_VEHICLE) {
|
||||
/* If the main window is following a vehicle, then first let go of it! */
|
||||
const Vehicle *veh = Vehicle::Get(_last_scroll_window->viewport->follow_vehicle);
|
||||
ScrollMainWindowTo(veh->x_pos, veh->y_pos, veh->z_pos, true); // This also resets follow_vehicle
|
||||
@ -2922,7 +2934,7 @@ const std::chrono::milliseconds TIME_BETWEEN_DOUBLE_CLICK(500); ///< Time betwee
|
||||
static void ScrollMainViewport(int x, int y)
|
||||
{
|
||||
if (_game_mode != GM_MENU && _game_mode != GM_BOOTSTRAP) {
|
||||
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
Window *w = GetMainWindow();
|
||||
assert(w);
|
||||
|
||||
w->viewport->dest_scrollpos_x += ScaleByZoom(x, w->viewport->zoom);
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
Window *FindWindowById(WindowClass cls, WindowNumber number);
|
||||
Window *FindWindowByClass(WindowClass cls);
|
||||
Window *GetMainWindow();
|
||||
void ChangeWindowOwner(Owner old_owner, Owner new_owner);
|
||||
|
||||
void ResizeWindow(Window *w, int x, int y, bool clamp_to_screen = true);
|
||||
|
Loading…
Reference in New Issue
Block a user