2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-06-07 03:53:27 +00:00

Finish CGunWeapon

This commit is contained in:
Jack Andersen 2017-09-04 17:00:19 -10:00
parent 640623f3ef
commit 361aa1512b
38 changed files with 990 additions and 169 deletions

View File

@ -3,6 +3,7 @@
#include "ITweak.hpp" #include "ITweak.hpp"
#include "Runtime/IFactory.hpp" #include "Runtime/IFactory.hpp"
#include "Runtime/CPlayerState.hpp"
namespace DataSpec namespace DataSpec
{ {
@ -10,14 +11,7 @@ namespace DataSpec
struct ITweakGunRes : ITweak struct ITweakGunRes : ITweak
{ {
using ResId = urde::CAssetId; using ResId = urde::CAssetId;
enum class EBeamId using EBeamId = urde::CPlayerState::EBeamId;
{
Power,
Ice,
Wave,
Plasma,
Phazon
};
ResId x4_gunMotion; ResId x4_gunMotion;
ResId x8_grappleArm; ResId x8_grappleArm;
@ -54,6 +48,7 @@ struct ITweakGunRes : ITweak
b = 0; b = 0;
switch (EBeamId(b)) switch (EBeamId(b))
{ {
default:
case EBeamId::Power: case EBeamId::Power:
return x10_powerBeam; return x10_powerBeam;
case EBeamId::Ice: case EBeamId::Ice:

View File

@ -6,29 +6,32 @@
namespace DataSpec namespace DataSpec
{ {
/* Same as CDamageInfo */
struct SShotParam : BigYAML struct SShotParam : BigYAML
{ {
DECL_YAML DECL_YAML
Value<atUint32> weaponType = -1; Value<atInt32> weaponType = -1;
bool charged : 1;
bool combo : 1;
bool instaKill : 1;
Value<float> damage = 0.f; Value<float> damage = 0.f;
Value<float> radiusDamage = 0.f; Value<float> radiusDamage = 0.f;
Value<float> radius = 0.f; Value<float> radius = 0.f;
Value<float> knockback = 0.f; Value<float> knockback = 0.f;
virtual bool Charged() const { return false; } bool noImmunity : 1;
virtual bool Comboed() const { return false; } SShotParam() { charged = false; combo = false; instaKill = false; noImmunity = false; }
virtual bool InstaKill() const { return false; }
}; };
struct SComboShotParam : SShotParam struct SComboShotParam : SShotParam
{ {
DECL_YAML DECL_YAML
bool Comboed() const { return true; } SComboShotParam() { combo = true; }
}; };
struct SChargedShotParam : SShotParam struct SChargedShotParam : SShotParam
{ {
DECL_YAML DECL_YAML
bool Charged() const { return true; } SChargedShotParam() { charged = true; }
}; };
struct SWeaponInfo : BigYAML struct SWeaponInfo : BigYAML

View File

@ -95,7 +95,8 @@ public:
Ice, Ice,
Wave, Wave,
Plasma, Plasma,
Phazon = 27 Phazon,
Phazon2 = 27
}; };
private: private:

View File

@ -2314,7 +2314,7 @@ void CStateManager::UpdateRoomAcoustics(TAreaId aid)
return; return;
} }
int idx = updateCount * x900_activeRandom->Float() * 0.99f; auto idx = int(updateCount * x900_activeRandom->Float() * 0.99f);
updates[idx]->EnableAuxCallbacks(); updates[idx]->EnableAuxCallbacks();
} }

View File

@ -440,6 +440,7 @@ public:
float GetThermalColdScale2() const { return xf28_thermColdScale2; } float GetThermalColdScale2() const { return xf28_thermColdScale2; }
void SetThermalColdScale2(float s) { xf28_thermColdScale2 = s; } void SetThermalColdScale2(float s) { xf28_thermColdScale2 = s; }
float IntegrateVisorFog(float f) const; float IntegrateVisorFog(float f) const;
u32 GetUpdateFrameIndex() const { return x8d8_updateFrameIdx; }
static float g_EscapeShakeCountdown; static float g_EscapeShakeCountdown;
static bool g_EscapeShakeCountdownInit; static bool g_EscapeShakeCountdownInit;

View File

@ -147,4 +147,9 @@ CCameraShakeData CCameraShakeData::LoadCameraShakeData(CInputStream& in)
return {duration, 100.f, 0, zeus::CVector3f::skZero, shaker1, shaker2, shaker3}; return {duration, 100.f, 0, zeus::CVector3f::skZero, shaker1, shaker2, shaker3};
} }
const CCameraShakeData CCameraShakeData::skChargedCameraShakeData =
{0.3f, 100.f, 0, zeus::CVector3f::skZero, CCameraShakerComponent(),
CCameraShakerComponent(1, {0, 0.f, 0.f, 0.3f, -1.f}, {1, 0.f, 0.f, 0.05f, 0.3f}),
CCameraShakerComponent()};
} }

View File

@ -51,6 +51,7 @@ class CCameraShakeData
float xd0_f2; float xd0_f2;
public: public:
static const CCameraShakeData skChargedCameraShakeData;
CCameraShakeData(float duration, float f2, u32 w1, const zeus::CVector3f& sfxPos, CCameraShakeData(float duration, float f2, u32 w1, const zeus::CVector3f& sfxPos,
const CCameraShakerComponent& shaker1, const CCameraShakerComponent& shaker2, const CCameraShakerComponent& shaker1, const CCameraShakerComponent& shaker2,
const CCameraShakerComponent& shaker3); const CCameraShakerComponent& shaker3);

View File

