mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Fix NPCAutoLevel and set_npc_level opcode
- Now properly doesn't shift first level up too early and doesn't set "early" flag - Fixed using set_npc_level without disabling engine leveling logic - Renamed to PartyMemberNoEarlyLevelUpPatch to match behavior
This commit is contained in:
+3
-3
@@ -383,9 +383,9 @@ TownMapHotkeysFix=1
|
|||||||
;Set to 1 to disable the Horrigan encounter
|
;Set to 1 to disable the Horrigan encounter
|
||||||
DisableHorrigan=0
|
DisableHorrigan=0
|
||||||
|
|
||||||
;Set to 1 to disable the random element in NPC levelling
|
;Set to 1 to disable the random element in party member levelling
|
||||||
;This will cause all NPC party members to automatically level up as soon as the player reaches the requirements
|
;This will prevent party members from randomly leveling up "earlier" and instead level up in defined regular intervals
|
||||||
NPCAutoLevel=0
|
PartyMemberNoEarlyLevelUp=0
|
||||||
|
|
||||||
;Change the initial starting location and world map viewport
|
;Change the initial starting location and world map viewport
|
||||||
;Leave at -1 for default
|
;Leave at -1 for default
|
||||||
|
|||||||
@@ -34,7 +34,6 @@
|
|||||||
namespace sfall
|
namespace sfall
|
||||||
{
|
{
|
||||||
|
|
||||||
bool npcAutoLevelEnabled;
|
|
||||||
bool npcEngineLevelUp = true;
|
bool npcEngineLevelUp = true;
|
||||||
|
|
||||||
static bool isControllingNPC = false;
|
static bool isControllingNPC = false;
|
||||||
@@ -837,11 +836,12 @@ void PartyControl::OrderAttackPatch() {
|
|||||||
orderAttackPatch = true;
|
orderAttackPatch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NpcAutoLevelPatch() {
|
static void PartyMemberNoEarlyLevelUpPatch() {
|
||||||
npcAutoLevelEnabled = IniReader::GetConfigInt("Misc", "NPCAutoLevel", 0) != 0;
|
if (IniReader::GetConfigInt("Misc", "PartyMemberNoEarlyLevelUp", 0) != 0) {
|
||||||
if (npcAutoLevelEnabled) {
|
dlogr("Applying PartyMemberNoEarlyLevelUp patch.", DL_INIT);
|
||||||
dlogr("Applying NPC autolevel patch.", DL_INIT);
|
// if (numLevels % level_up_every) != 0, skip random "early level up" roll and continue to the next party member instead
|
||||||
SafeWrite8(0x495CFB, CodeType::JumpShort); // jmps 0x495D28 (skip random check)
|
SafeWrite8(0x495CFD, CodeType::Jump); // JMP
|
||||||
|
SafeWrite32(0x495CFE, 0x14F); // jumps to 0x495E51
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -864,7 +864,7 @@ void PartyControl::init() {
|
|||||||
0x47136D // right slot
|
0x47136D // right slot
|
||||||
});
|
});
|
||||||
|
|
||||||
NpcAutoLevelPatch();
|
PartyMemberNoEarlyLevelUpPatch();
|
||||||
|
|
||||||
// Display party member's current level & AC & addict flag
|
// Display party member's current level & AC & addict flag
|
||||||
if (IniReader::GetConfigInt("Misc", "PartyMemberExtraInfo", 0)) {
|
if (IniReader::GetConfigInt("Misc", "PartyMemberExtraInfo", 0)) {
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ public:
|
|||||||
static void OrderAttackPatch();
|
static void OrderAttackPatch();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern bool npcAutoLevelEnabled;
|
|
||||||
extern bool npcEngineLevelUp;
|
extern bool npcEngineLevelUp;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,10 +56,9 @@ static void __cdecl IncNPCLevel(const char* fmt, const char* name) {
|
|||||||
|
|
||||||
SafeMemSet(0x495C77, CodeType::Nop, 6); // Check that the player is high enough for the npc to consider this level
|
SafeMemSet(0x495C77, CodeType::Nop, 6); // Check that the player is high enough for the npc to consider this level
|
||||||
//SafeMemSet(0x495C8C, CodeType::Nop, 6); // Check that the npc isn't already at its maximum level
|
//SafeMemSet(0x495C8C, CodeType::Nop, 6); // Check that the npc isn't already at its maximum level
|
||||||
SafeMemSet(0x495CEC, CodeType::Nop, 6); // Check that the npc hasn't already levelled up recently
|
SafeMemSet(0x495CE3, CodeType::Nop, 5); // Check if npc had "early" level up before the next scheduled one, resets the "early" flag
|
||||||
if (!npcAutoLevelEnabled) {
|
SafeMemSet(0x495CEC, CodeType::Nop, 6); // Related to above
|
||||||
SafeWrite8(0x495CFB, CodeType::JumpShort); // Disable random element
|
SafeWrite8(0x495CFB, CodeType::JumpShort); // Skip random roll for early level up
|
||||||
}
|
|
||||||
__asm mov dword ptr [ebp + 0x150 - 0x28 + 16], 255; // set counter for exit loop
|
__asm mov dword ptr [ebp + 0x150 - 0x28 + 16], 255; // set counter for exit loop
|
||||||
} else {
|
} else {
|
||||||
if (!onceNpcLoop) {
|
if (!onceNpcLoop) {
|
||||||
@@ -80,17 +79,18 @@ void op_inc_npc_level(OpcodeContext& ctx) {
|
|||||||
onceNpcLoop = false;
|
onceNpcLoop = false;
|
||||||
|
|
||||||
// restore code
|
// restore code
|
||||||
|
SafeWrite32(0x495BF1 + 1, 0x031352); // restore debug_printf call
|
||||||
SafeWrite32(0x495C50, 0x01FB840F);
|
SafeWrite32(0x495C50, 0x01FB840F);
|
||||||
__int64 data = 0x01D48C0F;
|
__int64 data = 0x01D48C0F;
|
||||||
SafeWriteBytes(0x495C77, (BYTE*)&data, 6);
|
SafeWriteBytes(0x495C77, (BYTE*)&data, 6);
|
||||||
//SafeWrite16(0x495C8C, 0x8D0F);
|
//SafeWrite16(0x495C8C, 0x8D0F);
|
||||||
//SafeWrite32(0x495C8E, 0x000001BF);
|
//SafeWrite32(0x495C8E, 0x000001BF);
|
||||||
data = 0x0130850F;
|
data = 0x0169E9;
|
||||||
|
SafeWriteBytes(0x495CE3, (BYTE*)&data, 5);
|
||||||
|
data = 0x015F850F;
|
||||||
SafeWriteBytes(0x495CEC, (BYTE*)&data, 6);
|
SafeWriteBytes(0x495CEC, (BYTE*)&data, 6);
|
||||||
if (!npcAutoLevelEnabled) {
|
|
||||||
SafeWrite8(0x495CFB, CodeType::JumpZ);
|
SafeWrite8(0x495CFB, CodeType::JumpZ);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void op_get_npc_level(OpcodeContext& ctx) {
|
void op_get_npc_level(OpcodeContext& ctx) {
|
||||||
int level = -1;
|
int level = -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user