mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added optional options to the perks ini file
* to toggle modification sections for perks and traits. Reorganized ini reading functions in main.cpp, and edited related code in Perks/Stats modules. Added error/warning icons to message boxes.
This commit is contained in:
@@ -27,6 +27,10 @@ WeaponAccurateBonus=20
|
||||
WeaponHandlingBonus=3
|
||||
|
||||
;##############################################################################
|
||||
[Perks]
|
||||
;Set to 1 to enable the modifications to perks
|
||||
Enable=0
|
||||
|
||||
;Name=The name of the perk (max 63 characters)
|
||||
;Desc=The description of the perk (max 255 characters)
|
||||
;Image=The line number (0-indexed) of the corresponding FRM in skilldex.lst
|
||||
@@ -119,6 +123,11 @@ Skill4Mod=0
|
||||
Skill5=-1
|
||||
Skill5Mod=0
|
||||
|
||||
;##############################################################################
|
||||
[Traits]
|
||||
;Set to 1 to enable the modifications to traits
|
||||
Enable=0
|
||||
|
||||
;This is a modification to trait 0
|
||||
[t0]
|
||||
NoHardcode=0
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ namespace sfall
|
||||
static const DWORD ExpectedSize = 0x00122800;
|
||||
static const DWORD ExpectedCRC[] = {0xe1680293, 0xef34f989};
|
||||
|
||||
static void inline Fail(const char* a) { MessageBoxA(0, a, "Error", MB_TASKMODAL); ExitProcess(1); }
|
||||
static void inline Fail(const char* a) { MessageBoxA(0, a, "Error", MB_TASKMODAL | MB_ICONERROR); ExitProcess(1); }
|
||||
|
||||
static const DWORD CRC_table[256] = {
|
||||
0x00000000, 0x0A5F4D75, 0x14BE9AEA, 0x1EE1D79F, 0x14C5EB57, 0x1E9AA622, 0x007B71BD, 0x0A243CC8,
|
||||
|
||||
@@ -998,7 +998,7 @@ void Graphics::init() {
|
||||
HMODULE h = LoadLibraryEx(_DLL_NAME, 0, LOAD_LIBRARY_AS_DATAFILE);
|
||||
if (!h) {
|
||||
MessageBoxA(0, "You have selected graphics mode 4 or 5, but " _DLL_NAME " is missing.\n"
|
||||
"Switch back to mode 0, or install an up to date version of DirectX.", "Error", 0);
|
||||
"Switch back to mode 0, or install an up to date version of DirectX.", "Error", MB_TASKMODAL | MB_ICONERROR);
|
||||
ExitProcess(-1);
|
||||
} else {
|
||||
FreeLibrary(h);
|
||||
|
||||
@@ -354,7 +354,7 @@ static long _stdcall AddHeroCritNames() { // art_init_
|
||||
critterListSize = critterArt.total / 2;
|
||||
if (critterListSize > 2048) {
|
||||
MessageBoxA(0, "This mod cannot be used because the maximum limit of the FID count in the critters.lst is exceeded.\n"
|
||||
"Please disable the mod and restart the game.", "Hero Appearance mod", 0x10);
|
||||
"Please disable the mod and restart the game.", "Hero Appearance mod", MB_TASKMODAL | MB_ICONERROR);
|
||||
ExitProcess(-1);
|
||||
}
|
||||
critterArraySize = critterListSize * 13;
|
||||
|
||||
+134
-125
@@ -45,7 +45,9 @@ static char PerkBoxTitle[33];
|
||||
|
||||
static const int startFakeID = 256;
|
||||
static DWORD addPerkMode = 2;
|
||||
|
||||
static bool perksReInit = false;
|
||||
static int perksEnable = 0;
|
||||
|
||||
static PerkInfo perks[PERK_count];
|
||||
static TraitInfo traits[TRAIT_count];
|
||||
@@ -851,8 +853,6 @@ static void PerkEngineInit() {
|
||||
}
|
||||
|
||||
static void PerkSetup() {
|
||||
memcpy(perks, var::perk_data, sizeof(PerkInfo) * PERK_count); // copy vanilla data
|
||||
|
||||
if (!perksReInit) {
|
||||
// _perk_data
|
||||
SafeWriteBatch<DWORD>((DWORD)perks, {0x496669, 0x496837, 0x496BAD, 0x496C41, 0x496D25});
|
||||
@@ -861,50 +861,52 @@ static void PerkSetup() {
|
||||
SafeWrite32(0x496BF5, (DWORD)perks + 8);
|
||||
SafeWrite32(0x496AD4, (DWORD)perks + 12);
|
||||
}
|
||||
if (perksFile[0] != '\0') {
|
||||
memcpy(perks, var::perk_data, sizeof(PerkInfo) * PERK_count); // copy vanilla data
|
||||
|
||||
if (perksEnable) {
|
||||
char num[4];
|
||||
for (int i = 0; i < PERK_count; i++) {
|
||||
_itoa_s(i, num, 10);
|
||||
if (GetPrivateProfileString(num, "Name", "", &Name[i * maxNameLen], maxNameLen - 1, perksFile)) {
|
||||
if (iniGetString(num, "Name", "", &Name[i * maxNameLen], maxNameLen - 1, perksFile)) {
|
||||
perks[i].name = &Name[i * maxNameLen];
|
||||
}
|
||||
if (GetPrivateProfileString(num, "Desc", "", &Desc[i * descLen], descLen - 1, perksFile)) {
|
||||
if (iniGetString(num, "Desc", "", &Desc[i * descLen], descLen - 1, perksFile)) {
|
||||
perks[i].description = &Desc[i * descLen];
|
||||
}
|
||||
int value;
|
||||
value = GetPrivateProfileInt(num, "Image", -99999, perksFile);
|
||||
value = iniGetInt(num, "Image", -99999, perksFile);
|
||||
if (value != -99999) perks[i].image = value;
|
||||
value = GetPrivateProfileInt(num, "Ranks", -99999, perksFile);
|
||||
value = iniGetInt(num, "Ranks", -99999, perksFile);
|
||||
if (value != -99999) perks[i].ranks = value;
|
||||
value = GetPrivateProfileInt(num, "Level", -99999, perksFile);
|
||||
value = iniGetInt(num, "Level", -99999, perksFile);
|
||||
if (value != -99999) perks[i].levelMin = value;
|
||||
value = GetPrivateProfileInt(num, "Stat", -99999, perksFile);
|
||||
value = iniGetInt(num, "Stat", -99999, perksFile);
|
||||
if (value != -99999) perks[i].stat = value;
|
||||
value = GetPrivateProfileInt(num, "StatMag", -99999, perksFile);
|
||||
value = iniGetInt(num, "StatMag", -99999, perksFile);
|
||||
if (value != -99999) perks[i].statMod = value;
|
||||
value = GetPrivateProfileInt(num, "Skill1", -99999, perksFile);
|
||||
value = iniGetInt(num, "Skill1", -99999, perksFile);
|
||||
if (value != -99999) perks[i].skill1 = value;
|
||||
value = GetPrivateProfileInt(num, "Skill1Mag", -99999, perksFile);
|
||||
value = iniGetInt(num, "Skill1Mag", -99999, perksFile);
|
||||
if (value != -99999) perks[i].skill1Min = value;
|
||||
value = GetPrivateProfileInt(num, "Type", -99999, perksFile);
|
||||
value = iniGetInt(num, "Type", -99999, perksFile);
|
||||
if (value != -99999) perks[i].skillOperator = value;
|
||||
value = GetPrivateProfileInt(num, "Skill2", -99999, perksFile);
|
||||
value = iniGetInt(num, "Skill2", -99999, perksFile);
|
||||
if (value != -99999) perks[i].skill2 = value;
|
||||
value = GetPrivateProfileInt(num, "Skill2Mag", -99999, perksFile);
|
||||
value = iniGetInt(num, "Skill2Mag", -99999, perksFile);
|
||||
if (value != -99999) perks[i].skill2Min = value;
|
||||
value = GetPrivateProfileInt(num, "STR", -99999, perksFile);
|
||||
value = iniGetInt(num, "STR", -99999, perksFile);
|
||||
if (value != -99999) perks[i].strengthMin = value;
|
||||
value = GetPrivateProfileInt(num, "PER", -99999, perksFile);
|
||||
value = iniGetInt(num, "PER", -99999, perksFile);
|
||||
if (value != -99999) perks[i].perceptionMin = value;
|
||||
value = GetPrivateProfileInt(num, "END", -99999, perksFile);
|
||||
value = iniGetInt(num, "END", -99999, perksFile);
|
||||
if (value != -99999) perks[i].enduranceMin = value;
|
||||
value = GetPrivateProfileInt(num, "CHR", -99999, perksFile);
|
||||
value = iniGetInt(num, "CHR", -99999, perksFile);
|
||||
if (value != -99999) perks[i].charismaMin = value;
|
||||
value = GetPrivateProfileInt(num, "INT", -99999, perksFile);
|
||||
value = iniGetInt(num, "INT", -99999, perksFile);
|
||||
if (value != -99999) perks[i].intelligenceMin = value;
|
||||
value = GetPrivateProfileInt(num, "AGL", -99999, perksFile);
|
||||
value = iniGetInt(num, "AGL", -99999, perksFile);
|
||||
if (value != -99999) perks[i].agilityMin = value;
|
||||
value = GetPrivateProfileInt(num, "LCK", -99999, perksFile);
|
||||
value = iniGetInt(num, "LCK", -99999, perksFile);
|
||||
if (value != -99999) perks[i].luckMin = value;
|
||||
}
|
||||
if (perksReInit) {
|
||||
@@ -917,41 +919,41 @@ static void PerkSetup() {
|
||||
int n = 0;
|
||||
for (int id = PERK_count; id < startFakeID; id++) {
|
||||
_itoa(id, num, 10);
|
||||
int ranks = GetPrivateProfileInt(num, "Ranks", -1, perksFile);
|
||||
int ranks = iniGetInt(num, "Ranks", -1, perksFile);
|
||||
if (ranks == -1) continue;
|
||||
extPerks[n].data.ranks = ranks;
|
||||
extPerks[n].data.image = GetPrivateProfileInt(num, "Image", -1, perksFile);
|
||||
extPerks[n].data.levelMin = GetPrivateProfileInt(num, "Level", -1, perksFile);
|
||||
extPerks[n].data.stat = GetPrivateProfileInt(num, "Stat", -1, perksFile);
|
||||
extPerks[n].data.statMod = GetPrivateProfileInt(num, "StatMag", 0, perksFile);
|
||||
extPerks[n].data.skill1 = GetPrivateProfileInt(num, "Skill1", -1, perksFile);
|
||||
extPerks[n].data.skill1Min = GetPrivateProfileInt(num, "Skill1Mag", 0, perksFile);
|
||||
extPerks[n].data.skillOperator = GetPrivateProfileInt(num, "Type", 0, perksFile);
|
||||
extPerks[n].data.skill2 = GetPrivateProfileInt(num, "Skill2", -1, perksFile);
|
||||
extPerks[n].data.skill2Min = GetPrivateProfileInt(num, "Skill2Mag", 0, perksFile);
|
||||
extPerks[n].data.strengthMin = GetPrivateProfileInt(num, "STR", 0, perksFile);
|
||||
extPerks[n].data.perceptionMin = GetPrivateProfileInt(num, "PER", 0, perksFile);
|
||||
extPerks[n].data.enduranceMin = GetPrivateProfileInt(num, "END", 0, perksFile);
|
||||
extPerks[n].data.charismaMin = GetPrivateProfileInt(num, "CHR", 0, perksFile);
|
||||
extPerks[n].data.intelligenceMin = GetPrivateProfileInt(num, "INT", 0, perksFile);
|
||||
extPerks[n].data.agilityMin = GetPrivateProfileInt(num, "AGL", 0, perksFile);
|
||||
extPerks[n].data.luckMin = GetPrivateProfileInt(num, "LCK", 0, perksFile);
|
||||
extPerks[n].data.image = iniGetInt(num, "Image", -1, perksFile);
|
||||
extPerks[n].data.levelMin = iniGetInt(num, "Level", -1, perksFile);
|
||||
extPerks[n].data.stat = iniGetInt(num, "Stat", -1, perksFile);
|
||||
extPerks[n].data.statMod = iniGetInt(num, "StatMag", 0, perksFile);
|
||||
extPerks[n].data.skill1 = iniGetInt(num, "Skill1", -1, perksFile);
|
||||
extPerks[n].data.skill1Min = iniGetInt(num, "Skill1Mag", 0, perksFile);
|
||||
extPerks[n].data.skillOperator = iniGetInt(num, "Type", 0, perksFile);
|
||||
extPerks[n].data.skill2 = iniGetInt(num, "Skill2", -1, perksFile);
|
||||
extPerks[n].data.skill2Min = iniGetInt(num, "Skill2Mag", 0, perksFile);
|
||||
extPerks[n].data.strengthMin = iniGetInt(num, "STR", 0, perksFile);
|
||||
extPerks[n].data.perceptionMin = iniGetInt(num, "PER", 0, perksFile);
|
||||
extPerks[n].data.enduranceMin = iniGetInt(num, "END", 0, perksFile);
|
||||
extPerks[n].data.charismaMin = iniGetInt(num, "CHR", 0, perksFile);
|
||||
extPerks[n].data.intelligenceMin = iniGetInt(num, "INT", 0, perksFile);
|
||||
extPerks[n].data.agilityMin = iniGetInt(num, "AGL", 0, perksFile);
|
||||
extPerks[n].data.luckMin = iniGetInt(num, "LCK", 0, perksFile);
|
||||
|
||||
GetPrivateProfileString(num, "Name", "Error", extPerks[n].Name, maxNameLen - 1, perksFile);
|
||||
iniGetString(num, "Name", "Error", extPerks[n].Name, maxNameLen - 1, perksFile);
|
||||
extPerks[n].data.name = extPerks[n].Name;
|
||||
GetPrivateProfileString(num, "Desc", "Error", extPerks[n].Desc, descLen - 1, perksFile);
|
||||
iniGetString(num, "Desc", "Error", extPerks[n].Desc, descLen - 1, perksFile);
|
||||
extPerks[n].data.description = extPerks[n].Desc;
|
||||
|
||||
extPerks[n].stat1 = GetPrivateProfileInt(num, "Stat1", -1, perksFile);
|
||||
extPerks[n].stat1Mod = GetPrivateProfileInt(num, "Stat1Mag", 0, perksFile);
|
||||
extPerks[n].stat2 = GetPrivateProfileInt(num, "Stat2", -1, perksFile);
|
||||
extPerks[n].stat2Mod = GetPrivateProfileInt(num, "Stat2Mag", 0, perksFile);
|
||||
extPerks[n].skill3 = GetPrivateProfileInt(num, "Skill3", -1, perksFile);
|
||||
extPerks[n].skill3Mod = GetPrivateProfileInt(num, "Skill3Mod", 0, perksFile);
|
||||
extPerks[n].skill4 = GetPrivateProfileInt(num, "Skill4", -1, perksFile);
|
||||
extPerks[n].skill4Mod = GetPrivateProfileInt(num, "Skill4Mod", 0, perksFile);
|
||||
extPerks[n].skill5 = GetPrivateProfileInt(num, "Skill5", -1, perksFile);
|
||||
extPerks[n].skill5Mod = GetPrivateProfileInt(num, "Skill5Mod", 0, perksFile);
|
||||
extPerks[n].stat1 = iniGetInt(num, "Stat1", -1, perksFile);
|
||||
extPerks[n].stat1Mod = iniGetInt(num, "Stat1Mag", 0, perksFile);
|
||||
extPerks[n].stat2 = iniGetInt(num, "Stat2", -1, perksFile);
|
||||
extPerks[n].stat2Mod = iniGetInt(num, "Stat2Mag", 0, perksFile);
|
||||
extPerks[n].skill3 = iniGetInt(num, "Skill3", -1, perksFile);
|
||||
extPerks[n].skill3Mod = iniGetInt(num, "Skill3Mod", 0, perksFile);
|
||||
extPerks[n].skill4 = iniGetInt(num, "Skill4", -1, perksFile);
|
||||
extPerks[n].skill4Mod = iniGetInt(num, "Skill4Mod", 0, perksFile);
|
||||
extPerks[n].skill5 = iniGetInt(num, "Skill5", -1, perksFile);
|
||||
extPerks[n].skill5Mod = iniGetInt(num, "Skill5Mod", 0, perksFile);
|
||||
extPerks[n].id = id;
|
||||
++n;
|
||||
extPerks.resize(n + 1); // add next 'empty' perk
|
||||
@@ -1121,80 +1123,78 @@ static void TraitSetup() {
|
||||
SafeWrite32(0x4B3BA0, (DWORD)traits + 4);
|
||||
SafeWrite32(0x4B3BC0, (DWORD)traits + 8);
|
||||
|
||||
if (perksFile[0] != '\0') {
|
||||
char buf[512], num[5] = {'t'};
|
||||
char* num2 = &num[1];
|
||||
for (int i = 0; i < TRAIT_count; i++) {
|
||||
_itoa_s(i, num2, 4, 10);
|
||||
if (GetPrivateProfileString(num, "Name", "", &tName[i * maxNameLen], maxNameLen - 1, perksFile)) {
|
||||
traits[i].name = &tName[i * maxNameLen];
|
||||
}
|
||||
if (GetPrivateProfileString(num, "Desc", "", &tDesc[i * descLen], descLen - 1, perksFile)) {
|
||||
traits[i].description = &tDesc[i * descLen];
|
||||
}
|
||||
int value;
|
||||
value = GetPrivateProfileInt(num, "Image", -99999, perksFile);
|
||||
if (value != -99999) traits[i].image = value;
|
||||
char buf[512], num[5] = {'t'};
|
||||
char* num2 = &num[1];
|
||||
for (int i = 0; i < TRAIT_count; i++) {
|
||||
_itoa_s(i, num2, 4, 10);
|
||||
if (iniGetString(num, "Name", "", &tName[i * maxNameLen], maxNameLen - 1, perksFile)) {
|
||||
traits[i].name = &tName[i * maxNameLen];
|
||||
}
|
||||
if (iniGetString(num, "Desc", "", &tDesc[i * descLen], descLen - 1, perksFile)) {
|
||||
traits[i].description = &tDesc[i * descLen];
|
||||
}
|
||||
int value;
|
||||
value = iniGetInt(num, "Image", -99999, perksFile);
|
||||
if (value != -99999) traits[i].image = value;
|
||||
|
||||
if (GetPrivateProfileStringA(num, "StatMod", "", buf, 512, perksFile) > 0) {
|
||||
char *stat, *mod;
|
||||
stat = strtok(buf, "|");
|
||||
if (iniGetString(num, "StatMod", "", buf, 512, perksFile) > 0) {
|
||||
char *stat, *mod;
|
||||
stat = strtok(buf, "|");
|
||||
mod = strtok(0, "|");
|
||||
while (stat&&mod) {
|
||||
int _stat = atoi(stat), _mod = atoi(mod);
|
||||
if (_stat >= 0 && _stat <= STAT_max_derived) TraitStatBonuses[_stat * TRAIT_count + i] = _mod;
|
||||
stat = strtok(0, "|");
|
||||
mod = strtok(0, "|");
|
||||
while (stat&&mod) {
|
||||
int _stat = atoi(stat), _mod = atoi(mod);
|
||||
if (_stat >= 0 && _stat <= STAT_max_derived) TraitStatBonuses[_stat * TRAIT_count + i] = _mod;
|
||||
stat = strtok(0, "|");
|
||||
mod = strtok(0, "|");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GetPrivateProfileStringA(num, "SkillMod", "", buf, 512, perksFile) > 0) {
|
||||
char *stat, *mod;
|
||||
stat = strtok(buf, "|");
|
||||
if (iniGetString(num, "SkillMod", "", buf, 512, perksFile) > 0) {
|
||||
char *stat, *mod;
|
||||
stat = strtok(buf, "|");
|
||||
mod = strtok(0, "|");
|
||||
while (stat&&mod) {
|
||||
int _stat = atoi(stat), _mod = atoi(mod);
|
||||
if (_stat >= 0 && _stat < 18) TraitSkillBonuses[_stat * TRAIT_count + i] = _mod;
|
||||
stat = strtok(0, "|");
|
||||
mod = strtok(0, "|");
|
||||
while (stat&&mod) {
|
||||
int _stat = atoi(stat), _mod = atoi(mod);
|
||||
if (_stat >= 0 && _stat < 18) TraitSkillBonuses[_stat * TRAIT_count + i] = _mod;
|
||||
stat = strtok(0, "|");
|
||||
mod = strtok(0, "|");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GetPrivateProfileInt(num, "NoHardcode", 0, perksFile)) {
|
||||
disableTraits[i] = true;
|
||||
switch (i) {
|
||||
case TRAIT_one_hander:
|
||||
HookCall(0x4245E0, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_finesse:
|
||||
HookCall(0x4248F9, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_fast_shot:
|
||||
HookCall(0x478C8A, BlockedTrait); // fast shot
|
||||
HookCall(0x478E70, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_bloody_mess:
|
||||
HookCall(0x410707, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_jinxed:
|
||||
HookCall(0x42389F, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_drug_addict:
|
||||
HookCall(0x47A0CD, BlockedTrait);
|
||||
HookCall(0x47A51A, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_drug_resistant:
|
||||
HookCall(0x479BE1, BlockedTrait);
|
||||
HookCall(0x47A0DD, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_skilled:
|
||||
HookCall(0x43C295, BlockedTrait);
|
||||
HookCall(0x43C2F3, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_gifted:
|
||||
HookCall(0x43C2A4, BlockedTrait);
|
||||
break;
|
||||
}
|
||||
if (iniGetInt(num, "NoHardcode", 0, perksFile)) {
|
||||
disableTraits[i] = true;
|
||||
switch (i) {
|
||||
case TRAIT_one_hander:
|
||||
HookCall(0x4245E0, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_finesse:
|
||||
HookCall(0x4248F9, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_fast_shot:
|
||||
HookCall(0x478C8A, BlockedTrait); // fast shot
|
||||
HookCall(0x478E70, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_bloody_mess:
|
||||
HookCall(0x410707, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_jinxed:
|
||||
HookCall(0x42389F, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_drug_addict:
|
||||
HookCall(0x47A0CD, BlockedTrait);
|
||||
HookCall(0x47A51A, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_drug_resistant:
|
||||
HookCall(0x479BE1, BlockedTrait);
|
||||
HookCall(0x47A0DD, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_skilled:
|
||||
HookCall(0x43C295, BlockedTrait);
|
||||
HookCall(0x43C2F3, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_gifted:
|
||||
HookCall(0x43C2A4, BlockedTrait);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1294,6 +1294,8 @@ void PerksReset() {
|
||||
SafeWrite32(0x496880, 0x019078);
|
||||
// Pyromaniac bonus
|
||||
SafeWrite8(0x424AB6, 5);
|
||||
// Swift Learner bonus
|
||||
SafeWrite32(0x4AFAE2, 100);
|
||||
// Restore 'Heave Ho' modify fix
|
||||
if (perkHeaveHoModFix) {
|
||||
SafeWrite8(0x478AC4, 0xBA);
|
||||
@@ -1442,40 +1444,47 @@ void PerksAcceptCharScreen() {
|
||||
}
|
||||
|
||||
void Perks::init() {
|
||||
LoadGameHook::OnGameReset() += PerksReset;
|
||||
|
||||
FastShotTraitFix();
|
||||
|
||||
for (int i = STAT_st; i <= STAT_lu; i++) SafeWrite8(GainStatPerks[i][0], (BYTE)GainStatPerks[i][1]);
|
||||
|
||||
PerkEngineInit();
|
||||
HookCall(0x442729, PerkInitWrapper); // game_init_
|
||||
|
||||
if (GetConfigString("Misc", "PerksFile", "", &perksFile[2], MAX_PATH - 3)) {
|
||||
perksFile[0] = '.';
|
||||
perksFile[1] = '\\';
|
||||
HookCall(0x44272E, TraitInitWrapper); // game_init_
|
||||
if (GetFileAttributes(perksFile) == INVALID_FILE_ATTRIBUTES) return;
|
||||
|
||||
perksEnable = iniGetInt("Perks", "Enable", 1, perksFile);
|
||||
if (iniGetInt("Traits", "Enable", 1, perksFile)) {
|
||||
HookCall(0x44272E, TraitInitWrapper); // game_init_
|
||||
}
|
||||
|
||||
// Engine perks settings
|
||||
long enginePerkMod = GetPrivateProfileIntA("PerksTweak", "WeaponScopeRangePenalty", -1, perksFile);
|
||||
long enginePerkMod = iniGetInt("PerksTweak", "WeaponScopeRangePenalty", -1, perksFile);
|
||||
if (enginePerkMod >= 0 && enginePerkMod != 8) SafeWrite32(0x42448E, enginePerkMod);
|
||||
enginePerkMod = GetPrivateProfileIntA("PerksTweak", "WeaponScopeRangeBonus", -1, perksFile);
|
||||
enginePerkMod = iniGetInt("PerksTweak", "WeaponScopeRangeBonus", -1, perksFile);
|
||||
if (enginePerkMod >= 2 && enginePerkMod != 5) SafeWrite32(0x424489, enginePerkMod);
|
||||
|
||||
enginePerkMod = GetPrivateProfileIntA("PerksTweak", "WeaponLongRangeBonus", -1, perksFile);
|
||||
enginePerkMod = iniGetInt("PerksTweak", "WeaponLongRangeBonus", -1, perksFile);
|
||||
if (enginePerkMod >= 2 && enginePerkMod != 4) SafeWrite32(0x424474, enginePerkMod);
|
||||
|
||||
enginePerkMod = GetPrivateProfileIntA("PerksTweak", "WeaponAccurateBonus", -1, perksFile);
|
||||
enginePerkMod = iniGetInt("PerksTweak", "WeaponAccurateBonus", -1, perksFile);
|
||||
if (enginePerkMod >= 0 && enginePerkMod != 20) {
|
||||
if (enginePerkMod > 200) enginePerkMod = 200;
|
||||
SafeWrite8(0x42465D, static_cast<BYTE>(enginePerkMod));
|
||||
}
|
||||
|
||||
enginePerkMod = GetPrivateProfileIntA("PerksTweak", "WeaponHandlingBonus", -1, perksFile);
|
||||
enginePerkMod = iniGetInt("PerksTweak", "WeaponHandlingBonus", -1, perksFile);
|
||||
if (enginePerkMod >= 0 && enginePerkMod != 3) {
|
||||
if (enginePerkMod > 10) enginePerkMod = 10;
|
||||
SafeWrite8(0x424636, static_cast<char>(enginePerkMod));
|
||||
SafeWrite8(0x4251CE, static_cast<signed char>(-enginePerkMod));
|
||||
}
|
||||
}
|
||||
LoadGameHook::OnGameReset() += PerksReset;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -473,6 +473,7 @@ static void PrepareGlobalScriptsListByMask() {
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
char* name = _strlwr(filenames[i]); // name of the script in lower case
|
||||
if (name[0] != 'g' || name[1] != 'l') continue; // fix bug in db_get_file_list fuction (if the script name begins with a non-Latin character)
|
||||
|
||||
std::string baseName(name);
|
||||
int lastDot = baseName.find_last_of('.');
|
||||
|
||||
@@ -299,19 +299,20 @@ void Stats::init() {
|
||||
|
||||
char key[6], buf2[256], buf3[256];
|
||||
const char* statFile = statsFile.insert(0, ".\\").c_str();
|
||||
if (GetFileAttributes(statFile) == INVALID_FILE_ATTRIBUTES) return;
|
||||
|
||||
for (int i = fo::Stat::STAT_max_hit_points; i <= fo::Stat::STAT_poison_resist; i++) {
|
||||
if (i >= fo::Stat::STAT_dmg_thresh && i <= fo::Stat::STAT_dmg_resist_explosion) continue;
|
||||
|
||||
_itoa(i, key, 10);
|
||||
statFormulas[i].base = GetPrivateProfileInt(key, "base", statFormulas[i].base, statFile);
|
||||
statFormulas[i].min = GetPrivateProfileInt(key, "min", statFormulas[i].min, statFile);
|
||||
statFormulas[i].base = iniGetInt(key, "base", statFormulas[i].base, statFile);
|
||||
statFormulas[i].min = iniGetInt(key, "min", statFormulas[i].min, statFile);
|
||||
for (int j = 0; j < fo::Stat::STAT_max_hit_points; j++) {
|
||||
sprintf(buf2, "shift%d", j);
|
||||
statFormulas[i].shift[j] = GetPrivateProfileInt(key, buf2, statFormulas[i].shift[j], statFile);
|
||||
statFormulas[i].shift[j] = iniGetInt(key, buf2, statFormulas[i].shift[j], statFile);
|
||||
sprintf(buf2, "multi%d", j);
|
||||
_gcvt(statFormulas[i].multi[j], 16, buf3);
|
||||
GetPrivateProfileStringA(key, buf2, buf3, buf2, 256, statFile);
|
||||
iniGetString(key, buf2, buf3, buf2, 256, statFile);
|
||||
statFormulas[i].multi[j] = atof(buf2);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-10
@@ -102,16 +102,20 @@ DWORD HRPAddressOffset(DWORD offset) {
|
||||
return (hrpDLLBaseAddr + offset);
|
||||
}
|
||||
|
||||
unsigned int GetConfigInt(const char* section, const char* setting, int defaultValue) {
|
||||
return GetPrivateProfileIntA(section, setting, defaultValue, ini);
|
||||
int iniGetInt(const char* section, const char* setting, int defaultValue, const char* iniFile) {
|
||||
return GetPrivateProfileIntA(section, setting, defaultValue, iniFile);
|
||||
}
|
||||
|
||||
size_t iniGetString(const char* section, const char* setting, const char* defaultValue, char* buf, size_t bufSize, const char* iniFile) {
|
||||
return GetPrivateProfileStringA(section, setting, defaultValue, buf, bufSize, iniFile);
|
||||
}
|
||||
|
||||
std::string GetIniString(const char* section, const char* setting, const char* defaultValue, size_t bufSize, const char* iniFile) {
|
||||
char* buf = new char[bufSize];
|
||||
GetPrivateProfileStringA(section, setting, defaultValue, buf, bufSize, iniFile);
|
||||
iniGetString(section, setting, defaultValue, buf, bufSize, iniFile);
|
||||
std::string str(buf);
|
||||
delete[] buf;
|
||||
return trim(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
std::vector<std::string> GetIniList(const char* section, const char* setting, const char* defaultValue, size_t bufSize, char delimiter, const char* iniFile) {
|
||||
@@ -120,12 +124,19 @@ std::vector<std::string> GetIniList(const char* section, const char* setting, co
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
For ddraw.ini config
|
||||
*/
|
||||
unsigned int GetConfigInt(const char* section, const char* setting, int defaultValue) {
|
||||
return iniGetInt(section, setting, defaultValue, ini);
|
||||
}
|
||||
|
||||
std::string GetConfigString(const char* section, const char* setting, const char* defaultValue, size_t bufSize) {
|
||||
return GetIniString(section, setting, defaultValue, bufSize, ini);
|
||||
return trim(GetIniString(section, setting, defaultValue, bufSize, ini));
|
||||
}
|
||||
|
||||
size_t GetConfigString(const char* section, const char* setting, const char* defaultValue, char* buf, size_t bufSize) {
|
||||
return GetPrivateProfileStringA(section, setting, defaultValue, buf, bufSize, ini);
|
||||
return iniGetString(section, setting, defaultValue, buf, bufSize, ini);
|
||||
}
|
||||
|
||||
std::vector<std::string> GetConfigList(const char* section, const char* setting, const char* defaultValue, size_t bufSize) {
|
||||
@@ -137,7 +148,7 @@ std::string Translate(const char* section, const char* setting, const char* defa
|
||||
}
|
||||
|
||||
size_t Translate(const char* section, const char* setting, const char* defaultValue, char* buffer, size_t bufSize) {
|
||||
return GetPrivateProfileStringA(section, setting, defaultValue, buffer, bufSize, translationIni);
|
||||
return iniGetString(section, setting, defaultValue, buffer, bufSize, translationIni);
|
||||
}
|
||||
|
||||
static void InitModules() {
|
||||
@@ -228,7 +239,7 @@ static void CompatModeCheck(HKEY root, const char* filepath, int extra) {
|
||||
MessageBoxA(0, "Fallout appears to be running in compatibility mode.\n" //, and sfall was not able to disable it.\n"
|
||||
"Please check the compatibility tab of fallout2.exe, and ensure that the following settings are unchecked:\n"
|
||||
"Run this program in compatibility mode for..., run in 256 colours, and run in 640x480 resolution.\n"
|
||||
"If these options are disabled, click the 'change settings for all users' button and see if that enables them.", "Error", 0);
|
||||
"If these options are disabled, click the 'change settings for all users' button and see if that enables them.", "Error", MB_TASKMODAL | MB_ICONERROR);
|
||||
|
||||
ExitProcess(-1);
|
||||
}
|
||||
@@ -297,8 +308,8 @@ inline void SfallInit() {
|
||||
CloseHandle(h);
|
||||
strcat_s(ini, cmdline);
|
||||
} else {
|
||||
MessageBox(0, "You gave a command line argument to fallout, but it couldn't be matched to a file\n" \
|
||||
"Using default ddraw.ini instead", "Warning", MB_TASKMODAL);
|
||||
MessageBoxA(0, "You gave a command line argument to Fallout, but it couldn't be matched to a file.\n" \
|
||||
"Using default ddraw.ini instead.", "Warning", MB_TASKMODAL | MB_ICONWARNING);
|
||||
goto defaultIni;
|
||||
}
|
||||
} else {
|
||||
|
||||
+12
-6
@@ -73,21 +73,27 @@ namespace sfall
|
||||
#define pushadc __asm push eax __asm push edx __asm push ecx
|
||||
#define popadc __asm pop ecx __asm pop edx __asm pop eax
|
||||
|
||||
// Gets the integer value from Sfall configuration INI file.
|
||||
unsigned int GetConfigInt(const char* section, const char* setting, int defaultValue);
|
||||
// Gets the integer value from given INI file.
|
||||
int iniGetInt(const char* section, const char* setting, int defaultValue, const char* iniFile);
|
||||
|
||||
// Gets the string value from given INI file.
|
||||
size_t 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.
|
||||
std::string GetIniString(const char* section, const char* setting, const char* defaultValue, size_t bufSize, const char* iniFile);
|
||||
|
||||
// Loads the string value from Sfall configuration INI file into the provided buffer.
|
||||
size_t GetConfigString(const char* section, const char* setting, const char* defaultValue, char* buffer, size_t bufSize = 128);
|
||||
|
||||
// Parses the comma-separated list setting from given INI file.
|
||||
std::vector<std::string> GetIniList(const char* section, const char* setting, const char* defaultValue, size_t bufSize, char delimiter, const char* iniFile);
|
||||
|
||||
// Gets the string value from Sfall configuration INI file.
|
||||
// Gets the integer value from Sfall configuration INI file.
|
||||
unsigned int GetConfigInt(const char* section, const char* setting, int defaultValue);
|
||||
|
||||
// Gets the string value from Sfall configuration INI file with trim function.
|
||||
std::string 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 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> GetConfigList(const char* section, const char* setting, const char* defaultValue, size_t bufSize = 128);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user