1#include <game/bases/d_a_iceball.hpp>
2#include <game/bases/d_a_player_manager.hpp>
4#include <game/bases/d_actor.hpp>
5#include <game/bases/d_eff_actor_manager.hpp>
6#include <game/bases/d_effectmanager.hpp>
7#include <game/bases/d_s_stage.hpp>
8#include <game/bases/d_cd.hpp>
9#include <game/bases/d_bg.hpp>
11#include <game/framework/f_profile_name.hpp>
12#include <game/sLib/s_GlobalData.hpp>
29const sBcSensorPoint l_iceball_foot = { SENSOR_IS_POINT, 0, -0x3000 };
30const sBcSensorPoint l_iceball_head = { SENSOR_IS_POINT, 0, 0x3000 };
31const sBcSensorPoint l_iceball_wall = { SENSOR_IS_POINT, 0x3000, 0 };
38 BIT_FLAG(CC_KIND_PLAYER_ATTACK) | BIT_FLAG(CC_KIND_ENEMY) |
39 BIT_FLAG(CC_KIND_BALLOON) | BIT_FLAG(CC_KIND_ITEM) | BIT_FLAG(CC_KIND_TAMA) | BIT_FLAG(CC_KIND_KILLER),
40 BIT_FLAG(CC_ATTACK_ICE_BREAK) | BIT_FLAG(CC_ATTACK_KOOPA_FIRE) | BIT_FLAG(CC_ATTACK_YOSHI_EAT),
45const float l_cull_data[4] = { 0.0f, 0.0f, 8.0f, 8.0f };
70 mCc.mAmiLine = ACTOR_PARAM(AmiLine);
71 mBc.mAmiLine = ACTOR_PARAM(AmiLine);
72 mRc.mLineKind = ACTOR_PARAM(AmiLine);
74 mLayer = ACTOR_PARAM(Layer);
75 mCc.mLayer = ACTOR_PARAM(Layer);
76 mBc.mLayer = ACTOR_PARAM(Layer);
81 float groundHeight = 0.0f;
83 mPos.y = groundHeight + 4.0f;
97 mAreaNo = dCd_c::m_instance->getFileP(dScStage_c::m_instance->mCurrFile)->getAreaNo(&
mPos);
108 if (dBc_c::checkTenjou(&ceilCheckPos, &ceilingHeight,
mLayer, 1)) {
109 if (
mPos.y > ceilingHeight - 6.0f) {
110 mPos.y = ceilingHeight - 6.0f;
114 mBc.set(
this, l_iceball_foot, l_iceball_head, l_iceball_wall);
153 if (
mBc.checkWall(
nullptr)) {
162 return dBc_c::checkWall(&a, &b, &c,
mLayer, 1,
nullptr);
169 if (dBc_c::checkGround(&pos, &height,
mLayer, 1, -1)) {
170 if (height < pos.y && height >=
mPos.y - 3.0f) {
171 groundHeight = height;
191 if (
mRc.check(
mBc.checkFoot(), 0, 0)) {
192 mBc.mFlags |= dBc_c::FLAG_15;
195 mBc.checkWall(
nullptr);
198 if (
mBc.isCollision()) {
206 EffectManager_c::SetIceBallMissshitEffect(&
mPos);
210 if ((other->
mCcData.mVsDamage & (1 << CC_ATTACK_ICEBALL)) == 0) {
214 self->
mInfo |= CC_NO_HIT;
220 if (otherActor->
mProfName == fProf::EN_MARUTA) {
221 if (thisIceball->
mSpeed.y >= 0.0f) {
233 if ((otherActor->
mProfName == fProf::KOOPA_FIRE) && ((
int)(otherActor->
mParam & 0xF) == 1)) {
257 }
else if (
mLayer == LAYER_2) {
272 if (
mBc.isWallL() |
mBc.isWallR() |
mBc.isHead()) {
275 if ((
mBc.mFlags & dBc_c::FLAG_15) && (
mRc.isRideFlag(0x200) & 0xFFFF)) {
278 if (
mBc.getFootAttr() == 3) {
284 if (
mRc.getRide() && (
mRc.getRide()->mFlags & 0x1000)) {
294 bool destroyIceball =
false;
296 case dBc_c::WATER_CHECK_WATER:
297 if (prevLiquid == dBc_c::WATER_CHECK_NONE) {
301 case dBc_c::WATER_CHECK_WATER_BUBBLE:
302 if (prevLiquid == dBc_c::WATER_CHECK_NONE) {
306 case dBc_c::WATER_CHECK_YOGAN:
307 if (prevLiquid == dBc_c::WATER_CHECK_NONE) {
310 destroyIceball =
true;
312 case dBc_c::WATER_CHECK_POISON:
313 if (prevLiquid == dBc_c::WATER_CHECK_NONE) {
316 destroyIceball =
true;
322 return destroyIceball;
330 if (pos.y ==
mPos.y) {
331 splashFlags =
mLayer << 16 | 1;
333 splashFlags =
mLayer << 16 | 2;
336 dEffActorMng_c::m_instance->createWaterSplashEff(pos, splashFlags, -1,
mVec3_c(1.0f, 1.0f, 1.0f));
337 dBg_c::m_bg_p->setWaterInWave(pos.x, pos.y, 8);
344 u32 splashFlags =
mLayer << 16 | 4;
345 mVec3_c scale(0.6f, 0.6f, 0.6f);
347 dEffActorMng_c::m_instance->createWaterSplashEff(pos, splashFlags, -1, scale);
348 dBg_c::m_bg_p->setWaterInWave(pos.x, pos.y, 18);
355 u32 splashFlags =
mLayer << 16 | 6;
356 mVec3_c scale(0.6f, 0.6f, 0.6f);
358 dEffActorMng_c::m_instance->createWaterSplashEff(pos, splashFlags, -1, scale);
359 dBg_c::m_bg_p->setWaterInWave(pos.x, pos.y, 25);
362void daIceBall_c::initializeState_FireMove() {
363 static const float x_speeds[] = {3.6f, -3.6f};
370void daIceBall_c::finalizeState_FireMove() {}
372void daIceBall_c::executeState_FireMove() {
373 EffectManager_c::SetIceBallEffect(&
mPos);
385 if (
mBc.mFlags & dBc_c::FLAG_FOOT) {
398 dAudio::SoundEffectID_t(SE_OBJ_PNGN_ICEBALL_DISAPP).playMapSound(
mPos, 0);
406void daIceBall_c::initializeState_Move() {
407 static const float cs_speed_x[] = {3.0f, -3.0f};
408 static const float cs_max_speed_x[] = {1.5f, -1.5f};
415 if (playerXSpeed > moveBoostThreshold) {
416 float baseBoost = moveBoostScale * moveBoostThreshold;
418 }
else if (playerXSpeed < -moveBoostThreshold) {
419 float baseBoost = -moveBoostScale * moveBoostThreshold;
422 speedBoost = moveBoostScale * playerXSpeed;
432void daIceBall_c::finalizeState_Move() {}
434void daIceBall_c::executeState_Move() {
435 EffectManager_c::SetIceBallEffect(&
mPos);
453 dAudio::SoundEffectID_t(SE_OBJ_PNGN_ICEBALL_DISAPP).playMapSound(
mPos, 0);
460 dAudio::SoundEffectID_t(SE_OBJ_PNGN_ICEBALL_DISAPP).playMapSound(
mPos, 0);
471void daIceBall_c::initializeState_EatIn() {}
473void daIceBall_c::finalizeState_EatIn() {}
475void daIceBall_c::executeState_EatIn() {
476 EffectManager_c::SetIceBallEffect(&
mPos);
482void daIceBall_c::initializeState_EatNow() {}
484void daIceBall_c::finalizeState_EatNow() {}
486void daIceBall_c::executeState_EatNow() {}
488void daIceBall_c::initializeState_Kill() {
493void daIceBall_c::finalizeState_Kill() {}
495void daIceBall_c::executeState_Kill() {}
The player class for Mario, Luigi and the Toads.
sFStateMgr_c< dActorState_c, sStateMethodUsr_FI_c > mStateMgr
The state manager.
dBc_c mBc
The actor-to-tile collision sensor.
u8 mKind
The actor's kind. Value is a STAGE_ACTOR_KIND_e.
u8 mEatState
The actor's eat state. Value is a EAT_STATE_e.
u8 mDirection
The actor's facing direction.
dCc_c mCc
The actor-to-actor collision sensor.
@ EAT_TYPE_ICEBALL
Yoshi can spit an iceball after eating the actor.
virtual void removeCc()
Disables the actor's collision.
virtual void eatMove(dActor_c *eatingActor)
Updates the actor's position during eating actions.
u8 mAreaNo
The actor's zone ID.
u8 mEatBehavior
The actor's eat behaviour. Value is a EAT_BEHAVIOR_e.
s8 mPlayerNo
The player associated with the actor, -1 if not associated to any player.
static int screenCullCheck(const mVec3_c &pos, const sRangeDataF &visibleBound, sRangeDataF destroyBound, u8 areaID)
Checks if the actor should be culled due to being outside the screen.
@ EAT_STATE_EATEN
The actor has been successfully eaten.
dActor_c()
Constructs a new actor.
dRc_c mRc
The actor's ride surface manager.
u8 mLayer
The actor's layer.
float mAccelF
The actor's horizontal acceleration.
mVec3_c mSpeed
The actor's speed.
mVec3_c mPos
The actor's position.
mVec3_c mSpeedMax
The actor's maximum speed.
void calcSpeedX()
Updates the actor's X speed. See here for details.
mVec3_c mCenterOffs
The offset from the position to the center of the actor (defaults to 0).
void calcFallSpeed()
Updates the actor's falling speed. See here for details.
void posMove()
Moves the actor by its speed.
float mMaxFallSpeed
The actor's maximum fall speed.
u32 mActorProperties
The actor's properties. See fProf::fActorProfile_c::mActorProperties.
float mAccelY
The actor's vertical acceleration.
Collider ("Collision Check") class - handles collisions between actors.
u8 mInfo
Info flags for this collider. See CC_INFO_e.
dActor_c * getOwner() const
Gets the owner actor of this collider.
sCcDatNewF mCcData
The collision data of this collider.
An iceball, thrown by the player.
static int sm_IceBallAliveCount[4]
The number of "alive" iceballs for each player.
bool checkInitLine(float &groundHeight)
Checks if the iceball is close to the ground so that it can spawn a bit higher up.
virtual int create()
do method for the create operation.
dBc_c::WATER_TYPE_e mLiquidType
The type of liquid the iceball is currently in contact with.
void waterSplash(float height)
Creates a water splash effect and sound at a specified height.
u32 mHitEntity
Whether the iceball has hit an entity.
static const int smc_MAX_ALIVE_ICEBALL_COUNT
bool checkInitVanish()
Checks whether the iceball should vanish on creation. This happens if the iceball is supposed to spaw...
static sFStateID_c< daIceBall_c > StateID_EatIn
The iceball is being eaten.
bool bgCheck()
Checks for collisions and returns whether a collision occurred.
mVec3_c mStartPos
The starting position of the iceball when it was created.
static sFStateID_c< daIceBall_c > StateID_Kill
The iceball has hit something and should be deleted.
void yoganSplash(float height)
Creates a lava splash effect and sound at a specified height.
virtual void eatMove(dActor_c *eatingActor)
Updates the actor's position during eating actions.
static const int smc_MAX_ICEBALL_COUNT
void setDeleteEffect()
Creates an effect for when the iceball gets destroyed.
float mLiquidHeight
The height of the liquid surface the iceball is in contact with.
static sFStateID_c< daIceBall_c > StateID_EatNow
The iceball has been eaten.
static sFStateID_c< daIceBall_c > StateID_FireMove
The iceball is moving downwards after being thrown.
virtual int doDelete()
do method for the delete operation.
bool checkDeleteBg()
Checks if the iceball should be deleted due to hitting something.
void poisonSplash(float height)
Creates a poison splash effect and sound at a specified height.
void lightProc()
Updates the iceball's light mask.
static int sm_IceBallCount[4]
The number of iceballs that currently exist for each player.
virtual void deleteReady()
Informs the base that it's about to be deleted.
void chgZpos()
Updates the iceball's Z position.
static sFStateID_c< daIceBall_c > StateID_Move
The iceball hit the ground and is doing a final bounce.
virtual void setEatTongue(dActor_c *eatingActor)
Callback for when the actor is targeted by Yoshi's tongue.
@ CREATE_SPIN
Use smc_MAX_ICEBALL_COUNT.
bool waterlineCheck()
Checks if the iceball hit the surface of a liquid. If it did, it creates a splash effect and sound.
static bool isIceBallEnable(int playerNo, CreateKind_e kind)
Checks if a new iceball can be created for a player based on the limit mode.
virtual int draw()
do method for the draw operation.
dHeapAllocator_c mAllocator
Heap allocator for the iceball.
bool cullCheck()
Checks if the iceball is within the camera's view.
static void ccCallback_Iceball(dCc_c *self, dCc_c *other)
Collision callback for the iceball.
dCircleLightMask_c mLightMask
Light mask for the iceball.
daIceBall_c()
Creates a new iceball actor.
virtual int execute()
do method for the execute operation.
u32 mAliveTimer
Timer for the iceball's lifetime. This is used to limit how quickly the player can throw multiple ice...
@ CANCELED
The operation was canceled early.
void deleteRequest()
Requests deletion of the base.
@ ENEMY
The base is an enemy.
ProfileName mProfName
The base's profile name.
u32 mParam
A bitfield that configures the base's behaviour. Its usage varies from profile to profile.
@ SUCCEEDED
The step was completed successfully.
A three-dimensional floating point vector.
static const T::GlobalData_t mData
virtual void changeState(const sStateIDIf_c &newState)
Transitions to a new state ID.
#define ACTOR_PROFILE(profName, className, properties)
Creates an actor profile, using the profile number as the execute and draw order value.
#define STATE_DEFINE(class, name)
Defines a state.
A structure that contains information about a collider.
u8 mKind
The type of this collider. See CC_KIND_e.
u8 mAttack
The attack type of this collider. See CC_ATTACK_e.