2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-07-12 16:05:52 +00:00

Implement MetroidPrimeStage1 loader

This commit is contained in:
Jack Andersen 2017-08-19 19:23:22 -10:00
parent 3fa80babf6
commit 96b17ac73d
38 changed files with 1042 additions and 436 deletions

View File

@ -130,7 +130,7 @@ struct ITweakPlayer : ITweak
virtual float GetFreeLookDampenFactor() const=0; // x14c virtual float GetFreeLookDampenFactor() const=0; // x14c
virtual float GetLeftLogicalThreshold() const=0; virtual float GetLeftLogicalThreshold() const=0;
virtual float GetRightLogicalThreshold() const=0; virtual float GetRightLogicalThreshold() const=0;
virtual float GetOrbitZBasedDistance(int type) const=0; virtual float GetOrbitMinDistance(int type) const=0;
virtual float GetOrbitNormalDistance(int type) const=0; virtual float GetOrbitNormalDistance(int type) const=0;
virtual float GetOrbitMaxDistance(int type) const=0; virtual float GetOrbitMaxDistance(int type) const=0;
virtual float GetFrozenTimeout() const=0; virtual float GetFrozenTimeout() const=0;

View File

@ -12,7 +12,7 @@ namespace DNAMP1
struct MetroidPrimeStage1 : IScriptObject struct MetroidPrimeStage1 : IScriptObject
{ {
DECL_YAML DECL_YAML
Value<atUint32> unknown1; Value<atUint32> version;
String<-1> name; String<-1> name;
Value<atVec3f> location; Value<atVec3f> location;
Value<atVec3f> orientation; Value<atVec3f> orientation;
@ -46,7 +46,7 @@ struct MetroidPrimeStage1 : IScriptObject
Value<float> unknown12; Value<float> unknown12;
Value<float> unknown13; Value<float> unknown13;
Value<float> unknown14; Value<float> unknown14;
} primeStruct1_1, primeStruct1_2, primeStruct1_3, primeStruct1_4; } primeStruct1[4];
Value<atUint32> unknown10; Value<atUint32> unknown10;
Value<atUint32> unknown11; Value<atUint32> unknown11;
@ -54,63 +54,84 @@ struct MetroidPrimeStage1 : IScriptObject
struct MassivePrimeStruct : BigYAML struct MassivePrimeStruct : BigYAML
{ {
DECL_YAML DECL_YAML
Value<atUint32> unknown1; Value<atUint32> propertyCount;
PatternedInfo patternedInfo; PatternedInfo patternedInfo;
ActorParameters actorParameters; ActorParameters actorParameters;
Value<atUint32> unknown2; Value<atUint32> unknown2;
struct PrimeStruct2 : BigYAML struct CameraShakeData : BigYAML
{ {
DECL_YAML DECL_YAML
Value<bool> unknown1; Value<bool> unknown1;
Value<float> unknown2; Value<float> duration;
Value<float> unknown3; Value<float> unknown3;
struct PrimeStruct3 : BigYAML struct CameraShakerComponent : BigYAML
{ {
DECL_YAML DECL_YAML
Value<bool> unknown1; Value<bool> unknown1;
Value<float> unknown2; struct CameraShakePoint : BigYAML
Value<float> unknown3; {
Value<float> unknown4; DECL_YAML
Value<float> unknown5; Value<float> unknown2;
Value<float> unknown6; Value<float> unknown3;
Value<float> unknown7; Value<float> duration;
Value<float> unknown8; Value<float> magnitude;
Value<float> unknown9; } shakePoints[2];
} primeStruct3_1, primeStruct3_2, primeStruct3_3; } shakerComponents[3];
} primeStruct2_1, primeStruct2_2, primeStruct2_3; } shakeDatas[3];
struct PrimeStruct2B : BigYAML
{
DECL_YAML
Value<atUint32> propertyCount;
UniqueID32 particle1;
UniqueID32 particle2;
UniqueID32 particle3;
DamageInfo damageInfo1;
Value<float> unknown5;
Value<float> unknown6;
UniqueID32 texture1;
Value<atUint32> unknown7;
Value<atUint32> unknown8;
void nameIDs(PAKRouter<PAKBridge>& pakRouter, const std::string& name) const
{
if (particle1)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
ent->name = name + "_part1";
}
if (particle2)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
ent->name = name + "_part2";
}
if (particle3)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3);
ent->name = name + "_part3";
}
if (texture1)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1);
ent->name = name + "_tex1";
}
}
void depIDs(std::vector<hecl::ProjectPath>& pathsOut) const
{
g_curSpec->flattenDependencies(particle1, pathsOut);
g_curSpec->flattenDependencies(particle2, pathsOut);
g_curSpec->flattenDependencies(particle3, pathsOut);
g_curSpec->flattenDependencies(texture1, pathsOut);
}
} primeStruct2b;
Value<atUint32> unknown4;
UniqueID32 particle1;
UniqueID32 particle2;
UniqueID32 particle3;
DamageInfo damageInfo1;
Value<float> unknown5;
Value<float> unknown6;
UniqueID32 texture1;
Value<atUint32> unknown7;
Value<atUint32> unknown8;
UniqueID32 particle4; UniqueID32 particle4;
struct PrimeStruct4 : BigYAML struct PrimeStruct4 : BigYAML
{ {
DECL_YAML DECL_YAML
Value<atUint32> unknown1; BeamInfo beamInfo;
Value<atUint32> unknown2;
UniqueID32 particle1;
UniqueID32 particle2;
UniqueID32 texture1;
UniqueID32 texture2;
Value<float> unknown3;
Value<float> unknown4;
Value<float> unknown5;
Value<float> unknown6;
Value<float> unknown7;
Value<float> unknown8;
Value<float> unknown9;
Value<float> unknown10;
Value<float> unknown11;
Value<atVec4f> unknown12; // CColor
Value<atVec4f> unknown13; // CColor
UniqueID32 wpsc; UniqueID32 wpsc;
DamageInfo damageInfo1; DamageInfo damageInfo1;
struct PrimeStruct5 : BigYAML struct PrimeStruct5 : BigYAML
@ -157,26 +178,7 @@ struct MetroidPrimeStage1 : IScriptObject
void nameIDs(PAKRouter<PAKBridge>& pakRouter, const std::string& name) const void nameIDs(PAKRouter<PAKBridge>& pakRouter, const std::string& name) const
{ {
if (particle1) beamInfo.nameIDs(pakRouter, name + "_beamInfo");
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
ent->name = name + "_part1";
}
if (particle2)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
ent->name = name + "_part2";
}
if (texture1)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1);
ent->name = name + "_tex1";
}
if (texture2)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture2);
ent->name = name + "_tex2";
}
if (wpsc) if (wpsc)
{ {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc);
@ -187,34 +189,57 @@ struct MetroidPrimeStage1 : IScriptObject
void depIDs(std::vector<hecl::ProjectPath>& pathsOut) const void depIDs(std::vector<hecl::ProjectPath>& pathsOut) const
{ {
g_curSpec->flattenDependencies(particle1, pathsOut); beamInfo.depIDs(pathsOut);
g_curSpec->flattenDependencies(particle2, pathsOut);
g_curSpec->flattenDependencies(texture1, pathsOut);
g_curSpec->flattenDependencies(texture2, pathsOut);
g_curSpec->flattenDependencies(wpsc, pathsOut); g_curSpec->flattenDependencies(wpsc, pathsOut);
primeStruct5.depIDs(pathsOut); primeStruct5.depIDs(pathsOut);
} }
} primeStruct4_1, primeStruct4_2, primeStruct4_3, primeStruct4_4; } primeStruct4s[4];
UniqueID32 wpsc1; UniqueID32 wpsc1;
DamageInfo damageInfo2; DamageInfo damageInfo2;
PrimeStruct2 primeStruct2_4; CameraShakeData primeStruct2_4;
UniqueID32 wpsc2; UniqueID32 wpsc2;
DamageInfo damageInfo3; DamageInfo damageInfo3;
PrimeStruct2 primeStruct2_5; CameraShakeData primeStruct2_5;
Value<atUint32> unknown3;
UniqueID32 particle5; struct PrimeStruct5B : BigYAML
DamageInfo damageInfo4; {
Value<float> unknown9; DECL_YAML
Value<float> unknown10; Value<atUint32> propertyCount;
Value<float> unknown11; UniqueID32 particle5;
UniqueID32 texture2; DamageInfo damageInfo4;
Value<bool> unknown12; Value<float> unknown9;
Value<bool> unknown13; Value<float> unknown10;
Value<bool> unknown14; Value<float> unknown11;
Value<bool> unknown15; UniqueID32 texture2;
Value<bool> unknown12;
Value<bool> unknown13;
Value<bool> unknown14;
Value<bool> unknown15;
void nameIDs(PAKRouter<PAKBridge>& pakRouter, const std::string& name) const
{
if (particle5)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle5);
ent->name = name + "_part5";
}
if (texture2)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture2);
ent->name = name + "_tex2";
}
}
void depIDs(std::vector<hecl::ProjectPath>& pathsOut) const
{
g_curSpec->flattenDependencies(particle5, pathsOut);
g_curSpec->flattenDependencies(texture2, pathsOut);
}
} primeStruct5b;
DamageInfo damageInfo5; DamageInfo damageInfo5;
PrimeStruct2 primeStruct2_6; CameraShakeData primeStruct2_6;
UniqueID32 particle6; UniqueID32 particle6;
UniqueID32 swhc; UniqueID32 swhc;
UniqueID32 particle7; UniqueID32 particle7;
@ -225,38 +250,19 @@ struct MetroidPrimeStage1 : IScriptObject
DECL_YAML DECL_YAML
Value<atUint32> propertyCount; Value<atUint32> propertyCount;
DamageVulnerability damageVulnerability; DamageVulnerability damageVulnerability;
Value<atVec4f> unknown1; DNAColor unknown1;
Value<atUint32> unknown2; Value<atUint32> unknown2;
Value<atUint32> unknown3; Value<atUint32> unknown3;
} primeStruct6_1, primeStruct6_2, primeStruct6_3, primeStruct6_4; } primeStruct6s[4];
void nameIDs(PAKRouter<PAKBridge>& pakRouter, const std::string& name) const void nameIDs(PAKRouter<PAKBridge>& pakRouter, const std::string& name) const
{ {
if (particle1) primeStruct2b.nameIDs(pakRouter, name + "_prime2b");
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
ent->name = name + "_part1";
}
if (particle2)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
ent->name = name + "_part2";
}
if (particle3)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3);
ent->name = name + "_part3";
}
if (particle4) if (particle4)
{ {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4);
ent->name = name + "_part4"; ent->name = name + "_part4";
} }
if (particle5)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle5);
ent->name = name + "_part5";
}
if (particle6) if (particle6)
{ {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle6); PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle6);
@ -277,16 +283,6 @@ struct MetroidPrimeStage1 : IScriptObject
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(swhc); PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(swhc);
ent->name = name + "_swhc"; ent->name = name + "_swhc";
} }
if (texture1)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1);
ent->name = name + "_tex1";
}
if (texture2)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture2);
ent->name = name + "_tex2";
}
if (wpsc1) if (wpsc1)
{ {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1);
@ -299,33 +295,30 @@ struct MetroidPrimeStage1 : IScriptObject
} }
patternedInfo.nameIDs(pakRouter, name + "_patterned"); patternedInfo.nameIDs(pakRouter, name + "_patterned");
actorParameters.nameIDs(pakRouter, name + "_actp"); actorParameters.nameIDs(pakRouter, name + "_actp");
primeStruct4_1.nameIDs(pakRouter, name + "_prime41"); primeStruct4s[0].nameIDs(pakRouter, name + "_prime41");
primeStruct4_2.nameIDs(pakRouter, name + "_prime42"); primeStruct4s[1].nameIDs(pakRouter, name + "_prime42");
primeStruct4_3.nameIDs(pakRouter, name + "_prime43"); primeStruct4s[2].nameIDs(pakRouter, name + "_prime43");
primeStruct4_4.nameIDs(pakRouter, name + "_prime44"); primeStruct4s[3].nameIDs(pakRouter, name + "_prime44");
primeStruct5b.nameIDs(pakRouter, name + "_prime5");
} }
void depIDs(std::vector<hecl::ProjectPath>& pathsOut) const void depIDs(std::vector<hecl::ProjectPath>& pathsOut) const
{ {
g_curSpec->flattenDependencies(particle1, pathsOut); primeStruct2b.depIDs(pathsOut);
g_curSpec->flattenDependencies(particle2, pathsOut);
g_curSpec->flattenDependencies(particle3, pathsOut);
g_curSpec->flattenDependencies(particle4, pathsOut); g_curSpec->flattenDependencies(particle4, pathsOut);
g_curSpec->flattenDependencies(particle5, pathsOut);
g_curSpec->flattenDependencies(particle6, pathsOut); g_curSpec->flattenDependencies(particle6, pathsOut);
g_curSpec->flattenDependencies(particle7, pathsOut); g_curSpec->flattenDependencies(particle7, pathsOut);
g_curSpec->flattenDependencies(particle8, pathsOut); g_curSpec->flattenDependencies(particle8, pathsOut);
g_curSpec->flattenDependencies(swhc, pathsOut); g_curSpec->flattenDependencies(swhc, pathsOut);
g_curSpec->flattenDependencies(texture1, pathsOut);
g_curSpec->flattenDependencies(texture2, pathsOut);
g_curSpec->flattenDependencies(wpsc1, pathsOut); g_curSpec->flattenDependencies(wpsc1, pathsOut);
g_curSpec->flattenDependencies(wpsc2, pathsOut); g_curSpec->flattenDependencies(wpsc2, pathsOut);
patternedInfo.depIDs(pathsOut); patternedInfo.depIDs(pathsOut);
actorParameters.depIDs(pathsOut); actorParameters.depIDs(pathsOut);
primeStruct4_1.depIDs(pathsOut); primeStruct4s[0].depIDs(pathsOut);
primeStruct4_2.depIDs(pathsOut); primeStruct4s[1].depIDs(pathsOut);
primeStruct4_3.depIDs(pathsOut); primeStruct4s[2].depIDs(pathsOut);
primeStruct4_4.depIDs(pathsOut); primeStruct4s[3].depIDs(pathsOut);
primeStruct5b.depIDs(pathsOut);
} }
void scanIDs(std::vector<Scan>& scansOut) const void scanIDs(std::vector<Scan>& scansOut) const

View File

@ -455,6 +455,61 @@ struct ActorParameters : BigYAML
scannableParameters.scanIDs(scansOut); scannableParameters.scanIDs(scansOut);
} }
}; };
struct BeamInfo : BigYAML
{
DECL_YAML
Value<atUint32> propertyCount;
Value<atUint32> unknown1;
UniqueID32 particle1;
UniqueID32 particle2;
UniqueID32 texture1;
UniqueID32 texture2;
Value<float> unknown2;
Value<float> unknown3;
Value<float> unknown4;
Value<float> unknown5;
Value<float> unknown6;
Value<float> unknown7;
Value<float> unknown8;
Value<float> unknown9;
Value<float> unknown10;
DNAColor unknown11;
DNAColor unknown12;
void nameIDs(PAKRouter<PAKBridge>& pakRouter, const std::string& name) const
{
if (particle1)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
ent->name = name + "_part1";
}
if (particle2)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
ent->name = name + "_part2";
}
if (texture1)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1);
ent->name = name + "_tex1";
}
if (texture2)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture2);
ent->name = name + "_tex2";
}
}
void depIDs(std::vector<hecl::ProjectPath>& pathsOut) const
{
g_curSpec->flattenDependencies(particle1, pathsOut);
g_curSpec->flattenDependencies(particle2, pathsOut);
g_curSpec->flattenDependencies(texture1, pathsOut);
g_curSpec->flattenDependencies(texture2, pathsOut);
}
};
} }
} }

View File

@ -17,59 +17,7 @@ struct ScriptBeam : IScriptObject
Value<atVec3f> orientation; Value<atVec3f> orientation;
Value<bool> unknown1; Value<bool> unknown1;
UniqueID32 wpsc; UniqueID32 wpsc;
struct ScriptBeamParameters : BigYAML BeamInfo beamInfo;
{
DECL_YAML
Value<atUint32> propertyCount;
Value<atUint32> unknown1;
UniqueID32 particle1;
UniqueID32 particle2;
UniqueID32 texture1;
UniqueID32 texture2;
Value<float> unknown2;
Value<float> unknown3;
Value<float> unknown4;
Value<float> unknown5;
Value<float> unknown6;
Value<float> unknown7;
Value<float> unknown8;
Value<float> unknown9;
Value<float> unknown10;
Value<atVec4f> unknown11; // CColor
Value<atVec4f> unknown12; // CColor
void nameIDs(PAKRouter<PAKBridge>& pakRouter, const std::string& name) const
{
if (particle1)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
ent->name = name + "_part1";
}
if (particle2)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
ent->name = name + "_part2";
}
if (texture1)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1);
ent->name = name + "_tex1";
}
if (texture2)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture2);
ent->name = name + "_tex2";
}
}
void depIDs(std::vector<hecl::ProjectPath>& pathsOut) const
{
g_curSpec->flattenDependencies(particle1, pathsOut);
g_curSpec->flattenDependencies(particle2, pathsOut);
g_curSpec->flattenDependencies(texture1, pathsOut);
g_curSpec->flattenDependencies(texture2, pathsOut);
}
} beamParametrs;
DamageInfo damageInfo; DamageInfo damageInfo;
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const void nameIDs(PAKRouter<PAKBridge>& pakRouter) const
@ -79,13 +27,13 @@ struct ScriptBeam : IScriptObject
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc);
ent->name = name + "_wpsc"; ent->name = name + "_wpsc";
} }
beamParametrs.nameIDs(pakRouter, name + "_beamp"); beamInfo.nameIDs(pakRouter, name + "_beamInfo");
} }
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{ {
g_curSpec->flattenDependencies(wpsc, pathsOut); g_curSpec->flattenDependencies(wpsc, pathsOut);
beamParametrs.depIDs(pathsOut); beamInfo.depIDs(pathsOut);
} }
}; };
} }

View File