@ -54,6 +54,33 @@ void CModelData::Render(const CStateManager& stateMgr, const zeus::CTransform& x
Render(GetRenderingModel(stateMgr), xf, lights, drawFlags); Render(GetRenderingModel(stateMgr), xf, lights, drawFlags);
} }
bool CModelData::IsLoaded(int shaderIdx) const
{
if (x10_animData)
{
if (!x10_animData->xd8_modelData->GetModel()->IsLoaded(shaderIdx))
return false;
if (const CSkinnedModel* model = x10_animData->xf4_xrayModel.get())
if (!model->GetModel()->IsLoaded(shaderIdx))
return false;
if (const CSkinnedModel* model = x10_animData->xf8_infraModel.get())
if (!model->GetModel()->IsLoaded(shaderIdx))
return false;
}
if (const CModel* model = x1c_normalModel.GetObj())
if (!model->IsLoaded(shaderIdx))
return false;
if (const CModel* model = x2c_xrayModel.GetObj())
if (!model->IsLoaded(shaderIdx))
return false;
if (const CModel* model = x3c_infraModel.GetObj())
if (!model->IsLoaded(shaderIdx))
return false;
return true;
}
CModelData::EWhichModel CModelData::GetRenderingModel(const CStateManager& stateMgr) CModelData::EWhichModel CModelData::GetRenderingModel(const CStateManager& stateMgr)
{ {
switch (stateMgr.GetPlayerState()->GetActiveVisor(stateMgr)) switch (stateMgr.GetPlayerState()->GetActiveVisor(stateMgr))

View File

@ -111,6 +111,7 @@ public:
SAdvancementDeltas GetAdvancementDeltas(const CCharAnimTime& a, const CCharAnimTime& b) const; SAdvancementDeltas GetAdvancementDeltas(const CCharAnimTime& a, const CCharAnimTime& b) const;
void Render(const CStateManager& stateMgr, const zeus::CTransform& xf, void Render(const CStateManager& stateMgr, const zeus::CTransform& xf,
const CActorLights* lights, const CModelFlags& drawFlags) const; const CActorLights* lights, const CModelFlags& drawFlags) const;
bool IsLoaded(int shaderIdx) const;
static EWhichModel GetRenderingModel(const CStateManager& stateMgr); static EWhichModel GetRenderingModel(const CStateManager& stateMgr);
CSkinnedModel& PickAnimatedModel(EWhichModel which) const; CSkinnedModel& PickAnimatedModel(EWhichModel which) const;
const std::unique_ptr<CBooModel>& PickStaticModel(EWhichModel which) const; const std::unique_ptr<CBooModel>& PickStaticModel(EWhichModel which) const;

View File

@ -12,6 +12,10 @@ boo::IShaderPipeline* CElementGenShaders::m_texAdditiveZTest = nullptr;
boo::IShaderPipeline* CElementGenShaders::m_texAdditiveNoZTest = nullptr; boo::IShaderPipeline* CElementGenShaders::m_texAdditiveNoZTest = nullptr;
boo::IShaderPipeline* CElementGenShaders::m_texRedToAlphaZTest = nullptr; boo::IShaderPipeline* CElementGenShaders::m_texRedToAlphaZTest = nullptr;
boo::IShaderPipeline* CElementGenShaders::m_texRedToAlphaNoZTest = nullptr; boo::IShaderPipeline* CElementGenShaders::m_texRedToAlphaNoZTest = nullptr;
boo::IShaderPipeline* CElementGenShaders::m_texZTestNoZWriteSub = nullptr;
boo::IShaderPipeline* CElementGenShaders::m_texNoZTestNoZWriteSub = nullptr;
boo::IShaderPipeline* CElementGenShaders::m_texRedToAlphaZTestSub = nullptr;
boo::IShaderPipeline* CElementGenShaders::m_texRedToAlphaNoZTestSub = nullptr;
boo::IShaderPipeline* CElementGenShaders::m_indTexZWrite = nullptr; boo::IShaderPipeline* CElementGenShaders::m_indTexZWrite = nullptr;
boo::IShaderPipeline* CElementGenShaders::m_indTexNoZWrite = nullptr; boo::IShaderPipeline* CElementGenShaders::m_indTexNoZWrite = nullptr;
@ -51,7 +55,9 @@ void CElementGenShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Conte
{ {
CGenDescription* desc = gen.x1c_genDesc.GetObj(); CGenDescription* desc = gen.x1c_genDesc.GetObj();
boo::IShaderPipeline* regPipeline = nullptr; boo::IShaderPipeline* regPipeline = nullptr;
boo::IShaderPipeline* regPipelineSub = nullptr;
boo::IShaderPipeline* redToAlphaPipeline = nullptr; boo::IShaderPipeline* redToAlphaPipeline = nullptr;
boo::IShaderPipeline* redToAlphaPipelineSub = nullptr;
boo::IShaderPipeline* regPipelinePmus = nullptr; boo::IShaderPipeline* regPipelinePmus = nullptr;
boo::IShaderPipeline* redToAlphaPipelinePmus = nullptr; boo::IShaderPipeline* redToAlphaPipelinePmus = nullptr;
@ -87,9 +93,17 @@ void CElementGenShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Conte
else else
{ {
if (gen.x26c_28_zTest) if (gen.x26c_28_zTest)
{
redToAlphaPipeline = m_texRedToAlphaZTest; redToAlphaPipeline = m_texRedToAlphaZTest;
regPipelineSub = m_texZTestNoZWriteSub;
redToAlphaPipelineSub = m_texRedToAlphaZTestSub;
}
else else
{
redToAlphaPipeline = m_texRedToAlphaNoZTest; redToAlphaPipeline = m_texRedToAlphaNoZTest;
regPipelineSub = m_texNoZTestNoZWriteSub;
redToAlphaPipelineSub = m_texRedToAlphaNoZTestSub;
}
if (gen.x26c_26_AAPH) if (gen.x26c_26_AAPH)
{ {
@ -164,7 +178,7 @@ void CElementGenShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Conte
} }
} }
CElementGenShaders shad(gen, regPipeline, redToAlphaPipeline, CElementGenShaders shad(gen, regPipeline, regPipelineSub, redToAlphaPipeline, redToAlphaPipelineSub,
regPipelinePmus, redToAlphaPipelinePmus); regPipelinePmus, redToAlphaPipelinePmus);
TShader<CElementGenShaders>::BuildShaderDataBinding(ctx, shad); TShader<CElementGenShaders>::BuildShaderDataBinding(ctx, shad);
} }

View File

@ -35,6 +35,10 @@ private:
static boo::IShaderPipeline* m_texAdditiveNoZTest; static boo::IShaderPipeline* m_texAdditiveNoZTest;
static boo::IShaderPipeline* m_texRedToAlphaZTest; static boo::IShaderPipeline* m_texRedToAlphaZTest;
static boo::IShaderPipeline* m_texRedToAlphaNoZTest; static boo::IShaderPipeline* m_texRedToAlphaNoZTest;
static boo::IShaderPipeline* m_texZTestNoZWriteSub;
static boo::IShaderPipeline* m_texNoZTestNoZWriteSub;
static boo::IShaderPipeline* m_texRedToAlphaZTestSub;
static boo::IShaderPipeline* m_texRedToAlphaNoZTestSub;
static boo::IShaderPipeline* m_indTexZWrite; static boo::IShaderPipeline* m_indTexZWrite;
static boo::IShaderPipeline* m_indTexNoZWrite; static boo::IShaderPipeline* m_indTexNoZWrite;
@ -57,15 +61,20 @@ private:
CElementGen& m_gen; CElementGen& m_gen;
boo::IShaderPipeline* m_regPipeline; boo::IShaderPipeline* m_regPipeline;
boo::IShaderPipeline* m_regPipelineSub;
boo::IShaderPipeline* m_redToAlphaPipeline; boo::IShaderPipeline* m_redToAlphaPipeline;
boo::IShaderPipeline* m_redToAlphaPipelineSub;
boo::IShaderPipeline* m_regPipelinePmus; boo::IShaderPipeline* m_regPipelinePmus;
boo::IShaderPipeline* m_redToAlphaPipelinePmus; boo::IShaderPipeline* m_redToAlphaPipelinePmus;
CElementGenShaders(CElementGen& gen, CElementGenShaders(CElementGen& gen,
boo::IShaderPipeline* regPipeline, boo::IShaderPipeline* regPipeline,
boo::IShaderPipeline* regPipelineSub,
boo::IShaderPipeline* redToAlphaPipeline, boo::IShaderPipeline* redToAlphaPipeline,
boo::IShaderPipeline* redToAlphaPipelineSub,
boo::IShaderPipeline* regPipelinePmus, boo::IShaderPipeline* regPipelinePmus,
boo::IShaderPipeline* redToAlphaPipelinePmus) boo::IShaderPipeline* redToAlphaPipelinePmus)
: m_gen(gen), m_regPipeline(regPipeline), m_redToAlphaPipeline(redToAlphaPipeline), : m_gen(gen), m_regPipeline(regPipeline), m_regPipelineSub(regPipelineSub),
m_redToAlphaPipeline(redToAlphaPipeline), m_redToAlphaPipelineSub(redToAlphaPipelineSub),
m_regPipelinePmus(regPipelinePmus), m_redToAlphaPipelinePmus(redToAlphaPipelinePmus) {} m_regPipelinePmus(regPipelinePmus), m_redToAlphaPipelinePmus(redToAlphaPipelinePmus) {}
public: public:

View File

@ -66,8 +66,8 @@ BOO_GLSL_BINDING_HEAD
"TBINDING0 uniform sampler2D tex;\n" "TBINDING0 uniform sampler2D tex;\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" colorOut = vtf.color * texture(tex, vtf.uv);\n" " colorOut = vtf.color;\n"
" colorOut.a = colorOut.r;\n" " colorOut.a = texture(tex, vtf.uv).r;\n"
"}\n"; "}\n";
static const char* VS_GLSL_INDTEX = static const char* VS_GLSL_INDTEX =
@ -302,10 +302,18 @@ struct OGLElementDataBindingFactory : TShader<CElementGenShaders>::IDataBindingF
gen.m_normalDataBind = ctx.newShaderDataBinding(shaders.m_regPipeline, vtxFmt, nullptr, gen.m_normalDataBind = ctx.newShaderDataBinding(shaders.m_regPipeline, vtxFmt, nullptr,
gen.m_instBuf, nullptr, 1, uniforms, gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr); nullptr, texCount, textures, nullptr, nullptr);
if (shaders.m_regPipelineSub)
gen.m_normalSubDataBind = ctx.newShaderDataBinding(shaders.m_regPipelineSub, vtxFmt, nullptr,
gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr);
if (shaders.m_redToAlphaPipeline) if (shaders.m_redToAlphaPipeline)
gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, vtxFmt, nullptr, gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, vtxFmt, nullptr,
gen.m_instBuf, nullptr, 1, uniforms, gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr); nullptr, texCount, textures, nullptr, nullptr);
if (shaders.m_redToAlphaPipelineSub)
gen.m_redToAlphaSubDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipelineSub, vtxFmt, nullptr,
gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr);
} }
if (gen.m_instBufPmus) if (gen.m_instBufPmus)
@ -368,6 +376,24 @@ TShader<CElementGenShaders>::IDataBindingFactory* CElementGenShaders::Initialize
boo::Primitive::TriStrips, boo::ZTest::None, false, boo::Primitive::TriStrips, boo::ZTest::None, false,
true, false, boo::CullMode::None); true, false, boo::CullMode::None);
m_texZTestNoZWriteSub = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, 1, TexNames, 1, UniNames,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
true, false, boo::CullMode::None);
m_texNoZTestNoZWriteSub = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, 1, TexNames, 1, UniNames,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::None, false,
true, false, boo::CullMode::None);
m_texRedToAlphaZTestSub = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX_REDTOALPHA, 1, TexNames, 1, UniNames,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
true, false, boo::CullMode::None);
m_texRedToAlphaNoZTestSub = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX_REDTOALPHA, 1, TexNames, 1, UniNames,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::None, false,
true, false, boo::CullMode::None);
m_indTexZWrite = ctx.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_INDTEX, 3, TindTexNames, 1, UniNames, m_indTexZWrite = ctx.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_INDTEX, 3, TindTexNames, 1, UniNames,
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
boo::Primitive::TriStrips, boo::ZTest::None, true, boo::Primitive::TriStrips, boo::ZTest::None, true,
@ -457,10 +483,19 @@ struct VulkanElementDataBindingFactory : TShader<CElementGenShaders>::IDataBindi
gen.m_normalDataBind = ctx.newShaderDataBinding(shaders.m_regPipeline, nullptr, nullptr, gen.m_normalDataBind = ctx.newShaderDataBinding(shaders.m_regPipeline, nullptr, nullptr,
gen.m_instBuf, nullptr, 1, uniforms, gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr); nullptr, texCount, textures, nullptr, nullptr);
if (shaders.m_regPipelineSub)
gen.m_normalSubDataBind = ctx.newShaderDataBinding(shaders.m_regPipelineSub, nullptr, nullptr,
gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr);
if (shaders.m_redToAlphaPipeline) if (shaders.m_redToAlphaPipeline)
gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, nullptr, nullptr, gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, nullptr, nullptr,
gen.m_instBuf, nullptr, 1, uniforms, gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr); nullptr, texCount, textures, nullptr, nullptr);
if (shaders.m_redToAlphaPipelineSub)
gen.m_redToAlphaSubDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipelineSub, nullptr, nullptr,
gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr);
} }
if (gen.m_instBufPmus) if (gen.m_instBufPmus)
@ -561,6 +596,24 @@ TShader<CElementGenShaders>::IDataBindingFactory* CElementGenShaders::Initialize
boo::Primitive::TriStrips, boo::ZTest::None, false, boo::Primitive::TriStrips, boo::ZTest::None, false,
true, false, boo::CullMode::None); true, false, boo::CullMode::None);
m_texZTestNoZWriteSub = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
true, false, boo::CullMode::None);
m_texNoZTestNoZWriteSub = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::None, false,
true, false, boo::CullMode::None);
m_texRedToAlphaZTestSub = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX_REDTOALPHA, m_vtxFormatTex,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
true, false, boo::CullMode::None);
m_texRedToAlphaNoZTestSub = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX_REDTOALPHA, m_vtxFormatTex,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::None, false,
true, false, boo::CullMode::None);
m_indTexZWrite = ctx.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_INDTEX, m_vtxFormatIndTex, m_indTexZWrite = ctx.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_INDTEX, m_vtxFormatIndTex,
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
boo::Primitive::TriStrips, boo::ZTest::LEqual, true, boo::Primitive::TriStrips, boo::ZTest::LEqual, true,

View File

