1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-19 04:53:12 +01:00

signs and banners editable in multiplayer

This commit is contained in:
zsilencer
2015-10-31 02:25:43 -06:00
parent 6c5acdde6a
commit a95357a32d
6 changed files with 260 additions and 133 deletions

View File

@@ -404,7 +404,7 @@ static int game_check_affordability(int cost)
return MONEY32_UNDEFINED;
}
static GAME_COMMAND_POINTER* new_game_command_table[58];
static GAME_COMMAND_POINTER* new_game_command_table[62];
/**
*
@@ -1131,7 +1131,7 @@ void game_load_or_quit_no_save_prompt()
}
}
static GAME_COMMAND_POINTER* new_game_command_table[58] = {
static GAME_COMMAND_POINTER* new_game_command_table[62] = {
game_command_set_ride_appearance,
game_command_set_land_height,
game_pause_toggle,
@@ -1189,5 +1189,9 @@ static GAME_COMMAND_POINTER* new_game_command_table[58] = {
game_command_set_large_scenery_colour,
game_command_set_banner_colour,
game_command_set_land_ownership,
game_command_clear_scenery
game_command_clear_scenery,
game_command_set_banner_name,
game_command_set_sign_name,
game_command_set_banner_style,
game_command_set_sign_style
};

View File

@@ -83,7 +83,11 @@ enum GAME_COMMAND {
GAME_COMMAND_SET_LARGE_SCENERY_COLOUR,
GAME_COMMAND_SET_BANNER_COLOUR,
GAME_COMMAND_SET_LAND_OWNERSHIP,
GAME_COMMAND_CLEAR_SCENERY
GAME_COMMAND_CLEAR_SCENERY,
GAME_COMMAND_SET_BANNER_NAME,
GAME_COMMAND_SET_SIGN_NAME,
GAME_COMMAND_SET_BANNER_STYLE,
GAME_COMMAND_SET_SIGN_STYLE
};
enum {

View File

@@ -199,13 +199,7 @@ static void window_banner_mouseup(rct_window *w, int widgetIndex)
break;
case WIDX_BANNER_NO_ENTRY:
textinput_cancel();
banner->flags ^= BANNER_FLAG_NO_ENTRY;
window_invalidate(w);
map_element->properties.banner.flags = 0xFF;
if (banner->flags & BANNER_FLAG_NO_ENTRY){
map_element->properties.banner.flags &= ~(1 << map_element->properties.banner.position);
}
game_do_command(1, GAME_COMMAND_FLAG_APPLY, w->number, banner->colour, GAME_COMMAND_SET_BANNER_STYLE, banner->text_colour, banner->flags ^ BANNER_FLAG_NO_ENTRY);
break;
}
}
@@ -254,35 +248,13 @@ static void window_banner_dropdown(rct_window *w, int widgetIndex, int dropdownI
if (dropdownIndex == -1)
break;
banner->colour = (uint8)dropdownIndex;
window_invalidate(w);
game_do_command(1, GAME_COMMAND_FLAG_APPLY, w->number, dropdownIndex, GAME_COMMAND_SET_BANNER_STYLE, banner->text_colour, 0);
break;
case WIDX_TEXT_COLOR_DROPDOWN_BUTTON:
if (dropdownIndex == -1)
break;
banner->text_colour = dropdownIndex + 1;
int colourCodepoint = FORMAT_COLOUR_CODE_START + banner->text_colour;
uint8 buffer[256];
format_string(buffer, banner->string_idx, 0);
int firstCodepoint = utf8_get_next(buffer, NULL);
if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) {
utf8_write_codepoint(buffer, colourCodepoint);
} else {
utf8_insert_codepoint(buffer, colourCodepoint);
}
rct_string_id stringId = user_string_allocate(128, buffer);
if (stringId != 0) {
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = stringId;
user_string_free(prev_string_id);
window_invalidate(w);
} else {
window_error_open(2984, RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id));
}
game_do_command(1, GAME_COMMAND_FLAG_APPLY, w->number, banner->colour, GAME_COMMAND_SET_BANNER_STYLE, dropdownIndex + 1, 0);
break;
}
}
@@ -291,22 +263,9 @@ static void window_banner_dropdown(rct_window *w, int widgetIndex, int dropdownI
static void window_banner_textinput(rct_window *w, int widgetIndex, char *text)
{
if (widgetIndex == WIDX_BANNER_TEXT && text != NULL) {
rct_banner* banner = &gBanners[w->number];
utf8 *buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, uint8);
utf8 *dst = buffer;
dst = utf8_write_codepoint(dst, FORMAT_COLOUR_CODE_START + banner->text_colour);
strncpy(dst, text, 32);
rct_string_id stringId = user_string_allocate(128, buffer);
if (stringId) {
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = stringId;
user_string_free(prev_string_id);
window_invalidate(w);
} else {
window_error_open(2984, RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id));
}
game_do_command(1, GAME_COMMAND_FLAG_APPLY, w->number, *((int*)(text + 0)), GAME_COMMAND_SET_BANNER_NAME, *((int*)(text + 8)), *((int*)(text + 4)));
game_do_command(2, GAME_COMMAND_FLAG_APPLY, w->number, *((int*)(text + 12)), GAME_COMMAND_SET_BANNER_NAME, *((int*)(text + 20)), *((int*)(text + 16)));
game_do_command(0, GAME_COMMAND_FLAG_APPLY, w->number, *((int*)(text + 24)), GAME_COMMAND_SET_BANNER_NAME, *((int*)(text + 32)), *((int*)(text + 28)));
}
}

View File

@@ -187,8 +187,10 @@ void window_sign_open(rct_windownumber number)
int view_z = map_element->base_height << 3;
w->frame_no = view_z;
w->list_information_type = map_element->properties.scenerymultiple.colour[0] & 0x1F;
w->var_492 = map_element->properties.scenerymultiple.colour[1] & 0x1F;
rct_banner* banner = &gBanners[w->number];
banner->colour = map_element->properties.scenerymultiple.colour[0] & 0x1F;
banner->text_colour = map_element->properties.scenerymultiple.colour[1] & 0x1F;
w->var_48C = map_element->properties.scenerymultiple.type;
view_x += 16;
@@ -274,10 +276,10 @@ static void window_sign_mousedown(int widgetIndex, rct_window*w, rct_widget* wid
switch (widgetIndex) {
case WIDX_MAIN_COLOR:
window_dropdown_show_colour(w, widget, w->colours[1] | 0x80, (uint8)w->list_information_type);
window_dropdown_show_colour(w, widget, w->colours[1] | 0x80, (uint8)banner->colour);
break;
case WIDX_TEXT_COLOR:
window_dropdown_show_colour(w, widget, w->colours[1] | 0x80, (uint8)w->var_492);
window_dropdown_show_colour(w, widget, w->colours[1] | 0x80, (uint8)banner->text_colour);
break;
}
}
@@ -285,70 +287,31 @@ static void window_sign_mousedown(int widgetIndex, rct_window*w, rct_widget* wid
/* rct2: 0x6B979C */
static void window_sign_dropdown(rct_window *w, int widgetIndex, int dropdownIndex)
{
rct_banner *banner = &gBanners[w->number];
switch (widgetIndex){
case WIDX_MAIN_COLOR:
if (dropdownIndex == -1) return;
w->list_information_type = dropdownIndex;
game_do_command(1, GAME_COMMAND_FLAG_APPLY, w->number, banner->text_colour, GAME_COMMAND_SET_SIGN_STYLE, dropdownIndex, 1);
break;
case WIDX_TEXT_COLOR:
if (dropdownIndex == -1) return;
w->var_492 = dropdownIndex;
game_do_command(1, GAME_COMMAND_FLAG_APPLY, w->number, dropdownIndex, GAME_COMMAND_SET_SIGN_STYLE, banner->colour, 1);
break;
default:
return;
}
rct_banner *banner = &gBanners[w->number];
rct_map_element *mapElement = banner_get_map_element(w->number);
if (mapElement == NULL || map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_SCENERY_MULTIPLE)
return;
sign_set_colour(
banner->x * 32,
banner->y * 32,
mapElement->base_height,
mapElement->type & 3,
mapElement->properties.scenerymultiple.type >> 10,
w->list_information_type & 0xFF,
w->var_492 & 0xFF
);
window_invalidate(w);
}
/* rct2: 0x6B9791 & 0x6E6171*/
static void window_sign_textinput(rct_window *w, int widgetIndex, char *text)
{
rct_banner* banner = &gBanners[w->number];
int x = banner->x << 5;
int y = banner->y << 5;
if (widgetIndex == WIDX_SIGN_TEXT && text != NULL) {
if (*text != 0) {
rct_string_id string_id = user_string_allocate(128, text);
if (string_id != 0) {
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = string_id;
user_string_free(prev_string_id);
banner->flags &= ~(BANNER_FLAG_2);
gfx_invalidate_screen();
} else {
window_error_open(2984, RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id));
}
}
else{
int rideIndex = banner_get_closest_ride_index(x, y, 16);
if (rideIndex == -1)
return;
banner->colour = rideIndex;
banner->flags |= BANNER_FLAG_2;
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = 778;
user_string_free(prev_string_id);
gfx_invalidate_screen();
}
game_do_command(1, GAME_COMMAND_FLAG_APPLY, w->number, *((int*)(text + 0)), GAME_COMMAND_SET_SIGN_NAME, *((int*)(text + 8)), *((int*)(text + 4)));
game_do_command(2, GAME_COMMAND_FLAG_APPLY, w->number, *((int*)(text + 12)), GAME_COMMAND_SET_SIGN_NAME, *((int*)(text + 20)), *((int*)(text + 16)));
game_do_command(0, GAME_COMMAND_FLAG_APPLY, w->number, *((int*)(text + 24)), GAME_COMMAND_SET_SIGN_NAME, *((int*)(text + 32)), *((int*)(text + 28)));
}
}
@@ -372,8 +335,10 @@ static void window_sign_invalidate(rct_window *w)
text_colour_btn->type = WWT_COLORBTN;
}
main_colour_btn->image = (w->list_information_type << 19) | 0x600013C3;
text_colour_btn->image = (w->var_492 << 19) | 0x600013C3;
rct_banner* banner = &gBanners[w->number];
main_colour_btn->image = (banner->colour << 19) | 0x600013C3;
text_colour_btn->image = (banner->text_colour << 19) | 0x600013C3;
}
/* rct2: 0x006B9754 & 0x006E6134 */
@@ -468,8 +433,9 @@ void window_sign_small_open(rct_windownumber number){
int view_z = map_element->base_height << 3;
w->frame_no = view_z;
w->list_information_type = map_element->properties.fence.item[1] & 0x1F;
w->var_492 = (map_element->properties.fence.item[1] >> 5) | ((map_element->flags&0x60) >> 2);
rct_banner* banner = &gBanners[w->number];
banner->colour = map_element->properties.fence.item[1] & 0x1F;
banner->text_colour = (map_element->properties.fence.item[1] >> 5) | ((map_element->flags&0x60) >> 2);
w->var_48C = map_element->properties.fence.type;
view_x += 16;
@@ -550,43 +516,21 @@ static void window_sign_small_mouseup(rct_window *w, int widgetIndex)
/* rct2: 0x6E617C */
static void window_sign_small_dropdown(rct_window *w, int widgetIndex, int dropdownIndex)
{
rct_banner* banner = &gBanners[w->number];
switch (widgetIndex){
case WIDX_MAIN_COLOR:
if (dropdownIndex == -1) return;
w->list_information_type = dropdownIndex;
game_do_command(1, GAME_COMMAND_FLAG_APPLY, w->number, dropdownIndex, GAME_COMMAND_SET_SIGN_STYLE, banner->text_colour, 0);
break;
case WIDX_TEXT_COLOR:
if (dropdownIndex == -1) return;
w->var_492 = dropdownIndex;
game_do_command(1, GAME_COMMAND_FLAG_APPLY, w->number, banner->colour, GAME_COMMAND_SET_SIGN_STYLE, dropdownIndex, 0);
break;
default:
return;
}
rct_banner* banner = &gBanners[w->number];
int x = banner->x << 5;
int y = banner->y << 5;
rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32);
while (1){
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_FENCE) {
rct_scenery_entry* scenery_entry = g_wallSceneryEntries[map_element->properties.fence.type];
if (scenery_entry->wall.var_0D != 0xFF){
if (map_element->properties.fence.item[0] == w->number)
break;
}
}
map_element++;
}
map_element->flags &= 0x9F;
map_element->properties.fence.item[1] =
w->list_information_type |
((w->var_492 & 0x7) << 5);
map_element->flags |= ((w->var_492 & 0x18) << 2);
map_invalidate_tile(x, y, map_element->base_height * 8, map_element->clearance_height * 8);
window_invalidate(w);
}
@@ -610,6 +554,8 @@ static void window_sign_small_invalidate(rct_window *w)
text_colour_btn->type = WWT_COLORBTN;
}
main_colour_btn->image = (w->list_information_type << 19) | 0x600013C3;
text_colour_btn->image = (w->var_492 << 19) | 0x600013C3;
rct_banner* banner = &gBanners[w->number];
main_colour_btn->image = (banner->colour << 19) | 0x600013C3;
text_colour_btn->image = (banner->text_colour << 19) | 0x600013C3;
}

