mirror of
https://github.com/MonsterDruide1/OdysseyDecomp
synced 2026-04-26 18:44:33 +00:00
217 lines
11 KiB
C++
217 lines
11 KiB
C++
#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 CtorParams; \
|
|
\
|
|
virtual ~SensorMsg##Type() = default; \
|
|
\
|
|
private: \
|
|
DECL_MEMBER_VAR_MULTI SensorMsgParams; \
|
|
}; \
|
|
inline SensorMsg##Type::SensorMsg##Type(PARAM_LIST CtorParams)
|
|
|
|
/*
|
|
|
|
Same as above, but returns the actual stored field types from the getters
|
|
instead of the constructor parameter types. Useful when the stored data
|
|
types differ from the constructor argument types
|
|
|
|
*/
|
|
|
|
#define SENSOR_MSG_WITH_DATA_CUSTOM_CTOR_DIRECT_GETTERS(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* receiver) { \
|
|
SensorMsg##Type msg; \
|
|
return alActorSensorFunction::sendMsgToActorUnusedSensor(msg, receiver); \
|
|
}
|
|
|
|
#define SEND_MSG_TO_ACTOR_IMPL(Name) SEND_MSG_TO_ACTOR_IMPL_(Name, Name)
|
|
|
|
// Same as SEND_MSG_TO_ACTOR_IMPL but also includes data like the macro above
|
|
#define SEND_MSG_DATA_TO_ACTOR_IMPL(Name, DataType, DataName) \
|
|
bool sendMsg##Name(al::LiveActor* receiver, DataType DataName) { \
|
|
SensorMsg##Name msg(DataName); \
|
|
return alActorSensorFunction::sendMsgToActorUnusedSensor(msg, receiver); \
|
|
}
|
|
|
|
/*
|
|
|
|
Implements a sendMsg function that takes in any number data variables and sends a message of the
|
|
given message type with the data. 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_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_IMPL(Name, ...) SEND_MSG_DATA_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*, ComboCounter))
|
|
#define SEND_MSG_COMBO_IMPL(Name) SEND_MSG_DATA_IMPL_(Name, Name, (al::ComboCounter*, ComboCounter))
|