@ -65,8 +65,7 @@ static const char* FS_HLSL_TEX_REDTOALPHA =
"\n" "\n"
"float4 main(in VertToFrag vtf) : SV_Target0\n" "float4 main(in VertToFrag vtf) : SV_Target0\n"
"{\n" "{\n"
" float4 colr = vtf.color * tex0.Sample(samp, vtf.uv);\n" " return float4(vtf.color.rgb, tex0.Sample(samp, vtf.uv).r);\n"
" return float4(colr.rgb, colr.r);"
"}\n"; "}\n";
static const char* VS_HLSL_INDTEX = static const char* VS_HLSL_INDTEX =
@ -222,11 +221,21 @@ struct D3DElementDataBindingFactory : TShader<CElementGenShaders>::IDataBindingF
gen.m_instBuf, nullptr, 1, uniforms, gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, texCount, textures,
nullptr, nullptr); nullptr, nullptr);
if (shaders.m_regPipelineSub)
gen.m_normalSubDataBind = ctx.newShaderDataBinding(shaders.m_regPipelineSub, nullptr, nullptr,
gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures,
nullptr, nullptr);
if (shaders.m_redToAlphaPipeline) if (shaders.m_redToAlphaPipeline)
gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, nullptr, nullptr, gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, nullptr, nullptr,
gen.m_instBuf, nullptr, 1, uniforms, gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, texCount, textures,
nullptr, nullptr); nullptr, nullptr);
if (shaders.m_redToAlphaPipelineSub)
gen.m_redToAlphaSubDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipelineSub, nullptr, nullptr,
gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures,
nullptr, nullptr);
} }
if (gen.m_instBufPmus) if (gen.m_instBufPmus)
@ -334,6 +343,28 @@ TShader<CElementGenShaders>::IDataBindingFactory* CElementGenShaders::Initialize
boo::Primitive::TriStrips, boo::ZTest::None, false, boo::Primitive::TriStrips, boo::ZTest::None, false,
true, false, boo::CullMode::None); true, false, boo::CullMode::None);
m_texZTestNoZWriteSub = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX, nullptr, nullptr,
nullptr, m_vtxFormatTex,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
true, false, boo::CullMode::None);
m_texNoZTestNoZWriteSub = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX, nullptr, nullptr,
nullptr, m_vtxFormatTex,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::None, false,
true, false, boo::CullMode::None);
m_texRedToAlphaZTestSub = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX_REDTOALPHA, nullptr, nullptr,
nullptr, m_vtxFormatTex,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
true, false, boo::CullMode::None);
m_texRedToAlphaNoZTestSub = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX_REDTOALPHA, nullptr, nullptr,
nullptr, m_vtxFormatTex,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::None, false,
true, false, boo::CullMode::None);
m_indTexZWrite = ctx.newShaderPipeline(VS_HLSL_INDTEX, FS_HLSL_INDTEX, nullptr, nullptr, m_indTexZWrite = ctx.newShaderPipeline(VS_HLSL_INDTEX, FS_HLSL_INDTEX, nullptr, nullptr,
nullptr, m_vtxFormatIndTex, nullptr, m_vtxFormatIndTex,
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,

View File

@ -71,8 +71,7 @@ static const char* FS_METAL_TEX_REDTOALPHA =
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n" "fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n"
" texture2d<float> tex0 [[ texture(0) ]])\n" " texture2d<float> tex0 [[ texture(0) ]])\n"
"{\n" "{\n"
" float4 colr = vtf.color * tex0.sample(samp, vtf.uv);\n" " return float4(vtf.color.rgb, tex0.sample(samp, vtf.uv).r);\n"
" return float4(colr.rgb, colr.r);"
"}\n"; "}\n";
static const char* VS_METAL_INDTEX = static const char* VS_METAL_INDTEX =
@ -242,10 +241,18 @@ struct MetalElementDataBindingFactory : TShader<CElementGenShaders>::IDataBindin
gen.m_normalDataBind = ctx.newShaderDataBinding(shader.m_regPipeline, nullptr, nullptr, gen.m_normalDataBind = ctx.newShaderDataBinding(shader.m_regPipeline, nullptr, nullptr,
gen.m_instBuf, nullptr, 1, uniforms, gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr); nullptr, texCount, textures, nullptr, nullptr);
if (shader.m_regPipelineSub)
gen.m_normalSubDataBind = ctx.newShaderDataBinding(shader.m_regPipelineSub, nullptr, nullptr,
gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr);
if (shader.m_redToAlphaPipeline) if (shader.m_redToAlphaPipeline)
gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shader.m_redToAlphaPipeline, nullptr, nullptr, gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shader.m_redToAlphaPipeline, nullptr, nullptr,
gen.m_instBuf, nullptr, 1, uniforms, gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr); nullptr, texCount, textures, nullptr, nullptr);
if (shader.m_redToAlphaPipelineSub)
gen.m_redToAlphaSubDataBind = ctx.newShaderDataBinding(shader.m_redToAlphaPipelineSub, nullptr, nullptr,
gen.m_instBuf, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr);
} }
if (gen.m_instBufPmus) if (gen.m_instBufPmus)
@ -254,11 +261,11 @@ struct MetalElementDataBindingFactory : TShader<CElementGenShaders>::IDataBindin
texCount = std::min(texCount, 1); texCount = std::min(texCount, 1);
if (shader.m_regPipelinePmus) if (shader.m_regPipelinePmus)
gen.m_normalDataBind = ctx.newShaderDataBinding(shader.m_regPipelinePmus, nullptr, nullptr, gen.m_normalDataBindPmus = ctx.newShaderDataBinding(shader.m_regPipelinePmus, nullptr, nullptr,
gen.m_instBufPmus, nullptr, 1, uniforms, gen.m_instBufPmus, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr); nullptr, texCount, textures, nullptr, nullptr);
if (shader.m_redToAlphaPipelinePmus) if (shader.m_redToAlphaPipelinePmus)
gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shader.m_redToAlphaPipelinePmus, nullptr, nullptr, gen.m_redToAlphaDataBindPmus = ctx.newShaderDataBinding(shader.m_redToAlphaPipelinePmus, nullptr, nullptr,
gen.m_instBufPmus, nullptr, 1, uniforms, gen.m_instBufPmus, nullptr, 1, uniforms,
nullptr, texCount, textures, nullptr, nullptr); nullptr, texCount, textures, nullptr, nullptr);
} }
@ -343,6 +350,28 @@ TShader<CElementGenShaders>::IDataBindingFactory* CElementGenShaders::Initialize
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
boo::Primitive::TriStrips, boo::ZTest::None, false, true, true, boo::CullMode::None); boo::Primitive::TriStrips, boo::ZTest::None, false, true, true, boo::CullMode::None);
m_texZTestNoZWriteSub = ctx.newShaderPipeline(VS_METAL_TEX, FS_METAL_TEX, m_vtxFormatTex,
CGraphics::g_ViewportSamples,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
true, false, boo::CullMode::None);
m_texNoZTestNoZWriteSub = ctx.newShaderPipeline(VS_METAL_TEX, FS_METAL_TEX, m_vtxFormatTex,
CGraphics::g_ViewportSamples,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::None, false,
true, false, boo::CullMode::None);
m_texRedToAlphaZTestSub = ctx.newShaderPipeline(VS_METAL_TEX, FS_METAL_TEX_REDTOALPHA, m_vtxFormatTex,
CGraphics::g_ViewportSamples,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
true, false, boo::CullMode::None);
m_texRedToAlphaNoZTestSub = ctx.newShaderPipeline(VS_METAL_TEX, FS_METAL_TEX_REDTOALPHA, m_vtxFormatTex,
CGraphics::g_ViewportSamples,
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
boo::Primitive::TriStrips, boo::ZTest::None, false,
true, false, boo::CullMode::None);
m_indTexZWrite = ctx.newShaderPipeline(VS_METAL_INDTEX, FS_METAL_INDTEX, m_vtxFormatIndTex, m_indTexZWrite = ctx.newShaderPipeline(VS_METAL_INDTEX, FS_METAL_INDTEX, m_vtxFormatIndTex,
CGraphics::g_ViewportSamples, CGraphics::g_ViewportSamples,
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,

View File

@ -374,7 +374,7 @@ bool CInventoryScreen::IsRightInventoryItemEquipped(int idx) const
case 3: // Plasma Beam case 3: // Plasma Beam
return playerState.GetCurrentBeam() == CPlayerState::EBeamId::Plasma; return playerState.GetCurrentBeam() == CPlayerState::EBeamId::Plasma;
case 4: // Phazon Beam case 4: // Phazon Beam
return playerState.GetCurrentBeam() == CPlayerState::EBeamId::Phazon; return playerState.GetCurrentBeam() == CPlayerState::EBeamId::Phazon2;
case 5: // Morph Ball case 5: // Morph Ball
return playerState.HasPowerUp(CPlayerState::EItemType::MorphBall); return playerState.HasPowerUp(CPlayerState::EItemType::MorphBall);
case 6: // Boost Ball case 6: // Boost Ball

View File

@ -90,7 +90,8 @@ CFlameThrower* MP1::CActorContraption::CreateFlameThrower(const std::string& nam
CFlameInfo flameInfo(6, 6, x308_flameFxId, 20, 0.5f, 1.f, 1.f); CFlameInfo flameInfo(6, 6, x308_flameFxId, 20, 0.5f, 1.f, 1.f);
CFlameThrower* ret = new CFlameThrower(x300_flameThrowerGen, name, EWeaponType::Missile, flameInfo, CFlameThrower* ret = new CFlameThrower(x300_flameThrowerGen, name, EWeaponType::Missile, flameInfo,
zeus::CTransform::Identity(), EMaterialTypes::CollisionActor, x30c_dInfo, zeus::CTransform::Identity(), EMaterialTypes::CollisionActor, x30c_dInfo,
id, GetAreaId(), GetUniqueId(), 0, -1, -1, -1); id, GetAreaId(), GetUniqueId(), CWeapon::EProjectileAttrib::None,
-1, -1, -1);
x2e8_children.emplace_back(id, name); x2e8_children.emplace_back(id, name);

View File

@ -18,6 +18,7 @@ static logvisor::Module Log("urde::CElementGen");
URDE_DECL_SPECIALIZE_SHADER(CElementGenShaders) URDE_DECL_SPECIALIZE_SHADER(CElementGenShaders)
u16 CElementGen::g_GlobalSeed = 99; u16 CElementGen::g_GlobalSeed = 99;
bool CElementGen::g_subtractBlend = false;
int CElementGen::g_ParticleAliveCount; int CElementGen::g_ParticleAliveCount;
int CElementGen::g_ParticleSystemAliveCount; int CElementGen::g_ParticleSystemAliveCount;
@ -1152,16 +1153,20 @@ void CElementGen::RenderModels()
else else
{ {
CModel* model = desc->x5c_x48_PMDL.m_token.GetObj(); CModel* model = desc->x5c_x48_PMDL.m_token.GetObj();
if (desc->x44_31_x31_25_PMAB) if (g_subtractBlend)
{ {
model->Draw({3, 0, 1, col}); model->Draw({5, 0, 1, zeus::CColor(1.f, 0.5f)});
}
else if (desc->x44_31_x31_25_PMAB)
{
model->Draw({7, 0, 1, col});
} }
else else
{ {
if (1.f == col.a) if (1.f == col.a)
model->Draw({0, 0, 3, zeus::CColor::skWhite}); model->Draw({0, 0, 3, zeus::CColor::skWhite});
else else
model->Draw({4, 0, 1, col}); model->Draw({5, 0, 1, col});
} }
} }
@ -1389,10 +1394,20 @@ void CElementGen::RenderParticles()
if (sMoveRedToAlphaBuffer && x26c_26_AAPH) if (sMoveRedToAlphaBuffer && x26c_26_AAPH)
moveRedToAlphaBuffer = true; moveRedToAlphaBuffer = true;
if (g_subtractBlend)
{
if (moveRedToAlphaBuffer)
CGraphics::SetShaderDataBinding(m_redToAlphaSubDataBind);
else
CGraphics::SetShaderDataBinding(m_normalSubDataBind);
}
else
{
if (moveRedToAlphaBuffer) if (moveRedToAlphaBuffer)
CGraphics::SetShaderDataBinding(m_redToAlphaDataBind); CGraphics::SetShaderDataBinding(m_redToAlphaDataBind);
else else
CGraphics::SetShaderDataBinding(m_normalDataBind); CGraphics::SetShaderDataBinding(m_normalDataBind);
}
int mbspVal = std::max(1, x270_MBSP); int mbspVal = std::max(1, x270_MBSP);

View File

@ -27,8 +27,10 @@ class CParticleElectric;
class CElementGen : public CParticleGen class CElementGen : public CParticleGen
{ {
static u16 g_GlobalSeed; static u16 g_GlobalSeed;
static bool g_subtractBlend;
public: public:
static void SetGlobalSeed(u16 seed) { g_GlobalSeed = seed; } static void SetGlobalSeed(u16 seed) { g_GlobalSeed = seed; }
static void SetSubtractBlend(bool s) { g_subtractBlend = s; }
enum class EModelOrientationType enum class EModelOrientationType
{ {
Normal, Normal,
@ -172,7 +174,9 @@ public:
boo::GraphicsDataToken m_gfxToken; boo::GraphicsDataToken m_gfxToken;
boo::IShaderDataBinding* m_normalDataBind = nullptr; boo::IShaderDataBinding* m_normalDataBind = nullptr;
boo::IShaderDataBinding* m_normalSubDataBind = nullptr;
boo::IShaderDataBinding* m_redToAlphaDataBind = nullptr; boo::IShaderDataBinding* m_redToAlphaDataBind = nullptr;
boo::IShaderDataBinding* m_redToAlphaSubDataBind = nullptr;
boo::IGraphicsBufferD* m_instBuf = nullptr; boo::IGraphicsBufferD* m_instBuf = nullptr;
boo::IGraphicsBufferD* m_uniformBuf = nullptr; boo::IGraphicsBufferD* m_uniformBuf = nullptr;

View File

@ -5,9 +5,10 @@ namespace urde
{ {
CBeamProjectile::CBeamProjectile(const TToken<CWeaponDescription>& wDesc, const std::string& name, EWeaponType wType, CBeamProjectile::CBeamProjectile(const TToken<CWeaponDescription>& wDesc, const std::string& name, EWeaponType wType,
const zeus::CTransform& xf, int attribs, float f1, float f2, EMaterialTypes matType, const zeus::CTransform& xf, int flags, float f1, float f2, EMaterialTypes matType,
const CDamageInfo& dInfo, TUniqueId owner, TAreaId aid, TUniqueId uid, u32 w1, bool b1) const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner,
: CGameProjectile(false, wDesc, name, wType, xf, matType, dInfo, owner, aid, uid, kInvalidUniqueId, w1, false, EProjectileAttrib attribs, bool b1)
: CGameProjectile(false, wDesc, name, wType, xf, matType, dInfo, uid, aid, owner, kInvalidUniqueId, attribs, false,
zeus::CVector3f::skOne, {}, -1, false) zeus::CVector3f::skOne, {}, -1, false)
{ {
} }

View File

@ -7,8 +7,10 @@ namespace urde
class CBeamProjectile : public CGameProjectile class CBeamProjectile : public CGameProjectile
{ {
public: public:
CBeamProjectile(const TToken<CWeaponDescription>&, const std::string&, EWeaponType, const zeus::CTransform&, int, CBeamProjectile(const TToken<CWeaponDescription>& wDesc, const std::string& name, EWeaponType wType,
float, float, EMaterialTypes, const CDamageInfo&, TUniqueId, TAreaId, TUniqueId, u32, bool); const zeus::CTransform& xf, int flags, float f1, float f2, EMaterialTypes matType,
const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner,
EProjectileAttrib attribs, bool b1);
void Accept(IVisitor &visitor); void Accept(IVisitor &visitor);
float GetMaxRadius() const; float GetMaxRadius() const;

View File

@ -5,12 +5,12 @@ namespace urde
CEnergyProjectile::CEnergyProjectile(bool active, const TToken<CWeaponDescription>& desc, EWeaponType type, CEnergyProjectile::CEnergyProjectile(bool active, const TToken<CWeaponDescription>& desc, EWeaponType type,
const zeus::CTransform& xf, EMaterialTypes materials, const CDamageInfo& damage, const zeus::CTransform& xf, EMaterialTypes materials, const CDamageInfo& damage,
TUniqueId id0, TAreaId aid, TUniqueId id1, TUniqueId id2, u32 w1, bool b1, TUniqueId uid, TAreaId aid, TUniqueId owner, TUniqueId homingTarget,
const zeus::CVector3f& scale, EProjectileAttrib attribs, bool underwater, const zeus::CVector3f& scale,
const rstl::optional_object<TLockedToken<CGenDescription>>& particle, const rstl::optional_object<TLockedToken<CGenDescription>>& particle,
s16 w2, bool b2) s16 w2, bool b2)
: CGameProjectile(active, desc, "GameProjectile", type, xf, materials, damage, id0, aid, : CGameProjectile(active, desc, "GameProjectile", type, xf, materials, damage, uid, aid,
id1, id2, w1, b1, scale, particle, w2, b2), owner, homingTarget, attribs, underwater, scale, particle, w2, b2),
x2ec_dir(xf.basis[1]), x2f8_mag(x2ec_dir.magnitude()), x2ec_dir(xf.basis[1]), x2f8_mag(x2ec_dir.magnitude()),
x2fc_camShake(CCameraShakeData::BuildProjectileCameraShake(0.5f, 0.75f)) x2fc_camShake(CCameraShakeData::BuildProjectileCameraShake(0.5f, 0.75f))
{ {

View File

@ -28,8 +28,8 @@ class CEnergyProjectile : public CGameProjectile
public: public:
CEnergyProjectile(bool active, const TToken<CWeaponDescription>& desc, EWeaponType type, CEnergyProjectile(bool active, const TToken<CWeaponDescription>& desc, EWeaponType type,
const zeus::CTransform& xf, EMaterialTypes materials, const CDamageInfo& damage, const zeus::CTransform& xf, EMaterialTypes materials, const CDamageInfo& damage,
TUniqueId id0, TAreaId aid, TUniqueId id1, TUniqueId id2, u32 w1, bool b1, TUniqueId uid, TAreaId aid, TUniqueId owner, TUniqueId homingTarget,
const zeus::CVector3f& scale, EProjectileAttrib attribs, bool underwater, const zeus::CVector3f& scale,
const rstl::optional_object<TLockedToken<CGenDescription>>& particle, const rstl::optional_object<TLockedToken<CGenDescription>>& particle,
s16 w2, bool b2); s16 w2, bool b2);
}; };

View File

@ -10,9 +10,9 @@ const zeus::CVector3f CFlameThrower::kLightOffset(0, 3.f, 2.f);
CFlameThrower::CFlameThrower(const TToken<CWeaponDescription>& wDesc, const std::string& name, EWeaponType wType, CFlameThrower::CFlameThrower(const TToken<CWeaponDescription>& wDesc, const std::string& name, EWeaponType wType,
const CFlameInfo& flameInfo, const zeus::CTransform& xf, EMaterialTypes matType, const CFlameInfo& flameInfo, const zeus::CTransform& xf, EMaterialTypes matType,
const CDamageInfo& dInfo, TUniqueId owner, TAreaId aId, TUniqueId uid, u32 w1, u32 w2, const CDamageInfo& dInfo, TUniqueId uid, TAreaId aId, TUniqueId owner,
s16 sId, u32 w3) EProjectileAttrib attribs, u32 w2, s16 sId, u32 w3)
: CGameProjectile(false, wDesc, name, wType, xf, matType, dInfo, owner, aId, uid, kInvalidUniqueId, w1, false, : CGameProjectile(false, wDesc, name, wType, xf, matType, dInfo, uid, aId, owner, kInvalidUniqueId, attribs, false,
zeus::CVector3f(1.f), {}, -1, false) zeus::CVector3f(1.f), {}, -1, false)
, x2e8_(xf) , x2e8_(xf)
, x33c_flameDesc(g_SimplePool->GetObj({FOURCC('PART'), flameInfo.GetFlameFxId()})) , x33c_flameDesc(g_SimplePool->GetObj({FOURCC('PART'), flameInfo.GetFlameFxId()}))

View File

@ -27,8 +27,8 @@ class CFlameThrower : public CGameProjectile
public: public:
CFlameThrower(const TToken<CWeaponDescription>& wDesc, const std::string& name, EWeaponType wType, CFlameThrower(const TToken<CWeaponDescription>& wDesc, const std::string& name, EWeaponType wType,
const CFlameInfo& flameInfo, const zeus::CTransform& xf, EMaterialTypes matType, const CFlameInfo& flameInfo, const zeus::CTransform& xf, EMaterialTypes matType,
const CDamageInfo& dInfo, TUniqueId owner, TAreaId aId, TUniqueId uid, u32 w1, u32 w2, s16 sId, const CDamageInfo& dInfo, TUniqueId uid, TAreaId aId, TUniqueId owner, EProjectileAttrib attribs,
u32 w3); u32 w2, s16 sId, u32 w3);
void Accept(IVisitor& visitor); void Accept(IVisitor& visitor);
void SetTransform(const zeus::CTransform& xf); void SetTransform(const zeus::CTransform& xf);

View File

@ -8,14 +8,15 @@ namespace urde
{ {
CGameProjectile::CGameProjectile(bool active, const TToken<CWeaponDescription>&, const std::string& name, CGameProjectile::CGameProjectile(bool active, const TToken<CWeaponDescription>&, const std::string& name,
EWeaponType wType, const zeus::CTransform& xf, EMaterialTypes matType, EWeaponType wType, const zeus::CTransform& xf, EMaterialTypes matType,
const CDamageInfo& dInfo, TUniqueId owner, TAreaId aid, TUniqueId uid, TUniqueId, const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner,
u32 w1, bool b2, const zeus::CVector3f&, TUniqueId homingTarget, EProjectileAttrib attribs, bool underwater,
const rstl::optional_object<TLockedToken<CGenDescription>>&, s16, bool b3) const zeus::CVector3f& scale,
: CWeapon(owner, aid, active, uid, wType, name, xf, const rstl::optional_object<TLockedToken<CGenDescription>>& particle, s16 s1, bool b3)
: CWeapon(uid, aid, active, owner, wType, name, xf,
CMaterialFilter::MakeIncludeExclude( CMaterialFilter::MakeIncludeExclude(
{EMaterialTypes::NonSolidDamageable, matType}, {EMaterialTypes::NonSolidDamageable, matType},
{EMaterialTypes::Projectile, EMaterialTypes::ProjectilePassthrough, matType, EMaterialTypes::Solid}), {EMaterialTypes::Projectile, EMaterialTypes::ProjectilePassthrough, matType, EMaterialTypes::Solid}),
CMaterialList(), dInfo, EProjectileAttrib(w1) | GetBeamAttribType(wType), CModelData::CModelDataNull()) CMaterialList(), dInfo, attribs | GetBeamAttribType(wType), CModelData::CModelDataNull())
{ {
} }
@ -23,25 +24,25 @@ void CGameProjectile::Accept(urde::IVisitor& visitor) { visitor.Visit(this); }
void CGameProjectile::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId /*uid*/, CStateManager& mgr) void CGameProjectile::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId /*uid*/, CStateManager& mgr)
{ {
if (msg == EScriptObjectMessage::UpdateSplashInhabitant) if (msg == EScriptObjectMessage::AddSplashInhabitant)
{ {
if (!x2e4_27_) if (!x2e4_27_inWater)
{ {
x2e4_27_ = true; x2e4_27_inWater = true;
x2e4_26_ = true; x2e4_26_waterUpdate = true;
} }
} }
else if (msg == EScriptObjectMessage::UpdateSplashInhabitant) else if (msg == EScriptObjectMessage::UpdateSplashInhabitant)
{ {
if (!x2e4_26_) if (!x2e4_26_waterUpdate)
x2e4_26_ = true; x2e4_26_waterUpdate = true;
} }
else if (msg == EScriptObjectMessage::RemoveSplashInhabitant) else if (msg == EScriptObjectMessage::RemoveSplashInhabitant)
{ {
if (x2e4_26_) if (x2e4_26_waterUpdate)
{ {
x2e4_26_ = false; x2e4_26_waterUpdate = false;
x2e4_27_ = false; x2e4_27_inWater = false;
} }
} }
else if (msg == EScriptObjectMessage::Deleted) else if (msg == EScriptObjectMessage::Deleted)

View File

@ -24,15 +24,17 @@ class CGameProjectile : public CWeapon
{ {
bool x2e4_24_ : 1; bool x2e4_24_ : 1;
bool x2e4_25_ : 1; bool x2e4_25_ : 1;
bool x2e4_26_ : 1; bool x2e4_26_waterUpdate : 1;
bool x2e4_27_ : 1; bool x2e4_27_inWater : 1;
bool x2e4_28_ : 1; bool x2e4_28_ : 1;
}; };
}; };
public: public:
CGameProjectile(bool, const TToken<CWeaponDescription>&, const std::string&, EWeaponType, const zeus::CTransform&, CGameProjectile(bool active, const TToken<CWeaponDescription>&, const std::string& name,
EMaterialTypes, const CDamageInfo&, TUniqueId, TAreaId, TUniqueId, TUniqueId, u32, bool, EWeaponType wType, const zeus::CTransform& xf, EMaterialTypes matType,
const zeus::CVector3f&, const rstl::optional_object<TLockedToken<CGenDescription>>&, s16, bool); const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner,
TUniqueId homingTarget, EProjectileAttrib attribs, bool underwater, const zeus::CVector3f& scale,
const rstl::optional_object<TLockedToken<CGenDescription>>& particle, s16 s1, bool b3);
virtual void Accept(IVisitor &visitor); virtual void Accept(IVisitor &visitor);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager &); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager &);

View File

@ -1,11 +1,16 @@
#include "CGunWeapon.hpp" #include "CGunWeapon.hpp"
#include "GameGlobalObjects.hpp" #include "GameGlobalObjects.hpp"
#include "CSimplePool.hpp" #include "CSimplePool.hpp"
#include "Character/CModelData.hpp" #include "CDependencyGroup.hpp"
#include "CGameState.hpp"
#include "CWeapon.hpp"
#include "CEnergyProjectile.hpp"
#include "Graphics/CSkinnedModel.hpp"
#include "Graphics/CVertexMorphEffect.hpp"
namespace urde namespace urde
{ {
const char* CGunWeapon::skBeamXferNames[5] = static const char* skBeamXferNames[] =
{ {
"PowerXfer", "PowerXfer",
"IceXfer", "IceXfer",
@ -14,7 +19,7 @@ const char* CGunWeapon::skBeamXferNames[5] =
"PhazonXfer" "PhazonXfer"
}; };
const char* CGunWeapon::skSuitArmNames[8] = static const char* skSuitArmNames[] =
{ {
"PowerArm", "PowerArm",
"GravityArm", "GravityArm",
@ -26,19 +31,65 @@ const char* CGunWeapon::skSuitArmNames[8] =
"FusionArmP", "FusionArmP",
}; };
s32 GetWeaponIndex(EWeaponType type) static const char* skMuzzleNames[] =
{
"PowerMuzzle",
"PowerCharge",
"IceMuzzle",
"IceCharge",
"PowerMuzzle",
"WaveCharge",
"PlasmaMuzzle",
"PlasmaCharge",
"PhazonMuzzle",
"EmptyMuzzle"
};
static const char* skFrozenNames[] =
{
"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"
};
static const char* skAnimDependencyNames[] =
{
"Power_Anim_DGRP",
"Ice_Anim_DGRP",
"Wave_Anim_DGRP",
"Plasma_Anim_DGRP",
"Phazon_Anim_DGRP"
};
CPlayerState::EBeamId GetWeaponIndex(EWeaponType type)
{ {
if (type == EWeaponType::Power) if (type == EWeaponType::Power)
return 0; return CPlayerState::EBeamId::Power;
else if (type == EWeaponType::Ice) else if (type == EWeaponType::Ice)
return 1; return CPlayerState::EBeamId::Ice;
else if (type == EWeaponType::Wave) else if (type == EWeaponType::Wave)
return 2; return CPlayerState::EBeamId::Wave;
else if (type == EWeaponType::Plasma) else if (type == EWeaponType::Plasma)
return 3; return CPlayerState::EBeamId::Plasma;
else if (type == EWeaponType::Phazon) else if (type == EWeaponType::Phazon)
return 4; return CPlayerState::EBeamId::Phazon;
return 0; return CPlayerState::EBeamId::Power;
} }
CGunWeapon::CGunWeapon(CAssetId ancsId, EWeaponType type, TUniqueId playerId, CGunWeapon::CGunWeapon(CAssetId ancsId, EWeaponType type, TUniqueId playerId,
@ -46,26 +97,86 @@ CGunWeapon::CGunWeapon(CAssetId ancsId, EWeaponType type, TUniqueId playerId,
: 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))])),
x1c0_weaponType(type), x1c0_weaponType(type),
x1c4_playerId(playerId), x1c4_playerId(playerId),
x1c8_playerMaterial(playerMaterial) x1c8_playerMaterial(playerMaterial),
x200_beamId(GetWeaponIndex(type)),
x20c_shaderIdx(u32(x200_beamId)),
x214_ancsId(ancsId)
{ {
AllocResPools(x200_beamId);
BuildDependencyList(x200_beamId);
}
void CGunWeapon::AllocResPools(CPlayerState::EBeamId beam)
{
const CAssetId* wPair = g_tweakGunRes->GetWeaponPair(beam);
const char** muzzleNames = &skMuzzleNames[int(beam) * 2];
const char** frozenNames = &skFrozenNames[int(beam) * 2];
for (int i=0 ; i<2 ; ++i)
{
x16c_muzzleEffects.push_back(g_SimplePool->GetObj(muzzleNames[i]));
x144_weapons.push_back(g_SimplePool->GetObj(SObjectTag{FOURCC('WPSC'), wPair[1]}));
x188_frozenEffects.push_back(g_SimplePool->GetObj(frozenNames[i]));
}
}
void CGunWeapon::FreeResPools()
{
x160_xferEffect.Unlock();
for (int i=0 ; i<2 ; ++i)
{
x16c_muzzleEffects[i].Unlock();
x144_weapons[i].Unlock();
x188_frozenEffects[i].Unlock();
}
x10c_anims.clear();
x1a4_muzzleGenerators.clear();
x1d0_velInfo.Clear();
}
void CGunWeapon::FillTokenVector(const std::vector<SObjectTag>& tags, std::vector<CToken>& objects)
{
for (const SObjectTag& tag : tags)
objects.push_back(g_SimplePool->GetObj(tag));
}
void CGunWeapon::BuildDependencyList(CPlayerState::EBeamId beam)
{
TLockedToken<CDependencyGroup> deps = g_SimplePool->GetObj(skDependencyNames[int(beam)]);
TLockedToken<CDependencyGroup> animDeps = g_SimplePool->GetObj(skAnimDependencyNames[int(beam)]);
x12c_deps.reserve(deps->GetObjectTagVector().size() + animDeps->GetObjectTagVector().size());
FillTokenVector(deps->GetObjectTagVector(), x12c_deps);
FillTokenVector(animDeps->GetObjectTagVector(), x12c_deps);
} }
void CGunWeapon::AsyncLoadSuitArm(CStateManager& mgr) void CGunWeapon::AsyncLoadSuitArm(CStateManager& mgr)
{ {
xb0_suitArmModelData = std::experimental::nullopt;
x13c_armCharacter = g_SimplePool->GetObj(skSuitArmNames[int(NWeaponTypes::get_current_suit(mgr))]);
x13c_armCharacter.Lock();
x218_28_suitArmLocked = true;
} }
void CGunWeapon::AllocResPools(CPlayerState::EBeamId) void CGunWeapon::Reset(CStateManager& mgr)
{ {
if (!x218_26_loaded)
return;
x10_solidModelData->AnimationData()->EnableLooping(false);
if (x218_25_enableCharge)
x218_25_enableCharge = false;
else
x100_gunController->Reset();
} }
static const s32 skAnimTypeList[] = { 0, 4, 1, 2, 3, 5, 6, 7, 8, 9, 10 }; 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 && type >= NWeaponTypes::EGunAnimType::BasePosition && if (x218_26_loaded && type >= NWeaponTypes::EGunAnimType::BasePosition &&
type <= NWeaponTypes::EGunAnimType::ToBeam) type <= NWeaponTypes::EGunAnimType::ToBeam)
{ {
x10_solidModelData->AnimationData()->EnableLooping(loop); x10_solidModelData->AnimationData()->EnableLooping(loop);
@ -74,54 +185,520 @@ void CGunWeapon::PlayAnim(NWeaponTypes::EGunAnimType type, bool loop)
} }
} }
void CGunWeapon::BuildSecondaryEffect(ESecondaryFxType type) void CGunWeapon::PreRenderGunFx(const CStateManager& mgr, const zeus::CTransform& xf)
{
// Empty
}
void CGunWeapon::PostRenderGunFx(const CStateManager& mgr, const zeus::CTransform& xf)
{
if (x218_26_loaded && x1b8_frozenGenerator && x204_frozenEffect != EFrozenFxType::None)
x1b8_frozenGenerator->Render();
}
void CGunWeapon::UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr, const zeus::CTransform& xf)
{
if (x218_26_loaded && x204_frozenEffect != EFrozenFxType::None)
{
if (x204_frozenEffect == EFrozenFxType::Thawed)
{
if (x1b8_frozenGenerator->IsSystemDeletable())
{
x1b8_frozenGenerator.reset();
}
else
{
x1b8_frozenGenerator->SetTranslation(xf.origin);
x1b8_frozenGenerator->SetOrientation(xf.getRotation());
}
}
else
{
x1b8_frozenGenerator->SetGlobalOrientAndTrans(xf);
}
if (x1b8_frozenGenerator)
x1b8_frozenGenerator->Update(dt);
}
}
const s32 CGunWeapon::skShootAnim[2] = { 4, 3 };
void CGunWeapon::Fire(bool underwater, float dt, EChargeState chargeState, const zeus::CTransform& xf,
CStateManager& mgr, TUniqueId homingTarget, float chargeFactor1, float chargeFactor2)
{
CDamageInfo dInfo = GetDamageInfo(mgr, chargeState, chargeFactor1);
zeus::CVector3f scale(chargeState == EChargeState::Normal ? 1.f : chargeFactor2);
bool partialCharge = chargeState == EChargeState::Normal ? false : std::fabs(chargeFactor1 - 1.f) >= 0.00001f;
CWeapon::EProjectileAttrib attribs = CWeapon::EProjectileAttrib::ArmCannon;
if (partialCharge)
attribs |= CWeapon::EProjectileAttrib::PartialCharge;
if (chargeState == EChargeState::Charged)
attribs |= CWeapon::EProjectileAttrib::Charged;
CEnergyProjectile* proj = new CEnergyProjectile(true, x144_weapons[int(chargeState)], x1c0_weaponType,
xf, x1c8_playerMaterial, dInfo, mgr.AllocateUniqueId(),
kInvalidAreaId, x1c4_playerId, homingTarget, attribs,
underwater, scale, {}, -1, false);
mgr.AddObject(proj);
proj->Think(dt, mgr);
if (chargeState == EChargeState::Charged)
{
x218_25_enableCharge = true;
mgr.GetCameraManager()->AddCameraShaker(CCameraShakeData::skChargedCameraShakeData, false);
}
x10_solidModelData->AnimationData()->EnableLooping(false);
CAnimPlaybackParms parms(skShootAnim[int(chargeState)], -1, 1.f, true);
x10_solidModelData->AnimationData()->SetAnimation(parms, false);
}
void CGunWeapon::EnableFx(bool enable)
{
// Empty
}
void CGunWeapon::EnableSecondaryFx(ESecondaryFxType type)
{
x1cc_enabledSecondaryEffect = type;
}
void CGunWeapon::EnableFrozenEffect(EFrozenFxType type)
{ {
switch (type) switch (type)
{ {
case ESecondaryFxType::Two: case EFrozenFxType::Thawed:
if (x204_secondaryEffectType == ESecondaryFxType::Two) if (x204_frozenEffect == EFrozenFxType::Thawed)
break; break;
x1b8_secondaryEffect = std::make_unique<CElementGen>(x188_secondaryEffects[1], x1b8_frozenGenerator = std::make_unique<CElementGen>(x188_frozenEffects[1],
CElementGen::EModelOrientationType::Normal, CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One); CElementGen::EOptionalSystemFlags::One);
x1b8_secondaryEffect->SetGlobalScale(x4_scale); x1b8_frozenGenerator->SetGlobalScale(x4_scale);
break; break;
case ESecondaryFxType::One: case EFrozenFxType::Frozen:
if (x204_secondaryEffectType == ESecondaryFxType::One) if (x204_frozenEffect == EFrozenFxType::Frozen)
break; break;
x1b8_secondaryEffect = std::make_unique<CElementGen>(x188_secondaryEffects[0], x1b8_frozenGenerator = std::make_unique<CElementGen>(x188_frozenEffects[0],
CElementGen::EModelOrientationType::Normal, CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One); CElementGen::EOptionalSystemFlags::One);
x1b8_secondaryEffect->SetGlobalScale(x4_scale); x1b8_frozenGenerator->SetGlobalScale(x4_scale);
break; break;
default: default:
break; break;
} }
x204_secondaryEffectType = type; x204_frozenEffect = type;
} }
void CGunWeapon::ActivateCharge(bool b1, bool b2) void CGunWeapon::ActivateCharge(bool enable, bool resetEffect)
{ {
x1a4_muzzleGenerators[x208_muzzleEffectIdx]->SetParticleEmission(false);
x208_muzzleEffectIdx = u32(enable);
if (enable || resetEffect)
{
x1a4_muzzleGenerators[x208_muzzleEffectIdx] =
std::make_unique<CElementGen>(x16c_muzzleEffects[x208_muzzleEffectIdx],
CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One);
}
} }
void CGunWeapon::Touch(const CStateManager& mgr) void CGunWeapon::Touch(const CStateManager& mgr)
{ {
if (x10_solidModelData)
{
x10_solidModelData->Touch(mgr, x20c_shaderIdx);
if (xb0_suitArmModelData)
xb0_suitArmModelData->Touch(mgr, 0);
}
} }
void CGunWeapon::TouchHolo(const CStateManager& mgr) void CGunWeapon::TouchHolo(const CStateManager& mgr)
{ {
if (x60_holoModelData)
x60_holoModelData->Touch(mgr, 0);
}
void CGunWeapon::PointGenerator(void* ctx, const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn)
{
reinterpret_cast<CRainSplashGenerator*>(ctx)->GeneratePoints(vn);
}
void CGunWeapon::Draw(bool drawSuitArm, const CStateManager& mgr, const zeus::CTransform& xf,
const CModelFlags& flags, const CActorLights* lights) const
{
if (!x218_26_loaded)
return;
zeus::CTransform armXf = xf * x10_solidModelData->GetScaledLocatorTransform("elbow");
if (x1bc_rainSplashGenerator && x1bc_rainSplashGenerator->IsRaining())
CSkinnedModel::SetPointGeneratorFunc(x1bc_rainSplashGenerator, PointGenerator);
if (mgr.GetParticleFlags() == 0 && x200_beamId != CPlayerState::EBeamId::Ice)
{
zeus::CColor color1(flags.x4_color.a, flags.x4_color.a);
zeus::CColor color2(0.25f, 0.25f);
if (x218_29_drawHologram)
DrawHologram(mgr, xf, flags);
else
x10_solidModelData->RenderThermal(xf, color1, color2);
if (drawSuitArm && xb0_suitArmModelData)
{
xb0_suitArmModelData->RenderThermal(xf, color1, color2);
}
}
else
{
if (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::XRay && !x218_29_drawHologram)
{
CModelFlags useFlags = flags;
useFlags.x1_matSetIdx = u8(x20c_shaderIdx);
x10_solidModelData->Render(mgr, xf, lights, useFlags);
}
else
{
DrawHologram(mgr, xf, flags);
}
if (drawSuitArm && xb0_suitArmModelData)
{
xb0_suitArmModelData->Render(mgr, armXf, lights, flags);
}
}
if (x1bc_rainSplashGenerator && x1bc_rainSplashGenerator->IsRaining())
{
CSkinnedModel::ClearPointGeneratorFunc();
x1bc_rainSplashGenerator->Draw(xf);
}
}
void CGunWeapon::DrawMuzzleFx(const CStateManager& mgr) const
{
if (const CElementGen* effect = x1a4_muzzleGenerators[x208_muzzleEffectIdx].get())
{
if (x200_beamId != CPlayerState::EBeamId::Ice &&
mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay)
{
CElementGen::SetSubtractBlend(true);
const_cast<CElementGen*>(effect)->Render();
CElementGen::SetSubtractBlend(false);
}
else
{
const_cast<CElementGen*>(effect)->Render();
}
}
}
void CGunWeapon::LoadSuitArm(CStateManager& mgr)
{
if (x13c_armCharacter.IsLoaded())
{
CAssetId armId = NWeaponTypes::get_asset_id_from_name(skSuitArmNames[int(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)
{
s32 defaultAnim = x218_27_subtypeBasePose ? 0 : 9;
x10_solidModelData.emplace(CAnimRes(x214_ancsId, 0, x4_scale, defaultAnim, false));
x60_holoModelData.emplace(CAnimRes(x214_ancsId, 1, x4_scale, defaultAnim, false));
CAnimPlaybackParms parms(defaultAnim, -1, 1.f, true);
x10_solidModelData->AnimationData()->SetAnimation(parms, true);
LoadSuitArm(mgr);
x10_solidModelData->SetSortThermal(true);
x60_holoModelData->SetSortThermal(true);
x100_gunController = std::make_unique<CGunController>(*x10_solidModelData);
}
void CGunWeapon::LoadAnimations()
{
NWeaponTypes::get_token_vector(*x10_solidModelData->GetAnimationData(), 0, 15, x10c_anims, true);
}
bool CGunWeapon::IsAnimsLoaded() const
{
for (const CToken& tok : x10c_anims)
if (!tok.IsLoaded())
return false;
return true;
}
void CGunWeapon::LoadMuzzleFx(float dt)
{
for (int i=0 ; i<2 ; ++i)
{
x1a4_muzzleGenerators.push_back(std::make_unique<CElementGen>(x16c_muzzleEffects[i],
CElementGen::EModelOrientationType::Normal, CElementGen::EOptionalSystemFlags::One));
x1a4_muzzleGenerators.back()->SetParticleEmission(false);
x1a4_muzzleGenerators.back()->Update(dt);
}
}
void CGunWeapon::LoadProjectileData(CStateManager& mgr)
{
CRandom16 random(mgr.GetUpdateFrameIndex());
CGlobalRandom grand(random);
for (int i=0 ; i<2 ; ++i)
{
zeus::CVector3f weaponVel;
if (const CVectorElement* ivec = x144_weapons[i]->x4_IVEC.get())
ivec->GetValue(0, weaponVel);
x1d0_velInfo.x0_vel.push_back(weaponVel);
float tratVal = 0.f;
if (const CRealElement* trat = x144_weapons[i]->x30_TRAT.get())
trat->GetValue(0, tratVal);
x1d0_velInfo.x24_trat.push_back(tratVal);
x1d0_velInfo.x1c_targetHoming.push_back(x144_weapons[i]->x29_HOMG);
if (weaponVel.y > 0.f)
x1d0_velInfo.x0_vel.back() *= zeus::CVector3f(60.f);
else
x1d0_velInfo.x0_vel.back() = zeus::CVector3f::skForward;
}
}
void CGunWeapon::LoadFxIdle(float dt, CStateManager& mgr)
{
if (NWeaponTypes::are_tokens_ready(x12c_deps))
{
if ((x210_ & 0x2) != 0 && (x210_ & 0x4) != 0 && (x210_ & 0x10) != 0)
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 (!x188_frozenEffects[i].IsLoaded())
{
loaded = false;
break;
}
}
if (!x160_xferEffect.IsLoaded())
loaded = false;
if (loaded)
{
if ((x210_ & 0x2) != 0x2)
{
LoadMuzzleFx(dt);
x210_ |= 0x2;
}
x210_ |= 0x10;
if ((x210_ & 0x4) != 0x4)
{
LoadProjectileData(mgr);
x210_ |= 0x4;
}
}
}
}
void CGunWeapon::Update(float dt, CStateManager& mgr)
{
if (x218_26_loaded)
{
x10_solidModelData->AdvanceAnimation(dt, mgr, kInvalidAreaId, true);
x100_gunController->Update(dt, mgr);
if (x218_28_suitArmLocked)
LoadSuitArm(mgr);
}
else
{
if (x104_gunCharacter)
{
if (x104_gunCharacter.IsLoaded())
{
if ((x210_ & 0x1) != 0x1)
{
LoadGunModels(mgr);
LoadAnimations();
x210_ |= 0x1;
}
if ((x210_ & 0x8) != 0x8)
{
if (IsAnimsLoaded())
x210_ |= 0x8;
}
}
LoadFxIdle(dt, mgr);
if ((x210_ & 0x1f) == 0x1f)
{
if (x10_solidModelData->PickAnimatedModel(CModelData::EWhichModel::Normal).GetModel()->
IsLoaded(x20c_shaderIdx) && xb0_suitArmModelData->IsLoaded(0))
x218_26_loaded = true;
}
}
}
}
void CGunWeapon::LockTokens(CStateManager& mgr)
{
AsyncLoadSuitArm(mgr);
NWeaponTypes::lock_tokens(x12c_deps);
}
void CGunWeapon::UnlockTokens()
{
x13c_armCharacter.Unlock();
NWeaponTypes::unlock_tokens(x12c_deps);
}
void CGunWeapon::Load(CStateManager& mgr, bool subtypeBasePose)
{
LockTokens(mgr);
x218_27_subtypeBasePose = subtypeBasePose;
x204_frozenEffect = EFrozenFxType::None;
x1b8_frozenGenerator.reset();
x104_gunCharacter.Lock();
x160_xferEffect.Lock();
for (int i=0 ; i<2 ; ++i)
{
x16c_muzzleEffects[i].Lock();
x144_weapons[i].Lock();
}
for (int i=0 ; i<2 ; ++i)
x188_frozenEffects[i].Lock();
}
void CGunWeapon::Unload(CStateManager& mgr)
{
UnlockTokens();
x210_ = 0;
x204_frozenEffect = EFrozenFxType::None;
x10_solidModelData = std::experimental::nullopt;
x60_holoModelData = std::experimental::nullopt;
xb0_suitArmModelData = std::experimental::nullopt;
x100_gunController.reset();
x1bc_rainSplashGenerator = nullptr;
x1b8_frozenGenerator.reset();
FreeResPools();
x104_gunCharacter.Unlock();
x218_26_loaded = false;
}
bool CGunWeapon::IsLoaded() const
{
return x218_26_loaded;
} }
void CGunWeapon::DrawHologram(const CStateManager& mgr, const zeus::CTransform& xf, const CModelFlags& flags) const void CGunWeapon::DrawHologram(const CStateManager& mgr, const zeus::CTransform& xf, const CModelFlags& flags) const
{ {
if (!x218_26_loaded)
return;
if (x218_29_drawHologram)
{
CModelFlags useFlags = flags;
useFlags.m_extendedShader = EExtendedShader::Flat;
x60_holoModelData->Render(CModelData::EWhichModel::Normal, xf, nullptr, useFlags);
}
else
{
CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x10_solidModelData->GetScale()));
//CGraphics::DisableAllLights();
//g_Renderer->SetAmbientColor(zeus::CColor::skWhite);
CSkinnedModel& model =
const_cast<CSkinnedModel&>(*x60_holoModelData->GetAnimationData()->GetModelData());
model.GetModelInst()->ActivateLights({CLight::BuildLocalAmbient({}, zeus::CColor::skWhite)});
const_cast<CGunWeapon*>(this)->x10_solidModelData->AnimationData()->Render(model, flags, {}, nullptr);
//g_Renderer->SetAmbientColor(zeus::CColor::skWhite);
//CGraphics::DisableAllLights();
}
} }
void CGunWeapon::UpdateMuzzleFx(float dt, const zeus::CVector3f& scale, const zeus::CVector3f& pos, bool emitting) void CGunWeapon::UpdateMuzzleFx(float dt, const zeus::CVector3f& scale, const zeus::CVector3f& pos, bool emitting)
{ {
x1a4_muzzleGenerators[x208_muzzleEffectIdx]->SetGlobalTranslation(pos);
x1a4_muzzleGenerators[x208_muzzleEffectIdx]->SetGlobalScale(scale);
x1a4_muzzleGenerators[x208_muzzleEffectIdx]->SetParticleEmission(emitting);
x1a4_muzzleGenerators[x208_muzzleEffectIdx]->Update(dt);
}
void CGunWeapon::ReturnToDefault(CStateManager& mgr)
{
x100_gunController->ReturnToDefault(mgr, 0.f, false);
}
bool CGunWeapon::PlayPasAnim(SamusGun::EAnimationState state, CStateManager& mgr, float angle)
{
switch (state)
{
case SamusGun::EAnimationState::ComboFire:
x100_gunController->EnterComboFire(mgr, s32(x200_beamId));
return true;
default:
return false;
case SamusGun::EAnimationState::Wander:
return true;
}
}
void CGunWeapon::UnLoadFidget()
{
x100_gunController->UnLoadFidget();
}
bool CGunWeapon::IsFidgetLoaded() const
{
return x100_gunController->IsFidgetLoaded();
}
void CGunWeapon::AsyncLoadFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 animSet)
{
x100_gunController->LoadFidgetAnimAsync(mgr, s32(type), s32(x200_beamId), animSet);
}
void CGunWeapon::EnterFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 parm2)
{
x100_gunController->EnterFidget(mgr, s32(type), s32(x200_beamId), parm2);
}
CDamageInfo CGunWeapon::GetShotDamageInfo(const SShotParam& shotParam, CStateManager& mgr) const
{
CDamageInfo ret(shotParam);
if (g_GameState->GetHardMode())
ret.MultiplyDamage(g_GameState->GetHardModeWeaponMultiplier());
return ret;
}
CDamageInfo CGunWeapon::GetDamageInfo(CStateManager& mgr, EChargeState chargeState, float chargeFactor) const
{
const SWeaponInfo& wInfo = GetWeaponInfo();
if (chargeState == EChargeState::Normal)
{
return GetShotDamageInfo(wInfo.x4_normal, mgr);
}
else
{
SShotParam param = wInfo.x20_charged;
param.damage *= chargeFactor;
param.radiusDamage *= chargeFactor;
param.radius *= chargeFactor;
param.knockback *= chargeFactor;
param.noImmunity = false;
return GetShotDamageInfo(param, mgr);
}
} }
const SWeaponInfo& CGunWeapon::GetWeaponInfo() const const SWeaponInfo& CGunWeapon::GetWeaponInfo() const
@ -145,7 +722,7 @@ zeus::CAABox CGunWeapon::GetBounds(const zeus::CTransform& xf) const
bool CGunWeapon::IsChargeAnimOver() const bool CGunWeapon::IsChargeAnimOver() const
{ {
return false; return !(x218_25_enableCharge && x10_solidModelData->GetAnimationData()->IsAnimTimeRemaining(0.001f, "Whole Body"));
} }
} }

View File

@ -13,6 +13,7 @@
#include "CGunController.hpp" #include "CGunController.hpp"
#include "WeaponCommon.hpp" #include "WeaponCommon.hpp"
#include "CGunMotion.hpp" #include "CGunMotion.hpp"
#include "World/CDamageInfo.hpp"
namespace urde namespace urde
{ {
@ -28,16 +29,24 @@ enum class EChargeState
}; };
using SWeaponInfo = DataSpec::SWeaponInfo; using SWeaponInfo = DataSpec::SWeaponInfo;
using SShotParam = DataSpec::SShotParam;
using SChargedShotParam = DataSpec::SChargedShotParam;
class CVelocityInfo class CVelocityInfo
{ {
friend class CGunWeapon; friend class CGunWeapon;
rstl::reserved_vector<zeus::CVector3f, 2> x0_vel; rstl::reserved_vector<zeus::CVector3f, 2> x0_vel;
rstl::reserved_vector<bool, 2> x1c_targetHoming; rstl::reserved_vector<bool, 2> x1c_targetHoming;
rstl::reserved_vector<float, 2> x24_; rstl::reserved_vector<float, 2> x24_trat;
public: public:
const zeus::CVector3f& GetVelocity(int i) const { return x0_vel[i]; } const zeus::CVector3f& GetVelocity(int i) const { return x0_vel[i]; }
bool GetTargetHoming(int i) const { return x1c_targetHoming[i]; } bool GetTargetHoming(int i) const { return x1c_targetHoming[i]; }
void Clear()
{
x0_vel.clear();
x1c_targetHoming.clear();
x24_trat.clear();
}
}; };
class CGunWeapon class CGunWeapon
@ -50,33 +59,39 @@ public:
Two, Two,
Three Three
}; };
enum class EFrozenFxType
{
None,
Frozen,
Thawed
};
protected: protected:
static const char* skBeamXferNames[5]; static const s32 skShootAnim[2];
static const char* skAnimDependencyNames[5];
static const char* skDependencyNames[5];
static const char* skSuitArmNames[8];
zeus::CVector3f x4_scale; zeus::CVector3f x4_scale;
std::experimental::optional<CModelData> x10_solidModelData; std::experimental::optional<CModelData> x10_solidModelData;
std::experimental::optional<CModelData> x60_; std::experimental::optional<CModelData> x60_holoModelData;
std::experimental::optional<CModelData> xb0_; std::experimental::optional<CModelData> xb0_suitArmModelData;
std::unique_ptr<CGunController> x100_gunController; std::unique_ptr<CGunController> x100_gunController;
TToken<CAnimCharacterSet> x104_gunCharacter; TToken<CAnimCharacterSet> x104_gunCharacter;
std::vector<CToken> x10c_anims;
std::vector<CToken> x12c_deps;
TToken<CAnimCharacterSet> x13c_armCharacter; TToken<CAnimCharacterSet> x13c_armCharacter;
rstl::reserved_vector<TCachedToken<CWeaponDescription>, 2> x144_weapons; rstl::reserved_vector<TCachedToken<CWeaponDescription>, 2> x144_weapons;
TCachedToken<CGenDescription> x160_xferEffect; TCachedToken<CGenDescription> x160_xferEffect;
rstl::reserved_vector<TCachedToken<CGenDescription>, 2> x16c_muzzleEffects; rstl::reserved_vector<TCachedToken<CGenDescription>, 2> x16c_muzzleEffects;
rstl::reserved_vector<TCachedToken<CGenDescription>, 2> x188_secondaryEffects; rstl::reserved_vector<TCachedToken<CGenDescription>, 2> x188_frozenEffects;
rstl::reserved_vector<std::unique_ptr<CElementGen>, 2> x1a4_muzzleGenerators; rstl::reserved_vector<std::unique_ptr<CElementGen>, 2> x1a4_muzzleGenerators;
std::unique_ptr<CElementGen> x1b8_secondaryEffect; std::unique_ptr<CElementGen> x1b8_frozenGenerator;
CRainSplashGenerator* x1bc_rainSplashGenerator = nullptr; CRainSplashGenerator* x1bc_rainSplashGenerator = nullptr;
EWeaponType x1c0_weaponType; EWeaponType x1c0_weaponType;
TUniqueId x1c4_playerId; TUniqueId x1c4_playerId;
EMaterialTypes x1c8_playerMaterial; EMaterialTypes x1c8_playerMaterial;
ESecondaryFxType x1cc_enabledSecondaryEffect = ESecondaryFxType::Zero;
CVelocityInfo x1d0_velInfo; CVelocityInfo x1d0_velInfo;
CPlayerState::EBeamId x200_beamId; CPlayerState::EBeamId x200_beamId;
ESecondaryFxType x204_secondaryEffectType = ESecondaryFxType::Zero; EFrozenFxType x204_frozenEffect = EFrozenFxType::None;
u32 x208_ = 0; u32 x208_muzzleEffectIdx = 0;
CPlayerState::EBeamId x20c_; u32 x20c_shaderIdx;
u32 x210_ = 0; u32 x210_ = 0;
CAssetId x214_ancsId; CAssetId x214_ancsId;
union union
@ -85,61 +100,78 @@ protected:
{ {
bool x218_24 : 1; bool x218_24 : 1;
bool x218_25_enableCharge : 1; bool x218_25_enableCharge : 1;
bool x218_26 : 1; bool x218_26_loaded : 1;
bool x218_27 : 1; // Initialize in selected beam's pose, rather than power beam's pose
bool x218_28 : 1; bool x218_27_subtypeBasePose : 1;
bool x218_29_leavingBeam : 1; bool x218_28_suitArmLocked : 1;
bool x218_29_drawHologram : 1;
}; };
u32 _dummy = 0; u32 _dummy = 0;
}; };
void AllocResPools(CPlayerState::EBeamId beam);
void FreeResPools();
void FillTokenVector(const std::vector<SObjectTag>& tags, std::vector<CToken>& objects);
void BuildDependencyList(CPlayerState::EBeamId beam);
CDamageInfo GetShotDamageInfo(const SShotParam& shotParam, CStateManager& mgr) const;
void LoadSuitArm(CStateManager& mgr);
void LoadGunModels(CStateManager& mgr);
void LoadAnimations();
bool IsAnimsLoaded() const;
void LoadMuzzleFx(float dt);
void LoadProjectileData(CStateManager& mgr);
void LoadFxIdle(float dt, CStateManager& mgr);
void LockTokens(CStateManager& mgr);
void UnlockTokens();
static void PointGenerator(void* ctx, const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn);
public: public:
CGunWeapon(CAssetId ancsId, EWeaponType type, TUniqueId playerId, EMaterialTypes, const zeus::CVector3f& scale); CGunWeapon(CAssetId ancsId, EWeaponType type, TUniqueId playerId, EMaterialTypes playerMaterial,
const zeus::CVector3f& scale);
void AsyncLoadSuitArm(CStateManager& mgr); void AsyncLoadSuitArm(CStateManager& mgr);
void AllocResPools(CPlayerState::EBeamId); virtual void Reset(CStateManager& mgr);
virtual void Reset(CStateManager&) {}
virtual void PlayAnim(NWeaponTypes::EGunAnimType type, bool loop); virtual void PlayAnim(NWeaponTypes::EGunAnimType type, bool loop);
virtual void PreRenderGunFx(const CStateManager&, const zeus::CTransform&) {} virtual void PreRenderGunFx(const CStateManager& mgr, const zeus::CTransform& xf);
virtual void PostRenderGunFx(const CStateManager&, const zeus::CTransform&) {} virtual void PostRenderGunFx(const CStateManager& mgr, const zeus::CTransform& xf);
virtual void UpdateGunFx(bool shotSmoke, float, const CStateManager&, const zeus::CTransform&) {} virtual void UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr, const zeus::CTransform& xf);
virtual void Fire(bool underwater, float dt, EChargeState chargeState, const zeus::CTransform& xf, virtual void Fire(bool underwater, float dt, EChargeState chargeState, const zeus::CTransform& xf,
CStateManager& mgr, TUniqueId homingTarget) {} CStateManager& mgr, TUniqueId homingTarget, float chargeFactor1, float chargeFactor2);
virtual void EnableFx(bool) {} virtual void EnableFx(bool enable);
virtual void EnableSecondaryFx(ESecondaryFxType) {} virtual void EnableSecondaryFx(ESecondaryFxType type);
void BuildSecondaryEffect(ESecondaryFxType type); void EnableFrozenEffect(EFrozenFxType type);
void ActivateCharge(bool b1, bool b2); void ActivateCharge(bool enable, bool resetEffect);
void Touch(const CStateManager& mgr); void Touch(const CStateManager& mgr);
void TouchHolo(const CStateManager& mgr); void TouchHolo(const CStateManager& mgr);
virtual void Draw(bool, const CStateManager&, const zeus::CTransform&, const CModelFlags&, virtual void Draw(bool drawSuitArm, const CStateManager& mgr, const zeus::CTransform& xf,
const CActorLights*) const {} const CModelFlags& flags, const CActorLights* lights) const;
virtual void DrawMuzzleFx(const CStateManager&) const {} virtual void DrawMuzzleFx(const CStateManager& mgr) const;
virtual void Update(float, CStateManager&) {} virtual void Update(float dt, CStateManager& mgr);
virtual void Load(CStateManager& mgr, bool) {} virtual void Load(CStateManager& mgr, bool subtypeBasePose);
virtual void Unload(CStateManager&) {} virtual void Unload(CStateManager& mgr);
virtual bool IsLoaded() const {return false;} virtual bool IsLoaded() const;
void DrawHologram(const CStateManager& mgr, const zeus::CTransform& xf, const CModelFlags& flags) const; void DrawHologram(const CStateManager& mgr, const zeus::CTransform& xf, const CModelFlags& flags) const;
void UpdateMuzzleFx(float dt, const zeus::CVector3f& scale, const zeus::CVector3f& pos, bool emitting); void UpdateMuzzleFx(float dt, const zeus::CVector3f& scale, const zeus::CVector3f& pos, bool emitting);
const CVelocityInfo& GetVelocityInfo() const { return x1d0_velInfo; } const CVelocityInfo& GetVelocityInfo() const { return x1d0_velInfo; }
void SetRainSplashGenerator(CRainSplashGenerator* g) { x1bc_rainSplashGenerator = g; } void SetRainSplashGenerator(CRainSplashGenerator* g) { x1bc_rainSplashGenerator = g; }
CElementGen* GetChargeMuzzleFx() const { return x1a4_muzzleGenerators[1].get(); } CElementGen* GetChargeMuzzleFx() const { return x1a4_muzzleGenerators[1].get(); }
const TToken<CGenDescription>& GetComboXferDescr() const { return x160_xferEffect; } const TToken<CGenDescription>& GetComboXferDescr() const { return x160_xferEffect; }
void ReturnToDefault(CStateManager& mgr) {} void ReturnToDefault(CStateManager& mgr);
bool PlayPasAnim(SamusGun::EAnimationState state, CStateManager& mgr, float angle) { return false; } bool PlayPasAnim(SamusGun::EAnimationState state, CStateManager& mgr, float angle);
void UnLoadFidget() {} void UnLoadFidget();
bool IsFidgetLoaded() const { return x100_gunController->IsFidgetLoaded(); } bool IsFidgetLoaded() const;
void AsyncLoadFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 animSet) void AsyncLoadFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 animSet);
{ x100_gunController->LoadFidgetAnimAsync(mgr, s32(type), s32(x200_beamId), animSet); } void EnterFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 parm2);
void EnterFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 parm2)
{ x100_gunController->EnterFidget(mgr, s32(type), s32(x200_beamId), parm2); }
bool HasSolidModelData() const { return x10_solidModelData.operator bool(); } bool HasSolidModelData() const { return x10_solidModelData.operator bool(); }
CModelData& GetSolidModelData() { return *x10_solidModelData; } CModelData& GetSolidModelData() { return *x10_solidModelData; }
const SWeaponInfo& GetWeaponInfo() const; const SWeaponInfo& GetWeaponInfo() const;
CDamageInfo GetDamageInfo(CStateManager& mgr, EChargeState chargeState, float chargeFactor) const;
EWeaponType GetWeaponType() const { return x1c0_weaponType; } EWeaponType GetWeaponType() const { return x1c0_weaponType; }
zeus::CAABox GetBounds() const; zeus::CAABox GetBounds() const;
zeus::CAABox GetBounds(const zeus::CTransform& xf) const; zeus::CAABox GetBounds(const zeus::CTransform& xf) const;
bool ComboFireOver() const { return x100_gunController->IsComboOver(); } bool ComboFireOver() const { return x100_gunController->IsComboOver(); }
bool IsChargeAnimOver() const; bool IsChargeAnimOver() const;
void SetLeavingBeam(bool leaving) { x218_29_leavingBeam = leaving; } void SetDrawHologram(bool d) { x218_29_drawHologram = d; }
void EnableCharge(bool c) { x218_25_enableCharge = c; } void EnableCharge(bool c) { x218_25_enableCharge = c; }
}; };
} }

