From 7d5336aaa51faf875889a8b65e8fbfd91b107ab6 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Thu, 19 Sep 2024 16:37:16 +0200 Subject: [PATCH 1/3] console/cmd: move /give to libtrx --- meson.build | 1 + src/game/backpack.c | 8 ++++ src/game/console.c | 14 +++--- src/game/console_cmd.c | 95 ++++++++-------------------------------- src/game/game_string.def | 2 - src/game/objects/names.c | 24 +++++++--- src/game/objects/names.h | 5 ++- subprojects/libtrx | 2 +- 8 files changed, 56 insertions(+), 95 deletions(-) create mode 100644 src/game/backpack.c diff --git a/meson.build b/meson.build index df8f093c9..12b2d4ed2 100644 --- a/meson.build +++ b/meson.build @@ -95,6 +95,7 @@ sources = [ 'src/config.c', 'src/config_map.c', 'src/game/anim.c', + 'src/game/backpack.c', 'src/game/box.c', 'src/game/camera.c', 'src/game/carrier.c', diff --git a/src/game/backpack.c b/src/game/backpack.c new file mode 100644 index 000000000..4bcc51018 --- /dev/null +++ b/src/game/backpack.c @@ -0,0 +1,8 @@ +#include "game/inventory.h" + +#include + +bool Backpack_AddItem(const GAME_OBJECT_ID object_id) +{ + return Inv_AddItem(object_id); +} diff --git a/src/game/console.c b/src/game/console.c index a774fbebf..8adba2aea 100644 --- a/src/game/console.c +++ b/src/game/console.c @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -82,16 +83,17 @@ static COMMAND_RESULT M_Eval(const char *const cmdline) break; } - if (strstr(cmdline, cur_cmd->prefix) != cmdline) { + char regex[strlen(cur_cmd->prefix) + 13]; + sprintf(regex, "^(%s)(\\s+.*)?$", cur_cmd->prefix); + if (!String_Match(cmdline, regex)) { continue; } - if (cmdline[strlen(cur_cmd->prefix)] == ' ') { - args = cmdline + strlen(cur_cmd->prefix) + 1; - } else if (cmdline[strlen(cur_cmd->prefix)] == '\0') { - args = ""; + args = strstr(cmdline, " "); + if (args != NULL) { + args++; } else { - continue; + args = ""; } matching_cmd = cur_cmd; diff --git a/src/game/console_cmd.c b/src/game/console_cmd.c index 3e586f9db..bc423ba42 100644 --- a/src/game/console_cmd.c +++ b/src/game/console_cmd.c @@ -22,6 +22,7 @@ #include "global/vars.h" #include +#include #include #include #include @@ -35,6 +36,7 @@ #include #include +static bool M_CanTargetObject_Enemy(GAME_OBJECT_ID object_id); static bool M_IsFloatRound(const float num); static COMMAND_RESULT Console_Cmd_Fps(const char *const args); static COMMAND_RESULT Console_Cmd_VSync(const char *const args); @@ -44,7 +46,6 @@ static COMMAND_RESULT Console_Cmd_Cheats(const char *const args); static COMMAND_RESULT Console_Cmd_Teleport(const char *const args); static COMMAND_RESULT Console_Cmd_Fly(const char *const args); static COMMAND_RESULT Console_Cmd_Speed(const char *const args); -static COMMAND_RESULT Console_Cmd_GiveItem(const char *args); static COMMAND_RESULT Console_Cmd_FlipMap(const char *args); static COMMAND_RESULT Console_Cmd_Kill(const char *args); static COMMAND_RESULT Console_Cmd_LoadGame(const char *args); @@ -56,6 +57,11 @@ static COMMAND_RESULT Console_Cmd_EndLevel(const char *args); static COMMAND_RESULT Console_Cmd_StartLevel(const char *args); static COMMAND_RESULT Console_Cmd_Abortion(const char *args); +static bool M_CanTargetObject_Enemy(const GAME_OBJECT_ID object_id) +{ + return Object_IsObjectType(object_id, g_EnemyObjects); +} + static inline bool M_IsFloatRound(const float num) { return (fabsf(num) - roundf(num)) < 0.0001f; @@ -164,7 +170,8 @@ static COMMAND_RESULT Console_Cmd_Teleport(const char *const args) // Nearest item of this name if (!String_Equivalent(args, "")) { int32_t match_count = 0; - GAME_OBJECT_ID *matching_objs = Object_IdsFromName(args, &match_count); + GAME_OBJECT_ID *matching_objs = + Object_IdsFromName(args, &match_count, NULL); const ITEM_INFO *best_item = NULL; int32_t best_distance = INT32_MAX; @@ -252,68 +259,6 @@ static COMMAND_RESULT Console_Cmd_Speed(const char *const args) return CR_BAD_INVOCATION; } -static COMMAND_RESULT Console_Cmd_GiveItem(const char *args) -{ - if (g_GameInfo.current_level_type == GFL_TITLE - || g_GameInfo.current_level_type == GFL_DEMO - || g_GameInfo.current_level_type == GFL_CUTSCENE) { - return CR_UNAVAILABLE; - } - - if (g_LaraItem == NULL) { - return CR_UNAVAILABLE; - } - - if (String_Equivalent(args, "keys")) { - return Lara_Cheat_GiveAllKeys() ? CR_SUCCESS : CR_FAILURE; - } - - if (String_Equivalent(args, "guns")) { - return Lara_Cheat_GiveAllGuns() ? CR_SUCCESS : CR_FAILURE; - } - - if (String_Equivalent(args, "all")) { - return Lara_Cheat_GiveAllItems() ? CR_SUCCESS : CR_FAILURE; - } - - int32_t num = 1; - if (sscanf(args, "%d ", &num) == 1) { - args = strstr(args, " "); - if (!args) { - return CR_BAD_INVOCATION; - } - args++; - } - - if (String_Equivalent(args, "")) { - return CR_BAD_INVOCATION; - } - - bool found = false; - int32_t match_count = 0; - GAME_OBJECT_ID *matching_objs = Object_IdsFromName(args, &match_count); - for (int32_t i = 0; i < match_count; i++) { - const GAME_OBJECT_ID object_id = matching_objs[i]; - if (Object_IsObjectType(object_id, g_PickupObjects)) { - if (g_Objects[object_id].loaded) { - Inv_AddItemNTimes(object_id, num); - Console_Log( - GS(OSD_GIVE_ITEM), - Object_GetCanonicalName(object_id, args)); - found = true; - } - } - } - Memory_FreePointer(&matching_objs); - - if (!found) { - Console_Log(GS(OSD_INVALID_ITEM), args); - return CR_FAILURE; - } - - return CR_SUCCESS; -} - static COMMAND_RESULT Console_Cmd_FlipMap(const char *args) { if (g_GameInfo.current_level_type == GFL_TITLE @@ -399,25 +344,22 @@ static COMMAND_RESULT Console_Cmd_Kill(const char *args) // kill a single enemy type { int32_t match_count = 0; - GAME_OBJECT_ID *matching_objs = Object_IdsFromName(args, &match_count); - bool matched = false; + GAME_OBJECT_ID *matching_objs = + Object_IdsFromName(args, &match_count, M_CanTargetObject_Enemy); int32_t num = 0; for (int32_t i = 0; i < match_count; i++) { const GAME_OBJECT_ID object_id = matching_objs[i]; - if (Object_IsObjectType(object_id, g_EnemyObjects)) { - matched = true; - for (int16_t item_num = 0; item_num < Item_GetTotalCount(); - item_num++) { - if (g_Items[item_num].object_id == object_id - && Lara_Cheat_KillEnemy(item_num)) { - num++; - } + for (int16_t item_num = 0; item_num < Item_GetTotalCount(); + item_num++) { + if (g_Items[item_num].object_id == object_id + && Lara_Cheat_KillEnemy(item_num)) { + num++; } } } Memory_FreePointer(&matching_objs); - if (!matched) { + if (!match_count) { return CR_BAD_INVOCATION; } if (num == 0) { @@ -584,8 +526,6 @@ CONSOLE_COMMAND *g_ConsoleCommands[] = { &(CONSOLE_COMMAND) { .prefix = "tp", .proc = Console_Cmd_Teleport }, &(CONSOLE_COMMAND) { .prefix = "fly", .proc = Console_Cmd_Fly }, &(CONSOLE_COMMAND) { .prefix = "speed", .proc = Console_Cmd_Speed }, - &(CONSOLE_COMMAND) { .prefix = "give", .proc = Console_Cmd_GiveItem }, - &(CONSOLE_COMMAND) { .prefix = "gimme", .proc = Console_Cmd_GiveItem }, &(CONSOLE_COMMAND) { .prefix = "flip", .proc = Console_Cmd_FlipMap }, &(CONSOLE_COMMAND) { .prefix = "flipmap", .proc = Console_Cmd_FlipMap }, &(CONSOLE_COMMAND) { .prefix = "kill", .proc = Console_Cmd_Kill }, @@ -604,5 +544,6 @@ CONSOLE_COMMAND *g_ConsoleCommands[] = { &g_Console_Cmd_Heal, &g_Console_Cmd_SetHealth, &g_Console_Cmd_Config, + &g_Console_Cmd_GiveItem, NULL, }; diff --git a/src/game/game_string.def b/src/game/game_string.def index beb9cc3cf..59689b140 100644 --- a/src/game/game_string.def +++ b/src/game/game_string.def @@ -146,7 +146,6 @@ GS_DEFINE(OSD_POS_SET_ITEM, "Teleported to object: %s") GS_DEFINE(OSD_POS_SET_ITEM_FAIL, "Failed to teleport to object: %s") GS_DEFINE(OSD_SPEED_GET, "Current speed: %d") GS_DEFINE(OSD_SPEED_SET, "Speed set to %d") -GS_DEFINE(OSD_GIVE_ITEM, "Added %s to Lara's inventory") GS_DEFINE(OSD_GIVE_ITEM_ALL_KEYS, "Surprise! Every key item Lara needs is now in her backpack.") GS_DEFINE(OSD_GIVE_ITEM_ALL_GUNS, "Lock'n'load - Lara's armed to the teeth!") GS_DEFINE(OSD_GIVE_ITEM_CHEAT, "Lara's backpack just got way heavier!") @@ -167,7 +166,6 @@ GS_DEFINE(OSD_PERSPECTIVE_FILTER_ON, "Perspective filter enabled") GS_DEFINE(OSD_PERSPECTIVE_FILTER_OFF, "Perspective filter disabled") GS_DEFINE(OSD_FPS_COUNTER_ON, "FPS counter enabled") GS_DEFINE(OSD_FPS_COUNTER_OFF, "FPS counter disabled") -GS_DEFINE(OSD_INVALID_ITEM, "Unknown item: %s") GS_DEFINE(OSD_INVALID_ROOM, "Invalid room: %d. Valid rooms are 0-%d") GS_DEFINE(OSD_INVALID_LEVEL, "Invalid level") GS_DEFINE(OSD_UNKNOWN_COMMAND, "Unknown command: %s") diff --git a/src/game/objects/names.c b/src/game/objects/names.c index 3c13594b3..5d46ede81 100644 --- a/src/game/objects/names.c +++ b/src/game/objects/names.c @@ -216,7 +216,9 @@ static const ITEM_NAME m_ItemNames[] = { { NO_OBJECT, "" }, }; -GAME_OBJECT_ID *Object_IdsFromName(const char *name, int32_t *out_match_count) +GAME_OBJECT_ID *Object_IdsFromName( + const char *const name, int32_t *const out_match_count, + bool (*const filter)(GAME_OBJECT_ID)) { // first, calculate the number of matches to allocate VECTOR *matches = Vector_Create(sizeof(MATCH)); @@ -224,6 +226,9 @@ GAME_OBJECT_ID *Object_IdsFromName(const char *name, int32_t *out_match_count) // Store matches from hardcoded strings for (const ITEM_NAME *desc = m_ItemNames; desc->object_id != NO_OBJECT; desc++) { + if (filter != NULL && !filter(desc->object_id)) { + continue; + } const int32_t match_length = String_Match(name, desc->regex); if (match_length > 0) { MATCH match = { @@ -237,20 +242,25 @@ GAME_OBJECT_ID *Object_IdsFromName(const char *name, int32_t *out_match_count) // Store matches from customizable inventory strings for (const INVENTORY_ITEM *const *item_ptr = m_InvItems; *item_ptr != NULL; item_ptr++) { - const INVENTORY_ITEM *item = *item_ptr; + const INVENTORY_ITEM *const item = *item_ptr; + const GAME_OBJECT_ID object_id = + Object_GetCognateInverse(item->object_id, g_ItemToInvObjectMap); + if (filter != NULL && !filter(object_id)) { + continue; + } + if (String_CaseSubstring(item->string, name)) { MATCH match = { .match_length = strlen(name), - .object_id = Object_GetCognateInverse( - item->object_id, g_ItemToInvObjectMap), + .object_id = object_id, }; Vector_Add(matches, &match); } } // sort by match length so that best-matching results appear first - for (int i = 0; i < matches->count; i++) { - for (int j = i + 1; j < matches->count; j++) { + for (int32_t i = 0; i < matches->count; i++) { + for (int32_t j = i + 1; j < matches->count; j++) { if (((MATCH *)Vector_Get(matches, i))->match_length < ((MATCH *)Vector_Get(matches, j))->match_length) { Vector_Swap(matches, i, j); @@ -291,7 +301,7 @@ GAME_OBJECT_ID *Object_IdsFromName(const char *name, int32_t *out_match_count) return unique_ids; } -const char *Object_GetCanonicalName( +const char *Object_GetName( const GAME_OBJECT_ID object_id, const char *user_input) { for (const INVENTORY_ITEM *const *item_ptr = m_InvItems; *item_ptr != NULL; diff --git a/src/game/objects/names.h b/src/game/objects/names.h index 88bad38a5..7a3d034c3 100644 --- a/src/game/objects/names.h +++ b/src/game/objects/names.h @@ -5,7 +5,8 @@ // Return a list of object ids that match given string. // out_match_count may be NULL. // The result must be freed by the caller. -GAME_OBJECT_ID *Object_IdsFromName(const char *name, int32_t *out_match_count); +GAME_OBJECT_ID *Object_IdsFromName( + const char *name, int32_t *out_match_count, bool (*filter)(GAME_OBJECT_ID)); -const char *Object_GetCanonicalName( +const char *Object_GetName( const GAME_OBJECT_ID object_id, const char *user_input); diff --git a/subprojects/libtrx b/subprojects/libtrx index 39c2d5512..43678a60e 160000 --- a/subprojects/libtrx +++ b/subprojects/libtrx @@ -1 +1 @@ -Subproject commit 39c2d55127f456909c21934ba48f431a0040eac6 +Subproject commit 43678a60e92dc7d9ac8d9259c1e632949a19a5dd From 7d2f02a4f02bec5ecf5d20d6cea9bc891b27048e Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Fri, 20 Sep 2024 23:27:38 +0200 Subject: [PATCH 2/3] console/cmd: follow libtrx folder structure --- meson.build | 22 +- src/game/clock.c | 2 +- src/game/console/cmd/braid.c | 18 + src/game/console/cmd/braid.h | 5 + src/game/console/cmd/cheats.c | 18 + src/game/console/cmd/cheats.h | 5 + src/game/console/cmd/die.c | 32 ++ src/game/console/cmd/die.h | 5 + src/game/console/cmd/end_level.c | 22 + src/game/console/cmd/end_level.h | 5 + src/game/console/cmd/exit_game.c | 17 + src/game/console/cmd/exit_game.h | 5 + src/game/console/cmd/exit_to_title.c | 17 + src/game/console/cmd/exit_to_title.h | 5 + src/game/console/cmd/flipmap.c | 41 ++ src/game/console/cmd/flipmap.h | 5 + src/game/console/cmd/fly.c | 22 + src/game/console/cmd/fly.h | 5 + src/game/console/cmd/fps.c | 18 + src/game/console/cmd/fps.h | 5 + src/game/console/cmd/kill.c | 112 +++++ src/game/console/cmd/kill.h | 5 + src/game/console/cmd/load_game.c | 41 ++ src/game/console/cmd/load_game.h | 5 + src/game/console/cmd/play_demo.c | 17 + src/game/console/cmd/play_demo.h | 5 + src/game/console/cmd/play_level.c | 56 +++ src/game/console/cmd/play_level.h | 5 + src/game/console/cmd/save_game.c | 38 ++ src/game/console/cmd/save_game.h | 5 + src/game/console/cmd/speed.c | 29 ++ src/game/console/cmd/speed.h | 5 + src/game/console/cmd/teleport.c | 156 +++++++ src/game/console/cmd/teleport.h | 5 + src/game/console/cmd/vsync.c | 20 + src/game/console/cmd/vsync.h | 5 + src/game/console/cmd/wireframe.c | 20 + src/game/console/cmd/wireframe.h | 5 + src/game/{console.c => console/common.c} | 5 +- src/game/{console.h => console/common.h} | 0 src/game/console/setup.c | 43 ++ src/game/console/setup.h | 5 + src/game/console_cmd.c | 549 ----------------------- src/game/game/game.c | 2 +- src/game/lara/lara_cheat.c | 2 +- src/game/output.c | 2 +- src/game/phase/phase_inventory.c | 2 +- src/game/shell.c | 2 +- src/specific/s_shell.c | 2 +- subprojects/libtrx | 2 +- 50 files changed, 862 insertions(+), 562 deletions(-) create mode 100644 src/game/console/cmd/braid.c create mode 100644 src/game/console/cmd/braid.h create mode 100644 src/game/console/cmd/cheats.c create mode 100644 src/game/console/cmd/cheats.h create mode 100644 src/game/console/cmd/die.c create mode 100644 src/game/console/cmd/die.h create mode 100644 src/game/console/cmd/end_level.c create mode 100644 src/game/console/cmd/end_level.h create mode 100644 src/game/console/cmd/exit_game.c create mode 100644 src/game/console/cmd/exit_game.h create mode 100644 src/game/console/cmd/exit_to_title.c create mode 100644 src/game/console/cmd/exit_to_title.h create mode 100644 src/game/console/cmd/flipmap.c create mode 100644 src/game/console/cmd/flipmap.h create mode 100644 src/game/console/cmd/fly.c create mode 100644 src/game/console/cmd/fly.h create mode 100644 src/game/console/cmd/fps.c create mode 100644 src/game/console/cmd/fps.h create mode 100644 src/game/console/cmd/kill.c create mode 100644 src/game/console/cmd/kill.h create mode 100644 src/game/console/cmd/load_game.c create mode 100644 src/game/console/cmd/load_game.h create mode 100644 src/game/console/cmd/play_demo.c create mode 100644 src/game/console/cmd/play_demo.h create mode 100644 src/game/console/cmd/play_level.c create mode 100644 src/game/console/cmd/play_level.h create mode 100644 src/game/console/cmd/save_game.c create mode 100644 src/game/console/cmd/save_game.h create mode 100644 src/game/console/cmd/speed.c create mode 100644 src/game/console/cmd/speed.h create mode 100644 src/game/console/cmd/teleport.c create mode 100644 src/game/console/cmd/teleport.h create mode 100644 src/game/console/cmd/vsync.c create mode 100644 src/game/console/cmd/vsync.h create mode 100644 src/game/console/cmd/wireframe.c create mode 100644 src/game/console/cmd/wireframe.h rename src/game/{console.c => console/common.c} (99%) rename src/game/{console.h => console/common.h} (100%) create mode 100644 src/game/console/setup.c create mode 100644 src/game/console/setup.h delete mode 100644 src/game/console_cmd.c diff --git a/meson.build b/meson.build index 12b2d4ed2..10948991f 100644 --- a/meson.build +++ b/meson.build @@ -101,8 +101,26 @@ sources = [ 'src/game/carrier.c', 'src/game/clock.c', 'src/game/collide.c', - 'src/game/console.c', - 'src/game/console_cmd.c', + 'src/game/console/cmd/braid.c', + 'src/game/console/cmd/cheats.c', + 'src/game/console/cmd/die.c', + 'src/game/console/cmd/end_level.c', + 'src/game/console/cmd/exit_game.c', + 'src/game/console/cmd/exit_to_title.c', + 'src/game/console/cmd/flipmap.c', + 'src/game/console/cmd/fly.c', + 'src/game/console/cmd/fps.c', + 'src/game/console/cmd/kill.c', + 'src/game/console/cmd/load_game.c', + 'src/game/console/cmd/play_demo.c', + 'src/game/console/cmd/play_level.c', + 'src/game/console/cmd/save_game.c', + 'src/game/console/cmd/speed.c', + 'src/game/console/cmd/teleport.c', + 'src/game/console/cmd/vsync.c', + 'src/game/console/cmd/wireframe.c', + 'src/game/console/common.c', + 'src/game/console/setup.c', 'src/game/creature.c', 'src/game/effect_routines/bubbles.c', 'src/game/effect_routines/chain_block.c', diff --git a/src/game/clock.c b/src/game/clock.c index 8488d2b7c..3a5c3d125 100644 --- a/src/game/clock.c +++ b/src/game/clock.c @@ -1,7 +1,7 @@ #include "game/clock.h" #include "config.h" -#include "game/console.h" +#include "game/console/common.h" #include "game/game_string.h" #include "global/const.h" diff --git a/src/game/console/cmd/braid.c b/src/game/console/cmd/braid.c new file mode 100644 index 000000000..d3855c21f --- /dev/null +++ b/src/game/console/cmd/braid.c @@ -0,0 +1,18 @@ +#include "game/console/cmd/braid.h" + +#include "config.h" + +#include + +static COMMAND_RESULT M_Entrypoint(const char *const args); + +static COMMAND_RESULT M_Entrypoint(const char *const args) +{ + return Console_Cmd_Config_Helper( + Console_Cmd_Config_GetOptionFromTarget(&g_Config.enable_braid), args); +} + +CONSOLE_COMMAND g_Console_Cmd_Braid = { + .prefix = "braid", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/braid.h b/src/game/console/cmd/braid.h new file mode 100644 index 000000000..86455d5bd --- /dev/null +++ b/src/game/console/cmd/braid.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_Braid; diff --git a/src/game/console/cmd/cheats.c b/src/game/console/cmd/cheats.c new file mode 100644 index 000000000..c032a6759 --- /dev/null +++ b/src/game/console/cmd/cheats.c @@ -0,0 +1,18 @@ +#include "game/console/cmd/cheats.h" + +#include "config.h" + +#include + +static COMMAND_RESULT M_Entrypoint(const char *const args); + +static COMMAND_RESULT M_Entrypoint(const char *const args) +{ + return Console_Cmd_Config_Helper( + Console_Cmd_Config_GetOptionFromTarget(&g_Config.enable_cheats), args); +} + +CONSOLE_COMMAND g_Console_Cmd_Cheats = { + .prefix = "cheats", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/cheats.h b/src/game/console/cmd/cheats.h new file mode 100644 index 000000000..7d44f3364 --- /dev/null +++ b/src/game/console/cmd/cheats.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_Cheats; diff --git a/src/game/console/cmd/die.c b/src/game/console/cmd/die.c new file mode 100644 index 000000000..3dc79934e --- /dev/null +++ b/src/game/console/cmd/die.c @@ -0,0 +1,32 @@ +#include "game/console/cmd/die.h" + +#include "game/effects.h" +#include "game/effects/exploding_death.h" +#include "game/objects/common.h" +#include "game/sound.h" +#include "global/vars.h" + +static COMMAND_RESULT M_Entrypoint(const char *args); + +static COMMAND_RESULT M_Entrypoint(const char *args) +{ + if (!g_Objects[O_LARA].loaded) { + return CR_UNAVAILABLE; + } + + if (g_LaraItem->hit_points <= 0) { + return CR_UNAVAILABLE; + } + + Effect_ExplodingDeath(g_Lara.item_num, -1, 0); + Sound_Effect(SFX_EXPLOSION_CHEAT, &g_LaraItem->pos, SPM_NORMAL); + Sound_Effect(SFX_LARA_FALL, &g_LaraItem->pos, SPM_NORMAL); + g_LaraItem->hit_points = 0; + g_LaraItem->flags |= IS_INVISIBLE; + return CR_SUCCESS; +} + +CONSOLE_COMMAND g_Console_Cmd_Die = { + .prefix = "abortion|natlastinks", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/die.h b/src/game/console/cmd/die.h new file mode 100644 index 000000000..bf50d44b5 --- /dev/null +++ b/src/game/console/cmd/die.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_Die; diff --git a/src/game/console/cmd/end_level.c b/src/game/console/cmd/end_level.c new file mode 100644 index 000000000..ab05033f0 --- /dev/null +++ b/src/game/console/cmd/end_level.c @@ -0,0 +1,22 @@ +#include "game/console/cmd/end_level.h" + +#include "game/lara/lara_cheat.h" + +#include + +static COMMAND_RESULT M_Entrypoint(const char *args); + +static COMMAND_RESULT M_Entrypoint(const char *const args) +{ + if (!String_Equivalent(args, "")) { + return CR_BAD_INVOCATION; + } + + Lara_Cheat_EndLevel(); + return CR_SUCCESS; +} + +CONSOLE_COMMAND g_Console_Cmd_EndLevel = { + .prefix = "endlevel", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/end_level.h b/src/game/console/cmd/end_level.h new file mode 100644 index 000000000..818a1a08e --- /dev/null +++ b/src/game/console/cmd/end_level.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_EndLevel; diff --git a/src/game/console/cmd/exit_game.c b/src/game/console/cmd/exit_game.c new file mode 100644 index 000000000..a413a5035 --- /dev/null +++ b/src/game/console/cmd/exit_game.c @@ -0,0 +1,17 @@ +#include "game/console/cmd/exit_game.h" + +#include "global/vars.h" + +static COMMAND_RESULT M_Entrypoint(const char *args); + +static COMMAND_RESULT M_Entrypoint(const char *args) +{ + g_GameInfo.override_gf_command = + (GAMEFLOW_COMMAND) { .action = GF_EXIT_GAME }; + return CR_SUCCESS; +} + +CONSOLE_COMMAND g_Console_Cmd_ExitGame = { + .prefix = "exit", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/exit_game.h b/src/game/console/cmd/exit_game.h new file mode 100644 index 000000000..a6f367cd1 --- /dev/null +++ b/src/game/console/cmd/exit_game.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_ExitGame; diff --git a/src/game/console/cmd/exit_to_title.c b/src/game/console/cmd/exit_to_title.c new file mode 100644 index 000000000..4475c3321 --- /dev/null +++ b/src/game/console/cmd/exit_to_title.c @@ -0,0 +1,17 @@ +#include "game/console/cmd/exit_to_title.h" + +#include "global/vars.h" + +static COMMAND_RESULT M_Entrypoint(const char *args); + +static COMMAND_RESULT M_Entrypoint(const char *args) +{ + g_GameInfo.override_gf_command = + (GAMEFLOW_COMMAND) { .action = GF_EXIT_TO_TITLE }; + return CR_SUCCESS; +} + +CONSOLE_COMMAND g_Console_Cmd_ExitToTitle = { + .prefix = "title", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/exit_to_title.h b/src/game/console/cmd/exit_to_title.h new file mode 100644 index 000000000..ee8064ddd --- /dev/null +++ b/src/game/console/cmd/exit_to_title.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_ExitToTitle; diff --git a/src/game/console/cmd/flipmap.c b/src/game/console/cmd/flipmap.c new file mode 100644 index 000000000..4a38955c8 --- /dev/null +++ b/src/game/console/cmd/flipmap.c @@ -0,0 +1,41 @@ +#include "game/console/cmd/flipmap.h" + +#include "game/game_string.h" +#include "game/room.h" +#include "global/vars.h" + +#include + +static COMMAND_RESULT M_Entrypoint(const char *args); + +static COMMAND_RESULT M_Entrypoint(const char *args) +{ + if (g_GameInfo.current_level_type == GFL_TITLE + || g_GameInfo.current_level_type == GFL_DEMO + || g_GameInfo.current_level_type == GFL_CUTSCENE) { + return CR_UNAVAILABLE; + } + + bool new_state; + if (String_Equivalent(args, "")) { + new_state = !g_FlipStatus; + } else if (!String_ParseBool(args, &new_state)) { + return CR_BAD_INVOCATION; + } + + if (g_FlipStatus == new_state) { + Console_Log( + new_state ? GS(OSD_FLIPMAP_FAIL_ALREADY_ON) + : GS(OSD_FLIPMAP_FAIL_ALREADY_OFF)); + return CR_SUCCESS; + } + + Room_FlipMap(); + Console_Log(new_state ? GS(OSD_FLIPMAP_ON) : GS(OSD_FLIPMAP_OFF)); + return CR_SUCCESS; +} + +CONSOLE_COMMAND g_Console_Cmd_FlipMap = { + .prefix = "flip|flipmap", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/flipmap.h b/src/game/console/cmd/flipmap.h new file mode 100644 index 000000000..1f9786ddc --- /dev/null +++ b/src/game/console/cmd/flipmap.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_FlipMap; diff --git a/src/game/console/cmd/fly.c b/src/game/console/cmd/fly.c new file mode 100644 index 000000000..5900ef5f3 --- /dev/null +++ b/src/game/console/cmd/fly.c @@ -0,0 +1,22 @@ +#include "game/console/cmd/fly.h" + +#include "game/game.h" +#include "game/game_string.h" +#include "game/lara/lara_cheat.h" + +static COMMAND_RESULT M_Entrypoint(const char *const args); + +static COMMAND_RESULT M_Entrypoint(const char *const args) +{ + if (!Game_IsPlayable()) { + return CR_UNAVAILABLE; + } + Console_Log(GS(OSD_FLY_MODE_ON)); + Lara_Cheat_EnterFlyMode(); + return CR_SUCCESS; +} + +CONSOLE_COMMAND g_Console_Cmd_Fly = { + .prefix = "fly", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/fly.h b/src/game/console/cmd/fly.h new file mode 100644 index 000000000..24e195a5f --- /dev/null +++ b/src/game/console/cmd/fly.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_Fly; diff --git a/src/game/console/cmd/fps.c b/src/game/console/cmd/fps.c new file mode 100644 index 000000000..1390bb55c --- /dev/null +++ b/src/game/console/cmd/fps.c @@ -0,0 +1,18 @@ +#include "game/console/cmd/fps.h" + +#include "config.h" + +#include + +static COMMAND_RESULT M_Entrypoint(const char *const args); + +static COMMAND_RESULT M_Entrypoint(const char *const args) +{ + return Console_Cmd_Config_Helper( + Console_Cmd_Config_GetOptionFromTarget(&g_Config.rendering.fps), args); +} + +CONSOLE_COMMAND g_Console_Cmd_FPS = { + .prefix = "fps", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/fps.h b/src/game/console/cmd/fps.h new file mode 100644 index 000000000..6ee3103af --- /dev/null +++ b/src/game/console/cmd/fps.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_FPS; diff --git a/src/game/console/cmd/kill.c b/src/game/console/cmd/kill.c new file mode 100644 index 000000000..1581b9812 --- /dev/null +++ b/src/game/console/cmd/kill.c @@ -0,0 +1,112 @@ +#include "game/console/cmd/kill.h" + +#include "game/game_string.h" +#include "game/items.h" +#include "game/lara.h" +#include "game/lara/lara_cheat.h" +#include "game/objects/common.h" +#include "game/objects/names.h" +#include "game/sound.h" +#include "global/vars.h" + +#include +#include +#include + +static bool M_CanTargetObject_Enemy(GAME_OBJECT_ID object_id); +static COMMAND_RESULT M_Entrypoint(const char *args); + +static bool M_CanTargetObject_Enemy(const GAME_OBJECT_ID object_id) +{ + return Object_IsObjectType(object_id, g_EnemyObjects); +} + +static COMMAND_RESULT M_Entrypoint(const char *args) +{ + if (g_GameInfo.current_level_type == GFL_TITLE + || g_GameInfo.current_level_type == GFL_DEMO + || g_GameInfo.current_level_type == GFL_CUTSCENE) { + return CR_UNAVAILABLE; + } + + // kill all the enemies in the level + if (String_Equivalent(args, "all")) { + int32_t num = 0; + for (int16_t item_num = 0; item_num < Item_GetTotalCount(); + item_num++) { + if (Lara_Cheat_KillEnemy(item_num)) { + num++; + } + } + + if (num == 0) { + Console_Log(GS(OSD_KILL_ALL_FAIL), num); + return CR_FAILURE; + } + + Sound_Effect(SFX_EXPLOSION_CHEAT, &g_LaraItem->pos, SPM_NORMAL); + Console_Log(GS(OSD_KILL_ALL), num); + return CR_SUCCESS; + } + + // kill all the enemies around Lara within one tile, or a single nearest + // enemy + if (String_Equivalent(args, "")) { + bool found = false; + while (true) { + const int16_t best_item_num = Lara_GetNearestEnemy(); + if (best_item_num == NO_ITEM) { + break; + } + + ITEM_INFO *const item = &g_Items[best_item_num]; + const int32_t distance = Item_GetDistance(item, &g_LaraItem->pos); + found |= Lara_Cheat_KillEnemy(best_item_num); + if (distance >= WALL_L) { + break; + } + } + + if (!found) { + Console_Log(GS(OSD_KILL_FAIL)); + return CR_FAILURE; + } + + Console_Log(GS(OSD_KILL)); + return CR_SUCCESS; + } + + // kill a single enemy type + { + int32_t match_count = 0; + GAME_OBJECT_ID *matching_objs = + Object_IdsFromName(args, &match_count, M_CanTargetObject_Enemy); + int32_t num = 0; + for (int32_t i = 0; i < match_count; i++) { + const GAME_OBJECT_ID object_id = matching_objs[i]; + for (int16_t item_num = 0; item_num < Item_GetTotalCount(); + item_num++) { + if (g_Items[item_num].object_id == object_id + && Lara_Cheat_KillEnemy(item_num)) { + num++; + } + } + } + Memory_FreePointer(&matching_objs); + + if (!match_count) { + return CR_BAD_INVOCATION; + } + if (num == 0) { + Console_Log(GS(OSD_KILL_ALL_FAIL)); + return CR_FAILURE; + } + Console_Log(GS(OSD_KILL_ALL), num); + return CR_SUCCESS; + } +} + +CONSOLE_COMMAND g_Console_Cmd_Kill = { + .prefix = "kill", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/kill.h b/src/game/console/cmd/kill.h new file mode 100644 index 000000000..3766fe1f8 --- /dev/null +++ b/src/game/console/cmd/kill.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_Kill; diff --git a/src/game/console/cmd/load_game.c b/src/game/console/cmd/load_game.c new file mode 100644 index 000000000..a3aa0027e --- /dev/null +++ b/src/game/console/cmd/load_game.c @@ -0,0 +1,41 @@ +#include "game/console/cmd/load_game.h" + +#include "config.h" +#include "game/game_string.h" +#include "global/vars.h" + +#include + +static COMMAND_RESULT M_Entrypoint(const char *args); + +static COMMAND_RESULT M_Entrypoint(const char *args) +{ + int32_t slot_num; + if (!String_ParseInteger(args, &slot_num)) { + return CR_BAD_INVOCATION; + } + + const int32_t slot_idx = slot_num - 1; // convert 1-indexing to 0-indexing + + if (slot_idx < 0 || slot_idx >= g_Config.maximum_save_slots) { + Console_Log(GS(OSD_LOAD_GAME_FAIL_INVALID_SLOT), slot_num); + return CR_FAILURE; + } + + if (g_SavegameRequester.items[slot_idx].is_blocked) { + Console_Log(GS(OSD_LOAD_GAME_FAIL_UNAVAILABLE_SLOT), slot_num); + return CR_FAILURE; + } + + g_GameInfo.override_gf_command = (GAMEFLOW_COMMAND) { + .action = GF_START_SAVED_GAME, + .param = slot_idx, + }; + Console_Log(GS(OSD_LOAD_GAME), slot_num); + return CR_SUCCESS; +} + +CONSOLE_COMMAND g_Console_Cmd_LoadGame = { + .prefix = "load", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/load_game.h b/src/game/console/cmd/load_game.h new file mode 100644 index 000000000..6bf43395c --- /dev/null +++ b/src/game/console/cmd/load_game.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_LoadGame; diff --git a/src/game/console/cmd/play_demo.c b/src/game/console/cmd/play_demo.c new file mode 100644 index 000000000..835b6d32d --- /dev/null +++ b/src/game/console/cmd/play_demo.c @@ -0,0 +1,17 @@ +#include "game/console/cmd/play_demo.h" + +#include "global/vars.h" + +static COMMAND_RESULT M_Entrypoint(const char *args); + +static COMMAND_RESULT M_Entrypoint(const char *args) +{ + g_GameInfo.override_gf_command = + (GAMEFLOW_COMMAND) { .action = GF_START_DEMO }; + return CR_SUCCESS; +} + +CONSOLE_COMMAND g_Console_Cmd_PlayDemo = { + .prefix = "demo", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/play_demo.h b/src/game/console/cmd/play_demo.h new file mode 100644 index 000000000..51c80a8ef --- /dev/null +++ b/src/game/console/cmd/play_demo.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_PlayDemo; diff --git a/src/game/console/cmd/play_level.c b/src/game/console/cmd/play_level.c new file mode 100644 index 000000000..c90cdb3a8 --- /dev/null +++ b/src/game/console/cmd/play_level.c @@ -0,0 +1,56 @@ +#include "game/console/cmd/play_level.h" + +#include "game/game_string.h" +#include "game/gameflow.h" +#include "global/vars.h" + +#include + +static COMMAND_RESULT M_Entrypoint(const char *args); + +static COMMAND_RESULT M_Entrypoint(const char *const args) +{ + if (String_Equivalent(args, "")) { + return CR_BAD_INVOCATION; + } + + int32_t level_to_load = -1; + if (!String_ParseInteger(args, &level_to_load)) { + for (int i = 0; i < g_GameFlow.level_count; i++) { + if (String_CaseSubstring(g_GameFlow.levels[i].level_title, args) + != NULL) { + level_to_load = i; + break; + } + } + if (level_to_load == -1 && String_Equivalent(args, "gym")) { + level_to_load = g_GameFlow.gym_level_num; + } + if (level_to_load == -1) { + Console_Log(GS(OSD_INVALID_LEVEL)); + return CR_FAILURE; + } + } + + if (level_to_load == -1) { + return CR_BAD_INVOCATION; + } + + if (level_to_load >= g_GameFlow.level_count) { + Console_Log(GS(OSD_INVALID_LEVEL)); + return CR_FAILURE; + } + + g_GameInfo.override_gf_command = (GAMEFLOW_COMMAND) { + .action = GF_SELECT_GAME, + .param = level_to_load, + }; + Console_Log( + GS(OSD_PLAY_LEVEL), g_GameFlow.levels[level_to_load].level_title); + return CR_SUCCESS; +} + +CONSOLE_COMMAND g_Console_Cmd_PlayLevel = { + .prefix = "play|level", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/play_level.h b/src/game/console/cmd/play_level.h new file mode 100644 index 000000000..200cc8c77 --- /dev/null +++ b/src/game/console/cmd/play_level.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_PlayLevel; diff --git a/src/game/console/cmd/save_game.c b/src/game/console/cmd/save_game.c new file mode 100644 index 000000000..de88562b4 --- /dev/null +++ b/src/game/console/cmd/save_game.c @@ -0,0 +1,38 @@ +#include "game/console/cmd/save_game.h" + +#include "config.h" +#include "game/game.h" +#include "game/game_string.h" +#include "game/savegame.h" +#include "global/vars.h" + +#include + +static COMMAND_RESULT M_Entrypoint(const char *args); + +static COMMAND_RESULT M_Entrypoint(const char *args) +{ + if (!Game_IsPlayable()) { + return CR_UNAVAILABLE; + } + + int32_t slot_num; + if (!String_ParseInteger(args, &slot_num)) { + return CR_BAD_INVOCATION; + } + const int32_t slot_idx = slot_num - 1; // convert 1-indexing to 0-indexing + + if (slot_idx < 0 || slot_idx >= g_Config.maximum_save_slots) { + Console_Log(GS(OSD_SAVE_GAME_FAIL_INVALID_SLOT), slot_num); + return CR_BAD_INVOCATION; + } + + Savegame_Save(slot_idx, &g_GameInfo); + Console_Log(GS(OSD_SAVE_GAME), slot_num); + return CR_SUCCESS; +} + +CONSOLE_COMMAND g_Console_Cmd_SaveGame = { + .prefix = "save", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/save_game.h b/src/game/console/cmd/save_game.h new file mode 100644 index 000000000..26cab28fe --- /dev/null +++ b/src/game/console/cmd/save_game.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_SaveGame; diff --git a/src/game/console/cmd/speed.c b/src/game/console/cmd/speed.c new file mode 100644 index 000000000..80a7783b3 --- /dev/null +++ b/src/game/console/cmd/speed.c @@ -0,0 +1,29 @@ +#include "game/console/cmd/speed.h" + +#include "game/clock.h" +#include "game/game_string.h" + +#include + +static COMMAND_RESULT M_Entrypoint(const char *const args); + +static COMMAND_RESULT M_Entrypoint(const char *const args) +{ + if (String_Equivalent(args, "")) { + Console_Log(GS(OSD_SPEED_GET), Clock_GetTurboSpeed()); + return CR_SUCCESS; + } + + int32_t num = -1; + if (String_ParseInteger(args, &num)) { + Clock_SetTurboSpeed(num); + return CR_SUCCESS; + } + + return CR_BAD_INVOCATION; +} + +CONSOLE_COMMAND g_Console_Cmd_Speed = { + .prefix = "speed", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/speed.h b/src/game/console/cmd/speed.h new file mode 100644 index 000000000..c7a5866d6 --- /dev/null +++ b/src/game/console/cmd/speed.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_Speed; diff --git a/src/game/console/cmd/teleport.c b/src/game/console/cmd/teleport.c new file mode 100644 index 000000000..4a24cb673 --- /dev/null +++ b/src/game/console/cmd/teleport.c @@ -0,0 +1,156 @@ +#include "game/console/cmd/teleport.h" + +#include "game/game_string.h" +#include "game/items.h" +#include "game/lara/lara_cheat.h" +#include "game/objects/common.h" +#include "game/objects/names.h" +#include "game/random.h" +#include "game/room.h" +#include "global/const.h" +#include "global/vars.h" + +#include + +#include +#include + +static bool M_IsFloatRound(const float num); +; +static COMMAND_RESULT M_Entrypoint(const char *const args); + +static inline bool M_IsFloatRound(const float num) +{ + return (fabsf(num) - roundf(num)) < 0.0001f; +} + +static COMMAND_RESULT M_Entrypoint(const char *const args) +{ + if (g_GameInfo.current_level_type == GFL_TITLE + || g_GameInfo.current_level_type == GFL_DEMO + || g_GameInfo.current_level_type == GFL_CUTSCENE) { + return CR_UNAVAILABLE; + } + + if (!g_Objects[O_LARA].loaded || !g_LaraItem->hit_points) { + return CR_UNAVAILABLE; + } + + // X Y Z + { + float x, y, z; + if (sscanf(args, "%f %f %f", &x, &y, &z) == 3) { + if (M_IsFloatRound(x)) { + x += 0.5f; + } + if (M_IsFloatRound(z)) { + z += 0.5f; + } + + if (Lara_Cheat_Teleport(x * WALL_L, y * WALL_L, z * WALL_L)) { + Console_Log(GS(OSD_POS_SET_POS), x, y, z); + return CR_SUCCESS; + } + + Console_Log(GS(OSD_POS_SET_POS_FAIL), x, y, z); + return CR_FAILURE; + } + } + + // Room number + { + int16_t room_num = NO_ROOM; + if (sscanf(args, "%hd", &room_num) == 1) { + if (room_num < 0 || room_num >= g_RoomCount) { + Console_Log(GS(OSD_INVALID_ROOM), room_num, g_RoomCount - 1); + return CR_SUCCESS; + } + + const ROOM_INFO *const room = &g_RoomInfo[room_num]; + + const int32_t x1 = room->x + WALL_L; + const int32_t x2 = (room->x_size << WALL_SHIFT) + room->x - WALL_L; + const int32_t y1 = room->min_floor; + const int32_t y2 = room->max_ceiling; + const int32_t z1 = room->z + WALL_L; + const int32_t z2 = (room->z_size << WALL_SHIFT) + room->z - WALL_L; + + for (int i = 0; i < 100; i++) { + int32_t x = x1 + Random_GetControl() * (x2 - x1) / 0x7FFF; + int32_t y = y1; + int32_t z = z1 + Random_GetControl() * (z2 - z1) / 0x7FFF; + if (Lara_Cheat_Teleport(x, y, z)) { + Console_Log(GS(OSD_POS_SET_ROOM), room_num); + return CR_SUCCESS; + } + } + + Console_Log(GS(OSD_POS_SET_ROOM_FAIL), room_num); + return CR_FAILURE; + } + } + + // Nearest item of this name + if (!String_Equivalent(args, "")) { + int32_t match_count = 0; + GAME_OBJECT_ID *matching_objs = + Object_IdsFromName(args, &match_count, NULL); + + const ITEM_INFO *best_item = NULL; + int32_t best_distance = INT32_MAX; + + for (int16_t item_num = 0; item_num < Item_GetTotalCount(); + item_num++) { + const ITEM_INFO *const item = &g_Items[item_num]; + const bool is_consumable = + Object_IsObjectType(item->object_id, g_PickupObjects) + || item->object_id == O_SAVEGAME_ITEM; + if (is_consumable + && (item->status == IS_INVISIBLE + || item->status == IS_DEACTIVATED)) { + continue; + } + + if (item->flags & IF_KILLED_ITEM) { + continue; + } + + bool is_matched = false; + for (int32_t i = 0; i < match_count; i++) { + if (matching_objs[i] == item->object_id) { + is_matched = true; + break; + } + } + if (!is_matched) { + continue; + } + + const int32_t distance = Item_GetDistance(item, &g_LaraItem->pos); + if (distance < best_distance) { + best_distance = distance; + best_item = item; + } + } + + if (best_item != NULL) { + if (Lara_Cheat_Teleport( + best_item->pos.x, best_item->pos.y, best_item->pos.z)) { + Console_Log(GS(OSD_POS_SET_ITEM), args); + } else { + Console_Log(GS(OSD_POS_SET_ITEM_FAIL), args); + } + return CR_SUCCESS; + } else { + Console_Log(GS(OSD_POS_SET_ITEM_FAIL), args); + return CR_FAILURE; + } + } + + return CR_BAD_INVOCATION; +} + +CONSOLE_COMMAND g_Console_Cmd_Teleport = { + .prefix = "tp", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/teleport.h b/src/game/console/cmd/teleport.h new file mode 100644 index 000000000..be17673b4 --- /dev/null +++ b/src/game/console/cmd/teleport.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_Teleport; diff --git a/src/game/console/cmd/vsync.c b/src/game/console/cmd/vsync.c new file mode 100644 index 000000000..0f434475f --- /dev/null +++ b/src/game/console/cmd/vsync.c @@ -0,0 +1,20 @@ +#include "game/console/cmd/vsync.h" + +#include "config.h" + +#include + +static COMMAND_RESULT M_Entrypoint(const char *const args); + +static COMMAND_RESULT M_Entrypoint(const char *const args) +{ + return Console_Cmd_Config_Helper( + Console_Cmd_Config_GetOptionFromTarget( + &g_Config.rendering.enable_vsync), + args); +} + +CONSOLE_COMMAND g_Console_Cmd_VSync = { + .prefix = "vsync", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/vsync.h b/src/game/console/cmd/vsync.h new file mode 100644 index 000000000..60330b72c --- /dev/null +++ b/src/game/console/cmd/vsync.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_VSync; diff --git a/src/game/console/cmd/wireframe.c b/src/game/console/cmd/wireframe.c new file mode 100644 index 000000000..2c6f482a6 --- /dev/null +++ b/src/game/console/cmd/wireframe.c @@ -0,0 +1,20 @@ +#include "game/console/cmd/wireframe.h" + +#include "config.h" + +#include + +static COMMAND_RESULT M_Entrypoint(const char *const args); + +static COMMAND_RESULT M_Entrypoint(const char *const args) +{ + return Console_Cmd_Config_Helper( + Console_Cmd_Config_GetOptionFromTarget( + &g_Config.rendering.enable_wireframe), + args); +} + +CONSOLE_COMMAND g_Console_Cmd_Wireframe = { + .prefix = "wireframe", + .proc = M_Entrypoint, +}; diff --git a/src/game/console/cmd/wireframe.h b/src/game/console/cmd/wireframe.h new file mode 100644 index 000000000..6c184c589 --- /dev/null +++ b/src/game/console/cmd/wireframe.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND g_Console_Cmd_Wireframe; diff --git a/src/game/console.c b/src/game/console/common.c similarity index 99% rename from src/game/console.c rename to src/game/console/common.c index 8adba2aea..addb53e79 100644 --- a/src/game/console.c +++ b/src/game/console/common.c @@ -1,7 +1,8 @@ -#include "game/console.h" +#include "game/console/common.h" #include "config.h" #include "game/clock.h" +#include "game/console/setup.h" #include "game/game_string.h" #include "game/input.h" #include "game/output.h" @@ -54,8 +55,6 @@ static void M_UpdatePromptTextstring(void); static void M_UpdateCaretTextstring(void); static COMMAND_RESULT M_Eval(const char *const cmdline); -extern CONSOLE_COMMAND *g_ConsoleCommands[]; - static void M_UpdatePromptTextstring(void) { Text_ChangeText(m_Prompt.prompt_ts, m_Prompt.text); diff --git a/src/game/console.h b/src/game/console/common.h similarity index 100% rename from src/game/console.h rename to src/game/console/common.h diff --git a/src/game/console/setup.c b/src/game/console/setup.c new file mode 100644 index 000000000..368ec1783 --- /dev/null +++ b/src/game/console/setup.c @@ -0,0 +1,43 @@ +#include "game/console/setup.h" + +#include "game/console/cmd/braid.h" +#include "game/console/cmd/cheats.h" +#include "game/console/cmd/die.h" +#include "game/console/cmd/end_level.h" +#include "game/console/cmd/exit_game.h" +#include "game/console/cmd/exit_to_title.h" +#include "game/console/cmd/flipmap.h" +#include "game/console/cmd/fly.h" +#include "game/console/cmd/fps.h" +#include "game/console/cmd/kill.h" +#include "game/console/cmd/load_game.h" +#include "game/console/cmd/play_demo.h" +#include "game/console/cmd/play_level.h" +#include "game/console/cmd/save_game.h" +#include "game/console/cmd/speed.h" +#include "game/console/cmd/teleport.h" +#include "game/console/cmd/vsync.h" +#include "game/console/cmd/wireframe.h" + +#include +#include +#include +#include +#include + +#include + +CONSOLE_COMMAND *g_ConsoleCommands[] = { + &g_Console_Cmd_Braid, &g_Console_Cmd_FPS, + &g_Console_Cmd_VSync, &g_Console_Cmd_Wireframe, + &g_Console_Cmd_Cheats, &g_Console_Cmd_Teleport, + &g_Console_Cmd_Fly, &g_Console_Cmd_Speed, + &g_Console_Cmd_FlipMap, &g_Console_Cmd_Kill, + &g_Console_Cmd_EndLevel, &g_Console_Cmd_PlayLevel, + &g_Console_Cmd_LoadGame, &g_Console_Cmd_SaveGame, + &g_Console_Cmd_PlayDemo, &g_Console_Cmd_ExitGame, + &g_Console_Cmd_ExitToTitle, &g_Console_Cmd_Die, + &g_Console_Cmd_Pos, &g_Console_Cmd_Heal, + &g_Console_Cmd_SetHealth, &g_Console_Cmd_Config, + &g_Console_Cmd_GiveItem, NULL, +}; diff --git a/src/game/console/setup.h b/src/game/console/setup.h new file mode 100644 index 000000000..11f2f9671 --- /dev/null +++ b/src/game/console/setup.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern CONSOLE_COMMAND *g_ConsoleCommands[]; diff --git a/src/game/console_cmd.c b/src/game/console_cmd.c deleted file mode 100644 index bc423ba42..000000000 --- a/src/game/console_cmd.c +++ /dev/null @@ -1,549 +0,0 @@ -#include "config.h" -#include "config_map.h" -#include "game/clock.h" -#include "game/console.h" -#include "game/effects/exploding_death.h" -#include "game/game_string.h" -#include "game/gameflow.h" -#include "game/inventory.h" -#include "game/items.h" -#include "game/lara.h" -#include "game/lara/lara_cheat.h" -#include "game/objects/common.h" -#include "game/objects/names.h" -#include "game/output.h" -#include "game/random.h" -#include "game/room.h" -#include "game/savegame.h" -#include "game/sound.h" -#include "global/const.h" -#include "global/enum_str.h" -#include "global/types.h" -#include "global/vars.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -static bool M_CanTargetObject_Enemy(GAME_OBJECT_ID object_id); -static bool M_IsFloatRound(const float num); -static COMMAND_RESULT Console_Cmd_Fps(const char *const args); -static COMMAND_RESULT Console_Cmd_VSync(const char *const args); -static COMMAND_RESULT Console_Cmd_Wireframe(const char *const args); -static COMMAND_RESULT Console_Cmd_Braid(const char *const args); -static COMMAND_RESULT Console_Cmd_Cheats(const char *const args); -static COMMAND_RESULT Console_Cmd_Teleport(const char *const args); -static COMMAND_RESULT Console_Cmd_Fly(const char *const args); -static COMMAND_RESULT Console_Cmd_Speed(const char *const args); -static COMMAND_RESULT Console_Cmd_FlipMap(const char *args); -static COMMAND_RESULT Console_Cmd_Kill(const char *args); -static COMMAND_RESULT Console_Cmd_LoadGame(const char *args); -static COMMAND_RESULT Console_Cmd_SaveGame(const char *args); -static COMMAND_RESULT Console_Cmd_StartDemo(const char *args); -static COMMAND_RESULT Console_Cmd_ExitToTitle(const char *args); -static COMMAND_RESULT Console_Cmd_ExitGame(const char *args); -static COMMAND_RESULT Console_Cmd_EndLevel(const char *args); -static COMMAND_RESULT Console_Cmd_StartLevel(const char *args); -static COMMAND_RESULT Console_Cmd_Abortion(const char *args); - -static bool M_CanTargetObject_Enemy(const GAME_OBJECT_ID object_id) -{ - return Object_IsObjectType(object_id, g_EnemyObjects); -} - -static inline bool M_IsFloatRound(const float num) -{ - return (fabsf(num) - roundf(num)) < 0.0001f; -} - -static COMMAND_RESULT Console_Cmd_Fps(const char *const args) -{ - return Console_Cmd_Config_Helper( - Console_Cmd_Config_GetOptionFromTarget(&g_Config.rendering.fps), args); -} - -static COMMAND_RESULT Console_Cmd_VSync(const char *const args) -{ - return Console_Cmd_Config_Helper( - Console_Cmd_Config_GetOptionFromTarget( - &g_Config.rendering.enable_vsync), - args); -} - -static COMMAND_RESULT Console_Cmd_Wireframe(const char *const args) -{ - return Console_Cmd_Config_Helper( - Console_Cmd_Config_GetOptionFromTarget( - &g_Config.rendering.enable_wireframe), - args); -} - -static COMMAND_RESULT Console_Cmd_Braid(const char *const args) -{ - return Console_Cmd_Config_Helper( - Console_Cmd_Config_GetOptionFromTarget(&g_Config.enable_braid), args); -} - -static COMMAND_RESULT Console_Cmd_Cheats(const char *const args) -{ - return Console_Cmd_Config_Helper( - Console_Cmd_Config_GetOptionFromTarget(&g_Config.enable_cheats), args); -} - -static COMMAND_RESULT Console_Cmd_Teleport(const char *const args) -{ - if (g_GameInfo.current_level_type == GFL_TITLE - || g_GameInfo.current_level_type == GFL_DEMO - || g_GameInfo.current_level_type == GFL_CUTSCENE) { - return CR_UNAVAILABLE; - } - - if (!g_Objects[O_LARA].loaded || !g_LaraItem->hit_points) { - return CR_UNAVAILABLE; - } - - // X Y Z - { - float x, y, z; - if (sscanf(args, "%f %f %f", &x, &y, &z) == 3) { - if (M_IsFloatRound(x)) { - x += 0.5f; - } - if (M_IsFloatRound(z)) { - z += 0.5f; - } - - if (Lara_Cheat_Teleport(x * WALL_L, y * WALL_L, z * WALL_L)) { - Console_Log(GS(OSD_POS_SET_POS), x, y, z); - return CR_SUCCESS; - } - - Console_Log(GS(OSD_POS_SET_POS_FAIL), x, y, z); - return CR_FAILURE; - } - } - - // Room number - { - int16_t room_num = NO_ROOM; - if (sscanf(args, "%hd", &room_num) == 1) { - if (room_num < 0 || room_num >= g_RoomCount) { - Console_Log(GS(OSD_INVALID_ROOM), room_num, g_RoomCount - 1); - return CR_SUCCESS; - } - - const ROOM_INFO *const room = &g_RoomInfo[room_num]; - - const int32_t x1 = room->x + WALL_L; - const int32_t x2 = (room->x_size << WALL_SHIFT) + room->x - WALL_L; - const int32_t y1 = room->min_floor; - const int32_t y2 = room->max_ceiling; - const int32_t z1 = room->z + WALL_L; - const int32_t z2 = (room->z_size << WALL_SHIFT) + room->z - WALL_L; - - for (int i = 0; i < 100; i++) { - int32_t x = x1 + Random_GetControl() * (x2 - x1) / 0x7FFF; - int32_t y = y1; - int32_t z = z1 + Random_GetControl() * (z2 - z1) / 0x7FFF; - if (Lara_Cheat_Teleport(x, y, z)) { - Console_Log(GS(OSD_POS_SET_ROOM), room_num); - return CR_SUCCESS; - } - } - - Console_Log(GS(OSD_POS_SET_ROOM_FAIL), room_num); - return CR_FAILURE; - } - } - - // Nearest item of this name - if (!String_Equivalent(args, "")) { - int32_t match_count = 0; - GAME_OBJECT_ID *matching_objs = - Object_IdsFromName(args, &match_count, NULL); - - const ITEM_INFO *best_item = NULL; - int32_t best_distance = INT32_MAX; - - for (int16_t item_num = 0; item_num < Item_GetTotalCount(); - item_num++) { - const ITEM_INFO *const item = &g_Items[item_num]; - const bool is_consumable = - Object_IsObjectType(item->object_id, g_PickupObjects) - || item->object_id == O_SAVEGAME_ITEM; - if (is_consumable - && (item->status == IS_INVISIBLE - || item->status == IS_DEACTIVATED)) { - continue; - } - - if (item->flags & IF_KILLED_ITEM) { - continue; - } - - bool is_matched = false; - for (int32_t i = 0; i < match_count; i++) { - if (matching_objs[i] == item->object_id) { - is_matched = true; - break; - } - } - if (!is_matched) { - continue; - } - - const int32_t distance = Item_GetDistance(item, &g_LaraItem->pos); - if (distance < best_distance) { - best_distance = distance; - best_item = item; - } - } - - if (best_item != NULL) { - if (Lara_Cheat_Teleport( - best_item->pos.x, best_item->pos.y, best_item->pos.z)) { - Console_Log(GS(OSD_POS_SET_ITEM), args); - } else { - Console_Log(GS(OSD_POS_SET_ITEM_FAIL), args); - } - return CR_SUCCESS; - } else { - Console_Log(GS(OSD_POS_SET_ITEM_FAIL), args); - return CR_FAILURE; - } - } - - return CR_BAD_INVOCATION; -} - -static COMMAND_RESULT Console_Cmd_Fly(const char *const args) -{ - if (g_GameInfo.current_level_type == GFL_TITLE - || g_GameInfo.current_level_type == GFL_DEMO - || g_GameInfo.current_level_type == GFL_CUTSCENE) { - return CR_UNAVAILABLE; - } - - if (!g_Objects[O_LARA].loaded) { - return CR_UNAVAILABLE; - } - Console_Log(GS(OSD_FLY_MODE_ON)); - Lara_Cheat_EnterFlyMode(); - return CR_SUCCESS; -} - -static COMMAND_RESULT Console_Cmd_Speed(const char *const args) -{ - if (String_Equivalent(args, "")) { - Console_Log(GS(OSD_SPEED_GET), Clock_GetTurboSpeed()); - return CR_SUCCESS; - } - - int32_t num = -1; - if (sscanf(args, "%d", &num) == 1) { - Clock_SetTurboSpeed(num); - return CR_SUCCESS; - } - - return CR_BAD_INVOCATION; -} - -static COMMAND_RESULT Console_Cmd_FlipMap(const char *args) -{ - if (g_GameInfo.current_level_type == GFL_TITLE - || g_GameInfo.current_level_type == GFL_DEMO - || g_GameInfo.current_level_type == GFL_CUTSCENE) { - return CR_UNAVAILABLE; - } - - bool new_state; - if (String_Equivalent(args, "")) { - new_state = !g_FlipStatus; - } else if (!String_ParseBool(args, &new_state)) { - return CR_BAD_INVOCATION; - } - - if (g_FlipStatus == new_state) { - Console_Log( - new_state ? GS(OSD_FLIPMAP_FAIL_ALREADY_ON) - : GS(OSD_FLIPMAP_FAIL_ALREADY_OFF)); - return CR_SUCCESS; - } - - Room_FlipMap(); - Console_Log(new_state ? GS(OSD_FLIPMAP_ON) : GS(OSD_FLIPMAP_OFF)); - return CR_SUCCESS; -} - -static COMMAND_RESULT Console_Cmd_Kill(const char *args) -{ - if (g_GameInfo.current_level_type == GFL_TITLE - || g_GameInfo.current_level_type == GFL_DEMO - || g_GameInfo.current_level_type == GFL_CUTSCENE) { - return CR_UNAVAILABLE; - } - - // kill all the enemies in the level - if (String_Equivalent(args, "all")) { - int32_t num = 0; - for (int16_t item_num = 0; item_num < Item_GetTotalCount(); - item_num++) { - if (Lara_Cheat_KillEnemy(item_num)) { - num++; - } - } - - if (num == 0) { - Console_Log(GS(OSD_KILL_ALL_FAIL), num); - return CR_FAILURE; - } - - Sound_Effect(SFX_EXPLOSION_CHEAT, &g_LaraItem->pos, SPM_NORMAL); - Console_Log(GS(OSD_KILL_ALL), num); - return CR_SUCCESS; - } - - // kill all the enemies around Lara within one tile, or a single nearest - // enemy - if (String_Equivalent(args, "")) { - bool found = false; - while (true) { - const int16_t best_item_num = Lara_GetNearestEnemy(); - if (best_item_num == NO_ITEM) { - break; - } - - ITEM_INFO *const item = &g_Items[best_item_num]; - const int32_t distance = Item_GetDistance(item, &g_LaraItem->pos); - found |= Lara_Cheat_KillEnemy(best_item_num); - if (distance >= WALL_L) { - break; - } - } - - if (!found) { - Console_Log(GS(OSD_KILL_FAIL)); - return CR_FAILURE; - } - - Console_Log(GS(OSD_KILL)); - return CR_SUCCESS; - } - - // kill a single enemy type - { - int32_t match_count = 0; - GAME_OBJECT_ID *matching_objs = - Object_IdsFromName(args, &match_count, M_CanTargetObject_Enemy); - int32_t num = 0; - for (int32_t i = 0; i < match_count; i++) { - const GAME_OBJECT_ID object_id = matching_objs[i]; - for (int16_t item_num = 0; item_num < Item_GetTotalCount(); - item_num++) { - if (g_Items[item_num].object_id == object_id - && Lara_Cheat_KillEnemy(item_num)) { - num++; - } - } - } - Memory_FreePointer(&matching_objs); - - if (!match_count) { - return CR_BAD_INVOCATION; - } - if (num == 0) { - Console_Log(GS(OSD_KILL_ALL_FAIL)); - return CR_FAILURE; - } - Console_Log(GS(OSD_KILL_ALL), num); - return CR_SUCCESS; - } -} - -static COMMAND_RESULT Console_Cmd_StartDemo(const char *args) -{ - g_GameInfo.override_gf_command = - (GAMEFLOW_COMMAND) { .action = GF_START_DEMO }; - return CR_SUCCESS; -} - -static COMMAND_RESULT Console_Cmd_ExitToTitle(const char *args) -{ - g_GameInfo.override_gf_command = - (GAMEFLOW_COMMAND) { .action = GF_EXIT_TO_TITLE }; - return CR_SUCCESS; -} - -static COMMAND_RESULT Console_Cmd_ExitGame(const char *args) -{ - g_GameInfo.override_gf_command = - (GAMEFLOW_COMMAND) { .action = GF_EXIT_GAME }; - return CR_SUCCESS; -} - -static COMMAND_RESULT Console_Cmd_LoadGame(const char *args) -{ - int32_t slot_num; - if (!String_ParseInteger(args, &slot_num)) { - return CR_BAD_INVOCATION; - } - - const int32_t slot_idx = slot_num - 1; // convert 1-indexing to 0-indexing - - if (slot_idx < 0 || slot_idx >= g_Config.maximum_save_slots) { - Console_Log(GS(OSD_LOAD_GAME_FAIL_INVALID_SLOT), slot_num); - return CR_FAILURE; - } - - if (g_SavegameRequester.items[slot_idx].is_blocked) { - Console_Log(GS(OSD_LOAD_GAME_FAIL_UNAVAILABLE_SLOT), slot_num); - return CR_FAILURE; - } - - g_GameInfo.override_gf_command = (GAMEFLOW_COMMAND) { - .action = GF_START_SAVED_GAME, - .param = slot_idx, - }; - Console_Log(GS(OSD_LOAD_GAME), slot_num); - return CR_SUCCESS; -} - -static COMMAND_RESULT Console_Cmd_SaveGame(const char *args) -{ - if (g_GameInfo.current_level_type == GFL_TITLE - || g_GameInfo.current_level_type == GFL_DEMO - || g_GameInfo.current_level_type == GFL_CUTSCENE) { - return CR_UNAVAILABLE; - } - - int32_t slot_num; - if (!String_ParseInteger(args, &slot_num)) { - return CR_BAD_INVOCATION; - } - const int32_t slot_idx = slot_num - 1; // convert 1-indexing to 0-indexing - - if (slot_idx < 0 || slot_idx >= g_Config.maximum_save_slots) { - Console_Log(GS(OSD_SAVE_GAME_FAIL_INVALID_SLOT), slot_num); - return CR_BAD_INVOCATION; - } - - if (g_LaraItem == NULL) { - return CR_UNAVAILABLE; - } - - Savegame_Save(slot_idx, &g_GameInfo); - Console_Log(GS(OSD_SAVE_GAME), slot_num); - return CR_SUCCESS; -} - -static COMMAND_RESULT Console_Cmd_EndLevel(const char *const args) -{ - if (!String_Equivalent(args, "")) { - return CR_BAD_INVOCATION; - } - - Lara_Cheat_EndLevel(); - return CR_SUCCESS; -} - -static COMMAND_RESULT Console_Cmd_StartLevel(const char *const args) -{ - if (String_Equivalent(args, "")) { - return CR_BAD_INVOCATION; - } - - int32_t level_to_load = -1; - if (!String_ParseInteger(args, &level_to_load)) { - for (int i = 0; i < g_GameFlow.level_count; i++) { - if (String_CaseSubstring(g_GameFlow.levels[i].level_title, args) - != NULL) { - level_to_load = i; - break; - } - } - if (level_to_load == -1 && String_Equivalent(args, "gym")) { - level_to_load = g_GameFlow.gym_level_num; - } - if (level_to_load == -1) { - Console_Log(GS(OSD_INVALID_LEVEL)); - return CR_FAILURE; - } - } - - if (level_to_load == -1) { - return CR_BAD_INVOCATION; - } - - if (level_to_load >= g_GameFlow.level_count) { - Console_Log(GS(OSD_INVALID_LEVEL)); - return CR_FAILURE; - } - - g_GameInfo.override_gf_command = (GAMEFLOW_COMMAND) { - .action = GF_SELECT_GAME, - .param = level_to_load, - }; - Console_Log( - GS(OSD_PLAY_LEVEL), g_GameFlow.levels[level_to_load].level_title); - return CR_SUCCESS; -} - -static COMMAND_RESULT Console_Cmd_Abortion(const char *args) -{ - if (!g_Objects[O_LARA].loaded) { - return CR_UNAVAILABLE; - } - - if (g_LaraItem->hit_points <= 0) { - return CR_UNAVAILABLE; - } - - Effect_ExplodingDeath(g_Lara.item_num, -1, 0); - Sound_Effect(SFX_EXPLOSION_CHEAT, &g_LaraItem->pos, SPM_NORMAL); - Sound_Effect(SFX_LARA_FALL, &g_LaraItem->pos, SPM_NORMAL); - g_LaraItem->hit_points = 0; - g_LaraItem->flags |= IS_INVISIBLE; - return CR_SUCCESS; -} - -CONSOLE_COMMAND *g_ConsoleCommands[] = { - &(CONSOLE_COMMAND) { .prefix = "fps", .proc = Console_Cmd_Fps }, - &(CONSOLE_COMMAND) { .prefix = "vsync", .proc = Console_Cmd_VSync }, - &(CONSOLE_COMMAND) { .prefix = "wireframe", .proc = Console_Cmd_Wireframe }, - &(CONSOLE_COMMAND) { .prefix = "braid", .proc = Console_Cmd_Braid }, - &(CONSOLE_COMMAND) { .prefix = "cheats", .proc = Console_Cmd_Cheats }, - &(CONSOLE_COMMAND) { .prefix = "tp", .proc = Console_Cmd_Teleport }, - &(CONSOLE_COMMAND) { .prefix = "fly", .proc = Console_Cmd_Fly }, - &(CONSOLE_COMMAND) { .prefix = "speed", .proc = Console_Cmd_Speed }, - &(CONSOLE_COMMAND) { .prefix = "flip", .proc = Console_Cmd_FlipMap }, - &(CONSOLE_COMMAND) { .prefix = "flipmap", .proc = Console_Cmd_FlipMap }, - &(CONSOLE_COMMAND) { .prefix = "kill", .proc = Console_Cmd_Kill }, - &(CONSOLE_COMMAND) { .prefix = "endlevel", .proc = Console_Cmd_EndLevel }, - &(CONSOLE_COMMAND) { .prefix = "play", .proc = Console_Cmd_StartLevel }, - &(CONSOLE_COMMAND) { .prefix = "level", .proc = Console_Cmd_StartLevel }, - &(CONSOLE_COMMAND) { .prefix = "load", .proc = Console_Cmd_LoadGame }, - &(CONSOLE_COMMAND) { .prefix = "save", .proc = Console_Cmd_SaveGame }, - &(CONSOLE_COMMAND) { .prefix = "demo", .proc = Console_Cmd_StartDemo }, - &(CONSOLE_COMMAND) { .prefix = "title", .proc = Console_Cmd_ExitToTitle }, - &(CONSOLE_COMMAND) { .prefix = "exit", .proc = Console_Cmd_ExitGame }, - &(CONSOLE_COMMAND) { .prefix = "abortion", .proc = Console_Cmd_Abortion }, - &(CONSOLE_COMMAND) { .prefix = "natlastinks", - .proc = Console_Cmd_Abortion }, - &g_Console_Cmd_Pos, - &g_Console_Cmd_Heal, - &g_Console_Cmd_SetHealth, - &g_Console_Cmd_Config, - &g_Console_Cmd_GiveItem, - NULL, -}; diff --git a/src/game/game/game.c b/src/game/game/game.c index 913004e84..47590c000 100644 --- a/src/game/game/game.c +++ b/src/game/game/game.c @@ -250,7 +250,7 @@ bool Game_IsPlayable(void) return false; } - if (!g_Objects[O_LARA].loaded) { + if (!g_Objects[O_LARA].loaded || g_LaraItem == NULL) { return false; } diff --git a/src/game/lara/lara_cheat.c b/src/game/lara/lara_cheat.c index 3e6719c57..9f1d1c591 100644 --- a/src/game/lara/lara_cheat.c +++ b/src/game/lara/lara_cheat.c @@ -2,7 +2,7 @@ #include "game/camera.h" #include "game/carrier.h" -#include "game/console.h" +#include "game/console/common.h" #include "game/effects/exploding_death.h" #include "game/game_string.h" #include "game/gameflow.h" diff --git a/src/game/output.c b/src/game/output.c index 3ac543963..2e833af5f 100644 --- a/src/game/output.c +++ b/src/game/output.c @@ -2,7 +2,7 @@ #include "config.h" #include "game/clock.h" -#include "game/console.h" +#include "game/console/common.h" #include "game/gamebuf.h" #include "game/overlay.h" #include "game/phase/phase.h" diff --git a/src/game/phase/phase_inventory.c b/src/game/phase/phase_inventory.c index b1ba906ba..2f66a7568 100644 --- a/src/game/phase/phase_inventory.c +++ b/src/game/phase/phase_inventory.c @@ -2,7 +2,7 @@ #include "config.h" #include "game/clock.h" -#include "game/console.h" +#include "game/console/common.h" #include "game/game.h" #include "game/gameflow.h" #include "game/input.h" diff --git a/src/game/shell.c b/src/game/shell.c index c8c69dd57..dfb26b209 100644 --- a/src/game/shell.c +++ b/src/game/shell.c @@ -2,7 +2,7 @@ #include "config.h" #include "game/clock.h" -#include "game/console.h" +#include "game/console/common.h" #include "game/fmv.h" #include "game/game.h" #include "game/game_string.h" diff --git a/src/specific/s_shell.c b/src/specific/s_shell.c index 7f20bb274..4fb2ad304 100644 --- a/src/specific/s_shell.c +++ b/src/specific/s_shell.c @@ -1,7 +1,7 @@ #include "specific/s_shell.h" #include "config.h" -#include "game/console.h" +#include "game/console/common.h" #include "game/input.h" #include "game/music.h" #include "game/output.h" diff --git a/subprojects/libtrx b/subprojects/libtrx index 43678a60e..e37658930 160000 --- a/subprojects/libtrx +++ b/subprojects/libtrx @@ -1 +1 @@ -Subproject commit 43678a60e92dc7d9ac8d9259c1e632949a19a5dd +Subproject commit e376589305ba378c34fafcdf143d07d2f14a8b77 From 451e6199991ee43141e04dcb824a44d56791652a Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Sat, 21 Sep 2024 01:16:00 +0200 Subject: [PATCH 3/3] console/cmd: move /kill to libtrx --- data/ship/cfg/TR1X_gameflow.json5 | 2 + data/ship/cfg/TR1X_gameflow_demo_pc.json5 | 2 + data/ship/cfg/TR1X_gameflow_ub.json5 | 2 + meson.build | 1 - src/game/console/cmd/kill.c | 112 ---------------------- src/game/console/cmd/kill.h | 5 - src/game/console/setup.c | 2 +- src/game/creature.c | 10 ++ src/game/game_string.def | 4 - src/game/items.c | 5 + src/game/objects/common.c | 8 ++ src/game/objects/common.h | 1 + subprojects/libtrx | 2 +- 13 files changed, 32 insertions(+), 124 deletions(-) delete mode 100644 src/game/console/cmd/kill.c delete mode 100644 src/game/console/cmd/kill.h diff --git a/data/ship/cfg/TR1X_gameflow.json5 b/data/ship/cfg/TR1X_gameflow.json5 index 9d5b0db55..30554c14c 100644 --- a/data/ship/cfg/TR1X_gameflow.json5 +++ b/data/ship/cfg/TR1X_gameflow.json5 @@ -721,6 +721,7 @@ "OSD_HEAL_SUCCESS": "Healed Lara back to full health", "OSD_INVALID_ITEM": "Unknown item: %s", "OSD_INVALID_LEVEL": "Invalid level", + "OSD_INVALID_OBJECT": "Invalid object", "OSD_INVALID_ROOM": "Invalid room: %d. Valid rooms are 0-%d", "OSD_KILL": "Bye-bye!", "OSD_KILL_ALL": "Poof! %d enemies gone!", @@ -729,6 +730,7 @@ "OSD_LOAD_GAME": "Loaded game from save slot %d", "OSD_LOAD_GAME_FAIL_INVALID_SLOT": "Invalid save slot %d", "OSD_LOAD_GAME_FAIL_UNAVAILABLE_SLOT": "Save slot %d is not available", + "OSD_OBJECT_NOT_FOUND": "Object not found", "OSD_PERSPECTIVE_FILTER_OFF": "Perspective filter disabled", "OSD_PERSPECTIVE_FILTER_ON": "Perspective filter enabled", "OSD_PLAY_LEVEL": "Loading %s", diff --git a/data/ship/cfg/TR1X_gameflow_demo_pc.json5 b/data/ship/cfg/TR1X_gameflow_demo_pc.json5 index 472a79b55..71f058c81 100644 --- a/data/ship/cfg/TR1X_gameflow_demo_pc.json5 +++ b/data/ship/cfg/TR1X_gameflow_demo_pc.json5 @@ -216,6 +216,7 @@ "OSD_HEAL_SUCCESS": "Healed Lara back to full health", "OSD_INVALID_ITEM": "Unknown item: %s", "OSD_INVALID_LEVEL": "Invalid level", + "OSD_INVALID_OBJECT": "Invalid object", "OSD_INVALID_ROOM": "Invalid room: %d. Valid rooms are 0-%d", "OSD_KILL": "Bye-bye!", "OSD_KILL_ALL": "Poof! %d enemies gone!", @@ -224,6 +225,7 @@ "OSD_LOAD_GAME": "Loaded game from save slot %d", "OSD_LOAD_GAME_FAIL_INVALID_SLOT": "Invalid save slot %d", "OSD_LOAD_GAME_FAIL_UNAVAILABLE_SLOT": "Save slot %d is not available", + "OSD_OBJECT_NOT_FOUND": "Object not found", "OSD_PERSPECTIVE_FILTER_OFF": "Perspective filter disabled", "OSD_PERSPECTIVE_FILTER_ON": "Perspective filter enabled", "OSD_PLAY_LEVEL": "Loading %s", diff --git a/data/ship/cfg/TR1X_gameflow_ub.json5 b/data/ship/cfg/TR1X_gameflow_ub.json5 index c69f87e54..695edc409 100644 --- a/data/ship/cfg/TR1X_gameflow_ub.json5 +++ b/data/ship/cfg/TR1X_gameflow_ub.json5 @@ -288,6 +288,7 @@ "OSD_HEAL_SUCCESS": "Healed Lara back to full health", "OSD_INVALID_ITEM": "Unknown item: %s", "OSD_INVALID_LEVEL": "Invalid level", + "OSD_INVALID_OBJECT": "Invalid object", "OSD_INVALID_ROOM": "Invalid room: %d. Valid rooms are 0-%d", "OSD_KILL": "Bye-bye!", "OSD_KILL_ALL": "Poof! %d enemies gone!", @@ -296,6 +297,7 @@ "OSD_LOAD_GAME": "Loaded game from save slot %d", "OSD_LOAD_GAME_FAIL_INVALID_SLOT": "Invalid save slot %d", "OSD_LOAD_GAME_FAIL_UNAVAILABLE_SLOT": "Save slot %d is not available", + "OSD_OBJECT_NOT_FOUND": "Object not found", "OSD_PERSPECTIVE_FILTER_OFF": "Perspective filter disabled", "OSD_PERSPECTIVE_FILTER_ON": "Perspective filter enabled", "OSD_PLAY_LEVEL": "Loading %s", diff --git a/meson.build b/meson.build index 10948991f..03b5536d6 100644 --- a/meson.build +++ b/meson.build @@ -110,7 +110,6 @@ sources = [ 'src/game/console/cmd/flipmap.c', 'src/game/console/cmd/fly.c', 'src/game/console/cmd/fps.c', - 'src/game/console/cmd/kill.c', 'src/game/console/cmd/load_game.c', 'src/game/console/cmd/play_demo.c', 'src/game/console/cmd/play_level.c', diff --git a/src/game/console/cmd/kill.c b/src/game/console/cmd/kill.c deleted file mode 100644 index 1581b9812..000000000 --- a/src/game/console/cmd/kill.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "game/console/cmd/kill.h" - -#include "game/game_string.h" -#include "game/items.h" -#include "game/lara.h" -#include "game/lara/lara_cheat.h" -#include "game/objects/common.h" -#include "game/objects/names.h" -#include "game/sound.h" -#include "global/vars.h" - -#include -#include -#include - -static bool M_CanTargetObject_Enemy(GAME_OBJECT_ID object_id); -static COMMAND_RESULT M_Entrypoint(const char *args); - -static bool M_CanTargetObject_Enemy(const GAME_OBJECT_ID object_id) -{ - return Object_IsObjectType(object_id, g_EnemyObjects); -} - -static COMMAND_RESULT M_Entrypoint(const char *args) -{ - if (g_GameInfo.current_level_type == GFL_TITLE - || g_GameInfo.current_level_type == GFL_DEMO - || g_GameInfo.current_level_type == GFL_CUTSCENE) { - return CR_UNAVAILABLE; - } - - // kill all the enemies in the level - if (String_Equivalent(args, "all")) { - int32_t num = 0; - for (int16_t item_num = 0; item_num < Item_GetTotalCount(); - item_num++) { - if (Lara_Cheat_KillEnemy(item_num)) { - num++; - } - } - - if (num == 0) { - Console_Log(GS(OSD_KILL_ALL_FAIL), num); - return CR_FAILURE; - } - - Sound_Effect(SFX_EXPLOSION_CHEAT, &g_LaraItem->pos, SPM_NORMAL); - Console_Log(GS(OSD_KILL_ALL), num); - return CR_SUCCESS; - } - - // kill all the enemies around Lara within one tile, or a single nearest - // enemy - if (String_Equivalent(args, "")) { - bool found = false; - while (true) { - const int16_t best_item_num = Lara_GetNearestEnemy(); - if (best_item_num == NO_ITEM) { - break; - } - - ITEM_INFO *const item = &g_Items[best_item_num]; - const int32_t distance = Item_GetDistance(item, &g_LaraItem->pos); - found |= Lara_Cheat_KillEnemy(best_item_num); - if (distance >= WALL_L) { - break; - } - } - - if (!found) { - Console_Log(GS(OSD_KILL_FAIL)); - return CR_FAILURE; - } - - Console_Log(GS(OSD_KILL)); - return CR_SUCCESS; - } - - // kill a single enemy type - { - int32_t match_count = 0; - GAME_OBJECT_ID *matching_objs = - Object_IdsFromName(args, &match_count, M_CanTargetObject_Enemy); - int32_t num = 0; - for (int32_t i = 0; i < match_count; i++) { - const GAME_OBJECT_ID object_id = matching_objs[i]; - for (int16_t item_num = 0; item_num < Item_GetTotalCount(); - item_num++) { - if (g_Items[item_num].object_id == object_id - && Lara_Cheat_KillEnemy(item_num)) { - num++; - } - } - } - Memory_FreePointer(&matching_objs); - - if (!match_count) { - return CR_BAD_INVOCATION; - } - if (num == 0) { - Console_Log(GS(OSD_KILL_ALL_FAIL)); - return CR_FAILURE; - } - Console_Log(GS(OSD_KILL_ALL), num); - return CR_SUCCESS; - } -} - -CONSOLE_COMMAND g_Console_Cmd_Kill = { - .prefix = "kill", - .proc = M_Entrypoint, -}; diff --git a/src/game/console/cmd/kill.h b/src/game/console/cmd/kill.h deleted file mode 100644 index 3766fe1f8..000000000 --- a/src/game/console/cmd/kill.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include - -extern CONSOLE_COMMAND g_Console_Cmd_Kill; diff --git a/src/game/console/setup.c b/src/game/console/setup.c index 368ec1783..3cc728d26 100644 --- a/src/game/console/setup.c +++ b/src/game/console/setup.c @@ -9,7 +9,6 @@ #include "game/console/cmd/flipmap.h" #include "game/console/cmd/fly.h" #include "game/console/cmd/fps.h" -#include "game/console/cmd/kill.h" #include "game/console/cmd/load_game.h" #include "game/console/cmd/play_demo.h" #include "game/console/cmd/play_level.h" @@ -22,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/src/game/creature.c b/src/game/creature.c index 2a6a1ddde..b2cd50c06 100644 --- a/src/game/creature.c +++ b/src/game/creature.c @@ -817,3 +817,13 @@ static bool M_TestSwitchOrKill( Item_Kill(item_num); return false; } + +bool Creature_IsEnemy(const ITEM_INFO *const item) +{ + return Object_IsObjectType(item->object_id, g_EnemyObjects); +} + +bool Creature_IsAlly(const ITEM_INFO *const item) +{ + return Object_IsObjectType(item->object_id, g_AllyObjects); +} diff --git a/src/game/game_string.def b/src/game/game_string.def index 59689b140..1b948f8e6 100644 --- a/src/game/game_string.def +++ b/src/game/game_string.def @@ -153,10 +153,6 @@ GS_DEFINE(OSD_FLIPMAP_ON, "Flipmap set to ON") GS_DEFINE(OSD_FLIPMAP_OFF, "Flipmap set to OFF") GS_DEFINE(OSD_FLIPMAP_FAIL_ALREADY_ON, "Flipmap is already ON") GS_DEFINE(OSD_FLIPMAP_FAIL_ALREADY_OFF, "Flipmap is already OFF") -GS_DEFINE(OSD_KILL_ALL, "Poof! %d enemies gone!") -GS_DEFINE(OSD_KILL_ALL_FAIL, "Uh-oh, there are no enemies left to kill...") -GS_DEFINE(OSD_KILL, "Bye-bye!") -GS_DEFINE(OSD_KILL_FAIL, "No enemy nearby...") GS_DEFINE(OSD_COMPLETE_LEVEL, "Level complete!") GS_DEFINE(OSD_PLAY_LEVEL, "Loading %s") GS_DEFINE(OSD_TEXTURE_FILTER_SET, "Texture filter set to %s") diff --git a/src/game/items.c b/src/game/items.c index f8d594275..e956ac683 100644 --- a/src/game/items.c +++ b/src/game/items.c @@ -838,3 +838,8 @@ bool Item_TestFrameRange(ITEM_INFO *item, int16_t start, int16_t end) item->frame_num, g_Anims[item->anim_num].frame_base + start, g_Anims[item->anim_num].frame_base + end); } + +ITEM_INFO *Item_Get(const int16_t item_num) +{ + return &g_Items[item_num]; +} diff --git a/src/game/objects/common.c b/src/game/objects/common.c index 879fa80db..9d9e43b2b 100644 --- a/src/game/objects/common.c +++ b/src/game/objects/common.c @@ -52,6 +52,14 @@ const GAME_OBJECT_ID g_EnemyObjects[] = { // clang-format on }; +const GAME_OBJECT_ID g_AllyObjects[] = { + // clang-format off + O_LARA, + NO_OBJECT, + // Lara's social skills: still loading... + // clang-format on +}; + const GAME_OBJECT_ID g_BossObjects[] = { // clang-format off O_TREX, diff --git a/src/game/objects/common.h b/src/game/objects/common.h index f022dc98c..5ebd5d8f9 100644 --- a/src/game/objects/common.h +++ b/src/game/objects/common.h @@ -10,6 +10,7 @@ typedef struct GAME_OBJECT_PAIR { } GAME_OBJECT_PAIR; extern const GAME_OBJECT_ID g_EnemyObjects[]; +extern const GAME_OBJECT_ID g_AllyObjects[]; extern const GAME_OBJECT_ID g_BossObjects[]; extern const GAME_OBJECT_ID g_PlaceholderObjects[]; extern const GAME_OBJECT_ID g_PickupObjects[]; diff --git a/subprojects/libtrx b/subprojects/libtrx index e37658930..41cd1a09e 160000 --- a/subprojects/libtrx +++ b/subprojects/libtrx @@ -1 +1 @@ -Subproject commit e376589305ba378c34fafcdf143d07d2f14a8b77 +Subproject commit 41cd1a09e3ea1c445df702cd9fa0d7682761459f