Library/LiveActor: Implement all SensorMsgs within al (#415)

Co-authored-by: MonsterDruide1 <5958456@gmail.com>
This commit is contained in:
LynxDev2 2025-07-25 13:16:47 +03:00 committed by GitHub
parent dc3ffa1417
commit 6ae7bccd0c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 2034 additions and 972 deletions

File diff suppressed because it is too large Load diff

View file

@ -89,3 +89,36 @@
#define NO_DELIM()
#define FOR_EACH(action, x0, ...) VFUNC(FE_, __VA_ARGS__)(action, NO_DELIM, x0, __VA_ARGS__)
#define _FUNC_(name, n) name n
#define FOR_EACH_TUPL(action, ...) FOR_EACH(_FUNC_, action, __VA_ARGS__)
#define FOR_EACH_TUPL_DELIM(action, delim, ...) FOR_EACH_DELIM(_FUNC_, delim, action, __VA_ARGS__)
#define COMMA() ,
#define LOGICAL_OR() ||
#define DECL_MEMBER_VAR(type, name) type m##name;
#define PARAM(type, name) type p##name
#define DECL_GET(type, name) \
type get##name() const { \
return m##name; \
}
#define POINTER_PARAM(type, name) PARAM(type*, name)
#define PARAM_START_COMMA(type, name) , type p##name
#define CALL_PARAM(_, name) p##name
#define SET_MEMBER_PARAM(_, name) m##name = p##name;
#define DECL_MEMBER_VAR_MULTI(...) FOR_EACH_TUPL(DECL_MEMBER_VAR, __VA_ARGS__)
#define DECL_GET_MULTI(...) FOR_EACH_TUPL(DECL_GET, __VA_ARGS__)
#define PARAM_LIST(...) FOR_EACH_TUPL_DELIM(PARAM, COMMA, __VA_ARGS__)
#define POINTER_PARAM_LIST(...) FOR_EACH_TUPL_DELIM(POINTER_PARAM, COMMA, __VA_ARGS__)
#define CALL_PARAM_LIST(...) FOR_EACH_TUPL_DELIM(CALL_PARAM, COMMA, __VA_ARGS__)
#define SET_MEMBER_PARAM_MULTI(...) FOR_EACH_TUPL(SET_MEMBER_PARAM, __VA_ARGS__)

View file

