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 };
68 mCc.mAmiLine = ACTOR_PARAM(AmiLine);
69 mBc.mAmiLine = ACTOR_PARAM(AmiLine);
70 mRc.mLineKind = ACTOR_PARAM(AmiLine);
72 mLayer = ACTOR_PARAM(Layer);
73 mCc.mLayer = ACTOR_PARAM(Layer);
74 mBc.mLayer = ACTOR_PARAM(Layer);
79 float groundHeight = 0.0f;
81 mPos.y = groundHeight + 4.0f;
95 mAreaNo = dCd_c::m_instance->getFileP(dScStage_c::m_instance->mCurrFile)->getAreaNo(&
mPos);
106 if (dBc_c::checkTenjou(&ceilCheckPos, &ceilingHeight,
mLayer, 1)) {
107 if (
mPos.y > ceilingHeight - 6.0f) {
108 mPos.y = ceilingHeight - 6.0f;
112 mBc.set(
this, l_iceball_foot, l_iceball_head, l_iceball_wall);
151 if (
mBc.checkWall(
nullptr)) {
160 return dBc_c::checkWall(&a, &b, &c,
mLayer, 1,
nullptr);
167 if (dBc_c::checkGround(&pos, &height,
mLayer, 1, -1)) {
168 if (height < pos.y && height >=
mPos.y - 3.0f) {
169 groundHeight = height;
189 if (
mRc.check(
mBc.checkFoot(), 0, 0)) {
190 mBc.mFlags |= dBc_c::FLAG_15;
193 mBc.checkWall(
nullptr);
196 if (
mBc.isCollision()) {
204 EffectManager_c::SetIceBallMissshitEffect(&
mPos);
208 if ((other->
mCcData.mVsDamage & (1 << CC_ATTACK_ICEBALL)) == 0) {
212 self->
mInfo |= CC_NO_HIT;
218 if (otherActor->
mProfName == fProfile::EN_MARUTA) {
219 if (thisIceball->
mSpeed.y >= 0.0f) {
231 if ((otherActor->
mProfName == fProfile::KOOPA_FIRE) && ((
int)(otherActor->
mParam & 0xF) == 1)) {
270 if (
mBc.isWallL() |
mBc.isWallR() |
mBc.isHead()) {
273 if ((
mBc.mFlags & dBc_c::FLAG_15) && (
mRc.isRideFlag(0x200) & 0xFFFF)) {
276 if (
mBc.getFootAttr() == 3) {
282 if (
mRc.getRide() && (
mRc.getRide()->mFlags & 0x1000)) {
292 bool destroyIceball =
false;
294 case dBc_c::WATER_CHECK_WATER:
295 if (prevLiquid == dBc_c::WATER_CHECK_NONE) {
299 case dBc_c::WATER_CHECK_WATER_BUBBLE:
300 if (prevLiquid == dBc_c::WATER_CHECK_NONE) {
304 case dBc_c::WATER_CHECK_YOGAN:
305 if (prevLiquid == dBc_c::WATER_CHECK_NONE) {
308 destroyIceball =
true;
310 case dBc_c::WATER_CHECK_POISON:
311 if (prevLiquid == dBc_c::WATER_CHECK_NONE) {
314 destroyIceball =
true;
320 return destroyIceball;
328 if (pos.y ==
mPos.y) {
329 splashFlags =
mLayer << 16 | 1;
331 splashFlags =
mLayer << 16 | 2;
334 dEffActorMng_c::m_instance->createWaterSplashEff(pos, splashFlags, -1,
mVec3_c(1.0f, 1.0f, 1.0f));
335 dBg_c::m_bg_p->setWaterInWave(pos.x, pos.y, 8);
342 u32 splashFlags =
mLayer << 16 | 4;
343 mVec3_c scale(0.6f, 0.6f, 0.6f);
345 dEffActorMng_c::m_instance->createWaterSplashEff(pos, splashFlags, -1, scale);
346 dBg_c::m_bg_p->setWaterInWave(pos.x, pos.y, 18);
353 u32 splashFlags =
mLayer << 16 | 6;
354 mVec3_c scale(0.6f, 0.6f, 0.6f);
356 dEffActorMng_c::m_instance->createWaterSplashEff(pos, splashFlags, -1, scale);
357 dBg_c::m_bg_p->setWaterInWave(pos.x, pos.y, 25);
360void daIceBall_c::initializeState_FireMove() {
361 static const float x_speeds[] = {3.6f, -3.6f};
368void daIceBall_c::finalizeState_FireMove() {}
370void daIceBall_c::executeState_FireMove() {
371 EffectManager_c::SetIceBallEffect(&
mPos);
383 if (
mBc.mFlags & dBc_c::FLAG_FOOT) {
396 dAudio::SoundEffectID_t(SE_OBJ_PNGN_ICEBALL_DISAPP).playMapSound(
mPos, 0);
404void daIceBall_c::initializeState_Move() {
405 static const float cs_speed_x[] = {3.0f, -3.0f};
406 static const float cs_max_speed_x[] = {1.5f, -1.5f};
413 if (playerXSpeed > moveBoostThreshold) {
414 float baseBoost = moveBoostScale * moveBoostThreshold;
416 }
else if (playerXSpeed < -moveBoostThreshold) {
417 float baseBoost = -moveBoostScale * moveBoostThreshold;
420 speedBoost = moveBoostScale * playerXSpeed;
430void daIceBall_c::finalizeState_Move() {}
432void daIceBall_c::executeState_Move() {
433 EffectManager_c::SetIceBallEffect(&
mPos);
451 dAudio::SoundEffectID_t(SE_OBJ_PNGN_ICEBALL_DISAPP).playMapSound(
mPos, 0);
458 dAudio::SoundEffectID_t(SE_OBJ_PNGN_ICEBALL_DISAPP).playMapSound(
mPos, 0);
469void daIceBall_c::initializeState_EatIn() {}
471void daIceBall_c::finalizeState_EatIn() {}
473void daIceBall_c::executeState_EatIn() {
474 EffectManager_c::SetIceBallEffect(&
mPos);
480void daIceBall_c::initializeState_EatNow() {}
482void daIceBall_c::finalizeState_EatNow() {}
484void daIceBall_c::executeState_EatNow() {}
486void daIceBall_c::initializeState_Kill() {
491void daIceBall_c::finalizeState_Kill() {}
493void daIceBall_c::executeState_Kill() {}
497 if (limitMode == 1) {
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 mEatBehaviour
The actor's eat behaviour. Value is a EAT_BEHAVIOR_e.
u8 mAreaNo
The actor's zone ID.
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 fProfile::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.
static bool CheckIceballLimit(int playerNo, int limitMode)
Checks if a new iceball can be created for a player based on the limit mode.
virtual void setEatTongue(dActor_c *eatingActor)
Callback for when the actor is targeted by Yoshi's tongue.
bool waterlineCheck()
Checks if the iceball hit the surface of a liquid. If it did, it creates a splash effect and sound.
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.