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.
This commit is contained in:
NovaRain
2020-10-08 13:49:58 +08:00
parent 2f750a8a4b
commit c71ca95665
10 changed files with 35 additions and 30 deletions
+1
View File
@@ -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)
+2 -1
View File
@@ -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
+9 -4
View File
@@ -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 -------
------------------------
+1
View File
@@ -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);
+7 -10
View File
@@ -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);
@@ -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}},
@@ -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);
}
}
}
+2
View File
@@ -151,5 +151,7 @@ void mf_get_ini_section(OpcodeContext&);
void mf_npc_engine_level_up(OpcodeContext&);
void mf_combat_data(OpcodeContext&);
}
}
+2 -13
View File
@@ -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) {
+2 -2
View File
@@ -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);