Add op_set_self

This commit is contained in:
Alexander Batalov 2023-09-03 18:23:19 +03:00
parent ad3e0eb752
commit 6e9f1ae517
4 changed files with 39 additions and 2 deletions

View File

@ -1580,12 +1580,22 @@ static void opPickup(Program* program)
return;
}
if (script->target == NULL) {
Object* self = script->target;
// SFALL: Override `self` via `op_set_self`.
// CE: Implementation is different. Sfall integrates via `scriptGetSid` by
// returning fake script with overridden `self` (and `target` in this case).
if (script->overriddenSelf != nullptr) {
self = script->overriddenSelf;
script->overriddenSelf = nullptr;
}
if (self == NULL) {
scriptPredefinedError(program, "pickup_obj", SCRIPT_ERROR_OBJECT_IS_NULL);
return;
}
actionPickUp(script->target, object);
actionPickUp(self, object);
}
// drop_obj
@ -4548,6 +4558,15 @@ static void opUseObjectOnObject(Program* program)
}
Object* self = scriptGetSelf(program);
// SFALL: Override `self` via `op_set_self`.
// CE: Implementation is different. Sfall integrates via `scriptGetSid` by
// returning fake script with overridden `self`.
if (script->overriddenSelf != nullptr) {
self = script->overriddenSelf;
script->overriddenSelf = nullptr;
}
if (PID_TYPE(self->pid) == OBJ_TYPE_CRITTER) {
_action_use_an_item_on_object(self, target, item);
} else {

View File

@ -2214,6 +2214,8 @@ int scriptAdd(int* sidPtr, int scriptType)
scr->procs[index] = SCRIPT_PROC_NO_PROC;
}
scr->overriddenSelf = nullptr;
scriptListExtent->length++;
return 0;

View File

@ -143,6 +143,8 @@ typedef struct Script {
int field_D4;
int field_D8;
int field_DC;
Object* overriddenSelf;
} Script;
extern const char* gScriptProcNames[SCRIPT_PROC_COUNT];

View File

@ -345,6 +345,19 @@ static void op_set_proto_data(Program* program)
*reinterpret_cast<int*>(reinterpret_cast<unsigned char*>(proto) + offset) = value;
}
// set_self
static void op_set_self(Program* program)
{
Object* obj = static_cast<Object*>(programStackPopPointer(program));
int sid = scriptGetSid(program);
Script* scr;
if (scriptGetScript(sid, &scr) == 0) {
scr->overriddenSelf = obj;
}
}
// list_begin
static void opListBegin(Program* program)
{
@ -1055,6 +1068,7 @@ void sfallOpcodesInit()
interpreterRegisterOpcode(0x81F5, op_get_script);
interpreterRegisterOpcode(0x8204, op_get_proto_data);
interpreterRegisterOpcode(0x8205, op_set_proto_data);
interpreterRegisterOpcode(0x8206, op_set_self);
interpreterRegisterOpcode(0x820D, opListBegin);
interpreterRegisterOpcode(0x820E, opListNext);
interpreterRegisterOpcode(0x820F, opListEnd);