tr1/stats: change the detailed stats option to three modes

Resolves #2658.
The three stat options include:
minimal: kills, pickups, secrets, time
detailed: minimal and max pickup and max kill count
full: detailed and ammo hits/used, health packs used, distance
This commit is contained in:
walkawayy 2025-03-20 19:54:54 -04:00
parent 9424083dd8
commit 66d1b59330
12 changed files with 95 additions and 50 deletions

View file

@ -5,10 +5,11 @@
- added support for `-s`/`--save` argument to immediately start a saved game
- added support for custom levels to use `disable_floor` in the gameflow, similar to TR2's Floating Islands (#2541)
- added drawing of object mesh spheres to the `/debug` console command
- added TR2+ stats if the detailed stats option is enabled (#2561):
- added TR2+ stats if the full stat detail mode option is enabled (#2561):
- ammo hits / used
- health packs used
- distance travelled
- added a TR2+ style bordered stat box to the end of level stats if the full stat detail mode option is enabled (#2658)
- changed the Controls screen to hide the reset and unbind texts when changing a key (#2103)
- changed injections to a new file format with a smaller footprint and improved applicability tests (#1967)
- changed the `/pos` command to show `Demo` and `Cutscene` instead of `Level` when relevant

View file

@ -507,6 +507,7 @@ Not all options are turned on by default. Refer to `TR1X_ConfigTool.exe` for det
- ammo hits / used
- health packs used
- distance travelled
- added an optional TR2+ style bordered stat box to the end of level stats
#### Visuals
- added quadrilateral texture correction

View file

@ -3,7 +3,7 @@ CFG_BOOL(g_Config, gameplay.disable_medpacks, false)
CFG_BOOL(g_Config, gameplay.disable_magnums, false)
CFG_BOOL(g_Config, gameplay.disable_uzis, false)
CFG_BOOL(g_Config, gameplay.disable_shotgun, false)
CFG_BOOL(g_Config, gameplay.enable_detailed_stats, true)
CFG_ENUM(g_Config, gameplay.stat_detail_mode, SDM_FULL, STAT_DETAIL_MODE)
CFG_BOOL(g_Config, gameplay.enable_deaths_counter, true)
CFG_BOOL(g_Config, gameplay.enable_enhanced_look, true)
CFG_BOOL(g_Config, visuals.enable_gun_lighting, true)

View file

@ -99,12 +99,19 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleLevelStats)
if (seq_ctx != GFSC_NORMAL) {
return gf_cmd;
}
#if TR_VERSION == 1
const bool use_bare_style = g_Config.gameplay.stat_detail_mode != SDM_FULL;
#else
const bool use_bare_style = false;
#endif
PHASE *const phase = Phase_Stats_Create((PHASE_STATS_ARGS) {
.background_type =
(TR_VERSION == 1 || Game_IsInGym()) ? BK_TRANSPARENT : BK_OBJECT,
.level_num = -1,
.show_final_stats = false,
.use_bare_style = TR_VERSION == 1,
.use_bare_style = use_bare_style,
});
gf_cmd = PhaseExecutor_Run(phase);
Phase_Stats_Destroy(phase);

View file

@ -63,6 +63,12 @@ typedef enum {
UI_STYLE_PC,
} UI_STYLE;
typedef enum {
SDM_MINIMAL,
SDM_DETAILED,
SDM_FULL,
} STAT_DETAIL_MODE;
typedef struct {
bool loaded;
@ -148,7 +154,7 @@ typedef struct {
bool enable_eidos_logo;
bool enable_loading_screens;
bool enable_cine;
bool enable_detailed_stats;
STAT_DETAIL_MODE stat_detail_mode;
bool enable_walk_to_items;
bool enable_enhanced_saves;
bool enable_jump_twists;

View file

@ -18,7 +18,8 @@
#define ROW_HEIGHT_BARE 25
#define ROW_HEIGHT_BORDERED 18
#define ROW_WIDTH_BORDERED 315
#define ROW_WIDTH_BORDERED 200
#define ROW_WIDTH_BORDERED_FULL 315
typedef enum {
M_ROW_KILLS,
@ -119,8 +120,11 @@ static void M_AddRow(
UI_STACK_LAYOUT_HORIZONTAL, UI_STACK_AUTO_SIZE, row_height);
} else {
row_height = ROW_HEIGHT_BORDERED;
row->stack = UI_Stack_Create(
UI_STACK_LAYOUT_HORIZONTAL, ROW_WIDTH_BORDERED, row_height);
const int32_t row_width = g_Config.gameplay.stat_detail_mode == SDM_FULL
? ROW_WIDTH_BORDERED_FULL
: ROW_WIDTH_BORDERED;
row->stack =
UI_Stack_Create(UI_STACK_LAYOUT_HORIZONTAL, row_width, row_height);
UI_Stack_SetHAlign(row->stack, UI_STACK_H_ALIGN_DISTRIBUTE);
}
@ -144,9 +148,10 @@ static void M_AddRowFromRole(
const STATS_COMMON *const stats, const GAME_INFO *const game_info)
{
char buf[50];
const char *const num_fmt = g_Config.gameplay.enable_detailed_stats
? GS(STATS_DETAIL_FMT)
: GS(STATS_BASIC_FMT);
const char *const num_fmt =
g_Config.gameplay.stat_detail_mode == SDM_MINIMAL
? GS(STATS_BASIC_FMT)
: GS(STATS_DETAIL_FMT);
switch (role) {
case M_ROW_KILLS:
@ -207,36 +212,31 @@ static void M_AddCommonRows(
UI_STATS_DIALOG *const self, const STATS_COMMON *const stats,
const GAME_INFO *const game_info)
{
if (g_Config.gameplay.enable_detailed_stats) {
M_AddRowFromRole(self, M_ROW_TIMER, stats, game_info);
M_AddRowFromRole(self, M_ROW_SECRETS, stats, game_info);
M_AddRowFromRole(self, M_ROW_PICKUPS, stats, game_info);
if (g_Config.gameplay.stat_detail_mode == SDM_MINIMAL) {
M_AddRowFromRole(self, M_ROW_KILLS, stats, game_info);
M_AddRowFromRole(self, M_ROW_AMMO, stats, game_info);
M_AddRowFromRole(self, M_ROW_MEDIPACKS_USED, stats, game_info);
M_AddRowFromRole(self, M_ROW_DISTANCE_TRAVELLED, stats, game_info);
if (g_Config.gameplay.enable_deaths_counter
&& game_info->death_count >= 0) {
// Always use sum of all levels for the deaths.
// Deaths get stored in the resume info for the level they happen
// on, so if the player dies in Vilcabamba and reloads Caves, they
// should still see an incremented death counter.
M_AddRowFromRole(self, M_ROW_DEATHS, stats, game_info);
}
M_AddRowFromRole(self, M_ROW_PICKUPS, stats, game_info);
M_AddRowFromRole(self, M_ROW_SECRETS, stats, game_info);
M_AddRowFromRole(self, M_ROW_TIMER, stats, game_info);
} else {
M_AddRowFromRole(self, M_ROW_KILLS, stats, game_info);
M_AddRowFromRole(self, M_ROW_PICKUPS, stats, game_info);
M_AddRowFromRole(self, M_ROW_SECRETS, stats, game_info);
M_AddRowFromRole(self, M_ROW_TIMER, stats, game_info);
if (g_Config.gameplay.enable_deaths_counter
&& game_info->death_count >= 0) {
// Always use sum of all levels for the deaths.
// Deaths get stored in the resume info for the level they happen
// on, so if the player dies in Vilcabamba and reloads Caves, they
// should still see an incremented death counter.
M_AddRowFromRole(self, M_ROW_DEATHS, stats, game_info);
M_AddRowFromRole(self, M_ROW_SECRETS, stats, game_info);
M_AddRowFromRole(self, M_ROW_PICKUPS, stats, game_info);
M_AddRowFromRole(self, M_ROW_KILLS, stats, game_info);
if (g_Config.gameplay.stat_detail_mode == SDM_FULL) {
M_AddRowFromRole(self, M_ROW_AMMO, stats, game_info);
M_AddRowFromRole(self, M_ROW_MEDIPACKS_USED, stats, game_info);
M_AddRowFromRole(self, M_ROW_DISTANCE_TRAVELLED, stats, game_info);
}
}
if (g_Config.gameplay.enable_deaths_counter
&& game_info->death_count >= 0) {
// Always use sum of all levels for the deaths.
// Deaths get stored in the resume info for the level they happen
// on, so if the player dies in Vilcabamba and reloads Caves, they
// should still see an incremented death counter.
M_AddRowFromRole(self, M_ROW_DEATHS, stats, game_info);
}
}
static void M_AddLevelStatsRows(UI_STATS_DIALOG *const self)

View file

@ -33,3 +33,7 @@ ENUM_MAP_DEFINE(TARGET_LOCK_MODE, TLM_NONE, "no-lock")
ENUM_MAP_DEFINE(MUSIC_LOAD_CONDITION, MUSIC_LOAD_NEVER, "never")
ENUM_MAP_DEFINE(MUSIC_LOAD_CONDITION, MUSIC_LOAD_NON_AMBIENT, "non-ambient")
ENUM_MAP_DEFINE(MUSIC_LOAD_CONDITION, MUSIC_LOAD_ALWAYS, "always")
ENUM_MAP_DEFINE(STAT_DETAIL_MODE, SDM_MINIMAL, "minimal")
ENUM_MAP_DEFINE(STAT_DETAIL_MODE, SDM_DETAILED, "detailed")
ENUM_MAP_DEFINE(STAT_DETAIL_MODE, SDM_FULL, "full")

View file

@ -58,6 +58,11 @@
"never": "Never",
"non-ambient": "Non-ambient",
"always": "Always"
},
"stat_mode": {
"minimal": "Minimal",
"detailed": "Detailed",
"full": "Full"
}
},
"Properties": {
@ -229,9 +234,9 @@
"Title": "Level statistics in compass",
"Description": "Enables showing level statistics when the compass is selected."
},
"enable_detailed_stats": {
"Title": "Show detailed stats",
"Description": "Enables showing the maximum pickup count and kill count on each level, ammo hits, ammo used, health packs used, and distance travelled."
"stat_detail_mode": {
"Title": "Stat detail mode",
"Description": "Allows various levels of stat detail.\n- Minimal: shows kills, pickups, secrets, and time taken.\n- Detailed: shows all stats from minimal as well as the maximum pickup count and kill count of each level.\n- Full: shows all stats from detailed as well as ammo hits, ammo used, health packs used, and distance travelled."
},
"enable_cine": {
"Title": "Enable cutscenes",

View file

@ -69,6 +69,11 @@
"never": "Nunca",
"non-ambient": "No ambiental",
"always": "Siempre"
},
"stat_mode": {
"minimal": "Mínimo",
"detailed": "Detallado",
"full": "Completo"
}
},
"Properties": {
@ -164,9 +169,9 @@
"Title": "Habilitar modo de demostración",
"Description": "Habilita las demostraciones que se muestran en el menú principal."
},
"enable_detailed_stats": {
"Title": "Mostrar total de objetos y muertes",
"Description": "Permite mostrar el recuento máximo de recogidas y muertes en cada nivel, los impactos de munición, la munición utilizada, los paquetes de salud utilizados y la distancia recorrida."
"stat_detail_mode": {
"Title": "Modo de estadísticas detalladas",
"Description": "Permite varios niveles de detalle de estadísticas.\n- Mínimo: muestra muertes, recogidas, secretos y tiempo empleado.\n- Detallado: muestra todas las estadísticas de mínimo así como el recuento máximo de recogidas y muertes de cada nivel.\n- Completo: muestra todas las estadísticas de detailed así como impactos de munición, munición usada, paquetes de salud usados y distancia recorrida."
},
"enemy_healthbar_show_mode": {
"Title": "Mostrar barra de salud enemiga",

View file

@ -69,6 +69,11 @@
"never": "Jamais",
"non-ambient": "Non ambiant",
"always": "Toujours"
},
"stat_mode": {
"minimal": "Minime",
"detailed": "Détaillée",
"full": "Complet"
}
},
"Properties": {
@ -240,9 +245,9 @@
"Title": "Statistiques de niveau dans la boussole",
"Description": "Active l'affichage des statistiques de niveau lorsque la boussole est sélectionnée."
},
"enable_detailed_stats": {
"Title": "Afficher le nombre total de victimes et de collectibles",
"Description": "Permet d'afficher le nombre maximum de ramassages et de tués à chaque niveau, le nombre de munitions, les munitions utilisées, les trousses de santé utilisées et la distance parcourue."
"stat_detail_mode": {
"Title": "Mode détail Stat",
"Description": "Permet différents niveaux de détail des statistiques.\n- Minime: indique les tués, les ramassages, les secrets et le temps passé.\n- Détaillée: indique toutes les statistiques de nu ainsi que le nombre maximum de ramassages et de tués pour chaque niveau.\n- Complet: indique toutes les statistiques de détaillé ainsi que les munitions touchées, les munitions utilisées, les trousses de santé utilisées et la distance parcourue."
},
"enable_cine": {
"Title": "Activer les cutscenes",

View file

@ -69,6 +69,11 @@
"never": "Mai",
"non-ambient": "Non ambientale",
"always": "Sempre"
},
"stat_mode": {
"minimal": "Minimo",
"detailed": "Dettagliato",
"full": "Completo"
}
},
"Properties": {
@ -240,9 +245,9 @@
"Title": "Statistiche del livello nella bussola",
"Description": "Abilita la visualizzazione delle statistiche del livello quando è selezionata la bussola."
},
"enable_detailed_stats": {
"Title": "Mostra il numero totale di uccisioni e oggetti",
"Description": "Consente di visualizzare il numero massimo di prelievi e di uccisioni in ogni livello, i colpi delle munizioni, le munizioni utilizzate, i pacchetti salute utilizzati e la distanza percorsa."
"stat_detail_mode": {
"Title": "Modalità di visualizzazione delle statistiche",
"Description": "Consente di scegliere tra vari livelli di dettaglio per la visualizzazione delle statistiche.\n- Minimo: mostra le uccisioni, gli oggetti raccolti, i segreti e il tempo impiegato per completare il livello.\n- Dettagliato: mostra tutte le statistiche della modalità 'Minimo' e, in aggiunta, il numero massimo di uccisioni e di oggetti recuperabili di ogni livello.\n- Completo: mostra tutte le statistiche della modalità 'Dettagliato' e, in aggiunta, i colpi andati a segno, le munizioni utilizzate, i kit medici adoperati e la distanza percorsa."
},
"enable_cine": {
"Title": "Abilita le scene di intermezzo",

View file

@ -62,6 +62,11 @@
"never",
"non-ambient",
"always"
],
"stat_mode": [
"minimal",
"detailed",
"full"
]
},
"CategorisedProperties": [
@ -303,9 +308,10 @@
"DefaultValue": true
},
{
"Field": "enable_detailed_stats",
"DataType": "Bool",
"DefaultValue": true
"Field": "stat_detail_mode",
"DataType": "Enum",
"EnumKey": "stat_mode",
"DefaultValue": "full"
},
{
"Field": "enable_cine",