mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added class to most of modules
Added missing ReplacementFuncs.h.
This commit is contained in:
+2
-2
@@ -90,7 +90,7 @@ bool CRC(const char* filepath) {
|
||||
|
||||
DWORD size = GetFileSize(h, 0);
|
||||
|
||||
if (size != ExpectedSize && GetIntDefaultConfig("Debugging", "SkipSizeCheck", 0) == 0) {
|
||||
if (size != ExpectedSize && IniReader::GetIntDefaultConfig("Debugging", "SkipSizeCheck", 0) == 0) {
|
||||
CloseHandle(h);
|
||||
sprintf_s(buf, "You're trying to use sfall with an incompatible version of Fallout.\n"
|
||||
"Was expecting '" TARGETVERSION "'.\n\n"
|
||||
@@ -113,7 +113,7 @@ bool CRC(const char* filepath) {
|
||||
|
||||
bool matchedCRC = false;
|
||||
|
||||
std::vector<std::string> extraCrcList = GetListDefaultConfig("Debugging", "ExtraCRC", "", 512, ',');
|
||||
std::vector<std::string> extraCrcList = IniReader::GetListDefaultConfig("Debugging", "ExtraCRC", "", 512, ',');
|
||||
if (!extraCrcList.empty()) {
|
||||
matchedCRC = std::any_of(extraCrcList.begin(), extraCrcList.end(), [crc](const std::string& testCrcStr) -> bool {
|
||||
DWORD testedCrc = strtoul(testCrcStr.c_str(), 0, 16);
|
||||
|
||||
@@ -196,7 +196,7 @@ void CombatAI::init() {
|
||||
sf::SafeWrite8(0x429BE9, sf::CodeType::JumpNZ); // jz > jnz
|
||||
sf::SafeWrite8(0x429BF1, sf::CodeType::JumpShort); // jnz > jmp
|
||||
|
||||
drugUsePerfFixMode = sf::GetConfigInt("Misc", "AIDrugUsePerfFix", 0);
|
||||
drugUsePerfFixMode = sf::IniReader::GetConfigInt("Misc", "AIDrugUsePerfFix", 0);
|
||||
if (drugUsePerfFixMode > 0) sf::dlogr("Applying AI drug use preference fix.", DL_FIX);
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ DWORD __stdcall Inventory::adjust_fid() {
|
||||
if ((*fo::ptr::inven_dude)->TypeFid() == fo::OBJ_TYPE_CRITTER) {
|
||||
DWORD indexNum;
|
||||
DWORD weaponAnimCode = 0;
|
||||
if (sf::PartyControl_IsNpcControlled()) {
|
||||
if (sf::PartyControl::IsNpcControlled()) {
|
||||
// if NPC is under control, use current FID of critter
|
||||
indexNum = (*fo::ptr::inven_dude)->artFid & 0xFFF;
|
||||
} else {
|
||||
@@ -159,7 +159,7 @@ DWORD __stdcall Inventory::adjust_fid() {
|
||||
}
|
||||
*fo::ptr::i_fid = fid;
|
||||
// OnAdjustFid
|
||||
if (sf::appModEnabled) sf::AdjustHeroArmorArt(fid);
|
||||
if (sf::HeroAppearance::appModEnabled) sf::AdjustHeroArmorArt(fid);
|
||||
sf::AdjustFidHook(fid); // should be called last
|
||||
return *fo::ptr::i_fid;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ long __stdcall Items::item_weapon_range(fo::GameObject* source, fo::GameObject*
|
||||
long heaveHoMod = Stats::perk_level(source, fo::Perk::PERK_heave_ho);
|
||||
long stRange = fo::func::stat_level(source, fo::Stat::STAT_st);
|
||||
|
||||
if (sf::perkHeaveHoModTweak) {
|
||||
if (sf::Perks::perkHeaveHoModTweak) {
|
||||
stRange *= 3;
|
||||
if (stRange > range) stRange = range;
|
||||
return stRange + (heaveHoMod * 6);
|
||||
@@ -129,7 +129,7 @@ static long __stdcall item_w_mp_cost_sub(fo::GameObject* source, fo::GameObject*
|
||||
|
||||
long type = fo::func::item_w_subtype(item, hitMode);
|
||||
|
||||
if (source->protoId == fo::ProtoID::PID_Player && sf::DudeHasTrait(fo::Trait::TRAIT_fast_shot)) {
|
||||
if (source->protoId == fo::ProtoID::PID_Player && sf::Perks::DudeHasTrait(fo::Trait::TRAIT_fast_shot)) {
|
||||
// Alternative behaviors of the Fast Shot trait
|
||||
if (item && fastShotTweak > 2) { // Fallout 1 behavior (allowed for all weapons)
|
||||
cost--;
|
||||
@@ -217,7 +217,7 @@ long __fastcall Items::item_w_mp_cost(fo::GameObject* source, fo::AttackType hit
|
||||
// unarmed hits
|
||||
long cost = unarmedAPCost;
|
||||
if (hitMode == fo::AttackType::ATKTYPE_PUNCH || hitMode == fo::AttackType::ATKTYPE_KICK || hitMode >= fo::AttackType::ATKTYPE_STRONGPUNCH) {
|
||||
cost = sf::Unarmed_GetHitAPCost(hitMode);
|
||||
cost = sf::Unarmed::GetHitAPCost(hitMode);
|
||||
}
|
||||
|
||||
// return cost
|
||||
@@ -248,7 +248,7 @@ void Items::init() {
|
||||
// Replace the item_w_mp_cost_ function with the sfall implementation
|
||||
sf::MakeJump(fo::funcoffs::item_w_mp_cost_ + 1, item_w_mp_cost_hack); // 0x478B25
|
||||
|
||||
fastShotTweak = sf::GetConfigInt("Misc", "FastShotFix", 0);
|
||||
fastShotTweak = sf::IniReader::GetConfigInt("Misc", "FastShotFix", 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ static void __stdcall Draw(fo::Window* win, BYTE* surface, long width, long heig
|
||||
}
|
||||
|
||||
if (!win->randY) return;
|
||||
surface = &sf::WinRender_GetOverlaySurface(win)[rect.left - win->rect.x] + ((rect.top - win->rect.y) * win->width);
|
||||
surface = &sf::WindowRender::GetOverlaySurface(win)[rect.left - win->rect.x] + ((rect.top - win->rect.y) * win->width);
|
||||
|
||||
if (toBuffer) {
|
||||
fo::func::trans_buf_to_buf(surface, width, height, widthFrom, &toBuffer[rect.left - updateRect->left] + ((rect.top - updateRect->top) * toWidth), toWidth);
|
||||
@@ -58,7 +58,7 @@ void __fastcall Render::GNW_win_refresh(fo::Window* win, RECT* updateRect, BYTE*
|
||||
}*/
|
||||
int h = (updateRect->bottom - updateRect->top) + 1;
|
||||
|
||||
sf::UpdateDDSurface(GetBuffer(), w, h, w, updateRect); // update the entire rectangle area
|
||||
sf::Graphics::UpdateDDSurface(GetBuffer(), w, h, w, updateRect); // update the entire rectangle area
|
||||
|
||||
} else {
|
||||
fo::func::mouse_show(); // for updating background cursor area
|
||||
@@ -81,7 +81,7 @@ void __fastcall Render::GNW_win_refresh(fo::Window* win, RECT* updateRect, BYTE*
|
||||
int wRect = (rects->wRect.right - rects->wRect.left) + 1;
|
||||
int hRect = (rects->wRect.bottom - rects->wRect.top) + 1;
|
||||
|
||||
sf::UpdateDDSurface(&GetBuffer()[rects->wRect.left - updateRect->left] + (rects->wRect.top - updateRect->top) * w, wRect, hRect, w, &rects->wRect);
|
||||
sf::Graphics::UpdateDDSurface(&GetBuffer()[rects->wRect.left - updateRect->left] + (rects->wRect.top - updateRect->top) * w, wRect, hRect, w, &rects->wRect);
|
||||
|
||||
fo::RectList* free = rects;
|
||||
rects = rects->nextRect;
|
||||
@@ -117,7 +117,7 @@ void __fastcall Render::GNW_win_refresh(fo::Window* win, RECT* updateRect, BYTE*
|
||||
}
|
||||
|
||||
int widthFrom = win->width;
|
||||
int toWidth = (toBuffer) ? (updateRect->right - updateRect->left) + 1 : sf::Gfx_GetGameWidthRes();
|
||||
int toWidth = (toBuffer) ? (updateRect->right - updateRect->left) + 1 : sf::Graphics::GetGameWidthRes();
|
||||
|
||||
fo::func::win_clip(win, &rects, toBuffer);
|
||||
|
||||
@@ -153,7 +153,7 @@ void __fastcall Render::GNW_win_refresh(fo::Window* win, RECT* updateRect, BYTE*
|
||||
int height = (rects->rect.offy - rects->rect.y) + 1;
|
||||
int widthFrom = toWidth;
|
||||
|
||||
sf::UpdateDDSurface(&GetBuffer()[rects->rect.x] + (rects->rect.y * widthFrom), width, height, widthFrom, &rects->wRect);
|
||||
sf::Graphics::UpdateDDSurface(&GetBuffer()[rects->rect.x] + (rects->rect.y * widthFrom), width, height, widthFrom, &rects->wRect);
|
||||
}
|
||||
fo::RectList* next = rects->nextRect;
|
||||
fo::util::rect_free(rects);
|
||||
|
||||
@@ -20,14 +20,14 @@ namespace sf = sfall;
|
||||
|
||||
int __stdcall Skills::trait_adjust_skill(DWORD skillID) {
|
||||
int result = 0;
|
||||
if (sf::TraitsModEnable()) {
|
||||
if (fo::ptr::pc_trait[0] != -1) result += sf::GetTraitSkillBonus(skillID, 0);
|
||||
if (fo::ptr::pc_trait[1] != -1) result += sf::GetTraitSkillBonus(skillID, 1);
|
||||
if (sf::Perks::TraitsModEnable()) {
|
||||
if (fo::ptr::pc_trait[0] != -1) result += sf::Perks::GetTraitSkillBonus(skillID, 0);
|
||||
if (fo::ptr::pc_trait[1] != -1) result += sf::Perks::GetTraitSkillBonus(skillID, 1);
|
||||
}
|
||||
|
||||
if (sf::DudeHasTrait(fo::TRAIT_gifted)) result -= 10;
|
||||
if (sf::Perks::DudeHasTrait(fo::TRAIT_gifted)) result -= 10;
|
||||
|
||||
if (sf::DudeHasTrait(fo::TRAIT_good_natured)) {
|
||||
if (sf::Perks::DudeHasTrait(fo::TRAIT_good_natured)) {
|
||||
if (skillID <= fo::SKILL_THROWING) {
|
||||
result -= 10;
|
||||
} else if (skillID == fo::SKILL_FIRST_AID || skillID == fo::SKILL_DOCTOR || skillID == fo::SKILL_CONVERSANT || skillID == fo::SKILL_BARTER) {
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace sf = sfall;
|
||||
static bool smallFrameTraitFix = false;
|
||||
|
||||
int __stdcall Stats::trait_level(DWORD traitID) {
|
||||
return sf::DudeHasTrait(traitID);
|
||||
return sf::Perks::DudeHasTrait(traitID);
|
||||
}
|
||||
|
||||
// Wrapper of perk_level_ function, for quickly skipping other critters
|
||||
@@ -36,9 +36,9 @@ int __stdcall Stats::trait_adjust_stat(DWORD statID) {
|
||||
if (statID > fo::STAT_max_derived) return 0;
|
||||
|
||||
int result = 0;
|
||||
if (sf::TraitsModEnable()) {
|
||||
if (fo::ptr::pc_trait[0] != -1) result += sf::GetTraitStatBonus(statID, 0);
|
||||
if (fo::ptr::pc_trait[1] != -1) result += sf::GetTraitStatBonus(statID, 1);
|
||||
if (sf::Perks::TraitsModEnable()) {
|
||||
if (fo::ptr::pc_trait[0] != -1) result += sf::Perks::GetTraitStatBonus(statID, 0);
|
||||
if (fo::ptr::pc_trait[1] != -1) result += sf::Perks::GetTraitStatBonus(statID, 1);
|
||||
}
|
||||
|
||||
switch (statID) {
|
||||
@@ -124,7 +124,7 @@ void Stats::init() {
|
||||
sf::MakeJump(fo::funcoffs::trait_adjust_stat_, trait_adjust_stat_replacement); // 0x4B3C7C
|
||||
|
||||
// Fix the carry weight penalty of the Small Frame trait not being applied to bonus Strength points
|
||||
smallFrameTraitFix = (sf::GetConfigInt("Misc", "SmallFrameFix", 0) != 0);
|
||||
smallFrameTraitFix = (sf::IniReader::GetConfigInt("Misc", "SmallFrameFix", 0) != 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+17
-17
@@ -23,7 +23,7 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
DWORD modifiedIni;
|
||||
DWORD IniReader::modifiedIni;
|
||||
|
||||
static const char* ddrawIni = ".\\ddraw.ini";
|
||||
static char ini[65] = ".\\";
|
||||
@@ -50,67 +50,67 @@ static std::vector<std::string> __stdcall getList(const char* section, const cha
|
||||
return list;
|
||||
}
|
||||
|
||||
const char* GetConfigFile() {
|
||||
const char* IniReader::GetConfigFile() {
|
||||
return ini;
|
||||
}
|
||||
|
||||
void SetDefaultConfigFile() {
|
||||
void IniReader::SetDefaultConfigFile() {
|
||||
std::strcpy(&ini[2], &ddrawIni[2]);
|
||||
}
|
||||
|
||||
void SetConfigFile(const char* iniFile) {
|
||||
void IniReader::SetConfigFile(const char* iniFile) {
|
||||
strcat_s(ini, iniFile);
|
||||
}
|
||||
|
||||
int __stdcall GetIntDefaultConfig(const char* section, const char* setting, int defaultValue) {
|
||||
int __stdcall IniReader::GetIntDefaultConfig(const char* section, const char* setting, int defaultValue) {
|
||||
return getInt(section, setting, defaultValue, ddrawIni);
|
||||
}
|
||||
|
||||
std::vector<std::string> __stdcall GetListDefaultConfig(const char* section, const char* setting, const char* defaultValue, size_t bufSize, char delimiter) {
|
||||
std::vector<std::string> __stdcall IniReader::GetListDefaultConfig(const char* section, const char* setting, const char* defaultValue, size_t bufSize, char delimiter) {
|
||||
return getList(section, setting, defaultValue, bufSize, delimiter, ddrawIni);
|
||||
}
|
||||
|
||||
int __stdcall GetConfigInt(const char* section, const char* setting, int defaultValue) {
|
||||
int __stdcall IniReader::GetConfigInt(const char* section, const char* setting, int defaultValue) {
|
||||
return getInt(section, setting, defaultValue, ini);
|
||||
}
|
||||
|
||||
std::string __stdcall GetConfigString(const char* section, const char* setting, const char* defaultValue, size_t bufSize) {
|
||||
std::string __stdcall IniReader::GetConfigString(const char* section, const char* setting, const char* defaultValue, size_t bufSize) {
|
||||
return trim(getString(section, setting, defaultValue, bufSize, ini));
|
||||
}
|
||||
|
||||
size_t __stdcall GetConfigString(const char* section, const char* setting, const char* defaultValue, char* buf, size_t bufSize) {
|
||||
size_t __stdcall IniReader::GetConfigString(const char* section, const char* setting, const char* defaultValue, char* buf, size_t bufSize) {
|
||||
return getString(section, setting, defaultValue, buf, bufSize, ini);
|
||||
}
|
||||
|
||||
std::vector<std::string> __stdcall GetConfigList(const char* section, const char* setting, const char* defaultValue, size_t bufSize) {
|
||||
std::vector<std::string> __stdcall IniReader::GetConfigList(const char* section, const char* setting, const char* defaultValue, size_t bufSize) {
|
||||
return getList(section, setting, defaultValue, bufSize, ',', ini);
|
||||
}
|
||||
|
||||
int __stdcall IniGetInt(const char* section, const char* setting, int defaultValue, const char* iniFile) {
|
||||
int __stdcall IniReader::GetInt(const char* section, const char* setting, int defaultValue, const char* iniFile) {
|
||||
return getInt(section, setting, defaultValue, iniFile);
|
||||
}
|
||||
|
||||
size_t __stdcall IniGetString(const char* section, const char* setting, const char* defaultValue, char* buf, size_t bufSize, const char* iniFile) {
|
||||
size_t __stdcall IniReader::GetString(const char* section, const char* setting, const char* defaultValue, char* buf, size_t bufSize, const char* iniFile) {
|
||||
return getString(section, setting, defaultValue, buf, bufSize, iniFile);
|
||||
}
|
||||
|
||||
std::string __stdcall IniGetString(const char* section, const char* setting, const char* defaultValue, size_t bufSize, const char* iniFile) {
|
||||
std::string __stdcall IniReader::GetString(const char* section, const char* setting, const char* defaultValue, size_t bufSize, const char* iniFile) {
|
||||
return getString(section, setting, defaultValue, bufSize, iniFile);
|
||||
}
|
||||
|
||||
std::vector<std::string> __stdcall IniGetList(const char* section, const char* setting, const char* defaultValue, size_t bufSize, char delimiter, const char* iniFile) {
|
||||
std::vector<std::string> __stdcall IniReader::GetList(const char* section, const char* setting, const char* defaultValue, size_t bufSize, char delimiter, const char* iniFile) {
|
||||
return getList(section, setting, defaultValue, bufSize, delimiter, iniFile);
|
||||
}
|
||||
|
||||
int __stdcall SetConfigInt(const char* section, const char* setting, int value) {
|
||||
int __stdcall IniReader::SetConfigInt(const char* section, const char* setting, int value) {
|
||||
char buf[33];
|
||||
_itoa_s(value, buf, 33, 10);
|
||||
int result = WritePrivateProfileStringA(section, setting, buf, ini);
|
||||
return result;
|
||||
}
|
||||
|
||||
void IniReader_Init() {
|
||||
modifiedIni = GetConfigInt("Main", "ModifiedIni", 0);
|
||||
void IniReader::init() {
|
||||
modifiedIni = IniReader::GetConfigInt("Main", "ModifiedIni", 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+29
-26
@@ -21,44 +21,47 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
extern DWORD modifiedIni;
|
||||
class IniReader {
|
||||
public:
|
||||
static void init();
|
||||
|
||||
void IniReader_Init();
|
||||
static DWORD modifiedIni;
|
||||
|
||||
const char* GetConfigFile();
|
||||
void SetDefaultConfigFile();
|
||||
void SetConfigFile(const char* iniFile);
|
||||
static const char* GetConfigFile();
|
||||
static void SetDefaultConfigFile();
|
||||
static void SetConfigFile(const char* iniFile);
|
||||
|
||||
// Gets the integer value from the default config (i.e. ddraw.ini)
|
||||
int __stdcall GetIntDefaultConfig(const char* section, const char* setting, int defaultValue);
|
||||
// Gets the integer value from the default config (i.e. ddraw.ini)
|
||||
static int __stdcall GetIntDefaultConfig(const char* section, const char* setting, int defaultValue);
|
||||
|
||||
// Gets a list of values separated by the delimiter from the default config (i.e. ddraw.ini)
|
||||
std::vector<std::string> __stdcall GetListDefaultConfig(const char* section, const char* setting, const char* defaultValue, size_t bufSize, char delimiter);
|
||||
// Gets a list of values separated by the delimiter from the default config (i.e. ddraw.ini)
|
||||
static std::vector<std::string> __stdcall GetListDefaultConfig(const char* section, const char* setting, const char* defaultValue, size_t bufSize, char delimiter);
|
||||
|
||||
// Gets the integer value from sfall configuration INI file
|
||||
int __stdcall GetConfigInt(const char* section, const char* setting, int defaultValue);
|
||||
// Gets the integer value from sfall configuration INI file
|
||||
static int __stdcall GetConfigInt(const char* section, const char* setting, int defaultValue);
|
||||
|
||||
// Gets the string value from sfall configuration INI file with trim function
|
||||
std::string __stdcall GetConfigString(const char* section, const char* setting, const char* defaultValue, size_t bufSize = 128);
|
||||
// Gets the string value from sfall configuration INI file with trim function
|
||||
static std::string __stdcall GetConfigString(const char* section, const char* setting, const char* defaultValue, size_t bufSize = 128);
|
||||
|
||||
// Loads the string value from sfall configuration INI file into the provided buffer
|
||||
size_t __stdcall GetConfigString(const char* section, const char* setting, const char* defaultValue, char* buffer, size_t bufSize = 128);
|
||||
// Loads the string value from sfall configuration INI file into the provided buffer
|
||||
static size_t __stdcall GetConfigString(const char* section, const char* setting, const char* defaultValue, char* buffer, size_t bufSize = 128);
|
||||
|
||||
// Parses the comma-separated list from the settings from sfall configuration INI file
|
||||
std::vector<std::string> __stdcall GetConfigList(const char* section, const char* setting, const char* defaultValue, size_t bufSize = 128);
|
||||
// Parses the comma-separated list from the settings from sfall configuration INI file
|
||||
static std::vector<std::string> __stdcall GetConfigList(const char* section, const char* setting, const char* defaultValue, size_t bufSize = 128);
|
||||
|
||||
// Gets the integer value from given INI file
|
||||
int __stdcall IniGetInt(const char* section, const char* setting, int defaultValue, const char* iniFile);
|
||||
// Gets the integer value from given INI file
|
||||
static int __stdcall GetInt(const char* section, const char* setting, int defaultValue, const char* iniFile);
|
||||
|
||||
// Gets the string value from given INI file
|
||||
size_t __stdcall IniGetString(const char* section, const char* setting, const char* defaultValue, char* buf, size_t bufSize, const char* iniFile);
|
||||
// Gets the string value from given INI file
|
||||
static size_t __stdcall GetString(const char* section, const char* setting, const char* defaultValue, char* buf, size_t bufSize, const char* iniFile);
|
||||
|
||||
// Gets the string value from given INI file
|
||||
std::string __stdcall IniGetString(const char* section, const char* setting, const char* defaultValue, size_t bufSize, const char* iniFile);
|
||||
// Gets the string value from given INI file
|
||||
static std::string __stdcall GetString(const char* section, const char* setting, const char* defaultValue, size_t bufSize, const char* iniFile);
|
||||
|
||||
// Parses the comma-separated list setting from given INI file
|
||||
std::vector<std::string> __stdcall IniGetList(const char* section, const char* setting, const char* defaultValue, size_t bufSize, char delimiter, const char* iniFile);
|
||||
// Parses the comma-separated list setting from given INI file
|
||||
static std::vector<std::string> __stdcall GetList(const char* section, const char* setting, const char* defaultValue, size_t bufSize, char delimiter, const char* iniFile);
|
||||
|
||||
int __stdcall SetConfigInt(const char* section, const char* setting, int value);
|
||||
static int __stdcall SetConfigInt(const char* section, const char* setting, int value);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+10
-10
@@ -194,7 +194,7 @@ public:
|
||||
|
||||
// Only called for the mouse
|
||||
HRESULT __stdcall GetDeviceState(DWORD a, LPVOID b) {
|
||||
Gfx_RefreshGraphics();
|
||||
Graphics::RefreshGraphics();
|
||||
if (DeviceType != kDeviceType_MOUSE) {
|
||||
return RealDevice->GetDeviceState(a, b);
|
||||
}
|
||||
@@ -301,8 +301,8 @@ public:
|
||||
keysDown[buf[i].dwOfs] = state;
|
||||
}
|
||||
// OnKeyPressed
|
||||
InventoryKeyPressedHook(buf[i].dwOfs, (state > 0));
|
||||
DebugEditorKeyPressedHook(buf[i].dwOfs, (state > 0));
|
||||
Inventory::KeyPressedHook(buf[i].dwOfs, (state > 0));
|
||||
DebugEditor::KeyPressedHook(buf[i].dwOfs, (state > 0));
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
@@ -428,20 +428,20 @@ public:
|
||||
};
|
||||
|
||||
inline void InitInputFeatures() {
|
||||
reverseMouse = GetConfigInt("Input", "ReverseMouseButtons", 0) != 0;
|
||||
useScrollWheel = GetConfigInt("Input", "UseScrollWheel", 1) != 0;
|
||||
wheelMod = GetConfigInt("Input", "ScrollMod", 0);
|
||||
reverseMouse = IniReader::GetConfigInt("Input", "ReverseMouseButtons", 0) != 0;
|
||||
useScrollWheel = IniReader::GetConfigInt("Input", "UseScrollWheel", 1) != 0;
|
||||
wheelMod = IniReader::GetConfigInt("Input", "ScrollMod", 0);
|
||||
|
||||
long MouseSpeed = GetConfigInt("Input", "MouseSensitivity", 100);
|
||||
long MouseSpeed = IniReader::GetConfigInt("Input", "MouseSensitivity", 100);
|
||||
if (MouseSpeed != 100) {
|
||||
adjustMouseSpeed = true;
|
||||
mouseSpeedMod = ((double)MouseSpeed) / 100.0;
|
||||
}
|
||||
|
||||
middleMouseKey = GetConfigInt("Input", "MiddleMouse", DIK_B);
|
||||
middleMouseKey = IniReader::GetConfigInt("Input", "MiddleMouse", DIK_B);
|
||||
|
||||
backgroundKeyboard = GetConfigInt("Input", "BackgroundKeyboard", 0) != 0;
|
||||
backgroundMouse = GetConfigInt("Input", "BackgroundMouse", 0) != 0;
|
||||
backgroundKeyboard = IniReader::GetConfigInt("Input", "BackgroundKeyboard", 0) != 0;
|
||||
backgroundMouse = IniReader::GetConfigInt("Input", "BackgroundMouse", 0) != 0;
|
||||
|
||||
keyboardLayout = GetKeyboardLayout(0);
|
||||
}
|
||||
|
||||
+5
-5
@@ -80,19 +80,19 @@ void devlog_f(...) {}
|
||||
void LoggingInit() {
|
||||
Log.open("sfall-log.txt", std::ios_base::out | std::ios_base::trunc);
|
||||
|
||||
if (GetIntDefaultConfig("Debugging", "Init", 0)) {
|
||||
if (IniReader::GetIntDefaultConfig("Debugging", "Init", 0)) {
|
||||
DebugTypes |= DL_INIT;
|
||||
}
|
||||
if (GetIntDefaultConfig("Debugging", "Hook", 0)) {
|
||||
if (IniReader::GetIntDefaultConfig("Debugging", "Hook", 0)) {
|
||||
DebugTypes |= DL_HOOK;
|
||||
}
|
||||
if (GetIntDefaultConfig("Debugging", "Script", 0)) {
|
||||
if (IniReader::GetIntDefaultConfig("Debugging", "Script", 0)) {
|
||||
DebugTypes |= DL_SCRIPT;
|
||||
}
|
||||
if (GetIntDefaultConfig("Debugging", "Criticals", 0)) {
|
||||
if (IniReader::GetIntDefaultConfig("Debugging", "Criticals", 0)) {
|
||||
DebugTypes |= DL_CRITICALS;
|
||||
}
|
||||
if (GetIntDefaultConfig("Debugging", "Fixes", 0)) {
|
||||
if (IniReader::GetIntDefaultConfig("Debugging", "Fixes", 0)) {
|
||||
DebugTypes |= DL_FIX;
|
||||
}
|
||||
}
|
||||
|
||||
+15
-15
@@ -40,7 +40,7 @@ static std::tr1::unordered_map<fo::GameObject*, fo::GameObject*> sources;
|
||||
////////////////////////////////// AI HELPERS //////////////////////////////////
|
||||
|
||||
// Returns the friendly critter or any blocking object in the line of fire
|
||||
fo::GameObject* __stdcall AIHelpers_CheckShootAndFriendlyInLineOfFire(fo::GameObject* object, long targetTile, long team) {
|
||||
fo::GameObject* __stdcall AIHelpers::CheckShootAndFriendlyInLineOfFire(fo::GameObject* object, long targetTile, long team) {
|
||||
if (object && object->IsCritter() && object->critter.teamNum != team) { // is not friendly fire
|
||||
long objTile = object->tile;
|
||||
if (objTile == targetTile) return nullptr;
|
||||
@@ -54,26 +54,26 @@ fo::GameObject* __stdcall AIHelpers_CheckShootAndFriendlyInLineOfFire(fo::GameOb
|
||||
fo::GameObject* obj = object; // for ignoring the object (multihex) when building the path
|
||||
fo::func::make_straight_path_func(object, objTile, targetTile, 0, (DWORD*)&obj, 0x20, (void*)fo::funcoffs::obj_shoot_blocking_at_);
|
||||
|
||||
object = AIHelpers_CheckShootAndFriendlyInLineOfFire(obj, targetTile, team);
|
||||
object = CheckShootAndFriendlyInLineOfFire(obj, targetTile, team);
|
||||
}
|
||||
return object; // friendly critter, any object or null
|
||||
}
|
||||
|
||||
// Returns the friendly critter in the line of fire
|
||||
fo::GameObject* __stdcall AIHelpers_CheckFriendlyFire(fo::GameObject* target, fo::GameObject* attacker) {
|
||||
fo::GameObject* __stdcall AIHelpers::CheckFriendlyFire(fo::GameObject* target, fo::GameObject* attacker) {
|
||||
fo::GameObject* object = nullptr;
|
||||
fo::func::make_straight_path_func(attacker, attacker->tile, target->tile, 0, (DWORD*)&object, 0x20, (void*)fo::funcoffs::obj_shoot_blocking_at_);
|
||||
object = AIHelpers_CheckShootAndFriendlyInLineOfFire(object, target->tile, attacker->critter.teamNum);
|
||||
object = CheckShootAndFriendlyInLineOfFire(object, target->tile, attacker->critter.teamNum);
|
||||
return (object && object->IsCritter()) ? object : nullptr; // 0 - if there are no friendly critters
|
||||
}
|
||||
|
||||
bool __stdcall AIHelpers_AttackInRange(fo::GameObject* source, fo::GameObject* weapon, long distance) {
|
||||
bool __stdcall AIHelpers::AttackInRange(fo::GameObject* source, fo::GameObject* weapon, long distance) {
|
||||
if (game::Items::item_weapon_range(source, weapon, fo::AttackType::ATKTYPE_RWEAPON_PRIMARY) >= distance) return true;
|
||||
return (game::Items::item_weapon_range(source, weapon, fo::AttackType::ATKTYPE_RWEAPON_SECONDARY) >= distance);
|
||||
}
|
||||
|
||||
bool __stdcall AIHelpers_AttackInRange(fo::GameObject* source, fo::GameObject* weapon, fo::GameObject* target) {
|
||||
return AIHelpers_AttackInRange(source, weapon, fo::func::obj_dist(source, target));
|
||||
bool __stdcall AIHelpers::AttackInRange(fo::GameObject* source, fo::GameObject* weapon, fo::GameObject* target) {
|
||||
return AIHelpers::AttackInRange(source, weapon, fo::func::obj_dist(source, target));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -289,7 +289,7 @@ static long __fastcall ai_try_attack_switch_fix(fo::GameObject* target, long &hi
|
||||
// is using a close range weapon?
|
||||
long wType = fo::func::item_w_subtype(item, fo::AttackType::ATKTYPE_RWEAPON_PRIMARY);
|
||||
if (wType <= fo::AttackSubType::MELEE) { // unarmed and melee weapons, check the distance before switching
|
||||
if (!AIHelpers_AttackInRange(source, item, target)) return -1; // target out of range, exit ai_try_attack_
|
||||
if (!AIHelpers::AttackInRange(source, item, target)) return -1; // target out of range, exit ai_try_attack_
|
||||
}
|
||||
return 1; // all good, execute vanilla behavior of ai_switch_weapons_ function
|
||||
}
|
||||
@@ -534,7 +534,7 @@ fix:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool __fastcall RollFriendlyFire(fo::GameObject* target, fo::GameObject* attacker) {
|
||||
if (AIHelpers_CheckFriendlyFire(target, attacker)) {
|
||||
if (AIHelpers::CheckFriendlyFire(target, attacker)) {
|
||||
long dice = fo::func::roll_random(1, 10);
|
||||
return (fo::func::stat_level(attacker, fo::STAT_iq) >= dice); // true - is friendly
|
||||
}
|
||||
@@ -612,19 +612,19 @@ static void __declspec(naked) combat_attack_hook() {
|
||||
}
|
||||
}
|
||||
|
||||
void AICombatClear() {
|
||||
void AI::AICombatClear() {
|
||||
targets.clear();
|
||||
sources.clear();
|
||||
}
|
||||
|
||||
void AI_Init() {
|
||||
void AI::init() {
|
||||
const DWORD combatAttackAddr[] = {
|
||||
0x426A95, // combat_attack_this_
|
||||
0x42A796 // ai_attack_
|
||||
};
|
||||
HookCalls(combat_attack_hook, combatAttackAddr);
|
||||
|
||||
RetryCombatMinAP = GetConfigInt("Misc", "NPCsTryToSpendExtraAP", 0);
|
||||
RetryCombatMinAP = IniReader::GetConfigInt("Misc", "NPCsTryToSpendExtraAP", 0);
|
||||
if (RetryCombatMinAP > 0) {
|
||||
dlog("Applying retry combat patch.", DL_INIT);
|
||||
HookCall(0x422B94, RetryCombatHook); // combat_turn_
|
||||
@@ -633,7 +633,7 @@ void AI_Init() {
|
||||
|
||||
/////////////////////// Combat behavior AI fixes ///////////////////////
|
||||
#ifndef NDEBUG
|
||||
if (GetIntDefaultConfig("Debugging", "AIFixes", 1) == 0) return;
|
||||
if (IniReader::GetIntDefaultConfig("Debugging", "AIFixes", 1) == 0) return;
|
||||
#endif
|
||||
|
||||
// Fix for NPCs not fully reloading a weapon if it has an ammo capacity more than a box of ammo
|
||||
@@ -708,12 +708,12 @@ void AI_Init() {
|
||||
MakeCall(0x42A8D9, ai_try_attack_hack_check_safe_weapon);
|
||||
}
|
||||
|
||||
fo::GameObject* __stdcall AIGetLastAttacker(fo::GameObject* target) {
|
||||
fo::GameObject* __stdcall AI::AIGetLastAttacker(fo::GameObject* target) {
|
||||
iter itr = sources.find(target);
|
||||
return (itr != sources.end()) ? itr->second : 0;
|
||||
}
|
||||
|
||||
fo::GameObject* __stdcall AIGetLastTarget(fo::GameObject* source) {
|
||||
fo::GameObject* __stdcall AI::AIGetLastTarget(fo::GameObject* source) {
|
||||
iter itr = targets.find(source);
|
||||
return (itr != targets.end()) ? itr->second : 0;
|
||||
}
|
||||
|
||||
+18
-10
@@ -23,19 +23,27 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
void AI_Init();
|
||||
void AICombatClear();
|
||||
class AI {
|
||||
public:
|
||||
static const char* name() { return "AI"; }
|
||||
static void init();
|
||||
|
||||
// Returns the friendly critter or any blocking object in the line of fire
|
||||
fo::GameObject* __stdcall AIHelpers_CheckShootAndFriendlyInLineOfFire(fo::GameObject* object, long targetTile, long team);
|
||||
static void AICombatClear();
|
||||
|
||||
// Returns the friendly critter in the line of fire
|
||||
fo::GameObject* __stdcall AIHelpers_CheckFriendlyFire(fo::GameObject* target, fo::GameObject* attacker);
|
||||
static fo::GameObject* __stdcall AIGetLastAttacker(fo::GameObject* target);
|
||||
static fo::GameObject* __stdcall AIGetLastTarget(fo::GameObject* source);
|
||||
};
|
||||
|
||||
bool __stdcall AIHelpers_AttackInRange(fo::GameObject* source, fo::GameObject* weapon, long distance);
|
||||
bool __stdcall AIHelpers_AttackInRange(fo::GameObject* source, fo::GameObject* weapon, fo::GameObject* target);
|
||||
class AIHelpers {
|
||||
public:
|
||||
// Returns the friendly critter or any blocking object in the line of fire
|
||||
static fo::GameObject* __stdcall CheckShootAndFriendlyInLineOfFire(fo::GameObject* object, long targetTile, long team);
|
||||
|
||||
fo::GameObject* __stdcall AIGetLastAttacker(fo::GameObject* target);
|
||||
fo::GameObject* __stdcall AIGetLastTarget(fo::GameObject* source);
|
||||
// Returns the friendly critter in the line of fire
|
||||
static fo::GameObject* __stdcall CheckFriendlyFire(fo::GameObject* target, fo::GameObject* attacker);
|
||||
|
||||
static bool __stdcall AttackInRange(fo::GameObject* source, fo::GameObject* weapon, long distance);
|
||||
static bool __stdcall AttackInRange(fo::GameObject* source, fo::GameObject* weapon, fo::GameObject* target);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -392,13 +392,13 @@ isLock:
|
||||
}
|
||||
}
|
||||
|
||||
void ClearAllLockAnimSets() {
|
||||
static void ClearAllLock() {
|
||||
std::fill(lockAnimSet.begin(), lockAnimSet.end(), 0);
|
||||
}
|
||||
|
||||
static void __declspec(naked) anim_stop_hack() {
|
||||
__asm {
|
||||
call ClearAllLockAnimSets;
|
||||
call ClearAllLock;
|
||||
mov edx, 1;
|
||||
retn;
|
||||
}
|
||||
@@ -507,7 +507,7 @@ notDude:
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyAnimationsAtOncePatches(signed char aniMax) {
|
||||
static void ApplyAnimationsAtOncePatches(signed char aniMax) {
|
||||
//allocate memory to store larger animation struct arrays
|
||||
sf_anim_set.resize(aniMax + 1); // include a dummy
|
||||
sf_sad.resize(aniMax + 1); // -8?
|
||||
@@ -562,8 +562,12 @@ void ApplyAnimationsAtOncePatches(signed char aniMax) {
|
||||
SafeWriteBatch<DWORD>((DWORD)&animSad->pathData[0].tile, sad_28);
|
||||
}
|
||||
|
||||
void Animations_Init() {
|
||||
animationLimit = GetConfigInt("Misc", "AnimationsAtOnceLimit", 32);
|
||||
void Animations::OnGameLoad() {
|
||||
ClearAllLock();
|
||||
}
|
||||
|
||||
void Animations::init() {
|
||||
animationLimit = IniReader::GetConfigInt("Misc", "AnimationsAtOnceLimit", 32);
|
||||
if (animationLimit < 32) animationLimit = 32;
|
||||
if (animationLimit > 32) {
|
||||
if (animationLimit > 127) animationLimit = 127;
|
||||
@@ -610,7 +614,7 @@ void Animations_Init() {
|
||||
MakeCall(0x419A17, art_alias_fid_hack);
|
||||
|
||||
// Fix for grave type containers in the open state not executing the use_p_proc procedure
|
||||
if (GetConfigInt("Misc", "GraveContainersFix", 0)) {
|
||||
if (IniReader::GetConfigInt("Misc", "GraveContainersFix", 0)) {
|
||||
dlog("Applying grave type containers fix.", DL_INIT);
|
||||
HookCall(0x49CFAC, obj_use_container_hook);
|
||||
SafeWrite16(0x4122D9, 0x9090); // action_get_an_object_
|
||||
@@ -618,7 +622,7 @@ void Animations_Init() {
|
||||
}
|
||||
}
|
||||
|
||||
//void Animations_Exit() {
|
||||
//void Animations::exit() {
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,8 +21,13 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
void Animations_Init();
|
||||
//void Animations_Exit();
|
||||
void ClearAllLockAnimSets();
|
||||
class Animations {
|
||||
public:
|
||||
static const char* name() { return "Animations"; }
|
||||
static void init();
|
||||
//static void exit();
|
||||
|
||||
static void OnGameLoad();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+24
-24
@@ -25,7 +25,7 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
static int boxCount; // current box count
|
||||
int BarBoxes::boxCount; // current box count
|
||||
static int totalBoxCount, actualBoxCount; // total boxes and w/o vanilla
|
||||
static int initCount = 5; // init config counter (5 - vanilla box)
|
||||
static int sizeBox, setBoxIndex = 5;
|
||||
@@ -165,11 +165,7 @@ static void ResetBoxes() {
|
||||
//SafeWriteBytes(0x461243, restoreData, 5);
|
||||
}
|
||||
|
||||
int __stdcall BarBoxes_MaxBox() {
|
||||
return boxCount - 1;
|
||||
}
|
||||
|
||||
void __stdcall BarBoxes_SetText(int box, const char* text, DWORD color) {
|
||||
void __stdcall BarBoxes::SetText(int box, const char* text, DWORD color) {
|
||||
setBoxIndex = box;
|
||||
boxes[box].colour = color;
|
||||
box -= 5;
|
||||
@@ -227,8 +223,8 @@ static void SetEngine(int count) {
|
||||
}
|
||||
}
|
||||
|
||||
long BarBoxes_SetMaxSlots() {
|
||||
long scrWidth = Gfx_GetGameWidthRes();
|
||||
static long SetMaxSlots() {
|
||||
long scrWidth = Graphics::GetGameWidthRes();
|
||||
|
||||
int slots = scrWidth / 127;
|
||||
if (++slots > 16) {
|
||||
@@ -247,7 +243,7 @@ long BarBoxes_SetMaxSlots() {
|
||||
|
||||
static long __fastcall GetOffsetX(int width) {
|
||||
int x_offset = 0;
|
||||
if (BarBoxes_SetMaxSlots() > 640 && width > ifaceWidth) {
|
||||
if (SetMaxSlots() > 640 && width > ifaceWidth) {
|
||||
x_offset -= (width - ifaceWidth) / 2;
|
||||
}
|
||||
return x_offset;
|
||||
@@ -264,7 +260,11 @@ static void __declspec(naked) refresh_box_bar_win_hack() {
|
||||
}
|
||||
}
|
||||
|
||||
void BarBoxes_OnGameLoad() {
|
||||
void BarBoxes::OnAfterGameInit() {
|
||||
SetMaxSlots();
|
||||
}
|
||||
|
||||
void BarBoxes::OnGameLoad() {
|
||||
ResetBoxes();
|
||||
if (initCount != totalBoxCount) {
|
||||
boxCount = initCount;
|
||||
@@ -272,8 +272,8 @@ void BarBoxes_OnGameLoad() {
|
||||
}
|
||||
}
|
||||
|
||||
void BarBoxes_Init() {
|
||||
initCount += GetConfigInt("Misc", "BoxBarCount", 5);
|
||||
void BarBoxes::init() {
|
||||
initCount += IniReader::GetConfigInt("Misc", "BoxBarCount", 5);
|
||||
if (initCount < 5) initCount = 5; // exclude the influence of negative values from the config
|
||||
if (initCount > 100) initCount = 100;
|
||||
|
||||
@@ -287,7 +287,7 @@ void BarBoxes_Init() {
|
||||
boxes[i].msg = 100 + i;
|
||||
}
|
||||
|
||||
std::string boxBarColors = GetConfigString("Misc", "BoxBarColours", "", actualBoxCount + 1);
|
||||
std::string boxBarColors = IniReader::GetConfigString("Misc", "BoxBarColours", "", actualBoxCount + 1);
|
||||
for (size_t i = 0; i < boxBarColors.size(); i++) {
|
||||
if (boxBarColors[i] == '1') {
|
||||
boxes[i + 5].colour = 1; // red color
|
||||
@@ -306,15 +306,15 @@ void BarBoxes_Init() {
|
||||
MakeCall(0x4615FA, refresh_box_bar_win_hack);
|
||||
SafeWriteBatch<DWORD>((DWORD)newBoxSlot, bboxSlotAddr); // _bboxslot
|
||||
|
||||
ifaceWidth = IniGetInt("IFACE", "IFACE_BAR_WIDTH", 640, ".\\f2_res.ini");
|
||||
ifaceWidth = IniReader::GetInt("IFACE", "IFACE_BAR_WIDTH", 640, ".\\f2_res.ini");
|
||||
if (ifaceWidth < 640) ifaceWidth = 640;
|
||||
}
|
||||
|
||||
long __stdcall BarBoxes_AddExtraBox() {
|
||||
long __stdcall BarBoxes::AddExtraBox() {
|
||||
if (boxCount < totalBoxCount) {
|
||||
actualBoxCount++;
|
||||
boxCount++;
|
||||
return BarBoxes_MaxBox(); // just return the number of the previously added box
|
||||
return MaxBox(); // just return the number of the previously added box
|
||||
}
|
||||
if (totalBoxCount > 126) return -1; // limit is exceeded
|
||||
|
||||
@@ -346,27 +346,27 @@ long __stdcall BarBoxes_AddExtraBox() {
|
||||
actualBoxCount++;
|
||||
|
||||
SetEngine(totalBoxCount);
|
||||
return BarBoxes_MaxBox(); // current number of added box
|
||||
return MaxBox(); // current number of added box
|
||||
}
|
||||
|
||||
bool __stdcall BarBoxes_GetBox(int i) {
|
||||
if (i < 5 || i > BarBoxes_MaxBox()) return false;
|
||||
bool __stdcall BarBoxes::GetBox(int i) {
|
||||
if (i < 5 || i > BarBoxes::MaxBox()) return false;
|
||||
return boxText[i - 5].isActive;
|
||||
}
|
||||
|
||||
void __stdcall BarBoxes_AddBox(int i) {
|
||||
if (i < 5 || i > BarBoxes_MaxBox()) return;
|
||||
void __stdcall BarBoxes::AddBox(int i) {
|
||||
if (i < 5 || i > BarBoxes::MaxBox()) return;
|
||||
boxText[i - 5].isActive = true;
|
||||
__asm call fo::funcoffs::refresh_box_bar_win_;
|
||||
}
|
||||
|
||||
void __stdcall BarBoxes_RemoveBox(int i) {
|
||||
if (i < 5 || i > BarBoxes_MaxBox()) return;
|
||||
void __stdcall BarBoxes::RemoveBox(int i) {
|
||||
if (i < 5 || i > BarBoxes::MaxBox()) return;
|
||||
boxText[i - 5].isActive = false;
|
||||
__asm call fo::funcoffs::refresh_box_bar_win_;
|
||||
}
|
||||
|
||||
void BarBoxes_Exit() {
|
||||
void BarBoxes::exit() {
|
||||
delete[] boxes;
|
||||
delete[] boxText;
|
||||
}
|
||||
|
||||
+18
-10
@@ -3,17 +3,25 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
void BarBoxes_Init();
|
||||
void BarBoxes_Exit();
|
||||
void BarBoxes_OnGameLoad();
|
||||
long BarBoxes_SetMaxSlots();
|
||||
class BarBoxes {
|
||||
private:
|
||||
static int boxCount;
|
||||
|
||||
int __stdcall BarBoxes_MaxBox();
|
||||
void __stdcall BarBoxes_SetText(int box, const char* text, DWORD color);
|
||||
public:
|
||||
static const char* name() { return "BarBoxes"; }
|
||||
static void init();
|
||||
static void exit();
|
||||
|
||||
bool __stdcall BarBoxes_GetBox(int i);
|
||||
void __stdcall BarBoxes_AddBox(int i);
|
||||
void __stdcall BarBoxes_RemoveBox(int i);
|
||||
long __stdcall BarBoxes_AddExtraBox();
|
||||
static void OnGameLoad();
|
||||
static void OnAfterGameInit();
|
||||
|
||||
static int MaxBox() { return boxCount - 1; }
|
||||
static void __stdcall SetText(int box, const char* text, DWORD color);
|
||||
|
||||
static bool __stdcall GetBox(int i);
|
||||
static void __stdcall AddBox(int i);
|
||||
static void __stdcall RemoveBox(int i);
|
||||
static long __stdcall AddExtraBox();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -85,16 +85,16 @@ static void LoadVanillaBooks() {
|
||||
books[4].skill = 17;
|
||||
}
|
||||
|
||||
void Books_Init() {
|
||||
std::string booksFile = GetConfigString("Misc", "BooksFile", "", MAX_PATH);
|
||||
void Books::init() {
|
||||
std::string booksFile = IniReader::GetConfigString("Misc", "BooksFile", "", MAX_PATH);
|
||||
if (!booksFile.empty()) {
|
||||
dlog("Applying books patch...", DL_INIT);
|
||||
const char* iniBooks = booksFile.insert(0, ".\\").c_str();
|
||||
|
||||
bool includeVanilla = (IniGetInt("main", "overrideVanilla", 0, iniBooks) == 0);
|
||||
bool includeVanilla = (IniReader::GetInt("main", "overrideVanilla", 0, iniBooks) == 0);
|
||||
if (includeVanilla) BooksCount = 5;
|
||||
|
||||
int count = IniGetInt("main", "count", 0, iniBooks);
|
||||
int count = IniReader::GetInt("main", "count", 0, iniBooks);
|
||||
|
||||
int n = 0;
|
||||
if (count > 0) {
|
||||
@@ -106,9 +106,9 @@ void Books_Init() {
|
||||
char section[4];
|
||||
for (int i = 1; i <= count; i++) {
|
||||
_itoa_s(i, section, 10);
|
||||
if (books[BooksCount].bookPid = IniGetInt(section, "PID", 0, iniBooks)) {
|
||||
books[BooksCount].msgID = IniGetInt(section, "TextID", 0, iniBooks);
|
||||
books[BooksCount].skill = IniGetInt(section, "Skill", 0, iniBooks);
|
||||
if (books[BooksCount].bookPid = IniReader::GetInt(section, "PID", 0, iniBooks)) {
|
||||
books[BooksCount].msgID = IniReader::GetInt(section, "TextID", 0, iniBooks);
|
||||
books[BooksCount].skill = IniReader::GetInt(section, "Skill", 0, iniBooks);
|
||||
BooksCount++;
|
||||
n++;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ void Books_Init() {
|
||||
}
|
||||
}
|
||||
|
||||
void Books_Exit() {
|
||||
void Books::exit() {
|
||||
if (books) delete[] books;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,11 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
void Books_Init();
|
||||
void Books_Exit();
|
||||
class Books {
|
||||
public:
|
||||
static const char* name() { return "Books"; }
|
||||
static void init();
|
||||
static void exit();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+57
-57
@@ -41,7 +41,7 @@ static int __fastcall DrugPidPop() {
|
||||
return pid;
|
||||
}
|
||||
|
||||
void BugFixes_DrugsSaveFix(HANDLE file) {
|
||||
void BugFixes::DrugsSaveFix(HANDLE file) {
|
||||
DWORD sizeWrite, count = drugsPid.size();
|
||||
WriteFile(file, &count, 4, &sizeWrite, 0);
|
||||
if (!count) return;
|
||||
@@ -53,7 +53,7 @@ void BugFixes_DrugsSaveFix(HANDLE file) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool BugFixes_DrugsLoadFix(HANDLE file) {
|
||||
bool BugFixes::DrugsLoadFix(HANDLE file) {
|
||||
DWORD count, sizeRead;
|
||||
ReadFile(file, &count, 4, &sizeRead, 0);
|
||||
if (sizeRead != 4) return false;
|
||||
@@ -73,7 +73,7 @@ void ResetBodyState() {
|
||||
__asm mov weightOnBody, 0;
|
||||
}
|
||||
|
||||
void BugFixes_Initialization() {
|
||||
static void Initialization() {
|
||||
// Restore calling original engine functions from HRP hacks (there is no difference in HRP functions)
|
||||
__int64 data = 0xC189565153;
|
||||
SafeWriteBytes(0x4D78CC, (BYTE*)&data, 5); // win_get_top_win_
|
||||
@@ -83,9 +83,9 @@ void BugFixes_Initialization() {
|
||||
|
||||
static std::vector<fo::AIcap> aiCapsBackup;
|
||||
|
||||
void combat_ai_init_backup() {
|
||||
static void combat_ai_init_backup() {
|
||||
long num_caps = *fo::ptr::num_caps;
|
||||
AIcap* caps = *fo::ptr::cap;
|
||||
fo::AIcap* caps = *fo::ptr::cap;
|
||||
|
||||
aiCapsBackup.resize(num_caps);
|
||||
std::memcpy(&aiCapsBackup[0], caps, num_caps * sizeof(fo::AIcap));
|
||||
@@ -93,7 +93,7 @@ void combat_ai_init_backup() {
|
||||
|
||||
static void combat_ai_reset() {
|
||||
long num_caps = *fo::ptr::num_caps;
|
||||
AIcap* caps = *fo::ptr::cap;
|
||||
fo::AIcap* caps = *fo::ptr::cap;
|
||||
std::memcpy(caps, &aiCapsBackup[0], num_caps * sizeof(fo::AIcap));
|
||||
}
|
||||
|
||||
@@ -2533,7 +2533,7 @@ static void __declspec(naked) wmAreaMarkVisitedState_hack() {
|
||||
//static const DWORD wmAreaMarkVisitedState_Error = 0x4C4698;
|
||||
static long isNoRadius;
|
||||
|
||||
isNoRadius = Worldmap_AreaMarkStateIsNoRadius(); // F1 behavior radius
|
||||
isNoRadius = Worldmap::AreaMarkStateIsNoRadius(); // F1 behavior radius
|
||||
__asm {
|
||||
mov [ecx + 0x40], esi; // wmAreaInfoList.visited
|
||||
test esi, esi; // mark "unknown" state
|
||||
@@ -3109,7 +3109,7 @@ static void __declspec(naked) op_create_object_sid_hack() {
|
||||
mov eax, esi;
|
||||
retn;
|
||||
init:
|
||||
call IsMapLoading;
|
||||
call LoadGameHook::IsMapLoading;
|
||||
test al, al;
|
||||
jnz end; // yes - initialization will be performed by engine functions
|
||||
cmp createObjectSidStartFix, 0;
|
||||
@@ -3135,25 +3135,25 @@ noObject:
|
||||
jmp end;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
// Missing game initialization
|
||||
void BugFixes_OnBeforeGameInit() {
|
||||
void BugFixes::OnBeforeGameInit() {
|
||||
Initialization();
|
||||
}
|
||||
|
||||
void BugFixes_OnAfterGameInit() {
|
||||
void BugFixes::OnAfterGameInit() {
|
||||
combat_ai_init_backup();
|
||||
}
|
||||
*/
|
||||
void BugFixes_OnGameLoad() {
|
||||
|
||||
void BugFixes::OnGameLoad() {
|
||||
dudeIsAnimDeath = false;
|
||||
combat_ai_reset();
|
||||
}
|
||||
|
||||
void BugFixes_Init()
|
||||
void BugFixes::init()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (GetIntDefaultConfig("Debugging", "BugFixes", 1) == 0) return;
|
||||
if (IniReader::GetIntDefaultConfig("Debugging", "BugFixes", 1) == 0) return;
|
||||
#endif
|
||||
|
||||
// Fix vanilla negate operator for float values
|
||||
@@ -3169,19 +3169,19 @@ void BugFixes_Init()
|
||||
SafeWrite16(0x46A4E7, 0x04DB);
|
||||
|
||||
// Fix for vanilla division operator treating negative integers as unsigned
|
||||
if (GetConfigInt("Misc", "DivisionOperatorFix", 1)) {
|
||||
if (IniReader::GetConfigInt("Misc", "DivisionOperatorFix", 1)) {
|
||||
dlog("Applying division operator fix.", DL_FIX);
|
||||
SafeWrite32(0x46A51D, 0xFBF79990); // xor edx, edx; div ebx > cdq; idiv ebx
|
||||
dlogr(" Done", DL_FIX);
|
||||
}
|
||||
|
||||
//if (GetConfigInt("Misc", "SpecialUnarmedAttacksFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "SpecialUnarmedAttacksFix", 1)) {
|
||||
dlog("Applying Special Unarmed Attacks fix.", DL_FIX);
|
||||
//MakeJump(0x42394D, compute_attack_hack); - implementation moved to Unarmed module
|
||||
dlogr(" Done", DL_FIX);
|
||||
//}
|
||||
|
||||
//if (GetConfigInt("Misc", "SharpshooterFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "SharpshooterFix", 1)) {
|
||||
dlog("Applying Sharpshooter patch.", DL_FIX);
|
||||
// https://www.nma-fallout.com/threads/fo2-engine-tweaks-sfall.178390/page-119#post-4050162
|
||||
// by Slider2k
|
||||
@@ -3205,7 +3205,7 @@ void BugFixes_Init()
|
||||
|
||||
// Fix for "Too Many Items" bug
|
||||
// http://fforum.kochegarov.com/index.php?showtopic=29288&view=findpost&p=332242
|
||||
//if (GetConfigInt("Misc", "TooManyItemsBugFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "TooManyItemsBugFix", 1)) {
|
||||
dlog("Applying preventive patch for \"Too Many Items\" bug.", DL_FIX);
|
||||
const DWORD writeScriptNodeAddr[] = {0x4A596A, 0x4A59C1};
|
||||
HookCalls(scr_write_ScriptNode_hook, writeScriptNodeAddr);
|
||||
@@ -3216,7 +3216,7 @@ void BugFixes_Init()
|
||||
MakeCall(0x49BE70, obj_use_power_on_car_hack);
|
||||
|
||||
// Fix for being able to charge the car by using cells on other scenery/critters
|
||||
if (GetConfigInt("Misc", "CarChargingFix", 1)) {
|
||||
if (IniReader::GetConfigInt("Misc", "CarChargingFix", 1)) {
|
||||
dlog("Applying car charging fix.", DL_FIX);
|
||||
MakeJump(0x49C36D, protinst_default_use_item_hack);
|
||||
dlogr(" Done", DL_FIX);
|
||||
@@ -3236,7 +3236,7 @@ void BugFixes_Init()
|
||||
// Evil bug! If party member has the same armor type in inventory as currently equipped, then
|
||||
// on level up he loses Armor Class equal to the one received from this armor.
|
||||
// The same happens if you just order NPC to remove the armor through dialogue.
|
||||
//if (GetConfigInt("Misc", "ArmorCorruptsNPCStatsFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "ArmorCorruptsNPCStatsFix", 1)) {
|
||||
dlog("Applying fix for armor reducing NPC original stats when removed.", DL_FIX);
|
||||
HookCall(0x495F3B, partyMemberCopyLevelInfo_hook_stat_level);
|
||||
HookCall(0x45419B, correctFidForRemovedItem_hook_adjust_ac);
|
||||
@@ -3255,7 +3255,7 @@ void BugFixes_Init()
|
||||
dlogr(" Done", DL_FIX);
|
||||
|
||||
// Allow 9 options (lines of text) to be displayed correctly in a dialog window
|
||||
//if (GetConfigInt("Misc", "DialogOptions9Lines", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "DialogOptions9Lines", 1)) {
|
||||
dlog("Applying 9 dialog options patch.", DL_FIX);
|
||||
MakeCall(0x447021, gdProcessUpdate_hack, 1);
|
||||
dlogr(" Done", DL_FIX);
|
||||
@@ -3280,7 +3280,7 @@ void BugFixes_Init()
|
||||
dlogr(" Done", DL_FIX);
|
||||
|
||||
// Fix for not counting in the weight/size of equipped items on NPC when stealing or bartering
|
||||
//if (GetConfigInt("Misc", "NPCWeightFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "NPCWeightFix", 1)) {
|
||||
dlog("Applying fix for not counting in weight of equipped items on NPC.", DL_FIX);
|
||||
MakeCall(0x473B4E, loot_container_hack);
|
||||
HookCall(0x4758AB, barter_inventory_hook);
|
||||
@@ -3296,7 +3296,7 @@ void BugFixes_Init()
|
||||
// Corrects the max text width of the player name in inventory to be 140 (was 80), which matches the width for item name
|
||||
SafeWrite32(0x471E48, 140);
|
||||
|
||||
//if (GetConfigInt("Misc", "InventoryDragIssuesFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "InventoryDragIssuesFix", 1)) {
|
||||
dlog("Applying inventory reverse order issues fix.", DL_FIX);
|
||||
// Fix for minor visual glitch when picking up solo item from the top of inventory
|
||||
// and there is multiple item stack at the bottom of inventory
|
||||
@@ -3310,7 +3310,7 @@ void BugFixes_Init()
|
||||
//}
|
||||
|
||||
// Enable party members with level 6 protos to reach level 6
|
||||
//if (GetConfigInt("Misc", "NPCStage6Fix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "NPCStage6Fix", 1)) {
|
||||
dlog("Applying NPC Stage 6 Fix.", DL_FIX);
|
||||
MakeJump(0x493CE9, NPCStage6Fix1); // partyMember_init_
|
||||
MakeJump(0x494224, NPCStage6Fix2); // partyMemberGetAIOptions_
|
||||
@@ -3319,32 +3319,32 @@ void BugFixes_Init()
|
||||
dlogr(" Done", DL_FIX);
|
||||
//}
|
||||
|
||||
//if (GetConfigInt("Misc", "NPCLevelFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "NPCLevelFix", 1)) {
|
||||
dlog("Applying NPC level fix.", DL_FIX);
|
||||
HookCall(0x495BC9, (void*)0x495E51); // jz 0x495E7F > jz 0x495E51
|
||||
dlogr(" Done", DL_FIX);
|
||||
//}
|
||||
|
||||
//if (GetConfigInt("Misc", "BlackSkilldexFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "BlackSkilldexFix", 1)) {
|
||||
dlog("Applying black Skilldex patch.", DL_FIX);
|
||||
HookCall(0x497D0F, PipStatus_AddHotLines_hook);
|
||||
dlogr(" Done", DL_FIX);
|
||||
//}
|
||||
|
||||
//if (GetConfigInt("Misc", "FixWithdrawalPerkDescCrash", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "FixWithdrawalPerkDescCrash", 1)) {
|
||||
dlog("Applying withdrawal perk description crash fix.", DL_FIX);
|
||||
HookCall(0x47A501, perform_withdrawal_start_display_print_hook);
|
||||
dlogr(" Done", DL_FIX);
|
||||
//}
|
||||
|
||||
//if (GetConfigInt("Misc", "JetAntidoteFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "JetAntidoteFix", 1)) {
|
||||
dlog("Applying Jet Antidote fix.", DL_FIX);
|
||||
// Fix for Jet antidote not being removed after removing the addiction effect (when using the item)
|
||||
MakeJump(0x47A013, (void*)0x47A168); // item_d_take_drug_
|
||||
dlogr(" Done", DL_FIX);
|
||||
//}
|
||||
|
||||
//if (GetConfigInt("Misc", "NPCDrugAddictionFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "NPCDrugAddictionFix", 1)) {
|
||||
dlog("Applying NPC's drug addiction fix.", DL_FIX);
|
||||
// proper checks for NPC's addiction instead of always using global vars
|
||||
const DWORD itemTakeDrugHkAddr[] = {0x479FBC, 0x47A0AE};
|
||||
@@ -3356,13 +3356,13 @@ void BugFixes_Init()
|
||||
dlogr(" Done", DL_FIX);
|
||||
//}
|
||||
|
||||
//if (GetConfigInt("Misc", "ShivPatch", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "ShivPatch", 1)) {
|
||||
dlog("Applying shiv patch.", DL_FIX);
|
||||
SafeWrite8(0x477B2B, CodeType::JumpShort);
|
||||
dlogr(" Done", DL_FIX);
|
||||
//}
|
||||
|
||||
//if (GetConfigInt("Misc", "ImportedProcedureFix", 0)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "ImportedProcedureFix", 0)) {
|
||||
dlog("Applying imported procedure patch.", DL_FIX);
|
||||
// http://teamx.ru/site_arc/smf/index.php-topic=398.0.htm
|
||||
SafeWrite16(0x46B35B, 0x1C60); // Fix problems with the temporary stack
|
||||
@@ -3376,14 +3376,14 @@ void BugFixes_Init()
|
||||
SafeWrite8(0x46C7AC, 0x76); // jb > jbe
|
||||
|
||||
// Update the AC counter
|
||||
//if (GetConfigInt("Misc", "WieldObjCritterFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "WieldObjCritterFix", 1)) {
|
||||
dlog("Applying wield_obj_critter fix.", DL_FIX);
|
||||
SafeWrite8(0x456912, 0x1E); // jnz 0x456931
|
||||
HookCall(0x45697F, op_wield_obj_critter_adjust_ac_hook);
|
||||
dlogr(" Done", DL_FIX);
|
||||
//}
|
||||
|
||||
//if (GetConfigInt("Misc", "MultiHexPathingFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "MultiHexPathingFix", 1)) {
|
||||
dlog("Applying MultiHex Pathing Fix.", DL_FIX);
|
||||
HookCall(0x416144, make_path_func_hook); // Fix for building the path to the central hex of a multihex object
|
||||
//const DWORD multiHexPathAddr[] = {0x42901F, 0x429170};
|
||||
@@ -3398,7 +3398,7 @@ void BugFixes_Init()
|
||||
dlogr(" Done", DL_FIX);
|
||||
//}
|
||||
|
||||
//if (GetConfigInt("Misc", "DodgyDoorsFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "DodgyDoorsFix", 1)) {
|
||||
dlog("Applying Dodgy Door Fix.", DL_FIX);
|
||||
MakeCall(0x4113D3, action_melee_hack, 2);
|
||||
MakeCall(0x411BC9, action_ranged_hack, 2);
|
||||
@@ -3419,7 +3419,7 @@ void BugFixes_Init()
|
||||
|
||||
// Fix for "NPC turns into a container" bug
|
||||
// https://www.nma-fallout.com/threads/fo2-engine-tweaks-sfall.178390/page-123#post-4065716
|
||||
//if (GetConfigInt("Misc", "NPCTurnsIntoContainerFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "NPCTurnsIntoContainerFix", 1)) {
|
||||
dlog("Applying fix for \"NPC turns into a container\" bug.", DL_FIX);
|
||||
MakeJump(0x42E46E, critter_wake_clear_hack);
|
||||
MakeCall(0x488EF3, obj_load_func_hack, 1);
|
||||
@@ -3442,7 +3442,7 @@ void BugFixes_Init()
|
||||
dlogr(" Done", DL_FIX);
|
||||
|
||||
// Fix for being unable to sell used geiger counters or stealth boys
|
||||
if (GetConfigInt("Misc", "CanSellUsedGeiger", 1)) {
|
||||
if (IniReader::GetConfigInt("Misc", "CanSellUsedGeiger", 1)) {
|
||||
dlog("Applying fix for being unable to sell used geiger counters or stealth boys.", DL_FIX);
|
||||
const DWORD itemQueuedAddr[] = {0x478115, 0x478138}; // item_queued_ (will return the found item)
|
||||
SafeWriteBatch<BYTE>(0xBA, itemQueuedAddr);
|
||||
@@ -3466,20 +3466,20 @@ void BugFixes_Init()
|
||||
// Fix for checking the horizontal position on the y-axis instead of x when setting coordinates on the world map
|
||||
SafeWrite8(0x4C4743, 0xC6); // cmp esi, eax
|
||||
|
||||
//if (GetConfigInt("Misc", "PrintToFileFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "PrintToFileFix", 1)) {
|
||||
dlog("Applying print to file fix.", DL_FIX);
|
||||
MakeCall(0x4C67D4, db_get_file_list_hack);
|
||||
dlogr(" Done", DL_FIX);
|
||||
//}
|
||||
|
||||
// Fix for display issues when calling gdialog_mod_barter with critters with no "Barter" flag set
|
||||
//if (GetConfigInt("Misc", "gdBarterDispFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "gdBarterDispFix", 1)) {
|
||||
dlog("Applying gdialog_mod_barter display fix.", DL_FIX);
|
||||
HookCall(0x448250, gdActivateBarter_hook);
|
||||
dlogr(" Done", DL_FIX);
|
||||
//}
|
||||
|
||||
//if (GetConfigInt("Misc", "BagBackpackFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "BagBackpackFix", 1)) {
|
||||
dlog("Applying fix for bag/backpack bugs.", DL_FIX);
|
||||
// Fix for items disappearing from inventory when you try to drag them to bag/backpack in the inventory list
|
||||
// and are overloaded
|
||||
@@ -3510,7 +3510,7 @@ void BugFixes_Init()
|
||||
HookCall(0x4211C0, combat_load_hook_item);
|
||||
|
||||
// Fix for Bonus Move APs being replenished when you save and load the game in combat
|
||||
//if (GetConfigInt("Misc", "BonusMoveFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "BonusMoveFix", 1)) {
|
||||
dlog("Applying fix for Bonus Move exploit.", DL_FIX);
|
||||
HookCall(0x420E93, combat_load_hook);
|
||||
MakeCall(0x422A06, combat_turn_hack);
|
||||
@@ -3525,7 +3525,7 @@ void BugFixes_Init()
|
||||
MakeCall(0x424CD2, apply_damage_hack);
|
||||
|
||||
// Fix for the double damage effect of Silent Death perk not being applied to critical hits
|
||||
//if (GetConfigInt("Misc", "SilentDeathFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "SilentDeathFix", 1)) {
|
||||
dlog("Applying Silent Death patch.", DL_FIX);
|
||||
SafeWrite8(0x4238DF, 0x8C); // jl loc_423A0D
|
||||
HookCall(0x423A99, compute_attack_hook);
|
||||
@@ -3567,7 +3567,7 @@ void BugFixes_Init()
|
||||
dlogr(" Done", DL_FIX);
|
||||
|
||||
// Display full item description for weapon/ammo in the barter screen
|
||||
showItemDescription = (GetConfigInt("Misc", "FullItemDescInBarter", 0) != 0);
|
||||
showItemDescription = (IniReader::GetConfigInt("Misc", "FullItemDescInBarter", 0) != 0);
|
||||
if (showItemDescription) {
|
||||
dlog("Applying full item description in barter patch.", DL_FIX);
|
||||
HookCall(0x49B452, obj_examine_func_hack_weapon); // it's jump
|
||||
@@ -3575,7 +3575,7 @@ void BugFixes_Init()
|
||||
}
|
||||
|
||||
// Display experience points with the bonus from Swift Learner perk when gained from non-scripted situations
|
||||
if (GetConfigInt("Misc", "DisplaySwiftLearnerExp", 1)) {
|
||||
if (IniReader::GetConfigInt("Misc", "DisplaySwiftLearnerExp", 1)) {
|
||||
dlog("Applying Swift Learner exp display patch.", DL_FIX);
|
||||
MakeCall(0x4AFAEF, statPCAddExperienceCheckPMs_hack);
|
||||
HookCall(0x4221E2, combat_give_exps_hook);
|
||||
@@ -3591,7 +3591,7 @@ void BugFixes_Init()
|
||||
SafeWrite16(0x456B76, 0x23EB); // jmp loc_456B9B (skip unused engine code)
|
||||
|
||||
// Fix broken obj_can_hear_obj function
|
||||
if (GetConfigInt("Misc", "ObjCanHearObjFix", 0)) {
|
||||
if (IniReader::GetConfigInt("Misc", "ObjCanHearObjFix", 0)) {
|
||||
dlog("Applying obj_can_hear_obj fix.", DL_FIX);
|
||||
SafeWrite8(0x4583D8, 0x3B); // jz loc_458414
|
||||
SafeWrite8(0x4583DE, CodeType::JumpZ); // jz loc_458414
|
||||
@@ -3599,7 +3599,7 @@ void BugFixes_Init()
|
||||
dlogr(" Done", DL_FIX);
|
||||
}
|
||||
|
||||
if (GetConfigInt("Misc", "AIBestWeaponFix", 1)) {
|
||||
if (IniReader::GetConfigInt("Misc", "AIBestWeaponFix", 1)) {
|
||||
dlog("Applying AI best weapon choice fix.", DL_FIX);
|
||||
// Fix for the incorrect item being checked for the presence of weapon perks
|
||||
HookCall(0x42954B, ai_best_weapon_hook);
|
||||
@@ -3640,7 +3640,7 @@ void BugFixes_Init()
|
||||
dlogr(" Done", DL_FIX);
|
||||
|
||||
// Fix for the "mood" argument of start_gdialog function being ignored for talking heads
|
||||
if (GetConfigInt("Misc", "StartGDialogFix", 0)) {
|
||||
if (IniReader::GetConfigInt("Misc", "StartGDialogFix", 0)) {
|
||||
dlog("Applying start_gdialog argument fix.", DL_FIX);
|
||||
MakeCall(0x456F08, op_start_gdialog_hack);
|
||||
dlogr(" Done", DL_FIX);
|
||||
@@ -3657,9 +3657,9 @@ void BugFixes_Init()
|
||||
// Radiation fixes
|
||||
MakeCall(0x42D6C3, process_rads_hack, 1); // prevents player's death if a stat is less than 1 when removing radiation effects
|
||||
HookCall(0x42D67A, process_rads_hook); // fix for the same effect message being displayed when removing radiation effects
|
||||
radEffectsMsgNum = GetConfigInt("Misc", "RadEffectsRemovalMsg", radEffectsMsgNum);
|
||||
radEffectsMsgNum = IniReader::GetConfigInt("Misc", "RadEffectsRemovalMsg", radEffectsMsgNum);
|
||||
// Display messages about radiation for the active geiger counter
|
||||
if (GetConfigInt("Misc", "ActiveGeigerMsgs", 1)) {
|
||||
if (IniReader::GetConfigInt("Misc", "ActiveGeigerMsgs", 1)) {
|
||||
dlog("Applying active geiger counter messages patch.", DL_FIX);
|
||||
const DWORD activeGeigerAddr[] = {0x42D424, 0x42D444};
|
||||
SafeWriteBatch<BYTE>(CodeType::JumpZ, activeGeigerAddr); // jnz > jz
|
||||
@@ -3668,7 +3668,7 @@ void BugFixes_Init()
|
||||
// Display a pop-up message box about death from radiation
|
||||
HookCall(0x42D733, process_rads_hook_msg);
|
||||
|
||||
//int drugUsePerfFix = GetConfigInt("Misc", "AIDrugUsePerfFix", 0);
|
||||
//int drugUsePerfFix = IniReader::GetConfigInt("Misc", "AIDrugUsePerfFix", 0);
|
||||
//if (drugUsePerfFix > 0) {
|
||||
// dlog("Applying AI drug use preference fix.", DL_FIX);
|
||||
// if (drugUsePerfFix == 1) {
|
||||
@@ -3696,7 +3696,7 @@ void BugFixes_Init()
|
||||
// Fix and repurpose the unused called_shot/num_attack arguments of attack_complex function
|
||||
// called_shot - additional damage when hitting the target
|
||||
// num_attacks - the number of free action points on the first turn only
|
||||
if (GetConfigInt("Misc", "AttackComplexFix", 0)) {
|
||||
if (IniReader::GetConfigInt("Misc", "AttackComplexFix", 0)) {
|
||||
dlog("Applying attack_complex arguments fix.", DL_FIX);
|
||||
HookCall(0x456D4A, op_attack_hook);
|
||||
SafeWrite8(0x456D61, 0x74); // mov [gcsd.free_move], esi
|
||||
@@ -3803,7 +3803,7 @@ void BugFixes_Init()
|
||||
// up an item due to not enough space in the inventory
|
||||
HookCall(0x49B6E7, obj_pickup_hook);
|
||||
HookCall(0x49B71C, obj_pickup_hook_message);
|
||||
Translate_Get("sfall", "NPCPickupFail", "%s cannot pick up the item.", pickupMessage, 65);
|
||||
Translate::Get("sfall", "NPCPickupFail", "%s cannot pick up the item.", pickupMessage, 65);
|
||||
|
||||
// Fix for anim_move_to_tile_ engine function ignoring the distance argument for the player
|
||||
HookCall(0x416D44, anim_move_to_tile_hook);
|
||||
@@ -3814,7 +3814,7 @@ void BugFixes_Init()
|
||||
MakeCall(0x411DF7, action_climb_ladder_hack); // bug caused by anim_move_to_tile_ fix
|
||||
|
||||
// Partial fix for incorrect positioning after exiting small/medium locations (e.g. Ghost Farm)
|
||||
//if (GetConfigInt("Misc", "SmallLocExitFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "SmallLocExitFix", 1)) {
|
||||
dlog("Applying fix for incorrect positioning after exiting small/medium locations.", DL_FIX);
|
||||
MakeJump(0x4C5A41, wmTeleportToArea_hack);
|
||||
dlogr(" Done", DL_FIX);
|
||||
@@ -3830,7 +3830,7 @@ void BugFixes_Init()
|
||||
MakeCall(0x4C03AA, wmWorldMap_hack, 2);
|
||||
|
||||
// Fix to prevent using number keys to enter unvisited areas on a town map
|
||||
if (GetConfigInt("Misc", "TownMapHotkeysFix", 1)) {
|
||||
if (IniReader::GetConfigInt("Misc", "TownMapHotkeysFix", 1)) {
|
||||
dlog("Applying town map hotkeys patch.", DL_FIX);
|
||||
MakeCall(0x4C495A, wmTownMapFunc_hack, 1);
|
||||
dlogr(" Done", DL_FIX);
|
||||
@@ -3842,7 +3842,7 @@ void BugFixes_Init()
|
||||
|
||||
// Fix for the car being lost when entering a location via the Town/World button and then leaving on foot
|
||||
// (sets GVAR_CAR_PLACED_TILE (633) to -1 on exit to the world map)
|
||||
if (GetConfigInt("Misc", "CarPlacedTileFix", 1)) {
|
||||
if (IniReader::GetConfigInt("Misc", "CarPlacedTileFix", 1)) {
|
||||
dlog("Applying car placed tile fix.", DL_FIX);
|
||||
MakeCall(0x4C2367, wmInterfaceInit_hack);
|
||||
dlogr(" Done", DL_FIX);
|
||||
@@ -3860,7 +3860,7 @@ void BugFixes_Init()
|
||||
HookCall(0x458B3D, op_critter_add_trait_hook);
|
||||
|
||||
// Fix to prevent corpses from blocking line of fire
|
||||
//if (GetConfigInt("Misc", "CorpseLineOfFireFix", 1)) {
|
||||
//if (IniReader::GetConfigInt("Misc", "CorpseLineOfFireFix", 1)) {
|
||||
dlog("Applying fix for corpses blocking line of fire.", DL_FIX);
|
||||
MakeJump(0x48B994, obj_shoot_blocking_at_hack0);
|
||||
MakeJump(0x48BA04, obj_shoot_blocking_at_hack1);
|
||||
@@ -3962,7 +3962,7 @@ void BugFixes_Init()
|
||||
HookCall(0x4B6C13, checkAllRegions_hook);
|
||||
|
||||
// Fix for the script attached to an object not being initialized properly upon object creation
|
||||
createObjectSidStartFix = (GetConfigInt("Misc", "CreateObjectSidFix", 0) != 0);
|
||||
createObjectSidStartFix = (IniReader::GetConfigInt("Misc", "CreateObjectSidFix", 0) != 0);
|
||||
MakeCall(0x4551C0, op_create_object_sid_hack, 1);
|
||||
// Fix the error handling in create_object_sid function to prevent a crash when the proto is missing
|
||||
SafeWrite8(0x45507B, 0x51); // jz 0x4550CD
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user