mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Expanded get/inc_npc_level functions to accept party member PIDs (from Mr.Stalin)
Some code correction in Skills.cpp.
This commit is contained in:
@@ -162,8 +162,8 @@
|
||||
0x81a3 - int eax_available()
|
||||
0x81a4 - void set_eax_environment(int environment)
|
||||
|
||||
0x81a5 - void inc_npc_level(string npc)
|
||||
0x8241 - int get_npc_level(string npc)
|
||||
0x81a5 - void inc_npc_level(string npcName/int pid)
|
||||
0x8241 - int get_npc_level(string npcName/int pid)
|
||||
|
||||
0x81a6 - int get_viewport_x()
|
||||
0x81a7 - int get_viewport_y()
|
||||
|
||||
+79
-127
@@ -538,152 +538,104 @@ static void __declspec(naked) EaxAvailable() {
|
||||
retn;
|
||||
}
|
||||
}
|
||||
static char* NPCToInc;
|
||||
static void _stdcall IncNPCLevel4(char* npc) {
|
||||
if (_stricmp(npc, NPCToInc)) {
|
||||
SafeWrite8(0x495C50, 0xE9);
|
||||
SafeWrite32(0x495C51, 0x000001FC);
|
||||
} else {
|
||||
SafeWrite16(0x495C50, 0x840F); //Want to keep this check intact.
|
||||
SafeWrite32(0x495C52, 0x000001FB);
|
||||
|
||||
//SafeMemSet(0x495C50, 0x90, 6);
|
||||
SafeMemSet(0x495C77, 0x90, 6); //Check that the player is high enough for the npc to consider this level
|
||||
//SafeMemSet(0x495C8C, 0x90, 6); //Check that the npc isn't already at its maximum level
|
||||
SafeMemSet(0x495CEC, 0x90, 6); //Check that the npc hasn't already levelled up recently
|
||||
if (!npcautolevel) {
|
||||
SafeMemSet(0x495D22, 0x90, 6); //Random element
|
||||
static const char* nameNPCToInc;
|
||||
static long pidNPCToInc;
|
||||
static bool onceNpcLoop;
|
||||
|
||||
static void __cdecl IncNPCLevelFunc(const char* fmt, const char* name) {
|
||||
TGameObj* mObj;
|
||||
__asm {
|
||||
push edx;
|
||||
mov eax, [ebp + 0x150 - 0x1C + 16]; // ebp <- esp
|
||||
mov edx, [eax];
|
||||
mov mObj, edx;
|
||||
}
|
||||
|
||||
if ((pidNPCToInc && (mObj && mObj->pid == pidNPCToInc)) || (!pidNPCToInc && !_stricmp(name, nameNPCToInc))) {
|
||||
DebugPrintf(fmt, name);
|
||||
|
||||
SafeWrite32(0x495C50, 0x01FB840F); // Want to keep this check intact. (restore)
|
||||
|
||||
SafeMemSet(0x495C77, 0x90, 6); // Check that the player is high enough for the npc to consider this level
|
||||
//SafeMemSet(0x495C8C, 0x90, 6); // Check that the npc isn't already at its maximum level
|
||||
SafeMemSet(0x495CEC, 0x90, 6); // Check that the npc hasn't already levelled up recently
|
||||
if (!npcAutoLevelEnabled) {
|
||||
SafeWrite8(0x495CFB, 0xEB); // Disable random element
|
||||
}
|
||||
__asm mov [ebp + 0x150 - 0x28 + 16], 255; // set counter for exit loop
|
||||
} else {
|
||||
if (!onceNpcLoop) {
|
||||
SafeWrite32(0x495C50, 0x01FCE9); // set goto next member
|
||||
onceNpcLoop = true;
|
||||
}
|
||||
}
|
||||
__asm pop edx;
|
||||
}
|
||||
static void __declspec(naked) IncNPCLevel3() {
|
||||
__asm {
|
||||
pushad;
|
||||
push eax;
|
||||
call IncNPCLevel4;
|
||||
popad;
|
||||
push 0x495BF9;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
static void _stdcall IncNPCLevel2(char* npc) {
|
||||
NPCToInc = npc;
|
||||
MakeJump(0x495BEB, IncNPCLevel3); //Replace the debug output with a jmp
|
||||
__asm {
|
||||
call partyMemberIncLevels_;
|
||||
}
|
||||
SafeWrite16(0x495C50, 0x840F);
|
||||
SafeWrite32(0x495C52, 0x000001FB);
|
||||
|
||||
static void _stdcall IncNPCLevel2() {
|
||||
nameNPCToInc = opHandler.arg(0).asString();
|
||||
pidNPCToInc = opHandler.arg(0).asInt(); // set to 0 if passing npc name
|
||||
if (pidNPCToInc == 0 && nameNPCToInc[0] == 0) return;
|
||||
|
||||
MakeCall(0x495BF1, IncNPCLevelFunc); // Replace the debug output
|
||||
__asm call partyMemberIncLevels_;
|
||||
onceNpcLoop = false;
|
||||
|
||||
// restore code
|
||||
SafeWrite32(0x495C50, 0x01FB840F);
|
||||
SafeWrite16(0x495C77, 0x8C0F);
|
||||
SafeWrite32(0x495C79, 0x000001D4);
|
||||
//SafeWrite16(0x495C8C, 0x8D0F);
|
||||
//SafeWrite32(0x495C8E, 0x000001BF);
|
||||
SafeWrite16(0x495CEC, 0x850F);
|
||||
SafeWrite32(0x495CEE, 0x00000130);
|
||||
if (!npcautolevel) {
|
||||
SafeWrite16(0x495D22, 0x8F0F);
|
||||
SafeWrite32(0x495D24, 0x00000129);
|
||||
if (!npcAutoLevelEnabled) {
|
||||
SafeWrite8(0x495CFB, 0x74);
|
||||
}
|
||||
}
|
||||
static void __declspec(naked) IncNPCLevel() {
|
||||
__asm {
|
||||
push ebx;
|
||||
push ecx;
|
||||
push edx;
|
||||
push edi;
|
||||
mov edi, eax;
|
||||
call interpretPopShort_;
|
||||
mov edx, eax;
|
||||
mov eax, edi;
|
||||
call interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_STR2;
|
||||
jz next;
|
||||
cmp dx, VAR_TYPE_STR;
|
||||
jnz end;
|
||||
next:
|
||||
mov ebx, eax;
|
||||
mov eax, edi;
|
||||
call interpretGetString_;
|
||||
push eax;
|
||||
call IncNPCLevel2;
|
||||
end:
|
||||
pop edi;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
pop ebx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
static int _stdcall get_npc_level2(DWORD numMembers, DWORD maxMembers, DWORD* members, DWORD* pids, DWORD* words, const char* name) {
|
||||
for (DWORD i = 0; i < numMembers; i++) {
|
||||
const char* name2;
|
||||
__asm {
|
||||
mov eax, members;
|
||||
mov eax, [eax];
|
||||
call critter_name_
|
||||
mov name2, eax;
|
||||
}
|
||||
if (_stricmp(name, name2)) {
|
||||
members += 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
DWORD pid = ((DWORD*)members[0])[25];
|
||||
DWORD id = -1;
|
||||
for (DWORD j = 0; j < maxMembers; j++) {
|
||||
static void __declspec(naked) IncNPCLevel() {
|
||||
_WRAP_OPCODE(IncNPCLevel2, 1, 0)
|
||||
}
|
||||
|
||||
static void _stdcall get_npc_level2() {
|
||||
int level = -1;
|
||||
DWORD pid = opHandler.arg(0).asInt(); // set to 0 if passing npc name
|
||||
if (!pid) {
|
||||
const char *critterName, *name = opHandler.arg(0).strValue();
|
||||
if (name[0] != 0) {
|
||||
DWORD* members = *(DWORD**)_partyMemberList;
|
||||
for (DWORD i = 0; i < *(DWORD*)_partyMemberCount; i++) {
|
||||
__asm {
|
||||
mov eax, members;
|
||||
mov eax, [eax];
|
||||
call critter_name_;
|
||||
mov critterName, eax;
|
||||
}
|
||||
if (!_stricmp(name, critterName)) { // found npc
|
||||
pid = ((TGameObj*)*members)->pid;
|
||||
break;
|
||||
}
|
||||
members += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pid) {
|
||||
DWORD* pids = *(DWORD**)_partyMemberPidList;
|
||||
DWORD* lvlUpInfo = *(DWORD**)_partyMemberLevelUpInfoList;
|
||||
for (DWORD j = 0; j < *(DWORD*)_partyMemberMaxCount; j++) {
|
||||
if (pids[j] == pid) {
|
||||
id = j;
|
||||
level = lvlUpInfo[j * 3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (id == -1) break;
|
||||
|
||||
return words[id * 3];
|
||||
}
|
||||
return 0;
|
||||
opHandler.setReturn(level);
|
||||
}
|
||||
|
||||
static void __declspec(naked) get_npc_level() {
|
||||
__asm {
|
||||
push ebx;
|
||||
push ecx;
|
||||
push edx;
|
||||
push edi;
|
||||
mov edi, eax;
|
||||
call interpretPopShort_;
|
||||
mov edx, eax;
|
||||
mov eax, edi;
|
||||
call interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_STR2;
|
||||
jz next;
|
||||
cmp dx, VAR_TYPE_STR;
|
||||
jnz fail;
|
||||
next:
|
||||
mov ebx, eax;
|
||||
mov eax, edi;
|
||||
call interpretGetString_;
|
||||
push eax;
|
||||
push ds:[_partyMemberLevelUpInfoList];
|
||||
push ds:[_partyMemberPidList];
|
||||
push ds:[_partyMemberList];
|
||||
push ds:[_partyMemberMaxCount];
|
||||
push ds:[_partyMemberCount];
|
||||
call get_npc_level2;
|
||||
mov edx, eax;
|
||||
jmp end;
|
||||
fail:
|
||||
xor edx, edx;
|
||||
end:
|
||||
mov eax, edi;
|
||||
call interpretPushLong_;
|
||||
mov eax, edi;
|
||||
mov edx, VAR_TYPE_INT;
|
||||
call interpretPushShort_;
|
||||
pop edi;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
pop ebx;
|
||||
retn;
|
||||
}
|
||||
_WRAP_OPCODE(get_npc_level2, 1, 1)
|
||||
}
|
||||
|
||||
static int ParseIniSetting(const char* iniString, const char* &key, char section[], char file[]) {
|
||||
@@ -715,7 +667,7 @@ static char IniStrBuffer[128];
|
||||
static DWORD _stdcall GetIniSetting2(const char* c, DWORD string) {
|
||||
const char* key;
|
||||
char section[33], file[67];
|
||||
|
||||
|
||||
if (ParseIniSetting(c, key, section, file) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
+3
-3
@@ -83,7 +83,7 @@ char dfModelName[65];
|
||||
static const char* musicOverridePath = "data\\sound\\music\\";
|
||||
|
||||
DWORD AddUnarmedStatToGetYear = 0;
|
||||
bool npcautolevel;
|
||||
bool npcAutoLevelEnabled;
|
||||
|
||||
static int* scriptDialog = nullptr;
|
||||
|
||||
@@ -1134,8 +1134,8 @@ static void DllMain2() {
|
||||
|
||||
DebugEditorInit();
|
||||
|
||||
npcautolevel = GetPrivateProfileIntA("Misc", "NPCAutoLevel", 0, ini) != 0;
|
||||
if (npcautolevel) {
|
||||
npcAutoLevelEnabled = GetPrivateProfileIntA("Misc", "NPCAutoLevel", 0, ini) != 0;
|
||||
if (npcAutoLevelEnabled) {
|
||||
dlog("Applying NPC autolevel patch.", DL_INIT);
|
||||
SafeWrite8(0x495CFB, 0xEB); // jmps 0x495D28 (skip random check)
|
||||
dlogr(" Done", DL_INIT);
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ extern DWORD modifiedIni;
|
||||
extern char dmModelName[65];
|
||||
extern char dfModelName[65];
|
||||
|
||||
extern bool npcautolevel;
|
||||
extern bool npcAutoLevelEnabled;
|
||||
|
||||
DWORD GetAddedYears(bool isCheck = true);
|
||||
void SetAddedYears(DWORD years);
|
||||
|
||||
+4
-2
@@ -82,7 +82,7 @@ static int __fastcall SkillNegative(TGameObj* critter, int base, int skill) {
|
||||
}
|
||||
if (tagged) rawPoints *= 2;
|
||||
base += rawPoints; // add the negative skill points after calculating the skill level
|
||||
if (base < -300) return -300;
|
||||
if (base < 0) return max(-999, base);
|
||||
}
|
||||
return CheckSkillMax(critter, base);
|
||||
}
|
||||
@@ -330,7 +330,9 @@ void SkillsInit() {
|
||||
skills[i].base = GetPrivateProfileIntA("Skills", key, skills[i].base, file);
|
||||
|
||||
sprintf(key, "SkillMulti%d", i);
|
||||
skills[i].skillPointMulti = GetPrivateProfileIntA("Skills", key, skills[i].skillPointMulti, file);
|
||||
int multi = GetPrivateProfileIntA("Skills", key, skills[i].skillPointMulti, file);
|
||||
if (multi < 1) multi = 1; else if (multi > 10) multi = 10;
|
||||
skills[i].skillPointMulti = multi;
|
||||
|
||||
sprintf(key, "SkillImage%d", i);
|
||||
skills[i].image = GetPrivateProfileIntA("Skills", key, skills[i].image, file);
|
||||
|
||||
Reference in New Issue
Block a user