@ -251,20 +251,20 @@ void CTweakPlayer::read(athena::io::IStreamReader& __dna_reader)
x264_aimAssistHorizontalAngle = __dna_reader.readFloatBig(); x264_aimAssistHorizontalAngle = __dna_reader.readFloatBig();
/* x268_aimAssistVerticalAngle */ /* x268_aimAssistVerticalAngle */
x268_aimAssistVerticalAngle = __dna_reader.readFloatBig(); x268_aimAssistVerticalAngle = __dna_reader.readFloatBig();
/* x158_orbitZBasedDistance[0] */ /* x158_orbitMinDistance[0] */
x158_orbitZBasedDistance[0] = __dna_reader.readFloatBig(); x158_orbitMinDistance[0] = __dna_reader.readFloatBig();
/* x164_orbitNormalDistance[0] */ /* x164_orbitNormalDistance[0] */
x164_orbitNormalDistance[0] = __dna_reader.readFloatBig(); x164_orbitNormalDistance[0] = __dna_reader.readFloatBig();
/* x170_orbitMaxDistance[0] */ /* x170_orbitMaxDistance[0] */
x170_orbitMaxDistance[0] = __dna_reader.readFloatBig(); x170_orbitMaxDistance[0] = __dna_reader.readFloatBig();
/* x158_orbitZBasedDistance[1] */ /* x158_orbitMinDistance[1] */
x158_orbitZBasedDistance[1] = __dna_reader.readFloatBig(); x158_orbitMinDistance[1] = __dna_reader.readFloatBig();
/* x164_orbitNormalDistance[1] */ /* x164_orbitNormalDistance[1] */
x164_orbitNormalDistance[1] = __dna_reader.readFloatBig(); x164_orbitNormalDistance[1] = __dna_reader.readFloatBig();
/* x170_orbitMaxDistance[1] */ /* x170_orbitMaxDistance[1] */
x170_orbitMaxDistance[1] = __dna_reader.readFloatBig(); x170_orbitMaxDistance[1] = __dna_reader.readFloatBig();
/* x158_orbitZBasedDistance[2] */ /* x158_orbitMinDistance[2] */
x158_orbitZBasedDistance[2] = __dna_reader.readFloatBig(); x158_orbitMinDistance[2] = __dna_reader.readFloatBig();
/* x164_orbitNormalDistance[2] */ /* x164_orbitNormalDistance[2] */
x164_orbitNormalDistance[2] = __dna_reader.readFloatBig(); x164_orbitNormalDistance[2] = __dna_reader.readFloatBig();
/* x170_orbitMaxDistance[2] */ /* x170_orbitMaxDistance[2] */
@ -691,20 +691,20 @@ void CTweakPlayer::write(athena::io::IStreamWriter& __dna_writer) const
__dna_writer.writeFloatBig(x264_aimAssistHorizontalAngle); __dna_writer.writeFloatBig(x264_aimAssistHorizontalAngle);
/* x268_aimAssistVerticalAngle */ /* x268_aimAssistVerticalAngle */
__dna_writer.writeFloatBig(x268_aimAssistVerticalAngle); __dna_writer.writeFloatBig(x268_aimAssistVerticalAngle);
/* x158_orbitZBasedDistance[0] */ /* x158_orbitMinDistance[0] */
__dna_writer.writeFloatBig(x158_orbitZBasedDistance[0]); __dna_writer.writeFloatBig(x158_orbitMinDistance[0]);
/* x164_orbitNormalDistance[0] */ /* x164_orbitNormalDistance[0] */
__dna_writer.writeFloatBig(x164_orbitNormalDistance[0]); __dna_writer.writeFloatBig(x164_orbitNormalDistance[0]);
/* x170_orbitMaxDistance[0] */ /* x170_orbitMaxDistance[0] */
__dna_writer.writeFloatBig(x170_orbitMaxDistance[0]); __dna_writer.writeFloatBig(x170_orbitMaxDistance[0]);
/* x158_orbitZBasedDistance[1] */ /* x158_orbitMinDistance[1] */
__dna_writer.writeFloatBig(x158_orbitZBasedDistance[1]); __dna_writer.writeFloatBig(x158_orbitMinDistance[1]);
/* x164_orbitNormalDistance[1] */ /* x164_orbitNormalDistance[1] */
__dna_writer.writeFloatBig(x164_orbitNormalDistance[1]); __dna_writer.writeFloatBig(x164_orbitNormalDistance[1]);
/* x170_orbitMaxDistance[1] */ /* x170_orbitMaxDistance[1] */
__dna_writer.writeFloatBig(x170_orbitMaxDistance[1]); __dna_writer.writeFloatBig(x170_orbitMaxDistance[1]);
/* x158_orbitZBasedDistance[2] */ /* x158_orbitMinDistance[2] */
__dna_writer.writeFloatBig(x158_orbitZBasedDistance[2]); __dna_writer.writeFloatBig(x158_orbitMinDistance[2]);
/* x164_orbitNormalDistance[2] */ /* x164_orbitNormalDistance[2] */
__dna_writer.writeFloatBig(x164_orbitNormalDistance[2]); __dna_writer.writeFloatBig(x164_orbitNormalDistance[2]);
/* x170_orbitMaxDistance[2] */ /* x170_orbitMaxDistance[2] */
@ -1161,16 +1161,16 @@ void CTweakPlayer::read(athena::io::YAMLDocReader& __dna_docin)
x264_aimAssistHorizontalAngle = __dna_docin.readFloat("x264_aimAssistHorizontalAngle"); x264_aimAssistHorizontalAngle = __dna_docin.readFloat("x264_aimAssistHorizontalAngle");
/* x268_aimAssistVerticalAngle */ /* x268_aimAssistVerticalAngle */
x268_aimAssistVerticalAngle = __dna_docin.readFloat("x268_aimAssistVerticalAngle"); x268_aimAssistVerticalAngle = __dna_docin.readFloat("x268_aimAssistVerticalAngle");
/* x158_orbitZBasedDistance */ /* x158_orbitMinDistance */
size_t __x158_Count; size_t __x158_Count;
if (auto v = __dna_docin.enterSubVector("x158_orbitZBasedDistance", __x158_Count)) if (auto v = __dna_docin.enterSubVector("x158_orbitMinDistance", __x158_Count))
{ {
/* x158_orbitZBasedDistance[0] */ /* x158_orbitMinDistance[0] */
x158_orbitZBasedDistance[0] = __dna_docin.readFloat("x158_orbitZBasedDistance"); x158_orbitMinDistance[0] = __dna_docin.readFloat("x158_orbitMinDistance");
/* x158_orbitZBasedDistance[1] */ /* x158_orbitMinDistance[1] */
x158_orbitZBasedDistance[1] = __dna_docin.readFloat("x158_orbitZBasedDistance"); x158_orbitMinDistance[1] = __dna_docin.readFloat("x158_orbitMinDistance");
/* x158_orbitZBasedDistance[2] */ /* x158_orbitMinDistance[2] */
x158_orbitZBasedDistance[2] = __dna_docin.readFloat("x158_orbitZBasedDistance"); x158_orbitMinDistance[2] = __dna_docin.readFloat("x158_orbitMinDistance");
} }
/* x164_orbitNormalDistance */ /* x164_orbitNormalDistance */
size_t __x164_Count; size_t __x164_Count;
@ -1670,15 +1670,15 @@ void CTweakPlayer::write(athena::io::YAMLDocWriter& __dna_docout) const
__dna_docout.writeFloat("x264_aimAssistHorizontalAngle", x264_aimAssistHorizontalAngle); __dna_docout.writeFloat("x264_aimAssistHorizontalAngle", x264_aimAssistHorizontalAngle);
/* x268_aimAssistVerticalAngle */ /* x268_aimAssistVerticalAngle */
__dna_docout.writeFloat("x268_aimAssistVerticalAngle", x268_aimAssistVerticalAngle); __dna_docout.writeFloat("x268_aimAssistVerticalAngle", x268_aimAssistVerticalAngle);
/* x158_orbitZBasedDistance */ /* x158_orbitMinDistance */
if (auto v = __dna_docout.enterSubVector("x158_orbitZBasedDistance")) if (auto v = __dna_docout.enterSubVector("x158_orbitMinDistance"))
{ {
/* x158_orbitZBasedDistance[0] */ /* x158_orbitMinDistance[0] */
__dna_docout.writeFloat("x158_orbitZBasedDistance", x158_orbitZBasedDistance[0]); __dna_docout.writeFloat("x158_orbitMinDistance", x158_orbitMinDistance[0]);
/* x158_orbitZBasedDistance[1] */ /* x158_orbitMinDistance[1] */
__dna_docout.writeFloat("x158_orbitZBasedDistance", x158_orbitZBasedDistance[1]); __dna_docout.writeFloat("x158_orbitMinDistance", x158_orbitMinDistance[1]);
/* x158_orbitZBasedDistance[2] */ /* x158_orbitMinDistance[2] */
__dna_docout.writeFloat("x158_orbitZBasedDistance", x158_orbitZBasedDistance[2]); __dna_docout.writeFloat("x158_orbitMinDistance", x158_orbitMinDistance[2]);
} }
/* x164_orbitNormalDistance */ /* x164_orbitNormalDistance */
if (auto v = __dna_docout.enterSubVector("x164_orbitNormalDistance")) if (auto v = __dna_docout.enterSubVector("x164_orbitNormalDistance"))

View File

@ -54,7 +54,7 @@ struct CTweakPlayer : ITweakPlayer
Value<float> x14c_freeLookDampenFactor; Value<float> x14c_freeLookDampenFactor;
Value<float> x150_leftDiv; Value<float> x150_leftDiv;
Value<float> x154_rightDiv; Value<float> x154_rightDiv;
Value<float> x158_orbitZBasedDistance[3]; Value<float> x158_orbitMinDistance[3];
Value<float> x164_orbitNormalDistance[3]; Value<float> x164_orbitNormalDistance[3];
Value<float> x170_orbitMaxDistance[3]; Value<float> x170_orbitMaxDistance[3];
Value<float> x17c_; Value<float> x17c_;
@ -296,7 +296,7 @@ struct CTweakPlayer : ITweakPlayer
float GetFreeLookDampenFactor() const { return x14c_freeLookDampenFactor; } float GetFreeLookDampenFactor() const { return x14c_freeLookDampenFactor; }
float GetLeftLogicalThreshold() const { return x150_leftDiv; } float GetLeftLogicalThreshold() const { return x150_leftDiv; }
float GetRightLogicalThreshold() const { return x154_rightDiv; } float GetRightLogicalThreshold() const { return x154_rightDiv; }
float GetOrbitZBasedDistance(int type) const { return x158_orbitZBasedDistance[type]; } float GetOrbitMinDistance(int type) const { return x158_orbitMinDistance[type]; }
float GetOrbitNormalDistance(int type) const { return x164_orbitNormalDistance[type]; } float GetOrbitNormalDistance(int type) const { return x164_orbitNormalDistance[type]; }
float GetOrbitMaxDistance(int type) const { return x170_orbitMaxDistance[type]; } float GetOrbitMaxDistance(int type) const { return x170_orbitMaxDistance[type]; }
float GetFrozenTimeout() const { return x2f8_frozenTimeout; } float GetFrozenTimeout() const { return x2f8_frozenTimeout; }

View File

