From 09878668963b8447292dcbbde7c721a7d07c2c0c Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Tue, 15 May 2018 18:07:38 -1000 Subject: [PATCH] Implement CScriptDebris; EVNT POI fixes --- DataSpec/DNAMP1/ScriptObjects/Debris.hpp | 22 +- .../DNAMP1/ScriptObjects/DebrisExtended.hpp | 60 +-- DataSpec/DNAMP1/ScriptObjects/Generator.hpp | 14 +- Editor/ViewManager.cpp | 2 +- Runtime/CStateManager.cpp | 1 + Runtime/Character/CActorLights.hpp | 2 + Runtime/Character/CPOINode.cpp | 14 +- Runtime/MP1/CFrontEndUI.cpp | 2 +- Runtime/MkCastTo.py | 1 + Runtime/World/CScriptDebris.cpp | 403 +++++++++++++++++- Runtime/World/CScriptDebris.hpp | 98 +++-- Runtime/World/CScriptGenerator.cpp | 86 ++-- Runtime/World/CScriptGenerator.hpp | 9 +- Runtime/World/ScriptLoader.cpp | 99 ++--- 14 files changed, 620 insertions(+), 193 deletions(-) diff --git a/DataSpec/DNAMP1/ScriptObjects/Debris.hpp b/DataSpec/DNAMP1/ScriptObjects/Debris.hpp index a028e7154..28daae50d 100644 --- a/DataSpec/DNAMP1/ScriptObjects/Debris.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/Debris.hpp @@ -15,20 +15,20 @@ struct Debris : IScriptObject Value location; Value orientation; Value scale; - Value unknown1; - Value unknown2; - Value unknown3; // CColor - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; + Value zImpulse; + Value velocity; + DNAColor endsColor; + Value mass; + Value restitution; + Value duration; + Value scaleType; + Value randomAngImpulse; UniqueID32 model; ActorParameters actorParameters; UniqueID32 particle; - Value unknown9; - Value unknown10; - Value unknown11; + Value particleScale; + Value b1; + Value active; void nameIDs(PAKRouter& pakRouter) const { diff --git a/DataSpec/DNAMP1/ScriptObjects/DebrisExtended.hpp b/DataSpec/DNAMP1/ScriptObjects/DebrisExtended.hpp index f1d2bfc02..13e6fc109 100644 --- a/DataSpec/DNAMP1/ScriptObjects/DebrisExtended.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/DebrisExtended.hpp @@ -15,41 +15,41 @@ struct DebrisExtended : IScriptObject Value location; Value orientation; Value scale; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; // CColor - Value unknown11; // CColor - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - Value unknown16; + Value linConeAngle; + Value linMinMag; + Value linMaxMag; + Value angMinMag; + Value angMaxMag; + Value minDuration; + Value maxDuration; + Value colorInT; + Value colorOutT; + DNAColor color; + DNAColor endsColor; + Value scaleOutT; + Value endScale; + Value restitution; + Value downwardSpeed; + Value localOffset; UniqueID32 model; ActorParameters actorParameters; UniqueID32 particle1; - Value unknown17; - Value unknown18; - Value unknown19; - Value unknown20; + Value particle1Scale; + Value particle1GlobalTranslation; + Value deferDeleteTillParticle1Done; + Value particle1Or; UniqueID32 particle2; - Value unknown21; - Value unknown22; - Value unknown23; - Value unknown24; + Value particle2Scale; + Value particle2GlobalTranslation; + Value deferDeleteTillParticle2Done; + Value particle2Or; UniqueID32 particle3; - Value unknown25; - Value unknown26; - Value unknown27; - Value unknown28; - Value unknown29; - Value unknown30; + Value particle3Scale; + Value particle3Or; + Value solid; + Value dieOnProjectile; + Value noBounce; + Value active; void nameIDs(PAKRouter& pakRouter) const { diff --git a/DataSpec/DNAMP1/ScriptObjects/Generator.hpp b/DataSpec/DNAMP1/ScriptObjects/Generator.hpp index e3837ebce..f41761244 100644 --- a/DataSpec/DNAMP1/ScriptObjects/Generator.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/Generator.hpp @@ -12,13 +12,13 @@ struct Generator : IScriptObject AT_DECL_DNA_YAML AT_DECL_DNAV String<-1> name; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; + Value spawnCount; + Value noReuseFollowers; + Value noInheritXf; + Value offset; + Value active; + Value minScale; + Value maxScale; }; } diff --git a/Editor/ViewManager.cpp b/Editor/ViewManager.cpp index c95b4e541..6efa33f7e 100644 --- a/Editor/ViewManager.cpp +++ b/Editor/ViewManager.cpp @@ -102,7 +102,7 @@ void ViewManager::TestGameView::think() "Total Objects: %i, Total Layers: %i, Total Active Layers: %i\n" "Active Layer bits: %s\n", pl.GetTranslation().x, pl.GetTranslation().y, pl.GetTranslation().z, plQ.w, plQ.x, plQ.y, - plQ.z, g_GameState->CurrentWorldAssetId().Value(), + plQ.z, u32(g_GameState->CurrentWorldAssetId().Value()), (tbl.IsLoaded() ? (" " + hecl::Char16ToUTF8(tbl->GetString(0))).c_str() : ""), aId, g_StateManager->GetAllObjectList().size(), layerStates->GetAreaLayerCount(aId), totalActive, layerBits.c_str())); diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index a0fc5e153..e1538f752 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -52,6 +52,7 @@ #include "GameGlobalObjects.hpp" #include "World/CScriptDoor.hpp" #include "World/CScriptDamageableTrigger.hpp" +#include "World/CScriptDebris.hpp" #include namespace urde diff --git a/Runtime/Character/CActorLights.hpp b/Runtime/Character/CActorLights.hpp index d503de2fb..5e81a51cd 100644 --- a/Runtime/Character/CActorLights.hpp +++ b/Runtime/Character/CActorLights.hpp @@ -92,6 +92,8 @@ public: bool HasShadowLight() const { return x29c_shadowLightArrIdx != -1; } s32 GetShadowLightArrIndex() const { return x29c_shadowLightArrIdx; } s32 GetShadowLightIndex() const { return x2a0_shadowLightIdx; } + u32 GetAreaUpdateFramePeriod() const { return x2a8_areaUpdateFramePeriod; } + void SetAreaUpdateFramePeriod(u32 p) { x2a8_areaUpdateFramePeriod = p; } }; } diff --git a/Runtime/Character/CPOINode.cpp b/Runtime/Character/CPOINode.cpp index 00e4a6243..972c9c975 100644 --- a/Runtime/Character/CPOINode.cpp +++ b/Runtime/Character/CPOINode.cpp @@ -74,9 +74,11 @@ u32 _getPOIList(const CCharAnimTime& time, { u32 idx = iterator + ret; if (idx < capacity) + { listOut[idx] = T::CopyNodeMinusStartTime(stream[passedCount], curTime); + ++ret; + } ++passedCount; - ++ret; if (passedCount < stream.size()) nodeTime = stream[passedCount].GetTime(); } @@ -97,13 +99,15 @@ u32 _getPOIList(const CCharAnimTime& time, for (u32 it = iterator ; it < stream.size() ; ++it) { - CCharAnimTime nodeTime = stream[ret].GetTime(); + CCharAnimTime nodeTime = stream[it].GetTime(); if (nodeTime > targetTime) return ret; u32 idx = iterator + ret; - if (idx < capacity) - listOut[idx] = T::CopyNodeMinusStartTime(stream[ret], curTime); - ++ret; + if (nodeTime >= curTime && idx < capacity) + { + listOut[idx] = T::CopyNodeMinusStartTime(stream[it], curTime); + ++ret; + } } return ret; diff --git a/Runtime/MP1/CFrontEndUI.cpp b/Runtime/MP1/CFrontEndUI.cpp index 533fa6405..d68e0e8a0 100644 --- a/Runtime/MP1/CFrontEndUI.cpp +++ b/Runtime/MP1/CFrontEndUI.cpp @@ -2006,7 +2006,7 @@ CFrontEndUI::CFrontEndUI() m->ResetGameState(); g_GameState->SetCurrentWorldId(g_ResFactory->TranslateOriginalToNew(g_DefaultWorldTag.id)); - g_GameState->CurrentWorldState().SetAreaId(7); + g_GameState->CurrentWorldState().SetAreaId(0); g_GameState->GameOptions().ResetToDefaults(); g_GameState->WriteBackupBuf(); diff --git a/Runtime/MkCastTo.py b/Runtime/MkCastTo.py index 2665d09e4..cc8a36be7 100644 --- a/Runtime/MkCastTo.py +++ b/Runtime/MkCastTo.py @@ -74,6 +74,7 @@ CENTITY_TYPES = ( ('CScriptSpindleCamera', 'World/CScriptSpindleCamera.hpp'), ('CWallCrawlerSwarm', 'World/CWallCrawlerSwarm.hpp'), ('CWeapon', 'Weapon/CWeapon.hpp'), + ('CScriptDebris', 'World/CScriptDebris.hpp'), ) def getqualified(tp): diff --git a/Runtime/World/CScriptDebris.cpp b/Runtime/World/CScriptDebris.cpp index 47b971949..758d48dd7 100644 --- a/Runtime/World/CScriptDebris.cpp +++ b/Runtime/World/CScriptDebris.cpp @@ -2,47 +2,420 @@ #include "Collision/CCollisionInfoList.hpp" #include "Particle/CElementGen.hpp" #include "TCastTo.hpp" +#include "GameGlobalObjects.hpp" +#include "CSimplePool.hpp" +#include "CStateManager.hpp" +#include "Graphics/CBooRenderer.hpp" namespace urde { CScriptDebris::CScriptDebris(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, - CModelData&& mData, const CActorParameters& aParams, CAssetId, const zeus::CVector3f&, - float, const zeus::CVector3f&, const zeus::CColor&, float f1, float f2, float f3, - CScriptDebris::EScaleType, bool, bool, bool active) + CModelData&& mData, const CActorParameters& aParams, CAssetId particleId, + const zeus::CVector3f& particleScale, float zImpulse, const zeus::CVector3f& velocity, + const zeus::CColor& endsColor, float mass, float restitution, float duration, + EScaleType scaleType, bool b1, bool randomAngImpulse, bool active) : CPhysicsActor(uid, active, name, info, xf, std::move(mData), CMaterialList(EMaterialTypes::Solid, EMaterialTypes::Debris), mData.GetBounds(xf.getRotation()), - SMoverData(f2), aParams, 0.3f, 0.1f) - + SMoverData(mass), aParams, 0.3f, 0.1f), x258_velocity(velocity), x264_color(1.f, 0.5f, 0.5f, 1.f), + x268_endsColor(endsColor), x26c_zImpulse(zImpulse), x274_duration(duration >= 0.f ? duration : 0.5f), + x278_ooDuration(1.f / x274_duration), x27c_restitution(restitution), + x280_scaleType(scaleType), x2b0_scale(mData.GetScale()), x2e0_speedAvg(2.f) { + x281_24_randomAngImpulse = randomAngImpulse; + if (scaleType == EScaleType::NoScale) + x2bc_endScale = mData.GetScale(); + else if (scaleType == EScaleType::EndsToZero) + x2bc_endScale = zeus::CVector3f::skZero; + else + x2bc_endScale.splat(5.f); + + xe7_30_doTargetDistanceTest = false; + + if (x90_actorLights) + x90_actorLights->SetAreaUpdateFramePeriod(x90_actorLights->GetAreaUpdateFramePeriod() * 2); + + SetUseInSortedLists(false); + + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, + {EMaterialTypes::Debris, EMaterialTypes::Character, EMaterialTypes::Player, EMaterialTypes::Projectile})); + + if (g_ResFactory->GetResourceTypeById(particleId)) + { + TToken desc = g_SimplePool->GetObj({FOURCC('PART'), particleId}); + x2d4_particleGens[0] = std::make_unique(desc, CElementGen::EModelOrientationType::Normal, + CElementGen::EOptionalSystemFlags::One); + x2d4_particleGens[0]->SetGlobalScale(particleScale); + } + + x150_momentum = zeus::CVector3f(0.f, 0.f, -24.525f * xe8_mass); + + if (x90_actorLights) + x90_actorLights->SetAmbientChannelOverflow(true); } CScriptDebris::CScriptDebris(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, - CModelData&& mData, const CActorParameters& aParams, float, float, float, float, float, - float, float, float, float, const zeus::CColor&, const zeus::CColor&, float, - const zeus::CVector3f&, const zeus::CVector3f&, float, float, const zeus::CVector3f&, - CAssetId, const zeus::CVector3f&, bool, bool, CScriptDebris::EOrientationType, CAssetId, - const zeus::CVector3f&, bool, bool, CScriptDebris::EOrientationType, CAssetId, - const zeus::CVector3f&, CScriptDebris::EOrientationType, bool, bool, bool, bool active) + CModelData&& mData, const CActorParameters& aParams, float linConeAngle, float linMinMag, + float linMaxMag, float angMinMag, float angMaxMag, float minDuration, float maxDuration, + float colorInT, float colorOutT, const zeus::CColor& color, const zeus::CColor& endsColor, + float scaleOutStartT, const zeus::CVector3f& scale, const zeus::CVector3f& endScale, + float restitution, float downwardSpeed, const zeus::CVector3f& localOffset, + CAssetId particle1, const zeus::CVector3f& particle1Scale, bool particle1GlobalTranslation, + bool deferDeleteTillParticle1Done, EOrientationType particle1Or, + CAssetId particle2, const zeus::CVector3f& particle2Scale, bool particle2GlobalTranslation, + bool deferDeleteTillParticle2Done, EOrientationType particle2Or, + CAssetId particle3, const zeus::CVector3f& particle3Scale, EOrientationType particle3Or, + bool solid, bool dieOnProjectile, bool noBounce, bool active) : CPhysicsActor( uid, active, name, info, xf, std::move(mData), CMaterialList(EMaterialTypes::Solid, EMaterialTypes::Debris), (mData.HasAnimData() || mData.HasNormalModel() ? mData.GetBounds(xf.getRotation()) : zeus::CAABox{-0.5f, 0.5f}), - SMoverData(1.f), aParams, 0.3f, 0.1f) + SMoverData(1.f), aParams, 0.3f, 0.1f), x264_color(color), x268_endsColor(endsColor), + x27c_restitution(restitution), x288_linConeAngle(linConeAngle), x28c_linMinMag(linMinMag), x290_linMaxMag(linMaxMag), + x294_angMinMag(angMinMag), x298_angMaxMag(angMaxMag), x29c_minDuration(minDuration), x2a0_maxDuration(maxDuration), + x2a4_colorInT(colorInT / 100.f), x2a8_colorOutT(colorOutT / 100.f), x2ac_scaleOutStartT(scaleOutStartT / 100.f), + x2b0_scale(scale), x2bc_endScale(scale * endScale), x2e0_speedAvg(2.f) { + x281_25_particle1GlobalTranslation = particle1GlobalTranslation; + x281_26_deferDeleteTillParticle1Done = deferDeleteTillParticle1Done; + x281_27_particle2GlobalTranslation = particle2GlobalTranslation; + x281_28_deferDeleteTillParticle2Done = deferDeleteTillParticle2Done; + x281_30_debrisExtended = true; + x281_31_dieOnProjectile = dieOnProjectile; + x282_24_noBounce = noBounce; + x283_particleOrs[0] = particle1Or; + x283_particleOrs[1] = particle2Or; + x283_particleOrs[2] = particle3Or; + + SetUseInSortedLists(false); + + SetTranslation(x34_transform.rotate(localOffset) + x34_transform.origin); + + if (solid) + { + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, + {EMaterialTypes::Debris, EMaterialTypes::Character, EMaterialTypes::Player})); + } + else + { + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude({}, + {EMaterialTypes::Debris, EMaterialTypes::Character, EMaterialTypes::Player, + EMaterialTypes::Projectile, EMaterialTypes::Solid})); + } + + if (g_ResFactory->GetResourceTypeById(particle1)) + { + TToken desc = g_SimplePool->GetObj({FOURCC('PART'), particle1}); + x2d4_particleGens[0] = std::make_unique(desc, CElementGen::EModelOrientationType::Normal, + CElementGen::EOptionalSystemFlags::One); + x2d4_particleGens[0]->SetGlobalScale(particle1Scale); + } + + if (g_ResFactory->GetResourceTypeById(particle2)) + { + TToken desc = g_SimplePool->GetObj({FOURCC('PART'), particle2}); + x2d4_particleGens[1] = std::make_unique(desc, CElementGen::EModelOrientationType::Normal, + CElementGen::EOptionalSystemFlags::One); + x2d4_particleGens[1]->SetGlobalScale(particle2Scale); + } + + if (g_ResFactory->GetResourceTypeById(particle3)) + { + TToken desc = g_SimplePool->GetObj({FOURCC('PART'), particle3}); + x2d4_particleGens[2] = std::make_unique(desc, CElementGen::EModelOrientationType::Normal, + CElementGen::EOptionalSystemFlags::One); + x2d4_particleGens[2]->SetGlobalScale(particle3Scale); + } + + x150_momentum = zeus::CVector3f(0.f, 0.f, -downwardSpeed * xe8_mass); } void CScriptDebris::Accept(IVisitor& visitor) { visitor.Visit(this); } -std::experimental::optional CScriptDebris::GetTouchBounds() const { return {}; } +void CScriptDebris::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const +{ + if (x2d4_particleGens[0]) + if (x270_curTime < x274_duration || x281_26_deferDeleteTillParticle1Done) + g_Renderer->AddParticleGen(*x2d4_particleGens[0]); + + if (x2d4_particleGens[1]) + if (x270_curTime < x274_duration || x281_28_deferDeleteTillParticle2Done) + g_Renderer->AddParticleGen(*x2d4_particleGens[1]); + + if (x281_29_particle3Active) + g_Renderer->AddParticleGen(*x2d4_particleGens[2]); + + if (x64_modelData && !x64_modelData->IsNull()) + if (x270_curTime < x274_duration) + CActor::AddToRenderer(frustum, mgr); +} + +static zeus::CVector3f debris_cone(CStateManager& mgr, float coneAng, float minMag, float maxMag) +{ + float mag = mgr.GetActiveRandom()->Float() * (maxMag - minMag) + minMag; + float side = 1.f - (1.f - std::cos(zeus::degToRad(coneAng))) * mgr.GetActiveRandom()->Float(); + float hyp = std::max(0.f, 1.f - side * side); + if (hyp != 0.f) + hyp = std::sqrt(hyp); + hyp *= mag; + float ang = mgr.GetActiveRandom()->Float() * 2.f * M_PIF; + return {std::cos(ang) * hyp, std::sin(ang) * hyp, mag * side}; +} + +void CScriptDebris::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) +{ + switch (msg) + { + case EScriptObjectMessage::Activate: + if (!x281_30_debrisExtended) + { + zeus::CVector3f linImpulse; + linImpulse.z = std::fabs(mgr.GetActiveRandom()->Next() % 32767 / 16383.5f - 1.f) * + xe8_mass * x258_velocity.z + x26c_zImpulse; + linImpulse.y = (mgr.GetActiveRandom()->Next() % 32767 / 16383.5f - 1.f) * + xe8_mass * x258_velocity.y; + linImpulse.x = (mgr.GetActiveRandom()->Next() % 32767 / 16383.5f - 1.f) * + xe8_mass * x258_velocity.x; + linImpulse += x34_transform.basis[2]; + zeus::CAxisAngle angImpulse; + if (x281_24_randomAngImpulse) + { + if (mgr.GetActiveRandom()->Next() % 100 < 50) + { + zeus::CVector3f rotVec; + rotVec.x = (mgr.GetActiveRandom()->Next() % 32767 / 16383.5f - 1.f) * 45.f; + rotVec.y = (mgr.GetActiveRandom()->Next() % 32767 / 16383.5f - 1.f) * 15.f; + rotVec.z = (mgr.GetActiveRandom()->Next() % 32767 / 16383.5f - 1.f) * 35.f; + angImpulse = zeus::CAxisAngle(rotVec); + } + } + ApplyImpulseWR(linImpulse, angImpulse); + } + else + { + zeus::CVector3f linImpulse = debris_cone(mgr, x288_linConeAngle, x28c_linMinMag, x290_linMaxMag); + zeus::CVector3f angImpulse = debris_cone(mgr, 360.f, x294_angMinMag, x298_angMaxMag); + ApplyImpulseOR(linImpulse, angImpulse); + x274_duration = mgr.GetActiveRandom()->Float() * (x2a0_maxDuration - x29c_minDuration) + x29c_minDuration; + } + + if (x2d4_particleGens[0]) + x2d4_particleGens[0]->SetParticleEmission(true); + if (x2d4_particleGens[1]) + x2d4_particleGens[1]->SetParticleEmission(true); + break; + case EScriptObjectMessage::OnFloor: + if (!x282_24_noBounce) + ApplyImpulseWR(-x27c_restitution * xfc_constantForce, -x27c_restitution * x108_angularMomentum); + break; + default: + break; + } + + CActor::AcceptScriptMsg(msg, sender, mgr); +} + +void CScriptDebris::Think(float dt, CStateManager& mgr) +{ + if (!GetActive()) + return; + + x270_curTime += dt; + bool done = x270_curTime >= x274_duration; + + if (x2d4_particleGens[0]) + { + if (x270_curTime >= x274_duration) + { + x2d4_particleGens[0]->SetParticleEmission(false); + } + else + { + if (x281_25_particle1GlobalTranslation) + x2d4_particleGens[0]->SetGlobalTranslation(GetTranslation()); + else + x2d4_particleGens[0]->SetTranslation(GetTranslation()); + + if (x283_particleOrs[0] == EOrientationType::AlongVelocity) + { + if (x138_velocity.canBeNormalized()) + { + zeus::CVector3f normVel = x138_velocity.normalized(); + zeus::CTransform orient = + zeus::lookAt(zeus::CVector3f::skZero, normVel, + std::fabs(normVel.z) < 0.99f ? zeus::CVector3f::skUp : zeus::CVector3f::skForward); + x2d4_particleGens[0]->SetOrientation(orient); + } + } + else if (x283_particleOrs[0] == EOrientationType::ToObject) + { + x2d4_particleGens[0]->SetOrientation(x34_transform.getRotation()); + } + } + + if (x281_26_deferDeleteTillParticle1Done && x2d4_particleGens[0]->GetParticleCount() != 0) + done = false; + + if (x270_curTime < x274_duration || x281_26_deferDeleteTillParticle1Done) + x2d4_particleGens[0]->Update(dt); + } + + if (x2d4_particleGens[1]) + { + if (x270_curTime >= x274_duration) + { + x2d4_particleGens[1]->SetParticleEmission(false); + } + else + { + if (x281_27_particle2GlobalTranslation) + x2d4_particleGens[1]->SetGlobalTranslation(GetTranslation()); + else + x2d4_particleGens[1]->SetTranslation(GetTranslation()); + + if (x283_particleOrs[1] == EOrientationType::AlongVelocity) + { + if (x138_velocity.canBeNormalized()) + { + zeus::CVector3f normVel = x138_velocity.normalized(); + zeus::CTransform orient = + zeus::lookAt(zeus::CVector3f::skZero, normVel, + std::fabs(normVel.z) < 0.99f ? zeus::CVector3f::skUp : zeus::CVector3f::skForward); + x2d4_particleGens[1]->SetOrientation(orient); + } + } + else if (x283_particleOrs[1] == EOrientationType::ToObject) + { + x2d4_particleGens[1]->SetOrientation(x34_transform.getRotation()); + } + } + + if (x281_28_deferDeleteTillParticle2Done && x2d4_particleGens[1]->GetParticleCount() != 0) + done = false; + + if (x270_curTime < x274_duration || x281_28_deferDeleteTillParticle2Done) + x2d4_particleGens[1]->Update(dt); + } + + /* End particle */ + if (x2d4_particleGens[2]) + { + if (x270_curTime >= x274_duration && !x281_29_particle3Active) + { + x2d4_particleGens[2]->SetGlobalTranslation(GetTranslation()); + + if (x283_particleOrs[2] == EOrientationType::AlongVelocity) + { + if (x138_velocity.canBeNormalized()) + { + zeus::CVector3f normVel = x138_velocity.normalized(); + zeus::CTransform orient = + zeus::lookAt(zeus::CVector3f::skZero, normVel, + std::fabs(normVel.z) < 0.99f ? zeus::CVector3f::skUp : zeus::CVector3f::skForward); + x2d4_particleGens[2]->SetOrientation(orient); + } + } + else if (x283_particleOrs[2] == EOrientationType::ToObject) + { + x2d4_particleGens[2]->SetOrientation(x34_transform.getRotation()); + } + else if (x283_particleOrs[2] == EOrientationType::AlongCollisionNormal) + { + if (x2c8_collisionNormal.magSquared() == 0.f) + x2c8_collisionNormal = zeus::CVector3f::skUp; + zeus::CTransform orient = + zeus::lookAt(zeus::CVector3f::skZero, x2c8_collisionNormal, + std::fabs(x2c8_collisionNormal.dot(zeus::CVector3f::skUp)) > 0.99f ? + zeus::CVector3f::skRight : zeus::CVector3f::skUp); + x2d4_particleGens[2]->SetOrientation(orient); + } + + x281_29_particle3Active = true; + } + + if (x281_29_particle3Active) + { + x2d4_particleGens[2]->Update(dt); + if (!x2d4_particleGens[2]->IsSystemDeletable()) + done = false; + } + } + + if (x64_modelData && !x64_modelData->IsNull()) + { + float t = x270_curTime / x274_duration > x2ac_scaleOutStartT ? + (x270_curTime - x2ac_scaleOutStartT * x274_duration) / ((1.f - x2ac_scaleOutStartT) * x274_duration) : 0.f; + x64_modelData->SetScale(zeus::CVector3f::lerp(x2b0_scale, x2bc_endScale, t)); + } + + if (x270_curTime >= x274_duration) + { + x150_momentum = zeus::CVector3f::skZero; + SetMaterialFilter(CMaterialFilter::MakeExclude({EMaterialTypes::Debris, EMaterialTypes::Character, + EMaterialTypes::Player, EMaterialTypes::Projectile})); + + if (done) + { + mgr.FreeScriptObject(x8_uid); + return; + } + } + + if (xf8_24_movable) + { + float speed = x138_velocity.magnitude(); + x2e0_speedAvg.AddValue(speed); + if (x2e0_speedAvg.GetAverage() < 0.1f) + xf8_24_movable = false; + } +} + +void CScriptDebris::Touch(CActor& other, CStateManager& mgr) +{ + if (x281_31_dieOnProjectile) + { + if (TCastToPtr(other)) + { + SendScriptMsgs(EScriptObjectState::Dead, mgr, EScriptObjectMessage::None); + mgr.FreeScriptObject(x8_uid); + } + } +} + +std::experimental::optional CScriptDebris::GetTouchBounds() const +{ + if (x281_31_dieOnProjectile) + return {GetBoundingBox()}; + return {}; +} + +void CScriptDebris::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) +{ + CActor::PreRender(mgr, frustum); + + float t = x270_curTime / x274_duration; + if (t < x2a4_colorInT) + t = x2a4_colorInT > 0.f ? 1.f - x270_curTime / (x274_duration * x2a4_colorInT) : 0.f; + else if (t > x2a8_colorOutT) + t = (x270_curTime - x274_duration * x2a8_colorOutT) / x274_duration * (1.f - x2a8_colorOutT); + else + t = 0.f; + + xb4_drawFlags = CModelFlags(5, 0, 3, zeus::CColor::lerp(zeus::CColor::skWhite, x268_endsColor, t)); +} + +void CScriptDebris::Render(const CStateManager& mgr) const +{ + CPhysicsActor::Render(mgr); +} void CScriptDebris::CollidedWith(TUniqueId, const CCollisionInfoList& colList, CStateManager&) { if (colList.GetCount() == 0) return; - if (x282_24_) + if (x282_24_noBounce) { - x274_ = x270_; + x274_duration = x270_curTime; SetVelocityWR(zeus::CVector3f::skZero); } else diff --git a/Runtime/World/CScriptDebris.hpp b/Runtime/World/CScriptDebris.hpp index 58b6c0d97..4015b07d0 100644 --- a/Runtime/World/CScriptDebris.hpp +++ b/Runtime/World/CScriptDebris.hpp @@ -11,49 +11,89 @@ class CScriptDebris : public CPhysicsActor public: enum class EScaleType { + NoScale, + EndsToZero }; enum class EOrientationType { + NotOriented, + AlongVelocity, + ToObject, + AlongCollisionNormal }; private: - zeus::CVector3f x258_; - zeus::CColor x264_; - float x26c_ = 0.f; - float x270_ = 0.f; - float x274_ = 0.f; - float x278_; - float x27c_; - bool x281_24_ : 1; - bool x281_25_ : 1; - bool x281_26_ : 1; - bool x281_27_ : 1; - bool x281_28_ : 1; - bool x281_29_ : 1; - bool x281_30_ : 1; - bool x281_31_ : 1; - bool x282_24_ : 1; + zeus::CVector3f x258_velocity; + zeus::CColor x264_color; + zeus::CColor x268_endsColor; + float x26c_zImpulse = 0.f; + float x270_curTime = 0.f; + float x274_duration = 0.f; + float x278_ooDuration = 0.f; + float x27c_restitution; + CScriptDebris::EScaleType x280_scaleType = CScriptDebris::EScaleType::NoScale; + union + { + struct + { + bool x281_24_randomAngImpulse : 1; + bool x281_25_particle1GlobalTranslation : 1; + bool x281_26_deferDeleteTillParticle1Done : 1; + bool x281_27_particle2GlobalTranslation : 1; + bool x281_28_deferDeleteTillParticle2Done : 1; + bool x281_29_particle3Active : 1; + bool x281_30_debrisExtended : 1; + bool x281_31_dieOnProjectile : 1; + bool x282_24_noBounce : 1; + }; + u32 _dummy = 0; + }; + EOrientationType x283_particleOrs[3] = {}; + float x288_linConeAngle = 0.f; + float x28c_linMinMag = 0.f; + float x290_linMaxMag = 0.f; + float x294_angMinMag = 0.f; + float x298_angMaxMag = 0.f; + float x29c_minDuration = 0.f; + float x2a0_maxDuration = 0.f; + float x2a4_colorInT = 0.f; + float x2a8_colorOutT = 0.f; + float x2ac_scaleOutStartT = 0.f; + zeus::CVector3f x2b0_scale; + zeus::CVector3f x2bc_endScale; zeus::CVector3f x2c8_collisionNormal; - std::unique_ptr x2d4_; - std::unique_ptr x2d8_; - std::unique_ptr x2dc_; - TReservedAverage x2e0_; + std::unique_ptr x2d4_particleGens[3]; /* x2d4, x2d8, x2dc */ + TReservedAverage x2e0_speedAvg; public: - CScriptDebris(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, - const CActorParameters&, CAssetId, const zeus::CVector3f&, float, const zeus::CVector3f&, - const zeus::CColor&, float, float, float, EScaleType, bool, bool, bool); + CScriptDebris(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CActorParameters& aParams, CAssetId particleId, + const zeus::CVector3f& particleScale, float zImpulse, const zeus::CVector3f& velocity, + const zeus::CColor& endsColor, float mass, float restitution, float duration, + EScaleType scaleType, bool b1, bool randomAngImpulse, bool active); - CScriptDebris(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, - const CActorParameters&, float, float, float, float, float, float, float, float, float, - const zeus::CColor&, const zeus::CColor&, float, const zeus::CVector3f&, const zeus::CVector3f&, - float, float, const zeus::CVector3f&, CAssetId, const zeus::CVector3f&, bool, bool, EOrientationType, - CAssetId, const zeus::CVector3f&, bool, bool, EOrientationType, CAssetId, const zeus::CVector3f&, - EOrientationType, bool, bool, bool, bool); + CScriptDebris(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CActorParameters& aParams, float linConeAngle, float linMinMag, + float linMaxMag, float angMinMag, float angMaxMag, float minDuration, float maxDuration, + float colorInT, float colorOutT, const zeus::CColor& color, const zeus::CColor& endsColor, + float scaleOutStartT, const zeus::CVector3f& scale, const zeus::CVector3f& endScale, + float restitution, float downwardSpeed, const zeus::CVector3f& localOffset, + CAssetId particle1, const zeus::CVector3f& particle1Scale, bool particle1GlobalTranslation, + bool deferDeleteTillParticle1Done, EOrientationType particle1Or, + CAssetId particle2, const zeus::CVector3f& particle2Scale, bool particle2GlobalTranslation, + bool deferDeleteTillParticle2Done, EOrientationType particle2Or, + CAssetId particle3, const zeus::CVector3f& particle3Scale, EOrientationType particle3Or, + bool solid, bool dieOnProjectile, bool noBounce, bool active); void Accept(IVisitor& visitor); + void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr); + void Think(float dt, CStateManager& mgr); + void Touch(CActor& other, CStateManager& mgr); std::experimental::optional GetTouchBounds() const; + void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum); + void Render(const CStateManager& mgr) const; void CollidedWith(TUniqueId uid, const CCollisionInfoList&, CStateManager&); }; diff --git a/Runtime/World/CScriptGenerator.cpp b/Runtime/World/CScriptGenerator.cpp index 94f5291d7..8470f9450 100644 --- a/Runtime/World/CScriptGenerator.cpp +++ b/Runtime/World/CScriptGenerator.cpp @@ -7,12 +7,12 @@ namespace urde { CScriptGenerator::CScriptGenerator(TUniqueId uid, std::string_view name, const CEntityInfo& info, u32 spawnCount, - bool reuseFollowers, const zeus::CVector3f& vec1, bool inheritXf, bool active, + bool noReuseFollowers, const zeus::CVector3f& vec1, bool noInheritXf, bool active, float minScale, float maxScale) : CEntity(uid, info, active, name) , x34_spawnCount(spawnCount) -, x38_24_reuseFollowers(reuseFollowers) -, x38_25_inheritTransform(inheritXf) +, x38_24_noReuseFollowers(noReuseFollowers) +, x38_25_noInheritTransform(noInheritXf) , x3c_offset(vec1) , x48_minScale(minScale) , x4c_maxScale(maxScale) @@ -21,11 +21,15 @@ CScriptGenerator::CScriptGenerator(TUniqueId uid, std::string_view name, const C void CScriptGenerator::Accept(IVisitor& visitor) { visitor.Visit(this); } -void CScriptGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) +void CScriptGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& stateMgr) { - return; - if (msg == EScriptObjectMessage::SetToZero && GetActive() && !x20_conns.empty()) + switch (msg) { + case EScriptObjectMessage::SetToZero: + { + if (!GetActive()) + break; + std::vector follows; follows.reserve(x20_conns.size()); for (const SConnection& conn : x20_conns) @@ -38,6 +42,9 @@ void CScriptGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId follows.push_back(uid); } + if (follows.empty()) + follows.push_back(sender); + std::vector> activates; activates.reserve(x20_conns.size()); @@ -47,21 +54,26 @@ void CScriptGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId continue; TUniqueId uid = stateMgr.GetIdForScript(conn.x8_objId); - - if (conn.x4_msg != EScriptObjectMessage::Activate) - { - stateMgr.SendScriptMsgAlways(GetUniqueId(), uid, conn.x4_msg); + if (uid == kInvalidUniqueId) continue; + + if (conn.x4_msg == EScriptObjectMessage::Activate) + { + if (!stateMgr.GetObjectById(uid)) + continue; + activates.emplace_back(uid, conn.x8_objId); } - if (stateMgr.GetObjectById(uid) != nullptr) - activates.emplace_back(uid, conn.x8_objId); + stateMgr.SendScriptMsgAlways(GetUniqueId(), uid, conn.x4_msg); } + if (activates.empty()) + break; + for (u32 i = 0; i < x34_spawnCount; ++i) { if (activates.size() == 0 || follows.size() == 0) - return; + break; u32 activatesRand = 0.99f * (stateMgr.GetActiveRandom()->Float() * activates.size()); u32 followsRand = 0.99f * (stateMgr.GetActiveRandom()->Float() * follows.size()); @@ -84,54 +96,44 @@ void CScriptGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId if (objId.second != kInvalidUniqueId) { - TCastToPtr activateActor(stateMgr.ObjectById(idPair.first)); - TCastToPtr followActor(follow); - TCastToPtr wallCrawlerSwarm(follow); - - if (activateActor && wallCrawlerSwarm) + if (CEntity* genObj = stateMgr.ObjectById(objId.second)) { - if (x38_25_inheritTransform) - activateActor->SetTransform(wallCrawlerSwarm->GetTransform()); - activateActor->SetTranslation(wallCrawlerSwarm->GetLastKilledOffset() + x3c_offset); - } - else if (activateActor && followActor) - { - if (x38_25_inheritTransform) - activateActor->SetTransform(followActor->GetTransform()); - activateActor->SetTranslation(followActor->GetTranslation() + x3c_offset); - } - else if (follow != nullptr) - { - TCastToPtr activateActor(stateMgr.ObjectById(objId.second)); + TCastToPtr activateActor(genObj); + TCastToPtr followActor(follow); + TCastToPtr wallCrawlerSwarm(follow); if (activateActor && wallCrawlerSwarm) { - if (x38_25_inheritTransform) + if (!x38_25_noInheritTransform) activateActor->SetTransform(wallCrawlerSwarm->GetTransform()); activateActor->SetTranslation(wallCrawlerSwarm->GetLastKilledOffset() + x3c_offset); } else if (activateActor && followActor) { - if (x38_25_inheritTransform) + if (!x38_25_noInheritTransform) activateActor->SetTransform(followActor->GetTransform()); activateActor->SetTranslation(followActor->GetTranslation() + x3c_offset); } float rnd = stateMgr.GetActiveRandom()->Range(x48_minScale, x4c_maxScale); - CModelData* mData = followActor->ModelData(); - if (mData && (mData->AnimationData() || mData->GetNormalModel())) + CModelData* mData = activateActor->ModelData(); + if (mData && !mData->IsNull()) mData->SetScale(rnd * mData->GetScale()); + + stateMgr.SendScriptMsg(genObj, GetUniqueId(), EScriptObjectMessage::Activate); } - - stateMgr.SendScriptMsg(activate, GetUniqueId(), EScriptObjectMessage::Activate); - - activates.erase(std::find(activates.begin(), activates.end(), idPair)); - if (!x38_24_reuseFollowers) - follows.erase(std::find(follows.begin(), follows.end(), follows[followsRand])); } + + activates.erase(std::find(activates.begin(), activates.end(), idPair)); + if (x38_24_noReuseFollowers) + follows.erase(std::find(follows.begin(), follows.end(), follows[followsRand])); } + break; + } + default: + break; } - CEntity::AcceptScriptMsg(msg, objId, stateMgr); + CEntity::AcceptScriptMsg(msg, sender, stateMgr); } } // namespace urde diff --git a/Runtime/World/CScriptGenerator.hpp b/Runtime/World/CScriptGenerator.hpp index 3529ce9ea..5e644f820 100644 --- a/Runtime/World/CScriptGenerator.hpp +++ b/Runtime/World/CScriptGenerator.hpp @@ -13,8 +13,8 @@ class CScriptGenerator : public CEntity union { struct { - bool x38_24_reuseFollowers : 1; - bool x38_25_inheritTransform : 1; + bool x38_24_noReuseFollowers : 1; + bool x38_25_noInheritTransform : 1; }; u8 dummy1 = 0; }; @@ -23,8 +23,9 @@ class CScriptGenerator : public CEntity float x4c_maxScale; public: - CScriptGenerator(TUniqueId uid, std::string_view name, const CEntityInfo& info, u32, bool, const zeus::CVector3f&, - bool, bool, float, float); + CScriptGenerator(TUniqueId uid, std::string_view name, const CEntityInfo& info, u32 spawnCount, + bool noReuseFollowers, const zeus::CVector3f& vec1, bool noInheritXf, bool active, + float minScale, float maxScale); void Accept(IVisitor& visitor); void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr); diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index b8e371cde..0cef22d92 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -706,8 +706,8 @@ CEntity* ScriptLoader::LoadGenerator(CStateManager& mgr, CInputStream& in, int p std::string name = mgr.HashInstanceName(in); u32 spawnCount = in.readUint32Big(); - bool reuseFollowers = in.readBool(); - bool inheritXf = in.readBool(); + bool noReuseFollowers = in.readBool(); + bool noInheritXf = in.readBool(); zeus::CVector3f offset = zeus::CVector3f::ReadBig(in); @@ -715,7 +715,7 @@ CEntity* ScriptLoader::LoadGenerator(CStateManager& mgr, CInputStream& in, int p float minScale = in.readFloatBig(); float maxScale = in.readFloatBig(); - return new CScriptGenerator(mgr.AllocateUniqueId(), name, info, spawnCount, reuseFollowers, offset, inheritXf, + return new CScriptGenerator(mgr.AllocateUniqueId(), name, info, spawnCount, noReuseFollowers, offset, noInheritXf, active, minScale, maxScale); } @@ -1140,27 +1140,28 @@ CEntity* ScriptLoader::LoadDebris(CStateManager& mgr, CInputStream& in, int prop return nullptr; SScaledActorHead head = LoadScaledActorHead(in, mgr); - float f1 = in.readFloatBig(); - zeus::CVector3f v1 = zeus::CVector3f::ReadBig(in); - zeus::CColor color; - color.readRGBABig(in); - float f2 = in.readFloatBig(); - float f3 = in.readFloatBig(); - float f4 = in.readFloatBig(); + float zImpulse = in.readFloatBig(); + zeus::CVector3f velocity = zeus::CVector3f::ReadBig(in); + zeus::CColor endsColor; + endsColor.readRGBABig(in); + float mass = in.readFloatBig(); + float restitution = in.readFloatBig(); + float duration = in.readFloatBig(); CScriptDebris::EScaleType scaleType = CScriptDebris::EScaleType(in.readUint32Big()); - bool b1 = in.readBool(); + bool randomAngImpulse = in.readBool(); CAssetId model = in.readUint32Big(); CActorParameters aParams = LoadActorParameters(in); - CAssetId w3 = in.readUint32Big(); - zeus::CVector3f v2 = zeus::CVector3f::ReadBig(in); - bool b2 = in.readBool(); - bool b3 = in.readBool(); + CAssetId particleId = in.readUint32Big(); + zeus::CVector3f particleScale = zeus::CVector3f::ReadBig(in); + bool b1 = in.readBool(); + bool active = in.readBool(); if (!g_ResFactory->GetResourceTypeById(model)) return nullptr; return new CScriptDebris(mgr.AllocateUniqueId(), head.x0_name, info, head.x10_transform, - CStaticRes(model, head.x40_scale), aParams, w3, v2, f1, v1, color, f2, f3, f4, scaleType, - b2, b1, b3); + CStaticRes(model, head.x40_scale), aParams, particleId, particleScale, zImpulse, + velocity, endsColor, mass, restitution, duration, scaleType, + b1, randomAngImpulse, active); } CEntity* ScriptLoader::LoadCameraShaker(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -1706,27 +1707,27 @@ CEntity* ScriptLoader::LoadDebrisExtended(CStateManager& mgr, CInputStream& in, SScaledActorHead aHead = LoadScaledActorHead(in, mgr); - float f1 = in.readFloatBig(); - float f2 = in.readFloatBig(); - float f3 = in.readFloatBig(); - float f4 = in.readFloatBig(); - float f5 = in.readFloatBig(); - float f6 = in.readFloatBig(); - float f7 = in.readFloatBig(); - float f8 = in.readFloatBig(); - float f9 = in.readFloatBig(); + float linConeAngle = in.readFloatBig(); + float linMinMag = in.readFloatBig(); + float linMaxMag = in.readFloatBig(); + float angMinMag = in.readFloatBig(); + float angMaxMag = in.readFloatBig(); + float minDuration = in.readFloatBig(); + float maxDuration = in.readFloatBig(); + float colorInT = in.readFloatBig(); + float colorOutT = in.readFloatBig(); - zeus::CColor c1 = zeus::CColor::ReadRGBABig(in); - zeus::CColor c2 = zeus::CColor::ReadRGBABig(in); + zeus::CColor color = zeus::CColor::ReadRGBABig(in); + zeus::CColor endsColor = zeus::CColor::ReadRGBABig(in); - float f10 = in.readFloatBig(); + float scaleOutT = in.readFloatBig(); - zeus::CVector3f v1 = zeus::CVector3f::ReadBig(in); + zeus::CVector3f endScale = zeus::CVector3f::ReadBig(in); - float f11 = in.readFloatBig(); - float f12 = in.readFloatBig(); + float restitution = in.readFloatBig(); + float downwardSpeed = in.readFloatBig(); - zeus::CVector3f v2 = zeus::CVector3f::ReadBig(in); + zeus::CVector3f localOffset = zeus::CVector3f::ReadBig(in); CAssetId model = in.readUint32Big(); @@ -1734,34 +1735,36 @@ CEntity* ScriptLoader::LoadDebrisExtended(CStateManager& mgr, CInputStream& in, CAssetId particle1 = in.readUint32Big(); zeus::CVector3f particle1Scale = zeus::CVector3f::ReadBig(in); - bool particle1B1 = in.readBool(); - bool particle1B2 = in.readBool(); - CScriptDebris::EOrientationType particle1W = CScriptDebris::EOrientationType(in.readUint32Big()); + bool particle1GlobalTranslation = in.readBool(); + bool deferDeleteTillParticle1Done = in.readBool(); + CScriptDebris::EOrientationType particle1Or = CScriptDebris::EOrientationType(in.readUint32Big()); CAssetId particle2 = in.readUint32Big(); zeus::CVector3f particle2Scale = zeus::CVector3f::ReadBig(in); - bool particle2B1 = in.readBool(); - bool particle2B2 = in.readBool(); - CScriptDebris::EOrientationType particle2W = CScriptDebris::EOrientationType(in.readUint32Big()); + bool particle2GlobalTranslation = in.readBool(); + bool deferDeleteTillParticle2Done = in.readBool(); + CScriptDebris::EOrientationType particle2Or = CScriptDebris::EOrientationType(in.readUint32Big()); CAssetId particle3 = in.readUint32Big(); zeus::CVector3f particle3Scale = zeus::CVector3f::ReadBig(in); - CScriptDebris::EOrientationType particle3W = CScriptDebris::EOrientationType(in.readUint32Big()); + CScriptDebris::EOrientationType particle3Or = CScriptDebris::EOrientationType(in.readUint32Big()); - bool b1 = in.readBool(); - bool b2 = in.readBool(); - bool b3 = in.readBool(); - bool b4 = in.readBool(); + bool solid = in.readBool(); + bool dieOnProjectile = in.readBool(); + bool noBounce = in.readBool(); + bool active = in.readBool(); CModelData modelData; if (g_ResFactory->GetResourceTypeById(model)) modelData = CModelData(CStaticRes(model, aHead.x40_scale)); return new CScriptDebris(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform, std::move(modelData), - aParam, f1, f2, f3, f4, f5, f6, f7, f8, f9, c1, c2, f10, aHead.x40_scale, v1, f11, f12, v2, - particle1, particle1Scale, particle1B1, particle1B2, particle1W, particle2, particle2Scale, - particle2B1, particle2B2, particle2W, particle3, particle3Scale, particle3W, b1, b2, b3, - b4); + aParam, linConeAngle, linMinMag, linMaxMag, angMinMag, angMaxMag, minDuration, maxDuration, + colorInT, colorOutT, color, endsColor, scaleOutT, aHead.x40_scale, endScale, restitution, + downwardSpeed, localOffset, particle1, particle1Scale, particle1GlobalTranslation, + deferDeleteTillParticle1Done, particle1Or, particle2, particle2Scale, + particle2GlobalTranslation, deferDeleteTillParticle2Done, particle2Or, particle3, + particle3Scale, particle3Or, solid, dieOnProjectile, noBounce, active); } CEntity* ScriptLoader::LoadSteam(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)