Implement CScriptEffect, more fixes for CScritDock

This commit is contained in:
Phillip Stephens 2018-05-13 20:38:36 -07:00
parent 9130b9459a
commit 8d395d932e
13 changed files with 550 additions and 70 deletions

View File

@ -47,7 +47,11 @@ void ViewManager::TestGameView::resized(const boo::SWindowRect& root, const boo:
specter::View::resized(root, sub);
urde::CGraphics::SetViewportResolution({sub.size[0], sub.size[1]});
if (m_debugText)
m_debugText->resized(root, sub);
{
boo::SWindowRect newSub = sub;
newSub.location[1] = 5 * m_vm.m_viewResources.pixelFactor();
m_debugText->resized(root, newSub);
}
}
void ViewManager::TestGameView::draw(boo::IGraphicsCommandQueue* gfxQ)
@ -60,15 +64,48 @@ void ViewManager::TestGameView::draw(boo::IGraphicsCommandQueue* gfxQ)
void ViewManager::TestGameView::think()
{
if (!m_debugText)
m_debugText.reset(new specter::MultiLineTextView(m_vm.m_viewResources, *this, m_vm.m_viewResources.m_heading18));
{
m_debugText.reset(
new specter::MultiLineTextView(m_vm.m_viewResources, *this, m_vm.m_viewResources.m_monoFont18));
boo::SWindowRect sub = subRect();
sub.location[1] = 5 * m_vm.m_viewResources.pixelFactor();
m_debugText->resized(rootView().subRect(), sub);
}
if (m_debugText && g_StateManager && g_StateManager->Player())
{
TLockedToken<CStringTable> tbl =
g_SimplePool->GetObj({FOURCC('STRG'), g_StateManager->GetWorld()->IGetStringTableAssetId()});
const CPlayer& pl = g_StateManager->GetPlayer();
zeus::CQuaternion plQ = zeus::CQuaternion(pl.GetTransform().getRotation().buildMatrix3f());
m_debugText->typesetGlyphs(hecl::Format("Player Position: x %f, y %f, z %f\n"
" Quaternion: w %f, x %f, y %f, z %f\n", pl.GetTranslation().x, pl.GetTranslation().y, pl.GetTranslation().z,
plQ.w, plQ.x, plQ.y, plQ.z));
const auto& layerStates = g_GameState->CurrentWorldState().GetLayerState();
const urde::TAreaId aId = g_GameState->CurrentWorldState().GetCurrentAreaId();
std::string layerBits;
u32 totalActive = 0;
for (s32 i = 0; i < layerStates->GetAreaLayerCount(aId); ++i)
{
if (layerStates->IsLayerActive(aId, i))
{
++totalActive;
layerBits += "1";
}
else
layerBits += "0";
}
m_debugText->typesetGlyphs(
hecl::Format("Player Position: x %f, y %f, z %f\n"
" Quaternion: w %f, x %f, y %f, z %f\n"
"World: 0x%08X%s, Area: %i\n"
"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(),
(tbl.IsLoaded() ? (" " + hecl::Char16ToUTF8(tbl->GetString(0))).c_str() : ""), aId,
g_StateManager->GetAllObjectList().size(), layerStates->GetAreaLayerCount(aId), totalActive,
layerBits.c_str()));
}
}
@ -93,7 +130,7 @@ SplashScreen* ViewManager::SetupSplashView()
return m_splash.get();
}
void ViewManager::RootSpaceViewBuilt(specter::View *view)
void ViewManager::RootSpaceViewBuilt(specter::View* view)
{
std::vector<specter::View*>& cViews = m_rootView->accessContentViews();
cViews.clear();
@ -142,10 +179,13 @@ void ViewManager::DismissSplash()
}
ViewManager::ViewManager(hecl::Runtime::FileStoreManager& fileMgr, hecl::CVarManager& cvarMgr)
: m_fileStoreManager(fileMgr), m_cvarManager(cvarMgr), m_projManager(*this),
m_fontCache(fileMgr), m_translator(urde::SystemLocaleOrEnglish()),
m_recentProjectsPath(hecl::SysFormat(_S("%s/recent_projects.txt"), fileMgr.getStoreRoot().data())),
m_recentFilesPath(hecl::SysFormat(_S("%s/recent_files.txt"), fileMgr.getStoreRoot().data()))
: m_fileStoreManager(fileMgr)
, m_cvarManager(cvarMgr)
, m_projManager(*this)
, m_fontCache(fileMgr)
, m_translator(urde::SystemLocaleOrEnglish())
, m_recentProjectsPath(hecl::SysFormat(_S("%s/recent_projects.txt"), fileMgr.getStoreRoot().data()))
, m_recentFilesPath(hecl::SysFormat(_S("%s/recent_files.txt"), fileMgr.getStoreRoot().data()))
{
Space::SpaceMenuNode::InitializeStrings(*this);
char path[2048];
@ -213,7 +253,8 @@ void ViewManager::pushRecentFile(hecl::SystemStringView path)
for (hecl::SystemString& pPath : m_recentFiles)
fprintf(fp, "%s\n", hecl::SystemUTF8Conv(pPath).c_str());
fclose(fp);
}}
}
}
void ViewManager::init(boo::IApplication* app)
{
@ -258,8 +299,7 @@ void ViewManager::init(boo::IApplication* app)
{
hecl::SystemString rootPath(root.getAbsolutePath());
hecl::Sstat theStat;
if (!hecl::Stat((rootPath + _S("/out/files/Metroid1.upak")).c_str(), &theStat) &&
S_ISREG(theStat.st_mode))
if (!hecl::Stat((rootPath + _S("/out/files/Metroid1.upak")).c_str(), &theStat) && S_ISREG(theStat.st_mode))
m_deferedProject = rootPath + _S("/out");
}
}
@ -310,7 +350,7 @@ bool ViewManager::proc()
++m_editorFrames;
if (m_rootSpaceView && m_editorFrames <= 30)
m_rootSpaceView->setMultiplyColor(zeus::CColor::lerp({1,1,1,0}, {1,1,1,1}, m_editorFrames / 30.0));
m_rootSpaceView->setMultiplyColor(zeus::CColor::lerp({1, 1, 1, 0}, {1, 1, 1, 1}, m_editorFrames / 30.0));
m_projManager.mainUpdate();
@ -344,5 +384,4 @@ void ViewManager::stop()
m_mainWindow->getCommandQueue()->stopRenderer();
}
}
} // namespace urde

View File

@ -25,7 +25,10 @@ public:
CWorldLayerState() = default;
CWorldLayerState(CBitStreamReader& reader, const CSaveWorld& saveWorld);
bool IsLayerActive(int areaIdx, int layerIdx) const { return (x0_areaLayers[areaIdx].m_layerBits >> layerIdx) & 1; }
bool IsLayerActive(int areaIdx, int layerIdx) const
{
return ((x0_areaLayers[areaIdx].m_layerBits >> layerIdx) & 1);
}
void SetLayerActive(int areaIdx, int layerIdx, bool active)
{
@ -83,8 +86,7 @@ class CGameState
u64 x210_cardSerial = 0;
std::vector<u8> x218_backupBuf;
union
{
union {
struct
{
bool x228_24_hardMode : 1;
@ -137,6 +139,6 @@ public:
};
static GameFileStateInfo LoadGameFileState(const u8* data);
};
}
} // namespace urde
#endif // __URDE_CGAMESTATE_HPP__

View File

@ -239,7 +239,7 @@ public:
size_t GetNumActiveChildParticles() const { return x290_activePartChildren.size(); }
CParticleGen& GetActiveChildParticle(size_t idx) const { return *x290_activePartChildren[idx]; }
bool IsIndirectTextured() const { return x28_loadedGenDesc->x54_x40_TEXR && x28_loadedGenDesc->x58_x44_TIND; }
void SetModelsUseLights(bool v) { x26d_26_modelsUseLights = v; }
static void SetMoveRedToAlphaBuffer(bool);
};
ENABLE_BITWISE_ENUM(CElementGen::EOptionalSystemFlags)

View File

@ -59,7 +59,12 @@ public:
}
static CActorParameters None() { return CActorParameters(); }
CActorParameters HotInThermal(bool hot) const
{
CActorParameters ret = *this;
ret.x58_25_thermalHeat = hot;
return ret;
}
void SetVisorParameters(const CVisorParameters& vParams) { x54_visorParms = vParams; }
const CVisorParameters& GetVisorParameters() const { return x54_visorParms; }
const CLightParameters& GetLightParameters() const { return x0_lightParms; }

View File

