Initial working projectiles

This commit is contained in:
Jack Andersen 2018-02-11 19:30:21 -10:00
parent 547471c6ba
commit 46a4a37cc6
45 changed files with 545 additions and 166 deletions

View File

@ -157,7 +157,7 @@ struct DamageVulnerability : BigYAML
Value<atUint32> enemyWeapon4; Value<atUint32> enemyWeapon4;
Value<atUint32> unkownWeapon1; Value<atUint32> unkownWeapon1;
Value<atUint32> unkownWeapon2; Value<atUint32> unkownWeapon2;
Value<atUint32> unkownWeapon3; Value<atUint32> deflected;
struct ChargedBeams : BigYAML struct ChargedBeams : BigYAML
{ {
DECL_YAML DECL_YAML
@ -166,7 +166,7 @@ struct DamageVulnerability : BigYAML
Value<atUint32> ice; Value<atUint32> ice;
Value<atUint32> wave; Value<atUint32> wave;
Value<atUint32> plasma; Value<atUint32> plasma;
Value<atUint32> phazon; Value<atUint32> deflected;
} chargedBeams; } chargedBeams;
struct BeamCombos : BigYAML struct BeamCombos : BigYAML
@ -177,7 +177,7 @@ struct DamageVulnerability : BigYAML
Value<atUint32> iceSpreader; Value<atUint32> iceSpreader;
Value<atUint32> wavebuster; Value<atUint32> wavebuster;
Value<atUint32> flameThrower; Value<atUint32> flameThrower;
Value<atUint32> phazonCombo; Value<atUint32> deflected;
} beamCombos; } beamCombos;
}; };

View File

