mirror of https://github.com/OpenTTD/OpenTTD
Change: replace per-AI "start_date" with a global "competitors_interval" (#10653)
The per-AI "start_date" is a lot of custom code, and was rarely used in the way it was meant. While at it, also ported this part over to the new timer system.pull/10668/head
parent
43a7e54067
commit
ed83c4b0da
|
@ -88,9 +88,9 @@
|
|||
abs( 21): 21
|
||||
|
||||
--AIBase--
|
||||
Rand(): 2232656694
|
||||
Rand(): 2514636170
|
||||
Rand(): 3897038727
|
||||
Rand(): 2113409458
|
||||
Rand(): 2000129769
|
||||
Rand(): 1788051963
|
||||
RandRange(0): 0
|
||||
RandRange(0): 0
|
||||
RandRange(0): 0
|
||||
|
@ -99,13 +99,13 @@
|
|||
RandRange(1): 0
|
||||
RandRange(2): 0
|
||||
RandRange(2): 0
|
||||
RandRange(2): 0
|
||||
RandRange(1000000): 666804
|
||||
RandRange(1000000): 624059
|
||||
RandRange(1000000): 697029
|
||||
Chance(1, 2): true
|
||||
RandRange(2): 1
|
||||
RandRange(1000000): 338687
|
||||
RandRange(1000000): 274895
|
||||
RandRange(1000000): 217539
|
||||
Chance(1, 2): false
|
||||
Chance(1, 2): true
|
||||
Chance(1, 2): false
|
||||
|
||||
--List--
|
||||
IsEmpty(): true
|
||||
|
@ -420,144 +420,144 @@
|
|||
1098 => 46116
|
||||
1099 => 46158
|
||||
Randomize ListDump:
|
||||
1 => 688298322
|
||||
2 => 2585420314
|
||||
1000 => 1701392078
|
||||
1001 => 2664118875
|
||||
1002 => 3408466361
|
||||
1003 => 4098642324
|
||||
1004 => 3858929894
|
||||
1005 => 3774625512
|
||||
1006 => 2809742492
|
||||
1007 => 3983931060
|
||||
1008 => 2791524857
|
||||
1009 => 4184021601
|
||||
1010 => 4212142121
|
||||
1011 => 46859773
|
||||
1012 => 3095744278
|
||||
1013 => 3104411371
|
||||
1014 => 326384434
|
||||
1015 => 1486817960
|
||||
1016 => 2883541699
|
||||
1017 => 3786540442
|
||||
1018 => 820019294
|
||||
1019 => 710762995
|
||||
1020 => 3534100264
|
||||
1021 => 3585356150
|
||||
1022 => 732190215
|
||||
1023 => 236336673
|
||||
1024 => 740596257
|
||||
1025 => 1135321785
|
||||
1026 => 2067474156
|
||||
1027 => 2899283689
|
||||
1028 => 4054438597
|
||||
1029 => 928616892
|
||||
1030 => 1712486685
|
||||
1031 => 1994118287
|
||||
1032 => 1333321243
|
||||
1033 => 194124284
|
||||
1034 => 615083294
|
||||
1035 => 628086450
|
||||
1036 => 498957825
|
||||
1037 => 1359697121
|
||||
1038 => 1888433963
|
||||
1039 => 941623020
|
||||
1040 => 2369304004
|
||||
1041 => 3523427032
|
||||
1042 => 3236625937
|
||||
1043 => 182127597
|
||||
1044 => 646955927
|
||||
1045 => 2870345582
|
||||
1046 => 623062612
|
||||
1047 => 2308011710
|
||||
1048 => 3026140316
|
||||
1049 => 3838191076
|
||||
1051 => 3182411967
|
||||
1052 => 2762833244
|
||||
1053 => 1960404034
|
||||
1054 => 1573325453
|
||||
1055 => 3978347993
|
||||
1056 => 699712177
|
||||
1057 => 863274966
|
||||
1058 => 1728276475
|
||||
1059 => 4048271407
|
||||
1060 => 1919485436
|
||||
1061 => 111273464
|
||||
1062 => 125435213
|
||||
1063 => 155132602
|
||||
1064 => 4123293220
|
||||
1065 => 655046914
|
||||
1066 => 1577399562
|
||||
1067 => 1028818150
|
||||
1068 => 447058239
|
||||
1069 => 3237047027
|
||||
1070 => 2968751973
|
||||
1071 => 4096278708
|
||||
1072 => 1523643051
|
||||
1073 => 231373233
|
||||
1074 => 1121759962
|
||||
1075 => 1449439846
|
||||
1076 => 2679696543
|
||||
1077 => 2785673432
|
||||
1078 => 2116903943
|
||||
1079 => 672822173
|
||||
1080 => 3325393385
|
||||
1081 => 1589904755
|
||||
1082 => 1148782015
|
||||
1083 => 663503316
|
||||
1084 => 933352745
|
||||
1085 => 577717039
|
||||
1086 => 402172048
|
||||
1087 => 1812250453
|
||||
1088 => 667300501
|
||||
1089 => 2456141519
|
||||
1090 => 3438492520
|
||||
1091 => 420696035
|
||||
1092 => 2131427774
|
||||
1093 => 3859663748
|
||||
1094 => 4134083418
|
||||
1095 => 1969629634
|
||||
1096 => 3739173141
|
||||
1097 => 3459847605
|
||||
1098 => 2834059387
|
||||
1099 => 3148043212
|
||||
1 => 1667006376
|
||||
2 => 814756458
|
||||
1000 => 2792131700
|
||||
1001 => 3417650573
|
||||
1002 => 1856129988
|
||||
1003 => 1800973341
|
||||
1004 => 4197962148
|
||||
1005 => 2463509731
|
||||
1006 => 2312121797
|
||||
1007 => 1357932132
|
||||
1008 => 1603755907
|
||||
1009 => 1718096015
|
||||
1010 => 3850074449
|
||||
1011 => 2711130211
|
||||
1012 => 2371249199
|
||||
1013 => 881020769
|
||||
1014 => 3366660077
|
||||
1015 => 808768948
|
||||
1016 => 3035331984
|
||||
1017 => 2813590961
|
||||
1018 => 2745021820
|
||||
1019 => 3075151719
|
||||
1020 => 2553774560
|
||||
1021 => 4267762096
|
||||
1022 => 3863175846
|
||||
1023 => 4198397908
|
||||
1024 => 817599906
|
||||
1025 => 3149240362
|
||||
1026 => 3003005979
|
||||
1027 => 1214815375
|
||||
1028 => 3784363817
|
||||
1029 => 3181864540
|
||||
1030 => 325341059
|
||||
1031 => 1011889231
|
||||
1032 => 3142617173
|
||||
1033 => 1197220206
|
||||
1034 => 4060510885
|
||||
1035 => 3596342467
|
||||
1036 => 219406671
|
||||
1037 => 3695508783
|
||||
1038 => 2823603997
|
||||
1039 => 2625659720
|
||||
1040 => 4113498476
|
||||
1041 => 1125297786
|
||||
1042 => 671905104
|
||||
1043 => 1231077134
|
||||
1044 => 892292375
|
||||
1045 => 2441486929
|
||||
1046 => 1804593432
|
||||
1047 => 2536560053
|
||||
1048 => 1896826021
|
||||
1049 => 1672512966
|
||||
1051 => 977884299
|
||||
1052 => 681948608
|
||||
1053 => 3853505792
|
||||
1054 => 4118706553
|
||||
1055 => 3581698138
|
||||
1056 => 3073782502
|
||||
1057 => 1084753140
|
||||
1058 => 2266056077
|
||||
1059 => 1239805090
|
||||
1060 => 1183528423
|
||||
1061 => 501361238
|
||||
1062 => 66542127
|
||||
1063 => 775638990
|
||||
1064 => 1111474321
|
||||
1065 => 3465462871
|
||||
1066 => 2317535037
|
||||
1067 => 878310882
|
||||
1068 => 2231368582
|
||||
1069 => 2353633007
|
||||
1070 => 179259867
|
||||
1071 => 1322707275
|
||||
1072 => 1474105363
|
||||
1073 => 619989187
|
||||
1074 => 3221603092
|
||||
1075 => 2400416540
|
||||
1076 => 3926392705
|
||||
1077 => 1122978123
|
||||
1078 => 3266139701
|
||||
1079 => 2948697341
|
||||
1080 => 3262493501
|
||||
1081 => 2200252596
|
||||
1082 => 4091101485
|
||||
1083 => 2797438343
|
||||
1084 => 2608201933
|
||||
1085 => 2577605442
|
||||
1086 => 1178956760
|
||||
1087 => 3047709109
|
||||
1088 => 1065186815
|
||||
1089 => 841440515
|
||||
1090 => 842182476
|
||||
1091 => 289059855
|
||||
1092 => 2114106829
|
||||
1093 => 436435334
|
||||
1094 => 111052607
|
||||
1095 => 81827083
|
||||
1096 => 1961213887
|
||||
1097 => 1374385392
|
||||
1098 => 3255118186
|
||||
1099 => 2245402931
|
||||
KeepTop(10):
|
||||
1 => 688298322
|
||||
2 => 2585420314
|
||||
1000 => 1701392078
|
||||
1001 => 2664118875
|
||||
1002 => 3408466361
|
||||
1003 => 4098642324
|
||||
1004 => 3858929894
|
||||
1005 => 3774625512
|
||||
1006 => 2809742492
|
||||
1007 => 3983931060
|
||||
1 => 1667006376
|
||||
2 => 814756458
|
||||
1000 => 2792131700
|
||||
1001 => 3417650573
|
||||
1002 => 1856129988
|
||||
1003 => 1800973341
|
||||
1004 => 4197962148
|
||||
1005 => 2463509731
|
||||
1006 => 2312121797
|
||||
1007 => 1357932132
|
||||
KeepBottom(8):
|
||||
1000 => 1701392078
|
||||
1001 => 2664118875
|
||||
1002 => 3408466361
|
||||
1003 => 4098642324
|
||||
1004 => 3858929894
|
||||
1005 => 3774625512
|
||||
1006 => 2809742492
|
||||
1007 => 3983931060
|
||||
1000 => 2792131700
|
||||
1001 => 3417650573
|
||||
1002 => 1856129988
|
||||
1003 => 1800973341
|
||||
1004 => 4197962148
|
||||
1005 => 2463509731
|
||||
1006 => 2312121797
|
||||
1007 => 1357932132
|
||||
RemoveBottom(2):
|
||||
1000 => 1701392078
|
||||
1001 => 2664118875
|
||||
1002 => 3408466361
|
||||
1003 => 4098642324
|
||||
1004 => 3858929894
|
||||
1005 => 3774625512
|
||||
1000 => 2792131700
|
||||
1001 => 3417650573
|
||||
1002 => 1856129988
|
||||
1003 => 1800973341
|
||||
1004 => 4197962148
|
||||
1005 => 2463509731
|
||||
RemoveTop(2):
|
||||
1002 => 3408466361
|
||||
1003 => 4098642324
|
||||
1004 => 3858929894
|
||||
1005 => 3774625512
|
||||
1002 => 1856129988
|
||||
1003 => 1800973341
|
||||
1004 => 4197962148
|
||||
1005 => 2463509731
|
||||
RemoveList({1003, 1004}):
|
||||
1002 => 3408466361
|
||||
1005 => 3774625512
|
||||
1002 => 1856129988
|
||||
1005 => 2463509731
|
||||
KeepList({1003, 1004, 1005}):
|
||||
1005 => 3774625512
|
||||
1005 => 2463509731
|
||||
AddList({1005, 4000, 4001, 4002}):
|
||||
1005 => 1005
|
||||
4000 => 8000
|
||||
|
@ -588,7 +588,7 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||
SetName(): false
|
||||
GetLastErrorString(): ERR_NAME_IS_NOT_UNIQUE
|
||||
GetName(): Regression
|
||||
GetPresidentName(): J. Green
|
||||
GetPresidentName(): F. Gribble
|
||||
SetPresidentName(): true
|
||||
GetPresidentName(): Regression AI
|
||||
GetBankBalance(): 100000
|
||||
|
@ -9320,12 +9320,12 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||
GetLocation(): 33417
|
||||
GetEngineType(): 153
|
||||
GetUnitNumber(): 1
|
||||
GetAge(): 0
|
||||
GetAge(): 1
|
||||
GetMaxAge(): 5490
|
||||
GetAgeLeft(): 5490
|
||||
GetAgeLeft(): 5489
|
||||
GetCurrentSpeed(): 7
|
||||
GetRunningCost(): 421
|
||||
GetProfitThisYear(): 0
|
||||
GetProfitThisYear(): -1
|
||||
GetProfitLastYear(): 0
|
||||
GetCurrentValue(): 5947
|
||||
GetVehicleType(): 1
|
||||
|
@ -9335,7 +9335,7 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||
IsInDepot(): false
|
||||
GetNumWagons(): 1
|
||||
GetWagonEngineType(): 153
|
||||
GetWagonAge(): 0
|
||||
GetWagonAge(): 1
|
||||
GetLength(): 8
|
||||
GetOwner(): 1
|
||||
BuildVehicle(): 14
|
||||
|
@ -9408,11 +9408,11 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||
14 => 1
|
||||
12 => 1
|
||||
Age ListDump:
|
||||
17 => 1
|
||||
16 => 1
|
||||
14 => 1
|
||||
13 => 1
|
||||
12 => 1
|
||||
17 => 0
|
||||
16 => 0
|
||||
MaxAge ListDump:
|
||||
16 => 10980
|
||||
14 => 10980
|
||||
|
@ -9420,9 +9420,9 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||
13 => 5490
|
||||
12 => 5490
|
||||
AgeLeft ListDump:
|
||||
16 => 10979
|
||||
16 => 10980
|
||||
14 => 10979
|
||||
17 => 7319
|
||||
17 => 7320
|
||||
13 => 5489
|
||||
12 => 5489
|
||||
CurrentSpeed ListDump:
|
||||
|
|
Binary file not shown.
|
@ -19,18 +19,6 @@
|
|||
*/
|
||||
class AI {
|
||||
public:
|
||||
/**
|
||||
* The default months AIs start after each other.
|
||||
*/
|
||||
enum StartNext {
|
||||
START_NEXT_EASY = DAYS_IN_YEAR * 2,
|
||||
START_NEXT_MEDIUM = DAYS_IN_YEAR,
|
||||
START_NEXT_HARD = DAYS_IN_YEAR / 2,
|
||||
START_NEXT_MIN = 0,
|
||||
START_NEXT_MAX = 3600,
|
||||
START_NEXT_DEVIATION = 60,
|
||||
};
|
||||
|
||||
/**
|
||||
* Is it possible to start a new AI company?
|
||||
* @return True if a new AI company can be started.
|
||||
|
@ -124,11 +112,6 @@ public:
|
|||
*/
|
||||
static void Save(CompanyID company);
|
||||
|
||||
/**
|
||||
* Get the number of days before the next AI should start.
|
||||
*/
|
||||
static int GetStartNextTime();
|
||||
|
||||
/** Wrapper function for AIScanner::GetAIConsoleList */
|
||||
static std::string GetConsoleList(bool newest_only = false);
|
||||
/** Wrapper function for AIScanner::GetAIConsoleLibraryList */
|
||||
|
|
|
@ -16,32 +16,6 @@
|
|||
|
||||
#include "../safeguards.h"
|
||||
|
||||
/** Configuration for AI start date, every AI has this setting. */
|
||||
ScriptConfigItem _start_date_config = {
|
||||
"start_date",
|
||||
"", // STR_AI_SETTINGS_START_DELAY
|
||||
AI::START_NEXT_MIN,
|
||||
AI::START_NEXT_MAX,
|
||||
AI::START_NEXT_MEDIUM,
|
||||
AI::START_NEXT_EASY,
|
||||
AI::START_NEXT_MEDIUM,
|
||||
AI::START_NEXT_HARD,
|
||||
AI::START_NEXT_DEVIATION,
|
||||
30,
|
||||
SCRIPTCONFIG_NONE,
|
||||
nullptr,
|
||||
false
|
||||
};
|
||||
|
||||
AIConfig::AIConfig(const AIConfig *config) : ScriptConfig(config)
|
||||
{
|
||||
/* Override start_date as per AIConfig::AddRandomDeviation().
|
||||
* This is necessary because the ScriptConfig constructor will instead call
|
||||
* ScriptConfig::AddRandomDeviation(). */
|
||||
int start_date = config->GetSetting("start_date");
|
||||
this->SetSetting("start_date", start_date != 0 ? std::max(1, this->GetSetting("start_date")) : 0);
|
||||
}
|
||||
|
||||
/* static */ AIConfig *AIConfig::GetConfig(CompanyID company, ScriptSettingSource source)
|
||||
{
|
||||
AIConfig **config;
|
||||
|
@ -69,70 +43,3 @@ bool AIConfig::ResetInfo(bool force_exact_match)
|
|||
this->info = (ScriptInfo *)AI::FindInfo(this->name, force_exact_match ? this->version : -1, force_exact_match);
|
||||
return this->info != nullptr;
|
||||
}
|
||||
|
||||
void AIConfig::PushExtraConfigList()
|
||||
{
|
||||
this->config_list->push_back(_start_date_config);
|
||||
}
|
||||
|
||||
void AIConfig::ClearConfigList()
|
||||
{
|
||||
/* The special casing for start_date is here to ensure that the
|
||||
* start_date setting won't change even if you chose another Script. */
|
||||
int start_date = this->GetSetting("start_date");
|
||||
|
||||
ScriptConfig::ClearConfigList();
|
||||
|
||||
this->SetSetting("start_date", start_date);
|
||||
}
|
||||
|
||||
int AIConfig::GetSetting(const char *name) const
|
||||
{
|
||||
if (this->info == nullptr) {
|
||||
SettingValueList::const_iterator it = this->settings.find(name);
|
||||
if (it == this->settings.end()) {
|
||||
assert(strcmp("start_date", name) == 0);
|
||||
switch (GetGameSettings().script.settings_profile) {
|
||||
case SP_EASY: return AI::START_NEXT_EASY;
|
||||
case SP_MEDIUM: return AI::START_NEXT_MEDIUM;
|
||||
case SP_HARD: return AI::START_NEXT_HARD;
|
||||
case SP_CUSTOM: return AI::START_NEXT_MEDIUM;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
return (*it).second;
|
||||
}
|
||||
|
||||
return ScriptConfig::GetSetting(name);
|
||||
}
|
||||
|
||||
void AIConfig::SetSetting(const char *name, int value)
|
||||
{
|
||||
if (this->info == nullptr) {
|
||||
if (strcmp("start_date", name) != 0) return;
|
||||
value = Clamp(value, AI::START_NEXT_MIN, AI::START_NEXT_MAX);
|
||||
|
||||
SettingValueList::iterator it = this->settings.find(name);
|
||||
if (it != this->settings.end()) {
|
||||
(*it).second = value;
|
||||
} else {
|
||||
this->settings[stredup(name)] = value;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ScriptConfig::SetSetting(name, value);
|
||||
}
|
||||
|
||||
void AIConfig::AddRandomDeviation()
|
||||
{
|
||||
int start_date = this->GetSetting("start_date");
|
||||
|
||||
ScriptConfig::AddRandomDeviation();
|
||||
|
||||
/* start_date = 0 is a special case, where random deviation does not occur.
|
||||
* If start_date was not already 0, then a minimum value of 1 must apply. */
|
||||
this->SetSetting("start_date", start_date != 0 ? std::max(1, this->GetSetting("start_date")) : 0);
|
||||
}
|
||||
|
|
|
@ -24,14 +24,12 @@ public:
|
|||
ScriptConfig()
|
||||
{}
|
||||
|
||||
AIConfig(const AIConfig *config);
|
||||
AIConfig(const AIConfig *config) :
|
||||
ScriptConfig(config)
|
||||
{}
|
||||
|
||||
class AIInfo *GetInfo() const;
|
||||
|
||||
int GetSetting(const char *name) const override;
|
||||
void SetSetting(const char *name, int value) override;
|
||||
void AddRandomDeviation() override;
|
||||
|
||||
/**
|
||||
* When ever the AI Scanner is reloaded, all infos become invalid. This
|
||||
* function tells AIConfig about this.
|
||||
|
@ -43,8 +41,6 @@ public:
|
|||
bool ResetInfo(bool force_exact_match);
|
||||
|
||||
protected:
|
||||
void PushExtraConfigList() override;
|
||||
void ClearConfigList() override;
|
||||
ScriptInfo *FindInfo(const char *name, int version, bool force_exact_match) override;
|
||||
};
|
||||
|
||||
|
|
|
@ -289,17 +289,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
/* static */ int AI::GetStartNextTime()
|
||||
{
|
||||
/* Find the first company which doesn't exist yet */
|
||||
for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
|
||||
if (!Company::IsValidID(c)) return AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->GetSetting("start_date");
|
||||
}
|
||||
|
||||
/* Currently no AI can be started, check again in a year. */
|
||||
return DAYS_IN_YEAR;
|
||||
}
|
||||
|
||||
/* static */ std::string AI::GetConsoleList(bool newest_only)
|
||||
{
|
||||
return AI::scanner_info->GetConsoleList(newest_only);
|
||||
|
|
|
@ -35,11 +35,17 @@ static const NWidgetPart _nested_ai_config_widgets[] = {
|
|||
NWidget(WWT_PANEL, COLOUR_MAUVE, WID_AIC_BACKGROUND),
|
||||
NWidget(NWID_VERTICAL), SetPIP(4, 4, 4),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(7, 0, 7),
|
||||
NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_DECREASE), SetDataTip(AWV_DECREASE, STR_NULL),
|
||||
NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_INCREASE), SetDataTip(AWV_INCREASE, STR_NULL),
|
||||
NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_DECREASE_NUMBER), SetDataTip(AWV_DECREASE, STR_NULL),
|
||||
NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_INCREASE_NUMBER), SetDataTip(AWV_INCREASE, STR_NULL),
|
||||
NWidget(NWID_SPACER), SetMinimalSize(6, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_MAUVE, WID_AIC_NUMBER), SetDataTip(STR_AI_CONFIG_MAX_COMPETITORS, STR_NULL), SetFill(1, 0),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(7, 0, 7),
|
||||
NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_DECREASE_INTERVAL), SetDataTip(AWV_DECREASE, STR_NULL),
|
||||
NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_INCREASE_INTERVAL), SetDataTip(AWV_INCREASE, STR_NULL),
|
||||
NWidget(NWID_SPACER), SetMinimalSize(6, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_MAUVE, WID_AIC_INTERVAL), SetDataTip(STR_AI_CONFIG_COMPETITORS_INTERVAL, STR_NULL), SetFill(1, 0),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_MOVE_UP), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_CONFIG_MOVE_UP, STR_AI_CONFIG_MOVE_UP_TOOLTIP),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_MOVE_DOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_CONFIG_MOVE_DOWN, STR_AI_CONFIG_MOVE_DOWN_TOOLTIP),
|
||||
|
@ -106,14 +112,20 @@ struct AIConfigWindow : public Window {
|
|||
case WID_AIC_NUMBER:
|
||||
SetDParam(0, GetGameSettings().difficulty.max_no_competitors);
|
||||
break;
|
||||
|
||||
case WID_AIC_INTERVAL:
|
||||
SetDParam(0, GetGameSettings().difficulty.competitors_interval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_AIC_DECREASE:
|
||||
case WID_AIC_INCREASE:
|
||||
case WID_AIC_DECREASE_NUMBER:
|
||||
case WID_AIC_INCREASE_NUMBER:
|
||||
case WID_AIC_DECREASE_INTERVAL:
|
||||
case WID_AIC_INCREASE_INTERVAL:
|
||||
*size = maxdim(*size, NWidgetScrollbar::GetHorizontalDimension());
|
||||
break;
|
||||
|
||||
|
@ -179,10 +191,10 @@ struct AIConfigWindow : public Window {
|
|||
}
|
||||
|
||||
switch (widget) {
|
||||
case WID_AIC_DECREASE:
|
||||
case WID_AIC_INCREASE: {
|
||||
case WID_AIC_DECREASE_NUMBER:
|
||||
case WID_AIC_INCREASE_NUMBER: {
|
||||
int new_value;
|
||||
if (widget == WID_AIC_DECREASE) {
|
||||
if (widget == WID_AIC_DECREASE_NUMBER) {
|
||||
new_value = std::max(0, GetGameSettings().difficulty.max_no_competitors - 1);
|
||||
} else {
|
||||
new_value = std::min(MAX_COMPANIES - 1, GetGameSettings().difficulty.max_no_competitors + 1);
|
||||
|
@ -191,6 +203,18 @@ struct AIConfigWindow : public Window {
|
|||
break;
|
||||
}
|
||||
|
||||
case WID_AIC_DECREASE_INTERVAL:
|
||||
case WID_AIC_INCREASE_INTERVAL: {
|
||||
int new_value;
|
||||
if (widget == WID_AIC_DECREASE_INTERVAL) {
|
||||
new_value = std::max(static_cast<int>(MIN_COMPETITORS_INTERVAL), GetGameSettings().difficulty.competitors_interval - 1);
|
||||
} else {
|
||||
new_value = std::min(static_cast<int>(MAX_COMPETITORS_INTERVAL), GetGameSettings().difficulty.competitors_interval + 1);
|
||||
}
|
||||
IConsoleSetSetting("difficulty.competitors_interval", new_value);
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_AIC_LIST: { // Select a slot
|
||||
this->selected_slot = (CompanyID)this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget);
|
||||
this->InvalidateData();
|
||||
|
@ -251,8 +275,10 @@ struct AIConfigWindow : public Window {
|
|||
|
||||
if (!gui_scope) return;
|
||||
|
||||
this->SetWidgetDisabledState(WID_AIC_DECREASE, GetGameSettings().difficulty.max_no_competitors == 0);
|
||||
this->SetWidgetDisabledState(WID_AIC_INCREASE, GetGameSettings().difficulty.max_no_competitors == MAX_COMPANIES - 1);
|
||||
this->SetWidgetDisabledState(WID_AIC_DECREASE_NUMBER, GetGameSettings().difficulty.max_no_competitors == 0);
|
||||
this->SetWidgetDisabledState(WID_AIC_INCREASE_NUMBER, GetGameSettings().difficulty.max_no_competitors == MAX_COMPANIES - 1);
|
||||
this->SetWidgetDisabledState(WID_AIC_DECREASE_INTERVAL, GetGameSettings().difficulty.competitors_interval == MIN_COMPETITORS_INTERVAL);
|
||||
this->SetWidgetDisabledState(WID_AIC_INCREASE_INTERVAL, GetGameSettings().difficulty.competitors_interval == MAX_COMPETITORS_INTERVAL);
|
||||
this->SetWidgetDisabledState(WID_AIC_CHANGE, this->selected_slot == INVALID_COMPANY);
|
||||
this->SetWidgetDisabledState(WID_AIC_CONFIGURE, this->selected_slot == INVALID_COMPANY || AIConfig::GetConfig(this->selected_slot)->GetConfigList()->size() == 0);
|
||||
this->SetWidgetDisabledState(WID_AIC_MOVE_UP, this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot - 1)));
|
||||
|
|
|
@ -69,11 +69,6 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
|
|||
SQInteger res = ScriptInfo::Constructor(vm, info);
|
||||
if (res != 0) return res;
|
||||
|
||||
ScriptConfigItem config = _start_date_config;
|
||||
config.name = stredup(config.name);
|
||||
config.description = stredup(config.description);
|
||||
info->config_list.push_front(config);
|
||||
|
||||
if (info->engine->MethodExists(*info->SQ_instance, "MinVersionToLoad")) {
|
||||
if (!info->engine->CallIntegerMethod(*info->SQ_instance, "MinVersionToLoad", &info->min_loadable_version, MAX_GET_OPS)) return SQ_ERROR;
|
||||
} else {
|
||||
|
|
|
@ -170,7 +170,6 @@ struct Company : CompanyProperties, CompanyPool::PoolItem<&_company_pool> {
|
|||
Money CalculateCompanyValue(const Company *c, bool including_loan = true);
|
||||
Money CalculateCompanyValueExcludingShares(const Company *c, bool including_loan = true);
|
||||
|
||||
extern uint _next_competitor_start;
|
||||
extern uint _cur_company_tick_index;
|
||||
|
||||
#endif /* COMPANY_BASE_H */
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "company_cmd.h"
|
||||
#include "timer/timer.h"
|
||||
#include "timer/timer_game_calendar.h"
|
||||
#include "timer/timer_game_tick.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
|
@ -50,7 +51,6 @@ CompanyID _local_company; ///< Company controlled by the human player at this
|
|||
CompanyID _current_company; ///< Company currently doing an action.
|
||||
Colours _company_colours[MAX_COMPANIES]; ///< NOSAVE: can be determined from company structs.
|
||||
CompanyManagerFace _company_manager_face; ///< for company manager face storage in openttd.cfg
|
||||
uint _next_competitor_start; ///< the number of ticks before the next AI is started
|
||||
uint _cur_company_tick_index; ///< used to generate a name for one company that doesn't have a name yet per tick
|
||||
|
||||
CompanyPool _company_pool("Company"); ///< Pool of companies.
|
||||
|
@ -599,16 +599,10 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY)
|
|||
return c;
|
||||
}
|
||||
|
||||
/** Start the next competitor now. */
|
||||
void StartupCompanies()
|
||||
{
|
||||
_next_competitor_start = 0;
|
||||
}
|
||||
|
||||
/** Start a new competitor company if possible. */
|
||||
static bool MaybeStartNewCompany()
|
||||
{
|
||||
if (_networking && Company::GetNumItems() >= _settings_client.network.max_companies) return false;
|
||||
TimeoutTimer<TimerGameTick> _new_competitor_timeout(0, []() {
|
||||
if (_game_mode == GM_MENU || !AI::CanStartNew()) return;
|
||||
if (_networking && Company::GetNumItems() >= _settings_client.network.max_companies) return;
|
||||
|
||||
/* count number of competitors */
|
||||
uint n = 0;
|
||||
|
@ -616,13 +610,26 @@ static bool MaybeStartNewCompany()
|
|||
if (c->is_ai) n++;
|
||||
}
|
||||
|
||||
if (n < (uint)_settings_game.difficulty.max_no_competitors) {
|
||||
/* Send a command to all clients to start up a new AI.
|
||||
* Works fine for Multiplayer and Singleplayer */
|
||||
return Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID );
|
||||
}
|
||||
if (n >= (uint)_settings_game.difficulty.max_no_competitors) return;
|
||||
|
||||
return false;
|
||||
/* Send a command to all clients to start up a new AI.
|
||||
* Works fine for Multiplayer and Singleplayer */
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID);
|
||||
});
|
||||
|
||||
/** Start of a new game. */
|
||||
void StartupCompanies()
|
||||
{
|
||||
/* Ensure the timeout is aborted, so it doesn't fire based on information of the last game. */
|
||||
_new_competitor_timeout.Abort();
|
||||
|
||||
/* If there is no delay till the start of the next competitor, start all competitors at the start of the game. */
|
||||
if (_settings_game.difficulty.competitors_interval == 0 && _game_mode != GM_MENU && AI::CanStartNew()) {
|
||||
for (auto i = 0; i < _settings_game.difficulty.max_no_competitors; i++) {
|
||||
if (_networking && Company::GetNumItems() >= _settings_client.network.max_companies) break;
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Initialize the pool of companies. */
|
||||
|
@ -722,20 +729,15 @@ void OnTick_Companies()
|
|||
if (c->bankrupt_asked != 0) HandleBankruptcyTakeover(c);
|
||||
}
|
||||
|
||||
if (_next_competitor_start == 0) {
|
||||
/* AI::GetStartNextTime() can return 0. */
|
||||
_next_competitor_start = std::max(1, AI::GetStartNextTime() * DAY_TICKS);
|
||||
}
|
||||
if (_new_competitor_timeout.HasFired() && _game_mode != GM_MENU && AI::CanStartNew()) {
|
||||
int32 timeout = _settings_game.difficulty.competitors_interval * 60 * TICKS_PER_SECOND;
|
||||
/* If the interval is zero, check every ~10 minutes if a company went bankrupt and needs replacing. */
|
||||
if (timeout == 0) timeout = 10 * 60 * TICKS_PER_SECOND;
|
||||
|
||||
if (_game_mode != GM_MENU && AI::CanStartNew() && --_next_competitor_start == 0) {
|
||||
/* Allow multiple AIs to possibly start in the same tick. */
|
||||
do {
|
||||
if (!MaybeStartNewCompany()) break;
|
||||
/* Randomize a bit when the AI is actually going to start; ranges from 87.5% .. 112.5% of indicated value. */
|
||||
timeout += ScriptObject::GetRandomizer(OWNER_NONE).Next(timeout / 4) - timeout / 8;
|
||||
|
||||
/* In networking mode, we can only send a command to start but it
|
||||
* didn't execute yet, so we cannot loop. */
|
||||
if (_networking) break;
|
||||
} while (AI::GetStartNextTime() == 0);
|
||||
_new_competitor_timeout.Reset(std::max(1, timeout));
|
||||
}
|
||||
|
||||
_cur_company_tick_index = (_cur_company_tick_index + 1) % MAX_COMPANIES;
|
||||
|
|
|
@ -42,6 +42,9 @@ static const uint MAX_LENGTH_COMPANY_NAME_CHARS = 32; ///< The maximum length
|
|||
static const uint MAX_HISTORY_QUARTERS = 24; ///< The maximum number of quarters kept as performance's history
|
||||
static const uint MAX_COMPANY_SHARE_OWNERS = 4; ///< The maximum number of shares of a company that can be owned by another company.
|
||||
|
||||
static const uint MIN_COMPETITORS_INTERVAL = 0; ///< The minimum interval (in minutes) between competitors.
|
||||
static const uint MAX_COMPETITORS_INTERVAL = 500; ///< The maximum interval (in minutes) between competitors.
|
||||
|
||||
/** Define basic enum properties */
|
||||
template <> struct EnumPropsT<Owner> : MakeEnumPropsT<Owner, byte, OWNER_BEGIN, OWNER_END, INVALID_OWNER> {};
|
||||
|
||||
|
|
|
@ -4592,6 +4592,7 @@ STR_AI_CONFIG_RANDOM_AI :Random AI
|
|||
STR_AI_CONFIG_NONE :(none)
|
||||
STR_AI_CONFIG_NAME_VERSION :{RAW_STRING} {YELLOW}v{NUM}
|
||||
STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maximum no. competitors: {ORANGE}{COMMA}
|
||||
STR_AI_CONFIG_COMPETITORS_INTERVAL :{LTBLUE}Interval between starting of competitors: {ORANGE}{COMMA} minute{P "" s}
|
||||
|
||||
STR_AI_CONFIG_MOVE_UP :{BLACK}Move Up
|
||||
STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Move selected AI up in the list
|
||||
|
@ -4638,7 +4639,6 @@ STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Game Script
|
|||
STR_AI_SETTINGS_CLOSE :{BLACK}Close
|
||||
STR_AI_SETTINGS_RESET :{BLACK}Reset
|
||||
STR_AI_SETTINGS_SETTING :{RAW_STRING}: {ORANGE}{STRING1}
|
||||
STR_AI_SETTINGS_START_DELAY :Number of days to start this AI after the previous one (give or take): {ORANGE}{STRING1}
|
||||
|
||||
|
||||
# Textfile window
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#include "misc_cmd.h"
|
||||
#include "timer/timer.h"
|
||||
#include "timer/timer_game_calendar.h"
|
||||
#include "timer/timer_game_tick.h"
|
||||
|
||||
#include "linkgraph/linkgraphschedule.h"
|
||||
|
||||
|
@ -1419,6 +1420,7 @@ void StateGameLoop()
|
|||
BasePersistentStorageArray::SwitchMode(PSM_ENTER_GAMELOOP);
|
||||
AnimateAnimatedTiles();
|
||||
TimerManager<TimerGameCalendar>::Elapsed(1);
|
||||
TimerManager<TimerGameTick>::Elapsed(1);
|
||||
RunTileLoop();
|
||||
CallVehicleTicks();
|
||||
CallLandscapeTick();
|
||||
|
|
|
@ -58,6 +58,8 @@
|
|||
#include "../disaster_vehicle.h"
|
||||
#include "../ship.h"
|
||||
#include "../water.h"
|
||||
#include "../timer/timer.h"
|
||||
#include "../timer/timer_game_tick.h"
|
||||
|
||||
#include "saveload_internal.h"
|
||||
|
||||
|
@ -3259,6 +3261,16 @@ bool AfterLoadGame()
|
|||
for (Station *st : Station::Iterate()) UpdateStationAcceptance(st, false);
|
||||
}
|
||||
|
||||
if (IsSavegameVersionBefore(SLV_AI_START_DATE)) {
|
||||
/* For older savegames, we don't now the actual interval; so set it to the newgame value. */
|
||||
_settings_game.difficulty.competitors_interval = _settings_newgame.difficulty.competitors_interval;
|
||||
|
||||
/* We did load the "period" of the timer, but not the fired/elapsed. We can deduce that here. */
|
||||
extern TimeoutTimer<TimerGameTick> _new_competitor_timeout;
|
||||
_new_competitor_timeout.storage.elapsed = 0;
|
||||
_new_competitor_timeout.fired = _new_competitor_timeout.period == 0;
|
||||
}
|
||||
|
||||
AfterLoadLabelMaps();
|
||||
AfterLoadCompanyStats();
|
||||
AfterLoadStoryBook();
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "../gfx_func.h"
|
||||
#include "../core/random_func.hpp"
|
||||
#include "../fios.h"
|
||||
#include "../timer/timer.h"
|
||||
#include "../timer/timer_game_tick.h"
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
|
@ -67,6 +69,7 @@ void ResetViewportAfterLoadGame()
|
|||
}
|
||||
|
||||
byte _age_cargo_skip_counter; ///< Skip aging of cargo? Used before savegame version 162.
|
||||
extern TimeoutTimer<TimerGameTick> _new_competitor_timeout;
|
||||
|
||||
static const SaveLoad _date_desc[] = {
|
||||
SLEG_CONDVAR("date", _date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
|
||||
|
@ -81,10 +84,14 @@ static const SaveLoad _date_desc[] = {
|
|||
SLEG_VAR("random_state[0]", _random.state[0], SLE_UINT32),
|
||||
SLEG_VAR("random_state[1]", _random.state[1], SLE_UINT32),
|
||||
SLEG_VAR("company_tick_counter", _cur_company_tick_index, SLE_FILE_U8 | SLE_VAR_U32),
|
||||
SLEG_CONDVAR("next_competitor_start", _next_competitor_start, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_109),
|
||||
SLEG_CONDVAR("next_competitor_start", _next_competitor_start, SLE_UINT32, SLV_109, SL_MAX_VERSION),
|
||||
SLEG_VAR("trees_tick_counter", _trees_tick_ctr, SLE_UINT8),
|
||||
SLEG_CONDVAR("pause_mode", _pause_mode, SLE_UINT8, SLV_4, SL_MAX_VERSION),
|
||||
/* For older savegames, we load the current value as the "period"; afterload will set the "fired" and "elapsed". */
|
||||
SLEG_CONDVAR("next_competitor_start", _new_competitor_timeout.period, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_109),
|
||||
SLEG_CONDVAR("next_competitor_start", _new_competitor_timeout.period, SLE_UINT32, SLV_109, SLV_AI_START_DATE),
|
||||
SLEG_CONDVAR("competitors_interval", _new_competitor_timeout.period, SLE_UINT32, SLV_AI_START_DATE, SL_MAX_VERSION),
|
||||
SLEG_CONDVAR("competitors_interval_elapsed", _new_competitor_timeout.storage.elapsed, SLE_UINT32, SLV_AI_START_DATE, SL_MAX_VERSION),
|
||||
SLEG_CONDVAR("competitors_interval_fired", _new_competitor_timeout.fired, SLE_BOOL, SLV_AI_START_DATE, SL_MAX_VERSION),
|
||||
};
|
||||
|
||||
static const SaveLoad _date_check_desc[] = {
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "../company_base.h"
|
||||
#include "../disaster_vehicle.h"
|
||||
#include "../core/smallvec_type.hpp"
|
||||
#include "../timer/timer.h"
|
||||
#include "../timer/timer_game_tick.h"
|
||||
#include "saveload_internal.h"
|
||||
#include "oldloader.h"
|
||||
#include <array>
|
||||
|
@ -489,6 +491,7 @@ static inline uint RemapOrderIndex(uint x)
|
|||
}
|
||||
|
||||
extern std::vector<TileIndex> _animated_tiles;
|
||||
extern TimeoutTimer<TimerGameTick> _new_competitor_timeout;
|
||||
extern char *_old_name_array;
|
||||
|
||||
static uint32 _old_town_index;
|
||||
|
@ -1677,7 +1680,7 @@ static const OldChunks main_chunk[] = {
|
|||
|
||||
OCL_ASSERT( OC_TTO, 0x496CE ),
|
||||
|
||||
OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_next_competitor_start ),
|
||||
OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_new_competitor_timeout.period ),
|
||||
|
||||
OCL_CNULL( OC_TTO, 2 ), ///< available monorail bitmask
|
||||
|
||||
|
|
|
@ -351,6 +351,7 @@ enum SaveLoadVersion : uint16 {
|
|||
SLV_CONSISTENT_PARTIAL_Z, ///< 306 PR#10570 Conversion from an inconsistent partial Z calculation for slopes, to one that is (more) consistent.
|
||||
SLV_MORE_CARGO_AGE, ///< 307 PR#10596 Track cargo age for a longer period.
|
||||
SLV_LINKGRAPH_SECONDS, ///< 308 PR#10610 Store linkgraph update intervals in seconds instead of days.
|
||||
SLV_AI_START_DATE, ///< 309 PR#10653 Removal of individual AI start dates and added a generic one.
|
||||
|
||||
SL_MAX_VERSION, ///< Highest possible saveload version
|
||||
};
|
||||
|
|
|
@ -26,7 +26,6 @@ void ScriptConfig::Change(const char *name, int version, bool force_exact_match,
|
|||
this->is_random = is_random;
|
||||
if (this->config_list != nullptr) delete this->config_list;
|
||||
this->config_list = (info == nullptr) ? nullptr : new ScriptConfigItemList();
|
||||
if (this->config_list != nullptr) this->PushExtraConfigList();
|
||||
this->to_load_data.reset();
|
||||
|
||||
this->ClearConfigList();
|
||||
|
@ -79,7 +78,6 @@ const ScriptConfigItemList *ScriptConfig::GetConfigList()
|
|||
if (this->info != nullptr) return this->info->GetConfigList();
|
||||
if (this->config_list == nullptr) {
|
||||
this->config_list = new ScriptConfigItemList();
|
||||
this->PushExtraConfigList();
|
||||
}
|
||||
return this->config_list;
|
||||
}
|
||||
|
|
|
@ -51,8 +51,6 @@ struct ScriptConfigItem {
|
|||
|
||||
typedef std::list<ScriptConfigItem> ScriptConfigItemList; ///< List of ScriptConfig items.
|
||||
|
||||
extern ScriptConfigItem _start_date_config;
|
||||
|
||||
/**
|
||||
* Script settings.
|
||||
*/
|
||||
|
@ -127,12 +125,12 @@ public:
|
|||
* @return The (default) value of the setting, or -1 if the setting was not
|
||||
* found.
|
||||
*/
|
||||
virtual int GetSetting(const char *name) const;
|
||||
int GetSetting(const char *name) const;
|
||||
|
||||
/**
|
||||
* Set the value of a setting for this config.
|
||||
*/
|
||||
virtual void SetSetting(const char *name, int value);
|
||||
void SetSetting(const char *name, int value);
|
||||
|
||||
/**
|
||||
* Reset all settings to their default value.
|
||||
|
@ -147,7 +145,7 @@ public:
|
|||
/**
|
||||
* Randomize all settings the Script requested to be randomized.
|
||||
*/
|
||||
virtual void AddRandomDeviation();
|
||||
void AddRandomDeviation();
|
||||
|
||||
/**
|
||||
* Is this config attached to an Script? In other words, is there a Script
|
||||
|
@ -202,16 +200,10 @@ protected:
|
|||
bool is_random; ///< True if the AI in this slot was randomly chosen.
|
||||
std::unique_ptr<ScriptInstance::ScriptData> to_load_data; ///< Data to load after the Script start.
|
||||
|
||||
/**
|
||||
* In case you have mandatory non-Script-definable config entries in your
|
||||
* list, add them to this function.
|
||||
*/
|
||||
virtual void PushExtraConfigList() {};
|
||||
|
||||
/**
|
||||
* Routine that clears the config list.
|
||||
*/
|
||||
virtual void ClearConfigList();
|
||||
void ClearConfigList();
|
||||
|
||||
/**
|
||||
* This function should call back to the Scanner in charge of this Config,
|
||||
|
|
|
@ -379,14 +379,8 @@ struct ScriptSettingsWindow : public Window {
|
|||
TextColour colour;
|
||||
uint idx = 0;
|
||||
if (StrEmpty(config_item.description)) {
|
||||
if (this->slot != OWNER_DEITY && !strcmp(config_item.name, "start_date")) {
|
||||
/* Build-in translation */
|
||||
str = STR_AI_SETTINGS_START_DELAY;
|
||||
colour = TC_LIGHT_BLUE;
|
||||
} else {
|
||||
str = STR_JUST_STRING;
|
||||
colour = TC_ORANGE;
|
||||
}
|
||||
str = STR_JUST_STRING;
|
||||
colour = TC_ORANGE;
|
||||
} else {
|
||||
str = STR_AI_SETTINGS_SETTING;
|
||||
colour = TC_LIGHT_BLUE;
|
||||
|
|
|
@ -76,6 +76,7 @@ struct DifficultySettings {
|
|||
byte competitor_intelligence; ///< Unused value, used to load old savegames.
|
||||
|
||||
byte max_no_competitors; ///< the number of competitors (AIs)
|
||||
uint16 competitors_interval; ///< the interval (in minutes) between adding competitors
|
||||
byte number_towns; ///< the amount of towns
|
||||
byte industry_density; ///< The industry density. @see IndustryDensity
|
||||
uint32 max_loan; ///< the maximum initial loan
|
||||
|
|
|
@ -57,6 +57,15 @@ interval = 1
|
|||
post_cb = MaxNoAIsChange
|
||||
cat = SC_BASIC
|
||||
|
||||
[SDT_VAR]
|
||||
var = difficulty.competitors_interval
|
||||
type = SLE_UINT16
|
||||
from = SLV_AI_START_DATE
|
||||
def = 10
|
||||
min = MIN_COMPETITORS_INTERVAL
|
||||
max = MAX_COMPETITORS_INTERVAL
|
||||
interval = 1
|
||||
|
||||
[SDT_VAR]
|
||||
var = difficulty.competitor_start_time
|
||||
type = SLE_UINT8
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
add_files(
|
||||
timer_game_calendar.cpp
|
||||
timer_game_calendar.h
|
||||
timer_game_tick.cpp
|
||||
timer_game_tick.h
|
||||
timer_window.cpp
|
||||
timer_window.h
|
||||
timer_manager.h
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file timer_game_tick.cpp
|
||||
* This file implements the timer logic for the tick-based game-timer.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "timer.h"
|
||||
#include "timer_game_tick.h"
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
template<>
|
||||
void IntervalTimer<TimerGameTick>::Elapsed(TimerGameTick::TElapsed delta)
|
||||
{
|
||||
if (this->period == 0) return;
|
||||
|
||||
this->storage.elapsed += delta;
|
||||
|
||||
uint count = 0;
|
||||
while (this->storage.elapsed >= this->period) {
|
||||
this->storage.elapsed -= this->period;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
this->callback(count);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void TimeoutTimer<TimerGameTick>::Elapsed(TimerGameTick::TElapsed delta)
|
||||
{
|
||||
if (this->fired) return;
|
||||
if (this->period == 0) return;
|
||||
|
||||
this->storage.elapsed += delta;
|
||||
|
||||
if (this->storage.elapsed >= this->period) {
|
||||
this->callback();
|
||||
this->fired = true;
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void TimerManager<TimerGameTick>::Elapsed(TimerGameTick::TElapsed delta)
|
||||
{
|
||||
for (auto timer : TimerManager<TimerGameTick>::GetTimers()) {
|
||||
timer->Elapsed(delta);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_ASSERT
|
||||
template<>
|
||||
void TimerManager<TimerGameTick>::Validate(TimerGameTick::TPeriod period)
|
||||
{
|
||||
}
|
||||
#endif /* WITH_ASSERT */
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file timer_game_tick.h Definition of the tick-based game-timer */
|
||||
|
||||
#ifndef TIMER_GAME_TICK_H
|
||||
#define TIMER_GAME_TICK_H
|
||||
|
||||
#include "gfx_type.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
/** Estimation of how many ticks fit in a single second. */
|
||||
static const uint TICKS_PER_SECOND = 1000 / MILLISECONDS_PER_TICK;
|
||||
|
||||
/**
|
||||
* Timer that represents the game-ticks. It will pause when the game is paused.
|
||||
*
|
||||
* @note Callbacks are executed in the game-thread.
|
||||
*/
|
||||
class TimerGameTick {
|
||||
public:
|
||||
using TPeriod = uint;
|
||||
using TElapsed = uint;
|
||||
struct TStorage {
|
||||
uint elapsed;
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* TIMER_GAME_TICK_H */
|
|
@ -15,9 +15,12 @@
|
|||
/** Widgets of the #AIConfigWindow class. */
|
||||
enum AIConfigWidgets {
|
||||
WID_AIC_BACKGROUND, ///< Window background.
|
||||
WID_AIC_DECREASE, ///< Decrease the number of AIs.
|
||||
WID_AIC_INCREASE, ///< Increase the number of AIs.
|
||||
WID_AIC_DECREASE_NUMBER, ///< Decrease the number of AIs.
|
||||
WID_AIC_INCREASE_NUMBER, ///< Increase the number of AIs.
|
||||
WID_AIC_NUMBER, ///< Number of AIs.
|
||||
WID_AIC_DECREASE_INTERVAL,///< Decrease the interval.
|
||||
WID_AIC_INCREASE_INTERVAL,///< Increase the interval.
|
||||
WID_AIC_INTERVAL, ///< Interval between time AIs start.
|
||||
WID_AIC_LIST, ///< List with currently selected AIs.
|
||||
WID_AIC_SCROLLBAR, ///< Scrollbar to scroll through the selected AIs.
|
||||
WID_AIC_MOVE_UP, ///< Move up button.
|
||||
|
|
Loading…
Reference in New Issue