@ -93,6 +93,7 @@ public:
lights->SetAmbientColor(x18_noLightsAmbient);
return std::unique_ptr<CActorLights>(lights);
}
const zeus::CColor& GetNoLightsAmbient() const { return x18_noLightsAmbient; }
};
}

View File

@ -7,12 +7,12 @@ 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,
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)
: 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)
CMaterialList(EMaterialTypes::Solid, EMaterialTypes::Debris), mData.GetBounds(xf.getRotation()),
SMoverData(f2), aParams, 0.3f, 0.1f)
{
}
@ -20,26 +20,20 @@ CScriptDebris::CScriptDebris(TUniqueId uid, std::string_view name, const CEntity
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)
: CPhysicsActor(uid, active, name, info, xf, std::move(mData),
CMaterialList(EMaterialTypes::Solid, EMaterialTypes::Debris),
mData.GetBounds(xf.getRotation()), SMoverData(1.f), aParams, 0.3f, 0.1f)
{
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)
: 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)
{
}
void CScriptDebris::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
void CScriptDebris::Accept(IVisitor& visitor) { visitor.Visit(this); }
std::experimental::optional<zeus::CAABox> CScriptDebris::GetTouchBounds() const
{
return {};
}
std::experimental::optional<zeus::CAABox> CScriptDebris::GetTouchBounds() const { return {}; }
void CScriptDebris::CollidedWith(TUniqueId, const CCollisionInfoList& colList, CStateManager&)
{
@ -57,4 +51,4 @@ void CScriptDebris::CollidedWith(TUniqueId, const CCollisionInfoList& colList, C
}
}
}
} // namespace urde

View File

@ -18,15 +18,28 @@ public:
};
private:
float x270_;
float x274_;
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 x2c8_collisionNormal;
std::unique_ptr<CElementGen> x2d4_;
std::unique_ptr<CElementGen> x2d8_;
std::unique_ptr<CElementGen> x2dc_;
TReservedAverage<float, 8> x2e0_;
public:
CScriptDebris(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
const CActorParameters&, CAssetId, const zeus::CVector3f&, float, const zeus::CVector3f&,
@ -35,15 +48,15 @@ public:
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);
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);
void Accept(IVisitor& visitor);
std::experimental::optional<zeus::CAABox> GetTouchBounds() const;
void CollidedWith(TUniqueId uid, const CCollisionInfoList&, CStateManager&);
};
}
} // namespace urde
#endif // __URDE_CSCRIPTDEBRIS_HPP__

View File

@ -20,9 +20,9 @@ CMaterialList MakeDockMaterialList()
return list;
}
CScriptDock::CScriptDock(TUniqueId uid, std::string_view name, const CEntityInfo& info,
const zeus::CVector3f position, const zeus::CVector3f& extents, s32 dock, TAreaId area,
bool active, s32 dockReferenceCount, bool loadConnected)
CScriptDock::CScriptDock(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CVector3f position,
const zeus::CVector3f& extents, s32 dock, TAreaId area, bool active, s32 dockReferenceCount,
bool loadConnected)
: CPhysicsActor(uid, active, name, info, zeus::CTransform(zeus::CMatrix3f::skIdentityMatrix3f, position),
CModelData::CModelDataNull(), MakeDockMaterialList(), zeus::CAABox(-extents * 0.5f, extents * 0.5f),
SMoverData(1.f), CActorParameters::None(), 0.3f, 0.1f)
@ -33,10 +33,7 @@ CScriptDock::CScriptDock(TUniqueId uid, std::string_view name, const CEntityInfo
x268_25_loadConnected = loadConnected;
}
void CScriptDock::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
void CScriptDock::Accept(IVisitor& visitor) { visitor.Visit(this); }
void CScriptDock::Think(float dt, CStateManager& mgr)
{
@ -240,7 +237,7 @@ void CScriptDock::UpdateAreaActivateFlags(CStateManager& mgr)
bool CScriptDock::HasPointCrossedDock(const CStateManager& mgr, const zeus::CVector3f& point) const
{
const zeus::CPlane plane = GetPlane(mgr);
return (plane.vec.dot(point) >= plane.d);
return (point.dot(plane.vec) < plane.d);
}
void CScriptDock::AreaLoaded(CStateManager& mgr) { SetLoadConnected(mgr, x268_25_loadConnected); }
@ -254,4 +251,4 @@ void CScriptDock::SetLoadConnected(CStateManager& mgr, bool loadOther)
dock->SetShouldLoadOther(dock->GetReferenceCount(), loadOther);
}
}
} // namespace urde

