summaryrefslogtreecommitdiff
path: root/src/REL/d/a/d_a_t_wood_area.cpp
blob: 9a92f9db2fa807aec820c667e16718597e191406 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "d/a/d_a_t_wood_area.h"

#include "common.h"
#include "d/a/d_a_player.h"
#include "toBeSorted/d_emitter.h"

const f32 dAcTWoodArea_c::scaleX = 100.0f;
const f32 dAcTWoodArea_c::scaleY = 100.0f;

SPECIAL_ACTOR_PROFILE(WOODAREA_TAG, dAcTWoodArea_c, fProfile::WOODAREA_TAG, 0x166, 0, 2);

STATE_DEFINE(dAcTWoodArea_c, Init);
STATE_DEFINE(dAcTWoodArea_c, Wait);

int dAcTWoodArea_c::actorCreate() {
    mStateMgr.changeState(StateID_Init);
    MTXTrans(mWorldMtx.m, mPosition.x, mPosition.y, mPosition.z);
    mBoundingBox.mMin = mVec3_c(-0.0f, -0.0f, -0.0f);
    mBoundingBox.mMax = mVec3_c(0.0f, 0.0f, 0.0f);
    return SUCCEEDED;
}

static const ProfileName FILTER_PROFILE[] = {
    fProfile::OBJ_FRUIT, fProfile::ITEM, fProfile::NPC_KYUI_THIRD, fProfile::OBJ_IVY_ROPE, fProfile::NPC_SORAJIMA_BOY,
};

int dAcTWoodArea_c::actorPostCreate() {
    for (u32 i = 0; i < 5; i++) {
        attachCloseObjects(FILTER_PROFILE[i]);
    }
    return SUCCEEDED;
}

int dAcTWoodArea_c::doDelete() {
    return SUCCEEDED;
}

int dAcTWoodArea_c::actorExecute() {
    mStateMgr.executeState();
    return SUCCEEDED;
}

int dAcTWoodArea_c::draw() {
    return SUCCEEDED;
}

void dAcTWoodArea_c::initializeState_Init() {}
void dAcTWoodArea_c::executeState_Init() {
    mStateMgr.changeState(StateID_Wait);
}
void dAcTWoodArea_c::finalizeState_Init() {}

extern const u16 PARTICLE_RESOURCE_ID_MAPPING_8_;

void dAcTWoodArea_c::initializeState_Wait() {}

void dAcTWoodArea_c::executeState_Wait() {
    if (dAcPy_c::LINK != nullptr && dAcPy_c::LINK->checkFlags0x350(0x2000)) {
        // This is a bit messed up
        mVec3_c dist = mPosition - dAcPy_c::LINK->mPosition;
        f32 attachRadius = getAttachRadius();
        attachRadius = attachRadius * attachRadius;
        if (dist.x * dist.x + dist.z * dist.z < attachRadius) {
            bool someEffectThing = mSubtype != 1 ? (mParams & 0xF) != 0 ? false : true : true;
            if (someEffectThing) {
                mVec3_c tmp(mPosition.x, mPosition.y + getAttachHeight(), mPosition.z);
                dJEffManager_c::spawnEffect(
                    PARTICLE_RESOURCE_ID_MAPPING_8_, tmp, nullptr, nullptr, nullptr, nullptr, 0, 0
                );
            }
            dropItems();
        }
    }
}
void dAcTWoodArea_c::finalizeState_Wait() {}

void dAcTWoodArea_c::attachCloseObjects(ProfileName profID) {
    fBase_c *base = nullptr;
    f32 attachRadius = getAttachRadius() * getAttachRadius();
    while (true) {
        base = fManager_c::searchBaseByProfName(profID, base);
        if (base == nullptr) {
            break;
        }

        dAcObjBase_c *obj = static_cast<dAcObjBase_c *>(base);
        if (obj->canBeLinkedToWoodTag()) {
            if (!(obj->getSquareDistanceTo(mPosition) > attachRadius)) {
                if (!attachObject(obj)) {
                    return;
                }
            }
        }
    }
}

void dAcTWoodArea_c::dropItems() {
    for (int i = 0; i < 8; i++) {
        if (mRefs[i].get() != nullptr) {
            if (mRefs[i].get()->drop()) {
                mRefs[i].unlink();
            }
        }
    }
}

bool dAcTWoodArea_c::attachObject(dAcObjBase_c *obj) {
    for (int i = 0; i < 8; i++) {
        if (mRefs[i].get() == nullptr) {
            mRefs[i].link(obj);
            return true;
        }
    }
    return false;
}