From 19bcfebe0d9b59088d54d39d28fe352ec062b9bb Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 7 Nov 2022 20:41:33 +0300 Subject: [PATCH] Add ammo/charges opcodes See #200 --- src/sfall_opcodes.cc | 72 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/src/sfall_opcodes.cc b/src/sfall_opcodes.cc index 8cf5954..55d09d9 100644 --- a/src/sfall_opcodes.cc +++ b/src/sfall_opcodes.cc @@ -3,6 +3,7 @@ #include "art.h" #include "interface.h" #include "interpreter.h" +#include "item.h" #include "mouse.h" #include "svga.h" @@ -14,6 +15,74 @@ static void opGetCurrentHand(Program* program) programStackPushInteger(program, interfaceGetCurrentHand()); } +// get_weapon_ammo_pid +static void opGetWeaponAmmoPid(Program* program) +{ + Object* obj = static_cast(programStackPopPointer(program)); + + int pid = -1; + if (obj != nullptr) { + if (PID_TYPE(obj->pid) == OBJ_TYPE_ITEM) { + switch (itemGetType(obj)) { + case ITEM_TYPE_WEAPON: + pid = weaponGetAmmoTypePid(obj); + break; + case ITEM_TYPE_MISC: + pid = miscItemGetPowerTypePid(obj); + break; + } + } + } + + programStackPushInteger(program, pid); +} + +// get_weapon_ammo_count +static void opGetWeaponAmmoCount(Program* program) +{ + Object* obj = static_cast(programStackPopPointer(program)); + + // CE: Implementation is different. + int ammoQuantityOrCharges = 0; + if (obj != nullptr) { + if (PID_TYPE(obj->pid) == OBJ_TYPE_ITEM) { + switch (itemGetType(obj)) { + case ITEM_TYPE_AMMO: + case ITEM_TYPE_WEAPON: + ammoQuantityOrCharges = ammoGetQuantity(obj); + break; + case ITEM_TYPE_MISC: + ammoQuantityOrCharges = miscItemGetCharges(obj); + break; + } + } + } + + programStackPushInteger(program, ammoQuantityOrCharges); +} + +// set_weapon_ammo_count +static void opSetWeaponAmmoCount(Program* program) +{ + int ammoQuantityOrCharges = programStackPopInteger(program); + Object* obj = static_cast(programStackPopPointer(program)); + + // CE: Implementation is different. + if (obj != nullptr) { + if (PID_TYPE(obj->pid) == OBJ_TYPE_ITEM) { + switch (itemGetType(obj)) { + case ITEM_TYPE_AMMO: + case ITEM_TYPE_WEAPON: + ammoSetQuantity(obj, ammoQuantityOrCharges); + break; + case ITEM_TYPE_MISC: + miscItemSetCharges(obj, ammoQuantityOrCharges); + break; + } + } + } +} + // get_mouse_x static void opGetMouseX(Program* program) { @@ -80,6 +149,9 @@ static void opArtExists(Program* program) void sfallOpcodesInit() { interpreterRegisterOpcode(0x8193, opGetCurrentHand); + interpreterRegisterOpcode(0x8217, opGetWeaponAmmoPid); + interpreterRegisterOpcode(0x8219, opGetWeaponAmmoCount); + interpreterRegisterOpcode(0x821A, opSetWeaponAmmoCount); interpreterRegisterOpcode(0x821C, opGetMouseX); interpreterRegisterOpcode(0x821D, opGetMouseY); interpreterRegisterOpcode(0x8220, opGetScreenWidth);