mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 12:47:58 +03:00
tr2/stats: allow two of each secret type
This allows custom levels to define up to two of each secret type per level, and continue to have statistics accurately captured. Resolves #2674.
This commit is contained in:
parent
46892814fb
commit
5727910c6e
7 changed files with 57 additions and 26 deletions
|
@ -1,5 +1,6 @@
|
|||
## [Unreleased](https://github.com/LostArtefacts/TRX/compare/tr2-0.10...develop) - ××××-××-××
|
||||
- added the bonus level game flow type, which allows for levels to be unlocked if all main game secrets are found (#2668)
|
||||
- added the ability for custom levels to have up to two of each secret type per level (#2674)
|
||||
- fixed the final two levels not allowing for secrets to be counted in the statistics (#1582)
|
||||
- removed the need to specify in the game flow levels that have no secrets (secrets will be automatically counted) (#1582)
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ game with new enhancements and features.
|
|||
- added optional fade effects to the hardware renderer
|
||||
- added text information when changing rendering options at runtime
|
||||
- added support for animated sprites
|
||||
- added the ability for custom levels to have up to two of each secret type per level
|
||||
- changed the hardware renderer to always use 16-bit textures
|
||||
- changed the software renderer to use the picture's palette for the background pictures
|
||||
- changed fullscreen behavior to use windowed desktop mode
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "game/inventory_ring.h"
|
||||
#include "game/items.h"
|
||||
#include "game/objects/vars.h"
|
||||
#include "game/stats.h"
|
||||
#include "global/vars.h"
|
||||
|
||||
#include <libtrx/utils.h>
|
||||
|
@ -212,15 +213,9 @@ bool Inv_AddItem(const GAME_OBJECT_ID obj_id)
|
|||
return true;
|
||||
|
||||
case O_SECRET_1:
|
||||
g_SaveGame.current_stats.secret_flags |= 1;
|
||||
return true;
|
||||
|
||||
case O_SECRET_2:
|
||||
g_SaveGame.current_stats.secret_flags |= 2;
|
||||
return true;
|
||||
|
||||
case O_SECRET_3:
|
||||
g_SaveGame.current_stats.secret_flags |= 4;
|
||||
Stats_MarkSecretCollected(obj_id);
|
||||
return true;
|
||||
|
||||
case O_KEY_ITEM_1:
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "game/output.h"
|
||||
#include "game/overlay.h"
|
||||
#include "game/room.h"
|
||||
#include "game/stats.h"
|
||||
#include "global/vars.h"
|
||||
|
||||
#include <libtrx/config.h>
|
||||
|
@ -82,10 +83,7 @@ static void M_DoPickup(const int16_t item_num)
|
|||
Inv_AddItem(item->object_id);
|
||||
|
||||
if (Object_IsType(item->object_id, g_SecretObjects)
|
||||
&& (g_SaveGame.current_stats.secret_flags & 1)
|
||||
+ ((g_SaveGame.current_stats.secret_flags >> 1) & 1)
|
||||
+ ((g_SaveGame.current_stats.secret_flags >> 2) & 1)
|
||||
>= 3) {
|
||||
&& Stats_CheckAllLevelSecretsCollected()) {
|
||||
GF_InventoryModifier_Apply(Game_GetCurrentLevel(), GF_INV_SECRET);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
static int32_t m_CachedItemCount = 0;
|
||||
static int32_t m_LevelSecrets = 0;
|
||||
|
||||
static bool M_SetSecretFlag(uint8_t *flags, GAME_OBJECT_ID obj_id);
|
||||
|
||||
#if USE_REAL_CLOCK
|
||||
static CLOCK_TIMER m_StartCounter = { .type = CLOCK_TYPE_REAL };
|
||||
static int32_t m_StartTimer = 0;
|
||||
|
@ -38,6 +40,19 @@ void Stats_UpdateTimer(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool M_SetSecretFlag(uint8_t *const flags, const GAME_OBJECT_ID obj_id)
|
||||
{
|
||||
for (int32_t i = 0; i < 2; i++) {
|
||||
const int32_t flag = 1 << ((obj_id - O_SECRET_1) + i * 3);
|
||||
if ((*flags & flag) == 0) {
|
||||
*flags |= flag;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
FINAL_STATS Stats_ComputeFinalStats(GF_LEVEL_TYPE level_type)
|
||||
{
|
||||
FINAL_STATS result = {};
|
||||
|
@ -86,7 +101,7 @@ void Stats_ObserveItemsLoad(void)
|
|||
void Stats_CalculateStats(void)
|
||||
{
|
||||
m_LevelSecrets = 0;
|
||||
int32_t secret_flags = 0;
|
||||
uint8_t secret_flags = 0;
|
||||
|
||||
for (int32_t i = 0; i < m_CachedItemCount; i++) {
|
||||
const ITEM *const item = Item_Get(i);
|
||||
|
@ -95,12 +110,9 @@ void Stats_CalculateStats(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (Object_IsType(item->object_id, g_SecretObjects)) {
|
||||
const int32_t flag = 1 << (item->object_id - O_SECRET_1);
|
||||
if ((secret_flags & flag) == 0) {
|
||||
m_LevelSecrets++;
|
||||
secret_flags |= flag;
|
||||
}
|
||||
if (Object_IsType(item->object_id, g_SecretObjects)
|
||||
&& M_SetSecretFlag(&secret_flags, item->object_id)) {
|
||||
m_LevelSecrets++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,6 +122,23 @@ int32_t Stats_GetSecrets(void)
|
|||
return m_LevelSecrets;
|
||||
}
|
||||
|
||||
void Stats_MarkSecretCollected(const GAME_OBJECT_ID obj_id)
|
||||
{
|
||||
M_SetSecretFlag(&g_SaveGame.current_stats.secret_flags, obj_id);
|
||||
}
|
||||
|
||||
bool Stats_CheckAllLevelSecretsCollected(void)
|
||||
{
|
||||
int32_t flags = g_SaveGame.current_stats.secret_flags;
|
||||
int32_t count = 0;
|
||||
while (flags != 0) {
|
||||
count += flags & 1;
|
||||
flags >>= 1;
|
||||
}
|
||||
|
||||
return count >= g_SaveGame.current_stats.max_secret_count;
|
||||
}
|
||||
|
||||
bool Stats_CheckAllSecretsCollected(GF_LEVEL_TYPE level_type)
|
||||
{
|
||||
const FINAL_STATS stats = Stats_ComputeFinalStats(level_type);
|
||||
|
|
|
@ -9,5 +9,7 @@ void Stats_UpdateTimer(void);
|
|||
void Stats_Reset(void);
|
||||
void Stats_CalculateStats(void);
|
||||
int32_t Stats_GetSecrets(void);
|
||||
void Stats_MarkSecretCollected(GAME_OBJECT_ID obj_id);
|
||||
bool Stats_CheckAllLevelSecretsCollected(void);
|
||||
FINAL_STATS Stats_ComputeFinalStats(GF_LEVEL_TYPE level_type);
|
||||
bool Stats_CheckAllSecretsCollected(GF_LEVEL_TYPE level_type);
|
||||
|
|
|
@ -72,7 +72,7 @@ static void M_AddRowFromRole(
|
|||
UI_STATS_DIALOG *const self, const M_ROW_ROLE role,
|
||||
const STATS_COMMON *const stats)
|
||||
{
|
||||
char buf[32];
|
||||
char buf[64];
|
||||
|
||||
switch (role) {
|
||||
case M_ROW_TIMER: {
|
||||
|
@ -86,15 +86,20 @@ static void M_AddRowFromRole(
|
|||
case M_ROW_LEVEL_SECRETS: {
|
||||
char *ptr = buf;
|
||||
int32_t num_secrets = 0;
|
||||
for (int32_t i = 0; i < 3; i++) {
|
||||
if (((LEVEL_STATS *)stats)->secret_flags & (1 << i)) {
|
||||
sprintf(ptr, "\\{secret %d}", i + 1);
|
||||
num_secrets++;
|
||||
} else {
|
||||
strcpy(ptr, " ");
|
||||
const LEVEL_STATS *const level_stats = (LEVEL_STATS *)stats;
|
||||
for (int32_t i = 1; i >= 0; i--) {
|
||||
for (int32_t j = 0; j < 3; j++) {
|
||||
const int32_t flag = 1 << (j + i * 3);
|
||||
if ((level_stats->secret_flags & flag) != 0) {
|
||||
sprintf(ptr, "\\{secret %d}", j + 1);
|
||||
num_secrets++;
|
||||
} else {
|
||||
strcpy(ptr, " ");
|
||||
}
|
||||
ptr += strlen(ptr);
|
||||
}
|
||||
ptr += strlen(ptr);
|
||||
}
|
||||
|
||||
*ptr++ = '\0';
|
||||
if (num_secrets == 0) {
|
||||
strcpy(buf, GS(MISC_NONE));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue