mirror of https://github.com/AxioDL/metaforce.git
Initial PAL/JP/Trilogy imps, various cleanup
This commit is contained in:
parent
3487ea92c7
commit
582d8a6999
|
@ -21,6 +21,9 @@ struct ITweakPlayerRes : ITweak {
|
|||
ResId x18_minesBreakSecondTopIcon;
|
||||
ResId x1c_minesBreakSecondBottomIcon;
|
||||
|
||||
ResId rs5_mapArrowUp;
|
||||
ResId rs5_mapArrowDown;
|
||||
|
||||
/* N, U, UL, L, DL, D, DR, R, UR */
|
||||
std::array<ResId, 9> x24_lStick;
|
||||
std::array<ResId, 9> x4c_cStick;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "PATH.hpp"
|
||||
|
||||
#include "DataSpec/DNACommon/Tweaks/TweakWriter.hpp"
|
||||
#include "DataSpec/DNACommon/URDEVersionInfo.hpp"
|
||||
#include "Tweaks/CTweakPlayerRes.hpp"
|
||||
#include "Tweaks/CTweakGunRes.hpp"
|
||||
#include "Tweaks/CTweakPlayer.hpp"
|
||||
|
@ -237,8 +238,8 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssoci
|
|||
if (animResInfo.evntId.isValid()) {
|
||||
PAK::Entry* evntEnt = (PAK::Entry*)m_pak.lookupEntry(animResInfo.evntId);
|
||||
evntEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}_evnt"), id, animResInfo.name);
|
||||
charAssoc.m_cskrToCharacter[animResInfo.evntId] =
|
||||
std::make_pair(entry.id, fmt::format(FMT_STRING("{}_{}.evnt.yaml"), animResInfo.name, animResInfo.evntId));
|
||||
charAssoc.m_cskrToCharacter[animResInfo.evntId] = std::make_pair(
|
||||
entry.id, fmt::format(FMT_STRING("{}_{}.evnt.yaml"), animResInfo.name, animResInfo.evntId));
|
||||
}
|
||||
}
|
||||
} else if (entry.type == FOURCC('MREA')) {
|
||||
|
@ -275,8 +276,8 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
|
|||
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry).getParentPath();
|
||||
|
||||
if (mlvl.worldNameId.isValid())
|
||||
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath,
|
||||
fmt::format(FMT_STRING(_SYS_STR("!name_{}.yaml")), mlvl.worldNameId));
|
||||
pathOverrides[mlvl.worldNameId] =
|
||||
hecl::ProjectPath(mlvlDirPath, fmt::format(FMT_STRING(_SYS_STR("!name_{}.yaml")), mlvl.worldNameId));
|
||||
|
||||
for (const MLVL::Area& area : mlvl.areas) {
|
||||
{
|
||||
|
@ -292,8 +293,8 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
|
|||
|
||||
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
|
||||
if (area.areaNameId.isValid())
|
||||
pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath,
|
||||
fmt::format(FMT_STRING(_SYS_STR("!name_{}.yaml")), area.areaNameId));
|
||||
pathOverrides[area.areaNameId] =
|
||||
hecl::ProjectPath(areaDirPath, fmt::format(FMT_STRING(_SYS_STR("!name_{}.yaml")), area.areaNameId));
|
||||
}
|
||||
|
||||
if (mlvl.worldMap.isValid()) {
|
||||
|
@ -383,8 +384,14 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, con
|
|||
std::string catalogueName;
|
||||
std::string name = pak.bestEntryName(pakNode, entry, catalogueName);
|
||||
if (!catalogueName.empty()) {
|
||||
if (catalogueName == "PlayerRes"sv)
|
||||
return {ExtractTweak<CTweakPlayerRes>, {_SYS_STR(".yaml")}};
|
||||
if (catalogueName == "PlayerRes"sv) {
|
||||
if (isCurrentSpecWii() || getCurrentRegion() == ERegion::PAL || getCurrentRegion() == ERegion::NTSC_J) {
|
||||
/* We need to use the new rep for these tweaks */
|
||||
return {ExtractTweak<CTweakPlayerRes<true>>, {_SYS_STR(".yaml")}};
|
||||
}
|
||||
/* We need to use the old rep for these tweaks */
|
||||
return {ExtractTweak<CTweakPlayerRes<false>>, {_SYS_STR(".yaml")}};
|
||||
}
|
||||
if (catalogueName == "GunRes"sv)
|
||||
return {ExtractTweak<CTweakGunRes>, {_SYS_STR(".yaml")}};
|
||||
if (catalogueName == "Player"sv)
|
||||
|
@ -395,8 +402,14 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, con
|
|||
return {ExtractTweak<CTweakSlideShow>, {_SYS_STR(".yaml")}};
|
||||
if (catalogueName == "Game"sv)
|
||||
return {ExtractTweak<CTweakGame>, {_SYS_STR(".yaml")}};
|
||||
if (catalogueName == "Targeting"sv)
|
||||
return {ExtractTweak<CTweakTargeting>, {_SYS_STR(".yaml")}};
|
||||
if (catalogueName == "Targeting"sv) {
|
||||
if (isCurrentSpecWii() || getCurrentRegion() == ERegion::PAL || getCurrentRegion() == ERegion::NTSC_J) {
|
||||
/* We need to use the new rep for these tweaks */
|
||||
return {ExtractTweak<CTweakTargeting<true>>, {_SYS_STR(".yaml")}};
|
||||
}
|
||||
/* We need to use the old rep for these tweaks */
|
||||
return {ExtractTweak<CTweakTargeting<false>>, {_SYS_STR(".yaml")}};
|
||||
}
|
||||
if (catalogueName == "Gui"sv)
|
||||
return {ExtractTweak<CTweakGui>, {_SYS_STR(".yaml")}};
|
||||
if (catalogueName == "AutoMapper"sv)
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
namespace DataSpec::DNAMP1 {
|
||||
|
||||
struct CTweakPlayerRes final : ITweakPlayerRes {
|
||||
template <bool NewRep>
|
||||
struct AT_SPECIALIZE_PARMS(true, false) CTweakPlayerRes final : ITweakPlayerRes {
|
||||
AT_DECL_DNA_YAML
|
||||
|
||||
String<-1> m_saveStationIcon;
|
||||
|
@ -16,6 +17,9 @@ struct CTweakPlayerRes final : ITweakPlayerRes {
|
|||
String<-1> m_minesBreakSecondTopIcon;
|
||||
String<-1> m_minesBreakSecondBottomIcon;
|
||||
|
||||
String<AT_DNA_COUNT(NewRep==true ? -1 : 0)> m_mapArrowDown;
|
||||
String<AT_DNA_COUNT(NewRep==true ? -1 : 0)> m_mapArrowUp;
|
||||
|
||||
String<-1> m_lStickN;
|
||||
String<-1> m_lStickU;
|
||||
String<-1> m_lStickUL;
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
#include "../../DNACommon/Tweaks/ITweakTargeting.hpp"
|
||||
|
||||
namespace DataSpec::DNAMP1 {
|
||||
struct CTweakTargeting final : public ITweakTargeting {
|
||||
template<bool NewRep>
|
||||
struct AT_SPECIALIZE_PARMS(true, false) CTweakTargeting final : public ITweakTargeting {
|
||||
AT_DECL_DNA_YAML
|
||||
Value<atUint32> x4_targetRadiusMode;
|
||||
Value<float> x8_currLockOnExitDuration;
|
||||
|
@ -132,6 +133,69 @@ struct CTweakTargeting final : public ITweakTargeting {
|
|||
Value<float> x220_scanTargetClampMax;
|
||||
Value<float> x224_angularLagSpeed;
|
||||
|
||||
// RS5
|
||||
Vector<float, AT_DNA_COUNT(NewRep == true ? 1 : 0)> x218_;
|
||||
Vector<float, AT_DNA_COUNT(NewRep == true ? 1 : 0)> x21c_;
|
||||
bool x224_ = true;
|
||||
bool x225_ = false;
|
||||
bool x226_ = true;
|
||||
bool x227_ = true;
|
||||
bool x22c_ = true;
|
||||
bool x22d_ = false;
|
||||
bool x22e_ = true;
|
||||
bool x22f_ = true;
|
||||
bool x234_ = true;
|
||||
bool x235_ = false;
|
||||
bool x236_ = true;
|
||||
bool x237_ = true;
|
||||
zeus::CVector3f x23c_ = zeus::skZero3f;
|
||||
|
||||
float x2c8_ = 0.25f;
|
||||
float x2cc_ = 0.35f;
|
||||
zeus::CColor x2d0_ = (zeus::Comp32)0xb6e6ffff;
|
||||
float x2d4_ = 0.39215687f;
|
||||
zeus::CColor x2d8_ = (zeus::Comp32)0xa82a00ff;
|
||||
float x2dc_ = 0.78431374f;
|
||||
zeus::CVector3f x2e0_ = zeus::CVector3f(0.f, 0.f, 0.46f);
|
||||
float x2ec_ = 0.25f;
|
||||
float x2f0_ = 0.25f;
|
||||
float x2f4_ = 120.f;
|
||||
float x2f8_ = 0.25f;
|
||||
float x2fc_ = 3.5f;
|
||||
float x300_ = 0.35f;
|
||||
zeus::CColor x304_ = (zeus::Comp32)0xa82a00ff;
|
||||
float x308_ = 0.78431374f;
|
||||
zeus::CColor x30c_ = (zeus::Comp32)0x89d6ffff;
|
||||
float x310_ = 0.5019608f;
|
||||
float x314_ = 11.25f;
|
||||
float x318_ = 0.25f;
|
||||
float x31c_ = 0.125f;
|
||||
zeus::CColor x320_ = (zeus::Comp32)0xffca28ff;
|
||||
float x324_ = 0.78431374f;
|
||||
zeus::CColor x328_ = (zeus::Comp32)0x89d6ffff;
|
||||
float x32c_ = 0.19607843f;
|
||||
float x330_ = 0.f;
|
||||
float x334_ = 0.25f;
|
||||
float x338_ = 3.f;
|
||||
float x33c_ = 0.25f;
|
||||
float x340_ = 0.25f;
|
||||
float x344_ = 0.25f;
|
||||
float x348_ = 0.25f;
|
||||
float x34c_ = 45.f;
|
||||
float x350_ = 0.5f;
|
||||
float x354_ = 0.65f;
|
||||
float x358_ = 1.5f;
|
||||
float x35c_ = 0.18f;
|
||||
float x360_ = 0.15f;
|
||||
float x364_ = 0.25f;
|
||||
zeus::CColor x368_ = (zeus::Comp32)0x56c1fb9f;
|
||||
zeus::CColor x36c_ = (zeus::Comp32)0x49c3f6a0;
|
||||
zeus::CColor x370_ = (zeus::Comp32)0x49c3f631;
|
||||
zeus::CColor x374_ = (zeus::Comp32)0xff8930ff;
|
||||
zeus::CColor x378_ = (zeus::Comp32)0xff2f28ff;
|
||||
zeus::CColor x37c_ = (zeus::Comp32)0x93e9ffff;
|
||||
zeus::CColor x380_ = (zeus::Comp32)0xff6b60ff;
|
||||
|
||||
CTweakTargeting() = default;
|
||||
CTweakTargeting(athena::io::IStreamReader& r) {
|
||||
this->read(r);
|
||||
|
|
|
@ -39,6 +39,12 @@ static const hecl::SystemChar* MomErr[] = {_SYS_STR("Your metroid is in another
|
|||
|
||||
constexpr uint32_t MomErrCount = std::extent<decltype(MomErr)>::value;
|
||||
|
||||
static ERegion g_CurRegion = ERegion::Invalid;
|
||||
static bool g_CurSpecIsWii = false;
|
||||
|
||||
ERegion getCurrentRegion() { return g_CurRegion; }
|
||||
bool isCurrentSpecWii() { return g_CurSpecIsWii; }
|
||||
|
||||
SpecBase::SpecBase(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc)
|
||||
: hecl::Database::IDataSpec(specEntry)
|
||||
, m_project(project)
|
||||
|
@ -94,6 +100,9 @@ bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector<ExtractReport
|
|||
break;
|
||||
}
|
||||
|
||||
setCurRegion(m_region);
|
||||
setCurSpecIsWii(m_isWii);
|
||||
|
||||
if (m_standalone)
|
||||
return checkFromStandaloneDisc(*m_disc, *regstr, info.extractArgs, reps);
|
||||
else
|
||||
|
@ -1223,4 +1232,11 @@ void SpecBase::WriteVersionInfo(hecl::Database::Project& project, const hecl::Pr
|
|||
athena::io::FileWriter writer(versionPath.getAbsolutePath());
|
||||
athena::io::ToYAMLStream(info, writer);
|
||||
}
|
||||
void SpecBase::setCurRegion(ERegion region) {
|
||||
g_CurRegion = region;
|
||||
}
|
||||
void SpecBase::setCurSpecIsWii(bool isWii) {
|
||||
g_CurSpecIsWii = isWii;
|
||||
}
|
||||
|
||||
} // namespace DataSpec
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "hecl/Blender/Token.hpp"
|
||||
#include "Runtime/RetroTypes.hpp"
|
||||
|
||||
|
||||
namespace nod {
|
||||
class DiscBase;
|
||||
class Node;
|
||||
|
@ -26,6 +25,9 @@ class YAMLDocWriter;
|
|||
namespace DataSpec {
|
||||
enum class ERegion;
|
||||
enum class EGame;
|
||||
ERegion getCurrentRegion();
|
||||
bool isCurrentSpecWii();
|
||||
|
||||
struct SpecBase : hecl::Database::IDataSpec {
|
||||
/* HECL Adaptors */
|
||||
void setThreadProject() override;
|
||||
|
@ -181,8 +183,8 @@ protected:
|
|||
bool m_backgroundRunning = false;
|
||||
|
||||
void readCatalog(const hecl::ProjectPath& catalogPath, athena::io::YAMLDocWriter& nameWriter);
|
||||
void insertPathTag(athena::io::YAMLDocWriter& cacheWriter, const urde::SObjectTag& tag,
|
||||
const hecl::ProjectPath& path, bool dump = true);
|
||||
void insertPathTag(athena::io::YAMLDocWriter& cacheWriter, const urde::SObjectTag& tag, const hecl::ProjectPath& path,
|
||||
bool dump = true);
|
||||
bool addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter);
|
||||
void backgroundIndexRecursiveProc(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter,
|
||||
athena::io::YAMLDocWriter& nameWriter, int level);
|
||||
|
@ -206,6 +208,9 @@ protected:
|
|||
std::string m_version;
|
||||
|
||||
void WriteVersionInfo(hecl::Database::Project& project, const hecl::ProjectPath& pakPath);
|
||||
|
||||
static void setCurRegion(ERegion region);
|
||||
static void setCurSpecIsWii(bool isWii);
|
||||
};
|
||||
|
||||
bool IsPathAudioGroup(const hecl::ProjectPath& path);
|
||||
|
|
|
@ -428,7 +428,9 @@ struct SpecMP1 : SpecBase {
|
|||
return true;
|
||||
else if (classType == DNAFont::FONT<UniqueID32>::DNAType())
|
||||
return true;
|
||||
else if (classType == DNAMP1::CTweakPlayerRes::DNAType())
|
||||
else if (classType == DNAMP1::CTweakPlayerRes<true>::DNAType())
|
||||
return true;
|
||||
else if (classType == DNAMP1::CTweakPlayerRes<false>::DNAType())
|
||||
return true;
|
||||
else if (classType == DNAMP1::CTweakGunRes::DNAType())
|
||||
return true;
|
||||
|
@ -442,7 +444,9 @@ struct SpecMP1 : SpecBase {
|
|||
return true;
|
||||
else if (classType == DNAMP1::CTweakAutoMapper::DNAType())
|
||||
return true;
|
||||
else if (classType == DNAMP1::CTweakTargeting::DNAType())
|
||||
else if (classType == DNAMP1::CTweakTargeting<true>::DNAType())
|
||||
return true;
|
||||
else if (classType == DNAMP1::CTweakTargeting<false>::DNAType())
|
||||
return true;
|
||||
else if (classType == DNAMP1::CTweakGui::DNAType())
|
||||
return true;
|
||||
|
@ -583,13 +587,15 @@ struct SpecMP1 : SpecBase {
|
|||
} else if (className == DataSpec::DNAMP1::SCAN::DNAType()) {
|
||||
resTag.type = SBIG('SCAN');
|
||||
return true;
|
||||
} else if (className == DataSpec::DNAMP1::CTweakPlayerRes::DNAType() ||
|
||||
} else if (className == DataSpec::DNAMP1::CTweakPlayerRes<true>::DNAType() ||
|
||||
className == DataSpec::DNAMP1::CTweakPlayerRes<false>::DNAType() ||
|
||||
className == DataSpec::DNAMP1::CTweakGunRes::DNAType() ||
|
||||
className == DataSpec::DNAMP1::CTweakSlideShow::DNAType() ||
|
||||
className == DataSpec::DNAMP1::CTweakPlayer::DNAType() ||
|
||||
className == DataSpec::DNAMP1::CTweakCameraBob::DNAType() ||
|
||||
className == DataSpec::DNAMP1::CTweakGame::DNAType() ||
|
||||
className == DataSpec::DNAMP1::CTweakTargeting::DNAType() ||
|
||||
className == DataSpec::DNAMP1::CTweakTargeting<true>::DNAType() ||
|
||||
className == DataSpec::DNAMP1::CTweakTargeting<false>::DNAType() ||
|
||||
className == DataSpec::DNAMP1::CTweakAutoMapper::DNAType() ||
|
||||
className == DataSpec::DNAMP1::CTweakGui::DNAType() ||
|
||||
className == DataSpec::DNAMP1::CTweakPlayerControl::DNAType() ||
|
||||
|
@ -834,8 +840,12 @@ struct SpecMP1 : SpecBase {
|
|||
DNAFont::FONT<UniqueID32> font;
|
||||
font.read(reader);
|
||||
DNAFont::WriteFONT(font, out);
|
||||
} else if (classStr == DNAMP1::CTweakPlayerRes::DNAType()) {
|
||||
DNAMP1::CTweakPlayerRes playerRes;
|
||||
} else if (classStr == DNAMP1::CTweakPlayerRes<true>::DNAType()) {
|
||||
DNAMP1::CTweakPlayerRes<true> playerRes;
|
||||
playerRes.read(reader);
|
||||
WriteTweak(playerRes, out);
|
||||
} else if (classStr == DNAMP1::CTweakPlayerRes<false>::DNAType()) {
|
||||
DNAMP1::CTweakPlayerRes<false> playerRes;
|
||||
playerRes.read(reader);
|
||||
WriteTweak(playerRes, out);
|
||||
} else if (classStr == DNAMP1::CTweakGunRes::DNAType()) {
|
||||
|
@ -862,8 +872,12 @@ struct SpecMP1 : SpecBase {
|
|||
DNAMP1::CTweakAutoMapper autoMapper;
|
||||
autoMapper.read(reader);
|
||||
WriteTweak(autoMapper, out);
|
||||
} else if (classStr == DNAMP1::CTweakTargeting::DNAType()) {
|
||||
DNAMP1::CTweakTargeting targeting;
|
||||
} else if (classStr == DNAMP1::CTweakTargeting<true>::DNAType()) {
|
||||
DNAMP1::CTweakTargeting<false> targeting;
|
||||
targeting.read(reader);
|
||||
WriteTweak(targeting, out);
|
||||
} else if (classStr == DNAMP1::CTweakTargeting<false>::DNAType()) {
|
||||
DNAMP1::CTweakTargeting<false> targeting;
|
||||
targeting.read(reader);
|
||||
WriteTweak(targeting, out);
|
||||
} else if (classStr == DNAMP1::CTweakGui::DNAType()) {
|
||||
|
|
|
@ -1428,11 +1428,14 @@ void CStateManager::InformListeners(const zeus::CVector3f& pos, EListenNoiseType
|
|||
|
||||
void CStateManager::ApplyKnockBack(CActor& actor, const CDamageInfo& info, const CDamageVulnerability& vuln,
|
||||
const zeus::CVector3f& pos, float dampen) {
|
||||
if (vuln.GetVulnerability(info.GetWeaponMode(), false) == EVulnerability::Deflect)
|
||||
if (vuln.GetVulnerability(info.GetWeaponMode(), false) == EVulnerability::Deflect) {
|
||||
return;
|
||||
}
|
||||
|
||||
CHealthInfo* hInfo = actor.HealthInfo(*this);
|
||||
if (!hInfo)
|
||||
if (hInfo == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
float dampedPower = (1.f - dampen) * info.GetKnockBackPower();
|
||||
if (TCastToPtr<CPlayer> player = actor) {
|
||||
|
@ -1446,30 +1449,34 @@ void CStateManager::ApplyKnockBack(CActor& actor, const CDamageInfo& info, const
|
|||
if (TCastToPtr<CPhysicsActor> physActor = actor) {
|
||||
zeus::CVector3f kbVec = pos * (dampedPower - hInfo->GetKnockbackResistance()) * physActor->GetMass() * 1.5f;
|
||||
if (physActor->GetMaterialList().HasMaterial(EMaterialTypes::Immovable) ||
|
||||
!physActor->GetMaterialList().HasMaterial(EMaterialTypes::Grass))
|
||||
!physActor->GetMaterialList().HasMaterial(EMaterialTypes::Solid)) {
|
||||
return;
|
||||
}
|
||||
physActor->ApplyImpulseWR(kbVec, zeus::CAxisAngle());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ai)
|
||||
if (ai) {
|
||||
ai->KnockBack(pos, *this, info, dampen == 0.f ? EKnockBackType::Direct : EKnockBackType::Radius, false,
|
||||
dampedPower);
|
||||
}
|
||||
}
|
||||
|
||||
void CStateManager::KnockBackPlayer(CPlayer& player, const zeus::CVector3f& pos, float power, float resistance) {
|
||||
if (player.GetMaterialList().HasMaterial(EMaterialTypes::Immovable))
|
||||
if (player.GetMaterialList().HasMaterial(EMaterialTypes::Immovable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
float usePower;
|
||||
if (player.GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed) {
|
||||
usePower = power * 1000.f;
|
||||
CPlayer::ESurfaceRestraints surface =
|
||||
player.x2b0_outOfWaterTicks == 2 ? player.x2ac_surfaceRestraint : CPlayer::ESurfaceRestraints::Water;
|
||||
if (surface != CPlayer::ESurfaceRestraints::Normal && player.GetOrbitState() == CPlayer::EPlayerOrbitState::NoOrbit)
|
||||
if (surface != CPlayer::ESurfaceRestraints::Normal && player.GetOrbitState() == CPlayer::EPlayerOrbitState::NoOrbit) {
|
||||
usePower /= 7.f;
|
||||
}
|
||||
} else {
|
||||
usePower = power * 500.f;
|
||||
}
|
||||
|
@ -1496,15 +1503,17 @@ void CStateManager::ApplyDamageToWorld(TUniqueId damager, const CActor& actor, c
|
|||
|
||||
bool bomb = false;
|
||||
TCastToConstPtr<CWeapon> weapon = actor;
|
||||
if (weapon)
|
||||
if (weapon) {
|
||||
bomb = True(weapon->GetAttribField() & (EProjectileAttrib::Bombs | EProjectileAttrib::PowerBombs));
|
||||
}
|
||||
|
||||
rstl::reserved_vector<TUniqueId, 1024> nearList;
|
||||
BuildNearList(nearList, aabb, filter, &actor);
|
||||
for (TUniqueId id : nearList) {
|
||||
CEntity* ent = ObjectById(id);
|
||||
if (!ent)
|
||||
if (ent == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TCastToPtr<CPlayer> player = ent;
|
||||
if (bomb && player) {
|
||||
|
@ -1513,20 +1522,24 @@ void CStateManager::ApplyDamageToWorld(TUniqueId damager, const CActor& actor, c
|
|||
MP1::CSamusHud::DisplayHudMemo(u"", CHUDMemoParms{0.f, true, true, true});
|
||||
player->UnFreeze(*this);
|
||||
} else {
|
||||
if ((weapon->GetAttribField() & EProjectileAttrib::Bombs) == EProjectileAttrib::Bombs)
|
||||
if ((weapon->GetAttribField() & EProjectileAttrib::Bombs) == EProjectileAttrib::Bombs) {
|
||||
player->BombJump(pos, *this);
|
||||
}
|
||||
}
|
||||
} else if (ent->GetUniqueId() != damager) {
|
||||
TestBombHittingWater(actor, pos, static_cast<CActor&>(*ent));
|
||||
if (TestRayDamage(pos, static_cast<CActor&>(*ent), nearList))
|
||||
if (TestRayDamage(pos, static_cast<CActor&>(*ent), nearList)) {
|
||||
ApplyRadiusDamage(actor, pos, static_cast<CActor&>(*ent), info);
|
||||
}
|
||||
}
|
||||
|
||||
if (TCastToPtr<CWallCrawlerSwarm> swarm = ent)
|
||||
if (TCastToPtr<CWallCrawlerSwarm> swarm = ent) {
|
||||
swarm->ApplyRadiusDamage(pos, info, *this);
|
||||
}
|
||||
|
||||
if (TCastToPtr<CSnakeWeedSwarm> swarm = ent)
|
||||
if (TCastToPtr<CSnakeWeedSwarm> swarm = ent) {
|
||||
swarm->ApplyRadiusDamage(pos, info, *this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1555,28 +1568,29 @@ void CStateManager::ApplyRadiusDamage(const CActor& a1, const zeus::CVector3f& p
|
|||
((bounds = a2.GetTouchBounds()) &&
|
||||
CCollidableSphere::Sphere_AABox_Bool(zeus::CSphere{pos, info.GetRadius()}, *bounds))) {
|
||||
float rad = info.GetRadius();
|
||||
if (rad > FLT_EPSILON)
|
||||
if (rad > FLT_EPSILON) {
|
||||
rad = delta.magnitude() / rad;
|
||||
else
|
||||
} else {
|
||||
rad = 0.f;
|
||||
if (rad > 0.f)
|
||||
}
|
||||
if (rad > 0.f) {
|
||||
delta.normalize();
|
||||
}
|
||||
|
||||
bool alive = false;
|
||||
if (CHealthInfo* hInfo = a2.HealthInfo(*this))
|
||||
if (hInfo->GetHP() > 0.f)
|
||||
if (CHealthInfo* hInfo = a2.HealthInfo(*this)) {
|
||||
if (hInfo->GetHP() > 0.f) {
|
||||
alive = true;
|
||||
}
|
||||
}
|
||||
|
||||
const CDamageVulnerability* vuln;
|
||||
if (rad > 0.f)
|
||||
vuln = a2.GetDamageVulnerability(pos, delta, info);
|
||||
else
|
||||
vuln = a2.GetDamageVulnerability();
|
||||
const CDamageVulnerability* vuln = rad > 0.f ? a2.GetDamageVulnerability(pos, delta, info) : a2.GetDamageVulnerability();
|
||||
|
||||
if (vuln->WeaponHurts(info.GetWeaponMode(), true)) {
|
||||
float dam = info.GetRadiusDamage(*vuln);
|
||||
if (dam > 0.f)
|
||||
if (dam > 0.f) {
|
||||
ApplyLocalDamage(pos, delta, a2, dam, info.GetWeaponMode());
|
||||
}
|
||||
a2.SendScriptMsgs(EScriptObjectState::Damage, *this, EScriptObjectMessage::None);
|
||||
SendScriptMsg(&a2, a1.GetUniqueId(), EScriptObjectMessage::Damage);
|
||||
} else {
|
||||
|
@ -1584,8 +1598,9 @@ void CStateManager::ApplyRadiusDamage(const CActor& a1, const zeus::CVector3f& p
|
|||
SendScriptMsg(&a2, a1.GetUniqueId(), EScriptObjectMessage::InvulnDamage);
|
||||
}
|
||||
|
||||
if (alive && info.GetKnockBackPower() > 0.f)
|
||||
if (alive && info.GetKnockBackPower() > 0.f) {
|
||||
ApplyKnockBack(a2, info, *vuln, (a2.GetTranslation() - a1.GetTranslation()).normalized(), rad);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,11 +57,9 @@ extern class CStateManager* g_StateManager;
|
|||
#if USE_DOWNCAST_TWEAKS
|
||||
using ITweakGame = DataSpec::DNAMP1::CTweakGame;
|
||||
using ITweakPlayer = DataSpec::DNAMP1::CTweakPlayer;
|
||||
using ITweakPlayerRes = DataSpec::DNAMP1::CTweakPlayerRes;
|
||||
using ITweakPlayerControl = DataSpec::DNAMP1::CTweakPlayerControl;
|
||||
using ITweakPlayerGun = DataSpec::DNAMP1::CTweakPlayerGun;
|
||||
using ITweakGunRes = DataSpec::DNAMP1::CTweakGunRes;
|
||||
using ITweakTargeting = DataSpec::DNAMP1::CTweakTargeting;
|
||||
using ITweakAutoMapper = DataSpec::DNAMP1::CTweakAutoMapper;
|
||||
using ITweakGui = DataSpec::DNAMP1::CTweakGui;
|
||||
using ITweakSlideShow = DataSpec::DNAMP1::CTweakSlideShow;
|
||||
|
@ -71,11 +69,9 @@ using ITweakGuiColors = DataSpec::DNAMP1::CTweakGuiColors;
|
|||
#else
|
||||
using ITweakGame = DataSpec::ITweakGame;
|
||||
using ITweakPlayer = DataSpec::ITweakPlayer;
|
||||
using ITweakPlayerRes = DataSpec::ITweakPlayerRes;
|
||||
using ITweakPlayerControl = DataSpec::ITweakPlayerControl;
|
||||
using ITweakPlayerGun = DataSpec::ITweakPlayerGun;
|
||||
using ITweakGunRes = DataSpec::ITweakGunRes;
|
||||
using ITweakTargeting = DataSpec::ITweakTargeting;
|
||||
using ITweakAutoMapper = DataSpec::ITweakAutoMapper;
|
||||
using ITweakGui = DataSpec::ITweakGui;
|
||||
using ITweakSlideShow = DataSpec::ITweakSlideShow;
|
||||
|
@ -83,6 +79,8 @@ using ITweakParticle = DataSpec::ITweakParticle;
|
|||
using ITweakBall = DataSpec::ITweakBall;
|
||||
using ITweakGuiColors = DataSpec::ITweakGuiColors;
|
||||
#endif
|
||||
using ITweakPlayerRes = DataSpec::ITweakPlayerRes;
|
||||
using ITweakTargeting = DataSpec::ITweakTargeting;
|
||||
|
||||
extern ITweakGame* g_tweakGame;
|
||||
extern ITweakPlayer* g_tweakPlayer;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <boo/boo.hpp>
|
||||
#include <boo/audiodev/IAudioVoiceEngine.hpp>
|
||||
#include <hecl/Runtime.hpp>
|
||||
#include "DataSpec/DNACommon/URDEVersionInfo.hpp"
|
||||
|
||||
namespace hecl {
|
||||
class Console;
|
||||
|
@ -13,6 +14,9 @@ class CVarManager;
|
|||
} // namespace hecl
|
||||
|
||||
namespace urde {
|
||||
using ERegion = DataSpec::ERegion;
|
||||
using EGame = DataSpec::EGame;
|
||||
|
||||
class CStopwatch;
|
||||
enum class EGameplayResult { None, Win, Lose, Playing };
|
||||
|
||||
|
@ -40,5 +44,12 @@ public:
|
|||
virtual size_t GetExpectedIdSize() const = 0;
|
||||
virtual void WarmupShaders() = 0;
|
||||
virtual hecl::Console* Console() const = 0;
|
||||
virtual EGame GetGame() const =0;
|
||||
virtual ERegion GetRegion() const =0;
|
||||
virtual bool IsPAL() const = 0;
|
||||
virtual bool IsJapanese() const = 0;
|
||||
virtual bool IsUSA() const = 0;
|
||||
virtual bool IsTrilogy() const = 0;
|
||||
virtual std::string_view GetVersionString() const=0;
|
||||
};
|
||||
} // namespace urde
|
||||
|
|
|
@ -63,8 +63,13 @@ void CTweaks::RegisterTweaks(hecl::CVarManager* cvarMgr) {
|
|||
/* Targeting */
|
||||
tag = g_ResFactory->GetResourceIdByName("Targeting");
|
||||
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
|
||||
g_tweakTargeting = new DataSpec::DNAMP1::CTweakTargeting(*strm);
|
||||
g_tweakTargeting->initCVars(cvarMgr);
|
||||
if (g_Main->IsTrilogy() || g_Main->IsPAL() || g_Main->IsJapanese()) {
|
||||
g_tweakTargeting = new DataSpec::DNAMP1::CTweakTargeting<true>(*strm);
|
||||
g_tweakTargeting->initCVars(cvarMgr);
|
||||
} else {
|
||||
g_tweakTargeting = new DataSpec::DNAMP1::CTweakTargeting<false>(*strm);
|
||||
g_tweakTargeting->initCVars(cvarMgr);
|
||||
}
|
||||
|
||||
/* Game */
|
||||
tag = g_ResFactory->GetResourceIdByName("Game");
|
||||
|
@ -121,7 +126,12 @@ void CTweaks::RegisterResourceTweaks(hecl::CVarManager* cvarMgr) {
|
|||
|
||||
tag = g_ResFactory->GetResourceIdByName("PlayerRes");
|
||||
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
|
||||
g_tweakPlayerRes = new DataSpec::DNAMP1::CTweakPlayerRes(*strm);
|
||||
if (g_Main->IsTrilogy() || g_Main->IsPAL() || g_Main->IsJapanese()) {
|
||||
g_tweakPlayerRes = new DataSpec::DNAMP1::CTweakPlayerRes<true>(*strm);
|
||||
} else {
|
||||
g_tweakPlayerRes = new DataSpec::DNAMP1::CTweakPlayerRes<false>(*strm);
|
||||
}
|
||||
|
||||
g_tweakPlayerRes->ResolveResources(*g_ResFactory);
|
||||
g_tweakPlayerRes->initCVars(cvarMgr);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "Runtime/GuiSys/CTextExecuteBuffer.hpp"
|
||||
#include "DataSpec/DNAMP1/Tweaks/CTweakPlayer.hpp"
|
||||
#include "DataSpec/DNAMP1/Tweaks/CTweakGame.hpp"
|
||||
#include "DataSpec/DNACommon/URDEVersionInfo.hpp"
|
||||
#include "hecl/Console.hpp"
|
||||
#include "hecl/CVarCommons.hpp"
|
||||
|
||||
|
@ -49,8 +48,6 @@ class IObjectStore;
|
|||
|
||||
namespace MP1 {
|
||||
class CMain;
|
||||
using ERegion = DataSpec::ERegion;
|
||||
using EGame = DataSpec::EGame;
|
||||
|
||||
class CGameGlobalObjects {
|
||||
friend class CMain;
|
||||
|
@ -315,13 +312,13 @@ public:
|
|||
void ListWorlds(hecl::Console*, const std::vector<std::string>&);
|
||||
void Warp(hecl::Console*, const std::vector<std::string>&);
|
||||
hecl::Console* Console() const override { return m_console.get(); }
|
||||
bool IsPAL() const { return m_version.region == ERegion::PAL; }
|
||||
bool IsJapanese() const { return m_version.region == ERegion::NTSC_J; }
|
||||
bool IsUSA() const { return m_version.region == ERegion::NTSC_U; }
|
||||
bool IsTrilogy() const { return m_version.isTrilogy; }
|
||||
ERegion GetRegion() const { return m_version.region; }
|
||||
EGame GetGame() const { return m_version.game; }
|
||||
std::string_view GetVersionString() const { return m_version.version; }
|
||||
bool IsPAL() const override { return m_version.region == ERegion::PAL; }
|
||||
bool IsJapanese() const override { return m_version.region == ERegion::NTSC_J; }
|
||||
bool IsUSA() const override { return m_version.region == ERegion::NTSC_U; }
|
||||
bool IsTrilogy() const override { return m_version.isTrilogy; }
|
||||
ERegion GetRegion() const override { return m_version.region; }
|
||||
EGame GetGame() const override { return m_version.game; }
|
||||
std::string_view GetVersionString() const override{ return m_version.version; }
|
||||
|
||||
int m_warpWorldIdx = -1;
|
||||
TAreaId m_warpAreaId = 0;
|
||||
|
|
|
@ -149,6 +149,15 @@ bool CProjectileWeaponDataFactory::CreateWPSM(CWeaponDescription* desc, CInputSt
|
|||
case SBIG('FOFF'):
|
||||
desc->xb0_FOFF = CPF::GetRealElement(in);
|
||||
break;
|
||||
case SBIG('SPS1'):
|
||||
desc->x28_SPS1 = CPF::GetBool(in);
|
||||
break;
|
||||
case SBIG('SPS2'):
|
||||
desc->x29_SPS2 = CPF::GetBool(in);
|
||||
break;
|
||||
case SBIG('FC60'):
|
||||
desc->x29_FC60 = CPF::GetBool(in);
|
||||
break;
|
||||
default: {
|
||||
Log.report(logvisor::Fatal, FMT_STRING("Unknown WPSM class {} @{}"), clsId, in.position());
|
||||
return false;
|
||||
|
|
|
@ -54,5 +54,9 @@ public:
|
|||
s32 xa8_PJFX = -1;
|
||||
std::unique_ptr<CRealElement> xac_RNGE;
|
||||
std::unique_ptr<CRealElement> xb0_FOFF;
|
||||
// PAL/RS5
|
||||
bool x28_SPS1 = false;
|
||||
bool x29_SPS2 = false;
|
||||
bool x29_FC60 = false;
|
||||
};
|
||||
} // namespace urde
|
||||
|
|
|
@ -36,10 +36,12 @@ float CDamageInfo::GetDamage(const CDamageVulnerability& dVuln) const {
|
|||
|
||||
float CDamageInfo::GetRadiusDamage(const CDamageVulnerability& dVuln) const {
|
||||
EVulnerability vuln = dVuln.GetVulnerability(x0_weaponMode, false);
|
||||
if (vuln == EVulnerability::Deflect)
|
||||
if (vuln == EVulnerability::Deflect) {
|
||||
return 0.f;
|
||||
else if (vuln == EVulnerability::Weak)
|
||||
}
|
||||
if (vuln == EVulnerability::Weak) {
|
||||
return 2.f * xc_radiusDamage;
|
||||
}
|
||||
|
||||
return xc_radiusDamage;
|
||||
}
|
||||
|
|
|
@ -240,36 +240,44 @@ 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::OrangePhazon)
|
||||
if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::OrangePhazon) {
|
||||
return EVulnerability::Deflect;
|
||||
}
|
||||
|
||||
if (mode.IsInstantKill())
|
||||
if (mode.IsInstantKill()) {
|
||||
return EVulnerability::Normal;
|
||||
}
|
||||
|
||||
EVulnerability vuln = (&x0_power)[u32(mode.GetType())];
|
||||
if (mode.IsCharged()) {
|
||||
if (mode.GetType() < EWeaponType::Bomb)
|
||||
if (mode.GetType() < EWeaponType::Bomb) {
|
||||
vuln = (&x3c_chargedPower)[u32(mode.GetType())];
|
||||
else
|
||||
} else {
|
||||
vuln = EVulnerability::Normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode.IsComboed()) {
|
||||
if (mode.GetType() < EWeaponType::Bomb)
|
||||
if (mode.GetType() < EWeaponType::Bomb) {
|
||||
vuln = (&x3c_chargedPower)[u32(mode.GetType())];
|
||||
else
|
||||
} else {
|
||||
vuln = EVulnerability::Normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (ignoreDirect)
|
||||
if (ignoreDirect) {
|
||||
return vuln;
|
||||
}
|
||||
|
||||
if (vuln == EVulnerability::DirectWeak)
|
||||
if (vuln == EVulnerability::DirectWeak) {
|
||||
return EVulnerability::Weak;
|
||||
else if (vuln == EVulnerability::DirectNormal)
|
||||
}
|
||||
if (vuln == EVulnerability::DirectNormal) {
|
||||
return EVulnerability::Normal;
|
||||
else if (vuln == EVulnerability::DirectImmune)
|
||||
}
|
||||
if (vuln == EVulnerability::DirectImmune) {
|
||||
return EVulnerability::Immune;
|
||||
}
|
||||
|
||||
return vuln;
|
||||
}
|
||||
|
|
|
@ -483,8 +483,9 @@ void CKnockBackController::DoKnockBackAnimation(const zeus::CVector3f& backVec,
|
|||
switch (x4_activeParms.x0_animState) {
|
||||
case EKnockBackAnimationState::Hurled: {
|
||||
float hurlVel = 5.f;
|
||||
if (CHealthInfo* hInfo = parent.HealthInfo(mgr))
|
||||
if (CHealthInfo* hInfo = parent.HealthInfo(mgr)) {
|
||||
hurlVel += CalculateExtraHurlVelocity(mgr, magnitude, hInfo->GetKnockbackResistance());
|
||||
}
|
||||
hurlVel = std::sqrt(parent.GetGravityConstant() * 0.5f * hurlVel);
|
||||
zeus::CVector3f backUpVec = backVec + backVec.magnitude() * zeus::skUp;
|
||||
if (backUpVec.canBeNormalized()) {
|
||||
|
@ -520,10 +521,11 @@ void CKnockBackController::ResetKnockBackImpulse(CPatterned& parent, const zeus:
|
|||
if (x81_24_autoResetImpulse && x4_activeParms.x0_animState == EKnockBackAnimationState::KnockBack &&
|
||||
x4_activeParms.x4_animFollowup != EKnockBackAnimationFollowUp::Freeze) {
|
||||
x50_impulseDir = backVec.canBeNormalized() ? backVec.normalized() : -parent.GetTransform().basis[1];
|
||||
if (x60_impulseRemTime <= 0.f)
|
||||
if (x60_impulseRemTime <= 0.f) {
|
||||
x5c_impulseMag = magnitude;
|
||||
else
|
||||
} else {
|
||||
x5c_impulseMag += magnitude * (1.f - x60_impulseRemTime / ImpulseDurationTable[x20_impulseDurationIdx]);
|
||||
}
|
||||
x60_impulseRemTime = ImpulseDurationTable[x20_impulseDurationIdx];
|
||||
}
|
||||
}
|
||||
|
@ -565,21 +567,25 @@ void CKnockBackController::SetAutoResetImpulse(bool b) {
|
|||
void CKnockBackController::Update(float dt, CStateManager& mgr, CPatterned& parent) {
|
||||
ApplyImpulse(dt, parent);
|
||||
x64_flinchRemTime -= dt;
|
||||
if (TickDeferredTimer(dt))
|
||||
if (TickDeferredTimer(dt)) {
|
||||
DoDeferredKnockBack(mgr, parent);
|
||||
if (x82_26_locomotionDuringElectrocution && parent.GetBodyController()->IsElectrocuting())
|
||||
}
|
||||
if (x82_26_locomotionDuringElectrocution && parent.GetBodyController()->IsElectrocuting()) {
|
||||
parent.GetBodyController()->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::Locomotion));
|
||||
}
|
||||
}
|
||||
|
||||
EKnockBackWeaponType CKnockBackController::GetKnockBackWeaponType(const CDamageInfo& info, EWeaponType wType,
|
||||
EKnockBackType type) {
|
||||
int stacking = 0;
|
||||
if (info.GetWeaponMode().IsCharged())
|
||||
if (info.GetWeaponMode().IsCharged()) {
|
||||
stacking = 1;
|
||||
else if (info.GetWeaponMode().IsComboed())
|
||||
} else if (info.GetWeaponMode().IsComboed()) {
|
||||
stacking = 2;
|
||||
if (wType > EWeaponType::Phazon)
|
||||
}
|
||||
if (wType > EWeaponType::Phazon) {
|
||||
return EKnockBackWeaponType::Invalid;
|
||||
}
|
||||
switch (wType) {
|
||||
case EWeaponType::Power:
|
||||
return EKnockBackWeaponType(type != EKnockBackType::Direct ? stacking : stacking + 1);
|
||||
|
@ -604,6 +610,8 @@ EKnockBackWeaponType CKnockBackController::GetKnockBackWeaponType(const CDamageI
|
|||
|
||||
void CKnockBackController::SelectDamageState(CPatterned& parent, const CDamageInfo& info, EWeaponType wType,
|
||||
EKnockBackType type) {
|
||||
|
||||
x4_activeParms = KnockBackParms();
|
||||
EKnockBackWeaponType weaponType = GetKnockBackWeaponType(info, wType, type);
|
||||
if (weaponType != EKnockBackWeaponType::Invalid) {
|
||||
x4_activeParms =
|
||||
|
@ -616,8 +624,9 @@ void CKnockBackController::KnockBack(const zeus::CVector3f& backVec, CStateManag
|
|||
const CDamageInfo& info, EKnockBackType type, float magnitude) {
|
||||
if (!x82_25_inDeferredKnockBack) {
|
||||
zeus::CVector3f vec(backVec.toVec2f());
|
||||
if (!vec.isMagnitudeSafe())
|
||||
if (!vec.isMagnitudeSafe()) {
|
||||
vec = -parent.GetTransform().basis[1];
|
||||
}
|
||||
SelectDamageState(parent, info, info.GetWeaponMode().GetType(), type);
|
||||
DoKnockBackAnimation(vec, mgr, parent, magnitude);
|
||||
ResetKnockBackImpulse(parent, vec, 2.f);
|
||||
|
|
|
@ -497,10 +497,11 @@ void CPatterned::Death(CStateManager& mgr, const zeus::CVector3f& dir, EScriptOb
|
|||
void CPatterned::KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, const CDamageInfo& info,
|
||||
EKnockBackType type, bool inDeferred, float magnitude) {
|
||||
CHealthInfo* hInfo = HealthInfo(mgr);
|
||||
if (!x401_27_phazingOut && !x401_28_burning && hInfo) {
|
||||
if (!x401_27_phazingOut && !x401_28_burning && hInfo != nullptr) {
|
||||
x460_knockBackController.KnockBack(backVec, mgr, *this, info, type, magnitude);
|
||||
if (x450_bodyController->IsFrozen() && x460_knockBackController.GetActiveParms().xc_intoFreezeDur >= 0.f)
|
||||
if (x450_bodyController->IsFrozen() && x460_knockBackController.GetActiveParms().xc_intoFreezeDur >= 0.f) {
|
||||
x450_bodyController->FrozenBreakout();
|
||||
}
|
||||
switch (x460_knockBackController.GetActiveParms().x4_animFollowup) {
|
||||
case EKnockBackAnimationFollowUp::Freeze:
|
||||
Freeze(mgr, zeus::skZero3f, zeus::CUnitVector3f(x34_transform.transposeRotate(backVec)),
|
||||
|
@ -545,10 +546,11 @@ void CPatterned::KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, c
|
|||
break;
|
||||
case EKnockBackAnimationFollowUp::IceDeath:
|
||||
Death(mgr, zeus::skZero3f, EScriptObjectState::DeathRattle);
|
||||
if (x54c_iceDeathExplosionParticle)
|
||||
if (x54c_iceDeathExplosionParticle) {
|
||||
MassiveFrozenDeath(mgr);
|
||||
else if (x450_bodyController->IsFrozen())
|
||||
} else if (x450_bodyController->IsFrozen()) {
|
||||
x450_bodyController->FrozenBreakout();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -835,7 +835,7 @@ void CWallCrawlerSwarm::Think(float dt, CStateManager& mgr) {
|
|||
const zeus::CAABox aabb = BoxForPosition(r26, r27, r20, x374_boidRadius + 0.5f);
|
||||
CAreaCollisionCache ccache(aabb);
|
||||
CGameCollision::BuildAreaCollisionCache(mgr, ccache);
|
||||
while (boid) {
|
||||
while (boid != nullptr) {
|
||||
r21 += 1;
|
||||
if (boid->GetActive()) {
|
||||
if (x558_flavor == EFlavor::Scarab) {
|
||||
|
@ -1235,5 +1235,15 @@ zeus::CVector3f CWallCrawlerSwarm::GetAimPosition(const CStateManager&, float dt
|
|||
|
||||
return x108_boids[x42c_lockOnIdx].x30_velocity * dt + x124_lastOrbitPosition;
|
||||
}
|
||||
void CWallCrawlerSwarm::ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& stateMgr) {
|
||||
for (CBoid& boid : x108_boids) {
|
||||
if (boid.GetActive() && (boid.GetTranslation() - pos).magSquared() < info.GetRadius() * info.GetRadius()) {
|
||||
boid.x78_health -= info.GetRadiusDamage();
|
||||
if (boid.x78_health <= 0.f) {
|
||||
KillBoid(boid, stateMgr, 1.f, 0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -205,7 +205,7 @@ public:
|
|||
zeus::CVector3f GetOrbitPosition(const CStateManager&) const override;
|
||||
zeus::CVector3f GetAimPosition(const CStateManager&, float) const override;
|
||||
const zeus::CVector3f& GetLastKilledOffset() const { return x130_lastKilledOffset; }
|
||||
void ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& stateMgr) {}
|
||||
void ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& stateMgr);
|
||||
const std::vector<CBoid>& GetBoids() const { return x108_boids; }
|
||||
int GetCurrentLockOnId() const { return x42c_lockOnIdx; }
|
||||
bool GetLockOnLocationValid(int id) const { return id >= 0 && id < x108_boids.size() && x108_boids[id].GetActive(); }
|
||||
|
|
Loading…
Reference in New Issue