View File

@ -6,9 +6,10 @@ namespace urde
CPlasmaProjectile::CPlasmaProjectile(const TToken<CWeaponDescription>& wDesc, const std::string& name, CPlasmaProjectile::CPlasmaProjectile(const TToken<CWeaponDescription>& wDesc, const std::string& name,
EWeaponType wType, const CBeamInfo& bInfo, const zeus::CTransform& xf, EWeaponType wType, const CBeamInfo& bInfo, const zeus::CTransform& xf,
EMaterialTypes matType, const CDamageInfo& dInfo, TUniqueId owner, TAreaId aid, EMaterialTypes matType, const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid,
TUniqueId uid, u32 w1, bool b1, u32 w2) TUniqueId owner, u32 w1, bool b1, EProjectileAttrib attribs)
: CBeamProjectile(wDesc, name, wType, xf, bInfo.x18_, bInfo.x1c_, bInfo.x38_, matType, dInfo, owner, aid, uid, w2, b1) : CBeamProjectile(wDesc, name, wType, xf, bInfo.x18_, bInfo.x1c_, bInfo.x38_, matType,
dInfo, uid, aid, owner, attribs, b1)
{ {
} }

View File

@ -10,9 +10,10 @@ namespace urde
class CPlasmaProjectile : public CBeamProjectile class CPlasmaProjectile : public CBeamProjectile
{ {
public: public:
CPlasmaProjectile(const TToken<CWeaponDescription>&, const std::string&, EWeaponType, const CBeamInfo&, CPlasmaProjectile(const TToken<CWeaponDescription>& wDesc, const std::string& name,
const zeus::CTransform&, EMaterialTypes, const CDamageInfo&, TUniqueId, TAreaId, TUniqueId, u32, EWeaponType wType, const CBeamInfo& bInfo, const zeus::CTransform& xf,
bool, u32); EMaterialTypes matType, const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid,
TUniqueId owner, u32 w1, bool b1, EProjectileAttrib attribs);
void Accept(IVisitor& visitor); void Accept(IVisitor& visitor);

View File

@ -1155,7 +1155,7 @@ void CPlayerGun::StartPhazonBeamTransition(bool active, CStateManager& mgr, CPla
SetPhazonBeamFeedback(active); SetPhazonBeamFeedback(active);
x72c_currentBeam->SetRainSplashGenerator(x748_rainSplashGenerator.get()); x72c_currentBeam->SetRainSplashGenerator(x748_rainSplashGenerator.get());
x72c_currentBeam->EnableFx(true); x72c_currentBeam->EnableFx(true);
x72c_currentBeam->SetLeavingBeam(false); x72c_currentBeam->SetDrawHologram(false);
PlayAnim(NWeaponTypes::EGunAnimType::ToBeam, false); PlayAnim(NWeaponTypes::EGunAnimType::ToBeam, false);
if (x833_31_inFreeLook) if (x833_31_inFreeLook)
EnterFreeLook(mgr); EnterFreeLook(mgr);
@ -1656,7 +1656,8 @@ void CPlayerGun::UpdateNormalShotCycle(float dt, CStateManager& mgr)
homingTarget = GetTargetId(mgr); homingTarget = GetTargetId(mgr);
else else
homingTarget = kInvalidUniqueId; homingTarget = kInvalidUniqueId;
x72c_currentBeam->Fire(x834_27_underwater, dt, x330_chargeState, xf, mgr, homingTarget); x72c_currentBeam->Fire(x834_27_underwater, dt, x330_chargeState, xf, mgr, homingTarget,
x340_chargeBeamFactor, x340_chargeBeamFactor);
mgr.InformListeners(x4a8_gunWorldXf.origin, EListenNoiseType::Zero); mgr.InformListeners(x4a8_gunWorldXf.origin, EListenNoiseType::Zero);
} }
@ -2076,11 +2077,11 @@ void CPlayerGun::Update(float grappleSwingT, float cameraBobT, float dt, CStateM
if (becameFrozen) if (becameFrozen)
{ {
x72c_currentBeam->EnableSecondaryFx(CGunWeapon::ESecondaryFxType::Zero); x72c_currentBeam->EnableSecondaryFx(CGunWeapon::ESecondaryFxType::Zero);
x72c_currentBeam->BuildSecondaryEffect(CGunWeapon::ESecondaryFxType::One); x72c_currentBeam->EnableFrozenEffect(CGunWeapon::EFrozenFxType::Frozen);
} }
else if (becameThawed) else if (becameThawed)
{ {
x72c_currentBeam->BuildSecondaryEffect(CGunWeapon::ESecondaryFxType::Two); x72c_currentBeam->EnableFrozenEffect(CGunWeapon::EFrozenFxType::Thawed);
} }
if (becameFrozen || becameThawed) if (becameFrozen || becameThawed)
@ -2151,14 +2152,14 @@ void CPlayerGun::Update(float grappleSwingT, float cameraBobT, float dt, CStateM
case ENextState::EnterPhazonBeam: case ENextState::EnterPhazonBeam:
if (x75c_phazonBeam->IsLoaded()) if (x75c_phazonBeam->IsLoaded())
break; break;
x72c_currentBeam->SetLeavingBeam(true); x72c_currentBeam->SetDrawHologram(true);
x75c_phazonBeam->Load(mgr, false); x75c_phazonBeam->Load(mgr, false);
x33c_phazonBeamState = EPhazonBeamState::Entering; x33c_phazonBeamState = EPhazonBeamState::Entering;
break; break;
case ENextState::ExitPhazonBeam: case ENextState::ExitPhazonBeam:
if (x738_nextBeam->IsLoaded()) if (x738_nextBeam->IsLoaded())
break; break;
x72c_currentBeam->SetLeavingBeam(true); x72c_currentBeam->SetDrawHologram(true);
x738_nextBeam->Load(mgr, false); x738_nextBeam->Load(mgr, false);
x33c_phazonBeamState = EPhazonBeamState::Exiting; x33c_phazonBeamState = EPhazonBeamState::Exiting;
break; break;
@ -2515,7 +2516,7 @@ void CPlayerGun::Render(const CStateManager& mgr, const zeus::CVector3f& pos, co
x744_auxWeapon->RenderMuzzleFx(); x744_auxWeapon->RenderMuzzleFx();
x72c_currentBeam->PreRenderGunFx(mgr, offsetWorldXf); x72c_currentBeam->PreRenderGunFx(mgr, offsetWorldXf);
bool r26 = !x740_grappleArm->IsGrappling() && bool drawSuitArm = !x740_grappleArm->IsGrappling() &&
mgr.GetPlayer().GetGunHolsterState() == CPlayer::EGunHolsterState::Drawn; mgr.GetPlayer().GetGunHolsterState() == CPlayer::EGunHolsterState::Drawn;
x73c_gunMotion->Draw(mgr, offsetWorldXf); x73c_gunMotion->Draw(mgr, offsetWorldXf);
@ -2531,7 +2532,7 @@ void CPlayerGun::Render(const CStateManager& mgr, const zeus::CVector3f& pos, co
kHandThermalFlag : kHandHoloFlag); kHandThermalFlag : kHandHoloFlag);
} }
DrawArm(mgr, pos, flags); DrawArm(mgr, pos, flags);
x72c_currentBeam->Draw(r26, mgr, offsetWorldXf, useFlags, &x0_lights); x72c_currentBeam->Draw(drawSuitArm, mgr, offsetWorldXf, useFlags, &x0_lights);
x82c_shadow->DisableModelProjectedShadow(); x82c_shadow->DisableModelProjectedShadow();
break; break;
case CGunMorph::EGunState::InWipeDone: case CGunMorph::EGunState::InWipeDone:
@ -2550,7 +2551,7 @@ void CPlayerGun::Render(const CStateManager& mgr, const zeus::CVector3f& pos, co
x82c_shadow->EnableModelProjectedShadow(offsetWorldXf, x0_lights.GetShadowLightArrIndex(), 2.15f); x82c_shadow->EnableModelProjectedShadow(offsetWorldXf, x0_lights.GetShadowLightArrIndex(), 2.15f);
CGraphics::SetModelMatrix(morphXf); CGraphics::SetModelMatrix(morphXf);
DrawClipCube(x6c8_hologramClipCube); DrawClipCube(x6c8_hologramClipCube);
x72c_currentBeam->Draw(r26, mgr, offsetWorldXf, useFlags, &x0_lights); x72c_currentBeam->Draw(drawSuitArm, mgr, offsetWorldXf, useFlags, &x0_lights);
x82c_shadow->DisableModelProjectedShadow(); x82c_shadow->DisableModelProjectedShadow();
} }
else else

View File

@ -5,9 +5,9 @@
namespace urde namespace urde
{ {
CWeapon::CWeapon(TUniqueId uid, TAreaId aid, bool active, TUniqueId, EWeaponType, const std::string& name, CWeapon::CWeapon(TUniqueId uid, TAreaId aid, bool active, TUniqueId owner, EWeaponType type,
const zeus::CTransform& xf, const CMaterialFilter& filter, const CMaterialList& mList, const CDamageInfo&, const std::string& name, const zeus::CTransform& xf, const CMaterialFilter& filter,
EProjectileAttrib, CModelData&& mData) const CMaterialList& mList, const CDamageInfo&, EProjectileAttrib attribs, CModelData&& mData)
: CActor(uid, active, name, CEntityInfo(aid, CEntity::NullConnectionList), xf, std::move(mData), mList, : CActor(uid, active, name, CEntityInfo(aid, CEntity::NullConnectionList), xf, std::move(mData), mList,
CActorParameters::None(), kInvalidUniqueId) CActorParameters::None(), kInvalidUniqueId)
, xf8_(filter) , xf8_(filter)

View File

@ -14,6 +14,9 @@ public:
enum class EProjectileAttrib enum class EProjectileAttrib
{ {
None = 0, None = 0,
PartialCharge = (1 << 0),
PlasmaProjectile = (1 << 1),
Charged = (1 << 2),
Ice = (1 << 3), Ice = (1 << 3),
Wave = (1 << 4), Wave = (1 << 4),
Plasma = (1 << 5), Plasma = (1 << 5),
@ -21,6 +24,7 @@ public:
Unknown1 = (1 << 7), Unknown1 = (1 << 7),
Bombs = (1 << 8), Bombs = (1 << 8),
PowerBombs = (1 << 9), PowerBombs = (1 << 9),
ArmCannon = (1 << 11),
BigStrike = (1 << 12), BigStrike = (1 << 12),
StaticInterference = (1 << 14), StaticInterference = (1 << 14),
}; };
@ -39,8 +43,9 @@ private:
float x150_damageDuration; float x150_damageDuration;
float x154_interferenceDuration; float x154_interferenceDuration;
public: public:
CWeapon(TUniqueId, TAreaId, bool, TUniqueId, EWeaponType, const std::string&, const zeus::CTransform&, CWeapon(TUniqueId uid, TAreaId aid, bool active, TUniqueId owner, EWeaponType type,
const CMaterialFilter&, const CMaterialList&, const CDamageInfo&, EProjectileAttrib, CModelData&&); const std::string& name, const zeus::CTransform& xf, const CMaterialFilter& filter,
const CMaterialList& mList, const CDamageInfo&, EProjectileAttrib attribs, CModelData&& mData);
virtual void Accept(IVisitor &visitor); virtual void Accept(IVisitor &visitor);
bool HasAttrib(EProjectileAttrib) const; bool HasAttrib(EProjectileAttrib) const;

View File

@ -6,22 +6,23 @@ namespace urde
{ {
CDamageInfo::CDamageInfo(const DataSpec::SShotParam& other) CDamageInfo::CDamageInfo(const DataSpec::SShotParam& other)
: x0_weaponMode(CWeaponMode(EWeaponType(other.weaponType), other.Charged(), other.Comboed(), other.InstaKill())) : x0_weaponMode(CWeaponMode(EWeaponType(other.weaponType), other.charged, other.combo, other.instaKill))
, x8_damage(other.damage) , x8_damage(other.damage)
, xc_radiusDamage(other.radiusDamage) , xc_radiusDamage(other.radiusDamage)
, x10_radius(other.radius) , x10_radius(other.radius)
, x14_knockback(other.knockback) , x14_knockback(other.knockback)
, x18_noImmunity(other.noImmunity)
{ {
} }
CDamageInfo& CDamageInfo::operator=(const DataSpec::SShotParam& other) CDamageInfo& CDamageInfo::operator=(const DataSpec::SShotParam& other)
{ {
x0_weaponMode = CWeaponMode(EWeaponType(other.weaponType), other.Charged(), other.Comboed(), other.InstaKill()); x0_weaponMode = CWeaponMode(EWeaponType(other.weaponType), other.charged, other.combo, other.instaKill);
x8_damage = other.damage; x8_damage = other.damage;
xc_radiusDamage = x8_damage; xc_radiusDamage = other.radiusDamage;
x10_radius = other.radius; x10_radius = other.radius;
x14_knockback = other.knockback; x14_knockback = other.knockback;
x18_noImmunity = false; x18_noImmunity = other.noImmunity;
return *this; return *this;
} }

View File

@ -51,6 +51,12 @@ public:
float GetRadiusDamage() const { return xc_radiusDamage; } float GetRadiusDamage() const { return xc_radiusDamage; }
float GetRadiusDamage(const CDamageVulnerability& dVuln) const; float GetRadiusDamage(const CDamageVulnerability& dVuln) const;
bool NoImmunity() const { return x18_noImmunity; } bool NoImmunity() const { return x18_noImmunity; }
void MultiplyDamage(float m)
{
x8_damage *= m;
xc_radiusDamage *= m;
x14_knockback *= m;
}
}; };
} }

