Work on CGameProjectile

This commit is contained in:
Jack Andersen 2018-02-08 21:12:26 -10:00
parent ae6797f24b
commit 083571e693
22 changed files with 446 additions and 43 deletions

View File

@ -1403,7 +1403,7 @@ void CStateManager::ApplyDamageToWorld(TUniqueId damager, const CActor& actor, c
g_GameState->SystemOptions().IncrementFrozenBallCount();
CHUDMemoParms info = {0.f, true, true, true};
MP1::CSamusHud::DisplayHudMemo(u"", info);
player->Stop(*this);
player->UnFreeze(*this);
}
else
{

View File

@ -84,7 +84,7 @@ int CCameraManager::AddCameraShaker(const CCameraShakeData& data, bool sfx)
void CCameraManager::EnterCinematic(CStateManager& mgr)
{
mgr.GetPlayer().GetPlayerGun()->CancelFiring(mgr);
mgr.GetPlayer().Stop(mgr);
mgr.GetPlayer().UnFreeze(mgr);
for (CEntity* ent : mgr.GetAllObjectList())
{

View File

@ -364,9 +364,15 @@ void CModelData::RenderUnsortedParts(EWhichModel which, const zeus::CTransform&
const auto& model = PickStaticModel(which);
if (lights)
{
lights->ActivateLights(*model);
}
else
model->ActivateLights({});
{
std::vector<CLight> useLights;
useLights.push_back(CLight::BuildLocalAmbient(zeus::CVector3f::skZero, x18_ambientColor));
model->ActivateLights(useLights);
}
model->DrawNormal(drawFlags, nullptr, nullptr);
// Set ambient to white
@ -390,9 +396,15 @@ void CModelData::Render(EWhichModel which, const zeus::CTransform& xf,
{
CSkinnedModel& model = PickAnimatedModel(which);
if (lights)
{
lights->ActivateLights(*model.GetModelInst());
}
else
model.GetModelInst()->ActivateLights({});
{
std::vector<CLight> useLights;
useLights.push_back(CLight::BuildLocalAmbient(zeus::CVector3f::skZero, x18_ambientColor));
model.GetModelInst()->ActivateLights(useLights);
}
x10_animData->Render(model, drawFlags, {}, nullptr);
}
@ -400,9 +412,15 @@ void CModelData::Render(EWhichModel which, const zeus::CTransform& xf,
{
const auto& model = PickStaticModel(which);
if (lights)
{
lights->ActivateLights(*model);
}
else
model->ActivateLights({});
{
std::vector<CLight> useLights;
useLights.push_back(CLight::BuildLocalAmbient(zeus::CVector3f::skZero, x18_ambientColor));
model->ActivateLights(useLights);
}
if (x14_24_renderSorted)
model->DrawAlpha(drawFlags, nullptr, nullptr);

View File

@ -34,7 +34,7 @@ static TUniqueId _initializeLight(const std::weak_ptr<CParticleGen>& system, CSt
stateMgr.AddObject(
new CGameLight(ret, areaId, false, "ParticleLight",
zeus::CTransform(systemRef->GetOrientation().buildMatrix3f(), systemRef->GetTranslation()),
kInvalidUniqueId, systemRef->GetLight(), lightId, 0, 0.f));
kInvalidUniqueId, systemRef->GetLight(), u32(lightId), 0, 0.f));
}
return ret;
}

View File

@ -25,7 +25,7 @@ struct CModelFlags
{
u8 x0_blendMode = 0; /* >6: additive, >4: blend, else opaque */
u8 x1_matSetIdx = 0;
EExtendedShader m_extendedShader = EExtendedShader::Flat;
EExtendedShader m_extendedShader = EExtendedShader::Lighting;
bool m_noCull = false;
bool m_noZWrite = false;
u16 x2_flags = 0; /* Flags */
@ -35,7 +35,7 @@ struct CModelFlags
CModelFlags() = default;
CModelFlags(u8 blendMode, u8 shadIdx, u16 flags, const zeus::CColor& col)
: x0_blendMode(blendMode), x1_matSetIdx(shadIdx), m_extendedShader(EExtendedShader::Lighting),
: x0_blendMode(blendMode), x1_matSetIdx(shadIdx),
x2_flags(flags), x4_color(col)
{
/* Blend mode will override this if the surface's original material is opaque */

View File

@ -8,7 +8,7 @@ std::experimental::optional<CModelShaders> CModelShaders::g_ModelShaders;
void CModelShaders::LightingUniform::ActivateLights(const std::vector<CLight>& lts)
{
ambient = zeus::CColor::skBlack;
ambient = zeus::CColor::skClear;
size_t curLight = 0;
for (const CLight& light : lts)

View File

@ -1,27 +1,69 @@
#include "Weapon/CGameProjectile.hpp"
#include "Graphics/CLight.hpp"
#include "World/CGameLight.hpp"
#include "CStateManager.hpp"
#include "TCastTo.hpp"
#include "World/CPlayer.hpp"
#include "World/CHUDBillboardEffect.hpp"
#include "World/CWallCrawlerSwarm.hpp"
#include "World/CScriptDoor.hpp"
#include "Collision/CInternalRayCastStructure.hpp"
namespace urde
{
CGameProjectile::CGameProjectile(bool active, const TToken<CWeaponDescription>&, std::string_view name,
CGameProjectile::CGameProjectile(bool active, const TToken<CWeaponDescription>& wDesc, std::string_view name,
EWeaponType wType, const zeus::CTransform& xf, EMaterialTypes matType,
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)
const rstl::optional_object<TLockedToken<CGenDescription>>& visorParticle,
u16 visorSfx, bool sendCollideMsg)
: CWeapon(uid, aid, active, owner, wType, name, xf,
CMaterialFilter::MakeIncludeExclude(
{EMaterialTypes::NonSolidDamageable, matType},
{EMaterialTypes::Projectile, EMaterialTypes::ProjectilePassthrough, matType, EMaterialTypes::Solid}),
CMaterialList(), dInfo, attribs | GetBeamAttribType(wType), CModelData::CModelDataNull())
CMaterialList(), dInfo, attribs | GetBeamAttribType(wType), CModelData::CModelDataNull()),
x158_visorParticle(visorParticle), x168_visorSfx(visorSfx), x170_projectile(wDesc, xf.origin, xf.basis, scale,
(attribs & EProjectileAttrib::Sixteen) != EProjectileAttrib::None), x298_(xf.origin),
x2a4_((xe8_projectileAttribs & EProjectileAttrib::Ten) == EProjectileAttrib::Ten ? 0.25f : 0.1f),
x2c0_homingTargetId(homingTarget), x2cc_wpscId(wDesc.GetObjectTag()->id)
{
x2e4_24_ = true;
x2e4_25_ = underwater;
x2e4_26_waterUpdate = underwater;
x2e4_27_inWater = underwater;
x2e4_28_sendProjectileCollideMsg = sendCollideMsg;
}
void CGameProjectile::Accept(urde::IVisitor& visitor) { visitor.Visit(this); }
void CGameProjectile::ResolveCollisionWithActor(const CRayCastResult& res, CActor& act, CStateManager& mgr)
{
zeus::CVector3f revDir = -x34_transform.basis[1].normalized();
if (TCastToPtr<CPlayer>(act))
{
if (x158_visorParticle && mgr.GetPlayer().GetCameraState() == CPlayer::EPlayerCameraState::FirstPerson)
{
if (zeus::radToDeg(
std::acos(mgr.GetCameraManager()->GetCurrentCameraTransform(mgr).
basis[1].normalized().dot(revDir))) <= 45.f)
{
/* Hit us head on! Draw Billboard! */
std::experimental::optional<TToken<CGenDescription>> bb = {*x158_visorParticle};
CHUDBillboardEffect* effect = new CHUDBillboardEffect(bb, {},
mgr.AllocateUniqueId(), true, "VisorAcid",
CHUDBillboardEffect::GetNearClipDistance(mgr),
CHUDBillboardEffect::GetScaleForPOV(mgr),
zeus::CColor::skWhite, zeus::CVector3f::skOne,
zeus::CVector3f::skZero);
mgr.AddObject(effect);
CSfxManager::SfxStart(x168_visorSfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
if (x2e4_28_sendProjectileCollideMsg)
mgr.SendScriptMsg(&mgr.GetPlayer(), GetUniqueId(), EScriptObjectMessage::ProjectileCollide);
}
}
}
}
void CGameProjectile::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId /*uid*/, CStateManager& mgr)
{
if (msg == EScriptObjectMessage::AddSplashInhabitant)
@ -77,11 +119,254 @@ void CGameProjectile::CreateProjectileLight(std::string_view name, const CLight&
DeleteProjectileLight(mgr);
x2c8_projectileLight = mgr.AllocateUniqueId();
mgr.AddObject(new CGameLight(x2c8_projectileLight, GetAreaId(), GetActive(), name, GetTransform(), GetUniqueId(),
light, x2cc_, 0, 0.f));
light, u32(x2cc_wpscId.Value()), 0, 0.f));
}
void CGameProjectile::Chase(float dt, CStateManager& mgr)
{
if (!x170_projectile.IsProjectileActive() ||
x2c0_homingTargetId == kInvalidUniqueId)
return;
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(x2c0_homingTargetId))
{
if (!act->GetMaterialList().HasMaterial(EMaterialTypes::Target) &&
!act->GetMaterialList().HasMaterial(EMaterialTypes::Player))
{
x2c0_homingTargetId = kInvalidUniqueId;
}
else
{
zeus::CVector3f homingPos = act->GetHomingPosition(mgr, 0.f);
TCastToConstPtr<CWallCrawlerSwarm> swarm = act.GetPtr();
if (swarm)
{
int lockOnId = swarm->GetCurrentLockOnId();
if (swarm->GetLockOnLocationValid(lockOnId))
{
homingPos = swarm->GetLockOnLocation(lockOnId);
}
else
{
x2c0_homingTargetId = kInvalidUniqueId;
return;
}
}
zeus::CVector3f projToPos = homingPos - x170_projectile.GetTranslation();
if (x2e0_minHomingDist > 0.f && projToPos.magnitude() < x2e0_minHomingDist)
{
x2c0_homingTargetId = kInvalidUniqueId;
return;
}
if (!swarm && !TCastToConstPtr<CPhysicsActor>(act.GetPtr()))
if (auto tb = act->GetTouchBounds())
projToPos.z += (tb->max.z - tb->min.z) * 0.5f;
zeus::CQuaternion qDelta =
zeus::CQuaternion::shortestRotationArc(x170_projectile.GetTransform().basis[1], projToPos);
float wThres = qDelta.w * qDelta.w * 2.f - 1.f;
if (wThres > 0.99f)
return;
float turnRate;
if (x2e4_26_waterUpdate)
turnRate = x170_projectile.GetMaxTurnRate() * 0.5f;
else
turnRate = x170_projectile.GetMaxTurnRate();
float maxTurnDelta = zeus::degToRad(turnRate * dt);
float turnDelta = std::acos(wThres);
if (maxTurnDelta < turnDelta)
{
/* Clamp quat to max delta */
qDelta = zeus::CQuaternion(std::cos(maxTurnDelta * 0.5f),
(std::sin(maxTurnDelta * 0.5f) / std::sin(turnDelta * 0.5f)) * qDelta.getImaginary());
}
zeus::CTransform xf = qDelta.toTransform() * x170_projectile.GetTransform();
xf.orthonormalize();
x170_projectile.SetWorldSpaceOrientation(xf);
}
}
}
void CGameProjectile::UpdateHoming(float dt, CStateManager& mgr)
{
if (!x2e4_24_ || x2c0_homingTargetId == kInvalidUniqueId || x2a8_homingDt <= 0.f)
return;
x2b0_targetHomingTime += dt;
while (x2b0_targetHomingTime >= x2b8_curHomingTime)
{
Chase(x2a8_homingDt, mgr);
x2b8_curHomingTime += x2a8_homingDt;
}
}
void CGameProjectile::UpdateProjectileMovement(float dt, CStateManager& mgr)
{
float useDt = dt;
if (x2e4_26_waterUpdate)
useDt = 37.5f * dt * dt;
x298_ = x34_transform.origin;
x170_projectile.Update(useDt);
SetTransform(x170_projectile.GetTransform());
SetTranslation(x170_projectile.GetTranslation());
UpdateHoming(dt, mgr);
}
CRayCastResult
CGameProjectile::DoCollisionCheck(TUniqueId& idOut, CStateManager& mgr)
{
CRayCastResult res;
if (x2e4_24_)
{
zeus::CVector3f posDelta = x34_transform.origin - x298_;
rstl::reserved_vector<TUniqueId, 1024> nearList;
mgr.BuildNearList(nearList, GetProjectileBounds(),
CMaterialFilter::MakeExclude(EMaterialTypes::ProjectilePassthrough), this);
res = RayCollisionCheckWithWorld(idOut, x298_, x34_transform.origin,
posDelta.magnitude(), nearList, mgr);
}
return res;
}
void CGameProjectile::ApplyDamageToActors(CStateManager& mgr, const CDamageInfo& dInfo)
{
if (x2c6_ != kInvalidUniqueId)
{
if (TCastToPtr<CActor> act = mgr.ObjectById(x2c6_))
{
mgr.ApplyDamage(GetUniqueId(), act->GetUniqueId(), xec_ownerId, dInfo, xf8_filter, x34_transform.basis[1]);
if ((xe8_projectileAttribs & EProjectileAttrib::PlayerUnFreeze) == EProjectileAttrib::PlayerUnFreeze &&
mgr.GetPlayer().GetUniqueId() == act->GetUniqueId() && mgr.GetPlayer().GetFrozenState())
mgr.GetPlayer().UnFreeze(mgr);
}
x2c6_ = kInvalidUniqueId;
}
for (CProjectileTouchResult& res : x2d0_touchResults)
{
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(res.GetActorId()))
{
mgr.ApplyDamage(GetUniqueId(), act->GetUniqueId(), xec_ownerId, dInfo, xf8_filter, x34_transform.basis[1]);
if ((xe8_projectileAttribs & EProjectileAttrib::PlayerUnFreeze) == EProjectileAttrib::PlayerUnFreeze &&
mgr.GetPlayer().GetUniqueId() == act->GetUniqueId() && mgr.GetPlayer().GetFrozenState())
mgr.GetPlayer().UnFreeze(mgr);
}
}
x2d0_touchResults.clear();
}
void CGameProjectile::FluidFxThink(EFluidState state, CScriptWater& water, CStateManager& mgr)
{
if (x170_projectile.GetWeaponDescription()->xa6_SWTR)
CWeapon::FluidFXThink(state, water, mgr);
}
CRayCastResult
CGameProjectile::RayCollisionCheckWithWorld(TUniqueId& idOut, const zeus::CVector3f& start,
const zeus::CVector3f& end, float mag,
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
CStateManager& mgr)
{
x2d0_touchResults.clear();
idOut = kInvalidUniqueId;
x2c6_ = kInvalidUniqueId;
CRayCastResult res;
zeus::CVector3f delta = end - start;
if (!delta.canBeNormalized())
return res;
float bestMag = mag;
zeus::CVector3f dir = delta.normalized();
CRayCastResult res2 = mgr.RayStaticIntersection(start, dir, mag, xf8_filter);
if (res2.IsValid())
{
bestMag = res2.GetT();
res = res2;
}
for (TUniqueId id : nearList)
{
if (CActor* ent = static_cast<CActor*>(mgr.ObjectById(id)))
{
CProjectileTouchResult tRes = CanCollideWith(*ent, mgr);
if (tRes.GetActorId() == kInvalidUniqueId)
continue;
if (tRes.HasRayCastResult())
{
if (tRes.GetRayCastResult().GetT() < bestMag)
{
ent->Touch(*this, mgr);
bestMag = tRes.GetRayCastResult().GetT();
res = tRes.GetRayCastResult();
x2c6_ = idOut = tRes.GetActorId();
}
}
else
{
auto tb = ent->GetTouchBounds();
CGameProjectile* projObj = nullptr;
if (TCastToPtr<CScriptDoor> door = ent)
{
tb = door->GetProjectileBounds();
}
else if (TCastToPtr<CGameProjectile> proj = ent)
{
tb.emplace(proj->GetProjectileBounds());
projObj = proj.GetPtr();
}
if (!tb)
continue;
CCollidableAABox prim(*tb, ent->GetMaterialList());
CRayCastResult res3 =
prim.CastRayInternal(CInternalRayCastStructure(start, dir, mag, {},
CMaterialFilter::skPassEverything));
if (res3.IsValid())
{
if (res3.GetT() < bestMag)
{
bestMag = res3.GetT();
res = res3;
x2c6_ = idOut = tRes.GetActorId();
}
}
else if (tb->pointInside(start) || (projObj && projObj->GetProjectileBounds().intersects(*tb)))
{
x2c6_ = idOut = ent->GetUniqueId();
zeus::CUnitVector3f norm(-dir);
res = CRayCastResult(0.f, start, {norm, norm.dot(start)}, ent->GetMaterialList());
break;
}
}
}
}
if (x2e4_27_inWater && idOut == kInvalidUniqueId)
x2e4_27_inWater = false;
return res;
}
CProjectileTouchResult CGameProjectile::CanCollideWith(CActor& act, CStateManager& mgr)
{
return {{}, {}};
}
zeus::CAABox CGameProjectile::GetProjectileBounds() const
{
return {};
}
}

View File

@ -8,17 +8,43 @@
#include "RetroTypes.hpp"
#include "CToken.hpp"
#include "Weapon/CProjectileWeapon.hpp"
#include "Collision/CRayCastResult.hpp"
namespace urde
{
class CGenDescription;
class CWeaponDescription;
class CProjectileTouchResult
{
TUniqueId x0_id;
rstl::optional_object<CRayCastResult> x4_result;
public:
CProjectileTouchResult(TUniqueId id, const rstl::optional_object<CRayCastResult>& result)
: x0_id(id), x4_result(result) {}
TUniqueId GetActorId() const { return x0_id; }
bool HasRayCastResult() const { return x4_result.operator bool(); }
const CRayCastResult& GetRayCastResult() const { return *x4_result; }
};
class CGameProjectile : public CWeapon
{
//CProjectileWeapon x170_;
rstl::optional_object<TLockedToken<CGenDescription>> x158_visorParticle;
u16 x168_visorSfx;
CProjectileWeapon x170_projectile;
zeus::CVector3f x298_;
float x2a4_;
float x2a8_homingDt = 0.03f;
double x2b0_targetHomingTime = 0.0;
double x2b8_curHomingTime = x2a8_homingDt;
TUniqueId x2c0_homingTargetId;
TUniqueId x2c8_projectileLight;
u32 x2cc_;
TUniqueId x2c2_ = kInvalidUniqueId;
TUniqueId x2c4_ = kInvalidUniqueId;
TUniqueId x2c6_ = kInvalidUniqueId;
TUniqueId x2c8_projectileLight = kInvalidUniqueId;
CAssetId x2cc_wpscId;
std::vector<CProjectileTouchResult> x2d0_touchResults;
float x2e0_minHomingDist = 0.f;
union
{
struct
@ -27,7 +53,7 @@ class CGameProjectile : public CWeapon
bool x2e4_25_ : 1;
bool x2e4_26_waterUpdate : 1;
bool x2e4_27_inWater : 1;
bool x2e4_28_ : 1;
bool x2e4_28_sendProjectileCollideMsg : 1;
};
};
public:
@ -35,14 +61,27 @@ public:
EWeaponType wType, const zeus::CTransform& xf, EMaterialTypes matType,
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);
const rstl::optional_object<TLockedToken<CGenDescription>>& visorParticle,
u16 visorSfx, bool sendCollideMsg);
virtual void Accept(IVisitor &visitor);
virtual void ResolveCollisionWithActor(const CRayCastResult& res, CActor& act, CStateManager& mgr);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager &);
static EProjectileAttrib GetBeamAttribType(EWeaponType wType);
void DeleteProjectileLight(CStateManager&);
void CreateProjectileLight(std::string_view, const CLight&, CStateManager&);
void Chase(float, CStateManager&);
void Chase(float dt, CStateManager& mgr);
void UpdateHoming(float dt, CStateManager& mgr);
void UpdateProjectileMovement(float dt, CStateManager& mgr);
CRayCastResult DoCollisionCheck(TUniqueId& idOut, CStateManager& mgr);
void ApplyDamageToActors(CStateManager& mgr, const CDamageInfo& dInfo);
void FluidFxThink(EFluidState state, CScriptWater& water, CStateManager& mgr);
CRayCastResult RayCollisionCheckWithWorld(TUniqueId& idOut, const zeus::CVector3f& start,
const zeus::CVector3f& end, float mag,
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
CStateManager& mgr);
CProjectileTouchResult CanCollideWith(CActor& act, CStateManager& mgr);
zeus::CAABox GetProjectileBounds() const;
TUniqueId GetHomingTargetId() const { return x2c0_homingTargetId; }
};
}

