//
// Generated by dtk
// Translation Unit: f_op_actor_mng.cpp
//

#include "f_op/f_op_actor_mng.h"
#include "f_op/f_op_actor.h"
#include "f_op/f_op_scene_mng.h"
#include "d/d_com_inf_game.h"
#include "d/d_item_data.h"
#include "d/d_stage.h"
#include "d/d_procname.h"
#include "d/d_item.h"
#include "d/d_item_data.h"
#include "d/actor/d_a_player.h"
#include "d/actor/d_a_player_link.h"
#include "d/actor/d_a_item.h"
#include "d/actor/d_a_sea.h"
#include "m_Do/m_Do_ext.h"
#include "m_Do/m_Do_lib.h"
#include "m_Do/m_Do_printf.h"
#include "m_Do/m_Do_mtx.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JKernel/JKRSolidHeap.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "SSystem/SComponent/c_malloc.h"

/* 80024060-80024104       .text fopAcM_setStageLayer__FPv */
void fopAcM_setStageLayer(void* pProc) {
    scene_class* stageProc = fopScnM_SearchByID(dStage_roomControl_c::getProcID());
    JUT_ASSERT(0xee, stageProc != 0);
    fpcM_ChangeLayerID(pProc, fopScnM_LayerID(stageProc));
}

/* 80024104-800241C0       .text fopAcM_setRoomLayer__FPvi */
void fopAcM_setRoomLayer(void* pProc, int room_no) {
    if (room_no >= 0) {
        scene_class* roomProc = fopScnM_SearchByID(dStage_roomControl_c::getStatusProcID(room_no));
        JUT_ASSERT(0x105, roomProc != 0);
        fpcM_ChangeLayerID(pProc, fopScnM_LayerID(roomProc));
    }
}

/* 800241C0-80024230       .text fopAcM_SearchByID__FUiPP10fopAc_ac_c */
s32 fopAcM_SearchByID(unsigned int actorID, fopAc_ac_c** pDstActor) {
    if (fpcM_IsCreating(actorID)) {
        *pDstActor = NULL;
    } else {
        fopAc_ac_c *pActor = (fopAc_ac_c *) fopAcIt_Judge((fopAcIt_JudgeFunc)fpcSch_JudgeByID, &actorID);
        *pDstActor = pActor;
        if (*pDstActor == NULL)
            return 0;
    }

    return 1;
}

/* 80024230-800242AC       .text fopAcM_SearchByName__FsPP10fopAc_ac_c */
s32 fopAcM_SearchByName(s16 procName, fopAc_ac_c** pDstActor) {
    *pDstActor = (fopAc_ac_c*) fopAcIt_Judge((fopAcIt_JudgeFunc)fpcSch_JudgeForPName, &procName);
    if (*pDstActor == NULL) {
        return 0;
    } else {
        if (fpcM_IsCreating(fopAcM_GetID(*pDstActor))) {
            *pDstActor = NULL;
        }
        return 1;
    }
}

/* 800242AC-80024320       .text fopAcM_CreateAppend__Fv */
fopAcM_prm_class* fopAcM_CreateAppend() {
    fopAcM_prm_class* params = (fopAcM_prm_class*) cMl::memalignB(-4, sizeof(fopAcM_prm_class));
    if (params != NULL) {
        cLib_memSet(params, 0, sizeof(fopAcM_prm_class));
        params->mSetId = 0xFFFF;
        params->mRoomNo = -1;
        params->mScale[0] = 10;
        params->mScale[1] = 10;
        params->mScale[2] = 10;
        params->mParentPcId = -1;
        params->mSubtype = -1;
    }
    return params;
}

/* 80024320-80024474       .text createAppend__FUlP4cXyziP5csXyzP4cXyzScUi */
fopAcM_prm_class * createAppend(u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, s8 subtype, unsigned int parentPcId) {
    fopAcM_prm_class * params = fopAcM_CreateAppend();
    if (params == NULL)
        return NULL;

    if (pPos != NULL)
        params->mPos = *pPos;
    else
        params->mPos = cXyz::Zero;

    params->mRoomNo = roomNo;

    if (pAngle != NULL)
        params->mAngle = *pAngle;
    else
        params->mAngle = csXyz::Zero;

    if (pScale != NULL) {
        params->mScale[0] = 10.0f * pScale->x;
        params->mScale[1] = 10.0f * pScale->y;
        params->mScale[2] = 10.0f * pScale->z;
    } else {
        params->mScale[0] = 10.0f;
        params->mScale[1] = 10.0f;
        params->mScale[2] = 10.0f;
    }

    params->mParameter = parameter;
    params->mParentPcId = parentPcId;
    params->mSubtype = subtype;

    return params;
}

/* 80024474-80024478       .text fopAcM_Log__FP10fopAc_ac_cPc */
void fopAcM_Log(fopAc_ac_c*, char*) {
    /* Empty function */
}

/* 80024478-800244B8       .text fopAcM_delete__FP10fopAc_ac_c */
s32 fopAcM_delete(fopAc_ac_c* pActor) {
    /* "Deleting Actor" */
    fopAcM_Log(pActor, "アクターの削除");
    return fpcM_Delete(pActor);
}

/* 800244B8-8002451C       .text fopAcM_delete__FUi */
s32 fopAcM_delete(unsigned int actorID) {
    fopAc_ac_c* pActor = (fopAc_ac_c*)fopAcM_SearchByID(actorID);

    if (pActor != NULL) {
        /* "Deleting Actor" */
        fopAcM_Log(pActor, "アクターの削除");
        return fpcM_Delete(pActor);
    } else {
        return TRUE;
    }
}

/* 8002451C-80024598       .text fopAcM_create__FsUlP4cXyziP5csXyzP4cXyzScPFPv_i */
s32 fopAcM_create(s16 procName, u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, s8 subtype, createFunc createFunc) {
    fopAcM_prm_class* params = createAppend(parameter, pPos, roomNo, pAngle, pScale, subtype, 0xFFFFFFFF);
    if (params == NULL)
        return -1;

    return fpcM_Create(procName, createFunc, params);
}

/* 80024598-80024614       .text fopAcM_create__FPcUlP4cXyziP5csXyzP4cXyzPFPv_i */
s32 fopAcM_create(char* pProcNameString, u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, createFunc createFunc) {
    dStage_objectNameInf * nameInf = dStage_searchName(pProcNameString);
    if (nameInf == NULL)
        return -1;

    return fopAcM_create(nameInf->mProcName, parameter, pPos, roomNo, pAngle, pScale, nameInf->mSubtype, createFunc);
}

/* 80024614-8002468C       .text fopAcM_fastCreate__FsUlP4cXyziP5csXyzP4cXyzScPFPv_iPv */
void* fopAcM_fastCreate(s16 procName, u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, s8 subtype, createFunc createFunc, void* pUserData) {
    fopAcM_prm_class* params = createAppend(parameter, pPos, roomNo, pAngle, pScale, subtype, 0xFFFFFFFF);
    if (params == NULL)
        return NULL;

    return fpcM_FastCreate(procName, createFunc, pUserData, params);
}

