Files
libsm64/src/FakeObject.c
T
NepuShiro 42132a5646
Build libsm64 / Build libsm64 for linux (push) Successful in 33s
Build libsm64 / Build libsm64 for web (push) Successful in 33s
Build libsm64 / Build libsm64 for windows (push) Successful in 25s
test synced pole
2026-06-01 14:54:23 -05:00

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;
}
}