@ -0,0 +1,208 @@
#pragma once
#include <prim/seadRuntimeTypeInfo.h>
#include "Library/Base/Macros.h"
#include "Library/LiveActor/ActorSensorFunction.h"
namespace al {
class HitSensor;
class ComboCounter;
class SensorMsg {
SEAD_RTTI_BASE(SensorMsg)
public:
virtual ~SensorMsg() = default;
};
} // namespace al
/*
Declares a SensorMsg class
Creating a SensorMsg class called SensorMsgTest:
SENSOR_MSG(Test);
*/
#define SENSOR_MSG(Type) \
class SensorMsg##Type : public al::SensorMsg { \
SEAD_RTTI_OVERRIDE(SensorMsg##Type, al::SensorMsg) \
public: \
inline SensorMsg##Type() = default; \
virtual ~SensorMsg##Type() = default; \
};
/*
Declares a SensorMsg class with data.
Creating a SensorMsg class called SensorMsgTest2 that holds a string referenced as `mStr` or `pStr`:
SENSOR_MSG_WITH_DATA(Test2, (const char*, Str));
*/
#define SENSOR_MSG_WITH_DATA(Type, ...) \
class SensorMsg##Type : public al::SensorMsg { \
SEAD_RTTI_OVERRIDE(SensorMsg##Type, al::SensorMsg) \
public: \
inline SensorMsg##Type(PARAM_LIST(__VA_ARGS__)) { \
SET_MEMBER_PARAM_MULTI(__VA_ARGS__); \
} \
\
DECL_GET_MULTI(__VA_ARGS__) \
\
virtual ~SensorMsg##Type() = default; \
\
private: \
DECL_MEMBER_VAR_MULTI(__VA_ARGS__); \
};
/*
Same as above, but allows adding a custom constructor. The second argument is a list of member
variables the message should store and the third argument is a list of arguments to the constructor.
This is especially useful for implementing existing SensorMsgs that store vectors because the ctor
for them needs to call `set()` on the vector:
SENSOR_MSG_WITH_DATA_CUSTOM_CTOR(MyVecMsg, ((sead::Vector3f, Vec)), ((const sead::Vector3f&, Vec)))
{ mVec.set(pVec);
};
*/
#define SENSOR_MSG_WITH_DATA_CUSTOM_CTOR(Type, SensorMsgParams, CtorParams) \
class SensorMsg##Type : public al::SensorMsg { \
SEAD_RTTI_OVERRIDE(SensorMsg##Type, al::SensorMsg) \
\
public: \
inline SensorMsg##Type(PARAM_LIST CtorParams); \
\
DECL_GET_MULTI SensorMsgParams; \
\
virtual ~SensorMsg##Type() = default; \
\
private: \
DECL_MEMBER_VAR_MULTI SensorMsgParams; \
}; \
inline SensorMsg##Type::SensorMsg##Type(PARAM_LIST CtorParams)
// Use this in the edge cases where there's no macro to implement a specific type of isMsg
#define MSG_TYPE_CHECK_(MsgVar, Type) sead::IsDerivedFrom<SensorMsg##Type>(MsgVar)
/*
Implements an isMsg function that checkes if the given message is one of multiple message types.
Implementing a function called isMsgTestAll that checks if the given message is of type
SensorMsgTest or SensorMsgTest2: IS_MSG_MULTIPLE_IMPL(TestAll, Test, Test2);
*/
#define IS_MSG_MULTIPLE_IMPL(Name, ...) \
bool isMsg##Name(const al::SensorMsg* msg) { \
return FOR_EACH_DELIM(MSG_TYPE_CHECK_, LOGICAL_OR, msg, __VA_ARGS__); \
}
/*
Implements an isMsg function that checks if the given message is of a specific message type.
Creating a function called isMsgX that checks if the message is of type SensorMsgTest2:
IS_MSG_IMPL_(X, Test2);
*/
#define IS_MSG_IMPL_(Name, Type) \
bool isMsg##Name(const al::SensorMsg* msg) { \
return MSG_TYPE_CHECK_(msg, Type); \
}
/*
Same as above, but the name of the isMsg function and the SensorMsg are the same.
Creating a function called isMsgTest that checks if the message is of type SensorMsgTest:
IS_MSG_IMPL(Test);
*/
#define IS_MSG_IMPL(Name) IS_MSG_IMPL_(Name, Name)
/*
Implements a sendMsg function that sends a message of the given type.
Creating a function called sendMsgX that sends a SensorMsgTest2:
SEND_MSG_IMPL_(X, Test2);
*/
#define SEND_MSG_IMPL_(Name, Type) \
bool sendMsg##Name(al::HitSensor* receiver, al::HitSensor* sender) { \
SensorMsg##Type msg; \
return alActorSensorFunction::sendMsgSensorToSensor(msg, sender, receiver); \
}
// Same as above, but a shorter version
#define SEND_MSG_IMPL(Name) SEND_MSG_IMPL_(Name, Name)
/*
Implements a sendMsg function that sends a message of the given type to the first sensor of the
actor passed in.
Creating a function called sendMsgX that sends a SensorMsgTest2 to the first sensor
of the target actor:
SEND_MSG_TO_ACTOR_IMPL(X, Test2);
*/
#define SEND_MSG_TO_ACTOR_IMPL_(Name, Type) \
bool sendMsg##Name(al::LiveActor* actor) { \
SensorMsg##Type msg; \
return alActorSensorFunction::sendMsgToActorUnusedSensor(msg, actor); \
}
#define SEND_MSG_TO_ACTOR_IMPL(Name) SEND_MSG_TO_ACTOR_IMPL_(Name, Name)
/*
Implements a sendMsg function that takes in data of a specific type and sends a message of the given
message type with the data. Creating a function called sendMsgX that takes a const char* and sends a
SensorMsgTest2 with that string: SEND_MSG_DATA_IMPL(X, Test2, const char*);
*/
#define SEND_MSG_DATA_IMPL_(Name, Type, DataType) \
bool sendMsg##Name(al::HitSensor* receiver, al::HitSensor* sender, DataType data) { \
SensorMsg##Type msg(data); \
return alActorSensorFunction::sendMsgSensorToSensor(msg, sender, receiver); \
}
// Same as above, but a shorter version
#define SEND_MSG_DATA_IMPL(Name, DataType) SEND_MSG_DATA_IMPL_(Name, Name, DataType)
// Same as SEND_MSG_TO_ACTOR_IMPL but also includes data like the macro above
#define SEND_MSG_DATA_TO_ACTOR_IMPL(Name, DataType) \
bool sendMsg##Name(al::LiveActor* actor, DataType data) { \
SensorMsg##Name msg(data); \
return alActorSensorFunction::sendMsgToActorUnusedSensor(msg, actor); \
}
/*
Similar to SEND_MSG_DATA_IMPL, but for sending a message with multiple different data fields.
Creating a function called sendMsgX that takes a const char* and and a s32 and sends a
SensorMsgTest2 with that string and s32: SEND_MSG_DATA_IMPL(X, Test2, (const char*, String), (s32,
Number));
*/
#define SEND_MSG_DATA_MULTI_IMPL_(Name, Type, ...) \
bool sendMsg##Name(al::HitSensor* receiver, al::HitSensor* sender, PARAM_LIST(__VA_ARGS__)) { \
SensorMsg##Type msg(CALL_PARAM_LIST(__VA_ARGS__)); \
return alActorSensorFunction::sendMsgSensorToSensor(msg, sender, receiver); \
}
// Same as above, but a shorter version
#define SEND_MSG_DATA_MULTI_IMPL(Name, ...) SEND_MSG_DATA_MULTI_IMPL_(Name, Name, __VA_ARGS__)
// Shorter macros for messages that store a ComboCounter (There are 31 of them in al alone)
#define SENSOR_MSG_COMBO(Name) SENSOR_MSG_WITH_DATA(Name, (al::ComboCounter*, ComboCounter))
#define SEND_MSG_COMBO_IMPL_(Name, Type) SEND_MSG_DATA_IMPL_(Name, Type, al::ComboCounter*)
#define SEND_MSG_COMBO_IMPL(Name) SEND_MSG_DATA_IMPL_(Name, Name, al::ComboCounter*)

