mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added combat rating check to "Snipe" distance preference fix
Added a fix to reduce friendly fire in burst attacks. Updated the info of TGameObj struct.
This commit is contained in:
+1
-1
@@ -106,7 +106,7 @@ AllowDShowSound=0
|
|||||||
|
|
||||||
;Set to 1 to override the music path used by default (i.e. data\sound\music\) if not present in the cfg
|
;Set to 1 to override the music path used by default (i.e. data\sound\music\) if not present in the cfg
|
||||||
;Set to 2 to overwrite all occurances of the music path
|
;Set to 2 to overwrite all occurances of the music path
|
||||||
OverrideMusicDir=2
|
OverrideMusicDir=1
|
||||||
|
|
||||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||||
[Input]
|
[Input]
|
||||||
|
|||||||
@@ -28,6 +28,23 @@ typedef std::tr1::unordered_map<TGameObj*, TGameObj*>::const_iterator iter;
|
|||||||
static std::tr1::unordered_map<TGameObj*, TGameObj*> targets;
|
static std::tr1::unordered_map<TGameObj*, TGameObj*> targets;
|
||||||
static std::tr1::unordered_map<TGameObj*, TGameObj*> sources;
|
static std::tr1::unordered_map<TGameObj*, TGameObj*> sources;
|
||||||
|
|
||||||
|
TGameObj* __stdcall sf_check_critters_in_lof(TGameObj* object, DWORD checkTile, DWORD team) {
|
||||||
|
if (object && object->pid >> 24 == OBJ_TYPE_CRITTER && object->teamNum != team) { // not friendly fire
|
||||||
|
if (object->tile == checkTile) return nullptr;
|
||||||
|
TGameObj* obj = nullptr; // continue checking the line of fire from object to checkTile
|
||||||
|
MakeStraightPathFunc(object, object->tile, checkTile, 0, (DWORD*)&obj, 32, (void*)obj_shoot_blocking_at_);
|
||||||
|
if (!sf_check_critters_in_lof(obj, checkTile, team)) return nullptr;
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the friendly critter that is in the line of fire
|
||||||
|
TGameObj* __stdcall CheckFriendlyFire(TGameObj* target, TGameObj* attacker) {
|
||||||
|
TGameObj* object = nullptr;
|
||||||
|
MakeStraightPathFunc(attacker, attacker->tile, target->tile, 0, (DWORD*)&object, 32, (void*)obj_shoot_blocking_at_);
|
||||||
|
return sf_check_critters_in_lof(object, target->tile, attacker->teamNum); // 0 if there are no friendly critters
|
||||||
|
}
|
||||||
|
|
||||||
static void __declspec(naked) ai_try_attack_hook_FleeFix() {
|
static void __declspec(naked) ai_try_attack_hook_FleeFix() {
|
||||||
__asm {
|
__asm {
|
||||||
or byte ptr [esi + 0x3C], 8; // set new 'ReTarget' flag
|
or byte ptr [esi + 0x3C], 8; // set new 'ReTarget' flag
|
||||||
@@ -272,6 +289,14 @@ static void __declspec(naked) cai_perform_distance_prefs_hack() {
|
|||||||
lea edx, [edx + ecx - 1];
|
lea edx, [edx + ecx - 1];
|
||||||
cmp edx, 5; // minimum threshold distance
|
cmp edx, 5; // minimum threshold distance
|
||||||
jge skipMove; // distance >= 5?
|
jge skipMove; // distance >= 5?
|
||||||
|
// check combat rating
|
||||||
|
mov eax, esi;
|
||||||
|
call combatai_rating_;
|
||||||
|
mov edx, eax; // source rating
|
||||||
|
mov eax, edi;
|
||||||
|
call combatai_rating_;
|
||||||
|
cmp eax, edx; // target vs source rating
|
||||||
|
jl skipMove; // target rating is low
|
||||||
moveAway:
|
moveAway:
|
||||||
mov ebx, 10; // move away max distance
|
mov ebx, 10; // move away max distance
|
||||||
retn;
|
retn;
|
||||||
@@ -283,6 +308,32 @@ skipMove:
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static long __fastcall RollFriendlyFire(TGameObj* target, TGameObj* attacker) {
|
||||||
|
if (CheckFriendlyFire(target, attacker)) {
|
||||||
|
long dice = RollRandom(1, 10);
|
||||||
|
return (StatLevel(attacker, STAT_iq) >= dice); // 1 - is friendly
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __declspec(naked) combat_safety_invalidate_weapon_func_hook_check() {
|
||||||
|
static DWORD safety_invalidate_weapon_burst_friendly = 0x4216C9;
|
||||||
|
__asm {
|
||||||
|
pushadc;
|
||||||
|
mov ecx, esi; // target
|
||||||
|
call RollFriendlyFire;
|
||||||
|
test eax, eax;
|
||||||
|
jnz friendly;
|
||||||
|
popadc;
|
||||||
|
jmp combat_ctd_init_;
|
||||||
|
friendly:
|
||||||
|
lea esp, [esp + 8 + 3 * 4];
|
||||||
|
jmp safety_invalidate_weapon_burst_friendly; // "Friendly was in the way!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void __fastcall CombatAttackHook(TGameObj* source, TGameObj* target) {
|
static void __fastcall CombatAttackHook(TGameObj* source, TGameObj* target) {
|
||||||
sources[target] = source; // who attacked the 'target' from the last time
|
sources[target] = source; // who attacked the 'target' from the last time
|
||||||
targets[source] = target; // who was attacked by the 'source' from the last time
|
targets[source] = target; // who was attacked by the 'source' from the last time
|
||||||
@@ -328,6 +379,10 @@ void AIInit() {
|
|||||||
|
|
||||||
/////////////////////// Combat AI behavior fixes ///////////////////////
|
/////////////////////// Combat AI behavior fixes ///////////////////////
|
||||||
|
|
||||||
|
// Fix to reduce friendly fire in burst attacks
|
||||||
|
// Adds a check/roll for friendly critters in the line of fire when AI uses burst attacks
|
||||||
|
HookCall(0x421666, combat_safety_invalidate_weapon_func_hook_check);
|
||||||
|
|
||||||
// Fix for duplicate critters being added to the list of potential targets for AI
|
// Fix for duplicate critters being added to the list of potential targets for AI
|
||||||
MakeCall(0x428E75, ai_find_attackers_hack_target2, 2);
|
MakeCall(0x428E75, ai_find_attackers_hack_target2, 2);
|
||||||
MakeCall(0x428EB5, ai_find_attackers_hack_target3);
|
MakeCall(0x428EB5, ai_find_attackers_hack_target3);
|
||||||
|
|||||||
@@ -21,6 +21,10 @@
|
|||||||
#include "FalloutEngine.h"
|
#include "FalloutEngine.h"
|
||||||
|
|
||||||
void AIInit();
|
void AIInit();
|
||||||
|
|
||||||
|
TGameObj* __stdcall sf_check_critters_in_lof(TGameObj* object, DWORD checkTile, DWORD team);
|
||||||
|
TGameObj* __stdcall CheckFriendlyFire(TGameObj* target, TGameObj* attacker);
|
||||||
|
|
||||||
void __stdcall AICombatStart();
|
void __stdcall AICombatStart();
|
||||||
void __stdcall AICombatEnd();
|
void __stdcall AICombatEnd();
|
||||||
|
|
||||||
|
|||||||
@@ -303,6 +303,7 @@ const DWORD combat_input_ = 0x4227F4;
|
|||||||
const DWORD combat_should_end_ = 0x422C60;
|
const DWORD combat_should_end_ = 0x422C60;
|
||||||
const DWORD combat_turn_ = 0x42299C;
|
const DWORD combat_turn_ = 0x42299C;
|
||||||
const DWORD combat_turn_run_ = 0x4227DC;
|
const DWORD combat_turn_run_ = 0x4227DC;
|
||||||
|
const DWORD combatai_rating_ = 0x42B90C;
|
||||||
const DWORD compute_damage_ = 0x4247B8;
|
const DWORD compute_damage_ = 0x4247B8;
|
||||||
const DWORD compute_spray_ = 0x423488;
|
const DWORD compute_spray_ = 0x423488;
|
||||||
const DWORD config_get_string_ = 0x42BF48;
|
const DWORD config_get_string_ = 0x42BF48;
|
||||||
@@ -994,6 +995,10 @@ TGameObj* __stdcall ScrFindObjFromProgram(TProgram* program) {
|
|||||||
WRAP_WATCOM_CALL1(scr_find_obj_from_program_, program)
|
WRAP_WATCOM_CALL1(scr_find_obj_from_program_, program)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long __stdcall RollRandom(long minValue, long maxValue) {
|
||||||
|
WRAP_WATCOM_CALL2(roll_random_, minValue, maxValue)
|
||||||
|
}
|
||||||
|
|
||||||
// Saves pointer to script object into scriptPtr using scriptID.
|
// Saves pointer to script object into scriptPtr using scriptID.
|
||||||
// Returns 0 on success, -1 on failure.
|
// Returns 0 on success, -1 on failure.
|
||||||
long __stdcall ScrPtr(long scriptId, TScript** scriptPtr) {
|
long __stdcall ScrPtr(long scriptId, TScript** scriptPtr) {
|
||||||
|
|||||||
@@ -564,6 +564,7 @@ extern const DWORD combat_input_;
|
|||||||
extern const DWORD combat_should_end_;
|
extern const DWORD combat_should_end_;
|
||||||
extern const DWORD combat_turn_;
|
extern const DWORD combat_turn_;
|
||||||
extern const DWORD combat_turn_run_;
|
extern const DWORD combat_turn_run_;
|
||||||
|
extern const DWORD combatai_rating_;
|
||||||
extern const DWORD compute_damage_;
|
extern const DWORD compute_damage_;
|
||||||
extern const DWORD compute_spray_;
|
extern const DWORD compute_spray_;
|
||||||
extern const DWORD config_get_string_;
|
extern const DWORD config_get_string_;
|
||||||
@@ -1144,6 +1145,8 @@ long __stdcall XFSeek(DbFile* file, long fOffset, long origin);
|
|||||||
|
|
||||||
TGameObj* __stdcall ScrFindObjFromProgram(TProgram* program);
|
TGameObj* __stdcall ScrFindObjFromProgram(TProgram* program);
|
||||||
|
|
||||||
|
long __stdcall RollRandom(long minValue, long maxValue);
|
||||||
|
|
||||||
// Saves pointer to script object into scriptPtr using scriptID.
|
// Saves pointer to script object into scriptPtr using scriptID.
|
||||||
// Returns 0 on success, -1 on failure.
|
// Returns 0 on success, -1 on failure.
|
||||||
long __stdcall ScrPtr(long scriptId, TScript** scriptPtr);
|
long __stdcall ScrPtr(long scriptId, TScript** scriptPtr);
|
||||||
|
|||||||
@@ -76,9 +76,14 @@ struct TGameObj {
|
|||||||
char gap_38[4];
|
char gap_38[4];
|
||||||
long itemCharges;
|
long itemCharges;
|
||||||
long critterAP_weaponAmmoPid;
|
long critterAP_weaponAmmoPid;
|
||||||
char gap_44[16];
|
long damageFlags; // critter
|
||||||
TGameObj* whoHitMe;
|
long damageLastTurn; // critter
|
||||||
char gap_58[12];
|
long aiPacket; // critter
|
||||||
|
long teamNum; // critter
|
||||||
|
TGameObj* whoHitMe; // critter
|
||||||
|
long health; // critter
|
||||||
|
long rads; // critter
|
||||||
|
long poison; // critter
|
||||||
DWORD pid;
|
DWORD pid;
|
||||||
long cid;
|
long cid;
|
||||||
long lightDistance;
|
long lightDistance;
|
||||||
|
|||||||
@@ -737,7 +737,7 @@ static void sf_unwield_slot() {
|
|||||||
if (update) IntfaceUpdateItems(0, -1, -1);
|
if (update) IntfaceUpdateItems(0, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sf_get_window_attribute() {
|
static void sf_get_window_attribute() {
|
||||||
long attr = 0;
|
long attr = 0;
|
||||||
if (opHandler.numArgs() > 1) attr = opHandler.arg(1).rawValue();
|
if (opHandler.numArgs() > 1) attr = opHandler.arg(1).rawValue();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user