// // Created by nepushiro on 5/29/26. // #include "FakeObject.h" #include #include "decomp/global_state.h" #include "decomp/engine/math_util.h" #include "decomp/game/interaction.h" #include "decomp/game/object_stuff.h" #include "decomp/include/object_fields.h" #include "libsm64.h" #include #include #include "decomp/shim.h" #define o gCurrentObject struct Object *cur_obj_find_nearest_pole(void) { struct Object *closestObj = NULL; struct Object *obj; f32 minDist = 0x20000; for (s32 i = 0; i < s_fakeobj_instance_pool.size; i++) { obj = s_fakeobj_instance_pool.objects[i]; if (obj == NULL) continue; if (obj->activeFlags == ACTIVE_FLAG_DEACTIVATED) continue; if (!(obj->oInteractType & INTERACT_POLE)) continue; if (obj == o) continue; f32 objDist = dist_between_objects(o, obj); if (objDist < minDist) { closestObj = obj; minDist = objDist; } } return closestObj; } f32 dist_between_objects(struct Object *obj1, struct Object *obj2) { if (obj1 == NULL || obj2 == NULL) { return 0; } f32 dx = obj1->oPosX - obj2->oPosX; f32 dy = obj1->oPosY - obj2->oPosY; f32 dz = obj1->oPosZ - obj2->oPosZ; return sqrtf(dx * dx + dy * dy + dz * dz); } void fake_object_init(struct FakeObject *fake, float x, float y, float z) { memset(fake, 0, sizeof(*fake)); struct Object *obj = &fake->object; obj->activeFlags = ACTIVE_FLAG_ACTIVE | ACTIVE_FLAG_UNK8; obj->parentObj = NULL; obj->prevObj = NULL; obj->collidedObjInteractTypes = 0; obj->numCollidedObjs = 0; for (s32 i = 0; i < 0x50; i++) { #ifdef _WIN32 obj->rawData.asS32[i] = 0; #endif #ifdef _WIN64 obj->ptrData.asVoidPtr[i] = NULL; #endif } obj->unused1 = 0; obj->bhvStackIndex = 0; obj->bhvDelayTimer = 0; obj->hitboxRadius = 50.0f; obj->hitboxHeight = 100.0f; obj->hurtboxRadius = 0.0f; obj->hurtboxHeight = 0.0f; obj->hitboxDownOffset = 0.0f; obj->unused2 = 0; obj->platform = NULL; obj->collisionData = NULL; obj->oIntangibleTimer = -1; obj->oDamageOrCoinValue = 0; obj->oHealth = 2048; obj->oCollisionDistance = 1000.0f; obj->oDrawingDistance = 4000.0f; mtxf_identity(obj->transform); obj->respawnInfoType = RESPAWN_INFO_TYPE_NULL; obj->respawnInfo = NULL; obj->oDistanceToMario = 19000.0f; obj->oRoom = -1; obj->oInteractType = 0; obj->oInteractionSubtype = 0; obj->oHeldState = 0; obj->oAction = 0; obj->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; obj->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE; obj->header.gfx.node.flags &= ~GRAPH_RENDER_BILLBOARD; obj->header.gfx.pos[0] = x; obj->header.gfx.pos[1] = y; obj->header.gfx.pos[2] = z; obj->header.gfx.angle[0] = 0; obj->header.gfx.angle[1] = 0; obj->header.gfx.angle[2] = 0; obj->header.gfx.throwMatrix = NULL; obj->header.gfx.sharedChild = NULL; obj->header.gfx.animInfo.curAnim = NULL; obj->header.gfx.animInfo.animID = 0; obj->header.gfx.animInfo.animFrame = 0; obj->header.gfx.animInfo.animTimer = 0; obj->oPosX = x; obj->oPosY = y; obj->oPosZ = z; obj->oMoveAnglePitch = 0; obj->oMoveAngleYaw = 0; obj->oMoveAngleRoll = 0; obj->oFaceAnglePitch = 0; obj->oFaceAngleYaw = 0; obj->oFaceAngleRoll = 0; } void fake_object_sync_position(struct FakeObject *fake) { struct Object *obj = &fake->object; obj->header.gfx.pos[0] = obj->oPosX; obj->header.gfx.pos[1] = obj->oPosY; obj->header.gfx.pos[2] = obj->oPosZ; } bool fake_object_overlaps_mario(struct FakeObject *fake, struct MarioState *m) { struct Object *obj = &fake->object; float dx = obj->oPosX - m->pos[0]; float dz = obj->oPosZ - m->pos[2]; float radius = obj->hitboxRadius; float top = obj->oPosY + obj->hitboxHeight; float bottom = obj->oPosY - obj->hitboxDownOffset; if ((dx * dx) + (dz * dz) > radius * radius) { return false; } if (m->pos[1] < bottom || m->pos[1] > top) { return false; } return true; } void fake_object_add_collision(struct FakeObject *fake, struct MarioState *m) { struct Object *obj = &fake->object; if (obj->oHeldState != 0) { return; } m->marioObj->collidedObjInteractTypes |= obj->oInteractType; if (m->marioObj->numCollidedObjs < 4) { m->marioObj->collidedObjs[m->marioObj->numCollidedObjs++] = obj; } } void fake_object_apply_pole(struct FakeObject *fake) { (void)fake; } void fake_object_set_preset(struct FakeObject *fake, uint32_t preset) { struct Object *obj = &fake->object; switch (preset) { case 1: obj->oInteractType = INTERACT_POLE; obj->oInteractionSubtype = 0; obj->hitboxRadius = 60.0f; obj->hitboxHeight = 1000.0f; obj->hitboxDownOffset = 0.0f; break; case 0: default: obj->oInteractType = 0; obj->oInteractionSubtype = 0; obj->hitboxRadius = 50.0f; obj->hitboxHeight = 100.0f; obj->hitboxDownOffset = 0.0f; break; } }