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(ObjectBase *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;
114f32 ObjectDirector::distAboveRisingWater(f32 offset)
const {
116 return offset - m_psea->pos().y;
120f32 ObjectDirector::risingWaterKillPlaneHeight()
const {
122 return m_psea->pos().y - 260.0f;
126ObjectDirector *ObjectDirector::CreateInstance() {
128 s_instance =
new ObjectDirector;
130 ObjectDrivableDirector::CreateInstance();
132 s_instance->createObjects();
138void ObjectDirector::DestroyInstance() {
140 auto *instance = s_instance;
141 s_instance =
nullptr;
144 ObjectDrivableDirector::DestroyInstance();
148ObjectDirector::ObjectDirector()
149 : m_flowTable(
"ObjFlow.bin"), m_hitTableKart(
"GeoHitTableKart.bin"),
150 m_hitTableKartObject(
"GeoHitTableKartObj.bin"), m_psea(nullptr) {}
153ObjectDirector::~ObjectDirector() {
155 s_instance =
nullptr;
156 WARN(
"ObjectDirector instance not explicitly handled!");
159 for (
auto *&obj : m_objects) {
165void ObjectDirector::createObjects() {
166 const auto *courseMap = System::CourseMap::Instance();
167 size_t objectCount = courseMap->getGeoObjCount();
171 size_t maxCount = std::min(objectCount, MAX_UNIT_COUNT);
172 m_objects.reserve(maxCount);
173 m_calcObjects.reserve(maxCount);
174 m_collisionObjects.reserve(maxCount);
176 auto *objDrivableDir = ObjectDrivableDirector::Instance();
177 auto course = System::RaceConfig::Instance()->raceScenario().course;
178 bool rGV2 = course == Course::SNES_Ghost_Valley_2;
183 s_wanwanMaxPitch = course == Course::GCN_Mario_Circuit ? -20.0f : -30.0f;
185 for (
size_t i = 0; i < objectCount; ++i) {
186 const auto *pObj = courseMap->getGeoObj(i);
190 if (!(pObj->presenceFlag() & 1)) {
195 if (IsObjectBlacklisted(pObj->id())) {
201 switch (
static_cast<ObjectId
>(pObj->id())) {
202 case ObjectId::ObakeBlockSFCc:
203 case ObjectId::ObakeBlock2SFCc:
204 case ObjectId::ObakeBlock3SFCc: {
206 auto *obakeManager = objDrivableDir->obakeManager();
208 objDrivableDir->createObakeManager(*pObj);
210 obakeManager->addBlock(*pObj);
218 ObjectBase *
object = createObject(*pObj);
221 if (object->id() == ObjectId::SunDS) {
226 if (course == Course::Moonview_Highway) {
227 auto *highwayMgr =
new ObjectHighwayManager;
232 auto *sunMgr =
new ObjectSunManager;
236 if (course == Course::GBA_Shy_Guy_Beach) {
237 auto *shipMgr =
new ObjectHeyhoShipManager;
244 ObjectId
id =
static_cast<ObjectId
>(params.id());
247 return new ObjectPsea(params);
248 case ObjectId::Woodbox:
249 return new ObjectWoodbox(params);
250 case ObjectId::WLWallGC:
251 return new ObjectWLWallGC(params);
252 case ObjectId::CarA1:
253 case ObjectId::CarA2:
254 case ObjectId::CarA3:
255 return new ObjectCarA(params);
256 case ObjectId::Basabasa:
257 return new ObjectBasabasa(params);
258 case ObjectId::HeyhoShipGBA:
259 return new ObjectHeyhoShip(params);
260 case ObjectId::KartTruck:
261 case ObjectId::CarBody:
262 return new ObjectCarTGE(params);
263 case ObjectId::KoopaBall:
264 return new ObjectKoopaBall(params);
265 case ObjectId::W_Woodbox:
266 return new ObjectWoodboxW(params);
267 case ObjectId::SunDS:
268 return new ObjectSunDS(params);
269 case ObjectId::ItemboxLine:
270 return new ObjectItemboxLine(params);
271 case ObjectId::VolcanoBall:
272 return new ObjectVolcanoBallLauncher(params);
273 case ObjectId::PenguinS:
274 return new ObjectPenguinS(params);
275 case ObjectId::PenguinM:
276 return new ObjectPenguin(params);
277 case ObjectId::Dossunc:
278 return new ObjectDossunc(params);
279 case ObjectId::Boble:
280 return new ObjectBoble(params);
281 case ObjectId::Hanachan:
282 return new ObjectHanachan(params);
283 case ObjectId::Seagull:
284 return new ObjectBird(params);
286 return new ObjectCrab(params);
287 case ObjectId::Hwanwan:
288 return new ObjectHwanwanManager(params);
289 case ObjectId::HeyhoBallGBA:
290 return new ObjectHeyhoBall(params);
291 case ObjectId::DokanSFC:
292 return new ObjectDokan(params);
293 case ObjectId::Pylon:
294 return new ObjectPylon(params);
295 case ObjectId::OilSFC:
296 return new ObjectOilSFC(params);
297 case ObjectId::ParasolR:
298 return new ObjectParasolR(params);
299 case ObjectId::KoopaFigure64:
300 return new ObjectKoopaFigure64(params);
301 case ObjectId::Kuribo:
302 return new ObjectKuribo(params);
303 case ObjectId::Choropu:
304 case ObjectId::Choropu2:
305 return new ObjectChoropu(params);
307 return new ObjectCowHerd(params);
308 case ObjectId::PakkunF:
309 return new ObjectPakkunF(params);
310 case ObjectId::WLFirebarGC:
311 case ObjectId::KoopaFirebar:
312 return new ObjectFirebar(params);
313 case ObjectId::Wanwan:
314 return new ObjectWanwan(params);
315 case ObjectId::Poihana:
316 return new ObjectPoihana(params);
317 case ObjectId::Propeller:
318 return new ObjectPropeller(params);
319 case ObjectId::DKRockGC:
320 return new ObjectRock(params);
321 case ObjectId::Sanbo:
322 return new ObjectSanbo(params);
323 case ObjectId::TruckWagon:
324 return new ObjectTruckWagon(params);
325 case ObjectId::Heyho:
326 return new ObjectHeyho(params);
327 case ObjectId::Press:
328 return new ObjectPress(params);
329 case ObjectId::WLFireRingGC:
330 return new ObjectFireRing(params);
331 case ObjectId::FireSnake:
332 return new ObjectFireSnake(params);
333 case ObjectId::FireSnakeV:
334 return new ObjectFireSnakeV(params);
335 case ObjectId::PuchiPakkun:
337 case ObjectId::KinokoUd:
338 return new ObjectKinokoUd(params);
339 case ObjectId::KinokoBend:
340 return new ObjectKinokoBend(params);
341 case ObjectId::VolcanoRock:
342 return new ObjectVolcanoRock(params);
343 case ObjectId::BulldozerL:
344 case ObjectId::BulldozerR:
345 return new ObjectBulldozer(params);
346 case ObjectId::KinokoNm:
347 return new ObjectKinokoNm(params);
348 case ObjectId::Crane:
349 return new ObjectCrane(params);
350 case ObjectId::VolcanoPiece:
351 return new ObjectVolcanoPiece(params);
352 case ObjectId::FlamePole:
353 return new ObjectFlamePoleFoot(params);
354 case ObjectId::TwistedWay:
355 return new ObjectTwistedWay(params);
356 case ObjectId::TownBridge:
357 return new ObjectTownBridge(params);
358 case ObjectId::DKShip64:
359 return new ObjectShip64(params);
360 case ObjectId::Turibashi:
361 return new ObjectTuribashi(params);
362 case ObjectId::Aurora:
363 return new ObjectAurora(params);
364 case ObjectId::DCPillar:
365 return new ObjectPillar(params);
366 case ObjectId::Sandcone:
367 return new ObjectSandcone(params);
368 case ObjectId::FlamePoleV:
369 case ObjectId::FlamePoleVBig:
370 return new ObjectFlamePoleV(params);
372 return new ObjectAmi(params);
373 case ObjectId::BeltEasy:
374 return new ObjectBeltEasy(params);
375 case ObjectId::BeltCrossing:
376 return new ObjectBeltCrossing(params);
377 case ObjectId::BeltCurveA:
378 return new ObjectBeltCurveA(params);
379 case ObjectId::Escalator:
380 return new ObjectEscalator(params);
381 case ObjectId::EscalatorGroup:
382 return new ObjectEscalatorGroup(params);
386 case ObjectId::DummyPole:
387 case ObjectId::CastleTree1c:
388 case ObjectId::MarioTreeGCc:
389 case ObjectId::PeachTreeGCc:
390 case ObjectId::MarioGo64c:
391 case ObjectId::KinokoT1:
392 case ObjectId::PalmTree:
393 case ObjectId::Parasol:
394 case ObjectId::HeyhoTreeGBAc:
395 case ObjectId::GardenTreeDSc:
396 case ObjectId::DKtreeA64c:
397 case ObjectId::DKTreeB64c:
398 case ObjectId::TownTreeDsc:
399 case ObjectId::PakkunDokan:
400 return new ObjectCollidable(params);
401 case ObjectId::WLDokanGC:
402 case ObjectId::Mdush:
403 return new ObjectKCL(params);
405 return new ObjectNoImpl(params);
409f32 ObjectDirector::s_wanwanMaxPitch;
411ObjectDirector *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.