mirror of https://github.com/AxioDL/metaforce.git
commit
ce45cd279c
|
@ -1,30 +1,48 @@
|
||||||
#include "CGunWeapon.hpp"
|
#include "Runtime/Weapon/CGunWeapon.hpp"
|
||||||
#include "GameGlobalObjects.hpp"
|
|
||||||
#include "CSimplePool.hpp"
|
#include <algorithm>
|
||||||
#include "CDependencyGroup.hpp"
|
#include <array>
|
||||||
#include "CGameState.hpp"
|
|
||||||
#include "CWeapon.hpp"
|
#include "Runtime/CDependencyGroup.hpp"
|
||||||
#include "CEnergyProjectile.hpp"
|
#include "Runtime/CGameState.hpp"
|
||||||
#include "Graphics/CSkinnedModel.hpp"
|
#include "Runtime/CSimplePool.hpp"
|
||||||
#include "Graphics/CVertexMorphEffect.hpp"
|
#include "Runtime/GameGlobalObjects.hpp"
|
||||||
|
#include "Runtime/Graphics/CSkinnedModel.hpp"
|
||||||
|
#include "Runtime/Graphics/CVertexMorphEffect.hpp"
|
||||||
|
#include "Runtime/Weapon/CEnergyProjectile.hpp"
|
||||||
|
#include "Runtime/Weapon/CWeapon.hpp"
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
static const char* skBeamXferNames[] = {"PowerXfer", "IceXfer", "WaveXfer", "PlasmaXfer", "PhazonXfer"};
|
namespace {
|
||||||
|
constexpr std::array skBeamXferNames{
|
||||||
|
"PowerXfer", "IceXfer", "WaveXfer", "PlasmaXfer", "PhazonXfer",
|
||||||
|
};
|
||||||
|
|
||||||
static const char* skSuitArmNames[] = {
|
constexpr std::array skSuitArmNames{
|
||||||
"PowerArm", "GravityArm", "VariaArm", "PhazonArm", "FusionArm", "FusionArmG", "FusionArmV", "FusionArmP",
|
"PowerArm", "GravityArm", "VariaArm", "PhazonArm", "FusionArm", "FusionArmG", "FusionArmV", "FusionArmP",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* skMuzzleNames[] = {"PowerMuzzle", "PowerCharge", "IceMuzzle", "IceCharge", "PowerMuzzle",
|
constexpr std::array skMuzzleNames{
|
||||||
"WaveCharge", "PlasmaMuzzle", "PlasmaCharge", "PhazonMuzzle", "EmptyMuzzle"};
|
"PowerMuzzle", "PowerCharge", "IceMuzzle", "IceCharge", "PowerMuzzle",
|
||||||
|
"WaveCharge", "PlasmaMuzzle", "PlasmaCharge", "PhazonMuzzle", "EmptyMuzzle",
|
||||||
|
};
|
||||||
|
|
||||||
static const char* skFrozenNames[] = {"powerFrozen", "Ice2nd_2", "iceFrozen", "Ice2nd_2", "waveFrozen",
|
constexpr std::array skFrozenNames{
|
||||||
"Ice2nd_2", "plasmaFrozen", "Ice2nd_2", "iceFrozen", "Ice2nd_2"};
|
"powerFrozen", "Ice2nd_2", "iceFrozen", "Ice2nd_2", "waveFrozen",
|
||||||
|
"Ice2nd_2", "plasmaFrozen", "Ice2nd_2", "iceFrozen", "Ice2nd_2",
|
||||||
|
};
|
||||||
|
|
||||||
static const char* skDependencyNames[] = {"Power_DGRP", "Ice_DGRP", "Wave_DGRP", "Plasma_DGRP", "Phazon_DGRP"};
|
constexpr std::array skDependencyNames{
|
||||||
|
"Power_DGRP", "Ice_DGRP", "Wave_DGRP", "Plasma_DGRP", "Phazon_DGRP",
|
||||||
|
};
|
||||||
|
|
||||||
static const char* skAnimDependencyNames[] = {"Power_Anim_DGRP", "Ice_Anim_DGRP", "Wave_Anim_DGRP", "Plasma_Anim_DGRP",
|
constexpr std::array skAnimDependencyNames{
|
||||||
"Phazon_Anim_DGRP"};
|
"Power_Anim_DGRP", "Ice_Anim_DGRP", "Wave_Anim_DGRP", "Plasma_Anim_DGRP", "Phazon_Anim_DGRP",
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr std::array skAnimTypeList{
|
||||||
|
0, 4, 1, 2, 3, 5, 6, 7, 8, 9, 10,
|
||||||
|
};
|
||||||
|
|
||||||
CPlayerState::EBeamId GetWeaponIndex(EWeaponType type) {
|
CPlayerState::EBeamId GetWeaponIndex(EWeaponType type) {
|
||||||
if (type == EWeaponType::Power)
|
if (type == EWeaponType::Power)
|
||||||
|
@ -39,13 +57,14 @@ CPlayerState::EBeamId GetWeaponIndex(EWeaponType type) {
|
||||||
return CPlayerState::EBeamId::Phazon;
|
return CPlayerState::EBeamId::Phazon;
|
||||||
return CPlayerState::EBeamId::Power;
|
return CPlayerState::EBeamId::Power;
|
||||||
}
|
}
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
CGunWeapon::CGunWeapon(CAssetId ancsId, EWeaponType type, TUniqueId playerId, EMaterialTypes playerMaterial,
|
CGunWeapon::CGunWeapon(CAssetId ancsId, EWeaponType type, TUniqueId playerId, EMaterialTypes playerMaterial,
|
||||||
const zeus::CVector3f& scale)
|
const zeus::CVector3f& scale)
|
||||||
: x4_scale(scale)
|
: x4_scale(scale)
|
||||||
, x104_gunCharacter(g_SimplePool->GetObj(SObjectTag{FOURCC('ANCS'), ancsId}))
|
, x104_gunCharacter(g_SimplePool->GetObj(SObjectTag{FOURCC('ANCS'), ancsId}))
|
||||||
, x13c_armCharacter(g_SimplePool->GetObj(skSuitArmNames[0]))
|
, x13c_armCharacter(g_SimplePool->GetObj(skSuitArmNames[0]))
|
||||||
, x160_xferEffect(g_SimplePool->GetObj(skBeamXferNames[int(GetWeaponIndex(type))]))
|
, x160_xferEffect(g_SimplePool->GetObj(skBeamXferNames[size_t(GetWeaponIndex(type))]))
|
||||||
, x1c0_weaponType(type)
|
, x1c0_weaponType(type)
|
||||||
, x1c4_playerId(playerId)
|
, x1c4_playerId(playerId)
|
||||||
, x1c8_playerMaterial(playerMaterial)
|
, x1c8_playerMaterial(playerMaterial)
|
||||||
|
@ -57,10 +76,11 @@ CGunWeapon::CGunWeapon(CAssetId ancsId, EWeaponType type, TUniqueId playerId, EM
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGunWeapon::AllocResPools(CPlayerState::EBeamId beam) {
|
void CGunWeapon::AllocResPools(CPlayerState::EBeamId beam) {
|
||||||
const CAssetId* wPair = g_tweakGunRes->GetWeaponPair(beam);
|
const CAssetId* const wPair = g_tweakGunRes->GetWeaponPair(beam);
|
||||||
const char** muzzleNames = &skMuzzleNames[int(beam) * 2];
|
const char* const* muzzleNames = &skMuzzleNames[size_t(beam) * 2];
|
||||||
const char** frozenNames = &skFrozenNames[int(beam) * 2];
|
const char* const* frozenNames = &skFrozenNames[size_t(beam) * 2];
|
||||||
for (int i = 0; i < 2; ++i) {
|
|
||||||
|
for (size_t i = 0; i < x16c_muzzleEffects.capacity(); ++i) {
|
||||||
x16c_muzzleEffects.push_back(g_SimplePool->GetObj(muzzleNames[i]));
|
x16c_muzzleEffects.push_back(g_SimplePool->GetObj(muzzleNames[i]));
|
||||||
x144_weapons.push_back(g_SimplePool->GetObj(SObjectTag{FOURCC('WPSC'), wPair[i]}));
|
x144_weapons.push_back(g_SimplePool->GetObj(SObjectTag{FOURCC('WPSC'), wPair[i]}));
|
||||||
x188_frozenEffects.push_back(g_SimplePool->GetObj(frozenNames[i]));
|
x188_frozenEffects.push_back(g_SimplePool->GetObj(frozenNames[i]));
|
||||||
|
@ -69,11 +89,13 @@ void CGunWeapon::AllocResPools(CPlayerState::EBeamId beam) {
|
||||||
|
|
||||||
void CGunWeapon::FreeResPools() {
|
void CGunWeapon::FreeResPools() {
|
||||||
x160_xferEffect.Unlock();
|
x160_xferEffect.Unlock();
|
||||||
for (int i = 0; i < 2; ++i) {
|
|
||||||
|
for (size_t i = 0; i < x16c_muzzleEffects.size(); ++i) {
|
||||||
x16c_muzzleEffects[i].Unlock();
|
x16c_muzzleEffects[i].Unlock();
|
||||||
x144_weapons[i].Unlock();
|
x144_weapons[i].Unlock();
|
||||||
x188_frozenEffects[i].Unlock();
|
x188_frozenEffects[i].Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
x10c_anims.clear();
|
x10c_anims.clear();
|
||||||
x1a4_muzzleGenerators.clear();
|
x1a4_muzzleGenerators.clear();
|
||||||
x1d0_velInfo.Clear();
|
x1d0_velInfo.Clear();
|
||||||
|
@ -85,8 +107,8 @@ void CGunWeapon::FillTokenVector(const std::vector<SObjectTag>& tags, std::vecto
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGunWeapon::BuildDependencyList(CPlayerState::EBeamId beam) {
|
void CGunWeapon::BuildDependencyList(CPlayerState::EBeamId beam) {
|
||||||
TLockedToken<CDependencyGroup> deps = g_SimplePool->GetObj(skDependencyNames[int(beam)]);
|
TLockedToken<CDependencyGroup> deps = g_SimplePool->GetObj(skDependencyNames[size_t(beam)]);
|
||||||
TLockedToken<CDependencyGroup> animDeps = g_SimplePool->GetObj(skAnimDependencyNames[int(beam)]);
|
TLockedToken<CDependencyGroup> animDeps = g_SimplePool->GetObj(skAnimDependencyNames[size_t(beam)]);
|
||||||
x12c_deps.reserve(deps->GetObjectTagVector().size() + animDeps->GetObjectTagVector().size());
|
x12c_deps.reserve(deps->GetObjectTagVector().size() + animDeps->GetObjectTagVector().size());
|
||||||
FillTokenVector(deps->GetObjectTagVector(), x12c_deps);
|
FillTokenVector(deps->GetObjectTagVector(), x12c_deps);
|
||||||
FillTokenVector(animDeps->GetObjectTagVector(), x12c_deps);
|
FillTokenVector(animDeps->GetObjectTagVector(), x12c_deps);
|
||||||
|
@ -95,7 +117,7 @@ void CGunWeapon::BuildDependencyList(CPlayerState::EBeamId beam) {
|
||||||
void CGunWeapon::AsyncLoadSuitArm(CStateManager& mgr) {
|
void CGunWeapon::AsyncLoadSuitArm(CStateManager& mgr) {
|
||||||
|
|
||||||
xb0_suitArmModelData = std::nullopt;
|
xb0_suitArmModelData = std::nullopt;
|
||||||
x13c_armCharacter = g_SimplePool->GetObj(skSuitArmNames[int(NWeaponTypes::get_current_suit(mgr))]);
|
x13c_armCharacter = g_SimplePool->GetObj(skSuitArmNames[size_t(NWeaponTypes::get_current_suit(mgr))]);
|
||||||
x13c_armCharacter.Lock();
|
x13c_armCharacter.Lock();
|
||||||
x218_28_suitArmLocked = true;
|
x218_28_suitArmLocked = true;
|
||||||
}
|
}
|
||||||
|
@ -111,15 +133,14 @@ void CGunWeapon::Reset(CStateManager& mgr) {
|
||||||
x100_gunController->Reset();
|
x100_gunController->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const s32 skAnimTypeList[] = {0, 4, 1, 2, 3, 5, 6, 7, 8, 9, 10};
|
|
||||||
|
|
||||||
void CGunWeapon::PlayAnim(NWeaponTypes::EGunAnimType type, bool loop) {
|
void CGunWeapon::PlayAnim(NWeaponTypes::EGunAnimType type, bool loop) {
|
||||||
if (x218_26_loaded && type >= NWeaponTypes::EGunAnimType::BasePosition &&
|
if (!x218_26_loaded || type < NWeaponTypes::EGunAnimType::BasePosition || type > NWeaponTypes::EGunAnimType::ToBeam) {
|
||||||
type <= NWeaponTypes::EGunAnimType::ToBeam) {
|
return;
|
||||||
x10_solidModelData->GetAnimationData()->EnableLooping(loop);
|
|
||||||
CAnimPlaybackParms parms(skAnimTypeList[int(type)], -1, 1.f, true);
|
|
||||||
x10_solidModelData->GetAnimationData()->SetAnimation(parms, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x10_solidModelData->GetAnimationData()->EnableLooping(loop);
|
||||||
|
const CAnimPlaybackParms parms(skAnimTypeList[size_t(type)], -1, 1.f, true);
|
||||||
|
x10_solidModelData->GetAnimationData()->SetAnimation(parms, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGunWeapon::PreRenderGunFx(const CStateManager& mgr, const zeus::CTransform& xf) {
|
void CGunWeapon::PreRenderGunFx(const CStateManager& mgr, const zeus::CTransform& xf) {
|
||||||
|
@ -149,7 +170,7 @@ void CGunWeapon::UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const s32 CGunWeapon::skShootAnim[2] = {4, 3};
|
const std::array<s32, 2> CGunWeapon::skShootAnim{4, 3};
|
||||||
|
|
||||||
void CGunWeapon::Fire(bool underwater, float dt, EChargeState chargeState, const zeus::CTransform& xf,
|
void CGunWeapon::Fire(bool underwater, float dt, EChargeState chargeState, const zeus::CTransform& xf,
|
||||||
CStateManager& mgr, TUniqueId homingTarget, float chargeFactor1, float chargeFactor2) {
|
CStateManager& mgr, TUniqueId homingTarget, float chargeFactor1, float chargeFactor2) {
|
||||||
|
@ -277,26 +298,29 @@ void CGunWeapon::Draw(bool drawSuitArm, const CStateManager& mgr, const zeus::CT
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGunWeapon::DrawMuzzleFx(const CStateManager& mgr) const {
|
void CGunWeapon::DrawMuzzleFx(const CStateManager& mgr) const {
|
||||||
if (const CElementGen* effect = x1a4_muzzleGenerators[x208_muzzleEffectIdx].get()) {
|
if (CElementGen* const effect = x1a4_muzzleGenerators[x208_muzzleEffectIdx].get()) {
|
||||||
if (x200_beamId != CPlayerState::EBeamId::Ice &&
|
if (x200_beamId != CPlayerState::EBeamId::Ice &&
|
||||||
mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) {
|
mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) {
|
||||||
CElementGen::SetSubtractBlend(true);
|
CElementGen::SetSubtractBlend(true);
|
||||||
const_cast<CElementGen*>(effect)->Render();
|
effect->Render();
|
||||||
CElementGen::SetSubtractBlend(false);
|
CElementGen::SetSubtractBlend(false);
|
||||||
} else {
|
} else {
|
||||||
const_cast<CElementGen*>(effect)->Render();
|
effect->Render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGunWeapon::LoadSuitArm(CStateManager& mgr) {
|
void CGunWeapon::LoadSuitArm(CStateManager& mgr) {
|
||||||
if (x13c_armCharacter.IsLoaded()) {
|
if (!x13c_armCharacter.IsLoaded()) {
|
||||||
CAssetId armId = NWeaponTypes::get_asset_id_from_name(skSuitArmNames[int(NWeaponTypes::get_current_suit(mgr))]);
|
return;
|
||||||
xb0_suitArmModelData.emplace(CStaticRes(armId, x4_scale));
|
|
||||||
xb0_suitArmModelData->SetSortThermal(true);
|
|
||||||
x218_28_suitArmLocked = false;
|
|
||||||
x13c_armCharacter.Unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CAssetId armId =
|
||||||
|
NWeaponTypes::get_asset_id_from_name(skSuitArmNames[size_t(NWeaponTypes::get_current_suit(mgr))]);
|
||||||
|
xb0_suitArmModelData.emplace(CStaticRes(armId, x4_scale));
|
||||||
|
xb0_suitArmModelData->SetSortThermal(true);
|
||||||
|
x218_28_suitArmLocked = false;
|
||||||
|
x13c_armCharacter.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGunWeapon::LoadGunModels(CStateManager& mgr) {
|
void CGunWeapon::LoadGunModels(CStateManager& mgr) {
|
||||||
|
@ -316,15 +340,12 @@ void CGunWeapon::LoadAnimations() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGunWeapon::IsAnimsLoaded() const {
|
bool CGunWeapon::IsAnimsLoaded() const {
|
||||||
for (const CToken& tok : x10c_anims)
|
return std::all_of(x10c_anims.cbegin(), x10c_anims.cend(), [](const auto& anim) { return anim.IsLoaded(); });
|
||||||
if (!tok.IsLoaded())
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGunWeapon::LoadMuzzleFx(float dt) {
|
void CGunWeapon::LoadMuzzleFx(float dt) {
|
||||||
for (int i = 0; i < 2; ++i) {
|
for (const auto& muzzleEffect : x16c_muzzleEffects) {
|
||||||
x1a4_muzzleGenerators.push_back(std::make_unique<CElementGen>(x16c_muzzleEffects[i]));
|
x1a4_muzzleGenerators.push_back(std::make_unique<CElementGen>(muzzleEffect));
|
||||||
x1a4_muzzleGenerators.back()->SetParticleEmission(false);
|
x1a4_muzzleGenerators.back()->SetParticleEmission(false);
|
||||||
x1a4_muzzleGenerators.back()->Update(dt);
|
x1a4_muzzleGenerators.back()->Update(dt);
|
||||||
}
|
}
|
||||||
|
@ -333,60 +354,68 @@ void CGunWeapon::LoadMuzzleFx(float dt) {
|
||||||
void CGunWeapon::LoadProjectileData(CStateManager& mgr) {
|
void CGunWeapon::LoadProjectileData(CStateManager& mgr) {
|
||||||
CRandom16 random(mgr.GetUpdateFrameIndex());
|
CRandom16 random(mgr.GetUpdateFrameIndex());
|
||||||
CGlobalRandom grand(random);
|
CGlobalRandom grand(random);
|
||||||
for (int i = 0; i < 2; ++i) {
|
|
||||||
|
for (const auto& weapon : x144_weapons) {
|
||||||
zeus::CVector3f weaponVel;
|
zeus::CVector3f weaponVel;
|
||||||
if (const CVectorElement* ivec = x144_weapons[i]->x4_IVEC.get())
|
if (const CVectorElement* ivec = weapon->x4_IVEC.get()) {
|
||||||
ivec->GetValue(0, weaponVel);
|
ivec->GetValue(0, weaponVel);
|
||||||
|
}
|
||||||
|
|
||||||
x1d0_velInfo.x0_vel.push_back(weaponVel);
|
x1d0_velInfo.x0_vel.push_back(weaponVel);
|
||||||
float tratVal = 0.f;
|
float tratVal = 0.f;
|
||||||
if (const CRealElement* trat = x144_weapons[i]->x30_TRAT.get())
|
if (const CRealElement* trat = weapon->x30_TRAT.get()) {
|
||||||
trat->GetValue(0, tratVal);
|
trat->GetValue(0, tratVal);
|
||||||
|
}
|
||||||
|
|
||||||
x1d0_velInfo.x24_trat.push_back(tratVal);
|
x1d0_velInfo.x24_trat.push_back(tratVal);
|
||||||
x1d0_velInfo.x1c_targetHoming.push_back(x144_weapons[i]->x29_HOMG);
|
x1d0_velInfo.x1c_targetHoming.push_back(weapon->x29_HOMG);
|
||||||
if (weaponVel.y() > 0.f)
|
if (weaponVel.y() > 0.f) {
|
||||||
x1d0_velInfo.x0_vel.back() *= zeus::CVector3f(60.f);
|
x1d0_velInfo.x0_vel.back() *= zeus::CVector3f(60.f);
|
||||||
else
|
} else {
|
||||||
x1d0_velInfo.x0_vel.back() = zeus::skForward;
|
x1d0_velInfo.x0_vel.back() = zeus::skForward;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGunWeapon::LoadFxIdle(float dt, CStateManager& mgr) {
|
void CGunWeapon::LoadFxIdle(float dt, CStateManager& mgr) {
|
||||||
if (NWeaponTypes::are_tokens_ready(x12c_deps)) {
|
if (!NWeaponTypes::are_tokens_ready(x12c_deps)) {
|
||||||
if ((x210_loadFlags & 0x2) != 0 && (x210_loadFlags & 0x4) != 0 && (x210_loadFlags & 0x10) != 0)
|
return;
|
||||||
return;
|
}
|
||||||
bool loaded = true;
|
|
||||||
for (int i = 0; i < 2; ++i) {
|
|
||||||
if (!x16c_muzzleEffects[i].IsLoaded()) {
|
|
||||||
loaded = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!x144_weapons[i].IsLoaded()) {
|
|
||||||
loaded = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 2; ++i) {
|
if ((x210_loadFlags & 0x2) != 0 && (x210_loadFlags & 0x4) != 0 && (x210_loadFlags & 0x10) != 0) {
|
||||||
if (!x188_frozenEffects[i].IsLoaded()) {
|
return;
|
||||||
loaded = false;
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!x160_xferEffect.IsLoaded())
|
const bool muzzlesLoaded = std::all_of(x16c_muzzleEffects.cbegin(), x16c_muzzleEffects.cend(),
|
||||||
loaded = false;
|
[](const auto& muzzle) { return muzzle.IsLoaded(); });
|
||||||
|
if (!muzzlesLoaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (loaded) {
|
const bool weaponsLoaded =
|
||||||
if ((x210_loadFlags & 0x2) != 0x2) {
|
std::all_of(x144_weapons.cbegin(), x144_weapons.cend(), [](const auto& weapon) { return weapon.IsLoaded(); });
|
||||||
LoadMuzzleFx(dt);
|
if (!weaponsLoaded) {
|
||||||
x210_loadFlags |= 0x2;
|
return;
|
||||||
}
|
}
|
||||||
x210_loadFlags |= 0x10;
|
|
||||||
if ((x210_loadFlags & 0x4) != 0x4) {
|
const bool frozenLoaded = std::all_of(x188_frozenEffects.cbegin(), x188_frozenEffects.cend(),
|
||||||
LoadProjectileData(mgr);
|
[](const auto& effect) { return effect.IsLoaded(); });
|
||||||
x210_loadFlags |= 0x4;
|
if (!frozenLoaded) {
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!x160_xferEffect.IsLoaded()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((x210_loadFlags & 0x2) != 0x2) {
|
||||||
|
LoadMuzzleFx(dt);
|
||||||
|
x210_loadFlags |= 0x2;
|
||||||
|
}
|
||||||
|
x210_loadFlags |= 0x10;
|
||||||
|
if ((x210_loadFlags & 0x4) != 0x4) {
|
||||||
|
LoadProjectileData(mgr);
|
||||||
|
x210_loadFlags |= 0x4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,12 +468,15 @@ void CGunWeapon::Load(CStateManager& mgr, bool subtypeBasePose) {
|
||||||
x1b8_frozenGenerator.reset();
|
x1b8_frozenGenerator.reset();
|
||||||
x104_gunCharacter.Lock();
|
x104_gunCharacter.Lock();
|
||||||
x160_xferEffect.Lock();
|
x160_xferEffect.Lock();
|
||||||
for (int i = 0; i < 2; ++i) {
|
|
||||||
|
for (size_t i = 0; i < x16c_muzzleEffects.size(); ++i) {
|
||||||
x16c_muzzleEffects[i].Lock();
|
x16c_muzzleEffects[i].Lock();
|
||||||
x144_weapons[i].Lock();
|
x144_weapons[i].Lock();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 2; ++i)
|
|
||||||
x188_frozenEffects[i].Lock();
|
for (auto& frozenEffect : x188_frozenEffects) {
|
||||||
|
frozenEffect.Lock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGunWeapon::Unload(CStateManager& mgr) {
|
void CGunWeapon::Unload(CStateManager& mgr) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ public:
|
||||||
enum class EFrozenFxType { None, Frozen, Thawed };
|
enum class EFrozenFxType { None, Frozen, Thawed };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const s32 skShootAnim[2];
|
static const std::array<s32, 2> skShootAnim;
|
||||||
zeus::CVector3f x4_scale;
|
zeus::CVector3f x4_scale;
|
||||||
std::optional<CModelData> x10_solidModelData;
|
std::optional<CModelData> x10_solidModelData;
|
||||||
std::optional<CModelData> x60_holoModelData;
|
std::optional<CModelData> x60_holoModelData;
|
||||||
|
|
|
@ -1,9 +1,20 @@
|
||||||
#include "CWaveBeam.hpp"
|
#include "Runtime/Weapon/CWaveBeam.hpp"
|
||||||
#include "GameGlobalObjects.hpp"
|
|
||||||
#include "CSimplePool.hpp"
|
#include <array>
|
||||||
#include "CEnergyProjectile.hpp"
|
|
||||||
|
#include "Runtime/CSimplePool.hpp"
|
||||||
|
#include "Runtime/GameGlobalObjects.hpp"
|
||||||
|
#include "Runtime/Weapon/CEnergyProjectile.hpp"
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
namespace {
|
||||||
|
constexpr float skShotAnglePitch = 120.f;
|
||||||
|
|
||||||
|
constexpr std::array<u16, 2> kSoundId{
|
||||||
|
SFXwpn_fire_wave_normal,
|
||||||
|
SFXwpn_fire_wave_charged,
|
||||||
|
};
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
CWaveBeam::CWaveBeam(CAssetId characterId, EWeaponType type, TUniqueId playerId, EMaterialTypes playerMaterial,
|
CWaveBeam::CWaveBeam(CAssetId characterId, EWeaponType type, TUniqueId playerId, EMaterialTypes playerMaterial,
|
||||||
const zeus::CVector3f& scale)
|
const zeus::CVector3f& scale)
|
||||||
|
@ -50,9 +61,6 @@ void CWaveBeam::UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr,
|
||||||
CGunWeapon::UpdateGunFx(shotSmoke, dt, mgr, xf);
|
CGunWeapon::UpdateGunFx(shotSmoke, dt, mgr, xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const float skShotAnglePitch = 120.f;
|
|
||||||
static const u16 kSoundId[] = {SFXwpn_fire_wave_normal, SFXwpn_fire_wave_charged};
|
|
||||||
|
|
||||||
void CWaveBeam::Fire(bool underwater, float dt, EChargeState chargeState, const zeus::CTransform& xf,
|
void CWaveBeam::Fire(bool underwater, float dt, EChargeState chargeState, const zeus::CTransform& xf,
|
||||||
CStateManager& mgr, TUniqueId homingTarget, float chargeFactor1, float chargeFactor2) {
|
CStateManager& mgr, TUniqueId homingTarget, float chargeFactor1, float chargeFactor2) {
|
||||||
if (chargeState == EChargeState::Charged) {
|
if (chargeState == EChargeState::Charged) {
|
||||||
|
@ -74,8 +82,8 @@ void CWaveBeam::Fire(bool underwater, float dt, EChargeState chargeState, const
|
||||||
if (chargeState == EChargeState::Charged)
|
if (chargeState == EChargeState::Charged)
|
||||||
x218_25_enableCharge = true;
|
x218_25_enableCharge = true;
|
||||||
|
|
||||||
NWeaponTypes::play_sfx(kSoundId[int(chargeState)], underwater, false, 0.165f);
|
NWeaponTypes::play_sfx(kSoundId[size_t(chargeState)], underwater, false, 0.165f);
|
||||||
CAnimPlaybackParms parms(skShootAnim[int(chargeState)], -1, 1.f, true);
|
const CAnimPlaybackParms parms(skShootAnim[size_t(chargeState)], -1, 1.f, true);
|
||||||
x10_solidModelData->GetAnimationData()->EnableLooping(false);
|
x10_solidModelData->GetAnimationData()->EnableLooping(false);
|
||||||
x10_solidModelData->GetAnimationData()->SetAnimation(parms, false);
|
x10_solidModelData->GetAnimationData()->SetAnimation(parms, false);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue