mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Fixed a bug in 4.3.1 that caused AI to be unable to use some weapons
Code edits regarding AIpref in Enums.h. Added GamePids.h (derived from ItemPid.h in mapper scripts)
This commit is contained in:
+13
-76
@@ -18,6 +18,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GamePids.h"
|
||||
|
||||
namespace fo
|
||||
{
|
||||
|
||||
@@ -287,74 +289,6 @@ enum ArtType : char
|
||||
OBJ_TYPE_SKILLDEX = 10
|
||||
};
|
||||
|
||||
// Some FO2 PIDs possibly used by engine
|
||||
enum ProtoID : unsigned long
|
||||
{
|
||||
PID_POWERED_ARMOR = 3,
|
||||
// PID_ROCK = 19,
|
||||
PID_SMALL_ENERGY_CELL = 38,
|
||||
PID_MICRO_FUSION_CELL = 39,
|
||||
PID_STIMPAK = 40,
|
||||
PID_BOTTLE_CAPS = 41,
|
||||
PID_FIRST_AID_KIT = 47,
|
||||
PID_RADAWAY = 48,
|
||||
PID_ANTIDOTE = 49,
|
||||
PID_DYNAMITE = 51,
|
||||
PID_GEIGER_COUNTER = 52,
|
||||
PID_MENTATS = 53,
|
||||
PID_STEALTH_BOY = 54,
|
||||
// PID_WATER_CHIP = 55,
|
||||
// PID_HOLODISK = 58,
|
||||
PID_MOTION_SENSOR = 59,
|
||||
PID_MUTATED_FRUIT = 71,
|
||||
PID_BIG_BOOK_OF_SCIENCE = 73,
|
||||
PID_DEANS_ELECTRONICS = 76,
|
||||
PID_FLARE = 79,
|
||||
PID_FIRST_AID_BOOK = 80,
|
||||
PID_PLASTIC_EXPLOSIVES = 85,
|
||||
PID_SCOUT_HANDBOOK = 86,
|
||||
PID_BUFFOUT = 87,
|
||||
PID_DOCTORS_BAG = 91,
|
||||
// PID_PUMP_PARTS = 98,
|
||||
PID_GUNS_AND_BULLETS = 102,
|
||||
PID_NUKA_COLA = 106,
|
||||
PID_RAD_X = 109,
|
||||
PID_PSYCHO = 110,
|
||||
PID_BEER = 124,
|
||||
PID_BOOZE = 125,
|
||||
PID_SUPER_STIMPAK = 144,
|
||||
PID_ACTIVE_FLARE = 205,
|
||||
PID_ACTIVE_DYNAMITE = 206,
|
||||
PID_ACTIVE_GEIGER_COUNTER = 207,
|
||||
PID_ACTIVE_MOTION_SENSOR = 208,
|
||||
PID_ACTIVE_PLASTIC_EXPLOSIVE = 209,
|
||||
PID_ACTIVE_STEALTH_BOY = 210,
|
||||
PID_TECHNICAL_MANUAL = 228,
|
||||
PID_HARDENED_POWER_ARMOR = 232,
|
||||
PID_CHEMISTRY_MANUAL = 237,
|
||||
PID_JET = 259,
|
||||
PID_JET_ANTIDOTE = 260,
|
||||
PID_HEALING_POWDER = 273,
|
||||
PID_DECK_OF_TRAGIC_CARDS = 306,
|
||||
PID_ADVANCED_POWER_ARMOR = 348,
|
||||
PID_ADVANCED_POWER_ARMOR_MK2 = 349,
|
||||
// PID_GECK = 366,
|
||||
PID_SOLAR_SCORCHER = 390,
|
||||
PID_CAR_TRUNK = 455,
|
||||
PID_JESSE_CONTAINER = 467,
|
||||
|
||||
// critter
|
||||
PID_Player = 0x01000000,
|
||||
|
||||
// scenery
|
||||
PID_RAD_GOO_1 = 0x020003D9,
|
||||
PID_RAD_GOO_4 = 0x020003DC,
|
||||
PID_DRIVABLE_CAR = 0x020003F1, // index 1009
|
||||
|
||||
// misc type
|
||||
PID_CORPSE_BLOOD = 0x05000004,
|
||||
};
|
||||
|
||||
//XXXXXXXXXXXXXXXXXXXXX
|
||||
//XX Critter defines XX
|
||||
//XXXXXXXXXXXXXXXXXXXXX
|
||||
@@ -888,8 +822,9 @@ namespace WinFlags {
|
||||
}
|
||||
|
||||
namespace AIpref {
|
||||
enum distance : long
|
||||
enum class Distance : long
|
||||
{
|
||||
unset = -1,
|
||||
stay_close = 0, // the attacker will stay at a distance no more than 5 hexes from the player (behavior only for party members, defined in ai_move_steps_closer, cai_perform_distance_prefs)
|
||||
charge = 1, // AI will always try to get close to its target before or after attack
|
||||
snipe = 2, // keep distance, when the distance between the attacker and the target decreases, the attacker will try to move away from the target to a distance of up to 10 hexes
|
||||
@@ -898,7 +833,7 @@ namespace AIpref {
|
||||
};
|
||||
|
||||
// presets for party members
|
||||
enum disposition : long
|
||||
enum class Disposition : long
|
||||
{
|
||||
none = -1,
|
||||
custom = 0,
|
||||
@@ -908,7 +843,7 @@ namespace AIpref {
|
||||
berserk = 4
|
||||
};
|
||||
|
||||
enum class attack_who : long
|
||||
enum class AttackWho : long
|
||||
{
|
||||
no_attack_mode = -1,
|
||||
whomever_attacking_me = 0, // attack the target that the player is attacking (only for party members)
|
||||
@@ -918,7 +853,7 @@ namespace AIpref {
|
||||
closest = 4, // only attack near targets
|
||||
};
|
||||
|
||||
enum class run_away_mode : long
|
||||
enum class RunAway : long
|
||||
{
|
||||
none = -1, // get the value from the cap.min_hp (in cai_get_min_hp_)
|
||||
coward = 0, // 0%
|
||||
@@ -929,9 +864,10 @@ namespace AIpref {
|
||||
never = 5 // 100%
|
||||
};
|
||||
|
||||
enum class weapon_pref : long
|
||||
enum class WeaponPref : long
|
||||
{
|
||||
no_pref = 0,
|
||||
unset = -1, // same as no_pref
|
||||
no_pref = 0, // Guns > ...
|
||||
melee = 1,
|
||||
melee_over_ranged = 2,
|
||||
ranged_over_melee = 3,
|
||||
@@ -941,7 +877,7 @@ namespace AIpref {
|
||||
random = 7 // not available for party member in control panel
|
||||
};
|
||||
|
||||
enum class area_attack_mode : long
|
||||
enum class AreaAttack : long
|
||||
{
|
||||
no_pref = -1, // special logic for NPC (not available for party member in control panel)
|
||||
always = 0,
|
||||
@@ -951,8 +887,9 @@ namespace AIpref {
|
||||
be_absolutely_sure = 4, // 95% hit chance
|
||||
};
|
||||
|
||||
enum class chem_use_mode : long
|
||||
enum class ChemUse : long
|
||||
{
|
||||
unset = -1,
|
||||
clean = 0,
|
||||
stims_when_hurt_little = 1,
|
||||
stims_when_hurt_lots = 2,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -184,11 +184,11 @@ struct GameObject {
|
||||
|
||||
union {
|
||||
struct {
|
||||
fo::MiscFlags miscFlags; // aka updated_flags
|
||||
MiscFlags miscFlags; // aka updated_flags
|
||||
// for weapons - ammo in magazine, for ammo - amount of ammo in last ammo pack
|
||||
long charges;
|
||||
// current type of ammo loaded in magazine
|
||||
long ammoPid;
|
||||
ProtoID ammoPid;
|
||||
long unused[8]; // offset 0x44 (not saved)
|
||||
} item;
|
||||
|
||||
@@ -240,13 +240,13 @@ struct GameObject {
|
||||
} critter;
|
||||
|
||||
struct {
|
||||
fo::MiscFlags sceneryFlags; // unused for scenery? (aka updated_flags)
|
||||
fo::MiscFlags doorFlags; // used for doors states open/locked/jammed (aka cur_open_flags)
|
||||
MiscFlags sceneryFlags; // unused for scenery? (aka updated_flags)
|
||||
MiscFlags doorFlags; // used for doors states open/locked/jammed (aka cur_open_flags)
|
||||
long unused[9]; // offset 0x40 (not saved)
|
||||
} scenery;
|
||||
};
|
||||
|
||||
DWORD protoId; // object PID
|
||||
ProtoID protoId; // object PID
|
||||
long cid; // combat ID (don't change while in combat)
|
||||
long lightDistance;
|
||||
long lightIntensity;
|
||||
@@ -1000,24 +1000,16 @@ struct AIcap {
|
||||
long outline_color;
|
||||
long chance_message;
|
||||
long combat_message_data[24];
|
||||
long area_attack_mode;
|
||||
long run_away_mode;
|
||||
long best_weapon;
|
||||
long distance;
|
||||
long attack_who;
|
||||
long chem_use;
|
||||
AIpref::AreaAttack area_attack_mode;
|
||||
AIpref::RunAway run_away_mode;
|
||||
AIpref::WeaponPref pref_weapon;
|
||||
AIpref::Distance distance;
|
||||
AIpref::AttackWho attack_who;
|
||||
AIpref::ChemUse chem_use;
|
||||
long chem_primary_desire[3];
|
||||
long disposition;
|
||||
AIpref::Disposition disposition;
|
||||
const char* body_type; // unused
|
||||
const char* general_type; // unused
|
||||
|
||||
inline AIpref::distance getDistance() {
|
||||
return (AIpref::distance)distance;
|
||||
}
|
||||
inline AIpref::run_away_mode getRunAwayMode() {
|
||||
return (AIpref::run_away_mode)run_away_mode;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct Queue {
|
||||
|
||||
+10
-10
@@ -43,25 +43,25 @@ void __stdcall CombatAI::ai_check_drugs(fo::GameObject* source) {
|
||||
long hpPercent = 50;
|
||||
long chance = 0;
|
||||
|
||||
switch ((fo::AIpref::chem_use_mode)cap->chem_use) {
|
||||
case fo::AIpref::chem_use_mode::stims_when_hurt_little: // use only healing drugs
|
||||
switch (cap->chem_use) {
|
||||
case fo::AIpref::ChemUse::stims_when_hurt_little: // use only healing drugs
|
||||
hpPercent = 60;
|
||||
break;
|
||||
case fo::AIpref::chem_use_mode::stims_when_hurt_lots: // use only healing drugs
|
||||
case fo::AIpref::ChemUse::stims_when_hurt_lots: // use only healing drugs
|
||||
hpPercent = 30;
|
||||
break;
|
||||
case fo::AIpref::chem_use_mode::sometimes:
|
||||
case fo::AIpref::ChemUse::sometimes:
|
||||
if (!(fo::var::combatNumTurns % 3)) chance = 25; // every three turns
|
||||
//hpPercent = 50;
|
||||
break;
|
||||
case fo::AIpref::chem_use_mode::anytime:
|
||||
case fo::AIpref::ChemUse::anytime:
|
||||
if (!(fo::var::combatNumTurns % 3)) chance = 75; // every three turns
|
||||
//hpPercent = 50;
|
||||
break;
|
||||
case fo::AIpref::chem_use_mode::always:
|
||||
case fo::AIpref::ChemUse::always:
|
||||
chance = 100; // 99%
|
||||
break;
|
||||
case fo::AIpref::chem_use_mode::clean:
|
||||
case fo::AIpref::ChemUse::clean:
|
||||
return; // exit: don't use drugs
|
||||
}
|
||||
|
||||
@@ -136,9 +136,9 @@ void __stdcall CombatAI::ai_check_drugs(fo::GameObject* source) {
|
||||
source->critter.decreaseAP(aiUseItemAPCost);
|
||||
slot = -1;
|
||||
|
||||
fo::AIpref::chem_use_mode chemUse = (fo::AIpref::chem_use_mode)cap->chem_use;
|
||||
if (chemUse == fo::AIpref::chem_use_mode::sometimes ||
|
||||
(chemUse == fo::AIpref::chem_use_mode::anytime && usedCount >= 2))
|
||||
fo::AIpref::ChemUse chemUse = cap->chem_use;
|
||||
if (chemUse == fo::AIpref::ChemUse::sometimes ||
|
||||
(chemUse == fo::AIpref::ChemUse::anytime && usedCount >= 2))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ static long __fastcall CheckDisableBurst(fo::GameObject* critter, fo::GameObject
|
||||
return 10; // Disable Burst (area_attack_mode - non-existent value)
|
||||
}
|
||||
}
|
||||
return cap->area_attack_mode; // default engine code
|
||||
return (long)cap->area_attack_mode; // default engine code
|
||||
}
|
||||
|
||||
static void __declspec(naked) ai_pick_hit_mode_hack_noBurst() {
|
||||
|
||||
@@ -744,8 +744,8 @@ static void __fastcall action_attack_to(long unused, fo::GameObject* partyMember
|
||||
validTarget->outline = outlineColor;
|
||||
|
||||
fo::AIcap* cap = fo::func::ai_cap(partyMember);
|
||||
if (cap->disposition == fo::AIpref::disposition::custom) {
|
||||
cap->attack_who = (long)fo::AIpref::attack_who::whomever;
|
||||
if (cap->disposition == fo::AIpref::Disposition::custom) {
|
||||
cap->attack_who = fo::AIpref::AttackWho::whomever;
|
||||
}
|
||||
|
||||
// floating text messages
|
||||
|
||||
@@ -241,7 +241,7 @@ void op_set_weapon_ammo_pid(OpcodeContext& ctx) {
|
||||
if (fo::util::GetProto(obj->protoId, &proto)) {
|
||||
long type = proto->item.type;
|
||||
if (type == fo::ItemType::item_type_weapon || type == fo::ItemType::item_type_misc_item) {
|
||||
obj->item.ammoPid = ctx.arg(1).rawValue();
|
||||
obj->item.ammoPid = (fo::ProtoID)ctx.arg(1).rawValue();
|
||||
}
|
||||
} else {
|
||||
ctx.printOpcodeError(protoFailedLoad, ctx.getOpcodeName(), obj->protoId);
|
||||
@@ -490,22 +490,22 @@ void mf_get_object_ai_data(OpcodeContext& ctx) {
|
||||
value = cap->aggression;
|
||||
break;
|
||||
case 1:
|
||||
value = cap->area_attack_mode;
|
||||
value = (long)cap->area_attack_mode;
|
||||
break;
|
||||
case 2:
|
||||
value = cap->attack_who;
|
||||
value = (long)cap->attack_who;
|
||||
break;
|
||||
case 3:
|
||||
value = cap->best_weapon;
|
||||
value = (long)cap->pref_weapon;
|
||||
break;
|
||||
case 4:
|
||||
value = cap->chem_use;
|
||||
value = (long)cap->chem_use;
|
||||
break;
|
||||
case 5:
|
||||
value = cap->disposition;
|
||||
value = (long)cap->disposition;
|
||||
break;
|
||||
case 6:
|
||||
value = cap->distance;
|
||||
value = (long)cap->distance;
|
||||
break;
|
||||
case 7:
|
||||
value = cap->max_dist;
|
||||
@@ -520,7 +520,7 @@ void mf_get_object_ai_data(OpcodeContext& ctx) {
|
||||
value = cap->hurt_too_much; // DAM_BLIND/DAM_CRIP_* flags
|
||||
break;
|
||||
case 11:
|
||||
value = cap->run_away_mode;
|
||||
value = (long)cap->run_away_mode;
|
||||
break;
|
||||
case 12:
|
||||
value = cap->secondary_freq;
|
||||
|
||||
@@ -64,6 +64,7 @@ static void __declspec(naked) ai_can_use_weapon_hack() {
|
||||
using namespace fo;
|
||||
using namespace Fields;
|
||||
__asm {
|
||||
mov ebp, ebx;
|
||||
test dword ptr [esi + miscFlags], CantUse;
|
||||
jnz cantUse;
|
||||
mov eax, [edi + damageFlags];
|
||||
|
||||
@@ -292,6 +292,7 @@
|
||||
<ClInclude Include="FalloutEngine\Fallout2.h" />
|
||||
<ClInclude Include="FalloutEngine\FunctionOffsets.h" />
|
||||
<ClInclude Include="FalloutEngine\FunctionOffsets_def.h" />
|
||||
<ClInclude Include="FalloutEngine\GamePids.h" />
|
||||
<ClInclude Include="FalloutEngine\Structs.h" />
|
||||
<ClInclude Include="FalloutEngine\EngineUtils.h" />
|
||||
<ClInclude Include="FalloutEngine\VariableOffsets.h" />
|
||||
|
||||
@@ -437,6 +437,9 @@
|
||||
<ClInclude Include="Modules\SubModules\DirectDraw.h">
|
||||
<Filter>Modules\SubModules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FalloutEngine\GamePids.h">
|
||||
<Filter>FalloutEngine</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
|
||||
Reference in New Issue
Block a user