1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-11-14 13:30:47 +00:00
oot/src/code/z_actor.c
2020-03-22 18:55:23 +01:00

6101 lines
178 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <ultra64.h>
#include <global.h>
#include <vt.h>
void ActorShape_Init(ActorShape* shape, f32 arg1, void* shadowDrawFunc, f32 arg3)
{
shape->unk_08 = arg1;
shape->shadowDrawFunc = shadowDrawFunc;
shape->unk_10 = arg3;
shape->unk_14 = -1;
}
void func_8002B200(Actor* actor, LightMapper* lightMapper, GlobalContext* globalCtx, u32 dlist, Color_RGBA8* color)
{
f32 temp1;
f32 temp2;
MtxF sp60;
GraphicsContext* gfxCtx;
Gfx* gfxArr[4];
if (actor->floorPoly != NULL)
{
temp1 = actor->posRot.pos.y - actor->unk_80;
if (temp1 >= -50.0f && temp1 < 500.0f)
{
gfxCtx = globalCtx->state.gfxCtx;
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 1553);
gfxCtx->polyOpa.p = func_80093774(gfxCtx->polyOpa.p, 0x2C);
gDPSetCombineLERP(gfxCtx->polyOpa.p++,
0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0,
0, 0, 0, COMBINED, 0, 0, 0, COMBINED);
temp1 = (temp1 < 0.0f) ? 0.0f : ((temp1 > 150.0f) ? 150.0f : temp1);
temp2 = 1.0f - (temp1 * (1.f / 350));
if (color != NULL)
gDPSetPrimColor(gfxCtx->polyOpa.p++, 0, 0, color->r, color->g, color->b,
(u32)(actor->shape.unk_14 * temp2) & 0xFF);
else
gDPSetPrimColor(gfxCtx->polyOpa.p++, 0, 0, 0, 0, 0,
(u32)(actor->shape.unk_14 * temp2) & 0xFF);
func_80038A28(actor->floorPoly, actor->posRot.pos.x, actor->unk_80, actor->posRot.pos.z, &sp60);
Matrix_Put(&sp60);
if (dlist != (u32)&D_04049210)
Matrix_RotateY(actor->shape.rot.y * (M_PI / 32768), MTXMODE_APPLY);
temp2 = (1.0f - (temp1 * (1.f / 350))) * actor->shape.unk_10;
Matrix_Scale(actor->scale.x * temp2, 1.0f, actor->scale.z * temp2, MTXMODE_APPLY);
gSPMatrix(gfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_actor.c", 1588), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(gfxCtx->polyOpa.p++, dlist);
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 1594);
}
}
}
void ActorShadow_DrawFunc_Circle(Actor* actor, LightMapper* lightMapper, GlobalContext* globalCtx)
{
func_8002B200(actor, lightMapper, globalCtx, &D_04049210, NULL);
}
Color_RGBA8 D_80115F80 = { 0xFF, 0xFF, 0xFF, 0xFF };
void ActorShadow_DrawFunc_WhiteCircle(Actor* actor, LightMapper* lightMapper, GlobalContext* globalCtx)
{
func_8002B200(actor, lightMapper, globalCtx, &D_04049210, &D_80115F80);
}
void ActorShadow_DrawFunc_Squiggly(Actor* actor, LightMapper* lightMapper, GlobalContext* globalCtx)
{
func_8002B200(actor, lightMapper, globalCtx, &D_04049AD0, NULL);
}
void func_8002B66C(GlobalContext* globalCtx, Light* light, MtxF* arg2, s32 arg3, f32 arg4, f32 arg5, f32 arg6)
{
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
f32 sp58;
Gfx* gfxArr[7];
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 1661);
gDPSetPrimColor(gfxCtx->polyOpa.p++, 0, 0, 0, 0, 0,
(u32)(((arg3 * 0.00005f) > 1.0f ? 1.0f : (arg3 * 0.00005f)) * arg4) & 0xFF);
sp58 = Math_atan2f(light->l.dir[0], light->l.dir[2]);
arg6 *= (4.5f - (light->l.dir[1] * 0.035f));
arg6 = (arg6 < 1.0f) ? 1.0f : arg6;
Matrix_Put(arg2);
Matrix_RotateY(sp58, MTXMODE_APPLY);
Matrix_Scale(arg5, 1.0f, arg5 * arg6, MTXMODE_APPLY);
gSPMatrix(gfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_actor.c", 1687), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(gfxCtx->polyOpa.p++, &D_04048180);
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 1693);
}
#ifdef NON_MATCHING
// this function still needs a lot of work
void ActorShadow_DrawFunc_Teardrop(Actor* actor, LightMapper* lightMapper, GlobalContext* globalCtx)
{
GraphicsContext* gfxCtx;
MtxF spE8;
Vec2f spE0;
s32 index;
f32* spAC;
Gfx* gfxArr[7];
f32 temp_10;
u8 temp_14;
f32 temp_f0;
f32 temp_f20;
f32 temp_f20_2;
f32 temp_f22_2;
f32 temp_f24;
s32 temp_a3;
s32 temp_lo;
u8 temp_s6;
Vec3f* phi_s7;
f32 phi_f2;
Light* phi_s0;
s32 phi_s1;
s32 phi_s2;
temp_f20 = actor->posRot.pos.y - actor->unk_80;
if (temp_f20 > 20.0f)
{
temp_10 = actor->shape.unk_10;
actor->shape.unk_10 *= 0.3f;
temp_14 = actor->shape.unk_14;
actor->shape.unk_14 *= ((temp_f20 - 20.0f) * 0.02f) > 1.0f ? 1.0f : ((temp_f20 - 20.0f) * 0.02f);
ActorShadow_DrawFunc_Circle(actor, lightMapper, globalCtx);
actor->shape.unk_10 = temp_10;
actor->shape.unk_14 = temp_14;
}
if (temp_f20 < 200.0f)
{
spAC = &spE0.x;
gfxCtx = globalCtx->state.gfxCtx;
temp_s6 = lightMapper->numLights - 2;
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 1741);
gfxCtx->polyOpa.p = func_80093774(gfxCtx->polyOpa.p, 0x2C);
actor->shape.unk_15 = 0;
phi_s7 = &actor->unk_CC;
for (index = 0; index < 2; index++)
{
phi_s7->y += 50.0f;
*spAC = func_800BFCB8(globalCtx, &spE8, phi_s7);
phi_s7->y -= 50.0f;
actor->shape.unk_15 *= 2;
phi_f2 = phi_s7->y - *spAC;
if ((phi_f2 >= -1.0f) && (phi_f2 < 500.0f))
{
phi_s0 = lightMapper->lights;
if (phi_f2 <= 0.0f)
actor->shape.unk_15++;
if (30.0f < phi_f2)
phi_f2 = 30.0f;
temp_f24 = actor->shape.unk_14 * (1.0f - (phi_f2 * (1.f / 30)));
if (30.0f < phi_f2)
phi_f2 = 30.0f;
temp_f20_2 = 1.0f - (phi_f2 * (1.f / 70));
temp_f22_2 = (actor->shape.unk_10 * temp_f20_2) * actor->scale.x;
phi_s2 = 0;
for (phi_s1 = 0; phi_s1 < temp_s6; phi_s1++)
{
if (phi_s0->l.dir[1] > 0)
{
temp_lo = ABS(phi_s0->l.dir[1]) * ((phi_s0->l.col[0] + phi_s0->l.col[1]) + phi_s0->l.col[2]);
if (temp_lo > 0)
{
func_8002B66C(globalCtx, phi_s0, &spE8, temp_lo, temp_f24, temp_f22_2, temp_f20_2);
phi_s2 += temp_lo;
}
}
phi_s0++;
}
for (phi_s1 = 0; phi_s1 < 2; phi_s1++)
{
if (phi_s0->l.dir[1] > 0)
{
temp_a3 = (ABS(phi_s0->l.dir[1]) * ((phi_s0->l.col[0] + phi_s0->l.col[1]) + phi_s0->l.col[2])) - (phi_s2 * 8);
if (temp_a3 > 0)
func_8002B66C(globalCtx, phi_s0, &spE8, temp_a3, temp_f24, temp_f22_2, temp_f20_2);
}
phi_s0++;
}
}
spAC++;
phi_s7++;
}
if (!(actor->bgCheckFlags & 1))
actor->shape.unk_15 = 0;
else if (actor->shape.unk_15 == 3)
{
temp_f0 = actor->unk_CC.y - actor->unk_D8.y;
if ((spE0.x + temp_f0) < (spE0.y - temp_f0))
actor->shape.unk_15 = 2;
else
actor->shape.unk_15 = 1;
}
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 1831);
}
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/ActorShadow_DrawFunc_Teardrop.s")
#endif
void func_8002BDB0(Actor* actor, s32 arg1, s32 arg2, UNK_PTR arg3, s32 arg4, UNK_PTR arg5)
{
if (arg1 == arg2)
Matrix_MultVec3f(arg3, &actor->unk_CC);
else if (arg1 == arg4)
Matrix_MultVec3f(arg5, &actor->unk_D8);
}
void func_8002BE04(GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, f32* arg3)
{
func_800A6E10(&globalCtx->mf_11D60, arg1, arg2, arg3);
*arg3 = (*arg3 < 1.0f) ? 1.0f : (1.0f / *arg3);
}
typedef struct
{
/* 0x00 */ Color_RGBA8 inner;
/* 0x04 */ Color_RGBA8 outer;
} NaviColor; // size = 0x8
NaviColor sNaviColorList[] =
{
{ { 0x00, 0xFF, 0x00, 0xFF }, { 0x00, 0xFF, 0x00, 0x00 } },
{ { 0x00, 0xFF, 0x00, 0xFF }, { 0x00, 0xFF, 0x00, 0x00 } },
{ { 0xFF, 0xFF, 0xFF, 0xFF }, { 0x00, 0x00, 0xFF, 0x00 } },
{ { 0x00, 0xFF, 0x00, 0xFF }, { 0x00, 0xFF, 0x00, 0x00 } },
{ { 0x96, 0x96, 0xFF, 0xFF }, { 0x96, 0x96, 0xFF, 0x00 } },
{ { 0xFF, 0xFF, 0x00, 0xFF }, { 0xC8, 0x9B, 0x00, 0x00 } },
{ { 0x00, 0xFF, 0x00, 0xFF }, { 0x00, 0xFF, 0x00, 0x00 } },
{ { 0x00, 0xFF, 0x00, 0xFF }, { 0x00, 0xFF, 0x00, 0x00 } },
{ { 0x00, 0xFF, 0x00, 0xFF }, { 0x00, 0xFF, 0x00, 0x00 } },
{ { 0xFF, 0xFF, 0x00, 0xFF }, { 0xC8, 0x9B, 0x00, 0x00 } },
{ { 0x00, 0xFF, 0x00, 0xFF }, { 0x00, 0xFF, 0x00, 0x00 } },
{ { 0x00, 0xFF, 0x00, 0xFF }, { 0x00, 0xFF, 0x00, 0x00 } },
{ { 0x00, 0xFF, 0x00, 0xFF }, { 0x00, 0xFF, 0x00, 0x00 } },
};
// unused
Gfx D_80115FF0[] =
{
gsSPEndDisplayList(),
};
void func_8002BE64(TargetContext* targetCtx, s32 index, f32 arg2, f32 arg3, f32 arg4)
{
targetCtx->arr_50[index].pos.x = arg2;
targetCtx->arr_50[index].pos.y = arg3;
targetCtx->arr_50[index].pos.z = arg4;
targetCtx->arr_50[index].unk_0C = targetCtx->unk_44;
}
void func_8002BE98(TargetContext* targetCtx, s32 actorType, GlobalContext* globalCtx)
{
TargetContextEntry* entry;
NaviColor* naviColor;
s32 i;
Math_Vec3f_Copy(&targetCtx->targetCenterPos, &globalCtx->view.eye);
targetCtx->unk_44 = 500.0f;
targetCtx->unk_48 = 0x100;
naviColor = &sNaviColorList[actorType];
entry = &targetCtx->arr_50[0];
for (i = 0; i < ARRAY_COUNT(targetCtx->arr_50); i++)
{
func_8002BE64(targetCtx, i, 0.0f, 0.0f, 0.0f);
entry->color.r = naviColor->inner.r;
entry->color.g = naviColor->inner.g;
entry->color.b = naviColor->inner.b;
entry++;
}
}
void func_8002BF60(TargetContext* targetCtx, Actor* actor, s32 actorType, GlobalContext* globalCtx)
{
NaviColor* naviColor = &sNaviColorList[actorType];
targetCtx->naviRefPos.x = actor->posRot2.pos.x;
targetCtx->naviRefPos.y = actor->posRot2.pos.y + (actor->unk_4C * actor->scale.y);
targetCtx->naviRefPos.z = actor->posRot2.pos.z;
targetCtx->naviInner.r = naviColor->inner.r;
targetCtx->naviInner.g = naviColor->inner.g;
targetCtx->naviInner.b = naviColor->inner.b;
targetCtx->naviInner.a = naviColor->inner.a;
targetCtx->naviOuter.r = naviColor->outer.r;
targetCtx->naviOuter.g = naviColor->outer.g;
targetCtx->naviOuter.b = naviColor->outer.b;
targetCtx->naviOuter.a = naviColor->outer.a;
}
void func_8002C0C0(TargetContext* targetCtx, Actor* actor, GlobalContext* globalCtx)
{
targetCtx->arrowPointedActor = NULL;
targetCtx->targetedActor = NULL;
targetCtx->unk_40 = 0.0f;
targetCtx->unk_8C = NULL;
targetCtx->unk_90 = NULL;
targetCtx->unk_4B = 0;
targetCtx->unk_4C = 0;
func_8002BF60(targetCtx, actor, actor->type, globalCtx);
func_8002BE98(targetCtx, actor->type, globalCtx);
}
#ifdef NON_MATCHING
// this function still needs some work
void func_8002C124(TargetContext* targetCtx, GlobalContext* globalCtx)
{
Actor* actor;
Player* player;
GraphicsContext* gfxCtx;
Gfx* gfxArr[5];
s16 spCE;
Vec3f spBC;
s32 spB8;
f32 spB4;
s32 spB0;
s32 spAC;
s32 i;
TargetContextEntry* entry;
f32 temp1;
f32 var1;
f32 var2;
Vec3f* vec;
gfxCtx = globalCtx->state.gfxCtx;
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 2029);
if (targetCtx->unk_48 != 0)
{
player = PLAYER;
spCE = 0xFF;
var1 = 1.0f;
if (targetCtx->unk_4B != 0)
spB8 = 1;
else
spB8 = 3;
if (targetCtx->targetedActor != NULL)
{
Math_Vec3f_Copy(&targetCtx->targetCenterPos, &targetCtx->targetedActor->posRot2.pos);
var1 = (500.0f - targetCtx->unk_44) / 420.0f;
}
else
{
targetCtx->unk_48 -= 0x78;
if (targetCtx->unk_48 < 0)
targetCtx->unk_48 = 0;
spCE = targetCtx->unk_48;
}
func_8002BE04(globalCtx, &targetCtx->targetCenterPos, &spBC, &spB4);
temp1 = ((spBC.x * spB4) * 160.0f) * var1;
spBC.x = (temp1 < -320.0f) ? -320.0f : ((temp1 > 320.0f) ? 320.0f : temp1);
temp1 = ((spBC.y * spB4) * 120.0f) * var1;
spBC.y = (temp1 < -240.0f) ? -240.0f : ((temp1 > 240.0f) ? 240.0f : temp1);
spBC.z *= var1;
targetCtx->unk_4C--;
if (targetCtx->unk_4C < 0)
targetCtx->unk_4C = 2;
func_8002BE64(targetCtx, targetCtx->unk_4C, spBC.x, spBC.y, spBC.z);
if ((!(player->stateFlags1 & 0x40)) || (targetCtx->targetedActor != player->unk_664))
{
gfxCtx->overlay.p = func_80093774(gfxCtx->overlay.p, 0x39);
for (spB0 = 0, spAC = targetCtx->unk_4C; spB0 < spB8; spB0++)
{
entry = &targetCtx->arr_50[spAC];
if (entry->unk_0C < 500.0f)
{
if (entry->unk_0C <= 120.0f)
var2 = 0.15f;
else
var2 = ((entry->unk_0C - 120.0f) * 0.001f) + 0.15f;
Matrix_Translate(entry->pos.x, entry->pos.y, 0.0f, MTXMODE_NEW);
Matrix_Scale(var2, 0.15f, 1.0f, MTXMODE_APPLY);
gDPSetPrimColor(gfxCtx->overlay.p++, 0, 0,
entry->color.r, entry->color.g, entry->color.b, (u8)spCE);
Matrix_RotateZ((targetCtx->unk_4B & 0x7F) * (M_PI / 64), MTXMODE_APPLY);
for (i = 0; i < 4; i++)
{
Matrix_RotateZ(M_PI / 2, MTXMODE_APPLY);
Matrix_Push();
Matrix_Translate(entry->unk_0C, entry->unk_0C, 0.0f, MTXMODE_APPLY);
gSPMatrix(gfxCtx->overlay.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_actor.c", 2116), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(gfxCtx->overlay.p++, &D_0404D450);
Matrix_Pull();
}
}
spCE = spCE - (0xFF / 3);
if (spCE < 0)
spCE = 0;
spAC = (spAC + 1) % 3;
}
}
}
actor = targetCtx->unk_94;
if ((actor != NULL) && !(actor->flags & 0x8000000))
{
NaviColor* naviColor = &sNaviColorList[actor->type];
gfxCtx->polyXlu.p = func_80093774(gfxCtx->polyXlu.p, 0x7);
Matrix_Translate(actor->posRot2.pos.x,
actor->posRot2.pos.y + (actor->unk_4C * actor->scale.y) + 17.0f,
actor->posRot2.pos.z,
MTXMODE_NEW);
Matrix_RotateY((f32)((u16)(globalCtx->gameplayFrames * 3000)) * (M_PI / 32768), MTXMODE_APPLY);
Matrix_Scale((iREG(27) + 35) / 1000.0f,
(iREG(28) + 60) / 1000.0f,
(iREG(29) + 50) / 1000.0f,
MTXMODE_APPLY);
gDPSetPrimColor(gfxCtx->polyXlu.p++, 0, 0,
naviColor->inner.r, naviColor->inner.g, naviColor->inner.b, 0xFF);
gSPMatrix(gfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_actor.c", 2153), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(gfxCtx->polyXlu.p++, &D_0400CB70);
}
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 2158);
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_8002C124.s")
#endif
void func_8002C7BC(TargetContext* targetCtx, Player* player, Actor* actorArg, GlobalContext* globalCtx)
{
s32 pad;
Actor* unkActor;
s32 actorType;
Vec3f sp50;
f32 sp4C;
f32 temp1;
f32 temp2;
f32 temp3;
f32 temp4;
f32 temp5;
f32 temp6;
s32 lockOnSfxId;
unkActor = NULL;
if ((player->unk_664 != NULL) && (player->unk_84B[player->unk_846] == 2))
targetCtx->unk_94 = NULL;
else
{
func_80032AF0(globalCtx, &globalCtx->actorCtx, &unkActor, player);
targetCtx->unk_94 = unkActor;
}
if (targetCtx->unk_8C != NULL)
{
unkActor = targetCtx->unk_8C;
targetCtx->unk_8C = NULL;
}
else if (actorArg != NULL)
unkActor = actorArg;
if (unkActor != NULL)
actorType = unkActor->type;
else
actorType = player->actor.type;
if ((unkActor != targetCtx->arrowPointedActor) || (actorType != targetCtx->activeType))
{
targetCtx->arrowPointedActor = unkActor;
targetCtx->activeType = actorType;
targetCtx->unk_40 = 1.0f;
}
if (unkActor == NULL)
unkActor = &player->actor;
if (Math_ApproxF(&targetCtx->unk_40, 0.0f, 0.25f) == 0)
{
temp1 = 0.25f / targetCtx->unk_40;
temp2 = unkActor->posRot.pos.x - targetCtx->naviRefPos.x;
temp3 = (unkActor->posRot.pos.y + (unkActor->unk_4C * unkActor->scale.y)) - targetCtx->naviRefPos.y;
temp4 = unkActor->posRot.pos.z - targetCtx->naviRefPos.z;
targetCtx->naviRefPos.x += temp2 * temp1;
targetCtx->naviRefPos.y += temp3 * temp1;
targetCtx->naviRefPos.z += temp4 * temp1;
}
else
func_8002BF60(targetCtx, unkActor, actorType, globalCtx);
if ((actorArg != NULL) && (targetCtx->unk_4B == 0))
{
func_8002BE04(globalCtx, &actorArg->posRot2.pos, &sp50, &sp4C);
if (((sp50.z <= 0.0f) || (1.0f <= fabsf(sp50.x * sp4C))) || (1.0f <= fabsf(sp50.y * sp4C)))
actorArg = NULL;
}
if (actorArg != NULL)
{
if (actorArg != targetCtx->targetedActor)
{
func_8002BE98(targetCtx, actorArg->type, globalCtx);
targetCtx->targetedActor = actorArg;
if (actorArg->id == ACTOR_EN_BOOM)
targetCtx->unk_48 = 0;
lockOnSfxId = ((actorArg->flags & 5) == 5) ? NA_SE_SY_LOCK_ON : NA_SE_SY_LOCK_ON_HUMAN;
func_80078884(lockOnSfxId);
}
targetCtx->targetCenterPos.x = actorArg->posRot.pos.x;
targetCtx->targetCenterPos.y = actorArg->posRot.pos.y - (actorArg->shape.unk_08 * actorArg->scale.y);
targetCtx->targetCenterPos.z = actorArg->posRot.pos.z;
if (targetCtx->unk_4B == 0)
{
temp5 = (500.0f - targetCtx->unk_44) * 3.0f;
temp6 = (temp5 < 30.0f) ? 30.0f : ((100.0f < temp5) ? 100.0f : temp5);
if (Math_ApproxF(&targetCtx->unk_44, 80.0f, temp6) != 0)
targetCtx->unk_4B++;
}
else
{
targetCtx->unk_4B = (targetCtx->unk_4B + 3) | 0x80;
targetCtx->unk_44 = 120.0f;
}
}
else
{
targetCtx->targetedActor = NULL;
Math_ApproxF(&targetCtx->unk_44, 500.0f, 80.0f);
}
}
/**
* Tests if current scene switch flag is set.
*/
s32 Flags_GetSwitch(GlobalContext* globalCtx, s32 flag)
{
if (flag < 0x20)
return globalCtx->actorCtx.flags.swch & (1 << flag);
else
return globalCtx->actorCtx.flags.tempSwch & (1 << flag);
}
/**
* Sets current scene switch flag.
*/
void Flags_SetSwitch(GlobalContext* globalCtx, s32 flag)
{
if (flag < 0x20)
globalCtx->actorCtx.flags.swch |= (1 << flag);
else
globalCtx->actorCtx.flags.tempSwch |= (1 << flag);
}
/**
* Unsets current scene switch flag.
*/
void Flags_UnsetSwitch(GlobalContext* globalCtx, s32 flag)
{
if (flag < 0x20)
globalCtx->actorCtx.flags.swch &= ~(1 << flag);
else
globalCtx->actorCtx.flags.tempSwch &= ~(1 << flag);
}
/**
* Tests if current scene unknown flag is set.
*/
s32 Flags_GetUnknown(GlobalContext* globalCtx, s32 flag)
{
if (flag < 0x20)
return globalCtx->actorCtx.flags.unk0 & (1 << flag);
else
return globalCtx->actorCtx.flags.unk1 & (1 << flag);
}
/**
* Sets current scene unknown flag.
*/
void Flags_SetUnknown(GlobalContext* globalCtx, s32 flag)
{
if (flag < 0x20)
globalCtx->actorCtx.flags.unk0 |= (1 << flag);
else
globalCtx->actorCtx.flags.unk1 |= (1 << flag);
}
/**
* Unsets current scene unknown flag.
*/
void Flags_UnsetUnknown(GlobalContext* globalCtx, s32 flag)
{
if (flag < 0x20)
globalCtx->actorCtx.flags.unk0 &= ~(1 << flag);
else
globalCtx->actorCtx.flags.unk1 &= ~(1 << flag);
}
/**
* Tests if current scene chest flag is set.
*/
s32 Flags_GetTreasure(GlobalContext* globalCtx, s32 flag)
{
return globalCtx->actorCtx.flags.chest & (1 << flag);
}
/**
* Sets current scene chest flag.
*/
void Flags_SetTreasure(GlobalContext* globalCtx, s32 flag)
{
globalCtx->actorCtx.flags.chest |= (1 << flag);
}
/**
* Tests if current scene clear flag is set.
*/
s32 Flags_GetClear(GlobalContext* globalCtx, s32 flag)
{
return globalCtx->actorCtx.flags.clear & (1 << flag);
}
/**
* Sets current scene clear flag.
*/
void Flags_SetClear(GlobalContext* globalCtx, s32 flag)
{
globalCtx->actorCtx.flags.clear |= (1 << flag);
}
/**
* Unsets current scene clear flag.
*/
void Flags_UnsetClear(GlobalContext* globalCtx, s32 flag)
{
globalCtx->actorCtx.flags.clear &= ~(1 << flag);
}
/**
* Tests if current scene temp clear flag is set.
*/
s32 Flags_GetTempClear(GlobalContext* globalCtx, s32 flag)
{
return globalCtx->actorCtx.flags.tempClear & (1 << flag);
}
/**
* Sets current scene temp clear flag.
*/
void Flags_SetTempClear(GlobalContext* globalCtx, s32 flag)
{
globalCtx->actorCtx.flags.tempClear |= 1 << flag;
}
/**
* Unsets current scene temp clear flag.
*/
void Flags_UnsetTempClear(GlobalContext* globalCtx, s32 flag)
{
globalCtx->actorCtx.flags.tempClear &= ~(1 << flag);
}
/**
* Tests if current scene collectible flag is set.
*/
s32 Flags_GetCollectible(GlobalContext* globalCtx, s32 flag)
{
if (flag < 0x20)
return globalCtx->actorCtx.flags.collect & (1 << flag);
else
return globalCtx->actorCtx.flags.tempCollect & (1 << flag);
}
/**
* Sets current scene collectible flag.
*/
void Flags_SetCollectible(GlobalContext* globalCtx, s32 flag)
{
if (flag != 0)
{
if (flag < 0x20)
globalCtx->actorCtx.flags.collect |= 1 << flag;
else
globalCtx->actorCtx.flags.tempCollect |= 1 << flag;
}
}
void func_8002CDE4(GlobalContext* globalCtx, TitleCardContext* titleCtx)
{
titleCtx->delayA = titleCtx->delayB = titleCtx->unk_E = titleCtx->unk_C = 0;
}
void TitleCard_InitBossName(GlobalContext* globalCtx, TitleCardContext* titleCtx, u32 texture,
s16 arg3, s16 arg4, u8 arg5, u8 arg6)
{
titleCtx->texture = texture;
titleCtx->unk_4 = arg3;
titleCtx->unk_6 = arg4;
titleCtx->unk_8 = arg5;
titleCtx->unk_9 = arg6;
titleCtx->delayA = 80;
titleCtx->delayB = 0;
}
void TitleCard_InitPlaceName(GlobalContext* globalCtx, TitleCardContext* titleCtx, u32 texture,
s32 arg3, s32 arg4, s32 arg5, s32 arg6, s32 arg7)
{
Scene* loadedScene = globalCtx->loadedScene;
u32 size = loadedScene->titleVromEnd - loadedScene->titleVromStart;
if ((size != 0) && (size <= 0x3000))
DmaMgr_SendRequest1(texture, loadedScene->titleVromStart, size, "../z_actor.c", 2765);
titleCtx->texture = texture;
titleCtx->unk_4 = arg3;
titleCtx->unk_6 = arg4;
titleCtx->unk_8 = arg5;
titleCtx->unk_9 = arg6;
titleCtx->delayA = 80;
titleCtx->delayB = arg7;
}
void TitleCard_Update(GlobalContext* globalCtx, TitleCardContext* titleCtx)
{
if (DECR(titleCtx->delayB) == 0)
{
if (DECR(titleCtx->delayA) == 0)
{
Math_ApproxS(&titleCtx->unk_C, 0, 30);
Math_ApproxS(&titleCtx->unk_E, 0, 70);
}
else
{
Math_ApproxS(&titleCtx->unk_C, 255, 10);
Math_ApproxS(&titleCtx->unk_E, 255, 20);
}
}
}
#ifdef NON_MATCHING
// major ordering and stack usage differences
void TitleCard_Draw(GlobalContext* globalCtx, TitleCardContext* titleCtx)
{
s32 spCC;
s32 spC8;
s32 unk1;
s32 spC0;
s32 unk2;
s32 spB8;
s32 spB4;
s32 spB0;
GraphicsContext* gfxCtx;
Gfx* gfxArr[4];
s32 sp38;
if (titleCtx->unk_C != 0)
{
spCC = titleCtx->unk_8;
spC8 = titleCtx->unk_9;
spC0 = (titleCtx->unk_4 * 4) - (spCC * 2);
spB8 = (titleCtx->unk_6 * 4) - (spC8 * 2);
sp38 = spCC * 2;
gfxCtx = globalCtx->state.gfxCtx;
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 2824);
spB0 = spCC * spC8 * gSaveContext.language;
spC8 = (spCC * spC8 > 0x1000) ? 0x1000 / spCC : spC8;
spB4 = (spC8 * 4) + spB8;
gfxCtx->overlay.p = func_80093808(gfxCtx->overlay.p);
gDPSetPrimColor(gfxCtx->overlay.p++, 0, 0,
(u8)titleCtx->unk_E, (u8)titleCtx->unk_E,
(u8)titleCtx->unk_E, (u8)titleCtx->unk_C);
gDPLoadTextureBlock(gfxCtx->overlay.p++,
titleCtx->texture + spB0,
G_IM_FMT_IA,
G_IM_SIZ_8b,
spCC, spC8,
0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMASK, G_TX_NOMASK,
G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle(gfxCtx->overlay.p++, spC0, spB8,
((sp38 * 2) + spC0) - 4, spB8 - 1, G_TX_RENDERTILE,
0, 0, 1024, 1024);
spC8 = titleCtx->unk_9 - spC8;
if (spC8 > 0)
{
gDPLoadTextureBlock(gfxCtx->overlay.p++,
titleCtx->texture + spB0 + 0x1000,
G_IM_FMT_IA,
G_IM_SIZ_8b,
spCC, spC8,
0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMASK, G_TX_NOMASK,
G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle(gfxCtx->overlay.p++, spC0, spB4,
((sp38 * 2) + spC0) - 4, spB4 - 1, G_TX_RENDERTILE,
0, 0, 1024, 1024);
}
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 2880);
}
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/TitleCard_Draw.s")
#endif
s32 func_8002D53C(GlobalContext* globalCtx, TitleCardContext* titleCtx)
{
if ((globalCtx->actorCtx.titleCtx.delayB != 0) ||
(globalCtx->actorCtx.titleCtx.unk_C != 0))
{
titleCtx->delayA = 0;
titleCtx->delayB = 0;
return 0;
}
return 1;
}
void Actor_Kill(Actor* actor)
{
actor->draw = NULL;
actor->update = NULL;
actor->flags &= ~0x1;
}
void Actor_InitPosRot(Actor* actor)
{
actor->posRot = actor->initPosRot;
}
void Actor_SetHeight(Actor* actor, f32 offset)
{
actor->posRot2.pos.x = actor->posRot.pos.x;
actor->posRot2.pos.y = actor->posRot.pos.y + offset;
actor->posRot2.pos.z = actor->posRot.pos.z;
actor->posRot2.rot.x = actor->posRot.rot.x;
actor->posRot2.rot.y = actor->posRot.rot.y;
actor->posRot2.rot.z = actor->posRot.rot.z;
}
void func_8002D5F4(Actor* actor)
{
actor->posRot.rot = actor->shape.rot;
}
void func_8002D610(Actor* actor)
{
actor->shape.rot = actor->posRot.rot;
}
void Actor_SetScale(Actor* actor, f32 scale)
{
actor->scale.z = scale;
actor->scale.y = scale;
actor->scale.x = scale;
}
void Actor_SetObjectDependency(GlobalContext* globalCtx, Actor* actor)
{
gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[actor->objBankIndex].segment);
}
void Actor_Init(Actor* actor, GlobalContext* globalCtx)
{
Actor_InitPosRot(actor);
func_8002D610(actor);
Actor_SetHeight(actor, 0.0f);
Math_Vec3f_Copy(&actor->pos4, &actor->posRot.pos);
Actor_SetScale(actor, 0.01f);
actor->unk_1F = 3;
actor->minVelocityY = -20.0f;
actor->waterSurfaceDist = FLT_MAX;
actor->naviEnemyId = 0xFF;
actor->unk_F4 = 1000.0f;
actor->unk_F8 = 350.0f;
actor->unk_FC = 700.0f;
func_80061E48(&actor->sub_98);
actor->floorPolySource = 0x32;
ActorShape_Init(&actor->shape, 0.0f, NULL, 0.0f);
if (Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex))
{
Actor_SetObjectDependency(globalCtx, actor);
actor->init(actor, globalCtx);
actor->init = NULL;
}
}
void Actor_Destroy(Actor* actor, GlobalContext* globalCtx)
{
ActorOverlay* overlayEntry;
char* name;
if (actor->destroy != NULL)
{
actor->destroy(actor, globalCtx);
actor->destroy = NULL;
}
else
{
overlayEntry = actor->overlayEntry;
name = overlayEntry->name != NULL ? overlayEntry->name : "";
// Translates to: "NO Actor CLASS DESTRUCT [%s]"
osSyncPrintf("Actorクラス デストラクトがありません [%s]\n" VT_RST, name);
}
}
void func_8002D7EC(Actor* actor)
{
f32 speedRate = R_UPDATE_RATE * 0.5f;
actor->posRot.pos.x += (actor->velocity.x * speedRate) + actor->sub_98.displacement.x;
actor->posRot.pos.y += (actor->velocity.y * speedRate) + actor->sub_98.displacement.y;
actor->posRot.pos.z += (actor->velocity.z * speedRate) + actor->sub_98.displacement.z;
}
void func_8002D868(Actor* actor)
{
actor->velocity.x = Math_Sins(actor->posRot.rot.y) * actor->speedXZ;
actor->velocity.z = Math_Coss(actor->posRot.rot.y) * actor->speedXZ;
actor->velocity.y += actor->gravity;
if (actor->velocity.y < actor->minVelocityY)
actor->velocity.y = actor->minVelocityY;
}
void Actor_MoveForward(Actor* actor)
{
func_8002D868(actor);
func_8002D7EC(actor);
}
void func_8002D908(Actor* actor)
{
f32 sp24 = Math_Coss(actor->posRot.rot.x) * actor->speedXZ;
actor->velocity.x = Math_Sins(actor->posRot.rot.y) * sp24;
actor->velocity.y = Math_Sins(actor->posRot.rot.x) * actor->speedXZ;
actor->velocity.z = Math_Coss(actor->posRot.rot.y) * sp24;
}
void func_8002D97C(Actor* actor)
{
func_8002D908(actor);
func_8002D7EC(actor);
}
void func_8002D9A4(Actor* actor, f32 arg1)
{
actor->speedXZ = Math_Coss(actor->posRot.rot.x) * arg1;
actor->velocity.y = -Math_Sins(actor->posRot.rot.x) * arg1;
}
void func_8002D9F8(Actor* actor, UNK_PTR arg1)
{
Vec3f sp1C;
func_800A54FC(arg1, &sp1C, actor->shape.rot.y, actor);
actor->posRot.pos.x += sp1C.x * actor->scale.x;
actor->posRot.pos.y += sp1C.y * actor->scale.y;
actor->posRot.pos.z += sp1C.z * actor->scale.z;
}
s16 func_8002DA78(Actor* actorA, Actor* actorB)
{
return Math_Vec3f_Yaw(&actorA->posRot.pos, &actorB->posRot.pos);
}
s16 func_8002DA9C(Actor* actorA, Actor* actorB)
{
return Math_Vec3f_Yaw(&actorA->posRot2.pos, &actorB->posRot2.pos);
}
s16 func_8002DAC0(Actor* actor, Vec3f* arg1)
{
return Math_Vec3f_Yaw(&actor->posRot.pos, arg1);
}
s16 func_8002DAE0(Actor* actorA, Actor* actorB)
{
return Math_Vec3f_Pitch(&actorA->posRot.pos, &actorB->posRot.pos);
}
s16 func_8002DB04(Actor* actorA, Actor* actorB)
{
return Math_Vec3f_Pitch(&actorA->posRot2.pos, &actorB->posRot2.pos);
}
s16 func_8002DB28(Actor* actor, Vec3f* arg1)
{
return Math_Vec3f_Pitch(&actor->posRot.pos, arg1);
}
f32 func_8002DB48(Actor* actorA, Actor* actorB)
{
return Math_Vec3f_DistXYZ(&actorA->posRot.pos, &actorB->posRot.pos);
}
f32 func_8002DB6C(Actor* actor, Vec3f* arg1)
{
return Math_Vec3f_DistXYZ(&actor->posRot.pos, arg1);
}
f32 func_8002DB8C(Actor* actorA, Actor* actorB)
{
return Math_Vec3f_DistXZ(&actorA->posRot.pos, &actorB->posRot.pos);
}
f32 func_8002DBB0(Actor* actor, Vec3f* arg1)
{
return Math_Vec3f_DistXZ(&actor->posRot.pos, arg1);
}
void func_8002DBD0(Actor* actor, Vec3f* result, Vec3f* arg2)
{
f32 cosRot2Y;
f32 sinRot2Y;
f32 deltaX;
f32 deltaZ;
cosRot2Y = Math_Coss(actor->shape.rot.y);
sinRot2Y = Math_Sins(actor->shape.rot.y);
deltaX = arg2->x - actor->posRot.pos.x;
deltaZ = arg2->z - actor->posRot.pos.z;
result->x = (deltaX * cosRot2Y) - (deltaZ * sinRot2Y);
result->z = (deltaX * sinRot2Y) + (deltaZ * cosRot2Y);
result->y = arg2->y - actor->posRot.pos.y;
}
f32 Actor_HeightDiff(Actor* actorA, Actor* actorB)
{
return actorB->posRot.pos.y - actorA->posRot.pos.y;
}
f32 func_8002DC84(Player* player)
{
f32 offset = (player->stateFlags1 & 0x800000) ? 32.0f : 0.0f;
if (LINK_IS_ADULT)
return offset + 68.0f;
else
return offset + 44.0f;
}
f32 func_8002DCE4(Player* player)
{
if (player->stateFlags1 & 0x800000)
return 8.0f;
else if (player->stateFlags1 & 0x8000000)
return (R_RUN_SPEED_LIMIT / 100.0f) * 0.6f;
else
return R_RUN_SPEED_LIMIT / 100.0f;
}
s32 func_8002DD6C(Player* player)
{
return player->stateFlags1 & 0x8;
}
s32 func_8002DD78(Player* player)
{
return func_8002DD6C(player) && player->unk_834;
}
s32 func_8002DDA8(GlobalContext* globalCtx)
{
Player* player = PLAYER;
return (player->stateFlags1 & 0x800) || func_8002DD78(player);
}
s32 func_8002DDE4(GlobalContext* globalCtx)
{
Player* player = PLAYER;
return player->stateFlags2 & 0x8;
}
s32 func_8002DDF4(GlobalContext* globalCtx)
{
Player* player = PLAYER;
return player->stateFlags2 & 0x1000;
}
typedef struct
{
/* 0x000 */ Actor actor;
/* 0x14C */ char unk_14C[0xB4];
/* 0x200 */ Actor* unk_200;
/* 0x204 */ f32 unk_204;
/* 0x208 */ f32 unk_208;
/* 0x20C */ f32 unk_20C;
/* 0x210 */ s16 unk_210;
} ActorArmsHook;
void func_8002DE04(GlobalContext* globalCtx, Actor* actorA, Actor* actorB)
{
ActorArmsHook* hookActor;
hookActor = (ActorArmsHook*)Actor_Find(&globalCtx->actorCtx, 0x0066, ACTORTYPE_ITEMACTION);
hookActor->unk_200 = actorB;
hookActor->unk_204 = 0.0f;
hookActor->unk_208 = 0.0f;
hookActor->unk_20C = 0.0f;
actorB->flags |= 0x2000;
actorA->flags &= ~0x2000;
}
void func_8002DE74(GlobalContext* globalCtx, Player* player)
{
if ((globalCtx->roomCtx.curRoom.unk_03 != 4) && func_800C0CB8(globalCtx))
func_8005A77C(func_800C04A4(globalCtx, 0), 6);
}
void func_8002DECC(GlobalContext* globalCtx, Player* player, Actor* actor)
{
player->rideActor = actor;
player->stateFlags1 |= 0x800000;
actor->attachedB = &player->actor;
}
s32 func_8002DEEC(Player* player)
{
return (player->stateFlags1 & 0x20000080) || player->action;
}
void func_8002DF18(GlobalContext* globalCtx, ActorContext* actorCtx)
{
func_8006DC68(globalCtx, actorCtx);
}
u32 func_8002DF38(GlobalContext* globalCtx, Actor* actor, u8 newAction)
{
Player* player = PLAYER;
player->action = newAction;
player->unk_448 = actor;
player->unk_46A = 0;
return 1;
}
s32 func_8002DF54(GlobalContext* globalCtx, Actor* actor, u8 arg2)
{
Player* player = PLAYER;
func_8002DF38(globalCtx, actor, arg2);
player->unk_46A = 1;
return 1;
}
void func_8002DF90(DynaPolyActor* dynaActor)
{
dynaActor->unk_154 = 0.0f;
dynaActor->unk_150 = 0.0f;
}
void func_8002DFA4(DynaPolyActor* dynaActor, f32 arg1, s16 arg2)
{
dynaActor->unk_150 += arg1;
dynaActor->unk_158 = arg2;
}
s32 func_8002DFC8(Actor* actor, s16 arg1, GlobalContext* globalCtx)
{
Player* player = PLAYER;
s16 var = (s16)(actor->rotTowardsLinkY + 0x8000) - player->actor.shape.rot.y;
if (ABS(var) < arg1)
return 1;
return 0;
}
s32 func_8002E020(Actor* actorA, Actor* actorB, s16 arg2)
{
s16 var = (s16)(func_8002DA78(actorA, actorB) + 0x8000) - actorB->shape.rot.y;
if (ABS(var) < arg2)
return 1;
return 0;
}
s32 func_8002E084(Actor* actor, s16 arg1)
{
s16 var = actor->rotTowardsLinkY - actor->shape.rot.y;
if (ABS(var) < arg1)
return 1;
return 0;
}
s32 func_8002E0D0(Actor* actorA, Actor* actorB, s16 arg2)
{
s16 var = func_8002DA78(actorA, actorB) - actorA->shape.rot.y;
if (ABS(var) < arg2)
return 1;
return 0;
}
s32 func_8002E12C(Actor* actor, f32 arg1, s16 arg2)
{
s16 var = actor->rotTowardsLinkY - actor->shape.rot.y;
if (ABS(var) < arg2)
{
f32 xyzDistanceFromLink = sqrtf(SQ(actor->xzDistanceFromLink) + SQ(actor->yDistanceFromLink));
if (xyzDistanceFromLink < arg1)
return 1;
}
return 0;
}
s32 func_8002E1A8(Actor* actorA, Actor* actorB, f32 arg2, s16 arg3)
{
if (func_8002DB48(actorA, actorB) < arg2)
{
s16 var = func_8002DA78(actorA, actorB) - actorA->shape.rot.y;
if (ABS(var) < arg3)
return 1;
}
return 0;
}
s32 func_8002E234(Actor* actor, f32 arg1, s32 arg2)
{
if ((actor->bgCheckFlags & 0x1) && (arg1 < -11.0f))
{
actor->bgCheckFlags &= ~0x1;
actor->bgCheckFlags |= 0x4;
if ((actor->velocity.y < 0.0f) && (arg2 & 0x10))
actor->velocity.y = 0.0f;
return 0;
}
return 1;
}
UNK_TYPE D_8015BBA0;
u32 D_8015BBA4;
s32 func_8002E2AC(GlobalContext* globalCtx, Actor* actor, Vec3f* arg2, s32 arg3)
{
f32 sp34;
u32 sp30;
arg2->y += 50.0f;
actor->unk_80 = func_8003CA0C(globalCtx, &globalCtx->colCtx, &actor->floorPoly, &sp30, actor, arg2);
actor->bgCheckFlags &= ~0x0086;
if (actor->unk_80 <= -32000.0f)
return func_8002E234(actor, -32000.0f, arg3);
sp34 = actor->unk_80 - actor->posRot.pos.y;
actor->floorPolySource = sp30;
if (sp34 >= 0.0f)
{
actor->bgCheckFlags |= 0x80;
if (actor->bgCheckFlags & 0x10)
{
if (sp30 != D_8015BBA4)
{
if (sp34 > 15.0f)
actor->bgCheckFlags |= 0x100;
}
else
{
actor->posRot.pos.x = actor->pos4.x;
actor->posRot.pos.z = actor->pos4.z;
}
}
actor->posRot.pos.y = actor->unk_80;
if (actor->velocity.y <= 0.0f)
{
if (!(actor->bgCheckFlags & 0x1))
actor->bgCheckFlags |= 0x2;
else if ((arg3 & 0x8) && (actor->gravity < 0.0f))
actor->velocity.y = -4.0f;
else
actor->velocity.y = 0.0f;
actor->bgCheckFlags |= 0x1;
func_80043334(&globalCtx->colCtx, actor, actor->floorPolySource);
}
}
else
{
if ((actor->bgCheckFlags & 0x1) && (sp34 >= -11.0f))
func_80043334(&globalCtx->colCtx, actor, actor->floorPolySource);
return func_8002E234(actor, sp34, arg3);
}
return 1;
}
void func_8002E4B4(GlobalContext* globalCtx, Actor* actor, f32 arg2, f32 arg3, f32 arg4, s32 arg5)
{
f32 sp74;
s32 pad;
Vec3f sp64;
u32 sp60;
CollisionPoly* sp5C;
f32 sp58;
UNK_TYPE sp54;
f32 sp50;
Vec3f sp44;
sp74 = actor->posRot.pos.y - actor->pos4.y;
if ((actor->floorPolySource != 0x32) && (actor->bgCheckFlags & 1))
func_800433A4(&globalCtx->colCtx, actor->floorPolySource, actor);
if (arg5 & 1)
{
if ((!(arg5 & 0x80) && func_8003D52C(&globalCtx->colCtx, &sp64, &actor->posRot.pos,
&actor->pos4, arg3, &actor->wallPoly, &sp60, actor, arg2)) ||
((arg5 & 0x80) && func_8003D594(&globalCtx->colCtx, &sp64, &actor->posRot.pos,
&actor->pos4, arg3, &actor->wallPoly, &sp60, actor, arg2)))
{
sp5C = actor->wallPoly;
Math_Vec3f_Copy(&actor->posRot.pos, &sp64);
actor->unk_7E = atan2s(sp5C->norm.z, sp5C->norm.x);
actor->bgCheckFlags |= 8;
actor->wallPolySource = sp60;
}
else
actor->bgCheckFlags &= ~8;
}
sp64.x = actor->posRot.pos.x;
sp64.z = actor->posRot.pos.z;
if (arg5 & 2)
{
sp64.y = actor->pos4.y + 10.0f;
if (func_8003D7A0(&globalCtx->colCtx, &sp58, &sp64, (arg4 + sp74) - 10.0f, &D_8015BBA0, &D_8015BBA4, actor))
{
actor->bgCheckFlags |= 0x10;
actor->posRot.pos.y = (sp58 + sp74) - 10.0f;
}
else
actor->bgCheckFlags &= ~0x10;
}
if (arg5 & 4)
{
sp64.y = actor->pos4.y;
func_8002E2AC(globalCtx, actor, &sp64, arg5);
sp50 = actor->posRot.pos.y;
if (func_8004213C(globalCtx, &globalCtx->colCtx, actor->posRot.pos.x, actor->posRot.pos.z, &sp50, &sp54))
{
actor->unk_84 = sp50 - actor->posRot.pos.y;
if (actor->unk_84 < 0.0f)
actor->bgCheckFlags &= ~0x60;
else
{
if (!(actor->bgCheckFlags & 0x20))
{
actor->bgCheckFlags |= 0x40;
if (!(arg5 & 0x40))
{
sp44.x = actor->posRot.pos.x;
sp44.y = sp50;
sp44.z = actor->posRot.pos.z;
func_80029444(globalCtx, &sp44, 100, 500, 0);
func_80029444(globalCtx, &sp44, 100, 500, 4);
func_80029444(globalCtx, &sp44, 100, 500, 8);
}
}
actor->bgCheckFlags |= 0x20;
}
}
else
{
actor->bgCheckFlags &= ~0x60;
actor->unk_84 = -32000.0f;
}
}
}
s32 D_8015BBA8[16];
Gfx* func_8002E830(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext* gfxCtx, Gfx* gfx, Hilite** hilite)
{
Gfx* lookAt;
f32 correctedEyeX;
lookAt = Graph_Alloc(gfxCtx, 4 * sizeof(Gfx));
correctedEyeX = (eye->x == object->x) && (eye->z == object->z) ? eye->x + 0.001f : eye->x;
*hilite = Graph_Alloc(gfxCtx, sizeof(Hilite));
if (HREG(80) == 6)
osSyncPrintf("z_actor.c 3529 eye=[%f(%f) %f %f] object=[%f %f %f] light_direction=[%f %f %f]\n",
(f64)correctedEyeX, (f64)eye->x, (f64)eye->y, (f64)eye->z,
(f64)object->x, (f64)object->y, (f64) object->z,
(f64)lightDir->x, (f64)lightDir->y, (f64)lightDir->z);
func_800ABE74(correctedEyeX, eye->y, eye->z);
func_80103A70(&D_8015BBA8, lookAt, *hilite,
correctedEyeX, eye->y, eye->z,
object->x, object->y, object->z,
0.0f, 1.0f, 0.0f,
lightDir->x, lightDir->y, lightDir->z,
lightDir->x, lightDir->y, lightDir->z,
0x10, 0x10);
gSPLookAt(gfx++, lookAt);
gDPSetHilite1Tile(gfx++, 1, *hilite, 0x10, 0x10);
return gfx;
}
Hilite* func_8002EABC(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext* gfxCtx)
{
Hilite* hilite;
Gfx* gfxArr[5];
func_800C6AC4(gfxArr, gfxCtx, "../z_actor.c", 4306);
gfxCtx->polyOpa.p = func_8002E830(object, eye, lightDir, gfxCtx, gfxCtx->polyOpa.p, &hilite);
func_800C6B54(gfxArr, gfxCtx, "../z_actor.c", 4313);
return hilite;
}
Hilite* func_8002EB44(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext* gfxCtx)
{
Hilite* hilite;
Gfx* gfxArr[5];
func_800C6AC4(gfxArr, gfxCtx, "../z_actor.c", 4332);
gfxCtx->polyXlu.p = func_8002E830(object, eye, lightDir, gfxCtx, gfxCtx->polyXlu.p, &hilite);
func_800C6B54(gfxArr, gfxCtx, "../z_actor.c", 4339);
return hilite;
}
void func_8002EBCC(Actor* actor, GlobalContext* globalCtx, s32 flag)
{
Hilite* hilite;
Vec3f lightDir;
Gfx* displayListHead;
Gfx* displayList;
GraphicsContext* gfxCtx;
Gfx* gfxArr[4];
lightDir.x = globalCtx->unk_10A4E;
lightDir.y = globalCtx->unk_10A4F;
lightDir.z = globalCtx->unk_10A50;
if (HREG(80) == 6)
osSyncPrintf("z_actor.c 3637 game_play->view.eye=[%f(%f) %f %f]\n",
(f64)globalCtx->view.eye.x, (f64)globalCtx->view.eye.y, (f64)globalCtx->view.eye.z);
hilite = func_8002EABC(&actor->posRot.pos, &globalCtx->view.eye, &lightDir, globalCtx->state.gfxCtx);
if (flag != 0)
{
displayList = Graph_Alloc(globalCtx->state.gfxCtx, 2 * sizeof(Gfx));
displayListHead = displayList;
gfxCtx = globalCtx->state.gfxCtx;
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 4384);
gDPSetHilite1Tile(displayListHead++, 1, hilite, 0x10, 0x10);
gSPEndDisplayList(displayListHead);
gSPSegment(gfxCtx->polyOpa.p++, 0x07, displayList);
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 4394);
}
}
void func_8002ED80(Actor* actor, GlobalContext* globalCtx, s32 flag)
{
Hilite* hilite;
Vec3f lightDir;
Gfx* displayListHead;
Gfx* displayList;
GraphicsContext* gfxCtx;
Gfx* gfxArr[4];
lightDir.x = globalCtx->unk_10A4E;
lightDir.y = globalCtx->unk_10A4F;
lightDir.z = globalCtx->unk_10A50;
hilite = func_8002EB44(&actor->posRot.pos, &globalCtx->view.eye, &lightDir, globalCtx->state.gfxCtx);
if (flag != 0)
{
displayList = Graph_Alloc(globalCtx->state.gfxCtx, 2 * sizeof(Gfx));
displayListHead = displayList;
gfxCtx = globalCtx->state.gfxCtx;
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 4429);
gDPSetHilite1Tile(displayListHead++, 1, hilite, 0x10, 0x10);
gSPEndDisplayList(displayListHead);
gSPSegment(gfxCtx->polyXlu.p++, 0x07, displayList);
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 4439);
}
}
PosRot* func_8002EEE4(PosRot* arg0, Actor* actor)
{
*arg0 = actor->posRot2;
return arg0;
}
PosRot* func_8002EF14(PosRot* arg0, Actor* actor)
{
*arg0 = actor->posRot;
return arg0;
}
PosRot* func_8002EF44(PosRot* arg0, Actor* actor)
{
PosRot sp1C;
Math_Vec3f_Copy(&sp1C.pos, &actor->posRot.pos);
sp1C.rot = actor->shape.rot;
*arg0 = sp1C;
return arg0;
}
#ifdef NON_MATCHING
// single regalloc difference
f32 func_8002EFC0(Actor* actor, Player* player, s16 arg2)
{
s16 var;
s16 abs_var;
var = (s16)(actor->rotTowardsLinkY - 0x8000) - arg2;
abs_var = ABS(var);
if (player->unk_664 != NULL)
{
if ((abs_var > 0x4000) || (actor->flags & 0x8000000))
return FLT_MAX;
else
return actor->waterSurfaceDist - actor->waterSurfaceDist * 0.8f * ((0x4000 - abs_var) * 3.0517578125e-05f);
}
if (abs_var > 0x2AAA)
return FLT_MAX;
return actor->waterSurfaceDist;
}
#else
extern f32 func_8002EFC0(Actor* actor, Player* player, s16 arg2);
#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_8002EFC0.s")
#endif
typedef struct
{
f32 unk_0, unk_4;
} struct_80115FF8; // size = 0x8
struct_80115FF8 D_80115FF8[] =
{
{ 4900.0f, 0.5f },
{ 28900.0f, 0.6666667f },
{ 78400.0f, 0.05f },
{ 122500.0f, 0.6666667f },
{ 490000.0f, 0.6666667f },
{ 1000000.0f, 0.6666667f },
{ 10000.0f, 0.94905096f },
{ 19600.0f, 0.85714287f },
{ 57600.0f, 0.41666666f },
{ 78400.0f, 0.001f },
};
u32 func_8002F090(Actor* actor, f32 arg1)
{
return arg1 < D_80115FF8[actor->unk_1F].unk_0;
}
s32 func_8002F0C8(Actor* actor, Player* player, s32 flag)
{
s16 var;
s16 abs_var;
f32 dist;
if ((actor->update == NULL) || !(actor->flags & 1))
return 1;
if (!flag)
{
var = (s16)(actor->rotTowardsLinkY - 0x8000) - player->actor.shape.rot.y;
abs_var = ABS(var);
if ((player->unk_664 == NULL) && (abs_var > 0x2AAA))
dist = FLT_MAX;
else
dist = actor->waterSurfaceDist;
return !func_8002F090(actor, D_80115FF8[actor->unk_1F].unk_4 * dist);
}
return 0;
}
u32 func_8002F194(Actor* actor, GlobalContext* globalCtx)
{
if (actor->flags & 0x100)
{
actor->flags &= ~0x100;
return 1;
}
return 0;
}
s32 func_8002F1C4(Actor* actor, GlobalContext* globalCtx, f32 arg2, f32 arg3, u32 arg4)
{
Player* player = PLAYER;
// This is convoluted but it seems like it must be a single if statement to match
if ((player->actor.flags & 0x100) ||
((arg4 != 0) && func_8008E988(globalCtx)) ||
((actor->unk_10C == 0) &&
((arg3 < fabsf(actor->yDistanceFromLink)) ||
(player->unk_698 < actor->xzDistanceFromLink) ||
(arg2 < actor->xzDistanceFromLink))))
return 0;
player->unk_694 = actor;
player->unk_698 = actor->xzDistanceFromLink;
player->exchangeItemId = arg4;
return 1;
}
s32 func_8002F298(Actor* actor, GlobalContext* globalCtx, f32 arg2, u32 arg3)
{
return func_8002F1C4(actor, globalCtx, arg2, arg2, arg3);
}
s32 func_8002F2CC(Actor* actor, GlobalContext* globalCtx, f32 arg2)
{
return func_8002F298(actor, globalCtx, arg2, 0);
}
s32 func_8002F2F4(Actor* actor, GlobalContext* globalCtx)
{
f32 var1 = 50.0f + actor->sub_98.unk_10;
return func_8002F2CC(actor, globalCtx, var1);
}
u32 func_8002F334(Actor* actor, GlobalContext* globalCtx)
{
if (func_8010BDBC(&globalCtx->msgCtx) == 2)
return 1;
else
return 0;
}
s8 func_8002F368(GlobalContext* globalCtx)
{
Player* player = PLAYER;
return player->exchangeItemId;
}
void func_8002F374(GlobalContext* globalCtx, Actor* actor, s16* arg2, s16* arg3)
{
Vec3f sp1C;
f32 sp18;
func_8002BE04(globalCtx, &actor->posRot2.pos, &sp1C, &sp18);
*arg2 = sp1C.x * sp18 * 160.0f + 160.0f;
*arg3 = sp1C.y * sp18 * -120.0f + 120.0f;
}
u32 func_8002F410(Actor* actor, GlobalContext* globalCtx)
{
if (actor->attachedA != NULL)
return 1;
else
return 0;
}
s32 func_8002F434(Actor* actor, GlobalContext* globalCtx, s32 getItemId, f32 xzRange, f32 yRange)
{
Player* player = PLAYER;
s16 var;
s32 abs_var;
if (!(player->stateFlags1 & 0x3C7080) && func_8008F29C(player) < 0)
{
if ((((player->heldActor != NULL) || (actor == player->unk_694)) && (getItemId > 0) && (getItemId < 0x7E)) ||
(!(player->stateFlags1 & 0x20000800)))
{
if ((actor->xzDistanceFromLink < xzRange) && (fabsf(actor->yDistanceFromLink) < yRange))
{
var = actor->rotTowardsLinkY - player->actor.shape.rot.y;
abs_var = ABS(var);
if ((getItemId != 0) || (player->getItemDirection < abs_var))
{
player->getItemId = getItemId;
player->interactRangeActor = actor;
player->getItemDirection = abs_var;
return 1;
}
}
}
}
return 0;
}
void func_8002F554(Actor* actor, GlobalContext* globalCtx, s32 getItemId)
{
func_8002F434(actor, globalCtx, getItemId, 50.0f, 10.0f);
}
void func_8002F580(Actor* actor, GlobalContext* globalCtx)
{
func_8002F554(actor, globalCtx, 0);
}
u32 func_8002F5A0(Actor* actor, GlobalContext* globalCtx)
{
if (actor->attachedA == NULL)
return 1;
else
return 0;
}
void func_8002F5C4(Actor* actorA, Actor* actorB, GlobalContext* globalCtx)
{
Actor* actorAttachedA = actorA->attachedA;
if (actorAttachedA->id == ACTOR_PLAYER)
{
Player* player = (Player*)actorAttachedA;
player->heldActor = actorB;
player->interactRangeActor = actorB;
}
actorAttachedA->attachedB = actorB;
actorB->attachedA = actorAttachedA;
actorA->attachedA = NULL;
}
void func_8002F5F0(Actor* actor, GlobalContext* globalCtx)
{
Player* player = PLAYER;
if (actor->waterSurfaceDist < player->unk_6A4)
player->unk_6A4 = actor->waterSurfaceDist;
}
u32 func_8002F618(GlobalContext* globalCtx, Actor* actor)
{
if (actor->attachedB != NULL)
return 1;
else
return 0;
}
u32 func_8002F63C(GlobalContext* globalCtx, Actor* actor, s32 arg2)
{
Player* player = PLAYER;
if (!(player->stateFlags1 & 0x003C7880))
{
player->rideActor = actor;
player->unk_43C = arg2;
return 1;
}
return 0;
}
u32 func_8002F674(GlobalContext* globalCtx, Actor* actor)
{
if (actor->attachedB == NULL)
return 1;
else
return 0;
}
void func_8002F698(GlobalContext* globalCtx, u32 arg1, f32 arg2, s16 arg3, f32 arg4, u32 arg5, u32 arg6)
{
Player* player = PLAYER;
player->unk_8A0 = arg6;
player->unk_8A1 = arg5;
player->unk_8A2 = arg3;
player->unk_8A4 = arg2;
player->unk_8A8 = arg4;
}
void func_8002F6D4(GlobalContext* globalCtx, u32 arg1, f32 arg2, s16 arg3, f32 arg4, u32 arg5)
{
func_8002F698(globalCtx, arg1, arg2, arg3, arg4, 2, arg5);
}
void func_8002F71C(GlobalContext* globalCtx, u32 arg1, f32 arg2, s16 arg3, f32 arg4)
{
func_8002F6D4(globalCtx, arg1, arg2, arg3, arg4, 0);
}
void func_8002F758(GlobalContext* globalCtx, u32 arg1, f32 arg2, s16 arg3, f32 arg4, u32 arg5)
{
func_8002F698(globalCtx, arg1, arg2, arg3, arg4, 1, arg5);
}
void func_8002F7A0(GlobalContext* globalCtx, u32 arg1, f32 arg2, s16 arg3, f32 arg4)
{
func_8002F758(globalCtx, arg1, arg2, arg3, arg4, 0);
}
void func_8002F7DC(Actor* actor, u16 sfxId)
{
Audio_PlaySoundGeneral(sfxId, &actor->unk_E4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
}
void Audio_PlayActorSound2(Actor* actor, u16 sfxId)
{
func_80078914(&actor->unk_E4, sfxId);
}
void func_8002F850(GlobalContext* globalCtx, Actor* actor)
{
s32 sfxId;
if (actor->bgCheckFlags & 0x20)
{
if (actor->unk_84 < 20.0f)
sfxId = NA_SE_PL_WALK_WATER0;
else
sfxId = NA_SE_PL_WALK_WATER1;
}
else
sfxId = func_80041F34(&globalCtx->colCtx, actor->floorPoly, actor->floorPolySource, actor);
func_80078914(&actor->unk_E4, NA_SE_EV_BOMB_BOUND);
func_80078914(&actor->unk_E4, sfxId + 0x800);
}
void func_8002F8F0(Actor* actor, u16 sfxId)
{
actor->soundEffect = sfxId;
actor->flags |= 0x80000;
actor->flags &= ~0x10300000;
}
void func_8002F91C(Actor* actor, u16 sfxId)
{
actor->soundEffect = sfxId;
actor->flags |= 0x100000;
actor->flags &= ~0x10280000;
}
void func_8002F948(Actor* actor, u16 sfxId)
{
actor->soundEffect = sfxId;
actor->flags |= 0x200000;
actor->flags &= ~0x10180000;
}
void func_8002F974(Actor* actor, u16 sfxId)
{
actor->flags &= ~0x10380000;
actor->soundEffect = sfxId;
}
void func_8002F994(Actor* actor, s32 sfxId)
{
actor->flags |= 0x10000000;
actor->flags &= ~0x00380000;
if (sfxId < NA_SE_PL_LAND_GRASS)
actor->soundEffect = NA_SE_PL_WALK_DIRT;
else if (sfxId < NA_SE_PL_DIVE_BUBBLE)
actor->soundEffect = NA_SE_PL_WALK_CONCRETE;
else
actor->soundEffect = NA_SE_PL_WALK_SAND;
}
s32 func_8002F9EC(GlobalContext* globalCtx, Actor* actor, UNK_TYPE arg2, UNK_TYPE arg3, UNK_TYPE arg4)
{
if (func_80041D4C(&globalCtx->colCtx, arg2, arg3) == 8)
{
globalCtx->unk_11D30[0] = 1;
func_8005DFAC(globalCtx, 0, arg4);
Audio_PlayActorSound2(actor, NA_SE_IT_WALL_HIT_BUYO);
return 1;
}
return 0;
}
// Local data used for Farore's Wind light (stored in BSS, possibly a struct?)
LightInfoPositional D_8015BC00;
z_Light* D_8015BC10;
s32 D_8015BC14;
f32 D_8015BC18;
void func_8002FA60(GlobalContext* globalCtx)
{
Vec3f lightPos;
if (gSaveContext.fw.set)
{
gSaveContext.respawn[RESPAWN_MODE_TOP].data = 0x28;
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.x = gSaveContext.fw.pos_x;
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y = gSaveContext.fw.pos_y;
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z = gSaveContext.fw.pos_z;
gSaveContext.respawn[RESPAWN_MODE_TOP].yaw = gSaveContext.fw.yaw;
gSaveContext.respawn[RESPAWN_MODE_TOP].player_params = gSaveContext.fw.player_params;
gSaveContext.respawn[RESPAWN_MODE_TOP].entrance_index = gSaveContext.fw.entrance_index;
gSaveContext.respawn[RESPAWN_MODE_TOP].room_index = gSaveContext.fw.room_index;
gSaveContext.respawn[RESPAWN_MODE_TOP].temp_swch_flags = gSaveContext.fw.temp_swch_flags;
gSaveContext.respawn[RESPAWN_MODE_TOP].temp_collect_flags = gSaveContext.fw.temp_collect_flags;
}
else
{
gSaveContext.respawn[RESPAWN_MODE_TOP].data = 0;
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.x = 0.0f;
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y = 0.0f;
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z = 0.0f;
}
lightPos.x = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.x;
lightPos.y = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y + 80.0f;
lightPos.z = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z;
Lights_InitType0PositionalLight(&D_8015BC00, lightPos.x, lightPos.y, lightPos.z, 0xFF, 0xFF, 0xFF, -1);
D_8015BC10 = Lights_Insert(globalCtx, &globalCtx->lightCtx, (LightInfo*)&D_8015BC00);
D_8015BC14 = 0;
D_8015BC18 = 0.0f;
}
Vec3f D_80116048 = { 0.0f, -0.05f, 0.0f };
Vec3f D_80116054 = { 0.0f, -0.025f, 0.0f };
Color_RGB8 D_80116060 = { 0xFF, 0xFF, 0xFF };
Color_RGB8 D_80116064 = { 0x64, 0xC8, 0x00 };
#ifdef NON_MATCHING
// this function still needs a lot of work
void func_8002FBAC(GlobalContext* globalCtx)
{
GraphicsContext* gfxCtx;
Gfx* gfxArr[6];
Vec3f lightPos;
f32 spD8;
f32 spD4;
s32 spD0;
f32 spC0;
Vec3f spB4;
Vec3f spA4;
f32 sp9C;
Vec3f sp7C;
Vec3f sp70;
f32 temp_f12;
f32 temp_f14;
f32 temp_f2;
f32 temp_ret;
s32 temp_a3;
f32 phi_f14;
f32 phi_f10;
f32 phi_f6;
gfxCtx = globalCtx->state.gfxCtx;
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 5308);
if (gSaveContext.respawn[RESPAWN_MODE_TOP].data != 0)
{
if (LINK_IS_ADULT)
spD8 = 80.0f;
else
spD8 = 60.0f;
spD0 = 0xFF;
spD4 = 1.0f;
temp_a3 = gSaveContext.respawn[RESPAWN_MODE_TOP].data - 0x28;
if (temp_a3 < 0)
{
gSaveContext.respawn[RESPAWN_MODE_TOP].data++;
spD4 = ABS(gSaveContext.respawn[RESPAWN_MODE_TOP].data) * 0.025f;
D_8015BC14 = 60;
D_8015BC18 = 1.0f;
}
else if (D_8015BC14 != 0)
{
D_8015BC14--;
}
else if (D_8015BC18 > 0.0f)
{
spC0 = D_8015BC18;
temp_ret = Math_Vec3f_DistXYZAndStoreDiff(&gSaveContext.respawn[RESPAWN_MODE_DOWN].pos,
&gSaveContext.respawn[RESPAWN_MODE_TOP].pos,
&spB4);
if (temp_ret < 20.0f)
{
D_8015BC18 = 0.0f;
Math_Vec3f_Copy(&gSaveContext.respawn[RESPAWN_MODE_TOP].pos, &gSaveContext.respawn[RESPAWN_MODE_DOWN].pos);
}
else
{
sp9C = (1.0f / D_8015BC18) * temp_ret;
phi_f14 = 20.0f / sp9C;
phi_f14 = (phi_f14 < 0.05f) ? 0.05f : phi_f14;
Math_ApproxF(&D_8015BC18, 0.0f, phi_f14);
temp_f2 = ((D_8015BC18 / spC0) * temp_ret) / temp_ret;
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.x = gSaveContext.respawn[RESPAWN_MODE_DOWN].pos.x + (spB4.x * temp_f2);
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y = gSaveContext.respawn[RESPAWN_MODE_DOWN].pos.y + (spB4.y * temp_f2);
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z = gSaveContext.respawn[RESPAWN_MODE_DOWN].pos.z + (spB4.z * temp_f2);
temp_f12 = sp9C * 0.5f;
temp_f14 = temp_ret - temp_f12;
spD8 += sqrtf((temp_f12 * temp_f12) - (temp_f14 * temp_f14)) * 0.2f;
osSyncPrintf("-------- DISPLAY Y=%f\n", (f64)spD8);
}
spA4.x = Math_Rand_CenteredFloat(6.0f) + gSaveContext.respawn[RESPAWN_MODE_TOP].pos.x;
spA4.y = Math_Rand_ZeroOne() * 6.0f + gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y + 80.0f;
spA4.z = Math_Rand_CenteredFloat(6.0f) + gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z;
func_80028BB0(globalCtx, &spA4, &D_80116048, &D_80116054, &D_80116060, &D_80116064, 1000, 0x10);
if (D_8015BC18 == 0.0f)
{
gSaveContext.respawn[RESPAWN_MODE_TOP] = gSaveContext.respawn[RESPAWN_MODE_DOWN];
gSaveContext.respawn[RESPAWN_MODE_TOP].player_params = 0x06FF;
gSaveContext.respawn[RESPAWN_MODE_TOP].data = 0x28;
}
gSaveContext.respawn[RESPAWN_MODE_TOP].pos = gSaveContext.respawn[RESPAWN_MODE_TOP].pos;
}
else if (temp_a3 > 0)
{
temp_f12 = temp_a3 * 0.1f;
if (temp_f12 < 1.0f)
{
sp7C.x = globalCtx->view.eye.x;
sp7C.y = globalCtx->view.eye.y - spD8;
sp7C.z = globalCtx->view.eye.z;
temp_ret = Math_Vec3f_DistXYZAndStoreDiff(&sp7C, &gSaveContext.respawn[RESPAWN_MODE_TOP].pos, &sp70);
temp_f2 = (((1.0f - temp_f12) / (1.0f - ((f32)(temp_a3 - 1) * 0.1f))) * temp_ret) / temp_ret;
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.x = sp70.x * temp_f2 + sp7C.x;
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y = sp70.y * temp_f2 + sp7C.y;
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z = sp70.z * temp_f2 + sp7C.z;
}
// somehow this shouldn't be optimized out
gSaveContext.respawn[RESPAWN_MODE_TOP].pos = gSaveContext.respawn[RESPAWN_MODE_TOP].pos;
spD0 = 0xFF - (((temp_a3 * 0x10) - temp_a3) * 2);
if (spD0 < 0)
{
gSaveContext.fw.set = 0;
gSaveContext.respawn[RESPAWN_MODE_TOP].data = 0;
spD0 = 0;
}
else
{
gSaveContext.respawn[RESPAWN_MODE_TOP].data++;
}
spD4 = temp_a3 * 0.200000000000000011102230246252 + 1.0f;
}
if ((globalCtx->csCtx.state == 0) &&
(gSaveContext.respawn[RESPAWN_MODE_TOP].entrance_index == gSaveContext.entrance_index) &&
(globalCtx->roomCtx.curRoom.num == gSaveContext.respawn[RESPAWN_MODE_TOP].room_index))
{
gfxCtx->polyXlu.p = func_80093774(gfxCtx->polyXlu.p, 0x19);
Matrix_Translate(gSaveContext.respawn[RESPAWN_MODE_TOP].pos.x,
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y + spD8,
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z,
MTXMODE_NEW);
Matrix_Scale(0.025f * spD4, 0.025f * spD4, 0.025f * spD4, MTXMODE_APPLY);
Matrix_Mult(&globalCtx->mf_11D60, MTXMODE_APPLY);
Matrix_Push();
gDPPipeSync(gfxCtx->polyXlu.p++);
gDPSetPrimColor(gfxCtx->polyXlu.p++, 0x80, 0x80, 0xFF, 0xFF, 0xC8, spD0);
gDPSetEnvColor(gfxCtx->polyXlu.p++, 0x64, 0xC8, 0x00, 0xFF);
phi_f10 = (globalCtx->gameplayFrames * 1500) & 0xFFFF;
Matrix_RotateZ((phi_f10 * M_PI) / 32768.0f, MTXMODE_APPLY);
gSPMatrix(gfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_actor.c", 5458), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(gfxCtx->polyXlu.p++, &D_04010130);
Matrix_Pull();
phi_f6 = ~((globalCtx->gameplayFrames * 1200) & 0xFFFF);
Matrix_RotateZ((phi_f6 * M_PI) / 32768.0f, MTXMODE_APPLY);
gSPMatrix(gfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_actor.c", 5463), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(gfxCtx->polyXlu.p++, &D_04010130);
}
lightPos.x = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.x;
lightPos.y = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y + spD8;
lightPos.z = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z;
Lights_InitType0PositionalLight(&D_8015BC00, lightPos.x, lightPos.y, lightPos.z, 0xFF, 0xFF, 0xFF, 500.0f * spD4);
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 5474);
}
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_8002FBAC.s")
#endif
void func_80030488(GlobalContext* globalCtx)
{
Lights_Remove(globalCtx, &globalCtx->lightCtx, D_8015BC10);
}
void func_800304B0(GlobalContext* globalCtx)
{
if (globalCtx->actorCtx.unk_03 != 0)
{
globalCtx->actorCtx.unk_03 = 0;
func_800876C8(globalCtx);
}
}
void func_800304DC(GlobalContext* globalCtx, ActorContext* actorCtx, ActorEntry* actorEntry)
{
ActorOverlay* overlayEntry;
SaveSceneFlags* saveSceneFlags;
s32 i;
saveSceneFlags = &gSaveContext.scene_flags[globalCtx->sceneNum];
bzero(actorCtx, sizeof(*actorCtx));
ActorOverlayTable_Init();
Matrix_MtxFCopy(&globalCtx->mf_11DA0, &gMtxFClear);
Matrix_MtxFCopy(&globalCtx->mf_11D60, &gMtxFClear);
overlayEntry = &gActorOverlayTable[0];
for (i = 0; i < ARRAY_COUNT(gActorOverlayTable); i++)
{
overlayEntry->loadedRamAddr = NULL;
overlayEntry->nbLoaded = 0;
overlayEntry++;
}
actorCtx->flags.chest = saveSceneFlags->chest;
actorCtx->flags.swch = saveSceneFlags->swch;
actorCtx->flags.clear = saveSceneFlags->clear;
actorCtx->flags.collect = saveSceneFlags->collect;
func_8002CDE4(globalCtx, &actorCtx->titleCtx);
actorCtx->absoluteSpace = NULL;
Actor_SpawnEntry(actorCtx, actorEntry, globalCtx);
func_8002C0C0(&actorCtx->targetCtx, actorCtx->actorList[ACTORTYPE_PLAYER].first, globalCtx);
func_8002FA60(globalCtx);
}
u32 D_80116068[] =
{
0x100000C0,
0x100000C0,
0x00000000,
0x100004C0,
0x00000080,
0x300000C0,
0x10000080,
0x00000000,
0x300000C0,
0x100004C0,
0x00000000,
0x100000C0,
};
void Actor_UpdateAll(GlobalContext* globalCtx, ActorContext* actorCtx)
{
Actor* refActor;
Actor* actor;
Player* player;
u32* sp80;
u32 unkFlag;
u32 unkCondition;
Actor* sp74;
ActorEntry* actorEntry;
s32 i;
player = PLAYER;
if (0)
{
// This assert is optimized out but it exists due to its presence in rodata
if (gMaxProfile != ACTOR_DLF_MAX)
__assert("MaxProfile == ACTOR_DLF_MAX", "../z_actor.c", UNK_LINE);
}
sp74 = NULL;
unkFlag = 0;
if (globalCtx->nbSetupActors != 0)
{
actorEntry = &globalCtx->setupActorList[0];
for (i = 0; i < globalCtx->nbSetupActors; i++)
Actor_SpawnEntry(&globalCtx->actorCtx, actorEntry++, globalCtx);
globalCtx->nbSetupActors = 0;
}
if (actorCtx->unk_02 != 0)
actorCtx->unk_02--;
if (KREG(0) == -100)
{
refActor = &PLAYER->actor;
KREG(0) = 0;
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG,
refActor->posRot.pos.x, refActor->posRot.pos.y + 100.0f, refActor->posRot.pos.z,
0, 0, 0, 1);
}
sp80 = &D_80116068[0];
if (player->stateFlags2 & 0x8000000)
unkFlag = 0x2000000;
if ((player->stateFlags1 & 0x40) && ((player->actor.textId & 0xFF00) != 0x600))
sp74 = player->unk_694;
for (i = 0; i < ARRAY_COUNT(actorCtx->actorList); i++, sp80++)
{
unkCondition = (*sp80 & player->stateFlags1);
actor = actorCtx->actorList[i].first;
while (actor != NULL)
{
if (actor->posRot.pos.y < -25000.0f)
actor->posRot.pos.y = -25000.0f;
actor->soundEffect = 0;
if (actor->init != NULL)
{
if (Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex))
{
Actor_SetObjectDependency(globalCtx, actor);
actor->init(actor, globalCtx);
actor->init = NULL;
}
actor = actor->next;
}
else if (!Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex))
{
Actor_Kill(actor);
actor = actor->next;
}
else if ((unkFlag && !(actor->flags & unkFlag)) ||
(!unkFlag && unkCondition &&
(sp74 != actor) && (actor != player->unk_68C) &&
(actor != player->heldActor) && (&player->actor != actor->attachedA)))
{
func_80061E8C(&actor->sub_98);
actor = actor->next;
}
else if (actor->update == NULL)
{
if (!actor->activelyDrawn)
actor = Actor_Delete(&globalCtx->actorCtx, actor, globalCtx);
else
{
Actor_Destroy(actor, globalCtx);
actor = actor->next;
}
}
else
{
Math_Vec3f_Copy(&actor->pos4, &actor->posRot.pos);
actor->xzDistanceFromLink = func_8002DB8C(actor, &player->actor);
actor->yDistanceFromLink = Actor_HeightDiff(actor, &player->actor);
actor->waterSurfaceDist = SQ(actor->xzDistanceFromLink) + SQ(actor->yDistanceFromLink);
actor->rotTowardsLinkY = func_8002DA78(actor, &player->actor);
actor->flags &= ~0x1000000;
if ((DECR(actor->freeze) == 0) && (actor->flags & 0x50))
{
if (actor == player->unk_664)
actor->unk_10C = 1;
else
actor->unk_10C = 0;
if ((actor->unk_10D != 0) && (player->unk_664 == NULL))
actor->unk_10D = 0;
Actor_SetObjectDependency(globalCtx, actor);
if (actor->unk_114 != 0)
actor->unk_114--;
actor->update(actor, globalCtx);
func_8003F8EC(globalCtx, &globalCtx->colCtx.dyna, actor);
}
func_80061E8C(&actor->sub_98);
actor = actor->next;
}
}
if (i == ACTORTYPE_BG)
func_8003F984(globalCtx, &globalCtx->colCtx.dyna);
}
actor = player->unk_664;
if ((actor != NULL) && (actor->update == NULL))
{
actor = NULL;
func_8008EDF0(player);
}
if ((actor == NULL) || (player->unk_66C < 5))
{
actor = NULL;
if (actorCtx->targetCtx.unk_4B != 0)
{
actorCtx->targetCtx.unk_4B = 0;
func_80078884(NA_SE_SY_LOCK_OFF);
}
}
func_8002C7BC(&actorCtx->targetCtx, player, actor, globalCtx);
TitleCard_Update(globalCtx, &actorCtx->titleCtx);
func_8003FB64(globalCtx, &globalCtx->colCtx.dyna);
}
void Actor_FaultPrint(Actor* actor, char* command)
{
ActorOverlay* overlayEntry;
char* name;
if ((actor == NULL) || (actor->overlayEntry == NULL))
{
FaultDrawer_SetCursor(48, 24);
FaultDrawer_Printf("ACTOR NAME is NULL");
}
overlayEntry = actor->overlayEntry;
name = overlayEntry->name != NULL ? overlayEntry->name : "";
// Translates to: "ACTOR NAME(%08x:%s)"
osSyncPrintf("アクターの名前(%08x:%s)\n", actor, name);
if (command != NULL)
// Translates to: "COMMAND:%s"
osSyncPrintf("コメント:%s\n", command);
FaultDrawer_SetCursor(48, 24);
FaultDrawer_Printf("ACTOR NAME %08x:%s", actor, name);
}
void Actor_Draw(GlobalContext* globalCtx, Actor* actor)
{
FaultClient faultClient;
LightMapper* lightMapper;
GraphicsContext* gfxCtx;
Camera* camera;
Gfx* gfxArr[3];
Fault_AddClient(&faultClient, Actor_FaultPrint, actor, "Actor_draw");
gfxCtx = globalCtx->state.gfxCtx;
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 6035);
lightMapper = Lights_CreateMapper(&globalCtx->lightCtx, globalCtx->state.gfxCtx);
func_8007A474(lightMapper, globalCtx->lightCtx.lightsHead, (actor->flags & 0x400000) ? NULL : &actor->posRot.pos);
func_80079EFC(lightMapper, globalCtx->state.gfxCtx);
if (actor->flags & 0x1000)
{
camera = &globalCtx->cameraCtx.activeCameras[0];
func_800D1694(actor->posRot.pos.x + camera->unk_80.x,
actor->posRot.pos.y + (f32)((actor->shape.unk_08 * actor->scale.y) + camera->unk_80.y),
actor->posRot.pos.z + camera->unk_80.z,
&actor->shape.rot);
}
else
{
func_800D1694(actor->posRot.pos.x,
actor->posRot.pos.y + (actor->shape.unk_08 * actor->scale.y),
actor->posRot.pos.z,
&actor->shape.rot);
}
Matrix_Scale(actor->scale.x, actor->scale.y, actor->scale.z, MTXMODE_APPLY);
Actor_SetObjectDependency(globalCtx, actor);
gSPSegment(gfxCtx->polyOpa.p++, 0x06, globalCtx->objectCtx.status[actor->objBankIndex].segment);
gSPSegment(gfxCtx->polyXlu.p++, 0x06, globalCtx->objectCtx.status[actor->objBankIndex].segment);
if (actor->unk_114 != 0)
{
// Must be inline data to match
Color_RGBA8 sp2C = { 0x00, 0x00, 0x00, 0xFF };
if (actor->unk_112 & 0x8000)
sp2C.r = sp2C.g = sp2C.b = ((actor->unk_112 & 0x1F00) >> 5) | 7;
else if (actor->unk_112 & 0x4000)
sp2C.r = ((actor->unk_112 & 0x1F00) >> 5) | 7;
else
sp2C.b = ((actor->unk_112 & 0x1F00) >> 5) | 7;
if (actor->unk_112 & 0x2000)
func_80026860(globalCtx, &sp2C, actor->unk_114, actor->unk_112 & 0xFF);
else
func_80026400(globalCtx, &sp2C, actor->unk_114, actor->unk_112 & 0xFF);
}
actor->draw(actor, globalCtx);
if (actor->unk_114 != 0)
{
if (actor->unk_112 & 0x2000)
func_80026A6C(globalCtx);
else
func_80026608(globalCtx);
}
if (actor->shape.shadowDrawFunc != NULL)
actor->shape.shadowDrawFunc(actor, lightMapper, globalCtx);
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 6119);
Fault_RemoveClient(&faultClient);
}
void func_80030ED8(Actor* actor)
{
if (actor->flags & 0x80000)
Audio_PlaySoundGeneral(actor->soundEffect, &actor->unk_E4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
else if (actor->flags & 0x100000)
func_80078884(actor->soundEffect);
else if (actor->flags & 0x200000)
func_800788CC(actor->soundEffect);
else if (actor->flags & 0x10000000)
func_800F4C58(&D_801333D4, 0x2021, (s8)(actor->soundEffect - 1));
else
func_80078914(&actor->unk_E4, actor->soundEffect);
}
void func_80030FA8(GraphicsContext* gfxCtx)
{
Gfx* gfxArr[5];
func_800C6AC4(gfxArr, gfxCtx, "../z_actor.c", 6161);
gDPLoadTextureBlock(gfxCtx->polyXlu.p++,
&D_0401E370,
G_IM_FMT_I,
G_IM_SIZ_8b,
64, 64,
0,
G_TX_MIRROR | G_TX_CLAMP, G_TX_MIRROR | G_TX_CLAMP,
6, 6,
G_TX_NOLOD, G_TX_NOLOD);
gDPSetTileSize(gfxCtx->polyXlu.p++, G_TX_RENDERTILE, 384, 224, 892, 732);
gSPTextureRectangle(gfxCtx->polyXlu.p++, 0, 0, 1280, 960, G_TX_RENDERTILE, 2240, 1600, 576, 597);
gDPPipeSync(gfxCtx->polyXlu.p++);
func_800C6B54(gfxArr, gfxCtx, "../z_actor.c", 6183);
}
void func_8003115C(GlobalContext* globalCtx, s32 nbInvisibleActors, Actor** invisibleActors)
{
Actor** invisibleActor;
GraphicsContext* gfxCtx;
s32 i;
Gfx* gfxArr[5];
gfxCtx = globalCtx->state.gfxCtx;
func_800C6AC4(gfxArr, gfxCtx, "../z_actor.c", 6197);
// Translates to: "MAGIC LENS START"
gDma1p(gfxCtx->polyOpa.p++, G_NOOP, "魔法のメガネ START", 0, 2);
gDPPipeSync(gfxCtx->polyXlu.p++);
if (globalCtx->roomCtx.curRoom.showInvisActors == 0)
{
gDPSetOtherMode(gfxCtx->polyXlu.p++,
G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP |
G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_THRESHOLD | G_ZS_PRIM | Z_UPD | G_RM_CLD_SURF | G_RM_CLD_SURF2);
gDPSetCombineMode(gfxCtx->polyXlu.p++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
gDPSetPrimColor(gfxCtx->polyXlu.p++, 0, 0, 0xFF, 0x00, 0x00, 0xFF);
}
else
{
gDPSetOtherMode(gfxCtx->polyXlu.p++,
G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP |
G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_THRESHOLD | G_ZS_PRIM | Z_UPD |
IM_RD | CVG_DST_SAVE | ZMODE_OPA | FORCE_BL |
GBL_c1(G_BL_CLR_BL, G_BL_0, G_BL_CLR_MEM, G_BL_1MA) |
GBL_c2(G_BL_CLR_BL, G_BL_0, G_BL_CLR_MEM, G_BL_1MA));
gDPSetCombineLERP(gfxCtx->polyXlu.p++,
PRIMITIVE, TEXEL0, PRIM_LOD_FRAC, 0, PRIMITIVE, TEXEL0, PRIM_LOD_FRAC, 0,
PRIMITIVE, TEXEL0, PRIM_LOD_FRAC, 0, PRIMITIVE, TEXEL0, PRIM_LOD_FRAC, 0);
gDPSetPrimColor(gfxCtx->polyXlu.p++, 0, 0xFF, 0x4A, 0x4A, 0x4A, 0x4A);
}
gDPSetPrimDepth(gfxCtx->polyXlu.p++, 0, 0);
func_80030FA8(gfxCtx);
// Translates to: "MAGIC LENS INVISIBLE ACTOR DISPLAY START"
gDma1p(gfxCtx->polyOpa.p++, G_NOOP, "魔法のメガネ 見えないc表示 START", nbInvisibleActors, 2);
invisibleActor = &invisibleActors[0];
for (i = 0; i < nbInvisibleActors; i++)
{
// Translates to: "MAGIC LENS INVISIBLE ACTOR DISPLAY"
gDma1p(gfxCtx->polyOpa.p++, G_NOOP, "魔法のメガネ 見えないc表示", i, 2);
Actor_Draw(globalCtx, *(invisibleActor++));
}
// Translates to: "MAGIC LENS INVISIBLE ACTOR DISPLAY END"
gDma1p(gfxCtx->polyOpa.p++, G_NOOP, "魔法のメガネ 見えないc表示 END", nbInvisibleActors, 2);
if (globalCtx->roomCtx.curRoom.showInvisActors != 0)
{
// Translates to: "BLUE SPECTACLES (EXTERIOR)"
gDma1p(gfxCtx->polyOpa.p++, G_NOOP, "青い眼鏡(外側)", 0, 2);
gDPPipeSync(gfxCtx->polyXlu.p++);
gDPSetOtherMode(gfxCtx->polyXlu.p++,
G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP |
G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_THRESHOLD | G_ZS_PRIM | G_RM_CLD_SURF | G_RM_CLD_SURF2);
gDPSetCombineMode(gfxCtx->polyXlu.p++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
gDPSetPrimColor(gfxCtx->polyXlu.p++, 0, 0, 0xFF, 0x00, 0x00, 0xFF);
func_80030FA8(gfxCtx);
// Translates to: "BLUE SPECTACLES (EXTERIOR)"
gDma1p(gfxCtx->polyOpa.p++, G_NOOP, "青い眼鏡(外側)", 1, 2);
}
// Translates to: "MAGIC LENS END"
gDma1p(gfxCtx->polyOpa.p++, G_NOOP, "魔法のメガネ END", 0, 2);
func_800C6B54(gfxArr, gfxCtx, "../z_actor.c", 6284);
}
s32 func_800314B0(GlobalContext* globalCtx, Actor* actor)
{
return func_800314D4(globalCtx, actor, &actor->unk_E4, actor->unk_F0);
}
s32 func_800314D4(GlobalContext* globalCtx, Actor* actor, Vec3f* arg2, f32 arg3)
{
f32 var;
if ((arg2->z > -actor->unk_F8) && (arg2->z < (actor->unk_F4 + actor->unk_F8)))
{
var = (arg3 < 1.0f) ? 1.0f : 1.0f / arg3;
if ((((fabsf(arg2->x) - actor->unk_F8) * var) < 1.0f) &&
(((arg2->y + actor->unk_FC) * var) > -1.0f) &&
(((arg2->y - actor->unk_F8) * var) < 1.0f))
return 1;
}
return 0;
}
void func_800315AC(GlobalContext* globalCtx, ActorContext* actorCtx)
{
s32 invisibleActorCounter;
Actor* invisibleActors[INVISIBLE_ACTOR_MAX];
ActorListEntry* actorListEntry;
GraphicsContext* gfxCtx;
s32 i;
Gfx* gfxArr[5];
Actor* actor;
ActorOverlay* overlayEntry;
char* actorName;
gfxCtx = globalCtx->state.gfxCtx;
invisibleActorCounter = 0;
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 6336);
actorListEntry = &actorCtx->actorList[0];
for (i = 0; i < ARRAY_COUNT(actorCtx->actorList); i++, actorListEntry++)
{
actor = actorListEntry->first;
while (actor != NULL)
{
overlayEntry = actor->overlayEntry;
actorName = overlayEntry->name != NULL ? overlayEntry->name : "";
gDma1p(gfxCtx->polyOpa.p++, G_NOOP, actorName, i, 2);
gDma1p(gfxCtx->polyXlu.p++, G_NOOP, actorName, i, 2);
HREG(66) = i;
if ((HREG(64) != 1) ||
((HREG(65) != -1) && (HREG(65) != HREG(66))) ||
(HREG(68) == 0))
{
func_800A6E10(&globalCtx->mf_11D60, &actor->posRot.pos, &actor->unk_E4, &actor->unk_F0);
}
if ((HREG(64) != 1) ||
((HREG(65) != -1) && (HREG(65) != HREG(66))) ||
(HREG(69) == 0))
{
if (actor->soundEffect != 0)
func_80030ED8(actor);
}
if ((HREG(64) != 1) ||
((HREG(65) != -1) && (HREG(65) != HREG(66))) ||
(HREG(70) == 0))
{
if (func_800314B0(globalCtx, actor))
actor->flags |= 0x40;
else
actor->flags &= ~0x40;
}
actor->activelyDrawn = 0;
if ((HREG(64) != 1) ||
((HREG(65) != -1) && (HREG(65) != HREG(66))) ||
(HREG(71) == 0))
{
if ((actor->init == NULL) && (actor->draw != NULL) && (actor->flags & 0x60))
{
if ((actor->flags & 0x80) &&
((globalCtx->roomCtx.curRoom.showInvisActors == 0) ||
(globalCtx->actorCtx.unk_03 != 0) ||
(actor->room != globalCtx->roomCtx.curRoom.num)))
{
if (invisibleActorCounter >= INVISIBLE_ACTOR_MAX)
__assert("invisible_actor_counter < INVISIBLE_ACTOR_MAX", "../z_actor.c", 6464);
invisibleActors[invisibleActorCounter] = actor;
invisibleActorCounter++;
}
else
{
if ((HREG(64) != 1) ||
((HREG(65) != -1) && (HREG(65) != HREG(66))) ||
(HREG(72) == 0))
{
Actor_Draw(globalCtx, actor);
actor->activelyDrawn = 1;
}
}
}
}
actor = actor->next;
}
}
if ((HREG(64) != 1) || (HREG(73) != 0))
func_80026E74(globalCtx->state.gfxCtx);
if ((HREG(64) != 1) || (HREG(74) != 0))
func_80027BDC(globalCtx);
if ((HREG(64) != 1) || (HREG(72) != 0))
{
if (globalCtx->actorCtx.unk_03 != 0)
{
func_8003115C(globalCtx, invisibleActorCounter, invisibleActors);
if ((globalCtx->csCtx.state != 0) || func_8008E988(globalCtx))
func_800304B0(globalCtx);
}
}
func_8002FBAC(globalCtx);
if (IREG(32) == 0)
func_8007ABBC(globalCtx);
if ((HREG(64) != 1) || (HREG(75) != 0))
TitleCard_Draw(globalCtx, &actorCtx->titleCtx);
if ((HREG(64) != 1) || (HREG(76) != 0))
func_8005D62C(globalCtx, &globalCtx->sub_11E60);
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 6563);
}
void func_80031A28(GlobalContext* globalCtx, ActorContext* actorCtx)
{
Actor* actor;
s32 i;
for (i = 0; i < ARRAY_COUNT(actorCtx->actorList); i++)
{
actor = actorCtx->actorList[i].first;
while (actor != NULL)
{
if (!Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex))
Actor_Kill(actor);
actor = actor->next;
}
}
}
u8 sEnemyActorTypes[] = { ACTORTYPE_ENEMY, ACTORTYPE_BOSS };
void Actor_FreezeAllEnemies(GlobalContext* globalCtx, ActorContext* actorCtx, s32 freezeValue)
{
Actor* actor;
s32 i;
for (i = 0; i < ARRAY_COUNT(sEnemyActorTypes); i++)
{
actor = actorCtx->actorList[sEnemyActorTypes[i]].first;
while (actor != NULL)
{
actor->freeze = freezeValue;
actor = actor->next;
}
}
}
void func_80031B14(GlobalContext* globalCtx, ActorContext* actorCtx)
{
Actor* actor;
s32 i;
for (i = 0; i < ARRAY_COUNT(actorCtx->actorList); i++)
{
actor = actorCtx->actorList[i].first;
while (actor != NULL)
{
if ((actor->room >= 0) &&
(actor->room != globalCtx->roomCtx.curRoom.num) &&
(actor->room != globalCtx->roomCtx.prevRoom.num))
{
if (!actor->activelyDrawn)
actor = Actor_Delete(actorCtx, actor, globalCtx);
else
{
Actor_Kill(actor);
Actor_Destroy(actor, globalCtx);
actor = actor->next;
}
}
else
actor = actor->next;
}
}
func_8005D40C(globalCtx, &globalCtx->sub_11E60);
actorCtx->flags.tempClear = 0;
actorCtx->flags.tempSwch &= 0xFFFFFF;
globalCtx->msgCtx.unk_E3F4 = 0;
}
void func_80031C3C(ActorContext* actorCtx, GlobalContext* globalCtx)
{
Actor* actor;
s32 i;
for (i = 0; i < ARRAY_COUNT(actorCtx->actorList); i++)
{
actor = actorCtx->actorList[i].first;
while (actor != NULL)
{
Actor_Delete(actorCtx, actor, globalCtx);
actor = actorCtx->actorList[i].first;
}
}
if (HREG(20) != 0)
// Translates to: "ABSOLUTE MAGIC FIELD DEALLOCATION"
osSyncPrintf("絶対魔法領域解放\n");
if (actorCtx->absoluteSpace != NULL)
{
ZeldaArena_FreeDebug(actorCtx->absoluteSpace, "../z_actor.c", 6731);
actorCtx->absoluteSpace = NULL;
}
func_800C0A44(globalCtx);
func_80030488(globalCtx);
ActorOverlayTable_Cleanup();
}
/**
* Adds a given actor instance at the front of the actor list of the specified type.
* Also sets the actor instance as being of that type.
*/
void Actor_AddToTypeList(ActorContext* actorCtx, Actor* actorToAdd, u8 actorType)
{
Actor* prevFirstActor;
actorToAdd->type = actorType;
actorCtx->total++;
actorCtx->actorList[actorType].length++;
prevFirstActor = actorCtx->actorList[actorType].first;
if (prevFirstActor != NULL)
prevFirstActor->prev = actorToAdd;
actorCtx->actorList[actorType].first = actorToAdd;
actorToAdd->next = prevFirstActor;
}
/**
* Removes a given actor instance from its actor list.
* Also sets the temp clear flag of the current room if the actor removed was the last enemy loaded.
*/
Actor* Actor_RemoveFromTypeList(GlobalContext* globalCtx, ActorContext* actorCtx, Actor* actorToRemove)
{
Actor* newFirstActor;
actorCtx->total--;
actorCtx->actorList[actorToRemove->type].length--;
if (actorToRemove->prev != NULL)
actorToRemove->prev->next = actorToRemove->next;
else
actorCtx->actorList[actorToRemove->type].first = actorToRemove->next;
newFirstActor = actorToRemove->next;
if (newFirstActor != NULL)
newFirstActor->prev = actorToRemove->prev;
actorToRemove->next = NULL;
actorToRemove->prev = NULL;
if ((actorToRemove->room == globalCtx->roomCtx.curRoom.num) &&
(actorToRemove->type == ACTORTYPE_ENEMY) &&
(actorCtx->actorList[ACTORTYPE_ENEMY].length == 0))
{
Flags_SetTempClear(globalCtx, globalCtx->roomCtx.curRoom.num);
}
return newFirstActor;
}
void Actor_FreeOverlay(ActorOverlay* actorOverlay)
{
osSyncPrintf(VT_FGCOL(CYAN));
if (actorOverlay->nbLoaded == 0)
{
if (HREG(20) != 0)
// Translates to: "ACTOR CLIENT IS NOW 0"
osSyncPrintf("アクタークライアントが0になりました\n");
if (actorOverlay->loadedRamAddr != NULL)
{
if (actorOverlay->allocType & ALLOCTYPE_PERMANENT)
{
if (HREG(20) != 0)
// Translates to: "OVERLAY WILL NOT BE DEALLOCATED"
osSyncPrintf("オーバーレイ解放しません\n");
}
else if (actorOverlay->allocType & ALLOCTYPE_ABSOLUTE)
{
if (HREG(20) != 0)
// Translates to: "ABSOLUTE MAGIC FIELD RESERVED, SO DEALLOCATION WILL NOT OCCUR"
osSyncPrintf("絶対魔法領域確保なので解放しません\n");
actorOverlay->loadedRamAddr = NULL;
}
else
{
if (HREG(20) != 0)
// Translates to: "OVERLAY DEALLOCATED"
osSyncPrintf("オーバーレイ解放します\n");
ZeldaArena_FreeDebug(actorOverlay->loadedRamAddr, "../z_actor.c", 6834);
actorOverlay->loadedRamAddr = NULL;
}
}
}
else if (HREG(20) != 0)
// Translates to: "%d OF ACTOR CLIENT REMAINS"
osSyncPrintf("アクタークライアントはあと %d 残っています\n", actorOverlay->nbLoaded);
osSyncPrintf(VT_RST);
}
Actor* Actor_Spawn(ActorContext* actorCtx, GlobalContext* globalCtx, s16 actorId,
f32 posX, f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, s16 params)
{
s32 pad;
Actor* actor;
ActorInit* actorInit;
s32 objBankIndex;
ActorOverlay* overlayEntry;
u32 temp;
char* name;
u32 overlaySize;
overlayEntry = &gActorOverlayTable[actorId];
if (actorId >= ACTOR_DLF_MAX)
__assert("profile < ACTOR_DLF_MAX", "../z_actor.c", 6883);
name = overlayEntry->name != NULL ? overlayEntry->name : "";
overlaySize = (u32)overlayEntry->vramEnd - (u32)overlayEntry->vramStart;
if (HREG(20) != 0)
// Translates to: "ACTOR CLASS ADDITION [%d:%s]"
osSyncPrintf("アクタークラス追加 [%d:%s]\n", actorId, name);
if (actorCtx->total > ACTOR_NUMBER_MAX)
{
// Translates to: " SET NUMBER EXCEEDED"
osSyncPrintf(VT_COL(YELLOW, BLACK) "Actorセット数オーバー\n" VT_RST);
return NULL;
}
if (overlayEntry->vramStart == 0)
{
if (HREG(20) != 0)
// Translates to: "NOT AN OVERLAY"
osSyncPrintf("オーバーレイではありません\n");
actorInit = overlayEntry->initInfo;
}
else
{
if (overlayEntry->loadedRamAddr != NULL)
{
if (HREG(20) != 0)
// Translates to: "ALREADY LOADED"
osSyncPrintf("既にロードされています\n");
}
else
{
if (overlayEntry->allocType & ALLOCTYPE_ABSOLUTE)
{
if (overlaySize > AM_FIELD_SIZE)
__assert("actor_segsize <= AM_FIELD_SIZE", "../z_actor.c", 6934);
if (actorCtx->absoluteSpace == NULL)
{
// Translates to: "AMF: ABSOLUTE MAGIC FIELD"
actorCtx->absoluteSpace = ZeldaArena_MallocRDebug(AM_FIELD_SIZE, "AMF:絶対魔法領域", 0);
if (HREG(20) != 0)
// Translates to: "ABSOLUTE MAGIC FIELD RESERVATION - %d BYTES RESERVED"
osSyncPrintf("絶対魔法領域確保 %d バイト確保\n", AM_FIELD_SIZE);
}
overlayEntry->loadedRamAddr = actorCtx->absoluteSpace;
}
else if (overlayEntry->allocType & ALLOCTYPE_PERMANENT)
overlayEntry->loadedRamAddr = ZeldaArena_MallocRDebug(overlaySize, name, 0);
else
overlayEntry->loadedRamAddr = ZeldaArena_MallocDebug(overlaySize, name, 0);
if (overlayEntry->loadedRamAddr == NULL)
{
// Translates to: "CANNOT RESERVE ACTOR PROGRAM MEMORY"
osSyncPrintf(VT_COL(RED, WHITE) "Actorプログラムメモリが確保できません\n" VT_RST);
return NULL;
}
Overlay_Load(overlayEntry->vromStart, overlayEntry->vromEnd,
overlayEntry->vramStart, overlayEntry->vramEnd,
overlayEntry->loadedRamAddr);
osSyncPrintf(VT_FGCOL(GREEN));
osSyncPrintf("OVL(a):Seg:%08x-%08x Ram:%08x-%08x Off:%08x %s\n",
overlayEntry->vramStart, overlayEntry->vramEnd,
overlayEntry->loadedRamAddr,
(u32)overlayEntry->loadedRamAddr + (u32)overlayEntry->vramEnd - (u32)overlayEntry->vramStart,
(u32)overlayEntry->vramStart - (u32)overlayEntry->loadedRamAddr,
name);
osSyncPrintf(VT_RST);
overlayEntry->nbLoaded = 0;
}
actorInit = (ActorInit*)((u32)(overlayEntry->initInfo != NULL ?
(ActorInit*)((u32)overlayEntry->initInfo - (s32)((u32)overlayEntry->vramStart - (u32)overlayEntry->loadedRamAddr)) :
NULL));
}
objBankIndex = Object_GetIndex(&globalCtx->objectCtx, actorInit->objectId);
if ((objBankIndex < 0) ||
((actorInit->type == ACTORTYPE_ENEMY) && (Flags_GetClear(globalCtx, globalCtx->roomCtx.curRoom.num))))
{
// Translates to: "NO DATA BANK!! <DATA BANK%d> (profilep->bank=%d)"
osSyncPrintf(VT_COL(RED, WHITE) "データバンク無し!!<データバンク=%d>(profilep->bank=%d)\n" VT_RST, objBankIndex, actorInit->objectId);
Actor_FreeOverlay(overlayEntry);
return NULL;
}
actor = ZeldaArena_MallocDebug(actorInit->instanceSize, name, 1);
if (actor == NULL)
{
// Translates to: "ACTOR CLASS CANNOT BE RESERVED! %s <SIZE%d BYTES>"
osSyncPrintf(VT_COL(RED, WHITE) "Actorクラス確保できません! %s <サイズ=%dバイト>\n", VT_RST, name, actorInit->instanceSize);
Actor_FreeOverlay(overlayEntry);
return NULL;
}
if (overlayEntry->nbLoaded >= 255)
__assert("actor_dlftbl->clients < 255", "../z_actor.c", 7031);
overlayEntry->nbLoaded++;
if (HREG(20) != 0)
// Translates to: "ACTOR CLIENT No. %d"
osSyncPrintf("アクタークライアントは %d 個目です\n", overlayEntry->nbLoaded);
Lib_MemSet(actor, actorInit->instanceSize, 0);
actor->overlayEntry = overlayEntry;
actor->id = actorInit->id;
actor->flags = actorInit->flags;
if (actorInit->id == ACTOR_EN_PART)
{
actor->objBankIndex = rotZ;
rotZ = 0;
}
else
{
actor->objBankIndex = objBankIndex;
}
actor->init = actorInit->init;
actor->destroy = actorInit->destroy;
actor->update = actorInit->update;
actor->draw = actorInit->draw;
actor->room = globalCtx->roomCtx.curRoom.num;
actor->initPosRot.pos.x = posX;
actor->initPosRot.pos.y = posY;
actor->initPosRot.pos.z = posZ;
actor->initPosRot.rot.x = rotX;
actor->initPosRot.rot.y = rotY;
actor->initPosRot.rot.z = rotZ;
actor->params = params;
Actor_AddToTypeList(actorCtx, actor, actorInit->type);
temp = gSegments[6];
Actor_Init(actor, globalCtx);
gSegments[6] = temp;
return actor;
}
Actor* Actor_SpawnAttached(ActorContext* actorCtx, Actor* attachedTo, GlobalContext* globalCtx, s16 actorId,
f32 posX, f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, s16 params)
{
Actor* spawnedActor = Actor_Spawn(actorCtx, globalCtx, actorId,
posX, posY, posZ,
rotX, rotY, rotZ, params);
if (spawnedActor == NULL)
return NULL;
attachedTo->attachedB = spawnedActor;
spawnedActor->attachedA = attachedTo;
if (spawnedActor->room >= 0)
spawnedActor->room = attachedTo->room;
return spawnedActor;
}
void Actor_SpawnTransitionActors(GlobalContext* globalCtx, ActorContext* actorCtx)
{
TransitionActorEntry* transitionActor;
u8 nbTransitionActors;
s32 i;
transitionActor = globalCtx->transitionActorList;
nbTransitionActors = globalCtx->nbTransitionActors;
for (i = 0; i < nbTransitionActors; i++)
{
if (transitionActor->id >= 0)
{
if (((transitionActor->frontRoom >= 0) &&
((transitionActor->frontRoom == globalCtx->roomCtx.curRoom.num) ||
(transitionActor->frontRoom == globalCtx->roomCtx.prevRoom.num))) ||
((transitionActor->backRoom >= 0) &&
((transitionActor->backRoom == globalCtx->roomCtx.curRoom.num) ||
(transitionActor->backRoom == globalCtx->roomCtx.prevRoom.num))))
{
Actor_Spawn(actorCtx, globalCtx, (s16)(transitionActor->id & 0x1FFF),
transitionActor->pos.x, transitionActor->pos.y, transitionActor->pos.z,
0, transitionActor->rotY, 0,
(i << 0xA) + transitionActor->params);
transitionActor->id = -transitionActor->id;
nbTransitionActors = globalCtx->nbTransitionActors;
}
}
transitionActor++;
}
}
Actor* Actor_SpawnEntry(ActorContext* actorCtx, ActorEntry* actorEntry, GlobalContext* globalCtx)
{
return Actor_Spawn(actorCtx, globalCtx, actorEntry->id,
actorEntry->pos.x, actorEntry->pos.y, actorEntry->pos.z,
actorEntry->rot.x, actorEntry->rot.y, actorEntry->rot.z,
actorEntry->params);
}
Actor* Actor_Delete(ActorContext* actorCtx, Actor* actor, GlobalContext* globalCtx)
{
char* name;
Player* player;
Actor* newFirstActor;
ActorOverlay* overlayEntry;
player = PLAYER;
overlayEntry = actor->overlayEntry;
name = overlayEntry->name != NULL ? overlayEntry->name : "";
if (HREG(20) != 0)
// Translates to: "ACTOR CLASS DELETED [%s]"
osSyncPrintf("アクタークラス削除 [%s]\n", name);
if ((player != NULL) && (actor == player->unk_664))
{
func_8008EDF0(player);
func_8005A444(func_800C04A4(globalCtx, func_800C030C(globalCtx)), 0);
}
if (actor == actorCtx->targetCtx.arrowPointedActor)
actorCtx->targetCtx.arrowPointedActor = NULL;
if (actor == actorCtx->targetCtx.unk_8C)
actorCtx->targetCtx.unk_8C = NULL;
if (actor == actorCtx->targetCtx.unk_90)
actorCtx->targetCtx.unk_90 = NULL;
func_800F89E8(&actor->unk_E4);
Actor_Destroy(actor, globalCtx);
newFirstActor = Actor_RemoveFromTypeList(globalCtx, actorCtx, actor);
ZeldaArena_FreeDebug(actor, "../z_actor.c", 7242);
if (overlayEntry->vramStart == 0)
{
if (HREG(20) != 0)
// Translates to: "NOT AN OVERLAY"
osSyncPrintf("オーバーレイではありません\n");
}
else
{
if (overlayEntry->loadedRamAddr == NULL)
__assert("actor_dlftbl->allocp != NULL", "../z_actor.c", 7251);
if (overlayEntry->nbLoaded <= 0)
__assert("actor_dlftbl->clients > 0", "../z_actor.c", 7252);
overlayEntry->nbLoaded--;
Actor_FreeOverlay(overlayEntry);
}
return newFirstActor;
}
s32 func_80032880(GlobalContext* globalCtx, Actor* actor)
{
s16 sp1E;
s16 sp1C;
func_8002F374(globalCtx, actor, &sp1E, &sp1C);
return (sp1E > -20) && (sp1E < 340) && (sp1C > -160) && (sp1C < 400);
}
Actor* D_8015BBE8;
Actor* D_8015BBEC;
f32 D_8015BBF0;
f32 D_8015BBF4;
s32 D_8015BBF8;
s16 D_8015BBFC;
void func_800328D4(GlobalContext* globalCtx, ActorContext* actorCtx, Player* player, u32 actorType)
{
f32 var;
Actor* actor;
Actor* sp84;
CollisionPoly *sp80;
UNK_TYPE sp7C;
Vec3f sp70;
actor = actorCtx->actorList[actorType].first;
sp84 = player->unk_664;
while (actor != NULL)
{
if ((actor->update != NULL) && ((Player*)actor != player) && ((actor->flags & 1) == 1))
{
if ((actorType == ACTORTYPE_ENEMY) && ((actor->flags & 5) == 5) &&
(actor->waterSurfaceDist < 250000.0f) && (actor->waterSurfaceDist < D_8015BBF4))
{
actorCtx->targetCtx.unk_90 = actor;
D_8015BBF4 = actor->waterSurfaceDist;
}
if (actor != sp84)
{
var = func_8002EFC0(actor, player, D_8015BBFC);
if ((var < D_8015BBF0) &&
func_8002F090(actor, var) &&
func_80032880(globalCtx, actor) &&
(!func_8003DD6C(&globalCtx->colCtx, &player->actor.posRot2.pos,
&actor->posRot2.pos, &sp70, &sp80, 1, 1, 1, 1, &sp7C) ||
func_80042048(&globalCtx->colCtx, sp80, sp7C)))
{
if (actor->unk_10D != 0)
{
if (actor->unk_10D < D_8015BBF8)
{
D_8015BBEC = actor;
D_8015BBF8 = actor->unk_10D;
}
}
else
{
D_8015BBE8 = actor;
D_8015BBF0 = var;
}
}
}
}
actor = actor->next;
}
}
u8 D_801160A0[] =
{
ACTORTYPE_BOSS,
ACTORTYPE_ENEMY,
ACTORTYPE_BG,
ACTORTYPE_EXPLOSIVES,
ACTORTYPE_NPC,
ACTORTYPE_ITEMACTION,
ACTORTYPE_CHEST,
ACTORTYPE_SWITCH,
ACTORTYPE_PROP,
ACTORTYPE_MISC,
ACTORTYPE_DOOR,
ACTORTYPE_SWITCH,
};
Actor* func_80032AF0(GlobalContext* globalCtx, ActorContext* actorCtx, Actor** actorPtr, Player* player)
{
s32 i;
u8* entry;
D_8015BBE8 = D_8015BBEC = NULL;
D_8015BBF0 = D_8015BBF4 = FLT_MAX;
D_8015BBF8 = 0x7FFFFFFF;
if (!func_8008E988(globalCtx))
{
entry = &D_801160A0[0];
actorCtx->targetCtx.unk_90 = NULL;
D_8015BBFC = player->actor.shape.rot.y;
for (i = 0; i < 3; i++)
{
func_800328D4(globalCtx, actorCtx, player, *entry);
entry++;
}
if (D_8015BBE8 == NULL)
{
for (i; i < ARRAY_COUNT(D_801160A0); i++)
{
func_800328D4(globalCtx, actorCtx, player, *entry);
entry++;
}
}
}
if (D_8015BBE8 == 0)
*actorPtr = D_8015BBEC;
else
*actorPtr = D_8015BBE8;
return *actorPtr;
}
/**
* Finds the first actor instance of a specified id and type if there is one.
*/
Actor* Actor_Find(ActorContext* actorCtx, s32 actorId, s32 actorType)
{
Actor* actor = actorCtx->actorList[actorType].first;
while (actor != NULL)
{
if (actorId == actor->id)
return actor;
actor = actor->next;
}
return NULL;
}
void func_80032C7C(GlobalContext* globalCtx, Actor* actor)
{
globalCtx->actorCtx.unk_00 = 5;
Audio_PlaySoundAtPosition(globalCtx, &actor->posRot.pos, 0x14, NA_SE_EN_LAST_DAMAGE);
}
s16 func_80032CB4(s16* arg0, s16 arg1, s16 arg2, s16 arg3)
{
if (DECR(arg0[1]) == 0)
arg0[1] = Math_Rand_S16Offset(arg1, arg2);
if ((arg0[1] - arg3) > 0)
arg0[0] = 0;
else if (((arg0[1] - arg3) > -2) || (arg0[1] < 2))
arg0[0] = 1;
else
arg0[0] = 2;
return arg0[0];
}
s16 func_80032D60(s16* arg0, s16 arg1, s16 arg2, s16 arg3)
{
if (DECR(arg0[1]) == 0)
{
arg0[1] = Math_Rand_S16Offset(arg1, arg2);
arg0[0]++;
if ((arg0[0] % 3) == 0)
arg0[0] = (s32)(Math_Rand_ZeroOne() * arg3) * 3;
}
return arg0[0];
}
typedef struct
{
/* 0x00 */ MtxF* unk_00;
/* 0x04 */ s16* unk_04;
/* 0x08 */ s16 unk_08;
/* 0x0A */ char unk_0A[0x02];
/* 0x0C */ s32* unk_0C;
/* 0x10 */ s32 unk_10;
/* 0x14 */ s32 unk_14;
} struct_80032E24;
void func_80032E24(struct_80032E24* arg0, s32 arg1, GlobalContext* globalCtx)
{
u32 sp28;
u32 sp24;
u32 sp20;
sp28 = (arg1 * sizeof(*arg0->unk_00)) + sizeof(*arg0->unk_00);
arg0->unk_00 = ZeldaArena_MallocDebug(sp28, "../z_actor.c", 7540);
if (arg0->unk_00 != NULL)
{
sp24 = (arg1 * sizeof(*arg0->unk_0C)) + sizeof(*arg0->unk_0C);
arg0->unk_0C = ZeldaArena_MallocDebug(sp24, "../z_actor.c", 7543);
if (arg0->unk_0C != NULL)
{
sp20 = (arg1 * sizeof(*arg0->unk_04)) + sizeof(*arg0->unk_04);
arg0->unk_04 = ZeldaArena_MallocDebug(sp20, "../z_actor.c", 7546);
if (arg0->unk_04 != NULL)
{
Lib_MemSet(arg0->unk_00, sp28, 0);
Lib_MemSet(arg0->unk_0C, sp24, 0);
Lib_MemSet(arg0->unk_04, sp20, 0);
arg0->unk_10 = 1;
return;
}
}
}
if (arg0->unk_00 != NULL)
ZeldaArena_FreeDebug(arg0->unk_00, "../z_actor.c", 7558);
if (arg0->unk_0C != NULL)
ZeldaArena_FreeDebug(arg0->unk_0C, "../z_actor.c", 7561);
if (arg0->unk_04 != NULL)
ZeldaArena_FreeDebug(arg0->unk_04, "../z_actor.c", 7564);
}
void func_80032F54(struct_80032E24* arg0, s32 arg1, s32 arg2, s32 arg3, u32 arg4, s32* arg5, s16 arg6)
{
GlobalContext* globalCtx = func_80026B00();
if ((globalCtx->actorCtx.unk_00 == 0) && (arg0->unk_10 > 0))
{
if ((arg1 >= arg2) && (arg3 >= arg1) && (*arg5 != 0))
{
arg0->unk_0C[arg0->unk_10] = *arg5;
Matrix_Get(&arg0->unk_00[arg0->unk_10]);
arg0->unk_04[arg0->unk_10] = arg6;
arg0->unk_10++;
}
if (arg1 != arg0->unk_14)
arg0->unk_08++;
if (arg0->unk_08 >= arg4)
{
arg0->unk_08 = arg0->unk_10 - 1;
arg0->unk_10 = -1;
}
}
arg0->unk_14 = arg1;
}
typedef struct
{
/* 0x000 */ Actor actor;
/* 0x14C */ u8 unk_14C;
/* 0x14E */ s16 unk_14E;
/* 0x150 */ s32 unk_150;
/* 0x154 */ f32 unk_154;
/* 0x158 */ f32 unk_158;
} ActorEnPart;
s32 func_8003305C(Actor* actor, struct_80032E24* arg1, GlobalContext* globalCtx, s16 params)
{
ActorEnPart* spawnedEnPart;
MtxF* mtx;
s16 objBankIndex;
if (arg1->unk_10 != -1)
return 0;
while (arg1->unk_08 > 0)
{
Matrix_Put(&arg1->unk_00[arg1->unk_08]);
Matrix_Scale(1.0f / actor->scale.x, 1.0f / actor->scale.y, 1.0f / actor->scale.z, MTXMODE_APPLY);
Matrix_Get(&arg1->unk_00[arg1->unk_08]);
if (1) // Necessary to match
{
if (arg1->unk_04[arg1->unk_08] >= 0)
objBankIndex = arg1->unk_04[arg1->unk_08];
else
objBankIndex = actor->objBankIndex;
}
mtx = &arg1->unk_00[arg1->unk_08];
spawnedEnPart = (ActorEnPart*)Actor_SpawnAttached(&globalCtx->actorCtx, actor, globalCtx, ACTOR_EN_PART,
mtx->wx, mtx->wy, mtx->wz,
0, 0, objBankIndex, params);
if (spawnedEnPart != NULL)
{
func_800D20CC(&arg1->unk_00[arg1->unk_08], &spawnedEnPart->actor.shape.rot, 0);
spawnedEnPart->unk_150 = arg1->unk_0C[arg1->unk_08];
spawnedEnPart->actor.scale = actor->scale;
}
arg1->unk_08--;
}
arg1->unk_10 = 0;
ZeldaArena_FreeDebug(arg1->unk_00, "../z_actor.c", 7678);
ZeldaArena_FreeDebug(arg1->unk_0C, "../z_actor.c", 7679);
ZeldaArena_FreeDebug(arg1->unk_04, "../z_actor.c", 7680);
return 1;
}
void func_80033260(GlobalContext* globalCtx, Actor* actor, Vec3f* arg2, f32 arg3, s32 arg4, f32 arg5, s16 arg6, s16 arg7, u8 arg8)
{
Vec3f sp9C;
Vec3f sp90 = { 0.0f, 0.0f, 0.0f };
Vec3f sp84 = { 0.0f, 0.3f, 0.0f };
f32 var;
s32 i;
var = (Math_Rand_ZeroOne() - 0.5f) * 6.28f;
sp9C.y = actor->unk_80;
sp84.y += (Math_Rand_ZeroOne() - 0.5f) * 0.2f;
for (i = arg4; i >= 0; i--)
{
sp9C.x = (func_800CA720(var) * arg3) + arg2->x;
sp9C.z = (func_800CA774(var) * arg3) + arg2->z;
sp84.x = (Math_Rand_ZeroOne() - 0.5f) * arg5;
sp84.z = (Math_Rand_ZeroOne() - 0.5f) * arg5;
if (arg6 == 0)
func_8002857C(globalCtx, &sp9C, &sp90, &sp84);
else if (arg8 != 0)
func_800286CC(globalCtx, &sp9C, &sp90, &sp84, arg6, arg7);
else
func_8002865C(globalCtx, &sp9C, &sp90, &sp84, arg6, arg7);
var += 6.28f / (arg4 + 1.0f);
}
}
void func_80033480(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2, s32 arg3, s16 arg4, s16 arg5, u8 arg6)
{
Vec3f sp94;
Vec3f sp88 = { 0.0f, 0.0f, 0.0f };
Vec3f sp7C = { 0.0f, 0.3f, 0.0f };
s16 var;
u32 var2;
s32 i;
for (i = arg3; i >= 0; i--)
{
sp94.x = arg1->x + ((Math_Rand_ZeroOne() - 0.5f) * arg2);
sp94.y = arg1->y + ((Math_Rand_ZeroOne() - 0.5f) * arg2);
sp94.z = arg1->z + ((Math_Rand_ZeroOne() - 0.5f) * arg2);
var = (s16)((Math_Rand_ZeroOne() * arg4) * 0.2f) + arg4;
var2 = arg6;
if (var2 != 0)
func_800286CC(globalCtx, &sp94, &sp88, &sp7C, var, arg5);
else
func_8002865C(globalCtx, &sp94, &sp88, &sp7C, var, arg5);
}
}
Actor* func_80033640(GlobalContext* globalCtx, Collider* collider)
{
if ((collider->collideFlags & 0x2) && (collider->ac->type == ACTORTYPE_EXPLOSIVES))
{
collider->collideFlags &= ~0x2;
return collider->ac;
}
return NULL;
}
Actor* func_80033684(GlobalContext* globalCtx, Actor* explosiveActor)
{
Actor* actor = globalCtx->actorCtx.actorList[ACTORTYPE_EXPLOSIVES].first;
while (actor != NULL)
{
if ((actor == explosiveActor) || (actor->params != 1))
{
actor = actor->next;
}
else
{
if (func_8002DB48(explosiveActor, actor) <= (actor->shape.rot.z * 10) + 80.0f)
return actor;
else
actor = actor->next;
}
}
return NULL;
}
/**
* Dynamically changes the type of a given actor instance.
* This is done by moving it to the corresponding type list and setting its type variable accordingly.
*/
void Actor_ChangeType(GlobalContext* globalCtx, ActorContext* actorCtx, Actor* actor, u8 actorType)
{
Actor_RemoveFromTypeList(globalCtx, actorCtx, actor);
Actor_AddToTypeList(actorCtx, actor, actorType);
}
typedef struct
{
/* 0x000 */ Actor actor;
/* 0x14C */ char unk_14C[0xC4];
/* 0x210 */ s16 unk_210;
} Actor_80033780;
Actor_80033780* func_80033780(GlobalContext* globalCtx, Actor* refActor, f32 arg2)
{
Actor_80033780* itemActor;
Vec3f spA8;
f32 deltaX;
f32 deltaY;
f32 deltaZ;
Vec3f sp90;
Vec3f sp84;
Actor* actor;
actor = globalCtx->actorCtx.actorList[ACTORTYPE_ITEMACTION].first;
while (actor != NULL)
{
if (((actor->id != ACTOR_ARMS_HOOK) && (actor->id != ACTOR_EN_ARROW)) || (actor == refActor))
actor = actor->next;
else
{
itemActor = (Actor_80033780*)actor;
if ((arg2 < Math_Vec3f_DistXYZ(&refActor->posRot.pos, &itemActor->actor.posRot.pos)) || (itemActor->unk_210 == 0))
{
actor = actor->next;
}
else
{
deltaX = Math_Sins(itemActor->actor.posRot.rot.y) * (itemActor->actor.speedXZ * 10.0f);
deltaY = itemActor->actor.velocity.y + (itemActor->actor.gravity * 10.0f);
deltaZ = Math_Coss(itemActor->actor.posRot.rot.y) * (itemActor->actor.speedXZ * 10.0f);
spA8.x = itemActor->actor.posRot.pos.x + deltaX;
spA8.y = itemActor->actor.posRot.pos.y + deltaY;
spA8.z = itemActor->actor.posRot.pos.z + deltaZ;
if (func_80062ECC(refActor->sub_98.unk_10, refActor->sub_98.unk_12, 0.0f,
&refActor->posRot.pos, &itemActor->actor.posRot.pos, &spA8, &sp90, &sp84))
return itemActor;
else
actor = actor->next;
}
}
}
return NULL;
}
/**
* Sets the actor's text id with a dynamic prefix based on the current scene.
*/
void Actor_SetTextWithPrefix(GlobalContext* globalCtx, Actor* actor, s16 baseTextId)
{
s16 prefix;
switch (globalCtx->sceneNum)
{
case SCENE_YDAN:
case SCENE_YDAN_BOSS:
case SCENE_MORIBOSSROOM:
case SCENE_KOKIRI_HOME:
case SCENE_KOKIRI_HOME3:
case SCENE_KOKIRI_HOME4:
case SCENE_KOKIRI_HOME5:
case SCENE_KOKIRI_SHOP:
case SCENE_LINK_HOME:
case SCENE_SPOT04:
case SCENE_SPOT05:
case SCENE_SPOT10:
case 112:
prefix = 0x1000;
break;
case SCENE_MALON_STABLE:
case SCENE_SPOT00:
case SCENE_SPOT20:
prefix = 0x2000;
break;
case SCENE_HIDAN:
case SCENE_DDAN_BOSS:
case SCENE_FIRE_BS:
case SCENE_SPOT16:
case SCENE_SPOT17:
case SCENE_SPOT18:
prefix = 0x3000;
break;
case SCENE_BDAN:
case SCENE_BDAN_BOSS:
case SCENE_SPOT03:
case SCENE_SPOT07:
case SCENE_SPOT08:
prefix = 0x4000;
break;
case SCENE_HAKADAN:
case SCENE_HAKADAN_BS:
case SCENE_KAKARIKO:
case SCENE_KAKARIKO3:
case SCENE_IMPA:
case SCENE_HUT:
case SCENE_HAKAANA:
case SCENE_HAKASITARELAY:
case SCENE_SPOT01:
case SCENE_SPOT02:
prefix = 0x5000;
break;
case SCENE_JYASINZOU:
case SCENE_JYASINBOSS:
case SCENE_LABO:
case SCENE_TENT:
case SCENE_SPOT06:
case SCENE_SPOT09:
case SCENE_SPOT11:
prefix = 0x6000;
break;
case SCENE_ENTRA:
case SCENE_MARKET_ALLEY:
case SCENE_MARKET_ALLEY_N:
case SCENE_MARKET_DAY:
case SCENE_MARKET_NIGHT:
case SCENE_MARKET_RUINS:
case SCENE_SPOT15:
prefix = 0x7000;
break;
default:
prefix = 0x0000;
break;
}
actor->textId = prefix | baseTextId;
}
s16 func_800339B8(Actor* actor, GlobalContext* globalCtx, f32 arg2, s16 arg3)
{
s16 ret;
s16 sp44;
f32 sp40;
f32 sp3C;
Vec3f sp30;
Math_Vec3f_Copy(&sp30, &actor->posRot.pos);
sp44 = actor->bgCheckFlags;
sp40 = Math_Sins(arg3) * arg2;
sp3C = Math_Coss(arg3) * arg2;
actor->posRot.pos.x += sp40;
actor->posRot.pos.z += sp3C;
func_8002E4B4(globalCtx, actor, 0.0f, 0.0f, 0.0f, 4);
Math_Vec3f_Copy(&actor->posRot.pos, &sp30);
ret = actor->bgCheckFlags & 1;
actor->bgCheckFlags = sp44;
return ret;
}
s32 func_80033A84(GlobalContext* globalCtx, Actor* actor)
{
Player* player = PLAYER;
if ((player->stateFlags1 & 0x10) && (actor->unk_10C != 0))
return 1;
else
return 0;
}
s32 func_80033AB8(GlobalContext* globalCtx, Actor* actor)
{
Player* player = PLAYER;
if ((player->stateFlags1 & 0x10) && (actor->unk_10C == 0))
return 1;
else
return 0;
}
f32 func_80033AEC(Vec3f* arg0, Vec3f* arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5)
{
f32 ret = 0.0f;
if (arg4 <= Math_Vec3f_DistXYZ(arg0, arg1))
{
ret = Math_SmoothScaleMaxMinF(&arg1->x, arg0->x, arg2, arg3, 0.0f);
ret += Math_SmoothScaleMaxMinF(&arg1->y, arg0->y, arg2, arg3, 0.0f);
ret += Math_SmoothScaleMaxMinF(&arg1->z, arg0->z, arg2, arg3, 0.0f);
}
else if (arg5 < Math_Vec3f_DistXYZ(arg0, arg1))
{
ret = Math_SmoothScaleMaxMinF(&arg1->x, arg0->x, arg2, arg3, 0.0f);
ret += Math_SmoothScaleMaxMinF(&arg1->y, arg0->y, arg2, arg3, 0.0f);
ret += Math_SmoothScaleMaxMinF(&arg1->z, arg0->z, arg2, arg3, 0.0f);
}
return ret;
}
void func_80033C30(Vec3f* arg0, Vec3f* arg1, u8 alpha, GlobalContext* globalCtx)
{
MtxF sp60;
f32 var;
Vec3f sp50;
CollisionPoly* sp4C;
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
Gfx* gfxArr[4];
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 8120);
if (0) ; // Necessary to match
gfxCtx->polyOpa.p = func_80093774(gfxCtx->polyOpa.p, 0x2C);
gDPSetPrimColor(gfxCtx->polyOpa.p++, 0, 0, 0x00, 0x00, 0x00, alpha);
sp50.x = arg0->x;
sp50.y = arg0->y + 1.0f;
sp50.z = arg0->z;
var = func_8003C8EC(globalCtx, &globalCtx->colCtx, &sp4C, &sp50);
if (sp4C != NULL)
{
func_80038A28(sp4C, arg0->x, var, arg0->z, &sp60);
Matrix_Put(&sp60);
}
else
Matrix_Translate(arg0->x, arg0->y, arg0->z, MTXMODE_NEW);
Matrix_Scale(arg1->x, 1.0f, arg1->z, MTXMODE_APPLY);
gSPMatrix(gfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_actor.c", 8149), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(gfxCtx->polyOpa.p++, &D_04049210);
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 8155);
}
void func_80033DB8(GlobalContext* globalCtx, s16 arg1, s16 arg2)
{
s16 var = func_80092F88(&globalCtx->cameraCtx.activeCameras[0], 3);
func_80092DAC(var, 20000);
func_80092E70(var, arg1, 0, 0, 0);
func_80092DF0(var, arg2);
}
void func_80033E1C(GlobalContext* globalCtx, s16 arg1, s16 arg2, s16 arg3)
{
s16 var = func_80092F88(&globalCtx->cameraCtx.activeCameras[0], 3);
func_80092DAC(var, arg3);
func_80092E70(var, arg1, 0, 0, 0);
func_80092DF0(var, arg2);
}
void func_80033E88(Actor* actor, GlobalContext* globalCtx, s16 arg2, s16 arg3)
{
if (arg2 >= 5)
func_800AA000(actor->waterSurfaceDist, 0xFF, 0x14, 0x96);
else
func_800AA000(actor->waterSurfaceDist, 0xB4, 0x14, 0x64);
func_80033DB8(globalCtx, arg2, arg3);
}
f32 Math_Rand_ZeroFloat(f32 f)
{
return Math_Rand_ZeroOne() * f;
}
f32 Math_Rand_CenteredFloat(f32 f)
{
return (Math_Rand_ZeroOne() - 0.5f) * f;
}
typedef struct
{
/* 0x00 */ f32 unk_00;
/* 0x04 */ f32 unk_04;
/* 0x08 */ f32 unk_08;
/* 0x0C */ f32 unk_0C;
/* 0x10 */ f32 unk_10;
/* 0x14 */ u32 unk_14;
/* 0x18 */ u32 unk_18;
} struct_801160DC; // size = 0x1C
struct_801160DC D_801160DC[3] =
{
{ 0.54f, 6000.0f, 5000.0f, 1.0f, 0.0f, 0x050011F0, 0x05001100 },
{ 0.644f, 12000.0f, 8000.0f, 1.0f, 0.0f, 0x06001530, 0x06001400 },
{ 0.64000005f, 8500.0f, 8000.0f, 1.75f, 0.1f, 0x050011F0, 0x05001100 },
};
void func_80033F54(GlobalContext* globalCtx, s32 arg1, s32 arg2)
{
struct_801160DC* entry;
s32 i;
MtxF spB0;
f32 var;
f32 temp1;
f32 temp2;
f32 temp3;
GraphicsContext* gfxCtx;
Gfx* gfxArr[4];
entry = &D_801160DC[arg2];
var = entry->unk_10;
gfxCtx = globalCtx->state.gfxCtx;
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 8265);
Matrix_Translate(0.0f, entry->unk_08, 500.0f, MTXMODE_APPLY);
Matrix_Get(&spB0);
temp1 = sinf(entry->unk_00 - var) * -(10 - arg1) * 0.1f * entry->unk_04;
temp2 = cosf(entry->unk_00 - var) * (10 - arg1) * 0.1f * entry->unk_04;
for (i = 0; i < 4; i++)
{
Matrix_Put(&spB0);
Matrix_RotateZ(var, MTXMODE_APPLY);
Matrix_Translate(temp1, temp2, 0.0f, MTXMODE_APPLY);
if (entry->unk_0C != 1.0f)
Matrix_Scale(entry->unk_0C, entry->unk_0C, entry->unk_0C, MTXMODE_APPLY);
gSPMatrix(gfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_actor.c", 8299), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(gfxCtx->polyOpa.p++, entry->unk_14);
if (i % 2)
temp3 = entry->unk_00 + entry->unk_00;
else
temp3 = M_PI - (entry->unk_00 + entry->unk_00);
var += temp3;
}
Matrix_Put(&spB0);
Matrix_Scale(arg1 * 0.1f, arg1 * 0.1f, arg1 * 0.1f, MTXMODE_APPLY);
gSPMatrix(gfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_actor.c", 8314), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(gfxCtx->polyOpa.p++, entry->unk_18);
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 8319);
}
void func_8003424C(GlobalContext* globalCtx, Vec3f* arg1)
{
func_80062D60(globalCtx, arg1);
}
void func_8003426C(Actor* actor, s16 arg1, s16 arg2, s16 arg3, s16 arg4)
{
if ((arg1 == 0x8000) && !(arg2 & 0x8000))
Audio_PlayActorSound2(actor, NA_SE_EN_LIGHT_ARROW_HIT);
actor->unk_112 = arg1 | arg3 | ((arg2 & 0xF8) << 5) | arg4;
actor->unk_114 = arg4;
}
Hilite* func_800342EC(Vec3f* object, GlobalContext* globalCtx)
{
Vec3f lightDir;
lightDir.x = globalCtx->unk_10A4E;
lightDir.y = globalCtx->unk_10A4F;
lightDir.z = globalCtx->unk_10A50;
return func_8002EABC(object, &globalCtx->view.eye, &lightDir, globalCtx->state.gfxCtx);
}
Hilite* func_8003435C(Vec3f* object, GlobalContext* globalCtx)
{
Vec3f lightDir;
lightDir.x = globalCtx->unk_10A4E;
lightDir.y = globalCtx->unk_10A4F;
lightDir.z = globalCtx->unk_10A50;
return func_8002EB44(object, &globalCtx->view.eye, &lightDir, globalCtx->state.gfxCtx);
}
s32 func_800343CC(GlobalContext* globalCtx, Actor* actor, s16* arg2, f32 arg3, u16 (*unkFunc1)(GlobalContext*, Actor*), s16 (*unkFunc2)(GlobalContext*, Actor*))
{
s16 sp26;
s16 sp24;
if (func_8002F194(actor, globalCtx))
{
*arg2 = 1;
return 1;
}
if (*arg2 != 0)
{
*arg2 = unkFunc2(globalCtx, actor);
return 0;
}
func_8002F374(globalCtx, actor, &sp26, &sp24);
if ((sp26 < 0) || (sp26 > 0x140) || (sp24 < 0) || (sp24 > 0xF0))
return 0;
if (!func_8002F2CC(actor, globalCtx, arg3))
return 0;
actor->textId = unkFunc1(globalCtx, actor);
return 0;
}
typedef struct
{
/* 0x00 */ s16 unk_00;
/* 0x02 */ s16 unk_02;
/* 0x04 */ s16 unk_04;
/* 0x06 */ s16 unk_06;
/* 0x08 */ s16 unk_08;
/* 0x0A */ s16 unk_0A;
/* 0x0C */ char unk_0C[0x2];
/* 0x0E */ s16 unk_0E;
/* 0x10 */ s16 unk_10;
/* 0x12 */ char unk_12[0x2];
/* 0x14 */ f32 unk_14;
/* 0x18 */ Vec3f unk_18;
} struct_80034A14_arg1;
typedef struct
{
/* 0x00 */ s16 unk_00;
/* 0x02 */ s16 unk_02;
/* 0x04 */ s16 unk_04;
/* 0x06 */ s16 unk_06;
/* 0x08 */ s16 unk_08;
/* 0x0A */ s16 unk_0A;
/* 0x0C */ u8 unk_0C;
} struct_80116130_0; // size = 0x10
typedef struct
{
/* 0x00 */ struct_80116130_0 sub_00;
/* 0x10 */ f32 unk_10;
/* 0x14 */ s16 unk_14;
} struct_80116130; // size = 0x18
struct_80116130 D_80116130[13] =
{
{ { 0x2AA8, 0xF1C8, 0x18E2, 0x1554, 0x0000, 0x0000, 1 }, 170.0f, 0x3FFC },
{ { 0x2AA8, 0xEAAC, 0x1554, 0x1554, 0xF8E4, 0x0E38, 1 }, 170.0f, 0x3FFC },
{ { 0x31C4, 0xE390, 0x0E38, 0x0E38, 0xF1C8, 0x071C, 1 }, 170.0f, 0x3FFC },
{ { 0x1554, 0xF1C8, 0x0000, 0x071C, 0xF8E4, 0x0000, 1 }, 170.0f, 0x3FFC },
{ { 0x2AA8, 0xF8E4, 0x071C, 0x0E38, 0xD558, 0x2AA8, 1 }, 170.0f, 0x3FFC },
{ { 0x0000, 0xE390, 0x2AA8, 0x3FFC, 0xF1C8, 0x0E38, 1 }, 170.0f, 0x3FFC },
{ { 0x2AA8, 0xF1C8, 0x0E38, 0x0E38, 0x0000, 0x0000, 1 }, 0.0f, 0x0000 },
{ { 0x2AA8, 0xF1C8, 0x0000, 0x0E38, 0x0000, 0x1C70, 1 }, 0.0f, 0x0000 },
{ { 0x2AA8, 0xF1C8, 0xF1C8, 0x0000, 0x0000, 0x0000, 1 }, 0.0f, 0x0000 },
{ { 0x071C, 0xF1C8, 0x0E38, 0x1C70, 0x0000, 0x0000, 1 }, 0.0f, 0x0000 },
{ { 0x0E38, 0xF1C8, 0x0000, 0x1C70, 0x0000, 0x0E38, 1 }, 0.0f, 0x0000 },
{ { 0x2AA8, 0xE390, 0x1C70, 0x0E38, 0xF1C8, 0x0E38, 1 }, 0.0f, 0x0000 },
{ { 0x18E2, 0xF1C8, 0x0E38, 0x0E38, 0x0000, 0x0000, 1 }, 0.0f, 0x0000 },
};
#ifdef NON_MATCHING
// this function still needs a lot of work
void func_800344BC(Actor* actor, struct_80034A14_arg1* arg1, s16 arg2, s16 arg3, s16 arg4, s16 arg5, s16 arg6, s16 arg7, u8 arg8)
{
s16 sp46;
s16 sp44;
s16 temp1;
s16 sp40;
s16 temp2;
Vec3f sp30;
s16 temp3;
s16 temp4;
sp30.x = actor->posRot.pos.x;
sp30.y = actor->posRot.pos.y + arg1->unk_14;
sp30.z = actor->posRot.pos.z;
sp46 = Math_Vec3f_Pitch(&sp30, &arg1->unk_18);
sp44 = Math_Vec3f_Yaw(&sp30, &arg1->unk_18);
temp1 = Math_Vec3f_Yaw(&actor->posRot.pos, &arg1->unk_18) - actor->shape.rot.y;
Math_SmoothScaleMaxMinS(&arg1->unk_0A, (temp1 < -arg2) ? -arg2 : ((temp1 > arg2) ? arg2 : temp1), 6, 2000, 1);
temp3 = (ABS(temp1) >= 0x8000) ? 0 : ((temp1 >= 0) ? temp1 : -temp1);
arg1->unk_0A = ((arg1->unk_0A < -temp3) ? -temp3 : ((arg1->unk_0A > temp3) ? temp3 : arg1->unk_0A));
sp40 = temp1 - arg1->unk_0A;
Math_SmoothScaleMaxMinS(&arg1->unk_10, (sp40 < -arg5) ? -arg5 : ((sp40 > arg5) ? arg5 : sp40), 6, 2000, 1);
temp4 = (ABS(sp40) >= 0x8000) ? 0 : ((sp40 >= 0) ? sp40 : -sp40);
arg1->unk_10 = ((arg1->unk_10 < -temp4) ? -temp4 : ((arg1->unk_10 > temp4) ? temp4 : arg1->unk_10));
if (arg8 != 0)
Math_SmoothScaleMaxMinS(&actor->shape.rot.y, sp44, 6, 2000, 1);
Math_SmoothScaleMaxMinS(&arg1->unk_08, (sp46 < arg4) ? arg4 : ((sp46 > arg3) ? arg3 : sp46), 6, 2000, 1);
temp2 = sp46 - arg1->unk_08;
Math_SmoothScaleMaxMinS(&arg1->unk_0E, (temp2 < arg7) ? arg4 : ((temp2 > arg6) ? arg3 : temp2), 6, 2000, 1);
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800344BC.s")
#endif
s16 func_800347E8(s16 arg0)
{
return D_80116130[arg0].unk_14;
}
s16 func_80034810(Actor* actor, struct_80034A14_arg1* arg1, f32 arg2, s16 arg3, s16 arg4)
{
s32 pad;
s16 var;
s16 abs_var;
if (arg4 != 0)
return arg4;
if (arg1->unk_00 != 0)
return 4;
if (arg2 < Math_Vec3f_DistXYZ(&actor->posRot.pos, &arg1->unk_18))
{
arg1->unk_04 = 0;
arg1->unk_06 = 0;
return 1;
}
var = Math_Vec3f_Yaw(&actor->posRot.pos, &arg1->unk_18);
abs_var = ABS((s16)((f32)var - actor->shape.rot.y));
if (arg3 >= abs_var)
{
arg1->unk_04 = 0;
arg1->unk_06 = 0;
return 2;
}
if (DECR(arg1->unk_04) != 0)
return arg1->unk_02;
switch (arg1->unk_06)
{
case 0:
case 2:
arg1->unk_04 = Math_Rand_S16Offset(30, 30);
arg1->unk_06++;
return 1;
case 1:
arg1->unk_04 = Math_Rand_S16Offset(10, 10);
arg1->unk_06++;
return 3;
}
return 4;
}
void func_80034A14(Actor* actor, struct_80034A14_arg1* arg1, s16 arg2, s16 arg3)
{
struct_80116130_0 sp38;
arg1->unk_02 = func_80034810(actor, arg1, D_80116130[arg2].unk_10, D_80116130[arg2].unk_14, arg3);
sp38 = D_80116130[arg2].sub_00;
switch (arg1->unk_02)
{
case 1:
sp38.unk_00 = 0;
sp38.unk_04 = 0;
sp38.unk_02 = 0;
case 3:
sp38.unk_06 = 0;
sp38.unk_0A = 0;
sp38.unk_08 = 0;
case 2:
sp38.unk_0C = 0;
}
func_800344BC(actor, arg1, sp38.unk_00, sp38.unk_04, sp38.unk_02,
sp38.unk_06, sp38.unk_0A, sp38.unk_08, sp38.unk_0C);
}
Gfx* func_80034B28(GraphicsContext* gfxCtx)
{
Gfx* displayList;
displayList = Graph_Alloc(gfxCtx, sizeof(Gfx));
gSPEndDisplayList(displayList);
return displayList;
}
#ifdef NON_MATCHING
// doesn't generate the 2 useless move instructions before returning
Gfx* func_80034B54(GraphicsContext* gfxCtx)
{
Gfx* displayList;
Gfx* displayListHead;
displayList = Graph_Alloc(gfxCtx, 2 * sizeof(Gfx));
displayListHead = displayList;
gDPSetRenderMode(displayListHead++,
AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL |
GBL_c1(G_BL_CLR_FOG, G_BL_A_SHADE, G_BL_CLR_IN, G_BL_1MA),
AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL |
GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA));
gSPEndDisplayList(displayListHead);
return displayList;
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_80034B54.s")
#endif
void func_80034BA0(GlobalContext* globalCtx, SkelAnime* skelAnime, void* unkFunc1, void* unkFunc2, Actor* actor, s16 alpha)
{
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
Gfx* gfxArr[4];
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 8831);
func_80093D18(globalCtx->state.gfxCtx);
gDPPipeSync(gfxCtx->polyOpa.p++);
gDPSetEnvColor(gfxCtx->polyOpa.p++, 0x00, 0x00, 0x00, alpha);
gDPPipeSync(gfxCtx->polyOpa.p++);
gSPSegment(gfxCtx->polyOpa.p++, 0x0C, func_80034B28(globalCtx->state.gfxCtx));
gfxCtx->polyOpa.p = func_800A273C(globalCtx, skelAnime->limbIndex, skelAnime->actorDrawTbl,
skelAnime->dListCount, unkFunc1, unkFunc2, actor, gfxCtx->polyOpa.p);
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 8860);
}
void func_80034CC4(GlobalContext* globalCtx, SkelAnime* skelAnime, void* unkFunc1, void* unkFunc2, Actor* actor, s16 alpha)
{
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
Gfx* gfxArr[4];
func_800C6AC4(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 8876);
func_80093D84(globalCtx->state.gfxCtx);
gDPPipeSync(gfxCtx->polyXlu.p++);
gDPSetEnvColor(gfxCtx->polyXlu.p++, 0x00, 0x00, 0x00, alpha);
gSPSegment(gfxCtx->polyXlu.p++, 0x0C, func_80034B54(globalCtx->state.gfxCtx));
gfxCtx->polyXlu.p = func_800A273C(globalCtx, skelAnime->limbIndex, skelAnime->actorDrawTbl,
skelAnime->dListCount, unkFunc1, unkFunc2, actor, gfxCtx->polyXlu.p);
func_800C6B54(gfxArr, globalCtx->state.gfxCtx, "../z_actor.c", 8904);
}
s16 func_80034DD4(Actor* actor, GlobalContext* globalCtx, s16 arg2, f32 arg3)
{
Player* player = PLAYER;
f32 var;
if ((globalCtx->csCtx.state != 0) || (D_8011D394 != 0))
var = Math_Vec3f_DistXYZ(&actor->posRot.pos, &globalCtx->view.eye) * 0.25f;
else
var = Math_Vec3f_DistXYZ(&actor->posRot.pos, &player->actor.posRot.pos);
if (arg3 < var)
{
actor->flags &= ~1;
Math_SmoothScaleMaxMinS(&arg2, 0, 6, 0x14, 1);
}
else
{
actor->flags |= 1;
Math_SmoothScaleMaxMinS(&arg2, 0xFF, 6, 0x14, 1);
}
return arg2;
}
void func_80034EC0(SkelAnime* skelAnime, struct_80034EC0_Entry* arg1, s32 arg2)
{
f32 frameCount;
arg1 += arg2;
if (arg1->frameCount > 0.0f)
frameCount = arg1->frameCount;
else
frameCount = SkelAnime_GetFrameCount(arg1->animation);
SkelAnime_ChangeAnimation(skelAnime, arg1->animation, arg1->playbackSpeed,
arg1->unk_08, frameCount, arg1->unk_10, arg1->transitionRate);
}
void func_80034F54(GlobalContext* globalCtx, s16* arg1, s16* arg2, s32 arg3)
{
u32 frames = globalCtx->gameplayFrames;
s32 i;
for (i = 0; i < arg3; i++)
{
arg1[i] = (0x814 + 50 * i) * frames;
arg2[i] = (0x940 + 50 * i) * frames;
}
}
void Actor_Noop(Actor* actor, GlobalContext* globalCtx)
{
}
s32 func_80035124(Actor* actor, GlobalContext* globalCtx)
{
s32 ret = 0;
switch (actor->params)
{
case 0:
if (func_8002F410(actor, globalCtx))
{
actor->params = 1;
}
else if (!(actor->bgCheckFlags & 1))
{
Actor_MoveForward(actor);
Math_SmoothScaleMaxMinF(&actor->speedXZ, 0.0f, 1.0f, 0.1f, 0.0f);
}
else if ((actor->bgCheckFlags & 2) && (actor->velocity.y < -4.0f))
{
ret = 1;
}
else
{
actor->shape.rot.x = actor->shape.rot.z = 0;
func_8002F580(actor, globalCtx);
}
break;
case 1:
if (func_8002F5A0(actor, globalCtx))
{
actor->params = 0;
}
break;
}
func_8002E4B4(globalCtx, actor, actor->sub_98.unk_12, actor->sub_98.unk_10, actor->sub_98.unk_10, 0x1D);
return ret;
}
#include "z_cheap_proc.c"
u8 func_800353E8(GlobalContext* globalCtx)
{
Player* player = PLAYER;
return player->unk_845;
}
/**
* Finds the first actor instance of a specified id and type within a given range from an actor if there is one.
* If the id provided is -1, this will look for any actor of the specified type rather than a specific id.
*/
Actor* Actor_FindNearby(GlobalContext* globalCtx, Actor* refActor, s16 actorId, u8 actorType, f32 range)
{
Actor* actor = globalCtx->actorCtx.actorList[actorType].first;
while (actor != NULL)
{
if (actor == refActor || ((actorId != -1) && (actorId != actor->id)))
{
actor = actor->next;
}
else
{
if (func_8002DB48(refActor, actor) <= range)
return actor;
else
actor = actor->next;
}
}
return NULL;
}
s32 func_800354B4(GlobalContext* globalCtx, Actor* actor, f32 range, s16 arg3, s16 arg4, s16 arg5)
{
Player* player = PLAYER;
s16 var1;
s16 var2;
var1 = (s16)(actor->rotTowardsLinkY + 0x8000) - player->actor.shape.rot.y;
var2 = actor->rotTowardsLinkY - arg5;
if ((actor->xzDistanceFromLink <= range) && (player->swordState != 0) &&
(arg4 >= ABS(var1)) && (arg3 >= ABS(var2)))
return 1;
else
return 0;
}
void func_8003555C(GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3)
{
Color_RGB8 color1;
Color_RGB8 color2;
color1.r = 0xC8;
color1.g = 0xA0;
color1.b = 0x78;
color2.r = 0x82;
color2.g = 0x5A;
color2.b = 0x32;
func_80028B74(globalCtx, arg1, arg2, arg3, &color1, &color2);
}
Vec3f D_80116268 = { 0.0f, -1.5f, 0.0f };
Vec3f D_80116274 = { 0.0f, -0.2f, 0.0f };
// unused
Gfx D_80116280[] =
{
gsDPSetRenderMode(AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG |
CVG_DST_WRAP | ZMODE_XLU | FORCE_BL |
GBL_c1(G_BL_CLR_FOG, G_BL_A_SHADE, G_BL_CLR_IN, G_BL_1MA),
AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG |
CVG_DST_WRAP | ZMODE_XLU | FORCE_BL |
GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)),
gsDPSetAlphaCompare(G_AC_THRESHOLD),
gsSPEndDisplayList(),
};
void func_800355B8(GlobalContext* globalCtx, Vec3f* arg1)
{
func_8003555C(globalCtx, arg1, &D_80116268, &D_80116274);
}
u8 func_800355E4(GlobalContext* globalCtx, ColliderCylinderInit* colCylinderInit)
{
Player* player = PLAYER;
if ((colCylinderInit->inner.toucherDamage & 0x08) && (player->swordState != 0) && (player->swordAnimation == 0x16))
return 1;
else
return 0;
}
u8 Actor_ApplyDamage(Actor* actor)
{
if (actor->sub_98.damage >= actor->sub_98.health)
actor->sub_98.health = 0;
else
actor->sub_98.health -= actor->sub_98.damage;
return actor->sub_98.health;
}
void func_80035650(Actor* actor, ColliderBody* colBody, s32 freezeFlag)
{
if (colBody->colliding == NULL)
{
actor->unk_116 = 0x00;
}
else if (freezeFlag && (colBody->colliding->toucher.flags & 0x10060000))
{
actor->freeze = colBody->colliding->toucher.damage;
actor->unk_116 = 0x00;
}
else if (colBody->colliding->toucher.flags & 0x0800)
{
actor->unk_116 = 0x01;
}
else if (colBody->colliding->toucher.flags & 0x1000)
{
actor->unk_116 = 0x02;
}
else if (colBody->colliding->toucher.flags & 0x4000)
{
actor->unk_116 = 0x04;
}
else if (colBody->colliding->toucher.flags & 0x8000)
{
actor->unk_116 = 0x08;
}
else if ((colBody->colliding->toucher.flags << 0xF) < 0)
{
actor->unk_116 = 0x10;
}
else if (colBody->colliding->toucher.flags & 0x2000)
{
actor->unk_116 = 0x20;
}
else if ((colBody->colliding->toucher.flags << 0xC) < 0)
{
if (freezeFlag)
actor->freeze = colBody->colliding->toucher.damage;
actor->unk_116 = 0x40;
}
else
{
actor->unk_116 = 0x00;
}
}
void func_8003573C(Actor* actor, ColliderBody* colBody, s32 freezeFlag)
{
ColliderBody* curColBody;
s32 flag;
s32 i;
actor->unk_116 = 0x00;
for (i = colBody->unk_18 - 1; i >= 0; i--)
{
curColBody = &colBody->colBuf[i].c;
if (curColBody->colliding == NULL)
{
flag = 0x00;
}
else if (freezeFlag && (curColBody->colliding->toucher.flags & 0x10060000))
{
actor->freeze = curColBody->colliding->toucher.damage;
flag = 0x00;
}
else if (curColBody->colliding->toucher.flags & 0x0800)
{
flag = 0x01;
}
else if (curColBody->colliding->toucher.flags & 0x1000)
{
flag = 0x02;
}
else if (curColBody->colliding->toucher.flags & 0x4000)
{
flag = 0x04;
}
else if (curColBody->colliding->toucher.flags & 0x8000)
{
flag = 0x08;
}
else if (curColBody->colliding->toucher.flags & 0x10000)
{
flag = 0x10;
}
else if (curColBody->colliding->toucher.flags & 0x2000)
{
flag = 0x20;
}
else if (curColBody->colliding->toucher.flags & 0x80000)
{
if (freezeFlag)
actor->freeze = curColBody->colliding->toucher.damage;
flag = 0x40;
}
else
{
flag = 0x00;
}
actor->unk_116 |= flag;
}
}
void func_80035844(Vec3f* arg0, Vec3f* arg1, s16* arg2, s32 arg3)
{
f32 dx = arg1->x - arg0->x;
f32 dz = arg1->z - arg0->z;
f32 dy = arg3 ? (arg1->y - arg0->y) : (arg0->y - arg1->y);
arg2[1] = atan2s(dz, dx);
arg2[0] = atan2s(sqrtf(SQ(dx) + SQ(dz)), dy);
}
/**
* Spawns En_Part (Dissipating Flames) actor attached to the given actor.
*/
ActorEnPart* func_800358DC(Actor* actor, Vec3f* spawnPos, Vec3s* spawnRot, Vec3f* arg3, s32 arg4,
s32 unused, GlobalContext* globalCtx, s16 params, s32 arg8)
{
ActorEnPart* spawnedEnPart;
spawnedEnPart = (ActorEnPart*)Actor_SpawnAttached(&globalCtx->actorCtx, actor, globalCtx, ACTOR_EN_PART,
spawnPos->x, spawnPos->y, spawnPos->z,
spawnRot->x, spawnRot->y, actor->objBankIndex,
params);
if (spawnedEnPart != NULL)
{
spawnedEnPart->actor.scale = actor->scale;
spawnedEnPart->actor.speedXZ = arg3->x;
spawnedEnPart->unk_150 = arg8;
spawnedEnPart->unk_14C = 2;
spawnedEnPart->unk_14E = arg4;
spawnedEnPart->unk_154 = arg3->y;
spawnedEnPart->unk_158 = arg3->z;
return spawnedEnPart;
}
return NULL;
}
void func_800359B8(Actor* actor, s16 arg1, Vec3s* arg2)
{
f32 sp44;
f32 sp40;
f32 sp3C;
f32 sp38;
f32 sp34;
f32 sp30;
f32 sp2C;
f32 sp28;
f32 sp24;
CollisionPoly* floorPoly;
s32 pad;
if (actor->floorPoly != NULL)
{
floorPoly = actor->floorPoly;
sp44 = floorPoly->norm.x * (1.f / 32767);
sp40 = floorPoly->norm.y * (1.f / 32767);
sp3C = floorPoly->norm.z * (1.f / 32767);
sp38 = Math_Sins(arg1);
sp34 = Math_Coss(arg1);
sp28 = (-(sp44 * sp38) - (sp3C * sp34));
arg2->x = -(s16)(Math_atan2f(sp28 * sp40, 1.0f) * (32768 / M_PI));
sp2C = Math_Sins(arg1 - 16375);
sp30 = Math_Coss(arg1 - 16375);
sp24 = (-(sp44 * sp2C) - (sp3C * sp30));
arg2->z = -(s16)(Math_atan2f(sp24 * sp40, 1.0f) * (32768 / M_PI));
}
}
void func_80035B18(GlobalContext* globalCtx, Actor* actor, u16 textId)
{
func_8010B720(globalCtx, textId);
actor->textId = textId;
}
/**
* Tests if event_chk_inf flag is set.
*/
s32 Flags_GetEventChkInf(s32 flag)
{
return gSaveContext.event_chk_inf[flag >> 4] & (1 << (flag & 0xF));
}
/**
* Sets event_chk_inf flag.
*/
void Flags_SetEventChkInf(s32 flag)
{
gSaveContext.event_chk_inf[flag >> 4] |= (1 << (flag & 0xF));
}
/**
* Tests if inf_table flag is set.
*/
s32 Flags_GetInfTable(s32 flag)
{
return gSaveContext.inf_table[flag >> 4] & (1 << (flag & 0xF));
}
/**
* Sets inf_table flag.
*/
void Flags_SetInfTable(s32 flag)
{
gSaveContext.inf_table[flag >> 4] |= (1 << (flag & 0xF));
}
u32 func_80035BFC(GlobalContext* globalCtx, s16 arg1)
{
u16 retTextId = 0;
switch(arg1)
{
case 0:
if (Flags_GetEventChkInf(0x9))
{
if (Flags_GetInfTable(0x5))
retTextId = 0x1048;
else
retTextId = 0x1047;
}
else
{
if (Flags_GetEventChkInf(0x2))
{
if (Flags_GetInfTable(0x3))
retTextId = 0x1032;
else
retTextId = 0x1031;
}
else
{
if (Flags_GetInfTable(0x0))
{
if (Flags_GetInfTable(0x1))
retTextId = 0x1003;
else
retTextId = 0x1002;
}
else
retTextId = 0x1001;
}
}
break;
case 1:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x9))
{
if (Flags_GetInfTable(0x10))
retTextId = 0x1046;
else
retTextId = 0x1045;
}
else
{
if (Flags_GetEventChkInf(0x3))
{
if (Flags_GetInfTable(0xE))
retTextId = 0x1034;
else
retTextId = 0x1033;
}
else
{
if (Flags_GetInfTable(0xC))
retTextId = 0x1030;
else
retTextId = 0x102F;
}
}
}
else
{
if (Flags_GetEventChkInf(0x5C))
{
if (Flags_GetInfTable(0x19))
retTextId = 0x1071;
else
retTextId = 0x1070;
}
else
{
if (Flags_GetEventChkInf(0xB))
{
if (Flags_GetInfTable(0x17))
retTextId = 0x1068;
else
retTextId = 0x1067;
}
else
{
if (Flags_GetInfTable(0x15))
retTextId = 0x1061;
else
retTextId = 0x1060;
}
}
}
break;
case 2:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x9))
retTextId = 0x1042;
else
retTextId = 0x1004;
}
else
{
if (Flags_GetEventChkInf(0x5C))
retTextId = 0x1072;
else if (Flags_GetInfTable(0x41))
retTextId = 0x1055;
else
retTextId = 0x1056;
}
break;
case 3:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x9))
retTextId = 0x1043;
else
{
if (Flags_GetInfTable(0x1E))
retTextId = 0x1006;
else
retTextId = 0x1005;
}
}
else
{
if (Flags_GetEventChkInf(0x5C))
retTextId = 0x1073;
else
retTextId = 0x105A;
}
break;
case 4:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x9))
retTextId = 0x1042;
else
retTextId = 0x1007;
}
else
{
if (Flags_GetEventChkInf(0x5C))
retTextId = 0x1072;
else if (Flags_GetInfTable(0x47))
retTextId = 0x105E;
else
retTextId = 0x105D;
}
break;
case 5:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x9))
retTextId = 0x1044;
else if (Flags_GetInfTable(0x22))
retTextId = 0x1009;
else
retTextId = 0x1008;
}
else
{
if (Flags_GetEventChkInf(0x5C))
retTextId = 0x1075;
else
retTextId = 0x105B;
}
break;
case 6:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x9))
retTextId = 0x1042;
else if (Flags_GetInfTable(0x24))
retTextId = 0x100B;
else
retTextId = 0x100A;
}
else
{
if (Flags_GetEventChkInf(0x5C))
retTextId = 0x1056;
else
retTextId = 0x105F;
}
break;
case 7:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x9))
retTextId = 0x1043;
else if (Flags_GetInfTable(0x26))
retTextId = 0x100D;
else
retTextId = 0x100C;
}
else
{
if (Flags_GetEventChkInf(0x5C))
retTextId = 0x1057;
else
retTextId = 0x1057;
}
break;
case 8:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x9))
retTextId = 0x1043;
else if (Flags_GetInfTable(0x28))
retTextId = 0x1019;
else
retTextId = 0x100E;
}
else
{
if (Flags_GetEventChkInf(0x5C))
retTextId = 0x1077;
else if (Flags_GetInfTable(0x51))
retTextId = 0x1058;
else
retTextId = 0x1059;
}
break;
case 9:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x9))
retTextId = 0x1049;
else
retTextId = 0x1035;
}
else
{
if (Flags_GetEventChkInf(0x5C))
retTextId = 0x1079;
else
retTextId = 0x104e;
}
break;
case 10:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x9))
retTextId = 0x104A;
else
retTextId = 0x1038;
}
else
{
if (Flags_GetEventChkInf(0x5C))
retTextId = 0x1079;
else if (Flags_GetInfTable(0x59))
retTextId = 0x1050;
else
retTextId = 0x104F;
}
break;
case 11:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x9))
retTextId = 0x104B;
else
retTextId = 0x103C;
}
else
{
if (Flags_GetEventChkInf(0x5C))
retTextId = 0x107b;
else
retTextId = 0x1051;
}
break;
case 12:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x9))
retTextId = 0x104C;
else
retTextId = 0x103D;
}
else
{
if (Flags_GetEventChkInf(0x5C))
retTextId = 0x107C;
else
retTextId = 0x1052;
}
break;
case 13:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x9))
retTextId = 0x104D;
else
retTextId = 0x103E;
}
else
{
if (Flags_GetEventChkInf(0x5C))
retTextId = 0x106E;
else if (Flags_GetInfTable(0x61))
retTextId = 0x1053;
else
retTextId = 0x1054;
}
break;
case 15:
if (Flags_GetEventChkInf(0x5C))
retTextId = 0x1078;
else if (Flags_GetInfTable(0x66))
retTextId = 0x1066;
else
retTextId = 0x1062;
break;
case 16:
if (globalCtx->sceneNum == SCENE_SPOT15)
retTextId = 0x7002;
else if (Flags_GetInfTable(0x6A))
retTextId = 0x7004;
else if ((gSaveContext.day_time >= 0x4000) && (gSaveContext.day_time < 0xC556))
retTextId = 0x7002;
else
retTextId = 0x7003;
break;
case 17:
if (Flags_GetEventChkInf(0x9) && Flags_GetEventChkInf(0x25) && Flags_GetEventChkInf(0x37))
{
if (Flags_GetInfTable(0x6c))
retTextId = 0x7008;
else
retTextId = 0x7007;
}
else
retTextId = 0;
break;
case 19:
retTextId = 0x702D;
break;
case 18:
if (Flags_GetEventChkInf(0x9) && Flags_GetEventChkInf(0x25) && Flags_GetEventChkInf(0x37))
retTextId = 0x7006;
else
{
if (Flags_GetEventChkInf(0x12))
{
if (Flags_GetInfTable(0x71))
retTextId = 0x7072;
else
retTextId = 0x7071;
}
else
retTextId = 0x7029;
}
break;
case 20:
case 21:
if (Flags_GetEventChkInf(0x42))
retTextId = 0x2012;
else if (Flags_GetEventChkInf(0x41))
{
if (Flags_GetInfTable(0x76))
retTextId = 0x2011;
else
retTextId = 0x2010;
}
else if (Flags_GetEventChkInf(0x40))
retTextId = 0x200F;
else
retTextId = 0x200E;
break;
case 24:
if (Flags_GetEventChkInf(0x9) && Flags_GetEventChkInf(0x25) && Flags_GetEventChkInf(0x37))
retTextId = 0x7044;
else
retTextId = 0x7015;
break;
case 25:
if (Flags_GetEventChkInf(0x9) && Flags_GetEventChkInf(0x25) && Flags_GetEventChkInf(0x37))
retTextId = 0x7045;
else
{
Flags_GetInfTable(0xC2);
retTextId = 0x7016;
}
break;
case 26:
if (Flags_GetEventChkInf(0x9) && Flags_GetEventChkInf(0x25) && Flags_GetEventChkInf(0x37))
retTextId = 0x7046;
else
{
Flags_GetInfTable(0xc2);
retTextId = 0x7018;
}
break;
case 27:
if (Flags_GetEventChkInf(0x9) && Flags_GetEventChkInf(0x25) && Flags_GetEventChkInf(0x37))
retTextId = 0x7047;
else if (Flags_GetEventChkInf(0x14))
retTextId = 0x701A;
else if (Flags_GetEventChkInf(0x11))
{
if (Flags_GetInfTable(0xC6))
retTextId = 0x701C;
else
retTextId = 0x701B;
}
else
retTextId = 0x701A;
break;
case 28:
if (Flags_GetEventChkInf(0x9) && Flags_GetEventChkInf(0x25) && Flags_GetEventChkInf(0x37))
retTextId = 0x7048;
else
{
Flags_GetInfTable(0xca);
retTextId = 0x701D;
}
break;
case 29:
if (Flags_GetEventChkInf(0x9) && Flags_GetEventChkInf(0x25) && Flags_GetEventChkInf(0x37))
retTextId = 0x7049;
else
{
Flags_GetInfTable(0xcc);
retTextId = 0x701F;
}
break;
case 30:
if (Flags_GetEventChkInf(0x9) && Flags_GetEventChkInf(0x25) && Flags_GetEventChkInf(0x37))
retTextId = 0x704A;
else
{
Flags_GetInfTable(0xCE);
retTextId = 0x7021;
}
break;
case 31:
if (Flags_GetEventChkInf(0x9) && Flags_GetEventChkInf(0x25) && Flags_GetEventChkInf(0x37))
retTextId = 0x704B;
else
{
Flags_GetInfTable(0xD0);
retTextId = 0x7023;
}
break;
case 32:
if (Flags_GetEventChkInf(0x9) && Flags_GetEventChkInf(0x25) && Flags_GetEventChkInf(0x37))
retTextId = 0x704C;
else
{
Flags_GetInfTable(0xD2);
retTextId = 0x7025;
}
break;
case 33:
if (Flags_GetEventChkInf(0x9) && Flags_GetEventChkInf(0x25) && Flags_GetEventChkInf(0x37))
retTextId = 0x704D;
else
{
Flags_GetInfTable(0xD4);
retTextId = 0x7027;
}
break;
case 34:
Flags_GetInfTable(0xD6);
retTextId = 0x403C;
break;
case 35:
if (Flags_GetInfTable(0xD8))
retTextId = 0x5029;
else
retTextId = 0x5028;
break;
case 37:
retTextId = 0x5002;
break;
case 38:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x25))
retTextId = 0x3027;
else if (Flags_GetEventChkInf(0x23))
retTextId = 0x3021;
else if (Flags_GetInfTable(0xE0))
retTextId = 0x302A;
else
retTextId = 0x3008;
}
else
{
if (Flags_GetEventChkInf(0x20))
retTextId = 0x4043;
else
retTextId = 0x302A;
}
break;
case 39:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x25))
retTextId = 0x3027;
else if (Flags_GetEventChkInf(0x23))
retTextId = 0x3026;
else
retTextId = 0x3009;
}
else
{
if (Flags_GetEventChkInf(0x2A))
retTextId = 0x4043;
else
retTextId = 0x302A;
}
break;
case 40:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x25))
retTextId = 0x3027;
else if (Flags_GetEventChkInf(0x23))
retTextId = 0x3026;
else if (Flags_GetInfTable(0xEB))
retTextId = 0x302B;
else
retTextId = 0x300A;
}
else
{
if (Flags_GetEventChkInf(0x2B))
retTextId = 0x4043;
else
retTextId = 0x302A;
}
break;
case 41:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x25))
retTextId = 0x3027;
else if (Flags_GetInfTable(0xF0))
retTextId = 0x3015;
else
retTextId = 0x3014;
}
else
{
if (Flags_GetEventChkInf(0x2C))
retTextId = 0x4043;
else
retTextId = 0x302A;
}
break;
case 42:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x25))
retTextId = 0x3027;
else if (Flags_GetInfTable(0xF4))
retTextId = 0x3017;
else
retTextId = 0x3016;
}
else
{
if (Flags_GetEventChkInf(0x2C))
retTextId = 0x4043;
else
retTextId = 0x302A;
}
break;
case 43:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x25))
retTextId = 0x3027;
else if (Flags_GetInfTable(0xF8))
retTextId = 0x3019;
else
retTextId = 0x3018;
}
else
{
if (Flags_GetEventChkInf(0x2D))
retTextId = 0x4043;
else
retTextId = 0x302A;
}
break;
case 48:
if (Flags_GetEventChkInf(0x25))
retTextId = 0x3029;
else if (Flags_GetEventChkInf(0x20) && Flags_GetEventChkInf(0x21))
retTextId = 0x301B;
else
retTextId = 0x301A;
break;
case 49:
if (Flags_GetEventChkInf(0x37))
retTextId = 0x402D;
else if (Flags_GetEventChkInf(0x30))
retTextId = 0x4007;
else
retTextId = 0x4006;
break;
case 50:
if (Flags_GetEventChkInf(0x37))
retTextId = 0x402E;
else if (Flags_GetEventChkInf(0x30))
{
if (Flags_GetInfTable(0x124))
retTextId = 0x4009;
else
retTextId = 0x4008;
}
else
retTextId = 0x4006;
break;
case 51:
if (Flags_GetEventChkInf(0x37))
retTextId = 0x402D;
else if (Flags_GetEventChkInf(0x31))
{
if (Flags_GetInfTable(0x12A))
retTextId = 0x400B;
else
retTextId = 0x402F;
}
else if (Flags_GetEventChkInf(0x30))
retTextId = 0x400A;
else
retTextId = 0x4006;
break;
case 52:
if (Flags_GetEventChkInf(0x37))
retTextId = 0x402E;
else if (Flags_GetEventChkInf(0x30))
retTextId = 0x400C;
else
retTextId = 0x4006;
break;
case 53:
if (Flags_GetEventChkInf(0x37))
retTextId = 0x402D;
else if (Flags_GetEventChkInf(0x33))
retTextId = 0x4010;
else if (Flags_GetEventChkInf(0x30))
retTextId = 0x400F;
else
retTextId = 0x4006;
break;
case 54:
if (Flags_GetEventChkInf(0x37))
retTextId = 0x402E;
else if (Flags_GetEventChkInf(0x30))
retTextId = 0x4011;
else
retTextId = 0x4006;
break;
case 55:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x37))
retTextId = 0x402B;
else if (Flags_GetEventChkInf(0x31))
{
if (Flags_GetInfTable(0x138))
retTextId = 0x401C;
else
retTextId = 0x401B;
}
else
retTextId = 0x401A;
}
else
retTextId = 0;
break;
case 58:
retTextId = 0x500F;
break;
case 59:
retTextId = 0x5010;
break;
case 60:
retTextId = 0x5012;
break;
case 61:
if (Flags_GetInfTable(0x166))
retTextId = 0x5001;
else
retTextId = 0x5000;
break;
case 62:
retTextId = 0x5012;
break;
case 63:
if (Flags_GetInfTable(0x16A))
retTextId = 0x5001;
else
retTextId = 0x5000;
break;
case 71:
if (Flags_GetEventChkInf(0x16))
retTextId = 0x2049;
else if (Flags_GetEventChkInf(0x15))
retTextId = 0x2048;
else if (Flags_GetEventChkInf(0x14))
retTextId = 0x2047;
else if (Flags_GetEventChkInf(0x12) && !Flags_GetEventChkInf(0x14))
retTextId = 0x2044;
else if (Flags_GetEventChkInf(0x10))
{
if (Flags_GetEventChkInf(0x11))
retTextId = 0x2043;
else
retTextId = 0x2042;
}
else
retTextId = 0x2041;
break;
case 72:
if (LINK_IS_CHILD)
{
if (Flags_GetEventChkInf(0x14))
retTextId = 0x2040;
else if (Flags_GetInfTable(0x94))
retTextId = 0x2040;
else
retTextId = 0x203F;
}
else
{
if (!Flags_GetEventChkInf(0x18))
{
if (gSaveContext.night_flag)
retTextId = 0x204E;
else if (Flags_GetInfTable(0x9A))
retTextId = 0x2031;
else
retTextId = 0x2030;
}
else
retTextId = 0;
}
break;
}
if (retTextId == 0)
retTextId = 1;
return retTextId;
}
void func_80036E50(u16 textId, s16 arg1)
{
switch (arg1)
{
case 0:
switch (textId)
{
case 0x1001:
Flags_SetInfTable(0x0);
return;
case 0x1002:
Flags_SetInfTable(0x1);
return;
case 0x1031:
Flags_SetEventChkInf(0x3);
Flags_SetInfTable(0x3);
return;
case 0x1047:
Flags_SetInfTable(0x5);
return;
}
return;
case 1:
switch (textId)
{
case 0x102F:
Flags_SetEventChkInf(0x2);
Flags_SetInfTable(0xC);
return;
case 0x1033:
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
Flags_SetEventChkInf(0x4);
Flags_SetInfTable(0xE);
return;
case 0x1045:
Flags_SetInfTable(0x10);
return;
case 0x1060:
Flags_SetInfTable(0x15);
return;
case 0x1067:
Flags_SetEventChkInf(0xA);
Flags_SetInfTable(0x17);
return;
case 0x1070:
Flags_SetInfTable(0x19);
return;
}
return;
case 2:
if (textId == 0x1056)
Flags_SetInfTable(0x41);
return;
case 3:
if (textId == 0x1005)
Flags_SetInfTable(0x1E);
return;
case 4:
if (textId == 0x105D)
Flags_SetInfTable(0x47);
return;
case 5:
if (textId == 0x1008)
Flags_SetInfTable(0x22);
return;
case 6:
if (textId == 0x100A)
Flags_SetInfTable(0x24);
return;
case 7:
if (textId == 0x100C)
Flags_SetInfTable(0x26);
return;
case 8:
if (textId == 0x100E)
Flags_SetInfTable(0x28);
if (textId == 0x1059)
Flags_SetInfTable(0x51);
return;
case 10:
if (textId == 0x104F)
Flags_SetInfTable(0x59);
return;
case 13:
if (textId == 0x1054)
Flags_SetInfTable(0x61);
return;
case 15:
if (textId == 0x1062)
Flags_SetInfTable(0x66);
return;
case 16:
if (textId == 0x7002)
Flags_SetInfTable(0x6A);
if (textId == 0x7003)
Flags_SetInfTable(0x6A);
return;
case 17:
if (textId == 0x7007)
Flags_SetInfTable(0x6C);
return;
case 18:
if (textId == 0x7071)
Flags_SetInfTable(0x71);
return;
case 20:
case 21:
if (textId == 0x2010)
Flags_SetInfTable(0x76);
return;
case 25:
if (textId == 0x7016)
Flags_SetInfTable(0xC2);
return;
case 26:
if (textId == 0x7018)
Flags_SetInfTable(0xC4);
return;
case 28:
if (textId == 0x701D)
Flags_SetInfTable(0xCA);
return;
case 29:
if (textId == 0x701F)
Flags_SetInfTable(0xCC);
return;
case 30:
if (textId == 0x7021)
Flags_SetInfTable(0xCE);
return;
case 31:
if (textId == 0x7023)
Flags_SetInfTable(0xD0);
return;
case 32:
if (textId == 0x7025)
Flags_SetInfTable(0xD2);
return;
case 33:
if (textId == 0x7027)
Flags_SetInfTable(0xD4);
return;
case 34:
if (textId == 0x403c)
Flags_SetInfTable(0xD6);
return;
case 35:
if (textId == 0x5028)
Flags_SetInfTable(0xD8);
return;
case 38:
if (textId == 0x3008)
Flags_SetInfTable(0xE0);
return;
case 40:
if (textId == 0x300B)
Flags_SetInfTable(0xEB);
return;
case 41:
if (textId == 0x3014)
Flags_SetInfTable(0xF0);
return;
case 42:
if (textId == 0x3016)
Flags_SetInfTable(0xF4);
return;
case 43:
if (textId == 0x3018)
{
Flags_SetEventChkInf(0x20);
Flags_SetInfTable(0xF8);
}
return;
case 48:
if (textId == 0x3020)
{
Flags_SetEventChkInf(0x22);
Flags_SetInfTable(0x113);
}
return;
case 49:
case 52:
case 53:
case 54:
if (textId == 0x4006)
Flags_SetEventChkInf(0x30);
return;
case 50:
if (textId == 0x4006)
Flags_SetEventChkInf(0x30);
if (textId == 0x4008)
Flags_SetInfTable(0x124);
return;
case 51:
if (textId == 0x4006)
Flags_SetEventChkInf(0x30);
if (textId == 0x400A)
Flags_SetEventChkInf(0x32);
if (textId == 0x402F)
Flags_SetInfTable(0x12A);
return;
case 55:
if (textId == 0x401B)
{
Flags_SetEventChkInf(0x33);
Flags_SetInfTable(0x138);
}
return;
case 61:
if (textId == 0x5000)
Flags_SetInfTable(0x166);
return;
case 63:
if (textId == 0x5013)
Flags_SetInfTable(0x16A);
return;
case 71:
if (textId == 0x2041)
Flags_SetEventChkInf(0x10);
if (textId == 0x2044)
Flags_SetEventChkInf(0x12);
if (textId == 0x2047)
Flags_SetEventChkInf(0x15);
if (textId == 0x2048)
Flags_SetEventChkInf(0x16);
return;
case 72:
return;
}
}
s32 func_800374E0(GlobalContext* globalCtx, Actor* actor, u16 textId)
{
MessageContext* msgCtx = &globalCtx->msgCtx;
s32 ret = 1;
switch (textId)
{
case 0x1035:
if (msgCtx->choiceIndex == 0)
{
if (Flags_GetInfTable(0x2A))
func_80035B18(globalCtx, actor, 0x1036);
else
func_80035B18(globalCtx, actor, 0x1041);
}
if (msgCtx->choiceIndex == 1)
{
if (Flags_GetInfTable(0x2B))
func_80035B18(globalCtx, actor, 0x1037);
else
func_80035B18(globalCtx, actor, 0x1041);
}
ret = 0;
break;
case 0x1038:
if (msgCtx->choiceIndex == 0)
{
if (Flags_GetInfTable(0x2E))
func_80035B18(globalCtx, actor, 0x1039);
else
func_80035B18(globalCtx, actor, 0x1041);
}
if (msgCtx->choiceIndex == 1)
{
if (Flags_GetInfTable(0x2F))
func_80035B18(globalCtx, actor, 0x103A);
else
func_80035B18(globalCtx, actor, 0x1041);
}
if (msgCtx->choiceIndex == 2)
{
if (Flags_GetInfTable(0x30))
func_80035B18(globalCtx, actor, 0x103B);
else
func_80035B18(globalCtx, actor, 0x1041);
}
ret = 0;
break;
case 0x103E:
if (msgCtx->choiceIndex == 0)
func_80035B18(globalCtx, actor, 0x103F);
if (msgCtx->choiceIndex == 1)
func_80035B18(globalCtx, actor, 0x1040);
ret = 0;
break;
case 0x1041:
if (msgCtx->unk_E2FA == 0x1035)
{
if (msgCtx->choiceIndex == 0)
{
func_80035B18(globalCtx, actor, 0x1036);
Flags_SetInfTable(0x2A);
}
if (msgCtx->choiceIndex == 1)
{
func_80035B18(globalCtx, actor, 0x1037);
Flags_SetInfTable(0x2B);
}
}
if (msgCtx->unk_E2FA == 0x1038)
{
if (msgCtx->choiceIndex == 0)
{
func_80035B18(globalCtx, actor, 0x1039);
Flags_SetInfTable(0x2E);
}
if (msgCtx->choiceIndex == 1)
{
func_80035B18(globalCtx, actor, 0x103A);
Flags_SetInfTable(0x2F);
}
if (msgCtx->choiceIndex == 2)
{
func_80035B18(globalCtx, actor, 0x103B);
Flags_SetInfTable(0x30);
}
}
ret = 0;
break;
case 0x1062:
if (msgCtx->choiceIndex == 0)
func_80035B18(globalCtx, actor, 0x1063);
if (msgCtx->choiceIndex == 1)
func_80035B18(globalCtx, actor, 0x1064);
ret = 0;
break;
case 0x2030:
case 0x2031:
if (msgCtx->choiceIndex == 0)
{
if (gSaveContext.rupees >= 10)
{
func_80035B18(globalCtx, actor, 0x2034);
Rupees_ChangeBy(-10);
}
else
func_80035B18(globalCtx, actor, 0x2032);
}
if (msgCtx->choiceIndex == 1)
func_80035B18(globalCtx, actor, 0x2032);
Flags_SetInfTable(0x9A);
ret = 0;
break;
case 0x2036:
case 0x2037:
if (msgCtx->choiceIndex == 0)
func_80035B18(globalCtx, actor, 0x201F);
if (msgCtx->choiceIndex == 1)
func_80035B18(globalCtx, actor, 0x205A);
ret = 0;
break;
case 0x2038:
if (msgCtx->choiceIndex == 0)
break;
if (msgCtx->choiceIndex == 1)
func_80035B18(globalCtx, actor, 0x205A);
ret = 0;
break;
case 0x2034:
if (msgCtx->choiceIndex != 0)
break;
func_80035B18(globalCtx, actor, 0x2035);
ret = 0;
break;
case 0x2043:
if (Flags_GetEventChkInf(0x12))
break;
func_80035B18(globalCtx, actor, 0x2044);
ret = 0;
break;
case 0x205A:
break;
case 0x300A:
if (msgCtx->choiceIndex == 0)
{
if (Flags_GetEventChkInf(0x22))
func_80035B18(globalCtx, actor, 0x300B);
else
func_80035B18(globalCtx, actor, 0x300C);
}
if (msgCtx->choiceIndex == 1)
func_80035B18(globalCtx, actor, 0x300D);
ret = 0;
break;
case 0x301B:
if (msgCtx->choiceIndex == 0)
{
func_80035B18(globalCtx, actor, 0x301D);
}
if (msgCtx->choiceIndex == 1)
{
if (Flags_GetInfTable(0x113))
func_80035B18(globalCtx, actor, 0x301F);
else
func_80035B18(globalCtx, actor, 0x301E);
}
ret = 0;
break;
case 0x301E:
func_80035B18(globalCtx, actor, 0x3020);
ret = 0;
break;
case 0x400C:
if (msgCtx->choiceIndex == 0)
func_80035B18(globalCtx, actor, 0x400D);
if (msgCtx->choiceIndex == 1)
func_80035B18(globalCtx, actor, 0x400E);
ret = 0;
break;
case 0x7007:
func_80035B18(globalCtx, actor, 0x703E);
ret = 0;
break;
case 0x703E:
func_80035B18(globalCtx, actor, 0x703F);
ret = 0;
break;
case 0x703F:
func_80035B18(globalCtx, actor, 0x7042);
ret = 0;
break;
}
return ret;
}
u16 func_80037C30(GlobalContext* globalCtx, s16 arg1)
{
return func_80035BFC(globalCtx, arg1);
}
s32 func_80037C5C(GlobalContext* globalCtx, s16 arg1, u16 textId)
{
func_80036E50(textId, arg1);
return 0;
}
s32 func_80037C94(GlobalContext* globalCtx, Actor* actor, s32 arg2)
{
return func_800374E0(globalCtx, actor, actor->textId);
}
s32 func_80037CB8(GlobalContext* globalCtx, Actor* actor, s16 arg2)
{
MessageContext* msgCtx = &globalCtx->msgCtx;
s32 ret = 0;
switch (func_8010BDBC(msgCtx))
{
case 2:
func_80037C5C(globalCtx, arg2, actor->textId);
ret = 1;
break;
case 4:
case 5:
if (func_80106BC8(globalCtx) && func_80037C94(globalCtx, actor, arg2))
{
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
msgCtx->msgMode = 0x36;
ret = 1;
}
break;
}
return ret;
}
s32 func_80037D98(GlobalContext* globalCtx, Actor* actor, s16 arg2, s32* arg3)
{
s16 var;
s16 sp2C;
s16 sp2A;
s16 abs_var;
if (func_8002F194(actor, globalCtx))
{
*arg3 = 1;
return 1;
}
if (*arg3 == 1)
{
if (func_80037CB8(globalCtx, actor, arg2))
*arg3 = 0;
return 0;
}
func_8002F374(globalCtx, actor, &sp2C, &sp2A);
if (0) ; // Necessary to match
if ((sp2C < 0) || (sp2C > 320) || (sp2A < 0) || (sp2A > 240))
return 0;
var = actor->rotTowardsLinkY - actor->shape.rot.y;
abs_var = ABS(var);
if (abs_var >= 0x4300)
return 0;
if ((actor->waterSurfaceDist > 25600.0f) && (actor->unk_10C == 0))
return 0;
if (actor->waterSurfaceDist <= 6400.0f)
{
if (func_8002F2CC(actor, globalCtx, 80.0f))
actor->textId = func_80037C30(globalCtx, arg2);
}
else
{
if (func_8002F2F4(actor, globalCtx))
actor->textId = func_80037C30(globalCtx, arg2);
}
return 0;
}
s32 func_80037F30(Vec3s* arg0, Vec3s* arg1)
{
Math_SmoothScaleMaxMinS(&arg0->y, 0, 6, 6200, 100);
Math_SmoothScaleMaxMinS(&arg0->x, 0, 6, 6200, 100);
Math_SmoothScaleMaxMinS(&arg1->y, 0, 6, 6200, 100);
Math_SmoothScaleMaxMinS(&arg1->x, 0, 6, 6200, 100);
return 1;
}
s32 func_80037FC8(Actor* actor, Vec3f* arg1, Vec3s* arg2, Vec3s* arg3)
{
s16 sp36;
s16 sp34;
s16 var;
sp36 = Math_Vec3f_Pitch(&actor->posRot2.pos, arg1);
sp34 = Math_Vec3f_Yaw(&actor->posRot2.pos, arg1) - actor->posRot.rot.y;
Math_SmoothScaleMaxMinS(&arg2->x, sp36, 6, 2000, 1);
arg2->x = (arg2->x < -6000) ? -6000 : ((arg2->x > 6000) ? 6000 : arg2->x);
var = Math_SmoothScaleMaxMinS(&arg2->y, sp34, 6, 2000, 1);
arg2->y = (arg2->y < -8000) ? -8000 : ((arg2->y > 8000) ? 8000 : arg2->y);
if (var && (ABS(arg2->y) < 8000))
return 0;
Math_SmoothScaleMaxMinS(&arg3->y, sp34 - arg2->y, 4, 2000, 1);
arg3->y = (arg3->y < -12000) ? -12000 : ((arg3->y > 12000) ? 12000 : arg3->y);
return 1;
}
s32 func_80038154(GlobalContext* globalCtx, Actor* actor, Vec3s* arg2, Vec3s* arg3, f32 arg4)
{
Player* player = PLAYER;
s32 pad;
Vec3f sp2C;
s16 var;
s16 abs_var;
actor->posRot2.pos = actor->posRot.pos;
actor->posRot2.pos.y += arg4;
if (!(((globalCtx->csCtx.state != 0) || (D_8011D394 != 0)) && (gSaveContext.entrance_index == 0x00EE)))
{
var = actor->rotTowardsLinkY - actor->shape.rot.y;
abs_var = ABS(var);
if (abs_var >= 0x4300)
{
func_80037F30(arg2, arg3);
return 0;
}
}
if (((globalCtx->csCtx.state != 0) || (D_8011D394 != 0)) && (gSaveContext.entrance_index == 0x00EE))
sp2C = globalCtx->view.eye;
else
sp2C = player->actor.posRot2.pos;
func_80037FC8(actor, &sp2C, arg2, arg3);
return 1;
}
s32 func_80038290(GlobalContext* globalCtx, Actor* actor, Vec3s* arg2, Vec3s* arg3, Vec3f arg4)
{
Player* player = PLAYER;
s32 pad;
Vec3f sp24;
s16 var;
s16 abs_var;
actor->posRot2.pos = arg4;
if (!(((globalCtx->csCtx.state != 0) || (D_8011D394 != 0)) && (gSaveContext.entrance_index == 0x00EE)))
{
var = actor->rotTowardsLinkY - actor->shape.rot.y;
abs_var = ABS(var);
if (abs_var >= 0x4300)
{
func_80037F30(arg2, arg3);
return 0;
}
}
if (((globalCtx->csCtx.state != 0) || (D_8011D394 != 0)) && (gSaveContext.entrance_index == 0x00EE))
sp24 = globalCtx->view.eye;
else
sp24 = player->actor.posRot2.pos;
func_80037FC8(actor, &sp24, arg2, arg3);
return 1;
}