/* 8002468C-80024710       .text fopAcM_fastCreate__FPcUlP4cXyziP5csXyzP4cXyzPFPv_iPv */
void* fopAcM_fastCreate(char* pProcNameString, u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, createFunc createFunc, void *pUserData) {
    dStage_objectNameInf * nameInf = dStage_searchName(pProcNameString);
    if (nameInf == NULL)
        return NULL;

    return fopAcM_fastCreate(nameInf->mProcName, parameter, pPos, roomNo, pAngle, pScale, nameInf->mSubtype, createFunc, pUserData);
}

/* 80024710-80024790       .text fopAcM_createChild__FsUiUlP4cXyziP5csXyzP4cXyzScPFPv_i */
s32 fopAcM_createChild(s16 procName, unsigned int parentPcId, u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, s8 subtype, createFunc createFunc) {
    fopAcM_prm_class* params = createAppend(parameter, pPos, roomNo, pAngle, pScale, subtype, parentPcId);
    if (params == NULL)
        return -1;

    return fpcM_Create(procName, createFunc, params);
}

/* 80024790-80024814       .text fopAcM_createChild__FPcUiUlP4cXyziP5csXyzP4cXyzPFPv_i */
s32 fopAcM_createChild(char* pProcNameString, unsigned int parentPcId, u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, createFunc createFunc) {
    dStage_objectNameInf * nameInf = dStage_searchName(pProcNameString);
    if (nameInf == NULL)
        return -1;

    return fopAcM_createChild(nameInf->mProcName, parentPcId, parameter, pPos, roomNo, pAngle, pScale, nameInf->mSubtype, createFunc);
}

/* 80024814-800249D4       .text fopAcM_createChildFromOffset__FsUiUlP4cXyziP5csXyzP4cXyzScPFPv_i */
s32 fopAcM_createChildFromOffset(s16 procName, unsigned int parentPcId, u32 parameter, cXyz* pPosOffs, int roomNo, csXyz* pAngleOffs, cXyz* pScale, s8 subtype, createFunc createFunc) {
    fopAc_ac_c * pParent = fopAcM_SearchByID(parentPcId);
    s16 parentAngleY = pParent->current.angle.y;

    cXyz posOffs;
    if (pPosOffs == NULL)
        posOffs = cXyz::Zero;
    else
        posOffs = *pPosOffs;

    csXyz angleOffs;
    if (pAngleOffs == NULL)
        angleOffs = csXyz::Zero;
    else
        angleOffs = *pAngleOffs;

    cXyz pos = pParent->current.pos;

    csXyz angle(angleOffs);
    angle.y += parentAngleY;

    pos.x += posOffs.z * cM_ssin(parentAngleY) + posOffs.x * cM_scos(parentAngleY);
    pos.y += posOffs.y;
    pos.z += posOffs.z * cM_scos(parentAngleY) - posOffs.x * cM_ssin(parentAngleY);

    fopAcM_prm_class* params = createAppend(parameter, &pos, roomNo, &angle, pScale, subtype, parentPcId);
    if (params == NULL)
        return -1;

    return fpcM_Create(procName, createFunc, params);
}

/* 800249D4-80024B78       .text fopAcM_createChildFromOffset__FPcUiUlP4cXyziP5csXyzP4cXyzPFPv_i */
s32 fopAcM_createChildFromOffset(char* pProcNameString, unsigned int parentPcId, u32 parameter, cXyz* pPosOffs, int roomNo, csXyz* pAngleOffs, cXyz* pScale, createFunc createFunc) {
    fopAc_ac_c * pParent = fopAcM_SearchByID(parentPcId);
    s16 parentAngleY = pParent->current.angle.y;

    cXyz pos = pParent->current.pos;

    cXyz posOffs;
    if (pPosOffs == NULL)
        posOffs = cXyz::Zero;
    else
        posOffs = *pPosOffs;

    csXyz angleOffs;
    if (pAngleOffs == NULL)
        angleOffs = csXyz::Zero;
    else
        angleOffs = *pAngleOffs;

    csXyz angle(angleOffs);
    angle.y += parentAngleY;

    pos.x += posOffs.z * cM_ssin(parentAngleY) + posOffs.x * cM_scos(parentAngleY);
    pos.y += posOffs.y;
    pos.z += posOffs.z * cM_scos(parentAngleY) - posOffs.x * cM_ssin(parentAngleY);

    return fopAcM_createChild(pProcNameString, parentPcId, parameter, &pos, roomNo, &angle, pScale, createFunc);
}

/* 80024B78-80024CA0       .text fopAcM_createHeap__FP10fopAc_ac_cUlUl */
s32 fopAcM_createHeap(fopAc_ac_c* i_this, u32 size, u32 align) {
    JUT_ASSERT(0x33b, i_this);
    JUT_ASSERT(0x33c, i_this->heap == 0);
    fopAcM_Log(i_this, "アクターのヒープの生成");
    if (align == 0)
        align = 0x20;

    i_this->heap = mDoExt_createSolidHeapFromGameToCurrent(size, align);
    if (i_this->heap == 0) {
        OSReport_Error("fopAcM_createHeap 確保失敗\n");
        JUT_CONFIRM(0x34c, i_this->heap != 0);
        return FALSE;
    }

    return TRUE;
}

/* 80024CA0-80024CD4       .text fopAcM_adjustHeap__FP10fopAc_ac_c */
void fopAcM_adjustHeap(fopAc_ac_c* i_this) {
    mDoExt_restoreCurrentHeap();
    mDoExt_adjustSolidHeap(i_this->heap);
}

/* 80024CD4-80024D24       .text fopAcM_DeleteHeap__FP10fopAc_ac_c */
void fopAcM_DeleteHeap(fopAc_ac_c* i_this) {
    /* "Destroying Actor Heap" */
    fopAcM_Log(i_this, "アクターのヒープの破壊");

    if (i_this->heap != NULL) {
        mDoExt_destroySolidHeap(i_this->heap);
        i_this->heap = NULL;
    }
}

namespace fopAcM {
    bool HeapAdjustEntry;
    bool HeapAdjustVerbose;
    bool HeapAdjustQuiet;
}

