218 lines
5.3 KiB
C
218 lines
5.3 KiB
C
//
|
|
// Created by nepushiro on 5/29/26.
|
|
//
|
|
|
|
#include "FakeObject.h"
|
|
|
|
#include <string.h>
|
|
|
|
#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 <stdint.h>
|
|
#include <stdbool.h>
|
|
#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;
|
|
}
|
|
}
|