View File

@ -11,4 +11,39 @@ CProjectileWeapon::CProjectileWeapon(const TToken<CWeaponDescription>& wDesc, co
{
}
zeus::CTransform CProjectileWeapon::GetTransform() const
{
return x14_localToWorldXf * x44_localXf;
}
zeus::CVector3f CProjectileWeapon::GetTranslation() const
{
return x14_localToWorldXf * (x44_localXf * x8c_ + x80_) + x74_;
}
void CProjectileWeapon::RenderParticles() const
{
}
void CProjectileWeapon::Update(float dt)
{
}
void CProjectileWeapon::UpdateParticleFx()
{
}
void CProjectileWeapon::UpdateChildParticleSystems(float dt)
{
}
void CProjectileWeapon::SetWorldSpaceOrientation(const zeus::CTransform& xf)
{
x44_localXf = x14_localToWorldXf.inverse() * xf;
}
}

View File

@ -19,8 +19,8 @@ class CProjectileWeapon
static u16 g_GlobalSeed;
TLockedToken<CWeaponDescription> x4_weaponDesc;
CRandom16 x10_random;
zeus::CTransform x14_;
zeus::CTransform x44_;
zeus::CTransform x14_localToWorldXf;
zeus::CTransform x44_localXf;
zeus::CVector3f x74_ = zeus::CVector3f::skZero;
zeus::CVector3f x80_ = zeus::CVector3f::skZero;
zeus::CVector3f x8c_ = zeus::CVector3f::skZero;
@ -31,7 +31,7 @@ class CProjectileWeapon
zeus::CColor xc8_ = zeus::CColor::skWhite;
double xd0_ = 0.0;
double xd8_ = 0.0;
float xe0_;
float xe0_maxTurnRate;
u32 xe4_;
u32 xe8_lifetime = 0x7FFFFF;
u32 xec_ = 0;
@ -50,7 +50,7 @@ class CProjectileWeapon
{
struct
{
bool x124_24_ : 1;
bool x124_24_active : 1;
bool x124_25_ : 1;
bool x124_26_ap11 : 1;
bool x124_27_ap21 : 1;
@ -62,12 +62,20 @@ class CProjectileWeapon
};
public:
CProjectileWeapon(const TToken<CWeaponDescription>& wDesc, const zeus::CVector3f&, const zeus::CTransform&,
const zeus::CVector3f&, s32);
void GetTransform();
void Update(float);
CProjectileWeapon(const TToken<CWeaponDescription>& wDesc, const zeus::CVector3f& pos,
const zeus::CTransform& orient, const zeus::CVector3f& scale, s32);
virtual ~CProjectileWeapon() = default;
bool IsProjectileActive() const { return x124_24_active; }
virtual zeus::CTransform GetTransform() const;
virtual zeus::CVector3f GetTranslation() const;
float GetMaxTurnRate() const { return xe0_maxTurnRate; }
TLockedToken<CWeaponDescription> GetWeaponDescription() const { return x4_weaponDesc; }
virtual void RenderParticles() const;
virtual void Update(float);
void UpdateParticleFx();
void UpdateChildParticleSystems(float);
void SetWorldSpaceOrientation(const zeus::CTransform& xf);
void SetRelativeOrientation(const zeus::CTransform& xf) { x44_localXf = xf; }
static void SetGlobalSeed(u16 seed) { g_GlobalSeed = seed; }
};
}

