mirror of https://github.com/AxioDL/metaforce.git
Implement CPlasmaProjectile
This commit is contained in:
parent
4f3c8daf27
commit
5b55320e9b
|
@ -12,6 +12,25 @@
|
|||
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
||||
</Objective-C>
|
||||
<Objective-C-extensions>
|
||||
<file>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||
</file>
|
||||
<class>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||
</class>
|
||||
<extensions>
|
||||
<pair source="cpp" header="hpp" fileNamingConvention="NONE" />
|
||||
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||
|
|
|
@ -17,31 +17,31 @@ struct NewIntroBoss : IScriptObject {
|
|||
Value<float> unknown1;
|
||||
UniqueID32 weaponDesc;
|
||||
DamageInfo damageInfo;
|
||||
UniqueID32 particle1;
|
||||
UniqueID32 particle2;
|
||||
UniqueID32 texture1;
|
||||
UniqueID32 texture2;
|
||||
UniqueID32 beamContactFxId;
|
||||
UniqueID32 beamPulseFxId;
|
||||
UniqueID32 beamTextureId;
|
||||
UniqueID32 beamGlowTextureId;
|
||||
|
||||
void addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const {
|
||||
actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters);
|
||||
}
|
||||
|
||||
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const {
|
||||
if (particle1) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
|
||||
ent->name = name + "_part1";
|
||||
if (beamContactFxId) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamContactFxId);
|
||||
ent->name = name + "_beamContactFxId";
|
||||
}
|
||||
if (particle2) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
|
||||
ent->name = name + "_part2";
|
||||
if (beamPulseFxId) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamPulseFxId);
|
||||
ent->name = name + "_beamPulseFxId";
|
||||
}
|
||||
if (texture1) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1);
|
||||
ent->name = name + "_tex1";
|
||||
if (beamTextureId) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamTextureId);
|
||||
ent->name = name + "_beamTextureId";
|
||||
}
|
||||
if (texture2) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture2);
|
||||
ent->name = name + "_tex2";
|
||||
if (beamGlowTextureId) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamGlowTextureId);
|
||||
ent->name = name + "_beamGlowTextureId";
|
||||
}
|
||||
patternedInfo.nameIDs(pakRouter, name + "_patterned");
|
||||
actorParameters.nameIDs(pakRouter, name + "_actp");
|
||||
|
@ -49,10 +49,10 @@ struct NewIntroBoss : IScriptObject {
|
|||
|
||||
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut, std::vector<hecl::ProjectPath>& lazyOut) const {
|
||||
g_curSpec->flattenDependencies(weaponDesc, pathsOut);
|
||||
g_curSpec->flattenDependencies(particle1, pathsOut);
|
||||
g_curSpec->flattenDependencies(particle2, pathsOut);
|
||||
g_curSpec->flattenDependencies(texture1, pathsOut);
|
||||
g_curSpec->flattenDependencies(texture2, pathsOut);
|
||||
g_curSpec->flattenDependencies(beamContactFxId, pathsOut);
|
||||
g_curSpec->flattenDependencies(beamPulseFxId, pathsOut);
|
||||
g_curSpec->flattenDependencies(beamTextureId, pathsOut);
|
||||
g_curSpec->flattenDependencies(beamGlowTextureId, pathsOut);
|
||||
patternedInfo.depIDs(pathsOut);
|
||||
actorParameters.depIDs(pathsOut, lazyOut);
|
||||
}
|
||||
|
|
|
@ -424,47 +424,47 @@ struct ActorParameters : BigDNA {
|
|||
struct BeamInfo : BigDNA {
|
||||
AT_DECL_DNA_YAML
|
||||
Value<atUint32> propertyCount;
|
||||
Value<atUint32> unknown1;
|
||||
UniqueID32 particle1;
|
||||
UniqueID32 particle2;
|
||||
UniqueID32 texture1;
|
||||
UniqueID32 texture2;
|
||||
Value<float> unknown2;
|
||||
Value<float> unknown3;
|
||||
Value<float> unknown4;
|
||||
Value<float> unknown5;
|
||||
Value<float> unknown6;
|
||||
Value<float> unknown7;
|
||||
Value<float> unknown8;
|
||||
Value<float> unknown9;
|
||||
Value<float> unknown10;
|
||||
DNAColor unknown11;
|
||||
DNAColor unknown12;
|
||||
Value<atUint32> beamAttributes;
|
||||
UniqueID32 contactFxId;
|
||||
UniqueID32 pulseFxId;
|
||||
UniqueID32 textureId;
|
||||
UniqueID32 glowTextureId;
|
||||
Value<float> length;
|
||||
Value<float> radius;
|
||||
Value<float> expansionSpeed;
|
||||
Value<float> lifeTime;
|
||||
Value<float> pulseSpeed;
|
||||
Value<float> shutdownTime;
|
||||
Value<float> contactFxScale;
|
||||
Value<float> pulseFxScale;
|
||||
Value<float> travelSpeed;
|
||||
DNAColor innerColor;
|
||||
DNAColor outerColor;
|
||||
|
||||
void nameIDs(PAKRouter<PAKBridge>& pakRouter, const std::string& name) const {
|
||||
if (particle1) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
|
||||
if (contactFxId) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(contactFxId);
|
||||
ent->name = name + "_part1";
|
||||
}
|
||||
if (particle2) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
|
||||
if (pulseFxId) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(pulseFxId);
|
||||
ent->name = name + "_part2";
|
||||
}
|
||||
if (texture1) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1);
|
||||
if (textureId) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(textureId);
|
||||
ent->name = name + "_tex1";
|
||||
}
|
||||
if (texture2) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture2);
|
||||
if (glowTextureId) {
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(glowTextureId);
|
||||
ent->name = name + "_tex2";
|
||||
}
|
||||
}
|
||||
|
||||
void depIDs(std::vector<hecl::ProjectPath>& pathsOut) const {
|
||||
g_curSpec->flattenDependencies(particle1, pathsOut);
|
||||
g_curSpec->flattenDependencies(particle2, pathsOut);
|
||||
g_curSpec->flattenDependencies(texture1, pathsOut);
|
||||
g_curSpec->flattenDependencies(texture2, pathsOut);
|
||||
g_curSpec->flattenDependencies(contactFxId, pathsOut);
|
||||
g_curSpec->flattenDependencies(pulseFxId, pathsOut);
|
||||
g_curSpec->flattenDependencies(textureId, pathsOut);
|
||||
g_curSpec->flattenDependencies(glowTextureId, pathsOut);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -837,7 +837,7 @@ bool CBSJump::CheckForWallJump(CBodyController& bc, CStateManager& mgr) {
|
|||
float distToWall = (xc_waypoint1 - act->GetTranslation()).magnitude();
|
||||
zeus::CAABox aabb = act->GetBoundingBox();
|
||||
float xExtent = (aabb.max.x() - aabb.min.x()) * 0.5f;
|
||||
if (distToWall < 1.414f * xExtent || (act->CanLongJump() && distToWall < 3.f * xExtent)) {
|
||||
if (distToWall < 1.414f * xExtent || (act->MadeSolidCollision() && distToWall < 3.f * xExtent)) {
|
||||
x4_state = x30_26_wallBounceRight ? pas::EJumpState::WallBounceRight : pas::EJumpState::WallBounceLeft;
|
||||
CPASAnimParmData parms(13, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_jumpType)));
|
||||
bc.PlayBestAnimation(parms, *mgr.GetActiveRandom());
|
||||
|
@ -851,7 +851,7 @@ bool CBSJump::CheckForWallJump(CBodyController& bc, CStateManager& mgr) {
|
|||
|
||||
void CBSJump::CheckForLand(CBodyController& bc, CStateManager& mgr) {
|
||||
if (TCastToPtr<CPatterned> act = bc.GetOwner()) {
|
||||
if (act->CanLongJump() || act->IsOnGround()) {
|
||||
if (act->MadeSolidCollision() || act->IsOnGround()) {
|
||||
x4_state = pas::EJumpState::OutOfJump;
|
||||
CPASAnimParmData parms(13, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_jumpType)));
|
||||
bc.PlayBestAnimation(parms, *mgr.GetActiveRandom());
|
||||
|
@ -1044,7 +1044,7 @@ void CBSHurled::PlayLandAnimation(CBodyController& bc, CStateManager& mgr) {
|
|||
|
||||
bool CBSHurled::ShouldStartStrikeWall(CBodyController& bc) const {
|
||||
if (TCastToPtr<CPatterned> ai = bc.GetOwner()) {
|
||||
if (ai->CanLongJump())
|
||||
if (ai->MadeSolidCollision())
|
||||
if (!ai->IsOnGround())
|
||||
return true;
|
||||
}
|
||||
|
@ -1361,7 +1361,7 @@ void CBSWallHang::FixInPlace(CBodyController& bc) {
|
|||
|
||||
bool CBSWallHang::CheckForLand(CBodyController& bc, CStateManager& mgr) {
|
||||
if (TCastToPtr<CPatterned> ai = bc.GetOwner()) {
|
||||
if (ai->CanLongJump() || ai->IsOnGround()) {
|
||||
if (ai->MadeSolidCollision() || ai->IsOnGround()) {
|
||||
x4_state = pas::EWallHangState::DetachOutOfJump;
|
||||
CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state)));
|
||||
bc.PlayBestAnimation(parms, *mgr.GetActiveRandom());
|
||||
|
@ -1379,7 +1379,7 @@ bool CBSWallHang::CheckForWall(CBodyController& bc, CStateManager& mgr) {
|
|||
if (wp)
|
||||
magSq = (wp->GetTranslation() - ai->GetTranslation()).magSquared();
|
||||
|
||||
if (magSq < 1.f || ai->CanLongJump()) {
|
||||
if (magSq < 1.f || ai->MadeSolidCollision()) {
|
||||
x4_state = pas::EWallHangState::IntoWallHang;
|
||||
CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state)));
|
||||
std::pair<float, s32> best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1);
|
||||
|
|
|
@ -615,6 +615,16 @@ CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac)
|
|||
m_staticEntropy = store.GetObj("RandomStaticEntropy");
|
||||
|
||||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
u8 clearPixel[] = {0, 0, 0, 0};
|
||||
m_clearTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8,
|
||||
boo::TextureClampMode::Repeat, clearPixel, 4).get();
|
||||
u8 blackPixel[] = {0, 0, 0, 255};
|
||||
m_blackTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8,
|
||||
boo::TextureClampMode::Repeat, blackPixel, 4).get();
|
||||
u8 whitePixel[] = {255, 255, 255, 255};
|
||||
m_whiteTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8,
|
||||
boo::TextureClampMode::Repeat, whitePixel, 4).get();
|
||||
|
||||
GenerateFogVolumeRampTex(ctx);
|
||||
GenerateSphereRampTex(ctx);
|
||||
m_ballShadowId = ctx.newRenderTexture(m_ballShadowIdW, m_ballShadowIdH, boo::TextureClampMode::Repeat, 1, 0);
|
||||
|
|
|
@ -106,6 +106,10 @@ class CBooRenderer final : public IRenderer {
|
|||
// boo::ITextureS* xe4_blackTex = nullptr;
|
||||
bool xee_24_ : 1;
|
||||
|
||||
boo::ObjToken<boo::ITexture> m_clearTexture;
|
||||
boo::ObjToken<boo::ITexture> m_blackTexture;
|
||||
boo::ObjToken<boo::ITexture> m_whiteTexture;
|
||||
|
||||
boo::ObjToken<boo::ITextureR> x14c_reflectionTex;
|
||||
// boo::ITextureS* x150_mirrorRamp = nullptr;
|
||||
boo::ObjToken<boo::ITextureS> x1b8_fogVolumeRamp;
|
||||
|
@ -269,6 +273,10 @@ public:
|
|||
const boo::ObjToken<boo::IGraphicsBufferS>& GetScanLinesEvenVBO() const { return m_scanLinesEvenVBO; }
|
||||
const boo::ObjToken<boo::IGraphicsBufferS>& GetScanLinesOddVBO() const { return m_scanLinesOddVBO; }
|
||||
|
||||
const boo::ObjToken<boo::ITexture>& GetClearTexture() { return m_clearTexture; }
|
||||
const boo::ObjToken<boo::ITexture>& GetBlackTexture() { return m_blackTexture; }
|
||||
const boo::ObjToken<boo::ITexture>& GetWhiteTexture() { return m_whiteTexture; }
|
||||
|
||||
static void BindMainDrawTarget() { CGraphics::g_BooMainCommandQueue->setRenderTarget(CGraphics::g_SpareTexture); }
|
||||
void BindReflectionDrawTarget() { CGraphics::g_BooMainCommandQueue->setRenderTarget(x14c_reflectionTex); }
|
||||
void BindBallShadowIdTarget() {
|
||||
|
|
|
@ -22,6 +22,7 @@ set(GRAPHICS_SOURCES
|
|||
Shaders/CLineRendererShaders.hpp Shaders/CLineRendererShaders.cpp
|
||||
Shaders/CTexturedQuadFilter.hpp Shaders/CTexturedQuadFilter.cpp
|
||||
Shaders/CColoredQuadFilter.hpp Shaders/CColoredQuadFilter.cpp
|
||||
Shaders/CColoredStripShader.hpp Shaders/CColoredStripShader.cpp
|
||||
Shaders/CModelShaders.hpp Shaders/CModelShaders.cpp
|
||||
Shaders/CModelShadersGLSL.cpp Shaders/CModelShadersHLSL.cpp Shaders/CModelShadersMetal.cpp
|
||||
Shaders/CThermalColdFilter.hpp Shaders/CThermalColdFilter.cpp
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
#include "CColoredStripShader.hpp"
|
||||
#include "Graphics/CGraphics.hpp"
|
||||
#include "hecl/Pipeline.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "Graphics/CBooRenderer.hpp"
|
||||
|
||||
namespace urde {
|
||||
|
||||
static boo::ObjToken<boo::IShaderPipeline> s_Pipeline;
|
||||
static boo::ObjToken<boo::IShaderPipeline> s_AdditivePipeline;
|
||||
static boo::ObjToken<boo::IShaderPipeline> s_FullAdditivePipeline;
|
||||
|
||||
void CColoredStripShader::Initialize() {
|
||||
s_Pipeline = hecl::conv->convert(Shader_CColoredStripShader{});
|
||||
s_AdditivePipeline = hecl::conv->convert(Shader_CColoredStripShaderAdditive{});
|
||||
s_FullAdditivePipeline = hecl::conv->convert(Shader_CColoredStripShaderFullAdditive{});
|
||||
}
|
||||
|
||||
void CColoredStripShader::Shutdown() {
|
||||
s_Pipeline.reset();
|
||||
s_AdditivePipeline.reset();
|
||||
s_FullAdditivePipeline.reset();
|
||||
}
|
||||
|
||||
static const boo::ObjToken<boo::IShaderPipeline>& SelectPipeline(CColoredStripShader::Mode mode) {
|
||||
switch (mode) {
|
||||
case CColoredStripShader::Mode::Alpha:
|
||||
default:
|
||||
return s_Pipeline;
|
||||
case CColoredStripShader::Mode::Additive:
|
||||
return s_AdditivePipeline;
|
||||
case CColoredStripShader::Mode::FullAdditive:
|
||||
return s_FullAdditivePipeline;
|
||||
}
|
||||
}
|
||||
|
||||
void CColoredStripShader::BuildResources(boo::IGraphicsDataFactory::Context& ctx, size_t maxVerts, Mode mode,
|
||||
boo::ObjToken<boo::ITexture> tex) {
|
||||
m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vert), maxVerts);
|
||||
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1);
|
||||
boo::ObjToken<boo::IGraphicsBuffer> bufs[] = {m_uniBuf.get()};
|
||||
boo::PipelineStage stages[] = {boo::PipelineStage::Vertex};
|
||||
boo::ObjToken<boo::ITexture> texs[1];
|
||||
if (tex)
|
||||
texs[0] = tex;
|
||||
else
|
||||
texs[0] = g_Renderer->GetWhiteTexture();
|
||||
m_dataBind = ctx.newShaderDataBinding(SelectPipeline(mode), m_vbo.get(), nullptr, nullptr, 1, bufs, stages, nullptr,
|
||||
nullptr, 1, texs, nullptr, nullptr);
|
||||
}
|
||||
|
||||
CColoredStripShader::CColoredStripShader(size_t maxVerts, Mode mode, boo::ObjToken<boo::ITexture> tex) {
|
||||
CGraphics::CommitResources([this, maxVerts, mode, tex](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
BuildResources(ctx, maxVerts, mode, tex);
|
||||
return true;
|
||||
} BooTrace);
|
||||
}
|
||||
|
||||
CColoredStripShader::CColoredStripShader(boo::IGraphicsDataFactory::Context& ctx, size_t maxVerts, Mode mode,
|
||||
boo::ObjToken<boo::ITexture> tex) {
|
||||
BuildResources(ctx, maxVerts, mode, tex);
|
||||
}
|
||||
|
||||
void CColoredStripShader::draw(const zeus::CColor& color, size_t numVerts, const Vert* verts) {
|
||||
m_vbo->load(verts, sizeof(Vert) * numVerts);
|
||||
|
||||
m_uniform.m_matrix = CGraphics::GetPerspectiveProjectionMatrix(true) * CGraphics::g_GXModelView.toMatrix4f();
|
||||
m_uniform.m_color = color;
|
||||
m_uniBuf->load(&m_uniform, sizeof(m_uniform));
|
||||
|
||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||
CGraphics::DrawArray(0, numVerts);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
|
||||
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||
#include "zeus/CMatrix4f.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
class CColoredStripShader {
|
||||
public:
|
||||
enum class Mode {
|
||||
Alpha,
|
||||
Additive,
|
||||
FullAdditive
|
||||
};
|
||||
private:
|
||||
struct Uniform {
|
||||
zeus::CMatrix4f m_matrix;
|
||||
zeus::CColor m_color;
|
||||
};
|
||||
boo::ObjToken<boo::IGraphicsBufferD> m_vbo;
|
||||
boo::ObjToken<boo::IGraphicsBufferD> m_uniBuf;
|
||||
boo::ObjToken<boo::IShaderDataBinding> m_dataBind;
|
||||
Uniform m_uniform;
|
||||
|
||||
void BuildResources(boo::IGraphicsDataFactory::Context& ctx, size_t maxVerts, Mode mode,
|
||||
boo::ObjToken<boo::ITexture> tex);
|
||||
public:
|
||||
struct Vert {
|
||||
zeus::CVector3f m_pos;
|
||||
zeus::CColor m_color;
|
||||
zeus::CVector2f m_uv;
|
||||
};
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
CColoredStripShader(size_t maxVerts, Mode mode, boo::ObjToken<boo::ITexture> tex);
|
||||
CColoredStripShader(boo::IGraphicsDataFactory::Context& ctx, size_t maxVerts, Mode mode,
|
||||
boo::ObjToken<boo::ITexture> tex);
|
||||
void draw(const zeus::CColor& color, size_t numVerts, const Vert* verts);
|
||||
};
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
#include "Graphics/Shaders/CThermalHotFilter.hpp"
|
||||
#include "Graphics/Shaders/CSpaceWarpFilter.hpp"
|
||||
#include "Graphics/Shaders/CColoredQuadFilter.hpp"
|
||||
#include "Graphics/Shaders/CColoredStripShader.hpp"
|
||||
#include "Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
#include "Graphics/Shaders/CCameraBlurFilter.hpp"
|
||||
#include "Graphics/Shaders/CXRayBlurFilter.hpp"
|
||||
|
@ -244,6 +245,7 @@ CMain::BooSetter::BooSetter(boo::IGraphicsDataFactory* factory, boo::IGraphicsCo
|
|||
CAABoxShader::Initialize();
|
||||
CWorldShadowShader::Initialize();
|
||||
CColoredQuadFilter::Initialize();
|
||||
CColoredStripShader::Initialize();
|
||||
CTexturedQuadFilter::Initialize();
|
||||
CTexturedQuadFilterAlpha::Initialize();
|
||||
CTextSupportShader::Initialize();
|
||||
|
@ -823,6 +825,7 @@ void CMain::Shutdown() {
|
|||
CAABoxShader::Shutdown();
|
||||
CWorldShadowShader::Shutdown();
|
||||
CColoredQuadFilter::Shutdown();
|
||||
CColoredStripShader::Shutdown();
|
||||
CTexturedQuadFilter::Shutdown();
|
||||
CTexturedQuadFilterAlpha::Shutdown();
|
||||
CTextSupportShader::Shutdown();
|
||||
|
|
|
@ -477,7 +477,7 @@ void CBeetle::Generate(CStateManager& mgr, EStateMsg msg, float dt) {
|
|||
AddMaterial(EMaterialTypes::Character, EMaterialTypes::Solid, EMaterialTypes::GroundCollider, mgr);
|
||||
x328_25_verticalMovement = false;
|
||||
x838_25_burrowing = false;
|
||||
if (x328_26_longJump)
|
||||
if (x328_26_solidCollision)
|
||||
DeathDelete(mgr);
|
||||
break;
|
||||
default:
|
||||
|
@ -581,7 +581,7 @@ void CBeetle::Attack(CStateManager& mgr, EStateMsg msg, float dt) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (x328_26_longJump)
|
||||
if (x328_26_solidCollision)
|
||||
x838_24_hitSomething = true;
|
||||
break;
|
||||
case EStateMsg::Deactivate:
|
||||
|
|
|
@ -104,7 +104,7 @@ void CEyeball::Think(float dt, CStateManager& mgr) {
|
|||
if (GetActive()) {
|
||||
CPlasmaProjectile* projectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId));
|
||||
if (projectile && projectile->GetActive())
|
||||
projectile->UpdateFX(GetLctrTransform(skEyeLocator), dt, mgr);
|
||||
projectile->UpdateFx(GetLctrTransform(skEyeLocator), dt, mgr);
|
||||
}
|
||||
|
||||
if (x60c_28_firingBeam) {
|
||||
|
@ -125,7 +125,7 @@ void CEyeball::CreateBeam(CStateManager& mgr) {
|
|||
mgr.AddObject(new CPlasmaProjectile(x5b4_projectileInfo.Token(), "EyeBall_Beam"sv, EWeaponType::AI, beamInfo,
|
||||
zeus::CTransform::Identity(), EMaterialTypes::Immovable,
|
||||
x5b4_projectileInfo.GetDamage(), x5ec_projectileId, GetAreaIdAlways(),
|
||||
GetUniqueId(), 8, false, EProjectileAttrib::KeepInCinematic));
|
||||
GetUniqueId(), {}, false, EProjectileAttrib::KeepInCinematic));
|
||||
}
|
||||
|
||||
void CEyeball::InActive(CStateManager&, EStateMsg msg, float) {
|
||||
|
|
|
@ -14,17 +14,17 @@ namespace urde::MP1 {
|
|||
|
||||
CNewIntroBoss::CNewIntroBoss(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
|
||||
CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms,
|
||||
float f1, CAssetId projectile, const CDamageInfo& dInfo, CAssetId part1, CAssetId part2,
|
||||
CAssetId tex1, CAssetId tex2)
|
||||
float f1, CAssetId projectile, const CDamageInfo& dInfo, CAssetId beamContactFxId,
|
||||
CAssetId beamPulseFxId, CAssetId beamTextureId, CAssetId beamGlowTextureId)
|
||||
: CPatterned(ECharacter::NewIntroBoss, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
|
||||
EMovementType::Flyer, EColliderType::One, EBodyType::Restricted, actParms, EKnockBackVariant::Medium)
|
||||
, x570_(f1)
|
||||
, x574_boneTracking(*GetModelData()->GetAnimationData(), "Head_1"sv, zeus::degToRad(80.f), zeus::degToRad(180.f), false)
|
||||
, x5ac_projectileInfo(projectile, dInfo)
|
||||
, x5f0_(part1)
|
||||
, x5f4_(part2)
|
||||
, x5f8_(tex1)
|
||||
, x5fc_(tex2) {
|
||||
, x5f0_beamContactFxId(beamContactFxId)
|
||||
, x5f4_beamPulseFxId(beamPulseFxId)
|
||||
, x5f8_beamTextureId(beamTextureId)
|
||||
, x5fc_beamGlowTextureId(beamGlowTextureId) {
|
||||
const_cast<TToken<CWeaponDescription>*>(&x5ac_projectileInfo.Token())->Lock();
|
||||
x574_boneTracking.SetActive(true);
|
||||
}
|
||||
|
@ -58,10 +58,12 @@ void CNewIntroBoss::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSt
|
|||
x450_bodyController->Activate(mgr);
|
||||
|
||||
if (x5d4_stage1Projectile == kInvalidUniqueId) {
|
||||
CBeamInfo stage1BeamInfo = CBeamInfo(3, x5f0_, x5f4_, x5f8_, x5fc_, 50, 1.f, 1.f, 1.5f, 20.f, 1.f, 4.f, 8.f,
|
||||
zeus::CColor::skYellow, zeus::CColor(0.1098f, 0.5764f, 0.1592f), 150.f);
|
||||
CBeamInfo stage2BeamInfo(3, x5f0_, x5f4_, x5f8_, x5fc_, 50, 1.f, 1.f, 2.f, 20.f, 1.f, 4.f, 8.f,
|
||||
zeus::CColor::skYellow, zeus::CColor(0.1098f, 0.5764f, 0.1592f), 150.f);
|
||||
CBeamInfo stage1BeamInfo(3, x5f0_beamContactFxId, x5f4_beamPulseFxId, x5f8_beamTextureId, x5fc_beamGlowTextureId,
|
||||
50, 1.f, 1.f, 1.5f, 20.f, 1.f, 4.f, 8.f, zeus::CColor::skYellow,
|
||||
zeus::CColor(0.1098f, 0.5764f, 0.1592f), 150.f);
|
||||
CBeamInfo stage2BeamInfo(3, x5f0_beamContactFxId, x5f4_beamPulseFxId, x5f8_beamTextureId, x5fc_beamGlowTextureId,
|
||||
50, 1.f, 1.f, 2.f, 20.f, 1.f, 4.f, 8.f, zeus::CColor::skYellow,
|
||||
zeus::CColor(0.1098f, 0.5764f, 0.1592f), 150.f);
|
||||
|
||||
x5d4_stage1Projectile = mgr.AllocateUniqueId();
|
||||
x5d6_stage2Projectile = mgr.AllocateUniqueId();
|
||||
|
@ -69,15 +71,15 @@ void CNewIntroBoss::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSt
|
|||
CPlasmaProjectile* stage1Projectile =
|
||||
new CPlasmaProjectile(x5ac_projectileInfo.Token(), "IntroBoss_Beam"sv, EWeaponType::AI, stage1BeamInfo, {},
|
||||
EMaterialTypes::Character, x5ac_projectileInfo.GetDamage(), x5d4_stage1Projectile,
|
||||
GetAreaIdAlways(), GetUniqueId(), 8, true, EProjectileAttrib::KeepInCinematic);
|
||||
GetAreaIdAlways(), GetUniqueId(), {}, true, EProjectileAttrib::KeepInCinematic);
|
||||
CPlasmaProjectile* stage2Projectile =
|
||||
new CPlasmaProjectile(x5ac_projectileInfo.Token(), "IntroBoss_Beam_Stage2"sv, EWeaponType::AI, stage2BeamInfo,
|
||||
{}, EMaterialTypes::Character, x5ac_projectileInfo.GetDamage(), x5d6_stage2Projectile,
|
||||
GetAreaIdAlways(), GetUniqueId(), 8, true, EProjectileAttrib::KeepInCinematic);
|
||||
GetAreaIdAlways(), GetUniqueId(), {}, true, EProjectileAttrib::KeepInCinematic);
|
||||
CPlasmaProjectile* stage3Projectile =
|
||||
new CPlasmaProjectile(x5ac_projectileInfo.Token(), "IntroBoss_Beam_Stage2"sv, EWeaponType::AI, stage2BeamInfo,
|
||||
{}, EMaterialTypes::Character, x5ac_projectileInfo.GetDamage(), x5d8_stage3Projectile,
|
||||
GetAreaIdAlways(), GetUniqueId(), 8, true, EProjectileAttrib::KeepInCinematic);
|
||||
GetAreaIdAlways(), GetUniqueId(), {}, true, EProjectileAttrib::KeepInCinematic);
|
||||
mgr.AddObject(stage1Projectile);
|
||||
mgr.AddObject(stage2Projectile);
|
||||
mgr.AddObject(stage3Projectile);
|
||||
|
@ -219,16 +221,18 @@ void CNewIntroBoss::Think(float dt, CStateManager& mgr) {
|
|||
|
||||
CPlasmaProjectile* curProjectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x676_curProjectile));
|
||||
if (curProjectile && curProjectile->GetActive()) {
|
||||
x628_ += dt;
|
||||
x628_firingTime += dt;
|
||||
zeus::CTransform xf = GetLctrTransform(x5dc_damageLocator);
|
||||
|
||||
if (x400_25_alive) {
|
||||
zeus::CQuaternion clampedQuat = zeus::CQuaternion::clampedRotateTo(
|
||||
(x610_lookPos + (zeus::min(x628_ / 1.5f, 1.f) * (x61c_ - x610_lookPos))) - xf.origin, xf.frontVector(),
|
||||
zeus::CQuaternion clampedQuat = zeus::CQuaternion::clampedRotateTo(xf.frontVector(),
|
||||
(x610_lookPos + (zeus::min(x628_firingTime / 1.5f, 1.f) * (x61c_startPlayerPos - x610_lookPos))) - xf.origin,
|
||||
zeus::CRelAngle::FromDegrees(30.f));
|
||||
curProjectile->UpdateFX(clampedQuat.toTransform() * xf.getRotation(), dt, mgr);
|
||||
zeus::CTransform newXf = clampedQuat.toTransform() * xf.getRotation();
|
||||
newXf.origin = xf.origin;
|
||||
curProjectile->UpdateFx(newXf, dt, mgr);
|
||||
} else
|
||||
curProjectile->UpdateFX(xf, dt, mgr);
|
||||
curProjectile->UpdateFx(xf, dt, mgr);
|
||||
}
|
||||
|
||||
TCastToPtr<CCollisionActor> headAct = mgr.ObjectById(x600_headActor);
|
||||
|
@ -263,7 +267,8 @@ void CNewIntroBoss::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& nod
|
|||
zeus::CTransform xf = GetLctrTransform(x5dc_damageLocator);
|
||||
zeus::CVector3f playerPos = PlayerPos(mgr);
|
||||
x604_predictedPlayerPos = x610_lookPos = x62c_targetPos = playerPos;
|
||||
x628_ = 0.f;
|
||||
x61c_startPlayerPos = playerPos;
|
||||
x628_firingTime = 0.f;
|
||||
if (GetLocoForHealth(mgr) == pas::ELocomotionType::Combat)
|
||||
x676_curProjectile = x5d8_stage3Projectile;
|
||||
else if (GetLocoForHealth(mgr) == pas::ELocomotionType::Lurk)
|
||||
|
@ -337,24 +342,24 @@ bool CNewIntroBoss::ShouldAttack(CStateManager& mgr, float dt) {
|
|||
|
||||
bool CNewIntroBoss::AIStage(CStateManager& mgr, float) { return x568_locomotion != GetLocoForHealth(mgr); }
|
||||
|
||||
bool CNewIntroBoss::AnimOver(urde::CStateManager&, float) { return x56c_ == 3; }
|
||||
bool CNewIntroBoss::AnimOver(urde::CStateManager&, float) { return x56c_stateProg == 3; }
|
||||
|
||||
void CNewIntroBoss::Generate(CStateManager& mgr, EStateMsg msg, float dt) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x56c_ = 0;
|
||||
x56c_stateProg = 0;
|
||||
x568_locomotion = GetLocoForHealth(mgr);
|
||||
SendScriptMsgs(EScriptObjectState::Entered, mgr, EScriptObjectMessage::None);
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (x56c_ == 0) {
|
||||
if (x56c_stateProg == 0) {
|
||||
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Generate) {
|
||||
x56c_ = 2;
|
||||
x56c_stateProg = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(GetGenerateForHealth(mgr)));
|
||||
} else if (x56c_ == 2) {
|
||||
} else if (x56c_stateProg == 2) {
|
||||
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::Generate) {
|
||||
x56c_ = 3;
|
||||
x56c_stateProg = 3;
|
||||
SendScriptMsgs(EScriptObjectState::Exited, mgr, EScriptObjectMessage::None);
|
||||
}
|
||||
}
|
||||
|
@ -373,18 +378,18 @@ bool CNewIntroBoss::InAttackPosition(CStateManager& mgr, float dt) {
|
|||
|
||||
void CNewIntroBoss::Attack(CStateManager& mgr, EStateMsg msg, float dt) {
|
||||
if (msg == EStateMsg::Activate)
|
||||
x56c_ = 0;
|
||||
x56c_stateProg = 0;
|
||||
else if (msg == EStateMsg::Update) {
|
||||
if (x56c_ == 0) {
|
||||
if (x56c_stateProg == 0) {
|
||||
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::ProjectileAttack)
|
||||
x56c_ = 2;
|
||||
x56c_stateProg = 2;
|
||||
else {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(
|
||||
CBCProjectileAttackCmd(pas::ESeverity::One, mgr.GetPlayer().GetTranslation(), false));
|
||||
}
|
||||
} else if (x56c_ == 2) {
|
||||
} else if (x56c_stateProg == 2) {
|
||||
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::ProjectileAttack) {
|
||||
x56c_ = 3;
|
||||
x56c_stateProg = 3;
|
||||
x638_ = 0.f;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ class CCollisionActorManager;
|
|||
namespace MP1 {
|
||||
class CNewIntroBoss : public CPatterned {
|
||||
pas::ELocomotionType x568_locomotion = pas::ELocomotionType::Relaxed;
|
||||
u32 x56c_ = 0;
|
||||
u32 x56c_stateProg = 0;
|
||||
float x570_;
|
||||
CBoneTracking x574_boneTracking;
|
||||
CProjectileInfo x5ac_projectileInfo;
|
||||
|
@ -20,16 +20,16 @@ class CNewIntroBoss : public CPatterned {
|
|||
TUniqueId x5d8_stage3Projectile = kInvalidUniqueId;
|
||||
std::string x5dc_damageLocator; // ???
|
||||
std::unique_ptr<CCollisionActorManager> x5ec_collisionManager;
|
||||
CAssetId x5f0_;
|
||||
CAssetId x5f4_;
|
||||
CAssetId x5f8_;
|
||||
CAssetId x5fc_;
|
||||
CAssetId x5f0_beamContactFxId;
|
||||
CAssetId x5f4_beamPulseFxId;
|
||||
CAssetId x5f8_beamTextureId;
|
||||
CAssetId x5fc_beamGlowTextureId;
|
||||
TUniqueId x600_headActor = kInvalidUniqueId;
|
||||
TUniqueId x602_pelvisActor = kInvalidUniqueId;
|
||||
zeus::CVector3f x604_predictedPlayerPos;
|
||||
zeus::CVector3f x610_lookPos;
|
||||
zeus::CVector3f x61c_;
|
||||
float x628_ = 0.f;
|
||||
zeus::CVector3f x61c_startPlayerPos;
|
||||
float x628_firingTime = 0.f;
|
||||
zeus::CVector3f x62c_targetPos;
|
||||
float x638_ = 0.2f;
|
||||
float x63c_attackTime = 8.f;
|
||||
|
@ -48,8 +48,9 @@ class CNewIntroBoss : public CPatterned {
|
|||
public:
|
||||
DEFINE_PATTERNED(NewIntroBoss)
|
||||
CNewIntroBoss(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
|
||||
CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, float, CAssetId,
|
||||
const CDamageInfo& dInfo, CAssetId, CAssetId, CAssetId, CAssetId);
|
||||
CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms,
|
||||
float f1, CAssetId projectile, const CDamageInfo& dInfo, CAssetId beamContactFxId,
|
||||
CAssetId beamPulseFxId, CAssetId beamTextureId, CAssetId beamGlowTextureId);
|
||||
|
||||
void Accept(IVisitor& visitor);
|
||||
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager&);
|
||||
|
|
|
@ -5,62 +5,87 @@
|
|||
#include "zeus/CColor.hpp"
|
||||
|
||||
namespace urde {
|
||||
struct CBeamInfo {
|
||||
class CBeamInfo {
|
||||
u32 x0_;
|
||||
s32 x4_;
|
||||
CAssetId x8_;
|
||||
CAssetId xc_;
|
||||
CAssetId x10_;
|
||||
CAssetId x14_;
|
||||
s32 x18_;
|
||||
float x1c_;
|
||||
float x20_;
|
||||
float x24_;
|
||||
float x28_;
|
||||
float x2c_;
|
||||
float x30_;
|
||||
float x34_;
|
||||
float x38_;
|
||||
zeus::CColor x3c_;
|
||||
zeus::CColor x40_;
|
||||
/*
|
||||
* 0x1: motion blur
|
||||
* 0x2: pulse effect
|
||||
* 0x4: one shot
|
||||
* 0x8: phazon damage
|
||||
*/
|
||||
s32 x4_beamAttributes;
|
||||
CAssetId x8_contactFxId;
|
||||
CAssetId xc_pulseFxId;
|
||||
CAssetId x10_textureId;
|
||||
CAssetId x14_glowTextureId;
|
||||
s32 x18_length;
|
||||
float x1c_radius;
|
||||
float x20_expansionSpeed;
|
||||
float x24_lifeTime;
|
||||
float x28_pulseSpeed;
|
||||
float x2c_shutdownTime;
|
||||
float x30_contactFxScale;
|
||||
float x34_pulseFxScale;
|
||||
float x38_travelSpeed;
|
||||
zeus::CColor x3c_innerColor;
|
||||
zeus::CColor x40_outerColor;
|
||||
|
||||
public:
|
||||
CBeamInfo(CInputStream& in)
|
||||
: x0_(in.readUint32Big())
|
||||
, x4_(in.readUint32Big())
|
||||
, x8_(in.readUint32Big())
|
||||
, xc_(in.readUint32Big())
|
||||
, x10_(in.readUint32Big())
|
||||
, x14_(in.readUint32Big())
|
||||
, x18_(in.readFloatBig())
|
||||
, x1c_(in.readFloatBig())
|
||||
, x20_(in.readFloatBig())
|
||||
, x24_(in.readFloatBig())
|
||||
, x28_(in.readFloatBig())
|
||||
, x2c_(in.readFloatBig())
|
||||
, x30_(in.readFloatBig())
|
||||
, x34_(in.readFloatBig())
|
||||
, x38_(in.readFloatBig())
|
||||
, x3c_(zeus::CColor::ReadRGBABig(in))
|
||||
, x40_(zeus::CColor::ReadRGBABig(in)) {}
|
||||
, x4_beamAttributes(in.readUint32Big())
|
||||
, x8_contactFxId(in.readUint32Big())
|
||||
, xc_pulseFxId(in.readUint32Big())
|
||||
, x10_textureId(in.readUint32Big())
|
||||
, x14_glowTextureId(in.readUint32Big())
|
||||
, x18_length(in.readFloatBig())
|
||||
, x1c_radius(in.readFloatBig())
|
||||
, x20_expansionSpeed(in.readFloatBig())
|
||||
, x24_lifeTime(in.readFloatBig())
|
||||
, x28_pulseSpeed(in.readFloatBig())
|
||||
, x2c_shutdownTime(in.readFloatBig())
|
||||
, x30_contactFxScale(in.readFloatBig())
|
||||
, x34_pulseFxScale(in.readFloatBig())
|
||||
, x38_travelSpeed(in.readFloatBig())
|
||||
, x3c_innerColor(zeus::CColor::ReadRGBABig(in))
|
||||
, x40_outerColor(zeus::CColor::ReadRGBABig(in)) {}
|
||||
|
||||
CBeamInfo(s32 w1, CAssetId w2, CAssetId w3, CAssetId w4, CAssetId w5, s32 w6, float f1, float f2, float f3, float f4,
|
||||
float f5, float f6, float f7, const zeus::CColor& col1, const zeus::CColor& col2, float f8)
|
||||
: x4_(w1)
|
||||
, x8_(w2)
|
||||
, xc_(w3)
|
||||
, x10_(w4)
|
||||
, x14_(w5)
|
||||
, x18_(w6)
|
||||
, x1c_(f1)
|
||||
, x20_(f2)
|
||||
, x24_(f3)
|
||||
, x28_(f4)
|
||||
, x2c_(f5)
|
||||
, x30_(f6)
|
||||
, x34_(f7)
|
||||
, x38_(f8)
|
||||
, x3c_(col1)
|
||||
, x40_(col2) {}
|
||||
CBeamInfo(s32 beamAttributes, CAssetId contactFxId, CAssetId pulseFxId, CAssetId textureId, CAssetId glowTextureId,
|
||||
s32 length, float radius, float f2, float f3, float f4, float f5, float contactFxScale, float pulseFxScale,
|
||||
const zeus::CColor& innerColor, const zeus::CColor& outerColor, float travelSpeed)
|
||||
: x4_beamAttributes(beamAttributes)
|
||||
, x8_contactFxId(contactFxId)
|
||||
, xc_pulseFxId(pulseFxId)
|
||||
, x10_textureId(textureId)
|
||||
, x14_glowTextureId(glowTextureId)
|
||||
, x18_length(length)
|
||||
, x1c_radius(radius)
|
||||
, x20_expansionSpeed(f2)
|
||||
, x24_lifeTime(f3)
|
||||
, x28_pulseSpeed(f4)
|
||||
, x2c_shutdownTime(f5)
|
||||
, x30_contactFxScale(contactFxScale)
|
||||
, x34_pulseFxScale(pulseFxScale)
|
||||
, x38_travelSpeed(travelSpeed)
|
||||
, x3c_innerColor(innerColor)
|
||||
, x40_outerColor(outerColor) {}
|
||||
|
||||
s32 GetBeamAttributes() const { return x4_beamAttributes; }
|
||||
CAssetId GetContactFxId() const { return x8_contactFxId; }
|
||||
CAssetId GetPulseFxId() const { return xc_pulseFxId; }
|
||||
CAssetId GetTextureId() const { return x10_textureId; }
|
||||
CAssetId GetGlowTextureId() const { return x14_glowTextureId; }
|
||||
s32 GetLength() const { return x18_length; }
|
||||
float GetRadius() const { return x1c_radius; }
|
||||
float GetExpansionSpeed() const { return x20_expansionSpeed; }
|
||||
float GetLifeTime() const { return x24_lifeTime; }
|
||||
float GetPulseSpeed() const { return x28_pulseSpeed; }
|
||||
float GetShutdownTime() const { return x2c_shutdownTime; }
|
||||
float GetContactFxScale() const { return x30_contactFxScale; }
|
||||
float GetPulseFxScale() const { return x34_pulseFxScale; }
|
||||
float GetTravelSpeed() const { return x38_travelSpeed; }
|
||||
const zeus::CColor& GetInnerColor() const { return x3c_innerColor; }
|
||||
const zeus::CColor& GetOuterColor() const { return x40_outerColor; }
|
||||
};
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -1,41 +1,91 @@
|
|||
#include "Weapon/CBeamProjectile.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
#include "CStateManager.hpp"
|
||||
|
||||
namespace urde {
|
||||
|
||||
CBeamProjectile::CBeamProjectile(const TToken<CWeaponDescription>& wDesc, std::string_view name, EWeaponType wType,
|
||||
const zeus::CTransform& xf, s32 flags, float f1, float f2, EMaterialTypes matType,
|
||||
const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner,
|
||||
EProjectileAttrib attribs, bool b1)
|
||||
const zeus::CTransform& xf, s32 maxLength, float beamRadius, float travelSpeed,
|
||||
EMaterialTypes matType, const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid,
|
||||
TUniqueId owner, EProjectileAttrib attribs, bool growingBeam)
|
||||
: CGameProjectile(false, wDesc, name, wType, xf, matType, dInfo, uid, aid, owner, kInvalidUniqueId, attribs, false,
|
||||
zeus::CVector3f::skOne, {}, -1, false)
|
||||
, x2e8_(std::abs(flags))
|
||||
, x2ec_(x2e8_)
|
||||
, x2f0_(1.f / x2ec_)
|
||||
, x2f4_(f1)
|
||||
, x300_(b1 == false ? x2ec_ : 0.f)
|
||||
, x308_(f2)
|
||||
, x464_24_(b1)
|
||||
, x464_25_(false) {}
|
||||
zeus::CVector3f::skOne, {}, 0xffff, false)
|
||||
, x2e8_intMaxLength(std::abs(maxLength))
|
||||
, x2ec_maxLength(x2e8_intMaxLength)
|
||||
, x2f0_invMaxLength(1.f / x2ec_maxLength)
|
||||
, x2f4_beamRadius(beamRadius)
|
||||
, x300_intBeamLength(growingBeam ? 0.f : x2ec_maxLength)
|
||||
, x304_beamLength(x2ec_maxLength)
|
||||
, x308_travelSpeed(travelSpeed)
|
||||
, x464_24_growingBeam(growingBeam)
|
||||
, x464_25_enableTouchDamage(false) {
|
||||
x384_.resize(10);
|
||||
x400_pointCache.resize(8);
|
||||
}
|
||||
|
||||
std::experimental::optional<zeus::CAABox> CBeamProjectile::GetTouchBounds() const {
|
||||
if (!GetActive())
|
||||
return {};
|
||||
if (!x464_25_) {
|
||||
if (x464_25_enableTouchDamage) {
|
||||
zeus::CVector3f pos = GetTranslation();
|
||||
return {{pos - 1.f, pos + 1.f}};
|
||||
return {{pos - 0.1f, pos + 0.1f}};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void CBeamProjectile::CalculateRenderBounds() { x9c_renderBounds = x354_.getTransformedAABox(x324_); }
|
||||
void CBeamProjectile::CalculateRenderBounds() { x9c_renderBounds = x354_.getTransformedAABox(x324_xf); }
|
||||
|
||||
void CBeamProjectile::ResetBeam(CStateManager&, bool) {
|
||||
if (x464_24_)
|
||||
x300_ = 0.f;
|
||||
if (x464_24_growingBeam)
|
||||
x300_intBeamLength = 0.f;
|
||||
}
|
||||
|
||||
void CBeamProjectile::UpdateFX(const zeus::CTransform&, float, CStateManager&) {}
|
||||
void CBeamProjectile::SetCollisionResultData(EDamageType dType, CRayCastResult& res, TUniqueId id) {
|
||||
x2f8_damageType = dType;
|
||||
x304_beamLength = res.GetT();
|
||||
x318_collisionPoint = res.GetPoint();
|
||||
x30c_collisionNormal = res.GetPlane().normal();
|
||||
x2fe_collisionActorId = dType == EDamageType::Actor ? id : kInvalidUniqueId;
|
||||
SetTranslation(res.GetPoint());
|
||||
}
|
||||
|
||||
void CBeamProjectile::UpdateFx(const zeus::CTransform& xf, float dt, CStateManager& mgr) {
|
||||
if (!GetActive())
|
||||
return;
|
||||
|
||||
SetTransform(xf.getRotation());
|
||||
if (x464_24_growingBeam) {
|
||||
x300_intBeamLength += x308_travelSpeed * dt;
|
||||
if (x300_intBeamLength > x2ec_maxLength)
|
||||
x300_intBeamLength = x2ec_maxLength;
|
||||
}
|
||||
x304_beamLength = x300_intBeamLength;
|
||||
x2f8_damageType = EDamageType::None;
|
||||
x298_previousPos = xf.origin;
|
||||
zeus::CVector3f beamEnd = xf.basis[1].normalized() * x300_intBeamLength + xf.origin;
|
||||
SetTranslation(beamEnd);
|
||||
x354_ = zeus::CAABox(zeus::CVector3f{-x2f4_beamRadius, 0.f, -x2f4_beamRadius},
|
||||
zeus::CVector3f{x2f4_beamRadius, x304_beamLength, x2f4_beamRadius});
|
||||
x36c_ = zeus::CAABox(zeus::CVector3f{-x2f4_beamRadius, 0.f, -x2f4_beamRadius},
|
||||
zeus::CVector3f{x2f4_beamRadius, x300_intBeamLength, x2f4_beamRadius}).getTransformedAABox(xf);
|
||||
rstl::reserved_vector<TUniqueId, 1024> nearList;
|
||||
mgr.BuildNearList(nearList, x36c_, CMaterialFilter::MakeExclude({EMaterialTypes::ProjectilePassthrough}), nullptr);
|
||||
TUniqueId collideId = kInvalidUniqueId;
|
||||
CRayCastResult res = RayCollisionCheckWithWorld(collideId, x298_previousPos, beamEnd, x300_intBeamLength, nearList, mgr);
|
||||
if (TCastToPtr<CActor> act = mgr.ObjectById(collideId)) {
|
||||
SetCollisionResultData(EDamageType::Actor, res, collideId);
|
||||
if (x464_25_enableTouchDamage)
|
||||
ApplyDamageToActors(mgr, CDamageInfo(x12c_curDamageInfo, dt));
|
||||
} else if (res.IsValid()) {
|
||||
SetCollisionResultData(EDamageType::World, res, kInvalidUniqueId);
|
||||
if (x464_25_enableTouchDamage)
|
||||
mgr.ApplyDamageToWorld(xec_ownerId, *this, res.GetPoint(), CDamageInfo(x12c_curDamageInfo, dt), xf8_filter);
|
||||
} else {
|
||||
x318_collisionPoint = xf * zeus::CVector3f(x2f4_beamRadius, x304_beamLength, x2f4_beamRadius);
|
||||
SetTranslation(x318_collisionPoint);
|
||||
}
|
||||
x324_xf = xf;
|
||||
}
|
||||
|
||||
void CBeamProjectile::Accept(urde::IVisitor& visitor) { visitor.Visit(this); }
|
||||
|
||||
|
|
|
@ -3,48 +3,61 @@
|
|||
#include "Weapon/CGameProjectile.hpp"
|
||||
namespace urde {
|
||||
class CBeamProjectile : public CGameProjectile {
|
||||
u32 x2e8_;
|
||||
float x2ec_;
|
||||
float x2f0_;
|
||||
float x2f4_;
|
||||
u32 x2f8_ = 0;
|
||||
public:
|
||||
enum class EDamageType {
|
||||
None,
|
||||
Actor,
|
||||
World
|
||||
};
|
||||
|
||||
private:
|
||||
s32 x2e8_intMaxLength;
|
||||
float x2ec_maxLength;
|
||||
float x2f0_invMaxLength;
|
||||
float x2f4_beamRadius;
|
||||
EDamageType x2f8_damageType = EDamageType::None;
|
||||
TUniqueId x2fc_ = kInvalidUniqueId;
|
||||
TUniqueId x2fe_ = kInvalidUniqueId;
|
||||
float x300_;
|
||||
float x304_;
|
||||
float x308_;
|
||||
zeus::CVector3f x30c_ = zeus::CVector3f::skUp;
|
||||
zeus::CTransform x324_;
|
||||
TUniqueId x2fe_collisionActorId = kInvalidUniqueId;
|
||||
float x300_intBeamLength;
|
||||
float x304_beamLength;
|
||||
float x308_travelSpeed;
|
||||
zeus::CVector3f x30c_collisionNormal = zeus::CVector3f::skUp;
|
||||
zeus::CVector3f x318_collisionPoint = zeus::CVector3f::skZero;
|
||||
zeus::CTransform x324_xf;
|
||||
zeus::CAABox x354_ = zeus::CAABox::skNullBox;
|
||||
zeus::CAABox x36c_ = zeus::CAABox::skNullBox;
|
||||
rstl::reserved_vector<zeus::CVector3f, 10> x384_;
|
||||
rstl::reserved_vector<zeus::CVector3f, 8> x400_;
|
||||
bool x464_24_ : 1;
|
||||
bool x464_25_ : 1;
|
||||
rstl::reserved_vector<zeus::CVector3f, 8> x400_pointCache;
|
||||
bool x464_24_growingBeam : 1;
|
||||
bool x464_25_enableTouchDamage : 1;
|
||||
|
||||
void SetCollisionResultData(EDamageType dType, CRayCastResult& res, TUniqueId id);
|
||||
|
||||
public:
|
||||
CBeamProjectile(const TToken<CWeaponDescription>& wDesc, std::string_view name, EWeaponType wType,
|
||||
const zeus::CTransform& xf, s32 flags, float f1, float f2, EMaterialTypes matType,
|
||||
const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner, EProjectileAttrib attribs,
|
||||
bool b1);
|
||||
const zeus::CTransform& xf, s32 maxLength, float beamRadius, float travelSpeed,
|
||||
EMaterialTypes matType, const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner,
|
||||
EProjectileAttrib attribs, bool growingBeam);
|
||||
|
||||
void Accept(IVisitor& visitor);
|
||||
float GetMaxRadius() const;
|
||||
zeus::CVector3f GetSurfaceNormal() const;
|
||||
void GetDamageType() const;
|
||||
void GetCurrentPos() const;
|
||||
void PointCache();
|
||||
void GetPointCache() const;
|
||||
void CauseDamage(bool);
|
||||
zeus::CVector3f GetBeamOrigin() const;
|
||||
void GetInvMaxLength() const;
|
||||
void GetCurrentLength();
|
||||
void GetMaxLength();
|
||||
s32 GetIntMaxLength();
|
||||
float GetMaxRadius() const { return x2f4_beamRadius; }
|
||||
const zeus::CVector3f& GetSurfaceNormal() const { return x30c_collisionNormal; }
|
||||
EDamageType GetDamageType() const { return x2f8_damageType; }
|
||||
const zeus::CVector3f& GetCurrentPos() const { return x318_collisionPoint; }
|
||||
rstl::reserved_vector<zeus::CVector3f, 8>& PointCache() { return x400_pointCache; }
|
||||
const rstl::reserved_vector<zeus::CVector3f, 8>& GetPointCache() const { return x400_pointCache; }
|
||||
void CauseDamage(bool b) { x464_25_enableTouchDamage = b; }
|
||||
const zeus::CTransform& GetBeamTransform() const { return x324_xf; }
|
||||
float GetInvMaxLength() const { return x2f0_invMaxLength; }
|
||||
float GetCurrentLength() const { return x304_beamLength; }
|
||||
float GetMaxLength() const { return x2ec_maxLength; }
|
||||
s32 GetIntMaxLength() const { return x2e8_intMaxLength; }
|
||||
TUniqueId GetCollisionActorId() const { return x2fe_collisionActorId; }
|
||||
|
||||
std::experimental::optional<zeus::CAABox> GetTouchBounds() const;
|
||||
void CalculateRenderBounds();
|
||||
virtual void ResetBeam(CStateManager&, bool);
|
||||
virtual void UpdateFX(const zeus::CTransform&, float, CStateManager&);
|
||||
virtual void UpdateFx(const zeus::CTransform&, float, CStateManager&);
|
||||
virtual void Fire(const zeus::CTransform&, CStateManager&, bool) = 0;
|
||||
};
|
||||
} // namespace urde
|
||||
|
|
|
@ -28,7 +28,7 @@ CGameProjectile::CGameProjectile(bool active, const TToken<CWeaponDescription>&
|
|||
, x168_visorSfx(visorSfx)
|
||||
, x170_projectile(wDesc, xf.origin, xf.basis, scale,
|
||||
(attribs & EProjectileAttrib::ParticleOPTS) == EProjectileAttrib::ParticleOPTS)
|
||||
, x298_lastOrigin(xf.origin)
|
||||
, x298_previousPos(xf.origin)
|
||||
, x2a4_projExtent((xe8_projectileAttribs & EProjectileAttrib::BigProjectile) == EProjectileAttrib::BigProjectile ? 0.25f
|
||||
: 0.1f)
|
||||
, x2c0_homingTargetId(homingTarget)
|
||||
|
@ -186,7 +186,7 @@ void CGameProjectile::UpdateProjectileMovement(float dt, CStateManager& mgr) {
|
|||
if (x2e4_26_waterUpdate)
|
||||
useDt = 37.5f * dt * dt;
|
||||
|
||||
x298_lastOrigin = x34_transform.origin;
|
||||
x298_previousPos = x34_transform.origin;
|
||||
x170_projectile.Update(useDt);
|
||||
SetTransform(x170_projectile.GetTransform());
|
||||
SetTranslation(x170_projectile.GetTranslation());
|
||||
|
@ -196,12 +196,12 @@ void CGameProjectile::UpdateProjectileMovement(float dt, CStateManager& mgr) {
|
|||
CRayCastResult CGameProjectile::DoCollisionCheck(TUniqueId& idOut, CStateManager& mgr) {
|
||||
CRayCastResult res;
|
||||
if (x2e4_24_active) {
|
||||
zeus::CVector3f posDelta = x34_transform.origin - x298_lastOrigin;
|
||||
zeus::CVector3f posDelta = x34_transform.origin - x298_previousPos;
|
||||
rstl::reserved_vector<TUniqueId, 1024> nearList;
|
||||
mgr.BuildNearList(nearList, GetProjectileBounds(),
|
||||
CMaterialFilter::MakeExclude(EMaterialTypes::ProjectilePassthrough), this);
|
||||
|
||||
res = RayCollisionCheckWithWorld(idOut, x298_lastOrigin, x34_transform.origin, posDelta.magnitude(), nearList, mgr);
|
||||
res = RayCollisionCheckWithWorld(idOut, x298_previousPos, x34_transform.origin, posDelta.magnitude(), nearList, mgr);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -335,25 +335,25 @@ CProjectileTouchResult CGameProjectile::CanCollideWithComplexCollision(CActor& a
|
|||
if (useAct) {
|
||||
const CCollisionPrimitive* prim = useAct->GetCollisionPrimitive();
|
||||
zeus::CTransform xf = useAct->GetPrimitiveTransform();
|
||||
zeus::CVector3f deltaPos = GetTranslation() - x298_lastOrigin;
|
||||
zeus::CVector3f deltaPos = GetTranslation() - x298_previousPos;
|
||||
if (deltaPos.canBeNormalized()) {
|
||||
zeus::CVector3f dir = deltaPos.normalized();
|
||||
float mag = deltaPos.magnitude();
|
||||
CRayCastResult res = prim->CastRayInternal(
|
||||
{x298_lastOrigin, dir, mag, xf,
|
||||
{x298_previousPos, dir, mag, xf,
|
||||
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::ProjectilePassthrough})});
|
||||
if (!res.IsValid()) {
|
||||
if (prim->GetPrimType() == FOURCC('SPHR')) {
|
||||
mag *= 2.f;
|
||||
CRayCastResult res2 = prim->CastRayInternal(
|
||||
{x298_lastOrigin - dir * mag, dir, deltaPos.magnitude(), xf,
|
||||
{x298_previousPos - dir * mag, dir, deltaPos.magnitude(), xf,
|
||||
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::ProjectilePassthrough})});
|
||||
if (res2.IsValid())
|
||||
return {act.GetUniqueId(), {res2}};
|
||||
} else if (TCastToPtr<CCollisionActor> cAct = act) {
|
||||
float rad = cAct->GetSphereRadius();
|
||||
if ((x298_lastOrigin - GetTranslation()).magSquared() < rad * rad) {
|
||||
zeus::CVector3f point = x298_lastOrigin - dir * rad * 1.125f;
|
||||
if ((x298_previousPos - GetTranslation()).magSquared() < rad * rad) {
|
||||
zeus::CVector3f point = x298_previousPos - dir * rad * 1.125f;
|
||||
zeus::CUnitVector3f revDir(-dir);
|
||||
return {act.GetUniqueId(), {{0.f, point, {revDir, point.dot(revDir)}, act.GetMaterialList()}}};
|
||||
}
|
||||
|
@ -415,12 +415,12 @@ CProjectileTouchResult CGameProjectile::CanCollideWithTrigger(CActor& act, CStat
|
|||
}
|
||||
|
||||
zeus::CAABox CGameProjectile::GetProjectileBounds() const {
|
||||
return {{std::min(x298_lastOrigin.x(), GetTranslation().x()) - x2a4_projExtent,
|
||||
std::min(x298_lastOrigin.y(), GetTranslation().y()) - x2a4_projExtent,
|
||||
std::min(x298_lastOrigin.z(), GetTranslation().z()) - x2a4_projExtent},
|
||||
{std::max(x298_lastOrigin.x(), GetTranslation().x()) + x2a4_projExtent,
|
||||
std::max(x298_lastOrigin.y(), GetTranslation().y()) + x2a4_projExtent,
|
||||
std::max(x298_lastOrigin.z(), GetTranslation().z()) + x2a4_projExtent}};
|
||||
return {{std::min(x298_previousPos.x(), GetTranslation().x()) - x2a4_projExtent,
|
||||
std::min(x298_previousPos.y(), GetTranslation().y()) - x2a4_projExtent,
|
||||
std::min(x298_previousPos.z(), GetTranslation().z()) - x2a4_projExtent},
|
||||
{std::max(x298_previousPos.x(), GetTranslation().x()) + x2a4_projExtent,
|
||||
std::max(x298_previousPos.y(), GetTranslation().y()) + x2a4_projExtent,
|
||||
std::max(x298_previousPos.z(), GetTranslation().z()) + x2a4_projExtent}};
|
||||
}
|
||||
|
||||
std::experimental::optional<zeus::CAABox> CGameProjectile::GetTouchBounds() const {
|
||||
|
|
|
@ -30,7 +30,7 @@ protected:
|
|||
std::experimental::optional<TLockedToken<CGenDescription>> x158_visorParticle;
|
||||
u16 x168_visorSfx;
|
||||
CProjectileWeapon x170_projectile;
|
||||
zeus::CVector3f x298_lastOrigin;
|
||||
zeus::CVector3f x298_previousPos;
|
||||
float x2a4_projExtent;
|
||||
float x2a8_homingDt = 0.03f;
|
||||
double x2b0_targetHomingTime = 0.0;
|
||||
|
@ -83,6 +83,6 @@ public:
|
|||
zeus::CAABox GetProjectileBounds() const;
|
||||
std::experimental::optional<zeus::CAABox> GetTouchBounds() const;
|
||||
TUniqueId GetHomingTargetId() const { return x2c0_homingTargetId; }
|
||||
zeus::CVector3f GetPreviousPos() const { return x298_lastOrigin; }
|
||||
zeus::CVector3f GetPreviousPos() const { return x298_previousPos; }
|
||||
};
|
||||
} // namespace urde
|
||||
|
|
|
@ -1,17 +1,436 @@
|
|||
#include "CPlasmaProjectile.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "CSimplePool.hpp"
|
||||
#include "World/CGameLight.hpp"
|
||||
#include "CStateManager.hpp"
|
||||
#include "Graphics/CBooRenderer.hpp"
|
||||
#include "World/CPlayer.hpp"
|
||||
#include "World/CHUDBillboardEffect.hpp"
|
||||
|
||||
namespace urde {
|
||||
|
||||
CPlasmaProjectile::RenderObjects::RenderObjects(boo::IGraphicsDataFactory::Context& ctx,
|
||||
boo::ObjToken<boo::ITexture> tex,
|
||||
boo::ObjToken<boo::ITexture> glowTex)
|
||||
: m_beamStrip1(ctx, 8, CColoredStripShader::Mode::Additive, {})
|
||||
, m_beamStrip2(ctx, 10, CColoredStripShader::Mode::FullAdditive, tex)
|
||||
, m_beamStrip3(ctx, 18, CColoredStripShader::Mode::FullAdditive, tex)
|
||||
, m_beamStrip4(ctx, 14, CColoredStripShader::Mode::Additive, glowTex)
|
||||
, m_motionBlurStrip(ctx, 16, CColoredStripShader::Mode::Alpha, {}) {}
|
||||
|
||||
CPlasmaProjectile::CPlasmaProjectile(const TToken<CWeaponDescription>& wDesc, std::string_view name, EWeaponType wType,
|
||||
const CBeamInfo& bInfo, const zeus::CTransform& xf, EMaterialTypes matType,
|
||||
const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner, u32 w1,
|
||||
bool b1, EProjectileAttrib attribs)
|
||||
: CBeamProjectile(wDesc, name, wType, xf, bInfo.x18_, bInfo.x1c_, bInfo.x38_, matType, dInfo, uid, aid, owner, attribs,
|
||||
b1) {}
|
||||
const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner,
|
||||
const PlayerEffectResoures& res, bool growingBeam, EProjectileAttrib attribs)
|
||||
: CBeamProjectile(wDesc, name, wType, xf, bInfo.GetLength(), bInfo.GetRadius(), bInfo.GetTravelSpeed(), matType,
|
||||
dInfo, uid, aid, owner, attribs, growingBeam)
|
||||
, x478_beamAttributes(bInfo.GetBeamAttributes())
|
||||
, x47c_lifeTime(bInfo.GetLifeTime())
|
||||
, x480_pulseSpeed(bInfo.GetPulseSpeed())
|
||||
, x484_shutdownTime(bInfo.GetShutdownTime())
|
||||
, x488_expansionSpeed(bInfo.GetExpansionSpeed())
|
||||
, x48c_(bInfo.GetLength() / 32.f)
|
||||
, x490_innerColor(bInfo.GetInnerColor())
|
||||
, x494_outerColor(bInfo.GetOuterColor()) {
|
||||
x4e8_texture = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), bInfo.GetTextureId()});
|
||||
x4f4_glowTexture = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), bInfo.GetGlowTextureId()});
|
||||
x500_contactFxDesc = g_SimplePool->GetObj(SObjectTag{FOURCC('PART'), bInfo.GetContactFxId()});
|
||||
x50c_pulseFxDesc = g_SimplePool->GetObj(SObjectTag{FOURCC('PART'), bInfo.GetPulseFxId()});
|
||||
x518_contactGen = std::make_unique<CElementGen>(x500_contactFxDesc, CElementGen::EModelOrientationType::One);
|
||||
x51c_pulseGen = std::make_unique<CElementGen>(x50c_pulseFxDesc, CElementGen::EModelOrientationType::Normal);
|
||||
x524_freezeSteamTxtr = res[0];
|
||||
x528_freezeIceTxtr = res[1];
|
||||
if (res[2] != UINT64_MAX)
|
||||
x52c_visorElectric = g_SimplePool->GetObj(SObjectTag{FOURCC('ELSC'), res[2]});
|
||||
if (res[3] != UINT64_MAX)
|
||||
x538_visorParticle = g_SimplePool->GetObj(SObjectTag{FOURCC('PART'), res[3]});
|
||||
x544_freezeSfx = CSfxManager::TranslateSFXID(res[4]);
|
||||
x546_electricSfx = CSfxManager::TranslateSFXID(res[5]);
|
||||
x548_25_enableEnergyPulse = true;
|
||||
x548_28_drawOwnerFirst = growingBeam;
|
||||
x518_contactGen->SetGlobalScale(zeus::CVector3f(bInfo.GetContactFxScale()));
|
||||
x51c_pulseGen->SetGlobalScale(zeus::CVector3f(bInfo.GetPulseFxScale()));
|
||||
x518_contactGen->SetParticleEmission(false);
|
||||
x51c_pulseGen->SetParticleEmission(false);
|
||||
|
||||
CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
m_renderObjs.emplace(ctx, x4e8_texture->GetBooTexture(), x4f4_glowTexture->GetBooTexture());
|
||||
return true;
|
||||
} BooTrace);
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::Accept(IVisitor& visitor) { visitor.Visit(this); }
|
||||
|
||||
void CPlasmaProjectile::Fire(const zeus::CTransform&, CStateManager&, bool) { SetActive(true); }
|
||||
void CPlasmaProjectile::SetLightsActive(bool active, CStateManager& mgr) {
|
||||
for (TUniqueId lid : x468_lights) {
|
||||
if (lid != kInvalidUniqueId) {
|
||||
if (TCastToPtr<CGameLight> light = mgr.ObjectById(lid)) {
|
||||
light->SetActive(active);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::CreatePlasmaLights(u32 sourceId, const CLight& l, CStateManager& mgr) {
|
||||
DeletePlasmaLights(mgr);
|
||||
x468_lights.reserve(3);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
TUniqueId lid = mgr.AllocateUniqueId();
|
||||
auto* light =
|
||||
new CGameLight(lid, GetAreaId(), GetActive(), ""sv, GetTransform(), GetUniqueId(), l, sourceId, 0, 0.f);
|
||||
mgr.AddObject(light);
|
||||
x468_lights.push_back(lid);
|
||||
}
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::DeletePlasmaLights(CStateManager& mgr) {
|
||||
for (TUniqueId lid : x468_lights)
|
||||
mgr.FreeScriptObject(lid);
|
||||
x468_lights.clear();
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::UpdateLights(float expansion, float dt, CStateManager& mgr) {
|
||||
if (x520_weaponGen) {
|
||||
x520_weaponGen->Update(dt);
|
||||
CLight l = x520_weaponGen->GetLight();
|
||||
l.SetColor(zeus::CColor::lerp(zeus::CColor::skClear, l.GetColor(), expansion));
|
||||
float halfLen = 0.5f * GetCurrentLength();
|
||||
float y = 0.f;
|
||||
for (TUniqueId lid : x468_lights) {
|
||||
if (TCastToPtr<CGameLight> light = mgr.ObjectById(lid)) {
|
||||
light->SetTransform({});
|
||||
light->SetTranslation(GetBeamTransform() * zeus::CVector3f(0.f, y, 0.f));
|
||||
light->SetLight(l);
|
||||
}
|
||||
y += halfLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::UpdateEnergyPulse(float dt) {
|
||||
if (GetDamageType() != EDamageType::None && x548_25_enableEnergyPulse) {
|
||||
x4d8_energyPulseTimer -= dt;
|
||||
if (x4d8_energyPulseTimer <= 0.f) {
|
||||
x4d8_energyPulseTimer = 2.f * dt;
|
||||
x51c_pulseGen->SetParticleEmission(true);
|
||||
float t = GetCurrentLength() / GetMaxLength();
|
||||
for (float i = 0.f; i <= t; i += 0.1f) {
|
||||
float y = i * GetMaxLength() + x4cc_energyPulseStartY;
|
||||
if (y > GetCurrentLength())
|
||||
continue;
|
||||
x51c_pulseGen->SetTranslation({0.f, y, 0.f});
|
||||
x51c_pulseGen->ForceParticleCreation(1);
|
||||
}
|
||||
x51c_pulseGen->SetGlobalOrientAndTrans(GetBeamTransform());
|
||||
x51c_pulseGen->SetParticleEmission(false);
|
||||
}
|
||||
}
|
||||
x51c_pulseGen->Update(dt);
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::RenderMotionBlur() const {
|
||||
CGraphics::SetModelMatrix({});
|
||||
zeus::CColor color1 = x494_outerColor;
|
||||
zeus::CColor color2 = x494_outerColor;
|
||||
color1.a() = 63.f / 255.f;
|
||||
color2.a() = 0.f;
|
||||
CColoredStripShader::Vert verts[16];
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
auto& v1 = verts[i * 2];
|
||||
auto& v2 = verts[i * 2 + 1];
|
||||
v1.m_pos = GetBeamTransform().origin;
|
||||
v1.m_color = zeus::CColor::lerp(color1, color2, i / 8.f);
|
||||
v2.m_pos = GetPointCache()[i];
|
||||
v2.m_color = v1.m_color;
|
||||
}
|
||||
m_renderObjs->m_motionBlurStrip.draw(zeus::CColor::skWhite, 16, verts);
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::RenderBeam(s32 subdivs, float width, const zeus::CColor& color, s32 flags,
|
||||
CColoredStripShader& shader) const {
|
||||
// Flags: 0x1: textured, 0x2: length controlled UVY 0x4: alpha controlled additive blend,
|
||||
// 0x8: glow texture, 0x10: subtractive blend
|
||||
if ((flags & 0x1) == 0 || (flags & 0x8) ? x4f4_glowTexture.IsLoaded() : x4e8_texture.IsLoaded()) {
|
||||
float angIncrement = 2.f * M_PIF / float(subdivs);
|
||||
float uvY1 = -(x4cc_energyPulseStartY / 16.f);
|
||||
float uvY2 = (uvY1 + float((flags & 0x3) == 0x3) != 0.f) ? 2.f : 0.5f * GetCurrentLength();
|
||||
CColoredStripShader::Vert verts[18];
|
||||
s32 numNodes = subdivs + 1;
|
||||
float angle = 0.f;
|
||||
bool flip = false;
|
||||
for (s32 i = 0; i < numNodes; ++i) {
|
||||
CColoredStripShader::Vert& v0 = verts[i * 2];
|
||||
CColoredStripShader::Vert& v1 = verts[i * 2 + 1];
|
||||
float x = std::cos(angle);
|
||||
float y = std::sin(angle);
|
||||
float uvX;
|
||||
if (flags & 0x8)
|
||||
uvX = 0.5f * y;
|
||||
else if (flip)
|
||||
uvX = width;
|
||||
else
|
||||
uvX = 0.f;
|
||||
flip ^= true;
|
||||
v0.m_pos = zeus::CVector3f(width * x, 0.f, width * y);
|
||||
v0.m_color = color;
|
||||
v0.m_uv = zeus::CVector2f(uvX, uvY1);
|
||||
v1.m_pos = zeus::CVector3f(width * x, GetCurrentLength(), width * y);
|
||||
v1.m_color = color;
|
||||
v1.m_uv = zeus::CVector2f(uvX, uvY2);
|
||||
angle += angIncrement;
|
||||
}
|
||||
shader.draw(zeus::CColor::skWhite, numNodes * 2, verts);
|
||||
}
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::ResetBeam(CStateManager& mgr, bool fullReset) {
|
||||
if (fullReset) {
|
||||
SetActive(false);
|
||||
SetLightsActive(false, mgr);
|
||||
x4bc_lifeTimer = 0.f;
|
||||
x4c0_expansionT = 0.f;
|
||||
x4c8_beamAngle = 0.f;
|
||||
x4d0_shutdownTimer = 0.f;
|
||||
x4d4_contactPulseTimer = 0.f;
|
||||
x4d8_energyPulseTimer = 0.f;
|
||||
x4dc_playerEffectPulseTimer = 0.f;
|
||||
x4b4_expansionState = EExpansionState::Inactive;
|
||||
x548_26_firing = false;
|
||||
x518_contactGen->SetParticleEmission(false);
|
||||
x51c_pulseGen->SetParticleEmission(false);
|
||||
} else {
|
||||
x548_26_firing = false;
|
||||
x4b4_expansionState = EExpansionState::Release;
|
||||
x518_contactGen->SetParticleEmission(false);
|
||||
x51c_pulseGen->SetParticleEmission(false);
|
||||
}
|
||||
}
|
||||
|
||||
float CPlasmaProjectile::UpdateBeamState(float dt, CStateManager& mgr) {
|
||||
switch (x4b4_expansionState) {
|
||||
case EExpansionState::Attack:
|
||||
if (x4c0_expansionT > 0.5f)
|
||||
x4b4_expansionState = EExpansionState::Sustain;
|
||||
else
|
||||
x4c0_expansionT += dt * x488_expansionSpeed;
|
||||
break;
|
||||
case EExpansionState::Sustain:
|
||||
if (x478_beamAttributes & 0x4) {
|
||||
if (x4bc_lifeTimer > x47c_lifeTime)
|
||||
x4b4_expansionState = EExpansionState::Release;
|
||||
else
|
||||
x4bc_lifeTimer += dt;
|
||||
}
|
||||
break;
|
||||
case EExpansionState::Release:
|
||||
x4c0_expansionT += dt * x488_expansionSpeed;
|
||||
if (x4c0_expansionT > 1.f) {
|
||||
x4c0_expansionT = 1.f;
|
||||
x4b4_expansionState = EExpansionState::Done;
|
||||
x548_25_enableEnergyPulse = false;
|
||||
}
|
||||
break;
|
||||
case EExpansionState::Done:
|
||||
x4d0_shutdownTimer += dt;
|
||||
if (x4d0_shutdownTimer > x484_shutdownTime &&
|
||||
(!x518_contactGen || x518_contactGen->GetParticleCountAll() == 0)) {
|
||||
x4b4_expansionState = EExpansionState::Inactive;
|
||||
ResetBeam(mgr, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -4.f * x4c0_expansionT * (x4c0_expansionT - 1.f);
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) {
|
||||
switch (msg) {
|
||||
case EScriptObjectMessage::Registered: {
|
||||
xe6_27_thermalVisorFlags = 2;
|
||||
const SChildGeneratorDesc& apsm = x170_projectile.GetWeaponDescription()->x34_APSM;
|
||||
if (apsm)
|
||||
x520_weaponGen = std::make_unique<CElementGen>(apsm.m_token);
|
||||
if (x520_weaponGen && x520_weaponGen->SystemHasLight())
|
||||
CreatePlasmaLights(x170_projectile.GetWeaponDescription().GetObjectTag()->id.Value(),
|
||||
x520_weaponGen->GetLight(), mgr);
|
||||
else
|
||||
x520_weaponGen.reset();
|
||||
if (x548_28_drawOwnerFirst)
|
||||
xc6_nextDrawNode = xec_ownerId;
|
||||
mgr.AddWeaponId(xec_ownerId, xf0_weaponType);
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Deleted:
|
||||
mgr.RemoveWeaponId(xec_ownerId, xf0_weaponType);
|
||||
DeletePlasmaLights(mgr);
|
||||
if (x548_29_activePlayerPhazon) {
|
||||
mgr.GetPlayer().DecrementPhazon();
|
||||
x548_29_activePlayerPhazon = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CGameProjectile::AcceptScriptMsg(msg, sender, mgr);
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::MakeBillboardEffect(const std::experimental::optional<TToken<CGenDescription>>& particle,
|
||||
const std::experimental::optional<TToken<CElectricDescription>>& electric,
|
||||
std::string_view name, CStateManager& mgr) {
|
||||
auto* effect = new CHUDBillboardEffect(particle, electric, mgr.AllocateUniqueId(), true, name,
|
||||
CHUDBillboardEffect::GetNearClipDistance(mgr),
|
||||
CHUDBillboardEffect::GetScaleForPOV(mgr),
|
||||
zeus::CColor::skWhite, zeus::CVector3f::skOne, zeus::CVector3f::skZero);
|
||||
mgr.AddObject(effect);
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::UpdatePlayerEffects(float dt, CStateManager& mgr) {
|
||||
x4dc_playerEffectPulseTimer -= dt;
|
||||
if ((x4b4_expansionState == EExpansionState::Attack || x4b4_expansionState == EExpansionState::Sustain) &&
|
||||
x4dc_playerEffectPulseTimer <= 0.f && GetDamageType() == EDamageType::Actor &&
|
||||
GetCollisionActorId() == mgr.GetPlayer().GetUniqueId()) {
|
||||
if ((x478_beamAttributes & 0x8) && !x548_29_activePlayerPhazon) {
|
||||
x548_29_activePlayerPhazon = true;
|
||||
x4e4_playerDamageTimer = 0.f;
|
||||
mgr.GetPlayer().IncrementPhazon();
|
||||
}
|
||||
switch (xf0_weaponType) {
|
||||
case EWeaponType::Ice:
|
||||
mgr.GetPlayer().Freeze(mgr, x524_freezeSteamTxtr, x544_freezeSfx, x528_freezeIceTxtr);
|
||||
break;
|
||||
case EWeaponType::Wave:
|
||||
if (x52c_visorElectric) {
|
||||
MakeBillboardEffect({}, {x52c_visorElectric}, "PlasmaElectricFx"sv, mgr);
|
||||
CSfxManager::SfxStart(x546_electricSfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
||||
mgr.GetPlayer().SetHudDisable(3.f, 0.5f, 2.5f);
|
||||
mgr.GetPlayer().SetOrbitRequestForTarget(mgr.GetPlayer().GetOrbitTargetId(),
|
||||
CPlayer::EPlayerOrbitRequest::ActivateOrbitSource, mgr);
|
||||
mgr.GetPlayerState()->GetStaticInterference().AddSource(GetUniqueId(), 0.2f, 3.f);
|
||||
}
|
||||
break;
|
||||
case EWeaponType::Plasma:
|
||||
if (x538_visorParticle)
|
||||
MakeBillboardEffect({x538_visorParticle}, {}, "PlasmaVisorFx"sv, mgr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
x4dc_playerEffectPulseTimer = 0.75f;
|
||||
}
|
||||
if (x548_29_activePlayerPhazon) {
|
||||
CDamageInfo scaledDamage(x498_phazonDamage, dt);
|
||||
mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), xec_ownerId, scaledDamage, xf8_filter,
|
||||
zeus::CVector3f::skZero);
|
||||
x4e4_playerDamageTimer += dt;
|
||||
if (x4e4_playerDamageTimer >= x4e0_playerDamageDuration) {
|
||||
mgr.GetPlayer().DecrementPhazon();
|
||||
x4e4_playerDamageTimer = 0.f;
|
||||
x548_29_activePlayerPhazon = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::UpdateFx(const zeus::CTransform& xf, float dt, CStateManager& mgr) {
|
||||
if (!GetActive())
|
||||
return;
|
||||
|
||||
x548_27_texturesLoaded = x4e8_texture.IsLoaded() && x4f4_glowTexture.IsLoaded();
|
||||
CauseDamage(x4b4_expansionState == EExpansionState::Attack || x4b4_expansionState == EExpansionState::Sustain);
|
||||
CBeamProjectile::UpdateFx(xf, dt, mgr);
|
||||
UpdatePlayerEffects(dt, mgr);
|
||||
if (x478_beamAttributes & 0x1) {
|
||||
for (int i = 7; i > 0; --i)
|
||||
PointCache()[i] = PointCache()[i - 1];
|
||||
PointCache()[0] = GetCurrentPos();
|
||||
}
|
||||
if (x518_contactGen) {
|
||||
x4d4_contactPulseTimer -= dt;
|
||||
if ((GetDamageType() != EDamageType::None ? x548_25_enableEnergyPulse : false) && x4d4_contactPulseTimer <= 0.f) {
|
||||
x518_contactGen->SetOrientation(zeus::lookAt(zeus::CVector3f::skZero, GetSurfaceNormal()));
|
||||
x518_contactGen->SetTranslation(GetSurfaceNormal() * 0.001f + GetCurrentPos());
|
||||
x518_contactGen->SetParticleEmission(true);
|
||||
x4d4_contactPulseTimer = 1.f / 16.f;
|
||||
} else {
|
||||
x518_contactGen->SetParticleEmission(false);
|
||||
}
|
||||
x518_contactGen->Update(dt);
|
||||
}
|
||||
float modulation = UpdateBeamState(dt, mgr);
|
||||
UpdateEnergyPulse(dt);
|
||||
x4c8_beamAngle += 720.f * dt;
|
||||
if (x4c8_beamAngle > 360.f)
|
||||
x4c8_beamAngle = 0.f;
|
||||
x4b8_beamWidth = modulation * GetMaxRadius();
|
||||
x4c4_expansion = modulation;
|
||||
x4cc_energyPulseStartY += dt * x480_pulseSpeed;
|
||||
if (x4cc_energyPulseStartY > 5.f)
|
||||
x4cc_energyPulseStartY = 0.f;
|
||||
UpdateLights(modulation, dt, mgr);
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::Fire(const zeus::CTransform& xf, CStateManager& mgr, bool b) {
|
||||
SetActive(true);
|
||||
SetLightsActive(true, mgr);
|
||||
x548_25_enableEnergyPulse = true;
|
||||
x548_26_firing = true;
|
||||
x548_24_ = b;
|
||||
x4b4_expansionState = EExpansionState::Attack;
|
||||
if (x478_beamAttributes & 0x1)
|
||||
std::fill(PointCache().begin(), PointCache().end(), xf.origin);
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::Touch(CActor& other, CStateManager& mgr) {
|
||||
// Empty
|
||||
}
|
||||
|
||||
bool CPlasmaProjectile::CanRenderUnsorted(const CStateManager& mgr) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const {
|
||||
if (GetActive()) {
|
||||
g_Renderer->AddParticleGen(*x518_contactGen);
|
||||
if (x478_beamAttributes & 0x2) {
|
||||
g_Renderer->AddParticleGen(*x51c_pulseGen);
|
||||
}
|
||||
}
|
||||
EnsureRendered(mgr, GetBeamTransform().origin, GetSortingBounds(mgr));
|
||||
}
|
||||
|
||||
void CPlasmaProjectile::Render(const CStateManager& mgr) const {
|
||||
if (!GetActive())
|
||||
return;
|
||||
|
||||
zeus::CTransform xf = GetBeamTransform();
|
||||
|
||||
// Subtractive blending for xray
|
||||
s32 flags = mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay ? 0x10 : 0x0;
|
||||
|
||||
if ((x478_beamAttributes & 0x1) == 0)
|
||||
xf.origin += mgr.GetCameraManager()->GetGlobalCameraTranslation(mgr);
|
||||
|
||||
// Z test, no write
|
||||
|
||||
if ((x478_beamAttributes & 0x1) && x548_25_enableEnergyPulse && x4b4_expansionState != EExpansionState::Attack)
|
||||
RenderMotionBlur();
|
||||
|
||||
// Pass1: alpha-controlled additive
|
||||
CGraphics::SetModelMatrix(xf);
|
||||
RenderBeam(3, 0.25f * x4b8_beamWidth, zeus::CColor(1.f, 0.3f), flags | 0x4, m_renderObjs->m_beamStrip1);
|
||||
|
||||
// Pass2: textured
|
||||
CGraphics::SetModelMatrix(xf * zeus::CTransform::RotateY(zeus::degToRad(x4c8_beamAngle)));
|
||||
RenderBeam(4, 0.5f * x4b8_beamWidth, x490_innerColor, flags | 0x1, m_renderObjs->m_beamStrip2);
|
||||
|
||||
// Pass3: textured | length-controlled UVY
|
||||
CGraphics::SetModelMatrix(xf * zeus::CTransform::RotateY(zeus::degToRad(-x4c8_beamAngle)));
|
||||
RenderBeam(8, x4b8_beamWidth, x494_outerColor, flags | 0x3, m_renderObjs->m_beamStrip3);
|
||||
|
||||
// Pass4: textured | alpha-controlled additive | glow texture
|
||||
CGraphics::SetModelMatrix(xf);
|
||||
RenderBeam(6, 1.25f * x4b8_beamWidth, x494_outerColor, flags | 0xd, m_renderObjs->m_beamStrip4);
|
||||
}
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -3,18 +3,111 @@
|
|||
#include "Weapon/CBeamProjectile.hpp"
|
||||
#include "Weapon/CBeamInfo.hpp"
|
||||
#include "World/CDamageInfo.hpp"
|
||||
#include "Graphics/Shaders/CColoredStripShader.hpp"
|
||||
|
||||
namespace urde {
|
||||
class CPlasmaProjectile : public CBeamProjectile {
|
||||
public:
|
||||
struct PlayerEffectResoures : rstl::reserved_vector<u64, 8> {
|
||||
PlayerEffectResoures(u64 a = UINT64_MAX, u64 b = UINT64_MAX, u64 c = UINT64_MAX, u64 d = UINT64_MAX,
|
||||
u64 e = UINT64_MAX, u64 f = UINT64_MAX, u64 g = UINT64_MAX, u64 h = UINT64_MAX)
|
||||
: rstl::reserved_vector<u64, 8>({a, b, c, d, e, f, g, h}) {}
|
||||
};
|
||||
private:
|
||||
std::vector<TUniqueId> x468_lights;
|
||||
s32 x478_beamAttributes;
|
||||
float x47c_lifeTime;
|
||||
float x480_pulseSpeed;
|
||||
float x484_shutdownTime;
|
||||
float x488_expansionSpeed;
|
||||
float x48c_;
|
||||
zeus::CColor x490_innerColor;
|
||||
zeus::CColor x494_outerColor;
|
||||
CDamageInfo x498_phazonDamage;
|
||||
enum class EExpansionState {
|
||||
Inactive,
|
||||
Attack,
|
||||
Sustain,
|
||||
Release,
|
||||
Done
|
||||
};
|
||||
EExpansionState x4b4_expansionState = EExpansionState::Inactive;
|
||||
float x4b8_beamWidth = 0.f;
|
||||
float x4bc_lifeTimer = 0.f;
|
||||
float x4c0_expansionT = 0.f;
|
||||
float x4c4_expansion = 0.f;
|
||||
float x4c8_beamAngle = 0.f;
|
||||
float x4cc_energyPulseStartY = 0.f;
|
||||
float x4d0_shutdownTimer = 0.f;
|
||||
float x4d4_contactPulseTimer = 0.f;
|
||||
float x4d8_energyPulseTimer = 0.f;
|
||||
float x4dc_playerEffectPulseTimer = 0.f;
|
||||
float x4e0_playerDamageDuration = 0.f;
|
||||
float x4e4_playerDamageTimer = 0.f;
|
||||
TLockedToken<CTexture> x4e8_texture;
|
||||
TLockedToken<CTexture> x4f4_glowTexture;
|
||||
TCachedToken<CGenDescription> x500_contactFxDesc;
|
||||
TCachedToken<CGenDescription> x50c_pulseFxDesc;
|
||||
std::unique_ptr<CElementGen> x518_contactGen;
|
||||
std::unique_ptr<CElementGen> x51c_pulseGen;
|
||||
std::unique_ptr<CElementGen> x520_weaponGen;
|
||||
CAssetId x524_freezeSteamTxtr;
|
||||
CAssetId x528_freezeIceTxtr;
|
||||
TToken<CElectricDescription> x52c_visorElectric; // Used to be optional
|
||||
TToken<CGenDescription> x538_visorParticle; // Used to be optional
|
||||
u16 x544_freezeSfx;
|
||||
u16 x546_electricSfx;
|
||||
union {
|
||||
struct {
|
||||
bool x548_24_ : 1;
|
||||
bool x548_25_enableEnergyPulse : 1;
|
||||
bool x548_26_firing : 1;
|
||||
bool x548_27_texturesLoaded : 1;
|
||||
bool x548_28_drawOwnerFirst : 1;
|
||||
bool x548_29_activePlayerPhazon : 1;
|
||||
};
|
||||
u32 _dummy3 = 0;
|
||||
};
|
||||
|
||||
struct RenderObjects {
|
||||
CColoredStripShader m_beamStrip1;
|
||||
CColoredStripShader m_beamStrip2;
|
||||
CColoredStripShader m_beamStrip3;
|
||||
CColoredStripShader m_beamStrip4;
|
||||
CColoredStripShader m_motionBlurStrip;
|
||||
RenderObjects(boo::IGraphicsDataFactory::Context& ctx,
|
||||
boo::ObjToken<boo::ITexture> tex,
|
||||
boo::ObjToken<boo::ITexture> glowTex);
|
||||
};
|
||||
mutable std::optional<RenderObjects> m_renderObjs;
|
||||
|
||||
void SetLightsActive(bool active, CStateManager& mgr);
|
||||
void CreatePlasmaLights(u32 sourceId, const CLight& l, CStateManager& mgr);
|
||||
void DeletePlasmaLights(CStateManager& mgr);
|
||||
void UpdateLights(float expansion, float dt, CStateManager& mgr);
|
||||
void UpdateEnergyPulse(float dt);
|
||||
void RenderMotionBlur() const;
|
||||
void RenderBeam(s32 subdivs, float width, const zeus::CColor& color, s32 flags,
|
||||
CColoredStripShader& shader) const;
|
||||
float UpdateBeamState(float dt, CStateManager& mgr);
|
||||
void MakeBillboardEffect(const std::experimental::optional<TToken<CGenDescription>>& particle,
|
||||
const std::experimental::optional<TToken<CElectricDescription>>& electric,
|
||||
std::string_view name, CStateManager& mgr);
|
||||
void UpdatePlayerEffects(float dt, CStateManager& mgr);
|
||||
public:
|
||||
CPlasmaProjectile(const TToken<CWeaponDescription>& wDesc, std::string_view name, EWeaponType wType,
|
||||
const CBeamInfo& bInfo, const zeus::CTransform& xf, EMaterialTypes matType,
|
||||
const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner, u32 w1, bool b1,
|
||||
EProjectileAttrib attribs);
|
||||
const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner,
|
||||
const PlayerEffectResoures& res, bool growingBeam, EProjectileAttrib attribs);
|
||||
|
||||
void Accept(IVisitor& visitor);
|
||||
|
||||
void UpdateFx(const zeus::CTransform&, float, CStateManager&) {}
|
||||
void Fire(const zeus::CTransform&, CStateManager&, bool);
|
||||
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr);
|
||||
void ResetBeam(CStateManager& mgr, bool fullReset);
|
||||
void UpdateFx(const zeus::CTransform& xf, float dt, CStateManager& mgr);
|
||||
void Fire(const zeus::CTransform& xf, CStateManager& mgr, bool b);
|
||||
void Touch(CActor& other, CStateManager& mgr);
|
||||
bool CanRenderUnsorted(const CStateManager& mgr) const;
|
||||
void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const;
|
||||
void Render(const CStateManager& mgr) const;
|
||||
};
|
||||
} // namespace urde
|
||||
|
|
|
@ -304,7 +304,7 @@ void CPatterned::Think(float dt, CStateManager& mgr) {
|
|||
|
||||
x460_knockBackController.Update(thinkDt, mgr, *this);
|
||||
x4e4_latestPredictedTranslation = GetTranslation() + PredictMotion(thinkDt).x0_translation;
|
||||
x328_26_longJump = false;
|
||||
x328_26_solidCollision = false;
|
||||
if (x420_curDamageRemTime > 0.f)
|
||||
x420_curDamageRemTime -= dt;
|
||||
|
||||
|
@ -320,7 +320,7 @@ void CPatterned::Think(float dt, CStateManager& mgr) {
|
|||
|
||||
if (x3cc_playerLeashRadius != 0.f) {
|
||||
zeus::CVector3f diffVec = (GetTranslation() - mgr.GetPlayer().GetTranslation());
|
||||
if (diffVec.magSquared() > x3cc_playerLeashRadius)
|
||||
if (diffVec.magSquared() > x3cc_playerLeashRadius * x3cc_playerLeashRadius)
|
||||
x3d4_curPlayerLeashTime += dt;
|
||||
else
|
||||
x3d4_curPlayerLeashTime = 0.f;
|
||||
|
@ -333,6 +333,44 @@ void CPatterned::Think(float dt, CStateManager& mgr) {
|
|||
x2f8_waypointPauseRemTime -= dt;
|
||||
}
|
||||
|
||||
void CPatterned::CollidedWith(TUniqueId other, const CCollisionInfoList& list, CStateManager& mgr) {
|
||||
if (x420_curDamageRemTime <= 0.f) {
|
||||
if (TCastToPtr<CPlayer> player = mgr.ObjectById(other)) {
|
||||
bool jumpOnHead = player->GetTimeSinceJump() < 5.f && list.GetCount() != 0 &&
|
||||
list.Front().GetNormalLeft().z() > 0.707f;
|
||||
if (x400_25_alive || jumpOnHead) {
|
||||
CDamageInfo cDamage = GetContactDamage();
|
||||
if (!x400_25_alive || x450_bodyController->IsFrozen())
|
||||
cDamage.SetDamage(0.f);
|
||||
if (jumpOnHead) {
|
||||
mgr.ApplyDamage(GetUniqueId(), player->GetUniqueId(), GetUniqueId(), cDamage,
|
||||
CMaterialFilter::skPassEverything, -player->GetVelocity());
|
||||
player->ResetTimeSinceJump();
|
||||
} else if (x400_25_alive && !x450_bodyController->IsFrozen()) {
|
||||
mgr.ApplyDamage(GetUniqueId(), player->GetUniqueId(), GetUniqueId(), cDamage,
|
||||
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), zeus::CVector3f::skZero);
|
||||
}
|
||||
x420_curDamageRemTime = x424_damageWaitTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
static CMaterialList testList(EMaterialTypes::Solid, EMaterialTypes::Ceiling, EMaterialTypes::Wall,
|
||||
EMaterialTypes::Floor, EMaterialTypes::Character);
|
||||
for (const CCollisionInfo& info : list) {
|
||||
if (info.GetMaterialLeft().Intersection(testList)) {
|
||||
if (!info.GetMaterialLeft().HasMaterial(EMaterialTypes::Floor)) {
|
||||
if (!x310_moveVec.isZero() && info.GetNormalLeft().dot(x310_moveVec) >= 0.f)
|
||||
continue;
|
||||
} else if (!x400_31_isFlyer) {
|
||||
continue;
|
||||
}
|
||||
x328_26_solidCollision = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
CPhysicsActor::CollidedWith(other, list, mgr);
|
||||
}
|
||||
|
||||
void CPatterned::Touch(CActor& act, CStateManager& mgr) {
|
||||
if (!x400_25_alive)
|
||||
return;
|
||||
|
@ -604,8 +642,7 @@ bool CPatterned::Leash(CStateManager&, float arg) {
|
|||
bool ret = x3d4_curPlayerLeashTime > x3d0_playerLeashTime;
|
||||
if (ret) {
|
||||
float posToLeashMagSq = (x3a0_latestLeashPosition - GetTranslation()).magSquared();
|
||||
if (posToLeashMagSq > x3c8_leashRadius * x3c8_leashRadius)
|
||||
return true;
|
||||
return posToLeashMagSq > x3c8_leashRadius * x3c8_leashRadius;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -1586,7 +1623,7 @@ void CPatterned::ThinkAboutMove(float dt) {
|
|||
|
||||
switch (x3f8_moveState) {
|
||||
case EMoveState::Zero:
|
||||
if (!x328_26_longJump)
|
||||
if (!x328_26_solidCollision)
|
||||
break;
|
||||
case EMoveState::One:
|
||||
doMove = false;
|
||||
|
@ -1601,7 +1638,7 @@ void CPatterned::ThinkAboutMove(float dt) {
|
|||
x3f8_moveState = EMoveState::Three;
|
||||
case EMoveState::Three:
|
||||
doMove = true;
|
||||
if (!x328_26_longJump) {
|
||||
if (!x328_26_solidCollision) {
|
||||
x3f8_moveState = EMoveState::Zero;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ protected:
|
|||
struct {
|
||||
bool x328_24_inPosition : 1;
|
||||
bool x328_25_verticalMovement : 1;
|
||||
bool x328_26_longJump : 1;
|
||||
bool x328_26_solidCollision : 1;
|
||||
bool x328_27_onGround : 1;
|
||||
bool x328_28_prevOnGround : 1;
|
||||
bool x328_29_noPatternShagging : 1;
|
||||
|
@ -263,6 +263,7 @@ public:
|
|||
void PreRender(CStateManager&, const zeus::CFrustum&);
|
||||
void Render(const CStateManager& mgr) const;
|
||||
|
||||
void CollidedWith(TUniqueId, const CCollisionInfoList&, CStateManager& mgr);
|
||||
void Touch(CActor& act, CStateManager& mgr);
|
||||
std::experimental::optional<zeus::CAABox> GetTouchBounds() const;
|
||||
bool CanRenderUnsorted(const CStateManager& mgr) const;
|
||||
|
@ -373,7 +374,7 @@ public:
|
|||
void SetCoverPoint(CScriptCoverPoint* cp, TUniqueId& id);
|
||||
void ReleaseCoverPoint(CStateManager& mgr, TUniqueId& id);
|
||||
|
||||
bool CanLongJump() const { return x328_26_longJump; }
|
||||
bool MadeSolidCollision() const { return x328_26_solidCollision; }
|
||||
bool IsMakingBigStrike() const { return x402_28_isMakingBigStrike; }
|
||||
|
||||
// region Casting Functions
|
||||
|
|
|
@ -588,6 +588,8 @@ public:
|
|||
const std::vector<TUniqueId>& GetOnScreenOrbitObjects() const { return x354_onScreenOrbitObjects; }
|
||||
const std::vector<TUniqueId>& GetOffScreenOrbitObjects() const { return x364_offScreenOrbitObjects; }
|
||||
void SetPlayerHitWallDuringMove();
|
||||
float GetTimeSinceJump() const { return x2a8_timeSinceJump; }
|
||||
void ResetTimeSinceJump() { x2a8_timeSinceJump = 1000.f; }
|
||||
ESurfaceRestraints GetCurrentSurfaceRestraint() const { return x2ac_surfaceRestraint; }
|
||||
ESurfaceRestraints GetSurfaceRestraint() const {
|
||||
return x2b0_outOfWaterTicks == 2 ? GetCurrentSurfaceRestraint() : ESurfaceRestraints::Water;
|
||||
|
|
|
@ -35,7 +35,7 @@ void CScriptBeam::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CSt
|
|||
mgr.AddObject(new CPlasmaProjectile(xe8_weaponDescription, x10_name + "-Projectile",
|
||||
x138_damageInfo.GetWeaponMode().GetType(), xf4_beamInfo, x34_transform,
|
||||
EMaterialTypes::Projectile, x138_damageInfo, x8_uid, x4_areaId,
|
||||
x154_projectileId, 8, false, EProjectileAttrib::PlasmaProjectile));
|
||||
x154_projectileId, {}, false, EProjectileAttrib::PlasmaProjectile));
|
||||
} else if (msg == EScriptObjectMessage::Deleted) {
|
||||
}
|
||||
|
||||
|
|
|
@ -791,14 +791,14 @@ CEntity* ScriptLoader::LoadNewIntroBoss(CStateManager& mgr, CInputStream& in, in
|
|||
CActorParameters actParms = LoadActorParameters(in);
|
||||
|
||||
float f1 = in.readFloatBig();
|
||||
CAssetId w1(in);
|
||||
CAssetId projectile(in);
|
||||
|
||||
CDamageInfo dInfo(in);
|
||||
|
||||
CAssetId w2(in);
|
||||
CAssetId w3(in);
|
||||
CAssetId w4(in);
|
||||
CAssetId w5(in);
|
||||
CAssetId beamContactFxId(in);
|
||||
CAssetId beamPulseFxId(in);
|
||||
CAssetId beamTextureId(in);
|
||||
CAssetId beamGlowTextureId(in);
|
||||
|
||||
const CAnimationParameters& aParms = pInfo.GetAnimationParameters();
|
||||
FourCC animType = g_ResFactory->GetResourceTypeById(aParms.GetACSFile());
|
||||
|
@ -808,7 +808,7 @@ CEntity* ScriptLoader::LoadNewIntroBoss(CStateManager& mgr, CInputStream& in, in
|
|||
CAnimRes res(aParms.GetACSFile(), aParms.GetCharacter(), head.x40_scale, aParms.GetInitialAnimation(), true);
|
||||
|
||||
return new MP1::CNewIntroBoss(mgr.AllocateUniqueId(), head.x0_name, info, head.x10_transform, res, pInfo, actParms,
|
||||
f1, w1, dInfo, w2, w3, w4, w5);
|
||||
f1, projectile, dInfo, beamContactFxId, beamPulseFxId, beamTextureId, beamGlowTextureId);
|
||||
}
|
||||
|
||||
CEntity* ScriptLoader::LoadSpawnPoint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {
|
||||
|
|
|
@ -255,6 +255,14 @@ public:
|
|||
using const_reverse_iterator = typename base::const_reverse_iterator;
|
||||
reserved_vector() : x0_size(0) {}
|
||||
|
||||
template <size_t LN>
|
||||
reserved_vector(const T(&l)[LN])
|
||||
: x0_size(LN) {
|
||||
static_assert(LN <= N, "initializer array too large for reserved_vector");
|
||||
for (size_t i = 0; i < LN; ++i)
|
||||
::new (static_cast<void*>(std::addressof(_value(i)))) T(l[i]);
|
||||
}
|
||||
|
||||
reserved_vector(const reserved_vector& other) : x0_size(other.x0_size) {
|
||||
for (size_t i = 0; i < x0_size; ++i)
|
||||
::new (static_cast<void*>(std::addressof(_value(i)))) T(other._value(i));
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
#shader CColoredStripShader
|
||||
#attribute position4
|
||||
#attribute color
|
||||
#attribute uv4
|
||||
#srcfac srcalpha
|
||||
#dstfac invsrcalpha
|
||||
#primitive tristrips
|
||||
#depthtest lequal
|
||||
#depthwrite false
|
||||
#culling none
|
||||
|
||||
|
||||
#vertex glsl
|
||||
layout(location=0) in vec4 posIn;
|
||||
layout(location=1) in vec4 colorIn;
|
||||
layout(location=2) in vec4 uvIn;
|
||||
|
||||
UBINDING0 uniform ColoredQuadUniform
|
||||
{
|
||||
mat4 xf;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
struct VertToFrag
|
||||
{
|
||||
vec4 color;
|
||||
vec2 uv;
|
||||
};
|
||||
|
||||
SBINDING(0) out VertToFrag vtf;
|
||||
void main()
|
||||
{
|
||||
vtf.color = colorIn * color;
|
||||
vtf.uv = uvIn.xy;
|
||||
gl_Position = xf * vec4(posIn.xyz, 1.0);
|
||||
}
|
||||
|
||||
#fragment glsl
|
||||
struct VertToFrag
|
||||
{
|
||||
vec4 color;
|
||||
vec2 uv;
|
||||
};
|
||||
|
||||
SBINDING(0) in VertToFrag vtf;
|
||||
layout(location=0) out vec4 colorOut;
|
||||
TBINDING0 uniform sampler2D tex;
|
||||
void main()
|
||||
{
|
||||
colorOut = vtf.color * texture(tex, vtf.uv);
|
||||
}
|
||||
|
||||
|
||||
#vertex hlsl
|
||||
struct VertData
|
||||
{
|
||||
float4 posIn : POSITION;
|
||||
float4 colorIn : COLOR;
|
||||
float4 uvIn : UV;
|
||||
};
|
||||
|
||||
cbuffer ColoredQuadUniform : register(b0)
|
||||
{
|
||||
float4x4 xf;
|
||||
float4 color;
|
||||
};
|
||||
|
||||
struct VertToFrag
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
float4 color : COLOR;
|
||||
float2 uv : UV;
|
||||
};
|
||||
|
||||
VertToFrag main(in VertData v)
|
||||
{
|
||||
VertToFrag vtf;
|
||||
vtf.color = v.colorIn * color;
|
||||
vtf.uv = v.uvIn.xy;
|
||||
vtf.position = mul(xf, float4(v.posIn.xyz, 1.0));
|
||||
return vtf;
|
||||
}
|
||||
|
||||
#fragment hlsl
|
||||
SamplerState samp : register(s0);
|
||||
Texture2D tex0 : register(t0);
|
||||
struct VertToFrag
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
float4 color : COLOR;
|
||||
float2 uv : UV;
|
||||
};
|
||||
|
||||
float4 main(in VertToFrag vtf) : SV_Target0
|
||||
{
|
||||
return vtf.color * tex0.Sample(samp, vtf.uv);
|
||||
}
|
||||
|
||||
|
||||
#vertex metal
|
||||
struct VertData
|
||||
{
|
||||
float4 posIn [[ attribute(0) ]];
|
||||
float4 colorIn [[ attribute(1) ]];
|
||||
float4 uvIn [[ attribute(2) ]];
|
||||
};
|
||||
|
||||
struct ColoredQuadUniform
|
||||
{
|
||||
float4x4 xf;
|
||||
float4 color;
|
||||
};
|
||||
|
||||
struct VertToFrag
|
||||
{
|
||||
float4 position [[ position ]];
|
||||
float4 color;
|
||||
float2 uv;
|
||||
};
|
||||
|
||||
vertex VertToFrag vmain(VertData v [[ stage_in ]], constant ColoredQuadUniform& cqu [[ buffer(2) ]])
|
||||
{
|
||||
VertToFrag vtf;
|
||||
vtf.color = v.colorIn * cqu.color;
|
||||
vtf.uv = v.uvIn.xy;
|
||||
vtf.position = cqu.xf * float4(v.posIn.xyz, 1.0);
|
||||
return vtf;
|
||||
}
|
||||
|
||||
#fragment metal
|
||||
struct VertToFrag
|
||||
{
|
||||
float4 position [[ position ]];
|
||||
float4 color;
|
||||
float2 uv;
|
||||
};
|
||||
|
||||
fragment float4 fmain(VertToFrag vtf [[ stage_in ]],
|
||||
sampler samp [[ sampler(0) ]],
|
||||
texture2d<float> tex0 [[ texture(0) ]])
|
||||
{
|
||||
return vtf.color * tex0.sample(samp, vtf.uv);
|
||||
}
|
||||
|
||||
#shader CColoredStripShaderAdditive : CColoredStripShader
|
||||
#srcfac srcalpha
|
||||
#dstfac one
|
||||
|
||||
#shader CColoredStripShaderFullAdditive : CColoredStripShader
|
||||
#srcfac one
|
||||
#dstfac one
|
|
@ -7,6 +7,7 @@ include_directories(../hecl/include
|
|||
add_shader(CAABoxShader)
|
||||
add_shader(CCameraBlurFilter)
|
||||
add_shader(CColoredQuadFilter)
|
||||
add_shader(CColoredStripShader)
|
||||
add_shader(CDecalShaders)
|
||||
add_shader(CElementGenShaders)
|
||||
add_shader(CEnergyBarShader)
|
||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit cdba678eee605cf0aff96f1276bc3593fca0de2b
|
||||
Subproject commit d4a0f17336f19906a6c4f2ed83fd34945f017593
|
Loading…
Reference in New Issue