/* 80024D24-800250E4       .text fopAcM_entrySolidHeap__FP10fopAc_ac_cPFP10fopAc_ac_c_iUl */
bool fopAcM_entrySolidHeap(fopAc_ac_c* i_this, heapCallbackFunc createHeapCB, u32 maxHeapSize) {
    const char * pProcNameString = fopAcM_getProcNameString(i_this);
    JKRSolidHeap * heap = NULL;

    if (maxHeapSize != 0) {
        heap = mDoExt_createSolidHeapFromGameToCurrent(maxHeapSize, 0x20);
        if (heap != NULL) {
            bool result = createHeapCB(i_this);
            if (heap->getFreeSize() >= 0x20)
                JKRHeap::alloc(0x20, 0, NULL);

            mDoExt_restoreCurrentHeap();

            if (!result) {
                if (!fopAcM::HeapAdjustQuiet)
                    OSReport_Error("見積もりヒープサイズ(%08x)で登録失敗しました。[%s]\n", maxHeapSize, pProcNameString);
                mDoExt_destroySolidHeap(heap);
                heap = NULL;
            } else {
                u32 allocSize = ALIGN_NEXT(heap->getSize() - heap->getFreeSize(), 0x20);
                if (maxHeapSize < allocSize + 0x40) {
                    mDoExt_adjustSolidHeap(heap);
                    i_this->heap = heap;
                    return true;
                }

                if (fopAcM::HeapAdjustVerbose)
                    OSReport_Warning("見積もりヒープサイズでは空きが多すぎます。 %08x %08x\n\x1b[m", allocSize, maxHeapSize);
            }
        } else {
            if (!fopAcM::HeapAdjustQuiet)
                OSReport_Warning("見積もりヒープが確保できませんでした。\n");
        }
    }

    if (heap == NULL) {
        heap = mDoExt_createSolidHeapFromGameToCurrent(-1, 0x20);
        JUT_ASSERT(0x453, heap);

        bool result = createHeapCB(i_this);
        mDoExt_restoreCurrentHeap();

        if (!result) {
            OSReport_Error("最大空きヒープサイズで登録失敗。[%s]\n", pProcNameString);
            mDoExt_destroySolidHeap(heap);
            return false;
        }

        if (!fopAcM::HeapAdjustQuiet)
            heap->getFreeSize();
    }

    if (heap != NULL) {
        if (!fopAcM::HeapAdjustEntry) {
            mDoExt_adjustSolidHeap(heap);
            i_this->heap = heap;
            return true;
        }

        JKRSolidHeap * heap1 = NULL;
        u32 allocSize = ALIGN_NEXT(heap->getSize() - heap->getFreeSize(), 0x10);
        if (allocSize + 0x90 < mDoExt_getGameHeap()->getFreeSize())
            heap1 = mDoExt_createSolidHeapFromGameToCurrent(allocSize, 0x20);

        if (heap1 != NULL) {
            if (heap1 < heap) {
                mDoExt_destroySolidHeap(heap);
                heap = NULL;
                bool result = createHeapCB(i_this);
                mDoExt_restoreCurrentHeap();
                JUT_ASSERT(0x48d, result != 0);
                if (result == 0) {
                    OSReport_Error("ぴったりサイズで、登録失敗？(バグ)\n");
                    mDoExt_destroySolidHeap(heap1);
                    heap1 = NULL;
                }
            } else {
                mDoExt_restoreCurrentHeap();
                mDoExt_destroySolidHeap(heap1);
                heap1 = NULL;
            }
        }

        if (heap1 != NULL) {
            mDoExt_adjustSolidHeap(heap1);
            i_this->heap = heap1;
            return true;
        }

        if (heap != NULL) {
            mDoExt_adjustSolidHeap(heap);
            i_this->heap = heap;
            return true;
        }

        OSReport_Error("ばぐばぐです\n");
        JUT_ASSERT(0x4b5, 0);
    }

    OSReport_Error("fopAcM_entrySolidHeap だめでした [%s]\n", pProcNameString);
    return false;
}

/* 800250E4-80025100       .text fopAcM_setCullSizeBox__FP10fopAc_ac_cffffff */
void fopAcM_setCullSizeBox(fopAc_ac_c* i_this, float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
    i_this->mCull.mBox.mMin.x = minX;
    i_this->mCull.mBox.mMin.y = minY;
    i_this->mCull.mBox.mMin.z = minZ;
    i_this->mCull.mBox.mMax.x = maxX;
    i_this->mCull.mBox.mMax.y = maxY;
    i_this->mCull.mBox.mMax.z = maxZ;
}

/* 80025100-80025114       .text fopAcM_setCullSizeSphere__FP10fopAc_ac_cffff */
void fopAcM_setCullSizeSphere(fopAc_ac_c* i_this, float x, float y, float z, float r) {
    i_this->mCull.mSphere.mCenter.x = x;
    i_this->mCull.mSphere.mCenter.y = y;
    i_this->mCull.mSphere.mCenter.z = z;
    i_this->mCull.mSphere.mRadius = r;
}

/* 80025114-80025144       .text fopAcM_addAngleY__FP10fopAc_ac_css */
bool fopAcM_addAngleY(fopAc_ac_c* i_this, short target, short step) {
    return cLib_chaseAngleS(&i_this->current.angle.y, target, step);
}

/* 80025144-800251A0       .text fopAcM_calcSpeed__FP10fopAc_ac_c */
void fopAcM_calcSpeed(fopAc_ac_c* i_this) {
    f32 speedF = fopAcM_GetSpeedF(i_this);
    f32 gravity = fopAcM_GetGravity(i_this);
    f32 xSpeed = speedF * cM_ssin(i_this->current.angle.y);
    f32 ySpeed = i_this->speed.y + gravity;
    f32 zSpeed = speedF * cM_scos(i_this->current.angle.y);

    if (ySpeed < fopAcM_GetMaxFallSpeed(i_this))
        ySpeed = fopAcM_GetMaxFallSpeed(i_this);

    fopAcM_SetSpeed(i_this, xSpeed, ySpeed, zSpeed);
}

/* 800251A0-8002520C       .text fopAcM_posMove__FP10fopAc_ac_cPC4cXyz */
void fopAcM_posMove(fopAc_ac_c* i_this, const cXyz* move) {
    i_this->current.pos.x += i_this->speed.x;
    i_this->current.pos.y += i_this->speed.y;
    i_this->current.pos.z += i_this->speed.z;

    if (move != NULL) {
        i_this->current.pos.x += move->x;
        i_this->current.pos.y += move->y;
        i_this->current.pos.z += move->z;
    }
}

/* 8002520C-80025250       .text fopAcM_posMoveF__FP10fopAc_ac_cPC4cXyz */
void fopAcM_posMoveF(fopAc_ac_c* i_this, const cXyz* move) {
    fopAcM_calcSpeed(i_this);
    fopAcM_posMove(i_this, move);
}

/* 80025250-80025278       .text fopAcM_searchActorAngleY__FP10fopAc_ac_cP10fopAc_ac_c */
s16 fopAcM_searchActorAngleY(fopAc_ac_c* i_this, fopAc_ac_c* i_other) {
    return cLib_targetAngleY(&i_this->current.pos, &i_other->current.pos);
}

/* 80025278-800252BC       .text fopAcM_seenActorAngleY__FP10fopAc_ac_cP10fopAc_ac_c */
s32 fopAcM_seenActorAngleY(fopAc_ac_c* i_this, fopAc_ac_c* i_other) {
    s16 angleY = cLib_targetAngleY(&i_this->current.pos, &i_other->current.pos);
    return abs((s16)(angleY - i_this->shape_angle.y));
}

/* 800252BC-80025370       .text fopAcM_searchActorDistance__FP10fopAc_ac_cP10fopAc_ac_c */
f32 fopAcM_searchActorDistance(fopAc_ac_c* i_this, fopAc_ac_c* i_other) {
    cXyz delta = i_other->current.pos - i_this->current.pos;
    return delta.abs();
}