View File

@ -2,6 +2,16 @@
#include "Character/CModelData.hpp"
#include "Collision/CMaterialList.hpp"
#include "CActorParameters.hpp"
#include "GameGlobalObjects.hpp"
#include "CSimplePool.hpp"
#include "Particle/CElementGen.hpp"
#include "Particle/CParticleElectric.hpp"
#include "CStateManager.hpp"
#include "World/CWorld.hpp"
#include "World/CGameLight.hpp"
#include "Camera/CGameCamera.hpp"
#include "CPlayerState.hpp"
#include "CScriptTrigger.hpp"
#include "TCastTo.hpp"
namespace urde
@ -12,12 +22,61 @@ u32 CScriptEffect::g_NumParticlesRendered = 0;
CScriptEffect::CScriptEffect(TUniqueId uid, std::string_view name, const CEntityInfo& info,
const zeus::CTransform& xf, const zeus::CVector3f& scale,
CAssetId partId, CAssetId elscId, bool, bool, bool, bool active,
bool, float, float, float, float, bool, float, float, float,
bool, bool, bool, const CLightParameters& lParms, bool)
CAssetId partId, CAssetId elscId, bool hotInThermal, bool b2, bool b3, bool active,
bool b4, float f1, float f2, float f3, float f4, bool b5, float f5, float f6, float f7,
bool b6, bool b7, bool b8, const CLightParameters& lParms, bool b9)
: CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(),
CActorParameters::None(), kInvalidUniqueId)
CActorParameters::None().HotInThermal(hotInThermal), kInvalidUniqueId)
, x10c_partId(partId)
, x110_24_(active)
, x110_25_(b2)
, x110_26_(b3)
, x110_27_(b4)
, x110_28_(b6)
, x110_29_(b7)
, x110_30_(b8)
, x110_31_(b8 && b7 && b6)
, x111_24_(b5)
, x111_25_(b9)
, x111_26_canRender(false)
, x114_(f1)
, x118_(f1 * f1)
, x11c_(f2)
, x120_(f5)
, x124_(f6)
, x128_(f7)
, x12c_(f3)
, x130_(f3)
, x134_(f4)
, x138_actorLights(lParms.MakeActorLights())
{
if (partId.IsValid())
{
xf8_particleSystemToken = g_SimplePool->GetObj({FOURCC('PART'), partId});
x104_particleSystem.reset(new CElementGen(xf8_particleSystemToken, CElementGen::EModelOrientationType::Normal, CElementGen::EOptionalSystemFlags::One));
zeus::CTransform newXf = xf;
newXf.origin = zeus::CVector3f::skZero;
x104_particleSystem->SetOrientation(newXf);
x104_particleSystem->SetTranslation(xf.origin);
x104_particleSystem->SetLocalScale(scale);
x104_particleSystem->SetParticleEmission(active);
x104_particleSystem->SetModulationColor(lParms.GetNoLightsAmbient());
x104_particleSystem->SetModelsUseLights(x138_actorLights != nullptr);
}
if (elscId.IsValid())
{
xe8_electricToken = g_SimplePool->GetObj({FOURCC('ELSC'), elscId});
xf4_electric.reset(new CParticleElectric(xe8_electricToken));
zeus::CTransform newXf = xf;
newXf.origin = zeus::CVector3f::skZero;
xf4_electric->SetOrientation(newXf);
xf4_electric->SetTranslation(xf.origin);
xf4_electric->SetLocalScale(scale);
xf4_electric->SetParticleEmission(active);
}
xe7_29_actorActive = true;
}
void CScriptEffect::Accept(IVisitor& visitor)
@ -25,4 +84,336 @@ void CScriptEffect::Accept(IVisitor& visitor)
visitor.Visit(this);
}
void CScriptEffect::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
bool active = GetActive();
if (msg == EScriptObjectMessage::Activate)
{
if (x110_26_)
{
if (x104_particleSystem)
{
zeus::CVector3f scale = x104_particleSystem->GetGlobalScale();
zeus::CColor color = x104_particleSystem->GetModulationColor();
x104_particleSystem.reset(new CElementGen(xf8_particleSystemToken));
zeus::CTransform newXf = GetTransform();
newXf.origin = zeus::CVector3f::skZero;
x104_particleSystem->SetOrientation(newXf);
x104_particleSystem->SetTranslation(GetTranslation());
x104_particleSystem->SetLocalScale(scale);
x104_particleSystem->SetParticleEmission(active);
x104_particleSystem->SetModulationColor(color);
x104_particleSystem->SetModelsUseLights(x138_actorLights != nullptr);
}
if (xf4_electric)
{
zeus::CVector3f scale = xf4_electric->GetGlobalScale();
zeus::CColor color = xf4_electric->GetModulationColor();
xf4_electric.reset(new CParticleElectric(xe8_electricToken));
zeus::CTransform newXf = GetTransform();
newXf.origin = zeus::CVector3f::skZero;
xf4_electric->SetOrientation(newXf);
xf4_electric->SetTranslation(GetTranslation());
xf4_electric->SetLocalScale(scale);
xf4_electric->SetParticleEmission(active);
xf4_electric->SetModulationColor(color);
}
}
}
else if (msg == EScriptObjectMessage::Registered)
{
if (x104_particleSystem && x104_particleSystem->SystemHasLight())
{
x108_lightId = mgr.AllocateUniqueId();
mgr.AddObject(new CGameLight(x108_lightId, GetAreaIdAlways(), true, std::string("EffectPLight_") + GetName().data(), x34_transform, GetUniqueId(), x104_particleSystem->GetLight(), x10c_partId.Value(), 1, 0.f));
}
}
else if (msg == EScriptObjectMessage::Deleted)
{
if (x108_lightId != kInvalidUniqueId)
{
mgr.FreeScriptObject(x108_lightId);
x108_lightId = kInvalidUniqueId;
}
}
else if (msg == EScriptObjectMessage::InitializedInArea)
{
for (const SConnection& conn : x20_conns)
{
if (!(conn.x0_state == EScriptObjectState::Active && conn.x4_msg == EScriptObjectMessage::Deactivate) ||
!(conn.x0_state == EScriptObjectState::Modify && conn.x4_msg == EScriptObjectMessage::Activate))
continue;
auto search = mgr.GetIdListForScript(conn.x8_objId);
for (auto it = search.first; it != search.second; ++it)
{
if (TCastToConstPtr<CScriptTrigger>(mgr.GetObjectById(it->second)))
x13c_triggerId = it->second;
}
}
}
CActor::AcceptScriptMsg(msg, uid, mgr);
TCastToPtr<CActor> act = mgr.ObjectById(x108_lightId);
mgr.SendScriptMsg(act, uid, msg);
if (active != GetActive())
{
std::vector<TUniqueId> playIds;
for (const SConnection& conn : x20_conns)
{
if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg != EScriptObjectMessage::Activate)
continue;
TUniqueId uid = mgr.GetIdForScript(conn.x8_objId);
if (uid != kInvalidUniqueId)
playIds.push_back(uid);
}
if (playIds.size() > 0)
{
TCastToConstPtr<CActor> otherAct = mgr.GetObjectById(playIds[u32(0.99f * playIds.size() * mgr.GetActiveRandom()->Float())]);
if (otherAct)
act->SetTransform(otherAct->GetTransform());
else
act->SetTransform(GetTransform());
}
x110_24_ = true;
if (x104_particleSystem)
x104_particleSystem->SetParticleEmission(GetActive());
if (xf4_electric)
xf4_electric->SetParticleEmission(GetActive());
if (GetActive())
x12c_ = zeus::max(x12c_, x130_);
}
}
void CScriptEffect::PreRender(CStateManager& mgr, const zeus::CFrustum&)
{
if (x110_27_ || x111_24_)
{
float f31 = 1.f;
const CGameCamera* cam = mgr.GetCameraManager()->GetCurrentCamera(mgr);
float f6 = cam->GetTranslation().y - GetTranslation().y;
float f4 = cam->GetTranslation().x - GetTranslation().x;
float f5 = cam->GetTranslation().z - GetTranslation().z;
float f1 = (f6 * f6);
float f3 = (f5 * f5);
f1 = (f4 * f4) + f1;
f1 = f3 + f1;
if (f1 <= 0.001f)
f3 = 0.f;
else if (f1 != 0.f)
f3 = f1 * zeus::sqrtF(f1);
if (x110_27_ && x118_ < f1)
{
float f0 = x114_;
float f2 = x11c_;
f0 = f3 / f0;
f1 = 1.f - f2;
f31 = f1 * f0 + f2;
}
if (x111_24_)
{
float f4 = x120_;
float f2 = x124_;
f1 = f3 - f4;
f2 = f2 - f4;
f1 = zeus::max(0.f, f1);
f1 = f1 / f2;
f2 = zeus::max(0.f, f1);
f1 = 1.f - f2;
float f0 = x128_;
f0 = f2 * f0;
f31 = f1 * f31 + f0;
}
x104_particleSystem->SetGeneratorRate(f31);
}
if (!mgr.GetObjectById(x13c_triggerId))
x13c_triggerId = kInvalidUniqueId;
}
void CScriptEffect::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const
{
if (!x111_26_canRender)
{
const_cast<CScriptEffect&>(*this).x12c_ = zeus::max(x12c_, x134_);
return;
}
if (!frustum.aabbFrustumTest(x9c_renderBounds))
return;
const_cast<CScriptEffect&>(*this).x12c_ = zeus::max(x12c_, x134_);
if (x110_31_)
{
bool visible = false;
const CPlayerState::EPlayerVisor visor = mgr.GetPlayerState()->GetActiveVisor(mgr);
if (visor == CPlayerState::EPlayerVisor::Combat || visor == CPlayerState::EPlayerVisor::Scan)
visible = x110_28_;
else if (visor == CPlayerState::EPlayerVisor::XRay)
visible = x110_30_;
else if (visor == CPlayerState::EPlayerVisor::Thermal)
visible = x110_29_;
if (visible && x138_actorLights)
{
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways());
const_cast<CScriptEffect&>(*this).x138_actorLights->BuildAreaLightList(mgr, *area, zeus::CAABox{x9c_renderBounds.center(), x9c_renderBounds.center()});
const_cast<CScriptEffect&>(*this).x138_actorLights->BuildDynamicLightList(mgr, x9c_renderBounds);
}
EnsureRendered(mgr);
}
}
void CScriptEffect::Render(const CStateManager& mgr) const
{
// if (x138_actorLights)
// x138_actorLights->ActivateLights();
if (x104_particleSystem && x104_particleSystem->GetParticleCountAll() > 0)
{
g_NumParticlesRendered += x104_particleSystem->GetParticleCountAll();
x104_particleSystem->Render();
}
if (xf4_electric && xf4_electric->GetParticleCount() > 0)
{
g_NumParticlesRendered += xf4_electric->GetParticleCount();
xf4_electric->Render();
}
}
void CScriptEffect::Think(float dt, CStateManager& mgr)
{
if (xe4_28_transformDirty)
{
if (x104_particleSystem)
{
zeus::CTransform newXf = x34_transform;
newXf.origin = zeus::CVector3f::skZero;
x104_particleSystem->SetOrientation(newXf);
x104_particleSystem->SetTranslation(x34_transform.origin);
}
if (xf4_electric)
{
zeus::CTransform newXf = x34_transform;
newXf.origin = zeus::CVector3f::skZero;
xf4_electric->SetOrientation(newXf);
xf4_electric->SetTranslation(x34_transform.origin);
}
if (TCastToPtr<CActor> act = mgr.ObjectById(x108_lightId))
act->SetTransform(GetTransform());
xe4_28_transformDirty = false;
}
if (x110_25_)
{
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways());
bool visible = area->GetActive() ? bool(area->GetOcclusionState()) : false;
if (!visible || x12c_ <= 0.f)
return;
}
else if (x12c_ <= 0.f)
return;
x12c_ -= dt;
if (x110_24_)
{
if (x104_particleSystem)
{
x104_particleSystem->Update(dt);
g_NumParticlesUpdating += x104_particleSystem->GetParticleCountAll();
}
if (xf4_electric)
{
xf4_electric->Update(dt);
g_NumParticlesUpdating += xf4_electric->GetParticleCount();
}
}
if (x108_lightId != kInvalidUniqueId)
{
if (TCastToPtr<CGameLight> light = mgr.ObjectById(x108_lightId))
{
if (x30_24_active)
light->SetLight(x104_particleSystem->GetLight());
}
}
if (x111_25_)
{
x140_ += dt;
if (x140_ > 15.f || AreBothSystemsDeleteable())
{
mgr.FreeScriptObject(GetUniqueId());
return;
}
}
if (x104_particleSystem)
{
if (xb4_drawFlags.x0_blendMode != 0)
x104_particleSystem->SetModulationColor(xb4_drawFlags.x4_color);
else
x104_particleSystem->SetModulationColor(zeus::CColor::skWhite);
}
}
void CScriptEffect::CalculateRenderBounds()
{
std::experimental::optional<zeus::CAABox> particleBounds;
if (x104_particleSystem)
particleBounds = x104_particleSystem->GetBounds();
std::experimental::optional<zeus::CAABox> electricBounds;
if (xf4_electric)
electricBounds = xf4_electric->GetBounds();
if (particleBounds || electricBounds)
{
zeus::CAABox renderBounds = zeus::CAABox::skNullBox;
if (particleBounds)
{
renderBounds.accumulateBounds(particleBounds->min);
renderBounds.accumulateBounds(particleBounds->max);
}
if (electricBounds)
{
renderBounds.accumulateBounds(electricBounds->min);
renderBounds.accumulateBounds(electricBounds->max);
}
x9c_renderBounds = renderBounds;
x111_26_canRender = true;
}
else
{
x9c_renderBounds = {GetTranslation(), GetTranslation()};
x111_26_canRender = false;
}
}
zeus::CAABox CScriptEffect::GetSortingBounds(const CStateManager& mgr) const
{
if (x13c_triggerId == kInvalidUniqueId)
return x9c_renderBounds;
else
return static_cast<const CScriptTrigger*>(mgr.GetObjectById(x13c_triggerId))->GetTriggerBoundsWR();
}
bool CScriptEffect::AreBothSystemsDeleteable()
{
return x104_particleSystem->IsSystemDeletable() && xf4_electric->IsSystemDeletable();
}
}

