fix expenditure table issues, fixes #762

This commit is contained in:
IntelOrca 2015-02-08 14:31:37 +00:00
parent 84c655e817
commit dfc723573c
15 changed files with 92 additions and 117 deletions

View File

@ -7,6 +7,8 @@
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>

View File

@ -397,12 +397,10 @@
#define RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER 0x0141ED68
#define RCT2_ADDRESS_AUDIO_INFO 0x01425B40
#define RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE 0x0141F56C
#define RCT2_ADDRESS_SOUND_CHANNEL_LIST 0x014262E0
#define RCT2_ADDRESS_WATER_RAISE_COST 0x0141F738
#define RCT2_ADDRESS_WATER_LOWER_COST 0x0141F73C
#define RCT2_ADDRESS_WATER_RAISE_COST 0x0141F738
#define RCT2_ADDRESS_WATER_LOWER_COST 0x0141F73C
#define RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_1 0x0141F740
#define RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_2 0x0141F741
@ -493,6 +491,10 @@
#define RCT2_ADDRESS_INPUT_QUEUE 0x01424340
#define RCT2_ADDRESS_AUDIO_INFO 0x01425B40
#define RCT2_ADDRESS_SOUND_CHANNEL_LIST 0x014262E0
#define RCT2_ADDRESS_COMMON_FORMAT_ARGS 0x013CE952
#define RCT2_ADDRESS_STAFF_MODE_ARRAY 0x013CA672

View File