View File

@ -24,14 +24,17 @@ public:
ComboShot = (1 << 7),
Bombs = (1 << 8),
PowerBombs = (1 << 9),
Ten = (1 << 10),
ArmCannon = (1 << 11),
BigStrike = (1 << 12),
DamageFalloff = (1 << 13),
StaticInterference = (1 << 14),
PlayerUnFreeze = (1 << 15),
Sixteen = (1 << 16),
KeepInCinematic = (1 << 17),
};
private:
protected:
EProjectileAttrib xe8_projectileAttribs;
TUniqueId xec_ownerId;
EWeaponType xf0_weaponType;

View File

@ -37,7 +37,7 @@ CActor::CActor(TUniqueId uid, bool active, std::string_view name, const CEntityI
x90_actorLights = mData.IsNull() ? std::unique_ptr<CActorLights>() : params.x0_lightParms.MakeActorLights();
if (mData.x10_animData || mData.x1c_normalModel)
x64_modelData = std::make_unique<CModelData>(std::move(mData));
xd0_thermalMag = params.x64_;
xd0_thermalMag = params.x64_thermalMag;
xd8_nonLoopingSfxHandles.resize(2);
xe4_27_notInSortedLists = true;
xe4_28_ = true;

View File

@ -30,7 +30,7 @@ class CActorParameters
};
float x5c_ = 0.f;
float x60_ = 0.f;
float x64_ = 0.f;
float x64_thermalMag = 0.f;
public:
CActorParameters() : x58_24_(true), x58_25_thermalHeat(false), x58_26_(false), x58_27_noSortThermal(false) {}

