mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-17 20:13:07 +01:00
fix rename and delete track design
This commit is contained in:
@@ -210,8 +210,8 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint16 var_480;
|
||||
uint16 var_482;
|
||||
uint16 var_484;
|
||||
bool reload_track_designs;
|
||||
} track_list_variables;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -1954,121 +1954,3 @@ static void track_design_preview_clear_map()
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006D3664
|
||||
*/
|
||||
bool track_design_rename(const char *text)
|
||||
{
|
||||
const char* txt_chr = text;
|
||||
|
||||
while (*txt_chr != '\0'){
|
||||
switch (*txt_chr){
|
||||
case '.':
|
||||
case '/':
|
||||
case '\\':
|
||||
case '*':
|
||||
case '?':
|
||||
// Invalid characters
|
||||
gGameCommandErrorText = STR_NEW_NAME_CONTAINS_INVALID_CHARACTERS;
|
||||
return false;
|
||||
}
|
||||
txt_chr++;
|
||||
}
|
||||
|
||||
char new_path[MAX_PATH];
|
||||
substitute_path(new_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), text);
|
||||
strcat(new_path, ".TD6");
|
||||
|
||||
rct_window* w = window_find_by_class(WC_TRACK_DESIGN_LIST);
|
||||
|
||||
char old_path[MAX_PATH];
|
||||
substitute_path(old_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), &RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, char)[128 * w->track_list.var_482]);
|
||||
|
||||
if (!platform_file_move(old_path, new_path)) {
|
||||
gGameCommandErrorText = STR_ANOTHER_FILE_EXISTS_WITH_NAME_OR_FILE_IS_WRITE_PROTECTED;
|
||||
return false;
|
||||
}
|
||||
|
||||
ride_list_item item = { 0xFC, 0 };
|
||||
// track_load_list(item);
|
||||
|
||||
item.type = RCT2_GLOBAL(0xF44158, uint8);
|
||||
item.entry_index = RCT2_GLOBAL(0xF44159, uint8);
|
||||
// track_load_list(item);
|
||||
|
||||
// reset_track_list_cache();
|
||||
|
||||
window_invalidate(w);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006D3761
|
||||
*/
|
||||
int track_delete()
|
||||
{
|
||||
rct_window* w = window_find_by_class(WC_TRACK_DESIGN_LIST);
|
||||
|
||||
char path[MAX_PATH];
|
||||
substitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), &RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, char)[128 * w->track_list.var_482]);
|
||||
|
||||
if (!platform_file_delete(path)) {
|
||||
gGameCommandErrorText = STR_FILE_IS_WRITE_PROTECTED_OR_LOCKED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ride_list_item item = { 0xFC, 0 };
|
||||
// track_load_list(item);
|
||||
|
||||
item.type = RCT2_GLOBAL(0xF44158, uint8);
|
||||
item.entry_index = RCT2_GLOBAL(0xF44159, uint8);
|
||||
// track_load_list(item);
|
||||
|
||||
// reset_track_list_cache();
|
||||
|
||||
window_invalidate(w);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006D40B2
|
||||
* returns 0 for copy fail, 1 for success, 2 for file exists.
|
||||
*/
|
||||
int install_track(char* source_path, char* dest_name){
|
||||
|
||||
// Make a copy of the track name (no extension)
|
||||
char track_name[MAX_PATH] = { 0 };
|
||||
char* dest = track_name;
|
||||
char* dest_name_pointer = dest_name;
|
||||
while (*dest_name_pointer != '.') *dest++ = *dest_name_pointer++;
|
||||
|
||||
// Check if .TD4 file exists under that name
|
||||
char* temp_extension_pointer = dest;
|
||||
strcat(track_name, ".TD4");
|
||||
|
||||
char dest_path[MAX_PATH];
|
||||
substitute_path(dest_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), track_name);
|
||||
|
||||
if (platform_file_exists(dest_path))
|
||||
return 2;
|
||||
|
||||
// Allow a concat onto the track_name but before extension
|
||||
*temp_extension_pointer = '\0';
|
||||
|
||||
// Check if .TD6 file exists under that name
|
||||
strcat(track_name, ".TD6");
|
||||
|
||||
substitute_path(dest_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), track_name);
|
||||
|
||||
if (platform_file_exists(dest_path))
|
||||
return 2;
|
||||
|
||||
// Set path for actual copy
|
||||
substitute_path(dest_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), dest_name);
|
||||
|
||||
return platform_file_copy(source_path, dest_path, false);
|
||||
}
|
||||
|
||||
@@ -163,7 +163,6 @@ extern uint8 gTrackDesignPlaceFlags;
|
||||
extern bool gTrackDesignSceneryToggle;
|
||||
|
||||
rct_track_design *temp_track_get_info(char* path, uint8** preview);
|
||||
int track_delete();
|
||||
void track_design_mirror(rct_track_td6 *td6);
|
||||
rct_track_td6 *track_design_open(const utf8 *path);
|
||||
void track_design_dispose(rct_track_td6 *td6);
|
||||
@@ -175,6 +174,8 @@ void track_design_index_create();
|
||||
size_t track_design_index_get_count_for_ride(uint8 rideType, const char *entry);
|
||||
size_t track_design_index_get_for_ride(track_design_file_ref **tdRefs, uint8 rideType, const char *entry);
|
||||
utf8 *track_design_get_name_from_path(const utf8 *path);
|
||||
bool track_design_index_rename(const utf8 *path, const utf8 *newName);
|
||||
bool track_design_index_delete(const utf8 *path);
|
||||
|
||||
void game_command_place_track_design(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_place_maze_design(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "../common.h"
|
||||
#include "../config.h"
|
||||
#include "../game.h"
|
||||
#include "../interface/window.h"
|
||||
#include "../localisation/string_ids.h"
|
||||
#include "../util/util.h"
|
||||
#include "track.h"
|
||||
#include "track_design.h"
|
||||
@@ -118,6 +121,7 @@ size_t track_design_index_get_for_ride(track_design_file_ref **tdRefs, uint8 rid
|
||||
refs[nextIndex].path = _strdup(tdItem.path);
|
||||
refsCount++;
|
||||
}
|
||||
SDL_RWclose(file);
|
||||
}
|
||||
|
||||
*tdRefs = realloc(refs, refsCount * sizeof(track_design_file_ref));
|
||||
@@ -137,6 +141,107 @@ utf8 *track_design_get_name_from_path(const utf8 *path)
|
||||
return strndup(filename, nameLength);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006D3664
|
||||
*/
|
||||
bool track_design_index_rename(const utf8 *path, const utf8 *newName)
|
||||
{
|
||||
if (str_is_null_or_empty(newName)) {
|
||||
gGameCommandErrorText = STR_CANT_RENAME_TRACK_DESIGN;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!filename_valid_characters(newName)) {
|
||||
gGameCommandErrorText = STR_NEW_NAME_CONTAINS_INVALID_CHARACTERS;
|
||||
return false;
|
||||
}
|
||||
|
||||
utf8 newPath[MAX_PATH];
|
||||
const char *lastPathSep = strrchr(path, platform_get_path_separator());
|
||||
if (lastPathSep == NULL) {
|
||||
gGameCommandErrorText = STR_CANT_RENAME_TRACK_DESIGN;
|
||||
return false;
|
||||
}
|
||||
size_t directoryLength = (size_t)(lastPathSep - path + 1);
|
||||
memcpy(newPath, path, directoryLength);
|
||||
strcpy(newPath + directoryLength, newName);
|
||||
strcat(newPath, ".td6");
|
||||
|
||||
if (!platform_file_move(path, newPath)) {
|
||||
gGameCommandErrorText = STR_ANOTHER_FILE_EXISTS_WITH_NAME_OR_FILE_IS_WRITE_PROTECTED;
|
||||
return false;
|
||||
}
|
||||
|
||||
track_design_index_create();
|
||||
|
||||
rct_window *trackListWindow = window_find_by_class(WC_TRACK_DESIGN_LIST);
|
||||
if (trackListWindow != NULL) {
|
||||
trackListWindow->track_list.reload_track_designs = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006D3761
|
||||
*/
|
||||
bool track_design_index_delete(const utf8 *path)
|
||||
{
|
||||
if (!platform_file_delete(path)) {
|
||||
gGameCommandErrorText = STR_FILE_IS_WRITE_PROTECTED_OR_LOCKED;
|
||||
return false;
|
||||
}
|
||||
|
||||
track_design_index_create();
|
||||
|
||||
rct_window *trackListWindow = window_find_by_class(WC_TRACK_DESIGN_LIST);
|
||||
if (trackListWindow != NULL) {
|
||||
trackListWindow->track_list.reload_track_designs = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006D40B2
|
||||
* returns 0 for copy fail, 1 for success, 2 for file exists.
|
||||
*/
|
||||
int install_track(char* source_path, char* dest_name){
|
||||
|
||||
// Make a copy of the track name (no extension)
|
||||
char track_name[MAX_PATH] = { 0 };
|
||||
char* dest = track_name;
|
||||
char* dest_name_pointer = dest_name;
|
||||
while (*dest_name_pointer != '.') *dest++ = *dest_name_pointer++;
|
||||
|
||||
// Check if .TD4 file exists under that name
|
||||
char* temp_extension_pointer = dest;
|
||||
strcat(track_name, ".TD4");
|
||||
|
||||
char dest_path[MAX_PATH];
|
||||
substitute_path(dest_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), track_name);
|
||||
|
||||
if (platform_file_exists(dest_path))
|
||||
return 2;
|
||||
|
||||
// Allow a concat onto the track_name but before extension
|
||||
*temp_extension_pointer = '\0';
|
||||
|
||||
// Check if .TD6 file exists under that name
|
||||
strcat(track_name, ".TD6");
|
||||
|
||||
substitute_path(dest_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), track_name);
|
||||
|
||||
if (platform_file_exists(dest_path))
|
||||
return 2;
|
||||
|
||||
// Set path for actual copy
|
||||
substitute_path(dest_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), dest_name);
|
||||
|
||||
return platform_file_copy(source_path, dest_path, false);
|
||||
}
|
||||
|
||||
static bool track_design_index_read_header(SDL_RWops *file, uint32 *tdidxCount)
|
||||
{
|
||||
uint32 tdidxMagicNumber, tdidxVersion;
|
||||
@@ -182,7 +287,7 @@ static int track_design_index_item_compare(const void *a, const void *b)
|
||||
|
||||
const utf8 *tdAName = path_get_filename(tdA->path);
|
||||
const utf8 *tdBName = path_get_filename(tdB->path);
|
||||
return strcmp(tdAName, tdBName);
|
||||
return _stricmp(tdAName, tdBName);
|
||||
}
|
||||
|
||||
static void track_design_index_include(const utf8 *directory)
|
||||
@@ -246,7 +351,7 @@ static void track_design_add(const td_index_item *item)
|
||||
|
||||
static void track_design_index_dispose()
|
||||
{
|
||||
free(_tdIndex);
|
||||
SafeFree(_tdIndex);
|
||||
_tdIndexSize = 0;
|
||||
_tdIndexCapacity = 0;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,6 @@ void window_install_track_open(const char* path)
|
||||
w->widgets = window_install_track_widgets;
|
||||
w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_ROTATE) | (1 << WIDX_TOGGLE_SCENERY) | (1 << WIDX_INSTALL) | (1 << WIDX_CANCEL);
|
||||
window_init_scroll_widgets(w);
|
||||
w->track_list.var_482 = 0;
|
||||
w->track_list.var_484 = 0;
|
||||
window_push_others_right(w);
|
||||
|
||||
@@ -268,11 +267,11 @@ static void window_install_track_invalidate(rct_window *w)
|
||||
w->pressed_widgets &= ~(1 << WIDX_TOGGLE_SCENERY);
|
||||
}
|
||||
|
||||
if (w->track_list.var_482 != 0xFFFF) {
|
||||
w->disabled_widgets &= ~(1 << WIDX_TRACK_PREVIEW);
|
||||
} else {
|
||||
w->disabled_widgets |= (1 << WIDX_TRACK_PREVIEW);
|
||||
}
|
||||
// if (w->track_list.var_482 != 0xFFFF) {
|
||||
// w->disabled_widgets &= ~(1 << WIDX_TRACK_PREVIEW);
|
||||
// } else {
|
||||
// w->disabled_widgets |= (1 << WIDX_TRACK_PREVIEW);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -291,8 +290,8 @@ static void window_install_track_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
||||
|
||||
window_draw_widgets(w, dpi);
|
||||
|
||||
if (w->track_list.var_482 == 0xFFFF)
|
||||
return;
|
||||
// if (w->track_list.var_482 == 0xFFFF)
|
||||
// return;
|
||||
|
||||
// Track preview
|
||||
widget = &window_install_track_widgets[WIDX_TRACK_PREVIEW];
|
||||
|
||||
@@ -53,6 +53,7 @@ static rct_widget window_track_list_widgets[] = {
|
||||
|
||||
static void window_track_list_close(rct_window *w);
|
||||
static void window_track_list_mouseup(rct_window *w, int widgetIndex);
|
||||
static void window_track_list_update(rct_window *w);
|
||||
static void window_track_list_scrollgetsize(rct_window *w, int scrollIndex, int *width, int *height);
|
||||
static void window_track_list_scrollmousedown(rct_window *w, int scrollIndex, int x, int y);
|
||||
static void window_track_list_scrollmouseover(rct_window *w, int scrollIndex, int x, int y);
|
||||
@@ -72,7 +73,7 @@ static rct_window_event_list window_track_list_events = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
window_track_list_update,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -138,8 +139,9 @@ void window_track_list_open(ride_list_item item)
|
||||
w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_ROTATE) | (1 << WIDX_TOGGLE_SCENERY) | (1 << WIDX_BACK);
|
||||
window_init_scroll_widgets(w);
|
||||
w->track_list.var_480 = 0xFFFF;
|
||||
w->track_list.var_482 = gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER ? 0 : 1;
|
||||
w->track_list.var_484 = 0;
|
||||
w->track_list.reload_track_designs = false;
|
||||
w->selected_list_item = gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER ? 0 : 1;
|
||||
gTrackDesignSceneryToggle = false;
|
||||
window_push_others_right(w);
|
||||
_currentTrackPieceDirection = 2;
|
||||
@@ -287,8 +289,8 @@ static void window_track_list_scrollmouseover(rct_window *w, int scrollIndex, in
|
||||
{
|
||||
if (!(w->track_list.var_484 & 1)) {
|
||||
int i = window_track_list_get_list_item_index_from_position(x, y);
|
||||
if (i != -1 && w->track_list.var_482 != i) {
|
||||
w->track_list.var_482 = i;
|
||||
if (i != -1 && w->selected_list_item != i) {
|
||||
w->selected_list_item = i;
|
||||
window_invalidate(w);
|
||||
}
|
||||
}
|
||||
@@ -303,6 +305,15 @@ static void window_track_list_tooltip(rct_window* w, int widgetIndex, rct_string
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint16) = STR_LIST;
|
||||
}
|
||||
|
||||
static void window_track_list_update(rct_window *w)
|
||||
{
|
||||
if (w->track_list.reload_track_designs) {
|
||||
track_list_load_designs(_window_track_list_item);
|
||||
w->selected_list_item = 0;
|
||||
window_invalidate(w);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006CF2D6
|
||||
@@ -329,7 +340,7 @@ static void window_track_list_invalidate(rct_window *w)
|
||||
window_track_list_widgets[WIDX_TRACK_LIST].tooltip = STR_CLICK_ON_DESIGN_TO_BUILD_IT_TIP;
|
||||
}
|
||||
|
||||
if ((gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) || w->track_list.var_482 != 0) {
|
||||
if ((gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) || w->selected_list_item != 0) {
|
||||
w->pressed_widgets |= 1 << WIDX_TRACK_PREVIEW;
|
||||
w->disabled_widgets &= ~(1 << WIDX_TRACK_PREVIEW);
|
||||
window_track_list_widgets[WIDX_ROTATE].type = WWT_FLATBTN;
|
||||
@@ -355,7 +366,7 @@ static void window_track_list_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
||||
{
|
||||
window_draw_widgets(w, dpi);
|
||||
|
||||
int trackIndex = w->track_list.var_482;
|
||||
int trackIndex = w->selected_list_item;
|
||||
if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) {
|
||||
if (_trackDesignsCount == 0 || trackIndex == -1) {
|
||||
return;
|
||||
@@ -551,7 +562,7 @@ static void window_track_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi,
|
||||
} else {
|
||||
// Build custom track item
|
||||
rct_string_id stringId;
|
||||
if (listIndex == w->track_list.var_482) {
|
||||
if (listIndex == w->selected_list_item) {
|
||||
// Highlight
|
||||
gfx_fill_rect(dpi, x, y, w->width, y + 9, 0x2000000 | 49);
|
||||
stringId = 1193;
|
||||
@@ -568,7 +579,7 @@ static void window_track_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi,
|
||||
for (size_t i = 0; i < _trackDesignsCount; i++, listIndex++) {
|
||||
if (y + 10 >= dpi->y && y < dpi->y + dpi->height) {
|
||||
rct_string_id stringId;
|
||||
if (listIndex == w->track_list.var_482) {
|
||||
if (listIndex == w->selected_list_item) {
|
||||
// Highlight
|
||||
gfx_fill_rect(dpi, x, y, w->width, y + 9, 0x2000000 | 49);
|
||||
stringId = 1193;
|
||||
|
||||
@@ -217,16 +217,16 @@ static void window_track_manage_mouseup(rct_window *w, int widgetIndex)
|
||||
*/
|
||||
static void window_track_manage_textinput(rct_window *w, int widgetIndex, char *text)
|
||||
{
|
||||
if (widgetIndex != WIDX_RENAME || text == NULL) {
|
||||
if (widgetIndex != WIDX_RENAME || str_is_null_or_empty(text)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if (track_rename(text)) {
|
||||
// window_close_by_class(WC_TRACK_DELETE_PROMPT);
|
||||
// window_close(w);
|
||||
// } else {
|
||||
// window_error_open(STR_CANT_RENAME_TRACK_DESIGN, gGameCommandErrorText);
|
||||
// }
|
||||
if (track_design_index_rename(_trackDesignFileReference->path, text)) {
|
||||
window_close_by_class(WC_TRACK_DELETE_PROMPT);
|
||||
window_close(w);
|
||||
} else {
|
||||
window_error_open(STR_CANT_RENAME_TRACK_DESIGN, gGameCommandErrorText);
|
||||
}
|
||||
}
|
||||
|
||||
static void window_track_manage_invalidate(rct_window *w)
|
||||
@@ -284,7 +284,7 @@ static void window_track_delete_prompt_mouseup(rct_window *w, int widgetIndex)
|
||||
break;
|
||||
case WIDX_PROMPT_DELETE:
|
||||
window_close(w);
|
||||
if (track_delete()) {
|
||||
if (track_design_index_delete(_trackDesignFileReference->path)) {
|
||||
window_close_by_class(WC_MANAGE_TRACK_DESIGN);
|
||||
} else {
|
||||
window_error_open(STR_CANT_DELETE_TRACK_DESIGN, gGameCommandErrorText);
|
||||
|
||||
Reference in New Issue
Block a user