Added update_water

Refactored up/down water commands so that it used more standard layout.
Not tested.
This commit is contained in:
Duncan Frost 2015-05-27 17:40:57 +01:00
parent 24f9898ce6
commit a59fd26b3d
4 changed files with 243 additions and 98 deletions

View File

@ -1955,7 +1955,7 @@ void sub_68862C()
* mapElement: edx
* viewport: edi
*/
void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, int *y, int *interactionType, rct_map_element **mapElement, rct_viewport **viewport)
void get_map_coordinates_from_pos(int screenX, int screenY, int flags, sint16 *x, sint16 *y, int *interactionType, rct_map_element **mapElement, rct_viewport **viewport)
{
RCT2_GLOBAL(0x9AC154, uint16_t) = flags & 0xFFFF;
RCT2_GLOBAL(0x9AC148, uint8_t) = 0;
@ -1994,7 +1994,7 @@ void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, i
if (viewport != NULL) *viewport = myviewport;
}
if (interactionType != NULL) *interactionType = RCT2_GLOBAL(0x9AC148, uint8_t);
if (x != NULL) *x = (int)RCT2_GLOBAL(0x9AC14C, int16_t);
if (y != NULL) *y = (int)RCT2_GLOBAL(0x9AC14E, int16_t);
if (x != NULL) *x = RCT2_GLOBAL(0x9AC14C, int16_t);
if (y != NULL) *y = RCT2_GLOBAL(0x9AC14E, int16_t);
if (mapElement != NULL) *mapElement = RCT2_GLOBAL(0x9AC150, rct_map_element*);
}

View File

