mirror of
https://github.com/CraftyBoss/SuperMarioOdysseyOnline.git
synced 2024-11-28 06:03:05 +00:00
197 lines
No EOL
5.3 KiB
C++
197 lines
No EOL
5.3 KiB
C++
#include "helpers.hpp"
|
|
#include "al/LiveActor/LiveActor.h"
|
|
#include "logger.hpp"
|
|
#include "sead/math/seadMathCalcCommon.h"
|
|
#include "sead/math/seadQuat.h"
|
|
#include "sead/math/seadVector.h"
|
|
#include "sead/time/seadTickSpan.h"
|
|
#include "sead/time/seadTickTime.h"
|
|
|
|
bool isPartOf(const char* w1, const char* w2) {
|
|
|
|
int i=0;
|
|
int j=0;
|
|
|
|
if(strlen(w1) <= 0) {
|
|
return false;
|
|
}
|
|
|
|
while(w1[i]!='\0'){
|
|
if(w1[i] == w2[j])
|
|
{
|
|
int init = i;
|
|
while (w1[i] == w2[j] && w2[j]!='\0')
|
|
{
|
|
j++;
|
|
i++;
|
|
}
|
|
if(w2[j]=='\0'){
|
|
return true;
|
|
}
|
|
j=0;
|
|
}
|
|
i++;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int indexOf(char *w1, char c1) {
|
|
|
|
for (int i = 0; i < strlen(w1); i++)
|
|
{
|
|
if(w1[i] == c1) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
sead::Vector3f QuatToEuler(sead::Quatf *quat) {
|
|
|
|
f32 x = quat->z;
|
|
f32 y = quat->y;
|
|
f32 z = quat->x;
|
|
f32 w = quat->w;
|
|
|
|
f32 t0 = 2.0 * (w * x + y * z);
|
|
f32 t1 = 1.0 - 2.0 * (x * x + y * y);
|
|
f32 roll = atan2f(t0, t1);
|
|
|
|
f32 t2 = 2.0 * (w * y - z * x);
|
|
t2 = t2 > 1.0 ? 1.0 : t2;
|
|
t2 = t2 < -1.0 ? -1.0 : t2;
|
|
f32 pitch = asinf(t2);
|
|
|
|
f32 t3 = 2.0 * (w * z + x * y);
|
|
f32 t4 = 1.0 - 2.0 * (y * y + z * z);
|
|
f32 yaw = atan2f(t3, t4);
|
|
|
|
return sead::Vector3f(yaw, pitch, roll);
|
|
}
|
|
|
|
void logVector(const char *vectorName, sead::Vector3f vector) {
|
|
Logger::log("%s: \nX: %f\nY: %f\nZ: %f\n", vectorName, vector.x, vector.y, vector.z);
|
|
}
|
|
|
|
void logQuat(const char *quatName, sead::Quatf &quat) {
|
|
Logger::log("%s: \nX: %f\nY: %f\nZ: %f\nW: %f\n", quatName, quat.x, quat.y, quat.z, quat.w);
|
|
}
|
|
|
|
float vecMagnitude(sead::Vector3f const &input) {
|
|
return (input.x * input.x + input.y * input.y + input.z * input.z);
|
|
}
|
|
|
|
float quatAngle(sead::Quatf const &q1, sead::Quatf &q2) {
|
|
float dot = (q1.x * q2.x) + (q1.y * q2.y) + (q1.z * q2.z) + (q1.w * q2.w);
|
|
float dotAngle = sead::Mathf::min(abs(dot), 1.0f);
|
|
|
|
return dotAngle > 1.0f - 0.000001f ? 0.0f : DEG(sead::Mathf::acos(dotAngle) * 2.0f);
|
|
}
|
|
|
|
bool isInCostumeList(const char *costumeName) {
|
|
for (size_t i = 0; i < sizeof(costumeNames)/sizeof(costumeNames[0]); i++)
|
|
{
|
|
if(al::isEqualString(costumeNames[i], costumeName)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const char *tryGetPuppetCapName(PuppetInfo *info) {
|
|
if(info->costumeHead && isInCostumeList(info->costumeHead)) {
|
|
return info->costumeHead;
|
|
}else {
|
|
return "Mario";
|
|
}
|
|
}
|
|
|
|
const char *tryGetPuppetBodyName(PuppetInfo *info) {
|
|
if(info->costumeBody && isInCostumeList(info->costumeBody)) {
|
|
return info->costumeBody;
|
|
}else {
|
|
return "Mario";
|
|
}
|
|
}
|
|
|
|
const char *tryConvertName(const char *className) {
|
|
for (size_t i = 0; i < ACNT(classHackNames); i++)
|
|
{
|
|
if(al::isEqualString(classHackNames[i].className, className)) {
|
|
return classHackNames[i].hackName;
|
|
}
|
|
}
|
|
return className;
|
|
}
|
|
|
|
// Unity Classes
|
|
|
|
float VisualUtils::SmoothMove(Transform moveTransform, Transform targetTransform, float timeDelta, float closingSpeed, float maxAngularSpeed)
|
|
{
|
|
|
|
// Position
|
|
|
|
sead::Vector3f posDiff = *targetTransform.position - *moveTransform.position;
|
|
|
|
float posDiffMag = posDiff.dot(posDiff);
|
|
|
|
if (posDiffMag > 0) {
|
|
|
|
float diffSpeed = sead::Mathf::max(k_MinSmoothSpeed, posDiffMag / k_TargetCatchupTime);
|
|
|
|
closingSpeed = sead::Mathf::max(closingSpeed, diffSpeed);
|
|
|
|
float maxMove = timeDelta * closingSpeed;
|
|
float moveDist = sead::Mathf::min(maxMove, posDiffMag);
|
|
posDiff *= (moveDist / posDiffMag);
|
|
|
|
moveTransform.position->x += posDiff.x;
|
|
moveTransform.position->y += posDiff.y;
|
|
moveTransform.position->z += posDiff.z;
|
|
|
|
if( moveDist == posDiffMag )
|
|
{
|
|
//we capped the move, meaning we exactly reached our target transform. Time to reset our velocity.
|
|
closingSpeed = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
closingSpeed = 0;
|
|
}
|
|
|
|
// Rotation
|
|
|
|
if (moveTransform.rotation) {
|
|
float angleDiff = quatAngle(*targetTransform.rotation, *moveTransform.rotation);
|
|
|
|
// if rotation is over 150 degrees, snap to new rotation instead of interpolating to it
|
|
if (angleDiff > 0)
|
|
{
|
|
float maxAngleMove = timeDelta * maxAngularSpeed;
|
|
float angleMove = sead::Mathf::min(maxAngleMove, angleDiff);
|
|
float t = angleMove / angleDiff;
|
|
sead::QuatCalcCommon<float>::slerpTo(*moveTransform.rotation, *moveTransform.rotation, *targetTransform.rotation, t);
|
|
}
|
|
}
|
|
|
|
return closingSpeed;
|
|
}
|
|
|
|
void killMainPlayer(al::LiveActor* actor) {
|
|
PlayerActorHakoniwa *mainPlayer = (PlayerActorHakoniwa*)al::getPlayerActor(actor, 0);
|
|
|
|
GameDataFunction::killPlayer(GameDataHolderAccessor(actor));
|
|
mainPlayer->startDemoPuppetable();
|
|
al::setVelocityZero(mainPlayer);
|
|
mainPlayer->mPlayerAnimator->endSubAnim();
|
|
mainPlayer->mPlayerAnimator->startAnimDead();
|
|
}
|
|
|
|
void killMainPlayer(PlayerActorHakoniwa* mainPlayer) {
|
|
GameDataFunction::killPlayer(GameDataHolderAccessor(mainPlayer));
|
|
mainPlayer->startDemoPuppetable();
|
|
al::setVelocityZero(mainPlayer);
|
|
mainPlayer->mPlayerAnimator->endSubAnim();
|
|
mainPlayer->mPlayerAnimator->startAnimDead();
|
|
} |