View File

@@ -4716,6 +4716,216 @@ void game_command_place_park_entrance(int* eax, int* ebx, int* ecx, int* edx, in
(*ebx >> 8) & 0xFF);
}
void game_command_set_banner_name(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) {
static char newName[128];
rct_banner* banner = &gBanners[*ecx];
int nameChunkIndex = *eax & 0xFFFF;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS * 4;
int nameChunkOffset = nameChunkIndex - 1;
if (nameChunkOffset < 0)
nameChunkOffset = 2;
nameChunkOffset *= 12;
RCT2_GLOBAL(newName + nameChunkOffset + 0, uint32) = *edx;
RCT2_GLOBAL(newName + nameChunkOffset + 4, uint32) = *ebp;
RCT2_GLOBAL(newName + nameChunkOffset + 8, uint32) = *edi;
if (nameChunkIndex != 0) {
*ebx = 0;
return;
}
utf8 *buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, uint8);
utf8 *dst = buffer;
dst = utf8_write_codepoint(dst, FORMAT_COLOUR_CODE_START + banner->text_colour);
strncpy(dst, newName, 32);
rct_string_id stringId = user_string_allocate(128, buffer);
if (stringId) {
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = stringId;
user_string_free(prev_string_id);
rct_window* w = window_bring_to_front_by_number(WC_BANNER, *ecx);
if (w) {
window_invalidate(w);
}
} else {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 2984;
*ebx = MONEY32_UNDEFINED;
return;
}
*ebx = 0;
}
void game_command_set_sign_name(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) {
static char newName[128];
rct_banner* banner = &gBanners[*ecx];
int x = banner->x << 5;
int y = banner->y << 5;
int nameChunkIndex = *eax & 0xFFFF;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS * 4;
int nameChunkOffset = nameChunkIndex - 1;
if (nameChunkOffset < 0)
nameChunkOffset = 2;
nameChunkOffset *= 12;
RCT2_GLOBAL(newName + nameChunkOffset + 0, uint32) = *edx;
RCT2_GLOBAL(newName + nameChunkOffset + 4, uint32) = *ebp;
RCT2_GLOBAL(newName + nameChunkOffset + 8, uint32) = *edi;
if (nameChunkIndex != 0) {
*ebx = 0;
return;
}
if (newName[0] != 0) {
rct_string_id string_id = user_string_allocate(128, newName);
if (string_id != 0) {
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = string_id;
user_string_free(prev_string_id);
banner->flags &= ~(BANNER_FLAG_2);
gfx_invalidate_screen();
} else {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 2984;
*ebx = MONEY32_UNDEFINED;
return;
}
}
else{
int rideIndex = banner_get_closest_ride_index(x, y, 16);
if (rideIndex == -1) {
*ebx = 0;
return;
}
banner->colour = rideIndex;
banner->flags |= BANNER_FLAG_2;
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = 778;
user_string_free(prev_string_id);
gfx_invalidate_screen();
}
*ebx = 0;
}
void game_command_set_banner_style(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) {
rct_banner* banner = &gBanners[*ecx];
banner->colour = (uint8)*edx;
banner->text_colour = (uint8)*edi;
banner->flags = (uint8)*ebp;
int x = banner->x << 5;
int y = banner->y << 5;
rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32);
while (1){
if ((map_element_get_type(map_element) == MAP_ELEMENT_TYPE_BANNER) &&
(map_element->properties.banner.index == *ecx)) break;
map_element++;
}
map_element->properties.banner.flags = 0xFF;
if (banner->flags & BANNER_FLAG_NO_ENTRY){
map_element->properties.banner.flags &= ~(1 << map_element->properties.banner.position);
}
int colourCodepoint = FORMAT_COLOUR_CODE_START + banner->text_colour;
uint8 buffer[256];
format_string(buffer, banner->string_idx, 0);
int firstCodepoint = utf8_get_next(buffer, NULL);
if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) {
utf8_write_codepoint(buffer, colourCodepoint);
} else {
utf8_insert_codepoint(buffer, colourCodepoint);
}
rct_string_id stringId = user_string_allocate(128, buffer);
if (stringId != 0) {
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = stringId;
user_string_free(prev_string_id);
rct_window* w = window_bring_to_front_by_number(WC_BANNER, *ecx);
if (w) {
window_invalidate(w);
}
} else {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 2984;
*ebx = MONEY32_UNDEFINED;
return;
}
*ebx = 0;
}
void game_command_set_sign_style(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) {
rct_banner *banner = &gBanners[*ecx];
int x = banner->x << 5;
int y = banner->y << 5;
banner->colour = (uint8)*edx;
banner->text_colour = (uint8)*edi;
if (*ebp == 0) { // small sign
rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32);
while (1){
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_FENCE) {
rct_scenery_entry* scenery_entry = g_wallSceneryEntries[map_element->properties.fence.type];
if (scenery_entry->wall.var_0D != 0xFF){
if (map_element->properties.fence.item[0] == *ecx)
break;
}
}
map_element++;
}
map_element->flags &= 0x9F;
map_element->properties.fence.item[1] =
banner->colour |
((banner->text_colour & 0x7) << 5);
map_element->flags |= ((banner->text_colour & 0x18) << 2);
map_invalidate_tile(x, y, map_element->base_height * 8, map_element->clearance_height * 8);
} else { // large sign
rct_map_element *mapElement = banner_get_map_element(*ecx);
if (mapElement == NULL || map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_SCENERY_MULTIPLE) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 2984;
*ebx = MONEY32_UNDEFINED;
return;
}
sign_set_colour(
banner->x * 32,
banner->y * 32,
mapElement->base_height,
mapElement->type & 3,
mapElement->properties.scenerymultiple.type >> 10,
banner->colour,
banner->text_colour
);
}
rct_window* w = window_bring_to_front_by_number(WC_BANNER, *ecx);
if (w) {
window_invalidate(w);
}
*ebx = 0;
}
/**
* Gets the map element at x, y, z.
* @param x x units, not tiles.

View File

@@ -335,6 +335,10 @@ void game_command_place_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi
void game_command_place_fence(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
void game_command_place_large_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
void game_command_place_park_entrance(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
void game_command_set_banner_name(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
void game_command_set_sign_name(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
void game_command_set_banner_style(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
void game_command_set_sign_style(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
#define GET_MAP_ELEMENT(x) (&(RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS, rct_map_element)[x]))
#define TILE_MAP_ELEMENT_POINTER(x) (RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[x])