d_t_beetle

This commit is contained in:
Cole Barker
2026-05-10 22:00:38 -04:00
parent f637091a32
commit ebfd1aaa0e
3 changed files with 173 additions and 11 deletions
+126
View File
@@ -1,3 +1,129 @@
#include "d/t/d_t_beetle.h"
#include "d/a/d_a_player.h"
#include "d/a/obj/d_a_obj_base.h"
#include "d/a/obj/d_a_obj_boomerang.h"
#include "d/d_sc_game.h"
#include "d/flag/sceneflag_manager.h"
#include "toBeSorted/area_math.h"
#include "toBeSorted/time_area_mgr.h"
SPECIAL_ACTOR_PROFILE(BEETLE_TAG, dTgBeetle_c, fProfile::BEETLE_TAG, 0x297, 0, 0);
int dTgBeetle_c::create() {
if (dScGame_c::currentSpawnInfo.stageName == "F103") { // flooded faron woods
if (mActorSubtype) {
mScale *= 0.01f;
}
// Haven't verfied but I think CO_TEST is an invisible sphere created around leaves
// underwater to prevent you from swimming through trees
dAcObjBase_c::create(fProfile::CO_TEST, mRoomID, 0, &mPosition, &mRotation, &mScale, 0xFFFFFFFF);
return FAILED;
} else {
if (!mActorSubtype) { // BtlTg
mZoneType = getFromParams(0, 0xF);
mZoneShape = getFromParams(4, 0x3);
mUnknown = getFromParams(6, 0xFF);
mBeetleFlag = getFromParams(0xE, 0xFF);
mPastOnly = getFromParams(0x16, 0x3);
} else {
mZoneType = LeafZone;
if (mActorSubtype == BtlTgA) { // BtlTgA
mZoneShape = RectangularPrismShape;
} else if (mActorSubtype == BtlTgB) { // BtlTgB
mZoneShape = CylinderShape;
} else if (mActorSubtype == BtlTgC) { // BtlTgC
mZoneShape = SphereShape;
}
}
matrixCreateFromPosRotYScale(mMatrix1, mPosition, mRotation.y, mScale, nullptr, 0);
return SUCCEEDED;
}
}
int dTgBeetle_c::doDelete() {
return SUCCEEDED;
}
int dTgBeetle_c::actorExecute() {
if (mPastOnly == 1 && !mActorSubtype) {
if (dTimeAreaMgr_c::GetInstance()->checkPositionIsInPastState(mRoomID, mPosition, nullptr, 1.0f) == 0) {
return SUCCEEDED;
}
}
if (!SceneflagManager::sInstance->checkBoolFlag(mRoomID, mBeetleFlag) || mActorSubtype) {
dAcBoomerang_c *beetlePtr =
(dAcBoomerang_c *)dAcPy_c::GetLink()
->vt_0x1C0(); // boomerang pointer cast required because function currently returns void*
if (mZoneShape == RectangularPrismShape) { // rectangular prism
if (beetlePtr && checkAreaBox(mMatrix1, beetlePtr->mPosition)) {
updateBeetle(*beetlePtr);
}
} else if (mZoneShape == CylinderShape) { // cylinder
if (beetlePtr && isWithinCylinder((beetlePtr->mPosition))) {
updateBeetle(*beetlePtr);
}
} else if (mZoneShape == SphereShape) { // sphere
if (beetlePtr && isWithinSphere((beetlePtr->mPosition))) {
updateBeetle(*beetlePtr);
}
}
}
return SUCCEEDED;
}
u32 dTgBeetle_c::isWithinSphere(
const mVec3_c &position
) const { // fn_302_520 is position within a sphere the size of the zone
mVec3_c diff = position - (mPosition + mScale.y * mVec3_c::Ey * 1.0f);
diff.x /= mScale.x;
diff.y /= mScale.y;
diff.z /= mScale.z;
return diff.mag() <= 1.0f; // is beetle within a certain distance from center
}
u32 dTgBeetle_c::isWithinCylinder(
const mVec3_c &position
) const { // is position within a really thin cylinder inside the zone
mVec3_c diff = (position - (mPosition + mVec3_c::Ey * mScale.y * 0.5f));
bool returnValue = 0;
bool returnCheck = 0;
diff.x /= mScale.x;
diff.y /= mScale.y;
diff.z /= mScale.z;
if (diff.absXZ() <= 0.01f && diff.y <= 0.5f) {
returnCheck = 1;
}
if (returnCheck && diff.y >= -0.5f) {
returnValue = 1;
}
return returnValue;
}
void dTgBeetle_c::updateBeetle(dAcBoomerang_c &boomerang) { // fn_302_620 update beetle based on zone type
if (mZoneType == LeafZone) { // leaf zone
return boomerang.setField_0x8CC(0x20);
} else if (mZoneType == BorderZone) { // border zone, reduce flight time
return boomerang.setRemainingFlightTime(0x3C);
} else if (mZoneType == UnknownZone) { //???
return boomerang.setField_0x8CC(0x80);
} else { // instant flashing red
return boomerang.setRemainingFlightTime(-1);
}
}
int dTgBeetle_c::draw() {
return 1;
}