1#include "Game/MapObj/BreakableCage.hpp"
2#include "Game/MapObj/PowerStar.hpp"
4inline f32 normalizeAngle(f32 a1, f32 a2) {
5 return a1 + (f32)fmod(360.0f + (a2 - a1), 360.0f);
8BreakableCage::BreakableCage(
const char *pName) :
LiveActor(pName) {
10 mCageType = CAGE_INVALID;
11 mRotationSpeed = 0.0f;
13 mIgnoreGravity =
false;
14 mDelayDeadActivate =
false;
15 mCameraInfo =
nullptr;
107void BreakableCage::appear() {
113 MR::validateClipping(
this);
119 if (mCageType == CAGE_TRASH && MR::isValidSwitchDead(
this)) {
120 MR::offSwitchDead(
this);
123 setNerve(&NrvBreakableCage::BreakableCageNrvWait::sInstance);
127void BreakableCage::kill() {
134 if (mItemModel !=
nullptr) {
141 if (mCageType == CAGE_NORMAL) {
144 TVec3f stack_14(0.0f, 1.0f, 0.0f);
146 stack_20.mMtx[0][3] = 0.0f;
147 stack_20.mMtx[1][3] = 0.0f;
148 stack_20.mMtx[2][3] = 0.0f;
149 stack_C.set(stack_14);
150 PSVECMag(stack_C.toCVec());
151 PSVECNormalize(stack_C.toCVec(), stack_C.toVec());
155 stack_50.mMtx[0][0] = v4 + ((1.0f - v4) * (stack_C.x * stack_C.x));
156 stack_50.mMtx[1][1] = v4 + ((1.0f - v4) * (stack_C.y * stack_C.y));
157 stack_50.mMtx[2][2] = v4 + ((1.0f - v4) * (stack_C.z * stack_C.z));
158 stack_50.mMtx[0][1] = (stack_C.y * ((1.0f - v4) * stack_C.x)) - (v3 * stack_C.z);
159 stack_50.mMtx[0][2] = (stack_C.z * ((1.0f - v4) * stack_C.x)) + (v3 * stack_C.y);
160 stack_50.mMtx[1][0] = (stack_C.y * ((1.0f - v4) * stack_C.x)) + (v3 * stack_C.z);
161 stack_50.mMtx[2][0] = (stack_C.z * ((1.0f - v4) * stack_C.x)) - (v3 * stack_C.y);
162 stack_50.mMtx[1][2] = (stack_C.z * ((1.0f - v4) * stack_C.y)) - (v3 * stack_C.x);
163 stack_50.mMtx[2][1] = (stack_C.z * ((1.0f - v4) * stack_C.y)) + (v3 * stack_C.x);
165 stack_20.concat(mMtx, stack_50);
166 MR::setBaseTRMtx(
this, stack_20);
169 MR::setBaseTRMtx(
this, mMtx);
176 if (MR::isMsgJetTurtleAttack(msg)) {
189 if (MR::isMsgEnemyAttackFire(msg) || MR::isMsgEnemyAttackFireStrong(msg)) {
199void BreakableCage::initMapToolInfo(
const JMapInfoIter &rIter) {
200 MR::initDefaultPos(
this, rIter);
201 MR::useStageSwitchReadAppear(
this, rIter);
202 MR::useStageSwitchWriteA(
this, rIter);
203 MR::useStageSwitchWriteB(
this, rIter);
204 MR::useStageSwitchWriteDead(
this, rIter);
206 if (mCageType == CAGE_NORMAL) {
207 MR::getJMapInfoArg0WithInit(rIter, &mRotationSpeed);
208 mRotationSpeed *= 0.0099999998f;
212 MR::getJMapInfoArg1NoInit(rIter, &mIgnoreGravity);
215 mIgnoreGravity =
true;
218 MR::getJMapInfoArg2NoInit(rIter, &mDelayDeadActivate);
221void BreakableCage::initModel(
const char *pName,
const JMapInfoIter &rIter) {
222 initModelManagerWithAnm(pName,
nullptr,
false);
224 ModelObj* obj = MR::createModelObjMapObjStrongLight(
"壊れる籠壊れモデル",
"BreakableCageBreak", mMtx.toMtxPtr());
228 MR::invalidateClipping(mBreakModel);
229 MR::registerDemoSimpleCastAll(mBreakModel);
230 mBreakModel->makeActorDead();
231 mItemModel = MR::createDummyDisplayModel(
this, rIter, -1, TVec3f(0.0f, 150.0f, 0.0f), TVec3f(0.0f, 0.0f, 0.0f));
232 if (mItemModel !=
nullptr) {
233 s32 model_id = MR::getDummyDisplayModelId(rIter, -1);
237 MR::startBck(mItemModel,
"Rotation",
nullptr);
246void BreakableCage::initBaseMtxForCage() {
247 MR::calcGravity(
this);
250 MR::makeMtxRotate(stack_20.toMtxPtr(),
mRotation);
252 f32 z = stack_20.mMtx[2][2];
253 f32 y = stack_20.mMtx[1][2];
254 f32 x = stack_20.mMtx[0][2];
255 stack_14.set(x, y, z);
258 MR::makeMtxUpFrontPos(&mMtx, stack_8, stack_14,
mPosition);
261bool BreakableCage::isTypeCage()
const {
265 CageType type = mCageType;
267 if (type && type != CAGE_LARGE) {
271 if (!v4 && type != CAGE_NORMAL) {
275 if (!v3 && type != CAGE_TRASH) {
282bool BreakableCage::isAppearPowerStar()
const {
284 if (mItemModel !=
nullptr && MR::getDummyDisplayModelId(mItemModel) == 7) {
291bool BreakableCage::tryBreak() {
292 if (isNerve(&NrvBreakableCage::BreakableCageNrvWait::sInstance)) {
293 if (mCameraInfo !=
nullptr) {
294 MR::requestStartDemoWithoutCinemaFrame(
this,
"破壊", &NrvBreakableCage::BreakableCageNrvBreak::sInstance, &NrvBreakableCage::BreakableCageNrvWaitStartDemoBreak::sInstance);
297 setNerve(&NrvBreakableCage::BreakableCageNrvBreak::sInstance);
306void BreakableCage::exeWait() {
307 if (mCageType == CAGE_NORMAL) {
311 if (mItemModel !=
nullptr) {
312 if (isAppearPowerStar()) {
314 mItemModel->
mRotation.y = normalizeAngle(0.0f, model->
mRotation.y + PowerStar::getPowerStarWaitRotateSpeed());
319void BreakableCage::exeBreak() {
324 if (mDelayDeadActivate || mItemModel !=
nullptr || mCageType == (s32)3 || mCageType == CAGE_TRASH) {
328 if (!v3 && mCageType != CAGE_NORMAL) {
332 if (MR::isFirstStep(
this)) {
335 MR::startSound(
this,
"SE_OJ_BREAK_FIXATION_BREAK", -1, -1);
338 MR::startSound(
this,
"SE_OJ_IRON_CAGE_BREAK", -1, -1);
344 MR::invalidateCollisionParts(
this);
345 MR::invalidateClipping(
this);
350 MR::startActorCameraTargetSelf(
this, getCamInfo(), -1);
351 if (mBreakModel !=
nullptr) {
352 MR::requestMovementOn(mBreakModel);
357 mBreakModel->appear();
358 MR::startBck(mBreakModel,
"Break",
nullptr);
361 MR::emitEffect(
this,
"Break");
364 if (isAppearPowerStar()) {
365 if (mItemModel !=
nullptr) {
366 MR::requestAppearPowerStar(
this, mItemModel->
mPosition);
369 MR::requestAppearPowerStar(
this,
this, 150.0f);
372 MR::requestMovementOn(
this);
375 if (mItemModel !=
nullptr) {
379 if (v2 && MR::isValidSwitchDead(
this)) {
380 MR::onSwitchDead(
this);
384 if (isAppearPowerStar() || mCameraInfo !=
nullptr) {
385 MR::stopSceneAtStep(
this, 2, 16);
387 else if (MR::isNearPlayer(
this, 1500.0f)) {
389 if (!MR::isJudgedToClipFrustum(
mPosition, radius)) {
390 MR::stopSceneAtStep(
this, 2, 6);
396 if (mCameraInfo !=
nullptr) {
397 canDoSwitch = MR::isStep(
this, 120);
399 else if (isTypeCage()) {
400 canDoSwitch = MR::isBckStopped(mBreakModel);
403 canDoSwitch = MR::isEffectValid(
this,
"Break") ==
false;
407 if (!v2 && MR::isValidSwitchDead(
this)) {
408 MR::onSwitchDead(
this);
411 if (MR::isValidSwitchB(
this)) {
412 MR::offSwitchB(
this);
415 if (mCameraInfo !=
nullptr) {
416 MR::endActorCamera(
this, getCamInfo(),
false, -1);
417 MR::endDemo(
this,
"破壊");
424BreakableCage::~BreakableCage() {
428namespace NrvBreakableCage {
429 INIT_NERVE(BreakableCageNrvWait);
430 INIT_NERVE(BreakableCageNrvWaitStartDemoBreak);
431 INIT_NERVE(BreakableCageNrvBreak);
433 void BreakableCageNrvBreak::execute(
Spine *pSpine)
const {
438 void BreakableCageNrvWaitStartDemoBreak::execute(
Spine *pSpine)
const {
442 void BreakableCageNrvWait::execute(
Spine *pSpine)
const {
virtual void calcAndSetBaseMtx()
Calculates and sets the base matrix of the actor.
The basis of a drawable actor that can contain states (see: Nerve)
TVec3f mRotation
3D vector of the actor's rotation.
TVec3f mPosition
3D vector of the actor's position.
TVec3f mScale
3D vector of the actor's scale.
TVec3f mGravity
3D vector of the actor's gravity.
HitSensor * getSensor(const char *pSensorName) const
Gets a sensor.
void initWithoutIter()
Initializes a NameObj without a JMapInfoIter instance.