1#include <game/bases/d_cc.hpp>
2#include <game/bases/d_s_stage.hpp>
3#include <game/bases/d_bg.hpp>
12char dCc_c::msIsInitialized;
42 for (
unsigned int i = 0; i < ARRAY_SIZE(
mCollOffsetX); i++) {
104 const static hitCheck checks[3] = {
109 _hitCheck[0][0] = checks[dScStage_c::m_loopType];
145 float _unused = (1.0f / 256.f);
201 if ((catInteract1 & catMask2) && (catInteract2 & catMask1)) {
212 && (attCatMask2 & attInteract1) == 0
217 && (attCatMask1 & attInteract2) == 0
231 if (attInteract1 & attCatMask2) {
234 if (attCatMask1 & attInteract2) {
235 c1->
mAttSent |= attInteract2 & attCatMask1;
240 if (attInteract1 & attCatMask2) {
241 c2->
mAttSent |= attInteract1 & attCatMask2;
243 if (attCatMask1 & attInteract2) {
273 float xDist = pos1.x - pos2.x;
275 float yDist = pos1.y - pos2.y;
278 if (EGG::Mathf::abs(xDist) < collSizeX && EGG::Mathf::abs(yDist) < collSizeY) {
291 float offsetX = (collSizeX - EGG::Mathf::abs(xDist)) / 2;
296 float offsetY = (collSizeY - EGG::Mathf::abs(yDist)) / 2;
331 p1.
incX(dBg_c::m_bg_p->mLoopOffset);
333 p2.
incX(dBg_c::m_bg_p->mLoopOffset);
350 float collSizeRadius = (collSizeX + collSizeY) / 2;
353 if (distVec.
getLength() <= collSizeRadius) {
355 float dist = collSizeRadius - distVec.
getLength();
356 s16 ang =
cM::atan2s(distVec.y, EGG::Mathf::abs(distVec.x));
385#define DIR2SCALE(dir) (1.0f - dir * 2.0f)
388 dCc_c *boxCc, *circleCc;
405 float closerEdgeX[] = {
409 float closerEdgeY[] = {
414 if (closerEdgeY[ABOVE] < circlePos.y && circlePos.y < closerEdgeY[BELOW]) {
416 float colliderXDist = DIR2SCALE(boxSideX) * (circlePos.x - closerEdgeX[boxSideX]);
417 if (colliderXDist < circleRadius) {
420 float circleOffsetX = DIR2SCALE(boxSideX) * (circleRadius - colliderXDist) / 2;
433 if (closerEdgeX[RIGHT] < circlePos.x && circlePos.x < closerEdgeX[LEFT]) {
435 float smthA = DIR2SCALE(boxSideY) * (circlePos.y - closerEdgeY[boxSideY]);
436 if (smthA < circleRadius) {
440 float circleOffsetY = DIR2SCALE(boxSideY) * (circleRadius - smthA) / 2;
455 mVec2_c closerCorner(closerEdgeX[boxSideX], closerEdgeY[boxSideY]);
456 mVec2_c distVec = circlePos - closerCorner;
457 float distance = distVec.normalise();
458 if (distance < circleRadius) {
459 float offsetBy = (circleRadius - distance) / 2;
475enum LINE_CHECK_RESULT_e {
483inline float ratioX(
mVec2_c diff,
float v) {
484 return v * diff.y / diff.x;
487inline float ratioY(
mVec2_c diff,
float v) {
488 return v * diff.x / diff.y;
491int dCc_c::_lineCheckUD(
mVec2_c p1,
mVec2_c p2,
float x,
float y) {
492 if (p1.x > x || p2.x < x) {
496 float scaled = ratioX(p2 - p1, x - p1.x);
497 if (scaled + p1.y < y) {
517 if (EGG::Mathf::abs(trpCenter.x - boxCenter.x) >= collSizeX) {
531 if (trpCorner1.y < boxBottom && trpCorner3.y < boxBottom) {
534 if (trpCorner2.y > boxTop && trpCorner4.y > boxTop) {
538 if (!(boxLeft <= trpCorner1.x) || !(trpCorner3.x <= boxRight)) {
539 if (_lineCheckUD(trpCorner1, trpCorner3, boxLeft, boxBottom) != THREE
540 && _lineCheckUD(trpCorner1, trpCorner3, boxRight, boxBottom) != THREE) {
544 if (_lineCheckUD(trpCorner2, trpCorner4, boxLeft, boxTop) != TWO
545 && _lineCheckUD(trpCorner2, trpCorner4, boxRight, boxTop) != TWO) {
563int dCc_c::_lineCheckLR(
mVec2_c p1,
mVec2_c p2,
float x,
float y) {
564 if (p1.y < y || p2.y > y) {
568 float scaled = ratioY(p1 - p2, y - p2.y);
569 if (scaled + p2.x < x) {
589 if (EGG::Mathf::abs(p1.y - p2.y) >= heightSum) {
603 if (trpCorner1.x > boxRight && trpCorner3.x > boxRight) {
606 if (trpCorner2.x < boxLeft && trpCorner4.x < boxLeft) {
610 if (!(boxBottom <= trpCorner3.y) || !(trpCorner1.y <= boxTop)) {
611 if (_lineCheckLR(trpCorner1, trpCorner3, boxRight, boxTop) != ZERO
612 && _lineCheckLR(trpCorner1, trpCorner3, boxRight, boxBottom) != ZERO) {
616 if (_lineCheckLR(trpCorner2, trpCorner4, boxLeft, boxTop) != ONE
617 && _lineCheckLR(trpCorner2, trpCorner4, boxLeft, boxBottom) != ONE) {
float getLength() const
Gets the length of the vector.
mVec3_c mPos
The actor's position.
Collider ("Collision Check") class - handles collisions between actors.
mVec2_c getCenterVec()
Gets the center of the collider as a vector.
static bool _hitCheckSquare(dCc_c *c1, dCc_c *c2, mVec2_c pos1, mVec2_c pos2)
A hit check function for rectangular colliders. Used in _hitCheckNormal and _hitCheckLoop.
bool mIsLinked
Whether this collider has been placed in the collider list.
u8 mFlag
Flags for this collider. See CC_FLAG_e .
static bool checkCollision(dCc_c *c1, dCc_c *c2, int active)
Checks for collisions between two colliders.
u8 mNonCollideMask
The non-collide mask for this collider.
static bool _hitCheckDaikeiUD_R(dCc_c *ccBox, dCc_c *ccTrp)
Check a rectangular collider against a trapezoid-shaped collider for collisions.
dActor_c * mpOwner
The actor this collider belongs to.
float getUnderPos()
Gets the Y position of the bottom of the collider.
static bool _hitCheckLoop(dCc_c *c1, dCc_c *c2)
Check two rectangular colliders against each other for collisions with stage looping.
float getTopPos()
Gets the Y position of the top of the collider.
static dCc_c * mEntryN
The first collider in the list.
u16 isHitAtDmg(u16 mask) const
Gets the result of an attack hit check.
dCc_c * mpPrev
The previous collider in the list.
void clear()
Clear the data related to previous collisions.
float getCenterPosY()
Gets the Y position of the center of the collider.
float mCollOffsetY[8]
The Y offset for a collision.
void entry()
Places this collider in the collider list.
u16 mCollidedWith
The categories of the previously collided with colliders.
u8 mShape
The shape of the collider. See CC_SHAPE_e .
u16 mAttSent
The attack types sent by this collider in the previous collisions.
u16 isHit(u16 mask) const
Gets the result of a hit check.
static hitCheck _hitCheck[4][4]
The hit check function for each combination of collider shapes.
u16 mAttReceived
The attack types received by this collider in the previous collisions.
u8 mLayer
The layer this collider is on.
@ CC_SHAPE_BOX
Rectangular collider.
@ CC_SHAPE_CIRCLE
Circular / elliptical collider.
void registerCc(dActor_c *actor, CcData_s *collInfo)
Registers an owner actor to this collider and sets the collider data.
CcData_s mCcData
The collision data of this collider.
float getCenterPosX()
Gets the X position of the center of the collider.
static bool _hitCheckCircle(dCc_c *c1, dCc_c *c2)
Check two circle colliders against each other for collisions.
float getLeftPos()
Gets the X position of the left side of the collider.
@ CC_DATA_NO_OFFSET
Don't set the collision offset if a collision occurs.
mVec2_c mCollPos
The position where the last collision occurred.
float getRightPos()
Gets the X position of the right side of the collider.
static bool _hitCheckDaikeiLR_R(dCc_c *ccBox, dCc_c *ccTrp)
Check a rectangular collider against a trapezoid-shaped collider for collisions.
virtual ~dCc_c()
Destroys the collider.
static void execute()
Check all colliders against each other for collisions.
dActor_c * mFriendActor
A second actor that this collider will not collide with.
void release()
Removes this collider from the collider list.
float mCollOffsetX[8]
The X offset for a collision.
static bool _hitCheckDaikeiLR(dCc_c *ccTrp, dCc_c *ccBox)
Check a trapezoid-shaped collider against a rectangular collider for collisions.
@ CC_DISABLE
Disables all collisions with this collider.
static bool _hitCheckBoxCircle(dCc_c *c1, dCc_c *c2)
Check a rectangular and a circle collider against each other for collisions.
static void reset()
Clears the collider list.
dCc_c * mpNext
The next collider in the list.
dCc_c()
Constructs a new collider.
static dCc_c * mEntryB
The last collider in the list.
static bool _hitCheckNormal(dCc_c *c1, dCc_c *c2)
Check two rectangular colliders against each other for collisions without stage looping.
static bool _hitCheckDaikeiUD(dCc_c *ccTrp, dCc_c *ccBox)
Check a trapezoid-shaped collider against a rectangular collider for collisions.
bool isInside(dCc_c *other)
Checks if this collider is inside another collider.
A two-dimensional floating point vector.
void incX(float x)
Increments the X coordinate.
s16 atan2s(float sin, float cos)
Converts a sine and a cosine to an angle in units.
float CosS(short ang)
Computes the cosine value.
float SinS(short ang)
Computes the sine value.
A structure that contains information about a collider.
void(* mCallback)(dCc_c *, dCc_c *)
The callback to execute when a collision occurs.
float mHeight
The height of the collider.
u32 mAttackCategoryInteract
Which attack categories this collider should be able to receive.
u8 mAttackCategory
The attack category of this collider. See CC_ATTACK_e .
float mOffsetX
The X offset of the collider.
u32 mCategoryInteract
Which categories this collider should be able to collide with.
float mWidth
The width of the collider.
u16 mFlag
Flags for this collider. See CC_DATA_FLAG_e .
float mOffsetY
The Y offset of the collider.
u8 mCategory
The category of this collider. See CC_CATEGORY_e .