@ -1272,7 +1272,7 @@ void CStateManager::ApplyKnockBack(CActor& actor, const CDamageInfo& info, const
{ {
if (vuln.GetVulnerability(info.GetWeaponMode(), false) == EVulnerability::Reflect) if (vuln.GetVulnerability(info.GetWeaponMode(), false) == EVulnerability::Reflect)
return; return;
CHealthInfo* hInfo = actor.HealthInfo(); CHealthInfo* hInfo = actor.HealthInfo(*this);
if (!hInfo) if (!hInfo)
return; return;
@ -1391,23 +1391,24 @@ void CStateManager::ApplyDamageToWorld(TUniqueId damager, const CActor& actor, c
} }
} }
void CStateManager::ProcessRadiusDamage(const CActor& a1, CActor& a2, TUniqueId senderId, const CDamageInfo& info, void CStateManager::ProcessRadiusDamage(const CActor& damager, CActor& damagee,
TUniqueId senderId, const CDamageInfo& info,
const CMaterialFilter& filter) const CMaterialFilter& filter)
{ {
zeus::CAABox aabb(a1.GetTranslation() - info.GetRadius(), a1.GetTranslation() + info.GetRadius()); zeus::CAABox aabb(damager.GetTranslation() - info.GetRadius(), damager.GetTranslation() + info.GetRadius());
rstl::reserved_vector<TUniqueId, 1024> nearList; rstl::reserved_vector<TUniqueId, 1024> nearList;
BuildNearList(nearList, aabb, filter, nullptr); BuildNearList(nearList, aabb, filter, nullptr);
for (TUniqueId id : nearList) for (TUniqueId id : nearList)
{ {
CEntity* ent = ObjectById(id); CEntity* ent = ObjectById(id);
if (!ent || ent->GetUniqueId() == a1.GetUniqueId() || if (!ent || ent->GetUniqueId() == damager.GetUniqueId() ||
ent->GetUniqueId() == senderId || ent->GetUniqueId() == senderId ||
ent->GetUniqueId() == a2.GetUniqueId()) ent->GetUniqueId() == damagee.GetUniqueId())
continue; continue;
TestBombHittingWater(a1, a1.GetTranslation(), static_cast<CActor&>(*ent)); TestBombHittingWater(damager, damager.GetTranslation(), static_cast<CActor&>(*ent));
if (TestRayDamage(a1.GetTranslation(), static_cast<CActor&>(*ent), nearList)) if (TestRayDamage(damager.GetTranslation(), static_cast<CActor&>(*ent), nearList))
ApplyRadiusDamage(a1, a1.GetTranslation(), static_cast<CActor&>(*ent), info); ApplyRadiusDamage(damager, damager.GetTranslation(), static_cast<CActor&>(*ent), info);
} }
} }
@ -1431,7 +1432,7 @@ void CStateManager::ApplyRadiusDamage(const CActor& a1, const zeus::CVector3f& p
delta.normalize(); delta.normalize();
bool alive = false; bool alive = false;
if (CHealthInfo* hInfo = a2.HealthInfo()) if (CHealthInfo* hInfo = a2.HealthInfo(*this))
if (hInfo->GetHP() > 0.f) if (hInfo->GetHP() > 0.f)
alive = true; alive = true;
@ -1451,8 +1452,8 @@ void CStateManager::ApplyRadiusDamage(const CActor& a1, const zeus::CVector3f& p
} }
else else
{ {
a2.SendScriptMsgs(EScriptObjectState::UNKS6, *this, EScriptObjectMessage::None); a2.SendScriptMsgs(EScriptObjectState::InvulnDamage, *this, EScriptObjectMessage::None);
SendScriptMsg(&a2, a1.GetUniqueId(), EScriptObjectMessage::InternalMessage20); SendScriptMsg(&a2, a1.GetUniqueId(), EScriptObjectMessage::InvulnDamage);
} }
if (alive && info.GetKnockBackPower() > 0.f) if (alive && info.GetKnockBackPower() > 0.f)
@ -1464,7 +1465,7 @@ void CStateManager::ApplyRadiusDamage(const CActor& a1, const zeus::CVector3f& p
bool CStateManager::TestRayDamage(const zeus::CVector3f& pos, const CActor& damagee, bool CStateManager::TestRayDamage(const zeus::CVector3f& pos, const CActor& damagee,
const rstl::reserved_vector<TUniqueId, 1024>& nearList) const rstl::reserved_vector<TUniqueId, 1024>& nearList)
{ {
const CHealthInfo* hInfo = const_cast<CActor&>(damagee).HealthInfo(); const CHealthInfo* hInfo = const_cast<CActor&>(damagee).HealthInfo(*this);
if (!hInfo) if (!hInfo)
return false; return false;
@ -1616,7 +1617,7 @@ void CStateManager::TestBombHittingWater(const CActor& damager, const zeus::CVec
bool CStateManager::ApplyLocalDamage(const zeus::CVector3f& vec1, const zeus::CVector3f& vec2, CActor& damagee, float dam, bool CStateManager::ApplyLocalDamage(const zeus::CVector3f& vec1, const zeus::CVector3f& vec2, CActor& damagee, float dam,
const CWeaponMode& weapMode) const CWeaponMode& weapMode)
{ {
CHealthInfo* hInfo = damagee.HealthInfo(); CHealthInfo* hInfo = damagee.HealthInfo(*this);
if (!hInfo || dam < 0.f) if (!hInfo || dam < 0.f)
return false; return false;
@ -1674,62 +1675,63 @@ bool CStateManager::ApplyLocalDamage(const zeus::CVector3f& vec1, const zeus::CV
return significant; return significant;
} }
bool CStateManager::ApplyDamage(TUniqueId id0, TUniqueId id1, TUniqueId id2, bool CStateManager::ApplyDamage(TUniqueId damagerId, TUniqueId damageeId, TUniqueId radiusSender,
const CDamageInfo& info, const CMaterialFilter& filter, const CDamageInfo& info, const CMaterialFilter& filter,
const zeus::CVector3f& vec) const zeus::CVector3f& knockbackVec)
{ {
CEntity* ent0 = ObjectById(id0); CEntity* ent0 = ObjectById(damagerId);
CEntity* ent1 = ObjectById(id1); CEntity* ent1 = ObjectById(damageeId);
TCastToPtr<CActor> act0 = ent0; TCastToPtr<CActor> damager = ent0;
TCastToPtr<CActor> act1 = ent1; TCastToPtr<CActor> damagee = ent1;
bool isPlayer = TCastToPtr<CPlayer>(ent1); bool isPlayer = TCastToPtr<CPlayer>(ent1);
if (act1) if (damagee)
{ {
if (CHealthInfo* hInfo = act1->HealthInfo()) if (CHealthInfo* hInfo = damagee->HealthInfo(*this))
{ {
zeus::CVector3f position; zeus::CVector3f position;
zeus::CVector3f direction = zeus::CVector3f::skRight; zeus::CVector3f direction = zeus::CVector3f::skRight;
bool alive = hInfo->GetHP() > 0.f; bool alive = hInfo->GetHP() > 0.f;
if (act0) if (damager)
{ {
position = act0->GetTranslation(); position = damager->GetTranslation();
direction = act0->GetTransform().basis[1]; direction = damager->GetTransform().basis[1];
} }
const CDamageVulnerability* dVuln; const CDamageVulnerability* dVuln;
if (act0 || isPlayer) if (damager || isPlayer)
dVuln = act1->GetDamageVulnerability(position, direction, info); dVuln = damagee->GetDamageVulnerability(position, direction, info);
else else
dVuln = act1->GetDamageVulnerability(); dVuln = damagee->GetDamageVulnerability();
if (info.GetWeaponMode().GetType() == EWeaponType::None || if (info.GetWeaponMode().GetType() == EWeaponType::None ||
dVuln->WeaponHurts(info.GetWeaponMode(), false)) dVuln->WeaponHurts(info.GetWeaponMode(), false))
{ {
if (info.GetDamage() > 0.f) if (info.GetDamage() > 0.f)
ApplyLocalDamage(position, direction, *act1, info.GetDamage(), info.GetWeaponMode()); ApplyLocalDamage(position, direction, *damagee, info.GetDamage(), info.GetWeaponMode());
act1->SendScriptMsgs(EScriptObjectState::Damage, *this, EScriptObjectMessage::None); damagee->SendScriptMsgs(EScriptObjectState::Damage, *this, EScriptObjectMessage::None);
SendScriptMsg(act1.GetPtr(), id0, EScriptObjectMessage::Damage); SendScriptMsg(damagee.GetPtr(), damagerId, EScriptObjectMessage::Damage);
} }
else else
{ {
act1->SendScriptMsgs(EScriptObjectState::UNKS6, *this, EScriptObjectMessage::None); damagee->SendScriptMsgs(EScriptObjectState::InvulnDamage, *this, EScriptObjectMessage::None);
SendScriptMsg(act1.GetPtr(), id0, EScriptObjectMessage::InternalMessage20); SendScriptMsg(damagee.GetPtr(), damagerId, EScriptObjectMessage::InvulnDamage);
} }
if (alive && act0 && info.GetKnockBackPower() > 0.f) if (alive && damager && info.GetKnockBackPower() > 0.f)
{ {
zeus::CVector3f delta = vec.isZero() ? (act1->GetTranslation() - act0->GetTranslation()) : vec; zeus::CVector3f delta = knockbackVec.isZero() ?
ApplyKnockBack(*act1, info, *dVuln, delta.normalized(), 0.f); (damagee->GetTranslation() - damager->GetTranslation()) : knockbackVec;
ApplyKnockBack(*damagee, info, *dVuln, delta.normalized(), 0.f);
} }
} }
if (act0 && info.GetRadius() > 0.f) if (damager && info.GetRadius() > 0.f)
ProcessRadiusDamage(*act0, *act1, id2, info, filter); ProcessRadiusDamage(*damager, *damagee, radiusSender, info, filter);
if (TCastToPtr<CWallCrawlerSwarm> swarm = ent1) if (TCastToPtr<CWallCrawlerSwarm> swarm = ent1)
if (act0) if (damager)
swarm->ApplyRadiusDamage(act0->GetTranslation(), info, *this); swarm->ApplyRadiusDamage(damager->GetTranslation(), info, *this);
} }
return false; return false;

View File

@ -320,8 +320,9 @@ public:
void TestBombHittingWater(const CActor& damager, const zeus::CVector3f& pos, CActor& damagee); void TestBombHittingWater(const CActor& damager, const zeus::CVector3f& pos, CActor& damagee);
bool ApplyLocalDamage(const zeus::CVector3f&, const zeus::CVector3f&, CActor&, float, bool ApplyLocalDamage(const zeus::CVector3f&, const zeus::CVector3f&, CActor&, float,
const CWeaponMode&); const CWeaponMode&);
bool ApplyDamage(TUniqueId, TUniqueId, TUniqueId, const CDamageInfo& info, bool ApplyDamage(TUniqueId damagerId, TUniqueId damageeId, TUniqueId radiusSender,
const CMaterialFilter&, const zeus::CVector3f&); const CDamageInfo& info, const CMaterialFilter& filter,
const zeus::CVector3f& knockbackVec);
void UpdateAreaSounds(); void UpdateAreaSounds();
void FrameEnd(); void FrameEnd();
void ProcessPlayerInput(); void ProcessPlayerInput();

View File

@ -104,8 +104,8 @@ void CFirstPersonCamera::UpdateTransform(CStateManager& mgr, float dt)
player->GetCameraBob()->SetCameraBobTransform(zeus::CTransform::Identity()); player->GetCameraBob()->SetCameraBobTransform(zeus::CTransform::Identity());
} }
if (player->GetOrbitState() == CPlayer::EPlayerOrbitState::Four || if (player->GetOrbitState() == CPlayer::EPlayerOrbitState::ForcedOrbitObject ||
player->GetOrbitState() == CPlayer::EPlayerOrbitState::One) player->GetOrbitState() == CPlayer::EPlayerOrbitState::OrbitObject)
{ {
const CActor* act = TCastToConstPtr<CActor>(mgr.GetObjectById(player->x310_orbitTargetId)); const CActor* act = TCastToConstPtr<CActor>(mgr.GetObjectById(player->x310_orbitTargetId));
if (act && act->GetMaterialList().Intersection(CMaterialList(EMaterialTypes::Lava)) != 0) if (act && act->GetMaterialList().Intersection(CMaterialList(EMaterialTypes::Lava)) != 0)
@ -154,8 +154,8 @@ void CFirstPersonCamera::UpdateTransform(CStateManager& mgr, float dt)
if (player->x3dc_inFreeLook) if (player->x3dc_inFreeLook)
{ {
if (player->GetOrbitState() == CPlayer::EPlayerOrbitState::Four || if (player->GetOrbitState() == CPlayer::EPlayerOrbitState::ForcedOrbitObject ||
player->GetOrbitState() == CPlayer::EPlayerOrbitState::One) player->GetOrbitState() == CPlayer::EPlayerOrbitState::OrbitObject)
{ {
zeus::CVector3f gunFrontVec = gunXf.frontVector(); zeus::CVector3f gunFrontVec = gunXf.frontVector();
@ -200,8 +200,8 @@ void CFirstPersonCamera::UpdateTransform(CStateManager& mgr, float dt)
qGun = zeus::CQuaternion::lookAt(rVec, gunFrontVec, zeus::CRelAngle::FromDegrees(360.f)); qGun = zeus::CQuaternion::lookAt(rVec, gunFrontVec, zeus::CRelAngle::FromDegrees(360.f));
} }
} }
else if (player->GetOrbitState() == CPlayer::EPlayerOrbitState::Two || else if (player->GetOrbitState() == CPlayer::EPlayerOrbitState::OrbitPoint ||
player->GetOrbitState() == CPlayer::EPlayerOrbitState::Three) player->GetOrbitState() == CPlayer::EPlayerOrbitState::OrbitCarcass)
{ {
dt *= g_tweakPlayer->GetOrbitCameraSpeed(); dt *= g_tweakPlayer->GetOrbitCameraSpeed();
CalculateGunFollowOrientationAndTransform(gunXf, qGun, dt, rVec); CalculateGunFollowOrientationAndTransform(gunXf, qGun, dt, rVec);

View File

@ -3,10 +3,36 @@
namespace urde namespace urde
{ {
zeus::CVector3f CSteeringBehaviors::ProjectOrbitalPosition(const zeus::CVector3f&, const zeus::CVector3f&, zeus::CVector3f
const zeus::CVector3f&, float) CSteeringBehaviors::ProjectOrbitalPosition(const zeus::CVector3f& pos, const zeus::CVector3f& vel,
const zeus::CVector3f& orbitPoint, float dt, float preThinkDt)
{ {
return {}; zeus::CVector3f usePos = pos;
if (vel.canBeNormalized())
{
zeus::CVector3f pointToPos = pos - orbitPoint;
pointToPos.z = 0.f;
if (pointToPos.canBeNormalized())
{
zeus::CVector3f useVel = vel;
pointToPos.normalize();
float f29 = pointToPos.dot(useVel);
float f30 = pointToPos.cross(zeus::CVector3f::skUp).dot(useVel);
for (float curDt = 0.f ; curDt < dt ;)
{
usePos += preThinkDt * useVel;
zeus::CVector3f usePointToPos = usePos - orbitPoint;
usePointToPos.z = 0.f;
if (usePointToPos.canBeNormalized())
{
usePointToPos.normalize();
useVel = usePointToPos.cross(zeus::CVector3f::skUp) * f30 + usePointToPos * f29;
}
curDt += std::min(dt - curDt, preThinkDt);
}
}
}
return usePos;
} }
} }

View File

@ -10,8 +10,8 @@ namespace urde
class CSteeringBehaviors class CSteeringBehaviors
{ {
public: public:
static zeus::CVector3f ProjectOrbitalPosition(const zeus::CVector3f&, const zeus::CVector3f&, static zeus::CVector3f ProjectOrbitalPosition(const zeus::CVector3f& pos, const zeus::CVector3f& vel,
const zeus::CVector3f&, float); const zeus::CVector3f& orbitPoint, float dt, float preThinkDt);
}; };
} }

View File

@ -90,7 +90,7 @@ void CCollisionActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C
CActor::AcceptScriptMsg(msg, uid, mgr); CActor::AcceptScriptMsg(msg, uid, mgr);
} }
CHealthInfo* CCollisionActor::HealthInfo() { return &x28c_healthInfo; } CHealthInfo* CCollisionActor::HealthInfo(CStateManager&) { return &x28c_healthInfo; }
const CDamageVulnerability* CCollisionActor::GetDamageVulnerability() const { return &x294_damageVuln; } const CDamageVulnerability* CCollisionActor::GetDamageVulnerability() const { return &x294_damageVuln; }

View File

@ -39,7 +39,7 @@ public:
void Accept(IVisitor &visitor); void Accept(IVisitor &visitor);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
CHealthInfo* HealthInfo(); CHealthInfo* HealthInfo(CStateManager&);
const CDamageVulnerability* GetDamageVulnerability() const; const CDamageVulnerability* GetDamageVulnerability() const;
const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f&, const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f&,
const CDamageInfo&) const; const CDamageInfo&) const;

View File

@ -494,7 +494,7 @@ void CHudDecoInterfaceXRay::SetFrameColorValue(float v)
void CHudDecoInterfaceXRay::Update(float dt, const CStateManager& stateMgr) void CHudDecoInterfaceXRay::Update(float dt, const CStateManager& stateMgr)
{ {
if (stateMgr.GetPlayer().GetOrbitState() == CPlayer::EPlayerOrbitState::One) if (stateMgr.GetPlayer().GetOrbitState() == CPlayer::EPlayerOrbitState::OrbitObject)
x4_seekerScale = std::max(x4_seekerScale - 3.f * dt, 0.35f); x4_seekerScale = std::max(x4_seekerScale - 3.f * dt, 0.35f);
else else
x4_seekerScale = std::min(3.f * dt + x4_seekerScale, 1.f); x4_seekerScale = std::min(3.f * dt + x4_seekerScale, 1.f);

View File

@ -408,7 +408,7 @@ void CSamusHud::UpdateEnergy(float dt, const CStateManager& mgr, bool init)
const CEntity* bossEnt = mgr.GetObjectById(mgr.GetBossId()); const CEntity* bossEnt = mgr.GetObjectById(mgr.GetBossId());
if (TCastToConstPtr<CActor> act = bossEnt) if (TCastToConstPtr<CActor> act = bossEnt)
{ {
if (const CHealthInfo* hInfo = act->GetHealthInfo()) if (const CHealthInfo* hInfo = act->GetHealthInfo(mgr))
{ {
float bossEnergy = std::ceil(hInfo->GetHP()); float bossEnergy = std::ceil(hInfo->GetHP());
x2b4_bossEnergyIntf->SetBossParams(true, g_MainStringTable->GetString(mgr.GetBossStringIdx()), x2b4_bossEnergyIntf->SetBossParams(true, g_MainStringTable->GetString(mgr.GetBossStringIdx()),

View File

@ -5,6 +5,7 @@ set(MP1_WORLD_SOURCES
CSpacePirate.hpp CSpacePirate.cpp CSpacePirate.hpp CSpacePirate.cpp
CBabygoth.hpp CBabygoth.cpp CBabygoth.hpp CBabygoth.cpp
CMetroidPrimeRelay.hpp CMetroidPrimeRelay.cpp CMetroidPrimeRelay.hpp CMetroidPrimeRelay.cpp
CMetroidPrimeExo.hpp CMetroidPrimeExo.cpp
CActorContraption.hpp CActorContraption.cpp CActorContraption.hpp CActorContraption.cpp
CThardusRockProjectile.hpp CThardusRockProjectile.cpp CThardusRockProjectile.hpp CThardusRockProjectile.cpp
CMetroidBeta.hpp CMetroidBeta.cpp CMetroidBeta.hpp CMetroidBeta.cpp

View File

@ -0,0 +1,168 @@
#include "CMetroidPrimeExo.hpp"
#include "World/ScriptLoader.hpp"
#include "GameGlobalObjects.hpp"
#include "CSimplePool.hpp"
#include "DataSpec/DNAMP1/ScriptObjects/MetroidPrimeStage1.hpp"
namespace urde
{
namespace MP1
{
SPrimeStruct2B::SPrimeStruct2B(CInputStream& in)
: x0_propertyCount(in.readUint32Big()),
x4_particle1(in.readUint32Big()),
x8_particle2(in.readUint32Big()),
xc_particle3(in.readUint32Big()),
x10_dInfo(in),
x2c_(in.readFloatBig()),
x30_(in.readFloatBig()),
x34_texture(in.readUint32Big()),
x38_(CSfxManager::TranslateSFXID(u16(in.readUint32Big()))),
x3a_(CSfxManager::TranslateSFXID(u16(in.readUint32Big())))
{}
SPrimeStruct5::SPrimeStruct5(CInputStream& in)
: x0_propertyCount(in.readUint32Big()),
x4_(in.readUint32Big()),
x8_(in.readUint32Big()),
xc_(in.readUint32Big()),
x10_(in.readUint32Big()),
x14_(in.readUint32Big()),
x18_(in.readUint32Big()),
x1c_(in.readUint32Big()),
x20_(in.readUint32Big())
{}
SPrimeStruct4::SPrimeStruct4(CInputStream& in)
: x0_beamInfo(in),
x44_(in.readUint32Big()),
x48_dInfo1(in),
x64_struct5(in),
x88_(in.readFloatBig()),
x8c_dInfo2(in)
{}
SPrimeStruct5B::SPrimeStruct5B(CInputStream& in)
: x0_propertyCount(in.readUint32Big()),
x4_particle(g_SimplePool->GetObj(SObjectTag{FOURCC('PART'), in.readUint32Big()})),
xc_dInfo(in),
x28_(in.readFloatBig()),
x2c_(in.readFloatBig()),
x30_(in.readFloatBig()),
x34_texture(in.readUint32Big())
{
x38_24_ = in.readBool();
x38_25_ = in.readBool();
x38_26_ = in.readBool();
x38_27_ = in.readBool();
}
SPrimeStruct6::SPrimeStruct6(CInputStream& in)
: x0_propertyCount(in.readUint32Big()),
x4_damageVulnerability(in),
x6c_color(zeus::CColor::ReadRGBABig(in)),
x70_(in.readUint32Big()),
x74_(in.readUint32Big())
{}
static CPatternedInfo LoadPatternedInfo(CInputStream& in)
{
std::pair<bool, u32> pcount = CPatternedInfo::HasCorrectParameterCount(in);
return CPatternedInfo(in, pcount.second);
}
using CameraShakeData = DataSpec::DNAMP1::MetroidPrimeStage1::MassivePrimeStruct::CameraShakeData;
static SCameraShakePoint BuildCameraShakePoint(CameraShakeData::CameraShakerComponent::CameraShakePoint& sp)
{
return SCameraShakePoint(0, sp.unknown2, sp.unknown3, sp.duration, sp.magnitude);
}
static CCameraShakerComponent BuildCameraShakerComponent(CameraShakeData::CameraShakerComponent& comp)
{
return CCameraShakerComponent(u32(comp.unknown1), BuildCameraShakePoint(comp.shakePoints[0]),
BuildCameraShakePoint(comp.shakePoints[1]));
}
static CCameraShakeData LoadCameraShakeData(CInputStream& in)
{
CameraShakeData shakeData;
shakeData.read(in);
return CCameraShakeData(shakeData.duration, shakeData.unknown3, u32(shakeData.unknown1),
zeus::CVector3f::skZero,
BuildCameraShakerComponent(shakeData.shakerComponents[0]),
BuildCameraShakerComponent(shakeData.shakerComponents[1]),
BuildCameraShakerComponent(shakeData.shakerComponents[2]));
}
static rstl::reserved_vector<SPrimeStruct4, 4> LoadPrimeStruct4s(CInputStream& in)
{
rstl::reserved_vector<SPrimeStruct4, 4> ret;
for (int i=0 ; i<4 ; ++i)
ret.emplace_back(in);
return ret;
}
static rstl::reserved_vector<SPrimeStruct6, 4> LoadPrimeStruct6s(CInputStream& in)
{
rstl::reserved_vector<SPrimeStruct6, 4> ret;
for (int i=0 ; i<4 ; ++i)
ret.emplace_back(in);
return ret;
}
SPrimeExoParameters::SPrimeExoParameters(CInputStream& in)
: x0_propertyCount(in.readUint32Big()),
x4_patternedInfo(LoadPatternedInfo(in)),
x13c_actorParms(ScriptLoader::LoadActorParameters(in)),
x1a4_(in.readUint32Big()),
x1a8_(LoadCameraShakeData(in)),
x27c_(LoadCameraShakeData(in)),
x350_(LoadCameraShakeData(in)),
x424_(in),
x460_particle1(in.readUint32Big()),
x464_(LoadPrimeStruct4s(in)),
x708_wpsc1(in.readUint32Big()),
x70c_dInfo1(in),
x728_shakeData1(LoadCameraShakeData(in)),
x7fc_wpsc2(in.readUint32Big()),
x800_dInfo2(in),
x81c_shakeData2(LoadCameraShakeData(in)),
x8f0_(in),
x92c_(in),
x948_(LoadCameraShakeData(in)),
xa1c_particle2(in.readUint32Big()),
xa20_swoosh(in.readUint32Big()),
xa24_particle3(in.readUint32Big()),
xa28_particle4(in.readUint32Big()),
xa2c_(LoadPrimeStruct6s(in))
{}
SPrimeExoRoomParameters::SPrimeExoRoomParameters(CInputStream& in)
{
u32 propCount = std::min(u32(14), in.readUint32Big());
for (int i=0 ; i<propCount ; ++i)
x0_.push_back(in.readFloatBig());
}
CMetroidPrimeExo::CMetroidPrimeExo(TUniqueId uid, const std::string& name, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
const CActorParameters& aParms, u32 pw1, const CCameraShakeData& shakeData1,
const CCameraShakeData& shakeData2, const CCameraShakeData& shakeData3,
const SPrimeStruct2B& struct2b, CAssetId particle1,
const rstl::reserved_vector<SPrimeStruct4, 4>& struct4s, CAssetId wpsc1,
const CDamageInfo& dInfo1, const CCameraShakeData& shakeData4, CAssetId wpsc2,
const CDamageInfo& dInfo2, const CCameraShakeData& shakeData5,
const SPrimeStruct5B& struct5b, const CDamageInfo& dInfo3,
const CCameraShakeData& shakeData6, CAssetId particle2, CAssetId swoosh,
CAssetId particle3, CAssetId particle4,
const rstl::reserved_vector<SPrimeStruct6, 4>& struct6s)
: CPatterned(ECharacter::MetroidPrimeExo, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
EMovementType::Flyer, EColliderType::One, EBodyType::Flyer, aParms, 2)
{
}
}
}

View File

@ -0,0 +1,136 @@
#ifndef CMETROIDPRIMEEXO_HPP
#define CMETROIDPRIMEEXO_HPP
#include "World/CPatterned.hpp"
#include "World/CPatternedInfo.hpp"
#include "World/CActorParameters.hpp"
#include "Camera/CCameraShakeData.hpp"
#include "Weapon/CBeamInfo.hpp"
namespace urde
{
class CCameraShakeData;
namespace MP1
{
struct SPrimeStruct2B
{
u32 x0_propertyCount;
CAssetId x4_particle1;
CAssetId x8_particle2;
CAssetId xc_particle3;
CDamageInfo x10_dInfo;
float x2c_;
float x30_;
CAssetId x34_texture;
u16 x38_;
u16 x3a_;
explicit SPrimeStruct2B(CInputStream& in);
};
struct SPrimeStruct5
{
u32 x0_propertyCount;
CAssetId x4_;
u32 x8_;
CAssetId xc_;
CAssetId x10_;
u32 x14_;
u32 x18_;
u32 x1c_;
u32 x20_;
explicit SPrimeStruct5(CInputStream& in);
};
struct SPrimeStruct4
{
CBeamInfo x0_beamInfo;
u32 x44_;
CDamageInfo x48_dInfo1;
SPrimeStruct5 x64_struct5;
float x88_;
CDamageInfo x8c_dInfo2;
explicit SPrimeStruct4(CInputStream& in);
};
struct SPrimeStruct5B
{
u32 x0_propertyCount;
TToken<CGenDescription> x4_particle;
CDamageInfo xc_dInfo;
float x28_;
float x2c_;
float x30_;
CAssetId x34_texture;
bool x38_24_ : 1;
bool x38_25_ : 1;
bool x38_26_ : 1;
bool x38_27_ : 1;
explicit SPrimeStruct5B(CInputStream& in);
};
struct SPrimeStruct6
{
u32 x0_propertyCount;
CDamageVulnerability x4_damageVulnerability;
zeus::CColor x6c_color;
u32 x70_;
u32 x74_;
explicit SPrimeStruct6(CInputStream& in);
};
struct SPrimeExoParameters
{
u32 x0_propertyCount;
CPatternedInfo x4_patternedInfo;
CActorParameters x13c_actorParms;
u32 x1a4_;
CCameraShakeData x1a8_;
CCameraShakeData x27c_;
CCameraShakeData x350_;
SPrimeStruct2B x424_;
CAssetId x460_particle1;
rstl::reserved_vector<SPrimeStruct4, 4> x464_;
CAssetId x708_wpsc1;
CDamageInfo x70c_dInfo1;
CCameraShakeData x728_shakeData1;
CAssetId x7fc_wpsc2;
CDamageInfo x800_dInfo2;
CCameraShakeData x81c_shakeData2;
SPrimeStruct5B x8f0_;
CDamageInfo x92c_;
CCameraShakeData x948_;
CAssetId xa1c_particle2;
CAssetId xa20_swoosh;
CAssetId xa24_particle3;
CAssetId xa28_particle4;
rstl::reserved_vector<SPrimeStruct6, 4> xa2c_;
explicit SPrimeExoParameters(CInputStream& in);
};
struct SPrimeExoRoomParameters
{
rstl::reserved_vector<float, 14> x0_;
explicit SPrimeExoRoomParameters(CInputStream& in);
};
class CMetroidPrimeExo : public CPatterned
{
public:
static constexpr ECharacter CharacterType = ECharacter::MetroidPrimeExo;
CMetroidPrimeExo(TUniqueId uid, const std::string& name, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& aParms,
u32 pw1, const CCameraShakeData& shakeData1, const CCameraShakeData& shakeData2,
const CCameraShakeData& shakeData3, const SPrimeStruct2B& struct2b, CAssetId particle1,
const rstl::reserved_vector<SPrimeStruct4, 4>& struct4s, CAssetId wpsc1, const CDamageInfo& dInfo1,
const CCameraShakeData& shakeData4, CAssetId wpsc2, const CDamageInfo& dInfo2,
const CCameraShakeData& shakeData5, const SPrimeStruct5B& struct5b, const CDamageInfo& dInfo3,
const CCameraShakeData& shakeData6, CAssetId particle2, CAssetId swoosh, CAssetId particle3,
CAssetId particle4, const rstl::reserved_vector<SPrimeStruct6, 4>& struct6s);
};
}
}
#endif // CMETROIDPRIMEEXO_HPP

View File

@ -0,0 +1,25 @@
#include "CMetroidPrimeRelay.hpp"
#include "TCastTo.hpp"
namespace urde
{
namespace MP1
{
CMetroidPrimeRelay::CMetroidPrimeRelay(TUniqueId uid, const std::string& name, const CEntityInfo& info, bool active,
const zeus::CTransform& xf, const zeus::CVector3f& scale,
SPrimeExoParameters&& parms, float f1, float f2, float f3, u32 w1,
bool b1, u32 w2, const CHealthInfo& hInfo1, const CHealthInfo& hInfo2, u32 w3,
u32 w4, u32 w5, rstl::reserved_vector<SPrimeExoRoomParameters, 4>&& roomParms)
: CEntity(uid, info, active, name), x38_xf(xf), x68_scale(scale), x74_parms(std::move(parms)), xc84_f1(f1),
xc88_f2(f2), xc8c_f3(f3), xc90_w1(w1), xc94_b1(b1), xc98_w2(w2), xc9c_hInfo1(hInfo1), xca4_hInfo2(hInfo2),
xcac_w3(w3), xcb0_w4(w4), xcb4_w5(w5), xcb8_roomParms(std::move(roomParms))
{}
void CMetroidPrimeRelay::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
}
}

View File

@ -0,0 +1,44 @@
#ifndef CMETROIDPRIMERELAY_HPP
#define CMETROIDPRIMERELAY_HPP
#include "World/CEntity.hpp"
#include "CMetroidPrimeExo.hpp"
namespace urde
{
namespace MP1
{
class CMetroidPrimeRelay : public CEntity
{
TUniqueId x34_mpUid = kInvalidUniqueId;
zeus::CTransform x38_xf;
zeus::CVector3f x68_scale;
SPrimeExoParameters x74_parms;
float xc84_f1;
float xc88_f2;
float xc8c_f3;
u32 xc90_w1;
bool xc94_b1;
u32 xc98_w2;
CHealthInfo xc9c_hInfo1;
CHealthInfo xca4_hInfo2;
u32 xcac_w3;
u32 xcb0_w4;
u32 xcb4_w5;
rstl::reserved_vector<SPrimeExoRoomParameters, 4> xcb8_roomParms;
public:
CMetroidPrimeRelay(TUniqueId uid, const std::string& name, const CEntityInfo& info, bool active,
const zeus::CTransform& xf, const zeus::CVector3f& scale, SPrimeExoParameters&& parms,
float f1, float f2, float f3, u32 w1, bool b1, u32 w2, const CHealthInfo& hInfo1,
const CHealthInfo& hInfo2, u32 w3, u32 w4, u32 w5,
rstl::reserved_vector<SPrimeExoRoomParameters, 4>&& roomParms);
void Accept(IVisitor& visitor);
TUniqueId GetMetroidPrimeExoId() const { return x34_mpUid; }
};
}
}
#endif // CMETROIDPRIMERELAY_HPP

View File

@ -23,7 +23,7 @@ enum class EWeaponType
Lava = 11, Lava = 11,
Hot = 12, Hot = 12,
Unused1 = 13, Unused1 = 13,
Unused2 = 14 OrangePhazon = 14
}; };
} }
#endif // __URDE_WEAPONCOMMON_HPP__ #endif // __URDE_WEAPONCOMMON_HPP__

View File

@ -101,7 +101,7 @@ void CActor::CalculateRenderBounds()
x9c_renderBounds = zeus::CAABox(x34_transform.origin, x34_transform.origin); x9c_renderBounds = zeus::CAABox(x34_transform.origin, x34_transform.origin);
} }
CHealthInfo* CActor::HealthInfo() { return nullptr; } CHealthInfo* CActor::HealthInfo(CStateManager&) { return nullptr; }
const CDamageVulnerability* CActor::GetDamageVulnerability() const { return nullptr; } const CDamageVulnerability* CActor::GetDamageVulnerability() const { return nullptr; }

View File

@ -108,7 +108,7 @@ public:
virtual void Render(const CStateManager&) const {} virtual void Render(const CStateManager&) const {}
virtual bool CanRenderUnsorted(const CStateManager&) const { return false; } virtual bool CanRenderUnsorted(const CStateManager&) const { return false; }
virtual void CalculateRenderBounds(); virtual void CalculateRenderBounds();
virtual CHealthInfo* HealthInfo(); virtual CHealthInfo* HealthInfo(CStateManager&);
virtual const CDamageVulnerability* GetDamageVulnerability() const; virtual const CDamageVulnerability* GetDamageVulnerability() const;
virtual const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f&, virtual const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f&,
const CDamageInfo&) const; const CDamageInfo&) const;
@ -174,7 +174,8 @@ public:
bool CanDrawStatic() const; bool CanDrawStatic() const;
bool GetE7_29() const { return xe7_29_; } bool GetE7_29() const { return xe7_29_; }
const CScannableObjectInfo* GetScannableObjectInfo() const; const CScannableObjectInfo* GetScannableObjectInfo() const;
const CHealthInfo* GetHealthInfo() const { return const_cast<CActor*>(this)->HealthInfo(); } const CHealthInfo* GetHealthInfo(const CStateManager& mgr) const
{ return const_cast<CActor*>(this)->HealthInfo(const_cast<CStateManager&>(mgr)); }
bool GetDoTargetDistanceTest() const { return xe7_30_doTargetDistanceTest; } bool GetDoTargetDistanceTest() const { return xe7_30_doTargetDistanceTest; }
void SetCalculateLighting(bool c); void SetCalculateLighting(bool c);
float GetAverageAnimVelocity(int anim) const; float GetAverageAnimVelocity(int anim) const;

View File

@ -46,7 +46,7 @@ public:
const CStateMachine* GetStateMachine() const; const CStateMachine* GetStateMachine() const;
virtual void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) {} virtual void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) {}
virtual CHealthInfo* HealthInfo() { return &x258_healthInfo; } virtual CHealthInfo* HealthInfo(CStateManager&) { return &x258_healthInfo; }
virtual void Death(CStateManager&, const zeus::CVector3f&, EStateMsg)=0; virtual void Death(CStateManager&, const zeus::CVector3f&, EStateMsg)=0;
virtual void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType, bool, float)=0; virtual void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType, bool, float)=0;
virtual CDamageVulnerability GetDamageVulnerability() { return x260_damageVulnerability; } virtual CDamageVulnerability GetDamageVulnerability() { return x260_damageVulnerability; }

