Fixed set_self function for use_obj_on_obj, attack, attack_complex vanilla functions (from Mr.Stalin) (#214)

This commit is contained in:
NovaRain
2019-01-21 09:56:06 +08:00
parent 46850a353b
commit a95f26a02d
2 changed files with 49 additions and 18 deletions
+2 -1
View File
@@ -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.
+47 -17
View File
@@ -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);