diff --git a/data/tr2/ship/cfg/TR2X_gameflow.json5 b/data/tr2/ship/cfg/TR2X_gameflow.json5 index 88bb694d9..f4c5fcbfa 100644 --- a/data/tr2/ship/cfg/TR2X_gameflow.json5 +++ b/data/tr2/ship/cfg/TR2X_gameflow.json5 @@ -11,28 +11,13 @@ "injections": [ "data/injections/wall_itemrots.bin", ], - "game_strings": { - "INV_ITEM_KEY_1": "Guardhouse Key", - "INV_ITEM_KEY_2": "Rusty Key", - }, }, // 2. Venice - { - "game_strings": { - "INV_ITEM_KEY_1": "Boathouse Key", - "INV_ITEM_KEY_2": "Steel Key", - "INV_ITEM_KEY_3": "Iron Key", - }, - }, + {}, // 3. Bartoli's Hideout - { - "game_strings": { - "INV_ITEM_KEY_1": "Library Key", - "INV_ITEM_KEY_2": "Detonator Key", - }, - }, + {}, // 4. Opera House { @@ -40,11 +25,6 @@ "data/injections/opera_fd.bin", "data/injections/opera_itemrots.bin", ], - "game_strings": { - "INV_ITEM_KEY_1": "Ornate Key", - "INV_ITEM_PUZZLE_1": "Relay Box", - "INV_ITEM_PUZZLE_2": "Circuit Board", - }, }, // 5. Offshore Rig @@ -52,11 +32,6 @@ "injections": [ "data/injections/rig_itemrots.bin", ], - "game_strings": { - "INV_ITEM_KEY_1": "Red Pass Card", - "INV_ITEM_KEY_2": "Yellow Pass Card", - "INV_ITEM_KEY_3": "Green Pass Card", - }, }, // 6. Diving Area @@ -64,49 +39,27 @@ "injections": [ "data/injections/diving_itemrots.bin", ], - "game_strings": { - "INV_ITEM_KEY_1": "Red Pass Card", - "INV_ITEM_KEY_4": "Blue Pass Card", - "INV_ITEM_PUZZLE_1": "Machine Chip", - }, }, // 7. 40 Fathoms {}, - // 8. The Wreck of Maria Doria + // 8. Wreck of the Maria Doria { "injections": [ "data/injections/wreck_fd.bin", "data/injections/wreck_itemrots.bin", ], - "game_strings": { - "INV_ITEM_KEY_1": "Rest Room Key", - "INV_ITEM_KEY_2": "Rusty Key", - "INV_ITEM_KEY_3": "Cabin Key", - "INV_ITEM_PUZZLE_1": "Circuit Breaker", - }, }, // 9. Living Quarters - { - "game_strings": { - "INV_ITEM_KEY_1": "Theatre Key", - "INV_ITEM_KEY_2": "Rusty Key", - }, - }, + {}, // 10. The Deck { "injections": [ "data/injections/deck_itemrots.bin", ], - "game_strings": { - "INV_ITEM_KEY_2": "Stern Key", - "INV_ITEM_KEY_3": "Storage Key", - "INV_ITEM_KEY_4": "Cabin Key", - "INV_ITEM_PUZZLE_4": "The Seraph", - }, }, // 11. Tibetan Foothills @@ -118,11 +71,6 @@ "object_strings": { "O_TIGER": "Snow Leopard", }, - "game_strings": { - "INV_ITEM_KEY_1": "Drawbridge Key", - "INV_ITEM_KEY_2": "Hut Key", - "INV_ITEM_PUZZLE_4": "The Seraph", - }, }, // 12. Barkhang Monastery @@ -130,15 +78,6 @@ "injections": [ "data/injections/barkhang_itemrots.bin", ], - "game_strings": { - "INV_ITEM_KEY_1": "Strongroom Key", - "INV_ITEM_KEY_2": "Trapdoor Key", - "INV_ITEM_KEY_3": "Rooftops Key", - "INV_ITEM_KEY_4": "Main Hall Key", - "INV_ITEM_PUZZLE_1": "Prayer Wheels", - "INV_ITEM_PUZZLE_2": "Gemstones", - "INV_ITEM_PUZZLE_4": "The Seraph", - }, }, // 13. Catacombs of the Talion @@ -147,13 +86,6 @@ "data/injections/catacombs_fd.bin", "data/injections/catacombs_itemrots.bin", ], - "object_strings": { - "O_TIGER": "Snow Leopard", - }, - "game_strings": { - "INV_ITEM_PICKUP_1": "Gong Hammer", - "INV_ITEM_PUZZLE_1": "Tibetan Mask", - }, }, // 14. Ice Palace @@ -162,14 +94,6 @@ "data/injections/palace_fd.bin", "data/injections/palace_itemrots.bin", ], - "object_strings": { - "O_TIGER": "Snow Leopard", - }, - "game_strings": { - "INV_ITEM_KEY_2": "Gong Hammer", - "INV_ITEM_PICKUP_2": "Talion", - "INV_ITEM_PUZZLE_1": "Tibetan Mask", - }, }, // 15. Temple of Xian @@ -178,12 +102,6 @@ "data/injections/xian_fd.bin", "data/injections/xian_itemrots.bin", ], - "game_strings": { - "INV_ITEM_KEY_2": "Gold Key", - "INV_ITEM_KEY_3": "Silver Key", - "INV_ITEM_KEY_4": "Main Chamber Key", - "INV_ITEM_PUZZLE_1": "The Dragon Seal", - }, }, // 16. Floating Islands @@ -192,453 +110,25 @@ "data/injections/floating_fd.bin", "data/injections/floating_itemrots.bin", ], - "game_strings": { - "INV_ITEM_PUZZLE_1": "Mystic Plaque", - "INV_ITEM_PUZZLE_2": "Mystic Plaque", - }, }, // 17. The Dragon's Lair - { - "game_strings": { - "INV_ITEM_PUZZLE_1": "Mystic Plaque", - "INV_ITEM_PUZZLE_2": "Dagger of Xian", - }, - }, + {}, // 18. Home Sweet Home { "injections": [ "data/injections/house_itemrots.bin", ], - "game_strings": { - "INV_ITEM_KEY_1": "Gun Cupboard Key", - "INV_ITEM_PUZZLE_1": "Dagger of Xian", - }, }, // 19. Demo 1 - { - "game_strings": { - "INV_ITEM_KEY_1": "Boathouse Key", - "INV_ITEM_KEY_2": "Steel Key", - "INV_ITEM_KEY_3": "Iron Key", - }, - }, + {}, // 20. Demo 2 - { - "game_strings": { - "INV_ITEM_KEY_1": "Rest Room Key", - "INV_ITEM_KEY_2": "Rusty Key", - "INV_ITEM_KEY_3": "Cabin Key", - "INV_ITEM_PUZZLE_1": "Circuit Breaker", - }, - }, + {}, // 21. Demo 3 - { - "game_strings": { - "INV_ITEM_KEY_1": "Drawbridge Key", - "INV_ITEM_KEY_2": "Hut Key", - "INV_ITEM_PUZZLE_4": "The Seraph", - }, - }, + {}, ], - - "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_BIRD_GUARDIAN": "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_SKIDOO_DRIVER": "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_DART": "Disc", - "O_DART_EMITTER": "Disc Emitter", - "O_DRAWBRIDGE": "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_SPRINGBOARD": "Springboard", - "O_CEILING_SPIKES": "Spiky Ceiling", - "O_BELL": "Bell", - "O_WATER_SPRITE": "Boat Wake", - "O_SNOW_SPRITE": "Snowmobile Wale", - "O_SKIDOO_TRACK": "Snowmobile Track", - "O_SWITCH_TYPE_AIRLOCK": "Airlock Switch", - "O_SWITCH_TYPE_SMALL": "Small Switch", - "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_ZIPLINE_HANDLE": "Zipline Handle", - "O_SWITCH_TYPE_BUTTON": "Switch Button", - "O_SWITCH_TYPE_NORMAL": "Lever/Switch", - "O_SWITCH_TYPE_UW": "Underwater Lever/Switch", - "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_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_FLARES_ITEM": "Flares Box", - "O_GAMMA_OPTION": "Gamma Option", - "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_HOLE_1": "Keyhole 1", - "O_KEY_HOLE_2": "Keyhole 2", - "O_KEY_HOLE_3": "Keyhole 3", - "O_KEY_HOLE_4": "Keyhole 4", - "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_BUBBLE": "Bubble", - "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 Mist", - "O_MISSILE_HARPOON": "Missile Harpoon", - "O_MISSILE_FLAME": "Missile Flame", - "O_MISSILE_KNIFE": "Missile Knife", - "O_GRENADE": "Grenade", - "O_HARPOON_BOLT": "Harpoon Bolt", - "O_EMBER": "Ember", - "O_EMBER_EMITTER": "Ember 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": { - "CONTROL_BACKEND_CONTROLLER": "Controller", - "CONTROL_BACKEND_KEYBOARD": "Keyboard", - "CONTROL_CUSTOMIZE": "Customize Controls", - "CONTROL_CUSTOM_1": "User Keys 1", - "CONTROL_CUSTOM_2": "User Keys 2", - "CONTROL_CUSTOM_3": "User Keys 3", - "CONTROL_DEFAULT_KEYS": "Default Keys", - "HEADING_GAME_OVER": "GAME OVER", - "HEADING_INVENTORY": "INVENTORY", - "HEADING_ITEMS": "ITEMS", - "HEADING_OPTION": "OPTION", - "INV_ITEM_CONTROLS": "Controls", - "INV_ITEM_DETAILS": "Detail Levels", - "INV_ITEM_FLARE": "Flare", - "INV_ITEM_GAME": "Game", - "INV_ITEM_GRENADE": "Grenade Launcher", - "INV_ITEM_GRENADE_AMMO": "Grenades", - "INV_ITEM_HARPOON": "Harpoon Gun", - "INV_ITEM_HARPOON_AMMO": "Harpoons", - "INV_ITEM_KEY_1": "Key", - "INV_ITEM_KEY_2": "Key", - "INV_ITEM_KEY_3": "Key", - "INV_ITEM_KEY_4": "Key", - "INV_ITEM_LARAS_HOME": "Lara's Home", - "INV_ITEM_LARGE_MEDIPACK": "Large Medi Pack", - "INV_ITEM_M16": "M16", - "INV_ITEM_M16_AMMO": "M16 Clips", - "INV_ITEM_MAGNUMS": "Automatic Pistols", - "INV_ITEM_MAGNUM_AMMO": "Automatic Pistol Clips", - "INV_ITEM_PICKUP_1": "Pickup", - "INV_ITEM_PICKUP_2": "Pickup", - "INV_ITEM_PISTOLS": "Pistols", - "INV_ITEM_PISTOL_AMMO": "Pistol Clips", - "INV_ITEM_PUZZLE_1": "Puzzle", - "INV_ITEM_PUZZLE_2": "Puzzle", - "INV_ITEM_PUZZLE_3": "Puzzle", - "INV_ITEM_PUZZLE_4": "Puzzle", - "INV_ITEM_SHOTGUN": "Shotgun", - "INV_ITEM_SHOTGUN_AMMO": "Shotgun Shells", - "INV_ITEM_SMALL_MEDIPACK": "Small Medi Pack", - "INV_ITEM_SOUND": "Sound", - "INV_ITEM_STOPWATCH": "Statistics", - "INV_ITEM_UZIS": "Uzis", - "INV_ITEM_UZI_AMMO": "Uzi Clips", - "KEYMAP_ACTION": "Action", - "KEYMAP_BACK": "Back", - "KEYMAP_CAMERA_BACK": "Camera Back", - "KEYMAP_CAMERA_DOWN": "Camera Down", - "KEYMAP_CAMERA_FORWARD": "Camera Forward", - "KEYMAP_CAMERA_LEFT": "Camera Left", - "KEYMAP_CAMERA_RESET": "Camera Reset", - "KEYMAP_CAMERA_RIGHT": "Camera Right", - "KEYMAP_CAMERA_UP": "Camera Up", - "KEYMAP_DRAW_WEAPON": "Draw Weapon", - "KEYMAP_ENTER_CONSOLE": "Dev Console", - "KEYMAP_FLY_CHEAT": "Fly Cheat", - "KEYMAP_INVENTORY": "Inventory", - "KEYMAP_ITEM_CHEAT": "Item Cheat", - "KEYMAP_JUMP": "Jump", - "KEYMAP_LEFT": "Left", - "KEYMAP_LEVEL_SKIP_CHEAT": "Level Skip", - "KEYMAP_LOOK": "Look", - "KEYMAP_PAUSE": "Pause", - "KEYMAP_RIGHT": "Right", - "KEYMAP_ROLL": "Roll", - "KEYMAP_RUN": "Run", - "KEYMAP_STEP_LEFT": "Step Left", - "KEYMAP_STEP_RIGHT": "Step Right", - "KEYMAP_TOGGLE_PHOTO_MODE": "Toggle Photo Mode", - "KEYMAP_TOGGLE_UI": "Toggle UI", - "KEYMAP_TURBO_CHEAT": "Turbo Speed", - "KEYMAP_USE_FLARE": "Flare", - "KEYMAP_WALK": "Walk", - "MISC_DEMO_MODE": "Demo Mode", - "MISC_EMPTY_SLOT": "- EMPTY SLOT -", - "MISC_EXIT": "Exit", - "MISC_NONE": "None", - "MISC_OFF": "Off", - "MISC_ON": "On", - "MISC_TOGGLE_HELP": "Toggle help", - "OSD_AMBIGUOUS_INPUT_2": "Ambiguous input: %s and %s", - "OSD_AMBIGUOUS_INPUT_3": "Ambiguous input: %s, %s, ...", - "OSD_BILINEAR_FILTER_OFF": "Bilinear filter: off", - "OSD_BILINEAR_FILTER_ON": "Bilinear filter: on", - "OSD_COMMAND_BAD_INVOCATION": "Invalid invocation: %s", - "OSD_COMMAND_UNAVAILABLE": "This command is not currently available", - "OSD_COMPLETE_LEVEL": "Level complete!", - "OSD_CONFIG_OPTION_GET": "%s is currently set to %s", - "OSD_CONFIG_OPTION_SET": "%s changed to %s", - "OSD_CONFIG_OPTION_UNKNOWN_OPTION": "Unknown option: %s", - "OSD_CURRENT_HEALTH_GET": "Current Lara's health: %d", - "OSD_CURRENT_HEALTH_SET": "Lara's health set to %d", - "OSD_DEPTH_BUFFER_OFF": "Z-Buffer: off", - "OSD_DEPTH_BUFFER_ON": "Z-Buffer: on", - "OSD_DOOR_CLOSE": "Close Sesame!", - "OSD_DOOR_OPEN": "Open Sesame!", - "OSD_DOOR_OPEN_FAIL": "No doors in Lara's proximity", - "OSD_FLIPMAP_FAIL_ALREADY_OFF": "Flipmap is already OFF", - "OSD_FLIPMAP_FAIL_ALREADY_ON": "Flipmap is already ON", - "OSD_FLIPMAP_OFF": "Flipmap set to OFF", - "OSD_FLIPMAP_ON": "Flipmap set to ON", - "OSD_FLY_MODE_OFF": "Fly mode disabled", - "OSD_FLY_MODE_ON": "Fly mode enabled", - "OSD_GIVE_ITEM": "Added %s to Lara's inventory", - "OSD_GIVE_ITEM_ALL_GUNS": "Lock'n'load - Lara's armed to the teeth!", - "OSD_GIVE_ITEM_ALL_KEYS": "Surprise! Every key item Lara needs is now in her backpack.", - "OSD_GIVE_ITEM_CHEAT": "Lara's backpack just got way heavier!", - "OSD_HARDWARE_RENDERING": "Hardware rendering", - "OSD_HEAL_ALREADY_FULL_HP": "Lara's already at full health", - "OSD_HEAL_SUCCESS": "Healed Lara back to full health", - "OSD_INVALID_DEMO": "Invalid demo", - "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_INVALID_SAMPLE": "Invalid sound: %d", - "OSD_KILL": "Bye-bye!", - "OSD_KILL_ALL": "Poof! %d enemies gone!", - "OSD_KILL_ALL_FAIL": "Uh-oh, there are no enemies left to kill...", - "OSD_KILL_FAIL": "No enemy nearby...", - "OSD_LIGHTNING_CONTRAST_FMT": "Lighting Contrast: %s", - "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 correction: off", - "OSD_PERSPECTIVE_FILTER_ON": "Perspective correction: on", - "OSD_PHOTO_MODE_LAUNCHED": "Entering photo mode, press %s for help", - "OSD_PLAY_LEVEL": "Loading %s", - "OSD_POS_GET": "Level: %d (%s) Room: %d\nPosition: %.3f, %.3f, %.3f\nRotation: %.3f,%.3f,%.3f", - "OSD_POS_SET_ITEM": "Teleported to object: %s", - "OSD_POS_SET_ITEM_FAIL": "Failed to teleport to object: %s", - "OSD_POS_SET_POS": "Teleported to position: %.3f %.3f %.3f", - "OSD_POS_SET_POS_FAIL": "Failed to teleport to position: %.3f %.3f %.3f", - "OSD_POS_SET_ROOM": "Teleported to room: %d", - "OSD_POS_SET_ROOM_FAIL": "Failed to teleport to room: %d", - "OSD_SAVE_GAME": "Saved game to save slot %d", - "OSD_SAVE_GAME_FAIL_INVALID_SLOT": "Invalid save slot %d", - "OSD_SCALER_FMT": "Scaler: x%d", - "OSD_SOFTWARE_RENDERING": "Software rendering", - "OSD_SOUND_AVAILABLE_SAMPLES": "Available sounds: %s", - "OSD_SOUND_PLAYING_SAMPLE": "Playing sound %d", - "OSD_SPEED_GET": "Current speed: %d", - "OSD_SPEED_SET": "Speed set to %d", - "OSD_UI_OFF": "UI disabled", - "OSD_UI_ON": "UI enabled", - "OSD_UNKNOWN_COMMAND": "Unknown command: %s", - "OSD_WIREFRAME_MODE_OFF": "Wireframe mode: off", - "OSD_WIREFRAME_MODE_ON": "Wireframe mode: on", - "PASSPORT_EXIT_DEMO": "Exit Demo", - "PASSPORT_EXIT_GAME": "Exit Game", - "PASSPORT_EXIT_TO_TITLE": "Exit to Title", - "PASSPORT_LOAD_GAME": "Load Game", - "PASSPORT_NEW_GAME": "New Game", - "PASSPORT_SAVE_GAME": "Save Game", - "PASSPORT_SELECT_LEVEL": "Select Level", - "PAUSE_ARE_YOU_SURE": "Are you sure?", - "PAUSE_CONTINUE": "Continue", - "PAUSE_EXIT_TO_TITLE": "Exit to title?", - "PAUSE_NO": "No", - "PAUSE_PAUSED": "Paused", - "PAUSE_QUIT": "Quit", - "PAUSE_YES": "Yes", - "PHOTO_MODE_FOV_PROMPT": "Adjust FOV", - "PHOTO_MODE_FOV_ROLE": "Draw <+Walk>", - "PHOTO_MODE_MOVE_PROMPT": "Move camera", - "PHOTO_MODE_RESET_PROMPT": "Reset camera", - "PHOTO_MODE_ROLL_PROMPT": "Roll camera", - "PHOTO_MODE_ROLL_ROLE": "Sidestep L/R", - "PHOTO_MODE_ROTATE90_PROMPT": "Rotate 90 degrees", - "PHOTO_MODE_ROTATE_PROMPT": "Rotate camera", - "PHOTO_MODE_SNAP_PROMPT": "Take picture", - "PHOTO_MODE_TITLE": "Photo Mode", - "SOUND_SET_VOLUMES": "Set Volumes", - "STATS_AMMO_HITS": "Hits", - "STATS_AMMO_USED": "Ammo Used", - "STATS_ASSAULT_FINISH": "Finish", - "STATS_ASSAULT_NO_TIMES_SET": "No Times Set", - "STATS_ASSAULT_TITLE": "BEST TIMES", - "STATS_BASIC_FMT": "%d", - "STATS_DETAIL_FMT": "%d of %d", - "STATS_DISTANCE_TRAVELLED": "Distance Travelled", - "STATS_FINAL_STATISTICS": "Final Statistics", - "STATS_KILLS": "Kills", - "STATS_MEDIPACKS_USED": "Health Packs Used", - "STATS_SECRETS": "Secrets Found", - "STATS_TIME_TAKEN": "Time Taken", - }, } diff --git a/data/tr2/ship/cfg/TR2X_strings.json5 b/data/tr2/ship/cfg/TR2X_strings.json5 new file mode 100644 index 000000000..cb621ae2b --- /dev/null +++ b/data/tr2/ship/cfg/TR2X_strings.json5 @@ -0,0 +1,598 @@ +{ + // NOTE: bad changes to this file may result in crashes. + // Lines starting with double slashes are comments and are ignored. + + "levels": [ + // 0. Lara's Home + {}, + + // 1. The Great Wall + { + "game_strings": { + "INV_ITEM_KEY_1": "Guardhouse Key", + "INV_ITEM_KEY_2": "Rusty Key", + }, + }, + + // 2. Venice + { + "game_strings": { + "INV_ITEM_KEY_1": "Boathouse Key", + "INV_ITEM_KEY_2": "Steel Key", + "INV_ITEM_KEY_3": "Iron Key", + }, + }, + + // 3. Bartoli's Hideout + { + "game_strings": { + "INV_ITEM_KEY_1": "Library Key", + "INV_ITEM_KEY_2": "Detonator Key", + }, + }, + + // 4. Opera House + { + "game_strings": { + "INV_ITEM_KEY_1": "Ornate Key", + "INV_ITEM_PUZZLE_1": "Relay Box", + "INV_ITEM_PUZZLE_2": "Circuit Board", + }, + }, + + // 5. Offshore Rig + { + "game_strings": { + "INV_ITEM_KEY_1": "Red Pass Card", + "INV_ITEM_KEY_2": "Yellow Pass Card", + "INV_ITEM_KEY_3": "Green Pass Card", + }, + }, + + // 6. Diving Area + { + "game_strings": { + "INV_ITEM_KEY_1": "Red Pass Card", + "INV_ITEM_KEY_4": "Blue Pass Card", + "INV_ITEM_PUZZLE_1": "Machine Chip", + }, + }, + + // 7. 40 Fathoms + {}, + + // 8. Wreck of the Maria Doria + { + "game_strings": { + "INV_ITEM_KEY_1": "Rest Room Key", + "INV_ITEM_KEY_2": "Rusty Key", + "INV_ITEM_KEY_3": "Cabin Key", + "INV_ITEM_PUZZLE_1": "Circuit Breaker", + }, + }, + + // 9. Living Quarters + { + "game_strings": { + "INV_ITEM_KEY_1": "Theatre Key", + "INV_ITEM_KEY_2": "Rusty Key", + }, + }, + + // 10. The Deck + { + "game_strings": { + "INV_ITEM_KEY_2": "Stern Key", + "INV_ITEM_KEY_3": "Storage Key", + "INV_ITEM_KEY_4": "Cabin Key", + "INV_ITEM_PUZZLE_4": "The Seraph", + }, + }, + + // 11. Tibetan Foothills + { + "object_strings": { + "O_TIGER": "Snow Leopard", + }, + "game_strings": { + "INV_ITEM_KEY_1": "Drawbridge Key", + "INV_ITEM_KEY_2": "Hut Key", + "INV_ITEM_PUZZLE_4": "The Seraph", + }, + }, + + // 12. Barkhang Monastery + { + "game_strings": { + "INV_ITEM_KEY_1": "Strongroom Key", + "INV_ITEM_KEY_2": "Trapdoor Key", + "INV_ITEM_KEY_3": "Rooftops Key", + "INV_ITEM_KEY_4": "Main Hall Key", + "INV_ITEM_PUZZLE_1": "Prayer Wheels", + "INV_ITEM_PUZZLE_2": "Gemstones", + "INV_ITEM_PUZZLE_4": "The Seraph", + }, + }, + + // 13. Catacombs of the Talion + { + "object_strings": { + "O_TIGER": "Snow Leopard", + }, + "game_strings": { + "INV_ITEM_PICKUP_1": "Gong Hammer", + "INV_ITEM_PUZZLE_1": "Tibetan Mask", + }, + }, + + // 14. Ice Palace + { + "object_strings": { + "O_TIGER": "Snow Leopard", + }, + "game_strings": { + "INV_ITEM_KEY_2": "Gong Hammer", + "INV_ITEM_PICKUP_2": "Talion", + "INV_ITEM_PUZZLE_1": "Tibetan Mask", + }, + }, + + // 15. Temple of Xian + { + "game_strings": { + "INV_ITEM_KEY_2": "Gold Key", + "INV_ITEM_KEY_3": "Silver Key", + "INV_ITEM_KEY_4": "Main Chamber Key", + "INV_ITEM_PUZZLE_1": "The Dragon Seal", + }, + }, + + // 16. Floating Islands + { + "game_strings": { + "INV_ITEM_PUZZLE_1": "Mystic Plaque", + "INV_ITEM_PUZZLE_2": "Mystic Plaque", + }, + }, + + // 17. The Dragon's Lair + { + "game_strings": { + "INV_ITEM_PUZZLE_1": "Mystic Plaque", + "INV_ITEM_PUZZLE_2": "Dagger of Xian", + }, + }, + + // 18. Home Sweet Home + { + "game_strings": { + "INV_ITEM_KEY_1": "Gun Cupboard Key", + "INV_ITEM_PUZZLE_1": "Dagger of Xian", + }, + }, + + // 19. Demo 1 + { + "game_strings": { + "INV_ITEM_KEY_1": "Boathouse Key", + "INV_ITEM_KEY_2": "Steel Key", + "INV_ITEM_KEY_3": "Iron Key", + }, + }, + + // 20. Demo 2 + { + "game_strings": { + "INV_ITEM_KEY_1": "Rest Room Key", + "INV_ITEM_KEY_2": "Rusty Key", + "INV_ITEM_KEY_3": "Cabin Key", + "INV_ITEM_PUZZLE_1": "Circuit Breaker", + }, + }, + + // 21. Demo 3 + { + "game_strings": { + "INV_ITEM_KEY_1": "Drawbridge Key", + "INV_ITEM_KEY_2": "Hut Key", + "INV_ITEM_PUZZLE_4": "The Seraph", + }, + }, + ], + + "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_BIRD_GUARDIAN": "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_SKIDOO_DRIVER": "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_DART": "Disc", + "O_DART_EMITTER": "Disc Emitter", + "O_DRAWBRIDGE": "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_SPRINGBOARD": "Springboard", + "O_CEILING_SPIKES": "Spiky Ceiling", + "O_BELL": "Bell", + "O_WATER_SPRITE": "Boat Wake", + "O_SNOW_SPRITE": "Snowmobile Wale", + "O_SKIDOO_TRACK": "Snowmobile Track", + "O_SWITCH_TYPE_AIRLOCK": "Airlock Switch", + "O_SWITCH_TYPE_SMALL": "Small Switch", + "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_ZIPLINE_HANDLE": "Zipline Handle", + "O_SWITCH_TYPE_BUTTON": "Switch Button", + "O_SWITCH_TYPE_NORMAL": "Lever/Switch", + "O_SWITCH_TYPE_UW": "Underwater Lever/Switch", + "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_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_FLARES_ITEM": "Flares Box", + "O_GAMMA_OPTION": "Gamma Option", + "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_HOLE_1": "Keyhole 1", + "O_KEY_HOLE_2": "Keyhole 2", + "O_KEY_HOLE_3": "Keyhole 3", + "O_KEY_HOLE_4": "Keyhole 4", + "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_BUBBLE": "Bubble", + "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 Mist", + "O_MISSILE_HARPOON": "Missile Harpoon", + "O_MISSILE_FLAME": "Missile Flame", + "O_MISSILE_KNIFE": "Missile Knife", + "O_GRENADE": "Grenade", + "O_HARPOON_BOLT": "Harpoon Bolt", + "O_EMBER": "Ember", + "O_EMBER_EMITTER": "Ember 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": { + "CONTROL_BACKEND_CONTROLLER": "Controller", + "CONTROL_BACKEND_KEYBOARD": "Keyboard", + "CONTROL_CUSTOMIZE": "Customize Controls", + "CONTROL_CUSTOM_1": "User Keys 1", + "CONTROL_CUSTOM_2": "User Keys 2", + "CONTROL_CUSTOM_3": "User Keys 3", + "CONTROL_DEFAULT_KEYS": "Default Keys", + "HEADING_GAME_OVER": "GAME OVER", + "HEADING_INVENTORY": "INVENTORY", + "HEADING_ITEMS": "ITEMS", + "HEADING_OPTION": "OPTION", + "INV_ITEM_CONTROLS": "Controls", + "INV_ITEM_DETAILS": "Detail Levels", + "INV_ITEM_FLARE": "Flare", + "INV_ITEM_GAME": "Game", + "INV_ITEM_GRENADE": "Grenade Launcher", + "INV_ITEM_GRENADE_AMMO": "Grenades", + "INV_ITEM_HARPOON": "Harpoon Gun", + "INV_ITEM_HARPOON_AMMO": "Harpoons", + "INV_ITEM_KEY_1": "Key", + "INV_ITEM_KEY_2": "Key", + "INV_ITEM_KEY_3": "Key", + "INV_ITEM_KEY_4": "Key", + "INV_ITEM_LARAS_HOME": "Lara's Home", + "INV_ITEM_LARGE_MEDIPACK": "Large Medi Pack", + "INV_ITEM_M16": "M16", + "INV_ITEM_M16_AMMO": "M16 Clips", + "INV_ITEM_MAGNUMS": "Automatic Pistols", + "INV_ITEM_MAGNUM_AMMO": "Automatic Pistol Clips", + "INV_ITEM_PICKUP_1": "Pickup", + "INV_ITEM_PICKUP_2": "Pickup", + "INV_ITEM_PISTOLS": "Pistols", + "INV_ITEM_PISTOL_AMMO": "Pistol Clips", + "INV_ITEM_PUZZLE_1": "Puzzle", + "INV_ITEM_PUZZLE_2": "Puzzle", + "INV_ITEM_PUZZLE_3": "Puzzle", + "INV_ITEM_PUZZLE_4": "Puzzle", + "INV_ITEM_SHOTGUN": "Shotgun", + "INV_ITEM_SHOTGUN_AMMO": "Shotgun Shells", + "INV_ITEM_SMALL_MEDIPACK": "Small Medi Pack", + "INV_ITEM_SOUND": "Sound", + "INV_ITEM_STOPWATCH": "Statistics", + "INV_ITEM_UZIS": "Uzis", + "INV_ITEM_UZI_AMMO": "Uzi Clips", + "KEYMAP_ACTION": "Action", + "KEYMAP_BACK": "Back", + "KEYMAP_CAMERA_BACK": "Camera Back", + "KEYMAP_CAMERA_DOWN": "Camera Down", + "KEYMAP_CAMERA_FORWARD": "Camera Forward", + "KEYMAP_CAMERA_LEFT": "Camera Left", + "KEYMAP_CAMERA_RESET": "Camera Reset", + "KEYMAP_CAMERA_RIGHT": "Camera Right", + "KEYMAP_CAMERA_UP": "Camera Up", + "KEYMAP_DRAW_WEAPON": "Draw Weapon", + "KEYMAP_ENTER_CONSOLE": "Dev Console", + "KEYMAP_FLY_CHEAT": "Fly Cheat", + "KEYMAP_INVENTORY": "Inventory", + "KEYMAP_ITEM_CHEAT": "Item Cheat", + "KEYMAP_JUMP": "Jump", + "KEYMAP_LEFT": "Left", + "KEYMAP_LEVEL_SKIP_CHEAT": "Level Skip", + "KEYMAP_LOOK": "Look", + "KEYMAP_PAUSE": "Pause", + "KEYMAP_RIGHT": "Right", + "KEYMAP_ROLL": "Roll", + "KEYMAP_RUN": "Run", + "KEYMAP_STEP_LEFT": "Step Left", + "KEYMAP_STEP_RIGHT": "Step Right", + "KEYMAP_TOGGLE_PHOTO_MODE": "Toggle Photo Mode", + "KEYMAP_TOGGLE_UI": "Toggle UI", + "KEYMAP_TURBO_CHEAT": "Turbo Speed", + "KEYMAP_USE_FLARE": "Flare", + "KEYMAP_WALK": "Walk", + "MISC_DEMO_MODE": "Demo Mode", + "MISC_EMPTY_SLOT": "- EMPTY SLOT -", + "MISC_EXIT": "Exit", + "MISC_NONE": "None", + "MISC_OFF": "Off", + "MISC_ON": "On", + "MISC_TOGGLE_HELP": "Toggle help", + "OSD_AMBIGUOUS_INPUT_2": "Ambiguous input: %s and %s", + "OSD_AMBIGUOUS_INPUT_3": "Ambiguous input: %s, %s, ...", + "OSD_BILINEAR_FILTER_OFF": "Bilinear filter: off", + "OSD_BILINEAR_FILTER_ON": "Bilinear filter: on", + "OSD_COMMAND_BAD_INVOCATION": "Invalid invocation: %s", + "OSD_COMMAND_UNAVAILABLE": "This command is not currently available", + "OSD_COMPLETE_LEVEL": "Level complete!", + "OSD_CONFIG_OPTION_GET": "%s is currently set to %s", + "OSD_CONFIG_OPTION_SET": "%s changed to %s", + "OSD_CONFIG_OPTION_UNKNOWN_OPTION": "Unknown option: %s", + "OSD_CURRENT_HEALTH_GET": "Current Lara's health: %d", + "OSD_CURRENT_HEALTH_SET": "Lara's health set to %d", + "OSD_DEPTH_BUFFER_OFF": "Z-Buffer: off", + "OSD_DEPTH_BUFFER_ON": "Z-Buffer: on", + "OSD_DOOR_CLOSE": "Close Sesame!", + "OSD_DOOR_OPEN": "Open Sesame!", + "OSD_DOOR_OPEN_FAIL": "No doors in Lara's proximity", + "OSD_FLIPMAP_FAIL_ALREADY_OFF": "Flipmap is already OFF", + "OSD_FLIPMAP_FAIL_ALREADY_ON": "Flipmap is already ON", + "OSD_FLIPMAP_OFF": "Flipmap set to OFF", + "OSD_FLIPMAP_ON": "Flipmap set to ON", + "OSD_FLY_MODE_OFF": "Fly mode disabled", + "OSD_FLY_MODE_ON": "Fly mode enabled", + "OSD_GIVE_ITEM": "Added %s to Lara's inventory", + "OSD_GIVE_ITEM_ALL_GUNS": "Lock'n'load - Lara's armed to the teeth!", + "OSD_GIVE_ITEM_ALL_KEYS": "Surprise! Every key item Lara needs is now in her backpack.", + "OSD_GIVE_ITEM_CHEAT": "Lara's backpack just got way heavier!", + "OSD_HARDWARE_RENDERING": "Hardware rendering", + "OSD_HEAL_ALREADY_FULL_HP": "Lara's already at full health", + "OSD_HEAL_SUCCESS": "Healed Lara back to full health", + "OSD_INVALID_DEMO": "Invalid demo", + "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_INVALID_SAMPLE": "Invalid sound: %d", + "OSD_KILL": "Bye-bye!", + "OSD_KILL_ALL": "Poof! %d enemies gone!", + "OSD_KILL_ALL_FAIL": "Uh-oh, there are no enemies left to kill...", + "OSD_KILL_FAIL": "No enemy nearby...", + "OSD_LIGHTNING_CONTRAST_FMT": "Lighting Contrast: %s", + "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 correction: off", + "OSD_PERSPECTIVE_FILTER_ON": "Perspective correction: on", + "OSD_PHOTO_MODE_LAUNCHED": "Entering photo mode, press %s for help", + "OSD_PLAY_LEVEL": "Loading %s", + "OSD_POS_GET": "Level: %d (%s) Room: %d\nPosition: %.3f, %.3f, %.3f\nRotation: %.3f,%.3f,%.3f", + "OSD_POS_SET_ITEM": "Teleported to object: %s", + "OSD_POS_SET_ITEM_FAIL": "Failed to teleport to object: %s", + "OSD_POS_SET_POS": "Teleported to position: %.3f %.3f %.3f", + "OSD_POS_SET_POS_FAIL": "Failed to teleport to position: %.3f %.3f %.3f", + "OSD_POS_SET_ROOM": "Teleported to room: %d", + "OSD_POS_SET_ROOM_FAIL": "Failed to teleport to room: %d", + "OSD_SAVE_GAME": "Saved game to save slot %d", + "OSD_SAVE_GAME_FAIL_INVALID_SLOT": "Invalid save slot %d", + "OSD_SCALER_FMT": "Scaler: x%d", + "OSD_SOFTWARE_RENDERING": "Software rendering", + "OSD_SOUND_AVAILABLE_SAMPLES": "Available sounds: %s", + "OSD_SOUND_PLAYING_SAMPLE": "Playing sound %d", + "OSD_SPEED_GET": "Current speed: %d", + "OSD_SPEED_SET": "Speed set to %d", + "OSD_UI_OFF": "UI disabled", + "OSD_UI_ON": "UI enabled", + "OSD_UNKNOWN_COMMAND": "Unknown command: %s", + "OSD_WIREFRAME_MODE_OFF": "Wireframe mode: off", + "OSD_WIREFRAME_MODE_ON": "Wireframe mode: on", + "PASSPORT_EXIT_DEMO": "Exit Demo", + "PASSPORT_EXIT_GAME": "Exit Game", + "PASSPORT_EXIT_TO_TITLE": "Exit to Title", + "PASSPORT_LOAD_GAME": "Load Game", + "PASSPORT_NEW_GAME": "New Game", + "PASSPORT_SAVE_GAME": "Save Game", + "PASSPORT_SELECT_LEVEL": "Select Level", + "PAUSE_ARE_YOU_SURE": "Are you sure?", + "PAUSE_CONTINUE": "Continue", + "PAUSE_EXIT_TO_TITLE": "Exit to title?", + "PAUSE_NO": "No", + "PAUSE_PAUSED": "Paused", + "PAUSE_QUIT": "Quit", + "PAUSE_YES": "Yes", + "PHOTO_MODE_FOV_PROMPT": "Adjust FOV", + "PHOTO_MODE_FOV_ROLE": "Draw <+Walk>", + "PHOTO_MODE_MOVE_PROMPT": "Move camera", + "PHOTO_MODE_RESET_PROMPT": "Reset camera", + "PHOTO_MODE_ROLL_PROMPT": "Roll camera", + "PHOTO_MODE_ROLL_ROLE": "Sidestep L/R", + "PHOTO_MODE_ROTATE90_PROMPT": "Rotate 90 degrees", + "PHOTO_MODE_ROTATE_PROMPT": "Rotate camera", + "PHOTO_MODE_SNAP_PROMPT": "Take picture", + "PHOTO_MODE_TITLE": "Photo Mode", + "SOUND_SET_VOLUMES": "Set Volumes", + "STATS_AMMO_HITS": "Hits", + "STATS_AMMO_USED": "Ammo Used", + "STATS_ASSAULT_FINISH": "Finish", + "STATS_ASSAULT_NO_TIMES_SET": "No Times Set", + "STATS_ASSAULT_TITLE": "BEST TIMES", + "STATS_BASIC_FMT": "%d", + "STATS_DETAIL_FMT": "%d of %d", + "STATS_DISTANCE_TRAVELLED": "Distance Travelled", + "STATS_FINAL_STATISTICS": "Final Statistics", + "STATS_KILLS": "Kills", + "STATS_MEDIPACKS_USED": "Health Packs Used", + "STATS_SECRETS": "Secrets Found", + "STATS_TIME_TAKEN": "Time Taken", + }, +} diff --git a/docs/tr2/CHANGELOG.md b/docs/tr2/CHANGELOG.md index 65b6489f6..987a8ead7 100644 --- a/docs/tr2/CHANGELOG.md +++ b/docs/tr2/CHANGELOG.md @@ -14,6 +14,7 @@ | Toggle photo mode | --- | F1 | | Toggle photo mode UI | --- | H | - changed the `/kill` command with no arguments to look for enemies within 5 tiles (#2297) +- changed the game data to use a separate strings file for text information, removing it from the game flow file - fixed showing inventory ring up/down arrows when uncalled for (#2225) - fixed Lara never stepping backwards off a step using her right foot (#1602) - fixed blood spawning on Lara from gunshots using incorrect positioning data (#2253) diff --git a/src/libtrx/game/game_string_table/aliases.def b/src/libtrx/game/game_string_table/aliases.def new file mode 100644 index 000000000..12c466e9c --- /dev/null +++ b/src/libtrx/game/game_string_table/aliases.def @@ -0,0 +1,5 @@ +#if TR_VERSION == 1 +#include "aliases_tr1.def" +#elif TR_VERSION == 2 +#include "aliases_tr2.def" +#endif diff --git a/src/libtrx/game/game_string_table/aliases_tr1.def b/src/libtrx/game/game_string_table/aliases_tr1.def new file mode 100644 index 000000000..53069ee14 --- /dev/null +++ b/src/libtrx/game/game_string_table/aliases_tr1.def @@ -0,0 +1,56 @@ +OBJ_ALIAS_DEFINE(O_PISTOL_ITEM, GS_ID(INV_ITEM_PISTOLS)) +OBJ_ALIAS_DEFINE(O_PISTOL_OPTION, GS_ID(INV_ITEM_PISTOLS)) +OBJ_ALIAS_DEFINE(O_SHOTGUN_ITEM, GS_ID(INV_ITEM_SHOTGUN)) +OBJ_ALIAS_DEFINE(O_SHOTGUN_OPTION, GS_ID(INV_ITEM_SHOTGUN)) +OBJ_ALIAS_DEFINE(O_MAGNUM_ITEM, GS_ID(INV_ITEM_MAGNUM)) +OBJ_ALIAS_DEFINE(O_MAGNUM_OPTION, GS_ID(INV_ITEM_MAGNUM)) +OBJ_ALIAS_DEFINE(O_UZI_ITEM, GS_ID(INV_ITEM_UZI)) +OBJ_ALIAS_DEFINE(O_UZI_OPTION, GS_ID(INV_ITEM_UZI)) +OBJ_ALIAS_DEFINE(O_PISTOL_AMMO_ITEM, GS_ID(INV_ITEM_PISTOL_AMMO)) +OBJ_ALIAS_DEFINE(O_PISTOL_AMMO_OPTION, GS_ID(INV_ITEM_PISTOL_AMMO)) +OBJ_ALIAS_DEFINE(O_SG_AMMO_ITEM, GS_ID(INV_ITEM_SHOTGUN_AMMO)) +OBJ_ALIAS_DEFINE(O_SG_AMMO_OPTION, GS_ID(INV_ITEM_SHOTGUN_AMMO)) +OBJ_ALIAS_DEFINE(O_MAG_AMMO_ITEM, GS_ID(INV_ITEM_MAGNUM_AMMO)) +OBJ_ALIAS_DEFINE(O_MAG_AMMO_OPTION, GS_ID(INV_ITEM_MAGNUM_AMMO)) +OBJ_ALIAS_DEFINE(O_UZI_AMMO_ITEM, GS_ID(INV_ITEM_UZI_AMMO)) +OBJ_ALIAS_DEFINE(O_UZI_AMMO_OPTION, GS_ID(INV_ITEM_UZI_AMMO)) +OBJ_ALIAS_DEFINE(O_EXPLOSIVE_ITEM, GS_ID(INV_ITEM_GRENADE)) +OBJ_ALIAS_DEFINE(O_EXPLOSIVE_OPTION, GS_ID(INV_ITEM_GRENADE)) +OBJ_ALIAS_DEFINE(O_MEDI_ITEM, GS_ID(INV_ITEM_SMALL_MEDIPACK)) +OBJ_ALIAS_DEFINE(O_MEDI_OPTION, GS_ID(INV_ITEM_SMALL_MEDIPACK)) +OBJ_ALIAS_DEFINE(O_BIGMEDI_ITEM, GS_ID(INV_ITEM_LARGE_MEDIPACK)) +OBJ_ALIAS_DEFINE(O_BIGMEDI_OPTION, GS_ID(INV_ITEM_LARGE_MEDIPACK)) +OBJ_ALIAS_DEFINE(O_PUZZLE_ITEM_1, GS_ID(INV_ITEM_PUZZLE_1)) +OBJ_ALIAS_DEFINE(O_PUZZLE_OPTION_1, GS_ID(INV_ITEM_PUZZLE_1)) +OBJ_ALIAS_DEFINE(O_PUZZLE_ITEM_2, GS_ID(INV_ITEM_PUZZLE_2)) +OBJ_ALIAS_DEFINE(O_PUZZLE_OPTION_2, GS_ID(INV_ITEM_PUZZLE_2)) +OBJ_ALIAS_DEFINE(O_PUZZLE_ITEM_3, GS_ID(INV_ITEM_PUZZLE_3)) +OBJ_ALIAS_DEFINE(O_PUZZLE_OPTION_3, GS_ID(INV_ITEM_PUZZLE_3)) +OBJ_ALIAS_DEFINE(O_PUZZLE_ITEM_4, GS_ID(INV_ITEM_PUZZLE_4)) +OBJ_ALIAS_DEFINE(O_PUZZLE_OPTION_4, GS_ID(INV_ITEM_PUZZLE_4)) +OBJ_ALIAS_DEFINE(O_KEY_ITEM_1, GS_ID(INV_ITEM_KEY_1)) +OBJ_ALIAS_DEFINE(O_KEY_OPTION_1, GS_ID(INV_ITEM_KEY_1)) +OBJ_ALIAS_DEFINE(O_KEY_ITEM_2, GS_ID(INV_ITEM_KEY_2)) +OBJ_ALIAS_DEFINE(O_KEY_OPTION_2, GS_ID(INV_ITEM_KEY_2)) +OBJ_ALIAS_DEFINE(O_KEY_ITEM_3, GS_ID(INV_ITEM_KEY_3)) +OBJ_ALIAS_DEFINE(O_KEY_OPTION_3, GS_ID(INV_ITEM_KEY_3)) +OBJ_ALIAS_DEFINE(O_KEY_ITEM_4, GS_ID(INV_ITEM_KEY_4)) +OBJ_ALIAS_DEFINE(O_KEY_OPTION_4, GS_ID(INV_ITEM_KEY_4)) +OBJ_ALIAS_DEFINE(O_PICKUP_ITEM_1, GS_ID(INV_ITEM_PICKUP_1)) +OBJ_ALIAS_DEFINE(O_PICKUP_OPTION_1, GS_ID(INV_ITEM_PICKUP_1)) +OBJ_ALIAS_DEFINE(O_PICKUP_ITEM_2, GS_ID(INV_ITEM_PICKUP_2)) +OBJ_ALIAS_DEFINE(O_PICKUP_OPTION_2, GS_ID(INV_ITEM_PICKUP_2)) +OBJ_ALIAS_DEFINE(O_LEADBAR_ITEM, GS_ID(INV_ITEM_LEADBAR)) +OBJ_ALIAS_DEFINE(O_LEADBAR_OPTION, GS_ID(INV_ITEM_LEADBAR)) +OBJ_ALIAS_DEFINE(O_SCION_ITEM_1, GS_ID(INV_ITEM_SCION)) +OBJ_ALIAS_DEFINE(O_SCION_ITEM_2, GS_ID(INV_ITEM_SCION)) +OBJ_ALIAS_DEFINE(O_SCION_ITEM_3, GS_ID(INV_ITEM_SCION)) +OBJ_ALIAS_DEFINE(O_SCION_ITEM_4, GS_ID(INV_ITEM_SCION)) +OBJ_ALIAS_DEFINE(O_SCION_OPTION, GS_ID(INV_ITEM_SCION)) +OBJ_ALIAS_DEFINE(O_COMPASS_OPTION, GS_ID(INV_ITEM_COMPASS)) +OBJ_ALIAS_DEFINE(O_PASSPORT_OPTION, GS_ID(INV_ITEM_GAME)) +OBJ_ALIAS_DEFINE(O_PASSPORT_CLOSED, GS_ID(INV_ITEM_GAME)) +OBJ_ALIAS_DEFINE(O_DETAIL_OPTION, GS_ID(INV_ITEM_DETAILS)) +OBJ_ALIAS_DEFINE(O_SOUND_OPTION, GS_ID(INV_ITEM_SOUND)) +OBJ_ALIAS_DEFINE(O_CONTROL_OPTION, GS_ID(INV_ITEM_CONTROLS)) +OBJ_ALIAS_DEFINE(O_PHOTO_OPTION, GS_ID(INV_ITEM_LARAS_HOME)) diff --git a/src/libtrx/game/game_string_table/aliases_tr2.def b/src/libtrx/game/game_string_table/aliases_tr2.def new file mode 100644 index 000000000..c6d97e1ba --- /dev/null +++ b/src/libtrx/game/game_string_table/aliases_tr2.def @@ -0,0 +1,62 @@ +OBJ_ALIAS_DEFINE(O_COMPASS_OPTION, GS_ID(INV_ITEM_STOPWATCH)) +OBJ_ALIAS_DEFINE(O_COMPASS_ITEM, GS_ID(INV_ITEM_STOPWATCH)) +OBJ_ALIAS_DEFINE(O_PISTOL_ITEM, GS_ID(INV_ITEM_PISTOLS)) +OBJ_ALIAS_DEFINE(O_PISTOL_OPTION, GS_ID(INV_ITEM_PISTOLS)) +OBJ_ALIAS_DEFINE(O_FLARE_ITEM, GS_ID(INV_ITEM_FLARE)) +OBJ_ALIAS_DEFINE(O_FLARES_OPTION, GS_ID(INV_ITEM_FLARE)) +OBJ_ALIAS_DEFINE(O_SHOTGUN_ITEM, GS_ID(INV_ITEM_SHOTGUN)) +OBJ_ALIAS_DEFINE(O_SHOTGUN_OPTION, GS_ID(INV_ITEM_SHOTGUN)) +OBJ_ALIAS_DEFINE(O_MAGNUM_ITEM, GS_ID(INV_ITEM_MAGNUMS)) +OBJ_ALIAS_DEFINE(O_MAGNUM_OPTION, GS_ID(INV_ITEM_MAGNUMS)) +OBJ_ALIAS_DEFINE(O_UZI_ITEM, GS_ID(INV_ITEM_UZIS)) +OBJ_ALIAS_DEFINE(O_UZI_OPTION, GS_ID(INV_ITEM_UZIS)) +OBJ_ALIAS_DEFINE(O_HARPOON_ITEM, GS_ID(INV_ITEM_HARPOON)) +OBJ_ALIAS_DEFINE(O_HARPOON_OPTION, GS_ID(INV_ITEM_HARPOON)) +OBJ_ALIAS_DEFINE(O_M16_ITEM, GS_ID(INV_ITEM_M16)) +OBJ_ALIAS_DEFINE(O_M16_OPTION, GS_ID(INV_ITEM_M16)) +OBJ_ALIAS_DEFINE(O_GRENADE_ITEM, GS_ID(INV_ITEM_GRENADE)) +OBJ_ALIAS_DEFINE(O_GRENADE_OPTION, GS_ID(INV_ITEM_GRENADE)) +OBJ_ALIAS_DEFINE(O_PISTOL_AMMO_ITEM, GS_ID(INV_ITEM_PISTOL_AMMO)) +OBJ_ALIAS_DEFINE(O_PISTOL_AMMO_OPTION, GS_ID(INV_ITEM_PISTOL_AMMO)) +OBJ_ALIAS_DEFINE(O_SHOTGUN_AMMO_ITEM, GS_ID(INV_ITEM_SHOTGUN_AMMO)) +OBJ_ALIAS_DEFINE(O_SHOTGUN_AMMO_OPTION, GS_ID(INV_ITEM_SHOTGUN_AMMO)) +OBJ_ALIAS_DEFINE(O_MAGNUM_AMMO_ITEM, GS_ID(INV_ITEM_MAGNUM_AMMO)) +OBJ_ALIAS_DEFINE(O_MAGNUM_AMMO_OPTION, GS_ID(INV_ITEM_MAGNUM_AMMO)) +OBJ_ALIAS_DEFINE(O_UZI_AMMO_ITEM, GS_ID(INV_ITEM_UZI_AMMO)) +OBJ_ALIAS_DEFINE(O_UZI_AMMO_OPTION, GS_ID(INV_ITEM_UZI_AMMO)) +OBJ_ALIAS_DEFINE(O_HARPOON_AMMO_ITEM, GS_ID(INV_ITEM_HARPOON_AMMO)) +OBJ_ALIAS_DEFINE(O_HARPOON_AMMO_OPTION, GS_ID(INV_ITEM_HARPOON_AMMO)) +OBJ_ALIAS_DEFINE(O_M16_AMMO_ITEM, GS_ID(INV_ITEM_M16_AMMO)) +OBJ_ALIAS_DEFINE(O_M16_AMMO_OPTION, GS_ID(INV_ITEM_M16_AMMO)) +OBJ_ALIAS_DEFINE(O_GRENADE_AMMO_ITEM, GS_ID(INV_ITEM_GRENADE_AMMO)) +OBJ_ALIAS_DEFINE(O_GRENADE_AMMO_OPTION, GS_ID(INV_ITEM_GRENADE_AMMO)) +OBJ_ALIAS_DEFINE(O_SMALL_MEDIPACK_ITEM, GS_ID(INV_ITEM_SMALL_MEDIPACK)) +OBJ_ALIAS_DEFINE(O_SMALL_MEDIPACK_OPTION, GS_ID(INV_ITEM_SMALL_MEDIPACK)) +OBJ_ALIAS_DEFINE(O_LARGE_MEDIPACK_ITEM, GS_ID(INV_ITEM_LARGE_MEDIPACK)) +OBJ_ALIAS_DEFINE(O_LARGE_MEDIPACK_OPTION, GS_ID(INV_ITEM_LARGE_MEDIPACK)) +OBJ_ALIAS_DEFINE(O_PICKUP_ITEM_1, GS_ID(INV_ITEM_PICKUP_1)) +OBJ_ALIAS_DEFINE(O_PICKUP_OPTION_1, GS_ID(INV_ITEM_PICKUP_1)) +OBJ_ALIAS_DEFINE(O_PICKUP_ITEM_2, GS_ID(INV_ITEM_PICKUP_2)) +OBJ_ALIAS_DEFINE(O_PICKUP_OPTION_2, GS_ID(INV_ITEM_PICKUP_2)) +OBJ_ALIAS_DEFINE(O_PUZZLE_ITEM_1, GS_ID(INV_ITEM_PUZZLE_1)) +OBJ_ALIAS_DEFINE(O_PUZZLE_OPTION_1, GS_ID(INV_ITEM_PUZZLE_1)) +OBJ_ALIAS_DEFINE(O_PUZZLE_ITEM_2, GS_ID(INV_ITEM_PUZZLE_2)) +OBJ_ALIAS_DEFINE(O_PUZZLE_OPTION_2, GS_ID(INV_ITEM_PUZZLE_2)) +OBJ_ALIAS_DEFINE(O_PUZZLE_ITEM_3, GS_ID(INV_ITEM_PUZZLE_3)) +OBJ_ALIAS_DEFINE(O_PUZZLE_OPTION_3, GS_ID(INV_ITEM_PUZZLE_3)) +OBJ_ALIAS_DEFINE(O_PUZZLE_ITEM_4, GS_ID(INV_ITEM_PUZZLE_4)) +OBJ_ALIAS_DEFINE(O_PUZZLE_OPTION_4, GS_ID(INV_ITEM_PUZZLE_4)) +OBJ_ALIAS_DEFINE(O_KEY_ITEM_1, GS_ID(INV_ITEM_KEY_1)) +OBJ_ALIAS_DEFINE(O_KEY_OPTION_1, GS_ID(INV_ITEM_KEY_1)) +OBJ_ALIAS_DEFINE(O_KEY_ITEM_2, GS_ID(INV_ITEM_KEY_2)) +OBJ_ALIAS_DEFINE(O_KEY_OPTION_2, GS_ID(INV_ITEM_KEY_2)) +OBJ_ALIAS_DEFINE(O_KEY_ITEM_3, GS_ID(INV_ITEM_KEY_3)) +OBJ_ALIAS_DEFINE(O_KEY_OPTION_3, GS_ID(INV_ITEM_KEY_3)) +OBJ_ALIAS_DEFINE(O_KEY_ITEM_4, GS_ID(INV_ITEM_KEY_4)) +OBJ_ALIAS_DEFINE(O_KEY_OPTION_4, GS_ID(INV_ITEM_KEY_4)) +OBJ_ALIAS_DEFINE(O_PASSPORT_OPTION, GS_ID(INV_ITEM_GAME)) +OBJ_ALIAS_DEFINE(O_PASSPORT_CLOSED, GS_ID(INV_ITEM_GAME)) +OBJ_ALIAS_DEFINE(O_DETAIL_OPTION, GS_ID(INV_ITEM_DETAILS)) +OBJ_ALIAS_DEFINE(O_SOUND_OPTION, GS_ID(INV_ITEM_SOUND)) +OBJ_ALIAS_DEFINE(O_CONTROL_OPTION, GS_ID(INV_ITEM_CONTROLS)) +OBJ_ALIAS_DEFINE(O_PHOTO_OPTION, GS_ID(INV_ITEM_LARAS_HOME)) diff --git a/src/libtrx/game/game_string_table/common.c b/src/libtrx/game/game_string_table/common.c new file mode 100644 index 000000000..f8d82005e --- /dev/null +++ b/src/libtrx/game/game_string_table/common.c @@ -0,0 +1,154 @@ +#include "debug.h" +#include "enum_map.h" +#include "game/game_string.h" +#include "game/game_string_table.h" +#include "game/game_string_table/priv.h" +#include "game/objects/names.h" +#include "log.h" +#include "memory.h" + +#include + +typedef void (*M_LOAD_STRING_FUNC)(const char *, const char *); + +GS_FILE g_GST_File = {}; + +static struct { + GAME_OBJECT_ID object_id; + GAME_STRING_ID game_string_id; +} m_ObjectAliases[] = { +#define OBJ_ALIAS_DEFINE(object_id_, game_string_id_) \ + { .object_id = object_id_, .game_string_id = game_string_id_ }, +#include "./aliases.def" +#undef OBJ_ALIAS_DEFINE + { .object_id = NO_OBJECT }, +}; + +static void M_GameStringTableEntry_Free(GS_TABLE_ENTRY *entry); +static void M_GameStringTable_Free(GS_TABLE *gs_table); +static void M_GameStringFile_Free(GS_FILE *gs_file); +static void M_ApplyGameString(const char *key, const char *value); +static void M_ApplyObjectString(const char *key, const char *value); +static void M_ApplyEntries( + const GS_TABLE_ENTRY *const entries, M_LOAD_STRING_FUNC load_func); +static void M_ApplyStrings( + const GS_TABLE_ENTRY *global_entries, const GS_TABLE_ENTRY *level_entries, + M_LOAD_STRING_FUNC load_func); +static void M_ApplyGameStrings(const GS_FILE *gs_table, int32_t level_num); +static void M_ApplyObjectStrings(const GS_FILE *gs_table, int32_t level_num); + +static void M_GameStringTableEntry_Free(GS_TABLE_ENTRY *const entry) +{ + if (entry == NULL) { + return; + } + GS_TABLE_ENTRY *cur = entry; + while (cur->key != NULL) { + Memory_FreePointer(&cur->key); + Memory_FreePointer(&cur->value); + cur++; + } + Memory_Free(entry); +} + +static void M_GameStringTable_Free(GS_TABLE *const gs_table) +{ + M_GameStringTableEntry_Free(gs_table->object_strings); + gs_table->object_strings = NULL; + M_GameStringTableEntry_Free(gs_table->game_strings); + gs_table->game_strings = NULL; +} + +static void M_GameStringFile_Free(GS_FILE *const gs_file) +{ + M_GameStringTable_Free(&gs_file->global); + for (int32_t i = 0; i < gs_file->level_count; i++) { + M_GameStringTable_Free(&gs_file->levels[i]); + } + Memory_FreePointer(&gs_file->levels); + gs_file->level_count = 0; +} + +static void M_ApplyGameString(const char *const key, const char *const value) +{ + if (!GameString_IsKnown(key)) { + LOG_ERROR("Invalid game string key: %s", key); + } else if (value == NULL) { + LOG_ERROR("Invalid game string value: %s", key); + } else { + GameString_Define(key, value); + } +} + +static void M_ApplyObjectString(const char *const key, const char *const value) +{ + const GAME_OBJECT_ID object_id = + ENUM_MAP_GET(GAME_OBJECT_ID, key, NO_OBJECT); + if (object_id == NO_OBJECT) { + LOG_ERROR("Invalid object id: %s", key); + } else { + Object_SetName(object_id, value); + } +} + +static void M_ApplyEntries( + const GS_TABLE_ENTRY *entries, const M_LOAD_STRING_FUNC load_func) +{ + while (entries != NULL && entries->key != NULL) { + load_func(entries->key, entries->value); + entries++; + } +} + +static void M_ApplyStrings( + const GS_TABLE_ENTRY *const global_entries, + const GS_TABLE_ENTRY *const level_entries, + const M_LOAD_STRING_FUNC load_func) +{ + M_ApplyEntries(global_entries, load_func); + if (level_entries != NULL) { + M_ApplyEntries(level_entries, load_func); + } +} + +static void M_ApplyGameStrings( + const GS_FILE *const gs_file, const int32_t level_num) +{ + ASSERT(level_num >= -1 && level_num < gs_file->level_count); + M_ApplyStrings( + gs_file->global.game_strings, + level_num != -1 ? gs_file->levels[level_num].game_strings : NULL, + M_ApplyGameString); +} + +static void M_ApplyObjectStrings( + const GS_FILE *const gs_file, const int32_t level_num) +{ + ASSERT(level_num >= -1 && level_num < gs_file->level_count); + M_ApplyStrings( + gs_file->global.object_strings, + level_num != -1 ? gs_file->levels[level_num].object_strings : NULL, + M_ApplyObjectString); +} + +void GameStringTable_Apply(const int32_t level_num) +{ + Object_ResetNames(); + + const GS_FILE *const gs_file = &g_GST_File; + M_ApplyObjectStrings(gs_file, level_num); + M_ApplyGameStrings(gs_file, level_num); + + for (int32_t i = 0; m_ObjectAliases[i].object_id != NO_OBJECT; i++) { + const char *const new_name = + GameString_Get(m_ObjectAliases[i].game_string_id); + if (new_name != NULL) { + Object_SetName(m_ObjectAliases[i].object_id, new_name); + } + } +} + +void GameStringTable_Shutdown(void) +{ + M_GameStringFile_Free(&g_GST_File); +} diff --git a/src/libtrx/game/game_string_table/priv.h b/src/libtrx/game/game_string_table/priv.h new file mode 100644 index 000000000..8bf65c7e9 --- /dev/null +++ b/src/libtrx/game/game_string_table/priv.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +typedef struct { + const char *key; + const char *value; +} GS_TABLE_ENTRY; + +typedef struct { + GS_TABLE_ENTRY *object_strings; + GS_TABLE_ENTRY *game_strings; +} GS_TABLE; + +typedef struct { + int32_t level_count; + GS_TABLE global; + GS_TABLE *levels; +} GS_FILE; + +extern GS_FILE g_GST_File; diff --git a/src/libtrx/game/game_string_table/reader.c b/src/libtrx/game/game_string_table/reader.c new file mode 100644 index 000000000..44d1e8759 --- /dev/null +++ b/src/libtrx/game/game_string_table/reader.c @@ -0,0 +1,139 @@ + +#include "filesystem.h" +#include "game/game_string_table.h" +#include "game/game_string_table/priv.h" +#include "game/gameflow.h" +#include "json.h" +#include "log.h" +#include "memory.h" + +#include + +static bool M_LoadTableFromJSON( + JSON_OBJECT *root_obj, const char *key, GS_TABLE_ENTRY **dest); +static bool M_LoadLevelsFromJSON(JSON_OBJECT *obj, GS_FILE *gs_file); + +static bool M_LoadTableFromJSON( + JSON_OBJECT *const root_obj, const char *const key, GS_TABLE_ENTRY **dest) +{ + const JSON_OBJECT *const strings_obj = JSON_ObjectGetObject(root_obj, key); + if (strings_obj == NULL) { + // key is missing - rely on default strings + return true; + } + + *dest = Memory_Alloc(sizeof(GS_TABLE_ENTRY) * (strings_obj->length + 1)); + + GS_TABLE_ENTRY *cur = *dest; + JSON_OBJECT_ELEMENT *strings_elem = strings_obj->start; + for (size_t i = 0; i < strings_obj->length; + i++, strings_elem = strings_elem->next) { + const char *const key = strings_elem->name->string; + const char *const value = JSON_ObjectGetString(strings_obj, key, NULL); + if (value == NULL) { + LOG_ERROR("invalid string key %s", strings_elem->name->string); + return NULL; + } + cur->key = Memory_DupStr(key); + cur->value = Memory_DupStr(value); + cur++; + } + + cur->key = NULL; + cur->value = NULL; + return true; +} + +static bool M_LoadLevelsFromJSON(JSON_OBJECT *const obj, GS_FILE *const gs_file) +{ + bool result = true; + + JSON_ARRAY *const jlvl_arr = JSON_ObjectGetArray(obj, "levels"); + if (jlvl_arr == NULL) { + LOG_ERROR("'levels' must be a list"); + result = false; + goto end; + } + + int32_t level_count = jlvl_arr->length; + if (level_count != GameFlow_GetLevelCount()) { + LOG_ERROR( + "'levels' must have exactly %d levels, as we still rely on legacy " + "tombpc.dat", + GameFlow_GetLevelCount()); + result = false; + goto end; + } + + gs_file->level_count = level_count; + gs_file->levels = Memory_Alloc(sizeof(GS_TABLE) * level_count); + + JSON_ARRAY_ELEMENT *jlvl_elem = jlvl_arr->start; + for (size_t i = 0; i < jlvl_arr->length; i++, jlvl_elem = jlvl_elem->next) { + GS_TABLE *const level = &gs_file->levels[i]; + + JSON_OBJECT *const jlvl_obj = JSON_ValueAsObject(jlvl_elem->value); + if (jlvl_obj == NULL) { + LOG_ERROR("'levels' elements must be dictionaries"); + result = false; + goto end; + } + + result &= M_LoadTableFromJSON( + jlvl_obj, "object_strings", &level->object_strings); + result &= + M_LoadTableFromJSON(jlvl_obj, "game_strings", &level->game_strings); + } + +end: + return result; +} + +bool GameStringTable_LoadFromFile(const char *const path) +{ + GameStringTable_Shutdown(); + + bool result = true; + JSON_VALUE *root = NULL; + + char *script_data = NULL; + if (!File_Load(path, &script_data, NULL)) { + LOG_ERROR("failed to open strings file"); + result = false; + goto end; + } + + JSON_PARSE_RESULT parse_result; + root = JSON_ParseEx( + script_data, strlen(script_data), JSON_PARSE_FLAGS_ALLOW_JSON5, NULL, + NULL, &parse_result); + if (root == NULL) { + LOG_ERROR( + "failed to parse script file: %s in line %d, char %d", + JSON_GetErrorDescription(parse_result.error), + parse_result.error_line_no, parse_result.error_row_no, script_data); + result = false; + goto end; + } + + GS_FILE *const gs_file = &g_GST_File; + JSON_OBJECT *root_obj = JSON_ValueAsObject(root); + result &= M_LoadTableFromJSON( + root_obj, "object_strings", &gs_file->global.object_strings); + result &= M_LoadTableFromJSON( + root_obj, "game_strings", &gs_file->global.game_strings); + result &= M_LoadLevelsFromJSON(root_obj, gs_file); + +end: + if (root != NULL) { + JSON_ValueFree(root); + root = NULL; + } + + if (!result) { + GameStringTable_Shutdown(); + } + + Memory_FreePointer(&script_data); + return result; +} diff --git a/src/libtrx/include/libtrx/game/game_string_table.h b/src/libtrx/include/libtrx/game/game_string_table.h new file mode 100644 index 000000000..130b341a3 --- /dev/null +++ b/src/libtrx/include/libtrx/game/game_string_table.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +bool GameStringTable_LoadFromFile(const char *path); +void GameStringTable_Apply(int32_t level_num); +void GameStringTable_Shutdown(void); diff --git a/src/libtrx/meson.build b/src/libtrx/meson.build index 959cbaa0d..e5d230bbe 100644 --- a/src/libtrx/meson.build +++ b/src/libtrx/meson.build @@ -110,6 +110,8 @@ sources = [ 'game/fader.c', 'game/game.c', 'game/game_string.c', + 'game/game_string_table/common.c', + 'game/game_string_table/reader.c', 'game/gamebuf.c', 'game/input/backends/controller.c', 'game/input/backends/internal.c', diff --git a/src/tr2/decomp/decomp.c b/src/tr2/decomp/decomp.c index 071072171..2fc3c9939 100644 --- a/src/tr2/decomp/decomp.c +++ b/src/tr2/decomp/decomp.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -63,8 +64,7 @@ static CAMERA_INFO m_LocalCamera = {}; GAME_FLOW_COMMAND TitleSequence(void) { - GF_N_LoadStrings(-1); - + GameStringTable_Apply(-1); if (!Level_Initialise(0, GFL_TITLE)) { return (GAME_FLOW_COMMAND) { .action = GF_EXIT_GAME }; } diff --git a/src/tr2/game/gameflow.c b/src/tr2/game/gameflow.c index b35dc4bfe..01f44c587 100644 --- a/src/tr2/game/gameflow.c +++ b/src/tr2/game/gameflow.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -344,7 +344,7 @@ bool GF_LoadScriptFile(const char *const fname) bool GF_DoFrontendSequence(void) { - GF_N_LoadStrings(-1); + GameStringTable_Apply(-1); const GAME_FLOW_COMMAND gf_cmd = GF_InterpretSequence(m_FrontendSequence, GFL_NORMAL); return gf_cmd.action == GF_EXIT_GAME; @@ -353,8 +353,7 @@ bool GF_DoFrontendSequence(void) GAME_FLOW_COMMAND GF_DoLevelSequence( const int32_t start_level, const GAME_FLOW_LEVEL_TYPE type) { - GF_N_LoadStrings(start_level); - + GameStringTable_Apply(start_level); int32_t current_level = start_level; while (true) { if (current_level > g_GameFlow.num_levels - 1) { diff --git a/src/tr2/game/gameflow/gameflow_new.c b/src/tr2/game/gameflow/gameflow_new.c index d44a58e53..626afcd57 100644 --- a/src/tr2/game/gameflow/gameflow_new.c +++ b/src/tr2/game/gameflow/gameflow_new.c @@ -1,179 +1,11 @@ #include "game/gameflow/gameflow_new.h" #include "game/game_string.h" -#include "game/requester.h" -#include "global/types.h" #include "global/vars.h" -#include -#include -#include -#include -#include - GAME_FLOW_NEW g_GameFlowNew; GAME_INFO g_GameInfo; -static void M_LoadObjectString(const char *key, const char *value); -static void M_LoadGameString(const char *key, const char *value); -static void M_LoadObjectStrings(const int32_t level_num); -static void M_LoadGameStrings(const int32_t level_num); - -static void M_LoadObjectString(const char *const key, const char *const value) -{ - const GAME_OBJECT_ID object_id = - ENUM_MAP_GET(GAME_OBJECT_ID, key, NO_OBJECT); - if (object_id == NO_OBJECT) { - LOG_ERROR("Invalid object id: %s", key); - } else { - Object_SetName(object_id, value); - } -} - -static void M_LoadGameString(const char *const key, const char *const value) -{ - if (!GameString_IsKnown(key)) { - LOG_ERROR("Invalid game string key: %s", key); - } else if (value == NULL) { - LOG_ERROR("Invalid game string value: %s", key); - } else { - GameString_Define(key, value); - } -} - -static void M_LoadObjectStrings(const int32_t level_num) -{ - const GAME_FLOW_NEW *const gf = &g_GameFlowNew; - - const GAME_FLOW_NEW_STRING_ENTRY *entry = gf->object_strings; - while (entry != NULL && entry->key != NULL) { - M_LoadObjectString(entry->key, entry->value); - entry++; - } - - if (level_num >= 0) { - ASSERT(level_num < gf->level_count); - const GAME_FLOW_NEW_LEVEL *const level = &gf->levels[level_num]; - entry = level->object_strings; - while (entry != NULL && entry->key != NULL) { - M_LoadObjectString(entry->key, entry->value); - entry++; - } - } -} - -static void M_LoadGameStrings(const int32_t level_num) -{ - const GAME_FLOW_NEW *const gf = &g_GameFlowNew; - - const GAME_FLOW_NEW_STRING_ENTRY *entry = gf->game_strings; - while (entry != NULL && entry->key != NULL) { - M_LoadGameString(entry->key, entry->value); - entry++; - } - - if (level_num >= 0) { - ASSERT(level_num < gf->level_count); - const GAME_FLOW_NEW_LEVEL *const level = &gf->levels[level_num]; - entry = level->game_strings; - while (entry != NULL && entry->key != NULL) { - M_LoadGameString(entry->key, entry->value); - entry++; - } - } -} - -void GF_N_LoadStrings(const int32_t level_num) -{ - Object_ResetNames(); - - M_LoadObjectStrings(level_num); - M_LoadGameStrings(level_num); - - struct { - GAME_OBJECT_ID object_id; - const char *name; - } game_string_defs[] = { - // clang-format off - { O_COMPASS_OPTION, GS(INV_ITEM_STOPWATCH) }, - { O_COMPASS_ITEM, GS(INV_ITEM_STOPWATCH) }, - { O_PISTOL_ITEM, GS(INV_ITEM_PISTOLS) }, - { O_PISTOL_OPTION, GS(INV_ITEM_PISTOLS) }, - { O_FLARE_ITEM, GS(INV_ITEM_FLARE) }, - { O_FLARES_OPTION, GS(INV_ITEM_FLARE) }, - { O_SHOTGUN_ITEM, GS(INV_ITEM_SHOTGUN) }, - { O_SHOTGUN_OPTION, GS(INV_ITEM_SHOTGUN) }, - { O_MAGNUM_ITEM, GS(INV_ITEM_MAGNUMS) }, - { O_MAGNUM_OPTION, GS(INV_ITEM_MAGNUMS) }, - { O_UZI_ITEM, GS(INV_ITEM_UZIS) }, - { O_UZI_OPTION, GS(INV_ITEM_UZIS) }, - { O_HARPOON_ITEM, GS(INV_ITEM_HARPOON) }, - { O_HARPOON_OPTION, GS(INV_ITEM_HARPOON) }, - { O_M16_ITEM, GS(INV_ITEM_M16) }, - { O_M16_OPTION, GS(INV_ITEM_M16) }, - { O_GRENADE_ITEM, GS(INV_ITEM_GRENADE) }, - { O_GRENADE_OPTION, GS(INV_ITEM_GRENADE) }, - { O_PISTOL_AMMO_ITEM, GS(INV_ITEM_PISTOL_AMMO) }, - { O_PISTOL_AMMO_OPTION, GS(INV_ITEM_PISTOL_AMMO) }, - { O_SHOTGUN_AMMO_ITEM, GS(INV_ITEM_SHOTGUN_AMMO) }, - { O_SHOTGUN_AMMO_OPTION, GS(INV_ITEM_SHOTGUN_AMMO) }, - { O_MAGNUM_AMMO_ITEM, GS(INV_ITEM_MAGNUM_AMMO) }, - { O_MAGNUM_AMMO_OPTION, GS(INV_ITEM_MAGNUM_AMMO) }, - { O_UZI_AMMO_ITEM, GS(INV_ITEM_UZI_AMMO) }, - { O_UZI_AMMO_OPTION, GS(INV_ITEM_UZI_AMMO) }, - { O_HARPOON_AMMO_ITEM, GS(INV_ITEM_HARPOON_AMMO) }, - { O_HARPOON_AMMO_OPTION, GS(INV_ITEM_HARPOON_AMMO) }, - { O_M16_AMMO_ITEM, GS(INV_ITEM_M16_AMMO) }, - { O_M16_AMMO_OPTION, GS(INV_ITEM_M16_AMMO) }, - { O_GRENADE_AMMO_ITEM, GS(INV_ITEM_GRENADE_AMMO) }, - { O_GRENADE_AMMO_OPTION, GS(INV_ITEM_GRENADE_AMMO) }, - { O_SMALL_MEDIPACK_ITEM, GS(INV_ITEM_SMALL_MEDIPACK) }, - { O_SMALL_MEDIPACK_OPTION, GS(INV_ITEM_SMALL_MEDIPACK) }, - { O_LARGE_MEDIPACK_ITEM, GS(INV_ITEM_LARGE_MEDIPACK) }, - { O_LARGE_MEDIPACK_OPTION, GS(INV_ITEM_LARGE_MEDIPACK) }, - { O_PICKUP_ITEM_1, GS(INV_ITEM_PICKUP_1) }, - { O_PICKUP_OPTION_1, GS(INV_ITEM_PICKUP_1) }, - { O_PICKUP_ITEM_2, GS(INV_ITEM_PICKUP_2) }, - { O_PICKUP_OPTION_2, GS(INV_ITEM_PICKUP_2) }, - { O_PUZZLE_ITEM_1, GS(INV_ITEM_PUZZLE_1) }, - { O_PUZZLE_OPTION_1, GS(INV_ITEM_PUZZLE_1) }, - { O_PUZZLE_ITEM_2, GS(INV_ITEM_PUZZLE_2) }, - { O_PUZZLE_OPTION_2, GS(INV_ITEM_PUZZLE_2) }, - { O_PUZZLE_ITEM_3, GS(INV_ITEM_PUZZLE_3) }, - { O_PUZZLE_OPTION_3, GS(INV_ITEM_PUZZLE_3) }, - { O_PUZZLE_ITEM_4, GS(INV_ITEM_PUZZLE_4) }, - { O_PUZZLE_OPTION_4, GS(INV_ITEM_PUZZLE_4) }, - { O_KEY_ITEM_1, GS(INV_ITEM_KEY_1) }, - { O_KEY_OPTION_1, GS(INV_ITEM_KEY_1) }, - { O_KEY_ITEM_2, GS(INV_ITEM_KEY_2) }, - { O_KEY_OPTION_2, GS(INV_ITEM_KEY_2) }, - { O_KEY_ITEM_3, GS(INV_ITEM_KEY_3) }, - { O_KEY_OPTION_3, GS(INV_ITEM_KEY_3) }, - { O_KEY_ITEM_4, GS(INV_ITEM_KEY_4) }, - { O_KEY_OPTION_4, GS(INV_ITEM_KEY_4) }, - { O_PASSPORT_OPTION, GS(INV_ITEM_GAME) }, - { O_PASSPORT_CLOSED, GS(INV_ITEM_GAME) }, - { O_DETAIL_OPTION, GS(INV_ITEM_DETAILS) }, - { O_SOUND_OPTION, GS(INV_ITEM_SOUND) }, - { O_CONTROL_OPTION, GS(INV_ITEM_CONTROLS) }, - { O_PHOTO_OPTION, GS(INV_ITEM_LARAS_HOME) }, - { NO_OBJECT, NULL }, - // clang-format on - }; - - for (int32_t i = 0; game_string_defs[i].object_id != NO_OBJECT; i++) { - const char *const new_name = game_string_defs[i].name; - if (new_name != NULL) { - Object_SetName(game_string_defs[i].object_id, new_name); - } - } - - Requester_SetHeading( - &g_LoadGameRequester, GS(PASSPORT_SELECT_LEVEL), 0, 0, 0); - Requester_SetHeading( - &g_SaveGameRequester, GS(PASSPORT_SELECT_LEVEL), 0, 0, 0); -} - int32_t GameFlow_GetLevelCount(void) { return g_GameFlowNew.level_count; diff --git a/src/tr2/game/gameflow/gameflow_new.h b/src/tr2/game/gameflow/gameflow_new.h index 8957e8d1f..d179dadf1 100644 --- a/src/tr2/game/gameflow/gameflow_new.h +++ b/src/tr2/game/gameflow/gameflow_new.h @@ -15,25 +15,14 @@ typedef struct { } GAME_INFO; typedef struct { - const char *key; - const char *value; -} GAME_FLOW_NEW_STRING_ENTRY; - -typedef struct { - GAME_FLOW_NEW_STRING_ENTRY *object_strings; - GAME_FLOW_NEW_STRING_ENTRY *game_strings; INJECTION_DATA injections; } GAME_FLOW_NEW_LEVEL; typedef struct { int32_t level_count; GAME_FLOW_NEW_LEVEL *levels; - GAME_FLOW_NEW_STRING_ENTRY *object_strings; - GAME_FLOW_NEW_STRING_ENTRY *game_strings; INJECTION_DATA injections; } GAME_FLOW_NEW; extern GAME_FLOW_NEW g_GameFlowNew; extern GAME_INFO g_GameInfo; - -void GF_N_LoadStrings(int32_t level_num); diff --git a/src/tr2/game/gameflow/reader.c b/src/tr2/game/gameflow/reader.c index 8b9c4bca3..41e194b30 100644 --- a/src/tr2/game/gameflow/reader.c +++ b/src/tr2/game/gameflow/reader.c @@ -11,9 +11,6 @@ static void M_LoadGlobalInjections(JSON_OBJECT *obj, GAME_FLOW_NEW *gf); static void M_LoadLevelInjections( JSON_OBJECT *obj, const GAME_FLOW_NEW *gf, GAME_FLOW_NEW_LEVEL *level); -static void M_StringTableShutdown(GAME_FLOW_NEW_STRING_ENTRY *dest); -static bool M_LoadStringTable( - JSON_OBJECT *root_obj, const char *key, GAME_FLOW_NEW_STRING_ENTRY **dest); static bool M_LoadScriptLevels(JSON_OBJECT *obj, GAME_FLOW_NEW *gf); static void M_LoadGlobalInjections( @@ -75,53 +72,6 @@ static void M_LoadLevelInjections( } } -static void M_StringTableShutdown(GAME_FLOW_NEW_STRING_ENTRY *const dest) -{ - if (dest == NULL) { - return; - } - GAME_FLOW_NEW_STRING_ENTRY *cur = dest; - while (cur->key != NULL) { - Memory_FreePointer(&cur->key); - Memory_FreePointer(&cur->value); - cur++; - } - Memory_Free(dest); -} - -static bool M_LoadStringTable( - JSON_OBJECT *const root_obj, const char *const key, - GAME_FLOW_NEW_STRING_ENTRY **dest) -{ - const JSON_OBJECT *const strings_obj = JSON_ObjectGetObject(root_obj, key); - if (strings_obj == NULL) { - // key is missing - rely on default strings - return true; - } - - *dest = Memory_Alloc( - sizeof(GAME_FLOW_NEW_STRING_ENTRY) * (strings_obj->length + 1)); - - GAME_FLOW_NEW_STRING_ENTRY *cur = *dest; - JSON_OBJECT_ELEMENT *strings_elem = strings_obj->start; - for (size_t i = 0; i < strings_obj->length; - i++, strings_elem = strings_elem->next) { - const char *const key = strings_elem->name->string; - const char *const value = JSON_ObjectGetString(strings_obj, key, NULL); - if (value == NULL) { - LOG_ERROR("invalid string key %s", strings_elem->name->string); - return NULL; - } - cur->key = Memory_DupStr(key); - cur->value = Memory_DupStr(value); - cur++; - } - - cur->key = NULL; - cur->value = NULL; - return true; -} - static bool M_LoadScriptLevels(JSON_OBJECT *obj, GAME_FLOW_NEW *const gf) { bool result = true; @@ -158,11 +108,6 @@ static bool M_LoadScriptLevels(JSON_OBJECT *obj, GAME_FLOW_NEW *const gf) } M_LoadLevelInjections(jlvl_obj, gf, level); - - result &= M_LoadStringTable( - jlvl_obj, "object_strings", &level->object_strings); - result &= - M_LoadStringTable(jlvl_obj, "game_strings", &level->game_strings); } end: @@ -199,9 +144,6 @@ bool GF_N_Load(const char *const path) GAME_FLOW_NEW *const gf = &g_GameFlowNew; JSON_OBJECT *root_obj = JSON_ValueAsObject(root); M_LoadGlobalInjections(root_obj, gf); - result &= - M_LoadStringTable(root_obj, "object_strings", &gf->object_strings); - result &= M_LoadStringTable(root_obj, "game_strings", &gf->game_strings); result &= M_LoadScriptLevels(root_obj, gf); end: @@ -228,15 +170,11 @@ void GF_N_Shutdown(void) Memory_FreePointer(&gf->injections.data_paths); for (int32_t i = 0; i < gf->level_count; i++) { - M_StringTableShutdown(gf->levels[i].object_strings); - M_StringTableShutdown(gf->levels[i].game_strings); - for (int32_t j = 0; j < gf->levels[i].injections.count; j++) { Memory_FreePointer(&gf->levels[i].injections.data_paths[j]); } Memory_FreePointer(&gf->levels[i].injections.data_paths); } - - M_StringTableShutdown(gf->object_strings); - M_StringTableShutdown(gf->game_strings); + Memory_FreePointer(&gf->levels); + gf->level_count = 0; } diff --git a/src/tr2/game/shell/common.c b/src/tr2/game/shell/common.c index 2aa288e96..395c30352 100644 --- a/src/tr2/game/shell/common.c +++ b/src/tr2/game/shell/common.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -37,6 +38,7 @@ static Uint64 m_UpdateDebounce = 0; static const char *m_CurrentGameFlowPath = "cfg/TR2X_gameflow.json5"; +static const char *m_CurrentGameStringsPath = "cfg/TR2X_strings.json5"; static void M_SyncToWindow(void); static void M_SyncFromWindow(void); @@ -362,12 +364,17 @@ void Shell_Main(void) Viewport_Reset(); if (!GF_LoadScriptFile("data\\tombPC.dat")) { - Shell_ExitSystem("GameMain: could not load script file"); + Shell_ExitSystem("Could not load the original script file."); return; } if (!GF_N_Load(m_CurrentGameFlowPath)) { - Shell_ExitSystem("GameMain: could not load new script file"); + Shell_ExitSystem("Could not load the new script file."); + return; + } + + if (!GameStringTable_LoadFromFile(m_CurrentGameStringsPath)) { + Shell_ExitSystem("Could not load game strings."); return; } diff --git a/tools/shared/linting.py b/tools/shared/linting.py index 840afc282..14950c968 100644 --- a/tools/shared/linting.py +++ b/tools/shared/linting.py @@ -164,7 +164,7 @@ def lint_unused_game_strings(context: LintContext) -> Iterable[LintWarning]: used_strings = defaultdict(set) for path in context.versioned_files: - if path.suffix != ".c": + if path.suffix not in {".c", ".def"}: continue relevant_project = get_relevant_project(context, path) @@ -189,7 +189,7 @@ def lint_unused_game_strings(context: LintContext) -> Iterable[LintWarning]: ) elif project == 'libtrx' and 'libtrx' not in used_projects and len(used_projects) == 1: yield LintWarning( - project_paths[project], f"game string used only in a single child project: {def_} ({used_projects!r}." + project_paths[project], f"game string used only in a single child project: {def_} ({used_projects!s})." ) diff --git a/tools/update_gameflow b/tools/update_gameflow index 5fc7dcff0..5e775d5ed 100755 --- a/tools/update_gameflow +++ b/tools/update_gameflow @@ -95,7 +95,7 @@ def process_tr2() -> None: assert object_strings_map assert game_strings_map - for gameflow_path in TR2Paths.shipped_data_dir.rglob("*gameflow*.json*"): + for gameflow_path in TR2Paths.shipped_data_dir.rglob("*strings*.json*"): old_gameflow = gameflow_path.read_text() new_gameflow = postprocess_gameflow( old_gameflow, object_strings_map, game_strings_map