/* 80025370-800253C0       .text fopAcM_searchActorDistance2__FP10fopAc_ac_cP10fopAc_ac_c */
f32 fopAcM_searchActorDistance2(fopAc_ac_c* i_this, fopAc_ac_c* i_other) {
    cXyz delta = i_other->current.pos - i_this->current.pos;
    return delta.abs2();
}

/* 800253C0-80025470       .text fopAcM_searchActorDistanceXZ__FP10fopAc_ac_cP10fopAc_ac_c */
f32 fopAcM_searchActorDistanceXZ(fopAc_ac_c* i_this, fopAc_ac_c* i_other) {
    /* Nonmatching */
    return (i_other->current.pos - i_this->current.pos).absXZ();
}

/* 80025470-800254BC       .text fopAcM_searchActorDistanceXZ2__FP10fopAc_ac_cP10fopAc_ac_c */
f32 fopAcM_searchActorDistanceXZ2(fopAc_ac_c* i_this, fopAc_ac_c* i_other) {
    /* Nonmatching */
    return (i_other->current.pos - i_this->current.pos).abs2XZ();
}

/* 800254BC-800255B4       .text fopAcM_rollPlayerCrash__FP10fopAc_ac_cfUl */
s32 fopAcM_rollPlayerCrash(fopAc_ac_c* i_this, f32 distAdjust, u32 flag) {
    f32 maxDist = distAdjust + 40.0f;
    f32 xzDist2 = fopAcM_searchPlayerDistanceXZ2(i_this);
    f32 yDist = fopAcM_searchPlayerDistanceY(i_this);
    if (xzDist2 < maxDist*maxDist && yDist > -100.0f && yDist < 200.0f) {
        daPy_py_c* player = (daPy_py_c*)dComIfGp_getPlayer(0);
        s16 angle = fopAcM_searchPlayerAngleY(i_this);
        if (cM_scos(player->current.angle.y - angle) < 0.9f) {
            if (fopAcM_GetName(player) == PROC_PLAYER) {
                player->onFrollCrashFlg(flag);
                return TRUE;
            }
        }
    }
    return FALSE;
}

/* 800255B4-80025660       .text fopAcM_checkCullingBox__FPA4_fffffff */
s32 fopAcM_checkCullingBox(Mtx pMtx, float x0, float y0, float z0, float x1, float y1, float z1) {
    Vec p0 = { x0, y0, z0 };
    Vec p1 = { x1, y1, z1 };
    Mtx viewMtx;
    MTXConcat(j3dSys.mViewMtx, pMtx, viewMtx);
    return mDoLib_clipper::clip(viewMtx, &p1, &p0) != 0;
}

static fopAc_cullSizeBox l_cullSizeBox[14]; // TODO
static fopAc_cullSizeSphere l_cullSizeSphere[8]; // TODO

/* 80025660-800259A8       .text fopAcM_cullingCheck__FP10fopAc_ac_c */
s32 fopAcM_cullingCheck(fopAc_ac_c* i_this) {
    MtxP pMtx;
    if (i_this->mCullMtx == NULL) {
        pMtx = j3dSys.getViewMtx();
    } else {
        Mtx mtx;
        cMtx_concat(j3dSys.getViewMtx(), i_this->mCullMtx, mtx);
        pMtx = mtx;
    }
    
    f32 cullFar = i_this->mCullSizeFar;
    if (dComIfGp_event_runCheck()) {
        cullFar *= dComIfGp_event_getCullRate();
    }
    
    int cullType = i_this->mCullType;
    bool isBox = false;
    if ((cullType >= 0 && cullType < fopAc_CULLBOX_CUSTOM_e) || cullType == fopAc_CULLBOX_CUSTOM_e) {
        isBox = true;
    }
    
    if (isBox) {
        if (cullType == fopAc_CULLBOX_CUSTOM_e) {
            if (i_this->mCullSizeFar > 0.0f) {
                mDoLib_clipper::mClipper.setFar(cullFar * mDoLib_clipper::mSystemFar);
                mDoLib_clipper::mClipper.calcViewFrustum();
                s32 ret = mDoLib_clipper::mClipper.clip(pMtx, &i_this->mCull.mBox.mMax, &i_this->mCull.mBox.mMin);
                mDoLib_clipper::mClipper.setFar(mDoLib_clipper::mSystemFar);
                mDoLib_clipper::mClipper.calcViewFrustum();
                return ret;
            } else {
                return mDoLib_clipper::mClipper.clip(pMtx, &i_this->mCull.mBox.mMax, &i_this->mCull.mBox.mMin);
            }
        } else {
            fopAc_cullSizeBox& cullBox = l_cullSizeBox[cullType];
            if (i_this->mCullSizeFar > 0.0f) {
                mDoLib_clipper::mClipper.setFar(cullFar * mDoLib_clipper::mSystemFar);
                mDoLib_clipper::mClipper.calcViewFrustum();
                s32 ret = mDoLib_clipper::mClipper.clip(pMtx, &cullBox.mMax, &cullBox.mMin);
                mDoLib_clipper::mClipper.setFar(mDoLib_clipper::mSystemFar);
                mDoLib_clipper::mClipper.calcViewFrustum();
                return ret;
            } else {
                return mDoLib_clipper::mClipper.clip(pMtx, &cullBox.mMax, &cullBox.mMin);
            }
        }
    } else { // Sphere
        if (cullType == fopAc_CULLSPHERE_CUSTOM_e) {
            if (i_this->mCullSizeFar > 0.0f) {
                mDoLib_clipper::mClipper.setFar(cullFar * mDoLib_clipper::mSystemFar);
                mDoLib_clipper::mClipper.calcViewFrustum();
                f32 radius = i_this->mCull.mSphere.mRadius;
                Vec center = i_this->mCull.mSphere.mCenter;
                Vec unusedCenter = center;
                s32 ret = mDoLib_clipper::mClipper.clip(pMtx, center, radius);
                mDoLib_clipper::mClipper.setFar(mDoLib_clipper::mSystemFar);
                mDoLib_clipper::mClipper.calcViewFrustum();
                return ret;
            } else {
                f32 radius = i_this->mCull.mSphere.mRadius;
                return mDoLib_clipper::mClipper.clip(pMtx, i_this->mCull.mSphere.mCenter, radius);
            }
        } else {
            fopAc_cullSizeSphere& cullSphere = l_cullSizeSphere[cullType - fopAc_CULLSPHERE_0_e];
            if (i_this->mCullSizeFar > 0.0f) {
                mDoLib_clipper::mClipper.setFar(cullFar * mDoLib_clipper::mSystemFar);
                mDoLib_clipper::mClipper.calcViewFrustum();
                f32 radius = cullSphere.mRadius;
                Vec center = cullSphere.mCenter;
                Vec unusedCenter = center;
                s32 ret = mDoLib_clipper::mClipper.clip(pMtx, center, radius);
                mDoLib_clipper::mClipper.setFar(mDoLib_clipper::mSystemFar);
                mDoLib_clipper::mClipper.calcViewFrustum();
                return ret;
            } else {
                f32 radius = cullSphere.mRadius;
                return mDoLib_clipper::mClipper.clip(pMtx, cullSphere.mCenter, radius);
            }
        }
    }
}

