Fix game time calculations (#307)

This commit is contained in:
Alexander Batalov 2023-07-13 13:04:31 +03:00 committed by GitHub
parent fe035d8514
commit c4c2806071
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 45 additions and 67 deletions

View File

@ -130,7 +130,7 @@ typedef struct LoadSaveSlotData {
short gameMonth; short gameMonth;
short gameDay; short gameDay;
short gameYear; short gameYear;
int gameTime; unsigned int gameTime;
short elevation; short elevation;
short map; short map;
char fileName[16]; char fileName[16];
@ -1863,7 +1863,7 @@ static int lsgSaveHeaderInSlot(int slot)
return -1; return -1;
} }
if (_db_fwriteLong(_flptr, ptr->gameTime) == -1) { if (fileWriteUInt32(_flptr, ptr->gameTime) == -1) {
return -1; return -1;
} }
@ -1964,7 +1964,7 @@ static int lsgLoadHeaderInSlot(int slot)
ptr->gameDay = v8[1]; ptr->gameDay = v8[1];
ptr->gameYear = v8[2]; ptr->gameYear = v8[2];
if (_db_freadInt(_flptr, &(ptr->gameTime)) == -1) { if (fileReadUInt32(_flptr, &(ptr->gameTime)) == -1) {
return -1; return -1;
} }

View File

@ -1746,7 +1746,7 @@ static int mapHeaderWrite(MapHeader* ptr, File* stream)
if (fileWriteInt32(stream, ptr->darkness) == -1) return -1; if (fileWriteInt32(stream, ptr->darkness) == -1) return -1;
if (fileWriteInt32(stream, ptr->globalVariablesCount) == -1) return -1; if (fileWriteInt32(stream, ptr->globalVariablesCount) == -1) return -1;
if (fileWriteInt32(stream, ptr->field_34) == -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; if (fileWriteInt32List(stream, ptr->field_3C, 44) == -1) return -1;
return 0; 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->darkness)) == -1) return -1;
if (fileReadInt32(stream, &(ptr->globalVariablesCount)) == -1) return -1; if (fileReadInt32(stream, &(ptr->globalVariablesCount)) == -1) return -1;
if (fileReadInt32(stream, &(ptr->field_34)) == -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; if (fileReadInt32List(stream, ptr->field_3C, 44) == -1) return -1;
return 0; return 0;

View File

@ -54,7 +54,7 @@ typedef struct MapHeader {
int field_34; int field_34;
// Time in game ticks when PC last visited this map. // Time in game ticks when PC last visited this map.
int lastVisitTime; unsigned int lastVisitTime;
int field_3C[44]; int field_3C[44];
} MapHeader; } MapHeader;

View File

