From cb2b9fa8bdc6cfe8f99cf6131e0beb03ae9f098c Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Mon, 4 Jun 2018 12:15:35 -0700 Subject: [PATCH] Initial CScriptGunTurret Implementation --- DataSpec/DNACommon/AROTBuilder.cpp | 2 +- DataSpec/DNAMP1/ScriptObjects/AmbientAI.hpp | 16 +- DataSpec/DNAMP3/CMakeLists.txt | 3 +- Editor/ViewManager.cpp | 84 +++++++---- Editor/main.cpp | 13 ++ Runtime/CPlayerState.cpp | 57 +++++++ Runtime/CPlayerState.hpp | 4 +- Runtime/CStateManager.cpp | 2 +- Runtime/CStateManager.hpp | 2 +- .../Graphics/Shaders/CModelShadersGLSL.cpp | 10 +- Runtime/MP1/MP1.cpp | 48 ++++-- Runtime/Weapon/CMakeLists.txt | 4 +- Runtime/World/CMakeLists.txt | 1 + Runtime/World/CScriptAiJumpPoint.cpp | 4 +- Runtime/World/CScriptAiJumpPoint.hpp | 2 +- Runtime/World/CScriptGunTurret.cpp | 141 +++++++++++++++++- Runtime/World/CScriptGunTurret.hpp | 114 +++++++++++--- Runtime/World/ScriptLoader.cpp | 121 +++++++++------ Runtime/World/ScriptLoader.hpp | 2 - specter | 2 +- 20 files changed, 494 insertions(+), 138 deletions(-) diff --git a/DataSpec/DNACommon/AROTBuilder.cpp b/DataSpec/DNACommon/AROTBuilder.cpp index 168fd4654..a32a8b65c 100644 --- a/DataSpec/DNACommon/AROTBuilder.cpp +++ b/DataSpec/DNACommon/AROTBuilder.cpp @@ -8,7 +8,7 @@ logvisor::Module Log("AROTBuilder"); #define AROT_MAX_LEVEL 6 #define AROT_MIN_MODELS 8 -#define COLLISION_MIN_NODE_TRIANGLES 16 +#define COLLISION_MIN_NODE_TRIANGLES 8 #define PATH_MIN_NODE_REGIONS 16 static zeus::CAABox SplitAABB(const zeus::CAABox& aabb, int i) diff --git a/DataSpec/DNAMP1/ScriptObjects/AmbientAI.hpp b/DataSpec/DNAMP1/ScriptObjects/AmbientAI.hpp index 516808e47..90b243605 100644 --- a/DataSpec/DNAMP1/ScriptObjects/AmbientAI.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/AmbientAI.hpp @@ -15,18 +15,18 @@ struct AmbientAI : IScriptObject Value location; Value orientation; Value scale; - Value unknown1; - Value scanOffset; - Value unknown2; + Value collisionExtent; + Value collisionOffset; + Value mass; HealthInfo healthInfo; DamageVulnerability damageVulnerability; AnimationParameters animationParameters; ActorParameters actorParameters; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; + Value alertRange; + Value impactRange; + Value alertAnim; + Value impactAnim; + Value active; void addCMDLRigPairs(PAKRouter& pakRouter, std::unordered_map>& addTo) const diff --git a/DataSpec/DNAMP3/CMakeLists.txt b/DataSpec/DNAMP3/CMakeLists.txt index c09a8c27f..a71869e80 100644 --- a/DataSpec/DNAMP3/CMakeLists.txt +++ b/DataSpec/DNAMP3/CMakeLists.txt @@ -9,7 +9,8 @@ make_dnalist(liblist DNAMP3 MREA SAVW CAUD - HINT) + HINT + SAND) set(DNAMP3_SOURCES DNAMP3.hpp DNAMP3.cpp PAK.cpp diff --git a/Editor/ViewManager.cpp b/Editor/ViewManager.cpp index ce802b4e6..e0a245569 100644 --- a/Editor/ViewManager.cpp +++ b/Editor/ViewManager.cpp @@ -66,48 +66,68 @@ void ViewManager::TestGameView::think() if (!m_debugText) { m_debugText.reset( - new specter::MultiLineTextView(m_vm.m_viewResources, *this, m_vm.m_viewResources.m_monoFont18)); + 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()) + if (m_debugText && g_StateManager) { - TLockedToken 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()); - const auto& layerStates = g_GameState->CurrentWorldState().GetLayerState(); + std::string overlayText; + const hecl::CVar* showFrameIdx = hecl::CVarManager::instance()->findCVar("debugOverlay.showFrameCounter"); + const hecl::CVar* playerInfo = hecl::CVarManager::instance()->findCVar("debugOverlay.playerInfo"); + const hecl::CVar* worldInfo = hecl::CVarManager::instance()->findCVar("debugOverlay.worldInfo"); + const hecl::CVar* areaInfo = hecl::CVarManager::instance()->findCVar("debugOverlay.areaInfo"); + if (showFrameIdx && showFrameIdx->toBoolean()) + overlayText += hecl::Format("Frame: %d\n", + g_StateManager->GetUpdateFrameIndex()); - const urde::TAreaId aId = g_GameState->CurrentWorldState().GetCurrentAreaId(); - - std::string layerBits; - u32 totalActive = 0; - for (s32 i = 0; i < layerStates->GetAreaLayerCount(aId); ++i) + if (g_StateManager->Player() && playerInfo && playerInfo->toBoolean()) { - if (layerStates->IsLayerActive(aId, i)) - { - ++totalActive; - layerBits += "1"; - } - else - layerBits += "0"; + const CPlayer& pl = g_StateManager->GetPlayer(); + zeus::CQuaternion plQ = zeus::CQuaternion(pl.GetTransform().getRotation().buildMatrix3f()); + overlayText += 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); + } + if (worldInfo && worldInfo->toBoolean()) + { + TLockedToken tbl = + g_SimplePool->GetObj({FOURCC('STRG'), g_StateManager->GetWorld()->IGetStringTableAssetId()}); + const urde::TAreaId aId = g_GameState->CurrentWorldState().GetCurrentAreaId(); + overlayText += hecl::Format("World: 0x%08X%s, Area: %i\n", + u32(g_GameState->CurrentWorldAssetId().Value()), + (tbl.IsLoaded() ? (" " + hecl::Char16ToUTF8(tbl->GetString(0))).c_str() : ""), aId); } - m_debugText->typesetGlyphs( - hecl::Format("Frame: %d\n" - "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", - g_StateManager->GetUpdateFrameIndex(), - pl.GetTranslation().x, pl.GetTranslation().y, pl.GetTranslation().z, plQ.w, plQ.x, plQ.y, - 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())); + const urde::TAreaId aId = g_GameState->CurrentWorldState().GetCurrentAreaId(); + if (areaInfo && areaInfo->toBoolean() && g_StateManager->WorldNC() && g_StateManager->WorldNC()->DoesAreaExist(aId)) + { + const auto& layerStates = g_GameState->CurrentWorldState().GetLayerState(); + std::string layerBits; + u32 totalActive = 0; + for (u32 i = 0; i < layerStates->GetAreaLayerCount(aId); ++i) + { + if (layerStates->IsLayerActive(aId, i)) + { + ++totalActive; + layerBits += "1"; + } + else + layerBits += "0"; + } + overlayText += hecl::Format("Area AssetId: 0x%08X, Total Objects: %i, Total Layers: %i, Total Active Layers: %i\n" + "Active Layer bits: %s\n", + g_StateManager->WorldNC()->GetArea(aId)->GetAreaAssetId().Value(), + g_StateManager->GetAllObjectList().size(), layerStates->GetAreaLayerCount(aId), + totalActive, layerBits.c_str()); + } + + + if (!overlayText.empty()) + m_debugText->typesetGlyphs(overlayText); } } diff --git a/Editor/main.cpp b/Editor/main.cpp index 4780d339f..136572a7f 100644 --- a/Editor/main.cpp +++ b/Editor/main.cpp @@ -108,6 +108,7 @@ struct Application : boo::IApplicationCallback void initialize(boo::IApplication* app) { zeus::detectCPU(); + createGlobalCVars(); for (const boo::SystemString& arg : app->getArgs()) { if (arg.find(_S("--verbosity=")) == 0 || arg.find(_S("-v=")) == 0) @@ -145,6 +146,18 @@ struct Application : boo::IApplicationCallback { return m_cvarCommons.getDeepColor(); } + + void createGlobalCVars() + { + m_cvarManager.findOrMakeCVar("debugOverlay.playerInfo"sv, "Displays information about the player, such as location and orientation"sv, false, + hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ReadOnly); + m_cvarManager.findOrMakeCVar("debugOverlay.worldInfo"sv, "Displays information about the current world, such as world asset ID, and areaId"sv, false, + hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ReadOnly); + m_cvarManager.findOrMakeCVar("debugOverlay.areaInfo"sv, "Displays information about the current area, such as asset ID, object/layer counts, and active layer bits"sv, false, + hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ReadOnly); + m_cvarManager.findOrMakeCVar("debugOverlay.showFrameCounter"sv, "Displays the current frame index"sv, false, + hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ReadOnly); + } }; } diff --git a/Runtime/CPlayerState.cpp b/Runtime/CPlayerState.cpp index 6fb941e84..48ec4c452 100644 --- a/Runtime/CPlayerState.cpp +++ b/Runtime/CPlayerState.cpp @@ -446,4 +446,61 @@ void CPlayerState::InitializeScanTimes() x170_scanTimes.emplace_back(state.first, 0.f); } +const std::unordered_map CPlayerState::g_TypeNameMap = { + {"powerbeam"sv, EItemType::PowerBeam}, + {"icebeam"sv, EItemType::IceBeam}, + {"wavebeam"sv, EItemType::WaveBeam}, + {"plasmabeam"sv, EItemType::PlasmaBeam}, + {"missiles"sv, EItemType::Missiles}, + {"scanvisor"sv, EItemType::ScanVisor}, + {"bombs"sv, EItemType::MorphBallBombs}, + {"ballbombs"sv, EItemType::MorphBallBombs}, + {"morphballbombs"sv, EItemType::MorphBallBombs}, + {"powerbombs"sv, EItemType::PowerBombs}, + {"flamethrower"sv, EItemType::Flamethrower}, + {"thermalvisor"sv, EItemType::ThermalVisor}, + {"chargebeam"sv, EItemType::ChargeBeam}, + {"supermissile"sv, EItemType::SuperMissile}, + {"grapplebeam"sv, EItemType::GrappleBeam}, + {"xrayvisor"sv, EItemType::XRayVisor}, + {"icespreader"sv, EItemType::IceSpreader}, + {"spacejumpboots"sv, EItemType::SpaceJumpBoots}, + {"morphball"sv, EItemType::MorphBall}, + {"combatvisor"sv, EItemType::CombatVisor}, + {"boostball"sv, EItemType::BoostBall}, + {"spiderball"sv, EItemType::SpiderBall}, + {"powersuit"sv, EItemType::PowerSuit}, + {"gravitysuit"sv, EItemType::GravitySuit}, + {"variasuit"sv, EItemType::VariaSuit}, + {"phazonsuit"sv, EItemType::PhazonSuit}, + {"energytanks"sv, EItemType::EnergyTanks}, + {"unknownitem1"sv, EItemType::UnknownItem1}, + {"healthrefill"sv, EItemType::HealthRefill}, + {"health"sv, EItemType::HealthRefill}, + {"unknownitem2"sv, EItemType::UnknownItem2}, + {"wavebuster"sv, EItemType::Wavebuster}, + {"truth"sv, EItemType::Truth}, + {"strength"sv, EItemType::Strength}, + {"elder"sv, EItemType::Elder}, + {"wild"sv, EItemType::Wild}, + {"lifegiver"sv, EItemType::Lifegiver}, + {"warrior"sv, EItemType::Warrior}, + {"chozo"sv, EItemType::Chozo}, + {"nature"sv, EItemType::Nature}, + {"sun"sv, EItemType::Sun}, + {"world"sv, EItemType::World}, + {"spirit"sv, EItemType::Spirit}, + {"newborn"sv, EItemType::Newborn}, +}; + +CPlayerState::EItemType CPlayerState::ItemNameToType(std::string_view name) +{ + std::string lowName = name.data(); + athena::utility::tolower(lowName); + if (g_TypeNameMap.find(lowName) == g_TypeNameMap.end()) + return EItemType::Invalid; + + return g_TypeNameMap.find(lowName)->second; +} + } diff --git a/Runtime/CPlayerState.hpp b/Runtime/CPlayerState.hpp index 1bfdc3eca..26988c0c6 100644 --- a/Runtime/CPlayerState.hpp +++ b/Runtime/CPlayerState.hpp @@ -100,7 +100,7 @@ public: }; private: - + static const std::unordered_map g_TypeNameMap; static const u32 PowerUpMaxValues[41]; static const char* PowerUpNames[41]; struct CPowerUp @@ -184,7 +184,7 @@ public: CPlayerState(CBitStreamReader& stream); void PutTo(CBitStreamWriter& stream); static u32 GetPowerUpMaxValue(EItemType type) { return PowerUpMaxValues[u32(type)]; } - + static EItemType ItemNameToType(std::string_view name); }; } diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index d471d3bb3..901916758 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -79,7 +79,7 @@ CStateManager::CStateManager(const std::weak_ptr& relayTracker, x88c_rumbleManager = &x86c_stateManagerContainer->xf250_rumbleManager; g_Renderer->SetDrawableCallback(&CStateManager::RendererDrawCallback, this); - + x908_loaderCount = int(EScriptObjectType::ScriptObjectTypeMAX); x90c_loaderFuncs[int(EScriptObjectType::Actor)] = ScriptLoader::LoadActor; x90c_loaderFuncs[int(EScriptObjectType::Waypoint)] = ScriptLoader::LoadWaypoint; x90c_loaderFuncs[int(EScriptObjectType::Door)] = ScriptLoader::LoadDoor; diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index d6bb479ba..9de108df4 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -169,7 +169,7 @@ private: CRandom16 x8fc_random; CRandom16* x900_activeRandom = nullptr; EGameState x904_gameState = EGameState::Running; - u32 x908_ = 0; + u32 x908_loaderCount = 0; FScriptLoader x90c_loaderFuncs[int(EScriptObjectType::ScriptObjectTypeMAX)] = {}; bool xab0_worldLoaded = false; diff --git a/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp b/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp index a9ff65b2f..e6e56283a 100644 --- a/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp +++ b/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp @@ -123,20 +123,20 @@ static const char* MainPostGLSL = " float fogZ, temp;\n" " switch (fog.mode)\n" " {\n" -" case 2:\n" +" case 2u:\n" " fogZ = (-vtf.mvPos.z - fog.start) * fog.rangeScale;\n" " break;\n" -" case 4:\n" +" case 4u:\n" " fogZ = 1.0 - exp2(-8.0 * (-vtf.mvPos.z - fog.start) * fog.rangeScale);\n" " break;\n" -" case 5:\n" +" case 5u:\n" " temp = (-vtf.mvPos.z - fog.start) * fog.rangeScale;\n" " fogZ = 1.0 - exp2(-8.0 * temp * temp);\n" " break;\n" -" case 6:\n" +" case 6u:\n" " fogZ = exp2(-8.0 * (fog.start + vtf.mvPos.z) * fog.rangeScale);\n" " break;\n" -" case 7:\n" +" case 7u:\n" " temp = (fog.start + vtf.mvPos.z) * fog.rangeScale;\n" " fogZ = exp2(-8.0 * temp * temp);\n" " break;\n" diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index 455d72626..022a5b936 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -458,7 +458,6 @@ void CMain::Give(hecl::Console* console, const std::vector& args) std::string type = args[0]; athena::utility::tolower(type); - console->report(hecl::Console::Level::Info, "Cheater....., Greatly increasing Metroid encounters, have fun!"); std::shared_ptr pState = g_GameState->GetPlayerState(); if (type == "all") { @@ -471,26 +470,49 @@ void CMain::Give(hecl::Console* console, const std::vector& args) } pState->IncrPickup(CPlayerState::EItemType::HealthRefill, 99999); } - else if (type == "missile") + else { - s32 missiles = 250; - if (args.size() == 2) + CPlayerState::EItemType eType = CPlayerState::ItemNameToType(type); + if (eType == CPlayerState::EItemType::Invalid) { - missiles = s32(strtol(args[1].c_str(), nullptr, 10)); - missiles = zeus::clamp(-250, missiles, 250); + console->report(hecl::Console::Level::Info, "Invalid item %s", type.c_str()); + return; + } + if (eType == CPlayerState::EItemType::HealthRefill) + { + pState->IncrPickup(eType, 9999); + console->report(hecl::Console::Level::Info, "Cheater....., Greatly increasing Metroid encounters, have fun!"); + return; } - u32 curCap = pState->GetItemCapacity(CPlayerState::EItemType::Missiles); - if (missiles > 0 && curCap < u32(missiles)) + s32 itemAmt = CPlayerState::GetPowerUpMaxValue(eType); + if (args.size() == 2) { - u32 tmp = ((u32(missiles) / 5) + (missiles % 5)) * 5; - pState->ReInitalizePowerUp(CPlayerState::EItemType::Missiles, tmp); + s32 itemMax = CPlayerState::GetPowerUpMaxValue(eType); + itemAmt = s32(strtol(args[1].c_str(), nullptr, 10)); + itemAmt = zeus::clamp(-itemMax, itemAmt, itemMax); } - if (missiles > 0) - pState->IncrPickup(CPlayerState::EItemType::Missiles, u32(missiles)); + + u32 curCap = pState->GetItemCapacity(eType); + if (itemAmt > 0 && curCap < u32(itemAmt)) + { + /* Handle special case with Missiles */ + if (eType == CPlayerState::EItemType::Missiles) + { + u32 tmp = ((u32(itemAmt) / 5) + (itemAmt % 5)) * 5; + pState->ReInitalizePowerUp(eType, tmp); + } + else + pState->ReInitalizePowerUp(eType, itemAmt); + } + + if (itemAmt > 0) + pState->IncrPickup(eType, u32(itemAmt)); else - pState->DecrPickup(CPlayerState::EItemType::Missiles, zeus::clamp(0u, u32(abs(missiles)), pState->GetItemAmount(CPlayerState::EItemType::Missiles))); + pState->DecrPickup(eType, zeus::clamp(0u, u32(abs(itemAmt)), pState->GetItemAmount(eType))); } + + console->report(hecl::Console::Level::Info, "Cheater....., Greatly increasing Metroid encounters, have fun!"); } void CMain::Teleport(hecl::Console *, const std::vector& args) diff --git a/Runtime/Weapon/CMakeLists.txt b/Runtime/Weapon/CMakeLists.txt index 4c60a17d9..62ee0219b 100644 --- a/Runtime/Weapon/CMakeLists.txt +++ b/Runtime/Weapon/CMakeLists.txt @@ -30,6 +30,8 @@ set(WEAPON_SOURCES CFlameInfo.hpp CFlameInfo.cpp CFlameThrower.hpp CFlameThrower.cpp CWaveBuster.hpp CWaveBuster.cpp - CNewFlameThrower.hpp CNewFlameThrower.cpp) + CNewFlameThrower.hpp CNewFlameThrower.cpp + CProjectileInfo.hpp CProjectileInfo.cpp + CBurstFire.hpp CBurstFire.cpp) runtime_add_list(Weapon WEAPON_SOURCES) diff --git a/Runtime/World/CMakeLists.txt b/Runtime/World/CMakeLists.txt index 2e76f895d..0b98111fc 100644 --- a/Runtime/World/CMakeLists.txt +++ b/Runtime/World/CMakeLists.txt @@ -91,6 +91,7 @@ set(WORLD_SOURCES CSnakeWeedSwarm.hpp CScriptSpindleCamera.hpp CScriptSpindleCamera.cpp CScriptCameraHintTrigger.hpp CScriptCameraHintTrigger.cpp + CAmbientAI.hpp CAmbientAI.cpp CScriptBeam.hpp CScriptBeam.cpp CScriptMazeNode.hpp CScriptMazeNode.cpp CScriptShadowProjector.hpp CScriptShadowProjector.cpp diff --git a/Runtime/World/CScriptAiJumpPoint.cpp b/Runtime/World/CScriptAiJumpPoint.cpp index 4aabf1c68..2f75cad3d 100644 --- a/Runtime/World/CScriptAiJumpPoint.cpp +++ b/Runtime/World/CScriptAiJumpPoint.cpp @@ -11,8 +11,8 @@ CScriptAiJumpPoint::CScriptAiJumpPoint(TUniqueId uid, std::string_view name, con : CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(EMaterialTypes::NoStepLogic), CActorParameters::None(), kInvalidUniqueId) , xe8_(f1) +, xec_touchBounds(xf.origin, xf.origin) { - xec_.emplace(xf.origin, xf.origin); } void CScriptAiJumpPoint::Accept(IVisitor& visitor) @@ -50,7 +50,7 @@ void CScriptAiJumpPoint::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId oth } } -std::experimental::optional CScriptAiJumpPoint::GetTouchBounds() const { return xec_; } +std::experimental::optional CScriptAiJumpPoint::GetTouchBounds() const { return xec_touchBounds; } bool CScriptAiJumpPoint::GetInUse(TUniqueId uid) const { diff --git a/Runtime/World/CScriptAiJumpPoint.hpp b/Runtime/World/CScriptAiJumpPoint.hpp index f69af899a..2e1d61647 100644 --- a/Runtime/World/CScriptAiJumpPoint.hpp +++ b/Runtime/World/CScriptAiJumpPoint.hpp @@ -9,7 +9,7 @@ class CScriptAiJumpPoint : public CActor { private: float xe8_; - std::experimental::optional xec_; + zeus::CAABox xec_touchBounds; union { struct { diff --git a/Runtime/World/CScriptGunTurret.cpp b/Runtime/World/CScriptGunTurret.cpp index 10d560bd2..35828cf92 100644 --- a/Runtime/World/CScriptGunTurret.cpp +++ b/Runtime/World/CScriptGunTurret.cpp @@ -1,4 +1,8 @@ #include "CScriptGunTurret.hpp" +#include "GameGlobalObjects.hpp" +#include "CSimplePool.hpp" +#include "Particle/CGenDescription.hpp" +#include "Particle/CElementGen.hpp" #include "TCastTo.hpp" namespace urde @@ -24,8 +28,8 @@ CScriptGunTurretData::CScriptGunTurretData(CInputStream& in, s32 propCount) x34_(in.readFloatBig()), x38_(in.readFloatBig()), x3c_(propCount >= 48 ? in.readBool() : false), - x40_(in.readUint32Big()), - x44_(in), + x40_projectileRes(in), + x44_projectileDamage(in), x60_(in.readUint32Big()), x64_(in.readUint32Big()), x68_(in.readUint32Big()), @@ -49,6 +53,74 @@ CScriptGunTurretData::CScriptGunTurretData(CInputStream& in, s32 propCount) { } +SBurst CScriptGunTurret::skOOVBurst4InfoTemplate[5] = +{ + {3, 1, 2, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {3, 7, 6, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {4, 3, 5, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {60, 16, 4, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {30, 4, 4, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f}, +}; + +SBurst CScriptGunTurret::skOOVBurst3InfoTemplate[5] = +{ + {30, 4, 5, 4, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {30, 2, 3, 4, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {30, 3, 4, 5, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {5, 16, 1, 2, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {5, 8, 7, 6, -1, 0, 0, 0, 0, 0.15f, 0.05f}, +}; + +SBurst CScriptGunTurret::skOOVBurst2InfoTemplate[7] = +{ + {5, 16, 1, 2, 3, 0, 0, 0, 0, 0.15f, 0.05f}, + {5, 9, 8, 7, 6, 0, 0, 0, 0, 0.15f, 0.05f}, + {15, 2, 3, 4, 5, 0, 0, 0, 0, 0.15f, 0.05f}, + {15, 5, 4, 3, 2, 0, 0, 0, 0, 0.15f, 0.05f}, + {15, 10, 11, 4, 13, 0, 0, 0, 0, 0.15f, 0.05f}, + {15, 14, 13, 4, 11, 0, 0, 0, 0, 0.15f, 0.05f}, + {30, 2, 4, 4, 6, 0, 0, 0, 0, 0.15f, 0.05f}, +}; + +SBurst CScriptGunTurret::skBurst4InfoTemplate[5] = +{ + {20, 16, 15, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {20, 8, 9, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {20, 13, 11, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {20, 2, 6, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {20, 3, 4, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f}, +}; + +SBurst CScriptGunTurret::skBurst3InfoTemplate[5] = +{ + {10, 14, 4, 10, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {10, 15, 13, 4, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {10, 9, 11, 4, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {35, 15, 13, 11, -1, 0, 0, 0, 0, 0.15f, 0.05f}, + {35, 9, 11, 13, -1, 0, 0, 0, 0, 0.15f, 0.05f}, +}; + +SBurst CScriptGunTurret::skBurst2InfoTemplate[6] = +{ + {10, 14, 13, 4, 11, 0, 0, 0, 0, 0.15f, 0.05f}, + {30, 1, 15, 13, 11, 0, 0, 0, 0, 0.15f, 0.05f}, + {20, 16, 15, 14, 13, 0, 0, 0, 0, 0.15f, 0.05f}, + {10, 8, 9, 11, 4, 0, 0, 0, 0, 0.15f, 0.05f}, + {10, 1, 15, 13, 4, 0, 0, 0, 0, 0.15f, 0.05f}, + {20, 8, 9, 10, 11, 0, 0, 0, 0, 0.15f, 0.05f} +}; + +SBurst* CScriptGunTurret::skBursts[] = +{ + skOOVBurst4InfoTemplate, + skOOVBurst3InfoTemplate, + skOOVBurst2InfoTemplate, + skBurst4InfoTemplate, + skBurst3InfoTemplate, + skBurst2InfoTemplate, + nullptr +}; + CScriptGunTurret::CScriptGunTurret(TUniqueId uid, std::string_view name, ETurretComponent comp, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& aabb, const CHealthInfo& hInfo, const CDamageVulnerability& dVuln, @@ -56,8 +128,42 @@ CScriptGunTurret::CScriptGunTurret(TUniqueId uid, std::string_view name, ETurret : CPhysicsActor(uid, true, name, info, xf, std::move(mData), comp == ETurretComponent::Turret ? skTurretMaterialList : skGunMaterialList, aabb, SMoverData(1000.f), aParms, 0.3f, 0.1f) +, x258_type(comp) +, x264_healthInfo(hInfo) +, x26c_damageVuln(dVuln) +, x2d4_data(turretData) +, x37c_projectileInfo(turretData.GetProjectileRes(), turretData.GetProjectileDamage()) +, x3a4_burstFire(skBursts, 1) +, x410_(g_SimplePool->GetObj({SBIG('PART'), turretData.x60_})) +, x41c_(g_SimplePool->GetObj({SBIG('PART'), turretData.x64_})) +, x428_(g_SimplePool->GetObj({SBIG('PART'), turretData.x68_})) +, x434_(g_SimplePool->GetObj({SBIG('PART'), turretData.x6c_})) +, x440_(g_SimplePool->GetObj({SBIG('PART'), turretData.x70_})) +, x44c_(g_SimplePool->GetObj({SBIG('PART'), turretData.x74_})) { + if (turretData.x78_.IsValid()) + x458_ = g_SimplePool->GetObj({SBIG('PART'), turretData.x78_}); + x468_.reset(new CElementGen(x410_)); + x470_.reset(new CElementGen(x41c_)); + x478_.reset(new CElementGen(x428_)); + x480_.reset(new CElementGen(x434_)); + x488_.reset(new CElementGen(x440_)); + x490_.reset(new CElementGen(x44c_)); + x4fc_ = xf.origin; + x514_ = xf.frontVector(); + x544_ = xf.frontVector(); + x550_ = xf.rightVector(); + x560_24_ = false; + x560_25_ = false; + x560_26_ = false; + x560_27_ = false; + x560_28_ = false; + x560_29_ = false; + x560_30_ = true; + x560_31_ = false; + if (comp == ETurretComponent::Turret && HasModelData() && GetModelData()->HasAnimData()) + ModelData()->EnableLooping(true); } void CScriptGunTurret::Accept(IVisitor& visitor) @@ -65,4 +171,35 @@ void CScriptGunTurret::Accept(IVisitor& visitor) visitor.Visit(this); } +void CScriptGunTurret::AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager &) +{ + +} + +void CScriptGunTurret::Think(float, CStateManager &) +{ + if (!GetActive()) + return; +} + +std::experimental::optional CScriptGunTurret::GetTouchBounds() const +{ + if (GetActive() && GetMaterialList().HasMaterial(EMaterialTypes::Solid)) + return {GetBoundingBox()}; + return {}; +} + +zeus::CVector3f CScriptGunTurret::GetOrbitPosition(const CStateManager& mgr) const +{ + return GetAimPosition(mgr, 0.f); +} + +zeus::CVector3f CScriptGunTurret::GetAimPosition(const CStateManager &, float) const +{ + if (x258_type == ETurretComponent::Turret) + return GetTranslation() + x34_transform.rotate(GetLocatorTransform("Gun_SDK"sv).origin); + + return GetTranslation(); +} + } diff --git a/Runtime/World/CScriptGunTurret.hpp b/Runtime/World/CScriptGunTurret.hpp index d467dbe33..b9577c7b5 100644 --- a/Runtime/World/CScriptGunTurret.hpp +++ b/Runtime/World/CScriptGunTurret.hpp @@ -3,11 +3,16 @@ #include "CPhysicsActor.hpp" #include "CDamageInfo.hpp" +#include "CDamageVulnerability.hpp" +#include "Weapon/CProjectileInfo.hpp" +#include "Weapon/CBurstFire.hpp" + namespace urde { class CScriptGunTurretData { + friend class CScriptGunTurret; float x0_; float x4_; float x8_; @@ -24,22 +29,22 @@ class CScriptGunTurretData float x34_; float x38_; bool x3c_; - u32 x40_; - CDamageInfo x44_; - u32 x60_; - u32 x64_; - u32 x68_; - u32 x6c_; - u32 x70_; - u32 x74_; - u32 x78_; + CAssetId x40_projectileRes; + CDamageInfo x44_projectileDamage; + CAssetId x60_; + CAssetId x64_; + CAssetId x68_; + CAssetId x6c_; + CAssetId x70_; + CAssetId x74_; + CAssetId x78_; u16 x7c_; u16 x7e_; u16 x80_; u16 x82_; u16 x84_; u16 x86_; - u32 x88_; + CAssetId x88_; float x8c_; u32 x90_; u32 x94_; @@ -49,27 +54,90 @@ class CScriptGunTurretData static constexpr s32 skMinProperties = 43; public: CScriptGunTurretData(CInputStream&, s32); - const CAssetId& GetPanningEffectRes() const; - const CAssetId& GetChargingEffectRes() const; - const CAssetId& GetFrozenEffectRes() const; - const CAssetId& GetTargettingLightRes() const; - const CAssetId& GetDeactivateLightRes() const; - const CAssetId& GetIdleLightRes() const; - const CDamageInfo& GetProjectileDamage() const; - const CAssetId& GetProjectileRes() const; + CAssetId GetPanningEffectRes() const; + CAssetId GetChargingEffectRes() const; + CAssetId GetFrozenEffectRes() const; + CAssetId GetTargettingLightRes() const; + CAssetId GetDeactivateLightRes() const; + CAssetId GetIdleLightRes() const; + const CDamageInfo& GetProjectileDamage() const { return x44_projectileDamage; } + CAssetId GetProjectileRes() const { return x40_projectileRes; } u16 GetUnFreezeSoundId() const; - void GetIntoDeactivateDelay() const; + float GetIntoDeactivateDelay() const; static s32 GetMinProperties() { return skMinProperties; } }; class CScriptGunTurret : public CPhysicsActor { + static SBurst skOOVBurst4InfoTemplate[5]; + static SBurst skOOVBurst3InfoTemplate[5]; + static SBurst skOOVBurst2InfoTemplate[7]; + static SBurst skBurst4InfoTemplate[5]; + static SBurst skBurst3InfoTemplate[5]; + static SBurst skBurst2InfoTemplate[6]; + static SBurst* skBursts[]; public: enum class ETurretComponent { Turret, Gun }; + ETurretComponent x258_type; + TUniqueId x25c_ = kInvalidUniqueId; + float x260_ = 0.f; + CHealthInfo x264_healthInfo; + CDamageVulnerability x26c_damageVuln; + CScriptGunTurretData x2d4_data; + TUniqueId x378_ = kInvalidUniqueId; + CProjectileInfo x37c_projectileInfo; + CBurstFire x3a4_burstFire; + zeus::CVector3f x404_; + TToken x410_; + TToken x41c_; + TToken x428_; + TToken x434_; + TToken x440_; + TToken x44c_; + TLockedToken x458_; + std::unique_ptr x468_; + std::unique_ptr x470_; + std::unique_ptr x478_; + std::unique_ptr x480_; + std::unique_ptr x488_; + std::unique_ptr x490_; + TUniqueId x498_ = kInvalidUniqueId; + u32 x49c_ = 0; + TUniqueId x4a0_ = kInvalidUniqueId; + std::experimental::optional x4a4_; + float x4f4_ = 0.f; + float x4f8_ = 0.f; + zeus::CVector3f x4fc_; + u8 x508_ = 0xFF; + u32 x50c_ = 0; + float x510_ = 0.f; + zeus::CVector3f x514_; + s32 x520_ = -1; + float x524_ = 0.f; + float x528_ = 0.f; + float x52c_ = 0.f; + float x530_ = 0.f; + float x534_ = 0.f; + float x538_ = 0.f; + float x53c_ = 0.f; + s32 x540_ = -1; + zeus::CVector3f x544_; + zeus::CVector3f x550_; + s32 x55c_ = -1; + union + { + struct + { + bool x560_24_ : 1; bool x560_25_ : 1; bool x560_26_ : 1; + bool x560_27_ : 1; bool x560_28_ : 1; bool x560_29_ : 1; + bool x560_30_ : 1; bool x560_31_ : 1; + }; + u32 _dummy = 0; + }; private: public: CScriptGunTurret(TUniqueId uid, std::string_view name, ETurretComponent comp, const CEntityInfo& info, @@ -78,6 +146,14 @@ public: const CActorParameters& aParms, const CScriptGunTurretData& turretData); void Accept(IVisitor&); + void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); + void Think(float, CStateManager&); + std::experimental::optional GetTouchBounds() const; + zeus::CVector3f GetOrbitPosition(const CStateManager&) const; + zeus::CVector3f GetAimPosition(const CStateManager&, float) const; + + CHealthInfo* HealthInfo(CStateManager&) { return &x264_healthInfo; } + const CDamageVulnerability* GetDamageVulnerability() const { return &x26c_damageVuln; } }; diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index 8c9b3e63f..57e02f2fa 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -16,6 +16,7 @@ #include "CScriptCameraFilterKeyframe.hpp" #include "CScriptCameraHint.hpp" #include "CScriptCameraHintTrigger.hpp" +#include "CAmbientAI.hpp" #include "CScriptCameraPitchVolume.hpp" #include "CTeamAiMgr.hpp" #include "CScriptCameraShaker.hpp" @@ -430,7 +431,8 @@ CEntity* ScriptLoader::LoadActor(CStateManager& mgr, CInputStream& in, int propC CModelData data; if (animType == SBIG('ANCS')) - data = CAnimRes(aParms.GetACSFile(), aParms.GetCharacter(), head.x40_scale, aParms.GetInitialAnimation(), false); + data = + CAnimRes(aParms.GetACSFile(), aParms.GetCharacter(), head.x40_scale, aParms.GetInitialAnimation(), false); else data = CStaticRes(staticId, head.x40_scale); @@ -608,8 +610,8 @@ CEntity* ScriptLoader::LoadEffect(CStateManager& mgr, CInputStream& in, int prop elscId, hotInThermal, noTimerUnlessAreaOccluded, rebuildSystemsOnActivate, active, useRateInverseCamDist, rateInverseCamDist, rateInverseCamDistRate, duration, durationResetWhileVisible, useRateCamDistRange, rateCamDistRangeMin, rateCamDistRangeMax, - rateCamDistRangeFarRate, combatVisorVisible, thermalVisorVisible, xrayVisorVisible, - lParms, dieWhenSystemsDone); + rateCamDistRangeFarRate, combatVisorVisible, thermalVisorVisible, xrayVisorVisible, lParms, + dieWhenSystemsDone); } CEntity* ScriptLoader::LoadPlatform(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -699,8 +701,8 @@ CEntity* ScriptLoader::LoadSound(CStateManager& mgr, CInputStream& in, int propC return nullptr; return new CScriptSound(mgr.AllocateUniqueId(), head.x0_name, info, head.x10_transform, u16(soundId), active, - maxDist, distComp, startDelay, minVol, vol, 0, prio, pan, 0, loop, - nonEmitter, autoStart, occlusionTest, acoustics, worldSfx, allowDuplicates, pitch); + maxDist, distComp, startDelay, minVol, vol, 0, prio, pan, 0, loop, nonEmitter, autoStart, + occlusionTest, acoustics, worldSfx, allowDuplicates, pitch); } CEntity* ScriptLoader::LoadGenerator(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -1164,9 +1166,8 @@ CEntity* ScriptLoader::LoadDebris(CStateManager& mgr, CInputStream& in, int prop 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, particleId, particleScale, zImpulse, - velocity, endsColor, mass, restitution, duration, scaleType, - b1, randomAngImpulse, active); + 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) @@ -1197,8 +1198,8 @@ CEntity* ScriptLoader::LoadActorKeyframe(CStateManager& mgr, CInputStream& in, i if (animId == -1) return nullptr; - return new CScriptActorKeyframe(mgr.AllocateUniqueId(), name, info, animId, looping, lifetime, false, - fadeOut, active, totalPlayback); + return new CScriptActorKeyframe(mgr.AllocateUniqueId(), name, info, animId, looping, lifetime, false, fadeOut, + active, totalPlayback); } CEntity* ScriptLoader::LoadWater(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -1456,7 +1457,8 @@ CEntity* ScriptLoader::LoadPathCamera(CStateManager& mgr, CInputStream& in, int CPathCamera::EInitialSplinePosition initPos = CPathCamera::EInitialSplinePosition(in.readUint32Big()); float f4 = in.readFloatBig(); float f5 = in.readFloatBig(); - return new CPathCamera(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform, active, f1, f2, f3, f4, f5, flags, initPos); + return new CPathCamera(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform, active, f1, f2, f3, f4, f5, + flags, initPos); } CEntity* ScriptLoader::LoadGrapplePoint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -1642,9 +1644,12 @@ CEntity* ScriptLoader::LoadParasite(CStateManager& mgr, CInputStream& in, int pr if (g_ResFactory->GetResourceTypeById(pInfo.GetAnimationParameters().GetACSFile()) != SBIG('ANCS')) return nullptr; const CAnimationParameters& animParms = pInfo.GetAnimationParameters(); - CModelData mData(CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true)); - return new MP1::CParasite(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo, 6, f1, f2, f3, f4, f5, f6, f7, - f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, 0.f, b1, 0, CDamageVulnerability::NormalVulnerabilty(), MP1::CParasiteInfo(), -1, -1, -1, -1, -1, 0.f, aParms); + CModelData mData( + CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true)); + return new MP1::CParasite(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo, 6, f1, f2, f3, + f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, 0.f, b1, 0, + CDamageVulnerability::NormalVulnerabilty(), MP1::CParasiteInfo(), -1, -1, -1, -1, -1, 0.f, + aParms); } CEntity* ScriptLoader::LoadPlayerHint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -1835,7 +1840,6 @@ CEntity* ScriptLoader::LoadTargetingPoint(CStateManager& mgr, CInputStream& in, if (!EnsurePropertyCount(propCount, 4, "TargetingPoint")) return nullptr; - SActorHead aHead = LoadActorHead(in, mgr); bool active = in.readBool(); @@ -1947,7 +1951,6 @@ CEntity* ScriptLoader::LoadFishCloud(CStateManager& mgr, CInputStream& in, int p float f13 = in.readFloatBig(); u32 w6 = in.readUint32Big(); - if (!g_ResFactory->GetResourceTypeById(w1)) return nullptr; @@ -1967,9 +1970,11 @@ CEntity* ScriptLoader::LoadFishCloud(CStateManager& mgr, CInputStream& in, int p bool b4 = in.readBool(); CModelData mData(CStaticRes(w1, zeus::CVector3f::skOne)); - CAnimRes animRes(animParms.GetACSFile(), animParms.GetCharacter(), zeus::CVector3f::skOne, animParms.GetInitialAnimation(), true); - return new CFishCloud(mgr.AllocateUniqueId(), b1, aHead.x0_name, info, aHead.x40_scale, aHead.x10_transform, std::move(mData), animRes, w5, - f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, w6, col, b2, f14, w7, w8, w9, w10, w11, w12, w13, w14, w15, b3, b4); + CAnimRes animRes(animParms.GetACSFile(), animParms.GetCharacter(), zeus::CVector3f::skOne, + animParms.GetInitialAnimation(), true); + return new CFishCloud(mgr.AllocateUniqueId(), b1, aHead.x0_name, info, aHead.x40_scale, aHead.x10_transform, + std::move(mData), animRes, w5, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, w6, + col, b2, f14, w7, w8, w9, w10, w11, w12, w13, w14, w15, b3, b4); } CEntity* ScriptLoader::LoadFishCloudModifier(CStateManager& mgr, CInputStream& in, int propCount, @@ -2078,8 +2083,8 @@ CEntity* ScriptLoader::LoadVisorGoo(CStateManager& mgr, CInputStream& in, int pr bool forceShow = in.readBool(); if (particle.IsValid() || electric.IsValid()) - return new CScriptVisorGoo(mgr.AllocateUniqueId(), name, info, xf, particle, electric, - minDist, maxDist, nearProb, farProb, color, sfx, forceShow, false); + return new CScriptVisorGoo(mgr.AllocateUniqueId(), name, info, xf, particle, electric, minDist, maxDist, + nearProb, farProb, color, sfx, forceShow, false); return nullptr; } @@ -2192,9 +2197,9 @@ CEntity* ScriptLoader::LoadWallCrawlerSwarm(CStateManager& mgr, CInputStream& in u32 w15 = in.readUint32Big(); return new CWallCrawlerSwarm(mgr.AllocateUniqueId(), active, aHead.x0_name, info, aHead.x40_scale, - aHead.x10_transform, w1, CAnimRes(w2, w3, zeus::CVector3f(1.5f), w4, true), w5, w6, - w7, w8, w9, w10, dInfo1, dInfo2, f1, f2, f3, f4, w11, w12, f5, f6, f7, f8, f9, f10, - f11, f12, f13, w13, f14, f15, f16, hInfo, dVulns, w14, w15, aParams); + aHead.x10_transform, w1, CAnimRes(w2, w3, zeus::CVector3f(1.5f), w4, true), w5, w6, w7, + w8, w9, w10, dInfo1, dInfo2, f1, f2, f3, f4, w11, w12, f5, f6, f7, f8, f9, f10, f11, + f12, f13, w13, f14, f15, f16, hInfo, dVulns, w14, w15, aParams); } CEntity* ScriptLoader::LoadAiJumpPoint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -2352,13 +2357,15 @@ CEntity* ScriptLoader::LoadGunTurret(CStateManager& mgr, CInputStream& in, int p if (!g_ResFactory->GetResourceTypeById(animParms.GetACSFile())) return nullptr; - CModelData mData(CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true)); + CModelData mData( + CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true)); zeus::CAABox aabb = GetCollisionBox(mgr, info.GetAreaId(), collisionExtent, collisionOffset); if ((collisionExtent.x < 0.f || collisionExtent.y < 0.f || collisionExtent.z < 0.f) || collisionExtent.isZero()) aabb = mData.GetBounds(xf.getRotation()); - return new CScriptGunTurret(mgr.AllocateUniqueId(), name, component, info, xf, std::move(mData), aabb, hInfo, dVuln, actParms, turretData); + return new CScriptGunTurret(mgr.AllocateUniqueId(), name, component, info, xf, std::move(mData), aabb, hInfo, dVuln, + actParms, turretData); } CEntity* ScriptLoader::LoadFogVolume(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -2439,9 +2446,9 @@ CEntity* ScriptLoader::LoadEnvFxDensityController(CStateManager& mgr, CInputStre u32 w1 = in.readUint32Big(); return new CScriptSpecialFunction(mgr.AllocateUniqueId(), name, info, zeus::CTransform::Identity(), - CScriptSpecialFunction::ESpecialFunction::EnvFxDensityController, "", density, - w1, 0.f, 0.f, zeus::CVector3f::skZero, zeus::CColor::skBlack, active, - CDamageInfo(), CAssetId(), CAssetId(), CAssetId(), -1, -1, -1); + CScriptSpecialFunction::ESpecialFunction::EnvFxDensityController, "", density, w1, + 0.f, 0.f, zeus::CVector3f::skZero, zeus::CColor::skBlack, active, CDamageInfo(), + CAssetId(), CAssetId(), CAssetId(), -1, -1, -1); } CEntity* ScriptLoader::LoadMagdolite(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -2464,11 +2471,6 @@ CEntity* ScriptLoader::LoadSnakeWeedSwarm(CStateManager& mgr, CInputStream& in, return nullptr; } -CEntity* ScriptLoader::Load(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) -{ - return nullptr; -} - CEntity* ScriptLoader::LoadActorContraption(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { @@ -2516,8 +2518,6 @@ CEntity* ScriptLoader::LoadGeemer(CStateManager& mgr, CInputStream& in, int prop return nullptr; } - - CEntity* ScriptLoader::LoadSpindleCamera(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { if (!EnsurePropertyCount(propCount, 24, "SpindleCamera")) @@ -2556,9 +2556,9 @@ CEntity* ScriptLoader::LoadSpindleCamera(CStateManager& mgr, CInputStream& in, i SSpindleProperty seg15(in); seg15.FixupAngles(); - return new CScriptSpindleCamera(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform, - active, flags, f1, f2, f3, f4, seg1, seg2, seg3, seg4, seg5, seg6, - seg7, seg8, seg9, seg10, seg11, seg12, seg13, seg14, seg15); + return new CScriptSpindleCamera(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform, active, flags, f1, + f2, f3, f4, seg1, seg2, seg3, seg4, seg5, seg6, seg7, seg8, seg9, seg10, seg11, + seg12, seg13, seg14, seg15); } CEntity* ScriptLoader::LoadAtomicAlpha(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -2601,16 +2601,45 @@ CEntity* ScriptLoader::LoadRumbleEffect(CStateManager& mgr, CInputStream& in, in u32 w1 = in.readUint32Big(); u32 pFlags = LoadParameterFlags(in); - return new CScriptSpecialFunction(mgr.AllocateUniqueId(), name, info, - ConvertEditorEulerToTransform4f(zeus::CVector3f::skZero, position), - CScriptSpecialFunction::ESpecialFunction::RumbleEffect, "", - f1, w1, pFlags, 0.f, zeus::CVector3f::skZero, - zeus::CColor::skBlack, active, {}, {}, {}, {}, -1, -1, -1); + return new CScriptSpecialFunction( + mgr.AllocateUniqueId(), name, info, ConvertEditorEulerToTransform4f(zeus::CVector3f::skZero, position), + CScriptSpecialFunction::ESpecialFunction::RumbleEffect, "", f1, w1, pFlags, 0.f, zeus::CVector3f::skZero, + zeus::CColor::skBlack, active, {}, {}, {}, {}, -1, -1, -1); } CEntity* ScriptLoader::LoadAmbientAI(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - return nullptr; + if (!EnsurePropertyCount(propCount, 16, "AmbientAI")) + return nullptr; + + SScaledActorHead head = LoadScaledActorHead(in, mgr); + zeus::CVector3f collisionExtent = zeus::CVector3f::ReadBig(in); + zeus::CVector3f collisionOffset = zeus::CVector3f::ReadBig(in); + float mass = in.readFloatBig(); + CHealthInfo hInfo(in); + CDamageVulnerability dVuln(in); + CAnimationParameters animParms = LoadAnimationParameters(in); + CActorParameters actParms = LoadActorParameters(in); + float alertRange = in.readFloatBig(); + float impactRange = in.readFloatBig(); + s32 alertAnim = in.readInt32Big(); + s32 impactAnim = in.readInt32Big(); + bool active = in.readBool(); + + if (!g_ResFactory->GetResourceTypeById(animParms.GetACSFile())) + return nullptr; + + zeus::CAABox aabox = GetCollisionBox(mgr, info.GetAreaId(), collisionExtent, collisionOffset); + + CMaterialList matList(EMaterialTypes::Immovable, EMaterialTypes::NonSolidDamageable); + + CModelData mData(CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), head.x40_scale, + animParms.GetInitialAnimation(), true)); + if ((collisionExtent.x < 0.f || collisionExtent.y < 0.f || collisionExtent.z < 0.f) || collisionExtent.isZero()) + aabox = mData.GetBounds(head.x10_transform.getRotation()); + + return new CAmbientAI(mgr.AllocateUniqueId(), head.x0_name, info, head.x10_transform, std::move(mData), aabox, + matList, mass, hInfo, dVuln, actParms, alertRange, impactRange, alertAnim, impactAnim, active); } CEntity* ScriptLoader::LoadAtomicBeta(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -2799,4 +2828,4 @@ CEntity* ScriptLoader::LoadEnergyBall(CStateManager& mgr, CInputStream& in, int { return nullptr; } -} +} // namespace urde diff --git a/Runtime/World/ScriptLoader.hpp b/Runtime/World/ScriptLoader.hpp index 6efb962f5..988712272 100644 --- a/Runtime/World/ScriptLoader.hpp +++ b/Runtime/World/ScriptLoader.hpp @@ -32,7 +32,6 @@ public: static CLightParameters LoadLightParameters(CInputStream& in); static CAnimationParameters LoadAnimationParameters(CInputStream& in); static CFluidUVMotion LoadFluidUVMotion(CInputStream& in); - static CCameraShakeData LoadCameraShakeData(CInputStream& in); static zeus::CTransform ConvertEditorEulerToTransform4f(const zeus::CVector3f& orientation, const zeus::CVector3f& position); @@ -135,7 +134,6 @@ public: static CEntity* LoadMagdolite(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info); static CEntity* LoadTeamAIMgr(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info); static CEntity* LoadSnakeWeedSwarm(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info); - static CEntity* Load(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info); static CEntity* LoadActorContraption(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info); static CEntity* LoadOculus(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info); static CEntity* LoadGeemer(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info); diff --git a/specter b/specter index ef3219dae..11cd223c8 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit ef3219dae294c3a83f6089a41ee4d37a491459c3 +Subproject commit 11cd223c88e9f298104747f204e9d64e6749530a