/* 800259A8-800259F8       .text fopAcM_orderTalkEvent__FP10fopAc_ac_cP10fopAc_ac_c */
s32 fopAcM_orderTalkEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) {
    return dComIfGp_event_order(dEvtType_TALK_e, 0x1FF, 0, 0x14F, i_this, i_partner, -1, 0xFF);
}

/* 800259F8-80025A48       .text fopAcM_orderTalkXBtnEvent__FP10fopAc_ac_cP10fopAc_ac_c */
s32 fopAcM_orderTalkXBtnEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) {
    return dComIfGp_event_order(dEvtType_SHOWITEM_X_e, 0x1F4, 0, 0x14F, i_this, i_partner, -1, 0xFF);
}

/* 80025A48-80025A98       .text fopAcM_orderTalkYBtnEvent__FP10fopAc_ac_cP10fopAc_ac_c */
s32 fopAcM_orderTalkYBtnEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) {
    return dComIfGp_event_order(dEvtType_SHOWITEM_Y_e, 0x1F4, 0, 0x14F, i_this, i_partner, -1, 0xFF);
}

/* 80025A98-80025AE8       .text fopAcM_orderTalkZBtnEvent__FP10fopAc_ac_cP10fopAc_ac_c */
s32 fopAcM_orderTalkZBtnEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) {
    return dComIfGp_event_order(dEvtType_SHOWITEM_Z_e, 0x1F4, 0, 0x14F, i_this, i_partner, -1, 0xFF);
}

/* 80025AE8-80025B3C       .text fopAcM_orderZHintEvent__FP10fopAc_ac_cP10fopAc_ac_c */
s32 fopAcM_orderZHintEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) {
    return dComIfGp_event_order(dEvtType_TALK_e, 0x1FF, 0, 0xFFFF, i_this, i_partner, -1, 0xFF);
}

/* 80025B3C-80025B8C       .text fopAcM_orderSpeakEvent__FP10fopAc_ac_c */
s32 fopAcM_orderSpeakEvent(fopAc_ac_c* i_this) {
    return dComIfGp_event_order(dEvtType_TALK_e, 0x1EA, 0, 0x14F, dComIfGp_getPlayer(0), i_this, -1, 0xFF);
}

/* 80025B8C-80025BE0       .text fopAcM_orderDoorEvent__FP10fopAc_ac_cP10fopAc_ac_c */
s32 fopAcM_orderDoorEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) {
    return dComIfGp_event_order(dEvtType_DOOR_e, 0xFF, 0, 0xFFFF, i_this, i_partner, -1, 0xFF);
}

/* 80025BE0-80025C34       .text fopAcM_orderCatchEvent__FP10fopAc_ac_cP10fopAc_ac_c */
s32 fopAcM_orderCatchEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) {
    return dComIfGp_event_order(dEvtType_CATCH_e, 1, 0, 0xFFFF, i_this, i_partner, -1, 0xFF);
}

/* 80025C34-80025CC8       .text fopAcM_orderOtherEvent2__FP10fopAc_ac_cPcUsUs */
s32 fopAcM_orderOtherEvent2(fopAc_ac_c* i_this, char* pEventName, u16 flag, u16 hind) {
    /* Nonmatching */
    u16 prio = dComIfGp_evmng_getEventPrio(dComIfGp_evmng_getEventIdx(pEventName, 0xFF));
    if (prio == 0)
        prio = 0xFF;

    return dComIfGp_event_orderOld(dEvtType_OTHER_e, prio, flag, hind, i_this, dComIfGp_getPlayer(0), pEventName);
}

/* 80025CC8-80025D28       .text fopAcM_orderChangeEvent__FP10fopAc_ac_cPcUsUs */
s32 fopAcM_orderChangeEvent(fopAc_ac_c* i_this, char* pEventName, u16 flag, u16 hind) {
    return fopAcM_orderChangeEventId(i_this, dComIfGp_evmng_getEventIdx(pEventName, 0xFF), flag, hind);
}

/* 80025D28-80025D94       .text fopAcM_orderChangeEvent__FP10fopAc_ac_cP10fopAc_ac_cPcUsUs */
s32 fopAcM_orderChangeEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner, char* pEventName, u16 flag, u16 hind) {
    return fopAcM_orderChangeEventId(i_this, i_partner, dComIfGp_evmng_getEventIdx(pEventName, 0xFF), flag, hind);
}

/* 80025D94-80025E1C       .text fopAcM_orderChangeEventId__FP10fopAc_ac_csUsUs */
s32 fopAcM_orderChangeEventId(fopAc_ac_c* i_this, s16 eventIdx, u16 flag, u16 hind) {
    /* Nonmatching */
    u16 prio = dComIfGp_evmng_getEventPrio(eventIdx);
    if (prio == 0)
        prio = 0xFF;

    return dComIfGp_event_order(dEvtType_CHANGE_e, prio, flag, hind, i_this, dComIfGp_getPlayer(0), eventIdx, 0xFF);
}

/* 80025E1C-80025EA4       .text fopAcM_orderChangeEventId__FP10fopAc_ac_cP10fopAc_ac_csUsUs */
s32 fopAcM_orderChangeEventId(fopAc_ac_c* i_this, fopAc_ac_c* i_partner, s16 eventIdx, u16 flag, u16 hind) {
    /* Nonmatching */
    u16 prio = dComIfGp_evmng_getEventPrio(eventIdx);
    if (prio == 0)
        prio = 0xFF;

    return dComIfGp_event_order(dEvtType_CHANGE_e, prio, flag, hind, i_this, i_partner, eventIdx, 0xFF);
}

/* 80025EA4-80025F3C       .text fopAcM_orderOtherEventId__FP10fopAc_ac_csUcUsUsUs */
s32 fopAcM_orderOtherEventId(fopAc_ac_c* i_this, s16 eventIdx, u8 infoIdx, u16 hind, u16 priority, u16 flag) {
    u16 prio;
    if (priority != 0) {
        prio = priority;
    } else {
        prio = dComIfGp_evmng_getEventPrio(eventIdx);
        if (prio == 0)
            prio = 0xFF;
    }

    return dComIfGp_event_order(dEvtType_OTHER_e, prio, flag, hind, i_this, dComIfGp_getPlayer(0), eventIdx, infoIdx);
}

/* 80025F3C-80025F9C       .text fopAcM_orderPotentialEvent__FP10fopAc_ac_cUsUsUs */
s32 fopAcM_orderPotentialEvent(fopAc_ac_c* i_this, u16 flag, u16 hind, u16 priority) {
    if (priority == 0)
        priority = 0xFF;

    return dComIfGp_event_order(dEvtType_POTENTIAL_e, priority, flag, hind, i_this, dComIfGp_getPlayer(0), -1, 0xFF);
}

/* 80025F9C-80025FF0       .text fopAcM_orderItemEvent__FP10fopAc_ac_c */
s32 fopAcM_orderItemEvent(fopAc_ac_c* i_this) {
    return dComIfGp_event_order(dEvtType_ITEM_e, 0xFF, 0, 0xFFFF, dComIfGp_getPlayer(0), i_this, -1, 0xFF);
}

