From f272c7354c78455b502b48d311ff3076d233181c Mon Sep 17 00:00:00 2001 From: aintDatCap Date: Fri, 5 Jan 2024 13:35:50 +0100 Subject: [PATCH 01/10] A bit of refactoring to start directx migration --- CMakeLists.txt | 2 +- src/{ogl => graphics}/color.hpp | 0 src/graphics/directx_wrapper.cpp | 28 ++++++++++++++++++++ src/{ogl => graphics}/opengl_wrapper.cpp | 0 src/{ogl => graphics}/opengl_wrapper.hpp | 0 src/{ogl => graphics}/opengl_wrapper_nix.cpp | 0 src/{ogl => graphics}/opengl_wrapper_win.cpp | 0 src/{ogl => graphics}/texture.cpp | 0 src/{ogl => graphics}/texture.hpp | 0 src/main.cpp | 1 + 10 files changed, 30 insertions(+), 1 deletion(-) rename src/{ogl => graphics}/color.hpp (100%) create mode 100644 src/graphics/directx_wrapper.cpp rename src/{ogl => graphics}/opengl_wrapper.cpp (100%) rename src/{ogl => graphics}/opengl_wrapper.hpp (100%) rename src/{ogl => graphics}/opengl_wrapper_nix.cpp (100%) rename src/{ogl => graphics}/opengl_wrapper_win.cpp (100%) rename src/{ogl => graphics}/texture.cpp (100%) rename src/{ogl => graphics}/texture.hpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index e92f5c238..e7be0b0e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -161,7 +161,7 @@ target_include_directories(AliceCommon INTERFACE ${PROJECT_SOURCE_DIR}/src/gui/topbar_subwindows/production_subwindows ${PROJECT_SOURCE_DIR}/src/gui/topbar_subwindows/politics_subwindows ${PROJECT_SOURCE_DIR}/src/gui/topbar_subwindows/military_subwindows - ${PROJECT_SOURCE_DIR}/src/ogl + ${PROJECT_SOURCE_DIR}/src/graphics ${PROJECT_SOURCE_DIR}/src/parsing ${PROJECT_SOURCE_DIR}/src/window ${PROJECT_SOURCE_DIR}/src/text diff --git a/src/ogl/color.hpp b/src/graphics/color.hpp similarity index 100% rename from src/ogl/color.hpp rename to src/graphics/color.hpp diff --git a/src/graphics/directx_wrapper.cpp b/src/graphics/directx_wrapper.cpp new file mode 100644 index 000000000..0ad5c9961 --- /dev/null +++ b/src/graphics/directx_wrapper.cpp @@ -0,0 +1,28 @@ +#include + +namespace directx { +void create_directx_context(sys::state& state) { + ID3D11Device* device; + ID3D11DeviceContext* context; + + D3D_FEATURE_LEVEL feature_levels[] = { D3D_FEATURE_LEVEL_11_0 }; + UINT flags = 0; +#ifdef _DEBUG + flags = D3D11_CREATE_DEVICE_DEBUG; +#endif + + HRESULT result = D3D11CreateDevice(0, D3D_DRIVER_TYPE_HARDWARE, 0, + flags, feature_levels, + ARRAYSIZE(feature_levels), + D3D11_SDK_VERSION, &device, 0, + &context); + + + if(FAILED(result)) { + MessageBox(nullptr, L"Failed to create DirectX 11 device", 0, 0); + std::abort(); + } + + +} +} diff --git a/src/ogl/opengl_wrapper.cpp b/src/graphics/opengl_wrapper.cpp similarity index 100% rename from src/ogl/opengl_wrapper.cpp rename to src/graphics/opengl_wrapper.cpp diff --git a/src/ogl/opengl_wrapper.hpp b/src/graphics/opengl_wrapper.hpp similarity index 100% rename from src/ogl/opengl_wrapper.hpp rename to src/graphics/opengl_wrapper.hpp diff --git a/src/ogl/opengl_wrapper_nix.cpp b/src/graphics/opengl_wrapper_nix.cpp similarity index 100% rename from src/ogl/opengl_wrapper_nix.cpp rename to src/graphics/opengl_wrapper_nix.cpp diff --git a/src/ogl/opengl_wrapper_win.cpp b/src/graphics/opengl_wrapper_win.cpp similarity index 100% rename from src/ogl/opengl_wrapper_win.cpp rename to src/graphics/opengl_wrapper_win.cpp diff --git a/src/ogl/texture.cpp b/src/graphics/texture.cpp similarity index 100% rename from src/ogl/texture.cpp rename to src/graphics/texture.cpp diff --git a/src/ogl/texture.hpp b/src/graphics/texture.hpp similarity index 100% rename from src/ogl/texture.hpp rename to src/graphics/texture.hpp diff --git a/src/main.cpp b/src/main.cpp index 4bc3c93ad..fb8f78a48 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -61,6 +61,7 @@ #include "window_win.cpp" #include "sound_win.cpp" #include "opengl_wrapper_win.cpp" +#include "directx_wrapper.cpp" #ifndef ALICE_NO_ENTRY_POINT #include "entry_point_win.cpp" From a37c4f58d4eff69f824cea532f9a539b60a2cea1 Mon Sep 17 00:00:00 2001 From: aintDatCap Date: Fri, 5 Jan 2024 15:05:39 +0100 Subject: [PATCH 02/10] Ported a bunch of functions to directx --- src/gamestate/system_state.hpp | 5 +++ src/graphics/directx_wrapper.cpp | 76 ++++++++++++++++++++++++++++++-- src/graphics/directx_wrapper.hpp | 16 +++++++ src/main.cpp | 4 ++ 4 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 src/graphics/directx_wrapper.hpp diff --git a/src/gamestate/system_state.hpp b/src/gamestate/system_state.hpp index 481c12c9f..065d6ec91 100644 --- a/src/gamestate/system_state.hpp +++ b/src/gamestate/system_state.hpp @@ -13,6 +13,7 @@ #include "simple_fs.hpp" #include "text.hpp" #include "opengl_wrapper.hpp" +#include "directx_wrapper.hpp" #include "fonts.hpp" #include "sound.hpp" #include "map_state.hpp" @@ -595,6 +596,10 @@ struct alignas(64) state { // graphics data ogl::data open_gl; +#ifdef DIRECTX_11 + directx::data directx; +#endif + // cheat data cheat_data_s cheat_data; diff --git a/src/graphics/directx_wrapper.cpp b/src/graphics/directx_wrapper.cpp index 0ad5c9961..66b3146f0 100644 --- a/src/graphics/directx_wrapper.cpp +++ b/src/graphics/directx_wrapper.cpp @@ -1,11 +1,20 @@ -#include +#include "directx_wrapper.hpp" +#include + namespace directx { + void create_directx_context(sys::state& state) { ID3D11Device* device; ID3D11DeviceContext* context; - D3D_FEATURE_LEVEL feature_levels[] = { D3D_FEATURE_LEVEL_11_0 }; + D3D_FEATURE_LEVEL feature_levels[] = { + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + }; + UINT flags = 0; #ifdef _DEBUG flags = D3D11_CREATE_DEVICE_DEBUG; @@ -22,7 +31,68 @@ void create_directx_context(sys::state& state) { MessageBox(nullptr, L"Failed to create DirectX 11 device", 0, 0); std::abort(); } + state.directx.device = device; + state.directx.context = context; +} + +void shutdown_directx(sys::state& state) { + state.directx.device->Release(); + state.directx.context->Release(); +} + +/* + file_name: the path to the shader file + entry_point: the name of the function that acts as entry point for the shader + blob: the resulting compiled shader +*/ +HRESULT compile_shader_from_file(sys::state& state, _In_ LPCWSTR file_name, _In_ LPCSTR entry_point, _Outptr_ ID3DBlob** blob) { + // Getting higher cs shader profile when possible + LPCSTR profile = (state.directx.device->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_0) ? "cs_5_0" : "cs_4_0"; + + // TODO: define required macros + const D3D_SHADER_MACRO defines[] = + { + NULL, NULL + }; + + UINT flags = D3DCOMPILE_ENABLE_STRICTNESS; +#if defined( DEBUG ) || defined( _DEBUG ) + flags |= D3DCOMPILE_DEBUG; +#endif + + ID3DBlob* shader_blob = nullptr; + ID3DBlob* error_blob = nullptr; + + HRESULT result = D3DCompileFromFile(file_name, defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, entry_point, profile, + flags, 0, &shader_blob, &error_blob); + + if(FAILED(result)) { + if(error_blob) { + MessageBox(state.win_ptr->hwnd, L"An error has occurred during shader compilation", L"Shader compilation error", MB_OK); + error_blob->Release(); + } + + if(shader_blob) + shader_blob->Release(); + + return result; + } + + *blob = shader_blob; + return result; +} +// TODO +void create_program(); + +void load_special_icons(sys::state& state) { + auto root = get_root(state.common_fs); + auto gfx_dir = simple_fs::open_directory(root, NATIVE("gfx")); + + auto interface_dir = simple_fs::open_directory(gfx_dir, NATIVE("interface")); + auto money_dds = simple_fs::open_file(interface_dir, NATIVE("icon_money_big.dds")); + if(money_dds) { + + } - } } diff --git a/src/graphics/directx_wrapper.hpp b/src/graphics/directx_wrapper.hpp new file mode 100644 index 000000000..90785684e --- /dev/null +++ b/src/graphics/directx_wrapper.hpp @@ -0,0 +1,16 @@ +#include + + +#ifndef DIRECTX_11 +#define DIRECTX_11 +#endif + +namespace directx { +struct data { + ID3D11Device* device; + ID3D11DeviceContext* context; +}; + +void create_directx_context(sys::state& state); +void shutdown_directx(sys::state& state); +} diff --git a/src/main.cpp b/src/main.cpp index fb8f78a48..e0bbe851e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -57,6 +57,10 @@ #ifdef _WIN64 // WINDOWS implementations go here +#pragma comment(lib, "d2d1.lib") +#pragma comment(lib, "D3D11.lib") +#pragma comment(lib, "dxguid.lib") + #include "simple_fs_win.cpp" #include "window_win.cpp" #include "sound_win.cpp" From e4dc2c2c16e69ef9bdf15d7be72d27f88fc57292 Mon Sep 17 00:00:00 2001 From: aintDatCap Date: Sat, 6 Jan 2024 11:43:26 +0100 Subject: [PATCH 03/10] Implemented most of load_special_icons for directx --- src/graphics/directx_wrapper.cpp | 92 +++++++++++++++++++++++++++++++- src/graphics/directx_wrapper.hpp | 9 ++++ src/main.cpp | 1 + 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/src/graphics/directx_wrapper.cpp b/src/graphics/directx_wrapper.cpp index 66b3146f0..31373ad1b 100644 --- a/src/graphics/directx_wrapper.cpp +++ b/src/graphics/directx_wrapper.cpp @@ -33,6 +33,15 @@ void create_directx_context(sys::state& state) { } state.directx.device = device; state.directx.context = context; + + // Initializing DirectXTex + HRESULT result = CoInitializeEx(nullptr, COINITBASE_MULTITHREADED); + + if(FAILED(result)) { + std::abort(); + } + + } void shutdown_directx(sys::state& state) { @@ -65,7 +74,7 @@ HRESULT compile_shader_from_file(sys::state& state, _In_ LPCWSTR file_name, _In_ HRESULT result = D3DCompileFromFile(file_name, defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, entry_point, profile, flags, 0, &shader_blob, &error_blob); - + if(FAILED(result)) { if(error_blob) { MessageBox(state.win_ptr->hwnd, L"An error has occurred during shader compilation", L"Shader compilation error", MB_OK); @@ -84,15 +93,94 @@ HRESULT compile_shader_from_file(sys::state& state, _In_ LPCWSTR file_name, _In_ // TODO void create_program(); +// to load a single special icon +HRESULT load_dds_from_file_content(IWICImagingFactory* iwici_factory, IWICStream* iwici_stream, simple_fs::file_contents content, IWICBitmapDecoder* decoder) { + + auto image_stream = const_cast(reinterpret_cast(content.data)); + + HRESULT result = iwici_stream->InitializeFromMemory(image_stream, content.file_size); + + if(FAILED(result)) { + return result; + } + + result = iwici_factory->CreateDecoderFromStream(iwici_stream, NULL, WICDecodeMetadataCacheOnLoad, &decoder); + return result; +} + +// to load them all void load_special_icons(sys::state& state) { + HRESULT result; + + IWICImagingFactory* iwici_factory; + IWICStream* iwici_stream = NULL; + + result = CoCreateInstance( + CLSID_WICImagingFactory, + NULL, + CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&iwici_factory) + ); + + if(FAILED(result)) { + // TODO + } + + result = iwici_factory->CreateStream(&iwici_stream); + + if(FAILED(result)) { + // TODO + } + auto root = get_root(state.common_fs); auto gfx_dir = simple_fs::open_directory(root, NATIVE("gfx")); auto interface_dir = simple_fs::open_directory(gfx_dir, NATIVE("interface")); auto money_dds = simple_fs::open_file(interface_dir, NATIVE("icon_money_big.dds")); if(money_dds) { - + auto content = simple_fs::view_contents(*money_dds); + result = load_dds_from_file_content(iwici_factory, iwici_stream, content, state.directx.money_icon_decoder); + if(FAILED(result)) { + // TODO + } + } + + auto n_dds = simple_fs::open_file(interface_dir, NATIVE("politics_foreign_naval_units.dds")); + if(n_dds) { + auto content = simple_fs::view_contents(*n_dds); + result = load_dds_from_file_content(iwici_factory, iwici_stream, content, state.directx.navy_icon_decoder); + if(FAILED(result)) { + // TODO + } + } + + auto a_dds = simple_fs::open_file(interface_dir, NATIVE("topbar_army.dds")); + if(a_dds) { + auto content = simple_fs::view_contents(*a_dds); + result = load_dds_from_file_content(iwici_factory, iwici_stream, content, state.directx.army_icon_decoder); + if(FAILED(result)) { + // TODO + } + } + + + auto assets_dir = simple_fs::open_directory(root, NATIVE("assets")); + auto cross_dds = simple_fs::open_file(assets_dir, NATIVE("trigger_not.dds")); + if(cross_dds) { + auto content = simple_fs::view_contents(*cross_dds); + result = load_dds_from_file_content(iwici_factory, iwici_stream, content, state.directx.cross_icon_decoder); + if(FAILED(result)) { + // TODO + } } + auto checkmark_dds = simple_fs::open_file(assets_dir, NATIVE("trigger_yes.dds")); + if(checkmark_dds) { + auto content = simple_fs::view_contents(*checkmark_dds); + result = load_dds_from_file_content(iwici_factory, iwici_stream, content, state.directx.checkmark_icon_decoder); + if(FAILED(result)) { + // TODO + } + } } } diff --git a/src/graphics/directx_wrapper.hpp b/src/graphics/directx_wrapper.hpp index 90785684e..ddf3d458f 100644 --- a/src/graphics/directx_wrapper.hpp +++ b/src/graphics/directx_wrapper.hpp @@ -1,4 +1,6 @@ +#pragma once #include +#include #ifndef DIRECTX_11 @@ -9,6 +11,13 @@ namespace directx { struct data { ID3D11Device* device; ID3D11DeviceContext* context; + + IWICBitmapDecoder* money_icon_decoder; + IWICBitmapDecoder* navy_icon_decoder; + IWICBitmapDecoder* army_icon_decoder; + IWICBitmapDecoder* cross_icon_decoder; + IWICBitmapDecoder* checkmark_icon_decoder; + }; void create_directx_context(sys::state& state); diff --git a/src/main.cpp b/src/main.cpp index e0bbe851e..f2df90699 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -60,6 +60,7 @@ #pragma comment(lib, "d2d1.lib") #pragma comment(lib, "D3D11.lib") #pragma comment(lib, "dxguid.lib") +#pragma comment(lib, "d3dcompiler.lib") #include "simple_fs_win.cpp" #include "window_win.cpp" From 749491ea0ff900e13472a5062b35cb79c9471a40 Mon Sep 17 00:00:00 2001 From: aintDatCap Date: Sat, 6 Jan 2024 11:47:06 +0100 Subject: [PATCH 04/10] fix --- src/graphics/directx_wrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/directx_wrapper.cpp b/src/graphics/directx_wrapper.cpp index 31373ad1b..980421107 100644 --- a/src/graphics/directx_wrapper.cpp +++ b/src/graphics/directx_wrapper.cpp @@ -35,7 +35,7 @@ void create_directx_context(sys::state& state) { state.directx.context = context; // Initializing DirectXTex - HRESULT result = CoInitializeEx(nullptr, COINITBASE_MULTITHREADED); + result = CoInitializeEx(nullptr, COINITBASE_MULTITHREADED); if(FAILED(result)) { std::abort(); From 85ae4c6cb505b21d97831868e46dcc5999429610 Mon Sep 17 00:00:00 2001 From: aintDatCap Date: Sat, 6 Jan 2024 11:54:29 +0100 Subject: [PATCH 05/10] Fix --- src/graphics/directx_wrapper.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/graphics/directx_wrapper.hpp b/src/graphics/directx_wrapper.hpp index ddf3d458f..9980fda25 100644 --- a/src/graphics/directx_wrapper.hpp +++ b/src/graphics/directx_wrapper.hpp @@ -3,9 +3,9 @@ #include -#ifndef DIRECTX_11 +#ifdef _WIN64 #define DIRECTX_11 -#endif + namespace directx { struct data { @@ -23,3 +23,4 @@ struct data { void create_directx_context(sys::state& state); void shutdown_directx(sys::state& state); } +#endif From 34f6fbe68439c3f7550089298d8c95d573e1e6e8 Mon Sep 17 00:00:00 2001 From: aintDatCap Date: Sat, 6 Jan 2024 11:56:53 +0100 Subject: [PATCH 06/10] fix --- src/graphics/directx_wrapper.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/graphics/directx_wrapper.hpp b/src/graphics/directx_wrapper.hpp index 9980fda25..79866872e 100644 --- a/src/graphics/directx_wrapper.hpp +++ b/src/graphics/directx_wrapper.hpp @@ -1,11 +1,10 @@ #pragma once -#include -#include - #ifdef _WIN64 #define DIRECTX_11 +#include +#include namespace directx { struct data { From 26ee80bbe6193664e8599e5e2b7c672e7a0e4294 Mon Sep 17 00:00:00 2001 From: dy080708 Date: Sat, 6 Jan 2024 17:16:05 -0300 Subject: [PATCH 07/10] Spanish translation of economy design --- README.md | 2 +- docs/economy_design_es.md | 81 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 docs/economy_design_es.md diff --git a/README.md b/README.md index 8f41b5a61..a3c68a3b5 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Join us on [discord](https://discord.gg/QUJExr4mRn) or visit our [documentation - Mods may or may not run with more or less problems (see the October update and the compatibility patches channel in the discord for more information about particular mods). ## Contributing -- Please, [visit this page](https://schombert.github.io/Project-Alice/md_contributing.html) ([简中](https://github.com/schombert/Project-Alice/blob/main/docs/zh-cn/contributing.md),[Español](https://github.com/schombert/Project-Alice/blob/main/docs/es-es/contributing.md) [Português](https://github.com/schombert/Project-Alice/blob/main/docs/pt/contributing.md)) +- Please, [visit this page](https://schombert.github.io/Project-Alice/md_contributing.html) ([简中](https://github.com/schombert/Project-Alice/blob/main/docs/zh-cn/contributing.md), [Español](https://github.com/schombert/Project-Alice/blob/main/docs/es-es/contributing.md), [Português](https://github.com/schombert/Project-Alice/blob/main/docs/pt/contributing.md)) ## Updates diff --git a/docs/economy_design_es.md b/docs/economy_design_es.md new file mode 100644 index 000000000..520c9326d --- /dev/null +++ b/docs/economy_design_es.md @@ -0,0 +1,81 @@ +# Diseño de la Economía + +Este documento proporciona una descripción general del diseño de cómo se implementará la economía 1.0. La economía 1.0 no es una réplica exacta de la economía de Victoria 2. Está diseñada para ser una aproximación cercana, pero se han realizado algunas modificaciones para mejorar el rendimiento. Sustancialmente, esto significa que intentamos almacenar la menor cantidad de información posible y realizar la menor cantidad de pasadas sobre los datos. Desafortunadamente, incluso una aproximación cercana requiere una secuenciación sustancial, y hay poca posibilidad de paralelismo. Lo mejor que podamos lograr es hacer que la economía sea lo más autosuficiente posible para que la actualización del resto del día pueda ejecutarse junto a ella. + +## Términos + +Rentabilidad virtual: qué tan rentable sería una unidad estandarizada de producción *si* todos los insumos estuvieran disponibles, con los bonos de los trabajadores como si tuvieran empleo completo. (Teniendo en cuenta la fracción de producción vendida el día anterior en comparación con la producción real) + +Escala de producción: la producción del productor se reducirá por dos factores: primero, por la disponibilidad de insumos. La escala efectiva de producción está limitada por la disponibilidad de insumos (y la escala real de producción se reducirá para cumplir con este valor). Cuando la oferta es mayor que la demanda real: la escala de producción disminuye a cierta tasa (por determinar, probablemente hasta cierta cantidad mínima, no hasta 0). Cuando la oferta es menor que la demanda real: la escala de producción aumenta a cierta tasa. Es posible que necesitemos un segundo factor de derivada aquí para reducir las fluctuaciones, ya que este es un segundo mecanismo de retroalimentación que empuja en la misma dirección que los movimientos de precios. + +Cerrado: una fábrica con una escala de producción lo suficientemente baja está cerrada. Los artesanos con una escala de producción lo suficientemente baja cambiarán la producción, incluso si es nominalmente rentable (ya que esto significa que tienen problemas de disponibilidad de insumos). + +## Actualización diaria + +Iteramos sobre las naciones, en orden de rango. + +### Estado inicial de la oferta nacional y global + +El estado inicial de la oferta nacional se basa en lo que se produjo internamente, y la oferta global es lo que se produjo internamente el día anterior y no se consumió. Para el resto de este documento, tomamos la oferta nacional como "oferta nacional, existencias nacionales si la compra está habilitada, y lo que queda en la oferta nacional del líder de la esfera", que emula el comportamiento de Victoria 2. + +Al comenzar el día, trasladamos la producción, de manera fraccional, al grupo de producción nacional del líder de la esfera, siguiendo la misma lógica que Victoria 2. + +#### Datos requeridos: + +Producción por nación (= pool de mercado nacional) para el día N - 1 + +### Calcular precios efectivos + +El problema de los dos precios: + +Para calcular la demanda y distribuir lo que está disponible de manera uniforme entre los consumidores de la nación, necesitamos saber cuáles son los precios para determinar cuánto es posible que un consumidor compre dada una renta particular (y cuál sería su renta suponiendo que podrían vender su producción). El problema es que los aranceles, etc., hacen que la compra desde el grupo global sea más cara. Esencialmente, hay dos precios, y la parte que puedes comprar localmente puede ser más barata (o más cara, en el caso de los subsidios) que el bien en el mercado global. Y esto significa que el costo efectivo depende de cuánto se compre en total, lo que a su vez depende del costo... + +Victoria 2 resuelve esto ordenando a los consumidores de manera arbitraria. Hacen compras en orden, cada uno comprando de la oferta nacional (sí, incluso si es más barato comprar de la oferta global) hasta que se agota, y luego el resto debe lidiar con el precio de la oferta global. Esto no es ideal si esos precios divergen significativamente, porque significa que algunas cosas pueden ser o no rentables según donde caigan en este orden arbitrario. + +Resolveremos este problema de la siguiente manera: usaremos la demanda real del *día anterior* para determinar cuánta de la compra se realizará desde las ofertas nacionales y globales (es decir, qué porcentaje se pudo hacer desde el grupo más barato). Usaremos eso para calcular un precio efectivo. Y luego, al final del día actual, veremos cuánto de esa compra provino realmente de cada grupo, etc. Dependiendo de la estabilidad de la simulación, en lugar de tomar el día anterior, podríamos construir este valor de manera iterativa como una combinación lineal del nuevo día y el día anterior. + +(Si quisiéramos ser *más* realistas que Victoria 2, también podríamos calcular un segundo precio de venta... pero ¿por qué deberíamos hacerlo, si el juego base no se molesta en hacerlo?). + +#### Datos requeridos: + +Demanda real por nación para el día N - 1. Búfer temporal de precio efectivo por comodidad. + +### Determinar empleo + +Los posibles empleados se distribuyen a las fábricas haciendo lo siguiente: + +Ordenamos las fábricas por prioridad y luego por rentabilidad *virtual* (bueno, como detalle de implementación, es más fácil hacer una ordenación estable por rentabilidad y luego una ordenación estable por prioridad, con estabilidad en ambos casos garantizando que el orden permanezca igual en todas partes). Ninguna fábrica contrata a más trabajadores de los que su escala de producción del día anterior permitiría. El empleo solo se permite cambiar tanto en un día (por determinar). + +Esto también se aplica a los RGO, aunque solo hay un objetivo para la distribución. + +#### Datos requeridos: + +Escala de producción por fábrica, escala de producción de RGO por provincia y artesano. Valores de empleo por fábrica y por provincia de RGO. + +### La nación determina el consumo objetivo y real + +Se calcula el consumo deseado para todas las fuentes (poblaciones, fábricas, artesanos, existencias nacionales, proyectos) según cuánto pueden comprar dado su dinero. Se supone que los artesanos y las fábricas toman prestado contra su beneficio esperado si serán rentables dados los precios efectivos actuales (es decir, si son virtualmente rentables, con los efectos de empleo tenidos en cuenta, y las fábr + +icas también deben tener en cuenta un costo de entrada de mano de obra mínima para el beneficio esperado). Si lo son, intentan comprar tanto como puedan dadas las limitaciones de su escala de producción y los números de empleo (y si no, su escala de producción disminuye). Las poblaciones intentan comprar tanto como puedan (hasta su último ingreso). Las naciones... aquí tenemos un problema. Es bastante natural decir: tanto como puedan dado sus reservas. Esto significaría que las naciones nunca entrarían en deuda. ¿Es eso lo que queremos? (Quizás para la IA y como opción del jugador). En cualquier caso, esto nos da números de "demanda real". + +A partir de esto, derivamos límites máximos en la escala de producción para fábricas / artesanos (pero estos números no serán completamente precisos: los límites en la disponibilidad del bien A pueden hacer que más de B esté disponible porque el proceso de producción que utiliza tanto A como B consumirá menos de B, dejando más de B disponible para un proceso de producción no limitado por A. Hay un algoritmo que puede resolver esto, es una forma de problema de optimización lineal, que es solucionable, pero es algo complicado). También reducimos la escala de todas las demás compras de la misma manera. + +Con la escala de consumo calculada, restamos las mercancías de los diversos grupos de oferta comenzando con el más barato de global o nacional. Dentro de lo nacional, primero restamos de lo verdaderamente nacional, luego del líder de la esfera nacional restante, luego de las existencias nacionales (si están habilitadas). + +#### Datos requeridos: + +Grupo de oferta global. Ingresos del día anterior por población. Búfer temporal de mercancías por comodidad para determinar disponibilidad. Existencias nacionales. + +### Efectos del consumo + +Las mercancías producidas (fábricas, artesanos, RGO) se colocan en el grupo de oferta nacional para el próximo día. Se calculan las ganancias de fábricas y artesanos, y las ganancias de los RGO, y a partir de estos valores se calculan los ingresos para diversas poblaciones de empleados para el próximo día. Las compras de la población se utilizan para calcular la satisfacción de necesidades, que no es un resultado directo de cuánto se consume, sino más bien una combinación lineal de la satisfacción anterior, que simula el ahorro de la población. + +Cualquier oferta nacional restante se traslada al grupo global para el próximo día. + +### Fin del día + +La oferta real frente a la demanda real hace que los precios se ajusten. Cualquier oferta restante en el grupo global se elimina. Calculamos cuánto de la producción total mundial fue comprada, ya que esto afectará el precio de venta efectivo para el próximo día. + +#### Datos requeridos: + +Valores de producción global, valores de consumo real (o tal vez solo la fracción). \ No newline at end of file From e9dc9fd718bd917b7824e18a6ae023439e54fe1b Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sun, 7 Jan 2024 01:03:56 +0000 Subject: [PATCH 08/10] Add AI define to control overestimation of offensives --- src/ai/ai.cpp | 2 +- src/parsing/defines.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ai/ai.cpp b/src/ai/ai.cpp index c9ccf2d1d..1f26e61a1 100644 --- a/src/ai/ai.cpp +++ b/src/ai/ai.cpp @@ -41,7 +41,7 @@ float estimate_additional_offensive_strength(sys::state& state, dcon::nation_id if(other.get_overlord_as_subject().get_ruler() != n && military::can_use_cb_against(state, other, target) && !military::has_truce_with(state, other, target)) value += estimate_strength(state, other); } - return value; + return value * state.defines.alice_ai_offensive_strength_overestimate; } void update_ai_general_status(sys::state& state) { diff --git a/src/parsing/defines.hpp b/src/parsing/defines.hpp index bbf2b7b03..6564dcd15 100644 --- a/src/parsing/defines.hpp +++ b/src/parsing/defines.hpp @@ -655,7 +655,7 @@ LUA_DEFINES_LIST_ELEMENT(alice_ai_threat_overestimate, 1.150000) \ LUA_DEFINES_LIST_ELEMENT(alice_ai_attack_target_radius, -0.996000) \ LUA_DEFINES_LIST_ELEMENT(alice_full_reinforce, 1.000000) \ - + LUA_DEFINES_LIST_ELEMENT(alice_ai_offensive_strength_overestimate, 1.000000) \ namespace parsing { struct defines { From 5115b3acae30ed188e4f945cc1f289fdfb4d722f Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sun, 7 Jan 2024 01:06:43 +0000 Subject: [PATCH 09/10] Rebel hunter balance estimations (this makes rebels more tolerable) --- src/culture/rebels.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/culture/rebels.cpp b/src/culture/rebels.cpp index f961dc320..6e97e93a4 100644 --- a/src/culture/rebels.cpp +++ b/src/culture/rebels.cpp @@ -789,8 +789,8 @@ void sort_hunting_targets(sys::state& state, dcon::army_id ar, std::vector(ai::estimate_army_strength(state, a), 1.f); - auto bs = 0.02f * std::max(ai::estimate_army_strength(state, b), 1.f); + auto as = 0.001f * std::max(ai::estimate_army_strength(state, a), 1.f); + auto bs = 0.001f * std::max(ai::estimate_army_strength(state, b), 1.f); auto da = province::sorting_distance(state, pa, closest_prov) + as; auto db = province::sorting_distance(state, pb, closest_prov) + bs; if(da != db) From 839a0b7bed0cc8a23afb97115603da8cd360a69c Mon Sep 17 00:00:00 2001 From: schombert Date: Sat, 6 Jan 2024 19:36:32 -0800 Subject: [PATCH 10/10] fix launcher build --- src/gui/gui_element_types.hpp | 3 +- src/launcher/launcher_main.cpp | 102 +++++++++++++++++---------------- src/map/modes/political.hpp | 1 + 3 files changed, 54 insertions(+), 52 deletions(-) diff --git a/src/gui/gui_element_types.hpp b/src/gui/gui_element_types.hpp index b77250bec..212946a34 100644 --- a/src/gui/gui_element_types.hpp +++ b/src/gui/gui_element_types.hpp @@ -1703,8 +1703,7 @@ class grid_box : public window_element_base { set_visible(state, true); } }; - -void populate_shortcut_tooltip(sys::state& state, ui::element_base& elm, text::columnar_layout& contents) noexcept { +inline void populate_shortcut_tooltip(sys::state& state, ui::element_base& elm, text::columnar_layout& contents) noexcept { if(elm.base_data.get_element_type() != ui::element_type::button) return; if(elm.base_data.data.button.shortcut == sys::virtual_key::NONE) diff --git a/src/launcher/launcher_main.cpp b/src/launcher/launcher_main.cpp index ad9d3c04c..76d3093df 100644 --- a/src/launcher/launcher_main.cpp +++ b/src/launcher/launcher_main.cpp @@ -444,58 +444,60 @@ void mouse_click() { } return; case ui_obj_play_game: - if(IsProcessorFeaturePresent(PF_AVX512F_INSTRUCTIONS_AVAILABLE)) { - native_string temp_command_line = native_string(NATIVE("Alice512.exe ")) + selected_scenario_file; - - STARTUPINFO si; - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - PROCESS_INFORMATION pi; - ZeroMemory(&pi, sizeof(pi)); - // Start the child process. - if(CreateProcessW( - nullptr, // Module name - const_cast(temp_command_line.c_str()), // Command line - nullptr, // Process handle not inheritable - nullptr, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - 0, // No creation flags - nullptr, // Use parent's environment block - nullptr, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi) != 0) { - - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - - return; // exit -- don't try starting avx2 + if(file_is_ready.load(std::memory_order::memory_order_acquire) && !selected_scenario_file.empty()) { + if(IsProcessorFeaturePresent(PF_AVX512F_INSTRUCTIONS_AVAILABLE)) { + native_string temp_command_line = native_string(NATIVE("Alice512.exe ")) + selected_scenario_file; + + STARTUPINFO si; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(pi)); + // Start the child process. + if(CreateProcessW( + nullptr, // Module name + const_cast(temp_command_line.c_str()), // Command line + nullptr, // Process handle not inheritable + nullptr, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + 0, // No creation flags + nullptr, // Use parent's environment block + nullptr, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi) != 0) { + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + + return; // exit -- don't try starting avx2 + } } - } - { // normal case (avx2) - native_string temp_command_line = native_string(NATIVE("Alice.exe ")) + selected_scenario_file; - - STARTUPINFO si; - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - PROCESS_INFORMATION pi; - ZeroMemory(&pi, sizeof(pi)); - // Start the child process. - if(CreateProcessW( - nullptr, // Module name - const_cast(temp_command_line.c_str()), // Command line - nullptr, // Process handle not inheritable - nullptr, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - 0, // No creation flags - nullptr, // Use parent's environment block - nullptr, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi) != 0) { - - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); + { // normal case (avx2) + native_string temp_command_line = native_string(NATIVE("Alice.exe ")) + selected_scenario_file; + + STARTUPINFO si; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(pi)); + // Start the child process. + if(CreateProcessW( + nullptr, // Module name + const_cast(temp_command_line.c_str()), // Command line + nullptr, // Process handle not inheritable + nullptr, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + 0, // No creation flags + nullptr, // Use parent's environment block + nullptr, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi) != 0) { + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } + return; } - return; } case ui_obj_host_game: case ui_obj_join_game: diff --git a/src/map/modes/political.hpp b/src/map/modes/political.hpp index 4a0240c25..d281ef541 100644 --- a/src/map/modes/political.hpp +++ b/src/map/modes/political.hpp @@ -1,4 +1,5 @@ #pragma once +#include "prng.hpp" uint32_t derive_color_from_ol_color(sys::state& state, uint32_t ol_color, dcon::nation_id n) { auto base = sys::rgb_to_hsv(ol_color);