@ -901,6 +901,15 @@ void CStateManager::DrawWorld() const
DrawAdditionalFilters(); DrawAdditionalFilters();
} }
void CStateManager::SetupFogForArea(TAreaId area) const
{
if (area == kInvalidAreaId)
area = x8cc_nextAreaId;
const CGameArea* areaObj = x850_world->GetAreaAlways(area);
if (areaObj->IsPostConstructed())
SetupFogForArea(*areaObj);
}
void CStateManager::SetupFogForArea(const CGameArea& area) const void CStateManager::SetupFogForArea(const CGameArea& area) const
{ {
if (SetupFogForDraw()) if (SetupFogForDraw())
@ -1305,7 +1314,7 @@ void CStateManager::InformListeners(const zeus::CVector3f& pos, EListenNoiseType
void CStateManager::ApplyKnockBack(CActor& actor, const CDamageInfo& info, const CDamageVulnerability& vuln, void CStateManager::ApplyKnockBack(CActor& actor, const CDamageInfo& info, const CDamageVulnerability& vuln,
const zeus::CVector3f& pos, float dampen) const zeus::CVector3f& pos, float dampen)
{ {
if (vuln.GetVulnerability(info.GetWeaponMode(), false) == EVulnerability::Reflect) if (vuln.GetVulnerability(info.GetWeaponMode(), false) == EVulnerability::Deflect)
return; return;
CHealthInfo* hInfo = actor.HealthInfo(*this); CHealthInfo* hInfo = actor.HealthInfo(*this);
if (!hInfo) if (!hInfo)
@ -1384,8 +1393,8 @@ void CStateManager::ApplyDamageToWorld(TUniqueId damager, const CActor& actor, c
bool bomb = false; bool bomb = false;
TCastToPtr<CWeapon> weapon = const_cast<CActor&>(actor); TCastToPtr<CWeapon> weapon = const_cast<CActor&>(actor);
if (weapon) if (weapon)
bomb = (weapon->GetAttribField() & (CWeapon::EProjectileAttrib::Bombs | bomb = (weapon->GetAttribField() & (EProjectileAttrib::Bombs |
CWeapon::EProjectileAttrib::PowerBombs)) != CWeapon::EProjectileAttrib::None; EProjectileAttrib::PowerBombs)) != EProjectileAttrib::None;
rstl::reserved_vector<TUniqueId, 1024> nearList; rstl::reserved_vector<TUniqueId, 1024> nearList;
BuildNearList(nearList, aabb, filter, &actor); BuildNearList(nearList, aabb, filter, &actor);
@ -1407,7 +1416,7 @@ void CStateManager::ApplyDamageToWorld(TUniqueId damager, const CActor& actor, c
} }
else else
{ {
if ((weapon->GetAttribField() & CWeapon::EProjectileAttrib::Bombs) != CWeapon::EProjectileAttrib::None) if ((weapon->GetAttribField() & EProjectileAttrib::Bombs) == EProjectileAttrib::Bombs)
player->BombJump(pos, *this); player->BombJump(pos, *this);
} }
} }
@ -1604,17 +1613,16 @@ void CStateManager::TestBombHittingWater(const CActor& damager, const zeus::CVec
{ {
if (TCastToPtr<CWeapon> wpn = const_cast<CActor&>(damager)) if (TCastToPtr<CWeapon> wpn = const_cast<CActor&>(damager))
{ {
if ((wpn->GetAttribField() & (CWeapon::EProjectileAttrib::Bombs | if ((wpn->GetAttribField() & (EProjectileAttrib::Bombs |
CWeapon::EProjectileAttrib::PowerBombs)) != CWeapon::EProjectileAttrib::None) EProjectileAttrib::PowerBombs)) != EProjectileAttrib::None)
{ {
bool powerBomb = (wpn->GetAttribField() & CWeapon::EProjectileAttrib::Bombs) != bool powerBomb = (wpn->GetAttribField() & EProjectileAttrib::PowerBombs) == EProjectileAttrib::PowerBombs;
CWeapon::EProjectileAttrib::None;
if (TCastToPtr<CScriptWater> water = damagee) if (TCastToPtr<CScriptWater> water = damagee)
{ {
zeus::CAABox bounds = water->GetTriggerBoundsWR(); zeus::CAABox bounds = water->GetTriggerBoundsWR();
zeus::CVector3f hitPos(pos.x, pos.y, bounds.max.z); zeus::CVector3f hitPos(pos.x, pos.y, bounds.max.z);
float bombRad = powerBomb ? 4.f : 2.f; float bombRad = powerBomb ? 4.f : 2.f;
float delta = -(pos.dot(zeus::CVector3f::skUp) - bounds.max.z); float delta = bounds.max.z - pos.dot(zeus::CVector3f::skUp);
if (delta <= bombRad && delta > 0.f) if (delta <= bombRad && delta > 0.f)
{ {
// Below surface // Below surface
@ -1626,7 +1634,8 @@ void CStateManager::TestBombHittingWater(const CActor& damager, const zeus::CVec
water->GetFluidPlane().AddRipple(mag, damager.GetUniqueId(), hitPos, *water, *this); water->GetFluidPlane().AddRipple(mag, damager.GetUniqueId(), hitPos, *water, *this);
} }
if (!powerBomb) if (!powerBomb)
x87c_fluidPlaneManager->CreateSplash(damager.GetUniqueId(), *this, *water, hitPos, rippleFactor, true); x87c_fluidPlaneManager->CreateSplash(damager.GetUniqueId(), *this, *water, hitPos,
rippleFactor, true);
} }
else else
{ {
@ -1649,8 +1658,8 @@ void CStateManager::TestBombHittingWater(const CActor& damager, const zeus::CVec
} }
} }
bool CStateManager::ApplyLocalDamage(const zeus::CVector3f& vec1, const zeus::CVector3f& vec2, CActor& damagee, float dam, bool CStateManager::ApplyLocalDamage(const zeus::CVector3f& vec1, const zeus::CVector3f& vec2, CActor& damagee,
const CWeaponMode& weapMode) float dam, const CWeaponMode& weapMode)
{ {
CHealthInfo* hInfo = damagee.HealthInfo(*this); CHealthInfo* hInfo = damagee.HealthInfo(*this);
if (!hInfo || dam < 0.f) if (!hInfo || dam < 0.f)

View File

@ -279,6 +279,7 @@ public:
zeus::CFrustum SetupViewForDraw(const SViewport& vp) const; zeus::CFrustum SetupViewForDraw(const SViewport& vp) const;
void ResetViewAfterDraw(const SViewport& backupViewport, const zeus::CTransform& backupViewMatrix) const; void ResetViewAfterDraw(const SViewport& backupViewport, const zeus::CTransform& backupViewMatrix) const;
void DrawWorld() const; void DrawWorld() const;
void SetupFogForArea(TAreaId area) const;
void SetupFogForArea(const CGameArea& area) const; void SetupFogForArea(const CGameArea& area) const;
bool SetupFogForDraw() const; bool SetupFogForDraw() const;
void PreRender(); void PreRender();

View File

@ -96,8 +96,8 @@ void CCameraManager::EnterCinematic(CStateManager& mgr)
{ {
if (weap->GetActive()) if (weap->GetActive())
{ {
if ((weap->GetAttribField() & CWeapon::EProjectileAttrib::KeepInCinematic) == if ((weap->GetAttribField() & EProjectileAttrib::KeepInCinematic) ==
CWeapon::EProjectileAttrib::None) EProjectileAttrib::None)
{ {
if (TCastToConstPtr<CAi>(mgr.GetObjectById(weap->GetOwnerId())) || if (TCastToConstPtr<CAi>(mgr.GetObjectById(weap->GetOwnerId())) ||
TCastToConstPtr<CPlayer>(mgr.GetObjectById(weap->GetOwnerId()))) TCastToConstPtr<CPlayer>(mgr.GetObjectById(weap->GetOwnerId())))

View File

@ -19,7 +19,7 @@ enum class EWeaponCollisionResponseTypes
None, Default, Unknown2, Metal, None, Default, Unknown2, Metal,
Grass, Ice, Goo, Wood, Grass, Ice, Goo, Wood,
Water, Mud, Lava, Sand, Water, Mud, Lava, Sand,
Projectile,Unknown13,Unknown14,Unknown15, Projectile,OtherProjectile,Unknown14,Unknown15,
EnemyNormal,EnemySpecial,EnemyShielded,Unknown19, EnemyNormal,EnemySpecial,EnemyShielded,Unknown19,
Unknown20,Unknown21,Unknown22,Unknown23, Unknown20,Unknown21,Unknown22,Unknown23,
Unknown24,Unknown25,Unknown26,Unknown27, Unknown24,Unknown25,Unknown26,Unknown27,

View File

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

View File

@ -1,7 +1,3 @@
//
// Created by Jack Andersen on 2/10/18.
//
#include "CFlaahgraProjectile.hpp" #include "CFlaahgraProjectile.hpp"
namespace urde::MP1 namespace urde::MP1

View File

@ -1,7 +1,3 @@
//
// Created by Jack Andersen on 2/10/18.
//
#include "CPuddleToadGamma.hpp" #include "CPuddleToadGamma.hpp"
namespace urde::MP1 namespace urde::MP1

View File

@ -55,4 +55,10 @@ void CDecalManager::Update(float dt, CStateManager& mgr)
} }
void CDecalManager::AddDecal(const TToken<CDecalDescription>& decal, const zeus::CTransform& xf,
bool b1, CStateManager& mgr)
{
}
} }

View File

@ -34,6 +34,8 @@ public:
static void Shutdown(); static void Shutdown();
static void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr); static void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr);
static void Update(float dt, CStateManager& mgr); static void Update(float dt, CStateManager& mgr);
static void AddDecal(const TToken<CDecalDescription>& decal, const zeus::CTransform& xf,
bool b1, CStateManager& mgr);
}; };
} }

View File

@ -127,7 +127,7 @@ bool CProjectileWeaponDataFactory::CreateWPSM(CWeaponDescription* desc, CInputSt
FourCC cid = CPF::GetClassID(in); FourCC cid = CPF::GetClassID(in);
if (cid == SBIG('NONE')) if (cid == SBIG('NONE'))
break; break;
CAssetId id = CPF::GetInt(in); CAssetId id(in);
if (id.IsValid()) if (id.IsValid())
desc->x94_COLR = {resPool->GetObj({FOURCC('CRSC'), id}), true}; desc->x94_COLR = {resPool->GetObj({FOURCC('CRSC'), id}), true};
break; break;

View File

@ -249,7 +249,7 @@ void CAuxWeapon::CreateFlameThrower(const zeus::CTransform& xf, CStateManager& m
x6e_flameThrowerId = mgr.AllocateUniqueId(); x6e_flameThrowerId = mgr.AllocateUniqueId();
CNewFlameThrower* ft = new CNewFlameThrower(x28_combos[3], "Player_FlameThrower", EWeaponType::Plasma, CNewFlameThrower* ft = new CNewFlameThrower(x28_combos[3], "Player_FlameThrower", EWeaponType::Plasma,
resInfo, xf, EMaterialTypes::Player, CGunWeapon::GetShotDamageInfo(g_tweakPlayerGun->GetComboShotInfo(3), mgr), resInfo, xf, EMaterialTypes::Player, CGunWeapon::GetShotDamageInfo(g_tweakPlayerGun->GetComboShotInfo(3), mgr),
x6e_flameThrowerId, kInvalidAreaId, x6c_playerId, CWeapon::EProjectileAttrib::None); x6e_flameThrowerId, kInvalidAreaId, x6c_playerId, EProjectileAttrib::None);
mgr.AddObject(ft); mgr.AddObject(ft);
ft->Think(dt, mgr); ft->Think(dt, mgr);
ft->StartFiring(xf, mgr); ft->StartFiring(xf, mgr);
@ -272,7 +272,7 @@ void CAuxWeapon::DeleteWaveBusterBeam(CStateManager& mgr)
} }
} }
void CAuxWeapon::CreateWaveBusterBeam(CWeapon::EProjectileAttrib attribs, TUniqueId homingTarget, void CAuxWeapon::CreateWaveBusterBeam(EProjectileAttrib attribs, TUniqueId homingTarget,
const zeus::CTransform& xf, CStateManager& mgr) const zeus::CTransform& xf, CStateManager& mgr)
{ {
DeleteFlameThrower(mgr); DeleteFlameThrower(mgr);
@ -294,7 +294,7 @@ void CAuxWeapon::CreateWaveBusterBeam(CWeapon::EProjectileAttrib attribs, TUniqu
static const u16 skSoundId[] = { 1810, 1837, 1847, 1842, 1810 }; static const u16 skSoundId[] = { 1810, 1837, 1847, 1842, 1810 };
void CAuxWeapon::LaunchMissile(float dt, bool underwater, bool charged, CPlayerState::EBeamId currentBeam, void CAuxWeapon::LaunchMissile(float dt, bool underwater, bool charged, CPlayerState::EBeamId currentBeam,
CWeapon::EProjectileAttrib attrib, const zeus::CTransform& xf, TUniqueId homingId, EProjectileAttrib attrib, const zeus::CTransform& xf, TUniqueId homingId,
CStateManager& mgr) CStateManager& mgr)
{ {
const SShotParam& info = const SShotParam& info =
@ -303,7 +303,7 @@ void CAuxWeapon::LaunchMissile(float dt, bool underwater, bool charged, CPlayerS
CEnergyProjectile* proj = new CEnergyProjectile(true, charged ? x28_combos[int(currentBeam)] : x0_missile, CEnergyProjectile* proj = new CEnergyProjectile(true, charged ? x28_combos[int(currentBeam)] : x0_missile,
charged ? EWeaponType::Power : EWeaponType::Missile, xf, EMaterialTypes::Player, charged ? EWeaponType::Power : EWeaponType::Missile, xf, EMaterialTypes::Player,
CGunWeapon::GetShotDamageInfo(info, mgr), mgr.AllocateUniqueId(), kInvalidAreaId, x6c_playerId, homingId, CGunWeapon::GetShotDamageInfo(info, mgr), mgr.AllocateUniqueId(), kInvalidAreaId, x6c_playerId, homingId,
attrib | CWeapon::EProjectileAttrib::ArmCannon, underwater, zeus::CVector3f::skOne, {}, -1, false); attrib | EProjectileAttrib::ArmCannon, underwater, zeus::CVector3f::skOne, {}, -1, false);
mgr.AddObject(proj); mgr.AddObject(proj);
proj->Think(dt, mgr); proj->Think(dt, mgr);
if (charged) if (charged)
@ -324,9 +324,9 @@ void CAuxWeapon::Fire(float dt, bool underwater, CPlayerState::EBeamId currentBe
if (!x80_24_isLoaded) if (!x80_24_isLoaded)
return; return;
CWeapon::EProjectileAttrib attrib = CWeapon::EProjectileAttrib::None; EProjectileAttrib attrib = EProjectileAttrib::None;
if (chargeState == EChargeState::Charged) if (chargeState == EChargeState::Charged)
attrib = CGameProjectile::GetBeamAttribType(type) | CWeapon::EProjectileAttrib::ComboShot; attrib = CGameProjectile::GetBeamAttribType(type) | EProjectileAttrib::ComboShot;
if (chargeState == EChargeState::Normal) if (chargeState == EChargeState::Normal)
{ {

View File

@ -30,10 +30,10 @@ class CAuxWeapon
void DeleteFlameThrower(CStateManager& mgr); void DeleteFlameThrower(CStateManager& mgr);
void CreateFlameThrower(const zeus::CTransform& xf, CStateManager& mgr, float dt); void CreateFlameThrower(const zeus::CTransform& xf, CStateManager& mgr, float dt);
void DeleteWaveBusterBeam(CStateManager& mgr); void DeleteWaveBusterBeam(CStateManager& mgr);
void CreateWaveBusterBeam(CWeapon::EProjectileAttrib attribs, TUniqueId homingTarget, void CreateWaveBusterBeam(EProjectileAttrib attribs, TUniqueId homingTarget,
const zeus::CTransform& xf, CStateManager& mgr); const zeus::CTransform& xf, CStateManager& mgr);
void LaunchMissile(float dt, bool underwater, bool charged, CPlayerState::EBeamId currentBeam, void LaunchMissile(float dt, bool underwater, bool charged, CPlayerState::EBeamId currentBeam,
CWeapon::EProjectileAttrib attrib, const zeus::CTransform& xf, TUniqueId homingId, EProjectileAttrib attrib, const zeus::CTransform& xf, TUniqueId homingId,
CStateManager& mgr); CStateManager& mgr);
public: public:
explicit CAuxWeapon(TUniqueId playerId); explicit CAuxWeapon(TUniqueId playerId);

View File

@ -1,6 +1,15 @@
#include <Runtime/GameGlobalObjects.hpp> #include "GameGlobalObjects.hpp"
#include "CEnergyProjectile.hpp" #include "CEnergyProjectile.hpp"
#include "CStateManager.hpp" #include "CStateManager.hpp"
#include "World/CWorld.hpp"
#include "World/CGameLight.hpp"
#include "World/CPlayer.hpp"
#include "Particle/CDecalManager.hpp"
#include "Camera/CGameCamera.hpp"
#include "World/CExplosion.hpp"
#include "World/CScriptPlatform.hpp"
#include "World/CIceImpact.hpp"
#include "CSimplePool.hpp"
#include "TCastTo.hpp" #include "TCastTo.hpp"
namespace urde namespace urde
@ -61,7 +70,7 @@ void CEnergyProjectile::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId send
switch (msg) switch (msg)
{ {
case EScriptObjectMessage::Deleted: case EScriptObjectMessage::Deleted:
if (x2e4_24_) if (x2e4_24_active)
mgr.RemoveWeaponId(xec_ownerId, xf0_weaponType); mgr.RemoveWeaponId(xec_ownerId, xf0_weaponType);
if (x2e8_sfx) if (x2e8_sfx)
{ {
@ -131,39 +140,291 @@ void CEnergyProjectile::ResolveCollisionWithWorld(const CRayCastResult& res, CSt
void CEnergyProjectile::ResolveCollisionWithActor(const CRayCastResult& res, CActor& act, CStateManager& mgr) void CEnergyProjectile::ResolveCollisionWithActor(const CRayCastResult& res, CActor& act, CStateManager& mgr)
{ {
x2c2_ = act.GetUniqueId();
EWeaponCollisionResponseTypes crType =
act.GetCollisionResponseType(res.GetPoint(), x34_transform.basis[1].normalized(),
x12c_curDamageInfo.GetWeaponMode(), xe8_projectileAttribs);
act.Touch(*this, mgr);
const CDamageVulnerability* dVuln = act.GetDamageVulnerability();
if (!Explode(res.GetPoint(), res.GetPlane().normal(), crType, mgr, *dVuln, act.GetUniqueId()))
{
mgr.SendScriptMsg(&act, GetUniqueId(), EScriptObjectMessage::Touched);
act.SendScriptMsgs(EScriptObjectState::ReflectedDamage, mgr, EScriptObjectMessage::None);
}
else
{
CGameProjectile::ResolveCollisionWithActor(res, act, mgr);
ApplyDamageToActors(mgr, x12c_curDamageInfo);
}
if (TCastToPtr<CEnergyProjectile> proj = act)
{
proj->Explode(GetTranslation(), x34_transform.basis[1],
EWeaponCollisionResponseTypes::OtherProjectile,
mgr, *GetDamageVulnerability(), GetUniqueId());
}
} }
void CEnergyProjectile::Think(float dt, CStateManager& mgr) void CEnergyProjectile::Think(float dt, CStateManager& mgr)
{ {
CWeapon::Think(dt, mgr);
if (mgr.GetWorld()->GetCurrentAreaId() != GetAreaIdAlways() &&
(xe8_projectileAttribs & EProjectileAttrib::ArmCannon) == EProjectileAttrib::ArmCannon)
mgr.SetActorAreaId(*this, mgr.GetWorld()->GetCurrentAreaId());
UpdateProjectileMovement(dt, mgr);
TUniqueId id = kInvalidUniqueId;
CRayCastResult res = DoCollisionCheck(id, mgr);
if (res.IsValid())
{
if (TCastToPtr<CActor> act = mgr.ObjectById(id))
ResolveCollisionWithActor(res, *act, mgr);
else
ResolveCollisionWithWorld(res, mgr);
}
x170_projectile.UpdateParticleFX();
if (x2e4_24_active && x3d0_26_)
Explode(GetTranslation(), zeus::CVector3f::skUp, EWeaponCollisionResponseTypes::Default, mgr,
CDamageVulnerability::NormalVulnerabilty(), kInvalidUniqueId);
if (x2c8_projectileLight != kInvalidUniqueId)
{
if (TCastToPtr<CGameLight> light = mgr.ObjectById(x2c8_projectileLight))
{
light->SetTransform(GetTransform());
light->SetTranslation(GetTranslation());
if (CElementGen* ps1 = x170_projectile.GetAttachedPS1())
if (ps1->SystemHasLight())
light->SetLight(ps1->GetLight());
}
}
if (x2e8_sfx)
{
CSfxManager::UpdateEmitter(x2e8_sfx, x170_projectile.GetTranslation(), x170_projectile.GetVelocity(), 1.f);
CSfxManager::PitchBend(x2e8_sfx, x2e4_26_waterUpdate ? -1.f : 0.f);
}
x3d4_curTime += dt;
if (x3d4_curTime > 45.f || x170_projectile.IsSystemDeletable() || x3d0_24_dead)
mgr.FreeScriptObject(GetUniqueId());
} }
void CEnergyProjectile::Render(const CStateManager& mgr) const void CEnergyProjectile::Render(const CStateManager& mgr) const
{ {
CPlayerState::EPlayerVisor visor = mgr.GetPlayerState()->GetActiveVisor(mgr);
if (visor == CPlayerState::EPlayerVisor::Combat)
{
if ((xe8_projectileAttribs & EProjectileAttrib::Charged) == EProjectileAttrib::Charged ||
(xe8_projectileAttribs & EProjectileAttrib::ComboShot) == EProjectileAttrib::ComboShot)
{
float warpTime = 1.f - float(x170_projectile.GameTime());
if (warpTime > 0.f)
mgr.DrawSpaceWarp(GetTranslation(), warpTime * 0.75f);
}
}
if (visor == CPlayerState::EPlayerVisor::XRay)
{
CElementGen::SetSubtractBlend((xe8_projectileAttribs & EProjectileAttrib::Ice) != EProjectileAttrib::Ice);
CGraphics::SetFog(ERglFogMode::PerspLin, 0.f, 75.f, zeus::CColor::skBlack);
x170_projectile.RenderParticles();
CGameProjectile::Render(mgr);
mgr.SetupFogForArea(GetAreaIdAlways());
CElementGen::SetSubtractBlend(false);
}
else if ((xe8_projectileAttribs & EProjectileAttrib::Ice) == EProjectileAttrib::Ice &&
mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot)
{
CElementGen::SetSubtractBlend(true);
x170_projectile.RenderParticles();
CGameProjectile::Render(mgr);
mgr.SetupFogForArea(GetAreaIdAlways());
CElementGen::SetSubtractBlend(false);
}
else
{
CGameProjectile::Render(mgr);
}
} }
void CEnergyProjectile::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const void CEnergyProjectile::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const
{ {
auto bounds = x170_projectile.GetBounds();
if (bounds && !frustum.aabbFrustumTest(*bounds))
return;
CPlayerState::EPlayerVisor visor = mgr.GetPlayerState()->GetActiveVisor(mgr);
if (visor != CPlayerState::EPlayerVisor::XRay &&
((xe8_projectileAttribs & EProjectileAttrib::Ice) != EProjectileAttrib::Ice ||
mgr.GetThermalDrawFlag() != EThermalDrawFlag::Hot))
x170_projectile.AddToRenderer();
EnsureRendered(mgr);
} }
void CEnergyProjectile::Touch(CActor& act, CStateManager& mgr) void CEnergyProjectile::Touch(CActor& act, CStateManager& mgr)
{ {
// Empty
} }
bool CEnergyProjectile::Explode(const zeus::CVector3f& pos, const zeus::CVector3f& dir, bool CEnergyProjectile::Explode(const zeus::CVector3f& pos, const zeus::CVector3f& normal,
EWeaponCollisionResponseTypes type, CStateManager& mgr, EWeaponCollisionResponseTypes type, CStateManager& mgr,
const CDamageVulnerability& dVuln, TUniqueId exploder) const CDamageVulnerability& dVuln, TUniqueId hitActor)
{ {
return false; zeus::CVector3f offsetPos = pos + normal * 0.01f;
bool done = true;
bool retargetPlayer = false;
bool deflect = false;
zeus::CVector3f targetPos;
EVulnerability vulnType = dVuln.GetVulnerability(x12c_curDamageInfo.GetWeaponMode(), false);
if (vulnType == EVulnerability::Deflect)
{
deflect = true;
EVulnerability deflectType = dVuln.GetDeflectionType(x12c_curDamageInfo.GetWeaponMode());
switch (deflectType)
{
case EVulnerability::DoubleDamage:
deflect = false;
break;
case EVulnerability::Deflect:
case EVulnerability::Immune:
if (deflectType != EVulnerability::Deflect ||
(xf0_weaponType != EWeaponType::Missile &&
(xe8_projectileAttribs & EProjectileAttrib::ComboShot) != EProjectileAttrib::ComboShot))
if (xf8_filter.GetExcludeList().HasMaterial(EMaterialTypes::Player))
retargetPlayer = true;
break;
default:
break;
}
if (retargetPlayer)
{
float ang = mgr.GetActiveRandom()->Range(0.f, 2.f * M_PIF);
float y = std::sin(ang);
float x = std::cos(ang);
targetPos = mgr.GetPlayer().GetAimPosition(mgr, 0.f) + zeus::CVector3f(x, 0.f, y);
ChangeProjectileOwner(hitActor, mgr);
}
}
if (vulnType != EVulnerability::Immune && !deflect)
{
deflect = (type == EWeaponCollisionResponseTypes::Unknown15 ||
type == EWeaponCollisionResponseTypes::EnemyShielded ||
(type >= EWeaponCollisionResponseTypes::Unknown69 &&
type <= EWeaponCollisionResponseTypes::Unknown93));
}
SetTranslation(offsetPos);
if (deflect)
{
done = false;
x2c0_homingTargetId = kInvalidUniqueId;
x3d0_25_ = false;
}
else
{
StopProjectile(mgr);
if (x3d0_27_camShakeDirty)
{
x2fc_camShake.SetSfxPositionAndDistance(pos, 50.f);
mgr.GetCameraManager()->AddCameraShaker(x2fc_camShake, false);
}
}
PlayImpactSound(pos, type);
mgr.InformListeners(pos, EListenNoiseType::Projectile);
if (auto particle = x170_projectile.CollisionOccured(type, !done, retargetPlayer, offsetPos, normal, targetPos))
{
zeus::CTransform particleXf = zeus::lookAt(zeus::CVector3f::skZero, normal);
if (xf0_weaponType != EWeaponType::Power ||
!xf8_filter.GetExcludeList().HasMaterial(EMaterialTypes::Player) ||
!x2e4_27_inWater)
{
if (auto decal = x170_projectile.GetDecalForCollision(type))
{
CDecalManager::AddDecal(*decal, particleXf,
(xe8_projectileAttribs & EProjectileAttrib::Ice) != EProjectileAttrib::Ice, mgr);
}
zeus::CVector3f scale = zeus::CVector3f::skOne;
bool camClose = false;
if (mgr.GetPlayer().GetCameraState() == CPlayer::EPlayerCameraState::FirstPerson)
{
float mag = (offsetPos - mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTranslation()).magnitude();
if (mag < 4.f)
{
scale = zeus::CVector3f(0.75f * (mag * 0.25f) + 0.25f);
camClose = true;
}
}
u32 explodeFlags = 0x8;
if ((xe8_projectileAttribs & EProjectileAttrib::Ice) == EProjectileAttrib::Ice)
explodeFlags |= 0x4;
if (camClose)
explodeFlags |= 0x2;
CEntityInfo explosionInfo(GetAreaIdAlways(), CEntity::NullConnectionList);
CExplosion* explosion = new CExplosion(*particle, mgr.AllocateUniqueId(), true, explosionInfo,
"Projectile collision response", particleXf, explodeFlags, scale, zeus::CColor::skWhite);
mgr.AddObject(explosion);
if (TCastToPtr<CActor> hActor = mgr.ObjectById(hitActor))
{
bool validPlat = false;
CScriptPlatform* plat = TCastToPtr<CScriptPlatform>(hActor.GetPtr()).GetPtr();
validPlat = plat != nullptr;
if (!validPlat && hActor->GetMaterialList().HasMaterial(EMaterialTypes::Bomb))
{
for (CEntity* ent : mgr.GetPlatformAndDoorObjectList())
{
if (TCastToPtr<CScriptPlatform> otherPlat = ent)
{
if (otherPlat->IsSlave(hitActor))
{
plat = otherPlat.GetPtr();
validPlat = true;
break;
}
}
}
}
if (validPlat)
plat->AddSlave(explosion->GetUniqueId(), mgr);
}
}
else
{
x3d0_24_dead = true;
}
if ((xe8_projectileAttribs & (EProjectileAttrib::ComboShot | EProjectileAttrib::Ice)) ==
(EProjectileAttrib::ComboShot | EProjectileAttrib::Ice))
{
/* Ice Spreader */
TLockedToken<CGenDescription> iceSpreadParticle = g_SimplePool->GetObj("IceSpread1");
u32 flags = (xe6_27_thermalVisorFlags & 0x2) == 0 ? 1 : 0;
flags |= 0x2;
CIceImpact* iceImpact = new CIceImpact(iceSpreadParticle, mgr.AllocateUniqueId(), GetAreaIdAlways(),
true, "Ice spread explosion", particleXf, flags,
zeus::CVector3f::skOne, zeus::CColor::skWhite);
mgr.AddObject(iceImpact);
}
}
return done;
} }
void CEnergyProjectile::StopProjectile(CStateManager& mgr) void CEnergyProjectile::StopProjectile(CStateManager& mgr)
{ {
DeleteProjectileLight(mgr);
mgr.RemoveWeaponId(xec_ownerId, xf0_weaponType);
x2e4_24_active = false;
x68_material = CMaterialList();
mgr.UpdateActorInSortedLists(*this);
if (x2e8_sfx)
{
CSfxManager::RemoveEmitter(x2e8_sfx);
x2e8_sfx.reset();
}
} }
} }

View File

@ -17,14 +17,14 @@ class CEnergyProjectile : public CGameProjectile
{ {
struct struct
{ {
bool x3d0_24_ : 1; bool x3d0_24_dead : 1;
bool x3d0_25_ : 1; bool x3d0_25_ : 1;
bool x3d0_26_ : 1; bool x3d0_26_ : 1;
bool x3d0_27_camShakeDirty : 1; bool x3d0_27_camShakeDirty : 1;
}; };
u32 _dummy = 0; u32 _dummy = 0;
}; };
float x3d4_ = 0.f; float x3d4_curTime = 0.f;
void StopProjectile(CStateManager& mgr); void StopProjectile(CStateManager& mgr);
public: public:
CEnergyProjectile(bool active, const TToken<CWeaponDescription>& desc, EWeaponType type, CEnergyProjectile(bool active, const TToken<CWeaponDescription>& desc, EWeaponType type,
@ -44,8 +44,8 @@ public:
void Render(const CStateManager& mgr) const; void Render(const CStateManager& mgr) const;
void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const; void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const;
void Touch(CActor& act, CStateManager& mgr); void Touch(CActor& act, CStateManager& mgr);
virtual bool Explode(const zeus::CVector3f& pos, const zeus::CVector3f& dir, EWeaponCollisionResponseTypes type, virtual bool Explode(const zeus::CVector3f& pos, const zeus::CVector3f& normal, EWeaponCollisionResponseTypes type,
CStateManager& mgr, const CDamageVulnerability& dVuln, TUniqueId exploder); CStateManager& mgr, const CDamageVulnerability& dVuln, TUniqueId hitActor);
}; };
} }

View File

@ -31,7 +31,7 @@ CGameProjectile::CGameProjectile(bool active, const TToken<CWeaponDescription>&
EProjectileAttrib::BigProjectile ? 0.25f : 0.1f), EProjectileAttrib::BigProjectile ? 0.25f : 0.1f),
x2c0_homingTargetId(homingTarget), x2cc_wpscId(wDesc.GetObjectTag()->id) x2c0_homingTargetId(homingTarget), x2cc_wpscId(wDesc.GetObjectTag()->id)
{ {
x2e4_24_ = true; x2e4_24_active = true;
x2e4_25_startedUnderwater = underwater; x2e4_25_startedUnderwater = underwater;
x2e4_26_waterUpdate = underwater; x2e4_26_waterUpdate = underwater;
x2e4_27_inWater = underwater; x2e4_27_inWater = underwater;
@ -95,7 +95,7 @@ void CGameProjectile::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId /*uid*
DeleteProjectileLight(mgr); DeleteProjectileLight(mgr);
} }
CWeapon::EProjectileAttrib CGameProjectile::GetBeamAttribType(EWeaponType wType) EProjectileAttrib CGameProjectile::GetBeamAttribType(EWeaponType wType)
{ {
if (wType == EWeaponType::Ice) if (wType == EWeaponType::Ice)
return EProjectileAttrib::Ice; return EProjectileAttrib::Ice;
@ -200,7 +200,7 @@ void CGameProjectile::Chase(float dt, CStateManager& mgr)
void CGameProjectile::UpdateHoming(float dt, CStateManager& mgr) void CGameProjectile::UpdateHoming(float dt, CStateManager& mgr)
{ {
if (!x2e4_24_ || x2c0_homingTargetId == kInvalidUniqueId || x2a8_homingDt <= 0.f) if (!x2e4_24_active || x2c0_homingTargetId == kInvalidUniqueId || x2a8_homingDt <= 0.f)
return; return;
x2b0_targetHomingTime += dt; x2b0_targetHomingTime += dt;
@ -229,7 +229,7 @@ CRayCastResult
CGameProjectile::DoCollisionCheck(TUniqueId& idOut, CStateManager& mgr) CGameProjectile::DoCollisionCheck(TUniqueId& idOut, CStateManager& mgr)
{ {
CRayCastResult res; CRayCastResult res;
if (x2e4_24_) if (x2e4_24_active)
{ {
zeus::CVector3f posDelta = x34_transform.origin - x298_lastOrigin; zeus::CVector3f posDelta = x34_transform.origin - x298_lastOrigin;
rstl::reserved_vector<TUniqueId, 1024> nearList; rstl::reserved_vector<TUniqueId, 1024> nearList;

View File

@ -50,7 +50,7 @@ protected:
{ {
struct struct
{ {
bool x2e4_24_ : 1; bool x2e4_24_active : 1;
bool x2e4_25_startedUnderwater : 1; bool x2e4_25_startedUnderwater : 1;
bool x2e4_26_waterUpdate : 1; bool x2e4_26_waterUpdate : 1;
bool x2e4_27_inWater : 1; bool x2e4_27_inWater : 1;

View File

@ -229,11 +229,11 @@ void CGunWeapon::Fire(bool underwater, float dt, EChargeState chargeState, const
CDamageInfo dInfo = GetDamageInfo(mgr, chargeState, chargeFactor1); CDamageInfo dInfo = GetDamageInfo(mgr, chargeState, chargeFactor1);
zeus::CVector3f scale(chargeState == EChargeState::Normal ? 1.f : chargeFactor2); zeus::CVector3f scale(chargeState == EChargeState::Normal ? 1.f : chargeFactor2);
bool partialCharge = chargeState == EChargeState::Normal ? false : !zeus::close_enough(chargeFactor1, 1.f); bool partialCharge = chargeState == EChargeState::Normal ? false : !zeus::close_enough(chargeFactor1, 1.f);
CWeapon::EProjectileAttrib attribs = CWeapon::EProjectileAttrib::ArmCannon; EProjectileAttrib attribs = EProjectileAttrib::ArmCannon;
if (partialCharge) if (partialCharge)
attribs |= CWeapon::EProjectileAttrib::PartialCharge; attribs |= EProjectileAttrib::PartialCharge;
if (chargeState == EChargeState::Charged) if (chargeState == EChargeState::Charged)
attribs |= CWeapon::EProjectileAttrib::Charged; attribs |= EProjectileAttrib::Charged;
CEnergyProjectile* proj = new CEnergyProjectile(true, x144_weapons[int(chargeState)], x1c0_weaponType, CEnergyProjectile* proj = new CEnergyProjectile(true, x144_weapons[int(chargeState)], x1c0_weaponType,
xf, x1c8_playerMaterial, dInfo, mgr.AllocateUniqueId(), xf, x1c8_playerMaterial, dInfo, mgr.AllocateUniqueId(),

View File

@ -304,8 +304,7 @@ void CPlayerGun::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CSt
bool metroidAttached = false; bool metroidAttached = false;
if (TCastToConstPtr<CEnergyProjectile> proj = mgr.GetObjectById(sender)) if (TCastToConstPtr<CEnergyProjectile> proj = mgr.GetObjectById(sender))
{ {
if ((proj->GetAttribField() & CGameProjectile::EProjectileAttrib::BigStrike) != if ((proj->GetAttribField() & EProjectileAttrib::BigStrike) == EProjectileAttrib::BigStrike)
CGameProjectile::EProjectileAttrib::None)
{ {
x394_damageTimer = proj->GetDamageDuration(); x394_damageTimer = proj->GetDamageDuration();
bigStrike = true; bigStrike = true;
@ -1528,7 +1527,7 @@ void CPlayerGun::FireSecondary(float dt, CStateManager& mgr)
fireXf.origin += mgr.GetCameraManager()->GetGlobalCameraTranslation(mgr); fireXf.origin += mgr.GetCameraManager()->GetGlobalCameraTranslation(mgr);
x744_auxWeapon->Fire(dt, x834_27_underwater, x310_currentBeam, x330_chargeState, fireXf, x744_auxWeapon->Fire(dt, x834_27_underwater, x310_currentBeam, x330_chargeState, fireXf,
mgr, x72c_currentBeam->GetWeaponType(), targetId); mgr, x72c_currentBeam->GetWeaponType(), targetId);
mgr.InformListeners(x4a8_gunWorldXf.origin, EListenNoiseType::Zero); mgr.InformListeners(x4a8_gunWorldXf.origin, EListenNoiseType::Character);
x3a0_missileExitTimer = 7.f; x3a0_missileExitTimer = 7.f;
if (!x832_26_comboFiring) if (!x832_26_comboFiring)
{ {
@ -1654,7 +1653,7 @@ void CPlayerGun::UpdateNormalShotCycle(float dt, CStateManager& mgr)
homingTarget = kInvalidUniqueId; homingTarget = kInvalidUniqueId;
x72c_currentBeam->Fire(x834_27_underwater, dt, x330_chargeState, xf, mgr, homingTarget, x72c_currentBeam->Fire(x834_27_underwater, dt, x330_chargeState, xf, mgr, homingTarget,
x340_chargeBeamFactor, x340_chargeBeamFactor); x340_chargeBeamFactor, x340_chargeBeamFactor);
mgr.InformListeners(x4a8_gunWorldXf.origin, EListenNoiseType::Zero); mgr.InformListeners(x4a8_gunWorldXf.origin, EListenNoiseType::Character);
} }
void CPlayerGun::ProcessNormalState(u32 releasedStates, u32 pressedStates, CStateManager& mgr, float dt) void CPlayerGun::ProcessNormalState(u32 releasedStates, u32 pressedStates, CStateManager& mgr, float dt)

View File

@ -1,6 +1,8 @@
#include "CProjectileWeapon.hpp" #include "CProjectileWeapon.hpp"
#include "Graphics/CModel.hpp" #include "Graphics/CModel.hpp"
#include "Particle/CParticleGlobals.hpp" #include "Particle/CParticleGlobals.hpp"
#include "GameGlobalObjects.hpp"
#include "Graphics/CBooRenderer.hpp"
namespace urde namespace urde
{ {
@ -89,6 +91,61 @@ zeus::CVector3f CProjectileWeapon::GetTranslation() const
return x14_localToWorldXf * (x44_localXf * x8c_projOffset + x80_localOffset) + x74_worldOffset; return x14_localToWorldXf * (x44_localXf * x8c_projOffset + x80_localOffset) + x74_worldOffset;
} }
rstl::optional_object<zeus::CAABox> CProjectileWeapon::GetBounds() const
{
zeus::CAABox aabb;
bool ret = false;
if (xfc_APSMGen)
{
if (auto b = xfc_APSMGen->GetBounds())
{
aabb.accumulateBounds(*b);
ret = true;
}
}
if (x100_APS2Gen)
{
if (auto b = x100_APS2Gen->GetBounds())
{
aabb.accumulateBounds(*b);
ret = true;
}
}
if (x118_swoosh1)
{
if (auto b = x118_swoosh1->GetBounds())
{
aabb.accumulateBounds(*b);
ret = true;
}
}
if (x11c_swoosh2)
{
if (auto b = x11c_swoosh2->GetBounds())
{
aabb.accumulateBounds(*b);
ret = true;
}
}
if (x120_swoosh3)
{
if (auto b = x120_swoosh3->GetBounds())
{
aabb.accumulateBounds(*b);
ret = true;
}
}
if (ret)
return {aabb};
return {};
}
float CProjectileWeapon::GetAudibleFallOff() const float CProjectileWeapon::GetAudibleFallOff() const
{ {
if (!x4_weaponDesc->x94_COLR) if (!x4_weaponDesc->x94_COLR)
@ -119,15 +176,15 @@ u16 CProjectileWeapon::GetSoundIdForCollision(EWeaponCollisionResponseTypes type
} }
rstl::optional_object<TLockedToken<CGenDescription>> rstl::optional_object<TLockedToken<CGenDescription>>
CProjectileWeapon::CollisionOccured(EWeaponCollisionResponseTypes type, bool alive, bool b2, CProjectileWeapon::CollisionOccured(EWeaponCollisionResponseTypes type, bool deflected, bool useTarget,
const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& pos, const zeus::CVector3f& normal,
const zeus::CVector3f& target) const zeus::CVector3f& target)
{ {
x80_localOffset = x14_localToWorldXf.transposeRotate(v1 - x74_worldOffset) - x8c_projOffset; x80_localOffset = x14_localToWorldXf.transposeRotate(pos - x74_worldOffset) - x8c_projOffset;
zeus::CVector3f posToTarget = target - GetTranslation(); zeus::CVector3f posToTarget = target - GetTranslation();
if (alive) if (deflected)
{ {
if (b2 && posToTarget.canBeNormalized()) if (useTarget && posToTarget.canBeNormalized())
{ {
SetWorldSpaceOrientation(zeus::lookAt(zeus::CVector3f::skZero, posToTarget.normalized())); SetWorldSpaceOrientation(zeus::lookAt(zeus::CVector3f::skZero, posToTarget.normalized()));
} }
@ -135,7 +192,7 @@ CProjectileWeapon::CollisionOccured(EWeaponCollisionResponseTypes type, bool ali
{ {
zeus::CTransform xf = GetTransform(); zeus::CTransform xf = GetTransform();
SetWorldSpaceOrientation( SetWorldSpaceOrientation(
zeus::lookAt(zeus::CVector3f::skZero, xf.basis[1] - v2 * (v2.dot(xf.basis[1]) * 2.f), v2)); zeus::lookAt(zeus::CVector3f::skZero, xf.basis[1] - normal * (normal.dot(xf.basis[1]) * 2.f), normal));
} }
return {}; return {};
} }
@ -174,20 +231,20 @@ void CProjectileWeapon::RenderParticles() const
x104_->Render(); x104_->Render();
} }
void CProjectileWeapon::UpdateParticles(double dt) void CProjectileWeapon::AddToRenderer() const
{ {
if (xfc_APSMGen) if (xfc_APSMGen)
xfc_APSMGen->Update(dt); g_Renderer->AddParticleGen(*xfc_APSMGen);
if (x100_APS2Gen) if (x100_APS2Gen)
x100_APS2Gen->Update(dt); g_Renderer->AddParticleGen(*x100_APS2Gen);
if (x118_swoosh1) if (x118_swoosh1)
x118_swoosh1->Update(dt); g_Renderer->AddParticleGen(*x118_swoosh1);
if (x11c_swoosh2) if (x11c_swoosh2)
x11c_swoosh2->Update(dt); g_Renderer->AddParticleGen(*x11c_swoosh2);
if (x120_swoosh3) if (x120_swoosh3)
x120_swoosh3->Update(dt); g_Renderer->AddParticleGen(*x120_swoosh3);
if (x104_) if (x104_)
x104_->Update(dt); g_Renderer->AddParticleGen(*x104_);
} }
void CProjectileWeapon::Render() const void CProjectileWeapon::Render() const

View File

@ -70,6 +70,7 @@ public:
const zeus::CTransform& orient, const zeus::CVector3f& scale, s32); const zeus::CTransform& orient, const zeus::CVector3f& scale, s32);
virtual ~CProjectileWeapon() = default; virtual ~CProjectileWeapon() = default;
bool IsProjectileActive() const { return x124_24_active; } bool IsProjectileActive() const { return x124_24_active; }
rstl::optional_object<zeus::CAABox> GetBounds() const;
const zeus::CVector3f& GetVelocity() const { return xb0_velocity; } const zeus::CVector3f& GetVelocity() const { return xb0_velocity; }
void SetVelocity(const zeus::CVector3f& vel) { xb0_velocity = vel; } void SetVelocity(const zeus::CVector3f& vel) { xb0_velocity = vel; }
float GetMaxTurnRate() const { return xe0_maxTurnRate; } float GetMaxTurnRate() const { return xe0_maxTurnRate; }
@ -79,11 +80,11 @@ public:
GetDecalForCollision(EWeaponCollisionResponseTypes type) const; GetDecalForCollision(EWeaponCollisionResponseTypes type) const;
u16 GetSoundIdForCollision(EWeaponCollisionResponseTypes type) const; u16 GetSoundIdForCollision(EWeaponCollisionResponseTypes type) const;
rstl::optional_object<TLockedToken<CGenDescription>> rstl::optional_object<TLockedToken<CGenDescription>>
CollisionOccured(EWeaponCollisionResponseTypes type, bool alive, bool b2, const zeus::CVector3f& v1, CollisionOccured(EWeaponCollisionResponseTypes type, bool deflected, bool useTarget, const zeus::CVector3f& pos,
const zeus::CVector3f& v2, const zeus::CVector3f& target); const zeus::CVector3f& normal, const zeus::CVector3f& target);
TLockedToken<CWeaponDescription> GetWeaponDescription() const { return x4_weaponDesc; } TLockedToken<CWeaponDescription> GetWeaponDescription() const { return x4_weaponDesc; }
void RenderParticles() const; void RenderParticles() const;
virtual void UpdateParticles(double dt); virtual void AddToRenderer() const;
virtual void Render() const; virtual void Render() const;
bool IsSystemDeletable() const; bool IsSystemDeletable() const;
void UpdateChildParticleSystems(float); void UpdateChildParticleSystems(float);
@ -97,6 +98,7 @@ public:
void SetGravity(const zeus::CVector3f& grav) { xbc_gravity = grav; } void SetGravity(const zeus::CVector3f& grav) { xbc_gravity = grav; }
static void SetGlobalSeed(u16 seed) { g_GlobalSeed = seed; } static void SetGlobalSeed(u16 seed) { g_GlobalSeed = seed; }
CElementGen* GetAttachedPS1() const { return xfc_APSMGen.get(); } CElementGen* GetAttachedPS1() const { return xfc_APSMGen.get(); }
double GameTime() const { return xd0_curTime; }
}; };
} }

View File

@ -1,7 +1,3 @@
//
// Created by Jack Andersen on 2/10/18.
//
#include "CTargetableProjectile.hpp" #include "CTargetableProjectile.hpp"
namespace urde namespace urde

View File

@ -80,7 +80,7 @@ void CWaveBeam::Fire(bool underwater, float dt, EChargeState chargeState, const
zeus::CTransform shotXf = xf * zeus::CTransform::RotateY(zeus::degToRad((randAng + i) * skShotAnglePitch)); zeus::CTransform shotXf = xf * zeus::CTransform::RotateY(zeus::degToRad((randAng + i) * skShotAnglePitch));
CEnergyProjectile* proj = new CEnergyProjectile(true, weaponDesc, x1c0_weaponType, shotXf, CEnergyProjectile* proj = new CEnergyProjectile(true, weaponDesc, x1c0_weaponType, shotXf,
x1c8_playerMaterial, GetDamageInfo(mgr, chargeState, chargeFactor1),mgr.AllocateUniqueId(), x1c8_playerMaterial, GetDamageInfo(mgr, chargeState, chargeFactor1),mgr.AllocateUniqueId(),
kInvalidAreaId, x1c4_playerId, homingTarget, CWeapon::EProjectileAttrib::ArmCannon, underwater, kInvalidAreaId, x1c4_playerId, homingTarget, EProjectileAttrib::ArmCannon, underwater,
zeus::CVector3f::skOne, {}, -1, false); zeus::CVector3f::skOne, {}, -1, false);
mgr.AddObject(proj); mgr.AddObject(proj);
proj->Think(dt, mgr); proj->Think(dt, mgr);

View File

@ -46,7 +46,7 @@ void CWeapon::Render(const CStateManager&) const
} }
EWeaponCollisionResponseTypes CWeapon::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, EWeaponCollisionResponseTypes CWeapon::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
const CWeaponMode&, int) const const CWeaponMode&, EProjectileAttrib) const
{ {
return EWeaponCollisionResponseTypes::Projectile; return EWeaponCollisionResponseTypes::Projectile;
} }

View File

@ -10,30 +10,6 @@ namespace urde
{ {
class CWeapon : public CActor class CWeapon : public CActor
{ {
public:
enum class EProjectileAttrib
{
None = 0,
PartialCharge = (1 << 0),
PlasmaProjectile = (1 << 1),
Charged = (1 << 2),
Ice = (1 << 3),
Wave = (1 << 4),
Plasma = (1 << 5),
Phazon = (1 << 6),
ComboShot = (1 << 7),
Bombs = (1 << 8),
PowerBombs = (1 << 9),
BigProjectile = (1 << 10),
ArmCannon = (1 << 11),
BigStrike = (1 << 12),
DamageFalloff = (1 << 13),
StaticInterference = (1 << 14),
PlayerUnFreeze = (1 << 15),
ParticleOPTS = (1 << 16),
KeepInCinematic = (1 << 17),
};
protected: protected:
EProjectileAttrib xe8_projectileAttribs; EProjectileAttrib xe8_projectileAttribs;
TUniqueId xec_ownerId; TUniqueId xec_ownerId;
@ -70,9 +46,8 @@ public:
void Think(float, CStateManager &); void Think(float, CStateManager &);
void Render(const CStateManager&) const; void Render(const CStateManager&) const;
EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
const CWeaponMode&, int) const; const CWeaponMode&, EProjectileAttrib) const;
void FluidFXThink(EFluidState state, CScriptWater& water, CStateManager& mgr); void FluidFXThink(EFluidState state, CScriptWater& water, CStateManager& mgr);
}; };
ENABLE_BITWISE_ENUM(CWeapon::EProjectileAttrib)
} }
#endif // __URDE_CWEAPON_HPP__ #endif // __URDE_CWEAPON_HPP__

View File

@ -34,6 +34,30 @@ enum class EWeaponType
OrangePhazon = 14 OrangePhazon = 14
}; };
enum class EProjectileAttrib
{
None = 0,
PartialCharge = (1 << 0),
PlasmaProjectile = (1 << 1),
Charged = (1 << 2),
Ice = (1 << 3),
Wave = (1 << 4),
Plasma = (1 << 5),
Phazon = (1 << 6),
ComboShot = (1 << 7),
Bombs = (1 << 8),
PowerBombs = (1 << 9),
BigProjectile = (1 << 10),
ArmCannon = (1 << 11),
BigStrike = (1 << 12),
DamageFalloff = (1 << 13),
StaticInterference = (1 << 14),
PlayerUnFreeze = (1 << 15),
ParticleOPTS = (1 << 16),
KeepInCinematic = (1 << 17),
};
ENABLE_BITWISE_ENUM(EProjectileAttrib)
namespace NWeaponTypes namespace NWeaponTypes
{ {

View File

@ -368,9 +368,9 @@ const zeus::CTransform CActor::GetLocatorTransform(std::string_view segName) con
} }
EWeaponCollisionResponseTypes CActor::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, EWeaponCollisionResponseTypes CActor::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
const CWeaponMode&, s32) const const CWeaponMode&, EProjectileAttrib) const
{ {
return EWeaponCollisionResponseTypes::Unknown13; return EWeaponCollisionResponseTypes::OtherProjectile;
} }
void CActor::FluidFXThink(CActor::EFluidState, CScriptWater&, CStateManager&) {} void CActor::FluidFXThink(CActor::EFluidState, CScriptWater&, CStateManager&) {}

View File

@ -11,6 +11,7 @@
#include "Collision/CCollisionResponseData.hpp" #include "Collision/CCollisionResponseData.hpp"
#include "Audio/CSfxManager.hpp" #include "Audio/CSfxManager.hpp"
#include "CScannableObjectInfo.hpp" #include "CScannableObjectInfo.hpp"
#include "Weapon/WeaponCommon.hpp"
namespace urde namespace urde
{ {
@ -127,7 +128,7 @@ public:
virtual zeus::CVector3f GetHomingPosition(const CStateManager&, float) const; virtual zeus::CVector3f GetHomingPosition(const CStateManager&, float) const;
virtual zeus::CVector3f GetScanObjectIndicatorPosition(const CStateManager&) const; virtual zeus::CVector3f GetScanObjectIndicatorPosition(const CStateManager&) const;
virtual EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, virtual EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
const CWeaponMode&, int) const; const CWeaponMode&, EProjectileAttrib) const;
virtual void FluidFXThink(EFluidState, CScriptWater&, CStateManager&); virtual void FluidFXThink(EFluidState, CScriptWater&, CStateManager&);
virtual void OnScanStateChanged(EScanState, CStateManager&); virtual void OnScanStateChanged(EScanState, CStateManager&);
virtual zeus::CAABox GetSortingBounds(const CStateManager&) const; virtual zeus::CAABox GetSortingBounds(const CStateManager&) const;

View File

@ -17,7 +17,9 @@ namespace urde
enum class EListenNoiseType enum class EListenNoiseType
{ {
Zero Character,
Bomb,
Projectile
}; };
enum class EKnockBackType enum class EKnockBackType

View File

@ -29,7 +29,7 @@ CDamageInfo& CDamageInfo::operator=(const DataSpec::SShotParam& other)
float CDamageInfo::GetDamage(const CDamageVulnerability& dVuln) const float CDamageInfo::GetDamage(const CDamageVulnerability& dVuln) const
{ {
EVulnerability vuln = dVuln.GetVulnerability(x0_weaponMode, false); EVulnerability vuln = dVuln.GetVulnerability(x0_weaponMode, false);
if (vuln == EVulnerability::Reflect) if (vuln == EVulnerability::Deflect)
return 0.f; return 0.f;
else if (vuln == EVulnerability::DoubleDamage) else if (vuln == EVulnerability::DoubleDamage)
return 2.f * x8_damage; return 2.f * x8_damage;
@ -40,7 +40,7 @@ float CDamageInfo::GetDamage(const CDamageVulnerability& dVuln) const
float CDamageInfo::GetRadiusDamage(const CDamageVulnerability& dVuln) const float CDamageInfo::GetRadiusDamage(const CDamageVulnerability& dVuln) const
{ {
EVulnerability vuln = dVuln.GetVulnerability(x0_weaponMode, false); EVulnerability vuln = dVuln.GetVulnerability(x0_weaponMode, false);
if (vuln == EVulnerability::Reflect) if (vuln == EVulnerability::Deflect)
return 0.f; return 0.f;
else if (vuln == EVulnerability::DoubleDamage) else if (vuln == EVulnerability::DoubleDamage)
return 2.f * xc_radiusDamage; return 2.f * xc_radiusDamage;

View File

@ -12,20 +12,20 @@ const CDamageVulnerability CDamageVulnerability::sNormalVulnerability(
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EVulnerability::DoubleDamage); EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EVulnerability::DoubleDamage);
const CDamageVulnerability CDamageVulnerability::sImmuneVulnerability( const CDamageVulnerability CDamageVulnerability::sImmuneVulnerability(
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::DoubleDamage); EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::DoubleDamage);
/* LOL, thanks retro */ /* LOL, thanks retro */
const CDamageVulnerability CDamageVulnerability::sReflectVulnerability( const CDamageVulnerability CDamageVulnerability::sReflectVulnerability(
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::DoubleDamage); EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::DoubleDamage);
const CDamageVulnerability CDamageVulnerability::sPassThroughVulnerability( const CDamageVulnerability CDamageVulnerability::sPassThroughVulnerability(
EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough,
@ -54,25 +54,25 @@ void CDamageVulnerability::ConstructNew(CInputStream& in, int propCount)
if (propCount < 15) if (propCount < 15)
{ {
for (int i = propCount; i < 15; ++i) for (int i = propCount; i < 15; ++i)
vulns[i] = EVulnerability::Reflect; vulns[i] = EVulnerability::Deflect;
} }
for (int i = 15; i < propCount; ++i) for (int i = 15; i < propCount; ++i)
in.readUint32Big(); in.readUint32Big();
x5c_ = EVulnerability(in.readUint32Big()); x5c_deflected = EVulnerability(in.readUint32Big());
EVulnerability* vulns2 = &x3c_chargedPower; EVulnerability* vulns2 = &x3c_chargedPower;
in.readUint32Big(); in.readUint32Big();
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
vulns2[i] = EVulnerability(in.readUint32Big()); vulns2[i] = EVulnerability(in.readUint32Big());
x60_chargedPhazon = EVulnerability(in.readUint32Big()); x60_chargedDeflected = EVulnerability(in.readUint32Big());
EVulnerability* vulns3 = &x4c_superMissile; EVulnerability* vulns3 = &x4c_superMissile;
in.readUint32Big(); in.readUint32Big();
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
vulns3[i] = EVulnerability(in.readUint32Big()); vulns3[i] = EVulnerability(in.readUint32Big());
x64_phazonCombo = EVulnerability(in.readUint32Big()); x64_comboDeflected = EVulnerability(in.readUint32Big());
} }
CDamageVulnerability::CDamageVulnerability(CInputStream& in) CDamageVulnerability::CDamageVulnerability(CInputStream& in)
@ -85,9 +85,9 @@ CDamageVulnerability::CDamageVulnerability(CInputStream& in)
vulns[i] = EVulnerability(in.readUint32Big()); vulns[i] = EVulnerability(in.readUint32Big());
if (propCount == 15) if (propCount == 15)
x5c_ = EVulnerability::DoubleDamage; x5c_deflected = EVulnerability::DoubleDamage;
else else
x5c_ = EVulnerability(in.readUint32Big()); x5c_deflected = EVulnerability(in.readUint32Big());
x3c_chargedPower = x0_power; x3c_chargedPower = x0_power;
x4c_superMissile = x0_power; x4c_superMissile = x0_power;
@ -110,7 +110,8 @@ CDamageVulnerability::CDamageVulnerability(EVulnerability power, EVulnerability
EVulnerability chargedPower, EVulnerability chargedIce, EVulnerability chargedPower, EVulnerability chargedIce,
EVulnerability chargedWave, EVulnerability chargedPlasma, EVulnerability chargedWave, EVulnerability chargedPlasma,
EVulnerability superMissile, EVulnerability iceSpreader, EVulnerability superMissile, EVulnerability iceSpreader,
EVulnerability waveBuster, EVulnerability flameThrower, EVulnerability v3) EVulnerability waveBuster, EVulnerability flameThrower,
EVulnerability deflected)
: x0_power(power) : x0_power(power)
, x4_ice(ice) , x4_ice(ice)
, x8_wave(wave) , x8_wave(wave)
@ -134,17 +135,17 @@ CDamageVulnerability::CDamageVulnerability(EVulnerability power, EVulnerability
, x50_iceSpreader(iceSpreader) , x50_iceSpreader(iceSpreader)
, x54_wavebuster(waveBuster) , x54_wavebuster(waveBuster)
, x58_flamethrower(flameThrower) , x58_flamethrower(flameThrower)
, x5c_(v3) , x5c_deflected(deflected)
{ {
} }
EVulnerability CDamageVulnerability::GetPhazonVulnerability(const CWeaponMode& mode) const EVulnerability CDamageVulnerability::GetDeflectionType(const CWeaponMode& mode) const
{ {
if (mode.IsCharged()) if (mode.IsCharged())
return x60_chargedPhazon; return x60_chargedDeflected;
if (mode.IsComboed()) if (mode.IsComboed())
return x64_phazonCombo; return x64_comboDeflected;
return x5c_; return x5c_deflected;
} }
bool CDamageVulnerability::WeaponHurts(const CWeaponMode& mode, bool ignoreDirect) const bool CDamageVulnerability::WeaponHurts(const CWeaponMode& mode, bool ignoreDirect) const
@ -238,7 +239,7 @@ bool CDamageVulnerability::WeaponHits(const CWeaponMode& mode, bool checkDirect)
EVulnerability CDamageVulnerability::GetVulnerability(const CWeaponMode& mode, bool ignoreDirect) const EVulnerability CDamageVulnerability::GetVulnerability(const CWeaponMode& mode, bool ignoreDirect) const
{ {
if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::OrangePhazon) if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::OrangePhazon)
return EVulnerability::Reflect; return EVulnerability::Deflect;
if (mode.IsInstantKill()) if (mode.IsInstantKill())
return EVulnerability::Normal; return EVulnerability::Normal;

View File

@ -11,7 +11,7 @@ enum class EVulnerability
{ {
DoubleDamage, DoubleDamage,
Normal, Normal,
Reflect, Deflect,
Immune, Immune,
PassThrough, PassThrough,
DirectDouble, DirectDouble,
@ -47,9 +47,9 @@ class CDamageVulnerability
EVulnerability x54_wavebuster; EVulnerability x54_wavebuster;
EVulnerability x58_flamethrower; EVulnerability x58_flamethrower;
EVulnerability x5c_; EVulnerability x5c_deflected;
EVulnerability x60_chargedPhazon; EVulnerability x60_chargedDeflected;
EVulnerability x64_phazonCombo; EVulnerability x64_comboDeflected;
void ConstructNew(CInputStream& in, int propCount); void ConstructNew(CInputStream& in, int propCount);
@ -67,9 +67,9 @@ public:
EVulnerability v2, EVulnerability chargedPower, EVulnerability chargedIce, EVulnerability v2, EVulnerability chargedPower, EVulnerability chargedIce,
EVulnerability chargedWave, EVulnerability chargedPlasma, EVulnerability superMissile, EVulnerability chargedWave, EVulnerability chargedPlasma, EVulnerability superMissile,
EVulnerability iceSpreader, EVulnerability waveBuster, EVulnerability flameThrower, EVulnerability iceSpreader, EVulnerability waveBuster, EVulnerability flameThrower,
EVulnerability v3); EVulnerability deflected);
EVulnerability GetPhazonVulnerability(const CWeaponMode& mode) const; EVulnerability GetDeflectionType(const CWeaponMode& mode) const;
bool WeaponHurts(const CWeaponMode&, bool ignoreDirect) const; bool WeaponHurts(const CWeaponMode&, bool ignoreDirect) const;
bool WeaponHits(const CWeaponMode& mode, bool checkDirect) const; bool WeaponHits(const CWeaponMode& mode, bool checkDirect) const;

View File

@ -0,0 +1,20 @@
#include "CIceImpact.hpp"
#include "TCastTo.hpp"
namespace urde
{
CIceImpact::CIceImpact(const TLockedToken<CGenDescription>& particle, TUniqueId uid, TAreaId aid,
bool active, std::string_view name, const zeus::CTransform& xf, u32 flags,
const zeus::CVector3f& scale, const zeus::CColor& color)
: CEffect(uid, CEntityInfo(aid, CEntity::NullConnectionList), active, name, xf)
{
}
void CIceImpact::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
}

View File

@ -0,0 +1,20 @@
#ifndef CICEIMPACT_HPP
#define CICEIMPACT_HPP
#include "CEffect.hpp"
namespace urde
{
class CIceImpact : public CEffect
{
public:
CIceImpact(const TLockedToken<CGenDescription>& particle, TUniqueId uid, TAreaId aid,
bool active, std::string_view name, const zeus::CTransform& xf, u32 flags,
const zeus::CVector3f& scale, const zeus::CColor& color);
void Accept(IVisitor& visitor);
};
}
#endif // CICEIMPACT_HPP

View File

@ -2902,8 +2902,8 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState
case EScriptObjectMessage::Damage: case EScriptObjectMessage::Damage:
if (TCastToPtr<CEnergyProjectile> energ = mgr.ObjectById(sender)) if (TCastToPtr<CEnergyProjectile> energ = mgr.ObjectById(sender))
{ {
if ((energ->GetAttribField() & CWeapon::EProjectileAttrib::StaticInterference) != if ((energ->GetAttribField() & EProjectileAttrib::StaticInterference) !=
CWeapon::EProjectileAttrib::None) EProjectileAttrib::None)
{ {
mgr.GetPlayerState()->GetStaticInterference(). mgr.GetPlayerState()->GetStaticInterference().
AddSource(GetUniqueId(), 0.3f, energ->GetInterferenceDuration()); AddSource(GetUniqueId(), 0.3f, energ->GetInterferenceDuration());

View File

@ -181,12 +181,12 @@ zeus::CAABox CScriptActor::GetSortingBounds(const CStateManager& mgr) const
EWeaponCollisionResponseTypes EWeaponCollisionResponseTypes
CScriptActor::GetCollisionResponseType(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const CScriptActor::GetCollisionResponseType(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const
CWeaponMode& wMode, int w) const CWeaponMode& wMode, EProjectileAttrib w) const
{ {
const CDamageVulnerability* dVuln = GetDamageVulnerability(); const CDamageVulnerability* dVuln = GetDamageVulnerability();
if (dVuln->GetVulnerability(wMode, false) == EVulnerability::Reflect) if (dVuln->GetVulnerability(wMode, false) == EVulnerability::Deflect)
{ {
EVulnerability phazonVuln = dVuln->GetPhazonVulnerability(wMode); EVulnerability phazonVuln = dVuln->GetDeflectionType(wMode);
if (phazonVuln < EVulnerability::PassThrough && phazonVuln >= EVulnerability::Normal) if (phazonVuln < EVulnerability::PassThrough && phazonVuln >= EVulnerability::Normal)
return EWeaponCollisionResponseTypes::Unknown15; return EWeaponCollisionResponseTypes::Unknown15;
} }

View File

@ -41,7 +41,7 @@ public:
void PreRender(CStateManager&, const zeus::CFrustum&); void PreRender(CStateManager&, const zeus::CFrustum&);
zeus::CAABox GetSortingBounds(const CStateManager&) const; zeus::CAABox GetSortingBounds(const CStateManager&) const;
EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
const CWeaponMode&, int) const; const CWeaponMode&, EProjectileAttrib) const;
rstl::optional_object<zeus::CAABox> GetTouchBounds() const; rstl::optional_object<zeus::CAABox> GetTouchBounds() const;
void Touch(CActor&, CStateManager&); void Touch(CActor&, CStateManager&);
const CDamageVulnerability* GetDamageVulnerability() const { return &x268_damageVulnerability; } const CDamageVulnerability* GetDamageVulnerability() const { return &x268_damageVulnerability; }

View File

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

View File

@ -116,9 +116,9 @@ void CScriptDamageableTrigger::AcceptScriptMsg(EScriptObjectMessage msg, TUnique
EWeaponCollisionResponseTypes EWeaponCollisionResponseTypes
CScriptDamageableTrigger::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, CScriptDamageableTrigger::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
const CWeaponMode& weapMode, int) const const CWeaponMode& weapMode, EProjectileAttrib) const
{ {
return x174_dVuln.WeaponHurts(weapMode, false) ? EWeaponCollisionResponseTypes::Unknown13 : return x174_dVuln.WeaponHurts(weapMode, false) ? EWeaponCollisionResponseTypes::OtherProjectile :
EWeaponCollisionResponseTypes::Unknown15; EWeaponCollisionResponseTypes::Unknown15;
} }

View File

@ -55,7 +55,7 @@ public:
void Accept(IVisitor& visitor); void Accept(IVisitor& visitor);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
const CWeaponMode&, int) const; const CWeaponMode&, EProjectileAttrib) const;
void Render(const CStateManager& mgr) const; void Render(const CStateManager& mgr) const;
void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const; void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const;
void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum); void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum);

View File

@ -53,4 +53,15 @@ bool CScriptPlatform::IsRider(TUniqueId id) const
return true; return true;
return false; return false;
} }
bool CScriptPlatform::IsSlave(TUniqueId id) const
{
auto search = std::find_if(x328_slaves1.begin(), x328_slaves1.end(),
[id](const SRiders& rider){ return rider.x0_uid == id; });
if (search != x328_slaves1.end())
return true;
search = std::find_if(x338_slaves2.begin(), x338_slaves2.end(),
[id](const SRiders& rider){ return rider.x0_uid == id; });
return search != x338_slaves2.end();
}
} }

View File

@ -37,8 +37,8 @@ class CScriptPlatform : public CPhysicsActor
rstl::optional_object<TLockedToken<CCollidableOBBTreeGroupContainer>> x304_treeGroupContainer; rstl::optional_object<TLockedToken<CCollidableOBBTreeGroupContainer>> x304_treeGroupContainer;
std::unique_ptr<CCollidableOBBTreeGroup> x314_treeGroup; std::unique_ptr<CCollidableOBBTreeGroup> x314_treeGroup;
std::vector<SRiders> x318_riders; std::vector<SRiders> x318_riders;
std::vector<SRiders> x328_; std::vector<SRiders> x328_slaves1;
std::vector<SRiders> x338_; std::vector<SRiders> x338_slaves2;
float x348_; float x348_;
u32 x34c_; u32 x34c_;
u32 x350_; u32 x350_;
@ -68,10 +68,11 @@ public:
void Accept(IVisitor& visitor); void Accept(IVisitor& visitor);
rstl::optional_object<zeus::CAABox> GetTouchBounds() const; rstl::optional_object<zeus::CAABox> GetTouchBounds() const;
bool IsRider(TUniqueId id) const; bool IsRider(TUniqueId id) const;
std::vector<SRiders>& GetX328() { return x328_; } bool IsSlave(TUniqueId id) const;
const std::vector<SRiders>& GetX328() const { return x328_; } std::vector<SRiders>& GetX328() { return x328_slaves1; }
std::vector<SRiders>& GetX338() { return x338_; } const std::vector<SRiders>& GetX328() const { return x328_slaves1; }
const std::vector<SRiders>& GetX338() const { return x338_; } std::vector<SRiders>& GetX338() { return x338_slaves2; }
const std::vector<SRiders>& GetX338() const { return x338_slaves2; }
void AddSlave(TUniqueId, CStateManager&) {} void AddSlave(TUniqueId, CStateManager&) {}
bool HasComplexCollision() const { return x314_treeGroup.operator bool(); } bool HasComplexCollision() const { return x314_treeGroup.operator bool(); }
}; };

View File

@ -284,10 +284,9 @@ void CScriptTrigger::Touch(CActor& act, CStateManager& mgr)
} }
else if (CWeapon* weap = TCastToPtr<CWeapon>(act)) else if (CWeapon* weap = TCastToPtr<CWeapon>(act))
{ {
if ((weap->GetAttribField() & CWeapon::EProjectileAttrib::Bombs) != CWeapon::EProjectileAttrib::None) if ((weap->GetAttribField() & EProjectileAttrib::Bombs) == EProjectileAttrib::Bombs)
testFlags |= ETriggerFlags::DetectBombs; testFlags |= ETriggerFlags::DetectBombs;
else if ((weap->GetAttribField() & CWeapon::EProjectileAttrib::PowerBombs) != else if ((weap->GetAttribField() & EProjectileAttrib::PowerBombs) == EProjectileAttrib::PowerBombs)
CWeapon::EProjectileAttrib::None)
testFlags |= ETriggerFlags::DetectPowerBombs; testFlags |= ETriggerFlags::DetectPowerBombs;
} }

View File

@ -547,7 +547,7 @@ zeus::CAABox CScriptWater::GetSortingBounds(const CStateManager& mgr) const
} }
EWeaponCollisionResponseTypes CScriptWater::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, EWeaponCollisionResponseTypes CScriptWater::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
const CWeaponMode&, int) const const CWeaponMode&, EProjectileAttrib) const
{ {
return EWeaponCollisionResponseTypes::Water; return EWeaponCollisionResponseTypes::Water;
} }

View File

@ -104,7 +104,7 @@ public:
void CalculateRenderBounds(); void CalculateRenderBounds();
zeus::CAABox GetSortingBounds(const CStateManager&) const; zeus::CAABox GetSortingBounds(const CStateManager&) const;
EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
const CWeaponMode&, int) const; const CWeaponMode&, EProjectileAttrib) const;
u16 GetSplashSound(float) const; u16 GetSplashSound(float) const;
const std::experimental::optional<TLockedToken<CGenDescription>>& GetSplashEffect(float) const; const std::experimental::optional<TLockedToken<CGenDescription>>& GetSplashEffect(float) const;