/* 80025FF0-80026044       .text fopAcM_orderTreasureEvent__FP10fopAc_ac_cP10fopAc_ac_c */
s32 fopAcM_orderTreasureEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) {
    return dComIfGp_event_order(dEvtType_TREASURE_e, 0xFF, 0, 0xFFFF, i_this, i_partner, -1, 0xFF);
}

/* 80026044-80026074       .text fopAcM_getTalkEventPartner__FP10fopAc_ac_c */
fopAc_ac_c* fopAcM_getTalkEventPartner(fopAc_ac_c*) {
    return dComIfGp_event_getTalkPartner();
}

/* 80026074-800260A4       .text fopAcM_getItemEventPartner__FP10fopAc_ac_c */
fopAc_ac_c* fopAcM_getItemEventPartner(fopAc_ac_c*) {
    return dComIfGp_event_getItemPartner();
}

/* 800260A4-80026118       .text fopAcM_getEventPartner__FP10fopAc_ac_c */
fopAc_ac_c* fopAcM_getEventPartner(fopAc_ac_c* i_this) {
    if (dComIfGp_event_getPt1() != i_this)
        return dComIfGp_event_getPt1();

    return dComIfGp_event_getPt2();
}

/* 80026118-800261E8       .text fopAcM_createItemForPresentDemo__FP4cXyziUciiP5csXyzP4cXyz */
s32 fopAcM_createItemForPresentDemo(cXyz* pos, int i_itemNo, u8 param_3, int roomNo, int param_5, csXyz* rot, cXyz* scale) {
    JUT_ASSERT(2413, 0 <= i_itemNo && i_itemNo < 256);
    
    dComIfGp_event_setGtItm(i_itemNo);
    
    if (i_itemNo == NO_ITEM) {
        return -1;
    }
    
    return fopAcM_createDemoItem(pos, i_itemNo, roomNo, rot, param_5, scale, param_3);
}

/* 800261E8-800262B4       .text fopAcM_createItemForTrBoxDemo__FP4cXyziiiP5csXyzP4cXyz */
s32 fopAcM_createItemForTrBoxDemo(cXyz* pos, int i_itemNo, int roomNo, int param_5, csXyz* rot, cXyz* scale) {
    JUT_ASSERT(2458, 0 <= i_itemNo && i_itemNo < 256);
    
    dComIfGp_event_setGtItm(i_itemNo);
    
    if (i_itemNo == NO_ITEM) {
        return -1;
    }
    
    return fopAcM_createDemoItem(pos, i_itemNo, roomNo, rot, param_5, scale, 0);
}

/* 800262B4-80026694       .text fopAcM_createItemFromTable__FP4cXyziiiiP5csXyziP4cXyz */
void fopAcM_createItemFromTable(cXyz*, int, int, int, int, csXyz*, int, cXyz*) {
    /* Nonmatching */
}

/* 80026694-800267C8       .text fopAcM_createRaceItemFromTable__FP4cXyziiiP5csXyzP4cXyzi */
void fopAcM_createRaceItemFromTable(cXyz*, int, int, int, csXyz*, cXyz*, int) {
    /* Nonmatching */
}

/* 800267C8-8002688C       .text fopAcM_createShopItem__FP4cXyziP5csXyziP4cXyzPFPv_i */
s32 fopAcM_createShopItem(cXyz* pos, int i_itemNo, csXyz* rot, int roomNo, cXyz* scale,
                           createFunc createFunc) {
    JUT_ASSERT(2716, 0 <= i_itemNo && i_itemNo < 256);
    if (i_itemNo == NO_ITEM) {
        return -1;
    }
    
    return fopAcM_create(PROC_ShopItem, i_itemNo, pos, roomNo, rot, scale, 0xFF, createFunc);
}

/* 8002688C-80026980       .text fopAcM_createRaceItem__FP4cXyziiP5csXyziP4cXyzi */
s32 fopAcM_createRaceItem(cXyz* pos, int i_itemNo, int i_itemBitNo, csXyz* rot, int roomNo, cXyz* scale, int param_7) {
    /* Nonmatching */
    JUT_ASSERT(2763, 0 <= i_itemNo && i_itemNo < 256 && (-1 <= i_itemBitNo && i_itemBitNo <= 79) || i_itemBitNo == 127);
    if (i_itemNo == NO_ITEM) {
        return -1;
    }
    
    i_itemNo = (u8)check_itemno(i_itemNo);
    u32 params = (i_itemBitNo & 0x7F) << 0x08 | i_itemNo | (param_7 & 0xF) << 0xF;
    fopAcM_create(PROC_RACEITEM, params, pos, roomNo, rot, scale, 0xFF, NULL);
}

/* 80026980-80026A68       .text fopAcM_createDemoItem__FP4cXyziiP5csXyziP4cXyzUc */
s32 fopAcM_createDemoItem(cXyz* pos, int i_itemNo, int i_itemBitNo, csXyz* rot, int roomNo, cXyz* scale, u8 param_7) {
    JUT_ASSERT(2813, 0 <= i_itemNo && i_itemNo < 256 && (-1 <= i_itemBitNo && i_itemBitNo <= 79) || i_itemBitNo == 127);
    if (i_itemNo == NO_ITEM) {
        return -1;
    }
    
    u32 params = i_itemNo & 0xFF | (i_itemBitNo & 0x7F) << 0x08 | (param_7 & 0xFF) << 0x10;
    fopAcM_create(PROC_Demo_Item, params, pos, roomNo, rot, scale, 0xFF, NULL);
}

/* 80026A68-80026ADC       .text fopAcM_createItemForBoss__FP4cXyziiP5csXyzP4cXyzi */
s32 fopAcM_createItemForBoss(cXyz* pos, int, int roomNo, csXyz* rot, cXyz* scale, int param_6) {
    switch (param_6) {
    case 1:
        return fopAcM_createItem(pos, UTUWA_HEART, -1, roomNo, 3, rot, 0xC, scale);
    case 0:
    default:
        return fopAcM_createItem(pos, UTUWA_HEART, -1, roomNo, 3, rot, 5, scale);
    }
}

/* 80026ADC-80026C90       .text fopAcM_createItem__FP4cXyziiiiP5csXyziP4cXyz */
s32 fopAcM_createItem(cXyz* pos, int i_itemNo, int i_itemBitNo, int roomNo, int type, csXyz* rot,
                      int action, cXyz* scale) {
    /* Nonmatching */
}