View file

@ -0,0 +1,582 @@
#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);
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*);
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);
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);
SEND_MSG_IMPL(Vanish);
SEND_MSG_DATA_TO_ACTOR_IMPL(ChangeAlpha, f32);
SEND_MSG_IMPL(ShowModel);
SEND_MSG_IMPL(HideModel);
SEND_MSG_IMPL(Restart);
// TODO: rename variables
SEND_MSG_DATA_MULTI_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**);
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*);
SEND_MSG_IMPL(AtmosOnlineLight);
SEND_MSG_IMPL(LightBurn);
SEND_MSG_IMPL(MoonLightBurn);
SEND_MSG_DATA_IMPL(String, const char*);
SEND_MSG_DATA_MULTI_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_MULTI_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);
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 receiverGravity = getGravity(receiver->getParentActor());
sead::Vector3f receiverUp = -receiverGravity;
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(receiverGravity);
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);
}
__attribute__((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&);
bool sendMsgPushAndKillVelocityToTarget(LiveActor* actor, HitSensor* receiver, HitSensor* sender) {
// BUG: Param ordering is wrong here
if (!sendMsgPush(sender, receiver))
return false;
sead::Vector3f diff = sender->getPos() - receiver->getPos();
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 = sender->getPos() - receiver->getPos();
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;
}
} // namespace al

View file

