From 07ff16af75db8d7679fb06bf147dd7824a63ae03 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Fri, 16 Aug 2019 15:17:59 +0800 Subject: [PATCH] Added an additional 'Energy Weapon' flag to ext flags in weapon protos * it forces the weapon to use EW skill regardless of its damage type. Placed an object with PID 0x5000004 (corpse blood) to the lower z-layer of the tile. --- artifacts/scripting/headers/define_extra.h | 1 + sfall/ScriptExtender.cpp | 101 +++++++++++++-------- sfall/skills.cpp | 18 ++++ 3 files changed, 80 insertions(+), 40 deletions(-) diff --git a/artifacts/scripting/headers/define_extra.h b/artifacts/scripting/headers/define_extra.h index f70402f3..9e3bccf9 100644 --- a/artifacts/scripting/headers/define_extra.h +++ b/artifacts/scripting/headers/define_extra.h @@ -31,6 +31,7 @@ #define WEAPON_BIGGUN 256 // 0x00000100 - Big Gun #define WEAPON_2HAND 512 // 0x00000200 - 2Hnd (weapon is two-handed) +#define WEAPON_ENERGYWEAPON 1024 // 0x00000400 - Energy Weapon (forces weapon to use Energy Weapons skill) #define ATKMODE_PRI_NONE 0 #define ATKMODE_PRI_PUNCH 1 // 0001 diff --git a/sfall/ScriptExtender.cpp b/sfall/ScriptExtender.cpp index 9f222c70..65ab407b 100644 --- a/sfall/ScriptExtender.cpp +++ b/sfall/ScriptExtender.cpp @@ -1089,6 +1089,26 @@ static void __declspec(naked) FreeProgramHook() { } } +static void __declspec(naked) CombatBeginHook() { + __asm { + push eax; + call scr_set_ext_param_; + pop eax; // pobj.sid + mov edx, combat_is_starting_p_proc; + jmp exec_script_proc_; + } +} + +static void __declspec(naked) CombatOverHook() { + __asm { + push eax; + call scr_set_ext_param_; + pop eax; // pobj.sid + mov edx, combat_is_over_p_proc; + jmp exec_script_proc_; + } +} + static void __declspec(naked) obj_outline_all_items_on() { __asm { pushad @@ -1169,48 +1189,9 @@ end: } } -static void __declspec(naked) CombatBeginHook() { - __asm { - push eax; - call scr_set_ext_param_; - pop eax; // pobj.sid - mov edx, combat_is_starting_p_proc; - jmp exec_script_proc_; - } -} - -static void __declspec(naked) CombatOverHook() { - __asm { - push eax; - call scr_set_ext_param_; - pop eax; // pobj.sid - mov edx, combat_is_over_p_proc; - jmp exec_script_proc_; - } -} - static int maxCountLoadProto = 512; -static void __declspec(naked) proto_ptr_hack() { - __asm { - mov ecx, maxCountLoadProto; - cmp ecx, 4096; - jae skip; - cmp eax, ecx; - jb end; - add ecx, 256; - mov maxCountLoadProto, ecx; -skip: - cmp eax, ecx; -end: - retn; - } -} -void LoadProtoAutoMaxLimit() { - MakeCall(0x4A21B2, proto_ptr_hack); -} - -long objUniqueID = UID_START; // saving to sfallgv.sav +long objUniqueID = UID_START; // current counter id, saving to sfallgv.sav // Assigns a new unique identifier to an object if it has not been previously assigned // the identifier is saved with the object in the saved game and this can used in various script @@ -1330,6 +1311,43 @@ end: } } +static void __declspec(naked) proto_ptr_hack() { + __asm { + mov ecx, maxCountLoadProto; + cmp ecx, 4096; + jae skip; + cmp eax, ecx; + jb end; + add ecx, 256; + mov maxCountLoadProto, ecx; +skip: + cmp eax, ecx; +end: + retn; + } +} + +void LoadProtoAutoMaxLimit() { + MakeCall(0x4A21B2, proto_ptr_hack); +} + +static void __declspec(naked) obj_insert_hack() { + __asm { + mov edi, [ebx]; + mov [esp + 0x38 - 0x1C + 4], esi; // 0 + test edi, edi; + jnz insert; + retn; +insert: + mov esi, [ecx]; // esi - inserted object + cmp dword ptr [esi + 0x64], 0x5000004; // corpse blood pid + jnz skip; + xor edi, edi; +skip: + retn; + } +} + static void __declspec(naked) map_save_in_game_hook() { __asm { call partyMemberSaveProtos_; @@ -1368,6 +1386,9 @@ void ScriptExtenderSetup() { // Additionally fix object IDs for queued events MakeCall(0x4A25BA, queue_add_hack); + // Place some objects on the tile to the lower z-layer + MakeCall(0x48D918, obj_insert_hack, 1); + arraysBehavior = GetPrivateProfileIntA("Misc", "arraysBehavior", 1, ini); if (arraysBehavior > 0) { arraysBehavior = 1; // only 1 and 0 allowed at this time diff --git a/sfall/skills.cpp b/sfall/skills.cpp index e4137e7a..f6a61f30 100644 --- a/sfall/skills.cpp +++ b/sfall/skills.cpp @@ -59,6 +59,19 @@ static double* multipliers = nullptr; static int skillNegPoints; // skill raw points (w/o limit) +static void __declspec(naked) item_w_skill_hook() { + __asm { + mov edx, [esp + 4]; // item proto + test byte ptr [edx + 0x19], 4; // weapon.flags_ext + jnz energy; + mov edx, ebx; + jmp item_w_damage_type_; +energy: + inc eax; // DMG_laser + retn; + } +} + static int __fastcall CheckSkillMax(TGameObj* critter, int base) { for (DWORD i = 0; i < SkillMaxMods.size(); i++) { if (critter->ID == SkillMaxMods[i].id) { @@ -272,6 +285,11 @@ void SkillsInit() { SafeWrite8(0x4AAA1A, SKILL_MIN_LIMIT); SafeWrite32(0x4AAA23, SKILL_MIN_LIMIT); + // Add an additional 'Energy Weapon' flag to the weapon flags (offset 0x0018) + // Weapon Flags: + // 0x00000400 - Energy Weapon (forces weapon to use Energy Weapons skill) + HookCall(0x47831E, item_w_skill_hook); + char buf[512], key[16], file[64]; if (GetPrivateProfileStringA("Misc", "SkillsFile", "", buf, 62, ini) > 0) { SkillInfo *skills = (SkillInfo*)_skill_data;