mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 20:58:07 +03:00
parent
c2b005cec5
commit
6e48174a92
11 changed files with 111 additions and 32 deletions
|
@ -22,6 +22,7 @@
|
|||
- changed default pitch of the save/load dialog ingame - it's now higher.
|
||||
- fixed the inability to completely mute the sounds, even at sound volume 0 (#2722)
|
||||
- fixed the final two levels not allowing for secrets to be counted in the statistics (#1582)
|
||||
- fixed assault course best times not being retained between game relaunches (#1578)
|
||||
- fixed Lara's holsters being empty if a game flow level removes all weapons but also re-adds the pistols (#2677)
|
||||
- fixed the console opening when remapping its key (#2641)
|
||||
- fixed the boat when it explodes after crossing mines, where Lara's hips would appear rather than exploded boat parts (#1605)
|
||||
|
|
|
@ -183,6 +183,7 @@ as Notepad.
|
|||
- added waterfalls to the savegame so that they now persist on load
|
||||
- changed inventory to pause the music rather than muting it
|
||||
- fixed killing the T-Rex with a grenade launcher crashing the game
|
||||
- fixed assault course best times not being retained between game relaunches
|
||||
- fixed secret rewards not displaying shotgun ammo
|
||||
- fixed numeric keys interfering with the demos
|
||||
- fixed the ammo counter being hidden while a demo plays in NG+
|
||||
|
|
|
@ -340,3 +340,51 @@ void ConfigFile_WriteEnum(
|
|||
{
|
||||
JSON_ObjectAppendString(obj, name, EnumMap_ToString(enum_name, value));
|
||||
}
|
||||
|
||||
bool ConfigFile_LoadAssaultStats(
|
||||
JSON_OBJECT *const root_obj, ASSAULT_STATS *const assault_stats)
|
||||
{
|
||||
JSON_OBJECT *const stats_obj =
|
||||
JSON_ObjectGetObject(root_obj, "assault_stats");
|
||||
if (stats_obj == nullptr) {
|
||||
return false;
|
||||
}
|
||||
JSON_ARRAY *const entries_arr = JSON_ObjectGetArray(stats_obj, "entries");
|
||||
if (entries_arr != nullptr) {
|
||||
for (size_t i = 0; i < entries_arr->length && i < MAX_ASSAULT_TIMES;
|
||||
i++) {
|
||||
JSON_OBJECT *const entry_obj = JSON_ArrayGetObject(entries_arr, i);
|
||||
if (entry_obj != nullptr) {
|
||||
assault_stats->entries[i].time = JSON_ObjectGetInt(
|
||||
entry_obj, "time", assault_stats->entries[i].time);
|
||||
assault_stats->entries[i].attempt_num = JSON_ObjectGetInt(
|
||||
entry_obj, "attempt_num",
|
||||
assault_stats->entries[i].attempt_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
assault_stats->best_time =
|
||||
JSON_ObjectGetInt(stats_obj, "best_time", assault_stats->best_time);
|
||||
assault_stats->total_attempts = JSON_ObjectGetInt(
|
||||
stats_obj, "total_attempts", assault_stats->total_attempts);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigFile_DumpAssaultStats(
|
||||
JSON_OBJECT *const root_obj, const ASSAULT_STATS *const assault_stats)
|
||||
{
|
||||
JSON_OBJECT *const stats_obj = JSON_ObjectNew();
|
||||
JSON_ARRAY *const entries_arr = JSON_ArrayNew();
|
||||
for (int i = 0; i < MAX_ASSAULT_TIMES; i++) {
|
||||
JSON_OBJECT *const entry_obj = JSON_ObjectNew();
|
||||
JSON_ObjectAppendInt(entry_obj, "time", assault_stats->entries[i].time);
|
||||
JSON_ObjectAppendInt(
|
||||
entry_obj, "attempt_num", assault_stats->entries[i].attempt_num);
|
||||
JSON_ArrayAppendObject(entries_arr, entry_obj);
|
||||
}
|
||||
JSON_ObjectAppendArray(stats_obj, "entries", entries_arr);
|
||||
JSON_ObjectAppendInt(
|
||||
stats_obj, "total_attempts", assault_stats->total_attempts);
|
||||
JSON_ObjectAppendObject(root_obj, "assault_stats", stats_obj);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "config/option.h"
|
||||
#include "enum_map.h"
|
||||
#include "game/gym.h"
|
||||
#include "json.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
@ -25,3 +26,8 @@ int ConfigFile_ReadEnum(
|
|||
const char *enum_name);
|
||||
void ConfigFile_WriteEnum(
|
||||
JSON_OBJECT *obj, const char *name, int value, const char *enum_name);
|
||||
|
||||
bool ConfigFile_LoadAssaultStats(
|
||||
JSON_OBJECT *root_obj, ASSAULT_STATS *assault_stats);
|
||||
bool ConfigFile_DumpAssaultStats(
|
||||
JSON_OBJECT *root_obj, const ASSAULT_STATS *assault_stats);
|
||||
|
|
|
@ -178,6 +178,9 @@ static void M_DumpControllerLayout(
|
|||
void Config_LoadFromJSON(JSON_OBJECT *root_obj)
|
||||
{
|
||||
ConfigFile_LoadOptions(root_obj, Config_GetOptionMap());
|
||||
if (Gym_HasAssaultStats()) {
|
||||
ConfigFile_LoadAssaultStats(root_obj, &g_Config.profile.assault_stats);
|
||||
}
|
||||
|
||||
for (INPUT_LAYOUT layout = INPUT_LAYOUT_CUSTOM_1;
|
||||
layout < INPUT_LAYOUT_NUMBER_OF; layout++) {
|
||||
|
@ -186,13 +189,15 @@ void Config_LoadFromJSON(JSON_OBJECT *root_obj)
|
|||
}
|
||||
|
||||
M_LoadLegacyOptions(root_obj);
|
||||
|
||||
g_Config.loaded = true;
|
||||
}
|
||||
|
||||
void Config_DumpToJSON(JSON_OBJECT *root_obj)
|
||||
{
|
||||
ConfigFile_DumpOptions(root_obj, Config_GetOptionMap());
|
||||
if (Gym_HasAssaultStats()) {
|
||||
ConfigFile_DumpAssaultStats(root_obj, &g_Config.profile.assault_stats);
|
||||
}
|
||||
|
||||
for (INPUT_LAYOUT layout = INPUT_LAYOUT_CUSTOM_1;
|
||||
layout < INPUT_LAYOUT_NUMBER_OF; layout++) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "config/vars.h"
|
||||
#include "debug.h"
|
||||
#include "game/clock.h"
|
||||
#include "game/gym.h"
|
||||
#include "game/input.h"
|
||||
#include "log.h"
|
||||
#include "utils.h"
|
||||
|
@ -111,6 +112,9 @@ static void M_LoadLegacyOptions(JSON_OBJECT *const parent_obj)
|
|||
void Config_LoadFromJSON(JSON_OBJECT *root_obj)
|
||||
{
|
||||
ConfigFile_LoadOptions(root_obj, Config_GetOptionMap());
|
||||
if (Gym_HasAssaultStats()) {
|
||||
ConfigFile_LoadAssaultStats(root_obj, &g_Config.profile.assault_stats);
|
||||
}
|
||||
M_LoadInputConfig(root_obj);
|
||||
M_LoadLegacyOptions(root_obj);
|
||||
g_Config.loaded = true;
|
||||
|
@ -120,6 +124,9 @@ void Config_LoadFromJSON(JSON_OBJECT *root_obj)
|
|||
void Config_DumpToJSON(JSON_OBJECT *root_obj)
|
||||
{
|
||||
ConfigFile_DumpOptions(root_obj, Config_GetOptionMap());
|
||||
if (Gym_HasAssaultStats()) {
|
||||
ConfigFile_DumpAssaultStats(root_obj, &g_Config.profile.assault_stats);
|
||||
}
|
||||
M_DumpInputConfig(root_obj);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "game/gym.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "game/const.h"
|
||||
#include "game/game.h"
|
||||
#include "game/game_flow.h"
|
||||
|
@ -10,16 +11,15 @@
|
|||
static bool m_IsInventoryOpenEnabled = true;
|
||||
static bool m_IsAssaultTimerDisplay = false;
|
||||
static bool m_IsAssaultTimerActive = false;
|
||||
static ASSAULT_STATS m_AssaultStats = { .best_time = -1 };
|
||||
|
||||
static bool M_StoreAssaultTime(uint32_t time);
|
||||
|
||||
static bool M_StoreAssaultTime(const uint32_t time)
|
||||
{
|
||||
ASSAULT_STATS *const assault = &g_Config.profile.assault_stats;
|
||||
int32_t insert_idx = -1;
|
||||
for (int32_t i = 0; i < MAX_ASSAULT_TIMES; i++) {
|
||||
if (m_AssaultStats.entries[i].time == 0
|
||||
|| time < m_AssaultStats.entries[i].time) {
|
||||
if (assault->entries[i].time == 0 || time < assault->entries[i].time) {
|
||||
insert_idx = i;
|
||||
break;
|
||||
}
|
||||
|
@ -29,13 +29,13 @@ static bool M_StoreAssaultTime(const uint32_t time)
|
|||
}
|
||||
|
||||
for (int32_t i = MAX_ASSAULT_TIMES - 1; i > insert_idx; i--) {
|
||||
m_AssaultStats.entries[i] = m_AssaultStats.entries[i - 1];
|
||||
assault->entries[i] = assault->entries[i - 1];
|
||||
}
|
||||
|
||||
m_AssaultStats.total_attempts++;
|
||||
m_AssaultStats.entries[insert_idx].time = time;
|
||||
m_AssaultStats.entries[insert_idx].attempt_num =
|
||||
m_AssaultStats.total_attempts;
|
||||
assault->total_attempts++;
|
||||
assault->entries[insert_idx].time = time;
|
||||
assault->entries[insert_idx].attempt_num = assault->total_attempts;
|
||||
Config_Write();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ bool Gym_IsAssaultTimerActive(void)
|
|||
|
||||
ASSAULT_STATS Gym_GetAssaultStats(void)
|
||||
{
|
||||
return m_AssaultStats;
|
||||
return g_Config.profile.assault_stats;
|
||||
}
|
||||
|
||||
void Gym_ResetAssault(void)
|
||||
|
@ -91,28 +91,28 @@ void Gym_FinishAssault(void)
|
|||
return;
|
||||
}
|
||||
|
||||
ASSAULT_STATS *const assault = &g_Config.profile.assault_stats;
|
||||
const RESUME_INFO *const resume =
|
||||
Savegame_GetCurrentInfo(Game_GetCurrentLevel());
|
||||
M_StoreAssaultTime(resume->stats.timer);
|
||||
|
||||
if (m_AssaultStats.best_time < 0) {
|
||||
if (assault->best_time <= 0) {
|
||||
if (resume->stats.timer < 100 * LOGIC_FPS) {
|
||||
// "Gosh! That was my best time yet!"
|
||||
Music_Play(MX_GYM_HINT_15, MPM_ALWAYS);
|
||||
m_AssaultStats.best_time = resume->stats.timer;
|
||||
assault->best_time = resume->stats.timer;
|
||||
} else {
|
||||
// "Congratulations! You did it! But perhaps I could've been
|
||||
// faster."
|
||||
Music_Play(MX_GYM_HINT_17, MPM_ALWAYS);
|
||||
m_AssaultStats.best_time = 100 * LOGIC_FPS;
|
||||
assault->best_time = 100 * LOGIC_FPS;
|
||||
}
|
||||
} else if (resume->stats.timer < (uint32_t)m_AssaultStats.best_time) {
|
||||
} else if (resume->stats.timer < (uint32_t)assault->best_time) {
|
||||
// "Gosh! That was my best time yet!"
|
||||
Music_Play(MX_GYM_HINT_15, MPM_ALWAYS);
|
||||
m_AssaultStats.best_time = resume->stats.timer;
|
||||
assault->best_time = resume->stats.timer;
|
||||
} else if (
|
||||
resume->stats.timer
|
||||
< (uint32_t)m_AssaultStats.best_time + 5 * LOGIC_FPS) {
|
||||
resume->stats.timer < (uint32_t)assault->best_time + 5 * LOGIC_FPS) {
|
||||
// "Almost. Perhaps another try and I might beat it."
|
||||
Music_Play(MX_GYM_HINT_16, MPM_ALWAYS);
|
||||
} else {
|
||||
|
@ -122,3 +122,8 @@ void Gym_FinishAssault(void)
|
|||
|
||||
m_IsAssaultTimerActive = false;
|
||||
}
|
||||
|
||||
bool Gym_HasAssaultStats(void)
|
||||
{
|
||||
return TR_VERSION >= 2;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "./const.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
MUSIC_LOAD_NEVER,
|
||||
MUSIC_LOAD_NON_AMBIENT,
|
||||
|
@ -11,6 +15,15 @@ typedef enum {
|
|||
UI_STYLE_PC,
|
||||
} UI_STYLE;
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
uint32_t time;
|
||||
uint32_t attempt_num;
|
||||
} entries[MAX_ASSAULT_TIMES];
|
||||
int32_t best_time;
|
||||
uint32_t total_attempts;
|
||||
} ASSAULT_STATS;
|
||||
|
||||
#if TR_VERSION == 1
|
||||
#include "./types_tr1.h"
|
||||
#elif TR_VERSION == 2
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "../game/gym.h"
|
||||
#include "../game/output/types.h"
|
||||
#include "../game/sound/enum.h"
|
||||
#include "../gfx/common.h"
|
||||
#include "../screenshot.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define CONFIG_MIN_BRIGHTNESS 0.1f
|
||||
#define CONFIG_MAX_BRIGHTNESS 2.0f
|
||||
#define CONFIG_MIN_TEXT_SCALE 0.5
|
||||
|
@ -216,5 +215,6 @@ typedef struct {
|
|||
|
||||
struct {
|
||||
bool new_game_plus_unlock;
|
||||
ASSAULT_STATS assault_stats;
|
||||
} profile;
|
||||
} CONFIG;
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "../colors.h"
|
||||
#include "../game/gym.h"
|
||||
#include "../game/input.h"
|
||||
#include "../game/sound/enum.h"
|
||||
#include "../gfx/common.h"
|
||||
#include "../screenshot.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
LIGHTING_CONTRAST_LOW,
|
||||
LIGHTING_CONTRAST_MEDIUM,
|
||||
|
@ -125,5 +124,6 @@ typedef struct {
|
|||
|
||||
struct {
|
||||
bool new_game_plus_unlock;
|
||||
ASSAULT_STATS assault_stats;
|
||||
} profile;
|
||||
} CONFIG;
|
||||
|
|
|
@ -1,25 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "../config/types.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_ASSAULT_TIMES 10
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
uint32_t time;
|
||||
uint32_t attempt_num;
|
||||
} entries[MAX_ASSAULT_TIMES];
|
||||
int32_t best_time;
|
||||
uint32_t total_attempts;
|
||||
} ASSAULT_STATS;
|
||||
|
||||
extern bool Gym_IsAccessible(void);
|
||||
void Gym_SetInventoryOpenEnabled(bool enabled);
|
||||
bool Gym_IsInventoryOpenEnabled(void);
|
||||
|
||||
bool Gym_HasAssaultStats(void);
|
||||
bool Gym_IsAssaultTimerDisplay(void);
|
||||
bool Gym_IsAssaultTimerActive(void);
|
||||
ASSAULT_STATS Gym_GetAssaultStats(void);
|
||||
void Gym_SetAssaultStats(ASSAULT_STATS stats);
|
||||
|
||||
void Gym_ResetAssault(void);
|
||||
void Gym_StartAssault(void);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue