Added "firstInput" stat and repurposed the "fileCreatedAt" stat. (#6070)
- The "firstInput" stat is set on first input in game. Used for RTA Timing. - The "fileCreatedAt" stat is now set when then save file is created (After the player is done entering the file name). Useful for seeding non rando randomizers like Mirrorworld, Enemy Randomizer, extraTraps, etc.
This commit is contained in:
@@ -97,6 +97,7 @@ typedef struct {
|
||||
/* */ u32 entrancesDiscovered[SAVEFILE_ENTRANCES_DISCOVERED_IDX_COUNT];
|
||||
/* */ u32 scenesDiscovered[SAVEFILE_SCENES_DISCOVERED_IDX_COUNT];
|
||||
/* */ bool rtaTiming;
|
||||
/* */ uint64_t firstInput;
|
||||
/* */ uint64_t fileCreatedAt;
|
||||
} SohStats;
|
||||
|
||||
|
||||
@@ -299,6 +299,7 @@ void LoadStatsVersion1() {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("rtaTiming", gSaveContext.ship.stats.rtaTiming);
|
||||
SaveManager::Instance->LoadData("firstInput", gSaveContext.ship.stats.firstInput);
|
||||
SaveManager::Instance->LoadData("fileCreatedAt", gSaveContext.ship.stats.fileCreatedAt);
|
||||
SaveManager::Instance->LoadData("playTimer", gSaveContext.ship.stats.playTimer);
|
||||
SaveManager::Instance->LoadData("pauseTimer", gSaveContext.ship.stats.pauseTimer);
|
||||
@@ -348,6 +349,7 @@ void SaveStats(SaveContext* saveContext, int sectionID, bool fullSave) {
|
||||
SaveManager::Instance->SaveData("", saveContext->ship.stats.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->SaveData("rtaTiming", saveContext->ship.stats.rtaTiming);
|
||||
SaveManager::Instance->SaveData("firstInput", saveContext->ship.stats.firstInput);
|
||||
SaveManager::Instance->SaveData("fileCreatedAt", saveContext->ship.stats.fileCreatedAt);
|
||||
SaveManager::Instance->SaveData("playTimer", saveContext->ship.stats.playTimer);
|
||||
SaveManager::Instance->SaveData("pauseTimer", saveContext->ship.stats.pauseTimer);
|
||||
@@ -694,7 +696,8 @@ void InitStats(bool isDebug) {
|
||||
gSaveContext.ship.stats.dungeonKeys[dungeon] = isDebug ? 8 : 0;
|
||||
}
|
||||
gSaveContext.ship.stats.rtaTiming = CVarGetInteger(CVAR_GAMEPLAY_STATS("RTATiming"), 0);
|
||||
gSaveContext.ship.stats.fileCreatedAt = 0;
|
||||
gSaveContext.ship.stats.fileCreatedAt = GetUnixTimestamp();
|
||||
gSaveContext.ship.stats.firstInput = 0;
|
||||
gSaveContext.ship.stats.playTimer = 0;
|
||||
gSaveContext.ship.stats.pauseTimer = 0;
|
||||
for (int timestamp = 0; timestamp < ARRAY_COUNT(gSaveContext.ship.stats.itemTimestamp); timestamp++) {
|
||||
|
||||
@@ -22,9 +22,9 @@ char* GameplayStats_GetCurrentTime();
|
||||
#define GAMEPLAYSTAT_TOTAL_TIME \
|
||||
(gSaveContext.ship.stats.rtaTiming \
|
||||
? (!gSaveContext.ship.stats.gameComplete \
|
||||
? (!gSaveContext.ship.stats.fileCreatedAt \
|
||||
? (!gSaveContext.ship.stats.firstInput \
|
||||
? 0 \
|
||||
: ((GetUnixTimestamp() - gSaveContext.ship.stats.fileCreatedAt) / 100)) \
|
||||
: ((GetUnixTimestamp() - gSaveContext.ship.stats.firstInput) / 100)) \
|
||||
: (gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] \
|
||||
? gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] \
|
||||
: gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED])) \
|
||||
|
||||
@@ -93,12 +93,14 @@ inline void from_json(const json& j, Inventory& inventory) {
|
||||
inline void to_json(json& j, const SohStats& sohStats) {
|
||||
j = json{
|
||||
{ "entrancesDiscovered", sohStats.entrancesDiscovered },
|
||||
{ "firstInput", sohStats.firstInput },
|
||||
{ "fileCreatedAt", sohStats.fileCreatedAt },
|
||||
};
|
||||
}
|
||||
|
||||
inline void from_json(const json& j, SohStats& sohStats) {
|
||||
j.at("entrancesDiscovered").get_to(sohStats.entrancesDiscovered);
|
||||
j.at("firstInput").get_to(sohStats.firstInput);
|
||||
j.at("fileCreatedAt").get_to(sohStats.fileCreatedAt);
|
||||
}
|
||||
|
||||
|
||||
@@ -189,6 +189,7 @@ void Anchor::HandlePacket_UpdateTeamState(nlohmann::json payload) {
|
||||
gSaveContext.gsFlags[i] = loadedData.gsFlags[i];
|
||||
}
|
||||
|
||||
gSaveContext.ship.stats.firstInput = loadedData.ship.stats.firstInput;
|
||||
gSaveContext.ship.stats.fileCreatedAt = loadedData.ship.stats.fileCreatedAt;
|
||||
|
||||
// Restore master sword state
|
||||
|
||||
@@ -1631,6 +1631,7 @@ void SaveManager::LoadBaseVersion2() {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("rtaTiming", gSaveContext.ship.stats.rtaTiming);
|
||||
SaveManager::Instance->LoadData("firstInput", gSaveContext.ship.stats.firstInput);
|
||||
SaveManager::Instance->LoadData("fileCreatedAt", gSaveContext.ship.stats.fileCreatedAt);
|
||||
SaveManager::Instance->LoadData("playTimer", gSaveContext.ship.stats.playTimer);
|
||||
SaveManager::Instance->LoadData("pauseTimer", gSaveContext.ship.stats.pauseTimer);
|
||||
@@ -1848,6 +1849,7 @@ void SaveManager::LoadBaseVersion3() {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.stats.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("rtaTiming", gSaveContext.ship.stats.rtaTiming);
|
||||
SaveManager::Instance->LoadData("firstInput", gSaveContext.ship.stats.firstInput);
|
||||
SaveManager::Instance->LoadData("fileCreatedAt", gSaveContext.ship.stats.fileCreatedAt);
|
||||
SaveManager::Instance->LoadData("playTimer", gSaveContext.ship.stats.playTimer);
|
||||
SaveManager::Instance->LoadData("pauseTimer", gSaveContext.ship.stats.pauseTimer);
|
||||
|
||||
@@ -781,10 +781,10 @@ void Play_Update(PlayState* play) {
|
||||
}
|
||||
|
||||
// Start RTA timing on first non-c-up input after intro cutscene
|
||||
if (!gSaveContext.ship.stats.fileCreatedAt && !Player_InCsMode(play) &&
|
||||
if (!gSaveContext.ship.stats.firstInput && !Player_InCsMode(play) &&
|
||||
((input[0].press.button && input[0].press.button != 0x8) || input[0].rel.stick_x != 0 ||
|
||||
input[0].rel.stick_y != 0)) {
|
||||
gSaveContext.ship.stats.fileCreatedAt = GetUnixTimestamp();
|
||||
gSaveContext.ship.stats.firstInput = GetUnixTimestamp();
|
||||
}
|
||||
}
|
||||
// #endregion
|
||||
|
||||
Reference in New Issue
Block a user