mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Refactored world map related code/funcs in main.cpp (from Mr.Stalin)
Fixed TimeLimit option and removed the pointless value of -2 (now it works the same as -3). Fixed the slow mouse cursor on the world map when WorldMapFPSPatch is enabled.
This commit is contained in:
+4
-5
@@ -176,8 +176,7 @@ DebugEditorKey=0
|
||||
;Time limit in years. Must be between -3 and 13
|
||||
;Set to 0 if you want to die the instant you leave arroyo
|
||||
;Set to -1 to remove the time limit, and automatically reset the date back to 2241 each time you would have reached it
|
||||
;Set to -2 to remove the time limit without resetting the date. The game will lock up on 8th of March 2255
|
||||
;Set to -3 to remove the time limit, automatically reset the date, but override Fallout's GetDate function to return the correct year
|
||||
;Set to -2 or -3 to remove the time limit, automatically reset the date, but override Fallout's GetDate function to return the correct year
|
||||
TimeLimit=13
|
||||
|
||||
;World map travel time percentage modifier
|
||||
@@ -185,9 +184,6 @@ TimeLimit=13
|
||||
;100 is normal speed, 0 stops time from passing
|
||||
WorldMapTimeMod=100
|
||||
|
||||
;Set to 1 to enable functions relating to overriding the file system
|
||||
UseFileSystemOverride=0
|
||||
|
||||
;Set to 1 to use the Fallout 1 code to control world map speed
|
||||
WorldMapFPSPatch=1
|
||||
|
||||
@@ -214,6 +210,9 @@ WorldMapSlots=0
|
||||
;To use a config file other than fallout2.cfg, uncomment the next line and add the name of your new file
|
||||
;ConfigFile=
|
||||
|
||||
;Set to 1 to enable functions relating to overriding the file system
|
||||
UseFileSystemOverride=0
|
||||
|
||||
;To use a patch file other than patch000.dat, uncomment the next line and add your new file name
|
||||
;If you want to check for multiple patch files, you can include a %d in the file name (sprintf syntax)
|
||||
;By default, only the first patch file found will be used.
|
||||
|
||||
@@ -166,3 +166,14 @@ struct TProgram
|
||||
long *procTablePtr;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct Queue
|
||||
{
|
||||
DWORD time;
|
||||
long type;
|
||||
TGameObj* object;
|
||||
long data;
|
||||
Queue* next;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
@@ -95,13 +95,13 @@ static void _stdcall SaveGame2() {
|
||||
|
||||
dlog_f("Saving game: %s\n", DL_MAIN, buf);
|
||||
|
||||
DWORD size, unused = 0;
|
||||
DWORD size, data;
|
||||
HANDLE h = CreateFileA(buf, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
|
||||
if (h != INVALID_HANDLE_VALUE) {
|
||||
SaveGlobals(h);
|
||||
WriteFile(h, &objUniqueID, 4, &size, 0); // save unique id counter
|
||||
unused++;
|
||||
WriteFile(h, &unused, 4, &size, 0);
|
||||
data = GetAddedYears(false) << 16; // save to high bytes (short)
|
||||
WriteFile(h, &data, 4, &size, 0);
|
||||
PerksSave(h);
|
||||
SaveArrays(h);
|
||||
CloseHandle(h);
|
||||
@@ -179,12 +179,13 @@ static void _stdcall LoadGame2_Before() {
|
||||
|
||||
HANDLE h = CreateFileA(buf, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
if (h != INVALID_HANDLE_VALUE) {
|
||||
DWORD size, unused;
|
||||
DWORD size, data;
|
||||
LoadGlobals(h);
|
||||
long uID = 0;
|
||||
ReadFile(h, &uID, 4, &size, 0);
|
||||
if (uID > UID_START) objUniqueID = uID;
|
||||
ReadFile(h, &unused, 4, &size, 0);
|
||||
ReadFile(h, &data, 4, &size, 0);
|
||||
SetAddedYears(data >> 16);
|
||||
if (size == 4) {
|
||||
PerksLoad(h);
|
||||
LoadArrays(h);
|
||||
|
||||
+10
-25
@@ -148,37 +148,22 @@ end:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
static void __declspec(naked) GetYear() {
|
||||
|
||||
static void GetYear2() {
|
||||
int year = 0;
|
||||
__asm {
|
||||
push ebx;
|
||||
push ecx;
|
||||
push edx;
|
||||
push edi;
|
||||
mov edi, eax;
|
||||
sub esp, 4;
|
||||
xor eax, eax;
|
||||
xor edx, edx;
|
||||
mov ebx, esp;
|
||||
lea ebx, year;
|
||||
call game_time_date_;
|
||||
mov edx, [esp];
|
||||
mov eax, AddUnarmedStatToGetYear;
|
||||
test eax, eax;
|
||||
jz end;
|
||||
add edx, ds:[_pc_proto + 0x4C];
|
||||
end:
|
||||
mov eax, edi;
|
||||
call interpretPushLong_;
|
||||
mov edx, VAR_TYPE_INT;
|
||||
mov eax, edi;
|
||||
call interpretPushShort_;
|
||||
add esp, 4;
|
||||
pop edi;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
pop ebx;
|
||||
retn;
|
||||
}
|
||||
opHandler.setReturn(year);
|
||||
}
|
||||
|
||||
static void __declspec(naked) GetYear() {
|
||||
_WRAP_OPCODE(GetYear2, 0, 1)
|
||||
}
|
||||
|
||||
static void __declspec(naked) GameLoaded() {
|
||||
__asm {
|
||||
push ebx;
|
||||
|
||||
+193
-112
@@ -114,8 +114,8 @@ static DWORD AddrGetLocalTime;
|
||||
static DWORD ViewportX;
|
||||
static DWORD ViewportY;
|
||||
|
||||
static const DWORD GetDateAddr[] = {
|
||||
0x4392F8, 0x443808, 0x47E127, 0x4975A2, 0x497712, 0x4979C9, 0x4C3CB5,
|
||||
static const DWORD ScrollCityListAddr[] = {
|
||||
0x4C04B9, 0x4C04C8, 0x4C4A34, 0x4C4A3D,
|
||||
};
|
||||
|
||||
static const DWORD FastShotFixF1[] = {
|
||||
@@ -143,57 +143,113 @@ static const DWORD WalkDistanceAddr[] = {
|
||||
0x411FF0, 0x4121C4, 0x412475, 0x412906,
|
||||
};
|
||||
|
||||
static __declspec(naked) void GetDateWrapper() {
|
||||
#define ONE_GAME_YEAR (315360000UL)
|
||||
|
||||
static bool addYear = false; // used as additional years indicator
|
||||
static DWORD addedYears = 0;
|
||||
void SetAddedYears(DWORD years) {
|
||||
addedYears = years;
|
||||
}
|
||||
|
||||
DWORD GetAddedYears(bool isCheck) {
|
||||
return (isCheck && !addYear) ? 0 : addedYears;
|
||||
}
|
||||
|
||||
static __declspec(naked) void TimeDateFix() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push esi;
|
||||
push ebx;
|
||||
call game_time_date_;
|
||||
mov ecx, ds:[_pc_proto + 0x4C];
|
||||
pop esi;
|
||||
test esi, esi;
|
||||
test edi, edi; // year buf
|
||||
jz end;
|
||||
add ecx, [esi];
|
||||
mov [esi], ecx;
|
||||
add esi, addedYears;
|
||||
mov [edi], esi;
|
||||
end:
|
||||
pop esi;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void TimerReset() {
|
||||
*((DWORD*)_fallout_game_time) = 0;
|
||||
*((DWORD*)_pc_proto + 0x4C) += 13;
|
||||
__asm push ecx;
|
||||
|
||||
const DWORD time = ONE_GAME_YEAR * 13;
|
||||
*ptr_fallout_game_time -= time;
|
||||
addedYears += 13;
|
||||
|
||||
// fix queue time
|
||||
Queue* queue = (Queue*)(*ptr_queue);
|
||||
while (queue) {
|
||||
if (queue->time > time) {
|
||||
queue->time -= time;
|
||||
} else {
|
||||
queue->time = 0;
|
||||
}
|
||||
queue = queue->next;
|
||||
}
|
||||
__asm pop ecx;
|
||||
}
|
||||
|
||||
static double TickFrac = 0;
|
||||
static double MapMulti = 1;
|
||||
static double MapMulti2 = 1;
|
||||
void _stdcall SetMapMulti(float d) { MapMulti2 = d; }
|
||||
static __declspec(naked) void PathfinderFix3() {
|
||||
static __declspec(naked) void script_chk_timed_events_hack() {
|
||||
__asm {
|
||||
xor eax, eax;
|
||||
mov eax, dword ptr ds:[_fallout_game_time];
|
||||
inc eax;
|
||||
mov dword ptr ds:[_fallout_game_time], eax;
|
||||
cmp eax, ONE_GAME_YEAR * 13;
|
||||
jae reset;
|
||||
retn;
|
||||
reset:
|
||||
jmp TimerReset;
|
||||
}
|
||||
}
|
||||
|
||||
static __declspec(naked) void set_game_time_hack() {
|
||||
__asm {
|
||||
mov dword ptr ds:[_fallout_game_time], eax;
|
||||
mov edx, eax;
|
||||
call IsMapLoaded;
|
||||
test al, al;
|
||||
jz end;
|
||||
cmp edx, ONE_GAME_YEAR * 13;
|
||||
jb end;
|
||||
call TimerReset;
|
||||
end:
|
||||
xor edx, edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
static DWORD _stdcall PathfinderFix2(DWORD perkLevel, DWORD ticks) {
|
||||
double d = MapMulti * MapMulti2;
|
||||
if (perkLevel == 1) d *= 0.75;
|
||||
else if (perkLevel == 2) d *= 0.5;
|
||||
else if (perkLevel == 3) d *= 0.25;
|
||||
d = ((double)ticks) * d + TickFrac;
|
||||
TickFrac = modf(d, &d);
|
||||
return (DWORD)d;
|
||||
|
||||
static double tickFract = 0.0;
|
||||
static double mapMultiMod = 1.0;
|
||||
static float scriptMapMulti = 1.0;
|
||||
void _stdcall SetMapMulti(float value) {
|
||||
scriptMapMulti = value;
|
||||
}
|
||||
|
||||
static DWORD _stdcall PathfinderCalc(DWORD perkLevel, DWORD ticks) {
|
||||
double multi = mapMultiMod * scriptMapMulti;
|
||||
|
||||
switch (perkLevel) {
|
||||
case 1:
|
||||
multi *= 0.75;
|
||||
break;
|
||||
case 2:
|
||||
multi *= 0.5;
|
||||
break;
|
||||
case 3:
|
||||
multi *= 0.25;
|
||||
break;
|
||||
}
|
||||
multi = ((double)ticks) * multi + tickFract;
|
||||
tickFract = modf(multi, &multi);
|
||||
|
||||
return static_cast<DWORD>(multi);
|
||||
}
|
||||
|
||||
static __declspec(naked) void PathfinderFix() {
|
||||
__asm {
|
||||
push eax;
|
||||
push eax; // ticks
|
||||
mov eax, ds:[_obj_dude];
|
||||
mov edx, PERK_pathfinder;
|
||||
call perk_level_;
|
||||
push eax;
|
||||
call PathfinderFix2;
|
||||
call PathfinderCalc;
|
||||
jmp inc_game_time_;
|
||||
}
|
||||
}
|
||||
@@ -213,39 +269,73 @@ static __declspec(naked) void palette_fade_to_hook() {
|
||||
}
|
||||
|
||||
static int mapSlotsScrollMax = 27 * (17 - 7);
|
||||
static __declspec(naked) void ScrollCityListHook() {
|
||||
static __declspec(naked) void ScrollCityListFix() {
|
||||
__asm {
|
||||
push ebx;
|
||||
mov ebx, ds:[0x672F10];
|
||||
test eax, eax;
|
||||
jl up;
|
||||
cmp ebx, mapSlotsScrollMax;
|
||||
je end;
|
||||
jmp run;
|
||||
pop ebx;
|
||||
jne run;
|
||||
retn;
|
||||
up:
|
||||
test ebx, ebx;
|
||||
jz end;
|
||||
run:
|
||||
call wmInterfaceScrollTabsStart_;
|
||||
end:
|
||||
pop ebx;
|
||||
jnz run;
|
||||
retn;
|
||||
run:
|
||||
jmp wmInterfaceScrollTabsStart_;
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD worldMapDelay;
|
||||
static DWORD worldMapTicks;
|
||||
static DWORD worldMapAdjustDelay = 4;
|
||||
static void __declspec(naked) WorldMapFpsPatch() {
|
||||
__asm {
|
||||
pushadc;
|
||||
push dword ptr ds:[_last_buttons];
|
||||
push dword ptr ds:[0x6AC7B0]; // _mouse_buttons
|
||||
xor ecx, ecx;
|
||||
loopDelay:
|
||||
call process_bk_;
|
||||
dec ecx;
|
||||
jg subLoop; // jmp ecx > -1
|
||||
call RunGlobalScripts3;
|
||||
mov ecx, worldMapDelay;
|
||||
tck:
|
||||
mov eax, ds:[0x50fb08];
|
||||
mov ecx, worldMapAdjustDelay; // adjust invoke frequency
|
||||
subLoop:
|
||||
mov eax, worldMapTicks;
|
||||
call elapsed_time_;
|
||||
cmp eax, ecx;
|
||||
jl tck;
|
||||
cmp eax, 10; // delay
|
||||
jle subLoop;
|
||||
cmp eax, worldMapDelay;
|
||||
jl loopDelay; // elapsed < worldMapDelay
|
||||
|
||||
call get_time_;
|
||||
mov ds:[0x50fb08], eax;
|
||||
mov worldMapTicks, eax;
|
||||
pop dword ptr ds:[0x6AC7B0]; // _mouse_buttons
|
||||
pop dword ptr ds:[_last_buttons];
|
||||
popadc;
|
||||
jmp get_input_;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) WorldMapFpsPatch2() {
|
||||
__asm {
|
||||
pushadc;
|
||||
loopDelay:
|
||||
call RunGlobalScripts3;
|
||||
subLoop:
|
||||
mov eax, worldMapTicks;
|
||||
call elapsed_time_;
|
||||
test eax, eax; // 1 min delay
|
||||
jz subLoop;
|
||||
cmp eax, worldMapDelay;
|
||||
jl loopDelay; // elapsed < worldMapDelay
|
||||
|
||||
call get_time_;
|
||||
mov worldMapTicks, eax;
|
||||
popadc;
|
||||
jmp get_input_;
|
||||
}
|
||||
@@ -315,8 +405,8 @@ end_cppf:
|
||||
}
|
||||
}
|
||||
|
||||
//Only used if the world map speed patch is disabled, so that world map scripts are still run
|
||||
static void __declspec(naked) WorldMapHook() {
|
||||
// Only used if the world map speed patch is disabled, so that world map scripts are still run
|
||||
static void __declspec(naked) wmWorldMap_hook() {
|
||||
__asm {
|
||||
pushadc;
|
||||
call RunGlobalScripts3;
|
||||
@@ -649,8 +739,8 @@ bjmp:
|
||||
}
|
||||
}
|
||||
|
||||
static const DWORD ScannerHookRet=0x41BC1D;
|
||||
static const DWORD ScannerHookFail=0x41BC65;
|
||||
static const DWORD ScannerHookRet = 0x41BC1D;
|
||||
static const DWORD ScannerHookFail = 0x41BC65;
|
||||
static void __declspec(naked) ScannerAutomapHook() {
|
||||
__asm {
|
||||
mov eax, ds:[_obj_dude];
|
||||
@@ -679,26 +769,20 @@ static void __declspec(naked) op_obj_can_see_obj_hook() {
|
||||
|
||||
static void __declspec(naked) wmTownMapFunc_hack() {
|
||||
__asm {
|
||||
cmp edx, 0x31;
|
||||
jl end;
|
||||
cmp edx, ecx;
|
||||
jge end;
|
||||
push edx;
|
||||
sub edx, 0x31;
|
||||
lea eax, ds:0[edx*8];
|
||||
sub eax, edx;
|
||||
pop edx;
|
||||
cmp dword ptr [edi+eax*4+0x0], 0; // Visited
|
||||
cmp dword ptr [edi][eax * 4 + 0], 0; // Visited
|
||||
je end;
|
||||
cmp dword ptr [edi+eax*4+0x4], -1; // Xpos
|
||||
cmp dword ptr [edi][eax * 4 + 4], -1; // Xpos
|
||||
je end;
|
||||
cmp dword ptr [edi+eax*4+0x8], -1; // Ypos
|
||||
cmp dword ptr [edi][eax * 4 + 8], -1; // Ypos
|
||||
je end;
|
||||
// engine code
|
||||
mov edx, [edi][eax * 4 + 0xC];
|
||||
mov [esi], edx
|
||||
retn;
|
||||
end:
|
||||
add esp, 4; // destroy the return address
|
||||
push 0x4C4976;
|
||||
retn;
|
||||
mov eax, 0x4C4976;
|
||||
jmp eax;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -917,17 +1001,16 @@ static void DllMain2() {
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
date = GetPrivateProfileInt("Misc", "LocalMapXLimit", 0, ini);
|
||||
if (date) {
|
||||
tmp = GetPrivateProfileInt("Misc", "LocalMapXLimit", 0, ini);
|
||||
if (tmp) {
|
||||
dlog("Applying local map x limit patch.", DL_INIT);
|
||||
SafeWrite32(0x4B13B9, date);
|
||||
SafeWrite32(0x4B13B9, tmp);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
date = GetPrivateProfileInt("Misc", "LocalMapYLimit", 0, ini);
|
||||
if (date) {
|
||||
tmp = GetPrivateProfileInt("Misc", "LocalMapYLimit", 0, ini);
|
||||
if (tmp) {
|
||||
dlog("Applying local map y limit patch.", DL_INIT);
|
||||
SafeWrite32(0x4B13C7, date);
|
||||
SafeWrite32(0x4B13C7, tmp);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
@@ -951,48 +1034,54 @@ static void DllMain2() {
|
||||
if (ViewportX != -1) {
|
||||
dlog("Applying starting x view patch.", DL_INIT);
|
||||
SafeWrite32(_wmWorldOffsetX, ViewportX);
|
||||
HookCall(0x4BCF07, &ViewportHook);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
ViewportY = GetPrivateProfileInt("Misc", "ViewYPos", -1, ini);
|
||||
if (ViewportY != -1) {
|
||||
dlog("Applying starting y view patch.", DL_INIT);
|
||||
SafeWrite32(_wmWorldOffsetY, ViewportY);
|
||||
if (ViewportX == -1) HookCall(0x4BCF07, &ViewportHook);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
if (ViewportX != -1 || ViewportY != -1) HookCall(0x4BCF07, ViewportHook); // game_reset_
|
||||
|
||||
//if (GetPrivateProfileIntA("Misc", "PathfinderFix", 0, ini)) {
|
||||
dlog("Applying pathfinder patch.", DL_INIT);
|
||||
HookCall(0x4C1FF1, &PathfinderFix3);
|
||||
HookCall(0x4C1C78, &PathfinderFix);
|
||||
MapMulti = (double)GetPrivateProfileIntA("Misc", "WorldMapTimeMod", 100, ini) / 100.0;
|
||||
dlog("Applying Pathfinder patch.", DL_INIT);
|
||||
SafeWrite16(0x4C1FF6, 0x9090); // wmPartyWalkingStep_
|
||||
HookCall(0x4C1C78, PathfinderFix); // wmGameTimeIncrement_
|
||||
mapMultiMod = (double)GetPrivateProfileIntA("Misc", "WorldMapTimeMod", 100, ini) / 100.0;
|
||||
dlogr(" Done", DL_INIT);
|
||||
//}
|
||||
|
||||
bool fpsPatchOK = (*(DWORD*)0x4BFE5E == 0x8D16);
|
||||
if (GetPrivateProfileInt("Misc", "WorldMapFPSPatch", 0, ini)) {
|
||||
dlog("Applying world map fps patch.", DL_INIT);
|
||||
if (*(DWORD*)0x4BFE5E != 0x8D16) {
|
||||
if (!fpsPatchOK) {
|
||||
dlogr(" Failed", DL_INIT);
|
||||
} else {
|
||||
worldMapDelay = GetPrivateProfileInt("Misc", "WorldMapDelay2", 66, ini);
|
||||
HookCall(0x4BFE5D, WorldMapFpsPatch);
|
||||
AvailableGlobalScriptTypes |= 2;
|
||||
int delay = GetPrivateProfileInt("Misc", "WorldMapDelay2", 66, ini);
|
||||
worldMapDelay = max(1, delay);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
} else {
|
||||
if (*(DWORD*)0x4BFE5E == 0x8D16) {
|
||||
HookCall(0x4BFE5D, WorldMapHook);
|
||||
AvailableGlobalScriptTypes |= 2;
|
||||
}
|
||||
if (fpsPatchOK) {
|
||||
void* func;
|
||||
if (worldMapDelay == 0) {
|
||||
func = wmWorldMap_hook;
|
||||
} else if (worldMapDelay > 15) {
|
||||
worldMapAdjustDelay += worldMapDelay / 10;
|
||||
func = WorldMapFpsPatch;
|
||||
} else {
|
||||
func = WorldMapFpsPatch2;
|
||||
}
|
||||
HookCall(0x4BFE5D, func);
|
||||
AvailableGlobalScriptTypes |= 2;
|
||||
}
|
||||
|
||||
if (GetPrivateProfileIntA("Misc", "WorldMapEncounterFix", 0, ini)) {
|
||||
dlog("Applying world map encounter patch.", DL_INIT);
|
||||
WorldMapEncounterRate = GetPrivateProfileIntA("Misc", "WorldMapEncounterRate", 5, ini);
|
||||
SafeWrite32(0x4C232D, 0x01EBC031); // xor eax, eax; jmps 0x4C2332
|
||||
HookCall(0x4BFEE0, &wmWorldMapFunc_hook);
|
||||
HookCall(0x4BFEE0, wmWorldMapFunc_hook);
|
||||
MakeCall(0x4C0667, wmRndEncounterOccurred_hack);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
@@ -1035,10 +1124,9 @@ static void DllMain2() {
|
||||
|
||||
//if (GetPrivateProfileIntA("Misc", "WorldMapCitiesListFix", 0, ini)) {
|
||||
dlog("Applying world map cities list patch.", DL_INIT);
|
||||
HookCall(0x4C04B9, &ScrollCityListHook);
|
||||
HookCall(0x4C04C8, &ScrollCityListHook);
|
||||
HookCall(0x4C4A34, &ScrollCityListHook);
|
||||
HookCall(0x4C4A3D, &ScrollCityListHook);
|
||||
for (int i = 0; i < sizeof(ScrollCityListAddr) / 4; i++) {
|
||||
HookCall(ScrollCityListAddr[i], ScrollCityListFix);
|
||||
}
|
||||
dlogr(" Done", DL_INIT);
|
||||
//}
|
||||
|
||||
@@ -1055,8 +1143,9 @@ static void DllMain2() {
|
||||
dlog("Applying world map slots patch.", DL_INIT);
|
||||
if (tmp < 7) tmp = 7;
|
||||
mapSlotsScrollMax = (tmp - 7) * 27;
|
||||
if (tmp < 25) SafeWrite32(0x4C21FD, 230 - (tmp - 17) * 27);
|
||||
else {
|
||||
if (tmp < 25) {
|
||||
SafeWrite32(0x4C21FD, 230 - (tmp - 17) * 27);
|
||||
} else {
|
||||
SafeWrite8(0x4C21FC, 0xC2);
|
||||
SafeWrite32(0x4C21FD, 2 + 27 * (tmp - 26));
|
||||
}
|
||||
@@ -1064,28 +1153,20 @@ static void DllMain2() {
|
||||
}
|
||||
|
||||
int limit = GetPrivateProfileIntA("Misc", "TimeLimit", 13, ini);
|
||||
if (limit == -2) limit = 14;
|
||||
if (limit == -3) {
|
||||
dlog("Applying time limit patch (-3).", DL_INIT);
|
||||
limit = -1;
|
||||
AddUnarmedStatToGetYear = 1;
|
||||
|
||||
for (int i = 0; i < sizeof(GetDateAddr) / 4; i++) {
|
||||
HookCall(GetDateAddr[i], &GetDateWrapper);
|
||||
if (limit == -2 || limit == -3) {
|
||||
addYear = true;
|
||||
MakeCall(0x4A33B8, TimeDateFix, 1); // game_time_date_
|
||||
limit = -1; // also reset time
|
||||
}
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
if (limit <= 14 && limit >= -1 && limit != 13) {
|
||||
if (limit >= -1 && limit < 13) {
|
||||
dlog("Applying time limit patch.", DL_INIT);
|
||||
if (limit == -1) {
|
||||
HookCall(0x4A34F9, &TimerReset);
|
||||
HookCall(0x4A3551, &TimerReset);
|
||||
|
||||
SafeMemSet(0x4A34EF, 0x90, 10);
|
||||
SafeMemSet(0x4A34FE, 0x90, 6);
|
||||
|
||||
SafeMemSet(0x4A3547, 0x90, 10);
|
||||
SafeMemSet(0x4A3556, 0x90, 6);
|
||||
MakeCall(0x4A3DF5, script_chk_timed_events_hack, 1);
|
||||
MakeCall(0x4A3488, set_game_time_hack);
|
||||
MakeCall(0x4A34EF, TimerReset); // inc_game_time_
|
||||
MakeCall(0x4A3547, TimerReset); // inc_game_time_in_seconds_
|
||||
SafeMemSet(0x4A34F4, 0x90, 16);
|
||||
SafeMemSet(0x4A354C, 0x90, 16);
|
||||
} else {
|
||||
SafeWrite8(0x4A34EC, limit);
|
||||
SafeWrite8(0x4A3544, limit);
|
||||
@@ -1441,7 +1522,7 @@ static void DllMain2() {
|
||||
|
||||
if (GetPrivateProfileIntA("Misc", "TownMapHotkeysFix", 1, ini)) {
|
||||
dlog("Applying town map hotkeys patch.", DL_INIT);
|
||||
MakeCall(0x4C4945, wmTownMapFunc_hack);
|
||||
MakeCall(0x4C495A, wmTownMapFunc_hack, 1);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -70,9 +70,11 @@ extern DWORD modifiedIni;
|
||||
extern char dmModelName[65];
|
||||
extern char dfModelName[65];
|
||||
|
||||
extern DWORD AddUnarmedStatToGetYear;
|
||||
extern bool npcautolevel;
|
||||
|
||||
DWORD GetAddedYears(bool isCheck = true);
|
||||
void SetAddedYears(DWORD years);
|
||||
|
||||
template<typename T>
|
||||
T SimplePatch(DWORD addr, const char* iniSection, const char* iniKey, T defaultValue, T minValue = 0, T maxValue = INT_MAX)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user