View File

@ -7,10 +7,10 @@ namespace urde
{
CGameLight::CGameLight(TUniqueId uid, TAreaId aid, bool active, std::string_view name, const zeus::CTransform& xf,
TUniqueId parentId, const CLight& light, u32 w1, u32 w2, float f1)
TUniqueId parentId, const CLight& light, u32 sourceId, u32 w2, float f1)
: CActor(uid, active, name, CEntityInfo(aid, CEntity::NullConnectionList), xf,
CModelData::CModelDataNull(), CMaterialList(), CActorParameters::None(), kInvalidUniqueId),
xe8_parentId(parentId), xec_light(light), x13c_loadedIdx(w1), x140_priority(w2), x144_lifeTime(f1)
xe8_parentId(parentId), xec_light(light), x13c_lightId(sourceId), x140_priority(w2), x144_lifeTime(f1)
{
xec_light.GetRadius();
xec_light.GetIntensity();
@ -35,7 +35,7 @@ void CGameLight::Think(float dt, CStateManager& mgr)
void CGameLight::SetLightPriorityAndId()
{
xec_light.x3c_priority = x140_priority;
xec_light.x40_lightId = x13c_loadedIdx;
xec_light.x40_lightId = x13c_lightId;
}
void CGameLight::SetLight(const CLight& light)

View File

@ -9,13 +9,13 @@ class CGameLight : public CActor
{
TUniqueId xe8_parentId;
CLight xec_light;
u32 x13c_loadedIdx;
u32 x13c_lightId;
u32 x140_priority;
float x144_lifeTime;
public:
CGameLight(TUniqueId, TAreaId, bool, std::string_view, const zeus::CTransform&, TUniqueId, const CLight&, u32,
u32, float);
CGameLight(TUniqueId, TAreaId, bool, std::string_view, const zeus::CTransform&, TUniqueId, const CLight&,
u32 sourceId, u32, float);
void Accept(IVisitor &visitor);
void Think(float, CStateManager&);

View File

@ -208,7 +208,7 @@ void CMorphBall::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CSt
CGameLight* l = new CGameLight(x1c10_ballInnerGlowLight, kInvalidAreaId, false, "BallLight",
GetBallToWorld(), x0_player.GetUniqueId(),
x19d0_ballInnerGlowGen->GetLight(),
u32(reinterpret_cast<uintptr_t>(x1988_ballInnerGlow.GetObj())), 0, 0.f);
u32(x1988_ballInnerGlow.GetObjectTag()->id.Value()), 0, 0.f);
mgr.AddObject(l);
}
break;

