Skip to content

Commit

Permalink
gun: add target changing and target lock mode options (#1148)
Browse files Browse the repository at this point in the history
Resolves #1145 and #1146.
  • Loading branch information
walkawayy authored Jan 30, 2024
1 parent e8c7219 commit 1bee557
Show file tree
Hide file tree
Showing 15 changed files with 218 additions and 22 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
## [Unreleased](https://github.com/LostArtefacts/TR1X/compare/stable...develop) - ××××-××-××
- added the option to change weapon targets by tapping the look key like in TR4+ (#1145)
- added three targeting lock options: full lock always keeps target lock (OG), semi lock loses target lock if the enemy dies, and no lock loses target lock if the enemey goes out of sight or dies (TR4+) (#1146)

## [3.1.1](https://github.com/LostArtefacts/TR1X/compare/3.1...3.1.1) - 2024-01-19
- changed quick load to show empty passport instead of opening the save game menu when there are no saves (#1141)
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,11 @@ Not all options are turned on by default. Refer to `TR1X_ConfigTool.exe` for det
- fixed not being able to close level stats with Escape
- fixed Lara jumping forever when alt+tabbing out of the game
- stopped the default controls from functioning when the user unbound them
- added the option to change weapon targets by tapping the look key like in TR4+
- added three targeting lock options:
- full lock: always keep target lock even if the enemy moves out of sight or dies (OG TR1)
- semi lock: keep target lock if the enemy moves out of sight but lose target lock if the enemy dies
- no lock: lose target lock if the enemey goes out of sight or dies (TR4+)

#### Statistics
- added ability to keep timer on in inventory
Expand Down
8 changes: 8 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ typedef enum {
BSM_PS1 = 5,
} BAR_SHOW_MODE;

typedef enum {
TLM_FULL = 0,
TLM_SEMI = 1,
TLM_NONE = 2,
} TARGET_LOCK_MODE;

typedef struct {
bool loaded;

Expand Down Expand Up @@ -127,6 +133,8 @@ typedef struct {
bool enable_uw_roll;
bool enable_buffering;
bool enable_lean_jumping;
bool enable_target_change;
TARGET_LOCK_MODE target_mode;

struct {
int32_t layout;
Expand Down
9 changes: 9 additions & 0 deletions src/config_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ static const CONFIG_OPTION_ENUM_MAP m_BarColors[] = {
{ NULL, -1 },
};

static const CONFIG_OPTION_ENUM_MAP m_TargetLockModes[] = {
{ "full-lock", TLM_FULL },
{ "semi-lock", TLM_SEMI },
{ "no-lock", TLM_NONE },
{ NULL, -1 },
};

static const CONFIG_OPTION_ENUM_MAP m_ScreenshotFormats[] = {
{ "jpg", SCREENSHOT_FORMAT_JPEG },
{ "jpeg", SCREENSHOT_FORMAT_JPEG },
Expand Down Expand Up @@ -108,6 +115,7 @@ const CONFIG_OPTION g_ConfigOptionMap[] = {
{ .name = "enemy_healthbar_color", .type = COT_ENUM, .target = &g_Config.enemy_healthbar_color, .default_value = &(int32_t){BC_GREY}, .param = m_BarColors},
{ .name = "screenshot_format", .type = COT_ENUM, .target = &g_Config.screenshot_format, .default_value = &(int32_t){SCREENSHOT_FORMAT_JPEG}, .param = m_ScreenshotFormats},
{ .name = "menu_style", .type = COT_ENUM, .target = &g_Config.ui.menu_style, .default_value = &(int32_t){UI_STYLE_PC}, .param = m_UIStyles},
{ .name = "target_mode", .type = COT_ENUM, .target = &g_Config.target_mode, .default_value = &(TARGET_LOCK_MODE){TLM_FULL}, .param = m_TargetLockModes},
{ .name = "maximum_save_slots", .type = COT_INT32, .target = &g_Config.maximum_save_slots, .default_value = &(int32_t){25}, 0},
{ .name = "revert_to_pistols", .type = COT_BOOL, .target = &g_Config.revert_to_pistols, .default_value = &(bool){false}, 0},
{ .name = "enable_enhanced_saves", .type = COT_BOOL, .target = &g_Config.enable_enhanced_saves, .default_value = &(bool){true}, 0},
Expand All @@ -128,6 +136,7 @@ const CONFIG_OPTION g_ConfigOptionMap[] = {
{ .name = "enable_uw_roll", .type = COT_BOOL, .target = &g_Config.enable_uw_roll, .default_value = &(bool){true}, 0},
{ .name = "enable_buffering", .type = COT_BOOL, .target = &g_Config.enable_buffering, .default_value = &(bool){false}, 0},
{ .name = "enable_lean_jumping", .type = COT_BOOL, .target = &g_Config.enable_lean_jumping, .default_value = &(bool){false}, 0},
{ .name = "enable_target_change", .type = COT_BOOL, .target = &g_Config.enable_target_change, .default_value = &(bool){true}, 0},
{ .name = "render_mode", .type = COT_INT32, .target = &g_Config.rendering.render_mode, .default_value = &(int32_t){GFX_RM_LEGACY}, 0},
{ .name = "enable_fullscreen", .type = COT_BOOL, .target = &g_Config.rendering.enable_fullscreen, .default_value = &(bool){true}, 0},
{ .name = "enable_maximized", .type = COT_BOOL, .target = &g_Config.rendering.enable_maximized, .default_value = &(bool){true}, 0},
Expand Down
97 changes: 91 additions & 6 deletions src/game/gun/gun_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "config.h"
#include "game/collide.h"
#include "game/effects/blood.h"
#include "game/input.h"
#include "game/inventory.h"
#include "game/items.h"
#include "game/los.h"
Expand Down Expand Up @@ -49,6 +50,9 @@
#define SHOTGUN_RARM_XMIN (-65 * PHD_DEGREE)
#define SHOTGUN_RARM_XMAX (+65 * PHD_DEGREE)

static ITEM_INFO *m_TargetList[NUM_SLOTS];
static ITEM_INFO *m_LastTargetList[NUM_SLOTS];

WEAPON_INFO g_Weapons[NUM_WEAPONS] = {
// null
{
Expand Down Expand Up @@ -195,8 +199,15 @@ void Gun_TargetInfo(WEAPON_INFO *winfo)

void Gun_GetNewTarget(WEAPON_INFO *winfo)
{
ITEM_INFO *bestitem = NULL;
int16_t bestyrot = 0x7FFF;
// Preserve OG targeting behavior.
if (g_Config.target_mode == TLM_FULL && !g_Config.enable_target_change
&& !g_Input.action) {
g_Lara.target = NULL;
}

ITEM_INFO *best_target = NULL;
int16_t best_yrot = 0x7FFF;
int16_t num_targets = 0;

int32_t maxdist = winfo->target_dist;
int32_t maxdist2 = maxdist * maxdist;
Expand Down Expand Up @@ -241,14 +252,85 @@ void Gun_GetNewTarget(WEAPON_INFO *winfo)
&& ang[1] >= winfo->lock_angles[2]
&& ang[1] <= winfo->lock_angles[3]) {
int16_t yrot = ABS(ang[0]);
if (yrot < bestyrot) {
bestyrot = yrot;
bestitem = item;
m_TargetList[num_targets] = item;
num_targets++;
if (yrot < best_yrot) {
best_yrot = yrot;
best_target = item;
}
}
}
m_TargetList[num_targets] = NULL;

if ((g_Config.target_mode == TLM_FULL || g_Config.target_mode == TLM_SEMI)
&& g_Input.action && g_Lara.target) {
Gun_TargetInfo(winfo);
return;
}

if (num_targets > 0) {
for (int slot = 0; slot < NUM_SLOTS; slot++) {
if (!m_TargetList[slot]) {
g_Lara.target = NULL;
}

if (m_TargetList[slot] == g_Lara.target) {
break;
}
}

if (!g_Lara.target) {
g_Lara.target = best_target;
m_LastTargetList[0] = NULL;
}
} else {
g_Lara.target = NULL;
}

if (g_Lara.target != m_LastTargetList[0]) {
for (int slot = NUM_SLOTS - 1; slot > 0; slot--) {
m_LastTargetList[slot] = m_LastTargetList[slot - 1];
}
m_LastTargetList[0] = g_Lara.target;
}

Gun_TargetInfo(winfo);
}

void Gun_ChangeTarget(WEAPON_INFO *winfo)
{
g_Lara.target = NULL;
bool found_new_target = false;

for (int new_target = 0; new_target < NUM_SLOTS; new_target++) {
if (!m_TargetList[new_target]) {
break;
}

for (int last_target = 0; last_target < NUM_SLOTS; last_target++) {
if (!m_LastTargetList[last_target]) {
found_new_target = true;
break;
}

if (m_LastTargetList[last_target] == m_TargetList[new_target]) {
break;
}
}

if (found_new_target) {
g_Lara.target = m_TargetList[new_target];
break;
}
}

if (g_Lara.target != m_LastTargetList[0]) {
for (int last_target = NUM_SLOTS - 1; last_target > 0; last_target--) {
m_LastTargetList[last_target] = m_LastTargetList[last_target - 1];
}
m_LastTargetList[0] = g_Lara.target;
}

g_Lara.target = bestitem;
Gun_TargetInfo(winfo);
}

Expand Down Expand Up @@ -409,6 +491,9 @@ void Gun_HitTarget(ITEM_INFO *item, GAME_VECTOR *hitpos, int16_t damage)
{
if (item->hit_points > 0 && item->hit_points <= damage) {
g_GameInfo.current[g_CurrentLevel].stats.kill_count++;
if (g_Config.target_mode == TLM_SEMI) {
g_Lara.target = NULL;
}
}
Item_TakeDamage(item, damage, true);

Expand Down
1 change: 1 addition & 0 deletions src/game/gun/gun_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern WEAPON_INFO g_Weapons[NUM_WEAPONS];

void Gun_TargetInfo(WEAPON_INFO *winfo);
void Gun_GetNewTarget(WEAPON_INFO *winfo);
void Gun_ChangeTarget(WEAPON_INFO *winfo);
void Gun_FindTargetPoint(ITEM_INFO *item, GAME_VECTOR *target);
void Gun_AimWeapon(WEAPON_INFO *winfo, LARA_ARM *arm);
int32_t Gun_FireWeapon(
Expand Down
12 changes: 5 additions & 7 deletions src/game/gun/gun_pistols.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "game/gun/gun_pistols.h"

#include "config.h"
#include "game/anim.h"
#include "game/gun/gun_misc.h"
#include "game/input.h"
Expand Down Expand Up @@ -159,13 +160,10 @@ void Gun_Pistols_Control(LARA_GUN_TYPE weapon_type)
{
WEAPON_INFO *winfo = &g_Weapons[weapon_type];

if (g_Input.action) {
Gun_TargetInfo(winfo);
} else {
g_Lara.target = NULL;
}
if (!g_Lara.target) {
Gun_GetNewTarget(winfo);
Gun_GetNewTarget(winfo);

if (g_InputDB.change_target && g_Config.enable_target_change) {
Gun_ChangeTarget(winfo);
}

Gun_AimWeapon(winfo, &g_Lara.left_arm);
Expand Down
11 changes: 4 additions & 7 deletions src/game/gun/gun_rifle.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,10 @@ void Gun_Rifle_Control(LARA_GUN_TYPE weapon_type)
{
WEAPON_INFO *winfo = &g_Weapons[LGT_SHOTGUN];

if (g_Input.action) {
Gun_TargetInfo(winfo);
} else {
g_Lara.target = NULL;
}
if (!g_Lara.target) {
Gun_GetNewTarget(winfo);
Gun_GetNewTarget(winfo);

if (g_InputDB.change_target && g_Config.enable_target_change) {
Gun_ChangeTarget(winfo);
}

Gun_AimWeapon(winfo, &g_Lara.left_arm);
Expand Down
29 changes: 29 additions & 0 deletions src/game/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include <stdint.h>

#define LOOK_HOLD_TIME 6
#define LOOK_ENABLED 100
#define DELAY_FRAMES 12
#define HOLD_FRAMES 3

Expand All @@ -17,9 +19,32 @@ static bool m_KeyConflict[INPUT_ROLE_NUMBER_OF] = { false };
static bool m_BtnConflict[INPUT_ROLE_NUMBER_OF] = { false };
static int32_t m_HoldBack = 0;
static int32_t m_HoldForward = 0;
static int32_t m_HoldLook = 0;

static void Input_CheckChangeTarget(INPUT_STATE *input);
static INPUT_STATE Input_GetDebounced(INPUT_STATE input);

static void Input_CheckChangeTarget(INPUT_STATE *input)
{
if (g_Lara.gun_status != LGS_READY) {
return;
}

if (input->look) {
if (m_HoldLook >= LOOK_HOLD_TIME) {
m_HoldLook = LOOK_ENABLED;
} else {
input->look = 0;
m_HoldLook++;
}
} else {
if (m_HoldLook && m_HoldLook != LOOK_ENABLED) {
input->change_target = 1;
}
m_HoldLook = 0;
}
}

static INPUT_STATE Input_GetDebounced(INPUT_STATE input)
{
INPUT_STATE result;
Expand Down Expand Up @@ -141,6 +166,10 @@ void Input_Update(void)
}
}

if (g_Config.enable_target_change) {
Input_CheckChangeTarget(&g_Input);
}

g_InputDB = Input_GetDebounced(g_Input);
}

Expand Down
6 changes: 6 additions & 0 deletions src/game/objects/creatures/natla.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "game/objects/creatures/natla.h"

#include "config.h"
#include "game/creature.h"
#include "game/effects.h"
#include "game/effects/gun.h"
Expand All @@ -14,6 +15,7 @@
#include "math/math.h"

#include <stdbool.h>
#include <stddef.h>

#define NATLA_SHOT_DAMAGE 100
#define NATLA_NEAR_DEATH 200
Expand Down Expand Up @@ -164,6 +166,10 @@ void Natla_Control(int16_t item_num)
item->hit_points = NATLA_NEAR_DEATH;
Music_Play(MX_NATLA_SPEECH);
} else {
if (g_Config.target_mode == TLM_SEMI
|| g_Config.target_mode == TLM_NONE) {
g_Lara.target = NULL;
}
item->hit_points = DONT_TARGET;
}
break;
Expand Down
1 change: 1 addition & 0 deletions src/global/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -2073,6 +2073,7 @@ typedef union INPUT_STATE {
uint64_t menu_right : 1;
uint64_t menu_confirm : 1;
uint64_t menu_back : 1;
uint64_t change_target : 1;
};
} INPUT_STATE;

Expand Down
13 changes: 13 additions & 0 deletions tools/config/TR1X_ConfigTool/Resources/Lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@
"bottom-left": "Bottom left",
"bottom-center": "Bottom center",
"bottom-right": "Bottom right"
},
"target_mode": {
"full-lock": "Full lock",
"semi-lock": "Semi lock",
"no-lock": "No lock"
}
},
"Categories": {
Expand Down Expand Up @@ -107,6 +112,14 @@
"Title": "Underwater roll",
"Description": "Allows Lara to roll while underwater, similar to TR2+."
},
"enable_target_change": {
"Title": "Target change",
"Description": "Enables TR4+ target changing while aiming weapons. Press look while aiming to change targets."
},
"target_mode": {
"Title": "Weapon target lock mode",
"Description": "Changes the behavior of how weapons lock onto targets.\n- Full lock: always keep target lock even if the enemy moves out of sight or dies (OG TR1).\n- Semi lock: keep target lock if the enemy moves out of sight but lose target lock if the enemy dies.\n- No lock: lose target lock if the enemey goes out of sight or dies (TR4+)."
},
"enable_lean_jumping": {
"Title": "Lean jumping",
"Description": "Allows Lara to creep forwards or backwards further when performing neutral jumps with the relevant input key pressed, similar to TR2+."
Expand Down
Loading

0 comments on commit 1bee557

Please sign in to comment.