Merge pull request #83 from Tawling/vbo-shooting-gallery

GameInteractor hooks for adult and child shooting gallery
This commit is contained in:
Garrett Cox 2024-02-12 01:14:35 -06:00 committed by GitHub
commit e433cce799
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 39 additions and 32 deletions

View File

@ -203,6 +203,9 @@ typedef enum {
GI_VB_OVERRIDE_LINK_THE_GORON_DIALOGUE,
// Opt: *EnGo2
GI_VB_EN_GO2_RESET_AFTER_GET_ITEM,
// Opt: *EnSyatekiMan
// Vanilla condition: (this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50)
GI_VB_BE_ELIGIBLE_FOR_ADULT_SHOOTING_GAME_REWARD,
/*** Play Cutscenes ***/
@ -269,6 +272,9 @@ typedef enum {
// Opt: *EnFr
GI_VB_GIVE_ITEM_FROM_FROGS,
// Opt: *EnSyatekiMan
GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY,
GI_VB_GIVE_ITEM_FAIRY_OCARINA,
GI_VB_GIVE_ITEM_WEIRD_EGG,
GI_VB_GIVE_ITEM_LIGHT_ARROW,

View File

@ -23,6 +23,7 @@ extern "C" {
#include "src/overlays/actors/ovl_En_Go2/z_en_go2.h"
#include "src/overlays/actors/ovl_En_Ms/z_en_ms.h"
#include "src/overlays/actors/ovl_En_Fr/z_en_fr.h"
#include "src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h"
#include "adult_trade_shuffle.h"
extern SaveContext gSaveContext;
extern PlayState* gPlayState;
@ -775,6 +776,26 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void
*should &= !EnDs_RandoCanGetGrannyItem();
break;
}
case GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY: {
EnSyatekiMan* enSyatekiMan = static_cast<EnSyatekiMan*>(optionalArg);
enSyatekiMan->getItemId = GI_RUPEE_PURPLE;
if (LINK_IS_ADULT) {
// Give purple rupee if we've already obtained the reward OR we don't have a bow
*should = Flags_GetItemGetInf(ITEMGETINF_0E) || CUR_UPG_VALUE(UPG_QUIVER) == 0;
} else {
// Give purple rupee if we've already obtained the reward
*should = Flags_GetItemGetInf(ITEMGETINF_0D);
}
break;
}
case GI_VB_BE_ELIGIBLE_FOR_ADULT_SHOOTING_GAME_REWARD: {
*should = CUR_UPG_VALUE(UPG_QUIVER) > 0;
if (!*should) {
// In Rando without a quiver, display a message reminding the player to come back with a bow
Message_StartTextbox(gPlayState, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW, NULL);
}
break;
}
case GI_VB_TRADE_CLAIM_CHECK:
case GI_VB_TRADE_TIMER_ODD_MUSHROOM:
case GI_VB_TRADE_TIMER_EYEDROPS:

View File

@ -672,7 +672,7 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x3E, "Bombchu Bowling Second Prize", "MK Bombchu Bowling Second Prize", RHT_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(18), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true);
locationTable[RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x00, "Bombchu Bowling Bombchus", "MK Bombchu Bowling Bombchus", RHT_MARKET_BOMBCHU_BOWLING_BOMBCHUS, RG_BOMBCHU_DROP, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, 0x3E, "Lost Dog", "MK Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x09), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true);
locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x60, "Shooting Gallery", "MK Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(13), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true);
locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x60, "Shooting Gallery", "MK Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0D), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true);
locationTable[RC_MARKET_10_BIG_POES] = Location::Base(RC_MARKET_10_BIG_POES, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_MARKET_GUARD_HOUSE, 0x00, 0x0F, "10 Big Poes", "MK 10 Big Poes", RHT_MARKET_10_BIG_POES, RG_EMPTY_BOTTLE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_10_BIG_POES), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true);
locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x01, "Chest Game First Room Chest", "MK Chest Game First Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x03, "Chest Game Second Room Chest", "MK Chest Game Second Room Chest", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
@ -692,7 +692,7 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_KAK_50_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_50_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x3E, "50 Gold Skulltula Reward", "Kak 50 Gold Skulltula Reward", RHT_KAK_50_GOLD_SKULLTULA_REWARD, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xDE), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true);
locationTable[RC_KAK_100_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_100_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x3E, "100 Gold Skulltula Reward", "Kak 100 Gold Skulltula Reward", RHT_KAK_100_GOLD_SKULLTULA_REWARD, RG_HUGE_RUPEE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[RC_KAK_MAN_ON_ROOF] = Location::Base(RC_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x3E, "Man on Roof", "Kak Man on Roof", RHT_KAK_MAN_ON_ROOF, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(21), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true);
locationTable[RC_KAK_SHOOTING_GALLERY_REWARD] = Location::Base(RC_KAK_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x30, "Shooting Gallery Reward", "Kak Shooting Gallery Reward", RHT_KAK_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::Chest(0x42, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true);
locationTable[RC_KAK_SHOOTING_GALLERY_REWARD] = Location::Base(RC_KAK_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x30, "Shooting Gallery Reward", "Kak Shooting Gallery Reward", RHT_KAK_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0E), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true);
locationTable[RC_KAK_TRADE_ODD_MUSHROOM] = Location::Base(RC_KAK_TRADE_ODD_MUSHROOM, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, 0x20, "Trade Odd Mushroom", "Kak Trade Odd Mushroom", RHT_KAK_TRADE_ODD_MUSHROOM, RG_ODD_POTION, { Category::cAdultTrade }, SpoilerCollectionCheck::ItemGetInf(48), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true);
locationTable[RC_KAK_GRANNYS_SHOP] = Location::Base(RC_KAK_GRANNYS_SHOP, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, 0x4E, "Granny's Shop", "Kak Granny's Shop", RHT_KAK_GRANNYS_SHOP, RG_BUY_BLUE_POTION, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true);
locationTable[RC_KAK_ANJU_AS_ADULT] = Location::Base(RC_KAK_ANJU_AS_ADULT, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x1D, "Anju as Adult", "Kak Anju as Adult", RHT_KAK_ANJU_AS_ADULT, RG_CLAIM_CHECK, {}, SpoilerCollectionCheck::ItemGetInf(44), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true);

View File

@ -4,6 +4,7 @@
#include "objects/object_ossan/object_ossan.h"
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
#include "soh/Enhancements/custom-message/CustomMessageTypes.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_LOCKON)
@ -180,7 +181,6 @@ void EnSyatekiMan_Init(Actor* thisx, PlayState* play) {
this->blinkFunc = EnSyatekiMan_BlinkWait;
this->actor.colChkInfo.cylRadius = 100;
this->actionFunc = EnSyatekiMan_Start;
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
}
void EnSyatekiMan_Destroy(Actor* thisx, PlayState* play) {
@ -355,11 +355,7 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, PlayState* play) {
this->tempGallery = this->actor.parent;
this->actor.parent = NULL;
if (!LINK_IS_ADULT) {
if(IS_RANDO && !Flags_GetTreasure(play, 0x1E)) {
this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_SHOOTING_GALLERY_REWARD, GI_BULLET_BAG_50);
this->getItemId = this->getItemEntry.getItemId;
Flags_SetTreasure(play, 0x1E);
} else if (!IS_RANDO && !Flags_GetItemGetInf(ITEMGETINF_0D)) {
if (!Flags_GetItemGetInf(ITEMGETINF_0D)) {
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ Equip_Pachinko ☆☆☆☆☆ %d\n" VT_RST,
CUR_UPG_VALUE(UPG_BULLET_BAG));
if (CUR_UPG_VALUE(UPG_BULLET_BAG) == 1) {
@ -368,16 +364,11 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, PlayState* play) {
this->getItemId = GI_BULLET_BAG_50;
}
} else {
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
this->getItemId = GI_RUPEE_PURPLE;
}
} else {
// Only give the adult rando reward when the player has a quiver
if (IS_RANDO && !Flags_GetTreasure(play, 0x1F) && CUR_UPG_VALUE(UPG_QUIVER) > 0) {
this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_SHOOTING_GALLERY_REWARD, GI_QUIVER_50);
this->getItemId = this->getItemEntry.getItemId;
Flags_SetTreasure(play, 0x1F);
} else if (!IS_RANDO && !Flags_GetItemGetInf(ITEMGETINF_0E)) {
if (!Flags_GetItemGetInf(ITEMGETINF_0E)) {
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ Equip_Bow ☆☆☆☆☆ %d\n" VT_RST,
CUR_UPG_VALUE(UPG_QUIVER));
switch (CUR_UPG_VALUE(UPG_QUIVER)) {
@ -392,14 +383,11 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, PlayState* play) {
break;
}
} else {
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
this->getItemId = GI_RUPEE_PURPLE;
}
}
if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) {
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, true, this)) {
func_8002F434(&this->actor, play, this->getItemId, 2000.0f, 1000.0f);
} else {
GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 2000.0f, 1000.0f);
}
this->actionFunc = EnSyatekiMan_GivePrize;
break;
@ -426,33 +414,26 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, PlayState* play) {
}
}
}
}
}
void EnSyatekiMan_GivePrize(EnSyatekiMan* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
if (Actor_HasParent(&this->actor, play)) {
if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, true, this)) {
this->actionFunc = EnSyatekiMan_FinishPrize;
} else {
if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) {
func_8002F434(&this->actor, play, this->getItemId, 2000.0f, 1000.0f);
} else {
GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 2000.0f, 1000.0f);
}
} else {
func_8002F434(&this->actor, play, this->getItemId, 2000.0f, 1000.0f);
}
}
void EnSyatekiMan_FinishPrize(EnSyatekiMan* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) {
if (((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, true, this)) {
// "Successful completion"
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n" VT_RST);
if (!LINK_IS_ADULT) {
Flags_SetItemGetInf(ITEMGETINF_0D);
} else if ((this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50)) {
} else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_ADULT_SHOOTING_GAME_REWARD, (this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50), this)) {
Flags_SetItemGetInf(ITEMGETINF_0E);
} else if (IS_RANDO && LINK_IS_ADULT && CUR_UPG_VALUE(UPG_QUIVER) == 0) {
// In Rando without a quiver, display a message reminding the player to come back with a bow
Message_StartTextbox(play, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW, NULL);
}
this->gameResult = SYATEKI_RESULT_NONE;
this->actor.parent = this->tempGallery;

View File

@ -28,7 +28,6 @@ typedef struct EnSyatekiMan {
/* 0x0220 */ Actor* tempGallery;
/* 0x0224 */ EnSyatekiManOtherFunc blinkFunc; // Seems to be part of a blink system with unk_20C and unk_20E, but it's unused.
/* 0x0228 */ s16 csCam;
/* */ GetItemEntry getItemEntry;
} EnSyatekiMan; // size = 0x022C
#endif