@ -1792,6 +1792,140 @@ void top_toolbar_tool_update_land(sint16 x, sint16 y){
}
}
/**
*
* rct2: 0x006E6BDC
*/
void top_toolbar_tool_update_water(sint16 x, sint16 y){
map_invalidate_selection_rect();
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) == 3){
if (!(RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 0)))
return;
money32 lower_cost = lower_water(
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16),
0);
money32 raise_cost = raise_water(
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16),
0);
if (RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, money32) != raise_cost ||
RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, money32) != lower_cost){
RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, money32) = raise_cost;
RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, money32) = lower_cost;
window_invalidate_by_class(WC_WATER);
}
return;
}
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0);
rct_xy16 mapTile = { 0 };
int interaction_type = 0;
get_map_coordinates_from_pos(
x,
y,
VIEWPORT_INTERACTION_MASK_TERRAIN & VIEWPORT_INTERACTION_MASK_WATER,
&mapTile.x,
&mapTile.y,
&interaction_type,
NULL,
NULL);
if (interaction_type == VIEWPORT_INTERACTION_ITEM_NONE){
if (RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, money32) != MONEY32_UNDEFINED ||
RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, money32) != MONEY32_UNDEFINED){
RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, money32) = MONEY32_UNDEFINED;
RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, money32) = MONEY32_UNDEFINED;
window_invalidate_by_class(WC_WATER);
}
return;
}
mapTile.x += 16;
mapTile.y += 16;
uint8 state_changed = 0;
if (!(RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 0))){
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 0);
state_changed++;
}
if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) != 4){
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4;
state_changed++;
}
sint16 tool_size = RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16);
if (tool_size == 0)
tool_size = 1;
sint16 tool_length = (tool_size - 1) * 32;
// Move to tool bottom left
mapTile.x -= (tool_size - 1) * 16;
mapTile.y -= (tool_size - 1) * 16;
mapTile.x &= 0xFFE0;
mapTile.y &= 0xFFE0;
if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) != mapTile.x){
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) = mapTile.x;
state_changed++;
}
if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) != mapTile.y){
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) = mapTile.y;
state_changed++;
}
mapTile.x += tool_length;
mapTile.y += tool_length;
if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) != mapTile.x){
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) = mapTile.x;
state_changed++;
}
if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) != mapTile.y){
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) = mapTile.y;
state_changed++;
}
map_invalidate_selection_rect();
if (!state_changed)
return;
money32 lower_cost = lower_water(
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16),
0);
money32 raise_cost = raise_water(
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16),
0);
if (RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, money32) != raise_cost ||
RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, money32) != lower_cost){
RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, money32) = raise_cost;
RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, money32) = lower_cost;
window_invalidate_by_class(WC_WATER);
}
}
/**
*
* rct2: 0x0066CB25

View File

@ -1560,68 +1560,59 @@ void game_command_lower_land(int* eax, int* ebx, int* ecx, int* edx, int* esi, i
*ebx = cost;
}
/**
*
* rct2: 0x006E66A0
*/
void game_command_raise_water(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp)
{
int ax = (uint16)*eax;
int ay = (uint16)*ecx;
int bx = (uint16)*edi;
int by = (uint16)*ebp;
int cost = 0;
money32 raise_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags){
money32 cost = 0;
uint8 max_height = 0xFF;
for(int yi = ay; yi <= by; yi += 32){
for(int xi = ax; xi <= bx; xi += 32){
for (int yi = y0; yi <= y1; yi += 32){
for (int xi = x0; xi <= x1; xi += 32){
rct_map_element* map_element = map_get_surface_element_at(xi / 32, yi / 32);
uint8 height = map_element->base_height;
if(map_element->properties.surface.terrain & 0x1F){
if (map_element->properties.surface.terrain & 0x1F){
height = (map_element->properties.surface.terrain & 0x1F) * 2;
}
if(max_height > height){
if (max_height > height){
max_height = height;
}
}
}
for(int yi = ay; yi <= by; yi += 32){
for(int xi = ax; xi <= bx; xi += 32){
for (int yi = y0; yi <= y1; yi += 32){
for (int xi = x0; xi <= x1; xi += 32){
rct_map_element* map_element = map_get_surface_element_at(xi / 32, yi / 32);
if(map_element->base_height <= max_height){
if (map_element->base_height <= max_height){
uint8 height = (map_element->properties.surface.terrain & 0x1F);
if(height){
if (height){
height *= 2;
if(height > max_height){
if (height > max_height){
continue;
}
height += 2;
}else{
}
else{
height = map_element->base_height + 2;
}
int eax2 = xi, ebx2 = *ebx, ecx2 = yi, edx2 = (max_height << 8) + height, esi2, edi2, ebp2;
ebx2 = game_do_command_p(GAME_COMMAND_16, &eax2, &ebx2, &ecx2, &edx2, &esi2, &edi2, &ebp2);
if(ebx2 == MONEY32_UNDEFINED){
*ebx = MONEY32_UNDEFINED;
return;
}else{
cost += ebx2;
money32 cost2 = game_do_command(GAME_COMMAND_16, xi, flags, yi, (max_height << 8) + height, 0, 0, 0);
if (cost2 == MONEY32_UNDEFINED){
return MONEY32_UNDEFINED;
}
else{
cost += cost2;
}
}
}
}
if(*ebx & GAME_COMMAND_FLAG_APPLY){
int x = ((ax + bx) / 2) + 16;
int y = ((ay + by) / 2) + 16;
if (flags & GAME_COMMAND_FLAG_APPLY){
int x = ((x0 + x1) / 2) + 16;
int y = ((y0 + y1) / 2) + 16;
int z = map_element_height(x, y);
sint16 water_height_z = z >> 16;
sint16 base_height_z = z;
z = water_height_z;
if(!z){
if (!z){
z = base_height_z;
}
RCT2_GLOBAL(0x009DEA5E, uint32) = x;
@ -1629,7 +1620,79 @@ void game_command_raise_water(int* eax, int* ebx, int* ecx, int* edx, int* esi,
RCT2_GLOBAL(0x009DEA62, uint32) = z;
sound_play_panned(SOUND_LAYING_OUT_WATER, 0x8001, x, y, z);
}
*ebx = cost;
return cost;
}
/**
*
* rct2: 0x006E66A0
*/
void game_command_raise_water(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp)
{
*ebx = raise_water(
(sint16)*eax,
(sint16)*ecx,
(sint16)*edi,
(sint16)*ebp,
(uint8)*ebx);
}
money32 lower_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags){
money32 cost = 0;
uint8 min_height = 0;
for (int yi = y0; yi <= y1; yi += 32){
for (int xi = x0; xi <= x1; xi += 32){
rct_map_element* map_element = map_get_surface_element_at(xi / 32, yi / 32);
uint8 height = map_element->properties.surface.terrain & 0x1F;
if (height){
height *= 2;
if (height > min_height){
min_height = height;
}
}
}
}
for (int yi = y0; yi <= y1; yi += 32){
for (int xi = x0; xi <= x1; xi += 32){
rct_map_element* map_element = map_get_surface_element_at(xi / 32, yi / 32);
uint8 height = (map_element->properties.surface.terrain & 0x1F);
if (height){
height *= 2;
if (height < min_height){
continue;
}
height -= 2;
int cost2 = game_do_command(xi, flags, yi, (min_height << 8) + height, GAME_COMMAND_16, 0, 0);
if (cost2 == MONEY32_UNDEFINED){
return MONEY32_UNDEFINED;
}
else{
cost += cost2;
}
}
}
}
if (flags & GAME_COMMAND_FLAG_APPLY){
int x = ((x0 + x1) / 2) + 16;
int y = ((y0 + y1) / 2) + 16;
int z = map_element_height(x, y);
sint16 water_height_z = z >> 16;
sint16 base_height_z = z;
z = water_height_z;
if (!z){
z = base_height_z;
}
RCT2_GLOBAL(0x009DEA5E, uint32) = x;
RCT2_GLOBAL(0x009DEA60, uint32) = y;
RCT2_GLOBAL(0x009DEA62, uint32) = z;
sound_play_panned(SOUND_LAYING_OUT_WATER, 0x8001, x, y, z);
}
return cost;
}
/**
@ -1638,66 +1701,12 @@ void game_command_raise_water(int* eax, int* ebx, int* ecx, int* edx, int* esi,
*/
void game_command_lower_water(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp)
{
int ax = (uint16)*eax;
int ay = (uint16)*ecx;
int bx = (uint16)*edi;
int by = (uint16)*ebp;
int cost = 0;
uint8 min_height = 0;
for(int yi = ay; yi <= by; yi += 32){
for(int xi = ax; xi <= bx; xi += 32){
rct_map_element* map_element = map_get_surface_element_at(xi / 32, yi / 32);
uint8 height = map_element->properties.surface.terrain & 0x1F;
if(height){
height *= 2;
if(height > min_height){
min_height = height;
}
}
}
}
for(int yi = ay; yi <= by; yi += 32){
for(int xi = ax; xi <= bx; xi += 32){
rct_map_element* map_element = map_get_surface_element_at(xi / 32, yi / 32);
uint8 height = (map_element->properties.surface.terrain & 0x1F);
if(height){
height *= 2;
if(height < min_height){
continue;
}
height -= 2;
int ebx2 = game_do_command(xi, *ebx, yi, (min_height << 8) + height, GAME_COMMAND_16, 0, 0);
if(ebx2 == MONEY32_UNDEFINED){
*ebx = MONEY32_UNDEFINED;
return;
}else{
cost += ebx2;
}
}
}
}
if(*ebx & GAME_COMMAND_FLAG_APPLY){
int x = ((ax + bx) / 2) + 16;
int y = ((ay + by) / 2) + 16;
int z = map_element_height(x, y);
sint16 water_height_z = z >> 16;
sint16 base_height_z = z;
z = water_height_z;
if(!z){
z = base_height_z;
}
RCT2_GLOBAL(0x009DEA5E, uint32) = x;
RCT2_GLOBAL(0x009DEA60, uint32) = y;
RCT2_GLOBAL(0x009DEA62, uint32) = z;
sound_play_panned(SOUND_LAYING_OUT_WATER, 0x8001, x, y, z);
}
*ebx = cost;
*ebx = lower_water(
(sint16)*eax,
(sint16)*ecx,
(sint16)*edi,
(sint16)*ebp,
(uint8)*ebx);
}
/**

View File

@ -280,6 +280,8 @@ int map_can_construct_with_clear_at(int x, int y, int zLow, int zHigh, void *cle
int map_can_construct_at(int x, int y, int zLow, int zHigh, uint8 bl);
int sub_6BA278(int ebx);
money32 map_clear_scenery(int x0, int y0, int x1, int y1, int flags);
money32 lower_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags);
money32 raise_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags);
void game_command_remove_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
void game_command_remove_large_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);