View File

@ -5,11 +5,41 @@
namespace urde
{
class CElementGen;
class CParticleElectric;
class CScriptEffect : public CActor
{
static u32 g_NumParticlesUpdating;
static u32 g_NumParticlesRendered;
TLockedToken<CElectricDescription> xe8_electricToken;
std::unique_ptr<CParticleElectric> xf4_electric;
TLockedToken<CGenDescription> xf8_particleSystemToken;
std::unique_ptr<CElementGen> x104_particleSystem;
TUniqueId x108_lightId = kInvalidUniqueId;
CAssetId x10c_partId;
bool x110_24_ : 1;
bool x110_25_ : 1;
bool x110_26_ : 1;
bool x110_27_ : 1;
bool x110_28_ : 1;
bool x110_29_ : 1;
bool x110_30_ : 1;
bool x110_31_ : 1;
bool x111_24_ : 1;
bool x111_25_ : 1;
bool x111_26_canRender : 1;
float x114_;
float x118_;
float x11c_;
float x120_;
float x124_;
float x128_;
float x12c_;
float x130_;
float x134_;
std::unique_ptr<CActorLights> x138_actorLights;
TUniqueId x13c_triggerId = kInvalidUniqueId;
float x140_ = 0.f;
public:
CScriptEffect(TUniqueId, std::string_view name, const CEntityInfo& info,
const zeus::CTransform& xf, const zeus::CVector3f& scale,
@ -18,7 +48,15 @@ public:
bool, bool, bool, const CLightParameters& lParms, bool);
void Accept(IVisitor& visitor);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void PreRender(CStateManager&, const zeus::CFrustum&);
void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const;
void Render(const CStateManager&) const;
void Think(float, CStateManager&);
bool CanRenderUnsorted(const CStateManager&) const { return false; }
void CalculateRenderBounds();
zeus::CAABox GetSortingBounds(const CStateManager&) const;
bool AreBothSystemsDeleteable();
static void ResetParticleCounts()
{
g_NumParticlesUpdating = 0;

View File

@ -134,4 +134,4 @@ void CScriptGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId
CEntity::AcceptScriptMsg(msg, objId, stateMgr);
}
}
} // namespace urde

View File

@ -574,8 +574,8 @@ CEntity* ScriptLoader::LoadEffect(CStateManager& mgr, CInputStream& in, int prop
SScaledActorHead head = LoadScaledActorHead(in, mgr);
CAssetId partId = in.readUint32Big();
CAssetId elscId = in.readUint32Big();
CAssetId partId(in);
CAssetId elscId(in);
bool b1 = in.readBool();
bool b2 = in.readBool();
bool b3 = in.readBool();

@ -1 +1 @@
Subproject commit 498c570050df733cb7c8a97c262d76920b5aac16
Subproject commit 369cf0cdd900b0b5abc5957dd1f20244ae671e4a