From 6dcbcb97ade576f210a2c04ea828be4f68dbddad Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Fri, 21 Jul 2023 10:50:33 +0300 Subject: [PATCH 01/62] Add process_pull_down --- src/window_manager_private.cc | 219 +++++++++++++++++++++++++++++++++- 1 file changed, 217 insertions(+), 2 deletions(-) diff --git a/src/window_manager_private.cc b/src/window_manager_private.cc index 2f4c706..2330211 100644 --- a/src/window_manager_private.cc +++ b/src/window_manager_private.cc @@ -1218,8 +1218,223 @@ int _win_input_str(int win, char* dest, int maxLength, int x, int y, int textCol // 0x4DBD04 int process_pull_down(int win, Rect* rect, char** items, int itemsLength, int foregroundColor, int backgroundColor, MenuBar* menuBar, int pulldownIndex) { - // TODO: Incomplete. - return -1; + if (menuBar != NULL) { + unsigned char* parentWindowBuffer = windowGetWindow(menuBar->win)->buffer; + MenuPulldown* pulldown = &(menuBar->pulldowns[pulldownIndex]); + + int x = pulldown->rect.left; + int y = pulldown->rect.top; + int width = pulldown->rect.right - x + 1; + int height = pulldown->rect.bottom - y + 1; + + int color1 = menuBar->foregroundColor; + if ((color1 & 0xFF00) != 0) { + int colorIndex = (color1 & 0xFF) - 1; + color1 = (color1 & ~0xFFFF) | _colorTable[_GNW_wcolor[colorIndex]]; + } + + int color2 = menuBar->backgroundColor; + if ((color2 & 0xFF00) != 0) { + int colorIndex = (color2 & 0xFF) - 1; + color2 = (color2 & ~0xFFFF) | _colorTable[_GNW_wcolor[colorIndex]]; + } + + _swap_color_buf(parentWindowBuffer + width * y + x, + width, + height, + windowGetWidth(menuBar->win), + color1, + color2); + windowRefreshRect(menuBar->win, &(pulldown->rect)); + } + + unsigned char* windowBuffer = windowGetWindow(win)->buffer; + int width = rectGetWidth(rect); + int height = rectGetHeight(rect); + + int focusedIndex = -1; + int rc; + int mx1; + int my1; + int mx2; + int my2; + int input; + + mouseGetPosition(&mx1, &my1); + + while (1) { + sharedFpsLimiter.mark(); + + input = inputGetInput(); + if (input != -1) { + break; + } + + mouseGetPosition(&mx2, &my2); + + if (mx2 < mx1 - 4 + || mx2 > mx1 + 4 + || my2 < my1 - 4 + || my2 > my1 + 4) { + break; + } + + renderPresent(); + sharedFpsLimiter.throttle(); + } + + while (1) { + sharedFpsLimiter.mark(); + + mouseGetPosition(&mx2, &my2); + + if (input == -2) { + if (menuBar != NULL) { + if (_mouse_click_in(menuBar->rect.left, menuBar->rect.top, menuBar->rect.right, menuBar->rect.bottom)) { + int index; + for (index = 0; index < menuBar->pulldownsLength; index++) { + MenuPulldown* pulldown = &(menuBar->pulldowns[index]); + if (_mouse_click_in(pulldown->rect.left, pulldown->rect.top, pulldown->rect.right, pulldown->rect.bottom)) { + break; + } + } + + if (index < menuBar->pulldownsLength && index != pulldownIndex) { + rc = -2 - index; + break; + } + } + } + } + + if ((mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_UP) != 0 + || ((mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_DOWN) != 0 + && (mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT) == 0)) { + if (_mouse_click_in(rect->left, rect->top + 8, rect->right, rect->bottom - 9)) { + rc = focusedIndex; + } else { + rc = -1; + } + break; + } + + bool done = false; + switch (input) { + case KEY_ESCAPE: + rc = -1; + done = true; + break; + case KEY_RETURN: + rc = focusedIndex; + done = true; + break; + case KEY_ARROW_LEFT: + if (menuBar != NULL && pulldownIndex > 0) { + rc = -2 - (pulldownIndex - 1); + done = true; + } + break; + case KEY_ARROW_RIGHT: + if (menuBar != NULL && pulldownIndex < menuBar->pulldownsLength - 1) { + rc = -2 - (pulldownIndex + 1); + done = true; + } + break; + case KEY_ARROW_UP: + while (focusedIndex > 0) { + focusedIndex--; + + if (items[focusedIndex][0] != '\0') { + break; + } + } + input = -3; + break; + case KEY_ARROW_DOWN: + while (focusedIndex < itemsLength - 1) { + focusedIndex++; + + if (items[focusedIndex][0] != '\0') { + break; + } + } + input = -3; + break; + default: + if (mx2 != mx1 || my2 != my1) { + if (_mouse_click_in(rect->left, rect->top + 8, rect->right, rect->bottom - 9)) { + input = (my2 - rect->top - 8) / fontGetLineHeight(); + if (input != -1) { + focusedIndex = items[input][0] != '\0' ? input : -1; + input = -3; + } + } + + mx1 = mx2; + my1 = my2; + } + break; + } + + if (done) { + break; + } + + if (input == -3) { + windowFill(win, 2, 8, width - 4, height - 16, backgroundColor); + _win_text(win, items, itemsLength, width - 4, 2, 8, foregroundColor); + + if (focusedIndex != -1) { + _lighten_buf(windowBuffer + (focusedIndex * fontGetLineHeight() + 8) * width + 2, + width - 4, + fontGetLineHeight(), + width); + } + + windowRefresh(win); + } + + input = inputGetInput(); + + renderPresent(); + sharedFpsLimiter.throttle(); + } + + if (menuBar != NULL) { + unsigned char* parentWindowBuffer = windowGetWindow(menuBar->win)->buffer; + MenuPulldown* pulldown = &(menuBar->pulldowns[pulldownIndex]); + + int x = pulldown->rect.left; + int y = pulldown->rect.top; + int width = pulldown->rect.right - x + 1; + int height = pulldown->rect.bottom - y + 1; + + int color1 = menuBar->foregroundColor; + if ((color1 & 0xFF00) != 0) { + int colorIndex = (color1 & 0xFF) - 1; + color1 = (color1 & ~0xFFFF) | _colorTable[_GNW_wcolor[colorIndex]]; + } + + int color2 = menuBar->backgroundColor; + if ((color2 & 0xFF00) != 0) { + int colorIndex = (color2 & 0xFF) - 1; + color2 = (color2 & ~0xFFFF) | _colorTable[_GNW_wcolor[colorIndex]]; + } + + _swap_color_buf(parentWindowBuffer + width * y + x, + width, + height, + windowGetWidth(menuBar->win), + color1, + color2); + windowRefreshRect(menuBar->win, &(pulldown->rect)); + + renderPresent(); + } + + windowDestroy(win); + + return rc; } // 0x4DC930 From f6cfc1fa3aa5b8471873b1d5db5edf8a76500cb2 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Fri, 21 Jul 2023 11:02:54 +0300 Subject: [PATCH 02/62] Clarify GNW_check_menu_bars param --- src/window_manager.cc | 9 ++++----- src/window_manager.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/window_manager.cc b/src/window_manager.cc index f3d01ce..f014295 100644 --- a/src/window_manager.cc +++ b/src/window_manager.cc @@ -1257,19 +1257,18 @@ Button* buttonGetButton(int btn, Window** windowPtr) } // 0x4D7A34 -int _GNW_check_menu_bars(int a1) +int _GNW_check_menu_bars(int input) { if (!gWindowSystemInitialized) { return -1; } - int v1 = a1; for (int index = gWindowsLength - 1; index >= 1; index--) { Window* window = gWindows[index]; if (window->menuBar != NULL) { for (int pulldownIndex = 0; pulldownIndex < window->menuBar->pulldownsLength; pulldownIndex++) { - if (v1 == window->menuBar->pulldowns[pulldownIndex].keyCode) { - v1 = _GNW_process_menu(window->menuBar, pulldownIndex); + if (input == window->menuBar->pulldowns[pulldownIndex].keyCode) { + input = _GNW_process_menu(window->menuBar, pulldownIndex); break; } } @@ -1280,7 +1279,7 @@ int _GNW_check_menu_bars(int a1) } } - return v1; + return input; } // 0x4D69DC diff --git a/src/window_manager.h b/src/window_manager.h index 99180d7..2f76563 100644 --- a/src/window_manager.h +++ b/src/window_manager.h @@ -177,7 +177,7 @@ int windowGetWidth(int win); int windowGetHeight(int win); int windowGetRect(int win, Rect* rect); int _win_check_all_buttons(); -int _GNW_check_menu_bars(int a1); +int _GNW_check_menu_bars(int input); void programWindowSetTitle(const char* title); bool showMesageBox(const char* str); int buttonCreate(int win, int x, int y, int width, int height, int mouseEnterEventCode, int mouseExitEventCode, int mouseDownEventCode, int mouseUpEventCode, unsigned char* up, unsigned char* dn, unsigned char* hover, int flags); From 7a45ac72f021fd05d51a0764db22a92d96b4389b Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Fri, 21 Jul 2023 11:10:15 +0300 Subject: [PATCH 03/62] Add reading mapper config --- src/game_config.cc | 20 ++++++++++++++++++-- src/game_config.h | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/game_config.cc b/src/game_config.cc index dde349d..7063ec7 100644 --- a/src/game_config.cc +++ b/src/game_config.cc @@ -125,10 +125,26 @@ bool gameConfigInit(bool isMapper, int argc, char** argv) char* ch = strrchr(executable, '\\'); if (ch != NULL) { *ch = '\0'; - snprintf(gGameConfigFilePath, sizeof(gGameConfigFilePath), "%s\\%s", executable, GAME_CONFIG_FILE_NAME); + if (isMapper) { + snprintf(gGameConfigFilePath, + sizeof(gGameConfigFilePath), + "%s\\%s", + executable, + MAPPER_CONFIG_FILE_NAME); + } else { + snprintf(gGameConfigFilePath, + sizeof(gGameConfigFilePath), + "%s\\%s", + executable, + GAME_CONFIG_FILE_NAME); + } *ch = '\\'; } else { - strcpy(gGameConfigFilePath, GAME_CONFIG_FILE_NAME); + if (isMapper) { + strcpy(gGameConfigFilePath, MAPPER_CONFIG_FILE_NAME); + } else { + strcpy(gGameConfigFilePath, GAME_CONFIG_FILE_NAME); + } } // Read contents of `fallout2.cfg` into config. The values from the file diff --git a/src/game_config.h b/src/game_config.h index a444762..78a1299 100644 --- a/src/game_config.h +++ b/src/game_config.h @@ -5,8 +5,8 @@ namespace fallout { -// The file name of the main config file. #define GAME_CONFIG_FILE_NAME "fallout2.cfg" +#define MAPPER_CONFIG_FILE_NAME "mapper2.cfg" #define GAME_CONFIG_SYSTEM_KEY "system" #define GAME_CONFIG_PREFERENCES_KEY "preferences" From d27eafe03a46512d4cd2c6c38fe2e65ba0c51aa2 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Fri, 21 Jul 2023 11:22:57 +0300 Subject: [PATCH 04/62] Fix win_get_str return code --- src/window_manager_private.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/window_manager_private.cc b/src/window_manager_private.cc index 2330211..beef020 100644 --- a/src/window_manager_private.cc +++ b/src/window_manager_private.cc @@ -612,7 +612,7 @@ int _win_get_str(char* dest, int length, const char* title, int x, int y) windowRefresh(win); - _win_input_str(win, + int rc = _win_input_str(win, dest, length, 16, @@ -622,7 +622,7 @@ int _win_get_str(char* dest, int length, const char* title, int x, int y) windowDestroy(win); - return 0; + return rc; } // 0x4DB920 From ccabbd76888b61f42399d89d500160b089c4f32d Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 22 Jul 2023 14:46:51 +0300 Subject: [PATCH 05/62] Add proto_is_subtype --- src/proto.cc | 17 +++++++++++++++++ src/proto.h | 1 + 2 files changed, 18 insertions(+) diff --git a/src/proto.cc b/src/proto.cc index efb05b0..421939e 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -828,6 +828,23 @@ int _proto_dude_init(const char* path) return 0; } +// 0x49FEDC +bool proto_is_subtype(Proto* proto, int subtype) +{ + if (subtype == -1) { + return true; + } + + switch (PID_TYPE(proto->pid)) { + case OBJ_TYPE_ITEM: + return proto->item.type == subtype; + case OBJ_TYPE_SCENERY: + return proto->scenery.type == subtype; + } + + return false; +} + // proto_data_member // 0x49FFD8 int protoGetDataMember(int pid, int member, ProtoDataMemberValue* value) diff --git a/src/proto.h b/src/proto.h index d6f13e6..e68140f 100644 --- a/src/proto.h +++ b/src/proto.h @@ -118,6 +118,7 @@ int objectDataWrite(Object* obj, File* stream); int _proto_update_init(Object* obj); int _proto_dude_update_gender(); int _proto_dude_init(const char* path); +bool proto_is_subtype(Proto* proto, int subtype); int protoGetDataMember(int pid, int member, ProtoDataMemberValue* value); int protoInit(); void protoReset(); From a4daffa30e1636df56a4a96947670db95ee379bc Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 22 Jul 2023 14:49:56 +0300 Subject: [PATCH 06/62] Add proto_copy_proto --- src/proto.cc | 28 ++++++++++++++++++++++++++++ src/proto.h | 1 + 2 files changed, 29 insertions(+) diff --git a/src/proto.cc b/src/proto.cc index 421939e..f1d6aea 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -828,6 +828,34 @@ int _proto_dude_init(const char* path) return 0; } +// 0x49FE74 +int proto_copy_proto(int srcPid, int dstPid) +{ + int srcType; + int dstType; + Proto* src; + Proto* dst; + + srcType = PID_TYPE(srcPid); + dstType = PID_TYPE(dstPid); + if (srcType != dstType) { + return -1; + } + + if (protoGetProto(srcPid, &src) == -1) { + return -1; + } + + if (protoGetProto(dstPid, &dst) == -1) { + return -1; + } + + memcpy(dst, src, _proto_sizes[srcType]); + dst->pid = dstPid; + + return 0; +} + // 0x49FEDC bool proto_is_subtype(Proto* proto, int subtype) { diff --git a/src/proto.h b/src/proto.h index e68140f..9448a09 100644 --- a/src/proto.h +++ b/src/proto.h @@ -118,6 +118,7 @@ int objectDataWrite(Object* obj, File* stream); int _proto_update_init(Object* obj); int _proto_dude_update_gender(); int _proto_dude_init(const char* path); +int proto_copy_proto(int srcPid, int dstPid); bool proto_is_subtype(Proto* proto, int subtype); int protoGetDataMember(int pid, int member, ProtoDataMemberValue* value); int protoInit(); From ffc440c8097f0b34282f0b398b22f8d7867fa773 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 22 Jul 2023 14:53:22 +0300 Subject: [PATCH 07/62] Add proto_misc_init --- src/proto.cc | 19 +++++++++++++++++++ src/proto.h | 1 + 2 files changed, 20 insertions(+) diff --git a/src/proto.cc b/src/proto.cc index f1d6aea..33a505a 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -828,6 +828,25 @@ int _proto_dude_init(const char* path) return 0; } +// 0x49FDFC +int proto_misc_init(Proto* proto, int a2) +{ + int v1 = a2 & 0xFFFFFF; + + proto->misc.pid = -1; + proto->misc.messageId = 100 * v1; + proto->misc.fid = buildFid(OBJ_TYPE_MISC, v1 - 1, 0, 0, 0); + if (!artExists(proto->misc.fid)) { + proto->misc.fid = buildFid(OBJ_TYPE_MISC, 0, 0, 0, 0); + } + proto->misc.lightDistance = 0; + proto->misc.lightIntensity = 0; + proto->misc.flags = 0; + proto->misc.extendedFlags = 0; + + return 0; +} + // 0x49FE74 int proto_copy_proto(int srcPid, int dstPid) { diff --git a/src/proto.h b/src/proto.h index 9448a09..5573a87 100644 --- a/src/proto.h +++ b/src/proto.h @@ -118,6 +118,7 @@ int objectDataWrite(Object* obj, File* stream); int _proto_update_init(Object* obj); int _proto_dude_update_gender(); int _proto_dude_init(const char* path); +int proto_misc_init(Proto* proto, int a2); int proto_copy_proto(int srcPid, int dstPid); bool proto_is_subtype(Proto* proto, int subtype); int protoGetDataMember(int pid, int member, ProtoDataMemberValue* value); From 1d310eb6266308138e653bd9d3a31cbd4d536f0f Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 22 Jul 2023 14:58:47 +0300 Subject: [PATCH 08/62] Add proto_tile_init --- src/proto.cc | 19 +++++++++++++++++++ src/proto.h | 1 + 2 files changed, 20 insertions(+) diff --git a/src/proto.cc b/src/proto.cc index 33a505a..b6d544f 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -828,6 +828,25 @@ int _proto_dude_init(const char* path) return 0; } +// 0x49FD84 +int proto_tile_init(Proto* proto, int a2) +{ + int v1 = a2 & 0xFFFFFF; + + proto->tile.pid = -1; + proto->tile.messageId = 100 * v1; + proto->tile.fid = buildFid(OBJ_TYPE_TILE, v1 - 1, 0, 0, 0); + if (!artExists(proto->tile.fid)) { + proto->tile.fid = buildFid(OBJ_TYPE_TILE, 0, 0, 0, 0); + } + proto->tile.flags = 0; + proto->tile.extendedFlags = 0x2000; + proto->tile.sid = -1; + proto->tile.material = 1; + + return 0; +} + // 0x49FDFC int proto_misc_init(Proto* proto, int a2) { diff --git a/src/proto.h b/src/proto.h index 5573a87..e771b8d 100644 --- a/src/proto.h +++ b/src/proto.h @@ -118,6 +118,7 @@ int objectDataWrite(Object* obj, File* stream); int _proto_update_init(Object* obj); int _proto_dude_update_gender(); int _proto_dude_init(const char* path); +int proto_tile_init(Proto* proto, int a2); int proto_misc_init(Proto* proto, int a2); int proto_copy_proto(int srcPid, int dstPid); bool proto_is_subtype(Proto* proto, int subtype); From 6a75ec07e9edd6ca9a3aa47fa5017346a2bb2908 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 22 Jul 2023 14:59:32 +0300 Subject: [PATCH 09/62] Add proto_wall_init --- src/proto.cc | 21 +++++++++++++++++++++ src/proto.h | 1 + 2 files changed, 22 insertions(+) diff --git a/src/proto.cc b/src/proto.cc index b6d544f..cf4af89 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -828,6 +828,27 @@ int _proto_dude_init(const char* path) return 0; } +// 0x49FCFC +int proto_wall_init(Proto* proto, int a2) +{ + int v1 = a2 & 0xFFFFFF; + + proto->wall.pid = -1; + proto->wall.messageId = 100 * v1; + proto->wall.fid = buildFid(OBJ_TYPE_WALL, v1 - 1, 0, 0, 0); + if (!artExists(proto->wall.fid)) { + proto->wall.fid = buildFid(OBJ_TYPE_WALL, 0, 0, 0, 0); + } + proto->wall.lightDistance = 0; + proto->wall.lightIntensity = 0; + proto->wall.flags = 0; + proto->wall.extendedFlags = 0x2000; + proto->wall.sid = -1; + proto->wall.material = 1; + + return 0; +} + // 0x49FD84 int proto_tile_init(Proto* proto, int a2) { diff --git a/src/proto.h b/src/proto.h index e771b8d..ba4626b 100644 --- a/src/proto.h +++ b/src/proto.h @@ -118,6 +118,7 @@ int objectDataWrite(Object* obj, File* stream); int _proto_update_init(Object* obj); int _proto_dude_update_gender(); int _proto_dude_init(const char* path); +int proto_wall_init(Proto* proto, int a2); int proto_tile_init(Proto* proto, int a2); int proto_misc_init(Proto* proto, int a2); int proto_copy_proto(int srcPid, int dstPid); From 01a68af4a4db88feb1c8235d6467896078a2c4d6 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 22 Jul 2023 15:05:00 +0300 Subject: [PATCH 10/62] Add proto_scenery_subdata_init --- src/proto.cc | 31 +++++++++++++++++++++++++++++++ src/proto.h | 1 + 2 files changed, 32 insertions(+) diff --git a/src/proto.cc b/src/proto.cc index cf4af89..597af60 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -828,6 +828,37 @@ int _proto_dude_init(const char* path) return 0; } +// 0x49FC74 +int proto_scenery_subdata_init(Proto* proto, int type) +{ + switch (type) { + case SCENERY_TYPE_DOOR: + proto->scenery.data.door.openFlags = 0; + proto->scenery.extendedFlags |= 0x800; + break; + case SCENERY_TYPE_STAIRS: + proto->scenery.data.stairs.field_0 = -1; + proto->scenery.data.stairs.field_4 = -1; + proto->scenery.extendedFlags |= 0x800; + break; + case SCENERY_TYPE_ELEVATOR: + proto->scenery.data.elevator.type = -1; + proto->scenery.data.elevator.level = -1; + proto->scenery.extendedFlags |= 0x800; + break; + case SCENERY_TYPE_LADDER_UP: + proto->scenery.data.ladder.field_0 = -1; + proto->scenery.extendedFlags |= 0x800; + break; + case SCENERY_TYPE_LADDER_DOWN: + proto->scenery.data.ladder.field_0 = -1; + proto->scenery.extendedFlags |= 0x800; + break; + } + + return 0; +} + // 0x49FCFC int proto_wall_init(Proto* proto, int a2) { diff --git a/src/proto.h b/src/proto.h index ba4626b..982af88 100644 --- a/src/proto.h +++ b/src/proto.h @@ -118,6 +118,7 @@ int objectDataWrite(Object* obj, File* stream); int _proto_update_init(Object* obj); int _proto_dude_update_gender(); int _proto_dude_init(const char* path); +int proto_scenery_subdata_init(Proto* proto, int type); int proto_wall_init(Proto* proto, int a2); int proto_tile_init(Proto* proto, int a2); int proto_misc_init(Proto* proto, int a2); From 3d5cb4c3f435fdac4048d2d7f504b7582edf8354 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 22 Jul 2023 15:07:39 +0300 Subject: [PATCH 11/62] Add proto_scenery_init --- src/proto.cc | 24 ++++++++++++++++++++++++ src/proto.h | 1 + 2 files changed, 25 insertions(+) diff --git a/src/proto.cc b/src/proto.cc index 597af60..312aa05 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -828,6 +828,30 @@ int _proto_dude_init(const char* path) return 0; } +// 0x49FBBC +int proto_scenery_init(Proto* proto, int a2) +{ + int v1 = a2 & 0xFFFFFF; + + proto->scenery.pid = -1; + proto->scenery.messageId = 100 * v1; + proto->scenery.fid = buildFid(OBJ_TYPE_SCENERY, v1 - 1, 0, 0, 0); + if (!artExists(proto->scenery.fid)) { + proto->scenery.fid = buildFid(OBJ_TYPE_SCENERY, 0, 0, 0, 0); + } + proto->scenery.lightDistance = 0; + proto->scenery.lightIntensity = 0; + proto->scenery.flags = 0; + proto->scenery.extendedFlags = 0x2000; + proto->scenery.sid = -1; + proto->scenery.type = SCENERY_TYPE_GENERIC; + proto_scenery_subdata_init(proto, proto->scenery.type); + proto->scenery.field_2C = -1; + proto->scenery.field_34 = '0'; + + return 0; +} + // 0x49FC74 int proto_scenery_subdata_init(Proto* proto, int type) { diff --git a/src/proto.h b/src/proto.h index 982af88..4b09e3b 100644 --- a/src/proto.h +++ b/src/proto.h @@ -118,6 +118,7 @@ int objectDataWrite(Object* obj, File* stream); int _proto_update_init(Object* obj); int _proto_dude_update_gender(); int _proto_dude_init(const char* path); +int proto_scenery_init(Proto* proto, int a2); int proto_scenery_subdata_init(Proto* proto, int type); int proto_wall_init(Proto* proto, int a2); int proto_tile_init(Proto* proto, int a2); From fd9fa802046a3e658073bdadb08e6f060b597716 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 22 Jul 2023 15:22:05 +0300 Subject: [PATCH 12/62] Add proto_item_subdata_init --- src/proto.cc | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/proto.h | 1 + 2 files changed, 84 insertions(+) diff --git a/src/proto.cc b/src/proto.cc index 312aa05..2771b1a 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -370,6 +370,89 @@ char* protoGetDescription(int pid) return protoGetMessage(pid, PROTOTYPE_MESSAGE_DESCRIPTION); } +// 0x49EBFC +int proto_item_subdata_init(Proto* proto, int type) +{ + int index; + + switch (type) { + case ITEM_TYPE_ARMOR: + proto->item.data.armor.armorClass = 0; + + for (index = 0; index < DAMAGE_TYPE_COUNT; index++) { + proto->item.data.armor.damageResistance[index] = 0; + proto->item.data.armor.damageThreshold[index] = 0; + } + + proto->item.data.armor.perk = -1; + proto->item.data.armor.maleFid = -1; + proto->item.data.armor.femaleFid = -1; + break; + case ITEM_TYPE_CONTAINER: + proto->item.data.container.openFlags = 0; + proto->item.data.container.maxSize = 250; + proto->item.extendedFlags |= 0x800; + break; + case ITEM_TYPE_DRUG: + proto->item.data.drug.stat[0] = STAT_STRENGTH; + proto->item.data.drug.stat[1] = -1; + proto->item.data.drug.stat[2] = -1; + proto->item.data.drug.amount[0] = 0; + proto->item.data.drug.amount[1] = 0; + proto->item.data.drug.amount[2] = 0; + proto->item.data.drug.duration1 = 0; + proto->item.data.drug.amount1[0] = 0; + proto->item.data.drug.amount1[1] = 0; + proto->item.data.drug.amount1[2] = 0; + proto->item.data.drug.duration2 = 0; + proto->item.data.drug.amount2[0] = 0; + proto->item.data.drug.amount2[1] = 0; + proto->item.data.drug.amount2[2] = 0; + proto->item.data.drug.addictionChance = 0; + proto->item.data.drug.withdrawalEffect = 0; + proto->item.data.drug.withdrawalOnset = 0; + proto->item.extendedFlags |= 0x1000; + break; + case ITEM_TYPE_WEAPON: + proto->item.data.weapon.animationCode = 0; + proto->item.data.weapon.minDamage = 0; + proto->item.data.weapon.maxDamage = 0; + proto->item.data.weapon.damageType = 0; + proto->item.data.weapon.maxRange1 = 0; + proto->item.data.weapon.maxRange2 = 0; + proto->item.data.weapon.projectilePid = -1; + proto->item.data.weapon.minStrength = 0; + proto->item.data.weapon.actionPointCost1 = 0; + proto->item.data.weapon.actionPointCost2 = 0; + proto->item.data.weapon.criticalFailureType = 0; + proto->item.data.weapon.perk = -1; + proto->item.data.weapon.rounds = 0; + proto->item.data.weapon.caliber = 0; + proto->item.data.weapon.ammoTypePid = -1; + proto->item.data.weapon.ammoCapacity = 0; + proto->item.data.weapon.soundCode = 0; + break; + case ITEM_TYPE_AMMO: + proto->item.data.ammo.caliber = 0; + proto->item.data.ammo.quantity = 20; + proto->item.data.ammo.armorClassModifier = 0; + proto->item.data.ammo.damageResistanceModifier = 0; + proto->item.data.ammo.damageMultiplier = 1; + proto->item.data.ammo.damageDivisor = 1; + break; + case ITEM_TYPE_MISC: + proto->item.data.misc.powerTypePid = -1; + proto->item.data.misc.powerType = 20; + break; + case ITEM_TYPE_KEY: + proto->item.data.key.keyCode = -1; + proto->item.extendedFlags |= 0x1000; + break; + } + + return 0; +} + // 0x49EDB4 static int _proto_critter_init(Proto* a1, int a2) { diff --git a/src/proto.h b/src/proto.h index 4b09e3b..e96e8f6 100644 --- a/src/proto.h +++ b/src/proto.h @@ -112,6 +112,7 @@ int _proto_action_can_pickup(int pid); char* protoGetMessage(int pid, int message); char* protoGetName(int pid); char* protoGetDescription(int pid); +int proto_item_subdata_init(Proto* proto, int type); void objectDataReset(Object* obj); int objectDataRead(Object* obj, File* stream); int objectDataWrite(Object* obj, File* stream); From 3c7248af5fda7d6ec405f5bc025e0180cc4d3afc Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 22 Jul 2023 15:34:32 +0300 Subject: [PATCH 13/62] Add proto_item_init --- src/proto.cc | 28 ++++++++++++++++++++++++++++ src/proto.h | 1 + 2 files changed, 29 insertions(+) diff --git a/src/proto.cc b/src/proto.cc index 2771b1a..007c580 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -370,6 +370,34 @@ char* protoGetDescription(int pid) return protoGetMessage(pid, PROTOTYPE_MESSAGE_DESCRIPTION); } +// 0x49EB2C +int proto_item_init(Proto* proto, int a2) +{ + int v1 = a2 & 0xFFFFFF; + + proto->item.pid = -1; + proto->item.messageId = 100 * v1; + proto->item.fid = buildFid(OBJ_TYPE_ITEM, v1 - 1, 0, 0, 0); + if (!artExists(proto->item.fid)) { + proto->item.fid = buildFid(OBJ_TYPE_ITEM, 0, 0, 0, 0); + } + proto->item.lightDistance = 0; + proto->item.lightIntensity = 0; + proto->item.flags = 0xA0000008; + proto->item.extendedFlags = 0xA000; + proto->item.sid = -1; + proto->item.type = ITEM_TYPE_MISC; + proto_item_subdata_init(proto, proto->item.type); + proto->item.material = 1; + proto->item.size = 1; + proto->item.weight = 10; + proto->item.cost = 0; + proto->item.inventoryFid = -1; + proto->item.field_80 = '0'; + + return 0; +} + // 0x49EBFC int proto_item_subdata_init(Proto* proto, int type) { diff --git a/src/proto.h b/src/proto.h index e96e8f6..a9a6126 100644 --- a/src/proto.h +++ b/src/proto.h @@ -112,6 +112,7 @@ int _proto_action_can_pickup(int pid); char* protoGetMessage(int pid, int message); char* protoGetName(int pid); char* protoGetDescription(int pid); +int proto_item_init(Proto* proto, int a2); int proto_item_subdata_init(Proto* proto, int type); void objectDataReset(Object* obj); int objectDataRead(Object* obj, File* stream); From d6c3d74b3f854345e01fec1ed79cdc584d6d43d7 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 22 Jul 2023 15:36:51 +0300 Subject: [PATCH 14/62] Clarify proto_make_path address --- src/proto.cc | 12 ++++++------ src/proto.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/proto.cc b/src/proto.cc index 007c580..234cf5b 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -187,8 +187,8 @@ static char** _perk_code_strs; // 0x6648BC static char** _critter_stats_list; -// NOTE: Inlined. -void _proto_make_path(char* path, int pid) +// 0x49E270 +void proto_make_path(char* path, int pid) { strcpy(path, _cd_path_base); strcat(path, _proto_path_base); @@ -211,7 +211,7 @@ int _proto_list_str(int pid, char* proto_path) } char path[COMPAT_MAX_PATH]; - _proto_make_path(path, pid); + proto_make_path(path, pid); strcat(path, "\\"); strcat(path, artGetObjectTypeName(PID_TYPE(pid))); strcat(path, ".lst"); @@ -1521,7 +1521,7 @@ static int _proto_header_load() ptr->max_entries_num = 1; char path[COMPAT_MAX_PATH]; - _proto_make_path(path, index << 24); + proto_make_path(path, index << 24); strcat(path, "\\"); strcat(path, artGetObjectTypeName(index)); strcat(path, ".lst"); @@ -1931,7 +1931,7 @@ int _proto_save_pid(int pid) } char path[260]; - _proto_make_path(path, pid); + proto_make_path(path, pid); strcat(path, "\\"); _proto_list_str(pid, path + strlen(path)); @@ -1952,7 +1952,7 @@ int _proto_save_pid(int pid) static int _proto_load_pid(int pid, Proto** protoPtr) { char path[COMPAT_MAX_PATH]; - _proto_make_path(path, pid); + proto_make_path(path, pid); strcat(path, "\\"); if (_proto_list_str(pid, path + strlen(path)) == -1) { diff --git a/src/proto.h b/src/proto.h index a9a6126..61c7575 100644 --- a/src/proto.h +++ b/src/proto.h @@ -102,7 +102,7 @@ extern char _cd_path_base[COMPAT_MAX_PATH]; extern MessageList gProtoMessageList; extern char* _proto_none_str; -void _proto_make_path(char* path, int pid); +void proto_make_path(char* path, int pid); int _proto_list_str(int pid, char* proto_path); size_t proto_size(int type); bool _proto_action_can_use(int pid); From c72d8778bac317635b791b8695ee53480ad4b29b Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 22 Jul 2023 16:53:01 +0300 Subject: [PATCH 15/62] Add proto_new --- src/proto.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ src/proto.h | 1 + 2 files changed, 43 insertions(+) diff --git a/src/proto.cc b/src/proto.cc index 234cf5b..7bc7004 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -2031,6 +2031,48 @@ static int _proto_find_free_subnode(int type, Proto** protoPtr) return 0; } +// 0x4A1E90 +int proto_new(int* pid, int type) +{ + Proto* proto; + + if (_proto_find_free_subnode(type, &proto) == -1) { + return -1; + } + + *pid = _proto_new_id(type) | (type << 24); + switch (type) { + case OBJ_TYPE_ITEM: + proto_item_init(proto, *pid); + proto->item.pid = *pid; + break; + case OBJ_TYPE_CRITTER: + _proto_critter_init(proto, *pid); + proto->critter.pid = *pid; + break; + case OBJ_TYPE_SCENERY: + proto_scenery_init(proto, *pid); + proto->scenery.pid = *pid; + break; + case OBJ_TYPE_WALL: + proto_wall_init(proto, *pid); + proto->wall.pid = *pid; + break; + case OBJ_TYPE_TILE: + proto_tile_init(proto, *pid); + proto->tile.pid = *pid; + break; + case OBJ_TYPE_MISC: + proto_misc_init(proto, *pid); + proto->misc.pid = *pid; + break; + default: + return -1; + } + + return 0; +} + // Evict top most proto cache block. // // 0x4A2040 diff --git a/src/proto.h b/src/proto.h index 61c7575..99c9d7e 100644 --- a/src/proto.h +++ b/src/proto.h @@ -132,6 +132,7 @@ int protoInit(); void protoReset(); void protoExit(); int _proto_save_pid(int pid); +int proto_new(int* pid, int type); void _proto_remove_all(); int protoGetProto(int pid, Proto** out_proto); int _ResetPlayer(); From cbb9cbc6fd2f2cfddf737c2f8ddc12bf58d615bd Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 22 Jul 2023 17:00:24 +0300 Subject: [PATCH 16/62] Clarify some proto params --- src/proto.cc | 87 ++++++++++++++++++++++++++-------------------------- src/proto.h | 13 ++++---- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/proto.cc b/src/proto.cc index 7bc7004..001217f 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -24,7 +24,6 @@ namespace fallout { -static int _proto_critter_init(Proto* a1, int a2); static int objectCritterCombatDataRead(CritterCombatData* data, File* stream); static int objectCritterCombatDataWrite(CritterCombatData* data, File* stream); static int _proto_update_gen(Object* obj); @@ -39,8 +38,8 @@ static int _proto_load_pid(int pid, Proto** out_proto); static int _proto_find_free_subnode(int type, Proto** out_ptr); static void _proto_remove_some_list(int type); static void _proto_remove_list(int type); -static int _proto_new_id(int a1); -static int _proto_max_id(int a1); +static int _proto_new_id(int type); +static int _proto_max_id(int type); // 0x50CF3C static char _aProto_0[] = "proto\\"; @@ -482,31 +481,31 @@ int proto_item_subdata_init(Proto* proto, int type) } // 0x49EDB4 -static int _proto_critter_init(Proto* a1, int a2) +int proto_critter_init(Proto* proto, int pid) { if (!_protos_been_initialized) { return -1; } - int v1 = a2 & 0xFFFFFF; + int num = pid & 0xFFFFFF; - a1->pid = -1; - a1->messageId = 100 * v1; - a1->fid = buildFid(OBJ_TYPE_CRITTER, v1 - 1, 0, 0, 0); - a1->critter.lightDistance = 0; - a1->critter.lightIntensity = 0; - a1->critter.flags = 0x20000000; - a1->critter.extendedFlags = 0x6000; - a1->critter.sid = -1; - a1->critter.data.flags = 0; - a1->critter.data.bodyType = 0; - a1->critter.headFid = -1; - a1->critter.aiPacket = 1; - if (!artExists(a1->fid)) { - a1->fid = buildFid(OBJ_TYPE_CRITTER, 0, 0, 0, 0); + proto->pid = -1; + proto->messageId = 100 * num; + proto->fid = buildFid(OBJ_TYPE_CRITTER, num - 1, 0, 0, 0); + proto->critter.lightDistance = 0; + proto->critter.lightIntensity = 0; + proto->critter.flags = 0x20000000; + proto->critter.extendedFlags = 0x6000; + proto->critter.sid = -1; + proto->critter.data.flags = 0; + proto->critter.data.bodyType = 0; + proto->critter.headFid = -1; + proto->critter.aiPacket = 1; + if (!artExists(proto->fid)) { + proto->fid = buildFid(OBJ_TYPE_CRITTER, 0, 0, 0, 0); } - CritterProtoData* data = &(a1->critter.data); + CritterProtoData* data = &(proto->critter.data); data->experience = 60; data->killType = 0; data->damageType = 0; @@ -940,13 +939,13 @@ int _proto_dude_init(const char* path) } // 0x49FBBC -int proto_scenery_init(Proto* proto, int a2) +int proto_scenery_init(Proto* proto, int pid) { - int v1 = a2 & 0xFFFFFF; + int num = pid & 0xFFFFFF; proto->scenery.pid = -1; - proto->scenery.messageId = 100 * v1; - proto->scenery.fid = buildFid(OBJ_TYPE_SCENERY, v1 - 1, 0, 0, 0); + proto->scenery.messageId = 100 * num; + proto->scenery.fid = buildFid(OBJ_TYPE_SCENERY, num - 1, 0, 0, 0); if (!artExists(proto->scenery.fid)) { proto->scenery.fid = buildFid(OBJ_TYPE_SCENERY, 0, 0, 0, 0); } @@ -995,13 +994,13 @@ int proto_scenery_subdata_init(Proto* proto, int type) } // 0x49FCFC -int proto_wall_init(Proto* proto, int a2) +int proto_wall_init(Proto* proto, int pid) { - int v1 = a2 & 0xFFFFFF; + int num = pid & 0xFFFFFF; proto->wall.pid = -1; - proto->wall.messageId = 100 * v1; - proto->wall.fid = buildFid(OBJ_TYPE_WALL, v1 - 1, 0, 0, 0); + proto->wall.messageId = 100 * num; + proto->wall.fid = buildFid(OBJ_TYPE_WALL, num - 1, 0, 0, 0); if (!artExists(proto->wall.fid)) { proto->wall.fid = buildFid(OBJ_TYPE_WALL, 0, 0, 0, 0); } @@ -1016,13 +1015,13 @@ int proto_wall_init(Proto* proto, int a2) } // 0x49FD84 -int proto_tile_init(Proto* proto, int a2) +int proto_tile_init(Proto* proto, int pid) { - int v1 = a2 & 0xFFFFFF; + int num = pid & 0xFFFFFF; proto->tile.pid = -1; - proto->tile.messageId = 100 * v1; - proto->tile.fid = buildFid(OBJ_TYPE_TILE, v1 - 1, 0, 0, 0); + proto->tile.messageId = 100 * num; + proto->tile.fid = buildFid(OBJ_TYPE_TILE, num - 1, 0, 0, 0); if (!artExists(proto->tile.fid)) { proto->tile.fid = buildFid(OBJ_TYPE_TILE, 0, 0, 0, 0); } @@ -1035,13 +1034,13 @@ int proto_tile_init(Proto* proto, int a2) } // 0x49FDFC -int proto_misc_init(Proto* proto, int a2) +int proto_misc_init(Proto* proto, int pid) { - int v1 = a2 & 0xFFFFFF; + int num = pid & 0xFFFFFF; proto->misc.pid = -1; - proto->misc.messageId = 100 * v1; - proto->misc.fid = buildFid(OBJ_TYPE_MISC, v1 - 1, 0, 0, 0); + proto->misc.messageId = 100 * num; + proto->misc.fid = buildFid(OBJ_TYPE_MISC, num - 1, 0, 0, 0); if (!artExists(proto->misc.fid)) { proto->misc.fid = buildFid(OBJ_TYPE_MISC, 0, 0, 0, 0); } @@ -1353,7 +1352,7 @@ int protoInit() compat_mkdir(path); // TODO: Get rid of cast. - _proto_critter_init((Proto*)&gDudeProto, 0x1000000); + proto_critter_init((Proto*)&gDudeProto, 0x1000000); gDudeProto.pid = 0x1000000; gDudeProto.fid = buildFid(OBJ_TYPE_CRITTER, 1, 0, 0, 0); @@ -1472,7 +1471,7 @@ void protoReset() int i; // TODO: Get rid of cast. - _proto_critter_init((Proto*)&gDudeProto, 0x1000000); + proto_critter_init((Proto*)&gDudeProto, 0x1000000); gDudeProto.pid = 0x1000000; gDudeProto.fid = buildFid(OBJ_TYPE_CRITTER, 1, 0, 0, 0); @@ -2047,7 +2046,7 @@ int proto_new(int* pid, int type) proto->item.pid = *pid; break; case OBJ_TYPE_CRITTER: - _proto_critter_init(proto, *pid); + proto_critter_init(proto, *pid); proto->critter.pid = *pid; break; case OBJ_TYPE_SCENERY: @@ -2162,18 +2161,18 @@ int protoGetProto(int pid, Proto** protoPtr) } // 0x4A21DC -static int _proto_new_id(int a1) +static int _proto_new_id(int type) { - int result = _protoLists[a1].max_entries_num; - _protoLists[a1].max_entries_num = result + 1; + int result = _protoLists[type].max_entries_num; + _protoLists[type].max_entries_num = result + 1; return result; } // 0x4A2214 -static int _proto_max_id(int a1) +static int _proto_max_id(int type) { - return _protoLists[a1].max_entries_num; + return _protoLists[type].max_entries_num; } // 0x4A22C0 diff --git a/src/proto.h b/src/proto.h index 99c9d7e..f00eef9 100644 --- a/src/proto.h +++ b/src/proto.h @@ -112,19 +112,20 @@ int _proto_action_can_pickup(int pid); char* protoGetMessage(int pid, int message); char* protoGetName(int pid); char* protoGetDescription(int pid); -int proto_item_init(Proto* proto, int a2); +int proto_item_init(Proto* proto, int pid); int proto_item_subdata_init(Proto* proto, int type); +int proto_critter_init(Proto* proto, int pid); void objectDataReset(Object* obj); int objectDataRead(Object* obj, File* stream); int objectDataWrite(Object* obj, File* stream); int _proto_update_init(Object* obj); int _proto_dude_update_gender(); int _proto_dude_init(const char* path); -int proto_scenery_init(Proto* proto, int a2); +int proto_scenery_init(Proto* proto, int pid); int proto_scenery_subdata_init(Proto* proto, int type); -int proto_wall_init(Proto* proto, int a2); -int proto_tile_init(Proto* proto, int a2); -int proto_misc_init(Proto* proto, int a2); +int proto_wall_init(Proto* proto, int pid); +int proto_tile_init(Proto* proto, int pid); +int proto_misc_init(Proto* proto, int pid); int proto_copy_proto(int srcPid, int dstPid); bool proto_is_subtype(Proto* proto, int subtype); int protoGetDataMember(int pid, int member, ProtoDataMemberValue* value); @@ -134,7 +135,7 @@ void protoExit(); int _proto_save_pid(int pid); int proto_new(int* pid, int type); void _proto_remove_all(); -int protoGetProto(int pid, Proto** out_proto); +int protoGetProto(int pid, Proto** protoPtr); int _ResetPlayer(); static bool isExitGridPid(int pid) From 4b65bdf0217d22dd0f5309d7b72ca0fb2c2c3267 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 22 Jul 2023 17:09:19 +0300 Subject: [PATCH 17/62] Add scripts_request_townmap --- src/scripts.cc | 14 ++++++++++++-- src/scripts.h | 3 ++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/scripts.cc b/src/scripts.cc index ddcf5c6..58dab5d 100644 --- a/src/scripts.cc +++ b/src/scripts.cc @@ -913,8 +913,8 @@ int scriptsHandleRequests() } } - if ((gScriptsRequests & SCRIPT_REQUEST_0x02) != 0) { - gScriptsRequests &= ~SCRIPT_REQUEST_0x02; + if ((gScriptsRequests & SCRIPT_REQUEST_TOWN_MAP) != 0) { + gScriptsRequests &= ~SCRIPT_REQUEST_TOWN_MAP; wmTownMap(); } @@ -1128,6 +1128,16 @@ void _scripts_request_combat_locked(STRUCT_664980* a1) gScriptsRequests |= (SCRIPT_REQUEST_0x0400 | SCRIPT_REQUEST_COMBAT); } +// 0x4A461C +void scripts_request_townmap() +{ + if (isInCombat()) { + _game_user_wants_to_quit = 1; + } + + gScriptsRequests |= SCRIPT_REQUEST_TOWN_MAP; +} + // request_world_map() // 0x4A4644 void scriptsRequestWorldMap() diff --git a/src/scripts.h b/src/scripts.h index e061fd0..5cc3220 100644 --- a/src/scripts.h +++ b/src/scripts.h @@ -25,7 +25,7 @@ namespace fallout { typedef enum ScriptRequests { SCRIPT_REQUEST_COMBAT = 0x01, - SCRIPT_REQUEST_0x02 = 0x02, + SCRIPT_REQUEST_TOWN_MAP = 0x02, SCRIPT_REQUEST_WORLD_MAP = 0x04, SCRIPT_REQUEST_ELEVATOR = 0x08, SCRIPT_REQUEST_EXPLOSION = 0x10, @@ -175,6 +175,7 @@ int scriptsHandleRequests(); int _scripts_check_state_in_combat(); int scriptsRequestCombat(STRUCT_664980* a1); void _scripts_request_combat_locked(STRUCT_664980* ptr); +void scripts_request_townmap(); void scriptsRequestWorldMap(); int scriptsRequestElevator(Object* a1, int a2); int scriptsRequestExplosion(int tile, int elevation, int minDamage, int maxDamage); From 28d1d410d5117145027c5203d0dcd46a61dac4ba Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 06:08:23 +0300 Subject: [PATCH 18/62] Add get_num_i --- src/window_manager_private.cc | 111 ++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/src/window_manager_private.cc b/src/window_manager_private.cc index beef020..26d5c8f 100644 --- a/src/window_manager_private.cc +++ b/src/window_manager_private.cc @@ -20,6 +20,7 @@ namespace fallout { /// Maximum number of timed messages. static constexpr int kTimedMsgs = 5; +static int get_num_i(int win, int* value, int max_chars_wcursor, bool clear, bool allow_negative, int x, int y); static void tm_watch_msgs(); static void tm_kill_msg(); static void tm_kill_out_of_order(int queueIndex); @@ -1500,6 +1501,116 @@ size_t _calc_max_field_chars_wcursor(int value1, int value2) return std::max(len1, len2) + 1; } +// 0x4DD0AC +int get_num_i(int win, int* value, int max_chars_wcursor, bool clear, bool allow_negative, int x, int y) +{ + bool first_press = false; + + Window* window = windowGetWindow(win); + if (window == NULL) { + return -1; + } + + int original = *value; + + int width = max_chars_wcursor * fontGetMonospacedCharacterWidth(); + int height = fontGetLineHeight(); + + char* string = (char*)internal_malloc(max_chars_wcursor + 1); + + if (clear) { + string[0] = '\0'; + } else { + snprintf(string, + max_chars_wcursor + 1, + "%d", + *value); + } + + int cursorPos = strlen(string); + string[cursorPos] = '_'; + string[cursorPos + 1] = '\0'; + + windowDrawText(win, string, width, x, y, 0x100 | 4); + + Rect rect; + rect.left = x; + rect.top = y; + rect.right = x + width; + rect.bottom = y + height; + windowRefreshRect(win, &rect); + + bool done = false; + while (cursorPos <= max_chars_wcursor && !done) { + sharedFpsLimiter.mark(); + + int input = inputGetInput(); + if (input == KEY_RETURN) { + done = true; + } else if (input == KEY_BACKSPACE) { + if (cursorPos > 0) { + int stringWidth = fontGetStringWidth(string); + if (first_press) { + string[0] = '_'; + string[1] = '\0'; + cursorPos = 1; + first_press = false; + } else { + string[cursorPos - 1] = '_'; + string[cursorPos] = '\0'; + cursorPos--; + } + + windowFill(win, x, y, stringWidth, height, 0x100 | 1); + windowDrawText(win, string, width, x, y, 0x100 | 4); + windowRefreshRect(win, &rect); + } + } else if (input == KEY_ESCAPE) { + *value = original; + internal_free(string); + + return -1; + } else if (input == KEY_ARROW_LEFT) { + if (cursorPos > 0) { + int stringWidth = fontGetStringWidth(string); + string[cursorPos - 1] = '_'; + string[cursorPos] = '\0'; + windowFill(win, x, y, stringWidth, height, 0x100 | 1); + windowDrawText(win, string, width, x, y, 0x100 | 4); + windowRefreshRect(win, &rect); + + first_press = false; + cursorPos--; + } + } else { + if (cursorPos != max_chars_wcursor - 1) { + if ((input == '-' && allow_negative) + || (input >= '0' && input <= '9')) { + string[cursorPos] = input; + string[cursorPos + 1] = '_'; + string[cursorPos + 2] = '\0'; + + int stringWidth = fontGetStringWidth(string); + windowFill(win, x, y, stringWidth, height, 0x100 | 1); + windowDrawText(win, string, width, x, y, 0x100 | 4); + windowRefreshRect(win, &rect); + + first_press = false; + cursorPos++; + } + } + } + + renderPresent(); + sharedFpsLimiter.throttle(); + } + + *value = atoi(string); + internal_free(string); + + return 0; +} + // 0x4DD3EC void _GNW_intr_init() { From 127de143189a6d5732089f6c825a7f411832c9fd Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 07:20:56 +0300 Subject: [PATCH 19/62] Add win_get_num_i --- src/window_manager_private.cc | 107 ++++++++++++++++++++++++++++++++++ src/window_manager_private.h | 1 + 2 files changed, 108 insertions(+) diff --git a/src/window_manager_private.cc b/src/window_manager_private.cc index 26d5c8f..9c5f04e 100644 --- a/src/window_manager_private.cc +++ b/src/window_manager_private.cc @@ -1216,6 +1216,113 @@ int _win_input_str(int win, char* dest, int maxLength, int x, int y, int textCol return 0; } +// 0x4DCD68 +int win_get_num_i(int* value, int min, int max, bool clear, const char* title, int x, int y) +{ + if (!gWindowSystemInitialized) { + return -1; + } + + if (max < min) { + return -1; + } + + if (*value < min) { + *value = min; + } else if (*value > max) { + *value = max; + } + + int original = *value; + int max_chars_wcursor = _calc_max_field_chars_wcursor(min, max); + if (max_chars_wcursor == -1) { + return -1; + } + + int v2 = fontGetMonospacedCharacterWidth() * max_chars_wcursor; + + int width = fontGetStringWidth(title); + if (width < v2) { + width = v2; + } + + width += 16; + if (width < 160) { + width = 160; + } + + int height = 5 * fontGetLineHeight() + 16; + int v3 = (width - v2) / 2; + int v4 = fontGetLineHeight(); + int v5 = fontGetLineHeight() + 2; + + int win = windowCreate(x, y, width, height, 0x100, WINDOW_MODAL | WINDOW_MOVE_ON_TOP); + if (win == -1) { + return -1; + } + + windowDrawBorder(win); + windowFill(win, v3, v4 + 14, v2, v5, 0x100 | 1); + windowDrawText(win, title, width - 16, 8, 8, 0x100 | 5); + + bufferDrawRectShadowed(windowGetBuffer(win), + width, + v3 - 2, + v4 + 12, + v3 + v2 + 1, + v4 + 14 + v5 - 1, + _colorTable[_GNW_wcolor[2]], + _colorTable[_GNW_wcolor[1]]); + + _win_register_text_button(win, + width / 2 - 72, + height - fontGetLineHeight() - 14, + -1, + -1, + -1, + KEY_RETURN, + "Done", + 0); + + _win_register_text_button(win, + width / 2 + 16, + height - fontGetLineHeight() - 14, + -1, + -1, + -1, + KEY_ESCAPE, + "Cancel", + 0); + + char* hint = (char*)internal_malloc(80); + if (hint == NULL) { + return -1; + } + + sprintf(hint, "Please enter a number between %d and %d.", min, max); + windowRefresh(win); + + int rc; + while (1) { + rc = get_num_i(win, value, max_chars_wcursor, clear, min < 0, v3, v4 + 14); + if (*value >= min && *value <= max) { + break; + } + + if (rc == -1) { + break; + } + + _win_msg(hint, x - 70, y + 100, 0x100 | 6); + *value = original; + } + + internal_free(hint); + windowDestroy(win); + + return rc; +} + // 0x4DBD04 int process_pull_down(int win, Rect* rect, char** items, int itemsLength, int foregroundColor, int backgroundColor, MenuBar* menuBar, int pulldownIndex) { diff --git a/src/window_manager_private.h b/src/window_manager_private.h index c4e00e4..cfdecc7 100644 --- a/src/window_manager_private.h +++ b/src/window_manager_private.h @@ -30,6 +30,7 @@ int _win_width_needed(char** fileNameList, int fileNameListLength); int _win_input_str(int win, char* dest, int maxLength, int x, int y, int textColor, int backgroundColor); int process_pull_down(int win, Rect* rect, char** items, int itemsLength, int a5, int a6, MenuBar* menuBar, int pulldownIndex); int _GNW_process_menu(MenuBar* menuBar, int pulldownIndex); +int win_get_num_i(int* value, int min, int max, bool clear, const char* title, int x, int y); size_t _calc_max_field_chars_wcursor(int value1, int value2); void _GNW_intr_init(); void _GNW_intr_exit(); From 78ae0fb3bf1d2acfb7e90e7b3d0f57ebac41466a Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 09:25:56 +0300 Subject: [PATCH 20/62] Add mapper_mark_all_exit_grids --- src/mapper/mapper.cc | 30 ++++++++++++++++++++++++++++++ src/mapper/mapper.h | 12 ++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/mapper/mapper.cc create mode 100644 src/mapper/mapper.h diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc new file mode 100644 index 0000000..a3885e9 --- /dev/null +++ b/src/mapper/mapper.cc @@ -0,0 +1,30 @@ +#include "mapper/mapper.h" + +#include "object.h" +#include "proto.h" + +namespace fallout { + +static void mapper_mark_all_exit_grids(); + +// 0x559748 +MapTransition mapInfo = { -1, -1, 0, 0 }; + +// 0x48C704 +void mapper_mark_all_exit_grids() +{ + Object* obj; + + obj = objectFindFirstAtElevation(gElevation); + while (obj != NULL) { + if (isExitGridPid(obj->pid)) { + obj->data.misc.map = mapInfo.map; + obj->data.misc.tile = mapInfo.tile; + obj->data.misc.elevation = mapInfo.elevation; + obj->data.misc.rotation = mapInfo.rotation; + } + obj = objectFindNextAtElevation(); + } +} + +} // namespace fallout diff --git a/src/mapper/mapper.h b/src/mapper/mapper.h new file mode 100644 index 0000000..3d6adb3 --- /dev/null +++ b/src/mapper/mapper.h @@ -0,0 +1,12 @@ +#ifndef FALLOUT_MAPPER_MAPPER_H_ +#define FALLOUT_MAPPER_MAPPER_H_ + +#include "map.h" + +namespace fallout { + +extern MapTransition mapInfo; + +} // namespace fallout + +#endif /* FALLOUT_MAPPER_MAPPER_H_ */ From e68c2a4784c80e389f05a809c1bd83cd1fc9fe58 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 09:39:13 +0300 Subject: [PATCH 21/62] Add mapper_mark_exit_grid --- src/mapper/mapper.cc | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index a3885e9..da5072b 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -1,15 +1,45 @@ #include "mapper/mapper.h" +#include "game_mouse.h" #include "object.h" #include "proto.h" namespace fallout { +static int mapper_mark_exit_grid(); static void mapper_mark_all_exit_grids(); // 0x559748 MapTransition mapInfo = { -1, -1, 0, 0 }; +// 0x48C678 +int mapper_mark_exit_grid() +{ + int y; + int x; + int tile; + Object* obj; + + for (y = -2000; y != 2000; y += 200) { + for (x = -10; x < 10; x++) { + tile = gGameMouseBouncingCursor->tile + y + x; + + obj = objectFindFirstAtElevation(gElevation); + while (obj != NULL) { + if (isExitGridPid(obj->pid)) { + obj->data.misc.map = mapInfo.map; + obj->data.misc.tile = mapInfo.tile; + obj->data.misc.elevation = mapInfo.elevation; + obj->data.misc.rotation = mapInfo.rotation; + } + obj = objectFindNextAtElevation(); + } + } + } + + return 0; +} + // 0x48C704 void mapper_mark_all_exit_grids() { From 1366b050b081cffd506605927da4a066c77e696e Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 09:44:09 +0300 Subject: [PATCH 22/62] Add mapper_inven_unwield --- src/mapper/mapper.cc | 29 +++++++++++++++++++++++++++++ src/mapper/mapper.h | 3 +++ 2 files changed, 32 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index da5072b..77b9551 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -1,6 +1,9 @@ #include "mapper/mapper.h" +#include "animation.h" +#include "art.h" #include "game_mouse.h" +#include "inventory.h" #include "object.h" #include "proto.h" @@ -12,6 +15,32 @@ static void mapper_mark_all_exit_grids(); // 0x559748 MapTransition mapInfo = { -1, -1, 0, 0 }; +// 0x48C604 +int mapper_inven_unwield(Object* obj, int right_hand) +{ + Object* item; + int fid; + + reg_anim_begin(ANIMATION_REQUEST_RESERVED); + + if (right_hand) { + item = critterGetItem2(obj); + } else { + item = critterGetItem1(obj); + } + + if (item != NULL) { + item->flags &= ~OBJECT_IN_ANY_HAND; + } + + animationRegisterAnimate(obj, ANIM_PUT_AWAY, 0); + + fid = buildFid(OBJ_TYPE_CRITTER, obj->fid & 0xFFF, 0, 0, (obj->fid & 0x70000000) >> 28); + animationRegisterSetFid(obj, fid, 0); + + return reg_anim_end(); +} + // 0x48C678 int mapper_mark_exit_grid() { diff --git a/src/mapper/mapper.h b/src/mapper/mapper.h index 3d6adb3..f69546b 100644 --- a/src/mapper/mapper.h +++ b/src/mapper/mapper.h @@ -2,11 +2,14 @@ #define FALLOUT_MAPPER_MAPPER_H_ #include "map.h" +#include "obj_types.h" namespace fallout { extern MapTransition mapInfo; +int mapper_inven_unwield(Object* obj, int right_hand); + } // namespace fallout #endif /* FALLOUT_MAPPER_MAPPER_H_ */ From 480094a3ebe154642beea08df940121129a0ec8f Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 09:49:22 +0300 Subject: [PATCH 23/62] Add redraw_toolname --- src/mapper/mapper.cc | 18 ++++++++++++++++++ src/mapper/mapper.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index 77b9551..22b775c 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -6,15 +6,33 @@ #include "inventory.h" #include "object.h" #include "proto.h" +#include "svga.h" +#include "window_manager.h" namespace fallout { +static void redraw_toolname(); static int mapper_mark_exit_grid(); static void mapper_mark_all_exit_grids(); // 0x559748 MapTransition mapInfo = { -1, -1, 0, 0 }; +// 0x6EC4AC +int tool_win; + +// 0x48B230 +void redraw_toolname() +{ + Rect rect; + + rect.left = _scr_size.right - _scr_size.left - 149; + rect.top = 60; + rect.right = _scr_size.right - _scr_size.left + 1; + rect.bottom = 95; + windowRefreshRect(tool_win, &rect); +} + // 0x48C604 int mapper_inven_unwield(Object* obj, int right_hand) { diff --git a/src/mapper/mapper.h b/src/mapper/mapper.h index f69546b..c85597b 100644 --- a/src/mapper/mapper.h +++ b/src/mapper/mapper.h @@ -8,6 +8,8 @@ namespace fallout { extern MapTransition mapInfo; +extern int tool_win; + int mapper_inven_unwield(Object* obj, int right_hand); } // namespace fallout From 9faa427a286c16e3da3c4cb80ecd04e0f76a743c Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 09:52:59 +0300 Subject: [PATCH 24/62] Add clear_toolname --- src/mapper/mapper.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index 22b775c..a555404 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -12,6 +12,7 @@ namespace fallout { static void redraw_toolname(); +static void clear_toolname(); static int mapper_mark_exit_grid(); static void mapper_mark_all_exit_grids(); @@ -33,6 +34,15 @@ void redraw_toolname() windowRefreshRect(tool_win, &rect); } +// 0x48B278 +void clear_toolname() +{ + windowDrawText(tool_win, "", 120, _scr_size.right - _scr_size.left - 149, 60, 260); + windowDrawText(tool_win, "", 120, _scr_size.right - _scr_size.left - 149, 70, 260); + windowDrawText(tool_win, "", 120, _scr_size.right - _scr_size.left - 149, 80, 260); + redraw_toolname(); +} + // 0x48C604 int mapper_inven_unwield(Object* obj, int right_hand) { From 8cc48cf52a94e9b8c29fc6ae9f2f6e9d94be57d2 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 09:55:58 +0300 Subject: [PATCH 25/62] Add update_high_obj_name --- src/mapper/mapper.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index a555404..81d7ac7 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -13,6 +13,7 @@ namespace fallout { static void redraw_toolname(); static void clear_toolname(); +static void update_high_obj_name(Object* obj); static int mapper_mark_exit_grid(); static void mapper_mark_all_exit_grids(); @@ -43,6 +44,19 @@ void clear_toolname() redraw_toolname(); } +// 0x48B5BC +void update_high_obj_name(Object* obj) +{ + Proto* proto; + + if (protoGetProto(obj->pid, &proto) != -1) { + windowDrawText(tool_win, protoGetName(obj->pid), 120, _scr_size.right - _scr_size.left - 149, 60, 260); + windowDrawText(tool_win, "", 120, _scr_size.right - _scr_size.left - 149, 70, 260); + windowDrawText(tool_win, "", 120, _scr_size.right - _scr_size.left - 149, 80, 260); + redraw_toolname(); + } +} + // 0x48C604 int mapper_inven_unwield(Object* obj, int right_hand) { From c652312157b834d4c689eefbc43e338be0cc60f2 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 10:01:58 +0300 Subject: [PATCH 26/62] Add print_toolbar_name --- src/mapper/mapper.cc | 29 +++++++++++++++++++++++++++++ src/mapper/mapper.h | 2 ++ 2 files changed, 31 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index 81d7ac7..b74fbef 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -1,7 +1,11 @@ #include "mapper/mapper.h" +#include + #include "animation.h" #include "art.h" +#include "color.h" +#include "draw.h" #include "game_mouse.h" #include "inventory.h" #include "object.h" @@ -20,9 +24,34 @@ static void mapper_mark_all_exit_grids(); // 0x559748 MapTransition mapInfo = { -1, -1, 0, 0 }; +// 0x6EC4A8 +unsigned char* tool; + // 0x6EC4AC int tool_win; +// 0x48B16C +void print_toolbar_name(int object_type) +{ + Rect rect; + char name[80]; + + rect.left = 0; + rect.top = 0; + rect.right = 0; + rect.bottom = 22; + bufferFill(tool + 2 + 2 * (_scr_size.right - _scr_size.left) + 2, + 96, + _scr_size.right - _scr_size.left + 1, + 19, + _colorTable[21140]); + + sprintf(name, "%s", artGetObjectTypeName(object_type)); + name[0] = toupper(name[0]); + windowDrawText(tool_win, name, 0, 7, 7, _colorTable[32747] | 0x2000000); + windowRefreshRect(tool_win, &rect); +} + // 0x48B230 void redraw_toolname() { diff --git a/src/mapper/mapper.h b/src/mapper/mapper.h index c85597b..cc106d0 100644 --- a/src/mapper/mapper.h +++ b/src/mapper/mapper.h @@ -8,8 +8,10 @@ namespace fallout { extern MapTransition mapInfo; +extern unsigned char* tool; extern int tool_win; +void print_toolbar_name(int object_type); int mapper_inven_unwield(Object* obj, int right_hand); } // namespace fallout From 4eaea0e3c096d2126946dc26e2d1d2ce1b2041a8 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 10:10:09 +0300 Subject: [PATCH 27/62] Add proto_user_is_librarian --- src/mapper/mapper.cc | 14 ++++++++++++++ src/mapper/mp_proto.cc | 8 ++++++++ src/mapper/mp_proto.h | 10 ++++++++++ 3 files changed, 32 insertions(+) create mode 100644 src/mapper/mp_proto.cc create mode 100644 src/mapper/mp_proto.h diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index b74fbef..e5f20b6 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -8,13 +8,16 @@ #include "draw.h" #include "game_mouse.h" #include "inventory.h" +#include "mapper/mp_proto.h" #include "object.h" #include "proto.h" +#include "settings.h" #include "svga.h" #include "window_manager.h" namespace fallout { +static bool proto_user_is_librarian(); static void redraw_toolname(); static void clear_toolname(); static void update_high_obj_name(Object* obj); @@ -30,6 +33,17 @@ unsigned char* tool; // 0x6EC4AC int tool_win; +// 0x487784 +bool proto_user_is_librarian() +{ + if (!settings.mapper.librarian) { + return false; + } + + can_modify_protos = true; + return true; +} + // 0x48B16C void print_toolbar_name(int object_type) { diff --git a/src/mapper/mp_proto.cc b/src/mapper/mp_proto.cc new file mode 100644 index 0000000..3e89993 --- /dev/null +++ b/src/mapper/mp_proto.cc @@ -0,0 +1,8 @@ +#include "mapper/mp_proto.h" + +namespace fallout { + +// 0x559C60 +bool can_modify_protos = false; + +} // namespace fallout diff --git a/src/mapper/mp_proto.h b/src/mapper/mp_proto.h new file mode 100644 index 0000000..2bf6e8d --- /dev/null +++ b/src/mapper/mp_proto.h @@ -0,0 +1,10 @@ +#ifndef FALLOUT_MAPPER_MP_PROTO_H_ +#define FALLOUT_MAPPER_MP_PROTO_H_ + +namespace fallout { + +extern bool can_modify_protos; + +} // namespace fallout + +#endif /* FALLOUT_MAPPER_MP_PROTO_H_ */ From 9f08c73b3ce3ae99dd4375e25a59433c10b81d56 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 10:15:51 +0300 Subject: [PATCH 28/62] Add categoryUnhide --- src/mapper/mapper.cc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index e5f20b6..38cfa5e 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -17,6 +17,7 @@ namespace fallout { +static int categoryUnhide(); static bool proto_user_is_librarian(); static void redraw_toolname(); static void clear_toolname(); @@ -27,12 +28,31 @@ static void mapper_mark_all_exit_grids(); // 0x559748 MapTransition mapInfo = { -1, -1, 0, 0 }; +// 0x5598AC +static int categoryWin = -1; + +// 0x5598B0 +static bool categoryIsHidden = false; + // 0x6EC4A8 unsigned char* tool; // 0x6EC4AC int tool_win; +// 0x487774 +int categoryUnhide() +{ + if (categoryWin == -1) { + return -1; + } + + windowShow(categoryWin); + categoryIsHidden = false; + + return 0; +} + // 0x487784 bool proto_user_is_librarian() { From f933bff8ae615bf242f15f3f60badb6ca29fb583 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 10:16:59 +0300 Subject: [PATCH 29/62] Add categoryHide --- src/mapper/mapper.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index 38cfa5e..4b3aea2 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -17,6 +17,7 @@ namespace fallout { +static int categoryHide(); static int categoryUnhide(); static bool proto_user_is_librarian(); static void redraw_toolname(); @@ -40,6 +41,19 @@ unsigned char* tool; // 0x6EC4AC int tool_win; +// 0x487728 +int categoryHide() +{ + if (categoryWin == -1) { + return -1; + } + + windowHide(categoryWin); + categoryIsHidden = true; + + return 0; +} + // 0x487774 int categoryUnhide() { From b1049fceb1f61aa4cff4f6d772e376ddd5fffe39 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 10:17:52 +0300 Subject: [PATCH 30/62] Add categoryToggleState --- src/mapper/mapper.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index 4b3aea2..65af3cf 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -18,6 +18,7 @@ namespace fallout { static int categoryHide(); +static int categoryToggleState(); static int categoryUnhide(); static bool proto_user_is_librarian(); static void redraw_toolname(); @@ -54,6 +55,16 @@ int categoryHide() return 0; } +// 0x487768 +int categoryToggleState() +{ + if (categoryIsHidden) { + return categoryUnhide(); + } else { + return categoryHide(); + } +} + // 0x487774 int categoryUnhide() { From 661c68902959a4909b088f92ff77f5b30fd8bd1d Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 10:19:02 +0300 Subject: [PATCH 31/62] Add categoryExit --- src/mapper/mapper.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index 65af3cf..a33d59a 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -17,6 +17,7 @@ namespace fallout { +static int categoryExit(); static int categoryHide(); static int categoryToggleState(); static int categoryUnhide(); @@ -42,6 +43,19 @@ unsigned char* tool; // 0x6EC4AC int tool_win; +// 0x487700 +int categoryExit() +{ + if (categoryWin == -1) { + return -1; + } + + windowDestroy(categoryWin); + categoryWin = -1; + + return 0; +} + // 0x487728 int categoryHide() { From 3331ad02b0d0a45fbea84d060e7d069afd503961 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 10:20:54 +0300 Subject: [PATCH 32/62] Add categoryInit --- src/mapper/mapper.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index a33d59a..58c5ac7 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -17,6 +17,7 @@ namespace fallout { +static int categoryInit(); static int categoryExit(); static int categoryHide(); static int categoryToggleState(); @@ -43,6 +44,12 @@ unsigned char* tool; // 0x6EC4AC int tool_win; +// 0x4875B4 +int categoryInit() +{ + return 0; +} + // 0x487700 int categoryExit() { From 093d4f23d84b91e441c1308f89a4e1f035544688 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 10:22:42 +0300 Subject: [PATCH 33/62] Add bookmarkUnHide --- src/mapper/mapper.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index 58c5ac7..24d3fe3 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -17,6 +17,7 @@ namespace fallout { +static void bookmarkUnHide(); static int categoryInit(); static int categoryExit(); static int categoryHide(); @@ -32,6 +33,9 @@ static void mapper_mark_all_exit_grids(); // 0x559748 MapTransition mapInfo = { -1, -1, 0, 0 }; +// 0x5598A8 +static int bookmarkWin = -1; + // 0x5598AC static int categoryWin = -1; @@ -44,6 +48,14 @@ unsigned char* tool; // 0x6EC4AC int tool_win; +// 0x4875F8 +void bookmarkUnHide() +{ + if (bookmarkWin != -1) { + windowShow(bookmarkWin); + } +} + // 0x4875B4 int categoryInit() { From a2d61dc7c4213d3535c3dd3f6602baf0ba458db9 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 10:23:55 +0300 Subject: [PATCH 34/62] Add bookmarkHide --- src/mapper/mapper.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index 24d3fe3..97c9b42 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -17,6 +17,7 @@ namespace fallout { +static void bookmarkHide(); static void bookmarkUnHide(); static int categoryInit(); static int categoryExit(); @@ -48,6 +49,14 @@ unsigned char* tool; // 0x6EC4AC int tool_win; +// 0x4875E0 +void bookmarkHide() +{ + if (bookmarkWin != -1) { + windowHide(bookmarkWin); + } +} + // 0x4875F8 void bookmarkUnHide() { From a27b2496d469f4b146a38b2ef0fe617afdd9e171 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 10:25:58 +0300 Subject: [PATCH 35/62] Add bookmarkExit --- src/mapper/mapper.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index 97c9b42..df8e57e 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -17,6 +17,7 @@ namespace fallout { +static int bookmarkExit(); static void bookmarkHide(); static void bookmarkUnHide(); static int categoryInit(); @@ -49,6 +50,19 @@ unsigned char* tool; // 0x6EC4AC int tool_win; +// 0x4875B8 +int bookmarkExit() +{ + if (bookmarkWin == -1) { + return -1; + } + + windowDestroy(bookmarkWin); + bookmarkWin = -1; + + return 0; +} + // 0x4875E0 void bookmarkHide() { From d16f0010ac345da2fcc1f1cf422a88b0c65bad26 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 10:26:43 +0300 Subject: [PATCH 36/62] Add bookmarkInit --- src/mapper/mapper.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index df8e57e..b0c55d5 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -17,6 +17,7 @@ namespace fallout { +static int bookmarkInit(); static int bookmarkExit(); static void bookmarkHide(); static void bookmarkUnHide(); @@ -50,6 +51,12 @@ unsigned char* tool; // 0x6EC4AC int tool_win; +// 0x4875B4 +int bookmarkInit() +{ + return 0; +} + // 0x4875B8 int bookmarkExit() { From 7327588fc3ebad3731d576bdc50f7bc04f2af305 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 10:35:16 +0300 Subject: [PATCH 37/62] Add MapperInit --- src/mapper/mapper.cc | 55 ++++++++++++++++++++++++++++++++++++++++++++ src/mapper/mapper.h | 3 +++ 2 files changed, 58 insertions(+) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index b0c55d5..e419825 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -8,6 +8,7 @@ #include "draw.h" #include "game_mouse.h" #include "inventory.h" +#include "kb.h" #include "mapper/mp_proto.h" #include "object.h" #include "proto.h" @@ -17,6 +18,7 @@ namespace fallout { +static void MapperInit(); static int bookmarkInit(); static int bookmarkExit(); static void bookmarkHide(); @@ -45,12 +47,65 @@ static int categoryWin = -1; // 0x5598B0 static bool categoryIsHidden = false; +// 0x6EAA40 +int menu_val_0[8]; + +// 0x6EAA60 +int menu_val_2[8]; + +// 0x6EC408 +int menu_val_1[21]; + // 0x6EC4A8 unsigned char* tool; // 0x6EC4AC int tool_win; +// 0x485E00 +void MapperInit() +{ + menu_val_0[0] = KEY_ALT_N; + menu_val_0[1] = KEY_ALT_O; + menu_val_0[2] = KEY_ALT_S; + menu_val_0[3] = KEY_ALT_A; + menu_val_0[4] = KEY_ESCAPE; + menu_val_0[5] = KEY_ALT_K; + menu_val_0[6] = KEY_ALT_I; + menu_val_0[7] = KEY_ESCAPE; + + menu_val_1[0] = KEY_ALT_U; + menu_val_1[1] = KEY_ALT_Y; + menu_val_1[2] = KEY_ESCAPE; + menu_val_1[3] = KEY_ALT_G; + menu_val_1[4] = 4186; + menu_val_1[5] = 4188; + menu_val_1[6] = KEY_ESCAPE; + menu_val_1[7] = KEY_ALT_B; + menu_val_1[8] = KEY_ALT_E; + menu_val_1[9] = KEY_ALT_D; + menu_val_1[10] = KEY_LOWERCASE_B; + menu_val_1[11] = 2165; + menu_val_1[12] = 3123; + menu_val_1[13] = KEY_ALT_Z; + menu_val_1[14] = 5677; + menu_val_1[15] = 5678; + menu_val_1[16] = 5679; + menu_val_1[17] = 5666; + menu_val_1[18] = KEY_ESCAPE; + menu_val_1[19] = 5406; + menu_val_1[20] = 5405; + + menu_val_2[0] = KEY_LOWERCASE_I; + menu_val_2[1] = 5400; + menu_val_2[2] = KEY_LOWERCASE_S; + menu_val_2[3] = KEY_CTRL_F8; + menu_val_2[4] = 5410; + menu_val_2[5] = KEY_GRAVE; + menu_val_2[6] = KEY_ALT_W; + menu_val_2[7] = 5544; +} + // 0x4875B4 int bookmarkInit() { diff --git a/src/mapper/mapper.h b/src/mapper/mapper.h index cc106d0..3eb594c 100644 --- a/src/mapper/mapper.h +++ b/src/mapper/mapper.h @@ -8,6 +8,9 @@ namespace fallout { extern MapTransition mapInfo; +extern int menu_val_0[8]; +extern int menu_val_2[8]; +extern int menu_val_1[21]; extern unsigned char* tool; extern int tool_win; From cdfd308193f08211d0259861e454412f13d42ee2 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 11:01:03 +0300 Subject: [PATCH 38/62] Add mapper_main --- src/mapper/mapper.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ src/mapper/mapper.h | 1 + src/memory.cc | 5 +---- src/memory.h | 1 + 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index e419825..c1cc87b 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -10,6 +10,7 @@ #include "inventory.h" #include "kb.h" #include "mapper/mp_proto.h" +#include "memory.h" #include "object.h" #include "proto.h" #include "settings.h" @@ -19,6 +20,8 @@ namespace fallout { static void MapperInit(); +static int mapper_edit_init(int argc, char** argv); +static void mapper_edit_exit(); static int bookmarkInit(); static int bookmarkExit(); static void bookmarkHide(); @@ -29,6 +32,7 @@ static int categoryHide(); static int categoryToggleState(); static int categoryUnhide(); static bool proto_user_is_librarian(); +static void edit_mapper(); static void redraw_toolname(); static void clear_toolname(); static void update_high_obj_name(Object* obj); @@ -62,6 +66,24 @@ unsigned char* tool; // 0x6EC4AC int tool_win; +// gnw_main +// 0x485DD0 +int mapper_main(int argc, char** argv) +{ + MapperInit(); + + if (mapper_edit_init(argc, argv) == -1) { + mem_check(); + return 0; + } + + edit_mapper(); + mapper_edit_exit(); + mem_check(); + + return 0; +} + // 0x485E00 void MapperInit() { @@ -106,6 +128,20 @@ void MapperInit() menu_val_2[7] = 5544; } +// 0x485F94 +int mapper_edit_init(int argc, char** argv) +{ + // TODO: Incomplete. + + return 0; +} + +// 0x48752C +void mapper_edit_exit() +{ + // TODO: Incomplete. +} + // 0x4875B4 int bookmarkInit() { @@ -207,6 +243,12 @@ bool proto_user_is_librarian() return true; } +// 0x4877D0 +void edit_mapper() +{ + // TODO: Incomplete. +} + // 0x48B16C void print_toolbar_name(int object_type) { diff --git a/src/mapper/mapper.h b/src/mapper/mapper.h index 3eb594c..4ae73cf 100644 --- a/src/mapper/mapper.h +++ b/src/mapper/mapper.h @@ -14,6 +14,7 @@ extern int menu_val_1[21]; extern unsigned char* tool; extern int tool_win; +int mapper_main(int argc, char** argv); void print_toolbar_name(int object_type); int mapper_inven_unwield(Object* obj, int right_hand); diff --git a/src/memory.cc b/src/memory.cc index 5f15047..c51ff39 100644 --- a/src/memory.cc +++ b/src/memory.cc @@ -32,7 +32,6 @@ typedef struct MemoryBlockFooter { static void* memoryBlockMallocImpl(size_t size); static void* memoryBlockReallocImpl(void* ptr, size_t size); static void memoryBlockFreeImpl(void* ptr); -static void memoryBlockPrintStats(); static void* mem_prep_block(void* block, size_t size); static void memoryBlockValidate(void* block); @@ -176,10 +175,8 @@ static void memoryBlockFreeImpl(void* ptr) } } -// NOTE: Not used. -// // 0x4C5C5C -static void memoryBlockPrintStats() +void mem_check() { if (gMallocProc == memoryBlockMallocImpl) { debugPrint("Current memory allocated: %6d blocks, %9u bytes total\n", gMemoryBlocksCurrentCount, gMemoryBlocksCurrentSize); diff --git a/src/memory.h b/src/memory.h index facaa54..96b0364 100644 --- a/src/memory.h +++ b/src/memory.h @@ -9,6 +9,7 @@ char* internal_strdup(const char* string); void* internal_malloc(size_t size); void* internal_realloc(void* ptr, size_t size); void internal_free(void* ptr); +void mem_check(); } // namespace fallout From 4b51b2f29bafbc4518d63b6f65cea5caec138d62 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 14:15:20 +0300 Subject: [PATCH 39/62] Add tile_toggle_roof --- src/tile.cc | 11 +++++++++++ src/tile.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/tile.cc b/src/tile.cc index af68a39..4bee912 100644 --- a/src/tile.cc +++ b/src/tile.cc @@ -654,6 +654,17 @@ static void tileRefreshGame(Rect* rect, int elevation) gTileWindowRefreshProc(&rectToUpdate); } +// 0x4B1634 +void tile_toggle_roof(bool refresh) +{ + gTileRoofIsVisible = !gTileRoofIsVisible; + + if (refresh) { + // NOTE: Uninline. + tileWindowRefresh(); + } +} + // 0x4B166C int tileRoofIsVisible() { diff --git a/src/tile.h b/src/tile.h index ae227d2..97acc8f 100644 --- a/src/tile.h +++ b/src/tile.h @@ -26,6 +26,7 @@ void tileEnable(); void tileWindowRefreshRect(Rect* rect, int elevation); void tileWindowRefresh(); int tileSetCenter(int tile, int flags); +void tile_toggle_roof(bool refresh); int tileRoofIsVisible(); int tileToScreenXY(int tile, int* x, int* y, int elevation); int tileFromScreenXY(int x, int y, int elevation, bool ignoreBounds = false); From 053e70dde4eb027d204c01bfc6f1424f259d1105 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 23 Jul 2023 14:27:52 +0300 Subject: [PATCH 40/62] Add gmouse_set_mapper_mode --- src/game_mouse.cc | 6 ++++++ src/game_mouse.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/game_mouse.cc b/src/game_mouse.cc index 9f82fcd..fca7c79 100644 --- a/src/game_mouse.cc +++ b/src/game_mouse.cc @@ -1328,6 +1328,12 @@ int gameMouseGetCursor() return gGameMouseCursor; } +// 0x44C9F0 +void gmouse_set_mapper_mode(int mode) +{ + _gmouse_mapper_mode = mode; +} + // 0x44C9F8 void _gmouse_3d_enable_modes() { diff --git a/src/game_mouse.h b/src/game_mouse.h index fc65633..2b99efe 100644 --- a/src/game_mouse.h +++ b/src/game_mouse.h @@ -86,6 +86,7 @@ void gameMouseRefresh(); void _gmouse_handle_event(int mouseX, int mouseY, int mouseState); int gameMouseSetCursor(int cursor); int gameMouseGetCursor(); +void gmouse_set_mapper_mode(int mode); void gameMouseSetMode(int a1); int gameMouseGetMode(); void gameMouseCycleMode(); From 4cd40b33afc0fd0e7e4af85a8dd5729d5ea67a19 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 06:50:07 +0300 Subject: [PATCH 41/62] Add mapper_edit_init --- src/graph_lib.cc | 8 + src/graph_lib.h | 1 + src/mapper/map_func.cc | 11 + src/mapper/map_func.h | 10 + src/mapper/mapper.cc | 1088 +++++++++++++++++++++++++++++++++++++++- src/mapper/mp_proto.cc | 6 + src/mapper/mp_proto.h | 2 + src/mapper/mp_targt.cc | 19 + src/mapper/mp_targt.h | 11 + src/mapper/mp_text.cc | 13 + src/mapper/mp_text.h | 10 + 11 files changed, 1178 insertions(+), 1 deletion(-) create mode 100644 src/mapper/map_func.cc create mode 100644 src/mapper/map_func.h create mode 100644 src/mapper/mp_targt.cc create mode 100644 src/mapper/mp_targt.h create mode 100644 src/mapper/mp_text.cc create mode 100644 src/mapper/mp_text.h diff --git a/src/graph_lib.cc b/src/graph_lib.cc index 08a65dd..6a432bd 100644 --- a/src/graph_lib.cc +++ b/src/graph_lib.cc @@ -52,6 +52,14 @@ unsigned char HighRGB(unsigned char color) return std::max(std::max(r, g), b); } +// 0x44ED98 +int load_lbm_to_buf(const char* path, unsigned char* buffer, int a3, int a4, int a5, int a6, int a7) +{ + // TODO: Incomplete. + + return -1; +} + // 0x44F250 int graphCompress(unsigned char* a1, unsigned char* a2, int a3) { diff --git a/src/graph_lib.h b/src/graph_lib.h index 4364973..8278c6a 100644 --- a/src/graph_lib.h +++ b/src/graph_lib.h @@ -4,6 +4,7 @@ namespace fallout { unsigned char HighRGB(unsigned char color); +int load_lbm_to_buf(const char* path, unsigned char* buffer, int a3, int a4, int a5, int a6, int a7); int graphCompress(unsigned char* a1, unsigned char* a2, int a3); int graphDecompress(unsigned char* a1, unsigned char* a2, int a3); void grayscalePaletteUpdate(int a1, int a2); diff --git a/src/mapper/map_func.cc b/src/mapper/map_func.cc new file mode 100644 index 0000000..9d96f2e --- /dev/null +++ b/src/mapper/map_func.cc @@ -0,0 +1,11 @@ +#include "mapper/map_func.h" + +namespace fallout { + +// 0x4825B0 +void setup_map_dirs() +{ + // TODO: Incomplete. +} + +} // namespace fallout diff --git a/src/mapper/map_func.h b/src/mapper/map_func.h new file mode 100644 index 0000000..fb71b2b --- /dev/null +++ b/src/mapper/map_func.h @@ -0,0 +1,10 @@ +#ifndef FALLOUT_MAPPER_MAP_FUNC_H_ +#define FALLOUT_MAPPER_MAP_FUNC_H_ + +namespace fallout { + +void setup_map_dirs(); + +} // namespace fallout + +#endif /* FALLOUT_MAPPER_MAP_FUNC_H_ */ diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index c1cc87b..786b5a5 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -5,17 +5,26 @@ #include "animation.h" #include "art.h" #include "color.h" +#include "debug.h" #include "draw.h" +#include "game.h" #include "game_mouse.h" +#include "graph_lib.h" #include "inventory.h" #include "kb.h" +#include "mapper/map_func.h" #include "mapper/mp_proto.h" +#include "mapper/mp_targt.h" +#include "mapper/mp_text.h" #include "memory.h" +#include "mouse.h" #include "object.h" #include "proto.h" #include "settings.h" #include "svga.h" +#include "tile.h" #include "window_manager.h" +#include "window_manager_private.h" namespace fallout { @@ -33,15 +42,141 @@ static int categoryToggleState(); static int categoryUnhide(); static bool proto_user_is_librarian(); static void edit_mapper(); +static void mapper_load_toolbar(int a1, int a2); static void redraw_toolname(); static void clear_toolname(); static void update_high_obj_name(Object* obj); static int mapper_mark_exit_grid(); static void mapper_mark_all_exit_grids(); +// TODO: Underlying menu/pulldown interface wants menu items to be non-const, +// needs some refactoring. + +static char kSeparator[] = ""; + +static char kNew[] = " New "; +static char kOpen[] = " Open "; +static char kSave[] = " Save "; +static char kSaveAs[] = " Save As... "; +static char kInfo[] = " Info "; +static char kOpenFromText[] = " Open From Text "; +static char kQuit[] = " Quit "; + +static char kCreatePattern[] = " Create Pattern "; +static char kUsePattern[] = " Use Pattern "; +static char kMoveMap[] = " Move Map "; +static char kMoveMapElev[] = " Move Map Elev "; +static char kCopyMapElev[] = " Copy Map Elev "; +static char kEditObjDude[] = " Edit Obj_dude "; +static char kFlushCache[] = " Flush Cache "; +static char kToggleAnimStepping[] = " Toggle Anim Stepping "; +static char kFixMapObjectsToPids[] = " Fix map-objects to pids "; +static char kSetBookmark[] = " Set Bookmark "; +static char kToggleBlockObjView[] = " Toggle Block Obj View "; +static char kToggleClickToScroll[] = " Toggle Click-To-Scroll "; +static char kSetExitGridData[] = " Set Exit-Grid Data "; +static char kMarkExitGrids[] = " Mark Exit-Grids "; +static char kMarkAllExitGrids[] = " Mark *ALL* Exit Grids "; +static char kClearMapLevel[] = " *Clear Map Level* "; +static char kCreateAllMapTexts[] = " Create ALL MAP TEXTS "; +static char kRebuildAllMaps[] = " Rebuild ALL MAPS "; + +static char kListAllScripts[] = " List all Scripts "; +static char kSetStartHex[] = " Set Start Hex "; +static char kPlaceSpatialScript[] = " Place Spatial Script "; +static char kDeleteSpatialScript[] = " Delete Spatial Script "; +static char kDeleteAllSpatialScripts[] = " Delete *ALL* Spatial SCRIPTS! "; +static char kCreateScript[] = " Create Script "; +static char kSetMapScript[] = " Set Map Script "; +static char kShowMapScript[] = " Show Map Script "; + +static char kRebuildWeapons[] = " Rebuild Weapons "; +static char kRebuildProtoList[] = " Rebuild Proto List "; +static char kRebuildAll[] = " Rebuild ALL "; +static char kRebuildBinary[] = " Rebuild Binary "; +static char kArtToProtos[] = " Art => New Protos "; +static char kSwapPrototypse[] = " Swap Prototypes "; + +// 0x559648 +char* menu_0[] = { + kNew, + kOpen, + kSave, + kSaveAs, + kSeparator, + kInfo, + kOpenFromText, + kQuit, +}; + +// 0x559668 +char* menu_1[] = { + kCreatePattern, + kUsePattern, + kSeparator, + kMoveMap, + kMoveMapElev, + kCopyMapElev, + kSeparator, + kEditObjDude, + kFlushCache, + kToggleAnimStepping, + kFixMapObjectsToPids, + kSetBookmark, + kToggleBlockObjView, + kToggleClickToScroll, + kSetExitGridData, + kMarkExitGrids, + kMarkAllExitGrids, + kClearMapLevel, + kSeparator, + kCreateAllMapTexts, + kRebuildAllMaps, +}; + +// 0x5596BC +char* menu_2[] = { + kListAllScripts, + kSetStartHex, + kPlaceSpatialScript, + kDeleteSpatialScript, + kDeleteAllSpatialScripts, + kCreateScript, + kSetMapScript, + kShowMapScript, +}; + +// 0x5596DC +char* menu_3[] = { + kRebuildWeapons, + kRebuildProtoList, + kRebuildAll, + kRebuildBinary, + kSeparator, + kArtToProtos, + kSwapPrototypse, +}; + +// 0x5596F8 +char** menu_names[] = { + menu_0, + menu_1, + menu_2, + menu_3, +}; + // 0x559748 MapTransition mapInfo = { -1, -1, 0, 0 }; +// 0x559880 +int max_art_buttons = 7; + +// 0x559884 +int art_scale_width = 49; + +// 0x559888 +int art_scale_height = 48; + // 0x5598A8 static int bookmarkWin = -1; @@ -57,15 +192,234 @@ int menu_val_0[8]; // 0x6EAA60 int menu_val_2[8]; +// 0x6EAA80 +unsigned char e_num[4][19 * 26]; + // 0x6EC408 int menu_val_1[21]; +// 0x6EC468 +unsigned char* art_shape; + +// 0x6EC46C +int to_paint_bid; + +// 0x6EC470 +int edit_bid; + +// 0x6EC474 +int paste_bid; + +// 0x6EC478 +int misc_bid; + +// 0x6EC47C +int tile_bid; + +// 0x6EC480 +int copy_bid; + +// 0x6EC484 +int delete_bid; + +// 0x6EC488 +int wall_bid; + +// 0x6EC48C +int obj_bid; + +// 0x6EC490 +int to_topdown_bid; + +// 0x6EC494 +int roof_bid; + +// 0x6EC498 +int hex_bid; + +// 0x6EC49C +int to_iso_bid; + +// 0x6EC4A0 +int scen_bid; + +// 0x6EC4A4 +int crit_bid; + // 0x6EC4A8 unsigned char* tool; // 0x6EC4AC int tool_win; +// 0x6EC4B0 +int menu_bar; + +// 0x6EC4B4 +unsigned char* lbm_buf; + +// 0x6EC4B8 +unsigned char height_inc_up[18 * 23]; + +// 0x6EC656 +unsigned char height_dec_up[18 * 23]; + +// 0x6EC7F4 +unsigned char height_dec_down[18 * 23]; + +// 0x6EC992 +unsigned char height_inc_down[18 * 23]; + +// 0x6ECB30 +unsigned char obj_down[66 * 13]; + +// 0x6ECE8A +unsigned char to_iso_down[58 * 13]; + +// 0x6ED17C +unsigned char scen_up[66 * 13]; + +// 0x6ED4D6 +unsigned char roof_up[58 * 13]; + +// 0x6ED7C8 +unsigned char crit_down[66 * 13]; + +// 0x6EDB22 +unsigned char obj_up[66 * 13]; + +// 0x6EDE7C +unsigned char crit_up[66 * 13]; + +// 0x6EE1D6 +unsigned char to_topdown_down[58 * 13]; + +// 0x6EE4C8 +unsigned char hex_up[58 * 13]; + +// 0x6EE7BA +unsigned char hex_down[58 * 13]; + +// 0x6EEAAC +unsigned char to_topdown_up[58 * 13]; + +// 0x6EED9E +unsigned char scen_down[66 * 13]; + +// 0x6EF0F8 +unsigned char edec_down[18 * 23]; + +// 0x6EF296 +unsigned char to_iso_up[58 * 13]; + +// 0x6EF588 +unsigned char roof_down[58 * 13]; + +// 0x6EF87A +unsigned char r_up[18 * 23]; + +// 0x6EFA18 +unsigned char einc_down[18 * 23]; + +// 0x6EFBB6 +unsigned char shift_l_up[18 * 23]; + +// 0x6EFD54 +unsigned char edec_up[18 * 23]; + +// 0x6EFEF2 +unsigned char shift_r_up[18 * 23]; + +// 0x6F0090 +unsigned char shift_r_down[18 * 23]; + +// 0x6F022E +unsigned char r_down[18 * 23]; + +// 0x6F03CC +unsigned char einc_up[18 * 23]; + +// 0x6F056A +unsigned char l_down[18 * 23]; + +// 0x6F0708 +unsigned char shift_l_down[18 * 23]; + +// 0x6F08A6 +unsigned char l_up[18 * 23]; + +// 0x6F0A44 +unsigned char to_edit_up[45 * 43]; + +// 0x6F11D3 +unsigned char erase_up[45 * 43]; + +// 0x6F1962 +unsigned char copy_group_up[45 * 43]; + +// 0x6F20F1 +unsigned char to_paint_down[45 * 43]; + +// 0x6F2880 +unsigned char erase_down[45 * 43]; + +// 0x6F300F +unsigned char copy_group_down[45 * 43]; + +// 0x6F379E +unsigned char to_edit_down[45 * 43]; + +// 0x6F3F2D +unsigned char copy_up[49 * 19]; + +// 0x6F42D0 +unsigned char misc_down[53 * 18]; + +// 0x6F4581 +unsigned char wall_down[53 * 18]; + +// 0x6F4832 +unsigned char delete_up[49 * 19]; + +// 0x6F4BD5 +unsigned char edit_up[49 * 19]; + +// 0x6F4F78 +unsigned char tile_up[53 * 18]; + +// 0x6F5229 +unsigned char edit_down[49 * 19]; + +// 0x6F55CC +unsigned char paste_down[49 * 19]; + +// 0x6F596F +unsigned char delete_down[49 * 19]; + +// 0x6F5D12 +unsigned char tile_down[53 * 18]; + +// 0x6F5FC3 +unsigned char copy_down[49 * 19]; + +// 0x6F6366 +unsigned char misc_up[53 * 18]; + +// 0x6F6617 +unsigned char paste_up[49 * 19]; + +// 0x6F69BA +unsigned char to_paint_up[1935]; + +// 0x6F7149 +unsigned char wall_up[53 * 18]; + +// 0x6F73FA +bool draw_mode; + +// 0x6F73FB +bool view_mode; + // gnw_main // 0x485DD0 int mapper_main(int argc, char** argv) @@ -131,7 +485,733 @@ void MapperInit() // 0x485F94 int mapper_edit_init(int argc, char** argv) { - // TODO: Incomplete. + int index; + + if (gameInitWithOptions("FALLOUT Mapper", true, 2, 0, argc, argv) == -1) { + return -1; + } + + tileEnable(); + gmouse_set_mapper_mode(true); + settings.system.executable = "mapper"; + + if (settings.mapper.override_librarian) { + can_modify_protos = true; + target_override_protection(); + } + + setup_map_dirs(); + mapper_load_toolbar(4, 0); + + max_art_buttons = (_scr_size.right - _scr_size.left - 136) / 50; + art_shape = (unsigned char*)internal_malloc(art_scale_height * art_scale_width); + if (art_shape == NULL) { + printf("Can't malloc memory!!\n"); + exit(1); + } + + menu_bar = windowCreate(0, + 0, + rectGetWidth(&_scr_size), + 16, + _colorTable[0], + WINDOW_HIDDEN); + _win_register_menu_bar(menu_bar, + 0, + 0, + rectGetWidth(&_scr_size), + 16, + 260, + _colorTable[8456]); + _win_register_menu_pulldown(menu_bar, + 8, + "FILE", + 289, + 8, + menu_names[0], + 260, + _colorTable[8456]); + _win_register_menu_pulldown(menu_bar, + 40, + "TOOLS", + 303, + 21, + menu_names[1], + 260, + _colorTable[8456]); + _win_register_menu_pulldown(menu_bar, + 80, + "SCRIPTS", + 276, + 8, + menu_names[2], + 260, + _colorTable[8456]); + + if (can_modify_protos) { + _win_register_menu_pulldown(menu_bar, + 130, + "LIBRARIAN", + 292, + 6, + &(menu_1[14]), + 260, + _colorTable[8456]); + } + + tool_win = windowCreate(0, + _scr_size.bottom - 99, + rectGetWidth(&_scr_size), + 100, + 256, + 0); + tool = windowGetBuffer(tool_win); + + lbm_buf = (unsigned char*)internal_malloc(640 * 480); + load_lbm_to_buf("data\\mapper2.lbm", + lbm_buf, + rectGetWidth(&_scr_size), + 0, + 0, + _scr_size.right - _scr_size.left, + 479); + + // + blitBufferToBuffer(lbm_buf + 380 * rectGetWidth(&_scr_size), + rectGetWidth(&_scr_size), + 100, + rectGetWidth(&_scr_size), + tool, + rectGetWidth(&_scr_size)); + + // + blitBufferToBuffer(lbm_buf + 406 * (rectGetWidth(&_scr_size)) + 101, + 18, + 23, + rectGetWidth(&_scr_size), + l_up, + 18); + blitBufferToBuffer(lbm_buf + 253 * (rectGetWidth(&_scr_size)) + 101, + 18, + 23, + rectGetWidth(&_scr_size), + l_down, + 18); + buttonCreate(tool_win, + 101, + 26, + 18, + 23, + -1, + -1, + 45, + -1, + l_up, + l_down, + NULL, + 0); + + // + blitBufferToBuffer(lbm_buf + 406 * (rectGetWidth(&_scr_size)) + 622, + 18, + 23, + rectGetWidth(&_scr_size), + r_up, + 18); + blitBufferToBuffer(lbm_buf + 253 * (rectGetWidth(&_scr_size)) + 622, + 18, + 23, + rectGetWidth(&_scr_size), + r_down, + 18); + buttonCreate(tool_win, + _scr_size.right - 18, + 1, + 18, + 23, + -1, + -1, + 61, + -1, + r_up, + r_down, + NULL, + 0); + + // + blitBufferToBuffer(lbm_buf + 381 * (rectGetWidth(&_scr_size)) + 101, + 18, + 23, + rectGetWidth(&_scr_size), + shift_l_up, + 18); + blitBufferToBuffer(lbm_buf + 228 * (rectGetWidth(&_scr_size)) + 101, + 18, + 23, + rectGetWidth(&_scr_size), + shift_l_down, + 18); + buttonCreate(tool_win, + 101, + 1, + 18, + 23, + -1, + -1, + 95, + -1, + shift_l_up, + shift_l_down, + NULL, + 0); + + // + blitBufferToBuffer(lbm_buf + 381 * (rectGetWidth(&_scr_size)) + 622, + 18, + 23, + rectGetWidth(&_scr_size), + shift_r_up, + 18); + blitBufferToBuffer(lbm_buf + 228 * (rectGetWidth(&_scr_size)) + 622, + 18, + 23, + rectGetWidth(&_scr_size), + shift_r_down, + 18); + buttonCreate(tool_win, + _scr_size.right - 18, + 1, + 18, + 23, + -1, + -1, + 43, + -1, + shift_r_up, + shift_r_down, + NULL, + 0); + + // + for (index = 0; index < max_art_buttons; index++) { + int btn = buttonCreate(tool_win, + index * (art_scale_width + 1) + 121, + 1, + art_scale_width, + art_scale_height, + index + max_art_buttons + 161, + 58, + 160 + index, + -1, + NULL, + NULL, + NULL, + 0); + buttonSetRightMouseCallbacks(btn, 160 + index, -1, NULL, NULL); + } + + // ELEVATION INC + blitBufferToBuffer(lbm_buf + 431 * (rectGetWidth(&_scr_size)) + 1, + 18, + 23, + rectGetWidth(&_scr_size), + einc_up, + 18); + blitBufferToBuffer(lbm_buf + 325 * (rectGetWidth(&_scr_size)) + 1, + 18, + 23, + rectGetWidth(&_scr_size), + einc_down, + 18); + buttonCreate(tool_win, + 1, + 51, + 18, + 23, + -1, + -1, + 329, + -1, + einc_up, + einc_down, + NULL, + 0); + + // ELEVATION DEC + blitBufferToBuffer(lbm_buf + 456 * (rectGetWidth(&_scr_size)) + 1, + 18, + 23, + rectGetWidth(&_scr_size), + edec_up, + 18); + blitBufferToBuffer(lbm_buf + 350 * (rectGetWidth(&_scr_size)) + 1, + 18, + 23, + rectGetWidth(&_scr_size), + edec_down, + 18); + buttonCreate(tool_win, + 1, + 76, + 18, + 23, + -1, + -1, + 337, + -1, + edec_up, + edec_down, + NULL, + 0); + + // ELEVATION + for (index = 0; index < 4; index++) { + blitBufferToBuffer(lbm_buf + 293 * rectGetWidth(&_scr_size) + 19 * index, + 19, + 26, + rectGetWidth(&_scr_size), + e_num[1], + 19); + } + + view_mode = false; + + // + blitBufferToBuffer(lbm_buf + 169 * (rectGetWidth(&_scr_size)) + 64, + 58, + 13, + rectGetWidth(&_scr_size), + to_iso_up, + 58); + blitBufferToBuffer(lbm_buf + 108 * (rectGetWidth(&_scr_size)) + 64, + 58, + 13, + rectGetWidth(&_scr_size), + to_iso_down, + 58); + + // ROOF + blitBufferToBuffer(lbm_buf + 464 * (rectGetWidth(&_scr_size)) + 64, + 58, + 13, + rectGetWidth(&_scr_size), + roof_up, + 58); + blitBufferToBuffer(lbm_buf + 358 * (rectGetWidth(&_scr_size)) + 64, + 58, + 13, + rectGetWidth(&_scr_size), + roof_down, + 58); + roof_bid = buttonCreate(tool_win, + 64, + 69, + 58, + 13, + -1, + -1, + 'r', + 'r', + roof_up, + roof_down, + NULL, + BUTTON_FLAG_0x01); + + if (tileRoofIsVisible()) { + tile_toggle_roof(false); + } + + // HEX + blitBufferToBuffer(lbm_buf + 464 * (rectGetWidth(&_scr_size)) + 64, + 58, + 13, + rectGetWidth(&_scr_size), + hex_up, + 58); + blitBufferToBuffer(lbm_buf + 358 * (rectGetWidth(&_scr_size)) + 64, + 58, + 13, + rectGetWidth(&_scr_size), + hex_down, + 58); + hex_bid = buttonCreate(tool_win, + 64, + 84, + 58, + 13, + -1, + -1, + 350, + 350, + hex_up, + hex_down, + NULL, + BUTTON_FLAG_0x01); + + // OBJ + blitBufferToBuffer(lbm_buf + 434 * (rectGetWidth(&_scr_size)) + 125, + 66, + 13, + rectGetWidth(&_scr_size), + obj_up, + 66); + blitBufferToBuffer(lbm_buf + 328 * (rectGetWidth(&_scr_size)) + 125, + 66, + 13, + rectGetWidth(&_scr_size), + obj_down, + 66); + obj_bid = buttonCreate(tool_win, + 125, + 54, + 66, + 13, + -1, + -1, + 350, + 350, + obj_up, + obj_down, + NULL, + BUTTON_FLAG_0x01); + + // CRIT + blitBufferToBuffer(lbm_buf + 449 * (rectGetWidth(&_scr_size)) + 125, + 66, + 13, + rectGetWidth(&_scr_size), + crit_up, + 66); + blitBufferToBuffer(lbm_buf + 343 * (rectGetWidth(&_scr_size)) + 125, + 66, + 13, + rectGetWidth(&_scr_size), + crit_down, + 66); + crit_bid = buttonCreate(tool_win, + 125, + 69, + 66, + 13, + -1, + -1, + 351, + 351, + crit_up, + crit_down, + NULL, + BUTTON_FLAG_0x01); + + // SCEN + blitBufferToBuffer(lbm_buf + 434 * (rectGetWidth(&_scr_size)) + 194, + 53, + 13, + rectGetWidth(&_scr_size), + scen_up, + 53); + blitBufferToBuffer(lbm_buf + 328 * (rectGetWidth(&_scr_size)) + 194, + 53, + 13, + rectGetWidth(&_scr_size), + scen_down, + 53); + scen_bid = buttonCreate(tool_win, + 125, + 84, + 66, + 13, + -1, + -1, + 352, + 352, + scen_up, + scen_down, + NULL, + BUTTON_FLAG_0x01); + + // WALL + blitBufferToBuffer(lbm_buf + 434 * (rectGetWidth(&_scr_size)) + 194, + 53, + 13, + rectGetWidth(&_scr_size), + wall_up, + 53); + blitBufferToBuffer(lbm_buf + 328 * (rectGetWidth(&_scr_size)) + 194, + 53, + 13, + rectGetWidth(&_scr_size), + wall_down, + 53); + wall_bid = buttonCreate(tool_win, + 194, + 54, + 53, + 13, + -1, + -1, + 355, + 355, + wall_up, + wall_down, + NULL, + BUTTON_FLAG_0x01); + + // MISC + blitBufferToBuffer(lbm_buf + 464 * (rectGetWidth(&_scr_size)) + 194, + 53, + 13, + rectGetWidth(&_scr_size), + misc_up, + 53); + blitBufferToBuffer(lbm_buf + 358 * (rectGetWidth(&_scr_size)) + 194, + 53, + 13, + rectGetWidth(&_scr_size), + misc_down, + 53); + misc_bid = buttonCreate(tool_win, + 194, + 84, + 53, + 13, + -1, + -1, + 355, + 355, + misc_up, + misc_down, + NULL, + BUTTON_FLAG_0x01); + + // HEIGHT INC + blitBufferToBuffer(lbm_buf + 431 * rectGetWidth(&_scr_size) + 251, + 18, + 23, + rectGetWidth(&_scr_size), + height_inc_up, + 18); + blitBufferToBuffer(lbm_buf + 325 * rectGetWidth(&_scr_size) + 251, + 18, + 23, + rectGetWidth(&_scr_size), + height_inc_down, + 18); + buttonCreate(tool_win, + 251, + 51, + 18, + 23, + -1, + -1, + 371, + -1, + height_dec_up, + height_dec_down, + NULL, + 0); + + // HEIGHT DEC + blitBufferToBuffer(lbm_buf + 456 * rectGetWidth(&_scr_size) + 251, + 18, + 23, + rectGetWidth(&_scr_size), + height_dec_up, + 18); + blitBufferToBuffer(lbm_buf + 350 * rectGetWidth(&_scr_size) + 251, + 18, + 23, + rectGetWidth(&_scr_size), + height_dec_down, + 18); + buttonCreate(tool_win, + 251, + 76, + 18, + 23, + -1, + -1, + 371, + -1, + height_dec_up, + height_dec_down, + NULL, + 0); + + // ARROWS + for (index = 0; index < ROTATION_COUNT; index++) { + } + + // COPY + blitBufferToBuffer(lbm_buf + 435 * (rectGetWidth(&_scr_size)) + 325, + 49, + 19, + rectGetWidth(&_scr_size), + copy_up, + 49); + blitBufferToBuffer(lbm_buf + 329 * (rectGetWidth(&_scr_size)) + 325, + 49, + 19, + rectGetWidth(&_scr_size), + copy_down, + 49); + copy_bid = buttonCreate(tool_win, + 325, + 55, + 49, + 19, + -1, + -1, + 99, + -1, + copy_up, + copy_down, + 0, + 0); + + // PASTE + blitBufferToBuffer(lbm_buf + 457 * (rectGetWidth(&_scr_size)) + 325, + 49, + 19, + rectGetWidth(&_scr_size), + paste_up, + 49); + blitBufferToBuffer(lbm_buf + 351 * (rectGetWidth(&_scr_size)) + 325, + 49, + 19, + rectGetWidth(&_scr_size), + paste_down, + 49); + paste_bid = buttonCreate(tool_win, + 325, + 77, + 49, + 19, + -1, + -1, + 67, + -1, + paste_up, + paste_down, + NULL, + 0); + + // EDIT + blitBufferToBuffer(lbm_buf + 435 * (rectGetWidth(&_scr_size)) + 378, + 49, + 19, + rectGetWidth(&_scr_size), + edit_up, + 49); + blitBufferToBuffer(lbm_buf + 329 * (rectGetWidth(&_scr_size)) + 378, + 49, + 19, + rectGetWidth(&_scr_size), + edit_down, + 49); + edit_bid = buttonCreate(tool_win, + 378, + 55, + 49, + 19, + -1, + -1, + 101, + -1, + edit_up, + edit_down, + NULL, + 0); + + // DELETE + blitBufferToBuffer(lbm_buf + 457 * rectGetWidth(&_scr_size) + 378, + 49, + 19, + rectGetWidth(&_scr_size), + delete_up, + 49); + blitBufferToBuffer(lbm_buf + 351 * rectGetWidth(&_scr_size) + 378, + 49, + 19, + rectGetWidth(&_scr_size), + delete_down, + 49); + delete_bid = buttonCreate(tool_win, + 378, + 77, + 49, + 19, + -1, + -1, + 339, + -1, + delete_up, + delete_down, + NULL, + 0); + + draw_mode = false; + + blitBufferToBuffer(lbm_buf + 169 * rectGetWidth(&_scr_size) + 430, + 45, + 43, + rectGetWidth(&_scr_size), + to_edit_up, + 45); + blitBufferToBuffer(lbm_buf + 108 * rectGetWidth(&_scr_size) + 430, + 45, + 43, + rectGetWidth(&_scr_size), + to_edit_down, + 45); + + blitBufferToBuffer(lbm_buf + 169 * rectGetWidth(&_scr_size) + 327, + 45, + 43, + rectGetWidth(&_scr_size), + copy_group_up, + 45); + blitBufferToBuffer(lbm_buf + 108 * rectGetWidth(&_scr_size) + 327, + 45, + 43, + rectGetWidth(&_scr_size), + copy_group_down, + 45); + + blitBufferToBuffer(lbm_buf + 169 * rectGetWidth(&_scr_size) + 379, + 45, + 43, + rectGetWidth(&_scr_size), + erase_up, + 45); + blitBufferToBuffer(lbm_buf + 108 * rectGetWidth(&_scr_size) + 379, + 45, + 43, + rectGetWidth(&_scr_size), + erase_down, + 45); + + internal_free(lbm_buf); + windowRefresh(tool_win); + + if (bookmarkInit() == -1) { + debugPrint("\nbookmarkInit() Failed!"); + } + + if (categoryInit() == -1) { + debugPrint("\ncategoryInit() Failed!"); + } + + tileScrollBlockingDisable(); + tileScrollLimitingDisable(); + init_mapper_protos(); + _map_init(); + target_init(); + mouseShowCursor(); + + if (settings.mapper.rebuild_protos) { + proto_build_all_texts(); + settings.mapper.rebuild_protos = false; + } return 0; } @@ -249,6 +1329,12 @@ void edit_mapper() // TODO: Incomplete. } +// 0x48AFFC +void mapper_load_toolbar(int a1, int a2) +{ + // TODO: Incomplete. +} + // 0x48B16C void print_toolbar_name(int object_type) { diff --git a/src/mapper/mp_proto.cc b/src/mapper/mp_proto.cc index 3e89993..7678d9c 100644 --- a/src/mapper/mp_proto.cc +++ b/src/mapper/mp_proto.cc @@ -5,4 +5,10 @@ namespace fallout { // 0x559C60 bool can_modify_protos = false; +// 0x4922F8 +void init_mapper_protos() +{ + // TODO: Incomplete. +} + } // namespace fallout diff --git a/src/mapper/mp_proto.h b/src/mapper/mp_proto.h index 2bf6e8d..63cda50 100644 --- a/src/mapper/mp_proto.h +++ b/src/mapper/mp_proto.h @@ -5,6 +5,8 @@ namespace fallout { extern bool can_modify_protos; +void init_mapper_protos(); + } // namespace fallout #endif /* FALLOUT_MAPPER_MP_PROTO_H_ */ diff --git a/src/mapper/mp_targt.cc b/src/mapper/mp_targt.cc new file mode 100644 index 0000000..b9892bd --- /dev/null +++ b/src/mapper/mp_targt.cc @@ -0,0 +1,19 @@ +#include "mapper/mp_targt.h" + +namespace fallout { + +// 0x49B2F0 +void target_override_protection() +{ + // TODO: Incomplete. +} + +// 0x49B424 +int target_init() +{ + // TODO: Incomplete. + + return 0; +} + +} // namespace fallout diff --git a/src/mapper/mp_targt.h b/src/mapper/mp_targt.h new file mode 100644 index 0000000..9e7f071 --- /dev/null +++ b/src/mapper/mp_targt.h @@ -0,0 +1,11 @@ +#ifndef FALLOUT_MAPPER_MP_TARGT_H_ +#define FALLOUT_MAPPER_MP_TARGT_H_ + +namespace fallout { + +void target_override_protection(); +int target_init(); + +} // namespace fallout + +#endif /* FALLOUT_MAPPER_MP_TARGT_H_ */ diff --git a/src/mapper/mp_text.cc b/src/mapper/mp_text.cc new file mode 100644 index 0000000..3d40fb8 --- /dev/null +++ b/src/mapper/mp_text.cc @@ -0,0 +1,13 @@ +#include "mapper/mp_text.h" + +namespace fallout { + +// 0x49DAC4 +int proto_build_all_texts() +{ + // TODO: Incomplete. + + return 0; +} + +} // namespace fallout diff --git a/src/mapper/mp_text.h b/src/mapper/mp_text.h new file mode 100644 index 0000000..b275878 --- /dev/null +++ b/src/mapper/mp_text.h @@ -0,0 +1,10 @@ +#ifndef FALLOUT_MAPPER_MP_TEXT_H_ +#define FALLOUT_MAPPER_MP_TEXT_H_ + +namespace fallout { + +int proto_build_all_texts(); + +} // namespace fallout + +#endif /* FALLOUT_MAPPER_MP_TEXT_H_ */ From f6e9a9d975cfe85fa080b44bf8b464b4039d80f1 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 07:15:58 +0300 Subject: [PATCH 42/62] Make MapDirErase public --- src/loadsave.cc | 35 +++++++++++++++++------------------ src/loadsave.h | 1 + 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/loadsave.cc b/src/loadsave.cc index 90f09c3..a0fa76b 100644 --- a/src/loadsave.cc +++ b/src/loadsave.cc @@ -169,7 +169,6 @@ static int _GameMap2Slot(File* stream); static int _SlotMap2Game(File* stream); static int _mygets(char* dest, File* stream); static int _copy_file(const char* existingFileName, const char* newFileName); -static int _MapDirErase(const char* path, const char* extension); static int _SaveBackup(); static int _RestoreSave(); static int _LoadObjDudeCid(File* stream); @@ -340,9 +339,9 @@ void _InitLoadSave() _slot_cursor = 0; _patches = settings.system.master_patches_path.c_str(); - _MapDirErase("MAPS\\", "SAV"); - _MapDirErase(PROTO_DIR_NAME "\\" CRITTERS_DIR_NAME "\\", PROTO_FILE_EXT); - _MapDirErase(PROTO_DIR_NAME "\\" ITEMS_DIR_NAME "\\", PROTO_FILE_EXT); + MapDirErase("MAPS\\", "SAV"); + MapDirErase(PROTO_DIR_NAME "\\" CRITTERS_DIR_NAME "\\", PROTO_FILE_EXT); + MapDirErase(PROTO_DIR_NAME "\\" ITEMS_DIR_NAME "\\", PROTO_FILE_EXT); configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_AUTO_QUICK_SAVE, &quickSaveSlots); if (quickSaveSlots > 0 && quickSaveSlots <= 10) { @@ -353,9 +352,9 @@ void _InitLoadSave() // 0x47B85C void _ResetLoadSave() { - _MapDirErase("MAPS\\", "SAV"); - _MapDirErase(PROTO_DIR_NAME "\\" CRITTERS_DIR_NAME "\\", PROTO_FILE_EXT); - _MapDirErase(PROTO_DIR_NAME "\\" ITEMS_DIR_NAME "\\", PROTO_FILE_EXT); + MapDirErase("MAPS\\", "SAV"); + MapDirErase(PROTO_DIR_NAME "\\" CRITTERS_DIR_NAME "\\", PROTO_FILE_EXT); + MapDirErase(PROTO_DIR_NAME "\\" ITEMS_DIR_NAME "\\", PROTO_FILE_EXT); } // SaveGame @@ -1570,7 +1569,7 @@ static int lsgPerformSaveGame() debugPrint("\nLOADSAVE: ** Error opening save game for writing! **\n"); _RestoreSave(); snprintf(_gmpath, sizeof(_gmpath), "%s\\%s%.2d\\", "SAVEGAME", "SLOT", _slot_cursor + 1); - _MapDirErase(_gmpath, "BAK"); + MapDirErase(_gmpath, "BAK"); _partyMemberUnPrepSave(); backgroundSoundResume(); return -1; @@ -1583,7 +1582,7 @@ static int lsgPerformSaveGame() fileClose(_flptr); _RestoreSave(); snprintf(_gmpath, sizeof(_gmpath), "%s\\%s%.2d\\", "SAVEGAME", "SLOT", _slot_cursor + 1); - _MapDirErase(_gmpath, "BAK"); + MapDirErase(_gmpath, "BAK"); _partyMemberUnPrepSave(); backgroundSoundResume(); return -1; @@ -1597,7 +1596,7 @@ static int lsgPerformSaveGame() fileClose(_flptr); _RestoreSave(); snprintf(_gmpath, sizeof(_gmpath), "%s\\%s%.2d\\", "SAVEGAME", "SLOT", _slot_cursor + 1); - _MapDirErase(_gmpath, "BAK"); + MapDirErase(_gmpath, "BAK"); _partyMemberUnPrepSave(); backgroundSoundResume(); return -1; @@ -1678,7 +1677,7 @@ static int lsgPerformSaveGame() } snprintf(_gmpath, sizeof(_gmpath), "%s\\%s%.2d\\", "SAVEGAME", "SLOT", _slot_cursor + 1); - _MapDirErase(_gmpath, "BAK"); + MapDirErase(_gmpath, "BAK"); gLoadSaveMessageListItem.num = 140; if (messageListGetItem(&gLoadSaveMessageList, &gLoadSaveMessageListItem)) { @@ -1771,7 +1770,7 @@ static int lsgLoadGameInSlot(int slot) } snprintf(_str, sizeof(_str), "%s\\", "MAPS"); - _MapDirErase(_str, "BAK"); + MapDirErase(_str, "BAK"); _proto_dude_update_gender(); // Game Loaded. @@ -2487,7 +2486,7 @@ static int _GameMap2Slot(File* stream) snprintf(_gmpath, sizeof(_gmpath), "%s\\%s%.2d\\", "SAVEGAME", "SLOT", _slot_cursor + 1); - if (_MapDirErase(_gmpath, "SAV") == -1) { + if (MapDirErase(_gmpath, "SAV") == -1) { fileNameListFree(&fileNameList, 0); return -1; } @@ -2566,19 +2565,19 @@ static int _SlotMap2Game(File* stream) snprintf(_str0, sizeof(_str0), "%s\\", PROTO_DIR_NAME "\\" CRITTERS_DIR_NAME); - if (_MapDirErase(_str0, PROTO_FILE_EXT) == -1) { + if (MapDirErase(_str0, PROTO_FILE_EXT) == -1) { debugPrint("LOADSAVE: returning 3\n"); return -1; } snprintf(_str0, sizeof(_str0), "%s\\", PROTO_DIR_NAME "\\" ITEMS_DIR_NAME); - if (_MapDirErase(_str0, PROTO_FILE_EXT) == -1) { + if (MapDirErase(_str0, PROTO_FILE_EXT) == -1) { debugPrint("LOADSAVE: returning 4\n"); return -1; } snprintf(_str0, sizeof(_str0), "%s\\", "MAPS"); - if (_MapDirErase(_str0, "SAV") == -1) { + if (MapDirErase(_str0, "SAV") == -1) { debugPrint("LOADSAVE: returning 5\n"); return -1; } @@ -2749,11 +2748,11 @@ void lsgInit() { char path[COMPAT_MAX_PATH]; snprintf(path, sizeof(path), "%s\\", "MAPS"); - _MapDirErase(path, "SAV"); + MapDirErase(path, "SAV"); } // 0x480040 -static int _MapDirErase(const char* relativePath, const char* extension) +int MapDirErase(const char* relativePath, const char* extension) { char path[COMPAT_MAX_PATH]; snprintf(path, sizeof(path), "%s*.%s", relativePath, extension); diff --git a/src/loadsave.h b/src/loadsave.h index 32e1263..567548e 100644 --- a/src/loadsave.h +++ b/src/loadsave.h @@ -20,6 +20,7 @@ int lsgSaveGame(int mode); int lsgLoadGame(int mode); bool _isLoadingGame(); void lsgInit(); +int MapDirErase(const char* path, const char* extension); int _MapDirEraseFile_(const char* a1, const char* a2); } // namespace fallout From 57711cae5f61121c71b3e828657c2712a531a7d7 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 07:17:21 +0300 Subject: [PATCH 43/62] Add mapper_edit_exit --- src/mapper/map_func.cc | 6 ++++++ src/mapper/map_func.h | 1 + src/mapper/mapper.cc | 32 +++++++++++++++++++++++++++++++- src/mapper/mp_targt.cc | 8 ++++++++ src/mapper/mp_targt.h | 1 + 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/mapper/map_func.cc b/src/mapper/map_func.cc index 9d96f2e..b9f297d 100644 --- a/src/mapper/map_func.cc +++ b/src/mapper/map_func.cc @@ -8,4 +8,10 @@ void setup_map_dirs() // TODO: Incomplete. } +// 0x4826B4 +void copy_proto_lists() +{ + // TODO: Incomplete. +} + } // namespace fallout diff --git a/src/mapper/map_func.h b/src/mapper/map_func.h index fb71b2b..1292604 100644 --- a/src/mapper/map_func.h +++ b/src/mapper/map_func.h @@ -4,6 +4,7 @@ namespace fallout { void setup_map_dirs(); +void copy_proto_lists(); } // namespace fallout diff --git a/src/mapper/mapper.cc b/src/mapper/mapper.cc index 786b5a5..8afe3eb 100644 --- a/src/mapper/mapper.cc +++ b/src/mapper/mapper.cc @@ -12,6 +12,7 @@ #include "graph_lib.h" #include "inventory.h" #include "kb.h" +#include "loadsave.h" #include "mapper/map_func.h" #include "mapper/mp_proto.h" #include "mapper/mp_targt.h" @@ -97,6 +98,8 @@ static char kRebuildBinary[] = " Rebuild Binary "; static char kArtToProtos[] = " Art => New Protos "; static char kSwapPrototypse[] = " Swap Prototypes "; +static char kTmpMapName[] = "TMP$MAP#.MAP"; + // 0x559648 char* menu_0[] = { kNew, @@ -177,6 +180,9 @@ int art_scale_width = 49; // 0x559888 int art_scale_height = 48; +// 0x5598A4 +static char* tmp_map_name = kTmpMapName; + // 0x5598A8 static int bookmarkWin = -1; @@ -1219,7 +1225,31 @@ int mapper_edit_init(int argc, char** argv) // 0x48752C void mapper_edit_exit() { - // TODO: Incomplete. + remove(tmp_map_name); + remove("\\fallout\\cd\\data\\maps\\TMP$MAP#.MAP"); + remove("\\fallout\\cd\\data\\maps\\TMP$MAP#.CFG"); + + MapDirErase("MAPS\\", "SAV"); + + if (can_modify_protos) { + copy_proto_lists(); + + // NOTE: There is a call to an ambiguous function at `0x4B9ACC`, likely + // `proto_save`. + } + + target_exit(); + _map_exit(); + bookmarkExit(); + categoryExit(); + + windowDestroy(tool_win); + tool = NULL; + + windowDestroy(menu_bar); + + internal_free(art_shape); + gameExit(); } // 0x4875B4 diff --git a/src/mapper/mp_targt.cc b/src/mapper/mp_targt.cc index b9892bd..1bbea4a 100644 --- a/src/mapper/mp_targt.cc +++ b/src/mapper/mp_targt.cc @@ -16,4 +16,12 @@ int target_init() return 0; } +// 0x49B434 +int target_exit() +{ + // TODO: Incomplete. + + return 0; +} + } // namespace fallout diff --git a/src/mapper/mp_targt.h b/src/mapper/mp_targt.h index 9e7f071..ef308e4 100644 --- a/src/mapper/mp_targt.h +++ b/src/mapper/mp_targt.h @@ -5,6 +5,7 @@ namespace fallout { void target_override_protection(); int target_init(); +int target_exit(); } // namespace fallout From 708862ca24d5d28ba957f4ff07e6b8492168d976 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 08:03:25 +0300 Subject: [PATCH 44/62] Add target_overriden --- src/mapper/mp_targt.cc | 9 +++++++++ src/mapper/mp_targt.h | 1 + 2 files changed, 10 insertions(+) diff --git a/src/mapper/mp_targt.cc b/src/mapper/mp_targt.cc index 1bbea4a..390fcb1 100644 --- a/src/mapper/mp_targt.cc +++ b/src/mapper/mp_targt.cc @@ -2,12 +2,21 @@ namespace fallout { +// 0x559DBC +static bool tgt_overriden = false; + // 0x49B2F0 void target_override_protection() { // TODO: Incomplete. } +// 0x49B2F0 +bool target_overriden() +{ + return tgt_overriden; +} + // 0x49B424 int target_init() { diff --git a/src/mapper/mp_targt.h b/src/mapper/mp_targt.h index ef308e4..d70651c 100644 --- a/src/mapper/mp_targt.h +++ b/src/mapper/mp_targt.h @@ -4,6 +4,7 @@ namespace fallout { void target_override_protection(); +bool target_overriden(); int target_init(); int target_exit(); From ac1f4477ef81edcb74c79b4c23cb2839ed474304 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 08:08:01 +0300 Subject: [PATCH 45/62] Add target_make_path --- src/mapper/mp_targt.cc | 26 ++++++++++++++++++++++++++ src/mapper/mp_targt.h | 1 + 2 files changed, 27 insertions(+) diff --git a/src/mapper/mp_targt.cc b/src/mapper/mp_targt.cc index 390fcb1..0bc7aed 100644 --- a/src/mapper/mp_targt.cc +++ b/src/mapper/mp_targt.cc @@ -1,7 +1,18 @@ #include "mapper/mp_targt.h" +#include + +#include "art.h" +#include "proto.h" + namespace fallout { +// 0x53F354 +static char default_target_path_base[] = "\\fallout2\\dev\\proto\\"; + +// 0x559CD0 +static char* target_path_base = default_target_path_base; + // 0x559DBC static bool tgt_overriden = false; @@ -17,6 +28,21 @@ bool target_overriden() return tgt_overriden; } +// 0x49B34C +void target_make_path(char* path, int pid) +{ + if (_cd_path_base[0] != '\0' && _cd_path_base[1] == ':') { + strncpy(path, _cd_path_base, 2); + strcat(path, target_path_base); + } else { + strcpy(path, target_path_base); + } + + if (pid != -1) { + strcat(path, artGetObjectTypeName(PID_TYPE(pid))); + } +} + // 0x49B424 int target_init() { diff --git a/src/mapper/mp_targt.h b/src/mapper/mp_targt.h index d70651c..1c0a782 100644 --- a/src/mapper/mp_targt.h +++ b/src/mapper/mp_targt.h @@ -5,6 +5,7 @@ namespace fallout { void target_override_protection(); bool target_overriden(); +void target_make_path(char* path, int pid); int target_init(); int target_exit(); From 3a271a399f7e41e955859676fc78eb0790bb2744 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 08:10:46 +0300 Subject: [PATCH 46/62] Add pick_rot --- src/mapper/mp_targt.cc | 15 +++++++++++++++ src/mapper/mp_targt.h | 1 + 2 files changed, 16 insertions(+) diff --git a/src/mapper/mp_targt.cc b/src/mapper/mp_targt.cc index 0bc7aed..bc0c6e1 100644 --- a/src/mapper/mp_targt.cc +++ b/src/mapper/mp_targt.cc @@ -4,6 +4,7 @@ #include "art.h" #include "proto.h" +#include "window_manager_private.h" namespace fallout { @@ -59,4 +60,18 @@ int target_exit() return 0; } +// 0x49BD98 +int pick_rot() +{ + int value; + win_get_num_i(&value, + -1, + 5, + false, + "Rotation", + 100, + 100); + return value; +} + } // namespace fallout diff --git a/src/mapper/mp_targt.h b/src/mapper/mp_targt.h index 1c0a782..b27660a 100644 --- a/src/mapper/mp_targt.h +++ b/src/mapper/mp_targt.h @@ -8,6 +8,7 @@ bool target_overriden(); void target_make_path(char* path, int pid); int target_init(); int target_exit(); +int pick_rot(); } // namespace fallout From f6461a44dc3c58cdef44dcc2ed4d2b39c8891dc8 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 08:13:45 +0300 Subject: [PATCH 47/62] Add target_pick_global_var --- src/mapper/mp_targt.cc | 26 ++++++++++++++++++++++++++ src/mapper/mp_targt.h | 1 + 2 files changed, 27 insertions(+) diff --git a/src/mapper/mp_targt.cc b/src/mapper/mp_targt.cc index bc0c6e1..4a8f517 100644 --- a/src/mapper/mp_targt.cc +++ b/src/mapper/mp_targt.cc @@ -3,6 +3,7 @@ #include #include "art.h" +#include "game.h" #include "proto.h" #include "window_manager_private.h" @@ -74,4 +75,29 @@ int pick_rot() return value; } +// 0x49BDD0 +int target_pick_global_var(int* value_ptr) +{ + int value; + int rc; + + if (gGameGlobalVarsLength == 0) { + return -1; + } + + rc = win_get_num_i(&value, + 0, + gGameGlobalVarsLength - 1, + false, + "Global Variable Index #:", + 100, + 100); + if (rc == -1) { + return -1; + } + + *value_ptr = value; + return 0; +} + } // namespace fallout diff --git a/src/mapper/mp_targt.h b/src/mapper/mp_targt.h index b27660a..b553db3 100644 --- a/src/mapper/mp_targt.h +++ b/src/mapper/mp_targt.h @@ -9,6 +9,7 @@ void target_make_path(char* path, int pid); int target_init(); int target_exit(); int pick_rot(); +int target_pick_global_var(int* value_ptr); } // namespace fallout From ca206da4af2c6013572ca91570d931c0c091dea1 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 08:17:04 +0300 Subject: [PATCH 48/62] Add target_pick_map_var --- src/map.cc | 4 ++-- src/map.h | 2 ++ src/mapper/mp_targt.cc | 26 ++++++++++++++++++++++++++ src/mapper/mp_targt.h | 1 + 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/map.cc b/src/map.cc index 8b07d6f..333935f 100644 --- a/src/map.cc +++ b/src/map.cc @@ -108,7 +108,7 @@ int* gMapLocalVars = NULL; // map_vars // 0x51956C -static int* gMapGlobalVars = NULL; +int* gMapGlobalVars = NULL; // local_vars_num // 0x519570 @@ -116,7 +116,7 @@ int gMapLocalVarsLength = 0; // map_vars_num // 0x519574 -static int gMapGlobalVarsLength = 0; +int gMapGlobalVarsLength = 0; // Current elevation. // diff --git a/src/map.h b/src/map.h index 09247f8..70e8d7f 100644 --- a/src/map.h +++ b/src/map.h @@ -69,7 +69,9 @@ typedef void IsoWindowRefreshProc(Rect* rect); extern int gMapSid; extern int* gMapLocalVars; +extern int* gMapGlobalVars; extern int gMapLocalVarsLength; +extern int gMapGlobalVarsLength; extern int gElevation; extern MessageList gMapMessageList; diff --git a/src/mapper/mp_targt.cc b/src/mapper/mp_targt.cc index 4a8f517..e5249d2 100644 --- a/src/mapper/mp_targt.cc +++ b/src/mapper/mp_targt.cc @@ -4,6 +4,7 @@ #include "art.h" #include "game.h" +#include "map.h" #include "proto.h" #include "window_manager_private.h" @@ -100,4 +101,29 @@ int target_pick_global_var(int* value_ptr) return 0; } +// 0x49BE20 +int target_pick_map_var(int* value_ptr) +{ + int value; + int rc; + + if (gMapGlobalVarsLength == 0) { + return -1; + } + + rc = win_get_num_i(&value, + 0, + gMapGlobalVarsLength - 1, + false, + "Map Variable Index #:", + 100, + 100); + if (rc == -1) { + return -1; + } + + *value_ptr = value; + return 0; +} + } // namespace fallout diff --git a/src/mapper/mp_targt.h b/src/mapper/mp_targt.h index b553db3..d22c700 100644 --- a/src/mapper/mp_targt.h +++ b/src/mapper/mp_targt.h @@ -10,6 +10,7 @@ int target_init(); int target_exit(); int pick_rot(); int target_pick_global_var(int* value_ptr); +int target_pick_map_var(int* value_ptr); } // namespace fallout From f93aa710a424f9ee2d550c32ed44a39a864c1586 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 08:20:15 +0300 Subject: [PATCH 49/62] Add target_pick_local_var --- src/mapper/mp_targt.cc | 25 +++++++++++++++++++++++++ src/mapper/mp_targt.h | 1 + 2 files changed, 26 insertions(+) diff --git a/src/mapper/mp_targt.cc b/src/mapper/mp_targt.cc index e5249d2..b654011 100644 --- a/src/mapper/mp_targt.cc +++ b/src/mapper/mp_targt.cc @@ -126,4 +126,29 @@ int target_pick_map_var(int* value_ptr) return 0; } +// 0x49BE70 +int target_pick_local_var(int* value_ptr) +{ + int value; + int rc; + + if (gMapLocalVarsLength == 0) { + return -1; + } + + rc = win_get_num_i(&value, + 0, + gMapLocalVarsLength - 1, + false, + "Local Variable Index #:", + 100, + 100); + if (rc == -1) { + return -1; + } + + *value_ptr = value; + return 0; +} + } // namespace fallout diff --git a/src/mapper/mp_targt.h b/src/mapper/mp_targt.h index d22c700..2a0578d 100644 --- a/src/mapper/mp_targt.h +++ b/src/mapper/mp_targt.h @@ -11,6 +11,7 @@ int target_exit(); int pick_rot(); int target_pick_global_var(int* value_ptr); int target_pick_map_var(int* value_ptr); +int target_pick_local_var(int* value_ptr); } // namespace fallout From e0e0db219c42e7feab6c43ced26ae80baab7d9ba Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 08:27:42 +0300 Subject: [PATCH 50/62] Add combat_ai_num --- src/combat_ai.cc | 6 ++++++ src/combat_ai.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/combat_ai.cc b/src/combat_ai.cc index 3ee2082..2cf475e 100644 --- a/src/combat_ai.cc +++ b/src/combat_ai.cc @@ -701,6 +701,12 @@ static int aiPacketWrite(File* stream, AiPacket* ai) return 0; } +// 0x428058 +int combat_ai_num() +{ + return gAiPacketsLength; +} + // Get ai from object // // 0x4280B4 diff --git a/src/combat_ai.h b/src/combat_ai.h index 12cf21d..e182a2c 100644 --- a/src/combat_ai.h +++ b/src/combat_ai.h @@ -30,6 +30,7 @@ void aiReset(); int aiExit(); int aiLoad(File* stream); int aiSave(File* stream); +int combat_ai_num(); int aiGetAreaAttackMode(Object* obj); int aiGetRunAwayMode(Object* obj); int aiGetBestWeapon(Object* obj); From 49804a52e6d821f0e354e3b527720878b5e240e5 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 08:29:19 +0300 Subject: [PATCH 51/62] Add combat_ai_name --- src/combat_ai.cc | 18 ++++++++++++++++++ src/combat_ai.h | 1 + 2 files changed, 19 insertions(+) diff --git a/src/combat_ai.cc b/src/combat_ai.cc index 2cf475e..2110b9d 100644 --- a/src/combat_ai.cc +++ b/src/combat_ai.cc @@ -707,6 +707,24 @@ int combat_ai_num() return gAiPacketsLength; } +// 0x428060 +char* combat_ai_name(int packet_num) +{ + int index; + + if (packet_num < 0 || packet_num >= gAiPacketsLength) { + return NULL; + } + + for (index = 0; index < gAiPacketsLength; index++) { + if (gAiPackets[index].packet_num == packet_num) { + return gAiPackets[index].name; + } + } + + return NULL; +} + // Get ai from object // // 0x4280B4 diff --git a/src/combat_ai.h b/src/combat_ai.h index e182a2c..1e11dfb 100644 --- a/src/combat_ai.h +++ b/src/combat_ai.h @@ -31,6 +31,7 @@ int aiExit(); int aiLoad(File* stream); int aiSave(File* stream); int combat_ai_num(); +char* combat_ai_name(int packet_num); int aiGetAreaAttackMode(Object* obj); int aiGetRunAwayMode(Object* obj); int aiGetBestWeapon(Object* obj); From c1258cbb4c7957cdbaa2fd6b5925bc4aea1d0360 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 08:43:27 +0300 Subject: [PATCH 52/62] Add proto_pick_ai_packet --- src/mapper/mp_proto.cc | 45 ++++++++++++++++++++++++++++++++++++++++++ src/mapper/mp_proto.h | 1 + 2 files changed, 46 insertions(+) diff --git a/src/mapper/mp_proto.cc b/src/mapper/mp_proto.cc index 7678d9c..10d36da 100644 --- a/src/mapper/mp_proto.cc +++ b/src/mapper/mp_proto.cc @@ -1,5 +1,12 @@ #include "mapper/mp_proto.h" +#include + +#include "color.h" +#include "combat_ai.h" +#include "memory.h" +#include "window_manager_private.h" + namespace fallout { // 0x559C60 @@ -11,4 +18,42 @@ void init_mapper_protos() // TODO: Incomplete. } +// 0x497568 +int proto_pick_ai_packet(int* value) +{ + int count; + char** names; + int index; + int rc; + + count = combat_ai_num(); + if (count <= 0) { + return -1; + } + + names = (char**)internal_malloc(sizeof(char*) * count); + for (index = 0; index < count; index++) { + names[index] = (char*)internal_malloc(strlen(combat_ai_name(index)) + 1); + strcpy(names[index], combat_ai_name(index)); + } + + rc = _win_list_select("AI Packet", + names, + count, + NULL, + 50, + 100, + _colorTable[15855]); + if (rc != -1) { + *value = rc; + } + + for (index = 0; index < count; index++) { + internal_free(names[index]); + } + + internal_free(names); + return 0; +} + } // namespace fallout diff --git a/src/mapper/mp_proto.h b/src/mapper/mp_proto.h index 63cda50..58a7277 100644 --- a/src/mapper/mp_proto.h +++ b/src/mapper/mp_proto.h @@ -6,6 +6,7 @@ namespace fallout { extern bool can_modify_protos; void init_mapper_protos(); +int proto_pick_ai_packet(int* value); } // namespace fallout From e9f3b3488892c3056d8582dee5906822db849ebf Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 08:55:43 +0300 Subject: [PATCH 53/62] Add mp_pick_kill_type --- src/mapper/mp_proto.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/mapper/mp_proto.cc b/src/mapper/mp_proto.cc index 10d36da..a9e1e8b 100644 --- a/src/mapper/mp_proto.cc +++ b/src/mapper/mp_proto.cc @@ -4,11 +4,14 @@ #include "color.h" #include "combat_ai.h" +#include "critter.h" #include "memory.h" #include "window_manager_private.h" namespace fallout { +static int mp_pick_kill_type(); + // 0x559C60 bool can_modify_protos = false; @@ -18,6 +21,25 @@ void init_mapper_protos() // TODO: Incomplete. } +// 0x497520 +int mp_pick_kill_type() +{ + char* names[KILL_TYPE_COUNT]; + int index; + + for (index = 0; index < KILL_TYPE_COUNT; index++) { + names[index] = killTypeGetName(index); + } + + return _win_list_select("Kill Type", + names, + KILL_TYPE_COUNT, + NULL, + 50, + 100, + _colorTable[15855]); +} + // 0x497568 int proto_pick_ai_packet(int* value) { From 369a54f836d648745434adfa33ef1ac9464cfae5 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 09:04:11 +0300 Subject: [PATCH 54/62] Add critter_flag_set --- src/critter.cc | 18 ++++++++++++++++++ src/critter.h | 1 + 2 files changed, 19 insertions(+) diff --git a/src/critter.cc b/src/critter.cc index 4439eb0..50fa5f3 100644 --- a/src/critter.cc +++ b/src/critter.cc @@ -1396,4 +1396,22 @@ bool _critter_flag_check(int pid, int flag) return (proto->critter.data.flags & flag) != 0; } +// 0x42E6F0 +void critter_flag_set(int pid, int flag) +{ + Proto* proto; + + if (pid == -1) { + return; + } + + if (PID_TYPE(pid) != OBJ_TYPE_CRITTER) { + return; + } + + protoGetProto(pid, &proto); + + proto->critter.data.flags |= flag; +} + } // namespace fallout diff --git a/src/critter.h b/src/critter.h index 7423834..ea83f8d 100644 --- a/src/critter.h +++ b/src/critter.h @@ -70,6 +70,7 @@ int critterGetMovementPointCostAdjustedForCrippledLegs(Object* critter, int a2); bool critterIsEncumbered(Object* critter); bool critterIsFleeing(Object* a1); bool _critter_flag_check(int pid, int flag); +void critter_flag_set(int pid, int flag); } // namespace fallout From f3f61abc18d643a5b6d00519274e269d2b36e0db Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 09:07:02 +0300 Subject: [PATCH 55/62] Add critter_flag_unset --- src/critter.cc | 18 ++++++++++++++++++ src/critter.h | 1 + 2 files changed, 19 insertions(+) diff --git a/src/critter.cc b/src/critter.cc index 50fa5f3..c576549 100644 --- a/src/critter.cc +++ b/src/critter.cc @@ -1414,4 +1414,22 @@ void critter_flag_set(int pid, int flag) proto->critter.data.flags |= flag; } +// 0x42E71C +void critter_flag_unset(int pid, int flag) +{ + Proto* proto; + + if (pid == -1) { + return; + } + + if (PID_TYPE(pid) != OBJ_TYPE_CRITTER) { + return; + } + + protoGetProto(pid, &proto); + + proto->critter.data.flags &= ~flag; +} + } // namespace fallout diff --git a/src/critter.h b/src/critter.h index ea83f8d..ef4f873 100644 --- a/src/critter.h +++ b/src/critter.h @@ -71,6 +71,7 @@ bool critterIsEncumbered(Object* critter); bool critterIsFleeing(Object* a1); bool _critter_flag_check(int pid, int flag); void critter_flag_set(int pid, int flag); +void critter_flag_unset(int pid, int flag); } // namespace fallout From f78096917810438e70c003d7b808867c3d7824c5 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 10:46:31 +0300 Subject: [PATCH 56/62] Add proto_critter_flags_modify --- src/mapper/mp_proto.cc | 136 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/src/mapper/mp_proto.cc b/src/mapper/mp_proto.cc index a9e1e8b..a3d9ef8 100644 --- a/src/mapper/mp_proto.cc +++ b/src/mapper/mp_proto.cc @@ -6,21 +6,157 @@ #include "combat_ai.h" #include "critter.h" #include "memory.h" +#include "proto.h" #include "window_manager_private.h" namespace fallout { +#define CRITTER_FLAG_COUNT 10 + +static int proto_critter_flags_modify(int pid); static int mp_pick_kill_type(); // 0x559C60 bool can_modify_protos = false; +// 0x559C6C +static int critFlagList[CRITTER_FLAG_COUNT] = { + CRITTER_NO_STEAL, + CRITTER_NO_DROP, + CRITTER_NO_LIMBS, + CRITTER_NO_AGE, + CRITTER_NO_HEAL, + CRITTER_INVULNERABLE, + CRITTER_FLAT, + CRITTER_SPECIAL_DEATH, + CRITTER_LONG_LIMBS, + CRITTER_NO_KNOCKBACK, +}; + // 0x4922F8 void init_mapper_protos() { // TODO: Incomplete. } +// 0x496120 +int proto_critter_flags_modify(int pid) +{ + Proto* proto; + int rc; + int flags = 0; + int index; + + if (protoGetProto(pid, &proto) == -1) { + return -1; + } + + rc = win_yes_no("Can't be stolen from?", 340, 200, _colorTable[15855]); + if (rc == -1) { + return -1; + } + + if (rc == 1) { + flags |= CRITTER_NO_STEAL; + } + + rc = win_yes_no("Can't Drop items?", 340, 200, _colorTable[15855]); + if (rc == -1) { + return -1; + } + + if (rc == 1) { + flags |= CRITTER_NO_DROP; + } + + rc = win_yes_no("Can't lose limbs?", 340, 200, _colorTable[15855]); + if (rc == -1) { + return -1; + } + + if (rc == 1) { + flags |= CRITTER_NO_LIMBS; + } + + rc = win_yes_no("Dead Bodies Can't Age?", 340, 200, _colorTable[15855]); + if (rc == -1) { + return -1; + } + + if (rc == 1) { + flags |= CRITTER_NO_AGE; + } + + rc = win_yes_no("Can't Heal by Aging?", 340, 200, _colorTable[15855]); + if (rc == -1) { + return -1; + } + + if (rc == 1) { + flags |= CRITTER_NO_HEAL; + } + + rc = win_yes_no("Is Invlunerable????", 340, 200, _colorTable[15855]); + if (rc == -1) { + return -1; + } + + if (rc == 1) { + flags |= CRITTER_INVULNERABLE; + } + + rc = win_yes_no("Can't Flatten on Death?", 340, 200, _colorTable[15855]); + if (rc == -1) { + return -1; + } + + if (rc == 1) { + flags |= CRITTER_FLAT; + } + + rc = win_yes_no("Has Special Death?", 340, 200, _colorTable[15855]); + if (rc == -1) { + return -1; + } + + if (rc == 1) { + flags |= CRITTER_SPECIAL_DEATH; + } + + rc = win_yes_no("Has Extra Hand-To-Hand Range?", 340, 200, _colorTable[15855]); + if (rc == -1) { + return -1; + } + + if (rc == 1) { + flags |= CRITTER_LONG_LIMBS; + } + + rc = win_yes_no("Can't be knocked back?", 340, 200, _colorTable[15855]); + if (rc == -1) { + return -1; + } + + if (rc == 1) { + flags |= CRITTER_NO_KNOCKBACK; + } + + if (!can_modify_protos) { + win_timed_msg("Can't modify protos!", _colorTable[31744] | 0x10000); + return -1; + } + + for (index = 0; index < CRITTER_FLAG_COUNT; index++) { + if ((critFlagList[index] & flags) != 0) { + critter_flag_set(pid, critFlagList[index]); + } else { + critter_flag_unset(pid, critFlagList[index]); + } + } + + return 0; +} + // 0x497520 int mp_pick_kill_type() { From c5ad0c294fd76cf4e42e8326a5dc6cc55a7ce114 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 10:53:04 +0300 Subject: [PATCH 57/62] Add proto_critter_flags_redraw --- src/mapper/mp_proto.cc | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/mapper/mp_proto.cc b/src/mapper/mp_proto.cc index a3d9ef8..fc03401 100644 --- a/src/mapper/mp_proto.cc +++ b/src/mapper/mp_proto.cc @@ -7,12 +7,14 @@ #include "critter.h" #include "memory.h" #include "proto.h" +#include "window_manager.h" #include "window_manager_private.h" namespace fallout { #define CRITTER_FLAG_COUNT 10 +static void proto_critter_flags_redraw(int win, int pid); static int proto_critter_flags_modify(int pid); static int mp_pick_kill_type(); @@ -33,12 +35,45 @@ static int critFlagList[CRITTER_FLAG_COUNT] = { CRITTER_NO_KNOCKBACK, }; +// 0x559C94 +static const char* critFlagStrs[CRITTER_FLAG_COUNT] = { + "_Steal", + "_Drop", + "_Limbs", + "_Ages", + "_Heal", + "Invuln.,", + "_Flattens", + "Special", + "Rng", + "_Knock", +}; + // 0x4922F8 void init_mapper_protos() { // TODO: Incomplete. } +// 0x4960B8 +void proto_critter_flags_redraw(int win, int pid) +{ + int index; + int color; + int x = 110; + + for (index = 0; index < CRITTER_FLAG_COUNT; index++) { + if (_critter_flag_check(pid, critFlagList[index])) { + color = _colorTable[992]; + } else { + color = _colorTable[10570]; + } + + windowDrawText(win, critFlagStrs[index], 44, x, 195, color | 0x10000); + x += 48; + } +} + // 0x496120 int proto_critter_flags_modify(int pid) { From 6ce6639f10edaf11b7bfc65626701f4467f6d2e2 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 10:57:31 +0300 Subject: [PATCH 58/62] Add proto_wall_light_str --- src/mapper/mp_proto.cc | 36 ++++++++++++++++++++++++++++++++++++ src/mapper/mp_proto.h | 1 + 2 files changed, 37 insertions(+) diff --git a/src/mapper/mp_proto.cc b/src/mapper/mp_proto.cc index fc03401..8adc13f 100644 --- a/src/mapper/mp_proto.cc +++ b/src/mapper/mp_proto.cc @@ -18,6 +18,16 @@ static void proto_critter_flags_redraw(int win, int pid); static int proto_critter_flags_modify(int pid); static int mp_pick_kill_type(); +// 0x559B94 +static const char* wall_light_strs[] = { + "North/South", + "East/West", + "North Corner", + "South Corner", + "East Corner", + "West Corner", +}; + // 0x559C60 bool can_modify_protos = false; @@ -55,6 +65,32 @@ void init_mapper_protos() // TODO: Incomplete. } +// 0x495438 +const char* proto_wall_light_str(int flags) +{ + if ((flags & 0x8000000) != 0) { + return wall_light_strs[1]; + } + + if ((flags & 0x10000000) != 0) { + return wall_light_strs[2]; + } + + if ((flags & 0x20000000) != 0) { + return wall_light_strs[3]; + } + + if ((flags & 0x40000000) != 0) { + return wall_light_strs[4]; + } + + if ((flags & 0x80000000) != 0) { + return wall_light_strs[5]; + } + + return wall_light_strs[0]; +} + // 0x4960B8 void proto_critter_flags_redraw(int win, int pid) { diff --git a/src/mapper/mp_proto.h b/src/mapper/mp_proto.h index 58a7277..e6a520e 100644 --- a/src/mapper/mp_proto.h +++ b/src/mapper/mp_proto.h @@ -6,6 +6,7 @@ namespace fallout { extern bool can_modify_protos; void init_mapper_protos(); +const char* proto_wall_light_str(int flags); int proto_pick_ai_packet(int* value); } // namespace fallout From f1f4cac316f231f07ba13434bc96dcccd036c383 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 15:15:06 +0300 Subject: [PATCH 59/62] Add proto_choose_container_flags --- src/mapper/mp_proto.cc | 148 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/src/mapper/mp_proto.cc b/src/mapper/mp_proto.cc index 8adc13f..1133674 100644 --- a/src/mapper/mp_proto.cc +++ b/src/mapper/mp_proto.cc @@ -5,8 +5,11 @@ #include "color.h" #include "combat_ai.h" #include "critter.h" +#include "input.h" +#include "kb.h" #include "memory.h" #include "proto.h" +#include "svga.h" #include "window_manager.h" #include "window_manager_private.h" @@ -14,10 +17,17 @@ namespace fallout { #define CRITTER_FLAG_COUNT 10 +#define YES 0 +#define NO 1 + +static int proto_choose_container_flags(Proto* proto); static void proto_critter_flags_redraw(int win, int pid); static int proto_critter_flags_modify(int pid); static int mp_pick_kill_type(); +static char kYes[] = "YES"; +static char kNo[] = "NO"; + // 0x559B94 static const char* wall_light_strs[] = { "North/South", @@ -28,6 +38,15 @@ static const char* wall_light_strs[] = { "West Corner", }; +// 0x559C50 +static char* yesno[] = { + kYes, + kNo, +}; + +// 0x559C58 +int edit_window_color = 1; + // 0x559C60 bool can_modify_protos = false; @@ -65,6 +84,135 @@ void init_mapper_protos() // TODO: Incomplete. } +// 0x492840 +int proto_choose_container_flags(Proto* proto) +{ + int win = windowCreate(320, + 185, + 220, + 205, + edit_window_color, + WINDOW_MOVE_ON_TOP); + if (win == -1) { + return -1; + } + + _win_register_text_button(win, + 10, + 11, + -1, + -1, + -1, + '1', + "Magic Hands Grnd", + 0); + + if ((proto->item.data.container.openFlags & 0x1) != 0) { + windowDrawText(win, + yesno[YES], + 50, + 125, + 15, + _colorTable[32747] | 0x10000); + } else { + windowDrawText(win, + yesno[NO], + 50, + 125, + 15, + _colorTable[32747] | 0x10000); + } + + _win_register_text_button(win, + 10, + 32, + -1, + -1, + -1, + '2', + "Cannot Pick Up", + 0); + + if (_proto_action_can_pickup(proto->pid)) { + windowDrawText(win, + yesno[YES], + 50, + 125, + 36, + _colorTable[32747] | 0x10000); + } else { + windowDrawText(win, + yesno[NO], + 50, + 125, + 36, + _colorTable[32747] | 0x10000); + } + + windowDrawBorder(win); + windowRefresh(win); + + while (1) { + sharedFpsLimiter.mark(); + + int input = inputGetInput(); + if (input == KEY_ESCAPE + || input == KEY_BAR + || input == KEY_RETURN) { + break; + } + + if (input == '1') { + proto->item.data.container.openFlags ^= 0x1; + + if ((proto->item.data.container.openFlags & 0x1) != 0) { + windowDrawText(win, + yesno[YES], + 50, + 125, + 15, + _colorTable[32747] | 0x10000); + } else { + windowDrawText(win, + yesno[NO], + 50, + 125, + 15, + _colorTable[32747] | 0x10000); + } + + windowRefresh(win); + } else if (input == '2') { + proto->item.extendedFlags ^= 0x8000; + + if (_proto_action_can_pickup(proto->pid)) { + windowDrawText(win, + yesno[YES], + 50, + 125, + 36, + _colorTable[32747] | 0x10000); + } else { + windowDrawText(win, + yesno[NO], + 50, + 125, + 36, + _colorTable[32747] | 0x10000); + } + + windowRefresh(win); + } + + renderPresent(); + sharedFpsLimiter.throttle(); + } + + windowDestroy(win); + + return 0; +} + // 0x495438 const char* proto_wall_light_str(int flags) { From 1de7ef015184d6c1f980a98240179039555a7f64 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 24 Jul 2023 15:19:18 +0300 Subject: [PATCH 60/62] Add init_mapper_protos --- src/mapper/mp_proto.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mapper/mp_proto.cc b/src/mapper/mp_proto.cc index 1133674..513fb57 100644 --- a/src/mapper/mp_proto.cc +++ b/src/mapper/mp_proto.cc @@ -7,6 +7,7 @@ #include "critter.h" #include "input.h" #include "kb.h" +#include "mapper/mp_targt.h" #include "memory.h" #include "proto.h" #include "svga.h" @@ -81,7 +82,8 @@ static const char* critFlagStrs[CRITTER_FLAG_COUNT] = { // 0x4922F8 void init_mapper_protos() { - // TODO: Incomplete. + edit_window_color = _colorTable[10570]; + can_modify_protos = target_overriden(); } // 0x492840 From 8329d2fcf6818e970397ae2484d3623a4c6a5f33 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Tue, 25 Jul 2023 11:14:41 +0300 Subject: [PATCH 61/62] Add map_scr_remove_all_spatials --- src/mapper/mp_scrpt.cc | 55 ++++++++++++++++++++++++++++++++++++++++++ src/mapper/mp_scrpt.h | 10 ++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/mapper/mp_scrpt.cc create mode 100644 src/mapper/mp_scrpt.h diff --git a/src/mapper/mp_scrpt.cc b/src/mapper/mp_scrpt.cc new file mode 100644 index 0000000..5a100f9 --- /dev/null +++ b/src/mapper/mp_scrpt.cc @@ -0,0 +1,55 @@ +#include "mapper/mp_scrpt.h" + +#include "art.h" +#include "object.h" +#include "scripts.h" +#include "tile.h" + +namespace fallout { + +// 0x49B214 +int map_scr_remove_all_spatials() +{ + int elevation; + Script* scr; + Object* obj; + int sid; + + for (elevation = 0; elevation < ELEVATION_COUNT; elevation++) { + scr = scriptGetFirstSpatialScript(elevation); + while (scr != NULL) { + scriptRemove(scr->sid); + + scr = scriptGetFirstSpatialScript(elevation); + } + + obj = objectFindFirstAtElevation(elevation); + while (obj != NULL) { + if (buildFid(OBJ_TYPE_INTERFACE, 3, 0, 0, 0) == obj->fid) { + objectDestroy(obj, NULL); + + obj = objectFindFirstAtElevation(elevation); + continue; + } + + obj = objectFindNextAtElevation(); + } + } + + tileWindowRefresh(); + + for (sid = 0; sid < 15000; sid++) { + if (scriptGetScript(sid, &scr) != -1) { + if (scr->owner != NULL) { + if (scr->owner->pid == 0x500000C) { + scr->owner->sid = -1; + scriptRemove(sid); + } + } + } + } + + return 0; +} + +} // namespace fallout diff --git a/src/mapper/mp_scrpt.h b/src/mapper/mp_scrpt.h new file mode 100644 index 0000000..6912a8e --- /dev/null +++ b/src/mapper/mp_scrpt.h @@ -0,0 +1,10 @@ +#ifndef FALLOUT_MAPPER_MP_SCRPTR_H_ +#define FALLOUT_MAPPER_MP_SCRPTR_H_ + +namespace fallout { + +int map_scr_remove_all_spatials(); + +} // namespace fallout + +#endif /* FALLOUT_MAPPER_MP_SCRPTR_H_ */ From cba1fc8f61fb7bb5f4ef5c386356c9c7a6eef694 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Tue, 25 Jul 2023 11:56:20 +0300 Subject: [PATCH 62/62] Add map_scr_remove_spatial --- src/mapper/mp_scrpt.cc | 35 +++++++++++++++++++++++++++++++++++ src/mapper/mp_scrpt.h | 1 + 2 files changed, 36 insertions(+) diff --git a/src/mapper/mp_scrpt.cc b/src/mapper/mp_scrpt.cc index 5a100f9..eb2f9c6 100644 --- a/src/mapper/mp_scrpt.cc +++ b/src/mapper/mp_scrpt.cc @@ -7,6 +7,41 @@ namespace fallout { +// 0x49B170 +int map_scr_remove_spatial(int tile, int elevation) +{ + Script* scr; + Object* obj; + Rect rect; + + scr = scriptGetFirstSpatialScript(elevation); + while (scr != NULL) { + if (builtTileGetTile(scr->sp.built_tile) == tile) { + scriptRemove(scr->sid); + + scr = scriptGetFirstSpatialScript(elevation); + continue; + } + + scr = scriptGetNextSpatialScript(); + } + + obj = objectFindFirstAtElevation(elevation); + while (obj != NULL) { + if (obj->tile == tile && buildFid(OBJ_TYPE_INTERFACE, 3, 0, 0, 0) == obj->fid) { + objectDestroy(obj, &rect); + tileWindowRefreshRect(&rect, elevation); + + obj = objectFindFirstAtElevation(elevation); + continue; + } + + obj = objectFindNextAtElevation(); + } + + return 0; +} + // 0x49B214 int map_scr_remove_all_spatials() { diff --git a/src/mapper/mp_scrpt.h b/src/mapper/mp_scrpt.h index 6912a8e..64c2d59 100644 --- a/src/mapper/mp_scrpt.h +++ b/src/mapper/mp_scrpt.h @@ -3,6 +3,7 @@ namespace fallout { +int map_scr_remove_spatial(int tile, int elevation); int map_scr_remove_all_spatials(); } // namespace fallout