#include "CustomObject.h"
#include "port/Rando/Rando.h"
#include "port/ShipUtils.h"
#include "port/Save/Types.h"
#include <map>
#include "save.h"
#define BUNDLE_STATE_DEFAULT 1
typedef struct {
s32 index;
s16 flags;
s16 unk6;
f32 position[3];
f32 velocity[3];
f32 yaw;
f32 yaw_speed;
f32 elapsed_time;
u8 unk2C;
u8 unk2D;
u8 unk2E;
u8 state;
} Bundle;
typedef struct {
f32 velocity_x;
f32 velocity_y;
f32 velocity_z;
f32 randomVelocity_x;
f32 randomVelocity_y;
f32 randomVelocity_z;
f32 yaw;
int32_t flags;
} BundlePhysics;
extern "C" {
extern SaveData gameFile_saveData[4];
extern u8 sItemscoreNoteScores[0xE];
void ml_vec3f_copy(f32 dst[3], f32 src[3]);
extern f32 gBundle_randomVelocity;
extern f32 gBundle_yaw;
f32 randf2(f32 min, f32 max);
f32 randf(void);
void ml_vec3f_yaw_rotate_copy(f32 dst[3], f32 src[3], f32 yaw);
}
static f32 baseSpeed = 400.0f;
std::map<RandoCheckId, BundlePhysics> customActorPhysicsMap = {
{ RC_UNKNOWN, { 0, 0, 0, 0, 0, 0, 0, 0 } },
{ RC_BGS_JIGGY_TANKTUP, { 0, 100.0f, 300.0f, 0, 0, 0, 0, 0x1 } },
{ RC_GL_JIGGY_WITCH_SWITCH_TREASURE_TROVE_COVE, { 0, 100.0f, 2800.0f, 0, 0, 0, 0, 0x1 } },
{ RC_MM_JIGGY_CHIMPY, { 0, 800.0f, 0, 0, 10.0f, 0, 0, 0x1 } },
{ RC_MM_JIGGY_CONGA, { 350.0f, 275.0f, 0, 0, 0, 0, 0, 0x1 } },
{ RC_MM_JIGGY_JUJU, { 0, 300.0f, 0, 0, 10.0f, 0, 0, 0x1 } },
{ RC_MM_NOTE_HUT_BUNDLE_1, { 125.0f, 725.0f, 125.0f, 0, 0, 0, 0, 0x1 } },
};
BundlePhysics jinjoJiggySpawnPhysics = { 0, 300.0f, 0, 0, 10.0f, 0, 0, 0x1 };
BundlePhysics GetPhysicsByCheckId(RandoCheckId randoCheckId) {
for (auto& [check, physics] : customActorPhysicsMap) {
if (check == randoCheckId) {
return physics;
}
}
return customActorPhysicsMap.at(RC_UNKNOWN);
}
void UpdateSaveDataNoteScores() {
u64* noteData = (u64*)&gameFile_saveData[selectedFileNum].data[NOTE_OFFSET];
u64 currentSaveData;
u64 packed_notes = 0;
int8_t level_id = (int8_t)LEVEL_A_MAD_MONSTER_MANSION;
for (int i = 0; i <= LEVEL_A_MAD_MONSTER_MANSION; i++) {
packed_notes <<= 7;
packed_notes |= (sItemscoreNoteScores[level_id] & 0x7F);
level_id--;
if (level_id == LEVEL_6_LAIR) {
level_id--;
}
}
currentSaveData = *noteData;
currentSaveData &= ~((u64)0x7FFFFFFFFFFFFFFF);
currentSaveData |= (packed_notes & 0x7FFFFFFFFFFFFFFF);
*noteData = currentSaveData;
}
void ApplyBundleActorPhysics(Actor* actor, int32_t bundle_id, BundleInfo* bundle_info, f32 bundleYaw) {
actor->is_bundle = true;
Bundle* bundle = (Bundle*)&actor->unkBC;
bundle->index = bundle_id;
bundle->state = BUNDLE_STATE_DEFAULT;
bundle->unk6 = 1;
ml_vec3f_copy(bundle->position, actor->position);
ml_vec3f_copy(actor->position, bundle->position);
if (gBundle_randomVelocity != 1.0f) {
bundle->velocity[0] = bundle_info->velocity_x * gBundle_randomVelocity;
bundle->velocity[1] = bundle_info->velocity_y + randf2(0.0f, bundle_info->randomVelocity_y);
bundle->velocity[2] = bundle_info->velocity_z * gBundle_randomVelocity;
gBundle_randomVelocity = 1.0f;
} else {
bundle->velocity[0] = bundle_info->velocity_x + randf2(0.0f, bundle_info->randomVelocity_x);
bundle->velocity[1] = bundle_info->velocity_y + randf2(0.0f, bundle_info->randomVelocity_y);
bundle->velocity[2] = bundle_info->velocity_z + randf2(0.0f, bundle_info->randomVelocity_z);
}
ml_vec3f_yaw_rotate_copy(bundle->velocity, bundle->velocity, bundleYaw);
bundle->yaw_speed = (baseSpeed *= -1.0f);
float targetYaw = (bundle_info->flags & 0x20) ? bundle_info->yaw : randf2(0.0f, 360.0f);
actor->yaw = bundle->yaw = targetYaw;
bundle->elapsed_time = 0.0f;
bundle->unk2C = 0;
bundle->unk2D = 1;
bundle->flags = bundle_info->flags;
bundle->unk2E = (bundle_info->flags & 0x1) ? (randf() > 0.5f) : 0;
if (bundle_info->flags & 0x200) {
actor->unk5C = bundle->position[1];
}
}
void ApplyCustomActorPhysics(RandoCheckId randoCheckId, Actor* actor, bool isJinjoJiggy) {
if (actor == NULL) {
return;
}
float bundleYaw = gBundle_yaw;
BundlePhysics physicsData;
if ((randoCheckId >= RC_MM_NOTE_HUT_BUNDLE_1 && randoCheckId <= RC_MM_NOTE_HUT_BUNDLE_5) ||
randoCheckId == RC_MM_JINJO_GREEN || randoCheckId == RC_MM_JIGGY_HUTS) {
physicsData = GetPhysicsByCheckId(RC_MM_NOTE_HUT_BUNDLE_1);
} else {
physicsData = isJinjoJiggy ? jinjoJiggySpawnPhysics : GetPhysicsByCheckId(randoCheckId);
}
actor->is_bundle = true;
Bundle* bundle = (Bundle*)&actor->unkBC;
bundle->index = 0;
bundle->state = BUNDLE_STATE_DEFAULT;
bundle->unk6 = 1;
ml_vec3f_copy(bundle->position, actor->position);
ml_vec3f_copy(actor->position, bundle->position);
bundle->velocity[0] = physicsData.velocity_x + randf2(0.0f, physicsData.randomVelocity_x);
bundle->velocity[1] = physicsData.velocity_y + randf2(0.0f, physicsData.randomVelocity_y);
bundle->velocity[2] = physicsData.velocity_z + randf2(0.0f, physicsData.randomVelocity_z);
ml_vec3f_yaw_rotate_copy(bundle->velocity, bundle->velocity, bundleYaw);
bundle->yaw_speed = (baseSpeed *= -1.0f);
float targetYaw = (physicsData.flags & 0x20) ? physicsData.yaw : randf2(0.0f, 360.0f);
actor->yaw = bundle->yaw = targetYaw;
bundle->elapsed_time = 0.0f;
bundle->unk2C = 0;
bundle->unk2D = 1;
bundle->flags = physicsData.flags;
bundle->unk2E = (physicsData.flags & 0x1) ? (randf() > 0.5f) : 0;
}