From c71ca9566553b268042e2e07f8380491adbb90bc Mon Sep 17 00:00:00 2001 From: NovaRain Date: Thu, 8 Oct 2020 13:35:12 +0800 Subject: [PATCH] Added "combat_data" script function Added a new argument to HOOK_COMBATDAMAGE. Removed the check for valid objects from get/set_object_data functions. Some code fixes. --- artifacts/scripting/headers/sfall.h | 1 + artifacts/scripting/hookscripts.txt | 3 ++- artifacts/scripting/sfall function notes.txt | 13 +++++++++---- sfall/Modules/Graphics.cpp | 1 + sfall/Modules/HookScripts/CombatHs.cpp | 17 +++++++---------- sfall/Modules/Scripting/Handlers/Metarule.cpp | 1 + sfall/Modules/Scripting/Handlers/Misc.cpp | 8 ++++++++ sfall/Modules/Scripting/Handlers/Misc.h | 2 ++ sfall/Modules/Scripting/Handlers/Objects.cpp | 15 ++------------- sfall/Modules/Worldmap.h | 4 ++-- 10 files changed, 35 insertions(+), 30 deletions(-) diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index 14af4bd2..1bd44389 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -294,6 +294,7 @@ #define art_cache_clear sfall_func0("art_cache_clear") #define attack_is_aimed sfall_func0("attack_is_aimed") #define car_gas_amount sfall_func0("car_gas_amount") +#define combat_data sfall_func0("combat_data") #define create_win(winName, x, y, w, h) sfall_func5("create_win", winName, x, y, w, h) #define create_win_flag(winName, x, y, w, h, flag) sfall_func6("create_win", winName, x, y, w, h, flag) #define critter_inven_obj2(obj, type) sfall_func2("critter_inven_obj2", obj, type) diff --git a/artifacts/scripting/hookscripts.txt b/artifacts/scripting/hookscripts.txt index e9b84bca..1f917e7f 100644 --- a/artifacts/scripting/hookscripts.txt +++ b/artifacts/scripting/hookscripts.txt @@ -174,6 +174,7 @@ int arg9 - Damage Multiplier (this is divided by 2, so a value of 3 does 1. int arg10 - Number of bullets actually hit the target (1 for melee attacks) int arg11 - The amount of knockback to the target int arg12 - Attack Type (see ATKTYPE_* constants) +mixed arg13 - computed attack data (see C_ATTACK_* for offsets and use get/set_object_data functions to get/set the data) int ret1 - The damage to the target int ret2 - The damage to the attacker @@ -619,7 +620,7 @@ int arg8 - bonus ranged damage from the perk int arg9 - damage multiplier (this is divided by 2, so a value of 3 does 1.5x damage, and 8 does 4x damage. Usually it's 2; for critical hits, the value is taken from the critical table; with Silent Death perk and the corresponding attack conditions, the value will be doubled) int arg10 - combat difficulty multiplier (125 - rough, 100 - normal, 75 - wimpy; for player or party members it's always 100) int arg11 - the calculated amount of damage (usually 0, required when using multiple hook scripts to calculate damage and using the set_sfall_arg function) -mixed arg12 - computed attack results (see C_ATTACK_* for offsets and use get/set_object_data functions to get/set the data) +mixed arg12 - computed attack data (see C_ATTACK_* for offsets and use get/set_object_data functions to get/set the data) int ret1 - the returned amount of damage diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index 0d13e395..620fe9fe 100644 --- a/artifacts/scripting/sfall function notes.txt +++ b/artifacts/scripting/sfall function notes.txt @@ -468,13 +468,13 @@ Some utility/math functions are available: - NOTE: all keys and their values will be of String type > int sfall_func0("car_gas_amount") -- returns current amount of fuel in player's car (between 0 and 80000) +- returns the current amount of fuel in player's car (between 0 and 80000) - to change fuel amount, use vanilla function: metarule(METARULE_GIVE_CAR_GAS, amount) - amount can be positive or negative > void sfall_func1("set_car_intface_art", int artIndex) -- changes the interface art (index in LST file) for the car image on worldmap screen -- should be called before going to worldmap -- vanilla art index is 0x1B1 +- changes the interface art (index in intrface.lst) for the car image on the world map interface +- should be called before going to the world map +- vanilla art index is 433 > int sfall_func0("get_cursor_mode") - returns the current cursor mode (0 - movement cursor, 1 - command cursor, 2 - targeting cursor) @@ -769,6 +769,11 @@ optional arguments: 0x2000000 - fills the background of the text with black color, the 'textnofill' compiler constant (works the other way around) - width (optional): the maximum width of the text. The text will be wrapped to fit within the specified width +> mixed sfall_func0("combat_data") +- returns a pointer to the C_ATTACK_* data for the current combat attack turn (see defined constants in define_extra.h) +- can be used in conjunction with the get_object_data and set_object_data functions + example: sfall_func3("set_object_data", sfall_func0("combat_data"), C_ATTACK_UNUSED, 255); + ------------------------ ------ MORE INFO ------- ------------------------ diff --git a/sfall/Modules/Graphics.cpp b/sfall/Modules/Graphics.cpp index edd4c966..6023d124 100644 --- a/sfall/Modules/Graphics.cpp +++ b/sfall/Modules/Graphics.cpp @@ -1339,6 +1339,7 @@ void Graphics::init() { // Enable support for transparent interface windows SafeWrite16(0x4D5D46, 0x9090); // win_init_ (create screen_buffer) + SafeWrite8(0x42F869, fo::WinFlags::MoveOnTop | fo::WinFlags::OwnerFlag); // addWindow_ (remove Transparent flag) if (Graphics::mode) { // custom implementation of the GNW_win_refresh function MakeJump(0x4D6FD9, GNW_win_refresh_hack, 1); diff --git a/sfall/Modules/HookScripts/CombatHs.cpp b/sfall/Modules/HookScripts/CombatHs.cpp index ec4c49a2..bb808ba7 100644 --- a/sfall/Modules/HookScripts/CombatHs.cpp +++ b/sfall/Modules/HookScripts/CombatHs.cpp @@ -68,17 +68,13 @@ static DWORD __fastcall AfterHitRollHook_Script(fo::ComputeAttackResult &ctd, DW static void __declspec(naked) AfterHitRollHook() { using namespace fo; __asm { - push ecx; - push edx; - mov ecx, esi; // ctd - mov edx, [esp + 0x18 + 12]; // hit chance - push eax; // was it a hit? + mov ecx, esi; // ctd + mov edx, [esp + 0x18 + 4]; // hit chance + push eax; // was it a hit? call AfterHitRollHook_Script; - pop edx; - pop ecx; // engine code mov ebx, eax; - cmp ebx, ROLL_FAILURE; + cmp eax, ROLL_FAILURE; retn; } } @@ -153,7 +149,7 @@ static void __declspec(naked) CalcApCostHook2() { static void __fastcall ComputeDamageHook_Script(fo::ComputeAttackResult &ctd, DWORD rounds, DWORD multiplier) { BeginHook(); - argCount = 12; + argCount = 13; args[0] = (DWORD)ctd.target; // Target args[1] = (DWORD)ctd.attacker; // Attacker @@ -167,6 +163,7 @@ static void __fastcall ComputeDamageHook_Script(fo::ComputeAttackResult &ctd, DW args[9] = rounds; // number of rounds args[10] = ctd.knockbackValue; args[11] = ctd.hitMode; // attack type + args[12] = (DWORD)&ctd; // main_ctd/shoot_ctd/explosion_ctd RunHookScript(HOOK_COMBATDAMAGE); @@ -227,7 +224,7 @@ static void __fastcall SubComputeDamageHook_Script(fo::ComputeAttackResult &ctd, args[8] = multiplyDamage; args[9] = difficulty; args[10] = accumulatedDamage; - args[11] = (DWORD)&ctd; + args[11] = (DWORD)&ctd; // main_ctd/shoot_ctd/explosion_ctd RunHookScript(HOOK_SUBCOMBATDAMAGE); diff --git a/sfall/Modules/Scripting/Handlers/Metarule.cpp b/sfall/Modules/Scripting/Handlers/Metarule.cpp index 3097f402..d45262ea 100644 --- a/sfall/Modules/Scripting/Handlers/Metarule.cpp +++ b/sfall/Modules/Scripting/Handlers/Metarule.cpp @@ -70,6 +70,7 @@ static const SfallMetarule metarules[] = { {"art_cache_clear", mf_art_cache_flush, 0, 0}, {"attack_is_aimed", mf_attack_is_aimed, 0, 0}, {"car_gas_amount", mf_car_gas_amount, 0, 0}, + {"combat_data", mf_combat_data, 0, 0}, {"create_win", mf_create_win, 5, 6, -1, {ARG_STRING, ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}}, {"critter_inven_obj2", mf_critter_inven_obj2, 2, 2, 0, {ARG_OBJECT, ARG_INT}}, {"dialog_message", mf_dialog_message, 1, 1, -1, {ARG_STRING}}, diff --git a/sfall/Modules/Scripting/Handlers/Misc.cpp b/sfall/Modules/Scripting/Handlers/Misc.cpp index f0aea6b1..1c76a30b 100644 --- a/sfall/Modules/Scripting/Handlers/Misc.cpp +++ b/sfall/Modules/Scripting/Handlers/Misc.cpp @@ -911,5 +911,13 @@ void mf_npc_engine_level_up(OpcodeContext& ctx) { } } +void mf_combat_data(OpcodeContext& ctx) { + fo::ComputeAttackResult* ctd = nullptr; + if (fo::var::combat_state & 1) { + ctd = &fo::var::main_ctd; + } + ctx.setReturn((DWORD)ctd, DataType::INT); +} + } } diff --git a/sfall/Modules/Scripting/Handlers/Misc.h b/sfall/Modules/Scripting/Handlers/Misc.h index e6da8a64..09357cbd 100644 --- a/sfall/Modules/Scripting/Handlers/Misc.h +++ b/sfall/Modules/Scripting/Handlers/Misc.h @@ -151,5 +151,7 @@ void mf_get_ini_section(OpcodeContext&); void mf_npc_engine_level_up(OpcodeContext&); +void mf_combat_data(OpcodeContext&); + } } diff --git a/sfall/Modules/Scripting/Handlers/Objects.cpp b/sfall/Modules/Scripting/Handlers/Objects.cpp index 5665c688..5ce19561 100644 --- a/sfall/Modules/Scripting/Handlers/Objects.cpp +++ b/sfall/Modules/Scripting/Handlers/Objects.cpp @@ -408,24 +408,13 @@ void op_set_proto_data(OpcodeContext& ctx) { } void mf_get_object_data(OpcodeContext& ctx) { - DWORD result = 0; DWORD* object_ptr = (DWORD*)ctx.arg(0).rawValue(); - if (*(object_ptr - 1) != 0xFEEDFACE) { - ctx.printOpcodeError("%s() - invalid object pointer.", ctx.getMetaruleName()); - } else { - result = *(long*)((BYTE*)object_ptr + ctx.arg(1).rawValue()); - } - ctx.setReturn(result); + ctx.setReturn(*(long*)((BYTE*)object_ptr + ctx.arg(1).rawValue())); } void mf_set_object_data(OpcodeContext& ctx) { DWORD* object_ptr = (DWORD*)ctx.arg(0).rawValue(); - if (*(object_ptr - 1) != 0xFEEDFACE) { - ctx.printOpcodeError("%s() - invalid object pointer.", ctx.getMetaruleName()); - ctx.setReturn(-1); - } else { - *(long*)((BYTE*)object_ptr + ctx.arg(1).rawValue()) = ctx.arg(2).rawValue(); - } + *(long*)((BYTE*)object_ptr + ctx.arg(1).rawValue()) = ctx.arg(2).rawValue(); } void mf_get_object_ai_data(OpcodeContext& ctx) { diff --git a/sfall/Modules/Worldmap.h b/sfall/Modules/Worldmap.h index cd96eb15..51b7f91f 100644 --- a/sfall/Modules/Worldmap.h +++ b/sfall/Modules/Worldmap.h @@ -48,8 +48,8 @@ public: static const char* GetCurrentTerrainName(); static bool AreaTitlesIsEmpty(); - static const char* GetCustomAreaTitle(long areaId); - static void SetCustomAreaTitle(long areaId, const char* msg); + static const char* GetCustomAreaTitle(long areaID); + static void SetCustomAreaTitle(long areaID, const char* msg); static long AreaMarkStateIsNoRadius(); static void SetMapMulti(float value);