mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-08-29 23:51:49 -04:00
update item service and fix master sword checks
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include <mods/svc/log.hpp>
|
||||
#include <mods/items.h>
|
||||
|
||||
#include "Z2AudioLib/Z2SceneMgr.h"
|
||||
#include "c/c_damagereaction.h"
|
||||
#include "d/actor/d_a_alink.h"
|
||||
#include "d/actor/d_a_b_bq.h"
|
||||
@@ -33,18 +34,20 @@
|
||||
#include "d/actor/d_a_npc_zrc.h"
|
||||
#include "d/actor/d_a_npc_zrz.h"
|
||||
#include "d/actor/d_a_obj_bosswarp.h"
|
||||
#include "d/actor/d_a_shop_item.h"
|
||||
#include "d/actor/d_a_obj_swBallC.h"
|
||||
#include "d/actor/d_a_obj_zra_rock.h"
|
||||
#include "d/actor/d_a_tag_kmsg.h"
|
||||
#include "d/actor/d_a_tbox2.h"
|
||||
#include "d/actor/d_a_obj_item.h"
|
||||
#include "d/actor/d_a_obj_life_container.h"
|
||||
#include "d/actor/d_a_obj_master_sword.h"
|
||||
#include "d/actor/d_a_obj_swBallC.h"
|
||||
#include "d/actor/d_a_obj_zra_rock.h"
|
||||
#include "d/actor/d_a_shop_item.h"
|
||||
#include "d/actor/d_a_tag_kmsg.h"
|
||||
#include "d/actor/d_a_tbox2.h"
|
||||
#include "d/d_door_param2.h"
|
||||
#include "d/d_event.h"
|
||||
#include "d/d_file_sel_info.h"
|
||||
#include "d/d_file_select.h"
|
||||
#include "d/d_gameover.h"
|
||||
#include "d/d_item.h"
|
||||
#include "d/d_menu_item_explain.h"
|
||||
#include "d/d_menu_ring.h"
|
||||
#include "d/d_meter2_info.h"
|
||||
@@ -53,10 +56,8 @@
|
||||
#include "d/d_s_play.h"
|
||||
#include "d/d_save.h"
|
||||
#include "d/d_shop_system.h"
|
||||
#include "d/d_item.h"
|
||||
#include "f_op/f_op_overlap_mng.h"
|
||||
#include "m_Do/m_Do_Reset.h"
|
||||
#include "Z2AudioLib/Z2SceneMgr.h"
|
||||
|
||||
DEFINE_HOOK(&dFile_select_c::selectDataNameMove, dFile_select_c__selectDataNameMove);
|
||||
DEFINE_HOOK(&dFile_select_c::dataSelect, dFile_select_c__dataSelect);
|
||||
@@ -209,6 +210,8 @@ DEFINE_HOOK_SYMBOL("dComIfGs_getCollectSmell", u8(), getCollectSmell);
|
||||
|
||||
DEFINE_HOOK(&dEvt_control_c::skipper, dEvt_control_c__skipper);
|
||||
|
||||
DEFINE_HOOK(&daObjMasterSword_c::executeWait, daObjMasterSword_c__executeWait);
|
||||
|
||||
namespace randomizer::ui {
|
||||
dialogSelectModeState g_dialogSelectModeState = SelectReady;
|
||||
}
|
||||
@@ -3338,6 +3341,15 @@ void hookReplaceEvtControlSkipper(ModContext*, void* args, void* retval, void*)
|
||||
*static_cast<bool*>(retval) = doSkip;
|
||||
}
|
||||
|
||||
void hookPostMasterSwordExecuteWait(ModContext*, void* args, void* retval, void*) {
|
||||
auto objMasterSword = mods::arg<daObjMasterSword_c*>(args, 0);
|
||||
|
||||
if (fopAcM_checkCarryNow(objMasterSword)) {
|
||||
dComIfGs_onTmpBit(0x820);
|
||||
objMasterSword->actor_status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ModResult initialize() {
|
||||
@@ -3501,6 +3513,8 @@ ModResult initialize() {
|
||||
|
||||
ADD_HOOK_REPLACE(dEvt_control_c__skipper, hookReplaceEvtControlSkipper);
|
||||
|
||||
ADD_HOOK_POST(daObjMasterSword_c__executeWait, hookPostMasterSwordExecuteWait);
|
||||
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
@@ -3636,6 +3650,8 @@ ModResult uninstall() {
|
||||
|
||||
mods::hook::uninstall<dEvt_control_c__skipper>(svc_hook);
|
||||
|
||||
mods::hook::uninstall<daObjMasterSword_c__executeWait>(svc_hook);
|
||||
|
||||
return MOD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#define ITEM_SERVICE_ID "dev.twilitrealm.dusklight.item"
|
||||
#define ITEM_SERVICE_MAJOR 2u
|
||||
#define ITEM_SERVICE_MINOR 2u
|
||||
#define ITEM_SERVICE_MINOR 3u
|
||||
|
||||
/* 0 is never a valid handle. */
|
||||
typedef uint64_t ItemCheckHandle;
|
||||
@@ -32,11 +32,13 @@ typedef struct ItemCheckInfo {
|
||||
uint8_t vanilla_item;
|
||||
uint8_t current_item;
|
||||
uint8_t current_display_item;
|
||||
bool was_resolved;
|
||||
} ItemCheckInfo;
|
||||
|
||||
typedef struct ItemCheckResolution {
|
||||
uint8_t item;
|
||||
uint8_t display_item; /* leave unset (0xFF/NONE) to use the item */
|
||||
bool was_resolved;
|
||||
} ItemCheckResolution;
|
||||
|
||||
/* Return true and write out_result to replace the result, or false to leave it unchanged. */
|
||||
|
||||
@@ -462,7 +462,7 @@ int daDitem_c::create() {
|
||||
m_itemNo = daDitem_prm::getNo(this);
|
||||
|
||||
#if TARGET_PC
|
||||
const auto [item, displayItem] = dusk::mods::item_check_resolve(mItemGiveTag, m_itemNo, this);
|
||||
const auto [item, displayItem, _] = dusk::mods::item_check_resolve(mItemGiveTag, m_itemNo, this);
|
||||
m_itemNo = item;
|
||||
setDisplayItemNo(displayItem);
|
||||
const char* arc_name = dItem_data::getArcName(displayItem);
|
||||
|
||||
@@ -268,7 +268,7 @@ int daItem_c::_daItem_create() {
|
||||
const u32 params = fopAcM_GetParam(this);
|
||||
mOriginalItemNo = params & 0xFF;
|
||||
mItemGiveTag = dusk::mods::item_give_tag_freestanding(daItem_prm::getItemBitNo(this));
|
||||
const auto [item, displayItem] =
|
||||
const auto [item, displayItem, _] =
|
||||
dusk::mods::item_check_resolve(mItemGiveTag, mOriginalItemNo, this);
|
||||
mItemOverridden = item != mOriginalItemNo;
|
||||
setDisplayItemNo(displayItem);
|
||||
|
||||
@@ -153,7 +153,7 @@ int daObjLife_c::create() {
|
||||
if (mItemGiveOriginalNo == dItemNo_NONE_e) {
|
||||
mOriginalItemNo = parameterItemNo;
|
||||
mItemGiveTag = dusk::mods::item_give_tag_freestanding(getSaveBitNo());
|
||||
const auto [item, displayItem] =
|
||||
const auto [item, displayItem, _] =
|
||||
dusk::mods::item_check_resolve(mItemGiveTag, mOriginalItemNo, this);
|
||||
setDisplayItemNo(displayItem);
|
||||
mItemOverridden = item != mOriginalItemNo;
|
||||
@@ -163,7 +163,7 @@ int daObjLife_c::create() {
|
||||
} else if (mGoldenWolfItem) {
|
||||
mOriginalItemNo = mItemGiveOriginalNo;
|
||||
mItemGiveTag = dusk::mods::item_give_tag_golden_wolf(static_cast<u16>(field_0x938));
|
||||
const auto [item, displayItem] =
|
||||
const auto [item, displayItem, _] =
|
||||
dusk::mods::item_check_resolve(mItemGiveTag, mOriginalItemNo, this);
|
||||
setDisplayItemNo(displayItem);
|
||||
mItemOverridden = item != mOriginalItemNo;
|
||||
|
||||
@@ -151,11 +151,7 @@ void daObjMasterSword_c::create_init() {
|
||||
int daObjMasterSword_c::create() {
|
||||
fopAcM_ct(this, daObjMasterSword_c);
|
||||
|
||||
#if TARGET_PC
|
||||
if (dComIfGs_isEventBit(dSv_event_flag_c::F_0264)) {
|
||||
#else
|
||||
if (dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[getFlagNo()])) {
|
||||
#endif
|
||||
return cPhs_ERROR_e;
|
||||
}
|
||||
|
||||
@@ -199,7 +195,7 @@ int daObjMasterSword_c::execute() {
|
||||
#if TARGET_PC
|
||||
const auto masterSword = dusk::mods::item_check_commit(
|
||||
ITEM_CHECK_MASTER_SWORD, dItemNo_MASTER_SWORD_e, this);
|
||||
if (masterSword.itemNo == dItemNo_MASTER_SWORD_e) {
|
||||
if (!masterSword.was_resolved) {
|
||||
dComIfGs_onItemFirstBit(dItemNo_MASTER_SWORD_e);
|
||||
dMeter2Info_setSword(dItemNo_MASTER_SWORD_e, false);
|
||||
dComIfGs_setSelectEquipSword(dItemNo_MASTER_SWORD_e);
|
||||
@@ -214,7 +210,7 @@ int daObjMasterSword_c::execute() {
|
||||
|
||||
const auto shadowCrystal = dusk::mods::item_check_commit(
|
||||
ITEM_CHECK_SHADOW_CRYSTAL, dItemNo_SHADOW_CRYSTAL_e, this);
|
||||
if (shadowCrystal.itemNo == dItemNo_SHADOW_CRYSTAL_e) {
|
||||
if (!shadowCrystal.was_resolved) {
|
||||
execItemGet(shadowCrystal.itemNo, shadowCrystal.tag, this);
|
||||
} else if (shadowCrystal.itemNo == dItemNo_NONE_e) {
|
||||
dusk::mods::item_check_complete(shadowCrystal, this);
|
||||
@@ -222,15 +218,14 @@ int daObjMasterSword_c::execute() {
|
||||
dusk::mods::item_check_enqueue(shadowCrystal, dusk::mods::ItemGiveMode::Demo);
|
||||
}
|
||||
|
||||
dComIfGs_onEventBit(dSv_event_flag_c::F_0264);
|
||||
#else
|
||||
dComIfGs_onItemFirstBit(dItemNo_MASTER_SWORD_e);
|
||||
dMeter2Info_setSword(dItemNo_MASTER_SWORD_e, false);
|
||||
dComIfGs_setSelectEquipSword(dItemNo_MASTER_SWORD_e);
|
||||
|
||||
dComIfGp_setItemLifeCount(dComIfGs_getMaxLife(), 0);
|
||||
dComIfGs_onEventBit(dSv_event_flag_c::saveBitLabels[getFlagNo()]);
|
||||
#endif
|
||||
dComIfGs_onEventBit(dSv_event_flag_c::saveBitLabels[getFlagNo()]);
|
||||
fopAcM_delete(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ int daKey_c::create() {
|
||||
|
||||
#if TARGET_PC
|
||||
mItemGiveTag = dusk::mods::item_give_tag_freestanding(getSaveBitNo());
|
||||
const auto [item, displayItem] =
|
||||
const auto [item, displayItem, _] =
|
||||
dusk::mods::item_check_resolve(mItemGiveTag, dItemNo_SMALL_KEY_e, this);
|
||||
m_itemNo = item;
|
||||
if (m_itemNo == dItemNo_NONE_e) {
|
||||
|
||||
@@ -106,7 +106,7 @@ const char* daShopItem_c::getShopArcname() {
|
||||
if (m_itemNo != dItemNo_NONE_e && mItemGiveOriginalNo == dItemNo_NONE_e) {
|
||||
mItemGiveOriginalNo = m_itemNo;
|
||||
mItemGiveTag = dusk::mods::item_give_tag_shop(mItemGiveOriginalNo);
|
||||
const auto [_, displayItem] =
|
||||
const auto [_, displayItem, was_resolved] =
|
||||
dusk::mods::item_check_resolve(mItemGiveTag, mItemGiveOriginalNo, this);
|
||||
setDisplayItemNo(displayItem);
|
||||
mItemOverridden = displayItem != mItemGiveOriginalNo;
|
||||
|
||||
@@ -20,6 +20,7 @@ struct ItemCheckResult {
|
||||
uint32_t tag = 0;
|
||||
uint8_t itemNo = 0;
|
||||
uint8_t displayItemNo = 0;
|
||||
bool was_resolved = false;
|
||||
};
|
||||
|
||||
ItemCheckResolution item_check_resolve(const char* name, uint8_t itemNo, fopAc_ac_c* giver);
|
||||
|
||||
@@ -235,6 +235,7 @@ ItemCheckResolution item_check_resolve(const char* name, uint8_t itemNo, fopAc_a
|
||||
.vanilla_item = itemNo,
|
||||
.current_item = itemNo,
|
||||
.current_display_item = itemNo,
|
||||
.was_resolved = false,
|
||||
};
|
||||
for (const auto& resolve : resolves) {
|
||||
if (!resolve.mod->active) {
|
||||
@@ -243,6 +244,7 @@ ItemCheckResolution item_check_resolve(const char* name, uint8_t itemNo, fopAc_a
|
||||
if (resolve.fixedValue) {
|
||||
info.current_item = resolve.itemNo;
|
||||
info.current_display_item = resolve.itemNo;
|
||||
info.was_resolved = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -257,6 +259,7 @@ ItemCheckResolution item_check_resolve(const char* name, uint8_t itemNo, fopAc_a
|
||||
}
|
||||
info.current_item = resolution.item;
|
||||
info.current_display_item = resolution.display_item;
|
||||
info.was_resolved = true;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
fail_mod(*resolve.mod, MOD_ERROR,
|
||||
@@ -269,6 +272,7 @@ ItemCheckResolution item_check_resolve(const char* name, uint8_t itemNo, fopAc_a
|
||||
return {
|
||||
.item = info.current_item,
|
||||
.display_item = info.current_display_item,
|
||||
.was_resolved = info.was_resolved,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -265,6 +265,7 @@ ItemCheckResult item_check_commit(uint32_t giveTag, uint8_t itemNo, fopAc_ac_c*
|
||||
.tag = giveTag,
|
||||
.itemNo = committed->resolution.item,
|
||||
.displayItemNo = committed->resolution.display_item,
|
||||
.was_resolved = committed->resolution.was_resolved,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -274,6 +275,7 @@ ItemCheckResult item_check_commit(uint32_t giveTag, uint8_t itemNo, fopAc_ac_c*
|
||||
.tag = giveTag,
|
||||
.itemNo = committed.resolution.item,
|
||||
.displayItemNo = committed.resolution.display_item,
|
||||
.was_resolved = committed.resolution.was_resolved,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user