mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Fixed set_self function for use_obj_on_obj, attack, attack_complex vanilla functions (from Mr.Stalin) (#214)
This commit is contained in:
@@ -163,8 +163,9 @@ array - array ID to be used with array-related functions (actually an integer)
|
|||||||
- overrides the scripts self_obj for the next function call.
|
- overrides the scripts self_obj for the next function call.
|
||||||
- It is primarily used to allow the calling of functions which take an implicit self_obj parameter (e.g. drop_obj) from global scripts, but it can also be used from normal scripts;
|
- It is primarily used to allow the calling of functions which take an implicit self_obj parameter (e.g. drop_obj) from global scripts, but it can also be used from normal scripts;
|
||||||
- self_obj will revert back to its original value after the next function call.
|
- self_obj will revert back to its original value after the next function call.
|
||||||
- calling self_obj(0) will also revert self_obj to original value
|
- calling self_obj(0) will also revert self_obj to original value. It is recommended to call this after each use of set_self in normal scripts in order to avoid unforeseen side effects.
|
||||||
- source_obj, target_obj, and similar functions will not work if preceded by "set_self"
|
- source_obj, target_obj, and similar functions will not work if preceded by "set_self"
|
||||||
|
- NOTE: for use_obj_on_obj vanilla function to work correctly, it is required to call set_self twice.
|
||||||
|
|
||||||
> void mod_skill_points_per_level(int x)
|
> void mod_skill_points_per_level(int x)
|
||||||
- accepts a value of between -100 and 100, and modifies the number of skill points the player receives when they level up.
|
- accepts a value of between -100 and 100, and modifies the number of skill points the player receives when they level up.
|
||||||
|
|||||||
@@ -72,6 +72,16 @@ struct ExportedVar {
|
|||||||
ExportedVar() : val(0), type(VAR_TYPE_INT) {}
|
ExportedVar() : val(0), type(VAR_TYPE_INT) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SelfOverrideObj {
|
||||||
|
fo::GameObject* object;
|
||||||
|
char counter;
|
||||||
|
|
||||||
|
bool UnSetSelf() {
|
||||||
|
if (counter) counter--;
|
||||||
|
return counter == 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static std::vector<std::string> globalScriptPathList;
|
static std::vector<std::string> globalScriptPathList;
|
||||||
static std::map<std::string, std::string> globalScriptFilesList;
|
static std::map<std::string, std::string> globalScriptFilesList;
|
||||||
|
|
||||||
@@ -83,7 +93,7 @@ typedef std::unordered_map<fo::Program*, ScriptProgram> SfallProgsMap;
|
|||||||
static SfallProgsMap sfallProgsMap;
|
static SfallProgsMap sfallProgsMap;
|
||||||
|
|
||||||
// a map scriptPtr => self_obj to override self_obj for all script types using set_self
|
// a map scriptPtr => self_obj to override self_obj for all script types using set_self
|
||||||
std::unordered_map<fo::Program*, fo::GameObject*> selfOverrideMap;
|
std::unordered_map<fo::Program*, SelfOverrideObj> selfOverrideMap;
|
||||||
|
|
||||||
typedef std::unordered_map<std::string, ExportedVar> ExportedVarsMap;
|
typedef std::unordered_map<std::string, ExportedVar> ExportedVarsMap;
|
||||||
static ExportedVarsMap globalExportedVars;
|
static ExportedVarsMap globalExportedVars;
|
||||||
@@ -98,23 +108,24 @@ DWORD availableGlobalScriptTypes = 0;
|
|||||||
bool isGameLoading;
|
bool isGameLoading;
|
||||||
bool alwaysFindScripts;
|
bool alwaysFindScripts;
|
||||||
|
|
||||||
fo::ScriptInstance overrideScriptStruct;
|
fo::ScriptInstance overrideScriptStruct = {0};
|
||||||
|
|
||||||
static const DWORD scr_ptr_back = fo::funcoffs::scr_ptr_ + 5;
|
static const DWORD scr_ptr_back = fo::funcoffs::scr_ptr_ + 5;
|
||||||
static const DWORD scr_find_sid_from_program = fo::funcoffs::scr_find_sid_from_program_ + 5;
|
static const DWORD scr_find_sid_from_program = fo::funcoffs::scr_find_sid_from_program_ + 5;
|
||||||
static const DWORD scr_find_obj_from_program = fo::funcoffs::scr_find_obj_from_program_ + 7;
|
static const DWORD scr_find_obj_from_program = fo::funcoffs::scr_find_obj_from_program_ + 7;
|
||||||
|
|
||||||
static DWORD _stdcall FindSid(fo::Program* script) {
|
static DWORD _stdcall FindSid(fo::Program* script) {
|
||||||
std::unordered_map<fo::Program*, fo::GameObject*>::iterator overrideIt = selfOverrideMap.find(script);
|
std::unordered_map<fo::Program*, SelfOverrideObj>::iterator overrideIt = selfOverrideMap.find(script);
|
||||||
if (overrideIt != selfOverrideMap.end()) {
|
if (overrideIt != selfOverrideMap.end()) {
|
||||||
DWORD scriptId = overrideIt->second->scriptId;
|
DWORD scriptId = overrideIt->second.object->scriptId; // script
|
||||||
|
overrideScriptStruct.id = scriptId;
|
||||||
if (scriptId != -1) {
|
if (scriptId != -1) {
|
||||||
selfOverrideMap.erase(overrideIt);
|
if (overrideIt->second.UnSetSelf()) selfOverrideMap.erase(overrideIt);
|
||||||
return scriptId; // returns the real scriptId of object if it is scripted
|
return scriptId; // returns the real scriptId of object if it is scripted
|
||||||
}
|
}
|
||||||
overrideScriptStruct.selfObject = overrideIt->second;
|
overrideScriptStruct.selfObject = overrideIt->second.object;
|
||||||
overrideScriptStruct.targetObject = overrideIt->second;
|
overrideScriptStruct.targetObject = overrideIt->second.object;
|
||||||
selfOverrideMap.erase(overrideIt); // this reverts self_obj back to original value for next function calls
|
if (overrideIt->second.UnSetSelf()) selfOverrideMap.erase(overrideIt); // this reverts self_obj back to original value for next function calls
|
||||||
return -2; // override struct
|
return -2; // override struct
|
||||||
}
|
}
|
||||||
// this will allow to use functions like roll_vs_skill, etc without calling set_self (they don't really need self object)
|
// this will allow to use functions like roll_vs_skill, etc without calling set_self (they don't really need self object)
|
||||||
@@ -142,12 +153,16 @@ static void __declspec(naked) FindSidHack() {
|
|||||||
retn;
|
retn;
|
||||||
override_script:
|
override_script:
|
||||||
test edx, edx;
|
test edx, edx;
|
||||||
jz end;
|
jz skip;
|
||||||
add esp, 4;
|
add esp, 4;
|
||||||
lea eax, overrideScriptStruct;
|
lea eax, overrideScriptStruct;
|
||||||
mov [edx], eax;
|
mov [edx], eax;
|
||||||
mov eax, -2;
|
mov eax, -2;
|
||||||
retn;
|
retn;
|
||||||
|
skip:
|
||||||
|
add esp, 4;
|
||||||
|
dec eax; // set -3;
|
||||||
|
retn;
|
||||||
end:
|
end:
|
||||||
pop eax;
|
pop eax;
|
||||||
push ebx;
|
push ebx;
|
||||||
@@ -162,7 +177,15 @@ end:
|
|||||||
static void __declspec(naked) ScrPtrHack() {
|
static void __declspec(naked) ScrPtrHack() {
|
||||||
__asm {
|
__asm {
|
||||||
cmp eax, -2;
|
cmp eax, -2;
|
||||||
jnz end;
|
jnz skip;
|
||||||
|
xor eax, eax;
|
||||||
|
retn;
|
||||||
|
skip:
|
||||||
|
cmp eax, -3;
|
||||||
|
jne end;
|
||||||
|
lea eax, overrideScriptStruct;
|
||||||
|
mov [edx], eax;
|
||||||
|
mov esi, [eax]; // script.id
|
||||||
xor eax, eax;
|
xor eax, eax;
|
||||||
retn;
|
retn;
|
||||||
end:
|
end:
|
||||||
@@ -360,13 +383,21 @@ DWORD _stdcall GetGlobalVarInt(DWORD var) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _stdcall SetSelfObject(fo::Program* script, fo::GameObject* obj) {
|
void _stdcall SetSelfObject(fo::Program* script, fo::GameObject* obj) {
|
||||||
|
std::unordered_map<fo::Program*, SelfOverrideObj>::iterator it = selfOverrideMap.find(script);
|
||||||
|
bool isFind = (it != selfOverrideMap.end());
|
||||||
if (obj) {
|
if (obj) {
|
||||||
selfOverrideMap[script] = obj;
|
if (isFind)
|
||||||
} else {
|
if (it->second.object == obj)
|
||||||
std::unordered_map<fo::Program*, fo::GameObject*>::iterator it = selfOverrideMap.find(script);
|
it->second.counter = 2;
|
||||||
if (it != selfOverrideMap.end()) {
|
else {
|
||||||
selfOverrideMap.erase(it);
|
it->second.object = obj;
|
||||||
|
it->second.counter = 0;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
selfOverrideMap[script] = {obj, 0};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isFind) selfOverrideMap.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,7 +579,7 @@ static void RunScript(GlobalScript* script) {
|
|||||||
- reset reg_anim_* combatstate checks
|
- reset reg_anim_* combatstate checks
|
||||||
*/
|
*/
|
||||||
static void ResetStateAfterFrame() {
|
static void ResetStateAfterFrame() {
|
||||||
if (tempArrays.size()) {
|
if (!tempArrays.empty()) {
|
||||||
for (std::set<DWORD>::iterator it = tempArrays.begin(); it != tempArrays.end(); ++it)
|
for (std::set<DWORD>::iterator it = tempArrays.begin(); it != tempArrays.end(); ++it)
|
||||||
FreeArray(*it);
|
FreeArray(*it);
|
||||||
tempArrays.clear();
|
tempArrays.clear();
|
||||||
@@ -702,7 +733,6 @@ void ScriptExtender::init() {
|
|||||||
|
|
||||||
MakeJump(0x4A390C, FindSidHack);
|
MakeJump(0x4A390C, FindSidHack);
|
||||||
MakeJump(0x4A5E34, ScrPtrHack);
|
MakeJump(0x4A5E34, ScrPtrHack);
|
||||||
memset(&overrideScriptStruct, 0, sizeof(fo::ScriptInstance));
|
|
||||||
|
|
||||||
MakeJump(0x4A67F0, ExecMapScriptsHack);
|
MakeJump(0x4A67F0, ExecMapScriptsHack);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user