mirror of
https://github.com/HarbourMasters/SpaghettiKart
synced 2026-06-04 10:49:12 -04:00
Merge branch 'next' of https://github.com/MegaMech/SpaghettiKart into next
This commit is contained in:
@@ -26,8 +26,10 @@ extern "C" {
|
||||
extern s8 gPlayerCount;
|
||||
}
|
||||
|
||||
OBombKart::OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C) {
|
||||
size_t OBombKart::_count = 0;
|
||||
|
||||
OBombKart::OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C) {
|
||||
_idx = _count;
|
||||
Vec3f _pos = {0, 0, 0};
|
||||
|
||||
if (waypoint) { // Spawn kart on waypoint
|
||||
@@ -68,6 +70,8 @@ OBombKart::OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex,
|
||||
WheelPos[3][1] = _pos[1];
|
||||
WheelPos[3][2] = _pos[2];
|
||||
check_bounding_collision(&_Collision, 2.0f, _pos[0], _pos[1], _pos[2]);
|
||||
|
||||
_count++;
|
||||
}
|
||||
|
||||
void OBombKart::Spawn() {
|
||||
@@ -334,9 +338,7 @@ void OBombKart::Draw(s32 cameraId) {
|
||||
}
|
||||
|
||||
if (GetCourse() == GetPodiumCeremony()) {
|
||||
// This isn't functionally equivallent.
|
||||
// Technicaly it should be if (kart[0].WaypointIndex < 16)
|
||||
if (WaypointIndex < 16) {
|
||||
if ((_idx == 0) && (WaypointIndex < 16)) {
|
||||
return;
|
||||
} else {
|
||||
cameraId = PLAYER_FOUR;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <vector>
|
||||
#include "engine/Matrix.h"
|
||||
|
||||
#include "World.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
#include "main.h"
|
||||
@@ -53,16 +55,26 @@ public:
|
||||
// Set waypoint to NULL if using a spawn position and not a waypoint.
|
||||
explicit OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C);
|
||||
|
||||
~OBombKart() {
|
||||
_count--;
|
||||
}
|
||||
|
||||
static size_t GetCount() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void Spawn();
|
||||
void BeginPlay();
|
||||
void Tick();
|
||||
void Draw(s32 playerId);
|
||||
void Draw(s32 cameraId);
|
||||
void DrawBattle(s32 cameraId);
|
||||
void Collision(s32 playerId, Player* player);
|
||||
void SomeRender(Vec3f arg1);
|
||||
void LoadMtx();
|
||||
void Waypoint(s32 screenId);
|
||||
private:
|
||||
static size_t _count;
|
||||
s32 _idx;
|
||||
Player* FindTarget();
|
||||
void Chase(Player*, Vec3f pos);
|
||||
|
||||
|
||||
@@ -52,7 +52,6 @@ void OCheepCheep::Draw(s32 cameraId) { // func_8005217C
|
||||
Lights1* D_800E45C0l = (Lights1*) (D_800E45C0);
|
||||
Object* object;
|
||||
s32 temp_a3;
|
||||
|
||||
temp_a3 = indexObjectList2[0];
|
||||
object = &gObjectList[temp_a3];
|
||||
if (object->state >= 2) {
|
||||
|
||||
+15
-15
@@ -23,25 +23,28 @@ extern "C" {
|
||||
#include "assets/koopa_troopa_beach_data.h"
|
||||
}
|
||||
|
||||
OCrab::OCrab(s32 i, Vec3f pos) {
|
||||
size_t OCrab::_count = 0;
|
||||
|
||||
OCrab::OCrab(const FVector2D& start, const FVector2D& end) {
|
||||
s32 objectId;
|
||||
//for (i = 0; i < NUM_CRABS; i++) {
|
||||
_idx = i;
|
||||
objectId = indexObjectList1[i];
|
||||
_idx = _count;
|
||||
_start = start;
|
||||
_end = end;
|
||||
|
||||
objectId = indexObjectList1[_idx];
|
||||
init_object(objectId, 0);
|
||||
gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] =
|
||||
gCrabSpawns[i].startX * xOrientation;
|
||||
gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = start.x * xOrientation;
|
||||
gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = start.z;
|
||||
|
||||
gObjectList[objectId].unk_01C[0] = gCrabSpawns[i].patrolX * xOrientation;
|
||||
gObjectList[objectId].unk_01C[0] = end.x * xOrientation;
|
||||
gObjectList[objectId].unk_01C[2] = end.z;
|
||||
|
||||
gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = gCrabSpawns[i].startZ;
|
||||
gObjectList[objectId].unk_01C[2] = gCrabSpawns[i].patrolZ;
|
||||
_count++;
|
||||
}
|
||||
|
||||
void OCrab::Tick(void) {
|
||||
s32 objectIndex;
|
||||
|
||||
//for (var_s1 = 0; var_s1 < NUM_CRABS; var_s1++) {
|
||||
objectIndex = indexObjectList1[_idx];
|
||||
if (gObjectList[objectIndex].state != 0) {
|
||||
OCrab::func_80082B34(objectIndex);
|
||||
@@ -49,12 +52,11 @@ void OCrab::Tick(void) {
|
||||
OCrab::func_80082C30(objectIndex);
|
||||
OCrab::func_80082E18(objectIndex);
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
void OCrab::Draw(s32 objectIndex, s32 cameraId) {
|
||||
void OCrab::Draw(s32 cameraId) {
|
||||
Camera* camera;
|
||||
|
||||
s32 objectIndex = indexObjectList1[_idx];
|
||||
if (gObjectList[objectIndex].state >= 2) {
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog);
|
||||
camera = &camera1[cameraId];
|
||||
@@ -72,7 +74,6 @@ void OCrab::DrawModel(s32 cameraId) {
|
||||
s32 someIndex;
|
||||
s32 test;
|
||||
|
||||
//for (someIndex = 0; someIndex < NUM_CRABS; someIndex++) {
|
||||
test = indexObjectList1[_idx];
|
||||
func_8008A364(test, cameraId, 0x2AABU, 800);
|
||||
if (is_obj_flag_status_active(test, VISIBLE) != 0) {
|
||||
@@ -86,7 +87,6 @@ void OCrab::DrawModel(s32 cameraId) {
|
||||
draw_2d_texture_at(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation, gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, (u8*)gObjectList[objectIndex].activeTexture, (Vtx*)common_vtx_hedgehog, 0x00000040, 0x00000040, 0x00000040, 0x00000020);
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
void OCrab::init_ktb_crab(s32 objectIndex) {
|
||||
|
||||
+20
-13
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <libultraship.h>
|
||||
#include <vector>
|
||||
#include "engine/objects/Object.h"
|
||||
#include "World.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
@@ -14,20 +16,23 @@ extern "C" {
|
||||
#include "some_data.h"
|
||||
}
|
||||
|
||||
|
||||
class OCrab {
|
||||
/**
|
||||
* @arg start x and z spawn location
|
||||
* @arg end x and z patrol location
|
||||
*
|
||||
* Crab patrols between start and end.
|
||||
* The game automatically places the actor on the course surface.
|
||||
* Therefore, providing a Y height is unnecessary.
|
||||
*
|
||||
* Crab appears to have a maximum patrolling distance and will patrol between
|
||||
* end --> max distance rather than start --> end or start --> max distance.
|
||||
*/
|
||||
class OCrab : public OObject {
|
||||
public:
|
||||
enum Behaviour : uint16_t {
|
||||
};
|
||||
explicit OCrab(const FVector2D& start, const FVector2D& end);
|
||||
|
||||
public:
|
||||
f32 Diameter = 0.0f; // Waddle in a circle around the spawn point at this diameter.
|
||||
uint16_t MirrorModeAngleOffset;
|
||||
|
||||
explicit OCrab(s32 i, Vec3f pos);
|
||||
|
||||
void Tick();
|
||||
void Draw(s32 objectIndex, s32 cameraId);
|
||||
virtual void Tick() override;
|
||||
virtual void Draw(s32 cameraId) override;
|
||||
void DrawModel(s32 cameraId);
|
||||
|
||||
void init_ktb_crab(s32 objectIndex);
|
||||
@@ -36,6 +41,8 @@ public:
|
||||
void func_80082E18(s32 objectIndex);
|
||||
|
||||
private:
|
||||
|
||||
FVector2D _start;
|
||||
FVector2D _end;
|
||||
static size_t _count;
|
||||
s32 _idx;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
#include "Flagpole.h"
|
||||
#include "World.h"
|
||||
|
||||
extern "C" {
|
||||
#include "code_800029B0.h"
|
||||
#include "render_objects.h"
|
||||
#include "update_objects.h"
|
||||
#include "assets/yoshi_valley_data.h"
|
||||
#include "assets/common_data.h"
|
||||
#include "math_util.h"
|
||||
#include "math_util_2.h"
|
||||
#include "code_80086E70.h"
|
||||
#include "code_80057C60.h"
|
||||
}
|
||||
|
||||
size_t OFlagpole::_count = 0;
|
||||
|
||||
OFlagpole::OFlagpole(const FVector& pos, s16 direction) {
|
||||
_idx = _count;
|
||||
_pos = pos;
|
||||
_direction = direction;
|
||||
|
||||
init_object(indexObjectList1[_idx], 0);
|
||||
|
||||
_count++;
|
||||
}
|
||||
|
||||
void OFlagpole::Tick() { // func_80083080
|
||||
s32 objectIndex = indexObjectList1[_idx];
|
||||
|
||||
if (gObjectList[objectIndex].state != 0) {
|
||||
OFlagpole::func_80083018(objectIndex);
|
||||
OFlagpole::func_80083060(objectIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void OFlagpole::Draw(s32 cameraId) { // func_80055228
|
||||
s32 objectIndex = indexObjectList1[_idx];
|
||||
|
||||
func_8008A364(objectIndex, cameraId, 0x4000U, 0x000005DC);
|
||||
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
|
||||
OFlagpole::func_80055164(objectIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void OFlagpole::func_80055164(s32 objectIndex) { // func_80055164
|
||||
if (gObjectList[objectIndex].state >= 2) {
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0077A0);
|
||||
rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].direction_angle,
|
||||
gObjectList[objectIndex].sizeScaling);
|
||||
if (gIsGamePaused == 0) {
|
||||
gObjectList[objectIndex].unk_0A2 = render_animated_model((Armature*) gObjectList[objectIndex].model,
|
||||
(Animation**) gObjectList[objectIndex].vertex, 0,
|
||||
gObjectList[objectIndex].unk_0A2);
|
||||
} else {
|
||||
render_animated_model((Armature*) gObjectList[objectIndex].model,
|
||||
(Animation**) gObjectList[objectIndex].vertex, 0, gObjectList[objectIndex].unk_0A2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OFlagpole::func_80082F1C(s32 objectIndex) {
|
||||
gObjectList[objectIndex].model = (Gfx*) d_course_yoshi_valley_unk5;
|
||||
gObjectList[objectIndex].vertex = (Vtx*) d_course_yoshi_valley_unk4;
|
||||
gObjectList[objectIndex].sizeScaling = 0.027f;
|
||||
object_next_state(objectIndex);
|
||||
set_obj_origin_pos(objectIndex, _pos.x * xOrientation, _pos.y, _pos.z);
|
||||
set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f);
|
||||
set_obj_direction_angle(objectIndex, 0U, _direction, 0U);
|
||||
}
|
||||
|
||||
void OFlagpole::func_80083018(s32 objectIndex) {
|
||||
switch (gObjectList[objectIndex].state) {
|
||||
case 1:
|
||||
OFlagpole::func_80082F1C(objectIndex);
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OFlagpole::func_80083060(s32 objectIndex) {
|
||||
object_calculate_new_pos_offset(objectIndex);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <libultraship.h>
|
||||
#include <vector>
|
||||
#include "Object.h"
|
||||
|
||||
#include "World.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
#include "main.h"
|
||||
#include "vehicles.h"
|
||||
#include "waypoints.h"
|
||||
#include "common_structs.h"
|
||||
#include "objects.h"
|
||||
#include "camera.h"
|
||||
#include "some_data.h"
|
||||
}
|
||||
|
||||
class OFlagpole : public OObject {
|
||||
public:
|
||||
explicit OFlagpole(const FVector& pos, s16 direction);
|
||||
|
||||
~OFlagpole() {
|
||||
_count--;
|
||||
}
|
||||
|
||||
static size_t GetCount() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
virtual void Tick() override;
|
||||
virtual void Draw(s32 cameraId) override;
|
||||
|
||||
void func_80055164(s32 objectIndex);
|
||||
void func_80082F1C(s32 objectIndex);
|
||||
void func_80083018(s32 objectIndex);
|
||||
void func_80083060(s32 objectIndex);
|
||||
|
||||
private:
|
||||
FVector _pos;
|
||||
s16 _direction;
|
||||
static size_t _count;
|
||||
size_t _idx;
|
||||
};
|
||||
@@ -0,0 +1,183 @@
|
||||
#include "Hedgehog.h"
|
||||
#include "World.h"
|
||||
|
||||
extern "C" {
|
||||
#include "render_objects.h"
|
||||
#include "update_objects.h"
|
||||
#include "assets/yoshi_valley_data.h"
|
||||
#include "assets/common_data.h"
|
||||
#include "math_util.h"
|
||||
#include "math_util_2.h"
|
||||
#include "code_80086E70.h"
|
||||
#include "code_80057C60.h"
|
||||
}
|
||||
|
||||
size_t OHedgehog::_count = 0;
|
||||
|
||||
OHedgehog::OHedgehog(const FVector& pos, const FVector2D& patrolPoint, s16 unk) {
|
||||
_idx = _count;
|
||||
_pos = pos;
|
||||
|
||||
s32 objectId = indexObjectList2[_idx];
|
||||
init_object(objectId, 0);
|
||||
gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = pos.x * xOrientation;
|
||||
gObjectList[objectId].pos[1] = gObjectList[objectId].surfaceHeight = pos.y + 6.0;
|
||||
gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = pos.z;
|
||||
gObjectList[objectId].unk_0D5 = (u8)unk;
|
||||
gObjectList[objectId].unk_09C = patrolPoint.x * xOrientation;
|
||||
gObjectList[objectId].unk_09E = patrolPoint.z;
|
||||
|
||||
_count++;
|
||||
}
|
||||
|
||||
void OHedgehog::Tick() {
|
||||
s32 objectIndex = indexObjectList2[_idx];
|
||||
|
||||
OHedgehog::func_800833D0(objectIndex, _idx);
|
||||
OHedgehog::func_80083248(objectIndex);
|
||||
OHedgehog::func_80083474(objectIndex);
|
||||
|
||||
// This func clears a bit from all hedgehogs. This results in setting the height of all hedgehogs to zero.
|
||||
// The solution is to only clear the bit from the current instance; `self` or `this`
|
||||
//func_80072120(indexObjectList2, NUM_HEDGEHOGS);
|
||||
clear_object_flag(objectIndex, 0x00600000); // The fix
|
||||
}
|
||||
|
||||
void OHedgehog::Draw(s32 cameraId) {
|
||||
s32 objectIndex = indexObjectList2[_idx];
|
||||
u32 something = func_8008A364(objectIndex, cameraId, 0x4000U, 0x000003E8);
|
||||
|
||||
if (CVarGetInteger("gNoCulling", 0) == 1) {
|
||||
something = MIN(something, 0x52211U - 1);
|
||||
}
|
||||
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
|
||||
set_object_flag(objectIndex, 0x00200000);
|
||||
if (something < 0x2711U) {
|
||||
set_object_flag(objectIndex, 0x00000020);
|
||||
} else {
|
||||
clear_object_flag(objectIndex, 0x00000020);
|
||||
}
|
||||
if (something < 0x57E41U) {
|
||||
set_object_flag(objectIndex, 0x00400000);
|
||||
}
|
||||
if (something < 0x52211U) {
|
||||
OHedgehog::func_800555BC(objectIndex, cameraId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OHedgehog::func_800555BC(s32 objectIndex, s32 cameraId) {
|
||||
Camera* camera;
|
||||
|
||||
if (gObjectList[objectIndex].state >= 2) {
|
||||
camera = &camera1[cameraId];
|
||||
OHedgehog::func_8004A870(objectIndex, 0.7f);
|
||||
gObjectList[objectIndex].orientation[1] =
|
||||
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos);
|
||||
draw_2d_texture_at(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation,
|
||||
gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT,
|
||||
(u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 64, 64, 64, 32);
|
||||
}
|
||||
}
|
||||
|
||||
void OHedgehog::func_8004A870(s32 objectIndex, f32 arg1) {
|
||||
Mat4 mtx;
|
||||
Object* object;
|
||||
|
||||
if ((is_obj_flag_status_active(objectIndex, 0x00000020) != 0) &&
|
||||
(is_obj_flag_status_active(objectIndex, 0x00800000) != 0)) {
|
||||
object = &gObjectList[objectIndex];
|
||||
D_80183E50[0] = object->pos[0];
|
||||
D_80183E50[1] = object->surfaceHeight + 0.8;
|
||||
D_80183E50[2] = object->pos[2];
|
||||
set_transform_matrix(mtx, object->unk_01C, D_80183E50, 0U, arg1);
|
||||
// convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], mtx);
|
||||
// gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]),
|
||||
// G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
||||
AddHudMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007B98);
|
||||
}
|
||||
}
|
||||
|
||||
const char* sHedgehogTexList[] = { d_course_yoshi_valley_hedgehog };
|
||||
|
||||
void OHedgehog::func_8008311C(s32 objectIndex, s32 arg1) {
|
||||
Object* object;
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog);
|
||||
|
||||
init_texture_object(objectIndex, (u8*)d_course_yoshi_valley_hedgehog_tlut, sHedgehogTexList, 0x40U, (u16) 0x00000040);
|
||||
object = &gObjectList[objectIndex];
|
||||
object->activeTLUT = d_course_yoshi_valley_hedgehog_tlut;
|
||||
object->activeTexture = d_course_yoshi_valley_hedgehog;
|
||||
object->vertex = vtx;
|
||||
object->sizeScaling = 0.2f;
|
||||
object->textureListIndex = 0;
|
||||
object_next_state(objectIndex);
|
||||
set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f);
|
||||
set_obj_orientation(objectIndex, 0U, 0U, 0x8000U);
|
||||
object->unk_034 = ((arg1 % 6) * 0.1) + 0.5;
|
||||
func_80086E70(objectIndex);
|
||||
set_object_flag(objectIndex, 0x04000600);
|
||||
object->boundingBoxSize = 2;
|
||||
}
|
||||
|
||||
void OHedgehog::func_80083248(s32 objectIndex) {
|
||||
switch (gObjectList[objectIndex].unk_0AE) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
if (func_80087A0C(objectIndex, gObjectList[objectIndex].origin_pos[0], gObjectList[objectIndex].unk_09C,
|
||||
gObjectList[objectIndex].origin_pos[2], gObjectList[objectIndex].unk_09E) != 0) {
|
||||
func_80086FD4(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
func_800871AC(objectIndex, 0x0000003C);
|
||||
break;
|
||||
case 3:
|
||||
if (func_80087A0C(objectIndex, gObjectList[objectIndex].unk_09C, gObjectList[objectIndex].origin_pos[0],
|
||||
gObjectList[objectIndex].unk_09E, gObjectList[objectIndex].origin_pos[2]) != 0) {
|
||||
func_80086FD4(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (func_80087060(objectIndex, 0x0000003C) != 0) {
|
||||
func_8008701C(objectIndex, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
object_calculate_new_pos_offset(objectIndex);
|
||||
if (is_obj_flag_status_active(objectIndex, 0x00200000) != 0) {
|
||||
if (is_obj_flag_status_active(objectIndex, 0x00400000) != 0) {
|
||||
func_8008861C(objectIndex);
|
||||
}
|
||||
gObjectList[objectIndex].pos[1] = gObjectList[objectIndex].surfaceHeight + 6.0;
|
||||
}
|
||||
}
|
||||
|
||||
void OHedgehog::func_800833D0(s32 objectIndex, s32 arg1) {
|
||||
switch (gObjectList[objectIndex].state) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
OHedgehog::func_8008311C(objectIndex, arg1);
|
||||
break;
|
||||
case 2:
|
||||
func_80072D3C(objectIndex, 0, 1, 4, -1);
|
||||
break;
|
||||
}
|
||||
if (gObjectList[objectIndex].textureListIndex == 0) {
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog);
|
||||
gObjectList[objectIndex].vertex = vtx;
|
||||
} else {
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(D_0D006130);
|
||||
gObjectList[objectIndex].vertex = vtx;
|
||||
}
|
||||
}
|
||||
|
||||
void OHedgehog::func_80083474(s32 objectIndex) {
|
||||
if (gObjectList[objectIndex].state >= 2) {
|
||||
func_80089F24(objectIndex);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <libultraship.h>
|
||||
#include <vector>
|
||||
#include "Object.h"
|
||||
|
||||
#include "engine/World.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
#include "main.h"
|
||||
#include "vehicles.h"
|
||||
#include "waypoints.h"
|
||||
#include "common_structs.h"
|
||||
#include "objects.h"
|
||||
#include "camera.h"
|
||||
#include "some_data.h"
|
||||
}
|
||||
|
||||
/**
|
||||
* @arg pos FVector xyz spawn position
|
||||
* @arg patrolPoint FVector2D xz patrol to location. Actor automatically calculates the Y value
|
||||
* @arg unk unknown. Likely actor type.
|
||||
*/
|
||||
class OHedgehog : public OObject {
|
||||
public:
|
||||
explicit OHedgehog(const FVector& pos, const FVector2D& patrolPoint, s16 unk);
|
||||
|
||||
~OHedgehog() {
|
||||
_count--;
|
||||
}
|
||||
|
||||
static size_t GetCount() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
virtual void Tick() override;
|
||||
virtual void Draw(s32 cameraId) override;
|
||||
|
||||
void func_800555BC(s32 objectIndex, s32 cameraId);
|
||||
void func_8004A870(s32 objectIndex, f32 arg1);
|
||||
|
||||
void func_8008311C(s32 objectIndex, s32 arg1);
|
||||
void func_80083248(s32 objectIndex);
|
||||
void func_800833D0(s32 objectIndex, s32 arg1);
|
||||
void func_80083474(s32 objectIndex);
|
||||
|
||||
|
||||
private:
|
||||
FVector _pos;
|
||||
static size_t _count;
|
||||
size_t _idx;
|
||||
};
|
||||
@@ -0,0 +1,174 @@
|
||||
#include "HotAirBalloon.h"
|
||||
#include "World.h"
|
||||
#include "port/Game.h"
|
||||
|
||||
extern "C" {
|
||||
#include "render_objects.h"
|
||||
#include "update_objects.h"
|
||||
#include "assets/luigi_raceway_data.h"
|
||||
#include "assets/common_data.h"
|
||||
#include "math_util.h"
|
||||
#include "math_util_2.h"
|
||||
#include "code_80086E70.h"
|
||||
#include "code_80057C60.h"
|
||||
#include "actors.h"
|
||||
}
|
||||
|
||||
OHotAirBalloon::OHotAirBalloon(const FVector& pos) {
|
||||
_pos = pos;
|
||||
|
||||
D_80165898 = 0;
|
||||
|
||||
// Spawn balloon on second lap.
|
||||
if (GetCourse() == GetLuigiRaceway()) {
|
||||
_visible = (bool*)&D_80165898;
|
||||
} else { // Spawn balloon on race start
|
||||
bool mod = true;
|
||||
_visible = &mod;
|
||||
}
|
||||
|
||||
init_object(indexObjectList1[0], 0);
|
||||
}
|
||||
|
||||
void OHotAirBalloon::Tick() {
|
||||
s32 objectIndex = indexObjectList1[0];
|
||||
|
||||
if (*_visible) {
|
||||
if (gObjectList[objectIndex].state != 0) {
|
||||
OHotAirBalloon::func_80085768(objectIndex);
|
||||
OHotAirBalloon::func_80085534(objectIndex);
|
||||
object_calculate_new_pos_offset(objectIndex);
|
||||
if (gObjectList[objectIndex].state >= 2) {
|
||||
gActorHotAirBalloonItemBox->pos[0] = gObjectList[objectIndex].pos[0];
|
||||
gActorHotAirBalloonItemBox->pos[1] = gObjectList[objectIndex].pos[1] - 10.0;
|
||||
gActorHotAirBalloonItemBox->pos[2] = gObjectList[objectIndex].pos[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OHotAirBalloon::Draw(s32 cameraId) {
|
||||
s32 objectIndex;
|
||||
objectIndex = indexObjectList1[0];
|
||||
if (*_visible) {
|
||||
if (gGamestate != CREDITS_SEQUENCE) {
|
||||
func_8008A1D0(objectIndex, cameraId, 0x000005DC, 0x00000BB8);
|
||||
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
|
||||
OHotAirBalloon::func_80055CCC(objectIndex, cameraId);
|
||||
}
|
||||
} else {
|
||||
clear_object_flag(objectIndex, 0x00100000);
|
||||
OHotAirBalloon::func_80055CCC(objectIndex, cameraId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OHotAirBalloon::func_80055CCC(s32 objectIndex, s32 cameraId) {
|
||||
UNUSED s32 pad;
|
||||
f32 test;
|
||||
Camera* camera;
|
||||
|
||||
camera = &camera1[cameraId];
|
||||
if (gObjectList[objectIndex].state >= 2) {
|
||||
func_8008A454(objectIndex, cameraId, 0x0000012C);
|
||||
test = gObjectList[objectIndex].pos[1] - gObjectList[objectIndex].surfaceHeight;
|
||||
func_8004A6EC(objectIndex, (20.0 / test) + 0.5);
|
||||
if (is_obj_index_flag_status_inactive(objectIndex, 0x00100000) != 0) {
|
||||
func_80043328(gObjectList[objectIndex].pos, (u16*) gObjectList[objectIndex].direction_angle,
|
||||
gObjectList[objectIndex].sizeScaling, (Gfx*)d_course_luigi_raceway_dl_F960);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_luigi_raceway_dl_F650);
|
||||
} else {
|
||||
D_80183E80[0] = (s16) gObjectList[objectIndex].direction_angle[0];
|
||||
D_80183E80[1] =
|
||||
(s16) (func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos) +
|
||||
0x8000);
|
||||
D_80183E80[2] = (u16) gObjectList[objectIndex].direction_angle[2];
|
||||
func_80043328(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling,
|
||||
(Gfx*)d_course_luigi_raceway_dl_FBE0);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_luigi_raceway_dl_FA20);
|
||||
if (gPlayerCountSelection1 == 1) {
|
||||
gObjectList[objectIndex].direction_angle[1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OHotAirBalloon::init_hot_air_balloon(s32 objectIndex) {
|
||||
gObjectList[objectIndex].sizeScaling = 1.0f;
|
||||
gObjectList[objectIndex].model = (Gfx*)d_course_luigi_raceway_dl_F960;
|
||||
if (gGamestate != CREDITS_SEQUENCE) {
|
||||
set_obj_origin_pos(objectIndex, xOrientation * _pos.x, _pos.y, _pos.z);
|
||||
set_obj_origin_offset(objectIndex, 0.0f, 300.0f, 0.0f);
|
||||
} else {
|
||||
set_obj_origin_pos(objectIndex, xOrientation * _pos.x, _pos.y, _pos.z);
|
||||
set_obj_origin_offset(objectIndex, 0.0f, 300.0f, 0.0f);
|
||||
}
|
||||
func_8008B844(objectIndex);
|
||||
func_800886F4(objectIndex);
|
||||
func_80086EF0(objectIndex);
|
||||
gObjectList[objectIndex].velocity[1] = -2.0f;
|
||||
init_actor_hot_air_balloon_item_box(0.0f, 0.0f, 0.0f);
|
||||
object_next_state(objectIndex);
|
||||
}
|
||||
|
||||
void OHotAirBalloon::func_80085534(s32 objectIndex) {
|
||||
switch (gObjectList[objectIndex].unk_0AE) {
|
||||
case 1:
|
||||
if (gObjectList[objectIndex].offset[1] <= 18.0) {
|
||||
func_80086FD4(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f);
|
||||
if (gObjectList[objectIndex].velocity[1] == 0.0) {
|
||||
func_80086FD4(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
func_800871AC(objectIndex, 1);
|
||||
break;
|
||||
case 4:
|
||||
f32_step_towards(&gObjectList[objectIndex].velocity[1], 1.0f, 0.05f);
|
||||
if (gObjectList[objectIndex].velocity[1] == 1.0) {
|
||||
func_80086FD4(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
func_800871AC(objectIndex, 90);
|
||||
break;
|
||||
case 6:
|
||||
f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f);
|
||||
if (gObjectList[objectIndex].velocity[1] == 0.0) {
|
||||
func_80086FD4(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
f32_step_towards(&gObjectList[objectIndex].velocity[1], -1.0f, 0.05f);
|
||||
if (gObjectList[objectIndex].velocity[1] == -1.0) {
|
||||
func_80086FD4(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
func_800871AC(objectIndex, 90);
|
||||
break;
|
||||
case 9:
|
||||
f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f);
|
||||
if (func_80087060(objectIndex, 90) != 0) {
|
||||
func_8008701C(objectIndex, 3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
object_add_velocity_offset_y(objectIndex);
|
||||
gObjectList[objectIndex].direction_angle[1] += 0x100;
|
||||
}
|
||||
|
||||
void OHotAirBalloon::func_80085768(s32 objectIndex) {
|
||||
switch (gObjectList[objectIndex].state) { /* irregular */
|
||||
case 1:
|
||||
OHotAirBalloon::init_hot_air_balloon(objectIndex);
|
||||
break;
|
||||
case 0:
|
||||
case 2:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <libultraship.h>
|
||||
#include <vector>
|
||||
#include "Object.h"
|
||||
|
||||
#include "World.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
#include "main.h"
|
||||
#include "vehicles.h"
|
||||
#include "waypoints.h"
|
||||
#include "common_structs.h"
|
||||
#include "objects.h"
|
||||
#include "camera.h"
|
||||
#include "some_data.h"
|
||||
}
|
||||
|
||||
class OHotAirBalloon : public OObject {
|
||||
public:
|
||||
explicit OHotAirBalloon(const FVector& pos);
|
||||
|
||||
virtual void Tick() override;
|
||||
virtual void Draw(s32 cameraId) override;
|
||||
void func_80055CCC(s32 objectIndex, s32 cameraId);
|
||||
void init_hot_air_balloon(s32 objectIndex);
|
||||
void func_80085534(s32 objectIndex);
|
||||
void func_80085768(s32 objectIndex);
|
||||
|
||||
private:
|
||||
FVector _pos;
|
||||
bool *_visible;
|
||||
};
|
||||
@@ -0,0 +1,856 @@
|
||||
#include <libultraship.h>
|
||||
#include <libultra/gbi.h>
|
||||
#include "Lakitu.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"
|
||||
#include "race_logic.h"
|
||||
#include "effects.h"
|
||||
#include "memory.h"
|
||||
extern s8 gPlayerCount;
|
||||
}
|
||||
|
||||
OLakitu::OLakitu(s32 playerId, LakituType type) {
|
||||
_playerId = playerId;
|
||||
|
||||
init_object(gIndexLakituList[playerId], (s32)type);
|
||||
}
|
||||
|
||||
void OLakitu::Activate(LakituType type) {
|
||||
init_object(gIndexLakituList[_playerId], (s32)type);
|
||||
}
|
||||
|
||||
void OLakitu::Tick() {
|
||||
OLakitu::func_8007AA44(_playerId);
|
||||
}
|
||||
|
||||
void OLakitu::Tick60fps() { // update_object_lakitu
|
||||
s32 playerId = _playerId;
|
||||
s32 objectIndex = gIndexLakituList[playerId];
|
||||
|
||||
switch (gObjectList[objectIndex].unk_0D8) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
OLakitu::update_object_lakitu_starter(objectIndex, playerId);
|
||||
func_8008BFFC(objectIndex);
|
||||
break;
|
||||
case 2:
|
||||
OLakitu::update_object_lakitu_checkered_flag(objectIndex, playerId);
|
||||
func_8008BFFC(objectIndex);
|
||||
break;
|
||||
case 3:
|
||||
OLakitu::update_object_lakitu_fishing(objectIndex, playerId);
|
||||
break;
|
||||
case 4:
|
||||
OLakitu::update_object_lakitu_second_lap(objectIndex, playerId);
|
||||
func_8008BFFC(objectIndex);
|
||||
break;
|
||||
case 5:
|
||||
OLakitu::update_object_lakitu_final_lap(objectIndex, playerId);
|
||||
func_8008BFFC(objectIndex);
|
||||
break;
|
||||
case 6:
|
||||
OLakitu::update_object_lakitu_reverse(objectIndex, playerId);
|
||||
func_8008BFFC(objectIndex);
|
||||
break;
|
||||
case 7:
|
||||
OLakitu::update_object_lakitu_fishing2(objectIndex, playerId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OLakitu::Draw(s32 cameraId) {
|
||||
UNUSED s32 stackPadding;
|
||||
Camera* camera;
|
||||
f32 var_f0;
|
||||
f32 var_f2;
|
||||
s32 objectIndex;
|
||||
Object* object;
|
||||
|
||||
objectIndex = gIndexLakituList[cameraId];
|
||||
camera = &camera1[cameraId];
|
||||
if (is_obj_flag_status_active(objectIndex, 0x00000010) != 0) {
|
||||
object = &gObjectList[objectIndex];
|
||||
object->orientation[0] = 0;
|
||||
object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos);
|
||||
object->orientation[2] = 0x8000;
|
||||
if (func_80072354(objectIndex, 2) != 0) {
|
||||
draw_2d_texture_at(object->pos, object->orientation, object->sizeScaling, (u8*) object->activeTLUT,
|
||||
(u8*)object->activeTexture, object->vertex, (s32) object->textureWidth,
|
||||
(s32) object->textureHeight, (s32) object->textureWidth,
|
||||
(s32) object->textureHeight / 2);
|
||||
} else {
|
||||
func_800485C4(object->pos, object->orientation, object->sizeScaling, (s32) object->primAlpha,
|
||||
(u8*) object->activeTLUT, (u8*)object->activeTexture, object->vertex, (s32) object->textureWidth,
|
||||
(s32) object->textureHeight, (s32) object->textureWidth, (s32) object->textureHeight / 2);
|
||||
}
|
||||
if (gScreenModeSelection == SCREEN_MODE_1P) {
|
||||
var_f0 = object->pos[0] - camera->pos[0];
|
||||
var_f2 = object->pos[2] - camera->pos[2];
|
||||
if (var_f0 < 0.0f) {
|
||||
var_f0 = -var_f0;
|
||||
}
|
||||
if (var_f2 < 0.0f) {
|
||||
var_f2 = -var_f2;
|
||||
}
|
||||
if ((var_f0 + var_f2) <= 200.0) {
|
||||
func_8004A630(&D_8018C0B0[cameraId], object->pos, 0.35f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OLakitu::func_80079114(s32 objectIndex, s32 playerId, s32 arg2) {
|
||||
s32 a;
|
||||
if (gObjectList[objectIndex].state >= 2) {
|
||||
if ((u8) gObjectList[objectIndex].unk_0D8 == 1) {
|
||||
if (playerId == 0) {
|
||||
func_80074894(objectIndex, gLakituTexturePtr);
|
||||
return;
|
||||
}
|
||||
a = gIndexLakituList[0];
|
||||
gObjectList[objectIndex].activeTLUT = gObjectList[a].activeTLUT;
|
||||
gObjectList[objectIndex].activeTexture = gObjectList[a].activeTexture;
|
||||
if (0) {}
|
||||
return;
|
||||
}
|
||||
switch (arg2) {
|
||||
case 0:
|
||||
func_800748F4(objectIndex, gLakituTexturePtr);
|
||||
break;
|
||||
case 1:
|
||||
func_800748C4(objectIndex, gLakituTexturePtr);
|
||||
break;
|
||||
case 2:
|
||||
func_80074894(objectIndex, gLakituTexturePtr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OLakitu::func_800791F0(s32 objectIndex, s32 playerId) {
|
||||
Player* player = &gPlayerOne[playerId];
|
||||
|
||||
if ((gObjectList[objectIndex].unk_0D8 != 3) && (gObjectList[objectIndex].unk_0D8 != 7)) {
|
||||
func_800722CC(objectIndex, 1);
|
||||
if (CourseManager_GetProps()->LakituTowType == LakituTowType::ICE) {
|
||||
player->unk_0CA &= 0xFFEF;
|
||||
}
|
||||
}
|
||||
|
||||
if (CourseManager_GetProps()->LakituTowType == LakituTowType::ICE) {
|
||||
func_800722CC(objectIndex, 0x00000010);
|
||||
player->unk_0CA &= 0xFFDF;
|
||||
}
|
||||
func_800C9018(playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28));
|
||||
}
|
||||
|
||||
static const char* sLakituTextures[] = {
|
||||
gTextureLakituNoLights1, gTextureLakituNoLights2, gTextureLakituNoLights3, gTextureLakituNoLights4,
|
||||
gTextureLakituNoLights5, gTextureLakituNoLights6, gTextureLakituNoLights7, gTextureLakituNoLights8,
|
||||
gTextureLakituRedLights01, gTextureLakituRedLights02, gTextureLakituRedLights03, gTextureLakituRedLights04,
|
||||
gTextureLakituRedLights05, gTextureLakituRedLights06, gTextureLakituRedLights07, gTextureLakituRedLights08,
|
||||
gTextureLakituRedLights09, gTextureLakituRedLights10, gTextureLakituRedLights11, gTextureLakituRedLights12,
|
||||
gTextureLakituRedLights13, gTextureLakituRedLights14, gTextureLakituRedLights15, gTextureLakituRedLights16,
|
||||
gTextureLakituBlueLight1, gTextureLakituBlueLight2, gTextureLakituBlueLight3, gTextureLakituBlueLight4,
|
||||
gTextureLakituBlueLight5, gTextureLakituBlueLight6, gTextureLakituBlueLight7, gTextureLakituBlueLight8,
|
||||
};
|
||||
|
||||
void OLakitu::init_obj_lakitu_starter_and_checkered_flag(s32 objectIndex, s32 playerId) {
|
||||
if (playerId == 0) {
|
||||
D_801656F0 = 0;
|
||||
D_8018D168 = 0;
|
||||
}
|
||||
|
||||
// u8 *tlut = (u8 *) LOAD_ASSET_RAW(common_tlut_lakitu_countdown);
|
||||
// u8 *lights = (u8 *) LOAD_ASSET_RAW(gTextureLakituNoLights1);
|
||||
|
||||
init_texture_object(
|
||||
objectIndex,
|
||||
(u8*) load_lakitu_tlut_x64(common_tlut_lakitu_countdown, ARRAY_COUNT(common_tlut_lakitu_countdown)),
|
||||
sLakituTextures, 56, (u16) 72);
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_lakitu);
|
||||
gObjectList[objectIndex].vertex = vtx;
|
||||
gObjectList[objectIndex].sizeScaling = 0.15f;
|
||||
clear_object_flag(objectIndex, 0x00000010);
|
||||
object_next_state(objectIndex);
|
||||
gObjectList[objectIndex].unk_048 = D_8018D180;
|
||||
}
|
||||
|
||||
void OLakitu::update_object_lakitu_starter(s32 objectIndex, s32 arg1) {
|
||||
UNUSED s32 pad;
|
||||
switch (gObjectList[objectIndex].state) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
OLakitu::init_obj_lakitu_starter_and_checkered_flag(objectIndex, arg1);
|
||||
break;
|
||||
case 2:
|
||||
set_and_run_timer_object(objectIndex, gObjectList[objectIndex].unk_048);
|
||||
if ((gObjectList[objectIndex].timer == 0x00000055) && (gPlayerCount == 3) && (arg1 == 0)) {
|
||||
D_8018D168 = 1;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
set_object_flag(objectIndex, 0x00000010);
|
||||
func_80086F10(objectIndex, 1, &D_800E67B8); // set a spline
|
||||
object_next_state(objectIndex);
|
||||
break;
|
||||
case 4:
|
||||
if ((set_and_run_timer_object(objectIndex, 0x0000001E) != false) && (gPlayerCount != 3) && (arg1 == 0)) {
|
||||
D_8018D168 = 1;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
set_and_run_timer_object(objectIndex, 0x0000001E);
|
||||
break;
|
||||
case 6:
|
||||
func_80072E54(objectIndex, 1, 7, 1, 2, 0);
|
||||
break;
|
||||
case 7:
|
||||
if (set_and_run_timer_object(objectIndex, 0x00000014) != 0) {
|
||||
gObjectList[objectIndex].tlutList += 0x200;
|
||||
if (arg1 == 0) {
|
||||
play_sound2(SOUND_ACTION_COUNTDOWN_LIGHT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
func_80072E54(objectIndex, 8, 0x0000000F, 1, 6, 0);
|
||||
break;
|
||||
case 9:
|
||||
if ((set_and_run_timer_object(objectIndex, 8) != 0) && (arg1 == 0)) {
|
||||
play_sound2(SOUND_ACTION_COUNTDOWN_LIGHT);
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if ((func_80072E54(objectIndex, 0x00000010, 0x00000017, 1, 6, 0) != 0) && (arg1 == 0)) {
|
||||
D_801656F0 = 1;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
if (set_and_run_timer_object(objectIndex, 8) != 0) {
|
||||
gObjectList[objectIndex].tlutList += 0x200;
|
||||
if (arg1 == 0) {
|
||||
play_sound2(SOUND_ACTION_GREEN_LIGHT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
func_80072E54(objectIndex, 0x00000018, 0x0000001B, 1, 6, 0);
|
||||
break;
|
||||
case 13:
|
||||
if (arg1 == 0) {
|
||||
OLakitu::func_800729EC(objectIndex);
|
||||
D_8018D160 = 1;
|
||||
break;
|
||||
}
|
||||
object_next_state(objectIndex);
|
||||
break;
|
||||
case 14:
|
||||
set_and_run_timer_object(objectIndex, 0x00000078);
|
||||
break;
|
||||
case 15:
|
||||
func_80072428(objectIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OLakitu::func_800729EC(s32 objectIndex) {
|
||||
u32 temp_v1 = 1;
|
||||
s32 i;
|
||||
|
||||
start_race();
|
||||
object_next_state(objectIndex);
|
||||
D_8018D2BC = 1;
|
||||
D_8018D2A4 = 1;
|
||||
|
||||
if (GetCourse() != GetYoshiValley()) {
|
||||
for (i = 0; i < gPlayerCount; i++) {
|
||||
playerHUD[i].unk_81 = temp_v1;
|
||||
}
|
||||
}
|
||||
func_8005AB20();
|
||||
}
|
||||
|
||||
static const char* sLakituCheckeredList[] = {
|
||||
gTextureLakituCheckeredFlag01, gTextureLakituCheckeredFlag02, gTextureLakituCheckeredFlag03,
|
||||
gTextureLakituCheckeredFlag04, gTextureLakituCheckeredFlag05, gTextureLakituCheckeredFlag06,
|
||||
gTextureLakituCheckeredFlag07, gTextureLakituCheckeredFlag08, gTextureLakituCheckeredFlag09,
|
||||
gTextureLakituCheckeredFlag10, gTextureLakituCheckeredFlag11, gTextureLakituCheckeredFlag12,
|
||||
gTextureLakituCheckeredFlag13, gTextureLakituCheckeredFlag14, gTextureLakituCheckeredFlag15,
|
||||
gTextureLakituCheckeredFlag16, gTextureLakituCheckeredFlag17, gTextureLakituCheckeredFlag18,
|
||||
gTextureLakituCheckeredFlag19, gTextureLakituCheckeredFlag20, gTextureLakituCheckeredFlag21,
|
||||
gTextureLakituCheckeredFlag22, gTextureLakituCheckeredFlag23, gTextureLakituCheckeredFlag24,
|
||||
gTextureLakituCheckeredFlag25, gTextureLakituCheckeredFlag26, gTextureLakituCheckeredFlag27,
|
||||
gTextureLakituCheckeredFlag28, gTextureLakituCheckeredFlag29, gTextureLakituCheckeredFlag30,
|
||||
gTextureLakituCheckeredFlag31, gTextureLakituCheckeredFlag32
|
||||
};
|
||||
|
||||
void OLakitu::init_obj_lakitu_checkered_flag(s32 objectIndex, s32 playerIndex) {
|
||||
Object* object;
|
||||
|
||||
OLakitu::func_800791F0(objectIndex, playerIndex);
|
||||
|
||||
u8* tex = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_checkered_flag);
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_also_lakitu);
|
||||
|
||||
init_texture_object(objectIndex, (u8*) tex, sLakituCheckeredList, 0x48U, (u16) 0x00000038);
|
||||
object = &gObjectList[objectIndex];
|
||||
object->activeTexture = *gObjectList[objectIndex].textureList;
|
||||
object->vertex = vtx;
|
||||
object->pos[2] = 5000.0f;
|
||||
object->pos[1] = 5000.0f;
|
||||
object->pos[0] = 5000.0f;
|
||||
object->sizeScaling = 0.15f;
|
||||
func_80086F10(objectIndex, 2, &D_800E6834);
|
||||
clear_object_flag(objectIndex, 0x00000010);
|
||||
object_next_state(objectIndex);
|
||||
}
|
||||
|
||||
void OLakitu::update_object_lakitu_checkered_flag(s32 objectIndex, s32 playerIndex) {
|
||||
switch (gObjectList[objectIndex].state) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
OLakitu::init_obj_lakitu_checkered_flag(objectIndex, playerIndex);
|
||||
break;
|
||||
case 2:
|
||||
set_object_flag(objectIndex, 0x00000010);
|
||||
object_next_state(objectIndex);
|
||||
break;
|
||||
case 3:
|
||||
func_80072E54(objectIndex, 0, 0x0000001F, 1, 2, -1);
|
||||
break;
|
||||
case 4:
|
||||
func_80072428(objectIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OLakitu::func_800797AC(s32 playerId) {
|
||||
s32 objectIndex;
|
||||
Player* player;
|
||||
|
||||
objectIndex = gIndexLakituList[playerId];
|
||||
player = &gPlayerOne[playerId];
|
||||
//if ((GetCourse() == GetSherbetLand()) && (player->unk_0CA & 1)) {
|
||||
if ((CourseManager_GetProps()->LakituTowType == LakituTowType::ICE) && (player->unk_0CA & 1)) {
|
||||
init_object(objectIndex, 7);
|
||||
player->unk_0CA |= 0x10;
|
||||
} else {
|
||||
init_object(objectIndex, 3);
|
||||
}
|
||||
func_800722A4(objectIndex, 1);
|
||||
}
|
||||
|
||||
void OLakitu::func_80079860(s32 playerId) {
|
||||
s32 objectIndex;
|
||||
Player* player;
|
||||
|
||||
objectIndex = gIndexLakituList[playerId];
|
||||
player = &gPlayerOne[playerId];
|
||||
if ((func_80072354(objectIndex, 1) != 0) &&
|
||||
(((func_802ABDF4(player->collision.meshIndexZX) != 0) && (player->collision.surfaceDistance[2] <= 3.0f)) ||
|
||||
(player->unk_0CA & 1) || ((player->surfaceType == OUT_OF_BOUNDS) && !(player->effects & 8)))) {
|
||||
func_80090778(player);
|
||||
OLakitu::func_800797AC(playerId);
|
||||
}
|
||||
}
|
||||
|
||||
void OLakitu::func_8007993C(s32 objectIndex, Player* player) {
|
||||
if (player->unk_0CA & 4) {
|
||||
func_800722A4(objectIndex, 2);
|
||||
gObjectList[objectIndex].primAlpha = player->unk_0C6;
|
||||
return;
|
||||
}
|
||||
func_800722CC(objectIndex, 2);
|
||||
}
|
||||
|
||||
static const char* sLakituFishingTextures[] = { gTextureLakituFishing1, gTextureLakituFishing2, gTextureLakituFishing3,
|
||||
gTextureLakituFishing4 };
|
||||
|
||||
void OLakitu::init_obj_lakitu_red_flag_fishing(s32 objectIndex, s32 arg1) {
|
||||
|
||||
u8* tlut = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_fishing);
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(D_0D005F30);
|
||||
|
||||
OLakitu::func_800791F0(objectIndex, arg1);
|
||||
init_texture_object(objectIndex, tlut, sLakituFishingTextures, 0x38U, (u16) 0x00000048);
|
||||
gObjectList[objectIndex].vertex = vtx;
|
||||
gObjectList[objectIndex].sizeScaling = 0.15f;
|
||||
func_80086E70(objectIndex);
|
||||
clear_object_flag(objectIndex, 0x00000010);
|
||||
func_80073720(objectIndex);
|
||||
object_next_state(objectIndex);
|
||||
func_800C8F80((u8) arg1, 0x0100FA28);
|
||||
}
|
||||
|
||||
void OLakitu::func_80079A5C(s32 objectIndex, UNUSED Player* player) {
|
||||
switch (gObjectList[objectIndex].unk_0AE) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
gObjectList[objectIndex].origin_pos[2] = 0.0f;
|
||||
gObjectList[objectIndex].origin_pos[1] = 0.0f;
|
||||
gObjectList[objectIndex].origin_pos[0] = 0.0f;
|
||||
gObjectList[objectIndex].offset[2] = 0.0f;
|
||||
gObjectList[objectIndex].offset[0] = 0.0f;
|
||||
gObjectList[objectIndex].offset[1] = 80.0f;
|
||||
func_80086FD4(objectIndex);
|
||||
break;
|
||||
case 2:
|
||||
if (f32_step_down_towards(&gObjectList[objectIndex].offset[1], 5.0f, 1.0f) != 0) {
|
||||
func_80086F60(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], 100.0f, 1.0f) != 0) {
|
||||
func_80086F60(objectIndex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OLakitu::update_object_lakitu_fishing(s32 objectIndex, s32 playerId) {
|
||||
Player* player = &gPlayerOne[playerId];
|
||||
|
||||
switch (gObjectList[objectIndex].state) { /* switch 1; irregular */
|
||||
case 0: /* switch 1 */
|
||||
break;
|
||||
case 1: /* switch 1 */
|
||||
OLakitu::init_obj_lakitu_red_flag_fishing(objectIndex, playerId);
|
||||
break;
|
||||
case 2: /* switch 1 */
|
||||
set_object_flag(objectIndex, 0x00000010);
|
||||
func_800736E0(objectIndex);
|
||||
object_next_state(objectIndex);
|
||||
break;
|
||||
case 3: /* switch 1 */
|
||||
func_800730BC(objectIndex, 0, 3, 1, 2, -1);
|
||||
break;
|
||||
}
|
||||
switch (gObjectList[objectIndex].unk_0D6) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
if (func_80086FA4(objectIndex) != 0) {
|
||||
func_80073654(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
func_80090868(player);
|
||||
func_80073654(objectIndex);
|
||||
break;
|
||||
case 3:
|
||||
if (!(player->unk_0CA & 2)) {
|
||||
func_80086EAC(objectIndex, 0, 3);
|
||||
func_80073654(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (func_80086FA4(objectIndex) != 0) {
|
||||
func_80073654(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
func_800722CC(objectIndex, 1);
|
||||
func_800C9018((u8) playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28));
|
||||
func_80072428(objectIndex);
|
||||
func_80073720(objectIndex);
|
||||
break;
|
||||
}
|
||||
if (gObjectList[objectIndex].state >= 2) {
|
||||
OLakitu::func_8007993C(objectIndex, player);
|
||||
}
|
||||
OLakitu::func_80079A5C(objectIndex, player);
|
||||
}
|
||||
|
||||
void OLakitu::update_object_lakitu_fishing2(s32 objectIndex, s32 playerId) {
|
||||
Player* player = &gPlayerOne[playerId];
|
||||
|
||||
switch (gObjectList[objectIndex].state) { /* switch 1; irregular */
|
||||
case 0: /* switch 1 */
|
||||
break;
|
||||
case 1: /* switch 1 */
|
||||
OLakitu::init_obj_lakitu_red_flag_fishing(objectIndex, playerId);
|
||||
break;
|
||||
case 2: /* switch 1 */
|
||||
set_object_flag(objectIndex, 0x00000010);
|
||||
func_800736E0(objectIndex);
|
||||
player->unk_0CA |= 0x80;
|
||||
object_next_state(objectIndex);
|
||||
break;
|
||||
case 3: /* switch 1 */
|
||||
func_800730BC(objectIndex, 0, 3, 1, 2, -1);
|
||||
break;
|
||||
}
|
||||
switch (gObjectList[objectIndex].unk_0D6) {
|
||||
case 1:
|
||||
if (func_80086FA4(objectIndex) != 0) {
|
||||
func_800C9060((u8) playerId, 0x1900A055U);
|
||||
func_80073654(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
func_80090868(player);
|
||||
func_800722A4(objectIndex, 4);
|
||||
func_80073654(objectIndex);
|
||||
break;
|
||||
case 3:
|
||||
if ((player->surfaceType == ICE) && !(player->unk_0CA & 1) &&
|
||||
((f64) player->collision.surfaceDistance[2] <= 30.0)) {
|
||||
func_800722A4(objectIndex, 8);
|
||||
}
|
||||
if (!(player->unk_0CA & 2)) {
|
||||
func_80086EAC(objectIndex, 0, 3);
|
||||
func_80073654(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
func_8007375C(objectIndex, 0x0000001E);
|
||||
break;
|
||||
case 5:
|
||||
player->unk_0CA &= 0xFF7F;
|
||||
func_800722A4(objectIndex, 0x00000010);
|
||||
func_800722A4(objectIndex, 0x00000020);
|
||||
func_800722CC(objectIndex, 4);
|
||||
func_800722CC(objectIndex, 8);
|
||||
func_80073654(objectIndex);
|
||||
func_800C9060((u8) playerId, 0x1900A056U);
|
||||
break;
|
||||
case 6:
|
||||
if (func_8007375C(objectIndex, 0x000000A0) != 0) {
|
||||
func_800722CC(objectIndex, 0x00000010);
|
||||
player->unk_0CA &= 0xFFEF;
|
||||
player->unk_0CA |= 0x20;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
func_8007375C(objectIndex, 0x0000003C);
|
||||
break;
|
||||
case 8:
|
||||
func_80073720(objectIndex);
|
||||
func_80072428(objectIndex);
|
||||
player->unk_0CA &= 0xFFDF;
|
||||
func_800722CC(objectIndex, 1);
|
||||
func_800C9018((u8) playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28));
|
||||
break;
|
||||
}
|
||||
|
||||
if (gObjectList[objectIndex].state >= 2) {
|
||||
OLakitu::func_8007993C(objectIndex, player);
|
||||
}
|
||||
OLakitu::func_80079A5C(objectIndex, player);
|
||||
}
|
||||
|
||||
static const char* sLakituSecondLapTextures[] = {
|
||||
gTextureLakituSecondLap01, gTextureLakituSecondLap02, gTextureLakituSecondLap03, gTextureLakituSecondLap04,
|
||||
gTextureLakituSecondLap05, gTextureLakituSecondLap06, gTextureLakituSecondLap07, gTextureLakituSecondLap08,
|
||||
gTextureLakituSecondLap09, gTextureLakituSecondLap10, gTextureLakituSecondLap11, gTextureLakituSecondLap12,
|
||||
gTextureLakituSecondLap13, gTextureLakituSecondLap14, gTextureLakituSecondLap15, gTextureLakituSecondLap16
|
||||
};
|
||||
|
||||
void OLakitu::func_8007A060(s32 objectIndex, s32 playerIndex) {
|
||||
Object* object;
|
||||
|
||||
OLakitu::func_800791F0(objectIndex, playerIndex);
|
||||
|
||||
u8* tlut = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_second_lap);
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_also_lakitu);
|
||||
|
||||
init_texture_object(objectIndex, tlut, sLakituSecondLapTextures, 0x48U, (u16) 0x00000038);
|
||||
object = &gObjectList[objectIndex];
|
||||
object->activeTexture = *gObjectList[objectIndex].textureList;
|
||||
object->vertex = vtx;
|
||||
object->pos[2] = 5000.0f;
|
||||
object->pos[1] = 5000.0f;
|
||||
object->pos[0] = 5000.0f;
|
||||
object->sizeScaling = 0.15f;
|
||||
clear_object_flag(objectIndex, 0x00000010);
|
||||
func_80086F10(objectIndex, 5, &D_800E694C);
|
||||
object_next_state(objectIndex);
|
||||
}
|
||||
|
||||
void OLakitu::update_object_lakitu_second_lap(s32 objectIndex, s32 playerIndex) {
|
||||
switch (gObjectList[objectIndex].state) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
OLakitu::func_8007A060(objectIndex, playerIndex);
|
||||
break;
|
||||
case 2:
|
||||
set_object_flag(objectIndex, 0x00000010);
|
||||
object_next_state(objectIndex);
|
||||
break;
|
||||
case 3:
|
||||
set_and_run_timer_object(objectIndex, 0x00000014);
|
||||
break;
|
||||
case 4:
|
||||
func_80072E54(objectIndex, 0, 0x0000000F, 1, 2, 1);
|
||||
break;
|
||||
case 5:
|
||||
set_and_run_timer_object(objectIndex, 0x0000003C);
|
||||
break;
|
||||
case 6:
|
||||
func_80072F88(objectIndex, 0x0000000F, 0, 1, 2, 1);
|
||||
break;
|
||||
case 7:
|
||||
if (gObjectList[objectIndex].unk_0AE == 0) {
|
||||
func_80072428(objectIndex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* sLakituFinalLapTextures[] = {
|
||||
gTextureLakituFinalLap01, gTextureLakituFinalLap02, gTextureLakituFinalLap03, gTextureLakituFinalLap04,
|
||||
gTextureLakituFinalLap05, gTextureLakituFinalLap06, gTextureLakituFinalLap07, gTextureLakituFinalLap08,
|
||||
gTextureLakituFinalLap09, gTextureLakituFinalLap10, gTextureLakituFinalLap11, gTextureLakituFinalLap12,
|
||||
gTextureLakituFinalLap13, gTextureLakituFinalLap14, gTextureLakituFinalLap15, gTextureLakituFinalLap16,
|
||||
};
|
||||
|
||||
void OLakitu::func_8007A228(s32 objectIndex, s32 playerIndex) {
|
||||
Object* object;
|
||||
|
||||
OLakitu::func_800791F0(objectIndex, playerIndex);
|
||||
|
||||
u8* tlut = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_final_lap);
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_also_lakitu);
|
||||
|
||||
init_texture_object(objectIndex, tlut, sLakituFinalLapTextures, 0x48U, (u16) 0x00000038);
|
||||
object = &gObjectList[objectIndex];
|
||||
object->activeTexture = *gObjectList[objectIndex].textureList;
|
||||
object->vertex = vtx;
|
||||
object->pos[2] = 5000.0f;
|
||||
object->pos[1] = 5000.0f;
|
||||
object->pos[0] = 5000.0f;
|
||||
object->sizeScaling = 0.15f;
|
||||
clear_object_flag(objectIndex, 0x00000010);
|
||||
func_80086F10(objectIndex, 5, &D_800E694C);
|
||||
object_next_state(objectIndex);
|
||||
}
|
||||
|
||||
void OLakitu::update_object_lakitu_final_lap(s32 objectIndex, s32 playerIndex) {
|
||||
switch (gObjectList[objectIndex].state) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
OLakitu::func_8007A228(objectIndex, playerIndex);
|
||||
break;
|
||||
case 2:
|
||||
set_object_flag(objectIndex, 0x00000010);
|
||||
object_next_state(objectIndex);
|
||||
break;
|
||||
case 3:
|
||||
set_and_run_timer_object(objectIndex, 0x00000014);
|
||||
break;
|
||||
case 4:
|
||||
func_80072E54(objectIndex, 0, 0x0000000F, 1, 2, 1);
|
||||
break;
|
||||
case 5:
|
||||
set_and_run_timer_object(objectIndex, 0x0000003C);
|
||||
break;
|
||||
case 6:
|
||||
func_80072F88(objectIndex, 0x0000000F, 0, 1, 2, 1);
|
||||
break;
|
||||
case 7:
|
||||
if (gObjectList[objectIndex].unk_0AE == 0) {
|
||||
func_80072428(objectIndex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* sLakituReverseTextures[] = {
|
||||
gTextureLakituReverse01, gTextureLakituReverse02, gTextureLakituReverse03, gTextureLakituReverse04,
|
||||
gTextureLakituReverse05, gTextureLakituReverse06, gTextureLakituReverse07, gTextureLakituReverse08,
|
||||
gTextureLakituReverse09, gTextureLakituReverse10, gTextureLakituReverse11, gTextureLakituReverse12,
|
||||
gTextureLakituReverse13, gTextureLakituReverse14, gTextureLakituReverse15, gTextureLakituReverse16
|
||||
};
|
||||
|
||||
void OLakitu::func_8007A3F0(s32 objectIndex, s32 arg1) {
|
||||
f32 var = 5000.0f;
|
||||
OLakitu::func_800791F0(objectIndex, arg1);
|
||||
|
||||
u8* tlut = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_reverse);
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_also_lakitu);
|
||||
|
||||
init_texture_object(objectIndex, tlut, sLakituReverseTextures, 72, (u16) 56);
|
||||
gObjectList[objectIndex].activeTexture = *gObjectList[objectIndex].textureList;
|
||||
gObjectList[objectIndex].vertex = vtx;
|
||||
gObjectList[objectIndex].pos[2] = var;
|
||||
gObjectList[objectIndex].pos[1] = var;
|
||||
gObjectList[objectIndex].pos[0] = var;
|
||||
gObjectList[objectIndex].sizeScaling = 0.15f;
|
||||
clear_object_flag(objectIndex, 0x00000010);
|
||||
func_80086F10(objectIndex, 6, &D_800E69B0);
|
||||
gObjectList[objectIndex].unk_0D6 = 0;
|
||||
object_next_state(objectIndex);
|
||||
func_800C8F80((u8) arg1, 0x0100FA28);
|
||||
}
|
||||
|
||||
void OLakitu::update_object_lakitu_reverse(s32 objectIndex, s32 playerId) {
|
||||
Player* sp2C = &gPlayerOne[playerId];
|
||||
|
||||
switch (gObjectList[objectIndex].state) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
OLakitu::func_8007A3F0(objectIndex, playerId);
|
||||
break;
|
||||
case 2:
|
||||
set_object_flag(objectIndex, 0x00000010);
|
||||
gObjectList[objectIndex].unk_0D6 = 1;
|
||||
object_next_state(objectIndex);
|
||||
break;
|
||||
case 3:
|
||||
func_800730BC(objectIndex, 0, 0x0000000F, 1, 2, -1);
|
||||
break;
|
||||
case 4:
|
||||
func_80072428(objectIndex);
|
||||
break;
|
||||
}
|
||||
switch (gObjectList[objectIndex].unk_0D6) {
|
||||
case 1:
|
||||
if ((gObjectList[objectIndex].state >= 3) && (!(sp2C->effects & 0x400000))) {
|
||||
func_80086F10(objectIndex, 6, &D_800E69F4);
|
||||
gObjectList[objectIndex].unk_0D6 = 2;
|
||||
gObjectList[objectIndex].unk_04C = 0x00000050;
|
||||
func_800C9018((u8) playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
case 2:
|
||||
gObjectList[objectIndex].unk_04C--;
|
||||
if (gObjectList[objectIndex].unk_04C == 0) {
|
||||
object_next_state(objectIndex);
|
||||
gObjectList[objectIndex].unk_0D6 = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OLakitu::func_8007A66C(s32 objectIndex) {
|
||||
Player* player = &gPlayers[_playerId];
|
||||
Camera* camera = &cameras[_playerId];
|
||||
u16 rot = 0x8000 - camera->rot[1];
|
||||
|
||||
gObjectList[objectIndex].pos[0] =
|
||||
(player->pos[0] +
|
||||
(coss(rot) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) -
|
||||
(sins(rot) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2]));
|
||||
gObjectList[objectIndex].pos[1] =
|
||||
player->unk_074 + gObjectList[objectIndex].origin_pos[1] + gObjectList[objectIndex].offset[1];
|
||||
gObjectList[objectIndex].pos[2] =
|
||||
(player->pos[2] +
|
||||
(sins(rot) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) +
|
||||
(coss(rot) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2]));
|
||||
}
|
||||
|
||||
void OLakitu::func_8007A778(s32 objectIndex) {
|
||||
Player* player = &gPlayers[_playerId];
|
||||
Camera* camera = &cameras[_playerId];
|
||||
u16 rot = 0x8000 - camera->rot[1];
|
||||
|
||||
gObjectList[objectIndex].pos[0] =
|
||||
(player->pos[0] +
|
||||
(coss(rot) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) -
|
||||
(sins(rot) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2]));
|
||||
gObjectList[objectIndex].pos[1] =
|
||||
player->pos[1] + gObjectList[objectIndex].origin_pos[1] + gObjectList[objectIndex].offset[1];
|
||||
gObjectList[objectIndex].pos[2] =
|
||||
(player->pos[2] +
|
||||
(sins(rot) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) +
|
||||
(coss(rot) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2]));
|
||||
}
|
||||
|
||||
void OLakitu::func_8007A88C(s32 playerId) {
|
||||
s32 objectIndex;
|
||||
Player* player;
|
||||
|
||||
objectIndex = gIndexLakituList[playerId];
|
||||
player = &gPlayerOne[playerId];
|
||||
|
||||
if ((gObjectList[objectIndex].state == 0) && (player->effects & 0x400000)) {
|
||||
//func_800790E4(playerId);
|
||||
init_object(gIndexLakituList[playerId], 6);
|
||||
}
|
||||
}
|
||||
|
||||
void OLakitu::func_8007A910(s32 arg0) {
|
||||
if (D_801657B4 == 0) {
|
||||
OLakitu::func_8007A88C(arg0);
|
||||
}
|
||||
func_80079860(arg0);
|
||||
}
|
||||
|
||||
// animate lakitu?
|
||||
void OLakitu::func_8007AA44(s32 playerId) {
|
||||
s32 objectIndex;
|
||||
|
||||
OLakitu::func_8007A910(playerId);
|
||||
objectIndex = gIndexLakituList[playerId];
|
||||
gLakituTexturePtr = (const char**)&gLakituTextureBuffer[playerId];
|
||||
switch (gObjectList[objectIndex].unk_0D8) {
|
||||
case 1:
|
||||
OLakitu::func_80079114(objectIndex, playerId, 2);
|
||||
OLakitu::func_8007A66C(objectIndex);
|
||||
break;
|
||||
case 2:
|
||||
OLakitu::func_80079114(objectIndex, playerId, 0);
|
||||
OLakitu::func_8007A66C(objectIndex);
|
||||
break;
|
||||
case 3:
|
||||
OLakitu::func_80079114(objectIndex, playerId, 0);
|
||||
OLakitu::func_8007A778(objectIndex);
|
||||
break;
|
||||
case 4:
|
||||
OLakitu::func_80079114(objectIndex, playerId, 0);
|
||||
OLakitu::func_8007A66C(objectIndex);
|
||||
break;
|
||||
case 5:
|
||||
OLakitu::func_80079114(objectIndex, playerId, 0);
|
||||
OLakitu::func_8007A66C(objectIndex);
|
||||
break;
|
||||
case 6:
|
||||
OLakitu::func_80079114(objectIndex, playerId, 0);
|
||||
OLakitu::func_8007A66C(objectIndex);
|
||||
break;
|
||||
case 7:
|
||||
OLakitu::func_80079114(objectIndex, playerId, 0);
|
||||
OLakitu::func_8007A778(objectIndex);
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
|
||||
#include <libultraship.h>
|
||||
#include <vector>
|
||||
#include "Object.h"
|
||||
#include "World.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
#include "main.h"
|
||||
#include "vehicles.h"
|
||||
#include "waypoints.h"
|
||||
#include "common_structs.h"
|
||||
#include "objects.h"
|
||||
#include "course_offsets.h"
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that you only want 1 lakitu spawned in per human player
|
||||
* Otherwise Lakitu will animate faster than normal.
|
||||
*/
|
||||
class OLakitu : public OObject {
|
||||
public:
|
||||
enum LakituType : uint32_t {
|
||||
STARTER = 1,
|
||||
FINISH, // Checkered flag
|
||||
TOW, // Picks up an out of bounds player
|
||||
SECOND_LAP,
|
||||
FINAL_LAP,
|
||||
REVERSE,
|
||||
TOW_ICE_CUBE, // Picks up an out of bounds player in sherbet land as an ice-cube
|
||||
};
|
||||
|
||||
enum LakituTowType : uint16_t {
|
||||
NORMAL,
|
||||
ICE, // Used in sherbet land to put an ice-cube on the player
|
||||
};
|
||||
|
||||
public:
|
||||
explicit OLakitu(s32 playerId, LakituType type);
|
||||
|
||||
void Activate(LakituType type); // Triggers Lakitu into a behaviour
|
||||
|
||||
virtual void Tick() override;
|
||||
virtual void Tick60fps() override;
|
||||
virtual void Draw(s32 playerId) override;
|
||||
|
||||
void func_80078F64();
|
||||
void func_80079054(s32 playerId);
|
||||
void func_80079084(s32 playerId);
|
||||
void func_800790B4(s32 playerId);
|
||||
void func_800790E4(s32 playerId);
|
||||
void func_80079114(s32 objectIndex, s32 playerId, s32 arg2);
|
||||
void func_800791F0(s32 objectIndex, s32 playerId);
|
||||
void init_obj_lakitu_starter_and_checkered_flag(s32 objectIndex, s32 playerId);
|
||||
void update_object_lakitu_starter(s32 objectIndex, s32 arg1);
|
||||
void func_800729EC(s32 objectIndex);
|
||||
void init_obj_lakitu_checkered_flag(s32 objectIndex, s32 playerIndex);
|
||||
void update_object_lakitu_checkered_flag(s32 objectIndex, s32 playerIndex);
|
||||
void func_800797AC(s32 playerId);
|
||||
void func_80079860(s32 playerId);
|
||||
void func_8007993C(s32 objectIndex, Player* player);
|
||||
void init_obj_lakitu_red_flag_fishing(s32 objectIndex, s32 arg1);
|
||||
void func_80079A5C(s32 objectIndex, UNUSED Player* player);
|
||||
void update_object_lakitu_fishing(s32 objectIndex, s32 playerId);
|
||||
void update_object_lakitu_fishing2(s32 objectIndex, s32 playerId);
|
||||
void func_8007A060(s32 objectIndex, s32 playerIndex);
|
||||
void update_object_lakitu_second_lap(s32 objectIndex, s32 playerIndex);
|
||||
void func_8007A228(s32 objectIndex, s32 playerIndex);
|
||||
void update_object_lakitu_final_lap(s32 objectIndex, s32 playerIndex);
|
||||
void func_8007A3F0(s32 objectIndex, s32 arg1);
|
||||
void update_object_lakitu_reverse(s32 objectIndex, s32 playerId);
|
||||
void func_8007A66C(s32 objectIndex);
|
||||
void func_8007A778(s32 objectIndex);
|
||||
void func_8007A88C(s32 playerId);
|
||||
void func_8007A910(s32 arg0);
|
||||
void func_8007AA44(s32 playerId); // animate lakitu
|
||||
|
||||
private:
|
||||
LakituType _type;
|
||||
s32 _playerId;
|
||||
};
|
||||
@@ -13,8 +13,11 @@ extern "C" {
|
||||
OObject::OObject() {}
|
||||
|
||||
// Virtual functions to be overridden by derived classes
|
||||
void OObject::Tick() { }
|
||||
void OObject::Tick() { }
|
||||
void OObject::Tick60fps() {}
|
||||
void OObject::Draw(s32 cameraId) { }
|
||||
void OObject::Collision() {}
|
||||
void OObject::Expire() { }
|
||||
void OObject::Destroy() { }
|
||||
void OObject::Destroy() {
|
||||
PendingDestroy = true;
|
||||
}
|
||||
|
||||
@@ -11,14 +11,16 @@ class OObject {
|
||||
public:
|
||||
uint8_t uuid[16];
|
||||
Object o;
|
||||
bool PendingDestroy = false;
|
||||
|
||||
virtual ~OObject() = default;
|
||||
|
||||
explicit OObject();
|
||||
|
||||
virtual void Tick();
|
||||
virtual void Tick60fps();
|
||||
virtual void Draw(s32 cameraId);
|
||||
virtual void Collision();
|
||||
virtual void Expire();
|
||||
virtual void Destroy();
|
||||
virtual void Destroy(); // Mark object for deletion at the start of the next frame
|
||||
};
|
||||
|
||||
@@ -33,16 +33,19 @@ extern "C" {
|
||||
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;
|
||||
size_t OPenguin::_count = 0;
|
||||
|
||||
OPenguin::OPenguin(Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour) {
|
||||
_idx = _count;
|
||||
_type = type;
|
||||
_bhv = behaviour;
|
||||
|
||||
s32 objectIndex = indexObjectList1[i];
|
||||
if (_idx >= 32) {
|
||||
printf("MAX penguin REACHED (32), skipping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
s32 objectIndex = indexObjectList1[_idx];
|
||||
init_object(objectIndex, 0);
|
||||
|
||||
Object *object = &gObjectList[objectIndex];
|
||||
@@ -73,6 +76,7 @@ OPenguin::OPenguin(s32 i, Vec3f pos, u16 direction, PenguinType type, Behaviour
|
||||
break;
|
||||
}
|
||||
|
||||
_count++;
|
||||
}
|
||||
|
||||
void OPenguin::Tick(void) {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <libultraship.h>
|
||||
#include <vector>
|
||||
#include "engine/World.h"
|
||||
#include "engine/objects/Object.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
@@ -13,7 +15,7 @@ extern "C" {
|
||||
#include "course_offsets.h"
|
||||
}
|
||||
|
||||
class OPenguin {
|
||||
class OPenguin : public OObject {
|
||||
public:
|
||||
enum PenguinType : uint32_t {
|
||||
CHICK,
|
||||
@@ -36,10 +38,19 @@ 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);
|
||||
explicit OPenguin(Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour);
|
||||
|
||||
void Tick();
|
||||
void Draw(s32 playerId);
|
||||
~OPenguin() {
|
||||
_count--;
|
||||
}
|
||||
|
||||
static size_t GetCount() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
|
||||
virtual void Tick() override;
|
||||
virtual void Draw(s32 cameraId) override;
|
||||
private:
|
||||
void Behaviours(s32 objectIndex, s32 arg1);
|
||||
void EmperorPenguin(s32 objectIndex);
|
||||
@@ -51,7 +62,7 @@ private:
|
||||
void OtherPenguin(s32 objectIndex);
|
||||
void InitOtherPenguin(s32 objectIndex);
|
||||
|
||||
|
||||
static size_t _count;
|
||||
s32 _idx;
|
||||
PenguinType _type;
|
||||
Behaviour _bhv;
|
||||
|
||||
@@ -27,24 +27,26 @@ extern Vec3s D_800E634C[];
|
||||
|
||||
OPodium::OPodium(const FVector& pos) {
|
||||
|
||||
_pos = pos;
|
||||
|
||||
for (size_t i = 0; i < NUM_PODIUMS; i++) {
|
||||
s32 objectIndex = indexObjectList1[i];
|
||||
init_object(objectIndex, 0);
|
||||
set_obj_origin_pos(objectIndex, pos.x - 1.5, pos.y, pos.z);
|
||||
//init_object(objectIndex, 0);
|
||||
//set_obj_origin_pos(objectIndex, pos.x - 1.5, pos.y, pos.z);
|
||||
}
|
||||
}
|
||||
|
||||
void OPodium::Tick() { // func_80086604
|
||||
s32 objectIndex;
|
||||
// if ((D_8016347C != 0) && (D_802874D8.unk1D < 3)) {
|
||||
// if (D_801658C6 == 0) {
|
||||
// for (size_t i = 0; i < 3; i++) {
|
||||
// objectIndex = indexObjectList1[i];
|
||||
// init_object(objectIndex, 0);
|
||||
// }
|
||||
// D_801658C6 = 1;
|
||||
// }
|
||||
// }
|
||||
if ((D_8016347C != 0) && (D_802874D8.unk1D < 3)) {
|
||||
if (D_801658C6 == 0) {
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
objectIndex = indexObjectList1[i];
|
||||
init_object(objectIndex, 0);
|
||||
}
|
||||
D_801658C6 = 1;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i != NUM_PODIUMS; i++) {
|
||||
objectIndex = indexObjectList1[i];
|
||||
if (gObjectList[objectIndex].state != 0) {
|
||||
@@ -58,9 +60,9 @@ void OPodium::Draw(s32 cameraId) { // func_80055F48
|
||||
for (size_t i = 0; i < NUM_PODIUMS; i++) {
|
||||
Object* object;
|
||||
|
||||
object = &gObjectList[i];
|
||||
object = &gObjectList[indexObjectList1[i]];
|
||||
if (object->state >= 2) {
|
||||
func_80043220(object->pos, object->direction_angle, object->sizeScaling, object->model);
|
||||
//func_80043220(object->pos, object->direction_angle, object->sizeScaling, object->model);
|
||||
rsp_set_matrix_transformation(object->pos, object->direction_angle, object->sizeScaling);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0077A0);
|
||||
gSPDisplayList(gDisplayListHead++, object->model);
|
||||
@@ -86,7 +88,7 @@ void OPodium::func_8008629C(s32 objectIndex, s32 arg1) {
|
||||
break;
|
||||
}
|
||||
gObjectList[objectIndex].sizeScaling = 1.0f;
|
||||
//set_obj_origin_pos(objectIndex, D_800E634C[0][0] - 1.5, D_800E634C[0][1], D_800E634C[0][2]);
|
||||
set_obj_origin_pos(objectIndex, _pos.x - 1.5, _pos.y, _pos.z);
|
||||
set_obj_origin_offset(objectIndex, 0.0f, -10.0f, 0.0f);
|
||||
set_obj_direction_angle(objectIndex, 0U, 0xF8E4U, 0U);
|
||||
gObjectList[objectIndex].unk_048 = 0;
|
||||
|
||||
@@ -35,4 +35,5 @@ public:
|
||||
private:
|
||||
|
||||
s32 _idx;
|
||||
FVector _pos;
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <libultraship.h>
|
||||
#include <libultra/gbi.h>
|
||||
#include "Seagull.h"
|
||||
#include "engine/Actor.h"
|
||||
#include <vector>
|
||||
#include "World.h"
|
||||
|
||||
#include "port/Game.h"
|
||||
|
||||
@@ -29,9 +29,14 @@ extern SplineData D_800E6280;
|
||||
|
||||
SplineData* D_800E633C[] = { &D_800E6034, &D_800E60F0, &D_800E61B4, &D_800E6280 };
|
||||
|
||||
OSeagull::OSeagull(s32 i, Vec3f pos) {
|
||||
size_t objectId;
|
||||
_idx = i;
|
||||
size_t OSeagull::_count = 0;
|
||||
|
||||
OSeagull::OSeagull(Vec3f pos) {
|
||||
size_t objectIndex;
|
||||
_idx = _count;
|
||||
_pos[0] = pos[0];
|
||||
_pos[1] = pos[1];
|
||||
_pos[2] = pos[2];
|
||||
|
||||
s16 randZ;
|
||||
s16 randX;
|
||||
@@ -40,60 +45,48 @@ OSeagull::OSeagull(s32 i, Vec3f pos) {
|
||||
randY = random_int(20);
|
||||
randZ = random_int(200) + -100.0;
|
||||
|
||||
SpawnPos[0] = pos[0] + randX;
|
||||
SpawnPos[1] = pos[1] + randY;
|
||||
SpawnPos[2] = pos[2] + randZ;
|
||||
|
||||
//for (i = 0; i < NUM_SEAGULLS; i++) {
|
||||
|
||||
|
||||
//objectId = indexObjectList2[i];
|
||||
//init_object(objectId, 0);
|
||||
objectIndex = indexObjectList2[_idx];
|
||||
init_object(objectIndex, 0);
|
||||
|
||||
|
||||
//set_obj_origin_pos(objectId, pos[0], pos[1], pos[2]);
|
||||
//if (i < (NUM_SEAGULLS / 2)) {
|
||||
//gObjectList[objectId].unk_0D5 = 0;
|
||||
//} else {
|
||||
// gObjectList[objectId].unk_0D5 = 1;
|
||||
//}
|
||||
//}
|
||||
set_obj_origin_pos(objectIndex, pos[0], pos[1], pos[2]);
|
||||
if (_idx < (NUM_SEAGULLS / 2)) {
|
||||
gObjectList[objectIndex].unk_0D5 = 0;
|
||||
} else {
|
||||
gObjectList[objectIndex].unk_0D5 = 1;
|
||||
}
|
||||
|
||||
_count++;
|
||||
}
|
||||
|
||||
bool OSeagull::IsMod() { return true; }
|
||||
|
||||
void OSeagull::Tick() {
|
||||
Object* object;
|
||||
UNUSED s32* var_s4;
|
||||
s32 temp_s0;
|
||||
s32 objectIndex = indexObjectList2[_idx];
|
||||
|
||||
//for (var_s3 = 0; var_s3 < NUM_SEAGULLS; var_s3++) {
|
||||
//temp_s0 = indexObjectList2[_idx];
|
||||
|
||||
//object = &gObjectList[temp_s0];
|
||||
if (_state == 0) {
|
||||
object = &gObjectList[objectIndex];
|
||||
if (object->state == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
OSeagull::func_80082714(temp_s0, _idx);
|
||||
OSeagull::func_8008275C(temp_s0);
|
||||
if (_toggle) {
|
||||
_toggle = false;
|
||||
OSeagull::func_80082714(objectIndex, _idx);
|
||||
OSeagull::func_8008275C(objectIndex);
|
||||
if (func_80072320(objectIndex, 2) != 0) {
|
||||
func_800722CC(objectIndex, 2);
|
||||
if (D_80165A90 != 0) {
|
||||
D_80165A90 = 0;
|
||||
D_80183E40[0] = 0.0f;
|
||||
D_80183E40[1] = 0.0f;
|
||||
D_80183E40[2] = 0.0f;
|
||||
if (gGamestate != CREDITS_SEQUENCE) {
|
||||
func_800C98B8(Pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43));
|
||||
func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43));
|
||||
} else {
|
||||
//temp_s0 = indexObjectList2[1];
|
||||
//! @todo confirm this is equivallent to indexObjectList2[1];
|
||||
if (_idx == 1) {
|
||||
if (gCutsceneShotTimer <= 150) {
|
||||
//object = &gObjectList[temp_s0];
|
||||
func_800C98B8(Pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43));
|
||||
}
|
||||
objectIndex = indexObjectList2[1];
|
||||
if (gCutsceneShotTimer <= 150) {
|
||||
object = &gObjectList[objectIndex];
|
||||
func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,19 +107,32 @@ void OSeagull::Tick() {
|
||||
D_80165908 = 0;
|
||||
}
|
||||
|
||||
void OSeagull::Draw(Camera* camera) { // render_object_seagulls
|
||||
s32 var_s1;
|
||||
//for (i = 0; i < NUM_SEAGULLS; i++) {
|
||||
var_s1 = indexObjectList2[_idx];
|
||||
//! @todo: Quick hack to let seagull work in actor system. Should be cameraId not camera->playerId
|
||||
//if (func_8008A364(var_s1, camera->playerId, 0x5555U, 0x000005DC) < 0x9C401 && CVarGetInteger("gNoCulling", 0) == 0) {
|
||||
D_80165908 = 1;
|
||||
_toggle = true;
|
||||
//}
|
||||
//if (is_obj_flag_status_active(var_s1, VISIBLE) != 0) {
|
||||
func_800552BC(var_s1);
|
||||
//}
|
||||
//}
|
||||
void OSeagull::Draw(s32 cameraId) { // render_object_seagulls
|
||||
s32 objectIndex = indexObjectList2[_idx];
|
||||
|
||||
if (func_8008A364(objectIndex, cameraId, 0x5555U, 0x000005DC) < 0x9C401 && CVarGetInteger("gNoCulling", 0) == 0) {
|
||||
D_80165908 = 1;
|
||||
_toggle = true;
|
||||
}
|
||||
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
|
||||
OSeagull::func_800552BC(objectIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void OSeagull::func_800552BC(s32 objectIndex) {
|
||||
if (gObjectList[objectIndex].state >= 2) {
|
||||
rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].direction_angle,
|
||||
gObjectList[objectIndex].sizeScaling);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0077D0);
|
||||
if (gIsGamePaused == 0) {
|
||||
gObjectList[objectIndex].unk_0A2 = render_animated_model((Armature*) gObjectList[objectIndex].model,
|
||||
(Animation**) gObjectList[objectIndex].vertex, 0,
|
||||
gObjectList[objectIndex].unk_0A2);
|
||||
} else {
|
||||
render_animated_model((Armature*) gObjectList[objectIndex].model,
|
||||
(Animation**) gObjectList[objectIndex].vertex, 0, gObjectList[objectIndex].unk_0A2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OSeagull::func_8008275C(s32 objectIndex) {
|
||||
@@ -139,11 +145,11 @@ void OSeagull::func_8008275C(s32 objectIndex) {
|
||||
case 2:
|
||||
func_8008B78C(objectIndex);
|
||||
vec3f_copy(gObjectList[objectIndex].unk_01C, gObjectList[objectIndex].pos);
|
||||
func_8000D940(SpawnPos, (s16*) &gObjectList[objectIndex].unk_0C6,
|
||||
func_8000D940(gObjectList[objectIndex].origin_pos, (s16*) &gObjectList[objectIndex].unk_0C6,
|
||||
gObjectList[objectIndex].unk_034, 0.0f, 0);
|
||||
Offset[0] *= 2.0;
|
||||
Offset[1] *= 2.5;
|
||||
Offset[2] *= 2.0;
|
||||
gObjectList[objectIndex].offset[0] *= 2.0;
|
||||
gObjectList[objectIndex].offset[1] *= 2.5;
|
||||
gObjectList[objectIndex].offset[2] *= 2.0;
|
||||
object_calculate_new_pos_offset(objectIndex);
|
||||
gObjectList[objectIndex].direction_angle[1] =
|
||||
get_angle_between_two_vectors(gObjectList[objectIndex].unk_01C, gObjectList[objectIndex].pos);
|
||||
@@ -153,31 +159,26 @@ void OSeagull::func_8008275C(s32 objectIndex) {
|
||||
}
|
||||
|
||||
void OSeagull::func_8008241C(s32 objectIndex, s32 arg1) {
|
||||
UNUSED s16 stackPadding0;
|
||||
s16 randZ;
|
||||
s16 randX;
|
||||
s16 randY;
|
||||
|
||||
gObjectList[objectIndex].unk_0D8 = 1;
|
||||
gObjectList[objectIndex].model = (Gfx*) d_course_koopa_troopa_beach_unk4;
|
||||
gObjectList[objectIndex].vertex = (Vtx*) d_course_koopa_troopa_beach_unk_data5;
|
||||
gObjectList[objectIndex].sizeScaling = 0.2f;
|
||||
gObjectList[objectIndex].unk_0DD = 1;
|
||||
// if (gGamestate == CREDITS_SEQUENCE) {
|
||||
// set_obj_origin_pos(objectIndex, randX + -360.0, randY + 60.0, randZ + -1300.0);
|
||||
// } else if (gObjectList[objectIndex].unk_0D5 != 0) {
|
||||
// set_obj_origin_pos(objectIndex, (randX + 328.0) * xOrientation, randY + 20.0, randZ + 2541.0);
|
||||
// } else {
|
||||
// set_obj_origin_pos(objectIndex, (randX + -985.0) * xOrientation, randY + 15.0, randZ + 1200.0);
|
||||
// }
|
||||
randX = random_int(0x00C8) + -100.0;
|
||||
randY = random_int(0x0014);
|
||||
randZ = random_int(0x00C8) + -100.0;
|
||||
|
||||
set_obj_origin_pos(objectIndex, (randX + _pos[0]) * xOrientation, randY + _pos[1], randZ + _pos[2]);
|
||||
set_obj_direction_angle(objectIndex, 0U, 0U, 0U);
|
||||
gObjectList[objectIndex].unk_034 = 1.0f;
|
||||
func_80086EF0(objectIndex);
|
||||
//gObjectList[objectIndex].spline = D_800E633C[arg1 % 4];
|
||||
spline = D_800E633C[arg1 % 4];
|
||||
//set_object_flag(objectIndex, 0x800);
|
||||
//object_next_state(objectIndex);
|
||||
_status |= 0x800;
|
||||
_timer = 0;
|
||||
_status &= ~0x2000;
|
||||
_state++;
|
||||
gObjectList[objectIndex].spline = D_800E633C[arg1 % 4];
|
||||
set_object_flag(objectIndex, 0x00000800);
|
||||
object_next_state(objectIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
#include <libultraship.h>
|
||||
#include <vector>
|
||||
#include "engine/Actor.h"
|
||||
#include "Object.h"
|
||||
|
||||
#include "engine/World.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
@@ -11,33 +13,34 @@ extern "C" {
|
||||
#include "waypoints.h"
|
||||
#include "common_structs.h"
|
||||
#include "objects.h"
|
||||
#include "course_offsets.h"
|
||||
#include "some_data.h"
|
||||
#include "camera.h"
|
||||
}
|
||||
|
||||
|
||||
class OSeagull : public AActor {
|
||||
//! @todo unk_0D5 needs to be a struct variable probably. What does it do? Behaviour?
|
||||
class OSeagull : public OObject {
|
||||
public:
|
||||
enum Behaviour : uint16_t {
|
||||
};
|
||||
explicit OSeagull(Vec3f pos);
|
||||
|
||||
public:
|
||||
explicit OSeagull(s32 i, Vec3f pos);
|
||||
~OSeagull() {
|
||||
_count--;
|
||||
}
|
||||
|
||||
static size_t GetCount() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
virtual void Tick() override;
|
||||
virtual void Draw(Camera*) override;
|
||||
virtual void Draw(s32 cameraId) override;
|
||||
|
||||
void func_800552BC(s32 objectIndex);
|
||||
|
||||
void func_8008275C(s32 objectIndex);
|
||||
void func_8008241C(s32 objectIndex, s32 arg1);
|
||||
void func_80082714(s32 objectIndex, s32 arg1);
|
||||
virtual bool IsMod() override;
|
||||
Vec3f Offset;
|
||||
Vec3f SpawnPos;
|
||||
private:
|
||||
Vec3f _pos;
|
||||
static size_t _count;
|
||||
s32 _idx;
|
||||
s32 _state;
|
||||
s32 _timer;
|
||||
s32 _status;
|
||||
bool _toggle;
|
||||
|
||||
SplineData *spline;
|
||||
|
||||
@@ -17,8 +17,8 @@ static const char* sSnowmanHeadList[] = { d_course_frappe_snowland_snowman_head
|
||||
size_t OSnowman::_count = 0;
|
||||
|
||||
OSnowman::OSnowman(const FVector& pos) {
|
||||
_pos = pos;
|
||||
_idx = _count;
|
||||
_pos = pos;
|
||||
|
||||
s32 objectId = indexObjectList2[_idx];
|
||||
init_object(objectId, 0);
|
||||
@@ -106,7 +106,7 @@ void OSnowman::func_800836F0(Vec3f pos) {
|
||||
if (objectIndex == NULL_OBJECT_ID) {
|
||||
break;
|
||||
}
|
||||
func_80083538(objectIndex, pos, i, D_8018D3BC);
|
||||
OSnowman::func_80083538(objectIndex, pos, i, D_8018D3BC);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,4 +297,47 @@ void OSnowman::func_80083B0C(s32 objectIndex) {
|
||||
gObjectList[objectIndex].boundingBoxSize = 2;
|
||||
gObjectList[objectIndex].unk_034 = 1.5f;
|
||||
set_object_flag(objectIndex, 0x04000210);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OSnowman::func_80083538(s32 objectIndex, Vec3f arg1, s32 arg2, s32 arg3) {
|
||||
Object* object;
|
||||
|
||||
init_object(objectIndex, 0);
|
||||
object = &gObjectList[objectIndex];
|
||||
object->activeTexture = (const char*)d_course_frappe_snowland_snow;
|
||||
object->textureList = (const char**)d_course_frappe_snowland_snow;
|
||||
object->activeTLUT = d_course_frappe_snowland_snow_tlut;
|
||||
object->tlutList = (u8*)d_course_frappe_snowland_snow_tlut;
|
||||
object->sizeScaling = random_int(0x0064U);
|
||||
object->sizeScaling = (object->sizeScaling * 0.001) + 0.05;
|
||||
object->velocity[1] = random_int(0x0014U);
|
||||
object->velocity[1] = (object->velocity[1] * 0.5) + 2.6;
|
||||
object->unk_034 = random_int(0x000AU);
|
||||
object->unk_034 = (object->unk_034 * 0.1) + 4.5;
|
||||
object->direction_angle[1] = (arg2 << 0x10) / arg3;
|
||||
object->origin_pos[0] = arg1[0];
|
||||
object->origin_pos[1] = arg1[1];
|
||||
object->origin_pos[2] = arg1[2];
|
||||
object->primAlpha = random_int(0x4000U) + 0x1000;
|
||||
}
|
||||
|
||||
void OSnowman::func_8008379C(s32 objectIndex) {
|
||||
switch (gObjectList[objectIndex].state) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
if (func_80087E08(objectIndex, gObjectList[objectIndex].velocity[1], 0.74f,
|
||||
gObjectList[objectIndex].unk_034, gObjectList[objectIndex].direction_angle[1],
|
||||
0x00000064) != 0) {
|
||||
object_next_state(objectIndex);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
func_80086F60(objectIndex);
|
||||
func_80072428(objectIndex);
|
||||
break;
|
||||
}
|
||||
object_calculate_new_pos_offset(objectIndex);
|
||||
gObjectList[objectIndex].orientation[2] += gObjectList[objectIndex].primAlpha;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
void func_80083BE4(s32);
|
||||
void func_800836F0(Vec3f);
|
||||
bool func_80073D0C(s32 objectIndex, s16* arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6);
|
||||
void func_80083538(s32 objectIndex, Vec3f arg1, s32 arg2, s32 arg3);
|
||||
void func_8008379C(s32 objectIndex);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@@ -44,16 +44,19 @@ f32 D_800E594C[][2] = {
|
||||
|
||||
s16 D_800E597C[] = { 0x0000, 0x0000, 0x4000, 0x8000, 0x8000, 0xc000 };
|
||||
|
||||
OThwomp::OThwomp(s32 i, s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize) {
|
||||
if (i >= 32) {
|
||||
printf("MAX THWOMPS REACHED (32), skipping\n");
|
||||
return;
|
||||
}
|
||||
_idx = i;
|
||||
size_t OThwomp::_count = 0;
|
||||
|
||||
OThwomp::OThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize) {
|
||||
_idx = _count;
|
||||
_faceDirection = direction;
|
||||
_boundingBoxSize = boundingBoxSize;
|
||||
State = (States)behaviour;
|
||||
s32 objectId = indexObjectList1[i];
|
||||
|
||||
if (_idx >= 32) {
|
||||
printf("MAX THWOMPS REACHED (32), skipping\n");
|
||||
return;
|
||||
}
|
||||
s32 objectId = indexObjectList1[_idx];
|
||||
init_object(objectId, 0);
|
||||
gObjectList[objectId].origin_pos[0] = x * xOrientation;
|
||||
gObjectList[objectId].origin_pos[2] = z;
|
||||
@@ -66,9 +69,11 @@ OThwomp::OThwomp(s32 i, s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s
|
||||
}
|
||||
|
||||
gObjectList[objectId].sizeScaling = scale;
|
||||
|
||||
_count++;
|
||||
}
|
||||
|
||||
void OThwomp::Tick() { // func_80081210
|
||||
void OThwomp::Tick60fps() { // func_80081210
|
||||
Player* player;
|
||||
s32 objectIndex;
|
||||
s32 var_s2_3;
|
||||
@@ -80,6 +85,13 @@ void OThwomp::Tick() { // func_80081210
|
||||
|
||||
OThwomp::func_8007F8D8();
|
||||
|
||||
// Tick lights only one time. This gets applied to every thwomp.
|
||||
// Running this more than once per frame will result in the lights moving at a high rate of speed.
|
||||
if (_idx == 0) {
|
||||
D_80165834[0] += 0x100;
|
||||
D_80165834[1] += 0x200;
|
||||
}
|
||||
|
||||
objectIndex = indexObjectList1[_idx];
|
||||
if (gObjectList[objectIndex].state != 0) {
|
||||
switch (State) {
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
#include <libultraship.h>
|
||||
#include <vector>
|
||||
|
||||
#include "engine/World.h"
|
||||
#include "engine/objects/Object.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
#include "main.h"
|
||||
@@ -27,7 +30,7 @@ extern "C" {
|
||||
* @arg primAlpha unknown
|
||||
* @arg boundingBoxSize optional. The size of the bounding box for the thwomp. Default value is 12
|
||||
*/
|
||||
class OThwomp {
|
||||
class OThwomp : public OObject {
|
||||
private:
|
||||
enum States : uint16_t {
|
||||
DISABLED,
|
||||
@@ -42,12 +45,20 @@ private:
|
||||
public:
|
||||
States State = States::DISABLED;
|
||||
|
||||
explicit OThwomp(s32 i, s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize);
|
||||
explicit OThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize = 7);
|
||||
|
||||
void Tick();
|
||||
~OThwomp() {
|
||||
_count--;
|
||||
}
|
||||
|
||||
static size_t GetCount() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
virtual void Tick60fps() override;
|
||||
virtual void Draw(s32 cameraId) override;
|
||||
void SetVisibility(s32 objectIndex);
|
||||
void func_80080B28(s32 objectIndex, s32 playerId);
|
||||
void Draw(s32 playerId);
|
||||
void DrawModel(s32);
|
||||
void TranslateThwompLights();
|
||||
void ThwompLights(s32 objectIndex);
|
||||
@@ -100,6 +111,7 @@ public:
|
||||
|
||||
void func_8007E63C(s32 objectIndex);
|
||||
private:
|
||||
static size_t _count;
|
||||
s32 _idx;
|
||||
s16 _faceDirection;
|
||||
//! @todo Write this better. This effects the squish size and the bounding box size.
|
||||
|
||||
@@ -24,7 +24,18 @@ OTrophy::OTrophy(const FVector& pos, TrophyType trophy, Behaviour bhv) {
|
||||
_spawnPos.y += 16.0f; // Adjust the height so the trophy sits on the surface when positioned to 0,0,0
|
||||
_bhv = bhv;
|
||||
|
||||
init_object(objectIndex, 0);
|
||||
if (bhv == OTrophy::Behaviour::PODIUM_CEREMONY) {
|
||||
_toggleVisibility = &D_801658CE;
|
||||
} else {
|
||||
int8_t toggle = 1;
|
||||
_toggleVisibility = &toggle;
|
||||
_isMod = true;
|
||||
}
|
||||
|
||||
// This allows spawning for mods
|
||||
if (*_toggleVisibility == true) {
|
||||
init_object(objectIndex, 0);
|
||||
}
|
||||
|
||||
switch (trophy) {
|
||||
case TrophyType::GOLD:
|
||||
@@ -47,13 +58,6 @@ OTrophy::OTrophy(const FVector& pos, TrophyType trophy, Behaviour bhv) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (OTrophy::Behaviour::PODIUM_CEREMONY) {
|
||||
_toggleVisibility = &D_801658CE;
|
||||
} else {
|
||||
int8_t toggle = 1;
|
||||
_toggleVisibility = &toggle;
|
||||
}
|
||||
|
||||
// Set defaults for modded behaviours
|
||||
if (_bhv != OTrophy::Behaviour::PODIUM_CEREMONY) {
|
||||
gObjectList[objectIndex].sizeScaling = 0.025f;
|
||||
@@ -81,15 +85,15 @@ void OTrophy::Tick() { // func_80086D80
|
||||
s32 objectIndex = indexObjectList1[3];
|
||||
s32 var_s0;
|
||||
|
||||
// if ((D_801658CE != 0) && (D_801658DC == 0)) {
|
||||
// temp_s2 = indexObjectList1[3];
|
||||
// init_object(temp_s2, 0);
|
||||
// D_801658DC = 1;
|
||||
// }
|
||||
// Fallback for podium ceremony where the trophy is not spawned until it is needed
|
||||
if ((*_toggleVisibility == true) && (D_801658DC == 0) && (_isMod == false)) {
|
||||
init_object(objectIndex, 0);
|
||||
D_801658DC = 1;
|
||||
}
|
||||
|
||||
switch(_bhv) {
|
||||
case OTrophy::Behaviour::PODIUM_CEREMONY:
|
||||
if (gObjectList[objectIndex].state != 0) {
|
||||
if (gObjectList[objectIndex].state != 0 && (*_toggleVisibility == true)) {
|
||||
OTrophy::func_80086C14(objectIndex);
|
||||
OTrophy::func_80086940(objectIndex);
|
||||
if (D_801658F4 != 0) {
|
||||
@@ -197,8 +201,7 @@ void OTrophy::Draw(s32 cameraId) {
|
||||
Mat4 someMatrix1;
|
||||
Mat4 someMatrix2;
|
||||
Object* object;
|
||||
|
||||
if (_toggleVisibility) {
|
||||
if (*_toggleVisibility == true) {
|
||||
object = &gObjectList[listIndex];
|
||||
if (object->state >= 2) {
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]),
|
||||
@@ -332,3 +335,60 @@ void OTrophy::func_80086C6C(s32 objectIndex) {
|
||||
}
|
||||
func_800773D8(sp24, (s32) D_801658F4);
|
||||
}
|
||||
|
||||
void OTrophy::func_800773D8(f32* arg0, s32 arg1) {
|
||||
s32 objectIndex = add_unused_obj_index(gObjectParticle3, &gNextFreeObjectParticle3, gObjectParticle3_SIZE);
|
||||
if (objectIndex != NULL_OBJECT_ID) {
|
||||
func_80077138(objectIndex, arg0, arg1);
|
||||
}
|
||||
}
|
||||
|
||||
void OTrophy::func_80077138(s32 objectIndex, Vec3f arg1, s32 arg2) {
|
||||
s8 temp_v0_3;
|
||||
Vec3s sp30;
|
||||
|
||||
init_object(objectIndex, arg2);
|
||||
gObjectList[objectIndex].unk_0D5 = 0x0C;
|
||||
gObjectList[objectIndex].sizeScaling = 0.05f;
|
||||
set_obj_origin_pos(objectIndex, arg1[0], arg1[1], arg1[2]);
|
||||
set_obj_orientation(objectIndex, 0U, 0U, 0U);
|
||||
set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f);
|
||||
switch (arg2) {
|
||||
case 0:
|
||||
gObjectList[objectIndex].velocity[1] = -1.0f;
|
||||
gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x004BU) * 0.01) + 0.25);
|
||||
gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA;
|
||||
func_8008751C(objectIndex);
|
||||
gObjectList[objectIndex].unk_084[5] = 0x001E;
|
||||
break;
|
||||
case 1:
|
||||
gObjectList[objectIndex].velocity[1] = 1.5f;
|
||||
gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x0064U) * 0.01) + 0.5);
|
||||
gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA;
|
||||
func_8008751C(objectIndex);
|
||||
gObjectList[objectIndex].unk_084[5] = 0x0032;
|
||||
break;
|
||||
}
|
||||
temp_v0_3 = random_int(0x000CU);
|
||||
if (temp_v0_3 < 9) {
|
||||
func_8005C674(temp_v0_3, &sp30[2], &sp30[1], sp30);
|
||||
gObjectList[objectIndex].unk_048 = 0;
|
||||
gObjectList[objectIndex].unk_084[0] = sp30[2];
|
||||
gObjectList[objectIndex].unk_084[1] = sp30[1];
|
||||
gObjectList[objectIndex].unk_084[2] = sp30[0];
|
||||
} else {
|
||||
temp_v0_3 = random_int(3U);
|
||||
func_8005C6B4(temp_v0_3, &sp30[2], &sp30[1], sp30);
|
||||
gObjectList[objectIndex].unk_084[0] = sp30[2];
|
||||
gObjectList[objectIndex].unk_084[1] = sp30[1];
|
||||
gObjectList[objectIndex].unk_084[2] = sp30[0];
|
||||
gObjectList[objectIndex].unk_084[4] = temp_v0_3;
|
||||
gObjectList[objectIndex].unk_048 = 1;
|
||||
}
|
||||
gObjectList[objectIndex].primAlpha = 0x00FF;
|
||||
gObjectList[objectIndex].unk_084[3] = random_int(0x0800U) + 0x400;
|
||||
if ((gObjectList[objectIndex].direction_angle[1] < 0x3000) ||
|
||||
(gObjectList[objectIndex].direction_angle[1] >= 0xB001)) {
|
||||
gObjectList[objectIndex].unk_084[3] = -gObjectList[objectIndex].unk_084[3];
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
void func_80086940(s32 objectIndex);
|
||||
void func_80086C14(s32 objectIndex);
|
||||
void func_80086C6C(s32 objectIndex);
|
||||
void func_800773D8(f32* arg0, s32 arg1);
|
||||
void func_80077138(s32 objectIndex, Vec3f arg1, s32 arg2);
|
||||
|
||||
private:
|
||||
|
||||
@@ -52,4 +54,5 @@ private:
|
||||
Behaviour _bhv;
|
||||
int8_t *_toggleVisibility;
|
||||
Vec3f _oldPos;
|
||||
bool _isMod = false;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user