mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Rewrote some script functions in ObjectsOps in C++
* remove_script, set/get_script, set_critter_burst_disable. Changed the return value of get_script to 0 for unscripted objects.
This commit is contained in:
@@ -153,12 +153,13 @@ array - array ID to be used with array-related functions (actually an integer)
|
||||
- accepts a pointer to an object and will remove the script from that object.
|
||||
|
||||
> void set_script(object, int scriptid)
|
||||
- accepts a pointer to an object and scriptID, and applies the given script to an object (scriptID accept the same values as create_object_sid from sfall 3.6)
|
||||
- accepts a pointer to an object and scriptID, and applies the given script to an object (scriptID accepts the same values as create_object_sid)
|
||||
- If used on an object that is already scripted, it will remove the existing script first; you cannot have multiple scripts attached to a single object. Calling set_script on self_obj will have all sorts of wacky side effects, and should be avoided.
|
||||
- if you add 0x80000000 to the sid when calling set_script, map_enter_p_proc will be SKIPPED. The start proc will always be run.
|
||||
|
||||
> int get_script(object)
|
||||
- accepts a pointer to an object and returns its scriptID (line number in scripts.lst), or -1 if the object is unscripted.
|
||||
- accepts a pointer to an object and returns its scriptID (line number in scripts.lst), or 0 if the object is unscripted.
|
||||
- returns -1 on argument error.
|
||||
|
||||
> void set_self(int obj)
|
||||
- overrides the scripts self_obj for the next function call.
|
||||
|
||||
+2
-2
@@ -243,7 +243,7 @@ static void __declspec(naked) determine_to_hit_func_hack() {
|
||||
}
|
||||
|
||||
static long __fastcall CheckDisableBurst(TGameObj* critter) {
|
||||
for (DWORD i = 0; i < noBursts.size(); i++) {
|
||||
for (size_t i = 0; i < noBursts.size(); i++) {
|
||||
if (noBursts[i] == critter->ID) {
|
||||
return 10; // Disable Burst (area_attack_mode - non-existent value)
|
||||
}
|
||||
@@ -354,7 +354,7 @@ void _stdcall SetHitChanceMax(TGameObj* critter, DWORD maximum, DWORD mod) {
|
||||
hitChanceMods.push_back(cm);
|
||||
}
|
||||
|
||||
void _stdcall SetNoBurstMode(TGameObj* critter, DWORD on) {
|
||||
void _stdcall SetNoBurstMode(TGameObj* critter, bool on) {
|
||||
if (critter == *ptr_obj_dude || critter->pid >> 24 != OBJ_TYPE_CRITTER) return;
|
||||
|
||||
long id = SetObjectUniqueID(critter);
|
||||
|
||||
+1
-1
@@ -29,6 +29,6 @@ void _stdcall KnockbackSetMod(TGameObj* object, DWORD type, float val, DWORD mod
|
||||
void _stdcall KnockbackRemoveMod(TGameObj* object, DWORD mode);
|
||||
void CombatInit();
|
||||
void Combat_OnGameLoad();
|
||||
void _stdcall SetNoBurstMode(TGameObj* critter, DWORD on);
|
||||
void _stdcall SetNoBurstMode(TGameObj* critter, bool on);
|
||||
void _stdcall DisableAimedShots(DWORD pid);
|
||||
void _stdcall ForceAimedShots(DWORD pid);
|
||||
|
||||
+33
-3
@@ -873,16 +873,38 @@ void SkillSetTags(int* tags, DWORD num) {
|
||||
}
|
||||
}
|
||||
|
||||
TGameObj* __stdcall ScrFindObjFromProgram(TProgram* program) {
|
||||
__asm {
|
||||
mov eax, program;
|
||||
call scr_find_obj_from_program_;
|
||||
}
|
||||
}
|
||||
|
||||
// Saves pointer to script object into scriptPtr using scriptID.
|
||||
// Returns 0 on success, -1 on failure.
|
||||
long __stdcall ScrPtr(long scriptId, TScript** scriptPtr) {
|
||||
__asm {
|
||||
mov eax, scriptId;
|
||||
mov edx, scriptPtr;
|
||||
mov eax, scriptId;
|
||||
call scr_ptr_;
|
||||
}
|
||||
}
|
||||
|
||||
long __stdcall ScrNew(long* scriptID, long sType) {
|
||||
__asm {
|
||||
mov edx, sType;
|
||||
mov eax, scriptID;
|
||||
call scr_new_;
|
||||
}
|
||||
}
|
||||
|
||||
long __stdcall ScrRemove(long scriptID) {
|
||||
__asm {
|
||||
mov eax, scriptID;
|
||||
call scr_remove_;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the number of local variables of the object script
|
||||
long GetScriptLocalVars(long sid) {
|
||||
TScript* script = nullptr;
|
||||
@@ -1037,10 +1059,10 @@ TGameObj* __stdcall InvenRightHand(TGameObj* critter) {
|
||||
}
|
||||
}
|
||||
|
||||
long __fastcall CreateWindowFunc(const char* winName, long x, long y, long width, long height, long bgColorIndex, long flags) {
|
||||
long __fastcall CreateWindowFunc(const char* winName, DWORD x, DWORD y, DWORD width, DWORD height, long color, long flags) {
|
||||
__asm {
|
||||
push flags;
|
||||
push bgColorIndex;
|
||||
push color;
|
||||
push height;
|
||||
mov eax, ecx;
|
||||
mov ebx, y;
|
||||
@@ -1300,6 +1322,14 @@ TGameObj* __fastcall ObjBlockingAt(TGameObj* object, long tile, long elevation)
|
||||
}
|
||||
}
|
||||
|
||||
long __fastcall ObjNewSidInst(TGameObj* object, long sType, long scriptIndex) {
|
||||
__asm {
|
||||
mov ebx, scriptIndex;
|
||||
mov eax, ecx;
|
||||
call obj_new_sid_inst_;
|
||||
}
|
||||
}
|
||||
|
||||
long __fastcall TileNumInDirection(long tile, long rotation, long distance) {
|
||||
__asm {
|
||||
mov ebx, distance;
|
||||
|
||||
@@ -1042,10 +1042,16 @@ void __stdcall CritterPcSetName(const char* newName);
|
||||
// Checks if given file exists in DB
|
||||
bool __stdcall DbAccess(const char* fileName);
|
||||
|
||||
TGameObj* __stdcall ScrFindObjFromProgram(TProgram* program);
|
||||
|
||||
// Saves pointer to script object into scriptPtr using scriptID.
|
||||
// Returns 0 on success, -1 on failure.
|
||||
long __stdcall ScrPtr(long scriptId, TScript** scriptPtr);
|
||||
|
||||
long __stdcall ScrNew(long* scriptID, long sType);
|
||||
|
||||
long __stdcall ScrRemove(long scriptID);
|
||||
|
||||
// Returns the number of local variables of the object script
|
||||
long GetScriptLocalVars(long sid);
|
||||
|
||||
@@ -1099,7 +1105,7 @@ void __declspec() InterpretError(const char* fmt, ...);
|
||||
const char* __stdcall FindCurrentProc(TProgram* program);
|
||||
|
||||
// creates a window with the name and flags
|
||||
long __fastcall CreateWindowFunc(const char* winName, long x, long y, long width, long height, long bgColorIndex, long flags);
|
||||
long __fastcall CreateWindowFunc(const char* winName, DWORD x, DWORD y, DWORD width, DWORD height, long color, long flags);
|
||||
|
||||
// creates a button
|
||||
long __stdcall WinRegisterButton(DWORD winRef, long xPos, long yPos, long width, long height, long hoverOn, long hoverOff, long buttonDown, long buttonUp, BYTE* pictureUp, BYTE* pictureDown, long arg12, long buttonType);
|
||||
@@ -1156,6 +1162,8 @@ void __stdcall MapDirErase(const char* folder, const char* ext);
|
||||
|
||||
TGameObj* __fastcall ObjBlockingAt(TGameObj* object, long tile, long elevation);
|
||||
|
||||
long __fastcall ObjNewSidInst(TGameObj* object, long sType, long scriptIndex);
|
||||
|
||||
long __fastcall TileNumInDirection(long tile, long rotation, long distance);
|
||||
|
||||
long __stdcall TileDir(long scrTile, long dstTile);
|
||||
|
||||
@@ -128,7 +128,7 @@ struct TScript {
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
enum ScriptTypes
|
||||
enum ScriptTypes : long
|
||||
{
|
||||
SCRIPT_SYSTEM = 0,
|
||||
SCRIPT_SPATIAL = 1,
|
||||
@@ -138,7 +138,7 @@ enum ScriptTypes
|
||||
};
|
||||
|
||||
/* 24 */
|
||||
enum ObjectTypes
|
||||
enum ObjectTypes : char
|
||||
{
|
||||
OBJ_TYPE_ITEM = 0,
|
||||
OBJ_TYPE_CRITTER = 1,
|
||||
|
||||
+94
-167
@@ -24,97 +24,66 @@
|
||||
#include "Objects.h"
|
||||
#include "PartyControl.h"
|
||||
|
||||
//script control functions
|
||||
#define exec_script_proc(script, proc) __asm { \
|
||||
__asm mov eax, script \
|
||||
__asm mov edx, proc \
|
||||
__asm call exec_script_proc_ \
|
||||
}
|
||||
|
||||
// TODO: rewrite
|
||||
static void __declspec(naked) RemoveScript() {
|
||||
__asm {
|
||||
push ebx;
|
||||
push ecx;
|
||||
push edx;
|
||||
mov ecx, eax;
|
||||
call interpretPopShort_;
|
||||
mov edx, eax;
|
||||
mov eax, ecx;
|
||||
call interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
test eax, eax;
|
||||
jz end;
|
||||
mov edx, eax;
|
||||
mov eax, [eax+0x78];
|
||||
cmp eax, 0xffffffff;
|
||||
jz end;
|
||||
call scr_remove_
|
||||
mov dword ptr [edx+0x78], 0xffffffff;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
pop ebx;
|
||||
retn;
|
||||
static void _stdcall RemoveScript2() {
|
||||
TGameObj* object = opHandler.arg(0).asObject();
|
||||
if (object) {
|
||||
if (object->scriptID != 0xFFFFFFFF) {
|
||||
ScrRemove(object->scriptID);
|
||||
object->scriptID = 0xFFFFFFFF;
|
||||
}
|
||||
} else {
|
||||
OpcodeInvalidArgs("remove_script");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: rewrite
|
||||
static void __declspec(naked) SetScript() {
|
||||
__asm {
|
||||
pushad;
|
||||
mov ecx, eax;
|
||||
call interpretPopShort_;
|
||||
mov edx, eax;
|
||||
mov eax, ecx;
|
||||
call interpretPopLong_;
|
||||
mov ebx, eax;
|
||||
mov eax, ecx;
|
||||
call interpretPopShort_;
|
||||
mov edi, eax;
|
||||
mov eax, ecx;
|
||||
call interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
cmp di, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
test eax, eax;
|
||||
jz end;
|
||||
mov esi, [eax+0x78];
|
||||
cmp esi, 0xffffffff;
|
||||
jz newscript
|
||||
push eax;
|
||||
mov eax, esi;
|
||||
call scr_remove_
|
||||
pop eax;
|
||||
mov dword ptr [eax+0x78], 0xffffffff;
|
||||
newscript:
|
||||
mov esi, 1;
|
||||
test ebx, 0x80000000;
|
||||
jz execMapEnter;
|
||||
xor esi, esi;
|
||||
xor ebx, 0x80000000;
|
||||
execMapEnter:
|
||||
mov ecx, eax;
|
||||
mov edx, 3; // script_type_item
|
||||
mov edi, [eax+0x64];
|
||||
shr edi, 24;
|
||||
cmp edi, 1;
|
||||
jnz notCritter;
|
||||
inc edx; // 4 - "critter" type script
|
||||
notCritter:
|
||||
dec ebx;
|
||||
call obj_new_sid_inst_
|
||||
mov eax, [ecx+0x78];
|
||||
mov edx, 1; // start
|
||||
call exec_script_proc_
|
||||
cmp esi, 1; // run map enter?
|
||||
jnz end;
|
||||
mov eax, [ecx+0x78];
|
||||
mov edx, 0xf; // map_enter_p_proc
|
||||
call exec_script_proc_
|
||||
end:
|
||||
popad;
|
||||
retn;
|
||||
static void __declspec(naked) RemoveScript() {
|
||||
_WRAP_OPCODE(RemoveScript2, 1, 0)
|
||||
}
|
||||
|
||||
static void _stdcall SetScript2() {
|
||||
TGameObj* object = opHandler.arg(0).asObject();
|
||||
const ScriptValue &scriptIdxArg = opHandler.arg(1);
|
||||
|
||||
if (object && scriptIdxArg.isInt()) {
|
||||
long scriptType;
|
||||
unsigned long valArg = scriptIdxArg.rawValue();
|
||||
|
||||
long scriptIndex = valArg & ~0xF0000000;
|
||||
if (scriptIndex == 0 || valArg > 0x8FFFFFFF) { // negative values are not allowed
|
||||
opHandler.printOpcodeError("set_script() - the script index number is incorrect.");
|
||||
return;
|
||||
}
|
||||
scriptIndex--;
|
||||
|
||||
if (object->scriptID != 0xFFFFFFFF) {
|
||||
ScrRemove(object->scriptID);
|
||||
object->scriptID = 0xFFFFFFFF;
|
||||
}
|
||||
if (object->pid >> 24 == OBJ_TYPE_CRITTER) {
|
||||
scriptType = SCRIPT_CRITTER;
|
||||
} else {
|
||||
scriptType = SCRIPT_ITEM;
|
||||
}
|
||||
ObjNewSidInst(object, scriptType, scriptIndex);
|
||||
|
||||
long scriptId = object->scriptID;
|
||||
exec_script_proc(scriptId, start);
|
||||
if ((valArg & 0x80000000) == 0) exec_script_proc(scriptId, map_enter_p_proc);
|
||||
} else {
|
||||
OpcodeInvalidArgs("set_script");
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) SetScript() {
|
||||
_WRAP_OPCODE(SetScript2, 2, 0)
|
||||
}
|
||||
|
||||
static void _stdcall op_create_spatial2() {
|
||||
const ScriptValue &scriptIdxArg = opHandler.arg(0),
|
||||
&tileArg = opHandler.arg(1),
|
||||
@@ -125,38 +94,21 @@ static void _stdcall op_create_spatial2() {
|
||||
DWORD scriptIndex = scriptIdxArg.rawValue(),
|
||||
tile = tileArg.rawValue(),
|
||||
elevation = elevArg.rawValue(),
|
||||
radius = radiusArg.rawValue(),
|
||||
scriptId, tmp, objectPtr,
|
||||
scriptPtr;
|
||||
__asm {
|
||||
lea eax, scriptId;
|
||||
mov edx, 1;
|
||||
call scr_new_;
|
||||
mov tmp, eax;
|
||||
}
|
||||
if (tmp == -1) return;
|
||||
__asm {
|
||||
mov eax, scriptId;
|
||||
lea edx, scriptPtr;
|
||||
call scr_ptr_;
|
||||
mov tmp, eax;
|
||||
}
|
||||
if (tmp == -1) return;
|
||||
// fill spatial script properties:
|
||||
*(DWORD*)(scriptPtr + 0x14) = scriptIndex - 1;
|
||||
*(DWORD*)(scriptPtr + 0x8) = (elevation << 29) & 0xE0000000 | tile;
|
||||
*(DWORD*)(scriptPtr + 0xC) = radius;
|
||||
radius = radiusArg.rawValue();
|
||||
|
||||
long scriptId;
|
||||
TScript* scriptPtr;
|
||||
if (ScrNew(&scriptId, SCRIPT_SPATIAL) == -1 || ScrPtr(scriptId, &scriptPtr) == -1) return;
|
||||
|
||||
// set spatial script properties:
|
||||
scriptPtr->script_index = scriptIndex - 1;
|
||||
scriptPtr->elevation_and_tile = (elevation << 29) & 0xE0000000 | tile;
|
||||
scriptPtr->spatial_radius = radius;
|
||||
|
||||
// this will load appropriate script program and link it to the script instance we just created:
|
||||
__asm {
|
||||
mov eax, scriptId;
|
||||
mov edx, 1; // start_p_proc
|
||||
call exec_script_proc_;
|
||||
mov eax, scriptPtr;
|
||||
mov eax, [eax + 0x18]; // program pointer
|
||||
call scr_find_obj_from_program_;
|
||||
mov objectPtr, eax;
|
||||
}
|
||||
opHandler.setReturn(objectPtr);
|
||||
exec_script_proc(scriptId, start);
|
||||
|
||||
opHandler.setReturn(ScrFindObjFromProgram(scriptPtr->program_ptr));
|
||||
} else {
|
||||
OpcodeInvalidArgs("create_spatial");
|
||||
opHandler.setReturn(0);
|
||||
@@ -180,64 +132,36 @@ static void sf_spatial_radius() {
|
||||
}
|
||||
}
|
||||
|
||||
static void _stdcall GetScript2() {
|
||||
TGameObj* object = opHandler.arg(0).asObject();
|
||||
if (object) {
|
||||
long scriptIndex = object->script_index;
|
||||
opHandler.setReturn((scriptIndex >= 0) ? ++scriptIndex : 0);
|
||||
} else {
|
||||
OpcodeInvalidArgs("get_script");
|
||||
opHandler.setReturn(-1);
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) GetScript() {
|
||||
__asm {
|
||||
pushad;
|
||||
mov ecx, eax;
|
||||
mov ecx, eax;
|
||||
call interpretPopShort_;
|
||||
mov edx, eax;
|
||||
mov eax, ecx;
|
||||
call interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_INT;
|
||||
jnz fail;
|
||||
test eax, eax;
|
||||
jz fail;
|
||||
mov edx, [eax+0x80];
|
||||
cmp edx, -1;
|
||||
jz fail;
|
||||
inc edx;
|
||||
jmp end;
|
||||
fail:
|
||||
xor edx, edx;
|
||||
dec edx;
|
||||
end:
|
||||
mov eax, ecx;
|
||||
call interpretPushLong_;
|
||||
mov eax, ecx;
|
||||
mov edx, VAR_TYPE_INT;
|
||||
call interpretPushShort_;
|
||||
popad;
|
||||
retn;
|
||||
_WRAP_OPCODE(GetScript2, 1, 1)
|
||||
}
|
||||
|
||||
static void _stdcall set_critter_burst_disable2() {
|
||||
TGameObj* critter = opHandler.arg(0).asObject();
|
||||
const ScriptValue &disableArg = opHandler.arg(1);
|
||||
|
||||
if (critter && disableArg.isInt()) {
|
||||
SetNoBurstMode(critter, disableArg.asBool());
|
||||
} else {
|
||||
OpcodeInvalidArgs("set_critter_burst_disable");
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) set_critter_burst_disable() {
|
||||
__asm {
|
||||
pushad;
|
||||
mov ebp, eax;
|
||||
call interpretPopShort_;
|
||||
mov edi, eax;
|
||||
mov eax, ebp;
|
||||
call interpretPopLong_;
|
||||
mov ecx, eax;
|
||||
mov eax, ebp;
|
||||
call interpretPopShort_;
|
||||
mov esi, eax;
|
||||
mov eax, ebp;
|
||||
call interpretPopLong_;
|
||||
cmp di, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
cmp si, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
push ecx;
|
||||
push eax;
|
||||
call SetNoBurstMode;
|
||||
end:
|
||||
popad;
|
||||
retn;
|
||||
}
|
||||
_WRAP_OPCODE(set_critter_burst_disable2, 2, 0)
|
||||
}
|
||||
|
||||
static void __declspec(naked) get_weapon_ammo_pid() {
|
||||
__asm {
|
||||
pushad;
|
||||
@@ -265,6 +189,7 @@ end:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) set_weapon_ammo_pid() {
|
||||
__asm {
|
||||
pushad;
|
||||
@@ -291,6 +216,7 @@ end:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) get_weapon_ammo_count() {
|
||||
__asm {
|
||||
pushad;
|
||||
@@ -317,6 +243,7 @@ end:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) set_weapon_ammo_count() {
|
||||
__asm {
|
||||
pushad;
|
||||
|
||||
@@ -529,11 +529,7 @@ static void FillListVector(DWORD type, std::vector<TGameObj*>& vec) {
|
||||
self_obj = scriptPtr->self_obj;
|
||||
if (self_obj == nullptr) {
|
||||
programPtr = scriptPtr->program_ptr;
|
||||
__asm {
|
||||
mov eax, programPtr;
|
||||
call scr_find_obj_from_program_;
|
||||
mov self_obj, eax;
|
||||
}
|
||||
self_obj = ScrFindObjFromProgram(programPtr);
|
||||
}
|
||||
vec.push_back(self_obj);
|
||||
__asm {
|
||||
|
||||
Reference in New Issue
Block a user