From bb4a482bfca8ec39f3f977330724b1c0066c32f9 Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 11 Jan 2017 22:53:33 +0000 Subject: [PATCH] Start writing new game action execution --- src/openrct2/actions/GameAction.cpp | 82 +++++++++++++++++++++++- src/openrct2/actions/GameAction.h | 3 + src/openrct2/localisation/localisation.h | 3 + 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/openrct2/actions/GameAction.cpp b/src/openrct2/actions/GameAction.cpp index df139d6a08..2b348ba011 100644 --- a/src/openrct2/actions/GameAction.cpp +++ b/src/openrct2/actions/GameAction.cpp @@ -15,9 +15,18 @@ #pragma endregion #include "../core/Guard.hpp" +#include "../core/Memory.hpp" #include "../core/Util.hpp" +#include "../network/network.h" #include "GameAction.h" +extern "C" +{ + #include "../localisation/localisation.h" + #include "../windows/error.h" + #include "../world/park.h" +} + GameActionResult::GameActionResult() { } @@ -55,25 +64,94 @@ namespace GameActions return result; } + static bool CheckActionInPausedMode(uint32 actionFlags) + { + if (gGamePaused == 0) return true; + if (gCheatsBuildInPauseMode) return true; + if (actionFlags & GA_FLAGS::ALLOW_WHILE_PAUSED) return true; + return false; + } + + static bool CheckActionAffordability(const GameActionResult * result) + { + if (gParkFlags & PARK_FLAGS_NO_MONEY) return true; + if (result->Cost <= 0) return true; + if (result->Cost <= DECRYPT_MONEY(gCashEncrypted)) return true; + return false; + } + GameActionResult Query(const IGameAction * action) { Guard::ArgumentNotNull(action); - return action->Query(); + GameActionResult result; + uint16 actionFlags = action->GetFlags(); + if (!CheckActionInPausedMode(actionFlags)) + { + result.Error = GA_ERROR::GAME_PAUSED; + result.ErrorMessage = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED; + } + else + { + result = action->Query(); + if (result.Error == GA_ERROR::OK) + { + if (!CheckActionAffordability(&result)) + { + result.Error = GA_ERROR::INSUFFICIENT_FUNDS; + result.ErrorMessage = STR_NOT_ENOUGH_CASH_REQUIRES; + set_format_arg_on(result.ErrorMessageArgs, 0, uint32, result.Cost); + } + } + } + return result; } void Execute(const IGameAction * action, GameActionCallback callback) { Guard::ArgumentNotNull(action); - GameActionResult result = action->Query(); + uint16 actionFlags = action->GetFlags(); + GameActionResult result = Query(action); if (result.Error == GA_ERROR::OK) { + // Execute the action, changing the game state result = action->Execute(); + + // Update money balance + if (!(gParkFlags & PARK_FLAGS_NO_MONEY) && result.Cost != 0) + { + finance_payment(result.Cost, result.ExpenditureType); + money_effect_create(result.Cost); + } + + if (!(actionFlags & GA_FLAGS::CLIENT_ONLY)) + { + if (network_get_mode() == NETWORK_MODE_SERVER) + { + // network_set_player_last_action(network_get_player_index(network_get_current_player_id()), command); + // network_add_player_money_spent(network_get_current_player_id(), cost); + } + } + + // Allow autosave to commence + if (gLastAutoSaveUpdate == AUTOSAVE_PAUSE) + { + gLastAutoSaveUpdate = SDL_GetTicks(); + } } + + // Call callback for asynchronous events if (callback != nullptr) { callback(result); } + + if (result.Error != GA_ERROR::OK) + { + // Show the error box + Memory::Copy(gCommonFormatArgs, result.ErrorMessageArgs, sizeof(result.ErrorMessageArgs)); + window_error_open(result.ErrorTitle, result.ErrorMessage); + } } } diff --git a/src/openrct2/actions/GameAction.h b/src/openrct2/actions/GameAction.h index ce4d4a7123..06fc908b8d 100644 --- a/src/openrct2/actions/GameAction.h +++ b/src/openrct2/actions/GameAction.h @@ -34,6 +34,7 @@ enum class GA_ERROR : uint16 OK, INVALID_PARAMETERS, DISALLOWED, + GAME_PAUSED, INSUFFICIENT_FUNDS, NOT_OWNED, @@ -55,7 +56,9 @@ namespace GA_FLAGS struct GameActionResult { GA_ERROR Error = GA_ERROR::OK; + rct_string_id ErrorTitle = (rct_string_id)-1; rct_string_id ErrorMessage = (rct_string_id)-1; + uint8 ErrorMessageArgs[8] = { 0 }; rct_xyz32 Position = { 0 }; money32 Cost = 0; uint16 ExpenditureType = 0; diff --git a/src/openrct2/localisation/localisation.h b/src/openrct2/localisation/localisation.h index f33a6e6eb1..f78b7b7cc3 100644 --- a/src/openrct2/localisation/localisation.h +++ b/src/openrct2/localisation/localisation.h @@ -104,6 +104,9 @@ static inline void set_format_arg_body(uint8 *args, size_t offset, uintptr_t val do { static_assert(sizeof(type) <= sizeof(uintptr_t), "Type too large"); \ set_format_arg_body(gCommonFormatArgs, offset, (uintptr_t)value, sizeof(type)); } while (0) +#define set_format_arg_on(args, offset, type, value) \ + set_format_arg_body(args, offset, (uintptr_t)value, sizeof(type)) + #define set_map_tooltip_format_arg(offset, type, value) \ do { static_assert(sizeof(type) <= sizeof(uintptr_t), "Type too large"); \ set_format_arg_body(gMapTooltipFormatArgs, offset, (uintptr_t)value, sizeof(type)); } while (0)