Merge branch 'modding' into modding+

This commit is contained in:
MegaMech 2024-12-04 11:20:07 -07:00 committed by GitHub
commit c774537ad3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 556 additions and 14 deletions

View File

@ -703,6 +703,7 @@ void render_object_for_player(s32 cameraId) {
CourseManager_RenderCourseObjects(cameraId);
CourseManager_TrainSmokeDraw(cameraId);
CourseManager_DrawThwomps(cameraId);
CourseManager_DrawPenguins(cameraId);
// switch (gCurrentCourseId) {
// case COURSE_MARIO_RACEWAY:
@ -1580,6 +1581,7 @@ void update_object(void) {
CourseManager_UpdateCourseObjects();
CourseManager_TrainSmokeTick();
CourseManager_TickPenguins();
// switch (gCurrentCourseId) {
// case COURSE_MARIO_RACEWAY:

View File

@ -17,7 +17,7 @@ f32 D_8018D00C;
s16 D_8018D010;
UNUSED s32 D_8018D014;
s16 D_8018D018;
f32 xOrientation;
f32 xOrientation; // For mirror/extra mode
s16 D_8018D020;
f32 D_8018D028[8];
s16 D_8018D048;

View File

@ -47,6 +47,7 @@ static size_t tankerTrucks;
static size_t cars;
static size_t boats;
static size_t thwomps;
static size_t penguins;
/**
* Note that you can only remove the tender if there are no carriages
@ -104,6 +105,13 @@ void World::AddThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16
gNumActiveThwomps = thwomps;
}
std::shared_ptr<OPenguin> World::AddPenguin(Vec3f pos, u16 direction, OPenguin::PenguinType type, OPenguin::Behaviour behaviour) {
auto penguin = std::make_shared<OPenguin>(penguins, pos, direction, type, behaviour);
Penguins.push_back(penguin);
penguins++;
return penguin;
}
u32 World::GetCupIndex() {
return this->CupIndex;
}

View File

@ -10,6 +10,7 @@
#include "vehicles/Train.h"
#include "TrainCrossing.h"
#include "vehicles/OThwomp.h"
#include "vehicles/OPenguin.h"
#include <memory>
#include "Actor.h"
@ -146,6 +147,9 @@ public:
std::vector<std::unique_ptr<OThwomp>> Thwomps;
void AddThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize = 7);
std::vector<std::shared_ptr<OPenguin>> Penguins;
std::shared_ptr<OPenguin> AddPenguin(Vec3f pos, u16 direction, OPenguin::PenguinType type, OPenguin::Behaviour behaviour);
TrainCrossing* AddCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius);
std::vector<std::shared_ptr<TrainCrossing>> Crossings;

View File

@ -151,23 +151,81 @@ void SherbetLand::MinimapSettings() {
}
void SherbetLand::InitCourseObjects() {
for (size_t i = 0; i < NUM_PENGUINS; i++) {
init_object(indexObjectList1[i], 0);
//! @bug Skip spawning penguins due to animation crash for now
if (gGamestate == CREDITS_SEQUENCE) {
return;
}
// Originally, multiplayer did not spawn the big penguin
// if (gPlayerCountSelection1 == 1) {
Vec3f pos = {-383.0f, 2.0f, -690.0f};
gWorldInstance.AddPenguin(pos, 0, OPenguin::PenguinType::EMPEROR, OPenguin::Behaviour::STRUT);
// }
Vec3f pos2 = {-2960.0f, -80.0f, 1521.0f};
auto penguin = gWorldInstance.AddPenguin(pos2, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE);
auto penguin2 = gWorldInstance.AddPenguin(pos2, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE);
penguin->Diameter = penguin2->Diameter = 100.0f;
Vec3f pos3 = {-2490.0f, -80.0f, 1612.0f};
auto penguin3 = gWorldInstance.AddPenguin(pos3, 0x100, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE);
auto penguin4 = gWorldInstance.AddPenguin(pos3, 0x100, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE);
penguin3->Diameter = penguin4->Diameter = 80.0f;
Vec3f pos4 = {-2098.0f, -80.0f, 1624.0f};
auto penguin5 = gWorldInstance.AddPenguin(pos4, 0xFF00, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE);
auto penguin6 = gWorldInstance.AddPenguin(pos4, 0xFF00, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE);
penguin5->Diameter = penguin6->Diameter = 80.0f;
Vec3f pos5 = {-2080.0f, -80.0f, 1171.0f};
auto penguin7 = gWorldInstance.AddPenguin(pos5, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE);
auto penguin8 = gWorldInstance.AddPenguin(pos5, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE);
penguin7->Diameter = penguin8->Diameter = 80.0f;
if (gGamestate == CREDITS_SEQUENCE) {
Vec3f pos6 = {380.0, 0.0f, -535.0f};
auto penguin9 = gWorldInstance.AddPenguin(pos6, 0x9000, OPenguin::PenguinType::CREDITS, OPenguin::Behaviour::SLIDE3);
penguin9->MirrorModeAngleOffset = -0x4000;
} else {
Vec3f pos6 = {146.0f, 0.0f, -380.0f};
auto penguin9 = gWorldInstance.AddPenguin(pos6, 0x9000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE3);
penguin9->MirrorModeAngleOffset = -0x4000;
}
Vec3f pos7 = {380.0f, 0.0f, -766.0f};
auto penguin10 = gWorldInstance.AddPenguin(pos7, 0x5000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE4);
penguin10->MirrorModeAngleOffset = 0x8000;
Vec3f pos8 = {-2300.0f, 0.0f, -210.0f};
auto penguin11 = gWorldInstance.AddPenguin(pos8, 0xC000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6);
penguin11->MirrorModeAngleOffset = 0x8000;
Vec3f pos9 = {-2500.0f, 0.0f, -250.0f};
auto penguin12 = gWorldInstance.AddPenguin(pos9, 0x4000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6);
penguin12->MirrorModeAngleOffset = 0x8000;
Vec3f pos10 = {-535.0f, 0.0f, 875.0f};
auto penguin13 = gWorldInstance.AddPenguin(pos10, 0x8000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6);
penguin13->MirrorModeAngleOffset = -0x4000;
Vec3f pos11 = {-250.0f, 0.0f, 953.0f};
auto penguin14 = gWorldInstance.AddPenguin(pos11, 0x9000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6);
penguin14->MirrorModeAngleOffset = -0x4000;
}
void SherbetLand::UpdateCourseObjects() {
if (gGamestate != CREDITS_SEQUENCE) {
func_800842C8();
}
update_penguins();
}
void SherbetLand::RenderCourseObjects(s32 cameraId) {
if (gGamestate != CREDITS_SEQUENCE) {
func_80052E30(cameraId);
}
render_object_train_penguins(cameraId);
}
void SherbetLand::SomeSounds() {

View File

@ -142,6 +142,12 @@ void YoshiValley::MinimapSettings() {
void YoshiValley::InitCourseObjects() {
size_t objectId;
size_t i;
//! @bug Skip spawning due to animation crash for now
if (gGamestate == CREDITS_SEQUENCE) {
return;
}
for (i = 0; i < NUM_YV_FLAG_POLES; i++) {
init_object(indexObjectList1[i], 0);
}

View File

@ -0,0 +1,383 @@
#include <libultraship.h>
#include <libultra/gbi.h>
#include "engine/vehicles/OPenguin.h"
#include <vector>
#include "port/Game.h"
extern "C" {
#include "macros.h"
#include "main.h"
#include "actors.h"
#include "math_util.h"
#include "sounds.h"
#include "update_objects.h"
#include "render_player.h"
#include "external.h"
#include "bomb_kart.h"
#include "collision.h"
#include "code_80086E70.h"
#include "render_objects.h"
#include "code_80057C60.h"
#include "defines.h"
#include "code_80005FD0.h"
#include "math_util_2.h"
#include "collision.h"
#include "assets/bowsers_castle_data.h"
#include "ceremony_and_credits.h"
#include "objects.h"
#include "update_objects.h"
#include "render_objects.h"
#include "course_offsets.h"
#include "data/some_data.h"
extern s8 gPlayerCount;
}
OPenguin::OPenguin(s32 i, Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour) {
if (i >= 32) {
printf("MAX penguin REACHED (32), skipping\n");
return;
}
_idx = i;
_type = type;
_bhv = behaviour;
s32 objectIndex = indexObjectList1[i];
init_object(objectIndex, 0);
Object *object = &gObjectList[objectIndex];
object->origin_pos[0] = pos[0] * xOrientation;
object->origin_pos[1] = pos[1];
object->origin_pos[2] = pos[2];
object->unk_0C6 = direction;
switch(type) {
case PenguinType::CHICK:
object->surfaceHeight = 5.0f;
object->sizeScaling = 0.04f;
object->boundingBoxSize = 4;
break;
case PenguinType::ADULT:
object->surfaceHeight = -80.0f;
object->sizeScaling = 0.08f;
object->boundingBoxSize = 4;
break;
case PenguinType::CREDITS:
object->surfaceHeight = -80.0f;
object->sizeScaling = 0.08f;
object->sizeScaling = 0.15f;
break;
case PenguinType::EMPEROR:
object->sizeScaling = 0.2f;
object->boundingBoxSize = 0x000C;
break;
}
}
void OPenguin::Tick(void) {
s32 objectIndex;
objectIndex = indexObjectList1[_idx];
if (gObjectList[objectIndex].state != 0) {
if (_type == PenguinType::EMPEROR) {
OPenguin::EmperorPenguin(objectIndex);
} else {
OPenguin::OtherPenguin(objectIndex);
}
OPenguin::Behaviours(objectIndex, _idx);
}
if (func_80072320(objectIndex, 1) != 0) {
func_80089820(objectIndex, 1.75f, 1.5f, 0x1900A046U);
} else if (func_80072320(objectIndex, 8) != 0) {
func_80089820(objectIndex, 1.3f, 1.0f, 0x1900A046U);
} else {
func_80089820(objectIndex, 1.5f, 1.25f, 0x1900A046U);
}
if ((is_obj_flag_status_active(objectIndex, 0x02000000) != 0) &&
(func_80072354(objectIndex, 0x00000020) != 0)) {
func_800722A4(objectIndex, 0x00000060);
set_object_flag_status_false(objectIndex, 0x02000000);
}
}
void OPenguin::Draw(s32 cameraId) {
s32 objectIndex;
s32 temp_s1;
s32 drawDistance;
u16 var_s1;
u32 var_s3;
if (gPlayerCountSelection1 == 1) {
var_s3 = 0x0003D090;
} else if (gPlayerCountSelection1 == 2) {
var_s3 = 0x00027100;
} else {
var_s3 = 0x00015F90;
}
objectIndex = indexObjectList1[_idx];
if (gObjectList[objectIndex].state >= 2) {
if (gPlayerCountSelection1 == 1) {
var_s1 = 0x4000;
if (_idx == 0) {
drawDistance = 0x000005DC;
} else if (func_80072320(objectIndex, 8) != 0) {
drawDistance = 0x00000320;
} else {
drawDistance = 0x000003E8;
}
} else {
if (func_80072320(objectIndex, 8) != 0) {
drawDistance = 0x000001F4;
var_s1 = 0x4000;
} else {
drawDistance = 0x00000258;
var_s1 = 0x5555;
}
}
temp_s1 = func_8008A364(objectIndex, cameraId, var_s1, drawDistance);
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
func_800557B4(objectIndex, (u32) temp_s1, var_s3);
}
}
}
void OPenguin::Behaviours(s32 objectIndex, s32 arg1) {
Object* object;
object = &gObjectList[objectIndex];
switch (_bhv) {
case 1: // emperor
func_80085080(objectIndex);
break;
case 2:
func_8008502C(objectIndex, arg1);
break;
case 3:
func_80084D2C(objectIndex, 0);
break;
case 4:
func_80084D2C(objectIndex, 1);
break;
case 5:
func_80084D2C(objectIndex, 2);
break;
case 6:
func_80084D2C(objectIndex, 3);
break;
}
if (func_80072320(objectIndex, 0x00000020) != 0) {
if (func_80072320(objectIndex, 0x00000040) != 0) {
func_800722CC(objectIndex, 0x00000040);
object->unk_084[6] = 0;
object->unk_084[7] = 0x0096;
}
if (object->unk_084[7] == 0) {
func_800722CC(objectIndex, 0x00000020);
} else {
object->unk_084[7]--;
object->orientation[0] = object->direction_angle[0];
object->orientation[1] += 0x2000;
object->orientation[2] = object->direction_angle[2];
}
} else {
object->orientation[0] = object->direction_angle[0];
object->orientation[1] = object->direction_angle[1];
object->orientation[2] = object->direction_angle[2];
}
}
void OPenguin::EmperorPenguin(s32 objectIndex) {
switch (gObjectList[objectIndex].state) {
case 0:
break;
case 1:
OPenguin::InitEmperorPenguin(objectIndex);
break;
case 2:
func_80072E54(objectIndex, 0, gObjectList[objectIndex].type, 1, 0, -1);
break;
}
}
void OPenguin::InitEmperorPenguin(s32 objectIndex) {
Object* object;
object = &gObjectList[objectIndex];
object->unk_0D8 = 0;
object->model = (Gfx*) d_course_sherbet_land_unk_data1;
object->vertex = (Vtx*) d_course_sherbet_land_unk_data11;
//object->sizeScaling = 0.2f;
//object->boundingBoxSize = 0x000C;
object->unk_09C = 1;
set_obj_direction_angle(objectIndex, 0U, 0U, 0U);
object->unk_0DD = 1;
func_80086EF0(objectIndex);
object->spline = D_800E672C[0];
set_object_flag_status_true(objectIndex, 0x04000800);
object->type = get_animation_length(d_course_sherbet_land_unk_data11, 0);
object_next_state(objectIndex);
}
void OPenguin::OtherPenguin(s32 objectIndex) {
Object* object;
object = &gObjectList[objectIndex];
switch (object->state) {
case 0:
break;
case 1:
OPenguin::InitOtherPenguin(objectIndex);
break;
case 2:
func_80072E54(objectIndex, 0, (s32) object->type, (s32) object->unk_09C, 0, -1);
if (func_80072354(objectIndex, 0x00000020) != 0) {
if (object->unk_084[6] == 0) {
object->unk_084[6] = random_int(0x005AU) + 0x5A;
func_800722A4(objectIndex, 0x00000080);
} else {
object->unk_084[6]--;
}
}
break;
case 3:
func_80072E54(objectIndex, 0, object->type, 1, 0, 0);
break;
case 4:
func_800722CC(objectIndex, 2);
object_next_state(objectIndex);
break;
}
if (func_80072320(objectIndex, 0x00000020) != 0) {
if (object->unk_084[6] == 0) {
func_800722A4(objectIndex, 0x00000080);
object->unk_084[6] = 0x0010;
} else {
object->unk_084[6]--;
}
}
if (func_80072320(objectIndex, 0x00000080) != 0) {
func_800722CC(objectIndex, 0x00000080);
if (func_80072320(objectIndex, 0x00000010) != 0) {
func_800C98B8(object->pos, object->velocity, SOUND_ARG_LOAD(0x19, 0x00, 0x70, 0x49));
} else {
func_800C98B8(object->pos, object->velocity, SOUND_ARG_LOAD(0x19, 0x00, 0x70, 0x17));
}
}
}
void OPenguin::InitOtherPenguin(s32 objectIndex) {
Object* object;
object = &gObjectList[objectIndex];
object->unk_0D8 = 0;
object->model = (Gfx*) d_course_sherbet_land_unk_data1;
object->vertex = (Vtx*) d_course_sherbet_land_unk_data11;
//object->boundingBoxSize = 4;
object->unk_09C = 2;
object->unk_04C = random_int(0x012CU);
set_object_flag_status_true(objectIndex, 0x04000220);
switch(_bhv) {
case Behaviour::CIRCLE:
object->unk_01C[1] = Diameter;
object->unk_0C4 = (_idx << 0xF) & 0xFFFF;
//object->unk_0DD = 2;
func_800722A4(objectIndex, 8);
break;
case Behaviour::SLIDE3:
case Behaviour::SLIDE4:
case Behaviour::SLIDE6:
case Behaviour::STRUT:
if (gIsMirrorMode) {
object->unk_0C6 = MirrorModeAngleOffset;
}
set_obj_direction_angle(objectIndex, 0U, object->unk_0C6 + 0x8000, 0U);
func_800722A4(objectIndex, 20);
break;
}
if ((_idx > 0) && (_idx < 9)) {
if ((_idx == 1) || (_idx == 2)) {
//object->unk_0C6 = 0x0150;
//object->unk_01C[1] = 100.0f;
} else if ((_idx == 3) || (_idx == 4)) {
//object->unk_0C6 = 0x0100;
//object->unk_01C[1] = 80.0f;
} else if ((_idx == 5) || (_idx == 6)) {
//object->unk_0C6 = 0xFF00;
//object->unk_01C[1] = 80.0f;
} else if ((_idx == 7) || (_idx == 8)) {
//object->unk_0C6 = 0x0150;
//object->unk_01C[1] = 80.0f;
}
//object->unk_0C4 = (_idx << 0xF) & 0xFFFF;
//object->surfaceHeight = -80.0f;
//object->sizeScaling = 0.08f;
//object->unk_0DD = 2;
//func_800722A4(objectIndex, 8);
} else if ((_idx > 8) && (_idx < 15)) {
switch (_idx) {
case 9:
if (gGamestate != CREDITS_SEQUENCE) {
} else {
//object->sizeScaling = 0.15f;
}
//object->unk_0C6 = 0x9000;
if (gIsMirrorMode != 0) {
//object->unk_0C6 -= 0x4000;
}
//object->unk_0DD = 3;
break;
case 10:
//object->unk_0C6 = 0x5000;
if (gIsMirrorMode != 0) {
//object->unk_0C6 += 0x8000;
}
//object->unk_0DD = 4;
break;
case 11:
//object->unk_0C6 = 0xC000;
//object->unk_0DD = 6;
if (gIsMirrorMode != 0) {
//object->unk_0C6 += 0x8000;
}
break;
case 12:
//object->unk_0C6 = 0x4000;
//object->unk_0DD = 6;
if (gIsMirrorMode != 0) {
//object->unk_0C6 += 0x8000;
}
break;
case 13:
// object->unk_0C6 = 0x8000;
//object->unk_0DD = 6;
if (gIsMirrorMode != 0) {
//object->unk_0C6 -= 0x4000;
}
break;
case 14:
//object->unk_0C6 = 0x9000;
//object->unk_0DD = 6;
if (gIsMirrorMode != 0) {
//object->unk_0C6 -= 0x4000;
}
break;
default:
break;
}
//set_obj_direction_angle(objectIndex, 0U, object->unk_0C6 + 0x8000, 0U);
//object->surfaceHeight = 5.0f;
//object->sizeScaling = 0.04f;
//func_800722A4(objectIndex, 0x00000014);
}
func_80086EF0(objectIndex);
object->unk_034 = 0.0f;
object->type = get_animation_length(d_course_sherbet_land_unk_data11, 0);
object_next_state(objectIndex);
}

View File

@ -0,0 +1,68 @@
#pragma once
#include <libultraship.h>
#include <vector>
#include "engine/vehicles/OPenguin.h"
extern "C" {
#include "macros.h"
#include "main.h"
#include "vehicles.h"
#include "waypoints.h"
#include "common_structs.h"
#include "objects.h"
}
//! @todo Make shadow size bigger if thwomp is scaled up
//! @todo make adjustable properties for squishSize and boundingBoxSize
/**
* Thwomp GameObject
*
* The game automatically places the actor on the ground so you do not need to provide a Y coordinate value.
*
* @arg direction the rotational direction the thwomp is facing.
* @arg behaviour the behaviour of the thwomp, uses values 1-6.
* @arg primAlpha unknown
* @arg boundingBoxSize optional. The size of the bounding box for the thwomp. Default value is 12
*/
class OPenguin {
public:
enum PenguinType : uint32_t {
CHICK,
ADULT,
CREDITS,
EMPEROR
};
enum Behaviour : uint16_t {
DISABLED,
STRUT, // Emperor penguin
CIRCLE, // Waddle in a circle
SLIDE3,
SLIDE4,
UNK, // unused
SLIDE6,
};
public:
f32 Diameter = 0.0f; // Waddle in a circle around the spawn point at this diameter.
uint16_t MirrorModeAngleOffset;
explicit OPenguin(s32 i, Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour);
void Tick();
void Draw(s32 playerId);
private:
void Behaviours(s32 objectIndex, s32 arg1);
void EmperorPenguin(s32 objectIndex);
void InitEmperorPenguin(s32 objectIndex);
void OtherPenguin(s32 objectIndex);
void InitOtherPenguin(s32 objectIndex);
s32 _idx;
PenguinType _type;
Behaviour _bhv;
};

View File

@ -295,8 +295,10 @@ extern "C" {
void CourseManager_ClearVehicles(void) {
gWorldInstance.ClearVehicles();
gWorldInstance.Crossings.clear();
gWorldInstance.BombKarts.clear();
gWorldInstance.Thwomps.clear();
gWorldInstance.Penguins.clear();
}
void CourseManager_CrossingTrigger() {
@ -501,6 +503,22 @@ extern "C" {
}
}
void CourseManager_TickPenguins(void) {
for (auto& penguin : gWorldInstance.Penguins) {
if (penguin) {
penguin->Tick();
}
}
}
void CourseManager_DrawPenguins(s32 cameraId) {
for (auto& penguin : gWorldInstance.Penguins) {
if (penguin) {
penguin->Draw(cameraId);
}
}
}
size_t GetCupCursorPosition() {
return gWorldInstance.CurrentCup->CursorPosition;
}

View File

@ -98,6 +98,10 @@ void CourseManager_DrawThwomps(s32 cameraId);
void CourseManager_TickThwomps();
void CourseManager_DrawPenguins(s32 cameraId);
void CourseManager_TickPenguins();
void CourseManager_CrossingTrigger();
void CourseManager_VehiclesCollision(s32 playerId, Player* player);

View File

@ -3637,7 +3637,6 @@ void func_80052D70(s32 playerId) {
void func_80052E30(UNUSED s32 arg0) {
s32 var_s0;
// Lights1 D_800E4620l = *(Lights1 *) LOAD_ASSET(D_800E4620);
D_800E4620.l[0].l.dir[0] = D_80165840[0];
D_800E4620.l[0].l.dir[1] = D_80165840[1];
D_800E4620.l[0].l.dir[2] = D_80165840[2];
@ -3760,20 +3759,12 @@ void render_lakitu(s32 cameraId) {
void translate_thwomp_lights(UNUSED s32 arg0) {
func_800419F8();
// Lights1 *D_800E4638l = (Lights1 *) LOAD_ASSET(D_800E4638);
D_800E4638.l[0].l.dir[0] = D_80165840[0];
D_800E4638.l[0].l.dir[1] = D_80165840[1];
D_800E4638.l[0].l.dir[2] = D_80165840[2];
}
void thwomp_lights(s32 objectIndex) {
// Lights1 *D_800E4638l = (Lights1 *) LOAD_ASSET(D_800E4638);
// Lights1 *D_800E4650l = (Lights1 *) LOAD_ASSET(D_800E4650);
// Lights1 *D_800E4668l = (Lights1 *) LOAD_ASSET(D_800E4668);
// Lights1 *D_800E4680l = (Lights1 *) LOAD_ASSET(D_800E4680);
// Lights1 *D_800E4698l = (Lights1 *) LOAD_ASSET(D_800E4698);
// Why these don't just use `gSPSetLights1` calls...
switch (gObjectList[objectIndex].type) { // hmm very strange 80165C18
case 0: