TombEngine/TR5Main/Game/gui.cpp
2021-12-24 03:32:19 +03:00

3918 lines
111 KiB
C++

#include "framework.h"
#include "Game/gui.h"
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/control/control.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_fire.h"
#include "Game/Lara/lara_one_gun.h"
#include "Game/Lara/lara_two_guns.h"
#include "Game/pickup/pickup.h"
#include "Game/savegame.h"
#include "Game/spotcam.h"
#include "Sound/sound.h"
#include "Specific/input.h"
#include "Specific/configuration.h"
#include "Specific/level.h"
#include "Specific/input.h"
#include "Renderer/Renderer11.h"
using namespace TEN::Renderer;
GuiController g_Gui;
const char* optmessages[] =
{
STRING_USE,
STRING_CHOOSE_AMMO,
STRING_COMBINE,
STRING_SEPARE,
STRING_EQUIP,
STRING_COMBINE_WITH,
STRING_LOAD_GAME,
STRING_SAVE_GAME,
STRING_EXAMINE,
STRING_STATISTICS,
STRING_CHOOSE_WEAPON,
""
// STRING_READ_DIARY
};
const char* controlmsgs[] =
{
STRING_CONTROLS_MOVE_FORWARD,
STRING_CONTROLS_MOVE_BACKWARD,
STRING_CONTROLS_MOVE_LEFT,
STRING_CONTROLS_MOVE_RIGHT,
STRING_CONTROLS_DUCK,
STRING_CONTROLS_DASH,
STRING_CONTROLS_WALK,
STRING_CONTROLS_JUMP,
STRING_CONTROLS_ACTION,
STRING_CONTROLS_DRAW_WEAPON,
STRING_CONTROLS_USE_FLARE,
STRING_CONTROLS_LOOK,
STRING_CONTROLS_ROLL,
STRING_CONTROLS_INVENTORY,
STRING_CONTROLS_STEP_LEFT,
STRING_CONTROLS_STEP_RIGHT
};
#define font_height 25
#define max_combines 60
#define phd_winxmax g_Configuration.Width
#define phd_winymax g_Configuration.Height
#define phd_centerx 400
#define phd_centery phd_winymax / 2
/*
if you wanna add an object to the inventory, edit the InventoryObjectTypes array then edit THIS inventry_objects_list array with the object IN THE RIGHT PLACE
the #s MUST MATCH.
i.e if uzi item is #2 in InventoryObjectTypes (starting count from 0), IT HAS TO BE THE THIRD ELEMENT IN inventry_objects_list. thank you.
note: don't forget to add your object to the proper list construction function
and if it's a weapon, add its ammo handling shit. (look at vars at the beginning of the file)
if it's combineable, add its things to the combine_table and don't forget to increment max_combines!!
*/
CombineList combine_table[max_combines] =
{
{combine_revolver_lasersight, INV_OBJECT_REVOLVER, INV_OBJECT_LASERSIGHT, INV_OBJECT_REVOLVER_LASER},
{combine_crossbow_lasersight, INV_OBJECT_CROSSBOW, INV_OBJECT_LASERSIGHT, INV_OBJECT_CROSSBOW_LASER},
{combine_HK_SILENCER, INV_OBJECT_HK, INV_OBJECT_SILENCER, INV_OBJECT_HK_SILENCER},
{combine_PuzzleItem1, INV_OBJECT_PUZZLE1_COMBO1, INV_OBJECT_PUZZLE1_COMBO2, INV_OBJECT_PUZZLE1},
{combine_PuzzleItem2, INV_OBJECT_PUZZLE2_COMBO1, INV_OBJECT_PUZZLE2_COMBO2, INV_OBJECT_PUZZLE2},
{combine_PuzzleItem3, INV_OBJECT_PUZZLE3_COMBO1, INV_OBJECT_PUZZLE3_COMBO2, INV_OBJECT_PUZZLE3},
{combine_PuzzleItem4, INV_OBJECT_PUZZLE4_COMBO1, INV_OBJECT_PUZZLE4_COMBO2, INV_OBJECT_PUZZLE4},
{combine_PuzzleItem5, INV_OBJECT_PUZZLE5_COMBO1, INV_OBJECT_PUZZLE5_COMBO2, INV_OBJECT_PUZZLE5},
{combine_PuzzleItem6, INV_OBJECT_PUZZLE6_COMBO1, INV_OBJECT_PUZZLE6_COMBO2, INV_OBJECT_PUZZLE6},
{combine_PuzzleItem7, INV_OBJECT_PUZZLE7_COMBO1, INV_OBJECT_PUZZLE7_COMBO2, INV_OBJECT_PUZZLE7},
{combine_PuzzleItem8, INV_OBJECT_PUZZLE8_COMBO1, INV_OBJECT_PUZZLE8_COMBO2, INV_OBJECT_PUZZLE8},
{combine_PuzzleItem9, INV_OBJECT_PUZZLE9_COMBO1, INV_OBJECT_PUZZLE9_COMBO2, INV_OBJECT_PUZZLE9},
{combine_PuzzleItem10, INV_OBJECT_PUZZLE10_COMBO1, INV_OBJECT_PUZZLE10_COMBO2, INV_OBJECT_PUZZLE10},
{combine_PuzzleItem11, INV_OBJECT_PUZZLE11_COMBO1, INV_OBJECT_PUZZLE11_COMBO2, INV_OBJECT_PUZZLE11},
{combine_PuzzleItem12, INV_OBJECT_PUZZLE12_COMBO1, INV_OBJECT_PUZZLE12_COMBO2, INV_OBJECT_PUZZLE12},
{combine_PuzzleItem13, INV_OBJECT_PUZZLE13_COMBO1, INV_OBJECT_PUZZLE13_COMBO2, INV_OBJECT_PUZZLE13},
{combine_PuzzleItem14, INV_OBJECT_PUZZLE14_COMBO1, INV_OBJECT_PUZZLE14_COMBO2, INV_OBJECT_PUZZLE14},
{combine_PuzzleItem15, INV_OBJECT_PUZZLE15_COMBO1, INV_OBJECT_PUZZLE15_COMBO2, INV_OBJECT_PUZZLE15},
{combine_PuzzleItem16, INV_OBJECT_PUZZLE16_COMBO1, INV_OBJECT_PUZZLE16_COMBO2, INV_OBJECT_PUZZLE16},
{combine_KeyItem1, INV_OBJECT_KEY1_COMBO1, INV_OBJECT_KEY1_COMBO2, INV_OBJECT_KEY1},
{combine_KeyItem2, INV_OBJECT_KEY2_COMBO1, INV_OBJECT_KEY2_COMBO2, INV_OBJECT_KEY2},
{combine_KeyItem3, INV_OBJECT_KEY3_COMBO1, INV_OBJECT_KEY3_COMBO2, INV_OBJECT_KEY3},
{combine_KeyItem4, INV_OBJECT_KEY4_COMBO1, INV_OBJECT_KEY4_COMBO2, INV_OBJECT_KEY4},
{combine_KeyItem5, INV_OBJECT_KEY5_COMBO1, INV_OBJECT_KEY5_COMBO2, INV_OBJECT_KEY5},
{combine_KeyItem6, INV_OBJECT_KEY6_COMBO1, INV_OBJECT_KEY6_COMBO2, INV_OBJECT_KEY6},
{combine_KeyItem7, INV_OBJECT_KEY7_COMBO1, INV_OBJECT_KEY7_COMBO2, INV_OBJECT_KEY7},
{combine_KeyItem8, INV_OBJECT_KEY8_COMBO1, INV_OBJECT_KEY8_COMBO2, INV_OBJECT_KEY8},
{combine_KeyItem9, INV_OBJECT_KEY9_COMBO1, INV_OBJECT_KEY9_COMBO2, INV_OBJECT_KEY9},
{combine_KeyItem10, INV_OBJECT_KEY10_COMBO1, INV_OBJECT_KEY10_COMBO2, INV_OBJECT_KEY10},
{combine_KeyItem11, INV_OBJECT_KEY11_COMBO1, INV_OBJECT_KEY11_COMBO2, INV_OBJECT_KEY11},
{combine_KeyItem12, INV_OBJECT_KEY12_COMBO1, INV_OBJECT_KEY12_COMBO2, INV_OBJECT_KEY12},
{combine_KeyItem13, INV_OBJECT_KEY13_COMBO1, INV_OBJECT_KEY13_COMBO2, INV_OBJECT_KEY13},
{combine_KeyItem14, INV_OBJECT_KEY14_COMBO1, INV_OBJECT_KEY14_COMBO2, INV_OBJECT_KEY14},
{combine_KeyItem15, INV_OBJECT_KEY15_COMBO1, INV_OBJECT_KEY15_COMBO2, INV_OBJECT_KEY15},
{combine_KeyItem16, INV_OBJECT_KEY16_COMBO1, INV_OBJECT_KEY16_COMBO2, INV_OBJECT_KEY16},
{combine_PickupItem1, INV_OBJECT_PICKUP1_COMBO1, INV_OBJECT_PICKUP1_COMBO2, INV_OBJECT_PICKUP1},
{combine_PickupItem2, INV_OBJECT_PICKUP2_COMBO1, INV_OBJECT_PICKUP2_COMBO2, INV_OBJECT_PICKUP2},
{combine_PickupItem3, INV_OBJECT_PICKUP3_COMBO1, INV_OBJECT_PICKUP3_COMBO2, INV_OBJECT_PICKUP3},
{combine_PickupItem4, INV_OBJECT_PICKUP4_COMBO1, INV_OBJECT_PICKUP4_COMBO2, INV_OBJECT_PICKUP4},
{combine_PickupItem5, INV_OBJECT_PICKUP5_COMBO1, INV_OBJECT_PICKUP5_COMBO2, INV_OBJECT_PICKUP5},
{combine_PickupItem6, INV_OBJECT_PICKUP6_COMBO1, INV_OBJECT_PICKUP6_COMBO2, INV_OBJECT_PICKUP6},
{combine_PickupItem7, INV_OBJECT_PICKUP7_COMBO1, INV_OBJECT_PICKUP7_COMBO2, INV_OBJECT_PICKUP7},
{combine_PickupItem8, INV_OBJECT_PICKUP8_COMBO1, INV_OBJECT_PICKUP8_COMBO2, INV_OBJECT_PICKUP8},
{combine_PickupItem9, INV_OBJECT_PICKUP9_COMBO1, INV_OBJECT_PICKUP9_COMBO2, INV_OBJECT_PICKUP9},
{combine_PickupItem10, INV_OBJECT_PICKUP10_COMBO1, INV_OBJECT_PICKUP10_COMBO2, INV_OBJECT_PICKUP10},
{combine_PickupItem11, INV_OBJECT_PICKUP11_COMBO1, INV_OBJECT_PICKUP11_COMBO2, INV_OBJECT_PICKUP11},
{combine_PickupItem12, INV_OBJECT_PICKUP12_COMBO1, INV_OBJECT_PICKUP12_COMBO2, INV_OBJECT_PICKUP12},
{combine_PickupItem13, INV_OBJECT_PICKUP13_COMBO1, INV_OBJECT_PICKUP13_COMBO2, INV_OBJECT_PICKUP13},
{combine_PickupItem14, INV_OBJECT_PICKUP14_COMBO1, INV_OBJECT_PICKUP14_COMBO2, INV_OBJECT_PICKUP14},
{combine_PickupItem15, INV_OBJECT_PICKUP15_COMBO1, INV_OBJECT_PICKUP15_COMBO2, INV_OBJECT_PICKUP15},
{combine_PickupItem16, INV_OBJECT_PICKUP16_COMBO1, INV_OBJECT_PICKUP16_COMBO2, INV_OBJECT_PICKUP16},
{combine_Examine1, INV_OBJECT_EXAMINE1_COMBO1, INV_OBJECT_EXAMINE1_COMBO2, INV_OBJECT_EXAMINE1},
{combine_Examine2, INV_OBJECT_EXAMINE2_COMBO1, INV_OBJECT_EXAMINE2_COMBO2, INV_OBJECT_EXAMINE2},
{combine_Examine3, INV_OBJECT_EXAMINE3_COMBO1, INV_OBJECT_EXAMINE3_COMBO2, INV_OBJECT_EXAMINE3},
{combine_Examine4, INV_OBJECT_EXAMINE4_COMBO1, INV_OBJECT_EXAMINE4_COMBO2, INV_OBJECT_EXAMINE4},
{combine_Examine5, INV_OBJECT_EXAMINE5_COMBO1, INV_OBJECT_EXAMINE5_COMBO2, INV_OBJECT_EXAMINE5},
{combine_Examine6, INV_OBJECT_EXAMINE6_COMBO1, INV_OBJECT_EXAMINE6_COMBO2, INV_OBJECT_EXAMINE6},
{combine_Examine7, INV_OBJECT_EXAMINE7_COMBO1, INV_OBJECT_EXAMINE7_COMBO2, INV_OBJECT_EXAMINE7},
{combine_Examine8, INV_OBJECT_EXAMINE8_COMBO1, INV_OBJECT_EXAMINE8_COMBO2, INV_OBJECT_EXAMINE8},
{combine_ClockWorkBeetle, INV_OBJECT_BEETLE_PART1, INV_OBJECT_BEETLE_PART2, INV_OBJECT_BEETLE}
};
InventoryObject inventry_objects_list[INVENTORY_TABLE_SIZE] =
{
// Weapons
{ID_PISTOLS_ITEM, 6, 0.5f, ANGLE(90), ANGLE(243.69873046875f), ANGLE(276.1328125), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_PISTOLS, STRING_PISTOLS, NO_MESH_BITS, INV_ROT_Y},
{ID_PISTOLS_AMMO_ITEM, 4, 0.5f, 0, ANGLE(90), 0, OPT_USE, STRING_PISTOLS_AMMO, NO_MESH_BITS, INV_ROT_Y},
{ID_UZI_ITEM, -4, 0.5f, ANGLE(-90) , ANGLE(135), ANGLE(90), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_UZI, STRING_UZI , NO_MESH_BITS, INV_ROT_Y},
{ID_UZI_AMMO_ITEM, 5, 0.5f, 0, 5384, 0, OPT_USE, STRING_UZI_AMMO, NO_MESH_BITS, INV_ROT_Y},
{ID_SHOTGUN_ITEM, -6, 0.8f, ANGLE(-20), ANGLE(270), ANGLE(45), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_SHOTGUN, STRING_SHOTGUN, 1, INV_ROT_Y},
{ID_SHOTGUN_AMMO1_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_SHOTGUN_AMMO1, NO_MESH_BITS, INV_ROT_Y},
{ID_SHOTGUN_AMMO2_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_SHOTGUN_AMMO2, NO_MESH_BITS, INV_ROT_Y},
{ID_REVOLVER_ITEM, 0, 0.5f, ANGLE(-90), ANGLE(60), ANGLE(85), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_REVOLVER, STRING_REVOLVER , 1, INV_ROT_Y},
{ID_REVOLVER_AMMO_ITEM, 0, 0.5f, ANGLE(90), ANGLE(-16), 0, OPT_USE, STRING_REVOLVER_AMMO, NO_MESH_BITS, INV_ROT_Y},
{ID_REVOLVER_ITEM, 0, 0.5f, ANGLE(90), ANGLE(60), ANGLE(85), OPT_EQUIP | OPT_SEPERATABLE | OPT_CHOOSEAMMO_REVOLVER, STRING_REVOLVER_LASER, 3, INV_ROT_Y},
{ID_CROSSBOW_ITEM, 0, 0.5f, ANGLE(-90), ANGLE(33), 0, OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_CROSSBOW, STRING_CROSSBOW, 1, INV_ROT_Y},
{ID_CROSSBOW_ITEM, 0, 0.5f, ANGLE(-90), ANGLE(33), 0, OPT_EQUIP | OPT_SEPERATABLE | OPT_CHOOSEAMMO_CROSSBOW, STRING_CROSSBOW_LASER, 3, INV_ROT_Y},
{ID_CROSSBOW_AMMO1_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO1, NO_MESH_BITS, INV_ROT_Y},
{ID_CROSSBOW_AMMO2_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO1, NO_MESH_BITS, INV_ROT_Y},
{ID_CROSSBOW_AMMO3_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO1, NO_MESH_BITS, INV_ROT_Y},
{ID_HK_ITEM, 0, 0.5f, ANGLE(0), ANGLE(280), 0, OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_HK, STRING_HK, 1, INV_ROT_Y},
{ID_HK_ITEM, 0, 0.5f, ANGLE(-45), ANGLE(280), 0, OPT_EQUIP | OPT_SEPERATABLE | OPT_CHOOSEAMMO_HK, STRING_HK_SILENCED, NO_MESH_BITS, INV_ROT_Y},
{ID_HK_AMMO_ITEM, 3, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_HK_AMMO, 2},
{ID_GRENADE_GUN_ITEM, 0, 0.5f, ANGLE(90), 0, ANGLE(65), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_GRENADEGUN, STRING_GRENADE_LAUNCHER, NO_MESH_BITS, INV_ROT_Y},
{ID_GRENADE_AMMO1_ITEM, 3, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_GRENADE_AMMO1, NO_MESH_BITS, INV_ROT_Y},
{ID_GRENADE_AMMO2_ITEM, 3, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_GRENADE_AMMO2, NO_MESH_BITS, INV_ROT_Y},
{ID_GRENADE_AMMO3_ITEM, 3, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_GRENADE_AMMO3, NO_MESH_BITS, INV_ROT_Y},
{ID_HARPOON_ITEM, 0, 0.5f, 0, ANGLE(-65), ANGLE(-20), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_HARPOON, STRING_HARPOON_GUN, NO_MESH_BITS, INV_ROT_Y},
{ID_HARPOON_AMMO_ITEM, 3, 0.5f, 0, ANGLE(15), 0, OPT_USE, STRING_HARPOON_AMMO, NO_MESH_BITS, INV_ROT_Y},
{ID_ROCKET_LAUNCHER_ITEM, 0, 0.5f, ANGLE(180), ANGLE(80), 0, OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_ROCKET, STRING_ROCKET_LAUNCHER, NO_MESH_BITS, INV_ROT_Y},
{ID_ROCKET_LAUNCHER_AMMO_ITEM, 3, 0.5f, ANGLE(90), 0, ANGLE(15), OPT_USE, STRING_ROCKET_AMMO, NO_MESH_BITS, INV_ROT_Y},
// Misc
{ID_LASERSIGHT_ITEM, 2, 0.5f, ANGLE(90), ANGLE(10), 0, OPT_USE | OPT_COMBINABLE, STRING_LASERSIGHT, NO_MESH_BITS, INV_ROT_Y},
{ID_SILENCER_ITEM, 1, 0.5f, 0, ANGLE(10), 0, OPT_USE | OPT_COMBINABLE, STRING_SILENCER, NO_MESH_BITS, INV_ROT_Y},
{ID_BIGMEDI_ITEM, 2, 0.7f, ANGLE(180), 0, 0, OPT_USE, STRING_LARGE_MEDIPACK, NO_MESH_BITS, INV_ROT_Y},
{ID_SMALLMEDI_ITEM, 0, 0.7f, ANGLE(180), ANGLE(112), 0, OPT_USE, STRING_SMALL_MEDIPACK, NO_MESH_BITS, INV_ROT_Y},
{ID_BINOCULARS_ITEM, -1, 0.5f, ANGLE(180), ANGLE(10), 0, OPT_USE, STRING_BINOCULARS, NO_MESH_BITS, INV_ROT_Y},
{ID_FLARE_INV_ITEM, 52, 0.8f, ANGLE(0), 0, 0, OPT_USE, STRING_FLARES, NO_MESH_BITS, INV_ROT_Y},
{ID_TIMEX_ITEM, 2, 0.4f, 0, 0, 0, OPT_STATS, STRING_TIMEX, NO_MESH_BITS, INV_ROT_Y},
{ID_PC_LOAD_INV_ITEM, 52, 0.3f, ANGLE(180), 0, 0, OPT_LOAD, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PC_LOAD_SAVE_ITEM, 52, 0.3f, ANGLE(180), 0, 0, OPT_SAVE, STRING_SAVE_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_BURNING_TORCH_ITEM, 14, 0.5f, 0, ANGLE(90), 0, OPT_USE, STRING_TORCH, NO_MESH_BITS, INV_ROT_Y},
{ID_CROWBAR_ITEM, 4, 0.5f, 0, ANGLE(90), 0, OPT_USE, STRING_CROWBAR, NO_MESH_BITS, INV_ROT_Y},
{ID_DIARY_ITEM, 0, 0.3f, ANGLE(180), 0, 0, OPT_DIARY, STRING_DIARY, NO_MESH_BITS, INV_ROT_Y},
{ID_COMPASS_ITEM, -14, 0.5f, 0, 0, 0, 0, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_CLOCKWORK_BEETLE, 14, 0.5f, 0, 0, 0, OPT_USE, STRING_CLOCKWORK_BEETLE, NO_MESH_BITS, INV_ROT_Y},
{ID_CLOCKWORK_BEETLE_COMBO1, 18, 0.5f, 0, 0, 0, OPT_COMBINABLE, STRING_CLOCKWORK_BEETLE_COMBO1, NO_MESH_BITS, INV_ROT_Y},
{ID_CLOCKWORK_BEETLE_COMBO2, 14, 0.5f, 0, 0, 0, OPT_COMBINABLE, STRING_CLOCKWORK_BEETLE_COMBO2, NO_MESH_BITS, INV_ROT_Y},
{ID_WATERSKIN1_EMPTY, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_SMALL_EMPTY, NO_MESH_BITS, INV_ROT_Y},
{ID_WATERSKIN1_1, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_SMALL_1, NO_MESH_BITS, INV_ROT_Y},
{ID_WATERSKIN1_2, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_SMALL_2, NO_MESH_BITS, INV_ROT_Y},
{ID_WATERSKIN1_3, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_SMALL_3, NO_MESH_BITS, INV_ROT_Y},
{ID_WATERSKIN2_EMPTY, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_EMPTY, NO_MESH_BITS, INV_ROT_Y},
{ID_WATERSKIN2_1, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_1, NO_MESH_BITS, INV_ROT_Y},
{ID_WATERSKIN2_2, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_2, NO_MESH_BITS, INV_ROT_Y},
{ID_WATERSKIN2_3, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_3, NO_MESH_BITS, INV_ROT_Y},
{ID_WATERSKIN2_4, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_4, NO_MESH_BITS, INV_ROT_Y},
{ID_WATERSKIN2_5, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_5, NO_MESH_BITS, INV_ROT_Y},
{ID_OPEN_DIARY_ITEM, 0, 0.9f, ANGLE(90), 0, 0, 0, 0, 0, 0},
// Puzzles
{ID_PUZZLE_ITEM1, 14, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM2, 14, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM3, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM4, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM5, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM6, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM7, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM8, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM9, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM10, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM11, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM12, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM13, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM14, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM15, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM16, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
// Puzzle combos
{ID_PUZZLE_ITEM1_COMBO1, 18, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM1_COMBO2, 18, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM2_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM2_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM3_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM3_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM4_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM4_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM5_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM5_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM6_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM6_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM7_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM7_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM8_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM8_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM9_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM9_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM10_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM10_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM11_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM11_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM12_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM12_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM13_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM13_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM14_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM14_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM15_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM15_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM16_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PUZZLE_ITEM16_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
// Keys
{ID_KEY_ITEM1, 14, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM2, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM3, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM4, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM5, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM6, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM7, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM8, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM9, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM10, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM11, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM12, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM13, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM14, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM15, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM16, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
// Key combos
{ID_KEY_ITEM1_COMBO1, 18, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM1_COMBO2, 18, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM2_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM2_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM3_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM3_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM4_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM4_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM5_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM5_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM6_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM6_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM7_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM7_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM8_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM8_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM9_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM9_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM10_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM10_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM11_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM11_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM12_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM12_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM13_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM13_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM14_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM14_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM15_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM15_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM16_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_KEY_ITEM16_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
// Pickups
{ID_PICKUP_ITEM1, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM2, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM3, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM4, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM5, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM6, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM7, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM8, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM9, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM10, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM11, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM12, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM13, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM14, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM15, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM16, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
// Pickup combos
{ID_PICKUP_ITEM1_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM1_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM2_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM2_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM3_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM3_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM4_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM4_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM5_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM5_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM6_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM6_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM7_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM7_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM8_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM8_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM9_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM9_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM10_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM10_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM11_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM11_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM12_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM12_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM13_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM13_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM14_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM14_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM15_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM15_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM16_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_PICKUP_ITEM16_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
// Examines
{ID_EXAMINE1, 4, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE2, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE3, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE4, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE5, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE6, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE7, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE8, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
// Examines combos
{ID_EXAMINE1_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE1_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE2_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE2_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE3_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE3_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE4_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE4_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE5_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE5_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE6_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE6_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE7_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE7_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE8_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
{ID_EXAMINE8_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
};
SettingsData GuiController::GetCurrentSettings()
{
return CurrentSettings;
}
InventoryRing* GuiController::GetRings(char num)
{
return rings[num];
}
short GuiController::GetSelectedOption()
{
return selected_option;
}
Menu GuiController::GetMenuToDisplay()
{
return menu_to_display;
}
void GuiController::SetSelectedOption(short menu)
{
selected_option = menu;
}
void GuiController::SetMenuToDisplay(Menu menu)
{
menu_to_display = menu;
}
InventoryMode GuiController::GetInventoryMode()
{
return invMode;
}
void GuiController::SetInventoryMode(InventoryMode mode)
{
invMode = mode;
}
void GuiController::SetInventoryItemChosen(int num)
{
inventoryItemChosen = num;
}
int GuiController::GetInventoryItemChosen()
{
return inventoryItemChosen;
}
void GuiController::SetEnterInventory(int num)
{
enterInventory = num;
}
int GuiController::GetEnterInventory()
{
return enterInventory;
}
int GuiController::GetLastInventoryItem()
{
return lastInvItem;
}
void GuiController::DrawInventory()
{
g_Renderer.renderInventory();
}
void GuiController::ClearInputVariables(bool flag)
{
goUp = goDown = goRight = goLeft = goSelect = goDeselect = 0;
if (flag)
return;
else //don't wanna make another function for the rest
{
dbUp = dbDown = dbRight = dbLeft = dbSelect = dbDeselect = 0;
rptRight = rptLeft = 0;
}
}
void GuiController::DoDebouncedInput()
{
ClearInputVariables(1);
if (TrInput & IN_LEFT)
{
if (rptLeft >= 8)
goLeft = 1;
else
rptLeft++;
if (!dbLeft)
goLeft = 1;
dbLeft = 1;
}
else
{
dbLeft = 0;
rptLeft = 0;
}
if (TrInput & IN_RIGHT)
{
if (rptRight >= 8)
goRight = 1;
else
rptRight++;
if (!dbRight)
goRight = 1;
dbRight = 1;
}
else
{
dbRight = 0;
rptRight = 0;
}
if (TrInput & IN_FORWARD)
{
if (!dbUp)
goUp = 1;
dbUp = 1;
}
else
dbUp = 0;
if (TrInput & IN_BACK)
{
if (!dbDown)
goDown = 1;
dbDown = 1;
}
else
dbDown = 0;
if (TrInput & IN_ACTION || TrInput & IN_SELECT)
{
dbSelect = 1;
if (invMode == InventoryMode::Save)
{
if (!stop_killing_me_you_dumb_input_system)
{
goSelect = TrInput & IN_SAVE ? 0 : 1;
dbSelect = !goSelect;
stop_killing_me_you_dumb_input_system = dbSelect;
}
}
else if (invMode == InventoryMode::Load)
{
if (!stop_killing_me_you_dumb_input_system)
{
goSelect = TrInput & IN_LOAD ? 0 : 1;
dbSelect = !goSelect;
stop_killing_me_you_dumb_input_system = dbSelect;
}
}
}
else
{
if (dbSelect == 1 && !stop_killing_me_you_dumb_input_system)
goSelect = 1;
dbSelect = 0;
stop_killing_me_you_dumb_input_system = 0;
}
if ((TrInput & IN_DESELECT))
dbDeselect = 1;
else
{
if (dbDeselect == 1 && !stop_killing_me_you_dumb_input_system2)
goDeselect = 1;
dbDeselect = 0;
stop_killing_me_you_dumb_input_system2 = 0;
}
}
InventoryResult GuiController::TitleOptions()
{
auto ret = InventoryResult::None;
static short selected_option_bak;
/*stuff for credits go here!*/
switch (menu_to_display)
{
case Menu::Title:
option_count = 3;
break;
case Menu::SelectLevel:
ret = InventoryResult::None;
option_count = g_GameFlow->GetNumLevels() - 2;
break;
case Menu::LoadGame:
option_count = SAVEGAME_MAX - 1;
break;
case Menu::Options:
option_count = 2;
break;
case Menu::Display:
option_count = 6;
HandleDisplaySettingsInput(0);
break;
case Menu::Controls:
option_count = 17;
HandleControlSettingsInput(0);
break;
case Menu::Sound:
option_count = 4;
HandleSoundSettingsInput(0);
break;
}
DoDebouncedInput();
if (menu_to_display == Menu::Title || menu_to_display == Menu::SelectLevel ||
menu_to_display == Menu::LoadGame || menu_to_display == Menu::Options)
{
if (goUp)
{
if (selected_option <= 0)
selected_option += option_count;
else
selected_option--;
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
}
if (goDown)
{
if (selected_option < option_count)
selected_option++;
else
selected_option -= option_count;
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
}
if (goDeselect && menu_to_display != Menu::Title)
{
menu_to_display = Menu::Title;
selected_option = selected_option_bak;
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
}
}
if (goSelect)
{
if (menu_to_display == Menu::Title)
{
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
switch (selected_option)
{
case 0:
if (g_GameFlow->PlayAnyLevel)
{
selected_option_bak = selected_option;
selected_option = 0;
menu_to_display = Menu::SelectLevel;
}
else
ret = InventoryResult::NewGame;
break;
case 1:
selected_option_bak = selected_option;
selected_option = 0;
menu_to_display = Menu::LoadGame;
break;
case 2:
selected_option_bak = selected_option;
selected_option = 0;
menu_to_display = Menu::Options;
break;
case 3:
ret = InventoryResult::ExitGame;
break;
}
}
else if (menu_to_display == Menu::SelectLevel)
{
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
g_GameFlow->SelectedLevelForNewGame = selected_option;
menu_to_display = Menu::Title;
selected_option = 0;
ret = InventoryResult::NewGameSelectedLevel;
}
else if (menu_to_display == Menu::LoadGame)
{
if (!SavegameInfos[selected_option].Present)
SayNo();
else
{
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
g_GameFlow->SelectedSaveGame = selected_option;
selected_option = 0;
ret = InventoryResult::LoadGame;
}
}
else if (menu_to_display == Menu::Options)
{
switch (selected_option)
{
case 0:
FillDisplayOptions();
menu_to_display = Menu::Display;
break;
case 1:
menu_to_display = Menu::Controls;
selected_option = 0;
break;
case 2:
FillSound();
menu_to_display = Menu::Sound;
selected_option = 0;
break;
}
}
}
return ret;
}
void GuiController::FillDisplayOptions()
{
// Copy configuration to a temporary object
memcpy(&CurrentSettings.conf, &g_Configuration, sizeof(GameConfiguration));
// Get current display mode
vector<RendererVideoAdapter>* adapters = g_Renderer.getAdapters();
RendererVideoAdapter* adapter = &(*adapters)[CurrentSettings.conf.Adapter];
CurrentSettings.videoMode = 0;
for (int i = 0; i < adapter->DisplayModes.size(); i++)
{
RendererDisplayMode* mode = &adapter->DisplayModes[i];
if (mode->Width == CurrentSettings.conf.Width && mode->Height == CurrentSettings.conf.Height &&
mode->RefreshRate == CurrentSettings.conf.RefreshRate)
{
CurrentSettings.videoMode = i;
break;
}
}
}
void GuiController::HandleDisplaySettingsInput(bool pause)
{
vector<RendererVideoAdapter>* adapters = g_Renderer.getAdapters();
RendererVideoAdapter* adapter = &(*adapters)[CurrentSettings.conf.Adapter];
SetDebounce = true;
S_UpdateInput();
SetDebounce = false;
DoDebouncedInput();
if (goDeselect)
{
SoundEffect(SFX_TR4_MENU_SELECT, NULL, 0);
menu_to_display = Menu::Options;
selected_option = 0;
return;
}
if (goLeft)
{
switch (selected_option)
{
case 0:
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
if (CurrentSettings.videoMode > 0)
CurrentSettings.videoMode--;
break;
case 1:
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
CurrentSettings.conf.Windowed = !CurrentSettings.conf.Windowed;
break;
case 2:
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
CurrentSettings.conf.EnableShadows = !CurrentSettings.conf.EnableShadows;
break;
case 3:
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
CurrentSettings.conf.EnableCaustics = !CurrentSettings.conf.EnableCaustics;
break;
case 4:
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
CurrentSettings.conf.EnableVolumetricFog = !CurrentSettings.conf.EnableVolumetricFog;
break;
}
}
if (goRight)
{
switch (selected_option)
{
case 0:
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
if (CurrentSettings.videoMode < adapter->DisplayModes.size() - 1)
CurrentSettings.videoMode++;
break;
case 1:
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
CurrentSettings.conf.Windowed = !CurrentSettings.conf.Windowed;
break;
case 2:
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
CurrentSettings.conf.EnableShadows = !CurrentSettings.conf.EnableShadows;
break;
case 3:
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
CurrentSettings.conf.EnableCaustics = !CurrentSettings.conf.EnableCaustics;
break;
case 4:
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
CurrentSettings.conf.EnableVolumetricFog = !CurrentSettings.conf.EnableVolumetricFog;
break;
}
}
if (goUp)
{
if (selected_option <= 0)
selected_option += option_count;
else
selected_option--;
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
}
if (goDown)
{
if (selected_option < option_count)
selected_option++;
else
selected_option -= option_count;
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
}
if (goSelect)
{
SoundEffect(SFX_TR4_MENU_SELECT, NULL, 0);
if (selected_option == 5)
{
// Save the configuration
RendererDisplayMode* mode = &adapter->DisplayModes[CurrentSettings.videoMode];
CurrentSettings.conf.Width = mode->Width;
CurrentSettings.conf.Height = mode->Height;
CurrentSettings.conf.RefreshRate = mode->RefreshRate;
memcpy(&g_Configuration, &CurrentSettings.conf, sizeof(GameConfiguration));
SaveConfiguration();
// Reset screen and go back
g_Renderer.changeScreenResolution(CurrentSettings.conf.Width, CurrentSettings.conf.Height,
CurrentSettings.conf.RefreshRate, CurrentSettings.conf.Windowed);
menu_to_display = pause ? Menu::Pause : Menu::Options;
selected_option = pause ? 1 : 0;
}
else if (selected_option == 6)
{
menu_to_display = pause ? Menu::Pause : Menu::Options;
selected_option = pause ? 1 : 0;
}
}
}
void GuiController::HandleControlSettingsInput(bool pause)
{
CurrentSettings.waitingForkey = false;
memcpy(&CurrentSettings.conf.KeyboardLayout, &KeyboardLayout[1], NUM_CONTROLS);
if (CurrentSettings.ignoreInput)
{
if (!TrInput)
CurrentSettings.ignoreInput = false;
return;
}
SetDebounce = true;
S_UpdateInput();
SetDebounce = false;
DoDebouncedInput();
if (goSelect && selected_option != 16 && selected_option != 17)
{
SoundEffect(SFX_TR4_MENU_SELECT, NULL, 0);
CurrentSettings.waitingForkey = true;
}
if (CurrentSettings.waitingForkey)
{
TrInput = 0;
DbInput = 0;
ZeroMemory(KeyMap, 256);
while (true)
{
int selectedKey = 0;
for (selectedKey = 0; selectedKey < 256; selectedKey++)
{
if (KeyMap[selectedKey] & 0x80)
break;
}
if (selectedKey == 256)
selectedKey = 0;
if (selectedKey && g_KeyNames[selectedKey])
{
if (selectedKey != DIK_ESCAPE)
{
KeyboardLayout[1][selected_option] = selectedKey;
DefaultConflict();
}
CurrentSettings.waitingForkey = false;
CurrentSettings.ignoreInput = true;
return;
}
if (pause)
{
g_Renderer.renderInventory();
Camera.numberFrames = g_Renderer.SyncRenderer();
}
else
{
g_Renderer.renderTitle();
Camera.numberFrames = g_Renderer.SyncRenderer();
int nframes = Camera.numberFrames;
ControlPhase(nframes, 0);
}
SetDebounce = true;
S_UpdateInput();
SetDebounce = false;
}
}
else
{
if (goUp)
{
if (selected_option <= 0)
selected_option += option_count;
else
selected_option--;
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
}
if (goDown)
{
if (selected_option < option_count)
selected_option++;
else
selected_option -= option_count;
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
}
if (goSelect)
{
if (selected_option == 16) // Apply
{
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
memcpy(KeyboardLayout[1], CurrentSettings.conf.KeyboardLayout, NUM_CONTROLS);
SaveConfiguration();
menu_to_display = pause ? Menu::Pause : Menu::Options;
selected_option = 1;
return;
}
if (selected_option == 17) // Cancel
{
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
menu_to_display = pause ? Menu::Pause : Menu::Options;
selected_option = 1;
return;
}
}
if (goDeselect)
{
menu_to_display = Menu::Options;
selected_option = 1;
}
}
}
void GuiController::FillSound()
{
memcpy(&CurrentSettings.conf, &g_Configuration, sizeof(GameConfiguration));
}
void GuiController::HandleSoundSettingsInput(bool pause)
{
SetDebounce = true;
S_UpdateInput();
SetDebounce = false;
DoDebouncedInput();
if (goDeselect)
{
menu_to_display = Menu::Options;
selected_option = 2;
SetVolumeMusic(g_Configuration.MusicVolume);
SetVolumeFX(g_Configuration.SfxVolume);
return;
}
if (goLeft)
{
switch (selected_option)
{
case 0:
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
CurrentSettings.conf.EnableAudioSpecialEffects = !CurrentSettings.conf.EnableAudioSpecialEffects;
break;
case 1:
if (CurrentSettings.conf.MusicVolume > 0)
{
static int db = 0;
CurrentSettings.conf.MusicVolume--;
SetVolumeMusic(CurrentSettings.conf.MusicVolume);
if (!db)
{
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
db = 10;
}
else
db -= 2;
}
break;
case 2:
if (CurrentSettings.conf.SfxVolume > 0)
{
static int db = 0;
CurrentSettings.conf.SfxVolume--;
SetVolumeFX(CurrentSettings.conf.SfxVolume);
if (!db)
{
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
db = 10;
}
else
db -= 2;
}
break;
}
}
if (goRight)
{
switch (selected_option)
{
case 0:
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
CurrentSettings.conf.EnableAudioSpecialEffects = !CurrentSettings.conf.EnableAudioSpecialEffects;
break;
case 1:
if (CurrentSettings.conf.MusicVolume < 100)
{
static int db = 0;
CurrentSettings.conf.MusicVolume++;
SetVolumeMusic(CurrentSettings.conf.MusicVolume);
if (!db)
{
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
db = 10;
}
else
db -= 2;
}
break;
case 2:
if (CurrentSettings.conf.SfxVolume < 100)
{
static int db = 0;
CurrentSettings.conf.SfxVolume++;
SetVolumeFX(CurrentSettings.conf.SfxVolume);
if (!db)
{
SoundEffect(SFX_TR4_MENU_CHOOSE, NULL, 0);
db = 10;
}
else
db -= 2;
}
break;
}
}
if (goUp)
{
if (selected_option <= 0)
selected_option += option_count;
else
selected_option--;
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
}
if (goDown)
{
if (selected_option < option_count)
selected_option++;
else
selected_option -= option_count;
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
}
if (goSelect)
{
SoundEffect(SFX_TR4_MENU_SELECT, NULL, 0);
if (selected_option == 3)
{
// Save the configuration
memcpy(&g_Configuration, &CurrentSettings.conf, sizeof(GameConfiguration));
SaveConfiguration();
menu_to_display = pause ? Menu::Pause : Menu::Options;
selected_option = pause ? 1 : 2;
}
else if (selected_option == 4)
{
SoundEffect(SFX_TR4_MENU_SELECT, NULL, 0);
SetVolumeMusic(g_Configuration.MusicVolume);
SetVolumeFX(g_Configuration.SfxVolume);
menu_to_display = pause ? Menu::Pause : Menu::Options;
selected_option = pause ? 1 : 2;
}
}
}
InventoryResult GuiController::DoPauseMenu()
{
//basically mini title
switch (menu_to_display)
{
case Menu::Pause:
option_count = 2;
break;
case Menu::Statistics:
option_count = 0;
break;
case Menu::Options:
option_count = 2;
break;
case Menu::Display:
option_count = 6;
HandleDisplaySettingsInput(1);
break;
case Menu::Controls:
option_count = 17;
HandleControlSettingsInput(1);
break;
case Menu::Sound:
option_count = 4;
HandleSoundSettingsInput(1);
break;
}
ClearInputVariables(1);
SetDebounce = true;
S_UpdateInput();
SetDebounce = false;
DoDebouncedInput();
if (menu_to_display == Menu::Pause || menu_to_display == Menu::Options)
{
if (goUp)
{
if (selected_option <= 0)
selected_option += option_count;
else
selected_option--;
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
}
if (goDown)
{
if (selected_option < option_count)
selected_option++;
else
selected_option -= option_count;
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
}
}
if (goDeselect)
{
if (menu_to_display == Menu::Pause)
{
invMode = InventoryMode::None;
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
return InventoryResult::None;
}
if (menu_to_display == Menu::Statistics || menu_to_display == Menu::Options)
{
selected_option = menu_to_display == Menu::Statistics ? 0 : 1;
menu_to_display = Menu::Pause;
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
}
}
if (goSelect)
{
if (menu_to_display == Menu::Pause)
{
switch (selected_option)
{
case 0:
selected_option = 0;
menu_to_display = Menu::Statistics;
break;
case 1:
selected_option = 0;
menu_to_display = Menu::Options;
break;
case 2:
invMode = InventoryMode::None;
return InventoryResult::ExitToTitle;
}
}
else if (menu_to_display == Menu::Options)
{
switch (selected_option)
{
case 0:
FillDisplayOptions();
menu_to_display = Menu::Display;
break;
case 1:
selected_option = 0;
menu_to_display = Menu::Controls;
break;
case 2:
FillSound();
selected_option = 0;
menu_to_display = Menu::Sound;
break;
}
}
}
return InventoryResult::None;
}
/*inventory*/
bool GuiController::DoObjectsCombine(int obj1, int obj2)
{
for (int n = 0; n < max_combines; n++)
{
if (combine_table[n].item1 == obj1 &&
combine_table[n].item2 == obj2)
return 1;
if (combine_table[n].item1 == obj2 &&
combine_table[n].item2 == obj1)
return 1;
}
return 0;
}
bool GuiController::IsItemCurrentlyCombinable(short obj)
{
if (obj < INV_OBJECT_SMOL_WATERSKIN || obj > INV_OBJECT_BIG_WATERSKIN5L)//trash
{
for (int n = 0; n < max_combines; n++)
{
if (combine_table[n].item1 == obj)
if (IsItemInInventory(combine_table[n].item2))
return 1;
if (combine_table[n].item2 == obj)
if (IsItemInInventory(combine_table[n].item1))
return 1;
}
}
else if (obj > INV_OBJECT_SMOL_WATERSKIN3L)
{
for (int n = 0; n < 4; n++)
{
if (IsItemInInventory(n + INV_OBJECT_SMOL_WATERSKIN))
return 1;
}
}
else
{
for (int n = 0; n < 6; n++)
{
if (IsItemInInventory(n + INV_OBJECT_BIG_WATERSKIN))
return 1;
}
}
return 0;
}
bool GuiController::IsItemInInventory(short obj)
{
for (int i = 0; i < INVENTORY_TABLE_SIZE; i++)
if (rings[(int)RingTypes::Inventory]->current_object_list[i].invitem == obj)
return 1;
return 0;
}
void GuiController::CombineObjects(short obj1, short obj2)
{
int n;
for (n = 0; n < max_combines; n++)
{
if (combine_table[n].item1 == obj1 &&
combine_table[n].item2 == obj2)
break;
if (combine_table[n].item1 == obj2 &&
combine_table[n].item2 == obj1)
break;
}
combine_table[n].combine_routine(0);
ConstructObjectList();
SetupObjectListStartPosition(combine_table[n].combined_item);
HandleObjectChangeover((int)RingTypes::Inventory);
}
void GuiController::SeparateObject(short obj)
{
int n;
for (n = 0; n < max_combines; n++)
if (combine_table[n].combined_item == obj)
break;
combine_table[n].combine_routine(1);
ConstructObjectList();
SetupObjectListStartPosition(combine_table[n].item1);
}
void GuiController::SetupObjectListStartPosition(short newobj)
{
for (int i = 0; i < INVENTORY_TABLE_SIZE; i++)
if (rings[(int)RingTypes::Inventory]->current_object_list[i].invitem == newobj)
rings[(int)RingTypes::Inventory]->curobjinlist = i;
}
void GuiController::HandleObjectChangeover(int ringnum)
{
current_selected_option = 0;
menu_active = 1;
SetupAmmoSelector();
}
void GuiController::SetupAmmoSelector()
{
int num;
unsigned __int64 opts;
num = 0;
opts = inventry_objects_list[rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->curobjinlist].invitem].opts;
ammo_selector_flag = 0;
num_ammo_slots = 0;
if (rings[(int)RingTypes::Ammo]->ringactive)
return;
ammo_object_list[0].xrot = 0;
ammo_object_list[0].yrot = 0;
ammo_object_list[0].zrot = 0;
ammo_object_list[1].xrot = 0;
ammo_object_list[1].yrot = 0;
ammo_object_list[1].zrot = 0;
ammo_object_list[2].xrot = 0;
ammo_object_list[2].yrot = 0;
ammo_object_list[2].zrot = 0;
if (opts &
(OPT_CHOOSEAMMO_UZI | OPT_CHOOSEAMMO_PISTOLS | OPT_CHOOSEAMMO_REVOLVER | OPT_CHOOSEAMMO_CROSSBOW |
OPT_CHOOSEAMMO_HK | OPT_CHOOSEAMMO_SHOTGUN | OPT_CHOOSEAMMO_GRENADEGUN | OPT_CHOOSEAMMO_HARPOON | OPT_CHOOSEAMMO_ROCKET))
{
ammo_selector_flag = 1;
ammo_selector_fade_dir = 1;
if (opts & OPT_CHOOSEAMMO_UZI)
{
ammo_object_list[0].invitem = INV_OBJECT_UZI_AMMO;
ammo_object_list[0].amount = AmountUziAmmo;
num++;
num_ammo_slots = num;
current_ammo_type = &CurrentUziAmmoType;
}
if (opts & OPT_CHOOSEAMMO_PISTOLS)
{
num++;
ammo_object_list[0].invitem = INV_OBJECT_PISTOLS_AMMO;
ammo_object_list[0].amount = -1;
num_ammo_slots = num;
current_ammo_type = &CurrentPistolsAmmoType;
}
if (opts & OPT_CHOOSEAMMO_REVOLVER)
{
num++;
ammo_object_list[0].invitem = INV_OBJECT_REVOLVER_AMMO;
ammo_object_list[0].amount = AmountRevolverAmmo;
num_ammo_slots = num;
current_ammo_type = &CurrentRevolverAmmoType;
}
if (opts & OPT_CHOOSEAMMO_CROSSBOW)
{
ammo_object_list[num].invitem = INV_OBJECT_CROSSBOW_AMMO1;
ammo_object_list[num].amount = AmountCrossBowAmmo1;
num++;
ammo_object_list[num].invitem = INV_OBJECT_CROSSBOW_AMMO2;
ammo_object_list[num].amount = AmountCrossBowAmmo2;
num++;
ammo_object_list[num].invitem = INV_OBJECT_CROSSBOW_AMMO3;
ammo_object_list[num].amount = AmountCrossBowAmmo3;
num++;
num_ammo_slots = num;
current_ammo_type = &CurrentCrossBowAmmoType;
}
if (opts & OPT_CHOOSEAMMO_HK)
{
ammo_object_list[num].invitem = INV_OBJECT_HK_AMMO;
ammo_object_list[num].amount = AmountHKAmmo1;
num++;
num_ammo_slots = num;
current_ammo_type = &CurrentHKAmmoType;
}
if (opts & OPT_CHOOSEAMMO_SHOTGUN)
{
ammo_object_list[num].invitem = INV_OBJECT_SHOTGUN_AMMO1;
ammo_object_list[num].amount = AmountShotGunAmmo1;
num++;
ammo_object_list[num].invitem = INV_OBJECT_SHOTGUN_AMMO2;
ammo_object_list[num].amount = AmountShotGunAmmo2;
num++;
num_ammo_slots = num;
current_ammo_type = &CurrentShotGunAmmoType;
}
if (opts & OPT_CHOOSEAMMO_GRENADEGUN)
{
ammo_object_list[num].invitem = INV_OBJECT_GRENADE_AMMO1;
ammo_object_list[num].amount = AmountGrenadeAmmo1;
num++;
ammo_object_list[num].invitem = INV_OBJECT_GRENADE_AMMO2;
ammo_object_list[num].amount = AmountGrenadeAmmo2;
num++;
ammo_object_list[num].invitem = INV_OBJECT_GRENADE_AMMO3;
ammo_object_list[num].amount = AmountGrenadeAmmo3;
num++;
num_ammo_slots = num;
current_ammo_type = &CurrentGrenadeGunAmmoType;
}
if (opts & OPT_CHOOSEAMMO_HARPOON)
{
ammo_object_list[num].invitem = INV_OBJECT_HARPOON_AMMO;
ammo_object_list[num].amount = AmountHarpoonAmmo;
num++;
num_ammo_slots = num;
current_ammo_type = &CurrentHarpoonAmmoType;
}
if (opts & OPT_CHOOSEAMMO_ROCKET)
{
ammo_object_list[num].invitem = INV_OBJECT_ROCKET_AMMO;
ammo_object_list[num].amount = AmountRocketsAmmo;
num++;
num_ammo_slots = num;
current_ammo_type = &CurrentRocketAmmoType;
}
}
}
void GuiController::InsertObjectIntoList(int num)
{
rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->numobjectsinlist].invitem = num;
rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->numobjectsinlist].xrot = 0;
rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->numobjectsinlist].yrot = 0;
rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->numobjectsinlist].zrot = 0;
rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->numobjectsinlist].bright = 32;
rings[(int)RingTypes::Inventory]->numobjectsinlist++;
}
void GuiController::InsertObjectIntoList_v2(int num)
{
unsigned __int64 opts = inventry_objects_list[num].opts;
if (opts & (OPT_COMBINABLE | OPT_ALWAYSCOMBINE))
{
if (rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->curobjinlist].invitem != num)
{
rings[(int)RingTypes::Ammo]->current_object_list[rings[(int)RingTypes::Ammo]->numobjectsinlist].invitem = num;
rings[(int)RingTypes::Ammo]->current_object_list[rings[(int)RingTypes::Ammo]->numobjectsinlist].xrot = 0;
rings[(int)RingTypes::Ammo]->current_object_list[rings[(int)RingTypes::Ammo]->numobjectsinlist].yrot = 0;
rings[(int)RingTypes::Ammo]->current_object_list[rings[(int)RingTypes::Ammo]->numobjectsinlist].zrot = 0;
rings[(int)RingTypes::Ammo]->current_object_list[rings[(int)RingTypes::Ammo]->numobjectsinlist++].bright = 32;
}
}
}
void GuiController::ConstructObjectList()
{
rings[(int)RingTypes::Inventory]->numobjectsinlist = 0;
for (int i = 0; i < INVENTORY_TABLE_SIZE; i++)
rings[(int)RingTypes::Inventory]->current_object_list[i].invitem = NO_ITEM;
CurrentPistolsAmmoType = 0;
CurrentUziAmmoType = 0;
CurrentRevolverAmmoType = 0;
CurrentShotGunAmmoType = 0;
CurrentGrenadeGunAmmoType = 0;
CurrentCrossBowAmmoType = 0;
if (!(g_GameFlow->GetLevel(CurrentLevel)->LaraType == LaraType::Young))
{
if (Lara.Weapons[WEAPON_PISTOLS].Present)
InsertObjectIntoList(INV_OBJECT_PISTOLS);
else if (AmountPistolsAmmo)
InsertObjectIntoList(INV_OBJECT_PISTOLS_AMMO);
if (Lara.Weapons[WEAPON_UZI].Present)
InsertObjectIntoList(INV_OBJECT_UZIS);
else if (AmountUziAmmo)
InsertObjectIntoList(INV_OBJECT_UZI_AMMO);
if (Lara.Weapons[WEAPON_REVOLVER].Present)
{
if (Lara.Weapons[WEAPON_REVOLVER].HasLasersight)
InsertObjectIntoList(INV_OBJECT_REVOLVER_LASER);
else
InsertObjectIntoList(INV_OBJECT_REVOLVER);
}
else if (AmountRevolverAmmo)
InsertObjectIntoList(INV_OBJECT_REVOLVER_AMMO);
if (Lara.Weapons[WEAPON_SHOTGUN].Present)
{
InsertObjectIntoList(INV_OBJECT_SHOTGUN);
if (Lara.Weapons[WEAPON_SHOTGUN].SelectedAmmo == WEAPON_AMMO2)
CurrentShotGunAmmoType = 1;
}
else
{
if (AmountShotGunAmmo1)
InsertObjectIntoList(INV_OBJECT_SHOTGUN_AMMO1);
if (AmountShotGunAmmo2)
InsertObjectIntoList(INV_OBJECT_SHOTGUN_AMMO2);
}
if (Lara.Weapons[WEAPON_HK].Present)
{
if (Lara.Weapons[WEAPON_HK].HasSilencer)
InsertObjectIntoList(INV_OBJECT_HK_SILENCER);
else
InsertObjectIntoList(INV_OBJECT_HK);
}
else if (AmountHKAmmo1)
InsertObjectIntoList(INV_OBJECT_HK_AMMO);
if (Lara.Weapons[WEAPON_CROSSBOW].Present)
{
if (Lara.Weapons[WEAPON_CROSSBOW].HasLasersight)
InsertObjectIntoList(INV_OBJECT_CROSSBOW_LASER);
else
InsertObjectIntoList(INV_OBJECT_CROSSBOW);
if (Lara.Weapons[WEAPON_CROSSBOW].SelectedAmmo == WEAPON_AMMO2)
CurrentCrossBowAmmoType = 1;
if (Lara.Weapons[WEAPON_CROSSBOW].SelectedAmmo == WEAPON_AMMO3)
CurrentCrossBowAmmoType = 2;
}
else
{
if (AmountCrossBowAmmo1)
InsertObjectIntoList(INV_OBJECT_CROSSBOW_AMMO1);
if (AmountCrossBowAmmo2)
InsertObjectIntoList(INV_OBJECT_CROSSBOW_AMMO2);
if (AmountCrossBowAmmo3)
InsertObjectIntoList(INV_OBJECT_CROSSBOW_AMMO3);
}
if (Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Present)
{
InsertObjectIntoList(INV_OBJECT_GRENADE_LAUNCHER);
if (Lara.Weapons[WEAPON_GRENADE_LAUNCHER].SelectedAmmo == WEAPON_AMMO2)
CurrentGrenadeGunAmmoType = 1;
if (Lara.Weapons[WEAPON_GRENADE_LAUNCHER].SelectedAmmo == WEAPON_AMMO3)
CurrentGrenadeGunAmmoType = 2;
}
else
{
if (AmountGrenadeAmmo1)
InsertObjectIntoList(INV_OBJECT_GRENADE_AMMO1);
if (AmountGrenadeAmmo2)
InsertObjectIntoList(INV_OBJECT_GRENADE_AMMO2);
if (AmountGrenadeAmmo3)
InsertObjectIntoList(INV_OBJECT_GRENADE_AMMO3);
}
if (Lara.Weapons[WEAPON_ROCKET_LAUNCHER].Present)
InsertObjectIntoList(INV_OBJECT_ROCKET_LAUNCHER);
else if (AmountRocketsAmmo)
InsertObjectIntoList(INV_OBJECT_ROCKET_AMMO);
if (Lara.Weapons[WEAPON_HARPOON_GUN].Present)
InsertObjectIntoList(INV_OBJECT_HARPOON_GUN);
else if (AmountHarpoonAmmo)
InsertObjectIntoList(INV_OBJECT_HARPOON_AMMO);
if (Lara.Lasersight)
InsertObjectIntoList(INV_OBJECT_LASERSIGHT);
if (Lara.Silencer)
InsertObjectIntoList(INV_OBJECT_SILENCER);
if (Lara.Binoculars)
InsertObjectIntoList(INV_OBJECT_BINOCULARS);
if (Lara.NumFlares)
InsertObjectIntoList(INV_OBJECT_FLARES);
}
InsertObjectIntoList(INV_OBJECT_TIMEX);//every level has the timex? what's a good way to check?!
if (Lara.NumSmallMedipacks)
InsertObjectIntoList(INV_OBJECT_SMALL_MEDIPACK);
if (Lara.NumLargeMedipacks)
InsertObjectIntoList(INV_OBJECT_LARGE_MEDIPACK);
if (Lara.Crowbar)
InsertObjectIntoList(INV_OBJECT_CROWBAR);
if (Lara.hasBeetleThings)
{
if (Lara.hasBeetleThings & 1)
InsertObjectIntoList(INV_OBJECT_BEETLE);
if (Lara.hasBeetleThings & 2)
InsertObjectIntoList(INV_OBJECT_BEETLE_PART1);
if (Lara.hasBeetleThings & 4)
InsertObjectIntoList(INV_OBJECT_BEETLE_PART2);
}
if (Lara.small_waterskin)
InsertObjectIntoList((Lara.small_waterskin - 1) + INV_OBJECT_SMOL_WATERSKIN);
if (Lara.big_waterskin)
InsertObjectIntoList((Lara.big_waterskin - 1) + INV_OBJECT_BIG_WATERSKIN);
for (int i = 0; i < NUM_PUZZLES; i++)
if (Lara.Puzzles[i])
InsertObjectIntoList(INV_OBJECT_PUZZLE1 + i);
for (int i = 0; i < NUM_PUZZLE_PIECES; i++)
if (Lara.PuzzlesCombo[i])
InsertObjectIntoList(INV_OBJECT_PUZZLE1_COMBO1 + i);
for (int i = 0; i < NUM_KEYS; i++)
if (Lara.Keys[i])
InsertObjectIntoList(INV_OBJECT_KEY1 + i);
for (int i = 0; i < NUM_KEY_PIECES; i++)
if (Lara.KeysCombo[i])
InsertObjectIntoList(INV_OBJECT_KEY1_COMBO1 + i);
for (int i = 0; i < NUM_PICKUPS; i++)
if (Lara.Pickups[i])
InsertObjectIntoList(INV_OBJECT_PICKUP1 + i);
for (int i = 0; i < NUM_PICKUPS_PIECES; i++)
if (Lara.PickupsCombo[i])
InsertObjectIntoList(INV_OBJECT_PICKUP1_COMBO1 + i);
for (int i = 0; i < NUM_EXAMINES; i++)
if (Lara.Examines[i])
InsertObjectIntoList(INV_OBJECT_EXAMINE1 + i);
for (int i = 0; i < NUM_EXAMINES_PIECES; i++)
if (Lara.ExaminesCombo[i])
InsertObjectIntoList(INV_OBJECT_EXAMINE1_COMBO1 + i);
if (Lara.Diary.Present)
InsertObjectIntoList(INV_OBJECT_DIARY);
if (g_GameFlow->EnableLoadSave)
{
InsertObjectIntoList(INV_OBJECT_LOAD_FLOPPY);
InsertObjectIntoList(INV_OBJECT_SAVE_FLOPPY);
}
rings[(int)RingTypes::Inventory]->objlistmovement = 0;
rings[(int)RingTypes::Inventory]->curobjinlist = 0;
rings[(int)RingTypes::Inventory]->ringactive = 1;
rings[(int)RingTypes::Ammo]->objlistmovement = 0;
rings[(int)RingTypes::Ammo]->curobjinlist = 0;
rings[(int)RingTypes::Ammo]->ringactive = 0;
HandleObjectChangeover((int)RingTypes::Inventory);
ammo_active = 0;
}
void GuiController::ConstructCombineObjectList()
{
rings[(int)RingTypes::Ammo]->numobjectsinlist = 0;
for (int i = 0; i < INVENTORY_TABLE_SIZE; i++)
rings[(int)RingTypes::Ammo]->current_object_list[i].invitem = NO_ITEM;
if (!(g_GameFlow->GetLevel(CurrentLevel)->LaraType == LaraType::Young))
{
if (Lara.Weapons[WEAPON_REVOLVER].Present)
{
if (Lara.Weapons[WEAPON_REVOLVER].HasLasersight)
InsertObjectIntoList_v2(INV_OBJECT_REVOLVER_LASER);
else
InsertObjectIntoList_v2(INV_OBJECT_REVOLVER);
}
if (Lara.Weapons[WEAPON_HK].Present)
InsertObjectIntoList_v2(INV_OBJECT_HK);
if (Lara.Weapons[WEAPON_CROSSBOW].Present)
{
if (Lara.Weapons[WEAPON_CROSSBOW].HasLasersight)
InsertObjectIntoList_v2(INV_OBJECT_CROSSBOW_LASER);
else
InsertObjectIntoList_v2(INV_OBJECT_CROSSBOW);
}
if (Lara.Lasersight)
InsertObjectIntoList_v2(INV_OBJECT_LASERSIGHT);
if (Lara.Silencer)
InsertObjectIntoList_v2(INV_OBJECT_SILENCER);
}
if (Lara.hasBeetleThings)
{
if (Lara.hasBeetleThings & 2)
InsertObjectIntoList_v2(INV_OBJECT_BEETLE_PART1);
if (Lara.hasBeetleThings & 4)
InsertObjectIntoList_v2(INV_OBJECT_BEETLE_PART2);
}
if (Lara.small_waterskin)
InsertObjectIntoList_v2(Lara.small_waterskin - 1 + INV_OBJECT_SMOL_WATERSKIN);
if (Lara.big_waterskin)
InsertObjectIntoList_v2(Lara.big_waterskin - 1 + INV_OBJECT_BIG_WATERSKIN);
for (int i = 0; i < NUM_PUZZLE_PIECES; i++)
if (Lara.PuzzlesCombo[i])
InsertObjectIntoList_v2(INV_OBJECT_PUZZLE1_COMBO1 + i);
for (int i = 0; i < NUM_KEY_PIECES; i++)
if (Lara.KeysCombo[i])
InsertObjectIntoList_v2(INV_OBJECT_KEY1_COMBO1 + i);
for (int i = 0; i < NUM_PICKUPS_PIECES; i++)
if (Lara.PickupsCombo[i])
InsertObjectIntoList_v2(INV_OBJECT_PICKUP1_COMBO1 + i);
for (int i = 0; i < NUM_EXAMINES_PIECES; i++)
if (Lara.ExaminesCombo[i])
InsertObjectIntoList_v2(INV_OBJECT_EXAMINE1_COMBO1 + i);
rings[(int)RingTypes::Ammo]->objlistmovement = 0;
rings[(int)RingTypes::Ammo]->curobjinlist = 0;
rings[(int)RingTypes::Ammo]->ringactive = 0;
}
void GuiController::InitializeInventory()
{
compassNeedleAngle = 4096;
AlterFOV(14560);
Lara.busy = 0;
inventoryItemChosen = NO_ITEM;
ClearInputVariables(0);
useItem = 0;
if (Lara.Weapons[WEAPON_SHOTGUN].Ammo[0].hasInfinite())
AmountShotGunAmmo1 = -1;
else
AmountShotGunAmmo1 = Lara.Weapons[WEAPON_SHOTGUN].Ammo[0].getCount() / 6;
if (Lara.Weapons[WEAPON_SHOTGUN].Ammo[1].hasInfinite())
AmountShotGunAmmo2 = -1;
else
AmountShotGunAmmo2 = Lara.Weapons[WEAPON_SHOTGUN].Ammo[1].getCount() / 6;
AmountHKAmmo1 = Lara.Weapons[WEAPON_HK].Ammo[WEAPON_AMMO1].hasInfinite() ? -1 : Lara.Weapons[WEAPON_HK].Ammo[WEAPON_AMMO1].getCount();
AmountCrossBowAmmo1 = Lara.Weapons[WEAPON_CROSSBOW].Ammo[WEAPON_AMMO1].hasInfinite() ? -1 : Lara.Weapons[WEAPON_CROSSBOW].Ammo[WEAPON_AMMO1].getCount();
AmountCrossBowAmmo2 = Lara.Weapons[WEAPON_CROSSBOW].Ammo[WEAPON_AMMO2].hasInfinite() ? -1 : Lara.Weapons[WEAPON_CROSSBOW].Ammo[WEAPON_AMMO2].getCount();
AmountCrossBowAmmo3 = Lara.Weapons[WEAPON_CROSSBOW].Ammo[WEAPON_AMMO3].hasInfinite() ? -1 : Lara.Weapons[WEAPON_CROSSBOW].Ammo[WEAPON_AMMO3].getCount();
AmountUziAmmo = Lara.Weapons[WEAPON_UZI].Ammo[WEAPON_AMMO1].hasInfinite() ? -1 : Lara.Weapons[WEAPON_UZI].Ammo[WEAPON_AMMO1].getCount();
AmountRevolverAmmo = Lara.Weapons[WEAPON_REVOLVER].Ammo[WEAPON_AMMO1].hasInfinite() ? -1 : Lara.Weapons[WEAPON_REVOLVER].Ammo[WEAPON_AMMO1].getCount();
AmountPistolsAmmo = Lara.Weapons[WEAPON_PISTOLS].Ammo[WEAPON_AMMO1].hasInfinite() ? -1 : Lara.Weapons[WEAPON_PISTOLS].Ammo[WEAPON_AMMO1].getCount();
AmountRocketsAmmo = Lara.Weapons[WEAPON_ROCKET_LAUNCHER].Ammo[WEAPON_AMMO1].hasInfinite() ? -1 : Lara.Weapons[WEAPON_ROCKET_LAUNCHER].Ammo[WEAPON_AMMO1].getCount();
AmountHarpoonAmmo = Lara.Weapons[WEAPON_HARPOON_GUN].Ammo[WEAPON_AMMO1].hasInfinite()? -1 : Lara.Weapons[WEAPON_HARPOON_GUN].Ammo[WEAPON_AMMO1].getCount();
AmountGrenadeAmmo1 = Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Ammo[WEAPON_AMMO1].hasInfinite()? -1 : Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Ammo[WEAPON_AMMO1].getCount();
AmountGrenadeAmmo2 = Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Ammo[WEAPON_AMMO2].hasInfinite() ? -1 : Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Ammo[WEAPON_AMMO2].getCount();
AmountGrenadeAmmo3 = Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Ammo[WEAPON_AMMO3].hasInfinite() ? -1 : Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Ammo[WEAPON_AMMO3].getCount();
ConstructObjectList();
if (enterInventory == NO_ITEM)
{
if (lastInvItem != NO_ITEM)
{
if (IsItemInInventory(lastInvItem))
SetupObjectListStartPosition(lastInvItem);
else//son of a bitch
{
if (lastInvItem >= INV_OBJECT_SMOL_WATERSKIN && lastInvItem <= INV_OBJECT_SMOL_WATERSKIN3L)
{
for (int i = INV_OBJECT_SMOL_WATERSKIN; i <= INV_OBJECT_SMOL_WATERSKIN3L; i++)
{
if (IsItemInInventory(i))
{
SetupObjectListStartPosition(i);
break;
}
}
}
else if (lastInvItem >= INV_OBJECT_BIG_WATERSKIN && lastInvItem <= INV_OBJECT_BIG_WATERSKIN5L)
{
for (int i = INV_OBJECT_BIG_WATERSKIN; i <= INV_OBJECT_BIG_WATERSKIN5L; i++)
{
if (IsItemInInventory(i))
{
SetupObjectListStartPosition(i);
break;
}
}
}
}
lastInvItem = NO_ITEM;
}
}
else
{
if (IsObjectInInventory(enterInventory))
SetupObjectListStartPosition2(enterInventory);
enterInventory = NO_ITEM;
}
ammo_selector_fade_val = 0;
ammo_selector_fade_dir = 0;
combine_ring_fade_val = 0;
combine_ring_fade_dir = 0;
combine_type_flag = 0;
seperate_type_flag = 0;
combine_obj1 = 0;
combine_obj2 = 0;
normal_ring_fade_val = 128;
normal_ring_fade_dir = 0;
HandleObjectChangeover((int)RingTypes::Inventory);
}
int GuiController::IsObjectInInventory(short object_number)
{
return GetInventoryCount(from_underlying(object_number));
}
void GuiController::SetupObjectListStartPosition2(short newobj)
{
for (int i = 0; i < INVENTORY_TABLE_SIZE; i++)
if (inventry_objects_list[rings[(int)RingTypes::Inventory]->current_object_list[i].invitem].object_number == newobj)
rings[(int)RingTypes::Inventory]->curobjinlist = i;
}
int GuiController::ConvertObjectToInventoryItem(short obj)
{
for (int i = 0; i < INVENTORY_TABLE_SIZE; i++)
{
if (inventry_objects_list[i].object_number == obj)
return i;
}
return -1;
}
int GuiController::ConvertInventoryItemToObject(int obj)
{
return inventry_objects_list[obj].object_number;
}
void GuiController::FadeAmmoSelector()
{
if (rings[(int)RingTypes::Inventory]->ringactive && (rptLeft >= 8 || rptRight >= 8))
ammo_selector_fade_val = 0;
else if (ammo_selector_fade_dir == 1)
{
if (ammo_selector_fade_val < 128)
ammo_selector_fade_val += 32;
if (ammo_selector_fade_val > 128)
{
ammo_selector_fade_val = 128;
ammo_selector_fade_dir = 0;
}
}
else if (ammo_selector_fade_dir == 2)
{
if (ammo_selector_fade_val > 0)
ammo_selector_fade_val -= 32;
if (ammo_selector_fade_val < 0)
{
ammo_selector_fade_val = 0;
ammo_selector_fade_dir = 0;
}
}
}
void GuiController::UseCurrentItem()
{
short invobject, gmeobject;
long OldBinocular;
OldBinocular = BinocularRange;
Lara.oldBusy = false;
BinocularRange = 0;
LaraItem->meshBits = -1;
invobject = rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->curobjinlist].invitem;
gmeobject = inventry_objects_list[invobject].object_number;
if (Lara.waterStatus == LW_ABOVE_WATER || Lara.waterStatus == LW_WADE)
{
if (gmeobject == ID_PISTOLS_ITEM)
{
Lara.requestGunType = WEAPON_PISTOLS;
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_PISTOLS)
Lara.gunStatus = LG_DRAW_GUNS;
return;
}
if (gmeobject == ID_UZI_ITEM)
{
Lara.requestGunType = WEAPON_UZI;
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_UZI)
Lara.gunStatus = LG_DRAW_GUNS;
return;
}
}
if (gmeobject != ID_SHOTGUN_ITEM && gmeobject != ID_REVOLVER_ITEM && gmeobject != ID_HK_ITEM && gmeobject != ID_CROSSBOW_ITEM &&
gmeobject != ID_GRENADE_GUN_ITEM && gmeobject != ID_ROCKET_LAUNCHER_ITEM && gmeobject != ID_HARPOON_ITEM)
{
if (gmeobject == ID_FLARE_INV_ITEM)
{
if (Lara.gunStatus == LG_HANDS_FREE)
{
if (LaraItem->currentAnimState != LS_CRAWL_IDLE &&
LaraItem->currentAnimState != LS_CRAWL_FORWARD &&
LaraItem->currentAnimState != LS_CRAWL_TURN_LEFT &&
LaraItem->currentAnimState != LS_CRAWL_TURN_RIGHT &&
LaraItem->currentAnimState != LS_CRAWL_BACK &&
LaraItem->currentAnimState != LS_CRAWL_TO_HANG)
{
if (Lara.gunType != WEAPON_FLARE)
{
TrInput = IN_FLARE;
LaraGun(LaraItem);
TrInput = 0;
}
return;
}
}
SayNo();
return;
}
switch (invobject)
{
case INV_OBJECT_BINOCULARS:
if (((LaraItem->currentAnimState == LS_IDLE && LaraItem->animNumber == LA_STAND_IDLE)
|| (Lara.isDucked && !(TrInput & IN_DUCK)))
&& !UseSpotCam
&& !TrackCameraInit)
{
Lara.oldBusy = true;
BinocularRange = 128;
if (Lara.gunStatus != LG_HANDS_FREE)
Lara.gunStatus = LG_UNDRAW_GUNS;
}
if (OldBinocular)
BinocularRange = OldBinocular;
else
BinocularOldCamera = Camera.oldType;
return;
case INV_OBJECT_SMALL_MEDIPACK:
if ((LaraItem->hitPoints <= 0 || LaraItem->hitPoints >= 1000) && !Lara.poisoned)
{
SayNo();
return;
}
if (Lara.NumSmallMedipacks != 0)
{
if (Lara.NumSmallMedipacks != -1)
Lara.NumSmallMedipacks--;
Lara.poisoned = 0;
LaraItem->hitPoints += 500;
if (LaraItem->hitPoints > 1000)
LaraItem->hitPoints = 1000;
SoundEffect(SFX_TR4_MENU_MEDI, 0, SFX_ALWAYS);
Statistics.Game.HealthUsed++;
}
else
SayNo();
return;
case INV_OBJECT_LARGE_MEDIPACK:
if ((LaraItem->hitPoints <= 0 || LaraItem->hitPoints >= 1000) && !Lara.poisoned)
{
SayNo();
return;
}
if (Lara.NumLargeMedipacks != 0)
{
if (Lara.NumLargeMedipacks != -1)
Lara.NumLargeMedipacks--;
Lara.poisoned = 0;
LaraItem->hitPoints = 1000;
SoundEffect(SFX_TR4_MENU_MEDI, 0, SFX_ALWAYS);
Statistics.Game.HealthUsed++;
}
else
SayNo();
return;
default:
inventoryItemChosen = gmeobject;
return;
}
return;
}
if (Lara.gunStatus == LG_HANDS_BUSY)
{
SayNo();
return;
}
if (LaraItem->currentAnimState == LS_CRAWL_IDLE ||
LaraItem->currentAnimState == LS_CRAWL_FORWARD ||
LaraItem->currentAnimState == LS_CRAWL_TURN_LEFT ||
LaraItem->currentAnimState == LS_CRAWL_TURN_RIGHT ||
LaraItem->currentAnimState == LS_CRAWL_BACK ||
LaraItem->currentAnimState == LS_CRAWL_TO_HANG ||
LaraItem->currentAnimState == LS_CROUCH_IDLE ||
LaraItem->currentAnimState == LS_CROUCH_TURN_LEFT ||
LaraItem->currentAnimState == LS_CROUCH_TURN_RIGHT)
{
SayNo();
return;
}
if (gmeobject == ID_SHOTGUN_ITEM)
{
Lara.requestGunType = WEAPON_SHOTGUN;
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_SHOTGUN)
Lara.gunStatus = LG_DRAW_GUNS;
return;
}
if (gmeobject == ID_REVOLVER_ITEM)
{
Lara.requestGunType = WEAPON_REVOLVER;
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_REVOLVER)
Lara.gunStatus = LG_DRAW_GUNS;
return;
}
else if (gmeobject == ID_HK_ITEM)
{
Lara.requestGunType = WEAPON_HK;
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_HK)
Lara.gunStatus = LG_DRAW_GUNS;
return;
}
else if (gmeobject == ID_CROSSBOW_ITEM)
{
Lara.requestGunType = WEAPON_CROSSBOW;
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_CROSSBOW)
Lara.gunStatus = LG_DRAW_GUNS;
return;
}
else if (gmeobject == ID_GRENADE_GUN_ITEM)
{
Lara.requestGunType = WEAPON_GRENADE_LAUNCHER;
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_GRENADE_LAUNCHER)
Lara.gunStatus = LG_DRAW_GUNS;
return;
}
else if (gmeobject == ID_HARPOON_ITEM)
{
Lara.requestGunType = WEAPON_HARPOON_GUN;
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_HARPOON_GUN)
Lara.gunStatus = LG_DRAW_GUNS;
return;
}
else if (gmeobject == ID_ROCKET_LAUNCHER_ITEM)
{
Lara.requestGunType = WEAPON_ROCKET_LAUNCHER;
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_ROCKET_LAUNCHER)
Lara.gunStatus = LG_DRAW_GUNS;
return;
}
}
void GuiController::HandleInventoryMenu()
{
int n;
unsigned __int64 opts;
int i;
int ypos;
int num;
if (rings[(int)RingTypes::Ammo]->ringactive)
{
g_Renderer.drawString(phd_centerx, phd_centery, g_GameFlow->GetString(optmessages[5]), PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER);
if (rings[(int)RingTypes::Inventory]->objlistmovement)
return;
if (rings[(int)RingTypes::Ammo]->objlistmovement)
return;
if (goSelect)
{
short invItem = rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->curobjinlist].invitem;
short ammoItem = rings[(int)RingTypes::Ammo]->current_object_list[rings[(int)RingTypes::Ammo]->curobjinlist].invitem;
if (DoObjectsCombine(invItem, ammoItem))
{
combine_ring_fade_dir = 2;
combine_type_flag = 1;
combine_obj1 = invItem;
combine_obj2 = ammoItem;
SoundEffect(SFX_TR4_MENU_COMBINE, 0, SFX_ALWAYS);
}
else if (ammoItem >= INV_OBJECT_SMOL_WATERSKIN && ammoItem <= INV_OBJECT_SMOL_WATERSKIN3L && invItem >= INV_OBJECT_BIG_WATERSKIN && invItem <= INV_OBJECT_BIG_WATERSKIN5L)
{
if (PerformWaterskinCombine(1))
{
combine_type_flag = 2;
combine_ring_fade_dir = 2;
SoundEffect(SFX_TR4_MENU_COMBINE, 0, SFX_ALWAYS);
return;
}
SayNo();
combine_ring_fade_dir = 2;
}
else if (invItem >= INV_OBJECT_SMOL_WATERSKIN && invItem <= INV_OBJECT_SMOL_WATERSKIN3L && ammoItem >= INV_OBJECT_BIG_WATERSKIN && ammoItem <= INV_OBJECT_BIG_WATERSKIN5L)
{
if (PerformWaterskinCombine(0))
{
combine_type_flag = 2;
combine_ring_fade_dir = 2;
SoundEffect(SFX_TR4_MENU_COMBINE, 0, SFX_ALWAYS);
return;
}
SayNo();
combine_ring_fade_dir = 2;
}
else
{
SayNo();
combine_ring_fade_dir = 2;
}
}
if (goDeselect)
{
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
combine_ring_fade_dir = 2;
goDeselect = 0;
}
return;
}
else
{
num = rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->curobjinlist].invitem;
for (n = 0; n < 3; n++)
{
current_options[n].type = MenuType::None;
current_options[n].text = 0;
}
n = 0;
if (!ammo_active)
{
opts = inventry_objects_list[rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->curobjinlist].invitem].opts;
if ((opts & OPT_LOAD))
{
current_options[0].type = MenuType::Load;
current_options[0].text = g_GameFlow->GetString(optmessages[6]);
n = 1;
}
if ((opts & OPT_SAVE))
{
current_options[n].type = MenuType::Save;
current_options[n].text = g_GameFlow->GetString(optmessages[7]);
n++;
}
if ((opts & OPT_EXAMINABLE))
{
current_options[n].type = MenuType::Examine;
current_options[n].text = g_GameFlow->GetString(optmessages[8]);
n++;
}
if ((opts & OPT_STATS))
{
current_options[n].type = MenuType::Statistics;
current_options[n].text = g_GameFlow->GetString(optmessages[9]);
n++;
}
if ((opts & OPT_USE))
{
current_options[n].type = MenuType::Use;
current_options[n].text = g_GameFlow->GetString(optmessages[0]);
n++;
}
if ((opts & OPT_EQUIP))
{
current_options[n].type = MenuType::Equip;
current_options[n].text = g_GameFlow->GetString(optmessages[4]);
n++;
}
if ((opts & (OPT_CHOOSEAMMO_SHOTGUN | OPT_CHOOSEAMMO_CROSSBOW | OPT_CHOOSEAMMO_GRENADEGUN)))
{
current_options[n].type = MenuType::ChooseAmmo;
current_options[n].text = g_GameFlow->GetString(optmessages[1]);
n++;
}
if ((opts & OPT_COMBINABLE))
{
if (IsItemCurrentlyCombinable(num))
{
current_options[n].type = MenuType::Combine;
current_options[n].text = g_GameFlow->GetString(optmessages[2]);
n++;
}
}
if ((opts & OPT_ALWAYSCOMBINE))
{
current_options[n].type = MenuType::Combine;
current_options[n].text = g_GameFlow->GetString(optmessages[2]);
n++;
}
if ((opts & OPT_SEPERATABLE))
{
current_options[n].type = MenuType::Seperate;
current_options[n].text = g_GameFlow->GetString(optmessages[3]);
n++;
}
if (opts & OPT_DIARY)
{
current_options[n].type = MenuType::Diary;
current_options[n].text = g_GameFlow->GetString(optmessages[11]);
n++;
}
}
else
{
current_options[0].type = MenuType::Ammo1;
current_options[0].text = g_GameFlow->GetString(inventry_objects_list[ammo_object_list[0].invitem].objname);
current_options[1].type = MenuType::Ammo2;
current_options[1].text = g_GameFlow->GetString(inventry_objects_list[ammo_object_list[1].invitem].objname);
n = 2;
opts = inventry_objects_list[rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->curobjinlist].invitem].opts;
if (opts & (OPT_CHOOSEAMMO_CROSSBOW | OPT_CHOOSEAMMO_GRENADEGUN))
{
n = 3;
current_options[2].type = MenuType::Ammo3;
current_options[2].text = g_GameFlow->GetString(inventry_objects_list[ammo_object_list[2].invitem].objname);
}
current_selected_option = *current_ammo_type;
}
ypos = 310 - font_height;
if (n == 1)
ypos += font_height;
else if (n == 2)
ypos += font_height >> 1;
if (n > 0)
{
for (i = 0; i < n; i++)
{
if (i == current_selected_option)
{
g_Renderer.drawString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER);
ypos += font_height;
}
else
{
g_Renderer.drawString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_CENTER);
ypos += font_height;
}
}
}
if (menu_active && !rings[(int)RingTypes::Inventory]->objlistmovement && !rings[(int)RingTypes::Ammo]->objlistmovement)
{
if (goUp && current_selected_option > 0)
{
current_selected_option--;
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
}
else if (goDown && current_selected_option < n - 1)
{
current_selected_option++;
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
}
if (ammo_active)
{
if (goLeft && current_selected_option > 0)
{
current_selected_option--;
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
}
if (goRight && current_selected_option < n - 1)
{
current_selected_option++;
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
}
*current_ammo_type = current_selected_option;
}
if (goSelect)
{
if (current_options[current_selected_option].type != MenuType::Equip && current_options[current_selected_option].type != MenuType::Use)
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
switch (current_options[current_selected_option].type)
{
case MenuType::ChooseAmmo:
rings[(int)RingTypes::Inventory]->ringactive = 0;
ammo_active = 1;
Stashedcurrent_selected_option = current_selected_option;
StashedCurrentPistolsAmmoType = CurrentPistolsAmmoType;
StashedCurrentUziAmmoType = CurrentUziAmmoType;
StashedCurrentRevolverAmmoType = CurrentRevolverAmmoType;
StashedCurrentShotGunAmmoType = CurrentShotGunAmmoType;
StashedCurrentGrenadeGunAmmoType = CurrentGrenadeGunAmmoType;
StashedCurrentCrossBowAmmoType = CurrentCrossBowAmmoType;
StashedCurrentHKAmmoType = CurrentHKAmmoType;
StashedCurrentHarpoonAmmoType = CurrentHarpoonAmmoType;
StashedCurrentRocketAmmoType = CurrentRocketAmmoType;
break;
case MenuType::Load:
//fill_up_savegames_array//or maybe not?
invMode = InventoryMode::Load;
break;
case MenuType::Save:
//fill_up_savegames_array
invMode = InventoryMode::Save;
break;
case MenuType::Examine:
invMode = InventoryMode::Examine;
break;
case MenuType::Statistics:
invMode = InventoryMode::Statistics;
break;
case MenuType::Ammo1:
case MenuType::Ammo2:
case MenuType::Ammo3:
ammo_active = 0;
rings[(int)RingTypes::Inventory]->ringactive = 1;
current_selected_option = 0;
break;
case MenuType::Combine:
ConstructCombineObjectList();
rings[(int)RingTypes::Inventory]->ringactive = 0;
rings[(int)RingTypes::Ammo]->ringactive = 1;
ammo_selector_flag = 0;
menu_active = 0;
combine_ring_fade_dir = 1;
break;
case MenuType::Seperate:
seperate_type_flag = 1;
normal_ring_fade_dir = 2;
break;
case MenuType::Equip:
case MenuType::Use:
menu_active = 0;
useItem = 1;
break;
case MenuType::Diary:
invMode = InventoryMode::Diary;
Lara.Diary.currentPage = 1;
break;
}
}
if (goDeselect && ammo_active)
{
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
goDeselect = 0;
ammo_active = 0;
rings[(int)RingTypes::Inventory]->ringactive = 1;
CurrentPistolsAmmoType = StashedCurrentPistolsAmmoType;
CurrentUziAmmoType = StashedCurrentUziAmmoType;
CurrentRevolverAmmoType = StashedCurrentRevolverAmmoType;
CurrentShotGunAmmoType = StashedCurrentShotGunAmmoType;
CurrentGrenadeGunAmmoType = StashedCurrentGrenadeGunAmmoType;
CurrentCrossBowAmmoType = StashedCurrentCrossBowAmmoType;
CurrentHKAmmoType = StashedCurrentHKAmmoType;
CurrentHarpoonAmmoType = StashedCurrentHarpoonAmmoType;
CurrentRocketAmmoType = StashedCurrentRocketAmmoType;
current_selected_option = Stashedcurrent_selected_option;
}
}
}
}
//this function is to UPDATE THE SELECTED AMMO OF WEPS THAT REQUIRE DOING SO, and only these..
void GuiController::UpdateWeaponStatus()
{
if (Lara.Weapons[WEAPON_SHOTGUN].Present)
{
if (CurrentShotGunAmmoType)
Lara.Weapons[WEAPON_SHOTGUN].SelectedAmmo = WEAPON_AMMO2;
else
Lara.Weapons[WEAPON_SHOTGUN].SelectedAmmo = WEAPON_AMMO1;
}
if (Lara.Weapons[WEAPON_CROSSBOW].Present)
{
Lara.Weapons[WEAPON_CROSSBOW].SelectedAmmo = WEAPON_AMMO1;
if (CurrentCrossBowAmmoType == 1)
Lara.Weapons[WEAPON_CROSSBOW].SelectedAmmo = WEAPON_AMMO2;
else if (CurrentCrossBowAmmoType == 2)
Lara.Weapons[WEAPON_CROSSBOW].SelectedAmmo = WEAPON_AMMO3;
}
if (Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Present)
{
Lara.Weapons[WEAPON_GRENADE_LAUNCHER].SelectedAmmo = WEAPON_AMMO1;
if (CurrentGrenadeGunAmmoType == 1)
Lara.Weapons[WEAPON_GRENADE_LAUNCHER].SelectedAmmo = WEAPON_AMMO2;
else if (CurrentGrenadeGunAmmoType == 2)
Lara.Weapons[WEAPON_GRENADE_LAUNCHER].SelectedAmmo = WEAPON_AMMO3;
}
}
void GuiController::SpinBack(unsigned short* angle)
{
unsigned short val;
unsigned short val2;
val = *angle;
if (val)
{
if (val <= 32768)
{
val2 = val;
if (val2 < ANGLE(5))
val = ANGLE(5);
else if (val2 > ANGLE(90))
val2 = ANGLE(90);
val -= (val2 >> 3);
if (val > 32768)
val = 0;
}
else
{
val2 = -val;
if (val2 < ANGLE(5))
val = ANGLE(5);
else if (val2 > ANGLE(90))
val2 = ANGLE(90);
val += (val2 >> 3);
if (val < ANGLE(180))
val = 0;
}
*angle = val;
}
}
void GuiController::DrawAmmoSelector()
{
int n;
int xpos;
unsigned short xrot, yrot, zrot;
InventoryObject* objme;
char invTextBuffer[256];
int x, y;
if (!ammo_selector_flag)
return;
xpos = (2 * phd_centerx - OBJLIST_SPACING) >> 1;
if (num_ammo_slots == 2)
xpos -= OBJLIST_SPACING / 2;
else if (num_ammo_slots == 3)
xpos -= OBJLIST_SPACING;
if (num_ammo_slots > 0)
{
for (n = 0; n < num_ammo_slots; n++)
{
objme = &inventry_objects_list[ammo_object_list[n].invitem];
if (n == *current_ammo_type)
{
if (objme->rot_flags & INV_ROT_X)
ammo_object_list[n].xrot += ANGLE(5);
if (objme->rot_flags & INV_ROT_Y)
ammo_object_list[n].yrot += ANGLE(5);
if (objme->rot_flags & INV_ROT_Z)
ammo_object_list[n].zrot += ANGLE(5);
}
else
{
SpinBack(&ammo_object_list[n].xrot);
SpinBack(&ammo_object_list[n].yrot);
SpinBack(&ammo_object_list[n].zrot);
}
xrot = ammo_object_list[n].xrot;
yrot = ammo_object_list[n].yrot;
zrot = ammo_object_list[n].zrot;
x = phd_centerx - 300 + xpos;
y = 430;
short obj = ConvertInventoryItemToObject(ammo_object_list[n].invitem);
float scaler = inventry_objects_list[ammo_object_list[n].invitem].scale1;
if (n == *current_ammo_type)
{
if (ammo_object_list[n].amount == -1)
sprintf(&invTextBuffer[0], "Unlimited %s", g_GameFlow->GetString(inventry_objects_list[ammo_object_list[n].invitem].objname));
else
sprintf(&invTextBuffer[0], "%d x %s", ammo_object_list[n].amount, g_GameFlow->GetString(inventry_objects_list[ammo_object_list[n].invitem].objname));
if (ammo_selector_fade_val)
g_Renderer.drawString(phd_centerx, 380, &invTextBuffer[0], PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER);
if (n == *current_ammo_type)
g_Renderer.drawObjectOn2DPosition(x, y, obj, xrot, yrot, zrot, scaler);
else
g_Renderer.drawObjectOn2DPosition(x, y, obj, xrot, yrot, zrot, scaler);
}
else
g_Renderer.drawObjectOn2DPosition(x, y, obj, xrot, yrot, zrot, scaler);
xpos += OBJLIST_SPACING;
}
}
}
void GuiController::DrawCurrentObjectList(int ringnum)
{
int n;
int maxobj;
int xoff;
int i;
int shade;
int minobj;
char textbufme[128];
int objmeup;
int nummeup;
short ymeup;
unsigned short xrot, yrot, zrot;
int activenum;
int count;
if (rings[ringnum]->current_object_list <= 0)
return;
if (ringnum == (int)RingTypes::Ammo)
{
ammo_selector_fade_val = 0;
ammo_selector_fade_dir = 0;
if (combine_ring_fade_dir == 1)
{
if (combine_ring_fade_val < 128)
combine_ring_fade_val += 32;
if (combine_ring_fade_val > 128)
{
combine_ring_fade_val = 128;
combine_ring_fade_dir = 0;
}
}
else if (combine_ring_fade_dir == 2)
{
combine_ring_fade_val -= 32;
if (combine_ring_fade_val <= 0)
{
combine_ring_fade_val = 0;
combine_ring_fade_dir = 0;
if (combine_type_flag)
normal_ring_fade_dir = 2;
else
{
rings[(int)RingTypes::Inventory]->ringactive = 1;
menu_active = 1;
rings[(int)RingTypes::Ammo]->ringactive = 0;
HandleObjectChangeover((int)RingTypes::Inventory);
}
rings[(int)RingTypes::Ammo]->ringactive = 0;
}
}
}
else if (normal_ring_fade_dir == 1)
{
if (normal_ring_fade_val < 128)
normal_ring_fade_val += 32;
if (normal_ring_fade_val > 128)
{
normal_ring_fade_val = 128;
normal_ring_fade_dir = 0;
rings[(int)RingTypes::Inventory]->ringactive = 1;
menu_active = 1;
}
}
else if (normal_ring_fade_dir == 2)
{
normal_ring_fade_val -= 32;
if (normal_ring_fade_val <= 0)
{
normal_ring_fade_val = 0;
normal_ring_fade_dir = 1;
if (combine_type_flag == 1)
{
combine_type_flag = 0;
CombineObjects(combine_obj1, combine_obj2);
}
else if (combine_type_flag == 2)
{
combine_type_flag = 0;
ConstructObjectList();
SetupObjectListStartPosition(combine_obj1);
}
else if (seperate_type_flag)
SeparateObject(rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->curobjinlist].invitem);
HandleObjectChangeover((int)RingTypes::Inventory);
}
}
minobj = 0;
maxobj = 0;
xoff = 0;
n = 0;
if (rings[ringnum]->numobjectsinlist != 1)
xoff = (OBJLIST_SPACING * rings[ringnum]->objlistmovement) >> 16;
if (rings[ringnum]->numobjectsinlist == 2)
{
minobj = -1;
maxobj = 0;
n = rings[ringnum]->curobjinlist - 1;
}
if (rings[ringnum]->numobjectsinlist == 3 || rings[ringnum]->numobjectsinlist == 4)
{
minobj = -2;
maxobj = 1;
n = rings[ringnum]->curobjinlist - 2;
}
if (rings[ringnum]->numobjectsinlist >= 5)
{
minobj = -3;
maxobj = 2;
n = rings[ringnum]->curobjinlist - 3;
}
if (n < 0)
n += rings[ringnum]->numobjectsinlist;
if (rings[ringnum]->objlistmovement < 0)
maxobj++;
if (minobj <= maxobj)
{
for (i = minobj; i <= maxobj; i++)
{
if (minobj == i)
{
if (rings[ringnum]->objlistmovement < 0)
shade = 0;
else
shade = rings[ringnum]->objlistmovement >> 9;
}
else if (i != minobj + 1 || maxobj == minobj + 1)
{
if (i != maxobj)
shade = 128;
else
{
if (rings[ringnum]->objlistmovement < 0)
shade = (-128 * rings[ringnum]->objlistmovement) >> 16;
else
shade = 128 - (short)(rings[ringnum]->objlistmovement >> 9);
}
}
else
{
if (rings[ringnum]->objlistmovement < 0)
shade = 128 - ((-128 * rings[ringnum]->objlistmovement) >> 16);
else
shade = 128;
}
if (!minobj && !maxobj)
shade = 128;
if (ringnum == (int)RingTypes::Ammo && combine_ring_fade_val < 128 && shade)
shade = combine_ring_fade_val;
else if (ringnum == (int)RingTypes::Inventory && normal_ring_fade_val < 128 && shade)
shade = normal_ring_fade_val;
if (!i)
{
nummeup = 0;
switch (inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].object_number)
{
case ID_BIGMEDI_ITEM:
nummeup = Lara.NumLargeMedipacks;
break;
case ID_SMALLMEDI_ITEM:
nummeup = Lara.NumSmallMedipacks;
break;
case ID_FLARE_INV_ITEM:
nummeup = Lara.NumFlares;
break;
default:
if (inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].object_number < ID_PUZZLE_ITEM1 ||
inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].object_number > ID_PUZZLE_ITEM16)
{
switch (inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].object_number)
{
case ID_SHOTGUN_AMMO1_ITEM:
count = Lara.Weapons[WEAPON_SHOTGUN].Ammo[WEAPON_AMMO1].getCount();
nummeup = count == -1 ? count : count / 6;
break;
case ID_SHOTGUN_AMMO2_ITEM:
count = Lara.Weapons[WEAPON_SHOTGUN].Ammo[WEAPON_AMMO2].getCount();
nummeup = count == -1 ? count : count / 6;
break;
case ID_HK_AMMO_ITEM:
nummeup = Lara.Weapons[WEAPON_HK].Ammo[WEAPON_AMMO1].getCount();
break;
case ID_CROSSBOW_AMMO1_ITEM:
count = Lara.Weapons[WEAPON_CROSSBOW].Ammo[WEAPON_AMMO1].getCount();
nummeup = count;
break;
case ID_CROSSBOW_AMMO2_ITEM:
count = Lara.Weapons[WEAPON_CROSSBOW].Ammo[WEAPON_AMMO2].getCount();
nummeup = count;
break;
case ID_CROSSBOW_AMMO3_ITEM:
count = Lara.Weapons[WEAPON_CROSSBOW].Ammo[WEAPON_AMMO3].getCount();
nummeup = count;
break;
case ID_GRENADE_AMMO1_ITEM:
count = Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Ammo[WEAPON_AMMO1].getCount();
nummeup = count;
break;
case ID_GRENADE_AMMO2_ITEM:
count = Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Ammo[WEAPON_AMMO2].getCount();
nummeup = count;
break;
case ID_GRENADE_AMMO3_ITEM:
count = Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Ammo[WEAPON_AMMO3].getCount();
nummeup = count;
break;
case ID_ROCKET_LAUNCHER_ITEM:
nummeup = Lara.Weapons[WEAPON_ROCKET_LAUNCHER].Ammo[WEAPON_AMMO1].getCount();
break;
case ID_HARPOON_ITEM:
nummeup = Lara.Weapons[WEAPON_HARPOON_GUN].Ammo[WEAPON_AMMO1].getCount();
break;
case ID_REVOLVER_AMMO_ITEM:
nummeup = Lara.Weapons[WEAPON_REVOLVER].Ammo[WEAPON_AMMO1].getCount();
break;
case ID_UZI_AMMO_ITEM:
nummeup = Lara.Weapons[WEAPON_UZI].Ammo[WEAPON_AMMO1].getCount();
break;
}
}
else
{
nummeup = Lara.Puzzles[inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].object_number - ID_PUZZLE_ITEM1];
if (nummeup <= 1)
sprintf(textbufme, g_GameFlow->GetString(inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].objname));
else
sprintf(textbufme, "%d x %s", nummeup, g_GameFlow->GetString(inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].objname));
}
break;
}
if (inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].object_number < ID_PUZZLE_ITEM1 ||
inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].object_number > ID_PUZZLE_ITEM16)
{
if (nummeup)
{
if (nummeup == -1)
sprintf(textbufme, "Unlimited %s", g_GameFlow->GetString(inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].objname));
else
sprintf(textbufme, "%d x %s", nummeup, g_GameFlow->GetString(inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].objname));
}
else
sprintf(textbufme, g_GameFlow->GetString(inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].objname));
}
if (ringnum == (int)RingTypes::Inventory)
objmeup = (int)(phd_centery - (phd_winymax + 1) * 0.0625 * 3.0);
else
objmeup = (int)((phd_winymax + 1) * 0.0625 * 3.0 + phd_centery);
g_Renderer.drawString(phd_centerx, ringnum == (int)RingTypes::Inventory ? 230 : 300, textbufme, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER);
}
if (!i && !rings[ringnum]->objlistmovement)
{
if (inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].rot_flags & INV_ROT_X)
rings[ringnum]->current_object_list[n].xrot += ANGLE(5);
if (inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].rot_flags & INV_ROT_Y)
rings[ringnum]->current_object_list[n].yrot += ANGLE(5);
if (inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].rot_flags & INV_ROT_Z)
rings[ringnum]->current_object_list[n].zrot += ANGLE(5);
}
else
{
SpinBack(&rings[ringnum]->current_object_list[n].xrot);
SpinBack(&rings[ringnum]->current_object_list[n].yrot);
SpinBack(&rings[ringnum]->current_object_list[n].zrot);
}
xrot = rings[ringnum]->current_object_list[n].xrot;
yrot = rings[ringnum]->current_object_list[n].yrot;
zrot = rings[ringnum]->current_object_list[n].zrot;
if (rings[ringnum]->objlistmovement)
{
if (rings[ringnum]->objlistmovement > 0)
activenum = -1;
else
activenum = 1;
}
else
activenum = 0;
if (i == activenum)
{
if (rings[ringnum]->current_object_list[n].bright < 160)
rings[ringnum]->current_object_list[n].bright += 16;
if (rings[ringnum]->current_object_list[n].bright > 160)
rings[ringnum]->current_object_list[n].bright = 160;
}
else
{
if (rings[ringnum]->current_object_list[n].bright > 32)
rings[ringnum]->current_object_list[n].bright -= 16;
if (rings[ringnum]->current_object_list[n].bright < 32)
rings[ringnum]->current_object_list[n].bright = 32;
}
int x, y, y2;
x = 400 + xoff + i * OBJLIST_SPACING;
y = 150;
y2 = 430;//combine
short obj = ConvertInventoryItemToObject(rings[ringnum]->current_object_list[n].invitem);
float scaler = inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].scale1;
g_Renderer.drawObjectOn2DPosition(x, ringnum == (int)RingTypes::Inventory ? y : y2, obj, xrot, yrot, zrot, scaler);
if (++n >= rings[ringnum]->numobjectsinlist)
n = 0;
}
if (rings[ringnum]->ringactive)
{
if (rings[ringnum]->numobjectsinlist != 1 && (ringnum != 1 || combine_ring_fade_val == 128))
{
if (rings[ringnum]->objlistmovement > 0)
rings[ringnum]->objlistmovement += 8192;
if (rings[ringnum]->objlistmovement < 0)
rings[ringnum]->objlistmovement -= 8192;
if (goLeft)
{
if (!rings[ringnum]->objlistmovement)
{
SoundEffect(SFX_TR4_MENU_ROTATE, 0, SFX_ALWAYS);
rings[ringnum]->objlistmovement += 8192;
if (ammo_selector_flag)
ammo_selector_fade_dir = 2;
}
}
if (goRight)
{
if (!rings[ringnum]->objlistmovement)
{
SoundEffect(SFX_TR4_MENU_ROTATE, 0, SFX_ALWAYS);
rings[ringnum]->objlistmovement -= 8192;
if (ammo_selector_flag)
ammo_selector_fade_dir = 2;
}
}
if (rings[ringnum]->objlistmovement < 65536)
{
if (rings[ringnum]->objlistmovement < -65535)
{
rings[ringnum]->curobjinlist++;
if (rings[ringnum]->curobjinlist >= rings[ringnum]->numobjectsinlist)
rings[ringnum]->curobjinlist = 0;
rings[ringnum]->objlistmovement = 0;
if (ringnum == (int)RingTypes::Inventory)
HandleObjectChangeover(0);
}
}
else
{
rings[ringnum]->curobjinlist--;
if (rings[ringnum]->curobjinlist < 0)
rings[ringnum]->curobjinlist = rings[ringnum]->numobjectsinlist - 1;
rings[ringnum]->objlistmovement = 0;
if (ringnum == (int)RingTypes::Inventory)
HandleObjectChangeover(0);
}
}
}
}
}
int GuiController::CallInventory(bool reset_mode)
{
int return_value;
Lara.oldBusy = Lara.busy;
if (TrInput & IN_SELECT)
stop_killing_me_you_dumb_input_system = 1;
rings[(int)RingTypes::Inventory] = &pcring1;
rings[(int)RingTypes::Ammo] = &pcring2;
g_Renderer.DumpGameScene();
if (reset_mode)
invMode = InventoryMode::InGame;
InitializeInventory();
Camera.numberFrames = 2;
while (true)
{
int val = 0;
OBJLIST_SPACING = phd_centerx >> 1;
if (compassNeedleAngle != 1024)
compassNeedleAngle -= 32;
SetDebounce = true;
S_UpdateInput();
TrInput = InputBusy;
GameTimer++;
if (DbInput & IN_OPTION)
{
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
val = 1;
}
return_value = ThreadEnded;
if (return_value)
return return_value;
DoDebouncedInput();
if (invMode == InventoryMode::Statistics)
DoStatisticsMode();
if (invMode == InventoryMode::Examine)
DoExamineMode();
if (invMode == InventoryMode::Diary)
DoDiary();
if (invMode == InventoryMode::Load)
return_value = DoLoad();
if (invMode == InventoryMode::Save)
DoSave();
DrawInventory();
DrawCompass();
if (useItem && !TrInput)
val = 1;
if (ExitInvLoop)
{
ExitInvLoop = 0;
val = 1;
}
Camera.numberFrames = g_Renderer.SyncRenderer();
if (val)
break;
}
lastInvItem = rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->curobjinlist].invitem;
UpdateWeaponStatus();
if (useItem)
UseCurrentItem();
Lara.busy = Lara.oldBusy;
invMode = InventoryMode::None;
ClearInputVariables(0);
return return_value;
}
void GuiController::DoStatisticsMode()
{
invMode = InventoryMode::Statistics;
if (goDeselect)
{
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
goDeselect = 0;
invMode = InventoryMode::None;
}
}
void GuiController::DoExamineMode()
{
invMode = InventoryMode::Examine;
if (goDeselect)
{
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
goDeselect = 0;
invMode = InventoryMode::None;
}
}
void GuiController::DrawCompass()
{
return;
g_Renderer.drawObjectOn2DPosition(130, 480, ID_COMPASS_ITEM, ANGLE(90), 0, ANGLE(180), inventry_objects_list[INV_OBJECT_COMPASS].scale1);
short compass_speed = phd_sin(compassNeedleAngle - LaraItem->pos.yRot);
short compass_angle = (LaraItem->pos.yRot + compass_speed) - ANGLE(180);
Matrix::CreateRotationY(compass_angle);
}
void GuiController::DoDiary()
{
invMode = InventoryMode::Diary;
if (goRight && Lara.Diary.currentPage < Lara.Diary.numPages)
{
Lara.Diary.currentPage++;
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
}
if (goLeft && Lara.Diary.currentPage > 1)
{
Lara.Diary.currentPage--;
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
}
if (goDeselect)
{
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
goDeselect = 0;
invMode = InventoryMode::None;
}
}
short GuiController::GetLoadSaveSelection()
{
return selected_slot;
}
int GuiController::DoLoad()
{
invMode = InventoryMode::Load;
if (goDown)
{
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
if (selected_slot == SAVEGAME_MAX - 1)
selected_slot -= SAVEGAME_MAX - 1; //go back up
else
selected_slot++;
}
if (goUp)
{
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
if (selected_slot== 0)
selected_slot += SAVEGAME_MAX - 1; //go back down
else
selected_slot--;
}
if (goSelect)
{
if (!SavegameInfos[selected_slot].Present)
SayNo();
else
{
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
g_GameFlow->SelectedSaveGame = selected_slot;
ExitInvLoop = 1;
return 1;
}
}
if (goDeselect)
{
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
goDeselect = 0;
invMode = InventoryMode::InGame;
}
return 0;
}
void GuiController::DoSave()
{
invMode = InventoryMode::Save;
if (goDown)
{
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
if (selected_slot == SAVEGAME_MAX - 1)
selected_slot -= SAVEGAME_MAX - 1; //go back up
else
selected_slot++;
}
if (goUp)
{
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
if (selected_slot == 0)
selected_slot += SAVEGAME_MAX - 1; //go back down
else
selected_slot--;
}
if (goSelect)
{
SoundEffect(SFX_TR4_MENU_CHOOSE, 0, SFX_ALWAYS);
SaveGame::Save(selected_slot);
ExitInvLoop = 1; //exit inv if the user has saved
}
if (goDeselect)
{
SoundEffect(SFX_TR4_MENU_SELECT, 0, SFX_ALWAYS);
goDeselect = 0;
invMode = InventoryMode::InGame;
}
}
void combine_revolver_lasersight(int flag)
{
if (flag)
{
Lara.Lasersight = 1;
Lara.Weapons[WEAPON_REVOLVER].HasLasersight = 0;
}
else
{
Lara.Lasersight = 0;
Lara.Weapons[WEAPON_REVOLVER].HasLasersight = 1;
}
if (Lara.gunStatus && Lara.gunType == WEAPON_REVOLVER)
{
undraw_pistol_mesh_right(WEAPON_REVOLVER);
draw_pistol_meshes(WEAPON_REVOLVER);
}
}
void combine_crossbow_lasersight(int flag)
{
if (flag)
{
Lara.Lasersight = 1;
Lara.Weapons[WEAPON_CROSSBOW].HasLasersight = 0;
}
else
{
Lara.Lasersight = 0;
Lara.Weapons[WEAPON_CROSSBOW].HasLasersight = 1;
}
if (Lara.gunStatus && Lara.gunType == WEAPON_CROSSBOW)
{
undraw_shotgun_meshes(WEAPON_CROSSBOW);
draw_shotgun_meshes(WEAPON_CROSSBOW);
}
}
void combine_HK_SILENCER(int flag)
{
if (flag)
{
Lara.Silencer = 1;
Lara.Weapons[WEAPON_HK].HasSilencer = 0;
}
else
{
Lara.Silencer = 0;
Lara.Weapons[WEAPON_HK].HasSilencer = 1;
}
}
void combine_PuzzleItem1(int flag)
{
Lara.PuzzlesCombo[0] = 0;
Lara.PuzzlesCombo[1] = 0;
Lara.Puzzles[0] = 1;
}
void combine_PuzzleItem2(int flag)
{
Lara.PuzzlesCombo[2] = 0;
Lara.PuzzlesCombo[3] = 0;
Lara.Puzzles[1] = 1;
}
void combine_PuzzleItem3(int flag)
{
Lara.PuzzlesCombo[4] = 0;
Lara.PuzzlesCombo[5] = 0;
Lara.Puzzles[2] = 1;
}
void combine_PuzzleItem4(int flag)
{
Lara.PuzzlesCombo[6] = 0;
Lara.PuzzlesCombo[7] = 0;
Lara.Puzzles[3] = 1;
}
void combine_PuzzleItem5(int flag)
{
Lara.PuzzlesCombo[8] = 0;
Lara.PuzzlesCombo[9] = 0;
Lara.Puzzles[4] = 1;
}
void combine_PuzzleItem6(int flag)
{
Lara.PuzzlesCombo[10] = 0;
Lara.PuzzlesCombo[11] = 0;
Lara.Puzzles[5] = 1;
}
void combine_PuzzleItem7(int flag)
{
Lara.PuzzlesCombo[12] = 0;
Lara.PuzzlesCombo[13] = 0;
Lara.Puzzles[6] = 1;
}
void combine_PuzzleItem8(int flag)
{
Lara.PuzzlesCombo[14] = 0;
Lara.PuzzlesCombo[15] = 0;
Lara.Puzzles[7] = 1;
}
void combine_PuzzleItem9(int flag)
{
Lara.PuzzlesCombo[16] = 0;
Lara.PuzzlesCombo[17] = 0;
Lara.Puzzles[8] = 1;
}
void combine_PuzzleItem10(int flag)
{
Lara.PuzzlesCombo[18] = 0;
Lara.PuzzlesCombo[19] = 0;
Lara.Puzzles[9] = 1;
}
void combine_PuzzleItem11(int flag)
{
Lara.PuzzlesCombo[20] = 0;
Lara.PuzzlesCombo[21] = 0;
Lara.Puzzles[10] = 1;
}
void combine_PuzzleItem12(int flag)
{
Lara.PuzzlesCombo[22] = 0;
Lara.PuzzlesCombo[23] = 0;
Lara.Puzzles[11] = 1;
}
void combine_PuzzleItem13(int flag)
{
Lara.PuzzlesCombo[24] = 0;
Lara.PuzzlesCombo[25] = 0;
Lara.Puzzles[12] = 1;
}
void combine_PuzzleItem14(int flag)
{
Lara.PuzzlesCombo[26] = 0;
Lara.PuzzlesCombo[27] = 0;
Lara.Puzzles[13] = 1;
}
void combine_PuzzleItem15(int flag)
{
Lara.PuzzlesCombo[28] = 0;
Lara.PuzzlesCombo[29] = 0;
Lara.Puzzles[14] = 1;
}
void combine_PuzzleItem16(int flag)
{
Lara.PuzzlesCombo[30] = 0;
Lara.PuzzlesCombo[31] = 0;
Lara.Puzzles[15] = 1;
}
void combine_KeyItem1(int flag)
{
Lara.Keys[0] = 1;
Lara.KeysCombo[0] = 0;
Lara.KeysCombo[1] = 0;
}
void combine_KeyItem2(int flag)
{
Lara.Keys[1] = 1;
Lara.KeysCombo[2] = 0;
Lara.KeysCombo[3] = 0;
}
void combine_KeyItem3(int flag)
{
Lara.Keys[2] = 1;
Lara.KeysCombo[4] = 0;
Lara.KeysCombo[5] = 0;
}
void combine_KeyItem4(int flag)
{
Lara.Keys[3] = 1;
Lara.KeysCombo[6] = 0;
Lara.KeysCombo[7] = 0;
}
void combine_KeyItem5(int flag)
{
Lara.Keys[4] = 1;
Lara.KeysCombo[8] = 0;
Lara.KeysCombo[9] = 0;
}
void combine_KeyItem6(int flag)
{
Lara.Keys[5] = 1;
Lara.KeysCombo[10] = 0;
Lara.KeysCombo[11] = 0;
}
void combine_KeyItem7(int flag)
{
Lara.Keys[6] = 1;
Lara.KeysCombo[12] = 0;
Lara.KeysCombo[13] = 0;
}
void combine_KeyItem8(int flag)
{
Lara.Keys[7] = 1;
Lara.KeysCombo[14] = 0;
Lara.KeysCombo[15] = 0;
}
void combine_KeyItem9(int flag)
{
Lara.Keys[8] = 1;
Lara.KeysCombo[16] = 0;
Lara.KeysCombo[17] = 0;
}
void combine_KeyItem10(int flag)
{
Lara.Keys[9] = 1;
Lara.KeysCombo[18] = 0;
Lara.KeysCombo[19] = 0;
}
void combine_KeyItem11(int flag)
{
Lara.Keys[10] = 1;
Lara.KeysCombo[20] = 0;
Lara.KeysCombo[21] = 0;
}
void combine_KeyItem12(int flag)
{
Lara.Keys[11] = 1;
Lara.KeysCombo[22] = 0;
Lara.KeysCombo[23] = 0;
}
void combine_KeyItem13(int flag)
{
Lara.Keys[12] = 1;
Lara.KeysCombo[24] = 0;
Lara.KeysCombo[25] = 0;
}
void combine_KeyItem14(int flag)
{
Lara.Keys[13] = 1;
Lara.KeysCombo[26] = 0;
Lara.KeysCombo[27] = 0;
}
void combine_KeyItem15(int flag)
{
Lara.Keys[14] = 1;
Lara.KeysCombo[28] = 0;
Lara.KeysCombo[29] = 0;
}
void combine_KeyItem16(int flag)
{
Lara.Keys[15] = 1;
Lara.KeysCombo[30] = 0;
Lara.KeysCombo[31] = 0;
}
void combine_PickupItem1(int flag)
{
Lara.Pickups[0] = 1;
Lara.PickupsCombo[0] = 0;
Lara.PickupsCombo[1] = 0;
}
void combine_PickupItem2(int flag)
{
Lara.Pickups[1] = 1;
Lara.PickupsCombo[2] = 0;
Lara.PickupsCombo[3] = 0;
}
void combine_PickupItem3(int flag)
{
Lara.Pickups[2] = 1;
Lara.PickupsCombo[4] = 0;
Lara.PickupsCombo[5] = 0;
}
void combine_PickupItem4(int flag)
{
Lara.Pickups[3] = 1;
Lara.PickupsCombo[6] = 0;
Lara.PickupsCombo[7] = 0;
}
void combine_PickupItem5(int flag)
{
Lara.Pickups[4] = 1;
Lara.PickupsCombo[8] = 0;
Lara.PickupsCombo[9] = 0;
}
void combine_PickupItem6(int flag)
{
Lara.Pickups[5] = 1;
Lara.PickupsCombo[10] = 0;
Lara.PickupsCombo[11] = 0;
}
void combine_PickupItem7(int flag)
{
Lara.Pickups[6] = 1;
Lara.PickupsCombo[12] = 0;
Lara.PickupsCombo[13] = 0;
}
void combine_PickupItem8(int flag)
{
Lara.Pickups[7] = 1;
Lara.PickupsCombo[14] = 0;
Lara.PickupsCombo[15] = 0;
}
void combine_PickupItem9(int flag)
{
Lara.Pickups[8] = 1;
Lara.PickupsCombo[16] = 0;
Lara.PickupsCombo[17] = 0;
}
void combine_PickupItem10(int flag)
{
Lara.Pickups[9] = 1;
Lara.PickupsCombo[18] = 0;
Lara.PickupsCombo[19] = 0;
}
void combine_PickupItem11(int flag)
{
Lara.Pickups[10] = 1;
Lara.PickupsCombo[20] = 0;
Lara.PickupsCombo[21] = 0;
}
void combine_PickupItem12(int flag)
{
Lara.Pickups[11] = 1;
Lara.PickupsCombo[22] = 0;
Lara.PickupsCombo[23] = 0;
}
void combine_PickupItem13(int flag)
{
Lara.Pickups[12] = 1;
Lara.PickupsCombo[24] = 0;
Lara.PickupsCombo[25] = 0;
}
void combine_PickupItem14(int flag)
{
Lara.Pickups[13] = 1;
Lara.PickupsCombo[26] = 0;
Lara.PickupsCombo[27] = 0;
}
void combine_PickupItem15(int flag)
{
Lara.Pickups[14] = 1;
Lara.PickupsCombo[28] = 0;
Lara.PickupsCombo[29] = 0;
}
void combine_PickupItem16(int flag)
{
Lara.Pickups[15] = 1;
Lara.PickupsCombo[30] = 0;
Lara.PickupsCombo[31] = 0;
}
void combine_Examine1(int flag)
{
Lara.Examines[0] = 1;
Lara.ExaminesCombo[0] = 0;
Lara.ExaminesCombo[1] = 0;
}
void combine_Examine2(int flag)
{
Lara.Examines[1] = 1;
Lara.ExaminesCombo[2] = 0;
Lara.ExaminesCombo[3] = 0;
}
void combine_Examine3(int flag)
{
Lara.Examines[2] = 1;
Lara.ExaminesCombo[4] = 0;
Lara.ExaminesCombo[5] = 0;
}
void combine_Examine4(int flag)
{
Lara.Examines[3] = 1;
Lara.ExaminesCombo[6] = 0;
Lara.ExaminesCombo[7] = 0;
}
void combine_Examine5(int flag)
{
Lara.Examines[4] = 1;
Lara.ExaminesCombo[8] = 0;
Lara.ExaminesCombo[9] = 0;
}
void combine_Examine6(int flag)
{
Lara.Examines[5] = 1;
Lara.ExaminesCombo[10] = 0;
Lara.ExaminesCombo[11] = 0;
}
void combine_Examine7(int flag)
{
Lara.Examines[6] = 1;
Lara.ExaminesCombo[12] = 0;
Lara.ExaminesCombo[13] = 0;
}
void combine_Examine8(int flag)
{
Lara.Examines[7] = 1;
Lara.ExaminesCombo[14] = 0;
Lara.ExaminesCombo[15] = 0;
}
void combine_ClockWorkBeetle(int flag)
{
Lara.hasBeetleThings &= 2;//remove combo1
Lara.hasBeetleThings &= 4;//remove combo2
Lara.hasBeetleThings |= 1;//get beetle
}
bool GuiController::PerformWaterskinCombine(int flag)
{
short small_liters, big_liters, small_capacity, big_capacity;
int i;
small_liters = Lara.small_waterskin - 1;//how many liters in the small one?
big_liters = Lara.big_waterskin - 1;//how many liters in the big one?
small_capacity = 3 - small_liters;//how many more liters can we fit in the small one?
big_capacity = 5 - big_liters;//how many more liters can we fit in the big one?
if (flag)
{
if (Lara.big_waterskin != 1 && small_capacity)//if the big one isn't empty and the small one isn't full
{
i = big_liters;
do
{
if (small_capacity)
{
small_liters++;
small_capacity--;
big_liters--;
}
i--;
} while (i);
Lara.small_waterskin = small_liters + 1;
Lara.big_waterskin = big_liters + 1;
combine_obj1 = (small_liters + 1) + (INV_OBJECT_SMOL_WATERSKIN - 1);
return 1;
}
}
else
{
if (Lara.small_waterskin != 1 && big_capacity)//if the small one isn't empty and the big one isn't full
{
i = Lara.small_waterskin - 1;
do
{
if (big_capacity)
{
big_liters++;
big_capacity--;
small_liters--;
}
i--;
} while (i);
Lara.small_waterskin = small_liters + 1;
Lara.big_waterskin = big_liters + 1;
combine_obj1 = (big_liters + 1) + (INV_OBJECT_BIG_WATERSKIN - 1);
return 1;
}
}
return 0;
}