mirror of
https://github.com/LostArtefacts/TR2X.git
synced 2025-03-01 10:36:00 +00:00
console: add ability to /tp to specific items
This commit is contained in:
parent
661d742c8d
commit
09353e32f4
@ -37,16 +37,28 @@
|
||||
{},
|
||||
|
||||
// 11. Tibetan Foothills
|
||||
{},
|
||||
{
|
||||
"object_strings": {
|
||||
"O_TIGER": "Snow Leopard",
|
||||
},
|
||||
},
|
||||
|
||||
// 12. Barkhang Monastery
|
||||
{},
|
||||
|
||||
// 13. Catacombs of the Talion
|
||||
{},
|
||||
{
|
||||
"object_strings": {
|
||||
"O_TIGER": "Snow Leopard",
|
||||
},
|
||||
},
|
||||
|
||||
// 14. Ice Palace
|
||||
{},
|
||||
{
|
||||
"object_strings": {
|
||||
"O_TIGER": "Snow Leopard",
|
||||
},
|
||||
},
|
||||
|
||||
// 15. Temple of Xian
|
||||
{},
|
||||
@ -70,6 +82,274 @@
|
||||
{},
|
||||
],
|
||||
|
||||
"object_strings": {
|
||||
"O_LARA": "Lara",
|
||||
"O_LARA_PISTOLS": "Pistols Animation",
|
||||
"O_LARA_HAIR": "Braid",
|
||||
"O_LARA_SHOTGUN": "Shotgun Animation",
|
||||
"O_LARA_MAGNUMS": "Magnums Animation",
|
||||
"O_LARA_UZIS": "Uzis Animation",
|
||||
"O_LARA_M16": "M16 Animation",
|
||||
"O_LARA_GRENADE": "Grenade Launcher Animation",
|
||||
"O_LARA_HARPOON": "Harpoon Animation",
|
||||
"O_LARA_FLARE": "Flare Animation",
|
||||
"O_LARA_SKIDOO": "Snowmobile Animation",
|
||||
"O_LARA_BOAT": "Boat Animation",
|
||||
"O_LARA_EXTRA": "Lara's Extra Animation",
|
||||
"O_SKIDOO_FAST": "Red Snowmobile",
|
||||
"O_BOAT": "Boat",
|
||||
"O_DOG": "Dog",
|
||||
"O_CULT_1": "Masked Goon 1",
|
||||
"O_CULT_1A": "Masked Goon 2",
|
||||
"O_CULT_1B": "Masked Goon 3",
|
||||
"O_CULT_2": "Knife Thrower",
|
||||
"O_CULT_3": "Shotgun Goon",
|
||||
"O_MOUSE": "Rat",
|
||||
"O_DRAGON_FRONT": "Dragon Front",
|
||||
"O_DRAGON_BACK": "Dragon Back",
|
||||
"O_GONDOLA": "Gondola",
|
||||
"O_SHARK": "Shark",
|
||||
"O_EEL": "Eel",
|
||||
"O_BIG_EEL": "Big Eel",
|
||||
"O_BARRACUDA": "Barracuda",
|
||||
"O_DIVER": "Scuba Diver",
|
||||
"O_WORKER_1": "Gunman Goon 1",
|
||||
"O_WORKER_2": "Gunman Goon 2",
|
||||
"O_WORKER_3": "Stick Wielding Goon 1",
|
||||
"O_WORKER_4": "Stick Wielding Goon 2",
|
||||
"O_WORKER_5": "Flamethrower Goon",
|
||||
"O_JELLY": "Jellyfish",
|
||||
"O_SPIDER": "Spider",
|
||||
"O_BIG_SPIDER": "Giant Spider",
|
||||
"O_CROW": "Crow",
|
||||
"O_TIGER": "Tiger",
|
||||
"O_BARTOLI": "Marco Bartoli",
|
||||
"O_XIAN_SPEARMAN": "Xian Spearman",
|
||||
"O_XIAN_SPEARMAN_STATUE": "Xian Spearman Statue",
|
||||
"O_XIAN_KNIGHT": "Xian Knight",
|
||||
"O_XIAN_KNIGHT_STATUE": "Xian Knight",
|
||||
"O_YETI": "Yeti",
|
||||
"O_GIANT_YETI": "Bird Monster",
|
||||
"O_EAGLE": "Eagle",
|
||||
"O_BANDIT_1": "Mercenary 1",
|
||||
"O_BANDIT_2": "Mercenary 2",
|
||||
"O_BANDIT_2B": "Mercenary 3",
|
||||
"O_SKIDOO_ARMED": "Black Snowmobile",
|
||||
"O_SKIDMAN": "Black Snowmobile Driver",
|
||||
"O_MONK_1": "Monk 1",
|
||||
"O_MONK_2": "Monk 2",
|
||||
"O_FALLING_BLOCK_1": "Falling Block 1",
|
||||
"O_FALLING_BLOCK_2": "Falling Block 2",
|
||||
"O_FALLING_BLOCK_3": "Loose Boards",
|
||||
"O_PENDULUM_1": "Sandbag",
|
||||
"O_SPIKES": "Spikes",
|
||||
"O_ROLLING_BALL_1": "Boulder 1",
|
||||
"O_DARTS": "Disc",
|
||||
"O_DART_EMITTER": "Disc Emitter",
|
||||
"O_DRAW_BRIDGE": "Drawbridge",
|
||||
"O_TEETH_TRAP": "Teeth Trap",
|
||||
"O_LIFT": "Lift",
|
||||
"O_GENERAL": "Minisub",
|
||||
"O_MOVABLE_BLOCK_1": "Push Block 1",
|
||||
"O_MOVABLE_BLOCK_2": "Push Block 2",
|
||||
"O_MOVABLE_BLOCK_3": "Push Block 3",
|
||||
"O_MOVABLE_BLOCK_4": "Push Block 4",
|
||||
"O_BIG_BOWL": "Lava Bowl",
|
||||
"O_WINDOW_1": "Breakable Window 1",
|
||||
"O_WINDOW_2": "Breakable Window 2",
|
||||
"O_WINDOW_3": "Breakable Window 3",
|
||||
"O_WINDOW_4": "Breakable Window 4",
|
||||
"O_PROPELLER_1": "Airplane Propeller",
|
||||
"O_POWER_SAW": "Power Saw",
|
||||
"O_HOOK": "Hook",
|
||||
"O_FALLING_CEILING": "Falling Ceiling",
|
||||
"O_SPINNING_BLADE": "Spinning Blade",
|
||||
"O_BLADE": "Wall-mounted Blade",
|
||||
"O_KILLER_STATUE": "Statue with Sword",
|
||||
"O_ROLLING_BALL_2": "Boulder 2",
|
||||
"O_ICICLE": "Icicles",
|
||||
"O_SPIKE_WALL": "Spike Wall",
|
||||
"O_SPRING_BOARD": "Springboard",
|
||||
"O_CEILING_SPIKES": "Spiky Ceiling",
|
||||
"O_BELL": "Bell",
|
||||
"O_WATER_SPRITE": "Boat Wake",
|
||||
"O_SNOW_SPRITE": "Snowmobile Wale",
|
||||
"O_SKIDOO_LARA": "Snowmobile Animation",
|
||||
"O_SWITCH_TYPE_1": "Switch 1",
|
||||
"O_SWITCH_TYPE_2": "Switch 2",
|
||||
"O_PROPELLER_2": "Underwater Propeller",
|
||||
"O_PROPELLER_3": "Air Fan",
|
||||
"O_PENDULUM_2": "Swinging Box",
|
||||
"O_MESH_SWAP_1": "Mesh Swap 1",
|
||||
"O_MESH_SWAP_2": "Mesh Swap 2",
|
||||
"O_LARA_SWAP": "Lara Mesh Swap",
|
||||
"O_TEXT_BOX": "UI Frame",
|
||||
"O_ROLLING_BALL_3": "Boulder 3",
|
||||
"O_DEATH_SLIDE": "Zipline Handle",
|
||||
"O_SWITCH_TYPE_3": "Switch 3",
|
||||
"O_SWITCH_TYPE_4": "Switch 4",
|
||||
"O_SWITCH_TYPE_5": "Switch 5",
|
||||
"O_DOOR_TYPE_1": "Door 1",
|
||||
"O_DOOR_TYPE_2": "Door 2",
|
||||
"O_DOOR_TYPE_3": "Door 3",
|
||||
"O_DOOR_TYPE_4": "Door 4",
|
||||
"O_DOOR_TYPE_5": "Door 5",
|
||||
"O_DOOR_TYPE_6": "Door 6",
|
||||
"O_DOOR_TYPE_7": "Door 7",
|
||||
"O_DOOR_TYPE_8": "Door 8",
|
||||
"O_TRAPDOOR_TYPE_1": "Trapdoor 1",
|
||||
"O_TRAPDOOR_TYPE_2": "Trapdoor 2",
|
||||
"O_TRAPDOOR_TYPE_3": "Trapdoor 3",
|
||||
"O_BRIDGE_FLAT": "Bridge Flat",
|
||||
"O_BRIDGE_TILT_1": "Bridge Tilt 1",
|
||||
"O_BRIDGE_TILT_2": "Bridge Tilt 2",
|
||||
"O_PASSPORT_OPTION": "Passport Option",
|
||||
"O_COMPASS_OPTION": "Compass Option",
|
||||
"O_PHOTO_OPTION": "Photo Option",
|
||||
"O_PLAYER_1": "Cutscene Actor 1",
|
||||
"O_PLAYER_2": "Cutscene Actor 2",
|
||||
"O_PLAYER_3": "Cutscene Actor 3",
|
||||
"O_PLAYER_4": "Cutscene Actor 4",
|
||||
"O_PLAYER_5": "Cutscene Actor 5",
|
||||
"O_PLAYER_6": "Cutscene Actor 6",
|
||||
"O_PLAYER_7": "Cutscene Actor 7",
|
||||
"O_PLAYER_8": "Cutscene Actor 8",
|
||||
"O_PLAYER_9": "Cutscene Actor 9",
|
||||
"O_PLAYER_10": "Cutscene Actor 10",
|
||||
"O_PASSPORT_CLOSED": "Passport Closed",
|
||||
"O_COMPASS_ITEM": "Compass",
|
||||
"O_PISTOL_ITEM": "Pistols",
|
||||
"O_SHOTGUN_ITEM": "Shotgun",
|
||||
"O_MAGNUM_ITEM": "Magnums",
|
||||
"O_UZI_ITEM": "Uzis",
|
||||
"O_HARPOON_ITEM": "Harpoon",
|
||||
"O_M16_ITEM": "M16",
|
||||
"O_GRENADE_ITEM": "Grenade Launcher",
|
||||
"O_PISTOL_AMMO_ITEM": "Pistol Ammo",
|
||||
"O_SHOTGUN_AMMO_ITEM": "Shotgun Ammo",
|
||||
"O_MAGNUM_AMMO_ITEM": "Magnum Ammo",
|
||||
"O_UZI_AMMO_ITEM": "Uzi Ammo",
|
||||
"O_HARPOON_AMMO_ITEM": "Harpoon Ammo",
|
||||
"O_M16_AMMO_ITEM": "M16 Ammo",
|
||||
"O_GRENADE_AMMO_ITEM": "Grenade Launcher Ammo",
|
||||
"O_SMALL_MEDIPACK_ITEM": "Small Medipack",
|
||||
"O_LARGE_MEDIPACK_ITEM": "Large Medipack",
|
||||
"O_FLARES_ITEM": "Flares Box",
|
||||
"O_FLARE_ITEM": "Flare",
|
||||
"O_DETAIL_OPTION": "Detail Option",
|
||||
"O_SOUND_OPTION": "Sound Option",
|
||||
"O_CONTROL_OPTION": "Control Option",
|
||||
"O_GAMMA_OPTION": "Gamma Option",
|
||||
"O_PISTOL_OPTION": "Pistol Option",
|
||||
"O_SHOTGUN_OPTION": "Shotgun Option",
|
||||
"O_MAGNUM_OPTION": "Magnum Option",
|
||||
"O_UZI_OPTION": "Uzi Option",
|
||||
"O_HARPOON_OPTION": "Harpoon Option",
|
||||
"O_M16_OPTION": "M16 Option",
|
||||
"O_GRENADE_OPTION": "Grenade Launcher Option",
|
||||
"O_PISTOL_AMMO_OPTION": "Pistol Ammo Option",
|
||||
"O_SHOTGUN_AMMO_OPTION": "Shotgun Ammo Option",
|
||||
"O_MAGNUM_AMMO_OPTION": "Magnum Ammo Option",
|
||||
"O_UZI_AMMO_OPTION": "Uzi Ammo Option",
|
||||
"O_HARPOON_AMMO_OPTION": "Harpoon Ammo Option",
|
||||
"O_M16_AMMO_OPTION": "M16 Ammo Option",
|
||||
"O_GRENADE_AMMO_OPTION": "Grenade Launcher Ammo Option",
|
||||
"O_SMALL_MEDIPACK_OPTION": "Small Medipack Option",
|
||||
"O_LARGE_MEDIPACK_OPTION": "Large Medipack Option",
|
||||
"O_FLARES_OPTION": "Flare Option",
|
||||
"O_PUZZLE_ITEM_1": "Puzzle Item 1",
|
||||
"O_PUZZLE_ITEM_2": "Puzzle Item 2",
|
||||
"O_PUZZLE_ITEM_3": "Puzzle Item 3",
|
||||
"O_PUZZLE_ITEM_4": "Puzzle Item 4",
|
||||
"O_PUZZLE_OPTION_1": "Puzzle Option 1",
|
||||
"O_PUZZLE_OPTION_2": "Puzzle Option 2",
|
||||
"O_PUZZLE_OPTION_3": "Puzzle Option 3",
|
||||
"O_PUZZLE_OPTION_4": "Puzzle Option 4",
|
||||
"O_PUZZLE_HOLE_1": "Puzzle Hole 1 (Empty)",
|
||||
"O_PUZZLE_HOLE_2": "Puzzle Hole 2 (Empty)",
|
||||
"O_PUZZLE_HOLE_3": "Puzzle Hole 3 (Empty)",
|
||||
"O_PUZZLE_HOLE_4": "Puzzle Hole 4 (Empty)",
|
||||
"O_PUZZLE_DONE_1": "Puzzle Hole 1 (Done)",
|
||||
"O_PUZZLE_DONE_2": "Puzzle Hole 2 (Done)",
|
||||
"O_PUZZLE_DONE_3": "Puzzle Hole 3 (Done)",
|
||||
"O_PUZZLE_DONE_4": "Puzzle Hole 4 (Done)",
|
||||
"O_SECRET_1": "Secret 1",
|
||||
"O_SECRET_2": "Secret 2",
|
||||
"O_SECRET_3": "Secret 3",
|
||||
"O_KEY_ITEM_1": "Key 1",
|
||||
"O_KEY_ITEM_2": "Key 2",
|
||||
"O_KEY_ITEM_3": "Key 3",
|
||||
"O_KEY_ITEM_4": "Key 4",
|
||||
"O_KEY_OPTION_1": "Key Option 1",
|
||||
"O_KEY_OPTION_2": "Key Option 2",
|
||||
"O_KEY_OPTION_3": "Key Option 3",
|
||||
"O_KEY_OPTION_4": "Key Option 4",
|
||||
"O_KEY_HOLE_1": "Key Hole 1",
|
||||
"O_KEY_HOLE_2": "Key Hole 2",
|
||||
"O_KEY_HOLE_3": "Key Hole 3",
|
||||
"O_KEY_HOLE_4": "Key Hole 4",
|
||||
"O_PICKUP_ITEM_1": "Pickup Item 1",
|
||||
"O_PICKUP_ITEM_2": "Pickup Item 2",
|
||||
"O_PICKUP_OPTION_1": "Pickup Option 1",
|
||||
"O_PICKUP_OPTION_2": "Pickup Option 2",
|
||||
"O_SPHERE_OF_DOOM_1": "Dragon Explosion 1",
|
||||
"O_SPHERE_OF_DOOM_2": "Dragon Explosion 2",
|
||||
"O_SPHERE_OF_DOOM_3": "Dragon Explosion 3",
|
||||
"O_ALARM_SOUND": "Alarm",
|
||||
"O_BIRD_TWEETER_1": "Dripping Water",
|
||||
"O_DINO": "T-Rex",
|
||||
"O_BIRD_TWEETER_2": "Singing Birds",
|
||||
"O_CLOCK_CHIMES": "Bartoli Hideout clock",
|
||||
"O_DRAGON_BONES_1": "Placeholder",
|
||||
"O_DRAGON_BONES_2": "Dragon Bones Front",
|
||||
"O_DRAGON_BONES_3": "Dragon Bones Back",
|
||||
"O_HOT_LIQUID": "Extra Fire",
|
||||
"O_BOAT_BITS": "Boat Bits",
|
||||
"O_MINE": "Aquatic Mine",
|
||||
"O_INV_BACKGROUND": "Menu Background",
|
||||
"O_FX_RESERVED": "Gray disk",
|
||||
"O_GONG_BONGER": "Gong Stick",
|
||||
"O_DETONATOR_1": "Gong",
|
||||
"O_DETONATOR_2": "Detonator Box",
|
||||
"O_COPTER": "Helicopter",
|
||||
"O_EXPLOSION": "Explosion",
|
||||
"O_SPLASH": "Water Ripples",
|
||||
"O_BUBBLES": "Bubbles",
|
||||
"O_BUBBLE_EMITTER": "Bubbles Emitter",
|
||||
"O_BLOOD": "Blood",
|
||||
"O_DART_EFFECT": "Dart Effect",
|
||||
"O_FLARE_FIRE": "Flare sparks",
|
||||
"O_GLOW": "Glow",
|
||||
"O_GLOW_RESERVED": "Map Glow",
|
||||
"O_RICOCHET": "Ricochet",
|
||||
"O_TWINKLE": "Sparkles",
|
||||
"O_GUN_FLASH": "Gun Flash",
|
||||
"O_M16_FLASH": "M16 Flash",
|
||||
"O_BODY_PART": "Body Part",
|
||||
"O_CAMERA_TARGET": "Camera Target",
|
||||
"O_WATERFALL": "Waterfall",
|
||||
"O_MISSILE_HARPOON": "Missile Harpoon",
|
||||
"O_MISSILE_FLAME": "Missile Flame",
|
||||
"O_MISSILE_KNIFE": "Missile Knife",
|
||||
"O_GRENADE": "Grenade",
|
||||
"O_HARPOON_BOLT": "Harpoon Bolt",
|
||||
"O_LAVA": "Lava",
|
||||
"O_LAVA_EMITTER": "Lava Emitter",
|
||||
"O_FLAME": "Flame",
|
||||
"O_FLAME_EMITTER": "Flame Emitter",
|
||||
"O_SKYBOX": "Skybox",
|
||||
"O_ALPHABET": "Alphabet",
|
||||
"O_DYING_MONK": "Dying monk",
|
||||
"O_DING_DONG": "Doorbell",
|
||||
"O_LARA_ALARM": "Alarm Bell",
|
||||
"O_MINI_COPTER": "Helicopter 2",
|
||||
"O_WINSTON": "Winston",
|
||||
"O_ASSAULT_DIGITS": "Assault Digits",
|
||||
"O_FINAL_LEVEL_COUNTER": "Final Level Counter",
|
||||
"O_CUT_SHOTGUN": "Shotgun Shower Animation",
|
||||
"O_EARTHQUAKE": "Earthquake",
|
||||
},
|
||||
|
||||
"game_strings": {
|
||||
"OSD_FLY_MODE_ON": "Fly mode enabled",
|
||||
"OSD_FLY_MODE_OFF": "Fly mode disabled",
|
||||
|
@ -2061,15 +2061,15 @@ typedef enum {
|
||||
O_WORKER_4 = 33,
|
||||
O_WORKER_5 = 34,
|
||||
O_JELLY = 35,
|
||||
O_SPIDER_or_WOLF = 36,
|
||||
O_BIG_SPIDER_or_BEAR = 37,
|
||||
O_SPIDER = 36,
|
||||
O_BIG_SPIDER = 37,
|
||||
O_CROW = 38,
|
||||
O_TIGER = 39,
|
||||
O_BARTOLI = 40,
|
||||
O_XIAN_LORD = 41,
|
||||
O_CHINESE_2 = 42,
|
||||
O_WARRIOR = 43,
|
||||
O_CHINESE_4 = 44,
|
||||
O_XIAN_SPEARMAN = 41,
|
||||
O_XIAN_SPEARMAN_STATUE = 42,
|
||||
O_XIAN_KNIGHT = 43,
|
||||
O_XIAN_KNIGHT_STATUE = 44,
|
||||
O_YETI = 45,
|
||||
O_GIANT_YETI = 46,
|
||||
O_EAGLE = 47,
|
||||
@ -2102,7 +2102,7 @@ typedef enum {
|
||||
O_WINDOW_3 = 74,
|
||||
O_WINDOW_4 = 75,
|
||||
O_PROPELLER_1 = 76,
|
||||
O_PROPELLER_2 = 77,
|
||||
O_POWER_SAW = 77,
|
||||
O_HOOK = 78,
|
||||
O_FALLING_CEILING = 79,
|
||||
O_SPINNING_BLADE = 80,
|
||||
@ -2119,8 +2119,8 @@ typedef enum {
|
||||
O_SKIDOO_LARA = 91,
|
||||
O_SWITCH_TYPE_1 = 92,
|
||||
O_SWITCH_TYPE_2 = 93,
|
||||
O_PROPELLER_3 = 94,
|
||||
O_PROPELLER_4 = 95,
|
||||
O_PROPELLER_2 = 94,
|
||||
O_PROPELLER_3 = 95,
|
||||
O_PENDULUM_2 = 96,
|
||||
O_MESH_SWAP_1 = 97,
|
||||
O_MESH_SWAP_2 = 98,
|
||||
|
@ -118,6 +118,7 @@ dll_sources = [
|
||||
'src/game/objects/creatures/diver.c',
|
||||
'src/game/objects/general/door.c',
|
||||
'src/game/objects/general/final_level_counter.c',
|
||||
'src/game/objects/names.c',
|
||||
'src/game/objects/vars.c',
|
||||
'src/game/objects/vehicles/boat.c',
|
||||
'src/game/option/option.c',
|
||||
|
@ -4,6 +4,9 @@
|
||||
#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/objects/vars.h"
|
||||
#include "game/random.h"
|
||||
#include "game/room.h"
|
||||
#include "game/sound.h"
|
||||
@ -70,7 +73,7 @@ static COMMAND_RESULT Console_Cmd_Teleport(const char *const args)
|
||||
z += 0.5f;
|
||||
}
|
||||
|
||||
if (Item_Teleport(g_LaraItem, x * WALL_L, y * WALL_L, z * WALL_L)) {
|
||||
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;
|
||||
}
|
||||
@ -104,7 +107,7 @@ static COMMAND_RESULT Console_Cmd_Teleport(const char *const args)
|
||||
int32_t x = x1 + Random_GetControl() * (x2 - x1) / 0x7FFF;
|
||||
int32_t y = y1;
|
||||
int32_t z = z1 + Random_GetControl() * (z2 - z1) / 0x7FFF;
|
||||
if (Item_Teleport(g_LaraItem, x, y, z)) {
|
||||
if (Lara_Cheat_Teleport(x, y, z)) {
|
||||
Console_Log(GS(OSD_POS_SET_ROOM), room_num);
|
||||
return CR_SUCCESS;
|
||||
}
|
||||
@ -115,6 +118,65 @@ 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);
|
||||
|
||||
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_pickup =
|
||||
Object_IsObjectType(item->object_num, g_PickupObjects);
|
||||
if (is_pickup
|
||||
&& (item->status == IS_INVISIBLE
|
||||
|| item->status == IS_DEACTIVATED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item->flags & IF_KILLED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool is_matched = false;
|
||||
for (int32_t i = 0; i < match_count; i++) {
|
||||
if (matching_objs[i] == item->object_num) {
|
||||
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),
|
||||
Object_GetName(best_item->object_num));
|
||||
} else {
|
||||
Console_Log(
|
||||
GS(OSD_POS_SET_ITEM_FAIL),
|
||||
Object_GetName(best_item->object_num));
|
||||
}
|
||||
return CR_SUCCESS;
|
||||
} else {
|
||||
Console_Log(GS(OSD_POS_SET_ITEM_FAIL), args);
|
||||
return CR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return CR_BAD_INVOCATION;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "game/demo.h"
|
||||
#include "game/game.h"
|
||||
#include "game/gun/gun.h"
|
||||
#include "game/objects/names.h"
|
||||
#include "game/overlay.h"
|
||||
#include "gameflow/gameflow_new.h"
|
||||
#include "global/funcs.h"
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "game/gameflow/gameflow_new.h"
|
||||
|
||||
#include "game/game_string.h"
|
||||
#include "game/objects/names.h"
|
||||
#include "global/enum_str.h"
|
||||
#include "global/types.h"
|
||||
|
||||
@ -8,9 +9,21 @@
|
||||
|
||||
GAMEFLOW_NEW g_GameflowNew;
|
||||
|
||||
static void GF_N_LoadObjectString(const char *key, const char *value);
|
||||
static void GF_N_LoadGameString(const char *key, const char *value);
|
||||
static void GF_N_LoadObjectStrings(const int32_t level_num);
|
||||
static void GF_N_LoadGameStrings(const int32_t level_num);
|
||||
|
||||
static void GF_N_LoadObjectString(
|
||||
const char *const key, const char *const value)
|
||||
{
|
||||
const GAME_OBJECT_ID object =
|
||||
ENUM_STRING_GET(GAME_OBJECT_ID, key, NO_OBJECT);
|
||||
if (object != NO_OBJECT) {
|
||||
Object_SetName(object, value);
|
||||
}
|
||||
}
|
||||
|
||||
static void GF_N_LoadGameString(const char *const key, const char *const value)
|
||||
{
|
||||
const GAME_STRING_ID game_string =
|
||||
@ -20,6 +33,27 @@ static void GF_N_LoadGameString(const char *const key, const char *const value)
|
||||
}
|
||||
}
|
||||
|
||||
static void GF_N_LoadObjectStrings(const int32_t level_num)
|
||||
{
|
||||
const GAMEFLOW_NEW *const gf = &g_GameflowNew;
|
||||
|
||||
const GAMEFLOW_NEW_STRING_ENTRY *entry = gf->object_strings;
|
||||
while (entry != NULL && entry->key != NULL) {
|
||||
GF_N_LoadObjectString(entry->key, entry->value);
|
||||
entry++;
|
||||
}
|
||||
|
||||
if (level_num >= 0) {
|
||||
assert(level_num < gf->level_count);
|
||||
const GAMEFLOW_NEW_LEVEL *const level = &gf->levels[level_num];
|
||||
entry = level->object_strings;
|
||||
while (entry != NULL && entry->key != NULL) {
|
||||
GF_N_LoadObjectString(entry->key, entry->value);
|
||||
entry++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void GF_N_LoadGameStrings(const int32_t level_num)
|
||||
{
|
||||
const GAMEFLOW_NEW *const gf = &g_GameflowNew;
|
||||
@ -43,5 +77,6 @@ static void GF_N_LoadGameStrings(const int32_t level_num)
|
||||
|
||||
void GF_N_LoadStrings(const int32_t level_num)
|
||||
{
|
||||
GF_N_LoadObjectStrings(level_num);
|
||||
GF_N_LoadGameStrings(level_num);
|
||||
}
|
||||
|
@ -105,6 +105,8 @@ static bool GF_N_LoadScriptLevels(
|
||||
goto end;
|
||||
}
|
||||
|
||||
result &= GF_N_LoadStringTable(
|
||||
jlvl_obj, "object_strings", &level->object_strings);
|
||||
result &= GF_N_LoadStringTable(
|
||||
jlvl_obj, "game_strings", &level->game_strings);
|
||||
}
|
||||
@ -141,6 +143,8 @@ bool GF_N_Load(const char *const path)
|
||||
|
||||
GAMEFLOW_NEW *const gf = &g_GameflowNew;
|
||||
struct json_object_s *root_obj = json_value_as_object(root);
|
||||
result &=
|
||||
GF_N_LoadStringTable(root_obj, "object_strings", &gf->object_strings);
|
||||
result &= GF_N_LoadStringTable(root_obj, "game_strings", &gf->game_strings);
|
||||
result &= GF_N_LoadScriptLevels(root_obj, gf);
|
||||
|
||||
@ -163,8 +167,10 @@ void GF_N_Shutdown(void)
|
||||
GAMEFLOW_NEW *const gf = &g_GameflowNew;
|
||||
|
||||
for (int32_t i = 0; i < gf->level_count; i++) {
|
||||
GF_N_StringTableShutdown(gf->levels[i].object_strings);
|
||||
GF_N_StringTableShutdown(gf->levels[i].game_strings);
|
||||
}
|
||||
|
||||
GF_N_StringTableShutdown(gf->object_strings);
|
||||
GF_N_StringTableShutdown(gf->game_strings);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "game/items.h"
|
||||
|
||||
#include "game/camera.h"
|
||||
#include "game/math.h"
|
||||
#include "game/matrix.h"
|
||||
#include "game/room.h"
|
||||
@ -13,6 +12,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
static int16_t m_MaxUsedItemCount = 0;
|
||||
static BOUNDS_16 m_InterpolatedBounds = { 0 };
|
||||
|
||||
static OBJECT_BOUNDS Item_ConvertBounds(const int16_t *bounds_in);
|
||||
@ -55,6 +55,7 @@ void __cdecl Item_InitialiseArray(const int32_t num_items)
|
||||
g_NextItemFree = g_LevelItemCount;
|
||||
g_PrevItemActive = NO_ITEM;
|
||||
g_NextItemActive = NO_ITEM;
|
||||
m_MaxUsedItemCount = g_LevelItemCount;
|
||||
for (int32_t i = g_NextItemFree; i < num_items - 1; i++) {
|
||||
ITEM_INFO *const item = &g_Items[i];
|
||||
item->active = 0;
|
||||
@ -63,14 +64,20 @@ void __cdecl Item_InitialiseArray(const int32_t num_items)
|
||||
g_Items[num_items - 1].next_item = NO_ITEM;
|
||||
}
|
||||
|
||||
int32_t Item_GetTotalCount(void)
|
||||
{
|
||||
return m_MaxUsedItemCount;
|
||||
}
|
||||
|
||||
int16_t __cdecl Item_Create(void)
|
||||
{
|
||||
const int16_t result = g_NextItemFree;
|
||||
if (result != NO_ITEM) {
|
||||
g_Items[result].flags = 0;
|
||||
g_NextItemFree = g_Items[result].next_item;
|
||||
const int16_t item_num = g_NextItemFree;
|
||||
if (item_num != NO_ITEM) {
|
||||
g_Items[item_num].flags = 0;
|
||||
g_NextItemFree = g_Items[item_num].next_item;
|
||||
}
|
||||
return result;
|
||||
m_MaxUsedItemCount = MAX(m_MaxUsedItemCount, item_num + 1);
|
||||
return item_num;
|
||||
}
|
||||
|
||||
void __cdecl Item_Kill(const int16_t item_num)
|
||||
@ -89,6 +96,11 @@ void __cdecl Item_Kill(const int16_t item_num)
|
||||
item->next_item = g_NextItemFree;
|
||||
g_NextItemFree = item_num;
|
||||
}
|
||||
|
||||
while (m_MaxUsedItemCount > 0
|
||||
&& g_Items[m_MaxUsedItemCount - 1].flags & IF_KILLED) {
|
||||
m_MaxUsedItemCount--;
|
||||
}
|
||||
}
|
||||
|
||||
void __cdecl Item_Initialise(const int16_t item_num)
|
||||
@ -279,32 +291,6 @@ void __cdecl Item_ClearKilled(void)
|
||||
g_PrevItemActive = NO_ITEM;
|
||||
}
|
||||
|
||||
bool __cdecl Item_Teleport(ITEM_INFO *item, int32_t x, int32_t y, int32_t z)
|
||||
{
|
||||
int16_t room_num = Room_GetIndexFromPos(x, y, z);
|
||||
if (room_num == NO_ROOM) {
|
||||
return false;
|
||||
}
|
||||
SECTOR_INFO *const sector = Room_GetSector(x, y, z, &room_num);
|
||||
const int16_t height = Room_GetHeight(sector, x, y, z);
|
||||
if (height != NO_HEIGHT) {
|
||||
item->pos.x = x;
|
||||
item->pos.y = y;
|
||||
item->pos.z = z;
|
||||
item->floor = height;
|
||||
if (item->room_num != room_num) {
|
||||
const int16_t item_num = item - g_Items;
|
||||
Item_NewRoom(item_num, room_num);
|
||||
}
|
||||
|
||||
if (item->object_num == O_LARA) {
|
||||
Camera_ResetPosition();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Item_IsSmashable(const ITEM_INFO *item)
|
||||
{
|
||||
return (item->object_num == O_WINDOW_1 || item->object_num == O_BELL);
|
||||
@ -751,3 +737,12 @@ void Item_TakeDamage(
|
||||
item->hit_status = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t Item_GetDistance(
|
||||
const ITEM_INFO *const item, const XYZ_32 *const target)
|
||||
{
|
||||
const int32_t x = (item->pos.x - target->x);
|
||||
const int32_t y = (item->pos.y - target->y);
|
||||
const int32_t z = (item->pos.z - target->z);
|
||||
return Math_Sqrt(SQUARE(x) + SQUARE(y) + SQUARE(z));
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "global/types.h"
|
||||
|
||||
void __cdecl Item_InitialiseArray(int32_t num_items);
|
||||
int32_t Item_GetTotalCount(void);
|
||||
int16_t __cdecl Item_Create(void);
|
||||
void __cdecl Item_Kill(int16_t item_num);
|
||||
void __cdecl Item_Initialise(int16_t item_num);
|
||||
@ -13,7 +14,6 @@ void __cdecl Item_NewRoom(int16_t item_num, int16_t room_num);
|
||||
int32_t __cdecl Item_GlobalReplace(
|
||||
int32_t src_object_num, int32_t dst_object_num);
|
||||
void __cdecl Item_ClearKilled(void);
|
||||
bool Item_Teleport(ITEM_INFO *item, int32_t x, int32_t y, int32_t z);
|
||||
void __cdecl Item_ShiftCol(ITEM_INFO *item, COLL_INFO *coll);
|
||||
void __cdecl Item_UpdateRoom(ITEM_INFO *item, int32_t height);
|
||||
int32_t __cdecl Item_TestBoundsCollide(
|
||||
@ -36,3 +36,4 @@ bool __cdecl Item_IsNearItem(
|
||||
|
||||
bool Item_IsSmashable(const ITEM_INFO *item);
|
||||
void Item_TakeDamage(ITEM_INFO *item, int16_t damage, bool hit_status);
|
||||
int32_t Item_GetDistance(const ITEM_INFO *item, const XYZ_32 *target);
|
||||
|
@ -1,14 +1,21 @@
|
||||
#include "game/lara/lara_cheat.h"
|
||||
|
||||
#include "game/camera.h"
|
||||
#include "game/console.h"
|
||||
#include "game/game_string.h"
|
||||
#include "game/inventory.h"
|
||||
#include "game/items.h"
|
||||
#include "game/lara/lara_control.h"
|
||||
#include "game/math.h"
|
||||
#include "game/output.h"
|
||||
#include "game/room.h"
|
||||
#include "global/funcs.h"
|
||||
#include "global/utils.h"
|
||||
#include "global/vars.h"
|
||||
|
||||
#include <libtrx/utils.h>
|
||||
#include <libtrx/vector.h>
|
||||
|
||||
void __cdecl Lara_Cheat_EndLevel(void)
|
||||
{
|
||||
g_LevelComplete = true;
|
||||
@ -21,6 +28,8 @@ bool __cdecl Lara_Cheat_EnterFlyMode(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
Lara_GetOffVehicle();
|
||||
|
||||
if (g_Lara.water_status != LWS_UNDERWATER || g_LaraItem->hit_points <= 0) {
|
||||
g_LaraItem->pos.y -= STEP_L;
|
||||
g_LaraItem->current_anim_state = LS_SWIM;
|
||||
@ -37,13 +46,6 @@ bool __cdecl Lara_Cheat_EnterFlyMode(void)
|
||||
g_Lara.torso_y_rot = 0;
|
||||
}
|
||||
|
||||
if (g_Lara.skidoo != NO_ITEM) {
|
||||
ITEM_INFO *const vehicle = &g_Items[g_Lara.skidoo];
|
||||
vehicle->anim_num = g_Objects[vehicle->object_num].anim_idx;
|
||||
vehicle->frame_num = g_Anims[vehicle->anim_num].frame_base;
|
||||
g_Lara.skidoo = NO_ITEM;
|
||||
}
|
||||
|
||||
g_Lara.water_status = LWS_CHEAT;
|
||||
g_Lara.spaz_effect_count = 0;
|
||||
g_Lara.spaz_effect = NULL;
|
||||
@ -114,3 +116,89 @@ void __cdecl Lara_Cheat_GetStuff(void)
|
||||
g_Lara.m16_ammo.ammo = 300;
|
||||
g_Lara.grenade_ammo.ammo = 300;
|
||||
}
|
||||
|
||||
bool Lara_Cheat_Teleport(int32_t x, int32_t y, int32_t z)
|
||||
{
|
||||
int16_t room_num = Room_GetIndexFromPos(x, y, z);
|
||||
if (room_num == NO_ROOM) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const SECTOR_INFO *sector = Room_GetSector(x, y, z, &room_num);
|
||||
int16_t height = Room_GetHeight(sector, x, y, z);
|
||||
|
||||
if (height == NO_HEIGHT) {
|
||||
// Sample a sphere of points around target x, y, z
|
||||
// and teleport to the first available location.
|
||||
VECTOR *const points = Vector_Create(sizeof(XYZ_32));
|
||||
|
||||
const int32_t radius = 10;
|
||||
const int32_t unit = STEP_L;
|
||||
for (int32_t dx = -radius; dx <= radius; dx++) {
|
||||
for (int32_t dz = -radius; dz <= radius; dz++) {
|
||||
if (SQUARE(dx) + SQUARE(dz) > SQUARE(radius)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const XYZ_32 point = {
|
||||
.x = ROUND_TO_SECTOR(x + dx * unit) + WALL_L / 2,
|
||||
.y = y,
|
||||
.z = ROUND_TO_SECTOR(z + dz * unit) + WALL_L / 2,
|
||||
};
|
||||
room_num = Room_GetIndexFromPos(point.x, point.y, point.z);
|
||||
if (room_num == NO_ROOM) {
|
||||
continue;
|
||||
}
|
||||
sector = Room_GetSector(point.x, point.y, point.z, &room_num);
|
||||
height = Room_GetHeight(sector, point.x, point.y, point.z);
|
||||
if (height == NO_HEIGHT) {
|
||||
continue;
|
||||
}
|
||||
Vector_Add(points, (void *)&point);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t best_distance = INT32_MAX;
|
||||
for (int32_t i = 0; i < points->count; i++) {
|
||||
const XYZ_32 *const point = (const XYZ_32 *)Vector_Get(points, i);
|
||||
const int32_t distance =
|
||||
XYZ_32_GetDistance(point, &g_LaraItem->pos);
|
||||
if (distance < best_distance) {
|
||||
best_distance = distance;
|
||||
x = point->x;
|
||||
y = point->y;
|
||||
z = point->z;
|
||||
}
|
||||
}
|
||||
|
||||
Vector_Free(points);
|
||||
if (best_distance == INT32_MAX) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
room_num = Room_GetIndexFromPos(x, y, z);
|
||||
if (room_num == NO_ROOM) {
|
||||
return false;
|
||||
}
|
||||
sector = Room_GetSector(x, y, z, &room_num);
|
||||
height = Room_GetHeight(sector, x, y, z);
|
||||
if (height == NO_HEIGHT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_LaraItem->pos.x = x;
|
||||
g_LaraItem->pos.y = y;
|
||||
g_LaraItem->pos.z = z;
|
||||
g_LaraItem->floor = height;
|
||||
|
||||
Lara_GetOffVehicle();
|
||||
|
||||
if (g_LaraItem->room_num != room_num) {
|
||||
const int16_t item_num = g_LaraItem - g_Items;
|
||||
Item_NewRoom(item_num, room_num);
|
||||
}
|
||||
|
||||
Camera_ResetPosition();
|
||||
return true;
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void __cdecl Lara_Cheat_EndLevel(void);
|
||||
bool __cdecl Lara_Cheat_EnterFlyMode(void);
|
||||
bool __cdecl Lara_Cheat_ExitFlyMode(void);
|
||||
void __cdecl Lara_Cheat_GetStuff(void);
|
||||
bool Lara_Cheat_Teleport(int32_t x, int32_t y, int32_t z);
|
||||
|
@ -952,3 +952,18 @@ void Lara_SwapSingleMesh(const LARA_MESH mesh, const GAME_OBJECT_ID object_id)
|
||||
{
|
||||
g_Lara.mesh_ptrs[mesh] = g_Meshes[g_Objects[object_id].mesh_idx + mesh];
|
||||
}
|
||||
|
||||
void Lara_GetOffVehicle(void)
|
||||
{
|
||||
if (g_Lara.skidoo != NO_ITEM) {
|
||||
ITEM_INFO *const vehicle = &g_Items[g_Lara.skidoo];
|
||||
vehicle->anim_num = g_Objects[vehicle->object_num].anim_idx;
|
||||
vehicle->frame_num = g_Anims[vehicle->anim_num].frame_base;
|
||||
g_Lara.skidoo = NO_ITEM;
|
||||
|
||||
g_LaraItem->current_anim_state = LS_STOP;
|
||||
g_LaraItem->goal_anim_state = LS_STOP;
|
||||
g_LaraItem->anim_num = LA_STAND_STILL;
|
||||
g_LaraItem->frame_num = g_Anims[g_LaraItem->anim_num].frame_base;
|
||||
}
|
||||
}
|
||||
|
@ -23,4 +23,5 @@ void __cdecl Lara_InitialiseInventory(int32_t level_num);
|
||||
|
||||
void __cdecl Lara_InitialiseMeshes(int32_t level_num);
|
||||
|
||||
void Lara_GetOffVehicle(void);
|
||||
void Lara_SwapSingleMesh(LARA_MESH mesh, GAME_OBJECT_ID);
|
||||
|
@ -641,7 +641,7 @@ static void __cdecl Level_LoadBoxes(VFILE *const file)
|
||||
for (int32_t i = 0; i < 2; i++) {
|
||||
for (int32_t j = 0; j < 4; j++) {
|
||||
const bool skip = j == 2
|
||||
|| (j == 1 && !g_Objects[O_SPIDER_or_WOLF].loaded
|
||||
|| (j == 1 && !g_Objects[O_SPIDER].loaded
|
||||
&& !g_Objects[O_SKIDOO_ARMED].loaded)
|
||||
|| (j == 3 && !g_Objects[O_YETI].loaded
|
||||
&& !g_Objects[O_WORKER_3].loaded);
|
||||
|
@ -149,7 +149,7 @@ void __cdecl LOT_InitialiseSlot(const int16_t item_num, const int32_t slot)
|
||||
creature->lot.drop = -WALL_L;
|
||||
break;
|
||||
|
||||
case O_SPIDER_or_WOLF:
|
||||
case O_SPIDER:
|
||||
case O_SKIDOO_ARMED:
|
||||
creature->lot.step = WALL_L / 2;
|
||||
creature->lot.drop = -WALL_L;
|
||||
|
218
src/game/objects/names.c
Normal file
218
src/game/objects/names.c
Normal file
@ -0,0 +1,218 @@
|
||||
#include "game/objects/names.h"
|
||||
|
||||
#include "game/inventory.h"
|
||||
#include "game/objects/common.h"
|
||||
#include "game/objects/vars.h"
|
||||
#include "global/vars.h"
|
||||
|
||||
#include <libtrx/log.h>
|
||||
#include <libtrx/memory.h>
|
||||
#include <libtrx/strings.h>
|
||||
#include <libtrx/utils.h>
|
||||
#include <libtrx/vector.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#define GOOD_MATCH_THRESHOLD 50
|
||||
|
||||
typedef struct {
|
||||
int32_t score;
|
||||
GAME_OBJECT_ID obj_id;
|
||||
} MATCH;
|
||||
|
||||
static const INVENTORY_ITEM *const m_InvItems[] = {
|
||||
&g_Inv_Item_Stopwatch, &g_Inv_Item_Pistols,
|
||||
&g_Inv_Item_Flare, &g_Inv_Item_Shotgun,
|
||||
&g_Inv_Item_Magnums, &g_Inv_Item_Uzis,
|
||||
&g_Inv_Item_Harpoon, &g_Inv_Item_M16,
|
||||
&g_Inv_Item_Grenade, &g_Inv_Item_PistolAmmo,
|
||||
&g_Inv_Item_ShotgunAmmo, &g_Inv_Item_MagnumAmmo,
|
||||
&g_Inv_Item_UziAmmo, &g_Inv_Item_HarpoonAmmo,
|
||||
&g_Inv_Item_M16Ammo, &g_Inv_Item_GrenadeAmmo,
|
||||
&g_Inv_Item_SmallMedi, &g_Inv_Item_LargeMedi,
|
||||
&g_Inv_Item_Pickup1, &g_Inv_Item_Pickup2,
|
||||
&g_Inv_Item_Puzzle1, &g_Inv_Item_Puzzle2,
|
||||
&g_Inv_Item_Puzzle3, &g_Inv_Item_Puzzle4,
|
||||
&g_Inv_Item_Key1, &g_Inv_Item_Key2,
|
||||
&g_Inv_Item_Key3, &g_Inv_Item_Key4,
|
||||
&g_Inv_Item_Passport, &g_Inv_Item_Graphics,
|
||||
&g_Inv_Item_Sound, &g_Inv_Item_Controls,
|
||||
&g_Inv_Item_Photo, NULL,
|
||||
};
|
||||
|
||||
static const char *m_ObjectNames[O_NUMBER_OF] = { NULL };
|
||||
|
||||
#undef OBJ_NAME_DEFINE
|
||||
#define OBJ_NAME_DEFINE(id, str) str,
|
||||
static const char *m_DefaultObjectNames[O_NUMBER_OF] = {
|
||||
#include "game/objects/names.def"
|
||||
};
|
||||
|
||||
#undef OBJ_NAME_DEFINE
|
||||
#define OBJ_NAME_DEFINE(id, str) \
|
||||
{ \
|
||||
QUOTE(id), \
|
||||
id, \
|
||||
},
|
||||
ENUM_STRING_MAP ENUM_STRING_MAP(GAME_OBJECT_ID)[] = {
|
||||
#include "game/objects/names.def"
|
||||
{ NULL, -1 }
|
||||
};
|
||||
|
||||
static int32_t Object_NameMatch(const char *user_input, const char *name);
|
||||
static void Object_TryMatch(
|
||||
VECTOR *matches, const char *user_input, const char *name,
|
||||
GAME_OBJECT_ID obj_id);
|
||||
|
||||
static int32_t Object_NameMatch(
|
||||
const char *const user_input, const char *const name)
|
||||
{
|
||||
int32_t score;
|
||||
|
||||
char *regex = Memory_Alloc(strlen(user_input) + 5);
|
||||
strcpy(regex, "\\b");
|
||||
strcat(regex, user_input);
|
||||
strcat(regex, "\\b");
|
||||
if (String_Match(name, regex)) {
|
||||
// Match by full word.
|
||||
score = GOOD_MATCH_THRESHOLD + strlen(user_input) * 100 / strlen(name);
|
||||
} else if (String_CaseSubstring(name, user_input)) {
|
||||
// Match by substring.
|
||||
score = strlen(user_input) * 100 / strlen(name);
|
||||
} else {
|
||||
// No match.
|
||||
score = 0;
|
||||
}
|
||||
Memory_FreePointer(®ex);
|
||||
return score;
|
||||
}
|
||||
|
||||
static void Object_TryMatch(
|
||||
VECTOR *const matches, const char *const user_input, const char *const name,
|
||||
const GAME_OBJECT_ID obj_id)
|
||||
{
|
||||
const int32_t score = Object_NameMatch(user_input, name);
|
||||
if (score > 0) {
|
||||
MATCH match = {
|
||||
.score = score,
|
||||
.obj_id = obj_id,
|
||||
};
|
||||
Vector_Add(matches, &match);
|
||||
}
|
||||
}
|
||||
|
||||
const char *Object_GetName(const GAME_OBJECT_ID obj_id)
|
||||
{
|
||||
// TODO: remove this in favor of changing the INVENTORY_ITEM.text directly
|
||||
// clang-format off
|
||||
switch (obj_id) {
|
||||
case O_PUZZLE_ITEM_1: return g_GF_Puzzle1Strings[g_CurrentLevel];
|
||||
case O_PUZZLE_ITEM_2: return g_GF_Puzzle2Strings[g_CurrentLevel];
|
||||
case O_PUZZLE_ITEM_3: return g_GF_Puzzle3Strings[g_CurrentLevel];
|
||||
case O_PUZZLE_ITEM_4: return g_GF_Puzzle4Strings[g_CurrentLevel];
|
||||
case O_KEY_ITEM_1: return g_GF_Key1Strings[g_CurrentLevel];
|
||||
case O_KEY_ITEM_2: return g_GF_Key2Strings[g_CurrentLevel];
|
||||
case O_KEY_ITEM_3: return g_GF_Key3Strings[g_CurrentLevel];
|
||||
case O_KEY_ITEM_4: return g_GF_Key4Strings[g_CurrentLevel];
|
||||
case O_PICKUP_ITEM_1: return g_GF_Pickup1Strings[g_CurrentLevel];
|
||||
case O_PICKUP_ITEM_2: return g_GF_Pickup2Strings[g_CurrentLevel];
|
||||
default: break;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
return m_ObjectNames[obj_id] != NULL ? (const char *)m_ObjectNames[obj_id]
|
||||
: m_DefaultObjectNames[obj_id];
|
||||
}
|
||||
|
||||
void Object_SetName(const GAME_OBJECT_ID obj_id, const char *const name)
|
||||
{
|
||||
assert(obj_id >= 0);
|
||||
assert(obj_id < O_NUMBER_OF);
|
||||
Memory_FreePointer(&m_ObjectNames[obj_id]);
|
||||
m_ObjectNames[obj_id] = Memory_DupStr(name);
|
||||
}
|
||||
|
||||
GAME_OBJECT_ID *Object_IdsFromName(
|
||||
const char *user_input, int32_t *out_match_count)
|
||||
{
|
||||
// first, calculate the number of matches to allocate
|
||||
VECTOR *matches = Vector_Create(sizeof(MATCH));
|
||||
|
||||
// Store matches from customizable inventory strings
|
||||
for (const INVENTORY_ITEM *const *item_ptr = m_InvItems; *item_ptr != NULL;
|
||||
item_ptr++) {
|
||||
const INVENTORY_ITEM *const item = *item_ptr;
|
||||
const GAME_OBJECT_ID obj_id =
|
||||
Object_GetCognateInverse(item->obj_num, g_ItemToInvObjectMap);
|
||||
Object_TryMatch(matches, user_input, item->string, obj_id);
|
||||
}
|
||||
|
||||
// Store matches from hardcoded strings
|
||||
for (GAME_OBJECT_ID obj_id = 0; obj_id < O_NUMBER_OF; obj_id++) {
|
||||
Object_TryMatch(matches, user_input, Object_GetName(obj_id), obj_id);
|
||||
}
|
||||
|
||||
// If we got a perfect match, discard poor matches
|
||||
bool good_matches = false;
|
||||
for (int i = 0; i < matches->count; i++) {
|
||||
const MATCH *const match = Vector_Get(matches, i);
|
||||
if (match->score >= GOOD_MATCH_THRESHOLD) {
|
||||
good_matches = true;
|
||||
}
|
||||
}
|
||||
if (good_matches) {
|
||||
for (int i = matches->count - 1; i >= 0; i--) {
|
||||
const MATCH *const match = Vector_Get(matches, i);
|
||||
if (match->score < GOOD_MATCH_THRESHOLD) {
|
||||
Vector_RemoveAt(matches, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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++) {
|
||||
if (((const MATCH *)Vector_Get(matches, i))->score
|
||||
< ((const MATCH *)Vector_Get(matches, j))->score) {
|
||||
Vector_Swap(matches, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < matches->count; i++) {
|
||||
const MATCH *const match = Vector_Get(matches, i);
|
||||
LOG_DEBUG(
|
||||
"%d. %s (%d)", i, Object_GetName(match->obj_id), match->score);
|
||||
}
|
||||
|
||||
// Make sure the returned matching object ids are unique
|
||||
GAME_OBJECT_ID *unique_ids =
|
||||
Memory_Alloc(sizeof(GAME_OBJECT_ID) * (matches->count + 1));
|
||||
|
||||
int32_t unique_count = 0;
|
||||
for (int32_t i = 0; i < matches->count; i++) {
|
||||
const MATCH *const match = Vector_Get(matches, i);
|
||||
bool is_unique = true;
|
||||
for (int32_t j = 0; j < unique_count; j++) {
|
||||
if (match->obj_id == unique_ids[j]) {
|
||||
is_unique = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_unique) {
|
||||
unique_ids[unique_count++] = match->obj_id;
|
||||
}
|
||||
}
|
||||
|
||||
Vector_Free(matches);
|
||||
matches = NULL;
|
||||
|
||||
// Finalize results
|
||||
unique_ids[unique_count] = NO_OBJECT;
|
||||
if (out_match_count != NULL) {
|
||||
*out_match_count = unique_count;
|
||||
}
|
||||
|
||||
Memory_FreePointer(&matches);
|
||||
return unique_ids;
|
||||
}
|
265
src/game/objects/names.def
Normal file
265
src/game/objects/names.def
Normal file
@ -0,0 +1,265 @@
|
||||
OBJ_NAME_DEFINE(O_LARA, "Lara")
|
||||
OBJ_NAME_DEFINE(O_LARA_PISTOLS, "Pistols Animation")
|
||||
OBJ_NAME_DEFINE(O_LARA_HAIR, "Braid")
|
||||
OBJ_NAME_DEFINE(O_LARA_SHOTGUN, "Shotgun Animation")
|
||||
OBJ_NAME_DEFINE(O_LARA_MAGNUMS, "Magnums Animation")
|
||||
OBJ_NAME_DEFINE(O_LARA_UZIS, "Uzis Animation")
|
||||
OBJ_NAME_DEFINE(O_LARA_M16, "M16 Animation")
|
||||
OBJ_NAME_DEFINE(O_LARA_GRENADE, "Grenade Launcher Animation")
|
||||
OBJ_NAME_DEFINE(O_LARA_HARPOON, "Harpoon Animation")
|
||||
OBJ_NAME_DEFINE(O_LARA_FLARE, "Flare Animation")
|
||||
OBJ_NAME_DEFINE(O_LARA_SKIDOO, "Snowmobile Animation")
|
||||
OBJ_NAME_DEFINE(O_LARA_BOAT, "Boat Animation")
|
||||
OBJ_NAME_DEFINE(O_LARA_EXTRA, "Lara's Extra Animation")
|
||||
OBJ_NAME_DEFINE(O_SKIDOO_FAST, "Red Snowmobile")
|
||||
OBJ_NAME_DEFINE(O_BOAT, "Boat")
|
||||
OBJ_NAME_DEFINE(O_DOG, "Dog")
|
||||
OBJ_NAME_DEFINE(O_CULT_1, "Masked Goon 1")
|
||||
OBJ_NAME_DEFINE(O_CULT_1A, "Masked Goon 2")
|
||||
OBJ_NAME_DEFINE(O_CULT_1B, "Masked Goon 3")
|
||||
OBJ_NAME_DEFINE(O_CULT_2, "Knife Thrower")
|
||||
OBJ_NAME_DEFINE(O_CULT_3, "Shotgun Goon")
|
||||
OBJ_NAME_DEFINE(O_MOUSE, "Rat")
|
||||
OBJ_NAME_DEFINE(O_DRAGON_FRONT, "Dragon Front")
|
||||
OBJ_NAME_DEFINE(O_DRAGON_BACK, "Dragon Back")
|
||||
OBJ_NAME_DEFINE(O_GONDOLA, "Gondola")
|
||||
OBJ_NAME_DEFINE(O_SHARK, "Shark")
|
||||
OBJ_NAME_DEFINE(O_EEL, "Eel")
|
||||
OBJ_NAME_DEFINE(O_BIG_EEL, "Big Eel")
|
||||
OBJ_NAME_DEFINE(O_BARRACUDA, "Barracuda")
|
||||
OBJ_NAME_DEFINE(O_DIVER, "Scuba Diver")
|
||||
OBJ_NAME_DEFINE(O_WORKER_1, "Gunman Goon 1")
|
||||
OBJ_NAME_DEFINE(O_WORKER_2, "Gunman Goon 2")
|
||||
OBJ_NAME_DEFINE(O_WORKER_3, "Stick Wielding Goon 1")
|
||||
OBJ_NAME_DEFINE(O_WORKER_4, "Stick Wielding Goon 2")
|
||||
OBJ_NAME_DEFINE(O_WORKER_5, "Flamethrower Goon")
|
||||
OBJ_NAME_DEFINE(O_JELLY, "Jellyfish")
|
||||
OBJ_NAME_DEFINE(O_SPIDER, "Spider")
|
||||
OBJ_NAME_DEFINE(O_BIG_SPIDER, "Giant Spider")
|
||||
OBJ_NAME_DEFINE(O_CROW, "Crow")
|
||||
OBJ_NAME_DEFINE(O_TIGER, "Tiger")
|
||||
OBJ_NAME_DEFINE(O_BARTOLI, "Marco Bartoli")
|
||||
OBJ_NAME_DEFINE(O_XIAN_SPEARMAN, "Xian Spearman")
|
||||
OBJ_NAME_DEFINE(O_XIAN_SPEARMAN_STATUE, "Xian Spearman Statue")
|
||||
OBJ_NAME_DEFINE(O_XIAN_KNIGHT, "Xian Knight")
|
||||
OBJ_NAME_DEFINE(O_XIAN_KNIGHT_STATUE, "Xian Knight")
|
||||
OBJ_NAME_DEFINE(O_YETI, "Yeti")
|
||||
OBJ_NAME_DEFINE(O_GIANT_YETI, "Bird Monster")
|
||||
OBJ_NAME_DEFINE(O_EAGLE, "Eagle")
|
||||
OBJ_NAME_DEFINE(O_BANDIT_1, "Mercenary 1")
|
||||
OBJ_NAME_DEFINE(O_BANDIT_2, "Mercenary 2")
|
||||
OBJ_NAME_DEFINE(O_BANDIT_2B, "Mercenary 3")
|
||||
OBJ_NAME_DEFINE(O_SKIDOO_ARMED, "Black Snowmobile")
|
||||
OBJ_NAME_DEFINE(O_SKIDMAN, "Black Snowmobile Driver")
|
||||
OBJ_NAME_DEFINE(O_MONK_1, "Monk 1")
|
||||
OBJ_NAME_DEFINE(O_MONK_2, "Monk 2")
|
||||
OBJ_NAME_DEFINE(O_FALLING_BLOCK_1, "Falling Block 1")
|
||||
OBJ_NAME_DEFINE(O_FALLING_BLOCK_2, "Falling Block 2")
|
||||
OBJ_NAME_DEFINE(O_FALLING_BLOCK_3, "Loose Boards")
|
||||
OBJ_NAME_DEFINE(O_PENDULUM_1, "Sandbag")
|
||||
OBJ_NAME_DEFINE(O_SPIKES, "Spikes")
|
||||
OBJ_NAME_DEFINE(O_ROLLING_BALL_1, "Boulder 1")
|
||||
OBJ_NAME_DEFINE(O_DARTS, "Disc")
|
||||
OBJ_NAME_DEFINE(O_DART_EMITTER, "Disc Emitter")
|
||||
OBJ_NAME_DEFINE(O_DRAW_BRIDGE, "Drawbridge")
|
||||
OBJ_NAME_DEFINE(O_TEETH_TRAP, "Teeth Trap")
|
||||
OBJ_NAME_DEFINE(O_LIFT, "Lift")
|
||||
OBJ_NAME_DEFINE(O_GENERAL, "Minisub")
|
||||
OBJ_NAME_DEFINE(O_MOVABLE_BLOCK_1, "Push Block 1")
|
||||
OBJ_NAME_DEFINE(O_MOVABLE_BLOCK_2, "Push Block 2")
|
||||
OBJ_NAME_DEFINE(O_MOVABLE_BLOCK_3, "Push Block 3")
|
||||
OBJ_NAME_DEFINE(O_MOVABLE_BLOCK_4, "Push Block 4")
|
||||
OBJ_NAME_DEFINE(O_BIG_BOWL, "Lava Bowl")
|
||||
OBJ_NAME_DEFINE(O_WINDOW_1, "Breakable Window 1")
|
||||
OBJ_NAME_DEFINE(O_WINDOW_2, "Breakable Window 2")
|
||||
OBJ_NAME_DEFINE(O_WINDOW_3, "Breakable Window 3")
|
||||
OBJ_NAME_DEFINE(O_WINDOW_4, "Breakable Window 4")
|
||||
OBJ_NAME_DEFINE(O_PROPELLER_1, "Airplane Propeller")
|
||||
OBJ_NAME_DEFINE(O_POWER_SAW, "Power Saw")
|
||||
OBJ_NAME_DEFINE(O_HOOK, "Hook")
|
||||
OBJ_NAME_DEFINE(O_FALLING_CEILING, "Falling Ceiling")
|
||||
OBJ_NAME_DEFINE(O_SPINNING_BLADE, "Spinning Blade")
|
||||
OBJ_NAME_DEFINE(O_BLADE, "Wall-mounted Blade")
|
||||
OBJ_NAME_DEFINE(O_KILLER_STATUE, "Statue with Sword")
|
||||
OBJ_NAME_DEFINE(O_ROLLING_BALL_2, "Boulder 2")
|
||||
OBJ_NAME_DEFINE(O_ICICLE, "Icicles")
|
||||
OBJ_NAME_DEFINE(O_SPIKE_WALL, "Spike Wall")
|
||||
OBJ_NAME_DEFINE(O_SPRING_BOARD, "Springboard")
|
||||
OBJ_NAME_DEFINE(O_CEILING_SPIKES, "Spiky Ceiling")
|
||||
OBJ_NAME_DEFINE(O_BELL, "Bell")
|
||||
OBJ_NAME_DEFINE(O_WATER_SPRITE, "Boat Wake")
|
||||
OBJ_NAME_DEFINE(O_SNOW_SPRITE, "Snowmobile Wale")
|
||||
OBJ_NAME_DEFINE(O_SKIDOO_LARA, "Snowmobile Animation")
|
||||
OBJ_NAME_DEFINE(O_SWITCH_TYPE_1, "Switch 1")
|
||||
OBJ_NAME_DEFINE(O_SWITCH_TYPE_2, "Switch 2")
|
||||
OBJ_NAME_DEFINE(O_PROPELLER_2, "Underwater Propeller")
|
||||
OBJ_NAME_DEFINE(O_PROPELLER_3, "Air Fan")
|
||||
OBJ_NAME_DEFINE(O_PENDULUM_2, "Swinging Box")
|
||||
OBJ_NAME_DEFINE(O_MESH_SWAP_1, "Mesh Swap 1")
|
||||
OBJ_NAME_DEFINE(O_MESH_SWAP_2, "Mesh Swap 2")
|
||||
OBJ_NAME_DEFINE(O_LARA_SWAP, "Lara Mesh Swap")
|
||||
OBJ_NAME_DEFINE(O_TEXT_BOX, "UI Frame")
|
||||
OBJ_NAME_DEFINE(O_ROLLING_BALL_3, "Boulder 3")
|
||||
OBJ_NAME_DEFINE(O_DEATH_SLIDE, "Zipline Handle")
|
||||
OBJ_NAME_DEFINE(O_SWITCH_TYPE_3, "Switch 3")
|
||||
OBJ_NAME_DEFINE(O_SWITCH_TYPE_4, "Switch 4")
|
||||
OBJ_NAME_DEFINE(O_SWITCH_TYPE_5, "Switch 5")
|
||||
OBJ_NAME_DEFINE(O_DOOR_TYPE_1, "Door 1")
|
||||
OBJ_NAME_DEFINE(O_DOOR_TYPE_2, "Door 2")
|
||||
OBJ_NAME_DEFINE(O_DOOR_TYPE_3, "Door 3")
|
||||
OBJ_NAME_DEFINE(O_DOOR_TYPE_4, "Door 4")
|
||||
OBJ_NAME_DEFINE(O_DOOR_TYPE_5, "Door 5")
|
||||
OBJ_NAME_DEFINE(O_DOOR_TYPE_6, "Door 6")
|
||||
OBJ_NAME_DEFINE(O_DOOR_TYPE_7, "Door 7")
|
||||
OBJ_NAME_DEFINE(O_DOOR_TYPE_8, "Door 8")
|
||||
OBJ_NAME_DEFINE(O_TRAPDOOR_TYPE_1, "Trapdoor 1")
|
||||
OBJ_NAME_DEFINE(O_TRAPDOOR_TYPE_2, "Trapdoor 2")
|
||||
OBJ_NAME_DEFINE(O_TRAPDOOR_TYPE_3, "Trapdoor 3")
|
||||
OBJ_NAME_DEFINE(O_BRIDGE_FLAT, "Bridge Flat")
|
||||
OBJ_NAME_DEFINE(O_BRIDGE_TILT_1, "Bridge Tilt 1")
|
||||
OBJ_NAME_DEFINE(O_BRIDGE_TILT_2, "Bridge Tilt 2")
|
||||
OBJ_NAME_DEFINE(O_PASSPORT_OPTION, "Passport Option")
|
||||
OBJ_NAME_DEFINE(O_COMPASS_OPTION, "Compass Option")
|
||||
OBJ_NAME_DEFINE(O_PHOTO_OPTION, "Photo Option")
|
||||
OBJ_NAME_DEFINE(O_PLAYER_1, "Cutscene Actor 1")
|
||||
OBJ_NAME_DEFINE(O_PLAYER_2, "Cutscene Actor 2")
|
||||
OBJ_NAME_DEFINE(O_PLAYER_3, "Cutscene Actor 3")
|
||||
OBJ_NAME_DEFINE(O_PLAYER_4, "Cutscene Actor 4")
|
||||
OBJ_NAME_DEFINE(O_PLAYER_5, "Cutscene Actor 5")
|
||||
OBJ_NAME_DEFINE(O_PLAYER_6, "Cutscene Actor 6")
|
||||
OBJ_NAME_DEFINE(O_PLAYER_7, "Cutscene Actor 7")
|
||||
OBJ_NAME_DEFINE(O_PLAYER_8, "Cutscene Actor 8")
|
||||
OBJ_NAME_DEFINE(O_PLAYER_9, "Cutscene Actor 9")
|
||||
OBJ_NAME_DEFINE(O_PLAYER_10, "Cutscene Actor 10")
|
||||
OBJ_NAME_DEFINE(O_PASSPORT_CLOSED, "Passport Closed")
|
||||
OBJ_NAME_DEFINE(O_COMPASS_ITEM, "Compass")
|
||||
OBJ_NAME_DEFINE(O_PISTOL_ITEM, "Pistols")
|
||||
OBJ_NAME_DEFINE(O_SHOTGUN_ITEM, "Shotgun")
|
||||
OBJ_NAME_DEFINE(O_MAGNUM_ITEM, "Magnums")
|
||||
OBJ_NAME_DEFINE(O_UZI_ITEM, "Uzis")
|
||||
OBJ_NAME_DEFINE(O_HARPOON_ITEM, "Harpoon")
|
||||
OBJ_NAME_DEFINE(O_M16_ITEM, "M16")
|
||||
OBJ_NAME_DEFINE(O_GRENADE_ITEM, "Grenade Launcher")
|
||||
OBJ_NAME_DEFINE(O_PISTOL_AMMO_ITEM, "Pistol Ammo")
|
||||
OBJ_NAME_DEFINE(O_SHOTGUN_AMMO_ITEM, "Shotgun Ammo")
|
||||
OBJ_NAME_DEFINE(O_MAGNUM_AMMO_ITEM, "Magnum Ammo")
|
||||
OBJ_NAME_DEFINE(O_UZI_AMMO_ITEM, "Uzi Ammo")
|
||||
OBJ_NAME_DEFINE(O_HARPOON_AMMO_ITEM, "Harpoon Ammo")
|
||||
OBJ_NAME_DEFINE(O_M16_AMMO_ITEM, "M16 Ammo")
|
||||
OBJ_NAME_DEFINE(O_GRENADE_AMMO_ITEM, "Grenade Launcher Ammo")
|
||||
OBJ_NAME_DEFINE(O_SMALL_MEDIPACK_ITEM, "Small Medipack")
|
||||
OBJ_NAME_DEFINE(O_LARGE_MEDIPACK_ITEM, "Large Medipack")
|
||||
OBJ_NAME_DEFINE(O_FLARES_ITEM, "Flares Box")
|
||||
OBJ_NAME_DEFINE(O_FLARE_ITEM, "Flare")
|
||||
OBJ_NAME_DEFINE(O_DETAIL_OPTION, "Detail Option")
|
||||
OBJ_NAME_DEFINE(O_SOUND_OPTION, "Sound Option")
|
||||
OBJ_NAME_DEFINE(O_CONTROL_OPTION, "Control Option")
|
||||
OBJ_NAME_DEFINE(O_GAMMA_OPTION, "Gamma Option")
|
||||
OBJ_NAME_DEFINE(O_PISTOL_OPTION, "Pistol Option")
|
||||
OBJ_NAME_DEFINE(O_SHOTGUN_OPTION, "Shotgun Option")
|
||||
OBJ_NAME_DEFINE(O_MAGNUM_OPTION, "Magnum Option")
|
||||
OBJ_NAME_DEFINE(O_UZI_OPTION, "Uzi Option")
|
||||
OBJ_NAME_DEFINE(O_HARPOON_OPTION, "Harpoon Option")
|
||||
OBJ_NAME_DEFINE(O_M16_OPTION, "M16 Option")
|
||||
OBJ_NAME_DEFINE(O_GRENADE_OPTION, "Grenade Launcher Option")
|
||||
OBJ_NAME_DEFINE(O_PISTOL_AMMO_OPTION, "Pistol Ammo Option")
|
||||
OBJ_NAME_DEFINE(O_SHOTGUN_AMMO_OPTION, "Shotgun Ammo Option")
|
||||
OBJ_NAME_DEFINE(O_MAGNUM_AMMO_OPTION, "Magnum Ammo Option")
|
||||
OBJ_NAME_DEFINE(O_UZI_AMMO_OPTION, "Uzi Ammo Option")
|
||||
OBJ_NAME_DEFINE(O_HARPOON_AMMO_OPTION, "Harpoon Ammo Option")
|
||||
OBJ_NAME_DEFINE(O_M16_AMMO_OPTION, "M16 Ammo Option")
|
||||
OBJ_NAME_DEFINE(O_GRENADE_AMMO_OPTION, "Grenade Launcher Ammo Option")
|
||||
OBJ_NAME_DEFINE(O_SMALL_MEDIPACK_OPTION, "Small Medipack Option")
|
||||
OBJ_NAME_DEFINE(O_LARGE_MEDIPACK_OPTION, "Large Medipack Option")
|
||||
OBJ_NAME_DEFINE(O_FLARES_OPTION, "Flare Option")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_ITEM_1, "Puzzle Item 1")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_ITEM_2, "Puzzle Item 2")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_ITEM_3, "Puzzle Item 3")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_ITEM_4, "Puzzle Item 4")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_OPTION_1, "Puzzle Option 1")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_OPTION_2, "Puzzle Option 2")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_OPTION_3, "Puzzle Option 3")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_OPTION_4, "Puzzle Option 4")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_HOLE_1, "Puzzle Hole 1 (Empty)")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_HOLE_2, "Puzzle Hole 2 (Empty)")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_HOLE_3, "Puzzle Hole 3 (Empty)")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_HOLE_4, "Puzzle Hole 4 (Empty)")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_DONE_1, "Puzzle Hole 1 (Done)")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_DONE_2, "Puzzle Hole 2 (Done)")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_DONE_3, "Puzzle Hole 3 (Done)")
|
||||
OBJ_NAME_DEFINE(O_PUZZLE_DONE_4, "Puzzle Hole 4 (Done)")
|
||||
OBJ_NAME_DEFINE(O_SECRET_1, "Secret 1")
|
||||
OBJ_NAME_DEFINE(O_SECRET_2, "Secret 2")
|
||||
OBJ_NAME_DEFINE(O_SECRET_3, "Secret 3")
|
||||
OBJ_NAME_DEFINE(O_KEY_ITEM_1, "Key 1")
|
||||
OBJ_NAME_DEFINE(O_KEY_ITEM_2, "Key 2")
|
||||
OBJ_NAME_DEFINE(O_KEY_ITEM_3, "Key 3")
|
||||
OBJ_NAME_DEFINE(O_KEY_ITEM_4, "Key 4")
|
||||
OBJ_NAME_DEFINE(O_KEY_OPTION_1, "Key Option 1")
|
||||
OBJ_NAME_DEFINE(O_KEY_OPTION_2, "Key Option 2")
|
||||
OBJ_NAME_DEFINE(O_KEY_OPTION_3, "Key Option 3")
|
||||
OBJ_NAME_DEFINE(O_KEY_OPTION_4, "Key Option 4")
|
||||
OBJ_NAME_DEFINE(O_KEY_HOLE_1, "Key Hole 1")
|
||||
OBJ_NAME_DEFINE(O_KEY_HOLE_2, "Key Hole 2")
|
||||
OBJ_NAME_DEFINE(O_KEY_HOLE_3, "Key Hole 3")
|
||||
OBJ_NAME_DEFINE(O_KEY_HOLE_4, "Key Hole 4")
|
||||
OBJ_NAME_DEFINE(O_PICKUP_ITEM_1, "Pickup Item 1")
|
||||
OBJ_NAME_DEFINE(O_PICKUP_ITEM_2, "Pickup Item 2")
|
||||
OBJ_NAME_DEFINE(O_PICKUP_OPTION_1, "Pickup Option 1")
|
||||
OBJ_NAME_DEFINE(O_PICKUP_OPTION_2, "Pickup Option 2")
|
||||
OBJ_NAME_DEFINE(O_SPHERE_OF_DOOM_1, "Dragon Explosion 1")
|
||||
OBJ_NAME_DEFINE(O_SPHERE_OF_DOOM_2, "Dragon Explosion 2")
|
||||
OBJ_NAME_DEFINE(O_SPHERE_OF_DOOM_3, "Dragon Explosion 3")
|
||||
OBJ_NAME_DEFINE(O_ALARM_SOUND, "Alarm")
|
||||
OBJ_NAME_DEFINE(O_BIRD_TWEETER_1, "Dripping Water")
|
||||
OBJ_NAME_DEFINE(O_DINO, "T-Rex")
|
||||
OBJ_NAME_DEFINE(O_BIRD_TWEETER_2, "Singing Birds")
|
||||
OBJ_NAME_DEFINE(O_CLOCK_CHIMES, "Bartoli Hideout clock")
|
||||
OBJ_NAME_DEFINE(O_DRAGON_BONES_1, "Placeholder")
|
||||
OBJ_NAME_DEFINE(O_DRAGON_BONES_2, "Dragon Bones Front")
|
||||
OBJ_NAME_DEFINE(O_DRAGON_BONES_3, "Dragon Bones Back")
|
||||
OBJ_NAME_DEFINE(O_HOT_LIQUID, "Extra Fire")
|
||||
OBJ_NAME_DEFINE(O_BOAT_BITS, "Boat Bits")
|
||||
OBJ_NAME_DEFINE(O_MINE, "Aquatic Mine")
|
||||
OBJ_NAME_DEFINE(O_INV_BACKGROUND, "Menu Background")
|
||||
OBJ_NAME_DEFINE(O_FX_RESERVED, "Gray disk")
|
||||
OBJ_NAME_DEFINE(O_GONG_BONGER, "Gong Stick")
|
||||
OBJ_NAME_DEFINE(O_DETONATOR_1, "Gong")
|
||||
OBJ_NAME_DEFINE(O_DETONATOR_2, "Detonator Box")
|
||||
OBJ_NAME_DEFINE(O_COPTER, "Helicopter")
|
||||
OBJ_NAME_DEFINE(O_EXPLOSION, "Explosion")
|
||||
OBJ_NAME_DEFINE(O_SPLASH, "Water Ripples")
|
||||
OBJ_NAME_DEFINE(O_BUBBLES, "Bubbles")
|
||||
OBJ_NAME_DEFINE(O_BUBBLE_EMITTER, "Bubbles Emitter")
|
||||
OBJ_NAME_DEFINE(O_BLOOD, "Blood")
|
||||
OBJ_NAME_DEFINE(O_DART_EFFECT, "Dart Effect")
|
||||
OBJ_NAME_DEFINE(O_FLARE_FIRE, "Flare sparks")
|
||||
OBJ_NAME_DEFINE(O_GLOW, "Glow")
|
||||
OBJ_NAME_DEFINE(O_GLOW_RESERVED, "Map Glow")
|
||||
OBJ_NAME_DEFINE(O_RICOCHET, "Ricochet")
|
||||
OBJ_NAME_DEFINE(O_TWINKLE, "Sparkles")
|
||||
OBJ_NAME_DEFINE(O_GUN_FLASH, "Gun Flash")
|
||||
OBJ_NAME_DEFINE(O_M16_FLASH, "M16 Flash")
|
||||
OBJ_NAME_DEFINE(O_BODY_PART, "Body Part")
|
||||
OBJ_NAME_DEFINE(O_CAMERA_TARGET, "Camera Target")
|
||||
OBJ_NAME_DEFINE(O_WATERFALL, "Waterfall")
|
||||
OBJ_NAME_DEFINE(O_MISSILE_HARPOON, "Missile Harpoon")
|
||||
OBJ_NAME_DEFINE(O_MISSILE_FLAME, "Missile Flame")
|
||||
OBJ_NAME_DEFINE(O_MISSILE_KNIFE, "Missile Knife")
|
||||
OBJ_NAME_DEFINE(O_GRENADE, "Grenade")
|
||||
OBJ_NAME_DEFINE(O_HARPOON_BOLT, "Harpoon Bolt")
|
||||
OBJ_NAME_DEFINE(O_LAVA, "Lava")
|
||||
OBJ_NAME_DEFINE(O_LAVA_EMITTER, "Lava Emitter")
|
||||
OBJ_NAME_DEFINE(O_FLAME, "Flame")
|
||||
OBJ_NAME_DEFINE(O_FLAME_EMITTER, "Flame Emitter")
|
||||
OBJ_NAME_DEFINE(O_SKYBOX, "Skybox")
|
||||
OBJ_NAME_DEFINE(O_ALPHABET, "Alphabet")
|
||||
OBJ_NAME_DEFINE(O_DYING_MONK, "Dying monk")
|
||||
OBJ_NAME_DEFINE(O_DING_DONG, "Doorbell")
|
||||
OBJ_NAME_DEFINE(O_LARA_ALARM, "Alarm Bell")
|
||||
OBJ_NAME_DEFINE(O_MINI_COPTER, "Helicopter 2")
|
||||
OBJ_NAME_DEFINE(O_WINSTON, "Winston")
|
||||
OBJ_NAME_DEFINE(O_ASSAULT_DIGITS, "Assault Digits")
|
||||
OBJ_NAME_DEFINE(O_FINAL_LEVEL_COUNTER, "Final Level Counter")
|
||||
OBJ_NAME_DEFINE(O_CUT_SHOTGUN, "Shotgun Shower Animation")
|
||||
OBJ_NAME_DEFINE(O_EARTHQUAKE, "Earthquake")
|
19
src/game/objects/names.h
Normal file
19
src/game/objects/names.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "global/types.h"
|
||||
|
||||
#include <libtrx/enum_str.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern ENUM_STRING_MAP ENUM_STRING_MAP(GAME_OBJECT_ID)[];
|
||||
|
||||
void Object_SetupNames(void);
|
||||
|
||||
const char *Object_GetName(GAME_OBJECT_ID obj_id);
|
||||
void Object_SetName(GAME_OBJECT_ID obj_id, const char *name);
|
||||
|
||||
// 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);
|
@ -24,15 +24,15 @@ const GAME_OBJECT_ID g_EnemyObjects[] = {
|
||||
O_WORKER_4,
|
||||
O_WORKER_5,
|
||||
O_JELLY,
|
||||
O_SPIDER_or_WOLF,
|
||||
O_BIG_SPIDER_or_BEAR,
|
||||
O_SPIDER,
|
||||
O_BIG_SPIDER,
|
||||
O_CROW,
|
||||
O_TIGER,
|
||||
O_BARTOLI,
|
||||
O_XIAN_LORD,
|
||||
O_CHINESE_2,
|
||||
O_WARRIOR,
|
||||
O_CHINESE_4,
|
||||
O_XIAN_SPEARMAN,
|
||||
O_XIAN_SPEARMAN_STATUE,
|
||||
O_XIAN_KNIGHT,
|
||||
O_XIAN_KNIGHT_STATUE,
|
||||
O_YETI,
|
||||
O_GIANT_YETI,
|
||||
O_EAGLE,
|
||||
@ -55,6 +55,42 @@ const GAME_OBJECT_ID g_FriendObjects[] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const GAME_OBJECT_ID g_PickupObjects[] = {
|
||||
// clang-format off
|
||||
O_PISTOL_ITEM,
|
||||
O_SHOTGUN_ITEM,
|
||||
O_MAGNUM_ITEM,
|
||||
O_UZI_ITEM,
|
||||
O_HARPOON_ITEM,
|
||||
O_M16_ITEM,
|
||||
O_GRENADE_ITEM,
|
||||
O_PISTOL_AMMO_ITEM,
|
||||
O_SHOTGUN_AMMO_ITEM,
|
||||
O_MAGNUM_AMMO_ITEM,
|
||||
O_UZI_AMMO_ITEM,
|
||||
O_HARPOON_AMMO_ITEM,
|
||||
O_M16_AMMO_ITEM,
|
||||
O_GRENADE_AMMO_ITEM,
|
||||
O_SMALL_MEDIPACK_ITEM,
|
||||
O_LARGE_MEDIPACK_ITEM,
|
||||
O_FLARES_ITEM,
|
||||
O_PUZZLE_ITEM_1,
|
||||
O_PUZZLE_ITEM_2,
|
||||
O_PUZZLE_ITEM_3,
|
||||
O_PUZZLE_ITEM_4,
|
||||
O_KEY_ITEM_1,
|
||||
O_KEY_ITEM_2,
|
||||
O_KEY_ITEM_3,
|
||||
O_KEY_ITEM_4,
|
||||
O_PICKUP_ITEM_1,
|
||||
O_PICKUP_ITEM_2,
|
||||
O_SECRET_1,
|
||||
O_SECRET_2,
|
||||
O_SECRET_3,
|
||||
NO_OBJECT,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const GAME_OBJECT_ID g_InvObjects[] = {
|
||||
// clang-format off
|
||||
O_PISTOL_OPTION,
|
||||
|
@ -6,4 +6,5 @@
|
||||
extern const GAME_OBJECT_ID g_EnemyObjects[];
|
||||
extern const GAME_OBJECT_ID g_FriendObjects[];
|
||||
extern const GAME_OBJECT_ID g_InvObjects[];
|
||||
extern const GAME_OBJECT_ID g_PickupObjects[];
|
||||
extern const GAME_OBJECT_PAIR g_ItemToInvObjectMap[];
|
||||
|
@ -2077,15 +2077,15 @@ typedef enum {
|
||||
O_WORKER_4 = 33,
|
||||
O_WORKER_5 = 34,
|
||||
O_JELLY = 35,
|
||||
O_SPIDER_or_WOLF = 36,
|
||||
O_BIG_SPIDER_or_BEAR = 37,
|
||||
O_SPIDER = 36,
|
||||
O_BIG_SPIDER = 37,
|
||||
O_CROW = 38,
|
||||
O_TIGER = 39,
|
||||
O_BARTOLI = 40,
|
||||
O_XIAN_LORD = 41,
|
||||
O_CHINESE_2 = 42,
|
||||
O_WARRIOR = 43,
|
||||
O_CHINESE_4 = 44,
|
||||
O_XIAN_SPEARMAN = 41,
|
||||
O_XIAN_SPEARMAN_STATUE = 42,
|
||||
O_XIAN_KNIGHT = 43,
|
||||
O_XIAN_KNIGHT_STATUE = 44,
|
||||
O_YETI = 45,
|
||||
O_GIANT_YETI = 46,
|
||||
O_EAGLE = 47,
|
||||
@ -2118,7 +2118,7 @@ typedef enum {
|
||||
O_WINDOW_3 = 74,
|
||||
O_WINDOW_4 = 75,
|
||||
O_PROPELLER_1 = 76,
|
||||
O_PROPELLER_2 = 77,
|
||||
O_POWER_SAW = 77,
|
||||
O_HOOK = 78,
|
||||
O_FALLING_CEILING = 79,
|
||||
O_SPINNING_BLADE = 80,
|
||||
@ -2135,8 +2135,8 @@ typedef enum {
|
||||
O_SKIDOO_LARA = 91,
|
||||
O_SWITCH_TYPE_1 = 92,
|
||||
O_SWITCH_TYPE_2 = 93,
|
||||
O_PROPELLER_3 = 94,
|
||||
O_PROPELLER_4 = 95,
|
||||
O_PROPELLER_2 = 94,
|
||||
O_PROPELLER_3 = 95,
|
||||
O_PENDULUM_2 = 96,
|
||||
O_MESH_SWAP_1 = 97,
|
||||
O_MESH_SWAP_2 = 98,
|
||||
|
6
src/global/utils.h
Normal file
6
src/global/utils.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "global/const.h"
|
||||
|
||||
#define ROUND_TO_CLICK(V) ((V) & ~(STEP_L - 1))
|
||||
#define ROUND_TO_SECTOR(V) ((V) & ~(WALL_L - 1))
|
@ -18,7 +18,19 @@ def get_string_map(path: Path) -> dict[str, str]:
|
||||
return result
|
||||
|
||||
|
||||
def postprocess_gameflow(gameflow: str, game_strings_map: dict[str, str]) -> str:
|
||||
def postprocess_gameflow(gameflow: str, object_strings_map: dict[str, str], game_strings_map: dict[str, str]) -> str:
|
||||
gameflow = re.sub(
|
||||
r'^( "object_strings": {)[^}]*(})',
|
||||
' "object_strings": {\n'
|
||||
+ "\n".join(
|
||||
f" {json.dumps(key)}: {json.dumps(value)},"
|
||||
for key, value in object_strings_map.items()
|
||||
)
|
||||
+ "\n }",
|
||||
gameflow,
|
||||
flags=re.M | re.DOTALL,
|
||||
)
|
||||
|
||||
gameflow = re.sub(
|
||||
r'^( "game_strings": {)[^}]*(})',
|
||||
' "game_strings": {\n'
|
||||
@ -34,12 +46,14 @@ def postprocess_gameflow(gameflow: str, game_strings_map: dict[str, str]) -> str
|
||||
|
||||
|
||||
def main() -> None:
|
||||
object_strings_map = get_string_map(OBJECT_STRINGS_DEF_PATH)
|
||||
game_strings_map = get_string_map(GAME_STRINGS_DEF_PATH)
|
||||
assert object_strings_map
|
||||
assert game_strings_map
|
||||
|
||||
for gameflow_path in SHIP_DIR.rglob("*gameflow*.json*"):
|
||||
old_gameflow = gameflow_path.read_text()
|
||||
new_gameflow = postprocess_gameflow(old_gameflow, game_strings_map)
|
||||
new_gameflow = postprocess_gameflow(old_gameflow, object_strings_map, game_strings_map)
|
||||
if new_gameflow != old_gameflow:
|
||||
gameflow_path.write_text(new_gameflow)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user