diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..86e403eb03 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,89 @@ +# Build and deployment notes + +This repository produces the game executable used by `B:\VictoriaModernAges`. +The release must always contain three matching CPU variants: + +| Build preset | Installed filename | CPU requirement | +| --- | --- | --- | +| `x64-release-sse-windows` | `AliceSSE.exe` | SSE4.2 | +| `x64-release-avx2-windows` | `Alice.exe` | AVX2 | +| `x64-release-avx512-windows` | `Alice512.exe` | AVX-512F | + +The stock `launch_alice.exe` detects the processor and chooses these names in +that order. Build the launcher from the SSE4.2 preset and deploy it together +with the game executables whenever scenario data structures or parsers change. +The launcher serializes scenarios, so an old launcher is not compatible with a +new executable after a change to `src/gamestate/dcon_generated.txt`. + +## Default development workflow + +Unless the user explicitly asks for a **release build**, use only the +SSE4.2 `AliceIncremental` target. Do not build AVX2, AVX-512, or the launcher, +and do not copy executables into `B:\VictoriaModernAges` as part of ordinary +development or testing. + +`Alice` is intentionally compiled as one large translation unit; even a small +source change can therefore trigger a lengthy rebuild. `AliceIncremental` +splits the game into many translation units so that incremental recompiles are +much faster. It is a development/testing executable, not a release artifact. + +Configure the SSE4.2 tree once if it does not already exist: + +```powershell +cmd /d /s /c 'call "C:\BuildTools\Common7\Tools\VsDevCmd.bat" -arch=x64 -host_arch=x64 >nul && cmake --preset x64-release-sse-windows' +``` + +For each normal code change, build only this target: + +```powershell +cmd /d /s /c 'call "C:\BuildTools\Common7\Tools\VsDevCmd.bat" -arch=x64 -host_arch=x64 >nul && cmake --build out/build/x64-release-sse-windows --config Release --target AliceIncremental --parallel 6' +``` + +The test executable is +`out\build\x64-release-sse-windows\Release\AliceIncremental.exe`. Run it +with `B:\VictoriaModernAges` as its working directory so it can access the +game data. The first incremental build may still take a while; subsequent +builds should recompile only affected source files. + +## Release builds only + +Perform the following procedure only after the user explicitly requests a +release build. A release must include all three CPU variants and, when needed, +the matching launcher. + +Configure and build each game variant: + +```powershell +cmd /d /s /c 'call "C:\BuildTools\Common7\Tools\VsDevCmd.bat" -arch=x64 -host_arch=x64 >nul && cmake --preset x64-release-sse-windows' +cmd /d /s /c 'call "C:\BuildTools\Common7\Tools\VsDevCmd.bat" -arch=x64 -host_arch=x64 >nul && cmake --build out/build/x64-release-sse-windows --config Release --target Alice --parallel 6' + +cmd /d /s /c 'call "C:\BuildTools\Common7\Tools\VsDevCmd.bat" -arch=x64 -host_arch=x64 >nul && cmake --preset x64-release-avx2-windows' +cmd /d /s /c 'call "C:\BuildTools\Common7\Tools\VsDevCmd.bat" -arch=x64 -host_arch=x64 >nul && cmake --build out/build/x64-release-avx2-windows --config Release --target Alice --parallel 6' + +cmd /d /s /c 'call "C:\BuildTools\Common7\Tools\VsDevCmd.bat" -arch=x64 -host_arch=x64 >nul && cmake --preset x64-release-avx512-windows' +cmd /d /s /c 'call "C:\BuildTools\Common7\Tools\VsDevCmd.bat" -arch=x64 -host_arch=x64 >nul && cmake --build out/build/x64-release-avx512-windows --config Release --target Alice --parallel 6' +``` + +Build the launcher once from the SSE4.2 tree: + +```powershell +cmd /d /s /c 'call "C:\BuildTools\Common7\Tools\VsDevCmd.bat" -arch=x64 -host_arch=x64 >nul && cmake --build out/build/x64-release-sse-windows --config Release --target launch_alice --parallel 6' +``` + +The parser and data-container generators are intentionally compiled for +SSE4.2. This allows the build to run on a machine without AVX2 while still +producing the AVX2 and AVX-512 game variants. + +The presets deliberately set `ALICE_ENABLE_LTCG=OFF` so all three compatible +executables can be produced promptly. Set it to `ON` only for a slower, +performance-focused rebuild; it does not affect format compatibility. + +## Deployment and verification + +1. Back up the four installed executables before replacing them. +2. Copy each generated `Release/Alice.exe` to the matching installed filename + above, and copy the SSE-built `Launcher/Release/launch_alice.exe` to the + game root. +3. Do not delete existing scenario cache files. Use the launcher to create a + fresh scenario after a change to scenario-tagged data. The cache is at + `%USERPROFILE%\Documents\Project Alice\scenarios`. diff --git a/CMakeLists.txt b/CMakeLists.txt index d47abcec76..c796db5678 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,28 @@ project (ProjectAlice LANGUAGES CXX C) set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use") set(CMAKE_CXX_STANDARD_REQUIRED ON) +# Windows releases are distributed in three CPU-specific variants. Keep the +# launcher on SSE4.2 so it can run on every supported machine and choose the +# correct game executable itself. +set(ALICE_CPU_TARGET "SSE42" CACHE STRING "CPU target for Alice (SSE42, AVX2, or AVX512)") +set_property(CACHE ALICE_CPU_TARGET PROPERTY STRINGS SSE42 AVX2 AVX512) +option(ALICE_ENABLE_LTCG "Enable MSVC link-time code generation for release builds" OFF) +if(MSVC) + if(ALICE_CPU_TARGET STREQUAL "SSE42") + set(ALICE_CPU_ARCH_FLAG /d2archSSE42) + elseif(ALICE_CPU_TARGET STREQUAL "AVX2") + set(ALICE_CPU_ARCH_FLAG /arch:AVX2) + elseif(ALICE_CPU_TARGET STREQUAL "AVX512") + set(ALICE_CPU_ARCH_FLAG /arch:AVX512) + else() + message(FATAL_ERROR "ALICE_CPU_TARGET must be SSE42, AVX2, or AVX512") + endif() + if(ALICE_ENABLE_LTCG) + set(ALICE_LTCG_COMPILE_FLAG /GL) + set(ALICE_LTCG_LINK_FLAG /LTCG) + endif() +endif() + # Turn on compile_commands.json export for wider editor/IDE support. # This option is ignored on anything but Unix makefiles/Ninja. set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -307,6 +329,12 @@ add_library(AliceCommon INTERFACE) target_compile_definitions(AliceCommon INTERFACE GLM_ENABLE_EXPERIMENTAL) target_compile_definitions(AliceCommon INTERFACE "PROJECT_ROOT=\"${PROJECT_SOURCE_DIR}\"") if(WIN32) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + # MSBuild batches Alice's large source files into one cl.exe invocation. + # /MP lets MSVC compile that batch concurrently and honours the host's + # normal processor limit. + target_compile_options(AliceCommon INTERFACE /MP) + endif() # string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # string(REPLACE "/W3" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # string(REPLACE "/MDd" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) @@ -315,8 +343,7 @@ if(WIN32) # string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) - # To build Non-AVX version : change all "/arch:AVX2" to "/d2archSSE42" - # -march=nehalem for clang release + # ALICE_CPU_ARCH_FLAG selects SSE4.2, AVX2, or AVX-512 for the MSVC builds. set(CMAKE_CXX_FLAGS "") set(CMAKE_CXX_FLAGS_DEBUG "") set(CMAKE_CXX_FLAGS_RELEASE "") @@ -362,36 +389,28 @@ if(WIN32) if(OPTIMIZE_MODE STREQUAL "On") message(STATUS "Optimizing with PGO data") target_compile_options(AliceCommon INTERFACE - ${CommonMSVCFlags} /wd4723 /d2archSSE42 /DNDEBUG /wd4530 /MT /O2 /Oi /GL /sdl- /GS- /Gy /Gw /Zc:inline) - target_link_options(AliceCommon INTERFACE /OPT:REF /OPT:ICF /LTCG /USEPROFILE) + ${CommonMSVCFlags} /wd4723 ${ALICE_CPU_ARCH_FLAG} /DNDEBUG /wd4530 /MT /O2 /Oi ${ALICE_LTCG_COMPILE_FLAG} /sdl- /GS- /Gy /Gw /Zc:inline) + target_link_options(AliceCommon INTERFACE /OPT:REF /OPT:ICF ${ALICE_LTCG_LINK_FLAG} /USEPROFILE) elseif(PROFILE_MODE STREQUAL "On") message(STATUS "Compiling for PGO instrumentation") target_compile_options(AliceCommon INTERFACE - ${CommonMSVCFlags} /wd4723 /d2archSSE42 /Z7 /DNDEBUG /wd4530 /MT /O2 /Oi /GL /sdl- /GS- /Gy /Gw /Zc:inline) + ${CommonMSVCFlags} /wd4723 ${ALICE_CPU_ARCH_FLAG} /Z7 /DNDEBUG /wd4530 /MT /O2 /Oi ${ALICE_LTCG_COMPILE_FLAG} /sdl- /GS- /Gy /Gw /Zc:inline) target_link_options(AliceCommon INTERFACE /DEBUG:FULL /OPT:REF /OPT:ICF /LTCG /GENPROFILE) else() message(STATUS "Normal, not PGO, build") target_compile_options(AliceCommon INTERFACE - ${CommonMSVCFlags} /Z7 - $<$: /EHsc /MTd /RTC1 /Od> + ${CommonMSVCFlags} ${ALICE_CPU_ARCH_FLAG} /Z7 + $<$: /EHsc /MTd /RTC1 /Od> # for faster debug builds, replace /RTC1 /Od with /O1 -- should be able to use /Ox, but for some reason that crashes ZSTD - $<$>: /DNDEBUG /wd4530 /MT /O2 /Oi /GL /sdl- /GS- /Gy /Gw /Zc:inline>) + $<$>: /DNDEBUG /wd4530 /MT /O2 /Oi ${ALICE_LTCG_COMPILE_FLAG} /sdl- /GS- /Gy /Gw /Zc:preprocessor /Zc:inline>) target_link_options(AliceCommon INTERFACE $<$: /DEBUG:FULL > - $<$>: /DEBUG:FULL /OPT:REF /OPT:ICF /LTCG>) + $<$>: /DEBUG:FULL /OPT:REF /OPT:ICF ${ALICE_LTCG_LINK_FLAG}>) endif() - if(VECTOR_MODE STREQUAL "AVX512") - target_compile_options(AliceCommon INTERFACE - /arch:AVX512 ) - elseif(VECTOR_MODE STREQUAL "AVX2") - target_compile_options(AliceCommon INTERFACE - /arch:AVX2 ) - else() - # No /fp:precise here since from my testing, seperate executables generated with Clang and MSVC will not be deterministic between eachother anyway no matter the flags. Both builds must be compiled with clang to get some level of float determinism - target_compile_options(AliceCommon INTERFACE - /d2archSSE42 ) - endif() + # The distribution presets set this once; do not append a VECTOR_MODE flag + # afterwards, or it would override the selected AVX target. + target_compile_options(AliceCommon INTERFACE ${ALICE_CPU_ARCH_FLAG}) diff --git a/CMakePresets.json b/CMakePresets.json index dd59e5bcf5..5c784ef154 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -22,7 +22,8 @@ "hidden": true, "cacheVariables": { "CMAKE_C_COMPILER": "cl.exe", - "CMAKE_CXX_COMPILER": "cl.exe" + "CMAKE_CXX_COMPILER": "cl.exe", + "CMAKE_POLICY_VERSION_MINIMUM": "3.5" }, "condition": { "type": "equals", @@ -96,6 +97,36 @@ "VECTOR_MODE": "AVX512" } }, + { + "name": "x64-release-sse-windows", + "displayName": "x64 Release (SSE4.2)", + "inherits": "windows-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "ALICE_CPU_TARGET": "SSE42", + "ALICE_ENABLE_LTCG": "OFF" + } + }, + { + "name": "x64-release-avx2-windows", + "displayName": "x64 Release (AVX2)", + "inherits": "windows-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "ALICE_CPU_TARGET": "AVX2", + "ALICE_ENABLE_LTCG": "OFF" + } + }, + { + "name": "x64-release-avx512-windows", + "displayName": "x64 Release (AVX-512)", + "inherits": "windows-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "ALICE_CPU_TARGET": "AVX512", + "ALICE_ENABLE_LTCG": "OFF" + } + }, { "name": "x64-profile-windows-sse", "displayName": "x64 Release (profile SSE)", diff --git a/FifInterfaceGenerator/CMakeLists.txt b/FifInterfaceGenerator/CMakeLists.txt index a283fe259e..fcccc6e3ad 100644 --- a/FifInterfaceGenerator/CMakeLists.txt +++ b/FifInterfaceGenerator/CMakeLists.txt @@ -17,7 +17,7 @@ if(WIN32) if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") target_compile_options(DCONINTERFACEGEN PRIVATE - /bigobj /wd4100 /wd4189 /wd4065 /GR- /W4 /permissive- /WX /arch:AVX2 /GF /w34388 /w34389 + /bigobj /wd4100 /wd4189 /wd4065 /GR- /W4 /permissive- /WX /d2archSSE42 /GF /w34388 /w34389 -Wno-missing-prototypes -Wno-unsafe-buffer-usage -Wno-switch-default -Wno-padded -Wno-unique-object-duplication $<$: /RTC1 /EHsc /MTd /Od /RTC1> $<$>: /DNDEBUG /wd4530 /MT /O2 /Oi /sdl- /GS- /Gy /Gw /Zc:inline>) @@ -26,7 +26,7 @@ if(WIN32) $<$>: /OPT:REF /OPT:ICF /LTCG>) else() target_compile_options(DCONINTERFACEGEN PRIVATE - /bigobj /wd4100 /wd4189 /wd4065 /GR- /W4 /permissive- /Zc:preprocessor /WX /arch:AVX2 /GF /w34388 /w34389 + /bigobj /wd4100 /wd4189 /wd4065 /GR- /W4 /permissive- /Zc:preprocessor /WX /d2archSSE42 /GF /w34388 /w34389 $<$: /RTC1 /EHsc /MTd /Od /RTC1> $<$>: /DNDEBUG /wd4530 /MT /O2 /Oi /GL /sdl- /Zc:preprocessor /GS- /Gy /Gw /Zc:inline>) target_link_options(DCONINTERFACEGEN PRIVATE @@ -42,4 +42,3 @@ else() # GCC or CLANG $<$: $<$: > $<$>: >>) endif() - diff --git a/ParserGenerator/CMakeLists.txt b/ParserGenerator/CMakeLists.txt index 76307867b2..e3e4bc97b4 100644 --- a/ParserGenerator/CMakeLists.txt +++ b/ParserGenerator/CMakeLists.txt @@ -15,7 +15,7 @@ if(WIN32) if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") target_compile_options(ParserGenerator PRIVATE - /bigobj /wd4100 /wd4189 /wd4065 /GR- /W4 /permissive- /WX /arch:AVX2 /GF /w34388 /w34389 + /bigobj /wd4100 /wd4189 /wd4065 /GR- /W4 /permissive- /WX /d2archSSE42 /GF /w34388 /w34389 -Wno-missing-prototypes -Wno-unsafe-buffer-usage -Wno-switch-default -Wno-padded -Wno-unique-object-duplication -Wno-nrvo $<$: /RTC1 /EHsc /MTd /Od /RTC1> $<$>: /DNDEBUG /wd4530 /MT /O2 /Oi /sdl- /GS- /Gy /Gw /Zc:inline>) @@ -24,7 +24,7 @@ if(WIN32) $<$>: /OPT:REF /OPT:ICF /LTCG>) else() target_compile_options(ParserGenerator PRIVATE - /bigobj /wd4100 /wd4189 /wd4065 /GR- /W4 /permissive- /Zc:preprocessor /WX /arch:AVX2 /GF /w34388 /w34389 + /bigobj /wd4100 /wd4189 /wd4065 /GR- /W4 /permissive- /Zc:preprocessor /WX /d2archSSE42 /GF /w34388 /w34389 $<$: /RTC1 /EHsc /MTd /Od /RTC1> $<$>: /DNDEBUG /wd4530 /MT /O2 /Oi /GL /sdl- /Zc:preprocessor /GS- /Gy /Gw /Zc:inline>) target_link_options(ParserGenerator PRIVATE @@ -40,4 +40,3 @@ else() # GCC or CLANG $<$: $<$: > $<$>: >>) endif() - diff --git a/assets/localisation/en-US/alice.csv b/assets/localisation/en-US/alice.csv index 51ce5943fd..4303a7272c 100644 --- a/assets/localisation/en-US/alice.csv +++ b/assets/localisation/en-US/alice.csv @@ -811,6 +811,17 @@ influence_explain_15;$x$ from our relationship influence_explain_16;$x$ from our investment in the nation influence_explain_17;$x$ from the size of the target nation influence_explain_18;$x$ from our relative score +great_power_influence_tooltip;$country$ influence in $country2$: $x$ / $y$ +great_power_influence_status_sphere;Status: In sphere of influence +great_power_influence_status_leader;Status: Leader +great_power_influence_status_contesting;Status: Contesting +great_power_influence_status_idle;Status: Not influencing +great_power_influence_leader;Leader: $country$ ($x$) +great_power_influence_gap;Gap to leader: $x$ +great_power_influence_no_daily_gain;Daily change: 0.00 +great_power_investment_tooltip;$country$ foreign investment in $country2$: $x$ +great_power_investment_share;Share of all foreign investment: $x$ +great_power_investment_influence_modifier;Influence modifier from investment: $x$ until_date;Until $x$ add_wg_1;You can't add a war goal against yourself add_wg_2;You are at war @@ -1184,6 +1195,7 @@ alice_unit_disable_rebel_hunt;Stop hunting rebels alice_regiment_battle_info;$m$ $name$ ?Y$type$?!\nOrganisation: ?Y$organisation$?W\nStrength: ?Y$strength$?W understaffed_regiment;?RThis regiment is understaffed and will only have $value$ soldiers!?W tech_queue_explain;Press ?YSHIFT?W to add to queue, ?YRight-click?W to remove +technology_prerequisites;Requirements: alice_province_building_build;?YSHIFT?W to build on the entire ?Gstate?W.\n?YSHIFT-Right-click?W to build on the entire ?Gcountry?W. commodity_shortage;?RThere is a shortage of this commodity commodity_surplus;?GThere is a surplus of this commodity @@ -1635,7 +1647,7 @@ alice_budget_gold;Gold Mines alice_budget_construction;Construction alice_budget_army_upkeep;Army Upkeep alice_budget_navy_upkeep;Navy Upkeep -alice_budget_domestic_investment;Public Works +alice_budget_domestic_investment;Investment Subsidies alice_budget_debt_service;Debt Service alice_budget_diplo_income;Diplomatic alice_budget_diplo_expenses;Diplomatic @@ -1653,6 +1665,28 @@ alice_budget_min;Min $x$ alice_budget_overlord;Taxes to overlord alice_budget_expand_tt;Show detailed breakdown alice_budget_contract_tt;Hide detailed breakdown +alice_budget_tooltip_setting_actual;Setting: ?Y$x$?W. Current amount: ?Y$val$?W. +alice_budget_tooltip_actual;Current amount: ?Y$val$?W. +alice_budget_poor_tax_tt;Collects a share of income from lower-class POPs. Higher taxes reduce their savings and ability to buy goods. Actual collection also depends on provincial control and administrative efficiency. +alice_budget_middle_tax_tt;Collects a share of income from middle-class POPs. Higher taxes reduce their savings and ability to buy goods. Actual collection also depends on provincial control and administrative efficiency. +alice_budget_rich_tax_tt;Collects a share of income from upper-class POPs. Higher taxes reduce their savings and investment capacity. Actual collection also depends on provincial control and administrative efficiency. +alice_budget_tariffs_import_tt;Collects duties on goods entering your market. Higher duties make imports more expensive and can reduce their volume. They do not apply to domestic trade or tariff-free agreements. +alice_budget_tariffs_export_tt;Collects duties on goods leaving your market. Higher duties raise export prices and can reduce their competitiveness and volume. +alice_budget_diplomatic_income_tt;Automatic income from war subsidies, reparations and subject payments. This category has no budget setting. +alice_budget_gold_tt;Income from gold production converted directly into money. It is not affected by tax settings. +alice_budget_diplomatic_expenses_tt;Automatic payments for war subsidies, reparations and overlord contributions. This category has no budget setting. +alice_budget_social_tt;Pays pensions and unemployment benefits to POPs. It only has an effect when the corresponding social reforms are active. +alice_budget_military_tt;Pays the needs of military POPs, chiefly soldiers and officers. It is separate from the goods used to supply military units. +alice_budget_education_tt;Funds schools and universities that provide free education. Their output helps POPs gain literacy when qualified labour is available. +alice_budget_administration_tt;Employs central and local administrators. They build state control, improving tax collection and crime fighting. +alice_budget_domestic_investment_tt;Transfers public support to capitalists and aristocrats. It supports private investment, but does not directly build state projects. +alice_budget_overseas_tt;Buys special goods for non-central possessions. Adequate funding reduces militancy pressure in overseas provinces. +alice_budget_subsidies_tt;Supports production selected through national or state production priorities. Funds are distributed by actual output, not simply by factory losses. +alice_budget_construction_tt;Buys materials for state construction, factories and military units. Progress depends on funding and the availability of required goods. +alice_budget_army_upkeep_tt;Buys supplies and reinforcements for land units. Market shortages can limit the effective level of supply. +alice_budget_navy_upkeep_tt;Buys supplies, repairs and reinforcements for naval units. Market shortages can limit the effective level of supply. +alice_budget_debt_tt;Mandatory interest payments on loans. These are paid before most other budget categories. +alice_budget_stockpile_tt;Buys goods toward targets set in the Trade window. Purchases depend on available funds and market supply. alice_budget_admin_eff1;Admin. alice_budget_admin_eff2;Efficiency: alice_budget_chart_top;100% diff --git a/assets/localisation/ru-RU/alice.csv b/assets/localisation/ru-RU/alice.csv index 4817da109d..5280d66941 100644 --- a/assets/localisation/ru-RU/alice.csv +++ b/assets/localisation/ru-RU/alice.csv @@ -669,6 +669,17 @@ influence_explain_15;$x$ от наших отношений influence_explain_16;$x$ от наших инвестиций в страну influence_explain_17;$x$ от размера целевой нации influence_explain_18;$x$ из нашей относительной оценки +great_power_influence_tooltip;Влияние $country$ в $country2$: $x$ / $y$ +great_power_influence_status_sphere;Статус: в сфере влияния +great_power_influence_status_leader;Статус: лидер +great_power_influence_status_contesting;Статус: соперничает +great_power_influence_status_idle;Статус: не влияет +great_power_influence_leader;Лидер: $country$ ($x$) +great_power_influence_gap;Отставание от лидера: $x$ +great_power_influence_no_daily_gain;Ежедневное изменение: 0.00 +great_power_investment_tooltip;Иностранные инвестиции $country$ в $country2$: $x$ +great_power_investment_share;Доля всех иностранных инвестиций: $x$ +great_power_investment_influence_modifier;Модификатор влияния от инвестиций: $x$ until_date;Until $x$ add_wg_1;You can't add a war goal against yourself add_wg_2;You are at war @@ -979,6 +990,7 @@ alice_unit_disable_rebel_hunt;Прекратить охоту на повста alice_regiment_battle_info;$m$ $name$ ?Y$type$?!\nОрганизация: ?Y$organisation$?W\nСила: ?Y$strength$?W understaffed_regiment;?RЭтот батальон не полон и имеет лишь $value$ солдат!?W tech_queue_explain;Нажатие с ?YSHIFT?W добавляет в очередь, ?YRight-click?W исключает +technology_prerequisites;Требования: alice_province_building_build;Нажатие с ?YSHIFT?W построит во всей ?Gпровинции?W.\n?YSHIFT-Right-click?W построит во всей стране ?Gcountry?W. commodity_shortage;?RНехватка товара commodity_surplus;?GИзбыток товара @@ -1359,6 +1371,28 @@ alice_budget_min;Минимум $x$ alice_budget_overlord;Налоги сюзерену alice_budget_expand_tt;Показать разбивку alice_budget_contract_tt;Скрыть разбивку +alice_budget_tooltip_setting_actual;Установлено: ?Y$x$?W. Текущая сумма: ?Y$val$?W. +alice_budget_tooltip_actual;Текущая сумма: ?Y$val$?W. +alice_budget_poor_tax_tt;Собирает часть дохода POP'ов низшего класса. Высокие налоги уменьшают их сбережения и возможность покупать товары. Реальный сбор также зависит от контроля провинций и эффективности администрации. +alice_budget_middle_tax_tt;Собирает часть дохода POP'ов среднего класса. Высокие налоги уменьшают их сбережения и возможность покупать товары. Реальный сбор также зависит от контроля провинций и эффективности администрации. +alice_budget_rich_tax_tt;Собирает часть дохода POP'ов высшего класса. Высокие налоги уменьшают их сбережения и возможности для инвестиций. Реальный сбор также зависит от контроля провинций и эффективности администрации. +alice_budget_tariffs_import_tt;Собирает пошлины с товаров, поступающих на ваш рынок. Высокие пошлины удорожают импорт и могут сократить его объём. Они не действуют на внутреннюю торговлю и соглашения без пошлин. +alice_budget_tariffs_export_tt;Собирает пошлины с товаров, покидающих ваш рынок. Высокие пошлины повышают цену экспорта и могут снизить его конкурентоспособность и объём. +alice_budget_diplomatic_income_tt;Автоматические доходы от военных субсидий, репараций и выплат зависимых стран. У этой категории нет настройки бюджета. +alice_budget_gold_tt;Доход от добычи золота, напрямую превращаемый в деньги. Не зависит от налоговых настроек. +alice_budget_diplomatic_expenses_tt;Автоматические выплаты военных субсидий, репараций и отчислений сюзерену. У этой категории нет настройки бюджета. +alice_budget_social_tt;Выплачивает POP'ам пенсии и пособия по безработице. Работает только при наличии соответствующих социальных реформ. +alice_budget_military_tt;Оплачивает потребности военных POP'ов, прежде всего солдат и офицеров. Не включает товары снабжения воинских частей. +alice_budget_education_tt;Финансирует школы и университеты, предоставляющие бесплатное образование. Их работа повышает грамотность POP'ов при наличии квалифицированных работников. +alice_budget_administration_tt;Нанимает центральных и местных администраторов. Они создают государственный контроль, повышая собираемость налогов и борьбу с преступностью. +alice_budget_domestic_investment_tt;Направляет государственную поддержку капиталистам и аристократам. Она поддерживает частные инвестиции, но не строит государственные проекты напрямую. +alice_budget_overseas_tt;Покупает специальные товары для нецентральных владений. Достаточное финансирование уменьшает воинственность POP'ов за морем. +alice_budget_subsidies_tt;Поддерживает выпуск, выбранный в национальных или региональных приоритетах производства. Средства распределяются по фактическому выпуску, а не просто покрывают убытки фабрик. +alice_budget_construction_tt;Покупает материалы для государственных строек, фабрик и воинских частей. Ход работ зависит от финансирования и доступности нужных товаров. +alice_budget_army_upkeep_tt;Покупает снабжение и пополнение для сухопутных частей. Нехватка товаров на рынке может ограничить фактический уровень снабжения. +alice_budget_navy_upkeep_tt;Покупает снабжение, ремонт и пополнение для флота. Нехватка товаров на рынке может ограничить фактический уровень снабжения. +alice_budget_debt_tt;Обязательные процентные выплаты по займам. Они списываются раньше большинства других расходов. +alice_budget_stockpile_tt;Покупает товары до целей, заданных в окне торговли. Закупки зависят от доступных денег и предложения на рынке. alice_budget_admin_eff1;Администр. alice_budget_admin_eff2;Эффективность: alice_budget_chart_top;100% diff --git a/dependencies/DataContainerGenerator/CMakeLists.txt b/dependencies/DataContainerGenerator/CMakeLists.txt index ad9db56a7a..04ef1ec229 100644 --- a/dependencies/DataContainerGenerator/CMakeLists.txt +++ b/dependencies/DataContainerGenerator/CMakeLists.txt @@ -25,7 +25,7 @@ if(WIN32) set(CMAKE_CXX_FLAGS_RELEASE "") if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") target_compile_options(DCONGENERATOR PRIVATE - /bigobj /wd4100 /wd4189 /wd4065 /GR- /W4 /permissive- /WX /arch:AVX2 /GF /wd4388 /wd4389 -Wno-switch-default -Wno-unused-parameter -Wno-sign-compare -Wno-newline-eof -Wno-missing-prototypes -Wno-unsafe-buffer-usage -Wno-shadow-uncaptured-local -Wno-unreachable-code-break -Wno-padded -Wno-unique-object-duplication + /bigobj /wd4100 /wd4189 /wd4065 /GR- /W4 /permissive- /WX /d2archSSE42 /GF /wd4388 /wd4389 -Wno-switch-default -Wno-unused-parameter -Wno-sign-compare -Wno-newline-eof -Wno-missing-prototypes -Wno-unsafe-buffer-usage -Wno-shadow-uncaptured-local -Wno-unreachable-code-break -Wno-padded -Wno-unique-object-duplication $<$: /RTC1 /EHsc /MTd /Od> $<$>: /DNDEBUG /wd4530 /MT /O2 /Oi /sdl- /GS- /Gy /Gw /Zc:inline>) target_link_options(DCONGENERATOR PRIVATE @@ -33,7 +33,7 @@ if(WIN32) $<$>: /OPT:REF /OPT:ICF /LTCG>) else() target_compile_options(DCONGENERATOR PRIVATE - /bigobj /wd4100 /wd4189 /wd4065 /GR- /W4 /permissive- /Zc:preprocessor /WX /arch:AVX2 /GF /wd4388 /wd4389 + /bigobj /wd4100 /wd4189 /wd4065 /GR- /W4 /permissive- /Zc:preprocessor /WX /d2archSSE42 /GF /wd4388 /wd4389 $<$: /RTC1 /EHsc /MTd /Od> $<$>: /DNDEBUG /wd4530 /MT /O2 /Oi /GL /sdl- /GS- /Gy /Gw /Zc:inline>) target_link_options(DCONGENERATOR PRIVATE diff --git a/dependencies/glew/CMakeLists.txt b/dependencies/glew/CMakeLists.txt index 90039f909a..7e22280ab8 100644 --- a/dependencies/glew/CMakeLists.txt +++ b/dependencies/glew/CMakeLists.txt @@ -9,7 +9,9 @@ include(FetchContent) FetchContent_Declare( glew GIT_REPOSITORY https://github.com/Perlmint/glew-cmake.git - GIT_TAG d06782b910213d675925e6e51a69ad0fd1fe1f23 + # The former commit pin was pruned from the dependency repository. Pin to + # the retained 2.2.0 release commit so a clean configure remains reproducible. + GIT_TAG f456deace7b408655109aaeff71421ef2d3858c6 GIT_PROGRESS TRUE ) diff --git a/src/ai/ai_campaign.cpp b/src/ai/ai_campaign.cpp index 0d8afe46da..044b91ead2 100644 --- a/src/ai/ai_campaign.cpp +++ b/src/ai/ai_campaign.cpp @@ -1,6 +1,7 @@ #include "ai_campaign.hpp" #include "ai_campaign_values.hpp" #include "ai_types.hpp" +#include "commands.hpp" #include "prng.hpp" #include "system_state.hpp" #include "commands.hpp" @@ -137,26 +138,13 @@ void update_ai_research(sys::state& state) { std::vector potential; for(auto tid : state.world.in_technology) { - if(state.world.nation_get_active_technologies(n, tid)) - continue; // Already researched - - if(state.current_date.to_ymd(state.start_date).year >= state.world.technology_get_year(tid)) { - // Research technologies costing LP (military doctrines) only if can research it immediately - if(culture::effective_technology_lp_cost(state, year, n, tid) > state.world.nation_get_leadership_points(n)) { - continue; - } - // Technologies costing RP: - // Find previous technology before this one - dcon::technology_id prev_tech = dcon::technology_id(dcon::technology_id::value_base_t(tid.id.index() - 1)); - // Previous technology is from the same folder so we have to check that we have researched it beforehand - if(tid.id.index() != 0 && state.world.technology_get_folder_index(prev_tech) == state.world.technology_get_folder_index(tid)) { - // Only allow if all previously researched techs are researched - if(state.world.nation_get_active_technologies(n, prev_tech)) - potential.push_back(potential_techs{ tid, 0.0f }); - } else { // first tech in folder - potential.push_back(potential_techs{ tid, 0.0f }); - } - } + // Uses the same explicit prerequisite graph as the player-facing command. + if(!command::can_start_research(state, n, tid)) + continue; + // Research technologies costing LP (military doctrines) only if can research it immediately. + if(culture::effective_technology_lp_cost(state, year, n, tid) > state.world.nation_get_leadership_points(n)) + continue; + potential.push_back(potential_techs{ tid, 0.0f }); } for(auto& pt : potential) { // weight techs diff --git a/src/ai/ai_influence.cpp b/src/ai/ai_influence.cpp index e9de2ea491..e27e4d706e 100644 --- a/src/ai/ai_influence.cpp +++ b/src/ai/ai_influence.cpp @@ -19,8 +19,8 @@ void update_influence_priorities(sys::state& state) { } else { auto& status = gprl.get_status(); gprl.set_status(uint8_t(status & ~nations::influence::priority_mask)); - if((status & nations::influence::level_mask) == nations::influence::level_in_sphere) { - gprl.set_status(uint8_t(status | nations::influence::priority_one)); + if(gprl.get_influence_target().get_in_sphere_of() == gprl.get_great_power()) { + gprl.set_status(uint8_t(gprl.get_status() | nations::influence::priority_one)); } } } @@ -155,43 +155,4 @@ void update_influence_priorities(sys::state& state) { } } -void perform_influence_actions(sys::state& state) { - for(auto gprl : state.world.in_gp_relationship) { - if(gprl.get_great_power().get_is_player_controlled()) { - // nothing -- player GP - } else { - if((gprl.get_status() & nations::influence::is_banned) != 0) - continue; // can't do anything with a banned nation - - if(military::are_at_war(state, gprl.get_great_power(), gprl.get_influence_target())) - continue; // can't do anything while at war - - auto clevel = (nations::influence::level_mask & gprl.get_status()); - if(clevel == nations::influence::level_in_sphere) - continue; // already in sphere - - auto current_sphere = gprl.get_influence_target().get_in_sphere_of(); - - if(state.defines.increaseopinion_influence_cost <= gprl.get_influence() && clevel != nations::influence::level_friendly) { - assert(command::can_increase_opinion(state, gprl.get_great_power(), gprl.get_influence_target())); - command::execute_increase_opinion(state, gprl.get_great_power(), gprl.get_influence_target()); - } else if(state.defines.removefromsphere_influence_cost <= gprl.get_influence() && current_sphere /* && current_sphere != gprl.get_great_power()*/ && clevel == nations::influence::level_friendly) { // condition taken care of by check above - assert(command::can_remove_from_sphere(state, gprl.get_great_power(), gprl.get_influence_target(), gprl.get_influence_target().get_in_sphere_of())); - command::execute_remove_from_sphere(state, gprl.get_great_power(), gprl.get_influence_target(), gprl.get_influence_target().get_in_sphere_of()); - } else if(state.defines.addtosphere_influence_cost <= gprl.get_influence() && !current_sphere && clevel == nations::influence::level_friendly) { - assert(command::can_add_to_sphere(state, gprl.get_great_power(), gprl.get_influence_target())); - command::execute_add_to_sphere(state, gprl.get_great_power(), gprl.get_influence_target()); - //De-sphere countries we have wargoals against, desphering countries need to check for going over infamy - } else if(military::can_use_cb_against(state, gprl.get_great_power(), gprl.get_influence_target()) - && state.defines.removefromsphere_influence_cost <= gprl.get_influence() - && current_sphere - && clevel == nations::influence::level_friendly - && (state.world.nation_get_infamy(gprl.get_great_power()) + state.defines.removefromsphere_infamy_cost) < state.defines.badboy_limit - ) { - assert(command::can_remove_from_sphere(state, gprl.get_great_power(), gprl.get_influence_target(), gprl.get_influence_target().get_in_sphere_of())); - command::execute_remove_from_sphere(state, gprl.get_great_power(), gprl.get_influence_target(), gprl.get_influence_target().get_in_sphere_of()); - } - } - } -} } diff --git a/src/ai/ai_influence.hpp b/src/ai/ai_influence.hpp index 43b93e2044..28c15b136a 100644 --- a/src/ai/ai_influence.hpp +++ b/src/ai/ai_influence.hpp @@ -7,5 +7,4 @@ struct state; namespace ai { void update_influence_priorities(sys::state& state); -void perform_influence_actions(sys::state& state); } diff --git a/src/gamestate/commands.cpp b/src/gamestate/commands.cpp index 9c66b9ac61..f448a7156f 100644 --- a/src/gamestate/commands.cpp +++ b/src/gamestate/commands.cpp @@ -267,9 +267,8 @@ void start_research(sys::state& state, dcon::nation_id source, dcon::technology_ } bool can_start_research(sys::state& state, dcon::nation_id source, dcon::technology_id tech) { - /* Nations can only start researching technologies if, they are not uncivilized, the tech - activation date is past by, and all the previous techs (if any) of the same folder index - are already researched fully. And they are not already researched. */ + /* Nations can only start researching technologies if they are civilized, the technology's + activation date has passed, and every explicit prerequisite has been researched. */ if(!state.current_scene.game_in_progress) { return false; } @@ -281,17 +280,14 @@ bool can_start_research(sys::state& state, dcon::nation_id source, dcon::technol return false; // Already being researched if(!state.world.nation_get_is_civilized(source)) return false; // Must be civilized - if(state.current_date.to_ymd(state.start_date).year >= state.world.technology_get_year(tech)) { - // Find previous technology before this one - dcon::technology_id prev_tech = dcon::technology_id(dcon::technology_id::value_base_t(tech.index() - 1)); - // Previous technology is from the same folder so we have to check that we have researched it beforehand - if(tech.index() != 0 && state.world.technology_get_folder_index(prev_tech) == state.world.technology_get_folder_index(tech)) { - // Only allow if all previously researched techs are researched - return state.world.nation_get_active_technologies(source, prev_tech); - } - return true; // First technology on folder can always be researched + if(state.current_date.to_ymd(state.start_date).year < state.world.technology_get_year(tech)) + return false; + + for(auto prerequisite : state.world.technology_get_prerequisites(tech)) { + if(!state.world.nation_get_active_technologies(source, prerequisite)) + return false; } - return false; + return true; } void execute_start_research(sys::state& state, dcon::nation_id source, dcon::technology_id tech) { @@ -1268,6 +1264,10 @@ void discredit_advisors(sys::state& state, dcon::nation_id source, dcon::nation_ } bool can_discredit_advisors(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target, dcon::nation_id affected_gp) { + // Influence sabotage was removed: neither players nor AI can issue this command. + return false; + +#if 0 /* The source must be a great power. The source must have define:DISCREDIT_INFLUENCE_COST influence points. The source may not be currently banned with the direct target or currently on the opposite side of a war involving them. Only a great power can be a @@ -1308,8 +1308,12 @@ bool can_discredit_advisors(sys::state& state, dcon::nation_id source, dcon::nat return nations::influence::is_influence_level_greater_or_equal(clevel, nations::influence::get_level(state, affected_gp, influence_target)); +#endif } void execute_discredit_advisors(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target, dcon::nation_id affected_gp) { + if(!can_discredit_advisors(state, source, influence_target, affected_gp)) + return; + /* A nation is discredited for define:DISCREDIT_DAYS. Being discredited twice does not add these durations together; it just resets the timer from the current day. Discrediting a nation "increases" your relationship with them by @@ -1346,6 +1350,10 @@ void expel_advisors(sys::state& state, dcon::nation_id source, dcon::nation_id i add_to_command_queue(state, p); } bool can_expel_advisors(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target, dcon::nation_id affected_gp) { + // Influence sabotage was removed: neither players nor AI can issue this command. + return false; + +#if 0 /* The source must be a great power. The source must have define:EXPELADVISORS_INFLUENCE_COST influence points. The source may not be currently banned with the direct target or currently on the opposite side of a war involving them. Only a great power @@ -1381,8 +1389,12 @@ bool can_expel_advisors(sys::state& state, dcon::nation_id source, dcon::nation_ return nations::influence::is_influence_level_greater_or_equal(clevel, nations::influence::get_level(state, affected_gp, influence_target)); +#endif } void execute_expel_advisors(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target, dcon::nation_id affected_gp) { + if(!can_expel_advisors(state, source, influence_target, affected_gp)) + return; + /* Expelling a nation's advisors "increases" your relationship with them by define:EXPELADVISORS_RELATION_ON_ACCEPT. This action costs define:EXPELADVISORS_INFLUENCE_COST influence points. Being expelled cancels any ongoing discredit effect. Being @@ -1420,6 +1432,10 @@ void ban_embassy(sys::state& state, dcon::nation_id source, dcon::nation_id infl add_to_command_queue(state, p); } bool can_ban_embassy(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target, dcon::nation_id affected_gp) { + // Influence sabotage was removed: neither players nor AI can issue this command. + return false; + +#if 0 /* The source must be a great power. The source must have define:BANEMBASSY_INFLUENCE_COST influence points. The source may not be currently banned with the direct target or currently on the opposite side of a war involving them. Only a great power can @@ -1456,8 +1472,12 @@ bool can_ban_embassy(sys::state& state, dcon::nation_id source, dcon::nation_id return nations::influence::is_influence_level_greater_or_equal(clevel, nations::influence::get_level(state, affected_gp, influence_target)); +#endif } void execute_ban_embassy(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target, dcon::nation_id affected_gp) { + if(!can_ban_embassy(state, source, influence_target, affected_gp)) + return; + /* Banning a nation's embassy "increases" your relationship with them by define:BANEMBASSY_RELATION_ON_ACCEPT. This action costs define:BANEMBASSY_INFLUENCE_COST influence points. The ban embassy effect lasts for define:BANEMBASSY_DAYS. If you are already @@ -1497,6 +1517,10 @@ void increase_opinion(sys::state& state, dcon::nation_id source, dcon::nation_id } bool can_increase_opinion(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target) { + // Opinion tiers are no longer advanced manually. + return false; + +#if 0 /* The source must be a great power. The source must have define:INCREASEOPINION_INFLUENCE_COST influence points. The source may not be currently banned with the direct target or currently on the opposite side of a war involving them. Only a great power @@ -1526,8 +1550,12 @@ bool can_increase_opinion(sys::state& state, dcon::nation_id source, dcon::natio return false; return true; +#endif } void execute_increase_opinion(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target) { + if(!can_increase_opinion(state, source, influence_target)) + return; + /* Increasing the opinion of a nation costs define:INCREASEOPINION_INFLUENCE_COST influence points. Opinion can be increased to a maximum of friendly. @@ -1557,6 +1585,10 @@ void decrease_opinion(sys::state& state, dcon::nation_id source, dcon::nation_id add_to_command_queue(state, p); } bool can_decrease_opinion(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target, dcon::nation_id affected_gp) { + // Opinion tiers are no longer advanced manually. + return false; + +#if 0 /* The source must be a great power. The source must have define:DECREASEOPINION_INFLUENCE_COST influence points. The source may not be currently banned with the direct target or currently on the opposite side of a war involving them. Only a great power @@ -1602,8 +1634,12 @@ bool can_decrease_opinion(sys::state& state, dcon::nation_id source, dcon::natio return nations::influence::is_influence_level_greater_or_equal(clevel, nations::influence::get_level(state, affected_gp, influence_target)); +#endif } void execute_decrease_opinion(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target, dcon::nation_id affected_gp) { + if(!can_decrease_opinion(state, source, influence_target, affected_gp)) + return; + /* Decreasing the opinion of a nation "increases" your relationship with them by define:DECREASEOPINION_RELATION_ON_ACCEPT. This actions costs define:DECREASEOPINION_INFLUENCE_COST influence points. Opinion of the influenced nation of the secondary target @@ -1641,6 +1677,10 @@ void add_to_sphere(sys::state& state, dcon::nation_id source, dcon::nation_id in } bool can_add_to_sphere(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target) { + // Sphere membership is resolved by the daily influence competition. + return false; + +#if 0 /* The source must be a great power. The source must have define:ADDTOSPHERE_INFLUENCE_COST influence points. The source may not be currently banned with the direct target or currently on the opposite side of a war involving them. Only a great power can @@ -1674,8 +1714,12 @@ bool can_add_to_sphere(sys::state& state, dcon::nation_id source, dcon::nation_i return false; return true; +#endif } void execute_add_to_sphere(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target) { + if(!can_add_to_sphere(state, source, influence_target)) + return; + auto rel = state.world.get_gp_relationship_by_gp_influence_pair(influence_target, source); auto& current_influence = state.world.gp_relationship_get_influence(rel); @@ -1702,73 +1746,33 @@ void remove_from_sphere(sys::state& state, dcon::nation_id source, dcon::nation_ } bool can_remove_from_sphere(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target, dcon::nation_id affected_gp) { - /* - The source must be a great power. The source must have define:REMOVEFROMSPHERE_INFLUENCE_COST influence points. The source may - not be currently banned with the direct target or currently on the opposite side of a war involving them. Only a great power - can be a secondary target for this action. To preform this action you must have an opinion level of friendly with the nation - you are removing from a sphere. - */ - if(!state.current_scene.game_in_progress) { - return false; - } - if(!state.world.nation_get_is_great_power(source) || !state.world.nation_get_is_great_power(affected_gp) || - state.world.nation_get_is_great_power(influence_target)) - return false; - - if(state.world.nation_get_in_sphere_of(influence_target) != affected_gp) - return false; - - auto rel = state.world.get_gp_relationship_by_gp_influence_pair(influence_target, source); - if(!rel) - return false; - - if(source != affected_gp && state.world.gp_relationship_get_influence(rel) < state.defines.removefromsphere_influence_cost) - return false; - - if((state.world.gp_relationship_get_status(rel) & nations::influence::is_banned) != 0) - return false; - - if(military::are_at_war(state, source, influence_target)) - return false; - - auto clevel = (nations::influence::level_mask & state.world.gp_relationship_get_status(rel)); - if(clevel != nations::influence::level_friendly && clevel != nations::influence::level_in_sphere) - return false; - - return true; + // This is the only retained manual sphere action: a great power may release + // a country from its own sphere. A rival may never remove another sphere. + return state.world.nation_get_is_great_power(source) && + !state.world.nation_get_is_great_power(influence_target) && + affected_gp == source && + state.world.nation_get_in_sphere_of(influence_target) == source; } void execute_remove_from_sphere(sys::state& state, dcon::nation_id source, dcon::nation_id influence_target, dcon::nation_id affected_gp) { - /* - Removing a nation from a sphere costs define:REMOVEFROMSPHERE_INFLUENCE_COST influence points. If you remove a nation from - your own sphere you lose define:REMOVEFROMSPHERE_PRESTIGE_COST prestige and gain define:REMOVEFROMSPHERE_INFAMY_COST infamy. - Removing a nation from the sphere of another nation "increases" your relationship with the former sphere leader by - define:REMOVEFROMSPHERE_RELATION_ON_ACCEPT points. The removed nation then becomes friendly with its former sphere leader. - */ - auto rel = state.world.get_gp_relationship_by_gp_influence_pair(influence_target, source); - auto orel = state.world.get_gp_relationship_by_gp_influence_pair(influence_target, affected_gp); - auto l = state.world.gp_relationship_get_status(orel); + if(!can_remove_from_sphere(state, source, influence_target, affected_gp)) + return; - nations::remove_from_sphere(state, influence_target, uint8_t(nations::influence::decrease_level(l))); + nations::remove_from_sphere(state, influence_target, nations::influence::level_neutral); + auto rel = state.world.get_gp_relationship_by_gp_influence_pair(influence_target, source); + state.world.gp_relationship_set_influence(rel, 0.0f); + auto status = state.world.gp_relationship_get_status(rel); + state.world.gp_relationship_set_status(rel, uint8_t(status & ~nations::influence::priority_mask)); - if(source != affected_gp) { - auto& current_influence = state.world.gp_relationship_get_influence(rel); - state.world.gp_relationship_set_influence(rel, current_influence - state.defines.removefromsphere_influence_cost); - nations::adjust_relationship(state, source, affected_gp, state.defines.removefromsphere_relation_on_accept); - } else { - auto& current_infamy = state.world.nation_get_infamy(source); - state.world.nation_set_infamy(source, current_infamy + state.defines.removefromsphere_infamy_cost); - nations::adjust_prestige(state, source, -state.defines.removefromsphere_prestige_cost); - } + auto& current_infamy = state.world.nation_get_infamy(source); + state.world.nation_set_infamy(source, current_infamy + state.defines.removefromsphere_infamy_cost); + nations::adjust_prestige(state, source, -state.defines.removefromsphere_prestige_cost); notification::post(state, notification::message{ - [source, influence_target, affected_gp](sys::state& state, text::layout_base& contents) { - if(source == affected_gp) - text::add_line(state, contents, "msg_rem_sphere_1", text::variable_type::x, source, text::variable_type::y, influence_target); - else - text::add_line(state, contents, "msg_rem_sphere_2", text::variable_type::x, source, text::variable_type::y, influence_target, text::variable_type::val, affected_gp); + [source, influence_target](sys::state& state, text::layout_base& contents) { + text::add_line(state, contents, "msg_rem_sphere_1", text::variable_type::x, source, text::variable_type::y, influence_target); }, "msg_rem_sphere_title", - source, affected_gp, influence_target, + source, dcon::nation_id{}, influence_target, sys::message_base_type::rem_sphere, dcon::province_id{ } }); } diff --git a/src/gamestate/dcon_generated.txt b/src/gamestate/dcon_generated.txt index 362c4ab3f6..9d3a9be15f 100644 --- a/src/gamestate/dcon_generated.txt +++ b/src/gamestate/dcon_generated.txt @@ -3505,6 +3505,21 @@ object { type{uint8_t} tag{ scenario } } + property{ + name{ prerequisites } + type{ vector_pool{2400}{technology_id} } + tag{ scenario } + } + property{ + name{ tree_x } + type{ int16_t } + tag{ scenario } + } + property{ + name{ tree_y } + type{ int16_t } + tag{ scenario } + } property{ name{year} type{int16_t} @@ -6187,4 +6202,3 @@ load_save{ only_properties{mp_data} } - diff --git a/src/gamestate/dcon_generated_ids.hpp b/src/gamestate/dcon_generated_ids.hpp new file mode 100644 index 0000000000..909649b4fb --- /dev/null +++ b/src/gamestate/dcon_generated_ids.hpp @@ -0,0 +1,5376 @@ +#pragma once + +// +// This file was automatically generated from: B:/Modern-Age/src/gamestate/dcon_generated.txt +// EDIT AT YOUR OWN RISK; all changes will be lost upon regeneration +// NOT SUITABLE FOR USE IN CRITICAL SOFTWARE WHERE LIVES OR LIVELIHOODS DEPEND ON THE CORRECT OPERATION +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common_types.hpp" +#ifndef DCON_NO_VE +#include "ve.hpp" +#endif + +#ifdef DCON_RELEASE_INLINE +#define DCON_RELEASE_INLINE_DEFINED +#endif +#ifndef DCON_RELEASE_INLINE_DEFINED +#ifdef NDEBUG +#ifdef _MSC_VER +#define DCON_RELEASE_INLINE __forceinline +#else +#define DCON_RELEASE_INLINE inline __attribute__((always_inline)) +#endif +#else +#define DCON_RELEASE_INLINE inline +#endif +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4324 ) +#endif +#endif +namespace dcon { + // + // definition of strongly typed index for government_flag_id + // + class government_flag_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr government_flag_id() noexcept = default; + explicit constexpr government_flag_id(uint8_t v) noexcept : value(v + 1) {} + constexpr government_flag_id(government_flag_id const& v) noexcept = default; + constexpr government_flag_id(government_flag_id&& v) noexcept = default; + + government_flag_id& operator=(government_flag_id const& v) noexcept = default; + government_flag_id& operator=(government_flag_id&& v) noexcept = default; + constexpr bool operator==(government_flag_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(government_flag_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class government_flag_id_pair { + public: + government_flag_id left; + government_flag_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(government_flag_id id) { return bool(id); } + + // + // definition of strongly typed index for national_identity_id + // + class national_identity_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr national_identity_id() noexcept = default; + explicit constexpr national_identity_id(uint16_t v) noexcept : value(v + 1) {} + constexpr national_identity_id(national_identity_id const& v) noexcept = default; + constexpr national_identity_id(national_identity_id&& v) noexcept = default; + + national_identity_id& operator=(national_identity_id const& v) noexcept = default; + national_identity_id& operator=(national_identity_id&& v) noexcept = default; + constexpr bool operator==(national_identity_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(national_identity_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class national_identity_id_pair { + public: + national_identity_id left; + national_identity_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(national_identity_id id) { return bool(id); } + + // + // definition of strongly typed index for political_party_id + // + class political_party_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr political_party_id() noexcept = default; + explicit constexpr political_party_id(uint16_t v) noexcept : value(v + 1) {} + constexpr political_party_id(political_party_id const& v) noexcept = default; + constexpr political_party_id(political_party_id&& v) noexcept = default; + + political_party_id& operator=(political_party_id const& v) noexcept = default; + political_party_id& operator=(political_party_id&& v) noexcept = default; + constexpr bool operator==(political_party_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(political_party_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class political_party_id_pair { + public: + political_party_id left; + political_party_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(political_party_id id) { return bool(id); } + + // + // definition of strongly typed index for leader_images_id + // + class leader_images_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr leader_images_id() noexcept = default; + explicit constexpr leader_images_id(uint8_t v) noexcept : value(v + 1) {} + constexpr leader_images_id(leader_images_id const& v) noexcept = default; + constexpr leader_images_id(leader_images_id&& v) noexcept = default; + + leader_images_id& operator=(leader_images_id const& v) noexcept = default; + leader_images_id& operator=(leader_images_id&& v) noexcept = default; + constexpr bool operator==(leader_images_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(leader_images_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class leader_images_id_pair { + public: + leader_images_id left; + leader_images_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(leader_images_id id) { return bool(id); } + + // + // definition of strongly typed index for religion_id + // + class religion_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr religion_id() noexcept = default; + explicit constexpr religion_id(uint8_t v) noexcept : value(v + 1) {} + constexpr religion_id(religion_id const& v) noexcept = default; + constexpr religion_id(religion_id&& v) noexcept = default; + + religion_id& operator=(religion_id const& v) noexcept = default; + religion_id& operator=(religion_id&& v) noexcept = default; + constexpr bool operator==(religion_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(religion_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class religion_id_pair { + public: + religion_id left; + religion_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(religion_id id) { return bool(id); } + + // + // definition of strongly typed index for culture_group_id + // + class culture_group_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr culture_group_id() noexcept = default; + explicit constexpr culture_group_id(uint16_t v) noexcept : value(v + 1) {} + constexpr culture_group_id(culture_group_id const& v) noexcept = default; + constexpr culture_group_id(culture_group_id&& v) noexcept = default; + + culture_group_id& operator=(culture_group_id const& v) noexcept = default; + culture_group_id& operator=(culture_group_id&& v) noexcept = default; + constexpr bool operator==(culture_group_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(culture_group_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class culture_group_id_pair { + public: + culture_group_id left; + culture_group_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(culture_group_id id) { return bool(id); } + + // + // definition of strongly typed index for culture_id + // + class culture_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr culture_id() noexcept = default; + explicit constexpr culture_id(uint16_t v) noexcept : value(v + 1) {} + constexpr culture_id(culture_id const& v) noexcept = default; + constexpr culture_id(culture_id&& v) noexcept = default; + + culture_id& operator=(culture_id const& v) noexcept = default; + culture_id& operator=(culture_id&& v) noexcept = default; + constexpr bool operator==(culture_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(culture_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class culture_id_pair { + public: + culture_id left; + culture_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(culture_id id) { return bool(id); } + + // + // definition of strongly typed index for culture_group_membership_id + // + class culture_group_membership_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr culture_group_membership_id() noexcept = default; + explicit constexpr culture_group_membership_id(uint16_t v) noexcept : value(v + 1) {} + constexpr culture_group_membership_id(culture_group_membership_id const& v) noexcept = default; + constexpr culture_group_membership_id(culture_group_membership_id&& v) noexcept = default; + + culture_group_membership_id& operator=(culture_group_membership_id const& v) noexcept = default; + culture_group_membership_id& operator=(culture_group_membership_id&& v) noexcept = default; + constexpr bool operator==(culture_group_membership_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(culture_group_membership_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class culture_group_membership_id_pair { + public: + culture_group_membership_id left; + culture_group_membership_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(culture_group_membership_id id) { return bool(id); } + + // + // definition of strongly typed index for cultural_union_of_id + // + class cultural_union_of_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr cultural_union_of_id() noexcept = default; + explicit constexpr cultural_union_of_id(uint16_t v) noexcept : value(v + 1) {} + constexpr cultural_union_of_id(cultural_union_of_id const& v) noexcept = default; + constexpr cultural_union_of_id(cultural_union_of_id&& v) noexcept = default; + + cultural_union_of_id& operator=(cultural_union_of_id const& v) noexcept = default; + cultural_union_of_id& operator=(cultural_union_of_id&& v) noexcept = default; + constexpr bool operator==(cultural_union_of_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(cultural_union_of_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class cultural_union_of_id_pair { + public: + cultural_union_of_id left; + cultural_union_of_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(cultural_union_of_id id) { return bool(id); } + + // + // definition of strongly typed index for commodity_id + // + class commodity_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr commodity_id() noexcept = default; + explicit constexpr commodity_id(uint8_t v) noexcept : value(v + 1) {} + constexpr commodity_id(commodity_id const& v) noexcept = default; + constexpr commodity_id(commodity_id&& v) noexcept = default; + + commodity_id& operator=(commodity_id const& v) noexcept = default; + commodity_id& operator=(commodity_id&& v) noexcept = default; + constexpr bool operator==(commodity_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(commodity_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class commodity_id_pair { + public: + commodity_id left; + commodity_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(commodity_id id) { return bool(id); } + + // + // definition of strongly typed index for modifier_id + // + class modifier_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr modifier_id() noexcept = default; + explicit constexpr modifier_id(uint16_t v) noexcept : value(v + 1) {} + constexpr modifier_id(modifier_id const& v) noexcept = default; + constexpr modifier_id(modifier_id&& v) noexcept = default; + + modifier_id& operator=(modifier_id const& v) noexcept = default; + modifier_id& operator=(modifier_id&& v) noexcept = default; + constexpr bool operator==(modifier_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(modifier_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class modifier_id_pair { + public: + modifier_id left; + modifier_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(modifier_id id) { return bool(id); } + + // + // definition of strongly typed index for factory_type_id + // + class factory_type_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr factory_type_id() noexcept = default; + explicit constexpr factory_type_id(uint16_t v) noexcept : value(v + 1) {} + constexpr factory_type_id(factory_type_id const& v) noexcept = default; + constexpr factory_type_id(factory_type_id&& v) noexcept = default; + + factory_type_id& operator=(factory_type_id const& v) noexcept = default; + factory_type_id& operator=(factory_type_id&& v) noexcept = default; + constexpr bool operator==(factory_type_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(factory_type_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class factory_type_id_pair { + public: + factory_type_id left; + factory_type_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(factory_type_id id) { return bool(id); } + + // + // definition of strongly typed index for ideology_group_id + // + class ideology_group_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr ideology_group_id() noexcept = default; + explicit constexpr ideology_group_id(uint8_t v) noexcept : value(v + 1) {} + constexpr ideology_group_id(ideology_group_id const& v) noexcept = default; + constexpr ideology_group_id(ideology_group_id&& v) noexcept = default; + + ideology_group_id& operator=(ideology_group_id const& v) noexcept = default; + ideology_group_id& operator=(ideology_group_id&& v) noexcept = default; + constexpr bool operator==(ideology_group_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(ideology_group_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class ideology_group_id_pair { + public: + ideology_group_id left; + ideology_group_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(ideology_group_id id) { return bool(id); } + + // + // definition of strongly typed index for ideology_id + // + class ideology_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr ideology_id() noexcept = default; + explicit constexpr ideology_id(uint8_t v) noexcept : value(v + 1) {} + constexpr ideology_id(ideology_id const& v) noexcept = default; + constexpr ideology_id(ideology_id&& v) noexcept = default; + + ideology_id& operator=(ideology_id const& v) noexcept = default; + ideology_id& operator=(ideology_id&& v) noexcept = default; + constexpr bool operator==(ideology_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(ideology_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class ideology_id_pair { + public: + ideology_id left; + ideology_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(ideology_id id) { return bool(id); } + + // + // definition of strongly typed index for ideology_group_membership_id + // + class ideology_group_membership_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr ideology_group_membership_id() noexcept = default; + explicit constexpr ideology_group_membership_id(uint8_t v) noexcept : value(v + 1) {} + constexpr ideology_group_membership_id(ideology_group_membership_id const& v) noexcept = default; + constexpr ideology_group_membership_id(ideology_group_membership_id&& v) noexcept = default; + + ideology_group_membership_id& operator=(ideology_group_membership_id const& v) noexcept = default; + ideology_group_membership_id& operator=(ideology_group_membership_id&& v) noexcept = default; + constexpr bool operator==(ideology_group_membership_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(ideology_group_membership_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class ideology_group_membership_id_pair { + public: + ideology_group_membership_id left; + ideology_group_membership_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(ideology_group_membership_id id) { return bool(id); } + + // + // definition of strongly typed index for issue_id + // + class issue_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr issue_id() noexcept = default; + explicit constexpr issue_id(uint8_t v) noexcept : value(v + 1) {} + constexpr issue_id(issue_id const& v) noexcept = default; + constexpr issue_id(issue_id&& v) noexcept = default; + + issue_id& operator=(issue_id const& v) noexcept = default; + issue_id& operator=(issue_id&& v) noexcept = default; + constexpr bool operator==(issue_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(issue_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class issue_id_pair { + public: + issue_id left; + issue_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(issue_id id) { return bool(id); } + + // + // definition of strongly typed index for issue_option_id + // + class issue_option_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr issue_option_id() noexcept = default; + explicit constexpr issue_option_id(uint16_t v) noexcept : value(v + 1) {} + constexpr issue_option_id(issue_option_id const& v) noexcept = default; + constexpr issue_option_id(issue_option_id&& v) noexcept = default; + + issue_option_id& operator=(issue_option_id const& v) noexcept = default; + issue_option_id& operator=(issue_option_id&& v) noexcept = default; + constexpr bool operator==(issue_option_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(issue_option_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class issue_option_id_pair { + public: + issue_option_id left; + issue_option_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(issue_option_id id) { return bool(id); } + + // + // definition of strongly typed index for reform_id + // + class reform_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr reform_id() noexcept = default; + explicit constexpr reform_id(uint8_t v) noexcept : value(v + 1) {} + constexpr reform_id(reform_id const& v) noexcept = default; + constexpr reform_id(reform_id&& v) noexcept = default; + + reform_id& operator=(reform_id const& v) noexcept = default; + reform_id& operator=(reform_id&& v) noexcept = default; + constexpr bool operator==(reform_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(reform_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class reform_id_pair { + public: + reform_id left; + reform_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(reform_id id) { return bool(id); } + + // + // definition of strongly typed index for reform_option_id + // + class reform_option_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr reform_option_id() noexcept = default; + explicit constexpr reform_option_id(uint16_t v) noexcept : value(v + 1) {} + constexpr reform_option_id(reform_option_id const& v) noexcept = default; + constexpr reform_option_id(reform_option_id&& v) noexcept = default; + + reform_option_id& operator=(reform_option_id const& v) noexcept = default; + reform_option_id& operator=(reform_option_id&& v) noexcept = default; + constexpr bool operator==(reform_option_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(reform_option_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class reform_option_id_pair { + public: + reform_option_id left; + reform_option_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(reform_option_id id) { return bool(id); } + + // + // definition of strongly typed index for cb_type_id + // + class cb_type_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr cb_type_id() noexcept = default; + explicit constexpr cb_type_id(uint16_t v) noexcept : value(v + 1) {} + constexpr cb_type_id(cb_type_id const& v) noexcept = default; + constexpr cb_type_id(cb_type_id&& v) noexcept = default; + + cb_type_id& operator=(cb_type_id const& v) noexcept = default; + cb_type_id& operator=(cb_type_id&& v) noexcept = default; + constexpr bool operator==(cb_type_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(cb_type_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class cb_type_id_pair { + public: + cb_type_id left; + cb_type_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(cb_type_id id) { return bool(id); } + + // + // definition of strongly typed index for leader_trait_id + // + class leader_trait_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr leader_trait_id() noexcept = default; + explicit constexpr leader_trait_id(uint16_t v) noexcept : value(v + 1) {} + constexpr leader_trait_id(leader_trait_id const& v) noexcept = default; + constexpr leader_trait_id(leader_trait_id&& v) noexcept = default; + + leader_trait_id& operator=(leader_trait_id const& v) noexcept = default; + leader_trait_id& operator=(leader_trait_id&& v) noexcept = default; + constexpr bool operator==(leader_trait_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(leader_trait_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class leader_trait_id_pair { + public: + leader_trait_id left; + leader_trait_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(leader_trait_id id) { return bool(id); } + + // + // definition of strongly typed index for pop_type_id + // + class pop_type_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr pop_type_id() noexcept = default; + explicit constexpr pop_type_id(uint8_t v) noexcept : value(v + 1) {} + constexpr pop_type_id(pop_type_id const& v) noexcept = default; + constexpr pop_type_id(pop_type_id&& v) noexcept = default; + + pop_type_id& operator=(pop_type_id const& v) noexcept = default; + pop_type_id& operator=(pop_type_id&& v) noexcept = default; + constexpr bool operator==(pop_type_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(pop_type_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class pop_type_id_pair { + public: + pop_type_id left; + pop_type_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(pop_type_id id) { return bool(id); } + + // + // definition of strongly typed index for rebel_type_id + // + class rebel_type_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr rebel_type_id() noexcept = default; + explicit constexpr rebel_type_id(uint16_t v) noexcept : value(v + 1) {} + constexpr rebel_type_id(rebel_type_id const& v) noexcept = default; + constexpr rebel_type_id(rebel_type_id&& v) noexcept = default; + + rebel_type_id& operator=(rebel_type_id const& v) noexcept = default; + rebel_type_id& operator=(rebel_type_id&& v) noexcept = default; + constexpr bool operator==(rebel_type_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(rebel_type_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class rebel_type_id_pair { + public: + rebel_type_id left; + rebel_type_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(rebel_type_id id) { return bool(id); } + + // + // definition of strongly typed index for government_type_id + // + class government_type_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr government_type_id() noexcept = default; + explicit constexpr government_type_id(uint8_t v) noexcept : value(v + 1) {} + constexpr government_type_id(government_type_id const& v) noexcept = default; + constexpr government_type_id(government_type_id&& v) noexcept = default; + + government_type_id& operator=(government_type_id const& v) noexcept = default; + government_type_id& operator=(government_type_id&& v) noexcept = default; + constexpr bool operator==(government_type_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(government_type_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class government_type_id_pair { + public: + government_type_id left; + government_type_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(government_type_id id) { return bool(id); } + + // + // definition of strongly typed index for province_id + // + class province_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr province_id() noexcept = default; + explicit constexpr province_id(uint16_t v) noexcept : value(v + 1) {} + constexpr province_id(province_id const& v) noexcept = default; + constexpr province_id(province_id&& v) noexcept = default; + + province_id& operator=(province_id const& v) noexcept = default; + province_id& operator=(province_id&& v) noexcept = default; + constexpr bool operator==(province_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(province_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class province_id_pair { + public: + province_id left; + province_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(province_id id) { return bool(id); } + + // + // definition of strongly typed index for province_adjacency_id + // + class province_adjacency_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr province_adjacency_id() noexcept = default; + explicit constexpr province_adjacency_id(uint16_t v) noexcept : value(v + 1) {} + constexpr province_adjacency_id(province_adjacency_id const& v) noexcept = default; + constexpr province_adjacency_id(province_adjacency_id&& v) noexcept = default; + + province_adjacency_id& operator=(province_adjacency_id const& v) noexcept = default; + province_adjacency_id& operator=(province_adjacency_id&& v) noexcept = default; + constexpr bool operator==(province_adjacency_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(province_adjacency_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class province_adjacency_id_pair { + public: + province_adjacency_id left; + province_adjacency_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(province_adjacency_id id) { return bool(id); } + + // + // definition of strongly typed index for nation_adjacency_id + // + class nation_adjacency_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr nation_adjacency_id() noexcept = default; + explicit constexpr nation_adjacency_id(uint16_t v) noexcept : value(v + 1) {} + constexpr nation_adjacency_id(nation_adjacency_id const& v) noexcept = default; + constexpr nation_adjacency_id(nation_adjacency_id&& v) noexcept = default; + + nation_adjacency_id& operator=(nation_adjacency_id const& v) noexcept = default; + nation_adjacency_id& operator=(nation_adjacency_id&& v) noexcept = default; + constexpr bool operator==(nation_adjacency_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(nation_adjacency_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class nation_adjacency_id_pair { + public: + nation_adjacency_id left; + nation_adjacency_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(nation_adjacency_id id) { return bool(id); } + + // + // definition of strongly typed index for regiment_id + // + class regiment_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr regiment_id() noexcept = default; + explicit constexpr regiment_id(uint16_t v) noexcept : value(v + 1) {} + constexpr regiment_id(regiment_id const& v) noexcept = default; + constexpr regiment_id(regiment_id&& v) noexcept = default; + + regiment_id& operator=(regiment_id const& v) noexcept = default; + regiment_id& operator=(regiment_id&& v) noexcept = default; + constexpr bool operator==(regiment_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(regiment_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class regiment_id_pair { + public: + regiment_id left; + regiment_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(regiment_id id) { return bool(id); } + + // + // definition of strongly typed index for automated_army_group_id + // + class automated_army_group_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr automated_army_group_id() noexcept = default; + explicit constexpr automated_army_group_id(uint8_t v) noexcept : value(v + 1) {} + constexpr automated_army_group_id(automated_army_group_id const& v) noexcept = default; + constexpr automated_army_group_id(automated_army_group_id&& v) noexcept = default; + + automated_army_group_id& operator=(automated_army_group_id const& v) noexcept = default; + automated_army_group_id& operator=(automated_army_group_id&& v) noexcept = default; + constexpr bool operator==(automated_army_group_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(automated_army_group_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class automated_army_group_id_pair { + public: + automated_army_group_id left; + automated_army_group_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(automated_army_group_id id) { return bool(id); } + + // + // definition of strongly typed index for automated_army_group_membership_regiment_id + // + class automated_army_group_membership_regiment_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr automated_army_group_membership_regiment_id() noexcept = default; + explicit constexpr automated_army_group_membership_regiment_id(uint16_t v) noexcept : value(v + 1) {} + constexpr automated_army_group_membership_regiment_id(automated_army_group_membership_regiment_id const& v) noexcept = default; + constexpr automated_army_group_membership_regiment_id(automated_army_group_membership_regiment_id&& v) noexcept = default; + + automated_army_group_membership_regiment_id& operator=(automated_army_group_membership_regiment_id const& v) noexcept = default; + automated_army_group_membership_regiment_id& operator=(automated_army_group_membership_regiment_id&& v) noexcept = default; + constexpr bool operator==(automated_army_group_membership_regiment_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(automated_army_group_membership_regiment_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class automated_army_group_membership_regiment_id_pair { + public: + automated_army_group_membership_regiment_id left; + automated_army_group_membership_regiment_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(automated_army_group_membership_regiment_id id) { return bool(id); } + + // + // definition of strongly typed index for automated_army_group_membership_navy_id + // + class automated_army_group_membership_navy_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr automated_army_group_membership_navy_id() noexcept = default; + explicit constexpr automated_army_group_membership_navy_id(uint16_t v) noexcept : value(v + 1) {} + constexpr automated_army_group_membership_navy_id(automated_army_group_membership_navy_id const& v) noexcept = default; + constexpr automated_army_group_membership_navy_id(automated_army_group_membership_navy_id&& v) noexcept = default; + + automated_army_group_membership_navy_id& operator=(automated_army_group_membership_navy_id const& v) noexcept = default; + automated_army_group_membership_navy_id& operator=(automated_army_group_membership_navy_id&& v) noexcept = default; + constexpr bool operator==(automated_army_group_membership_navy_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(automated_army_group_membership_navy_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class automated_army_group_membership_navy_id_pair { + public: + automated_army_group_membership_navy_id left; + automated_army_group_membership_navy_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(automated_army_group_membership_navy_id id) { return bool(id); } + + // + // definition of strongly typed index for regiment_automation_data_id + // + class regiment_automation_data_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr regiment_automation_data_id() noexcept = default; + explicit constexpr regiment_automation_data_id(uint16_t v) noexcept : value(v + 1) {} + constexpr regiment_automation_data_id(regiment_automation_data_id const& v) noexcept = default; + constexpr regiment_automation_data_id(regiment_automation_data_id&& v) noexcept = default; + + regiment_automation_data_id& operator=(regiment_automation_data_id const& v) noexcept = default; + regiment_automation_data_id& operator=(regiment_automation_data_id&& v) noexcept = default; + constexpr bool operator==(regiment_automation_data_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(regiment_automation_data_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class regiment_automation_data_id_pair { + public: + regiment_automation_data_id left; + regiment_automation_data_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(regiment_automation_data_id id) { return bool(id); } + + // + // definition of strongly typed index for automation_id + // + class automation_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr automation_id() noexcept = default; + explicit constexpr automation_id(uint16_t v) noexcept : value(v + 1) {} + constexpr automation_id(automation_id const& v) noexcept = default; + constexpr automation_id(automation_id&& v) noexcept = default; + + automation_id& operator=(automation_id const& v) noexcept = default; + automation_id& operator=(automation_id&& v) noexcept = default; + constexpr bool operator==(automation_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(automation_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class automation_id_pair { + public: + automation_id left; + automation_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(automation_id id) { return bool(id); } + + // + // definition of strongly typed index for ship_id + // + class ship_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr ship_id() noexcept = default; + explicit constexpr ship_id(uint16_t v) noexcept : value(v + 1) {} + constexpr ship_id(ship_id const& v) noexcept = default; + constexpr ship_id(ship_id&& v) noexcept = default; + + ship_id& operator=(ship_id const& v) noexcept = default; + ship_id& operator=(ship_id&& v) noexcept = default; + constexpr bool operator==(ship_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(ship_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class ship_id_pair { + public: + ship_id left; + ship_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(ship_id id) { return bool(id); } + + // + // definition of strongly typed index for army_id + // + class army_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr army_id() noexcept = default; + explicit constexpr army_id(uint16_t v) noexcept : value(v + 1) {} + constexpr army_id(army_id const& v) noexcept = default; + constexpr army_id(army_id&& v) noexcept = default; + + army_id& operator=(army_id const& v) noexcept = default; + army_id& operator=(army_id&& v) noexcept = default; + constexpr bool operator==(army_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(army_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class army_id_pair { + public: + army_id left; + army_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(army_id id) { return bool(id); } + + // + // definition of strongly typed index for army_pursuit_id + // + class army_pursuit_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr army_pursuit_id() noexcept = default; + explicit constexpr army_pursuit_id(uint16_t v) noexcept : value(v + 1) {} + constexpr army_pursuit_id(army_pursuit_id const& v) noexcept = default; + constexpr army_pursuit_id(army_pursuit_id&& v) noexcept = default; + + army_pursuit_id& operator=(army_pursuit_id const& v) noexcept = default; + army_pursuit_id& operator=(army_pursuit_id&& v) noexcept = default; + constexpr bool operator==(army_pursuit_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(army_pursuit_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class army_pursuit_id_pair { + public: + army_pursuit_id left; + army_pursuit_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(army_pursuit_id id) { return bool(id); } + + // + // definition of strongly typed index for navy_id + // + class navy_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr navy_id() noexcept = default; + explicit constexpr navy_id(uint16_t v) noexcept : value(v + 1) {} + constexpr navy_id(navy_id const& v) noexcept = default; + constexpr navy_id(navy_id&& v) noexcept = default; + + navy_id& operator=(navy_id const& v) noexcept = default; + navy_id& operator=(navy_id&& v) noexcept = default; + constexpr bool operator==(navy_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(navy_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class navy_id_pair { + public: + navy_id left; + navy_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(navy_id id) { return bool(id); } + + // + // definition of strongly typed index for army_transport_id + // + class army_transport_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr army_transport_id() noexcept = default; + explicit constexpr army_transport_id(uint16_t v) noexcept : value(v + 1) {} + constexpr army_transport_id(army_transport_id const& v) noexcept = default; + constexpr army_transport_id(army_transport_id&& v) noexcept = default; + + army_transport_id& operator=(army_transport_id const& v) noexcept = default; + army_transport_id& operator=(army_transport_id&& v) noexcept = default; + constexpr bool operator==(army_transport_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(army_transport_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class army_transport_id_pair { + public: + army_transport_id left; + army_transport_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(army_transport_id id) { return bool(id); } + + // + // definition of strongly typed index for army_control_id + // + class army_control_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr army_control_id() noexcept = default; + explicit constexpr army_control_id(uint16_t v) noexcept : value(v + 1) {} + constexpr army_control_id(army_control_id const& v) noexcept = default; + constexpr army_control_id(army_control_id&& v) noexcept = default; + + army_control_id& operator=(army_control_id const& v) noexcept = default; + army_control_id& operator=(army_control_id&& v) noexcept = default; + constexpr bool operator==(army_control_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(army_control_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class army_control_id_pair { + public: + army_control_id left; + army_control_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(army_control_id id) { return bool(id); } + + // + // definition of strongly typed index for army_rebel_control_id + // + class army_rebel_control_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr army_rebel_control_id() noexcept = default; + explicit constexpr army_rebel_control_id(uint16_t v) noexcept : value(v + 1) {} + constexpr army_rebel_control_id(army_rebel_control_id const& v) noexcept = default; + constexpr army_rebel_control_id(army_rebel_control_id&& v) noexcept = default; + + army_rebel_control_id& operator=(army_rebel_control_id const& v) noexcept = default; + army_rebel_control_id& operator=(army_rebel_control_id&& v) noexcept = default; + constexpr bool operator==(army_rebel_control_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(army_rebel_control_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class army_rebel_control_id_pair { + public: + army_rebel_control_id left; + army_rebel_control_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(army_rebel_control_id id) { return bool(id); } + + // + // definition of strongly typed index for army_location_id + // + class army_location_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr army_location_id() noexcept = default; + explicit constexpr army_location_id(uint16_t v) noexcept : value(v + 1) {} + constexpr army_location_id(army_location_id const& v) noexcept = default; + constexpr army_location_id(army_location_id&& v) noexcept = default; + + army_location_id& operator=(army_location_id const& v) noexcept = default; + army_location_id& operator=(army_location_id&& v) noexcept = default; + constexpr bool operator==(army_location_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(army_location_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class army_location_id_pair { + public: + army_location_id left; + army_location_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(army_location_id id) { return bool(id); } + + // + // definition of strongly typed index for army_membership_id + // + class army_membership_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr army_membership_id() noexcept = default; + explicit constexpr army_membership_id(uint16_t v) noexcept : value(v + 1) {} + constexpr army_membership_id(army_membership_id const& v) noexcept = default; + constexpr army_membership_id(army_membership_id&& v) noexcept = default; + + army_membership_id& operator=(army_membership_id const& v) noexcept = default; + army_membership_id& operator=(army_membership_id&& v) noexcept = default; + constexpr bool operator==(army_membership_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(army_membership_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class army_membership_id_pair { + public: + army_membership_id left; + army_membership_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(army_membership_id id) { return bool(id); } + + // + // definition of strongly typed index for regiment_source_id + // + class regiment_source_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr regiment_source_id() noexcept = default; + explicit constexpr regiment_source_id(uint16_t v) noexcept : value(v + 1) {} + constexpr regiment_source_id(regiment_source_id const& v) noexcept = default; + constexpr regiment_source_id(regiment_source_id&& v) noexcept = default; + + regiment_source_id& operator=(regiment_source_id const& v) noexcept = default; + regiment_source_id& operator=(regiment_source_id&& v) noexcept = default; + constexpr bool operator==(regiment_source_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(regiment_source_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class regiment_source_id_pair { + public: + regiment_source_id left; + regiment_source_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(regiment_source_id id) { return bool(id); } + + // + // definition of strongly typed index for navy_control_id + // + class navy_control_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr navy_control_id() noexcept = default; + explicit constexpr navy_control_id(uint16_t v) noexcept : value(v + 1) {} + constexpr navy_control_id(navy_control_id const& v) noexcept = default; + constexpr navy_control_id(navy_control_id&& v) noexcept = default; + + navy_control_id& operator=(navy_control_id const& v) noexcept = default; + navy_control_id& operator=(navy_control_id&& v) noexcept = default; + constexpr bool operator==(navy_control_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(navy_control_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class navy_control_id_pair { + public: + navy_control_id left; + navy_control_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(navy_control_id id) { return bool(id); } + + // + // definition of strongly typed index for navy_location_id + // + class navy_location_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr navy_location_id() noexcept = default; + explicit constexpr navy_location_id(uint16_t v) noexcept : value(v + 1) {} + constexpr navy_location_id(navy_location_id const& v) noexcept = default; + constexpr navy_location_id(navy_location_id&& v) noexcept = default; + + navy_location_id& operator=(navy_location_id const& v) noexcept = default; + navy_location_id& operator=(navy_location_id&& v) noexcept = default; + constexpr bool operator==(navy_location_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(navy_location_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class navy_location_id_pair { + public: + navy_location_id left; + navy_location_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(navy_location_id id) { return bool(id); } + + // + // definition of strongly typed index for navy_membership_id + // + class navy_membership_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr navy_membership_id() noexcept = default; + explicit constexpr navy_membership_id(uint16_t v) noexcept : value(v + 1) {} + constexpr navy_membership_id(navy_membership_id const& v) noexcept = default; + constexpr navy_membership_id(navy_membership_id&& v) noexcept = default; + + navy_membership_id& operator=(navy_membership_id const& v) noexcept = default; + navy_membership_id& operator=(navy_membership_id&& v) noexcept = default; + constexpr bool operator==(navy_membership_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(navy_membership_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class navy_membership_id_pair { + public: + navy_membership_id left; + navy_membership_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(navy_membership_id id) { return bool(id); } + + // + // definition of strongly typed index for naval_battle_id + // + class naval_battle_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr naval_battle_id() noexcept = default; + explicit constexpr naval_battle_id(uint16_t v) noexcept : value(v + 1) {} + constexpr naval_battle_id(naval_battle_id const& v) noexcept = default; + constexpr naval_battle_id(naval_battle_id&& v) noexcept = default; + + naval_battle_id& operator=(naval_battle_id const& v) noexcept = default; + naval_battle_id& operator=(naval_battle_id&& v) noexcept = default; + constexpr bool operator==(naval_battle_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(naval_battle_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class naval_battle_id_pair { + public: + naval_battle_id left; + naval_battle_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(naval_battle_id id) { return bool(id); } + + // + // definition of strongly typed index for naval_battle_location_id + // + class naval_battle_location_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr naval_battle_location_id() noexcept = default; + explicit constexpr naval_battle_location_id(uint16_t v) noexcept : value(v + 1) {} + constexpr naval_battle_location_id(naval_battle_location_id const& v) noexcept = default; + constexpr naval_battle_location_id(naval_battle_location_id&& v) noexcept = default; + + naval_battle_location_id& operator=(naval_battle_location_id const& v) noexcept = default; + naval_battle_location_id& operator=(naval_battle_location_id&& v) noexcept = default; + constexpr bool operator==(naval_battle_location_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(naval_battle_location_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class naval_battle_location_id_pair { + public: + naval_battle_location_id left; + naval_battle_location_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(naval_battle_location_id id) { return bool(id); } + + // + // definition of strongly typed index for naval_battle_in_war_id + // + class naval_battle_in_war_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr naval_battle_in_war_id() noexcept = default; + explicit constexpr naval_battle_in_war_id(uint16_t v) noexcept : value(v + 1) {} + constexpr naval_battle_in_war_id(naval_battle_in_war_id const& v) noexcept = default; + constexpr naval_battle_in_war_id(naval_battle_in_war_id&& v) noexcept = default; + + naval_battle_in_war_id& operator=(naval_battle_in_war_id const& v) noexcept = default; + naval_battle_in_war_id& operator=(naval_battle_in_war_id&& v) noexcept = default; + constexpr bool operator==(naval_battle_in_war_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(naval_battle_in_war_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class naval_battle_in_war_id_pair { + public: + naval_battle_in_war_id left; + naval_battle_in_war_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(naval_battle_in_war_id id) { return bool(id); } + + // + // definition of strongly typed index for navy_battle_participation_id + // + class navy_battle_participation_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr navy_battle_participation_id() noexcept = default; + explicit constexpr navy_battle_participation_id(uint16_t v) noexcept : value(v + 1) {} + constexpr navy_battle_participation_id(navy_battle_participation_id const& v) noexcept = default; + constexpr navy_battle_participation_id(navy_battle_participation_id&& v) noexcept = default; + + navy_battle_participation_id& operator=(navy_battle_participation_id const& v) noexcept = default; + navy_battle_participation_id& operator=(navy_battle_participation_id&& v) noexcept = default; + constexpr bool operator==(navy_battle_participation_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(navy_battle_participation_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class navy_battle_participation_id_pair { + public: + navy_battle_participation_id left; + navy_battle_participation_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(navy_battle_participation_id id) { return bool(id); } + + // + // definition of strongly typed index for attacking_admiral_id + // + class attacking_admiral_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr attacking_admiral_id() noexcept = default; + explicit constexpr attacking_admiral_id(uint16_t v) noexcept : value(v + 1) {} + constexpr attacking_admiral_id(attacking_admiral_id const& v) noexcept = default; + constexpr attacking_admiral_id(attacking_admiral_id&& v) noexcept = default; + + attacking_admiral_id& operator=(attacking_admiral_id const& v) noexcept = default; + attacking_admiral_id& operator=(attacking_admiral_id&& v) noexcept = default; + constexpr bool operator==(attacking_admiral_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(attacking_admiral_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class attacking_admiral_id_pair { + public: + attacking_admiral_id left; + attacking_admiral_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(attacking_admiral_id id) { return bool(id); } + + // + // definition of strongly typed index for defending_admiral_id + // + class defending_admiral_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr defending_admiral_id() noexcept = default; + explicit constexpr defending_admiral_id(uint16_t v) noexcept : value(v + 1) {} + constexpr defending_admiral_id(defending_admiral_id const& v) noexcept = default; + constexpr defending_admiral_id(defending_admiral_id&& v) noexcept = default; + + defending_admiral_id& operator=(defending_admiral_id const& v) noexcept = default; + defending_admiral_id& operator=(defending_admiral_id&& v) noexcept = default; + constexpr bool operator==(defending_admiral_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(defending_admiral_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class defending_admiral_id_pair { + public: + defending_admiral_id left; + defending_admiral_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(defending_admiral_id id) { return bool(id); } + + // + // definition of strongly typed index for land_battle_id + // + class land_battle_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr land_battle_id() noexcept = default; + explicit constexpr land_battle_id(uint16_t v) noexcept : value(v + 1) {} + constexpr land_battle_id(land_battle_id const& v) noexcept = default; + constexpr land_battle_id(land_battle_id&& v) noexcept = default; + + land_battle_id& operator=(land_battle_id const& v) noexcept = default; + land_battle_id& operator=(land_battle_id&& v) noexcept = default; + constexpr bool operator==(land_battle_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(land_battle_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class land_battle_id_pair { + public: + land_battle_id left; + land_battle_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(land_battle_id id) { return bool(id); } + + // + // definition of strongly typed index for land_battle_location_id + // + class land_battle_location_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr land_battle_location_id() noexcept = default; + explicit constexpr land_battle_location_id(uint16_t v) noexcept : value(v + 1) {} + constexpr land_battle_location_id(land_battle_location_id const& v) noexcept = default; + constexpr land_battle_location_id(land_battle_location_id&& v) noexcept = default; + + land_battle_location_id& operator=(land_battle_location_id const& v) noexcept = default; + land_battle_location_id& operator=(land_battle_location_id&& v) noexcept = default; + constexpr bool operator==(land_battle_location_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(land_battle_location_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class land_battle_location_id_pair { + public: + land_battle_location_id left; + land_battle_location_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(land_battle_location_id id) { return bool(id); } + + // + // definition of strongly typed index for land_battle_in_war_id + // + class land_battle_in_war_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr land_battle_in_war_id() noexcept = default; + explicit constexpr land_battle_in_war_id(uint16_t v) noexcept : value(v + 1) {} + constexpr land_battle_in_war_id(land_battle_in_war_id const& v) noexcept = default; + constexpr land_battle_in_war_id(land_battle_in_war_id&& v) noexcept = default; + + land_battle_in_war_id& operator=(land_battle_in_war_id const& v) noexcept = default; + land_battle_in_war_id& operator=(land_battle_in_war_id&& v) noexcept = default; + constexpr bool operator==(land_battle_in_war_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(land_battle_in_war_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class land_battle_in_war_id_pair { + public: + land_battle_in_war_id left; + land_battle_in_war_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(land_battle_in_war_id id) { return bool(id); } + + // + // definition of strongly typed index for army_battle_participation_id + // + class army_battle_participation_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr army_battle_participation_id() noexcept = default; + explicit constexpr army_battle_participation_id(uint16_t v) noexcept : value(v + 1) {} + constexpr army_battle_participation_id(army_battle_participation_id const& v) noexcept = default; + constexpr army_battle_participation_id(army_battle_participation_id&& v) noexcept = default; + + army_battle_participation_id& operator=(army_battle_participation_id const& v) noexcept = default; + army_battle_participation_id& operator=(army_battle_participation_id&& v) noexcept = default; + constexpr bool operator==(army_battle_participation_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(army_battle_participation_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class army_battle_participation_id_pair { + public: + army_battle_participation_id left; + army_battle_participation_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(army_battle_participation_id id) { return bool(id); } + + // + // definition of strongly typed index for attacking_general_id + // + class attacking_general_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr attacking_general_id() noexcept = default; + explicit constexpr attacking_general_id(uint16_t v) noexcept : value(v + 1) {} + constexpr attacking_general_id(attacking_general_id const& v) noexcept = default; + constexpr attacking_general_id(attacking_general_id&& v) noexcept = default; + + attacking_general_id& operator=(attacking_general_id const& v) noexcept = default; + attacking_general_id& operator=(attacking_general_id&& v) noexcept = default; + constexpr bool operator==(attacking_general_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(attacking_general_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class attacking_general_id_pair { + public: + attacking_general_id left; + attacking_general_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(attacking_general_id id) { return bool(id); } + + // + // definition of strongly typed index for defending_general_id + // + class defending_general_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr defending_general_id() noexcept = default; + explicit constexpr defending_general_id(uint16_t v) noexcept : value(v + 1) {} + constexpr defending_general_id(defending_general_id const& v) noexcept = default; + constexpr defending_general_id(defending_general_id&& v) noexcept = default; + + defending_general_id& operator=(defending_general_id const& v) noexcept = default; + defending_general_id& operator=(defending_general_id&& v) noexcept = default; + constexpr bool operator==(defending_general_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(defending_general_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class defending_general_id_pair { + public: + defending_general_id left; + defending_general_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(defending_general_id id) { return bool(id); } + + // + // definition of strongly typed index for leader_id + // + class leader_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr leader_id() noexcept = default; + explicit constexpr leader_id(uint16_t v) noexcept : value(v + 1) {} + constexpr leader_id(leader_id const& v) noexcept = default; + constexpr leader_id(leader_id&& v) noexcept = default; + + leader_id& operator=(leader_id const& v) noexcept = default; + leader_id& operator=(leader_id&& v) noexcept = default; + constexpr bool operator==(leader_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(leader_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class leader_id_pair { + public: + leader_id left; + leader_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(leader_id id) { return bool(id); } + + // + // definition of strongly typed index for army_leadership_id + // + class army_leadership_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr army_leadership_id() noexcept = default; + explicit constexpr army_leadership_id(uint16_t v) noexcept : value(v + 1) {} + constexpr army_leadership_id(army_leadership_id const& v) noexcept = default; + constexpr army_leadership_id(army_leadership_id&& v) noexcept = default; + + army_leadership_id& operator=(army_leadership_id const& v) noexcept = default; + army_leadership_id& operator=(army_leadership_id&& v) noexcept = default; + constexpr bool operator==(army_leadership_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(army_leadership_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class army_leadership_id_pair { + public: + army_leadership_id left; + army_leadership_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(army_leadership_id id) { return bool(id); } + + // + // definition of strongly typed index for navy_leadership_id + // + class navy_leadership_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr navy_leadership_id() noexcept = default; + explicit constexpr navy_leadership_id(uint16_t v) noexcept : value(v + 1) {} + constexpr navy_leadership_id(navy_leadership_id const& v) noexcept = default; + constexpr navy_leadership_id(navy_leadership_id&& v) noexcept = default; + + navy_leadership_id& operator=(navy_leadership_id const& v) noexcept = default; + navy_leadership_id& operator=(navy_leadership_id&& v) noexcept = default; + constexpr bool operator==(navy_leadership_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(navy_leadership_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class navy_leadership_id_pair { + public: + navy_leadership_id left; + navy_leadership_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(navy_leadership_id id) { return bool(id); } + + // + // definition of strongly typed index for leader_loyalty_id + // + class leader_loyalty_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr leader_loyalty_id() noexcept = default; + explicit constexpr leader_loyalty_id(uint16_t v) noexcept : value(v + 1) {} + constexpr leader_loyalty_id(leader_loyalty_id const& v) noexcept = default; + constexpr leader_loyalty_id(leader_loyalty_id&& v) noexcept = default; + + leader_loyalty_id& operator=(leader_loyalty_id const& v) noexcept = default; + leader_loyalty_id& operator=(leader_loyalty_id&& v) noexcept = default; + constexpr bool operator==(leader_loyalty_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(leader_loyalty_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class leader_loyalty_id_pair { + public: + leader_loyalty_id left; + leader_loyalty_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(leader_loyalty_id id) { return bool(id); } + + // + // definition of strongly typed index for war_id + // + class war_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr war_id() noexcept = default; + explicit constexpr war_id(uint16_t v) noexcept : value(v + 1) {} + constexpr war_id(war_id const& v) noexcept = default; + constexpr war_id(war_id&& v) noexcept = default; + + war_id& operator=(war_id const& v) noexcept = default; + war_id& operator=(war_id&& v) noexcept = default; + constexpr bool operator==(war_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(war_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class war_id_pair { + public: + war_id left; + war_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(war_id id) { return bool(id); } + + // + // definition of strongly typed index for peace_offer_id + // + class peace_offer_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr peace_offer_id() noexcept = default; + explicit constexpr peace_offer_id(uint8_t v) noexcept : value(v + 1) {} + constexpr peace_offer_id(peace_offer_id const& v) noexcept = default; + constexpr peace_offer_id(peace_offer_id&& v) noexcept = default; + + peace_offer_id& operator=(peace_offer_id const& v) noexcept = default; + peace_offer_id& operator=(peace_offer_id&& v) noexcept = default; + constexpr bool operator==(peace_offer_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(peace_offer_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class peace_offer_id_pair { + public: + peace_offer_id left; + peace_offer_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(peace_offer_id id) { return bool(id); } + + // + // definition of strongly typed index for pending_peace_offer_id + // + class pending_peace_offer_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr pending_peace_offer_id() noexcept = default; + explicit constexpr pending_peace_offer_id(uint8_t v) noexcept : value(v + 1) {} + constexpr pending_peace_offer_id(pending_peace_offer_id const& v) noexcept = default; + constexpr pending_peace_offer_id(pending_peace_offer_id&& v) noexcept = default; + + pending_peace_offer_id& operator=(pending_peace_offer_id const& v) noexcept = default; + pending_peace_offer_id& operator=(pending_peace_offer_id&& v) noexcept = default; + constexpr bool operator==(pending_peace_offer_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(pending_peace_offer_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class pending_peace_offer_id_pair { + public: + pending_peace_offer_id left; + pending_peace_offer_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(pending_peace_offer_id id) { return bool(id); } + + // + // definition of strongly typed index for war_settlement_id + // + class war_settlement_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr war_settlement_id() noexcept = default; + explicit constexpr war_settlement_id(uint8_t v) noexcept : value(v + 1) {} + constexpr war_settlement_id(war_settlement_id const& v) noexcept = default; + constexpr war_settlement_id(war_settlement_id&& v) noexcept = default; + + war_settlement_id& operator=(war_settlement_id const& v) noexcept = default; + war_settlement_id& operator=(war_settlement_id&& v) noexcept = default; + constexpr bool operator==(war_settlement_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(war_settlement_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class war_settlement_id_pair { + public: + war_settlement_id left; + war_settlement_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(war_settlement_id id) { return bool(id); } + + // + // definition of strongly typed index for wargoal_id + // + class wargoal_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr wargoal_id() noexcept = default; + explicit constexpr wargoal_id(uint16_t v) noexcept : value(v + 1) {} + constexpr wargoal_id(wargoal_id const& v) noexcept = default; + constexpr wargoal_id(wargoal_id&& v) noexcept = default; + + wargoal_id& operator=(wargoal_id const& v) noexcept = default; + wargoal_id& operator=(wargoal_id&& v) noexcept = default; + constexpr bool operator==(wargoal_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(wargoal_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class wargoal_id_pair { + public: + wargoal_id left; + wargoal_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(wargoal_id id) { return bool(id); } + + // + // definition of strongly typed index for war_participant_id + // + class war_participant_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr war_participant_id() noexcept = default; + explicit constexpr war_participant_id(uint16_t v) noexcept : value(v + 1) {} + constexpr war_participant_id(war_participant_id const& v) noexcept = default; + constexpr war_participant_id(war_participant_id&& v) noexcept = default; + + war_participant_id& operator=(war_participant_id const& v) noexcept = default; + war_participant_id& operator=(war_participant_id&& v) noexcept = default; + constexpr bool operator==(war_participant_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(war_participant_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class war_participant_id_pair { + public: + war_participant_id left; + war_participant_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(war_participant_id id) { return bool(id); } + + // + // definition of strongly typed index for wargoals_attached_id + // + class wargoals_attached_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr wargoals_attached_id() noexcept = default; + explicit constexpr wargoals_attached_id(uint16_t v) noexcept : value(v + 1) {} + constexpr wargoals_attached_id(wargoals_attached_id const& v) noexcept = default; + constexpr wargoals_attached_id(wargoals_attached_id&& v) noexcept = default; + + wargoals_attached_id& operator=(wargoals_attached_id const& v) noexcept = default; + wargoals_attached_id& operator=(wargoals_attached_id&& v) noexcept = default; + constexpr bool operator==(wargoals_attached_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(wargoals_attached_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class wargoals_attached_id_pair { + public: + wargoals_attached_id left; + wargoals_attached_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(wargoals_attached_id id) { return bool(id); } + + // + // definition of strongly typed index for peace_offer_item_id + // + class peace_offer_item_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr peace_offer_item_id() noexcept = default; + explicit constexpr peace_offer_item_id(uint16_t v) noexcept : value(v + 1) {} + constexpr peace_offer_item_id(peace_offer_item_id const& v) noexcept = default; + constexpr peace_offer_item_id(peace_offer_item_id&& v) noexcept = default; + + peace_offer_item_id& operator=(peace_offer_item_id const& v) noexcept = default; + peace_offer_item_id& operator=(peace_offer_item_id&& v) noexcept = default; + constexpr bool operator==(peace_offer_item_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(peace_offer_item_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class peace_offer_item_id_pair { + public: + peace_offer_item_id left; + peace_offer_item_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(peace_offer_item_id id) { return bool(id); } + + // + // definition of strongly typed index for state_definition_id + // + class state_definition_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr state_definition_id() noexcept = default; + explicit constexpr state_definition_id(uint16_t v) noexcept : value(v + 1) {} + constexpr state_definition_id(state_definition_id const& v) noexcept = default; + constexpr state_definition_id(state_definition_id&& v) noexcept = default; + + state_definition_id& operator=(state_definition_id const& v) noexcept = default; + state_definition_id& operator=(state_definition_id&& v) noexcept = default; + constexpr bool operator==(state_definition_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(state_definition_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class state_definition_id_pair { + public: + state_definition_id left; + state_definition_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(state_definition_id id) { return bool(id); } + + // + // definition of strongly typed index for administration_id + // + class administration_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr administration_id() noexcept = default; + explicit constexpr administration_id(uint16_t v) noexcept : value(v + 1) {} + constexpr administration_id(administration_id const& v) noexcept = default; + constexpr administration_id(administration_id&& v) noexcept = default; + + administration_id& operator=(administration_id const& v) noexcept = default; + administration_id& operator=(administration_id&& v) noexcept = default; + constexpr bool operator==(administration_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(administration_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class administration_id_pair { + public: + administration_id left; + administration_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(administration_id id) { return bool(id); } + + // + // definition of strongly typed index for nation_administration_id + // + class nation_administration_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr nation_administration_id() noexcept = default; + explicit constexpr nation_administration_id(uint16_t v) noexcept : value(v + 1) {} + constexpr nation_administration_id(nation_administration_id const& v) noexcept = default; + constexpr nation_administration_id(nation_administration_id&& v) noexcept = default; + + nation_administration_id& operator=(nation_administration_id const& v) noexcept = default; + nation_administration_id& operator=(nation_administration_id&& v) noexcept = default; + constexpr bool operator==(nation_administration_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(nation_administration_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class nation_administration_id_pair { + public: + nation_administration_id left; + nation_administration_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(nation_administration_id id) { return bool(id); } + + // + // definition of strongly typed index for state_instance_id + // + class state_instance_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr state_instance_id() noexcept = default; + explicit constexpr state_instance_id(uint16_t v) noexcept : value(v + 1) {} + constexpr state_instance_id(state_instance_id const& v) noexcept = default; + constexpr state_instance_id(state_instance_id&& v) noexcept = default; + + state_instance_id& operator=(state_instance_id const& v) noexcept = default; + state_instance_id& operator=(state_instance_id&& v) noexcept = default; + constexpr bool operator==(state_instance_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(state_instance_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class state_instance_id_pair { + public: + state_instance_id left; + state_instance_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(state_instance_id id) { return bool(id); } + + // + // definition of strongly typed index for colonization_id + // + class colonization_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr colonization_id() noexcept = default; + explicit constexpr colonization_id(uint16_t v) noexcept : value(v + 1) {} + constexpr colonization_id(colonization_id const& v) noexcept = default; + constexpr colonization_id(colonization_id&& v) noexcept = default; + + colonization_id& operator=(colonization_id const& v) noexcept = default; + colonization_id& operator=(colonization_id&& v) noexcept = default; + constexpr bool operator==(colonization_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(colonization_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class colonization_id_pair { + public: + colonization_id left; + colonization_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(colonization_id id) { return bool(id); } + + // + // definition of strongly typed index for state_ownership_id + // + class state_ownership_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr state_ownership_id() noexcept = default; + explicit constexpr state_ownership_id(uint16_t v) noexcept : value(v + 1) {} + constexpr state_ownership_id(state_ownership_id const& v) noexcept = default; + constexpr state_ownership_id(state_ownership_id&& v) noexcept = default; + + state_ownership_id& operator=(state_ownership_id const& v) noexcept = default; + state_ownership_id& operator=(state_ownership_id&& v) noexcept = default; + constexpr bool operator==(state_ownership_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(state_ownership_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class state_ownership_id_pair { + public: + state_ownership_id left; + state_ownership_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(state_ownership_id id) { return bool(id); } + + // + // definition of strongly typed index for flashpoint_focus_id + // + class flashpoint_focus_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr flashpoint_focus_id() noexcept = default; + explicit constexpr flashpoint_focus_id(uint16_t v) noexcept : value(v + 1) {} + constexpr flashpoint_focus_id(flashpoint_focus_id const& v) noexcept = default; + constexpr flashpoint_focus_id(flashpoint_focus_id&& v) noexcept = default; + + flashpoint_focus_id& operator=(flashpoint_focus_id const& v) noexcept = default; + flashpoint_focus_id& operator=(flashpoint_focus_id&& v) noexcept = default; + constexpr bool operator==(flashpoint_focus_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(flashpoint_focus_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class flashpoint_focus_id_pair { + public: + flashpoint_focus_id left; + flashpoint_focus_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(flashpoint_focus_id id) { return bool(id); } + + // + // definition of strongly typed index for abstract_state_membership_id + // + class abstract_state_membership_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr abstract_state_membership_id() noexcept = default; + explicit constexpr abstract_state_membership_id(uint16_t v) noexcept : value(v + 1) {} + constexpr abstract_state_membership_id(abstract_state_membership_id const& v) noexcept = default; + constexpr abstract_state_membership_id(abstract_state_membership_id&& v) noexcept = default; + + abstract_state_membership_id& operator=(abstract_state_membership_id const& v) noexcept = default; + abstract_state_membership_id& operator=(abstract_state_membership_id&& v) noexcept = default; + constexpr bool operator==(abstract_state_membership_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(abstract_state_membership_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class abstract_state_membership_id_pair { + public: + abstract_state_membership_id left; + abstract_state_membership_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(abstract_state_membership_id id) { return bool(id); } + + // + // definition of strongly typed index for region_id + // + class region_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr region_id() noexcept = default; + explicit constexpr region_id(uint16_t v) noexcept : value(v + 1) {} + constexpr region_id(region_id const& v) noexcept = default; + constexpr region_id(region_id&& v) noexcept = default; + + region_id& operator=(region_id const& v) noexcept = default; + region_id& operator=(region_id&& v) noexcept = default; + constexpr bool operator==(region_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(region_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class region_id_pair { + public: + region_id left; + region_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(region_id id) { return bool(id); } + + // + // definition of strongly typed index for region_membership_id + // + class region_membership_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr region_membership_id() noexcept = default; + explicit constexpr region_membership_id(uint16_t v) noexcept : value(v + 1) {} + constexpr region_membership_id(region_membership_id const& v) noexcept = default; + constexpr region_membership_id(region_membership_id&& v) noexcept = default; + + region_membership_id& operator=(region_membership_id const& v) noexcept = default; + region_membership_id& operator=(region_membership_id&& v) noexcept = default; + constexpr bool operator==(region_membership_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(region_membership_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class region_membership_id_pair { + public: + region_membership_id left; + region_membership_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(region_membership_id id) { return bool(id); } + + // + // definition of strongly typed index for core_id + // + class core_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr core_id() noexcept = default; + explicit constexpr core_id(uint16_t v) noexcept : value(v + 1) {} + constexpr core_id(core_id const& v) noexcept = default; + constexpr core_id(core_id&& v) noexcept = default; + + core_id& operator=(core_id const& v) noexcept = default; + core_id& operator=(core_id&& v) noexcept = default; + constexpr bool operator==(core_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(core_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class core_id_pair { + public: + core_id left; + core_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(core_id id) { return bool(id); } + + // + // definition of strongly typed index for identity_holder_id + // + class identity_holder_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr identity_holder_id() noexcept = default; + explicit constexpr identity_holder_id(uint16_t v) noexcept : value(v + 1) {} + constexpr identity_holder_id(identity_holder_id const& v) noexcept = default; + constexpr identity_holder_id(identity_holder_id&& v) noexcept = default; + + identity_holder_id& operator=(identity_holder_id const& v) noexcept = default; + identity_holder_id& operator=(identity_holder_id&& v) noexcept = default; + constexpr bool operator==(identity_holder_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(identity_holder_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class identity_holder_id_pair { + public: + identity_holder_id left; + identity_holder_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(identity_holder_id id) { return bool(id); } + + // + // definition of strongly typed index for technology_id + // + class technology_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr technology_id() noexcept = default; + explicit constexpr technology_id(uint16_t v) noexcept : value(v + 1) {} + constexpr technology_id(technology_id const& v) noexcept = default; + constexpr technology_id(technology_id&& v) noexcept = default; + + technology_id& operator=(technology_id const& v) noexcept = default; + technology_id& operator=(technology_id&& v) noexcept = default; + constexpr bool operator==(technology_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(technology_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class technology_id_pair { + public: + technology_id left; + technology_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(technology_id id) { return bool(id); } + + // + // definition of strongly typed index for invention_id + // + class invention_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr invention_id() noexcept = default; + explicit constexpr invention_id(uint16_t v) noexcept : value(v + 1) {} + constexpr invention_id(invention_id const& v) noexcept = default; + constexpr invention_id(invention_id&& v) noexcept = default; + + invention_id& operator=(invention_id const& v) noexcept = default; + invention_id& operator=(invention_id&& v) noexcept = default; + constexpr bool operator==(invention_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(invention_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class invention_id_pair { + public: + invention_id left; + invention_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(invention_id id) { return bool(id); } + + // + // definition of strongly typed index for nation_id + // + class nation_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr nation_id() noexcept = default; + explicit constexpr nation_id(uint16_t v) noexcept : value(v + 1) {} + constexpr nation_id(nation_id const& v) noexcept = default; + constexpr nation_id(nation_id&& v) noexcept = default; + + nation_id& operator=(nation_id const& v) noexcept = default; + nation_id& operator=(nation_id&& v) noexcept = default; + constexpr bool operator==(nation_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(nation_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class nation_id_pair { + public: + nation_id left; + nation_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(nation_id id) { return bool(id); } + + // + // definition of strongly typed index for market_id + // + class market_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr market_id() noexcept = default; + explicit constexpr market_id(uint16_t v) noexcept : value(v + 1) {} + constexpr market_id(market_id const& v) noexcept = default; + constexpr market_id(market_id&& v) noexcept = default; + + market_id& operator=(market_id const& v) noexcept = default; + market_id& operator=(market_id&& v) noexcept = default; + constexpr bool operator==(market_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(market_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class market_id_pair { + public: + market_id left; + market_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(market_id id) { return bool(id); } + + // + // definition of strongly typed index for local_market_id + // + class local_market_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr local_market_id() noexcept = default; + explicit constexpr local_market_id(uint16_t v) noexcept : value(v + 1) {} + constexpr local_market_id(local_market_id const& v) noexcept = default; + constexpr local_market_id(local_market_id&& v) noexcept = default; + + local_market_id& operator=(local_market_id const& v) noexcept = default; + local_market_id& operator=(local_market_id&& v) noexcept = default; + constexpr bool operator==(local_market_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(local_market_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class local_market_id_pair { + public: + local_market_id left; + local_market_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(local_market_id id) { return bool(id); } + + // + // definition of strongly typed index for trade_route_id + // + class trade_route_id { + public: + using value_base_t = uint32_t; + using zero_is_null_t = std::true_type; + + uint32_t value = 0; + + constexpr trade_route_id() noexcept = default; + explicit constexpr trade_route_id(uint32_t v) noexcept : value(v + 1) {} + constexpr trade_route_id(trade_route_id const& v) noexcept = default; + constexpr trade_route_id(trade_route_id&& v) noexcept = default; + + trade_route_id& operator=(trade_route_id const& v) noexcept = default; + trade_route_id& operator=(trade_route_id&& v) noexcept = default; + constexpr bool operator==(trade_route_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(trade_route_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint32_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class trade_route_id_pair { + public: + trade_route_id left; + trade_route_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(trade_route_id id) { return bool(id); } + + // + // definition of strongly typed index for diplomatic_relation_id + // + class diplomatic_relation_id { + public: + using value_base_t = uint32_t; + using zero_is_null_t = std::true_type; + + uint32_t value = 0; + + constexpr diplomatic_relation_id() noexcept = default; + explicit constexpr diplomatic_relation_id(uint32_t v) noexcept : value(v + 1) {} + constexpr diplomatic_relation_id(diplomatic_relation_id const& v) noexcept = default; + constexpr diplomatic_relation_id(diplomatic_relation_id&& v) noexcept = default; + + diplomatic_relation_id& operator=(diplomatic_relation_id const& v) noexcept = default; + diplomatic_relation_id& operator=(diplomatic_relation_id&& v) noexcept = default; + constexpr bool operator==(diplomatic_relation_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(diplomatic_relation_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint32_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class diplomatic_relation_id_pair { + public: + diplomatic_relation_id left; + diplomatic_relation_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(diplomatic_relation_id id) { return bool(id); } + + // + // definition of strongly typed index for unilateral_relationship_id + // + class unilateral_relationship_id { + public: + using value_base_t = uint32_t; + using zero_is_null_t = std::true_type; + + uint32_t value = 0; + + constexpr unilateral_relationship_id() noexcept = default; + explicit constexpr unilateral_relationship_id(uint32_t v) noexcept : value(v + 1) {} + constexpr unilateral_relationship_id(unilateral_relationship_id const& v) noexcept = default; + constexpr unilateral_relationship_id(unilateral_relationship_id&& v) noexcept = default; + + unilateral_relationship_id& operator=(unilateral_relationship_id const& v) noexcept = default; + unilateral_relationship_id& operator=(unilateral_relationship_id&& v) noexcept = default; + constexpr bool operator==(unilateral_relationship_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(unilateral_relationship_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint32_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class unilateral_relationship_id_pair { + public: + unilateral_relationship_id left; + unilateral_relationship_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(unilateral_relationship_id id) { return bool(id); } + + // + // definition of strongly typed index for gp_relationship_id + // + class gp_relationship_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr gp_relationship_id() noexcept = default; + explicit constexpr gp_relationship_id(uint16_t v) noexcept : value(v + 1) {} + constexpr gp_relationship_id(gp_relationship_id const& v) noexcept = default; + constexpr gp_relationship_id(gp_relationship_id&& v) noexcept = default; + + gp_relationship_id& operator=(gp_relationship_id const& v) noexcept = default; + gp_relationship_id& operator=(gp_relationship_id&& v) noexcept = default; + constexpr bool operator==(gp_relationship_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(gp_relationship_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class gp_relationship_id_pair { + public: + gp_relationship_id left; + gp_relationship_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(gp_relationship_id id) { return bool(id); } + + // + // definition of strongly typed index for factory_id + // + class factory_id { + public: + using value_base_t = uint32_t; + using zero_is_null_t = std::true_type; + + uint32_t value = 0; + + constexpr factory_id() noexcept = default; + explicit constexpr factory_id(uint32_t v) noexcept : value(v + 1) {} + constexpr factory_id(factory_id const& v) noexcept = default; + constexpr factory_id(factory_id&& v) noexcept = default; + + factory_id& operator=(factory_id const& v) noexcept = default; + factory_id& operator=(factory_id&& v) noexcept = default; + constexpr bool operator==(factory_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(factory_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint32_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class factory_id_pair { + public: + factory_id left; + factory_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(factory_id id) { return bool(id); } + + // + // definition of strongly typed index for factory_location_id + // + class factory_location_id { + public: + using value_base_t = uint32_t; + using zero_is_null_t = std::true_type; + + uint32_t value = 0; + + constexpr factory_location_id() noexcept = default; + explicit constexpr factory_location_id(uint32_t v) noexcept : value(v + 1) {} + constexpr factory_location_id(factory_location_id const& v) noexcept = default; + constexpr factory_location_id(factory_location_id&& v) noexcept = default; + + factory_location_id& operator=(factory_location_id const& v) noexcept = default; + factory_location_id& operator=(factory_location_id&& v) noexcept = default; + constexpr bool operator==(factory_location_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(factory_location_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint32_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class factory_location_id_pair { + public: + factory_location_id left; + factory_location_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(factory_location_id id) { return bool(id); } + + // + // definition of strongly typed index for province_ownership_id + // + class province_ownership_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr province_ownership_id() noexcept = default; + explicit constexpr province_ownership_id(uint16_t v) noexcept : value(v + 1) {} + constexpr province_ownership_id(province_ownership_id const& v) noexcept = default; + constexpr province_ownership_id(province_ownership_id&& v) noexcept = default; + + province_ownership_id& operator=(province_ownership_id const& v) noexcept = default; + province_ownership_id& operator=(province_ownership_id&& v) noexcept = default; + constexpr bool operator==(province_ownership_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(province_ownership_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class province_ownership_id_pair { + public: + province_ownership_id left; + province_ownership_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(province_ownership_id id) { return bool(id); } + + // + // definition of strongly typed index for province_control_id + // + class province_control_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr province_control_id() noexcept = default; + explicit constexpr province_control_id(uint16_t v) noexcept : value(v + 1) {} + constexpr province_control_id(province_control_id const& v) noexcept = default; + constexpr province_control_id(province_control_id&& v) noexcept = default; + + province_control_id& operator=(province_control_id const& v) noexcept = default; + province_control_id& operator=(province_control_id&& v) noexcept = default; + constexpr bool operator==(province_control_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(province_control_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class province_control_id_pair { + public: + province_control_id left; + province_control_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(province_control_id id) { return bool(id); } + + // + // definition of strongly typed index for province_rebel_control_id + // + class province_rebel_control_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr province_rebel_control_id() noexcept = default; + explicit constexpr province_rebel_control_id(uint16_t v) noexcept : value(v + 1) {} + constexpr province_rebel_control_id(province_rebel_control_id const& v) noexcept = default; + constexpr province_rebel_control_id(province_rebel_control_id&& v) noexcept = default; + + province_rebel_control_id& operator=(province_rebel_control_id const& v) noexcept = default; + province_rebel_control_id& operator=(province_rebel_control_id&& v) noexcept = default; + constexpr bool operator==(province_rebel_control_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(province_rebel_control_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class province_rebel_control_id_pair { + public: + province_rebel_control_id left; + province_rebel_control_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(province_rebel_control_id id) { return bool(id); } + + // + // definition of strongly typed index for province_land_construction_id + // + class province_land_construction_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr province_land_construction_id() noexcept = default; + explicit constexpr province_land_construction_id(uint16_t v) noexcept : value(v + 1) {} + constexpr province_land_construction_id(province_land_construction_id const& v) noexcept = default; + constexpr province_land_construction_id(province_land_construction_id&& v) noexcept = default; + + province_land_construction_id& operator=(province_land_construction_id const& v) noexcept = default; + province_land_construction_id& operator=(province_land_construction_id&& v) noexcept = default; + constexpr bool operator==(province_land_construction_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(province_land_construction_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class province_land_construction_id_pair { + public: + province_land_construction_id left; + province_land_construction_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(province_land_construction_id id) { return bool(id); } + + // + // definition of strongly typed index for province_naval_construction_id + // + class province_naval_construction_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr province_naval_construction_id() noexcept = default; + explicit constexpr province_naval_construction_id(uint16_t v) noexcept : value(v + 1) {} + constexpr province_naval_construction_id(province_naval_construction_id const& v) noexcept = default; + constexpr province_naval_construction_id(province_naval_construction_id&& v) noexcept = default; + + province_naval_construction_id& operator=(province_naval_construction_id const& v) noexcept = default; + province_naval_construction_id& operator=(province_naval_construction_id&& v) noexcept = default; + constexpr bool operator==(province_naval_construction_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(province_naval_construction_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class province_naval_construction_id_pair { + public: + province_naval_construction_id left; + province_naval_construction_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(province_naval_construction_id id) { return bool(id); } + + // + // definition of strongly typed index for province_building_construction_id + // + class province_building_construction_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr province_building_construction_id() noexcept = default; + explicit constexpr province_building_construction_id(uint16_t v) noexcept : value(v + 1) {} + constexpr province_building_construction_id(province_building_construction_id const& v) noexcept = default; + constexpr province_building_construction_id(province_building_construction_id&& v) noexcept = default; + + province_building_construction_id& operator=(province_building_construction_id const& v) noexcept = default; + province_building_construction_id& operator=(province_building_construction_id&& v) noexcept = default; + constexpr bool operator==(province_building_construction_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(province_building_construction_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class province_building_construction_id_pair { + public: + province_building_construction_id left; + province_building_construction_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(province_building_construction_id id) { return bool(id); } + + // + // definition of strongly typed index for factory_construction_id + // + class factory_construction_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr factory_construction_id() noexcept = default; + explicit constexpr factory_construction_id(uint16_t v) noexcept : value(v + 1) {} + constexpr factory_construction_id(factory_construction_id const& v) noexcept = default; + constexpr factory_construction_id(factory_construction_id&& v) noexcept = default; + + factory_construction_id& operator=(factory_construction_id const& v) noexcept = default; + factory_construction_id& operator=(factory_construction_id&& v) noexcept = default; + constexpr bool operator==(factory_construction_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(factory_construction_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class factory_construction_id_pair { + public: + factory_construction_id left; + factory_construction_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(factory_construction_id id) { return bool(id); } + + // + // definition of strongly typed index for overlord_id + // + class overlord_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr overlord_id() noexcept = default; + explicit constexpr overlord_id(uint16_t v) noexcept : value(v + 1) {} + constexpr overlord_id(overlord_id const& v) noexcept = default; + constexpr overlord_id(overlord_id&& v) noexcept = default; + + overlord_id& operator=(overlord_id const& v) noexcept = default; + overlord_id& operator=(overlord_id&& v) noexcept = default; + constexpr bool operator==(overlord_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(overlord_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class overlord_id_pair { + public: + overlord_id left; + overlord_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(overlord_id id) { return bool(id); } + + // + // definition of strongly typed index for rebel_faction_id + // + class rebel_faction_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr rebel_faction_id() noexcept = default; + explicit constexpr rebel_faction_id(uint16_t v) noexcept : value(v + 1) {} + constexpr rebel_faction_id(rebel_faction_id const& v) noexcept = default; + constexpr rebel_faction_id(rebel_faction_id&& v) noexcept = default; + + rebel_faction_id& operator=(rebel_faction_id const& v) noexcept = default; + rebel_faction_id& operator=(rebel_faction_id&& v) noexcept = default; + constexpr bool operator==(rebel_faction_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(rebel_faction_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class rebel_faction_id_pair { + public: + rebel_faction_id left; + rebel_faction_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(rebel_faction_id id) { return bool(id); } + + // + // definition of strongly typed index for rebellion_within_id + // + class rebellion_within_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr rebellion_within_id() noexcept = default; + explicit constexpr rebellion_within_id(uint16_t v) noexcept : value(v + 1) {} + constexpr rebellion_within_id(rebellion_within_id const& v) noexcept = default; + constexpr rebellion_within_id(rebellion_within_id&& v) noexcept = default; + + rebellion_within_id& operator=(rebellion_within_id const& v) noexcept = default; + rebellion_within_id& operator=(rebellion_within_id&& v) noexcept = default; + constexpr bool operator==(rebellion_within_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(rebellion_within_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class rebellion_within_id_pair { + public: + rebellion_within_id left; + rebellion_within_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(rebellion_within_id id) { return bool(id); } + + // + // definition of strongly typed index for movement_id + // + class movement_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr movement_id() noexcept = default; + explicit constexpr movement_id(uint16_t v) noexcept : value(v + 1) {} + constexpr movement_id(movement_id const& v) noexcept = default; + constexpr movement_id(movement_id&& v) noexcept = default; + + movement_id& operator=(movement_id const& v) noexcept = default; + movement_id& operator=(movement_id&& v) noexcept = default; + constexpr bool operator==(movement_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(movement_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class movement_id_pair { + public: + movement_id left; + movement_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(movement_id id) { return bool(id); } + + // + // definition of strongly typed index for movement_within_id + // + class movement_within_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr movement_within_id() noexcept = default; + explicit constexpr movement_within_id(uint16_t v) noexcept : value(v + 1) {} + constexpr movement_within_id(movement_within_id const& v) noexcept = default; + constexpr movement_within_id(movement_within_id&& v) noexcept = default; + + movement_within_id& operator=(movement_within_id const& v) noexcept = default; + movement_within_id& operator=(movement_within_id&& v) noexcept = default; + constexpr bool operator==(movement_within_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(movement_within_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class movement_within_id_pair { + public: + movement_within_id left; + movement_within_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(movement_within_id id) { return bool(id); } + + // + // definition of strongly typed index for pop_movement_membership_id + // + class pop_movement_membership_id { + public: + using value_base_t = uint32_t; + using zero_is_null_t = std::true_type; + + uint32_t value = 0; + + constexpr pop_movement_membership_id() noexcept = default; + explicit constexpr pop_movement_membership_id(uint32_t v) noexcept : value(v + 1) {} + constexpr pop_movement_membership_id(pop_movement_membership_id const& v) noexcept = default; + constexpr pop_movement_membership_id(pop_movement_membership_id&& v) noexcept = default; + + pop_movement_membership_id& operator=(pop_movement_membership_id const& v) noexcept = default; + pop_movement_membership_id& operator=(pop_movement_membership_id&& v) noexcept = default; + constexpr bool operator==(pop_movement_membership_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(pop_movement_membership_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint32_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class pop_movement_membership_id_pair { + public: + pop_movement_membership_id left; + pop_movement_membership_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(pop_movement_membership_id id) { return bool(id); } + + // + // definition of strongly typed index for pop_rebellion_membership_id + // + class pop_rebellion_membership_id { + public: + using value_base_t = uint32_t; + using zero_is_null_t = std::true_type; + + uint32_t value = 0; + + constexpr pop_rebellion_membership_id() noexcept = default; + explicit constexpr pop_rebellion_membership_id(uint32_t v) noexcept : value(v + 1) {} + constexpr pop_rebellion_membership_id(pop_rebellion_membership_id const& v) noexcept = default; + constexpr pop_rebellion_membership_id(pop_rebellion_membership_id&& v) noexcept = default; + + pop_rebellion_membership_id& operator=(pop_rebellion_membership_id const& v) noexcept = default; + pop_rebellion_membership_id& operator=(pop_rebellion_membership_id&& v) noexcept = default; + constexpr bool operator==(pop_rebellion_membership_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(pop_rebellion_membership_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint32_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class pop_rebellion_membership_id_pair { + public: + pop_rebellion_membership_id left; + pop_rebellion_membership_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(pop_rebellion_membership_id id) { return bool(id); } + + // + // definition of strongly typed index for pop_id + // + class pop_id { + public: + using value_base_t = uint32_t; + using zero_is_null_t = std::true_type; + + uint32_t value = 0; + + constexpr pop_id() noexcept = default; + explicit constexpr pop_id(uint32_t v) noexcept : value(v + 1) {} + constexpr pop_id(pop_id const& v) noexcept = default; + constexpr pop_id(pop_id&& v) noexcept = default; + + pop_id& operator=(pop_id const& v) noexcept = default; + pop_id& operator=(pop_id&& v) noexcept = default; + constexpr bool operator==(pop_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(pop_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint32_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class pop_id_pair { + public: + pop_id left; + pop_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(pop_id id) { return bool(id); } + + // + // definition of strongly typed index for pop_location_id + // + class pop_location_id { + public: + using value_base_t = uint32_t; + using zero_is_null_t = std::true_type; + + uint32_t value = 0; + + constexpr pop_location_id() noexcept = default; + explicit constexpr pop_location_id(uint32_t v) noexcept : value(v + 1) {} + constexpr pop_location_id(pop_location_id const& v) noexcept = default; + constexpr pop_location_id(pop_location_id&& v) noexcept = default; + + pop_location_id& operator=(pop_location_id const& v) noexcept = default; + pop_location_id& operator=(pop_location_id&& v) noexcept = default; + constexpr bool operator==(pop_location_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(pop_location_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint32_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class pop_location_id_pair { + public: + pop_location_id left; + pop_location_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(pop_location_id id) { return bool(id); } + + // + // definition of strongly typed index for national_event_id + // + class national_event_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr national_event_id() noexcept = default; + explicit constexpr national_event_id(uint16_t v) noexcept : value(v + 1) {} + constexpr national_event_id(national_event_id const& v) noexcept = default; + constexpr national_event_id(national_event_id&& v) noexcept = default; + + national_event_id& operator=(national_event_id const& v) noexcept = default; + national_event_id& operator=(national_event_id&& v) noexcept = default; + constexpr bool operator==(national_event_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(national_event_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class national_event_id_pair { + public: + national_event_id left; + national_event_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(national_event_id id) { return bool(id); } + + // + // definition of strongly typed index for provincial_event_id + // + class provincial_event_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr provincial_event_id() noexcept = default; + explicit constexpr provincial_event_id(uint16_t v) noexcept : value(v + 1) {} + constexpr provincial_event_id(provincial_event_id const& v) noexcept = default; + constexpr provincial_event_id(provincial_event_id&& v) noexcept = default; + + provincial_event_id& operator=(provincial_event_id const& v) noexcept = default; + provincial_event_id& operator=(provincial_event_id&& v) noexcept = default; + constexpr bool operator==(provincial_event_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(provincial_event_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class provincial_event_id_pair { + public: + provincial_event_id left; + provincial_event_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(provincial_event_id id) { return bool(id); } + + // + // definition of strongly typed index for free_national_event_id + // + class free_national_event_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr free_national_event_id() noexcept = default; + explicit constexpr free_national_event_id(uint16_t v) noexcept : value(v + 1) {} + constexpr free_national_event_id(free_national_event_id const& v) noexcept = default; + constexpr free_national_event_id(free_national_event_id&& v) noexcept = default; + + free_national_event_id& operator=(free_national_event_id const& v) noexcept = default; + free_national_event_id& operator=(free_national_event_id&& v) noexcept = default; + constexpr bool operator==(free_national_event_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(free_national_event_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class free_national_event_id_pair { + public: + free_national_event_id left; + free_national_event_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(free_national_event_id id) { return bool(id); } + + // + // definition of strongly typed index for free_provincial_event_id + // + class free_provincial_event_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr free_provincial_event_id() noexcept = default; + explicit constexpr free_provincial_event_id(uint16_t v) noexcept : value(v + 1) {} + constexpr free_provincial_event_id(free_provincial_event_id const& v) noexcept = default; + constexpr free_provincial_event_id(free_provincial_event_id&& v) noexcept = default; + + free_provincial_event_id& operator=(free_provincial_event_id const& v) noexcept = default; + free_provincial_event_id& operator=(free_provincial_event_id&& v) noexcept = default; + constexpr bool operator==(free_provincial_event_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(free_provincial_event_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class free_provincial_event_id_pair { + public: + free_provincial_event_id left; + free_provincial_event_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(free_provincial_event_id id) { return bool(id); } + + // + // definition of strongly typed index for national_focus_id + // + class national_focus_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr national_focus_id() noexcept = default; + explicit constexpr national_focus_id(uint8_t v) noexcept : value(v + 1) {} + constexpr national_focus_id(national_focus_id const& v) noexcept = default; + constexpr national_focus_id(national_focus_id&& v) noexcept = default; + + national_focus_id& operator=(national_focus_id const& v) noexcept = default; + national_focus_id& operator=(national_focus_id&& v) noexcept = default; + constexpr bool operator==(national_focus_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(national_focus_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class national_focus_id_pair { + public: + national_focus_id left; + national_focus_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(national_focus_id id) { return bool(id); } + + // + // definition of strongly typed index for stored_trigger_id + // + class stored_trigger_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr stored_trigger_id() noexcept = default; + explicit constexpr stored_trigger_id(uint16_t v) noexcept : value(v + 1) {} + constexpr stored_trigger_id(stored_trigger_id const& v) noexcept = default; + constexpr stored_trigger_id(stored_trigger_id&& v) noexcept = default; + + stored_trigger_id& operator=(stored_trigger_id const& v) noexcept = default; + stored_trigger_id& operator=(stored_trigger_id&& v) noexcept = default; + constexpr bool operator==(stored_trigger_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(stored_trigger_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class stored_trigger_id_pair { + public: + stored_trigger_id left; + stored_trigger_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(stored_trigger_id id) { return bool(id); } + + // + // definition of strongly typed index for gamerule_id + // + class gamerule_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr gamerule_id() noexcept = default; + explicit constexpr gamerule_id(uint8_t v) noexcept : value(v + 1) {} + constexpr gamerule_id(gamerule_id const& v) noexcept = default; + constexpr gamerule_id(gamerule_id&& v) noexcept = default; + + gamerule_id& operator=(gamerule_id const& v) noexcept = default; + gamerule_id& operator=(gamerule_id&& v) noexcept = default; + constexpr bool operator==(gamerule_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(gamerule_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class gamerule_id_pair { + public: + gamerule_id left; + gamerule_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(gamerule_id id) { return bool(id); } + + // + // definition of strongly typed index for decision_id + // + class decision_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr decision_id() noexcept = default; + explicit constexpr decision_id(uint16_t v) noexcept : value(v + 1) {} + constexpr decision_id(decision_id const& v) noexcept = default; + constexpr decision_id(decision_id&& v) noexcept = default; + + decision_id& operator=(decision_id const& v) noexcept = default; + decision_id& operator=(decision_id&& v) noexcept = default; + constexpr bool operator==(decision_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(decision_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class decision_id_pair { + public: + decision_id left; + decision_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(decision_id id) { return bool(id); } + + // + // definition of strongly typed index for locale_id + // + class locale_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr locale_id() noexcept = default; + explicit constexpr locale_id(uint16_t v) noexcept : value(v + 1) {} + constexpr locale_id(locale_id const& v) noexcept = default; + constexpr locale_id(locale_id&& v) noexcept = default; + + locale_id& operator=(locale_id const& v) noexcept = default; + locale_id& operator=(locale_id&& v) noexcept = default; + constexpr bool operator==(locale_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(locale_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class locale_id_pair { + public: + locale_id left; + locale_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(locale_id id) { return bool(id); } + + // + // definition of strongly typed index for mp_player_id + // + class mp_player_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr mp_player_id() noexcept = default; + explicit constexpr mp_player_id(uint16_t v) noexcept : value(v + 1) {} + constexpr mp_player_id(mp_player_id const& v) noexcept = default; + constexpr mp_player_id(mp_player_id&& v) noexcept = default; + + mp_player_id& operator=(mp_player_id const& v) noexcept = default; + mp_player_id& operator=(mp_player_id&& v) noexcept = default; + constexpr bool operator==(mp_player_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(mp_player_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class mp_player_id_pair { + public: + mp_player_id left; + mp_player_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(mp_player_id id) { return bool(id); } + + // + // definition of strongly typed index for player_nation_id + // + class player_nation_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr player_nation_id() noexcept = default; + explicit constexpr player_nation_id(uint16_t v) noexcept : value(v + 1) {} + constexpr player_nation_id(player_nation_id const& v) noexcept = default; + constexpr player_nation_id(player_nation_id&& v) noexcept = default; + + player_nation_id& operator=(player_nation_id const& v) noexcept = default; + player_nation_id& operator=(player_nation_id&& v) noexcept = default; + constexpr bool operator==(player_nation_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(player_nation_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class player_nation_id_pair { + public: + player_nation_id left; + player_nation_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(player_nation_id id) { return bool(id); } + + // + // definition of strongly typed index for client_id + // + class client_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr client_id() noexcept = default; + explicit constexpr client_id(uint16_t v) noexcept : value(v + 1) {} + constexpr client_id(client_id const& v) noexcept = default; + constexpr client_id(client_id&& v) noexcept = default; + + client_id& operator=(client_id const& v) noexcept = default; + client_id& operator=(client_id&& v) noexcept = default; + constexpr bool operator==(client_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(client_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class client_id_pair { + public: + client_id left; + client_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(client_id id) { return bool(id); } + + // + // definition of strongly typed index for player_client_id + // + class player_client_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr player_client_id() noexcept = default; + explicit constexpr player_client_id(uint16_t v) noexcept : value(v + 1) {} + constexpr player_client_id(player_client_id const& v) noexcept = default; + constexpr player_client_id(player_client_id&& v) noexcept = default; + + player_client_id& operator=(player_client_id const& v) noexcept = default; + player_client_id& operator=(player_client_id&& v) noexcept = default; + constexpr bool operator==(player_client_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(player_client_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class player_client_id_pair { + public: + player_client_id left; + player_client_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(player_client_id id) { return bool(id); } + + // + // definition of strongly typed index for text_key + // + class text_key { + public: + using value_base_t = uint32_t; + using zero_is_null_t = std::true_type; + + uint32_t value = 0; + + constexpr text_key() noexcept = default; + explicit constexpr text_key(uint32_t v) noexcept : value(v + 1) {} + constexpr text_key(text_key const& v) noexcept = default; + constexpr text_key(text_key&& v) noexcept = default; + + text_key& operator=(text_key const& v) noexcept = default; + text_key& operator=(text_key&& v) noexcept = default; + constexpr bool operator==(text_key v) const noexcept { return value == v.value; } + constexpr bool operator!=(text_key v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint32_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class text_key_pair { + public: + text_key left; + text_key right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(text_key id) { return bool(id); } + + // + // definition of strongly typed index for texture_id + // + class texture_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr texture_id() noexcept = default; + explicit constexpr texture_id(uint16_t v) noexcept : value(v + 1) {} + constexpr texture_id(texture_id const& v) noexcept = default; + constexpr texture_id(texture_id&& v) noexcept = default; + + texture_id& operator=(texture_id const& v) noexcept = default; + texture_id& operator=(texture_id&& v) noexcept = default; + constexpr bool operator==(texture_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(texture_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class texture_id_pair { + public: + texture_id left; + texture_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(texture_id id) { return bool(id); } + + // + // definition of strongly typed index for gfx_object_id + // + class gfx_object_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr gfx_object_id() noexcept = default; + explicit constexpr gfx_object_id(uint16_t v) noexcept : value(v + 1) {} + constexpr gfx_object_id(gfx_object_id const& v) noexcept = default; + constexpr gfx_object_id(gfx_object_id&& v) noexcept = default; + + gfx_object_id& operator=(gfx_object_id const& v) noexcept = default; + gfx_object_id& operator=(gfx_object_id&& v) noexcept = default; + constexpr bool operator==(gfx_object_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(gfx_object_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class gfx_object_id_pair { + public: + gfx_object_id left; + gfx_object_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(gfx_object_id id) { return bool(id); } + + // + // definition of strongly typed index for gui_def_id + // + class gui_def_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr gui_def_id() noexcept = default; + explicit constexpr gui_def_id(uint16_t v) noexcept : value(v + 1) {} + constexpr gui_def_id(gui_def_id const& v) noexcept = default; + constexpr gui_def_id(gui_def_id&& v) noexcept = default; + + gui_def_id& operator=(gui_def_id const& v) noexcept = default; + gui_def_id& operator=(gui_def_id&& v) noexcept = default; + constexpr bool operator==(gui_def_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(gui_def_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class gui_def_id_pair { + public: + gui_def_id left; + gui_def_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(gui_def_id id) { return bool(id); } + + // + // definition of strongly typed index for crime_id + // + class crime_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr crime_id() noexcept = default; + explicit constexpr crime_id(uint8_t v) noexcept : value(v + 1) {} + constexpr crime_id(crime_id const& v) noexcept = default; + constexpr crime_id(crime_id&& v) noexcept = default; + + crime_id& operator=(crime_id const& v) noexcept = default; + crime_id& operator=(crime_id&& v) noexcept = default; + constexpr bool operator==(crime_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(crime_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class crime_id_pair { + public: + crime_id left; + crime_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(crime_id id) { return bool(id); } + + // + // definition of strongly typed index for unit_type_id + // + class unit_type_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr unit_type_id() noexcept = default; + explicit constexpr unit_type_id(uint8_t v) noexcept : value(v + 1) {} + constexpr unit_type_id(unit_type_id const& v) noexcept = default; + constexpr unit_type_id(unit_type_id&& v) noexcept = default; + + unit_type_id& operator=(unit_type_id const& v) noexcept = default; + unit_type_id& operator=(unit_type_id&& v) noexcept = default; + constexpr bool operator==(unit_type_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(unit_type_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class unit_type_id_pair { + public: + unit_type_id left; + unit_type_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(unit_type_id id) { return bool(id); } + + // + // definition of strongly typed index for unit_name_id + // + class unit_name_id { + public: + using value_base_t = uint32_t; + using zero_is_null_t = std::true_type; + + uint32_t value = 0; + + constexpr unit_name_id() noexcept = default; + explicit constexpr unit_name_id(uint32_t v) noexcept : value(v + 1) {} + constexpr unit_name_id(unit_name_id const& v) noexcept = default; + constexpr unit_name_id(unit_name_id&& v) noexcept = default; + + unit_name_id& operator=(unit_name_id const& v) noexcept = default; + unit_name_id& operator=(unit_name_id&& v) noexcept = default; + constexpr bool operator==(unit_name_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(unit_name_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint32_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class unit_name_id_pair { + public: + unit_name_id left; + unit_name_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(unit_name_id id) { return bool(id); } + + // + // definition of strongly typed index for national_variable_id + // + class national_variable_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr national_variable_id() noexcept = default; + explicit constexpr national_variable_id(uint16_t v) noexcept : value(v + 1) {} + constexpr national_variable_id(national_variable_id const& v) noexcept = default; + constexpr national_variable_id(national_variable_id&& v) noexcept = default; + + national_variable_id& operator=(national_variable_id const& v) noexcept = default; + national_variable_id& operator=(national_variable_id&& v) noexcept = default; + constexpr bool operator==(national_variable_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(national_variable_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class national_variable_id_pair { + public: + national_variable_id left; + national_variable_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(national_variable_id id) { return bool(id); } + + // + // definition of strongly typed index for national_flag_id + // + class national_flag_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr national_flag_id() noexcept = default; + explicit constexpr national_flag_id(uint16_t v) noexcept : value(v + 1) {} + constexpr national_flag_id(national_flag_id const& v) noexcept = default; + constexpr national_flag_id(national_flag_id&& v) noexcept = default; + + national_flag_id& operator=(national_flag_id const& v) noexcept = default; + national_flag_id& operator=(national_flag_id&& v) noexcept = default; + constexpr bool operator==(national_flag_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(national_flag_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class national_flag_id_pair { + public: + national_flag_id left; + national_flag_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(national_flag_id id) { return bool(id); } + + // + // definition of strongly typed index for global_flag_id + // + class global_flag_id { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr global_flag_id() noexcept = default; + explicit constexpr global_flag_id(uint16_t v) noexcept : value(v + 1) {} + constexpr global_flag_id(global_flag_id const& v) noexcept = default; + constexpr global_flag_id(global_flag_id&& v) noexcept = default; + + global_flag_id& operator=(global_flag_id const& v) noexcept = default; + global_flag_id& operator=(global_flag_id&& v) noexcept = default; + constexpr bool operator==(global_flag_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(global_flag_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class global_flag_id_pair { + public: + global_flag_id left; + global_flag_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(global_flag_id id) { return bool(id); } + + // + // definition of strongly typed index for trigger_key + // + class trigger_key { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr trigger_key() noexcept = default; + explicit constexpr trigger_key(uint16_t v) noexcept : value(v + 1) {} + constexpr trigger_key(trigger_key const& v) noexcept = default; + constexpr trigger_key(trigger_key&& v) noexcept = default; + + trigger_key& operator=(trigger_key const& v) noexcept = default; + trigger_key& operator=(trigger_key&& v) noexcept = default; + constexpr bool operator==(trigger_key v) const noexcept { return value == v.value; } + constexpr bool operator!=(trigger_key v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class trigger_key_pair { + public: + trigger_key left; + trigger_key right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(trigger_key id) { return bool(id); } + + // + // definition of strongly typed index for effect_key + // + class effect_key { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr effect_key() noexcept = default; + explicit constexpr effect_key(uint16_t v) noexcept : value(v + 1) {} + constexpr effect_key(effect_key const& v) noexcept = default; + constexpr effect_key(effect_key&& v) noexcept = default; + + effect_key& operator=(effect_key const& v) noexcept = default; + effect_key& operator=(effect_key&& v) noexcept = default; + constexpr bool operator==(effect_key v) const noexcept { return value == v.value; } + constexpr bool operator!=(effect_key v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class effect_key_pair { + public: + effect_key left; + effect_key right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(effect_key id) { return bool(id); } + + // + // definition of strongly typed index for value_modifier_key + // + class value_modifier_key { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr value_modifier_key() noexcept = default; + explicit constexpr value_modifier_key(uint16_t v) noexcept : value(v + 1) {} + constexpr value_modifier_key(value_modifier_key const& v) noexcept = default; + constexpr value_modifier_key(value_modifier_key&& v) noexcept = default; + + value_modifier_key& operator=(value_modifier_key const& v) noexcept = default; + value_modifier_key& operator=(value_modifier_key&& v) noexcept = default; + constexpr bool operator==(value_modifier_key v) const noexcept { return value == v.value; } + constexpr bool operator!=(value_modifier_key v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class value_modifier_key_pair { + public: + value_modifier_key left; + value_modifier_key right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(value_modifier_key id) { return bool(id); } + + // + // definition of strongly typed index for pop_demographics_key + // + class pop_demographics_key { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr pop_demographics_key() noexcept = default; + explicit constexpr pop_demographics_key(uint16_t v) noexcept : value(v + 1) {} + constexpr pop_demographics_key(pop_demographics_key const& v) noexcept = default; + constexpr pop_demographics_key(pop_demographics_key&& v) noexcept = default; + + pop_demographics_key& operator=(pop_demographics_key const& v) noexcept = default; + pop_demographics_key& operator=(pop_demographics_key&& v) noexcept = default; + constexpr bool operator==(pop_demographics_key v) const noexcept { return value == v.value; } + constexpr bool operator!=(pop_demographics_key v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class pop_demographics_key_pair { + public: + pop_demographics_key left; + pop_demographics_key right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(pop_demographics_key id) { return bool(id); } + + // + // definition of strongly typed index for demographics_key + // + class demographics_key { + public: + using value_base_t = uint16_t; + using zero_is_null_t = std::true_type; + + uint16_t value = 0; + + constexpr demographics_key() noexcept = default; + explicit constexpr demographics_key(uint16_t v) noexcept : value(v + 1) {} + constexpr demographics_key(demographics_key const& v) noexcept = default; + constexpr demographics_key(demographics_key&& v) noexcept = default; + + demographics_key& operator=(demographics_key const& v) noexcept = default; + demographics_key& operator=(demographics_key&& v) noexcept = default; + constexpr bool operator==(demographics_key v) const noexcept { return value == v.value; } + constexpr bool operator!=(demographics_key v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint16_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class demographics_key_pair { + public: + demographics_key left; + demographics_key right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(demographics_key id) { return bool(id); } + + // + // definition of strongly typed index for provincial_modifier_value + // + class provincial_modifier_value { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr provincial_modifier_value() noexcept = default; + explicit constexpr provincial_modifier_value(uint8_t v) noexcept : value(v + 1) {} + constexpr provincial_modifier_value(provincial_modifier_value const& v) noexcept = default; + constexpr provincial_modifier_value(provincial_modifier_value&& v) noexcept = default; + + provincial_modifier_value& operator=(provincial_modifier_value const& v) noexcept = default; + provincial_modifier_value& operator=(provincial_modifier_value&& v) noexcept = default; + constexpr bool operator==(provincial_modifier_value v) const noexcept { return value == v.value; } + constexpr bool operator!=(provincial_modifier_value v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class provincial_modifier_value_pair { + public: + provincial_modifier_value left; + provincial_modifier_value right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(provincial_modifier_value id) { return bool(id); } + + // + // definition of strongly typed index for national_modifier_value + // + class national_modifier_value { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr national_modifier_value() noexcept = default; + explicit constexpr national_modifier_value(uint8_t v) noexcept : value(v + 1) {} + constexpr national_modifier_value(national_modifier_value const& v) noexcept = default; + constexpr national_modifier_value(national_modifier_value&& v) noexcept = default; + + national_modifier_value& operator=(national_modifier_value const& v) noexcept = default; + national_modifier_value& operator=(national_modifier_value&& v) noexcept = default; + constexpr bool operator==(national_modifier_value v) const noexcept { return value == v.value; } + constexpr bool operator!=(national_modifier_value v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class national_modifier_value_pair { + public: + national_modifier_value left; + national_modifier_value right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(national_modifier_value id) { return bool(id); } + + // + // definition of strongly typed index for production_directive_id + // + class production_directive_id { + public: + using value_base_t = uint8_t; + using zero_is_null_t = std::true_type; + + uint8_t value = 0; + + constexpr production_directive_id() noexcept = default; + explicit constexpr production_directive_id(uint8_t v) noexcept : value(v + 1) {} + constexpr production_directive_id(production_directive_id const& v) noexcept = default; + constexpr production_directive_id(production_directive_id&& v) noexcept = default; + + production_directive_id& operator=(production_directive_id const& v) noexcept = default; + production_directive_id& operator=(production_directive_id&& v) noexcept = default; + constexpr bool operator==(production_directive_id v) const noexcept { return value == v.value; } + constexpr bool operator!=(production_directive_id v) const noexcept { return value != v.value; } + explicit constexpr operator bool() const noexcept { return value != uint8_t(0); } + constexpr DCON_RELEASE_INLINE int32_t index() const noexcept { + return int32_t(value) - 1; + } + }; + + class production_directive_id_pair { + public: + production_directive_id left; + production_directive_id right; + }; + + DCON_RELEASE_INLINE bool is_valid_index(production_directive_id id) { return bool(id); } + +} + +#ifndef DCON_NO_VE +namespace ve { + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + + template<> + struct value_to_vector_type_s { + using type = ::ve::tagged_vector; + }; + +} + +#endif +#ifndef DCON_RELEASE_INLINE_DEFINED +#undef DCON_RELEASE_INLINE +#ifdef _MSC_VER +#pragma warning( pop ) +#endif +#else +#undef DCON_RELEASE_INLINE_DEFINED +#endif diff --git a/src/gamestate/system_state.cpp b/src/gamestate/system_state.cpp index adc1d55ac5..19b5565b59 100644 --- a/src/gamestate/system_state.cpp +++ b/src/gamestate/system_state.cpp @@ -2818,6 +2818,31 @@ void state::load_scenario_data(parsers::error_handler& err, sys::year_month_day for(auto& r : context.map_of_technologies) { parsers::read_pending_technology(r.second.id, r.second.generator_state, err, context); } + + // Technology prerequisites form a directed graph. Reject cycles and edges which + // point backwards in the visual tree; otherwise a technology could be impossible + // to unlock or its connection could not be drawn consistently. + std::vector visit_state(world.technology_size(), 0); + std::function validate_technology = [&](dcon::technology_id technology) { + auto& marker = visit_state[technology.index()]; + if(marker == 1) { + err.accumulated_errors += "Cyclic technology prerequisite detected at technology index " + std::to_string(technology.index()) + "\n"; + return; + } + if(marker == 2) + return; + + marker = 1; + for(auto prerequisite : world.technology_get_prerequisites(technology)) { + if(world.technology_get_tree_x(prerequisite) >= world.technology_get_tree_x(technology)) { + err.accumulated_errors += "Technology prerequisite must be in an earlier tree_x column (technology index " + + std::to_string(technology.index()) + ")\n"; + } + validate_technology(prerequisite); + } + marker = 2; + }; + world.for_each_technology(validate_technology); } // read pending inventions { @@ -5048,7 +5073,8 @@ void state::single_game_tick() { rebel::rebel_hunting_check(*this); break; case 13: - ai::perform_influence_actions(*this); + // Sphere contests resolve inside nations::update_influence; the AI only + // chooses priorities during its regular strategic update. break; case 14: ai::update_focuses(*this); diff --git a/src/gui/budgetwindow.cpp b/src/gui/budgetwindow.cpp index e95b1d1c0a..3d4c22879c 100644 --- a/src/gui/budgetwindow.cpp +++ b/src/gui/budgetwindow.cpp @@ -282,6 +282,10 @@ struct budgetwindow_main_espenses_table_t : public layout_generator { struct budgetwindow_section_header_label_t : public alice_ui::template_label { // BEGIN section_header::label::variables // END + ui::tooltip_behavior has_tooltip(sys::state & state) noexcept override { + return ui::tooltip_behavior::variable_tooltip; + } + void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override; void on_update(sys::state& state) noexcept override; }; struct budgetwindow_section_header_llbutton_t : public alice_ui::template_icon_button { @@ -2684,6 +2688,126 @@ std::unique_ptr make_budgetwindow_main(sys::state& state) { ptr->on_create(state); return ptr; } +void budgetwindow_section_header_label_t::update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept { + budgetwindow_section_header_t& section_header = *((budgetwindow_section_header_t*)(parent)); + auto n = state.local_player_nation; + auto spending_details = economy::national_budget::estimate_budget_detailed(state, n, economy::estimate_next_budget(state, n)); + auto taxes = economy::explain_tax_income(state, n); + + std::string_view tooltip_key; + int32_t setting = -1; + float actual_amount = 0.f; + + switch(section_header.section_type) { + case budget_categories::diplomatic_income: + tooltip_key = "alice_budget_diplomatic_income_tt"; + actual_amount = economy::estimate_diplomatic_income(state, n); + break; + case budget_categories::poor_tax: + tooltip_key = "alice_budget_poor_tax_tt"; + setting = state.world.nation_get_poor_tax(n); + actual_amount = taxes.poor; + break; + case budget_categories::middle_tax: + tooltip_key = "alice_budget_middle_tax_tt"; + setting = state.world.nation_get_middle_tax(n); + actual_amount = taxes.mid; + break; + case budget_categories::rich_tax: + tooltip_key = "alice_budget_rich_tax_tt"; + setting = state.world.nation_get_rich_tax(n); + actual_amount = taxes.rich; + break; + case budget_categories::tariffs_import: + tooltip_key = "alice_budget_tariffs_import_tt"; + setting = state.world.nation_get_tariffs_import(n); + actual_amount = economy::estimate_tariff_import_income(state, n); + break; + case budget_categories::tariffs_export: + tooltip_key = "alice_budget_tariffs_export_tt"; + setting = state.world.nation_get_tariffs_export(n); + actual_amount = economy::estimate_tariff_export_income(state, n); + break; + case budget_categories::gold: + tooltip_key = "alice_budget_gold_tt"; + actual_amount = economy::estimate_gold_income(state, n); + break; + case budget_categories::diplomatic_expenses: + tooltip_key = "alice_budget_diplomatic_expenses_tt"; + actual_amount = spending_details.diplomacy.actual_spending; + break; + case budget_categories::social: + tooltip_key = "alice_budget_social_tt"; + setting = state.world.nation_get_social_spending(n); + actual_amount = spending_details.social.actual_spending; + break; + case budget_categories::military: + tooltip_key = "alice_budget_military_tt"; + setting = state.world.nation_get_military_spending(n); + actual_amount = spending_details.military_wages.actual_spending; + break; + case budget_categories::education: + tooltip_key = "alice_budget_education_tt"; + setting = state.world.nation_get_education_spending(n); + actual_amount = spending_details.education_wages.actual_spending; + break; + case budget_categories::admin: + tooltip_key = "alice_budget_administration_tt"; + setting = state.world.nation_get_administrative_spending(n); + actual_amount = spending_details.administration_wages.actual_spending; + break; + case budget_categories::domestic_investment: + tooltip_key = "alice_budget_domestic_investment_tt"; + setting = state.world.nation_get_domestic_investment_spending(n); + actual_amount = spending_details.domestic_investments.actual_spending; + break; + case budget_categories::overseas_spending: + tooltip_key = "alice_budget_overseas_tt"; + setting = state.world.nation_get_overseas_spending(n); + actual_amount = spending_details.overseas_penalty.actual_spending; + break; + case budget_categories::subsidies: + tooltip_key = "alice_budget_subsidies_tt"; + setting = state.world.nation_get_subsidies_spending(n); + actual_amount = spending_details.subsidy.actual_spending; + break; + case budget_categories::construction: + tooltip_key = "alice_budget_construction_tt"; + setting = state.world.nation_get_construction_spending(n); + actual_amount = spending_details.construction_supplies.actual_spending; + break; + case budget_categories::army_upkeep: + tooltip_key = "alice_budget_army_upkeep_tt"; + setting = state.world.nation_get_land_spending(n); + actual_amount = spending_details.military_supplies_land.actual_spending; + break; + case budget_categories::navy_upkeep: + tooltip_key = "alice_budget_navy_upkeep_tt"; + setting = state.world.nation_get_naval_spending(n); + actual_amount = spending_details.military_supplies_navy.actual_spending; + break; + case budget_categories::debt_payment: + tooltip_key = "alice_budget_debt_tt"; + actual_amount = spending_details.interest.actual_spending; + break; + case budget_categories::stockpile: + tooltip_key = "alice_budget_stockpile_tt"; + actual_amount = spending_details.stockpile.actual_spending; + break; + default: + return; + } + + text::add_line(state, contents, tooltip_key); + text::add_line_break_to_layout(state, contents); + auto formatted_amount = text::prettify_currency(actual_amount); + if(setting >= 0) { + text::add_line(state, contents, "alice_budget_tooltip_setting_actual", text::variable_type::x, + text::fp_percentage{ float(setting) / 100.f }, text::variable_type::val, std::string_view{ formatted_amount }); + } else { + text::add_line(state, contents, "alice_budget_tooltip_actual", text::variable_type::val, std::string_view{ formatted_amount }); + } +} void budgetwindow_section_header_label_t::on_update(sys::state& state) noexcept { budgetwindow_section_header_t& section_header = *((budgetwindow_section_header_t*)(parent)); budgetwindow_main_t& main = *((budgetwindow_main_t*)(parent->parent)); diff --git a/src/gui/gui_common_elements.hpp b/src/gui/gui_common_elements.hpp index be39e53667..d59d5c5aed 100644 --- a/src/gui/gui_common_elements.hpp +++ b/src/gui/gui_common_elements.hpp @@ -113,6 +113,19 @@ class generic_name_text : public simple_text_element_base { } }; +// Pop types are named through their localisation key rather than the generic +// get_name_as_string overload set. The classic population window still uses +// this reusable text widget for its pop-type rows. +template<> +class generic_name_text : public simple_text_element_base { +public: + void on_update(sys::state& state) noexcept override { + auto const content = retrieve(state, parent); + simple_text_element_base::set_text(state, + text::produce_simple_string(state, state.world.pop_type_get_name(content))); + } +}; + template class generic_multiline_name_text : public multiline_text_element_base { public: @@ -298,6 +311,18 @@ class province_factory_count_text : public simple_text_element_base { void on_update(sys::state& state) noexcept override; }; +// Retained for the classic population window. The newer province view no +// longer uses this text element, but the window still needs the shared state +// population presentation. +class state_population_text : public simple_text_element_base { +public: + void on_update(sys::state& state) noexcept override { + auto content = retrieve(state, parent); + auto total_pop = state.world.state_instance_get_demographics(content, demographics::total); + set_text(state, text::prettify(int32_t(total_pop))); + } +}; + class standard_nation_text : public simple_text_element_base { public: virtual std::string get_text(sys::state& state, dcon::nation_id nation_id) noexcept; diff --git a/src/gui/gui_element_types.cpp b/src/gui/gui_element_types.cpp index 14d38e0d3d..bfff12137b 100644 --- a/src/gui/gui_element_types.cpp +++ b/src/gui/gui_element_types.cpp @@ -2769,11 +2769,11 @@ void u16_text_element_base::render(sys::state& state, int32_t x, int32_t y) noex void simple_body_text::on_create(sys::state& state) noexcept { if(base_data.get_element_type() == element_type::button) { - set_text(state, text::produce_simple_string(state, base_data.data.button.txt)); black_text = text::is_black_from_font_id(base_data.data.button.font_handle); + set_text(state, text::produce_simple_string(state, base_data.data.button.txt)); } else if(base_data.get_element_type() == element_type::text) { - set_text(state, text::produce_simple_string(state, base_data.data.text.txt)); black_text = text::is_black_from_font_id(base_data.data.text.font_handle); + set_text(state, text::produce_simple_string(state, base_data.data.text.txt)); } } void simple_body_text::set_text(sys::state& state, std::string const& new_text) { diff --git a/src/gui/gui_topbar.hpp b/src/gui/gui_topbar.hpp index f62ae0b32c..9933e078f3 100644 --- a/src/gui/gui_topbar.hpp +++ b/src/gui/gui_topbar.hpp @@ -1928,29 +1928,11 @@ class topbar_sphere_icon : public standard_nation_icon { bool added_increase_header = false; for(auto it : state.world.nation_get_gp_relationship_as_great_power(n)) { - if((it.get_status() & nations::influence::is_banned) == 0) { - if(it.get_influence() >= state.defines.increaseopinion_influence_cost - && (nations::influence::level_mask & it.get_status()) != nations::influence::level_in_sphere - && (nations::influence::level_mask & it.get_status()) != nations::influence::level_friendly) { - - if(!added_increase_header) - text::add_line(state, contents, std::string_view("countryalert_canincreaseopinion")); - added_increase_header = true; - text::nation_name_and_flag(state, it.get_influence_target(), contents, 15); - } else if(!(it.get_influence_target().get_in_sphere_of()) && - it.get_influence() >= state.defines.addtosphere_influence_cost) { - if(!added_increase_header) - text::add_line(state, contents, std::string_view("countryalert_canincreaseopinion")); - added_increase_header = true; - text::nation_name_and_flag(state, it.get_influence_target(), contents, 15); - } else if(it.get_influence_target().get_in_sphere_of() - && (nations::influence::level_mask & it.get_status()) == nations::influence::level_friendly && - it.get_influence() >= state.defines.removefromsphere_influence_cost) { - if(!added_increase_header) - text::add_line(state, contents, std::string_view("countryalert_canincreaseopinion")); - added_increase_header = true; - text::nation_name_and_flag(state, it.get_influence_target(), contents, 15); - } + if((it.get_status() & nations::influence::priority_mask) != nations::influence::priority_zero) { + if(!added_increase_header) + text::add_line(state, contents, std::string_view("countryalert_canincreaseopinion")); + added_increase_header = true; + text::nation_name_and_flag(state, it.get_influence_target(), contents, 15); } } bool added_reb_header = false; @@ -2175,8 +2157,7 @@ class topbar_window : public window_element_base { return btn; } else if(name == "topbarbutton_pops") { auto btn = make_element_by_type(state, id); - //auto tab = make_element_by_type(state, "country_pop"); - auto tab = alice_ui::make_demographicswindow_main(state); + auto tab = make_element_by_type(state, "country_pop"); tab->set_visible(state, false); btn->topbar_subwindow = tab.get(); diff --git a/src/gui/map_tooltip.cpp b/src/gui/map_tooltip.cpp index 7caa38f5d7..d97748fda6 100644 --- a/src/gui/map_tooltip.cpp +++ b/src/gui/map_tooltip.cpp @@ -611,21 +611,36 @@ void sphere_map_tt_box(sys::state& state, text::columnar_layout& contents, dcon: text::localised_format_box(state, contents, box, std::string_view("sphere_of_infl_is_in_sphere"), sub); } - bool bHasDisplayedHeader = false; - for(auto gpr : fat.get_nation_from_province_ownership().get_gp_relationship_as_influence_target()) { - if(!bHasDisplayedHeader) { - text::add_line_break_to_layout_box(state, contents, box); - text::localised_single_sub_box(state, contents, box, std::string_view("sphere_of_infl_is_infl_by"), text::variable_type::country, fat.get_nation_from_province_ownership()); - text::add_line_break_to_layout_box(state, contents, box); - bHasDisplayedHeader = true; - } - text::add_to_layout_box(state, contents, box, gpr.get_great_power().id, text::text_color::yellow); - text::add_to_layout_box(state, contents, box, ( - " (" + - text::format_float(gpr.get_influence(), 0) + - ")" - ), text::text_color::white); + auto owner = fat.get_nation_from_province_ownership(); + struct contender { + dcon::nation_id nation; + float influence; + }; + std::vector contenders; + contenders.reserve(state.great_nations.size()); + for(auto const& great_nation : state.great_nations) { + auto rel = state.world.get_gp_relationship_by_gp_influence_pair(owner, great_nation.nation); + auto influence = rel ? state.world.gp_relationship_get_influence(rel) : 0.0f; + contenders.push_back(contender{ great_nation.nation, influence }); + } + + std::sort(contenders.begin(), contenders.end(), [](auto const& a, auto const& b) { + if(a.influence != b.influence) + return a.influence > b.influence; + return a.nation.index() < b.nation.index(); + }); + + if(!contenders.empty()) { text::add_line_break_to_layout_box(state, contents, box); + text::localised_single_sub_box(state, contents, box, std::string_view("sphere_of_infl_is_infl_by"), text::variable_type::country, owner); + text::add_line_break_to_layout_box(state, contents, box); + auto add_contender = [&](contender const& contender) { + text::add_to_layout_box(state, contents, box, contender.nation, text::text_color::yellow); + text::add_to_layout_box(state, contents, box, " (" + text::format_float(contender.influence, 0) + ")", text::text_color::white); + text::add_line_break_to_layout_box(state, contents, box); + }; + for(auto const& contender : contenders) + add_contender(contender); } } text::close_layout_box(contents, box); diff --git a/src/gui/topbar_subwindows/diplomacy_subwindows/gui_diplomacy_actions_window.hpp b/src/gui/topbar_subwindows/diplomacy_subwindows/gui_diplomacy_actions_window.hpp index d02c2a4689..7dbc33833d 100644 --- a/src/gui/topbar_subwindows/diplomacy_subwindows/gui_diplomacy_actions_window.hpp +++ b/src/gui/topbar_subwindows/diplomacy_subwindows/gui_diplomacy_actions_window.hpp @@ -1049,23 +1049,8 @@ class diplomacy_action_remove_from_sphere_button : public diplomacy_action_btn_l text::add_line_break_to_layout(state, contents); text::add_line_with_condition(state, contents, "iaction_explain_5", state.world.nation_get_is_great_power(state.local_player_nation)); - text::add_line_with_condition(state, contents, "iaction_explain_6", !state.world.nation_get_is_great_power(target)); - - auto rel = state.world.get_gp_relationship_by_gp_influence_pair(target, state.local_player_nation); - text::add_line_with_condition(state, contents, "iaction_explain_1", state.world.gp_relationship_get_influence(rel) >= state.defines.removefromsphere_influence_cost, text::variable_type::x, int64_t(state.defines.removefromsphere_influence_cost)); - - text::add_line_with_condition(state, contents, "iaction_explain_2", (state.world.gp_relationship_get_status(rel) & nations::influence::is_banned) == 0); - text::add_line_with_condition(state, contents, "iaction_explain_3", !military::are_at_war(state, state.local_player_nation, target)); - - text::add_line_with_condition(state, contents, "rem_sphere_explain_1", bool(state.world.nation_get_in_sphere_of(target))); - - auto clevel = (nations::influence::level_mask & state.world.gp_relationship_get_status(rel)); - if(!in_players_sphere) { - text::add_line_with_condition(state, contents, "rem_sphere_explain_2", clevel == nations::influence::level_friendly); - } else { - text::add_line_with_condition(state, contents, "rem_sphere_explain_3", true); - } + text::add_line_with_condition(state, contents, "rem_sphere_explain_3", in_players_sphere); } }; @@ -1768,10 +1753,9 @@ class diplomacy_action_gp_dialog_select_window : public window_element_base { return make_element_by_type(state, id); } else if(name == "country_selected") { return make_element_by_type(state, id); - } else if(name == "country_discredited") { - return make_element_by_type(state, id); - } else if(name == "country_banned_embassy") { - return make_element_by_type(state, id); + } else if(name == "country_discredited" || name == "country_banned_embassy") { + // Influence sabotage has been removed; keep the legacy GUI slots empty. + return nullptr; } else if(name == "country_opinion") { return make_element_by_type(state, id); } else if(name == "country_influence") { diff --git a/src/gui/topbar_subwindows/gui_diplomacy_window.hpp b/src/gui/topbar_subwindows/gui_diplomacy_window.hpp index dd7a7ce358..702b6fa3fc 100644 --- a/src/gui/topbar_subwindows/gui_diplomacy_window.hpp +++ b/src/gui/topbar_subwindows/gui_diplomacy_window.hpp @@ -490,12 +490,12 @@ class diplomacy_country_select : public button_element_base { } }; -void explain_influence(sys::state& state, dcon::nation_id target, text::columnar_layout& contents) { +void explain_influence(sys::state& state, dcon::nation_id influencer, dcon::nation_id target, text::columnar_layout& contents) { int32_t total_influence_shares = 0; - auto n = fatten(state.world, state.local_player_nation); + auto n = fatten(state.world, influencer); - for(auto rel : state.world.nation_get_gp_relationship_as_great_power(state.local_player_nation)) { - if(nations::can_accumulate_influence_with(state, state.local_player_nation, rel.get_influence_target(), rel)) { + for(auto rel : state.world.nation_get_gp_relationship_as_great_power(influencer)) { + if(nations::can_accumulate_influence_with(state, influencer, rel.get_influence_target(), rel)) { switch(rel.get_status() & nations::influence::priority_mask) { case nations::influence::priority_one: total_influence_shares += 1; @@ -513,17 +513,13 @@ void explain_influence(sys::state& state, dcon::nation_id target, text::columnar } } - auto rel = fatten(state.world, state.world.get_gp_relationship_by_gp_influence_pair(target, state.local_player_nation)); + auto rel = fatten(state.world, state.world.get_gp_relationship_by_gp_influence_pair(target, influencer)); - if((state.world.gp_relationship_get_status(rel) & nations::influence::is_banned) != 0) { - text::add_line(state, contents, "influence_explain_1"); - return; - } - if(military::has_truce_with(state, state.local_player_nation, target) && state.world.nation_get_in_sphere_of(target) != state.local_player_nation) { + if(military::has_truce_with(state, influencer, target) && state.world.nation_get_in_sphere_of(target) != influencer) { text::add_line(state, contents, "influence_explain_2"); return; } - if(military::are_at_war(state, state.local_player_nation, target)) { + if(military::are_at_war(state, influencer, target)) { text::add_line(state, contents, "influence_explain_3"); return; } @@ -535,13 +531,10 @@ void explain_influence(sys::state& state, dcon::nation_id target, text::columnar float gp_score = n.get_industrial_score() + n.get_military_score() + nations::prestige_score(state, n); float base_shares = nations::get_base_shares(state, rel, total_gain, total_influence_shares); - float total_fi = nations::get_foreign_investment(state, n); + float total_fi = nations::get_foreign_investment(state, target); auto gp_invest = state.world.unilateral_relationship_get_foreign_investment( state.world.get_unilateral_relationship_by_unilateral_pair(target, n)); - float discredit_factor = (rel.get_status() & nations::influence::is_discredited) != 0 - ? state.defines.discredit_influence_gain_factor - : 0.0f; float neighbor_factor = bool(state.world.get_nation_adjacency_by_nation_adjacency_pair(n, target)) ? state.defines.neighbour_bonus_influence_percent : 0.0f; @@ -572,7 +565,7 @@ void explain_influence(sys::state& state, dcon::nation_id target, text::columnar ? std::max(1.0f - (state.world.nation_get_industrial_score(target) + state.world.nation_get_military_score(target) + nations::prestige_score(state, target)) / gp_score, 0.0f) : 0.0f; - float total_multiplier = 1.0f + discredit_factor + neighbor_factor + sphere_neighbor_factor + continent_factor + puppet_factor + relationship_factor + investment_factor + pop_factor + score_factor; + float total_multiplier = 1.0f + neighbor_factor + sphere_neighbor_factor + continent_factor + puppet_factor + relationship_factor + investment_factor + pop_factor + score_factor; auto gain_amount = std::max(0.0f, base_shares * total_multiplier); @@ -592,13 +585,10 @@ void explain_influence(sys::state& state, dcon::nation_id target, text::columnar text::add_line(state, contents, "influence_explain_8", text::variable_type::x, text::fp_two_places{ base_shares }); - if(discredit_factor != 0 || neighbor_factor != 0 || sphere_neighbor_factor != 0 || continent_factor != 0 || puppet_factor != 0 || relationship_factor != 0 || investment_factor != 0 || pop_factor != 0 || score_factor != 0) { + if(neighbor_factor != 0 || sphere_neighbor_factor != 0 || continent_factor != 0 || puppet_factor != 0 || relationship_factor != 0 || investment_factor != 0 || pop_factor != 0 || score_factor != 0) { text::add_line(state, contents, "influence_explain_9"); - if(discredit_factor != 0) { - text::add_line(state, contents, "influence_explain_10", text::variable_type::x, text::fp_two_places{ discredit_factor }, 15); - } if(neighbor_factor != 0) { text::add_line(state, contents, "influence_explain_11", text::variable_type::x, text::fp_two_places{ neighbor_factor }, 15); } @@ -624,6 +614,8 @@ void explain_influence(sys::state& state, dcon::nation_id target, text::columnar text::add_line(state, contents, "influence_explain_18", text::variable_type::x, text::fp_two_places{ score_factor }, 15); } } + } else { + text::add_line(state, contents, "great_power_influence_no_daily_gain"); } } @@ -726,7 +718,7 @@ class diplomacy_priority_button : public right_click_button_element_base { } else if(nations::is_great_power(state, nation_id)) { text::add_line(state, contents, "diplomacy_cannot_set_prio_gp"); } else { - explain_influence(state, nation_id, contents); + explain_influence(state, state.local_player_nation, nation_id, contents); } auto box = text::open_layout_box(contents, 0); @@ -1215,9 +1207,7 @@ class gp_detail_banned : public image_element_base { public: bool show = false; void on_update(sys::state& state) noexcept override { - auto gp = nations::get_nth_great_power(state, uint16_t(retrieve(state, parent).value)); - auto target = retrieve(state, parent); - show = (state.world.gp_relationship_get_status(state.world.get_gp_relationship_by_gp_influence_pair(target, gp)) & nations::influence::is_banned) != 0; + show = false; } tooltip_behavior has_tooltip(sys::state& state) noexcept override { return show ? tooltip_behavior::variable_tooltip : tooltip_behavior::no_tooltip; @@ -1240,9 +1230,7 @@ class gp_detail_discredited : public image_element_base { public: bool show = false; void on_update(sys::state& state) noexcept override { - auto gp = nations::get_nth_great_power(state, uint16_t(retrieve(state, parent).value)); - auto target = retrieve(state, parent); - show = (state.world.gp_relationship_get_status(state.world.get_gp_relationship_by_gp_influence_pair(target, gp)) & nations::influence::is_discredited) != 0; + show = false; } tooltip_behavior has_tooltip(sys::state& state) noexcept override { return show ? tooltip_behavior::variable_tooltip : tooltip_behavior::no_tooltip; @@ -1266,8 +1254,41 @@ class great_power_opinion_detail : public simple_text_element_base { void on_update(sys::state& state) noexcept override { auto gp = nations::get_nth_great_power(state, uint16_t(retrieve(state, parent).value)); auto target = retrieve(state, parent); + auto rel = state.world.get_gp_relationship_by_gp_influence_pair(target, gp); + if(!rel) { + set_text(state, std::string{}); + return; + } - set_text(state, text::get_influence_level_name(state, state.world.gp_relationship_get_status(state.world.get_gp_relationship_by_gp_influence_pair(target, gp)))); + if(state.world.nation_get_in_sphere_of(target) == gp) { + set_text(state, text::produce_simple_string(state, "in_sphere")); + return; + } + + dcon::gp_relationship_id leader; + dcon::gp_relationship_id runner_up; + for(auto other : state.world.nation_get_gp_relationship_as_influence_target(target)) { + if(!leader || other.get_influence() > state.world.gp_relationship_get_influence(leader) || + (other.get_influence() == state.world.gp_relationship_get_influence(leader) && + other.get_great_power().id.index() < state.world.gp_relationship_get_great_power(leader).index())) { + runner_up = leader; + leader = other.id; + } else if(!runner_up || other.get_influence() > state.world.gp_relationship_get_influence(runner_up) || + (other.get_influence() == state.world.gp_relationship_get_influence(runner_up) && + other.get_great_power().id.index() < state.world.gp_relationship_get_great_power(runner_up).index())) { + runner_up = other.id; + } + } + + if(leader && state.world.gp_relationship_get_great_power(leader) == gp) { + auto lead = state.world.gp_relationship_get_influence(leader) - + (runner_up ? state.world.gp_relationship_get_influence(runner_up) : 0.0f); + set_text(state, std::string("Leader +") + text::format_float(lead, 1)); + } else if(state.world.gp_relationship_get_influence(rel) > 0.0f) { + set_text(state, std::string("Contesting")); + } else { + set_text(state, std::string{}); + } } }; class great_power_influence_detail : public simple_text_element_base { @@ -1278,6 +1299,58 @@ class great_power_influence_detail : public simple_text_element_base { set_text(state, text::format_float(state.world.gp_relationship_get_influence(state.world.get_gp_relationship_by_gp_influence_pair(target, gp)), 1)); } + tooltip_behavior has_tooltip(sys::state& state) noexcept override { + return tooltip_behavior::variable_tooltip; + } + void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override { + auto gp = nations::get_nth_great_power(state, uint16_t(retrieve(state, parent).value)); + auto target = retrieve(state, parent); + auto rel = state.world.get_gp_relationship_by_gp_influence_pair(target, gp); + auto influence = state.world.gp_relationship_get_influence(rel); + + text::add_line(state, contents, "great_power_influence_tooltip", + text::variable_type::country, gp, + text::variable_type::country2, target, + text::variable_type::x, text::fp_two_places{ influence }, + text::variable_type::y, text::fp_two_places{ state.defines.max_influence }); + + dcon::gp_relationship_id leader; + dcon::gp_relationship_id runner_up; + for(auto other : state.world.nation_get_gp_relationship_as_influence_target(target)) { + if(!leader || other.get_influence() > state.world.gp_relationship_get_influence(leader) || + (other.get_influence() == state.world.gp_relationship_get_influence(leader) && + other.get_great_power().id.index() < state.world.gp_relationship_get_great_power(leader).index())) { + runner_up = leader; + leader = other.id; + } else if(!runner_up || other.get_influence() > state.world.gp_relationship_get_influence(runner_up) || + (other.get_influence() == state.world.gp_relationship_get_influence(runner_up) && + other.get_great_power().id.index() < state.world.gp_relationship_get_great_power(runner_up).index())) { + runner_up = other.id; + } + } + + if(state.world.nation_get_in_sphere_of(target) == gp) { + text::add_line(state, contents, "great_power_influence_status_sphere"); + } else if(leader && state.world.gp_relationship_get_great_power(leader) == gp) { + text::add_line(state, contents, "great_power_influence_status_leader"); + } else if(influence > 0.0f) { + text::add_line(state, contents, "great_power_influence_status_contesting"); + } else { + text::add_line(state, contents, "great_power_influence_status_idle"); + } + + if(leader && state.world.gp_relationship_get_great_power(leader) != gp) { + auto leader_influence = state.world.gp_relationship_get_influence(leader); + text::add_line(state, contents, "great_power_influence_leader", + text::variable_type::country, state.world.gp_relationship_get_great_power(leader), + text::variable_type::x, text::fp_two_places{ leader_influence }); + text::add_line(state, contents, "great_power_influence_gap", + text::variable_type::x, text::fp_two_places{ std::max(0.0f, leader_influence - influence) }); + } + + text::add_line_break_to_layout(state, contents); + explain_influence(state, gp, target, contents); + } }; class great_power_investment_detail : public simple_text_element_base { public: @@ -1287,6 +1360,26 @@ class great_power_investment_detail : public simple_text_element_base { set_text(state, text::format_money(state.world.unilateral_relationship_get_foreign_investment(state.world.get_unilateral_relationship_by_unilateral_pair(target, gp)))); } + tooltip_behavior has_tooltip(sys::state& state) noexcept override { + return tooltip_behavior::variable_tooltip; + } + void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override { + auto gp = nations::get_nth_great_power(state, uint16_t(retrieve(state, parent).value)); + auto target = retrieve(state, parent); + auto investment = state.world.unilateral_relationship_get_foreign_investment( + state.world.get_unilateral_relationship_by_unilateral_pair(target, gp)); + auto total_investment = nations::get_foreign_investment(state, target); + auto investment_share = total_investment > 0.0f ? investment / total_investment : 0.0f; + + text::add_line(state, contents, "great_power_investment_tooltip", + text::variable_type::country, gp, + text::variable_type::country2, target, + text::variable_type::x, text::fp_currency{ investment }); + text::add_line(state, contents, "great_power_investment_share", + text::variable_type::x, text::fp_percentage{ investment_share }); + text::add_line(state, contents, "great_power_investment_influence_modifier", + text::variable_type::x, text::fp_percentage{ state.defines.investment_influence_defense * investment_share }); + } }; class great_power_detail_flag : public flag_button { @@ -1314,10 +1407,9 @@ class great_power_inf_detail : public window_element_base { return make_element_by_type(state, id); } else if(name == "nongp_country_invest") { return make_element_by_type(state, id); - } else if(name == "country_discredited") { - return make_element_by_type(state, id); - } else if(name == "country_banned_embassy") { - return make_element_by_type(state, id); + } else if(name == "country_discredited" || name == "country_banned_embassy") { + // These legacy icon slots remain empty; no texture or layout changes are needed. + return nullptr; } return nullptr; @@ -1740,7 +1832,7 @@ class diplomacy_join_war_button : public button_element_base { auto rel_w_defender = state.world.get_gp_relationship_by_gp_influence_pair(defender, state.local_player_nation); auto inf = state.world.gp_relationship_get_status(rel_w_defender) & nations::influence::level_mask; - text::add_line_with_condition(state, contents, "intervene_17", inf == nations::influence::level_friendly); + text::add_line_with_condition(state, contents, "intervene_17", inf == nations::influence::level_friendly || inf == nations::influence::level_in_sphere); text::add_line_with_condition(state, contents, "intervene_7", !state.world.war_get_is_crisis_war(w)); text::add_line_with_condition(state, contents, "intervene_9", !B); @@ -2381,16 +2473,17 @@ inline static diplomacy_action_btn_logic* leftcolumnlogics[DiplomaticActionsRows &diplomacy_action_command_units_button_s }; inline static diplomacy_action_btn_logic* rightcolumnlogics[DiplomaticActionsRows] = { - &diplomacy_action_discredit_button_s, - &diplomacy_action_expel_advisors_button_s, - &diplomacy_action_ban_embassy_button_s, - &diplomacy_action_increase_opinion_button_s, - &diplomacy_action_decrease_opinion_button_s, - &diplomacy_action_add_to_sphere_button_s, &diplomacy_action_remove_from_sphere_button_s, &diplomacy_action_justify_war_button_s, &diplomacy_action_state_transfer_button_s, - &diplomacy_action_embargo_s + &diplomacy_action_embargo_s, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr }; class diplomacy_action_btn_left : public button_element_base { diff --git a/src/gui/topbar_subwindows/gui_population_window.cpp b/src/gui/topbar_subwindows/gui_population_window.cpp index db81d2d9e7..d4147acdb8 100644 --- a/src/gui/topbar_subwindows/gui_population_window.cpp +++ b/src/gui/topbar_subwindows/gui_population_window.cpp @@ -6,7 +6,6 @@ namespace ui { -/* void pop_national_focus_button::button_action(sys::state& state) noexcept { if(parent) { Cyto::Any payload = dcon::state_instance_id{}; @@ -19,6 +18,6 @@ void pop_national_focus_button::button_action(sys::state& state) noexcept { pop_window->move_child_to_front(pop_window->nf_win); pop_window->impl_on_update(state); } -}*/ +} } // namespace ui diff --git a/src/gui/topbar_subwindows/gui_population_window.hpp b/src/gui/topbar_subwindows/gui_population_window.hpp index 8c97538b2f..677418af6b 100644 --- a/src/gui/topbar_subwindows/gui_population_window.hpp +++ b/src/gui/topbar_subwindows/gui_population_window.hpp @@ -1,30 +1,49 @@ #pragma once -/* #include "gui_element_types.hpp" #include "gui_graphics.hpp" #include "gui_common_elements.hpp" #include "province_templates.hpp" #include "color.hpp" #include "triggers.hpp" +#include "gui_listbox_templates.hpp" +#include "gui_piechart_templates.hpp" #include "gui_province_window.hpp" #include "demographics.hpp" #include "economy_stats.hpp" -*/ -namespace ui { - -/* +namespace alice_ui { void describe_conversion(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids); void describe_migration(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids); void describe_colonial_migration(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids); void describe_emigration(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids); -void describe_promotion_demotion(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids); +void describe_promotion(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids); +void describe_demotion(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids); void describe_con(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids); void describe_mil(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids); void describe_lit(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids); void describe_growth(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids); void describe_assimilation(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids); +} + +namespace ui { + +using alice_ui::describe_conversion; +using alice_ui::describe_migration; +using alice_ui::describe_colonial_migration; +using alice_ui::describe_emigration; +using alice_ui::describe_promotion; +using alice_ui::describe_demotion; +using alice_ui::describe_con; +using alice_ui::describe_mil; +using alice_ui::describe_lit; +using alice_ui::describe_growth; +using alice_ui::describe_assimilation; + +inline void describe_promotion_demotion(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids) { + describe_promotion(state, contents, ids); + describe_demotion(state, contents, ids); +} class popwin_state_population : public state_population_text { public: @@ -1019,10 +1038,16 @@ class pop_distribution_plupp : public tinted_image_element_base { } }; +struct population_chart_source { + std::vector const* pops = nullptr; +}; + template class pop_distribution_piechart : public piechart { void iterate_one_pop(sys::state& state, dcon::pop_id pop_id) { auto const weight_fn = [&](T id, float weight) { + if(weight <= 0.0f) + return; auto it = std::find_if(this->distribution.begin(), this->distribution.end(), [id](auto& e) { return e.key == id; }); if(it != this->distribution.end()) it->value += weight; @@ -1031,12 +1056,14 @@ class pop_distribution_piechart : public piechart { }; if constexpr(std::is_same_v) { + auto size = float(state.world.pop_get_size(pop_id)); for(auto iopt : state.world.in_issue_option) { - weight_fn(iopt, pop_demographics::get_demo(state, pop_id, pop_demographics::to_key(state, iopt))); + weight_fn(iopt, pop_demographics::get_demo(state, pop_id, pop_demographics::to_key(state, iopt)) * size); } } else if constexpr(std::is_same_v) { + auto size = float(state.world.pop_get_size(pop_id)); for(auto iopt : state.world.in_ideology) { - weight_fn(iopt, pop_demographics::get_demo(state, pop_id, pop_demographics::to_key(state, iopt))); + weight_fn(iopt, pop_demographics::get_demo(state, pop_id, pop_demographics::to_key(state, iopt)) * size); } } else if constexpr(std::is_same_v) { auto prov_id = state.world.pop_location_get_province(state.world.pop_get_pop_location_as_pop(pop_id)); @@ -1072,15 +1099,26 @@ class pop_distribution_piechart : public piechart { if(piechart::parent) { if constexpr(Multiple) { - //auto& pop_list = get_pop_window_list(state); - //for(auto const pop_id : pop_list) - // iterate_one_pop(state, pop_id); + auto source = retrieve(state, state.ui_state.population_subwindow); + if(source.pops) { + for(auto const pop_id : *source.pops) + iterate_one_pop(state, pop_id); + } } else { iterate_one_pop(state, retrieve(state, piechart::parent)); } } piechart::update_chart(state); + + if(piechart::parent) { + std::vector> legend; + legend.reserve(piechart::distribution.size()); + for(auto const& entry : piechart::distribution) + legend.emplace_back(entry.key, entry.value); + Cyto::Any payload = std::move(legend); + piechart::parent->impl_set(state, payload); + } } public: @@ -1170,6 +1208,17 @@ class pop_distribution_window : public window_element_base { void on_update(sys::state& state) noexcept override { } + + message_result set(sys::state& state, Cyto::Any& payload) noexcept override { + if(payload.holds_type>>()) { + if(distrib_listbox) { + distrib_listbox->row_contents = any_cast>>(payload); + distrib_listbox->update(state); + } + return message_result::consumed; + } + return message_result::unseen; + } }; class issue_with_explanation : public simple_text_element_base { @@ -2196,7 +2245,15 @@ class pop_filter_button : public generic_settable_element()) { payload.emplace(filter); return message_result::consumed; + } else if(payload.holds_type()) { + payload.emplace(population_chart_source{ country_pop_listbox ? &country_pop_listbox->row_contents : nullptr }); + return message_result::consumed; } else if(payload.holds_type()) { auto expand_action = any_cast(payload); auto sid = std::get(expand_action); @@ -2766,6 +2826,5 @@ class population_window : public window_element_base { friend class pop_national_focus_button; }; -*/ } // namespace ui diff --git a/src/gui/topbar_subwindows/gui_technology_window.cpp b/src/gui/topbar_subwindows/gui_technology_window.cpp index d93bdb866a..64da44746e 100644 --- a/src/gui/topbar_subwindows/gui_technology_window.cpp +++ b/src/gui/topbar_subwindows/gui_technology_window.cpp @@ -760,4 +760,100 @@ message_result technology_item_window::set(sys::state& state, Cyto::Any& payload } return message_result::unseen; } + +void technology_window::on_create(sys::state& state) noexcept { + generic_tabbed_window::on_create(state); + + auto tech_categories = culture::get_active_tech_categories(state); + + xy_pair folder_offset = state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("folder_offset"))->second.definition].position; + for(auto curr_folder : tech_categories) { + auto ptr = make_element_by_type(state, + state.ui_state.defs_by_name.find(state.lookup_key("folder_window"))->second.definition); + ptr->set_category(state, curr_folder); + ptr->base_data.position = folder_offset; + folder_offset.x += ptr->base_data.size.x; + add_child_to_front(std::move(ptr)); + } + + auto tree = make_element_by_type(state, "tech_tree_view"); + if(tree) + add_child_to_front(std::move(tree)); + + Cyto::Any payload = active_tab; + impl_set(state, payload); + + set_visible(state, false); +} + +std::unique_ptr technology_window::make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept { + if(name == "main_bg") { + return make_element_by_type(state, id); + } else if(name == "bg_tech") { + return make_element_by_type(state, id); + } else if(name == "close_button") { + return make_element_by_type(state, id); + } else if(name == "administration") { + return make_element_by_type(state, id); + } else if(name == "current_research") { + return make_element_by_type(state, id); + } else if(name == "administration_type") { + return make_element_by_type(state, id); + } else if(name == "research_progress") { + return make_element_by_type(state, id); + } else if(name == "research_progress_name") { + return make_element_by_type(state, id); + } else if(name == "research_progress_category") { + return make_element_by_type(state, id); + } else if(name == "selected_tech_window") { + auto ptr = make_element_by_type(state, id); + selected_tech_win = ptr.get(); + return ptr; + } else if(name == "sort_by_type") { + auto ptr = make_element_by_type(state, id); + ptr->base_data.position.y -= 1; + return ptr; + } else if(name == "sort_by_name") { + return make_element_by_type(state, id); + } else if(name == "sort_by_percent") { + auto ptr = make_element_by_type(state, id); + ptr->base_data.position.y -= 1; + return ptr; + } else if(name == "inventions") { + return make_element_by_type(state, id); + } + return nullptr; +} + +message_result technology_window::set(sys::state& state, Cyto::Any& payload) noexcept { + if(payload.holds_type()) { + active_tab = any_cast(payload); + for(auto& c : children) + c->impl_set(state, payload); + return message_result::consumed; + } else if(payload.holds_type()) { + tech_id = any_cast(payload).tech_id; + selected_tech_win->impl_on_update(state); + return message_result::consumed; + } + return message_result::unseen; +} + +message_result technology_window::get(sys::state& state, Cyto::Any& payload) noexcept { + if(payload.holds_type()) { + payload.emplace(tech_id); + return message_result::consumed; + } else if(payload.holds_type()) { + payload.emplace(state.local_player_nation); + return message_result::consumed; + } else if(payload.holds_type>()) { + invention_sort = any_cast>(payload).data; + impl_on_update(state); + return message_result::consumed; + } else if(payload.holds_type()) { + payload = invention_sort; + return message_result::consumed; + } + return message_result::unseen; +} } // namespace ui diff --git a/src/gui/topbar_subwindows/gui_technology_window.hpp b/src/gui/topbar_subwindows/gui_technology_window.hpp index b4db0c174f..c7ba92373e 100644 --- a/src/gui/topbar_subwindows/gui_technology_window.hpp +++ b/src/gui/topbar_subwindows/gui_technology_window.hpp @@ -5,6 +5,9 @@ #include "triggers.hpp" #include "gui_listbox_templates.hpp" #include "gui_templates.hpp" +#include +#include +#include namespace ui { @@ -240,6 +243,21 @@ class technology_item_button : public button_element_base { text::close_layout_box(contents, box); } technology_description(state, contents, content); + auto prerequisites = state.world.technology_get_prerequisites(content); + if(prerequisites.begin() != prerequisites.end()) { + text::add_line_break_to_layout(state, contents); + text::add_line(state, contents, "technology_prerequisites"); + for(auto prerequisite : prerequisites) { + auto const researched = state.world.nation_get_active_technologies(state.local_player_nation, prerequisite); + auto box = text::open_layout_box(contents, 15); + text::add_to_layout_box(state, contents, box, + researched ? text::embedded_icon::check : text::embedded_icon::xmark); + text::add_space_to_layout_box(state, contents, box); + text::add_to_layout_box(state, contents, box, state.world.technology_get_name(prerequisite), + researched ? text::text_color::green : text::text_color::red); + text::close_layout_box(contents, box); + } + } { auto box = text::open_layout_box(contents, 0); text::localised_format_box(state, contents, box, "tech_queue_explain"); @@ -267,6 +285,7 @@ class technology_name_text : public simple_text_element_base { class technology_item_window : public window_element_base { technology_item_button* tech_button = nullptr; + technology_name_text* tech_name = nullptr; culture::tech_category category; public: @@ -278,12 +297,34 @@ class technology_item_window : public window_element_base { tech_button = ptr.get(); return ptr; } else if(name == "tech_name") { - return make_element_by_type(state, id); + auto ptr = make_element_by_type(state, id); + tech_name = ptr.get(); + return ptr; } else { return nullptr; } } + void set_tree_scale(sys::state& state, float scale) noexcept { + auto const width = int16_t(std::max(1L, std::lround(194.0f * scale))); + auto const height = int16_t(std::max(1L, std::lround(39.0f * scale))); + base_data.size = xy_pair{ width, height }; + + if(tech_button) { + tech_button->base_data.position = xy_pair{ 0, 0 }; + tech_button->base_data.size = xy_pair{ width, height }; + } + if(tech_name) { + auto const text_x = int16_t(std::max(3L, std::lround(7.0f * scale))); + auto const text_y = int16_t(std::max(2L, std::lround(9.0f * scale))); + tech_name->base_data.position = xy_pair{ text_x, text_y }; + tech_name->base_data.size = xy_pair{ int16_t(std::max(1, width - 2 * text_x)), int16_t(std::max(1, height - text_y)) }; + // Rebuild through the specialised update, otherwise the GUI definition key + // ("TECH_NAME") replaces the technology's localized display name. + tech_name->impl_on_update(state); + } + } + void on_update(sys::state& state) noexcept override { if(!tech_id) return; @@ -802,174 +843,183 @@ class technology_sort_by_percent_button : public button_element_base { } }; -class technology_window : public generic_tabbed_window { - technology_selected_tech_window* selected_tech_win = nullptr; - dcon::technology_id tech_id{}; - invention_sort_type invention_sort = invention_sort_type::type; -public: - void on_create(sys::state& state) noexcept override { - generic_tabbed_window::on_create(state); - - auto tech_categories = culture::get_active_tech_categories(state); - - xy_pair folder_offset = state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("folder_offset"))->second.definition].position; - for(auto curr_folder : tech_categories) { - auto ptr = make_element_by_type(state, - state.ui_state.defs_by_name.find(state.lookup_key("folder_window"))->second.definition); - ptr->set_category(state, curr_folder); - ptr->base_data.position = folder_offset; - folder_offset.x += ptr->base_data.size.x; - add_child_to_front(std::move(ptr)); - } - - // Collect folders by category; the order in which we add technology groups and stuff - // will be determined by this: - // Order of category - // **** Order of folders within category - // ******** Order of appearance of technologies that have said folder? - std::vector> folders_by_category(tech_categories.size()); - for(size_t i = 0; i < state.culture_definitions.tech_folders.size(); i++) { - auto const& folder = state.culture_definitions.tech_folders[i]; - folders_by_category[static_cast(folder.category)].push_back(i); - } - // Now obtain the x-offsets of each folder (remember only one category of folders - // is ever shown at a time) - std::vector folder_x_offset(state.culture_definitions.tech_folders.size(), 0); - for(auto const& folder_category : folders_by_category) { - size_t y_offset = 0; - for(auto const folder_index : folder_category) - folder_x_offset[folder_index] = y_offset++; - } - // Technologies per folder (used for positioning!!!) - std::vector items_per_folder(state.culture_definitions.tech_folders.size(), 0); - - xy_pair base_group_offset = - state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("tech_group_offset"))->second.definition].position; - xy_pair base_tech_offset = state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("tech_offset"))->second.definition].position; - - for(auto cat : tech_categories) { - // Add tech group names - int16_t group_count = 0; - for(auto const& folder : state.culture_definitions.tech_folders) { - if(folder.category != cat) - continue; +class technology_tree_view : public window_element_base { + std::unordered_map technology_nodes; + culture::tech_category active_category = culture::tech_category::army; + int32_t pan_x = 0; + int32_t pan_y = 0; + float zoom = 1.0f; + + static constexpr int32_t horizontal_spacing = 218; + static constexpr int32_t vertical_spacing = 62; + static constexpr int32_t left_padding = 8; + static constexpr int32_t top_padding = 8; + static constexpr float minimum_zoom = 0.60f; + static constexpr float maximum_zoom = 1.35f; + + int32_t scaled(int32_t value) const noexcept { + return int32_t(std::lround(float(value) * zoom)); + } - auto ptr = make_element_by_type(state, - state.ui_state.defs_by_name.find(state.lookup_key("tech_group"))->second.definition); + bool belongs_to_active_category(sys::state& state, dcon::technology_id tech) const noexcept { + auto folder = state.world.technology_get_folder_index(tech); + return state.culture_definitions.tech_folders[folder].category == active_category; + } - ptr->category = cat; - Cyto::Any payload = culture::folder_info(folder); - ptr->impl_set(state, payload); + void clamp_pan(sys::state& state) noexcept { + int32_t content_right = base_data.size.x; + int32_t content_bottom = base_data.size.y; + for(auto const& [index, node] : technology_nodes) { + dcon::technology_id tech{ dcon::technology_id::value_base_t(index) }; + if(!belongs_to_active_category(state, tech)) + continue; + content_right = std::max(content_right, left_padding + scaled(int32_t(state.world.technology_get_tree_x(tech)) * horizontal_spacing) + node->base_data.size.x); + content_bottom = std::max(content_bottom, top_padding + scaled(int32_t(state.world.technology_get_tree_y(tech)) * vertical_spacing) + node->base_data.size.y); + } - ptr->base_data.position.x = static_cast(base_group_offset.x + (group_count * ptr->base_data.size.x)); - ptr->base_data.position.y = base_group_offset.y; - ++group_count; - add_child_to_front(std::move(ptr)); - } + pan_x = std::clamp(pan_x, std::min(0, base_data.size.x - content_right), 0); + pan_y = std::clamp(pan_y, std::min(0, base_data.size.y - content_bottom), 0); + } - // Add technologies - state.world.for_each_technology([&](dcon::technology_id tid) { - auto tech = dcon::fatten(state.world, tid); - size_t folder_id = static_cast(tech.get_folder_index()); - const auto& folder = state.culture_definitions.tech_folders[folder_id]; - if(folder.category != cat) - return; - - auto ptr = make_element_by_type(state, - state.ui_state.defs_by_name.find(state.lookup_key("tech_window"))->second.definition); - - Cyto::Any payload = tid; - ptr->impl_set(state, payload); - - ptr->base_data.position.x = - static_cast(base_group_offset.x + (folder_x_offset[folder_id] * ptr->base_data.size.x)); - // 16px spacing between tech items, 109+16 base offset - ptr->base_data.position.y = - static_cast(base_group_offset.y + base_tech_offset.y + - (static_cast(items_per_folder[folder_id]) * ptr->base_data.size.y)); - items_per_folder[folder_id]++; - add_child_to_front(std::move(ptr)); - }); + void update_node_positions(sys::state& state) noexcept { + clamp_pan(state); + for(auto const& [index, node] : technology_nodes) { + dcon::technology_id tech{ dcon::technology_id::value_base_t(index) }; + node->base_data.position.x = int16_t(left_padding + scaled(int32_t(state.world.technology_get_tree_x(tech)) * horizontal_spacing) + pan_x); + node->base_data.position.y = int16_t(top_padding + scaled(int32_t(state.world.technology_get_tree_y(tech)) * vertical_spacing) + pan_y); } + } - // Properly setup technology displays... - Cyto::Any payload = active_tab; - impl_set(state, payload); + void update_node_scales(sys::state& state) noexcept { + for(auto const& [index, node] : technology_nodes) + node->set_tree_scale(state, zoom); + } - set_visible(state, false); + void draw_connection(sys::state& state, technology_item_window const& prerequisite, technology_item_window const& technology, + bool unlocked, int32_t x, int32_t y) const noexcept { + float const r = unlocked ? 0.28f : 0.38f; + float const g = unlocked ? 0.82f : 0.38f; + float const b = unlocked ? 0.42f : 0.38f; + // The connector is deliberately flush with both card edges. + float const start_x = float(x + prerequisite.base_data.position.x + prerequisite.base_data.size.x); + float const start_y = float(y + prerequisite.base_data.position.y + prerequisite.base_data.size.y / 2); + float const end_x = float(x + technology.base_data.position.x); + float const end_y = float(y + technology.base_data.position.y + technology.base_data.size.y / 2); + float const middle_x = start_x + std::max(3.0f, (end_x - start_x) * 0.5f); + + ogl::render_alpha_colored_rect(state, start_x, start_y - 1.0f, middle_x - start_x, 2.0f, r, g, b, 1.0f); + ogl::render_alpha_colored_rect(state, middle_x - 1.0f, std::min(start_y, end_y), 2.0f, std::abs(end_y - start_y) + 1.0f, r, g, b, 1.0f); + ogl::render_alpha_colored_rect(state, middle_x, end_y - 1.0f, end_x - middle_x, 2.0f, r, g, b, 1.0f); + + // The original compact arrow head now ends exactly at the target-card edge. + for(int32_t i = 0; i != 5; ++i) { + auto const head_height = float(10 - 2 * i); + ogl::render_alpha_colored_rect(state, end_x - 7.0f + float(i) * 1.5f, end_y - head_height * 0.5f, + 1.5f, head_height, r, g, b, 1.0f); + } } - std::unique_ptr make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override { - if(name == "main_bg") { - return make_element_by_type(state, id); - } else if(name == "bg_tech") { - return make_element_by_type(state, id); - } else if(name == "close_button") { - return make_element_by_type(state, id); - } else if(name == "administration") { - return make_element_by_type(state, id); - } else if(name == "current_research") { - return make_element_by_type(state, id); - } else if(name == "administration_type") { - return make_element_by_type(state, id); - } else if(name == "research_progress") { - return make_element_by_type(state, id); - } else if(name == "research_progress_name") { - return make_element_by_type(state, id); - } else if(name == "research_progress_category") { - return make_element_by_type(state, id); - } else if(name == "selected_tech_window") { - auto ptr = make_element_by_type(state, id); - selected_tech_win = ptr.get(); - return ptr; - } else if(name == "sort_by_type") { - auto ptr = make_element_by_type(state, id); - ptr->base_data.position.y -= 1; // Nudge - return ptr; - } else if(name == "sort_by_name") { - return make_element_by_type(state, id); - } else if(name == "sort_by_percent") { - auto ptr = make_element_by_type(state, id); - ptr->base_data.position.y -= 1; // Nudge - return ptr; - } else if(name == "inventions") { - return make_element_by_type(state, id); - } else { - return nullptr; +public: + void on_create(sys::state& state) noexcept override { + window_element_base::on_create(state); + state.world.for_each_technology([&](dcon::technology_id tech) { + auto node = make_element_by_type(state, "tech_window"); + if(!node) + return; + Cyto::Any payload = tech; + node->impl_set(state, payload); + node->set_tree_scale(state, zoom); + technology_nodes.emplace(tech.index(), node.get()); + add_child_to_back(std::move(node)); + }); + for(auto const& [index, node] : technology_nodes) { + Cyto::Any category_payload = active_category; + node->impl_set(state, category_payload); } + update_node_positions(state); } message_result set(sys::state& state, Cyto::Any& payload) noexcept override { if(payload.holds_type()) { - active_tab = any_cast(payload); - for(auto& c : children) - c->impl_set(state, payload); - return message_result::consumed; - } else if(payload.holds_type()) { - tech_id = any_cast(payload).tech_id; - selected_tech_win->impl_on_update(state); + active_category = any_cast(payload); + for(auto const& [index, node] : technology_nodes) { + Cyto::Any category_payload = active_category; + node->impl_set(state, category_payload); + } + pan_x = 0; + pan_y = 0; + update_node_positions(state); return message_result::consumed; } return message_result::unseen; } - message_result get(sys::state& state, Cyto::Any& payload) noexcept override { - if(payload.holds_type()) { - payload.emplace(tech_id); - return message_result::consumed; - } else if(payload.holds_type()) { - payload.emplace(state.local_player_nation); - return message_result::consumed; - } else if(payload.holds_type>()) { - invention_sort = any_cast>(payload).data; - impl_on_update(state); - return message_result::consumed; - } else if(payload.holds_type()) { - payload = invention_sort; - return message_result::consumed; + mouse_probe impl_probe_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type type) noexcept override { + if(x < 0 || y < 0 || x >= base_data.size.x || y >= base_data.size.y) + return mouse_probe{ nullptr, xy_pair{ int16_t(x), int16_t(y) } }; + return window_element_base::impl_probe_mouse(state, x, y, type); + } + + void impl_render(sys::state& state, int32_t x, int32_t y) noexcept override { + ogl::scissor_box clip{ state, x, y, base_data.size.x, base_data.size.y }; + window_element_base::impl_render(state, x, y); + } + + void render(sys::state& state, int32_t x, int32_t y) noexcept override { + for(auto const& [index, node] : technology_nodes) { + dcon::technology_id tech{ dcon::technology_id::value_base_t(index) }; + if(!node->is_visible()) + continue; + for(auto prerequisite : state.world.technology_get_prerequisites(tech)) { + auto it = technology_nodes.find(prerequisite.index()); + if(it == technology_nodes.end() || !it->second->is_visible()) + continue; + draw_connection(state, *it->second, *node, + state.world.nation_get_active_technologies(state.local_player_nation, prerequisite), x, y); + } } - return message_result::unseen; } + + message_result test_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type type) noexcept override { + return message_result::consumed; + } + + message_result on_lbutton_down(sys::state& state, int32_t x, int32_t y, sys::key_modifiers mods) noexcept override { + state.ui_state.drag_target = this; + return message_result::consumed; + } + + void on_drag(sys::state& state, int32_t oldx, int32_t oldy, int32_t x, int32_t y, sys::key_modifiers mods) noexcept override { + pan_x += x - oldx; + pan_y += y - oldy; + update_node_positions(state); + } + + message_result on_scroll(sys::state& state, int32_t x, int32_t y, float amount, sys::key_modifiers mods) noexcept override { + auto const old_zoom = zoom; + zoom = std::clamp(zoom + std::clamp(amount, -1.0f, 1.0f) * 0.10f, minimum_zoom, maximum_zoom); + if(zoom == old_zoom) + return message_result::consumed; + + // Keep the technology underneath the cursor in place while zooming. + float const zoom_ratio = zoom / old_zoom; + pan_x = int32_t(std::lround(float(x - left_padding) - float(x - left_padding - pan_x) * zoom_ratio)); + pan_y = int32_t(std::lround(float(y - top_padding) - float(y - top_padding - pan_y) * zoom_ratio)); + update_node_scales(state); + update_node_positions(state); + return message_result::consumed; + } +}; + +class technology_window : public generic_tabbed_window { + technology_selected_tech_window* selected_tech_win = nullptr; + dcon::technology_id tech_id{}; + invention_sort_type invention_sort = invention_sort_type::type; +public: + void on_create(sys::state& state) noexcept override; + std::unique_ptr make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override; + message_result set(sys::state& state, Cyto::Any& payload) noexcept override; + message_result get(sys::state& state, Cyto::Any& payload) noexcept override; }; } // namespace ui diff --git a/src/map/modes/sphere.hpp b/src/map/modes/sphere.hpp index 7aa681d3ad..ac4184ebb7 100644 --- a/src/map/modes/sphere.hpp +++ b/src/map/modes/sphere.hpp @@ -86,10 +86,10 @@ std::vector get_selected_sphere_color(sys::state& state) { } else { auto master_rel_id = state.world.get_gp_relationship_by_gp_influence_pair(owner, master); if(bool(master_rel_id)) { - auto master_rel_status = state.world.gp_relationship_get_status(master_rel_id); auto master_rel_inf = state.world.gp_relationship_get_influence(master_rel_id); + auto is_sphere_member = owner.get_in_sphere_of() == master; - if(master_rel_status == nations::influence::level_in_sphere || master_rel_inf != 0) { + if(is_sphere_member || master_rel_inf != 0) { owner.for_each_gp_relationship_as_influence_target([&](dcon::gp_relationship_id rel_id) { // Has more than one influencer if(rel_id != master_rel_id && state.world.gp_relationship_get_influence(rel_id) != 0 && @@ -98,7 +98,7 @@ std::vector get_selected_sphere_color(sys::state& state) { } }); - if(master_rel_status == nations::influence::level_in_sphere) { + if(is_sphere_member) { color = sphere_color; } else if(master_rel_inf != 0) { color = inf_color; diff --git a/src/nations/nations.cpp b/src/nations/nations.cpp index 82ca4bbb37..7774b0772b 100644 --- a/src/nations/nations.cpp +++ b/src/nations/nations.cpp @@ -1781,20 +1781,8 @@ bool is_losing_colonial_race(sys::state& state, dcon::nation_id n) { bool sphereing_progress_is_possible(sys::state& state, dcon::nation_id n) { for(auto it : state.world.nation_get_gp_relationship_as_great_power(n)) { - if((it.get_status() & influence::is_banned) == 0) { - if(it.get_influence() >= state.defines.increaseopinion_influence_cost - && (influence::level_mask & it.get_status()) != influence::level_in_sphere - && (influence::level_mask & it.get_status()) != influence::level_friendly) { - return true; - } else if(!(it.get_influence_target().get_in_sphere_of()) && - it.get_influence() >= state.defines.addtosphere_influence_cost) { - return true; - } else if(it.get_influence_target().get_in_sphere_of() && - (influence::level_mask & it.get_status()) == influence::level_friendly && - it.get_influence() >= state.defines.removefromsphere_influence_cost) { - return true; - } - } + if((it.get_status() & influence::priority_mask) != influence::priority_zero) + return true; } return false; } @@ -2777,15 +2765,10 @@ bool other_nation_is_influencing(sys::state& state, dcon::nation_id target, dcon } bool can_accumulate_influence_with(sys::state& state, dcon::nation_id gp, dcon::nation_id target, dcon::gp_relationship_id rel) { - if((state.world.gp_relationship_get_status(rel) & influence::is_banned) != 0) - return false; if(military::has_truce_with(state, gp, target) && state.world.nation_get_in_sphere_of(target) != gp ) return false; if(military::are_at_war(state, gp, target)) return false; - if(state.world.gp_relationship_get_influence(rel) >= state.defines.max_influence - && !other_nation_is_influencing(state, target, rel)) - return false; return true; } @@ -2828,12 +2811,39 @@ float get_avg_total_literacy(sys::state& state, dcon::nation_id n) { } void update_influence(sys::state& state) { + // Keep the new thresholds relative to the existing, serialized influence cap. + // Adding fields to parsing::defines would make previously generated scenarios + // unreadable by the game client. + auto const influence_decay = state.defines.max_influence * 0.001f; + auto const sphere_control_lead = state.defines.max_influence * 0.30f; + auto const sphere_transfer_owner_influence = state.defines.max_influence * 0.70f; + + // The old opinion and sabotage flags are deliberately no longer game mechanics. + // Keep level_in_sphere as a compatibility mirror for scripts and saved games; every + // other opinion level is reset to neutral so it cannot affect influence competition. for(auto rel : state.world.in_gp_relationship) { - if(rel.get_penalty_expires_date() == state.current_date) { - rel.set_status(rel.get_status() & ~(influence::is_banned | influence::is_discredited)); + if(!rel.get_great_power().get_is_great_power()) { + rel.set_status(uint8_t(rel.get_status() & ~(influence::is_banned | influence::is_discredited | influence::level_mask | influence::priority_mask))); + rel.set_influence(0.0f); + continue; + } + + auto clean_status = uint8_t(rel.get_status() & ~(influence::is_banned | influence::is_discredited | influence::level_mask)); + if(rel.get_influence_target().get_in_sphere_of() == rel.get_great_power()) + clean_status = uint8_t(clean_status | influence::level_in_sphere); + rel.set_status(clean_status); + + if((clean_status & influence::priority_mask) == influence::priority_zero) { + rel.set_influence(std::max(0.0f, rel.get_influence() - influence_decay)); } } + struct daily_gain { + dcon::gp_relationship_id rel; + float amount; + }; + std::vector gains; + for(auto& grn : state.great_nations) { dcon::nation_fat_id n = fatten(state.world, grn.nation); if(!is_great_power(state, n)) @@ -2871,7 +2881,7 @@ void update_influence(sys::state& state) { /* This influence value does not translate directly into influence with the target nation. Instead it is first multiplied - by the following factor: 1 + define:DISCREDIT_INFLUENCE_GAIN_FACTOR (if discredited) + + by the following factor: 1 + define:NEIGHBOUR_BONUS_INFLUENCE_PERCENT (if the nations are adjacent) + define:SPHERE_NEIGHBOUR_BONUS_INFLUENCE_PERCENT (if some member of the influencing nation's sphere is adjacent but not the influencing nation itself) + define:OTHER_CONTINENT_BONUS_INFLUENCE_PERCENT (if the influencing nation and the @@ -2894,10 +2904,8 @@ void update_influence(sys::state& state) { auto gp_invest = state.world.unilateral_relationship_get_foreign_investment( state.world.get_unilateral_relationship_by_unilateral_pair(rel.get_influence_target(), n)); - float discredit_factor = - (rel.get_status() & influence::is_discredited) != 0 ? state.defines.discredit_influence_gain_factor : 0.0f; float neighbor_factor = bool(state.world.get_nation_adjacency_by_nation_adjacency_pair(n, rel.get_influence_target())) - ? state.defines.neighbour_bonus_influence_percent + ? state.defines.neighbour_bonus_influence_percent : 0.0f; float sphere_neighbor_factor = nations::has_sphere_neighbour(state, n, rel.get_influence_target()) ? state.defines.sphere_neighbour_bonus_influence_percent @@ -2921,34 +2929,108 @@ void update_influence(sys::state& state) { ? std::max(1.0f - (rel.get_influence_target().get_industrial_score() + rel.get_influence_target().get_military_score() + prestige_score(state, rel.get_influence_target())) / gp_score, 0.0f) : 0.0f; - float total_multiplier = 1.0f + discredit_factor + neighbor_factor + sphere_neighbor_factor + continent_factor + puppet_factor + relationship_factor + investment_factor + pop_factor + score_factor; + float total_multiplier = 1.0f + neighbor_factor + sphere_neighbor_factor + continent_factor + puppet_factor + relationship_factor + investment_factor + pop_factor + score_factor; auto gain_amount = base_shares * total_multiplier; + if(gain_amount > 0.0f) + gains.push_back(daily_gain{ rel.id, gain_amount }); + } + } + } + } - /* - Any influence that accumulates beyond the max (define:MAX_INFLUENCE) will be subtracted from the influence of - the great power with the most influence (other than the influencing nation). - */ + for(auto const& gain : gains) { + auto old_value = state.world.gp_relationship_get_influence(gain.rel); + state.world.gp_relationship_set_influence(gain.rel, old_value + gain.amount); + } - rel.set_influence(rel.get_influence() + std::max(0.0f, gain_amount)); - if(rel.get_influence() > state.defines.max_influence) { - auto overflow = rel.get_influence() - state.defines.max_influence; - rel.set_influence(state.defines.max_influence); - dcon::gp_relationship_id other_rel; - for(auto orel : rel.get_influence_target().get_gp_relationship_as_influence_target()) { - if(orel != rel) { - if(orel.get_influence() > state.world.gp_relationship_get_influence(other_rel)) { - other_rel = orel; - } - } - } + // Resolve overflow target by target. Pressure is collected first and applied together, + // so the result does not depend on great-power iteration order. + for(auto target : state.world.in_nation) { + if(target.get_is_great_power()) + continue; - if(other_rel) { - auto& orl_i = state.world.gp_relationship_get_influence(other_rel); - state.world.gp_relationship_set_influence(other_rel, std::max(0.0f, orl_i - overflow)); - } - } - } + struct pressure_change { + dcon::gp_relationship_id rel; + float amount; + }; + struct overflow_source { + dcon::gp_relationship_id rel; + float amount; + }; + std::vector pressure; + std::vector overflows; + auto sphere_owner = target.get_in_sphere_of().id; + if(sphere_owner && !state.world.nation_get_is_great_power(sphere_owner)) { + remove_from_sphere(state, target.id, influence::level_neutral); + sphere_owner = dcon::nation_id{}; + } + + for(auto rel : target.get_gp_relationship_as_influence_target()) { + auto current = rel.get_influence(); + if(current <= state.defines.max_influence) + continue; + + overflows.push_back(overflow_source{ rel.id, current - state.defines.max_influence }); + rel.set_influence(state.defines.max_influence); + } + + // Overflow represents diplomatic pressure. Spread it over every rival in + // proportion to their current influence, so a third contender cannot gain + // for free while only the leading rival is being pushed back. + for(auto const& source : overflows) { + float competing_influence = 0.0f; + for(auto other : target.get_gp_relationship_as_influence_target()) { + if(other.id != source.rel) + competing_influence += other.get_influence(); + } + + if(competing_influence <= 0.0f) + continue; + + for(auto other : target.get_gp_relationship_as_influence_target()) { + if(other.id == source.rel || other.get_influence() <= 0.0f) + continue; + pressure.push_back(pressure_change{ other.id, source.amount * other.get_influence() / competing_influence }); + } + } + + for(auto const& change : pressure) { + auto current = state.world.gp_relationship_get_influence(change.rel); + state.world.gp_relationship_set_influence(change.rel, std::max(0.0f, current - change.amount)); + } + + dcon::gp_relationship_id leader; + dcon::gp_relationship_id runner_up; + for(auto rel : target.get_gp_relationship_as_influence_target()) { + if(!leader || rel.get_influence() > state.world.gp_relationship_get_influence(leader) || + (rel.get_influence() == state.world.gp_relationship_get_influence(leader) && + rel.get_great_power().id.index() < state.world.gp_relationship_get_great_power(leader).index())) { + runner_up = leader; + leader = rel.id; + } else if(!runner_up || rel.get_influence() > state.world.gp_relationship_get_influence(runner_up) || + (rel.get_influence() == state.world.gp_relationship_get_influence(runner_up) && + rel.get_great_power().id.index() < state.world.gp_relationship_get_great_power(runner_up).index())) { + runner_up = rel.id; + } + } + + if(!leader) + continue; + + auto leader_influence = state.world.gp_relationship_get_influence(leader); + auto runner_up_influence = runner_up ? state.world.gp_relationship_get_influence(runner_up) : 0.0f; + auto leader_gp = state.world.gp_relationship_get_great_power(leader); + + if(!sphere_owner) { + if(leader_influence >= state.defines.max_influence && leader_influence - runner_up_influence >= sphere_control_lead) + sphere_nation(state, target.id, leader_gp); + } else if(leader_gp != sphere_owner) { + auto owner_rel = state.world.get_gp_relationship_by_gp_influence_pair(target, sphere_owner); + auto owner_influence = owner_rel ? state.world.gp_relationship_get_influence(owner_rel) : 0.0f; + if(leader_influence >= state.defines.max_influence && owner_influence <= sphere_transfer_owner_influence) { + remove_from_sphere(state, target.id, influence::level_neutral); + sphere_nation(state, target.id, leader_gp); } } } @@ -3949,63 +4031,9 @@ void adjust_influence(sys::state& state, dcon::nation_id great_power, dcon::nati } void adjust_influence_with_overflow(sys::state& state, dcon::nation_id great_power, dcon::nation_id target, float delta) { - if(state.world.nation_get_owned_province_count(great_power) == 0 || state.world.nation_get_owned_province_count(target) == 0) - return; - if(great_power == target) - return; - if(state.world.nation_get_is_great_power(target) || !state.world.nation_get_is_great_power(great_power)) - return; - - auto rel = state.world.get_gp_relationship_by_gp_influence_pair(target, great_power); - if(!rel) { - rel = state.world.force_create_gp_relationship(target, great_power); - } - auto& inf = state.world.gp_relationship_get_influence(rel); - state.world.gp_relationship_set_influence(rel, inf + delta); - - while(inf < 0) { - if(state.world.nation_get_in_sphere_of(target) == great_power) { - state.world.gp_relationship_set_influence(rel, inf + state.defines.addtosphere_influence_cost); - auto l = state.world.gp_relationship_get_status(rel); - nations::remove_from_sphere(state, target, uint8_t(nations::influence::decrease_level(l))); - - } else { - state.world.gp_relationship_set_influence(rel, inf + state.defines.increaseopinion_influence_cost); - - auto& l = state.world.gp_relationship_get_status(rel); - state.world.gp_relationship_set_status(rel, uint8_t(nations::influence::decrease_level(l))); - } - } - - while(inf > state.defines.max_influence) { - // if already sphered, set influence to max - if((state.world.gp_relationship_get_status(rel) & influence::level_mask) == influence::level_in_sphere) { - state.world.gp_relationship_set_influence(rel, state.defines.max_influence); - } - else if((state.world.gp_relationship_get_status(rel) & influence::level_mask) == influence::level_friendly) { - // if in someone else's sphere, spend overflow influence to remove them from it first - if(bool(state.world.nation_get_in_sphere_of(target)) && state.world.nation_get_in_sphere_of(target) != great_power) { - state.world.gp_relationship_set_influence(rel, inf - state.defines.removefromsphere_influence_cost); - auto affected_gp = state.world.nation_get_in_sphere_of(target); - // the target was in a previous GP's sphere, update their state - auto orel = state.world.get_gp_relationship_by_gp_influence_pair(target, affected_gp); - auto l = state.world.gp_relationship_get_status(orel); - nations::remove_from_sphere(state, target, uint8_t(nations::influence::decrease_level(l))); - - } - // if they arent in a sphere, use overflow influence to spehere them - else { - nations::sphere_nation(state, target, great_power); - state.world.gp_relationship_set_influence(rel, inf - state.defines.addtosphere_influence_cost); - } - } - else { - state.world.gp_relationship_set_influence(rel, inf - state.defines.increaseopinion_influence_cost); - - auto& l = state.world.gp_relationship_get_status(rel); - state.world.gp_relationship_set_status(rel, uint8_t(nations::influence::increase_level(l))); - } - } + // Scripted effects may still grant influence, but sphere changes are always resolved + // by the daily competition pass above rather than by legacy opinion tiers. + adjust_influence(state, great_power, target, delta); } void adjust_foreign_investment(sys::state& state, dcon::nation_id great_power, dcon::nation_id target, float delta) { diff --git a/src/parsing/parser_defs.txt b/src/parsing/parser_defs.txt index bf4013f191..2efc826e5c 100644 --- a/src/parsing/parser_defs.txt +++ b/src/parsing/parser_defs.txt @@ -904,6 +904,9 @@ technology_contents year value int member_fn cost value int member_fn leadership_cost value int member_fn + prerequisite value text member_fn + tree_x value int member_fn + tree_y value int member_fn unit value int discard activate_unit value text member_fn activate_building value text member_fn diff --git a/src/parsing/parsers_declarations.cpp b/src/parsing/parsers_declarations.cpp index 1418b0809b..7365cd65ea 100644 --- a/src/parsing/parsers_declarations.cpp +++ b/src/parsing/parsers_declarations.cpp @@ -1,4 +1,5 @@ #include "parsers_declarations.hpp" +#include #include "system_state.hpp" #include "rebels.hpp" #include "fonts.hpp" @@ -1664,6 +1665,41 @@ void technology_contents::leadership_cost(association_type, int32_t value, error context.outer_context.state.world.technology_set_leadership_cost(context.id, value); } +void technology_contents::prerequisite(association_type, std::string_view value, error_handler& err, int32_t line, + tech_context& context) { + if(auto it = context.outer_context.map_of_technologies.find(std::string(value)); + it != context.outer_context.map_of_technologies.end()) { + if(it->second.id == context.id) { + err.accumulated_errors += "Technology cannot require itself (" + err.file_name + " line " + std::to_string(line) + ")\n"; + return; + } + auto prerequisites = context.outer_context.state.world.technology_get_prerequisites(context.id); + if(std::find(prerequisites.begin(), prerequisites.end(), it->second.id) != prerequisites.end()) { + err.accumulated_errors += "Technology prerequisite is listed more than once (" + err.file_name + " line " + std::to_string(line) + ")\n"; + return; + } + prerequisites.push_back(it->second.id); + } else { + err.accumulated_errors += "Invalid technology prerequisite " + std::string(value) + " (" + err.file_name + " line " + std::to_string(line) + ")\n"; + } +} + +void technology_contents::tree_x(association_type, int32_t value, error_handler& err, int32_t line, tech_context& context) { + if(value < 0 || value > 32767) { + err.accumulated_errors += "Technology tree_x must be between 0 and 32767 (" + err.file_name + " line " + std::to_string(line) + ")\n"; + return; + } + context.outer_context.state.world.technology_set_tree_x(context.id, int16_t(value)); +} + +void technology_contents::tree_y(association_type, int32_t value, error_handler& err, int32_t line, tech_context& context) { + if(value < 0 || value > 32767) { + err.accumulated_errors += "Technology tree_y must be between 0 and 32767 (" + err.file_name + " line " + std::to_string(line) + ")\n"; + return; + } + context.outer_context.state.world.technology_set_tree_y(context.id, int16_t(value)); +} + void technology_contents::area(association_type, std::string_view value, error_handler& err, int32_t line, tech_context& context) { if(auto it = context.outer_context.map_of_tech_folders.find(std::string(value)); diff --git a/src/parsing/parsers_declarations.hpp b/src/parsing/parsers_declarations.hpp index 10c8e44afe..be1b152c07 100644 --- a/src/parsing/parsers_declarations.hpp +++ b/src/parsing/parsers_declarations.hpp @@ -2196,6 +2196,9 @@ struct technology_contents : public modifier_base { void year(association_type, int32_t value, error_handler& err, int32_t line, tech_context& context); void cost(association_type, int32_t value, error_handler& err, int32_t line, tech_context& context); void leadership_cost(association_type, int32_t value, error_handler& err, int32_t line, tech_context& context); + void prerequisite(association_type, std::string_view value, error_handler& err, int32_t line, tech_context& context); + void tree_x(association_type, int32_t value, error_handler& err, int32_t line, tech_context& context); + void tree_y(association_type, int32_t value, error_handler& err, int32_t line, tech_context& context); void area(association_type, std::string_view value, error_handler& err, int32_t line, tech_context& context); void colonial_points(association_type, int32_t value, error_handler& err, int32_t line, tech_context& context); void activate_unit(association_type, std::string_view value, error_handler& err, int32_t line, tech_context& context);