@ -436,7 +436,7 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int *
//
if (!(flags & 0x20)) {
// Update money balance
finance_payment(cost, RCT2_GLOBAL(0x0141F56C, uint8));
finance_payment(cost, RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) / 4);
if (RCT2_GLOBAL(0x0141F568, uint8) == RCT2_GLOBAL(0x013CA740, uint8)) {
// Create a +/- money text effect
if (cost != 0)
@ -898,8 +898,8 @@ static uint32 game_do_command_table[58] = {
0x006666E7,
0,
0x006CD8CE,
(uint32)game_command_set_park_entrance_fee,
(uint32)game_command_update_staff_colour, // 40
0,
0, // 40
0x006E519A,
0x006E5597,
0x006B893C,
@ -961,8 +961,8 @@ static GAME_COMMAND_POINTER* new_game_command_table[58] = {
game_command_emptysub,
game_command_remove_park_entrance,
game_command_emptysub,
game_command_emptysub,
game_command_emptysub, // 40
game_command_set_park_entrance_fee,
game_command_update_staff_colour, // 40
game_command_emptysub,
game_command_emptysub,
game_command_emptysub,

View File

@ -223,7 +223,7 @@ typedef struct rct_window {
};
sint16 page; // 0x48A
sint16 var_48C;
sint16 frame_no; // 0x48E updated every tic for motion in windows sprites
uint16 frame_no; // 0x48E updated every tic for motion in windows sprites
uint16 list_information_type; // 0x490 0 for none, Used as current position of marquee in window_peep
sint16 var_492;
uint32 var_494;

View File

@ -44,6 +44,8 @@ const money32 research_cost_table[4] = {
MONEY(400,00) // Maximum funding
};
int dword_988E60[] = { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0 };
/**
* Pay an amount of money.
* rct2: 0x069C674
@ -58,7 +60,7 @@ void finance_payment(money32 amount, rct_expenditure_type type)
//overflow check
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(new_money);
RCT2_ADDRESS(RCT2_ADDRESS_EXPENDITURE_TABLE, money32)[type] -= amount;
if (RCT2_ADDRESS(0x00988E60, uint32)[type] & 1)
if (dword_988E60[type] & 1)
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_EXPENDITURE, money32) -= amount; // Cumulative amount of money spent this day
@ -133,7 +135,7 @@ void finance_pay_ride_upkeep()
if (upkeep != -1) {
ride->total_profit -= upkeep;
ride->var_14D |= 2;
finance_payment(upkeep, RCT2_EXPENDITURE_TYPE_RIDE_UPKEEP);
finance_payment(upkeep, RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS);
}
}
}
@ -268,7 +270,7 @@ void game_command_set_current_loan(int* eax, int* ebx, int* ecx, int* edx, int*
money = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, money32));
loanDifference = currentLoan - newLoan;
RCT2_GLOBAL(0x0141F56C, uint8) = 52;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_INTEREST * 4;
if (newLoan > currentLoan) {
if (newLoan > RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32)) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_BANK_REFUSES_TO_INCREASE_LOAN;

View File

@ -26,10 +26,20 @@
typedef int rct_expenditure_type;
enum {
RCT2_EXPENDITURE_TYPE_RIDE_UPKEEP = 1,
RCT_EXPENDITURE_TYPE_WAGES = 10,
RCT_EXPENDITURE_TYPE_RESEARCH = 12,
RCT_EXPENDITURE_TYPE_INTEREST = 13
RCT_EXPENDITURE_TYPE_RIDE_CONSRUCTION,
RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS,
RCT_EXPENDITURE_TYPE_LAND_PURCHASE,
RCT_EXPENDITURE_TYPE_LANDSCAPING,
RCT_EXPENDITURE_TYPE_PARK_ENTRANCE_TICKETS,
RCT_EXPENDITURE_TYPE_PARK_RIDE_TICKETS,
RCT_EXPENDITURE_TYPE_SHOP_SHOP_SALES,
RCT_EXPENDITURE_TYPE_SHOP_STOCK,
RCT_EXPENDITURE_TYPE_FOODDRINK_SALES,
RCT_EXPENDITURE_TYPE_FOODDRINK_STOCK,
RCT_EXPENDITURE_TYPE_WAGES,
RCT_EXPENDITURE_TYPE_MARKETING,
RCT_EXPENDITURE_TYPE_RESEARCH,
RCT_EXPENDITURE_TYPE_INTEREST
};
extern const money32 research_cost_table[4];

View File

@ -22,6 +22,7 @@
#include "../game.h"
#include "../interface/window.h"
#include "../localisation/localisation.h"
#include "../management/finance.h"
#include "../ride/ride.h"
#include "marketing.h"
#include "news_item.h"
@ -152,7 +153,7 @@ void game_command_start_campaign(int* eax, int* ebx, int* ecx, int* edx, int* es
int rideOrItem = (*edx >> 8) & 0xFF;
int numWeeks = (*ebx >> 8) & 0xFF;
RCT2_GLOBAL(0x0141F56C, uint8) = 44;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_MARKETING * 4;
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 3048;
*ebx = MONEY32_UNDEFINED;

View File

@ -22,10 +22,11 @@
#include "../game.h"
#include "../interface/window.h"
#include "../localisation/date.h"
#include "../management/finance.h"
#include "../scenario.h"
#include "../world/scenery.h"
#include "news_item.h"
#include "research.h"
#include "../scenario.h"
const int _researchRate[] = { 0, 160, 250, 400 };
@ -344,7 +345,7 @@ void game_command_set_research_funding(int* eax, int* ebx, int* ecx, int* edx, i
int fundingAmount = *edx;
int activeCategories = *edx;
RCT2_GLOBAL(0x0141F56C, uint8) = 48;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RESEARCH * 4;
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
if (!setPriorities)
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RESEARCH_LEVEL, uint8) = fundingAmount;

View File

@ -28,38 +28,23 @@
#include "staff.h"
/**
*
* rct2: 0x00669E55
*/
void game_command_update_staff_colour()
*
* rct2: 0x00669E55
*/
void game_command_update_staff_colour(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
{
uint8 staff_type, colour, _bl;
uint8 staffType, colour;
int spriteIndex;
rct_peep *peep;
#ifdef _MSC_VER
__asm mov _bl, bl
#else
__asm__("mov %[_bl], bl " : [_bl] "+m" (_bl));
#endif
staffType = (*ebx >> 8) & 0xFF;
colour = (*edx >> 8) & 0xFF;
#ifdef _MSC_VER
__asm mov staff_type, bh
#else
__asm__("mov %[staff_type], bh " : [staff_type] "+m" (staff_type));
#endif
#ifdef _MSC_VER
__asm mov colour, dh
#else
__asm__("mov %[colour], bh " : [colour] "+m" (colour));
#endif
if (_bl & 1) {
RCT2_ADDRESS(RCT2_ADDRESS_HANDYMAN_COLOUR, uint8)[staff_type] = colour;
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
RCT2_ADDRESS(RCT2_ADDRESS_HANDYMAN_COLOUR, uint8)[staffType] = colour;
FOR_ALL_PEEPS(spriteIndex, peep) {
if (peep->type == PEEP_TYPE_STAFF && peep->staff_type == staff_type) {
if (peep->type == PEEP_TYPE_STAFF && peep->staff_type == staffType) {
peep->tshirt_colour = colour;
peep->trousers_colour = colour;
}
@ -67,25 +52,19 @@ void game_command_update_staff_colour()
}
gfx_invalidate_screen();
#ifdef _MSC_VER
__asm mov ebx, 0
#else
__asm__("mov ebx, 0 ");
#endif
*ebx = 0;
}
/**
*
* rct2: 0x006BEFA1
*/
void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
int* esi, int* edi, int* ebp)
*
* rct2: 0x006BEFA1
*/
void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp)
{
uint8 _bl = *ebx & 0xFF, staff_type = (*ebx & 0xFF00) >> 8;
uint16 _ax = *eax & 0xFFFF, _cx = *ecx & 0xFFFF, _dx = *edx & 0xFFFF;
RCT2_GLOBAL(0x0141F56C, uint8) = 0x28;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_WAGES * 4;
RCT2_GLOBAL(0x009DEA5E, uint16) = _ax;
RCT2_GLOBAL(0x009DEA60, uint16) = _cx;
RCT2_GLOBAL(0x009DEA62, uint16) = _dx;
@ -234,30 +213,23 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
/*
* Updates the colour of the given staff type.
*/
void update_staff_colour(uint8 staff_type, uint16 colour)
*/
void update_staff_colour(uint8 staffType, uint16 colour)
{
game_do_command(
0,
(staff_type << 8) + 1,
0,
(colour << 8) + 4,
GAME_COMMAND_SET_STAFF_COLOUR,
0,
0);
game_do_command(0, (staffType << 8) | GAME_COMMAND_FLAG_APPLY, 0, (colour << 8) | 4, GAME_COMMAND_SET_STAFF_COLOUR, 0, 0);
}
/*
* Hires a new staff member of the given type. If the hire cannot be completed (eg. the maximum
* number of staff is reached or there are too many people in the game) it returns 0xFFFF.
*/
uint16 hire_new_staff_member(uint8 staff_type)
*/
uint16 hire_new_staff_member(uint8 staffType)
{
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_HIRE_NEW_STAFF;
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = 0x8000;
ebx = staff_type << 8 | 1;
ebx = staffType << 8 | GAME_COMMAND_FLAG_APPLY;
int result = game_do_command_p(GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);

View File

@ -40,11 +40,11 @@ enum STAFF_TYPE {
STAFF_TYPE_ENTERTAINER
};
void game_command_update_staff_colour();
void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
void game_command_update_staff_colour(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
void game_command_hire_new_staff_member(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
void update_staff_colour(uint8 staff_type, uint16 color);
uint16 hire_new_staff_member(uint8 staff_type);
void update_staff_colour(uint8 staffType, uint16 color);
uint16 hire_new_staff_member(uint8 staffType);
void sub_6C0C3F();
int mechanic_is_location_in_patrol(rct_peep *mechanic, int x, int y);

View File

@ -26,6 +26,7 @@
#include "../interface/window.h"
#include "../localisation/date.h"
#include "../localisation/localisation.h"
#include "../management/finance.h"
#include "../management/news_item.h"
#include "../peep/peep.h"
#include "../peep/staff.h"
@ -2713,7 +2714,7 @@ void game_command_set_ride_name(int *eax, int *ebx, int *ecx, int *edx, int *esi
int rideIndex = (*ebx >> 8) & 0xFF;
int nameChunkIndex = *eax & 0xFFFF;
RCT2_GLOBAL(0x0141F56C, uint8) = 4;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS * 4;
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
int nameChunkOffset = nameChunkIndex - 1;
if (nameChunkOffset < 0)

View File

@ -1361,12 +1361,12 @@ static void window_park_price_mousedown(int widgetIndex, rct_window*w, rct_widge
window_park_set_page(w, widgetIndex - WIDX_TAB_1);
break;
case WIDX_INCREASE_PRICE:
newFee = min(1000, RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, uint16) + 10);
game_do_command(0, 1, 0, 0, GAME_COMMAND_SET_PARK_ENTRANCE_FEE, newFee, 0);
newFee = min(MONEY(100,00), RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) + MONEY(1,00));
park_set_entrance_fee(newFee);
break;
case WIDX_DECREASE_PRICE:
newFee = max(0, RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, uint16) - 10);
game_do_command(0, 1, 0, 0, GAME_COMMAND_SET_PARK_ENTRANCE_FEE, newFee, 0);
newFee = max(MONEY(0,00), RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) - MONEY(1,00));
park_set_entrance_fee(newFee);
break;
}
}

View File

@ -22,6 +22,7 @@
#include "../game.h"
#include "../localisation/date.h"
#include "../localisation/localisation.h"
#include "../management/finance.h"
#include "climate.h"
#include "map.h"
#include "park.h"
@ -590,7 +591,7 @@ money32 map_try_clear_scenery(int x, int y, rct_map_element *mapElement, int fla
entry = g_smallSceneryEntries[mapElement->properties.scenery.type];
cost = entry->small_scenery.removal_price * 10;
RCT2_GLOBAL(0x0141F56C, uint8) = 12;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_LANDSCAPING * 4;
RCT2_GLOBAL(0x009DEA5E, uint32) = x * 32 + 16;
RCT2_GLOBAL(0x009DEA60, uint32) = y * 32 + 16;
RCT2_GLOBAL(0x009DEA62, uint32) = mapElement->base_height * 8;
@ -718,7 +719,7 @@ money32 map_clear_scenery(int x0, int y0, int x1, int y1, int flags)
int x, y, z;
money32 totalCost, cost;
RCT2_GLOBAL(0x0141F56C, uint8) = 12;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_LANDSCAPING * 4;
x = (x0 + x1) / 2 + 16;
y = (y0 + y1) / 2 + 16;

View File

@ -579,40 +579,22 @@ void park_update_histories()
RCT2_CALLPROC_EBPSAFE(0x0066A231);
}
/**
*
* rct2: 0x00669E30
*/
void game_command_set_park_entrance_fee()
void park_set_entrance_fee(money32 value)
{
uint8 _bl;
uint16 new_fee;
#ifdef _MSC_VER
__asm mov _bl, bl
#else
__asm__("mov %[_bl], bl " : [_bl] "+m" (_bl));
#endif
#ifdef _MSC_VER
__asm mov new_fee, di
#else
__asm__("mov %[new_fee], di " : [new_fee] "+m" (new_fee));
#endif
RCT2_GLOBAL(0x0141F56C, uint8) = 0x10;
if (_bl & 1){
RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, uint16) = new_fee;
game_do_command(0, GAME_COMMAND_FLAG_APPLY, 0, 0, GAME_COMMAND_SET_PARK_ENTRANCE_FEE, value, 0);
}
/**
*
* rct2: 0x00669E30
*/
void game_command_set_park_entrance_fee(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
{
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_PARK_ENTRANCE_TICKETS * 4;
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) = (*edi & 0xFFFF);
window_invalidate_by_class(WC_PARK_INFORMATION);
}
#ifdef _MSC_VER
__asm mov ebx, 0
#else
__asm__("mov ebx, 0 ");
#endif
}
void park_set_open(int open)
@ -633,7 +615,7 @@ void game_command_set_park_open(int* eax, int* ebx, int* ecx, int* edx, int* esi
int dh = (*edx >> 8) & 0xFF;
RCT2_GLOBAL(0x0141F56C, uint8) = 16;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_PARK_ENTRANCE_TICKETS * 4;
switch (dh) {
case 0:
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN) {
@ -718,7 +700,7 @@ void game_command_remove_park_entrance(int *eax, int *ebx, int *ecx, int *edx, i
y = *ecx & 0xFFFF;
z = *edx * 16;
RCT2_GLOBAL(0x0141F56C, uint32) = 8;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint32) = RCT_EXPENDITURE_TYPE_LAND_PURCHASE * 4;
RCT2_GLOBAL(0x009DEA5E, uint16) = x;
RCT2_GLOBAL(0x009DEA60, uint16) = y;
RCT2_GLOBAL(0x009DEA62, uint16) = z;
@ -773,7 +755,7 @@ void game_command_set_park_name(int *eax, int *ebx, int *ecx, int *edx, int *esi
int nameChunkIndex = *eax & 0xFFFF;
RCT2_GLOBAL(0x0141F56C, uint8) = 12;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_LANDSCAPING * 4;
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
int nameChunkOffset = nameChunkIndex - 1;
if (nameChunkOffset < 0)

View File

@ -63,9 +63,10 @@ uint8 calculate_guest_initial_happiness(uint8 percentage);
void park_set_open(int open);
void park_set_name(const char *name);
void park_set_entrance_fee(money32 value);
void game_command_set_park_entrance_fee();
void game_command_set_park_open(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
void game_command_set_park_entrance_fee(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
void game_command_set_park_open(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
void game_command_remove_park_entrance(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
void game_command_set_park_name(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);