From c4c2806071aebeb6ff257c0ef46bc0edefc02268 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Thu, 13 Jul 2023 13:04:31 +0300 Subject: [PATCH] Fix game time calculations (#307) --- src/loadsave.cc | 6 ++--- src/map.cc | 4 +-- src/map.h | 2 +- src/pipboy.cc | 8 +++--- src/queue.cc | 70 +++++++++++++++++++------------------------------ src/queue.h | 2 +- src/random.cc | 2 +- src/scripts.cc | 12 +++------ src/scripts.h | 4 +-- src/skill.cc | 2 +- 10 files changed, 45 insertions(+), 67 deletions(-) diff --git a/src/loadsave.cc b/src/loadsave.cc index 4886ba8..645dcab 100644 --- a/src/loadsave.cc +++ b/src/loadsave.cc @@ -130,7 +130,7 @@ typedef struct LoadSaveSlotData { short gameMonth; short gameDay; short gameYear; - int gameTime; + unsigned int gameTime; short elevation; short map; char fileName[16]; @@ -1863,7 +1863,7 @@ static int lsgSaveHeaderInSlot(int slot) return -1; } - if (_db_fwriteLong(_flptr, ptr->gameTime) == -1) { + if (fileWriteUInt32(_flptr, ptr->gameTime) == -1) { return -1; } @@ -1964,7 +1964,7 @@ static int lsgLoadHeaderInSlot(int slot) ptr->gameDay = v8[1]; ptr->gameYear = v8[2]; - if (_db_freadInt(_flptr, &(ptr->gameTime)) == -1) { + if (fileReadUInt32(_flptr, &(ptr->gameTime)) == -1) { return -1; } diff --git a/src/map.cc b/src/map.cc index 4166e60..8b07d6f 100644 --- a/src/map.cc +++ b/src/map.cc @@ -1746,7 +1746,7 @@ static int mapHeaderWrite(MapHeader* ptr, File* stream) if (fileWriteInt32(stream, ptr->darkness) == -1) return -1; if (fileWriteInt32(stream, ptr->globalVariablesCount) == -1) return -1; if (fileWriteInt32(stream, ptr->field_34) == -1) return -1; - if (fileWriteInt32(stream, ptr->lastVisitTime) == -1) return -1; + if (fileWriteUInt32(stream, ptr->lastVisitTime) == -1) return -1; if (fileWriteInt32List(stream, ptr->field_3C, 44) == -1) return -1; return 0; @@ -1766,7 +1766,7 @@ static int mapHeaderRead(MapHeader* ptr, File* stream) if (fileReadInt32(stream, &(ptr->darkness)) == -1) return -1; if (fileReadInt32(stream, &(ptr->globalVariablesCount)) == -1) return -1; if (fileReadInt32(stream, &(ptr->field_34)) == -1) return -1; - if (fileReadInt32(stream, &(ptr->lastVisitTime)) == -1) return -1; + if (fileReadUInt32(stream, &(ptr->lastVisitTime)) == -1) return -1; if (fileReadInt32List(stream, ptr->field_3C, 44) == -1) return -1; return 0; diff --git a/src/map.h b/src/map.h index 0cdebb1..09247f8 100644 --- a/src/map.h +++ b/src/map.h @@ -54,7 +54,7 @@ typedef struct MapHeader { int field_34; // Time in game ticks when PC last visited this map. - int lastVisitTime; + unsigned int lastVisitTime; int field_3C[44]; } MapHeader; diff --git a/src/pipboy.cc b/src/pipboy.cc index 5b58020..45f79db 100644 --- a/src/pipboy.cc +++ b/src/pipboy.cc @@ -1962,7 +1962,7 @@ static bool pipboyRest(int hours, int minutes, int duration) double v2 = v1 * (1.0 / 1440.0) * 3.5 + 0.25; double v3 = (double)minutes / v1 * v2; if (minutes != 0) { - int gameTime = gameTimeGetTime(); + unsigned int gameTime = gameTimeGetTime(); double v4 = v3 * 20.0; int v5 = 0; @@ -2025,7 +2025,7 @@ static bool pipboyRest(int hours, int minutes, int duration) } if (hours != 0 && !rc) { - int gameTime = gameTimeGetTime(); + unsigned int gameTime = gameTimeGetTime(); double v7 = (v2 - v3) * 20.0; for (int hour = 0; hour < (int)v7; hour++) { @@ -2143,9 +2143,7 @@ static bool pipboyRest(int hours, int minutes, int duration) } } - int gameTime = gameTimeGetTime(); - int nextEventGameTime = queueGetNextEventTime(); - if (gameTime > nextEventGameTime) { + if (gameTimeGetTime() > queueGetNextEventTime()) { if (queueProcessEvents()) { debugPrint("PIPBOY: Returning from Queue trigger...\n"); _proc_bail_flag = 1; diff --git a/src/queue.cc b/src/queue.cc index 96d1b62..ab0b54c 100644 --- a/src/queue.cc +++ b/src/queue.cc @@ -18,8 +18,7 @@ namespace fallout { typedef struct QueueListNode { - // TODO: Make unsigned. - int time; + unsigned int time; int type; Object* owner; void* data; @@ -102,7 +101,7 @@ int queueLoad(File* stream) break; } - if (fileReadInt32(stream, &(queueListNode->time)) == -1) { + if (fileReadUInt32(stream, &(queueListNode->time)) == -1) { internal_free(queueListNode); rc = -1; break; @@ -169,27 +168,20 @@ int queueLoad(File* stream) } } - if (oldListHead != NULL) { - QueueListNode** v13 = &gQueueListHead; - QueueListNode* v15; - do { - while (true) { - QueueListNode* v14 = *v13; - if (v14 == NULL) { - break; - } - - if (v14->time > oldListHead->time) { - break; - } - - v13 = &(v14->next); + while (oldListHead != NULL) { + QueueListNode** queueListNodePtr = &gQueueListHead; + while (*queueListNodePtr != NULL) { + if ((*queueListNodePtr)->time > oldListHead->time) { + break; } - v15 = oldListHead->next; - oldListHead->next = *v13; - *v13 = oldListHead; - oldListHead = v15; - } while (v15 != NULL); + + queueListNodePtr = &((*queueListNodePtr)->next); + } + + QueueListNode* next = oldListHead->next; + oldListHead->next = *queueListNodePtr; + *queueListNodePtr = oldListHead; + oldListHead = next; } return rc; @@ -217,7 +209,7 @@ int queueSave(File* stream) Object* object = queueListNode->owner; int objectId = object != NULL ? object->id : -2; - if (fileWriteInt32(stream, queueListNode->time) == -1) { + if (fileWriteUInt32(stream, queueListNode->time) == -1) { return -1; } @@ -250,9 +242,7 @@ int queueAddEvent(int delay, Object* obj, void* data, int eventType) return -1; } - int v1 = gameTimeGetTime(); - int v2 = v1 + delay; - newQueueListNode->time = v2; + newQueueListNode->time = gameTimeGetTime() + delay; newQueueListNode->type = eventType; newQueueListNode->owner = obj; newQueueListNode->data = data; @@ -261,22 +251,18 @@ int queueAddEvent(int delay, Object* obj, void* data, int eventType) obj->flags |= OBJECT_QUEUED; } - QueueListNode** v3 = &gQueueListHead; + QueueListNode** queueListNodePtr = &gQueueListHead; - if (gQueueListHead != NULL) { - QueueListNode* v4; + while (*queueListNodePtr != NULL) { + if (newQueueListNode->time < (*queueListNodePtr)->time) { + break; + } - do { - v4 = *v3; - if (v2 < v4->time) { - break; - } - v3 = &(v4->next); - } while (v4->next != NULL); + queueListNodePtr = &((*queueListNodePtr)->next); } - newQueueListNode->next = *v3; - *v3 = newQueueListNode; + newQueueListNode->next = *queueListNodePtr; + *queueListNodePtr = newQueueListNode; return 0; } @@ -357,7 +343,7 @@ bool queueHasEvent(Object* owner, int eventType) // 0x4A26D0 int queueProcessEvents() { - int time = gameTimeGetTime(); + unsigned int time = gameTimeGetTime(); int v1 = 0; while (gQueueListHead != NULL) { @@ -437,10 +423,8 @@ void _queue_clear_type(int eventType, QueueEventHandler* fn) } } -// TODO: Make unsigned. -// // 0x4A2808 -int queueGetNextEventTime() +unsigned int queueGetNextEventTime() { if (gQueueListHead == NULL) { return 0; diff --git a/src/queue.h b/src/queue.h index d77179e..78b7197 100644 --- a/src/queue.h +++ b/src/queue.h @@ -66,7 +66,7 @@ bool queueHasEvent(Object* owner, int eventType); int queueProcessEvents(); void queueClear(); void _queue_clear_type(int eventType, QueueEventHandler* fn); -int queueGetNextEventTime(); +unsigned int queueGetNextEventTime(); void _queue_leaving_map(); bool queueIsEmpty(); void* queueFindFirstEvent(Object* owner, int eventType); diff --git a/src/random.cc b/src/random.cc index 82f47b3..321e389 100644 --- a/src/random.cc +++ b/src/random.cc @@ -100,7 +100,7 @@ int randomRoll(int difficulty, int criticalSuccessModifier, int* howMuchPtr) // 0x4A3030 static int randomTranslateRoll(int delta, int criticalSuccessModifier) { - int gameTime = gameTimeGetTime(); + unsigned int gameTime = gameTimeGetTime(); // SFALL: Remove criticals time limits. bool criticalsTimeLimitsRemoved = false; diff --git a/src/scripts.cc b/src/scripts.cc index f0d2c60..e517466 100644 --- a/src/scripts.cc +++ b/src/scripts.cc @@ -127,7 +127,7 @@ static int _script_engine_game_mode = 0; // Game time in ticks (1/10 second). // // 0x51C720 -static int gGameTime = 302400; +static unsigned int gGameTime = 302400; // 0x51C724 static const int gGameTimeDaysPerMonth[12] = { @@ -277,12 +277,10 @@ static int gMovieTimerArtimer2; static int gMovieTimerArtimer3; static int gMovieTimerArtimer4; -// TODO: Make unsigned. -// // Returns game time in ticks (1/10 second). // // 0x4A3330 -int gameTimeGetTime() +unsigned int gameTimeGetTime() { return gGameTime; } @@ -351,7 +349,7 @@ char* gameTimeGetTimeString() // TODO: Make unsigned. // // 0x4A347C -void gameTimeSetTime(int time) +void gameTimeSetTime(unsigned int time) { if (time == 0) { time = 1; @@ -775,9 +773,7 @@ static void _script_chk_timed_events() if (v1) { while (!queueIsEmpty()) { - int time = gameTimeGetTime(); - int v2 = queueGetNextEventTime(); - if (time < v2) { + if (gameTimeGetTime() < queueGetNextEventTime()) { break; } diff --git a/src/scripts.h b/src/scripts.h index 0c4b508..e061fd0 100644 --- a/src/scripts.h +++ b/src/scripts.h @@ -147,13 +147,13 @@ typedef struct Script { extern const char* gScriptProcNames[SCRIPT_PROC_COUNT]; -int gameTimeGetTime(); +unsigned int gameTimeGetTime(); void gameTimeGetDate(int* monthPtr, int* dayPtr, int* yearPtr); int gameTimeGetHour(); char* gameTimeGetTimeString(); void gameTimeAddTicks(int a1); void gameTimeAddSeconds(int a1); -void gameTimeSetTime(int time); +void gameTimeSetTime(unsigned int time); int gameTimeScheduleUpdateEvent(); int gameTimeEventProcess(Object* obj, void* data); int _scriptsCheckGameEvents(int* moviePtr, int window); diff --git a/src/skill.cc b/src/skill.cc index 9093068..2ea2a2f 100644 --- a/src/skill.cc +++ b/src/skill.cc @@ -1151,7 +1151,7 @@ static int skillGetFreeUsageSlot(int skill) } } - int time = gameTimeGetTime(); + unsigned int time = gameTimeGetTime(); int hoursSinceLastUsage = (time - _timesSkillUsed[skill][0]) / GAME_TIME_TICKS_PER_HOUR; if (hoursSinceLastUsage <= 24) { return -1;