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 GetLeftLogicalThreshold() 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 GetOrbitMaxDistance(int type) const=0;
virtual float GetFrozenTimeout() const=0;

View File

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

View File

@ -455,6 +455,61 @@ struct ActorParameters : BigYAML
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<bool> unknown1;
UniqueID32 wpsc;
struct ScriptBeamParameters : 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;
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;
BeamInfo beamInfo;
DamageInfo damageInfo;
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const
@ -79,13 +27,13 @@ struct ScriptBeam : IScriptObject
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc);
ent->name = name + "_wpsc";
}
beamParametrs.nameIDs(pakRouter, name + "_beamp");
beamInfo.nameIDs(pakRouter, name + "_beamInfo");
}
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
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();
/* x268_aimAssistVerticalAngle */
x268_aimAssistVerticalAngle = __dna_reader.readFloatBig();
/* x158_orbitZBasedDistance[0] */
x158_orbitZBasedDistance[0] = __dna_reader.readFloatBig();
/* x158_orbitMinDistance[0] */
x158_orbitMinDistance[0] = __dna_reader.readFloatBig();
/* x164_orbitNormalDistance[0] */
x164_orbitNormalDistance[0] = __dna_reader.readFloatBig();
/* x170_orbitMaxDistance[0] */
x170_orbitMaxDistance[0] = __dna_reader.readFloatBig();
/* x158_orbitZBasedDistance[1] */
x158_orbitZBasedDistance[1] = __dna_reader.readFloatBig();
/* x158_orbitMinDistance[1] */
x158_orbitMinDistance[1] = __dna_reader.readFloatBig();
/* x164_orbitNormalDistance[1] */
x164_orbitNormalDistance[1] = __dna_reader.readFloatBig();
/* x170_orbitMaxDistance[1] */
x170_orbitMaxDistance[1] = __dna_reader.readFloatBig();
/* x158_orbitZBasedDistance[2] */
x158_orbitZBasedDistance[2] = __dna_reader.readFloatBig();
/* x158_orbitMinDistance[2] */
x158_orbitMinDistance[2] = __dna_reader.readFloatBig();
/* x164_orbitNormalDistance[2] */
x164_orbitNormalDistance[2] = __dna_reader.readFloatBig();
/* x170_orbitMaxDistance[2] */
@ -691,20 +691,20 @@ void CTweakPlayer::write(athena::io::IStreamWriter& __dna_writer) const
__dna_writer.writeFloatBig(x264_aimAssistHorizontalAngle);
/* x268_aimAssistVerticalAngle */
__dna_writer.writeFloatBig(x268_aimAssistVerticalAngle);
/* x158_orbitZBasedDistance[0] */
__dna_writer.writeFloatBig(x158_orbitZBasedDistance[0]);
/* x158_orbitMinDistance[0] */
__dna_writer.writeFloatBig(x158_orbitMinDistance[0]);
/* x164_orbitNormalDistance[0] */
__dna_writer.writeFloatBig(x164_orbitNormalDistance[0]);
/* x170_orbitMaxDistance[0] */
__dna_writer.writeFloatBig(x170_orbitMaxDistance[0]);
/* x158_orbitZBasedDistance[1] */
__dna_writer.writeFloatBig(x158_orbitZBasedDistance[1]);
/* x158_orbitMinDistance[1] */
__dna_writer.writeFloatBig(x158_orbitMinDistance[1]);
/* x164_orbitNormalDistance[1] */
__dna_writer.writeFloatBig(x164_orbitNormalDistance[1]);
/* x170_orbitMaxDistance[1] */
__dna_writer.writeFloatBig(x170_orbitMaxDistance[1]);
/* x158_orbitZBasedDistance[2] */
__dna_writer.writeFloatBig(x158_orbitZBasedDistance[2]);
/* x158_orbitMinDistance[2] */
__dna_writer.writeFloatBig(x158_orbitMinDistance[2]);
/* x164_orbitNormalDistance[2] */
__dna_writer.writeFloatBig(x164_orbitNormalDistance[2]);
/* x170_orbitMaxDistance[2] */
@ -1161,16 +1161,16 @@ void CTweakPlayer::read(athena::io::YAMLDocReader& __dna_docin)
x264_aimAssistHorizontalAngle = __dna_docin.readFloat("x264_aimAssistHorizontalAngle");
/* x268_aimAssistVerticalAngle */
x268_aimAssistVerticalAngle = __dna_docin.readFloat("x268_aimAssistVerticalAngle");
/* x158_orbitZBasedDistance */
/* x158_orbitMinDistance */
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_orbitZBasedDistance[0] = __dna_docin.readFloat("x158_orbitZBasedDistance");
/* x158_orbitZBasedDistance[1] */
x158_orbitZBasedDistance[1] = __dna_docin.readFloat("x158_orbitZBasedDistance");
/* x158_orbitZBasedDistance[2] */
x158_orbitZBasedDistance[2] = __dna_docin.readFloat("x158_orbitZBasedDistance");
/* x158_orbitMinDistance[0] */
x158_orbitMinDistance[0] = __dna_docin.readFloat("x158_orbitMinDistance");
/* x158_orbitMinDistance[1] */
x158_orbitMinDistance[1] = __dna_docin.readFloat("x158_orbitMinDistance");
/* x158_orbitMinDistance[2] */
x158_orbitMinDistance[2] = __dna_docin.readFloat("x158_orbitMinDistance");
}
/* x164_orbitNormalDistance */
size_t __x164_Count;
@ -1670,15 +1670,15 @@ void CTweakPlayer::write(athena::io::YAMLDocWriter& __dna_docout) const
__dna_docout.writeFloat("x264_aimAssistHorizontalAngle", x264_aimAssistHorizontalAngle);
/* x268_aimAssistVerticalAngle */
__dna_docout.writeFloat("x268_aimAssistVerticalAngle", x268_aimAssistVerticalAngle);
/* x158_orbitZBasedDistance */
if (auto v = __dna_docout.enterSubVector("x158_orbitZBasedDistance"))
/* x158_orbitMinDistance */
if (auto v = __dna_docout.enterSubVector("x158_orbitMinDistance"))
{
/* x158_orbitZBasedDistance[0] */
__dna_docout.writeFloat("x158_orbitZBasedDistance", x158_orbitZBasedDistance[0]);
/* x158_orbitZBasedDistance[1] */
__dna_docout.writeFloat("x158_orbitZBasedDistance", x158_orbitZBasedDistance[1]);
/* x158_orbitZBasedDistance[2] */
__dna_docout.writeFloat("x158_orbitZBasedDistance", x158_orbitZBasedDistance[2]);
/* x158_orbitMinDistance[0] */
__dna_docout.writeFloat("x158_orbitMinDistance", x158_orbitMinDistance[0]);
/* x158_orbitMinDistance[1] */
__dna_docout.writeFloat("x158_orbitMinDistance", x158_orbitMinDistance[1]);
/* x158_orbitMinDistance[2] */
__dna_docout.writeFloat("x158_orbitMinDistance", x158_orbitMinDistance[2]);
}
/* 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> x150_leftDiv;
Value<float> x154_rightDiv;
Value<float> x158_orbitZBasedDistance[3];
Value<float> x158_orbitMinDistance[3];
Value<float> x164_orbitNormalDistance[3];
Value<float> x170_orbitMaxDistance[3];
Value<float> x17c_;
@ -296,7 +296,7 @@ struct CTweakPlayer : ITweakPlayer
float GetFreeLookDampenFactor() const { return x14c_freeLookDampenFactor; }
float GetLeftLogicalThreshold() const { return x150_leftDiv; }
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 GetOrbitMaxDistance(int type) const { return x170_orbitMaxDistance[type]; }
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)
return;
CHealthInfo* hInfo = actor.HealthInfo();
CHealthInfo* hInfo = actor.HealthInfo(*this);
if (!hInfo)
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)
{
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;
BuildNearList(nearList, aabb, filter, nullptr);
for (TUniqueId id : nearList)
{
CEntity* ent = ObjectById(id);
if (!ent || ent->GetUniqueId() == a1.GetUniqueId() ||
if (!ent || ent->GetUniqueId() == damager.GetUniqueId() ||
ent->GetUniqueId() == senderId ||
ent->GetUniqueId() == a2.GetUniqueId())
ent->GetUniqueId() == damagee.GetUniqueId())
continue;
TestBombHittingWater(a1, a1.GetTranslation(), static_cast<CActor&>(*ent));
if (TestRayDamage(a1.GetTranslation(), static_cast<CActor&>(*ent), nearList))
ApplyRadiusDamage(a1, a1.GetTranslation(), static_cast<CActor&>(*ent), info);
TestBombHittingWater(damager, damager.GetTranslation(), static_cast<CActor&>(*ent));
if (TestRayDamage(damager.GetTranslation(), static_cast<CActor&>(*ent), nearList))
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();
bool alive = false;
if (CHealthInfo* hInfo = a2.HealthInfo())
if (CHealthInfo* hInfo = a2.HealthInfo(*this))
if (hInfo->GetHP() > 0.f)
alive = true;
@ -1451,8 +1452,8 @@ void CStateManager::ApplyRadiusDamage(const CActor& a1, const zeus::CVector3f& p
}
else
{
a2.SendScriptMsgs(EScriptObjectState::UNKS6, *this, EScriptObjectMessage::None);
SendScriptMsg(&a2, a1.GetUniqueId(), EScriptObjectMessage::InternalMessage20);
a2.SendScriptMsgs(EScriptObjectState::InvulnDamage, *this, EScriptObjectMessage::None);
SendScriptMsg(&a2, a1.GetUniqueId(), EScriptObjectMessage::InvulnDamage);
}
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,
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)
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,
const CWeaponMode& weapMode)
{
CHealthInfo* hInfo = damagee.HealthInfo();
CHealthInfo* hInfo = damagee.HealthInfo(*this);
if (!hInfo || dam < 0.f)
return false;
@ -1674,62 +1675,63 @@ bool CStateManager::ApplyLocalDamage(const zeus::CVector3f& vec1, const zeus::CV
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 zeus::CVector3f& vec)
const zeus::CVector3f& knockbackVec)
{
CEntity* ent0 = ObjectById(id0);
CEntity* ent1 = ObjectById(id1);
TCastToPtr<CActor> act0 = ent0;
TCastToPtr<CActor> act1 = ent1;
CEntity* ent0 = ObjectById(damagerId);
CEntity* ent1 = ObjectById(damageeId);
TCastToPtr<CActor> damager = ent0;
TCastToPtr<CActor> damagee = 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 direction = zeus::CVector3f::skRight;
bool alive = hInfo->GetHP() > 0.f;
if (act0)
if (damager)
{
position = act0->GetTranslation();
direction = act0->GetTransform().basis[1];
position = damager->GetTranslation();
direction = damager->GetTransform().basis[1];
}
const CDamageVulnerability* dVuln;
if (act0 || isPlayer)
dVuln = act1->GetDamageVulnerability(position, direction, info);
if (damager || isPlayer)
dVuln = damagee->GetDamageVulnerability(position, direction, info);
else
dVuln = act1->GetDamageVulnerability();
dVuln = damagee->GetDamageVulnerability();
if (info.GetWeaponMode().GetType() == EWeaponType::None ||
dVuln->WeaponHurts(info.GetWeaponMode(), false))
{
if (info.GetDamage() > 0.f)
ApplyLocalDamage(position, direction, *act1, info.GetDamage(), info.GetWeaponMode());
act1->SendScriptMsgs(EScriptObjectState::Damage, *this, EScriptObjectMessage::None);
SendScriptMsg(act1.GetPtr(), id0, EScriptObjectMessage::Damage);
ApplyLocalDamage(position, direction, *damagee, info.GetDamage(), info.GetWeaponMode());
damagee->SendScriptMsgs(EScriptObjectState::Damage, *this, EScriptObjectMessage::None);
SendScriptMsg(damagee.GetPtr(), damagerId, EScriptObjectMessage::Damage);
}
else
{
act1->SendScriptMsgs(EScriptObjectState::UNKS6, *this, EScriptObjectMessage::None);
SendScriptMsg(act1.GetPtr(), id0, EScriptObjectMessage::InternalMessage20);
damagee->SendScriptMsgs(EScriptObjectState::InvulnDamage, *this, EScriptObjectMessage::None);
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;
ApplyKnockBack(*act1, info, *dVuln, delta.normalized(), 0.f);
zeus::CVector3f delta = knockbackVec.isZero() ?
(damagee->GetTranslation() - damager->GetTranslation()) : knockbackVec;
ApplyKnockBack(*damagee, info, *dVuln, delta.normalized(), 0.f);
}
}
if (act0 && info.GetRadius() > 0.f)
ProcessRadiusDamage(*act0, *act1, id2, info, filter);
if (damager && info.GetRadius() > 0.f)
ProcessRadiusDamage(*damager, *damagee, radiusSender, info, filter);
if (TCastToPtr<CWallCrawlerSwarm> swarm = ent1)
if (act0)
swarm->ApplyRadiusDamage(act0->GetTranslation(), info, *this);
if (damager)
swarm->ApplyRadiusDamage(damager->GetTranslation(), info, *this);
}
return false;

View File

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

View File

@ -104,8 +104,8 @@ void CFirstPersonCamera::UpdateTransform(CStateManager& mgr, float dt)
player->GetCameraBob()->SetCameraBobTransform(zeus::CTransform::Identity());
}
if (player->GetOrbitState() == CPlayer::EPlayerOrbitState::Four ||
player->GetOrbitState() == CPlayer::EPlayerOrbitState::One)
if (player->GetOrbitState() == CPlayer::EPlayerOrbitState::ForcedOrbitObject ||
player->GetOrbitState() == CPlayer::EPlayerOrbitState::OrbitObject)
{
const CActor* act = TCastToConstPtr<CActor>(mgr.GetObjectById(player->x310_orbitTargetId));
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->GetOrbitState() == CPlayer::EPlayerOrbitState::Four ||
player->GetOrbitState() == CPlayer::EPlayerOrbitState::One)
if (player->GetOrbitState() == CPlayer::EPlayerOrbitState::ForcedOrbitObject ||
player->GetOrbitState() == CPlayer::EPlayerOrbitState::OrbitObject)
{
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));
}
}
else if (player->GetOrbitState() == CPlayer::EPlayerOrbitState::Two ||
player->GetOrbitState() == CPlayer::EPlayerOrbitState::Three)
else if (player->GetOrbitState() == CPlayer::EPlayerOrbitState::OrbitPoint ||
player->GetOrbitState() == CPlayer::EPlayerOrbitState::OrbitCarcass)
{
dt *= g_tweakPlayer->GetOrbitCameraSpeed();
CalculateGunFollowOrientationAndTransform(gunXf, qGun, dt, rVec);

View File

@ -3,10 +3,36 @@
namespace urde
{
zeus::CVector3f CSteeringBehaviors::ProjectOrbitalPosition(const zeus::CVector3f&, const zeus::CVector3f&,
const zeus::CVector3f&, float)
zeus::CVector3f
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
{
public:
static zeus::CVector3f ProjectOrbitalPosition(const zeus::CVector3f&, const zeus::CVector3f&,
const zeus::CVector3f&, float);
static zeus::CVector3f ProjectOrbitalPosition(const zeus::CVector3f& pos, const zeus::CVector3f& vel,
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);
}
CHealthInfo* CCollisionActor::HealthInfo() { return &x28c_healthInfo; }
CHealthInfo* CCollisionActor::HealthInfo(CStateManager&) { return &x28c_healthInfo; }
const CDamageVulnerability* CCollisionActor::GetDamageVulnerability() const { return &x294_damageVuln; }

View File

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

View File

@ -494,7 +494,7 @@ void CHudDecoInterfaceXRay::SetFrameColorValue(float v)
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);
else
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());
if (TCastToConstPtr<CActor> act = bossEnt)
{
if (const CHealthInfo* hInfo = act->GetHealthInfo())
if (const CHealthInfo* hInfo = act->GetHealthInfo(mgr))
{
float bossEnergy = std::ceil(hInfo->GetHP());
x2b4_bossEnergyIntf->SetBossParams(true, g_MainStringTable->GetString(mgr.GetBossStringIdx()),

View File

@ -5,6 +5,7 @@ set(MP1_WORLD_SOURCES
CSpacePirate.hpp CSpacePirate.cpp
CBabygoth.hpp CBabygoth.cpp
CMetroidPrimeRelay.hpp CMetroidPrimeRelay.cpp
CMetroidPrimeExo.hpp CMetroidPrimeExo.cpp
CActorContraption.hpp CActorContraption.cpp
CThardusRockProjectile.hpp CThardusRockProjectile.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,
Hot = 12,
Unused1 = 13,
Unused2 = 14
OrangePhazon = 14
};
}
#endif // __URDE_WEAPONCOMMON_HPP__

View File

@ -101,7 +101,7 @@ void CActor::CalculateRenderBounds()
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; }

View File

@ -108,7 +108,7 @@ public:
virtual void Render(const CStateManager&) const {}
virtual bool CanRenderUnsorted(const CStateManager&) const { return false; }
virtual void CalculateRenderBounds();
virtual CHealthInfo* HealthInfo();
virtual CHealthInfo* HealthInfo(CStateManager&);
virtual const CDamageVulnerability* GetDamageVulnerability() const;
virtual const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f&,
const CDamageInfo&) const;
@ -174,7 +174,8 @@ public:
bool CanDrawStatic() const;
bool GetE7_29() const { return xe7_29_; }
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; }
void SetCalculateLighting(bool c);
float GetAverageAnimVelocity(int anim) const;

View File

@ -46,7 +46,7 @@ public:
const CStateMachine* GetStateMachine() const;
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 KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType, bool, float)=0;
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
{
if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::Unused2)
if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::OrangePhazon)
return false;
if (mode.IsInstantKill())
return true;
@ -198,7 +198,7 @@ bool CDamageVulnerability::WeaponHurts(const CWeaponMode& mode, bool ignoreDirec
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;
if (mode.IsInstantKill())
return true;
@ -237,7 +237,7 @@ bool CDamageVulnerability::WeaponHits(const CWeaponMode& mode, bool checkDirect)
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;
if (mode.IsInstantKill())

View File

@ -143,7 +143,7 @@ public:
void GetTouchedHalfPipeRecently() const {}
void SetTouchedHalfPipeRecently(bool) {}
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&) {}
bool IsInFrustum(const zeus::CFrustum&) const { return false; }
void ComputeLiftForces(const zeus::CVector3f&, const zeus::CVector3f&, const CStateManager&) {}

View File

@ -23,6 +23,7 @@
#include "CHUDBillboardEffect.hpp"
#include "Audio/CStreamAudioManager.hpp"
#include "CScriptPlayerHint.hpp"
#include "CScriptAreaAttributes.hpp"
namespace urde
{
@ -201,7 +202,7 @@ void CPlayer::TransitionToMorphBallState(float dt, CStateManager& mgr)
ballCam->SetFovInterpolation(mgr.GetCameraManager()->GetFirstPersonCamera()->GetFov(),
CCameraManager::ThirdPersonFOV(), 1.f, 0.f);
}
SetOrbitRequest(EPlayerOrbitRequest::Two, mgr);
SetOrbitRequest(EPlayerOrbitRequest::EnterMorphBall, mgr);
x490_gun->CancelFiring(mgr);
HolsterGun(mgr);
}
@ -724,10 +725,10 @@ float CPlayer::GetAcceleration() const
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) *
g_tweakPlayer->GetOrbitZBasedDistance(int(type));
g_tweakPlayer->GetOrbitMinDistance(int(type));
}
void CPlayer::PostUpdate(float dt, CStateManager& mgr)
@ -813,7 +814,7 @@ bool CPlayer::HasTransitionBeamModel() const
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 CDamageInfo& info) const
@ -829,14 +830,14 @@ const CDamageVulnerability* CPlayer::GetDamageVulnerability() const
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)
return x34_transform.origin + PredictMotion(dt).x0_translation;
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;
if (dt > 0.f)
@ -844,7 +845,7 @@ zeus::CVector3f CPlayer::GetAimPosition(CStateManager& mgr, float dt) const
if (x304_orbitState == EPlayerOrbitState::NoOrbit)
ret += PredictMotion(dt).x0_translation;
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)
@ -949,7 +950,7 @@ void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location,
switch (type)
{
case EWeaponType::Phazon:
case EWeaponType::Unused2:
case EWeaponType::OrangePhazon:
damageLoopSfx = 3114;
damageSamusVoiceSfx = 1653;
break;
@ -992,7 +993,7 @@ void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location,
doRumble = true;
}
if (damageLoopSfx && !x9c7_24_ && x2ac_surfaceRestraint >= ESurfaceRestraints::Ice)
if (damageLoopSfx && !x9c7_24_noDamageLoopSfx && xa2c_damageLoopSfxDelayTicks >= 2)
{
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);
x788_damageLoopSfxId = suitDamageSfx;
xa2c_ = 0;
xa2c_damageLoopSfxDelayTicks = 0;
doRumble = true;
}
@ -1035,7 +1036,7 @@ void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location,
}
if (x3b8_grappleState != EGrappleState::None)
BreakGrapple(EPlayerOrbitRequest::Eleven, mgr);
BreakGrapple(EPlayerOrbitRequest::DamageOnGrapple, mgr);
}
void CPlayer::Accept(IVisitor& visitor)
@ -1043,7 +1044,7 @@ void CPlayer::Accept(IVisitor& visitor)
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
{
@ -1156,7 +1157,7 @@ bool CPlayer::ValidateScanning(const CFinalInput& input, CStateManager& mgr)
{
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))
{
@ -1606,7 +1607,7 @@ void CPlayer::ComputeFreeLook(const CFinalInput& input)
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 ||
(x3b8_grappleState != EGrappleState::None && x3b8_grappleState != EGrappleState::Firing))
{
@ -2141,9 +2142,9 @@ void CPlayer::Freeze(CStateManager& stateMgr, CAssetId steamTxtr, u16 sfx, CAsse
CPhysicsActor::Stop();
ClearForcesAndTorques();
if (x3b8_grappleState != EGrappleState::None)
BreakGrapple(EPlayerOrbitRequest::Ten, stateMgr);
BreakGrapple(EPlayerOrbitRequest::Freeze, stateMgr);
else
SetOrbitRequest(EPlayerOrbitRequest::Ten, stateMgr);
SetOrbitRequest(EPlayerOrbitRequest::Freeze, stateMgr);
AddMaterial(EMaterialTypes::Immovable, stateMgr);
xa08_steamTextureId = steamTxtr;
@ -2260,12 +2261,95 @@ void CPlayer::UpdateWaterSurfaceCameraBias(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)
{
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()
@ -2329,11 +2413,10 @@ void CPlayer::AddToPlayerHintRemoveList(TUniqueId id, CStateManager& mgr)
{
if (TCastToPtr<CScriptPlayerHint> hint = mgr.ObjectById(id))
{
bool alreadyAdded = false;
for (TUniqueId existId : x93c_playerHintsToRemove)
if (id == existId)
return;
if (!alreadyAdded && x93c_playerHintsToRemove.size() != 32)
if (x93c_playerHintsToRemove.size() != 32)
x93c_playerHintsToRemove.push_back(id);
}
}
@ -2342,11 +2425,10 @@ void CPlayer::AddToPlayerHintAddList(TUniqueId id, CStateManager& mgr)
{
if (TCastToPtr<CScriptPlayerHint> hint = mgr.ObjectById(id))
{
bool alreadyAdded = false;
for (TUniqueId existId : x980_playerHintsToAdd)
if (id == existId)
return;
if (!alreadyAdded && x980_playerHintsToAdd.size() != 32)
if (x980_playerHintsToAdd.size() != 32)
x980_playerHintsToAdd.push_back(id);
}
}
@ -2355,11 +2437,10 @@ void CPlayer::DeactivatePlayerHint(TUniqueId id, CStateManager& mgr)
{
if (TCastToPtr<CScriptPlayerHint> hint = mgr.ObjectById(id))
{
bool alreadyAdded = false;
for (TUniqueId existId : x93c_playerHintsToRemove)
if (id == existId)
return;
if (!alreadyAdded && x93c_playerHintsToRemove.size() != 32)
if (x93c_playerHintsToRemove.size() != 32)
{
x93c_playerHintsToRemove.push_back(id);
hint->ClearObjectList();
@ -2432,7 +2513,7 @@ void CPlayer::UpdatePlayerHints(CStateManager& mgr)
if ((needsNewHint || removedHint) && x838_playerHints.empty())
{
x830_playerHint = kInvalidUniqueId;
x834_ = 1000;
x834_playerHintPriority = 1000;
ResetPlayerHintState();
return;
}
@ -2455,14 +2536,14 @@ void CPlayer::UpdatePlayerHints(CStateManager& mgr)
if (!foundHintInArea)
{
x830_playerHint = kInvalidUniqueId;
x834_ = 1000;
x834_playerHintPriority = 1000;
ResetPlayerHintState();
}
if (foundHint != nullptr && foundHintInArea && x830_playerHint != foundHint->GetUniqueId())
{
x830_playerHint = foundHint->GetUniqueId();
x834_ = foundHint->GetPriority();
x834_playerHintPriority = foundHint->GetPriority();
if (SetAreaPlayerHint(*foundHint, mgr))
DeactivatePlayerHint(x830_playerHint, mgr);
}
@ -2647,7 +2728,7 @@ void CPlayer::PreThink(float dt, CStateManager& mgr)
x55c_damageAmt = 0.f;
x560_prevDamageAmt = 0.f;
x564_damageLocation = zeus::CVector3f::skZero;
xa04_ = dt;
xa04_preThinkDt = dt;
}
static const u16 skPlayerLandSfxSoft[] =
@ -2812,7 +2893,7 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState
break;
case EScriptObjectMessage::ProjectileCollide:
x378_orbitPreventionTimer = g_tweakPlayer->GetOrbitPreventionTime();
SetOrbitRequest(EPlayerOrbitRequest::Nine, mgr);
SetOrbitRequest(EPlayerOrbitRequest::ProjectileCollide, mgr);
break;
case EScriptObjectMessage::AddPlatformRider:
x82e_ridingPlatform = sender;
@ -3642,7 +3723,7 @@ void CPlayer::ApplyGrappleForces(const CFinalInput& input, CStateManager& mgr, f
}
else
{
BreakGrapple(EPlayerOrbitRequest::Six, mgr);
BreakGrapple(EPlayerOrbitRequest::InvalidateTarget, mgr);
}
break;
}
@ -3726,7 +3807,7 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
{
if (!g_tweakPlayer->GetGrappleJumpMode() && x3d8_grappleJumpTimeout <= 0.f)
ApplyGrappleJump(mgr);
BreakGrapple(EPlayerOrbitRequest::Zero, mgr);
BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
}
}
break;
@ -3735,7 +3816,7 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
}
break;
case EPlayerOrbitState::One:
case EPlayerOrbitState::OrbitObject:
if (playerToPoint.canBeNormalized())
{
CRayCastResult result =
@ -3815,14 +3896,14 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
{
if (x304_orbitState >= EPlayerOrbitState::Grapple)
return;
if (x304_orbitState != EPlayerOrbitState::One)
if (x304_orbitState != EPlayerOrbitState::OrbitObject)
return;
}
else
{
if (!point)
{
BreakGrapple(EPlayerOrbitRequest::Three, mgr);
BreakGrapple(EPlayerOrbitRequest::Default, mgr);
return;
}
@ -3834,7 +3915,7 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
x3d8_grappleJumpTimeout -= input.DeltaTime();
if (x3d8_grappleJumpTimeout <= 0.f)
{
BreakGrapple(EPlayerOrbitRequest::Zero, mgr);
BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
SetMoveState(EPlayerMovementState::StartingJump, mgr);
ComputeMovement(input, mgr, input.DeltaTime());
PreventFallingCameraPitch();
@ -3859,14 +3940,14 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
{
SetMoveState(EPlayerMovementState::StartingJump, mgr);
ComputeMovement(input, mgr, input.DeltaTime());
BreakGrapple(EPlayerOrbitRequest::Zero, mgr);
BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
PreventFallingCameraPitch();
}
break;
case EGrappleState::Firing:
case EGrappleState::Pull:
if (!ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input))
BreakGrapple(EPlayerOrbitRequest::Zero, mgr);
BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
break;
default:
break;
@ -3885,7 +3966,7 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
LineOfSightFilter);
if (result.IsValid())
{
BreakGrapple(EPlayerOrbitRequest::Twelve, mgr);
BreakGrapple(EPlayerOrbitRequest::LostGrappleLineOfSight, mgr);
}
}
return;
@ -3893,7 +3974,7 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
if (x490_gun->GetGrappleArm().BeamActive() && g_tweakPlayer->GetGrappleJumpMode() == 1 &&
!ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input))
BreakGrapple(EPlayerOrbitRequest::Zero, mgr);
BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
}
void CPlayer::ApplyGrappleJump(CStateManager& mgr)
@ -3951,10 +4032,11 @@ void CPlayer::SetOrbitRequest(EPlayerOrbitRequest req, CStateManager& mgr)
x30c_orbitRequest = req;
switch (req)
{
case EPlayerOrbitRequest::Eight:
case EPlayerOrbitRequest::Seven:
SetOrbitState(EPlayerOrbitState::Two, mgr);
case EPlayerOrbitRequest::ActivateOrbitSource:
ActivateOrbitSource(mgr);
break;
case EPlayerOrbitRequest::BadVerticalAngle:
SetOrbitState(EPlayerOrbitState::OrbitPoint, mgr);
x314_orbitPoint = g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)) *
x34_transform.basis[1] + x34_transform.origin;
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
{
if (x258_movementState == EPlayerMovementState::OnGround)
@ -3980,17 +4077,17 @@ void CPlayer::PreventFallingCameraPitch()
void CPlayer::OrbitCarcass(CStateManager& mgr)
{
if (x304_orbitState == EPlayerOrbitState::One)
if (x304_orbitState == EPlayerOrbitState::OrbitObject)
{
x308_orbitType = EPlayerOrbitType::Two;
SetOrbitState(EPlayerOrbitState::Three, mgr);
x308_orbitType = EPlayerOrbitType::Default;
SetOrbitState(EPlayerOrbitState::OrbitCarcass, mgr);
}
}
void CPlayer::OrbitPoint(EPlayerOrbitType type, CStateManager& mgr)
{
x308_orbitType = type;
SetOrbitState(EPlayerOrbitState::Two, mgr);
SetOrbitState(EPlayerOrbitState::OrbitPoint, 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();
switch (x304_orbitState)
{
case EPlayerOrbitState::One:
case EPlayerOrbitState::OrbitObject:
cam->SetLockCamera(false);
break;
case EPlayerOrbitState::Three:
case EPlayerOrbitState::OrbitCarcass:
{
cam->SetLockCamera(true);
zeus::CVector3f playerToPoint = x314_orbitPoint - GetTranslation();
@ -4026,7 +4123,7 @@ void CPlayer::SetOrbitState(EPlayerOrbitState state, CStateManager& mgr)
SetOrbitTargetId(kInvalidUniqueId, mgr);
x33c_orbitNextTargetId = kInvalidUniqueId;
break;
case EPlayerOrbitState::Two:
case EPlayerOrbitState::OrbitPoint:
SetOrbitTargetId(kInvalidUniqueId, mgr);
x33c_orbitNextTargetId = kInvalidUniqueId;
break;
@ -4054,12 +4151,12 @@ void CPlayer::UpdateOrbitPosition(float dist, CStateManager& mgr)
{
switch (x304_orbitState)
{
case EPlayerOrbitState::Two:
case EPlayerOrbitState::Three:
case EPlayerOrbitState::OrbitPoint:
case EPlayerOrbitState::OrbitCarcass:
SetOrbitPosition(dist, mgr);
break;
case EPlayerOrbitState::One:
case EPlayerOrbitState::Four:
case EPlayerOrbitState::OrbitObject:
case EPlayerOrbitState::ForcedOrbitObject:
case EPlayerOrbitState::Grapple:
if (TCastToPtr<CActor> act = mgr.ObjectById(x310_orbitTargetId))
if (x310_orbitTargetId != kInvalidUniqueId)
@ -4071,7 +4168,7 @@ void CPlayer::UpdateOrbitPosition(float dist, CStateManager& mgr)
void CPlayer::UpdateOrbitZPosition()
{
if (x304_orbitState == EPlayerOrbitState::Two)
if (x304_orbitState == EPlayerOrbitState::OrbitPoint)
{
if (std::fabs(x320_orbitVector.z) < g_tweakPlayer->GetOrbitZRange())
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)
{
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;
zeus::CVector3f fwd = camXf.basis[1];
float dot = fwd.normalized().dot(fwd);
@ -4130,8 +4228,8 @@ void CPlayer::UpdateAimTarget(CStateManager& mgr)
if (g_tweakPlayer->GetAimWhenOrbitingPoint())
{
if (x304_orbitState == EPlayerOrbitState::One ||
x304_orbitState == EPlayerOrbitState::Four)
if (x304_orbitState == EPlayerOrbitState::OrbitObject ||
x304_orbitState == EPlayerOrbitState::ForcedOrbitObject)
{
if (ValidateOrbitTargetId(x310_orbitTargetId, mgr) == EOrbitValidationResult::OK)
ResetAimTargetPrediction(x310_orbitTargetId);
@ -4180,8 +4278,8 @@ bool CPlayer::ValidateAimTargetId(TUniqueId uid, CStateManager& mgr)
if (!act || !act->GetMaterialList().HasMaterial(EMaterialTypes::Target) || !act->GetIsTargetable())
return false;
if (x304_orbitState == EPlayerOrbitState::One ||
x304_orbitState == EPlayerOrbitState::Four)
if (x304_orbitState == EPlayerOrbitState::OrbitObject ||
x304_orbitState == EPlayerOrbitState::ForcedOrbitObject)
{
if (ValidateOrbitTargetId(x310_orbitTargetId, mgr) != EOrbitValidationResult::OK)
{
@ -4205,8 +4303,8 @@ bool CPlayer::ValidateAimTargetId(TUniqueId uid, CStateManager& mgr)
vpHHalf + screenPos.y * vpHHalf,
screenPos.z);
if (WithinOrbitScreenBox(posInBox, x330_orbitZoneMode, x334_orbitType) ||
(x330_orbitZoneMode != EPlayerZoneInfo::Zero &&
WithinOrbitScreenBox(posInBox, EPlayerZoneInfo::Zero, x334_orbitType)))
(x330_orbitZoneMode != EPlayerZoneInfo::Targeting &&
WithinOrbitScreenBox(posInBox, EPlayerZoneInfo::Targeting, x334_orbitType)))
{
float eyeToAimMag = eyeToAim.magnitude();
if (eyeToAimMag <= g_tweakPlayer->GetAimMaxDistance())
@ -4248,7 +4346,7 @@ bool CPlayer::ValidateObjectForMode(TUniqueId uid, CStateManager& mgr) const
if (GetCombatMode())
{
if (CHealthInfo* hInfo = act->HealthInfo())
if (CHealthInfo* hInfo = act->HealthInfo(mgr))
{
if (hInfo->GetHP() > 0.f)
return true;
@ -4270,7 +4368,7 @@ bool CPlayer::ValidateObjectForMode(TUniqueId uid, CStateManager& mgr) const
if (GetExplorationMode())
{
if (!act->HealthInfo())
if (!act->HealthInfo(mgr))
{
if (TCastToPtr<CScriptGrapplePoint> point = mgr.ObjectById(uid))
{
@ -4308,7 +4406,7 @@ TUniqueId CPlayer::FindAimTargetId(CStateManager& mgr)
g_tweakPlayer->GetAimBoxHeight(), dist);
rstl::reserved_vector<TUniqueId, 1024> nearList;
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
@ -4752,13 +4850,13 @@ void CPlayer::UpdateOrbitZone(CStateManager& mgr)
{
x334_orbitType = EPlayerZoneType::Ellipse;
x338_ = 1;
x330_orbitZoneMode = EPlayerZoneInfo::Zero;
x330_orbitZoneMode = EPlayerZoneInfo::Targeting;
}
else
{
x334_orbitType = EPlayerZoneType::Box;
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))
ResetAimTargetPrediction(x310_orbitTargetId);
SetOrbitState(EPlayerOrbitState::One, mgr);
SetOrbitState(EPlayerOrbitState::OrbitObject, mgr);
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
}
}
@ -4799,15 +4897,15 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
break;
case EPlayerOrbitState::Grapple:
if (x310_orbitTargetId == kInvalidUniqueId)
BreakGrapple(EPlayerOrbitRequest::Zero, mgr);
BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
break;
case EPlayerOrbitState::One:
case EPlayerOrbitState::OrbitObject:
if (TCastToConstPtr<CScriptGrapplePoint> point = mgr.GetObjectById(x310_orbitTargetId))
{
if (ValidateCurrentOrbitTargetId(mgr) == EOrbitValidationResult::OK)
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
else
BreakGrapple(EPlayerOrbitRequest::Six, mgr);
BreakGrapple(EPlayerOrbitRequest::InvalidateTarget, mgr);
}
else
{
@ -4817,13 +4915,13 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
else if (result == EOrbitValidationResult::BrokenLookAngle)
OrbitPoint(EPlayerOrbitType::Far, mgr);
else if (result == EOrbitValidationResult::ExtremeHorizonAngle)
SetOrbitRequest(EPlayerOrbitRequest::Seven, mgr);
SetOrbitRequest(EPlayerOrbitRequest::BadVerticalAngle, mgr);
else
ActivateOrbitSource(mgr);
}
UpdateOrbitSelection(input, mgr);
break;
case EPlayerOrbitState::Two:
case EPlayerOrbitState::OrbitPoint:
if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitObject, input))
{
SetOrbitTargetId(FindOrbitTargetId(mgr), mgr);
@ -4831,7 +4929,7 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
{
if (ValidateAimTargetId(x310_orbitTargetId, mgr))
ResetAimTargetPrediction(x310_orbitTargetId);
SetOrbitState(EPlayerOrbitState::One, mgr);
SetOrbitState(EPlayerOrbitState::OrbitObject, 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);
}
break;
break;
default:
break;
}
}
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
break;
case EPlayerOrbitState::Three:
case EPlayerOrbitState::OrbitCarcass:
if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitObject, input))
{
SetOrbitTargetId(FindOrbitTargetId(mgr), mgr);
@ -4869,13 +4966,13 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
{
if (ValidateAimTargetId(x310_orbitTargetId, mgr))
ResetAimTargetPrediction(x310_orbitTargetId);
SetOrbitState(EPlayerOrbitState::One, mgr);
SetOrbitState(EPlayerOrbitState::OrbitObject, mgr);
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
}
}
UpdateOrbitSelection(input, mgr);
break;
case EPlayerOrbitState::Four:
case EPlayerOrbitState::ForcedOrbitObject:
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
UpdateOrbitSelection(input, mgr);
break;
@ -4892,11 +4989,11 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
{
switch (x304_orbitState)
{
case EPlayerOrbitState::One:
case EPlayerOrbitState::OrbitObject:
if (TCastToConstPtr<CScriptGrapplePoint> point = mgr.GetObjectById(x310_orbitTargetId))
BreakGrapple(EPlayerOrbitRequest::Three, mgr);
BreakGrapple(EPlayerOrbitRequest::Default, mgr);
else
SetOrbitRequest(EPlayerOrbitRequest::Zero, mgr);
SetOrbitRequest(EPlayerOrbitRequest::StopOrbit, mgr);
break;
case EPlayerOrbitState::Grapple:
if (!g_tweakPlayer->GetOrbitReleaseBreaksGrapple())
@ -4907,15 +5004,15 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
}
else
{
BreakGrapple(EPlayerOrbitRequest::Zero, mgr);
BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr);
}
break;
case EPlayerOrbitState::Four:
case EPlayerOrbitState::ForcedOrbitObject:
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
UpdateOrbitSelection(input, mgr);
break;
default:
SetOrbitRequest(EPlayerOrbitRequest::Zero, mgr);
SetOrbitRequest(EPlayerOrbitRequest::StopOrbit, mgr);
break;
}
}
@ -4929,7 +5026,7 @@ void CPlayer::ActivateOrbitSource(CStateManager& mgr)
OrbitCarcass(mgr);
break;
case 1:
SetOrbitRequest(EPlayerOrbitRequest::Six, mgr);
SetOrbitRequest(EPlayerOrbitRequest::InvalidateTarget, mgr);
break;
case 2:
if (x394_orbitingEnemy)
@ -4957,7 +5054,7 @@ void CPlayer::UpdateOrbitSelection(const CFinalInput& input, CStateManager& mgr)
SetOrbitTargetId(x33c_orbitNextTargetId, mgr);
if (ValidateAimTargetId(x310_orbitTargetId, mgr))
ResetAimTargetPrediction(x310_orbitTargetId);
SetOrbitState(EPlayerOrbitState::One, mgr);
SetOrbitState(EPlayerOrbitState::OrbitObject, mgr);
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
}
}
@ -4969,12 +5066,12 @@ void CPlayer::UpdateOrbitOrientation(CStateManager& mgr)
switch (x304_orbitState)
{
case EPlayerOrbitState::Two:
case EPlayerOrbitState::OrbitPoint:
if (x3dc_inFreeLook)
return;
case EPlayerOrbitState::One:
case EPlayerOrbitState::Three:
case EPlayerOrbitState::Four:
case EPlayerOrbitState::OrbitObject:
case EPlayerOrbitState::OrbitCarcass:
case EPlayerOrbitState::ForcedOrbitObject:
{
zeus::CVector3f playerToPoint = x314_orbitPoint - GetTranslation();
if (!x374_orbitLockEstablished)
@ -5005,21 +5102,21 @@ void CPlayer::UpdateOrbitTarget(CStateManager& mgr)
switch (x304_orbitState)
{
case EPlayerOrbitState::One:
case EPlayerOrbitState::OrbitObject:
if (auto* ent = static_cast<const CActor*>(mgr.GetObjectById(x310_orbitTargetId)))
{
if (ent->GetDoTargetDistanceTest() &&
(playerToPointMag >= GetOrbitMaxLockDistance(mgr) || playerToPointMag < 0.5f))
{
if (playerToPointMag < 0.5f)
SetOrbitRequest(EPlayerOrbitRequest::Seven, mgr);
SetOrbitRequest(EPlayerOrbitRequest::BadVerticalAngle, mgr);
else
ActivateOrbitSource(mgr);
}
}
UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr);
break;
case EPlayerOrbitState::Two:
case EPlayerOrbitState::OrbitPoint:
{
if (g_tweakPlayer->GetOrbitFixedOffset() &&
std::fabs(x320_orbitVector.z) > g_tweakPlayer->GetOrbitFixedOffsetZDiff())
@ -5027,8 +5124,8 @@ void CPlayer::UpdateOrbitTarget(CStateManager& mgr)
UpdateOrbitFixedPosition();
return;
}
if (playerToPointMag < CalculateOrbitZBasedDistance(x308_orbitType))
UpdateOrbitPosition(CalculateOrbitZBasedDistance(x308_orbitType), mgr);
if (playerToPointMag < CalculateOrbitMinDistance(x308_orbitType))
UpdateOrbitPosition(CalculateOrbitMinDistance(x308_orbitType), mgr);
float maxDist = g_tweakPlayer->GetOrbitMaxDistance(int(x308_orbitType));
if (playerToPointMag > maxDist)
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));
if ((eyeToPoint.z >= 0.f && angleToPoint >= g_tweakPlayer->GetOrbitUpperAngle()) ||
(eyeToPoint.z < 0.f && angleToPoint >= g_tweakPlayer->GetOrbitLowerAngle()))
SetOrbitRequest(EPlayerOrbitRequest::Seven, mgr);
SetOrbitRequest(EPlayerOrbitRequest::BadVerticalAngle, mgr);
break;
}
case EPlayerOrbitState::Three:
case EPlayerOrbitState::OrbitCarcass:
{
if (x3dd_lookButtonHeld)
SetOrbitPosition(x340_, mgr);
if (playerToPointMag < CalculateOrbitZBasedDistance(x308_orbitType))
if (playerToPointMag < CalculateOrbitMinDistance(x308_orbitType))
{
UpdateOrbitPosition(CalculateOrbitZBasedDistance(x308_orbitType), mgr);
x340_ = CalculateOrbitZBasedDistance(x308_orbitType);
UpdateOrbitPosition(CalculateOrbitMinDistance(x308_orbitType), mgr);
x340_ = CalculateOrbitMinDistance(x308_orbitType);
}
float maxDist = g_tweakPlayer->GetOrbitMaxDistance(int(x308_orbitType));
if (playerToPointMag > maxDist)
@ -5292,7 +5389,7 @@ void CPlayer::Teleport(const zeus::CTransform& xf, CStateManager& mgr, bool rese
if (resetBallCam)
mgr.GetCameraManager()->GetBallCamera()->Reset(eyeXf, mgr);
ForceGunOrientation(x34_transform, mgr);
SetOrbitRequest(EPlayerOrbitRequest::One, mgr);
SetOrbitRequest(EPlayerOrbitRequest::Respawn, 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
{
if (x304_orbitState == EPlayerOrbitState::One || x304_orbitState == EPlayerOrbitState::Grapple)
if (x304_orbitState == EPlayerOrbitState::OrbitObject || x304_orbitState == EPlayerOrbitState::Grapple)
return 0.f;
if (IsMorphBallTransitioning())
return 0.f;
@ -5698,7 +5795,7 @@ zeus::CVector3f CPlayer::CalculateLeftStickEdgePosition(float strafeInput, float
bool CPlayer::SidewaysDashAllowed(float strafeInput, float forwardInput,
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;
if (g_tweakPlayer->GetDashOnButtonRelease())
@ -5778,7 +5875,7 @@ void CPlayer::ComputeDash(const CFinalInput& input, float dt, CStateManager& mgr
{
x384_dashTimer += dt;
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();
strafeVel *= strafeInput;
@ -5837,7 +5934,7 @@ void CPlayer::ComputeMovement(const CFinalInput& input, CStateManager& mgr, floa
turnSpeedMul = g_tweakPlayer->GetFreeLookTurnSpeedMultiplier();
if (x304_orbitState == EPlayerOrbitState::NoOrbit ||
(x3dd_lookButtonHeld && x304_orbitState != EPlayerOrbitState::One &&
(x3dd_lookButtonHeld && x304_orbitState != EPlayerOrbitState::OrbitObject &&
x304_orbitState != EPlayerOrbitState::Grapple))
{
if (std::fabs(zRotateInput) < 0.00001f)
@ -5897,10 +5994,10 @@ void CPlayer::ComputeMovement(const CFinalInput& input, CStateManager& mgr, floa
{
switch (x304_orbitState)
{
case EPlayerOrbitState::One:
case EPlayerOrbitState::Two:
case EPlayerOrbitState::Three:
case EPlayerOrbitState::Four:
case EPlayerOrbitState::OrbitObject:
case EPlayerOrbitState::OrbitPoint:
case EPlayerOrbitState::OrbitCarcass:
case EPlayerOrbitState::ForcedOrbitObject:
if (!InGrappleJumpCooldown())
ComputeDash(input, dt, mgr);
break;
@ -6145,7 +6242,7 @@ void CPlayer::UpdateCinematicState(CStateManager& mgr)
else
{
CPhysicsActor::Stop();
SetOrbitRequest(EPlayerOrbitRequest::One, mgr);
SetOrbitRequest(EPlayerOrbitRequest::Respawn, mgr);
switch (x2fc_spawnedMorphBallState)
{
case EPlayerMorphBallState::Unmorphed:
@ -6208,7 +6305,7 @@ void CPlayer::SetCameraState(EPlayerCameraState camState, CStateManager& stateMg
bool CPlayer::IsEnergyLow(const CStateManager& mgr) const
{
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
@ -6377,7 +6474,7 @@ void CPlayer::SetSpawnedMorphBallState(EPlayerMorphBallState state, CStateManage
if (x2fc_spawnedMorphBallState != x2f8_morphBallState)
{
CPhysicsActor::Stop();
SetOrbitRequest(EPlayerOrbitRequest::One, mgr);
SetOrbitRequest(EPlayerOrbitRequest::Respawn, mgr);
switch (x2fc_spawnedMorphBallState)
{
case EPlayerMorphBallState::Unmorphed:

View File

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

View File

@ -43,7 +43,7 @@ public:
rstl::optional_object<zeus::CAABox> GetTouchBounds() const;
void Touch(CActor&, CStateManager&);
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 GetXRayFogDistance() const { return x44_xrayFogDistance; }
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 PreRender(CStateManager& mgr, const zeus::CFrustum& frustum);
const CDamageVulnerability* GetDamageVulnerability() const { return &x174_dVuln; }
CHealthInfo* HealthInfo() { return &x16c_hInfo; }
CHealthInfo* HealthInfo(CStateManager&) { return &x16c_hInfo; }
void Think(float, CStateManager&);
rstl::optional_object<zeus::CAABox> GetTouchBounds() const;
};

View File

@ -1,6 +1,9 @@
#include "CScriptPlayerHint.hpp"
#include "CActorParameters.hpp"
#include "TCastTo.hpp"
#include "CStateManager.hpp"
#include "CPlayer.hpp"
#include "MP1/World/CMetroidPrimeRelay.hpp"
namespace urde
{
@ -16,4 +19,77 @@ void CScriptPlayerHint::Accept(IVisitor& visit)
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;
u32 x100_priority;
u32 x104_overrideFlags;
TUniqueId x108_actor = kInvalidUniqueId;
TUniqueId x108_mpId = kInvalidUniqueId;
void AddToObjectList(TUniqueId uid);
void RemoveFromObjectList(TUniqueId uid);
public:
CScriptPlayerHint(TUniqueId uid, const std::string& name, const CEntityInfo& info,
const zeus::CTransform& xf, bool active, u32 priority, u32 overrideFlags);
void Accept(IVisitor& visit);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
u32 GetPriority() const { return x100_priority; }
u32 GetOverrideFlags() const { return x104_overrideFlags; }
TUniqueId GetActorId() const { return x108_actor; }
TUniqueId GetActorId() const { return x108_mpId; }
void ClearObjectList() { xe8_objectList.clear(); }
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,
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,
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(
x8_uid, act.GetUniqueId(), x8_uid, {sktonOHurtWeaponMode, 10.f * hInfo->GetHP(), 0.f, 0.f},
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {0ull}), zeus::CVector3f::skZero);

View File

@ -72,6 +72,7 @@
#include "CScriptRoomAcoustics.hpp"
#include "CScriptControllerAction.hpp"
#include "CScriptPlayerHint.hpp"
#include "MP1/World/CMetroidPrimeRelay.hpp"
#include "CPatternedInfo.hpp"
#include "CSimplePool.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());
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)
@ -2395,7 +2397,33 @@ CEntity* ScriptLoader::LoadMetroidPrimeStage2(CStateManager& mgr, CInputStream&
CEntity* ScriptLoader::LoadMetroidPrimeStage1(CStateManager& mgr, CInputStream& in, int propCount,
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)

View File

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

2
hecl

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