1#include "ObjectDirector.hh"
3#include "game/field/BoxColManager.hh"
4#include "game/field/ObjectDrivableDirector.hh"
5#include "game/field/obj/ObjectRegistry.hh"
7#include "game/kart/KartObject.hh"
9#include "game/system/CourseMap.hh"
10#include "game/system/RaceConfig.hh"
15void ObjectDirector::init() {
21 ObjectDrivableDirector::Instance()->init();
25void ObjectDirector::calc() {
34 ObjectDrivableDirector::Instance()->calc();
38void ObjectDirector::addObject(ObjectCollidable *obj) {
39 u32 loadFlags = obj->loadFlags();
45 const auto *set = m_flowTable.set(m_flowTable.slot(obj->id()));
49 if (set && set->mode != 0) {
50 if (obj->collision()) {
58void ObjectDirector::addObjectNoImpl(ObjectNoImpl *obj) {
63void ObjectDirector::addManagedObject(ObjectCollidable *obj) {
64 m_managedObjects.push_back(obj);
69 ObjectCollisionConvexHull *convexHull) {
72 while (ObjectCollidable *obj = BoxColManager::Instance()->getNextObject()) {
73 auto *objCollision = obj->collision();
78 obj->calcCollisionTransform();
79 if (!obj->checkCollision(convexHull, m_hitDepths[count])) {
85 Kart::Reaction reactionOnKart = m_hitTableKart.reaction(m_hitTableKart.slot(obj->id()));
86 Kart::Reaction reactionOnObj =
87 m_hitTableKartObject.reaction(m_hitTableKartObject.slot(obj->id()));
90 obj->processKartReactions(kartObj, reactionOnKart, reactionOnObj);
92 Kart::Reaction reaction =
93 obj->onCollision(kartObj, reactionOnKart, reactionOnObj, m_hitDepths[count]);
94 m_reactions[count] = reaction;
96 if (reaction == Kart::Reaction::WallAllSpeed || reaction == Kart::Reaction::WallSpark) {
97 obj->onWallCollision(kartObj, m_hitDepths[count]);
99 obj->onObjectCollision(kartObj);
103 if (m_hitDepths[count].y < 0.0f) {
104 m_hitDepths[count].y = 0.0f;
114ObjectDirector *ObjectDirector::CreateInstance() {
116 s_instance =
new ObjectDirector;
118 ObjectDrivableDirector::CreateInstance();
120 s_instance->createObjects();
126void ObjectDirector::DestroyInstance() {
128 auto *instance = s_instance;
129 s_instance =
nullptr;
132 ObjectDrivableDirector::DestroyInstance();
136ObjectDirector::ObjectDirector()
137 : m_flowTable(
"ObjFlow.bin"), m_hitTableKart(
"GeoHitTableKart.bin"),
138 m_hitTableKartObject(
"GeoHitTableKartObj.bin") {}
141ObjectDirector::~ObjectDirector() {
143 s_instance =
nullptr;
144 WARN(
"ObjectDirector instance not explicitly handled!");
147 for (
auto *&obj : m_objects) {
153void ObjectDirector::createObjects() {
154 const auto *courseMap = System::CourseMap::Instance();
155 size_t objectCount = courseMap->getGeoObjCount();
159 size_t maxCount = std::min(objectCount, MAX_UNIT_COUNT);
160 m_objects.reserve(maxCount);
161 m_calcObjects.reserve(maxCount);
162 m_collisionObjects.reserve(maxCount);
164 auto *objDrivableDir = ObjectDrivableDirector::Instance();
165 const auto &raceScenario = System::RaceConfig::Instance()->raceScenario();
166 bool rGV2 = raceScenario.course == Course::SNES_Ghost_Valley_2;
168 for (
size_t i = 0; i < objectCount; ++i) {
169 const auto *pObj = courseMap->getGeoObj(i);
173 if (!(pObj->presenceFlag() & 1)) {
178 if (IsObjectBlacklisted(pObj->id())) {
184 switch (
static_cast<ObjectId
>(pObj->id())) {
185 case ObjectId::ObakeBlockSFCc:
186 case ObjectId::ObakeBlock2SFCc:
187 case ObjectId::ObakeBlock3SFCc: {
189 auto *obakeManager = objDrivableDir->obakeManager();
191 objDrivableDir->createObakeManager(*pObj);
193 obakeManager->addBlock(*pObj);
201 ObjectBase *
object = createObject(*pObj);
205 if (raceScenario.course == Course::Moonview_Highway) {
206 auto *highwayMgr =
new ObjectHighwayManager;
213 ObjectId
id =
static_cast<ObjectId
>(params.id());
215 case ObjectId::Woodbox:
216 return new ObjectWoodbox(params);
217 case ObjectId::WLWallGC:
218 return new ObjectWLWallGC(params);
219 case ObjectId::KartTruck:
220 case ObjectId::CarBody:
221 return new ObjectCarTGE(params);
222 case ObjectId::W_Woodbox:
223 return new ObjectWoodboxW(params);
224 case ObjectId::ItemboxLine:
225 return new ObjectItemboxLine(params);
226 case ObjectId::Boble:
227 return new ObjectBoble(params);
228 case ObjectId::Seagull:
229 return new ObjectBird(params);
230 case ObjectId::DokanSFC:
231 return new ObjectDokan(params);
232 case ObjectId::OilSFC:
233 return new ObjectOilSFC(params);
234 case ObjectId::ParasolR:
235 return new ObjectParasolR(params);
236 case ObjectId::Kuribo:
237 return new ObjectKuribo(params);
238 case ObjectId::Choropu:
239 case ObjectId::Choropu2:
240 return new ObjectChoropu(params);
242 return new ObjectCowHerd(params);
243 case ObjectId::WLFirebarGC:
244 return new ObjectFirebar(params);
245 case ObjectId::Sanbo:
246 return new ObjectSanbo(params);
247 case ObjectId::Press:
248 return new ObjectPress(params);
249 case ObjectId::WLFireRingGC:
250 return new ObjectFireRing(params);
251 case ObjectId::PuchiPakkun:
253 case ObjectId::KinokoUd:
254 return new ObjectKinokoUd(params);
255 case ObjectId::KinokoBend:
256 return new ObjectKinokoBend(params);
257 case ObjectId::BulldozerL:
258 case ObjectId::BulldozerR:
259 return new ObjectBulldozer(params);
260 case ObjectId::KinokoNm:
261 return new ObjectKinokoNm(params);
262 case ObjectId::Crane:
263 return new ObjectCrane(params);
264 case ObjectId::TownBridge:
265 return new ObjectTownBridge(params);
266 case ObjectId::Turibashi:
267 return new ObjectTuribashi(params);
268 case ObjectId::Aurora:
269 return new ObjectAurora(params);
270 case ObjectId::Sandcone:
271 return new ObjectSandcone(params);
273 return new ObjectAmi(params);
274 case ObjectId::BeltEasy:
275 return new ObjectBeltEasy(params);
276 case ObjectId::BeltCrossing:
277 return new ObjectBeltCrossing(params);
278 case ObjectId::BeltCurveA:
279 return new ObjectBeltCurveA(params);
283 case ObjectId::DummyPole:
284 case ObjectId::CastleTree1c:
285 case ObjectId::PeachTreeGCc:
286 case ObjectId::MarioGo64c:
287 case ObjectId::KinokoT1:
288 case ObjectId::PalmTree:
289 case ObjectId::Parasol:
290 case ObjectId::HeyhoTreeGBAc:
291 case ObjectId::GardenTreeDSc:
292 case ObjectId::DKtreeA64c:
293 case ObjectId::DKTreeB64c:
294 case ObjectId::TownTreeDsc:
295 case ObjectId::PakkunDokan:
296 return new ObjectCollidable(params);
297 case ObjectId::WLDokanGC:
298 case ObjectId::Mdush:
299 return new ObjectKCL(params);
301 return new ObjectNoImpl(params);
305ObjectDirector *ObjectDirector::s_instance =
nullptr;
std::vector< ObjectBase * > m_objects
All objects live here.
std::vector< ObjectBase * > m_collisionObjects
Objects having collision live here too.
std::array< ObjectCollidable *, MAX_UNIT_COUNT > m_collidingObjects
Objects we are currently colliding with.
std::vector< ObjectBase * > m_calcObjects
Objects needing calc() live here too.
The highest level abstraction for a kart.
ObjectDokan ObjectPuchiPakkun
This is just to help with readability. The rMR piranhas are really just pipes.