1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-07-16 04:44:44 +00:00

G_Switch, Syateki_Itm, and Syateki_Man (Shooting gallery and related actors) (#523)

* Darkmeiro decompilation

Bg_Gnd_Darkmeiro decompiled, matched, and documented.

* give this a shot

* fix conflict

* one more try

* could be useful

* whoops

* ZAP2 stuff

* ZAP why

* ZAP again

* rupees and, for some reason, pots

* and now an even larger man

* now for the gallery

* more progress

* naming continues

* even more docs

* another match

* match, fix, a new enum

* Update src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c

* fixes except globalctx

* well one more

* and now globalCtx
This commit is contained in:
petrie911 2020-12-11 16:38:23 -06:00 committed by GitHub
parent bc8e3745c7
commit f05a584dea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 1464 additions and 4117 deletions

View file

@ -44,8 +44,8 @@ void KaleidoSetup_Update(GlobalContext* globalCtx) {
if (pauseCtx->state == 0 && pauseCtx->flag == 0 && globalCtx->unk_10A20 == 0 && globalCtx->sceneLoadFlag == 0 &&
globalCtx->transitionMode == 0 && gSaveContext.cutsceneIndex < 0xFFF0 &&
gSaveContext.nextCutsceneIndex < 0xFFF0 && !Gameplay_InCsMode(globalCtx) && globalCtx->unk_11E5C < 2 &&
gSaveContext.unk_13F0 != 8 && gSaveContext.unk_13F0 != 9 &&
gSaveContext.nextCutsceneIndex < 0xFFF0 && !Gameplay_InCsMode(globalCtx) &&
globalCtx->shootingGalleryStatus <= 1 && gSaveContext.unk_13F0 != 8 && gSaveContext.unk_13F0 != 9 &&
(globalCtx->sceneNum != SCENE_BOWLING || !Flags_GetSwitch(globalCtx, 0x38))) {
if (CHECK_BTN_ALL(input->cur.button, BTN_L) && CHECK_BTN_ALL(input->press.button, BTN_CUP)) {

View file

@ -608,7 +608,7 @@ void func_80083108(GlobalContext* globalCtx) {
((globalCtx->sceneNum == SCENE_SPOT20) && (gSaveContext.cutsceneIndex == 0xFFF0))) {
gSaveContext.unk_13E7 = 0;
if ((player->stateFlags1 & 0x00800000) || (globalCtx->unk_11E5C >= 2) ||
if ((player->stateFlags1 & 0x00800000) || (globalCtx->shootingGalleryStatus > 1) ||
((globalCtx->sceneNum == SCENE_BOWLING) && Flags_GetSwitch(globalCtx, 0x38))) {
if (gSaveContext.equips.buttonItems[0] != ITEM_NONE) {
gSaveContext.unk_13E7 = 1;
@ -629,7 +629,7 @@ void func_80083108(GlobalContext* globalCtx) {
Interface_LoadItemIcon1(globalCtx, 0);
} else {
gSaveContext.equips.buttonItems[0] = ITEM_BOW;
if (globalCtx->unk_11E5C >= 2) {
if (globalCtx->shootingGalleryStatus > 1) {
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
gSaveContext.equips.buttonItems[0] = ITEM_SLINGSHOT;
}
@ -653,7 +653,7 @@ void func_80083108(GlobalContext* globalCtx) {
Interface_ChangeAlpha(1);
} else if (gSaveContext.minigameState == 1) {
Interface_ChangeAlpha(8);
} else if (globalCtx->unk_11E5C >= 2) {
} else if (globalCtx->shootingGalleryStatus > 1) {
Interface_ChangeAlpha(8);
} else if ((globalCtx->sceneNum == SCENE_BOWLING) && Flags_GetSwitch(globalCtx, 0x38)) {
Interface_ChangeAlpha(8);
@ -2867,10 +2867,10 @@ void Interface_DrawAmmoCount(GlobalContext* globalCtx, s16 button, s16 alpha) {
if ((button == 0) && (gSaveContext.minigameState == 1)) {
ammo = globalCtx->interfaceCtx.hbaAmmo;
} else if ((button == 0) && (globalCtx->unk_11E5C >= 2)) {
ammo = globalCtx->unk_11E5C - 1;
} else if ((button == 0) && (globalCtx->shootingGalleryStatus > 1)) {
ammo = globalCtx->shootingGalleryStatus - 1;
} else if ((button == 0) && (globalCtx->sceneNum == SCENE_BOWLING) && Flags_GetSwitch(globalCtx, 0x38)) {
ammo = globalCtx->bombchuBowlingAmmo;
ammo = globalCtx->bombchuBowlingStatus;
if (ammo < 0) {
ammo = 0;
}
@ -3208,7 +3208,7 @@ void Interface_Draw(GlobalContext* globalCtx) {
if (gSaveContext.equips.buttonItems[0] != ITEM_NONE) {
Interface_DrawItemIconTexture(globalCtx, (void*)(u32)interfaceCtx->icon_itemSegment, 0);
if ((player->stateFlags1 & 0x00800000) || (globalCtx->unk_11E5C >= 2) ||
if ((player->stateFlags1 & 0x00800000) || (globalCtx->shootingGalleryStatus > 1) ||
((globalCtx->sceneNum == SCENE_BOWLING) && Flags_GetSwitch(globalCtx, 0x38))) {
gDPPipeSync(OVERLAY_DISP++);
gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE,
@ -3495,7 +3495,7 @@ void Interface_Draw(GlobalContext* globalCtx) {
if ((globalCtx->pauseCtx.state == 0) && (globalCtx->pauseCtx.flag == 0) && (globalCtx->unk_10A20 == 0) &&
(msgCtx->msgMode == 0) && !(player->stateFlags2 & 0x01000000) && (globalCtx->sceneLoadFlag == 0) &&
(globalCtx->transitionMode == 0) && !Gameplay_InCsMode(globalCtx) && (gSaveContext.minigameState != 1) &&
(globalCtx->unk_11E5C < 2) &&
(globalCtx->shootingGalleryStatus <= 1) &&
!((globalCtx->sceneNum == SCENE_BOWLING) && Flags_GetSwitch(globalCtx, 0x38))) {
sp274 = 0;
switch (gSaveContext.timer1State) {

View file

@ -416,7 +416,7 @@ s32 func_8008EF30(GlobalContext* globalCtx) {
}
s32 func_8008EF44(GlobalContext* globalCtx, s32 ammo) {
globalCtx->unk_11E5C = ammo + 1;
globalCtx->shootingGalleryStatus = ammo + 1;
return 1;
}

View file

@ -67,7 +67,7 @@ void EnBomBowlMan_Init(Actor* thisx, GlobalContext* globalCtx) {
osSyncPrintf(VT_FGCOL(GREEN) "☆ もー 肩こっちゃうよねぇ〜 \t\t\n" VT_RST);
// ☆ Isn't there some sort of job that will pay better and be more relaxing? ☆ %d
osSyncPrintf(VT_FGCOL(GREEN) "☆ もっとラクしてもうかるバイトないかしら? ☆ %d\n" VT_RST,
globalCtx2->bombchuBowlingAmmo);
globalCtx2->bombchuBowlingStatus);
this->posCopy = this->actor.posRot.pos;
this->actor.shape.unk_08 = -60.0f;
Actor_SetScale(&this->actor, 0.013f);
@ -218,7 +218,7 @@ void EnBomBowMan_RunGame(EnBomBowlMan* this, GlobalContext* globalCtx) {
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
if (BREG(3)) {
osSyncPrintf(VT_FGCOL(RED) "☆ game_play->bomchu_game_flag ☆ %d\n" VT_RST, globalCtx->bombchuBowlingAmmo);
osSyncPrintf(VT_FGCOL(RED) "☆ game_play->bomchu_game_flag ☆ %d\n" VT_RST, globalCtx->bombchuBowlingStatus);
// HOW'S THE FIRST WALL DOING?
osSyncPrintf(VT_FGCOL(RED) "☆ 壁1の状態どう? ☆ %d\n" VT_RST, this->wallStatus[0]);
// HOW'S THE SECOND WALL DOING?
@ -237,7 +237,7 @@ void EnBomBowMan_RunGame(EnBomBowlMan* this, GlobalContext* globalCtx) {
// Center HIT!
osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 中央HIT!!!! ☆☆☆☆☆ \n" VT_RST);
}
if ((globalCtx->bombchuBowlingAmmo == -1) &&
if ((globalCtx->bombchuBowlingStatus == -1) &&
(globalCtx->actorCtx.actorList[ACTORTYPE_EXPLOSIVES].length == 0) && (this->bowlPit->status == 0) &&
(this->wallStatus[0] != 1) && (this->wallStatus[1] != 1)) {
this->gameResult = 2; // Lost
@ -254,7 +254,7 @@ void EnBomBowMan_RunGame(EnBomBowlMan* this, GlobalContext* globalCtx) {
this->exItem->unk_160 = 1;
this->exItem = NULL;
}
globalCtx->bombchuBowlingAmmo = 0;
globalCtx->bombchuBowlingStatus = 0;
this->playingAgain = true;
func_8010B680(globalCtx, this->actor.textId, NULL);
if (this->gameResult == 2) {
@ -289,7 +289,7 @@ void EnBomBowlMan_HandlePlayChoice(EnBomBowlMan* this, GlobalContext* globalCtx)
Rupees_ChangeBy(-30);
this->minigamePlayStatus = 1;
this->wallStatus[0] = this->wallStatus[1] = 0;
globalCtx->bombchuBowlingAmmo = 10;
globalCtx->bombchuBowlingStatus = 10;
Flags_SetSwitch(globalCtx, 0x38);
if (!this->startedPlaying && !this->playingAgain) {
this->actor.textId = 0x19;
@ -443,7 +443,7 @@ void EnBomBowlMan_BeginPlayGame(EnBomBowlMan* this, GlobalContext* globalCtx) {
BREG(2) = 0;
}
// "Wow"
osSyncPrintf(VT_FGCOL(YELLOW) "☆ わー ☆ %d\n" VT_RST, globalCtx->bombchuBowlingAmmo);
osSyncPrintf(VT_FGCOL(YELLOW) "☆ わー ☆ %d\n" VT_RST, globalCtx->bombchuBowlingStatus);
func_8002DF54(globalCtx, NULL, 7);
this->actionFunc = EnBomBowMan_SetupRunGame;
}

View file

@ -14,17 +14,18 @@ void EnExRuppy_Draw(Actor* thisx, GlobalContext* globalCtx);
void EnExRuppy_DropIntoWater(EnExRuppy* this, GlobalContext* globalCtx);
void EnExRuppy_WaitToBlowUp(EnExRuppy* this, GlobalContext* globalCtx);
void EnExRuppy_WaitAsCollectible(EnExRuppy* this, GlobalContext* globalCtx);
void func_80A0B0F4(EnExRuppy* this, GlobalContext* globalCtx);
void EnExRuppy_GalleryTarget(EnExRuppy* this, GlobalContext* globalCtx);
void EnExRuppy_EnterWater(EnExRuppy* this, GlobalContext* globalCtx);
void EnExRuppy_Sink(EnExRuppy* this, GlobalContext* globalCtx);
void func_80A0AD88(EnExRuppy* this, GlobalContext* globalCtx);
void func_80A0AEE0(EnExRuppy* this, GlobalContext* globalCtx);
void EnExRuppy_WaitInGame(EnExRuppy* this, GlobalContext* globalCtx);
void EnExRuppy_Kill(EnExRuppy* this, GlobalContext* globalCtx);
static s16 sEnExRuppyCollectibleTypes[] = {
ITEM00_RUPEE_GREEN, ITEM00_RUPEE_BLUE, ITEM00_RUPEE_RED, ITEM00_RUPEE_ORANGE, ITEM00_RUPEE_PURPLE,
};
static s16 D_80A0B32B[] = {
// Unused, as the function sets these directly
static s16 sRupeeValues[] = {
1, 5, 20, 500, 50,
};
@ -47,12 +48,12 @@ void EnExRuppy_Init(Actor* thisx, GlobalContext* globalCtx) {
f32 temp2;
s16 temp3;
this->unk_152 = this->actor.params;
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ インデックス ☆☆☆☆☆ %x\n" VT_RST, this->unk_152); // "Index"
this->type = this->actor.params;
// "Index"
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ インデックス ☆☆☆☆☆ %x\n" VT_RST, this->type);
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawFunc_Circle, 25.0f);
switch (this->unk_152) {
switch (this->type) {
case 0:
this->unk_160 = 0.01f;
Actor_SetScale(&this->actor, this->unk_160);
@ -62,7 +63,7 @@ void EnExRuppy_Init(Actor* thisx, GlobalContext* globalCtx) {
// If you haven't won the diving game before, you will always get 5 rupees
if (!(gSaveContext.eventChkInf[3] & 0x100)) {
this->rupeeValue = 5;
this->unk_150 = 1;
this->colorIdx = 1;
} else {
temp1 = 200.99f;
if (this->actor.parent != NULL) {
@ -76,21 +77,21 @@ void EnExRuppy_Init(Actor* thisx, GlobalContext* globalCtx) {
temp3 = Math_Rand_ZeroFloat(temp1);
if ((temp3 >= 0) && (temp3 < 40)) {
this->rupeeValue = 1;
this->unk_150 = 0;
this->colorIdx = 0;
} else if ((temp3 >= 40) && (temp3 < 170)) {
this->rupeeValue = 5;
this->unk_150 = 1;
this->colorIdx = 1;
} else if ((temp3 >= 170) && (temp3 < 190)) {
this->rupeeValue = 20;
this->unk_150 = 2;
this->colorIdx = 2;
} else if ((temp3 >= 190) && (temp3 < 200)) {
this->rupeeValue = 50;
this->unk_150 = 4;
this->colorIdx = 4;
} else {
this->unk_160 = 0.02f;
Actor_SetScale(&this->actor, this->unk_160);
this->rupeeValue = 500;
this->unk_150 = 3;
this->colorIdx = 3;
if (this->actor.parent != NULL) {
divingGame = (EnDivingGame*)this->actor.parent;
if (divingGame->actor.update != NULL) {
@ -111,15 +112,16 @@ void EnExRuppy_Init(Actor* thisx, GlobalContext* globalCtx) {
case 1:
case 2: // Giant pink ruppe that explodes when you touch it
if (this->unk_152 == 1) {
if (this->type == 1) {
Actor_SetScale(&this->actor, 0.1f);
this->unk_150 = 4;
this->colorIdx = 4;
} else {
Actor_SetScale(thisx, 0.02f);
this->unk_150 = (s16)Math_Rand_ZeroFloat(3.99f) + 1;
this->colorIdx = (s16)Math_Rand_ZeroFloat(3.99f) + 1;
}
this->actor.gravity = -3.0f;
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ わーなーコイン ☆☆☆☆☆ \n" VT_RST); // "Wow Coin"
// "Wow Coin"
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ わーなーコイン ☆☆☆☆☆ \n" VT_RST);
this->actor.shape.unk_10 = 6.0f;
this->actor.shape.unk_08 = 700.0f;
this->actor.flags &= ~1;
@ -128,32 +130,33 @@ void EnExRuppy_Init(Actor* thisx, GlobalContext* globalCtx) {
case 3: // Spawned by the guard in Hyrule courtyard
Actor_SetScale(&this->actor, 0.02f);
this->unk_150 = 0;
this->colorIdx = 0;
switch ((s16)Math_Rand_ZeroFloat(30.99f)) {
case 0:
this->unk_150 = 2;
this->colorIdx = 2;
break;
case 10:
case 20:
case 30:
this->unk_150 = 1;
this->colorIdx = 1;
break;
}
this->actor.gravity = -3.0f;
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ ノーマルルピー ☆☆☆☆☆ \n" VT_RST); // "Normal rupee"
// "Normal rupee"
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ ノーマルルピー ☆☆☆☆☆ \n" VT_RST);
this->actor.shape.unk_10 = 6.0f;
this->actor.shape.unk_08 = 700.0f;
this->actor.flags &= ~1;
this->actionFunc = EnExRuppy_WaitAsCollectible;
break;
case 4:
case 4: // Progress markers in the shooting gallery
this->actor.gravity = -3.0f;
this->actor.flags &= ~1;
Actor_SetScale(&this->actor, 0.01f);
this->actor.shape.unk_10 = 6.0f;
this->actor.shape.unk_08 = -700.0f;
this->actionFunc = func_80A0B0F4;
this->actionFunc = EnExRuppy_GalleryTarget;
break;
}
}
@ -203,18 +206,18 @@ void EnExRuppy_SpawnSparkles(EnExRuppy* this, GlobalContext* globalCtx, s16 numS
}
void EnExRuppy_DropIntoWater(EnExRuppy* this, GlobalContext* globalCtx) {
this->actor.shape.rot.y = (this->actor.shape.rot.y + 1960);
EnDivingGame* divingGame;
this->actor.shape.rot.y += 0x7A8;
Math_SmoothScaleMaxF(&this->actor.gravity, -2.0f, 0.3f, 1.0f);
EnExRuppy_SpawnSparkles(this, globalCtx, 2, 0);
func_80078884(NA_SE_EV_RAINBOW_SHOWER - SFX_FLAG);
if ((this->actor.parent != NULL) && (this->actor.parent->update != NULL) &&
(((((EnDivingGame*)this->actor.parent)->unk_296 == 0) || (this->actor.bgCheckFlags & 0x20)) ||
(this->timer == 0))) {
this->isFalling = 1;
divingGame = (EnDivingGame*)this->actor.parent;
if ((divingGame != NULL) && (divingGame->actor.update != NULL) &&
((divingGame->unk_296 == 0) || (this->actor.bgCheckFlags & 0x20) || (this->timer == 0))) {
this->invisible = true;
this->actor.speedXZ = 0.0f;
this->actor.velocity.z = 0.0f;
this->actor.velocity.y = 0.0f;
this->actor.velocity.x = 0.0f;
this->actor.velocity.x = this->actor.velocity.y = this->actor.velocity.z = 0.0f;
this->actor.gravity = 0.0f;
func_80078914(&this->actor.projectedPos, NA_SE_EV_BOMB_DROP_WATER);
this->actionFunc = EnExRuppy_EnterWater;
@ -222,12 +225,11 @@ void EnExRuppy_DropIntoWater(EnExRuppy* this, GlobalContext* globalCtx) {
}
void EnExRuppy_EnterWater(EnExRuppy* this, GlobalContext* globalCtx) {
s32 pad;
EnDivingGame* divingGame = (EnDivingGame*)this->actor.parent;
f32 temp_f2;
if (((this->actor.parent != NULL) && (this->actor.parent->update != NULL)) &&
(((EnDivingGame*)this->actor.parent)->unk_2A2 == 2)) {
this->isFalling = 0;
if ((divingGame != NULL) && (divingGame->actor.update != NULL) && (divingGame->unk_2A2 == 2)) {
this->invisible = false;
this->actor.posRot.pos.x = ((Math_Rand_ZeroOne() - 0.5f) * 300.0f) + -260.0f;
this->actor.posRot.pos.y = ((Math_Rand_ZeroOne() - 0.5f) * 200.0f) + 370.0f;
temp_f2 = this->unk_15A * -50.0f;
@ -244,26 +246,27 @@ void EnExRuppy_EnterWater(EnExRuppy* this, GlobalContext* globalCtx) {
}
void EnExRuppy_Sink(EnExRuppy* this, GlobalContext* globalCtx) {
s32 pad;
EnDivingGame* divingGame;
Vec3f pos;
s32 pad;
if ((this->actor.bgCheckFlags & 0x20) && (15.0f < this->actor.waterY)) {
if ((this->actor.bgCheckFlags & 0x20) && (this->actor.waterY > 15.0f)) {
pos = this->actor.posRot.pos;
pos.y += this->actor.waterY;
this->actor.velocity.y = -1.0f;
this->actor.gravity = -0.2f;
EffectSsGSplash_Spawn(globalCtx, &pos, 0, 0, 0, 800);
func_80078914(&this->actor.projectedPos, NA_SE_EV_BOMB_DROP_WATER);
this->actionFunc = func_80A0AD88;
this->actionFunc = EnExRuppy_WaitInGame;
}
if (((this->actor.parent != NULL) && (this->actor.parent->update != NULL) &&
((EnDivingGame*)this->actor.parent)->unk_29C == 0)) {
divingGame = (EnDivingGame*)this->actor.parent;
if ((divingGame != NULL) && (divingGame->actor.update != NULL) && (divingGame->unk_29C == 0)) {
this->timer = 20;
this->actionFunc = func_80A0AEE0;
this->actionFunc = EnExRuppy_Kill;
}
}
void func_80A0AD88(EnExRuppy* this, GlobalContext* globalCtx) {
void EnExRuppy_WaitInGame(EnExRuppy* this, GlobalContext* globalCtx) {
EnDivingGame* divingGame;
Vec3f D_80A0B388 = { 0.0f, 0.1f, 0.0f };
Vec3f D_80A0B394 = { 0.0f, 0.0f, 0.0f };
@ -278,10 +281,9 @@ void func_80A0AD88(EnExRuppy* this, GlobalContext* globalCtx) {
if (divingGame->actor.update != NULL) {
if (divingGame->unk_29C == 0) {
this->timer = 20;
this->actionFunc = func_80A0AEE0;
return;
}
if (this->actor.xyzDistFromLinkSq < SQ(localConst)) {
this->actionFunc = EnExRuppy_Kill;
if (1) {}
} else if (this->actor.xyzDistFromLinkSq < SQ(localConst)) {
Rupees_ChangeBy(this->rupeeValue);
func_80078884(NA_SE_SY_GET_RUPY);
divingGame->unk_2A4++;
@ -293,38 +295,46 @@ void func_80A0AD88(EnExRuppy* this, GlobalContext* globalCtx) {
}
}
void func_80A0AEE0(EnExRuppy* this, GlobalContext* globalCtx) {
this->isFalling += 1;
this->isFalling &= 1;
void EnExRuppy_Kill(EnExRuppy* this, GlobalContext* globalCtx) {
this->invisible += 1;
this->invisible &= 1; // Net effect is this->invisible = !this->invisible;
if (this->timer == 0) {
Actor_Kill(&this->actor);
}
}
typedef struct {
/* 0x000 */ Actor actor;
/* 0x14C */ char unk_14C[0x11A];
/* 0x226 */ s16 unk_226;
} EnExRuppyParentActor; // Unclear what actor was intended to spawn this.
void EnExRuppy_WaitToBlowUp(EnExRuppy* this, GlobalContext* globalCtx) {
f32 distToBlowUp;
EnExRuppyParentActor* parent;
Vec3f accel = { 0.0f, 0.1f, 0.0f };
Vec3f velocity = { 0.0f, 0.0f, 0.0f };
f32 distToBlowUp = 50.0f;
s16 explosionScale;
s16 explosionScaleStep;
distToBlowUp = 50.0f;
if (this->unk_152 == 2) {
if (this->type == 2) {
distToBlowUp = 30.0f;
}
if (this->actor.xyzDistFromLinkSq < SQ(distToBlowUp)) {
if (this->actor.parent != NULL) {
if (this->actor.parent->update != NULL) {
((EnDivingGame*)this->actor.parent)->transitionDrawTable[15].z = 1;
parent = (EnExRuppyParentActor*)this->actor.parent;
if (parent != NULL) {
if (parent->actor.update != NULL) {
parent->unk_226 = 1;
}
} else {
// "That idiot! error"
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ そ、そんなばかな!エラー!!!!! ☆☆☆☆☆ \n" VT_RST);
}
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ バカめ! ☆☆☆☆☆ \n" VT_RST); // "Stupid!"
// "Stupid!"
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ バカめ! ☆☆☆☆☆ \n" VT_RST);
explosionScale = 100;
explosionScaleStep = 30;
if (this->unk_152 == 2) {
if (this->type == 2) {
explosionScale = 20;
explosionScaleStep = 6;
}
@ -338,15 +348,16 @@ void EnExRuppy_WaitToBlowUp(EnExRuppy* this, GlobalContext* globalCtx) {
void EnExRuppy_WaitAsCollectible(EnExRuppy* this, GlobalContext* globalCtx) {
f32 localConst = 30.0f;
if (this->actor.xyzDistFromLinkSq < SQ(localConst)) {
func_80078884(NA_SE_SY_GET_RUPY);
Item_DropCollectible(globalCtx, &this->actor.posRot.pos, (sEnExRuppyCollectibleTypes[this->unk_150] | 0x8000));
Item_DropCollectible(globalCtx, &this->actor.posRot.pos, (sEnExRuppyCollectibleTypes[this->colorIdx] | 0x8000));
Actor_Kill(&this->actor);
}
}
void func_80A0B0F4(EnExRuppy* this, GlobalContext* globalCtx) {
if (this->unk_15C != 0) {
void EnExRuppy_GalleryTarget(EnExRuppy* this, GlobalContext* globalCtx) {
if (this->galleryFlag) {
Math_SmoothScaleMaxF(&this->actor.shape.unk_08, 700.0f, 0.5f, 200.0f);
} else {
Math_SmoothScaleMaxF(&this->actor.shape.unk_08, -700.0f, 0.5f, 200.0f);
@ -368,17 +379,17 @@ void EnExRuppy_Update(Actor* thisx, GlobalContext* globalCtx) {
UNK_PTR D_80A0B3B8[] = { 0x04042140, 0x04042160, 0x04042180, 0x040421C0, 0x040421A0 };
void EnExRuppy_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnExRuppy* this = THIS;
s32 pad;
EnExRuppy* this = THIS;
if (this->isFalling == 0) {
if (!this->invisible) {
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_ex_ruppy.c", 774);
func_80093D18(globalCtx->state.gfxCtx);
func_8002EBCC(thisx, globalCtx, 0);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_ex_ruppy.c", 780),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_80A0B3B8[this->unk_150]));
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_80A0B3B8[this->colorIdx]));
gSPDisplayList(POLY_OPA_DISP++, D_04042440);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_ex_ruppy.c", 784);

View file

@ -11,13 +11,13 @@ typedef void (*EnExRuppyActionFunc)(struct EnExRuppy*, GlobalContext*);
typedef struct EnExRuppy {
/* 0x0000 */ Actor actor;
/* 0x014C */ EnExRuppyActionFunc actionFunc;
/* 0x0150 */ s16 unk_150;
/* 0x0152 */ s16 unk_152;
/* 0x0154 */ s16 isFalling;
/* 0x0150 */ s16 colorIdx;
/* 0x0152 */ s16 type;
/* 0x0154 */ s16 invisible;
/* 0x0156 */ s16 timer;
/* 0x0158 */ s16 rupeeValue;
/* 0x015A */ s16 unk_15A;
/* 0x015C */ s16 unk_15C;
/* 0x015C */ s16 galleryFlag;
/* 0x0160 */ f32 unk_160;
} EnExRuppy; // size = 0x0164

View file

@ -1,17 +1,51 @@
#include "z_en_g_switch.h"
#include "vt.h"
#include "overlays/actors/ovl_En_Syateki_Itm/z_en_syateki_itm.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
#define FLAGS 0x00000030
#define THIS ((EnGSwitch*)thisx)
typedef enum {
/* 0 */ MOVE_TARGET,
/* 1 */ MOVE_HOME
} GSwitchMoveState;
void EnGSwitch_Init(Actor* thisx, GlobalContext* globalCtx);
void EnGSwitch_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnGSwitch_Update(Actor* thisx, GlobalContext* globalCtx);
void EnGSwitch_DrawRupee(Actor* thisx, GlobalContext* globalCtx);
void EnGSwitch_DrawPot(Actor* thisx, GlobalContext* globalCtx);
extern UNK_TYPE D_060017C0;
extern UNK_TYPE D_06001960;
void EnGSwitch_SilverRupeeTracker(EnGSwitch* this, GlobalContext* globalCtx);
void EnGSwitch_SilverRupeeIdle(EnGSwitch* this, GlobalContext* globalCtx);
void EnGSwitch_WaitForObject(EnGSwitch* this, GlobalContext* globalCtx);
void EnGSwitch_SilverRupeeCollected(EnGSwitch* this, GlobalContext* globalCtx);
void EnGSwitch_GalleryRupee(EnGSwitch* this, GlobalContext* globalCtx);
void EnGSwitch_ArcheryPot(EnGSwitch* this, GlobalContext* globalCtx);
void EnGSwitch_Kill(EnGSwitch* this, GlobalContext* globalCtx);
void EnGSwitch_SpawnEffects(EnGSwitch* this, Vec3f* pos, s16 scale, s16 colorIdx);
void EnGSwitch_UpdateEffects(EnGSwitch* this, GlobalContext* globalCtx);
void EnGSwitch_DrawEffects(EnGSwitch* this, GlobalContext* globalCtx);
extern Gfx D_060017C0[];
extern Gfx D_06001960[];
static s16 sCollectedCount = 0;
static ColliderCylinderInit sCylinderInit = {
{ COLTYPE_UNK10, 0x00, 0x09, 0x00, 0x20, COLSHAPE_CYLINDER },
{ 0x02, { 0x00000000, 0x00, 0x00 }, { 0xFFCFFFFF, 0x00, 0x00 }, 0x00, 0x01, 0x00 },
{ 13, 40, 0, { 0, 0, 0 } },
};
// Unused, but probably intended to be this
static s16 sRupeeTypes[] = {
ITEM00_RUPEE_GREEN, ITEM00_RUPEE_BLUE, ITEM00_RUPEE_RED, ITEM00_RUPEE_ORANGE, ITEM00_RUPEE_PURPLE,
};
/*
const ActorInit En_G_Switch_InitVars = {
ACTOR_EN_G_SWITCH,
ACTORTYPE_PROP,
@ -23,35 +57,497 @@ const ActorInit En_G_Switch_InitVars = {
(ActorFunc)EnGSwitch_Update,
NULL,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/EnGSwitch_Init.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/EnGSwitch_Destroy.s")
void EnGSwitch_Init(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnGSwitch* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/func_80A22250.s")
this->type = (this->actor.params >> 0xC) & 0xF;
this->switchFlag = this->actor.params & 0x3F;
this->numEffects = ARRAY_COUNT(this->effects);
// index
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ インデックス ☆☆☆☆☆ %x\n" VT_RST, this->type);
// save
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ セーブ\t ☆☆☆☆☆ %x\n" VT_RST, this->switchFlag);
switch (this->type) {
case ENGSWITCH_SILVER_TRACKER:
osSyncPrintf("\n\n");
// parent switch spawn
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 親スイッチ発生 ☆☆☆☆☆ %x\n" VT_RST, this->actor.params);
sCollectedCount = 0;
this->silverCount = this->actor.params >> 6;
this->silverCount &= 0x3F;
// maximum number of checks
osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 最大チェック数 ☆☆☆☆☆ %d\n" VT_RST, this->silverCount);
osSyncPrintf("\n\n");
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
// This is a reference to Hokuto no Ken
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ ☆☆☆☆☆ %d\n" VT_RST, this->switchFlag);
Actor_Kill(&this->actor);
} else {
this->actionFunc = EnGSwitch_SilverRupeeTracker;
}
break;
case ENGSWITCH_SILVER_RUPEE:
osSyncPrintf("\n\n");
// child switch spawn
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 子スイッチ発生 ☆☆☆☆☆ %x\n" VT_RST, this->actor.params);
this->colorIdx = 5;
this->numEffects = 20;
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
this->actor.draw = EnGSwitch_DrawRupee;
this->actor.shape.unk_08 = 700.0f;
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ ☆☆☆☆☆ %d\n" VT_RST, this->switchFlag);
Actor_Kill(&this->actor);
} else {
Actor_SetScale(&this->actor, 0.03f);
this->actionFunc = EnGSwitch_SilverRupeeIdle;
}
break;
case ENGSWITCH_ARCHERY_POT:
osSyncPrintf("\n\n");
// Horseback archery destructible pot
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ やぶさめぶち抜き壷 ☆☆☆☆☆ \n" VT_RST);
this->actor.gravity = -3.0f;
this->colorIdx = Math_Rand_ZeroFloat(2.99f);
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
this->actor.scale.x = 0.25f;
this->actor.scale.y = 0.45f;
this->actor.scale.z = 0.25f;
this->collider.body.bumper.flags = 0x1F820;
this->objId = OBJECT_TSUBO;
this->objIndex = Object_GetIndex(&globalCtx->objectCtx, this->objId);
if (this->objIndex < 0) {
Actor_Kill(&this->actor);
// what?
osSyncPrintf(VT_FGCOL(PURPLE) " なにみの? %d\n" VT_RST "\n", this->objIndex);
// bank is funny
osSyncPrintf(VT_FGCOL(CYAN) " バンクおかしいしぞ!%d\n" VT_RST "\n", this->actor.params);
}
this->collider.dim.radius = 24;
this->collider.dim.height = 74;
this->collider.dim.yShift = 0;
this->actionFunc = EnGSwitch_WaitForObject;
break;
case ENGSWITCH_TARGET_RUPEE:
this->actor.shape.unk_08 = 700.0f;
Actor_SetScale(&this->actor, 0.05f);
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
this->actor.draw = EnGSwitch_DrawRupee;
this->collider.dim.radius = 20;
this->collider.dim.height = 60;
this->collider.dim.yShift = 5;
this->actionFunc = EnGSwitch_GalleryRupee;
break;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/func_80A223F8.s")
void EnGSwitch_Destroy(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnGSwitch* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/func_80A2248C.s")
Collider_DestroyCylinder(globalCtx, &this->collider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/func_80A22598.s")
void EnGSwitch_Break(EnGSwitch* this, GlobalContext* globalCtx) {
Vec3f randPos;
Vec3f hitPos;
Vec3f accel = { 0.0f, 0.0f, 0.0f };
Vec3f velocity = { 0.0f, 0.0f, 0.0f };
s32 i;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/func_80A22680.s")
randPos.x = this->actor.posRot.pos.x + Math_Rand_CenteredFloat(40.0f);
randPos.y = this->actor.posRot.pos.y + 30.0f + Math_Rand_CenteredFloat(35.0f);
randPos.z = this->actor.posRot.pos.z + Math_Rand_CenteredFloat(40.0f);
hitPos.x = this->collider.body.bumper.unk_06.x;
hitPos.y = this->collider.body.bumper.unk_06.y;
hitPos.z = this->collider.body.bumper.unk_06.z;
EffectSsHitMark_SpawnCustomScale(globalCtx, 0, 700, &hitPos);
if (this->type == ENGSWITCH_ARCHERY_POT) {
velocity.y = 15.0f;
EffectSsExtra_Spawn(globalCtx, &hitPos, &velocity, &accel, 5, 2);
}
if (this->type == ENGSWITCH_TARGET_RUPEE) {
for (i = 0; i < this->numEffects; i++) {
EnGSwitch_SpawnEffects(this, &randPos, 100, this->colorIdx);
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/func_80A22764.s")
void EnGSwitch_WaitForObject(EnGSwitch* this, GlobalContext* globalCtx) {
if (Object_IsLoaded(&globalCtx->objectCtx, this->objIndex)) {
gSegments[6] = VIRTUAL_TO_PHYSICAL(globalCtx->objectCtx.status[this->objIndex].segment);
this->actor.objBankIndex = this->objIndex;
this->actor.draw = EnGSwitch_DrawPot;
this->actionFunc = EnGSwitch_ArcheryPot;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/func_80A22B1C.s")
void EnGSwitch_SilverRupeeTracker(EnGSwitch* this, GlobalContext* globalCtx) {
static s8 rupeePitches[] = { 0, 2, 4, 5, 7 };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/func_80A22E00.s")
if (this->pitchIndex < sCollectedCount) {
if (sCollectedCount < 5) {
// sound?
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 音? ☆☆☆☆☆ %d\n" VT_RST, this->pitchIndex);
func_800F4BF4(&D_801333D4, NA_SE_EV_FIVE_COUNT_LUPY, rupeePitches[this->pitchIndex]);
this->pitchIndex = sCollectedCount;
}
}
if (sCollectedCount >= this->silverCount) {
// It is now the end of the century.
// This another reference to Hokuto no Ken.
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 時はまさに世紀末〜 ☆☆☆☆☆ %d\n" VT_RST, this->switchFlag);
// Last!
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ らすとぉ! ☆☆☆☆☆ \n" VT_RST);
if ((globalCtx->sceneNum == SCENE_MEN) && (this->actor.room == 2)) {
Flags_SetTempClear(globalCtx, this->actor.room);
} else {
func_80078884(NA_SE_SY_CORRECT_CHIME);
Flags_SetSwitch(globalCtx, this->switchFlag);
}
func_80078884(NA_SE_SY_GET_RUPY);
Actor_Kill(&this->actor);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/EnGSwitch_Update.s")
void EnGSwitch_SilverRupeeIdle(EnGSwitch* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/func_80A22FDC.s")
this->actor.shape.rot.y += 0x800;
if (this->actor.xyzDistFromLinkSq < 900.0f) {
Rupees_ChangeBy(5);
sCollectedCount++;
func_80078884(NA_SE_SY_GET_RUPY);
this->actor.posRot.pos = player->actor.posRot.pos;
this->actor.posRot.pos.y += 40.0f;
if (LINK_IS_ADULT) {
this->actor.posRot.pos.y += 20.0f;
}
this->actor.gravity = 0.0f;
this->killTimer = 15;
this->actionFunc = EnGSwitch_SilverRupeeCollected;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/func_80A230A8.s")
void EnGSwitch_SilverRupeeCollected(EnGSwitch* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/func_80A23204.s")
this->actor.shape.rot.y += 0x3C0;
if (this->killTimer == 0) {
Actor_Kill(&this->actor);
return;
}
this->actor.posRot.pos = player->actor.posRot.pos;
this->actor.posRot.pos.y =
player->actor.posRot.pos.y + 40.0f + (this->killTimer * 0.3f) * Math_Sins(this->killTimer * 0x3A98);
if (LINK_IS_ADULT) {
this->actor.posRot.pos.y += 20.0f;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/func_80A23314.s")
void EnGSwitch_GalleryRupee(EnGSwitch* this, GlobalContext* globalCtx) {
EnSyatekiItm* gallery;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_G_Switch/func_80A234D4.s")
this->actor.shape.rot.y += 0x3C0;
if (this->delayTimer == 0) {
switch (this->moveMode) {
case GSWITCH_THROW:
Actor_MoveForward(&this->actor);
if ((this->actor.velocity.y < 0.0f) &&
(this->actor.posRot.pos.y < (this->actor.initPosRot.pos.y - 50.0f))) {
gallery = ((EnSyatekiItm*)this->actor.parent);
this->actor.velocity.y = 0.0f;
this->actor.gravity = 0.0f;
if (gallery->actor.update != NULL) {
gallery->targetState[this->index] = ENSYATEKIHIT_MISS;
}
Actor_Kill(&this->actor);
}
break;
case GSWITCH_LEFT:
func_8002D7EC(&this->actor);
if ((this->actor.velocity.x < 0.0f) && (this->actor.posRot.pos.x < this->targetPos.x)) {
gallery = ((EnSyatekiItm*)this->actor.parent);
if (gallery->actor.update != NULL) {
gallery->targetState[this->index] = ENSYATEKIHIT_MISS;
}
Actor_Kill(&this->actor);
}
break;
case GSWITCH_RIGHT:
func_8002D7EC(&this->actor);
if (this->actor.posRot.pos.x > this->targetPos.x) {
gallery = ((EnSyatekiItm*)this->actor.parent);
if (gallery->actor.update != NULL) {
gallery->targetState[this->index] = ENSYATEKIHIT_MISS;
}
Actor_Kill(&this->actor);
}
break;
default:
switch (this->moveState) {
case MOVE_TARGET:
if ((fabsf(this->actor.posRot.pos.x - this->targetPos.x) > 5.0f) ||
(fabsf(this->actor.posRot.pos.y - this->targetPos.y) > 5.0f)) {
Math_SmoothScaleMaxF(&this->actor.posRot.pos.x, this->targetPos.x, 0.3f, 30.0f);
Math_SmoothScaleMaxF(&this->actor.posRot.pos.y, this->targetPos.y, 0.3f, 30.0f);
} else {
this->moveState = MOVE_HOME;
this->waitTimer = 60;
}
break;
case MOVE_HOME:
if (this->waitTimer == 0) {
if ((fabsf(this->actor.posRot.pos.x - this->actor.initPosRot.pos.x) > 5.0f) ||
(fabsf(this->actor.posRot.pos.y - this->actor.initPosRot.pos.y) > 5.0f)) {
Math_SmoothScaleMaxF(&this->actor.posRot.pos.x, this->actor.initPosRot.pos.x, 0.3f,
30.0f);
Math_SmoothScaleMaxF(&this->actor.posRot.pos.y, this->actor.initPosRot.pos.y, 0.3f,
30.0f);
} else {
gallery = ((EnSyatekiItm*)this->actor.parent);
if (gallery->actor.update != NULL) {
gallery->targetState[this->index] = ENSYATEKIHIT_MISS;
}
Actor_Kill(&this->actor);
}
}
break;
}
break;
}
if ((this->collider.base.acFlags & 2) || BREG(8)) {
gallery = ((EnSyatekiItm*)this->actor.parent);
this->collider.base.acFlags &= ~2;
if (gallery->actor.update != NULL) {
gallery->hitCount++;
gallery->targetState[this->index] = ENSYATEKIHIT_HIT;
func_80078884(NA_SE_EV_HIT_SOUND);
func_80078884(NA_SE_SY_GET_RUPY);
// Yeah !
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ いぇぇーす!HIT!! ☆☆☆☆☆ %d\n" VT_RST, gallery->hitCount);
EnGSwitch_Break(this, globalCtx);
this->killTimer = 50;
this->broken = true;
this->actionFunc = EnGSwitch_Kill;
}
}
}
}
void EnGSwitch_ArcheryPot(EnGSwitch* this, GlobalContext* globalCtx) {
s32 i;
s16 angle;
Vec3f* thisPos = &this->actor.posRot.pos;
this->actor.shape.rot.y += 0x3C0;
if (this->collider.base.acFlags & 2) {
this->collider.base.acFlags &= ~2;
for (i = 0, angle = 0; i < 30; i++, angle += 0x4E20) {
Vec3f pos;
Vec3f vel;
f32 sn = Math_Sins(angle);
f32 cs = Math_Coss(angle);
f32 rand;
s32 phi_s0;
s32 scale;
s32 pad;
pos.x = sn * 8.0f;
pos.y = 10.0f + Math_Rand_CenteredFloat(5.0f);
pos.z = cs * 8.0f;
vel.x = pos.x / 2.0f;
vel.y = 10.0f + Math_Rand_ZeroOne() * 15.0f;
vel.z = pos.z / 2.0f;
pos.x += thisPos->x;
pos.y += thisPos->y;
pos.z += thisPos->z;
rand = Math_Rand_ZeroOne();
if (rand < 0.2f) {
phi_s0 = 0x60;
} else if (rand < 0.6f) {
phi_s0 = 0x40;
} else {
phi_s0 = 0x20;
}
scale = 30.0f + Math_Rand_ZeroOne() * 130.0f;
EffectSsKakera_Spawn(globalCtx, &pos, &vel, thisPos, -240, phi_s0, 10, 10, 0, scale, 0, 0x20, 60,
KAKERA_COLOR_NONE, OBJECT_TSUBO, D_06001960);
}
func_80033480(globalCtx, thisPos, 30.0f, 4, 20, 50, 0);
Audio_PlaySoundAtPosition(globalCtx, thisPos, 40, NA_SE_EV_POT_BROKEN);
EnGSwitch_Break(this, globalCtx);
this->killTimer = 50;
this->broken = true;
this->actionFunc = EnGSwitch_Kill;
}
}
void EnGSwitch_Kill(EnGSwitch* this, GlobalContext* globalCtx) {
if (this->killTimer == 0) {
Actor_Kill(&this->actor);
}
}
void EnGSwitch_Update(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnGSwitch* this = THIS;
this->actionFunc(this, globalCtx);
if (this->killTimer != 0) {
this->killTimer--;
}
if (this->waitTimer != 0) {
this->waitTimer--;
}
if (this->delayTimer != 0) {
this->delayTimer--;
}
if ((this->type != ENGSWITCH_SILVER_TRACKER) && (this->type != ENGSWITCH_SILVER_RUPEE) &&
(this->type != ENGSWITCH_TARGET_RUPEE)) {
Actor_MoveForward(&this->actor);
func_8002E4B4(globalCtx, &this->actor, 50.0f, 50.0f, 100.0f, 0x1C);
}
if (this->actor.draw != NULL) {
if (this->type == ENGSWITCH_TARGET_RUPEE) {
EnGSwitch_UpdateEffects(this, globalCtx);
}
if ((this->actionFunc != EnGSwitch_Kill) && (this->actionFunc != EnGSwitch_SilverRupeeIdle)) {
Collider_CylinderUpdate(&this->actor, &this->collider);
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
}
if (BREG(0) && (this->type == ENGSWITCH_SILVER_TRACKER)) {
DebugDisplay_AddObject(this->actor.posRot.pos.x, this->actor.posRot.pos.y, this->actor.posRot.pos.z,
this->actor.posRot.rot.x, this->actor.posRot.rot.y, this->actor.posRot.rot.z, 1.0f, 1.0f,
1.0f, 255, 0, 0, 255, 4, globalCtx->state.gfxCtx);
}
}
void EnGSwitch_DrawPot(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnGSwitch* this = THIS;
if (!this->broken) {
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_g_switch.c", 918);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_g_switch.c", 925),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, D_060017C0);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_g_switch.c", 928);
}
}
static u8* sRupeeTex[] = { 0x04042140, 0x04042160, 0x04042180, 0x040421C0, 0x040421A0, 0x040421E0 };
void EnGSwitch_DrawRupee(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnGSwitch* this = THIS;
if (1) {}
if (!this->broken) {
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_g_switch.c", 951);
func_80093D18(globalCtx->state.gfxCtx);
func_8002EBCC(&this->actor, globalCtx, 0);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_g_switch.c", 957),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sRupeeTex[this->colorIdx]));
gSPDisplayList(POLY_OPA_DISP++, D_04042440);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_g_switch.c", 961);
}
if (this->type == ENGSWITCH_TARGET_RUPEE) {
EnGSwitch_DrawEffects(this, globalCtx);
}
}
void EnGSwitch_SpawnEffects(EnGSwitch* this, Vec3f* pos, s16 scale, s16 colorIdx) {
EnGSwitchEffect* effect = this->effects;
s16 i;
for (i = 0; i < this->numEffects; i++, effect++) {
if (!effect->flag) {
Vec3f baseVel;
f32 pitch;
f32 yaw;
effect->pos = *pos;
effect->scale = scale;
effect->colorIdx = colorIdx;
effect->timer = 30;
effect->rot.x = effect->rot.y = effect->rot.z = 0.0f;
pitch = Math_Rand_CenteredFloat(1000.0f) - 13000.0f;
yaw = Math_Rand_CenteredFloat(65535.0f);
Matrix_RotateY(yaw, MTXMODE_NEW);
Matrix_RotateX(pitch, MTXMODE_APPLY);
baseVel.x = baseVel.y = 0.0f;
baseVel.z = 20.0f;
Matrix_MultVec3f(&baseVel, &effect->velocity);
effect->flag = true;
return;
}
}
}
void EnGSwitch_UpdateEffects(EnGSwitch* this, GlobalContext* globalCtx) {
Vec3f temp;
s16 i;
EnGSwitchEffect* effect = this->effects;
for (i = 0; i < this->numEffects; i++, effect++) {
if (effect->flag) {
effect->rot.x += Math_Rand_ZeroOne() * 10.0f + 15.0f;
effect->rot.y += Math_Rand_ZeroOne() * 10.0f + 15.0f;
effect->rot.z += Math_Rand_ZeroOne() * 10.0f + 15.0f;
temp.x = effect->pos.x + effect->velocity.x;
temp.y = effect->pos.y + effect->velocity.y;
temp.z = effect->pos.z + effect->velocity.z;
Math_SmoothScaleMaxF(&effect->pos.x, temp.x, 0.3f, 30.0f);
Math_SmoothScaleMaxF(&effect->pos.y, temp.y, 0.8f, 250.0f);
Math_SmoothScaleMaxF(&effect->pos.z, temp.z, 0.3f, 30.0f);
Math_SmoothScaleMaxF(&effect->velocity.y, -20.0f, 0.9f, 1.0f);
if (effect->timer != 0) {
effect->timer--;
} else if (effect->scale < 10) {
effect->flag = false;
} else {
effect->scale -= 2;
}
}
}
}
void EnGSwitch_DrawEffects(EnGSwitch* this, GlobalContext* globalCtx) {
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
EnGSwitchEffect* effect = this->effects;
s16 i;
f32 scale;
s32 pad;
OPEN_DISPS(gfxCtx, "../z_en_g_switch.c", 1073);
func_80093D18(globalCtx->state.gfxCtx);
for (i = 0; i < this->numEffects; i++, effect++) {
if (effect->flag) {
scale = effect->scale / 10000.0f;
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
Matrix_RotateX(effect->rot.x, MTXMODE_APPLY);
Matrix_RotateY(effect->rot.y, MTXMODE_APPLY);
Matrix_RotateZ(effect->rot.z, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_g_switch.c", 1088),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sRupeeTex[effect->colorIdx]));
gSPDisplayList(POLY_OPA_DISP++, D_04042440);
}
}
CLOSE_DISPS(gfxCtx, "../z_en_g_switch.c", 1095);
}

View file

@ -6,9 +6,55 @@
struct EnGSwitch;
typedef void (*EnGSwitchActionFunc)(struct EnGSwitch*, GlobalContext*);
typedef enum {
/* 0 */ GSWITCH_NONE,
/* 1 */ GSWITCH_APPEAR,
/* 2 */ GSWITCH_THROW,
/* 3 */ GSWITCH_UNUSED,
/* 4 */ GSWITCH_LEFT,
/* 5 */ GSWITCH_RIGHT
} EnGSwitchMoveMode;
typedef enum {
/* 0 */ ENGSWITCH_SILVER_TRACKER,
/* 1 */ ENGSWITCH_SILVER_RUPEE,
/* 2 */ ENGSWITCH_ARCHERY_POT,
/* 3 */ ENGSWITCH_TARGET_RUPEE
} EnGSwitchType;
typedef struct {
/* 0x00 */ Vec3f pos;
/* 0x0C */ s16 scale;
/* 0x0E */ s16 timer;
/* 0x10 */ s16 colorIdx;
/* 0x12 */ u8 flag;
/* 0x14 */ Vec3f velocity;
/* 0x20 */ Vec3f rot;
} EnGSwitchEffect; // size = 0x2C
typedef struct EnGSwitch {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x11AC];
/* 0x014C */ EnGSwitchActionFunc actionFunc;
/* 0x0150 */ s16 type;
/* 0x0152 */ s16 silverCount;
/* 0x0154 */ s16 switchFlag;
/* 0x0156 */ s16 killTimer;
/* 0x0158 */ s16 colorIdx;
/* 0x015A */ s16 broken;
/* 0x015C */ s16 numEffects;
/* 0x015E */ s16 objId;
/* 0x0160 */ s16 index; // first or second rupee in two-rupee patterns
/* 0x0162 */ s16 delayTimer; // delay between the two blue rupees appearing
/* 0x0164 */ s16 waitTimer; // time rupee waits before retreating
/* 0x0166 */ s16 moveMode; // Type of movement in the shooting gallery
/* 0x0168 */ s16 moveState; // Appear or retreat (for blue rupees and the stationary green one)
/* 0x016A */ s16 pitchIndex;
/* 0x016C */ Vec3f targetPos;
/* 0x0178 */ s8 objIndex;
/* 0x017C */ ColliderCylinder collider;
/* 0x01C8 */ EnGSwitchEffect effects[100];
} EnGSwitch; // size = 0x12F8
extern const ActorInit En_G_Switch_InitVars;

View file

@ -1,14 +1,34 @@
#include "z_en_syateki_itm.h"
#include "vt.h"
#include "overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h"
#include "overlays/actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.h"
#include "overlays/actors/ovl_En_G_Switch/z_en_g_switch.h"
#define FLAGS 0x00000010
#define THIS ((EnSyatekiItm*)thisx)
typedef enum {
SYATEKI_ROUND_GREEN_APPEAR,
SYATEKI_ROUND_BLUE_SEQUENTIAL,
SYATEKI_ROUND_GREEN_THROW,
SYATEKI_ROUND_BLUE_SIMUL,
SYATEKI_ROUND_RED_LEFT,
SYATEKI_ROUND_RED_RIGHT,
SYATEKI_ROUND_MAX
} EnSyatekItemRound;
void EnSyatekiItm_Init(Actor* thisx, GlobalContext* globalCtx);
void EnSyatekiItm_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnSyatekiItm_Update(Actor* thisx, GlobalContext* globalCtx);
/*
void EnSyatekiItm_Idle(EnSyatekiItm* this, GlobalContext* globalCtx);
void EnSyatekiItm_StartRound(EnSyatekiItm* this, GlobalContext* globalCtx);
void EnSyatekiItm_SpawnTargets(EnSyatekiItm* this, GlobalContext* globalCtx);
void EnSyatekiItm_CheckTargets(EnSyatekiItm* this, GlobalContext* globalCtx);
void EnSyatekiItm_CleanupGame(EnSyatekiItm* this, GlobalContext* globalCtx);
void EnSyatekiItm_EndGame(EnSyatekiItm* this, GlobalContext* globalCtx);
const ActorInit En_Syateki_Itm_InitVars = {
ACTOR_EN_SYATEKI_ITM,
ACTORTYPE_PROP,
@ -20,21 +40,314 @@ const ActorInit En_Syateki_Itm_InitVars = {
(ActorFunc)EnSyatekiItm_Update,
NULL,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Itm/EnSyatekiItm_Init.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Itm/EnSyatekiItm_Destroy.s")
static Vec3f sGreenAppearHome = { 0.0f, -10.0f, -270.0f };
static Vec3f sBlueSeqHome1 = { -220.0f, 66.0f, -320.0f };
static Vec3f sBlueSeqHome2 = { 260.0f, 66.0f, -320.0f };
static Vec3f sGreenThrowHome = { 0.0f, -10.0f, -270.0f };
static Vec3f sBlueSimulHome1 = { -220.0f, 66.0f, -320.0f };
static Vec3f sBlueSimulHome2 = { 260.0f, 66.0f, -320.0f };
static Vec3f sRedLeftHome1 = { 260.0f, 100.0f, -320.0f };
static Vec3f sRedLeftHome2 = { 360.0f, 100.0f, -320.0f };
static Vec3f sRedRightHome1 = { -230.0f, 94.0f, -360.0f };
static Vec3f sRedRightHome2 = { -400.0f, 94.0f, -360.0f };
static Vec3f sGreenAppearFinal = { 0.0f, 53.0f, -270.0f };
static Vec3f sBlueSeqFinal1 = { -60.0f, 63.0f, -320.0f };
static Vec3f sBlueSeqFinal2 = { 60.0f, 63.0f, -320.0f };
static Vec3f sGreenThrowFinal = { 0.0f, 0.0f, 0.0f };
static Vec3f sBlueSimulFinal1 = { -60.0f, 63.0f, -320.0f };
static Vec3f sBlueSimulFinal2 = { 60.0f, 63.0f, -320.0f };
static Vec3f sRedLeftFinal1 = { -230.0f, 0.0f, 0.0f };
static Vec3f sRedLeftFinal2 = { -230.0f, 0.0f, 0.0f };
static Vec3f sRedRightFinal1 = { 260.0f, 0.0f, 0.0f };
static Vec3f sRedRightFinal2 = { 260.0f, 0.0f, 0.0f };
static s16 sTargetColors[] = { 0, 1, 0, 1, 2, 2 };
static s16 sRupeeTypes[] = { 0, 1, 1, 0, 1, 1, 4, 4, 4, 4 };
static Vec3f sRupeePos[] = {
{ -40.0f, 0.0f, -90.0f }, { -20.0f, 0.0f, -90.0f }, { 0.0f, 0.0f, -90.0f }, { 20.0f, 0.0f, -90.0f },
{ 40.0f, 0.0f, -90.0f }, { -40.0f, 0.0f, -60.0f }, { -20.0f, 0.0f, -60.0f }, { 0.0f, 0.0f, -60.0f },
{ 20.0f, 0.0f, -60.0f }, { 40.0f, 0.0f, -60.0f },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Itm/func_80B0F838.s")
void EnSyatekiItm_Init(Actor* thisx, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = globalCtx2;
EnSyatekiItm* this = THIS;
s32 i;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Itm/func_80B0F944.s")
this->man = (EnSyatekiMan*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_SYATEKI_MAN,
140.0f, 0.0f, 255.0f, 0, -0x4000, 0, 0);
if (this->man == NULL) {
// Spawn error
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ エラー原 ☆☆☆☆ \n" VT_RST);
Actor_Kill(&this->actor);
return;
}
for (i = 0; i < 10; i++) {
this->markers[i] =
(EnExRuppy*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_EX_RUPPY,
sRupeePos[i].x, sRupeePos[i].y, sRupeePos[i].z, 0, 0, 0, 4);
if (this->markers[i] == NULL) {
// Second spawn error
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ エラー原セカンド ☆☆☆☆ \n" VT_RST);
Actor_Kill(&this->actor);
return;
}
this->markers[i]->colorIdx = sRupeeTypes[i];
}
this->actionFunc = EnSyatekiItm_Idle;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Itm/func_80B0FABC.s")
void EnSyatekiItm_Destroy(Actor* thisx, GlobalContext* globalCtx) {
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Itm/func_80B0FF44.s")
void EnSyatekiItm_Idle(EnSyatekiItm* this, GlobalContext* globalCtx) {
s32 i;
Player* player = PLAYER;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Itm/func_80B0FFE8.s")
if (this->signal == ENSYATEKI_START) {
player->actor.posRot.pos.x = -12.0f;
player->actor.posRot.pos.y = 20.0f;
player->actor.posRot.pos.z = 182.0f;
player->currentYaw = player->actor.posRot.rot.y = player->actor.shape.rot.y = 0x7F03;
player->actor.posRot.rot.x = player->actor.shape.rot.x = player->actor.posRot.rot.z =
player->actor.shape.rot.z = 0;
func_8008EF44(globalCtx, 15);
this->roundNum = this->hitCount = 0;
for (i = 0; i < 6; i++) {
this->roundFlags[i] = false;
}
for (i = 0; i < 10; i++) {
this->markers[i]->galleryFlag = false;
}
this->actionFunc = EnSyatekiItm_StartRound;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Itm/func_80B10070.s")
void EnSyatekiItm_StartRound(EnSyatekiItm* this, GlobalContext* globalCtx) {
s32 i;
s32 j;
Player* player = PLAYER;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Itm/EnSyatekiItm_Update.s")
if (this->unkTimer == 0) {
if (LINK_IS_ADULT) {
for (i = 0, j = 0; i < SYATEKI_ROUND_MAX; i++) {
if (this->roundFlags[i]) {
j++;
}
}
if (j >= SYATEKI_ROUND_MAX) {
player->actor.freezeTimer = 10;
this->signal = ENSYATEKI_END;
this->actionFunc = EnSyatekiItm_CleanupGame;
return;
}
i = Math_Rand_ZeroFloat(5.99f);
while (this->roundFlags[i]) {
i = Math_Rand_ZeroFloat(5.99f);
if (1) {}
}
this->roundNum = i + 1;
this->roundFlags[i] = true;
} else {
this->roundNum++;
if (this->roundNum > SYATEKI_ROUND_MAX) {
player->actor.freezeTimer = 10;
this->signal = ENSYATEKI_END;
this->actionFunc = EnSyatekiItm_CleanupGame;
return;
}
}
this->timer = (this->roundNum == 1) ? 50 : 30;
func_80078884(NA_SE_SY_FOUND);
this->actionFunc = EnSyatekiItm_SpawnTargets;
}
}
void EnSyatekiItm_SpawnTargets(EnSyatekiItm* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
s32 i;
s32 roundIdx;
if (globalCtx->shootingGalleryStatus == -1) {
player->actor.freezeTimer = 10;
this->signal = ENSYATEKI_END;
this->actionFunc = EnSyatekiItm_CleanupGame;
return;
}
if (this->timer == 0) {
for (i = 0; i < 2; i++) {
Math_Vec3f_Copy(&this->targetHome[i], &zeroVec);
Math_Vec3f_Copy(&this->targetFinal[i], &zeroVec);
this->targets[i] = NULL;
}
this->numTargets = 2;
this->curMarkers[0] = this->curMarkers[1] = NULL;
roundIdx = this->roundNum - 1;
switch (roundIdx) {
case SYATEKI_ROUND_GREEN_APPEAR:
Math_Vec3f_Copy(&this->targetHome[0], &sGreenAppearHome);
Math_Vec3f_Copy(&this->targetFinal[0], &sGreenAppearFinal);
this->curMarkers[0] = this->markers[0];
this->numTargets = 1;
break;
case SYATEKI_ROUND_BLUE_SEQUENTIAL:
Math_Vec3f_Copy(&this->targetHome[0], &sBlueSeqHome1);
Math_Vec3f_Copy(&this->targetHome[1], &sBlueSeqHome2);
Math_Vec3f_Copy(&this->targetFinal[0], &sBlueSeqFinal1);
Math_Vec3f_Copy(&this->targetFinal[1], &sBlueSeqFinal2);
this->curMarkers[0] = this->markers[1];
this->curMarkers[1] = this->markers[2];
break;
case SYATEKI_ROUND_GREEN_THROW:
Math_Vec3f_Copy(&this->targetHome[0], &sGreenThrowHome);
Math_Vec3f_Copy(&this->targetFinal[0], &sGreenThrowFinal);
this->curMarkers[0] = this->markers[3];
this->numTargets = 1;
break;
case SYATEKI_ROUND_BLUE_SIMUL:
Math_Vec3f_Copy(&this->targetHome[0], &sBlueSimulHome1);
Math_Vec3f_Copy(&this->targetHome[1], &sBlueSimulHome2);
Math_Vec3f_Copy(&this->targetFinal[0], &sBlueSimulFinal1);
Math_Vec3f_Copy(&this->targetFinal[1], &sBlueSimulFinal2);
this->curMarkers[0] = this->markers[4];
this->curMarkers[1] = this->markers[5];
break;
case SYATEKI_ROUND_RED_LEFT:
Math_Vec3f_Copy(&this->targetHome[0], &sRedLeftHome1);
Math_Vec3f_Copy(&this->targetHome[1], &sRedLeftHome2);
Math_Vec3f_Copy(&this->targetFinal[0], &sRedLeftFinal1);
Math_Vec3f_Copy(&this->targetFinal[1], &sRedLeftFinal2);
this->curMarkers[0] = this->markers[6];
this->curMarkers[1] = this->markers[7];
break;
case SYATEKI_ROUND_RED_RIGHT:
Math_Vec3f_Copy(&this->targetHome[0], &sRedRightHome1);
Math_Vec3f_Copy(&this->targetHome[1], &sRedRightHome2);
Math_Vec3f_Copy(&this->targetFinal[0], &sRedRightFinal1);
Math_Vec3f_Copy(&this->targetFinal[1], &sRedRightFinal2);
this->curMarkers[0] = this->markers[8];
this->curMarkers[1] = this->markers[9];
break;
}
for (i = 0; i < this->numTargets; i++) {
this->targets[i] = (EnGSwitch*)Actor_SpawnAsChild(
&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_G_SWITCH, this->targetHome[i].x,
this->targetHome[i].y, this->targetHome[i].z, 0, 0, 0, (ENGSWITCH_TARGET_RUPEE << 0xC) | 0x3F);
if (this->targets[i] == NULL) {
// Rupee spawn error
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ ルピーでエラー原 ☆☆☆☆ \n" VT_RST);
Actor_Kill(&this->actor);
return;
}
this->targets[i]->index = i;
this->targets[i]->colorIdx = sTargetColors[roundIdx];
Math_Vec3f_Copy(&this->targets[i]->targetPos, &this->targetFinal[i]);
switch (roundIdx) {
case SYATEKI_ROUND_BLUE_SEQUENTIAL:
if (i == 1) {
this->targets[i]->delayTimer = 60;
}
break;
case SYATEKI_ROUND_GREEN_THROW:
this->targets[i]->actor.velocity.y = 15.0f;
this->targets[i]->actor.gravity = -1.0f;
this->targets[i]->moveMode = GSWITCH_THROW;
break;
case SYATEKI_ROUND_RED_LEFT:
this->targets[i]->actor.velocity.x = -5.0f;
this->targets[i]->moveMode = GSWITCH_LEFT;
break;
case SYATEKI_ROUND_RED_RIGHT:
this->targets[i]->actor.velocity.x = 7.0f;
this->targets[i]->moveMode = GSWITCH_RIGHT;
break;
}
}
this->targetState[0] = this->targetState[1] = ENSYATEKIHIT_NONE;
this->actionFunc = EnSyatekiItm_CheckTargets;
}
}
void EnSyatekiItm_CheckTargets(EnSyatekiItm* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
s32 i;
s16 j;
if (globalCtx->shootingGalleryStatus == -1) {
player->actor.freezeTimer = 10;
this->signal = ENSYATEKI_END;
this->actionFunc = EnSyatekiItm_CleanupGame;
} else {
for (i = 0, j = 0; i < 2; i++) {
if (this->targetState[i] != ENSYATEKIHIT_NONE) {
if (this->targetState[i] == ENSYATEKIHIT_HIT) {
this->curMarkers[i]->galleryFlag = true;
}
j++;
}
}
if (j == this->numTargets) {
this->actionFunc = EnSyatekiItm_StartRound;
}
}
}
void EnSyatekiItm_CleanupGame(EnSyatekiItm* this, GlobalContext* globalCtx) {
s32 i;
for (i = 0; i < 2; i++) {
if ((this->targetState[i] == ENSYATEKIHIT_NONE) && (this->targets[i] != NULL)) {
Actor_Kill(&this->targets[i]->actor);
}
}
this->actionFunc = EnSyatekiItm_EndGame;
}
void EnSyatekiItm_EndGame(EnSyatekiItm* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
player->actor.freezeTimer = 10;
if (this->signal == ENSYATEKI_RESULTS) {
this->signal = ENSYATEKI_NONE;
this->actionFunc = EnSyatekiItm_Idle;
}
if (this->signal == ENSYATEKI_START) {
// 1 frame attack and defense!
osSyncPrintf(VT_FGCOL(RED) "☆☆☆☆☆ 1フレームの攻防! ☆☆☆☆ \n" VT_RST);
osSyncPrintf(VT_FGCOL(RED) "☆☆☆☆☆ 1フレームの攻防! ☆☆☆☆ \n" VT_RST);
osSyncPrintf(VT_FGCOL(RED) "☆☆☆☆☆ 1フレームの攻防! ☆☆☆☆ \n" VT_RST);
osSyncPrintf(VT_FGCOL(RED) "☆☆☆☆☆ 1フレームの攻防! ☆☆☆☆ \n" VT_RST);
osSyncPrintf(VT_FGCOL(RED) "☆☆☆☆☆ 1フレームの攻防! ☆☆☆☆ \n" VT_RST);
osSyncPrintf(VT_FGCOL(RED) "☆☆☆☆☆ 1フレームの攻防! ☆☆☆☆ \n" VT_RST);
osSyncPrintf(VT_FGCOL(RED) "☆☆☆☆☆ 1フレームの攻防! ☆☆☆☆ \n" VT_RST);
osSyncPrintf(VT_FGCOL(RED) "☆☆☆☆☆ 1フレームの攻防! ☆☆☆☆ \n" VT_RST);
osSyncPrintf(VT_FGCOL(RED) "☆☆☆☆☆ 1フレームの攻防! ☆☆☆☆ \n" VT_RST);
osSyncPrintf(VT_FGCOL(RED) "☆☆☆☆☆ 1フレームの攻防! ☆☆☆☆ \n" VT_RST);
this->signal = ENSYATEKI_NONE;
this->actionFunc = EnSyatekiItm_Idle;
}
}
void EnSyatekiItm_Update(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnSyatekiItm* this = THIS;
this->actionFunc(this, globalCtx);
if (this->timer != 0) {
this->timer--;
}
if (this->unkTimer != 0) {
this->unkTimer--;
}
if (BREG(0)) {
DebugDisplay_AddObject(this->actor.posRot.pos.x, this->actor.posRot.pos.y, this->actor.posRot.pos.z,
this->actor.posRot.rot.x, this->actor.posRot.rot.y, this->actor.posRot.rot.z, 1.0f, 1.0f,
1.0f, 255, 0, 0, 255, 4, globalCtx->state.gfxCtx);
}
}

View file

@ -6,9 +6,38 @@
struct EnSyatekiItm;
typedef void (*EnSyatekiItmActionFunc)(struct EnSyatekiItm*, GlobalContext*);
typedef enum {
/* 0 */ ENSYATEKI_NONE,
/* 1 */ ENSYATEKI_START,
/* 2 */ ENSYATEKI_END,
/* 3 */ ENSYATEKI_RESULTS
} EnSyatekiSignal;
typedef enum {
/* 0 */ ENSYATEKIHIT_NONE,
/* 1 */ ENSYATEKIHIT_MISS,
/* 2 */ ENSYATEKIHIT_HIT
} EnSyatekiHitState;
typedef struct EnSyatekiItm {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x8C];
/* 0x014C */ EnSyatekiItmActionFunc actionFunc;
/* 0x0150 */ s16 timer; // timer for next round
/* 0x0152 */ s16 unkTimer; // unk timer
/* 0x0154 */ s16 signal; // signal between this and shopkeeper
/* 0x0156 */ s16 hitCount; // total rupees hit
/* 0x0158 */ s16 roundNum; // current round
/* 0x015A */ s16 roundFlags[6]; // flags for each round happening
/* 0x0166 */ s16 targetState[2]; // current state of target rupees
/* 0x016A */ s16 numTargets; // number of target rupees for this round
/* 0x016C */ Vec3f targetHome[2]; // initial position of target rupees
/* 0x0184 */ Vec3f targetFinal[2]; // target position of target rupees
/* 0x019C */ struct EnExRuppy* markers[10]; // marker rupees for hits
/* 0x01C4 */ struct EnGSwitch* targets[2]; // currently spawned target rupees
/* 0x01CC */ struct EnSyatekiMan* man; // shopkeeper
/* 0x01D0 */ struct EnExRuppy* curMarkers[2]; // marker rupees for the current round
} EnSyatekiItm; // size = 0x01D8
extern const ActorInit En_Syateki_Itm_InitVars;

View file

@ -1,19 +1,52 @@
#include "z_en_syateki_man.h"
#include "vt.h"
#include "overlays/actors/ovl_En_Syateki_Itm/z_en_syateki_itm.h"
#define FLAGS 0x08000019
#define THIS ((EnSyatekiMan*)thisx)
typedef enum {
/* 0 */ SYATEKI_RESULT_NONE,
/* 1 */ SYATEKI_RESULT_WINNER,
/* 2 */ SYATEKI_RESULT_ALMOST,
/* 3 */ SYATEKI_RESULT_FAILURE,
/* 4 */ SYATEKI_RESULT_REFUSE
} EnSyatekiManGameResult;
typedef enum {
/* 0 */ SYATEKI_TEXT_CHOICE,
/* 1 */ SYATEKI_TEXT_START_GAME,
/* 2 */ SYATEKI_TEXT_NO_RUPEES,
/* 3 */ SYATEKI_TEXT_REFUSE
} EnSyatekiManTextIdx;
void EnSyatekiMan_Init(Actor* thisx, GlobalContext* globalCtx);
void EnSyatekiMan_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnSyatekiMan_Update(Actor* thisx, GlobalContext* globalCtx);
void EnSyatekiMan_Draw(Actor* thisx, GlobalContext* globalCtx);
extern UNK_TYPE D_06000338;
extern UNK_TYPE D_06007E28;
extern UNK_TYPE D_06009B38;
void EnSyatekiMan_Start(EnSyatekiMan* this, GlobalContext* globalCtx);
void EnSyatekiMan_SetupIdle(EnSyatekiMan* this, GlobalContext* globalCtx);
void EnSyatekiMan_Idle(EnSyatekiMan* this, GlobalContext* globalCtx);
void EnSyatekiMan_Talk(EnSyatekiMan* this, GlobalContext* globalCtx);
void EnSyatekiMan_StopTalk(EnSyatekiMan* this, GlobalContext* globalCtx);
void EnSyatekiMan_StartGame(EnSyatekiMan* this, GlobalContext* globalCtx);
void EnSyatekiMan_WaitForGame(EnSyatekiMan* this, GlobalContext* globalCtx);
void EnSyatekiMan_EndGame(EnSyatekiMan* this, GlobalContext* globalCtx);
void EnSyatekiMan_GivePrize(EnSyatekiMan* this, GlobalContext* globalCtx);
void EnSyaketiMan_FinishPrize(EnSyatekiMan* this, GlobalContext* globalCtx);
void EnSyatekiMan_RestartGame(EnSyatekiMan* this, GlobalContext* globalCtx);
void EnSyatekiMan_BlinkWait(EnSyatekiMan* this);
void EnSyatekiMan_Blink(EnSyatekiMan* this);
void EnSyatekiMan_SetBgm(void);
extern AnimationHeader D_06000338;
extern Gfx D_06007E28[];
extern FlexSkeletonHeader D_06009B38;
/*
const ActorInit En_Syateki_Man_InitVars = {
ACTOR_EN_SYATEKI_MAN,
ACTORTYPE_NPC,
@ -25,41 +58,372 @@ const ActorInit En_Syateki_Man_InitVars = {
(ActorFunc)EnSyatekiMan_Update,
(ActorFunc)EnSyatekiMan_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/EnSyatekiMan_Init.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/EnSyatekiMan_Destroy.s")
static u16 sBgmList[] = {
0x00, 0x01, 0x02, 0x18, 0x19, 0x02, 0x19, 0x1A, 0x1A, 0x81A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x922,
0x23, 0x924, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x92B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x32, 0x33, 0x34, 0x35,
0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5A, 0x5B, 0x5C, 0x5D, 0x6D, 0x5E, 0x5E, 0x5F, 0x60, 0x61, 0x6D, 0x62, 0x63, 0x64, 0x65, 0x66,
};
static s16 sTextIds[] = { 0x2B, 0x2E, 0xC8, 0x2D };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B10948.s")
static s16 sTextBoxCount[] = { 4, 5, 5, 5 };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B109DC.s")
void EnSyatekiMan_Init(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnSyatekiMan* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B10A2C.s")
osSyncPrintf("\n\n");
// Old man appeared!! Muhohohohohohohon
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 親父登場!!むほほほほほほほーん ☆☆☆☆☆ \n" VT_RST);
this->actor.unk_1F = 1;
Actor_SetScale(&this->actor, 0.01f);
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06009B38, &D_06000338, this->limbDrawTbl,
this->transitionDrawTbl, 9);
if (LINK_IS_CHILD) {
this->headRot.z = 20;
}
this->blinkTimer = 20;
this->eyeState = 0;
this->blinkFunc = EnSyatekiMan_BlinkWait;
this->actor.colChkInfo.unk_10 = 100;
this->actionFunc = EnSyatekiMan_Start;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B10A84.s")
void EnSyatekiMan_Destroy(Actor* thisx, GlobalContext* globalCtx) {
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B10C2C.s")
void EnSyatekiMan_Start(EnSyatekiMan* this, GlobalContext* globalCtx) {
f32 lastFrame = SkelAnime_GetFrameCount(&D_06000338);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B10CD4.s")
SkelAnime_ChangeAnim(&this->skelAnime, &D_06000338, 1.0f, 0.0f, (s16)lastFrame, 0, -10.0f);
this->actionFunc = EnSyatekiMan_SetupIdle;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B10D94.s")
void EnSyatekiMan_SetupIdle(EnSyatekiMan* this, GlobalContext* globalCtx) {
if (this->gameResult == SYATEKI_RESULT_REFUSE) {
this->textIdx = SYATEKI_TEXT_REFUSE;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B10EB0.s")
this->actor.textId = sTextIds[this->textIdx];
this->numTextBox = sTextBoxCount[this->textIdx];
this->actionFunc = EnSyatekiMan_Idle;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B11164.s")
void EnSyatekiMan_Idle(EnSyatekiMan* this, GlobalContext* globalCtx) {
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
if (func_8002F194(&this->actor, globalCtx)) {
this->actionFunc = EnSyatekiMan_Talk;
} else {
func_8002F2CC(&this->actor, globalCtx, 100.0f);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B111D4.s")
void EnSyatekiMan_Talk(EnSyatekiMan* this, GlobalContext* globalCtx) {
s16 nextState = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B112A0.s")
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
if (this->cameraHold) {
globalCtx->shootingGalleryStatus = -2;
}
if ((this->numTextBox == func_8010BDBC(&globalCtx->msgCtx)) && func_80106BC8(globalCtx)) {
if (this->textIdx == SYATEKI_TEXT_CHOICE) {
switch (globalCtx->msgCtx.choiceIndex) {
case 0:
if (gSaveContext.rupees >= 20) {
Rupees_ChangeBy(-20);
this->textIdx = SYATEKI_TEXT_START_GAME;
nextState = 1;
} else {
this->textIdx = SYATEKI_TEXT_NO_RUPEES;
nextState = 2;
}
this->actor.textId = sTextIds[this->textIdx];
this->numTextBox = sTextBoxCount[this->textIdx];
break;
case 1:
this->actor.textId = sTextIds[SYATEKI_TEXT_REFUSE];
this->numTextBox = sTextBoxCount[SYATEKI_TEXT_REFUSE];
nextState = 2;
break;
}
func_8010B720(globalCtx, this->actor.textId);
} else {
func_80106CCC(globalCtx);
}
switch (nextState) {
case 0:
this->actionFunc = EnSyatekiMan_SetupIdle;
break;
case 1:
this->actionFunc = EnSyatekiMan_StartGame;
break;
case 2:
this->actionFunc = EnSyatekiMan_StopTalk;
break;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B11310.s")
void EnSyatekiMan_StopTalk(EnSyatekiMan* this, GlobalContext* globalCtx) {
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
if (this->cameraHold) {
globalCtx->shootingGalleryStatus = -2;
}
if ((this->numTextBox == func_8010BDBC(&globalCtx->msgCtx)) && func_80106BC8(globalCtx)) {
if (this->cameraHold) {
func_800803F0(globalCtx, this->onePointCam);
this->onePointCam = -1;
this->cameraHold = false;
}
func_80106CCC(globalCtx);
this->actionFunc = EnSyatekiMan_SetupIdle;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B11344.s")
void EnSyatekiMan_StartGame(EnSyatekiMan* this, GlobalContext* globalCtx) {
EnSyatekiItm* gallery;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/EnSyatekiMan_Update.s")
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
if (this->cameraHold) {
globalCtx->shootingGalleryStatus = -2;
}
if ((this->numTextBox == func_8010BDBC(&globalCtx->msgCtx)) && func_80106BC8(globalCtx)) {
if (this->cameraHold) {
func_800803F0(globalCtx, this->onePointCam);
this->onePointCam = -1;
this->cameraHold = false;
}
func_80106CCC(globalCtx);
gallery = ((EnSyatekiItm*)this->actor.parent);
if (gallery->actor.update != NULL) {
gallery->signal = ENSYATEKI_START;
this->actionFunc = EnSyatekiMan_WaitForGame;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B1148C.s")
void EnSyatekiMan_WaitForGame(EnSyatekiMan* this, GlobalContext* globalCtx) {
EnSyatekiItm* gallery;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/EnSyatekiMan_Draw.s")
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
if (1) {}
gallery = ((EnSyatekiItm*)this->actor.parent);
if ((gallery->actor.update != NULL) && (gallery->signal == ENSYATEKI_END)) {
this->onePointCam = func_800800F8(globalCtx, 0x1F42, -0x63, &this->actor, 0);
switch (gallery->hitCount) {
case 10:
this->gameResult = SYATEKI_RESULT_WINNER;
this->actor.textId = 0x71AF;
break;
case 8:
case 9:
this->gameResult = SYATEKI_RESULT_ALMOST;
this->actor.textId = 0x71AE;
break;
default:
this->gameResult = SYATEKI_RESULT_FAILURE;
this->actor.textId = 0x71AD;
if (globalCtx->shootingGalleryStatus == 15 + 1) {
this->gameResult = SYATEKI_RESULT_REFUSE;
this->actor.textId = 0x2D;
}
break;
}
globalCtx->shootingGalleryStatus = -2;
func_8010B680(globalCtx, this->actor.textId, NULL);
this->actionFunc = EnSyatekiMan_EndGame;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Syateki_Man/func_80B1156C.s")
void EnSyatekiMan_EndGame(EnSyatekiMan* this, GlobalContext* globalCtx) {
EnSyatekiItm* gallery;
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
if ((this->numTextBox == func_8010BDBC(&globalCtx->msgCtx)) && func_80106BC8(globalCtx)) {
if (this->gameResult != SYATEKI_RESULT_FAILURE) {
func_800803F0(globalCtx, this->onePointCam);
this->onePointCam = -1;
}
func_80106CCC(globalCtx);
gallery = ((EnSyatekiItm*)this->actor.parent);
if (gallery->actor.update != NULL) {
gallery->signal = ENSYATEKI_RESULTS;
this->textIdx = 0;
switch (this->gameResult) {
case SYATEKI_RESULT_WINNER:
this->tempGallery = this->actor.parent;
this->actor.parent = NULL;
if (LINK_IS_CHILD) {
if (!(gSaveContext.itemGetInf[0] & 0x2000)) {
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ Equip_Pachinko ☆☆☆☆☆ %d\n" VT_RST, CUR_UPG_VALUE(UPG_BULLET_BAG));
if (CUR_UPG_VALUE(UPG_BULLET_BAG) == 1) {
this->getItemId = GI_BULLET_BAG_40;
} else {
this->getItemId = GI_BULLET_BAG_50;
}
} else {
this->getItemId = GI_RUPEE_PURPLE;
}
} else {
if (!(gSaveContext.itemGetInf[0] & 0x4000)) {
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ Equip_Bow ☆☆☆☆☆ %d\n" VT_RST, CUR_UPG_VALUE(UPG_QUIVER));
switch (CUR_UPG_VALUE(UPG_QUIVER)) {
case 0:
this->getItemId = GI_RUPEE_PURPLE;
break;
case 1:
this->getItemId = GI_QUIVER_40;
break;
case 2:
this->getItemId = GI_QUIVER_50;
break;
}
} else {
this->getItemId = GI_RUPEE_PURPLE;
}
}
func_8002F434(&this->actor, globalCtx, this->getItemId, 2000.0f, 1000.0f);
this->actionFunc = EnSyatekiMan_GivePrize;
break;
case SYATEKI_RESULT_ALMOST:
this->timer = 20;
func_8008EF44(globalCtx, 15);
this->actionFunc = EnSyatekiMan_RestartGame;
break;
default:
if (this->gameResult == SYATEKI_RESULT_REFUSE) {
this->actionFunc = EnSyatekiMan_SetupIdle;
} else {
this->cameraHold = true;
this->actor.textId = sTextIds[this->textIdx];
this->numTextBox = sTextBoxCount[this->textIdx];
func_8010B680(globalCtx, this->actor.textId, NULL);
this->actionFunc = EnSyatekiMan_Talk;
}
break;
}
}
}
}
void EnSyatekiMan_GivePrize(EnSyatekiMan* this, GlobalContext* globalCtx) {
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
if (Actor_HasParent(&this->actor, globalCtx)) {
this->actionFunc = EnSyaketiMan_FinishPrize;
} else {
func_8002F434(&this->actor, globalCtx, this->getItemId, 2000.0f, 1000.0f);
}
}
void EnSyaketiMan_FinishPrize(EnSyatekiMan* this, GlobalContext* globalCtx) {
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
if ((func_8010BDBC(&globalCtx->msgCtx) == 6) && func_80106BC8(globalCtx)) {
// Successful completion
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n" VT_RST);
if (LINK_IS_CHILD) {
gSaveContext.itemGetInf[0] |= 0x2000;
} else if ((this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50)) {
gSaveContext.itemGetInf[0] |= 0x4000;
}
this->gameResult = SYATEKI_RESULT_NONE;
this->actor.parent = this->tempGallery;
this->actor.flags |= 1;
this->actionFunc = EnSyatekiMan_SetupIdle;
}
}
void EnSyatekiMan_RestartGame(EnSyatekiMan* this, GlobalContext* globalCtx) {
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
if (this->timer == 0) {
EnSyatekiItm* gallery = ((EnSyatekiItm*)this->actor.parent);
if (gallery->actor.update != NULL) {
gallery->signal = ENSYATEKI_START;
this->gameResult = SYATEKI_RESULT_NONE;
this->actionFunc = EnSyatekiMan_WaitForGame;
// Let's try again! Baby!
osSyncPrintf(VT_FGCOL(BLUE) "再挑戦だぜ!ベイビー!" VT_RST "\n", this);
}
}
}
void EnSyatekiMan_BlinkWait(EnSyatekiMan* this) {
s16 decrBlinkTimer = this->blinkTimer - 1;
if (decrBlinkTimer != 0) {
this->blinkTimer = decrBlinkTimer;
} else {
this->blinkFunc = EnSyatekiMan_Blink;
}
}
void EnSyatekiMan_Blink(EnSyatekiMan* this) {
s16 decrBlinkTimer = this->blinkTimer - 1;
if (decrBlinkTimer != 0) {
this->blinkTimer = decrBlinkTimer;
} else {
s16 nextEyeState = this->eyeState + 1;
if (nextEyeState >= 3) {
this->eyeState = 0;
this->blinkTimer = 20 + (s32)(Math_Rand_ZeroOne() * 60.0f);
this->blinkFunc = EnSyatekiMan_BlinkWait;
} else {
this->eyeState = nextEyeState;
this->blinkTimer = 1;
}
}
}
void EnSyatekiMan_Update(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnSyatekiMan* this = THIS;
if (this->timer != 0) {
this->timer--;
}
this->actionFunc(this, globalCtx);
EnSyatekiMan_SetBgm();
this->blinkFunc(this);
this->actor.posRot2.pos.y = 70.0f;
Actor_SetHeight(&this->actor, 70.0f);
func_80038290(globalCtx, &this->actor, &this->headRot, &this->bodyRot, this->actor.posRot2.pos);
}
s32 func_80B1148C(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) {
EnSyatekiMan* this = THIS;
s32 turnDirection;
if (limbIndex == 1) {
rot->x += this->bodyRot.y;
}
if (limbIndex == 8) {
*dList = D_06007E28;
turnDirection = 1;
if (this->gameResult == SYATEKI_RESULT_REFUSE) {
turnDirection = -1;
}
rot->x += this->headRot.y * turnDirection;
rot->z += this->headRot.z;
}
return 0;
}
void EnSyatekiMan_Draw(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnSyatekiMan* this = THIS;
func_80093D18(globalCtx->state.gfxCtx);
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount,
func_80B1148C, NULL, this);
}
void EnSyatekiMan_SetBgm(void) {
if (BREG(80)) {
BREG(80) = false;
Audio_SetBGM(sBgmList[BREG(81)]);
}
}

View file

@ -6,9 +6,28 @@
struct EnSyatekiMan;
typedef void (*EnSyatekiManActionFunc) (struct EnSyatekiMan*, GlobalContext*);
typedef void (*EnSyatekiManOtherFunc) (struct EnSyatekiMan*);
typedef struct EnSyatekiMan {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0xE0];
/* 0x014C */ SkelAnime skelAnime;
/* 0x0190 */ Vec3s limbDrawTbl[9];
/* 0x01C6 */ Vec3s transitionDrawTbl[9];
/* 0x01FC */ EnSyatekiManActionFunc actionFunc;
/* 0x0200 */ Vec3s headRot;
/* 0x0206 */ Vec3s bodyRot;
/* 0x020C */ s16 eyeState; // Unused
/* 0x020E */ s16 blinkTimer; // Unused
/* 0x0210 */ s16 textIdx;
/* 0x0212 */ s16 numTextBox;
/* 0x0214 */ s16 gameResult;
/* 0x0216 */ s16 timer;
/* 0x0218 */ s32 getItemId;
/* 0x021C */ u8 cameraHold;
/* 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 onePointCam;
} EnSyatekiMan; // size = 0x022C
extern const ActorInit En_Syateki_Man_InitVars;

View file

@ -457,7 +457,7 @@ void func_80B12460(EnSyatekiNiw* this, GlobalContext* globalCtx) {
if (this->unk_25E == 1) {
globalCtx->sceneLoadFlag = 0x14;
globalCtx->nextEntranceIndex = gSaveContext.entranceIndex;
globalCtx->unk_11E5C = 0;
globalCtx->shootingGalleryStatus = 0;
player->actor.freezeTimer = 20;
this->unk_25E = 0x14;
this->actionFunc = func_80B128D8;
@ -643,7 +643,7 @@ void EnSyatekiNiw_Update(Actor* thisx, GlobalContext* globalCtx) {
i = 0;
switch (this->unk_29E) {
case 0:
if (globalCtx->unk_11E5C != 0) {
if (globalCtx->shootingGalleryStatus != 0) {
i = 1;
}
break;

View file

@ -1777,10 +1777,10 @@ void func_808337D4(GlobalContext* globalCtx, Player* this) {
this->actor.posRot.pos.x, this->actor.posRot.pos.y, this->actor.posRot.pos.z, 0,
this->actor.shape.rot.y, 0, 0);
if (spawnedActor != NULL) {
if ((explosiveType != 0) && (globalCtx->bombchuBowlingAmmo != 0)) {
globalCtx->bombchuBowlingAmmo--;
if (globalCtx->bombchuBowlingAmmo == 0) {
globalCtx->bombchuBowlingAmmo = -1;
if ((explosiveType != 0) && (globalCtx->bombchuBowlingStatus != 0)) {
globalCtx->bombchuBowlingStatus--;
if (globalCtx->bombchuBowlingStatus == 0) {
globalCtx->bombchuBowlingStatus = -1;
}
} else {
Inventory_ChangeAmmo(explosiveInfo->itemId, -1);
@ -1911,8 +1911,8 @@ s32 func_80833C98(s32 item1, s32 actionParam) {
s32 func_80833CDC(GlobalContext* globalCtx, s32 index) {
if (index >= 4) {
return ITEM_NONE;
} else if (globalCtx->bombchuBowlingAmmo != 0) {
return (globalCtx->bombchuBowlingAmmo > 0) ? ITEM_BOMBCHU : ITEM_NONE;
} else if (globalCtx->bombchuBowlingStatus != 0) {
return (globalCtx->bombchuBowlingStatus > 0) ? ITEM_BOMBCHU : ITEM_NONE;
} else if (index == 0) {
return B_BTN_ITEM;
} else if (index == 1) {
@ -2029,7 +2029,7 @@ void func_80834298(Player* this, GlobalContext* globalCtx) {
if ((this->actor.type == ACTORTYPE_PLAYER) && !(this->stateFlags1 & 0x100) &&
((this->heldItemActionParam == this->itemActionParam) || (this->stateFlags1 & 0x400000)) &&
(gSaveContext.health != 0) && (globalCtx->csCtx.state == 0) && (this->csMode == 0) &&
(globalCtx->unk_11E5C == 0) && (globalCtx->activeCamera == 0) && (globalCtx->sceneLoadFlag != 0x14) &&
(globalCtx->shootingGalleryStatus == 0) && (globalCtx->activeCamera == 0) && (globalCtx->sceneLoadFlag != 0x14) &&
(gSaveContext.timer1State != 10)) {
func_80833DF8(this, globalCtx);
}
@ -2054,8 +2054,8 @@ s32 func_80834380(GlobalContext* globalCtx, Player* this, s32* itemPtr, s32* typ
if (gSaveContext.minigameState == 1) {
return globalCtx->interfaceCtx.hbaAmmo;
} else if (globalCtx->unk_11E5C != 0) {
return globalCtx->unk_11E5C;
} else if (globalCtx->shootingGalleryStatus != 0) {
return globalCtx->shootingGalleryStatus;
} else {
return AMMO(*itemPtr);
}
@ -2145,7 +2145,7 @@ s32 func_80834758(GlobalContext* globalCtx, Player* this) {
LinkAnimationHeader* anim;
f32 frame;
if (!(this->stateFlags1 & 0x20C00000) && (globalCtx->unk_11E5C == 0) &&
if (!(this->stateFlags1 & 0x20C00000) && (globalCtx->shootingGalleryStatus == 0) &&
(this->heldItemActionParam == this->itemActionParam) && (this->currentShield != PLAYER_SHIELD_NONE) &&
!Player_IsChildWithHylianShield(this) && func_80833BCC(this) &&
CHECK_BTN_ALL(sControlInput->cur.button, BTN_R)) {
@ -2215,7 +2215,7 @@ s32 func_808349DC(Player* this, GlobalContext* globalCtx) {
s32 func_80834A2C(Player* this, GlobalContext* globalCtx) {
if (func_800A3BC0(globalCtx, &this->skelAnime2) ||
((Player_ItemToActionParam(this->heldItemId) == this->heldItemActionParam) &&
(D_80853614 = (D_80853614 || ((this->modelAnimType != 3) && (globalCtx->unk_11E5C == 0)))))) {
(D_80853614 = (D_80853614 || ((this->modelAnimType != 3) && (globalCtx->shootingGalleryStatus == 0)))))) {
func_80833638(this, D_80853EDC[this->heldItemActionParam]);
this->unk_834 = 0;
this->unk_6AC = 0;
@ -2307,12 +2307,12 @@ s32 func_80834D2C(Player* this, GlobalContext* globalCtx) {
}
s32 func_80834E44(GlobalContext* globalCtx) {
return (globalCtx->unk_11E5C > 0) && CHECK_BTN_ALL(sControlInput->press.button, BTN_B);
return (globalCtx->shootingGalleryStatus > 0) && CHECK_BTN_ALL(sControlInput->press.button, BTN_B);
}
s32 func_80834E7C(GlobalContext* globalCtx) {
return (globalCtx->unk_11E5C != 0) &&
((globalCtx->unk_11E5C < 0) ||
return (globalCtx->shootingGalleryStatus != 0) &&
((globalCtx->shootingGalleryStatus < 0) ||
CHECK_BTN_ANY(sControlInput->cur.button, BTN_A | BTN_B | BTN_CUP | BTN_CLEFT | BTN_CRIGHT | BTN_CDOWN));
}
@ -2376,14 +2376,14 @@ s32 func_808350A4(GlobalContext* globalCtx, Player* this) {
if (gSaveContext.minigameState == 1) {
globalCtx->interfaceCtx.hbaAmmo--;
} else if (globalCtx->unk_11E5C != 0) {
globalCtx->unk_11E5C--;
} else if (globalCtx->shootingGalleryStatus != 0) {
globalCtx->shootingGalleryStatus--;
} else {
Inventory_ChangeAmmo(item, -1);
}
if (globalCtx->unk_11E5C == 1) {
globalCtx->unk_11E5C = -10;
if (globalCtx->shootingGalleryStatus == 1) {
globalCtx->shootingGalleryStatus = -10;
}
func_8083264C(this, 150, 10, 150, 0);
@ -2763,7 +2763,7 @@ void func_80835F44(GlobalContext* globalCtx, Player* this, s32 item) {
((this->actor.bgCheckFlags & 1) &&
((actionParam == PLAYER_AP_HOOKSHOT) || (actionParam == PLAYER_AP_LONGSHOT)))) {
if ((globalCtx->bombchuBowlingAmmo == 0) &&
if ((globalCtx->bombchuBowlingStatus == 0) &&
(((actionParam == PLAYER_AP_STICK) && (AMMO(ITEM_STICK) == 0)) ||
((actionParam == PLAYER_AP_BEAN) && (AMMO(ITEM_BEAN) == 0)) ||
(temp = Player_ActionToExplosive(this, actionParam),
@ -5162,7 +5162,7 @@ s32 func_8083C2B0(Player* this, GlobalContext* globalCtx) {
LinkAnimationHeader* anim;
f32 frame;
if ((globalCtx->unk_11E5C == 0) && (this->currentShield != PLAYER_SHIELD_NONE) &&
if ((globalCtx->shootingGalleryStatus == 0) && (this->currentShield != PLAYER_SHIELD_NONE) &&
CHECK_BTN_ALL(sControlInput->cur.button, BTN_R) &&
(Player_IsChildWithHylianShield(this) || (!func_80833B2C(this) && (this->unk_664 == NULL)))) {
@ -9068,7 +9068,7 @@ void Player_Init(Actor* thisx, GlobalContext* globalCtx) {
s16 params;
u16 entranceSound;
globalCtx->unk_11E5C = globalCtx->bombchuBowlingAmmo = 0;
globalCtx->shootingGalleryStatus = globalCtx->bombchuBowlingStatus = 0;
globalCtx->playerInit = Player_InitCommon;
globalCtx->playerUpdate = Player_UpdateCommon;
@ -10554,7 +10554,8 @@ s16 func_8084ABD8(GlobalContext* globalCtx, Player* this, s32 arg2, s16 arg3) {
}
this->unk_6AE |= 2;
return func_80836AB8(this, (globalCtx->unk_11E5C != 0) || func_8002DD78(this) || func_808334B4(this)) - arg3;
return func_80836AB8(this, (globalCtx->shootingGalleryStatus != 0) || func_8002DD78(this) || func_808334B4(this)) -
arg3;
}
#else
s16 func_8084ABD8(GlobalContext* globalCtx, Player* this, s32 arg2, s16 arg3);
@ -10684,7 +10685,7 @@ void func_8084B1D8(Player* this, GlobalContext* globalCtx) {
}
s32 func_8084B3CC(GlobalContext* globalCtx, Player* this) {
if (globalCtx->unk_11E5C != 0) {
if (globalCtx->shootingGalleryStatus != 0) {
func_80832564(globalCtx, this);
func_80835C58(globalCtx, this, func_8084FA54, 0);
@ -12482,9 +12483,9 @@ void func_8084FA54(Player* this, GlobalContext* globalCtx) {
this->unk_6BE = func_8084ABD8(globalCtx, this, 1, 0) - this->actor.shape.rot.y;
this->unk_6AE |= 0x80;
if (globalCtx->unk_11E5C < 0) {
globalCtx->unk_11E5C++;
if (globalCtx->unk_11E5C == 0) {
if (globalCtx->shootingGalleryStatus < 0) {
globalCtx->shootingGalleryStatus++;
if (globalCtx->shootingGalleryStatus == 0) {
func_8083C148(this, globalCtx);
}
}