View File

@ -149,7 +149,7 @@ EVulnerability CDamageVulnerability::GetPhazonVulnerability(const CWeaponMode& m
bool CDamageVulnerability::WeaponHurts(const CWeaponMode& mode, bool ignoreDirect) const bool CDamageVulnerability::WeaponHurts(const CWeaponMode& mode, bool ignoreDirect) const
{ {
if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::Unused2) if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::OrangePhazon)
return false; return false;
if (mode.IsInstantKill()) if (mode.IsInstantKill())
return true; return true;
@ -198,7 +198,7 @@ bool CDamageVulnerability::WeaponHurts(const CWeaponMode& mode, bool ignoreDirec
bool CDamageVulnerability::WeaponHits(const CWeaponMode& mode, bool checkDirect) const bool CDamageVulnerability::WeaponHits(const CWeaponMode& mode, bool checkDirect) const
{ {
if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::Unused2) if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::OrangePhazon)
return false; return false;
if (mode.IsInstantKill()) if (mode.IsInstantKill())
return true; return true;
@ -237,7 +237,7 @@ bool CDamageVulnerability::WeaponHits(const CWeaponMode& mode, bool checkDirect)
EVulnerability CDamageVulnerability::GetVulnerability(const CWeaponMode& mode, bool ignoreDirect) const EVulnerability CDamageVulnerability::GetVulnerability(const CWeaponMode& mode, bool ignoreDirect) const
{ {
if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::Unused2) if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::OrangePhazon)
return EVulnerability::Reflect; return EVulnerability::Reflect;
if (mode.IsInstantKill()) if (mode.IsInstantKill())

View File

@ -143,7 +143,7 @@ public:
void GetTouchedHalfPipeRecently() const {} void GetTouchedHalfPipeRecently() const {}
void SetTouchedHalfPipeRecently(bool) {} void SetTouchedHalfPipeRecently(bool) {}
void DisableHalfPipeStatus() {} void DisableHalfPipeStatus() {}
void BallCloseToCollision(const CStateManager&, float) const {} bool BallCloseToCollision(const CStateManager&, float, const CMaterialFilter& filter) const { return false; }
void CollidedWith(TUniqueId, const CCollisionInfoList&, CStateManager&) {} void CollidedWith(TUniqueId, const CCollisionInfoList&, CStateManager&) {}
bool IsInFrustum(const zeus::CFrustum&) const { return false; } bool IsInFrustum(const zeus::CFrustum&) const { return false; }
void ComputeLiftForces(const zeus::CVector3f&, const zeus::CVector3f&, const CStateManager&) {} void ComputeLiftForces(const zeus::CVector3f&, const zeus::CVector3f&, const CStateManager&) {}

View File

@ -23,6 +23,7 @@
#include "CHUDBillboardEffect.hpp" #include "CHUDBillboardEffect.hpp"
#include "Audio/CStreamAudioManager.hpp" #include "Audio/CStreamAudioManager.hpp"
#include "CScriptPlayerHint.hpp" #include "CScriptPlayerHint.hpp"
#include "CScriptAreaAttributes.hpp"
namespace urde namespace urde
{ {
@ -201,7 +202,7 @@ void CPlayer::TransitionToMorphBallState(float dt, CStateManager& mgr)
ballCam->SetFovInterpolation(mgr.GetCameraManager()->GetFirstPersonCamera()->GetFov(), ballCam->SetFovInterpolation(mgr.GetCameraManager()->GetFirstPersonCamera()->GetFov(),
CCameraManager::ThirdPersonFOV(), 1.f, 0.f); CCameraManager::ThirdPersonFOV(), 1.f, 0.f);
} }
SetOrbitRequest(EPlayerOrbitRequest::Two, mgr); SetOrbitRequest(EPlayerOrbitRequest::EnterMorphBall, mgr);
x490_gun->CancelFiring(mgr); x490_gun->CancelFiring(mgr);
HolsterGun(mgr); HolsterGun(mgr);
} }
@ -724,10 +725,10 @@ float CPlayer::GetAcceleration() const
return x2b4_accelerationTable[x2d0_curAcceleration]; return x2b4_accelerationTable[x2d0_curAcceleration];
} }
float CPlayer::CalculateOrbitZBasedDistance(EPlayerOrbitType type) const float CPlayer::CalculateOrbitMinDistance(EPlayerOrbitType type) const
{ {
return zeus::clamp(1.f, std::fabs(x314_orbitPoint.z - GetTranslation().z) / 20.f, 4.f) * return zeus::clamp(1.f, std::fabs(x314_orbitPoint.z - GetTranslation().z) / 20.f, 4.f) *
g_tweakPlayer->GetOrbitZBasedDistance(int(type)); g_tweakPlayer->GetOrbitMinDistance(int(type));
} }
void CPlayer::PostUpdate(float dt, CStateManager& mgr) void CPlayer::PostUpdate(float dt, CStateManager& mgr)
@ -813,7 +814,7 @@ bool CPlayer::HasTransitionBeamModel() const
return x7f0_ballTransitionBeamModel && !x7f0_ballTransitionBeamModel->IsNull(); return x7f0_ballTransitionBeamModel && !x7f0_ballTransitionBeamModel->IsNull();
} }
bool CPlayer::CanRenderUnsorted(CStateManager& mgr) const { return false; } bool CPlayer::CanRenderUnsorted(const CStateManager& mgr) const { return false; }
const CDamageVulnerability* CPlayer::GetDamageVulnerability(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const CDamageVulnerability* CPlayer::GetDamageVulnerability(const zeus::CVector3f& v1, const zeus::CVector3f& v2,
const CDamageInfo& info) const const CDamageInfo& info) const
@ -829,14 +830,14 @@ const CDamageVulnerability* CPlayer::GetDamageVulnerability() const
return GetDamageVulnerability(zeus::CVector3f::skZero, zeus::CVector3f::skUp, info); return GetDamageVulnerability(zeus::CVector3f::skZero, zeus::CVector3f::skUp, info);
} }
zeus::CVector3f CPlayer::GetHomingPosition(CStateManager& mgr, float dt) const zeus::CVector3f CPlayer::GetHomingPosition(const CStateManager& mgr, float dt) const
{ {
if (dt > 0.f) if (dt > 0.f)
return x34_transform.origin + PredictMotion(dt).x0_translation; return x34_transform.origin + PredictMotion(dt).x0_translation;
return x34_transform.origin; return x34_transform.origin;
} }
zeus::CVector3f CPlayer::GetAimPosition(CStateManager& mgr, float dt) const zeus::CVector3f CPlayer::GetAimPosition(const CStateManager& mgr, float dt) const
{ {
zeus::CVector3f ret = x34_transform.origin; zeus::CVector3f ret = x34_transform.origin;
if (dt > 0.f) if (dt > 0.f)
@ -844,7 +845,7 @@ zeus::CVector3f CPlayer::GetAimPosition(CStateManager& mgr, float dt) const
if (x304_orbitState == EPlayerOrbitState::NoOrbit) if (x304_orbitState == EPlayerOrbitState::NoOrbit)
ret += PredictMotion(dt).x0_translation; ret += PredictMotion(dt).x0_translation;
else else
ret = CSteeringBehaviors::ProjectOrbitalPosition(ret, x138_velocity, x314_orbitPoint, dt); ret = CSteeringBehaviors::ProjectOrbitalPosition(ret, x138_velocity, x314_orbitPoint, dt, xa04_preThinkDt);
} }
if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) if (x2f8_morphBallState == EPlayerMorphBallState::Morphed)
@ -949,7 +950,7 @@ void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location,
switch (type) switch (type)
{ {
case EWeaponType::Phazon: case EWeaponType::Phazon:
case EWeaponType::Unused2: case EWeaponType::OrangePhazon:
damageLoopSfx = 3114; damageLoopSfx = 3114;
damageSamusVoiceSfx = 1653; damageSamusVoiceSfx = 1653;
break; break;
@ -992,7 +993,7 @@ void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location,
doRumble = true; doRumble = true;
} }
if (damageLoopSfx && !x9c7_24_ && x2ac_surfaceRestraint >= ESurfaceRestraints::Ice) if (damageLoopSfx && !x9c7_24_noDamageLoopSfx && xa2c_damageLoopSfxDelayTicks >= 2)
{ {
if (!x770_damageLoopSfx || x788_damageLoopSfxId != damageLoopSfx) if (!x770_damageLoopSfx || x788_damageLoopSfxId != damageLoopSfx)
{ {
@ -1013,7 +1014,7 @@ void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location,
} }
x770_damageLoopSfx = CSfxManager::SfxStart(suitDamageSfx, 1.f, 0.f, false, 0x7f, true, kInvalidAreaId); x770_damageLoopSfx = CSfxManager::SfxStart(suitDamageSfx, 1.f, 0.f, false, 0x7f, true, kInvalidAreaId);
x788_damageLoopSfxId = suitDamageSfx; x788_damageLoopSfxId = suitDamageSfx;
xa2c_ = 0; xa2c_damageLoopSfxDelayTicks = 0;
doRumble = true; doRumble = true;
} }
@ -1035,7 +1036,7 @@ void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location,
} }
if (x3b8_grappleState != EGrappleState::None) if (x3b8_grappleState != EGrappleState::None)
BreakGrapple(EPlayerOrbitRequest::Eleven, mgr); BreakGrapple(EPlayerOrbitRequest::DamageOnGrapple, mgr);
} }
void CPlayer::Accept(IVisitor& visitor) void CPlayer::Accept(IVisitor& visitor)
@ -1043,7 +1044,7 @@ void CPlayer::Accept(IVisitor& visitor)
visitor.Visit(this); visitor.Visit(this);
} }
CHealthInfo* CPlayer::HealthInfo(const CStateManager& mgr) { return &mgr.GetPlayerState()->HealthInfo(); } CHealthInfo* CPlayer::HealthInfo(CStateManager& mgr) { return &mgr.GetPlayerState()->HealthInfo(); }
bool CPlayer::IsUnderBetaMetroidAttack(CStateManager& mgr) const bool CPlayer::IsUnderBetaMetroidAttack(CStateManager& mgr) const
{ {
@ -1156,7 +1157,7 @@ bool CPlayer::ValidateScanning(const CFinalInput& input, CStateManager& mgr)
{ {
if (ControlMapper::GetDigitalInput(ControlMapper::ECommands::ScanItem, input)) if (ControlMapper::GetDigitalInput(ControlMapper::ECommands::ScanItem, input))
{ {
if (x304_orbitState == EPlayerOrbitState::One) if (x304_orbitState == EPlayerOrbitState::OrbitObject)
{ {
if (TCastToPtr<CActor> act = mgr.ObjectById(x310_orbitTargetId)) if (TCastToPtr<CActor> act = mgr.ObjectById(x310_orbitTargetId))
{ {
@ -1606,7 +1607,7 @@ void CPlayer::ComputeFreeLook(const CFinalInput& input)
void CPlayer::UpdateFreeLookState(const CFinalInput& input, float dt, CStateManager& mgr) void CPlayer::UpdateFreeLookState(const CFinalInput& input, float dt, CStateManager& mgr)
{ {
if (x304_orbitState == EPlayerOrbitState::Four || IsMorphBallTransitioning() || if (x304_orbitState == EPlayerOrbitState::ForcedOrbitObject || IsMorphBallTransitioning() ||
x2f8_morphBallState != EPlayerMorphBallState::Unmorphed || x2f8_morphBallState != EPlayerMorphBallState::Unmorphed ||
(x3b8_grappleState != EGrappleState::None && x3b8_grappleState != EGrappleState::Firing)) (x3b8_grappleState != EGrappleState::None && x3b8_grappleState != EGrappleState::Firing))
{ {
@ -2141,9 +2142,9 @@ void CPlayer::Freeze(CStateManager& stateMgr, CAssetId steamTxtr, u16 sfx, CAsse
CPhysicsActor::Stop(); CPhysicsActor::Stop();
ClearForcesAndTorques(); ClearForcesAndTorques();
if (x3b8_grappleState != EGrappleState::None) if (x3b8_grappleState != EGrappleState::None)
BreakGrapple(EPlayerOrbitRequest::Ten, stateMgr); BreakGrapple(EPlayerOrbitRequest::Freeze, stateMgr);
else else
SetOrbitRequest(EPlayerOrbitRequest::Ten, stateMgr); SetOrbitRequest(EPlayerOrbitRequest::Freeze, stateMgr);
AddMaterial(EMaterialTypes::Immovable, stateMgr); AddMaterial(EMaterialTypes::Immovable, stateMgr);
xa08_steamTextureId = steamTxtr; xa08_steamTextureId = steamTxtr;
@ -2260,12 +2261,95 @@ void CPlayer::UpdateWaterSurfaceCameraBias(CStateManager& mgr)
void CPlayer::UpdatePhazonCameraShake(float dt, CStateManager& mgr) void CPlayer::UpdatePhazonCameraShake(float dt, CStateManager& mgr)
{ {
xa2c_damageLoopSfxDelayTicks = std::min(2, xa2c_damageLoopSfxDelayTicks + 1);
if (xa10_phazonCounter != 0)
{
if (xa14_phazonCameraShakeTimer == 0.f)
mgr.GetCameraManager()->AddCameraShaker(CCameraShakeData::BuildPhazonCameraShakeData(1.f, 0.075f), false);
xa14_phazonCameraShakeTimer += dt;
if (xa14_phazonCameraShakeTimer > 2.f)
xa14_phazonCameraShakeTimer = 0.f;
}
} }
void CPlayer::UpdatePhazonDamage(float dt, CStateManager& mgr) void CPlayer::UpdatePhazonDamage(float dt, CStateManager& mgr)
{ {
if (x4_areaId == kInvalidAreaId)
return;
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(x4_areaId);
if (!area->IsPostConstructed())
return;
bool touchingPhazon = false;
EPhazonType phazonType;
if (const CScriptAreaAttributes* attr = area->GetPostConstructed()->x10d8_areaAttributes)
phazonType = attr->GetPhazonType();
else
phazonType = EPhazonType::None;
if (phazonType == EPhazonType::Orange ||
(!mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PhazonSuit) && phazonType == EPhazonType::Blue))
{
CMaterialFilter filter = CMaterialFilter::MakeInclude({EMaterialTypes::Phazon});
if (x2f8_morphBallState == EPlayerMorphBallState::Morphed)
{
touchingPhazon = x768_morphball->BallCloseToCollision(mgr, 2.9f, filter);
}
else
{
CMaterialList primMaterial(EMaterialTypes::Player, EMaterialTypes::Solid);
CCollidableSphere prim(zeus::CSphere(
GetCollisionPrimitive()->CalculateAABox(x34_transform).center(), 4.25f), primMaterial);
rstl::reserved_vector<TUniqueId, 1024> nearList;
mgr.BuildColliderList(nearList, *this, prim.CalculateLocalAABox());
if (CGameCollision::DetectStaticCollisionBoolean(mgr, prim, zeus::CTransform::Identity(), filter))
{
touchingPhazon = true;
}
else
{
for (TUniqueId id : nearList)
{
if (TCastToConstPtr<CPhysicsActor> act = mgr.GetObjectById(id))
{
CInternalCollisionStructure::CPrimDesc prim0(prim, filter, zeus::CTransform::Identity());
CInternalCollisionStructure::CPrimDesc prim1(*act->GetCollisionPrimitive(),
CMaterialFilter::skPassEverything,
act->GetPrimitiveTransform());
if (CCollisionPrimitive::CollideBoolean(prim0, prim1))
{
touchingPhazon = true;
break;
}
}
}
}
}
}
if (touchingPhazon)
{
xa18_phazonDamageLag += dt;
xa18_phazonDamageLag = std::min(xa18_phazonDamageLag, 3.f);
if (xa18_phazonDamageLag > 0.2f)
{
float damage = (xa18_phazonDamageLag - 0.2f) / 3.f * 60.f * dt;
CDamageInfo dInfo(CWeaponMode(phazonType == EPhazonType::Orange ?
EWeaponType::OrangePhazon : EWeaponType::Phazon), damage, 0.f, 0.f);
mgr.ApplyDamage(kInvalidUniqueId, GetUniqueId(), kInvalidUniqueId, dInfo,
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}),
zeus::CVector3f::skZero);
}
}
else
{
xa18_phazonDamageLag -= dt;
xa18_phazonDamageLag = std::min(0.2f, xa18_phazonDamageLag);
xa18_phazonDamageLag = std::max(0.f, xa18_phazonDamageLag);
}
xa1c_threatOverride = std::min(1.f, xa18_phazonDamageLag / 0.2f);
} }
void CPlayer::ResetPlayerHintState() void CPlayer::ResetPlayerHintState()
@ -2329,11 +2413,10 @@ void CPlayer::AddToPlayerHintRemoveList(TUniqueId id, CStateManager& mgr)
{ {
if (TCastToPtr<CScriptPlayerHint> hint = mgr.ObjectById(id)) if (TCastToPtr<CScriptPlayerHint> hint = mgr.ObjectById(id))
{ {
bool alreadyAdded = false;
for (TUniqueId existId : x93c_playerHintsToRemove) for (TUniqueId existId : x93c_playerHintsToRemove)
if (id == existId) if (id == existId)
return; return;
if (!alreadyAdded && x93c_playerHintsToRemove.size() != 32) if (x93c_playerHintsToRemove.size() != 32)
x93c_playerHintsToRemove.push_back(id); x93c_playerHintsToRemove.push_back(id);
} }
} }
@ -2342,11 +2425,10 @@ void CPlayer::AddToPlayerHintAddList(TUniqueId id, CStateManager& mgr)
{ {
if (TCastToPtr<CScriptPlayerHint> hint = mgr.ObjectById(id)) if (TCastToPtr<CScriptPlayerHint> hint = mgr.ObjectById(id))
{ {
bool alreadyAdded = false;
for (TUniqueId existId : x980_playerHintsToAdd) for (TUniqueId existId : x980_playerHintsToAdd)
if (id == existId) if (id == existId)
return; return;
if (!alreadyAdded && x980_playerHintsToAdd.size() != 32) if (x980_playerHintsToAdd.size() != 32)
x980_playerHintsToAdd.push_back(id); x980_playerHintsToAdd.push_back(id);
} }
} }
@ -2355,11 +2437,10 @@ void CPlayer::DeactivatePlayerHint(TUniqueId id, CStateManager& mgr)
{ {
if (TCastToPtr<CScriptPlayerHint> hint = mgr.ObjectById(id)) if (TCastToPtr<CScriptPlayerHint> hint = mgr.ObjectById(id))
{ {
bool alreadyAdded = false;
for (TUniqueId existId : x93c_playerHintsToRemove) for (TUniqueId existId : x93c_playerHintsToRemove)
if (id == existId) if (id == existId)
return; return;
if (!alreadyAdded && x93c_playerHintsToRemove.size() != 32) if (x93c_playerHintsToRemove.size() != 32)
{ {
x93c_playerHintsToRemove.push_back(id); x93c_playerHintsToRemove.push_back(id);
hint->ClearObjectList(); hint->ClearObjectList();
@ -2432,7 +2513,7 @@ void CPlayer::UpdatePlayerHints(CStateManager& mgr)
if ((needsNewHint || removedHint) && x838_playerHints.empty()) if ((needsNewHint || removedHint) && x838_playerHints.empty())
{ {
x830_playerHint = kInvalidUniqueId; x830_playerHint = kInvalidUniqueId;
x834_ = 1000; x834_playerHintPriority = 1000;
ResetPlayerHintState(); ResetPlayerHintState();
return; return;
} }
@ -2455,14 +2536,14 @@ void CPlayer::UpdatePlayerHints(CStateManager& mgr)
if (!foundHintInArea) if (!foundHintInArea)
{ {
x830_playerHint = kInvalidUniqueId; x830_playerHint = kInvalidUniqueId;
x834_ = 1000; x834_playerHintPriority = 1000;
ResetPlayerHintState(); ResetPlayerHintState();
} }
if (foundHint != nullptr && foundHintInArea && x830_playerHint != foundHint->GetUniqueId()) if (foundHint != nullptr && foundHintInArea && x830_playerHint != foundHint->GetUniqueId())
{ {
x830_playerHint = foundHint->GetUniqueId(); x830_playerHint = foundHint->GetUniqueId();
x834_ = foundHint->GetPriority(); x834_playerHintPriority = foundHint->GetPriority();
if (SetAreaPlayerHint(*foundHint, mgr)) if (SetAreaPlayerHint(*foundHint, mgr))
DeactivatePlayerHint(x830_playerHint, mgr); DeactivatePlayerHint(x830_playerHint, mgr);
} }
@ -2647,7 +2728,7 @@ void CPlayer::PreThink(float dt, CStateManager& mgr)
x55c_damageAmt = 0.f; x55c_damageAmt = 0.f;
x560_prevDamageAmt = 0.f; x560_prevDamageAmt = 0.f;
x564_damageLocation = zeus::CVector3f::skZero; x564_damageLocation = zeus::CVector3f::skZero;
xa04_ = dt; xa04_preThinkDt = dt;
} }
static const u16 skPlayerLandSfxSoft[] = static const u16 skPlayerLandSfxSoft[] =
@ -2812,7 +2893,7 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState
break; break;
case EScriptObjectMessage::ProjectileCollide: case EScriptObjectMessage::ProjectileCollide:
x378_orbitPreventionTimer = g_tweakPlayer->GetOrbitPreventionTime(); x378_orbitPreventionTimer = g_tweakPlayer->GetOrbitPreventionTime();
SetOrbitRequest(EPlayerOrbitRequest::Nine, mgr); SetOrbitRequest(EPlayerOrbitRequest::ProjectileCollide, mgr);
break; break;
case EScriptObjectMessage::AddPlatformRider: case EScriptObjectMessage::AddPlatformRider:
x82e_ridingPlatform = sender; x82e_ridingPlatform = sender;
@ -3642,7 +3723,7 @@ void CPlayer::ApplyGrappleForces(const CFinalInput& input, CStateManager& mgr, f
} }
else else
{ {
BreakGrapple(EPlayerOrbitRequest::Six, mgr); BreakGrapple(EPlayerOrbitRequest::InvalidateTarget, mgr);
} }
break; break;
} }
@ -3726,7 +3807,7 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
{ {
if (!g_tweakPlayer->GetGrappleJumpMode() && x3d8_grappleJumpTimeout <= 0.f) if (!g_tweakPlayer->GetGrappleJumpMode() && x3d8_grappleJumpTimeout <= 0.f)
ApplyGrappleJump(mgr); ApplyGrappleJump(mgr);
BreakGrapple(EPlayerOrbitRequest::Zero, mgr); BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
} }
} }
break; break;
@ -3735,7 +3816,7 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
} }
break; break;
case EPlayerOrbitState::One: case EPlayerOrbitState::OrbitObject:
if (playerToPoint.canBeNormalized()) if (playerToPoint.canBeNormalized())
{ {
CRayCastResult result = CRayCastResult result =
@ -3815,14 +3896,14 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
{ {
if (x304_orbitState >= EPlayerOrbitState::Grapple) if (x304_orbitState >= EPlayerOrbitState::Grapple)
return; return;
if (x304_orbitState != EPlayerOrbitState::One) if (x304_orbitState != EPlayerOrbitState::OrbitObject)
return; return;
} }
else else
{ {
if (!point) if (!point)
{ {
BreakGrapple(EPlayerOrbitRequest::Three, mgr); BreakGrapple(EPlayerOrbitRequest::Default, mgr);
return; return;
} }
@ -3834,7 +3915,7 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
x3d8_grappleJumpTimeout -= input.DeltaTime(); x3d8_grappleJumpTimeout -= input.DeltaTime();
if (x3d8_grappleJumpTimeout <= 0.f) if (x3d8_grappleJumpTimeout <= 0.f)
{ {
BreakGrapple(EPlayerOrbitRequest::Zero, mgr); BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
SetMoveState(EPlayerMovementState::StartingJump, mgr); SetMoveState(EPlayerMovementState::StartingJump, mgr);
ComputeMovement(input, mgr, input.DeltaTime()); ComputeMovement(input, mgr, input.DeltaTime());
PreventFallingCameraPitch(); PreventFallingCameraPitch();
@ -3859,14 +3940,14 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
{ {
SetMoveState(EPlayerMovementState::StartingJump, mgr); SetMoveState(EPlayerMovementState::StartingJump, mgr);
ComputeMovement(input, mgr, input.DeltaTime()); ComputeMovement(input, mgr, input.DeltaTime());
BreakGrapple(EPlayerOrbitRequest::Zero, mgr); BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
PreventFallingCameraPitch(); PreventFallingCameraPitch();
} }
break; break;
case EGrappleState::Firing: case EGrappleState::Firing:
case EGrappleState::Pull: case EGrappleState::Pull:
if (!ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input)) if (!ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input))
BreakGrapple(EPlayerOrbitRequest::Zero, mgr); BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
break; break;
default: default:
break; break;
@ -3885,7 +3966,7 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
LineOfSightFilter); LineOfSightFilter);
if (result.IsValid()) if (result.IsValid())
{ {
BreakGrapple(EPlayerOrbitRequest::Twelve, mgr); BreakGrapple(EPlayerOrbitRequest::LostGrappleLineOfSight, mgr);
} }
} }
return; return;
@ -3893,7 +3974,7 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
if (x490_gun->GetGrappleArm().BeamActive() && g_tweakPlayer->GetGrappleJumpMode() == 1 && if (x490_gun->GetGrappleArm().BeamActive() && g_tweakPlayer->GetGrappleJumpMode() == 1 &&
!ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input)) !ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input))
BreakGrapple(EPlayerOrbitRequest::Zero, mgr); BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
} }
void CPlayer::ApplyGrappleJump(CStateManager& mgr) void CPlayer::ApplyGrappleJump(CStateManager& mgr)
@ -3951,10 +4032,11 @@ void CPlayer::SetOrbitRequest(EPlayerOrbitRequest req, CStateManager& mgr)
x30c_orbitRequest = req; x30c_orbitRequest = req;
switch (req) switch (req)
{ {
case EPlayerOrbitRequest::Eight: case EPlayerOrbitRequest::ActivateOrbitSource:
ActivateOrbitSource(mgr);
case EPlayerOrbitRequest::Seven: break;
SetOrbitState(EPlayerOrbitState::Two, mgr); case EPlayerOrbitRequest::BadVerticalAngle:
SetOrbitState(EPlayerOrbitState::OrbitPoint, mgr);
x314_orbitPoint = g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)) * x314_orbitPoint = g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)) *
x34_transform.basis[1] + x34_transform.origin; x34_transform.basis[1] + x34_transform.origin;
break; break;
@ -3964,6 +4046,21 @@ void CPlayer::SetOrbitRequest(EPlayerOrbitRequest req, CStateManager& mgr)
} }
} }
void CPlayer::SetOrbitRequestForTarget(TUniqueId id, EPlayerOrbitRequest req, CStateManager& mgr)
{
switch (x304_orbitState)
{
case EPlayerOrbitState::OrbitObject:
case EPlayerOrbitState::ForcedOrbitObject:
case EPlayerOrbitState::Grapple:
if (id == x310_orbitTargetId)
SetOrbitRequest(req, mgr);
break;
default:
break;
}
}
bool CPlayer::InGrappleJumpCooldown() const bool CPlayer::InGrappleJumpCooldown() const
{ {
if (x258_movementState == EPlayerMovementState::OnGround) if (x258_movementState == EPlayerMovementState::OnGround)
@ -3980,17 +4077,17 @@ void CPlayer::PreventFallingCameraPitch()
void CPlayer::OrbitCarcass(CStateManager& mgr) void CPlayer::OrbitCarcass(CStateManager& mgr)
{ {
if (x304_orbitState == EPlayerOrbitState::One) if (x304_orbitState == EPlayerOrbitState::OrbitObject)
{ {
x308_orbitType = EPlayerOrbitType::Two; x308_orbitType = EPlayerOrbitType::Default;
SetOrbitState(EPlayerOrbitState::Three, mgr); SetOrbitState(EPlayerOrbitState::OrbitCarcass, mgr);
} }
} }
void CPlayer::OrbitPoint(EPlayerOrbitType type, CStateManager& mgr) void CPlayer::OrbitPoint(EPlayerOrbitType type, CStateManager& mgr)
{ {
x308_orbitType = type; x308_orbitType = type;
SetOrbitState(EPlayerOrbitState::Two, mgr); SetOrbitState(EPlayerOrbitState::OrbitPoint, mgr);
SetOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); SetOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
} }
@ -4005,10 +4102,10 @@ void CPlayer::SetOrbitState(EPlayerOrbitState state, CStateManager& mgr)
CFirstPersonCamera* cam = mgr.GetCameraManager()->GetFirstPersonCamera(); CFirstPersonCamera* cam = mgr.GetCameraManager()->GetFirstPersonCamera();
switch (x304_orbitState) switch (x304_orbitState)
{ {
case EPlayerOrbitState::One: case EPlayerOrbitState::OrbitObject:
cam->SetLockCamera(false); cam->SetLockCamera(false);
break; break;
case EPlayerOrbitState::Three: case EPlayerOrbitState::OrbitCarcass:
{ {
cam->SetLockCamera(true); cam->SetLockCamera(true);
zeus::CVector3f playerToPoint = x314_orbitPoint - GetTranslation(); zeus::CVector3f playerToPoint = x314_orbitPoint - GetTranslation();
@ -4026,7 +4123,7 @@ void CPlayer::SetOrbitState(EPlayerOrbitState state, CStateManager& mgr)
SetOrbitTargetId(kInvalidUniqueId, mgr); SetOrbitTargetId(kInvalidUniqueId, mgr);
x33c_orbitNextTargetId = kInvalidUniqueId; x33c_orbitNextTargetId = kInvalidUniqueId;
break; break;
case EPlayerOrbitState::Two: case EPlayerOrbitState::OrbitPoint:
SetOrbitTargetId(kInvalidUniqueId, mgr); SetOrbitTargetId(kInvalidUniqueId, mgr);
x33c_orbitNextTargetId = kInvalidUniqueId; x33c_orbitNextTargetId = kInvalidUniqueId;
break; break;
@ -4054,12 +4151,12 @@ void CPlayer::UpdateOrbitPosition(float dist, CStateManager& mgr)
{ {
switch (x304_orbitState) switch (x304_orbitState)
{ {
case EPlayerOrbitState::Two: case EPlayerOrbitState::OrbitPoint:
case EPlayerOrbitState::Three: case EPlayerOrbitState::OrbitCarcass:
SetOrbitPosition(dist, mgr); SetOrbitPosition(dist, mgr);
break; break;
case EPlayerOrbitState::One: case EPlayerOrbitState::OrbitObject:
case EPlayerOrbitState::Four: case EPlayerOrbitState::ForcedOrbitObject:
case EPlayerOrbitState::Grapple: case EPlayerOrbitState::Grapple:
if (TCastToPtr<CActor> act = mgr.ObjectById(x310_orbitTargetId)) if (TCastToPtr<CActor> act = mgr.ObjectById(x310_orbitTargetId))
if (x310_orbitTargetId != kInvalidUniqueId) if (x310_orbitTargetId != kInvalidUniqueId)
@ -4071,7 +4168,7 @@ void CPlayer::UpdateOrbitPosition(float dist, CStateManager& mgr)
void CPlayer::UpdateOrbitZPosition() void CPlayer::UpdateOrbitZPosition()
{ {
if (x304_orbitState == EPlayerOrbitState::Two) if (x304_orbitState == EPlayerOrbitState::OrbitPoint)
{ {
if (std::fabs(x320_orbitVector.z) < g_tweakPlayer->GetOrbitZRange()) if (std::fabs(x320_orbitVector.z) < g_tweakPlayer->GetOrbitZRange())
x314_orbitPoint.z = x320_orbitVector.z + x34_transform.origin.z + GetEyeHeight(); x314_orbitPoint.z = x320_orbitVector.z + x34_transform.origin.z + GetEyeHeight();
@ -4086,7 +4183,8 @@ void CPlayer::UpdateOrbitFixedPosition()
void CPlayer::SetOrbitPosition(float dist, CStateManager& mgr) void CPlayer::SetOrbitPosition(float dist, CStateManager& mgr)
{ {
zeus::CTransform camXf = GetFirstPersonCameraTransform(mgr); zeus::CTransform camXf = GetFirstPersonCameraTransform(mgr);
if (x304_orbitState == EPlayerOrbitState::Two && x30c_orbitRequest == EPlayerOrbitRequest::Seven) if (x304_orbitState == EPlayerOrbitState::OrbitPoint &&
x30c_orbitRequest == EPlayerOrbitRequest::BadVerticalAngle)
camXf = x34_transform; camXf = x34_transform;
zeus::CVector3f fwd = camXf.basis[1]; zeus::CVector3f fwd = camXf.basis[1];
float dot = fwd.normalized().dot(fwd); float dot = fwd.normalized().dot(fwd);
@ -4130,8 +4228,8 @@ void CPlayer::UpdateAimTarget(CStateManager& mgr)
if (g_tweakPlayer->GetAimWhenOrbitingPoint()) if (g_tweakPlayer->GetAimWhenOrbitingPoint())
{ {
if (x304_orbitState == EPlayerOrbitState::One || if (x304_orbitState == EPlayerOrbitState::OrbitObject ||
x304_orbitState == EPlayerOrbitState::Four) x304_orbitState == EPlayerOrbitState::ForcedOrbitObject)
{ {
if (ValidateOrbitTargetId(x310_orbitTargetId, mgr) == EOrbitValidationResult::OK) if (ValidateOrbitTargetId(x310_orbitTargetId, mgr) == EOrbitValidationResult::OK)
ResetAimTargetPrediction(x310_orbitTargetId); ResetAimTargetPrediction(x310_orbitTargetId);
@ -4180,8 +4278,8 @@ bool CPlayer::ValidateAimTargetId(TUniqueId uid, CStateManager& mgr)
if (!act || !act->GetMaterialList().HasMaterial(EMaterialTypes::Target) || !act->GetIsTargetable()) if (!act || !act->GetMaterialList().HasMaterial(EMaterialTypes::Target) || !act->GetIsTargetable())
return false; return false;
if (x304_orbitState == EPlayerOrbitState::One || if (x304_orbitState == EPlayerOrbitState::OrbitObject ||
x304_orbitState == EPlayerOrbitState::Four) x304_orbitState == EPlayerOrbitState::ForcedOrbitObject)
{ {
if (ValidateOrbitTargetId(x310_orbitTargetId, mgr) != EOrbitValidationResult::OK) if (ValidateOrbitTargetId(x310_orbitTargetId, mgr) != EOrbitValidationResult::OK)
{ {
@ -4205,8 +4303,8 @@ bool CPlayer::ValidateAimTargetId(TUniqueId uid, CStateManager& mgr)
vpHHalf + screenPos.y * vpHHalf, vpHHalf + screenPos.y * vpHHalf,
screenPos.z); screenPos.z);
if (WithinOrbitScreenBox(posInBox, x330_orbitZoneMode, x334_orbitType) || if (WithinOrbitScreenBox(posInBox, x330_orbitZoneMode, x334_orbitType) ||
(x330_orbitZoneMode != EPlayerZoneInfo::Zero && (x330_orbitZoneMode != EPlayerZoneInfo::Targeting &&
WithinOrbitScreenBox(posInBox, EPlayerZoneInfo::Zero, x334_orbitType))) WithinOrbitScreenBox(posInBox, EPlayerZoneInfo::Targeting, x334_orbitType)))
{ {
float eyeToAimMag = eyeToAim.magnitude(); float eyeToAimMag = eyeToAim.magnitude();
if (eyeToAimMag <= g_tweakPlayer->GetAimMaxDistance()) if (eyeToAimMag <= g_tweakPlayer->GetAimMaxDistance())
@ -4248,7 +4346,7 @@ bool CPlayer::ValidateObjectForMode(TUniqueId uid, CStateManager& mgr) const
if (GetCombatMode()) if (GetCombatMode())
{ {
if (CHealthInfo* hInfo = act->HealthInfo()) if (CHealthInfo* hInfo = act->HealthInfo(mgr))
{ {
if (hInfo->GetHP() > 0.f) if (hInfo->GetHP() > 0.f)
return true; return true;
@ -4270,7 +4368,7 @@ bool CPlayer::ValidateObjectForMode(TUniqueId uid, CStateManager& mgr) const
if (GetExplorationMode()) if (GetExplorationMode())
{ {
if (!act->HealthInfo()) if (!act->HealthInfo(mgr))
{ {
if (TCastToPtr<CScriptGrapplePoint> point = mgr.ObjectById(uid)) if (TCastToPtr<CScriptGrapplePoint> point = mgr.ObjectById(uid))
{ {
@ -4308,7 +4406,7 @@ TUniqueId CPlayer::FindAimTargetId(CStateManager& mgr)
g_tweakPlayer->GetAimBoxHeight(), dist); g_tweakPlayer->GetAimBoxHeight(), dist);
rstl::reserved_vector<TUniqueId, 1024> nearList; rstl::reserved_vector<TUniqueId, 1024> nearList;
mgr.BuildNearList(nearList, aabb, CMaterialFilter::MakeInclude({EMaterialTypes::Target}), this); mgr.BuildNearList(nearList, aabb, CMaterialFilter::MakeInclude({EMaterialTypes::Target}), this);
return CheckEnemiesAgainstOrbitZone(nearList, EPlayerZoneInfo::Zero, EPlayerZoneType::Ellipse, mgr); return CheckEnemiesAgainstOrbitZone(nearList, EPlayerZoneInfo::Targeting, EPlayerZoneType::Ellipse, mgr);
} }
const zeus::CTransform& CPlayer::GetFirstPersonCameraTransform(const CStateManager& mgr) const const zeus::CTransform& CPlayer::GetFirstPersonCameraTransform(const CStateManager& mgr) const
@ -4752,13 +4850,13 @@ void CPlayer::UpdateOrbitZone(CStateManager& mgr)
{ {
x334_orbitType = EPlayerZoneType::Ellipse; x334_orbitType = EPlayerZoneType::Ellipse;
x338_ = 1; x338_ = 1;
x330_orbitZoneMode = EPlayerZoneInfo::Zero; x330_orbitZoneMode = EPlayerZoneInfo::Targeting;
} }
else else
{ {
x334_orbitType = EPlayerZoneType::Box; x334_orbitType = EPlayerZoneType::Box;
x338_ = 2; x338_ = 2;
x330_orbitZoneMode = EPlayerZoneInfo::One; x330_orbitZoneMode = EPlayerZoneInfo::Scan;
} }
} }
@ -4785,7 +4883,7 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
{ {
if (ValidateAimTargetId(x310_orbitTargetId, mgr)) if (ValidateAimTargetId(x310_orbitTargetId, mgr))
ResetAimTargetPrediction(x310_orbitTargetId); ResetAimTargetPrediction(x310_orbitTargetId);
SetOrbitState(EPlayerOrbitState::One, mgr); SetOrbitState(EPlayerOrbitState::OrbitObject, mgr);
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
} }
} }
@ -4799,15 +4897,15 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
break; break;
case EPlayerOrbitState::Grapple: case EPlayerOrbitState::Grapple:
if (x310_orbitTargetId == kInvalidUniqueId) if (x310_orbitTargetId == kInvalidUniqueId)
BreakGrapple(EPlayerOrbitRequest::Zero, mgr); BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
break; break;
case EPlayerOrbitState::One: case EPlayerOrbitState::OrbitObject:
if (TCastToConstPtr<CScriptGrapplePoint> point = mgr.GetObjectById(x310_orbitTargetId)) if (TCastToConstPtr<CScriptGrapplePoint> point = mgr.GetObjectById(x310_orbitTargetId))
{ {
if (ValidateCurrentOrbitTargetId(mgr) == EOrbitValidationResult::OK) if (ValidateCurrentOrbitTargetId(mgr) == EOrbitValidationResult::OK)
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
else else
BreakGrapple(EPlayerOrbitRequest::Six, mgr); BreakGrapple(EPlayerOrbitRequest::InvalidateTarget, mgr);
} }
else else
{ {
@ -4817,13 +4915,13 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
else if (result == EOrbitValidationResult::BrokenLookAngle) else if (result == EOrbitValidationResult::BrokenLookAngle)
OrbitPoint(EPlayerOrbitType::Far, mgr); OrbitPoint(EPlayerOrbitType::Far, mgr);
else if (result == EOrbitValidationResult::ExtremeHorizonAngle) else if (result == EOrbitValidationResult::ExtremeHorizonAngle)
SetOrbitRequest(EPlayerOrbitRequest::Seven, mgr); SetOrbitRequest(EPlayerOrbitRequest::BadVerticalAngle, mgr);
else else
ActivateOrbitSource(mgr); ActivateOrbitSource(mgr);
} }
UpdateOrbitSelection(input, mgr); UpdateOrbitSelection(input, mgr);
break; break;
case EPlayerOrbitState::Two: case EPlayerOrbitState::OrbitPoint:
if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitObject, input)) if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitObject, input))
{ {
SetOrbitTargetId(FindOrbitTargetId(mgr), mgr); SetOrbitTargetId(FindOrbitTargetId(mgr), mgr);
@ -4831,7 +4929,7 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
{ {
if (ValidateAimTargetId(x310_orbitTargetId, mgr)) if (ValidateAimTargetId(x310_orbitTargetId, mgr))
ResetAimTargetPrediction(x310_orbitTargetId); ResetAimTargetPrediction(x310_orbitTargetId);
SetOrbitState(EPlayerOrbitState::One, mgr); SetOrbitState(EPlayerOrbitState::OrbitObject, mgr);
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
} }
} }
@ -4854,14 +4952,13 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
} }
break; break;
break;
default: default:
break; break;
} }
} }
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
break; break;
case EPlayerOrbitState::Three: case EPlayerOrbitState::OrbitCarcass:
if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitObject, input)) if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitObject, input))
{ {
SetOrbitTargetId(FindOrbitTargetId(mgr), mgr); SetOrbitTargetId(FindOrbitTargetId(mgr), mgr);
@ -4869,13 +4966,13 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
{ {
if (ValidateAimTargetId(x310_orbitTargetId, mgr)) if (ValidateAimTargetId(x310_orbitTargetId, mgr))
ResetAimTargetPrediction(x310_orbitTargetId); ResetAimTargetPrediction(x310_orbitTargetId);
SetOrbitState(EPlayerOrbitState::One, mgr); SetOrbitState(EPlayerOrbitState::OrbitObject, mgr);
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
} }
} }
UpdateOrbitSelection(input, mgr); UpdateOrbitSelection(input, mgr);
break; break;
case EPlayerOrbitState::Four: case EPlayerOrbitState::ForcedOrbitObject:
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
UpdateOrbitSelection(input, mgr); UpdateOrbitSelection(input, mgr);
break; break;
@ -4892,11 +4989,11 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
{ {
switch (x304_orbitState) switch (x304_orbitState)
{ {
case EPlayerOrbitState::One: case EPlayerOrbitState::OrbitObject:
if (TCastToConstPtr<CScriptGrapplePoint> point = mgr.GetObjectById(x310_orbitTargetId)) if (TCastToConstPtr<CScriptGrapplePoint> point = mgr.GetObjectById(x310_orbitTargetId))
BreakGrapple(EPlayerOrbitRequest::Three, mgr); BreakGrapple(EPlayerOrbitRequest::Default, mgr);
else else
SetOrbitRequest(EPlayerOrbitRequest::Zero, mgr); SetOrbitRequest(EPlayerOrbitRequest::StopOrbit, mgr);
break; break;
case EPlayerOrbitState::Grapple: case EPlayerOrbitState::Grapple:
if (!g_tweakPlayer->GetOrbitReleaseBreaksGrapple()) if (!g_tweakPlayer->GetOrbitReleaseBreaksGrapple())
@ -4907,15 +5004,15 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
} }
else else
{ {
BreakGrapple(EPlayerOrbitRequest::Zero, mgr); BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
} }
break; break;
case EPlayerOrbitState::Four: case EPlayerOrbitState::ForcedOrbitObject:
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
UpdateOrbitSelection(input, mgr); UpdateOrbitSelection(input, mgr);
break; break;
default: default:
SetOrbitRequest(EPlayerOrbitRequest::Zero, mgr); SetOrbitRequest(EPlayerOrbitRequest::StopOrbit, mgr);
break; break;
} }
} }
@ -4929,7 +5026,7 @@ void CPlayer::ActivateOrbitSource(CStateManager& mgr)
OrbitCarcass(mgr); OrbitCarcass(mgr);
break; break;
case 1: case 1:
SetOrbitRequest(EPlayerOrbitRequest::Six, mgr); SetOrbitRequest(EPlayerOrbitRequest::InvalidateTarget, mgr);
break; break;
case 2: case 2:
if (x394_orbitingEnemy) if (x394_orbitingEnemy)
@ -4957,7 +5054,7 @@ void CPlayer::UpdateOrbitSelection(const CFinalInput& input, CStateManager& mgr)
SetOrbitTargetId(x33c_orbitNextTargetId, mgr); SetOrbitTargetId(x33c_orbitNextTargetId, mgr);
if (ValidateAimTargetId(x310_orbitTargetId, mgr)) if (ValidateAimTargetId(x310_orbitTargetId, mgr))
ResetAimTargetPrediction(x310_orbitTargetId); ResetAimTargetPrediction(x310_orbitTargetId);
SetOrbitState(EPlayerOrbitState::One, mgr); SetOrbitState(EPlayerOrbitState::OrbitObject, mgr);
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
} }
} }
@ -4969,12 +5066,12 @@ void CPlayer::UpdateOrbitOrientation(CStateManager& mgr)
switch (x304_orbitState) switch (x304_orbitState)
{ {
case EPlayerOrbitState::Two: case EPlayerOrbitState::OrbitPoint:
if (x3dc_inFreeLook) if (x3dc_inFreeLook)
return; return;
case EPlayerOrbitState::One: case EPlayerOrbitState::OrbitObject:
case EPlayerOrbitState::Three: case EPlayerOrbitState::OrbitCarcass:
case EPlayerOrbitState::Four: case EPlayerOrbitState::ForcedOrbitObject:
{ {
zeus::CVector3f playerToPoint = x314_orbitPoint - GetTranslation(); zeus::CVector3f playerToPoint = x314_orbitPoint - GetTranslation();
if (!x374_orbitLockEstablished) if (!x374_orbitLockEstablished)
@ -5005,21 +5102,21 @@ void CPlayer::UpdateOrbitTarget(CStateManager& mgr)
switch (x304_orbitState) switch (x304_orbitState)
{ {
case EPlayerOrbitState::One: case EPlayerOrbitState::OrbitObject:
if (auto* ent = static_cast<const CActor*>(mgr.GetObjectById(x310_orbitTargetId))) if (auto* ent = static_cast<const CActor*>(mgr.GetObjectById(x310_orbitTargetId)))
{ {
if (ent->GetDoTargetDistanceTest() && if (ent->GetDoTargetDistanceTest() &&
(playerToPointMag >= GetOrbitMaxLockDistance(mgr) || playerToPointMag < 0.5f)) (playerToPointMag >= GetOrbitMaxLockDistance(mgr) || playerToPointMag < 0.5f))
{ {
if (playerToPointMag < 0.5f) if (playerToPointMag < 0.5f)
SetOrbitRequest(EPlayerOrbitRequest::Seven, mgr); SetOrbitRequest(EPlayerOrbitRequest::BadVerticalAngle, mgr);
else else
ActivateOrbitSource(mgr); ActivateOrbitSource(mgr);
} }
} }
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
break; break;
case EPlayerOrbitState::Two: case EPlayerOrbitState::OrbitPoint:
{ {
if (g_tweakPlayer->GetOrbitFixedOffset() && if (g_tweakPlayer->GetOrbitFixedOffset() &&
std::fabs(x320_orbitVector.z) > g_tweakPlayer->GetOrbitFixedOffsetZDiff()) std::fabs(x320_orbitVector.z) > g_tweakPlayer->GetOrbitFixedOffsetZDiff())
@ -5027,8 +5124,8 @@ void CPlayer::UpdateOrbitTarget(CStateManager& mgr)
UpdateOrbitFixedPosition(); UpdateOrbitFixedPosition();
return; return;
} }
if (playerToPointMag < CalculateOrbitZBasedDistance(x308_orbitType)) if (playerToPointMag < CalculateOrbitMinDistance(x308_orbitType))
UpdateOrbitPosition(CalculateOrbitZBasedDistance(x308_orbitType), mgr); UpdateOrbitPosition(CalculateOrbitMinDistance(x308_orbitType), mgr);
float maxDist = g_tweakPlayer->GetOrbitMaxDistance(int(x308_orbitType)); float maxDist = g_tweakPlayer->GetOrbitMaxDistance(int(x308_orbitType));
if (playerToPointMag > maxDist) if (playerToPointMag > maxDist)
UpdateOrbitPosition(maxDist, mgr); UpdateOrbitPosition(maxDist, mgr);
@ -5038,17 +5135,17 @@ void CPlayer::UpdateOrbitTarget(CStateManager& mgr)
float angleToPoint = std::asin(zeus::clamp(-1.f, std::fabs(eyeToPoint.z) / eyeToPoint.magnitude(), 1.f)); float angleToPoint = std::asin(zeus::clamp(-1.f, std::fabs(eyeToPoint.z) / eyeToPoint.magnitude(), 1.f));
if ((eyeToPoint.z >= 0.f && angleToPoint >= g_tweakPlayer->GetOrbitUpperAngle()) || if ((eyeToPoint.z >= 0.f && angleToPoint >= g_tweakPlayer->GetOrbitUpperAngle()) ||
(eyeToPoint.z < 0.f && angleToPoint >= g_tweakPlayer->GetOrbitLowerAngle())) (eyeToPoint.z < 0.f && angleToPoint >= g_tweakPlayer->GetOrbitLowerAngle()))
SetOrbitRequest(EPlayerOrbitRequest::Seven, mgr); SetOrbitRequest(EPlayerOrbitRequest::BadVerticalAngle, mgr);
break; break;
} }
case EPlayerOrbitState::Three: case EPlayerOrbitState::OrbitCarcass:
{ {
if (x3dd_lookButtonHeld) if (x3dd_lookButtonHeld)
SetOrbitPosition(x340_, mgr); SetOrbitPosition(x340_, mgr);
if (playerToPointMag < CalculateOrbitZBasedDistance(x308_orbitType)) if (playerToPointMag < CalculateOrbitMinDistance(x308_orbitType))
{ {
UpdateOrbitPosition(CalculateOrbitZBasedDistance(x308_orbitType), mgr); UpdateOrbitPosition(CalculateOrbitMinDistance(x308_orbitType), mgr);
x340_ = CalculateOrbitZBasedDistance(x308_orbitType); x340_ = CalculateOrbitMinDistance(x308_orbitType);
} }
float maxDist = g_tweakPlayer->GetOrbitMaxDistance(int(x308_orbitType)); float maxDist = g_tweakPlayer->GetOrbitMaxDistance(int(x308_orbitType));
if (playerToPointMag > maxDist) if (playerToPointMag > maxDist)
@ -5292,7 +5389,7 @@ void CPlayer::Teleport(const zeus::CTransform& xf, CStateManager& mgr, bool rese
if (resetBallCam) if (resetBallCam)
mgr.GetCameraManager()->GetBallCamera()->Reset(eyeXf, mgr); mgr.GetCameraManager()->GetBallCamera()->Reset(eyeXf, mgr);
ForceGunOrientation(x34_transform, mgr); ForceGunOrientation(x34_transform, mgr);
SetOrbitRequest(EPlayerOrbitRequest::One, mgr); SetOrbitRequest(EPlayerOrbitRequest::Respawn, mgr);
} }
void CPlayer::BombJump(const zeus::CVector3f& pos, CStateManager& mgr) void CPlayer::BombJump(const zeus::CVector3f& pos, CStateManager& mgr)
@ -5585,7 +5682,7 @@ float CPlayer::JumpInput(const CFinalInput& input, CStateManager& mgr)
float CPlayer::TurnInput(const CFinalInput& input) const float CPlayer::TurnInput(const CFinalInput& input) const
{ {
if (x304_orbitState == EPlayerOrbitState::One || x304_orbitState == EPlayerOrbitState::Grapple) if (x304_orbitState == EPlayerOrbitState::OrbitObject || x304_orbitState == EPlayerOrbitState::Grapple)
return 0.f; return 0.f;
if (IsMorphBallTransitioning()) if (IsMorphBallTransitioning())
return 0.f; return 0.f;
@ -5698,7 +5795,7 @@ zeus::CVector3f CPlayer::CalculateLeftStickEdgePosition(float strafeInput, float
bool CPlayer::SidewaysDashAllowed(float strafeInput, float forwardInput, bool CPlayer::SidewaysDashAllowed(float strafeInput, float forwardInput,
const CFinalInput& input, CStateManager& mgr) const const CFinalInput& input, CStateManager& mgr) const
{ {
if (x9c5_28_slidingOnWall || x9c5_29_hitWall || x304_orbitState != EPlayerOrbitState::One) if (x9c5_28_slidingOnWall || x9c5_29_hitWall || x304_orbitState != EPlayerOrbitState::OrbitObject)
return false; return false;
if (g_tweakPlayer->GetDashOnButtonRelease()) if (g_tweakPlayer->GetDashOnButtonRelease())
@ -5778,7 +5875,7 @@ void CPlayer::ComputeDash(const CFinalInput& input, float dt, CStateManager& mgr
{ {
x384_dashTimer += dt; x384_dashTimer += dt;
if (x258_movementState == EPlayerMovementState::OnGround || x384_dashTimer >= x3a0_dashDuration || if (x258_movementState == EPlayerMovementState::OnGround || x384_dashTimer >= x3a0_dashDuration ||
x9c5_28_slidingOnWall || x9c5_29_hitWall || x304_orbitState != EPlayerOrbitState::One) x9c5_28_slidingOnWall || x9c5_29_hitWall || x304_orbitState != EPlayerOrbitState::OrbitObject)
{ {
FinishSidewaysDash(); FinishSidewaysDash();
strafeVel *= strafeInput; strafeVel *= strafeInput;
@ -5837,7 +5934,7 @@ void CPlayer::ComputeMovement(const CFinalInput& input, CStateManager& mgr, floa
turnSpeedMul = g_tweakPlayer->GetFreeLookTurnSpeedMultiplier(); turnSpeedMul = g_tweakPlayer->GetFreeLookTurnSpeedMultiplier();
if (x304_orbitState == EPlayerOrbitState::NoOrbit || if (x304_orbitState == EPlayerOrbitState::NoOrbit ||
(x3dd_lookButtonHeld && x304_orbitState != EPlayerOrbitState::One && (x3dd_lookButtonHeld && x304_orbitState != EPlayerOrbitState::OrbitObject &&
x304_orbitState != EPlayerOrbitState::Grapple)) x304_orbitState != EPlayerOrbitState::Grapple))
{ {
if (std::fabs(zRotateInput) < 0.00001f) if (std::fabs(zRotateInput) < 0.00001f)
@ -5897,10 +5994,10 @@ void CPlayer::ComputeMovement(const CFinalInput& input, CStateManager& mgr, floa
{ {
switch (x304_orbitState) switch (x304_orbitState)
{ {
case EPlayerOrbitState::One: case EPlayerOrbitState::OrbitObject:
case EPlayerOrbitState::Two: case EPlayerOrbitState::OrbitPoint:
case EPlayerOrbitState::Three: case EPlayerOrbitState::OrbitCarcass:
case EPlayerOrbitState::Four: case EPlayerOrbitState::ForcedOrbitObject:
if (!InGrappleJumpCooldown()) if (!InGrappleJumpCooldown())
ComputeDash(input, dt, mgr); ComputeDash(input, dt, mgr);
break; break;
@ -6145,7 +6242,7 @@ void CPlayer::UpdateCinematicState(CStateManager& mgr)
else else
{ {
CPhysicsActor::Stop(); CPhysicsActor::Stop();
SetOrbitRequest(EPlayerOrbitRequest::One, mgr); SetOrbitRequest(EPlayerOrbitRequest::Respawn, mgr);
switch (x2fc_spawnedMorphBallState) switch (x2fc_spawnedMorphBallState)
{ {
case EPlayerMorphBallState::Unmorphed: case EPlayerMorphBallState::Unmorphed:
@ -6208,7 +6305,7 @@ void CPlayer::SetCameraState(EPlayerCameraState camState, CStateManager& stateMg
bool CPlayer::IsEnergyLow(const CStateManager& mgr) const bool CPlayer::IsEnergyLow(const CStateManager& mgr) const
{ {
float lowThreshold = mgr.GetPlayerState()->GetItemCapacity(CPlayerState::EItemType::EnergyTanks) < 4 ? 30.f : 100.f; float lowThreshold = mgr.GetPlayerState()->GetItemCapacity(CPlayerState::EItemType::EnergyTanks) < 4 ? 30.f : 100.f;
return HealthInfo(mgr)->GetHP() < lowThreshold; return GetHealthInfo(mgr)->GetHP() < lowThreshold;
} }
bool CPlayer::ObjectInScanningRange(TUniqueId id, const CStateManager& mgr) const bool CPlayer::ObjectInScanningRange(TUniqueId id, const CStateManager& mgr) const
@ -6377,7 +6474,7 @@ void CPlayer::SetSpawnedMorphBallState(EPlayerMorphBallState state, CStateManage
if (x2fc_spawnedMorphBallState != x2f8_morphBallState) if (x2fc_spawnedMorphBallState != x2f8_morphBallState)
{ {
CPhysicsActor::Stop(); CPhysicsActor::Stop();
SetOrbitRequest(EPlayerOrbitRequest::One, mgr); SetOrbitRequest(EPlayerOrbitRequest::Respawn, mgr);
switch (x2fc_spawnedMorphBallState) switch (x2fc_spawnedMorphBallState)
{ {
case EPlayerMorphBallState::Unmorphed: case EPlayerMorphBallState::Unmorphed:

View File

@ -43,34 +43,34 @@ public:
{ {
Close, Close,
Far, Far,
Two Default
}; };
enum class EPlayerOrbitState enum class EPlayerOrbitState
{ {
NoOrbit, NoOrbit,
One, OrbitObject,
Two, OrbitPoint,
Three, OrbitCarcass,
Four, ForcedOrbitObject, // For CMetroidBeta attack
Grapple Grapple
}; };
enum class EPlayerOrbitRequest enum class EPlayerOrbitRequest
{ {
Zero, StopOrbit,
One, Respawn,
Two, EnterMorphBall,
Three, Default,
Four, Four,
Five, Five,
Six, InvalidateTarget,
Seven, BadVerticalAngle,
Eight, ActivateOrbitSource,
Nine, ProjectileCollide,
Ten, Freeze,
Eleven, DamageOnGrapple,
Twelve LostGrappleLineOfSight
}; };
enum class EOrbitValidationResult enum class EOrbitValidationResult
@ -86,8 +86,8 @@ public:
enum class EPlayerZoneInfo enum class EPlayerZoneInfo
{ {
Zero, Targeting,
One Scan
}; };
enum class EPlayerZoneType enum class EPlayerZoneType
@ -232,12 +232,12 @@ private:
float x300_fallingTime = 0.f; float x300_fallingTime = 0.f;
EPlayerOrbitState x304_orbitState = EPlayerOrbitState::NoOrbit; EPlayerOrbitState x304_orbitState = EPlayerOrbitState::NoOrbit;
EPlayerOrbitType x308_orbitType = EPlayerOrbitType::Close; EPlayerOrbitType x308_orbitType = EPlayerOrbitType::Close;
EPlayerOrbitRequest x30c_orbitRequest = EPlayerOrbitRequest::Three; EPlayerOrbitRequest x30c_orbitRequest = EPlayerOrbitRequest::Default;
TUniqueId x310_orbitTargetId = kInvalidUniqueId; TUniqueId x310_orbitTargetId = kInvalidUniqueId;
zeus::CVector3f x314_orbitPoint; zeus::CVector3f x314_orbitPoint;
zeus::CVector3f x320_orbitVector; zeus::CVector3f x320_orbitVector;
float x32c_orbitModeTimer = 0.f; float x32c_orbitModeTimer = 0.f;
EPlayerZoneInfo x330_orbitZoneMode = EPlayerZoneInfo::Zero; EPlayerZoneInfo x330_orbitZoneMode = EPlayerZoneInfo::Targeting;
EPlayerZoneType x334_orbitType = EPlayerZoneType::Ellipse; EPlayerZoneType x334_orbitType = EPlayerZoneType::Ellipse;
u32 x338_ = 1; u32 x338_ = 1;
TUniqueId x33c_orbitNextTargetId = kInvalidUniqueId; TUniqueId x33c_orbitNextTargetId = kInvalidUniqueId;
@ -351,7 +351,7 @@ private:
bool x82c_inLava = false; bool x82c_inLava = false;
TUniqueId x82e_ridingPlatform = kInvalidUniqueId; TUniqueId x82e_ridingPlatform = kInvalidUniqueId;
TUniqueId x830_playerHint = kInvalidUniqueId; TUniqueId x830_playerHint = kInvalidUniqueId;
u32 x834_ = 1000; u32 x834_playerHintPriority = 1000;
rstl::reserved_vector<std::pair<u32, TUniqueId>, 32> x838_playerHints; rstl::reserved_vector<std::pair<u32, TUniqueId>, 32> x838_playerHints;
rstl::reserved_vector<TUniqueId, 32> x93c_playerHintsToRemove; rstl::reserved_vector<TUniqueId, 32> x93c_playerHintsToRemove;
rstl::reserved_vector<TUniqueId, 32> x980_playerHintsToAdd; rstl::reserved_vector<TUniqueId, 32> x980_playerHintsToAdd;
@ -384,7 +384,7 @@ private:
bool x9c6_29_disableInput : 1; bool x9c6_29_disableInput : 1;
bool x9c6_30_newScanScanning : 1; bool x9c6_30_newScanScanning : 1;
bool x9c6_31_overrideRadarRadius : 1; bool x9c6_31_overrideRadarRadius : 1;
bool x9c7_24_ : 1; bool x9c7_24_noDamageLoopSfx : 1;
bool x9c7_25_outOfBallLookAtHintActor : 1; bool x9c7_25_outOfBallLookAtHintActor : 1;
}; };
u32 _dummy = 0; u32 _dummy = 0;
@ -401,7 +401,7 @@ private:
float x9f8_controlDirInterpTime = 0.f; float x9f8_controlDirInterpTime = 0.f;
float x9fc_controlDirInterpDur = 0.f; float x9fc_controlDirInterpDur = 0.f;
TUniqueId xa00_deathPowerBomb = kInvalidUniqueId; TUniqueId xa00_deathPowerBomb = kInvalidUniqueId;
float xa04_ = 0.f; float xa04_preThinkDt = 0.f;
CAssetId xa08_steamTextureId; CAssetId xa08_steamTextureId;
CAssetId xa0c_iceTextureId; CAssetId xa0c_iceTextureId;
u32 xa10_phazonCounter = 0; u32 xa10_phazonCounter = 0;
@ -411,7 +411,7 @@ private:
float xa20_radarXYRadiusOverride = 1.f; float xa20_radarXYRadiusOverride = 1.f;
float xa24_radarZRadiusOverride = 1.f; float xa24_radarZRadiusOverride = 1.f;
float xa28_attachedActorStruggle = 0.f; float xa28_attachedActorStruggle = 0.f;
u32 xa2c_ = 2; int xa2c_damageLoopSfxDelayTicks = 2;
float xa30_samusExhaustedVoiceTimer = 4.f; float xa30_samusExhaustedVoiceTimer = 4.f;
void StartLandingControlFreeze(); void StartLandingControlFreeze();
@ -422,7 +422,7 @@ private:
void InitializeBallTransition(); void InitializeBallTransition();
float UpdateCameraBob(float dt, CStateManager& mgr); float UpdateCameraBob(float dt, CStateManager& mgr);
float GetAcceleration() const; float GetAcceleration() const;
float CalculateOrbitZBasedDistance(EPlayerOrbitType type) const; float CalculateOrbitMinDistance(EPlayerOrbitType type) const;
public: public:
CPlayer(TUniqueId, const zeus::CTransform&, const zeus::CAABox&, CAssetId w1, const zeus::CVector3f&, float, float, CPlayer(TUniqueId, const zeus::CTransform&, const zeus::CAABox&, CAssetId w1, const zeus::CVector3f&, float, float,
@ -444,20 +444,20 @@ public:
void AsyncLoadSuit(CStateManager& mgr); void AsyncLoadSuit(CStateManager& mgr);
void LoadAnimationTokens(); void LoadAnimationTokens();
bool HasTransitionBeamModel() const; bool HasTransitionBeamModel() const;
virtual bool CanRenderUnsorted(CStateManager& mgr) const; bool CanRenderUnsorted(const CStateManager& mgr) const;
virtual const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f& v1, const zeus::CVector3f& v2,
const CDamageInfo& info) const; const CDamageInfo& info) const;
virtual const CDamageVulnerability* GetDamageVulnerability() const; const CDamageVulnerability* GetDamageVulnerability() const;
virtual zeus::CVector3f GetHomingPosition(CStateManager& mgr, float) const; zeus::CVector3f GetHomingPosition(const CStateManager& mgr, float) const;
zeus::CVector3f GetAimPosition(CStateManager& mgr, float) const; zeus::CVector3f GetAimPosition(const CStateManager& mgr, float) const;
virtual void FluidFXThink(CActor::EFluidState, CScriptWater& water, CStateManager& mgr); void FluidFXThink(CActor::EFluidState, CScriptWater& water, CStateManager& mgr);
zeus::CVector3f GetDamageLocationWR() const { return x564_damageLocation; } zeus::CVector3f GetDamageLocationWR() const { return x564_damageLocation; }
float GetPrevDamageAmount() const { return x560_prevDamageAmt; } float GetPrevDamageAmount() const { return x560_prevDamageAmt; }
float GetDamageAmount() const { return x55c_damageAmt; } float GetDamageAmount() const { return x55c_damageAmt; }
bool WasDamaged() const { return x558_wasDamaged; } bool WasDamaged() const { return x558_wasDamaged; }
void TakeDamage(bool, const zeus::CVector3f&, float, EWeaponType, CStateManager& mgr); void TakeDamage(bool, const zeus::CVector3f&, float, EWeaponType, CStateManager& mgr);
void Accept(IVisitor& visitor); void Accept(IVisitor& visitor);
static CHealthInfo* HealthInfo(const CStateManager& mgr); CHealthInfo* HealthInfo(CStateManager& mgr);
bool IsUnderBetaMetroidAttack(CStateManager& mgr) const; bool IsUnderBetaMetroidAttack(CStateManager& mgr) const;
rstl::optional_object<zeus::CAABox> GetTouchBounds() const; rstl::optional_object<zeus::CAABox> GetTouchBounds() const;
void Touch(CActor& actor, CStateManager& mgr); void Touch(CActor& actor, CStateManager& mgr);
@ -541,6 +541,7 @@ public:
void BeginGrapple(zeus::CVector3f&, CStateManager& mgr); void BeginGrapple(zeus::CVector3f&, CStateManager& mgr);
void BreakGrapple(EPlayerOrbitRequest, CStateManager& mgr); void BreakGrapple(EPlayerOrbitRequest, CStateManager& mgr);
void SetOrbitRequest(EPlayerOrbitRequest req, CStateManager& mgr); void SetOrbitRequest(EPlayerOrbitRequest req, CStateManager& mgr);
void SetOrbitRequestForTarget(TUniqueId id, EPlayerOrbitRequest req, CStateManager& mgr);
bool InGrappleJumpCooldown() const; bool InGrappleJumpCooldown() const;
void PreventFallingCameraPitch(); void PreventFallingCameraPitch();
void OrbitCarcass(CStateManager&); void OrbitCarcass(CStateManager&);

View File

@ -116,7 +116,7 @@ void CScriptActor::Think(float dt, CStateManager& mgr)
} }
} }
if (!x2e2_25_dead && HealthInfo()->GetHP() <= 0.f) if (!x2e2_25_dead && HealthInfo(mgr)->GetHP() <= 0.f)
{ {
x2e2_25_dead = true; x2e2_25_dead = true;
SendScriptMsgs(EScriptObjectState::Dead, mgr, EScriptObjectMessage::None); SendScriptMsgs(EScriptObjectState::Dead, mgr, EScriptObjectMessage::None);

View File

@ -43,7 +43,7 @@ public:
rstl::optional_object<zeus::CAABox> GetTouchBounds() const; rstl::optional_object<zeus::CAABox> GetTouchBounds() const;
void Touch(CActor&, CStateManager&); void Touch(CActor&, CStateManager&);
const CDamageVulnerability* GetDamageVulnerability() const { return &x268_damageVulnerability; } const CDamageVulnerability* GetDamageVulnerability() const { return &x268_damageVulnerability; }
CHealthInfo* HealthInfo() { return &x260_currentHealth; } CHealthInfo* HealthInfo(CStateManager&) { return &x260_currentHealth; }
}; };
} }

View File

@ -32,6 +32,7 @@ public:
float GetThermalHeat() const { return x40_thermalHeat; } float GetThermalHeat() const { return x40_thermalHeat; }
float GetXRayFogDistance() const { return x44_xrayFogDistance; } float GetXRayFogDistance() const { return x44_xrayFogDistance; }
float GetWorldLightingLevel() const { return x48_worldLightingLevel; } float GetWorldLightingLevel() const { return x48_worldLightingLevel; }
EPhazonType GetPhazonType() const { return x50_phazon; }
}; };
} }

View File

@ -60,7 +60,7 @@ public:
void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const; void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const;
void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum); void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum);
const CDamageVulnerability* GetDamageVulnerability() const { return &x174_dVuln; } const CDamageVulnerability* GetDamageVulnerability() const { return &x174_dVuln; }
CHealthInfo* HealthInfo() { return &x16c_hInfo; } CHealthInfo* HealthInfo(CStateManager&) { return &x16c_hInfo; }
void Think(float, CStateManager&); void Think(float, CStateManager&);
rstl::optional_object<zeus::CAABox> GetTouchBounds() const; rstl::optional_object<zeus::CAABox> GetTouchBounds() const;
}; };

View File

@ -1,6 +1,9 @@
#include "CScriptPlayerHint.hpp" #include "CScriptPlayerHint.hpp"
#include "CActorParameters.hpp" #include "CActorParameters.hpp"
#include "TCastTo.hpp" #include "TCastTo.hpp"
#include "CStateManager.hpp"
#include "CPlayer.hpp"
#include "MP1/World/CMetroidPrimeRelay.hpp"
namespace urde namespace urde
{ {
@ -16,4 +19,77 @@ void CScriptPlayerHint::Accept(IVisitor& visit)
visit.Visit(this); visit.Visit(this);
} }
void CScriptPlayerHint::AddToObjectList(TUniqueId uid)
{
for (TUniqueId existId : xe8_objectList)
if (uid == existId)
return;
if (xe8_objectList.size() != 8)
xe8_objectList.push_back(uid);
}
void CScriptPlayerHint::RemoveFromObjectList(TUniqueId uid)
{
for (auto it = xe8_objectList.begin() ; it != xe8_objectList.end() ; ++it)
{
if (*it == uid)
{
xe8_objectList.erase(it);
return;
}
}
}
void CScriptPlayerHint::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr)
{
switch (msg)
{
case EScriptObjectMessage::Deactivate:
case EScriptObjectMessage::Deleted:
RemoveFromObjectList(sender);
mgr.GetPlayer().AddToPlayerHintRemoveList(GetUniqueId(), mgr);
xfc_deactivated = true;
break;
case EScriptObjectMessage::Increment:
x108_mpId = kInvalidUniqueId;
if ((x104_overrideFlags & 0x4000) != 0)
{
for (const SConnection& conn : x20_conns)
{
if (conn.x0_state != EScriptObjectState::Play)
continue;
x108_mpId = mgr.GetIdForScript(conn.x8_objId);
if (TCastToConstPtr<MP1::CMetroidPrimeRelay> mpRelay = mgr.GetObjectById(x108_mpId))
{
x108_mpId = mpRelay->GetMetroidPrimeExoId();
break;
}
}
}
break;
default:
break;
}
if (x30_24_active)
{
switch (msg)
{
case EScriptObjectMessage::Increment:
AddToObjectList(sender);
mgr.GetPlayer().AddToPlayerHintAddList(GetUniqueId(), mgr);
xfc_deactivated = false;
break;
case EScriptObjectMessage::Decrement:
RemoveFromObjectList(sender);
mgr.GetPlayer().AddToPlayerHintRemoveList(GetUniqueId(), mgr);
break;
default:
break;
}
}
CActor::AcceptScriptMsg(msg, sender, mgr);
}
} }

View File

@ -12,14 +12,17 @@ class CScriptPlayerHint : public CActor
bool xfc_deactivated = false; bool xfc_deactivated = false;
u32 x100_priority; u32 x100_priority;
u32 x104_overrideFlags; u32 x104_overrideFlags;
TUniqueId x108_actor = kInvalidUniqueId; TUniqueId x108_mpId = kInvalidUniqueId;
void AddToObjectList(TUniqueId uid);
void RemoveFromObjectList(TUniqueId uid);
public: public:
CScriptPlayerHint(TUniqueId uid, const std::string& name, const CEntityInfo& info, CScriptPlayerHint(TUniqueId uid, const std::string& name, const CEntityInfo& info,
const zeus::CTransform& xf, bool active, u32 priority, u32 overrideFlags); const zeus::CTransform& xf, bool active, u32 priority, u32 overrideFlags);
void Accept(IVisitor& visit); void Accept(IVisitor& visit);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
u32 GetPriority() const { return x100_priority; } u32 GetPriority() const { return x100_priority; }
u32 GetOverrideFlags() const { return x104_overrideFlags; } u32 GetOverrideFlags() const { return x104_overrideFlags; }
TUniqueId GetActorId() const { return x108_actor; } TUniqueId GetActorId() const { return x108_mpId; }
void ClearObjectList() { xe8_objectList.clear(); } void ClearObjectList() { xe8_objectList.clear(); }
void SetDeactivated() { xfc_deactivated = true; } void SetDeactivated() { xfc_deactivated = true; }
}; };

View File

@ -294,7 +294,7 @@ void CScriptTrigger::Touch(CActor& act, CStateManager& mgr)
{ {
mgr.SendScriptMsg(x8_uid, mgr.GetEditorIdForUniqueId(x8_uid), EScriptObjectMessage::Deactivate, mgr.SendScriptMsg(x8_uid, mgr.GetEditorIdForUniqueId(x8_uid), EScriptObjectMessage::Deactivate,
EScriptObjectState::Entered); EScriptObjectState::Entered);
if (act.HealthInfo() && x100_damageInfo.GetDamage() > 0.f) if (act.HealthInfo(mgr) && x100_damageInfo.GetDamage() > 0.f)
{ {
mgr.ApplyDamage(x8_uid, act.GetUniqueId(), x8_uid, x100_damageInfo, mgr.ApplyDamage(x8_uid, act.GetUniqueId(), x8_uid, x100_damageInfo,
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {0ull}), CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {0ull}),
@ -302,9 +302,9 @@ void CScriptTrigger::Touch(CActor& act, CStateManager& mgr)
} }
} }
if ((x12c_flags & ETriggerFlags::KillOnEnter) != ETriggerFlags::None && act.HealthInfo()) if ((x12c_flags & ETriggerFlags::KillOnEnter) != ETriggerFlags::None && act.HealthInfo(mgr))
{ {
CHealthInfo* hInfo = act.HealthInfo(); CHealthInfo* hInfo = act.HealthInfo(mgr);
mgr.ApplyDamage( mgr.ApplyDamage(
x8_uid, act.GetUniqueId(), x8_uid, {sktonOHurtWeaponMode, 10.f * hInfo->GetHP(), 0.f, 0.f}, x8_uid, act.GetUniqueId(), x8_uid, {sktonOHurtWeaponMode, 10.f * hInfo->GetHP(), 0.f, 0.f},
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {0ull}), zeus::CVector3f::skZero); CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {0ull}), zeus::CVector3f::skZero);

View File

@ -72,6 +72,7 @@
#include "CScriptRoomAcoustics.hpp" #include "CScriptRoomAcoustics.hpp"
#include "CScriptControllerAction.hpp" #include "CScriptControllerAction.hpp"
#include "CScriptPlayerHint.hpp" #include "CScriptPlayerHint.hpp"
#include "MP1/World/CMetroidPrimeRelay.hpp"
#include "CPatternedInfo.hpp" #include "CPatternedInfo.hpp"
#include "CSimplePool.hpp" #include "CSimplePool.hpp"
#include "Collision/CCollidableOBBTreeGroup.hpp" #include "Collision/CCollidableOBBTreeGroup.hpp"
@ -429,7 +430,8 @@ CEntity* ScriptLoader::LoadActor(CStateManager& mgr, CInputStream& in, int propC
aabb = data.GetBounds(head.x10_transform.getRotation()); aabb = data.GetBounds(head.x10_transform.getRotation());
return new CScriptActor(mgr.AllocateUniqueId(), head.x0_name, info, head.x10_transform, std::move(data), aabb, mass, return new CScriptActor(mgr.AllocateUniqueId(), head.x0_name, info, head.x10_transform, std::move(data), aabb, mass,
zMomentum, list, hInfo, dVuln, actParms, looping, active, w2, f3, b6, castsShadow, xposeRotate, b9); zMomentum, list, hInfo, dVuln, actParms, looping, active, w2, f3, b6, castsShadow,
xposeRotate, b9);
} }
CEntity* ScriptLoader::LoadWaypoint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) CEntity* ScriptLoader::LoadWaypoint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
@ -2395,7 +2397,33 @@ CEntity* ScriptLoader::LoadMetroidPrimeStage2(CStateManager& mgr, CInputStream&
CEntity* ScriptLoader::LoadMetroidPrimeStage1(CStateManager& mgr, CInputStream& in, int propCount, CEntity* ScriptLoader::LoadMetroidPrimeStage1(CStateManager& mgr, CInputStream& in, int propCount,
const CEntityInfo& info) const CEntityInfo& info)
{ {
return nullptr; if (!EnsurePropertyCount(propCount, 22, "MetroidPrimeStage1"))
return nullptr;
u32 version = in.readUint32Big();
if (version != 3)
return nullptr;
SScaledActorHead aHead = LoadScaledActorHead(in, mgr);
bool active = in.readBool();
float f1 = in.readFloatBig();
float f2 = in.readFloatBig();
float f3 = in.readFloatBig();
u32 w1 = in.readUint32Big();
bool b1 = in.readBool();
u32 w2 = in.readUint32Big();
CHealthInfo hInfo1(in);
CHealthInfo hInfo2(in);
u32 w3 = in.readUint32Big();
rstl::reserved_vector<MP1::SPrimeExoRoomParameters, 4> roomParms;
for (int i=0 ; i<4 ; ++i)
roomParms.emplace_back(in);
u32 w4 = in.readUint32Big();
u32 w5 = in.readUint32Big();
MP1::SPrimeExoParameters primeParms(in);
return new MP1::CMetroidPrimeRelay(mgr.AllocateUniqueId(), aHead.x0_name, info, active,
aHead.x10_transform, aHead.x40_scale, std::move(primeParms),
f1, f2, f3, w1, b1, w2, hInfo1, hInfo2, w3, w4, w5, std::move(roomParms));
} }
CEntity* ScriptLoader::LoadMazeNode(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) CEntity* ScriptLoader::LoadMazeNode(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)

View File

@ -162,7 +162,7 @@ enum class EScriptObjectState
DeathRattle, DeathRattle,
UNKS4, UNKS4,
Damage, Damage,
UNKS6, InvulnDamage,
UNKS5, UNKS5,
Modify, Modify,
ScanStart, ScanStart,
@ -219,7 +219,7 @@ enum class EScriptObjectMessage
RemoveSplashInhabitant = 39, RemoveSplashInhabitant = 39,
InternalMessage18 = 40, InternalMessage18 = 40,
Damage = 41, Damage = 41,
InternalMessage20 = 42, InvulnDamage = 42,
ProjectileCollide = 43, ProjectileCollide = 43,
InSnakeWeed = 44, InSnakeWeed = 44,
InternalMessage26 = 48 InternalMessage26 = 48

2
hecl

@ -1 +1 @@
Subproject commit 29786750653356581a5fc971c4cc8d732a00d776 Subproject commit f63a6a704b1e2ce3534e4d83cb2d2efd78b4966d