1#include "Util/ItemGenerator.h"
2
3#include <math/seadVectorCalcCommon.h>
4
5#include "Library/Item/ItemUtil.h"
6#include "Library/LiveActor/ActorInitInfo.h"
7#include "Library/LiveActor/ActorInitUtil.h"
8#include "Library/LiveActor/ActorPoseUtil.h"
9#include "Library/LiveActor/LiveActor.h"
10#include "Library/Math/MathUtil.h"
11
12#include "Enemy/KuriboMini.h"
13#include "Util/ItemUtil.h"
14
15ItemGenerator::ItemGenerator() {}
16
17ItemGenerator::ItemGenerator(al::LiveActor* creator, const al::ActorInitInfo& info)
18 : mCreator(creator) {
19 initLinkShine(creator, info, isAppearAbove: false);
20}
21
22void ItemGenerator::initLinkShine(al::LiveActor* creator, const al::ActorInitInfo& info,
23 bool isAppearAbove) {
24 mCreator = creator;
25 mItemType = rs::getItemType(info);
26
27 if (isShine()) {
28 mLinkShine = rs::tryInitLinkShine(info, name: "ShineActor", linkIndex: 0);
29 } else if (rs::isItemTypeKuriboMini(out: &mKuriboMiniCount, type: mItemType)) {
30 mKuriboMiniArray = new KuriboMini*[mKuriboMiniCount];
31 for (s32 i = 0; i < mKuriboMiniCount; i++) {
32 mKuriboMiniArray[i] = new KuriboMini("マメクリボー[アイテム]");
33 al::initCreateActorNoPlacementInfo(actor: mKuriboMiniArray[i], initInfo: info);
34 mKuriboMiniArray[i]->makeActorDead();
35 }
36 } else {
37 rs::tryInitItemByPlacementInfo(actor: mCreator, info, isAppearAbove);
38 }
39}
40
41void ItemGenerator::initNoLinkShine(al::LiveActor* creator, const al::ActorInitInfo& info,
42 bool isAppearAbove) {
43 mCreator = creator;
44 mItemType = rs::getItemType(info);
45
46 if (isShine()) {
47 mLinkShine = rs::initShineByPlacementInfo(info);
48 } else if (rs::isItemTypeKuriboMini(out: &mKuriboMiniCount, type: mItemType)) {
49 mKuriboMiniArray = new KuriboMini*[mKuriboMiniCount];
50 for (s32 i = 0; i < mKuriboMiniCount; i++) {
51 mKuriboMiniArray[i] = new KuriboMini("マメクリボー[アイテム]");
52 al::initCreateActorNoPlacementInfo(actor: mKuriboMiniArray[i], initInfo: info);
53 mKuriboMiniArray[i]->makeActorDead();
54 }
55 } else {
56 rs::tryInitItemByPlacementInfo(actor: mCreator, info, isAppearAbove);
57 }
58}
59
60void ItemGenerator::initHintPhotoShine(al::LiveActor* creator, const al::ActorInitInfo& info) {
61 mCreator = creator;
62 mItemType = rs::ItemType::Shine;
63 mLinkShine = rs::tryInitLinkShineHintPhoto(info, name: "ShineActor", linkIndex: 0);
64}
65
66void ItemGenerator::createShineEffectInsideObject(const al::ActorInitInfo& info) {
67 rs::createShineEffectInsideObject(shine: mLinkShine, actor: mCreator, info);
68}
69
70bool ItemGenerator::tryUpdateHintTransIfExistShine() {
71 const sead::Vector3f& trans = al::getTrans(actor: mCreator);
72 return tryUpdateHintTransIfExistShine(trans);
73}
74
75bool ItemGenerator::tryUpdateHintTransIfExistShine(const sead::Vector3f& trans) {
76 if (!mLinkShine || mGeneratedItemCount > 0)
77 return false;
78
79 rs::updateHintTrans(shine: mLinkShine, trans);
80 return true;
81}
82
83void generateKuribos(KuriboMini** kuriboMiniArray, s32 kuriboMiniCount, al::LiveActor* creator,
84 const sead::Vector3f& front) {
85 sead::Vector3f up = sead::Vector3f(0.0f, 1.0f, 0.0f);
86 al::verticalizeVec(out: &up, vertical: front, vec: up);
87
88 if (!al::tryNormalizeOrZero(out: &up))
89 al::calcDirVerticalAny(&up, front);
90
91 for (s32 i = 0; i < kuriboMiniCount; i++) {
92 sead::Vector3f frontDir = front;
93 al::rotateVectorDegree(&frontDir, frontDir, up,
94 al::normalize(x: i, min: 0, max: kuriboMiniCount) * 360.0f);
95 al::normalize(vec: &frontDir);
96
97 sead::Quatf quat = sead::Quatf::unit;
98 al::makeQuatFrontUp(outQuat: &quat, front: frontDir, up);
99 al::updatePoseQuat(actor: kuriboMiniArray[i], quat);
100
101 sead::Vector3f pos = sead::Vector3f(0.0f, 0.0f, 150.0f);
102 pos.rotate(q: quat);
103
104 al::setTrans(actor: kuriboMiniArray[i], trans: al::getTrans(actor: creator) - pos);
105 kuriboMiniArray[i]->appearPopBack();
106 }
107}
108
109bool ItemGenerator::isEnableGenerateByCount(s32 count) const {
110 return mGeneratedItemCount < count;
111}
112
113void ItemGenerator::generate(const sead::Vector3f& pos, const sead::Quatf& quat) {
114 if (isNone())
115 return;
116
117 KuriboMini** kuriboMiniArray = mKuriboMiniArray;
118 if (mLinkShine)
119 rs::appearPopupShine(shine: mLinkShine, trans: pos);
120 else if (kuriboMiniArray) {
121 al::LiveActor* creator = mCreator;
122 s32 kuriboMiniCount = mKuriboMiniCount;
123 sead::Vector3f vec = sead::Vector3f(0.0f, 0.0f, 0.0f);
124 al::calcQuatFront(out: &vec, quat);
125 generateKuribos(kuriboMiniArray, kuriboMiniCount, creator, front: vec);
126 } else
127 al::appearItem(actor: mCreator, pos, quat, sensor: nullptr);
128
129 mGeneratedItemCount++;
130}
131
132void ItemGenerator::generate(const sead::Vector3f& pos, const sead::Vector3f& vec) {
133 if (isNone())
134 return;
135
136 KuriboMini** kuriboMiniArray = mKuriboMiniArray;
137
138 if (mLinkShine)
139 rs::appearPopupShine(shine: mLinkShine, trans: pos);
140 else if (kuriboMiniArray)
141 generateKuribos(kuriboMiniArray: mKuriboMiniArray, kuriboMiniCount: mKuriboMiniCount, creator: mCreator, front: vec);
142 else
143 al::appearItem(actor: mCreator, pos, vec, sensor: nullptr);
144
145 mGeneratedItemCount++;
146}
147
148bool ItemGenerator::tryGenerate(const sead::Vector3f& pos, const sead::Quatf& quat, s32 count) {
149 if (isNone() || !isEnableGenerateByCount(count))
150 return false;
151
152 generate(pos, quat);
153 return true;
154}
155
156bool ItemGenerator::tryGenerate(const sead::Vector3f& pos, const sead::Vector3f& vec, s32 count) {
157 if (isNone() || !isEnableGenerateByCount(count))
158 return false;
159
160 generate(pos, vec);
161 return true;
162}
163
164bool ItemGenerator::isNone() const {
165 return mItemType == rs::ItemType::None;
166}
167
168bool ItemGenerator::isShine() const {
169 return mItemType == rs::ItemType::Shine;
170}
171
172bool ItemGenerator::isLifeUp() const {
173 return mItemType == rs::ItemType::LifeUpItem || mItemType == rs::ItemType::LifeMaxUpItem;
174}
175
176bool ItemGenerator::isLifeMaxUp() const {
177 return mItemType == rs::ItemType::LifeMaxUpItem;
178}
179
180bool ItemGenerator::isCoin() const {
181 return mItemType == rs::ItemType::Coin;
182}
183
184bool ItemGenerator::isCoinBlow() const {
185 return mItemType == rs::ItemType::CoinBlow;
186}
187
188bool ItemGenerator::isCoinStackBound() const {
189 return mItemType == rs::ItemType::CoinStackBound;
190}
191
192bool ItemGenerator::isKuriboMini3() const {
193 return mItemType == rs::ItemType::KuriboMini3;
194}
195
196bool ItemGenerator::isKuriboMini8() const {
197 return mItemType == rs::ItemType::KuriboMini8;
198}
199