@ -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 v2 = v1 * (1.0 / 1440.0) * 3.5 + 0.25;
double v3 = (double)minutes / v1 * v2; double v3 = (double)minutes / v1 * v2;
if (minutes != 0) { if (minutes != 0) {
int gameTime = gameTimeGetTime(); unsigned int gameTime = gameTimeGetTime();
double v4 = v3 * 20.0; double v4 = v3 * 20.0;
int v5 = 0; int v5 = 0;
@ -2025,7 +2025,7 @@ static bool pipboyRest(int hours, int minutes, int duration)
} }
if (hours != 0 && !rc) { if (hours != 0 && !rc) {
int gameTime = gameTimeGetTime(); unsigned int gameTime = gameTimeGetTime();
double v7 = (v2 - v3) * 20.0; double v7 = (v2 - v3) * 20.0;
for (int hour = 0; hour < (int)v7; hour++) { for (int hour = 0; hour < (int)v7; hour++) {
@ -2143,9 +2143,7 @@ static bool pipboyRest(int hours, int minutes, int duration)
} }
} }
int gameTime = gameTimeGetTime(); if (gameTimeGetTime() > queueGetNextEventTime()) {
int nextEventGameTime = queueGetNextEventTime();
if (gameTime > nextEventGameTime) {
if (queueProcessEvents()) { if (queueProcessEvents()) {
debugPrint("PIPBOY: Returning from Queue trigger...\n"); debugPrint("PIPBOY: Returning from Queue trigger...\n");
_proc_bail_flag = 1; _proc_bail_flag = 1;

View File

@ -18,8 +18,7 @@
namespace fallout { namespace fallout {
typedef struct QueueListNode { typedef struct QueueListNode {
// TODO: Make unsigned. unsigned int time;
int time;
int type; int type;
Object* owner; Object* owner;
void* data; void* data;
@ -102,7 +101,7 @@ int queueLoad(File* stream)
break; break;
} }
if (fileReadInt32(stream, &(queueListNode->time)) == -1) { if (fileReadUInt32(stream, &(queueListNode->time)) == -1) {
internal_free(queueListNode); internal_free(queueListNode);
rc = -1; rc = -1;
break; break;
@ -169,27 +168,20 @@ int queueLoad(File* stream)
} }
} }
if (oldListHead != NULL) { while (oldListHead != NULL) {
QueueListNode** v13 = &gQueueListHead; QueueListNode** queueListNodePtr = &gQueueListHead;
QueueListNode* v15; while (*queueListNodePtr != NULL) {
do { if ((*queueListNodePtr)->time > oldListHead->time) {
while (true) { break;
QueueListNode* v14 = *v13;
if (v14 == NULL) {
break;
}
if (v14->time > oldListHead->time) {
break;
}
v13 = &(v14->next);
} }
v15 = oldListHead->next;
oldListHead->next = *v13; queueListNodePtr = &((*queueListNodePtr)->next);
*v13 = oldListHead; }
oldListHead = v15;
} while (v15 != NULL); QueueListNode* next = oldListHead->next;
oldListHead->next = *queueListNodePtr;
*queueListNodePtr = oldListHead;
oldListHead = next;
} }
return rc; return rc;
@ -217,7 +209,7 @@ int queueSave(File* stream)
Object* object = queueListNode->owner; Object* object = queueListNode->owner;
int objectId = object != NULL ? object->id : -2; int objectId = object != NULL ? object->id : -2;
if (fileWriteInt32(stream, queueListNode->time) == -1) { if (fileWriteUInt32(stream, queueListNode->time) == -1) {
return -1; return -1;
} }
@ -250,9 +242,7 @@ int queueAddEvent(int delay, Object* obj, void* data, int eventType)
return -1; return -1;
} }
int v1 = gameTimeGetTime(); newQueueListNode->time = gameTimeGetTime() + delay;
int v2 = v1 + delay;
newQueueListNode->time = v2;
newQueueListNode->type = eventType; newQueueListNode->type = eventType;
newQueueListNode->owner = obj; newQueueListNode->owner = obj;
newQueueListNode->data = data; newQueueListNode->data = data;
@ -261,22 +251,18 @@ int queueAddEvent(int delay, Object* obj, void* data, int eventType)
obj->flags |= OBJECT_QUEUED; obj->flags |= OBJECT_QUEUED;
} }
QueueListNode** v3 = &gQueueListHead; QueueListNode** queueListNodePtr = &gQueueListHead;
if (gQueueListHead != NULL) { while (*queueListNodePtr != NULL) {
QueueListNode* v4; if (newQueueListNode->time < (*queueListNodePtr)->time) {
break;
}
do { queueListNodePtr = &((*queueListNodePtr)->next);
v4 = *v3;
if (v2 < v4->time) {
break;
}
v3 = &(v4->next);
} while (v4->next != NULL);
} }
newQueueListNode->next = *v3; newQueueListNode->next = *queueListNodePtr;
*v3 = newQueueListNode; *queueListNodePtr = newQueueListNode;
return 0; return 0;
} }
@ -357,7 +343,7 @@ bool queueHasEvent(Object* owner, int eventType)
// 0x4A26D0 // 0x4A26D0
int queueProcessEvents() int queueProcessEvents()
{ {
int time = gameTimeGetTime(); unsigned int time = gameTimeGetTime();
int v1 = 0; int v1 = 0;
while (gQueueListHead != NULL) { while (gQueueListHead != NULL) {
@ -437,10 +423,8 @@ void _queue_clear_type(int eventType, QueueEventHandler* fn)
} }
} }
// TODO: Make unsigned.
//
// 0x4A2808 // 0x4A2808
int queueGetNextEventTime() unsigned int queueGetNextEventTime()
{ {
if (gQueueListHead == NULL) { if (gQueueListHead == NULL) {
return 0; return 0;

View File

@ -66,7 +66,7 @@ bool queueHasEvent(Object* owner, int eventType);
int queueProcessEvents(); int queueProcessEvents();
void queueClear(); void queueClear();
void _queue_clear_type(int eventType, QueueEventHandler* fn); void _queue_clear_type(int eventType, QueueEventHandler* fn);
int queueGetNextEventTime(); unsigned int queueGetNextEventTime();
void _queue_leaving_map(); void _queue_leaving_map();
bool queueIsEmpty(); bool queueIsEmpty();
void* queueFindFirstEvent(Object* owner, int eventType); void* queueFindFirstEvent(Object* owner, int eventType);

View File

@ -100,7 +100,7 @@ int randomRoll(int difficulty, int criticalSuccessModifier, int* howMuchPtr)
// 0x4A3030 // 0x4A3030
static int randomTranslateRoll(int delta, int criticalSuccessModifier) static int randomTranslateRoll(int delta, int criticalSuccessModifier)
{ {
int gameTime = gameTimeGetTime(); unsigned int gameTime = gameTimeGetTime();
// SFALL: Remove criticals time limits. // SFALL: Remove criticals time limits.
bool criticalsTimeLimitsRemoved = false; bool criticalsTimeLimitsRemoved = false;

View File

@ -127,7 +127,7 @@ static int _script_engine_game_mode = 0;
// Game time in ticks (1/10 second). // Game time in ticks (1/10 second).
// //
// 0x51C720 // 0x51C720
static int gGameTime = 302400; static unsigned int gGameTime = 302400;
// 0x51C724 // 0x51C724
static const int gGameTimeDaysPerMonth[12] = { static const int gGameTimeDaysPerMonth[12] = {
@ -277,12 +277,10 @@ static int gMovieTimerArtimer2;
static int gMovieTimerArtimer3; static int gMovieTimerArtimer3;
static int gMovieTimerArtimer4; static int gMovieTimerArtimer4;
// TODO: Make unsigned.
//
// Returns game time in ticks (1/10 second). // Returns game time in ticks (1/10 second).
// //
// 0x4A3330 // 0x4A3330
int gameTimeGetTime() unsigned int gameTimeGetTime()
{ {
return gGameTime; return gGameTime;
} }
@ -351,7 +349,7 @@ char* gameTimeGetTimeString()
// TODO: Make unsigned. // TODO: Make unsigned.
// //
// 0x4A347C // 0x4A347C
void gameTimeSetTime(int time) void gameTimeSetTime(unsigned int time)
{ {
if (time == 0) { if (time == 0) {
time = 1; time = 1;
@ -775,9 +773,7 @@ static void _script_chk_timed_events()
if (v1) { if (v1) {
while (!queueIsEmpty()) { while (!queueIsEmpty()) {
int time = gameTimeGetTime(); if (gameTimeGetTime() < queueGetNextEventTime()) {
int v2 = queueGetNextEventTime();
if (time < v2) {
break; break;
} }

View File

@ -147,13 +147,13 @@ typedef struct Script {
extern const char* gScriptProcNames[SCRIPT_PROC_COUNT]; extern const char* gScriptProcNames[SCRIPT_PROC_COUNT];
int gameTimeGetTime(); unsigned int gameTimeGetTime();
void gameTimeGetDate(int* monthPtr, int* dayPtr, int* yearPtr); void gameTimeGetDate(int* monthPtr, int* dayPtr, int* yearPtr);
int gameTimeGetHour(); int gameTimeGetHour();
char* gameTimeGetTimeString(); char* gameTimeGetTimeString();
void gameTimeAddTicks(int a1); void gameTimeAddTicks(int a1);
void gameTimeAddSeconds(int a1); void gameTimeAddSeconds(int a1);
void gameTimeSetTime(int time); void gameTimeSetTime(unsigned int time);
int gameTimeScheduleUpdateEvent(); int gameTimeScheduleUpdateEvent();
int gameTimeEventProcess(Object* obj, void* data); int gameTimeEventProcess(Object* obj, void* data);
int _scriptsCheckGameEvents(int* moviePtr, int window); int _scriptsCheckGameEvents(int* moviePtr, int window);

View File

@ -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; int hoursSinceLastUsage = (time - _timesSkillUsed[skill][0]) / GAME_TIME_TICKS_PER_HOUR;
if (hoursSinceLastUsage <= 24) { if (hoursSinceLastUsage <= 24) {
return -1; return -1;