@ -5,6 +5,8 @@
#include <math/seadVector.h>
#include <prim/seadRuntimeTypeInfo.h>
#include "Library/HitSensor/SensorMsgSetupUtil.h"
namespace al {
class SensorMsg;
@ -310,9 +312,10 @@ bool sendMsgPlayerFloorTouchToColliderGround(LiveActor* receiver, HitSensor* sen
bool sendMsgPlayerUpperPunchToColliderCeiling(LiveActor* receiver, HitSensor* sender);
bool sendMsgEnemyFloorTouchToColliderGround(LiveActor* receiver, HitSensor* sender);
bool sendMsgEnemyUpperPunchToColliderCeiling(LiveActor* receiver, HitSensor* sender);
bool sendMsgAskSafetyPoint(HitSensor* receiver, HitSensor* sender, sead::Vector3f**);
bool sendMsgAskSafetyPoint(HitSensor* receiver, HitSensor* sender,
sead::Vector3f** safetyPointAccessor);
bool sendMsgAskSafetyPointToColliderGround(LiveActor* receiver, HitSensor* sender,
sead::Vector3f**);
sead::Vector3f** safetyPointAccessor);
bool sendMsgTouchAssist(HitSensor* receiver, HitSensor* sender);
bool sendMsgTouchAssistTrig(HitSensor* receiver, HitSensor* sender);
bool sendMsgTouchStroke(HitSensor* receiver, HitSensor* sender);
@ -559,17 +562,18 @@ bool isMsgString(const SensorMsg* msg);
bool isMsgStringV4fPtr(const SensorMsg* msg);
bool isMsgStringV4fSensorPtr(const SensorMsg* msg);
bool isMsgStringVoidPtr(const SensorMsg* msg);
bool isMsgPlayerTrampleForCrossoverSensor(const SensorMsg* msg, const HitSensor*, const HitSensor*);
// Unnamed function at 8FD424 here
bool isMsgPlayerTrampleReflectForCrossoverSensor(const SensorMsg* msg, const HitSensor*,
const HitSensor*);
bool isMsgPlayerUpperPunchForCrossoverSensor(const SensorMsg* msg, const HitSensor*,
const HitSensor*, f32);
bool isMsgKickStoneTrampleForCrossoverSensor(const SensorMsg* msg, const HitSensor*,
const HitSensor*);
bool sendMsgEnemyAttackForCrossoverSensor(HitSensor*, HitSensor*);
bool sendMsgEnemyAttackForCrossoverCylinderSensor(HitSensor*, HitSensor*, const sead::Vector3f&,
const sead::Vector3f&, f32);
bool isMsgPlayerTrampleForCrossoverSensor(const SensorMsg* msg, const HitSensor* sender,
const HitSensor* receiver);
bool isMsgPlayerTrampleReflectForCrossoverSensor(const SensorMsg* msg, const HitSensor* sender,
const HitSensor* receiver);
bool isMsgPlayerUpperPunchForCrossoverSensor(const SensorMsg* msg, const HitSensor* sender,
const HitSensor* receiver, f32 threshold);
bool isMsgKickStoneTrampleForCrossoverSensor(const SensorMsg* msg, const HitSensor* sender,
const HitSensor* receiver);
bool sendMsgEnemyAttackForCrossoverSensor(HitSensor* receiver, HitSensor* sender);
bool sendMsgEnemyAttackForCrossoverCylinderSensor(HitSensor* receiver, HitSensor* sender,
const sead::Vector3f& basePoint,
const sead::Vector3f& upAxis, f32 radius);
bool isSensorPlayer(const HitSensor*);
bool isSensorPlayerFoot(const HitSensor*);
@ -593,8 +597,8 @@ bool isMySensor(const HitSensor*, const LiveActor*);
bool isSensorHitAnyPlane(const HitSensor*, const HitSensor*, const sead::Vector3f&);
bool isSensorHitRingShape(const HitSensor*, const HitSensor*, f32);
bool tryGetEnemyAttackFireMaterialCode(const char**, const SensorMsg*);
bool sendMsgPushAndKillVelocityToTarget(LiveActor*, HitSensor*, HitSensor*);
bool sendMsgPushAndKillVelocityToTargetH(LiveActor*, HitSensor*, HitSensor*);
bool sendMsgPushAndKillVelocityToTarget(LiveActor* actor, HitSensor* receiver, HitSensor* sender);
bool sendMsgPushAndKillVelocityToTargetH(LiveActor* actor, HitSensor* receiver, HitSensor* sender);
bool pushAndAddVelocity(LiveActor*, const HitSensor*, const HitSensor*, f32);
bool pushAndAddVelocityH(LiveActor*, const HitSensor*, const HitSensor*, f32);
bool pushAndAddVelocityV(LiveActor*, const HitSensor*, const HitSensor*, f32);
@ -623,3 +627,233 @@ al::HitSensor* findNearestAttackSensor(const al::HitSensor*);
} // namespace AttackSensorFunction
// Unnamed function at 8FEB0C here
namespace al {
SENSOR_MSG_COMBO(PlayerAttackTrample);
SENSOR_MSG_COMBO(PlayerTrampleReflect);
SENSOR_MSG_COMBO(PlayerAttackHipDrop);
SENSOR_MSG_COMBO(PlayerAttackObjHipDrop);
SENSOR_MSG_COMBO(PlayerAttackObjHipDropReflect);
SENSOR_MSG_COMBO(PlayerAttackObjHipDropHighJump);
SENSOR_MSG(PlayerAttackHipDropKnockDown);
SENSOR_MSG_COMBO(PlayerAttackStatueDrop);
SENSOR_MSG_COMBO(PlayerAttackObjStatueDrop);
SENSOR_MSG_COMBO(PlayerAttackObjStatueDropReflect);
SENSOR_MSG(PlayerAttackObjStatueDropReflectNoCondition);
SENSOR_MSG(PlayerAttackStatueTouch);
SENSOR_MSG(PlayerAttackUpperPunch);
SENSOR_MSG(PlayerAttackObjUpperPunch);
SENSOR_MSG(PlayerAttackRollingAttack);
SENSOR_MSG(PlayerAttackRollingReflect);
SENSOR_MSG(PlayerAttackObjRollingAttack);
SENSOR_MSG(PlayerAttackObjRollingAttackFailure);
SENSOR_MSG_COMBO(PlayerAttackInvincibleAttack);
SENSOR_MSG(PlayerAttackFireBallAttack);
SENSOR_MSG(PlayerAttackRouteDokanFireBallAttack);
SENSOR_MSG_COMBO(PlayerAttackTailAttack);
SENSOR_MSG(PlayerAttackKick);
SENSOR_MSG(PlayerAttackCatch);
SENSOR_MSG_COMBO(PlayerAttackSlidingAttack);
SENSOR_MSG_COMBO(PlayerAttackBoomerangAttack);
SENSOR_MSG(PlayerAttackBoomerangAttackCollide);
SENSOR_MSG(PlayerAttackBoomerangReflect);
SENSOR_MSG(PlayerAttackBoomerangBreak);
SENSOR_MSG_COMBO(PlayerAttackBodyAttack);
SENSOR_MSG_COMBO(PlayerAttackBodyLanding);
SENSOR_MSG_COMBO(PlayerAttackBodyAttackReflect);
SENSOR_MSG_COMBO(PlayerAttackClimbAttack);
SENSOR_MSG_COMBO(PlayerAttackClimbSliding);
SENSOR_MSG_COMBO(PlayerAttackClimbRolling);
SENSOR_MSG_COMBO(PlayerAttackSpinAttack);
SENSOR_MSG_COMBO(PlayerAttackGiant);
SENSOR_MSG_COMBO(PlayerCooperationHipDrop);
SENSOR_MSG_COMBO(PlayerGiantHipDrop);
SENSOR_MSG(PlayerDisregard);
SENSOR_MSG(PlayerDamageTouch);
SENSOR_MSG(PlayerFloorTouchBind); // This msg is referenced by al::isMsgFloorTouchBind, but doesn't
// appear in the executable because it's never used
SENSOR_MSG(PlayerFloorTouch);
SENSOR_MSG(PlayerTouch);
SENSOR_MSG_COMBO(PlayerInvincibleTouch);
SENSOR_MSG(PlayerPutOnEquipment);
SENSOR_MSG(PlayerReleaseEquipment);
SENSOR_MSG_WITH_DATA(PlayerReleaseEquipmentGoal, (u32, Type));
SENSOR_MSG(PlayerCarryFront);
SENSOR_MSG(PlayerCarryFrontWallKeep);
SENSOR_MSG(PlayerCarryUp);
SENSOR_MSG(PlayerCarryKeepDemo);
SENSOR_MSG(PlayerCarryWarp);
SENSOR_MSG(PlayerLeave);
SENSOR_MSG(PlayerRelease);
SENSOR_MSG(PlayerReleaseBySwing);
SENSOR_MSG(PlayerReleaseDead);
SENSOR_MSG(PlayerReleaseDamage);
SENSOR_MSG(PlayerReleaseDemo);
SENSOR_MSG(PlayerToss);
SENSOR_MSG(PlayerItemGet);
SENSOR_MSG(RideAllPlayerItemGet);
SENSOR_MSG(KillerItemGet);
SENSOR_MSG(EnemyAttack);
SENSOR_MSG_WITH_DATA(EnemyAttackFire,
(const char*, MaterialCode)); // Usually null, sometimes "LavaRed"
SENSOR_MSG(EnemyAttackKnockDown);
SENSOR_MSG(EnemyAttackBoomerang);
SENSOR_MSG(EnemyAttackNeedle);
SENSOR_MSG(EnemyFloorTouch);
SENSOR_MSG(EnemyItemGet);
SENSOR_MSG(EnemyRouteDokanAttack);
SENSOR_MSG(EnemyRouteDokanFire);
SENSOR_MSG_COMBO(Explosion);
SENSOR_MSG_COMBO(ExplosionCollide);
SENSOR_MSG(Push);
SENSOR_MSG(PushStrong);
SENSOR_MSG(PushVeryStrong);
SENSOR_MSG(BindStart);
SENSOR_MSG_WITH_DATA(BindInit, (u32, BindType));
SENSOR_MSG(BindEnd);
SENSOR_MSG(BindCancel);
SENSOR_MSG(BindCancelByDemo);
SENSOR_MSG(BindDamage);
SENSOR_MSG(BindSteal);
SENSOR_MSG(BindGiant);
SENSOR_MSG(PressureDeath);
SENSOR_MSG(NpcTouch);
SENSOR_MSG(Hit);
SENSOR_MSG(HitStrong);
SENSOR_MSG(HitVeryStrong);
SENSOR_MSG(KnockDown);
SENSOR_MSG(MapPush);
SENSOR_MSG(Vanish);
SENSOR_MSG_WITH_DATA(ChangeAlpha, (f32, Alpha));
SENSOR_MSG(ShowModel);
SENSOR_MSG(HideModel);
SENSOR_MSG(Restart);
// Impulse
SENSOR_MSG(EnemyTouch);
SENSOR_MSG(EnemyUpperPunch);
SENSOR_MSG(EnemyTrample);
SENSOR_MSG(MapObjTrample);
SENSOR_MSG(NeedleBallAttack);
SENSOR_MSG(PunpunFloorTouch);
SENSOR_MSG(InvalidateFootPrint);
SENSOR_MSG_COMBO(KickKouraAttack);
SENSOR_MSG_COMBO(KickKouraAttackCollide);
SENSOR_MSG(KickKouraGetItem);
SENSOR_MSG(KickKouraReflect);
SENSOR_MSG(KickKouraCollideNoReflect);
SENSOR_MSG(KickKouraBreak);
SENSOR_MSG(KickKouraBlow);
SENSOR_MSG(KickStoneAttack);
SENSOR_MSG(KickStoneAttackCollide);
SENSOR_MSG(KickStoneAttackHold);
SENSOR_MSG(KickStoneAttackReflect);
SENSOR_MSG(KickStoneTrample);
SENSOR_MSG(KillerAttack);
SENSOR_MSG(LiftGeyser);
SENSOR_MSG(WarpStart);
SENSOR_MSG(WarpEnd);
SENSOR_MSG(HoldCancel);
SENSOR_MSG(HoleIn);
SENSOR_MSG(JumpInhibit);
SENSOR_MSG(GoalKill);
SENSOR_MSG(Goal);
SENSOR_MSG_COMBO(BallAttack);
SENSOR_MSG_COMBO(BallRouteDokanAttack);
SENSOR_MSG(BallAttackHold);
SENSOR_MSG(BallAttackDRCHold);
SENSOR_MSG(BallAttackCollide);
SENSOR_MSG_COMBO(BallTrample);
SENSOR_MSG(BallTrampleCollide);
SENSOR_MSG(BallItemGet);
SENSOR_MSG(FireBallCollide);
SENSOR_MSG(FireBallFloorTouch);
SENSOR_MSG(DokanBazookaAttack);
SENSOR_MSG(SwitchOn);
SENSOR_MSG(SwitchOnInit);
SENSOR_MSG(SwitchOffInit);
SENSOR_MSG(SwitchKillOn);
SENSOR_MSG(SwitchKillOnInit);
SENSOR_MSG(SwitchKillOffInit);
SENSOR_MSG_WITH_DATA(AskSafetyPoint, (sead::Vector3f**, SafetyPoint));
SENSOR_MSG(TouchAssist);
SENSOR_MSG(TouchAssistTrig);
// These ten are also referenced by isMsgs but don't appear in the executable
SENSOR_MSG(PlayerGiantTouch);
SENSOR_MSG(PlayerAttackDash);
SENSOR_MSG(TouchAssistNoPat);
SENSOR_MSG(TouchAssistTrigOff);
SENSOR_MSG(TouchAssistTrigNoPat);
SENSOR_MSG(TouchAssistBurn);
SENSOR_MSG(TouchReleaseItem);
SENSOR_MSG(TouchCarryItem);
SENSOR_MSG(KickKouraItemGet);
SENSOR_MSG(TouchStroke);
SENSOR_MSG(IsNerveSupportFreeze);
SENSOR_MSG(OnSyncSupportFreeze);
SENSOR_MSG(OffSyncSupportFreeze);
SENSOR_MSG(ScreenPointInvalidCollisionParts);
SENSOR_MSG_COMBO(BlockUpperPunch);
SENSOR_MSG_COMBO(BlockLowerPunch);
SENSOR_MSG(BlockItemGet);
SENSOR_MSG_COMBO(PlayerKouraAttack);
SENSOR_MSG(LightFlash);
SENSOR_MSG(ForceAbyss);
SENSOR_MSG(SwordAttackHighLeft);
SENSOR_MSG(SwordAttackHighRight);
SENSOR_MSG(SwordAttackLow);
SENSOR_MSG(SwordAttackLowLeft);
SENSOR_MSG(SwordAttackLowRight);
SENSOR_MSG(SwordBeamAttack);
SENSOR_MSG(SwordBeamReflectAttack);
SENSOR_MSG(SwordAttackJumpUnder);
SENSOR_MSG(ShieldGuard);
SENSOR_MSG(AskMultiPlayerEnemy);
SENSOR_MSG(ItemGettable);
SENSOR_MSG(KikkiThrow);
SENSOR_MSG(IsKikkiThrowTarget);
SENSOR_MSG(PlayerCloudGet);
SENSOR_MSG(AutoJump);
SENSOR_MSG(PlayerTouchShadow);
SENSOR_MSG(PlayerPullOutShadow);
SENSOR_MSG(PlayerAttackShadow);
SENSOR_MSG(PlayerAttackShadowStrong);
SENSOR_MSG_WITH_DATA(PlayerAttackChangePos, (sead::Vector3f*, Pos));
SENSOR_MSG(AtmosOnlineLight);
SENSOR_MSG(LightBurn);
SENSOR_MSG(MoonLightBurn);
SENSOR_MSG_WITH_DATA(String, (const char*, Str));
SENSOR_MSG_WITH_DATA(StringV4fPtr, (const char*, Str), (sead::Vector4f*, Vec));
SENSOR_MSG_WITH_DATA(StringV4fSensorPtr, (const char*, Str), (sead::Vector4f*, Vec),
(HitSensor*, Sensor));
SENSOR_MSG_WITH_DATA(StringVoidPtr, (const char*, Str), (void*, Ptr));
// TODO: rename variables
SENSOR_MSG_WITH_DATA_CUSTOM_CTOR(CollidePush, ((sead::Vector3f, Vec)),
((const sead::Vector3f&, Vec))) {
mVec.set(pVec);
}
// TODO: rename variables
SENSOR_MSG_WITH_DATA_CUSTOM_CTOR(CollisionImpulse,
((sead::Vector3f*, VecPtr), (const sead::Vector3f*, ConstVec),
(f32, FloatVal), (const sead::Vector3f*, ConstVec2),
(f32, FloatVal2)),
((sead::Vector3f*, VecPtr), (const sead::Vector3f&, VecRef),
(f32, FloatVal), (const sead::Vector3f&, VecRef2),
(f32, FloatVal2))) {
mVecPtr = pVecPtr;
mConstVec = &pVecRef;
mFloatVal = pFloatVal;
mConstVec2 = &pVecRef2;
mFloatVal2 = pFloatVal2;
}
} // namespace al