View File

@ -2092,7 +2092,7 @@ void CPlayer::CalculatePlayerMovementDirection(float dt)
x500_lookDir.normalize();
}
void CPlayer::Stop(CStateManager& stateMgr)
void CPlayer::UnFreeze(CStateManager& stateMgr)
{
if (GetFrozenState())
{
@ -2163,11 +2163,11 @@ void CPlayer::UpdateFrozenState(const CFinalInput& input, CStateManager& mgr)
if (x750_frozenTimeout > 0.f)
SetVisorSteam(0.7f, 0.42857146f, 0.071428575f, xa08_steamTextureId, false);
else
Stop(mgr);
UnFreeze(mgr);
if (x258_movementState == EPlayerMovementState::OnGround ||
x258_movementState == EPlayerMovementState::FallingMorphed)
{
Stop(mgr);
UnFreeze(mgr);
ClearForcesAndTorques();
}
x7a0_visorSteam.Update(input.DeltaTime());
@ -2200,7 +2200,7 @@ void CPlayer::UpdateFrozenState(const CFinalInput& input, CStateManager& mgr)
g_GameState->SystemOptions().IncrementFrozenFpsCount();
CHUDMemoParms info(0.f, true, true, true);
MP1::CSamusHud::DisplayHudMemo(u"", info);
Stop(mgr);
UnFreeze(mgr);
}
}
break;

