Fix game time calculations (#307)
This commit is contained in:
parent
fe035d8514
commit
c4c2806071
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
70
src/queue.cc
70
src/queue.cc
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue