mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b9ffd08a8 | ||
|
|
b26208141f | ||
|
|
147382de25 | ||
|
|
9529208c7c | ||
|
|
fc3b7180af | ||
|
|
f53aa16923 |
+7
-5
@@ -1,5 +1,5 @@
|
||||
;sfall configuration settings
|
||||
;v3.8.19
|
||||
;v3.8.19.1
|
||||
|
||||
[Main]
|
||||
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
|
||||
@@ -15,7 +15,7 @@ UseCommandLine=0
|
||||
NumSoundBuffers=0
|
||||
|
||||
;Set to 1 to allow attaching sound files to combat float messages
|
||||
AllowSoundForFloats=1
|
||||
AllowSoundForFloats=0
|
||||
|
||||
;Set to 1 to automatically search for alternative formats (mp3/wma/wav) when Fallout tries to play an acm
|
||||
;Set to 2 to play alternative music files even if original acm files are not present in the music folder
|
||||
@@ -173,7 +173,7 @@ FastMoveFromContainer=0
|
||||
|
||||
;A key to press to open a debug game editor
|
||||
;Set to 0 to disable, or a DX scancode otherwise
|
||||
;Requires sfall debugging mode and FalloutClient.exe from the modders pack
|
||||
;Requires sfall debugging mode to be enabled and FalloutClient.exe from the modders pack
|
||||
DebugEditorKey=0
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
@@ -682,6 +682,7 @@ Enable=0
|
||||
|
||||
;Fallout 2 Debug Patch
|
||||
;Set to 1 to send debug output to the screen, 2 to a debug.log file, or 3 to both the screen and a debug.log file
|
||||
;Does not require enabling sfall debugging mode
|
||||
;While you don't need to create an environment variable, you do still need to set the appropriate lines in fallout2.cfg:
|
||||
;-------
|
||||
;[debug]
|
||||
@@ -700,12 +701,12 @@ DebugMode=0
|
||||
SkipCompatModeCheck=0
|
||||
|
||||
;Set to 1 to skip the executable file size check
|
||||
;Does not require sfall debugging mode
|
||||
;Does not require enabling sfall debugging mode
|
||||
SkipSizeCheck=0
|
||||
|
||||
;If you're testing changes to the Fallout exe, you can override the CRC that sfall looks for here
|
||||
;You can use several hex values, separated by commas
|
||||
;Does not require sfall debugging mode
|
||||
;Does not require enabling sfall debugging mode
|
||||
;ExtraCRC=0x00000000,0x00000000
|
||||
|
||||
;Set to 1 to stop Fallout from deleting non read-only protos at startup
|
||||
@@ -716,6 +717,7 @@ DontDeleteProtos=0
|
||||
AllowUnsafeScripting=0
|
||||
|
||||
;Set to 1 to hide error messages in debug output when a null value is passed to the function as an object
|
||||
;Requires DebugMode to be enabled
|
||||
HideObjIsNullMsg=0
|
||||
|
||||
;Set to 1 to force critters to display combat float messages
|
||||
|
||||
+18
-15
@@ -176,12 +176,13 @@ bool LoadArrayElement(sArrayElement* el, HANDLE h)
|
||||
return (el->len) ? (unused != el->len) : (unused != 4);
|
||||
}
|
||||
|
||||
static bool LoadArraysOld(HANDLE h) {
|
||||
dlogr("Loading arrays (old fmt)", DL_MAIN);
|
||||
|
||||
static long LoadArraysOld(HANDLE h) {
|
||||
DWORD count, unused, id;
|
||||
ReadFile(h, &count, 4, &unused, 0); // count of saved arrays
|
||||
if (unused != 4) return true;
|
||||
if (unused != 4) return -1;
|
||||
if (!count) return 0;
|
||||
|
||||
dlogr("Loading arrays (old fmt)", DL_MAIN);
|
||||
|
||||
sArrayVarOld var;
|
||||
sArrayVar varN;
|
||||
@@ -189,7 +190,7 @@ static bool LoadArraysOld(HANDLE h) {
|
||||
for (DWORD i = 0; i < count; i++) {
|
||||
ReadFile(h, &id, 4, &unused, 0);
|
||||
ReadFile(h, &var, 8, &unused, 0);
|
||||
if (unused != 8) return true;
|
||||
if (unused != 8) return -1;
|
||||
|
||||
var.types = new DWORD[var.len];
|
||||
var.data = new char[var.len * var.datalen];
|
||||
@@ -219,23 +220,25 @@ static bool LoadArraysOld(HANDLE h) {
|
||||
arrays.insert(array_pair(id, varN));
|
||||
savedArrays[varN.key] = id;
|
||||
}
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool LoadArrays(HANDLE h) {
|
||||
long LoadArrays(HANDLE h) {
|
||||
nextArrayID = 1;
|
||||
|
||||
if (LoadArraysOld(h)) return true;
|
||||
|
||||
dlogr("Loading arrays (new fmt)", DL_MAIN);
|
||||
long result = LoadArraysOld(h);
|
||||
if (result) return result;
|
||||
|
||||
DWORD count, unused, elCount;
|
||||
ReadFile(h, &count, 4, &unused, 0); // count of saved arrays
|
||||
if (unused != 4) return true;
|
||||
if (unused != 4 && !result) return 1;
|
||||
|
||||
dlogr("Loading arrays (new fmt)", DL_MAIN);
|
||||
if (unused != 4) return -1;
|
||||
|
||||
sArrayVar arrayVar;
|
||||
for (DWORD i = 0; i < count; i++) {
|
||||
if (LoadArrayElement(&arrayVar.key, h)) return true;
|
||||
if (LoadArrayElement(&arrayVar.key, h)) return -1;
|
||||
if (arrayVar.key.intVal == 0 || static_cast<long>(arrayVar.key.type) >= 4) { // partial compatibility with 3.4
|
||||
arrayVar.key.intVal = static_cast<long>(arrayVar.key.type);
|
||||
arrayVar.key.type = DATATYPE_INT;
|
||||
@@ -243,12 +246,12 @@ bool LoadArrays(HANDLE h) {
|
||||
|
||||
ReadFile(h, &arrayVar.flags, 4, &unused, 0);
|
||||
ReadFile(h, &elCount, 4, &unused, 0); // actual number of elements: keys+values
|
||||
if (unused != 4) return true;
|
||||
if (unused != 4) return -1;
|
||||
|
||||
bool isAssoc = arrayVar.isAssoc();
|
||||
arrayVar.val.resize(elCount);
|
||||
for (size_t j = 0; j < elCount; j++) { // normal and associative arrays stored and loaded equally
|
||||
if (LoadArrayElement(&arrayVar.val[j], h)) return true;
|
||||
if (LoadArrayElement(&arrayVar.val[j], h)) return -1;
|
||||
if (isAssoc && (j % 2) == 0) { // only difference is that keyHash is filled with appropriate indexes
|
||||
arrayVar.keyHash[arrayVar.val[j]] = j;
|
||||
}
|
||||
@@ -260,7 +263,7 @@ bool LoadArrays(HANDLE h) {
|
||||
savedArrays[arrayVar.key] = nextArrayID++;
|
||||
arrayVar.keyHash.clear();
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SaveArrays(HANDLE h) {
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ extern DWORD arraysBehavior;
|
||||
// saved arrays: arrayKey => arrayId
|
||||
extern ArrayKeysMap savedArrays;
|
||||
|
||||
bool LoadArrays(HANDLE h);
|
||||
long LoadArrays(HANDLE h);
|
||||
void SaveArrays(HANDLE h);
|
||||
int GetNumArrays();
|
||||
void GetArrays(int* arrays);
|
||||
|
||||
+27
-2
@@ -47,7 +47,7 @@ void DrugsSaveFix(HANDLE file) {
|
||||
bool DrugsLoadFix(HANDLE file) {
|
||||
DWORD count, sizeRead;
|
||||
ReadFile(file, &count, 4, &sizeRead, 0);
|
||||
//if (sizeRead != 4) return true;
|
||||
if (sizeRead != 4) return false;
|
||||
for (DWORD i = 0; i < count; i++) {
|
||||
DWORD pid;
|
||||
ReadFile(file, &pid, 4, &sizeRead, 0);
|
||||
@@ -1440,6 +1440,26 @@ end:
|
||||
}
|
||||
}
|
||||
|
||||
//zero damage insta death criticals fix (moved from compute_damage hook)
|
||||
static void __fastcall InstantDeathFix(TComputeAttack &ctd) {
|
||||
if (ctd.targetDamage == 0 && (ctd.targetFlags & DAM_DEAD)) {
|
||||
ctd.targetDamage++; // set 1 hp damage
|
||||
}
|
||||
}
|
||||
|
||||
static const DWORD ComputeDamageRet = 0x424BA7;
|
||||
static void __declspec(naked) compute_damage_hack() {
|
||||
__asm {
|
||||
mov ecx, esi; // ctd
|
||||
call InstantDeathFix;
|
||||
// overwritten engine code
|
||||
add esp, 0x34;
|
||||
pop ebp;
|
||||
pop edi;
|
||||
jmp ComputeDamageRet;
|
||||
}
|
||||
}
|
||||
|
||||
static int currDescLen = 0;
|
||||
static bool showItemDescription = false;
|
||||
static void __stdcall AppendText(const char* text, const char* desc) {
|
||||
@@ -2224,7 +2244,7 @@ break:
|
||||
void BugFixesInit()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (isDebug && (GetPrivateProfileIntA("Debugging", "BugFixes", 1, ".\\ddraw.ini")) == 0)) return;
|
||||
if (isDebug && (GetPrivateProfileIntA("Debugging", "BugFixes", 1, ".\\ddraw.ini") == 0)) return;
|
||||
#endif
|
||||
|
||||
// fix vanilla negate operator on float values
|
||||
@@ -2573,6 +2593,11 @@ void BugFixesInit()
|
||||
// in their AI packages is set to stay_close/charge, or NPCsTryToSpendExtraAP is enabled
|
||||
HookCall(0x42A1A8, ai_move_steps_closer_hook); // 0x42B24D
|
||||
|
||||
// Fix instant death critical
|
||||
dlog("Applying instant death fix.", DL_INIT);
|
||||
MakeJump(0x424BA2, compute_damage_hack);
|
||||
dlogr(" Done", DL_INIT);
|
||||
|
||||
// Fix missing AC/DR mod stats when examining ammo in the barter screen
|
||||
dlog("Applying fix for displaying ammo stats in barter screen.", DL_INIT);
|
||||
MakeCall(0x49B4AD, obj_examine_func_hack_ammo0, 2);
|
||||
|
||||
@@ -359,7 +359,8 @@ void DontDeleteProtosPatch() {
|
||||
}
|
||||
|
||||
void DebugEditorInit() {
|
||||
if (!isDebug) return;
|
||||
DebugModePatch();
|
||||
|
||||
if (!isDebug) return;
|
||||
DontDeleteProtosPatch();
|
||||
}
|
||||
|
||||
+18
-11
@@ -78,20 +78,27 @@ struct TGameObj
|
||||
#pragma pack(push, 1)
|
||||
struct TComputeAttack
|
||||
{
|
||||
TGameObj *attacker;
|
||||
char gap_4[4];
|
||||
TGameObj *weapon;
|
||||
char gap_C[4];
|
||||
long damageAttacker;
|
||||
long flagsAttacker;
|
||||
long rounds;
|
||||
char gap_1C[4];
|
||||
TGameObj *target;
|
||||
TGameObj* attacker;
|
||||
long hitMode;
|
||||
TGameObj* weapon;
|
||||
long field_C;
|
||||
long attackerDamage;
|
||||
long attackerFlags;
|
||||
long numRounds;
|
||||
long message;
|
||||
TGameObj* target;
|
||||
long targetTile;
|
||||
long bodyPart;
|
||||
long damageTarget;
|
||||
long flagsTarget;
|
||||
long targetDamage;
|
||||
long targetFlags;
|
||||
long knockbackValue;
|
||||
TGameObj* mainTarget;
|
||||
long numExtras;
|
||||
TGameObj* extraTarget[6];
|
||||
long extraBodyPart[6];
|
||||
long extraDamage[6];
|
||||
long extraFlags[6];
|
||||
long extraKnockbackValue[6];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
+53
-76
@@ -366,76 +366,53 @@ skip:
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) CombatDamageHook() {
|
||||
// 4.x backport
|
||||
static void __fastcall ComputeDamageHook_Script(TComputeAttack &ctd, DWORD rounds, DWORD multiplier) {
|
||||
BeginHook();
|
||||
argCount = 12;
|
||||
|
||||
args[0] = (DWORD)ctd.target; // Target
|
||||
args[1] = (DWORD)ctd.attacker; // Attacker
|
||||
args[2] = ctd.targetDamage; // amountTarget
|
||||
args[3] = ctd.attackerDamage; // amountSource
|
||||
args[4] = ctd.targetFlags; // flagsTarget
|
||||
args[5] = ctd.attackerFlags; // flagsSource
|
||||
args[6] = (DWORD)ctd.weapon;
|
||||
args[7] = ctd.bodyPart;
|
||||
args[8] = multiplier; // damage multiplier
|
||||
args[9] = rounds; // number of rounds
|
||||
args[10] = ctd.knockbackValue;
|
||||
args[11] = ctd.hitMode; // attack type
|
||||
|
||||
RunHookScript(HOOK_COMBATDAMAGE);
|
||||
|
||||
if (cRet > 0) {
|
||||
ctd.targetDamage = rets[0];
|
||||
if (cRet > 1) {
|
||||
ctd.attackerDamage = rets[1];
|
||||
if (cRet > 2) {
|
||||
ctd.targetFlags = rets[2]; // flagsTarget
|
||||
if (cRet > 3) {
|
||||
ctd.attackerFlags = rets[3]; // flagsSource
|
||||
if (cRet > 4) ctd.knockbackValue = rets[4];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EndHook();
|
||||
}
|
||||
|
||||
static void __declspec(naked) ComputeDamageHook() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ebx;
|
||||
push eax;
|
||||
push ecx;
|
||||
push ebx; // store dmg multiplier args[8]
|
||||
push edx; // store num of rounds args[9]
|
||||
push eax; // store ctd
|
||||
call compute_damage_;
|
||||
pop edx;
|
||||
|
||||
//zero damage insta death criticals fix
|
||||
mov ebx, [edx+0x2c];
|
||||
test ebx, ebx;
|
||||
jnz hookscript;
|
||||
mov ebx, [edx+0x30];
|
||||
test bl, 0x80;
|
||||
jz hookscript;
|
||||
inc dword ptr ds:[edx+0x2c];
|
||||
hookscript:
|
||||
hookbegin(12);
|
||||
mov ebx, [edx+0x20];
|
||||
mov args[0x00], ebx;
|
||||
mov ebx, [edx+0x00];
|
||||
mov args[0x04], ebx;
|
||||
mov ebx, [edx+0x2c];
|
||||
mov args[0x08], ebx;
|
||||
mov ebx, [edx+0x10];
|
||||
mov args[0x0c], ebx;
|
||||
mov ebx, [edx+0x30];
|
||||
mov args[0x10], ebx;
|
||||
mov ebx, [edx+0x14];
|
||||
mov args[0x14], ebx;
|
||||
mov ebx, [edx+0x08];
|
||||
mov args[0x18], ebx;
|
||||
mov ebx, [edx+0x28];
|
||||
mov args[0x1c], ebx;
|
||||
pop ebx; // roll result
|
||||
mov args[0x20], ebx;
|
||||
pop ebx; // num rounds
|
||||
mov args[0x24], ebx;
|
||||
mov ebx, [edx+0x34]; // knockback value
|
||||
mov args[0x28], ebx;
|
||||
mov ebx, [edx+0x04]; // attack type
|
||||
mov args[0x2c], ebx;
|
||||
|
||||
pushad;
|
||||
push HOOK_COMBATDAMAGE;
|
||||
call RunHookScript;
|
||||
popad;
|
||||
|
||||
cmp cRet, 1;
|
||||
jl end;
|
||||
mov ebx, rets[0x00];
|
||||
mov [edx+0x2c], ebx;
|
||||
cmp cRet, 2;
|
||||
jl end;
|
||||
mov ebx, rets[0x04];
|
||||
mov [edx+0x10], ebx;
|
||||
cmp cRet, 3;
|
||||
jl end;
|
||||
mov ebx, rets[0x08];
|
||||
mov [edx+0x30], ebx;
|
||||
cmp cRet, 4;
|
||||
jl end;
|
||||
mov ebx, rets[0x0c];
|
||||
mov [edx+0x14], ebx;
|
||||
cmp cRet, 5;
|
||||
jl end;
|
||||
mov ebx, rets[0x10];
|
||||
mov [edx+0x34], ebx; // knockback
|
||||
end:
|
||||
hookend;
|
||||
pop ecx; // restore ctd (eax)
|
||||
pop edx; // restore num of rounds
|
||||
call ComputeDamageHook_Script; // stack - arg multiplier
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -1486,14 +1463,14 @@ static void HookScriptInit2() {
|
||||
HookCall(0x4109BF, &CalcDeathAnimHook2);
|
||||
|
||||
LoadHookScript("hs_combatdamage", HOOK_COMBATDAMAGE);
|
||||
HookCall(0x42326C, &CombatDamageHook); // check_ranged_miss()
|
||||
HookCall(0x4233E3, &CombatDamageHook); // shoot_along_path() - for extra burst targets
|
||||
HookCall(0x423AB7, &CombatDamageHook); // compute_attack()
|
||||
HookCall(0x423BBF, &CombatDamageHook); // compute_attack()
|
||||
HookCall(0x423DE7, &CombatDamageHook); // compute_explosion_on_extras()
|
||||
HookCall(0x423E69, &CombatDamageHook); // compute_explosion_on_extras()
|
||||
HookCall(0x424220, &CombatDamageHook); // attack_crit_failure()
|
||||
HookCall(0x4242FB, &CombatDamageHook); // attack_crit_failure()
|
||||
HookCall(0x42326C, ComputeDamageHook); // check_ranged_miss()
|
||||
HookCall(0x4233E3, ComputeDamageHook); // shoot_along_path() - for extra burst targets
|
||||
HookCall(0x423AB7, ComputeDamageHook); // compute_attack()
|
||||
HookCall(0x423BBF, ComputeDamageHook); // compute_attack()
|
||||
HookCall(0x423DE7, ComputeDamageHook); // compute_explosion_on_extras()
|
||||
HookCall(0x423E69, ComputeDamageHook); // compute_explosion_on_extras()
|
||||
HookCall(0x424220, ComputeDamageHook); // attack_crit_failure()
|
||||
HookCall(0x4242FB, ComputeDamageHook); // attack_crit_failure()
|
||||
|
||||
LoadHookScript("hs_ondeath", HOOK_ONDEATH);
|
||||
HookCall(0x4130CC, &OnDeathHook);
|
||||
|
||||
@@ -129,8 +129,8 @@ static void _stdcall SaveGame2() {
|
||||
} else {
|
||||
goto errorSave;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
errorSave:
|
||||
dlog_f("ERROR creating: %s\n", DL_MAIN, buf);
|
||||
@@ -198,18 +198,20 @@ static bool _stdcall LoadGame2_Before() {
|
||||
if (uID > UID_START) objUniqueID = uID;
|
||||
ReadFile(h, &data, 4, &size, 0);
|
||||
SetAddedYears(data >> 16);
|
||||
if (size != 4 || !PerksLoad(h) || LoadArrays(h)) goto errorLoad;
|
||||
if (DrugsLoadFix(h)) goto errorLoad;
|
||||
if (size != 4 || !PerksLoad(h)) goto errorLoad;
|
||||
long result = LoadArrays(h); // 1 - old save, -1 - broken save
|
||||
if (result == -1 || (!result && DrugsLoadFix(h))) goto errorLoad;
|
||||
CloseHandle(h);
|
||||
} else {
|
||||
dlogr("Cannot open sfallgv.sav - assuming non-sfall save.", DL_MAIN);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
errorLoad:
|
||||
CloseHandle(h);
|
||||
dlog_f("ERROR reading data: %s\n", DL_MAIN, buf);
|
||||
DebugPrintf("\n[SFALL] ERROR reading data: %s", buf);
|
||||
return (true & !isDebug);
|
||||
}
|
||||
|
||||
|
||||
@@ -124,8 +124,8 @@ static void TakeControlOfNPC(TGameObj* npc) {
|
||||
// reset traits
|
||||
ptr_pc_traits[0] = ptr_pc_traits[1] = -1;
|
||||
|
||||
// reset perks
|
||||
for (int i = 0; i < PERK_count; i++) {
|
||||
// reset perks (except Awareness)
|
||||
for (int i = 1; i < PERK_count; i++) {
|
||||
(*ptr_perkLevelDataList)[i] = 0;
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ static void RestoreRealDudeState(bool redraw = true) {
|
||||
IsControllingNPC = false;
|
||||
real_dude = nullptr;
|
||||
|
||||
if (isDebug) DebugPrintf("\n[SFALL] Restore control to dude.");
|
||||
if (isDebug) DebugPrintf("\n[SFALL] Restore control to dude.\n");
|
||||
}
|
||||
|
||||
static int __stdcall CombatTurn(TGameObj* obj) {
|
||||
@@ -296,14 +296,14 @@ int __stdcall PartyControl_SwitchHandHook(TGameObj* item) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
long __fastcall GetRealDudePerk(TGameObj* source, long perk) {
|
||||
static long __fastcall GetRealDudePerk(TGameObj* source, long perk) {
|
||||
if (IsControllingNPC && source == real_dude) {
|
||||
return real_perkLevelDataList[perk];
|
||||
}
|
||||
return PerkLevel(source, perk);
|
||||
}
|
||||
|
||||
long __fastcall GetRealDudeTrait(TGameObj* source, long trait) {
|
||||
static long __fastcall GetRealDudeTrait(TGameObj* source, long trait) {
|
||||
if (IsControllingNPC && source == real_dude) {
|
||||
return (trait == real_traits[0] || trait == real_traits[1]) ? 1 : 0;
|
||||
}
|
||||
|
||||
+14
-19
@@ -1342,9 +1342,6 @@ static void __declspec(naked) map_save_in_game_hook() {
|
||||
}
|
||||
|
||||
void ScriptExtenderSetup() {
|
||||
bool AllowUnsafeScripting = isDebug
|
||||
&& GetPrivateProfileIntA("Debugging", "AllowUnsafeScripting", 0, ".\\ddraw.ini") != 0;
|
||||
|
||||
toggleHighlightsKey = GetPrivateProfileIntA("Input", "ToggleItemHighlightsKey", 0, ini);
|
||||
if (toggleHighlightsKey) {
|
||||
MotionSensorMode = GetPrivateProfileIntA("Misc", "MotionScannerFlags", 1, ini);
|
||||
@@ -1410,17 +1407,24 @@ void ScriptExtenderSetup() {
|
||||
SafeWriteBytes(0x483CB4, (BYTE*)&data, 5);
|
||||
|
||||
dlogr("Adding additional opcodes", DL_SCRIPT);
|
||||
if (AllowUnsafeScripting) {
|
||||
dlogr(" Unsafe opcodes enabled.", DL_SCRIPT);
|
||||
} else {
|
||||
dlogr(" Unsafe opcodes disabled.", DL_SCRIPT);
|
||||
}
|
||||
|
||||
SafeWrite32(0x46E370, 0x300); // Maximum number of allowed opcodes
|
||||
SafeWrite32(0x46CE34, (DWORD)opcodes); // cmp check to make sure opcode exists
|
||||
SafeWrite32(0x46CE6C, (DWORD)opcodes); // call that actually jumps to the opcode
|
||||
SafeWrite32(0x46E390, (DWORD)opcodes); // mov that writes to the opcode
|
||||
|
||||
if (isDebug && (GetPrivateProfileIntA("Debugging", "AllowUnsafeScripting", 0, ".\\ddraw.ini") != 0)) {
|
||||
dlogr(" Unsafe opcodes enabled.", DL_SCRIPT);
|
||||
opcodes[0x1cf] = WriteByte;
|
||||
opcodes[0x1d0] = WriteShort;
|
||||
opcodes[0x1d1] = WriteInt;
|
||||
opcodes[0x21b] = WriteString;
|
||||
for (int i = 0x1d2; i < 0x1dc; i++) {
|
||||
opcodes[i] = CallOffset;
|
||||
}
|
||||
} else {
|
||||
dlogr(" Unsafe opcodes disabled.", DL_SCRIPT);
|
||||
}
|
||||
opcodes[0x156] = ReadByte;
|
||||
opcodes[0x157] = ReadShort;
|
||||
opcodes[0x158] = ReadInt;
|
||||
@@ -1533,14 +1537,7 @@ void ScriptExtenderSetup() {
|
||||
opcodes[0x1cc] = fApplyHeaveHoFix;
|
||||
opcodes[0x1cd] = SetSwiftLearnerMod;
|
||||
opcodes[0x1ce] = SetLevelHPMod;
|
||||
if (AllowUnsafeScripting) {
|
||||
opcodes[0x1cf] = WriteByte;
|
||||
opcodes[0x1d0] = WriteShort;
|
||||
opcodes[0x1d1] = WriteInt;
|
||||
for (int i = 0x1d2; i < 0x1dc; i++) {
|
||||
opcodes[i] = CallOffset;
|
||||
}
|
||||
}
|
||||
|
||||
opcodes[0x1dc] = ShowIfaceTag;
|
||||
opcodes[0x1dd] = HideIfaceTag;
|
||||
opcodes[0x1de] = IsIfaceTagActive;
|
||||
@@ -1604,9 +1601,7 @@ void ScriptExtenderSetup() {
|
||||
opcodes[0x218] = set_weapon_ammo_pid;
|
||||
opcodes[0x219] = get_weapon_ammo_count;
|
||||
opcodes[0x21a] = set_weapon_ammo_count;
|
||||
if (AllowUnsafeScripting) {
|
||||
opcodes[0x21b] = WriteString;
|
||||
}
|
||||
|
||||
opcodes[0x21c] = get_mouse_x;
|
||||
opcodes[0x21d] = get_mouse_y;
|
||||
opcodes[0x21e] = get_mouse_buttons;
|
||||
|
||||
+3
-4
@@ -25,13 +25,12 @@
|
||||
#define VERSION_MAJOR 3
|
||||
#define VERSION_MINOR 8
|
||||
#define VERSION_BUILD 19
|
||||
#define VERSION_REV 0
|
||||
#define VERSION_REV 1
|
||||
|
||||
#ifdef WIN2K
|
||||
#define VERSION_STRING "3.8.19 win2k"
|
||||
#define VERSION_STRING "3.8.19.1 win2k"
|
||||
#else
|
||||
#define VERSION_STRING "3.8.19"
|
||||
#define VERSION_STRING "3.8.19.1"
|
||||
#endif
|
||||
|
||||
//#define CHECK_VAL (4)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user