View file

@ -60,12 +60,16 @@ public:
const sead::Vector3f& getFollowPosOffset() const { return mFollowPosOffset; }
const sead::Vector3f& getPos() const { return mPos; }
f32 getRadius() const { return mRadius; }
void setFollowPosOffset(const sead::Vector3f& offset) { mFollowPosOffset.set(offset); }
void setRadius(f32 radius) { mRadius = radius; }
LiveActor* getParentActor() const { return mParentActor; }
void scaleY(f32 scaleY) {
mRadius *= scaleY;
mFollowPosOffset.y *= scaleY;

View file

@ -47,9 +47,9 @@ void SupportFreezeSyncGroup::movement() {
for (s32 i = 0; i < mActorCount; i++)
if (isAnyNerveSupportFreeze)
sendMsgOnSyncSupportFreeze(mActors[i]->getHitSensorKeeper()->getSensor(0), mHostSensor);
else
sendMsgOffSyncSupportFreeze(mActors[i]->getHitSensorKeeper()->getSensor(0),
mHostSensor);
else
sendMsgOnSyncSupportFreeze(mActors[i]->getHitSensorKeeper()->getSensor(0), mHostSensor);
}
} // namespace al

View file

@ -129,7 +129,7 @@ bool EnemyStateSwoon::tryReceiveMsgTrampleReflect(const al::SensorMsg* message)
bool EnemyStateSwoon::tryReceiveMsgTrampleReflect(const al::SensorMsg* message,
const al::HitSensor* other,
const al::HitSensor* self) {
if (al::isMsgPlayerTrampleForCrossoverSensor(message, other, self))
if (al::isMsgPlayerTrampleReflectForCrossoverSensor(message, other, self))
return tryReceiveMsgTrampleReflect(message);
return false;
}

