Files
tp/src/d/actor/d_a_spinner.cpp
T
TakaRikka 850fae1aa3 m_Do_main / f_ap_game / f_op_actor debug work and misc (#2744)
* m_Do_main / f_ap_game debug stuff

* revolution sdk compatibility

* f_op_actor debug work

* rename fopAcM_SetupActor to fopAcM_ct

* fix build

* fix jp/pal splits
2025-10-19 20:30:49 +03:00

989 lines
32 KiB
C++

/**
* @file d_a_spinner.cpp
*
*/
#include "d/dolzel_rel.h" // IWYU pragma: keep
#include "d/actor/d_a_spinner.h"
#include "d/actor/d_a_tag_sppath.h"
#include "dol2asm.h"
#include "d/actor/d_a_alink.h"
#include "d/actor/d_a_mirror.h"
#include "Z2AudioLib/Z2Instances.h"
#include "SSystem/SComponent/c_math.h"
#include "m_Do/m_Do_controller_pad.h"
/* 804D4D90-804D4D9C 000000 000C+00 9/9 0/0 0/0 .rodata @3768 */
static u8 const lit_3768[12] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
/* 804D198C-804D1A50 0000EC 00C4+00 1/1 0/0 0/0 .text createHeap__11daSpinner_cFv */
int daSpinner_c::createHeap() {
J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes(daAlink_c::getAlinkArcName(), 0x21);
mpModel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084);
if (mpModel == NULL) {
return 0;
}
mpSpoutBck = (J3DAnmTransform*)dComIfG_getObjectRes(daAlink_c::getAlinkArcName(), 0x16);
if (!mBck.init(mpSpoutBck, 1, 2, 1.0f, 0, -1, false)) {
return 0;
}
return 1;
}
/* 804D1A50-804D1A70 0001B0 0020+00 1/1 0/0 0/0 .text daSpinner_createHeap__FP10fopAc_ac_c */
static int daSpinner_createHeap(fopAc_ac_c* i_this) {
return ((daSpinner_c*)i_this)->createHeap();
}
/* 804D4EA8-804D4EEC 000000 0044+00 1/1 0/0 0/0 .data l_cylSrc */
static dCcD_SrcCyl l_cylSrc = {
{
{0, {{AT_TYPE_SPINNER, 1, 0x12}, {0, 0}, 0x69}},
{dCcD_SE_SPINNER, 1, 0, 0, {0}},
{dCcD_SE_NONE, 0, 0, 0, {0}},
{0},
},
{
{0.0f, 0.0f, 0.0f},
40.0f,
85.0f,
}
};
/* 804D1A70-804D1D60 0001D0 02F0+00 1/1 0/0 0/0 .text create__11daSpinner_cFv */
int daSpinner_c::create() {
fopAcM_ct(this, daSpinner_c);
if (!fopAcM_entrySolidHeap(this, daSpinner_createHeap, 0x900)) {
return cPhs_ERROR_e;
}
daAlink_c* player = daAlink_getAlinkActorClass();
mAcch.Set(this, 3, mAcchCir);
mAcch.SetWaterCheckOffset(10000.0f);
mAcch.OnLineCheck();
mAcch.SetWtrChkMode(2);
mAcchCir[0].SetWall(50.01f, 58.0f);
mAcchCir[1].SetWall(129.99f, 35.0f);
mAcchCir[2].SetWall(player->field_0x598, 35.0f);
mPaPo.init(&mAcch, 85.0f, 85.0f);
mSound.init(&current.pos, 1);
mStts.Init(200, 0, this);
mCyl.Set(l_cylSrc);
mCyl.SetStts(&mStts);
mCyl.StartCAt(current.pos);
this->model = mpModel;
gravity = player->getSpinnerGravity();
maxFallSpeed = player->getSpinnerMaxFallSpeed();
field_0xa76 = 1;
mAcch.CrrPos(dComIfG_Bgsp());
fopAcM_setStageLayer(this);
mBck.setFrame(mBck.getEndFrame());
mBck.setPlaySpeed(0.0f);
setMatrix();
setRoomInfo();
field_0xa82 = 0x82F;
return cPhs_COMPLEATE_e;
}
/* 804D1FB0-804D1FD0 000710 0020+00 1/0 0/0 0/0 .text daSpinner_Create__FP10fopAc_ac_c */
static int daSpinner_Create(fopAc_ac_c* i_this) {
return ((daSpinner_c*)i_this)->create();
}
/* 804D1FD0-804D21B8 000730 01E8+00 1/1 0/0 0/0 .text __dt__11daSpinner_cFv */
daSpinner_c::~daSpinner_c() {
mSound.deleteObject();
clearSpreadEffect();
clearPathMove();
}
/* 804D21B8-804D21E0 000918 0028+00 1/0 0/0 0/0 .text daSpinner_Delete__FP11daSpinner_c
*/
static int daSpinner_Delete(daSpinner_c* i_this) {
i_this->~daSpinner_c();
return 1;
}
/* 804D21E0-804D2278 000940 0098+00 2/2 0/0 0/0 .text setRoomInfo__11daSpinner_cFv */
void daSpinner_c::setRoomInfo() {
int roomNo;
if (mAcch.GetGroundH() != -G_CM3D_F_INF) {
roomNo = dComIfG_Bgsp().GetRoomId(mAcch.m_gnd);
tevStr.YukaCol = dComIfG_Bgsp().GetPolyColor(mAcch.m_gnd);
} else {
roomNo = dComIfGp_roomControl_getStayNo();
}
tevStr.room_no = roomNo;
mReverb = dComIfGp_getReverb(roomNo);
mStts.SetRoomId(roomNo);
fopAcM_SetRoomNo(this, roomNo);
}
/* 804D2278-804D2320 0009D8 00A8+00 2/2 0/0 0/0 .text setMatrix__11daSpinner_cFv */
void daSpinner_c::setMatrix() {
mDoMtx_stack_c::transS(current.pos.x, current.pos.y + field_0xa84 + 90.0f, current.pos.z);
mDoMtx_stack_c::ZXYrotM(shape_angle);
mDoMtx_stack_c::YrotM(mRotY);
mpModel->setBaseTRMtx(mDoMtx_stack_c::get());
mBck.entry(mpModel->getModelData());
mpModel->calc();
}
/* 804D2320-804D25F4 000A80 02D4+00 1/1 0/0 0/0 .text setEffect__11daSpinner_cFv */
void daSpinner_c::setEffect() {
static JGeometry::TVec3<f32> effDirection(0.0f, 1.0f, 0.0f);
static cXyz particleScale(1.5f, 1.5f, 1.5f);
cXyz effCenter(current.pos);
cXyz* sp24 = NULL;
if (mAcch.ChkWaterHit() && dComIfG_Bgsp().GetPolyAtt0(mAcch.m_wtr) != 6) {
if (mAcch.m_wtr.GetHeight() > mAcch.GetGroundH() && mAcch.m_wtr.GetHeight() > effCenter.y) {
effCenter.y = mAcch.m_wtr.GetHeight();
sp24 = &effCenter;
}
}
if (sp24 == NULL && mAcch.ChkGroundHit()) {
effCenter.y = mAcch.GetGroundH();
int sp20 = dComIfG_Bgsp().GetGroundCode(mAcch.m_gnd);
if (sp20 != 4 && sp20 != 10) {
sp24 = &effCenter;
}
}
mPaPo.setEffectCenter(&tevStr, &effCenter, 4, 0x60000, sp24, &current.angle, NULL, fopAcM_GetRoomNo(this), 0.0f, speedF);
for (int i = 0; i < 2; i++) {
u8 eff_type = mPaPo.getCenterEffType(i);
for (int j = 0; j < 4; j++) {
JPABaseEmitter* emitter = mPaPo.getCenterEmitter(i, j);
if (emitter != NULL) {
emitter->setDirection(effDirection);
if (eff_type == 0) {
emitter->setDirectionalSpeed(1.0f);
emitter->setGlobalParticleScale(particleScale);
} else if (eff_type == 1) {
emitter->setAwayFromCenterSpeed(3.0f);
emitter->setAwayFromAxisSpeed(3.0f);
emitter->setDirectionalSpeed(3.0f);
} else if (eff_type == 3) {
emitter->setRate(1.5f);
emitter->setAwayFromAxisSpeed(1.0f);
emitter->setGlobalParticleScale(particleScale);
} else if (eff_type == 4) {
emitter->setRate(1.5f);
emitter->setAwayFromCenterSpeed(2.0f);
emitter->setGlobalParticleScale(particleScale);
}
}
}
}
}
/* 804D25F4-804D3048 000D54 0A54+00 1/1 0/0 0/0 .text posMove__11daSpinner_cFv */
int daSpinner_c::posMove() {
daAlink_c* player = daAlink_getAlinkActorClass();
f32 move_speed;
if (!player->checkDemoSpinnerKeep()) {
if (player->checkDemoSpinnerKeepSpeed()) {
speedF = player->getSpinnerRideSpeedF();
}
move_speed = speedF * cM_scos(current.angle.x);
} else {
move_speed = 0.0f;
}
if (mpPathMove == NULL) {
speed.y += gravity;
if (speed.y < maxFallSpeed) {
speed.y = maxFallSpeed;
}
}
current.pos.x += move_speed * cM_ssin(current.angle.y);
current.pos.y += speed.y - (speedF * cM_ssin(current.angle.x));
current.pos.z += move_speed * cM_scos(current.angle.y);
if (mpPathMove != NULL) {
f32 var_f31 = speedF;
cM3dGLin sp60;
cXyz sp54;
while (var_f31 > 0.0f) {
Vec* curr_path_pos = &mpPathMove->m_points[mPathNo].m_position;
Vec* next_path_pos = getPathNextPos();
cXyz sp48(current.pos.x, current.pos.y - -20.0f, current.pos.z);
cXyz sp3C(curr_path_pos->x - next_path_pos->x, curr_path_pos->y - next_path_pos->y, curr_path_pos->z - next_path_pos->z);
int spC;
s16 spA = sp3C.atan2sX_Z();
sp3C.normalizeZP();
sp3C *= 58.0f;
sp3C.x += curr_path_pos->x;
sp3C.y += curr_path_pos->y;
sp3C.z += curr_path_pos->z;
sp60.set(sp3C, *next_path_pos);
f32 sp10;
if (!cM3d_Len3dSqPntAndSegLine(&sp60, &sp48, &sp54, &sp10)) {
if (setNextPathNum() && (mPathNo == 0 || mPathNo == mpPathMove->m_num - 1) && !dPath_ChkClose(mpPathMove)) {
var_f31 = 0.0f;
if (mpPathMove->m_points[mPathNo].mArg0 == 0) {
u8 sp8 = mPathNo;
setReflectAngle();
mPathNo = sp8;
if ((s16)(cM_atan2s(current.pos.x - next_path_pos->x, current.pos.z - next_path_pos->z) - spA) > 0) {
spA += 0x4000;
} else {
spA -= 0x4000;
}
field_0xab0.set(next_path_pos->x, next_path_pos->y, next_path_pos->z);
current.pos.set(next_path_pos->x + (52.199997f * cM_ssin(spA)), -20.0f + next_path_pos->y, next_path_pos->z + (52.199997f * cM_scos(spA)));
} else {
clearPathMove();
field_0xa74 = 1;
}
} else {
var_f31 -= field_0xab0.abs(*next_path_pos);
field_0xab0.set(next_path_pos->x, next_path_pos->y, next_path_pos->z);
sp3C = sp48 - field_0xab0;
if ((s16)(sp3C.atan2sX_Z() - current.angle.y) > 0) {
spC = 1;
} else {
spC = -1;
}
}
if (mpPathMove != NULL) {
curr_path_pos = &mpPathMove->m_points[mPathNo].m_position;
next_path_pos = getPathNextPos();
sp3C.set(next_path_pos->x - curr_path_pos->x, next_path_pos->y - curr_path_pos->y, next_path_pos->z - curr_path_pos->z);
spA = current.angle.y;
current.angle.y = sp3C.atan2sX_Z();
current.angle.x = sp3C.atan2sY_XZ();
if (var_f31 > 0.0f) {
spA = current.angle.y - spA;
var_f31 += 0.0055606803f * spA * spC;
if (var_f31 > 0.0f) {
sp3C.normalizeZP();
spA = current.angle.y + (spC << 0xE);
current.pos.set(curr_path_pos->x + (sp3C.x * var_f31), -20.0f + (curr_path_pos->y + (sp3C.y * var_f31)), curr_path_pos->z + (sp3C.z * var_f31));
} else {
spA = (spC << 0xE) + (current.angle.y + (spC * (179.8341f * fabsf(var_f31))));
current.pos.set(curr_path_pos->x, -20.0f + curr_path_pos->y, curr_path_pos->z);
}
current.pos.x += 29.0f * cM_ssin(spA);
current.pos.z += 29.0f * cM_scos(spA);
old.pos = current.pos;
}
}
} else {
var_f31 = 0.0f;
field_0xab0 = sp54;
}
}
} else if (mStts.GetCCMoveP() != NULL) {
current.pos += *mStts.GetCCMoveP();
}
mAcch.CrrPos(dComIfG_Bgsp());
if (mpPathMove == NULL) {
if (!mJumpFlg) {
if (!mAcch.ChkGroundHit()) {
if (current.angle.x < 0) {
mJumpFlg = true;
speed.y = speedF;
if (speed.y > player->getSpinnerRideSpeedF()) {
speed.y = player->getSpinnerRideSpeedF();
}
speed.y *= -player->getSpinnerJumpRate() * cM_ssin(current.angle.x);
} else {
f32 temp_f28 = mAcch.GetGroundH() - current.pos.y;
f32 var_f29 = current.pos.absXZ(old.pos) * cM_ssin(fopAcM_getPolygonAngle(mAcch.m_gnd, current.angle.y));
if (var_f29 < 0.0f) {
var_f29 = 0.0f;
}
if (temp_f28 < 0.0f && temp_f28 >= -mAcchCir[0].GetWallH() - var_f29) {
current.pos.y = mAcch.GetGroundH();
mAcch.SetGroundHit();
speed.y = 0.0f;
} else {
mJumpFlg = true;
}
}
}
} else if (mAcch.ChkGroundHit()) {
mJumpFlg = false;
} else {
mJumpFlg = true;
}
}
if (mAcch.ChkWaterHit()) {
f32 temp_f27 = mAcch.m_wtr.GetHeight() - current.pos.y;
if ((temp_f27 > 50.0f || (dComIfG_Bgsp().GetPolyAtt0(mAcch.m_wtr) == 6 && temp_f27 >= 0.0f))) {
mDeleteFlg = true;
return 0;
}
}
return 1;
}
/* 804D3090-804D3174 0017F0 00E4+00 3/3 0/0 0/0 .text setReflectAngle__11daSpinner_cFv */
void daSpinner_c::setReflectAngle() {
if (mpPathMove != NULL) {
current.angle.y += 0x8000;
current.angle.x *= -1;
setNextPathNum();
mPathDirection *= -1;
field_0xa76 *= -1;
} else {
s16 angle = current.angle.y - field_0xa80;
if (abs(angle) > 0x4800) {
current.angle.y = (field_0xa80 << 1) - (current.angle.y + 0x8000);
} else if (angle > 0x3800) {
current.angle.y = field_0xa80 + 0x3800;
} else if (angle < -0x3800) {
current.angle.y = field_0xa80 - 0x3800;
}
}
}
/* 804D3174-804D3468 0018D4 02F4+00 1/1 0/0 0/0 .text setWallHit__11daSpinner_cFsUl */
void daSpinner_c::setWallHit(s16 param_0, u32 param_1) {
field_0xa80 = param_0;
setReflectAngle();
cXyz line_start(current.pos.x, current.pos.y + mAcchCir[0].GetWallH(), current.pos.z);
cXyz line_end(current.pos.x - (mAcchCir[0].GetWallR() * cM_ssin(param_0)), line_start.y, current.pos.z - (mAcchCir[0].GetWallR() * cM_scos(param_0)));
mLinChk.Set(&line_start, &line_end, this);
csXyz spC;
cXyz* var_r29;
if (dComIfG_Bgsp().LineCross(&mLinChk)) {
cM3dGPla plane;
dComIfG_Bgsp().GetTriPla(mLinChk, &plane);
var_r29 = mLinChk.GetCrossP();
spC.set(cM_atan2s(plane.mNormal.y, plane.mNormal.absXZ()), cM_atan2s(-plane.mNormal.x, -plane.mNormal.z), 0);
} else {
var_r29 = &line_end;
spC.set(0, param_0 + 0x8000, 0);
}
if (field_0xa78 == 0) {
daAlink_getAlinkActorClass()->itemHitSE(Z2SE_HIT_SPINNER, param_1, &mSound);
field_0xa78 = 10;
if (field_0xa79 == 0) {
dComIfGp_getVibration().StartShock(VIBMODE_S_POWER1, 1, cXyz(0.0f, 1.0f, 0.0f));
dComIfGp_setHitMark(9, NULL, var_r29, &spC, NULL, 0);
}
}
}
/* 804D34B0-804D3618 001C10 0168+00 1/1 0/0 0/0 .text setAnm__11daSpinner_cFv */
void daSpinner_c::setAnm() {
if (mBck.isStop() && mTrigJump) {
mBck.init(mpSpoutBck, 1, -1, 1.0f, 0, -1, true);
daAlink_getAlinkActorClass()->seStartOnlyReverb(Z2SE_AL_SPINNER_EXTEND);
dComIfGp_getVibration().StartShock(2, 1, cXyz(0.0f, 1.0f, 0.0f));
if (!mJumpFlg) {
speed.y = 20.0f;
mJumpFlg = true;
mButtonJump = true;
}
if (mpPathMove != NULL) {
s16 targetAngle = cLib_targetAngleY(&mpPathMove->m_points[mPathNo].m_position, &current.pos);
if (s16(targetAngle - current.angle.y) > 0) {
current.angle.y += 0x3000;
} else {
current.angle.y -= 0x3000;
}
clearPathMove();
mAcch.ClrWallHit();
}
}
}
/* 804D3618-804D3694 001D78 007C+00 2/2 0/0 0/0 .text setNextPathNum__11daSpinner_cFv */
int daSpinner_c::setNextPathNum() {
if (mPathNo == 0 && mPathDirection == -1) {
mPathNo = mpPathMove->m_num - 1;
} else if (mPathNo == mpPathMove->m_num - 1 && mPathDirection == 1) {
mPathNo = 0;
} else {
mPathNo += mPathDirection;
return 1;
}
return 0;
}
/* 804D3694-804D36F4 001DF4 0060+00 1/1 0/0 0/0 .text getPathNextPos__11daSpinner_cFv */
Vec* daSpinner_c::getPathNextPos() {
int next_point_no = mPathNo + mPathDirection;
if (next_point_no < 0) {
return &(mpPathMove->m_points + mpPathMove->m_num - 1)->m_position;
}
if (next_point_no >= mpPathMove->m_num) {
return &mpPathMove->m_points[0].m_position;
}
return &mpPathMove->m_points[next_point_no].m_position;
}
/* 804D36F4-804D3774 001E54 0080+00 1/1 0/0 0/0 .text checkLineWallHit__11daSpinner_cFP4cXyzP4cXyz
*/
int daSpinner_c::checkLineWallHit(cXyz* i_start, cXyz* i_end) {
mLinChk.Set(i_start, i_end, this);
if (dComIfG_Bgsp().LineCross(&mLinChk)) {
if (dBgS_CheckBWallPoly(mLinChk) || daAlink_c::checkStageName("D_MN10A")) {
return 1;
}
}
return 0;
}
/* 804D3774-804D3D60 001ED4 05EC+00 1/1 0/0 0/0 .text checkPathMove__11daSpinner_cFv */
int daSpinner_c::checkPathMove() {
if (mpPathMove != NULL) {
return 1;
}
daTagSppath_c* sppath_tag = (daTagSppath_c*)mCyl.GetAtHitAc();
if (mCyl.ChkAtHit() && mSpinnerTag == TAG_NONE && sppath_tag != NULL && fopAcM_GetName(sppath_tag) == PROC_Tag_Sppath) {
if (sppath_tag->getKeepPath() == field_0xa68) {
return 0;
}
dComIfGp_getVibration().StartShock(VIBMODE_S_POWER2, 1, cXyz(0.0f, 1.0f, 0.0f));
mpPathMove = sppath_tag->getKeepPath();
field_0xa68 = mpPathMove;
mJumpFlg = false;
speed.y = 0.0f;
int var_r27 = sppath_tag->getKeepPointNum();
int sp10;
if (var_r27 != mpPathMove->m_num - 1) {
sp10 = var_r27 + 1;
} else if (dPath_ChkClose(mpPathMove)) {
sp10 = 0;
} else {
sp10 = var_r27;
var_r27--;
}
dPnt* temp_r26 = &mpPathMove->m_points[var_r27];
dPnt* temp_r25 = &mpPathMove->m_points[sp10];
cXyz sp50(temp_r25->m_position.x - temp_r26->m_position.x,
temp_r25->m_position.y - temp_r26->m_position.y,
temp_r25->m_position.z - temp_r26->m_position.z);
s16 sp8 = sp50.atan2sX_Z();
cXyz sp44;
cXyz sp38;
cXyz sp2C;
cXyz sp20;
static const Vec sideCheckVec0 = {30.0f, 10.0f, 5.0f};
static const Vec sideCheckVec1 = {-30.0f, 10.0f, 5.0f};
static const Vec initSide0 = {53.0f, 0.0f, 0.0f};
static const Vec initSide1 = {-53.0f, 0.0f, 0.0f};
static const Vec initSideOld0 = {78.0f, 0.0f, 0.0f};
static const Vec initSideOld1 = {-78.0f, 0.0f, 0.0f};
mDoMtx_stack_c::transS(sppath_tag->current.pos);
mDoMtx_stack_c::YrotM(sp8);
mDoMtx_stack_c::multVec(&sideCheckVec0, &sp44);
mDoMtx_stack_c::multVec(&sideCheckVec1, &sp38);
int var_r24 = 0;
int spC = 1;
cM3dGPla sp5C;
if (checkLineWallHit(&sp44, &sp38)) {
var_r24 = 1;
mDoMtx_stack_c::multVec(&initSide0, &sp2C);
mDoMtx_stack_c::multVec(&initSideOld0, &sp20);
} else if (checkLineWallHit(&sp38, &sp44)) {
var_r24 = 1;
mDoMtx_stack_c::multVec(&initSide1, &sp2C);
mDoMtx_stack_c::multVec(&initSideOld1, &sp20);
spC = 0;
} else {
mDoMtx_stack_c::YrotM(-0x8000);
mDoMtx_stack_c::multVec(&sideCheckVec1, &sp44);
mDoMtx_stack_c::multVec(&sideCheckVec0, &sp38);
if (checkLineWallHit(&sp44, &sp38)) {
var_r24 = 1;
mDoMtx_stack_c::multVec(&initSide1, &sp2C);
mDoMtx_stack_c::multVec(&initSideOld1, &sp20);
} else if (checkLineWallHit(&sp38, &sp44)) {
var_r24 = 1;
mDoMtx_stack_c::multVec(&initSide0, &sp2C);
mDoMtx_stack_c::multVec(&initSideOld0, &sp20);
spC = 0;
}
}
if (sppath_tag->checkDirectionFront() || (sppath_tag->checkDirectionNone() && cLib_distanceAngleS(sp8, current.angle.y) < 0x4000)) {
current.angle.y = sp8;
current.angle.x = sp50.atan2sY_XZ();
mPathNo = var_r27;
mPathDirection = 1;
if (spC != 0) {
field_0xa76 = -1;
} else {
field_0xa76 = 1;
}
} else {
current.angle.y = sp8 + 0x8000;
current.angle.x = cM_atan2s(sp50.y, sp50.absXZ());
mPathNo = sp10;
mPathDirection = -1;
if (spC != 0) {
field_0xa76 = 1;
} else {
field_0xa76 = -1;
}
}
if (var_r24 != 0) {
current.pos = sp2C;
old.pos = sp20;
old.pos.y += -20.0f;
} else {
current.pos = sppath_tag->current.pos;
}
field_0xab0 = current.pos;
current.pos.y += -20.0f;
mAcchCir[0].SetWallR(58.0f);
mCyl.SetR(58.0f);
mRideMoveTime = daAlink_getAlinkActorClass()->getSpinnerRideMoveTime();
if (mpPathMove->field_0x7 == 0xFF) {
speedF = daAlink_getAlinkActorClass()->getSpinnerRideSpeedF();
} else {
speedF = mpPathMove->field_0x7;
}
return 1;
}
field_0xa68 = 0;
return 0;
}
/* 804D3D60-804D3F14 0024C0 01B4+00 1/1 0/0 0/0 .text setSpreadEffect__11daSpinner_cFv */
void daSpinner_c::setSpreadEffect() {
u32* emitter_id = mSpreadEmitterIDs;
mDoMtx_stack_c::copy(mpModel->getBaseTRMtx());
if (field_0xa76 < 0) {
mDoMtx_stack_c::XrotM(0x7FFF);
}
mDoMtx_stack_c::get()[1][3] -= 10.0f;
for (int i = 0; i < 2; i++, emitter_id++) {
JPABaseEmitter* emitter = dComIfGp_particle_getEmitter(*emitter_id);
if (reflectAccept() || (emitter != NULL && !emitter->isEnableDeleteEmitter())) {
static const u16 effName[2] = {0x8C5, 0x8C6};
*emitter_id = dComIfGp_particle_set(*emitter_id, effName[i], &current.pos, &shape_angle, NULL);
}
emitter = dComIfGp_particle_getEmitter(*emitter_id);
if (emitter != NULL) {
emitter->setGlobalRTMatrix(mDoMtx_stack_c::get());
}
}
}
/* 804D3F14-804D3F8C 002674 0078+00 2/2 0/0 0/0 .text clearSpreadEffect__11daSpinner_cFv
*/
void daSpinner_c::clearSpreadEffect() {
for (int i = 0; i < 2; i++) {
JPABaseEmitter* emitter = dComIfGp_particle_getEmitter(mSpreadEmitterIDs[i]);
if (emitter != NULL) {
emitter->stopDrawParticle();
}
}
}
/* 804D3F8C-804D4B94 0026EC 0C08+00 1/1 0/0 0/0 .text execute__11daSpinner_cFv */
int daSpinner_c::execute() {
if (mDeleteFlg) {
clearSpreadEffect();
fopAcM_delete(this);
return 1;
}
int sp24 = 0;
mButtonJump = false;
daAlink_c* player = daAlink_getAlinkActorClass();
if (!player->checkGameOverWindow() && field_0xa78 != 0) {
field_0xa78--;
}
f32 pad_stick_value;
s16 move_angle;
if (dComIfGp_event_runCheck()) {
pad_stick_value = 0.0f;
move_angle = 0;
mTrigJump = false;
} else {
if (mSpinnerTag != TAG_NONE || mpPathMove != NULL || (mJumpFlg && daAlink_c::checkStageName("D_MN10A") && dComIfGs_isZoneSwitch(6, dComIfGp_roomControl_getStayNo()) && dComIfGs_isZoneSwitch(7, dComIfGp_roomControl_getStayNo()))) {
pad_stick_value = 0.0f;
} else {
pad_stick_value = mDoCPd_c::getStickValue(PAD_1);
}
move_angle = (mDoCPd_c::getStickAngle3D(PAD_1) + 0x10000 + dCam_getControledAngleY(dComIfGp_getCamera(dComIfGp_getPlayerCameraID(0)))) - 0x8000;
#if VERSION == VERSION_SHIELD_DEBUG
if (dComIfG_getTrigB(PAD_1) && dComIfGp_getSelectItem(3) == fpcNm_ITEM_SPINNER) {
#else
if (dComIfG_getTrigA(PAD_1)) {
#endif
mTrigJump = true;
} else {
mTrigJump = false;
}
if (fopAcM_GetParam(this) != 0 && mSpinnerTag == TAG_NONE) {
setAnm();
}
}
if (mPathForceRemove) {
if (mpPathMove != NULL) {
clearPathMove();
mAcch.ClrWallHit();
}
mPathForceRemove = false;
}
bool sp10 = player->checkSpinnerRideOwn(this);
mRotY += field_0xa82 * field_0xa76;
if (reflectAccept()) {
mRotY += field_0xa76 * 2000;
}
mBck.play();
mSound.framework(0, mReverb);
if (fopAcM_GetParam(this) == 0) {
field_0xa7c += (int)(2330.0f * (0.85f + cM_rndF(0.3f)));
field_0xa84 = 5.0f * cM_ssin(field_0xa7c);
field_0xa98 = current.pos;
if (sp10 != 0) {
current.angle.y = player->current.angle.y;
} else if (!player->checkSpinnerReady()) {
clearSpreadEffect();
fopAcM_delete(this);
return 1;
}
} else if (mSpinnerTag != TAG_NONE) {
mRideMoveTime = player->getSpinnerRideMoveTime();
speedF = player->getSpinnerRideSpeedF();
mJumpFlg = false;
field_0xa76 = 1;
if (mSpinnerTag == TAG_START) {
clearPathMove();
f32 temp_f30 = current.pos.y;
if (cLib_chasePosXZ(&current.pos, field_0xaa4, speedF)) {
mSpinnerTag = 2;
speed.y = 0.0f;
field_0xa84 = 0.0f;
current.pos.y = temp_f30;
}
} else if (mSpinnerTag == 2) {
speed.y += gravity;
if (speed.y < maxFallSpeed) {
speed.y = maxFallSpeed;
}
if (cLib_chaseF(&current.pos.y, field_0xaa4.y, fabsf(speed.y))) {
mSpinnerTag = TAG_INTO;
field_0xa82 = 0x800;
dComIfGp_particle_setPolyColor(0xE7, mAcch.m_gnd, &player->current.pos, &tevStr, NULL, NULL, 0, NULL, -1, NULL);
dComIfGp_getVibration().StartShock(VIBMODE_S_POWER4, 1, cXyz(0.0f, 1.0f, 0.0f));
}
} else {
current.pos = field_0xaa4;
if (mSpinnerTag != TAG_END) {
if (!dComIfGp_event_runCheck() && mTrigJump) {
field_0xa82 += 0x200;
if (field_0xa82 > 5000) {
field_0xa82 = 5000;
}
mSpinnerTag = TAG_INTO_INC_ROT;
} else {
field_0xa82 -= 0x40;
if (field_0xa82 < 0) {
field_0xa82 = 0;
}
mSpinnerTag = TAG_INTO;
}
}
}
} else {
field_0xa82 = 0x82F;
cLib_chaseF(&field_0xa84, 0.0f, 0.5f);
if (mRideMoveTime == 0) {
if (cLib_addCalc(&speedF, 0.0f, player->getSpinnerRideDecSpeedRate(), player->getSpinnerRideDecSpeedMax(), player->getSpinnerRideDecSpeedMin()) < 0.1f) {
mDeleteFlg = true;
return 1;
}
} else if (!player->checkDemoSpinnerKeep() && mpPathMove == NULL) {
mRideMoveTime--;
}
cM3dGPla tri;
s16 sp12;
if (mAcch.ChkGroundHit()) {
dComIfG_Bgsp().GetTriPla(mAcch.m_gnd, &tri);
sp12 = tri.mNormal.atan2sX_Z();
}
if (!checkPathMove()) {
if (mAcch.ChkWallHit() && field_0xa74 == 0) {
dBgS_AcchCir* acch_cir = mAcchCir;
for (int i = 0; i < 3; i++, acch_cir++) {
if (acch_cir->ChkWallHit()) {
setWallHit(acch_cir->GetWallAngleY(), dKy_pol_sound_get(acch_cir));
break;
}
}
} else if (mAcch.ChkGroundHit() && tri.mNormal.y < player->getSlideLimit() && dComIfG_Bgsp().GetSpecialCode(mAcch.m_gnd) != 2 && abs((s16)(sp12 - current.angle.y)) > 0x4000) {
setWallHit(sp12, dKy_pol_sound_get(&mAcch.m_gnd));
} else if (mCyl.ChkAtHit() && (mCyl.ChkAtShieldHit() || (mCyl.GetAtHitGObj() != NULL && ((dCcD_GObjInf*)mCyl.GetAtHitGObj())->ChkTgSpinnerReflect()))) {
cXyz sp58;
if (mCyl.GetAtHitAc() != NULL) {
sp58 = current.pos - mCyl.GetAtHitAc()->current.pos;
} else {
sp58 = current.pos - *mCyl.GetAtHitPosP();
}
field_0xa80 = sp58.atan2sX_Z();
setReflectAngle();
} else if (sp10 != 0 && pad_stick_value > 0.3f) {
cLib_addCalcAngleS(&current.angle.y, move_angle, 4, player->getSpinnerRideRotAngleMax(), player->getSpinnerRideRotAngleMin());
}
}
if (sp10 != 0) {
mCyl.OffCoSPrmBit(0x10);
} else {
mCyl.OnCoSPrmBit(0x10);
}
field_0xa74 = 0;
}
s16 var_r27;
if (mSpinnerTag != TAG_NONE || mpPathMove != NULL || sp24 != 0) {
var_r27 = 0;
} else {
var_r27 = ((shape_angle.y - current.angle.y) / player->getSpinnerRideRotAngleMax()) * 1500;
}
cLib_addCalcAngleS(&shape_angle.z, var_r27, 3, 300, 50);
if (mSpinnerTag != TAG_NONE || mpPathMove != NULL) {
var_r27 = 0;
} else {
var_r27 = 2000.0f * (speedF / player->getSpinnerRideSpeedF());
if (var_r27 > 2000) {
var_r27 = 2000;
}
}
cLib_addCalcAngleS(&shape_angle.x, var_r27, 3, 300, 50);
shape_angle.y = current.angle.y;
if (mSpinnerTag == TAG_NONE) {
if (!player->checkGameOverWindow() && !posMove()) {
return 1;
}
if (!dComIfGp_event_runCheck() && speedF > 3.0f && field_0xa98.abs2XZ(current.pos) < 9.0f) {
field_0xa79++;
if (field_0xa79 > 30) {
mDeleteFlg = true;
}
} else {
field_0xa79 = 0;
field_0xa98 = current.pos;
}
} else {
field_0xa79 = 0;
field_0xa98 = current.pos;
cXyz sp4C(speed);
mAcch.CrrPos(dComIfG_Bgsp());
current.pos = field_0xa98;
speed = sp4C;
}
setRoomInfo();
setMatrix();
setEffect();
if (mpPathMove == NULL) {
if (mAcch.ChkGroundHit()) {
current.angle.x = fopAcM_getPolygonAngle(mAcch.m_gnd, current.angle.y);
} else {
current.angle.x = 0;
}
}
mCyl.MoveCAt(current.pos);
dComIfG_Ccsp()->Set(&mCyl);
g_dComIfG_gameInfo.play.mCcs.mMass_Mng.Set(&mCyl, 1);
if (reflectAccept()) {
if (mpPathMove != NULL) {
mAcchCir[0].SetWallR(58.0f);
mCyl.SetR(58.0f);
} else {
mAcchCir[0].SetWallR(100.0f);
mCyl.SetR(100.0f);
}
mCyl.SetAtAtp(2);
} else {
mAcchCir[0].SetWallR(58.0f);
mCyl.SetR(58.0f);
mCyl.SetAtAtp(1);
}
setSpreadEffect();
return 1;
}
/* 804D4B94-804D4BB4 0032F4 0020+00 1/0 0/0 0/0 .text daSpinner_Execute__FP11daSpinner_c
*/
static int daSpinner_Execute(daSpinner_c* i_this) {
return i_this->execute();
}
/* 804D4BB4-804D4D08 003314 0154+00 1/1 0/0 0/0 .text draw__11daSpinner_cFv */
int daSpinner_c::draw() {
g_env_light.settingTevStruct(0, &current.pos, &tevStr);
g_env_light.setLightTevColorType_MAJI(mpModel, &tevStr);
if ((daAlink_getAlinkActorClass()->checkSpinnerReady() && daAlink_getAlinkActorClass()->gravity >= 0.0f) || mDeleteFlg) {
return 1;
}
mDoExt_modelEntryDL(mpModel);
daMirror_c::entry(mpModel);
if (!daAlink_getAlinkActorClass()->checkSpinnerRideOwn(this)) {
cXyz sp8(current.pos.x, 70.0f + current.pos.y, current.pos.z);
field_0xa94 = dComIfGd_setShadow(field_0xa94, 1, mpModel, &sp8, 300.0f, 0.0f, sp8.y, mAcch.GetGroundH(), mAcch.m_gnd, &tevStr, 0, 1.0f, dDlst_shadowControl_c::getSimpleTex());
}
return 1;
}
/* 804D4D08-804D4D28 003468 0020+00 1/0 0/0 0/0 .text daSpinner_Draw__FP11daSpinner_c */
static int daSpinner_Draw(daSpinner_c* i_this) {
return i_this->draw();
}
/* 804D4EEC-804D4F0C -00001 0020+00 1/0 0/0 0/0 .data l_daSpinner_Method */
static actor_method_class l_daSpinner_Method = {
(process_method_func)daSpinner_Create,
(process_method_func)daSpinner_Delete,
(process_method_func)daSpinner_Execute,
(process_method_func)NULL,
(process_method_func)daSpinner_Draw,
};
/* 804D4F0C-804D4F3C -00001 0030+00 0/0 0/0 1/0 .data g_profile_SPINNER */
extern actor_process_profile_definition g_profile_SPINNER = {
fpcLy_CURRENT_e, // mLayerID
4, // mListID
fpcPi_CURRENT_e, // mListPrio
PROC_SPINNER, // mProcName
&g_fpcLf_Method.base, // sub_method
sizeof(daSpinner_c), // mSize
0, // mSizeOther
0, // mParameters
&g_fopAc_Method.base, // sub_method
687, // mPriority
&l_daSpinner_Method, // sub_method
0x00060000, // mStatus
fopAc_UNK_GROUP_5_e, // mActorType
fopAc_CULLBOX_0_e, // cullType
};
AUDIO_INSTANCES
struct JAUSectionHeap;
JAUSectionHeap* JASGlobalInstance<JAUSectionHeap>::sInstance;