mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-23 15:52:55 +01:00
implement scenario_create_ducks
This commit is contained in:
87
src/game.c
87
src/game.c
@@ -465,18 +465,9 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int *
|
||||
*
|
||||
* rct2: 0x00667C15
|
||||
*/
|
||||
void game_pause_toggle()
|
||||
void game_pause_toggle(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
||||
{
|
||||
char input_bl;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov input_bl, bl
|
||||
#else
|
||||
__asm__ ( "mov %[input_bl], bl " : [input_bl] "+m" (input_bl) );
|
||||
#endif
|
||||
|
||||
|
||||
if (input_bl & 1) {
|
||||
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) ^= 1;
|
||||
window_invalidate_by_class(WC_TOP_TOOLBAR);
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) & 1)
|
||||
@@ -484,64 +475,30 @@ void game_pause_toggle()
|
||||
else
|
||||
unpause_sounds();
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov ebx, 0
|
||||
#else
|
||||
__asm__ ( "mov ebx, 0 " );
|
||||
#endif
|
||||
|
||||
*ebx = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066DB5F
|
||||
*/
|
||||
static void game_load_or_quit()
|
||||
static void game_load_or_quit(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
||||
{
|
||||
char input_bl, input_dl;
|
||||
short input_di;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov input_bl, bl
|
||||
#else
|
||||
__asm__ ( "mov %[input_bl], bl " : [input_bl] "+m" (input_bl) );
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov input_dl, dl
|
||||
#else
|
||||
__asm__ ( "mov %[input_dl], dl " : [input_dl] "+m" (input_dl) );
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov input_di, di
|
||||
#else
|
||||
__asm__ ( "mov %[input_di], di " : [input_di] "+m" (input_di) );
|
||||
#endif
|
||||
|
||||
if (!(input_bl & 1))
|
||||
return; // 0;
|
||||
|
||||
switch (input_dl) {
|
||||
case 0:
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SAVE_PROMPT_MODE, uint16) = input_di;
|
||||
window_save_prompt_open();
|
||||
break;
|
||||
case 1:
|
||||
window_close_by_class(WC_SAVE_PROMPT);
|
||||
break;
|
||||
default:
|
||||
game_load_or_quit_no_save_prompt();
|
||||
break;
|
||||
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
|
||||
switch (*edx & 0xFF) {
|
||||
case 0:
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SAVE_PROMPT_MODE, uint16) = *edi & 0xFF;
|
||||
window_save_prompt_open();
|
||||
break;
|
||||
case 1:
|
||||
window_close_by_class(WC_SAVE_PROMPT);
|
||||
break;
|
||||
default:
|
||||
game_load_or_quit_no_save_prompt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm mov ebx, 0
|
||||
#else
|
||||
__asm__ ( "mov ebx, 0 " );
|
||||
#endif
|
||||
|
||||
*ebx = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -861,10 +818,10 @@ void game_load_or_quit_no_save_prompt()
|
||||
static uint32 game_do_command_table[58] = {
|
||||
0x006B2FC5,
|
||||
0x0066397F,
|
||||
(uint32)game_pause_toggle,
|
||||
0,
|
||||
0x006C511D,
|
||||
0x006C5B69,
|
||||
(uint32)game_load_or_quit,
|
||||
0,
|
||||
0x006B3F0F,
|
||||
0x006B49D9,
|
||||
0x006B4EA6,
|
||||
@@ -924,10 +881,10 @@ void game_command_emptysub(int* eax, int* ebx, int* ecx, int* edx, int* esi, int
|
||||
static GAME_COMMAND_POINTER* new_game_command_table[58] = {
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_pause_toggle,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_load_or_quit,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
|
||||
@@ -106,7 +106,7 @@ void game_reduce_game_speed();
|
||||
|
||||
void game_load_or_quit_no_save_prompt();
|
||||
int game_load_save(const char *path);
|
||||
void game_pause_toggle();
|
||||
void game_pause_toggle(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
char save_game();
|
||||
void rct2_exit();
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#include "world/park.h"
|
||||
#include "world/sprite.h"
|
||||
|
||||
static int scenario_create_ducks();
|
||||
|
||||
/**
|
||||
* Loads only the basic information from a scenario.
|
||||
* rct2: 0x006761D6
|
||||
@@ -596,21 +598,24 @@ void scenario_update()
|
||||
|
||||
if ((current_days_in_month * next_month_tick) >> 16 != (current_days_in_month * month_tick) >> 16) {
|
||||
// daily checks
|
||||
finance_update_daily_profit(); // daily profit update
|
||||
finance_update_daily_profit();
|
||||
RCT2_CALLPROC_EBPSAFE(0x0069C35E); // some kind of peeps days_visited update loop
|
||||
get_local_time();
|
||||
RCT2_CALLPROC_EBPSAFE(0x0066A13C); // objective 6 dragging
|
||||
if (objective_type == 10 || objective_type == 9 || objective_type == 8 ||
|
||||
objective_type == 6 || objective_type == 5) {
|
||||
RCT2_CALLPROC_EBPSAFE(0x0066A13C); // objective 6 dragging
|
||||
switch (objective_type) {
|
||||
case OBJECTIVE_REPLAY_LOAN_AND_PARK_VALUE:
|
||||
case OBJECTIVE_FINISH_5_ROLLERCOASTERS:
|
||||
case OBJECTIVE_10_ROLLERCOASTERS_LENGTH:
|
||||
case OBJECTIVE_GUESTS_AND_RATING:
|
||||
case OBJECTIVE_10_ROLLERCOASTERS:
|
||||
scenario_objectives_check();
|
||||
break;
|
||||
}
|
||||
|
||||
window_invalidate_by_class(WC_BOTTOM_TOOLBAR);
|
||||
}
|
||||
|
||||
|
||||
//if ( (unsigned int)((4 * current_day) & 0xFFFF) >= 0xFFEFu) {
|
||||
if ( next_month_tick % 0x4000 == 0) {
|
||||
if (next_month_tick % 0x4000 == 0) {
|
||||
// weekly checks
|
||||
finance_pay_wages();
|
||||
finance_pay_research();
|
||||
@@ -621,18 +626,9 @@ void scenario_update()
|
||||
ride_update_favourited_stat();
|
||||
|
||||
if (month <= 1 && RCT2_GLOBAL(0x009ADAE0, sint32) != -1 && RCT2_GLOBAL(0x009ADAE0 + 14, uint16) & 1) {
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
int carry;
|
||||
RCT2_CALLPROC_EBPSAFE(0x006744A9); // clears carry flag on failure -.-
|
||||
#ifdef _MSC_VER
|
||||
__asm mov carry, 0;
|
||||
__asm adc carry, 0;
|
||||
#else
|
||||
__asm__ ( "mov %[carry], 0; " : [carry] "+m" (carry) );
|
||||
__asm__ ( "adc %[carry], 0; " : [carry] "+m" (carry) );
|
||||
#endif
|
||||
|
||||
if (!carry)
|
||||
// 100 attempts at finding some water to create a few ducks at
|
||||
for (int i = 0; i < 100; i++) {
|
||||
if (scenario_create_ducks())
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -640,7 +636,6 @@ void scenario_update()
|
||||
park_calculate_size();
|
||||
}
|
||||
|
||||
//if ( (unsigned int)((2 * current_day) & 0xFFFF) >= 0xFFF8) {
|
||||
if (next_month_tick % 0x8000 == 0) {
|
||||
// fortnightly
|
||||
finance_pay_ride_upkeep();
|
||||
@@ -656,13 +651,67 @@ void scenario_update()
|
||||
scenario_entrance_fee_too_high_check();
|
||||
award_update_all();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006E37D2
|
||||
*/
|
||||
*
|
||||
* rct2: 0x006744A9
|
||||
*/
|
||||
static int scenario_create_ducks()
|
||||
{
|
||||
int i, j, r, c, x, y, waterZ, centreWaterZ, x2, y2;
|
||||
|
||||
r = scenario_rand();
|
||||
x = ((r >> 16) & 0xFFFF) & 0x7F;
|
||||
y = (r & 0xFFFF) & 0x7F;
|
||||
x = (x + 64) * 32;
|
||||
y = (y + 64) * 32;
|
||||
|
||||
if (!map_is_location_in_park(x, y))
|
||||
return 0;
|
||||
|
||||
centreWaterZ = (map_element_height(x, y) >> 16) & 0xFFFF;
|
||||
if (centreWaterZ == 0)
|
||||
return 0;
|
||||
|
||||
// Check 7x7 area around centre tile
|
||||
x2 = x - (32 * 3);
|
||||
y2 = y - (32 * 3);
|
||||
c = 0;
|
||||
for (i = 0; i < 7; i++) {
|
||||
for (j = 0; j < 7; j++) {
|
||||
waterZ = (map_element_height(x2, y2) >> 16) & 0xFFFF;
|
||||
if (waterZ == centreWaterZ)
|
||||
c++;
|
||||
|
||||
x2 += 32;
|
||||
}
|
||||
x2 -= 224;
|
||||
y2 += 32;
|
||||
}
|
||||
|
||||
// Must be at least 25 water tiles of the same height in 7x7 area
|
||||
if (c < 25)
|
||||
return 0;
|
||||
|
||||
// Set x, y to the centre of the tile
|
||||
x += 16;
|
||||
y += 16;
|
||||
c = (scenario_rand() & 3) + 2;
|
||||
for (i = 0; i < c; i++) {
|
||||
r = scenario_rand();
|
||||
x2 = (r >> 16) & 0x7F;
|
||||
y2 = (r & 0xFFFF) & 0x7F;
|
||||
create_duck(x + x2 - 64, y + y2 - 64);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006E37D2
|
||||
*/
|
||||
unsigned int scenario_rand()
|
||||
{
|
||||
int eax = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_0, uint32);
|
||||
|
||||
@@ -595,6 +595,7 @@ void game_command_set_park_entrance_fee(int *eax, int *ebx, int *ecx, int *edx,
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) = (*edi & 0xFFFF);
|
||||
window_invalidate_by_class(WC_PARK_INFORMATION);
|
||||
}
|
||||
*ebx = 0;
|
||||
}
|
||||
|
||||
void park_set_open(int open)
|
||||
|
||||
@@ -33,6 +33,15 @@ void create_balloon(int x, int y, int z, int colour)
|
||||
RCT2_CALLPROC_X(0x006736C7, x, colour << 8, y, z, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0067440F
|
||||
*/
|
||||
void create_duck(int targetX, int targetY)
|
||||
{
|
||||
RCT2_CALLPROC_X(0x0067440F, targetX, 0, targetY, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* rct2: 0x006EC473 */
|
||||
void invalidate_sprite(rct_sprite* sprite){
|
||||
if (sprite->unknown.sprite_left == (sint16)0x8000) return;
|
||||
|
||||
@@ -97,6 +97,7 @@ typedef union {
|
||||
extern rct_sprite* g_sprite_list;
|
||||
|
||||
void create_balloon(int x, int y, int z, int colour);
|
||||
void create_duck(int targetX, int targetY);
|
||||
rct_sprite *create_sprite(uint8 bl);
|
||||
void reset_sprite_list();
|
||||
void reset_0x69EBE4();
|
||||
|
||||
Reference in New Issue
Block a user