View file

@ -73,7 +73,7 @@ void Popn::attackSensor(al::HitSensor* self, al::HitSensor* other) {
al::sendMsgPushAndKillVelocityToTarget(this, self, other);
if (al::isSensorEnemyAttack(self))
rs::sendMsgPushToPlayer(other, self) || al::sendMsgEnemyAttack(other, self);
al::sendMsgEnemyAttack(other, self) || rs::sendMsgPushToPlayer(other, self);
}
bool Popn::receiveMsg(const al::SensorMsg* message, al::HitSensor* other, al::HitSensor* self) {

View file

@ -40,9 +40,9 @@ AppearSwitchSave::AppearSwitchSave(al::LiveActor* actor, const al::ActorInitInfo
mKillTargetArray[i] = al::createLinksActorFromFactory(info, "KillTarget", i);
if (mIsOn) {
if (mKillTargetArray[i]->getHitSensorKeeper())
al::sendMsgSwitchOnInit(mKillTargetArray[i]);
al::sendMsgSwitchKillOnInit(mKillTargetArray[i]);
} else if (mKillTargetArray[i]->getHitSensorKeeper()) {
al::sendMsgSwitchOffInit(mKillTargetArray[i]);
al::sendMsgSwitchKillOffInit(mKillTargetArray[i]);
}
}

View file

@ -50,7 +50,7 @@ bool ShineTowerBackDoor::receiveMsg(const al::SensorMsg* message, al::HitSensor*
if (_118)
return false;
if (al::isMsgPlayerHipDropAll(message)) {
if (al::isMsgPlayerObjHipDropAll(message)) {
mBindTimer = 3;
return false;
}

View file

@ -286,7 +286,7 @@ def common_string_finder(c, path):
if not match.startswith("u"):
# Remove quotes from utf8 strings
match = match[1:-1]
if len(match) < 2:
if len(match) < 2:
continue
found = False
for x in string_table:
@ -443,6 +443,7 @@ def header_check_line(line, path, visibility, should_start_class, is_in_struct):
else:
allowed_name = (var_name.startswith("m") and var_name[1].isupper()) or any(
[var_name.startswith(p) for p in PREFIXES])
if path.endswith("SensorMsgSetupUtil.h") and "DECL_MEMBER_VAR_MULTI" in line: return
CHECK(lambda a: allowed_name, line, "Member variables must be prefixed with `m`!", path)
if var_type == "bool":