/* 80026C90-80026E5C       .text fopAcM_fastCreateItem2__FP4cXyziiiiP5csXyziP4cXyz */
void* fopAcM_fastCreateItem2(cXyz* pos, int i_itemNo, int i_itemBitNo, int roomNo, int type,
                             csXyz* rot, int action, cXyz* scale) {
    /* Nonmatching (regswap) */
    JUT_ASSERT(2995, 0 <= i_itemNo && i_itemNo < 256 && (-1 <= i_itemBitNo && i_itemBitNo <= 79) || i_itemBitNo == 127);
    
    csXyz prmRot = csXyz::Zero;
    
    if (i_itemNo == NO_ITEM) {
        return NULL;
    }
    
    if (rot) {
        prmRot = *rot;
    }
    prmRot.z = 0xFF;
    
    u32 params = check_itemno(i_itemNo);
    params = (i_itemBitNo & 0xFF) << 0x08 | params & 0xFF | 0x00FF0000 | (type & 3) << 0x18 | action << 0x1A;
    
    daItem_c* item;
    switch (i_itemNo) {
    case RECOVER_FAIRY:
        return fopAcM_fastCreate(PROC_NPC_FA1, 1, pos, roomNo, rot, scale, 0xFF, NULL, NULL);
    case TRIPLE_HEART:
        // Make the two extra hearts first, then fall-through to make the third heart as normal.
        for (int i = 0; i < 2; i++) {
            fopAcM_fastCreate(PROC_ITEM, params, pos, roomNo, &prmRot, scale, 0xFF, NULL, NULL);
        }
        // Fall-through
    default:
        return fopAcM_fastCreate(PROC_ITEM, params, pos, roomNo, &prmRot, scale, 0xFF, NULL, NULL);
    }
}

/* 80026E5C-80026F5C       .text fopAcM_createItemForKP2__FP4cXyziiP5csXyzP4cXyzfffUs */
void fopAcM_createItemForKP2(cXyz*, int, int, csXyz*, cXyz*, float, float, float, u16) {
    /* Nonmatching */
}

/* 80026F5C-80026F98       .text fopAcM_createItemForSimpleDemo__FP4cXyziiP5csXyzP4cXyzff */
void* fopAcM_createItemForSimpleDemo(cXyz*, int, int, csXyz*, cXyz*, float, float) {
    /* Nonmatching */
}

/* 80026F98-80027254       .text fopAcM_fastCreateItem__FP4cXyziiP5csXyzP4cXyzfffiPFPv_i */
void* fopAcM_fastCreateItem(cXyz* pos, int i_itemNo, int roomNo, csXyz* rot, cXyz* scale,
                            f32 speedF, f32 speedY, f32 gravity, int i_itemBitNo, createFunc createFunc) {
    /* Nonmatching (regswaps) */
    JUT_ASSERT(3201, 0 <= i_itemNo && i_itemNo < 256);
    if (i_itemNo == NO_ITEM) {
        return NULL;
    }
    
    u32 params = (u8)check_itemno(i_itemNo) & 0xFF | (i_itemBitNo & 0xFF) << 0x08 | 0x28FF0000;
    
    if (isHeart(i_itemNo)) {
        speedF = 2.0f * speedF;
    }
    
    daItem_c* item;
    csXyz prmRot;
    switch (i_itemNo) {
    case RECOVER_FAIRY:
        item = (daItem_c*)fopAcM_fastCreate(PROC_NPC_FA1, 1, pos, roomNo, rot, scale, 0xFF, NULL, NULL);
        return item;
    case TRIPLE_HEART:
        // Make the two extra hearts first, then fall-through to make the third heart as normal.
        for (int i = 0; i < 2; i++) {
            if (rot) {
                prmRot = *rot;
            } else {
                prmRot = csXyz::Zero;
            }
            prmRot.z = 0xFF;
            prmRot.y += (int)cM_rndFX(0x2000);
            
            item = (daItem_c*)fopAcM_fastCreate(PROC_ITEM, params, pos, roomNo, &prmRot, scale, 0xFF, createFunc, NULL);
            if (item) {
                item->speedF = speedF * (1.0f + cM_rndFX(0.3f));
                item->speed.y = speedY * (1.0f + cM_rndFX(0.2f));
                item->mGravity = gravity;
            }
        }
        // Fall-through
    default:
        if (rot) {
            prmRot = *rot;
        } else {
            prmRot = csXyz::Zero;
        }
        prmRot.z = 0xFF;
        
        item = (daItem_c*)fopAcM_fastCreate(PROC_ITEM, params, pos, roomNo, &prmRot, scale, 0xFF, createFunc, NULL);
        if (item) {
            item->speedF = speedF;
            item->speed.y = speedY;
            item->mGravity = gravity;
        }
        return item;
    }
}

/* 80027254-80027280       .text stealItem_CB__FPv */
BOOL stealItem_CB(void* actor) {
    if (actor) {
        daItem_c* item = (daItem_c*)actor;
        item->mScale.setAll(1.0f);
        item->mStatusFlags |= 0x40;
    }
    return TRUE;
}

/* 80027280-800273D4       .text fopAcM_createStealItem__FP4cXyziiP5csXyzi */
void fopAcM_createStealItem(cXyz*, int, int, csXyz*, int) {
    /* Nonmatching */
}

/* 800273D4-8002777C       .text fopAcM_createItemFromEnemyTable__FUsiiP4cXyzP5csXyz */
void fopAcM_createItemFromEnemyTable(u16, int, int, cXyz*, csXyz*) {
    /* Nonmatching */
}

/* 8002777C-800278D8       .text fopAcM_createIball__FP4cXyziiP5csXyzi */
s32 fopAcM_createIball(cXyz*, int, int, csXyz*, int) {
    /* Nonmatching */
}

/* 800278D8-80027920       .text fopAcM_createWarpFlower__FP4cXyzP5csXyziUc */
void fopAcM_createWarpFlower(cXyz*, csXyz*, int, unsigned char) {
    /* Nonmatching */
}

/* 80027920-80027970       .text enemySearchJugge__FPvPv */
fopAc_ac_c * enemySearchJugge(void* ptr, void*) {
    if (ptr != NULL && fopAc_IsActor(ptr)) {
        fopAc_ac_c * i_ac = (fopAc_ac_c *)ptr;
        if (i_ac->mGroup == fopAc_ENEMY_e)
            return i_ac;
    }
    return NULL;
}

/* 80027970-80027A9C       .text fopAcM_myRoomSearchEnemy__FSc */
fopAc_ac_c* fopAcM_myRoomSearchEnemy(s8 roomNo) {
    JUT_ASSERT(0xe07, roomNo >= 0);

    scene_class* roomProc = fopScnM_SearchByID(dStage_roomControl_c::getStatusProcID(roomNo));
    JUT_ASSERT(0xe0a, roomProc != 0);

    u32 grabProcID = daPy_getPlayerActorClass()->getGrabActorID();
    fopAc_ac_c* enemy = fopAcM_SearchByID(grabProcID);
    if (enemy != NULL && fopAcM_GetGroup(enemy) == fopAc_ENEMY_e)
        return enemy;

    return (fopAc_ac_c*) fpcM_JudgeInLayer(fpcM_LayerID(roomProc), (fpcCtIt_JudgeFunc)enemySearchJugge, NULL);
}

/* 80027A9C-80027B24       .text fopAcM_createDisappear__FP10fopAc_ac_cP4cXyzUcUcUc */
s32 fopAcM_createDisappear(fopAc_ac_c*, cXyz*, unsigned char, unsigned char, unsigned char) {
    /* Nonmatching */
}