View File

@ -487,7 +487,7 @@ public:
void CalculateLeaveMorphBallDirection(const CFinalInput& input);
void CalculatePlayerControlDirection(CStateManager& mgr);
void CalculatePlayerMovementDirection(float dt);
void Stop(CStateManager& stateMgr);
void UnFreeze(CStateManager& stateMgr);
void Freeze(CStateManager& stateMgr, CAssetId steamTxtr, u16 sfx, CAssetId iceTxtr);
bool GetFrozenState() const;
void UpdateFrozenState(const CFinalInput& input, CStateManager& mgr);

View File

@ -171,4 +171,11 @@ void CScriptDoor::SetDoorAnimation(CScriptDoor::EDoorAnimType type)
modelData->AnimationData()->SetAnimation(CAnimPlaybackParms(s32(type), -1, 1.f, true), false);
}
rstl::optional_object<zeus::CAABox> CScriptDoor::GetProjectileBounds() const
{
if (x2a8_28_)
return {{x284_modelBounds.min + GetTranslation(), x284_modelBounds.max + GetTranslation()}};
return {};
}
}

View File

@ -67,6 +67,7 @@ public:
void OpenDoor(TUniqueId, CStateManager&);
u32 GetDoorOpenCondition(CStateManager& mgr);
void SetDoorAnimation(EDoorAnimType);
rstl::optional_object<zeus::CAABox> GetProjectileBounds() const;
};
}

View File

@ -23,4 +23,5 @@ CWallCrawlerSwarm::CWallCrawlerSwarm(TUniqueId uid, bool active, std::string_vie
}
void CWallCrawlerSwarm::Accept(IVisitor& visitor) { visitor.Visit(this); }
}

View File

@ -55,6 +55,7 @@ private:
zeus::CAABox xe8_aabox = zeus::CAABox::skNullBox;
std::vector<CBoid> x108_boids;
zeus::CVector3f x130_lastKilledOffset;
int x42c_lockOnId = -1;
public:
CWallCrawlerSwarm(TUniqueId, bool, std::string_view, const CEntityInfo&, const zeus::CVector3f&,
@ -68,6 +69,11 @@ public:
void ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info,
CStateManager& stateMgr) {}
const std::vector<CBoid>& GetBoids() const { return x108_boids; }
int GetCurrentLockOnId() const { return x42c_lockOnId; }
bool GetLockOnLocationValid(int id) const
{ return id >= 0 && id < x108_boids.size() && x108_boids[id].GetActive(); }
const zeus::CVector3f& GetLockOnLocation(int id) const
{ return x108_boids[id].GetTranslation(); }
};
}