View File

@ -425,8 +425,9 @@ private:
float CalculateOrbitMinDistance(EPlayerOrbitType type) const; float CalculateOrbitMinDistance(EPlayerOrbitType type) const;
public: public:
CPlayer(TUniqueId, const zeus::CTransform&, const zeus::CAABox&, CAssetId w1, const zeus::CVector3f&, float, float, CPlayer(TUniqueId uid, const zeus::CTransform& xf, const zeus::CAABox& aabb, CAssetId resId,
float, float, const CMaterialList&); const zeus::CVector3f& playerScale, float mass, float stepUp, float stepDown, float ballRadius,
const CMaterialList& ml);
bool IsTransparent() const; bool IsTransparent() const;
bool GetControlsFrozen() const { return x760_controlsFrozen; } bool GetControlsFrozen() const { return x760_controlsFrozen; }

View File

@ -50,7 +50,7 @@ void CScriptBeam::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CSt
mgr.AddObject(new CPlasmaProjectile(xe8_weaponDescription, x10_name + "-Projectile", mgr.AddObject(new CPlasmaProjectile(xe8_weaponDescription, x10_name + "-Projectile",
x138_damageInfo.GetWeaponMode().GetType(), xf4_beamInfo, x34_transform, x138_damageInfo.GetWeaponMode().GetType(), xf4_beamInfo, x34_transform,
EMaterialTypes::Projectile, x138_damageInfo, x8_uid, x4_areaId, EMaterialTypes::Projectile, x138_damageInfo, x8_uid, x4_areaId,
x154_projectileId, 8, false, 2)); x154_projectileId, 8, false, CWeapon::EProjectileAttrib::PlasmaProjectile));
} }
else if (msg == EScriptObjectMessage::Deleted) else if (msg == EScriptObjectMessage::Deleted)
{ {

2
hecl

@ -1 +1 @@
Subproject commit af4857cfae81cb2ca03526bdbb76335d913a6e24 Subproject commit 806a802cff2bf5dc72afcc8145852e595cfdc654