/* 80027B24-80027E28       .text fopAcM_getGroundAngle__FP10fopAc_ac_cP5csXyz */
void fopAcM_getGroundAngle(fopAc_ac_c*, csXyz*) {
    /* Nonmatching */
}

/* 80027E28-80027E5C       .text fopAcM_setCarryNow__FP10fopAc_ac_ci */
void fopAcM_setCarryNow(fopAc_ac_c* i_this, int stageLayer) {
    fopAcM_OnStatus(i_this, fopAcStts_CARRY_e);
    if (stageLayer) {
        fopAcM_setStageLayer(i_this);
    }
}

/* 80027E5C-80027ED8       .text fopAcM_cancelCarryNow__FP10fopAc_ac_c */
void fopAcM_cancelCarryNow(fopAc_ac_c* i_this) {
    if (fopAcM_checkStatus(i_this, fopAcStts_CARRY_e)) {
        fopAcM_OffStatus(i_this, fopAcStts_CARRY_e);
        fopAcM_setRoomLayer(i_this, fopAcM_GetRoomNo(i_this));
        i_this->shape_angle.z = 0;
        
        if (dComIfGp_event_runCheck() && i_this->mGroup != fopAc_ENEMY_e) {
            fopAcM_OnStatus(i_this, fopAcStts_UNK800_e);
        }
    }
}

/* 80027ED8-800281D8       .text fopAcM_viewCutoffCheck__FP10fopAc_ac_cf */
void fopAcM_viewCutoffCheck(fopAc_ac_c*, float) {
    /* Nonmatching */
}

/* 800281D8-800282F8       .text fopAcM_otoCheck__FP10fopAc_ac_cf */
s32 fopAcM_otoCheck(fopAc_ac_c*, float) {
    /* Nonmatching */
}

/* 800282F8-8002833C       .text fopAcM_getProcNameString__FP10fopAc_ac_c */
const char * fopAcM_getProcNameString(fopAc_ac_c* i_this) {
    /* Nonmatching */
    const char * pProcNameString = dStage_getName2(fpcM_GetProfName(i_this), i_this->mSubtype);
    if (pProcNameString != NULL)
        return pProcNameString;
    return "UNKOWN";
}

struct findObjectCBParam {
    const char * mpProcName;
    u32 mParamMask;
    u32 mParameter;
};

/* 8002833C-80028410       .text fopAcM_findObjectCB__FP10fopAc_ac_cPv */
fopAc_ac_c* fopAcM_findObjectCB(fopAc_ac_c* it, void* i_prm) {
    findObjectCBParam* Prm = (findObjectCBParam*)i_prm;
    JUT_ASSERT(4095, Prm);

    dStage_objectNameInf *inf = dStage_searchName(Prm->mpProcName);
    if (inf == NULL)
        return NULL;

    if (inf->mProcName == fopAcM_GetProfName(it) && inf->mSubtype == it->mSubtype && (Prm->mParamMask == 0 || Prm->mParameter == (fopAcM_GetParam(it) & Prm->mParamMask)))
        return it;

    return NULL;
}

/* 80028410-80028448       .text fopAcM_searchFromName__FPcUlUl */
fopAc_ac_c* fopAcM_searchFromName(char* pProcName, u32 paramMask, u32 parameter) {
    findObjectCBParam param;
    param.mpProcName = pProcName;
    param.mParamMask = paramMask;
    param.mParameter = parameter;
    return (fopAc_ac_c*)fopAcIt_Judge((fopAcIt_JudgeFunc)fopAcM_findObjectCB, &param);
}

/* 80028448-80028560       .text fopAcM_getWaterY__FPC4cXyzPf */
s32 fopAcM_getWaterY(const cXyz* pPos, float* pDstWaterY) {
    /* Nonmatching */
    static dBgS_WtrChk water_check;
    s32 ret = 0;

    *pDstWaterY = -1e09;

    cXyz pos = *pPos;
    pos.y -= 500.0f;
    water_check.Set(pos, pos.y + 1000.0f);

    bool hit = dComIfG_Bgsp()->SplGrpChk(&water_check);
    if (hit) {
        *pDstWaterY = water_check.GetHeight();
        ret = 1;
    }

    if (daSea_ChkArea(pos.x, pos.z)) {
        f32 waveY = daSea_calcWave(pos.x, pos.z);
        if (waveY > *pDstWaterY)
            *pDstWaterY = waveY;
        ret = 1;
    }

    return ret;
}

/* 80028684-80028724       .text fopAcM_setGbaName__FP10fopAc_ac_cUcUcUc */
void fopAcM_setGbaName(fopAc_ac_c* i_this, u8 itemNo, u8 gbaName0, u8 gbaName1) {
    if (dComIfGs_checkGetItem(itemNo) || (itemNo == BOW && (dComIfGs_checkGetItem(MAGIC_ARROW) || dComIfGs_checkGetItem(LIGHT_ARROW))) || (itemNo == MAGIC_ARROW && dComIfGs_checkGetItem(LIGHT_ARROW)))
        i_this->mGbaName = gbaName1;
    else
        i_this->mGbaName = gbaName0;
}

/* 80028724-800287D8       .text fpoAcM_absolutePos__FP10fopAc_ac_cP4cXyzP4cXyz */
void fpoAcM_absolutePos(fopAc_ac_c* i_this, cXyz* relPos, cXyz* absPos) {
    *absPos = i_this->current.pos;
    absPos->x += relPos->z * cM_ssin(i_this->shape_angle.y) + relPos->x * cM_scos(i_this->shape_angle.y);
    absPos->y += relPos->y;
    absPos->z += relPos->z * cM_scos(i_this->shape_angle.y) - relPos->x * cM_ssin(i_this->shape_angle.y);
}

/* 800287D8-8002889C       .text fpoAcM_relativePos__FP10fopAc_ac_cP4cXyzP4cXyz */
void fpoAcM_relativePos(fopAc_ac_c* i_this, cXyz* absPos, cXyz* relPos) {
    s16 angle = -i_this->shape_angle.y;
    cXyz offset = *absPos - i_this->current.pos;
    relPos->x = offset.z * cM_ssin(angle) + offset.x * cM_scos(angle);
    relPos->y = offset.y;
    relPos->z = offset.z * cM_scos(angle) - offset.x * cM_ssin(angle);
}

#ifndef __INTELLISENSE__
/* 80029178-80029198       .text __ct__20fopAc_cullSizeSphereF4cXyzf */
fopAc_cullSizeSphere::fopAc_cullSizeSphere(cXyz p, float r) {
    mCenter = p;
    mRadius = r;
}

/* 80029198-800291CC       .text __ct__17fopAc_cullSizeBoxFRC17fopAc_cullSizeBox */
fopAc_cullSizeBox::fopAc_cullSizeBox(const fopAc_cullSizeBox& box) {
    mMin = box.mMin;
    mMax = box.mMax;
}

/* 800291CC-80029200       .text __ct__17fopAc_cullSizeBoxF4cXyz4cXyz */
fopAc_cullSizeBox::fopAc_cullSizeBox(cXyz min, cXyz max) {
    mMin = min;
    mMax = max;
}
#endif
