#include "Library/LiveActor/ActorSensorUtil.h" #include "Library/LiveActor/ActorCollisionFunction.h" #include "Library/LiveActor/ActorMovementFunction.h" #include "Library/LiveActor/ActorPoseUtil.h" #include "Library/LiveActor/ActorSensorFunction.h" #include "Library/Math/MathUtil.h" #include "Project/HitSensor/HitSensor.h" namespace al { SEND_MSG_IMPL(Push); SEND_MSG_IMPL(PushStrong); SEND_MSG_IMPL(PushVeryStrong); SEND_MSG_COMBO_IMPL(PlayerAttackTrample); SEND_MSG_COMBO_IMPL(PlayerTrampleReflect); SEND_MSG_COMBO_IMPL_(PlayerHipDrop, PlayerAttackHipDrop); SEND_MSG_COMBO_IMPL_(PlayerObjHipDrop, PlayerAttackObjHipDrop); SEND_MSG_COMBO_IMPL_(PlayerObjHipDropReflect, PlayerAttackObjHipDropReflect); SEND_MSG_COMBO_IMPL_(PlayerObjHipDropHighJump, PlayerAttackObjHipDropHighJump); SEND_MSG_IMPL_(PlayerHipDropKnockDown, PlayerAttackHipDropKnockDown); SEND_MSG_COMBO_IMPL_(PlayerStatueDrop, PlayerAttackStatueDrop); SEND_MSG_COMBO_IMPL_(PlayerObjStatueDrop, PlayerAttackObjStatueDrop); SEND_MSG_COMBO_IMPL_(PlayerObjStatueDropReflect, PlayerAttackObjStatueDropReflect); SEND_MSG_IMPL_(PlayerObjStatueDropReflectNoCondition, PlayerAttackObjStatueDropReflectNoCondition); SEND_MSG_IMPL_(PlayerStatueTouch, PlayerAttackStatueTouch); SEND_MSG_IMPL_(PlayerUpperPunch, PlayerAttackUpperPunch); SEND_MSG_IMPL_(PlayerObjUpperPunch, PlayerAttackObjUpperPunch); SEND_MSG_IMPL_(PlayerRollingAttack, PlayerAttackRollingAttack); SEND_MSG_IMPL_(PlayerRollingReflect, PlayerAttackRollingReflect); SEND_MSG_IMPL_(PlayerObjRollingAttack, PlayerAttackObjRollingAttack); SEND_MSG_IMPL_(PlayerObjRollingAttackFailure, PlayerAttackObjRollingAttackFailure); SEND_MSG_COMBO_IMPL_(PlayerInvincibleAttack, PlayerAttackInvincibleAttack); SEND_MSG_IMPL_(PlayerFireBallAttack, PlayerAttackFireBallAttack); SEND_MSG_IMPL_(PlayerRouteDokanFireBallAttack, PlayerAttackRouteDokanFireBallAttack); SEND_MSG_COMBO_IMPL_(PlayerTailAttack, PlayerAttackTailAttack); SEND_MSG_IMPL_(PlayerKick, PlayerAttackKick); SEND_MSG_IMPL_(PlayerCatch, PlayerAttackCatch); SEND_MSG_COMBO_IMPL_(PlayerSlidingAttack, PlayerAttackSlidingAttack); SEND_MSG_COMBO_IMPL_(PlayerBoomerangAttack, PlayerAttackBoomerangAttack); SEND_MSG_IMPL_(PlayerBoomerangAttackCollide, PlayerAttackBoomerangAttackCollide); SEND_MSG_IMPL_(PlayerBoomerangReflect, PlayerAttackBoomerangReflect); SEND_MSG_IMPL_(PlayerBoomerangBreak, PlayerAttackBoomerangBreak); SEND_MSG_COMBO_IMPL_(PlayerBodyAttack, PlayerAttackBodyAttack); SEND_MSG_COMBO_IMPL_(PlayerBodyLanding, PlayerAttackBodyLanding); SEND_MSG_COMBO_IMPL_(PlayerBodyAttackReflect, PlayerAttackBodyAttackReflect); SEND_MSG_COMBO_IMPL_(PlayerClimbAttack, PlayerAttackClimbAttack); SEND_MSG_COMBO_IMPL_(PlayerClimbSlidingAttack, PlayerAttackClimbSliding); SEND_MSG_COMBO_IMPL_(PlayerClimbRollingAttack, PlayerAttackClimbRolling); SEND_MSG_COMBO_IMPL_(PlayerSpinAttack, PlayerAttackSpinAttack); SEND_MSG_COMBO_IMPL_(PlayerGiantAttack, PlayerAttackGiant); SEND_MSG_COMBO_IMPL(PlayerCooperationHipDrop); SEND_MSG_COMBO_IMPL(PlayerGiantHipDrop); SEND_MSG_IMPL(PlayerDisregard); SEND_MSG_IMPL(PlayerDamageTouch); IS_MSG_MULTIPLE_IMPL(FloorTouch, PlayerFloorTouch, EnemyFloorTouch); SEND_MSG_IMPL(PlayerFloorTouch); SEND_MSG_IMPL(EnemyFloorTouch); IS_MSG_MULTIPLE_IMPL(UpperPunch, PlayerAttackUpperPunch, EnemyUpperPunch); SEND_MSG_IMPL(EnemyUpperPunch); SEND_MSG_IMPL(PlayerTouch); SEND_MSG_COMBO_IMPL(PlayerInvincibleTouch); SEND_MSG_IMPL(PlayerPutOnEquipment); SEND_MSG_IMPL(PlayerReleaseEquipment); SEND_MSG_DATA_IMPL(PlayerReleaseEquipmentGoal, (u32, Type)); SEND_MSG_IMPL(PlayerCarryFront); SEND_MSG_IMPL(PlayerCarryFrontWallKeep); SEND_MSG_IMPL(PlayerCarryUp); SEND_MSG_IMPL(PlayerCarryKeepDemo); SEND_MSG_IMPL(PlayerCarryWarp); SEND_MSG_IMPL(PlayerLeave); SEND_MSG_IMPL(PlayerToss); SEND_MSG_IMPL(PlayerRelease); SEND_MSG_IMPL(PlayerReleaseBySwing); SEND_MSG_IMPL(PlayerReleaseDead); SEND_MSG_IMPL(PlayerReleaseDamage); SEND_MSG_IMPL(PlayerReleaseDemo); SEND_MSG_IMPL(KillerItemGet); SEND_MSG_IMPL(PlayerItemGet); SEND_MSG_IMPL(RideAllPlayerItemGet); SEND_MSG_IMPL(EnemyAttack); SEND_MSG_DATA_IMPL(EnemyAttackFire, (const char*, MaterialCode)); SEND_MSG_IMPL(EnemyAttackKnockDown); SEND_MSG_IMPL(EnemyAttackBoomerang); SEND_MSG_IMPL(EnemyAttackNeedle); SEND_MSG_IMPL(EnemyItemGet); SEND_MSG_IMPL(EnemyRouteDokanAttack); SEND_MSG_IMPL(EnemyRouteDokanFire); SEND_MSG_COMBO_IMPL(Explosion); SEND_MSG_COMBO_IMPL(ExplosionCollide); SEND_MSG_IMPL(BindStart); SEND_MSG_DATA_IMPL(BindInit, (u32, BindType)); SEND_MSG_IMPL(BindEnd); SEND_MSG_IMPL(BindCancel); SEND_MSG_IMPL(BindCancelByDemo); SEND_MSG_IMPL(BindDamage); SEND_MSG_IMPL(BindSteal); SEND_MSG_IMPL(BindGiant); SEND_MSG_IMPL(PressureDeath); SEND_MSG_IMPL(NpcTouch); SEND_MSG_IMPL(Hit); SEND_MSG_IMPL(HitStrong); SEND_MSG_IMPL(HitVeryStrong); SEND_MSG_IMPL(KnockDown); SEND_MSG_IMPL_(MapPush, Push); SEND_MSG_IMPL(Vanish); SEND_MSG_DATA_TO_ACTOR_IMPL(ChangeAlpha, f32, pAlpha); SEND_MSG_IMPL(ShowModel); SEND_MSG_IMPL(HideModel); SEND_MSG_IMPL(Restart); // TODO: rename variables SEND_MSG_DATA_IMPL(CollisionImpulse, (sead::Vector3f*, VecPtr), (const sead::Vector3f&, ConstVec), (f32, FloatVal), (const sead::Vector3f&, ConstVec2), (f32, FloatVal2)); SEND_MSG_IMPL(EnemyTouch); SEND_MSG_IMPL(EnemyTrample); SEND_MSG_IMPL(MapObjTrample); SEND_MSG_IMPL(NeedleBallAttack); SEND_MSG_IMPL(PunpunFloorTouch); SEND_MSG_IMPL(InvalidateFootPrint); SEND_MSG_COMBO_IMPL(KickKouraAttack); SEND_MSG_COMBO_IMPL(KickKouraAttackCollide); SEND_MSG_IMPL(KickKouraGetItem); SEND_MSG_IMPL(KickKouraReflect); SEND_MSG_IMPL(KickKouraCollideNoReflect); SEND_MSG_IMPL(KickKouraBreak); SEND_MSG_IMPL(KickKouraBlow); SEND_MSG_IMPL(KickStoneAttack); SEND_MSG_IMPL(KickStoneAttackCollide); SEND_MSG_IMPL(KickStoneAttackHold); SEND_MSG_IMPL(KickStoneAttackReflect); SEND_MSG_IMPL(KickStoneTrample); SEND_MSG_IMPL(KillerAttack); SEND_MSG_IMPL(LiftGeyser); SEND_MSG_IMPL(WarpStart); SEND_MSG_IMPL(WarpEnd); SEND_MSG_IMPL(HoleIn); SEND_MSG_IMPL(HoldCancel); SEND_MSG_IMPL(JumpInhibit); SEND_MSG_IMPL(GoalKill); SEND_MSG_IMPL(Goal); SEND_MSG_COMBO_IMPL(BallAttack); SEND_MSG_COMBO_IMPL(BallRouteDokanAttack); SEND_MSG_IMPL(BallAttackHold); SEND_MSG_IMPL(BallAttackDRCHold); SEND_MSG_IMPL(BallAttackCollide); SEND_MSG_COMBO_IMPL(BallTrample); SEND_MSG_IMPL(BallTrampleCollide); SEND_MSG_IMPL(BallItemGet); SEND_MSG_IMPL_(FireBalCollide, FireBallCollide); // Nintendo made a funny typo here SEND_MSG_IMPL(FireBallFloorTouch); SEND_MSG_IMPL(DokanBazookaAttack); SEND_MSG_TO_ACTOR_IMPL(SwitchOn); SEND_MSG_TO_ACTOR_IMPL(SwitchOnInit); SEND_MSG_TO_ACTOR_IMPL(SwitchOffInit); SEND_MSG_TO_ACTOR_IMPL(SwitchKillOn); SEND_MSG_TO_ACTOR_IMPL(SwitchKillOnInit); SEND_MSG_TO_ACTOR_IMPL(SwitchKillOffInit); bool sendMsgPlayerFloorTouchToColliderGround(LiveActor* receiver, HitSensor* sender) { HitSensor* collidedSensor = tryGetCollidedGroundSensor(receiver); return sendMsgPlayerFloorTouch(collidedSensor, sender); } bool sendMsgPlayerUpperPunchToColliderCeiling(LiveActor* receiver, HitSensor* sender) { HitSensor* collidedSensor = tryGetCollidedCeilingSensor(receiver); return sendMsgPlayerUpperPunch(collidedSensor, sender); } bool sendMsgEnemyFloorTouchToColliderGround(LiveActor* receiver, HitSensor* sender) { HitSensor* collidedSensor = tryGetCollidedGroundSensor(receiver); return sendMsgEnemyFloorTouch(collidedSensor, sender); } bool sendMsgEnemyUpperPunchToColliderCeiling(LiveActor* receiver, HitSensor* sender) { HitSensor* collidedSensor = tryGetCollidedCeilingSensor(receiver); return sendMsgEnemyUpperPunch(collidedSensor, sender); } bool sendMsgAskSafetyPointToColliderGround(LiveActor* receiver, HitSensor* sender, sead::Vector3f** safetyPointAccessor) { HitSensor* collidedSensor = tryGetCollidedGroundSensor(receiver); return sendMsgAskSafetyPoint(collidedSensor, sender, safetyPointAccessor); } SEND_MSG_DATA_IMPL(AskSafetyPoint, (sead::Vector3f**, SafetyPoint)); SEND_MSG_IMPL(TouchAssist); SEND_MSG_IMPL(TouchAssistTrig); SEND_MSG_IMPL(TouchStroke); SEND_MSG_IMPL(IsNerveSupportFreeze); SEND_MSG_IMPL(OnSyncSupportFreeze); SEND_MSG_IMPL(OffSyncSupportFreeze); SEND_MSG_IMPL(ScreenPointInvalidCollisionParts); SEND_MSG_COMBO_IMPL(BlockUpperPunch); SEND_MSG_COMBO_IMPL(BlockLowerPunch); SEND_MSG_IMPL(BlockItemGet); SEND_MSG_COMBO_IMPL(PlayerKouraAttack); SEND_MSG_IMPL(LightFlash); SEND_MSG_IMPL(ForceAbyss); SEND_MSG_IMPL(SwordAttackHighLeft); SEND_MSG_IMPL(SwordAttackHighRight); SEND_MSG_IMPL(SwordAttackLowLeft); SEND_MSG_IMPL(SwordAttackLowRight); SEND_MSG_IMPL(SwordBeamAttack); SEND_MSG_IMPL(SwordBeamReflectAttack); SEND_MSG_IMPL(SwordAttackJumpUnder); SEND_MSG_IMPL(ShieldGuard); SEND_MSG_IMPL(AskMultiPlayerEnemy); SEND_MSG_IMPL(ItemGettable); SEND_MSG_IMPL(KikkiThrow); SEND_MSG_IMPL(IsKikkiThrowTarget); SEND_MSG_IMPL(PlayerCloudGet); SEND_MSG_IMPL(AutoJump); SEND_MSG_IMPL(PlayerTouchShadow); SEND_MSG_IMPL(PlayerPullOutShadow); SEND_MSG_IMPL(PlayerAttackShadow); SEND_MSG_IMPL(PlayerAttackShadowStrong); SEND_MSG_DATA_IMPL(PlayerAttackChangePos, (sead::Vector3f*, Pos)); SEND_MSG_IMPL(AtmosOnlineLight); SEND_MSG_IMPL(LightBurn); SEND_MSG_IMPL(MoonLightBurn); SEND_MSG_DATA_IMPL(String, (const char*, Str)); SEND_MSG_DATA_IMPL(StringV4fPtr, (const char*, String), (sead::Vector4f*, Vec)); bool sendMsgStringV4fSensorPtr(HitSensor* receiver, HitSensor* sender, const char* str, sead::Vector4f* vec) { SensorMsgStringV4fSensorPtr msg(str, vec, sender); return alActorSensorFunction::sendMsgSensorToSensor(msg, sender, receiver); } SEND_MSG_DATA_IMPL(StringVoidPtr, (const char*, String), (void*, Ptr)); SEND_MSG_TO_ACTOR_IMPL(HideModel); SEND_MSG_TO_ACTOR_IMPL(ShowModel); SEND_MSG_TO_ACTOR_IMPL(Restart); bool sendMsgPlayerReflectOrTrample(HitSensor* receiver, HitSensor* sender, ComboCounter* comboCounter) { return sendMsgPlayerTrampleReflect(receiver, sender, comboCounter) || sendMsgPlayerAttackTrample(receiver, sender, comboCounter); } IS_MSG_IMPL_(PlayerTrample, PlayerAttackTrample); IS_MSG_IMPL(PlayerTrampleReflect); IS_MSG_IMPL_(PlayerObjHipDropHighJump, PlayerAttackObjHipDropHighJump); IS_MSG_IMPL_(PlayerHipDropKnockDown, PlayerAttackHipDropKnockDown); IS_MSG_IMPL_(PlayerStatueDrop, PlayerAttackStatueDrop); IS_MSG_IMPL_(PlayerObjStatueDrop, PlayerAttackObjStatueDrop); IS_MSG_IMPL_(PlayerObjStatueDropReflect, PlayerAttackObjStatueDropReflect); IS_MSG_IMPL_(PlayerObjStatueDropReflectNoCondition, PlayerAttackObjStatueDropReflectNoCondition); IS_MSG_IMPL_(PlayerStatueTouch, PlayerAttackStatueTouch); IS_MSG_IMPL_(PlayerObjUpperPunch, PlayerAttackObjUpperPunch); IS_MSG_IMPL_(PlayerUpperPunch, PlayerAttackUpperPunch); IS_MSG_IMPL_(PlayerRollingAttack, PlayerAttackRollingAttack); IS_MSG_IMPL_(PlayerRollingReflect, PlayerAttackRollingReflect); IS_MSG_IMPL_(PlayerObjRollingAttack, PlayerAttackObjRollingAttack); IS_MSG_IMPL_(PlayerObjRollingAttackFailure, PlayerAttackObjRollingAttackFailure); IS_MSG_IMPL_(PlayerInvincibleAttack, PlayerAttackInvincibleAttack); IS_MSG_IMPL_(PlayerFireBallAttack, PlayerAttackFireBallAttack); IS_MSG_IMPL_(PlayerRouteDokanFireBallAttack, PlayerAttackRouteDokanFireBallAttack); IS_MSG_IMPL_(PlayerTailAttack, PlayerAttackTailAttack); IS_MSG_IMPL_(PlayerKick, PlayerAttackKick); IS_MSG_IMPL_(PlayerCatch, PlayerAttackCatch); IS_MSG_IMPL_(PlayerSlidingAttack, PlayerAttackSlidingAttack); IS_MSG_IMPL_(PlayerBoomerangAttack, PlayerAttackBoomerangAttack); IS_MSG_IMPL_(PlayerBoomerangAttackCollide, PlayerAttackBoomerangAttackCollide); IS_MSG_IMPL_(PlayerBoomerangReflect, PlayerAttackBoomerangReflect); IS_MSG_IMPL_(PlayerBoomerangBreak, PlayerAttackBoomerangBreak); IS_MSG_IMPL_(PlayerBodyAttack, PlayerAttackBodyAttack); IS_MSG_IMPL_(PlayerBodyLanding, PlayerAttackBodyLanding); IS_MSG_IMPL_(PlayerBodyAttackReflect, PlayerAttackBodyAttackReflect); IS_MSG_IMPL_(PlayerClimbAttack, PlayerAttackClimbAttack); IS_MSG_IMPL_(PlayerClimbSlidingAttack, PlayerAttackClimbSliding); IS_MSG_IMPL_(PlayerClimbRollingAttack, PlayerAttackClimbRolling); IS_MSG_IMPL_(PlayerSpinAttack, PlayerAttackSpinAttack); IS_MSG_IMPL_(PlayerGiantAttack, PlayerAttackGiant); IS_MSG_IMPL(PlayerCooperationHipDrop); IS_MSG_IMPL(PlayerGiantHipDrop); IS_MSG_IMPL(PlayerDisregard); IS_MSG_IMPL_(PlayerDash, PlayerAttackDash); IS_MSG_IMPL(PlayerDamageTouch); IS_MSG_IMPL(PlayerFloorTouchBind); IS_MSG_IMPL(PlayerFloorTouch); IS_MSG_IMPL(EnemyFloorTouch); IS_MSG_IMPL(PlayerTouch); IS_MSG_IMPL(PlayerInvincibleTouch); IS_MSG_IMPL(PlayerGiantTouch); IS_MSG_IMPL_(PlayerObjTouch, PlayerItemGet); IS_MSG_IMPL(PlayerPutOnEquipment); IS_MSG_IMPL(PlayerReleaseEquipment); IS_MSG_IMPL(PlayerReleaseEquipmentGoal); IS_MSG_IMPL(PlayerCarryFront); IS_MSG_IMPL(PlayerCarryFrontWallKeep); IS_MSG_IMPL(PlayerCarryUp); IS_MSG_IMPL(PlayerCarryKeepDemo); IS_MSG_IMPL(PlayerCarryWarp); IS_MSG_IMPL(PlayerLeave); IS_MSG_IMPL(PlayerToss); IS_MSG_IMPL(PlayerRelease); IS_MSG_IMPL(PlayerReleaseBySwing); IS_MSG_IMPL(PlayerReleaseDead); IS_MSG_IMPL(PlayerReleaseDamage); IS_MSG_IMPL(PlayerReleaseDemo); IS_MSG_IMPL(KillerItemGet); IS_MSG_IMPL(PlayerItemGet); IS_MSG_IMPL(RideAllPlayerItemGet); IS_MSG_IMPL(EnemyAttackFire); IS_MSG_IMPL(EnemyAttackKnockDown); IS_MSG_IMPL(EnemyAttackBoomerang); IS_MSG_IMPL(EnemyAttackNeedle); IS_MSG_IMPL(EnemyItemGet); IS_MSG_IMPL(EnemyRouteDokanAttack); IS_MSG_IMPL(EnemyRouteDokanFire); IS_MSG_IMPL(Explosion); IS_MSG_IMPL(ExplosionCollide); IS_MSG_IMPL(BindStart); IS_MSG_IMPL(BindInit); IS_MSG_IMPL(BindEnd); IS_MSG_IMPL(BindCancel); IS_MSG_IMPL(BindCancelByDemo); IS_MSG_IMPL(BindDamage); IS_MSG_IMPL(BindSteal); IS_MSG_IMPL(BindGiant); IS_MSG_IMPL(PressureDeath); IS_MSG_IMPL(NpcTouch); IS_MSG_IMPL(Hit); IS_MSG_IMPL(HitStrong); IS_MSG_IMPL(HitVeryStrong); IS_MSG_IMPL(KnockDown); IS_MSG_IMPL_(MapPush, Push); IS_MSG_IMPL(Vanish); IS_MSG_IMPL(ChangeAlpha); IS_MSG_IMPL(ShowModel); IS_MSG_IMPL(HideModel); IS_MSG_IMPL(Restart); IS_MSG_IMPL(EnemyTouch); IS_MSG_IMPL(EnemyUpperPunch); IS_MSG_IMPL(EnemyTrample); IS_MSG_IMPL(MapObjTrample); IS_MSG_IMPL(NeedleBallAttack); IS_MSG_IMPL(PunpunFloorTouch); IS_MSG_IMPL(InvalidateFootPrint); IS_MSG_IMPL(KickKouraAttack); IS_MSG_IMPL(KickKouraAttackCollide); IS_MSG_IMPL_(KickKouraItemGet, KickKouraGetItem); IS_MSG_IMPL(KickKouraReflect); IS_MSG_IMPL(KickKouraCollideNoReflect); IS_MSG_IMPL(KickKouraBreak); IS_MSG_IMPL(KickKouraBlow); IS_MSG_IMPL(KickStoneAttack); IS_MSG_IMPL(KickStoneAttackCollide); IS_MSG_IMPL(KickStoneAttackHold); IS_MSG_IMPL(KickStoneAttackReflect); IS_MSG_IMPL(KickStoneTrample); IS_MSG_IMPL(KillerAttack); IS_MSG_IMPL(LiftGeyser); IS_MSG_IMPL(WarpStart); IS_MSG_IMPL(WarpEnd); IS_MSG_IMPL(HoleIn); IS_MSG_IMPL(HoldCancel); IS_MSG_IMPL(JumpInhibit); IS_MSG_IMPL(GoalKill); IS_MSG_IMPL(Goal); IS_MSG_IMPL(BallAttack); IS_MSG_IMPL(BallRouteDokanAttack); IS_MSG_IMPL(BallAttackHold); IS_MSG_IMPL(BallAttackDRCHold); IS_MSG_IMPL(BallAttackCollide); IS_MSG_IMPL(BallTrample); IS_MSG_IMPL(BallTrampleCollide); IS_MSG_IMPL(BallItemGet); IS_MSG_IMPL(FireBallCollide); IS_MSG_IMPL(FireBallFloorTouch); IS_MSG_IMPL(DokanBazookaAttack); IS_MSG_IMPL(TouchAssistNoPat); IS_MSG_IMPL(TouchAssistTrig); IS_MSG_IMPL(TouchAssistTrigOff); IS_MSG_IMPL(TouchAssistTrigNoPat); IS_MSG_IMPL(TouchAssistBurn); IS_MSG_IMPL(SwitchOn); IS_MSG_IMPL(SwitchOnInit); IS_MSG_IMPL(SwitchOffInit); IS_MSG_IMPL(SwitchKillOn); IS_MSG_IMPL(SwitchKillOnInit); IS_MSG_IMPL(SwitchKillOffInit); IS_MSG_IMPL(AskSafetyPoint); IS_MSG_IMPL(TouchAssist); IS_MSG_IMPL(TouchStroke); IS_MSG_IMPL(IsNerveSupportFreeze); IS_MSG_IMPL(OnSyncSupportFreeze); IS_MSG_IMPL(OffSyncSupportFreeze); IS_MSG_IMPL(ScreenPointInvalidCollisionParts); IS_MSG_IMPL(BlockUpperPunch); IS_MSG_IMPL(BlockLowerPunch); IS_MSG_IMPL(BlockItemGet); IS_MSG_IMPL(PlayerKouraAttack); IS_MSG_IMPL(LightFlash); IS_MSG_IMPL(ForceAbyss); IS_MSG_MULTIPLE_IMPL(SwordAttackHigh, SwordAttackHighLeft, SwordAttackHighRight); IS_MSG_IMPL(SwordAttackHighLeft); IS_MSG_IMPL(SwordAttackHighRight); IS_MSG_MULTIPLE_IMPL(SwordAttackLow, SwordAttackLowLeft, SwordAttackLowRight); IS_MSG_IMPL(SwordAttackLowLeft); IS_MSG_IMPL(SwordAttackLowRight); IS_MSG_IMPL(SwordBeamReflectAttack); IS_MSG_IMPL(SwordAttackJumpUnder); IS_MSG_IMPL(ShieldGuard); IS_MSG_IMPL(AskMultiPlayerEnemy); IS_MSG_IMPL(ItemGettable); IS_MSG_IMPL(KikkiThrow); IS_MSG_IMPL(IsKikkiThrowTarget); IS_MSG_IMPL(PlayerCloudGet); IS_MSG_IMPL(AutoJump); IS_MSG_IMPL(PlayerTouchShadow); IS_MSG_IMPL(PlayerPullOutShadow); IS_MSG_IMPL(PlayerAttackShadow); IS_MSG_IMPL(PlayerAttackShadowStrong); IS_MSG_IMPL(PlayerAttackChangePos); IS_MSG_IMPL(AtmosOnlineLight); IS_MSG_IMPL(LightBurn); IS_MSG_IMPL(MoonLightBurn); IS_MSG_IMPL(String); IS_MSG_IMPL(StringV4fPtr); IS_MSG_IMPL(StringV4fSensorPtr); IS_MSG_IMPL(StringVoidPtr); bool isCrossoverSensor(const HitSensor* sender, const HitSensor* receiver) { sead::Vector3f diff = sender->getPos() - receiver->getPos(); sead::Vector3f receiverUp = -getGravity(receiver->getParentActor()); if (!tryNormalizeOrZero(&diff)) return false; // cos(70°) if (diff.dot(receiverUp) < 0.342020153f) return false; sead::Vector3f velocityDir; tryNormalizeOrZero(&velocityDir, getVelocity(sender->getParentActor())); if (diff.y < 0.0f) return false; f32 dot = velocityDir.dot(receiverUp); return !isNearZero(sead::Mathf::abs(dot)) && !isNearZero(dot - 1.0f); } bool isMsgPlayerTrampleForCrossoverSensor(const SensorMsg* msg, const HitSensor* sender, const HitSensor* receiver) { return isMsgPlayerTrample(msg) && isCrossoverSensor(sender, receiver); } bool isMsgPlayerTrampleReflectForCrossoverSensor(const SensorMsg* msg, const HitSensor* sender, const HitSensor* receiver) { return isMsgPlayerTrampleReflect(msg) && isCrossoverSensor(sender, receiver); } bool isMsgPlayerUpperPunchForCrossoverSensor(const SensorMsg* msg, const HitSensor* sender, const HitSensor* receiver, f32 threshold) { if (!isMsgPlayerObjUpperPunch(msg)) return false; sead::Vector3f diff = sender->getPos() - receiver->getPos(); sead::Vector3f receiverGravity = getGravity(receiver->getParentActor()); normalize(&diff); // cos(70°) if (receiverGravity.dot(diff) < 0.342020153f) return false; // Has to be written like this, return A || B doesn't match if (receiverGravity.dot(getVelocity(sender->getParentActor())) >= -threshold) return false; return true; } bool isMsgKickStoneTrampleForCrossoverSensor(const SensorMsg* msg, const HitSensor* sender, const HitSensor* receiver) { return isMsgKickStoneTrample(msg) && isCrossoverSensor(sender, receiver); } bool sendMsgEnemyAttackForCrossoverSensor(HitSensor* receiver, HitSensor* sender) { // BUG: should have been `!isCrossOverSensor(...)`, based on similar functions if (isCrossoverSensor(receiver, sender)) return false; return sendMsgEnemyAttack(receiver, sender); } ALWAYS_INLINE bool isWithinCrossoverCylinderVolume(HitSensor* receiver, HitSensor* sender, f32 maxSensorDistance, const sead::Vector3f& basePoint, const sead::Vector3f& upAxis, f32 extraRadius) { sead::Vector3f sensorDiff = receiver->getPos() - sender->getPos(); sead::Vector3f senderUp = -getGravity(sender->getParentActor()); verticalizeVec(&sensorDiff, upAxis, sensorDiff); if (!(sensorDiff.squaredLength() < sead::Mathf::square(maxSensorDistance))) { normalize(&sensorDiff); sead::Vector3f velocityDir; tryNormalizeOrZero(&velocityDir, getVelocity(sender->getParentActor())); if (!(sensorDiff.y < 0.0f)) { f32 dot = senderUp.dot(velocityDir); if (!isNearZero(sead::Mathf::abs(dot)) && !isNearZero(dot - 1.0f)) return false; } } sead::Vector3f cylinderDiff = basePoint - receiver->getPos(); verticalizeVec(&sensorDiff, upAxis, cylinderDiff); return sensorDiff.length() <= receiver->getRadius() + extraRadius; } bool sendMsgEnemyAttackForCrossoverCylinderSensor(HitSensor* receiver, HitSensor* sender, const sead::Vector3f& basePoint, const sead::Vector3f& upAxis, f32 radius) { if (!isWithinCrossoverCylinderVolume(receiver, sender, sead::Mathf::clamp(radius - 20.0f, 0.0f, radius), basePoint, upAxis, radius)) return false; return alActorSensorFunction::sendMsgSensorToSensor(SensorMsgEnemyAttack(), sender, receiver); } IS_MSG_MULTIPLE_IMPL(PushAll, Push, PushStrong, PushVeryStrong); IS_MSG_IMPL(Push); IS_MSG_IMPL(PushStrong); IS_MSG_IMPL(PushVeryStrong); IS_MSG_MULTIPLE_IMPL(SwordBeamAttack, SwordBeamAttack, SwordBeamReflectAttack); IS_MSG_MULTIPLE_IMPL(HoldReleaseAll, HoldCancel, PlayerRelease, PlayerReleaseBySwing, PlayerReleaseDead, PlayerReleaseDamage, PlayerReleaseDemo); IS_MSG_MULTIPLE_IMPL(ItemGetDirectAll, PlayerItemGet, RideAllPlayerItemGet, PlayerAttackTailAttack); IS_MSG_MULTIPLE_IMPL(ItemGetByObjAll, BallItemGet, KickKouraGetItem, KillerItemGet); // This could probably also be implemented with the IS_MSG_MULTIPLE_IMPL macro, but that would need // to be given all messages checked by both of these bool isMsgItemGetAll(const SensorMsg* msg) { return isMsgItemGetDirectAll(msg) || isMsgItemGetByObjAll(msg); } IS_MSG_MULTIPLE_IMPL(PlayerHipDropAll, PlayerAttackHipDrop, PlayerAttackStatueDrop); IS_MSG_MULTIPLE_IMPL(PlayerObjHipDropAll, PlayerAttackObjHipDrop, PlayerAttackObjStatueDrop); IS_MSG_MULTIPLE_IMPL(PlayerObjHipDropReflectAll, PlayerAttackObjHipDropReflect, PlayerAttackObjStatueDropReflect); IS_MSG_MULTIPLE_IMPL(TouchAssistAll, TouchAssist, TouchAssistTrig); IS_MSG_IMPL(TouchCarryItem); IS_MSG_IMPL(TouchReleaseItem); IS_MSG_MULTIPLE_IMPL(EnemyAttack, EnemyAttack, EnemyAttackFire, EnemyAttackKnockDown); SEND_MSG_DATA_IMPL(CollidePush, (const sead::Vector3f&, Vec)); bool sendMsgPushAndKillVelocityToTarget(LiveActor* actor, HitSensor* receiver, HitSensor* sender) { // BUG: Param ordering is wrong here if (!sendMsgPush(sender, receiver)) return false; sead::Vector3f diff = getSensorPos(sender) - getSensorPos(receiver); if (!tryNormalizeOrZero(&diff)) diff.set(sead::Vector3f::ez); if (getVelocity(actor).dot(diff) > 0.0f) verticalizeVec(getVelocityPtr(actor), diff, getVelocity(actor)); return true; } bool sendMsgPushAndKillVelocityToTargetH(LiveActor* actor, HitSensor* receiver, HitSensor* sender) { // BUG: Param ordering is wrong here if (!sendMsgPush(sender, receiver)) return false; sead::Vector3f diff = getSensorPos(sender) - getSensorPos(receiver); diff.y = 0.0f; if (!tryNormalizeOrZero(&diff)) diff.set(sead::Vector3f::ez); if (getVelocity(actor).dot(diff) > 0.0f) verticalizeVec(getVelocityPtr(actor), diff, getVelocity(actor)); return true; } const sead::Vector3f& getSensorPos(const HitSensor* sensor) { return sensor->getPos(); } } // namespace al