diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 000000000..a3c98d4fa --- /dev/null +++ b/.clang-tidy @@ -0,0 +1 @@ +Checks: '*,-misc-unused-parameters,-modernize-use-trailing-return-type,-readability-named-parameter,-readability-convert-member-functions-to-static,-readability-uppercase-literal-suffix,-readability-magic-numbers,-hicpp-uppercase-literal-suffix,-hicpp-signed-bitwise,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-non-private-member-variables-in-classes,-fuchsia-*,-google-runtime-references' diff --git a/CMakeLists.txt b/CMakeLists.txt index b747473f4..ba71b695e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,8 +36,15 @@ endif() project(urde VERSION 0.1.0) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) +# MSVC has a "latest" flag, which always uses the newest standard +# when available. GCC and Clang posess no such flag, and must be +# manually enforced. CMake, curiously, also doesn't have a "latest" +# standard flag either. +if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) +endif() + set(BUILD_SHARED_LIBS OFF CACHE BOOL "Force shared libs off" FORCE) set(BUILD_STATIC_LIBS ON CACHE BOOL "Force static libs on" FORCE) @@ -84,10 +91,17 @@ if(MSVC) set(HAVE_WORDS_BIGENDIAN_EXITCODE 0) endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") + add_compile_options(/EHsc) - # Link-time Code Generation for Release builds (excluding clang-cl) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + add_compile_options( + /std:c++latest # Use latest C++ standard. + /permissive- # Enforce various standards compliance features. + /Zc:externConstexpr # Allow extern constexpr variables according to the standard. + /Zc:throwingNew # Assume new throws, allowing for better code generation. + ) + + # Link-time Code Generation for Release builds (excluding clang-cl) set(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /O2 /Oy /GL /Gy /MD") set(CMAKE_C_FLAGS_RELWITHDEBINFO "/DNDEBUG /Zi /O2 /Oy- /GL /Gy /MD") set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "/LTCG") diff --git a/DataSpec/DNACommon/AROTBuilder.cpp b/DataSpec/DNACommon/AROTBuilder.cpp index 586f19d36..c31ae21f0 100644 --- a/DataSpec/DNACommon/AROTBuilder.cpp +++ b/DataSpec/DNACommon/AROTBuilder.cpp @@ -1,15 +1,19 @@ #include "AROTBuilder.hpp" + +#include +#include + #include "hecl/Blender/Connection.hpp" #include "PATH.hpp" namespace DataSpec { logvisor::Module Log("AROTBuilder"); -#define AROT_MAX_LEVEL 10 -#define AROT_MIN_SUBDIV 10.f -#define AROT_MIN_MODELS 8 -#define COLLISION_MIN_NODE_TRIANGLES 8 -#define PATH_MIN_NODE_REGIONS 16 +constexpr s32 AROT_MAX_LEVEL = 10; +constexpr s32 AROT_MIN_MODELS = 8; +constexpr s32 COLLISION_MIN_NODE_TRIANGLES = 8; +constexpr s32 PATH_MIN_NODE_REGIONS = 16; +constexpr float AROT_MIN_SUBDIV = 10.f; static zeus::CAABox SplitAABB(const zeus::CAABox& aabb, int i) { zeus::CAABox pos, neg; @@ -128,7 +132,9 @@ size_t AROTBuilder::BitmapPool::addIndices(const std::set& indices) { return m_pool.size() - 1; } -static const uint32_t AROTChildCounts[] = {0, 2, 2, 4, 2, 4, 4, 8}; +constexpr std::array AROTChildCounts{ + 0, 2, 2, 4, 2, 4, 4, 8, +}; void AROTBuilder::Node::nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff) { sz += 1; @@ -176,7 +182,7 @@ void AROTBuilder::Node::writeNodes(athena::io::MemoryWriter& w, int nodeIdx) { if (curIdx > 65535) Log.report(logvisor::Fatal, fmt("AROT node exceeds 16-bit node addressing; area too complex")); - int childIndices[8]; + std::array childIndices; for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) { for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) { @@ -280,17 +286,16 @@ void AROTBuilder::Node::pathWrite(DNAPATH::PATH& path, const zeus::CA n.aabb[0] = curAABB.min; n.aabb[1] = curAABB.max; n.centroid = curAABB.center(); - for (int i = 0; i < 8; ++i) - n.children[i] = 0xffffffff; + std::fill(std::begin(n.children), std::end(n.children), 0xFFFFFFFF); n.regionCount = childIndices.size(); n.regionStart = path.octreeRegionLookup.size(); for (int r : childIndices) path.octreeRegionLookup.push_back(r); } else { - atUint32 children[8]; - for (int i = 0; i < 8; ++i) { + std::array children; + for (size_t i = 0; i < children.size(); ++i) { /* Head recursion (first node will be a leaf) */ - childNodes[i].pathWrite(path, SplitAABB(curAABB, i)); + childNodes[i].pathWrite(path, SplitAABB(curAABB, static_cast(i))); children[i] = path.octree.size() - 1; } @@ -299,8 +304,7 @@ void AROTBuilder::Node::pathWrite(DNAPATH::PATH& path, const zeus::CA n.aabb[0] = curAABB.min; n.aabb[1] = curAABB.max; n.centroid = curAABB.center(); - for (int i = 0; i < 8; ++i) - n.children[i] = children[i]; + std::copy(children.cbegin(), children.cend(), std::begin(n.children)); n.regionCount = 0; n.regionStart = 0; } @@ -346,18 +350,20 @@ void AROTBuilder::build(std::vector>& secs, const zeus::CAA auto bmpIt = bmp.cbegin(); if (bmpIt != bmp.cend()) { int curIdx = 0; - for (size_t w = 0; w < bmpWordCount; ++w) { - for (int b = 0; b < 32; ++b) { + for (size_t word = 0; word < bmpWordCount; ++word) { + for (u32 b = 0; b < 32; ++b) { if (*bmpIt == curIdx) { - bmpWords[w] |= 1 << b; + bmpWords[word] |= 1U << b; ++bmpIt; - if (bmpIt == bmp.cend()) + if (bmpIt == bmp.cend()) { break; + } } ++curIdx; } - if (bmpIt == bmp.cend()) + if (bmpIt == bmp.cend()) { break; + } } } @@ -381,10 +387,10 @@ std::pair, uint32_t> AROTBuilder::buildCol(const ColM triBoxes.reserve(mesh.trianges.size()); for (const ColMesh::Triangle& tri : mesh.trianges) { zeus::CAABox& aabb = triBoxes.emplace_back(); - for (int e = 0; e < 3; ++e) { - const ColMesh::Edge& edge = mesh.edges[tri.edges[e]]; - for (int v = 0; v < 2; ++v) { - const auto& vert = mesh.verts[edge.verts[v]]; + for (const u32 edgeIdx : tri.edges) { + const ColMesh::Edge& edge = mesh.edges[edgeIdx]; + for (const u32 vertIdx : edge.verts) { + const auto& vert = mesh.verts[vertIdx]; aabb.accumulateBounds(zeus::CVector3f(vert)); } } diff --git a/DataSpec/DNACommon/ATBL.cpp b/DataSpec/DNACommon/ATBL.cpp index 24b4a37f1..10e5f3ead 100644 --- a/DataSpec/DNACommon/ATBL.cpp +++ b/DataSpec/DNACommon/ATBL.cpp @@ -48,9 +48,7 @@ bool ATBL::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat maxI = std::max(maxI, i); } - std::vector vecOut; - vecOut.resize(maxI + 1, 0xffff); - + std::vector vecOut(maxI + 1, 0xffff); for (const auto& pair : dr.getRootNode()->m_mapChildren) { unsigned long i = strtoul(pair.first.c_str(), nullptr, 0); vecOut[i] = hecl::SBig(uint16_t(strtoul(pair.second->m_scalarString.c_str(), nullptr, 0))); diff --git a/DataSpec/DNACommon/CRSC.cpp b/DataSpec/DNACommon/CRSC.cpp index e5e8c7878..45069cd35 100644 --- a/DataSpec/DNACommon/CRSC.cpp +++ b/DataSpec/DNACommon/CRSC.cpp @@ -1,248 +1,24 @@ #include "DataSpec/DNACommon/CRSC.hpp" - -#include - #include "DataSpec/DNACommon/PAK.hpp" -#include - namespace DataSpec::DNAParticle { -static const std::vector GeneratorTypes = { - SBIG('NODP'), SBIG('DEFS'), SBIG('CRTS'), SBIG('MTLS'), SBIG('GRAS'), SBIG('ICEE'), SBIG('GOOO'), SBIG('WODS'), - SBIG('WATR'), SBIG('1MUD'), SBIG('1LAV'), SBIG('1SAN'), SBIG('1PRJ'), SBIG('DCHR'), SBIG('DCHS'), SBIG('DCSH'), - SBIG('DENM'), SBIG('DESP'), SBIG('DESH'), SBIG('BTLE'), SBIG('WASP'), SBIG('TALP'), SBIG('PTGM'), SBIG('SPIR'), - SBIG('FPIR'), SBIG('FFLE'), SBIG('PARA'), SBIG('BMON'), SBIG('BFLR'), SBIG('PBOS'), SBIG('IBOS'), SBIG('1SVA'), - SBIG('1RPR'), SBIG('1MTR'), SBIG('1PDS'), SBIG('1FLB'), SBIG('1DRN'), SBIG('1MRE'), SBIG('CHOZ'), SBIG('JZAP'), - SBIG('1ISE'), SBIG('1BSE'), SBIG('1ATB'), SBIG('1ATA'), SBIG('BTSP'), SBIG('WWSP'), SBIG('TASP'), SBIG('TGSP'), - SBIG('SPSP'), SBIG('FPSP'), SBIG('FFSP'), SBIG('PSSP'), SBIG('BMSP'), SBIG('BFSP'), SBIG('PBSP'), SBIG('IBSP'), - SBIG('2SVA'), SBIG('2RPR'), SBIG('2MTR'), SBIG('2PDS'), SBIG('2FLB'), SBIG('2DRN'), SBIG('2MRE'), SBIG('CHSP'), - SBIG('JZSP'), SBIG('3ISE'), SBIG('3BSE'), SBIG('3ATB'), SBIG('3ATA'), SBIG('BTSH'), SBIG('WWSH'), SBIG('TASH'), - SBIG('TGSH'), SBIG('SPSH'), SBIG('FPSH'), SBIG('FFSH'), SBIG('PSSH'), SBIG('BMSH'), SBIG('BFSH'), SBIG('PBSH'), - SBIG('IBSH'), SBIG('3SVA'), SBIG('3RPR'), SBIG('3MTR'), SBIG('3PDS'), SBIG('3FLB'), SBIG('3DRN'), SBIG('3MRE'), - SBIG('CHSH'), SBIG('JZSH'), SBIG('5ISE'), SBIG('5BSE'), SBIG('5ATB'), SBIG('5ATA')}; -static const std::vector SFXTypes = { - SBIG('DSFX'), SBIG('CSFX'), SBIG('MSFX'), SBIG('GRFX'), SBIG('NSFX'), SBIG('DSFX'), SBIG('CSFX'), SBIG('MSFX'), - SBIG('GRFX'), SBIG('ICFX'), SBIG('GOFX'), SBIG('WSFX'), SBIG('WTFX'), SBIG('2MUD'), SBIG('2LAV'), SBIG('2SAN'), - SBIG('2PRJ'), SBIG('DCFX'), SBIG('DSFX'), SBIG('DSHX'), SBIG('DEFX'), SBIG('ESFX'), SBIG('SHFX'), SBIG('BEFX'), - SBIG('WWFX'), SBIG('TAFX'), SBIG('GTFX'), SBIG('SPFX'), SBIG('FPFX'), SBIG('FFFX'), SBIG('PAFX'), SBIG('BMFX'), - SBIG('BFFX'), SBIG('PBFX'), SBIG('IBFX'), SBIG('4SVA'), SBIG('4RPR'), SBIG('4MTR'), SBIG('4PDS'), SBIG('4FLB'), - SBIG('4DRN'), SBIG('4MRE'), SBIG('CZFX'), SBIG('JZAS'), SBIG('2ISE'), SBIG('2BSE'), SBIG('2ATB'), SBIG('2ATA'), - SBIG('BSFX'), SBIG('WSFX'), SBIG('TSFX'), SBIG('GSFX'), SBIG('SSFX'), SBIG('FSFX'), SBIG('SFFX'), SBIG('PSFX'), - SBIG('MSFX'), SBIG('SBFX'), SBIG('PBSX'), SBIG('IBSX'), SBIG('5SVA'), SBIG('5RPR'), SBIG('5MTR'), SBIG('5PDS'), - SBIG('5FLB'), SBIG('5DRN'), SBIG('5MRE'), SBIG('CSFX'), SBIG('JZPS'), SBIG('4ISE'), SBIG('4BSE'), SBIG('4ATB'), - SBIG('4ATA'), SBIG('BHFX'), SBIG('WHFX'), SBIG('THFX'), SBIG('GHFX'), SBIG('SHFX'), SBIG('FHFX'), SBIG('HFFX'), - SBIG('PHFX'), SBIG('MHFX'), SBIG('HBFX'), SBIG('PBHX'), SBIG('IBHX'), SBIG('6SVA'), SBIG('6RPR'), SBIG('6MTR'), - SBIG('6PDS'), SBIG('6FLB'), SBIG('6DRN'), SBIG('6MRE'), SBIG('CHFX'), SBIG('JZHS'), SBIG('6ISE'), SBIG('6BSE'), - SBIG('6ATB'), SBIG('6ATA'), -}; +template struct PPImpl<_CRSM>; +template struct PPImpl<_CRSM>; -static const std::vector DecalTypes = {SBIG('NCDL'), SBIG('DDCL'), SBIG('CODL'), SBIG('MEDL'), SBIG('GRDL'), - SBIG('ICDL'), SBIG('GODL'), SBIG('WODL'), SBIG('WTDL'), SBIG('3MUD'), - SBIG('3LAV'), SBIG('3SAN'), SBIG('CHDL'), SBIG('ENDL')}; +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_CRSM>) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_CRSM>) template <> -std::string_view CRSM::DNAType() { - return "CRSM"sv; +std::string_view PPImpl<_CRSM>::DNAType() { + return "urde::CRSM"sv; } template <> -std::string_view CRSM::DNAType() { - return "CRSM"sv; +std::string_view PPImpl<_CRSM>::DNAType() { + return "urde::CRSM"sv; } -template -void CRSM::_read(athena::io::YAMLDocReader& r) { - for (const auto& elem : r.getCurNode()->m_mapChildren) { - if (elem.first.size() < 4) { - LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), elem.first); - continue; - } - - if (auto rec = r.enterSubRecord(elem.first.c_str())) { - FourCC clsId(elem.first.c_str()); - auto gen = std::find_if(GeneratorTypes.begin(), GeneratorTypes.end(), - [&clsId](const FourCC& other) { return clsId == other; }); - if (gen != GeneratorTypes.end()) { - x0_generators[clsId].read(r); - continue; - } - - auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(), - [&clsId](const FourCC& other) { return clsId == other; }); - if (sfx != SFXTypes.end()) { - x10_sfx[clsId] = r.readInt32(clsId.toString()); - continue; - } - - auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(), - [&clsId](const FourCC& other) { return clsId == other; }); - if (decal != DecalTypes.end()) { - x20_decals[clsId].read(r); - continue; - } - if (clsId == SBIG('RNGE')) - x30_RNGE = r.readFloat(); - else if (clsId == SBIG('FOFF')) - x34_FOFF = r.readFloat(); - } - } -} - -template -void CRSM::_write(athena::io::YAMLDocWriter& w) const { - for (const auto& pair : x0_generators) - if (pair.second) - if (auto rec = w.enterSubRecord(pair.first.toString())) - pair.second.write(w); - - for (const auto& pair : x10_sfx) - if (pair.second != UINT32_MAX) - w.writeUint32(pair.first.toString(), pair.second); - - for (const auto& pair : x20_decals) - if (pair.second) - if (auto rec = w.enterSubRecord(pair.first.toString())) - pair.second.write(w); - - if (x30_RNGE != 50.f) - w.writeFloat("RNGE", x30_RNGE); - if (x34_FOFF != 0.2f) - w.writeFloat("FOFF", x34_FOFF); -} - -template -void CRSM::_binarySize(size_t& __isz) const { - __isz += 4; - for (const auto& pair : x0_generators) { - if (pair.second) { - __isz += 4; - pair.second.binarySize(__isz); - } - } - for (const auto& pair : x10_sfx) { - if (pair.second != UINT32_MAX) - __isz += 12; - } - - for (const auto& pair : x20_decals) { - if (pair.second) { - __isz += 4; - pair.second.binarySize(__isz); - } - } - - if (x30_RNGE != 50.f) - __isz += 12; - if (x34_FOFF != 0.2f) - __isz += 12; -} - -template -void CRSM::_read(athena::io::IStreamReader& r) { - DNAFourCC clsId; - clsId.read(r); - if (clsId != SBIG('CRSM')) { - LogModule.report(logvisor::Warning, fmt("non CRSM provided to CRSM parser")); - return; - } - - while (clsId != SBIG('_END')) { - clsId.read(r); - auto gen = std::find_if(GeneratorTypes.begin(), GeneratorTypes.end(), - [&clsId](const FourCC& other) { return clsId == other; }); - if (gen != GeneratorTypes.end()) { - x0_generators[clsId].read(r); - continue; - } - - auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(), - [&clsId](const FourCC& other) { return clsId == other; }); - if (sfx != SFXTypes.end()) { - DNAFourCC fcc; - fcc.read(r); - if (fcc != SBIG('NONE')) - x10_sfx[clsId] = r.readInt32Big(); - else - x10_sfx[clsId] = ~0; - continue; - } - - auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(), - [&clsId](const FourCC& other) { return clsId == other; }); - if (decal != DecalTypes.end()) { - x20_decals[clsId].read(r); - continue; - } - if (clsId == SBIG('RNGE')) { - r.readUint32(); - x30_RNGE = r.readFloatBig(); - continue; - } - if (clsId == SBIG('FOFF')) { - r.readUint32(); - x34_FOFF = r.readFloatBig(); - continue; - } - if (clsId != SBIG('_END')) - LogModule.report(logvisor::Fatal, fmt("Unknown CRSM class {} @{}"), clsId, r.position()); - } -} - -template -void CRSM::_write(athena::io::IStreamWriter& w) const { - w.writeBytes("CRSM", 4); - for (const auto& pair : x0_generators) { - w.writeBytes(pair.first.getChars(), 4); - pair.second.write(w); - } - - for (const auto& pair : x10_sfx) { - w.writeBytes(pair.first.getChars(), 4); - if (pair.second != UINT32_MAX) { - w.writeBytes("CNST", 4); - w.writeUint32Big(pair.second); - } else { - w.writeBytes("NONE", 4); - } - } - - for (const auto& pair : x20_decals) { - w.writeBytes(pair.first.getChars(), 4); - pair.second.write(w); - } - - if (x30_RNGE != 50.f) { - w.writeBytes("RNGECNST", 8); - w.writeFloatBig(x30_RNGE); - } - if (x34_FOFF != 0.2f) { - w.writeBytes("FOFFCNST", 8); - w.writeFloatBig(x34_FOFF); - } - w.writeBytes("_END", 4); -} - -AT_SUBSPECIALIZE_DNA_YAML(CRSM) -AT_SUBSPECIALIZE_DNA_YAML(CRSM) - -template -void CRSM::gatherDependencies(std::vector& pathsOut) const { - for (const auto& p : x0_generators) - g_curSpec->flattenDependencies(p.second.id, pathsOut); - for (const auto& p : x20_decals) - g_curSpec->flattenDependencies(p.second.id, pathsOut); -} - -template -CRSM::CRSM() : x30_RNGE(50.f), x34_FOFF(0.2f) { - for (const auto& sfx : SFXTypes) - x10_sfx[sfx] = ~0; -} - -template struct CRSM; -template struct CRSM; - template bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { athena::io::FileWriter writer(outPath.getAbsolutePath()); diff --git a/DataSpec/DNACommon/CRSC.def b/DataSpec/DNACommon/CRSC.def new file mode 100644 index 000000000..6fe2e2b7e --- /dev/null +++ b/DataSpec/DNACommon/CRSC.def @@ -0,0 +1,222 @@ +#ifndef ENTRY +#define ENTRY(name, identifier) +#endif + +#ifndef RES_ENTRY +#define RES_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef U32_ENTRY +#define U32_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef FLOAT_ENTRY +#define FLOAT_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +RES_ENTRY('NODP', NODP) +RES_ENTRY('DEFS', DEFS) +RES_ENTRY('CRTS', CRTS) +RES_ENTRY('MTLS', MTLS) +RES_ENTRY('GRAS', GRAS) +RES_ENTRY('ICEE', ICEE) +RES_ENTRY('GOOO', GOOO) +RES_ENTRY('WODS', WODS) +RES_ENTRY('WATR', WATR) +RES_ENTRY('1MUD', _1MUD) +RES_ENTRY('1LAV', _1LAV) +RES_ENTRY('1SAN', _1SAN) +RES_ENTRY('1PRJ', _1PRJ) +RES_ENTRY('DCHR', DCHR) +RES_ENTRY('DCHS', DCHS) +RES_ENTRY('DCSH', DCSH) +RES_ENTRY('DENM', DENM) +RES_ENTRY('DESP', DESP) +RES_ENTRY('DESH', DESH) +RES_ENTRY('BTLE', BTLE) +RES_ENTRY('WASP', WASP) +RES_ENTRY('TALP', TALP) +RES_ENTRY('PTGM', PTGM) +RES_ENTRY('SPIR', SPIR) +RES_ENTRY('FPIR', FPIR) +RES_ENTRY('FFLE', FFLE) +RES_ENTRY('PARA', PARA) +RES_ENTRY('BMON', BMON) +RES_ENTRY('BFLR', BFLR) +RES_ENTRY('PBOS', PBOS) +RES_ENTRY('IBOS', IBOS) +RES_ENTRY('1SVA', _1SVA) +RES_ENTRY('1RPR', _1RPR) +RES_ENTRY('1MTR', _1MTR) +RES_ENTRY('1PDS', _1PDS) +RES_ENTRY('1FLB', _1FLB) +RES_ENTRY('1DRN', _1DRN) +RES_ENTRY('1MRE', _1MRE) +RES_ENTRY('CHOZ', CHOZ) +RES_ENTRY('JZAP', JZAP) +RES_ENTRY('1ISE', _1ISE) +RES_ENTRY('1BSE', _1BSE) +RES_ENTRY('1ATB', _1ATB) +RES_ENTRY('1ATA', _1ATA) +RES_ENTRY('BTSP', BTSP) +RES_ENTRY('WWSP', WWSP) +RES_ENTRY('TASP', TASP) +RES_ENTRY('TGSP', TGSP) +RES_ENTRY('SPSP', SPSP) +RES_ENTRY('FPSP', FPSP) +RES_ENTRY('FFSP', FFSP) +RES_ENTRY('PSSP', PSSP) +RES_ENTRY('BMSP', BMSP) +RES_ENTRY('BFSP', BFSP) +RES_ENTRY('PBSP', PBSP) +RES_ENTRY('IBSP', IBSP) +RES_ENTRY('2SVA', _2SVA) +RES_ENTRY('2RPR', _2RPR) +RES_ENTRY('2MTR', _2MTR) +RES_ENTRY('2PDS', _2PDS) +RES_ENTRY('2FLB', _2FLB) +RES_ENTRY('2DRN', _2DRN) +RES_ENTRY('2MRE', _2MRE) +RES_ENTRY('CHSP', CHSP) +RES_ENTRY('JZSP', JZSP) +RES_ENTRY('3ISE', _3ISE) +RES_ENTRY('3BSE', _3BSE) +RES_ENTRY('3ATB', _3ATB) +RES_ENTRY('3ATA', _3ATA) +RES_ENTRY('BTSH', BTSH) +RES_ENTRY('WWSH', WWSH) +RES_ENTRY('TASH', TASH) +RES_ENTRY('TGSH', TGSH) +RES_ENTRY('SPSH', SPSH) +RES_ENTRY('FPSH', FPSH) +RES_ENTRY('FFSH', FFSH) +RES_ENTRY('PSSH', PSSH) +RES_ENTRY('BMSH', BMSH) +RES_ENTRY('BFSH', BFSH) +RES_ENTRY('PBSH', PBSH) +RES_ENTRY('IBSH', IBSH) +RES_ENTRY('3SVA', _3SVA) +RES_ENTRY('3RPR', _3RPR) +RES_ENTRY('3MTR', _3MTR) +RES_ENTRY('3PDS', _3PDS) +RES_ENTRY('3FLB', _3FLB) +RES_ENTRY('3DRN', _3DRN) +RES_ENTRY('3MRE', _3MRE) +RES_ENTRY('CHSH', CHSH) +RES_ENTRY('JZSH', JZSH) +RES_ENTRY('5ISE', _5ISE) +RES_ENTRY('5BSE', _5BSE) +RES_ENTRY('5ATB', _5ATB) +RES_ENTRY('5ATA', _5ATA) +RES_ENTRY('NCDL', NCDL) +RES_ENTRY('DDCL', DDCL) +RES_ENTRY('CODL', CODL) +RES_ENTRY('MEDL', MEDL) +RES_ENTRY('GRDL', GRDL) +RES_ENTRY('ICDL', ICDL) +RES_ENTRY('GODL', GODL) +RES_ENTRY('WODL', WODL) +RES_ENTRY('WTDL', WTDL) +RES_ENTRY('3MUD', _3MUD) +RES_ENTRY('3LAV', _3LAV) +RES_ENTRY('3SAN', _3SAN) +RES_ENTRY('CHDL', CHDL) +RES_ENTRY('ENDL', ENDL) + +U32_ENTRY('NSFX', NSFX) +U32_ENTRY('DSFX', DSFX) +U32_ENTRY('CSFX', CSFX) +U32_ENTRY('MSFX', MSFX) +U32_ENTRY('GRFX', GRFX) +U32_ENTRY('ICFX', ICFX) +U32_ENTRY('GOFX', GOFX) +U32_ENTRY('WSFX', WSFX) +U32_ENTRY('WTFX', WTFX) +U32_ENTRY('2MUD', _2MUD) +U32_ENTRY('2LAV', _2LAV) +U32_ENTRY('2SAN', _2SAN) +U32_ENTRY('2PRJ', _2PRJ) +U32_ENTRY('DCFX', DCFX) +U32_ENTRY('DSHX', DSHX) +U32_ENTRY('DEFX', DEFX) +U32_ENTRY('ESFX', ESFX) +U32_ENTRY('SHFX', SHFX) +U32_ENTRY('BEFX', BEFX) +U32_ENTRY('WWFX', WWFX) +U32_ENTRY('TAFX', TAFX) +U32_ENTRY('GTFX', GTFX) +U32_ENTRY('SPFX', SPFX) +U32_ENTRY('FPFX', FPFX) +U32_ENTRY('FFFX', FFFX) +U32_ENTRY('PAFX', PAFX) +U32_ENTRY('BMFX', BMFX) +U32_ENTRY('BFFX', BFFX) +U32_ENTRY('PBFX', PBFX) +U32_ENTRY('IBFX', IBFX) +U32_ENTRY('4SVA', _4SVA) +U32_ENTRY('4RPR', _4RPR) +U32_ENTRY('4MTR', _4MTR) +U32_ENTRY('4PDS', _4PDS) +U32_ENTRY('4FLB', _4FLB) +U32_ENTRY('4DRN', _4DRN) +U32_ENTRY('4MRE', _4MRE) +U32_ENTRY('CZFX', CZFX) +U32_ENTRY('JZAS', JZAS) +U32_ENTRY('2ISE', _2ISE) +U32_ENTRY('2BSE', _2BSE) +U32_ENTRY('2ATB', _2ATB) +U32_ENTRY('2ATA', _2ATA) +U32_ENTRY('BSFX', BSFX) +U32_ENTRY('TSFX', TSFX) +U32_ENTRY('GSFX', GSFX) +U32_ENTRY('SSFX', SSFX) +U32_ENTRY('FSFX', FSFX) +U32_ENTRY('SFFX', SFFX) +U32_ENTRY('PSFX', PSFX) +U32_ENTRY('SBFX', SBFX) +U32_ENTRY('PBSX', PBSX) +U32_ENTRY('IBSX', IBSX) +U32_ENTRY('5SVA', _5SVA) +U32_ENTRY('5RPR', _5RPR) +U32_ENTRY('5MTR', _5MTR) +U32_ENTRY('5PDS', _5PDS) +U32_ENTRY('5FLB', _5FLB) +U32_ENTRY('5DRN', _5DRN) +U32_ENTRY('5MRE', _5MRE) +U32_ENTRY('JZPS', JZPS) +U32_ENTRY('4ISE', _4ISE) +U32_ENTRY('4BSE', _4BSE) +U32_ENTRY('4ATB', _4ATB) +U32_ENTRY('4ATA', _4ATA) +U32_ENTRY('BHFX', BHFX) +U32_ENTRY('WHFX', WHFX) +U32_ENTRY('THFX', THFX) +U32_ENTRY('GHFX', GHFX) +U32_ENTRY('FHFX', FHFX) +U32_ENTRY('HFFX', HFFX) +U32_ENTRY('PHFX', PHFX) +U32_ENTRY('MHFX', MHFX) +U32_ENTRY('HBFX', HBFX) +U32_ENTRY('PBHX', PBHX) +U32_ENTRY('IBHX', IBHX) +U32_ENTRY('6SVA', _6SVA) +U32_ENTRY('6RPR', _6RPR) +U32_ENTRY('6MTR', _6MTR) +U32_ENTRY('6PDS', _6PDS) +U32_ENTRY('6FLB', _6FLB) +U32_ENTRY('6DRN', _6DRN) +U32_ENTRY('6MRE', _6MRE) +U32_ENTRY('CHFX', CHFX) +U32_ENTRY('JZHS', JZHS) +U32_ENTRY('6ISE', _6ISE) +U32_ENTRY('6BSE', _6BSE) +U32_ENTRY('6ATB', _6ATB) +U32_ENTRY('6ATA', _6ATA) + +FLOAT_ENTRY('RNGE', x30_RNGE) +FLOAT_ENTRY('FOFF', x34_FOFF) + +#undef ENTRY +#undef RES_ENTRY +#undef U32_ENTRY +#undef FLOAT_ENTRY diff --git a/DataSpec/DNACommon/CRSC.hpp b/DataSpec/DNACommon/CRSC.hpp index 3bc7ff2f1..bab40f942 100644 --- a/DataSpec/DNACommon/CRSC.hpp +++ b/DataSpec/DNACommon/CRSC.hpp @@ -18,20 +18,33 @@ class ProjectPath; } namespace DataSpec::DNAParticle { + template -struct CRSM : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - std::unordered_map> x0_generators; - std::unordered_map x10_sfx; - std::unordered_map> x20_decals; - float x30_RNGE; - float x34_FOFF; +struct _CRSM { + static constexpr ParticleType Type = ParticleType::CRSM; +#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; +#define U32_ENTRY(name, identifier) uint32_t identifier = ~0; +#define FLOAT_ENTRY(name, identifier) float identifier = 0.f; +#include "CRSC.def" - CRSM(); + template + void constexpr Enumerate(_Func f) { +#define ENTRY(name, identifier) f(FOURCC(name), identifier); +#include "CRSC.def" + } - void gatherDependencies(std::vector&) const; + template + bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { +#define ENTRY(name, identifier) case SBIG(name): f(identifier); return true; +#include "CRSC.def" + default: return false; + } + } }; +template +using CRSM = PPImpl<_CRSM>; + template bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); diff --git a/DataSpec/DNACommon/DNACommon.hpp b/DataSpec/DNACommon/DNACommon.hpp index e66593c9d..08587bb3d 100644 --- a/DataSpec/DNACommon/DNACommon.hpp +++ b/DataSpec/DNACommon/DNACommon.hpp @@ -118,40 +118,40 @@ public: using value_type = uint32_t; static UniqueID32 kInvalidId; AT_DECL_EXPLICIT_DNA_YAML - bool isValid() const { return m_id != 0xffffffff && m_id != 0; } - void assign(uint32_t id) { m_id = id ? id : 0xffffffff; } + bool isValid() const noexcept { return m_id != 0xffffffff && m_id != 0; } + void assign(uint32_t id) noexcept { m_id = id ? id : 0xffffffff; } - UniqueID32& operator=(const hecl::ProjectPath& path) { + UniqueID32& operator=(const hecl::ProjectPath& path) noexcept { assign(path.parsedHash32()); return *this; } - bool operator!=(const UniqueID32& other) const { return m_id != other.m_id; } - bool operator==(const UniqueID32& other) const { return m_id == other.m_id; } - bool operator<(const UniqueID32& other) const { return m_id < other.m_id; } - uint32_t toUint32() const { return m_id; } - uint64_t toUint64() const { return m_id; } + bool operator!=(const UniqueID32& other) const noexcept { return m_id != other.m_id; } + bool operator==(const UniqueID32& other) const noexcept { return m_id == other.m_id; } + bool operator<(const UniqueID32& other) const noexcept { return m_id < other.m_id; } + uint32_t toUint32() const noexcept { return m_id; } + uint64_t toUint64() const noexcept { return m_id; } std::string toString() const; - void clear() { m_id = 0xffffffff; } + void clear() noexcept { m_id = 0xffffffff; } - UniqueID32() = default; - UniqueID32(uint32_t idin) { assign(idin); } + UniqueID32() noexcept = default; + UniqueID32(uint32_t idin) noexcept { assign(idin); } UniqueID32(athena::io::IStreamReader& reader) { read(reader); } - UniqueID32(const hecl::ProjectPath& path) { *this = path; } - UniqueID32(const char* hexStr) { + UniqueID32(const hecl::ProjectPath& path) noexcept { *this = path; } + UniqueID32(const char* hexStr) noexcept { char copy[9]; strncpy(copy, hexStr, 8); copy[8] = '\0'; assign(strtoul(copy, nullptr, 16)); } - UniqueID32(const wchar_t* hexStr) { + UniqueID32(const wchar_t* hexStr) noexcept{ wchar_t copy[9]; wcsncpy(copy, hexStr, 8); copy[8] = L'\0'; assign(wcstoul(copy, nullptr, 16)); } - static constexpr size_t BinarySize() { return 4; } + static constexpr size_t BinarySize() noexcept { return 4; } }; /** PAK 32-bit Unique ID - writes zero when invalid */ @@ -169,39 +169,39 @@ class UniqueID64 : public BigDNA { public: using value_type = uint64_t; AT_DECL_EXPLICIT_DNA_YAML - bool isValid() const { return m_id != 0xffffffffffffffff && m_id != 0; } - void assign(uint64_t id) { m_id = id ? id : 0xffffffffffffffff; } + bool isValid() const noexcept { return m_id != 0xffffffffffffffff && m_id != 0; } + void assign(uint64_t id) noexcept { m_id = id ? id : 0xffffffffffffffff; } - UniqueID64& operator=(const hecl::ProjectPath& path) { + UniqueID64& operator=(const hecl::ProjectPath& path) noexcept { assign(path.hash().val64()); return *this; } - bool operator!=(const UniqueID64& other) const { return m_id != other.m_id; } - bool operator==(const UniqueID64& other) const { return m_id == other.m_id; } - bool operator<(const UniqueID64& other) const { return m_id < other.m_id; } - uint64_t toUint64() const { return m_id; } + bool operator!=(const UniqueID64& other) const noexcept { return m_id != other.m_id; } + bool operator==(const UniqueID64& other) const noexcept { return m_id == other.m_id; } + bool operator<(const UniqueID64& other) const noexcept { return m_id < other.m_id; } + uint64_t toUint64() const noexcept { return m_id; } std::string toString() const; - void clear() { m_id = 0xffffffffffffffff; } + void clear() noexcept { m_id = 0xffffffffffffffff; } - UniqueID64() = default; - UniqueID64(uint64_t idin) { assign(idin); } + UniqueID64() noexcept = default; + UniqueID64(uint64_t idin) noexcept { assign(idin); } UniqueID64(athena::io::IStreamReader& reader) { read(reader); } - UniqueID64(const hecl::ProjectPath& path) { *this = path; } - UniqueID64(const char* hexStr) { + UniqueID64(const hecl::ProjectPath& path) noexcept { *this = path; } + UniqueID64(const char* hexStr) noexcept { char copy[17]; std::strncpy(copy, hexStr, 16); copy[16] = '\0'; assign(std::strtoull(copy, nullptr, 16)); } - UniqueID64(const wchar_t* hexStr) { + UniqueID64(const wchar_t* hexStr) noexcept { wchar_t copy[17]; std::wcsncpy(copy, hexStr, 16); copy[16] = L'\0'; assign(std::wcstoull(copy, nullptr, 16)); } - static constexpr size_t BinarySize() { return 8; } + static constexpr size_t BinarySize() noexcept { return 8; } }; /** PAK 128-bit Unique ID */ @@ -220,26 +220,26 @@ private: public: using value_type = uint64_t; AT_DECL_EXPLICIT_DNA_YAML - UniqueID128() { + UniqueID128() noexcept { m_id.id[0] = 0xffffffffffffffff; m_id.id[1] = 0xffffffffffffffff; } - UniqueID128(uint64_t idin) { + UniqueID128(uint64_t idin) noexcept { m_id.id[0] = idin; m_id.id[1] = 0; } - bool isValid() const { + bool isValid() const noexcept { return m_id.id[0] != 0xffffffffffffffff && m_id.id[0] != 0 && m_id.id[1] != 0xffffffffffffffff && m_id.id[1] != 0; } - UniqueID128& operator=(const hecl::ProjectPath& path) { + UniqueID128& operator=(const hecl::ProjectPath& path) noexcept { m_id.id[0] = path.hash().val64(); m_id.id[1] = 0; return *this; } - UniqueID128(const hecl::ProjectPath& path) { *this = path; } + UniqueID128(const hecl::ProjectPath& path) noexcept { *this = path; } - bool operator!=(const UniqueID128& other) const { + bool operator!=(const UniqueID128& other) const noexcept { #if __SSE__ __m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128); int vmask = _mm_movemask_epi8(vcmp); @@ -248,7 +248,7 @@ public: return (m_id.id[0] != other.m_id.id[0]) || (m_id.id[1] != other.m_id.id[1]); #endif } - bool operator==(const UniqueID128& other) const { + bool operator==(const UniqueID128& other) const noexcept { #if __SSE__ __m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128); int vmask = _mm_movemask_epi8(vcmp); @@ -257,19 +257,19 @@ public: return (m_id.id[0] == other.m_id.id[0]) && (m_id.id[1] == other.m_id.id[1]); #endif } - bool operator<(const UniqueID128& other) const { + bool operator<(const UniqueID128& other) const noexcept { return m_id.id[0] < other.m_id.id[0] || (m_id.id[0] == other.m_id.id[0] && m_id.id[1] < other.m_id.id[1]); } - void clear() { + void clear() noexcept { m_id.id[0] = 0xffffffffffffffff; m_id.id[1] = 0xffffffffffffffff; } - uint64_t toUint64() const { return m_id.id[0]; } - uint64_t toHighUint64() const { return m_id.id[0]; } - uint64_t toLowUint64() const { return m_id.id[1]; } + uint64_t toUint64() const noexcept { return m_id.id[0]; } + uint64_t toHighUint64() const noexcept { return m_id.id[0]; } + uint64_t toLowUint64() const noexcept { return m_id.id[1]; } std::string toString() const; - static constexpr size_t BinarySize() { return 16; } + static constexpr size_t BinarySize() noexcept { return 16; } }; /** Casts ID type to its null-zero equivalent */ @@ -340,7 +340,7 @@ public: }; /** Resource cooker function */ -typedef std::function ResCooker; +using ResCooker = std::function; /** Mappings of resources involved in extracting characters */ template @@ -377,22 +377,22 @@ inline hecl::ProjectPath GetPathBeginsWith(const hecl::ProjectPath& parentPath, namespace std { template <> struct hash { - size_t operator()(const DataSpec::DNAFourCC& fcc) const { return fcc.toUint32(); } + size_t operator()(const DataSpec::DNAFourCC& fcc) const noexcept{ return fcc.toUint32(); } }; template <> struct hash { - size_t operator()(const DataSpec::UniqueID32& id) const { return id.toUint32(); } + size_t operator()(const DataSpec::UniqueID32& id) const noexcept{ return id.toUint32(); } }; template <> struct hash { - size_t operator()(const DataSpec::UniqueID64& id) const { return id.toUint64(); } + size_t operator()(const DataSpec::UniqueID64& id) const noexcept{ return id.toUint64(); } }; template <> struct hash { - size_t operator()(const DataSpec::UniqueID128& id) const { return id.toHighUint64() ^ id.toLowUint64(); } + size_t operator()(const DataSpec::UniqueID128& id) const noexcept { return id.toHighUint64() ^ id.toLowUint64(); } }; } // namespace std diff --git a/DataSpec/DNACommon/DPSC.cpp b/DataSpec/DNACommon/DPSC.cpp index ed3bc334d..4b88eda08 100644 --- a/DataSpec/DNACommon/DPSC.cpp +++ b/DataSpec/DNACommon/DPSC.cpp @@ -1,391 +1,24 @@ #include "DataSpec/DNACommon/DPSC.hpp" - #include "DataSpec/DNACommon/PAK.hpp" -#include -#include - namespace DataSpec::DNAParticle { +template struct PPImpl<_DPSM>; +template struct PPImpl<_DPSM>; + +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_DPSM>) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_DPSM>) + template <> -std::string_view DPSM::DNAType() { +std::string_view PPImpl<_DPSM>::DNAType() { return "DPSM"sv; } template <> -std::string_view DPSM::DNAType() { +std::string_view PPImpl<_DPSM>::DNAType() { return "DPSM"sv; } -template -void DPSM::_read(athena::io::YAMLDocReader& r) { - for (const auto& elem : r.getCurNode()->m_mapChildren) { - if (elem.first.size() < 4) { - LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), elem.first); - continue; - } - - if (auto rec = r.enterSubRecord(elem.first.c_str())) { - bool loadFirstDesc = false; - uint32_t clsId = *reinterpret_cast(elem.first.c_str()); - switch (clsId) { - case SBIG('1SZE'): - case SBIG('1LFT'): - case SBIG('1ROT'): - case SBIG('1OFF'): - case SBIG('1CLR'): - case SBIG('1TEX'): - case SBIG('1ADD'): - loadFirstDesc = true; - [[fallthrough]]; - case SBIG('2SZE'): - case SBIG('2LFT'): - case SBIG('2ROT'): - case SBIG('2OFF'): - case SBIG('2CLR'): - case SBIG('2TEX'): - case SBIG('2ADD'): - if (loadFirstDesc) - readQuadDecalInfo(r, clsId, x0_quad); - else - readQuadDecalInfo(r, clsId, x1c_quad); - break; - case SBIG('DMDL'): - x38_DMDL.read(r); - break; - case SBIG('DLFT'): - x48_DLFT.read(r); - break; - case SBIG('DMOP'): - x4c_DMOP.read(r); - break; - case SBIG('DMRT'): - x50_DMRT.read(r); - break; - case SBIG('DMSC'): - x54_DMSC.read(r); - break; - case SBIG('DMCL'): - x58_DMCL.read(r); - break; - case SBIG('DMAB'): - x5c_24_DMAB = r.readBool(); - break; - case SBIG('DMOO'): - x5c_25_DMOO = r.readBool(); - break; - } - } - } -} - -template -void DPSM::_write(athena::io::YAMLDocWriter& w) const { - writeQuadDecalInfo(w, x0_quad, true); - writeQuadDecalInfo(w, x1c_quad, false); - - if (x38_DMDL) - if (auto rec = w.enterSubRecord("DMDL")) - x38_DMDL.write(w); - if (x48_DLFT) - if (auto rec = w.enterSubRecord("DLFT")) - x48_DLFT.write(w); - if (x4c_DMOP) - if (auto rec = w.enterSubRecord("DMOP")) - x4c_DMOP.write(w); - if (x50_DMRT) - if (auto rec = w.enterSubRecord("DMRT")) - x50_DMRT.write(w); - if (x54_DMSC) - if (auto rec = w.enterSubRecord("DMSC")) - x54_DMSC.write(w); - if (x58_DMCL) - if (auto rec = w.enterSubRecord("DMCL")) - x54_DMSC.write(w); - - if (x5c_24_DMAB) - w.writeBool("DMAB", x5c_24_DMAB); - if (x5c_25_DMOO) - w.writeBool("DMOO", x5c_25_DMOO); -} - -template -template -void DPSM::readQuadDecalInfo(Reader& r, FourCC clsId, typename DPSM::SQuadDescr& quad) { - switch (clsId.toUint32()) { - case SBIG('1LFT'): - case SBIG('2LFT'): - quad.x0_LFT.read(r); - break; - case SBIG('1SZE'): - case SBIG('2SZE'): - quad.x4_SZE.read(r); - break; - case SBIG('1ROT'): - case SBIG('2ROT'): - quad.x8_ROT.read(r); - break; - case SBIG('1OFF'): - case SBIG('2OFF'): - quad.xc_OFF.read(r); - break; - case SBIG('1CLR'): - case SBIG('2CLR'): - quad.x10_CLR.read(r); - break; - case SBIG('1TEX'): - case SBIG('2TEX'): - quad.x14_TEX.read(r); - break; - case SBIG('1ADD'): - case SBIG('2ADD'): - quad.x18_ADD.read(r); - break; - } -} - -template -void DPSM::writeQuadDecalInfo(athena::io::YAMLDocWriter& w, const typename DPSM::SQuadDescr& quad, - bool first) const { - if (quad.x0_LFT) - if (auto rec = w.enterSubRecord((first ? "1LFT" : "2LFT"))) - quad.x0_LFT.write(w); - if (quad.x4_SZE) - if (auto rec = w.enterSubRecord((first ? "1SZE" : "2SZE"))) - quad.x4_SZE.write(w); - if (quad.x8_ROT) - if (auto rec = w.enterSubRecord((first ? "1ROT" : "2ROT"))) - quad.x8_ROT.write(w); - if (quad.xc_OFF) - if (auto rec = w.enterSubRecord((first ? "1OFF" : "2OFF"))) - quad.xc_OFF.write(w); - if (quad.x10_CLR) - if (auto rec = w.enterSubRecord((first ? "1CLR" : "2CLR"))) - quad.x10_CLR.write(w); - if (quad.x14_TEX) - if (auto rec = w.enterSubRecord((first ? "1TEX" : "2TEX"))) - quad.x14_TEX.write(w); - if (quad.x18_ADD) - if (auto rec = w.enterSubRecord((first ? "1ADD" : "2ADD"))) - quad.x18_ADD.write(w); -} - -template -void DPSM::_binarySize(size_t& s) const { - s += 4; - getQuadDecalBinarySize(s, x0_quad); - getQuadDecalBinarySize(s, x1c_quad); - if (x38_DMDL) { - s += 4; - x38_DMDL.binarySize(s); - } - if (x48_DLFT) { - s += 4; - x48_DLFT.binarySize(s); - } - if (x4c_DMOP) { - s += 4; - x4c_DMOP.binarySize(s); - } - if (x50_DMRT) { - s += 4; - x50_DMRT.binarySize(s); - } - if (x54_DMSC) { - s += 4; - x54_DMSC.binarySize(s); - } - if (x58_DMCL) { - x58_DMCL.binarySize(s); - } - if (x5c_24_DMAB) - s += 9; - if (x5c_25_DMOO) - s += 9; -} - -template -void DPSM::getQuadDecalBinarySize(size_t& s, const typename DPSM::SQuadDescr& quad) const { - if (quad.x0_LFT) { - s += 4; - quad.x0_LFT.binarySize(s); - } - if (quad.x4_SZE) { - s += 4; - quad.x4_SZE.binarySize(s); - } - if (quad.x8_ROT) { - s += 4; - quad.x8_ROT.binarySize(s); - } - if (quad.xc_OFF) { - s += 4; - quad.xc_OFF.binarySize(s); - } - if (quad.x10_CLR) { - s += 4; - quad.x10_CLR.binarySize(s); - } - if (quad.x14_TEX) { - s += 4; - quad.x14_TEX.binarySize(s); - } - if (quad.x18_ADD) { - s += 4; - quad.x18_ADD.binarySize(s); - } -} - -template -void DPSM::_read(athena::io::IStreamReader& r) { - DNAFourCC clsId; - clsId.read(r); - if (clsId != SBIG('DPSM')) { - LogModule.report(logvisor::Warning, fmt("non DPSM provided to DPSM parser")); - return; - } - bool loadFirstDesc = false; - clsId.read(r); - while (clsId != SBIG('_END')) { - switch (clsId.toUint32()) { - case SBIG('1SZE'): - case SBIG('1LFT'): - case SBIG('1ROT'): - case SBIG('1OFF'): - case SBIG('1CLR'): - case SBIG('1TEX'): - case SBIG('1ADD'): - loadFirstDesc = true; - [[fallthrough]]; - case SBIG('2SZE'): - case SBIG('2LFT'): - case SBIG('2ROT'): - case SBIG('2OFF'): - case SBIG('2CLR'): - case SBIG('2TEX'): - case SBIG('2ADD'): - if (loadFirstDesc) - readQuadDecalInfo(r, clsId, x0_quad); - else - readQuadDecalInfo(r, clsId, x1c_quad); - break; - case SBIG('DMDL'): - x38_DMDL.read(r); - break; - case SBIG('DLFT'): - x48_DLFT.read(r); - break; - case SBIG('DMOP'): - x4c_DMOP.read(r); - break; - case SBIG('DMRT'): - x50_DMRT.read(r); - break; - case SBIG('DMSC'): - x54_DMSC.read(r); - break; - case SBIG('DMCL'): - x58_DMCL.read(r); - break; - case SBIG('DMAB'): - r.readUint32(); - x5c_24_DMAB = r.readBool(); - break; - case SBIG('DMOO'): - r.readUint32(); - x5c_25_DMOO = r.readBool(); - break; - default: - LogModule.report(logvisor::Fatal, fmt("Unknown DPSM class {} @{}"), clsId, r.position()); - break; - } - clsId.read(r); - } -} - -template -void DPSM::_write(athena::io::IStreamWriter& w) const { - w.writeBytes("DPSM", 4); - writeQuadDecalInfo(w, x0_quad, true); - writeQuadDecalInfo(w, x1c_quad, false); - if (x38_DMDL) { - w.writeBytes("DMDL", 4); - x38_DMDL.write(w); - } - if (x48_DLFT) { - w.writeBytes("DLFT", 4); - x48_DLFT.write(w); - } - if (x4c_DMOP) { - w.writeBytes("DMOP", 4); - x4c_DMOP.write(w); - } - if (x50_DMRT) { - w.writeBytes("DMRT", 4); - x50_DMRT.write(w); - } - if (x54_DMSC) { - w.writeBytes("DMSC", 4); - x54_DMSC.write(w); - } - if (x58_DMCL) { - w.writeBytes("DMCL", 4); - x58_DMCL.write(w); - } - if (x5c_24_DMAB) - w.writeBytes("DMABCNST\x01", 9); - if (x5c_25_DMOO) - w.writeBytes("DMOOCNST\x01", 9); - w.writeBytes("_END", 4); -} - -template -void DPSM::writeQuadDecalInfo(athena::io::IStreamWriter& w, const typename DPSM::SQuadDescr& quad, - bool first) const { - if (quad.x0_LFT) { - w.writeBytes((first ? "1LFT" : "2LFT"), 4); - quad.x0_LFT.write(w); - } - if (quad.x4_SZE) { - w.writeBytes((first ? "1SZE" : "2SZE"), 4); - quad.x4_SZE.write(w); - } - if (quad.x8_ROT) { - w.writeBytes((first ? "1ROT" : "2ROT"), 4); - quad.x8_ROT.write(w); - } - if (quad.xc_OFF) { - w.writeBytes((first ? "1OFF" : "2OFF"), 4); - quad.xc_OFF.write(w); - } - if (quad.x10_CLR) { - w.writeBytes((first ? "1CLR" : "2CLR"), 4); - quad.x10_CLR.write(w); - } - if (quad.x14_TEX) { - w.writeBytes((first ? "1TEX" : "2TEX"), 4); - quad.x14_TEX.write(w); - } - if (quad.x18_ADD) { - w.writeBytes((first ? "1ADD" : "2ADD"), 4); - quad.x18_ADD.write(w); - } -} - -template -void DPSM::gatherDependencies(std::vector& pathsOut) const { - if (x0_quad.x14_TEX.m_elem) - x0_quad.x14_TEX.m_elem->gatherDependencies(pathsOut); - if (x1c_quad.x14_TEX.m_elem) - x1c_quad.x14_TEX.m_elem->gatherDependencies(pathsOut); - g_curSpec->flattenDependencies(x38_DMDL.id, pathsOut); -} - -AT_SUBSPECIALIZE_DNA_YAML(DPSM) -AT_SUBSPECIALIZE_DNA_YAML(DPSM) -template struct DPSM; -template struct DPSM; - template bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { athena::io::FileWriter writer(outPath.getAbsolutePath()); diff --git a/DataSpec/DNACommon/DPSC.def b/DataSpec/DNACommon/DPSC.def new file mode 100644 index 000000000..ac61eb49f --- /dev/null +++ b/DataSpec/DNACommon/DPSC.def @@ -0,0 +1,28 @@ +#ifndef ENTRY +#define ENTRY(name, identifier) +#endif + +ENTRY('1LFT', x0_quad.x0_LFT) +ENTRY('1SZE', x0_quad.x4_SZE) +ENTRY('1ROT', x0_quad.x8_ROT) +ENTRY('1OFF', x0_quad.xc_OFF) +ENTRY('1CLR', x0_quad.x10_CLR) +ENTRY('1TEX', x0_quad.x14_TEX) +ENTRY('1ADD', x0_quad.x18_ADD) +ENTRY('2LFT', x1c_quad.x0_LFT) +ENTRY('2SZE', x1c_quad.x4_SZE) +ENTRY('2ROT', x1c_quad.x8_ROT) +ENTRY('2OFF', x1c_quad.xc_OFF) +ENTRY('2CLR', x1c_quad.x10_CLR) +ENTRY('2TEX', x1c_quad.x14_TEX) +ENTRY('2ADD', x1c_quad.x18_ADD) +ENTRY('DMDL', x38_DMDL) +ENTRY('DLFT', x48_DLFT) +ENTRY('DMOP', x4c_DMOP) +ENTRY('DMRT', x50_DMRT) +ENTRY('DMSC', x54_DMSC) +ENTRY('DMCL', x58_DMCL) +ENTRY('DMAB', x5c_24_DMAB) +ENTRY('DMOO', x5c_25_DMOO) + +#undef ENTRY diff --git a/DataSpec/DNACommon/DPSC.hpp b/DataSpec/DNACommon/DPSC.hpp index f8feab5eb..2ef2c547c 100644 --- a/DataSpec/DNACommon/DPSC.hpp +++ b/DataSpec/DNACommon/DPSC.hpp @@ -20,9 +20,8 @@ class ProjectPath; namespace DataSpec::DNAParticle { template -struct DPSM : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA +struct _DPSM { + static constexpr ParticleType Type = ParticleType::DPSM; struct SQuadDescr { IntElementFactory x0_LFT; @@ -31,7 +30,7 @@ struct DPSM : BigDNA { VectorElementFactory xc_OFF; ColorElementFactory x10_CLR; UVElementFactory x14_TEX; - BoolHelper x18_ADD; + bool x18_ADD = false; }; SQuadDescr x0_quad; @@ -42,21 +41,27 @@ struct DPSM : BigDNA { VectorElementFactory x50_DMRT; VectorElementFactory x54_DMSC; ColorElementFactory x58_DMCL; - union { - struct { - bool x5c_24_DMAB : 1; - bool x5c_25_DMOO : 1; - }; - uint8_t dummy; - }; - template - void readQuadDecalInfo(Reader& r, FourCC clsId, SQuadDescr& quad); - void writeQuadDecalInfo(athena::io::YAMLDocWriter& w, const SQuadDescr& quad, bool first) const; - void getQuadDecalBinarySize(size_t& s, const SQuadDescr& desc) const; - void writeQuadDecalInfo(athena::io::IStreamWriter& w, const SQuadDescr& quad, bool first) const; - void gatherDependencies(std::vector&) const; + bool x5c_24_DMAB = false; + bool x5c_25_DMOO = false; + + template + void constexpr Enumerate(_Func f) { +#define ENTRY(name, identifier) f(FOURCC(name), identifier); +#include "DPSC.def" + } + + template + bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { +#define ENTRY(name, identifier) case SBIG(name): f(identifier); return true; +#include "DPSC.def" + default: return false; + } + } }; +template +using DPSM = PPImpl<_DPSM>; template bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); diff --git a/DataSpec/DNACommon/ELSC.cpp b/DataSpec/DNACommon/ELSC.cpp index b0e4703c7..7ea266f71 100644 --- a/DataSpec/DNACommon/ELSC.cpp +++ b/DataSpec/DNACommon/ELSC.cpp @@ -1,403 +1,13 @@ #include "DataSpec/DNACommon/ELSC.hpp" - -#include +#include "DataSpec/DNACommon/PAK.hpp" namespace DataSpec::DNAParticle { -template -void ELSM::_read(athena::io::IStreamReader& r) { - DNAFourCC clsId; - clsId.read(r); - if (clsId != SBIG('ELSM')) { - LogModule.report(logvisor::Warning, fmt("non ELSM provided to ELSM parser")); - return; - } +template struct PPImpl<_ELSM>; +template struct PPImpl<_ELSM>; - clsId.read(r); - while (clsId != SBIG('_END')) { - switch (clsId.toUint32()) { - case SBIG('LIFE'): - x0_LIFE.read(r); - break; - case SBIG('SLIF'): - x4_SLIF.read(r); - break; - case SBIG('GRAT'): - x8_GRAT.read(r); - break; - case SBIG('SCNT'): - xc_SCNT.read(r); - break; - case SBIG('SSEG'): - x10_SSEG.read(r); - break; - case SBIG('COLR'): - x14_COLR.read(r); - break; - case SBIG('IEMT'): - x18_IEMT.read(r); - break; - case SBIG('FEMT'): - x1c_FEMT.read(r); - break; - case SBIG('AMPL'): - x20_AMPL.read(r); - break; - case SBIG('AMPD'): - x24_AMPD.read(r); - break; - case SBIG('LWD1'): - x28_LWD1.read(r); - break; - case SBIG('LWD2'): - x2c_LWD2.read(r); - break; - case SBIG('LWD3'): - x30_LWD3.read(r); - break; - case SBIG('LCL1'): - x34_LCL1.read(r); - break; - case SBIG('LCL2'): - x38_LCL2.read(r); - break; - case SBIG('LCL3'): - x3c_LCL3.read(r); - break; - case SBIG('SSWH'): - x40_SSWH.read(r); - break; - case SBIG('GPSM'): - x50_GPSM.read(r); - break; - case SBIG('EPSM'): - x60_EPSM.read(r); - break; - case SBIG('ZERY'): - x70_ZERY.read(r); - break; - default: - LogModule.report(logvisor::Fatal, fmt("Unknown ELSM class {} @{}"), clsId, r.position()); - break; - } - clsId.read(r); - } -} - -template -void ELSM::_write(athena::io::IStreamWriter& w) const { - w.writeBytes((atInt8*)"ELSM", 4); - if (x0_LIFE) { - w.writeBytes((atInt8*)"LIFE", 4); - x0_LIFE.write(w); - } - if (x4_SLIF) { - w.writeBytes((atInt8*)"SLIF", 4); - x4_SLIF.write(w); - } - if (x8_GRAT) { - w.writeBytes((atInt8*)"GRAT", 4); - x8_GRAT.write(w); - } - if (xc_SCNT) { - w.writeBytes((atInt8*)"SCNT", 4); - xc_SCNT.write(w); - } - if (x10_SSEG) { - w.writeBytes((atInt8*)"SSEG", 4); - x10_SSEG.write(w); - } - if (x14_COLR) { - w.writeBytes((atInt8*)"COLR", 4); - x14_COLR.write(w); - } - if (x18_IEMT) { - w.writeBytes((atInt8*)"IEMT", 4); - x18_IEMT.write(w); - } - if (x1c_FEMT) { - w.writeBytes((atInt8*)"FEMT", 4); - x1c_FEMT.write(w); - } - if (x20_AMPL) { - w.writeBytes((atInt8*)"AMPL", 4); - x20_AMPL.write(w); - } - if (x24_AMPD) { - w.writeBytes((atInt8*)"AMPD", 4); - x24_AMPD.write(w); - } - if (x28_LWD1) { - w.writeBytes((atInt8*)"LWD1", 4); - x28_LWD1.write(w); - } - if (x2c_LWD2) { - w.writeBytes((atInt8*)"LWD2", 4); - x2c_LWD2.write(w); - } - if (x30_LWD3) { - w.writeBytes((atInt8*)"LWD3", 4); - x30_LWD3.write(w); - } - if (x34_LCL1) { - w.writeBytes((atInt8*)"LCL1", 4); - x34_LCL1.write(w); - } - if (x38_LCL2) { - w.writeBytes((atInt8*)"LCL2", 4); - x38_LCL2.write(w); - } - if (x3c_LCL3) { - w.writeBytes((atInt8*)"LCL3", 4); - x3c_LCL3.write(w); - } - if (x40_SSWH) { - w.writeBytes((atInt8*)"SSWH", 4); - x40_SSWH.write(w); - } - if (x50_GPSM) { - w.writeBytes((atInt8*)"GPSM", 4); - x50_GPSM.write(w); - } - if (x60_EPSM) { - w.writeBytes((atInt8*)"EPSM", 4); - x60_EPSM.write(w); - } - if (x70_ZERY) { - w.writeBytes((atInt8*)"ZERY", 4); - x70_ZERY.write(w); - } - w.writeBytes("_END", 4); -} - -template -void ELSM::_binarySize(size_t& s) const { - s += 4; - if (x0_LIFE) { - s += 4; - x0_LIFE.binarySize(s); - } - if (x4_SLIF) { - s += 4; - x4_SLIF.binarySize(s); - } - if (x8_GRAT) { - s += 4; - x8_GRAT.binarySize(s); - } - if (xc_SCNT) { - s += 4; - xc_SCNT.binarySize(s); - } - if (x10_SSEG) { - s += 4; - x10_SSEG.binarySize(s); - } - if (x14_COLR) { - s += 4; - x14_COLR.binarySize(s); - } - if (x18_IEMT) { - s += 4; - x18_IEMT.binarySize(s); - } - if (x1c_FEMT) { - s += 4; - x1c_FEMT.binarySize(s); - } - if (x20_AMPL) { - s += 4; - x20_AMPL.binarySize(s); - } - if (x24_AMPD) { - s += 4; - x24_AMPD.binarySize(s); - } - if (x28_LWD1) { - s += 4; - x28_LWD1.binarySize(s); - } - if (x2c_LWD2) { - s += 4; - x2c_LWD2.binarySize(s); - } - if (x30_LWD3) { - s += 4; - x30_LWD3.binarySize(s); - } - if (x34_LCL1) { - s += 4; - x34_LCL1.binarySize(s); - } - if (x38_LCL2) { - s += 4; - x38_LCL2.binarySize(s); - } - if (x3c_LCL3) { - s += 4; - x3c_LCL3.binarySize(s); - } - if (x40_SSWH) { - s += 4; - x40_SSWH.binarySize(s); - } - if (x50_GPSM) { - s += 4; - x50_GPSM.binarySize(s); - } - if (x60_EPSM) { - s += 4; - x60_EPSM.binarySize(s); - } - if (x70_ZERY) { - s += 4; - x70_ZERY.binarySize(s); - } -} - -template -void ELSM::_read(athena::io::YAMLDocReader& r) { - for (const auto& elem : r.getCurNode()->m_mapChildren) { - if (elem.first.size() < 4) { - LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), elem.first); - continue; - } - - if (auto rec = r.enterSubRecord(elem.first.c_str())) { - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('LIFE'): - x0_LIFE.read(r); - break; - case SBIG('SLIF'): - x4_SLIF.read(r); - break; - case SBIG('GRAT'): - x8_GRAT.read(r); - break; - case SBIG('SCNT'): - xc_SCNT.read(r); - break; - case SBIG('SSEG'): - x10_SSEG.read(r); - break; - case SBIG('COLR'): - x14_COLR.read(r); - break; - case SBIG('IEMT'): - x18_IEMT.read(r); - break; - case SBIG('FEMT'): - x1c_FEMT.read(r); - break; - case SBIG('AMPL'): - x20_AMPL.read(r); - break; - case SBIG('AMPD'): - x24_AMPD.read(r); - break; - case SBIG('LWD1'): - x28_LWD1.read(r); - break; - case SBIG('LWD2'): - x2c_LWD2.read(r); - break; - case SBIG('LWD3'): - x30_LWD3.read(r); - break; - case SBIG('LCL1'): - x34_LCL1.read(r); - break; - case SBIG('LCL2'): - x38_LCL2.read(r); - break; - case SBIG('LCL3'): - x3c_LCL3.read(r); - break; - case SBIG('SSWH'): - x40_SSWH.read(r); - break; - case SBIG('GPSM'): - x50_GPSM.read(r); - break; - case SBIG('EPSM'): - x60_EPSM.read(r); - break; - case SBIG('ZERY'): - x70_ZERY.read(r); - break; - default: - break; - } - } - } -} - -template -void ELSM::_write(athena::io::YAMLDocWriter& w) const { - if (x0_LIFE) - if (auto rec = w.enterSubRecord("LIFE")) - x0_LIFE.write(w); - if (x4_SLIF) - if (auto rec = w.enterSubRecord("SLIF")) - x4_SLIF.write(w); - if (x8_GRAT) - if (auto rec = w.enterSubRecord("GRAT")) - x8_GRAT.write(w); - if (xc_SCNT) - if (auto rec = w.enterSubRecord("SCNT")) - xc_SCNT.write(w); - if (x10_SSEG) - if (auto rec = w.enterSubRecord("SSEG")) - x10_SSEG.write(w); - if (x14_COLR) - if (auto rec = w.enterSubRecord("COLR")) - x14_COLR.write(w); - if (x18_IEMT) - if (auto rec = w.enterSubRecord("IEMT")) - x18_IEMT.write(w); - if (x1c_FEMT) - if (auto rec = w.enterSubRecord("FEMT")) - x1c_FEMT.write(w); - if (x20_AMPL) - if (auto rec = w.enterSubRecord("AMPL")) - x20_AMPL.write(w); - if (x24_AMPD) - if (auto rec = w.enterSubRecord("AMPD")) - x24_AMPD.write(w); - if (x28_LWD1) - if (auto rec = w.enterSubRecord("LWD1")) - x28_LWD1.write(w); - if (x2c_LWD2) - if (auto rec = w.enterSubRecord("LWD2")) - x2c_LWD2.write(w); - if (x30_LWD3) - if (auto rec = w.enterSubRecord("LWD3")) - x30_LWD3.write(w); - if (x34_LCL1) - if (auto rec = w.enterSubRecord("LCL1")) - x34_LCL1.write(w); - if (x38_LCL2) - if (auto rec = w.enterSubRecord("LCL2")) - x38_LCL2.write(w); - if (x3c_LCL3) - if (auto rec = w.enterSubRecord("LCL3")) - x3c_LCL3.write(w); - if (x40_SSWH) - if (auto rec = w.enterSubRecord("SSWH")) - x40_SSWH.write(w); - if (x50_GPSM) - if (auto rec = w.enterSubRecord("GPSM")) - x50_GPSM.write(w); - if (x60_EPSM) - if (auto rec = w.enterSubRecord("EPSM")) - x60_EPSM.write(w); - if (x70_ZERY) - if (auto rec = w.enterSubRecord("ZERY")) - x70_ZERY.write(w); -} - -AT_SUBSPECIALIZE_DNA_YAML(ELSM) -AT_SUBSPECIALIZE_DNA_YAML(ELSM) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_ELSM>) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_ELSM>) template <> std::string_view ELSM::DNAType() { @@ -409,16 +19,6 @@ std::string_view ELSM::DNAType() { return "urde::ELSM"sv; } -template -void ELSM::gatherDependencies(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(x40_SSWH.id, pathsOut); - g_curSpec->flattenDependencies(x50_GPSM.id, pathsOut); - g_curSpec->flattenDependencies(x60_EPSM.id, pathsOut); -} - -template struct ELSM; -template struct ELSM; - template bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { athena::io::FileWriter writer(outPath.getAbsolutePath()); diff --git a/DataSpec/DNACommon/ELSC.def b/DataSpec/DNACommon/ELSC.def new file mode 100644 index 000000000..b8498ab1a --- /dev/null +++ b/DataSpec/DNACommon/ELSC.def @@ -0,0 +1,56 @@ +#ifndef ENTRY +#define ENTRY(name, identifier) +#endif + +#ifndef INT_ENTRY +#define INT_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef REAL_ENTRY +#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef COLOR_ENTRY +#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef EMITTER_ENTRY +#define EMITTER_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef RES_ENTRY +#define RES_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef BOOL_ENTRY +#define BOOL_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +INT_ENTRY('LIFE', x0_LIFE) +INT_ENTRY('SLIF', x4_SLIF) +REAL_ENTRY('GRAT', x8_GRAT) +INT_ENTRY('SCNT', xc_SCNT) +INT_ENTRY('SSEG', x10_SSEG) +COLOR_ENTRY('COLR', x14_COLR) +EMITTER_ENTRY('IEMT', x18_IEMT) +EMITTER_ENTRY('FEMT', x1c_FEMT) +REAL_ENTRY('AMPL', x20_AMPL) +REAL_ENTRY('AMPD', x24_AMPD) +REAL_ENTRY('LWD1', x28_LWD1) +REAL_ENTRY('LWD2', x2c_LWD2) +REAL_ENTRY('LWD3', x30_LWD3) +COLOR_ENTRY('LCL1', x34_LCL1) +COLOR_ENTRY('LCL2', x38_LCL2) +COLOR_ENTRY('LCL3', x3c_LCL3) +RES_ENTRY('SSWH', x40_SSWH) +RES_ENTRY('GPSM', x50_GPSM) +RES_ENTRY('EPSM', x60_EPSM) +BOOL_ENTRY('ZERY', x70_ZERY) + +#undef ENTRY +#undef INT_ENTRY +#undef REAL_ENTRY +#undef COLOR_ENTRY +#undef EMITTER_ENTRY +#undef RES_ENTRY +#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/ELSC.hpp b/DataSpec/DNACommon/ELSC.hpp index 52ff09e35..a6eaaf41d 100644 --- a/DataSpec/DNACommon/ELSC.hpp +++ b/DataSpec/DNACommon/ELSC.hpp @@ -12,33 +12,36 @@ class ProjectPath; } namespace DataSpec::DNAParticle { -template -struct ELSM : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - IntElementFactory x0_LIFE; - IntElementFactory x4_SLIF; - RealElementFactory x8_GRAT; - IntElementFactory xc_SCNT; - IntElementFactory x10_SSEG; - ColorElementFactory x14_COLR; - EmitterElementFactory x18_IEMT; - EmitterElementFactory x1c_FEMT; - RealElementFactory x20_AMPL; - RealElementFactory x24_AMPD; - RealElementFactory x28_LWD1; - RealElementFactory x2c_LWD2; - RealElementFactory x30_LWD3; - ColorElementFactory x34_LCL1; - ColorElementFactory x38_LCL2; - ColorElementFactory x3c_LCL3; - ChildResourceFactory x40_SSWH; - ChildResourceFactory x50_GPSM; - ChildResourceFactory x60_EPSM; - BoolHelper x70_ZERY; - void gatherDependencies(std::vector&) const; +template +struct _ELSM { + static constexpr ParticleType Type = ParticleType::ELSM; + +#define INT_ENTRY(name, identifier) IntElementFactory identifier; +#define REAL_ENTRY(name, identifier) RealElementFactory identifier; +#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; +#define EMITTER_ENTRY(name, identifier) EmitterElementFactory identifier; +#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; +#define BOOL_ENTRY(name, identifier) bool identifier = false; +#include "ELSC.def" + + template + void constexpr Enumerate(_Func f) { +#define ENTRY(name, identifier) f(FOURCC(name), identifier); +#include "ELSC.def" + } + + template + bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { +#define ENTRY(name, identifier) case SBIG(name): f(identifier); return true; +#include "ELSC.def" + default: return false; + } + } }; +template +using ELSM = PPImpl<_ELSM>; template bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); diff --git a/DataSpec/DNACommon/MAPA.cpp b/DataSpec/DNACommon/MAPA.cpp index 46a58a3ef..3e8a868f5 100644 --- a/DataSpec/DNACommon/MAPA.cpp +++ b/DataSpec/DNACommon/MAPA.cpp @@ -27,11 +27,11 @@ void MAPA::Enumerate(typename Read::StreamT& __dna_reader) { /* version */ version = __dna_reader.readUint32Big(); if (version == 2) - header.reset(new HeaderMP1); + header = std::make_unique(); else if (version == 3) - header.reset(new HeaderMP2); + header = std::make_unique(); else if (version == 5) - header.reset(new HeaderMP3); + header = std::make_unique(); else { LogDNACommon.report(logvisor::Error, fmt("invalid MAPA version")); return; @@ -41,10 +41,11 @@ void MAPA::Enumerate(typename Read::StreamT& __dna_reader) { for (atUint32 i = 0; i < header->mappableObjectCount(); i++) { std::unique_ptr mo = nullptr; - if (version != 5) - mo.reset(new MappableObjectMP1_2); - else - mo.reset(new MappableObjectMP3); + if (version != 5) { + mo = std::make_unique(); + } else { + mo = std::make_unique(); + } mo->read(__dna_reader); mappableObjects.push_back(std::move(mo)); } diff --git a/DataSpec/DNACommon/PART.cpp b/DataSpec/DNACommon/PART.cpp index abdeea0d2..23176e42a 100644 --- a/DataSpec/DNACommon/PART.cpp +++ b/DataSpec/DNACommon/PART.cpp @@ -1,9 +1,14 @@ #include "DataSpec/DNACommon/PART.hpp" - #include "DataSpec/DNACommon/PAK.hpp" namespace DataSpec::DNAParticle { +template struct PPImpl<_GPSM>; +template struct PPImpl<_GPSM>; + +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_GPSM>) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_GPSM>) + template <> std::string_view GPSM::DNAType() { return "GPSM"sv; @@ -14,1399 +19,6 @@ std::string_view GPSM::DNAType() { return "GPSM"sv; } -template -void GPSM::_read(typename ReadYaml::StreamT& r) { - for (const auto& elem : r.getCurNode()->m_mapChildren) { - if (elem.first.size() < 4) { - LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), elem.first); - continue; - } - - if (auto rec = r.enterSubRecord(elem.first.c_str())) { - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('PMCL'): - x78_PMCL.read(r); - break; - case SBIG('LFOR'): - x118_LFOR.read(r); - break; - case SBIG('IDTS'): - xa4_IDTS.read(r); - break; - case SBIG('EMTR'): - x40_EMTR.read(r); - break; - case SBIG('COLR'): - x30_COLR.read(r); - break; - case SBIG('CIND'): - x45_30_CIND = r.readBool(); - break; - case SBIG('AAPH'): - x44_26_AAPH = r.readBool(); - break; - case SBIG('CSSD'): - xa0_CSSD.read(r); - break; - case SBIG('GRTE'): - x2c_GRTE.read(r); - break; - case SBIG('FXLL'): - x44_25_FXLL = r.readBool(); - break; - case SBIG('ICTS'): - x8c_ICTS.read(r); - break; - case SBIG('KSSM'): - xd0_KSSM.read(r); - break; - case SBIG('ILOC'): - x38_ILOC.read(r); - break; - case SBIG('IITS'): - xb8_IITS.read(r); - break; - case SBIG('IVEC'): - x3c_IVEC.read(r); - break; - case SBIG('LDIR'): - x110_LDIR.read(r); - break; - case SBIG('LCLR'): - x104_LCLR.read(r); - break; - case SBIG('LENG'): - x20_LENG.read(r); - break; - case SBIG('MAXP'): - x28_MAXP.read(r); - break; - case SBIG('LOFF'): - x10c_LOFF.read(r); - break; - case SBIG('LINT'): - x108_LINT.read(r); - break; - case SBIG('LINE'): - x44_24_LINE = r.readBool(); - break; - case SBIG('LFOT'): - x114_LFOT.read(r); - break; - case SBIG('LIT_'): - x44_29_LIT_ = r.readBool(); - break; - case SBIG('LTME'): - x34_LTME.read(r); - break; - case SBIG('LSLA'): - x11c_LSLA.read(r); - break; - case SBIG('LTYP'): - x100_LTYP.read(r); - break; - case SBIG('NDSY'): - xb4_NDSY.read(r); - break; - case SBIG('MBSP'): - x48_MBSP.read(r); - break; - case SBIG('MBLR'): - x44_30_MBLR = r.readBool(); - break; - case SBIG('NCSY'): - x9c_NCSY.read(r); - break; - case SBIG('PISY'): - xc8_PISY.read(r); - break; - case SBIG('OPTS'): - x45_31_OPTS = r.readBool(); - break; - case SBIG('PMAB'): - x44_31_PMAB = r.readBool(); - break; - case SBIG('SESD'): - xf8_SESD.read(r); - break; - case SBIG('SEPO'): - xfc_SEPO.read(r); - break; - case SBIG('PSLT'): - xc_PSLT.read(r); - break; - case SBIG('PMSC'): - x74_PMSC.read(r); - break; - case SBIG('PMOP'): - x6c_PMOP.read(r); - break; - case SBIG('PMDL'): - x5c_PMDL.read(r); - break; - case SBIG('PMRT'): - x70_PMRT.read(r); - break; - case SBIG('POFS'): - x18_POFS.read(r); - break; - case SBIG('PMUS'): - x45_24_PMUS = r.readBool(); - break; - case SBIG('PSIV'): - x0_PSIV.read(r); - break; - case SBIG('ROTA'): - x50_ROTA.read(r); - break; - case SBIG('PSVM'): - x4_PSVM.read(r); - break; - case SBIG('PSTS'): - x14_PSTS.read(r); - break; - case SBIG('PSOV'): - x8_PSOV.read(r); - break; - case SBIG('PSWT'): - x10_PSWT.read(r); - break; - case SBIG('PMLC'): - xec_PMLC.read(r); - break; - case SBIG('SEED'): - x1c_SEED.read(r); - break; - case SBIG('PMOO'): - x45_25_PMOO = r.readBool(); - break; - case SBIG('SSSD'): - xe4_SSSD.read(r); - break; - case SBIG('SORT'): - x44_28_SORT = r.readBool(); - break; - case SBIG('SIZE'): - x4c_SIZE.read(r); - break; - case SBIG('SISY'): - xcc_SISY.read(r); - break; - case SBIG('SSPO'): - xe8_SSPO.read(r); - break; - case SBIG('TEXR'): - x54_TEXR.read(r); - break; - case SBIG('SSWH'): - xd4_SSWH.read(r); - break; - case SBIG('TIND'): - x58_TIND.read(r); - break; - case SBIG('VMD4'): - x45_29_VMD4 = r.readBool(); - break; - case SBIG('VMD3'): - x45_28_VMD3 = r.readBool(); - break; - case SBIG('VMD2'): - x45_27_VMD2 = r.readBool(); - break; - case SBIG('VMD1'): - x45_26_VMD1 = r.readBool(); - break; - case SBIG('VEL4'): - x88_VEL4.read(r); - break; - case SBIG('VEL3'): - x84_VEL3.read(r); - break; - case SBIG('VEL2'): - x80_VEL2.read(r); - break; - case SBIG('VEL1'): - x7c_VEL1.read(r); - break; - case SBIG('ZBUF'): - x44_27_ZBUF = r.readBool(); - break; - case SBIG('WIDT'): - x24_WIDT.read(r); - break; - case SBIG('ORNT'): - x30_30_ORNT = r.readBool(); - break; - case SBIG('RSOP'): - x30_31_RSOP = r.readBool(); - break; - case SBIG('ADV1'): - x10c_ADV1.read(r); - break; - case SBIG('ADV2'): - x110_ADV2.read(r); - break; - case SBIG('ADV3'): - x114_ADV3.read(r); - break; - case SBIG('ADV4'): - x118_ADV4.read(r); - break; - case SBIG('ADV5'): - x11c_ADV5.read(r); - break; - case SBIG('ADV6'): - x120_ADV6.read(r); - break; - case SBIG('ADV7'): - x124_ADV7.read(r); - break; - case SBIG('SELC'): - xd8_SELC.read(r); - break; - default: - break; - } - } - } -} - -template -void GPSM::_write(typename WriteYaml::StreamT& w) const { - if (x0_PSIV) - if (auto rec = w.enterSubRecord("PSIV")) - x0_PSIV.write(w); - if (x4_PSVM) - if (auto rec = w.enterSubRecord("PSVM")) - x4_PSVM.write(w); - if (x8_PSOV) - if (auto rec = w.enterSubRecord("PSOV")) - x8_PSOV.write(w); - if (xc_PSLT) - if (auto rec = w.enterSubRecord("PSLT")) - xc_PSLT.write(w); - if (x10_PSWT) - if (auto rec = w.enterSubRecord("PSWT")) - x10_PSWT.write(w); - if (x14_PSTS) - if (auto rec = w.enterSubRecord("PSTS")) - x14_PSTS.write(w); - if (x18_POFS) - if (auto rec = w.enterSubRecord("POFS")) - x18_POFS.write(w); - if (x1c_SEED) - if (auto rec = w.enterSubRecord("SEED")) - x1c_SEED.write(w); - if (x20_LENG) - if (auto rec = w.enterSubRecord("LENG")) - x20_LENG.write(w); - if (x24_WIDT) - if (auto rec = w.enterSubRecord("WIDT")) - x24_WIDT.write(w); - if (x28_MAXP) - if (auto rec = w.enterSubRecord("MAXP")) - x28_MAXP.write(w); - if (x2c_GRTE) - if (auto rec = w.enterSubRecord("GRTE")) - x2c_GRTE.write(w); - if (x30_COLR) - if (auto rec = w.enterSubRecord("COLR")) - x30_COLR.write(w); - if (x34_LTME) - if (auto rec = w.enterSubRecord("LTME")) - x34_LTME.write(w); - if (x38_ILOC) - if (auto rec = w.enterSubRecord("ILOC")) - x38_ILOC.write(w); - if (x3c_IVEC) - if (auto rec = w.enterSubRecord("IVEC")) - x3c_IVEC.write(w); - if (x40_EMTR) - if (auto rec = w.enterSubRecord("EMTR")) - x40_EMTR.write(w); - if (x44_24_LINE) - w.writeBool("LINE", true); - if (x44_25_FXLL) - w.writeBool("FXLL", true); - if (x44_26_AAPH) - w.writeBool("AAPH", true); - if (x44_27_ZBUF) - w.writeBool("ZBUF", true); - if (x44_28_SORT) - w.writeBool("SORT", true); - if (x44_29_LIT_) - w.writeBool("LIT_", true); - if (x44_30_MBLR) - w.writeBool("MBLR", true); - if (x44_31_PMAB) - w.writeBool("PMAB", true); - if (x45_24_PMUS) - w.writeBool("PMUS", true); - if (!x45_25_PMOO) - w.writeBool("PMOO", false); - if (x45_26_VMD1) - w.writeBool("VMD1", true); - if (x45_27_VMD2) - w.writeBool("VMD2", true); - if (x45_28_VMD3) - w.writeBool("VMD3", true); - if (x45_29_VMD4) - w.writeBool("VMD4", true); - if (x45_30_CIND) - w.writeBool("CIND", true); - if (x45_31_OPTS) - w.writeBool("OPTS", true); - if (x30_30_ORNT) - w.writeBool("ORNT", true); - if (x30_31_RSOP) - w.writeBool("RSOP", true); - if (x48_MBSP) - if (auto rec = w.enterSubRecord("MBSP")) - x48_MBSP.write(w); - if (x4c_SIZE) - if (auto rec = w.enterSubRecord("SIZE")) - x4c_SIZE.write(w); - if (x50_ROTA) - if (auto rec = w.enterSubRecord("ROTA")) - x50_ROTA.write(w); - if (x54_TEXR) - if (auto rec = w.enterSubRecord("TEXR")) - x54_TEXR.write(w); - if (x58_TIND) - if (auto rec = w.enterSubRecord("TIND")) - x58_TIND.write(w); - if (x5c_PMDL) - if (auto rec = w.enterSubRecord("PMDL")) - x5c_PMDL.write(w); - if (x6c_PMOP) - if (auto rec = w.enterSubRecord("PMOP")) - x6c_PMOP.write(w); - if (x70_PMRT) - if (auto rec = w.enterSubRecord("PMRT")) - x70_PMRT.write(w); - if (x74_PMSC) - if (auto rec = w.enterSubRecord("PMSC")) - x74_PMSC.write(w); - if (x78_PMCL) - if (auto rec = w.enterSubRecord("PMCL")) - x78_PMCL.write(w); - if (x7c_VEL1) - if (auto rec = w.enterSubRecord("VEL1")) - x7c_VEL1.write(w); - if (x80_VEL2) - if (auto rec = w.enterSubRecord("VEL2")) - x80_VEL2.write(w); - if (x84_VEL3) - if (auto rec = w.enterSubRecord("VEL3")) - x84_VEL3.write(w); - if (x88_VEL4) - if (auto rec = w.enterSubRecord("VEL4")) - x88_VEL4.write(w); - if (x8c_ICTS) - if (auto rec = w.enterSubRecord("ICTS")) - x8c_ICTS.write(w); - if (x9c_NCSY) - if (auto rec = w.enterSubRecord("NCSY")) - x9c_NCSY.write(w); - if (xa0_CSSD) - if (auto rec = w.enterSubRecord("CSSD")) - xa0_CSSD.write(w); - if (xa4_IDTS) - if (auto rec = w.enterSubRecord("IDTS")) - xa4_IDTS.write(w); - if (xb4_NDSY) - if (auto rec = w.enterSubRecord("NDSY")) - xb4_NDSY.write(w); - if (xb8_IITS) - if (auto rec = w.enterSubRecord("IITS")) - xb8_IITS.write(w); - if (xc8_PISY) - if (auto rec = w.enterSubRecord("PISY")) - xc8_PISY.write(w); - if (xcc_SISY) - if (auto rec = w.enterSubRecord("SISY")) - xcc_SISY.write(w); - if (xd0_KSSM) - if (auto rec = w.enterSubRecord("KSSM")) - xd0_KSSM.write(w); - if (xd4_SSWH) - if (auto rec = w.enterSubRecord("SSWH")) - xd4_SSWH.write(w); - if (xd8_SELC) - if (auto rec = w.enterSubRecord("SELC")) - xd8_SELC.write(w); - if (xe4_SSSD) - if (auto rec = w.enterSubRecord("SSSD")) - xe4_SSSD.write(w); - if (xe8_SSPO) - if (auto rec = w.enterSubRecord("SSPO")) - xe8_SSPO.write(w); - if (xf8_SESD) - if (auto rec = w.enterSubRecord("SESD")) - xf8_SESD.write(w); - if (xfc_SEPO) - if (auto rec = w.enterSubRecord("SEPO")) - xfc_SEPO.write(w); - if (xec_PMLC) - if (auto rec = w.enterSubRecord("PMLC")) - xec_PMLC.write(w); - if (x100_LTYP) - if (auto rec = w.enterSubRecord("LTYP")) - x100_LTYP.write(w); - if (x104_LCLR) - if (auto rec = w.enterSubRecord("LCLR")) - x104_LCLR.write(w); - if (x108_LINT) - if (auto rec = w.enterSubRecord("LINT")) - x108_LINT.write(w); - if (x10c_LOFF) - if (auto rec = w.enterSubRecord("LOFF")) - x10c_LOFF.write(w); - if (x110_LDIR) - if (auto rec = w.enterSubRecord("LDIR")) - x110_LDIR.write(w); - if (x114_LFOT) - if (auto rec = w.enterSubRecord("LFOT")) - x114_LFOT.write(w); - if (x118_LFOR) - if (auto rec = w.enterSubRecord("LFOR")) - x118_LFOR.write(w); - if (x11c_LSLA) - if (auto rec = w.enterSubRecord("LSLA")) - x11c_LSLA.write(w); - if (x10c_ADV1) - if (auto rec = w.enterSubRecord("ADV1")) - x10c_ADV1.write(w); - if (x110_ADV2) - if (auto rec = w.enterSubRecord("ADV2")) - x110_ADV2.write(w); - if (x114_ADV3) - if (auto rec = w.enterSubRecord("ADV3")) - x114_ADV3.write(w); - if (x118_ADV4) - if (auto rec = w.enterSubRecord("ADV4")) - x118_ADV4.write(w); - if (x11c_ADV5) - if (auto rec = w.enterSubRecord("ADV5")) - x11c_ADV5.write(w); - if (x120_ADV6) - if (auto rec = w.enterSubRecord("ADV6")) - x120_ADV6.write(w); - if (x124_ADV7) - if (auto rec = w.enterSubRecord("ADV7")) - x124_ADV7.write(w); - if (x128_ADV8) - if (auto rec = w.enterSubRecord("ADV8")) - x128_ADV8.write(w); -} - -template -void GPSM::_binarySize(typename BinarySize::StreamT& s) const { - s += 4; - if (x0_PSIV) { - s += 4; - x0_PSIV.binarySize(s); - } - if (x4_PSVM) { - s += 4; - x4_PSVM.binarySize(s); - } - if (x8_PSOV) { - s += 4; - x8_PSOV.binarySize(s); - } - if (xc_PSLT) { - s += 4; - xc_PSLT.binarySize(s); - } - if (x10_PSWT) { - s += 4; - x10_PSWT.binarySize(s); - } - if (x14_PSTS) { - s += 4; - x14_PSTS.binarySize(s); - } - if (x18_POFS) { - s += 4; - x18_POFS.binarySize(s); - } - if (x1c_SEED) { - s += 4; - x1c_SEED.binarySize(s); - } - if (x20_LENG) { - s += 4; - x20_LENG.binarySize(s); - } - if (x24_WIDT) { - s += 4; - x24_WIDT.binarySize(s); - } - if (x28_MAXP) { - s += 4; - x28_MAXP.binarySize(s); - } - if (x2c_GRTE) { - s += 4; - x2c_GRTE.binarySize(s); - } - if (x30_COLR) { - s += 4; - x30_COLR.binarySize(s); - } - if (x34_LTME) { - s += 4; - x34_LTME.binarySize(s); - } - if (x38_ILOC) { - s += 4; - x38_ILOC.binarySize(s); - } - if (x3c_IVEC) { - s += 4; - x3c_IVEC.binarySize(s); - } - if (x40_EMTR) { - s += 4; - x40_EMTR.binarySize(s); - } - if (x44_24_LINE) - s += 9; - if (x44_25_FXLL) - s += 9; - if (x44_26_AAPH) - s += 9; - if (x44_27_ZBUF) - s += 9; - if (x44_28_SORT) - s += 9; - if (x44_29_LIT_) - s += 9; - if (x44_30_MBLR) - s += 9; - if (x44_31_PMAB) - s += 9; - if (x45_24_PMUS) - s += 9; - if (!x45_25_PMOO) - s += 9; - if (x45_26_VMD1) - s += 9; - if (x45_27_VMD2) - s += 9; - if (x45_28_VMD3) - s += 9; - if (x45_29_VMD4) - s += 9; - if (x45_30_CIND) - s += 9; - if (x45_31_OPTS) - s += 9; - if (x30_30_ORNT) - s += 9; - if (x30_31_RSOP) - s += 9; - if (x48_MBSP) { - s += 4; - x48_MBSP.binarySize(s); - } - if (x4c_SIZE) { - s += 4; - x4c_SIZE.binarySize(s); - } - if (x50_ROTA) { - s += 4; - x50_ROTA.binarySize(s); - } - if (x54_TEXR) { - s += 4; - x54_TEXR.binarySize(s); - } - if (x58_TIND) { - s += 4; - x58_TIND.binarySize(s); - } - if (x5c_PMDL) { - s += 4; - x5c_PMDL.binarySize(s); - } - if (x6c_PMOP) { - s += 4; - x6c_PMOP.binarySize(s); - } - if (x70_PMRT) { - s += 4; - x70_PMRT.binarySize(s); - } - if (x74_PMSC) { - s += 4; - x74_PMSC.binarySize(s); - } - if (x78_PMCL) { - s += 4; - x78_PMCL.binarySize(s); - } - if (x7c_VEL1) { - s += 4; - x7c_VEL1.binarySize(s); - } - if (x80_VEL2) { - s += 4; - x80_VEL2.binarySize(s); - } - if (x84_VEL3) { - s += 4; - x84_VEL3.binarySize(s); - } - if (x88_VEL4) { - s += 4; - x88_VEL4.binarySize(s); - } - if (x8c_ICTS) { - s += 4; - x8c_ICTS.binarySize(s); - } - if (x9c_NCSY) { - s += 4; - x9c_NCSY.binarySize(s); - } - if (xa0_CSSD) { - s += 4; - xa0_CSSD.binarySize(s); - } - if (xa4_IDTS) { - s += 4; - xa4_IDTS.binarySize(s); - } - if (xb4_NDSY) { - s += 4; - xb4_NDSY.binarySize(s); - } - if (xb8_IITS) { - s += 4; - xb8_IITS.binarySize(s); - } - if (xc8_PISY) { - s += 4; - xc8_PISY.binarySize(s); - } - if (xcc_SISY) { - s += 4; - xcc_SISY.binarySize(s); - } - if (xd0_KSSM) { - s += 4; - xd0_KSSM.binarySize(s); - } - if (xd4_SSWH) { - s += 4; - xd4_SSWH.binarySize(s); - } - if (xd8_SELC) { - s += 4; - xd8_SELC.binarySize(s); - } - if (xe4_SSSD) { - s += 4; - xe4_SSSD.binarySize(s); - } - if (xe8_SSPO) { - s += 4; - xe8_SSPO.binarySize(s); - } - if (xf8_SESD) { - s += 4; - xf8_SESD.binarySize(s); - } - if (xfc_SEPO) { - s += 4; - xfc_SEPO.binarySize(s); - } - if (xec_PMLC) { - s += 4; - xec_PMLC.binarySize(s); - } - if (x100_LTYP) { - s += 4; - x100_LTYP.binarySize(s); - } - if (x104_LCLR) { - s += 4; - x104_LCLR.binarySize(s); - } - if (x108_LINT) { - s += 4; - x108_LINT.binarySize(s); - } - if (x10c_LOFF) { - s += 4; - x10c_LOFF.binarySize(s); - } - if (x110_LDIR) { - s += 4; - x110_LDIR.binarySize(s); - } - if (x114_LFOT) { - s += 4; - x114_LFOT.binarySize(s); - } - if (x118_LFOR) { - s += 4; - x118_LFOR.binarySize(s); - } - if (x11c_LSLA) { - s += 4; - x11c_LSLA.binarySize(s); - } - if (x10c_ADV1) { - s += 4; - x10c_ADV1.binarySize(s); - } - if (x110_ADV2) { - s += 4; - x110_ADV2.binarySize(s); - } - if (x114_ADV3) { - s += 4; - x114_ADV3.binarySize(s); - } - if (x118_ADV4) { - s += 4; - x118_ADV4.binarySize(s); - } - if (x11c_ADV5) { - s += 4; - x11c_ADV5.binarySize(s); - } - if (x120_ADV6) { - s += 4; - x120_ADV6.binarySize(s); - } - if (x124_ADV7) { - s += 4; - x124_ADV7.binarySize(s); - } - if (x128_ADV8) { - s += 4; - x128_ADV8.binarySize(s); - } -} - -template -void GPSM::_read(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - if (clsId != SBIG('GPSM')) { - LogModule.report(logvisor::Warning, fmt("non GPSM provided to GPSM parser")); - return; - } - clsId.read(r); - while (clsId != SBIG('_END')) { - switch (clsId.toUint32()) { - case SBIG('PMCL'): - x78_PMCL.read(r); - break; - case SBIG('LFOR'): - x118_LFOR.read(r); - break; - case SBIG('IDTS'): - xa4_IDTS.read(r); - break; - case SBIG('EMTR'): - x40_EMTR.read(r); - break; - case SBIG('COLR'): - x30_COLR.read(r); - break; - case SBIG('CIND'): - r.readUint32Big(); - x45_30_CIND = r.readBool(); - break; - case SBIG('AAPH'): - r.readUint32Big(); - x44_26_AAPH = r.readBool(); - break; - case SBIG('CSSD'): - xa0_CSSD.read(r); - break; - case SBIG('GRTE'): - x2c_GRTE.read(r); - break; - case SBIG('FXLL'): - r.readUint32Big(); - x44_25_FXLL = r.readBool(); - break; - case SBIG('ICTS'): - x8c_ICTS.read(r); - break; - case SBIG('KSSM'): - xd0_KSSM.read(r); - break; - case SBIG('ILOC'): - x38_ILOC.read(r); - break; - case SBIG('IITS'): - xb8_IITS.read(r); - break; - case SBIG('IVEC'): - x3c_IVEC.read(r); - break; - case SBIG('LDIR'): - x110_LDIR.read(r); - break; - case SBIG('LCLR'): - x104_LCLR.read(r); - break; - case SBIG('LENG'): - x20_LENG.read(r); - break; - case SBIG('MAXP'): - x28_MAXP.read(r); - break; - case SBIG('LOFF'): - x10c_LOFF.read(r); - break; - case SBIG('LINT'): - x108_LINT.read(r); - break; - case SBIG('LINE'): - r.readUint32Big(); - x44_24_LINE = r.readBool(); - break; - case SBIG('LFOT'): - x114_LFOT.read(r); - break; - case SBIG('LIT_'): - r.readUint32Big(); - x44_29_LIT_ = r.readBool(); - break; - case SBIG('LTME'): - x34_LTME.read(r); - break; - case SBIG('LSLA'): - x11c_LSLA.read(r); - break; - case SBIG('LTYP'): - x100_LTYP.read(r); - break; - case SBIG('NDSY'): - xb4_NDSY.read(r); - break; - case SBIG('MBSP'): - x48_MBSP.read(r); - break; - case SBIG('MBLR'): - r.readUint32Big(); - x44_30_MBLR = r.readBool(); - break; - case SBIG('NCSY'): - x9c_NCSY.read(r); - break; - case SBIG('PISY'): - xc8_PISY.read(r); - break; - case SBIG('OPTS'): - r.readUint32Big(); - x45_31_OPTS = r.readBool(); - break; - case SBIG('PMAB'): - r.readUint32Big(); - x44_31_PMAB = r.readBool(); - break; - case SBIG('SESD'): - xf8_SESD.read(r); - break; - case SBIG('SEPO'): - xfc_SEPO.read(r); - break; - case SBIG('PSLT'): - xc_PSLT.read(r); - break; - case SBIG('PMSC'): - x74_PMSC.read(r); - break; - case SBIG('PMOP'): - x6c_PMOP.read(r); - break; - case SBIG('PMDL'): - x5c_PMDL.read(r); - break; - case SBIG('PMRT'): - x70_PMRT.read(r); - break; - case SBIG('POFS'): - x18_POFS.read(r); - break; - case SBIG('PMUS'): - r.readUint32Big(); - x45_24_PMUS = r.readBool(); - break; - case SBIG('PSIV'): - x0_PSIV.read(r); - break; - case SBIG('ROTA'): - x50_ROTA.read(r); - break; - case SBIG('PSVM'): - x4_PSVM.read(r); - break; - case SBIG('PSTS'): - x14_PSTS.read(r); - break; - case SBIG('PSOV'): - x8_PSOV.read(r); - break; - case SBIG('PSWT'): - x10_PSWT.read(r); - break; - case SBIG('PMLC'): - xec_PMLC.read(r); - break; - case SBIG('SEED'): - x1c_SEED.read(r); - break; - case SBIG('PMOO'): - r.readUint32Big(); - x45_25_PMOO = r.readBool(); - break; - case SBIG('SSSD'): - xe4_SSSD.read(r); - break; - case SBIG('SORT'): - r.readUint32Big(); - x44_28_SORT = r.readBool(); - break; - case SBIG('SIZE'): - x4c_SIZE.read(r); - break; - case SBIG('SISY'): - xcc_SISY.read(r); - break; - case SBIG('SSPO'): - xe8_SSPO.read(r); - break; - case SBIG('TEXR'): - x54_TEXR.read(r); - break; - case SBIG('SSWH'): - xd4_SSWH.read(r); - break; - case SBIG('TIND'): - x58_TIND.read(r); - break; - case SBIG('VMD4'): - r.readUint32Big(); - x45_29_VMD4 = r.readBool(); - break; - case SBIG('VMD3'): - r.readUint32Big(); - x45_28_VMD3 = r.readBool(); - break; - case SBIG('VMD2'): - r.readUint32Big(); - x45_27_VMD2 = r.readBool(); - break; - case SBIG('VMD1'): - r.readUint32Big(); - x45_26_VMD1 = r.readBool(); - break; - case SBIG('VEL4'): - x88_VEL4.read(r); - break; - case SBIG('VEL3'): - x84_VEL3.read(r); - break; - case SBIG('VEL2'): - x80_VEL2.read(r); - break; - case SBIG('VEL1'): - x7c_VEL1.read(r); - break; - case SBIG('ZBUF'): - r.readUint32Big(); - x44_27_ZBUF = r.readBool(); - break; - case SBIG('WIDT'): - x24_WIDT.read(r); - break; - case SBIG('ORNT'): - r.readUint32Big(); - x30_30_ORNT = r.readBool(); - break; - case SBIG('RSOP'): - r.readUint32Big(); - x30_31_RSOP = r.readBool(); - break; - case SBIG('ADV1'): - x10c_ADV1.read(r); - break; - case SBIG('ADV2'): - x110_ADV2.read(r); - break; - case SBIG('ADV3'): - x114_ADV3.read(r); - break; - case SBIG('ADV4'): - x118_ADV4.read(r); - break; - case SBIG('ADV5'): - x11c_ADV5.read(r); - break; - case SBIG('ADV6'): - x120_ADV6.read(r); - break; - case SBIG('ADV7'): - x124_ADV7.read(r); - break; - case SBIG('ADV8'): - x128_ADV8.read(r); - break; - case SBIG('SELC'): - xd8_SELC.read(r); - break; - default: - LogModule.report(logvisor::Fatal, fmt("Unknown GPSM class {} @{}"), clsId, r.position()); - break; - } - clsId.read(r); - } -} - -template -void GPSM::_write(typename Write::StreamT& w) const { - w.writeBytes((atInt8*)"GPSM", 4); - if (x0_PSIV) { - w.writeBytes((atInt8*)"PSIV", 4); - x0_PSIV.write(w); - } - if (x4_PSVM) { - w.writeBytes((atInt8*)"PSVM", 4); - x4_PSVM.write(w); - } - if (x8_PSOV) { - w.writeBytes((atInt8*)"PSOV", 4); - x8_PSOV.write(w); - } - if (xc_PSLT) { - w.writeBytes((atInt8*)"PSLT", 4); - xc_PSLT.write(w); - } - if (x10_PSWT) { - w.writeBytes((atInt8*)"PSWT", 4); - x10_PSWT.write(w); - } - if (x14_PSTS) { - w.writeBytes((atInt8*)"PSTS", 4); - x14_PSTS.write(w); - } - if (x18_POFS) { - w.writeBytes((atInt8*)"POFS", 4); - x18_POFS.write(w); - } - if (x1c_SEED) { - w.writeBytes((atInt8*)"SEED", 4); - x1c_SEED.write(w); - } - if (x20_LENG) { - w.writeBytes((atInt8*)"LENG", 4); - x20_LENG.write(w); - } - if (x24_WIDT) { - w.writeBytes((atInt8*)"WIDT", 4); - x24_WIDT.write(w); - } - if (x28_MAXP) { - w.writeBytes((atInt8*)"MAXP", 4); - x28_MAXP.write(w); - } - if (x2c_GRTE) { - w.writeBytes((atInt8*)"GRTE", 4); - x2c_GRTE.write(w); - } - if (x30_COLR) { - w.writeBytes((atInt8*)"COLR", 4); - x30_COLR.write(w); - } - if (x34_LTME) { - w.writeBytes((atInt8*)"LTME", 4); - x34_LTME.write(w); - } - if (x38_ILOC) { - w.writeBytes((atInt8*)"ILOC", 4); - x38_ILOC.write(w); - } - if (x3c_IVEC) { - w.writeBytes((atInt8*)"IVEC", 4); - x3c_IVEC.write(w); - } - if (x40_EMTR) { - w.writeBytes((atInt8*)"EMTR", 4); - x40_EMTR.write(w); - } - if (x44_24_LINE) { - w.writeBytes((atInt8*)"LINECNST\x01", 9); - } - if (x44_25_FXLL) { - w.writeBytes((atInt8*)"FXLLCNST\x01", 9); - } - if (x44_26_AAPH) { - w.writeBytes((atInt8*)"AAPHCNST\x01", 9); - } - if (x44_27_ZBUF) { - w.writeBytes((atInt8*)"ZBUFCNST\x01", 9); - } - if (x44_28_SORT) { - w.writeBytes((atInt8*)"SORTCNST\x01", 9); - } - if (x44_29_LIT_) { - w.writeBytes((atInt8*)"LIT_CNST\x01", 9); - } - if (x44_30_MBLR) { - w.writeBytes((atInt8*)"MBLRCNST\x01", 9); - } - if (x44_31_PMAB) { - w.writeBytes((atInt8*)"PMABCNST\x01", 9); - } - if (x45_24_PMUS) { - w.writeBytes((atInt8*)"PMUSCNST\x01", 9); - } - if (!x45_25_PMOO) { - w.writeBytes((atInt8*)"PMOOCNST\x00", 9); - } - if (x45_26_VMD1) { - w.writeBytes((atInt8*)"VMD1CNST\x01", 9); - } - if (x45_27_VMD2) { - w.writeBytes((atInt8*)"VMD2CNST\x01", 9); - } - if (x45_28_VMD3) { - w.writeBytes((atInt8*)"VMD3CNST\x01", 9); - } - if (x45_29_VMD4) { - w.writeBytes((atInt8*)"VMD4CNST\x01", 9); - } - if (x45_30_CIND) { - w.writeBytes((atInt8*)"CINDCNST\x01", 9); - } - if (x45_31_OPTS) { - w.writeBytes((atInt8*)"OPTSCNST\x01", 9); - } - if (x30_30_ORNT) { - w.writeBytes((atInt8*)"ORNTCNST\x01", 9); - } - if (x30_31_RSOP) { - w.writeBytes((atInt8*)"RSOPCNST\x01", 9); - } - if (x48_MBSP) { - w.writeBytes((atInt8*)"MBSP", 4); - x48_MBSP.write(w); - } - if (x4c_SIZE) { - w.writeBytes((atInt8*)"SIZE", 4); - x4c_SIZE.write(w); - } - if (x50_ROTA) { - w.writeBytes((atInt8*)"ROTA", 4); - x50_ROTA.write(w); - } - if (x54_TEXR) { - w.writeBytes((atInt8*)"TEXR", 4); - x54_TEXR.write(w); - } - if (x58_TIND) { - w.writeBytes((atInt8*)"TIND", 4); - x58_TIND.write(w); - } - if (x5c_PMDL) { - w.writeBytes((atInt8*)"PMDL", 4); - x5c_PMDL.write(w); - } - if (x6c_PMOP) { - w.writeBytes((atInt8*)"PMOP", 4); - x6c_PMOP.write(w); - } - if (x70_PMRT) { - w.writeBytes((atInt8*)"PMRT", 4); - x70_PMRT.write(w); - } - if (x74_PMSC) { - w.writeBytes((atInt8*)"PMSC", 4); - x74_PMSC.write(w); - } - if (x78_PMCL) { - w.writeBytes((atInt8*)"PMCL", 4); - x78_PMCL.write(w); - } - if (x7c_VEL1) { - w.writeBytes((atInt8*)"VEL1", 4); - x7c_VEL1.write(w); - } - if (x80_VEL2) { - w.writeBytes((atInt8*)"VEL2", 4); - x80_VEL2.write(w); - } - if (x84_VEL3) { - w.writeBytes((atInt8*)"VEL3", 4); - x84_VEL3.write(w); - } - if (x88_VEL4) { - w.writeBytes((atInt8*)"VEL4", 4); - x88_VEL4.write(w); - } - if (x8c_ICTS) { - w.writeBytes((atInt8*)"ICTS", 4); - x8c_ICTS.write(w); - } - if (x9c_NCSY) { - w.writeBytes((atInt8*)"NCSY", 4); - x9c_NCSY.write(w); - } - if (xa0_CSSD) { - w.writeBytes((atInt8*)"CSSD", 4); - xa0_CSSD.write(w); - } - if (xa4_IDTS) { - w.writeBytes((atInt8*)"IDTS", 4); - xa4_IDTS.write(w); - } - if (xb4_NDSY) { - w.writeBytes((atInt8*)"NDSY", 4); - xb4_NDSY.write(w); - } - if (xb8_IITS) { - w.writeBytes((atInt8*)"IITS", 4); - xb8_IITS.write(w); - } - if (xc8_PISY) { - w.writeBytes((atInt8*)"PISY", 4); - xc8_PISY.write(w); - } - if (xcc_SISY) { - w.writeBytes((atInt8*)"SISY", 4); - xcc_SISY.write(w); - } - if (xd0_KSSM) { - w.writeBytes((atInt8*)"KSSM", 4); - xd0_KSSM.write(w); - } - if (xd4_SSWH) { - w.writeBytes((atInt8*)"SSWH", 4); - xd4_SSWH.write(w); - } - if (xd8_SELC) { - w.writeBytes((atInt8*)"SELC", 4); - xd8_SELC.write(w); - } - if (xe4_SSSD) { - w.writeBytes((atInt8*)"SSSD", 4); - xe4_SSSD.write(w); - } - if (xe8_SSPO) { - w.writeBytes((atInt8*)"SSPO", 4); - xe8_SSPO.write(w); - } - if (xf8_SESD) { - w.writeBytes((atInt8*)"SESD", 4); - xf8_SESD.write(w); - } - if (xfc_SEPO) { - w.writeBytes((atInt8*)"SEPO", 4); - xfc_SEPO.write(w); - } - if (xec_PMLC) { - w.writeBytes((atInt8*)"PMLC", 4); - xec_PMLC.write(w); - } - if (x100_LTYP) { - w.writeBytes((atInt8*)"LTYP", 4); - x100_LTYP.write(w); - } - if (x104_LCLR) { - w.writeBytes((atInt8*)"LCLR", 4); - x104_LCLR.write(w); - } - if (x108_LINT) { - w.writeBytes((atInt8*)"LINT", 4); - x108_LINT.write(w); - } - if (x10c_LOFF) { - w.writeBytes((atInt8*)"LOFF", 4); - x10c_LOFF.write(w); - } - if (x110_LDIR) { - w.writeBytes((atInt8*)"LDIR", 4); - x110_LDIR.write(w); - } - if (x114_LFOT) { - w.writeBytes((atInt8*)"LFOT", 4); - x114_LFOT.write(w); - } - if (x118_LFOR) { - w.writeBytes((atInt8*)"LFOR", 4); - x118_LFOR.write(w); - } - if (x11c_LSLA) { - w.writeBytes((atInt8*)"LSLA", 4); - x11c_LSLA.write(w); - } - if (x10c_ADV1) { - w.writeBytes((atInt8*)"ADV1", 4); - x10c_ADV1.write(w); - } - if (x110_ADV2) { - w.writeBytes((atInt8*)"ADV2", 4); - x110_ADV2.write(w); - } - if (x114_ADV3) { - w.writeBytes((atInt8*)"ADV3", 4); - x114_ADV3.write(w); - } - if (x118_ADV4) { - w.writeBytes((atInt8*)"ADV4", 4); - x118_ADV4.write(w); - } - if (x11c_ADV5) { - w.writeBytes((atInt8*)"ADV5", 4); - x11c_ADV5.write(w); - } - if (x120_ADV6) { - w.writeBytes((atInt8*)"ADV6", 4); - x120_ADV6.write(w); - } - if (x124_ADV7) { - w.writeBytes((atInt8*)"ADV7", 4); - x124_ADV7.write(w); - } - if (x128_ADV8) { - w.writeBytes((atInt8*)"ADV8", 4); - x128_ADV8.write(w); - } - w.writeBytes("_END", 4); -} - -AT_SUBSPECIALIZE_DNA_YAML(GPSM) -AT_SUBSPECIALIZE_DNA_YAML(GPSM) - -template -void GPSM::gatherDependencies(std::vector& pathsOut) const { - if (x54_TEXR.m_elem) - x54_TEXR.m_elem->gatherDependencies(pathsOut); - if (x58_TIND.m_elem) - x58_TIND.m_elem->gatherDependencies(pathsOut); - g_curSpec->flattenDependencies(x5c_PMDL.id, pathsOut); - g_curSpec->flattenDependencies(x8c_ICTS.id, pathsOut); - g_curSpec->flattenDependencies(xa4_IDTS.id, pathsOut); - g_curSpec->flattenDependencies(xb8_IITS.id, pathsOut); - xd0_KSSM.gatherDependencies(pathsOut); - g_curSpec->flattenDependencies(xd4_SSWH.id, pathsOut); - g_curSpec->flattenDependencies(xec_PMLC.id, pathsOut); - g_curSpec->flattenDependencies(xd8_SELC.id, pathsOut); -} - -template struct GPSM; -template struct GPSM; - template bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { athena::io::FileWriter writer(outPath.getAbsolutePath()); diff --git a/DataSpec/DNACommon/PART.def b/DataSpec/DNACommon/PART.def new file mode 100644 index 000000000..8b932cbf3 --- /dev/null +++ b/DataSpec/DNACommon/PART.def @@ -0,0 +1,141 @@ +#ifndef ENTRY +#define ENTRY(name, identifier) +#endif + +#ifndef INT_ENTRY +#define INT_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef REAL_ENTRY +#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef VECTOR_ENTRY +#define VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef MOD_VECTOR_ENTRY +#define MOD_VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef COLOR_ENTRY +#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef EMITTER_ENTRY +#define EMITTER_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef UV_ENTRY +#define UV_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef RES_ENTRY +#define RES_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef KSSM_ENTRY +#define KSSM_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef BOOL_ENTRY +#define BOOL_ENTRY(name, identifier, def) ENTRY(name, identifier) +#endif + +VECTOR_ENTRY('PSIV', x0_PSIV) +MOD_VECTOR_ENTRY('PSVM', x4_PSVM) +VECTOR_ENTRY('PSOV', x8_PSOV) +INT_ENTRY('PSLT', xc_PSLT) +INT_ENTRY('PSWT', x10_PSWT) +REAL_ENTRY('PSTS', x14_PSTS) +VECTOR_ENTRY('POFS', x18_POFS) +INT_ENTRY('SEED', x1c_SEED) +REAL_ENTRY('LENG', x20_LENG) +REAL_ENTRY('WIDT', x24_WIDT) +INT_ENTRY('MAXP', x28_MAXP) +REAL_ENTRY('GRTE', x2c_GRTE) +COLOR_ENTRY('COLR', x30_COLR) +INT_ENTRY('LTME', x34_LTME) +VECTOR_ENTRY('ILOC', x38_ILOC) +VECTOR_ENTRY('IVEC', x3c_IVEC) +EMITTER_ENTRY('EMTR', x40_EMTR) +INT_ENTRY('MBSP', x48_MBSP) +REAL_ENTRY('SIZE', x4c_SIZE) +REAL_ENTRY('ROTA', x50_ROTA) +UV_ENTRY('TEXR', x54_TEXR) +UV_ENTRY('TIND', x58_TIND) +RES_ENTRY('PMDL', x5c_PMDL) +VECTOR_ENTRY('PMOP', x6c_PMOP) +VECTOR_ENTRY('PMRT', x70_PMRT) +VECTOR_ENTRY('PMSC', x74_PMSC) +COLOR_ENTRY('PMCL', x78_PMCL) +MOD_VECTOR_ENTRY('VEL1', x7c_VEL1) +MOD_VECTOR_ENTRY('VEL2', x80_VEL2) +MOD_VECTOR_ENTRY('VEL3', x84_VEL3) +MOD_VECTOR_ENTRY('VEL4', x88_VEL4) +RES_ENTRY('ICTS', x8c_ICTS) +INT_ENTRY('NCSY', x9c_NCSY) +INT_ENTRY('CSSD', xa0_CSSD) +RES_ENTRY('IDTS', xa4_IDTS) +INT_ENTRY('NDSY', xb4_NDSY) +RES_ENTRY('IITS', xb8_IITS) +INT_ENTRY('PISY', xc8_PISY) +INT_ENTRY('SISY', xcc_SISY) +KSSM_ENTRY('KSSM', xd0_KSSM) +RES_ENTRY('SSWH', xd4_SSWH) +INT_ENTRY('SSSD', xe4_SSSD) +VECTOR_ENTRY('SSPO', xe8_SSPO) +INT_ENTRY('SESD', xf8_SESD) +VECTOR_ENTRY('SEPO', xfc_SEPO) +RES_ENTRY('PMLC', xec_PMLC) +INT_ENTRY('LTYP', x100_LTYP) +COLOR_ENTRY('LCLR', x104_LCLR) +REAL_ENTRY('LINT', x108_LINT) +VECTOR_ENTRY('LOFF', x10c_LOFF) +VECTOR_ENTRY('LDIR', x110_LDIR) +INT_ENTRY('LFOT', x114_LFOT) +REAL_ENTRY('LFOR', x118_LFOR) +REAL_ENTRY('LSLA', x11c_LSLA) + +/* 0-00 additions */ +RES_ENTRY('SELC', xd8_SELC) +REAL_ENTRY('ADV1', x10c_ADV1) +REAL_ENTRY('ADV2', x110_ADV2) +REAL_ENTRY('ADV3', x114_ADV3) +REAL_ENTRY('ADV4', x118_ADV4) +REAL_ENTRY('ADV5', x11c_ADV5) +REAL_ENTRY('ADV6', x120_ADV6) +REAL_ENTRY('ADV7', x124_ADV7) +REAL_ENTRY('ADV8', x128_ADV8) + +BOOL_ENTRY('SORT', x44_28_SORT, false) +BOOL_ENTRY('MBLR', x44_30_MBLR, false) +BOOL_ENTRY('LINE', x44_24_LINE, false) +BOOL_ENTRY('LIT_', x44_29_LIT_, false) +BOOL_ENTRY('AAPH', x44_26_AAPH, false) +BOOL_ENTRY('ZBUF', x44_27_ZBUF, false) +BOOL_ENTRY('FXLL', x44_25_FXLL, false) +BOOL_ENTRY('PMAB', x44_31_PMAB, false) +BOOL_ENTRY('VMD4', x45_29_VMD4, false) +BOOL_ENTRY('VMD3', x45_28_VMD3, false) +BOOL_ENTRY('VMD2', x45_27_VMD2, false) +BOOL_ENTRY('VMD1', x45_26_VMD1, false) +BOOL_ENTRY('OPTS', x45_31_OPTS, false) +BOOL_ENTRY('PMUS', x45_24_PMUS, false) +BOOL_ENTRY('PMOO', x45_25_PMOO, true) +BOOL_ENTRY('CIND', x45_30_CIND, false) + +BOOL_ENTRY('ORNT', x30_30_ORNT, false) +BOOL_ENTRY('RSOP', x30_31_RSOP, false) + +#undef ENTRY +#undef INT_ENTRY +#undef REAL_ENTRY +#undef VECTOR_ENTRY +#undef MOD_VECTOR_ENTRY +#undef COLOR_ENTRY +#undef EMITTER_ENTRY +#undef UV_ENTRY +#undef RES_ENTRY +#undef KSSM_ENTRY +#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/PART.hpp b/DataSpec/DNACommon/PART.hpp index 0475dc217..8c30dc28d 100644 --- a/DataSpec/DNACommon/PART.hpp +++ b/DataSpec/DNACommon/PART.hpp @@ -17,107 +17,39 @@ class ProjectPath; namespace DataSpec::DNAParticle { template -struct GPSM : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - VectorElementFactory x0_PSIV; - ModVectorElementFactory x4_PSVM; - VectorElementFactory x8_PSOV; - IntElementFactory xc_PSLT; - IntElementFactory x10_PSWT; - RealElementFactory x14_PSTS; - VectorElementFactory x18_POFS; - IntElementFactory x1c_SEED; - RealElementFactory x20_LENG; - RealElementFactory x24_WIDT; - IntElementFactory x28_MAXP; - RealElementFactory x2c_GRTE; - ColorElementFactory x30_COLR; - IntElementFactory x34_LTME; - VectorElementFactory x38_ILOC; - VectorElementFactory x3c_IVEC; - EmitterElementFactory x40_EMTR; - union { - struct { - bool x44_28_SORT : 1; - bool x44_30_MBLR : 1; - bool x44_24_LINE : 1; - bool x44_29_LIT_ : 1; - bool x44_26_AAPH : 1; - bool x44_27_ZBUF : 1; - bool x44_25_FXLL : 1; - bool x44_31_PMAB : 1; - bool x45_29_VMD4 : 1; - bool x45_28_VMD3 : 1; - bool x45_27_VMD2 : 1; - bool x45_26_VMD1 : 1; - bool x45_31_OPTS : 1; - bool x45_24_PMUS : 1; - bool x45_25_PMOO : 1; - bool x45_30_CIND : 1; - }; - uint16_t dummy1 = 0; - }; - IntElementFactory x48_MBSP; - RealElementFactory x4c_SIZE; - RealElementFactory x50_ROTA; - UVElementFactory x54_TEXR; - UVElementFactory x58_TIND; - ChildResourceFactory x5c_PMDL; - VectorElementFactory x6c_PMOP; - VectorElementFactory x70_PMRT; - VectorElementFactory x74_PMSC; - ColorElementFactory x78_PMCL; - ModVectorElementFactory x7c_VEL1; - ModVectorElementFactory x80_VEL2; - ModVectorElementFactory x84_VEL3; - ModVectorElementFactory x88_VEL4; - ChildResourceFactory x8c_ICTS; - IntElementFactory x9c_NCSY; - IntElementFactory xa0_CSSD; - ChildResourceFactory xa4_IDTS; - IntElementFactory xb4_NDSY; - ChildResourceFactory xb8_IITS; - IntElementFactory xc8_PISY; - IntElementFactory xcc_SISY; - SpawnSystemKeyframeData xd0_KSSM; - ChildResourceFactory xd4_SSWH; - IntElementFactory xe4_SSSD; - VectorElementFactory xe8_SSPO; - IntElementFactory xf8_SESD; - VectorElementFactory xfc_SEPO; - ChildResourceFactory xec_PMLC; - IntElementFactory x100_LTYP; - ColorElementFactory x104_LCLR; - RealElementFactory x108_LINT; - VectorElementFactory x10c_LOFF; - VectorElementFactory x110_LDIR; - IntElementFactory x114_LFOT; - RealElementFactory x118_LFOR; - RealElementFactory x11c_LSLA; +struct _GPSM { + static constexpr ParticleType Type = ParticleType::GPSM; - /* 0-00 additions */ - ChildResourceFactory xd8_SELC; - union { - struct { - bool x30_30_ORNT : 1; - bool x30_31_RSOP : 1; - }; - uint16_t dummy2 = 0; - }; - RealElementFactory x10c_ADV1; - RealElementFactory x110_ADV2; - RealElementFactory x114_ADV3; - RealElementFactory x118_ADV4; - RealElementFactory x11c_ADV5; - RealElementFactory x120_ADV6; - RealElementFactory x124_ADV7; - RealElementFactory x128_ADV8; +#define INT_ENTRY(name, identifier) IntElementFactory identifier; +#define REAL_ENTRY(name, identifier) RealElementFactory identifier; +#define VECTOR_ENTRY(name, identifier) VectorElementFactory identifier; +#define MOD_VECTOR_ENTRY(name, identifier) ModVectorElementFactory identifier; +#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; +#define EMITTER_ENTRY(name, identifier) EmitterElementFactory identifier; +#define UV_ENTRY(name, identifier) UVElementFactory identifier; +#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; +#define KSSM_ENTRY(name, identifier) SpawnSystemKeyframeData identifier; +#define BOOL_ENTRY(name, identifier, def) bool identifier = def; +#include "PART.def" - GPSM() { x45_25_PMOO = true; } + template + void constexpr Enumerate(_Func f) { +#define ENTRY(name, identifier) f(FOURCC(name), identifier); +#define BOOL_ENTRY(name, identifier, def) f(FOURCC(name), identifier, def); +#include "PART.def" + } - void gatherDependencies(std::vector&) const; + template + bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { +#define ENTRY(name, identifier) case SBIG(name): f(identifier); return true; +#include "PART.def" + default: return false; + } + } }; +template +using GPSM = PPImpl<_GPSM>; template bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); diff --git a/DataSpec/DNACommon/ParticleCommon.cpp b/DataSpec/DNACommon/ParticleCommon.cpp index 7ef172e8b..301f6ac56 100644 --- a/DataSpec/DNACommon/ParticleCommon.cpp +++ b/DataSpec/DNACommon/ParticleCommon.cpp @@ -3,6 +3,24 @@ namespace DataSpec::DNAParticle { logvisor::Module LogModule("urde::DNAParticle"); +template struct PEImpl<_RealElementFactory>; +template struct PEImpl<_IntElementFactory>; +template struct PEImpl<_VectorElementFactory>; +template struct PEImpl<_ColorElementFactory>; +template struct PEImpl<_ModVectorElementFactory>; +template struct PEImpl<_EmitterElementFactory>; +template struct PEImpl<_UVElementFactory>; +template struct PEImpl<_UVElementFactory>; + +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_RealElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_IntElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_VectorElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_ColorElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_ModVectorElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_EmitterElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_UVElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_UVElementFactory>) + template <> void REConstant::Enumerate(typename ReadYaml::StreamT& r) { val = r.readFloat(); @@ -148,908 +166,6 @@ void MVEConstant::Enumerate(typename Write::StreamT& w) { comps[2].write(w); } -template <> -void RealElementFactory::Enumerate(typename ReadYaml::StreamT& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& elem = mapChildren[0]; - if (elem.first.size() < 4) - LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), elem.first); - - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('LFTW'): - m_elem.reset(new struct RELifetimeTween); - break; - case SBIG('CNST'): - m_elem.reset(new struct REConstant); - break; - case SBIG('CHAN'): - m_elem.reset(new struct RETimeChain); - break; - case SBIG('ADD_'): - m_elem.reset(new struct REAdd); - break; - case SBIG('CLMP'): - m_elem.reset(new struct REClamp); - break; - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct REKeyframeEmitter); - break; - case SBIG('IRND'): - m_elem.reset(new struct REInitialRandom); - break; - case SBIG('RAND'): - m_elem.reset(new struct RERandom); - break; - case SBIG('MULT'): - m_elem.reset(new struct REMultiply); - break; - case SBIG('PULS'): - m_elem.reset(new struct REPulse); - break; - case SBIG('SCAL'): - m_elem.reset(new struct RETimeScale); - break; - case SBIG('RLPT'): - m_elem.reset(new struct RELifetimePercent); - break; - case SBIG('SINE'): - m_elem.reset(new struct RESineWave); - break; - case SBIG('ISWT'): - m_elem.reset(new struct REInitialSwitch); - break; - case SBIG('CLTN'): - m_elem.reset(new struct RECompareLessThan); - break; - case SBIG('CEQL'): - m_elem.reset(new struct RECompareEquals); - break; - case SBIG('PAP1'): - m_elem.reset(new struct REParticleAdvanceParam1); - break; - case SBIG('PAP2'): - m_elem.reset(new struct REParticleAdvanceParam2); - break; - case SBIG('PAP3'): - m_elem.reset(new struct REParticleAdvanceParam3); - break; - case SBIG('PAP4'): - m_elem.reset(new struct REParticleAdvanceParam4); - break; - case SBIG('PAP5'): - m_elem.reset(new struct REParticleAdvanceParam5); - break; - case SBIG('PAP6'): - m_elem.reset(new struct REParticleAdvanceParam6); - break; - case SBIG('PAP7'): - m_elem.reset(new struct REParticleAdvanceParam7); - break; - case SBIG('PAP8'): - m_elem.reset(new struct REParticleAdvanceParam8); - break; - case SBIG('PSLL'): - m_elem.reset(new struct REParticleSizeOrLineLength); - break; - case SBIG('PRLW'): - m_elem.reset(new struct REParticleRotationOrLineWidth); - break; - case SBIG('SUB_'): - m_elem.reset(new struct RESubtract); - break; - case SBIG('VMAG'): - m_elem.reset(new struct REVectorMagnitude); - break; - case SBIG('VXTR'): - m_elem.reset(new struct REVectorXToReal); - break; - case SBIG('VYTR'): - m_elem.reset(new struct REVectorYToReal); - break; - case SBIG('VZTR'): - m_elem.reset(new struct REVectorZToReal); - break; - case SBIG('CEXT'): - m_elem.reset(new struct RECEXT); - break; - case SBIG('ITRL'): - m_elem.reset(new struct REIntTimesReal); - break; - default: - m_elem.reset(); - return; - } - if (auto rec = r.enterSubRecord(elem.first.c_str())) - m_elem->read(r); -} - -template <> -void RealElementFactory::Enumerate(typename WriteYaml::StreamT& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} - -template <> -void RealElementFactory::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - if (m_elem) - m_elem->binarySize(s); -} - -template <> -void RealElementFactory::Enumerate(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - switch (clsId.toUint32()) { - case SBIG('LFTW'): - m_elem.reset(new struct RELifetimeTween); - break; - case SBIG('CNST'): - m_elem.reset(new struct REConstant); - break; - case SBIG('CHAN'): - m_elem.reset(new struct RETimeChain); - break; - case SBIG('ADD_'): - m_elem.reset(new struct REAdd); - break; - case SBIG('CLMP'): - m_elem.reset(new struct REClamp); - break; - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct REKeyframeEmitter); - break; - case SBIG('IRND'): - m_elem.reset(new struct REInitialRandom); - break; - case SBIG('RAND'): - m_elem.reset(new struct RERandom); - break; - case SBIG('MULT'): - m_elem.reset(new struct REMultiply); - break; - case SBIG('PULS'): - m_elem.reset(new struct REPulse); - break; - case SBIG('SCAL'): - m_elem.reset(new struct RETimeScale); - break; - case SBIG('RLPT'): - m_elem.reset(new struct RELifetimePercent); - break; - case SBIG('SINE'): - m_elem.reset(new struct RESineWave); - break; - case SBIG('ISWT'): - m_elem.reset(new struct REInitialSwitch); - break; - case SBIG('CLTN'): - m_elem.reset(new struct RECompareLessThan); - break; - case SBIG('CEQL'): - m_elem.reset(new struct RECompareEquals); - break; - case SBIG('PAP1'): - m_elem.reset(new struct REParticleAdvanceParam1); - break; - case SBIG('PAP2'): - m_elem.reset(new struct REParticleAdvanceParam2); - break; - case SBIG('PAP3'): - m_elem.reset(new struct REParticleAdvanceParam3); - break; - case SBIG('PAP4'): - m_elem.reset(new struct REParticleAdvanceParam4); - break; - case SBIG('PAP5'): - m_elem.reset(new struct REParticleAdvanceParam5); - break; - case SBIG('PAP6'): - m_elem.reset(new struct REParticleAdvanceParam6); - break; - case SBIG('PAP7'): - m_elem.reset(new struct REParticleAdvanceParam7); - break; - case SBIG('PAP8'): - m_elem.reset(new struct REParticleAdvanceParam8); - break; - case SBIG('PSLL'): - m_elem.reset(new struct REParticleSizeOrLineLength); - break; - case SBIG('PRLW'): - m_elem.reset(new struct REParticleRotationOrLineWidth); - break; - case SBIG('SUB_'): - m_elem.reset(new struct RESubtract); - break; - case SBIG('VMAG'): - m_elem.reset(new struct REVectorMagnitude); - break; - case SBIG('VXTR'): - m_elem.reset(new struct REVectorXToReal); - break; - case SBIG('VYTR'): - m_elem.reset(new struct REVectorYToReal); - break; - case SBIG('VZTR'): - m_elem.reset(new struct REVectorZToReal); - break; - case SBIG('CEXT'): - m_elem.reset(new struct RECEXT); - break; - case SBIG('ITRL'): - m_elem.reset(new struct REIntTimesReal); - break; - case SBIG('NONE'): - m_elem.reset(); - return; - default: - m_elem.reset(); - LogModule.report(logvisor::Fatal, fmt("Unknown RealElement class {} @{}"), clsId, r.position()); - return; - } - m_elem->read(r); -} - -template <> -void RealElementFactory::Enumerate(typename Write::StreamT& w) { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} - -template <> -void IntElementFactory::Enumerate(typename ReadYaml::StreamT& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& elem = mapChildren[0]; - if (elem.first.size() < 4) - LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), elem.first); - - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct IEKeyframeEmitter); - break; - case SBIG('DETH'): - m_elem.reset(new struct IEDeath); - break; - case SBIG('CLMP'): - m_elem.reset(new struct IEClamp); - break; - case SBIG('CHAN'): - m_elem.reset(new struct IETimeChain); - break; - case SBIG('ADD_'): - m_elem.reset(new struct IEAdd); - break; - case SBIG('CNST'): - m_elem.reset(new struct IEConstant); - break; - case SBIG('IMPL'): - m_elem.reset(new struct IEImpulse); - break; - case SBIG('ILPT'): - m_elem.reset(new struct IELifetimePercent); - break; - case SBIG('IRND'): - m_elem.reset(new struct IEInitialRandom); - break; - case SBIG('PULS'): - m_elem.reset(new struct IEPulse); - break; - case SBIG('MULT'): - m_elem.reset(new struct IEMultiply); - break; - case SBIG('SPAH'): - m_elem.reset(new struct IESampleAndHold); - break; - case SBIG('RAND'): - m_elem.reset(new struct IERandom); - break; - case SBIG('TSCL'): - m_elem.reset(new struct IETimeScale); - break; - case SBIG('GTCP'): - m_elem.reset(new struct IEGTCP); - break; - case SBIG('MODU'): - m_elem.reset(new struct IEModulo); - break; - case SBIG('SUB_'): - m_elem.reset(new struct IESubtract); - break; - default: - m_elem.reset(); - return; - } - if (auto rec = r.enterSubRecord(elem.first.c_str())) - m_elem->read(r); -} - -template <> -void IntElementFactory::Enumerate(typename WriteYaml::StreamT& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} - -template <> -void IntElementFactory::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - if (m_elem) - m_elem->binarySize(s); -} - -template <> -void IntElementFactory::Enumerate(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - switch (clsId.toUint32()) { - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct IEKeyframeEmitter); - break; - case SBIG('DETH'): - m_elem.reset(new struct IEDeath); - break; - case SBIG('CLMP'): - m_elem.reset(new struct IEClamp); - break; - case SBIG('CHAN'): - m_elem.reset(new struct IETimeChain); - break; - case SBIG('ADD_'): - m_elem.reset(new struct IEAdd); - break; - case SBIG('CNST'): - m_elem.reset(new struct IEConstant); - break; - case SBIG('IMPL'): - m_elem.reset(new struct IEImpulse); - break; - case SBIG('ILPT'): - m_elem.reset(new struct IELifetimePercent); - break; - case SBIG('IRND'): - m_elem.reset(new struct IEInitialRandom); - break; - case SBIG('PULS'): - m_elem.reset(new struct IEPulse); - break; - case SBIG('MULT'): - m_elem.reset(new struct IEMultiply); - break; - case SBIG('SPAH'): - m_elem.reset(new struct IESampleAndHold); - break; - case SBIG('RAND'): - m_elem.reset(new struct IERandom); - break; - case SBIG('TSCL'): - m_elem.reset(new struct IETimeScale); - break; - case SBIG('GTCP'): - m_elem.reset(new struct IEGTCP); - break; - case SBIG('MODU'): - m_elem.reset(new struct IEModulo); - break; - case SBIG('SUB_'): - m_elem.reset(new struct IESubtract); - break; - case SBIG('NONE'): - m_elem.reset(); - return; - default: - m_elem.reset(); - LogModule.report(logvisor::Fatal, fmt("Unknown IntElement class {} @{}"), clsId, r.position()); - return; - } - m_elem->read(r); -} - -template <> -void IntElementFactory::Enumerate(typename Write::StreamT& w) { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} - -template <> -void VectorElementFactory::Enumerate(typename ReadYaml::StreamT& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& elem = mapChildren[0]; - if (elem.first.size() < 4) - LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), elem.first); - - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('CONE'): - m_elem.reset(new struct VECone); - break; - case SBIG('CHAN'): - m_elem.reset(new struct VETimeChain); - break; - case SBIG('ANGC'): - m_elem.reset(new struct VEAngleCone); - break; - case SBIG('ADD_'): - m_elem.reset(new struct VEAdd); - break; - case SBIG('CCLU'): - m_elem.reset(new struct VECircleCluster); - break; - case SBIG('CNST'): - m_elem.reset(new struct VEConstant); - break; - case SBIG('CIRC'): - m_elem.reset(new struct VECircle); - break; - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct VEKeyframeEmitter); - break; - case SBIG('MULT'): - m_elem.reset(new struct VEMultiply); - break; - case SBIG('RTOV'): - m_elem.reset(new struct VERealToVector); - break; - case SBIG('PULS'): - m_elem.reset(new struct VEPulse); - break; - case SBIG('PVEL'): - m_elem.reset(new struct VEParticleVelocity); - break; - case SBIG('SPOS'): - m_elem.reset(new struct VESPOS); - break; - case SBIG('PLCO'): - m_elem.reset(new struct VEPLCO); - break; - case SBIG('PLOC'): - m_elem.reset(new struct VEPLOC); - break; - case SBIG('PSOR'): - m_elem.reset(new struct VEPSOR); - break; - case SBIG('PSOF'): - m_elem.reset(new struct VEPSOF); - break; - default: - m_elem.reset(); - return; - } - if (auto rec = r.enterSubRecord(elem.first.c_str())) - m_elem->read(r); -} - -template <> -void VectorElementFactory::Enumerate(typename WriteYaml::StreamT& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} - -template <> -void VectorElementFactory::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - if (m_elem) - m_elem->binarySize(s); -} - -template <> -void VectorElementFactory::Enumerate(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - switch (clsId.toUint32()) { - case SBIG('CONE'): - m_elem.reset(new struct VECone); - break; - case SBIG('CHAN'): - m_elem.reset(new struct VETimeChain); - break; - case SBIG('ANGC'): - m_elem.reset(new struct VEAngleCone); - break; - case SBIG('ADD_'): - m_elem.reset(new struct VEAdd); - break; - case SBIG('CCLU'): - m_elem.reset(new struct VECircleCluster); - break; - case SBIG('CNST'): - m_elem.reset(new struct VEConstant); - break; - case SBIG('CIRC'): - m_elem.reset(new struct VECircle); - break; - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct VEKeyframeEmitter); - break; - case SBIG('MULT'): - m_elem.reset(new struct VEMultiply); - break; - case SBIG('RTOV'): - m_elem.reset(new struct VERealToVector); - break; - case SBIG('PULS'): - m_elem.reset(new struct VEPulse); - break; - case SBIG('PVEL'): - m_elem.reset(new struct VEParticleVelocity); - break; - case SBIG('SPOS'): - m_elem.reset(new struct VESPOS); - break; - case SBIG('PLCO'): - m_elem.reset(new struct VEPLCO); - break; - case SBIG('PLOC'): - m_elem.reset(new struct VEPLOC); - break; - case SBIG('PSOR'): - m_elem.reset(new struct VEPSOR); - break; - case SBIG('PSOF'): - m_elem.reset(new struct VEPSOF); - break; - case SBIG('NONE'): - m_elem.reset(); - return; - default: - m_elem.reset(); - LogModule.report(logvisor::Fatal, fmt("Unknown VectorElement class {} @{}"), clsId, r.position()); - return; - } - m_elem->read(r); -} - -template <> -void VectorElementFactory::Enumerate(typename Write::StreamT& w) { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} - -template <> -void ColorElementFactory::Enumerate(typename ReadYaml::StreamT& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& elem = mapChildren[0]; - if (elem.first.size() < 4) - LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), elem.first); - - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct CEKeyframeEmitter); - break; - case SBIG('CNST'): - m_elem.reset(new struct CEConstant); - break; - case SBIG('CHAN'): - m_elem.reset(new struct CETimeChain); - break; - case SBIG('CFDE'): - m_elem.reset(new struct CEFadeEnd); - break; - case SBIG('FADE'): - m_elem.reset(new struct CEFade); - break; - case SBIG('PULS'): - m_elem.reset(new struct CEPulse); - break; - default: - m_elem.reset(); - return; - } - if (auto rec = r.enterSubRecord(elem.first.c_str())) - m_elem->read(r); -} - -template <> -void ColorElementFactory::Enumerate(typename WriteYaml::StreamT& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} - -template <> -void ColorElementFactory::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - if (m_elem) - m_elem->binarySize(s); -} - -template <> -void ColorElementFactory::Enumerate(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - switch (clsId.toUint32()) { - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct CEKeyframeEmitter); - break; - case SBIG('CNST'): - m_elem.reset(new struct CEConstant); - break; - case SBIG('CHAN'): - m_elem.reset(new struct CETimeChain); - break; - case SBIG('CFDE'): - m_elem.reset(new struct CEFadeEnd); - break; - case SBIG('FADE'): - m_elem.reset(new struct CEFade); - break; - case SBIG('PULS'): - m_elem.reset(new struct CEPulse); - break; - case SBIG('NONE'): - m_elem.reset(); - return; - default: - m_elem.reset(); - LogModule.report(logvisor::Fatal, fmt("Unknown ColorElement class {} @{}"), clsId, r.position()); - return; - } - m_elem->read(r); -} - -template <> -void ColorElementFactory::Enumerate(typename Write::StreamT& w) { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} - -template <> -void ModVectorElementFactory::Enumerate(typename ReadYaml::StreamT& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& elem = mapChildren[0]; - if (elem.first.size() < 4) - LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), elem.first); - - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('IMPL'): - m_elem.reset(new struct MVEImplosion); - break; - case SBIG('EMPL'): - m_elem.reset(new struct MVEExponentialImplosion); - break; - case SBIG('CHAN'): - m_elem.reset(new struct MVETimeChain); - break; - case SBIG('BNCE'): - m_elem.reset(new struct MVEBounce); - break; - case SBIG('CNST'): - m_elem.reset(new struct MVEConstant); - break; - case SBIG('GRAV'): - m_elem.reset(new struct MVEGravity); - break; - case SBIG('EXPL'): - m_elem.reset(new struct MVEExplode); - break; - case SBIG('SPOS'): - m_elem.reset(new struct MVESetPosition); - break; - case SBIG('LMPL'): - m_elem.reset(new struct MVELinearImplosion); - break; - case SBIG('PULS'): - m_elem.reset(new struct MVEPulse); - break; - case SBIG('WIND'): - m_elem.reset(new struct MVEWind); - break; - case SBIG('SWRL'): - m_elem.reset(new struct MVESwirl); - break; - default: - m_elem.reset(); - return; - } - if (auto rec = r.enterSubRecord(elem.first.c_str())) - m_elem->read(r); -} - -template <> -void ModVectorElementFactory::Enumerate(typename WriteYaml::StreamT& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} - -template <> -void ModVectorElementFactory::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - if (m_elem) - m_elem->binarySize(s); -} - -template <> -void ModVectorElementFactory::Enumerate(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - switch (clsId.toUint32()) { - case SBIG('IMPL'): - m_elem.reset(new struct MVEImplosion); - break; - case SBIG('EMPL'): - m_elem.reset(new struct MVEExponentialImplosion); - break; - case SBIG('CHAN'): - m_elem.reset(new struct MVETimeChain); - break; - case SBIG('BNCE'): - m_elem.reset(new struct MVEBounce); - break; - case SBIG('CNST'): - m_elem.reset(new struct MVEConstant); - break; - case SBIG('GRAV'): - m_elem.reset(new struct MVEGravity); - break; - case SBIG('EXPL'): - m_elem.reset(new struct MVEExplode); - break; - case SBIG('SPOS'): - m_elem.reset(new struct MVESetPosition); - break; - case SBIG('LMPL'): - m_elem.reset(new struct MVELinearImplosion); - break; - case SBIG('PULS'): - m_elem.reset(new struct MVEPulse); - break; - case SBIG('WIND'): - m_elem.reset(new struct MVEWind); - break; - case SBIG('SWRL'): - m_elem.reset(new struct MVESwirl); - break; - case SBIG('NONE'): - m_elem.reset(); - return; - default: - m_elem.reset(); - LogModule.report(logvisor::Fatal, fmt("Unknown ModVectorElement class {} @{}"), clsId, r.position()); - return; - } - m_elem->read(r); -} - -template <> -void ModVectorElementFactory::Enumerate(typename Write::StreamT& w) { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} - -template <> -void EmitterElementFactory::Enumerate(typename ReadYaml::StreamT& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& elem = mapChildren[0]; - if (elem.first.size() < 4) - LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), elem.first); - - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('SETR'): - m_elem.reset(new struct EESimpleEmitterTR); - break; - case SBIG('SEMR'): - m_elem.reset(new struct EESimpleEmitter); - break; - case SBIG('SPHE'): - m_elem.reset(new struct VESphere); - break; - case SBIG('ASPH'): - m_elem.reset(new struct VEAngleSphere); - break; - default: - m_elem.reset(); - return; - } - if (auto rec = r.enterSubRecord(elem.first.c_str())) - m_elem->read(r); -} - -template <> -void EmitterElementFactory::Enumerate(typename WriteYaml::StreamT& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} - -template <> -void EmitterElementFactory::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - if (m_elem) - m_elem->binarySize(s); -} - -template <> -void EmitterElementFactory::Enumerate(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - switch (clsId.toUint32()) { - case SBIG('SETR'): - m_elem.reset(new struct EESimpleEmitterTR); - break; - case SBIG('SEMR'): - m_elem.reset(new struct EESimpleEmitter); - break; - case SBIG('SPHE'): - m_elem.reset(new struct VESphere); - break; - case SBIG('ASPH'): - m_elem.reset(new struct VEAngleSphere); - break; - case SBIG('NONE'): - m_elem.reset(); - return; - default: - m_elem.reset(); - LogModule.report(logvisor::Fatal, fmt("Unknown EmitterElement class {} @{}"), clsId, r.position()); - return; - } - m_elem->read(r); -} - -template <> -void EmitterElementFactory::Enumerate(typename Write::StreamT& w) { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} - template <> void BoolHelper::Enumerate(typename ReadYaml::StreamT& r) { value = r.readBool(); @@ -1073,14 +189,20 @@ void BoolHelper::Enumerate(typename Read::StreamT& r) { } template <> void BoolHelper::Enumerate(typename Write::StreamT& w) { - w.writeBytes((atInt8*)"CNST", 4); + w.writeBytes("CNST", 4); w.writeBool(value); } +template struct ValueHelper; +template struct ValueHelper; + +AT_SUBSPECIALIZE_DNA_YAML(ValueHelper) +AT_SUBSPECIALIZE_DNA_YAML(ValueHelper) + template <> void EESimpleEmitterTR::Enumerate(typename ReadYaml::StreamT& r) { - position.m_elem.reset(); - velocity.m_elem.reset(); + position.reset(); + velocity.reset(); if (auto rec = r.enterSubRecord("ILOC")) position.read(r); if (auto rec = r.enterSubRecord("IVEC")) @@ -1101,8 +223,8 @@ void EESimpleEmitterTR::Enumerate(typename BinarySize::Strea } template <> void EESimpleEmitterTR::Enumerate(typename Read::StreamT& r) { - position.m_elem.reset(); - velocity.m_elem.reset(); + position.reset(); + velocity.reset(); uint32_t clsId; r.readBytesToBuf(&clsId, 4); if (clsId == SBIG('ILOC')) { @@ -1114,9 +236,9 @@ void EESimpleEmitterTR::Enumerate(typename Read::StreamT& r) { } template <> void EESimpleEmitterTR::Enumerate(typename Write::StreamT& w) { - w.writeBytes((atInt8*)"ILOC", 4); + w.writeBytes("ILOC", 4); position.write(w); - w.writeBytes((atInt8*)"IVEC", 4); + w.writeBytes("IVEC", 4); velocity.write(w); } @@ -1155,7 +277,7 @@ void UVEConstant::_read(typename Read::StreamT& r) { } template void UVEConstant::_write(typename Write::StreamT& w) const { - w.writeBytes((atInt8*)"CNST", 4); + w.writeBytes("CNST", 4); tex.write(w); } @@ -1236,14 +358,14 @@ void UVEAnimTexture::_read(typename Read::StreamT& r) { } template void UVEAnimTexture::_write(typename Write::StreamT& w) const { - w.writeBytes((atInt8*)"CNST", 4); + w.writeBytes("CNST", 4); tex.write(w); tileW.write(w); tileH.write(w); strideW.write(w); strideH.write(w); cycleFrames.write(w); - w.writeBytes((atInt8*)"CNST", 4); + w.writeBytes("CNST", 4); w.writeBool(loop); } @@ -1262,61 +384,6 @@ std::string_view UVElementFactory::DNAType() { return "UVElementFactory"sv; } -template -void UVElementFactory::_read(typename Read::StreamT& r) { - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - switch (clsId) { - case SBIG('CNST'): - m_elem.reset(new struct UVEConstant); - break; - case SBIG('ATEX'): - m_elem.reset(new struct UVEAnimTexture); - break; - default: - m_elem.reset(); - return; - } - m_elem->read(r); -} -template -void UVElementFactory::_write(typename Write::StreamT& w) const { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} -template -void UVElementFactory::_read(typename ReadYaml::StreamT& r) { - if (auto rec = r.enterSubRecord("CNST")) { - m_elem.reset(new struct UVEConstant); - m_elem->read(r); - } else if (auto rec = r.enterSubRecord("ATEX")) { - m_elem.reset(new struct UVEAnimTexture); - m_elem->read(r); - } else - m_elem.reset(); -} -template -void UVElementFactory::_write(typename WriteYaml::StreamT& w) const { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} -template -void UVElementFactory::_binarySize(typename BinarySize::StreamT& _s) const { - if (m_elem) - m_elem->binarySize(_s); - _s += 4; -} - -AT_SUBSPECIALIZE_DNA_YAML(UVElementFactory) -AT_SUBSPECIALIZE_DNA_YAML(UVElementFactory) - -template struct UVElementFactory; -template struct UVElementFactory; - template <> std::string_view SpawnSystemKeyframeData::SpawnSystemKeyframeInfo::DNAType() { return "SpawnSystemKeyframeData::SpawnSystemKeyframeInfo"sv; @@ -1439,10 +506,10 @@ void SpawnSystemKeyframeData::_read(typename Read::StreamT& r) { template void SpawnSystemKeyframeData::_write(typename Write::StreamT& w) const { if (spawns.empty()) { - w.writeBytes((atInt8*)"NONE", 4); + w.writeBytes("NONE", 4); return; } - w.writeBytes((atInt8*)"CNST", 4); + w.writeBytes("CNST", 4); w.writeUint32Big(a); w.writeUint32Big(b); w.writeUint32Big(endFrame); @@ -1504,10 +571,10 @@ void ChildResourceFactory::_read(typename Read::StreamT& r) { template void ChildResourceFactory::_write(typename Write::StreamT& w) const { if (id.isValid()) { - w.writeBytes((atInt8*)"CNST", 4); + w.writeBytes("CNST", 4); id.write(w); } else - w.writeBytes((atInt8*)"NONE", 4); + w.writeBytes("NONE", 4); } AT_SUBSPECIALIZE_DNA_YAML(ChildResourceFactory) diff --git a/DataSpec/DNACommon/ParticleCommon.hpp b/DataSpec/DNACommon/ParticleCommon.hpp index 803a02f41..159cc85fd 100644 --- a/DataSpec/DNACommon/ParticleCommon.hpp +++ b/DataSpec/DNACommon/ParticleCommon.hpp @@ -10,6 +10,257 @@ namespace DataSpec::DNAParticle { extern logvisor::Module LogModule; +enum class ParticleType { + GPSM = SBIG('GPSM'), + SWSH = SBIG('SWSH'), + ELSM = SBIG('ELSM'), + DPSM = SBIG('DPSM'), + CRSM = SBIG('CRSM'), + WPSM = SBIG('WPSM') +}; + +/* + * The particle property (PP) metaclass system provides common compile-time utilities + * for storing, enumerating, and streaming particle scripts. + */ + +template +struct PPImpl : BigDNA, _Basis { + AT_DECL_EXPLICIT_DNA_YAML + + template + static constexpr bool _shouldStore(T& p, bool defaultBool) { + if constexpr (std::is_same_v) { + return p != defaultBool; + } else if constexpr (std::is_same_v) { + return p != 0xffffffff; + } else if constexpr (std::is_same_v) { + return true; + } else { + return p.operator bool(); + } + } + + constexpr void _read(athena::io::IStreamReader& r) { + constexpr FourCC RefType = uint32_t(_Basis::Type); + DNAFourCC clsId(r); + if (clsId != RefType) { + LogModule.report(logvisor::Warning, fmt("non {} provided to {} parser"), RefType, RefType); + return; + } + clsId.read(r); + while (clsId != SBIG('_END')) { + if (!_Basis::Lookup(clsId, [&](auto& p) { + using Tp = std::decay_t; + if constexpr (std::is_same_v) { + DNAFourCC tp(r); + if (tp == SBIG('CNST')) + p = r.readBool(); + } else if constexpr (std::is_same_v) { + DNAFourCC tp(r); + if (tp == SBIG('CNST')) + p = r.readUint32Big(); + } else if constexpr (std::is_same_v) { + DNAFourCC tp(r); + if (tp == SBIG('CNST')) + p = r.readFloatBig(); + } else { + p.read(r); + } + })) { + LogModule.report(logvisor::Fatal, fmt("Unknown {} class {} @{}"), RefType, clsId, r.position()); + } + clsId.read(r); + } + } + + constexpr void _write(athena::io::IStreamWriter& w) { + constexpr DNAFourCC RefType = uint32_t(_Basis::Type); + RefType.write(w); + _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { + if (_shouldStore(p, defaultBool)) { + using Tp = std::decay_t; + DNAFourCC(fcc).write(w); + if constexpr (std::is_same_v) { + w.writeBytes("CNST", 4); + w.writeBool(p); + } else if constexpr (std::is_same_v) { + w.writeBytes("CNST", 4); + w.writeUint32Big(p); + } else if constexpr (std::is_same_v) { + w.writeBytes("CNST", 4); + w.writeFloatBig(p); + } else { + p.write(w); + } + } + }); + w.writeBytes("_END", 4); + } + + constexpr void _binarySize(std::size_t& s) { + constexpr DNAFourCC RefType = uint32_t(_Basis::Type); + RefType.binarySize(s); + _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { + if (_shouldStore(p, defaultBool)) { + using Tp = std::decay_t; + DNAFourCC(fcc).binarySize(s); + if constexpr (std::is_same_v) { + s += 5; + } else if constexpr (std::is_same_v || std::is_same_v) { + s += 8; + } else { + p.binarySize(s); + } + } + }); + s += 4; + } + + void _read(athena::io::YAMLDocReader& r) { + constexpr DNAFourCC RefType = uint32_t(_Basis::Type); + + for (const auto& [key, value] : r.getCurNode()->m_mapChildren) { + if (key == "DNAType"sv) + continue; + if (key.size() < 4) { + LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), key); + continue; + } + + if (auto rec = r.enterSubRecord(key)) { + const DNAFourCC clsId = key.c_str(); + if (!_Basis::Lookup(clsId, [&](auto& p) { + using Tp = std::decay_t; + if constexpr (std::is_same_v) { + p = r.readBool(); + } else if constexpr (std::is_same_v) { + p = r.readUint32(); + } else if constexpr (std::is_same_v) { + p = r.readFloat(); + } else { + p.read(r); + } + })) { + LogModule.report(logvisor::Fatal, fmt("Unknown {} class {}"), RefType, clsId); + } + } + } + } + + constexpr void _write(athena::io::YAMLDocWriter& w) { + _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { + if (_shouldStore(p, defaultBool)) { + using Tp = std::decay_t; + if (auto rec = w.enterSubRecord(fcc.toStringView())) { + if constexpr (std::is_same_v) { + w.writeBool(p); + } else if constexpr (std::is_same_v) { + w.writeUint32(p); + } else if constexpr (std::is_same_v) { + w.writeFloat(p); + } else { + p.write(w); + } + } + } + }); + } + + constexpr void gatherDependencies(std::vector& deps) { + _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { + using Tp = std::decay_t; + if constexpr (!std::is_same_v && !std::is_same_v && !std::is_same_v) + p.gatherDependencies(deps); + }); + } + + constexpr void gatherDependencies(std::vector& deps) const { + const_cast(*this).gatherDependencies(deps); + } +}; + +template +struct PEType { + using Type = _Type; +}; + +template +struct PEImpl : BigDNA { + AT_DECL_EXPLICIT_DNA_YAML + using _PtrType = typename _Basis::PtrType; + + void _read(athena::io::IStreamReader& r) { + DNAFourCC clsId(r); + if (clsId == FOURCC('NONE')) { + m_elem.reset(); + return; + } + if (!_Basis::Lookup(clsId, [&](auto&& p) { + using Tp = std::decay_t; + m_elem = std::make_unique(); + m_elem->read(r); + })) { + LogModule.report(logvisor::Fatal, fmt("Unknown {} class {} @{}"), _PtrType::TypeName, clsId, r.position()); + } + } + + void _write(athena::io::IStreamWriter& w) { + if (m_elem) { + w.writeBytes(m_elem->ClassID().data(), 4); + m_elem->write(w); + } else { + w.writeBytes("NONE", 4); + } + } + + void _binarySize(std::size_t& s) { + if (m_elem) + m_elem->binarySize(s); + s += 4; + } + + void _read(athena::io::YAMLDocReader& r) { + const auto& mapChildren = r.getCurNode()->m_mapChildren; + if (mapChildren.empty()) { + m_elem.reset(); + return; + } + + const auto& [key, value] = mapChildren[0]; + if (key.size() < 4) + LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), key); + + if (auto rec = r.enterSubRecord(key)) { + const DNAFourCC clsId = key.c_str(); + if (!_Basis::Lookup(clsId, [&](auto&& p) { + using Tp = std::decay_t; + m_elem = std::make_unique(); + m_elem->read(r); + })) { + LogModule.report(logvisor::Fatal, fmt("Unknown {} class {}"), _PtrType::TypeName, clsId); + } + } + } + + void _write(athena::io::YAMLDocWriter& w) { + if (m_elem) + if (auto rec = w.enterSubRecord(m_elem->ClassID())) + m_elem->write(w); + } + + void gatherDependencies(std::vector& deps) const { + _Basis::gatherDependencies(deps, m_elem); + } + + operator bool() const { return m_elem.operator bool(); } + auto* get() const { return m_elem.get(); } + auto* operator->() const { return get(); } + void reset() { m_elem.reset(); } +private: + std::unique_ptr<_PtrType> m_elem; +}; + struct IElement : BigDNAVYaml { Delete _d; ~IElement() override = default; @@ -19,61 +270,296 @@ struct IElement : BigDNAVYaml { struct IRealElement : IElement { Delete _d2; + static constexpr std::string_view TypeName = "RealElement"sv; }; -struct RealElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct RELifetimeTween; +struct REConstant; +struct RETimeChain; +struct REAdd; +struct REClamp; +struct REKeyframeEmitter; +struct REKeyframeEmitter; +struct REInitialRandom; +struct RERandom; +struct REMultiply; +struct REPulse; +struct RETimeScale; +struct RELifetimePercent; +struct RESineWave; +struct REInitialSwitch; +struct RECompareLessThan; +struct RECompareEquals; +struct REParticleAdvanceParam1; +struct REParticleAdvanceParam2; +struct REParticleAdvanceParam3; +struct REParticleAdvanceParam4; +struct REParticleAdvanceParam5; +struct REParticleAdvanceParam6; +struct REParticleAdvanceParam7; +struct REParticleAdvanceParam8; +struct REParticleSizeOrLineLength; +struct REParticleRotationOrLineWidth; +struct RESubtract; +struct REVectorMagnitude; +struct REVectorXToReal; +struct REVectorYToReal; +struct REVectorZToReal; +struct RECEXT; +struct REIntTimesReal; +struct _RealElementFactory { + using PtrType = IRealElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('LFTW'): f(PEType{}); return true; + case SBIG('CNST'): f(PEType{}); return true; + case SBIG('CHAN'): f(PEType{}); return true; + case SBIG('ADD_'): f(PEType{}); return true; + case SBIG('CLMP'): f(PEType{}); return true; + case SBIG('KEYE'): f(PEType{}); return true; + case SBIG('KEYP'): f(PEType{}); return true; + case SBIG('IRND'): f(PEType{}); return true; + case SBIG('RAND'): f(PEType{}); return true; + case SBIG('MULT'): f(PEType{}); return true; + case SBIG('PULS'): f(PEType{}); return true; + case SBIG('SCAL'): f(PEType{}); return true; + case SBIG('RLPT'): f(PEType{}); return true; + case SBIG('SINE'): f(PEType{}); return true; + case SBIG('ISWT'): f(PEType{}); return true; + case SBIG('CLTN'): f(PEType{}); return true; + case SBIG('CEQL'): f(PEType{}); return true; + case SBIG('PAP1'): f(PEType{}); return true; + case SBIG('PAP2'): f(PEType{}); return true; + case SBIG('PAP3'): f(PEType{}); return true; + case SBIG('PAP4'): f(PEType{}); return true; + case SBIG('PAP5'): f(PEType{}); return true; + case SBIG('PAP6'): f(PEType{}); return true; + case SBIG('PAP7'): f(PEType{}); return true; + case SBIG('PAP8'): f(PEType{}); return true; + case SBIG('PSLL'): f(PEType{}); return true; + case SBIG('PRLW'): f(PEType{}); return true; + case SBIG('SUB_'): f(PEType{}); return true; + case SBIG('VMAG'): f(PEType{}); return true; + case SBIG('VXTR'): f(PEType{}); return true; + case SBIG('VYTR'): f(PEType{}); return true; + case SBIG('VZTR'): f(PEType{}); return true; + case SBIG('CEXT'): f(PEType{}); return true; + case SBIG('ITRL'): f(PEType{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) {} }; +using RealElementFactory = PEImpl<_RealElementFactory>; struct IIntElement : IElement { Delete _d2; + static constexpr std::string_view TypeName = "IntElement"sv; }; -struct IntElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct IEKeyframeEmitter; +struct IEKeyframeEmitter; +struct IEDeath; +struct IEClamp; +struct IETimeChain; +struct IEAdd; +struct IEConstant; +struct IEImpulse; +struct IELifetimePercent; +struct IEInitialRandom; +struct IEPulse; +struct IEMultiply; +struct IESampleAndHold; +struct IERandom; +struct IETimeScale; +struct IEGTCP; +struct IEModulo; +struct IESubtract; +struct _IntElementFactory { + using PtrType = IIntElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('KEYE'): f(PEType{}); return true; + case SBIG('KEYP'): f(PEType{}); return true; + case SBIG('DETH'): f(PEType{}); return true; + case SBIG('CLMP'): f(PEType{}); return true; + case SBIG('CHAN'): f(PEType{}); return true; + case SBIG('ADD_'): f(PEType{}); return true; + case SBIG('CNST'): f(PEType{}); return true; + case SBIG('IMPL'): f(PEType{}); return true; + case SBIG('ILPT'): f(PEType{}); return true; + case SBIG('IRND'): f(PEType{}); return true; + case SBIG('PULS'): f(PEType{}); return true; + case SBIG('MULT'): f(PEType{}); return true; + case SBIG('SPAH'): f(PEType{}); return true; + case SBIG('RAND'): f(PEType{}); return true; + case SBIG('TSCL'): f(PEType{}); return true; + case SBIG('GTCP'): f(PEType{}); return true; + case SBIG('MODU'): f(PEType{}); return true; + case SBIG('SUB_'): f(PEType{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) {} }; +using IntElementFactory = PEImpl<_IntElementFactory>; struct IVectorElement : IElement { Delete _d2; + static constexpr std::string_view TypeName = "VectorElement"sv; }; -struct VectorElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct VECone; +struct VETimeChain; +struct VEAngleCone; +struct VEAdd; +struct VECircleCluster; +struct VEConstant; +struct VECircle; +struct VEKeyframeEmitter; +struct VEKeyframeEmitter; +struct VEMultiply; +struct VERealToVector; +struct VEPulse; +struct VEParticleVelocity; +struct VESPOS; +struct VEPLCO; +struct VEPLOC; +struct VEPSOR; +struct VEPSOF; +struct _VectorElementFactory { + using PtrType = IVectorElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('CONE'): f(PEType{}); return true; + case SBIG('CHAN'): f(PEType{}); return true; + case SBIG('ANGC'): f(PEType{}); return true; + case SBIG('ADD_'): f(PEType{}); return true; + case SBIG('CCLU'): f(PEType{}); return true; + case SBIG('CNST'): f(PEType{}); return true; + case SBIG('CIRC'): f(PEType{}); return true; + case SBIG('KEYE'): f(PEType{}); return true; + case SBIG('KEYP'): f(PEType{}); return true; + case SBIG('MULT'): f(PEType{}); return true; + case SBIG('RTOV'): f(PEType{}); return true; + case SBIG('PULS'): f(PEType{}); return true; + case SBIG('PVEL'): f(PEType{}); return true; + case SBIG('SPOS'): f(PEType{}); return true; + case SBIG('PLCO'): f(PEType{}); return true; + case SBIG('PLOC'): f(PEType{}); return true; + case SBIG('PSOR'): f(PEType{}); return true; + case SBIG('PSOF'): f(PEType{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) {} }; +using VectorElementFactory = PEImpl<_VectorElementFactory>; struct IColorElement : IElement { Delete _d2; + static constexpr std::string_view TypeName = "ColorElement"sv; }; -struct ColorElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct CEKeyframeEmitter; +struct CEKeyframeEmitter; +struct CEConstant; +struct CETimeChain; +struct CEFadeEnd; +struct CEFade; +struct CEPulse; +struct _ColorElementFactory { + using PtrType = IColorElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('KEYE'): f(PEType{}); return true; + case SBIG('KEYP'): f(PEType{}); return true; + case SBIG('CNST'): f(PEType{}); return true; + case SBIG('CHAN'): f(PEType{}); return true; + case SBIG('CFDE'): f(PEType{}); return true; + case SBIG('FADE'): f(PEType{}); return true; + case SBIG('PULS'): f(PEType{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) {} }; +using ColorElementFactory = PEImpl<_ColorElementFactory>; struct IModVectorElement : IElement { Delete _d2; + static constexpr std::string_view TypeName = "ModVectorElement"sv; }; -struct ModVectorElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct MVEImplosion; +struct MVEExponentialImplosion; +struct MVETimeChain; +struct MVEBounce; +struct MVEConstant; +struct MVEGravity; +struct MVEExplode; +struct MVESetPosition; +struct MVELinearImplosion; +struct MVEPulse; +struct MVEWind; +struct MVESwirl; +struct _ModVectorElementFactory { + using PtrType = IModVectorElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('IMPL'): f(PEType{}); return true; + case SBIG('EMPL'): f(PEType{}); return true; + case SBIG('CHAN'): f(PEType{}); return true; + case SBIG('BNCE'): f(PEType{}); return true; + case SBIG('CNST'): f(PEType{}); return true; + case SBIG('GRAV'): f(PEType{}); return true; + case SBIG('EXPL'): f(PEType{}); return true; + case SBIG('SPOS'): f(PEType{}); return true; + case SBIG('LMPL'): f(PEType{}); return true; + case SBIG('PULS'): f(PEType{}); return true; + case SBIG('WIND'): f(PEType{}); return true; + case SBIG('SWRL'): f(PEType{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) {} }; +using ModVectorElementFactory = PEImpl<_ModVectorElementFactory>; struct IEmitterElement : IElement { Delete _d2; + static constexpr std::string_view TypeName = "EmitterElement"sv; }; -struct EmitterElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct EESimpleEmitterTR; +struct EESimpleEmitter; +struct VESphere; +struct VEAngleSphere; +struct _EmitterElementFactory { + using PtrType = IEmitterElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('SETR'): f(PEType{}); return true; + case SBIG('SEMR'): f(PEType{}); return true; + case SBIG('SPHE'): f(PEType{}); return true; + case SBIG('ASPH'): f(PEType{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) {} }; +using EmitterElementFactory = PEImpl<_EmitterElementFactory>; struct IUVElement : IElement { Delete _d2; virtual void gatherDependencies(std::vector& pathsOut) const = 0; + static constexpr std::string_view TypeName = "UVElement"sv; }; struct BoolHelper : IElement { @@ -87,6 +573,46 @@ struct BoolHelper : IElement { std::string_view ClassID() const override { return "BoolHelper"sv; } }; +template +struct ValueHelper : BigDNA { + AT_DECL_EXPLICIT_DNA_YAML + + void _read(athena::io::IStreamReader& r) { + hecl::DNAFourCC ValueType; + ValueType.read(r); + if (ValueType == FOURCC('CNST')) + athena::io::Read::Do({}, value.emplace(), r); + else + value = std::nullopt; + } + void _write(athena::io::IStreamWriter& w) { + if (value) { + w.writeBytes("CNST", 4); + athena::io::Write::Do({}, *value, w); + } else { + w.writeBytes("NONE", 4); + } + } + void _binarySize(std::size_t& s) { + s += 4; + if (value) + athena::io::BinarySize::Do({}, *value, s); + } + void _read(athena::io::YAMLDocReader& r) { + athena::io::ReadYaml::Do({}, value.emplace(), r); + } + void _write(athena::io::YAMLDocWriter& w) { + athena::io::WriteYaml::Do({}, *value, w); + } + + static constexpr void gatherDependencies(std::vector& pathsOut) {} + + std::optional value = {}; + void emplace(Tp val) { value.emplace(val); } + Tp operator*() const { return *value; } + operator bool() const { return value.operator bool(); } +}; + struct RELifetimeTween : IRealElement { AT_DECL_DNA_YAMLV_NO_TYPE RealElementFactory a; @@ -743,7 +1269,8 @@ struct UVEConstant : IUVElement { std::string_view ClassID() const override { return "CNST"sv; } void gatherDependencies(std::vector& pathsOut) const override { - g_curSpec->flattenDependencies(tex, pathsOut); + if (tex.isValid()) + g_curSpec->flattenDependencies(tex, pathsOut); } }; @@ -761,18 +1288,30 @@ struct UVEAnimTexture : IUVElement { std::string_view ClassID() const override { return "ATEX"sv; } void gatherDependencies(std::vector& pathsOut) const override { - g_curSpec->flattenDependencies(tex, pathsOut); + if (tex.isValid()) + g_curSpec->flattenDependencies(tex, pathsOut); } }; template -struct UVElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - DNAFourCC m_type; - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct _UVElementFactory { + using PtrType = IUVElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('CNST'): f(PEType>{}); return true; + case SBIG('ATEX'): f(PEType>{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) { + if (elemPtr) + elemPtr->gatherDependencies(pathsOut); + } }; +template +using UVElementFactory = PEImpl<_UVElementFactory>; template struct SpawnSystemKeyframeData : BigDNA { @@ -809,6 +1348,10 @@ struct ChildResourceFactory : BigDNA { AT_DECL_EXPLICIT_DNA_YAML AT_SUBDECL_DNA operator bool() const { return id.isValid(); } + void gatherDependencies(std::vector& pathsOut) const { + if (id.isValid()) + g_curSpec->flattenDependencies(id, pathsOut); + } }; } // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/SWHC.cpp b/DataSpec/DNACommon/SWHC.cpp index 3ff2b8ebd..404de21af 100644 --- a/DataSpec/DNACommon/SWHC.cpp +++ b/DataSpec/DNACommon/SWHC.cpp @@ -1,11 +1,14 @@ #include "DataSpec/DNACommon/SWHC.hpp" - #include "DataSpec/DNACommon/PAK.hpp" -#include - namespace DataSpec::DNAParticle { +template struct PPImpl<_SWSH>; +template struct PPImpl<_SWSH>; + +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_SWSH>) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_SWSH>) + template <> std::string_view SWSH::DNAType() { return "SWSH"sv; @@ -16,504 +19,6 @@ std::string_view SWSH::DNAType() { return "SWSH"sv; } -template -void SWSH::_read(typename BigDNA::ReadYaml::StreamT& r) { - for (const auto& elem : r.getCurNode()->m_mapChildren) { - if (elem.first.size() < 4) { - LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), elem.first); - continue; - } - - if (auto rec = r.enterSubRecord(elem.first.c_str())) { - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('PSLT'): - x0_PSLT.read(r); - break; - case SBIG('TIME'): - x4_TIME.read(r); - break; - case SBIG('LRAD'): - x8_LRAD.read(r); - break; - case SBIG('RRAD'): - xc_RRAD.read(r); - break; - case SBIG('LENG'): - x10_LENG.read(r); - break; - case SBIG('COLR'): - x14_COLR.read(r); - break; - case SBIG('SIDE'): - x18_SIDE.read(r); - break; - case SBIG('IROT'): - x1c_IROT.read(r); - break; - case SBIG('ROTM'): - x20_ROTM.read(r); - break; - case SBIG('POFS'): - x24_POFS.read(r); - break; - case SBIG('IVEL'): - x28_IVEL.read(r); - break; - case SBIG('NPOS'): - x2c_NPOS.read(r); - break; - case SBIG('VELM'): - x30_VELM.read(r); - break; - case SBIG('VLM2'): - x34_VLM2.read(r); - break; - case SBIG('SPLN'): - x38_SPLN.read(r); - break; - case SBIG('TEXR'): - x3c_TEXR.read(r); - break; - case SBIG('TSPN'): - x40_TSPN.read(r); - break; - case SBIG('LLRD'): - x44_24_LLRD = r.readBool(); - break; - case SBIG('CROS'): - x44_25_CROS = r.readBool(); - break; - case SBIG('VLS1'): - x44_26_VLS1 = r.readBool(); - break; - case SBIG('VLS2'): - x44_27_VLS2 = r.readBool(); - break; - case SBIG('SROT'): - x44_28_SROT = r.readBool(); - break; - case SBIG('WIRE'): - x44_29_WIRE = r.readBool(); - break; - case SBIG('TEXW'): - x44_30_TEXW = r.readBool(); - break; - case SBIG('AALP'): - x44_31_AALP = r.readBool(); - break; - case SBIG('ZBUF'): - x45_24_ZBUF = r.readBool(); - break; - case SBIG('ORNT'): - x45_25_ORNT = r.readBool(); - break; - case SBIG('CRND'): - x45_26_CRND = r.readBool(); - break; - default: - break; - } - } - } -} - -template -void SWSH::_write(typename BigDNA::WriteYaml::StreamT& w) const { - if (x0_PSLT) - if (auto rec = w.enterSubRecord("PSLT")) - x0_PSLT.write(w); - if (x4_TIME) - if (auto rec = w.enterSubRecord("TIME")) - x4_TIME.write(w); - if (x8_LRAD) - if (auto rec = w.enterSubRecord("LRAD")) - x8_LRAD.write(w); - if (xc_RRAD) - if (auto rec = w.enterSubRecord("RRAD")) - xc_RRAD.write(w); - if (x10_LENG) - if (auto rec = w.enterSubRecord("LENG")) - x10_LENG.write(w); - if (x14_COLR) - if (auto rec = w.enterSubRecord("COLR")) - x14_COLR.write(w); - if (x18_SIDE) - if (auto rec = w.enterSubRecord("SIDE")) - x18_SIDE.write(w); - if (x1c_IROT) - if (auto rec = w.enterSubRecord("IROT")) - x1c_IROT.write(w); - if (x20_ROTM) - if (auto rec = w.enterSubRecord("ROTM")) - x20_ROTM.write(w); - if (x24_POFS) - if (auto rec = w.enterSubRecord("POFS")) - x24_POFS.write(w); - if (x28_IVEL) - if (auto rec = w.enterSubRecord("IVEL")) - x28_IVEL.write(w); - if (x2c_NPOS) - if (auto rec = w.enterSubRecord("NPOS")) - x2c_NPOS.write(w); - if (x30_VELM) - if (auto rec = w.enterSubRecord("VELM")) - x30_VELM.write(w); - if (x34_VLM2) - if (auto rec = w.enterSubRecord("VLM2")) - x34_VLM2.write(w); - if (x38_SPLN) - if (auto rec = w.enterSubRecord("SPLN")) - x38_SPLN.write(w); - if (x3c_TEXR) - if (auto rec = w.enterSubRecord("TEXR")) - x3c_TEXR.write(w); - if (x40_TSPN) - if (auto rec = w.enterSubRecord("TSPN")) - x40_TSPN.write(w); - - if (x44_24_LLRD) - w.writeBool("LLRD", true); - if (!x44_25_CROS) - w.writeBool("CROS", false); - if (x44_26_VLS1) - w.writeBool("VLS1", true); - if (x44_27_VLS2) - w.writeBool("VLS2", true); - if (x44_28_SROT) - w.writeBool("SROT", true); - if (x44_29_WIRE) - w.writeBool("WIRE", true); - if (x44_30_TEXW) - w.writeBool("TEXW", true); - if (x44_31_AALP) - w.writeBool("AALP", true); - if (x45_24_ZBUF) - w.writeBool("ZBUF", true); - if (x45_25_ORNT) - w.writeBool("ORNT", true); - if (x45_26_CRND) - w.writeBool("CRND", true); -} - -template -void SWSH::_binarySize(typename BigDNA::BinarySize::StreamT& s) const { - s += 4; - if (x0_PSLT) { - s += 4; - x0_PSLT.binarySize(s); - } - if (x4_TIME) { - s += 4; - x4_TIME.binarySize(s); - } - if (x8_LRAD) { - s += 4; - x8_LRAD.binarySize(s); - } - if (xc_RRAD) { - s += 4; - xc_RRAD.binarySize(s); - } - if (x10_LENG) { - s += 4; - x10_LENG.binarySize(s); - } - if (x14_COLR) { - s += 4; - x14_COLR.binarySize(s); - } - if (x18_SIDE) { - s += 4; - x18_SIDE.binarySize(s); - } - if (x1c_IROT) { - s += 4; - x1c_IROT.binarySize(s); - } - if (x20_ROTM) { - s += 4; - x20_ROTM.binarySize(s); - } - if (x24_POFS) { - s += 4; - x24_POFS.binarySize(s); - } - if (x28_IVEL) { - s += 4; - x28_IVEL.binarySize(s); - } - if (x2c_NPOS) { - s += 4; - x2c_NPOS.binarySize(s); - } - if (x30_VELM) { - s += 4; - x30_VELM.binarySize(s); - } - if (x34_VLM2) { - s += 4; - x34_VLM2.binarySize(s); - } - if (x38_SPLN) { - s += 4; - x38_SPLN.binarySize(s); - } - if (x3c_TEXR) { - s += 4; - x3c_TEXR.binarySize(s); - } - if (x40_TSPN) { - s += 4; - x40_TSPN.binarySize(s); - } - if (x44_24_LLRD) - s += 9; - if (!x44_25_CROS) - s += 9; - if (x44_26_VLS1) - s += 9; - if (x44_27_VLS2) - s += 9; - if (x44_28_SROT) - s += 9; - if (x44_29_WIRE) - s += 9; - if (x44_30_TEXW) - s += 9; - if (x44_31_AALP) - s += 9; - if (x45_24_ZBUF) - s += 9; - if (x45_25_ORNT) - s += 9; - if (x45_26_CRND) - s += 9; -} - -template -void SWSH::_read(typename BigDNA::Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - if (clsId != SBIG('SWSH')) { - LogModule.report(logvisor::Warning, fmt("non SWSH provided to SWSH parser")); - return; - } - - clsId.read(r); - while (clsId != SBIG('_END')) { - switch (clsId.toUint32()) { - case SBIG('PSLT'): - x0_PSLT.read(r); - break; - case SBIG('TIME'): - x4_TIME.read(r); - break; - case SBIG('LRAD'): - x8_LRAD.read(r); - break; - case SBIG('RRAD'): - xc_RRAD.read(r); - break; - case SBIG('LENG'): - x10_LENG.read(r); - break; - case SBIG('COLR'): - x14_COLR.read(r); - break; - case SBIG('SIDE'): - x18_SIDE.read(r); - break; - case SBIG('IROT'): - x1c_IROT.read(r); - break; - case SBIG('ROTM'): - x20_ROTM.read(r); - break; - case SBIG('POFS'): - x24_POFS.read(r); - break; - case SBIG('IVEL'): - x28_IVEL.read(r); - break; - case SBIG('NPOS'): - x2c_NPOS.read(r); - break; - case SBIG('VELM'): - x30_VELM.read(r); - break; - case SBIG('VLM2'): - x34_VLM2.read(r); - break; - case SBIG('SPLN'): - x38_SPLN.read(r); - break; - case SBIG('TEXR'): - x3c_TEXR.read(r); - break; - case SBIG('TSPN'): - x40_TSPN.read(r); - break; - case SBIG('LLRD'): - r.readUint32Big(); - x44_24_LLRD = r.readBool(); - break; - case SBIG('CROS'): - r.readUint32Big(); - x44_25_CROS = r.readBool(); - break; - case SBIG('VLS1'): - r.readUint32Big(); - x44_26_VLS1 = r.readBool(); - break; - case SBIG('VLS2'): - r.readUint32Big(); - x44_27_VLS2 = r.readBool(); - break; - case SBIG('SROT'): - r.readUint32Big(); - x44_28_SROT = r.readBool(); - break; - case SBIG('WIRE'): - r.readUint32Big(); - x44_29_WIRE = r.readBool(); - break; - case SBIG('TEXW'): - r.readUint32Big(); - x44_30_TEXW = r.readBool(); - break; - case SBIG('AALP'): - r.readUint32Big(); - x44_31_AALP = r.readBool(); - break; - case SBIG('ZBUF'): - r.readUint32Big(); - x45_24_ZBUF = r.readBool(); - break; - case SBIG('ORNT'): - r.readUint32Big(); - x45_25_ORNT = r.readBool(); - break; - case SBIG('CRND'): - r.readUint32Big(); - x45_26_CRND = r.readBool(); - break; - default: - LogModule.report(logvisor::Fatal, fmt("Unknown SWSH class {} @{}"), clsId, r.position()); - break; - } - clsId.read(r); - } -} - -template -void SWSH::_write(typename BigDNA::Write::StreamT& w) const { - w.writeBytes((atInt8*)"SWSH", 4); - if (x0_PSLT) { - w.writeBytes((atInt8*)"PSLT", 4); - x0_PSLT.write(w); - } - if (x4_TIME) { - w.writeBytes((atInt8*)"TIME", 4); - x4_TIME.write(w); - } - if (x8_LRAD) { - w.writeBytes((atInt8*)"LRAD", 4); - x8_LRAD.write(w); - } - if (xc_RRAD) { - w.writeBytes((atInt8*)"RRAD", 4); - xc_RRAD.write(w); - } - if (x10_LENG) { - w.writeBytes((atInt8*)"LENG", 4); - x10_LENG.write(w); - } - if (x14_COLR) { - w.writeBytes((atInt8*)"COLR", 4); - x14_COLR.write(w); - } - if (x18_SIDE) { - w.writeBytes((atInt8*)"SIDE", 4); - x18_SIDE.write(w); - } - if (x1c_IROT) { - w.writeBytes((atInt8*)"IROT", 4); - x1c_IROT.write(w); - } - if (x20_ROTM) { - w.writeBytes((atInt8*)"ROTM", 4); - x20_ROTM.write(w); - } - if (x24_POFS) { - w.writeBytes((atInt8*)"POFS", 4); - x24_POFS.write(w); - } - if (x28_IVEL) { - w.writeBytes((atInt8*)"IVEL", 4); - x28_IVEL.write(w); - } - if (x2c_NPOS) { - w.writeBytes((atInt8*)"NPOS", 4); - x2c_NPOS.write(w); - } - if (x30_VELM) { - w.writeBytes((atInt8*)"VELM", 4); - x30_VELM.write(w); - } - if (x34_VLM2) { - w.writeBytes((atInt8*)"VLM2", 4); - x34_VLM2.write(w); - } - if (x38_SPLN) { - w.writeBytes((atInt8*)"SPLN", 4); - x38_SPLN.write(w); - } - if (x3c_TEXR) { - w.writeBytes((atInt8*)"TEXR", 4); - x3c_TEXR.write(w); - } - if (x40_TSPN) { - w.writeBytes((atInt8*)"TSPN", 4); - x40_TSPN.write(w); - } - - if (x44_24_LLRD) - w.writeBytes("LLRDCNST\x01", 9); - if (!x44_25_CROS) - w.writeBytes("CROSCNST\x00", 9); - if (x44_26_VLS1) - w.writeBytes("VLS1CNST\x01", 9); - if (x44_27_VLS2) - w.writeBytes("VLS2CNST\x01", 9); - if (x44_28_SROT) - w.writeBytes("SROTCNST\x01", 9); - if (x44_29_WIRE) - w.writeBytes("WIRECNST\x01", 9); - if (x44_30_TEXW) - w.writeBytes("TEXWCNST\x01", 9); - if (x44_31_AALP) - w.writeBytes("AALPCNST\x01", 9); - if (x45_24_ZBUF) - w.writeBytes("ZBUFCNST\x01", 9); - if (x45_25_ORNT) - w.writeBytes("ORNTCNST\x01", 9); - if (x45_26_CRND) - w.writeBytes("CRNDCNST\x01", 9); - w.writeBytes("_END", 4); -} - -AT_SUBSPECIALIZE_DNA_YAML(SWSH) -AT_SUBSPECIALIZE_DNA_YAML(SWSH) - -template -void SWSH::gatherDependencies(std::vector& pathsOut) const { - if (x3c_TEXR.m_elem) - x3c_TEXR.m_elem->gatherDependencies(pathsOut); -} - -template struct SWSH; -template struct SWSH; - template bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { athena::io::FileWriter writer(outPath.getAbsolutePath()); diff --git a/DataSpec/DNACommon/SWHC.def b/DataSpec/DNACommon/SWHC.def new file mode 100644 index 000000000..675d8b5ec --- /dev/null +++ b/DataSpec/DNACommon/SWHC.def @@ -0,0 +1,69 @@ +#ifndef ENTRY +#define ENTRY(name, identifier) +#endif + +#ifndef INT_ENTRY +#define INT_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef REAL_ENTRY +#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef VECTOR_ENTRY +#define VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef MOD_VECTOR_ENTRY +#define MOD_VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef COLOR_ENTRY +#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef UV_ENTRY +#define UV_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef BOOL_ENTRY +#define BOOL_ENTRY(name, identifier, def) ENTRY(name, identifier) +#endif + +INT_ENTRY('PSLT', x0_PSLT) +REAL_ENTRY('TIME', x4_TIME) +REAL_ENTRY('LRAD', x8_LRAD) +REAL_ENTRY('RRAD', xc_RRAD) +INT_ENTRY('LENG', x10_LENG) +COLOR_ENTRY('COLR', x14_COLR) +INT_ENTRY('SIDE', x18_SIDE) +REAL_ENTRY('IROT', x1c_IROT) +REAL_ENTRY('ROTM', x20_ROTM) +VECTOR_ENTRY('POFS', x24_POFS) +VECTOR_ENTRY('IVEL', x28_IVEL) +VECTOR_ENTRY('NPOS', x2c_NPOS) +MOD_VECTOR_ENTRY('VELM', x30_VELM) +MOD_VECTOR_ENTRY('VLM2', x34_VLM2) +INT_ENTRY('SPLN', x38_SPLN) +UV_ENTRY('TEXR', x3c_TEXR) +INT_ENTRY('TSPN', x40_TSPN) +BOOL_ENTRY('LLRD', x44_24_LLRD, false) +BOOL_ENTRY('CROS', x44_25_CROS, true) +BOOL_ENTRY('VLS1', x44_26_VLS1, false) +BOOL_ENTRY('VLS2', x44_27_VLS2, false) +BOOL_ENTRY('SROT', x44_28_SROT, false) +BOOL_ENTRY('WIRE', x44_29_WIRE, false) +BOOL_ENTRY('TEXW', x44_30_TEXW, false) +BOOL_ENTRY('AALP', x44_31_AALP, false) +BOOL_ENTRY('ZBUF', x45_24_ZBUF, false) +BOOL_ENTRY('ORNT', x45_25_ORNT, false) +BOOL_ENTRY('CRND', x45_26_CRND, false) + +#undef ENTRY +#undef INT_ENTRY +#undef REAL_ENTRY +#undef VECTOR_ENTRY +#undef MOD_VECTOR_ENTRY +#undef COLOR_ENTRY +#undef UV_ENTRY +#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/SWHC.hpp b/DataSpec/DNACommon/SWHC.hpp index 3c81344c0..269828ed2 100644 --- a/DataSpec/DNACommon/SWHC.hpp +++ b/DataSpec/DNACommon/SWHC.hpp @@ -16,48 +16,36 @@ class ProjectPath; namespace DataSpec::DNAParticle { template -struct SWSH : public BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA +struct _SWSH { + static constexpr ParticleType Type = ParticleType::SWSH; - IntElementFactory x0_PSLT; - RealElementFactory x4_TIME; - RealElementFactory x8_LRAD; - RealElementFactory xc_RRAD; - IntElementFactory x10_LENG; - ColorElementFactory x14_COLR; - IntElementFactory x18_SIDE; - RealElementFactory x1c_IROT; - RealElementFactory x20_ROTM; - VectorElementFactory x24_POFS; - VectorElementFactory x28_IVEL; - VectorElementFactory x2c_NPOS; - ModVectorElementFactory x30_VELM; - ModVectorElementFactory x34_VLM2; - IntElementFactory x38_SPLN; - UVElementFactory x3c_TEXR; - IntElementFactory x40_TSPN; - union { - struct { - bool x44_24_LLRD : 1; - bool x44_25_CROS : 1; - bool x44_26_VLS1 : 1; - bool x44_27_VLS2 : 1; - bool x44_28_SROT : 1; - bool x44_29_WIRE : 1; - bool x44_30_TEXW : 1; - bool x44_31_AALP : 1; - bool x45_24_ZBUF : 1; - bool x45_25_ORNT : 1; - bool x45_26_CRND : 1; - }; - uint16_t dummy = 0; - }; +#define INT_ENTRY(name, identifier) IntElementFactory identifier; +#define REAL_ENTRY(name, identifier) RealElementFactory identifier; +#define VECTOR_ENTRY(name, identifier) VectorElementFactory identifier; +#define MOD_VECTOR_ENTRY(name, identifier) ModVectorElementFactory identifier; +#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; +#define UV_ENTRY(name, identifier) UVElementFactory identifier; +#define BOOL_ENTRY(name, identifier, def) bool identifier = def; +#include "SWHC.def" - SWSH() { x44_25_CROS = true; } + template + void constexpr Enumerate(_Func f) { +#define ENTRY(name, identifier) f(FOURCC(name), identifier); +#define BOOL_ENTRY(name, identifier, def) f(FOURCC(name), identifier, def); +#include "SWHC.def" + } - void gatherDependencies(std::vector&) const; + template + bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { +#define ENTRY(name, identifier) case SBIG(name): f(identifier); return true; +#include "SWHC.def" + default: return false; + } + } }; +template +using SWSH = PPImpl<_SWSH>; template bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); diff --git a/DataSpec/DNACommon/TXTR.cpp b/DataSpec/DNACommon/TXTR.cpp index 0923baaa1..413b6f0ba 100644 --- a/DataSpec/DNACommon/TXTR.cpp +++ b/DataSpec/DNACommon/TXTR.cpp @@ -17,9 +17,11 @@ static logvisor::Module Log("libpng"); static int CountBits(uint32_t n) { int ret = 0; - for (int i = 0; i < 32; ++i) - if (((n >> i) & 1) != 0) + for (int i = 0; i < 32; ++i) { + if (((n >> i) & 1) != 0) { ++ret; + } + } return ret; } @@ -28,27 +30,29 @@ static void BoxFilter(const uint8_t* input, unsigned chanCount, unsigned inWidth bool dxt1) { unsigned mipWidth = 1; unsigned mipHeight = 1; - if (inWidth > 1) + if (inWidth > 1) { mipWidth = inWidth / 2; - if (inHeight > 1) + } + if (inHeight > 1) { mipHeight = inHeight / 2; + } - unsigned y, x, c; - for (y = 0; y < mipHeight; ++y) { - unsigned miplineBase = mipWidth * y; - unsigned in1LineBase = inWidth * (y * 2); - unsigned in2LineBase = inWidth * (y * 2 + 1); - for (x = 0; x < mipWidth; ++x) { + for (unsigned y = 0; y < mipHeight; ++y) { + const unsigned miplineBase = mipWidth * y; + const unsigned in1LineBase = inWidth * (y * 2); + const unsigned in2LineBase = inWidth * (y * 2 + 1); + for (unsigned x = 0; x < mipWidth; ++x) { uint8_t* out = &output[(miplineBase + x) * chanCount]; - for (c = 0; c < chanCount; ++c) { + for (unsigned c = 0; c < chanCount; ++c) { uint32_t tmp = 0; tmp += input[(in1LineBase + (x * 2)) * chanCount + c]; tmp += input[(in1LineBase + (x * 2 + 1)) * chanCount + c]; tmp += input[(in2LineBase + (x * 2)) * chanCount + c]; tmp += input[(in2LineBase + (x * 2 + 1)) * chanCount + c]; out[c] = uint8_t(tmp / 4); - if (c == 3 && dxt1) + if (c == 3 && dxt1) { out[c] = uint8_t(out[c] ? 0xff : 0x0); + } } } } @@ -65,52 +69,52 @@ static size_t ComputeMippedTexelCount(unsigned inWidth, unsigned inHeight) { } /* GX uses this upsampling technique to extract full 8-bit range */ -constexpr uint8_t Convert3To8(uint8_t v) { +static constexpr uint8_t Convert3To8(uint8_t v) { /* Swizzle bits: 00000123 -> 12312312 */ return (v << 5) | (v << 2) | (v >> 1); } -constexpr uint8_t Convert8To3(uint8_t v) { return v >> 5; } +static constexpr uint8_t Convert8To3(uint8_t v) { return v >> 5; } -constexpr uint8_t Convert4To8(uint8_t v) { +static constexpr uint8_t Convert4To8(uint8_t v) { /* Swizzle bits: 00001234 -> 12341234 */ return (v << 4) | v; } -constexpr uint8_t Convert8To4(uint8_t v) { return v >> 4; } +static constexpr uint8_t Convert8To4(uint8_t v) { return v >> 4; } -constexpr uint8_t Convert5To8(uint8_t v) { +static constexpr uint8_t Convert5To8(uint8_t v) { /* Swizzle bits: 00012345 -> 12345123 */ return (v << 3) | (v >> 2); } -constexpr uint8_t Convert8To5(uint8_t v) { return v >> 3; } +static constexpr uint8_t Convert8To5(uint8_t v) { return v >> 3; } -constexpr uint8_t Convert6To8(uint8_t v) { +static constexpr uint8_t Convert6To8(uint8_t v) { /* Swizzle bits: 00123456 -> 12345612 */ return (v << 2) | (v >> 4); } -constexpr uint8_t Convert8To6(uint8_t v) { return v >> 2; } +static constexpr uint8_t Convert8To6(uint8_t v) { return v >> 2; } static uint8_t Lookup4BPP(const uint8_t* texels, int width, int x, int y) { - int bwidth = (width + 7) / 8; - int bx = x / 8; - int by = y / 8; - int rx = x % 8; - int ry = y % 8; - int bidx = by * bwidth + bx; + const int bwidth = (width + 7) / 8; + const int bx = x / 8; + const int by = y / 8; + const int rx = x % 8; + const int ry = y % 8; + const int bidx = by * bwidth + bx; const uint8_t* btexels = &texels[32 * bidx]; return btexels[ry * 4 + rx / 2] >> ((rx & 1) ? 0 : 4) & 0xf; } static void Set4BPP(uint8_t* texels, int width, int x, int y, uint8_t val) { - int bwidth = (width + 7) / 8; - int bx = x / 8; - int by = y / 8; - int rx = x % 8; - int ry = y % 8; - int bidx = by * bwidth + bx; + const int bwidth = (width + 7) / 8; + const int bx = x / 8; + const int by = y / 8; + const int rx = x % 8; + const int ry = y % 8; + const int bidx = by * bwidth + bx; uint8_t* btexels = &texels[32 * bidx]; btexels[ry * 4 + rx / 2] |= (val & 0xf) << ((rx & 1) ? 0 : 4); } @@ -127,68 +131,68 @@ static uint8_t Lookup8BPP(const uint8_t* texels, int width, int x, int y) { } static void Set8BPP(uint8_t* texels, int width, int x, int y, uint8_t val) { - int bwidth = (width + 7) / 8; - int bx = x / 8; - int by = y / 4; - int rx = x % 8; - int ry = y % 4; - int bidx = by * bwidth + bx; + const int bwidth = (width + 7) / 8; + const int bx = x / 8; + const int by = y / 4; + const int rx = x % 8; + const int ry = y % 4; + const int bidx = by * bwidth + bx; uint8_t* btexels = &texels[32 * bidx]; btexels[ry * 8 + rx] = val; } static uint16_t Lookup16BPP(const uint8_t* texels, int width, int x, int y) { - int bwidth = (width + 3) / 4; - int bx = x / 4; - int by = y / 4; - int rx = x % 4; - int ry = y % 4; + const int bwidth = (width + 3) / 4; + const int bx = x / 4; + const int by = y / 4; + const int rx = x % 4; + const int ry = y % 4; int bidx = by * bwidth + bx; - const uint16_t* btexels = (uint16_t*)&texels[32 * bidx]; + const uint16_t* btexels = reinterpret_cast(&texels[32 * bidx]); return btexels[ry * 4 + rx]; } static void Set16BPP(uint8_t* texels, int width, int x, int y, uint16_t val) { - int bwidth = (width + 3) / 4; - int bx = x / 4; - int by = y / 4; - int rx = x % 4; - int ry = y % 4; - int bidx = by * bwidth + bx; - uint16_t* btexels = (uint16_t*)&texels[32 * bidx]; + const int bwidth = (width + 3) / 4; + const int bx = x / 4; + const int by = y / 4; + const int rx = x % 4; + const int ry = y % 4; + const int bidx = by * bwidth + bx; + auto* btexels = reinterpret_cast(&texels[32 * bidx]); btexels[ry * 4 + rx] = val; } static void LookupRGBA8(const uint8_t* texels, int width, int x, int y, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) { - int bwidth = (width + 3) / 4; - int bx = x / 4; - int by = y / 4; - int rx = x % 4; - int ry = y % 4; - int bidx = (by * bwidth + bx) * 2; - const uint16_t* artexels = (uint16_t*)&texels[32 * bidx]; - const uint16_t* gbtexels = (uint16_t*)&texels[32 * (bidx + 1)]; - uint16_t ar = hecl::SBig(artexels[ry * 4 + rx]); + const int bwidth = (width + 3) / 4; + const int bx = x / 4; + const int by = y / 4; + const int rx = x % 4; + const int ry = y % 4; + const int bidx = (by * bwidth + bx) * 2; + const auto* artexels = reinterpret_cast(&texels[32 * bidx]); + const auto* gbtexels = reinterpret_cast(&texels[32 * (bidx + 1)]); + const uint16_t ar = hecl::SBig(artexels[ry * 4 + rx]); *a = ar >> 8 & 0xff; *r = ar & 0xff; - uint16_t gb = hecl::SBig(gbtexels[ry * 4 + rx]); + const uint16_t gb = hecl::SBig(gbtexels[ry * 4 + rx]); *g = gb >> 8 & 0xff; *b = gb & 0xff; } static void SetRGBA8(uint8_t* texels, int width, int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - int bwidth = (width + 3) / 4; - int bx = x / 4; - int by = y / 4; - int rx = x % 4; - int ry = y % 4; - int bidx = (by * bwidth + bx) * 2; - uint16_t* artexels = (uint16_t*)&texels[32 * bidx]; - uint16_t* gbtexels = (uint16_t*)&texels[32 * (bidx + 1)]; - uint16_t ar = (a << 8) | r; + const int bwidth = (width + 3) / 4; + const int bx = x / 4; + const int by = y / 4; + const int rx = x % 4; + const int ry = y % 4; + const int bidx = (by * bwidth + bx) * 2; + uint16_t* artexels = reinterpret_cast(&texels[32 * bidx]); + uint16_t* gbtexels = reinterpret_cast(&texels[32 * (bidx + 1)]); + const uint16_t ar = (a << 8) | r; artexels[ry * 4 + rx] = hecl::SBig(ar); - uint16_t gb = (g << 8) | b; + const uint16_t gb = (g << 8) | b; gbtexels[ry * 4 + rx] = hecl::SBig(gb); } @@ -199,8 +203,9 @@ static void DecodeI4(png_structp png, png_infop info, const uint8_t* texels, int std::unique_ptr buf(new uint8_t[width]); // memset(buf.get(), 0, width); for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) + for (int x = 0; x < width; ++x) { buf[x] = Convert4To8(Lookup4BPP(texels, width, x, y)); + } png_write_row(png, buf.get()); } } @@ -223,16 +228,18 @@ static void DecodeI8(png_structp png, png_infop info, const uint8_t* texels, int png_write_info(png, info); std::unique_ptr buf(new uint8_t[width]); for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) + for (int x = 0; x < width; ++x) { buf[x] = Lookup8BPP(texels, width, x, y); + } png_write_row(png, buf.get()); } } static void EncodeI8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) { for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) + for (int x = 0; x < width; ++x) { Set8BPP(texels, width, x, y, rgbaIn[x]); + } rgbaIn += width; } } @@ -244,7 +251,7 @@ static void DecodeIA4(png_structp png, png_infop info, const uint8_t* texels, in std::unique_ptr buf(new uint8_t[width * 2]); for (int y = height - 1; y >= 0; --y) { for (int x = 0; x < width; ++x) { - uint8_t texel = Lookup8BPP(texels, width, x, y); + const uint8_t texel = Lookup8BPP(texels, width, x, y); buf[x * 2 ] = Convert4To8(texel & 0xf); buf[x * 2 + 1] = Convert4To8(texel >> 4 & 0xf); } @@ -274,22 +281,24 @@ static void DecodeIA8(png_structp png, png_infop info, const uint8_t* texels, in png_write_info(png, info); std::unique_ptr buf(new uint16_t[width]); for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) + for (int x = 0; x < width; ++x) { buf[x] = hecl::SBig(Lookup16BPP(texels, width, x, y)); - png_write_row(png, (png_bytep)buf.get()); + } + png_write_row(png, reinterpret_cast(buf.get())); } } static void EncodeIA8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) { for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) - Set16BPP(texels, width, x, y, hecl::SBig(((uint16_t*)rgbaIn)[x])); + for (int x = 0; x < width; ++x) { + Set16BPP(texels, width, x, y, hecl::SBig(reinterpret_cast(rgbaIn)[x])); + } rgbaIn += width * 2; } } static const uint8_t* DecodePalette(png_structp png, png_infop info, int numEntries, const uint8_t* data) { - uint32_t format = hecl::SBig(*(uint32_t*)data); + const auto format = hecl::SBig(*reinterpret_cast(data)); data += 8; png_color cEntries[256]; png_byte aEntries[256]; @@ -306,9 +315,9 @@ static const uint8_t* DecodePalette(png_structp png, png_infop info, int numEntr } case 1: { /* RGB565 */ - const uint16_t* data16 = (uint16_t*)data; + const auto* data16 = reinterpret_cast(data); for (int e = 0; e < numEntries; ++e) { - uint16_t texel = hecl::SBig(data16[e]); + const uint16_t texel = hecl::SBig(data16[e]); cEntries[e].red = Convert5To8(texel >> 11 & 0x1f); cEntries[e].green = Convert6To8(texel >> 5 & 0x3f); cEntries[e].blue = Convert5To8(texel & 0x1f); @@ -317,9 +326,9 @@ static const uint8_t* DecodePalette(png_structp png, png_infop info, int numEntr } case 2: { /* RGB5A3 */ - const uint16_t* data16 = (uint16_t*)data; + const auto* data16 = reinterpret_cast(data); for (int e = 0; e < numEntries; ++e) { - uint16_t texel = hecl::SBig(data16[e]); + const uint16_t texel = hecl::SBig(data16[e]); if (texel & 0x8000) { cEntries[e].red = Convert5To8(texel >> 10 & 0x1f); cEntries[e].green = Convert5To8(texel >> 5 & 0x1f); @@ -336,8 +345,9 @@ static const uint8_t* DecodePalette(png_structp png, png_infop info, int numEntr } } png_set_PLTE(png, info, cEntries, numEntries); - if (format == 0 || format == 2) + if (format == 0 || format == 2) { png_set_tRNS(png, info, aEntries, numEntries, nullptr); + } data += numEntries * 2; return data; } @@ -360,20 +370,21 @@ static uint8_t* EncodePalette(png_structp png, png_infop info, int numEntries, u uint32_t format = 0; /* Default IA8 */ for (int e = 0; e < pngNumEntries; ++e) { - png_colorp ent = &cEntries[e]; + const png_const_colorp ent = &cEntries[e]; if (ent->red != ent->green || ent->red != ent->blue) { - if (pngNumAEntries) + if (pngNumAEntries) { format = 2; /* RGB565 if not greyscale and has alpha */ - else + } else { format = 1; /* RGB565 if not greyscale */ + } break; } } - ((uint32_t*)data)[0] = hecl::SBig(format); + reinterpret_cast(data)[0] = hecl::SBig(format); data += 4; - ((uint16_t*)data)[0] = hecl::SBig(uint16_t(numEntries)); - ((uint16_t*)data)[1] = hecl::SBig(uint16_t(1)); + reinterpret_cast(data)[0] = hecl::SBig(uint16_t(numEntries)); + reinterpret_cast(data)[1] = hecl::SBig(uint16_t(1)); data += 4; switch (format) { @@ -393,7 +404,7 @@ static uint8_t* EncodePalette(png_structp png, png_infop info, int numEntries, u } case 1: { /* RGB565 */ - uint16_t* data16 = (uint16_t*)data; + uint16_t* data16 = reinterpret_cast(data); for (int e = 0; e < numEntries; ++e) { if (e < pngNumEntries) { uint16_t texel = Convert8To5(cEntries[e].red) << 11; @@ -408,11 +419,12 @@ static uint8_t* EncodePalette(png_structp png, png_infop info, int numEntries, u } case 2: { /* RGB5A3 */ - uint16_t* data16 = (uint16_t*)data; + auto* data16 = reinterpret_cast(data); for (int e = 0; e < numEntries; ++e) { uint8_t alpha = 0; - if (e < pngNumAEntries) + if (e < pngNumAEntries) { alpha = aEntries[e]; + } uint16_t texel = 0; if (alpha == 0xff) { @@ -440,7 +452,7 @@ static uint8_t* EncodePalette(png_structp png, png_infop info, int numEntries, u } static const uint8_t* DecodePaletteSPLT(png_structp png, png_infop info, int numEntries, const uint8_t* data) { - uint32_t format = hecl::SBig(*(uint32_t*)data); + const auto format = hecl::SBig(*reinterpret_cast(data)); data += 8; png_sPLT_entry entries[256] = {}; png_sPLT_t GXEntry = {(char*)"GXPalette", 8, entries, numEntries}; @@ -459,9 +471,9 @@ static const uint8_t* DecodePaletteSPLT(png_structp png, png_infop info, int num case 1: { /* RGB565 */ GXEntry.name = (char*)"GX_RGB565"; - const uint16_t* data16 = (uint16_t*)data; + const auto* data16 = reinterpret_cast(data); for (int e = 0; e < numEntries; ++e) { - uint16_t texel = hecl::SBig(data16[e]); + const uint16_t texel = hecl::SBig(data16[e]); entries[e].red = Convert5To8(texel >> 11 & 0x1f); entries[e].green = Convert6To8(texel >> 5 & 0x3f); entries[e].blue = Convert5To8(texel & 0x1f); @@ -472,9 +484,9 @@ static const uint8_t* DecodePaletteSPLT(png_structp png, png_infop info, int num case 2: { /* RGB5A3 */ GXEntry.name = (char*)"GX_RGB5A3"; - const uint16_t* data16 = (uint16_t*)data; + const auto* data16 = reinterpret_cast(data); for (int e = 0; e < numEntries; ++e) { - uint16_t texel = hecl::SBig(data16[e]); + const uint16_t texel = hecl::SBig(data16[e]); if (texel & 0x8000) { entries[e].red = Convert5To8(texel >> 10 & 0x1f); entries[e].green = Convert5To8(texel >> 5 & 0x1f); @@ -497,12 +509,12 @@ static const uint8_t* DecodePaletteSPLT(png_structp png, png_infop info, int num static uint8_t* EncodePaletteSPLT(png_structp png, png_infop info, int numEntries, uint8_t* data) { png_sPLT_tp palettes; - int pngNumPalettes = png_get_sPLT(png, info, &palettes); + const int pngNumPalettes = png_get_sPLT(png, info, &palettes); int pngNumEntries = 0; png_sPLT_entryp cEntries = nullptr; for (int i = 0; i < pngNumPalettes; ++i) { - png_sPLT_tp palette = &palettes[i]; - if (!strncmp(palette->name, "GX_", 3)) { + const png_const_sPLT_tp palette = &palettes[i]; + if (strncmp(palette->name, "GX_", 3) == 0) { pngNumEntries = palette->nentries; cEntries = palette->entries; break; @@ -511,20 +523,21 @@ static uint8_t* EncodePaletteSPLT(png_structp png, png_infop info, int numEntrie uint32_t format = 2; /* Default RGB5A3 */ for (int e = 0; e < pngNumEntries; ++e) { - png_sPLT_entryp ent = &cEntries[e]; + const png_const_sPLT_entryp ent = &cEntries[e]; if (ent->red != ent->green || ent->red != ent->blue) { if (ent->alpha) { format = 2; break; - } else + } else { format = 1; + } } } - ((uint32_t*)data)[0] = hecl::SBig(format); + reinterpret_cast(data)[0] = hecl::SBig(format); data += 4; - ((uint16_t*)data)[0] = hecl::SBig(uint16_t(1)); - ((uint16_t*)data)[1] = hecl::SBig(uint16_t(numEntries)); + reinterpret_cast(data)[0] = hecl::SBig(uint16_t(1)); + reinterpret_cast(data)[1] = hecl::SBig(uint16_t(numEntries)); data += 4; switch (format) { @@ -543,7 +556,7 @@ static uint8_t* EncodePaletteSPLT(png_structp png, png_infop info, int numEntrie } case 1: { /* RGB565 */ - uint16_t* data16 = (uint16_t*)data; + auto* data16 = reinterpret_cast(data); for (int e = 0; e < numEntries; ++e) { if (e < pngNumEntries) { uint16_t texel = Convert8To5(cEntries[e].red) << 11; @@ -558,7 +571,7 @@ static uint8_t* EncodePaletteSPLT(png_structp png, png_infop info, int numEntrie } case 2: { /* RGB5A3 */ - uint16_t* data16 = (uint16_t*)data; + auto* data16 = reinterpret_cast(data); for (int e = 0; e < numEntries; ++e) { uint16_t texel = 0; if (cEntries && cEntries[e].alpha == 0xff) { @@ -599,8 +612,9 @@ static void DecodeC4(png_structp png, png_infop info, const uint8_t* data, int w png_write_info(png, info); std::unique_ptr buf(new uint8_t[width]); for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) + for (int x = 0; x < width; ++x) { buf[x] = Lookup4BPP(texels, width, x, y); + } png_write_row(png, buf.get()); } } @@ -608,8 +622,9 @@ static void DecodeC4(png_structp png, png_infop info, const uint8_t* data, int w static void EncodeC4(png_structp png, png_infop info, const uint8_t* rgbaIn, uint8_t* data, int width, int height) { uint8_t* texels = EncodePaletteSPLT(png, info, 16, data); for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) + for (int x = 0; x < width; ++x) { Set4BPP(texels, width, x, y, rgbaIn[x]); + } rgbaIn += width; } } @@ -621,8 +636,9 @@ static void DecodeC8(png_structp png, png_infop info, const uint8_t* data, int w png_write_info(png, info); std::unique_ptr buf(new uint8_t[width]); for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) + for (int x = 0; x < width; ++x) { buf[x] = Lookup8BPP(texels, width, x, y); + } png_write_row(png, buf.get()); } } @@ -630,8 +646,9 @@ static void DecodeC8(png_structp png, png_infop info, const uint8_t* data, int w static void EncodeC8(png_structp png, png_infop info, const uint8_t* rgbaIn, uint8_t* data, int width, int height) { uint8_t* texels = EncodePalette(png, info, 256, data); for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) + for (int x = 0; x < width; ++x) { Set8BPP(texels, width, x, y, rgbaIn[x]); + } rgbaIn += width; } } @@ -643,7 +660,7 @@ static void DecodeRGB565(png_structp png, png_infop info, const uint8_t* texels, std::unique_ptr buf(new uint8_t[width * 3]); for (int y = height - 1; y >= 0; --y) { for (int x = 0; x < width; ++x) { - uint16_t texel = hecl::SBig(Lookup16BPP(texels, width, x, y)); + const uint16_t texel = hecl::SBig(Lookup16BPP(texels, width, x, y)); buf[x * 3] = Convert5To8(texel >> 11 & 0x1f); buf[x * 3 + 1] = Convert6To8(texel >> 5 & 0x3f); buf[x * 3 + 2] = Convert5To8(texel & 0x1f); @@ -676,7 +693,7 @@ static void DecodeRGB5A3(png_structp png, png_infop info, const uint8_t* texels, std::unique_ptr buf(new uint8_t[width * 4]); for (int y = height - 1; y >= 0; --y) { for (int x = 0; x < width; ++x) { - uint16_t texel = hecl::SBig(Lookup16BPP(texels, width, x, y)); + const uint16_t texel = hecl::SBig(Lookup16BPP(texels, width, x, y)); if (texel & 0x8000) { buf[x * 4] = Convert5To8(texel >> 10 & 0x1f); buf[x * 4 + 1] = Convert5To8(texel >> 5 & 0x1f); @@ -728,16 +745,18 @@ static void DecodeRGBA8(png_structp png, png_infop info, const uint8_t* texels, png_write_info(png, info); std::unique_ptr buf(new uint8_t[width * 4]); for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) + for (int x = 0; x < width; ++x) { LookupRGBA8(texels, width, x, y, &buf[x * 4], &buf[x * 4 + 1], &buf[x * 4 + 2], &buf[x * 4 + 3]); + } png_write_row(png, buf.get()); } } static void EncodeRGBA8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) { for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) + for (int x = 0; x < width; ++x) { SetRGBA8(texels, width, x, y, rgbaIn[x * 4], rgbaIn[x * 4 + 1], rgbaIn[x * 4 + 2], rgbaIn[x * 4 + 3]); + } rgbaIn += width * 4; } } @@ -754,50 +773,55 @@ static void DecodeCMPR(png_structp png, png_infop info, const uint8_t* texels, i png_write_info(png, info); /* Decode 8 rows at a time */ - int bwidth = (width + 7) / 8; - int bpwidth = bwidth * 8; + const int bwidth = (width + 7) / 8; + const int bpwidth = bwidth * 8; std::unique_ptr buf(new uint32_t[bpwidth * 8]); uint32_t* bTargets[4] = {buf.get(), buf.get() + 4, buf.get() + 4 * width, buf.get() + 4 * width + 4}; for (int y = height / 8 - 1; y >= 0; --y) { - const DXTBlock* blks = (DXTBlock*)(texels + 32 * bwidth * y); + const auto* blks = reinterpret_cast(texels + 32 * bwidth * y); for (int x = 0; x < width; x += 8) { uint32_t blkOut[4][4][4]; - squish::Decompress((uint8_t*)blkOut[0][0], blks++, squish::kDxt1GCN); - squish::Decompress((uint8_t*)blkOut[1][0], blks++, squish::kDxt1GCN); - squish::Decompress((uint8_t*)blkOut[2][0], blks++, squish::kDxt1GCN); - squish::Decompress((uint8_t*)blkOut[3][0], blks++, squish::kDxt1GCN); + squish::Decompress(reinterpret_cast(blkOut[0][0]), blks++, squish::kDxt1GCN); + squish::Decompress(reinterpret_cast(blkOut[1][0]), blks++, squish::kDxt1GCN); + squish::Decompress(reinterpret_cast(blkOut[2][0]), blks++, squish::kDxt1GCN); + squish::Decompress(reinterpret_cast(blkOut[3][0]), blks++, squish::kDxt1GCN); - for (int bt = 0; bt < 4; ++bt) - for (int by = 0; by < 4; ++by) - memcpy(bTargets[bt] + x + width * by, blkOut[bt][by], 16); + for (int bt = 0; bt < 4; ++bt) { + for (int by = 0; by < 4; ++by) { + std::memcpy(bTargets[bt] + x + width * by, blkOut[bt][by], 16); + } + } + } + for (int r = 7; r >= 0; --r) { + png_write_row(png, reinterpret_cast(bTargets[0] + width * r)); } - for (int r = 7; r >= 0; --r) - png_write_row(png, (png_bytep)(bTargets[0] + width * r)); } } static void EncodeCMPR(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) { /* Encode 8 rows at a time */ - int bwidth = (width + 7) / 8; - int bpwidth = bwidth * 8; + const int bwidth = (width + 7) / 8; + const int bpwidth = bwidth * 8; std::unique_ptr buf(new uint32_t[bpwidth * 8]); uint32_t* bTargets[4] = {buf.get(), buf.get() + 4, buf.get() + 4 * width, buf.get() + 4 * width + 4}; for (int y = height / 8 - 1; y >= 0; --y) { for (int r = 7; r >= 0; --r) { - memcpy(bTargets[0] + width * r, rgbaIn, width * 4); + std::memcpy(bTargets[0] + width * r, rgbaIn, width * 4); rgbaIn += width * 4; } - DXTBlock* blks = (DXTBlock*)(texels + 32 * bwidth * y); + auto* blks = reinterpret_cast(texels + 32 * bwidth * y); for (int x = 0; x < width; x += 8) { uint32_t blkIn[4][4][4]; - for (int bt = 0; bt < 4; ++bt) - for (int by = 0; by < 4; ++by) - memcpy(blkIn[bt][by], bTargets[bt] + x + width * by, 16); + for (int bt = 0; bt < 4; ++bt) { + for (int by = 0; by < 4; ++by) { + std::memcpy(blkIn[bt][by], bTargets[bt] + x + width * by, 16); + } + } - squish::Compress((uint8_t*)blkIn[0][0], blks++, squish::kDxt1GCN); - squish::Compress((uint8_t*)blkIn[1][0], blks++, squish::kDxt1GCN); - squish::Compress((uint8_t*)blkIn[2][0], blks++, squish::kDxt1GCN); - squish::Compress((uint8_t*)blkIn[3][0], blks++, squish::kDxt1GCN); + squish::Compress(reinterpret_cast(blkIn[0][0]), blks++, squish::kDxt1GCN); + squish::Compress(reinterpret_cast(blkIn[1][0]), blks++, squish::kDxt1GCN); + squish::Compress(reinterpret_cast(blkIn[2][0]), blks++, squish::kDxt1GCN); + squish::Compress(reinterpret_cast(blkIn[3][0]), blks++, squish::kDxt1GCN); } } } @@ -807,10 +831,10 @@ static void PNGErr(png_structp png, png_const_charp msg) { Log.report(logvisor:: static void PNGWarn(png_structp png, png_const_charp msg) { Log.report(logvisor::Warning, fmt("{}"), msg); } bool TXTR::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - uint32_t format = rs.readUint32Big(); - uint16_t width = rs.readUint16Big(); - uint16_t height = rs.readUint16Big(); - uint32_t numMips = rs.readUint32Big(); + const uint32_t format = rs.readUint32Big(); + const uint16_t width = rs.readUint16Big(); + const uint16_t height = rs.readUint16Big(); + const uint32_t numMips = rs.readUint32Big(); auto fp = hecl::FopenUnique(outPath.getAbsolutePath().data(), _SYS_STR("wb")); if (fp == nullptr) { @@ -869,11 +893,11 @@ bool TXTR::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { static std::unique_ptr ReadPalette(png_structp png, png_infop info, size_t& szOut) { std::unique_ptr ret; png_sPLT_tp palettes; - int paletteCount = png_get_sPLT(png, info, &palettes); - if (paletteCount) { + const int paletteCount = png_get_sPLT(png, info, &palettes); + if (paletteCount != 0) { for (int i = 0; i < paletteCount; ++i) { - png_sPLT_tp palette = &palettes[i]; - if (!strncmp(palette->name, "GX_", 3)) { + const png_const_sPLT_tp palette = &palettes[i]; + if (strncmp(palette->name, "GX_", 3) == 0) { if (palette->nentries > 16) { /* This is a C8 palette */ ret.reset(new uint8_t[4 * 257]); @@ -882,7 +906,7 @@ static std::unique_ptr ReadPalette(png_structp png, png_infop info, s uint8_t* cur = ret.get() + 4; for (int j = 0; j < 256; ++j) { if (j < palette->nentries) { - png_sPLT_entryp entry = &palette->entries[j]; + const png_const_sPLT_entryp entry = &palette->entries[j]; if (palette->depth == 16) { *cur++ = entry->red >> 8; *cur++ = entry->green >> 8; @@ -909,7 +933,7 @@ static std::unique_ptr ReadPalette(png_structp png, png_infop info, s uint8_t* cur = ret.get() + 4; for (int j = 0; j < 16; ++j) { if (j < palette->nentries) { - png_sPLT_entryp entry = &palette->entries[j]; + const png_const_sPLT_entryp entry = &palette->entries[j]; if (palette->depth == 16) { *cur++ = entry->red >> 8; *cur++ = entry->green >> 8; @@ -933,9 +957,9 @@ static std::unique_ptr ReadPalette(png_structp png, png_infop info, s } } } else { - png_colorp palettes; + png_colorp palettes2; int colorCount; - if (png_get_PLTE(png, info, &palettes, &colorCount) == PNG_INFO_PLTE) { + if (png_get_PLTE(png, info, &palettes2, &colorCount) == PNG_INFO_PLTE) { if (colorCount > 16) { /* This is a C8 palette */ ret.reset(new uint8_t[4 * 257]); @@ -944,7 +968,7 @@ static std::unique_ptr ReadPalette(png_structp png, png_infop info, s uint8_t* cur = ret.get() + 4; for (int j = 0; j < 256; ++j) { if (j < colorCount) { - png_colorp entry = &palettes[j]; + const png_const_colorp entry = &palettes2[j]; *cur++ = entry->red; *cur++ = entry->green; *cur++ = entry->blue; @@ -964,7 +988,7 @@ static std::unique_ptr ReadPalette(png_structp png, png_infop info, s uint8_t* cur = ret.get() + 4; for (int j = 0; j < 16; ++j) { if (j < colorCount) { - png_colorp entry = &palettes[j]; + const png_const_colorp entry = &palettes2[j]; *cur++ = entry->red; *cur++ = entry->green; *cur++ = entry->blue; @@ -984,11 +1008,11 @@ static std::unique_ptr ReadPalette(png_structp png, png_infop info, s static int GetNumPaletteEntriesForGCN(png_structp png, png_infop info) { png_sPLT_tp palettes; - int paletteCount = png_get_sPLT(png, info, &palettes); - if (paletteCount) { + const int paletteCount = png_get_sPLT(png, info, &palettes); + if (paletteCount != 0) { for (int i = 0; i < paletteCount; ++i) { - png_sPLT_tp palette = &palettes[i]; - if (!strncmp(palette->name, "GX_", 3)) { + const png_const_sPLT_tp palette = &palettes[i]; + if (strncmp(palette->name, "GX_", 3) == 0) { if (palette->nentries > 16) { /* This is a C8 palette */ return 256; @@ -996,13 +1020,12 @@ static int GetNumPaletteEntriesForGCN(png_structp png, png_infop info) { /* This is a C4 palette */ return 16; } - break; } } } else { - png_colorp palettes; + png_colorp palletes2; int colorCount; - if (png_get_PLTE(png, info, &palettes, &colorCount) == PNG_INFO_PLTE) { + if (png_get_PLTE(png, info, &palletes2, &colorCount) == PNG_INFO_PLTE) { if (colorCount > 16) { /* This is a C8 palette */ return 256; @@ -1054,10 +1077,10 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat png_read_info(pngRead, info); - png_uint_32 width = png_get_image_width(pngRead, info); - png_uint_32 height = png_get_image_height(pngRead, info); - png_byte colorType = png_get_color_type(pngRead, info); - png_byte bitDepth = png_get_bit_depth(pngRead, info); + const png_uint_32 width = png_get_image_width(pngRead, info); + const png_uint_32 height = png_get_image_height(pngRead, info); + const png_byte colorType = png_get_color_type(pngRead, info); + const png_byte bitDepth = png_get_bit_depth(pngRead, info); if (width < 4 || height < 4) { Log.report(logvisor::Error, fmt("image must be 4x4 or larger")); @@ -1070,18 +1093,22 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat png_text* textStruct; int numText; png_get_text(pngRead, info, &textStruct, &numText); - for (int i = 0; i < numText; ++i) - if (!strcmp(textStruct[i].key, "urde_nomip")) + for (int i = 0; i < numText; ++i) { + if (std::strcmp(textStruct[i].key, "urde_nomip") == 0) { mipmap = false; - if (colorType == PNG_COLOR_TYPE_PALETTE) + } + } + if (colorType == PNG_COLOR_TYPE_PALETTE) { mipmap = false; + } /* Compute mipmap levels */ size_t numMips = 1; if (mipmap && CountBits(width) == 1 && CountBits(height) == 1) { size_t index = std::min(width, height); - while (index >>= 1) + while (index >>= 1) { ++numMips; + } } if (bitDepth != 8) { @@ -1149,8 +1176,8 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat if (colorType == PNG_COLOR_TYPE_RGB) { png_read_row(pngRead, rowBuf.get(), nullptr); for (unsigned i = 0; i < width; ++i) { - size_t inbase = i * 3; - size_t outbase = (r * width + i) * 4; + const size_t inbase = i * 3; + const size_t outbase = (r * width + i) * 4; bufOut[outbase] = rowBuf[inbase]; bufOut[outbase + 1] = rowBuf[inbase + 1]; bufOut[outbase + 2] = rowBuf[inbase + 2]; @@ -1160,9 +1187,10 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat png_read_row(pngRead, &bufOut[(r * width) * nComps], nullptr); if (colorType == PNG_COLOR_TYPE_RGB_ALPHA) { for (unsigned i = 0; i < width; ++i) { - size_t outbase = (r * width + i) * nComps; - if (bufOut[outbase + 3] != 0 && bufOut[outbase + 3] != 255) + const size_t outbase = (r * width + i) * nComps; + if (bufOut[outbase + 3] != 0 && bufOut[outbase + 3] != 255) { doDXT1 = false; + } } } } @@ -1253,9 +1281,9 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat filterHeight = height; const uint8_t* rgbaIn = bufOut.get(); uint8_t* blocksOut = compOut.get(); - memset(blocksOut, 0, compLen); + std::memset(blocksOut, 0, compLen); for (size_t i = 0; i < numMips; ++i) { - int thisLen = squish::GetStorageRequirements(filterWidth, filterHeight, squish::kDxt1); + const int thisLen = squish::GetStorageRequirements(filterWidth, filterHeight, squish::kDxt1); EncodeCMPR(rgbaIn, blocksOut, filterWidth, filterHeight); rgbaIn += filterWidth * filterHeight * nComps; blocksOut += thisLen; @@ -1269,14 +1297,15 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat int filterHeight = height; compLen = bufLen; if (colorType == PNG_COLOR_TYPE_PALETTE) { - if (nPaletteEntries == 16) + if (nPaletteEntries == 16) { compLen /= 2; + } compLen += 8 + nPaletteEntries * 2; } compOut.reset(new uint8_t[compLen]); const uint8_t* rgbaIn = bufOut.get(); uint8_t* dataOut = compOut.get(); - memset(dataOut, 0, compLen); + std::memset(dataOut, 0, compLen); for (size_t i = 0; i < numMips; ++i) { switch (colorType) { case PNG_COLOR_TYPE_GRAY: @@ -1367,28 +1396,32 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP png_read_info(pngRead, info); - png_uint_32 width = png_get_image_width(pngRead, info); - png_uint_32 height = png_get_image_height(pngRead, info); - png_byte colorType = png_get_color_type(pngRead, info); - png_byte bitDepth = png_get_bit_depth(pngRead, info); + const png_uint_32 width = png_get_image_width(pngRead, info); + const png_uint_32 height = png_get_image_height(pngRead, info); + const png_byte colorType = png_get_color_type(pngRead, info); + const png_byte bitDepth = png_get_bit_depth(pngRead, info); /* Disable mipmapping if urde_nomip embedded */ bool mipmap = true; png_text* textStruct; int numText; png_get_text(pngRead, info, &textStruct, &numText); - for (int i = 0; i < numText; ++i) - if (!strcmp(textStruct[i].key, "urde_nomip")) + for (int i = 0; i < numText; ++i) { + if (std::strcmp(textStruct[i].key, "urde_nomip") == 0) { mipmap = false; - if (colorType == PNG_COLOR_TYPE_PALETTE) + } + } + if (colorType == PNG_COLOR_TYPE_PALETTE) { mipmap = false; + } /* Compute mipmap levels */ size_t numMips = 1; if (mipmap && CountBits(width) == 1 && CountBits(height) == 1) { size_t index = std::min(width, height); - while (index >>= 1) + while (index >>= 1) { ++numMips; + } } if (bitDepth != 8) { @@ -1454,7 +1487,7 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP switch (colorType) { case PNG_COLOR_TYPE_GRAY: for (unsigned i = 0; i < width; ++i) { - size_t outbase = (r * width + i) * 4; + const size_t outbase = (r * width + i) * 4; bufOut[outbase] = rowBuf[i]; bufOut[outbase + 1] = rowBuf[i]; bufOut[outbase + 2] = rowBuf[i]; @@ -1463,8 +1496,8 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP break; case PNG_COLOR_TYPE_GRAY_ALPHA: for (unsigned i = 0; i < width; ++i) { - size_t inbase = i * 2; - size_t outbase = (r * width + i) * 4; + const size_t inbase = i * 2; + const size_t outbase = (r * width + i) * 4; bufOut[outbase] = rowBuf[inbase]; bufOut[outbase + 1] = rowBuf[inbase]; bufOut[outbase + 2] = rowBuf[inbase]; @@ -1473,8 +1506,8 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP break; case PNG_COLOR_TYPE_RGB: for (unsigned i = 0; i < width; ++i) { - size_t inbase = i * 3; - size_t outbase = (r * width + i) * 4; + const size_t inbase = i * 3; + const size_t outbase = (r * width + i) * 4; bufOut[outbase] = rowBuf[inbase]; bufOut[outbase + 1] = rowBuf[inbase + 1]; bufOut[outbase + 2] = rowBuf[inbase + 2]; @@ -1483,8 +1516,8 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP break; case PNG_COLOR_TYPE_RGB_ALPHA: for (unsigned i = 0; i < width; ++i) { - size_t inbase = i * 4; - size_t outbase = (r * width + i) * 4; + const size_t inbase = i * 4; + const size_t outbase = (r * width + i) * 4; bufOut[outbase] = rowBuf[inbase]; bufOut[outbase + 1] = rowBuf[inbase + 1]; bufOut[outbase + 2] = rowBuf[inbase + 2]; @@ -1548,7 +1581,7 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP const uint8_t* rgbaIn = bufOut.get(); uint8_t* blocksOut = compOut.get(); for (i = 0; i < numMips; ++i) { - int thisLen = squish::GetStorageRequirements(filterWidth, filterHeight, compFlags); + const int thisLen = squish::GetStorageRequirements(filterWidth, filterHeight, compFlags); squish::CompressImage(rgbaIn, filterWidth, filterHeight, blocksOut, compFlags); rgbaIn += filterWidth * filterHeight * nComps; blocksOut += thisLen; @@ -1621,8 +1654,8 @@ static const atInt32 RetroToDol[11] { }; TXTR::Meta TXTR::GetMetaData(DataSpec::PAKEntryReadStream& rs) { - atUint32 retroFormat = rs.readUint32Big(); - atUint32 format = RetroToDol[retroFormat]; + const atUint32 retroFormat = rs.readUint32Big(); + const atUint32 format = RetroToDol[retroFormat]; if (format == UINT32_MAX) return {}; @@ -1636,10 +1669,10 @@ TXTR::Meta TXTR::GetMetaData(DataSpec::PAKEntryReadStream& rs) { meta.hasPalette = true; PaletteMeta& palMeta = meta.palette; palMeta.format = rs.readUint32Big(); - atUint16 palWidth = rs.readUint16Big(); - atUint16 palHeight = rs.readUint16Big(); + const atUint16 palWidth = rs.readUint16Big(); + const atUint16 palHeight = rs.readUint16Big(); palMeta.elementCount = palWidth * palHeight; - atUint32 palSize = atUint32(palWidth * palHeight * 2); + const atUint32 palSize = atUint32(palWidth * palHeight * 2); if (format == 8) textureSize /= 2; std::unique_ptr palData(new u8[palSize]); diff --git a/DataSpec/DNACommon/WPSC.cpp b/DataSpec/DNACommon/WPSC.cpp index 67fcfb57c..c801d8789 100644 --- a/DataSpec/DNACommon/WPSC.cpp +++ b/DataSpec/DNACommon/WPSC.cpp @@ -1,645 +1,13 @@ #include "DataSpec/DNACommon/WPSC.hpp" - #include "DataSpec/DNACommon/PAK.hpp" -#include - namespace DataSpec::DNAParticle { -template -void WPSM::_read(athena::io::YAMLDocReader& r) { - for (const auto& elem : r.getCurNode()->m_mapChildren) { - if (elem.first.size() < 4) { - LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), elem.first); - continue; - } +template struct PPImpl<_WPSM>; +template struct PPImpl<_WPSM>; - if (auto rec = r.enterSubRecord(elem.first.c_str())) { - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('IORN'): - x0_IORN.read(r); - break; - case SBIG('IVEC'): - x4_IVEC.read(r); - break; - case SBIG('PSOV'): - x8_PSOV.read(r); - break; - case SBIG('PSVM'): - xc_PSVM.read(r); - break; - case SBIG('VMD2'): - x10_VMD2.read(r); - break; - case SBIG('PSLT'): - x14_PSLT.read(r); - break; - case SBIG('PSCL'): - x18_PSCL.read(r); - break; - case SBIG('PCOL'): - x1c_PCOL.read(r); - break; - case SBIG('POFS'): - x20_POFS.read(r); - break; - case SBIG('OFST'): - x24_OFST.read(r); - break; - case SBIG('APSO'): - x28_APSO.read(r); - break; - case SBIG('HOMG'): - x29_HOMG.read(r); - break; - case SBIG('AP11'): - x2a_AP11.read(r); - break; - case SBIG('AP21'): - x2b_AP21.read(r); - break; - case SBIG('AS11'): - x2c_AS11.read(r); - break; - case SBIG('AS12'): - x2d_AS12.read(r); - break; - case SBIG('AS13'): - x2e_AS13.read(r); - break; - case SBIG('TRAT'): - x30_TRAT.read(r); - break; - case SBIG('APSM'): - x34_APSM.read(r); - break; - case SBIG('APS2'): - x44_APS2.read(r); - break; - case SBIG('ASW1'): - x54_ASW1.read(r); - break; - case SBIG('ASW2'): - x64_ASW2.read(r); - break; - case SBIG('ASW3'): - x74_ASW3.read(r); - break; - case SBIG('OHEF'): - x84_OHEF.read(r); - break; - case SBIG('COLR'): - x94_COLR.read(r); - break; - case SBIG('EWTR'): - xa4_EWTR.read(r); - break; - case SBIG('LWTR'): - xa5_LWTR.read(r); - break; - case SBIG('SWTR'): - xa6_SWTR.read(r); - break; - case SBIG('PJFX'): - xa8_PJFX = r.readUint32(); - break; - case SBIG('RNGE'): - xac_RNGE.read(r); - break; - case SBIG('FOFF'): - xb0_FOFF.read(r); - break; - case SBIG('FC60'): - xunk_FC60.read(r); - break; - case SBIG('SPS1'): - xunk_SPS1.read(r); - break; - case SBIG('SPS2'): - xunk_SPS2.read(r); - break; - } - } - } -} - -template -void WPSM::_write(athena::io::YAMLDocWriter& w) const { - if (x0_IORN) - if (auto rec = w.enterSubRecord("IORN")) - x0_IORN.write(w); - if (x4_IVEC) - if (auto rec = w.enterSubRecord("IVEC")) - x4_IVEC.write(w); - if (x8_PSOV) - if (auto rec = w.enterSubRecord("PSOV")) - x8_PSOV.write(w); - if (xc_PSVM) - if (auto rec = w.enterSubRecord("PSVM")) - xc_PSVM.write(w); - if (x10_VMD2) - if (auto rec = w.enterSubRecord("VMD2")) - x10_VMD2.write(w); - if (x14_PSLT) - if (auto rec = w.enterSubRecord("PSLT")) - x14_PSLT.write(w); - if (x18_PSCL) - if (auto rec = w.enterSubRecord("PSCL")) - x18_PSCL.write(w); - if (x1c_PCOL) - if (auto rec = w.enterSubRecord("PCOL")) - x1c_PCOL.write(w); - if (x20_POFS) - if (auto rec = w.enterSubRecord("POFS")) - x20_POFS.write(w); - if (x24_OFST) - if (auto rec = w.enterSubRecord("OFST")) - x24_OFST.write(w); - if (x28_APSO) - if (auto rec = w.enterSubRecord("APSO")) - x28_APSO.write(w); - if (x29_HOMG) - if (auto rec = w.enterSubRecord("HOMG")) - x29_HOMG.write(w); - if (x2a_AP11) - if (auto rec = w.enterSubRecord("AP11")) - x2a_AP11.write(w); - if (x2b_AP21) - if (auto rec = w.enterSubRecord("AP21")) - x2b_AP21.write(w); - if (x2c_AS11) - if (auto rec = w.enterSubRecord("AS11")) - x2c_AS11.write(w); - if (x2d_AS12) - if (auto rec = w.enterSubRecord("AS12")) - x2d_AS12.write(w); - if (x2e_AS13) - if (auto rec = w.enterSubRecord("AS13")) - x2e_AS13.write(w); - if (x30_TRAT) - if (auto rec = w.enterSubRecord("TRAT")) - x30_TRAT.write(w); - if (x34_APSM) - if (auto rec = w.enterSubRecord("APSM")) - x34_APSM.write(w); - if (x44_APS2) - if (auto rec = w.enterSubRecord("APS2")) - x44_APS2.write(w); - if (x54_ASW1) - if (auto rec = w.enterSubRecord("ASW1")) - x54_ASW1.write(w); - if (x64_ASW2) - if (auto rec = w.enterSubRecord("ASW2")) - x64_ASW2.write(w); - if (x74_ASW3) - if (auto rec = w.enterSubRecord("ASW3")) - x74_ASW3.write(w); - if (x84_OHEF) - if (auto rec = w.enterSubRecord("OHEF")) - x84_OHEF.write(w); - if (x94_COLR) - if (auto rec = w.enterSubRecord("COLR")) - x94_COLR.write(w); - if (!xa4_EWTR) - if (auto rec = w.enterSubRecord("EWTR")) - xa4_EWTR.write(w); - if (!xa5_LWTR) - if (auto rec = w.enterSubRecord("LWTR")) - xa5_LWTR.write(w); - if (!xa6_SWTR) - if (auto rec = w.enterSubRecord("SWTR")) - xa6_SWTR.write(w); - if (xa8_PJFX != UINT32_MAX) - w.writeUint32("PJFX", xa8_PJFX); - if (xac_RNGE) - if (auto rec = w.enterSubRecord("RNGE")) - xac_RNGE.write(w); - if (xb0_FOFF) - if (auto rec = w.enterSubRecord("FOFF")) - xb0_FOFF.write(w); - if (xunk_FC60) - if (auto rec = w.enterSubRecord("FC60")) - xunk_FC60.write(w); - if (xunk_SPS1) - if (auto rec = w.enterSubRecord("SPS1")) - xunk_SPS1.write(w); - if (xunk_SPS1) - if (auto rec = w.enterSubRecord("SPS2")) - xunk_SPS2.write(w); -} - -template -void WPSM::_binarySize(size_t& __isz) const { - __isz += 4; - if (x0_IORN) { - __isz += 4; - x0_IORN.binarySize(__isz); - } - if (x4_IVEC) { - __isz += 4; - x4_IVEC.binarySize(__isz); - } - if (x8_PSOV) { - __isz += 4; - x8_PSOV.binarySize(__isz); - } - if (xc_PSVM) { - __isz += 4; - xc_PSVM.binarySize(__isz); - } - if (x10_VMD2) { - __isz += 4; - x10_VMD2.binarySize(__isz); - } - if (x14_PSLT) { - __isz += 4; - x14_PSLT.binarySize(__isz); - } - if (x18_PSCL) { - __isz += 4; - x18_PSCL.binarySize(__isz); - } - if (x1c_PCOL) { - __isz += 4; - x1c_PCOL.binarySize(__isz); - } - if (x20_POFS) { - __isz += 4; - x20_POFS.binarySize(__isz); - } - if (x24_OFST) { - __isz += 4; - x24_OFST.binarySize(__isz); - } - if (x28_APSO) { - __isz += 4; - x28_APSO.binarySize(__isz); - } - if (x29_HOMG) { - __isz += 4; - x29_HOMG.binarySize(__isz); - } - if (x2a_AP11) { - __isz += 4; - x2a_AP11.binarySize(__isz); - } - if (x2b_AP21) { - __isz += 4; - x2b_AP21.binarySize(__isz); - } - if (x2c_AS11) { - __isz += 4; - x2c_AS11.binarySize(__isz); - } - if (x2d_AS12) { - __isz += 4; - x2d_AS12.binarySize(__isz); - } - if (x2e_AS13) { - __isz += 4; - x2e_AS13.binarySize(__isz); - } - if (x30_TRAT) { - __isz += 4; - x30_TRAT.binarySize(__isz); - } - if (x34_APSM) { - __isz += 4; - x34_APSM.binarySize(__isz); - } - if (x44_APS2) { - __isz += 4; - x44_APS2.binarySize(__isz); - } - if (x54_ASW1) { - __isz += 4; - x54_ASW1.binarySize(__isz); - } - if (x64_ASW2) { - __isz += 4; - x64_ASW2.binarySize(__isz); - } - if (x74_ASW3) { - __isz += 4; - x74_ASW3.binarySize(__isz); - } - if (x84_OHEF) { - __isz += 4; - x84_OHEF.binarySize(__isz); - } - if (x94_COLR) { - __isz += 4; - x94_COLR.binarySize(__isz); - } - if (!xa4_EWTR) { - __isz += 4; - xa4_EWTR.binarySize(__isz); - } - if (!xa5_LWTR) { - __isz += 4; - xa5_LWTR.binarySize(__isz); - } - if (!xa6_SWTR) { - __isz += 4; - xa6_SWTR.binarySize(__isz); - } - if (xa8_PJFX != UINT32_MAX) - __isz += 12; - if (xac_RNGE) { - __isz += 4; - xac_RNGE.binarySize(__isz); - } - if (xb0_FOFF) { - __isz += 4; - xb0_FOFF.binarySize(__isz); - } - if (xunk_FC60) { - __isz += 4; - xunk_FC60.binarySize(__isz); - } - if (xunk_SPS1) { - __isz += 4; - xunk_SPS1.binarySize(__isz); - } - if (xunk_SPS2) { - __isz += 4; - xunk_SPS2.binarySize(__isz); - } -} - -template -void WPSM::_read(athena::io::IStreamReader& r) { - DNAFourCC clsId; - clsId.read(r); - if (clsId != SBIG('WPSM')) { - LogModule.report(logvisor::Warning, fmt("non WPSM provided to WPSM parser")); - return; - } - clsId.read(r); - while (clsId != SBIG('_END')) { - switch (clsId.toUint32()) { - case SBIG('IORN'): - x0_IORN.read(r); - break; - case SBIG('IVEC'): - x4_IVEC.read(r); - break; - case SBIG('PSOV'): - x8_PSOV.read(r); - break; - case SBIG('PSVM'): - xc_PSVM.read(r); - break; - case SBIG('VMD2'): - x10_VMD2.read(r); - break; - case SBIG('PSLT'): - x14_PSLT.read(r); - break; - case SBIG('PSCL'): - x18_PSCL.read(r); - break; - case SBIG('PCOL'): - x1c_PCOL.read(r); - break; - case SBIG('POFS'): - x20_POFS.read(r); - break; - case SBIG('OFST'): - x24_OFST.read(r); - break; - case SBIG('APSO'): - r.readUint32(); - x28_APSO = r.readBool(); - break; - case SBIG('HOMG'): - x29_HOMG.read(r); - break; - case SBIG('AP11'): - x2a_AP11.read(r); - break; - case SBIG('AP21'): - x2b_AP21.read(r); - break; - case SBIG('AS11'): - x2c_AS11.read(r); - break; - case SBIG('AS12'): - x2d_AS12.read(r); - break; - case SBIG('AS13'): - x2e_AS13.read(r); - break; - case SBIG('TRAT'): - x30_TRAT.read(r); - break; - case SBIG('APSM'): - x34_APSM.read(r); - break; - case SBIG('APS2'): - x44_APS2.read(r); - break; - case SBIG('ASW1'): - x54_ASW1.read(r); - break; - case SBIG('ASW2'): - x64_ASW2.read(r); - break; - case SBIG('ASW3'): - x74_ASW3.read(r); - break; - case SBIG('OHEF'): - x84_OHEF.read(r); - break; - case SBIG('COLR'): - x94_COLR.read(r); - break; - case SBIG('EWTR'): - r.readUint32(); - xa4_EWTR = r.readBool(); - break; - case SBIG('LWTR'): - r.readUint32(); - xa5_LWTR = r.readBool(); - break; - case SBIG('SWTR'): - r.readUint32(); - xa6_SWTR = r.readBool(); - break; - case SBIG('PJFX'): { - uint32_t fcc; - r.readBytesToBuf(&fcc, 4); - if (fcc != SBIG('NONE')) - xa8_PJFX = r.readUint32Big(); - } break; - case SBIG('RNGE'): - xac_RNGE.read(r); - break; - case SBIG('FOFF'): - xb0_FOFF.read(r); - break; - case SBIG('FC60'): - xunk_FC60.read(r); - break; - case SBIG('SPS1'): - xunk_SPS1.read(r); - break; - case SBIG('SPS2'): - xunk_SPS2.read(r); - break; - default: - LogModule.report(logvisor::Fatal, fmt("Unknown WPSM class {} @{}"), clsId, r.position()); - break; - } - clsId.read(r); - } -} - -template -void WPSM::_write(athena::io::IStreamWriter& w) const { - w.writeBytes("WPSM", 4); - if (x0_IORN) { - w.writeBytes("IORN", 4); - x0_IORN.write(w); - } - if (x4_IVEC) { - w.writeBytes("IVEC", 4); - x4_IVEC.write(w); - } - if (x8_PSOV) { - w.writeBytes("PSOV", 4); - x8_PSOV.write(w); - } - if (xc_PSVM) { - w.writeBytes("PSVM", 4); - xc_PSVM.write(w); - } - if (x10_VMD2) { - w.writeBytes("VMD2", 4); - x10_VMD2.write(w); - } - if (x14_PSLT) { - w.writeBytes("PSLT", 4); - x14_PSLT.write(w); - } - if (x18_PSCL) { - w.writeBytes("PSCL", 4); - x18_PSCL.write(w); - } - if (x1c_PCOL) { - w.writeBytes("PCOL", 4); - x1c_PCOL.write(w); - } - if (x20_POFS) { - w.writeBytes("POFS", 4); - x20_POFS.write(w); - } - if (x24_OFST) { - w.writeBytes("OFST", 4); - x24_OFST.write(w); - } - if (x28_APSO) { - w.writeBytes("APSO", 4); - x28_APSO.write(w); - } - if (x29_HOMG) { - w.writeBytes("HOMG", 4); - x29_HOMG.write(w); - } - if (x2a_AP11) { - w.writeBytes("AP11", 4); - x2a_AP11.write(w); - } - if (x2b_AP21) { - w.writeBytes("AP21", 4); - x2b_AP21.write(w); - } - if (x2c_AS11) { - w.writeBytes("AS11", 4); - x2c_AS11.write(w); - } - if (x2d_AS12) { - w.writeBytes("AS12", 4); - x2d_AS12.write(w); - } - if (x2e_AS13) { - w.writeBytes("AS13", 4); - x2e_AS13.write(w); - } - if (x30_TRAT) { - w.writeBytes("TRAT", 4); - x30_TRAT.write(w); - } - if (x34_APSM) { - w.writeBytes("APSM", 4); - x34_APSM.write(w); - } - if (x44_APS2) { - w.writeBytes("APS2", 4); - x44_APS2.write(w); - } - if (x54_ASW1) { - w.writeBytes("ASW1", 4); - x54_ASW1.write(w); - } - if (x64_ASW2) { - w.writeBytes("ASW2", 4); - x64_ASW2.write(w); - } - if (x74_ASW3) { - w.writeBytes("ASW3", 4); - x74_ASW3.write(w); - } - if (x84_OHEF) { - w.writeBytes("OHEF", 4); - x84_OHEF.write(w); - } - if (x94_COLR) { - w.writeBytes("COLR", 4); - x94_COLR.write(w); - } - if (!xa4_EWTR) { - w.writeBytes("EWTR", 4); - xa4_EWTR.write(w); - } - if (!xa5_LWTR) { - w.writeBytes("LWTR", 4); - xa5_LWTR.write(w); - } - if (!xa6_SWTR) { - w.writeBytes("SWTR", 4); - xa6_SWTR.write(w); - } - if (xa8_PJFX != UINT32_MAX) { - w.writeBytes("PJFXCNST", 8); - w.writeUint32(xa8_PJFX); - } - if (xac_RNGE) { - w.writeBytes("RNGE", 4); - xac_RNGE.write(w); - } - if (xb0_FOFF) { - w.writeBytes("FOFF", 4); - xb0_FOFF.write(w); - } - if (xunk_FC60) { - w.writeBytes("FC60", 4); - xunk_FC60.write(w); - } - if (xunk_SPS1) { - w.writeBytes("SPS1", 4); - xunk_SPS1.write(w); - } - if (xunk_SPS2) { - w.writeBytes("SPS2", 4); - xunk_SPS2.write(w); - } - - w.writeBytes("_END", 4); -} - -AT_SUBSPECIALIZE_DNA_YAML(WPSM) -AT_SUBSPECIALIZE_DNA_YAML(WPSM) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_WPSM>) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_WPSM>) template <> std::string_view WPSM::DNAType() { @@ -651,20 +19,6 @@ std::string_view WPSM::DNAType() { return "WPSM"sv; } -template -void WPSM::gatherDependencies(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(x34_APSM.id, pathsOut); - g_curSpec->flattenDependencies(x44_APS2.id, pathsOut); - g_curSpec->flattenDependencies(x54_ASW1.id, pathsOut); - g_curSpec->flattenDependencies(x64_ASW2.id, pathsOut); - g_curSpec->flattenDependencies(x74_ASW3.id, pathsOut); - g_curSpec->flattenDependencies(x84_OHEF.id, pathsOut); - g_curSpec->flattenDependencies(x94_COLR.id, pathsOut); -} - -template struct WPSM; -template struct WPSM; - template bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { athena::io::FileWriter writer(outPath.getAbsolutePath()); diff --git a/DataSpec/DNACommon/WPSC.def b/DataSpec/DNACommon/WPSC.def new file mode 100644 index 000000000..04b6ce33f --- /dev/null +++ b/DataSpec/DNACommon/WPSC.def @@ -0,0 +1,87 @@ +#ifndef ENTRY +#define ENTRY(name, identifier) +#endif + +#ifndef INT_ENTRY +#define INT_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef U32_ENTRY +#define U32_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef REAL_ENTRY +#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef VECTOR_ENTRY +#define VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef MOD_VECTOR_ENTRY +#define MOD_VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef COLOR_ENTRY +#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef UV_ENTRY +#define UV_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef RES_ENTRY +#define RES_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef BOOL_ENTRY +#define BOOL_ENTRY(name, identifier, def) ENTRY(name, identifier) +#endif + +VECTOR_ENTRY('IORN', x0_IORN) +VECTOR_ENTRY('IVEC', x4_IVEC) +VECTOR_ENTRY('PSOV', x8_PSOV) +MOD_VECTOR_ENTRY('PSVM', xc_PSVM) +INT_ENTRY('PSLT', x14_PSLT) +VECTOR_ENTRY('PSCL', x18_PSCL) +COLOR_ENTRY('PCOL', x1c_PCOL) +VECTOR_ENTRY('POFS', x20_POFS) +VECTOR_ENTRY('OFST', x24_OFST) + +REAL_ENTRY('TRAT', x30_TRAT) +RES_ENTRY('APSM', x34_APSM) +RES_ENTRY('APS2', x44_APS2) +RES_ENTRY('ASW1', x54_ASW1) +RES_ENTRY('ASW2', x64_ASW2) +RES_ENTRY('ASW3', x74_ASW3) +RES_ENTRY('OHEF', x84_OHEF) +RES_ENTRY('COLR', x94_COLR) +U32_ENTRY('PJFX', xa8_PJFX) +REAL_ENTRY('RNGE', xac_RNGE) +REAL_ENTRY('FOFF', xb0_FOFF) + +BOOL_ENTRY('VMD2', x10_VMD2, false) +BOOL_ENTRY('APSO', x28_APSO, false) +BOOL_ENTRY('HOMG', x29_HOMG, false) +BOOL_ENTRY('AP11', x2a_AP11, false) +BOOL_ENTRY('AP21', x2b_AP21, false) +BOOL_ENTRY('AS11', x2c_AS11, false) +BOOL_ENTRY('AS12', x2d_AS12, false) +BOOL_ENTRY('AS13', x2e_AS13, false) +BOOL_ENTRY('EWTR', xa4_EWTR, true) +BOOL_ENTRY('LWTR', xa5_LWTR, true) +BOOL_ENTRY('SWTR', xa6_SWTR, true) +BOOL_ENTRY('FC60', xunk_FC60, false) +BOOL_ENTRY('SPS1', xunk_SPS1, false) +BOOL_ENTRY('SPS2', xunk_SPS2, false) + +#undef ENTRY +#undef INT_ENTRY +#undef U32_ENTRY +#undef REAL_ENTRY +#undef VECTOR_ENTRY +#undef MOD_VECTOR_ENTRY +#undef COLOR_ENTRY +#undef UV_ENTRY +#undef RES_ENTRY +#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/WPSC.hpp b/DataSpec/DNACommon/WPSC.hpp index 3df67b7bd..6a387ef7a 100644 --- a/DataSpec/DNACommon/WPSC.hpp +++ b/DataSpec/DNACommon/WPSC.hpp @@ -12,53 +12,40 @@ class ProjectPath; } namespace DataSpec::DNAParticle { -template -struct WPSM : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - VectorElementFactory x0_IORN; - VectorElementFactory x4_IVEC; - VectorElementFactory x8_PSOV; - ModVectorElementFactory xc_PSVM; - BoolHelper x10_VMD2; - IntElementFactory x14_PSLT; - VectorElementFactory x18_PSCL; - ColorElementFactory x1c_PCOL; - VectorElementFactory x20_POFS; - VectorElementFactory x24_OFST; - BoolHelper x28_APSO; - BoolHelper x29_HOMG; - BoolHelper x2a_AP11; - BoolHelper x2b_AP21; - BoolHelper x2c_AS11; - BoolHelper x2d_AS12; - BoolHelper x2e_AS13; - RealElementFactory x30_TRAT; - ChildResourceFactory x34_APSM; - ChildResourceFactory x44_APS2; - ChildResourceFactory x54_ASW1; - ChildResourceFactory x64_ASW2; - ChildResourceFactory x74_ASW3; - ChildResourceFactory x84_OHEF; - ChildResourceFactory x94_COLR; - BoolHelper xa4_EWTR; - BoolHelper xa5_LWTR; - BoolHelper xa6_SWTR; - uint32_t xa8_PJFX = ~0; - RealElementFactory xac_RNGE; - RealElementFactory xb0_FOFF; - BoolHelper xunk_FC60; - BoolHelper xunk_SPS1; - BoolHelper xunk_SPS2; - WPSM() { - xa4_EWTR = true; - xa5_LWTR = true; - xa6_SWTR = true; +template +struct _WPSM { + static constexpr ParticleType Type = ParticleType::WPSM; + +#define INT_ENTRY(name, identifier) IntElementFactory identifier; +#define U32_ENTRY(name, identifier) uint32_t identifier = ~0; +#define REAL_ENTRY(name, identifier) RealElementFactory identifier; +#define VECTOR_ENTRY(name, identifier) VectorElementFactory identifier; +#define MOD_VECTOR_ENTRY(name, identifier) ModVectorElementFactory identifier; +#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; +#define UV_ENTRY(name, identifier) UVElementFactory identifier; +#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; +#define BOOL_ENTRY(name, identifier, def) bool identifier = def; +#include "WPSC.def" + + template + void constexpr Enumerate(_Func f) { +#define ENTRY(name, identifier) f(FOURCC(name), identifier); +#define BOOL_ENTRY(name, identifier, def) f(FOURCC(name), identifier, def); +#include "WPSC.def" } - void gatherDependencies(std::vector&) const; + template + bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { +#define ENTRY(name, identifier) case SBIG(name): f(identifier); return true; +#include "WPSC.def" + default: return false; + } + } }; +template +using WPSM = PPImpl<_WPSM>; template bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); diff --git a/DataSpec/DNAMP1/ANCS.cpp b/DataSpec/DNAMP1/ANCS.cpp index a0d51c72b..3a9337759 100644 --- a/DataSpec/DNAMP1/ANCS.cpp +++ b/DataSpec/DNAMP1/ANCS.cpp @@ -611,30 +611,30 @@ std::string_view ANCS::CharacterSet::CharacterInfo::DNAType() { template <> void ANCS::AnimationSet::MetaAnimFactory::Enumerate(athena::io::IStreamReader& reader) { - IMetaAnim::Type type(IMetaAnim::Type(reader.readUint32Big())); + const auto type = IMetaAnim::Type(reader.readUint32Big()); switch (type) { case IMetaAnim::Type::Primitive: - m_anim.reset(new struct MetaAnimPrimitive); + m_anim = std::make_unique(); m_anim->read(reader); break; case IMetaAnim::Type::Blend: - m_anim.reset(new struct MetaAnimBlend); + m_anim = std::make_unique(); m_anim->read(reader); break; case IMetaAnim::Type::PhaseBlend: - m_anim.reset(new struct MetaAnimPhaseBlend); + m_anim = std::make_unique(); m_anim->read(reader); break; case IMetaAnim::Type::Random: - m_anim.reset(new struct MetaAnimRandom); + m_anim = std::make_unique(); m_anim->read(reader); break; case IMetaAnim::Type::Sequence: - m_anim.reset(new struct MetaAnimSequence); + m_anim = std::make_unique(); m_anim->read(reader); break; default: - m_anim.reset(nullptr); + m_anim.reset(); break; } } @@ -660,22 +660,22 @@ void ANCS::AnimationSet::MetaAnimFactory::Enumerate(athena::io std::string type = reader.readString("type"); std::transform(type.begin(), type.end(), type.begin(), tolower); if (type == "primitive") { - m_anim.reset(new struct MetaAnimPrimitive); + m_anim = std::make_unique(); m_anim->read(reader); } else if (type == "blend") { - m_anim.reset(new struct MetaAnimBlend); + m_anim = std::make_unique(); m_anim->read(reader); } else if (type == "phaseblend") { - m_anim.reset(new struct MetaAnimPhaseBlend); + m_anim = std::make_unique(); m_anim->read(reader); } else if (type == "random") { - m_anim.reset(new struct MetaAnimRandom); + m_anim = std::make_unique(); m_anim->read(reader); } else if (type == "sequence") { - m_anim.reset(new struct MetaAnimSequence); + m_anim = std::make_unique(); m_anim->read(reader); } else { - m_anim.reset(nullptr); + m_anim.reset(); } } @@ -696,20 +696,20 @@ void ANCS::AnimationSet::MetaTransFactory::Enumerate(athena::io::I IMetaTrans::Type type(IMetaTrans::Type(reader.readUint32Big())); switch (type) { case IMetaTrans::Type::MetaAnim: - m_trans.reset(new struct MetaTransMetaAnim); + m_trans = std::make_unique(); m_trans->read(reader); break; case IMetaTrans::Type::Trans: - m_trans.reset(new struct MetaTransTrans); + m_trans = std::make_unique(); m_trans->read(reader); break; case IMetaTrans::Type::PhaseTrans: - m_trans.reset(new struct MetaTransPhaseTrans); + m_trans = std::make_unique(); m_trans->read(reader); break; case IMetaTrans::Type::NoTrans: default: - m_trans.reset(nullptr); + m_trans.reset(); break; } } @@ -737,16 +737,16 @@ void ANCS::AnimationSet::MetaTransFactory::Enumerate(athena::i std::string type = reader.readString("type"); std::transform(type.begin(), type.end(), type.begin(), tolower); if (type == "metaanim") { - m_trans.reset(new struct MetaTransMetaAnim); + m_trans = std::make_unique(); m_trans->read(reader); } else if (type == "trans") { - m_trans.reset(new struct MetaTransTrans); + m_trans = std::make_unique(); m_trans->read(reader); } else if (type == "phasetrans") { - m_trans.reset(new struct MetaTransPhaseTrans); + m_trans = std::make_unique(); m_trans->read(reader); } else { - m_trans.reset(nullptr); + m_trans.reset(); } } diff --git a/DataSpec/DNAMP1/ANIM.cpp b/DataSpec/DNAMP1/ANIM.cpp index 203831ebf..0fce2c36a 100644 --- a/DataSpec/DNAMP1/ANIM.cpp +++ b/DataSpec/DNAMP1/ANIM.cpp @@ -122,15 +122,15 @@ void ANIM::Enumerate(typename Read::StreamT& reader) { atUint32 version = reader.readUint32Big(); switch (version) { case 0: - m_anim.reset(new struct ANIM0); + m_anim = std::make_unique(); m_anim->read(reader); break; case 2: - m_anim.reset(new struct ANIM2(false)); + m_anim = std::make_unique(false); m_anim->read(reader); break; case 3: - m_anim.reset(new struct ANIM2(true)); + m_anim = std::make_unique(true); m_anim->read(reader); break; default: @@ -548,7 +548,7 @@ void ANIM::ANIM2::Enumerate(size_t& __isz) { ANIM::ANIM(const BlenderAction& act, const std::unordered_map& idMap, const DNAANIM::RigInverter& rig, bool pc) { - m_anim.reset(new struct ANIM2(pc)); + m_anim = std::make_unique(pc); IANIM& newAnim = *m_anim; newAnim.looping = act.looping; diff --git a/DataSpec/DNAMP1/DCLN.hpp b/DataSpec/DNAMP1/DCLN.hpp index 503c72172..2136e029d 100644 --- a/DataSpec/DNAMP1/DCLN.hpp +++ b/DataSpec/DNAMP1/DCLN.hpp @@ -99,15 +99,18 @@ void DCLN::Collision::Node::Enumerate(typename Op::StreamT& s) { Do(athena::io::PropId{"halfExtent"}, halfExtent, s); Do(athena::io::PropId{"isLeaf"}, isLeaf, s); if (isLeaf) { - if (!leafData) - leafData.reset(new LeafData); + if (!leafData) { + leafData = std::make_unique(); + } Do(athena::io::PropId{"leafData"}, *leafData, s); } else { - if (!left) - left.reset(new Node); + if (!left) { + left = std::make_unique(); + } Do(athena::io::PropId{"left"}, *left, s); - if (!right) - right.reset(new Node); + if (!right) { + right = std::make_unique(); + } Do(athena::io::PropId{"right"}, *right, s); } } diff --git a/DataSpec/DNAMP1/FRME.cpp b/DataSpec/DNAMP1/FRME.cpp index b0405c334..4fdced531 100644 --- a/DataSpec/DNAMP1/FRME.cpp +++ b/DataSpec/DNAMP1/FRME.cpp @@ -54,43 +54,43 @@ void FRME::Widget::Enumerate(athena::io::IStreamReader& __dna_read header.read(__dna_reader); switch (type.toUint32()) { case SBIG('BWIG'): - widgetInfo.reset(new BWIGInfo); + widgetInfo = std::make_unique(); break; case SBIG('HWIG'): - widgetInfo.reset(new HWIGInfo); + widgetInfo = std::make_unique(); break; case SBIG('CAMR'): - widgetInfo.reset(new CAMRInfo); + widgetInfo = std::make_unique(); break; case SBIG('LITE'): - widgetInfo.reset(new LITEInfo); + widgetInfo = std::make_unique(); break; case SBIG('ENRG'): - widgetInfo.reset(new ENRGInfo); + widgetInfo = std::make_unique(); break; case SBIG('MODL'): - widgetInfo.reset(new MODLInfo); + widgetInfo = std::make_unique(); break; case SBIG('METR'): - widgetInfo.reset(new METRInfo); + widgetInfo = std::make_unique(); break; case SBIG('GRUP'): - widgetInfo.reset(new GRUPInfo); + widgetInfo = std::make_unique(); break; case SBIG('PANE'): - widgetInfo.reset(new PANEInfo); + widgetInfo = std::make_unique(); break; case SBIG('TXPN'): - widgetInfo.reset(new TXPNInfo(owner->version)); + widgetInfo = std::make_unique(owner->version); break; case SBIG('IMGP'): - widgetInfo.reset(new IMGPInfo); + widgetInfo = std::make_unique(); break; case SBIG('TBGP'): - widgetInfo.reset(new TBGPInfo); + widgetInfo = std::make_unique(); break; case SBIG('SLGP'): - widgetInfo.reset(new SLGPInfo); + widgetInfo = std::make_unique(); break; default: Log.report(logvisor::Fatal, fmt(_SYS_STR("Unsupported FRME widget type {}")), type); @@ -169,12 +169,13 @@ void FRME::Widget::Enumerate(size_t& __isz) { template <> void FRME::Widget::CAMRInfo::Enumerate(athena::io::IStreamReader& __dna_reader) { projectionType = ProjectionType(__dna_reader.readUint32Big()); - if (projectionType == ProjectionType::Perspective) - projection.reset(new PerspectiveProjection); - else if (projectionType == ProjectionType::Orthographic) - projection.reset(new OrthographicProjection); - else + if (projectionType == ProjectionType::Perspective) { + projection = std::make_unique(); + } else if (projectionType == ProjectionType::Orthographic) { + projection = std::make_unique(); + } else { Log.report(logvisor::Fatal, fmt(_SYS_STR("Invalid CAMR projection mode! {}")), int(projectionType)); + } projection->read(__dna_reader); } diff --git a/DataSpec/DNAMP1/PAK.cpp b/DataSpec/DNAMP1/PAK.cpp index f24d65721..4b7835662 100644 --- a/DataSpec/DNAMP1/PAK.cpp +++ b/DataSpec/DNAMP1/PAK.cpp @@ -97,8 +97,8 @@ std::unique_ptr PAK::Entry::getBuffer(const nod::Node& pak, atUint64& atUint32 decompSz; strm->read(&decompSz, 4); decompSz = hecl::SBig(decompSz); - atUint8* buf = new atUint8[decompSz]; - atUint8* bufCur = buf; + std::unique_ptr buf{new atUint8[decompSz]}; + atUint8* bufCur = buf.get(); atUint8 compBuf[0x8000]; if (compressed == 1) { @@ -106,7 +106,7 @@ std::unique_ptr PAK::Entry::getBuffer(const nod::Node& pak, atUint64& z_stream zs = {}; inflateInit(&zs); zs.avail_out = decompSz; - zs.next_out = buf; + zs.next_out = buf.get(); while (zs.avail_out) { atUint64 readSz = strm->read(compBuf, std::min(compRem, atUint32(0x8000))); compRem -= readSz; @@ -130,12 +130,12 @@ std::unique_ptr PAK::Entry::getBuffer(const nod::Node& pak, atUint64& } szOut = decompSz; - return std::unique_ptr(buf); + return buf; } else { - atUint8* buf = new atUint8[size]; - pak.beginReadStream(offset)->read(buf, size); + std::unique_ptr buf{new atUint8[size]}; + pak.beginReadStream(offset)->read(buf.get(), size); szOut = size; - return std::unique_ptr(buf); + return buf; } } diff --git a/DataSpec/DNAMP1/SCAN.cpp b/DataSpec/DNAMP1/SCAN.cpp index beabf6a5e..c09371284 100644 --- a/DataSpec/DNAMP1/SCAN.cpp +++ b/DataSpec/DNAMP1/SCAN.cpp @@ -1,12 +1,16 @@ #include "SCAN.hpp" +#include +#include + namespace DataSpec::DNAMP1 { -static const std::vector PaneNames = { - "imagepane_pane0", "imagepane_pane1", "imagepane_pane2", "imagepane_pane3", "imagepane_pane01", - "imagepane_pane12", "imagepane_pane23", "imagepane_pane012", "imagepane_pane123", "imagepane_pane0123", - "imagepane_pane4", "imagepane_pane5", "imagepane_pane6", "imagepane_pane7", "imagepane_pane45", - "imagepane_pane56", "imagepane_pane67", "imagepane_pane456", "imagepane_pane567", "imagepane_pane4567"}; +constexpr std::array PaneNames{ + "imagepane_pane0"sv, "imagepane_pane1"sv, "imagepane_pane2"sv, "imagepane_pane3"sv, "imagepane_pane01"sv, + "imagepane_pane12"sv, "imagepane_pane23"sv, "imagepane_pane012"sv, "imagepane_pane123"sv, "imagepane_pane0123"sv, + "imagepane_pane4"sv, "imagepane_pane5"sv, "imagepane_pane6"sv, "imagepane_pane7"sv, "imagepane_pane45"sv, + "imagepane_pane56"sv, "imagepane_pane67"sv, "imagepane_pane456"sv, "imagepane_pane567"sv, "imagepane_pane4567"sv, +}; template <> void SCAN::Texture::Enumerate(typename Read::StreamT& r) { diff --git a/DataSpec/DNAMP1/STRG.cpp b/DataSpec/DNAMP1/STRG.cpp index 4a52b3b17..6acf994ba 100644 --- a/DataSpec/DNAMP1/STRG.cpp +++ b/DataSpec/DNAMP1/STRG.cpp @@ -1,10 +1,14 @@ #include "STRG.hpp" + +#include + #include "DNAMP1.hpp" namespace DataSpec::DNAMP1 { -const std::vector skLanguages = {FOURCC('ENGL'), FOURCC('FREN'), FOURCC('GERM'), FOURCC('SPAN'), - FOURCC('ITAL'), FOURCC('DUTC'), FOURCC('JAPN')}; +constexpr std::array skLanguages{ + FOURCC('ENGL'), FOURCC('FREN'), FOURCC('GERM'), FOURCC('SPAN'), FOURCC('ITAL'), FOURCC('DUTC'), FOURCC('JAPN'), +}; static uint32_t ParseTag(const char16_t* str) { char parseStr[9]; diff --git a/DataSpec/DNAMP2/ANIM.cpp b/DataSpec/DNAMP2/ANIM.cpp index c2757f36a..333d543a1 100644 --- a/DataSpec/DNAMP2/ANIM.cpp +++ b/DataSpec/DNAMP2/ANIM.cpp @@ -126,11 +126,11 @@ void ANIM::Enumerate(typename Read::StreamT& reader) { atUint32 version = reader.readUint32Big(); switch (version) { case 0: - m_anim.reset(new struct ANIM0); + m_anim = std::make_unique(); m_anim->read(reader); break; case 2: - m_anim.reset(new struct ANIM2); + m_anim = std::make_unique(); m_anim->read(reader); break; default: diff --git a/DataSpec/DNAMP2/DNAMP2.cpp b/DataSpec/DNAMP2/DNAMP2.cpp index 779369826..63cc69754 100644 --- a/DataSpec/DNAMP2/DNAMP2.cpp +++ b/DataSpec/DNAMP2/DNAMP2.cpp @@ -153,7 +153,7 @@ void PAKBridge::build() { } void PAKBridge::addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const { - for (const std::pair& entry : m_pak.m_entries) { + for (const auto& entry : m_pak.m_entries) { if (entry.second.type == FOURCC('ANCS')) { PAKEntryReadStream rs = entry.second.beginReadStream(m_node); ANCS ancs; @@ -189,7 +189,7 @@ static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}}; void PAKBridge::addMAPATransforms(PAKRouter& pakRouter, std::unordered_map& addTo, std::unordered_map& pathOverrides) const { - for (const std::pair& entry : m_pak.m_entries) { + for (const auto& entry : m_pak.m_entries) { if (entry.second.type == FOURCC('MLVL')) { MLVL mlvl; { diff --git a/DataSpec/DNAMP2/STRG.cpp b/DataSpec/DNAMP2/STRG.cpp index 891c7b3da..30d0cb24a 100644 --- a/DataSpec/DNAMP2/STRG.cpp +++ b/DataSpec/DNAMP2/STRG.cpp @@ -67,8 +67,8 @@ void STRG::Enumerate(athena::io::IStreamWriter& writer) { writer.writeUint32Big(strCount); atUint32 offset = 0; - for (const std::pair>& lang : langs) { - lang.first.write(writer); + for (const auto& lang : langs) { + DNAFourCC{lang.first}.write(writer); writer.writeUint32Big(offset); offset += strCount * 4 + 4; atUint32 langStrCount = lang.second.size(); @@ -87,20 +87,22 @@ void STRG::Enumerate(athena::io::IStreamWriter& writer) { } atUint32 nameTableSz = names.size() * 8; - for (const std::pair& name : names) + for (const auto& name : names) { nameTableSz += name.first.size() + 1; + } writer.writeUint32Big(names.size()); writer.writeUint32Big(nameTableSz); offset = names.size() * 8; - for (const std::pair& name : names) { + for (const auto& name : names) { writer.writeUint32Big(offset); writer.writeInt32Big(name.second); offset += name.first.size() + 1; } - for (const std::pair& name : names) + for (const auto& name : names) { writer.writeString(name.first); + } - for (const std::pair>& lang : langs) { + for (const auto& lang : langs) { offset = strCount * 4; atUint32 langStrCount = lang.second.size(); for (atUint32 s = 0; s < strCount; ++s) { @@ -128,11 +130,12 @@ void STRG::Enumerate(size_t& __isz) { __isz += 8; __isz += names.size() * 8; - for (const std::pair& name : names) + for (const auto& name : names) { __isz += name.first.size() + 1; + } size_t strCount = STRG::count(); - for (const std::pair>& lang : langs) { + for (const auto& lang : langs) { atUint32 langStrCount = lang.second.size(); __isz += strCount * 4; diff --git a/DataSpec/DNAMP3/ANIM.cpp b/DataSpec/DNAMP3/ANIM.cpp index ab0b1bd8e..9abfea7ac 100644 --- a/DataSpec/DNAMP3/ANIM.cpp +++ b/DataSpec/DNAMP3/ANIM.cpp @@ -130,11 +130,11 @@ void ANIM::Enumerate(typename Read::StreamT& reader) { atUint32 version = reader.readUint32Big(); switch (version) { case 0: - m_anim.reset(new struct ANIM0); + m_anim = std::make_unique(); m_anim->read(reader); break; case 1: - m_anim.reset(new struct ANIM1); + m_anim = std::make_unique(); m_anim->read(reader); break; default: diff --git a/DataSpec/DNAMP3/CHAR.cpp b/DataSpec/DNAMP3/CHAR.cpp index 3836601d7..2f7324128 100644 --- a/DataSpec/DNAMP3/CHAR.cpp +++ b/DataSpec/DNAMP3/CHAR.cpp @@ -74,30 +74,30 @@ std::string_view CHAR::AnimationInfo::EVNT::SFXEvent::DNAType() { template <> void CHAR::AnimationInfo::MetaAnimFactory::Enumerate(athena::io::IStreamReader& reader) { - IMetaAnim::Type type(IMetaAnim::Type(reader.readUint32Big())); + const auto type = IMetaAnim::Type(reader.readUint32Big()); switch (type) { case IMetaAnim::Type::Primitive: - m_anim.reset(new struct MetaAnimPrimitive); + m_anim = std::make_unique(); m_anim->read(reader); break; case IMetaAnim::Type::Blend: - m_anim.reset(new struct MetaAnimBlend); + m_anim = std::make_unique(); m_anim->read(reader); break; case IMetaAnim::Type::PhaseBlend: - m_anim.reset(new struct MetaAnimPhaseBlend); + m_anim = std::make_unique(); m_anim->read(reader); break; case IMetaAnim::Type::Random: - m_anim.reset(new struct MetaAnimRandom); + m_anim = std::make_unique(); m_anim->read(reader); break; case IMetaAnim::Type::Sequence: - m_anim.reset(new struct MetaAnimSequence); + m_anim = std::make_unique(); m_anim->read(reader); break; default: - m_anim.reset(nullptr); + m_anim.reset(); break; } } @@ -123,22 +123,22 @@ void CHAR::AnimationInfo::MetaAnimFactory::Enumerate(athena::i std::string type = reader.readString("type"); std::transform(type.begin(), type.end(), type.begin(), tolower); if (type == "primitive") { - m_anim.reset(new struct MetaAnimPrimitive); + m_anim = std::make_unique(); m_anim->read(reader); } else if (type == "blend") { - m_anim.reset(new struct MetaAnimBlend); + m_anim = std::make_unique(); m_anim->read(reader); } else if (type == "phaseblend") { - m_anim.reset(new struct MetaAnimPhaseBlend); + m_anim = std::make_unique(); m_anim->read(reader); } else if (type == "random") { - m_anim.reset(new struct MetaAnimRandom); + m_anim = std::make_unique(); m_anim->read(reader); } else if (type == "sequence") { - m_anim.reset(new struct MetaAnimSequence); + m_anim = std::make_unique(); m_anim->read(reader); } else { - m_anim.reset(nullptr); + m_anim.reset(); } } diff --git a/DataSpec/DNAMP3/CMDLMaterials.cpp b/DataSpec/DNAMP3/CMDLMaterials.cpp index a6449dbf7..75f82dae7 100644 --- a/DataSpec/DNAMP3/CMDLMaterials.cpp +++ b/DataSpec/DNAMP3/CMDLMaterials.cpp @@ -12,19 +12,19 @@ void MaterialSet::Material::SectionFactory::Enumerate(typename Rea type.read(reader); switch (ISection::Type(type.toUint32())) { case ISection::Type::PASS: - section.reset(new struct SectionPASS); + section = std::make_unique(); section->read(reader); break; case ISection::Type::CLR: - section.reset(new struct SectionCLR); + section = std::make_unique(); section->read(reader); break; case ISection::Type::INT: - section.reset(new struct SectionINT); + section = std::make_unique(); section->read(reader); break; default: - section.reset(nullptr); + section.reset(); break; } } diff --git a/DataSpec/DNAMP3/DNAMP3.cpp b/DataSpec/DNAMP3/DNAMP3.cpp index 05158846c..a2b8199b0 100644 --- a/DataSpec/DNAMP3/DNAMP3.cpp +++ b/DataSpec/DNAMP3/DNAMP3.cpp @@ -157,7 +157,7 @@ void PAKBridge::build() { } void PAKBridge::addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const { - for (const std::pair& entry : m_pak.m_entries) { + for (const auto& entry : m_pak.m_entries) { if (entry.second.type == FOURCC('CHAR')) { PAKEntryReadStream rs = entry.second.beginReadStream(m_node); CHAR aChar; @@ -180,7 +180,7 @@ static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}}; void PAKBridge::addMAPATransforms(PAKRouter& pakRouter, std::unordered_map& addTo, std::unordered_map& pathOverrides) const { - for (const std::pair& entry : m_pak.m_entries) { + for (const auto& entry : m_pak.m_entries) { if (entry.second.type == FOURCC('MLVL')) { MLVL mlvl; { diff --git a/DataSpec/DNAMP3/PAK.cpp b/DataSpec/DNAMP3/PAK.cpp index 7ebd29659..2eddb7f08 100644 --- a/DataSpec/DNAMP3/PAK.cpp +++ b/DataSpec/DNAMP3/PAK.cpp @@ -142,7 +142,7 @@ std::unique_ptr PAK::Entry::getBuffer(const nod::Node& pak, atUint64& strm->read(&head, 8); if (head.magic != CMPD) { Log.report(logvisor::Error, fmt("invalid CMPD block")); - return std::unique_ptr(); + return nullptr; } head.blockCount = hecl::SBig(head.blockCount); @@ -165,8 +165,8 @@ std::unique_ptr PAK::Entry::getBuffer(const nod::Node& pak, atUint64& } std::unique_ptr compBuf(new atUint8[maxBlockSz]); - atUint8* buf = new atUint8[totalDecompSz]; - atUint8* bufCur = buf; + std::unique_ptr buf{new atUint8[totalDecompSz]}; + atUint8* bufCur = buf.get(); for (atUint32 b = 0; b < head.blockCount; ++b) { Block& block = blocks[b]; atUint8* compBufCur = compBuf.get(); @@ -189,12 +189,12 @@ std::unique_ptr PAK::Entry::getBuffer(const nod::Node& pak, atUint64& } szOut = totalDecompSz; - return std::unique_ptr(buf); + return buf; } else { - atUint8* buf = new atUint8[size]; - pak.beginReadStream(offset)->read(buf, size); + std::unique_ptr buf{new atUint8[size]}; + pak.beginReadStream(offset)->read(buf.get(), size); szOut = size; - return std::unique_ptr(buf); + return buf; } } diff --git a/DataSpec/DNAMP3/PAK.hpp b/DataSpec/DNAMP3/PAK.hpp index d45fe4785..298dc5770 100644 --- a/DataSpec/DNAMP3/PAK.hpp +++ b/DataSpec/DNAMP3/PAK.hpp @@ -61,7 +61,7 @@ struct PAK : BigDNA { bool mreaHasDupeResources(const UniqueID64& id) const { return m_dupeMREAs.find(id) != m_dupeMREAs.cend(); } - typedef UniqueID64 IDType; + using IDType = UniqueID64; }; } // namespace DataSpec::DNAMP3 diff --git a/DataSpec/SpecMP1.cpp b/DataSpec/SpecMP1.cpp index ddf973351..c98a0a940 100644 --- a/DataSpec/SpecMP1.cpp +++ b/DataSpec/SpecMP1.cpp @@ -108,7 +108,7 @@ struct TextureCache { auto rec = r.enterSubRecord(node.first.c_str()); TXTR::Meta meta; meta.read(r); - metaPairs.push_back(std::make_pair(projectPath.parsedHash32(), meta)); + metaPairs.emplace_back(projectPath.parsedHash32(), meta); } std::sort(metaPairs.begin(), metaPairs.end(), [](const auto& a, const auto& b) -> bool { @@ -201,11 +201,12 @@ struct SpecMP1 : SpecBase { /* Assemble extract report */ rep.childOpts.reserve(m_orderedPaks.size()); - for (const std::pair& item : m_orderedPaks) { - if (!item.second->m_doExtract) + for (const auto& item : m_orderedPaks) { + if (!item.second->m_doExtract) { continue; - rep.childOpts.emplace_back(); - ExtractReport& childRep = rep.childOpts.back(); + } + + ExtractReport& childRep = rep.childOpts.emplace_back(); hecl::SystemStringConv nameView(item.first); childRep.name = nameView.sys_str(); childRep.desc = item.second->getLevelString(); @@ -222,8 +223,7 @@ struct SpecMP1 : SpecBase { return false; /* Root Report */ - reps.emplace_back(); - ExtractReport& rep = reps.back(); + ExtractReport& rep = reps.emplace_back(); rep.name = _SYS_STR("MP1"); rep.desc = _SYS_STR("Metroid Prime ") + regstr; if (buildInfo) { @@ -277,8 +277,7 @@ struct SpecMP1 : SpecBase { const char* buildInfo = (char*)memmem(m_dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16) + 19; /* Root Report */ - reps.emplace_back(); - ExtractReport& rep = reps.back(); + ExtractReport& rep = reps.emplace_back(); rep.name = _SYS_STR("MP1"); rep.desc = _SYS_STR("Metroid Prime ") + regstr; if (buildInfo) { @@ -1023,7 +1022,7 @@ struct SpecMP1 : SpecBase { for (const auto& dep : area.deps) { urde::CAssetId newId = dep.id.toUint64(); if (dupeRes || addedTags.find(newId) == addedTags.end()) { - listOut.push_back({dep.type, newId}); + listOut.emplace_back(dep.type, newId); addedTags.insert(newId); } } @@ -1083,7 +1082,7 @@ struct SpecMP1 : SpecBase { for (atUint32 i = 0; i < mapaCount; ++i) { UniqueID32 id; id.read(r); - listOut.push_back({FOURCC('MAPA'), id.toUint64()}); + listOut.emplace_back(FOURCC('MAPA'), id.toUint64()); } } } diff --git a/DataSpec/SpecMP2.cpp b/DataSpec/SpecMP2.cpp index c15acc6e0..d013ca9ab 100644 --- a/DataSpec/SpecMP2.cpp +++ b/DataSpec/SpecMP2.cpp @@ -103,11 +103,12 @@ struct SpecMP2 : SpecBase { m_orderedPaks[std::string(dpak.getName())] = &dpak; /* Assemble extract report */ - for (const std::pair& item : m_orderedPaks) { - if (!item.second->m_doExtract) + for (const auto& item : m_orderedPaks) { + if (!item.second->m_doExtract) { continue; - rep.childOpts.emplace_back(); - ExtractReport& childRep = rep.childOpts.back(); + } + + ExtractReport& childRep = rep.childOpts.emplace_back(); hecl::SystemStringConv nameView(item.first); childRep.name = hecl::SystemString(nameView.sys_str()); childRep.desc = item.second->getLevelString(); @@ -123,8 +124,7 @@ struct SpecMP2 : SpecBase { return false; /* Root Report */ - reps.emplace_back(); - ExtractReport& rep = reps.back(); + ExtractReport& rep = reps.emplace_back(); rep.name = _SYS_STR("MP2"); rep.desc = _SYS_STR("Metroid Prime 2 ") + regstr; std::string buildStr(buildInfo); @@ -176,8 +176,7 @@ struct SpecMP2 : SpecBase { const char* buildInfo = (char*)memmem(dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16) + 19; /* Root Report */ - reps.emplace_back(); - ExtractReport& rep = reps.back(); + ExtractReport& rep = reps.emplace_back(); rep.name = _SYS_STR("MP2"); rep.desc = _SYS_STR("Metroid Prime 2 ") + regstr; if (buildInfo) { diff --git a/DataSpec/SpecMP3.cpp b/DataSpec/SpecMP3.cpp index 4429e6ee9..632d3c68d 100644 --- a/DataSpec/SpecMP3.cpp +++ b/DataSpec/SpecMP3.cpp @@ -132,11 +132,11 @@ struct SpecMP3 : SpecBase { } /* Assemble extract report */ - for (const std::pair& item : fe ? m_feOrderedPaks : m_orderedPaks) { + for (const auto& item : fe ? m_feOrderedPaks : m_orderedPaks) { if (!item.second->m_doExtract) continue; - rep.childOpts.emplace_back(); - ExtractReport& childRep = rep.childOpts.back(); + + ExtractReport& childRep = rep.childOpts.emplace_back(); hecl::SystemStringConv nameView(item.first); childRep.name = hecl::SystemString(nameView.sys_str()); if (item.first == "Worlds.pak") @@ -168,8 +168,7 @@ struct SpecMP3 : SpecBase { return false; /* Root Report */ - reps.emplace_back(); - ExtractReport& rep = reps.back(); + ExtractReport& rep = reps.emplace_back(); rep.name = _SYS_STR("MP3"); rep.desc = _SYS_STR("Metroid Prime 3 ") + regstr; std::string buildStr(buildInfo); @@ -250,8 +249,7 @@ struct SpecMP3 : SpecBase { } /* Root Report */ - reps.emplace_back(); - ExtractReport& rep = reps.back(); + ExtractReport& rep = reps.emplace_back(); rep.name = _SYS_STR("MP3"); rep.desc = _SYS_STR("Metroid Prime 3 ") + regstr; @@ -281,8 +279,7 @@ struct SpecMP3 : SpecBase { const char* buildInfo = (char*)memmem(dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16) + 19; /* Root Report */ - reps.emplace_back(); - ExtractReport& rep = reps.back(); + ExtractReport& rep = reps.emplace_back(); rep.name = _SYS_STR("fe"); rep.desc = _SYS_STR("Metroid Prime Trilogy Frontend ") + regstr; if (buildInfo) { @@ -305,7 +302,7 @@ struct SpecMP3 : SpecBase { } bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) override { - hecl::SystemString currentTarget = _SYS_STR(""); + hecl::SystemString currentTarget; size_t nodeCount = 0; int prog = 0; nod::ExtractionContext ctx = {force, [&](std::string_view name, float) { @@ -394,7 +391,7 @@ struct SpecMP3 : SpecBase { progress.startNewLine(); hecl::ClientProcess process; - for (std::pair pair : m_feOrderedPaks) { + for (auto& pair : m_feOrderedPaks) { DNAMP3::PAKBridge& pak = *pair.second; if (!pak.m_doExtract) continue; diff --git a/Runtime/Audio/CAudioGroupSet.cpp b/Runtime/Audio/CAudioGroupSet.cpp index 64910da34..db20e67c8 100644 --- a/Runtime/Audio/CAudioGroupSet.cpp +++ b/Runtime/Audio/CAudioGroupSet.cpp @@ -1,23 +1,31 @@ #include "Runtime/Audio/CAudioGroupSet.hpp" +#include + namespace urde { amuse::AudioGroupData CAudioGroupSet::LoadData() { + const auto readU32 = [](const u8* ptr) { + uint32_t value; + std::memcpy(&value, ptr, sizeof(value)); + return hecl::SBig(value); + }; + athena::io::MemoryReader r(m_buffer.get(), INT32_MAX); x10_baseName = r.readString(); x20_name = r.readString(); u8* buf = m_buffer.get() + r.position(); - uint32_t poolLen = hecl::SBig(*reinterpret_cast(buf)); + const uint32_t poolLen = readU32(buf); unsigned char* pool = buf + 4; buf += poolLen + 4; - uint32_t projLen = hecl::SBig(*reinterpret_cast(buf)); + const uint32_t projLen = readU32(buf); unsigned char* proj = buf + 4; buf += projLen + 4; - uint32_t sampLen = hecl::SBig(*reinterpret_cast(buf)); + const uint32_t sampLen = readU32(buf); unsigned char* samp = buf + 4; buf += sampLen + 4; - uint32_t sdirLen = hecl::SBig(*reinterpret_cast(buf)); + const uint32_t sdirLen = readU32(buf); unsigned char* sdir = buf + 4; return {proj, projLen, pool, poolLen, sdir, sdirLen, samp, sampLen, amuse::GCNDataTag{}}; diff --git a/Runtime/Audio/CAudioGroupSet.hpp b/Runtime/Audio/CAudioGroupSet.hpp index ef9d37f2e..d0b8c968b 100644 --- a/Runtime/Audio/CAudioGroupSet.hpp +++ b/Runtime/Audio/CAudioGroupSet.hpp @@ -21,7 +21,7 @@ class CAudioGroupSet { amuse::AudioGroupData LoadData(); public: - CAudioGroupSet(std::unique_ptr&& in); + explicit CAudioGroupSet(std::unique_ptr&& in); const amuse::AudioGroupData& GetAudioGroupData() const { return m_data; } std::string_view GetName() const { return x20_name; } }; diff --git a/Runtime/Audio/CMidiManager.hpp b/Runtime/Audio/CMidiManager.hpp index ebf757d5c..75b915473 100644 --- a/Runtime/Audio/CMidiManager.hpp +++ b/Runtime/Audio/CMidiManager.hpp @@ -19,7 +19,7 @@ public: u16 GetGroupId() const { return x2_groupId; } CAssetId GetAGSCAssetId() const { return x4_agscId; } const u8* GetArrData() const { return x8_arrData.get(); } - CMidiData(CInputStream& in); + explicit CMidiData(CInputStream& in); }; class CMidiWrapper { diff --git a/Runtime/Audio/CSfxManager.cpp b/Runtime/Audio/CSfxManager.cpp index ae5a77bca..91ece74d9 100644 --- a/Runtime/Audio/CSfxManager.cpp +++ b/Runtime/Audio/CSfxManager.cpp @@ -26,7 +26,7 @@ CFactoryFnReturn FAudioTranslationTableFactory(const SObjectTag& tag, CInputStre return TToken>::GetIObjObjectFor(std::move(obj)); } -CSfxManager::CSfxChannel CSfxManager::m_channels[4]; +std::array CSfxManager::m_channels; CSfxManager::ESfxChannels CSfxManager::m_currentChannel = CSfxManager::ESfxChannels::Default; bool CSfxManager::m_doUpdate; void* CSfxManager::m_usedSounds; @@ -186,7 +186,7 @@ void CSfxManager::SetChannel(ESfxChannels chan) { } void CSfxManager::KillAll(ESfxChannels chan) { - CSfxChannel& chanObj = m_channels[int(chan)]; + CSfxChannel& chanObj = m_channels[size_t(chan)]; for (auto it = chanObj.x48_handles.begin(); it != chanObj.x48_handles.end();) { const CSfxHandle& handle = *it; handle->Stop(); @@ -197,7 +197,7 @@ void CSfxManager::KillAll(ESfxChannels chan) { } void CSfxManager::TurnOnChannel(ESfxChannels chan) { - CSfxChannel& chanObj = m_channels[int(chan)]; + CSfxChannel& chanObj = m_channels[size_t(chan)]; m_currentChannel = chan; m_doUpdate = true; if (chanObj.x44_listenerActive) { @@ -208,7 +208,7 @@ void CSfxManager::TurnOnChannel(ESfxChannels chan) { } void CSfxManager::TurnOffChannel(ESfxChannels chan) { - CSfxChannel& chanObj = m_channels[int(chan)]; + CSfxChannel& chanObj = m_channels[size_t(chan)]; for (auto it = chanObj.x48_handles.begin(); it != chanObj.x48_handles.end();) { const CSfxHandle& handle = *it; if (handle->IsLooped()) { @@ -260,24 +260,29 @@ void CSfxManager::UpdateListener(const zeus::CVector3f& pos, const zeus::CVector } s16 CSfxManager::GetRank(CBaseSfxWrapper* sfx) { - CSfxChannel& chanObj = m_channels[int(m_currentChannel)]; - if (!sfx->IsInArea()) + const CSfxChannel& chanObj = m_channels[size_t(m_currentChannel)]; + if (!sfx->IsInArea()) { return 0; + } s16 rank = sfx->GetPriority() / 4; - if (sfx->IsPlaying()) + if (sfx->IsPlaying()) { ++rank; + } - if (sfx->IsLooped()) + if (sfx->IsLooped()) { rank -= 2; + } - if (sfx->Ready() && !sfx->IsPlaying()) + if (sfx->Ready() && !sfx->IsPlaying()) { rank += 3; + } if (chanObj.x44_listenerActive) { - ESfxAudibility aud = sfx->GetAudible(chanObj.x0_pos); - if (aud == ESfxAudibility::Aud0) + const ESfxAudibility aud = sfx->GetAudible(chanObj.x0_pos); + if (aud == ESfxAudibility::Aud0) { return 0; + } rank += int(aud) / 2; } @@ -285,7 +290,7 @@ s16 CSfxManager::GetRank(CBaseSfxWrapper* sfx) { } void CSfxManager::ApplyReverb() { - CSfxChannel& chanObj = m_channels[int(m_currentChannel)]; + const CSfxChannel& chanObj = m_channels[size_t(m_currentChannel)]; for (const CSfxHandle& handle : chanObj.x48_handles) { handle->SetReverb(m_reverbAmount); } @@ -344,7 +349,7 @@ void CSfxManager::StopSound(const CSfxHandle& handle) { m_doUpdate = true; handle->Stop(); handle->Release(); - CSfxChannel& chanObj = m_channels[int(m_currentChannel)]; + CSfxChannel& chanObj = m_channels[size_t(m_currentChannel)]; handle->Close(); chanObj.x48_handles.erase(handle); } @@ -357,7 +362,7 @@ CSfxHandle CSfxManager::SfxStart(u16 id, float vol, float pan, bool useAcoustics m_doUpdate = true; CSfxHandle wrapper = std::make_shared(looped, prio, id, vol, pan, useAcoustics, areaId); - CSfxChannel& chanObj = m_channels[int(m_currentChannel)]; + CSfxChannel& chanObj = m_channels[size_t(m_currentChannel)]; chanObj.x48_handles.insert(wrapper); return wrapper; } @@ -428,14 +433,13 @@ CSfxHandle CSfxManager::AddEmitter(const CAudioSys::C3DEmitterParmData& parmData data.x20_flags |= 0x6; // Pausable/restartable when inaudible m_doUpdate = true; CSfxHandle wrapper = std::make_shared(looped, prio, data, useAcoustics, areaId); - CSfxChannel& chanObj = m_channels[int(m_currentChannel)]; + CSfxChannel& chanObj = m_channels[size_t(m_currentChannel)]; chanObj.x48_handles.insert(wrapper); return wrapper; } void CSfxManager::StopAndRemoveAllEmitters() { - for (int i = 0; i < 4; ++i) { - CSfxChannel& chanObj = m_channels[i]; + for (auto& chanObj : m_channels) { for (auto it = chanObj.x48_handles.begin(); it != chanObj.x48_handles.end();) { const CSfxHandle& handle = *it; handle->Stop(); @@ -538,15 +542,15 @@ void CSfxManager::DisableAuxProcessing() { } void CSfxManager::SetActiveAreas(const rstl::reserved_vector& areas) { - CSfxChannel& chanObj = m_channels[int(m_currentChannel)]; + const CSfxChannel& chanObj = m_channels[size_t(m_currentChannel)]; for (const CSfxHandle& hnd : chanObj.x48_handles) { - TAreaId sndArea = hnd->GetArea(); + const TAreaId sndArea = hnd->GetArea(); if (sndArea == kInvalidAreaId) { hnd->SetInArea(true); } else { bool inArea = false; - for (TAreaId id : areas) { + for (const TAreaId id : areas) { if (sndArea == id) { inArea = true; break; @@ -559,7 +563,7 @@ void CSfxManager::SetActiveAreas(const rstl::reserved_vector& areas } void CSfxManager::Update(float dt) { - CSfxChannel& chanObj = m_channels[int(m_currentChannel)]; + CSfxChannel& chanObj = m_channels[size_t(m_currentChannel)]; for (auto it = chanObj.x48_handles.begin(); it != chanObj.x48_handles.end();) { const CSfxHandle& handle = *it; diff --git a/Runtime/Audio/CSfxManager.hpp b/Runtime/Audio/CSfxManager.hpp index 9d13697c9..2e4e6a155 100644 --- a/Runtime/Audio/CSfxManager.hpp +++ b/Runtime/Audio/CSfxManager.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -109,8 +110,7 @@ public: void SetTimeRemaining(float t) { x4_timeRemaining = t; } CBaseSfxWrapper(bool looped, s16 prio, /*const CSfxHandle& handle,*/ bool useAcoustics, TAreaId area) - : x8_rank(0) - , xa_prio(prio) + : xa_prio(prio) , /*xc_handle(handle),*/ x10_area(area) , x14_24_isActive(true) , x14_25_isPlaying(false) @@ -118,15 +118,16 @@ public: , x14_27_inArea(true) , x14_28_isReleased(false) , x14_29_useAcoustics(useAcoustics) + , m_isEmitter(false) , m_isClosed(false) {} }; class CSfxEmitterWrapper : public CBaseSfxWrapper { - float x1a_reverb; + float x1a_reverb = 0.0f; CAudioSys::C3DEmitterParmData x24_parmData; amuse::ObjToken x50_emitterHandle; bool x54_ready = true; - float x55_cachedMaxVol; + float x55_cachedMaxVol = 0.0f; public: bool IsPlaying() const override; @@ -177,7 +178,7 @@ public: } }; - static CSfxChannel m_channels[4]; + static std::array m_channels; static ESfxChannels m_currentChannel; static bool m_doUpdate; static void* m_usedSounds; diff --git a/Runtime/Audio/CStaticAudioPlayer.hpp b/Runtime/Audio/CStaticAudioPlayer.hpp index b2ee5551e..8ffb59460 100644 --- a/Runtime/Audio/CStaticAudioPlayer.hpp +++ b/Runtime/Audio/CStaticAudioPlayer.hpp @@ -53,7 +53,7 @@ class CStaticAudioPlayer { memset(data, 0, 4 * frames); return frames; } - AudioVoiceCallback(CStaticAudioPlayer& p) : m_parent(p) {} + explicit AudioVoiceCallback(CStaticAudioPlayer& p) : m_parent(p) {} } m_voiceCallback; boo::ObjToken m_voice; diff --git a/Runtime/Audio/CStreamAudioManager.cpp b/Runtime/Audio/CStreamAudioManager.cpp index adf9d3175..51ee8d788 100644 --- a/Runtime/Audio/CStreamAudioManager.cpp +++ b/Runtime/Audio/CStreamAudioManager.cpp @@ -6,6 +6,7 @@ #include "Runtime/CStringExtras.hpp" #include +#include #include #include #include @@ -36,7 +37,7 @@ struct dspadpcm_header { s16 x44_loop_ps; s16 x46_loop_hist1; s16 x48_loop_hist2; - u16 x4a_pad[11]; + std::array x4a_pad; }; struct SDSPStreamInfo { @@ -50,7 +51,7 @@ struct SDSPStreamInfo { s16 x1c_coef[8][2]; SDSPStreamInfo() = default; - SDSPStreamInfo(const CDSPStreamManager& stream); + explicit SDSPStreamInfo(const CDSPStreamManager& stream); }; struct SDSPStream : boo::IAudioVoiceCallback { @@ -74,7 +75,7 @@ struct SDSPStream : boo::IAudioVoiceCallback { u8 xec_readState = 0; // 0: NoRead 1: Read 2: ReadWrap std::optional m_file; - std::shared_ptr m_readReqs[2]; + std::array, 2> m_readReqs; void ReadBuffer(int buf) { u32 halfSize = xd8_ringBytes / 2; @@ -242,7 +243,7 @@ struct SDSPStream : boo::IAudioVoiceCallback { } static void Initialize() { - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < g_Streams.size(); ++i) { SDSPStream& stream = g_Streams[i]; stream.x0_active = false; stream.xd4_ringBuffer.reset(); @@ -258,29 +259,30 @@ struct SDSPStream : boo::IAudioVoiceCallback { } static void FreeAllStreams() { - for (int i = 0; i < 4; ++i) { - SDSPStream& stream = g_Streams[i]; + for (auto& stream : g_Streams) { stream.m_booVoice.reset(); stream.x0_active = false; - for (int j = 0; j < 2; ++j) - if (stream.m_readReqs[j]) { - stream.m_readReqs[j]->PostCancelRequest(); - stream.m_readReqs[j].reset(); + for (auto& request : stream.m_readReqs) { + if (request) { + request->PostCancelRequest(); + request.reset(); } + } stream.xd4_ringBuffer.reset(); stream.m_file = std::nullopt; } } static s32 PickFreeStream(SDSPStream*& streamOut, bool oneshot) { - for (int i = 0; i < 4; ++i) { - SDSPStream& stream = g_Streams[i]; - if (stream.x0_active || stream.x1_oneshot != oneshot) + for (auto& stream : g_Streams) { + if (stream.x0_active || stream.x1_oneshot != oneshot) { continue; + } stream.x0_active = true; stream.x4_ownerId = ++s_HandleCounter2; - if (stream.x4_ownerId == -1) + if (stream.x4_ownerId == -1) { stream.x4_ownerId = ++s_HandleCounter2; + } stream.x8_stereoLeft = nullptr; stream.xc_companionRight = nullptr; streamOut = &stream; @@ -290,22 +292,24 @@ struct SDSPStream : boo::IAudioVoiceCallback { } static s32 FindStreamIdx(s32 id) { - for (s32 i = 0; i < 4; ++i) { - SDSPStream& stream = g_Streams[i]; - if (stream.x4_ownerId == id) - return i; + for (size_t i = 0; i < g_Streams.size(); ++i) { + const SDSPStream& stream = g_Streams[i]; + if (stream.x4_ownerId == id) { + return s32(i); + } } return -1; } void UpdateStreamVolume(float vol) { x4c_vol = vol; - if (!x0_active || xe8_silent) + if (!x0_active || xe8_silent) { return; - float coefs[8] = {}; - coefs[int(boo::AudioChannel::FrontLeft)] = m_leftgain * vol; - coefs[int(boo::AudioChannel::FrontRight)] = m_rightgain * vol; - m_booVoice->setMonoChannelLevels(nullptr, coefs, true); + } + std::array coefs{}; + coefs[size_t(boo::AudioChannel::FrontLeft)] = m_leftgain * vol; + coefs[size_t(boo::AudioChannel::FrontRight)] = m_rightgain * vol; + m_booVoice->setMonoChannelLevels(nullptr, coefs.data(), true); } static void UpdateVolume(s32 id, float vol) { @@ -322,10 +326,11 @@ struct SDSPStream : boo::IAudioVoiceCallback { } void SilenceStream() { - if (!x0_active || xe8_silent) + if (!x0_active || xe8_silent) { return; - float coefs[8] = {}; - m_booVoice->setMonoChannelLevels(nullptr, coefs, true); + } + constexpr std::array coefs{}; + m_booVoice->setMonoChannelLevels(nullptr, coefs.data(), true); xe8_silent = true; x0_active = false; } @@ -399,13 +404,15 @@ struct SDSPStream : boo::IAudioVoiceCallback { void AllocateStream(const SDSPStreamInfo& info, float vol, float left, float right) { x10_info = info; m_file.emplace(x10_info.x0_fileName); - if (!xd4_ringBuffer) + if (!xd4_ringBuffer) { DoAllocateStream(); - for (int j = 0; j < 2; ++j) - if (m_readReqs[j]) { - m_readReqs[j]->PostCancelRequest(); - m_readReqs[j].reset(); + } + for (auto& request : m_readReqs) { + if (request) { + request->PostCancelRequest(); + request.reset(); } + } x4c_vol = vol; m_leftgain = left; m_rightgain = right; @@ -425,10 +432,10 @@ struct SDSPStream : boo::IAudioVoiceCallback { UpdateStreamVolume(vol); } - static SDSPStream g_Streams[4]; + static std::array g_Streams; }; -SDSPStream SDSPStream::g_Streams[4] = {}; +std::array SDSPStream::g_Streams{}; class CDSPStreamManager { friend struct SDSPStreamInfo; @@ -450,12 +457,12 @@ private: s8 x71_companionRight = -1; s8 x72_companionLeft = -1; float x73_volume = 0.f; - bool x74_oneshot; + bool x74_oneshot = false; s32 x78_handleId = -1; // arg2 s32 x7c_streamId = -1; std::shared_ptr m_dvdReq; // DVDFileInfo x80_dvdHandle; - static CDSPStreamManager g_Streams[4]; + static std::array g_Streams; public: CDSPStreamManager() { x70_24_unclaimed = true; } @@ -467,22 +474,23 @@ public: } static s32 FindUnclaimedStreamIdx() { - for (s32 i = 0; i < 4; ++i) { - CDSPStreamManager& stream = g_Streams[i]; - if (stream.x70_24_unclaimed) - return i; + for (size_t i = 0; i < g_Streams.size(); ++i) { + const CDSPStreamManager& stream = g_Streams[i]; + if (stream.x70_24_unclaimed) { + return s32(i); + } } return -1; } static bool FindUnclaimedStereoPair(s32& left, s32& right) { - s32 idx = FindUnclaimedStreamIdx(); + const s32 idx = FindUnclaimedStreamIdx(); - for (s32 i = 0; i < 4; ++i) { + for (size_t i = 0; i < g_Streams.size(); ++i) { CDSPStreamManager& stream = g_Streams[i]; - if (stream.x70_24_unclaimed && idx != i) { + if (stream.x70_24_unclaimed && idx != s32(i)) { left = idx; - right = i; + right = s32(i); return true; } } @@ -491,10 +499,11 @@ public: } static s32 FindClaimedStreamIdx(s32 handle) { - for (s32 i = 0; i < 4; ++i) { - CDSPStreamManager& stream = g_Streams[i]; - if (!stream.x70_24_unclaimed && stream.x78_handleId == handle) + for (size_t i = 0; i < g_Streams.size(); ++i) { + const CDSPStreamManager& stream = g_Streams[i]; + if (!stream.x70_24_unclaimed && stream.x78_handleId == handle) { return i; + } } return -1; } @@ -510,8 +519,7 @@ public: continue; } - for (int i = 0; i < 4; ++i) { - CDSPStreamManager& stream = g_Streams[i]; + for (auto& stream : g_Streams) { if (!stream.x70_24_unclaimed && stream.x78_handleId == handle) { good = false; break; @@ -595,9 +603,9 @@ public: void HeaderReadComplete() { s32 selfIdx = -1; - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < g_Streams.size(); ++i) { if (this == &g_Streams[i]) { - selfIdx = i; + selfIdx = s32(i); break; } } @@ -641,8 +649,7 @@ public: } static void PollHeaderReadCompletions() { - for (int i = 0; i < 4; ++i) { - CDSPStreamManager& stream = g_Streams[i]; + for (auto& stream : g_Streams) { if (stream.m_dvdReq && stream.m_dvdReq->IsComplete()) { stream.m_dvdReq.reset(); stream.HeaderReadComplete(); @@ -790,22 +797,20 @@ public: static void Initialize() { SDSPStream::Initialize(); - for (int i = 0; i < 4; ++i) { - CDSPStreamManager& stream = g_Streams[i]; + for (auto& stream : g_Streams) { stream = CDSPStreamManager(); } } static void Shutdown() { SDSPStream::FreeAllStreams(); - for (int i = 0; i < 4; ++i) { - CDSPStreamManager& stream = g_Streams[i]; + for (auto& stream : g_Streams) { stream = CDSPStreamManager(); } } }; -CDSPStreamManager CDSPStreamManager::g_Streams[4] = {}; +std::array CDSPStreamManager::g_Streams{}; SDSPStreamInfo::SDSPStreamInfo(const CDSPStreamManager& stream) { x0_fileName = stream.x60_fileName.c_str(); @@ -853,8 +858,10 @@ struct SDSPPlayer { , x20_internalHandle(handle) , x28_music(music) {} }; -static SDSPPlayer s_Players[2]; // looping, oneshot -static SDSPPlayer s_QueuedPlayers[2]; // looping, oneshot + +using PlayerArray = std::array; +static PlayerArray s_Players; // looping, oneshot +static PlayerArray s_QueuedPlayers; // looping, oneshot float CStreamAudioManager::GetTargetDSPVolume(float fileVol, bool music) { if (music) @@ -1000,7 +1007,7 @@ void CStreamAudioManager::UpdateDSPStreamers(float dt) { } void CStreamAudioManager::StopAllStreams() { - for (int i = 0; i < 2; ++i) { + for (size_t i = 0; i < s_Players.size(); ++i) { StopStreaming(bool(i)); SDSPPlayer& p = s_Players[i]; SDSPPlayer& qp = s_QueuedPlayers[i]; diff --git a/Runtime/AutoMapper/CAutoMapper.cpp b/Runtime/AutoMapper/CAutoMapper.cpp index c3999b055..487b48324 100644 --- a/Runtime/AutoMapper/CAutoMapper.cpp +++ b/Runtime/AutoMapper/CAutoMapper.cpp @@ -158,7 +158,7 @@ bool CAutoMapper::CanLeaveMapScreenInternal(const CStateManager& mgr) const { return false; } -void CAutoMapper::LeaveMapScreen(const CStateManager& mgr) { +void CAutoMapper::LeaveMapScreen(CStateManager& mgr) { if (x1c0_nextState == EAutoMapperState::MapScreenUniverse) { xa8_renderStates[1].x2c_drawDepth1 = GetMapAreaMiniMapDrawDepth(); xa8_renderStates[1].x30_drawDepth2 = GetMapAreaMiniMapDrawDepth(); @@ -180,9 +180,9 @@ void CAutoMapper::LeaveMapScreen(const CStateManager& mgr) { } } -void CAutoMapper::SetupMiniMapWorld(const CStateManager& mgr) { - const CWorld& wld = *mgr.GetWorld(); - const_cast(wld.GetMapWorld())->SetWhichMapAreasLoaded(wld, wld.GetCurrentAreaId(), 3); +void CAutoMapper::SetupMiniMapWorld(CStateManager& mgr) { + CWorld& wld = *mgr.GetWorld(); + wld.GetMapWorld()->SetWhichMapAreasLoaded(wld, wld.GetCurrentAreaId(), 3); x328_ = 3; } @@ -194,7 +194,7 @@ bool CAutoMapper::HasCurrentMapUniverseWorld() const { return false; } -bool CAutoMapper::CheckDummyWorldLoad(const CStateManager& mgr) { +bool CAutoMapper::CheckDummyWorldLoad(CStateManager& mgr) { const CMapUniverse::CMapWorldData& mapuWld = x8_mapu->GetMapWorldData(x9c_worldIdx); auto& dummyWorld = x14_dummyWorlds[x9c_worldIdx]; if (!dummyWorld) { @@ -216,13 +216,13 @@ bool CAutoMapper::CheckDummyWorldLoad(const CStateManager& mgr) { } xa0_curAreaId = aid; - dummyWorld->IMapWorld()->RecalculateWorldSphere(mwInfo, *dummyWorld); + dummyWorld->IGetMapWorld()->RecalculateWorldSphere(mwInfo, *dummyWorld); BeginMapperStateTransition(EAutoMapperState::MapScreen, mgr); x32c_loadingDummyWorld = false; return true; } -void CAutoMapper::UpdateHintNavigation(float dt, const CStateManager& mgr) { +void CAutoMapper::UpdateHintNavigation(float dt, CStateManager& mgr) { SAutoMapperHintStep& nextStep = x1e0_hintSteps.front(); bool oldProcessing = nextStep.x8_processing; nextStep.x8_processing = true; @@ -321,7 +321,7 @@ void CAutoMapper::SetCurWorldAssetId(CAssetId mlvlId) { } } -void CAutoMapper::BeginMapperStateTransition(EAutoMapperState state, const CStateManager& mgr) { +void CAutoMapper::BeginMapperStateTransition(EAutoMapperState state, CStateManager& mgr) { if (state == x1c0_nextState) return; if ((state == EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap) || @@ -372,7 +372,7 @@ void CAutoMapper::BeginMapperStateTransition(EAutoMapperState state, const CStat } } -void CAutoMapper::CompleteMapperStateTransition(const CStateManager& mgr) { +void CAutoMapper::CompleteMapperStateTransition(CStateManager& mgr) { if (x1bc_state == EAutoMapperState::MapScreenUniverse) TransformRenderStatesUniverseToWorld(); @@ -407,8 +407,8 @@ void CAutoMapper::CompleteMapperStateTransition(const CStateManager& mgr) { x1bc_state = x1c0_nextState; } -void CAutoMapper::ResetInterpolationTimer(float t) { - x1c4_interpDur = t; +void CAutoMapper::ResetInterpolationTimer(float duration) { + x1c4_interpDur = duration; x1c8_interpTime = 0.f; } @@ -754,8 +754,8 @@ void CAutoMapper::ProcessMapPanInput(const CFinalInput& input, const CStateManag } } -void CAutoMapper::SetShouldPanningSoundBePlaying(bool b) { - if (b) { +void CAutoMapper::SetShouldPanningSoundBePlaying(bool shouldBePlaying) { + if (shouldBePlaying) { if (!x1cc_panningSfx) x1cc_panningSfx = CSfxManager::SfxStart(SFXui_map_pan, 1.f, 0.f, false, 0x7f, true, kInvalidAreaId); } else { @@ -764,8 +764,8 @@ void CAutoMapper::SetShouldPanningSoundBePlaying(bool b) { } } -void CAutoMapper::SetShouldZoomingSoundBePlaying(bool b) { - if (b) { +void CAutoMapper::SetShouldZoomingSoundBePlaying(bool shouldBePlaying) { + if (shouldBePlaying) { if (!x1d4_zoomingSfx) x1d4_zoomingSfx = CSfxManager::SfxStart(SFXui_map_zoom, 1.f, 0.f, false, 0x7f, true, kInvalidAreaId); } else { @@ -774,8 +774,8 @@ void CAutoMapper::SetShouldZoomingSoundBePlaying(bool b) { } } -void CAutoMapper::SetShouldRotatingSoundBePlaying(bool b) { - if (b) { +void CAutoMapper::SetShouldRotatingSoundBePlaying(bool shouldBePlaying) { + if (shouldBePlaying) { if (!x1d0_rotatingSfx) x1d0_rotatingSfx = CSfxManager::SfxStart(SFXui_map_rotate, 1.f, 0.f, false, 0x7f, true, kInvalidAreaId); } else { @@ -784,7 +784,7 @@ void CAutoMapper::SetShouldRotatingSoundBePlaying(bool b) { } } -void CAutoMapper::ProcessMapScreenInput(const CFinalInput& input, const CStateManager& mgr) { +void CAutoMapper::ProcessMapScreenInput(const CFinalInput& input, CStateManager& mgr) { zeus::CMatrix3f camRot = xa8_renderStates[0].x8_camOrientation.toTransform().buildMatrix3f(); if (x1bc_state == EAutoMapperState::MapScreen) { if ((input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter)) && x328_ == 0 && HasCurrentMapUniverseWorld()) @@ -968,10 +968,11 @@ float CAutoMapper::GetDesiredMiniMapCameraDistance(const CStateManager& mgr) con std::tan(M_PIF / 2.f - 0.5f * 2.f * M_PIF * (xa8_renderStates[0].x1c_camAngle / 360.f)); } -float CAutoMapper::GetClampedMapScreenCameraDistance(float v) const { - if (x1bc_state == EAutoMapperState::MapScreenUniverse) - return zeus::clamp(g_tweakAutoMapper->GetMinUniverseCamDist(), v, g_tweakAutoMapper->GetMaxUniverseCamDist()); - return zeus::clamp(g_tweakAutoMapper->GetMinCamDist(), v, g_tweakAutoMapper->GetMaxCamDist()); +float CAutoMapper::GetClampedMapScreenCameraDistance(float value) const { + if (x1bc_state == EAutoMapperState::MapScreenUniverse) { + return zeus::clamp(g_tweakAutoMapper->GetMinUniverseCamDist(), value, g_tweakAutoMapper->GetMaxUniverseCamDist()); + } + return zeus::clamp(g_tweakAutoMapper->GetMinCamDist(), value, g_tweakAutoMapper->GetMaxCamDist()); } void CAutoMapper::MuteAllLoopedSounds() { @@ -1092,7 +1093,7 @@ void CAutoMapper::ProcessControllerInput(const CFinalInput& input, CStateManager } } -void CAutoMapper::Update(float dt, const CStateManager& mgr) { +void CAutoMapper::Update(float dt, CStateManager& mgr) { if (x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap) { x1d8_flashTimer = std::fmod(x1d8_flashTimer + dt, 0.75f); x1dc_playerFlashPulse = x1d8_flashTimer < 0.375f ? x1d8_flashTimer / 0.375f : (0.75f - x1d8_flashTimer) / 0.375f; @@ -1288,7 +1289,7 @@ void CAutoMapper::Update(float dt, const CStateManager& mgr) { wld->ICheckWorldComplete(); } -void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, float alpha) const { +void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, float alpha) { SCOPED_GRAPHICS_DEBUG_GROUP("CAutoMapper::Draw", zeus::skPurple); alpha *= g_GameState->GameOptions().GetHUDAlpha() / 255.f; // Blend mode alpha @@ -1341,7 +1342,7 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo if (x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap) { if (universeInterp < 1.f && x24_world) { const CMapWorldInfo& mwInfo = *g_GameState->StateForWorld(x24_world->IGetWorldAssetId()).MapWorldInfo(); - const CMapWorld* mw = x24_world->IGetMapWorld(); + CMapWorld* mw = x24_world->IGetMapWorld(); float hintFlash = 0.f; if (x1e0_hintSteps.size() && x1e0_hintSteps.front().x0_type == SAutoMapperHintStep::Type::ShowBeacon) { if (xa0_curAreaId == mgr.GetNextAreaId() && x24_world == mgr.GetWorld()) { @@ -1360,35 +1361,37 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo } } } - zeus::CTransform modelXf = planeXf * preXf; - CMapWorld::CMapWorldDrawParms parms(xa8_renderStates[0].x34_alphaSurfaceVisited * alphaInterp, - xa8_renderStates[0].x38_alphaOutlineVisited * alphaInterp, - xa8_renderStates[0].x3c_alphaSurfaceUnvisited * alphaInterp, - xa8_renderStates[0].x40_alphaOutlineUnvisited * alphaInterp, mapAlpha, 2.f, - mgr, modelXf, camXf, *x24_world, mwInfo, x1dc_playerFlashPulse, hintFlash, - objectScale, true); + const zeus::CTransform modelXf = planeXf * preXf; + const CMapWorld::CMapWorldDrawParms parms(xa8_renderStates[0].x34_alphaSurfaceVisited * alphaInterp, + xa8_renderStates[0].x38_alphaOutlineVisited * alphaInterp, + xa8_renderStates[0].x3c_alphaSurfaceUnvisited * alphaInterp, + xa8_renderStates[0].x40_alphaOutlineUnvisited * alphaInterp, mapAlpha, + 2.f, mgr, modelXf, camXf, *x24_world, mwInfo, x1dc_playerFlashPulse, + hintFlash, objectScale, true); mw->Draw(parms, xa0_curAreaId, xa0_curAreaId, xa8_renderStates[0].x2c_drawDepth1, xa8_renderStates[0].x30_drawDepth2, true); } } else if (IsInMapperState(EAutoMapperState::MiniMap)) { - const CMapWorld* mw = x24_world->IGetMapWorld(); + CMapWorld* mw = x24_world->IGetMapWorld(); const CMapWorldInfo& mwInfo = *g_GameState->StateForWorld(x24_world->IGetWorldAssetId()).MapWorldInfo(); - CMapWorld::CMapWorldDrawParms parms(xa8_renderStates[0].x34_alphaSurfaceVisited * alphaInterp, - xa8_renderStates[0].x38_alphaOutlineVisited * alphaInterp, - xa8_renderStates[0].x3c_alphaSurfaceUnvisited * alphaInterp, - xa8_renderStates[0].x40_alphaOutlineUnvisited * alphaInterp, mapAlpha, 1.f, mgr, - planeXf, camXf, *x24_world, mwInfo, 0.f, 0.f, objectScale, false); + const CMapWorld::CMapWorldDrawParms parms(xa8_renderStates[0].x34_alphaSurfaceVisited * alphaInterp, + xa8_renderStates[0].x38_alphaOutlineVisited * alphaInterp, + xa8_renderStates[0].x3c_alphaSurfaceUnvisited * alphaInterp, + xa8_renderStates[0].x40_alphaOutlineUnvisited * alphaInterp, mapAlpha, + 1.f, mgr, planeXf, camXf, *x24_world, mwInfo, 0.f, 0.f, objectScale, + false); mw->Draw(parms, xa0_curAreaId, xa4_otherAreaId, xa8_renderStates[0].x2c_drawDepth1, xa8_renderStates[0].x30_drawDepth2, false); } else { - const CMapWorld* mw = x24_world->IGetMapWorld(); + CMapWorld* mw = x24_world->IGetMapWorld(); const CMapWorldInfo& mwInfo = *g_GameState->StateForWorld(x24_world->IGetWorldAssetId()).MapWorldInfo(); zeus::CTransform modelXf = planeXf * preXf; - CMapWorld::CMapWorldDrawParms parms(xa8_renderStates[0].x34_alphaSurfaceVisited * alphaInterp, - xa8_renderStates[0].x38_alphaOutlineVisited * alphaInterp, - xa8_renderStates[0].x3c_alphaSurfaceUnvisited * alphaInterp, - xa8_renderStates[0].x40_alphaOutlineUnvisited * alphaInterp, mapAlpha, 2.f, mgr, - modelXf, camXf, *x24_world, mwInfo, 0.f, 0.f, objectScale, true); + const CMapWorld::CMapWorldDrawParms parms(xa8_renderStates[0].x34_alphaSurfaceVisited * alphaInterp, + xa8_renderStates[0].x38_alphaOutlineVisited * alphaInterp, + xa8_renderStates[0].x3c_alphaSurfaceUnvisited * alphaInterp, + xa8_renderStates[0].x40_alphaOutlineUnvisited * alphaInterp, mapAlpha, + 2.f, mgr, modelXf, camXf, *x24_world, mwInfo, 0.f, 0.f, objectScale, + true); mw->Draw(parms, xa0_curAreaId, xa0_curAreaId, xa8_renderStates[0].x2c_drawDepth1, xa8_renderStates[0].x30_drawDepth2, false); } @@ -1410,8 +1413,8 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo } } - CMapUniverse::CMapUniverseDrawParms parms(universeInterp, x9c_worldIdx, g_GameState->CurrentWorldAssetId(), hexIdx, - x1dc_playerFlashPulse, mgr, planeXf, camXf); + const CMapUniverse::CMapUniverseDrawParms parms(universeInterp, x9c_worldIdx, g_GameState->CurrentWorldAssetId(), + hexIdx, x1dc_playerFlashPulse, mgr, planeXf, camXf); x8_mapu->Draw(parms, zeus::skZero3f, 0.f, 0.f); } @@ -1444,7 +1447,7 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo if (IsInMapperState(EAutoMapperState::MapScreen)) { CAssetId wldMlvl = x24_world->IGetWorldAssetId(); const CMapWorld* mw = x24_world->IGetMapWorld(); - std::vector& hintBeaconFilters = const_cast(*this).m_hintBeaconFilters; + std::vector& hintBeaconFilters = m_hintBeaconFilters; if (hintBeaconFilters.size() < x1f8_hintLocations.size()) { hintBeaconFilters.reserve(x1f8_hintLocations.size()); for (u32 i = hintBeaconFilters.size(); i < x1f8_hintLocations.size(); ++i) @@ -1601,11 +1604,11 @@ CAssetId CAutoMapper::GetAreaHintDescriptionString(CAssetId mreaId) { return -1; } -void CAutoMapper::OnNewInGameGuiState(EInGameGuiState state, const CStateManager& mgr) { +void CAutoMapper::OnNewInGameGuiState(EInGameGuiState state, CStateManager& mgr) { if (state == EInGameGuiState::MapScreen) { MP1::CMain::EnsureWorldPaksReady(); - const CWorld& wld = *mgr.GetWorld(); - const_cast(wld.GetMapWorld())->SetWhichMapAreasLoaded(wld, 0, 9999); + CWorld& wld = *mgr.GetWorld(); + wld.GetMapWorld()->SetWhichMapAreasLoaded(wld, 0, 9999); SetupHintNavigation(); BeginMapperStateTransition(EAutoMapperState::MapScreen, mgr); x28_frmeMapScreen = g_SimplePool->GetObj("FRME_MapScreen"); diff --git a/Runtime/AutoMapper/CAutoMapper.hpp b/Runtime/AutoMapper/CAutoMapper.hpp index 3cd4b2719..acfccccb4 100644 --- a/Runtime/AutoMapper/CAutoMapper.hpp +++ b/Runtime/AutoMapper/CAutoMapper.hpp @@ -128,7 +128,7 @@ private: ELoadPhase x4_loadPhase = ELoadPhase::LoadResources; TLockedToken x8_mapu; std::vector> x14_dummyWorlds; - const CWorld* x24_world; + CWorld* x24_world; TLockedToken x28_frmeMapScreen; // Used to be ptr bool m_frmeInitialized = false; TLockedToken x30_miniMapSamus; @@ -194,29 +194,29 @@ private: } bool NotHintNavigating() const; bool CanLeaveMapScreenInternal(const CStateManager& mgr) const; - void LeaveMapScreen(const CStateManager& mgr); - void SetupMiniMapWorld(const CStateManager& mgr); + void LeaveMapScreen(CStateManager& mgr); + void SetupMiniMapWorld(CStateManager& mgr); bool HasCurrentMapUniverseWorld() const; - bool CheckDummyWorldLoad(const CStateManager& mgr); - void UpdateHintNavigation(float dt, const CStateManager& mgr); + bool CheckDummyWorldLoad(CStateManager& mgr); + void UpdateHintNavigation(float dt, CStateManager& mgr); static zeus::CVector2i GetMiniMapViewportSize(); static zeus::CVector2i GetMapScreenViewportSize(); static float GetMapAreaMiniMapDrawDepth() { return 2.f; } - float GetMapAreaMaxDrawDepth(const CStateManager&, TAreaId) const; - static float GetMapAreaMiniMapDrawAlphaSurfaceVisited(const CStateManager&); - static float GetMapAreaMiniMapDrawAlphaOutlineVisited(const CStateManager&); - static float GetMapAreaMiniMapDrawAlphaSurfaceUnvisited(const CStateManager&); - static float GetMapAreaMiniMapDrawAlphaOutlineUnvisited(const CStateManager&); - float GetDesiredMiniMapCameraDistance(const CStateManager&) const; + float GetMapAreaMaxDrawDepth(const CStateManager& mgr, TAreaId aid) const; + static float GetMapAreaMiniMapDrawAlphaSurfaceVisited(const CStateManager& mgr); + static float GetMapAreaMiniMapDrawAlphaOutlineVisited(const CStateManager& mgr); + static float GetMapAreaMiniMapDrawAlphaSurfaceUnvisited(const CStateManager& mgr); + static float GetMapAreaMiniMapDrawAlphaOutlineUnvisited(const CStateManager& mgr); + float GetDesiredMiniMapCameraDistance(const CStateManager& mgr) const; static float GetBaseMapScreenCameraMoveSpeed(); - float GetClampedMapScreenCameraDistance(float) const; + float GetClampedMapScreenCameraDistance(float value) const; float GetFinalMapScreenCameraMoveSpeed() const; void ProcessMapRotateInput(const CFinalInput& input, const CStateManager& mgr); void ProcessMapZoomInput(const CFinalInput& input, const CStateManager& mgr); void ProcessMapPanInput(const CFinalInput& input, const CStateManager& mgr); - void SetShouldPanningSoundBePlaying(bool); - void SetShouldZoomingSoundBePlaying(bool); - void SetShouldRotatingSoundBePlaying(bool); + void SetShouldPanningSoundBePlaying(bool shouldBePlaying); + void SetShouldZoomingSoundBePlaying(bool shouldBePlaying); + void SetShouldRotatingSoundBePlaying(bool shouldBePlaying); void TransformRenderStatesWorldToUniverse(); void TransformRenderStatesUniverseToWorld(); void TransformRenderStateWorldToUniverse(SAutoMapperRenderState&); @@ -224,9 +224,9 @@ private: CAssetId GetAreaHintDescriptionString(CAssetId mreaId); public: - CAutoMapper(CStateManager& stateMgr); + explicit CAutoMapper(CStateManager& stateMgr); bool CheckLoadComplete(); - bool CanLeaveMapScreen(const CStateManager&) const; + bool CanLeaveMapScreen(const CStateManager& mgr) const; float GetMapRotationX() const { return xa8_renderStates[0].x1c_camAngle; } float GetMapRotationZ() const { return xa8_renderStates[0].x8_camOrientation.yaw(); } TAreaId GetFocusAreaIndex() const { return xa0_curAreaId; } @@ -234,29 +234,30 @@ public: void SetCurWorldAssetId(CAssetId mlvlId); void MuteAllLoopedSounds(); void UnmuteAllLoopedSounds(); - void ProcessControllerInput(const CFinalInput&, CStateManager&); + void ProcessControllerInput(const CFinalInput& input, CStateManager& mgr); bool IsInPlayerControlState() const { return IsInMapperState(EAutoMapperState::MapScreen) || IsInMapperState(EAutoMapperState::MapScreenUniverse); } - void Update(float dt, const CStateManager& mgr); - void Draw(const CStateManager&, const zeus::CTransform&, float) const; + void Update(float dt, CStateManager& mgr); + void Draw(const CStateManager& mgr, const zeus::CTransform& xf, float alpha); float GetTimeIntoInterpolation() const { return x1c8_interpTime; } - void BeginMapperStateTransition(EAutoMapperState, const CStateManager&); - void CompleteMapperStateTransition(const CStateManager&); - void ResetInterpolationTimer(float); - SAutoMapperRenderState BuildMiniMapWorldRenderState(const CStateManager&, const zeus::CQuaternion&, TAreaId) const; - SAutoMapperRenderState BuildMapScreenWorldRenderState(const CStateManager&, const zeus::CQuaternion&, TAreaId, - bool) const; - SAutoMapperRenderState BuildMapScreenUniverseRenderState(const CStateManager&, const zeus::CQuaternion&, - TAreaId) const; + void BeginMapperStateTransition(EAutoMapperState state, CStateManager& mgr); + void CompleteMapperStateTransition(CStateManager& mgr); + void ResetInterpolationTimer(float duration); + SAutoMapperRenderState BuildMiniMapWorldRenderState(const CStateManager& stateMgr, const zeus::CQuaternion& rot, + TAreaId area) const; + SAutoMapperRenderState BuildMapScreenWorldRenderState(const CStateManager& mgr, const zeus::CQuaternion& rot, + TAreaId area, bool doingHint) const; + SAutoMapperRenderState BuildMapScreenUniverseRenderState(const CStateManager& mgr, const zeus::CQuaternion& rot, + TAreaId area) const; void LeaveMapScreenState(); - void ProcessMapScreenInput(const CFinalInput& input, const CStateManager& mgr); - zeus::CQuaternion GetMiniMapCameraOrientation(const CStateManager&) const; - zeus::CVector3f GetAreaPointOfInterest(const CStateManager&, TAreaId) const; - TAreaId FindClosestVisibleArea(const zeus::CVector3f&, const zeus::CUnitVector3f&, const CStateManager&, - const IWorld&, const CMapWorldInfo&) const; - std::pair FindClosestVisibleWorld(const zeus::CVector3f&, const zeus::CUnitVector3f&, - const CStateManager&) const; + void ProcessMapScreenInput(const CFinalInput& input, CStateManager& mgr); + zeus::CQuaternion GetMiniMapCameraOrientation(const CStateManager& stateMgr) const; + zeus::CVector3f GetAreaPointOfInterest(const CStateManager& mgr, TAreaId aid) const; + TAreaId FindClosestVisibleArea(const zeus::CVector3f& point, const zeus::CUnitVector3f& camDir, + const CStateManager& mgr, const IWorld& wld, const CMapWorldInfo& mwInfo) const; + std::pair FindClosestVisibleWorld(const zeus::CVector3f& point, const zeus::CUnitVector3f& camDir, + const CStateManager& mgr) const; EAutoMapperState GetNextState() const { return x1c0_nextState; } bool IsInMapperState(EAutoMapperState state) const { return state == x1bc_state && state == x1c0_nextState; } @@ -267,7 +268,7 @@ public: bool IsFullyOutOfMiniMapState() const { return x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap; } - void OnNewInGameGuiState(EInGameGuiState, const CStateManager&); + void OnNewInGameGuiState(EInGameGuiState state, CStateManager& mgr); float GetInterp() const { if (x1c4_interpDur > 0.f) return x1c8_interpTime / x1c4_interpDur; diff --git a/Runtime/AutoMapper/CMapArea.cpp b/Runtime/AutoMapper/CMapArea.cpp index e59dcb018..7ef16f942 100644 --- a/Runtime/AutoMapper/CMapArea.cpp +++ b/Runtime/AutoMapper/CMapArea.cpp @@ -1,5 +1,8 @@ #include "Runtime/AutoMapper/CMapArea.hpp" +#include +#include + #include "Runtime/CResFactory.hpp" #include "Runtime/CToken.hpp" #include "Runtime/GameGlobalObjects.hpp" @@ -8,101 +11,13 @@ #include "Runtime/World/CWorld.hpp" namespace urde { -CMapArea::CMapArea(CInputStream& in, u32 size) -: x0_magic(in.readUint32()) -, x4_version(in.readUint32Big()) -, x8_(in.readUint32Big()) -, xc_visibilityMode(EVisMode(in.readUint32Big())) -, x10_box(zeus::CAABox::ReadBoundingBoxBig(in)) -, x28_mappableObjCount(in.readUint32Big()) -, x2c_vertexCount(in.readUint32Big()) -, x30_surfaceCount(in.readUint32Big()) -, x34_size(size - 52) { - x44_buf.reset(new u8[x34_size]); - in.readUBytesToBuf(x44_buf.get(), x34_size); - PostConstruct(); -} +constexpr std::array MinesPostTransforms{{ + {0.f, 0.f, 200.f}, + {0.f, 0.f, 0.f}, + {0.f, 0.f, -200.f}, +}}; -void CMapArea::PostConstruct() { - x38_moStart = x44_buf.get(); - x3c_vertexStart = x38_moStart + (x28_mappableObjCount * 0x50); - x40_surfaceStart = x3c_vertexStart + (x2c_vertexCount * 12); - - m_mappableObjects.reserve(x28_mappableObjCount); - for (u32 i = 0, j = 0; i < x28_mappableObjCount; ++i, j += 0x50) { - m_mappableObjects.emplace_back(x38_moStart + j).PostConstruct(x44_buf.get()); - } - - u8* tmp = x3c_vertexStart; - m_verts.reserve(x2c_vertexCount); - for (u32 i = 0; i < x2c_vertexCount; ++i) { - float* fl = reinterpret_cast(tmp); - m_verts.emplace_back(hecl::SBig(fl[0]), hecl::SBig(fl[1]), hecl::SBig(fl[2])); - tmp += 12; - } - - std::vector index; - m_surfaces.reserve(x30_surfaceCount); - for (u32 i = 0, j = 0; i < x30_surfaceCount; ++i, j += 32) { - m_surfaces.emplace_back(x40_surfaceStart + j).PostConstruct(x44_buf.get(), index); - } - - CGraphics::CommitResources([this, &index](boo::IGraphicsDataFactory::Context& ctx) { - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, m_verts.data(), 16, m_verts.size()); - m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, index.data(), 4, index.size()); - - /* Only the map universe specifies Always; it draws a maximum of 1016 instances */ - size_t instCount = (xc_visibilityMode == EVisMode::Always) ? 1024 : 1; - - for (u32 i = 0; i < x30_surfaceCount; ++i) { - CMapAreaSurface& surf = m_surfaces[i]; - surf.m_instances.reserve(instCount); - for (u32 inst = 0; inst < instCount; ++inst) { - CMapAreaSurface::Instance& instance = surf.m_instances.emplace_back(ctx, m_vbo, m_ibo); - - athena::io::MemoryReader r(surf.x1c_outlineOffset, INT_MAX); - u32 outlineCount = r.readUint32Big(); - - std::vector& linePrims = instance.m_linePrims; - linePrims.reserve(outlineCount * 2); - for (u32 j = 0; j < 2; ++j) { - r.seek(4, athena::SeekOrigin::Begin); - for (u32 i = 0; i < outlineCount; ++i) { - u32 count = r.readUint32Big(); - r.seek(count); - r.seekAlign4(); - linePrims.emplace_back(ctx, CLineRenderer::EPrimitiveMode::LineStrip, count, nullptr, false, false, true); - } - } - } - } - - for (u32 i = 0; i < x28_mappableObjCount; ++i) { - CMappableObject& mapObj = m_mappableObjects[i]; - if (CMappableObject::IsDoorType(mapObj.GetType())) - mapObj.CreateDoorSurface(ctx); - } - return true; - } BooTrace); -} - -bool CMapArea::GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const { - switch (xc_visibilityMode) { - case EVisMode::Always: - return true; - case EVisMode::MapStationOrVisit: - return worldVis || areaVis; - case EVisMode::Visit: - return areaVis; - case EVisMode::Never: - return false; - default: - return true; - } -} - -static const zeus::CVector3f MinesPostTransforms[3] = {{0.f, 0.f, 200.f}, {0.f, 0.f, 0.f}, {0.f, 0.f, -200.f}}; -static const u8 MinesPostTransformIndices[] = { +constexpr std::array MinesPostTransformIndices{ 0, // 00 Transport to Tallon Overworld South 0, // 01 Quarry Access 0, // 02 Main Quarry @@ -147,6 +62,105 @@ static const u8 MinesPostTransformIndices[] = { 2, // 41 Fungal Hall A }; +CMapArea::CMapArea(CInputStream& in, u32 size) +: x0_magic(in.readUint32()) +, x4_version(in.readUint32Big()) +, x8_(in.readUint32Big()) +, xc_visibilityMode(EVisMode(in.readUint32Big())) +, x10_box(zeus::CAABox::ReadBoundingBoxBig(in)) +, x28_mappableObjCount(in.readUint32Big()) +, x2c_vertexCount(in.readUint32Big()) +, x30_surfaceCount(in.readUint32Big()) +, x34_size(size - 52) { + x44_buf.reset(new u8[x34_size]); + in.readUBytesToBuf(x44_buf.get(), x34_size); + PostConstruct(); +} + +void CMapArea::PostConstruct() { + x38_moStart = x44_buf.get(); + x3c_vertexStart = x38_moStart + (x28_mappableObjCount * 0x50); + x40_surfaceStart = x3c_vertexStart + (x2c_vertexCount * 12); + + m_mappableObjects.reserve(x28_mappableObjCount); + for (u32 i = 0, j = 0; i < x28_mappableObjCount; ++i, j += 0x50) { + m_mappableObjects.emplace_back(x38_moStart + j).PostConstruct(x44_buf.get()); + } + + u8* tmp = x3c_vertexStart; + m_verts.reserve(x2c_vertexCount); + for (u32 i = 0; i < x2c_vertexCount; ++i) { + float x; + std::memcpy(&x, tmp, sizeof(float)); + float y; + std::memcpy(&y, tmp + 4, sizeof(float)); + float z; + std::memcpy(&z, tmp + 8, sizeof(float)); + + m_verts.emplace_back(hecl::SBig(x), hecl::SBig(y), hecl::SBig(z)); + tmp += 12; + } + + std::vector index; + m_surfaces.reserve(x30_surfaceCount); + for (u32 i = 0, j = 0; i < x30_surfaceCount; ++i, j += 32) { + m_surfaces.emplace_back(x40_surfaceStart + j).PostConstruct(x44_buf.get(), index); + } + + CGraphics::CommitResources([this, &index](boo::IGraphicsDataFactory::Context& ctx) { + m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, m_verts.data(), 16, m_verts.size()); + m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, index.data(), 4, index.size()); + + /* Only the map universe specifies Always; it draws a maximum of 1016 instances */ + size_t instCount = (xc_visibilityMode == EVisMode::Always) ? 1024 : 1; + + for (u32 i = 0; i < x30_surfaceCount; ++i) { + CMapAreaSurface& surf = m_surfaces[i]; + surf.m_instances.reserve(instCount); + for (u32 inst = 0; inst < instCount; ++inst) { + CMapAreaSurface::Instance& instance = surf.m_instances.emplace_back(ctx, m_vbo, m_ibo); + + athena::io::MemoryReader r(surf.x1c_outlineOffset, INT_MAX); + u32 outlineCount = r.readUint32Big(); + + std::vector& linePrims = instance.m_linePrims; + linePrims.reserve(outlineCount * 2); + for (u32 j = 0; j < 2; ++j) { + r.seek(4, athena::SeekOrigin::Begin); + for (u32 k = 0; k < outlineCount; ++k) { + const u32 count = r.readUint32Big(); + r.seek(count); + r.seekAlign4(); + linePrims.emplace_back(ctx, CLineRenderer::EPrimitiveMode::LineStrip, count, nullptr, false, false, true); + } + } + } + } + + for (u32 i = 0; i < x28_mappableObjCount; ++i) { + CMappableObject& mapObj = m_mappableObjects[i]; + if (CMappableObject::IsDoorType(mapObj.GetType())) + mapObj.CreateDoorSurface(ctx); + } + return true; + } BooTrace); +} + +bool CMapArea::GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const { + switch (xc_visibilityMode) { + case EVisMode::Always: + return true; + case EVisMode::MapStationOrVisit: + return worldVis || areaVis; + case EVisMode::Visit: + return areaVis; + case EVisMode::Never: + return false; + default: + return true; + } +} + zeus::CTransform CMapArea::GetAreaPostTransform(const IWorld& world, TAreaId aid) const { if (world.IGetWorldAssetId() == 0xB1AC4D65) // Phazon Mines { @@ -243,15 +257,16 @@ void CMapArea::CMapAreaSurface::PostConstruct(const u8* buf, std::vector& i } void CMapArea::CMapAreaSurface::Draw(const zeus::CVector3f* verts, const zeus::CColor& surfColor, - const zeus::CColor& lineColor, float lineWidth, size_t instIdx) const { + const zeus::CColor& lineColor, float lineWidth, size_t instIdx) { if (instIdx >= m_instances.size()) { return; } - Instance& instance = const_cast(m_instances[instIdx]); + Instance& instance = m_instances[instIdx]; - if (surfColor.a()) + if (surfColor.a()) { instance.m_surfacePrims.draw(surfColor, m_primStart, m_primCount); + } if (lineColor.a()) { bool draw2 = lineWidth > 1.f; diff --git a/Runtime/AutoMapper/CMapArea.hpp b/Runtime/AutoMapper/CMapArea.hpp index 80c6c8379..3559b4479 100644 --- a/Runtime/AutoMapper/CMapArea.hpp +++ b/Runtime/AutoMapper/CMapArea.hpp @@ -38,11 +38,11 @@ public: std::vector m_instances; public: - CMapAreaSurface(const void* surfBuf); + explicit CMapAreaSurface(const void* surfBuf); CMapAreaSurface(CMapAreaSurface&&) = default; void PostConstruct(const u8* buf, std::vector& index); void Draw(const zeus::CVector3f* verts, const zeus::CColor& surfColor, const zeus::CColor& lineColor, - float lineWidth, size_t instIdx = 0) const; + float lineWidth, size_t instIdx = 0); const zeus::CVector3f& GetNormal() const { return x0_normal; } const zeus::CVector3f& GetCenterPosition() const { return xc_centroid; } }; @@ -69,12 +69,14 @@ private: boo::ObjToken m_ibo; public: - CMapArea(CInputStream& in, u32 size); + explicit CMapArea(CInputStream& in, u32 size); void PostConstruct(); bool GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const; zeus::CVector3f GetAreaCenterPoint() const { return x10_box.center(); } const zeus::CAABox& GetBoundingBox() const { return x10_box; } + CMappableObject& GetMappableObject(int idx) { return m_mappableObjects[idx]; } const CMappableObject& GetMappableObject(int idx) const { return m_mappableObjects[idx]; } + CMapAreaSurface& GetSurface(int idx) { return m_surfaces[idx]; } const CMapAreaSurface& GetSurface(int idx) const { return m_surfaces[idx]; } u32 GetNumMappableObjects() const { return m_mappableObjects.size(); } u32 GetNumSurfaces() const { return m_surfaces.size(); } diff --git a/Runtime/AutoMapper/CMapUniverse.cpp b/Runtime/AutoMapper/CMapUniverse.cpp index e916130c9..c9db5b12d 100644 --- a/Runtime/AutoMapper/CMapUniverse.cpp +++ b/Runtime/AutoMapper/CMapUniverse.cpp @@ -38,9 +38,10 @@ CMapUniverse::CMapWorldData::CMapWorldData(CInputStream& in, u32 version) x64_centerPoint *= zeus::CVector3f(1.0f / float(x44_hexagonXfs.size())); } -void CMapUniverse::Draw(const CMapUniverseDrawParms& parms, const zeus::CVector3f&, float, float) const { - if (!x4_hexagonToken.IsLoaded()) +void CMapUniverse::Draw(const CMapUniverseDrawParms& parms, const zeus::CVector3f&, float, float) { + if (!x4_hexagonToken.IsLoaded()) { return; + } SCOPED_GRAPHICS_DEBUG_GROUP("CMapUniverse::Draw", zeus::skBlue); u32 totalSurfaceCount = 0; @@ -100,7 +101,7 @@ void CMapUniverse::Draw(const CMapUniverseDrawParms& parms, const zeus::CVector3 zeus::CTransform hexXf = mwData.GetMapAreaData(info.GetAreaIndex()); hexXf.orthonormalize(); - const CMapArea::CMapAreaSurface& surf = x4_hexagonToken->GetSurface(info.GetObjectIndex()); + CMapArea::CMapAreaSurface& surf = x4_hexagonToken->GetSurface(info.GetObjectIndex()); zeus::CColor color(std::max(0.f, (-parms.GetCameraTransform().basis[1]).dot(hexXf.rotate(surf.GetNormal()))) * g_tweakAutoMapper->GetMapSurfaceNormColorLinear() + g_tweakAutoMapper->GetMapSurfaceNormColorConstant()); diff --git a/Runtime/AutoMapper/CMapUniverse.hpp b/Runtime/AutoMapper/CMapUniverse.hpp index 989a629f5..4b7254070 100644 --- a/Runtime/AutoMapper/CMapUniverse.hpp +++ b/Runtime/AutoMapper/CMapUniverse.hpp @@ -84,7 +84,7 @@ public: zeus::CVector3f x64_centerPoint = zeus::skZero3f; public: - CMapWorldData(CInputStream& in, u32 version); + explicit CMapWorldData(CInputStream& in, u32 version); CAssetId GetWorldAssetId() const { return x10_worldAssetId; } const zeus::CVector3f& GetWorldCenterPoint() const { return x64_centerPoint; } std::string_view GetWorldLabel() const { return x0_label; } @@ -105,7 +105,7 @@ private: float x2c_universeRadius = 1600.f; public: - CMapUniverse(CInputStream&, u32); + explicit CMapUniverse(CInputStream&, u32); const CMapWorldData& GetMapWorldData(s32 idx) const { return x10_worldDatas[idx]; } const CMapWorldData& GetMapWorldDataByWorldId(CAssetId id) const { for (const CMapWorldData& data : x10_worldDatas) @@ -116,7 +116,7 @@ public: u32 GetNumMapWorldDatas() const { return x10_worldDatas.size(); } float GetMapUniverseRadius() const { return x2c_universeRadius; } const zeus::CVector3f& GetMapUniverseCenterPoint() const { return x20_universeCenter; } - void Draw(const CMapUniverseDrawParms&, const zeus::CVector3f&, float, float) const; + void Draw(const CMapUniverseDrawParms&, const zeus::CVector3f&, float, float); std::vector::const_iterator begin() const { return x10_worldDatas.cbegin(); } std::vector::const_iterator end() const { return x10_worldDatas.cend(); } }; diff --git a/Runtime/AutoMapper/CMapWorld.cpp b/Runtime/AutoMapper/CMapWorld.cpp index 66b1220b5..125051c7e 100644 --- a/Runtime/AutoMapper/CMapWorld.cpp +++ b/Runtime/AutoMapper/CMapWorld.cpp @@ -1,5 +1,8 @@ #include "Runtime/AutoMapper/CMapWorld.hpp" +#include +#include + #include "Runtime/CSimplePool.hpp" #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" @@ -7,6 +10,254 @@ #include "Runtime/World/CWorld.hpp" namespace urde { +namespace { +struct Support { + int x0_; + std::array x4_; +}; + +struct Circle2 { + zeus::CVector2f x0_point; + float x8_radiusSq; +}; + +struct Circle { + zeus::CVector2f x0_point; + float x8_radius; + Circle(const Circle2& circ2) : x0_point(circ2.x0_point), x8_radius(std::sqrt(circ2.x8_radiusSq)) {} +}; + +Circle2 ExactCircle1(const zeus::CVector2f* a) { return {*a, 0.f}; } + +Circle2 ExactCircle2(const zeus::CVector2f* a, const zeus::CVector2f* b) { + Circle2 ret = {}; + ret.x0_point = 0.5f * (*a + *b); + ret.x8_radiusSq = (*b - *a).magSquared() * 0.25f; + return ret; +} + +Circle2 ExactCircle3(const zeus::CVector2f* a, const zeus::CVector2f* b, const zeus::CVector2f* c) { + Circle2 ret = {}; + zeus::CVector2f d1 = *b - *a; + zeus::CVector2f d2 = *c - *a; + float cross = d1.cross(d2); + zeus::CVector2f magVec(d1.magSquared() * 0.5f, d2.magSquared() * 0.5f); + if (std::fabs(cross) > 0.01f) { + zeus::CVector2f tmp((d2.y() * magVec.x() - d1.y() * magVec.y()) / cross, + (d1.x() * magVec.y() - d2.x() * magVec.x()) / cross); + ret.x0_point = *a + tmp; + ret.x8_radiusSq = tmp.magSquared(); + } else { + ret.x8_radiusSq = FLT_MAX; + } + return ret; +} + +bool PointInsideCircle(const zeus::CVector2f& point, const Circle2& circ, float& intersect) { + intersect = (point - circ.x0_point).magSquared() - circ.x8_radiusSq; + return intersect <= 0.f; +} + +Circle2 UpdateSupport1(int idx, const zeus::CVector2f** list, Support& support) { + Circle2 ret = ExactCircle2(list[support.x4_[0]], list[idx]); + support.x0_ = 2; + support.x4_[1] = idx; + return ret; +} + +Circle2 UpdateSupport2(int idx, const zeus::CVector2f** list, Support& support) { + std::array circs{}; + float intersect; + int circIdx = -1; + float minRad = FLT_MAX; + + circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]); + if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect)) { + minRad = circs[0].x8_radiusSq; + circIdx = 0; + } + + circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]); + if (circs[1].x8_radiusSq < minRad && PointInsideCircle(*list[support.x4_[0]], circs[1], intersect)) { + circIdx = 1; + } + + Circle2 ret; + if (circIdx != -1) { + ret = circs[circIdx]; + support.x4_[1 - circIdx] = idx; + } else { + ret = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]); + support.x0_ = 3; + support.x4_[2] = idx; + } + return ret; +} + +Circle2 UpdateSupport3(int idx, const zeus::CVector2f** list, Support& support) { + std::array circs{}; + float intersect; + int circIdxA = -1; + int circIdxB = -1; + float minRadA = FLT_MAX; + float minRadB = FLT_MAX; + + circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]); + if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect)) { + if (PointInsideCircle(*list[support.x4_[2]], circs[0], intersect)) { + minRadA = circs[0].x8_radiusSq; + circIdxA = 0; + } else { + minRadB = intersect; + circIdxB = 0; + } + } else { + minRadB = intersect; + circIdxB = 0; + } + + circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]); + if (circs[1].x8_radiusSq < minRadA) { + if (PointInsideCircle(*list[support.x4_[0]], circs[1], intersect)) { + if (PointInsideCircle(*list[support.x4_[2]], circs[1], intersect)) { + minRadA = circs[1].x8_radiusSq; + circIdxA = 1; + } else if (intersect < minRadB) { + minRadB = intersect; + circIdxB = 1; + } + } else if (intersect < minRadB) { + minRadB = intersect; + circIdxB = 1; + } + } + + circs[2] = ExactCircle2(list[support.x4_[2]], list[idx]); + if (circs[2].x8_radiusSq < minRadA) { + if (PointInsideCircle(*list[support.x4_[0]], circs[2], intersect)) { + if (PointInsideCircle(*list[support.x4_[1]], circs[2], intersect)) { + minRadA = circs[2].x8_radiusSq; + circIdxA = 2; + } else if (intersect < minRadB) { + minRadB = intersect; + circIdxB = 2; + } + } else if (intersect < minRadB) { + minRadB = intersect; + circIdxB = 2; + } + } + + circs[3] = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]); + if (circs[3].x8_radiusSq < minRadA) { + if (PointInsideCircle(*list[support.x4_[2]], circs[3], intersect)) { + minRadA = circs[3].x8_radiusSq; + circIdxA = 3; + } else if (intersect < minRadB) { + minRadB = intersect; + circIdxB = 3; + } + } + + circs[4] = ExactCircle3(list[support.x4_[0]], list[support.x4_[2]], list[idx]); + if (circs[4].x8_radiusSq < minRadA) { + if (PointInsideCircle(*list[support.x4_[1]], circs[4], intersect)) { + minRadA = circs[4].x8_radiusSq; + circIdxA = 4; + } else if (intersect < minRadB) { + minRadB = intersect; + circIdxB = 4; + } + } + + circs[5] = ExactCircle3(list[support.x4_[1]], list[support.x4_[2]], list[idx]); + if (circs[5].x8_radiusSq < minRadA) { + if (PointInsideCircle(*list[support.x4_[0]], circs[5], intersect)) { + circIdxA = 5; + } else if (intersect < minRadB) { + circIdxB = 5; + } + } + + if (circIdxA == -1) + circIdxA = circIdxB; + + switch (circIdxA) { + case 0: + support.x0_ = 2; + support.x4_[1] = idx; + break; + case 1: + support.x0_ = 2; + support.x4_[0] = idx; + break; + case 2: + support.x0_ = 2; + support.x4_[0] = support.x4_[2]; + support.x4_[1] = idx; + break; + case 3: + support.x4_[2] = idx; + break; + case 4: + support.x4_[1] = idx; + break; + case 5: + support.x4_[0] = idx; + break; + default: + break; + } + + return circs[circIdxA]; +} + +using FSupport = Circle2 (*)(int idx, const zeus::CVector2f** list, Support& support); +constexpr std::array SupportFuncs{ + nullptr, + UpdateSupport1, + UpdateSupport2, + UpdateSupport3, +}; + +Circle MinCircle(const std::vector& coords) { + Circle2 ret = {}; + if (coords.size() >= 1) { + std::unique_ptr randArr(new const zeus::CVector2f*[coords.size()]); + for (size_t i = 0; i < coords.size(); ++i) + randArr[i] = &coords[i]; + for (int i = coords.size() - 1; i >= 0; --i) { + int shuf = rand() % (i + 1); + if (shuf != i) + std::swap(randArr[i], randArr[shuf]); + } + ret = ExactCircle1(randArr[0]); + + Support support = {}; + support.x0_ = 1; + for (size_t i = 1; i < coords.size();) { + bool broke = false; + for (int j = 0; j < support.x0_; ++j) { + if ((*randArr[i] - *randArr[support.x4_[j]]).magSquared() < 0.01f) { + broke = true; + break; + } + } + float intersect; + if (!broke && !PointInsideCircle(*randArr[i], ret, intersect)) { + Circle2 circ = SupportFuncs[support.x0_](i, randArr.get(), support); + if (circ.x8_radiusSq > ret.x8_radiusSq) { + i = 0; + ret = circ; + continue; + } + } + ++i; + } + } + return ret; +} +} // Anonymous namespace CMapWorld::CMapAreaData::CMapAreaData(CAssetId areaRes, EMapAreaList list, CMapAreaData* next) : x0_area(g_SimplePool->GetObj(SObjectTag{FOURCC('MAPA'), areaRes})), x10_list(list), x14_next(next) {} @@ -60,13 +311,13 @@ void CMapWorld::SetWhichMapAreasLoaded(const IWorld& wld, int start, int count) } } -bool CMapWorld::IsMapAreasStreaming() const { +bool CMapWorld::IsMapAreasStreaming() { bool ret = false; CMapAreaData* data = x10_listHeads[1]; while (data != nullptr) { if (data->IsLoaded()) { CMapAreaData* next = data->GetNextMapAreaData(); - const_cast(this)->MoveMapAreaToList(data, EMapAreaList::Loaded); + MoveMapAreaToList(data, EMapAreaList::Loaded); data = next; } else { data = data->GetNextMapAreaData(); @@ -93,7 +344,7 @@ void CMapWorld::MoveMapAreaToList(CMapWorld::CMapAreaData* data, CMapWorld::EMap x10_listHeads[int(list)] = data; } -s32 CMapWorld::GetCurrentMapAreaDepth(const IWorld& wld, TAreaId aid) const { +s32 CMapWorld::GetCurrentMapAreaDepth(const IWorld& wld, TAreaId aid) { ClearTraversedFlags(); std::vector info; info.reserve(x0_areas.size()); @@ -118,8 +369,8 @@ std::vector CMapWorld::GetVisibleAreas(const IWorld& wld, const CMapWorldIn return ret; } -void CMapWorld::Draw(const CMapWorld::CMapWorldDrawParms& parms, int curArea, int otherArea, float depth1, float depth2, - bool inMapScreen) const { +void CMapWorld::Draw(const CMapWorldDrawParms& parms, int curArea, int otherArea, float depth1, float depth2, + bool inMapScreen) { if (depth1 == 0.f && depth2 == 0.f) return; SCOPED_GRAPHICS_DEBUG_GROUP("CMapWorld::Draw", zeus::skBlue); @@ -130,7 +381,7 @@ void CMapWorld::Draw(const CMapWorld::CMapWorldDrawParms& parms, int curArea, in std::vector bfsInfos; bfsInfos.reserve(x0_areas.size()); if (curArea != otherArea) { - const_cast(this)->x20_traversed[otherArea] = true; + x20_traversed[otherArea] = true; DoBFS(parms.GetWorld(), curArea, areaDepth, depth1, depth2, true, bfsInfos); float lowD1 = std::ceil(depth1 - 1.f); @@ -150,7 +401,7 @@ void CMapWorld::Draw(const CMapWorld::CMapWorldDrawParms& parms, int curArea, in int otherDepth = std::ceil(std::max(newD1, newD2)); if (parms.GetWorld().IGetAreaAlways(otherArea)->IIsActive()) { - const_cast(this)->x20_traversed[otherArea] = false; + x20_traversed[otherArea] = false; DoBFS(parms.GetWorld(), otherArea, otherDepth, newD1, newD2, true, bfsInfos); } } else { @@ -161,13 +412,13 @@ void CMapWorld::Draw(const CMapWorld::CMapWorldDrawParms& parms, int curArea, in } void CMapWorld::DoBFS(const IWorld& wld, int startArea, int areaCount, float surfDepth, float outlineDepth, - bool checkLoad, std::vector& bfsInfos) const { + bool checkLoad, std::vector& bfsInfos) { if (areaCount <= 0 || !IsMapAreaValid(wld, startArea, checkLoad)) return; size_t size = bfsInfos.size(); bfsInfos.emplace_back(startArea, 1, surfDepth, outlineDepth); - const_cast(this)->x20_traversed[startArea] = true; + x20_traversed[startArea] = true; for (; size != bfsInfos.size(); ++size) { CMapAreaBFSInfo& testInfo = bfsInfos[size]; @@ -182,7 +433,7 @@ void CMapWorld::DoBFS(const IWorld& wld, int startArea, int areaCount, float sur TAreaId attId = area->IGetAttachedAreaId(i); if (IsMapAreaValid(wld, attId, checkLoad) && !x20_traversed[attId]) { bfsInfos.emplace_back(attId, testInfo.GetDepth() + 1, surfDepth, outlineDepth); - const_cast(this)->x20_traversed[attId] = true; + x20_traversed[attId] = true; } } } @@ -197,8 +448,8 @@ bool CMapWorld::IsMapAreaValid(const IWorld& wld, int areaIdx, bool checkLoad) c return true; } -void CMapWorld::DrawAreas(const CMapWorld::CMapWorldDrawParms& parms, int selArea, - const std::vector& bfsInfos, bool inMapScreen) const { +void CMapWorld::DrawAreas(const CMapWorldDrawParms& parms, int selArea, const std::vector& bfsInfos, + bool inMapScreen) { // Alpha blend // Line width 1 @@ -328,17 +579,18 @@ void CMapWorld::DrawAreas(const CMapWorld::CMapWorldDrawParms& parms, int selAre u32 lastAreaIdx = UINT32_MAX; CMapObjectSortInfo::EObjectCode lastType = CMapObjectSortInfo::EObjectCode::Invalid; for (const CMapObjectSortInfo& info : sortInfos) { - const CMapArea* mapa = GetMapArea(info.GetAreaIndex()); + CMapArea* mapa = GetMapArea(info.GetAreaIndex()); zeus::CTransform areaPostXf = mapa->GetAreaPostTransform(parms.GetWorld(), info.GetAreaIndex()); if (info.GetObjectCode() == CMapObjectSortInfo::EObjectCode::Surface) { - const CMapArea::CMapAreaSurface& surf = mapa->GetSurface(info.GetLocalObjectIndex()); + CMapArea::CMapAreaSurface& surf = mapa->GetSurface(info.GetLocalObjectIndex()); zeus::CColor color( std::max(0.f, (-parms.GetCameraTransform().basis[1]).dot(areaPostXf.rotate(surf.GetNormal()))) * g_tweakAutoMapper->GetMapSurfaceNormColorLinear() + g_tweakAutoMapper->GetMapSurfaceNormColorConstant()); color *= info.GetSurfaceColor(); - if (lastAreaIdx != info.GetAreaIndex() || lastType != CMapObjectSortInfo::EObjectCode::Surface) + if (lastAreaIdx != info.GetAreaIndex() || lastType != CMapObjectSortInfo::EObjectCode::Surface) { CGraphics::SetModelMatrix(parms.GetPlaneProjectionTransform() * areaPostXf); + } surf.Draw(mapa->GetVertices(), color, info.GetOutlineColor(), parms.GetOutlineWidthScale()); lastAreaIdx = info.GetAreaIndex(); @@ -346,11 +598,11 @@ void CMapWorld::DrawAreas(const CMapWorld::CMapWorldDrawParms& parms, int selAre } } for (const CMapObjectSortInfo& info : sortInfos) { - const CMapArea* mapa = GetMapArea(info.GetAreaIndex()); + CMapArea* mapa = GetMapArea(info.GetAreaIndex()); if (info.GetObjectCode() == CMapObjectSortInfo::EObjectCode::Door || info.GetObjectCode() == CMapObjectSortInfo::EObjectCode::Object) { - const CMappableObject& mapObj = mapa->GetMappableObject(info.GetLocalObjectIndex()); - zeus::CTransform objXf = + CMappableObject& mapObj = mapa->GetMappableObject(info.GetLocalObjectIndex()); + const zeus::CTransform objXf = zeus::CTransform::Translate(CMapArea::GetAreaPostTranslate(parms.GetWorld(), info.GetAreaIndex())) * mapObj.GetTransform(); if (info.GetObjectCode() == CMapObjectSortInfo::EObjectCode::Door) { @@ -363,8 +615,8 @@ void CMapWorld::DrawAreas(const CMapWorld::CMapWorldDrawParms& parms, int selAre mapObj.Draw(selArea, mwInfo, parms.GetAlpha(), lastType != info.GetObjectCode()); lastType = info.GetObjectCode(); } else if (info.GetObjectCode() == CMapObjectSortInfo::EObjectCode::DoorSurface) { - const CMappableObject& mapObj = mapa->GetMappableObject(info.GetLocalObjectIndex() / 6); - zeus::CTransform objXf = + CMappableObject& mapObj = mapa->GetMappableObject(info.GetLocalObjectIndex() / 6); + const zeus::CTransform objXf = parms.GetPlaneProjectionTransform() * zeus::CTransform::Translate(CMapArea::GetAreaPostTranslate(parms.GetWorld(), info.GetAreaIndex())) * mapObj.GetTransform(); @@ -376,249 +628,7 @@ void CMapWorld::DrawAreas(const CMapWorld::CMapWorldDrawParms& parms, int selAre } } -struct Support { - int x0_; - int x4_[3]; -}; - -struct Circle2 { - zeus::CVector2f x0_point; - float x8_radiusSq; -}; - -struct Circle { - zeus::CVector2f x0_point; - float x8_radius; - Circle(const Circle2& circ2) : x0_point(circ2.x0_point), x8_radius(std::sqrt(circ2.x8_radiusSq)) {} -}; - -static Circle2 ExactCircle1(const zeus::CVector2f* a) { return {*a, 0.f}; } - -static Circle2 ExactCircle2(const zeus::CVector2f* a, const zeus::CVector2f* b) { - Circle2 ret = {}; - ret.x0_point = 0.5f * (*a + *b); - ret.x8_radiusSq = (*b - *a).magSquared() * 0.25f; - return ret; -} - -static Circle2 ExactCircle3(const zeus::CVector2f* a, const zeus::CVector2f* b, const zeus::CVector2f* c) { - Circle2 ret = {}; - zeus::CVector2f d1 = *b - *a; - zeus::CVector2f d2 = *c - *a; - float cross = d1.cross(d2); - zeus::CVector2f magVec(d1.magSquared() * 0.5f, d2.magSquared() * 0.5f); - if (std::fabs(cross) > 0.01f) { - zeus::CVector2f tmp((d2.y() * magVec.x() - d1.y() * magVec.y()) / cross, - (d1.x() * magVec.y() - d2.x() * magVec.x()) / cross); - ret.x0_point = *a + tmp; - ret.x8_radiusSq = tmp.magSquared(); - } else { - ret.x8_radiusSq = FLT_MAX; - } - return ret; -} - -static bool PointInsideCircle(const zeus::CVector2f& point, const Circle2& circ, float& intersect) { - intersect = (point - circ.x0_point).magSquared() - circ.x8_radiusSq; - return intersect <= 0.f; -} - -static Circle2 UpdateSupport1(int idx, const zeus::CVector2f** list, Support& support) { - Circle2 ret = ExactCircle2(list[support.x4_[0]], list[idx]); - support.x0_ = 2; - support.x4_[1] = idx; - return ret; -} - -static Circle2 UpdateSupport2(int idx, const zeus::CVector2f** list, Support& support) { - Circle2 circs[3] = {}; - float intersect; - int circIdx = -1; - float minRad = FLT_MAX; - - circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]); - if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect)) { - minRad = circs[0].x8_radiusSq; - circIdx = 0; - } - - circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]); - if (circs[1].x8_radiusSq < minRad && PointInsideCircle(*list[support.x4_[0]], circs[1], intersect)) { - circIdx = 1; - } - - Circle2 ret; - if (circIdx != -1) { - ret = circs[circIdx]; - support.x4_[1 - circIdx] = idx; - } else { - ret = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]); - support.x0_ = 3; - support.x4_[2] = idx; - } - return ret; -} - -static Circle2 UpdateSupport3(int idx, const zeus::CVector2f** list, Support& support) { - Circle2 circs[6] = {}; - float intersect; - int circIdxA = -1; - int circIdxB = -1; - float minRadA = FLT_MAX; - float minRadB = FLT_MAX; - - circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]); - if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect)) { - if (PointInsideCircle(*list[support.x4_[2]], circs[0], intersect)) { - minRadA = circs[0].x8_radiusSq; - circIdxA = 0; - } else { - minRadB = intersect; - circIdxB = 0; - } - } else { - minRadB = intersect; - circIdxB = 0; - } - - circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]); - if (circs[1].x8_radiusSq < minRadA) { - if (PointInsideCircle(*list[support.x4_[0]], circs[1], intersect)) { - if (PointInsideCircle(*list[support.x4_[2]], circs[1], intersect)) { - minRadA = circs[1].x8_radiusSq; - circIdxA = 1; - } else if (intersect < minRadB) { - minRadB = intersect; - circIdxB = 1; - } - } else if (intersect < minRadB) { - minRadB = intersect; - circIdxB = 1; - } - } - - circs[2] = ExactCircle2(list[support.x4_[2]], list[idx]); - if (circs[2].x8_radiusSq < minRadA) { - if (PointInsideCircle(*list[support.x4_[0]], circs[2], intersect)) { - if (PointInsideCircle(*list[support.x4_[1]], circs[2], intersect)) { - minRadA = circs[2].x8_radiusSq; - circIdxA = 2; - } else if (intersect < minRadB) { - minRadB = intersect; - circIdxB = 2; - } - } else if (intersect < minRadB) { - minRadB = intersect; - circIdxB = 2; - } - } - - circs[3] = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]); - if (circs[3].x8_radiusSq < minRadA) { - if (PointInsideCircle(*list[support.x4_[2]], circs[3], intersect)) { - minRadA = circs[3].x8_radiusSq; - circIdxA = 3; - } else if (intersect < minRadB) { - minRadB = intersect; - circIdxB = 3; - } - } - - circs[4] = ExactCircle3(list[support.x4_[0]], list[support.x4_[2]], list[idx]); - if (circs[4].x8_radiusSq < minRadA) { - if (PointInsideCircle(*list[support.x4_[1]], circs[4], intersect)) { - minRadA = circs[4].x8_radiusSq; - circIdxA = 4; - } else if (intersect < minRadB) { - minRadB = intersect; - circIdxB = 4; - } - } - - circs[5] = ExactCircle3(list[support.x4_[1]], list[support.x4_[2]], list[idx]); - if (circs[5].x8_radiusSq < minRadA) { - if (PointInsideCircle(*list[support.x4_[0]], circs[5], intersect)) { - circIdxA = 5; - } else if (intersect < minRadB) { - circIdxB = 5; - } - } - - if (circIdxA == -1) - circIdxA = circIdxB; - - switch (circIdxA) { - case 0: - support.x0_ = 2; - support.x4_[1] = idx; - break; - case 1: - support.x0_ = 2; - support.x4_[0] = idx; - break; - case 2: - support.x0_ = 2; - support.x4_[0] = support.x4_[2]; - support.x4_[1] = idx; - break; - case 3: - support.x4_[2] = idx; - break; - case 4: - support.x4_[1] = idx; - break; - case 5: - support.x4_[0] = idx; - break; - default: - break; - } - - return circs[circIdxA]; -} - -typedef Circle2 (*FSupport)(int idx, const zeus::CVector2f** list, Support& support); -static const FSupport SupportFuncs[] = {nullptr, UpdateSupport1, UpdateSupport2, UpdateSupport3}; - -static Circle MinCircle(const std::vector& coords) { - Circle2 ret = {}; - if (coords.size() >= 1) { - std::unique_ptr randArr(new const zeus::CVector2f*[coords.size()]); - for (size_t i = 0; i < coords.size(); ++i) - randArr[i] = &coords[i]; - for (int i = coords.size() - 1; i >= 0; --i) { - int shuf = rand() % (i + 1); - if (shuf != i) - std::swap(randArr[i], randArr[shuf]); - } - ret = ExactCircle1(randArr[0]); - - Support support = {}; - support.x0_ = 1; - for (size_t i = 1; i < coords.size();) { - bool broke = false; - for (int j = 0; j < support.x0_; ++j) { - if ((*randArr[i] - *randArr[support.x4_[j]]).magSquared() < 0.01f) { - broke = true; - break; - } - } - float intersect; - if (!broke && !PointInsideCircle(*randArr[i], ret, intersect)) { - Circle2 circ = SupportFuncs[support.x0_](i, randArr.get(), support); - if (circ.x8_radiusSq > ret.x8_radiusSq) { - i = 0; - ret = circ; - continue; - } - } - ++i; - } - } - return ret; -} - -void CMapWorld::RecalculateWorldSphere(const CMapWorldInfo& mwInfo, const IWorld& wld) const { +void CMapWorld::RecalculateWorldSphere(const CMapWorldInfo& mwInfo, const IWorld& wld) { std::vector coords; coords.reserve(x0_areas.size() * 8); float zMin = FLT_MAX; @@ -638,11 +648,10 @@ void CMapWorld::RecalculateWorldSphere(const CMapWorldInfo& mwInfo, const IWorld } } - Circle circle = MinCircle(coords); - const_cast(this)->x3c_worldSphereRadius = circle.x8_radius; - const_cast(this)->x30_worldSpherePoint = - zeus::CVector3f(circle.x0_point.x(), circle.x0_point.y(), (zMin + zMax) * 0.5f); - const_cast(this)->x40_worldSphereHalfDepth = (zMax - zMin) * 0.5f; + const Circle circle = MinCircle(coords); + x3c_worldSphereRadius = circle.x8_radius; + x30_worldSpherePoint = zeus::CVector3f(circle.x0_point.x(), circle.x0_point.y(), (zMin + zMax) * 0.5f); + x40_worldSphereHalfDepth = (zMax - zMin) * 0.5f; } zeus::CVector3f CMapWorld::ConstrainToWorldVolume(const zeus::CVector3f& point, const zeus::CVector3f& lookVec) const { @@ -670,10 +679,8 @@ zeus::CVector3f CMapWorld::ConstrainToWorldVolume(const zeus::CVector3f& point, return ret; } -void CMapWorld::ClearTraversedFlags() const { - std::vector& flags = const_cast(this)->x20_traversed; - for (size_t i = 0; i < flags.size(); ++i) - flags[i] = false; +void CMapWorld::ClearTraversedFlags() { + std::fill(x20_traversed.begin(), x20_traversed.end(), false); } CFactoryFnReturn FMapWorldFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& param, diff --git a/Runtime/AutoMapper/CMapWorld.hpp b/Runtime/AutoMapper/CMapWorld.hpp index 6babb6ebd..554b0d5c2 100644 --- a/Runtime/AutoMapper/CMapWorld.hpp +++ b/Runtime/AutoMapper/CMapWorld.hpp @@ -71,6 +71,7 @@ public: void Lock() { x0_area.Lock(); } void Unlock() { x0_area.Unlock(); } bool IsLoaded() const { return x0_area.IsLoaded(); } + CMapArea* GetMapArea() { return x0_area.GetObj(); } const CMapArea* GetMapArea() const { return x0_area.GetObj(); } CMapAreaData* GetNextMapAreaData() { return x14_next; } const CMapAreaData* GetNextMapAreaData() const { return x14_next; } @@ -142,22 +143,25 @@ private: float x40_worldSphereHalfDepth = 0.f; public: - CMapWorld(CInputStream&); + explicit CMapWorld(CInputStream& in); u32 GetNumAreas() const { return x0_areas.size(); } + CMapArea* GetMapArea(int aid) { return x0_areas[aid].GetMapArea(); } const CMapArea* GetMapArea(int aid) const { return x0_areas[aid].GetMapArea(); } - bool IsMapAreaInBFSInfoVector(const CMapAreaData*, const std::vector&) const; - void SetWhichMapAreasLoaded(const IWorld&, int start, int count); - bool IsMapAreasStreaming() const; - void MoveMapAreaToList(CMapAreaData*, EMapAreaList); - s32 GetCurrentMapAreaDepth(const IWorld&, int areaIdx) const; - std::vector GetVisibleAreas(const IWorld&, const CMapWorldInfo&) const; - void Draw(const CMapWorldDrawParms&, int, int, float, float, bool) const; - void DoBFS(const IWorld&, int, int, float, float, bool, std::vector&) const; - bool IsMapAreaValid(const IWorld&, int, bool) const; - void DrawAreas(const CMapWorldDrawParms&, int, const std::vector&, bool) const; - void RecalculateWorldSphere(const CMapWorldInfo&, const IWorld&) const; - zeus::CVector3f ConstrainToWorldVolume(const zeus::CVector3f&, const zeus::CVector3f&) const; - void ClearTraversedFlags() const; + bool IsMapAreaInBFSInfoVector(const CMapAreaData* area, const std::vector& vec) const; + void SetWhichMapAreasLoaded(const IWorld& wld, int start, int count); + bool IsMapAreasStreaming(); + void MoveMapAreaToList(CMapAreaData* data, EMapAreaList list); + s32 GetCurrentMapAreaDepth(const IWorld& wld, TAreaId aid); + std::vector GetVisibleAreas(const IWorld& wld, const CMapWorldInfo& mwInfo) const; + void Draw(const CMapWorldDrawParms& parms, int curArea, int otherArea, float depth1, float depth2, bool inMapScreen); + void DoBFS(const IWorld& wld, int startArea, int areaCount, float surfDepth, float outlineDepth, bool checkLoad, + std::vector& bfsInfos); + bool IsMapAreaValid(const IWorld& wld, int areaIdx, bool checkLoad) const; + void DrawAreas(const CMapWorldDrawParms& parms, int selArea, const std::vector& bfsInfos, + bool inMapScreen); + void RecalculateWorldSphere(const CMapWorldInfo& mwInfo, const IWorld& wld); + zeus::CVector3f ConstrainToWorldVolume(const zeus::CVector3f& point, const zeus::CVector3f& lookVec) const; + void ClearTraversedFlags(); }; CFactoryFnReturn FMapWorldFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& param, diff --git a/Runtime/AutoMapper/CMapWorldInfo.cpp b/Runtime/AutoMapper/CMapWorldInfo.cpp index 5cb5c73b0..280dfe9ce 100644 --- a/Runtime/AutoMapper/CMapWorldInfo.cpp +++ b/Runtime/AutoMapper/CMapWorldInfo.cpp @@ -10,43 +10,47 @@ CMapWorldInfo::CMapWorldInfo(CBitStreamReader& reader, const CSaveWorld& savw, C x4_visitedAreas.reserve((worldMem.GetAreaCount() + 31) / 32); for (u32 i = 0; i < worldMem.GetAreaCount(); ++i) { - bool visited = reader.ReadEncoded(1); + const bool visited = reader.ReadEncoded(1) != 0; SetAreaVisited(i, visited); } x18_mappedAreas.reserve((worldMem.GetAreaCount() + 31) / 32); for (u32 i = 0; i < worldMem.GetAreaCount(); ++i) { - bool mapped = reader.ReadEncoded(1); + const bool mapped = reader.ReadEncoded(1) != 0; SetIsMapped(i, mapped); } - for (TEditorId doorId : savw.GetDoors()) - SetDoorVisited(doorId, reader.ReadEncoded(1)); + for (const TEditorId doorId : savw.GetDoors()) { + SetDoorVisited(doorId, reader.ReadEncoded(1) != 0); + } - x38_mapStationUsed = reader.ReadEncoded(1); + x38_mapStationUsed = reader.ReadEncoded(1) != 0; } void CMapWorldInfo::PutTo(CBitStreamWriter& writer, const CSaveWorld& savw, CAssetId mlvlId) const { const CSaveWorldMemory& worldMem = g_MemoryCardSys->GetSaveWorldMemory(mlvlId); for (u32 i = 0; i < worldMem.GetAreaCount(); ++i) { - if (i < x0_visitedAreasAllocated) - writer.WriteEncoded(IsAreaVisited(i), 1); - else + if (i < x0_visitedAreasAllocated) { + writer.WriteEncoded(u32(IsAreaVisited(i)), 1); + } else { writer.WriteEncoded(0, 1); + } } for (u32 i = 0; i < worldMem.GetAreaCount(); ++i) { - if (i < x14_mappedAreasAllocated) - writer.WriteEncoded(IsMapped(i), 1); - else + if (i < x14_mappedAreasAllocated) { + writer.WriteEncoded(u32(IsMapped(i)), 1); + } else { writer.WriteEncoded(0, 1); + } } - for (TEditorId doorId : savw.GetDoors()) - writer.WriteEncoded(IsDoorVisited(doorId), 1); + for (const TEditorId doorId : savw.GetDoors()) { + writer.WriteEncoded(u32(IsDoorVisited(doorId)), 1); + } - writer.WriteEncoded(x38_mapStationUsed, 1); + writer.WriteEncoded(u32(x38_mapStationUsed), 1); } void CMapWorldInfo::SetDoorVisited(TEditorId eid, bool visited) { x28_visitedDoors[eid] = visited; } @@ -55,40 +59,44 @@ bool CMapWorldInfo::IsDoorVisited(TEditorId eid) const { return x28_visitedDoors bool CMapWorldInfo::IsAreaVisited(TAreaId aid) const { if (u32(aid) + 1 > x0_visitedAreasAllocated) { - const_cast(*this).x4_visitedAreas.resize((aid + 32) / 32); - const_cast(*this).x0_visitedAreasAllocated = aid + 1; + x4_visitedAreas.resize((u32(aid) + 32) / 32); + x0_visitedAreasAllocated = u32(aid) + 1; } - return (x4_visitedAreas[aid / 32] >> (aid % 32)) & 0x1; + return ((x4_visitedAreas[aid / 32] >> (aid % 32)) & 1) != 0; } void CMapWorldInfo::SetAreaVisited(TAreaId aid, bool visited) { if (u32(aid) + 1 > x0_visitedAreasAllocated) { - x4_visitedAreas.resize((aid + 32) / 32); - x0_visitedAreasAllocated = aid + 1; + x4_visitedAreas.resize((u32(aid) + 32) / 32); + x0_visitedAreasAllocated = u32(aid) + 1; + } + + if (visited) { + x4_visitedAreas[aid / 32] |= 1U << (aid % 32); + } else { + x4_visitedAreas[aid / 32] &= ~(1U << (aid % 32)); } - if (visited) - x4_visitedAreas[aid / 32] |= 1 << (aid % 32); - else - x4_visitedAreas[aid / 32] &= ~(1 << (aid % 32)); } bool CMapWorldInfo::IsMapped(TAreaId aid) const { if (u32(aid) + 1 > x14_mappedAreasAllocated) { - const_cast(*this).x18_mappedAreas.resize((aid + 32) / 32); - const_cast(*this).x14_mappedAreasAllocated = aid + 1; + x18_mappedAreas.resize((u32(aid) + 32) / 32); + x14_mappedAreasAllocated = u32(aid) + 1; } - return (x18_mappedAreas[aid / 32] >> (aid % 32)) & 0x1; + return ((x18_mappedAreas[aid / 32] >> (aid % 32)) & 1) != 0; } void CMapWorldInfo::SetIsMapped(TAreaId aid, bool mapped) { if (u32(aid) + 1 > x14_mappedAreasAllocated) { - x18_mappedAreas.resize((aid + 32) / 32); - x14_mappedAreasAllocated = aid + 1; + x18_mappedAreas.resize((u32(aid) + 32) / 32); + x14_mappedAreasAllocated = u32(aid) + 1; + } + + if (mapped) { + x18_mappedAreas[aid / 32] |= 1U << (aid % 32); + } else { + x18_mappedAreas[aid / 32] &= ~(1U << (aid % 32)); } - if (mapped) - x18_mappedAreas[aid / 32] |= 1 << (aid % 32); - else - x18_mappedAreas[aid / 32] &= ~(1 << (aid % 32)); } bool CMapWorldInfo::IsWorldVisible(TAreaId aid) const { return x38_mapStationUsed || IsMapped(aid); } @@ -96,12 +104,16 @@ bool CMapWorldInfo::IsWorldVisible(TAreaId aid) const { return x38_mapStationUse bool CMapWorldInfo::IsAreaVisible(TAreaId aid) const { return IsAreaVisited(aid) || IsMapped(aid); } bool CMapWorldInfo::IsAnythingSet() const { - for (u32 i = 0; i < x0_visitedAreasAllocated; ++i) - if (x4_visitedAreas[i / 32] & (1 << (i % 32))) + for (u32 i = 0; i < x0_visitedAreasAllocated; ++i) { + if ((x4_visitedAreas[i / 32] & (1U << (i % 32))) != 0) { return true; - for (u32 i = 0; i < x14_mappedAreasAllocated; ++i) - if (x18_mappedAreas[i / 32] & (1 << (i % 32))) + } + } + for (u32 i = 0; i < x14_mappedAreasAllocated; ++i) { + if ((x18_mappedAreas[i / 32] & (1U << (i % 32))) != 0) { return true; + } + } return x38_mapStationUsed; } diff --git a/Runtime/AutoMapper/CMapWorldInfo.hpp b/Runtime/AutoMapper/CMapWorldInfo.hpp index ae18e2d3e..7a468cd37 100644 --- a/Runtime/AutoMapper/CMapWorldInfo.hpp +++ b/Runtime/AutoMapper/CMapWorldInfo.hpp @@ -9,16 +9,16 @@ namespace urde { class CSaveWorld; class CMapWorldInfo { - u32 x0_visitedAreasAllocated = 0; - std::vector x4_visitedAreas; - u32 x14_mappedAreasAllocated = 0; - std::vector x18_mappedAreas; + mutable u32 x0_visitedAreasAllocated = 0; + mutable std::vector x4_visitedAreas; + mutable u32 x14_mappedAreasAllocated = 0; + mutable std::vector x18_mappedAreas; std::map x28_visitedDoors; bool x38_mapStationUsed = false; public: CMapWorldInfo() = default; - CMapWorldInfo(CBitStreamReader&, const CSaveWorld& saveWorld, CAssetId mlvlId); + explicit CMapWorldInfo(CBitStreamReader&, const CSaveWorld& saveWorld, CAssetId mlvlId); void PutTo(CBitStreamWriter& writer, const CSaveWorld& savw, CAssetId mlvlId) const; bool IsMapped(TAreaId) const; void SetIsMapped(TAreaId, bool); diff --git a/Runtime/AutoMapper/CMappableObject.cpp b/Runtime/AutoMapper/CMappableObject.cpp index 7dcdb02ae..c79ccf24f 100644 --- a/Runtime/AutoMapper/CMappableObject.cpp +++ b/Runtime/AutoMapper/CMappableObject.cpp @@ -8,9 +8,11 @@ #include "Runtime/Graphics/CTexture.hpp" namespace urde { -zeus::CVector3f CMappableObject::skDoorVerts[8] = {}; +std::array CMappableObject::skDoorVerts{}; -static const u32 DoorIndices[] = {6, 4, 2, 0, 3, 1, 7, 5, 1, 0, 5, 4, 7, 6, 3, 2, 3, 2, 1, 0, 5, 4, 7, 6}; +constexpr std::array DoorIndices{ + 6, 4, 2, 0, 3, 1, 7, 5, 1, 0, 5, 4, 7, 6, 3, 2, 3, 2, 1, 0, 5, 4, 7, 6, +}; CMappableObject::CMappableObject(const void* buf) { athena::io::MemoryReader r(buf, 64); @@ -106,12 +108,12 @@ std::pair CMappableObject::GetDoorColors(int curArea void CMappableObject::PostConstruct(const void*) { x10_transform = AdjustTransformForType(); } -void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha, bool needsVtxLoad) const { +void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha, bool needsVtxLoad) { SCOPED_GRAPHICS_DEBUG_GROUP("CMappableObject::Draw", zeus::skCyan); if (IsDoorType(x0_type)) { std::pair colors = GetDoorColors(curArea, mwInfo, alpha); for (int s = 0; s < 6; ++s) { - DoorSurface& ds = const_cast(*m_doorSurface); + DoorSurface& ds = *m_doorSurface; ds.m_surface.draw(colors.first, s * 4, 4); CLineRenderer& line = ds.m_outline; const u32* baseIdx = &DoorIndices[s * 4]; @@ -164,22 +166,24 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha iconColor.a() *= alpha; TLockedToken tex = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), iconRes}); - if (!m_texQuadFilter || m_texQuadFilter->GetTex().GetObj() != tex.GetObj()) - const_cast(this)->m_texQuadFilter.emplace(EFilterType::Add, tex, - CTexturedQuadFilter::ZTest::GEqual); + if (!m_texQuadFilter || m_texQuadFilter->GetTex().GetObj() != tex.GetObj()) { + m_texQuadFilter.emplace(EFilterType::Add, tex, CTexturedQuadFilter::ZTest::GEqual); + } - CTexturedQuadFilter::Vert verts[4] = {{{-2.6f, 0.f, 2.6f}, {0.f, 1.f}}, - {{-2.6f, 0.f, -2.6f}, {0.f, 0.f}}, - {{2.6f, 0.f, 2.6f}, {1.f, 1.f}}, - {{2.6f, 0.f, -2.6f}, {1.f, 0.f}}}; - const_cast(this)->m_texQuadFilter->drawVerts(iconColor, verts); + const std::array verts{{ + {{-2.6f, 0.f, 2.6f}, {0.f, 1.f}}, + {{-2.6f, 0.f, -2.6f}, {0.f, 0.f}}, + {{2.6f, 0.f, 2.6f}, {1.f, 1.f}}, + {{2.6f, 0.f, -2.6f}, {1.f, 0.f}}, + }}; + m_texQuadFilter->drawVerts(iconColor, verts.data()); } } void CMappableObject::DrawDoorSurface(int curArea, const CMapWorldInfo& mwInfo, float alpha, int surfIdx, - bool needsVtxLoad) const { + bool needsVtxLoad) { std::pair colors = GetDoorColors(curArea, mwInfo, alpha); - DoorSurface& ds = const_cast(*m_doorSurface); + DoorSurface& ds = *m_doorSurface; ds.m_surface.draw(colors.first, surfIdx * 4, 4); CLineRenderer& line = ds.m_outline; const u32* baseIdx = &DoorIndices[surfIdx * 4]; @@ -237,9 +241,10 @@ boo::ObjToken CMappableObject::g_doorIbo; void CMappableObject::ReadAutoMapperTweaks(const ITweakAutoMapper& tweaks) { const zeus::CVector3f& center = tweaks.GetDoorCenter(); - zeus::simd_floats centerF(center.mSimd); - zeus::CVector3f* doorVerts = CMappableObject::skDoorVerts; - /* Wrap door verts around -Z to build surface */ + const zeus::simd_floats centerF(center.mSimd); + + // Wrap door verts around -Z to build surface + auto& doorVerts = skDoorVerts; doorVerts[0].assign(-centerF[2], -centerF[1], 0.f); doorVerts[1].assign(-centerF[2], -centerF[1], 2.f * centerF[0]); doorVerts[2].assign(-centerF[2], centerF[1], 0.f); @@ -250,8 +255,8 @@ void CMappableObject::ReadAutoMapperTweaks(const ITweakAutoMapper& tweaks) { doorVerts[7].assign(.2f * -centerF[2], centerF[1], 2.f * centerF[0]); CGraphics::CommitResources([](boo::IGraphicsDataFactory::Context& ctx) { - g_doorVbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, skDoorVerts, 16, 8); - g_doorIbo = ctx.newStaticBuffer(boo::BufferUse::Index, DoorIndices, 4, 24); + g_doorVbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, skDoorVerts.data(), 16, skDoorVerts.size()); + g_doorIbo = ctx.newStaticBuffer(boo::BufferUse::Index, DoorIndices.data(), 4, DoorIndices.size()); return true; } BooTrace); } diff --git a/Runtime/AutoMapper/CMappableObject.hpp b/Runtime/AutoMapper/CMappableObject.hpp index 53cde42bb..6bedcc1d8 100644 --- a/Runtime/AutoMapper/CMappableObject.hpp +++ b/Runtime/AutoMapper/CMappableObject.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -52,7 +53,7 @@ public: enum class EVisMode { Always, MapStationOrVisit, Visit, Never, MapStationOrVisit2 }; private: - static zeus::CVector3f skDoorVerts[8]; + static std::array skDoorVerts; EMappableObjectType x0_type; EVisMode x4_visibilityMode; @@ -63,7 +64,7 @@ private: struct DoorSurface { CMapSurfaceShader m_surface; CLineRenderer m_outline; - DoorSurface(boo::IGraphicsDataFactory::Context& ctx) + explicit DoorSurface(boo::IGraphicsDataFactory::Context& ctx) : m_surface(ctx, g_doorVbo, g_doorIbo) , m_outline(ctx, CLineRenderer::EPrimitiveMode::LineLoop, 5, nullptr, false, false, true) {} }; @@ -74,13 +75,13 @@ private: std::pair GetDoorColors(int idx, const CMapWorldInfo& mwInfo, float alpha) const; public: - CMappableObject(const void* buf); + explicit CMappableObject(const void* buf); CMappableObject(CMappableObject&&) = default; void PostConstruct(const void*); const zeus::CTransform& GetTransform() const { return x10_transform; } EMappableObjectType GetType() const { return x0_type; } - void Draw(int, const CMapWorldInfo&, float, bool) const; - void DrawDoorSurface(int curArea, const CMapWorldInfo& mwInfo, float alpha, int surfIdx, bool needsVtxLoad) const; + void Draw(int, const CMapWorldInfo&, float, bool); + void DrawDoorSurface(int curArea, const CMapWorldInfo& mwInfo, float alpha, int surfIdx, bool needsVtxLoad); zeus::CVector3f BuildSurfaceCenterPoint(int surfIdx) const; bool IsDoorConnectedToArea(int idx, const CStateManager&) const; bool IsDoorConnectedToVisitedArea(const CStateManager&) const; diff --git a/Runtime/CArchitectureQueue.hpp b/Runtime/CArchitectureQueue.hpp index 8aae965a0..1c14c2a47 100644 --- a/Runtime/CArchitectureQueue.hpp +++ b/Runtime/CArchitectureQueue.hpp @@ -16,7 +16,7 @@ public: return msg; } void Clear() { m_list.clear(); } - operator bool() const { return m_list.size() != 0; } + explicit operator bool() const { return !m_list.empty(); } }; } // namespace urde diff --git a/Runtime/CDependencyGroup.hpp b/Runtime/CDependencyGroup.hpp index 603fb2471..e38a176d2 100644 --- a/Runtime/CDependencyGroup.hpp +++ b/Runtime/CDependencyGroup.hpp @@ -8,7 +8,7 @@ class CDependencyGroup { std::vector x0_objectTags; public: - CDependencyGroup(CInputStream& in); + explicit CDependencyGroup(CInputStream& in); void ReadFromStream(CInputStream& in); const std::vector& GetObjectTagVector() const { return x0_objectTags; } }; diff --git a/Runtime/CGameHintInfo.cpp b/Runtime/CGameHintInfo.cpp index 9544f593c..887e15224 100644 --- a/Runtime/CGameHintInfo.cpp +++ b/Runtime/CGameHintInfo.cpp @@ -31,15 +31,15 @@ CGameHintInfo::SHintLocation::SHintLocation(CInputStream& in, s32) , x8_areaId(in.readUint32Big()) , xc_stringId(in.readUint32Big()) {} -int CGameHintInfo::FindHintIndex(const char* str) { +int CGameHintInfo::FindHintIndex(std::string_view str) { const std::vector& gameHints = g_MemoryCardSys->GetHints(); - const auto& it = std::find_if(gameHints.begin(), gameHints.end(), - [&str](const CGameHint& gh) -> bool { return gh.GetName() == str; }); + const auto it = + std::find_if(gameHints.cbegin(), gameHints.cend(), [&str](const CGameHint& gh) { return gh.GetName() == str; }); - return (it != gameHints.end() ? it - gameHints.begin() : -1); + return it != gameHints.cend() ? it - gameHints.cbegin() : -1; } -CFactoryFnReturn FHintFactory(const SObjectTag&, CInputStream& in, const CVParamTransfer, CObjectReference*) { +CFactoryFnReturn FHintFactory(const SObjectTag&, CInputStream& in, const CVParamTransfer&, CObjectReference*) { in.readUint32Big(); s32 version = in.readInt32Big(); diff --git a/Runtime/CGameHintInfo.hpp b/Runtime/CGameHintInfo.hpp index 7b0e75ee3..0ce7b2caa 100644 --- a/Runtime/CGameHintInfo.hpp +++ b/Runtime/CGameHintInfo.hpp @@ -42,8 +42,8 @@ private: public: CGameHintInfo(CInputStream&, s32); const std::vector& GetHints() const { return x0_hints; } - static int FindHintIndex(const char* str); + static int FindHintIndex(std::string_view str); }; -CFactoryFnReturn FHintFactory(const SObjectTag&, CInputStream&, const CVParamTransfer, CObjectReference*); +CFactoryFnReturn FHintFactory(const SObjectTag&, CInputStream&, const CVParamTransfer&, CObjectReference*); } // namespace urde diff --git a/Runtime/CGameOptions.cpp b/Runtime/CGameOptions.cpp index bd6dece7c..fff4226eb 100644 --- a/Runtime/CGameOptions.cpp +++ b/Runtime/CGameOptions.cpp @@ -1,5 +1,7 @@ #include "Runtime/CGameOptions.hpp" +#include + #include "Runtime/CGameHintInfo.hpp" #include "Runtime/CGameState.hpp" #include "Runtime/CMemoryCardSys.hpp" @@ -522,18 +524,20 @@ CHintOptions::CHintOptions(CBitStreamReader& stream) { x0_hintStates.reserve(hints.size()); u32 hintIdx = 0; - for (const auto& hint : hints) { - (void)hint; - EHintState state = EHintState(stream.ReadEncoded(2)); - union { s32 i; float f; } timeBits = {stream.ReadEncoded(32)}; - float time = timeBits.f; - if (state == EHintState::Zero) + for ([[maybe_unused]] const auto& hint : hints) { + const auto state = EHintState(stream.ReadEncoded(2)); + const s32 timeBits = stream.ReadEncoded(32); + float time; + std::memcpy(&time, &timeBits, sizeof(s32)); + if (state == EHintState::Zero) { time = 0.f; + } x0_hintStates.emplace_back(state, time, false); - if (x10_nextHintIdx == -1 && state == EHintState::Displaying) + if (x10_nextHintIdx == -1 && state == EHintState::Displaying) { x10_nextHintIdx = hintIdx; + } ++hintIdx; } } @@ -541,8 +545,11 @@ CHintOptions::CHintOptions(CBitStreamReader& stream) { void CHintOptions::PutTo(CBitStreamWriter& writer) const { for (const SHintState& hint : x0_hintStates) { writer.WriteEncoded(u32(hint.x0_state), 2); - union { float f; u32 i; } timeBits = {hint.x4_time}; - writer.WriteEncoded(timeBits.i, 32); + + u32 timeBits; + std::memcpy(&timeBits, &hint.x4_time, sizeof(timeBits)); + + writer.WriteEncoded(timeBits, 32); } } @@ -578,43 +585,51 @@ const CHintOptions::SHintState* CHintOptions::GetCurrentDisplayedHint() const { return nullptr; } -void CHintOptions::DelayHint(const char* name) { - int idx = CGameHintInfo::FindHintIndex(name); - if (idx == -1) +void CHintOptions::DelayHint(std::string_view name) { + const int idx = CGameHintInfo::FindHintIndex(name); + if (idx == -1) { return; + } - if (x10_nextHintIdx == idx) - for (SHintState& state : x0_hintStates) + if (x10_nextHintIdx == idx) { + for (SHintState& state : x0_hintStates) { state.x4_time += 60.f; + } + } x0_hintStates[idx].x0_state = EHintState::Delayed; } -void CHintOptions::ActivateImmediateHintTimer(const char* name) { - int idx = CGameHintInfo::FindHintIndex(name); - if (idx == -1) +void CHintOptions::ActivateImmediateHintTimer(std::string_view name) { + const int idx = CGameHintInfo::FindHintIndex(name); + if (idx == -1) { return; + } SHintState& hintState = x0_hintStates[idx]; const CGameHintInfo::CGameHint& hint = g_MemoryCardSys->GetHints()[idx]; - if (hintState.x0_state != EHintState::Zero) + if (hintState.x0_state != EHintState::Zero) { return; + } hintState.x0_state = EHintState::Waiting; hintState.x4_time = hint.GetImmediateTime(); } -void CHintOptions::ActivateContinueDelayHintTimer(const char* name) { +void CHintOptions::ActivateContinueDelayHintTimer(std::string_view name) { int idx = x10_nextHintIdx; - if (idx != 0) + if (idx != 0) { idx = CGameHintInfo::FindHintIndex(name); - if (idx == -1) + } + if (idx == -1) { return; + } SHintState& hintState = x0_hintStates[idx]; const CGameHintInfo::CGameHint& hint = g_MemoryCardSys->GetHints()[idx]; - if (hintState.x0_state != EHintState::Displaying) + if (hintState.x0_state != EHintState::Displaying) { return; + } hintState.x4_time = hint.GetTextTime(); } diff --git a/Runtime/CGameOptions.hpp b/Runtime/CGameOptions.hpp index cc290db78..554ecea86 100644 --- a/Runtime/CGameOptions.hpp +++ b/Runtime/CGameOptions.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include "Runtime/CSaveWorld.hpp" @@ -70,7 +71,7 @@ class CPersistentOptions { public: CPersistentOptions() = default; - CPersistentOptions(CBitStreamReader& stream); + explicit CPersistentOptions(CBitStreamReader& stream); bool GetCinematicState(CAssetId mlvlId, TEditorId cineId) const; void SetCinematicState(CAssetId mlvlId, TEditorId cineId, bool state); @@ -133,7 +134,7 @@ class CGameOptions { public: CGameOptions(); - CGameOptions(CBitStreamReader& stream); + explicit CGameOptions(CBitStreamReader& stream); void ResetToDefaults(); void InitSoundMode(); void EnsureSettings(); @@ -200,14 +201,14 @@ private: public: CHintOptions() = default; - CHintOptions(CBitStreamReader& stream); + explicit CHintOptions(CBitStreamReader& stream); void PutTo(CBitStreamWriter& writer) const; void SetNextHintTime(); void InitializeMemoryState(); const SHintState* GetCurrentDisplayedHint() const; - void DelayHint(const char* name); - void ActivateImmediateHintTimer(const char* name); - void ActivateContinueDelayHintTimer(const char* name); + void DelayHint(std::string_view name); + void ActivateImmediateHintTimer(std::string_view name); + void ActivateContinueDelayHintTimer(std::string_view name); void DismissDisplayedHint(); u32 GetNextHintIdx() const; const std::vector& GetHintStates() const { return x0_hintStates; } diff --git a/Runtime/CGameState.cpp b/Runtime/CGameState.cpp index a3c123bdb..2bd9531f6 100644 --- a/Runtime/CGameState.cpp +++ b/Runtime/CGameState.cpp @@ -38,15 +38,17 @@ CWorldLayerState::CWorldLayerState(CBitStreamReader& reader, const CSaveWorld& s void CWorldLayerState::PutTo(CBitStreamWriter& writer) const { u32 totalLayerCount = 0; - for (int i = 0; i < x0_areaLayers.size(); ++i) - totalLayerCount += GetAreaLayerCount(i) - 1; + for (size_t i = 0; i < x0_areaLayers.size(); ++i) { + totalLayerCount += GetAreaLayerCount(s32(i)) - 1; + } writer.WriteEncoded(totalLayerCount, 10); - for (int i = 0; i < x0_areaLayers.size(); ++i) { - u32 count = GetAreaLayerCount(i); - for (u32 l = 1; l < count; ++l) - writer.WriteEncoded(IsLayerActive(i, l), 1); + for (size_t i = 0; i < x0_areaLayers.size(); ++i) { + const u32 count = GetAreaLayerCount(s32(i)); + for (u32 l = 1; l < count; ++l) { + writer.WriteEncoded(IsLayerActive(s32(i), s32(l)), 1); + } } } @@ -95,8 +97,9 @@ CGameState::GameFileStateInfo CGameState::LoadGameFileState(const u8* data) { CBitStreamReader stream(data, 4096); GameFileStateInfo ret; - for (u32 i = 0; i < 128; i++) + for (u32 i = 0; i < 128; i++) { stream.ReadEncoded(8); + } ret.x14_timestamp = stream.ReadEncoded(32); ret.x20_hardMode = stream.ReadEncoded(1); @@ -111,6 +114,7 @@ CGameState::GameFileStateInfo CGameState::LoadGameFileState(const u8* data) { CPlayerState playerState(stream); ret.x10_energyTanks = playerState.GetItemCapacity(CPlayerState::EItemType::EnergyTanks); + ret.xc_health = playerState.GetHealthInfo().GetHP(); u32 itemPercent; if (origMLVL == 0x158EFE17) @@ -142,8 +146,9 @@ CGameState::CGameState(CBitStreamReader& stream, u32 saveIdx) : x20c_saveFileIdx x9c_transManager = std::make_shared(); x228_25_initPowerupsAtFirstSpawn = true; - for (u32 i = 0; i < 128; i++) - x0_[i] = stream.ReadEncoded(8); + for (bool& value : x0_) { + value = stream.ReadEncoded(8) != 0; + } stream.ReadEncoded(32); x228_24_hardMode = stream.ReadEncoded(1); @@ -204,9 +209,10 @@ void CGameState::WriteBackupBuf() { PutTo(w); } -void CGameState::PutTo(CBitStreamWriter& writer) const { - for (u32 i = 0; i < 128; i++) - writer.WriteEncoded(x0_[i], 8); +void CGameState::PutTo(CBitStreamWriter& writer) { + for (const bool value : x0_) { + writer.WriteEncoded(u32(value), 8); + } writer.WriteEncoded(CBasics::ToWiiTime(std::chrono::system_clock::now()) / CBasics::TICKS_PER_SECOND, 32); writer.WriteEncoded(x228_24_hardMode, 1); @@ -226,7 +232,7 @@ void CGameState::PutTo(CBitStreamWriter& writer) const { for (const auto& memWorld : memWorlds) { TLockedToken saveWorld = g_SimplePool->GetObj(SObjectTag{FOURCC('SAVW'), memWorld.second.GetSaveWorldAssetId()}); - const CWorldState& wld = const_cast(*this).StateForWorld(memWorld.first); + const CWorldState& wld = StateForWorld(memWorld.first); wld.PutTo(writer, *saveWorld); } } diff --git a/Runtime/CGameState.hpp b/Runtime/CGameState.hpp index 5790af0d9..32349f8d9 100644 --- a/Runtime/CGameState.hpp +++ b/Runtime/CGameState.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -67,7 +68,7 @@ public: class CGameState { friend class CStateManager; - bool x0_[128] = {}; + std::array x0_{}; u32 x80_; CAssetId x84_mlvlId; std::vector x88_worldStates; @@ -116,7 +117,7 @@ public: void SetFileIdx(u32 idx) { x20c_saveFileIdx = idx; } void SetCardSerial(u64 serial) { x210_cardSerial = serial; } u64 GetCardSerial() const { return x210_cardSerial; } - void PutTo(CBitStreamWriter& writer) const; + void PutTo(CBitStreamWriter& writer); float GetHardModeDamageMultiplier() const; float GetHardModeWeaponMultiplier() const; void InitializeMemoryWorlds(); diff --git a/Runtime/CIOWin.hpp b/Runtime/CIOWin.hpp index ef5b5f396..43a3df3d8 100644 --- a/Runtime/CIOWin.hpp +++ b/Runtime/CIOWin.hpp @@ -16,13 +16,13 @@ class CIOWin { public: enum class EMessageReturn { Normal = 0, Exit = 1, RemoveIOWinAndExit = 2, RemoveIOWin = 3 }; - CIOWin(std::string_view name) : x4_name(name) { m_nameHash = std::hash()(name); } + explicit CIOWin(std::string_view name) : x4_name(name) { m_nameHash = std::hash()(name); } virtual ~CIOWin() = default; virtual EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&) = 0; virtual bool GetIsContinueDraw() const { return true; } - virtual void Draw() const {} - virtual void PreDraw() const {} + virtual void Draw() {} + virtual void PreDraw() {} std::string_view GetName() const { return x4_name; } size_t GetNameHash() const { return m_nameHash; } diff --git a/Runtime/CMFGameBase.hpp b/Runtime/CMFGameBase.hpp index c99416549..b73d1c71c 100644 --- a/Runtime/CMFGameBase.hpp +++ b/Runtime/CMFGameBase.hpp @@ -6,12 +6,12 @@ namespace urde { class CMFGameBase : public CIOWin { public: - CMFGameBase(const char* name) : CIOWin(name) {} + explicit CMFGameBase(const char* name) : CIOWin(name) {} }; class CMFGameLoaderBase : public CIOWin { public: - CMFGameLoaderBase(const char* name) : CIOWin(name) {} + explicit CMFGameLoaderBase(const char* name) : CIOWin(name) {} }; } // namespace urde diff --git a/Runtime/CMainFlowBase.hpp b/Runtime/CMainFlowBase.hpp index 22a17f39f..f16ad0fbe 100644 --- a/Runtime/CMainFlowBase.hpp +++ b/Runtime/CMainFlowBase.hpp @@ -11,7 +11,7 @@ protected: EClientFlowStates x14_gameState = EClientFlowStates::Unspecified; public: - CMainFlowBase(const char* name) : CIOWin(name) {} + explicit CMainFlowBase(const char* name) : CIOWin(name) {} EMessageReturn OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) override; virtual void AdvanceGameState(CArchitectureQueue& queue) = 0; virtual void SetGameState(EClientFlowStates state, CArchitectureQueue& queue) = 0; diff --git a/Runtime/CMemoryCardSys.cpp b/Runtime/CMemoryCardSys.cpp index a01ccbe7a..a3de34a70 100644 --- a/Runtime/CMemoryCardSys.cpp +++ b/Runtime/CMemoryCardSys.cpp @@ -30,12 +30,12 @@ bool CSaveWorldIntermediate::InitializePump() { x4_strgId = wld.IGetStringTableAssetId(); x8_savwId = wld.IGetSaveWorldAssetId(); - u32 areaCount = wld.IGetAreaCount(); + const u32 areaCount = wld.IGetAreaCount(); xc_areaIds.reserve(areaCount); for (u32 i = 0; i < areaCount; ++i) { const IGameArea* area = wld.IGetAreaAlways(i); - xc_areaIds.push_back(area->IGetAreaId()); + xc_areaIds.emplace_back(area->IGetAreaId()); } CAssetId mlvlId = wld.IGetWorldAssetId(); diff --git a/Runtime/CMemoryCardSys.hpp b/Runtime/CMemoryCardSys.hpp index 82b71a236..6281ca773 100644 --- a/Runtime/CMemoryCardSys.hpp +++ b/Runtime/CMemoryCardSys.hpp @@ -76,7 +76,7 @@ public: ECardResult result; CardResult(ECardResult res) : result(res) {} operator ECardResult() const { return result; } - operator bool() const { return result != ECardResult::READY; } + explicit operator bool() const { return result != ECardResult::READY; } }; struct CardFileHandle { diff --git a/Runtime/CObjectList.hpp b/Runtime/CObjectList.hpp index 121781177..a9f7a443d 100644 --- a/Runtime/CObjectList.hpp +++ b/Runtime/CObjectList.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "Runtime/RetroTypes.hpp" #include "Runtime/World/CEntity.hpp" @@ -25,7 +27,7 @@ class CObjectList { s16 next = -1; s16 prev = -1; }; - SObjectListEntry x0_list[1024]; // was an rstl::prereserved_vector + std::array x0_list; // was an rstl::prereserved_vector EGameObjectList x2004_listEnum; s16 x2008_firstId = -1; u16 x200a_count = 0; diff --git a/Runtime/CPlayMovieBase.hpp b/Runtime/CPlayMovieBase.hpp index 068ef615a..0c86a81f4 100644 --- a/Runtime/CPlayMovieBase.hpp +++ b/Runtime/CPlayMovieBase.hpp @@ -11,7 +11,7 @@ class CPlayMovieBase : public CIOWin { public: CPlayMovieBase(const char* iowName, const char* path) : CIOWin(iowName), x18_moviePlayer(path, 0.0, false, false) {} EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&) override { return EMessageReturn::Normal; } - void Draw() const override {} + void Draw() override {} }; } // namespace urde diff --git a/Runtime/CPlayerState.cpp b/Runtime/CPlayerState.cpp index 2a5373e4f..38e9e9841 100644 --- a/Runtime/CPlayerState.cpp +++ b/Runtime/CPlayerState.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "Runtime/CMemoryCardSys.hpp" #include "Runtime/CStateManager.hpp" @@ -81,12 +82,12 @@ CPlayerState::CPlayerState() : x188_staticIntf(5) { CPlayerState::CPlayerState(CBitStreamReader& stream) : x188_staticIntf(5) { x0_24_alive = true; x4_enabledItems = u32(stream.ReadEncoded(32)); - union { - float fHP; - u32 iHP; - } hp; - hp.iHP = u32(stream.ReadEncoded(32)); - xc_health.SetHP(hp.fHP); + + const u32 integralHP = u32(stream.ReadEncoded(32)); + float realHP; + std::memcpy(&realHP, &integralHP, sizeof(float)); + + xc_health.SetHP(realHP); x8_currentBeam = EBeamId(stream.ReadEncoded(CBitStreamReader::GetBitCount(5))); x20_currentSuit = EPlayerSuit(stream.ReadEncoded(CBitStreamReader::GetBitCount(4))); x24_powerups.resize(41); @@ -113,12 +114,12 @@ CPlayerState::CPlayerState(CBitStreamReader& stream) : x188_staticIntf(5) { void CPlayerState::PutTo(CBitStreamWriter& stream) { stream.WriteEncoded(x4_enabledItems, 32); - union { - float fHP; - u32 iHP; - } hp; - hp.fHP = xc_health.GetHP(); - stream.WriteEncoded(hp.iHP, 32); + + const float realHP = xc_health.GetHP(); + u32 integralHP; + std::memcpy(&integralHP, &realHP, sizeof(u32)); + + stream.WriteEncoded(integralHP, 32); stream.WriteEncoded(u32(x8_currentBeam), CBitStreamWriter::GetBitCount(5)); stream.WriteEncoded(u32(x20_currentSuit), CBitStreamWriter::GetBitCount(4)); for (size_t i = 0; i < x24_powerups.size(); ++i) { @@ -181,7 +182,7 @@ u32 CPlayerState::CalculateItemCollectionRate() const { return total + GetItemCapacity(EItemType::Wavebuster); } -CHealthInfo& CPlayerState::HealthInfo() { return xc_health; } +CHealthInfo& CPlayerState::GetHealthInfo() { return xc_health; } const CHealthInfo& CPlayerState::GetHealthInfo() const { return xc_health; } @@ -389,62 +390,66 @@ void CPlayerState::InitializeScanTimes() { u32 CPlayerState::GetPowerUpMaxValue(EItemType type) { return PowerUpMaxValues[size_t(type)]; } -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}, - {"grapple"sv, EItemType::GrappleBeam}, - {"grapplebeam"sv, EItemType::GrappleBeam}, - {"xrayvisor"sv, EItemType::XRayVisor}, - {"icespreader"sv, EItemType::IceSpreader}, - {"spacejump"sv, EItemType::SpaceJumpBoots}, - {"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; + static constexpr std::array, 46> 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}, + {"grapple"sv, EItemType::GrappleBeam}, + {"grapplebeam"sv, EItemType::GrappleBeam}, + {"xrayvisor"sv, EItemType::XRayVisor}, + {"icespreader"sv, EItemType::IceSpreader}, + {"spacejump"sv, EItemType::SpaceJumpBoots}, + {"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}, + }}; - return g_TypeNameMap.find(lowName)->second; + std::string lowName{name}; + athena::utility::tolower(lowName); + + const auto iter = std::find_if(typeNameMap.cbegin(), typeNameMap.cend(), + [&lowName](const auto& entry) { return entry.first == lowName; }); + if (iter == typeNameMap.cend()) { + return EItemType::Invalid; + } + + return iter->second; } } // namespace urde diff --git a/Runtime/CPlayerState.hpp b/Runtime/CPlayerState.hpp index ead556565..22134070d 100644 --- a/Runtime/CPlayerState.hpp +++ b/Runtime/CPlayerState.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include "Runtime/CStaticInterference.hpp" @@ -89,12 +88,11 @@ public: enum class EBeamId : s32 { Invalid = -1, Power, Ice, Wave, Plasma, Phazon, Phazon2 = 27 }; private: - static const std::unordered_map g_TypeNameMap; struct CPowerUp { u32 x0_amount = 0; u32 x4_capacity = 0; - CPowerUp() {} - CPowerUp(u32 amount, u32 capacity) : x0_amount(amount), x4_capacity(capacity) {} + constexpr CPowerUp() = default; + constexpr CPowerUp(u32 amount, u32 capacity) : x0_amount(amount), x4_capacity(capacity) {} }; union { struct { @@ -125,7 +123,7 @@ public: static constexpr float GetMissileComboChargeFactor() { return 1.8f; } u32 CalculateItemCollectionRate() const; - CHealthInfo& HealthInfo(); + CHealthInfo& GetHealthInfo(); const CHealthInfo& GetHealthInfo() const; u32 GetPickupTotal() { return 99; } void SetIsFusionEnabled(bool val) { x0_26_fusion = val; } @@ -172,7 +170,7 @@ public: CStaticInterference& GetStaticInterference() { return x188_staticIntf; } const std::vector>& GetScanTimes() const { return x170_scanTimes; } CPlayerState(); - CPlayerState(CBitStreamReader& stream); + explicit CPlayerState(CBitStreamReader& stream); void PutTo(CBitStreamWriter& stream); static u32 GetPowerUpMaxValue(EItemType type); static EItemType ItemNameToType(std::string_view name); diff --git a/Runtime/CRelayTracker.cpp b/Runtime/CRelayTracker.cpp index 4ce2215aa..20f358742 100644 --- a/Runtime/CRelayTracker.cpp +++ b/Runtime/CRelayTracker.cpp @@ -8,33 +8,41 @@ namespace urde { -CRelayTracker::CRelayTracker(CBitStreamReader& in, const CSaveWorld& saveworld) { - u32 relayCount = saveworld.GetRelayCount(); - if (saveworld.GetRelayCount()) { - std::vector relayStates(saveworld.GetRelayCount()); - for (u32 i = 0; i < relayCount; ++i) +CRelayTracker::CRelayTracker(CBitStreamReader& in, const CSaveWorld& saveWorld) { + const u32 relayCount = saveWorld.GetRelayCount(); + if (saveWorld.GetRelayCount()) { + std::vector relayStates(saveWorld.GetRelayCount()); + for (u32 i = 0; i < relayCount; ++i) { relayStates[i] = in.ReadEncoded(1); + } for (u32 i = 0; i < relayCount; ++i) { - if (!relayStates[i]) + if (!relayStates[i]) { continue; - x0_relayStates.push_back(saveworld.GetRelayEditorId(i)); + } + x0_relayStates.push_back(saveWorld.GetRelayEditorId(i)); } } } -bool CRelayTracker::HasRelay(TEditorId id) { - return std::find(x0_relayStates.begin(), x0_relayStates.end(), id) != x0_relayStates.end(); +bool CRelayTracker::HasRelay(TEditorId id) const { + return std::find(x0_relayStates.cbegin(), x0_relayStates.cend(), id) != x0_relayStates.cend(); } void CRelayTracker::AddRelay(TEditorId id) { - if (std::find(x0_relayStates.begin(), x0_relayStates.end(), id) == x0_relayStates.end()) - x0_relayStates.push_back(id); + if (HasRelay(id)) { + return; + } + + x0_relayStates.push_back(id); } void CRelayTracker::RemoveRelay(TEditorId id) { - if (std::find(x0_relayStates.begin(), x0_relayStates.end(), id) != x0_relayStates.end()) - x0_relayStates.erase(std::remove(x0_relayStates.begin(), x0_relayStates.end(), id), x0_relayStates.end()); + if (!HasRelay(id)) { + return; + } + + x0_relayStates.erase(std::remove(x0_relayStates.begin(), x0_relayStates.end(), id), x0_relayStates.end()); } void CRelayTracker::SendMsgs(TAreaId areaId, CStateManager& stateMgr) { @@ -71,18 +79,20 @@ void CRelayTracker::SendMsgs(TAreaId areaId, CStateManager& stateMgr) { } } -void CRelayTracker::PutTo(CBitStreamWriter& out, const CSaveWorld& saveworld) { - u32 relayCount = saveworld.GetRelayCount(); +void CRelayTracker::PutTo(CBitStreamWriter& out, const CSaveWorld& saveWorld) { + const u32 relayCount = saveWorld.GetRelayCount(); std::vector relays(relayCount); for (const TEditorId& id : x0_relayStates) { - s32 idx = saveworld.GetRelayIndex(id); - if (idx >= 0) + const s32 idx = saveWorld.GetRelayIndex(id); + if (idx >= 0) { relays[idx] = true; + } } - for (u32 i = 0; i < relayCount; ++i) + for (u32 i = 0; i < relayCount; ++i) { out.WriteEncoded(u32(relays[i]), 1); + } } } // namespace urde diff --git a/Runtime/CRelayTracker.hpp b/Runtime/CRelayTracker.hpp index cd6509d93..fdeb8bb0e 100644 --- a/Runtime/CRelayTracker.hpp +++ b/Runtime/CRelayTracker.hpp @@ -29,13 +29,13 @@ class CRelayTracker { public: CRelayTracker() = default; - CRelayTracker(CBitStreamReader&, const CSaveWorld&); + CRelayTracker(CBitStreamReader& in, const CSaveWorld& saveWorld); - bool HasRelay(TEditorId); - void AddRelay(TEditorId); - void RemoveRelay(TEditorId); - void SendMsgs(TAreaId, CStateManager&); - void PutTo(CBitStreamWriter&, const CSaveWorld&); + bool HasRelay(TEditorId id) const; + void AddRelay(TEditorId id); + void RemoveRelay(TEditorId id); + void SendMsgs(TAreaId areaId, CStateManager& stateMgr); + void PutTo(CBitStreamWriter& out, const CSaveWorld& saveWorld); }; } // namespace urde diff --git a/Runtime/CSaveWorld.cpp b/Runtime/CSaveWorld.cpp index abd25053e..4edc5ccf4 100644 --- a/Runtime/CSaveWorld.cpp +++ b/Runtime/CSaveWorld.cpp @@ -14,13 +14,13 @@ CSaveWorld::CSaveWorld(CInputStream& in) { const u32 cinematicCount = in.readUint32Big(); x4_cinematics.reserve(cinematicCount); for (u32 i = 0; i < cinematicCount; ++i) { - x4_cinematics.push_back(in.readUint32Big()); + x4_cinematics.emplace_back(in.readUint32Big()); } const u32 relayCount = in.readUint32Big(); x14_relays.reserve(relayCount); for (u32 i = 0; i < relayCount; ++i) { - x14_relays.push_back(in.readUint32Big()); + x14_relays.emplace_back(in.readUint32Big()); } } @@ -35,7 +35,7 @@ CSaveWorld::CSaveWorld(CInputStream& in) { const u32 doorCount = in.readUint32Big(); x34_doors.reserve(doorCount); for (u32 i = 0; i < doorCount; ++i) { - x34_doors.push_back(in.readUint32Big()); + x34_doors.emplace_back(in.readUint32Big()); } if (version <= 0) { diff --git a/Runtime/CSaveWorld.hpp b/Runtime/CSaveWorld.hpp index 75403fd74..097ed3522 100644 --- a/Runtime/CSaveWorld.hpp +++ b/Runtime/CSaveWorld.hpp @@ -31,7 +31,7 @@ private: std::vector x44_scans; public: - CSaveWorld(CInputStream& in); + explicit CSaveWorld(CInputStream& in); u32 GetAreaCount() const; u32 GetCinematicCount() const; s32 GetCinematicIndex(const TEditorId& id) const; diff --git a/Runtime/CSortedLists.cpp b/Runtime/CSortedLists.cpp index e22c0166e..2a9ecbb99 100644 --- a/Runtime/CSortedLists.cpp +++ b/Runtime/CSortedLists.cpp @@ -30,17 +30,19 @@ void CSortedListManager::Reset() { } } -void CSortedListManager::AddToLinkedList(s16 nodeId, s16& headId, s16& tailId) const { +void CSortedListManager::AddToLinkedList(s16 nodeId, s16& headId, s16& tailId) { if (headId == -1) { - const_cast(AccessElement(x0_nodes, nodeId)).x28_next = headId; + AccessElement(x0_nodes, nodeId).x28_next = headId; headId = nodeId; tailId = nodeId; } else { - if (AccessElement(x0_nodes, nodeId).x28_next != -1) + if (AccessElement(x0_nodes, nodeId).x28_next != -1) { return; - if (tailId == nodeId) + } + if (tailId == nodeId) { return; - const_cast(AccessElement(x0_nodes, nodeId)).x28_next = headId; + } + AccessElement(x0_nodes, nodeId).x28_next = headId; headId = nodeId; } } @@ -114,19 +116,19 @@ void CSortedListManager::InsertInList(ESortedList list, SNode& node) { ++sl.x800_size; } -s16 CSortedListManager::FindInListUpper(ESortedList list, float val) const { +s16 CSortedListManager::FindInListUpper(ESortedList list, float value) const { const auto listIndex = static_cast(list); const SSortedList& sl = xb000_sortedLists[listIndex]; int idx = 0; for (int i = sl.x800_size; i > 0;) { - /* Binary search cycle to find index */ - if (!(val < AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx + i / 2)).x4_box[listIndex])) { - /* Upper */ + // Binary search cycle to find index + if (!(value < AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx + i / 2)).x4_box[listIndex])) { + // Upper idx = idx + i / 2 + 1; i = i - i / 2 - 1; } else { - /* Lower */ + // Lower i /= 2; } } @@ -134,19 +136,19 @@ s16 CSortedListManager::FindInListUpper(ESortedList list, float val) const { return idx; } -s16 CSortedListManager::FindInListLower(ESortedList list, float val) const { +s16 CSortedListManager::FindInListLower(ESortedList list, float value) const { const auto listIndex = static_cast(list); const SSortedList& sl = xb000_sortedLists[listIndex]; int idx = 0; for (int i = sl.x800_size; i > 0;) { - /* Binary search cycle to find index */ - if (AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx + i / 2)).x4_box[listIndex] < val) { - /* Upper */ + // Binary search cycle to find index + if (AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx + i / 2)).x4_box[listIndex] < value) { + // Upper idx = idx + i / 2 + 1; i = i - i / 2 - 1; } else { - /* Lower */ + // Lower i /= 2; } } @@ -233,48 +235,52 @@ s16 CSortedListManager::CalculateIntersections(ESortedList la, ESortedList lb, s void CSortedListManager::BuildNearList(rstl::reserved_vector& out, const zeus::CVector3f& pos, const zeus::CVector3f& dir, float mag, const CMaterialFilter& filter, - const CActor* actor) const { - if (mag == 0.f) + const CActor* actor) { + if (mag == 0.f) { mag = 8000.f; + } const zeus::CVector3f ray = dir * mag; const zeus::CVector3f sum = ray + pos; - zeus::CVector3f maxs(std::max(pos.x(), sum.x()), std::max(pos.y(), sum.y()), std::max(pos.z(), sum.z())); - zeus::CVector3f mins(std::min(sum.x(), pos.x()), std::min(sum.y(), pos.y()), std::min(sum.z(), pos.z())); + const zeus::CVector3f maxs(std::max(pos.x(), sum.x()), std::max(pos.y(), sum.y()), std::max(pos.z(), sum.z())); + const zeus::CVector3f mins(std::min(sum.x(), pos.x()), std::min(sum.y(), pos.y()), std::min(sum.z(), pos.z())); BuildNearList(out, zeus::CAABox(mins, maxs), filter, actor); } void CSortedListManager::BuildNearList(rstl::reserved_vector& out, const CActor& actor, - const zeus::CAABox& aabb) const { + const zeus::CAABox& aabb) { const CMaterialFilter& filter = actor.GetMaterialFilter(); - s16 id = const_cast(*this).ConstructIntersectionArray(aabb); + s16 id = ConstructIntersectionArray(aabb); while (id != -1) { - const SNode& node = AccessElement(x0_nodes, id); + SNode& node = AccessElement(x0_nodes, id); if (&actor != node.x0_actor && filter.Passes(node.x0_actor->GetMaterialList()) && - node.x0_actor->GetMaterialFilter().Passes(actor.GetMaterialList())) + node.x0_actor->GetMaterialFilter().Passes(actor.GetMaterialList())) { out.push_back(node.x0_actor->GetUniqueId()); + } id = node.x28_next; - const_cast(node).x28_next = -1; + node.x28_next = -1; } } void CSortedListManager::BuildNearList(rstl::reserved_vector& out, const zeus::CAABox& aabb, - const CMaterialFilter& filter, const CActor* actor) const { - s16 id = const_cast(*this).ConstructIntersectionArray(aabb); + const CMaterialFilter& filter, const CActor* actor) { + s16 id = ConstructIntersectionArray(aabb); while (id != -1) { - const SNode& node = AccessElement(x0_nodes, id); - if (actor != node.x0_actor && filter.Passes(node.x0_actor->GetMaterialList())) + SNode& node = AccessElement(x0_nodes, id); + if (actor != node.x0_actor && filter.Passes(node.x0_actor->GetMaterialList())) { out.push_back(node.x0_actor->GetUniqueId()); + } id = node.x28_next; - const_cast(node).x28_next = -1; + node.x28_next = -1; } } -void CSortedListManager::Remove(const CActor* act) { - SNode& node = AccessElement(x0_nodes, act->GetUniqueId().Value()); - if (!node.x2a_populated) +void CSortedListManager::Remove(const CActor* actor) { + SNode& node = AccessElement(x0_nodes, actor->GetUniqueId().Value()); + if (!node.x2a_populated) { return; + } RemoveFromList(ESortedList::MinX, node.x1c_selfIdxs[0]); RemoveFromList(ESortedList::MaxX, node.x1c_selfIdxs[3]); @@ -285,8 +291,8 @@ void CSortedListManager::Remove(const CActor* act) { node.x2a_populated = false; } -void CSortedListManager::Move(const CActor* act, const zeus::CAABox& aabb) { - SNode& node = AccessElement(x0_nodes, act->GetUniqueId().Value()); +void CSortedListManager::Move(const CActor* actor, const zeus::CAABox& aabb) { + SNode& node = AccessElement(x0_nodes, actor->GetUniqueId().Value()); node.x4_box = aabb; MoveInList(ESortedList::MinX, node.x1c_selfIdxs[0]); @@ -297,14 +303,14 @@ void CSortedListManager::Move(const CActor* act, const zeus::CAABox& aabb) { MoveInList(ESortedList::MaxZ, node.x1c_selfIdxs[5]); } -void CSortedListManager::Insert(const CActor* act, const zeus::CAABox& aabb) { - SNode& node = AccessElement(x0_nodes, act->GetUniqueId().Value()); +void CSortedListManager::Insert(const CActor* actor, const zeus::CAABox& aabb) { + SNode& node = AccessElement(x0_nodes, actor->GetUniqueId().Value()); if (node.x2a_populated) { - Move(act, aabb); + Move(actor, aabb); return; } - SNode newNode(act, aabb); + SNode newNode(actor, aabb); InsertInList(ESortedList::MinX, newNode); InsertInList(ESortedList::MaxX, newNode); InsertInList(ESortedList::MinY, newNode); @@ -314,10 +320,11 @@ void CSortedListManager::Insert(const CActor* act, const zeus::CAABox& aabb) { node = newNode; } -bool CSortedListManager::ActorInLists(const CActor* act) const { - if (!act) +bool CSortedListManager::ActorInLists(const CActor* actor) const { + if (!actor) { return false; - const SNode& node = AccessElement(x0_nodes, act->GetUniqueId().Value()); + } + const SNode& node = AccessElement(x0_nodes, actor->GetUniqueId().Value()); return node.x2a_populated; } diff --git a/Runtime/CSortedLists.hpp b/Runtime/CSortedLists.hpp index f251ff662..ce7d49e4a 100644 --- a/Runtime/CSortedLists.hpp +++ b/Runtime/CSortedLists.hpp @@ -31,27 +31,27 @@ class CSortedListManager { std::array x0_nodes; std::array xb000_sortedLists; void Reset(); - void AddToLinkedList(s16 a, s16& b, s16& c) const; - void RemoveFromList(ESortedList, s16); - void MoveInList(ESortedList, s16); - void InsertInList(ESortedList, SNode& node); - s16 FindInListUpper(ESortedList, float) const; - s16 FindInListLower(ESortedList, float) const; - s16 ConstructIntersectionArray(const zeus::CAABox&); - s16 CalculateIntersections(ESortedList, ESortedList, s16, s16, s16, s16, ESortedList, ESortedList, ESortedList, - ESortedList, const zeus::CAABox&); + void AddToLinkedList(s16 nodeId, s16& headId, s16& tailId); + void RemoveFromList(ESortedList list, s16 idx); + void MoveInList(ESortedList list, s16 idx); + void InsertInList(ESortedList list, SNode& node); + s16 FindInListUpper(ESortedList list, float value) const; + s16 FindInListLower(ESortedList list, float value) const; + s16 ConstructIntersectionArray(const zeus::CAABox& aabb); + s16 CalculateIntersections(ESortedList la, ESortedList lb, s16 a, s16 b, s16 c, s16 d, ESortedList slA, + ESortedList slB, ESortedList slC, ESortedList slD, const zeus::CAABox& aabb); public: CSortedListManager(); - void BuildNearList(rstl::reserved_vector&, const zeus::CVector3f&, const zeus::CVector3f&, float, - const CMaterialFilter&, const CActor*) const; - void BuildNearList(rstl::reserved_vector&, const CActor&, const zeus::CAABox&) const; - void BuildNearList(rstl::reserved_vector&, const zeus::CAABox&, const CMaterialFilter&, - const CActor*) const; - void Remove(const CActor*); - void Move(const CActor* act, const zeus::CAABox& aabb); - void Insert(const CActor* act, const zeus::CAABox& aabb); - bool ActorInLists(const CActor* act) const; + void BuildNearList(rstl::reserved_vector& out, const zeus::CVector3f& pos, + const zeus::CVector3f& dir, float mag, const CMaterialFilter& filter, const CActor* actor); + void BuildNearList(rstl::reserved_vector& out, const CActor& actor, const zeus::CAABox& aabb); + void BuildNearList(rstl::reserved_vector& out, const zeus::CAABox& aabb, + const CMaterialFilter& filter, const CActor* actor); + void Remove(const CActor* actor); + void Move(const CActor* actor, const zeus::CAABox& aabb); + void Insert(const CActor* actor, const zeus::CAABox& aabb); + bool ActorInLists(const CActor* actor) const; }; } // namespace urde diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index 51fab9e31..fda9eeb25 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -74,133 +74,133 @@ CStateManager::CStateManager(const std::weak_ptr& relayTracker, 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; - x90c_loaderFuncs[int(EScriptObjectType::Trigger)] = ScriptLoader::LoadTrigger; - x90c_loaderFuncs[int(EScriptObjectType::Timer)] = ScriptLoader::LoadTimer; - x90c_loaderFuncs[int(EScriptObjectType::Counter)] = ScriptLoader::LoadCounter; - x90c_loaderFuncs[int(EScriptObjectType::Effect)] = ScriptLoader::LoadEffect; - x90c_loaderFuncs[int(EScriptObjectType::Platform)] = ScriptLoader::LoadPlatform; - x90c_loaderFuncs[int(EScriptObjectType::Sound)] = ScriptLoader::LoadSound; - x90c_loaderFuncs[int(EScriptObjectType::Generator)] = ScriptLoader::LoadGenerator; - x90c_loaderFuncs[int(EScriptObjectType::Dock)] = ScriptLoader::LoadDock; - x90c_loaderFuncs[int(EScriptObjectType::Camera)] = ScriptLoader::LoadCamera; - x90c_loaderFuncs[int(EScriptObjectType::CameraWaypoint)] = ScriptLoader::LoadCameraWaypoint; - x90c_loaderFuncs[int(EScriptObjectType::NewIntroBoss)] = ScriptLoader::LoadNewIntroBoss; - x90c_loaderFuncs[int(EScriptObjectType::SpawnPoint)] = ScriptLoader::LoadSpawnPoint; - x90c_loaderFuncs[int(EScriptObjectType::CameraHint)] = ScriptLoader::LoadCameraHint; - x90c_loaderFuncs[int(EScriptObjectType::Pickup)] = ScriptLoader::LoadPickup; - x90c_loaderFuncs[int(EScriptObjectType::MemoryRelay)] = ScriptLoader::LoadMemoryRelay; - x90c_loaderFuncs[int(EScriptObjectType::RandomRelay)] = ScriptLoader::LoadRandomRelay; - x90c_loaderFuncs[int(EScriptObjectType::Relay)] = ScriptLoader::LoadRelay; - x90c_loaderFuncs[int(EScriptObjectType::Beetle)] = ScriptLoader::LoadBeetle; - x90c_loaderFuncs[int(EScriptObjectType::HUDMemo)] = ScriptLoader::LoadHUDMemo; - x90c_loaderFuncs[int(EScriptObjectType::CameraFilterKeyframe)] = ScriptLoader::LoadCameraFilterKeyframe; - x90c_loaderFuncs[int(EScriptObjectType::CameraBlurKeyframe)] = ScriptLoader::LoadCameraBlurKeyframe; - x90c_loaderFuncs[int(EScriptObjectType::DamageableTrigger)] = ScriptLoader::LoadDamageableTrigger; - x90c_loaderFuncs[int(EScriptObjectType::Debris)] = ScriptLoader::LoadDebris; - x90c_loaderFuncs[int(EScriptObjectType::CameraShaker)] = ScriptLoader::LoadCameraShaker; - x90c_loaderFuncs[int(EScriptObjectType::ActorKeyframe)] = ScriptLoader::LoadActorKeyframe; - x90c_loaderFuncs[int(EScriptObjectType::Water)] = ScriptLoader::LoadWater; - x90c_loaderFuncs[int(EScriptObjectType::Warwasp)] = ScriptLoader::LoadWarWasp; - x90c_loaderFuncs[int(EScriptObjectType::SpacePirate)] = ScriptLoader::LoadSpacePirate; - x90c_loaderFuncs[int(EScriptObjectType::FlyingPirate)] = ScriptLoader::LoadFlyingPirate; - x90c_loaderFuncs[int(EScriptObjectType::ElitePirate)] = ScriptLoader::LoadElitePirate; - x90c_loaderFuncs[int(EScriptObjectType::MetroidBeta)] = ScriptLoader::LoadMetroidBeta; - x90c_loaderFuncs[int(EScriptObjectType::ChozoGhost)] = ScriptLoader::LoadChozoGhost; - x90c_loaderFuncs[int(EScriptObjectType::CoverPoint)] = ScriptLoader::LoadCoverPoint; - x90c_loaderFuncs[int(EScriptObjectType::SpiderBallWaypoint)] = ScriptLoader::LoadSpiderBallWaypoint; - x90c_loaderFuncs[int(EScriptObjectType::BloodFlower)] = ScriptLoader::LoadBloodFlower; - x90c_loaderFuncs[int(EScriptObjectType::FlickerBat)] = ScriptLoader::LoadFlickerBat; - x90c_loaderFuncs[int(EScriptObjectType::PathCamera)] = ScriptLoader::LoadPathCamera; - x90c_loaderFuncs[int(EScriptObjectType::GrapplePoint)] = ScriptLoader::LoadGrapplePoint; - x90c_loaderFuncs[int(EScriptObjectType::PuddleSpore)] = ScriptLoader::LoadPuddleSpore; - x90c_loaderFuncs[int(EScriptObjectType::DebugCameraWaypoint)] = ScriptLoader::LoadDebugCameraWaypoint; - x90c_loaderFuncs[int(EScriptObjectType::SpiderBallAttractionSurface)] = ScriptLoader::LoadSpiderBallAttractionSurface; - x90c_loaderFuncs[int(EScriptObjectType::PuddleToadGamma)] = ScriptLoader::LoadPuddleToadGamma; - x90c_loaderFuncs[int(EScriptObjectType::DistanceFog)] = ScriptLoader::LoadDistanceFog; - x90c_loaderFuncs[int(EScriptObjectType::FireFlea)] = ScriptLoader::LoadFireFlea; - x90c_loaderFuncs[int(EScriptObjectType::Metaree)] = ScriptLoader::LoadMetaree; - x90c_loaderFuncs[int(EScriptObjectType::DockAreaChange)] = ScriptLoader::LoadDockAreaChange; - x90c_loaderFuncs[int(EScriptObjectType::ActorRotate)] = ScriptLoader::LoadActorRotate; - x90c_loaderFuncs[int(EScriptObjectType::SpecialFunction)] = ScriptLoader::LoadSpecialFunction; - x90c_loaderFuncs[int(EScriptObjectType::SpankWeed)] = ScriptLoader::LoadSpankWeed; - x90c_loaderFuncs[int(EScriptObjectType::Parasite)] = ScriptLoader::LoadParasite; - x90c_loaderFuncs[int(EScriptObjectType::PlayerHint)] = ScriptLoader::LoadPlayerHint; - x90c_loaderFuncs[int(EScriptObjectType::Ripper)] = ScriptLoader::LoadRipper; - x90c_loaderFuncs[int(EScriptObjectType::PickupGenerator)] = ScriptLoader::LoadPickupGenerator; - x90c_loaderFuncs[int(EScriptObjectType::AIKeyframe)] = ScriptLoader::LoadAIKeyframe; - x90c_loaderFuncs[int(EScriptObjectType::PointOfInterest)] = ScriptLoader::LoadPointOfInterest; - x90c_loaderFuncs[int(EScriptObjectType::Drone)] = ScriptLoader::LoadDrone; - x90c_loaderFuncs[int(EScriptObjectType::Metroid)] = ScriptLoader::LoadMetroid; - x90c_loaderFuncs[int(EScriptObjectType::DebrisExtended)] = ScriptLoader::LoadDebrisExtended; - x90c_loaderFuncs[int(EScriptObjectType::Steam)] = ScriptLoader::LoadSteam; - x90c_loaderFuncs[int(EScriptObjectType::Ripple)] = ScriptLoader::LoadRipple; - x90c_loaderFuncs[int(EScriptObjectType::BallTrigger)] = ScriptLoader::LoadBallTrigger; - x90c_loaderFuncs[int(EScriptObjectType::TargetingPoint)] = ScriptLoader::LoadTargetingPoint; - x90c_loaderFuncs[int(EScriptObjectType::EMPulse)] = ScriptLoader::LoadEMPulse; - x90c_loaderFuncs[int(EScriptObjectType::IceSheegoth)] = ScriptLoader::LoadIceSheegoth; - x90c_loaderFuncs[int(EScriptObjectType::PlayerActor)] = ScriptLoader::LoadPlayerActor; - x90c_loaderFuncs[int(EScriptObjectType::Flaahgra)] = ScriptLoader::LoadFlaahgra; - x90c_loaderFuncs[int(EScriptObjectType::AreaAttributes)] = ScriptLoader::LoadAreaAttributes; - x90c_loaderFuncs[int(EScriptObjectType::FishCloud)] = ScriptLoader::LoadFishCloud; - x90c_loaderFuncs[int(EScriptObjectType::FishCloudModifier)] = ScriptLoader::LoadFishCloudModifier; - x90c_loaderFuncs[int(EScriptObjectType::VisorFlare)] = ScriptLoader::LoadVisorFlare; - x90c_loaderFuncs[int(EScriptObjectType::WorldTeleporter)] = ScriptLoader::LoadWorldTeleporter; - x90c_loaderFuncs[int(EScriptObjectType::VisorGoo)] = ScriptLoader::LoadVisorGoo; - x90c_loaderFuncs[int(EScriptObjectType::JellyZap)] = ScriptLoader::LoadJellyZap; - x90c_loaderFuncs[int(EScriptObjectType::ControllerAction)] = ScriptLoader::LoadControllerAction; - x90c_loaderFuncs[int(EScriptObjectType::Switch)] = ScriptLoader::LoadSwitch; - x90c_loaderFuncs[int(EScriptObjectType::PlayerStateChange)] = ScriptLoader::LoadPlayerStateChange; - x90c_loaderFuncs[int(EScriptObjectType::Thardus)] = ScriptLoader::LoadThardus; - x90c_loaderFuncs[int(EScriptObjectType::WallCrawlerSwarm)] = ScriptLoader::LoadWallCrawlerSwarm; - x90c_loaderFuncs[int(EScriptObjectType::AIJumpPoint)] = ScriptLoader::LoadAiJumpPoint; - x90c_loaderFuncs[int(EScriptObjectType::FlaahgraTentacle)] = ScriptLoader::LoadFlaahgraTentacle; - x90c_loaderFuncs[int(EScriptObjectType::RoomAcoustics)] = ScriptLoader::LoadRoomAcoustics; - x90c_loaderFuncs[int(EScriptObjectType::ColorModulate)] = ScriptLoader::LoadColorModulate; - x90c_loaderFuncs[int(EScriptObjectType::ThardusRockProjectile)] = ScriptLoader::LoadThardusRockProjectile; - x90c_loaderFuncs[int(EScriptObjectType::Midi)] = ScriptLoader::LoadMidi; - x90c_loaderFuncs[int(EScriptObjectType::StreamedAudio)] = ScriptLoader::LoadStreamedAudio; - x90c_loaderFuncs[int(EScriptObjectType::WorldTeleporterToo)] = ScriptLoader::LoadWorldTeleporter; - x90c_loaderFuncs[int(EScriptObjectType::Repulsor)] = ScriptLoader::LoadRepulsor; - x90c_loaderFuncs[int(EScriptObjectType::GunTurret)] = ScriptLoader::LoadGunTurret; - x90c_loaderFuncs[int(EScriptObjectType::FogVolume)] = ScriptLoader::LoadFogVolume; - x90c_loaderFuncs[int(EScriptObjectType::Babygoth)] = ScriptLoader::LoadBabygoth; - x90c_loaderFuncs[int(EScriptObjectType::Eyeball)] = ScriptLoader::LoadEyeball; - x90c_loaderFuncs[int(EScriptObjectType::RadialDamage)] = ScriptLoader::LoadRadialDamage; - x90c_loaderFuncs[int(EScriptObjectType::CameraPitchVolume)] = ScriptLoader::LoadCameraPitchVolume; - x90c_loaderFuncs[int(EScriptObjectType::EnvFxDensityController)] = ScriptLoader::LoadEnvFxDensityController; - x90c_loaderFuncs[int(EScriptObjectType::Magdolite)] = ScriptLoader::LoadMagdolite; - x90c_loaderFuncs[int(EScriptObjectType::TeamAIMgr)] = ScriptLoader::LoadTeamAIMgr; - x90c_loaderFuncs[int(EScriptObjectType::SnakeWeedSwarm)] = ScriptLoader::LoadSnakeWeedSwarm; - x90c_loaderFuncs[int(EScriptObjectType::ActorContraption)] = ScriptLoader::LoadActorContraption; - x90c_loaderFuncs[int(EScriptObjectType::Oculus)] = ScriptLoader::LoadOculus; - x90c_loaderFuncs[int(EScriptObjectType::Geemer)] = ScriptLoader::LoadGeemer; - x90c_loaderFuncs[int(EScriptObjectType::SpindleCamera)] = ScriptLoader::LoadSpindleCamera; - x90c_loaderFuncs[int(EScriptObjectType::AtomicAlpha)] = ScriptLoader::LoadAtomicAlpha; - x90c_loaderFuncs[int(EScriptObjectType::CameraHintTrigger)] = ScriptLoader::LoadCameraHintTrigger; - x90c_loaderFuncs[int(EScriptObjectType::RumbleEffect)] = ScriptLoader::LoadRumbleEffect; - x90c_loaderFuncs[int(EScriptObjectType::AmbientAI)] = ScriptLoader::LoadAmbientAI; - x90c_loaderFuncs[int(EScriptObjectType::AtomicBeta)] = ScriptLoader::LoadAtomicBeta; - x90c_loaderFuncs[int(EScriptObjectType::IceZoomer)] = ScriptLoader::LoadIceZoomer; - x90c_loaderFuncs[int(EScriptObjectType::Puffer)] = ScriptLoader::LoadPuffer; - x90c_loaderFuncs[int(EScriptObjectType::Tryclops)] = ScriptLoader::LoadTryclops; - x90c_loaderFuncs[int(EScriptObjectType::Ridley)] = ScriptLoader::LoadRidley; - x90c_loaderFuncs[int(EScriptObjectType::Seedling)] = ScriptLoader::LoadSeedling; - x90c_loaderFuncs[int(EScriptObjectType::ThermalHeatFader)] = ScriptLoader::LoadThermalHeatFader; - x90c_loaderFuncs[int(EScriptObjectType::Burrower)] = ScriptLoader::LoadBurrower; - x90c_loaderFuncs[int(EScriptObjectType::ScriptBeam)] = ScriptLoader::LoadBeam; - x90c_loaderFuncs[int(EScriptObjectType::WorldLightFader)] = ScriptLoader::LoadWorldLightFader; - x90c_loaderFuncs[int(EScriptObjectType::MetroidPrimeStage2)] = ScriptLoader::LoadMetroidPrimeStage2; - x90c_loaderFuncs[int(EScriptObjectType::MetroidPrimeStage1)] = ScriptLoader::LoadMetroidPrimeStage1; - x90c_loaderFuncs[int(EScriptObjectType::MazeNode)] = ScriptLoader::LoadMazeNode; - x90c_loaderFuncs[int(EScriptObjectType::OmegaPirate)] = ScriptLoader::LoadOmegaPirate; - x90c_loaderFuncs[int(EScriptObjectType::PhazonPool)] = ScriptLoader::LoadPhazonPool; - x90c_loaderFuncs[int(EScriptObjectType::PhazonHealingNodule)] = ScriptLoader::LoadPhazonHealingNodule; - x90c_loaderFuncs[int(EScriptObjectType::NewCameraShaker)] = ScriptLoader::LoadNewCameraShaker; - x90c_loaderFuncs[int(EScriptObjectType::ShadowProjector)] = ScriptLoader::LoadShadowProjector; - x90c_loaderFuncs[int(EScriptObjectType::EnergyBall)] = ScriptLoader::LoadEnergyBall; + x90c_loaderFuncs[size_t(EScriptObjectType::Actor)] = ScriptLoader::LoadActor; + x90c_loaderFuncs[size_t(EScriptObjectType::Waypoint)] = ScriptLoader::LoadWaypoint; + x90c_loaderFuncs[size_t(EScriptObjectType::Door)] = ScriptLoader::LoadDoor; + x90c_loaderFuncs[size_t(EScriptObjectType::Trigger)] = ScriptLoader::LoadTrigger; + x90c_loaderFuncs[size_t(EScriptObjectType::Timer)] = ScriptLoader::LoadTimer; + x90c_loaderFuncs[size_t(EScriptObjectType::Counter)] = ScriptLoader::LoadCounter; + x90c_loaderFuncs[size_t(EScriptObjectType::Effect)] = ScriptLoader::LoadEffect; + x90c_loaderFuncs[size_t(EScriptObjectType::Platform)] = ScriptLoader::LoadPlatform; + x90c_loaderFuncs[size_t(EScriptObjectType::Sound)] = ScriptLoader::LoadSound; + x90c_loaderFuncs[size_t(EScriptObjectType::Generator)] = ScriptLoader::LoadGenerator; + x90c_loaderFuncs[size_t(EScriptObjectType::Dock)] = ScriptLoader::LoadDock; + x90c_loaderFuncs[size_t(EScriptObjectType::Camera)] = ScriptLoader::LoadCamera; + x90c_loaderFuncs[size_t(EScriptObjectType::CameraWaypoint)] = ScriptLoader::LoadCameraWaypoint; + x90c_loaderFuncs[size_t(EScriptObjectType::NewIntroBoss)] = ScriptLoader::LoadNewIntroBoss; + x90c_loaderFuncs[size_t(EScriptObjectType::SpawnPoint)] = ScriptLoader::LoadSpawnPoint; + x90c_loaderFuncs[size_t(EScriptObjectType::CameraHint)] = ScriptLoader::LoadCameraHint; + x90c_loaderFuncs[size_t(EScriptObjectType::Pickup)] = ScriptLoader::LoadPickup; + x90c_loaderFuncs[size_t(EScriptObjectType::MemoryRelay)] = ScriptLoader::LoadMemoryRelay; + x90c_loaderFuncs[size_t(EScriptObjectType::RandomRelay)] = ScriptLoader::LoadRandomRelay; + x90c_loaderFuncs[size_t(EScriptObjectType::Relay)] = ScriptLoader::LoadRelay; + x90c_loaderFuncs[size_t(EScriptObjectType::Beetle)] = ScriptLoader::LoadBeetle; + x90c_loaderFuncs[size_t(EScriptObjectType::HUDMemo)] = ScriptLoader::LoadHUDMemo; + x90c_loaderFuncs[size_t(EScriptObjectType::CameraFilterKeyframe)] = ScriptLoader::LoadCameraFilterKeyframe; + x90c_loaderFuncs[size_t(EScriptObjectType::CameraBlurKeyframe)] = ScriptLoader::LoadCameraBlurKeyframe; + x90c_loaderFuncs[size_t(EScriptObjectType::DamageableTrigger)] = ScriptLoader::LoadDamageableTrigger; + x90c_loaderFuncs[size_t(EScriptObjectType::Debris)] = ScriptLoader::LoadDebris; + x90c_loaderFuncs[size_t(EScriptObjectType::CameraShaker)] = ScriptLoader::LoadCameraShaker; + x90c_loaderFuncs[size_t(EScriptObjectType::ActorKeyframe)] = ScriptLoader::LoadActorKeyframe; + x90c_loaderFuncs[size_t(EScriptObjectType::Water)] = ScriptLoader::LoadWater; + x90c_loaderFuncs[size_t(EScriptObjectType::Warwasp)] = ScriptLoader::LoadWarWasp; + x90c_loaderFuncs[size_t(EScriptObjectType::SpacePirate)] = ScriptLoader::LoadSpacePirate; + x90c_loaderFuncs[size_t(EScriptObjectType::FlyingPirate)] = ScriptLoader::LoadFlyingPirate; + x90c_loaderFuncs[size_t(EScriptObjectType::ElitePirate)] = ScriptLoader::LoadElitePirate; + x90c_loaderFuncs[size_t(EScriptObjectType::MetroidBeta)] = ScriptLoader::LoadMetroidBeta; + x90c_loaderFuncs[size_t(EScriptObjectType::ChozoGhost)] = ScriptLoader::LoadChozoGhost; + x90c_loaderFuncs[size_t(EScriptObjectType::CoverPoint)] = ScriptLoader::LoadCoverPoint; + x90c_loaderFuncs[size_t(EScriptObjectType::SpiderBallWaypoint)] = ScriptLoader::LoadSpiderBallWaypoint; + x90c_loaderFuncs[size_t(EScriptObjectType::BloodFlower)] = ScriptLoader::LoadBloodFlower; + x90c_loaderFuncs[size_t(EScriptObjectType::FlickerBat)] = ScriptLoader::LoadFlickerBat; + x90c_loaderFuncs[size_t(EScriptObjectType::PathCamera)] = ScriptLoader::LoadPathCamera; + x90c_loaderFuncs[size_t(EScriptObjectType::GrapplePoint)] = ScriptLoader::LoadGrapplePoint; + x90c_loaderFuncs[size_t(EScriptObjectType::PuddleSpore)] = ScriptLoader::LoadPuddleSpore; + x90c_loaderFuncs[size_t(EScriptObjectType::DebugCameraWaypoint)] = ScriptLoader::LoadDebugCameraWaypoint; + x90c_loaderFuncs[size_t(EScriptObjectType::SpiderBallAttractionSurface)] = ScriptLoader::LoadSpiderBallAttractionSurface; + x90c_loaderFuncs[size_t(EScriptObjectType::PuddleToadGamma)] = ScriptLoader::LoadPuddleToadGamma; + x90c_loaderFuncs[size_t(EScriptObjectType::DistanceFog)] = ScriptLoader::LoadDistanceFog; + x90c_loaderFuncs[size_t(EScriptObjectType::FireFlea)] = ScriptLoader::LoadFireFlea; + x90c_loaderFuncs[size_t(EScriptObjectType::Metaree)] = ScriptLoader::LoadMetaree; + x90c_loaderFuncs[size_t(EScriptObjectType::DockAreaChange)] = ScriptLoader::LoadDockAreaChange; + x90c_loaderFuncs[size_t(EScriptObjectType::ActorRotate)] = ScriptLoader::LoadActorRotate; + x90c_loaderFuncs[size_t(EScriptObjectType::SpecialFunction)] = ScriptLoader::LoadSpecialFunction; + x90c_loaderFuncs[size_t(EScriptObjectType::SpankWeed)] = ScriptLoader::LoadSpankWeed; + x90c_loaderFuncs[size_t(EScriptObjectType::Parasite)] = ScriptLoader::LoadParasite; + x90c_loaderFuncs[size_t(EScriptObjectType::PlayerHint)] = ScriptLoader::LoadPlayerHint; + x90c_loaderFuncs[size_t(EScriptObjectType::Ripper)] = ScriptLoader::LoadRipper; + x90c_loaderFuncs[size_t(EScriptObjectType::PickupGenerator)] = ScriptLoader::LoadPickupGenerator; + x90c_loaderFuncs[size_t(EScriptObjectType::AIKeyframe)] = ScriptLoader::LoadAIKeyframe; + x90c_loaderFuncs[size_t(EScriptObjectType::PointOfInterest)] = ScriptLoader::LoadPointOfInterest; + x90c_loaderFuncs[size_t(EScriptObjectType::Drone)] = ScriptLoader::LoadDrone; + x90c_loaderFuncs[size_t(EScriptObjectType::Metroid)] = ScriptLoader::LoadMetroid; + x90c_loaderFuncs[size_t(EScriptObjectType::DebrisExtended)] = ScriptLoader::LoadDebrisExtended; + x90c_loaderFuncs[size_t(EScriptObjectType::Steam)] = ScriptLoader::LoadSteam; + x90c_loaderFuncs[size_t(EScriptObjectType::Ripple)] = ScriptLoader::LoadRipple; + x90c_loaderFuncs[size_t(EScriptObjectType::BallTrigger)] = ScriptLoader::LoadBallTrigger; + x90c_loaderFuncs[size_t(EScriptObjectType::TargetingPoint)] = ScriptLoader::LoadTargetingPoint; + x90c_loaderFuncs[size_t(EScriptObjectType::EMPulse)] = ScriptLoader::LoadEMPulse; + x90c_loaderFuncs[size_t(EScriptObjectType::IceSheegoth)] = ScriptLoader::LoadIceSheegoth; + x90c_loaderFuncs[size_t(EScriptObjectType::PlayerActor)] = ScriptLoader::LoadPlayerActor; + x90c_loaderFuncs[size_t(EScriptObjectType::Flaahgra)] = ScriptLoader::LoadFlaahgra; + x90c_loaderFuncs[size_t(EScriptObjectType::AreaAttributes)] = ScriptLoader::LoadAreaAttributes; + x90c_loaderFuncs[size_t(EScriptObjectType::FishCloud)] = ScriptLoader::LoadFishCloud; + x90c_loaderFuncs[size_t(EScriptObjectType::FishCloudModifier)] = ScriptLoader::LoadFishCloudModifier; + x90c_loaderFuncs[size_t(EScriptObjectType::VisorFlare)] = ScriptLoader::LoadVisorFlare; + x90c_loaderFuncs[size_t(EScriptObjectType::WorldTeleporter)] = ScriptLoader::LoadWorldTeleporter; + x90c_loaderFuncs[size_t(EScriptObjectType::VisorGoo)] = ScriptLoader::LoadVisorGoo; + x90c_loaderFuncs[size_t(EScriptObjectType::JellyZap)] = ScriptLoader::LoadJellyZap; + x90c_loaderFuncs[size_t(EScriptObjectType::ControllerAction)] = ScriptLoader::LoadControllerAction; + x90c_loaderFuncs[size_t(EScriptObjectType::Switch)] = ScriptLoader::LoadSwitch; + x90c_loaderFuncs[size_t(EScriptObjectType::PlayerStateChange)] = ScriptLoader::LoadPlayerStateChange; + x90c_loaderFuncs[size_t(EScriptObjectType::Thardus)] = ScriptLoader::LoadThardus; + x90c_loaderFuncs[size_t(EScriptObjectType::WallCrawlerSwarm)] = ScriptLoader::LoadWallCrawlerSwarm; + x90c_loaderFuncs[size_t(EScriptObjectType::AIJumpPoint)] = ScriptLoader::LoadAiJumpPoint; + x90c_loaderFuncs[size_t(EScriptObjectType::FlaahgraTentacle)] = ScriptLoader::LoadFlaahgraTentacle; + x90c_loaderFuncs[size_t(EScriptObjectType::RoomAcoustics)] = ScriptLoader::LoadRoomAcoustics; + x90c_loaderFuncs[size_t(EScriptObjectType::ColorModulate)] = ScriptLoader::LoadColorModulate; + x90c_loaderFuncs[size_t(EScriptObjectType::ThardusRockProjectile)] = ScriptLoader::LoadThardusRockProjectile; + x90c_loaderFuncs[size_t(EScriptObjectType::Midi)] = ScriptLoader::LoadMidi; + x90c_loaderFuncs[size_t(EScriptObjectType::StreamedAudio)] = ScriptLoader::LoadStreamedAudio; + x90c_loaderFuncs[size_t(EScriptObjectType::WorldTeleporterToo)] = ScriptLoader::LoadWorldTeleporter; + x90c_loaderFuncs[size_t(EScriptObjectType::Repulsor)] = ScriptLoader::LoadRepulsor; + x90c_loaderFuncs[size_t(EScriptObjectType::GunTurret)] = ScriptLoader::LoadGunTurret; + x90c_loaderFuncs[size_t(EScriptObjectType::FogVolume)] = ScriptLoader::LoadFogVolume; + x90c_loaderFuncs[size_t(EScriptObjectType::Babygoth)] = ScriptLoader::LoadBabygoth; + x90c_loaderFuncs[size_t(EScriptObjectType::Eyeball)] = ScriptLoader::LoadEyeball; + x90c_loaderFuncs[size_t(EScriptObjectType::RadialDamage)] = ScriptLoader::LoadRadialDamage; + x90c_loaderFuncs[size_t(EScriptObjectType::CameraPitchVolume)] = ScriptLoader::LoadCameraPitchVolume; + x90c_loaderFuncs[size_t(EScriptObjectType::EnvFxDensityController)] = ScriptLoader::LoadEnvFxDensityController; + x90c_loaderFuncs[size_t(EScriptObjectType::Magdolite)] = ScriptLoader::LoadMagdolite; + x90c_loaderFuncs[size_t(EScriptObjectType::TeamAIMgr)] = ScriptLoader::LoadTeamAIMgr; + x90c_loaderFuncs[size_t(EScriptObjectType::SnakeWeedSwarm)] = ScriptLoader::LoadSnakeWeedSwarm; + x90c_loaderFuncs[size_t(EScriptObjectType::ActorContraption)] = ScriptLoader::LoadActorContraption; + x90c_loaderFuncs[size_t(EScriptObjectType::Oculus)] = ScriptLoader::LoadOculus; + x90c_loaderFuncs[size_t(EScriptObjectType::Geemer)] = ScriptLoader::LoadGeemer; + x90c_loaderFuncs[size_t(EScriptObjectType::SpindleCamera)] = ScriptLoader::LoadSpindleCamera; + x90c_loaderFuncs[size_t(EScriptObjectType::AtomicAlpha)] = ScriptLoader::LoadAtomicAlpha; + x90c_loaderFuncs[size_t(EScriptObjectType::CameraHintTrigger)] = ScriptLoader::LoadCameraHintTrigger; + x90c_loaderFuncs[size_t(EScriptObjectType::RumbleEffect)] = ScriptLoader::LoadRumbleEffect; + x90c_loaderFuncs[size_t(EScriptObjectType::AmbientAI)] = ScriptLoader::LoadAmbientAI; + x90c_loaderFuncs[size_t(EScriptObjectType::AtomicBeta)] = ScriptLoader::LoadAtomicBeta; + x90c_loaderFuncs[size_t(EScriptObjectType::IceZoomer)] = ScriptLoader::LoadIceZoomer; + x90c_loaderFuncs[size_t(EScriptObjectType::Puffer)] = ScriptLoader::LoadPuffer; + x90c_loaderFuncs[size_t(EScriptObjectType::Tryclops)] = ScriptLoader::LoadTryclops; + x90c_loaderFuncs[size_t(EScriptObjectType::Ridley)] = ScriptLoader::LoadRidley; + x90c_loaderFuncs[size_t(EScriptObjectType::Seedling)] = ScriptLoader::LoadSeedling; + x90c_loaderFuncs[size_t(EScriptObjectType::ThermalHeatFader)] = ScriptLoader::LoadThermalHeatFader; + x90c_loaderFuncs[size_t(EScriptObjectType::Burrower)] = ScriptLoader::LoadBurrower; + x90c_loaderFuncs[size_t(EScriptObjectType::ScriptBeam)] = ScriptLoader::LoadBeam; + x90c_loaderFuncs[size_t(EScriptObjectType::WorldLightFader)] = ScriptLoader::LoadWorldLightFader; + x90c_loaderFuncs[size_t(EScriptObjectType::MetroidPrimeStage2)] = ScriptLoader::LoadMetroidPrimeStage2; + x90c_loaderFuncs[size_t(EScriptObjectType::MetroidPrimeStage1)] = ScriptLoader::LoadMetroidPrimeStage1; + x90c_loaderFuncs[size_t(EScriptObjectType::MazeNode)] = ScriptLoader::LoadMazeNode; + x90c_loaderFuncs[size_t(EScriptObjectType::OmegaPirate)] = ScriptLoader::LoadOmegaPirate; + x90c_loaderFuncs[size_t(EScriptObjectType::PhazonPool)] = ScriptLoader::LoadPhazonPool; + x90c_loaderFuncs[size_t(EScriptObjectType::PhazonHealingNodule)] = ScriptLoader::LoadPhazonHealingNodule; + x90c_loaderFuncs[size_t(EScriptObjectType::NewCameraShaker)] = ScriptLoader::LoadNewCameraShaker; + x90c_loaderFuncs[size_t(EScriptObjectType::ShadowProjector)] = ScriptLoader::LoadShadowProjector; + x90c_loaderFuncs[size_t(EScriptObjectType::EnergyBall)] = ScriptLoader::LoadEnergyBall; CGameCollision::InitCollision(); ControlMapper::ResetCommandFilters(); @@ -285,24 +285,26 @@ void CStateManager::UpdateThermalVisor() { } } -void CStateManager::RendererDrawCallback(const void* drawable, const void* ctx, int type) { - const CStateManager& mgr = *static_cast(ctx); +void CStateManager::RendererDrawCallback(void* drawable, void* ctx, int type) { + CStateManager& mgr = *static_cast(ctx); switch (type) { case 0: { - const CActor& actor = *static_cast(drawable); - if (actor.xc8_drawnToken == mgr.x8dc_objectDrawToken) + CActor& actor = *static_cast(drawable); + if (actor.xc8_drawnToken == mgr.x8dc_objectDrawToken) { break; - if (actor.xc6_nextDrawNode != kInvalidUniqueId) + } + if (actor.xc6_nextDrawNode != kInvalidUniqueId) { mgr.RecursiveDrawTree(actor.xc6_nextDrawNode); + } actor.Render(mgr); - const_cast(actor).xc8_drawnToken = mgr.x8dc_objectDrawToken; + actor.xc8_drawnToken = mgr.x8dc_objectDrawToken; break; } case 1: - static_cast(drawable)->Render(mgr.x8f0_shadowTex); + static_cast(drawable)->Render(mgr.x8f0_shadowTex); break; case 2: - static_cast(drawable)->Render(); + static_cast(drawable)->Render(); break; default: break; @@ -316,14 +318,13 @@ bool CStateManager::RenderLast(TUniqueId uid) { return true; } -void CStateManager::AddDrawableActorPlane(const CActor& actor, const zeus::CPlane& plane, - const zeus::CAABox& aabb) const { - const_cast(actor).SetAddedToken(x8dc_objectDrawToken + 1); +void CStateManager::AddDrawableActorPlane(CActor& actor, const zeus::CPlane& plane, const zeus::CAABox& aabb) const { + actor.SetAddedToken(x8dc_objectDrawToken + 1); g_Renderer->AddPlaneObject(&actor, aabb, plane, 0); } -void CStateManager::AddDrawableActor(const CActor& actor, const zeus::CVector3f& vec, const zeus::CAABox& aabb) const { - const_cast(actor).SetAddedToken(x8dc_objectDrawToken + 1); +void CStateManager::AddDrawableActor(CActor& actor, const zeus::CVector3f& vec, const zeus::CAABox& aabb) const { + actor.SetAddedToken(x8dc_objectDrawToken + 1); g_Renderer->AddDrawable(&actor, vec, aabb, 0, IRenderer::EDrawableSorting::SortedCallback); } @@ -518,10 +519,11 @@ void CStateManager::DrawDebugStuff() const { } } -void CStateManager::RenderCamerasAndAreaLights() const { +void CStateManager::RenderCamerasAndAreaLights() { x870_cameraManager->RenderCameras(*this); - for (const CCameraFilterPassPoly& filter : xb84_camFilterPasses) + for (const CCameraFilterPassPoly& filter : xb84_camFilterPasses) { filter.Draw(); + } } void CStateManager::DrawE3DeathEffect() { @@ -632,46 +634,50 @@ void CStateManager::ResetViewAfterDraw(const SViewport& backupViewport, void CStateManager::DrawWorld() { SCOPED_GRAPHICS_DEBUG_GROUP("CStateManager::DrawWorld", zeus::skBlue); - CTimeProvider timeProvider(xf14_curTimeMod900); - SViewport backupViewport = g_Viewport; + const CTimeProvider timeProvider(xf14_curTimeMod900); + const SViewport backupViewport = g_Viewport; /* Area camera is in (not necessarily player) */ - TAreaId visAreaId = GetVisAreaId(); + const TAreaId visAreaId = GetVisAreaId(); x850_world->TouchSky(); DrawWorldCubeFaces(); - zeus::CFrustum frustum = SetupViewForDraw(g_Viewport); - zeus::CTransform backupViewMatrix = CGraphics::g_ViewMatrix; + const zeus::CFrustum frustum = SetupViewForDraw(g_Viewport); + const zeus::CTransform backupViewMatrix = CGraphics::g_ViewMatrix; int areaCount = 0; - const CGameArea* areaArr[10]; + std::array areaArr; for (const CGameArea& area : *x850_world) { - if (areaCount == 10) + if (areaCount == 10) { break; + } CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::Occluded; - if (area.IsPostConstructed()) + if (area.IsPostConstructed()) { occState = area.GetOcclusionState(); - if (occState == CGameArea::EOcclusionState::Visible) + } + if (occState == CGameArea::EOcclusionState::Visible) { areaArr[areaCount++] = &area; + } } - std::sort(std::begin(areaArr), std::begin(areaArr) + areaCount, - [visAreaId](const CGameArea* a, const CGameArea* b) -> bool { - if (a->x4_selfIdx == b->x4_selfIdx) - return false; - if (visAreaId == a->x4_selfIdx) - return false; - if (visAreaId == b->x4_selfIdx) - return true; - return CGraphics::g_ViewPoint.dot(a->GetAABB().center()) > - CGraphics::g_ViewPoint.dot(b->GetAABB().center()); - }); + std::sort(areaArr.begin(), areaArr.begin() + areaCount, [visAreaId](const CGameArea* a, const CGameArea* b) { + if (a->x4_selfIdx == b->x4_selfIdx) { + return false; + } + if (visAreaId == a->x4_selfIdx) { + return false; + } + if (visAreaId == b->x4_selfIdx) { + return true; + } + return CGraphics::g_ViewPoint.dot(a->GetAABB().center()) > CGraphics::g_ViewPoint.dot(b->GetAABB().center()); + }); int pvsCount = 0; - CPVSVisSet pvsArr[10]; - for (const CGameArea** area = areaArr; area != areaArr + areaCount; ++area) { + std::array pvsArr; + for (auto area = areaArr.cbegin(); area != areaArr.cbegin() + areaCount; ++area) { const CGameArea* areaPtr = *area; CPVSVisSet& pvsSet = pvsArr[pvsCount++]; pvsSet.Reset(EPVSVisSetState::OutOfBounds); @@ -712,14 +718,17 @@ void CStateManager::DrawWorld() { if (areaCount) SetupFogForArea(*areaArr[areaCount - 1]); - for (TUniqueId id : x86c_stateManagerContainer->xf370_) - if (const CActor* ent = static_cast(GetObjectById(id))) - if (!thermal || ent->xe6_27_thermalVisorFlags & 0x1) + for (const TUniqueId id : x86c_stateManagerContainer->xf370_) { + if (auto* ent = static_cast(ObjectById(id))) { + if (!thermal || ent->xe6_27_thermalVisorFlags & 0x1) { ent->Render(*this); + } + } + } bool morphingPlayerVisible = false; int thermalActorCount = 0; - CActor* thermalActorArr[1024]; + std::array thermalActorArr; for (int i = 0; i < areaCount; ++i) { const CGameArea& area = *areaArr[i]; CPVSVisSet& pvs = pvsArr[i]; @@ -780,19 +789,25 @@ void CStateManager::DrawWorld() { if (thermal) { if (x86c_stateManagerContainer->xf39c_renderLast.size()) { CGraphics::SetDepthRange(DEPTH_SCREEN_ACTORS, DEPTH_GUN); - for (TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast) - if (const CActor* actor = static_cast(GetObjectById(id))) - if (actor->xe6_27_thermalVisorFlags & 0x1) + for (const TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast) { + if (auto* actor = static_cast(ObjectById(id))) { + if (actor->xe6_27_thermalVisorFlags & 0x1) { actor->Render(*this); + } + } + } CGraphics::SetDepthRange(DEPTH_WORLD, DEPTH_FAR); } g_Renderer->DoThermalBlendCold(); xf34_thermalFlag = EThermalDrawFlag::Hot; - for (TUniqueId id : x86c_stateManagerContainer->xf370_) - if (const CActor* actor = static_cast(GetObjectById(id))) - if (actor->xe6_27_thermalVisorFlags & 0x2) + for (const TUniqueId id : x86c_stateManagerContainer->xf370_) { + if (auto* actor = static_cast(ObjectById(id))) { + if (actor->xe6_27_thermalVisorFlags & 0x2) { actor->Render(*this); + } + } + } for (int i = areaCount - 1; i >= 0; --i) { const CGameArea& area = *areaArr[i]; @@ -847,10 +862,13 @@ void CStateManager::DrawWorld() { if (x86c_stateManagerContainer->xf39c_renderLast.size()) { CGraphics::SetDepthRange(DEPTH_SCREEN_ACTORS, DEPTH_GUN); - for (TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast) - if (const CActor* actor = static_cast(GetObjectById(id))) - if (!thermal || actor->xe6_27_thermalVisorFlags & 0x2) + for (const TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast) { + if (auto* actor = static_cast(ObjectById(id))) { + if (!thermal || actor->xe6_27_thermalVisorFlags & 0x2) { actor->Render(*this); + } + } + } CGraphics::SetDepthRange(DEPTH_WORLD, DEPTH_FAR); } @@ -876,15 +894,18 @@ void CStateManager::DrawActorCubeFaces(CActor& actor, int& cubeInst) const { SViewport backupVp = g_Viewport; int areaCount = 0; - const CGameArea* areaArr[10]; + std::array areaArr; for (const CGameArea& area : *x850_world) { - if (areaCount == 10) + if (areaCount == 10) { break; + } CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::Occluded; - if (area.IsPostConstructed()) + if (area.IsPostConstructed()) { occState = area.GetOcclusionState(); - if (occState == CGameArea::EOcclusionState::Visible) + } + if (occState == CGameArea::EOcclusionState::Visible) { areaArr[areaCount++] = &area; + } } for (int f = 0; f < 6; ++f) { @@ -896,20 +917,22 @@ void CStateManager::DrawActorCubeFaces(CActor& actor, int& cubeInst) const { SetupViewForCubeFaceDraw(actor.GetRenderBounds().center(), f); CGraphics::g_BooMainCommandQueue->clearTarget(); - std::sort( - std::begin(areaArr), std::begin(areaArr) + areaCount, [visAreaId](const CGameArea* a, const CGameArea* b) { - if (a->x4_selfIdx == b->x4_selfIdx) - return false; - if (visAreaId == a->x4_selfIdx) - return false; - if (visAreaId == b->x4_selfIdx) - return true; - return CGraphics::g_ViewPoint.dot(a->GetAABB().center()) > CGraphics::g_ViewPoint.dot(b->GetAABB().center()); - }); + std::sort(areaArr.begin(), areaArr.begin() + areaCount, [visAreaId](const CGameArea* a, const CGameArea* b) { + if (a->x4_selfIdx == b->x4_selfIdx) { + return false; + } + if (visAreaId == a->x4_selfIdx) { + return false; + } + if (visAreaId == b->x4_selfIdx) { + return true; + } + return CGraphics::g_ViewPoint.dot(a->GetAABB().center()) > CGraphics::g_ViewPoint.dot(b->GetAABB().center()); + }); int pvsCount = 0; - CPVSVisSet pvsArr[10]; - for (const CGameArea** area = areaArr; area != areaArr + areaCount; ++area) { + std::array pvsArr; + for (auto area = areaArr.cbegin(); area != areaArr.cbegin() + areaCount; ++area) { const CGameArea* areaPtr = *area; CPVSVisSet& pvsSet = pvsArr[pvsCount++]; pvsSet.Reset(EPVSVisSetState::OutOfBounds); @@ -949,19 +972,22 @@ void CStateManager::DrawActorCubeFaces(CActor& actor, int& cubeInst) const { } void CStateManager::DrawWorldCubeFaces() const { - int areaCount = 0; - const CGameArea* areaArr[10]; + size_t areaCount = 0; + std::array areaArr; for (const CGameArea& area : *x850_world) { - if (areaCount == 10) + if (areaCount == areaArr.size()) { break; + } CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::Occluded; - if (area.IsPostConstructed()) + if (area.IsPostConstructed()) { occState = area.GetOcclusionState(); - if (occState == CGameArea::EOcclusionState::Visible) + } + if (occState == CGameArea::EOcclusionState::Visible) { areaArr[areaCount++] = &area; + } } - for (int ai = 0; ai < areaCount; ++ai) { + for (size_t ai = 0; ai < areaCount; ++ai) { const CGameArea& area = *areaArr[ai]; int cubeInst = 0; for (CEntity* ent : *area.GetAreaObjects()) { @@ -1161,14 +1187,16 @@ bool CStateManager::GetVisSetForArea(TAreaId a, TAreaId b, CPVSVisSet& setOut) c return false; } -void CStateManager::RecursiveDrawTree(TUniqueId node) const { - if (TCastToConstPtr actor = GetObjectById(node)) { +void CStateManager::RecursiveDrawTree(TUniqueId node) { + if (const TCastToPtr actor = ObjectById(node)) { if (x8dc_objectDrawToken != actor->xc8_drawnToken) { - if (actor->xc6_nextDrawNode != kInvalidUniqueId) + if (actor->xc6_nextDrawNode != kInvalidUniqueId) { RecursiveDrawTree(actor->xc6_nextDrawNode); - if (x8dc_objectDrawToken == actor->xcc_addedToken) + } + if (x8dc_objectDrawToken == actor->xcc_addedToken) { actor->Render(*this); - const_cast(actor.GetPtr())->xc8_drawnToken = x8dc_objectDrawToken; + } + actor->xc8_drawnToken = x8dc_objectDrawToken; } } } @@ -1320,8 +1348,9 @@ std::pair CStateManager::LoadScriptObject(TAreaId aid, ESc bool error = false; FScriptLoader loader = {}; - if (type < EScriptObjectType::ScriptObjectTypeMAX && type >= EScriptObjectType::Actor) - loader = x90c_loaderFuncs[int(type)]; + if (type < EScriptObjectType::ScriptObjectTypeMAX && type >= EScriptObjectType::Actor) { + loader = x90c_loaderFuncs[size_t(type)]; + } CEntity* ent = nullptr; if (loader) { @@ -1559,10 +1588,10 @@ bool CStateManager::TestRayDamage(const zeus::CVector3f& pos, const CActor& dama if (!hInfo) return false; - static const CMaterialList incList(EMaterialTypes::Solid); - static const CMaterialList exList(EMaterialTypes::ProjectilePassthrough, EMaterialTypes::Player, - EMaterialTypes::Occluder, EMaterialTypes::Character); - static const CMaterialFilter filter(incList, exList, CMaterialFilter::EFilterType::IncludeExclude); + static constexpr CMaterialList incList(EMaterialTypes::Solid); + static constexpr CMaterialList exList(EMaterialTypes::ProjectilePassthrough, EMaterialTypes::Player, + EMaterialTypes::Occluder, EMaterialTypes::Character); + static constexpr CMaterialFilter filter(incList, exList, CMaterialFilter::EFilterType::IncludeExclude); std::optional bounds = damagee.GetTouchBounds(); if (!bounds) @@ -1881,7 +1910,7 @@ void CStateManager::Update(float dt) { UpdateHintState(dt); } - for (int i = 0; i < 9; ++i) { + for (size_t i = 0; i < numCameraPasses; ++i) { xb84_camFilterPasses[i].Update(dt); xd14_camBlurPasses[i].Update(dt); } @@ -2060,35 +2089,45 @@ void CStateManager::MoveActors(float dt) { } void CStateManager::CrossTouchActors() { - bool visits[1024] = {}; + std::array visits{}; + for (CEntity* ent : GetActorObjectList()) { - if (!ent) + if (!ent) { continue; - CActor& actor = static_cast(*ent); - if (!actor.GetActive() || !actor.GetCallTouch()) + } + + auto& actor = static_cast(*ent); + if (!actor.GetActive() || !actor.GetCallTouch()) { continue; + } + std::optional touchAABB = actor.GetTouchBounds(); - if (!touchAABB) + if (!touchAABB) { continue; + } CMaterialFilter filter = CMaterialFilter::skPassEverything; - if (actor.GetMaterialList().HasMaterial(EMaterialTypes::Trigger)) + if (actor.GetMaterialList().HasMaterial(EMaterialTypes::Trigger)) { filter = CMaterialFilter::MakeExclude(EMaterialTypes::Trigger); + } rstl::reserved_vector nearList; BuildNearList(nearList, *touchAABB, filter, &actor); for (TUniqueId id : nearList) { - CActor* ent2 = static_cast(ObjectById(id)); - if (!ent2) + auto* ent2 = static_cast(ObjectById(id)); + if (!ent2) { continue; + } std::optional touchAABB2 = ent2->GetTouchBounds(); - if (!ent2->GetActive() || !touchAABB2) + if (!ent2->GetActive() || !touchAABB2) { continue; + } - if (visits[ent2->GetUniqueId().Value()]) + if (visits[ent2->GetUniqueId().Value()]) { continue; + } if (touchAABB->intersects(*touchAABB2)) { actor.Touch(*ent2, *this); @@ -2282,23 +2321,25 @@ void CStateManager::RemoveObject(TUniqueId uid) { void CStateManager::UpdateRoomAcoustics(TAreaId aid) { u32 updateCount = 0; - CScriptRoomAcoustics* updates[10]; + std::array updates; for (CEntity* ent : GetAllObjectList()) { if (TCastToPtr acoustics = ent) { - if (acoustics->GetAreaIdAlways() != aid || !acoustics->GetActive()) + if (acoustics->GetAreaIdAlways() != aid || !acoustics->GetActive()) { continue; + } updates[updateCount++] = acoustics.GetPtr(); } - if (updateCount >= 10) + if (updateCount >= updates.size()) { break; + } } - if (!updateCount) { + if (updateCount == 0) { CScriptRoomAcoustics::DisableAuxCallbacks(); return; } - auto idx = int(updateCount * x900_activeRandom->Float() * 0.99f); + const auto idx = int(updateCount * x900_activeRandom->Float() * 0.99f); updates[idx]->EnableAuxCallbacks(); } @@ -2314,7 +2355,7 @@ void CStateManager::SetCurrentAreaId(TAreaId aid) { if (x8c0_mapWorldInfo->IsAreaVisited(aid)) return; x8c0_mapWorldInfo->SetAreaVisited(aid, true); - x850_world->GetMapWorld()->RecalculateWorldSphere(*x8c0_mapWorldInfo, *x850_world); + x850_world->IGetMapWorld()->RecalculateWorldSphere(*x8c0_mapWorldInfo, *x850_world); } void CStateManager::AreaUnloaded(TAreaId) { diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index 7d8fd19e2..225c79e07 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -85,7 +85,7 @@ public: private: s16 x0_nextFreeIndex = 0; - u16 x8_idArr[1024] = {}; + std::array x8_idArr{}; /* std::unique_ptr x80c_allObjs; @@ -97,14 +97,16 @@ private: std::unique_ptr x83c_aiWaypointObjs; std::unique_ptr x844_platformAndDoorObjs; */ - std::array, 8> x808_objLists = {std::make_unique(EGameObjectList::All), - std::make_unique(), - std::make_unique(), - std::make_unique(), - std::make_unique(), - std::make_unique(), - std::make_unique(), - std::make_unique()}; + std::array, 8> x808_objLists{ + std::make_unique(EGameObjectList::All), + std::make_unique(), + std::make_unique(), + std::make_unique(), + std::make_unique(), + std::make_unique(), + std::make_unique(), + std::make_unique(), + }; std::unique_ptr x84c_player; std::unique_ptr x850_world; @@ -156,7 +158,7 @@ private: CRandom16* x900_activeRandom = nullptr; EGameState x904_gameState = EGameState::Running; u32 x908_loaderCount = 0; - FScriptLoader x90c_loaderFuncs[int(EScriptObjectType::ScriptObjectTypeMAX)] = {}; + std::array x90c_loaderFuncs{}; bool xab0_worldLoaded = false; @@ -165,8 +167,10 @@ private: std::set xb40_uniqueInstanceNames; CFinalInput xb54_finalInput; - CCameraFilterPassPoly xb84_camFilterPasses[9]; // size: 0x2c - CCameraBlurPass xd14_camBlurPasses[9]; // size: 0x34 + + static constexpr size_t numCameraPasses = 9; + std::array xb84_camFilterPasses; // size: 0x2c + std::array xd14_camBlurPasses; // size: 0x34 s32 xeec_hintIdx = -1; u32 xef0_hintPeriods = 0; @@ -212,12 +216,12 @@ private: u32 xf94_ = 0; }; - CColoredQuadFilter m_deathWhiteout = {EFilterType::Add}; - CColoredQuadFilter m_escapeWhiteout = {EFilterType::Add}; + CColoredQuadFilter m_deathWhiteout{EFilterType::Add}; + CColoredQuadFilter m_escapeWhiteout{EFilterType::Add}; bool m_warping = false; void UpdateThermalVisor(); - static void RendererDrawCallback(const void*, const void*, int); + static void RendererDrawCallback(void*, void*, int); public: CStateManager(const std::weak_ptr&, const std::weak_ptr&, @@ -227,8 +231,8 @@ public: u32 GetInputFrameIdx() const { return x8d4_inputFrameIdx; } bool RenderLast(TUniqueId); - void AddDrawableActorPlane(const CActor& actor, const zeus::CPlane&, const zeus::CAABox& aabb) const; - void AddDrawableActor(const CActor& actor, const zeus::CVector3f& vec, const zeus::CAABox& aabb) const; + void AddDrawableActorPlane(CActor& actor, const zeus::CPlane&, const zeus::CAABox& aabb) const; + void AddDrawableActor(CActor& actor, const zeus::CVector3f& vec, const zeus::CAABox& aabb) const; bool SpecialSkipCinematic(); TAreaId GetVisAreaId() const; s32 GetWeaponIdCount(TUniqueId, EWeaponType) const; @@ -251,7 +255,7 @@ public: const std::vector& GetDynamicLightList() const { return x8e0_dynamicLights; } void BuildDynamicLightListForWorld(); void DrawDebugStuff() const; - void RenderCamerasAndAreaLights() const; + void RenderCamerasAndAreaLights(); void DrawE3DeathEffect(); void DrawAdditionalFilters(); zeus::CFrustum SetupDrawFrustum(const SViewport& vp) const; @@ -271,7 +275,7 @@ public: void PreRender(); void GetCharacterRenderMaskAndTarget(bool thawed, int& mask, int& target) const; bool GetVisSetForArea(TAreaId, TAreaId, CPVSVisSet& setOut) const; - void RecursiveDrawTree(TUniqueId) const; + void RecursiveDrawTree(TUniqueId); void SendScriptMsg(CEntity* dest, TUniqueId src, EScriptObjectMessage msg); void SendScriptMsg(TUniqueId dest, TUniqueId src, EScriptObjectMessage msg); void SendScriptMsg(TUniqueId src, TEditorId dest, EScriptObjectMessage msg, EScriptObjectState state); diff --git a/Runtime/CStaticInterference.hpp b/Runtime/CStaticInterference.hpp index 9e2718912..2018165f9 100644 --- a/Runtime/CStaticInterference.hpp +++ b/Runtime/CStaticInterference.hpp @@ -16,7 +16,7 @@ class CStaticInterference { std::vector m_sources; public: - CStaticInterference(int sourceCount); + explicit CStaticInterference(int sourceCount); void RemoveSource(TUniqueId id); void Update(CStateManager&, float dt); float GetTotalInterference() const; diff --git a/Runtime/CTextureCache.hpp b/Runtime/CTextureCache.hpp index 70364d691..220e0ba5c 100644 --- a/Runtime/CTextureCache.hpp +++ b/Runtime/CTextureCache.hpp @@ -8,7 +8,7 @@ class CPaletteInfo { u64 m_dolphinHash; public: - CPaletteInfo(CInputStream& in) + explicit CPaletteInfo(CInputStream& in) : m_format(in.readUint32Big()), m_elementCount(in.readUint32Big()), m_dolphinHash(in.readUint64Big()) {} }; class CTextureInfo { @@ -20,7 +20,7 @@ class CTextureInfo { std::optional m_paletteInfo; public: - CTextureInfo(CInputStream& in) + explicit CTextureInfo(CInputStream& in) : m_format(ETexelFormat(in.readUint32Big())) , m_mipCount(in.readUint32Big()) , m_width(in.readUint16Big()) @@ -36,7 +36,7 @@ public: std::map m_textureInfo; public: - CTextureCache(CInputStream& in); + explicit CTextureCache(CInputStream& in); const CTextureInfo* GetTextureInfo(CAssetId id) const; diff --git a/Runtime/CToken.cpp b/Runtime/CToken.cpp index e30daf34f..38bfa24ed 100644 --- a/Runtime/CToken.cpp +++ b/Runtime/CToken.cpp @@ -112,7 +112,7 @@ CToken& CToken::operator=(const CToken& other) { } return *this; } -CToken& CToken::operator=(CToken&& other) { +CToken& CToken::operator=(CToken&& other) noexcept { Unlock(); RemoveRef(); x0_objRef = other.x0_objRef; diff --git a/Runtime/CToken.hpp b/Runtime/CToken.hpp index 7d156928a..1fec4bbd5 100644 --- a/Runtime/CToken.hpp +++ b/Runtime/CToken.hpp @@ -84,7 +84,7 @@ public: IObj* GetObj(); const IObj* GetObj() const { return const_cast(this)->GetObj(); } CToken& operator=(const CToken& other); - CToken& operator=(CToken&& other); + CToken& operator=(CToken&& other) noexcept; CToken() = default; CToken(const CToken& other); CToken(CToken&& other) noexcept; @@ -101,6 +101,7 @@ public: return TObjOwnerDerivedFromIObj::GetNewDerivedObject(std::move(obj)); } TToken() = default; + virtual ~TToken() = default; TToken(const CToken& other) : CToken(other) {} TToken(CToken&& other) : CToken(std::move(other)) {} TToken(std::unique_ptr&& obj) : CToken(GetIObjObjectFor(std::move(obj))) {} @@ -108,13 +109,19 @@ public: *this = CToken(GetIObjObjectFor(std::move(obj))); return this; } - T* GetObj() { + virtual void Unlock() { CToken::Unlock(); } + virtual void Lock() { CToken::Lock(); } + virtual T* GetObj() { TObjOwnerDerivedFromIObj* owner = static_cast*>(CToken::GetObj()); if (owner) return owner->GetObj(); return nullptr; } - const T* GetObj() const { return const_cast*>(this)->GetObj(); } + virtual const T* GetObj() const { return const_cast*>(this)->GetObj(); } + virtual TToken& operator=(const CToken& other) { + CToken::operator=(other); + return *this; + } T* operator->() { return GetObj(); } const T* operator->() const { return GetObj(); } T& operator*() { return *GetObj(); } @@ -130,26 +137,24 @@ public: TCachedToken() = default; TCachedToken(const CToken& other) : TToken(other) {} TCachedToken(CToken&& other) : TToken(std::move(other)) {} - T* GetObj() { + T* GetObj() override { if (!m_obj) m_obj = TToken::GetObj(); return m_obj; } - const T* GetObj() const { return const_cast*>(this)->GetObj(); } - T* operator->() { return GetObj(); } - const T* operator->() const { return GetObj(); } - void Unlock() { + const T* GetObj() const override { return const_cast*>(this)->GetObj(); } + void Unlock() override { TToken::Unlock(); m_obj = nullptr; } TCachedToken& operator=(const TCachedToken& other) { - CToken::operator=(other); + TToken::operator=(other); m_obj = nullptr; return *this; } - TCachedToken& operator=(const CToken& other) { - CToken::operator=(other); + TCachedToken& operator=(const CToken& other) override { + TToken::operator=(other); m_obj = nullptr; return *this; } @@ -167,7 +172,7 @@ public: return *this; } TLockedToken(const CToken& other) : TCachedToken(other) { CToken::Lock(); } - TLockedToken& operator=(const CToken& other) { + TLockedToken& operator=(const CToken& other) override { CToken oldTok = std::move(*this); TCachedToken::operator=(other); CToken::Lock(); diff --git a/Runtime/Camera/CBallCamera.cpp b/Runtime/Camera/CBallCamera.cpp index 0b51e809f..d2b285ae8 100644 --- a/Runtime/Camera/CBallCamera.cpp +++ b/Runtime/Camera/CBallCamera.cpp @@ -242,7 +242,7 @@ void CBallCamera::Reset(const zeus::CTransform& xf, CStateManager& mgr) { } } -void CBallCamera::Render(const CStateManager& mgr) const { +void CBallCamera::Render(CStateManager& mgr) { // Empty } @@ -586,13 +586,13 @@ void CBallCamera::CheckFailsafe(float dt, CStateManager& mgr) { void CBallCamera::UpdateObjectTooCloseId(CStateManager& mgr) { x3e0_tooCloseActorDist = 1000000.f; x3dc_tooCloseActorId = kInvalidUniqueId; - zeus::CVector3f ballPos = mgr.GetPlayer().GetBallPosition(); - for (CEntity* ent : mgr.GetPlatformAndDoorObjectList()) { - if (TCastToPtr door = ent) { + const zeus::CVector3f ballPos = mgr.GetPlayer().GetBallPosition(); + for (const CEntity* ent : mgr.GetPlatformAndDoorObjectList()) { + if (const TCastToConstPtr door = ent) { if (mgr.GetPlayer().GetAreaIdAlways() == door->GetAreaIdAlways()) { door->GetBoundingBox(); - float minMag = std::min((door->GetTranslation() - GetTranslation()).magnitude(), - (door->GetTranslation() - ballPos).magnitude()); + const float minMag = std::min((door->GetTranslation() - GetTranslation()).magnitude(), + (door->GetTranslation() - ballPos).magnitude()); if (minMag < 30.f && minMag < x3e0_tooCloseActorDist) { x3dc_tooCloseActorId = door->GetUniqueId(); x3e0_tooCloseActorDist = minMag; @@ -611,7 +611,7 @@ void CBallCamera::UpdateAnglePerSecond(float dt) { } void CBallCamera::UpdateUsingPathCameras(float dt, CStateManager& mgr) { - if (TCastToPtr cam = mgr.ObjectById(mgr.GetCameraManager()->GetPathCameraId())) { + if (const TCastToConstPtr cam = mgr.ObjectById(mgr.GetCameraManager()->GetPathCameraId())) { TeleportCamera(cam->GetTransform(), mgr); x18d_26_lookAtBall = true; } @@ -707,15 +707,15 @@ zeus::CVector3f CBallCamera::TweenVelocity(const zeus::CVector3f& curVel, const } zeus::CVector3f CBallCamera::MoveCollisionActor(const zeus::CVector3f& pos, float dt, CStateManager& mgr) { - if (TCastToPtr act = mgr.ObjectById(x46c_collisionActorId)) { - zeus::CVector3f posDelta = pos - act->GetTranslation(); + if (const TCastToPtr act = mgr.ObjectById(x46c_collisionActorId)) { + const zeus::CVector3f posDelta = pos - act->GetTranslation(); if (!posDelta.canBeNormalized() || posDelta.magnitude() < 0.01f) { act->Stop(); return act->GetTranslation(); } - zeus::CVector3f oldTranslation = act->GetTranslation(); - zeus::CVector3f oldVel = act->GetVelocity(); - zeus::CVector3f newVel = ComputeVelocity(oldVel, posDelta * (1.f / dt)); + const zeus::CVector3f oldTranslation = act->GetTranslation(); + const zeus::CVector3f oldVel = act->GetVelocity(); + const zeus::CVector3f newVel = ComputeVelocity(oldVel, posDelta * (1.f / dt)); act->SetVelocityWR(newVel); act->SetMovable(true); act->AddMaterial(EMaterialTypes::Solid, mgr); @@ -808,8 +808,8 @@ void CBallCamera::UpdateUsingFreeLook(float dt, CStateManager& mgr) { } x37c_camSpline.UpdateSplineLength(); - zeus::CVector3f pos = x37c_camSpline.GetInterpolatedSplinePointByLength(splineT * x37c_camSpline.x44_length).origin; - if (TCastToPtr act = mgr.ObjectById(x46c_collisionActorId)) { + const zeus::CVector3f pos = x37c_camSpline.GetInterpolatedSplinePointByLength(splineT * x37c_camSpline.x44_length).origin; + if (const TCastToPtr act = mgr.ObjectById(x46c_collisionActorId)) { CMaterialFilter filter = act->GetMaterialFilter(); CMaterialFilter tmpFilter = filter; tmpFilter.IncludeList().Add(EMaterialTypes::Wall); @@ -820,8 +820,9 @@ void CBallCamera::UpdateUsingFreeLook(float dt, CStateManager& mgr) { } zeus::CVector3f lookDir = x1d8_lookPos - desiredPos; - if (x18d_26_lookAtBall) + if (x18d_26_lookAtBall) { lookDir = ballPos - desiredPos; + } if (lookDir.canBeNormalized()) { lookDir.normalize(); @@ -830,8 +831,9 @@ void CBallCamera::UpdateUsingFreeLook(float dt, CStateManager& mgr) { TeleportCamera(desiredPos, mgr); - if (x3d0_24_camBehindFloorOrWall && x374_splineCtrl / x378_splineCtrlRange < 0.5f) + if (x3d0_24_camBehindFloorOrWall && x374_splineCtrl / x378_splineCtrlRange < 0.5f) { x36c_splineState = ESplineState::Invalid; + } } zeus::CVector3f CBallCamera::InterpolateCameraElevation(const zeus::CVector3f& camPos, float dt) { @@ -1307,7 +1309,7 @@ void CBallCamera::UpdateUsingColliders(float dt, CStateManager& mgr) { } void CBallCamera::UpdateUsingSpindleCameras(float dt, CStateManager& mgr) { - if (TCastToPtr cam = mgr.ObjectById(mgr.GetCameraManager()->GetSpindleCameraId())) { + if (const TCastToConstPtr cam = mgr.ObjectById(mgr.GetCameraManager()->GetSpindleCameraId())) { TeleportCamera(cam->GetTransform(), mgr); x18d_26_lookAtBall = true; } @@ -1315,12 +1317,13 @@ void CBallCamera::UpdateUsingSpindleCameras(float dt, CStateManager& mgr) { zeus::CVector3f CBallCamera::ClampElevationToWater(zeus::CVector3f& pos, CStateManager& mgr) const { zeus::CVector3f ret = pos; - if (TCastToConstPtr water = mgr.GetObjectById(mgr.GetPlayer().GetFluidId())) { - float waterZ = water->GetTriggerBoundsWR().max.z(); - if (pos.z() >= waterZ && pos.z() - waterZ <= 0.25f) + if (const TCastToConstPtr water = mgr.GetObjectById(mgr.GetPlayer().GetFluidId())) { + const float waterZ = water->GetTriggerBoundsWR().max.z(); + if (pos.z() >= waterZ && pos.z() - waterZ <= 0.25f) { ret.z() = 0.25f + waterZ; - else if (pos.z() < waterZ && pos.z() - waterZ >= -0.12f) + } else if (pos.z() < waterZ && pos.z() - waterZ >= -0.12f) { ret.z() = waterZ - 0.12f; + } } return ret; } @@ -1366,24 +1369,25 @@ void CBallCamera::UpdateUsingTransitions(float dt, CStateManager& mgr) { float distance = x194_targetMinDistance; ConstrainElevationAndDistance(elevation, distance, dt, mgr); distance = x194_targetMinDistance; - bool r28 = IsBallNearDoor(GetTranslation(), mgr) || x478_shortMoveCount > 2; - zeus::CVector3f toDesired = + const bool r28 = IsBallNearDoor(GetTranslation(), mgr) || x478_shortMoveCount > 2; + const zeus::CVector3f toDesired = FindDesiredPosition(distance, elevation, mgr.GetPlayer().GetMoveDir(), mgr, r28) - eyePos; zeus::CVector3f finalPos = toDesired * mgr.GetPlayer().GetMorphFactor() + eyePos; - if (TCastToPtr act = mgr.ObjectById(x46c_collisionActorId)) { + if (const TCastToPtr act = mgr.ObjectById(x46c_collisionActorId)) { act->SetTranslation(GetTranslation()); finalPos = ClampElevationToWater(finalPos, mgr); finalPos = MoveCollisionActor(finalPos, dt, mgr); zeus::CVector3f camToLookDir = x1d8_lookPos - finalPos; if (camToLookDir.canBeNormalized()) { camToLookDir.normalize(); - float devDot = std::fabs(zeus::clamp(-1.f, lookDir.dot(camToLookDir), 1.f)); - float devAngle = zeus::clamp(-1.f, mgr.GetPlayer().GetMorphFactor() * 0.5f, 1.f) * std::acos(devDot); - if (devDot < 1.f) + const float devDot = std::fabs(zeus::clamp(-1.f, lookDir.dot(camToLookDir), 1.f)); + const float devAngle = zeus::clamp(-1.f, mgr.GetPlayer().GetMorphFactor() * 0.5f, 1.f) * std::acos(devDot); + if (devDot < 1.f) { SetTransform(zeus::CQuaternion::lookAt(xe8.basis[1], camToLookDir, devAngle).toTransform() * xe8.getRotation()); - else + } else { SetTransform(zeus::lookAt(zeus::skZero3f, camToLookDir)); + } } } SetTransform(ValidateCameraTransform(x34_transform, xe8)); @@ -1509,7 +1513,7 @@ bool CBallCamera::SplineIntersectTest(CMaterialList& intersectMat, CStateManager TUniqueId xe38 = kInvalidUniqueId; rstl::reserved_vector xacc; rstl::reserved_vector xd10; - CMaterialFilter filter = + constexpr auto filter = CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid, EMaterialTypes::Floor, EMaterialTypes::Wall}, {EMaterialTypes::ProjectilePassthrough, EMaterialTypes::Player, EMaterialTypes::Character, EMaterialTypes::CameraPassthrough}); @@ -1544,18 +1548,23 @@ bool CBallCamera::SplineIntersectTest(CMaterialList& intersectMat, CStateManager } bool CBallCamera::IsBallNearDoor(const zeus::CVector3f& pos, CStateManager& mgr) { - TCastToConstPtr door = mgr.GetObjectById(mgr.GetCameraManager()->GetBallCamera()->x3dc_tooCloseActorId); - if (!door || door->x2a8_26_isOpen) + const TCastToConstPtr door = + mgr.GetObjectById(mgr.GetCameraManager()->GetBallCamera()->x3dc_tooCloseActorId); + if (!door || door->x2a8_26_isOpen) { return false; + } - auto tb = door->GetTouchBounds(); - zeus::CAABox testAABB(pos - 0.3f, pos + 0.3f); - if (!tb || !tb->intersects(testAABB)) + const auto tb = door->GetTouchBounds(); + const zeus::CAABox testAABB(pos - 0.3f, pos + 0.3f); + if (!tb || !tb->intersects(testAABB)) { return false; + } - if (TCastToConstPtr dock = mgr.GetObjectById(door->x282_dockId)) - if (std::fabs(dock->GetPlane(mgr).pointToPlaneDist(pos)) < 1.15f) + if (const TCastToConstPtr dock = mgr.GetObjectById(door->x282_dockId)) { + if (std::fabs(dock->GetPlane(mgr).pointToPlaneDist(pos)) < 1.15f) { return true; + } + } return false; } @@ -1586,17 +1595,20 @@ bool CBallCamera::ConstrainElevationAndDistance(float& elevation, float& distanc float newDistance = distance; float baseElevation = elevation; float springSpeed = 1.f; - if (TCastToConstPtr door = mgr.GetObjectById(x3dc_tooCloseActorId)) { + if (const TCastToConstPtr door = mgr.GetObjectById(x3dc_tooCloseActorId)) { if (!door->x2a8_29_ballDoor) { stretchFac = zeus::clamp(-1.f, std::fabs(x3e0_tooCloseActorDist / (3.f * distance)), 1.f); - if (x3e0_tooCloseActorDist < 3.f * distance) + if (x3e0_tooCloseActorDist < 3.f * distance) { doorClose = true; - if (door->x2a8_26_isOpen) + } + if (door->x2a8_26_isOpen) { newDistance = stretchFac * (distance - x468_conservativeDoorCamDistance) + x468_conservativeDoorCamDistance; - else + } else { newDistance = stretchFac * (distance - 5.f) + 5.f; - if (x18d_28_obtuseDirection) + } + if (x18d_28_obtuseDirection) { newDistance *= 1.f + x308_speedFactor; + } baseElevation = door->x2a8_26_isOpen ? 0.75f : 1.5f; springSpeed = 4.f; } @@ -1799,9 +1811,10 @@ bool CBallCamera::DetectCollision(const zeus::CVector3f& from, const zeus::CVect void CBallCamera::Think(float dt, CStateManager& mgr) { mgr.SetActorAreaId(*this, mgr.GetNextAreaId()); UpdatePlayerMovement(dt, mgr); - TCastToPtr colAct = mgr.ObjectById(x46c_collisionActorId); - if (colAct) + const TCastToPtr colAct = mgr.ObjectById(x46c_collisionActorId); + if (colAct) { mgr.SetActorAreaId(*colAct, mgr.GetNextAreaId()); + } switch (mgr.GetPlayer().GetCameraState()) { default: @@ -1936,8 +1949,9 @@ void CBallCamera::TeleportCamera(const zeus::CVector3f& pos, CStateManager& mgr) TeleportColliders(x264_smallColliders, pos); TeleportColliders(x274_mediumColliders, pos); TeleportColliders(x284_largeColliders, pos); - if (TCastToPtr act = mgr.ObjectById(x46c_collisionActorId)) + if (const TCastToPtr act = mgr.ObjectById(x46c_collisionActorId)) { act->SetTranslation(pos); + } } void CBallCamera::TeleportCamera(const zeus::CTransform& xf, CStateManager& mgr) { diff --git a/Runtime/Camera/CBallCamera.hpp b/Runtime/Camera/CBallCamera.hpp index 617cfd889..dcc6572b8 100644 --- a/Runtime/Camera/CBallCamera.hpp +++ b/Runtime/Camera/CBallCamera.hpp @@ -247,7 +247,7 @@ public: void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) override; void ProcessInput(const CFinalInput& input, CStateManager& mgr) override; void Reset(const zeus::CTransform&, CStateManager& mgr) override; - void Render(const CStateManager& mgr) const override; + void Render(CStateManager& mgr) override; EBallCameraBehaviour GetBehaviour() const { return x188_behaviour; } EBallCameraState GetState() const { return x400_state; } void SetState(EBallCameraState state, CStateManager& mgr); diff --git a/Runtime/Camera/CCameraFilter.cpp b/Runtime/Camera/CCameraFilter.cpp index 53ff45c88..426463ae5 100644 --- a/Runtime/Camera/CCameraFilter.cpp +++ b/Runtime/Camera/CCameraFilter.cpp @@ -104,9 +104,11 @@ void CCameraFilterPass::DisableFilter(float time) { } template -void CCameraFilterPass::Draw() const { - if (m_shader) - const_cast(*m_shader).DrawFilter(x8_shape, x18_curColor, GetT(x4_nextType == EFilterType::Passthru)); +void CCameraFilterPass::Draw() { + if (!m_shader) { + return; + } + m_shader->DrawFilter(x8_shape, x18_curColor, GetT(x4_nextType == EFilterType::Passthru)); } float CCameraFilterPassBase::GetT(bool invert) const { diff --git a/Runtime/Camera/CCameraFilter.hpp b/Runtime/Camera/CCameraFilter.hpp index 027bf2466..f42aeaec6 100644 --- a/Runtime/Camera/CCameraFilter.hpp +++ b/Runtime/Camera/CCameraFilter.hpp @@ -58,7 +58,7 @@ public: virtual void SetFilter(EFilterType type, EFilterShape shape, float time, const zeus::CColor& color, CAssetId txtr) = 0; virtual void DisableFilter(float time) = 0; - virtual void Draw() const = 0; + virtual void Draw() = 0; }; template @@ -69,11 +69,11 @@ public: void Update(float dt) override; void SetFilter(EFilterType type, EFilterShape shape, float time, const zeus::CColor& color, CAssetId txtr) override; void DisableFilter(float time) override; - void Draw() const override; + void Draw() override; }; class CCameraFilterPassPoly { - EFilterShape m_shape; + EFilterShape m_shape{}; std::unique_ptr m_filter; public: @@ -107,8 +107,8 @@ class CCameraBlurPass { // bool x2d_noPersistentCopy = false; // u32 x30_persistentBuf = 0; - mutable std::optional m_shader; - mutable std::optional m_xrayShader; + std::optional m_shader; + std::optional m_xrayShader; public: void Draw(bool clearDepth = false); diff --git a/Runtime/Camera/CCameraManager.cpp b/Runtime/Camera/CCameraManager.cpp index e6db7b765..b73158140 100644 --- a/Runtime/Camera/CCameraManager.cpp +++ b/Runtime/Camera/CCameraManager.cpp @@ -71,10 +71,10 @@ void CCameraManager::EnterCinematic(CStateManager& mgr) { mgr.GetPlayer().GetPlayerGun()->CancelFiring(mgr); mgr.GetPlayer().UnFreeze(mgr); - for (CEntity* ent : mgr.GetAllObjectList()) { - if (TCastToPtr explo = ent) { + for (const CEntity* ent : mgr.GetAllObjectList()) { + if (const TCastToConstPtr explo = ent) { mgr.FreeScriptObject(explo->GetUniqueId()); - } else if (TCastToPtr weap = ent) { + } else if (const TCastToConstPtr weap = ent) { if (weap->GetActive()) { if (False(weap->GetAttribField() & EProjectileAttrib::KeepInCinematic)) { if (TCastToConstPtr(mgr.GetObjectById(weap->GetOwnerId())) || @@ -87,13 +87,16 @@ void CCameraManager::EnterCinematic(CStateManager& mgr) { } void CCameraManager::AddCinemaCamera(TUniqueId id, CStateManager& stateMgr) { - if (x4_cineCameras.empty()) + if (x4_cineCameras.empty()) { EnterCinematic(stateMgr); + } + RemoveCinemaCamera(id, stateMgr); x4_cineCameras.push_back(id); - if (TCastToPtr cam = stateMgr.ObjectById(id)) { - if (cam->GetFlags() & 0x4) // into player eye - { + + if (const TCastToPtr cam = stateMgr.ObjectById(id)) { + // Into player eye + if ((cam->GetFlags() & 0x4) != 0) { float time = 4.f; float delayTime = cam->GetDuration() - 4.f; if (delayTime < 0.f) { @@ -105,12 +108,13 @@ void CCameraManager::AddCinemaCamera(TUniqueId id, CStateManager& stateMgr) { } } -void CCameraManager::SetInsideFluid(bool val, TUniqueId fluidId) { - if (val) { +void CCameraManager::SetInsideFluid(bool isInside, TUniqueId fluidId) { + if (isInside) { ++x74_fluidCounter; x78_fluidId = fluidId; - } else + } else { --x74_fluidCounter; + } } void CCameraManager::Update(float dt, CStateManager& stateMgr) { @@ -149,8 +153,8 @@ void CCameraManager::CreateStandardCameras(CStateManager& stateMgr) { } void CCameraManager::SkipCinematic(CStateManager& stateMgr) { - TUniqueId camId = GetCurrentCameraId(); - CCinematicCamera* ent = static_cast(stateMgr.ObjectById(camId)); + const TUniqueId camId = GetCurrentCameraId(); + auto* ent = static_cast(stateMgr.ObjectById(camId)); while (ent) { ent->SetActive(false); ent->WasDeactivated(stateMgr); @@ -162,7 +166,7 @@ void CCameraManager::SkipCinematic(CStateManager& stateMgr) { void CCameraManager::SetPathCamera(TUniqueId id, CStateManager& mgr) { xa4_pathCamId = id; - if (TCastToPtr cam = mgr.ObjectById(id)) { + if (const TCastToPtr cam = mgr.ObjectById(id)) { cam->Reset(GetCurrentCameraTransform(mgr), mgr); x80_ballCamera->TeleportCamera(cam->GetTransform(), mgr); } @@ -170,7 +174,7 @@ void CCameraManager::SetPathCamera(TUniqueId id, CStateManager& mgr) { void CCameraManager::SetSpindleCamera(TUniqueId id, CStateManager& mgr) { xa2_spindleCamId = id; - if (TCastToPtr cam = mgr.ObjectById(id)) { + if (const TCastToPtr cam = mgr.ObjectById(id)) { cam->Reset(GetCurrentCameraTransform(mgr), mgr); x80_ballCamera->TeleportCamera(cam->GetTransform(), mgr); } @@ -187,32 +191,37 @@ void CCameraManager::InterpolateToBallCamera(const zeus::CTransform& xf, TUnique } void CCameraManager::RestoreHintlessCamera(CStateManager& mgr) { - TCastToPtr hint = mgr.ObjectById(xa6_camHintId); - zeus::CTransform ballCamXf = x80_ballCamera->GetTransform(); + const TCastToConstPtr hint = mgr.ObjectById(xa6_camHintId); + const zeus::CTransform ballCamXf = x80_ballCamera->GetTransform(); + xa6_camHintId = kInvalidUniqueId; xa8_hintPriority = 1000; - if (hint) { - zeus::CVector3f camToPlayerFlat = mgr.GetPlayer().GetTranslation() - ballCamXf.origin; - camToPlayerFlat.z() = 0.f; - if (camToPlayerFlat.canBeNormalized()) - camToPlayerFlat.normalize(); - else - camToPlayerFlat = mgr.GetPlayer().GetMoveDir(); - x80_ballCamera->ResetToTweaks(mgr); - x80_ballCamera->UpdateLookAtPosition(0.f, mgr); - if (!mgr.GetPlayer().IsMorphBallTransitioning() && - hint->GetHint().GetBehaviourType() != CBallCamera::EBallCameraBehaviour::Default) { - if ((hint->GetHint().GetOverrideFlags() & 0x1000) != 0) { - x80_ballCamera->SetClampVelRange(hint->GetHint().GetClampVelRange()); - x80_ballCamera->SetClampVelTimer(hint->GetHint().GetClampVelTime()); - } else { - x80_ballCamera->TeleportCamera(x80_ballCamera->UpdateLookDirection(camToPlayerFlat, mgr), mgr); - InterpolateToBallCamera(ballCamXf, x80_ballCamera->GetUniqueId(), x80_ballCamera->GetLookPos(), - hint->GetHint().GetClampVelTime(), hint->GetHint().GetClampVelRange(), - hint->GetHint().GetClampRotRange(), (hint->GetHint().GetOverrideFlags() & 0x800) != 0, - mgr); - } + if (!hint) { + return; + } + + zeus::CVector3f camToPlayerFlat = mgr.GetPlayer().GetTranslation() - ballCamXf.origin; + camToPlayerFlat.z() = 0.f; + if (camToPlayerFlat.canBeNormalized()) { + camToPlayerFlat.normalize(); + } else { + camToPlayerFlat = mgr.GetPlayer().GetMoveDir(); + } + + x80_ballCamera->ResetToTweaks(mgr); + x80_ballCamera->UpdateLookAtPosition(0.f, mgr); + if (!mgr.GetPlayer().IsMorphBallTransitioning() && + hint->GetHint().GetBehaviourType() != CBallCamera::EBallCameraBehaviour::Default) { + if ((hint->GetHint().GetOverrideFlags() & 0x1000) != 0) { + x80_ballCamera->SetClampVelRange(hint->GetHint().GetClampVelRange()); + x80_ballCamera->SetClampVelTimer(hint->GetHint().GetClampVelTime()); + } else { + x80_ballCamera->TeleportCamera(x80_ballCamera->UpdateLookDirection(camToPlayerFlat, mgr), mgr); + InterpolateToBallCamera(ballCamXf, x80_ballCamera->GetUniqueId(), x80_ballCamera->GetLookPos(), + hint->GetHint().GetClampVelTime(), hint->GetHint().GetClampVelRange(), + hint->GetHint().GetClampRotRange(), (hint->GetHint().GetOverrideFlags() & 0x800) != 0, + mgr); } } } @@ -232,15 +241,16 @@ void CCameraManager::ApplyCameraHint(const CScriptCameraHint& hint, CStateManage mgr.GetPlayer().SetCameraState(CPlayer::EPlayerCameraState::Ball, mgr); } - TCastToPtr oldHint = mgr.ObjectById(xa6_camHintId); + const TCastToConstPtr oldHint = mgr.ObjectById(xa6_camHintId); xa6_camHintId = hint.GetUniqueId(); xa8_hintPriority = hint.GetPriority(); - zeus::CTransform camXf = GetCurrentCameraTransform(mgr); + const zeus::CTransform camXf = GetCurrentCameraTransform(mgr); x80_ballCamera->ApplyCameraHint(mgr); - if ((hint.GetHint().GetOverrideFlags() & 0x20) != 0) + if ((hint.GetHint().GetOverrideFlags() & 0x20) != 0) { x80_ballCamera->ResetPosition(mgr); + } switch (hint.GetHint().GetBehaviourType()) { case CBallCamera::EBallCameraBehaviour::PathCameraDesiredPos: @@ -256,8 +266,9 @@ void CCameraManager::ApplyCameraHint(const CScriptCameraHint& hint, CStateManage break; } - if ((hint.GetHint().GetOverrideFlags() & 0x2000) != 0) + if ((hint.GetHint().GetOverrideFlags() & 0x2000) != 0) { SkipBallCameraCinematic(mgr); + } x80_ballCamera->UpdateLookAtPosition(0.f, mgr); @@ -273,7 +284,7 @@ void CCameraManager::ApplyCameraHint(const CScriptCameraHint& hint, CStateManage void CCameraManager::UpdateCameraHints(float, CStateManager& mgr) { bool invalidHintRemoved = false; for (auto it = xac_cameraHints.begin(); it != xac_cameraHints.end();) { - if (!TCastToPtr(mgr.ObjectById(it->second))) { + if (!TCastToConstPtr(mgr.ObjectById(it->second))) { invalidHintRemoved = true; it = xac_cameraHints.erase(it); continue; @@ -282,8 +293,8 @@ void CCameraManager::UpdateCameraHints(float, CStateManager& mgr) { } bool inactiveHintRemoved = false; - for (TUniqueId id : x2b0_inactiveCameraHints) { - if (TCastToConstPtr hint = mgr.GetObjectById(id)) { + for (const TUniqueId id : x2b0_inactiveCameraHints) { + if (const TCastToConstPtr hint = mgr.GetObjectById(id)) { if (hint->GetHelperCount() == 0 || hint->GetInactive()) { for (auto it = xac_cameraHints.begin(); it != xac_cameraHints.end(); ++it) { if (it->second == id) { @@ -302,8 +313,8 @@ void CCameraManager::UpdateCameraHints(float, CStateManager& mgr) { x2b0_inactiveCameraHints.clear(); bool activeHintAdded = false; - for (TUniqueId id : x334_activeCameraHints) { - if (TCastToConstPtr hint = mgr.GetObjectById(id)) { + for (const TUniqueId id : x334_activeCameraHints) { + if (const TCastToConstPtr hint = mgr.GetObjectById(id)) { bool activeHintPresent = false; for (auto it = xac_cameraHints.begin(); it != xac_cameraHints.end(); ++it) { if (it->second == id) { @@ -329,16 +340,17 @@ void CCameraManager::UpdateCameraHints(float, CStateManager& mgr) { return; } bool foundHint = false; - CScriptCameraHint* bestHint = nullptr; + const CScriptCameraHint* bestHint = nullptr; for (auto& h : xac_cameraHints) { - if (TCastToPtr hint = mgr.ObjectById(h.second)) { + if (const TCastToConstPtr hint = mgr.ObjectById(h.second)) { bestHint = hint.GetPtr(); foundHint = true; break; } } - if (!foundHint) + if (!foundHint) { RestoreHintlessCamera(mgr); + } bool changeHint = false; if (bestHint && foundHint) { @@ -346,33 +358,37 @@ void CCameraManager::UpdateCameraHints(float, CStateManager& mgr) { zeus::CVector3f ballPos = mgr.GetPlayer().GetBallPosition(); if ((bestHint->GetHint().GetOverrideFlags() & 0x100) != 0) { zeus::CVector3f camToBall = ballPos - ballCamXf.origin; - if (camToBall.canBeNormalized()) + if (camToBall.canBeNormalized()) { camToBall.normalize(); - else + } else { camToBall = ballCamXf.basis[1]; + } for (auto it = xac_cameraHints.begin() + 1; it != xac_cameraHints.end(); ++it) { - if (TCastToPtr hint = mgr.ObjectById(it->second)) { + if (const TCastToConstPtr hint = mgr.ObjectById(it->second)) { if ((hint->GetHint().GetOverrideFlags() & 0x80) != 0 && hint->GetPriority() == bestHint->GetPriority() && hint->GetAreaIdAlways() == bestHint->GetAreaIdAlways()) { zeus::CVector3f hintToBall = ballPos - bestHint->GetTranslation(); - if (hintToBall.canBeNormalized()) + if (hintToBall.canBeNormalized()) { hintToBall.normalize(); - else + } else { hintToBall = bestHint->GetTransform().basis[1]; + } - float camHintDot = zeus::clamp(-1.f, camToBall.dot(hintToBall), 1.f); + const float camHintDot = zeus::clamp(-1.f, camToBall.dot(hintToBall), 1.f); zeus::CVector3f thisHintToBall = ballPos - hint->GetTranslation(); - if (thisHintToBall.canBeNormalized()) + if (thisHintToBall.canBeNormalized()) { thisHintToBall.normalize(); - else + } else { thisHintToBall = hint->GetTransform().basis[1]; + } - float camThisHintDot = zeus::clamp(-1.f, camToBall.dot(thisHintToBall), 1.f); + const float camThisHintDot = zeus::clamp(-1.f, camToBall.dot(thisHintToBall), 1.f); - if (camThisHintDot > camHintDot) + if (camThisHintDot > camHintDot) { bestHint = hint.GetPtr(); + } } else { break; } @@ -381,44 +397,49 @@ void CCameraManager::UpdateCameraHints(float, CStateManager& mgr) { } } } else { - if (TCastToConstPtr act = mgr.GetObjectById(bestHint->GetFirstHelper())) { + if (const TCastToConstPtr act = mgr.GetObjectById(bestHint->GetFirstHelper())) { zeus::CVector3f ballPos = mgr.GetPlayer().GetBallPosition(); zeus::CVector3f f26 = act->GetTranslation() - ballPos; zeus::CVector3f ballToHelper = f26; - if (ballToHelper.canBeNormalized()) + if (ballToHelper.canBeNormalized()) { ballToHelper.normalize(); - else + } else { ballToHelper = bestHint->GetTransform().basis[1]; + } for (auto it = xac_cameraHints.begin() + 1; it != xac_cameraHints.end(); ++it) { - if (TCastToPtr hint = mgr.ObjectById(it->second)) { + if (const TCastToConstPtr hint = mgr.ObjectById(it->second)) { if ((hint->GetHint().GetOverrideFlags() & 0x80) != 0 && hint->GetPriority() == bestHint->GetPriority() && hint->GetAreaIdAlways() == bestHint->GetAreaIdAlways()) { zeus::CVector3f hintToHelper = act->GetTranslation() - bestHint->GetTranslation(); - if (hintToHelper.canBeNormalized()) + if (hintToHelper.canBeNormalized()) { hintToHelper.normalize(); - else + } else { hintToHelper = bestHint->GetTransform().basis[1]; + } - float ballHintDot = zeus::clamp(-1.f, ballToHelper.dot(hintToHelper), 1.f); + const float ballHintDot = zeus::clamp(-1.f, ballToHelper.dot(hintToHelper), 1.f); zeus::CVector3f thisBallToHelper = f26; - if (thisBallToHelper.canBeNormalized()) + if (thisBallToHelper.canBeNormalized()) { thisBallToHelper.normalize(); - else + } else { thisBallToHelper = hint->GetTransform().basis[1]; + } zeus::CVector3f thisHintToHelper = act->GetTranslation() - hint->GetTranslation(); - if (thisHintToHelper.canBeNormalized()) + if (thisHintToHelper.canBeNormalized()) { thisHintToHelper.normalize(); - else + } else { thisHintToHelper = hint->GetTransform().basis[1]; + } - float thisBallHintDot = zeus::clamp(-1.f, thisBallToHelper.dot(thisHintToHelper), 1.f); + const float thisBallHintDot = zeus::clamp(-1.f, thisBallToHelper.dot(thisHintToHelper), 1.f); - if (thisBallHintDot > ballHintDot) + if (thisBallHintDot > ballHintDot) { bestHint = hint.GetPtr(); + } } else { break; } @@ -429,24 +450,27 @@ void CCameraManager::UpdateCameraHints(float, CStateManager& mgr) { } } - if (bestHint->GetUniqueId() != xa6_camHintId) + if (bestHint->GetUniqueId() != xa6_camHintId) { changeHint = true; + } } else if (xa6_camHintId != bestHint->GetUniqueId()) { if (bestHint->GetHint().GetBehaviourType() == CBallCamera::EBallCameraBehaviour::HintInitializePosition) { if ((bestHint->GetHint().GetOverrideFlags() & 0x20) != 0) { x80_ballCamera->TeleportCamera(zeus::lookAt(bestHint->GetTranslation(), x80_ballCamera->GetLookPos()), mgr); } DeleteCameraHint(bestHint->GetUniqueId(), mgr); - if ((bestHint->GetHint().GetOverrideFlags() & 0x2000) != 0) + if ((bestHint->GetHint().GetOverrideFlags() & 0x2000) != 0) { SkipBallCameraCinematic(mgr); + } changeHint = false; } else { changeHint = true; } } - if (changeHint) + if (changeHint) { ApplyCameraHint(*bestHint, mgr); + } } } } @@ -455,18 +479,20 @@ void CCameraManager::ThinkCameras(float dt, CStateManager& mgr) { CGameCameraList gcList = mgr.GetCameraObjectList(); for (CEntity* ent : gcList) { - if (TCastToPtr gc = ent) { + if (const TCastToPtr gc = ent) { gc->Think(dt, mgr); gc->UpdatePerspective(dt); } } - if (IsInCinematicCamera()) + if (IsInCinematicCamera()) { return; + } - TUniqueId camId = GetLastCameraId(); - if (const CGameCamera* cam = TCastToConstPtr(mgr.GetObjectById(camId))) + const TUniqueId camId = GetLastCameraId(); + if (const CGameCamera* cam = TCastToConstPtr(mgr.GetObjectById(camId))) { x3bc_curFov = cam->GetFov(); + } } void CCameraManager::UpdateFog(float dt, CStateManager& mgr) { @@ -480,14 +506,16 @@ void CCameraManager::UpdateFog(float dt, CStateManager& mgr) { } if (x74_fluidCounter) { - if (TCastToConstPtr water = mgr.GetObjectById(x78_fluidId)) { - zeus::CVector2f zRange(GetCurrentCamera(mgr)->GetNearClipDistance(), CalculateFogDensity(mgr, water.GetPtr())); + if (const TCastToConstPtr water = mgr.GetObjectById(x78_fluidId)) { + const zeus::CVector2f zRange(GetCurrentCamera(mgr)->GetNearClipDistance(), + CalculateFogDensity(mgr, water.GetPtr())); x3c_fog.SetFogExplicit(ERglFogMode::PerspExp, water->GetInsideFogColor(), zRange); - if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal) + if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal) { mgr.GetCameraFilterPass(4).DisableFilter(0.f); - else + } else { mgr.GetCameraFilterPass(4).SetFilter(EFilterType::Multiply, EFilterShape::Fullscreen, 0.f, water->GetInsideFogColor(), {}); + } } xa0_26_inWater = true; } else if (xa0_26_inWater) { @@ -524,8 +552,9 @@ void CCameraManager::UpdateRumble(float dt, CStateManager& mgr) { xa0_25_rumbling = false; } - if (mgr.GetPlayer().GetCameraState() != CPlayer::EPlayerCameraState::FirstPerson && !IsInCinematicCamera()) + if (mgr.GetPlayer().GetCameraState() != CPlayer::EPlayerCameraState::FirstPerson && !IsInCinematicCamera()) { x30_shakeOffset = zeus::skZero3f; + } } void CCameraManager::UpdateListener(CStateManager& mgr) { @@ -534,13 +563,14 @@ void CCameraManager::UpdateListener(CStateManager& mgr) { } float CCameraManager::CalculateFogDensity(CStateManager& mgr, const CScriptWater* water) const { - float distanceFactor = 1.f - water->GetFluidPlane().GetAlpha(); + const float distanceFactor = 1.f - water->GetFluidPlane().GetAlpha(); float distance = 0; - if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit)) + if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit)) { distance = g_tweakGame->GetGravityWaterFogDistanceRange() * distanceFactor + g_tweakGame->GetGravityWaterFogDistanceBase(); - else + } else { distance = g_tweakGame->GetWaterFogDistanceRange() * distanceFactor + g_tweakGame->GetWaterFogDistanceBase(); + } return distance * x94_fogDensityFactor; } @@ -550,7 +580,7 @@ void CCameraManager::ResetCameras(CStateManager& mgr) { xf.origin = mgr.GetPlayer().GetEyePosition(); for (CEntity* ent : mgr.GetCameraObjectList()) { - TCastToPtr camObj(ent); + const TCastToPtr camObj(ent); camObj->Reset(xf, mgr); } } @@ -562,25 +592,29 @@ void CCameraManager::SetSpecialCameras(CFirstPersonCamera& fp, CBallCamera& ball void CCameraManager::ProcessInput(const CFinalInput& input, CStateManager& stateMgr) { for (CEntity* ent : stateMgr.GetCameraObjectList()) { - if (ent == nullptr) + if (ent == nullptr) { continue; + } auto& cam = static_cast(*ent); - if (input.ControllerIdx() != cam.x16c_controllerIdx) + if (input.ControllerIdx() != cam.x16c_controllerIdx) { continue; + } cam.ProcessInput(input, stateMgr); } } -void CCameraManager::RenderCameras(const CStateManager& mgr) { - for (CEntity* cam : mgr.GetCameraObjectList()) +void CCameraManager::RenderCameras(CStateManager& mgr) { + for (CEntity* cam : mgr.GetCameraObjectList()) { static_cast(cam)->Render(mgr); + } } void CCameraManager::SetupBallCamera(CStateManager& mgr) { - if (TCastToPtr hint = mgr.ObjectById(xa6_camHintId)) { + if (const TCastToConstPtr hint = mgr.ObjectById(xa6_camHintId)) { if (hint->GetHint().GetBehaviourType() == CBallCamera::EBallCameraBehaviour::HintInitializePosition) { - if ((hint->GetHint().GetOverrideFlags() & 0x20) != 0) + if ((hint->GetHint().GetOverrideFlags() & 0x20) != 0) { x80_ballCamera->TeleportCamera(hint->GetTransform(), mgr); + } AddInactiveCameraHint(xa6_camHintId, mgr); } else { ApplyCameraHint(*hint, mgr); @@ -622,45 +656,60 @@ bool CCameraManager::HasBallCameraInitialPositionHint(CStateManager& mgr) const } void CCameraManager::RemoveCinemaCamera(TUniqueId uid, CStateManager& mgr) { - auto search = std::find(x4_cineCameras.begin(), x4_cineCameras.end(), uid); - if (search != x4_cineCameras.end()) - x4_cineCameras.erase(search); + const auto search = std::find(x4_cineCameras.cbegin(), x4_cineCameras.cend(), uid); + + if (search == x4_cineCameras.cend()) { + return; + } + + x4_cineCameras.erase(search); } void CCameraManager::DeleteCameraHint(TUniqueId id, CStateManager& mgr) { - if (TCastToPtr hint = mgr.ObjectById(id)) { - auto search = std::find_if(x2b0_inactiveCameraHints.begin(), x2b0_inactiveCameraHints.end(), - [id](TUniqueId tid) { return tid == id; }); - if (search == x2b0_inactiveCameraHints.end()) { - hint->ClearIdList(); - hint->SetInactive(true); - if (x2b0_inactiveCameraHints.size() != 64) - x2b0_inactiveCameraHints.push_back(id); - } + const TCastToPtr hint = mgr.ObjectById(id); + + if (!hint) { + return; + } + + const auto search = std::find_if(x2b0_inactiveCameraHints.cbegin(), x2b0_inactiveCameraHints.cend(), + [id](TUniqueId tid) { return tid == id; }); + + if (search != x2b0_inactiveCameraHints.cend()) { + return; + } + + hint->ClearIdList(); + hint->SetInactive(true); + if (x2b0_inactiveCameraHints.size() != 64) { + x2b0_inactiveCameraHints.push_back(id); } } void CCameraManager::AddInactiveCameraHint(TUniqueId id, CStateManager& mgr) { - if (TCastToPtr hint = mgr.ObjectById(id)) { - auto search = std::find_if(x2b0_inactiveCameraHints.begin(), x2b0_inactiveCameraHints.end(), - [id](TUniqueId tid) { return tid == id; }); - if (search == x2b0_inactiveCameraHints.end() && x2b0_inactiveCameraHints.size() != 64) + if (const TCastToConstPtr hint = mgr.ObjectById(id)) { + const auto search = std::find_if(x2b0_inactiveCameraHints.cbegin(), x2b0_inactiveCameraHints.cend(), + [id](TUniqueId tid) { return tid == id; }); + if (search == x2b0_inactiveCameraHints.cend() && x2b0_inactiveCameraHints.size() != 64) { x2b0_inactiveCameraHints.push_back(id); + } } } void CCameraManager::AddActiveCameraHint(TUniqueId id, CStateManager& mgr) { - if (TCastToPtr hint = mgr.ObjectById(id)) { - auto search = std::find_if(x334_activeCameraHints.begin(), x334_activeCameraHints.end(), - [id](TUniqueId tid) { return tid == id; }); - if (search == x334_activeCameraHints.end() && xac_cameraHints.size() != 64 && x334_activeCameraHints.size() != 64) + if (const TCastToConstPtr hint = mgr.ObjectById(id)) { + const auto search = std::find_if(x334_activeCameraHints.cbegin(), x334_activeCameraHints.cend(), + [id](TUniqueId tid) { return tid == id; }); + if (search == x334_activeCameraHints.cend() && xac_cameraHints.size() != 64 && x334_activeCameraHints.size() != 64) { x334_activeCameraHints.push_back(id); + } } } TUniqueId CCameraManager::GetLastCineCameraId() const { - if (x4_cineCameras.empty()) + if (x4_cineCameras.empty()) { return kInvalidUniqueId; + } return x4_cineCameras.back(); } diff --git a/Runtime/Camera/CCameraManager.hpp b/Runtime/Camera/CCameraManager.hpp index 365a0742a..7268b6bf8 100644 --- a/Runtime/Camera/CCameraManager.hpp +++ b/Runtime/Camera/CCameraManager.hpp @@ -80,7 +80,7 @@ class CCameraManager { void EnterCinematic(CStateManager& mgr); public: - CCameraManager(TUniqueId curCameraId = kInvalidUniqueId); + explicit CCameraManager(TUniqueId curCameraId = kInvalidUniqueId); static float Aspect() { return 1.42f; } static float FarPlane() { return 750.0f; } @@ -96,9 +96,9 @@ public: zeus::CTransform GetCurrentCameraTransform(const CStateManager& stateMgr) const; void RemoveCameraShaker(u32 id); int AddCameraShaker(const CCameraShakeData& data, bool sfx); - void AddCinemaCamera(TUniqueId, CStateManager& stateMgr); - void RemoveCinemaCamera(TUniqueId, CStateManager&); - void SetInsideFluid(bool, TUniqueId); + void AddCinemaCamera(TUniqueId id, CStateManager& stateMgr); + void RemoveCinemaCamera(TUniqueId uid, CStateManager& mgr); + void SetInsideFluid(bool isInside, TUniqueId fluidId); void Update(float dt, CStateManager& stateMgr); CGameCamera* GetCurrentCamera(CStateManager& stateMgr) const; const CGameCamera* GetCurrentCamera(const CStateManager& stateMgr) const; @@ -134,12 +134,12 @@ public: void UpdateRumble(float dt, CStateManager& mgr); void UpdateListener(CStateManager& mgr); - float CalculateFogDensity(CStateManager&, const CScriptWater*) const; - void SetFogDensity(float, float); + float CalculateFogDensity(CStateManager& mgr, const CScriptWater* water) const; + void SetFogDensity(float fogDensityTarget, float fogDensitySpeed); void ProcessInput(const CFinalInput& input, CStateManager& stateMgr); - void RenderCameras(const CStateManager& mgr); + void RenderCameras(CStateManager& mgr); void SetupBallCamera(CStateManager& mgr); void SetPlayerCamera(CStateManager& mgr, TUniqueId newCamId); int GetFluidCounter() const { return x74_fluidCounter; } diff --git a/Runtime/Camera/CCameraShakeData.cpp b/Runtime/Camera/CCameraShakeData.cpp index 9e2ded6f0..6de888378 100644 --- a/Runtime/Camera/CCameraShakeData.cpp +++ b/Runtime/Camera/CCameraShakeData.cpp @@ -27,22 +27,6 @@ CCameraShakerComponent CCameraShakerComponent::LoadNewCameraShakerComponent(CInp return {useModulation != 0, am, fm}; } -CCameraShakeData::CCameraShakeData(float duration, float sfxDist, u32 flags, const zeus::CVector3f& sfxPos, - const CCameraShakerComponent& shaker1, const CCameraShakerComponent& shaker2, - const CCameraShakerComponent& shaker3) -: x0_duration(duration) -, x8_shakerX(shaker1) -, x44_shakerY(shaker2) -, x80_shakerZ(shaker3) -, xc0_flags(flags) -, xc4_sfxPos(sfxPos) -, xd0_sfxDist(sfxDist) {} - -CCameraShakeData::CCameraShakeData(float duration, float magnitude) -: CCameraShakeData(duration, 100.f, 0, zeus::skZero3f, CCameraShakerComponent{}, CCameraShakerComponent{}, - CCameraShakerComponent{1, SCameraShakePoint{0, 0.25f * duration, 0.f, 0.75f * duration, magnitude}, - SCameraShakePoint{1, 0.f, 0.f, 0.5f * duration, 2.f}}) {} - CCameraShakeData::CCameraShakeData(CInputStream& in) { in.readUint32Big(); in.readFloatBig(); @@ -56,66 +40,6 @@ CCameraShakeData::CCameraShakeData(CInputStream& in) { BuildProjectileCameraShake(0.5f, 0.75f); } -CCameraShakeData CCameraShakeData::BuildLandingCameraShakeData(float duration, float magnitude) { - return {duration, - 100.f, - 0, - zeus::skZero3f, - CCameraShakerComponent(1, SCameraShakePoint(0, 0.15f * duration, 0.f, 0.85f * duration, magnitude), - SCameraShakePoint(1, 0.f, 0.f, 0.4f * duration, 1.5f)), - CCameraShakerComponent(), - CCameraShakerComponent(1, SCameraShakePoint(0, 0.25f * duration, 0.f, 0.75f * duration, magnitude), - SCameraShakePoint(1, 0.f, 0.f, 0.5f * duration, 2.f))}; -} - -CCameraShakeData CCameraShakeData::BuildProjectileCameraShake(float duration, float magnitude) { - return {duration, - 100.f, - 0, - zeus::skZero3f, - CCameraShakerComponent(1, SCameraShakePoint(0, 0.f, 0.f, duration, magnitude), - SCameraShakePoint(1, 0.f, 0.f, 0.5f * duration, 3.f)), - CCameraShakerComponent(), - CCameraShakerComponent()}; -} - -CCameraShakeData CCameraShakeData::BuildMissileCameraShake(float duration, float magnitude, float sfxDistance, - const zeus::CVector3f& sfxPos) { - CCameraShakeData ret(duration, magnitude); - ret.SetSfxPositionAndDistance(sfxPos, sfxDistance); - return ret; -} - -CCameraShakeData CCameraShakeData::BuildPhazonCameraShakeData(float duration, float magnitude) { - return {duration, - 100.f, - 0, - zeus::skZero3f, - CCameraShakerComponent(1, SCameraShakePoint(0, 0.15f * duration, 0.f, 0.25f * duration, magnitude), - SCameraShakePoint(1, 0.f, 0.f, 0.4f * duration, 0.3f)), - CCameraShakerComponent(), - CCameraShakerComponent(1, SCameraShakePoint(0, 0.25f * duration, 0.f, 0.25f * duration, magnitude), - SCameraShakePoint(1, 0.f, 0.f, 0.5f * duration, 0.5f))}; -} - -CCameraShakeData CCameraShakeData::BuildPatternedExplodeShakeData(float duration, float magnitude) { - return {duration, - 100.f, - 0, - zeus::skZero3f, - CCameraShakerComponent(1, SCameraShakePoint(0, 0.25f * duration, 0.f, 0.75f * duration, magnitude), - SCameraShakePoint(1, 0.f, 0.f, 0.5f * duration, 2.0f)), - CCameraShakerComponent(), - CCameraShakerComponent()}; -} - -CCameraShakeData CCameraShakeData::BuildPatternedExplodeShakeData(const zeus::CVector3f& pos, float duration, - float magnitude, float distance) { - CCameraShakeData shakeData = CCameraShakeData::BuildPatternedExplodeShakeData(duration, magnitude); - shakeData.SetSfxPositionAndDistance(pos, distance); - return shakeData; -} - void SCameraShakePoint::Update(float curTime) { float offTimePoint = xc_attackTime + x10_sustainTime; float factor = 1.f; @@ -198,13 +122,18 @@ CCameraShakeData CCameraShakeData::LoadCameraShakeData(CInputStream& in) { return {duration, 100.f, 0, zeus::skZero3f, shakerX, shakerY, shakerZ}; } -const CCameraShakeData CCameraShakeData::skChargedShotCameraShakeData = { +const CCameraShakeData CCameraShakeData::skChargedShotCameraShakeData{ 0.3f, 100.f, 0, zeus::skZero3f, - CCameraShakerComponent(), - CCameraShakerComponent(1, {0, 0.f, 0.f, 0.3f, -1.f}, {1, 0.f, 0.f, 0.05f, 0.3f}), - CCameraShakerComponent()}; + CCameraShakerComponent{}, + CCameraShakerComponent{ + true, + {false, 0.f, 0.f, 0.3f, -1.f}, + {true, 0.f, 0.f, 0.05f, 0.3f}, + }, + CCameraShakerComponent{}, +}; } // namespace urde diff --git a/Runtime/Camera/CCameraShakeData.hpp b/Runtime/Camera/CCameraShakeData.hpp index e425fa913..7e9ebd2e8 100644 --- a/Runtime/Camera/CCameraShakeData.hpp +++ b/Runtime/Camera/CCameraShakeData.hpp @@ -16,14 +16,15 @@ struct SCameraShakePoint { float xc_attackTime = 0.f; float x10_sustainTime = 0.f; float x14_duration = 0.f; - SCameraShakePoint() = default; - SCameraShakePoint(bool useEnvelope, float attackTime, float sustainTime, float duration, float magnitude) + constexpr SCameraShakePoint() noexcept = default; + constexpr SCameraShakePoint(bool useEnvelope, float attackTime, float sustainTime, float duration, + float magnitude) noexcept : x0_useEnvelope(useEnvelope) , x8_magnitude(magnitude) , xc_attackTime(attackTime) , x10_sustainTime(sustainTime) , x14_duration(duration) {} - float GetValue() const { return x0_useEnvelope ? x8_magnitude : x4_value; } + [[nodiscard]] constexpr float GetValue() const noexcept { return x0_useEnvelope ? x8_magnitude : x4_value; } static SCameraShakePoint LoadCameraShakePoint(CInputStream& in); void Update(float curTime); }; @@ -35,12 +36,13 @@ class CCameraShakerComponent { float x38_value = 0.f; public: - CCameraShakerComponent() = default; - CCameraShakerComponent(bool useModulation, const SCameraShakePoint& am, const SCameraShakePoint& fm) + constexpr CCameraShakerComponent() noexcept = default; + constexpr CCameraShakerComponent(bool useModulation, const SCameraShakePoint& am, + const SCameraShakePoint& fm) noexcept : x4_useModulation(useModulation), x8_am(am), x20_fm(fm) {} static CCameraShakerComponent LoadNewCameraShakerComponent(CInputStream& in); void Update(float curTime, float duration, float distAtt); - float GetValue() const { return x38_value; } + [[nodiscard]] constexpr float GetValue() const noexcept { return x38_value; } }; class CCameraShakeData { @@ -57,19 +59,112 @@ class CCameraShakeData { public: static const CCameraShakeData skChargedShotCameraShakeData; - CCameraShakeData(float duration, float sfxDist, u32 flags, const zeus::CVector3f& sfxPos, - const CCameraShakerComponent& shaker1, const CCameraShakerComponent& shaker2, - const CCameraShakerComponent& shaker3); - CCameraShakeData(float duration, float magnitude); - CCameraShakeData(CInputStream&); - static CCameraShakeData BuildLandingCameraShakeData(float duration, float magnitude); - static CCameraShakeData BuildProjectileCameraShake(float duration, float magnitude); - static CCameraShakeData BuildMissileCameraShake(float duration, float magnitude, float sfxDistance, - const zeus::CVector3f& sfxPos); - static CCameraShakeData BuildPhazonCameraShakeData(float duration, float magnitude); - static CCameraShakeData BuildPatternedExplodeShakeData(float duration, float magnitude); - static CCameraShakeData BuildPatternedExplodeShakeData(const zeus::CVector3f& pos, float duration, float magnitude, - float distance); + + constexpr CCameraShakeData(float duration, float sfxDist, u32 flags, const zeus::CVector3f& sfxPos, + const CCameraShakerComponent& shaker1, const CCameraShakerComponent& shaker2, + const CCameraShakerComponent& shaker3) noexcept + : x0_duration(duration) + , x8_shakerX(shaker1) + , x44_shakerY(shaker2) + , x80_shakerZ(shaker3) + , xc0_flags(flags) + , xc4_sfxPos(sfxPos) + , xd0_sfxDist(sfxDist) {} + + constexpr CCameraShakeData(float duration, float magnitude) noexcept + : CCameraShakeData( + duration, 100.f, 0, zeus::skZero3f, CCameraShakerComponent{}, CCameraShakerComponent{}, + CCameraShakerComponent{true, SCameraShakePoint{false, 0.25f * duration, 0.f, 0.75f * duration, magnitude}, + SCameraShakePoint{true, 0.f, 0.f, 0.5f * duration, 2.f}}) {} + + explicit CCameraShakeData(CInputStream&); + + static constexpr CCameraShakeData BuildLandingCameraShakeData(float duration, float magnitude) noexcept { + return { + duration, + 100.f, + 0, + zeus::skZero3f, + CCameraShakerComponent{ + true, + SCameraShakePoint(false, 0.15f * duration, 0.f, 0.85f * duration, magnitude), + SCameraShakePoint(true, 0.f, 0.f, 0.4f * duration, 1.5f), + }, + CCameraShakerComponent{}, + CCameraShakerComponent{ + true, + SCameraShakePoint(false, 0.25f * duration, 0.f, 0.75f * duration, magnitude), + SCameraShakePoint(true, 0.f, 0.f, 0.5f * duration, 2.f), + }, + }; + } + + static constexpr CCameraShakeData BuildProjectileCameraShake(float duration, float magnitude) noexcept { + return { + duration, + 100.f, + 0, + zeus::skZero3f, + CCameraShakerComponent{ + true, + SCameraShakePoint(false, 0.f, 0.f, duration, magnitude), + SCameraShakePoint(true, 0.f, 0.f, 0.5f * duration, 3.f), + }, + CCameraShakerComponent{}, + CCameraShakerComponent{}, + }; + } + + static constexpr CCameraShakeData BuildMissileCameraShake(float duration, float magnitude, float sfxDistance, + const zeus::CVector3f& sfxPos) noexcept { + CCameraShakeData ret(duration, magnitude); + ret.SetSfxPositionAndDistance(sfxPos, sfxDistance); + return ret; + } + + static constexpr CCameraShakeData BuildPhazonCameraShakeData(float duration, float magnitude) noexcept { + return { + duration, + 100.f, + 0, + zeus::skZero3f, + CCameraShakerComponent{ + true, + SCameraShakePoint(false, 0.15f * duration, 0.f, 0.25f * duration, magnitude), + SCameraShakePoint(true, 0.f, 0.f, 0.4f * duration, 0.3f), + }, + CCameraShakerComponent{}, + CCameraShakerComponent{ + true, + SCameraShakePoint(false, 0.25f * duration, 0.f, 0.25f * duration, magnitude), + SCameraShakePoint(true, 0.f, 0.f, 0.5f * duration, 0.5f), + }, + }; + } + + static constexpr CCameraShakeData BuildPatternedExplodeShakeData(float duration, float magnitude) noexcept { + return { + duration, + 100.f, + 0, + zeus::skZero3f, + CCameraShakerComponent{ + true, + SCameraShakePoint(false, 0.25f * duration, 0.f, 0.75f * duration, magnitude), + SCameraShakePoint(true, 0.f, 0.f, 0.5f * duration, 2.0f), + }, + CCameraShakerComponent{}, + CCameraShakerComponent{}, + }; + } + + static constexpr CCameraShakeData BuildPatternedExplodeShakeData(const zeus::CVector3f& pos, float duration, + float magnitude, float distance) noexcept { + CCameraShakeData shakeData = BuildPatternedExplodeShakeData(duration, magnitude); + shakeData.SetSfxPositionAndDistance(pos, distance); + return shakeData; + } + void Update(float dt, CStateManager& mgr); zeus::CVector3f GetPoint() const; float GetMaxAMComponent() const; @@ -77,10 +172,10 @@ public: void SetShakerId(u32 id) { xbc_shakerId = id; } u32 GetShakerId() const { return xbc_shakerId; } static CCameraShakeData LoadCameraShakeData(CInputStream& in); - void SetSfxPositionAndDistance(const zeus::CVector3f& pos, float f2) { + constexpr void SetSfxPositionAndDistance(const zeus::CVector3f& pos, float sfxDistance) noexcept { xc0_flags |= 0x1; xc4_sfxPos = pos; - xd0_sfxDist = f2; + xd0_sfxDist = sfxDistance; } }; diff --git a/Runtime/Camera/CCameraSpline.cpp b/Runtime/Camera/CCameraSpline.cpp index 310056762..3079feb64 100644 --- a/Runtime/Camera/CCameraSpline.cpp +++ b/Runtime/Camera/CCameraSpline.cpp @@ -18,13 +18,13 @@ void CCameraSpline::CalculateKnots(TUniqueId cameraId, const std::vector waypoint = mgr.ObjectById(mgr.GetIdForScript(lastConn->x8_objId)); + TCastToConstPtr waypoint = mgr.ObjectById(mgr.GetIdForScript(lastConn->x8_objId)); x14_wpTracker.clear(); x14_wpTracker.reserve(4); while (waypoint) { - auto search = std::find_if(x14_wpTracker.begin(), x14_wpTracker.end(), - [&waypoint](const auto& a) { return a == waypoint->GetUniqueId(); }); - if (search == x14_wpTracker.end()) { + const auto search = std::find_if(x14_wpTracker.cbegin(), x14_wpTracker.cend(), + [&waypoint](const auto& a) { return a == waypoint->GetUniqueId(); }); + if (search == x14_wpTracker.cend()) { x14_wpTracker.push_back(waypoint->GetUniqueId()); waypoint = mgr.ObjectById(waypoint->GetRandomNextWaypointId(mgr)); } @@ -34,9 +34,9 @@ void CCameraSpline::CalculateKnots(TUniqueId cameraId, const std::vectorx8_objId)); while (waypoint) { - auto search = std::find_if(x14_wpTracker.begin(), x14_wpTracker.end(), - [&waypoint](const auto& a) { return a == waypoint->GetUniqueId(); }); - if (search == x14_wpTracker.end()) { + const auto search = std::find_if(x14_wpTracker.cbegin(), x14_wpTracker.cend(), + [&waypoint](const auto& a) { return a == waypoint->GetUniqueId(); }); + if (search == x14_wpTracker.cend()) { x14_wpTracker.push_back(waypoint->GetUniqueId()); AddKnot(waypoint->GetTranslation(), waypoint->GetTransform().basis[1]); waypoint = mgr.ObjectById(waypoint->GetRandomNextWaypointId(mgr)); @@ -45,20 +45,23 @@ void CCameraSpline::CalculateKnots(TUniqueId cameraId, const std::vector& connections, CStateManager& mgr) { - CalculateKnots(camId, connections, mgr); +void CCameraSpline::Initialize(TUniqueId cameraId, const std::vector& connections, CStateManager& mgr) { + CalculateKnots(cameraId, connections, mgr); x44_length = CalculateSplineLength(); } -void CCameraSpline::Reset(int size) { +void CCameraSpline::Reset(size_t size) { x4_positions.clear(); x24_t.clear(); x34_directions.clear(); - if (size != 0) { - x4_positions.reserve(size); - x24_t.reserve(size); - x34_directions.reserve(size); + + if (size == 0) { + return; } + + x4_positions.reserve(size); + x24_t.reserve(size); + x34_directions.reserve(size); } void CCameraSpline::AddKnot(const zeus::CVector3f& pos, const zeus::CVector3f& dir) { @@ -66,21 +69,24 @@ void CCameraSpline::AddKnot(const zeus::CVector3f& pos, const zeus::CVector3f& d x34_directions.push_back(dir); } -void CCameraSpline::SetKnotPosition(int idx, const zeus::CVector3f& pos) { - if (idx >= x4_positions.size()) +void CCameraSpline::SetKnotPosition(size_t idx, const zeus::CVector3f& pos) { + if (idx >= x4_positions.size()) { return; + } x4_positions[idx] = pos; } -const zeus::CVector3f& CCameraSpline::GetKnotPosition(int idx) const { - if (idx >= x4_positions.size()) +const zeus::CVector3f& CCameraSpline::GetKnotPosition(size_t idx) const { + if (idx >= x4_positions.size()) { return zeus::skZero3f; + } return x4_positions[idx]; } -float CCameraSpline::GetKnotT(int idx) const { - if (idx >= x4_positions.size()) +float CCameraSpline::GetKnotT(size_t idx) const { + if (idx >= x4_positions.size()) { return 0.f; + } return x24_t[idx]; } @@ -117,10 +123,11 @@ float CCameraSpline::CalculateSplineLength() { return 0.f; } -bool CCameraSpline::GetSurroundingPoints(int idx, rstl::reserved_vector& positions, +bool CCameraSpline::GetSurroundingPoints(size_t idx, rstl::reserved_vector& positions, rstl::reserved_vector& directions) const { - if (x4_positions.size() <= 3 || idx < 0 || idx >= x4_positions.size()) + if (x4_positions.size() <= 3 || idx < 0 || idx >= x4_positions.size()) { return false; + } if (idx > 0) { positions.push_back(x4_positions[idx - 1]); diff --git a/Runtime/Camera/CCameraSpline.hpp b/Runtime/Camera/CCameraSpline.hpp index 400d063bc..7dd48aece 100644 --- a/Runtime/Camera/CCameraSpline.hpp +++ b/Runtime/Camera/CCameraSpline.hpp @@ -15,18 +15,18 @@ class CCameraSpline { std::vector x34_directions; float x44_length = 0.f; bool x48_closedLoop = false; - bool GetSurroundingPoints(int idx, rstl::reserved_vector& positions, + bool GetSurroundingPoints(size_t idx, rstl::reserved_vector& positions, rstl::reserved_vector& directions) const; public: - CCameraSpline(bool closedLoop); - void CalculateKnots(TUniqueId, const std::vector&, CStateManager&); - void Initialize(TUniqueId, const std::vector&, CStateManager&); - void Reset(int size); + explicit CCameraSpline(bool closedLoop); + void CalculateKnots(TUniqueId cameraId, const std::vector& connections, CStateManager& mgr); + void Initialize(TUniqueId cameraId, const std::vector& connections, CStateManager& mgr); + void Reset(size_t size); void AddKnot(const zeus::CVector3f& pos, const zeus::CVector3f& dir); - void SetKnotPosition(int idx, const zeus::CVector3f& pos); - const zeus::CVector3f& GetKnotPosition(int idx) const; - float GetKnotT(int idx) const; + void SetKnotPosition(size_t idx, const zeus::CVector3f& pos); + const zeus::CVector3f& GetKnotPosition(size_t idx) const; + float GetKnotT(size_t idx) const; float CalculateSplineLength(); void UpdateSplineLength() { x44_length = CalculateSplineLength(); } zeus::CTransform GetInterpolatedSplinePointByLength(float pos) const; diff --git a/Runtime/Camera/CCinematicCamera.cpp b/Runtime/Camera/CCinematicCamera.cpp index 505f2218e..816fa1829 100644 --- a/Runtime/Camera/CCinematicCamera.cpp +++ b/Runtime/Camera/CCinematicCamera.cpp @@ -14,7 +14,7 @@ namespace urde { CCinematicCamera::CCinematicCamera(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, bool active, float shotDuration, float fovy, float znear, float zfar, float aspect, u32 flags) -: CGameCamera(uid, active, name, info, xf, fovy, znear, zfar, aspect, kInvalidUniqueId, flags & 0x20, 0) +: CGameCamera(uid, active, name, info, xf, fovy, znear, zfar, aspect, kInvalidUniqueId, (flags & 0x20) != 0, 0) , x1e8_duration(shotDuration) , x1f0_origFovy(fovy) , x1fc_origOrientation(zeus::CQuaternion(xf.basis)) @@ -35,8 +35,9 @@ void CCinematicCamera::Reset(const zeus::CTransform&, CStateManager& mgr) { void CCinematicCamera::WasDeactivated(CStateManager& mgr) { mgr.GetCameraManager()->RemoveCinemaCamera(GetUniqueId(), mgr); mgr.GetPlayer().GetMorphBall()->LoadMorphBallModel(mgr); - if (x21c_flags & 0x100) + if ((x21c_flags & 0x100) != 0) { mgr.SetCinematicPause(false); + } x188_viewPoints.clear(); x198_viewOrientations.clear(); x1a8_viewPointArrivals.clear(); @@ -48,25 +49,28 @@ void CCinematicCamera::WasDeactivated(CStateManager& mgr) { zeus::CVector3f CCinematicCamera::GetInterpolatedSplinePoint(const std::vector& points, int& idxOut, float tin) const { if (points.size() > 0) { - float cycleT = std::fmod(tin, x1e8_duration); - float durPerPoint = x1e8_duration / float(points.size() - 1); + const float cycleT = std::fmod(tin, x1e8_duration); + const float durPerPoint = x1e8_duration / float(points.size() - 1); idxOut = int(cycleT / durPerPoint); - float t = (cycleT - idxOut * durPerPoint) / durPerPoint; + const float t = (cycleT - float(idxOut) * durPerPoint) / durPerPoint; - if (points.size() == 1) + if (points.size() == 1) { return points.front(); - else if (points.size() == 2) + } + if (points.size() == 2) { return (points[1] - points[0]) * t + points[0]; + } zeus::CVector3f ptA; - if (idxOut > 0) + if (idxOut > 0) { ptA = points[idxOut - 1]; - else + } else { ptA = points[0] - (points[1] - points[0]); + } - zeus::CVector3f ptB = points[idxOut]; + const zeus::CVector3f ptB = points[idxOut]; zeus::CVector3f ptC; - if (idxOut + 1 >= points.size()) { + if (size_t(idxOut + 1) >= points.size()) { const zeus::CVector3f& tmpA = points[points.size() - 1]; const zeus::CVector3f& tmpB = points[points.size() - 2]; ptC = tmpA - (tmpB - tmpA); @@ -75,7 +79,7 @@ zeus::CVector3f CCinematicCamera::GetInterpolatedSplinePoint(const std::vector= points.size()) { + if (size_t(idxOut + 2) >= points.size()) { const zeus::CVector3f& tmpA = points[points.size() - 1]; const zeus::CVector3f& tmpB = points[points.size() - 2]; ptD = tmpA - (tmpB - tmpA); @@ -91,39 +95,50 @@ zeus::CVector3f CCinematicCamera::GetInterpolatedSplinePoint(const std::vector& rotations, float tin) const { - if (rotations.size() == 0) + if (rotations.empty()) { return x1fc_origOrientation; - else if (rotations.size() == 1) - return rotations.front(); + } - float cycleT = std::fmod(tin, x1e8_duration); - float durPerPoint = x1e8_duration / float(rotations.size() - 1); - int idx = int(cycleT / durPerPoint); - float t = (cycleT - idx * durPerPoint) / durPerPoint; + if (rotations.size() == 1) { + return rotations.front(); + } + + const float cycleT = std::fmod(tin, x1e8_duration); + const float durPerPoint = x1e8_duration / float(rotations.size() - 1); + const int idx = int(cycleT / durPerPoint); + const float t = (cycleT - float(idx) * durPerPoint) / durPerPoint; return zeus::CQuaternion::slerp(rotations[idx], rotations[idx + 1], t); } float CCinematicCamera::GetInterpolatedHFov(const std::vector& fovs, float tin) const { - if (fovs.size() == 0) + if (fovs.empty()) { return x1f0_origFovy; - else if (fovs.size() == 1) - return fovs.front(); + } - float cycleT = std::fmod(tin, x1e8_duration); - float durPerPoint = x1e8_duration / float(fovs.size() - 1); - int idx = int(cycleT / durPerPoint); - float t = (cycleT - idx * durPerPoint) / durPerPoint; + if (fovs.size() == 1) { + return fovs.front(); + } + + const float cycleT = std::fmod(tin, x1e8_duration); + const float durPerPoint = x1e8_duration / float(fovs.size() - 1); + const int idx = int(cycleT / durPerPoint); + const float t = (cycleT - float(idx) * durPerPoint) / durPerPoint; return (fovs[idx + 1] - fovs[idx]) * t + fovs[idx]; } float CCinematicCamera::GetMoveOutofIntoAlpha() const { - float startDist = 0.25f + x160_znear; - float endDist = 1.f * startDist; - float deltaMag = (GetTranslation() - x210_moveIntoEyePos).magnitude(); - if (deltaMag >= startDist && deltaMag <= endDist) + const float startDist = 0.25f + x160_znear; + const float endDist = 1.f * startDist; + const float deltaMag = (GetTranslation() - x210_moveIntoEyePos).magnitude(); + + if (deltaMag >= startDist && deltaMag <= endDist) { return (deltaMag - startDist) / (endDist - startDist); - if (deltaMag > endDist) + } + + if (deltaMag > endDist) { return 1.f; + } + return 0.f; } @@ -136,7 +151,7 @@ void CCinematicCamera::DeactivateSelf(CStateManager& mgr) { void CCinematicCamera::Think(float dt, CStateManager& mgr) { if (GetActive()) { zeus::CVector3f viewPoint = GetTranslation(); - if (x188_viewPoints.size() > 0) { + if (!x188_viewPoints.empty()) { int idx = 0; viewPoint = GetInterpolatedSplinePoint(x188_viewPoints, idx, x1ec_t); if (idx > x1f4_passedViewPoint) { @@ -145,58 +160,67 @@ void CCinematicCamera::Think(float dt, CStateManager& mgr) { } } - zeus::CQuaternion orientation = GetInterpolatedOrientation(x198_viewOrientations, x1ec_t); + const zeus::CQuaternion orientation = GetInterpolatedOrientation(x198_viewOrientations, x1ec_t); if ((x21c_flags & 0x1) == 0) { - if (x1b8_targets.size() > 0) { + if (!x1b8_targets.empty()) { int idx = 0; zeus::CVector3f target = GetInterpolatedSplinePoint(x1b8_targets, idx, x1ec_t); if (x1b8_targets.size() == 1) { - if (TCastToConstPtr act = mgr.GetObjectById(x1c8_targetArrivals.front())) + if (const TCastToConstPtr act = mgr.GetObjectById(x1c8_targetArrivals.front())) { target = act->GetTranslation(); - else + } else { x1ec_t = x1e8_duration; + } } if (idx > x1f8_passedTarget) { x1f8_passedTarget = idx; SendArrivedMsg(x1c8_targetArrivals[x1f8_passedTarget], mgr); } - zeus::CVector3f upVec = orientation.transform(zeus::skUp); - if ((target - viewPoint).toVec2f().magnitude() < 0.0011920929f) + const zeus::CVector3f upVec = orientation.transform(zeus::skUp); + if ((target - viewPoint).toVec2f().magnitude() < 0.0011920929f) { SetTranslation(target); - else + } else { SetTransform(zeus::lookAt(viewPoint, target, upVec)); + } } else { SetTransform(zeus::CTransform(orientation, viewPoint)); } } else { zeus::CVector3f target = mgr.GetPlayer().GetTranslation(); - if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed) + if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed) { target.z() += mgr.GetPlayer().GetMorphBall()->GetBallRadius(); - else + } else { target.z() += mgr.GetPlayer().GetEyeHeight(); + } - zeus::CVector3f upVec = orientation.transform(zeus::skUp); - if ((target - viewPoint).toVec2f().magnitude() < 0.0011920929f) + const zeus::CVector3f upVec = orientation.transform(zeus::skUp); + if ((target - viewPoint).toVec2f().magnitude() < 0.0011920929f) { SetTranslation(target); - else + } else { SetTransform(zeus::lookAt(viewPoint, target, upVec)); + } } x15c_currentFov = GetInterpolatedHFov(x1d8_viewHFovs, x1ec_t) / x168_aspect; x170_24_perspDirty = true; - if (x20c_lookAtId != kInvalidUniqueId) - if (TCastToPtr act = mgr.ObjectById(x20c_lookAtId)) - if (act->IsPlayerActor()) + if (x20c_lookAtId != kInvalidUniqueId) { + if (const TCastToPtr act = mgr.ObjectById(x20c_lookAtId)) { + if (act->IsPlayerActor()) { act->SetDrawFlags({5, 0, 3, zeus::CColor(1.f, GetMoveOutofIntoAlpha())}); + } + } + } x1ec_t += dt; if (x1ec_t > x1e8_duration) { - for (size_t i = x1f4_passedViewPoint + 1; i < x1a8_viewPointArrivals.size(); ++i) + for (size_t i = x1f4_passedViewPoint + 1; i < x1a8_viewPointArrivals.size(); ++i) { SendArrivedMsg(x1a8_viewPointArrivals[i], mgr); - for (size_t i = x1f8_passedTarget + 1; i < x1c8_targetArrivals.size(); ++i) + } + for (size_t i = x1f8_passedTarget + 1; i < x1c8_targetArrivals.size(); ++i) { SendArrivedMsg(x1c8_targetArrivals[i], mgr); + } DeactivateSelf(mgr); } } @@ -206,14 +230,15 @@ void CCinematicCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CGameCamera::AcceptScriptMsg(msg, uid, mgr); switch (msg) { case EScriptObjectMessage::InitializedInArea: - if (x21c_flags & 0x4 || x21c_flags & 0x2) { + if ((x21c_flags & 0x4) != 0 || (x21c_flags & 0x2) != 0) { for (const SConnection& conn : x20_conns) { - TUniqueId id = mgr.GetIdForScript(conn.x8_objId); - if (TCastToPtr act = mgr.ObjectById(id)) { + const TUniqueId id = mgr.GetIdForScript(conn.x8_objId); + if (const TCastToConstPtr act = mgr.ObjectById(id)) { if (act->IsPlayerActor()) { x20c_lookAtId = id; - if (conn.x4_msg != EScriptObjectMessage::Deactivate && conn.x4_msg != EScriptObjectMessage::Reset) + if (conn.x4_msg != EScriptObjectMessage::Deactivate && conn.x4_msg != EScriptObjectMessage::Reset) { break; + } } } } @@ -221,19 +246,23 @@ void CCinematicCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, break; case EScriptObjectMessage::Activate: CalculateWaypoints(mgr); - if ((x21c_flags & 1) == 0 && x220_24_ && x1b8_targets.empty()) + if ((x21c_flags & 1) == 0 && x220_24_ && x1b8_targets.empty()) { break; + } x1ec_t = 0.f; Think(0.f, mgr); mgr.GetCameraManager()->AddCinemaCamera(GetUniqueId(), mgr); x1f4_passedViewPoint = 0; - if (x1a8_viewPointArrivals.size() > 0) + if (!x1a8_viewPointArrivals.empty()) { SendArrivedMsg(x1a8_viewPointArrivals[x1f4_passedViewPoint], mgr); + } x1f8_passedTarget = 0; - if (x1c8_targetArrivals.size() > 0) + if (!x1c8_targetArrivals.empty()) { SendArrivedMsg(x1c8_targetArrivals[x1f8_passedTarget], mgr); - if (x21c_flags & 0x100) + } + if ((x21c_flags & 0x100) != 0) { mgr.SetCinematicPause(true); + } break; case EScriptObjectMessage::Deactivate: WasDeactivated(mgr); @@ -247,7 +276,7 @@ void CCinematicCamera::CalculateMoveOutofIntoEyePosition(bool outOfEye, CStateMa zeus::CQuaternion q(mgr.GetPlayer().GetTransform().basis); zeus::CVector3f eyePos = mgr.GetPlayer().GetEyePosition(); if (x20c_lookAtId != kInvalidUniqueId) { - if (TCastToConstPtr act = mgr.GetObjectById(x20c_lookAtId)) { + if (const TCastToConstPtr act = mgr.GetObjectById(x20c_lookAtId)) { if (act->IsPlayerActor()) { if (const CModelData* mData = act->GetModelData()) { if (const CAnimData* aData = mData->GetAnimationData()) { @@ -255,8 +284,9 @@ void CCinematicCamera::CalculateMoveOutofIntoEyePosition(bool outOfEye, CStateMa const CSegId lEye = aData->GetLocatorSegId("L_eye"sv); const CSegId rEye = aData->GetLocatorSegId("R_eye"sv); if (lEye.IsValid() && rEye.IsValid()) { - CCharAnimTime time = outOfEye ? CCharAnimTime(0.f) : root->VGetSteadyStateAnimInfo().GetDuration(); - CCharAnimTime* pTime = outOfEye ? nullptr : &time; + const CCharAnimTime time = + outOfEye ? CCharAnimTime(0.f) : root->VGetSteadyStateAnimInfo().GetDuration(); + const CCharAnimTime* pTime = outOfEye ? nullptr : &time; eyePos = ((act->GetTransform() * mData->GetScaledLocatorTransformDynamic("L_eye"sv, pTime)).origin + (act->GetTransform() * mData->GetScaledLocatorTransformDynamic("R_eye"sv, pTime)).origin) * 0.5f; @@ -287,8 +317,8 @@ void CCinematicCamera::CalculateMoveOutofIntoEyePosition(bool outOfEye, CStateMa } void CCinematicCamera::GenerateMoveOutofIntoPoints(bool outOfEye, CStateManager& mgr) { - zeus::CQuaternion q(mgr.GetPlayer().GetTransform().basis); - zeus::CVector3f eyePos = mgr.GetPlayer().GetEyePosition(); + const zeus::CQuaternion q(mgr.GetPlayer().GetTransform().basis); + const zeus::CVector3f eyePos = mgr.GetPlayer().GetEyePosition(); zeus::CVector3f behindDelta = q.transform({0.f, -g_tweakPlayerRes->xf0_cinematicMoveOutofIntoPlayerDistance, 0.f}); zeus::CVector3f behindPos = eyePos; if (!outOfEye) { @@ -296,11 +326,11 @@ void CCinematicCamera::GenerateMoveOutofIntoPoints(bool outOfEye, CStateManager& behindDelta = -behindDelta; } for (int i = 0; i < 2; ++i) { - x188_viewPoints.push_back(behindPos); - x198_viewOrientations.push_back(q); - x1a8_viewPointArrivals.push_back(mgr.GetPlayer().GetUniqueId()); - x1b8_targets.push_back(eyePos); - x1c8_targetArrivals.push_back(kInvalidUniqueId); + x188_viewPoints.emplace_back(behindPos); + x198_viewOrientations.emplace_back(q); + x1a8_viewPointArrivals.emplace_back(mgr.GetPlayer().GetUniqueId()); + x1b8_targets.emplace_back(eyePos); + x1c8_targetArrivals.emplace_back(kInvalidUniqueId); behindPos += behindDelta; } CalculateMoveOutofIntoEyePosition(outOfEye, mgr); @@ -309,20 +339,25 @@ void CCinematicCamera::GenerateMoveOutofIntoPoints(bool outOfEye, CStateManager& bool CCinematicCamera::PickRandomActiveConnection(const std::vector& conns, SConnection& randConn, CStateManager& mgr) { int count = 0; - for (const SConnection& conn : conns) - if (conn.x0_state == EScriptObjectState::Arrived && conn.x4_msg == EScriptObjectMessage::Next) - if (TCastToConstPtr act = mgr.GetObjectById(mgr.GetIdForScript(conn.x8_objId))) - if (act->GetActive()) + for (const SConnection& conn : conns) { + if (conn.x0_state == EScriptObjectState::Arrived && conn.x4_msg == EScriptObjectMessage::Next) { + if (const TCastToConstPtr act = mgr.GetObjectById(mgr.GetIdForScript(conn.x8_objId))) { + if (act->GetActive()) { ++count; + } + } + } + } - if (!count) + if (count == 0) { return false; + } - int randIdx = mgr.GetActiveRandom()->Next() % count; + const int randIdx = mgr.GetActiveRandom()->Next() % count; int idx = 0; - for (const SConnection& conn : conns) - if (conn.x0_state == EScriptObjectState::Arrived && conn.x4_msg == EScriptObjectMessage::Next) - if (TCastToConstPtr act = mgr.GetObjectById(mgr.GetIdForScript(conn.x8_objId))) + for (const SConnection& conn : conns) { + if (conn.x0_state == EScriptObjectState::Arrived && conn.x4_msg == EScriptObjectMessage::Next) { + if (const TCastToConstPtr act = mgr.GetObjectById(mgr.GetIdForScript(conn.x8_objId))) { if (act->GetActive()) { if (randIdx == idx) { randConn = conn; @@ -330,6 +365,9 @@ bool CCinematicCamera::PickRandomActiveConnection(const std::vector } ++idx; } + } + } + } return true; } @@ -338,10 +376,11 @@ void CCinematicCamera::CalculateWaypoints(CStateManager& mgr) { const SConnection* firstVP = nullptr; const SConnection* firstTarget = nullptr; for (const SConnection& conn : x20_conns) { - if (conn.x0_state == EScriptObjectState::CameraPath && conn.x4_msg == EScriptObjectMessage::Activate) + if (conn.x0_state == EScriptObjectState::CameraPath && conn.x4_msg == EScriptObjectMessage::Activate) { firstVP = &conn; - else if (conn.x0_state == EScriptObjectState::CameraTarget && conn.x4_msg == EScriptObjectMessage::Activate) + } else if (conn.x0_state == EScriptObjectState::CameraTarget && conn.x4_msg == EScriptObjectMessage::Activate) { firstTarget = &conn; + } } x188_viewPoints.clear(); @@ -359,27 +398,31 @@ void CCinematicCamera::CalculateWaypoints(CStateManager& mgr) { x220_24_ = false; - if ((x21c_flags & 0x2) != 0 && (x21c_flags & 0x200) == 0) + if ((x21c_flags & 0x2) != 0 && (x21c_flags & 0x200) == 0) { GenerateMoveOutofIntoPoints(true, mgr); + } if (firstVP) { TCastToConstPtr wp = mgr.GetObjectById(mgr.GetIdForScript(firstVP->x8_objId)); while (wp) { x188_viewPoints.push_back(wp->GetTranslation()); x198_viewOrientations.emplace_back(wp->GetTransform().basis); - if (TCastToConstPtr cwp = wp.GetPtr()) + if (const TCastToConstPtr cwp = wp.GetPtr()) { x1d8_viewHFovs.push_back(cwp->GetHFov()); - auto search = std::find_if(x1a8_viewPointArrivals.begin(), x1a8_viewPointArrivals.end(), - [&](TUniqueId id) { return id == wp->GetUniqueId(); }); - if (search == x1a8_viewPointArrivals.end()) { + } + const auto search = std::find_if(x1a8_viewPointArrivals.cbegin(), x1a8_viewPointArrivals.cend(), + [&wp](TUniqueId id) { return id == wp->GetUniqueId(); }); + if (search == x1a8_viewPointArrivals.cend()) { x1a8_viewPointArrivals.push_back(wp->GetUniqueId()); SConnection randConn; - if (PickRandomActiveConnection(wp->GetConnectionList(), randConn, mgr)) + if (PickRandomActiveConnection(wp->GetConnectionList(), randConn, mgr)) { wp = mgr.GetObjectById(mgr.GetIdForScript(randConn.x8_objId)); - else + } else { break; - } else + } + } else { break; + } } } @@ -387,22 +430,25 @@ void CCinematicCamera::CalculateWaypoints(CStateManager& mgr) { TCastToConstPtr tgt = mgr.GetObjectById(mgr.GetIdForScript(firstTarget->x8_objId)); while (tgt) { x1b8_targets.push_back(tgt->GetTranslation()); - auto search = std::find_if(x1c8_targetArrivals.begin(), x1c8_targetArrivals.end(), - [&](TUniqueId id) { return id == tgt->GetUniqueId(); }); - if (search == x1c8_targetArrivals.end()) { + const auto search = std::find_if(x1c8_targetArrivals.cbegin(), x1c8_targetArrivals.cend(), + [&tgt](TUniqueId id) { return id == tgt->GetUniqueId(); }); + if (search == x1c8_targetArrivals.cend()) { x1c8_targetArrivals.push_back(tgt->GetUniqueId()); SConnection randConn; - if (PickRandomActiveConnection(tgt->GetConnectionList(), randConn, mgr)) + if (PickRandomActiveConnection(tgt->GetConnectionList(), randConn, mgr)) { tgt = mgr.GetObjectById(mgr.GetIdForScript(randConn.x8_objId)); - else + } else { break; - } else + } + } else { break; + } } } - if ((x21c_flags & 0x4) != 0 && (x21c_flags & 0x200) == 0) + if ((x21c_flags & 0x4) != 0 && (x21c_flags & 0x200) == 0) { GenerateMoveOutofIntoPoints(false, mgr); + } } void CCinematicCamera::SendArrivedMsg(TUniqueId reciever, CStateManager& mgr) { diff --git a/Runtime/Camera/CInterpolationCamera.cpp b/Runtime/Camera/CInterpolationCamera.cpp index 09d6eaedd..af20e7d51 100644 --- a/Runtime/Camera/CInterpolationCamera.cpp +++ b/Runtime/Camera/CInterpolationCamera.cpp @@ -14,7 +14,8 @@ CInterpolationCamera::CInterpolationCamera(TUniqueId uid, const zeus::CTransform : CGameCamera(uid, false, "Interpolation Camera", CEntityInfo(kInvalidAreaId, CEntity::NullConnectionList, kInvalidEditorId), xf, CCameraManager::ThirdPersonFOV(), CCameraManager::NearPlane(), CCameraManager::FarPlane(), - CCameraManager::Aspect(), kInvalidUniqueId, false, 0) {} + CCameraManager::Aspect(), kInvalidUniqueId, false, 0) +, x1d8_24_sinusoidal{false} {} void CInterpolationCamera::Accept(IVisitor& visitor) { visitor.Visit(this); } @@ -26,7 +27,7 @@ void CInterpolationCamera::ProcessInput(const CFinalInput& input, CStateManager& // Empty } -void CInterpolationCamera::Render(const CStateManager& mgr) const { +void CInterpolationCamera::Render(CStateManager& mgr) { // Empty } diff --git a/Runtime/Camera/CInterpolationCamera.hpp b/Runtime/Camera/CInterpolationCamera.hpp index 260b47203..3ac69efdd 100644 --- a/Runtime/Camera/CInterpolationCamera.hpp +++ b/Runtime/Camera/CInterpolationCamera.hpp @@ -26,11 +26,11 @@ class CInterpolationCamera : public CGameCamera { float maxTime, float curTime); public: - CInterpolationCamera(TUniqueId uid, const zeus::CTransform& xf); + explicit CInterpolationCamera(TUniqueId uid, const zeus::CTransform& xf); void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void ProcessInput(const CFinalInput&, CStateManager& mgr) override; - void Render(const CStateManager&) const override; + void Render(CStateManager&) override; void Reset(const zeus::CTransform&, CStateManager& mgr) override; void Think(float, CStateManager&) override; void SetInterpolation(const zeus::CTransform& xf, const zeus::CVector3f& lookPos, float maxTime, float positionSpeed, diff --git a/Runtime/Camera/CPathCamera.hpp b/Runtime/Camera/CPathCamera.hpp index 96691fe2d..7757e76a1 100644 --- a/Runtime/Camera/CPathCamera.hpp +++ b/Runtime/Camera/CPathCamera.hpp @@ -29,7 +29,7 @@ public: void Accept(IVisitor&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float, CStateManager&) override; - void Render(const CStateManager&) const override {} + void Render(CStateManager&) override {} void ProcessInput(const CFinalInput&, CStateManager& mgr) override; void Reset(const zeus::CTransform&, CStateManager& mgr) override; zeus::CTransform MoveAlongSpline(float, CStateManager&); diff --git a/Runtime/Character/CAdditiveAnimPlayback.cpp b/Runtime/Character/CAdditiveAnimPlayback.cpp index 28406e01a..fde744ded 100644 --- a/Runtime/Character/CAdditiveAnimPlayback.cpp +++ b/Runtime/Character/CAdditiveAnimPlayback.cpp @@ -18,7 +18,7 @@ void CAdditiveAnimPlayback::AddToSegStatementSet(const CSegIdList& list, const C CSegStatementSet stackSet; x8_anim->VGetSegStatementSet(list, stackSet); for (const CSegId& id : list.GetList()) { - CAnimPerSegmentData& data = stackSet.x4_segData[id]; + CAnimPerSegmentData& data = stackSet[id]; data.x10_offset = layout.GetFromParentUnrotated(id); data.x1c_hasOffset = true; } diff --git a/Runtime/Character/CAdditiveAnimPlayback.hpp b/Runtime/Character/CAdditiveAnimPlayback.hpp index 582bbeb48..637a287d8 100644 --- a/Runtime/Character/CAdditiveAnimPlayback.hpp +++ b/Runtime/Character/CAdditiveAnimPlayback.hpp @@ -20,7 +20,7 @@ public: x4_fadeOutDur = in.readFloatBig(); } CAdditiveAnimationInfo() = default; - CAdditiveAnimationInfo(CInputStream& in) { read(in); } + explicit CAdditiveAnimationInfo(CInputStream& in) { read(in); } float GetFadeInDuration() const { return x0_fadeInDur; } float GetFadeOutDuration() const { return x4_fadeOutDur; } }; diff --git a/Runtime/Character/CAdditiveBodyState.cpp b/Runtime/Character/CAdditiveBodyState.cpp index ff5a449f4..587e89499 100644 --- a/Runtime/Character/CAdditiveBodyState.cpp +++ b/Runtime/Character/CAdditiveBodyState.cpp @@ -14,9 +14,9 @@ void CABSAim::Start(CBodyController& bc, CStateManager& mgr) { const CPASAnimState* aimState = bc.GetPASDatabase().GetAnimState(22); // Left, Right, Up, Down - for (int i = 0; i < 4; ++i) { - CPASAnimParmData parms(22, CPASAnimParm::FromEnum(i)); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + for (size_t i = 0; i < x8_anims.size(); ++i) { + const CPASAnimParmData parms(22, CPASAnimParm::FromEnum(s32(i))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); x8_anims[i] = best.second; x18_angles[i] = zeus::degToRad(aimState->GetAnimParmData(x8_anims[i], 1).GetReal32Value()); } diff --git a/Runtime/Character/CAdditiveBodyState.hpp b/Runtime/Character/CAdditiveBodyState.hpp index 8bdbcfdd6..3c2c3bbb6 100644 --- a/Runtime/Character/CAdditiveBodyState.hpp +++ b/Runtime/Character/CAdditiveBodyState.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "Runtime/RetroTypes.hpp" #include "Runtime/Character/CBodyStateCmdMgr.hpp" #include "Runtime/Character/CharacterCommon.hpp" @@ -21,8 +23,8 @@ public: class CABSAim : public CAdditiveBodyState { bool x4_needsIdle = false; - s32 x8_anims[4]; - float x18_angles[4]; + std::array x8_anims{}; + std::array x18_angles{}; float x28_hWeight = 0.f; float x2c_hWeightVel = 0.f; float x30_vWeight = 0.f; diff --git a/Runtime/Character/CAllFormatsAnimSource.hpp b/Runtime/Character/CAllFormatsAnimSource.hpp index b762a5e8c..b8a60f9e8 100644 --- a/Runtime/Character/CAllFormatsAnimSource.hpp +++ b/Runtime/Character/CAllFormatsAnimSource.hpp @@ -26,12 +26,12 @@ class CAnimFormatUnion { static void SubConstruct(u8* storage, EAnimFormat fmt, CInputStream& in, IObjectStore& store); public: - CAnimFormatUnion(CInputStream& in, IObjectStore& store); + explicit CAnimFormatUnion(CInputStream& in, IObjectStore& store); ~CAnimFormatUnion(); EAnimFormat GetFormat() const { return x0_format; } - const CAnimSource& GetAsCAnimSource() const { return *reinterpret_cast(x4_storage); } - const CFBStreamedCompression& GetAsCFBStreamedCompression() const { - return *reinterpret_cast(x4_storage); + CAnimSource& GetAsCAnimSource() { return *reinterpret_cast(x4_storage); } + CFBStreamedCompression& GetAsCFBStreamedCompression() { + return *reinterpret_cast(x4_storage); } }; @@ -40,7 +40,7 @@ class CAllFormatsAnimSource : public CAnimFormatUnion { SObjectTag x74_tag; public: - CAllFormatsAnimSource(CInputStream& in, IObjectStore& store, const SObjectTag& tag); + explicit CAllFormatsAnimSource(CInputStream& in, IObjectStore& store, const SObjectTag& tag); static std::shared_ptr GetNewReader(const TLockedToken& tok, const CCharAnimTime& startTime); }; diff --git a/Runtime/Character/CAnimCharacterSet.hpp b/Runtime/Character/CAnimCharacterSet.hpp index 749abeb31..94bba47cf 100644 --- a/Runtime/Character/CAnimCharacterSet.hpp +++ b/Runtime/Character/CAnimCharacterSet.hpp @@ -12,7 +12,7 @@ class CAnimCharacterSet { CAnimationSet x1c_animationSet; public: - CAnimCharacterSet(CInputStream& in); + explicit CAnimCharacterSet(CInputStream& in); const CCharacterSet& GetCharacterSet() const { return x4_characterSet; } const CAnimationSet& GetAnimationSet() const { return x1c_animationSet; } }; diff --git a/Runtime/Character/CAnimData.cpp b/Runtime/Character/CAnimData.cpp index c621ed647..f201b064b 100644 --- a/Runtime/Character/CAnimData.cpp +++ b/Runtime/Character/CAnimData.cpp @@ -56,7 +56,7 @@ CAnimData::CAnimData(CAssetId id, const CCharacterInfo& character, int defaultAn , x204_charIdx(charIdx) , x208_defaultAnim(defaultAnim) , x224_pose(layout->GetSegIdList().GetList().size()) -, x2fc_poseBuilder(layout) +, x2fc_poseBuilder(CLayoutDescription{layout}) , m_drawInstCount(drawInstCount) { x220_25_loop = loop; @@ -72,7 +72,7 @@ CAnimData::CAnimData(CAssetId id, const CCharacterInfo& character, int defaultAn x108_aabb = xd8_modelData->GetModel()->GetAABB(); x120_particleDB.CacheParticleDesc(xc_charInfo.GetParticleResData()); - CHierarchyPoseBuilder pb(xcc_layoutData); + CHierarchyPoseBuilder pb(CLayoutDescription{xcc_layoutData}); pb.BuildNoScale(x224_pose); x220_30_poseBuilt = true; diff --git a/Runtime/Character/CAnimData.hpp b/Runtime/Character/CAnimData.hpp index d2cf6a91c..184874263 100644 --- a/Runtime/Character/CAnimData.hpp +++ b/Runtime/Character/CAnimData.hpp @@ -10,11 +10,13 @@ #include "Runtime/Character/CAdditiveAnimPlayback.hpp" #include "Runtime/Character/CAnimPlaybackParms.hpp" #include "Runtime/Character/CCharLayoutInfo.hpp" +#include "Runtime/Character/CCharacterFactory.hpp" #include "Runtime/Character/CCharacterInfo.hpp" #include "Runtime/Character/CHierarchyPoseBuilder.hpp" #include "Runtime/Character/CParticleDatabase.hpp" #include "Runtime/Character/CPoseAsTransforms.hpp" #include "Runtime/Character/IAnimReader.hpp" +#include "Runtime/Graphics/CSkinnedModel.hpp" #include #include @@ -64,7 +66,6 @@ class CAnimationManager; class CBoolPOINode; class CCharAnimTime; class CCharLayoutInfo; -class CCharacterFactory; class CInt32POINode; class CModel; class CMorphableSkinnedModel; @@ -74,7 +75,6 @@ class CRandom16; class CSegIdList; class CSegStatementSet; class CSkinRules; -class CSkinnedModel; class CSoundPOINode; class CStateManager; class CTransitionManager; @@ -161,36 +161,36 @@ public: TLockedToken charFactory, int drawInstCount); void SetParticleEffectState(std::string_view effectName, bool active, CStateManager& mgr); - void InitializeEffects(CStateManager&, TAreaId, const zeus::CVector3f&); - CAssetId GetEventResourceIdForAnimResourceId(CAssetId) const; + void InitializeEffects(CStateManager& mgr, TAreaId aId, const zeus::CVector3f& scale); + CAssetId GetEventResourceIdForAnimResourceId(CAssetId id) const; void AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet); static SAdvancementResults AdvanceAdditiveAnim(std::shared_ptr& anim, const CCharAnimTime& time); - SAdvancementDeltas AdvanceAdditiveAnims(float); - SAdvancementDeltas UpdateAdditiveAnims(float); - bool IsAdditiveAnimation(s32) const; - bool IsAdditiveAnimationAdded(s32) const; + SAdvancementDeltas AdvanceAdditiveAnims(float dt); + SAdvancementDeltas UpdateAdditiveAnims(float dt); + bool IsAdditiveAnimation(s32 idx) const; + bool IsAdditiveAnimationAdded(s32 idx) const; const std::shared_ptr& GetRootAnimationTree() const { return x1f8_animRoot; } - const std::shared_ptr& GetAdditiveAnimationTree(s32) const; - bool IsAdditiveAnimationActive(s32) const; - void DelAdditiveAnimation(s32); - void AddAdditiveAnimation(s32, float, bool, bool); + const std::shared_ptr& GetAdditiveAnimationTree(s32 idx) const; + bool IsAdditiveAnimationActive(s32 idx) const; + void DelAdditiveAnimation(s32 idx); + void AddAdditiveAnimation(s32 idx, float weight, bool active, bool fadeOut); float GetAdditiveAnimationWeight(s32 idx) const; std::shared_ptr GetAnimationManager(); const CCharacterInfo& GetCharacterInfo() const { return xc_charInfo; } const CCharLayoutInfo& GetCharLayoutInfo() const { return *xcc_layoutData.GetObj(); } - void SetPhase(float); + void SetPhase(float ph); void Touch(const CSkinnedModel& model, int shaderIdx) const; SAdvancementDeltas GetAdvancementDeltas(const CCharAnimTime& a, const CCharAnimTime& b) const; - CCharAnimTime GetTimeOfUserEvent(EUserEventType, const CCharAnimTime& time) const; - void MultiplyPlaybackRate(float); - void SetPlaybackRate(float); - void SetRandomPlaybackRate(CRandom16&); + CCharAnimTime GetTimeOfUserEvent(EUserEventType type, const CCharAnimTime& time) const; + void MultiplyPlaybackRate(float mul); + void SetPlaybackRate(float set); + void SetRandomPlaybackRate(CRandom16& r); void CalcPlaybackAlignmentParms(const CAnimPlaybackParms& parms, const std::shared_ptr& node); zeus::CTransform GetLocatorTransform(CSegId id, const CCharAnimTime* time) const; zeus::CTransform GetLocatorTransform(std::string_view name, const CCharAnimTime* time) const; - bool IsAnimTimeRemaining(float, std::string_view name) const; + bool IsAnimTimeRemaining(float rem, std::string_view name) const; float GetAnimTimeRemaining(std::string_view name) const; - float GetAnimationDuration(int) const; + float GetAnimationDuration(int animIn) const; bool GetIsLoop() const { return x220_25_loop; } void EnableLooping(bool val) { x220_25_loop = val; @@ -201,7 +201,7 @@ public: void SetAnimDir(EAnimDir dir) { x104_animDir = dir; } std::shared_ptr GetAnimSysContext() const; std::shared_ptr GetAnimationManager() const; - void RecalcPoseBuilder(const CCharAnimTime*); + void RecalcPoseBuilder(const CCharAnimTime* time); void RenderAuxiliary(const zeus::CFrustum& frustum) const; void Render(CSkinnedModel& model, const CModelFlags& drawFlags, const std::optional& morphEffect, const float* morphMagnitudes); @@ -214,15 +214,16 @@ public: static void PrimitiveSetToTokenVector(const std::set& primSet, std::vector& tokensOut, bool preLock); void GetAnimationPrimitives(const CAnimPlaybackParms& parms, std::set& primsOut) const; - void SetAnimation(const CAnimPlaybackParms& parms, bool); - SAdvancementDeltas DoAdvance(float, bool& suspendParticles, CRandom16&, bool advTree); - SAdvancementDeltas Advance(float, const zeus::CVector3f&, CStateManager& stateMgr, TAreaId aid, bool advTree); - SAdvancementDeltas AdvanceIgnoreParticles(float, CRandom16&, bool advTree); - void AdvanceAnim(CCharAnimTime& time, zeus::CVector3f&, zeus::CQuaternion&); + void SetAnimation(const CAnimPlaybackParms& parms, bool noTrans); + SAdvancementDeltas DoAdvance(float dt, bool& suspendParticles, CRandom16& random, bool advTree); + SAdvancementDeltas Advance(float dt, const zeus::CVector3f& scale, CStateManager& stateMgr, TAreaId aid, bool advTree); + SAdvancementDeltas AdvanceIgnoreParticles(float dt, CRandom16& random, bool advTree); + void AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::CQuaternion& quat); void SetXRayModel(const TLockedToken& model, const TLockedToken& skinRules); std::shared_ptr GetXRayModel() const { return xf4_xrayModel; } void SetInfraModel(const TLockedToken& model, const TLockedToken& skinRules); std::shared_ptr GetInfraModel() const { return xf8_infraModel; } + TLockedToken& GetModelData() { return xd8_modelData; } const TLockedToken& GetModelData() const { return xd8_modelData; } static void PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& pose, const CModelFlags& drawFlags, @@ -251,7 +252,7 @@ public: s32 GetCharacterIndex() const { return x204_charIdx; } u16 GetDefaultAnimation() const { return x208_defaultAnim; } - TLockedToken& IceModel() { return xe4_iceModelData; } + TLockedToken& GetIceModel() { return xe4_iceModelData; } const TLockedToken& GetIceModel() const { return xe4_iceModelData; } void SetParticleLightIdx(s32 idx) { x21c_particleLightIdx = idx; } diff --git a/Runtime/Character/CAnimPOIData.hpp b/Runtime/Character/CAnimPOIData.hpp index 84514f503..577bc688c 100644 --- a/Runtime/Character/CAnimPOIData.hpp +++ b/Runtime/Character/CAnimPOIData.hpp @@ -19,7 +19,7 @@ class CAnimPOIData { std::vector x34_soundNodes; public: - CAnimPOIData(CInputStream& in); + explicit CAnimPOIData(CInputStream& in); const std::vector& GetBoolPOIStream() const { return x4_boolNodes; } const std::vector& GetInt32POIStream() const { return x14_int32Nodes; } diff --git a/Runtime/Character/CAnimSource.cpp b/Runtime/Character/CAnimSource.cpp index c3c368ec3..6d884c56c 100644 --- a/Runtime/Character/CAnimSource.cpp +++ b/Runtime/Character/CAnimSource.cpp @@ -9,7 +9,7 @@ namespace urde { -static float ClampZeroToOne(float in) { return std::max(0.f, std::min(1.f, in)); } +static constexpr float ClampZeroToOne(float in) { return std::clamp(in, 0.0f, 1.0f); } u32 RotationAndOffsetStorage::DataSizeInBytes(u32 rotPerFrame, u32 transPerFrame, u32 frameCount) { return (transPerFrame * 12 + rotPerFrame * 16) * frameCount; @@ -117,33 +117,35 @@ CAnimSource::CAnimSource(CInputStream& in, IObjectStore& store) } void CAnimSource::GetSegStatementSet(const CSegIdList& list, CSegStatementSet& set, const CCharAnimTime& time) const { - u32 frameIdx = unsigned(time / x8_interval); + const auto frameIdx = u32(time / x8_interval); float remTime = time.GetSeconds() - frameIdx * x8_interval.GetSeconds(); - if (std::fabs(remTime) < 0.00001f) + if (std::fabs(remTime) < 0.00001f) { remTime = 0.f; - float t = ClampZeroToOne(remTime / x8_interval.GetSeconds()); + } + + const float t = ClampZeroToOne(remTime / x8_interval.GetSeconds()); const u32 floatsPerFrame = x40_data.x10_transPerFrame * 3 + x40_data.xc_rotPerFrame * 4; const u32 rotFloatsPerFrame = x40_data.xc_rotPerFrame * 4; for (const CSegId& id : list.GetList()) { - u8 rotIdx = x20_rotationChannels[id]; + const u8 rotIdx = x20_rotationChannels[id]; if (rotIdx != 0xff) { const float* frameDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotIdx * 4]; const float* frameDataB = &x40_data.x0_storage[(frameIdx + 1) * floatsPerFrame + rotIdx * 4]; - zeus::CQuaternion quatA(frameDataA[0], frameDataA[1], frameDataA[2], frameDataA[3]); - zeus::CQuaternion quatB(frameDataB[0], frameDataB[1], frameDataB[2], frameDataB[3]); - set.x4_segData[id].x0_rotation = zeus::CQuaternion::slerp(quatA, quatB, t); + const zeus::CQuaternion quatA(frameDataA[0], frameDataA[1], frameDataA[2], frameDataA[3]); + const zeus::CQuaternion quatB(frameDataB[0], frameDataB[1], frameDataB[2], frameDataB[3]); + set[id].x0_rotation = zeus::CQuaternion::slerp(quatA, quatB, t); - u8 transIdx = x30_translationChannels[rotIdx]; + const u8 transIdx = x30_translationChannels[rotIdx]; if (transIdx != 0xff) { - const float* frameDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; - const float* frameDataB = + const float* frameVecDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; + const float* frameVecDataB = &x40_data.x0_storage[(frameIdx - 1) * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; - zeus::CVector3f vecA(frameDataA[0], frameDataA[1], frameDataA[2]); - zeus::CVector3f vecB(frameDataB[0], frameDataB[1], frameDataB[2]); - set.x4_segData[id].x10_offset = zeus::CVector3f::lerp(vecA, vecB, t); - set.x4_segData[id].x1c_hasOffset = true; + const zeus::CVector3f vecA(frameVecDataA[0], frameVecDataA[1], frameVecDataA[2]); + const zeus::CVector3f vecB(frameVecDataB[0], frameVecDataB[1], frameVecDataB[2]); + set[id].x10_offset = zeus::CVector3f::lerp(vecA, vecB, t); + set[id].x1c_hasOffset = true; } } } diff --git a/Runtime/Character/CAnimSource.hpp b/Runtime/Character/CAnimSource.hpp index 7e093c747..26dc312cb 100644 --- a/Runtime/Character/CAnimSource.hpp +++ b/Runtime/Character/CAnimSource.hpp @@ -39,7 +39,7 @@ public: struct CRotationAndOffsetVectors { std::vector x0_rotations; std::vector x10_offsets; - CRotationAndOffsetVectors(CInputStream& in); + explicit CRotationAndOffsetVectors(CInputStream& in); }; u32 GetFrameSizeInBytes() const; RotationAndOffsetStorage(const CRotationAndOffsetVectors& vectors, u32 frameCount); @@ -61,7 +61,7 @@ class CAnimSource { void CalcAverageVelocity(); public: - CAnimSource(CInputStream& in, IObjectStore& store); + explicit CAnimSource(CInputStream& in, IObjectStore& store); void GetSegStatementSet(const CSegIdList& list, CSegStatementSet& set, const CCharAnimTime& time) const; diff --git a/Runtime/Character/CAnimSourceReader.cpp b/Runtime/Character/CAnimSourceReader.cpp index 2362dfff2..29c01fb9e 100644 --- a/Runtime/Character/CAnimSourceReader.cpp +++ b/Runtime/Character/CAnimSourceReader.cpp @@ -1,5 +1,7 @@ #include "Runtime/Character/CAnimSourceReader.hpp" +#include + #include "Runtime/Character/CBoolPOINode.hpp" #include "Runtime/Character/CFBStreamedAnimReader.hpp" #include "Runtime/Character/CInt32POINode.hpp" @@ -27,27 +29,33 @@ CCharAnimTime CAnimSourceInfo::GetAnimationDuration() const { return x4_token->G std::set> CAnimSourceReaderBase::GetUniqueParticlePOIs() const { const std::vector& particleNodes = x4_sourceInfo->GetParticlePOIStream(); std::set> ret; - for (const CParticlePOINode& node : particleNodes) - if (node.GetUnique()) - ret.insert(std::make_pair(std::string(node.GetString()), node.GetIndex())); + for (const CParticlePOINode& node : particleNodes) { + if (node.GetUnique()) { + ret.emplace(node.GetString(), node.GetIndex()); + } + } return ret; } std::set> CAnimSourceReaderBase::GetUniqueInt32POIs() const { const std::vector& int32Nodes = x4_sourceInfo->GetInt32POIStream(); std::set> ret; - for (const CInt32POINode& node : int32Nodes) - if (node.GetUnique()) - ret.insert(std::make_pair(std::string(node.GetString()), node.GetIndex())); + for (const CInt32POINode& node : int32Nodes) { + if (node.GetUnique()) { + ret.emplace(node.GetString(), node.GetIndex()); + } + } return ret; } std::set> CAnimSourceReaderBase::GetUniqueBoolPOIs() const { const std::vector& boolNodes = x4_sourceInfo->GetBoolPOIStream(); std::set> ret; - for (const CBoolPOINode& node : boolNodes) - if (node.GetUnique()) - ret.insert(std::make_pair(std::string(node.GetString()), node.GetIndex())); + for (const CBoolPOINode& node : boolNodes) { + if (node.GetUnique()) { + ret.emplace(node.GetString(), node.GetIndex()); + } + } return ret; } @@ -164,25 +172,37 @@ u32 CAnimSourceReaderBase::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOI return 0; } -bool CAnimSourceReaderBase::VGetBoolPOIState(const char* name) const { - for (const auto& node : x24_boolStates) - if (node.first == name) - return node.second; - return false; +bool CAnimSourceReaderBase::VGetBoolPOIState(std::string_view name) const { + const auto iter = std::find_if(x24_boolStates.cbegin(), x24_boolStates.cend(), + [name](const auto& entry) { return entry.first == name; }); + + if (iter == x24_boolStates.cend()) { + return false; + } + + return iter->second; } -s32 CAnimSourceReaderBase::VGetInt32POIState(const char* name) const { - for (const auto& node : x34_int32States) - if (node.first == name) - return node.second; - return 0; +s32 CAnimSourceReaderBase::VGetInt32POIState(std::string_view name) const { + const auto iter = std::find_if(x34_int32States.cbegin(), x34_int32States.cend(), + [name](const auto& entry) { return entry.first == name; }); + + if (iter == x34_int32States.cend()) { + return 0; + } + + return iter->second; } -CParticleData::EParentedMode CAnimSourceReaderBase::VGetParticlePOIState(const char* name) const { - for (const auto& node : x44_particleStates) - if (node.first == name) - return node.second; - return CParticleData::EParentedMode::Initial; +CParticleData::EParentedMode CAnimSourceReaderBase::VGetParticlePOIState(std::string_view name) const { + const auto iter = std::find_if(x44_particleStates.cbegin(), x44_particleStates.cend(), + [name](const auto& entry) { return entry.first == name; }); + + if (iter == x44_particleStates.cend()) { + return CParticleData::EParentedMode::Initial; + } + + return iter->second; } CAnimSourceReaderBase::CAnimSourceReaderBase(std::unique_ptr&& sourceInfo, const CCharAnimTime& time) diff --git a/Runtime/Character/CAnimSourceReader.hpp b/Runtime/Character/CAnimSourceReader.hpp index 5b55e5fb7..2628f3655 100644 --- a/Runtime/Character/CAnimSourceReader.hpp +++ b/Runtime/Character/CAnimSourceReader.hpp @@ -68,9 +68,9 @@ public: u32) const override; u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator, u32) const override; - bool VGetBoolPOIState(const char* name) const override; - s32 VGetInt32POIState(const char* name) const override; - CParticleData::EParentedMode VGetParticlePOIState(const char* name) const override; + bool VGetBoolPOIState(std::string_view name) const override; + s32 VGetInt32POIState(std::string_view name) const override; + CParticleData::EParentedMode VGetParticlePOIState(std::string_view name) const override; using IAnimReader::VGetOffset; virtual zeus::CVector3f VGetOffset(const CSegId& seg, const CCharAnimTime& b) const = 0; diff --git a/Runtime/Character/CAnimTreeAnimReaderContainer.cpp b/Runtime/Character/CAnimTreeAnimReaderContainer.cpp index a7105b6ab..f508095a8 100644 --- a/Runtime/Character/CAnimTreeAnimReaderContainer.cpp +++ b/Runtime/Character/CAnimTreeAnimReaderContainer.cpp @@ -58,15 +58,15 @@ u32 CAnimTreeAnimReaderContainer::VGetSoundPOIList(const CCharAnimTime& time, CS return x14_reader->GetSoundPOIList(time, listOut, capacity, iterator, unk); } -bool CAnimTreeAnimReaderContainer::VGetBoolPOIState(const char* name) const { +bool CAnimTreeAnimReaderContainer::VGetBoolPOIState(std::string_view name) const { return x14_reader->VGetBoolPOIState(name); } -s32 CAnimTreeAnimReaderContainer::VGetInt32POIState(const char* name) const { - return x14_reader->VGetBoolPOIState(name); +s32 CAnimTreeAnimReaderContainer::VGetInt32POIState(std::string_view name) const { + return x14_reader->VGetInt32POIState(name); } -CParticleData::EParentedMode CAnimTreeAnimReaderContainer::VGetParticlePOIState(const char* name) const { +CParticleData::EParentedMode CAnimTreeAnimReaderContainer::VGetParticlePOIState(std::string_view name) const { return x14_reader->VGetParticlePOIState(name); } diff --git a/Runtime/Character/CAnimTreeAnimReaderContainer.hpp b/Runtime/Character/CAnimTreeAnimReaderContainer.hpp index aec904573..5df66319e 100644 --- a/Runtime/Character/CAnimTreeAnimReaderContainer.hpp +++ b/Runtime/Character/CAnimTreeAnimReaderContainer.hpp @@ -37,9 +37,9 @@ public: u32) const override; u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator, u32) const override; - bool VGetBoolPOIState(const char*) const override; - s32 VGetInt32POIState(const char*) const override; - CParticleData::EParentedMode VGetParticlePOIState(const char*) const override; + bool VGetBoolPOIState(std::string_view name) const override; + s32 VGetInt32POIState(std::string_view name) const override; + CParticleData::EParentedMode VGetParticlePOIState(std::string_view name) const override; void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const override; void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const override; std::unique_ptr VClone() const override; diff --git a/Runtime/Character/CAnimTreeDoubleChild.cpp b/Runtime/Character/CAnimTreeDoubleChild.cpp index 5c3b1e69f..bd401390a 100644 --- a/Runtime/Character/CAnimTreeDoubleChild.cpp +++ b/Runtime/Character/CAnimTreeDoubleChild.cpp @@ -101,11 +101,11 @@ u32 CAnimTreeDoubleChild::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOIN return newCapacity; } -bool CAnimTreeDoubleChild::VGetBoolPOIState(const char* name) const { return x18_b->VGetBoolPOIState(name); } +bool CAnimTreeDoubleChild::VGetBoolPOIState(std::string_view name) const { return x18_b->VGetBoolPOIState(name); } -s32 CAnimTreeDoubleChild::VGetInt32POIState(const char* name) const { return x18_b->VGetBoolPOIState(name); } +s32 CAnimTreeDoubleChild::VGetInt32POIState(std::string_view name) const { return x18_b->VGetInt32POIState(name); } -CParticleData::EParentedMode CAnimTreeDoubleChild::VGetParticlePOIState(const char* name) const { +CParticleData::EParentedMode CAnimTreeDoubleChild::VGetParticlePOIState(std::string_view name) const { return x18_b->VGetParticlePOIState(name); } diff --git a/Runtime/Character/CAnimTreeDoubleChild.hpp b/Runtime/Character/CAnimTreeDoubleChild.hpp index 22c4b36e2..aa54957c9 100644 --- a/Runtime/Character/CAnimTreeDoubleChild.hpp +++ b/Runtime/Character/CAnimTreeDoubleChild.hpp @@ -41,9 +41,9 @@ public: u32) const override; u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator, u32) const override; - bool VGetBoolPOIState(const char* name) const override; - s32 VGetInt32POIState(const char* name) const override; - CParticleData::EParentedMode VGetParticlePOIState(const char* name) const override; + bool VGetBoolPOIState(std::string_view name) const override; + s32 VGetInt32POIState(std::string_view name) const override; + CParticleData::EParentedMode VGetParticlePOIState(std::string_view name) const override; void VSetPhase(float) override; SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const override; u32 Depth() const override; diff --git a/Runtime/Character/CAnimTreeNode.hpp b/Runtime/Character/CAnimTreeNode.hpp index 61906c067..d18b94eb9 100644 --- a/Runtime/Character/CAnimTreeNode.hpp +++ b/Runtime/Character/CAnimTreeNode.hpp @@ -14,7 +14,7 @@ protected: std::string x4_name; public: - CAnimTreeNode(std::string_view name) : x4_name(name) {} + explicit CAnimTreeNode(std::string_view name) : x4_name(name) {} bool IsCAnimTreeNode() const override { return true; } static std::shared_ptr Cast(std::unique_ptr&& ptr) { if (ptr->IsCAnimTreeNode()) diff --git a/Runtime/Character/CAnimTreeSingleChild.cpp b/Runtime/Character/CAnimTreeSingleChild.cpp index a7c9bf851..258225459 100644 --- a/Runtime/Character/CAnimTreeSingleChild.cpp +++ b/Runtime/Character/CAnimTreeSingleChild.cpp @@ -35,11 +35,11 @@ u32 CAnimTreeSingleChild::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOIN return x14_child->GetSoundPOIList(time, listOut, capacity, iterator, unk); } -bool CAnimTreeSingleChild::VGetBoolPOIState(const char* name) const { return x14_child->VGetBoolPOIState(name); } +bool CAnimTreeSingleChild::VGetBoolPOIState(std::string_view name) const { return x14_child->VGetBoolPOIState(name); } -s32 CAnimTreeSingleChild::VGetInt32POIState(const char* name) const { return x14_child->VGetInt32POIState(name); } +s32 CAnimTreeSingleChild::VGetInt32POIState(std::string_view name) const { return x14_child->VGetInt32POIState(name); } -CParticleData::EParentedMode CAnimTreeSingleChild::VGetParticlePOIState(const char* name) const { +CParticleData::EParentedMode CAnimTreeSingleChild::VGetParticlePOIState(std::string_view name) const { return x14_child->VGetParticlePOIState(name); } diff --git a/Runtime/Character/CAnimTreeSingleChild.hpp b/Runtime/Character/CAnimTreeSingleChild.hpp index 1158de80e..801ef9e97 100644 --- a/Runtime/Character/CAnimTreeSingleChild.hpp +++ b/Runtime/Character/CAnimTreeSingleChild.hpp @@ -27,9 +27,9 @@ public: u32) const override; u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator, u32) const override; - bool VGetBoolPOIState(const char* name) const override; - s32 VGetInt32POIState(const char* name) const override; - CParticleData::EParentedMode VGetParticlePOIState(const char* name) const override; + bool VGetBoolPOIState(std::string_view name) const override; + s32 VGetInt32POIState(std::string_view name) const override; + CParticleData::EParentedMode VGetParticlePOIState(std::string_view name) const override; void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const override; void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const override; void VSetPhase(float) override; diff --git a/Runtime/Character/CAnimTreeTimeScale.cpp b/Runtime/Character/CAnimTreeTimeScale.cpp index dbf5a754f..c1651e289 100644 --- a/Runtime/Character/CAnimTreeTimeScale.cpp +++ b/Runtime/Character/CAnimTreeTimeScale.cpp @@ -99,11 +99,11 @@ u32 CAnimTreeTimeScale::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINod return ret; } -bool CAnimTreeTimeScale::VGetBoolPOIState(const char* name) const { return x14_child->VGetBoolPOIState(name); } +bool CAnimTreeTimeScale::VGetBoolPOIState(std::string_view name) const { return x14_child->VGetBoolPOIState(name); } -s32 CAnimTreeTimeScale::VGetInt32POIState(const char* name) const { return x14_child->VGetInt32POIState(name); } +s32 CAnimTreeTimeScale::VGetInt32POIState(std::string_view name) const { return x14_child->VGetInt32POIState(name); } -CParticleData::EParentedMode CAnimTreeTimeScale::VGetParticlePOIState(const char* name) const { +CParticleData::EParentedMode CAnimTreeTimeScale::VGetParticlePOIState(std::string_view name) const { return x14_child->VGetParticlePOIState(name); } diff --git a/Runtime/Character/CAnimTreeTimeScale.hpp b/Runtime/Character/CAnimTreeTimeScale.hpp index a4ba6d016..7439b55de 100644 --- a/Runtime/Character/CAnimTreeTimeScale.hpp +++ b/Runtime/Character/CAnimTreeTimeScale.hpp @@ -34,9 +34,9 @@ public: u32) const override; u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator, u32) const override; - bool VGetBoolPOIState(const char* name) const override; - s32 VGetInt32POIState(const char* name) const override; - CParticleData::EParentedMode VGetParticlePOIState(const char* name) const override; + bool VGetBoolPOIState(std::string_view name) const override; + s32 VGetInt32POIState(std::string_view name) const override; + CParticleData::EParentedMode VGetParticlePOIState(std::string_view name) const override; CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const override; std::shared_ptr VGetBestUnblendedChild() const override; diff --git a/Runtime/Character/CAnimation.hpp b/Runtime/Character/CAnimation.hpp index 228284130..be592bbb4 100644 --- a/Runtime/Character/CAnimation.hpp +++ b/Runtime/Character/CAnimation.hpp @@ -14,7 +14,7 @@ class CAnimation { std::shared_ptr x10_anim; public: - CAnimation(CInputStream& in); + explicit CAnimation(CInputStream& in); const std::shared_ptr& GetMetaAnim() const { return x10_anim; } std::string_view GetMetaAnimName() const { return x0_name; } }; diff --git a/Runtime/Character/CAnimationDatabase.hpp b/Runtime/Character/CAnimationDatabase.hpp index 0d7d98c71..93f4c19e2 100644 --- a/Runtime/Character/CAnimationDatabase.hpp +++ b/Runtime/Character/CAnimationDatabase.hpp @@ -12,6 +12,7 @@ class IMetaAnim; class CAnimationDatabase { public: + virtual ~CAnimationDatabase() = default; virtual const std::shared_ptr& GetMetaAnim(s32) const = 0; virtual u32 GetNumMetaAnims() const = 0; virtual const char* GetMetaAnimName(s32) const = 0; diff --git a/Runtime/Character/CAnimationDatabaseGame.hpp b/Runtime/Character/CAnimationDatabaseGame.hpp index 9d28a708c..f4051b01a 100644 --- a/Runtime/Character/CAnimationDatabaseGame.hpp +++ b/Runtime/Character/CAnimationDatabaseGame.hpp @@ -12,7 +12,7 @@ class CAnimationDatabaseGame final : public CAnimationDatabase { std::vector> x10_anims; public: - CAnimationDatabaseGame(const std::vector& anims); + explicit CAnimationDatabaseGame(const std::vector& anims); const std::shared_ptr& GetMetaAnim(s32 idx) const override; u32 GetNumMetaAnims() const override; const char* GetMetaAnimName(s32 idx) const override; diff --git a/Runtime/Character/CAnimationSet.hpp b/Runtime/Character/CAnimationSet.hpp index c7b58929b..55ae41fba 100644 --- a/Runtime/Character/CAnimationSet.hpp +++ b/Runtime/Character/CAnimationSet.hpp @@ -24,7 +24,7 @@ class CAnimationSet { std::vector> x50_animRes; public: - CAnimationSet(CInputStream& in); + explicit CAnimationSet(CInputStream& in); const std::vector& GetAnimations() const { return x4_animations; } const std::vector& GetTransitions() const { return x14_transitions; } diff --git a/Runtime/Character/CBodyController.cpp b/Runtime/Character/CBodyController.cpp index a13feb6cd..ddd92cf35 100644 --- a/Runtime/Character/CBodyController.cpp +++ b/Runtime/Character/CBodyController.cpp @@ -17,7 +17,9 @@ CBodyController::CBodyController(CActor& actor, float turnSpeed, EBodyType bodyT x2a4_bodyStateInfo.x18_bodyController = this; } -void CBodyController::EnableAnimation(bool e) { x0_actor.GetModelData()->GetAnimationData()->EnableAnimation(e); } +void CBodyController::EnableAnimation(bool enable) { + x0_actor.GetModelData()->GetAnimationData()->EnableAnimation(enable); +} void CBodyController::Activate(CStateManager& mgr) { x300_25_active = true; @@ -61,7 +63,7 @@ void CBodyController::UpdateBody(float dt, CStateManager& mgr) { } } -void CBodyController::SetTurnSpeed(float s) { x2fc_turnSpeed = std::max(0.f, s); } +void CBodyController::SetTurnSpeed(float speed) { x2fc_turnSpeed = std::max(0.f, speed); } void CBodyController::Update(float dt, CStateManager& mgr) { SetPlaybackRate(1.f); @@ -76,7 +78,7 @@ void CBodyController::Update(float dt, CStateManager& mgr) { } } -bool CBodyController::HasBodyState(pas::EAnimationState s) const { return GetPASDatabase().HasState(s32(s)); } +bool CBodyController::HasBodyState(pas::EAnimationState state) const { return GetPASDatabase().HasState(s32(state)); } void CBodyController::SetCurrentAnimation(const CAnimPlaybackParms& parms, bool loop, bool noTrans) { x0_actor.GetModelData()->GetAnimationData()->SetAnimation(parms, noTrans); @@ -88,14 +90,18 @@ float CBodyController::GetAnimTimeRemaining() const { return x0_actor.GetModelData()->GetAnimationData()->GetAnimTimeRemaining("Whole Body"); } -void CBodyController::SetPlaybackRate(float r) { x0_actor.GetModelData()->GetAnimationData()->SetPlaybackRate(r); } +void CBodyController::SetPlaybackRate(float rate) { + x0_actor.GetModelData()->GetAnimationData()->SetPlaybackRate(rate); +} // GX uses a HW approximation of 3/8 + 5/8 instead of 1/3 + 2/3. const CPASDatabase& CBodyController::GetPASDatabase() const { return x0_actor.GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase(); } -void CBodyController::MultiplyPlaybackRate(float r) { x0_actor.GetModelData()->GetAnimationData()->MultiplyPlaybackRate(r); } +void CBodyController::MultiplyPlaybackRate(float mul) { + x0_actor.GetModelData()->GetAnimationData()->MultiplyPlaybackRate(mul); +} void CBodyController::FaceDirection(const zeus::CVector3f& v0, float dt) { if (x300_26_frozen) @@ -136,8 +142,8 @@ void CBodyController::FaceDirection3D(const zeus::CVector3f& v0, const zeus::CVe } } -bool CBodyController::HasBodyInfo(CActor& act) { - return act.GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase().GetNumAnimStates() != 0; +bool CBodyController::HasBodyInfo(const CActor& actor) { + return actor.GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase().GetNumAnimStates() != 0; } void CBodyController::PlayBestAnimation(const CPASAnimParmData& parms, CRandom16& r) { @@ -201,8 +207,8 @@ float CBodyController::GetPercentageFrozen() const { return 1.f - (x310_timeFrozen - (x308_frozenDur + x304_intoFreezeDur)) / x30c_breakoutDur; } -void CBodyController::SetOnFire(float dur) { - x320_fireDur = dur; +void CBodyController::SetOnFire(float duration) { + x320_fireDur = duration; x328_timeOnFire = 0.f; if (IsFrozen()) UnFreeze(); @@ -215,12 +221,12 @@ void CBodyController::DouseFlames() { x328_timeOnFire = 0.f; } -void CBodyController::SetElectrocuting(float dur) { +void CBodyController::SetElectrocuting(float duration) { if (!IsElectrocuting()) { CBCAdditiveReactionCmd reaction(pas::EAdditiveReactionType::Electrocution, 1.f, true); x4_cmdMgr.DeliverCmd(reaction); } - x324_electrocutionDur = dur; + x324_electrocutionDur = duration; x32c_timeElectrocuting = 0.f; if (IsFrozen()) UnFreeze(); diff --git a/Runtime/Character/CBodyController.hpp b/Runtime/Character/CBodyController.hpp index b116c2be5..ac9839dae 100644 --- a/Runtime/Character/CBodyController.hpp +++ b/Runtime/Character/CBodyController.hpp @@ -65,39 +65,39 @@ public: pas::ELocomotionType GetLocomotionType() const { return x2ec_locomotionType; } CActor& GetOwner() const { return x0_actor; } bool IsAnimationOver() const { return x300_24_animationOver; } - void EnableAnimation(bool e); + void EnableAnimation(bool enable); bool ShouldPlayDeathAnims() const { return x300_28_playDeathAnims; } s32 GetCurrentAnimId() const { return x2f8_curAnim; } - void Activate(CStateManager&); + void Activate(CStateManager& mgr); CAdditiveBodyState* GetCurrentAdditiveState() { return x2a4_bodyStateInfo.GetCurrentAdditiveState(); } - void SetState(pas::EAnimationState s) { x2a4_bodyStateInfo.SetState(s); } - void Update(float, CStateManager&); + void SetState(pas::EAnimationState state) { x2a4_bodyStateInfo.SetState(state); } + void Update(float dt, CStateManager& mgr); bool ShouldBeHurled() const { return HasBodyState(pas::EAnimationState::Hurled); } - bool HasBodyState(pas::EAnimationState s) const; + bool HasBodyState(pas::EAnimationState state) const; pas::EFallState GetFallState() const { return x2f0_fallState; } - void SetFallState(pas::EFallState s) { x2f0_fallState = s; } - void UpdateBody(float, CStateManager&); - void SetAdditiveState(pas::EAnimationState s) { x2a4_bodyStateInfo.SetAdditiveState(s); } - void SetTurnSpeed(float s); + void SetFallState(pas::EFallState state) { x2f0_fallState = state; } + void UpdateBody(float dt, CStateManager& mgr); + void SetAdditiveState(pas::EAnimationState state) { x2a4_bodyStateInfo.SetAdditiveState(state); } + void SetTurnSpeed(float speed); void SetCurrentAnimation(const CAnimPlaybackParms& parms, bool loop, bool noTrans); float GetAnimTimeRemaining() const; - void SetPlaybackRate(float); - void MultiplyPlaybackRate(float); + void SetPlaybackRate(float rate); + void MultiplyPlaybackRate(float mul); void SetDeltaRotation(const zeus::CQuaternion& q) { x2dc_rot *= q; } - void FaceDirection(const zeus::CVector3f&, float); - void FaceDirection3D(const zeus::CVector3f&, const zeus::CVector3f&, float); - static bool HasBodyInfo(CActor& act); + void FaceDirection(const zeus::CVector3f& v0, float dt); + void FaceDirection3D(const zeus::CVector3f& v0, const zeus::CVector3f& v1, float dt); + static bool HasBodyInfo(const CActor& actor); const CPASDatabase& GetPASDatabase() const; - void PlayBestAnimation(const CPASAnimParmData&, CRandom16&); - void LoopBestAnimation(const CPASAnimParmData&, CRandom16&); + void PlayBestAnimation(const CPASAnimParmData& parms, CRandom16& r); + void LoopBestAnimation(const CPASAnimParmData& parms, CRandom16& r); void Freeze(float intoFreezeDur, float frozenDur, float breakoutDur); void UnFreeze(); float GetPercentageFrozen() const; - void SetOnFire(float); + void SetOnFire(float duration); void DouseFlames(); - void SetElectrocuting(float dur); + void SetElectrocuting(float duration); void DouseElectrocuting(); - void UpdateFrozenInfo(float, CStateManager&); + void UpdateFrozenInfo(float dt, CStateManager& mgr); bool HasIceBreakoutState() const; void StopElectrocution(); void FrozenBreakout(); @@ -105,7 +105,7 @@ public: EBodyType GetBodyType() const { return x2f4_bodyType; } bool HasBeenFrozen() const { return x300_27_hasBeenFrozen; } float GetRestrictedFlyerMoveSpeed() const { return x330_restrictedFlyerMoveSpeed; } - void SetRestrictedFlyerMoveSpeed(float s) { x330_restrictedFlyerMoveSpeed = s; } + void SetRestrictedFlyerMoveSpeed(float speed) { x330_restrictedFlyerMoveSpeed = speed; } bool GetActive() const { return x300_25_active; } }; } // namespace urde diff --git a/Runtime/Character/CBodyState.cpp b/Runtime/Character/CBodyState.cpp index a99736fe9..20a1703d9 100644 --- a/Runtime/Character/CBodyState.cpp +++ b/Runtime/Character/CBodyState.cpp @@ -11,13 +11,12 @@ namespace urde { void CBSAttack::Start(CBodyController& bc, CStateManager& mgr) { - const CBCMeleeAttackCmd* cmd = - static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)); const CPASDatabase& pasDatabase = bc.GetPASDatabase(); - CPASAnimParmData parms(7, CPASAnimParm::FromEnum(s32(cmd->GetAttackSeverity())), - CPASAnimParm::FromEnum(s32(bc.GetLocomotionType()))); - std::pair best = pasDatabase.FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CPASAnimParmData parms(7, CPASAnimParm::FromEnum(s32(cmd->GetAttackSeverity())), + CPASAnimParm::FromEnum(s32(bc.GetLocomotionType()))); + const std::pair best = pasDatabase.FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); if (cmd->HasAttackTargetPos()) { x20_targetPos = cmd->GetAttackTargetPos(); @@ -39,58 +38,74 @@ void CBSAttack::Start(CBodyController& bc, CStateManager& mgr) { x34_curTime = 0.f; } -pas::EAnimationState CBSAttack::GetBodyStateTransition(float dt, CBodyController& bc) { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSAttack::GetBodyStateTransition(float dt, const CBodyController& bc) { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) { return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) { return pas::EAnimationState::KnockBack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) { return pas::EAnimationState::Locomotion; - if (const CBCSlideCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Slide))) { + } + if (const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Slide))) { x8_slide = *cmd; x4_nextState = pas::EAnimationState::Slide; } - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Generate)) + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Generate)) { return pas::EAnimationState::Generate; + } if (bc.IsAnimationOver()) { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)) + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)) { return pas::EAnimationState::MeleeAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ProjectileAttack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ProjectileAttack)) { return pas::EAnimationState::ProjectileAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)) { return pas::EAnimationState::LoopAttack; + } return x4_nextState; } - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::NextState)) + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::NextState)) { return x4_nextState; + } return pas::EAnimationState::Invalid; } -void CBSAttack::UpdatePhysicsActor(CBodyController& bc, float dt) { - if (x20_targetPos.isZero()) +void CBSAttack::UpdatePhysicsActor(const CBodyController& bc, float dt) { + if (x20_targetPos.isZero()) { return; - if (x34_curTime >= x2c_alignTargetPosStartTime && x34_curTime <= x30_alignTargetPosTime) { - if (TCastToPtr act = bc.GetOwner()) { - zeus::CVector3f delta = x20_targetPos - act->GetTranslation(); - float dur = x30_alignTargetPosTime - x2c_alignTargetPosStartTime; - if (dur > 0.f) - delta *= zeus::CVector3f(dt / dur); - zeus::CVector3f localDelta = act->GetTransform().transposeRotate(delta); - act->ApplyImpulseWR(act->GetMoveToORImpulseWR(localDelta, dt), zeus::CAxisAngle()); + } + + if (x34_curTime < x2c_alignTargetPosStartTime || x34_curTime > x30_alignTargetPosTime) { + return; + } + + if (const TCastToPtr act = bc.GetOwner()) { + zeus::CVector3f delta = x20_targetPos - act->GetTranslation(); + const float dur = x30_alignTargetPosTime - x2c_alignTargetPosStartTime; + if (dur > 0.f) { + delta *= zeus::CVector3f(dt / dur); } + const zeus::CVector3f localDelta = act->GetTransform().transposeRotate(delta); + act->ApplyImpulseWR(act->GetMoveToORImpulseWR(localDelta, dt), zeus::CAxisAngle()); } } pas::EAnimationState CBSAttack::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { x34_curTime += dt; - pas::EAnimationState st = GetBodyStateTransition(dt, bc); + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); if (st == pas::EAnimationState::Invalid) { - if (!bc.GetCommandMgr().GetTargetVector().isZero()) + if (!bc.GetCommandMgr().GetTargetVector().isZero()) { bc.FaceDirection(bc.GetCommandMgr().GetTargetVector(), dt); + } UpdatePhysicsActor(bc, dt); } else if (st == pas::EAnimationState::Slide) { bc.GetCommandMgr().DeliverCmd(x8_slide); @@ -99,65 +114,74 @@ pas::EAnimationState CBSAttack::UpdateBody(float dt, CBodyController& bc, CState } void CBSProjectileAttack::Start(CBodyController& bc, CStateManager& mgr) { - const CBCProjectileAttackCmd* cmd = + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::ProjectileAttack)); zeus::CVector3f localDelta = bc.GetOwner().GetTransform().transposeRotate(cmd->GetTargetPosition() - bc.GetOwner().GetTranslation()); zeus::CRelAngle angle = std::atan2(localDelta.y(), localDelta.x()); angle.makeRel(); - float attackAngle = angle.asDegrees(); - CPASAnimParmData parms(18, CPASAnimParm::FromEnum(s32(cmd->GetAttackSeverity())), - CPASAnimParm::FromReal32(angle.asDegrees()), - CPASAnimParm::FromEnum(s32(bc.GetLocomotionType()))); - std::pair best1 = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const float attackAngle = angle.asDegrees(); + const CPASAnimParmData parms(18, CPASAnimParm::FromEnum(s32(cmd->GetAttackSeverity())), + CPASAnimParm::FromReal32(angle.asDegrees()), + CPASAnimParm::FromEnum(s32(bc.GetLocomotionType()))); + const std::pair best1 = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); if (cmd->BlendTwoClosest()) { - std::pair best2 = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), best1.second); + const std::pair best2 = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), best1.second); const CPASAnimState* projAttackState = bc.GetPASDatabase().GetAnimState(18); float angle1 = projAttackState->GetAnimParmData(best1.second, 1).GetReal32Value(); float angle2 = projAttackState->GetAnimParmData(best2.second, 1).GetReal32Value(); - if (angle1 - angle2 > 180.f) + if (angle1 - angle2 > 180.f) { angle2 += 360.f; - else if (angle2 - angle1 > 180.f) + } else if (angle2 - angle1 > 180.f) { angle1 += 360.f; - CAnimPlaybackParms playParms(best1.second, best2.second, (angle1 - attackAngle) / (angle1 - angle2), true); + } + const CAnimPlaybackParms playParms(best1.second, best2.second, (angle1 - attackAngle) / (angle1 - angle2), true); bc.SetCurrentAnimation(playParms, false, false); } else { - CAnimPlaybackParms playParms(best1.second, -1, 1.f, true); + const CAnimPlaybackParms playParms(best1.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); } } -pas::EAnimationState CBSProjectileAttack::GetBodyStateTransition(float dt, CBodyController& bc) { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSProjectileAttack::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) { return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) { return pas::EAnimationState::KnockBack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) { return pas::EAnimationState::Locomotion; - if (bc.IsAnimationOver() || bc.GetCommandMgr().GetCmd(EBodyStateCmd::NextState)) + } + if (bc.IsAnimationOver() || bc.GetCommandMgr().GetCmd(EBodyStateCmd::NextState)) { return pas::EAnimationState::Locomotion; + } return pas::EAnimationState::Invalid; } pas::EAnimationState CBSProjectileAttack::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); - if (st == pas::EAnimationState::Invalid) - if (!bc.GetCommandMgr().GetTargetVector().isZero()) + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); + if (st == pas::EAnimationState::Invalid) { + if (!bc.GetCommandMgr().GetTargetVector().isZero()) { bc.FaceDirection(bc.GetCommandMgr().GetTargetVector(), dt); + } + } return st; } void CBSDie::Start(CBodyController& bc, CStateManager& mgr) { bool shouldReset = true; if (bc.ShouldPlayDeathAnims()) { - CPASAnimParmData parms(4, CPASAnimParm::FromEnum(s32(bc.GetFallState()))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CPASAnimParmData parms(4, CPASAnimParm::FromEnum(s32(bc.GetFallState()))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); if (best.first > 0.f) { - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); x4_remTime = bc.GetAnimTimeRemaining(); shouldReset = false; @@ -182,25 +206,25 @@ pas::EAnimationState CBSDie::UpdateBody(float dt, CBodyController& bc, CStateMan } void CBSFall::Start(CBodyController& bc, CStateManager& mgr) { - const CBCKnockDownCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)); zeus::CVector3f localDir = bc.GetOwner().GetTransform().transposeRotate(cmd->GetHitDirection()); zeus::CRelAngle angle = std::atan2(localDir.y(), localDir.z()); angle.makeRel(); - CPASAnimParmData parms(0, CPASAnimParm::FromReal32(angle.asDegrees()), - CPASAnimParm::FromEnum(s32(cmd->GetHitSeverity()))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CPASAnimParmData parms(0, CPASAnimParm::FromReal32(angle.asDegrees()), + CPASAnimParm::FromEnum(s32(cmd->GetHitSeverity()))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); const CPASAnimState* knockdownState = bc.GetPASDatabase().GetAnimState(0); if (!knockdownState->GetAnimParmData(best.second, 2).GetBoolValue()) { - float animAngle = zeus::degToRad(knockdownState->GetAnimParmData(best.second, 0).GetReal32Value()); + const float animAngle = zeus::degToRad(knockdownState->GetAnimParmData(best.second, 0).GetReal32Value()); zeus::CRelAngle delta1 = angle - animAngle; delta1.makeRel(); zeus::CRelAngle delta2 = animAngle - angle; delta2.makeRel(); - float minAngle = std::min(float(delta1), float(delta2)); + const float minAngle = std::min(float(delta1), float(delta2)); x8_remTime = 0.15f * bc.GetAnimTimeRemaining(); - float flippedAngle = (delta1 > M_PIF) ? -minAngle : minAngle; + const float flippedAngle = (delta1 > M_PIF) ? -minAngle : minAngle; x4_rotateSpeed = (x8_remTime > FLT_EPSILON) ? flippedAngle / x8_remTime : flippedAngle; } else { x8_remTime = 0.f; @@ -209,14 +233,15 @@ void CBSFall::Start(CBodyController& bc, CStateManager& mgr) { xc_fallState = pas::EFallState(knockdownState->GetAnimParmData(best.second, 3).GetEnumValue()); } -pas::EAnimationState CBSFall::GetBodyStateTransition(float dt, CBodyController& bc) { - if (bc.IsAnimationOver()) +pas::EAnimationState CBSFall::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.IsAnimationOver()) { return pas::EAnimationState::LieOnGround; + } return pas::EAnimationState::Invalid; } pas::EAnimationState CBSFall::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); if (st == pas::EAnimationState::Invalid && x8_remTime > 0.f) { zeus::CQuaternion quat; quat.rotateZ(x4_rotateSpeed * dt); @@ -229,13 +254,13 @@ pas::EAnimationState CBSFall::UpdateBody(float dt, CBodyController& bc, CStateMa void CBSFall::Shutdown(CBodyController& bc) { bc.SetFallState(xc_fallState); } void CBSGetup::Start(CBodyController& bc, CStateManager& mgr) { - const CBCGetupCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Getup)); - CPASAnimParmData parms(1, CPASAnimParm::FromEnum(s32(bc.GetFallState())), - CPASAnimParm::FromEnum(s32(cmd->GetGetupType()))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Getup)); + const CPASAnimParmData parms(1, CPASAnimParm::FromEnum(s32(bc.GetFallState())), + CPASAnimParm::FromEnum(s32(cmd->GetGetupType()))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); if (best.first > FLT_EPSILON) { if (best.second != bc.GetCurrentAnimId()) { - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); } x4_fallState = pas::EFallState(bc.GetPASDatabase().GetAnimState(1)->GetAnimParmData(best.second, 2).GetEnumValue()); @@ -244,14 +269,17 @@ void CBSGetup::Start(CBodyController& bc, CStateManager& mgr) { } } -pas::EAnimationState CBSGetup::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSGetup::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; + } if (bc.IsAnimationOver()) { - if (x4_fallState == pas::EFallState::Zero) + if (x4_fallState == pas::EFallState::Zero) { return pas::EAnimationState::Locomotion; + } return pas::EAnimationState::Getup; } return pas::EAnimationState::Invalid; @@ -264,24 +292,24 @@ pas::EAnimationState CBSGetup::UpdateBody(float dt, CBodyController& bc, CStateM void CBSGetup::Shutdown(CBodyController& bc) { bc.SetFallState(x4_fallState); } void CBSKnockBack::Start(CBodyController& bc, CStateManager& mgr) { - const CBCKnockBackCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)); - zeus::CVector3f localDir = bc.GetOwner().GetTransform().transposeRotate(cmd->GetHitDirection()); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)); + const zeus::CVector3f localDir = bc.GetOwner().GetTransform().transposeRotate(cmd->GetHitDirection()); zeus::CRelAngle angle = std::atan2(localDir.y(), localDir.x()); angle.makeRel(); - CPASAnimParmData parms(6, CPASAnimParm::FromReal32(angle.asDegrees()), - CPASAnimParm::FromEnum(s32(cmd->GetHitSeverity()))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CPASAnimParmData parms(6, CPASAnimParm::FromReal32(angle.asDegrees()), + CPASAnimParm::FromEnum(s32(cmd->GetHitSeverity()))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); const CPASAnimState* knockbackState = bc.GetPASDatabase().GetAnimState(6); if (!knockbackState->GetAnimParmData(best.second, 2).GetBoolValue()) { - float animAngle = zeus::degToRad(knockbackState->GetAnimParmData(best.second, 0).GetReal32Value()); + const float animAngle = zeus::degToRad(knockbackState->GetAnimParmData(best.second, 0).GetReal32Value()); zeus::CRelAngle delta1 = angle - animAngle; delta1.makeRel(); zeus::CRelAngle delta2 = animAngle - angle; delta2.makeRel(); - float minAngle = std::min(float(delta1), float(delta2)); - float flippedAngle = (delta1 > M_PIF) ? -minAngle : minAngle; + const float minAngle = std::min(float(delta1), float(delta2)); + const float flippedAngle = (delta1 > M_PIF) ? -minAngle : minAngle; xc_remTime = 0.15f * bc.GetAnimTimeRemaining(); x8_rotateSpeed = (xc_remTime > FLT_EPSILON) ? flippedAngle / xc_remTime : flippedAngle; } else { @@ -291,22 +319,27 @@ void CBSKnockBack::Start(CBodyController& bc, CStateManager& mgr) { x4_curTime = 0.f; } -pas::EAnimationState CBSKnockBack::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSKnockBack::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) { return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack) && x4_curTime > 0.2f) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack) && x4_curTime > 0.2f) { return pas::EAnimationState::KnockBack; - if (bc.IsAnimationOver()) + } + if (bc.IsAnimationOver()) { return pas::EAnimationState::Locomotion; + } return pas::EAnimationState::Invalid; } pas::EAnimationState CBSKnockBack::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); if (st == pas::EAnimationState::Invalid) { x4_curTime += dt; if (xc_remTime > 0.f) { @@ -324,23 +357,26 @@ CBSLieOnGround::CBSLieOnGround(CActor& actor) { } void CBSLieOnGround::Start(CBodyController& bc, CStateManager& mgr) { - CPASAnimParmData parms(2, CPASAnimParm::FromEnum(s32(bc.GetFallState()))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CPASAnimParmData parms(2, CPASAnimParm::FromEnum(s32(bc.GetFallState()))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); if (best.first > 0.f) { - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, true, false); } else { bc.EnableAnimation(false); } } -pas::EAnimationState CBSLieOnGround::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Die)) +pas::EAnimationState CBSLieOnGround::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Die)) { return pas::EAnimationState::Death; - if (x4_24_hasGroundHit && bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) + } + if (x4_24_hasGroundHit && bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) { return pas::EAnimationState::GroundHit; - if (!bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion) && bc.GetCommandMgr().GetCmd(EBodyStateCmd::Getup)) + } + if (!bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion) && bc.GetCommandMgr().GetCmd(EBodyStateCmd::Getup)) { return pas::EAnimationState::Getup; + } return pas::EAnimationState::Invalid; } @@ -351,116 +387,149 @@ pas::EAnimationState CBSLieOnGround::UpdateBody(float dt, CBodyController& bc, C void CBSLieOnGround::Shutdown(CBodyController& bc) { bc.EnableAnimation(true); } void CBSStep::Start(CBodyController& bc, CStateManager& mgr) { - const CBCStepCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Step)); - CPASAnimParmData parms(3, CPASAnimParm::FromEnum(s32(cmd->GetStepDirection())), - CPASAnimParm::FromEnum(s32(cmd->GetStepType()))); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Step)); + const CPASAnimParmData parms(3, CPASAnimParm::FromEnum(s32(cmd->GetStepDirection())), + CPASAnimParm::FromEnum(s32(cmd->GetStepType()))); bc.PlayBestAnimation(parms, *mgr.GetActiveRandom()); } -pas::EAnimationState CBSStep::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSStep::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) { return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) { return pas::EAnimationState::KnockBack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) { return pas::EAnimationState::Locomotion; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Generate)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Generate)) { return pas::EAnimationState::Generate; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)) { return pas::EAnimationState::MeleeAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ProjectileAttack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ProjectileAttack)) { return pas::EAnimationState::ProjectileAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)) { return pas::EAnimationState::LoopAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Jump)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Jump)) { return pas::EAnimationState::Jump; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopReaction)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopReaction)) { return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Scripted)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Scripted)) { return pas::EAnimationState::Scripted; - if (bc.IsAnimationOver() || bc.GetCommandMgr().GetCmd(EBodyStateCmd::NextState)) + } + if (bc.IsAnimationOver() || bc.GetCommandMgr().GetCmd(EBodyStateCmd::NextState)) { return pas::EAnimationState::Locomotion; + } return pas::EAnimationState::Invalid; } pas::EAnimationState CBSStep::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); - if (st == pas::EAnimationState::Invalid && !bc.GetCommandMgr().GetTargetVector().isZero()) + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); + if (st == pas::EAnimationState::Invalid && !bc.GetCommandMgr().GetTargetVector().isZero()) { bc.FaceDirection(bc.GetCommandMgr().GetTargetVector(), dt); + } return st; } void CBSTurn::Start(CBodyController& bc, CStateManager& mgr) { const zeus::CVector3f& lookDir = bc.GetOwner().GetTransform().basis[1]; - zeus::CVector2f lookDir2d(lookDir.toVec2f()); + const zeus::CVector2f lookDir2d(lookDir.toVec2f()); x8_dest = zeus::CVector2f(bc.GetCommandMgr().GetFaceVector().toVec2f()); - float deltaAngle = zeus::radToDeg(zeus::CVector2f::getAngleDiff(lookDir2d, x8_dest)); + const float deltaAngle = zeus::radToDeg(zeus::CVector2f::getAngleDiff(lookDir2d, x8_dest)); x10_turnDir = pas::ETurnDirection(zeus::CVector2f(lookDir2d.y(), -lookDir2d.x()).dot(x8_dest) > 0.f); - CPASAnimParmData parms(8, CPASAnimParm::FromEnum(s32(x10_turnDir)), CPASAnimParm::FromReal32(deltaAngle), - CPASAnimParm::FromEnum(s32(bc.GetLocomotionType()))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CPASAnimParmData parms(8, CPASAnimParm::FromEnum(s32(x10_turnDir)), CPASAnimParm::FromReal32(deltaAngle), + CPASAnimParm::FromEnum(s32(bc.GetLocomotionType()))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); - float animAngle = bc.GetPASDatabase().GetAnimState(8)->GetAnimParmData(best.second, 1).GetReal32Value(); + const float animAngle = bc.GetPASDatabase().GetAnimState(8)->GetAnimParmData(best.second, 1).GetReal32Value(); x4_rotateSpeed = zeus::degToRad((x10_turnDir == pas::ETurnDirection::Left) ? animAngle - deltaAngle : deltaAngle - animAngle); - float timeRem = bc.GetAnimTimeRemaining(); - if (timeRem > 0.f) + const float timeRem = bc.GetAnimTimeRemaining(); + if (timeRem > 0.f) { x4_rotateSpeed /= timeRem; + } } -bool CBSTurn::FacingDest(CBodyController& bc) const { +bool CBSTurn::FacingDest(const CBodyController& bc) const { const zeus::CVector3f& lookDir = bc.GetOwner().GetTransform().basis[1]; - zeus::CVector2f lookDir2d(lookDir.toVec2f()); - zeus::CVector2f leftDir(lookDir2d.y(), -lookDir2d.x()); + const zeus::CVector2f lookDir2d(lookDir.toVec2f()); + const zeus::CVector2f leftDir(lookDir2d.y(), -lookDir2d.x()); + if (x10_turnDir == pas::ETurnDirection::Left) { - if (leftDir.dot(x8_dest) < 0.f) + if (leftDir.dot(x8_dest) < 0.f) { return true; + } } else { - if (leftDir.dot(x8_dest) > 0.f) + if (leftDir.dot(x8_dest) > 0.f) { return true; + } } + return false; } pas::EAnimationState CBSTurn::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) { return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) { return pas::EAnimationState::KnockBack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) { return pas::EAnimationState::Locomotion; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Generate)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Generate)) { return pas::EAnimationState::Generate; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)) { return pas::EAnimationState::MeleeAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ProjectileAttack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ProjectileAttack)) { return pas::EAnimationState::ProjectileAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)) { return pas::EAnimationState::LoopAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopReaction)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopReaction)) { return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Jump)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Jump)) { return pas::EAnimationState::Jump; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Step)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Step)) { return pas::EAnimationState::Step; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Scripted)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Scripted)) { return pas::EAnimationState::Scripted; - if (bc.IsAnimationOver() || FacingDest(bc) || !bc.GetCommandMgr().GetMoveVector().isZero()) + } + if (bc.IsAnimationOver() || FacingDest(bc) || !bc.GetCommandMgr().GetMoveVector().isZero()) { return pas::EAnimationState::Locomotion; + } return pas::EAnimationState::Invalid; } pas::EAnimationState CBSTurn::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); if (st == pas::EAnimationState::Invalid) { zeus::CQuaternion quat; quat.rotateZ(x4_rotateSpeed * dt); @@ -470,94 +539,110 @@ pas::EAnimationState CBSTurn::UpdateBody(float dt, CBodyController& bc, CStateMa } void CBSFlyerTurn::Start(CBodyController& bc, CStateManager& mgr) { - if (bc.GetPASDatabase().GetAnimState(8)->GetNumAnims()) { + if (bc.GetPASDatabase().GetAnimState(8)->HasAnims()) { CBSTurn::Start(bc, mgr); } else { x8_dest = zeus::CVector2f(bc.GetCommandMgr().GetFaceVector().toVec2f()); const zeus::CVector3f& lookDir = bc.GetOwner().GetTransform().basis[1]; - zeus::CVector2f lookDir2d(lookDir.toVec2f()); + const zeus::CVector2f lookDir2d(lookDir.toVec2f()); x10_turnDir = pas::ETurnDirection(zeus::CVector2f(lookDir2d.y(), -lookDir2d.x()).dot(x8_dest) > 0.f); - CPASAnimParmData parms(5, CPASAnimParm::FromEnum(0), CPASAnimParm::FromEnum(s32(bc.GetLocomotionType()))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CPASAnimParmData parms(5, CPASAnimParm::FromEnum(0), CPASAnimParm::FromEnum(s32(bc.GetLocomotionType()))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); if (best.second != bc.GetCurrentAnimId()) { - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, true, false); } } } pas::EAnimationState CBSFlyerTurn::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - if (bc.GetPASDatabase().GetAnimState(8)->GetNumAnims()) { + if (bc.GetPASDatabase().GetAnimState(8)->HasAnims()) { return CBSTurn::UpdateBody(dt, bc, mgr); - } else { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); - if (st == pas::EAnimationState::Invalid) { - if (!bc.GetCommandMgr().GetFaceVector().isZero()) { - x8_dest = zeus::CVector2f(bc.GetCommandMgr().GetFaceVector().toVec2f()); - const zeus::CVector3f& lookDir = bc.GetOwner().GetTransform().basis[1]; - zeus::CVector2f lookDir2d(lookDir.toVec2f()); - x10_turnDir = pas::ETurnDirection(zeus::CVector2f(lookDir2d.y(), -lookDir2d.x()).dot(x8_dest) > 0.f); - } - bc.FaceDirection(zeus::CVector3f(x8_dest.x(), x8_dest.y(), 0.f), dt); - } - return st; } + + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); + if (st == pas::EAnimationState::Invalid) { + if (!bc.GetCommandMgr().GetFaceVector().isZero()) { + x8_dest = zeus::CVector2f(bc.GetCommandMgr().GetFaceVector().toVec2f()); + const zeus::CVector3f& lookDir = bc.GetOwner().GetTransform().basis[1]; + const zeus::CVector2f lookDir2d(lookDir.toVec2f()); + x10_turnDir = pas::ETurnDirection(zeus::CVector2f(lookDir2d.y(), -lookDir2d.x()).dot(x8_dest) > 0.f); + } + bc.FaceDirection(zeus::CVector3f(x8_dest.x(), x8_dest.y(), 0.f), dt); + } + return st; } void CBSLoopAttack::Start(CBodyController& bc, CStateManager& mgr) { - const CBCLoopAttackCmd* cmd = - static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)); x8_loopAttackType = cmd->GetAttackType(); xc_24_waitForAnimOver = cmd->WaitForAnimOver(); xc_25_advance = false; + if (bc.GetLocomotionType() == pas::ELocomotionType::Crouch) { - CPASAnimParmData parms(9, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_loopAttackType))); + const CPASAnimParmData parms(9, CPASAnimParm::FromEnum(s32(x4_state)), + CPASAnimParm::FromEnum(s32(x8_loopAttackType))); bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); } else { x4_state = pas::ELoopState::Begin; - CPASAnimParmData parms(9, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_loopAttackType))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CPASAnimParmData parms(9, CPASAnimParm::FromEnum(s32(x4_state)), + CPASAnimParm::FromEnum(s32(x8_loopAttackType))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); if (best.first > FLT_EPSILON) { - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); } else { x4_state = pas::ELoopState::Loop; - CPASAnimParmData parms(9, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_loopAttackType))); - bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); + const CPASAnimParmData loopParms(9, CPASAnimParm::FromEnum(s32(x4_state)), + CPASAnimParm::FromEnum(s32(x8_loopAttackType))); + bc.LoopBestAnimation(loopParms, *mgr.GetActiveRandom()); } } } -pas::EAnimationState CBSLoopAttack::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSLoopAttack::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) - return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) - return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) - return pas::EAnimationState::KnockBack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) - return pas::EAnimationState::Locomotion; - if (x4_state == pas::ELoopState::End) { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)) - return pas::EAnimationState::MeleeAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ProjectileAttack)) - return pas::EAnimationState::ProjectileAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)) - return pas::EAnimationState::LoopAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Step)) - return pas::EAnimationState::Step; - if (!bc.GetCommandMgr().GetMoveVector().isZero()) - return pas::EAnimationState::Locomotion; - if (!bc.GetCommandMgr().GetFaceVector().isZero()) - return pas::EAnimationState::Turn; } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { + return pas::EAnimationState::Fall; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) { + return pas::EAnimationState::LoopReaction; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) { + return pas::EAnimationState::KnockBack; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) { + return pas::EAnimationState::Locomotion; + } + + if (x4_state == pas::ELoopState::End) { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)) { + return pas::EAnimationState::MeleeAttack; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ProjectileAttack)) { + return pas::EAnimationState::ProjectileAttack; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)) { + return pas::EAnimationState::LoopAttack; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Step)) { + return pas::EAnimationState::Step; + } + if (!bc.GetCommandMgr().GetMoveVector().isZero()) { + return pas::EAnimationState::Locomotion; + } + if (!bc.GetCommandMgr().GetFaceVector().isZero()) { + return pas::EAnimationState::Turn; + } + } + return pas::EAnimationState::Invalid; } pas::EAnimationState CBSLoopAttack::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); if (st == pas::EAnimationState::Invalid) { xc_25_advance |= bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState) != nullptr; switch (x4_state) { @@ -567,7 +652,7 @@ pas::EAnimationState CBSLoopAttack::UpdateBody(float dt, CBodyController& bc, CS return pas::EAnimationState::Locomotion; } if (bc.IsAnimationOver()) { - CPASAnimParmData parms(9, CPASAnimParm::FromEnum(1), CPASAnimParm::FromEnum(s32(x8_loopAttackType))); + const CPASAnimParmData parms(9, CPASAnimParm::FromEnum(1), CPASAnimParm::FromEnum(s32(x8_loopAttackType))); bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); x4_state = pas::ELoopState::Loop; } else if (!bc.GetCommandMgr().GetTargetVector().isZero()) { @@ -577,7 +662,7 @@ pas::EAnimationState CBSLoopAttack::UpdateBody(float dt, CBodyController& bc, CS case pas::ELoopState::Loop: if (xc_25_advance && (!xc_24_waitForAnimOver || bc.IsAnimationOver())) { if (bc.GetLocomotionType() != pas::ELocomotionType::Crouch) { - CPASAnimParmData parms(9, CPASAnimParm::FromEnum(2), CPASAnimParm::FromEnum(s32(x8_loopAttackType))); + const CPASAnimParmData parms(9, CPASAnimParm::FromEnum(2), CPASAnimParm::FromEnum(s32(x8_loopAttackType))); bc.PlayBestAnimation(parms, *mgr.GetActiveRandom()); x4_state = pas::ELoopState::End; } else { @@ -600,61 +685,73 @@ pas::EAnimationState CBSLoopAttack::UpdateBody(float dt, CBodyController& bc, CS } void CBSLoopReaction::Start(CBodyController& bc, CStateManager& mgr) { - if (const CBCLoopReactionCmd* cmd = + if (const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopReaction))) { x8_reactionType = cmd->GetReactionType(); xc_24_loopHit = false; } else { - const CBCLoopHitReactionCmd* hcmd = + const auto* hcmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)); x8_reactionType = hcmd->GetReactionType(); xc_24_loopHit = true; } x4_state = pas::ELoopState::Begin; - CPASAnimParmData parms(10, CPASAnimParm::FromEnum(s32(x8_reactionType)), CPASAnimParm::FromEnum(s32(x4_state))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CPASAnimParmData parms(10, CPASAnimParm::FromEnum(s32(x8_reactionType)), CPASAnimParm::FromEnum(s32(x4_state))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); if (best.first > FLT_EPSILON) { - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); } else { x4_state = pas::ELoopState::Loop; - CPASAnimParmData parms(10, CPASAnimParm::FromEnum(s32(x8_reactionType)), CPASAnimParm::FromEnum(s32(x4_state))); - bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); + const CPASAnimParmData loopParms(10, CPASAnimParm::FromEnum(s32(x8_reactionType)), + CPASAnimParm::FromEnum(s32(x4_state))); + bc.LoopBestAnimation(loopParms, *mgr.GetActiveRandom()); } } -pas::EAnimationState CBSLoopReaction::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSLoopReaction::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) { return pas::EAnimationState::KnockBack; - if (!xc_24_loopHit && bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) + } + if (!xc_24_loopHit && bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) { return pas::EAnimationState::Locomotion; + } + if (x4_state == pas::ELoopState::End) { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)) + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)) { return pas::EAnimationState::MeleeAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ProjectileAttack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ProjectileAttack)) { return pas::EAnimationState::ProjectileAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)) { return pas::EAnimationState::LoopAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Step)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Step)) { return pas::EAnimationState::Step; - if (!bc.GetCommandMgr().GetMoveVector().isZero()) + } + if (!bc.GetCommandMgr().GetMoveVector().isZero()) { return pas::EAnimationState::Locomotion; - if (!bc.GetCommandMgr().GetFaceVector().isZero()) + } + if (!bc.GetCommandMgr().GetFaceVector().isZero()) { return pas::EAnimationState::Turn; + } } return pas::EAnimationState::Invalid; } bool CBSLoopReaction::PlayExitAnimation(CBodyController& bc, CStateManager& mgr) const { - CPASAnimParmData parms(10, CPASAnimParm::FromEnum(int(x8_reactionType)), CPASAnimParm::FromEnum(2)); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CPASAnimParmData parms(10, CPASAnimParm::FromEnum(int(x8_reactionType)), CPASAnimParm::FromEnum(2)); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); if (best.first > 0.f) { - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); return true; } @@ -662,7 +759,7 @@ bool CBSLoopReaction::PlayExitAnimation(CBodyController& bc, CStateManager& mgr) } pas::EAnimationState CBSLoopReaction::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); if (st == pas::EAnimationState::Invalid) { switch (x4_state) { case pas::ELoopState::Begin: @@ -675,7 +772,7 @@ pas::EAnimationState CBSLoopReaction::UpdateBody(float dt, CBodyController& bc, } } else { if (bc.IsAnimationOver()) { - CPASAnimParmData parms(10, CPASAnimParm::FromEnum(s32(x8_reactionType)), CPASAnimParm::FromEnum(1)); + const CPASAnimParmData parms(10, CPASAnimParm::FromEnum(s32(x8_reactionType)), CPASAnimParm::FromEnum(1)); bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); x4_state = pas::ELoopState::Loop; } else if (!bc.GetCommandMgr().GetTargetVector().isZero()) { @@ -709,24 +806,24 @@ pas::EAnimationState CBSLoopReaction::UpdateBody(float dt, CBodyController& bc, } void CBSGroundHit::Start(CBodyController& bc, CStateManager& mgr) { - const CBCKnockBackCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)); - zeus::CVector3f localDir = bc.GetOwner().GetTransform().transposeRotate(cmd->GetHitDirection()); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)); + const zeus::CVector3f localDir = bc.GetOwner().GetTransform().transposeRotate(cmd->GetHitDirection()); zeus::CRelAngle angle = std::atan2(localDir.y(), localDir.x()); angle.makeRel(); - CPASAnimParmData parms(11, CPASAnimParm::FromEnum(s32(bc.GetFallState())), - CPASAnimParm::FromReal32(angle.asDegrees())); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CPASAnimParmData parms(11, CPASAnimParm::FromEnum(s32(bc.GetFallState())), + CPASAnimParm::FromReal32(angle.asDegrees())); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); const CPASAnimState* groundHitState = bc.GetPASDatabase().GetAnimState(11); if (!groundHitState->GetAnimParmData(best.second, 2).GetBoolValue()) { - float animAngle = zeus::degToRad(groundHitState->GetAnimParmData(best.second, 1).GetReal32Value()); + const float animAngle = zeus::degToRad(groundHitState->GetAnimParmData(best.second, 1).GetReal32Value()); zeus::CRelAngle delta1 = angle - animAngle; delta1.makeRel(); zeus::CRelAngle delta2 = animAngle - angle; delta2.makeRel(); - float minAngle = std::min(float(delta1), float(delta2)); - float flippedAngle = (delta1 > M_PIF) ? -minAngle : minAngle; + const float minAngle = std::min(float(delta1), float(delta2)); + const float flippedAngle = (delta1 > M_PIF) ? -minAngle : minAngle; x8_remTime = 0.15f * bc.GetAnimTimeRemaining(); x4_rotateSpeed = (x8_remTime > FLT_EPSILON) ? flippedAngle / x8_remTime : flippedAngle; } else { @@ -736,17 +833,18 @@ void CBSGroundHit::Start(CBodyController& bc, CStateManager& mgr) { xc_fallState = pas::EFallState(groundHitState->GetAnimParmData(best.second, 3).GetEnumValue()); } -pas::EAnimationState CBSGroundHit::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.IsAnimationOver()) { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Die)) - return pas::EAnimationState::Death; - return pas::EAnimationState::LieOnGround; +pas::EAnimationState CBSGroundHit::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (!bc.IsAnimationOver()) { + return pas::EAnimationState::Invalid; } - return pas::EAnimationState::Invalid; + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Die)) { + return pas::EAnimationState::Death; + } + return pas::EAnimationState::LieOnGround; } pas::EAnimationState CBSGroundHit::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); if (st == pas::EAnimationState::Invalid && x8_remTime > 0.f) { zeus::CQuaternion quat; quat.rotateZ(x4_rotateSpeed * dt); @@ -759,48 +857,54 @@ pas::EAnimationState CBSGroundHit::UpdateBody(float dt, CBodyController& bc, CSt void CBSGroundHit::Shutdown(CBodyController& bc) { bc.SetFallState(xc_fallState); } void CBSGenerate::Start(CBodyController& bc, CStateManager& mgr) { - const CBCGenerateCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Generate)); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Generate)); s32 anim; if (!cmd->UseSpecialAnimId()) { - CPASAnimParmData parms(12, CPASAnimParm::FromEnum(s32(cmd->GetGenerateType()))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CPASAnimParmData parms(12, CPASAnimParm::FromEnum(s32(cmd->GetGenerateType()))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); anim = best.second; } else { anim = cmd->GetSpecialAnimId(); } if (cmd->HasExitTargetPos()) { - CAnimPlaybackParms playParms(anim, nullptr, &cmd->GetExitTargetPos(), &bc.GetOwner().GetTransform(), - &bc.GetOwner().GetModelData()->GetScale(), false); + const CAnimPlaybackParms playParms(anim, nullptr, &cmd->GetExitTargetPos(), &bc.GetOwner().GetTransform(), + &bc.GetOwner().GetModelData()->GetScale(), false); bc.SetCurrentAnimation(playParms, false, false); } else { - CAnimPlaybackParms playParms(anim, -1, 1.f, true); + const CAnimPlaybackParms playParms(anim, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); } } -pas::EAnimationState CBSGenerate::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSGenerate::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Generate)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Generate)) { return pas::EAnimationState::Generate; - if (bc.IsAnimationOver() || bc.GetCommandMgr().GetCmd(EBodyStateCmd::NextState)) + } + if (bc.IsAnimationOver() || bc.GetCommandMgr().GetCmd(EBodyStateCmd::NextState)) { return pas::EAnimationState::Locomotion; + } return pas::EAnimationState::Invalid; } pas::EAnimationState CBSGenerate::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); - if (st == pas::EAnimationState::Invalid) - if (!bc.GetCommandMgr().GetTargetVector().isZero()) + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); + if (st == pas::EAnimationState::Invalid) { + if (!bc.GetCommandMgr().GetTargetVector().isZero()) { bc.FaceDirection(bc.GetCommandMgr().GetTargetVector(), dt); + } + } return st; } void CBSJump::Start(CBodyController& bc, CStateManager& mgr) { - const CBCJumpCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Jump)); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Jump)); x8_jumpType = cmd->GetJumpType(); xc_waypoint1 = cmd->GetJumpTarget(); x24_waypoint2 = cmd->GetSecondJumpTarget(); @@ -808,52 +912,58 @@ void CBSJump::Start(CBodyController& bc, CStateManager& mgr) { x30_28_startInJumpLoop = cmd->StartInJumpLoop(); x30_24_bodyForceSet = false; x30_27_wallBounceComplete = false; - if (x30_25_wallJump) + if (x30_25_wallJump) { x30_26_wallBounceRight = - (xc_waypoint1 - bc.GetOwner().GetTranslation()).cross(zeus::skUp).dot(x24_waypoint2 - xc_waypoint1) < - 0.f; + (xc_waypoint1 - bc.GetOwner().GetTranslation()).cross(zeus::skUp).dot(x24_waypoint2 - xc_waypoint1) < 0.f; + } if (!cmd->StartInJumpLoop()) { x4_state = pas::EJumpState::IntoJump; - CPASAnimParmData parms(13, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_jumpType))); + const CPASAnimParmData parms(13, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_jumpType))); bc.PlayBestAnimation(parms, *mgr.GetActiveRandom()); } else { PlayJumpLoop(mgr, bc); } } -pas::EAnimationState CBSJump::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSJump::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Jump) && bc.GetBodyType() == EBodyType::WallWalker) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Jump) && bc.GetBodyType() == EBodyType::WallWalker) { return pas::EAnimationState::Jump; + } return pas::EAnimationState::Invalid; } bool CBSJump::CheckForWallJump(CBodyController& bc, CStateManager& mgr) { - if (x30_25_wallJump && !x30_27_wallBounceComplete) { - if (TCastToPtr act = bc.GetOwner()) { - float distToWall = (xc_waypoint1 - act->GetTranslation()).magnitude(); - zeus::CAABox aabb = act->GetBoundingBox(); - float xExtent = (aabb.max.x() - aabb.min.x()) * 0.5f; - if (distToWall < 1.414f * xExtent || (act->MadeSolidCollision() && distToWall < 3.f * xExtent)) { - x4_state = x30_26_wallBounceRight ? pas::EJumpState::WallBounceRight : pas::EJumpState::WallBounceLeft; - CPASAnimParmData parms(13, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_jumpType))); - bc.PlayBestAnimation(parms, *mgr.GetActiveRandom()); - mgr.SendScriptMsg(act.GetPtr(), kInvalidUniqueId, EScriptObjectMessage::OnFloor); - return true; - } + if (!x30_25_wallJump || x30_27_wallBounceComplete) { + return false; + } + + if (const TCastToPtr act = bc.GetOwner()) { + const float distToWall = (xc_waypoint1 - act->GetTranslation()).magnitude(); + const zeus::CAABox aabb = act->GetBoundingBox(); + const float xExtent = (aabb.max.x() - aabb.min.x()) * 0.5f; + if (distToWall < 1.414f * xExtent || (act->MadeSolidCollision() && distToWall < 3.f * xExtent)) { + x4_state = x30_26_wallBounceRight ? pas::EJumpState::WallBounceRight : pas::EJumpState::WallBounceLeft; + const CPASAnimParmData parms(13, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_jumpType))); + bc.PlayBestAnimation(parms, *mgr.GetActiveRandom()); + mgr.SendScriptMsg(act.GetPtr(), kInvalidUniqueId, EScriptObjectMessage::OnFloor); + return true; } } + return false; } void CBSJump::CheckForLand(CBodyController& bc, CStateManager& mgr) { - if (TCastToPtr act = bc.GetOwner()) { + if (const TCastToPtr act = bc.GetOwner()) { if (act->MadeSolidCollision() || act->IsOnGround()) { x4_state = pas::EJumpState::OutOfJump; - CPASAnimParmData parms(13, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_jumpType))); + const CPASAnimParmData parms(13, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_jumpType))); bc.PlayBestAnimation(parms, *mgr.GetActiveRandom()); mgr.SendScriptMsg(act.GetPtr(), kInvalidUniqueId, EScriptObjectMessage::OnFloor); } @@ -861,19 +971,20 @@ void CBSJump::CheckForLand(CBodyController& bc, CStateManager& mgr) { } void CBSJump::PlayJumpLoop(CStateManager& mgr, CBodyController& bc) { - CPASAnimParmData parms(13, CPASAnimParm::FromEnum(1), CPASAnimParm::FromEnum(s32(x8_jumpType))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CPASAnimParmData parms(13, CPASAnimParm::FromEnum(1), CPASAnimParm::FromEnum(s32(x8_jumpType))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); if (best.first > 99.f) { x4_state = pas::EJumpState::AmbushJump; - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); } else { x4_state = pas::EJumpState::Loop; - CPASAnimParmData parms(13, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_jumpType))); - bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); + const CPASAnimParmData loopParms(13, CPASAnimParm::FromEnum(s32(x4_state)), + CPASAnimParm::FromEnum(s32(x8_jumpType))); + bc.LoopBestAnimation(loopParms, *mgr.GetActiveRandom()); } - if (TCastToPtr act = bc.GetOwner()) { + if (const TCastToPtr act = bc.GetOwner()) { mgr.SendScriptMsg(act.GetPtr(), kInvalidUniqueId, EScriptObjectMessage::Falling); mgr.SendScriptMsg(act.GetPtr(), kInvalidUniqueId, EScriptObjectMessage::Jumped); x30_24_bodyForceSet = false; @@ -882,56 +993,65 @@ void CBSJump::PlayJumpLoop(CStateManager& mgr, CBodyController& bc) { } pas::EAnimationState CBSJump::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); if (st == pas::EAnimationState::Invalid) { switch (x4_state) { case pas::EJumpState::IntoJump: - if (bc.IsAnimationOver()) + if (bc.IsAnimationOver()) { PlayJumpLoop(mgr, bc); + } break; case pas::EJumpState::AmbushJump: if (!x30_24_bodyForceSet) { - if (TCastToPtr act = bc.GetOwner()) + if (const TCastToPtr act = bc.GetOwner()) { act->SetConstantForce(act->GetMass() * x18_velocity); + } x30_24_bodyForceSet = true; } - if (!bc.GetCommandMgr().GetTargetVector().isZero()) + if (!bc.GetCommandMgr().GetTargetVector().isZero()) { bc.FaceDirection(bc.GetCommandMgr().GetTargetVector(), dt); + } if (bc.IsAnimationOver()) { x4_state = pas::EJumpState::Loop; - CPASAnimParmData parms(13, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_jumpType))); + const CPASAnimParmData parms(13, CPASAnimParm::FromEnum(s32(x4_state)), + CPASAnimParm::FromEnum(s32(x8_jumpType))); bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); } else { - if (!CheckForWallJump(bc, mgr)) + if (!CheckForWallJump(bc, mgr)) { CheckForLand(bc, mgr); + } } break; case pas::EJumpState::Loop: if (!x30_24_bodyForceSet) { - if (TCastToPtr act = bc.GetOwner()) + if (const TCastToPtr act = bc.GetOwner()) { act->SetConstantForce(act->GetMass() * x18_velocity); + } x30_24_bodyForceSet = true; } - if (!bc.GetCommandMgr().GetTargetVector().isZero()) + if (!bc.GetCommandMgr().GetTargetVector().isZero()) { bc.FaceDirection(bc.GetCommandMgr().GetTargetVector(), dt); - if (!CheckForWallJump(bc, mgr)) + } + if (!CheckForWallJump(bc, mgr)) { CheckForLand(bc, mgr); + } break; case pas::EJumpState::WallBounceLeft: case pas::EJumpState::WallBounceRight: - if (TCastToPtr act = bc.GetOwner()) { + if (const TCastToPtr act = bc.GetOwner()) { act->Stop(); act->SetMomentumWR(zeus::skZero3f); } if (bc.IsAnimationOver()) { mgr.SendScriptMsg(&bc.GetOwner(), kInvalidUniqueId, EScriptObjectMessage::Falling); x4_state = pas::EJumpState::Loop; - CPASAnimParmData parms(13, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_jumpType))); + const CPASAnimParmData parms(13, CPASAnimParm::FromEnum(s32(x4_state)), + CPASAnimParm::FromEnum(s32(x8_jumpType))); bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); x30_27_wallBounceComplete = true; - if (TCastToPtr act = bc.GetOwner()) { - zeus::CVector3f toFinal = x24_waypoint2 - act->GetTranslation(); - float tmp = std::sqrt(act->GetGravityConstant() / (2.f * toFinal.z())); + if (const TCastToPtr act = bc.GetOwner()) { + const zeus::CVector3f toFinal = x24_waypoint2 - act->GetTranslation(); + const float tmp = std::sqrt(act->GetGravityConstant() / (2.f * toFinal.z())); act->SetVelocityWR(zeus::CVector3f(tmp * toFinal.x(), tmp * toFinal.y(), 0.f)); } } @@ -950,8 +1070,9 @@ pas::EAnimationState CBSJump::UpdateBody(float dt, CBodyController& bc, CStateMa } bool CBSJump::ApplyAnimationDeltas() const { - if (x4_state == pas::EJumpState::AmbushJump || x4_state == pas::EJumpState::Loop) + if (x4_state == pas::EJumpState::AmbushJump || x4_state == pas::EJumpState::Loop) { return false; + } return true; } @@ -962,105 +1083,119 @@ bool CBSJump::IsInAir(const CBodyController& bc) const { bool CBSJump::CanShoot() const { return x4_state == pas::EJumpState::AmbushJump || x4_state == pas::EJumpState::Loop; } void CBSHurled::Start(CBodyController& bc, CStateManager& mgr) { - const CBCHurledCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)); x4_state = pas::EHurledState(cmd->GetSkipLaunchState()); - zeus::CVector3f localDir = bc.GetOwner().GetTransform().transposeRotate(cmd->GetHitDirection()); + const zeus::CVector3f localDir = bc.GetOwner().GetTransform().transposeRotate(cmd->GetHitDirection()); zeus::CRelAngle angle = std::atan2(localDir.y(), localDir.x()); angle.makeRel(); x8_knockAngle = angle.asDegrees(); - CPASAnimParmData parms(14, CPASAnimParm::FromInt32(-1), CPASAnimParm::FromReal32(x8_knockAngle), - CPASAnimParm::FromEnum(s32(x4_state))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CPASAnimParmData parms(14, CPASAnimParm::FromInt32(-1), CPASAnimParm::FromReal32(x8_knockAngle), + CPASAnimParm::FromEnum(s32(x4_state))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); const CPASAnimState* hurledState = bc.GetPASDatabase().GetAnimState(14); xc_animSeries = hurledState->GetAnimParmData(best.second, 0).GetInt32Value(); mgr.SendScriptMsg(&bc.GetOwner(), kInvalidUniqueId, EScriptObjectMessage::Falling); mgr.SendScriptMsg(&bc.GetOwner(), kInvalidUniqueId, EScriptObjectMessage::Jumped); - if (!zeus::close_enough(cmd->GetLaunchVelocity(), zeus::skZero3f, 0.0001f)) - if (TCastToPtr act = bc.GetOwner()) + if (!zeus::close_enough(cmd->GetLaunchVelocity(), zeus::skZero3f, 0.0001f)) { + if (const TCastToPtr act = bc.GetOwner()) { act->SetConstantForce(act->GetMass() * cmd->GetLaunchVelocity()); - float animAngle = zeus::degToRad(hurledState->GetAnimParmData(best.second, 1).GetReal32Value()); + } + } + const float animAngle = zeus::degToRad(hurledState->GetAnimParmData(best.second, 1).GetReal32Value()); zeus::CRelAngle delta1 = angle - animAngle; delta1.makeRel(); zeus::CRelAngle delta2 = animAngle - angle; delta2.makeRel(); - float minAngle = std::min(float(delta1), float(delta2)); + const float minAngle = std::min(float(delta1), float(delta2)); x14_remTime = 0.15f * bc.GetAnimTimeRemaining(); - float flippedAngle = (delta1 > M_PIF) ? -minAngle : minAngle; + const float flippedAngle = (delta1 > M_PIF) ? -minAngle : minAngle; x10_rotateSpeed = (x14_remTime > FLT_EPSILON) ? flippedAngle / x14_remTime : flippedAngle; x18_curTime = 0.f; x2c_24_needsRecover = false; } pas::EAnimationState CBSHurled::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::NextState)) + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::NextState)) { return pas::EAnimationState::LieOnGround; + } + if (x18_curTime > 0.25f) { - if (const CBCHurledCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled))) { - const_cast(cmd)->SetSkipLaunchState(true); + if (auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled))) { + cmd->SetSkipLaunchState(true); return pas::EAnimationState::Hurled; } } + return pas::EAnimationState::Invalid; } void CBSHurled::Recover(CStateManager& mgr, CBodyController& bc, pas::EHurledState state) { - CPASAnimParmData parms(14, CPASAnimParm::FromInt32(xc_animSeries), CPASAnimParm::FromReal32(x8_knockAngle), - CPASAnimParm::FromEnum(s32(state))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CPASAnimParmData parms(14, CPASAnimParm::FromInt32(xc_animSeries), CPASAnimParm::FromReal32(x8_knockAngle), + CPASAnimParm::FromEnum(s32(state))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); if (best.first > FLT_EPSILON) { - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); x4_state = state; - if (TCastToPtr act = bc.GetOwner()) + if (const TCastToPtr act = bc.GetOwner()) { act->SetMomentumWR(zeus::skZero3f); + } } x2c_24_needsRecover = false; } void CBSHurled::PlayStrikeWallAnimation(CBodyController& bc, CStateManager& mgr) { - CPASAnimParmData parms(14, CPASAnimParm::FromInt32(xc_animSeries), CPASAnimParm::FromReal32(x8_knockAngle), - CPASAnimParm::FromEnum(3)); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); - if (best.first > FLT_EPSILON) { - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); - bc.SetCurrentAnimation(playParms, false, false); - x4_state = pas::EHurledState::StrikeWall; + const CPASAnimParmData parms(14, CPASAnimParm::FromInt32(xc_animSeries), CPASAnimParm::FromReal32(x8_knockAngle), + CPASAnimParm::FromEnum(3)); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + + if (best.first <= FLT_EPSILON) { + return; } + + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + bc.SetCurrentAnimation(playParms, false, false); + x4_state = pas::EHurledState::StrikeWall; } void CBSHurled::PlayLandAnimation(CBodyController& bc, CStateManager& mgr) { - CPASAnimParmData parms(14, CPASAnimParm::FromInt32(xc_animSeries), CPASAnimParm::FromReal32(x8_knockAngle), - CPASAnimParm::FromEnum(s32(x4_state))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CPASAnimParmData parms(14, CPASAnimParm::FromInt32(xc_animSeries), CPASAnimParm::FromReal32(x8_knockAngle), + CPASAnimParm::FromEnum(s32(x4_state))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); const CPASAnimState* hurledState = bc.GetPASDatabase().GetAnimState(14); bc.SetFallState(pas::EFallState(hurledState->GetAnimParmData(best.second, 3).GetEnumValue())); - if (TCastToPtr act = bc.GetOwner()) + if (const TCastToPtr act = bc.GetOwner()) { mgr.SendScriptMsg(act.GetPtr(), kInvalidUniqueId, EScriptObjectMessage::OnFloor); + } } bool CBSHurled::ShouldStartStrikeWall(CBodyController& bc) const { - if (TCastToPtr ai = bc.GetOwner()) { - if (ai->MadeSolidCollision()) - if (!ai->IsOnGround()) + if (const TCastToConstPtr ai = bc.GetOwner()) { + if (ai->MadeSolidCollision()) { + if (!ai->IsOnGround()) { return true; + } + } } return false; } bool CBSHurled::ShouldStartLand(float dt, CBodyController& bc) const { bool ret = true; - if (TCastToPtr ai = bc.GetOwner()) { + if (const TCastToConstPtr ai = bc.GetOwner()) { ret = false; - if (ai->IsOnGround()) + if (ai->IsOnGround()) { return true; + } if (zeus::close_enough(ai->GetTranslation(), x1c_lastTranslation, 0.0001f) && ai->GetVelocity().z() < 0.f) { x28_landedDur += dt; - if (x28_landedDur >= 0.25f) + if (x28_landedDur >= 0.25f) { ret = true; + } } else { x28_landedDur = 0.f; } @@ -1070,7 +1205,7 @@ bool CBSHurled::ShouldStartLand(float dt, CBodyController& bc) const { } pas::EAnimationState CBSHurled::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); if (st == pas::EAnimationState::Invalid) { x18_curTime += dt; if (x14_remTime > 0.f) { @@ -1079,13 +1214,14 @@ pas::EAnimationState CBSHurled::UpdateBody(float dt, CBodyController& bc, CState bc.SetDeltaRotation(quat); x14_remTime -= dt; } - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState)) + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState)) { x2c_24_needsRecover = true; + } switch (x4_state) { case pas::EHurledState::KnockIntoAir: { if (bc.IsAnimationOver()) { - CPASAnimParmData parms(14, CPASAnimParm::FromInt32(xc_animSeries), CPASAnimParm::FromReal32(x8_knockAngle), - CPASAnimParm::FromEnum(1)); + const CPASAnimParmData parms(14, CPASAnimParm::FromInt32(xc_animSeries), + CPASAnimParm::FromReal32(x8_knockAngle), CPASAnimParm::FromEnum(1)); bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); x4_state = pas::EHurledState::KnockLoop; x28_landedDur = 0.f; @@ -1098,8 +1234,9 @@ pas::EAnimationState CBSHurled::UpdateBody(float dt, CBodyController& bc, CState PlayLandAnimation(bc, mgr); } else if (ShouldStartStrikeWall(bc)) { PlayStrikeWallAnimation(bc, mgr); - if (TCastToPtr ai = bc.GetOwner()) + if (const TCastToPtr ai = bc.GetOwner()) { ai->SetVelocityWR(zeus::skDown * (2.f * dt * ai->GetGravityConstant())); + } } else if (x2c_24_needsRecover) { Recover(mgr, bc, pas::EHurledState::Six); } @@ -1107,8 +1244,8 @@ pas::EAnimationState CBSHurled::UpdateBody(float dt, CBodyController& bc, CState case pas::EHurledState::StrikeWall: if (bc.IsAnimationOver()) { x4_state = pas::EHurledState::StrikeWallFallLoop; - CPASAnimParmData parms(14, CPASAnimParm::FromInt32(xc_animSeries), CPASAnimParm::FromReal32(x8_knockAngle), - CPASAnimParm::FromEnum(s32(x4_state))); + const CPASAnimParmData parms(14, CPASAnimParm::FromInt32(xc_animSeries), + CPASAnimParm::FromReal32(x8_knockAngle), CPASAnimParm::FromEnum(s32(x4_state))); bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); x28_landedDur = 0.f; } @@ -1123,8 +1260,9 @@ pas::EAnimationState CBSHurled::UpdateBody(float dt, CBodyController& bc, CState break; case pas::EHurledState::Six: case pas::EHurledState::Seven: - if (TCastToPtr act = bc.GetOwner()) + if (const TCastToPtr act = bc.GetOwner()) { act->SetVelocityWR(act->GetVelocity() * std::pow(0.9, 60.0 * dt)); + } if (bc.IsAnimationOver()) { x4_state = pas::EHurledState::Invalid; return pas::EAnimationState::Locomotion; @@ -1134,8 +1272,9 @@ pas::EAnimationState CBSHurled::UpdateBody(float dt, CBodyController& bc, CState case pas::EHurledState::OutOfStrikeWall: if (bc.IsAnimationOver()) { x4_state = pas::EHurledState::Invalid; - if (bc.GetFallState() == pas::EFallState::Zero) + if (bc.GetFallState() == pas::EFallState::Zero) { return pas::EAnimationState::Locomotion; + } return pas::EAnimationState::LieOnGround; } break; @@ -1147,42 +1286,47 @@ pas::EAnimationState CBSHurled::UpdateBody(float dt, CBodyController& bc, CState } void CBSSlide::Start(CBodyController& bc, CStateManager& mgr) { - const CBCSlideCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Slide)); - zeus::CVector3f localDir = bc.GetOwner().GetTransform().transposeRotate(cmd->GetSlideDirection()); - float angle = std::atan2(localDir.y(), localDir.x()); - CPASAnimParmData parms(15, CPASAnimParm::FromEnum(s32(cmd->GetSlideType())), - CPASAnimParm::FromReal32(zeus::radToDeg(angle))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Slide)); + const zeus::CVector3f localDir = bc.GetOwner().GetTransform().transposeRotate(cmd->GetSlideDirection()); + const float angle = std::atan2(localDir.y(), localDir.x()); + const CPASAnimParmData parms(15, CPASAnimParm::FromEnum(s32(cmd->GetSlideType())), + CPASAnimParm::FromReal32(zeus::radToDeg(angle))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); - float timeRem = bc.GetAnimTimeRemaining(); + const float timeRem = bc.GetAnimTimeRemaining(); if (timeRem > FLT_EPSILON) { const CPASAnimState* slideState = bc.GetPASDatabase().GetAnimState(15); - float animAngle = zeus::degToRad(slideState->GetAnimParmData(best.second, 1).GetReal32Value()); - float delta1 = zeus::CRelAngle(angle - animAngle).asRel(); - float flippedAngle = (delta1 > M_PIF) ? delta1 - 2.f * M_PIF : delta1; + const float animAngle = zeus::degToRad(slideState->GetAnimParmData(best.second, 1).GetReal32Value()); + const float delta1 = zeus::CRelAngle(angle - animAngle).asRel(); + const float flippedAngle = (delta1 > M_PIF) ? delta1 - 2.f * M_PIF : delta1; x4_rotateSpeed = flippedAngle / timeRem; } else { x4_rotateSpeed = 0.f; } } -pas::EAnimationState CBSSlide::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSSlide::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) { return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) { return pas::EAnimationState::KnockBack; - if (bc.IsAnimationOver()) + } + if (bc.IsAnimationOver()) { return pas::EAnimationState::Locomotion; + } return pas::EAnimationState::Invalid; } pas::EAnimationState CBSSlide::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); if (st == pas::EAnimationState::Invalid && x4_rotateSpeed != 0.f) { zeus::CQuaternion quat; quat.rotateZ(x4_rotateSpeed * dt); @@ -1192,133 +1336,158 @@ pas::EAnimationState CBSSlide::UpdateBody(float dt, CBodyController& bc, CStateM } void CBSTaunt::Start(CBodyController& bc, CStateManager& mgr) { - const CBCTauntCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Taunt)); - CPASAnimParmData parms(16, CPASAnimParm::FromEnum(s32(cmd->GetTauntType()))); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Taunt)); + const CPASAnimParmData parms(16, CPASAnimParm::FromEnum(s32(cmd->GetTauntType()))); bc.PlayBestAnimation(parms, *mgr.GetActiveRandom()); } -pas::EAnimationState CBSTaunt::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSTaunt::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) { return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) { return pas::EAnimationState::KnockBack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) { return pas::EAnimationState::Locomotion; - if (bc.IsAnimationOver()) + } + if (bc.IsAnimationOver()) { return pas::EAnimationState::Locomotion; + } return pas::EAnimationState::Invalid; } pas::EAnimationState CBSTaunt::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); - if (st == pas::EAnimationState::Invalid && !bc.GetCommandMgr().GetTargetVector().isZero()) + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); + if (st == pas::EAnimationState::Invalid && !bc.GetCommandMgr().GetTargetVector().isZero()) { bc.FaceDirection(bc.GetCommandMgr().GetTargetVector(), dt); + } return st; } void CBSScripted::Start(CBodyController& bc, CStateManager& mgr) { - const CBCScriptedCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Scripted)); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Scripted)); x4_24_loopAnim = cmd->IsLooped(); x4_25_timedLoop = cmd->GetUseLoopDuration(); x8_remTime = cmd->GetLoopDuration(); - CAnimPlaybackParms playParms(cmd->GetAnimId(), -1, 1.f, true); + const CAnimPlaybackParms playParms(cmd->GetAnimId(), -1, 1.f, true); bc.SetCurrentAnimation(playParms, cmd->IsLooped(), false); } -pas::EAnimationState CBSScripted::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSScripted::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) { return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) { return pas::EAnimationState::KnockBack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Scripted)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Scripted)) { return pas::EAnimationState::Scripted; - if (x4_24_loopAnim && bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState)) + } + if (x4_24_loopAnim && bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState)) { return pas::EAnimationState::Locomotion; - if (bc.IsAnimationOver()) + } + if (bc.IsAnimationOver()) { return pas::EAnimationState::Locomotion; + } return pas::EAnimationState::Invalid; } pas::EAnimationState CBSScripted::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); if (st == pas::EAnimationState::Invalid) { - if (!bc.GetCommandMgr().GetTargetVector().isZero()) + if (!bc.GetCommandMgr().GetTargetVector().isZero()) { bc.FaceDirection(bc.GetCommandMgr().GetTargetVector(), dt); + } if (x4_24_loopAnim && x4_25_timedLoop) { x8_remTime -= dt; - if (x8_remTime <= 0.f) + if (x8_remTime <= 0.f) { return pas::EAnimationState::Locomotion; + } } } return st; } void CBSCover::Start(CBodyController& bc, CStateManager& mgr) { - const CBCCoverCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Cover)); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::Cover)); x8_coverDirection = cmd->GetDirection(); x4_state = pas::ECoverState::IntoCover; - CPASAnimParmData parms(19, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_coverDirection))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); - zeus::CQuaternion orientDelta = + const CPASAnimParmData parms(19, CPASAnimParm::FromEnum(s32(x4_state)), + CPASAnimParm::FromEnum(s32(x8_coverDirection))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const zeus::CQuaternion orientDelta = zeus::CQuaternion::lookAt(zeus::skForward, cmd->GetAlignDirection(), 2.f * M_PIF); - CAnimPlaybackParms playParms(best.second, &orientDelta, &cmd->GetTarget(), &bc.GetOwner().GetTransform(), - &bc.GetOwner().GetModelData()->GetScale(), false); + const CAnimPlaybackParms playParms(best.second, &orientDelta, &cmd->GetTarget(), &bc.GetOwner().GetTransform(), + &bc.GetOwner().GetModelData()->GetScale(), false); bc.SetCurrentAnimation(playParms, false, false); xc_needsExit = false; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState)) + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState)) { xc_needsExit = true; + } } -pas::EAnimationState CBSCover::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSCover::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) { return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) { return pas::EAnimationState::KnockBack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) { return pas::EAnimationState::Locomotion; + } return pas::EAnimationState::Invalid; } pas::EAnimationState CBSCover::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); if (st == pas::EAnimationState::Invalid) { switch (x4_state) { case pas::ECoverState::Lean: case pas::ECoverState::IntoCover: if (bc.IsAnimationOver()) { x4_state = pas::ECoverState::Cover; - CPASAnimParmData parms(19, CPASAnimParm::FromEnum(s32(x4_state)), - CPASAnimParm::FromEnum(s32(x8_coverDirection))); + const CPASAnimParmData parms(19, CPASAnimParm::FromEnum(s32(x4_state)), + CPASAnimParm::FromEnum(s32(x8_coverDirection))); bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); } - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState)) + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState)) { xc_needsExit = true; + } break; case pas::ECoverState::Cover: - if (!bc.GetCommandMgr().GetTargetVector().isZero()) + if (!bc.GetCommandMgr().GetTargetVector().isZero()) { bc.FaceDirection(bc.GetCommandMgr().GetTargetVector(), dt); + } if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState) || xc_needsExit) { xc_needsExit = false; x4_state = pas::ECoverState::OutOfCover; - CPASAnimParmData parms(19, CPASAnimParm::FromEnum(s32(x4_state)), - CPASAnimParm::FromEnum(s32(x8_coverDirection))); + const CPASAnimParmData parms(19, CPASAnimParm::FromEnum(s32(x4_state)), + CPASAnimParm::FromEnum(s32(x8_coverDirection))); bc.PlayBestAnimation(parms, *mgr.GetActiveRandom()); } else if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LeanFromCover)) { x4_state = pas::ECoverState::Lean; - CPASAnimParmData parms(19, CPASAnimParm::FromEnum(s32(x4_state)), - CPASAnimParm::FromEnum(s32(x8_coverDirection))); + const CPASAnimParmData parms(19, CPASAnimParm::FromEnum(s32(x4_state)), + CPASAnimParm::FromEnum(s32(x8_coverDirection))); bc.PlayBestAnimation(parms, *mgr.GetActiveRandom()); } break; @@ -1336,34 +1505,36 @@ pas::EAnimationState CBSCover::UpdateBody(float dt, CBodyController& bc, CStateM } void CBSWallHang::Start(CBodyController& bc, CStateManager& mgr) { - const CBCWallHangCmd* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::WallHang)); + const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::WallHang)); x4_state = pas::EWallHangState::IntoJump; x8_wpId = cmd->GetTarget(); x18_25_needsExit = false; - CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); + const CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); bc.PlayBestAnimation(parms, *mgr.GetActiveRandom()); } -pas::EAnimationState CBSWallHang::GetBodyStateTransition(float dt, CBodyController& bc) const { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) +pas::EAnimationState CBSWallHang::GetBodyStateTransition(float dt, const CBodyController& bc) const { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; + } return pas::EAnimationState::Invalid; } void CBSWallHang::FixInPlace(CBodyController& bc) { - if (TCastToPtr ai = bc.GetOwner()) { + if (const TCastToPtr ai = bc.GetOwner()) { ai->SetConstantForce(zeus::skZero3f); ai->SetVelocityWR(zeus::skZero3f); } } bool CBSWallHang::CheckForLand(CBodyController& bc, CStateManager& mgr) { - if (TCastToPtr ai = bc.GetOwner()) { + if (const TCastToPtr ai = bc.GetOwner()) { if (ai->MadeSolidCollision() || ai->IsOnGround()) { x4_state = pas::EWallHangState::DetachOutOfJump; - CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); + const CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); bc.PlayBestAnimation(parms, *mgr.GetActiveRandom()); mgr.SendScriptMsg(ai.GetPtr(), kInvalidUniqueId, EScriptObjectMessage::OnFloor); return true; @@ -1373,19 +1544,20 @@ bool CBSWallHang::CheckForLand(CBodyController& bc, CStateManager& mgr) { } bool CBSWallHang::CheckForWall(CBodyController& bc, CStateManager& mgr) { - if (TCastToPtr ai = bc.GetOwner()) { + if (const TCastToPtr ai = bc.GetOwner()) { float magSq = 10.f; - TCastToPtr wp = mgr.ObjectById(x8_wpId); - if (wp) + const TCastToConstPtr wp = mgr.ObjectById(x8_wpId); + if (wp) { magSq = (wp->GetTranslation() - ai->GetTranslation()).magSquared(); + } if (magSq < 1.f || ai->MadeSolidCollision()) { x4_state = pas::EWallHangState::IntoWallHang; - CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); const zeus::CVector3f& target = wp ? wp->GetTranslation() : ai->GetTranslation(); - CAnimPlaybackParms playParms(best.second, nullptr, &target, &bc.GetOwner().GetTransform(), - &bc.GetOwner().GetModelData()->GetScale(), false); + const CAnimPlaybackParms playParms(best.second, nullptr, &target, &bc.GetOwner().GetTransform(), + &bc.GetOwner().GetModelData()->GetScale(), false); bc.SetCurrentAnimation(playParms, false, false); ai->SetVelocityWR(zeus::skZero3f); ai->SetMomentumWR(zeus::skZero3f); @@ -1397,38 +1569,41 @@ bool CBSWallHang::CheckForWall(CBodyController& bc, CStateManager& mgr) { } void CBSWallHang::SetLaunchVelocity(CBodyController& bc) { - if (!x18_24_launched) { - if (TCastToPtr act = bc.GetOwner()) { - act->SetVelocityWR(xc_launchVel); - act->SetConstantForce(xc_launchVel * act->GetMass()); - } - x18_24_launched = true; + if (x18_24_launched) { + return; } + + if (const TCastToPtr act = bc.GetOwner()) { + act->SetVelocityWR(xc_launchVel); + act->SetConstantForce(xc_launchVel * act->GetMass()); + } + + x18_24_launched = true; } pas::EAnimationState CBSWallHang::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); if (st == pas::EAnimationState::Invalid) { switch (x4_state) { case pas::EWallHangState::IntoJump: { - CPASAnimParmData parms(20, CPASAnimParm::FromEnum(1)); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CPASAnimParmData parms(20, CPASAnimParm::FromEnum(1)); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); if (best.first > 0.f) { x4_state = pas::EWallHangState::JumpArc; - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); } else { x4_state = pas::EWallHangState::JumpAirLoop; - CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); - bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); + const CPASAnimParmData loopParms(20, CPASAnimParm::FromEnum(s32(x4_state))); + bc.LoopBestAnimation(loopParms, *mgr.GetActiveRandom()); } - if (TCastToPtr act = bc.GetOwner()) { + if (const TCastToPtr act = bc.GetOwner()) { mgr.SendScriptMsg(act.GetPtr(), kInvalidUniqueId, EScriptObjectMessage::Jumped); - if (TCastToPtr wp = mgr.ObjectById(x8_wpId)) { - zeus::CVector3f toWp = wp->GetTranslation() - act->GetTranslation(); + if (const TCastToConstPtr wp = mgr.ObjectById(x8_wpId)) { + const zeus::CVector3f toWp = wp->GetTranslation() - act->GetTranslation(); if (toWp.z() > 0.f) { float tmp = -act->GetMomentum().z() / act->GetMass(); - float tmp2 = std::sqrt(tmp * 2.f * toWp.z()); + const float tmp2 = std::sqrt(tmp * 2.f * toWp.z()); tmp = 1.f / (tmp2 / tmp); xc_launchVel = zeus::CVector3f(tmp * toWp.x(), tmp * toWp.y(), tmp2); x18_24_launched = false; @@ -1441,7 +1616,7 @@ pas::EAnimationState CBSWallHang::UpdateBody(float dt, CBodyController& bc, CSta SetLaunchVelocity(bc); if (bc.IsAnimationOver()) { x4_state = pas::EWallHangState::JumpAirLoop; - CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); + const CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); } else { CheckForWall(bc, mgr); @@ -1450,14 +1625,15 @@ pas::EAnimationState CBSWallHang::UpdateBody(float dt, CBodyController& bc, CSta } case pas::EWallHangState::JumpAirLoop: { SetLaunchVelocity(bc); - if (!CheckForWall(bc, mgr)) + if (!CheckForWall(bc, mgr)) { CheckForLand(bc, mgr); + } break; } case pas::EWallHangState::IntoWallHang: { if (bc.IsAnimationOver()) { x4_state = pas::EWallHangState::WallHang; - CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); + const CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); } else if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState)) { x18_25_needsExit = true; @@ -1466,19 +1642,20 @@ pas::EAnimationState CBSWallHang::UpdateBody(float dt, CBodyController& bc, CSta } case pas::EWallHangState::WallHang: { if (!bc.GetCommandMgr().GetTargetVector().isZero()) { - if (TCastToPtr wp = mgr.ObjectById(x8_wpId)) { - if (TCastToPtr act = bc.GetOwner()) { - zeus::CVector3f lookDir = bc.GetCommandMgr().GetTargetVector().normalized(); - float actorDotWp = act->GetTransform().basis[1].dot(wp->GetTransform().basis[1]); - float lookDotWp = lookDir.dot(wp->GetTransform().basis[1]); - if (actorDotWp < -0.5f || lookDotWp > 0.5f) + if (const TCastToConstPtr wp = mgr.ObjectById(x8_wpId)) { + if (const TCastToConstPtr act = bc.GetOwner()) { + const zeus::CVector3f lookDir = bc.GetCommandMgr().GetTargetVector().normalized(); + const float actorDotWp = act->GetTransform().basis[1].dot(wp->GetTransform().basis[1]); + const float lookDotWp = lookDir.dot(wp->GetTransform().basis[1]); + if (actorDotWp < -0.5f || lookDotWp > 0.5f) { bc.FaceDirection(lookDir, dt); + } } } } if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState) || x18_25_needsExit) { x4_state = pas::EWallHangState::OutOfWallHang; - CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); + const CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); bc.PlayBestAnimation(parms, *mgr.GetActiveRandom()); } FixInPlace(bc); @@ -1487,7 +1664,7 @@ pas::EAnimationState CBSWallHang::UpdateBody(float dt, CBodyController& bc, CSta case pas::EWallHangState::Five: { if (bc.IsAnimationOver()) { x4_state = pas::EWallHangState::WallHang; - CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); + const CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); } FixInPlace(bc); @@ -1495,21 +1672,21 @@ pas::EAnimationState CBSWallHang::UpdateBody(float dt, CBodyController& bc, CSta } case pas::EWallHangState::OutOfWallHang: { if (bc.IsAnimationOver()) { - CPASAnimParmData parms(20, CPASAnimParm::FromEnum(7)); - std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + const CPASAnimParmData parms(20, CPASAnimParm::FromEnum(7)); + const std::pair best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); if (best.first > 0.f) { x4_state = pas::EWallHangState::OutOfWallHangTurn; - CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); bc.SetCurrentAnimation(playParms, false, false); } else { x4_state = pas::EWallHangState::DetachJumpLoop; - CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); - bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); + const CPASAnimParmData loopParms(20, CPASAnimParm::FromEnum(s32(x4_state))); + bc.LoopBestAnimation(loopParms, *mgr.GetActiveRandom()); } - if (TCastToPtr act = bc.GetOwner()) { + if (const TCastToPtr act = bc.GetOwner()) { mgr.SendScriptMsg(act.GetPtr(), kInvalidUniqueId, EScriptObjectMessage::Jumped); x18_24_launched = false; - if (TCastToPtr wp = mgr.ObjectById(x8_wpId)) { + if (const TCastToConstPtr wp = mgr.ObjectById(x8_wpId)) { xc_launchVel = 15.f * wp->GetTransform().basis[1]; xc_launchVel.z() = 5.f; } else { @@ -1524,7 +1701,7 @@ pas::EAnimationState CBSWallHang::UpdateBody(float dt, CBodyController& bc, CSta SetLaunchVelocity(bc); if (bc.IsAnimationOver()) { x4_state = pas::EWallHangState::DetachJumpLoop; - CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); + const CPASAnimParmData parms(20, CPASAnimParm::FromEnum(s32(x4_state))); bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); } else { CheckForLand(bc, mgr); @@ -1598,11 +1775,12 @@ bool CBSWallHang::ApplyGravity() const { } float CBSLocomotion::GetStartVelocityMagnitude(const CBodyController& bc) const { - if (TCastToPtr act = bc.GetOwner()) { - float maxSpeed = bc.GetBodyStateInfo().GetMaxSpeed(); + if (const TCastToConstPtr act = bc.GetOwner()) { + const float maxSpeed = bc.GetBodyStateInfo().GetMaxSpeed(); float ret = 0.f; - if (maxSpeed > 0.f) + if (maxSpeed > 0.f) { ret = act->GetVelocity().magnitude() / maxSpeed; + } return std::min(1.f, ret); } return 0.f; @@ -1614,34 +1792,37 @@ void CBSLocomotion::ReStartBodyState(CBodyController& bc, bool maintainVel) { float CBSLocomotion::ComputeWeightPercentage(const std::pair& a, const std::pair& b, float f) const { - float range = b.second - a.second; - if (range > FLT_EPSILON) + const float range = b.second - a.second; + if (range > FLT_EPSILON) { return std::max(0.f, std::min(1.f, (f - a.second) / range)); + } return 0.f; } void CBSLocomotion::Start(CBodyController& bc, CStateManager& mgr) { x4_locomotionType = bc.GetLocomotionType(); - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MaintainVelocity)) + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MaintainVelocity)) { ReStartBodyState(bc, true); - else + } else { ReStartBodyState(bc, false); + } } pas::EAnimationState CBSLocomotion::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - pas::EAnimationState st = GetBodyStateTransition(dt, bc); - if (st == pas::EAnimationState::Invalid) + const pas::EAnimationState st = GetBodyStateTransition(dt, bc); + if (st == pas::EAnimationState::Invalid) { UpdateLocomotionAnimation(dt, ApplyLocomotionPhysics(dt, bc), bc, false); + } return st; } void CBSLocomotion::Shutdown(CBodyController& bc) { bc.MultiplyPlaybackRate(1.f); } float CBSLocomotion::ApplyLocomotionPhysics(float dt, CBodyController& bc) { - if (TCastToPtr act = bc.GetOwner()) { - zeus::CVector3f vec = (zeus::close_enough(bc.GetCommandMgr().GetFaceVector(), zeus::skZero3f, 0.0001f)) - ? bc.GetCommandMgr().GetMoveVector() - : bc.GetCommandMgr().GetFaceVector(); + if (const TCastToConstPtr act = bc.GetOwner()) { + const zeus::CVector3f vec = (zeus::close_enough(bc.GetCommandMgr().GetFaceVector(), zeus::skZero3f, 0.0001f)) + ? bc.GetCommandMgr().GetMoveVector() + : bc.GetCommandMgr().GetFaceVector(); if (vec.canBeNormalized()) { if (IsPitchable()) { zeus::CVector3f tmp = vec; @@ -1654,7 +1835,7 @@ float CBSLocomotion::ApplyLocomotionPhysics(float dt, CBodyController& bc) { lookVec2.z() = float(vec.z()); lookVec2.normalize(); if (!zeus::close_enough(lookVec, lookVec2, 0.0001f)) { - zeus::CRelAngle pitchAngle = + const zeus::CRelAngle pitchAngle = std::min(bc.GetBodyStateInfo().GetMaximumPitch(), zeus::CVector3f::getAngleDiff(vec, tmp)); lookVec2 = zeus::CVector3f::slerp(lookVec, lookVec2, pitchAngle); } @@ -1672,49 +1853,68 @@ float CBSLocomotion::ApplyLocomotionPhysics(float dt, CBodyController& bc) { } pas::EAnimationState CBSLocomotion::GetBodyStateTransition(float, CBodyController& bc) { - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Hurled)) { return pas::EAnimationState::Hurled; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)) { return pas::EAnimationState::Fall; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopHitReaction)) { return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockBack)) { return pas::EAnimationState::KnockBack; + } if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Locomotion)) { bc.GetCommandMgr().ClearLocomotionCmds(); return pas::EAnimationState::Invalid; } - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Slide)) + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Slide)) { return pas::EAnimationState::Slide; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Generate)) - return pas::EAnimationState::Generate; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)) - return pas::EAnimationState::MeleeAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ProjectileAttack)) - return pas::EAnimationState::ProjectileAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)) - return pas::EAnimationState::LoopAttack; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopReaction)) - return pas::EAnimationState::LoopReaction; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Jump)) - return pas::EAnimationState::Jump; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Taunt)) - return pas::EAnimationState::Taunt; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Step)) - return pas::EAnimationState::Step; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Cover)) - return pas::EAnimationState::Cover; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::WallHang)) - return pas::EAnimationState::WallHang; - if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Scripted)) - return pas::EAnimationState::Scripted; - if (bc.GetCommandMgr().GetMoveVector().isZero()) { - if (!bc.GetCommandMgr().GetFaceVector().isZero()) - if (!IsMoving()) - return pas::EAnimationState::Turn; } - if (x4_locomotionType != bc.GetLocomotionType()) + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Generate)) { + return pas::EAnimationState::Generate; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::MeleeAttack)) { + return pas::EAnimationState::MeleeAttack; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ProjectileAttack)) { + return pas::EAnimationState::ProjectileAttack; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopAttack)) { + return pas::EAnimationState::LoopAttack; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::LoopReaction)) { + return pas::EAnimationState::LoopReaction; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Jump)) { + return pas::EAnimationState::Jump; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Taunt)) { + return pas::EAnimationState::Taunt; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Step)) { + return pas::EAnimationState::Step; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Cover)) { + return pas::EAnimationState::Cover; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::WallHang)) { + return pas::EAnimationState::WallHang; + } + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Scripted)) { + return pas::EAnimationState::Scripted; + } + if (bc.GetCommandMgr().GetMoveVector().isZero()) { + if (!bc.GetCommandMgr().GetFaceVector().isZero()) { + if (!IsMoving()) { + return pas::EAnimationState::Turn; + } + } + } + if (x4_locomotionType != bc.GetLocomotionType()) { return pas::EAnimationState::Locomotion; + } return pas::EAnimationState::Invalid; } @@ -1723,13 +1923,14 @@ CBSBiPedLocomotion::CBSBiPedLocomotion(CActor& actor) { for (int i = 0; i < 14; ++i) { rstl::reserved_vector, 8>& innerVec = x8_anims.emplace_back(); for (int j = 0; j < 8; ++j) { - CPASAnimParmData parms(5, CPASAnimParm::FromEnum(j), CPASAnimParm::FromEnum(i)); - std::pair best = pasDatabase.FindBestAnimation(parms, -1); + const CPASAnimParmData parms(5, CPASAnimParm::FromEnum(j), CPASAnimParm::FromEnum(i)); + const std::pair best = pasDatabase.FindBestAnimation(parms, -1); float avgVel = 0.f; if (best.second != -1) { avgVel = actor.GetAverageAnimVelocity(best.second); - if (j == 0) + if (j == 0) { avgVel = 0.f; + } } innerVec.push_back({best.second, avgVel}); } @@ -1742,8 +1943,9 @@ void CBSBiPedLocomotion::Start(CBodyController& bc, CStateManager& mgr) { } pas::EAnimationState CBSBiPedLocomotion::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { - if (x3c8_primeTime < 0.2f) + if (x3c8_primeTime < 0.2f) { x3c8_primeTime += dt; + } return CBSLocomotion::UpdateBody(dt, bc, mgr); } @@ -1754,12 +1956,12 @@ float CBSBiPedLocomotion::GetLocomotionSpeed(pas::ELocomotionType type, pas::ELo float CBSBiPedLocomotion::UpdateRun(float vel, CBodyController& bc, pas::ELocomotionAnim anim) { const std::pair& walk = GetLocoAnimation(x4_locomotionType, pas::ELocomotionAnim::Walk); const std::pair& run = GetLocoAnimation(x4_locomotionType, pas::ELocomotionAnim::Run); - float perc = ComputeWeightPercentage(walk, run, vel); + const float perc = ComputeWeightPercentage(walk, run, vel); if (perc < 0.4f) { - float rate = walk.second > 0.f ? vel / walk.second : 1.f; + const float rate = walk.second > 0.f ? vel / walk.second : 1.f; if (anim != pas::ELocomotionAnim::Walk && bc.GetCurrentAnimId() != walk.first) { - CAnimPlaybackParms playParms(walk.first, -1, 1.f, true); + const CAnimPlaybackParms playParms(walk.first, -1, 1.f, true); bc.SetCurrentAnimation(playParms, true, false); x3c8_primeTime = 0.f; } @@ -1767,9 +1969,9 @@ float CBSBiPedLocomotion::UpdateRun(float vel, CBodyController& bc, pas::ELocomo x3c4_anim = pas::ELocomotionAnim::Walk; return rate; } else { - float rate = std::min(1.f, vel / run.second); + const float rate = std::min(1.f, vel / run.second); if (anim != pas::ELocomotionAnim::Run && bc.GetCurrentAnimId() != run.first) { - CAnimPlaybackParms playParms(run.first, -1, 1.f, true); + const CAnimPlaybackParms playParms(run.first, -1, 1.f, true); bc.SetCurrentAnimation(playParms, true, false); x3c8_primeTime = 0.f; } @@ -1783,7 +1985,7 @@ float CBSBiPedLocomotion::UpdateWalk(float vel, CBodyController& bc, pas::ELocom if (anim != pas::ELocomotionAnim::Walk) { const std::pair& walk = GetLocoAnimation(x4_locomotionType, pas::ELocomotionAnim::Walk); if (bc.GetCurrentAnimId() != walk.first) { - CAnimPlaybackParms playParms(walk.first, -1, 1.f, true); + const CAnimPlaybackParms playParms(walk.first, -1, 1.f, true); bc.SetCurrentAnimation(playParms, true, false); x3c8_primeTime = 0.f; } @@ -1792,30 +1994,33 @@ float CBSBiPedLocomotion::UpdateWalk(float vel, CBodyController& bc, pas::ELocom const std::pair& idle = GetLocoAnimation(x4_locomotionType, pas::ELocomotionAnim::Idle); const std::pair& walk = GetLocoAnimation(x4_locomotionType, pas::ELocomotionAnim::Walk); - float perc = std::max(0.5f, ComputeWeightPercentage(idle, walk, vel)); + const float perc = std::max(0.5f, ComputeWeightPercentage(idle, walk, vel)); bc.MultiplyPlaybackRate(perc); return perc; } -static const pas::ELocomotionAnim Strafes[] = {pas::ELocomotionAnim::StrafeRight, pas::ELocomotionAnim::StrafeLeft, - pas::ELocomotionAnim::Walk, pas::ELocomotionAnim::BackUp, - pas::ELocomotionAnim::StrafeUp, pas::ELocomotionAnim::StrafeDown}; +constexpr std::array Strafes{ + pas::ELocomotionAnim::StrafeRight, pas::ELocomotionAnim::StrafeLeft, pas::ELocomotionAnim::Walk, + pas::ELocomotionAnim::BackUp, pas::ELocomotionAnim::StrafeUp, pas::ELocomotionAnim::StrafeDown, +}; float CBSBiPedLocomotion::UpdateStrafe(float vel, CBodyController& bc, pas::ELocomotionAnim anim) { - if (TCastToPtr act = bc.GetOwner()) { - zeus::CVector3f localVec = act->GetTransform().transposeRotate(bc.GetCommandMgr().GetMoveVector()); - zeus::CVector3f localVecSq = localVec * localVec; + if (const TCastToConstPtr act = bc.GetOwner()) { + const zeus::CVector3f localVec = act->GetTransform().transposeRotate(bc.GetCommandMgr().GetMoveVector()); + const zeus::CVector3f localVecSq = localVec * localVec; int maxComp = 0; - for (int i = 0; i < 3; ++i) - if (localVecSq[i] >= localVecSq[maxComp]) + for (int i = 0; i < 3; ++i) { + if (localVecSq[i] >= localVecSq[maxComp]) { maxComp = i; - int strafeKey = maxComp * 2 + localVec[maxComp] > 0.f ? 0 : 1; - pas::ELocomotionAnim strafeType = Strafes[strafeKey]; - float rate = vel * GetLocomotionSpeed(x4_locomotionType, strafeType); + } + } + const int strafeKey = maxComp * 2 + localVec[maxComp] > 0.f ? 0 : 1; + const pas::ELocomotionAnim strafeType = Strafes[strafeKey]; + const float rate = vel * GetLocomotionSpeed(x4_locomotionType, strafeType); if (anim != strafeType) { const std::pair& strafe = GetLocoAnimation(x4_locomotionType, strafeType); if (bc.GetCurrentAnimId() != strafe.first) { - CAnimPlaybackParms playParms(strafe.first, -1, 1.f, true); + const CAnimPlaybackParms playParms(strafe.first, -1, 1.f, true); bc.SetCurrentAnimation(playParms, true, false); x3c8_primeTime = 0.f; } @@ -1823,26 +2028,26 @@ float CBSBiPedLocomotion::UpdateStrafe(float vel, CBodyController& bc, pas::ELoc } const std::pair& idle = GetLocoAnimation(x4_locomotionType, pas::ELocomotionAnim::Idle); const std::pair& strafe = GetLocoAnimation(x4_locomotionType, strafeType); - float perc = std::max(0.5f, ComputeWeightPercentage(idle, strafe, rate)); + const float perc = std::max(0.5f, ComputeWeightPercentage(idle, strafe, rate)); bc.MultiplyPlaybackRate(perc); } return 1.f; } float CBSBiPedLocomotion::UpdateLocomotionAnimation(float dt, float velMag, CBodyController& bc, bool init) { - float ret = 1.f; if (init || x3c8_primeTime >= 0.2f) { - pas::ELocomotionAnim anim = init ? pas::ELocomotionAnim::Invalid : x3c4_anim; - float maxSpeed = velMag * GetLocomotionSpeed(x4_locomotionType, pas::ELocomotionAnim::Run); - if (IsStrafing(bc) && velMag >= 0.01f) + const auto anim = init ? pas::ELocomotionAnim::Invalid : x3c4_anim; + const float maxSpeed = velMag * GetLocomotionSpeed(x4_locomotionType, pas::ELocomotionAnim::Run); + if (IsStrafing(bc) && velMag >= 0.01f) { return UpdateStrafe(velMag, bc, anim); + } if (maxSpeed < 0.01f) { if (anim != pas::ELocomotionAnim::Idle || init) { if (!bc.GetBodyStateInfo().GetLocoAnimChangeAtEndOfAnimOnly() || bc.GetAnimTimeRemaining() <= dt || init) { const std::pair& best = GetLocoAnimation(x4_locomotionType, pas::ELocomotionAnim::Idle); if (bc.GetCurrentAnimId() != best.first) { - CAnimPlaybackParms playParms(best.first, -1, 1.f, true); + const CAnimPlaybackParms playParms(best.first, -1, 1.f, true); bc.SetCurrentAnimation(playParms, true, false); x3c8_primeTime = 0.f; } @@ -1851,18 +2056,22 @@ float CBSBiPedLocomotion::UpdateLocomotionAnimation(float dt, float velMag, CBod } } else { const std::pair& best = GetLocoAnimation(x4_locomotionType, pas::ELocomotionAnim::Walk); - if (maxSpeed < best.second) + if (maxSpeed < best.second) { return UpdateWalk(maxSpeed, bc, anim); + } return UpdateRun(maxSpeed, bc, anim); } } - return ret; + + return 1.0f; } bool CBSBiPedLocomotion::IsStrafing(const CBodyController& bc) const { - if (!zeus::close_enough(bc.GetCommandMgr().GetMoveVector(), zeus::skZero3f, 0.0001f)) - if (!zeus::close_enough(bc.GetCommandMgr().GetFaceVector(), zeus::skZero3f, 0.0001f)) + if (!zeus::close_enough(bc.GetCommandMgr().GetMoveVector(), zeus::skZero3f, 0.0001f)) { + if (!zeus::close_enough(bc.GetCommandMgr().GetFaceVector(), zeus::skZero3f, 0.0001f)) { return true; + } + } return false; } @@ -1870,8 +2079,8 @@ CBSFlyerLocomotion::CBSFlyerLocomotion(CActor& actor, bool pitchable) : CBSBiPedLocomotion(actor), x3cc_pitchable(pitchable) {} float CBSFlyerLocomotion::ApplyLocomotionPhysics(float dt, CBodyController& bc) { - float ret = CBSLocomotion::ApplyLocomotionPhysics(dt, bc); - if (TCastToPtr act = bc.GetOwner()) { + const float ret = CBSLocomotion::ApplyLocomotionPhysics(dt, bc); + if (const TCastToPtr act = bc.GetOwner()) { if (std::fabs(bc.GetCommandMgr().GetMoveVector().z()) > 0.01f && (!x3cc_pitchable || bc.GetBodyStateInfo().GetMaximumPitch() < 0.17453292f)) { zeus::CVector3f dir; @@ -1885,19 +2094,21 @@ float CBSFlyerLocomotion::ApplyLocomotionPhysics(float dt, CBodyController& bc) CBSWallWalkerLocomotion::CBSWallWalkerLocomotion(CActor& actor) : CBSBiPedLocomotion(actor) {} float CBSWallWalkerLocomotion::ApplyLocomotionPhysics(float dt, CBodyController& bc) { - if (TCastToPtr act = bc.GetOwner()) { - float maxSpeed = bc.GetBodyStateInfo().GetMaxSpeed(); - zeus::CVector3f scaledMove = bc.GetCommandMgr().GetMoveVector() * maxSpeed; + if (const TCastToConstPtr act = bc.GetOwner()) { + const float maxSpeed = bc.GetBodyStateInfo().GetMaxSpeed(); + const zeus::CVector3f scaledMove = bc.GetCommandMgr().GetMoveVector() * maxSpeed; if ((zeus::CVector3f::getAngleDiff(bc.GetCommandMgr().GetFaceVector(), scaledMove) < (M_PIF / 2.f) ? scaledMove : bc.GetCommandMgr().GetFaceVector()) - .canBeNormalized()) + .canBeNormalized()) { bc.FaceDirection3D(scaledMove.normalized(), act->GetTransform().basis[1], dt); + } zeus::CVector3f impulse = act->GetMoveToORImpulseWR(act->GetTransform().transposeRotate(scaledMove * dt), dt); impulse = act->GetMass() > FLT_EPSILON ? impulse / act->GetMass() : zeus::CVector3f(0.f, act->GetVelocity().magnitude(), 0.f); - if (maxSpeed > FLT_EPSILON) + if (maxSpeed > FLT_EPSILON) { return std::min(1.f, impulse.magnitude() / maxSpeed); + } } return 0.f; } @@ -1905,56 +2116,61 @@ float CBSWallWalkerLocomotion::ApplyLocomotionPhysics(float dt, CBodyController& CBSNewFlyerLocomotion::CBSNewFlyerLocomotion(CActor& actor) : CBSBiPedLocomotion(actor) {} float CBSNewFlyerLocomotion::ApplyLocomotionPhysics(float dt, CBodyController& bc) { - if (TCastToPtr(bc.GetOwner())) + if (TCastToConstPtr(bc.GetOwner())) { bc.FaceDirection(bc.GetCommandMgr().GetFaceVector(), dt); + } return 0.f; } -static const pas::ELocomotionAnim RunStrafes[] = {pas::ELocomotionAnim::StrafeRight, pas::ELocomotionAnim::StrafeLeft, - pas::ELocomotionAnim::Run, pas::ELocomotionAnim::BackUp, - pas::ELocomotionAnim::StrafeUp, pas::ELocomotionAnim::StrafeDown}; +constexpr std::array RunStrafes{ + pas::ELocomotionAnim::StrafeRight, pas::ELocomotionAnim::StrafeLeft, pas::ELocomotionAnim::Run, + pas::ELocomotionAnim::BackUp, pas::ELocomotionAnim::StrafeUp, pas::ELocomotionAnim::StrafeDown, +}; float CBSNewFlyerLocomotion::UpdateLocomotionAnimation(float dt, float velMag, CBodyController& bc, bool init) { - if (TCastToPtr act = bc.GetOwner()) { + if (const TCastToConstPtr act = bc.GetOwner()) { pas::ELocomotionAnim strafeType = pas::ELocomotionAnim::Idle; if (bc.GetCommandMgr().GetMoveVector().canBeNormalized()) { - zeus::CVector3f localVec = act->GetTransform().transposeRotate(bc.GetCommandMgr().GetMoveVector()); - zeus::CVector3f localVecSq = localVec * localVec; + const zeus::CVector3f localVec = act->GetTransform().transposeRotate(bc.GetCommandMgr().GetMoveVector()); + const zeus::CVector3f localVecSq = localVec * localVec; int maxComp = 0; - for (int i = 0; i < 3; ++i) - if (localVecSq[i] >= localVecSq[maxComp]) + for (int i = 0; i < 3; ++i) { + if (localVecSq[i] >= localVecSq[maxComp]) { maxComp = i; - int strafeKey = maxComp * 2 + localVec[maxComp] > 0.f ? 0 : 1; + } + } + const int strafeKey = maxComp * 2 + localVec[maxComp] > 0.f ? 0 : 1; strafeType = RunStrafes[strafeKey]; } if (init || strafeType != x3c4_anim) { const std::pair& strafe = GetLocoAnimation(x4_locomotionType, strafeType); if (init || bc.GetCurrentAnimId() != strafe.first) { - CAnimPlaybackParms playParms(strafe.first, -1, 1.f, true); + const CAnimPlaybackParms playParms(strafe.first, -1, 1.f, true); bc.SetCurrentAnimation(playParms, true, false); } x3c4_anim = strafeType; } } + return 1.f; } CBSRestrictedLocomotion::CBSRestrictedLocomotion(CActor& actor) { const CPASDatabase& pasDatabase = actor.GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase(); for (int i = 0; i < 14; ++i) { - CPASAnimParmData parms(5, CPASAnimParm::FromEnum(0), CPASAnimParm::FromEnum(i)); - std::pair best = pasDatabase.FindBestAnimation(parms, -1); + const CPASAnimParmData parms(5, CPASAnimParm::FromEnum(0), CPASAnimParm::FromEnum(i)); + const std::pair best = pasDatabase.FindBestAnimation(parms, -1); x8_anims.push_back(best.second); } } float CBSRestrictedLocomotion::UpdateLocomotionAnimation(float dt, float velMag, CBodyController& bc, bool init) { - pas::ELocomotionAnim anim = init ? pas::ELocomotionAnim::Invalid : x44_anim; + const pas::ELocomotionAnim anim = init ? pas::ELocomotionAnim::Invalid : x44_anim; if (anim != pas::ELocomotionAnim::Idle) { - s32 newAnim = x8_anims[int(x4_locomotionType)]; + const s32 newAnim = x8_anims[int(x4_locomotionType)]; if (newAnim != bc.GetCurrentAnimId()) { - CAnimPlaybackParms playParms(newAnim, -1, 1.f, true); + const CAnimPlaybackParms playParms(newAnim, -1, 1.f, true); bc.SetCurrentAnimation(playParms, true, false); } x44_anim = pas::ELocomotionAnim::Idle; @@ -1965,7 +2181,7 @@ float CBSRestrictedLocomotion::UpdateLocomotionAnimation(float dt, float velMag, CBSRestrictedFlyerLocomotion::CBSRestrictedFlyerLocomotion(CActor& actor) : CBSRestrictedLocomotion(actor) {} float CBSRestrictedFlyerLocomotion::ApplyLocomotionPhysics(float dt, CBodyController& bc) { - if (TCastToPtr act = bc.GetOwner()) { + if (const TCastToPtr act = bc.GetOwner()) { bc.FaceDirection(bc.GetCommandMgr().GetFaceVector(), dt); act->ApplyImpulseWR(bc.GetCommandMgr().GetMoveVector() * bc.GetRestrictedFlyerMoveSpeed() * act->GetMass(), zeus::CAxisAngle()); diff --git a/Runtime/Character/CBodyState.hpp b/Runtime/Character/CBodyState.hpp index ed8a97ace..9dfce3539 100644 --- a/Runtime/Character/CBodyState.hpp +++ b/Runtime/Character/CBodyState.hpp @@ -33,8 +33,8 @@ class CBSAttack : public CBodyState { float x2c_alignTargetPosStartTime = -1.f; float x30_alignTargetPosTime = -1.f; float x34_curTime = 0.f; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc); - void UpdatePhysicsActor(CBodyController& bc, float dt); + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc); + void UpdatePhysicsActor(const CBodyController& bc, float dt); public: bool CanShoot() const override { return false; } @@ -44,7 +44,7 @@ public: }; class CBSProjectileAttack : public CBodyState { - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc); + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; public: bool CanShoot() const override { return true; } @@ -69,7 +69,7 @@ class CBSFall : public CBodyState { float x4_rotateSpeed = 0.f; float x8_remTime = 0.f; pas::EFallState xc_fallState = pas::EFallState::Invalid; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc); + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; public: void Start(CBodyController& bc, CStateManager& mgr) override; @@ -79,7 +79,7 @@ public: class CBSGetup : public CBodyState { pas::EFallState x4_fallState = pas::EFallState::Invalid; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; public: void Start(CBodyController& bc, CStateManager& mgr) override; @@ -91,7 +91,7 @@ class CBSKnockBack : public CBodyState { float x4_curTime = 0.f; float x8_rotateSpeed = 0.f; float xc_remTime = 0.f; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; public: bool IsMoving() const override { return true; } @@ -102,17 +102,17 @@ public: class CBSLieOnGround : public CBodyState { bool x4_24_hasGroundHit : 1; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; public: - CBSLieOnGround(CActor& actor); + explicit CBSLieOnGround(CActor& actor); void Start(CBodyController& bc, CStateManager& mgr) override; pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override; void Shutdown(CBodyController& bc) override; }; class CBSStep : public CBodyState { - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; public: bool IsMoving() const override { return true; } @@ -127,7 +127,7 @@ protected: float x4_rotateSpeed = 0.f; zeus::CVector2f x8_dest; pas::ETurnDirection x10_turnDir = pas::ETurnDirection::Invalid; - bool FacingDest(CBodyController& bc) const; + bool FacingDest(const CBodyController& bc) const; public: bool CanShoot() const override { return true; } @@ -148,7 +148,7 @@ class CBSLoopAttack : public CBodyState { pas::ELoopAttackType x8_loopAttackType = pas::ELoopAttackType::Invalid; bool xc_24_waitForAnimOver : 1; bool xc_25_advance : 1; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; public: CBSLoopAttack() { @@ -165,7 +165,7 @@ class CBSLoopReaction : public CBodyState { pas::ELoopState x4_state = pas::ELoopState::Invalid; pas::EReactionType x8_reactionType = pas::EReactionType::Invalid; bool xc_24_loopHit : 1; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; bool PlayExitAnimation(CBodyController& bc, CStateManager& mgr) const; public: @@ -179,7 +179,7 @@ class CBSGroundHit : public CBodyState { float x4_rotateSpeed = 0.f; float x8_remTime = 0.f; pas::EFallState xc_fallState = pas::EFallState::Invalid; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; public: void Start(CBodyController& bc, CStateManager& mgr) override; @@ -188,7 +188,7 @@ public: }; class CBSGenerate : public CBodyState { - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; public: void Start(CBodyController& bc, CStateManager& mgr) override; @@ -198,7 +198,7 @@ public: class CBSJump : public CBodyState { pas::EJumpState x4_state = pas::EJumpState::Invalid; - pas::EJumpType x8_jumpType; + pas::EJumpType x8_jumpType{}; zeus::CVector3f xc_waypoint1; zeus::CVector3f x18_velocity; zeus::CVector3f x24_waypoint2; @@ -212,7 +212,7 @@ class CBSJump : public CBodyState { }; u32 _dummy = 0; }; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; bool CheckForWallJump(CBodyController& bc, CStateManager& mgr); void CheckForLand(CBodyController& bc, CStateManager& mgr); void PlayJumpLoop(CStateManager& mgr, CBodyController& bc); @@ -257,7 +257,7 @@ public: class CBSSlide : public CBodyState { float x4_rotateSpeed = 0.f; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; public: bool ApplyHeadTracking() const override { return false; } @@ -268,7 +268,7 @@ public: }; class CBSTaunt : public CBodyState { - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; public: void Start(CBodyController& bc, CStateManager& mgr) override; @@ -285,7 +285,7 @@ class CBSScripted : public CBodyState { u32 _dummy = 0; }; float x8_remTime = 0.f; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; public: bool ApplyHeadTracking() const override { return false; } @@ -298,7 +298,7 @@ class CBSCover : public CBodyState { pas::ECoverState x4_state = pas::ECoverState::Invalid; pas::ECoverDirection x8_coverDirection = pas::ECoverDirection::Invalid; bool xc_needsExit = false; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; public: bool ApplyHeadTracking() const override { return false; } @@ -320,7 +320,7 @@ class CBSWallHang : public CBodyState { }; u32 _dummy = 0; }; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; + pas::EAnimationState GetBodyStateTransition(float dt, const CBodyController& bc) const; void FixInPlace(CBodyController& bc); bool CheckForLand(CBodyController& bc, CStateManager& mgr); bool CheckForWall(CBodyController& bc, CStateManager& mgr); @@ -362,16 +362,16 @@ class CBSBiPedLocomotion : public CBSLocomotion { protected: rstl::reserved_vector, 8>, 14> x8_anims; pas::ELocomotionAnim x3c4_anim = pas::ELocomotionAnim::Invalid; - float x3c8_primeTime; + float x3c8_primeTime = 0.0f; float UpdateRun(float vel, CBodyController& bc, pas::ELocomotionAnim anim); float UpdateWalk(float vel, CBodyController& bc, pas::ELocomotionAnim anim); float UpdateStrafe(float vel, CBodyController& bc, pas::ELocomotionAnim anim); const std::pair& GetLocoAnimation(pas::ELocomotionType type, pas::ELocomotionAnim anim) const { - return x8_anims[int(type)][int(anim)]; + return x8_anims[size_t(type)][size_t(anim)]; } public: - CBSBiPedLocomotion(CActor& actor); + explicit CBSBiPedLocomotion(CActor& actor); bool IsMoving() const override { return x3c4_anim != pas::ELocomotionAnim::Idle; } void Start(CBodyController& bc, CStateManager& mgr) override; pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override; @@ -384,7 +384,7 @@ class CBSFlyerLocomotion : public CBSBiPedLocomotion { bool x3cc_pitchable; public: - CBSFlyerLocomotion(CActor& actor, bool pitchable); + explicit CBSFlyerLocomotion(CActor& actor, bool pitchable); bool IsPitchable() const override { return x3cc_pitchable; } float ApplyLocomotionPhysics(float dt, CBodyController& bc) override; virtual bool IsBackPedal(CBodyController& bc) const { return false; } @@ -392,13 +392,13 @@ public: class CBSWallWalkerLocomotion : public CBSBiPedLocomotion { public: - CBSWallWalkerLocomotion(CActor& actor); + explicit CBSWallWalkerLocomotion(CActor& actor); float ApplyLocomotionPhysics(float dt, CBodyController& bc) override; }; class CBSNewFlyerLocomotion : public CBSBiPedLocomotion { public: - CBSNewFlyerLocomotion(CActor& actor); + explicit CBSNewFlyerLocomotion(CActor& actor); float ApplyLocomotionPhysics(float dt, CBodyController& bc) override; float UpdateLocomotionAnimation(float dt, float velMag, CBodyController& bc, bool init) override; }; @@ -408,7 +408,7 @@ class CBSRestrictedLocomotion : public CBSLocomotion { pas::ELocomotionAnim x44_anim = pas::ELocomotionAnim::Invalid; public: - CBSRestrictedLocomotion(CActor& actor); + explicit CBSRestrictedLocomotion(CActor& actor); bool IsMoving() const override { return false; } float GetLocomotionSpeed(pas::ELocomotionType type, pas::ELocomotionAnim anim) const override { return 0.f; } float UpdateLocomotionAnimation(float dt, float velMag, CBodyController& bc, bool init) override; @@ -416,7 +416,7 @@ public: class CBSRestrictedFlyerLocomotion : public CBSRestrictedLocomotion { public: - CBSRestrictedFlyerLocomotion(CActor& actor); + explicit CBSRestrictedFlyerLocomotion(CActor& actor); float ApplyLocomotionPhysics(float dt, CBodyController& bc) override; }; } // namespace urde diff --git a/Runtime/Character/CBodyStateCmdMgr.hpp b/Runtime/Character/CBodyStateCmdMgr.hpp index 35448520a..17f4e5af5 100644 --- a/Runtime/Character/CBodyStateCmdMgr.hpp +++ b/Runtime/Character/CBodyStateCmdMgr.hpp @@ -13,7 +13,7 @@ class CBodyStateCmd { public: virtual ~CBodyStateCmd() = default; - CBodyStateCmd(EBodyStateCmd cmd) : x4_cmd(cmd) {} + explicit CBodyStateCmd(EBodyStateCmd cmd) : x4_cmd(cmd) {} EBodyStateCmd GetCommandId() const { return x4_cmd; } }; @@ -23,10 +23,11 @@ class CBCMeleeAttackCmd : public CBodyStateCmd { bool x18_hasTargetPos = false; public: - CBCMeleeAttackCmd() : CBodyStateCmd(EBodyStateCmd::MeleeAttack) {} - CBCMeleeAttackCmd(pas::ESeverity severity) : CBodyStateCmd(EBodyStateCmd::MeleeAttack), x8_severity(severity) {} - CBCMeleeAttackCmd(pas::ESeverity severity, const zeus::CVector3f& target) : CBodyStateCmd(EBodyStateCmd::MeleeAttack) - , x8_severity(severity), xc_targetPos(target), x18_hasTargetPos(true) {} + explicit CBCMeleeAttackCmd() : CBodyStateCmd(EBodyStateCmd::MeleeAttack) {} + explicit CBCMeleeAttackCmd(pas::ESeverity severity) + : CBodyStateCmd(EBodyStateCmd::MeleeAttack), x8_severity(severity) {} + explicit CBCMeleeAttackCmd(pas::ESeverity severity, const zeus::CVector3f& target) + : CBodyStateCmd(EBodyStateCmd::MeleeAttack), x8_severity(severity), xc_targetPos(target), x18_hasTargetPos(true) {} pas::ESeverity GetAttackSeverity() const { return x8_severity; } bool HasAttackTargetPos() const { return x18_hasTargetPos; } const zeus::CVector3f& GetAttackTargetPos() const { return xc_targetPos; } @@ -38,8 +39,8 @@ class CBCProjectileAttackCmd : public CBodyStateCmd { bool x18_blendAnims = false; public: - CBCProjectileAttackCmd() : CBodyStateCmd(EBodyStateCmd::ProjectileAttack) {} - CBCProjectileAttackCmd(pas::ESeverity severity, const zeus::CVector3f& vec, bool b) + explicit CBCProjectileAttackCmd() : CBodyStateCmd(EBodyStateCmd::ProjectileAttack) {} + explicit CBCProjectileAttackCmd(pas::ESeverity severity, const zeus::CVector3f& vec, bool b) : CBodyStateCmd(EBodyStateCmd::ProjectileAttack), x8_severity(severity), xc_target(vec), x18_blendAnims(b) {} pas::ESeverity GetAttackSeverity() const { return x8_severity; } const zeus::CVector3f& GetTargetPosition() const { return xc_target; } @@ -51,8 +52,8 @@ class CBCStepCmd : public CBodyStateCmd { pas::EStepType xc_type = pas::EStepType::Normal; public: - CBCStepCmd() : CBodyStateCmd(EBodyStateCmd::Step) {} - CBCStepCmd(pas::EStepDirection dir, pas::EStepType type) + explicit CBCStepCmd() : CBodyStateCmd(EBodyStateCmd::Step) {} + explicit CBCStepCmd(pas::EStepDirection dir, pas::EStepType type) : CBodyStateCmd(EBodyStateCmd::Step), x8_dir(dir), xc_type(type) {} pas::EStepDirection GetStepDirection() const { return x8_dir; } pas::EStepType GetStepType() const { return xc_type; } @@ -66,16 +67,16 @@ class CBCJumpCmd : public CBodyStateCmd { bool x24_25_startInJumpLoop : 1; public: - CBCJumpCmd() : CBodyStateCmd(EBodyStateCmd::Jump) { + explicit CBCJumpCmd() : CBodyStateCmd(EBodyStateCmd::Jump) { x24_24_wallJump = false; x24_25_startInJumpLoop = false; } - CBCJumpCmd(const zeus::CVector3f& wp1, pas::EJumpType type, bool startInLoop = false) + explicit CBCJumpCmd(const zeus::CVector3f& wp1, pas::EJumpType type, bool startInLoop = false) : CBodyStateCmd(EBodyStateCmd::Jump), x8_type(type), xc_waypoint1(wp1) { x24_24_wallJump = false; x24_25_startInJumpLoop = startInLoop; } - CBCJumpCmd(const zeus::CVector3f& wp1, const zeus::CVector3f& wp2, pas::EJumpType type) + explicit CBCJumpCmd(const zeus::CVector3f& wp1, const zeus::CVector3f& wp2, pas::EJumpType type) : CBodyStateCmd(EBodyStateCmd::Jump), x8_type(type), xc_waypoint1(wp1), x18_waypoint2(wp2) { x24_24_wallJump = true; x24_25_startInJumpLoop = false; @@ -95,22 +96,22 @@ class CBCGenerateCmd : public CBodyStateCmd { bool x1c_25_overrideAnim : 1; public: - CBCGenerateCmd() : CBodyStateCmd(EBodyStateCmd::Generate) { + explicit CBCGenerateCmd() : CBodyStateCmd(EBodyStateCmd::Generate) { x1c_24_targetTransform = false; x1c_25_overrideAnim = false; } - CBCGenerateCmd(pas::EGenerateType type) + explicit CBCGenerateCmd(pas::EGenerateType type) : CBodyStateCmd(EBodyStateCmd::Generate), x8_type(type) { x1c_24_targetTransform = false; x1c_25_overrideAnim = false; } - CBCGenerateCmd(pas::EGenerateType type, s32 animId) + explicit CBCGenerateCmd(pas::EGenerateType type, s32 animId) : CBodyStateCmd(EBodyStateCmd::Generate), x8_type(type), x18_animId(animId) { x1c_24_targetTransform = false; x1c_25_overrideAnim = animId != -1; } - CBCGenerateCmd(pas::EGenerateType type, const zeus::CVector3f& vec, bool targetTransform = false, - bool overrideAnim = false) + explicit CBCGenerateCmd(pas::EGenerateType type, const zeus::CVector3f& vec, bool targetTransform = false, + bool overrideAnim = false) : CBodyStateCmd(EBodyStateCmd::Generate), x8_type(type), xc_targetPos(vec) { x1c_24_targetTransform = targetTransform; x1c_25_overrideAnim = overrideAnim; @@ -127,8 +128,8 @@ class CBCKnockBackCmd : public CBodyStateCmd { pas::ESeverity x14_severity = pas::ESeverity::Invalid; public: - CBCKnockBackCmd() : CBodyStateCmd(EBodyStateCmd::KnockBack) {} - CBCKnockBackCmd(const zeus::CVector3f& vec, pas::ESeverity severity) + explicit CBCKnockBackCmd() : CBodyStateCmd(EBodyStateCmd::KnockBack) {} + explicit CBCKnockBackCmd(const zeus::CVector3f& vec, pas::ESeverity severity) : CBodyStateCmd(EBodyStateCmd::KnockBack), x8_dir(vec), x14_severity(severity) {} const zeus::CVector3f& GetHitDirection() const { return x8_dir; } pas::ESeverity GetHitSeverity() const { return x14_severity; } @@ -140,8 +141,8 @@ class CBCHurledCmd : public CBodyStateCmd { bool x20_startInKnockLoop = false; public: - CBCHurledCmd() : CBodyStateCmd(EBodyStateCmd::Hurled) {} - CBCHurledCmd(const zeus::CVector3f& dir, const zeus::CVector3f& launchVel, bool startInLoop = false) + explicit CBCHurledCmd() : CBodyStateCmd(EBodyStateCmd::Hurled) {} + explicit CBCHurledCmd(const zeus::CVector3f& dir, const zeus::CVector3f& launchVel, bool startInLoop = false) : CBodyStateCmd(EBodyStateCmd::Hurled) , x8_direction(dir) , x14_launchVel(launchVel) @@ -156,8 +157,8 @@ class CBCGetupCmd : public CBodyStateCmd { pas::EGetupType x8_type = pas::EGetupType::Invalid; public: - CBCGetupCmd() : CBodyStateCmd(EBodyStateCmd::Getup) {} - CBCGetupCmd(pas::EGetupType type) : CBodyStateCmd(EBodyStateCmd::Getup), x8_type(type) {} + explicit CBCGetupCmd() : CBodyStateCmd(EBodyStateCmd::Getup) {} + explicit CBCGetupCmd(pas::EGetupType type) : CBodyStateCmd(EBodyStateCmd::Getup), x8_type(type) {} pas::EGetupType GetGetupType() const { return x8_type; } }; @@ -165,8 +166,8 @@ class CBCLoopReactionCmd : public CBodyStateCmd { pas::EReactionType x8_type = pas::EReactionType::Invalid; public: - CBCLoopReactionCmd() : CBodyStateCmd(EBodyStateCmd::LoopReaction) {} - CBCLoopReactionCmd(pas::EReactionType type) : CBodyStateCmd(EBodyStateCmd::LoopReaction), x8_type(type) {} + explicit CBCLoopReactionCmd() : CBodyStateCmd(EBodyStateCmd::LoopReaction) {} + explicit CBCLoopReactionCmd(pas::EReactionType type) : CBodyStateCmd(EBodyStateCmd::LoopReaction), x8_type(type) {} pas::EReactionType GetReactionType() const { return x8_type; } }; @@ -174,8 +175,8 @@ class CBCLoopHitReactionCmd : public CBodyStateCmd { pas::EReactionType x8_type = pas::EReactionType::Invalid; public: - CBCLoopHitReactionCmd() : CBodyStateCmd(EBodyStateCmd::LoopHitReaction) {} - CBCLoopHitReactionCmd(pas::EReactionType type) : CBodyStateCmd(EBodyStateCmd::LoopHitReaction), x8_type(type) {} + explicit CBCLoopHitReactionCmd() : CBodyStateCmd(EBodyStateCmd::LoopHitReaction) {} + explicit CBCLoopHitReactionCmd(pas::EReactionType type) : CBodyStateCmd(EBodyStateCmd::LoopHitReaction), x8_type(type) {} pas::EReactionType GetReactionType() const { return x8_type; } }; @@ -184,8 +185,8 @@ class CBCKnockDownCmd : public CBodyStateCmd { pas::ESeverity x14_severity = pas::ESeverity::Invalid; public: - CBCKnockDownCmd() : CBodyStateCmd(EBodyStateCmd::KnockDown) {} - CBCKnockDownCmd(const zeus::CVector3f& vec, pas::ESeverity severity) + explicit CBCKnockDownCmd() : CBodyStateCmd(EBodyStateCmd::KnockDown) {} + explicit CBCKnockDownCmd(const zeus::CVector3f& vec, pas::ESeverity severity) : CBodyStateCmd(EBodyStateCmd::KnockDown), x8_dir(vec), x14_severity(severity) {} const zeus::CVector3f& GetHitDirection() const { return x8_dir; } pas::ESeverity GetHitSeverity() const { return x14_severity; } @@ -196,8 +197,8 @@ class CBCSlideCmd : public CBodyStateCmd { zeus::CVector3f xc_dir; public: - CBCSlideCmd() : CBodyStateCmd(EBodyStateCmd::Slide) {} - CBCSlideCmd(pas::ESlideType type, const zeus::CVector3f& dir) + explicit CBCSlideCmd() : CBodyStateCmd(EBodyStateCmd::Slide) {} + explicit CBCSlideCmd(pas::ESlideType type, const zeus::CVector3f& dir) : CBodyStateCmd(EBodyStateCmd::Slide), x8_type(type), xc_dir(dir) {} pas::ESlideType GetSlideType() const { return x8_type; } const zeus::CVector3f& GetSlideDirection() const { return xc_dir; } @@ -210,11 +211,11 @@ class CBCScriptedCmd : public CBodyStateCmd { float x10_loopDur = 0.f; public: - CBCScriptedCmd() : CBodyStateCmd(EBodyStateCmd::Scripted) { + explicit CBCScriptedCmd() : CBodyStateCmd(EBodyStateCmd::Scripted) { xc_24_loopAnim = false; xc_25_timedLoop = false; } - CBCScriptedCmd(int i, bool b1, bool b2, float f) + explicit CBCScriptedCmd(int i, bool b1, bool b2, float f) : CBodyStateCmd(EBodyStateCmd::Scripted), x8_anim(i), x10_loopDur(f) { xc_24_loopAnim = b1; xc_25_timedLoop = b2; @@ -231,8 +232,8 @@ class CBCCoverCmd : public CBodyStateCmd { zeus::CVector3f x18_alignDir; public: - CBCCoverCmd() : CBodyStateCmd(EBodyStateCmd::Cover) {} - CBCCoverCmd(pas::ECoverDirection dir, const zeus::CVector3f& v1, const zeus::CVector3f& v2) + explicit CBCCoverCmd() : CBodyStateCmd(EBodyStateCmd::Cover) {} + explicit CBCCoverCmd(pas::ECoverDirection dir, const zeus::CVector3f& v1, const zeus::CVector3f& v2) : CBodyStateCmd(EBodyStateCmd::Cover), x8_dir(dir), xc_targetPos(v1), x18_alignDir(v2) {} pas::ECoverDirection GetDirection() const { return x8_dir; } const zeus::CVector3f& GetTarget() const { return xc_targetPos; } @@ -243,22 +244,22 @@ class CBCWallHangCmd : public CBodyStateCmd { TUniqueId x8_wpId = kInvalidUniqueId; public: - CBCWallHangCmd() : CBodyStateCmd(EBodyStateCmd::WallHang) {} - CBCWallHangCmd(TUniqueId uid) : CBodyStateCmd(EBodyStateCmd::WallHang), x8_wpId(uid) {} + explicit CBCWallHangCmd() : CBodyStateCmd(EBodyStateCmd::WallHang) {} + explicit CBCWallHangCmd(TUniqueId uid) : CBodyStateCmd(EBodyStateCmd::WallHang), x8_wpId(uid) {} TUniqueId GetTarget() const { return x8_wpId; } }; class CBCAdditiveAimCmd : public CBodyStateCmd { public: - CBCAdditiveAimCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveAim) {} + explicit CBCAdditiveAimCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveAim) {} }; class CBCAdditiveFlinchCmd : public CBodyStateCmd { float x8_weight = 1.f; public: - CBCAdditiveFlinchCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveFlinch) {} - CBCAdditiveFlinchCmd(float f) : CBodyStateCmd(EBodyStateCmd::AdditiveFlinch), x8_weight(f) {} + explicit CBCAdditiveFlinchCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveFlinch) {} + explicit CBCAdditiveFlinchCmd(float f) : CBodyStateCmd(EBodyStateCmd::AdditiveFlinch), x8_weight(f) {} float GetWeight() const { return x8_weight; } }; @@ -268,9 +269,9 @@ class CBCAdditiveReactionCmd : public CBodyStateCmd { bool x10_active = false; public: - CBCAdditiveReactionCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveReaction) {} - CBCAdditiveReactionCmd(pas::EAdditiveReactionType type, float f, bool active) - : CBodyStateCmd(EBodyStateCmd::AdditiveReaction), x8_weight(f), xc_type(type), x10_active(active) {} + explicit CBCAdditiveReactionCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveReaction) {} + explicit CBCAdditiveReactionCmd(pas::EAdditiveReactionType type, float weight, bool active) + : CBodyStateCmd(EBodyStateCmd::AdditiveReaction), x8_weight(weight), xc_type(type), x10_active(active) {} pas::EAdditiveReactionType GetType() const { return xc_type; } float GetWeight() const { return x8_weight; } bool GetIsActive() const { return x10_active; } @@ -281,8 +282,8 @@ class CBCLoopAttackCmd : public CBodyStateCmd { u32 xc_waitForAnimOver = 0; public: - CBCLoopAttackCmd() : CBodyStateCmd(EBodyStateCmd::LoopAttack) {} - CBCLoopAttackCmd(pas::ELoopAttackType type) : CBodyStateCmd(EBodyStateCmd::LoopAttack), x8_type(type) {} + explicit CBCLoopAttackCmd() : CBodyStateCmd(EBodyStateCmd::LoopAttack) {} + explicit CBCLoopAttackCmd(pas::ELoopAttackType type) : CBodyStateCmd(EBodyStateCmd::LoopAttack), x8_type(type) {} pas::ELoopAttackType GetAttackType() const { return x8_type; } bool WaitForAnimOver() const { return xc_waitForAnimOver == 1; } }; @@ -291,8 +292,8 @@ class CBCTauntCmd : public CBodyStateCmd { pas::ETauntType x8_type = pas::ETauntType::Invalid; public: - CBCTauntCmd() : CBodyStateCmd(EBodyStateCmd::Taunt) {} - CBCTauntCmd(pas::ETauntType type) : CBodyStateCmd(EBodyStateCmd::Taunt), x8_type(type) {} + explicit CBCTauntCmd() : CBodyStateCmd(EBodyStateCmd::Taunt) {} + explicit CBCTauntCmd(pas::ETauntType type) : CBodyStateCmd(EBodyStateCmd::Taunt), x8_type(type) {} pas::ETauntType GetTauntType() const { return x8_type; } }; @@ -302,7 +303,7 @@ class CBCLocomotionCmd { float x18_weight; public: - CBCLocomotionCmd(const zeus::CVector3f& move, const zeus::CVector3f& face, float weight) + explicit CBCLocomotionCmd(const zeus::CVector3f& move, const zeus::CVector3f& face, float weight) : x0_move(move), xc_face(face), x18_weight(weight) {} const zeus::CVector3f& GetMoveVector() const { return x0_move; } const zeus::CVector3f& GetFaceVector() const { return xc_face; } @@ -324,7 +325,7 @@ class CBodyStateCmdMgr { u32 xb4_deliveredCmdMask = 0; CBCGetupCmd xb8_getup; CBCStepCmd xc4_step; - CBodyStateCmd xd4_die = {EBodyStateCmd::Die}; + CBodyStateCmd xd4_die{EBodyStateCmd::Die}; CBCKnockDownCmd xdc_knockDown; CBCKnockBackCmd xf4_knockBack; CBCMeleeAttackCmd x10c_meleeAttack; @@ -332,10 +333,10 @@ class CBodyStateCmdMgr { CBCLoopAttackCmd x144_loopAttack; CBCLoopReactionCmd x154_loopReaction; CBCLoopHitReactionCmd x160_loopHitReaction; - CBodyStateCmd x16c_exitState = {EBodyStateCmd::ExitState}; - CBodyStateCmd x174_leanFromCover = {EBodyStateCmd::LeanFromCover}; - CBodyStateCmd x17c_nextState = {EBodyStateCmd::NextState}; - CBodyStateCmd x184_maintainVelocity = {EBodyStateCmd::MaintainVelocity}; + CBodyStateCmd x16c_exitState{EBodyStateCmd::ExitState}; + CBodyStateCmd x174_leanFromCover{EBodyStateCmd::LeanFromCover}; + CBodyStateCmd x17c_nextState{EBodyStateCmd::NextState}; + CBodyStateCmd x184_maintainVelocity{EBodyStateCmd::MaintainVelocity}; CBCGenerateCmd x18c_generate; CBCHurledCmd x1ac_hurled; CBCJumpCmd x1d0_jump; @@ -344,12 +345,12 @@ class CBodyStateCmdMgr { CBCScriptedCmd x21c_scripted; CBCCoverCmd x230_cover; CBCWallHangCmd x254_wallHang; - CBodyStateCmd x260_locomotion = {EBodyStateCmd::Locomotion}; - CBodyStateCmd x268_additiveIdle = {EBodyStateCmd::AdditiveIdle}; + CBodyStateCmd x260_locomotion{EBodyStateCmd::Locomotion}; + CBodyStateCmd x268_additiveIdle{EBodyStateCmd::AdditiveIdle}; CBCAdditiveAimCmd x270_additiveAim; CBCAdditiveFlinchCmd x278_additiveFlinch; CBCAdditiveReactionCmd x284_additiveReaction; - CBodyStateCmd x298_stopReaction = {EBodyStateCmd::StopReaction}; + CBodyStateCmd x298_stopReaction{EBodyStateCmd::StopReaction}; void DeliverCmd(EBodyStateCmd cmd) { xb4_deliveredCmdMask |= (1 << int(cmd)); } public: @@ -451,15 +452,23 @@ public: void BlendSteeringCmds(); void Reset(); void ClearLocomotionCmds(); - const CBodyStateCmd* GetCmd(EBodyStateCmd cmd) const { - if (xb4_deliveredCmdMask & (1 << int(cmd))) - return x40_commandTable[int(cmd)]; + + CBodyStateCmd* GetCmd(EBodyStateCmd cmd) { + if ((xb4_deliveredCmdMask & (1U << u32(cmd))) != 0) { + return x40_commandTable[size_t(cmd)]; + } return nullptr; } + const CBodyStateCmd* GetCmd(EBodyStateCmd cmd) const { + if ((xb4_deliveredCmdMask & (1U << u32(cmd))) != 0) { + return x40_commandTable[size_t(cmd)]; + } + return nullptr; + } + const zeus::CVector3f& GetMoveVector() const { return x0_move; } const zeus::CVector3f& GetFaceVector() const { return xc_face; } const zeus::CVector3f& GetTargetVector() const { return x18_target; } - void SetTargetVector(const zeus::CVector3f& target) { x18_target = target; } const zeus::CVector3f& GetAdditiveTargetVector() const { return x24_additiveTarget; } }; diff --git a/Runtime/Character/CBodyStateInfo.cpp b/Runtime/Character/CBodyStateInfo.cpp index 027a5891b..a3a480127 100644 --- a/Runtime/Character/CBodyStateInfo.cpp +++ b/Runtime/Character/CBodyStateInfo.cpp @@ -8,7 +8,7 @@ namespace urde { CBodyStateInfo::CBodyStateInfo(CActor& actor, EBodyType type) { x34_24_changeLocoAtEndOfAnimOnly = false; const CPASDatabase& pasDatabase = actor.GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase(); - for (int i = 0; i < pasDatabase.GetNumAnimStates(); ++i) { + for (size_t i = 0; i < pasDatabase.GetNumAnimStates(); ++i) { const CPASAnimState* state = pasDatabase.GetAnimStateByIndex(i); std::unique_ptr bs; @@ -42,10 +42,10 @@ CBodyStateInfo::CBodyStateInfo(CActor& actor, EBodyType type) { } x1c_additiveStates.reserve(4); - x1c_additiveStates.push_back({pas::EAnimationState::AdditiveIdle, std::make_unique()}); - x1c_additiveStates.push_back({pas::EAnimationState::AdditiveAim, std::make_unique()}); - x1c_additiveStates.push_back({pas::EAnimationState::AdditiveFlinch, std::make_unique()}); - x1c_additiveStates.push_back({pas::EAnimationState::AdditiveReaction, std::make_unique()}); + x1c_additiveStates.emplace_back(pas::EAnimationState::AdditiveIdle, std::make_unique()); + x1c_additiveStates.emplace_back(pas::EAnimationState::AdditiveAim, std::make_unique()); + x1c_additiveStates.emplace_back(pas::EAnimationState::AdditiveFlinch, std::make_unique()); + x1c_additiveStates.emplace_back(pas::EAnimationState::AdditiveReaction, std::make_unique()); } std::unique_ptr CBodyStateInfo::SetupRestrictedFlyerBodyStates(int stateId, CActor& actor) const { diff --git a/Runtime/Character/CBoneTracking.cpp b/Runtime/Character/CBoneTracking.cpp index 79c9b67c6..0814f4be2 100644 --- a/Runtime/Character/CBoneTracking.cpp +++ b/Runtime/Character/CBoneTracking.cpp @@ -98,7 +98,7 @@ void CBoneTracking::PreRender(const CStateManager& mgr, CAnimData& animData, con x18_time = 0.f; } -void CBoneTracking::SetActive(bool) { x36_24_active = true; } +void CBoneTracking::SetActive(bool active) { x36_24_active = active; } void CBoneTracking::SetTarget(TUniqueId target) { x34_target = target; } diff --git a/Runtime/Character/CBoneTracking.hpp b/Runtime/Character/CBoneTracking.hpp index 4f71351cc..148c8de06 100644 --- a/Runtime/Character/CBoneTracking.hpp +++ b/Runtime/Character/CBoneTracking.hpp @@ -53,7 +53,7 @@ public: const zeus::CVector3f& vec, const CBodyController& bodyController); void PreRender(const CStateManager& mgr, CAnimData& animData, const zeus::CTransform& worldXf, const zeus::CVector3f& localOffsetScale, bool tracking); - void SetActive(bool b); + void SetActive(bool active); void SetTarget(TUniqueId id); void UnsetTarget(); void SetTargetPosition(const zeus::CVector3f& pos); diff --git a/Runtime/Character/CBoolPOINode.hpp b/Runtime/Character/CBoolPOINode.hpp index 9dae11934..c64468da7 100644 --- a/Runtime/Character/CBoolPOINode.hpp +++ b/Runtime/Character/CBoolPOINode.hpp @@ -9,8 +9,8 @@ class CBoolPOINode : public CPOINode { bool x38_val = false; public: - CBoolPOINode(); - CBoolPOINode(CInputStream& in); + explicit CBoolPOINode(); + explicit CBoolPOINode(CInputStream& in); bool GetValue() const { return x38_val; } static CBoolPOINode CopyNodeMinusStartTime(const CBoolPOINode& node, const CCharAnimTime& startTime); }; diff --git a/Runtime/Character/CCharAnimTime.cpp b/Runtime/Character/CCharAnimTime.cpp index f64512ea7..6d3d0eea1 100644 --- a/Runtime/Character/CCharAnimTime.cpp +++ b/Runtime/Character/CCharAnimTime.cpp @@ -5,10 +5,6 @@ namespace urde { -CCharAnimTime CCharAnimTime::Infinity() { - return {EType::Infinity, 1.f}; -} - bool CCharAnimTime::EqualsZero() const { if (x4_type == EType::ZeroIncreasing || x4_type == EType::ZeroSteady || x4_type == EType::ZeroDecreasing) return true; diff --git a/Runtime/Character/CCharAnimTime.hpp b/Runtime/Character/CCharAnimTime.hpp index 3aed3e0e8..e28e36e7d 100644 --- a/Runtime/Character/CCharAnimTime.hpp +++ b/Runtime/Character/CCharAnimTime.hpp @@ -16,13 +16,12 @@ private: EType x4_type = EType::ZeroSteady; public: - CCharAnimTime() = default; - CCharAnimTime(CInputStream& in) : x0_time(in.readFloatBig()), x4_type(EType(in.readUint32Big())) {} - CCharAnimTime(float time) : x0_time(time), x4_type(x0_time != 0.f ? EType::NonZero : EType::ZeroSteady) {} + constexpr CCharAnimTime() = default; + constexpr CCharAnimTime(float time) : x0_time(time), x4_type(x0_time != 0.f ? EType::NonZero : EType::ZeroSteady) {} + constexpr CCharAnimTime(EType type, float t) : x0_time(t), x4_type(type) {} + explicit CCharAnimTime(CInputStream& in) : x0_time(in.readFloatBig()), x4_type(EType(in.readUint32Big())) {} - CCharAnimTime(EType type, const float& t) : x0_time(t), x4_type(type) {} - - static CCharAnimTime Infinity(); + static constexpr CCharAnimTime Infinity() { return {EType::Infinity, 1.0f}; } float GetSeconds() const { return x0_time; } bool EqualsZero() const; diff --git a/Runtime/Character/CCharacterFactory.cpp b/Runtime/Character/CCharacterFactory.cpp index 13088c44c..c0d2e71d7 100644 --- a/Runtime/Character/CCharacterFactory.cpp +++ b/Runtime/Character/CCharacterFactory.cpp @@ -76,17 +76,16 @@ std::unique_ptr CCharacterFactory::CDummyFactory::LoadNewResourcePartSync( std::unique_ptr CCharacterFactory::CreateCharacter(int charIdx, bool loop, const TLockedToken& factory, - int defaultAnim, int drawInsts) const { + int defaultAnim, int drawInsts) { const CCharacterInfo& charInfo = x4_charInfoDB[charIdx]; const CVParamTransfer charParm(new TObjOwnerParam(&charInfo)); - TToken skinnedModel = const_cast(this)->x70_cacheResPool.GetObj( - {FourCC(drawInsts << 16), charInfo.GetModelId()}, charParm); + TToken skinnedModel = + x70_cacheResPool.GetObj({FourCC(drawInsts << 16), charInfo.GetModelId()}, charParm); std::optional> iceModel; if (charInfo.GetIceModelId().IsValid() && charInfo.GetIceSkinRulesId().IsValid()) { - iceModel.emplace(const_cast(this)->x70_cacheResPool.GetObj( - {FourCC((drawInsts << 16) | 1), charInfo.GetIceModelId()}, charParm)); + iceModel.emplace(x70_cacheResPool.GetObj({FourCC((drawInsts << 16) | 1), charInfo.GetIceModelId()}, charParm)); } return std::make_unique(x68_selfId, charInfo, defaultAnim, charIdx, loop, x14_charLayoutInfoDB[charIdx], diff --git a/Runtime/Character/CCharacterFactory.hpp b/Runtime/Character/CCharacterFactory.hpp index 7222b1be0..b1dcf44ed 100644 --- a/Runtime/Character/CCharacterFactory.hpp +++ b/Runtime/Character/CCharacterFactory.hpp @@ -68,7 +68,7 @@ public: CCharacterFactory(CSimplePool& store, const CAnimCharacterSet& ancs, CAssetId); std::unique_ptr CreateCharacter(int charIdx, bool loop, const TLockedToken& factory, - int defaultAnim, int drawInsts) const; + int defaultAnim, int drawInsts); CAssetId GetEventResourceIdForAnimResourceId(CAssetId animId) const; const CCharacterInfo& GetCharInfo(int charIdx) const { return x4_charInfoDB[charIdx]; } diff --git a/Runtime/Character/CCharacterInfo.hpp b/Runtime/Character/CCharacterInfo.hpp index b5e5a8d22..9f57b57d9 100644 --- a/Runtime/Character/CCharacterInfo.hpp +++ b/Runtime/Character/CCharacterInfo.hpp @@ -47,7 +47,7 @@ private: std::vector xb0_animIdxs; public: - CCharacterInfo(CInputStream& in); + explicit CCharacterInfo(CInputStream& in); std::string_view GetCharacterName() const { return x4_name; } CAssetId GetModelId() const { return x14_cmdl; } diff --git a/Runtime/Character/CCharacterSet.hpp b/Runtime/Character/CCharacterSet.hpp index 9bb0fcdba..f3c8e46f7 100644 --- a/Runtime/Character/CCharacterSet.hpp +++ b/Runtime/Character/CCharacterSet.hpp @@ -13,7 +13,7 @@ class CCharacterSet { std::map x4_characters; public: - CCharacterSet(CInputStream& in); + explicit CCharacterSet(CInputStream& in); const std::map& GetCharacterInfoMap() const { return x4_characters; } }; diff --git a/Runtime/Character/CEffectComponent.hpp b/Runtime/Character/CEffectComponent.hpp index ab290af75..f0a8a688c 100644 --- a/Runtime/Character/CEffectComponent.hpp +++ b/Runtime/Character/CEffectComponent.hpp @@ -18,7 +18,7 @@ class CEffectComponent { static SObjectTag GetSObjectTagFromStream(CInputStream& in); public: - CEffectComponent(CInputStream& in); + explicit CEffectComponent(CInputStream& in); std::string_view GetComponentName() const { return x0_name; } const SObjectTag& GetParticleTag() const { return x10_tag; } diff --git a/Runtime/Character/CFBStreamedAnimReader.hpp b/Runtime/Character/CFBStreamedAnimReader.hpp index 15af8800d..aa892f081 100644 --- a/Runtime/Character/CFBStreamedAnimReader.hpp +++ b/Runtime/Character/CFBStreamedAnimReader.hpp @@ -42,7 +42,7 @@ class CFBStreamedAnimReaderTotals { void Allocate(u32 chanCount); public: - CFBStreamedAnimReaderTotals(const CFBStreamedCompression& source); + explicit CFBStreamedAnimReaderTotals(const CFBStreamedCompression& source); void Initialize(const CFBStreamedCompression& source); void IncrementInto(CBitLevelLoader& loader, const CFBStreamedCompression& source, CFBStreamedAnimReaderTotals& dest); void CalculateDown(); @@ -61,7 +61,7 @@ class CFBStreamedPairOfTotals { float x78_t = 0.f; public: - CFBStreamedPairOfTotals(const TSubAnimTypeToken& source); + explicit CFBStreamedPairOfTotals(const TSubAnimTypeToken& source); void SetTime(CBitLevelLoader& loader, const CCharAnimTime& time); void DoIncrement(CBitLevelLoader& loader); float GetT() const { return x78_t; } @@ -76,7 +76,7 @@ class CBitLevelLoader { size_t m_bitIdx = 0; public: - CBitLevelLoader(const void* data) : m_data(reinterpret_cast(data)) {} + explicit CBitLevelLoader(const void* data) : m_data(reinterpret_cast(data)) {} void Reset() { m_bitIdx = 0; } u32 LoadUnsigned(u8 q); s32 LoadSigned(u8 q); @@ -88,7 +88,7 @@ class CSegIdToIndexConverter { std::array x0_indices; public: - CSegIdToIndexConverter(const CFBStreamedAnimReaderTotals& totals); + explicit CSegIdToIndexConverter(const CFBStreamedAnimReaderTotals& totals); s32 SegIdToIndex(const CSegId& id) const { return x0_indices[id]; } }; @@ -104,7 +104,7 @@ class CFBStreamedAnimReader : public CAnimSourceReaderBase { zeus::CQuaternion GetRotation(const CSegId& seg) const; public: - CFBStreamedAnimReader(const TSubAnimTypeToken& source, const CCharAnimTime& time); + explicit CFBStreamedAnimReader(const TSubAnimTypeToken& source, const CCharAnimTime& time); SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const override; bool VSupportsReverseView() const override { return false; } diff --git a/Runtime/Character/CFBStreamedCompression.hpp b/Runtime/Character/CFBStreamedCompression.hpp index 0c37c0fd6..5c519280f 100644 --- a/Runtime/Character/CFBStreamedCompression.hpp +++ b/Runtime/Character/CFBStreamedCompression.hpp @@ -66,7 +66,7 @@ private: float CalculateAverageVelocity(const u8* chans) const; public: - CFBStreamedCompression(CInputStream& in, IObjectStore& objStore, bool pc); + explicit CFBStreamedCompression(CInputStream& in, IObjectStore& objStore, bool pc); const Header& MainHeader() const { return *reinterpret_cast(xc_rotsAndOffs.get()); } const u32* GetTimes() const; const u8* GetPerChannelHeaders() const; diff --git a/Runtime/Character/CHalfTransition.hpp b/Runtime/Character/CHalfTransition.hpp index ad6ab9397..76d5a58bb 100644 --- a/Runtime/Character/CHalfTransition.hpp +++ b/Runtime/Character/CHalfTransition.hpp @@ -13,7 +13,7 @@ class CHalfTransition { std::shared_ptr x4_trans; public: - CHalfTransition(CInputStream& in); + explicit CHalfTransition(CInputStream& in); u32 GetId() const { return x0_id; } const std::shared_ptr& GetMetaTrans() const { return x4_trans; } }; diff --git a/Runtime/Character/CHierarchyPoseBuilder.hpp b/Runtime/Character/CHierarchyPoseBuilder.hpp index aeaa10035..abe1f13e2 100644 --- a/Runtime/Character/CHierarchyPoseBuilder.hpp +++ b/Runtime/Character/CHierarchyPoseBuilder.hpp @@ -13,16 +13,18 @@ class CLayoutDescription; class CPoseAsTransforms; class CHierarchyPoseBuilder { - CLayoutDescription x0_layoutDesc; - CSegId x30_rootId; - bool x34_hasRoot = false; - +public: struct CTreeNode { CSegId x0_child = 0; CSegId x1_sibling = 0; zeus::CQuaternion x4_rotation; zeus::CVector3f x14_offset; }; + +private: + CLayoutDescription x0_layoutDesc; + CSegId x30_rootId; + bool x34_hasRoot = false; TSegIdMap x38_treeMap; void BuildIntoHierarchy(const CCharLayoutInfo& layout, const CSegId& boneId, const CSegId& nullId); @@ -34,7 +36,7 @@ class CHierarchyPoseBuilder { const zeus::CVector3f& offset) const; public: - CHierarchyPoseBuilder(const CLayoutDescription& layout); + explicit CHierarchyPoseBuilder(const CLayoutDescription& layout); const TLockedToken& CharLayoutInfo() const { return x0_layoutDesc.ScaledLayout(); } bool HasRoot() const { return x34_hasRoot; } diff --git a/Runtime/Character/CInt32POINode.hpp b/Runtime/Character/CInt32POINode.hpp index 898fff078..2ca709b42 100644 --- a/Runtime/Character/CInt32POINode.hpp +++ b/Runtime/Character/CInt32POINode.hpp @@ -15,7 +15,7 @@ class CInt32POINode : public CPOINode { public: CInt32POINode(); CInt32POINode(std::string_view, EPOIType, const CCharAnimTime&, s32, bool, float, s32, s32, s32, std::string_view); - CInt32POINode(CInputStream& in); + explicit CInt32POINode(CInputStream& in); s32 GetValue() const { return x38_val; } std::string_view GetLocatorName() const { return x3c_locatorName; } diff --git a/Runtime/Character/CLayoutDescription.hpp b/Runtime/Character/CLayoutDescription.hpp index 248f57486..e6f29864a 100644 --- a/Runtime/Character/CLayoutDescription.hpp +++ b/Runtime/Character/CLayoutDescription.hpp @@ -13,7 +13,7 @@ class CLayoutDescription { public: class CScaledLayoutDescription { TLockedToken x0_layoutToken; - float xc_scale; + float xc_scale = 0.0f; std::optional x10_scaleVec; public: @@ -27,7 +27,7 @@ private: std::optional xc_scaled; public: - CLayoutDescription(const TLockedToken& token) : x0_layoutToken(token) {} + explicit CLayoutDescription(const TLockedToken& token) : x0_layoutToken(token) {} const std::optional& GetScaledLayoutDescription() const { return xc_scaled; } diff --git a/Runtime/Character/CMetaAnimBlend.hpp b/Runtime/Character/CMetaAnimBlend.hpp index a2be465be..52bee1aa7 100644 --- a/Runtime/Character/CMetaAnimBlend.hpp +++ b/Runtime/Character/CMetaAnimBlend.hpp @@ -14,7 +14,7 @@ class CMetaAnimBlend : public IMetaAnim { bool x10_; public: - CMetaAnimBlend(CInputStream& in); + explicit CMetaAnimBlend(CInputStream& in); EMetaAnimType GetType() const override { return EMetaAnimType::Blend; } void GetUniquePrimitives(std::set& primsOut) const override; diff --git a/Runtime/Character/CMetaAnimPhaseBlend.hpp b/Runtime/Character/CMetaAnimPhaseBlend.hpp index 81686f5c7..c8131ff59 100644 --- a/Runtime/Character/CMetaAnimPhaseBlend.hpp +++ b/Runtime/Character/CMetaAnimPhaseBlend.hpp @@ -14,7 +14,7 @@ class CMetaAnimPhaseBlend : public IMetaAnim { bool x10_; public: - CMetaAnimPhaseBlend(CInputStream& in); + explicit CMetaAnimPhaseBlend(CInputStream& in); EMetaAnimType GetType() const override { return EMetaAnimType::PhaseBlend; } void GetUniquePrimitives(std::set& primsOut) const override; diff --git a/Runtime/Character/CMetaAnimPlay.hpp b/Runtime/Character/CMetaAnimPlay.hpp index 4f056eeb0..2939fc24a 100644 --- a/Runtime/Character/CMetaAnimPlay.hpp +++ b/Runtime/Character/CMetaAnimPlay.hpp @@ -11,7 +11,7 @@ class CMetaAnimPlay : public IMetaAnim { CCharAnimTime x1c_startTime; public: - CMetaAnimPlay(CInputStream& in); + explicit CMetaAnimPlay(CInputStream& in); EMetaAnimType GetType() const override { return EMetaAnimType::Play; } void GetUniquePrimitives(std::set& primsOut) const override; diff --git a/Runtime/Character/CMetaAnimRandom.hpp b/Runtime/Character/CMetaAnimRandom.hpp index 9abb4e8a2..8ee2a6b29 100644 --- a/Runtime/Character/CMetaAnimRandom.hpp +++ b/Runtime/Character/CMetaAnimRandom.hpp @@ -15,7 +15,7 @@ class CMetaAnimRandom : public IMetaAnim { static RandomData CreateRandomData(CInputStream& in); public: - CMetaAnimRandom(CInputStream& in); + explicit CMetaAnimRandom(CInputStream& in); EMetaAnimType GetType() const override { return EMetaAnimType::Random; } void GetUniquePrimitives(std::set& primsOut) const override; diff --git a/Runtime/Character/CMetaAnimSequence.hpp b/Runtime/Character/CMetaAnimSequence.hpp index 57d68bf6d..bc644b3e9 100644 --- a/Runtime/Character/CMetaAnimSequence.hpp +++ b/Runtime/Character/CMetaAnimSequence.hpp @@ -13,7 +13,7 @@ class CMetaAnimSequence : public IMetaAnim { std::vector> CreateSequence(CInputStream& in); public: - CMetaAnimSequence(CInputStream& in); + explicit CMetaAnimSequence(CInputStream& in); EMetaAnimType GetType() const override { return EMetaAnimType::Sequence; } void GetUniquePrimitives(std::set& primsOut) const override; diff --git a/Runtime/Character/CMetaTransMetaAnim.hpp b/Runtime/Character/CMetaTransMetaAnim.hpp index 03f459254..21e193015 100644 --- a/Runtime/Character/CMetaTransMetaAnim.hpp +++ b/Runtime/Character/CMetaTransMetaAnim.hpp @@ -12,7 +12,7 @@ class CMetaTransMetaAnim : public IMetaTrans { std::shared_ptr x4_metaAnim; public: - CMetaTransMetaAnim(CInputStream& in); + explicit CMetaTransMetaAnim(CInputStream& in); EMetaTransType GetType() const override { return EMetaTransType::MetaAnim; } std::shared_ptr VGetTransitionTree(const std::weak_ptr& a, diff --git a/Runtime/Character/CMetaTransPhaseTrans.hpp b/Runtime/Character/CMetaTransPhaseTrans.hpp index b9e5c9e5e..49005655c 100644 --- a/Runtime/Character/CMetaTransPhaseTrans.hpp +++ b/Runtime/Character/CMetaTransPhaseTrans.hpp @@ -13,7 +13,7 @@ class CMetaTransPhaseTrans : public IMetaTrans { u32 x10_flags; public: - CMetaTransPhaseTrans(CInputStream& in); + explicit CMetaTransPhaseTrans(CInputStream& in); EMetaTransType GetType() const override { return EMetaTransType::PhaseTrans; } std::shared_ptr VGetTransitionTree(const std::weak_ptr& a, diff --git a/Runtime/Character/CMetaTransTrans.hpp b/Runtime/Character/CMetaTransTrans.hpp index b3cf33efd..f1f259975 100644 --- a/Runtime/Character/CMetaTransTrans.hpp +++ b/Runtime/Character/CMetaTransTrans.hpp @@ -13,7 +13,7 @@ class CMetaTransTrans : public IMetaTrans { u32 x10_flags; public: - CMetaTransTrans(CInputStream& in); + explicit CMetaTransTrans(CInputStream& in); EMetaTransType GetType() const override { return EMetaTransType::Trans; } std::shared_ptr VGetTransitionTree(const std::weak_ptr& a, diff --git a/Runtime/Character/CModelData.cpp b/Runtime/Character/CModelData.cpp index 1ac59a504..b5ee3efda 100644 --- a/Runtime/Character/CModelData.cpp +++ b/Runtime/Character/CModelData.cpp @@ -20,7 +20,7 @@ namespace urde { static logvisor::Module Log("urde::CModelData"); -CModelData::~CModelData() {} +CModelData::~CModelData() = default; CModelData::CModelData() {} CModelData CModelData::CModelDataNull() { return CModelData(); } @@ -354,7 +354,7 @@ void CModelData::Render(EWhichModel which, const zeus::CTransform& xf, const CAc model.GetModelInst()->ActivateLights(useLights); } - x10_animData->Render(model, drawFlags, {}, nullptr); + x10_animData->Render(model, drawFlags, std::nullopt, nullptr); } else { const auto& model = PickStaticModel(which); if (lights) { @@ -388,18 +388,18 @@ void CModelData::InvSuitDraw(EWhichModel which, const zeus::CTransform& xf, cons /* Z-prime */ flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly; flags.x4_color = zeus::skWhite; - x10_animData->Render(model, flags, {}, nullptr); + x10_animData->Render(model, flags, std::nullopt, nullptr); /* Normal Blended */ lights->ActivateLights(*model.GetModelInst()); flags.m_extendedShader = EExtendedShader::ForcedAlpha; flags.x4_color = alphaColor; - x10_animData->Render(model, flags, {}, nullptr); + x10_animData->Render(model, flags, std::nullopt, nullptr); /* Selection Additive */ flags.m_extendedShader = EExtendedShader::ForcedAdditive; flags.x4_color = additiveColor; - x10_animData->Render(model, flags, {}, nullptr); + x10_animData->Render(model, flags, std::nullopt, nullptr); } else { CBooModel& model = *PickStaticModel(which); model.DisableAllLights(); @@ -441,7 +441,7 @@ void CModelData::DisintegrateDraw(EWhichModel which, const zeus::CTransform& xf, if (x10_animData) { CSkinnedModel& sModel = PickAnimatedModel(which); - x10_animData->Render(sModel, flags, {}, nullptr); + x10_animData->Render(sModel, flags, std::nullopt, nullptr); } else { CBooModel& model = *PickStaticModel(which); model.Draw(flags, nullptr, nullptr); diff --git a/Runtime/Character/CModelData.hpp b/Runtime/Character/CModelData.hpp index 917d45ab8..ab746220f 100644 --- a/Runtime/Character/CModelData.hpp +++ b/Runtime/Character/CModelData.hpp @@ -52,7 +52,7 @@ public: void SetCharacterNodeId(s32 id) { x4_charIdx = id; } const zeus::CVector3f& GetScale() const { return x8_scale; } bool CanLoop() const { return x14_canLoop; } - void SetCanLoop(bool l) { x14_canLoop = l; } + void SetCanLoop(bool loop) { x14_canLoop = loop; } s32 GetDefaultAnim() const { return x18_defaultAnim; } void SetDefaultAnim(s32 anim) { x18_defaultAnim = anim; } }; @@ -79,17 +79,17 @@ class CModelData { std::unique_ptr m_xrayModelInst; std::unique_ptr m_infraModelInst; - int m_drawInstCount; + int m_drawInstCount = 0; public: enum class EWhichModel { Normal, XRay, Thermal, ThermalHot }; - void SetSortThermal(bool v) { x14_25_sortThermal = v; } + void SetSortThermal(bool sort) { x14_25_sortThermal = sort; } bool GetSortThermal() const { return x14_25_sortThermal; } ~CModelData(); - CModelData(const CStaticRes& res, int instCount = 1); - CModelData(const CAnimRes& res, int instCount = 1); + explicit CModelData(const CStaticRes& res, int instCount = 1); + explicit CModelData(const CAnimRes& res, int instCount = 1); CModelData(CModelData&&) = default; CModelData& operator=(CModelData&&) = default; CModelData(); @@ -106,16 +106,16 @@ public: void SetInfraModel(const std::pair& modelSkin); bool IsDefinitelyOpaque(EWhichModel) const; bool GetIsLoop() const; - float GetAnimationDuration(int) const; - void EnableLooping(bool); - void AdvanceParticles(const zeus::CTransform& xf, float, CStateManager& stateMgr); + float GetAnimationDuration(int idx) const; + void EnableLooping(bool enable); + void AdvanceParticles(const zeus::CTransform& xf, float dt, CStateManager& stateMgr); zeus::CAABox GetBounds() const; zeus::CAABox GetBounds(const zeus::CTransform& xf) const; zeus::CTransform GetScaledLocatorTransformDynamic(std::string_view name, const CCharAnimTime* time) const; zeus::CTransform GetScaledLocatorTransform(std::string_view name) const; zeus::CTransform GetLocatorTransformDynamic(std::string_view name, const CCharAnimTime* time) const; zeus::CTransform GetLocatorTransform(std::string_view name) const; - SAdvancementDeltas AdvanceAnimationIgnoreParticles(float dt, CRandom16&, bool advTree); + SAdvancementDeltas AdvanceAnimationIgnoreParticles(float dt, CRandom16& rand, bool advTree); SAdvancementDeltas AdvanceAnimation(float dt, CStateManager& stateMgr, TAreaId aid, bool advTree); bool IsAnimating() const; bool IsInFrustum(const zeus::CTransform& xf, const zeus::CFrustum& frustum) const; diff --git a/Runtime/Character/CPASAnimInfo.cpp b/Runtime/Character/CPASAnimInfo.cpp index 222094958..6a11905b1 100644 --- a/Runtime/Character/CPASAnimInfo.cpp +++ b/Runtime/Character/CPASAnimInfo.cpp @@ -5,15 +5,18 @@ namespace urde { CPASAnimInfo::CPASAnimInfo(u32 id, rstl::reserved_vector&& parms) : x0_id(id), x4_parms(std::move(parms)) {} -CPASAnimParm::UParmValue CPASAnimInfo::GetAnimParmValue(u32 idx) const { - if (idx >= x4_parms.size()) +CPASAnimParm::UParmValue CPASAnimInfo::GetAnimParmValue(size_t idx) const { + if (idx >= x4_parms.size()) { return CPASAnimParm::UParmValue{}; + } return x4_parms[idx]; } -CPASAnimParm CPASAnimInfo::GetAnimParmData(u32 idx, CPASAnimParm::EParmType type) const { - if (idx >= x4_parms.size()) +CPASAnimParm CPASAnimInfo::GetAnimParmData(size_t idx, CPASAnimParm::EParmType type) const { + if (idx >= x4_parms.size()) { return CPASAnimParm::NoParameter(); + } + const CPASAnimParm::UParmValue& parm = x4_parms[idx]; switch (type) { diff --git a/Runtime/Character/CPASAnimInfo.hpp b/Runtime/Character/CPASAnimInfo.hpp index 1a86d22b9..a679f71f7 100644 --- a/Runtime/Character/CPASAnimInfo.hpp +++ b/Runtime/Character/CPASAnimInfo.hpp @@ -11,11 +11,11 @@ class CPASAnimInfo { rstl::reserved_vector x4_parms; public: - CPASAnimInfo(u32 id) : x0_id(id) {} - CPASAnimInfo(u32 id, rstl::reserved_vector&& parms); + explicit CPASAnimInfo(u32 id) : x0_id(id) {} + explicit CPASAnimInfo(u32 id, rstl::reserved_vector&& parms); u32 GetAnimId() const { return x0_id; } - CPASAnimParm::UParmValue GetAnimParmValue(u32 idx) const; - CPASAnimParm GetAnimParmData(u32, CPASAnimParm::EParmType) const; + CPASAnimParm::UParmValue GetAnimParmValue(size_t idx) const; + CPASAnimParm GetAnimParmData(size_t idx, CPASAnimParm::EParmType type) const; }; } // namespace urde diff --git a/Runtime/Character/CPASAnimParm.hpp b/Runtime/Character/CPASAnimParm.hpp index 2d093930b..bf706374f 100644 --- a/Runtime/Character/CPASAnimParm.hpp +++ b/Runtime/Character/CPASAnimParm.hpp @@ -19,47 +19,47 @@ private: EParmType x4_type; public: - CPASAnimParm(UParmValue val, EParmType tp) : x0_value(val), x4_type(tp) {} + constexpr CPASAnimParm(UParmValue val, EParmType tp) : x0_value(val), x4_type(tp) {} - EParmType GetParameterType() const { return x4_type; } - s32 GetEnumValue() const { return x0_value.m_int; } - bool GetBoolValue() const { return x0_value.m_bool; } - float GetReal32Value() const { return x0_value.m_float; } - u32 GetUint32Value() const { return x0_value.m_uint; } - s32 GetInt32Value() const { return x0_value.m_int; } + [[nodiscard]] constexpr EParmType GetParameterType() const { return x4_type; } + [[nodiscard]] constexpr s32 GetEnumValue() const { return x0_value.m_int; } + [[nodiscard]] constexpr bool GetBoolValue() const { return x0_value.m_bool; } + [[nodiscard]] constexpr float GetReal32Value() const { return x0_value.m_float; } + [[nodiscard]] constexpr u32 GetUint32Value() const { return x0_value.m_uint; } + [[nodiscard]] constexpr s32 GetInt32Value() const { return x0_value.m_int; } - static CPASAnimParm FromEnum(s32 val) { - UParmValue valin; + [[nodiscard]] static constexpr CPASAnimParm FromEnum(s32 val) { + UParmValue valin{}; valin.m_int = val; return CPASAnimParm(valin, EParmType::Enum); } - static CPASAnimParm FromBool(bool val) { - UParmValue valin; + [[nodiscard]] static constexpr CPASAnimParm FromBool(bool val) { + UParmValue valin{}; valin.m_bool = val; return CPASAnimParm(valin, EParmType::Bool); } - static CPASAnimParm FromReal32(float val) { - UParmValue valin; + [[nodiscard]] static constexpr CPASAnimParm FromReal32(float val) { + UParmValue valin{}; valin.m_float = val; return CPASAnimParm(valin, EParmType::Float); } - static CPASAnimParm FromUint32(u32 val) { - UParmValue valin; + [[nodiscard]] static constexpr CPASAnimParm FromUint32(u32 val) { + UParmValue valin{}; valin.m_uint = val; return CPASAnimParm(valin, EParmType::UInt32); } - static CPASAnimParm FromInt32(s32 val) { - UParmValue valin; + [[nodiscard]] static constexpr CPASAnimParm FromInt32(s32 val) { + UParmValue valin{}; valin.m_int = val; return CPASAnimParm(valin, EParmType::Int32); } - static CPASAnimParm NoParameter() { - UParmValue valin; + [[nodiscard]] static constexpr CPASAnimParm NoParameter() { + UParmValue valin{}; valin.m_int = -1; return CPASAnimParm(valin, EParmType::None); } diff --git a/Runtime/Character/CPASAnimParmData.hpp b/Runtime/Character/CPASAnimParmData.hpp index b985f0682..41ad3521f 100644 --- a/Runtime/Character/CPASAnimParmData.hpp +++ b/Runtime/Character/CPASAnimParmData.hpp @@ -12,28 +12,18 @@ class CPASAnimParmData { public: CPASAnimParmData() = default; - CPASAnimParmData(s32 stateId, const CPASAnimParm& parm1 = CPASAnimParm::NoParameter(), - const CPASAnimParm& parm2 = CPASAnimParm::NoParameter(), - const CPASAnimParm& parm3 = CPASAnimParm::NoParameter(), - const CPASAnimParm& parm4 = CPASAnimParm::NoParameter(), - const CPASAnimParm& parm5 = CPASAnimParm::NoParameter(), - const CPASAnimParm& parm6 = CPASAnimParm::NoParameter(), - const CPASAnimParm& parm7 = CPASAnimParm::NoParameter(), - const CPASAnimParm& parm8 = CPASAnimParm::NoParameter()); + explicit CPASAnimParmData(s32 stateId, const CPASAnimParm& parm1 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm2 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm3 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm4 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm5 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm6 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm7 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm8 = CPASAnimParm::NoParameter()); s32 GetStateId() const { return x0_stateId; } const rstl::reserved_vector& GetAnimParmData() const { return x4_parms; } - static CPASAnimParmData NoParameters(s32 stateId) { - return {stateId, - CPASAnimParm::NoParameter(), - CPASAnimParm::NoParameter(), - CPASAnimParm::NoParameter(), - CPASAnimParm::NoParameter(), - CPASAnimParm::NoParameter(), - CPASAnimParm::NoParameter(), - CPASAnimParm::NoParameter(), - CPASAnimParm::NoParameter()}; - } + static auto NoParameters(s32 stateId) { return CPASAnimParmData(stateId); } }; } // namespace urde diff --git a/Runtime/Character/CPASAnimState.cpp b/Runtime/Character/CPASAnimState.cpp index f0996e973..3bde8b003 100644 --- a/Runtime/Character/CPASAnimState.cpp +++ b/Runtime/Character/CPASAnimState.cpp @@ -60,14 +60,15 @@ CPASAnimState::CPASAnimState(CInputStream& in) { CPASAnimState::CPASAnimState(int stateId) : x0_id(stateId) {} -CPASAnimParm CPASAnimState::GetAnimParmData(s32 animId, u32 parmIdx) const { - auto search = rstl::binary_find(x14_anims.begin(), x14_anims.end(), animId, - [](const CPASAnimInfo& item) { return item.GetAnimId(); }); - if (search == x14_anims.end()) +CPASAnimParm CPASAnimState::GetAnimParmData(s32 animId, size_t parmIdx) const { + const auto search = rstl::binary_find(x14_anims.cbegin(), x14_anims.cend(), animId, + [](const CPASAnimInfo& item) { return item.GetAnimId(); }); + if (search == x14_anims.cend()) { return CPASAnimParm::NoParameter(); + } - CPASParmInfo parm = x4_parms.at(parmIdx); - return (*search).GetAnimParmData(parmIdx, parm.GetParameterType()); + const CPASParmInfo& parm = x4_parms.at(parmIdx); + return search->GetAnimParmData(parmIdx, parm.GetParameterType()); } s32 CPASAnimState::PickRandomAnimation(CRandom16& rand) const { @@ -100,7 +101,7 @@ std::pair CPASAnimState::FindBestAnimation(const rstl::reserved_vect u32 unweightedCount = 0; - for (u32 i = 0; i < x4_parms.size(); ++i) { + for (size_t i = 0; i < x4_parms.size(); ++i) { CPASAnimParm::UParmValue val = info.GetAnimParmValue(i); const CPASParmInfo& parmInfo = x4_parms[i]; float parmWeight = parmInfo.GetParameterWeight(); @@ -142,7 +143,7 @@ std::pair CPASAnimState::FindBestAnimation(const rstl::reserved_vect return {weight, PickRandomAnimation(rand)}; } -float CPASAnimState::ComputeExactMatchWeight(u32, const CPASAnimParm& parm, CPASAnimParm::UParmValue parmVal) const { +float CPASAnimState::ComputeExactMatchWeight(size_t, const CPASAnimParm& parm, CPASAnimParm::UParmValue parmVal) const { switch (parm.GetParameterType()) { case CPASAnimParm::EParmType::Int32: return (parm.GetInt32Value() == parmVal.m_int ? 1.f : 0.f); @@ -161,7 +162,7 @@ float CPASAnimState::ComputeExactMatchWeight(u32, const CPASAnimParm& parm, CPAS return 0.f; } -float CPASAnimState::ComputePercentErrorWeight(u32 idx, const CPASAnimParm& parm, +float CPASAnimState::ComputePercentErrorWeight(size_t idx, const CPASAnimParm& parm, CPASAnimParm::UParmValue parmVal) const { float range = 0.f; float val = 0.f; @@ -205,7 +206,7 @@ float CPASAnimState::ComputePercentErrorWeight(u32 idx, const CPASAnimParm& parm return (val < FLT_EPSILON ? 1.f : 0.f); } -float CPASAnimState::ComputeAngularPercentErrorWeight(u32 idx, const CPASAnimParm& parm, +float CPASAnimState::ComputeAngularPercentErrorWeight(size_t idx, const CPASAnimParm& parm, CPASAnimParm::UParmValue parmVal) const { float range = 0.f; float val = 0.f; diff --git a/Runtime/Character/CPASAnimState.hpp b/Runtime/Character/CPASAnimState.hpp index 59701ba76..493152edd 100644 --- a/Runtime/Character/CPASAnimState.hpp +++ b/Runtime/Character/CPASAnimState.hpp @@ -16,17 +16,21 @@ class CPASAnimState { std::vector x14_anims; mutable std::vector x24_selectionCache; + float ComputeExactMatchWeight(size_t idx, const CPASAnimParm& parm, CPASAnimParm::UParmValue parmVal) const; + float ComputePercentErrorWeight(size_t idx, const CPASAnimParm& parm, CPASAnimParm::UParmValue parmVal) const; + float ComputeAngularPercentErrorWeight(size_t idx, const CPASAnimParm& parm, CPASAnimParm::UParmValue parmVal) const; + + s32 PickRandomAnimation(CRandom16& rand) const; + public: explicit CPASAnimState(CInputStream& in); explicit CPASAnimState(int stateId); s32 GetStateId() const { return x0_id; } - s32 GetNumAnims() const { return x14_anims.size(); } - CPASAnimParm GetAnimParmData(s32, u32) const; - s32 PickRandomAnimation(CRandom16& rand) const; - std::pair FindBestAnimation(const rstl::reserved_vector&, CRandom16&, s32) const; - float ComputeExactMatchWeight(u32, const CPASAnimParm&, CPASAnimParm::UParmValue) const; - float ComputePercentErrorWeight(u32, const CPASAnimParm&, CPASAnimParm::UParmValue) const; - float ComputeAngularPercentErrorWeight(u32, const CPASAnimParm&, CPASAnimParm::UParmValue) const; + size_t GetNumAnims() const { return x14_anims.size(); } + bool HasAnims() const { return !x14_anims.empty(); } + CPASAnimParm GetAnimParmData(s32 animId, size_t parmIdx) const; + std::pair FindBestAnimation(const rstl::reserved_vector& parms, CRandom16& rand, + s32 ignoreAnim) const; }; } // namespace urde diff --git a/Runtime/Character/CPASDatabase.hpp b/Runtime/Character/CPASDatabase.hpp index 54545395c..e06afeec4 100644 --- a/Runtime/Character/CPASDatabase.hpp +++ b/Runtime/Character/CPASDatabase.hpp @@ -20,10 +20,10 @@ class CPASDatabase { public: explicit CPASDatabase(CInputStream& in); - std::pair FindBestAnimation(const CPASAnimParmData&, s32) const; - std::pair FindBestAnimation(const CPASAnimParmData&, CRandom16&, s32) const; + std::pair FindBestAnimation(const CPASAnimParmData& data, s32 ignoreAnim) const; + std::pair FindBestAnimation(const CPASAnimParmData& data, CRandom16& rand, s32 ignoreAnim) const; s32 GetDefaultState() const { return x10_defaultState; } - s32 GetNumAnimStates() const { return x0_states.size(); } + size_t GetNumAnimStates() const { return x0_states.size(); } const CPASAnimState* GetAnimState(s32 id) const { for (const CPASAnimState& state : x0_states) if (id == state.GetStateId()) @@ -31,11 +31,12 @@ public: return nullptr; } - const CPASAnimState* GetAnimStateByIndex(s32 index) const { - if (index < 0 || index >= x0_states.size()) + const CPASAnimState* GetAnimStateByIndex(size_t index) const { + if (index >= x0_states.size()) { return nullptr; + } - return &x0_states.at(index); + return &x0_states[index]; } bool HasState(s32 id) const { diff --git a/Runtime/Character/CPOINode.hpp b/Runtime/Character/CPOINode.hpp index a5777a3bd..3cc4c89b3 100644 --- a/Runtime/Character/CPOINode.hpp +++ b/Runtime/Character/CPOINode.hpp @@ -33,9 +33,9 @@ protected: s32 x34_flags; public: - CPOINode(std::string_view name, EPOIType type, const CCharAnimTime& time, s32 index, bool unique, float weight, - s32 charIdx, s32 flags); - CPOINode(CInputStream& in); + explicit CPOINode(std::string_view name, EPOIType type, const CCharAnimTime& time, s32 index, bool unique, + float weight, s32 charIdx, s32 flags); + explicit CPOINode(CInputStream& in); virtual ~CPOINode() = default; std::string_view GetString() const { return x8_name; } diff --git a/Runtime/Character/CParticleData.hpp b/Runtime/Character/CParticleData.hpp index 907f406d4..98428e200 100644 --- a/Runtime/Character/CParticleData.hpp +++ b/Runtime/Character/CParticleData.hpp @@ -22,7 +22,7 @@ private: public: CParticleData() = default; - CParticleData(CInputStream& in); + explicit CParticleData(CInputStream& in); u32 GetDuration() const { return x0_duration; } const SObjectTag& GetTag() const { return x4_particle; } std::string_view GetSegmentName() const { return xc_boneName; } diff --git a/Runtime/Character/CParticleGenInfo.cpp b/Runtime/Character/CParticleGenInfo.cpp index fd67f09fb..84709e5eb 100644 --- a/Runtime/Character/CParticleGenInfo.cpp +++ b/Runtime/Character/CParticleGenInfo.cpp @@ -55,50 +55,60 @@ void CParticleGenInfoGeneric::Render() { x84_system->Render(); } void CParticleGenInfoGeneric::Update(float dt, CStateManager& stateMgr) { x84_system->Update(dt); - if (x88_lightId != kInvalidUniqueId) { - TCastToPtr gl(stateMgr.ObjectById(x88_lightId)); - if (gl) - gl->SetLight(x84_system->GetLight()); + if (x88_lightId == kInvalidUniqueId) { + return; + } + + if (const TCastToPtr gl = stateMgr.ObjectById(x88_lightId)) { + gl->SetLight(x84_system->GetLight()); } } void CParticleGenInfoGeneric::SetOrientation(const zeus::CTransform& xf, CStateManager& stateMgr) { x84_system->SetOrientation(xf); - if (x88_lightId != kInvalidUniqueId) { - TCastToPtr gl(stateMgr.ObjectById(x88_lightId)); - if (gl) - gl->SetRotation(zeus::CQuaternion(xf.buildMatrix3f())); + if (x88_lightId == kInvalidUniqueId) { + return; + } + + if (const TCastToPtr gl = stateMgr.ObjectById(x88_lightId)) { + gl->SetRotation(zeus::CQuaternion(xf.buildMatrix3f())); } } void CParticleGenInfoGeneric::SetTranslation(const zeus::CVector3f& trans, CStateManager& stateMgr) { x84_system->SetTranslation(trans); - if (x88_lightId != kInvalidUniqueId) { - TCastToPtr gl(stateMgr.ObjectById(x88_lightId)); - if (gl) - gl->SetTranslation(trans); + if (x88_lightId == kInvalidUniqueId) { + return; + } + + if (const TCastToPtr gl = stateMgr.ObjectById(x88_lightId)) { + gl->SetTranslation(trans); } } void CParticleGenInfoGeneric::SetGlobalOrientation(const zeus::CTransform& xf, CStateManager& stateMgr) { x84_system->SetGlobalOrientation(xf); - if (x88_lightId != kInvalidUniqueId) { - TCastToPtr gl(stateMgr.ObjectById(x88_lightId)); - if (gl) - gl->SetRotation(zeus::CQuaternion(xf.buildMatrix3f())); + if (x88_lightId == kInvalidUniqueId) { + return; + } + + if (const TCastToPtr gl = stateMgr.ObjectById(x88_lightId)) { + gl->SetRotation(zeus::CQuaternion(xf.buildMatrix3f())); } } void CParticleGenInfoGeneric::SetGlobalTranslation(const zeus::CVector3f& trans, CStateManager& stateMgr) { x84_system->SetGlobalTranslation(trans); - if (x88_lightId != kInvalidUniqueId) { - TCastToPtr gl(stateMgr.ObjectById(x88_lightId)); - if (gl) - gl->SetTranslation(trans); + if (x88_lightId == kInvalidUniqueId) { + return; + } + + if (const TCastToPtr gl = stateMgr.ObjectById(x88_lightId)) { + gl->SetTranslation(trans); } } @@ -107,9 +117,7 @@ void CParticleGenInfoGeneric::SetGlobalScale(const zeus::CVector3f& scale) { x84 void CParticleGenInfoGeneric::SetParticleEmission(bool isActive, CStateManager& stateMgr) { x84_system->SetParticleEmission(isActive); - TCastToPtr gl(stateMgr.ObjectById(x88_lightId)); - - if (gl) { + if (const TCastToPtr gl = stateMgr.ObjectById(x88_lightId)) { gl->SetActive(isActive); } } diff --git a/Runtime/Character/CParticlePOINode.hpp b/Runtime/Character/CParticlePOINode.hpp index 065ad773c..33180a624 100644 --- a/Runtime/Character/CParticlePOINode.hpp +++ b/Runtime/Character/CParticlePOINode.hpp @@ -10,8 +10,8 @@ class CParticlePOINode : public CPOINode { CParticleData x38_data; public: - CParticlePOINode(); - CParticlePOINode(CInputStream& in); + explicit CParticlePOINode(); + explicit CParticlePOINode(CInputStream& in); const CParticleData& GetParticleData() const { return x38_data; } static CParticlePOINode CopyNodeMinusStartTime(const CParticlePOINode& node, const CCharAnimTime& startTime); diff --git a/Runtime/Character/CPrimitive.hpp b/Runtime/Character/CPrimitive.hpp index 16e7236cd..db9a44c8f 100644 --- a/Runtime/Character/CPrimitive.hpp +++ b/Runtime/Character/CPrimitive.hpp @@ -13,7 +13,7 @@ class CPrimitive { std::string x8_animName; public: - CPrimitive(CInputStream& in); + explicit CPrimitive(CInputStream& in); CAssetId GetAnimResId() const { return x0_animId; } u32 GetAnimDbIdx() const { return x4_animIdx; } std::string_view GetName() const { return x8_animName; } diff --git a/Runtime/Character/CRagDoll.hpp b/Runtime/Character/CRagDoll.hpp index b8f75d04b..678861df7 100644 --- a/Runtime/Character/CRagDoll.hpp +++ b/Runtime/Character/CRagDoll.hpp @@ -137,6 +137,7 @@ public: bool IsOver() const { return x68_25_over; } void SetNoOverTimer(bool b) { x68_28_noOverTimer = b; } void SetContinueSmallMovements(bool b) { x68_27_continueSmallMovements = b; } + u32 GetImpactCount() const { return x4c_impactCount; } }; } // namespace urde diff --git a/Runtime/Character/CSegIdList.hpp b/Runtime/Character/CSegIdList.hpp index 65f456371..37eceb21c 100644 --- a/Runtime/Character/CSegIdList.hpp +++ b/Runtime/Character/CSegIdList.hpp @@ -11,7 +11,7 @@ class CSegIdList { std::vector x0_list; public: - CSegIdList(CInputStream& in); + explicit CSegIdList(CInputStream& in); const std::vector& GetList() const { return x0_list; } }; diff --git a/Runtime/Character/CSegStatementSet.hpp b/Runtime/Character/CSegStatementSet.hpp index 9499f9b2b..48b40c7d4 100644 --- a/Runtime/Character/CSegStatementSet.hpp +++ b/Runtime/Character/CSegStatementSet.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "Runtime/Character/CAnimPerSegmentData.hpp" #include "Runtime/Character/CSegId.hpp" @@ -8,10 +10,12 @@ class CCharLayoutInfo; class CSegIdList; class CSegStatementSet { -public: +private: /* Used to be a pointer to arbitrary subclass-provided storage, * now it's a self-stored array */ - CAnimPerSegmentData x4_segData[100]; + std::array x4_segData; + +public: void Add(const CSegIdList& list, const CCharLayoutInfo& layout, const CSegStatementSet& other, float weight); CAnimPerSegmentData& operator[](const CSegId& idx) { return x4_segData[idx]; } diff --git a/Runtime/Character/CSkinBank.hpp b/Runtime/Character/CSkinBank.hpp index cce5921f0..604d19b17 100644 --- a/Runtime/Character/CSkinBank.hpp +++ b/Runtime/Character/CSkinBank.hpp @@ -12,7 +12,7 @@ class CSkinBank { std::vector x0_segments; public: - CSkinBank(CInputStream& in); + explicit CSkinBank(CInputStream& in); void GetBankTransforms(std::vector& out, const CPoseAsTransforms& pose) const; }; diff --git a/Runtime/Character/CSoundPOINode.hpp b/Runtime/Character/CSoundPOINode.hpp index 0f46bae1e..4e243fd5c 100644 --- a/Runtime/Character/CSoundPOINode.hpp +++ b/Runtime/Character/CSoundPOINode.hpp @@ -12,10 +12,10 @@ class CSoundPOINode : public CPOINode { float x40_maxDist; public: - CSoundPOINode(); - CSoundPOINode(CInputStream& in); - CSoundPOINode(std::string_view name, EPOIType type, const CCharAnimTime& time, u32 b, bool c, float d, u32 e, u32 f, - u32 sfxId, float falloff, float maxDist); + explicit CSoundPOINode(); + explicit CSoundPOINode(CInputStream& in); + explicit CSoundPOINode(std::string_view name, EPOIType type, const CCharAnimTime& time, u32 b, bool c, float d, u32 e, + u32 f, u32 sfxId, float falloff, float maxDist); static CSoundPOINode CopyNodeMinusStartTime(const CSoundPOINode& node, const CCharAnimTime& startTime); u32 GetSfxId() const { return x38_sfxId; } diff --git a/Runtime/Character/CTimeScaleFunctions.hpp b/Runtime/Character/CTimeScaleFunctions.hpp index e6bc159dc..0829b96e3 100644 --- a/Runtime/Character/CTimeScaleFunctions.hpp +++ b/Runtime/Character/CTimeScaleFunctions.hpp @@ -25,7 +25,7 @@ private: float x4_scale; public: - CConstantAnimationTimeScale(float scale) : x4_scale(scale) {} + explicit CConstantAnimationTimeScale(float scale) : x4_scale(scale) {} EVaryingAnimationTimeScaleType GetType() const override { return EVaryingAnimationTimeScaleType::Constant; } float VTimeScaleIntegral(float lowerLimit, float upperLimit) const override; @@ -46,7 +46,7 @@ class CLinearAnimationTimeScale : public IVaryingAnimationTimeScale { static float TimeScaleIntegralWithSortedLimits(const CFunctionDescription& desc, float lowerLimit, float upperLimit); public: - CLinearAnimationTimeScale(const CCharAnimTime& t1, float y1, const CCharAnimTime& t2, float y2); + explicit CLinearAnimationTimeScale(const CCharAnimTime& t1, float y1, const CCharAnimTime& t2, float y2); EVaryingAnimationTimeScaleType GetType() const override { return EVaryingAnimationTimeScaleType::Linear; } float VTimeScaleIntegral(float lowerLimit, float upperLimit) const override; diff --git a/Runtime/Character/CTransition.hpp b/Runtime/Character/CTransition.hpp index b7d7a0266..80f74ab70 100644 --- a/Runtime/Character/CTransition.hpp +++ b/Runtime/Character/CTransition.hpp @@ -15,7 +15,7 @@ class CTransition { std::shared_ptr xc_trans; public: - CTransition(CInputStream& in); + explicit CTransition(CInputStream& in); u32 GetAnimA() const { return x4_animA; } u32 GetAnimB() const { return x8_animB; } std::pair GetAnimPair() const { return {x4_animA, x8_animB}; } diff --git a/Runtime/Character/CTransitionDatabase.hpp b/Runtime/Character/CTransitionDatabase.hpp index 17266590e..891bbf166 100644 --- a/Runtime/Character/CTransitionDatabase.hpp +++ b/Runtime/Character/CTransitionDatabase.hpp @@ -8,6 +8,7 @@ class IMetaTrans; class CTransitionDatabase { public: + virtual ~CTransitionDatabase() = default; virtual const std::shared_ptr& GetMetaTrans(u32, u32) const = 0; }; diff --git a/Runtime/Character/CharacterCommon.hpp b/Runtime/Character/CharacterCommon.hpp index 7b0e628c7..51a3d710e 100644 --- a/Runtime/Character/CharacterCommon.hpp +++ b/Runtime/Character/CharacterCommon.hpp @@ -68,7 +68,7 @@ enum class EFallState { Invalid = -1, Zero, One , Two}; enum class EReactionType { Invalid = -1, Zero, One, Two, Three }; -enum class EAdditiveReactionType { Invalid = -1, Electrocution, One, Two, IceBreakout }; +enum class EAdditiveReactionType { Invalid = -1, Electrocution, One, Two, IceBreakout, Four, Five, Six, Seven }; enum class EJumpType { Normal, One, Ambush }; @@ -96,7 +96,7 @@ enum class ELoopState { Invalid = -1, Begin, Loop, End }; enum class ELoopAttackType { Invalid = -1 }; -enum class EGenerateType { Invalid = -1, Zero, One, Two, Three, Four }; +enum class EGenerateType { Invalid = -1, Zero, One, Two, Three, Four, Five }; enum class ESlideType { Invalid = -1, Zero = 0 }; diff --git a/Runtime/Character/IAnimReader.hpp b/Runtime/Character/IAnimReader.hpp index 3522a5ba7..59f7e1df9 100644 --- a/Runtime/Character/IAnimReader.hpp +++ b/Runtime/Character/IAnimReader.hpp @@ -2,6 +2,7 @@ #include #include +#include #include "Runtime/CToken.hpp" #include "Runtime/RetroTypes.hpp" @@ -71,31 +72,36 @@ template class TSubAnimTypeToken : public TLockedToken {}; template <> -class TSubAnimTypeToken : public TLockedToken { +class TSubAnimTypeToken : public TLockedToken { public: - TSubAnimTypeToken(const TLockedToken& token) - : TLockedToken(token) {} + // Converting constructor + TSubAnimTypeToken(const TLockedToken& token) : TLockedToken(token) {} - const CAnimSource* GetObj() const { - const CAllFormatsAnimSource* source = TLockedToken::GetObj(); + CAnimSource* GetObj() override { + CAllFormatsAnimSource* source = reinterpret_cast(TLockedToken::GetObj()); return &source->GetAsCAnimSource(); } - const CAnimSource* operator->() const { return GetObj(); } - const CAnimSource& operator*() const { return *GetObj(); } + + const CAnimSource* GetObj() const override { + return const_cast*>(this)->GetObj(); + } }; template <> -class TSubAnimTypeToken : public TLockedToken { +class TSubAnimTypeToken : public TLockedToken { public: - TSubAnimTypeToken(const TLockedToken& token) - : TLockedToken(token) {} + // Converting constructor + TSubAnimTypeToken(const TLockedToken& token) : TLockedToken(token) {} - const CFBStreamedCompression* GetObj() const { - const CAllFormatsAnimSource* source = TLockedToken::GetObj(); + CFBStreamedCompression* GetObj() override { + CAllFormatsAnimSource* source = + reinterpret_cast(TLockedToken::GetObj()); return &source->GetAsCFBStreamedCompression(); } - const CFBStreamedCompression* operator->() const { return GetObj(); } - const CFBStreamedCompression& operator*() const { return *GetObj(); } + + const CFBStreamedCompression* GetObj() const override { + return const_cast*>(this)->GetObj(); + } }; class IAnimReader { @@ -116,9 +122,9 @@ public: u32) const = 0; virtual u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator, u32) const = 0; - virtual bool VGetBoolPOIState(const char*) const = 0; - virtual s32 VGetInt32POIState(const char*) const = 0; - virtual CParticleData::EParentedMode VGetParticlePOIState(const char*) const = 0; + virtual bool VGetBoolPOIState(std::string_view name) const = 0; + virtual s32 VGetInt32POIState(std::string_view name) const = 0; + virtual CParticleData::EParentedMode VGetParticlePOIState(std::string_view name) const = 0; virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const = 0; virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const = 0; diff --git a/Runtime/Character/IMetaAnim.hpp b/Runtime/Character/IMetaAnim.hpp index 71b3fc77a..c941dafc5 100644 --- a/Runtime/Character/IMetaAnim.hpp +++ b/Runtime/Character/IMetaAnim.hpp @@ -35,8 +35,8 @@ class CPreAdvanceIndicator { u16 x3c_; */ public: - CPreAdvanceIndicator(const CCharAnimTime& time) : x0_isTime(true), x4_time(time) {} - CPreAdvanceIndicator(const char* string) : x0_isTime(false), xc_string(string) {} + explicit CPreAdvanceIndicator(const CCharAnimTime& time) : x0_isTime(true), x4_time(time) {} + explicit CPreAdvanceIndicator(const char* string) : x0_isTime(false), xc_string(string) {} const char* GetString() const { return xc_string; } bool IsString() const { return !x0_isTime; } const CCharAnimTime& GetTime() const { return x4_time; } diff --git a/Runtime/Character/IVaryingAnimationTimeScale.hpp b/Runtime/Character/IVaryingAnimationTimeScale.hpp index 1d577e57f..aea324e67 100644 --- a/Runtime/Character/IVaryingAnimationTimeScale.hpp +++ b/Runtime/Character/IVaryingAnimationTimeScale.hpp @@ -7,6 +7,7 @@ namespace urde { class IVaryingAnimationTimeScale { public: + virtual ~IVaryingAnimationTimeScale() = default; virtual u32 GetType() const = 0; virtual float VTimeScaleIntegral(const float&, const float&) const = 0; virtual float VFindUpperLimit(const float&, const float&) const = 0; diff --git a/Runtime/Character/TSegIdMap.hpp b/Runtime/Character/TSegIdMap.hpp index bcef067be..304590769 100644 --- a/Runtime/Character/TSegIdMap.hpp +++ b/Runtime/Character/TSegIdMap.hpp @@ -18,7 +18,7 @@ class TSegIdMap { CSegId xd4_curPrevBone = 0; public: - TSegIdMap(const CSegId& capacity) : x1_capacity(capacity), xd0_bones(new T[capacity]) {} + explicit TSegIdMap(const CSegId& capacity) : x1_capacity(capacity), xd0_bones(new T[capacity]) {} T& operator[](const CSegId& id) { return SetElement(id); } const T& operator[](const CSegId& id) const { return xd0_bones[x8_indirectionMap[id].second]; } diff --git a/Runtime/Collision/CAABoxFilter.hpp b/Runtime/Collision/CAABoxFilter.hpp index de28e207a..59e5c92c6 100644 --- a/Runtime/Collision/CAABoxFilter.hpp +++ b/Runtime/Collision/CAABoxFilter.hpp @@ -7,7 +7,7 @@ class CCollisionInfoList; class CAABoxFilter : public ICollisionFilter { public: - CAABoxFilter(CActor& actor) : ICollisionFilter(actor) {} + explicit CAABoxFilter(CActor& actor) : ICollisionFilter(actor) {} void Filter(const CCollisionInfoList& in, CCollisionInfoList& out) const override; static void FilterBoxFloorCollisions(const CCollisionInfoList& in, CCollisionInfoList& out); }; diff --git a/Runtime/Collision/CAreaOctTree.hpp b/Runtime/Collision/CAreaOctTree.hpp index d071ea0db..a1c2b57ea 100644 --- a/Runtime/Collision/CAreaOctTree.hpp +++ b/Runtime/Collision/CAreaOctTree.hpp @@ -27,7 +27,7 @@ public: const u16* m_ptr; public: - TriListReference(const u16* ptr) : m_ptr(ptr) {} + explicit TriListReference(const u16* ptr) : m_ptr(ptr) {} u16 GetAt(int idx) const { return m_ptr[idx + 1]; } u16 GetSize() const { return m_ptr[0]; } }; @@ -42,17 +42,17 @@ public: const CAreaOctTree& x1c_owner; ETreeType x20_nodeType; - bool LineTestInternal(const zeus::CLine&, const CMaterialFilter&, float, float, float, - const zeus::CVector3f&) const; - void LineTestExInternal(const zeus::CLine&, const CMaterialFilter&, SRayResult&, float, float, float, - const zeus::CVector3f&) const; + bool LineTestInternal(const zeus::CLine& line, const CMaterialFilter& filter, float lT, float hT, float maxT, + const zeus::CVector3f& vec) const; + void LineTestExInternal(const zeus::CLine& line, const CMaterialFilter& filter, SRayResult& res, float lT, float hT, + float maxT, const zeus::CVector3f& dirRecip) const; public: Node(const void* ptr, const zeus::CAABox& aabb, const CAreaOctTree& owner, ETreeType type) : x0_aabb(aabb), x18_ptr(reinterpret_cast(ptr)), x1c_owner(owner), x20_nodeType(type) {} - bool LineTest(const zeus::CLine&, const CMaterialFilter&, float) const; - void LineTestEx(const zeus::CLine&, const CMaterialFilter&, SRayResult&, float) const; + bool LineTest(const zeus::CLine& line, const CMaterialFilter& filter, float length) const; + void LineTestEx(const zeus::CLine& line, const CMaterialFilter& filter, SRayResult& res, float length) const; const CAreaOctTree& GetOwner() const { return x1c_owner; } diff --git a/Runtime/Collision/CBallFilter.hpp b/Runtime/Collision/CBallFilter.hpp index 803a72337..7ba532a03 100644 --- a/Runtime/Collision/CBallFilter.hpp +++ b/Runtime/Collision/CBallFilter.hpp @@ -8,7 +8,7 @@ class CPhysicsActor; class CBallFilter : public ICollisionFilter { public: - CBallFilter(CActor& actor) : ICollisionFilter(actor) {} + explicit CBallFilter(CActor& actor) : ICollisionFilter(actor) {} void Filter(const CCollisionInfoList& in, CCollisionInfoList& out) const override; }; diff --git a/Runtime/Collision/CCollidableOBBTree.cpp b/Runtime/Collision/CCollidableOBBTree.cpp index 0e7000f64..9d2fbd758 100644 --- a/Runtime/Collision/CCollidableOBBTree.cpp +++ b/Runtime/Collision/CCollidableOBBTree.cpp @@ -1,5 +1,7 @@ #include "Runtime/Collision/CCollidableOBBTree.hpp" +#include + #include "Runtime/Collision/CCollisionInfoList.hpp" #include "Runtime/Collision/CInternalRayCastStructure.hpp" #include "Runtime/Collision/CMaterialFilter.hpp" @@ -10,7 +12,7 @@ namespace urde { u32 CCollidableOBBTree::sTableIndex = 0; CCollidableOBBTree::CCollidableOBBTree(const COBBTree* tree, const urde::CMaterialList& material) -: CCollisionPrimitive(material), x10_tree((COBBTree*)tree) {} +: CCollisionPrimitive(material), x10_tree(tree) {} bool CCollidableOBBTree::LineIntersectsLeaf(const COBBTree::CLeafData& leaf, CRayCastInfo& info) const { bool ret = false; @@ -152,13 +154,14 @@ bool CCollidableOBBTree::SphereCollideWithLeafMoving(const COBBTree::CLeafData& zeus::CVector3f surfNormal = surf.GetNormal(); if ((sphere.position + moveVec - surf.GetVert(0)).dot(surfNormal) <= sphere.radius) { - float mag = (sphere.radius - (sphere.position - surf.GetVert(0)).dot(surfNormal)) / dir.dot(surfNormal); - zeus::CVector3f intersectPoint = sphere.position + mag * dir; + const float mag = (sphere.radius - (sphere.position - surf.GetVert(0)).dot(surfNormal)) / dir.dot(surfNormal); + const zeus::CVector3f intersectPoint = sphere.position + mag * dir; - bool outsideEdges[] = { + const std::array outsideEdges{ (intersectPoint - surf.GetVert(0)).dot((surf.GetVert(1) - surf.GetVert(0)).cross(surfNormal)) < 0.f, (intersectPoint - surf.GetVert(1)).dot((surf.GetVert(2) - surf.GetVert(1)).cross(surfNormal)) < 0.f, - (intersectPoint - surf.GetVert(2)).dot((surf.GetVert(0) - surf.GetVert(2)).cross(surfNormal)) < 0.f}; + (intersectPoint - surf.GetVert(2)).dot((surf.GetVert(0) - surf.GetVert(2)).cross(surfNormal)) < 0.f, + }; if (mag >= 0.f && !outsideEdges[0] && !outsideEdges[1] && !outsideEdges[2] && mag < dOut) { infoOut = CCollisionInfo(intersectPoint - sphere.radius * surfNormal, matList, triMat, surfNormal); @@ -166,8 +169,8 @@ bool CCollidableOBBTree::SphereCollideWithLeafMoving(const COBBTree::CLeafData& ret = true; } - bool intersects = (sphere.position - surf.GetVert(0)).dot(surfNormal) <= sphere.radius; - bool testVert[] = {true, true, true}; + const bool intersects = (sphere.position - surf.GetVert(0)).dot(surfNormal) <= sphere.radius; + std::array testVert{true, true, true}; const u16* edgeIndices = x10_tree->GetTriangleEdgeIndices(triIdx); for (int k = 0; k < 3; ++k) { if (intersects || outsideEdges[k]) { @@ -187,17 +190,17 @@ bool CCollidableOBBTree::SphereCollideWithLeafMoving(const COBBTree::CLeafData& float vtsDotEdge = vertToSphere.dot(edgeVec); zeus::CVector3f vtsRej = vertToSphere - vtsDotEdge * edgeVec; if (edgeRejMagSq > 0.f) { - float tmp = 2.f * vtsRej.dot(edgeRej); - float tmp2 = 4.f * edgeRejMagSq * (vtsRej.magSquared() - sphere.radius * sphere.radius) - tmp * tmp; + const float tmp = 2.f * vtsRej.dot(edgeRej); + const float tmp2 = 4.f * edgeRejMagSq * (vtsRej.magSquared() - sphere.radius * sphere.radius) - tmp * tmp; if (tmp2 >= 0.f) { - float mag = 0.5f / edgeRejMagSq * (-tmp - std::sqrt(tmp2)); - if (mag >= 0.f) { - float t = mag * dirDotEdge + vtsDotEdge; - if (t >= 0.f && t <= edgeVecMag && mag < dOut) { + const float mag2 = 0.5f / edgeRejMagSq * (-tmp - std::sqrt(tmp2)); + if (mag2 >= 0.f) { + const float t = mag2 * dirDotEdge + vtsDotEdge; + if (t >= 0.f && t <= edgeVecMag && mag2 < dOut) { zeus::CVector3f point = surf.GetVert(k) + t * edgeVec; infoOut = CCollisionInfo(point, matList, edgeMat, - (sphere.position + mag * dir - point).normalized()); - dOut = mag; + (sphere.position + mag2 * dir - point).normalized()); + dOut = mag2; ret = true; testVert[k] = false; testVert[nextIdx] = false; @@ -217,11 +220,9 @@ bool CCollidableOBBTree::SphereCollideWithLeafMoving(const COBBTree::CLeafData& } } - u16 vertIndices[3]; - x10_tree->GetTriangleVertexIndices(triIdx, vertIndices); - + const auto vertIndices = x10_tree->GetTriangleVertexIndices(triIdx); for (int k = 0; k < 3; ++k) { - u16 vertIdx = vertIndices[k]; + const u16 vertIdx = vertIndices[k]; if (testVert[k]) { if (CMetroidAreaCollider::g_DupPrimitiveCheckCount != CMetroidAreaCollider::g_DupVertexList[vertIdx]) { CMetroidAreaCollider::g_DupVertexList[vertIdx] = CMetroidAreaCollider::g_DupPrimitiveCheckCount; @@ -246,8 +247,7 @@ bool CCollidableOBBTree::SphereCollideWithLeafMoving(const COBBTree::CLeafData& CMetroidAreaCollider::g_DupEdgeList[edgeIndices[1]] = CMetroidAreaCollider::g_DupPrimitiveCheckCount; CMetroidAreaCollider::g_DupEdgeList[edgeIndices[2]] = CMetroidAreaCollider::g_DupPrimitiveCheckCount; - u16 vertIndices[3]; - x10_tree->GetTriangleVertexIndices(triIdx, vertIndices); + const auto vertIndices = x10_tree->GetTriangleVertexIndices(triIdx); CMetroidAreaCollider::g_DupVertexList[vertIndices[0]] = CMetroidAreaCollider::g_DupPrimitiveCheckCount; CMetroidAreaCollider::g_DupVertexList[vertIndices[1]] = CMetroidAreaCollider::g_DupPrimitiveCheckCount; CMetroidAreaCollider::g_DupVertexList[vertIndices[2]] = CMetroidAreaCollider::g_DupPrimitiveCheckCount; @@ -309,8 +309,7 @@ bool CCollidableOBBTree::AABoxCollideWithLeafMoving(const COBBTree::CLeafData& l if (CollisionUtil::TriBoxOverlap(center, extent, surf.GetVert(0), surf.GetVert(1), surf.GetVert(2))) { const_cast(*this).x1c_hits += 1; - u16 vertIndices[3]; - x10_tree->GetTriangleVertexIndices(triIdx, vertIndices); + const auto vertIndices = x10_tree->GetTriangleVertexIndices(triIdx); double d = dOut; if (CMetroidAreaCollider::MovingAABoxCollisionCheck_BoxVertexTri(surf, aabb, components.x6c4_vertIdxs, dir, d, @@ -363,8 +362,7 @@ bool CCollidableOBBTree::AABoxCollideWithLeafMoving(const COBBTree::CLeafData& l CMetroidAreaCollider::g_DupEdgeList[edgeIndices[1]] = CMetroidAreaCollider::g_DupPrimitiveCheckCount; CMetroidAreaCollider::g_DupEdgeList[edgeIndices[2]] = CMetroidAreaCollider::g_DupPrimitiveCheckCount; - u16 vertIndices[3]; - x10_tree->GetTriangleVertexIndices(triIdx, vertIndices); + const auto vertIndices = x10_tree->GetTriangleVertexIndices(triIdx); CMetroidAreaCollider::g_DupVertexList[vertIndices[0]] = CMetroidAreaCollider::g_DupPrimitiveCheckCount; CMetroidAreaCollider::g_DupVertexList[vertIndices[1]] = CMetroidAreaCollider::g_DupPrimitiveCheckCount; CMetroidAreaCollider::g_DupVertexList[vertIndices[2]] = CMetroidAreaCollider::g_DupPrimitiveCheckCount; @@ -511,7 +509,7 @@ bool CCollidableOBBTree::SphereCollision(const COBBTree::CNode& node, const zeus bool CCollidableOBBTree::AABoxCollideWithLeaf(const COBBTree::CLeafData& leaf, const zeus::CTransform& xf, const zeus::CAABox& aabb, const CMaterialList& material, - const CMaterialFilter& filter, const zeus::CPlane* planes, + const CMaterialFilter& filter, const std::array& planes, CCollisionInfoList& infoList) const { bool ret = false; zeus::CVector3f center = aabb.center(); @@ -540,7 +538,7 @@ bool CCollidableOBBTree::AABoxCollideWithLeaf(const COBBTree::CLeafData& leaf, c bool CCollidableOBBTree::AABoxCollision(const COBBTree::CNode& node, const zeus::CTransform& xf, const zeus::CAABox& aabb, const zeus::COBBox& obb, const CMaterialList& material, const CMaterialFilter& filter, - const zeus::CPlane* planes, CCollisionInfoList& infoList) const { + const std::array& planes, CCollisionInfoList& infoList) const { bool ret = false; const_cast(*this).x14_tries += 1; diff --git a/Runtime/Collision/CCollidableOBBTree.hpp b/Runtime/Collision/CCollidableOBBTree.hpp index ffa2088eb..9a8f58e9d 100644 --- a/Runtime/Collision/CCollidableOBBTree.hpp +++ b/Runtime/Collision/CCollidableOBBTree.hpp @@ -31,7 +31,7 @@ public: class CCollidableOBBTree : public CCollisionPrimitive { friend class CCollidableOBBTreeGroup; - COBBTree* x10_tree = nullptr; + const COBBTree* x10_tree = nullptr; u32 x14_tries = 0; u32 x18_misses = 0; u32 x1c_hits = 0; @@ -68,11 +68,11 @@ class CCollidableOBBTree : public CCollisionPrimitive { const zeus::COBBox& obb, const CMaterialList& material, const CMaterialFilter& filter, CCollisionInfoList& infoList) const; bool AABoxCollideWithLeaf(const COBBTree::CLeafData& leaf, const zeus::CTransform& xf, const zeus::CAABox& aabb, - const CMaterialList& material, const CMaterialFilter& filter, const zeus::CPlane* planes, - CCollisionInfoList& infoList) const; + const CMaterialList& material, const CMaterialFilter& filter, + const std::array& planes, CCollisionInfoList& infoList) const; bool AABoxCollision(const COBBTree::CNode& node, const zeus::CTransform& xf, const zeus::CAABox& aabb, const zeus::COBBox& obb, const CMaterialList& material, const CMaterialFilter& filter, - const zeus::CPlane* planes, CCollisionInfoList& infoList) const; + const std::array& planes, CCollisionInfoList& infoList) const; public: CCollidableOBBTree(const COBBTree* tree, const CMaterialList& material); diff --git a/Runtime/Collision/CCollidableOBBTreeGroup.cpp b/Runtime/Collision/CCollidableOBBTreeGroup.cpp index b0f5c69c2..83cc66466 100644 --- a/Runtime/Collision/CCollidableOBBTreeGroup.cpp +++ b/Runtime/Collision/CCollidableOBBTreeGroup.cpp @@ -150,25 +150,28 @@ bool CCollidableOBBTreeGroup::CollideMovingSphere(const CInternalCollisionStruct bool CCollidableOBBTreeGroup::AABoxCollide(const CInternalCollisionStructure& collision, CCollisionInfoList& list) { bool ret = false; - const CCollidableAABox& p0 = static_cast(collision.GetLeft().GetPrim()); - const CCollidableOBBTreeGroup& p1 = static_cast(collision.GetRight().GetPrim()); + const auto& p0 = static_cast(collision.GetLeft().GetPrim()); + const auto& p1 = static_cast(collision.GetRight().GetPrim()); - zeus::CAABox b0 = p0.CalculateAABox(collision.GetLeft().GetTransform()); - zeus::COBBox p0Obb = zeus::COBBox::FromAABox(p0.CalculateLocalAABox(), collision.GetRight().GetTransform().inverse() * - collision.GetLeft().GetTransform()); + const zeus::CAABox b0 = p0.CalculateAABox(collision.GetLeft().GetTransform()); + const zeus::COBBox p0Obb = zeus::COBBox::FromAABox( + p0.CalculateLocalAABox(), collision.GetRight().GetTransform().inverse() * collision.GetLeft().GetTransform()); - zeus::CPlane planes[] = {{zeus::skRight, b0.min.dot(zeus::skRight)}, - {zeus::skLeft, b0.max.dot(zeus::skLeft)}, - {zeus::skForward, b0.min.dot(zeus::skForward)}, - {zeus::skBack, b0.max.dot(zeus::skBack)}, - {zeus::skUp, b0.min.dot(zeus::skUp)}, - {zeus::skDown, b0.max.dot(zeus::skDown)}}; + const std::array planes{{ + {zeus::skRight, b0.min.dot(zeus::skRight)}, + {zeus::skLeft, b0.max.dot(zeus::skLeft)}, + {zeus::skForward, b0.min.dot(zeus::skForward)}, + {zeus::skBack, b0.max.dot(zeus::skBack)}, + {zeus::skUp, b0.min.dot(zeus::skUp)}, + {zeus::skDown, b0.max.dot(zeus::skDown)}, + }}; for (const std::unique_ptr& tree : p1.x10_container->x0_trees) { CCollidableOBBTree obbTree(tree.get(), p1.GetMaterial()); if (obbTree.AABoxCollision(obbTree.x10_tree->GetRoot(), collision.GetRight().GetTransform(), b0, p0Obb, - p0.GetMaterial(), collision.GetLeft().GetFilter(), planes, list)) + p0.GetMaterial(), collision.GetLeft().GetFilter(), planes, list)) { ret = true; + } } return ret; diff --git a/Runtime/Collision/CCollidableOBBTreeGroup.hpp b/Runtime/Collision/CCollidableOBBTreeGroup.hpp index 9957a9a47..e48aafc77 100644 --- a/Runtime/Collision/CCollidableOBBTreeGroup.hpp +++ b/Runtime/Collision/CCollidableOBBTreeGroup.hpp @@ -19,7 +19,7 @@ class CCollidableOBBTreeGroupContainer { zeus::CAABox x20_aabox; public: - CCollidableOBBTreeGroupContainer(CInputStream& in); + explicit CCollidableOBBTreeGroupContainer(CInputStream& in); CCollidableOBBTreeGroupContainer(const zeus::CVector3f&, const zeus::CVector3f&); }; diff --git a/Runtime/Collision/CCollisionActor.cpp b/Runtime/Collision/CCollisionActor.cpp index 1c3c4875a..a8007ceca 100644 --- a/Runtime/Collision/CCollisionActor.cpp +++ b/Runtime/Collision/CCollisionActor.cpp @@ -9,17 +9,17 @@ #include "TCastTo.hpp" // Generated file, do not modify include path namespace urde { -static const CMaterialList gkDefaultCollisionActorMaterials = +constexpr CMaterialList skDefaultCollisionActorMaterials = CMaterialList(EMaterialTypes::Solid, EMaterialTypes::CollisionActor, EMaterialTypes::ScanPassthrough, EMaterialTypes::CameraPassthrough); -CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, const zeus::CVector3f& extent, +CCollisionActor::CCollisionActor(TUniqueId uid, TAreaId areaId, TUniqueId owner, const zeus::CVector3f& extent, const zeus::CVector3f& center, bool active, float mass, std::string_view name) -: CPhysicsActor(uid1, active, "CollisionActor", CEntityInfo(aId, CEntity::NullConnectionList), - zeus::CTransform(), CModelData::CModelDataNull(), gkDefaultCollisionActorMaterials, +: CPhysicsActor(uid, active, "CollisionActor", CEntityInfo(areaId, CEntity::NullConnectionList), + zeus::CTransform(), CModelData::CModelDataNull(), skDefaultCollisionActorMaterials, zeus::skNullBox, SMoverData(mass), CActorParameters::None(), 0.3f, 0.1f) , x258_primitiveType(EPrimitiveType::OBBTreeGroup) -, x25c_owner(uid2) +, x25c_owner(owner) , x260_boxSize(extent) , x26c_center(center) , x278_obbContainer(std::make_unique(extent, center)) @@ -32,13 +32,13 @@ CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, co {EMaterialTypes::Solid}, {EMaterialTypes::CollisionActor, EMaterialTypes::NoStaticCollision})); } -CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, const zeus::CVector3f& boxSize, +CCollisionActor::CCollisionActor(TUniqueId uid, TAreaId areaId, TUniqueId owner, const zeus::CVector3f& boxSize, bool active, float mass, std::string_view name) -: CPhysicsActor(uid1, active, "CollisionActor", CEntityInfo(aId, CEntity::NullConnectionList), - zeus::CTransform(), CModelData::CModelDataNull(), gkDefaultCollisionActorMaterials, +: CPhysicsActor(uid, active, "CollisionActor", CEntityInfo(areaId, CEntity::NullConnectionList), + zeus::CTransform(), CModelData::CModelDataNull(), skDefaultCollisionActorMaterials, zeus::skNullBox, SMoverData(mass), CActorParameters::None(), 0.3f, 0.1f) , x258_primitiveType(EPrimitiveType::AABox) -, x25c_owner(uid2) +, x25c_owner(owner) , x260_boxSize(boxSize) , x280_aaboxPrimitive( std::make_unique(zeus::CAABox(-0.5f * boxSize, 0.5f * boxSize), @@ -51,13 +51,13 @@ CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, co {EMaterialTypes::Solid}, {EMaterialTypes::CollisionActor, EMaterialTypes::NoStaticCollision})); } -CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, bool active, float radius, float mass, +CCollisionActor::CCollisionActor(TUniqueId uid, TAreaId areaId, TUniqueId owner, bool active, float radius, float mass, std::string_view name) -: CPhysicsActor(uid1, active, "CollisionActor", CEntityInfo(aId, CEntity::NullConnectionList), - zeus::CTransform(), CModelData::CModelDataNull(), gkDefaultCollisionActorMaterials, +: CPhysicsActor(uid, active, "CollisionActor", CEntityInfo(areaId, CEntity::NullConnectionList), + zeus::CTransform(), CModelData::CModelDataNull(), skDefaultCollisionActorMaterials, zeus::skNullBox, SMoverData(mass), CActorParameters::None(), 0.3f, 0.1f) , x258_primitiveType(EPrimitiveType::Sphere) -, x25c_owner(uid2) +, x25c_owner(owner) , x284_spherePrimitive(std::make_unique( zeus::CSphere(zeus::skZero3f, radius), CMaterialList(EMaterialTypes::NoStaticCollision, EMaterialTypes::Solid))) , x288_sphereRadius(radius) { @@ -71,7 +71,7 @@ CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, bo void CCollisionActor::Accept(IVisitor& visitor) { visitor.Visit(this); } -void CCollisionActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { +void CCollisionActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) { switch (msg) { case EScriptObjectMessage::Falling: case EScriptObjectMessage::Registered: @@ -82,7 +82,7 @@ void CCollisionActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C case EScriptObjectMessage::Damage: case EScriptObjectMessage::InvulnDamage: { if (CEntity* ent = mgr.ObjectById(x25c_owner)) { - x2fc_lastTouched = uid; + x2fc_lastTouched = sender; mgr.SendScriptMsg(ent, GetUniqueId(), msg); } } break; @@ -91,7 +91,7 @@ void CCollisionActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C break; } - CActor::AcceptScriptMsg(msg, uid, mgr); + CActor::AcceptScriptMsg(msg, sender, mgr); } CHealthInfo* CCollisionActor::HealthInfo(CStateManager&) { return &x28c_healthInfo; } @@ -157,7 +157,7 @@ std::optional CCollisionActor::GetTouchBounds() const { return aabox; } -void CCollisionActor::OnScanStateChanged(CActor::EScanState state, CStateManager& mgr) { +void CCollisionActor::OnScanStateChanged(EScanState state, CStateManager& mgr) { TCastToPtr actor = mgr.ObjectById(x25c_owner); if (actor) actor->OnScanStateChanged(state, mgr); diff --git a/Runtime/Collision/CCollisionActor.hpp b/Runtime/Collision/CCollisionActor.hpp index 4b356f02b..09435e251 100644 --- a/Runtime/Collision/CCollisionActor.hpp +++ b/Runtime/Collision/CCollisionActor.hpp @@ -33,24 +33,27 @@ class CCollisionActor : public CPhysicsActor { zeus::CVector3f x304_extendedTouchBounds = zeus::skZero3f; public: - CCollisionActor(TUniqueId, TAreaId, TUniqueId, const zeus::CVector3f&, const zeus::CVector3f&, bool, float, + CCollisionActor(TUniqueId uid, TAreaId areaId, TUniqueId owner, const zeus::CVector3f& extent, + const zeus::CVector3f& center, bool active, float mass, std::string_view name); + CCollisionActor(TUniqueId uid, TAreaId areaId, TUniqueId owner, const zeus::CVector3f& boxSize, bool active, + float mass, std::string_view name); + CCollisionActor(TUniqueId uid, TAreaId areaId, TUniqueId owner, bool active, float radius, float mass, std::string_view name); - CCollisionActor(TUniqueId, TAreaId, TUniqueId, const zeus::CVector3f&, bool, float, std::string_view name); - CCollisionActor(TUniqueId, TAreaId, TUniqueId, bool, float, float, std::string_view name); void Accept(IVisitor& visitor) override; - void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; - CHealthInfo* HealthInfo(CStateManager&) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) override; + CHealthInfo* HealthInfo(CStateManager& mgr) override; const CDamageVulnerability* GetDamageVulnerability() const override; - const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f&, - const CDamageInfo&) const override; - void OnScanStateChanged(EScanState, CStateManager&) override; + const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f& vec1, const zeus::CVector3f& vec2, + const CDamageInfo& dInfo) const override; + void OnScanStateChanged(EScanState state, CStateManager& mgr) override; - void Touch(CActor&, CStateManager&) override; - zeus::CVector3f GetOrbitPosition(const CStateManager&) const override; + void Touch(CActor& actor, CStateManager& mgr) override; + zeus::CVector3f GetOrbitPosition(const CStateManager& mgr) const override; const CCollisionPrimitive* GetCollisionPrimitive() const override; - EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, - const CWeaponMode&, EProjectileAttrib) const override; + EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f& vec1, const zeus::CVector3f& vec2, + const CWeaponMode& mode, + EProjectileAttrib attribute) const override; void SetWeaponCollisionResponseType(EWeaponCollisionResponseTypes type) { x300_responseType = type; } zeus::CTransform GetPrimitiveTransform() const override; std::optional GetTouchBounds() const override; @@ -58,7 +61,7 @@ public: const zeus::CVector3f& GetBoxSize() const { return x260_boxSize; } TUniqueId GetOwnerId() const { return x25c_owner; } TUniqueId GetLastTouchedObject() const { return x2fc_lastTouched; } - zeus::CVector3f GetScanObjectIndicatorPosition(const CStateManager&) const override; + zeus::CVector3f GetScanObjectIndicatorPosition(const CStateManager& mgr) const override; void SetExtendedTouchBounds(const zeus::CVector3f& boundExt) { x304_extendedTouchBounds = boundExt; } void SetSphereRadius(float radius); float GetSphereRadius() const { return x288_sphereRadius; } diff --git a/Runtime/Collision/CCollisionActorManager.cpp b/Runtime/Collision/CCollisionActorManager.cpp index a94b4f346..963546c4e 100644 --- a/Runtime/Collision/CCollisionActorManager.cpp +++ b/Runtime/Collision/CCollisionActorManager.cpp @@ -13,88 +13,106 @@ CCollisionActorManager::CCollisionActorManager(CStateManager& mgr, TUniqueId own const std::vector& descs, bool active) : x10_ownerId(owner), x12_active(active) { if (TCastToConstPtr act = mgr.GetObjectById(x10_ownerId)) { - zeus::CTransform xf = act->GetTransform(); + const zeus::CTransform xf = act->GetTransform(); const CAnimData* animData = act->GetModelData()->GetAnimationData(); - zeus::CVector3f scale = act->GetModelData()->GetScale(); - zeus::CTransform scaleXf = zeus::CTransform::Scale(scale); + const zeus::CVector3f scale = act->GetModelData()->GetScale(); + const zeus::CTransform scaleXf = zeus::CTransform::Scale(scale); + x0_jointDescriptions.reserve(descs.size()); for (const CJointCollisionDescription& desc : descs) { CJointCollisionDescription modDesc = desc; modDesc.ScaleAllBounds(scale); - zeus::CTransform locXf = GetWRLocatorTransform(*animData, modDesc.GetPivotId(), xf, scaleXf); + const zeus::CTransform locXf = GetWRLocatorTransform(*animData, modDesc.GetPivotId(), xf, scaleXf); + if (modDesc.GetNextId().IsValid()) { - zeus::CTransform locXf2 = GetWRLocatorTransform(*animData, modDesc.GetNextId(), xf, scaleXf); - float dist = (locXf2.origin - locXf.origin).magnitude(); + const zeus::CTransform locXf2 = GetWRLocatorTransform(*animData, modDesc.GetNextId(), xf, scaleXf); + const float dist = (locXf2.origin - locXf.origin).magnitude(); + if (modDesc.GetType() == CJointCollisionDescription::ECollisionType::OBBAutoSize) { - if (dist <= FLT_EPSILON) + if (dist <= FLT_EPSILON) { continue; + } + zeus::CVector3f bounds = modDesc.GetBounds(); bounds.y() += dist; - CCollisionActor* newAct = + auto* newAct = new CCollisionActor(mgr.AllocateUniqueId(), area, x10_ownerId, bounds, zeus::CVector3f(0.f, 0.5f * dist, 0.f), active, modDesc.GetMass(), desc.GetName()); + if (modDesc.GetOrientationType() == CJointCollisionDescription::EOrientationType::Zero) { newAct->SetTransform(locXf); } else { - zeus::CVector3f delta = (locXf2.origin - locXf.origin).normalized(); + const zeus::CVector3f delta = (locXf2.origin - locXf.origin).normalized(); zeus::CVector3f upVector = locXf.basis[2]; - if (zeus::close_enough(std::fabs(delta.dot(upVector)), 1.f)) + + if (zeus::close_enough(std::fabs(delta.dot(upVector)), 1.f)) { upVector = locXf.basis[1]; + } + newAct->SetTransform(zeus::lookAt(locXf.origin, locXf.origin + delta, upVector)); } + mgr.AddObject(newAct); x0_jointDescriptions.push_back(desc); x0_jointDescriptions.back().SetCollisionActorId(newAct->GetUniqueId()); } else { - TUniqueId newId = mgr.AllocateUniqueId(); - CCollisionActor* newAct = - new CCollisionActor(newId, area, x10_ownerId, active, modDesc.GetRadius(), modDesc.GetMass(), - desc.GetName()); + const TUniqueId newId = mgr.AllocateUniqueId(); + auto* newAct = new CCollisionActor(newId, area, x10_ownerId, active, modDesc.GetRadius(), modDesc.GetMass(), + desc.GetName()); + newAct->SetTransform(locXf); mgr.AddObject(newAct); x0_jointDescriptions.push_back(CJointCollisionDescription::SphereCollision( modDesc.GetPivotId(), modDesc.GetRadius(), modDesc.GetName(), 0.001f)); x0_jointDescriptions.back().SetCollisionActorId(newId); - u32 numSeps = u32(dist / modDesc.GetMaxSeparation()); - if (numSeps) { + + const u32 numSeps = u32(dist / modDesc.GetMaxSeparation()); + if (numSeps != 0) { x0_jointDescriptions.reserve(x0_jointDescriptions.capacity() + numSeps); - float pitch = dist / float(numSeps + 1); + const float pitch = dist / float(numSeps + 1); for (u32 i = 0; i < numSeps; ++i) { - float separation = pitch * float(i + 1); + const float separation = pitch * float(i + 1); x0_jointDescriptions.push_back(CJointCollisionDescription::SphereSubdivideCollision( modDesc.GetPivotId(), modDesc.GetNextId(), modDesc.GetRadius(), separation, CJointCollisionDescription::EOrientationType::One, modDesc.GetName(), 0.001f)); - TUniqueId newId2 = mgr.AllocateUniqueId(); - CCollisionActor* newAct2 = - new CCollisionActor(newId2, area, x10_ownerId, active, modDesc.GetRadius(), modDesc.GetMass(), - desc.GetName()); + + const TUniqueId newId2 = mgr.AllocateUniqueId(); + auto* newAct2 = new CCollisionActor(newId2, area, x10_ownerId, active, modDesc.GetRadius(), + modDesc.GetMass(), desc.GetName()); if (modDesc.GetOrientationType() == CJointCollisionDescription::EOrientationType::Zero) { newAct2->SetTransform(zeus::CTransform::Translate(locXf.origin + separation * locXf.basis[1])); } else { - zeus::CVector3f delta = (locXf2.origin - locXf.origin).normalized(); + const zeus::CVector3f delta = (locXf2.origin - locXf.origin).normalized(); zeus::CVector3f upVector = locXf.basis[2]; - if (zeus::close_enough(std::fabs(delta.dot(upVector)), 1.f)) + + if (zeus::close_enough(std::fabs(delta.dot(upVector)), 1.f)) { upVector = locXf.basis[1]; - zeus::CTransform lookAt = zeus::lookAt(zeus::skZero3f, delta, upVector); + } + + const zeus::CTransform lookAt = zeus::lookAt(zeus::skZero3f, delta, upVector); newAct2->SetTransform(zeus::CTransform::Translate(lookAt.basis[1] * separation + locXf.origin)); } + mgr.AddObject(newAct2); x0_jointDescriptions.back().SetCollisionActorId(newId2); } } } } else { - TUniqueId newId = mgr.AllocateUniqueId(); + const TUniqueId newId = mgr.AllocateUniqueId(); CCollisionActor* newAct; - if (modDesc.GetType() == CJointCollisionDescription::ECollisionType::Sphere) + + if (modDesc.GetType() == CJointCollisionDescription::ECollisionType::Sphere) { newAct = new CCollisionActor(newId, area, x10_ownerId, active, modDesc.GetRadius(), modDesc.GetMass(), desc.GetName()); - else if (modDesc.GetType() == CJointCollisionDescription::ECollisionType::OBB) + } else if (modDesc.GetType() == CJointCollisionDescription::ECollisionType::OBB) { newAct = new CCollisionActor(newId, area, x10_ownerId, modDesc.GetBounds(), modDesc.GetPivotPoint(), active, modDesc.GetMass(), desc.GetName()); - else + } else { newAct = new CCollisionActor(newId, area, x10_ownerId, modDesc.GetBounds(), active, modDesc.GetMass(), desc.GetName()); + } + newAct->SetTransform(locXf); mgr.AddObject(newAct); x0_jointDescriptions.push_back(desc); @@ -105,8 +123,9 @@ CCollisionActorManager::CCollisionActorManager(CStateManager& mgr, TUniqueId own } void CCollisionActorManager::Destroy(CStateManager& mgr) const { - for (const CJointCollisionDescription& desc : x0_jointDescriptions) + for (const CJointCollisionDescription& desc : x0_jointDescriptions) { mgr.FreeScriptObject(desc.GetCollisionActorId()); + } const_cast(*this).x13_destroyed = true; } @@ -115,26 +134,33 @@ void CCollisionActorManager::SetActive(CStateManager& mgr, bool active) { x12_active = active; for (const CJointCollisionDescription& jDesc : x0_jointDescriptions) { if (TCastToPtr act = mgr.ObjectById(jDesc.GetCollisionActorId())) { - bool curActive = act->GetActive(); - if (curActive != active) + const bool curActive = act->GetActive(); + if (curActive != active) { act->SetActive(active); + } - if (active) + if (active) { Update(0.f, mgr, EUpdateOptions::WorldSpace); + } } } } void CCollisionActorManager::AddMaterial(CStateManager& mgr, const CMaterialList& list) { - for (const CJointCollisionDescription& jDesc : x0_jointDescriptions) - if (TCastToPtr act = mgr.ObjectById(jDesc.GetCollisionActorId())) + for (const CJointCollisionDescription& jDesc : x0_jointDescriptions) { + if (TCastToPtr act = mgr.ObjectById(jDesc.GetCollisionActorId())) { act->AddMaterial(list); + } + } } void CCollisionActorManager::SetMovable(CStateManager& mgr, bool movable) { - if (x14_movable == movable) + if (x14_movable == movable) { return; + } + x14_movable = movable; + for (const CJointCollisionDescription& jDesc : x0_jointDescriptions) { if (TCastToPtr act = mgr.ObjectById(jDesc.GetCollisionActorId())) { act->SetMovable(x14_movable); @@ -144,38 +170,46 @@ void CCollisionActorManager::SetMovable(CStateManager& mgr, bool movable) { } void CCollisionActorManager::Update(float dt, CStateManager& mgr, EUpdateOptions opts) { - if (!x14_movable) + if (!x14_movable) { SetMovable(mgr, true); - if (x12_active) { - if (TCastToPtr act = mgr.ObjectById(x10_ownerId)) { - const CAnimData& animData = *act->GetModelData()->GetAnimationData(); - zeus::CTransform actXf = act->GetTransform(); - zeus::CTransform scaleXf = zeus::CTransform::Scale(act->GetModelData()->GetScale()); - for (const CJointCollisionDescription& jDesc : x0_jointDescriptions) { - if (TCastToPtr cAct = mgr.ObjectById(jDesc.GetCollisionActorId())) { - zeus::CTransform pivotXf = GetWRLocatorTransform(animData, jDesc.GetPivotId(), actXf, scaleXf); - zeus::CVector3f origin = pivotXf.origin; - if (jDesc.GetType() == CJointCollisionDescription::ECollisionType::OBB || - jDesc.GetType() == CJointCollisionDescription::ECollisionType::OBBAutoSize) { - if (jDesc.GetOrientationType() == CJointCollisionDescription::EOrientationType::Zero) { - cAct->SetTransform(zeus::CQuaternion(pivotXf.basis).toTransform(cAct->GetTranslation())); - } else { - zeus::CTransform nextXf = GetWRLocatorTransform(animData, jDesc.GetNextId(), actXf, scaleXf); - cAct->SetTransform(zeus::CQuaternion(zeus::lookAt(pivotXf.origin, nextXf.origin, pivotXf.basis[2]).basis) - .toTransform(cAct->GetTranslation())); - } - } else if (jDesc.GetType() == CJointCollisionDescription::ECollisionType::SphereSubdivide) { - if (jDesc.GetOrientationType() == CJointCollisionDescription::EOrientationType::Zero) { - origin += jDesc.GetMaxSeparation() * pivotXf.basis[1]; - } else { - zeus::CTransform nextXf = GetWRLocatorTransform(animData, jDesc.GetNextId(), actXf, scaleXf); - origin += zeus::lookAt(origin, nextXf.origin, pivotXf.basis[2]).basis[1] * jDesc.GetMaxSeparation(); - } + } + + if (!x12_active) { + return; + } + + if (const TCastToConstPtr act = mgr.ObjectById(x10_ownerId)) { + const CAnimData& animData = *act->GetModelData()->GetAnimationData(); + const zeus::CTransform actXf = act->GetTransform(); + const zeus::CTransform scaleXf = zeus::CTransform::Scale(act->GetModelData()->GetScale()); + + for (const CJointCollisionDescription& jDesc : x0_jointDescriptions) { + if (TCastToPtr cAct = mgr.ObjectById(jDesc.GetCollisionActorId())) { + const zeus::CTransform pivotXf = GetWRLocatorTransform(animData, jDesc.GetPivotId(), actXf, scaleXf); + zeus::CVector3f origin = pivotXf.origin; + + if (jDesc.GetType() == CJointCollisionDescription::ECollisionType::OBB || + jDesc.GetType() == CJointCollisionDescription::ECollisionType::OBBAutoSize) { + if (jDesc.GetOrientationType() == CJointCollisionDescription::EOrientationType::Zero) { + cAct->SetTransform(zeus::CQuaternion(pivotXf.basis).toTransform(cAct->GetTranslation())); + } else { + const zeus::CTransform nextXf = GetWRLocatorTransform(animData, jDesc.GetNextId(), actXf, scaleXf); + cAct->SetTransform(zeus::CQuaternion(zeus::lookAt(pivotXf.origin, nextXf.origin, pivotXf.basis[2]).basis) + .toTransform(cAct->GetTranslation())); } - if (opts == EUpdateOptions::ObjectSpace) - cAct->MoveToOR(cAct->GetTransform().transposeRotate(origin - cAct->GetTranslation()), dt); - else - cAct->SetTranslation(origin); + } else if (jDesc.GetType() == CJointCollisionDescription::ECollisionType::SphereSubdivide) { + if (jDesc.GetOrientationType() == CJointCollisionDescription::EOrientationType::Zero) { + origin += jDesc.GetMaxSeparation() * pivotXf.basis[1]; + } else { + const zeus::CTransform nextXf = GetWRLocatorTransform(animData, jDesc.GetNextId(), actXf, scaleXf); + origin += zeus::lookAt(origin, nextXf.origin, pivotXf.basis[2]).basis[1] * jDesc.GetMaxSeparation(); + } + } + + if (opts == EUpdateOptions::ObjectSpace) { + cAct->MoveToOR(cAct->GetTransform().transposeRotate(origin - cAct->GetTranslation()), dt); + } else { + cAct->SetTranslation(origin); } } } @@ -186,7 +220,7 @@ zeus::CTransform CCollisionActorManager::GetWRLocatorTransform(const CAnimData& const zeus::CTransform& worldXf, const zeus::CTransform& localXf) { zeus::CTransform locXf = animData.GetLocatorTransform(id, nullptr); - zeus::CVector3f origin = worldXf * (localXf * locXf.origin); + const zeus::CVector3f origin = worldXf * (localXf * locXf.origin); locXf = worldXf.multiplyIgnoreTranslation(locXf); locXf.origin = origin; return locXf; @@ -194,21 +228,22 @@ zeus::CTransform CCollisionActorManager::GetWRLocatorTransform(const CAnimData& std::optional CCollisionActorManager::GetDeviation(const CStateManager& mgr, CSegId seg) { for (const CJointCollisionDescription& desc : x0_jointDescriptions) { - if (desc.GetPivotId() != seg) + if (desc.GetPivotId() != seg) { continue; + } - if (TCastToConstPtr act = mgr.GetObjectById(x10_ownerId)) { - if (TCastToConstPtr colAct = mgr.GetObjectById(desc.GetCollisionActorId())) { - zeus::CTransform xf = GetWRLocatorTransform(*act->GetModelData()->GetAnimationData(), desc.GetPivotId(), - act->GetTransform(), - zeus::CTransform::Scale(act->GetModelData()->GetScale())); + if (const TCastToConstPtr act = mgr.GetObjectById(x10_ownerId)) { + if (const TCastToConstPtr colAct = mgr.GetObjectById(desc.GetCollisionActorId())) { + const zeus::CTransform xf = + GetWRLocatorTransform(*act->GetModelData()->GetAnimationData(), desc.GetPivotId(), act->GetTransform(), + zeus::CTransform::Scale(act->GetModelData()->GetScale())); return {colAct->GetTranslation() - xf.origin}; } } } - return {}; + return std::nullopt; } } // namespace urde diff --git a/Runtime/Collision/CCollisionEdge.hpp b/Runtime/Collision/CCollisionEdge.hpp index 2b4a5db83..7c976a058 100644 --- a/Runtime/Collision/CCollisionEdge.hpp +++ b/Runtime/Collision/CCollisionEdge.hpp @@ -8,14 +8,14 @@ class CCollisionEdge { u16 x2_index2 = -1; public: - CCollisionEdge() = default; - CCollisionEdge(CInputStream&); - CCollisionEdge(u16 v0, u16 v1) : x0_index1(v0), x2_index2(v1) {} + constexpr CCollisionEdge() noexcept = default; + explicit CCollisionEdge(CInputStream&); + constexpr CCollisionEdge(u16 v0, u16 v1) noexcept : x0_index1(v0), x2_index2(v1) {} - u16 GetVertIndex1() const { return x0_index1; } - u16 GetVertIndex2() const { return x2_index2; } + [[nodiscard]] constexpr u16 GetVertIndex1() const noexcept { return x0_index1; } + [[nodiscard]] constexpr u16 GetVertIndex2() const noexcept { return x2_index2; } - void swapBig() { + constexpr void swapBig() noexcept { x0_index1 = hecl::SBig(x0_index1); x2_index2 = hecl::SBig(x2_index2); } diff --git a/Runtime/Collision/CCollisionInfoList.hpp b/Runtime/Collision/CCollisionInfoList.hpp index c41eaea3e..30a10d2b1 100644 --- a/Runtime/Collision/CCollisionInfoList.hpp +++ b/Runtime/Collision/CCollisionInfoList.hpp @@ -53,9 +53,10 @@ public: void Clear() { x0_list.clear(); } const CCollisionInfo& Front() const { return x0_list.front(); } const CCollisionInfo& GetItem(int i) const { return x0_list[i]; } - rstl::reserved_vector::iterator end() { return x0_list.end(); } - rstl::reserved_vector::const_iterator end() const { return x0_list.end(); } - rstl::reserved_vector::iterator begin() { return x0_list.begin(); } - rstl::reserved_vector::const_iterator begin() const { return x0_list.begin(); } + + auto end() noexcept { return x0_list.end(); } + auto end() const noexcept { return x0_list.end(); } + auto begin() noexcept { return x0_list.begin(); } + auto begin() const noexcept { return x0_list.begin(); } }; } // namespace urde diff --git a/Runtime/Collision/CCollisionPrimitive.hpp b/Runtime/Collision/CCollisionPrimitive.hpp index 79db8fbdc..bbe619908 100644 --- a/Runtime/Collision/CCollisionPrimitive.hpp +++ b/Runtime/Collision/CCollisionPrimitive.hpp @@ -134,7 +134,7 @@ private: public: CCollisionPrimitive() = default; - CCollisionPrimitive(const CMaterialList& list); + explicit CCollisionPrimitive(const CMaterialList& list); virtual u32 GetTableIndex() const = 0; virtual void SetMaterial(const CMaterialList&); virtual const CMaterialList& GetMaterial() const; diff --git a/Runtime/Collision/CCollisionResponseData.hpp b/Runtime/Collision/CCollisionResponseData.hpp index 019426945..4b61ca6d4 100644 --- a/Runtime/Collision/CCollisionResponseData.hpp +++ b/Runtime/Collision/CCollisionResponseData.hpp @@ -9,9 +9,9 @@ #include "Runtime/IObj.hpp" #include "Runtime/RetroTypes.hpp" #include "Runtime/Collision/CMaterialList.hpp" +#include "Runtime/Particle/CDecalDescription.hpp" namespace urde { -class CDecalDescription; class CGenDescription; class CSimplePool; @@ -126,7 +126,7 @@ class CCollisionResponseData { bool CheckAndAddResourceToResponse(FourCC clsId, CInputStream& in, CSimplePool* resPool); public: - CCollisionResponseData(CInputStream& in, CSimplePool* resPool); + explicit CCollisionResponseData(CInputStream& in, CSimplePool* resPool); const std::optional>& GetParticleDescription(EWeaponCollisionResponseTypes type) const; const std::optional>& GetDecalDescription(EWeaponCollisionResponseTypes type) const; s32 GetSoundEffectId(EWeaponCollisionResponseTypes type) const; diff --git a/Runtime/Collision/CCollisionSurface.cpp b/Runtime/Collision/CCollisionSurface.cpp index 749396146..f1b48e350 100644 --- a/Runtime/Collision/CCollisionSurface.cpp +++ b/Runtime/Collision/CCollisionSurface.cpp @@ -5,16 +5,16 @@ namespace urde { CCollisionSurface::CCollisionSurface(const zeus::CVector3f& a, const zeus::CVector3f& b, const zeus::CVector3f& c, u32 flags) -: x0_a(a), xc_b(b), x18_c(c), x24_flags(flags) {} +: x0_data{a, b, c}, x24_flags(flags) {} zeus::CVector3f CCollisionSurface::GetNormal() const { - zeus::CVector3f v1 = (xc_b - x0_a).cross(x18_c - x0_a); + const zeus::CVector3f v1 = (x0_data[1] - x0_data[0]).cross(x0_data[2] - x0_data[0]); return zeus::CUnitVector3f(v1, true); } zeus::CPlane CCollisionSurface::GetPlane() const { - zeus::CVector3f norm = GetNormal(); - return {norm, norm.dot(x0_a)}; + const zeus::CVector3f norm = GetNormal(); + return {norm, norm.dot(x0_data[0])}; } } // namespace urde diff --git a/Runtime/Collision/CCollisionSurface.hpp b/Runtime/Collision/CCollisionSurface.hpp index 9cc67cedb..ea7a6ce50 100644 --- a/Runtime/Collision/CCollisionSurface.hpp +++ b/Runtime/Collision/CCollisionSurface.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "Runtime/GCNTypes.hpp" #include @@ -7,17 +9,19 @@ namespace urde { class CCollisionSurface { - zeus::CVector3f x0_a; - zeus::CVector3f xc_b; - zeus::CVector3f x18_c; +public: + using Vertices = std::array; + +private: + Vertices x0_data; u32 x24_flags; public: - CCollisionSurface(const zeus::CVector3f&, const zeus::CVector3f&, const zeus::CVector3f&, u32); + CCollisionSurface(const zeus::CVector3f& a, const zeus::CVector3f& b, const zeus::CVector3f& c, u32 flags); zeus::CVector3f GetNormal() const; - const zeus::CVector3f& GetVert(s32 idx) const { return (&x0_a)[idx]; } - const zeus::CVector3f* GetVerts() const { return &x0_a; } + const zeus::CVector3f& GetVert(s32 idx) const { return x0_data[idx]; } + const Vertices& GetVerts() const { return x0_data; } zeus::CPlane GetPlane() const; u32 GetSurfaceFlags() const { return x24_flags; } }; diff --git a/Runtime/Collision/CGameCollision.cpp b/Runtime/Collision/CGameCollision.cpp index f510460fc..bf1585ea8 100644 --- a/Runtime/Collision/CGameCollision.cpp +++ b/Runtime/Collision/CGameCollision.cpp @@ -180,10 +180,12 @@ zeus::CVector3f CGameCollision::GetActorRelativeVelocities(const CPhysicsActor& zeus::CVector3f ret = act0.GetVelocity(); if (act1) { bool rider = false; - if (TCastToConstPtr plat = act1) + if (const TCastToConstPtr plat = act1) { rider = plat->IsRider(act0.GetUniqueId()); - if (!rider) + } + if (!rider) { ret -= act1->GetVelocity(); + } } return ret; } @@ -288,15 +290,16 @@ CRayCastResult CGameCollision::RayDynamicIntersection(const CStateManager& mgr, const rstl::reserved_vector& nearList) { CRayCastResult ret; float bestT = length; - if (bestT <= 0.f) + if (bestT <= 0.f) { bestT = 100000.f; + } for (TUniqueId id : nearList) { - CEntity* ent = const_cast(mgr.GetObjectById(id)); - if (TCastToPtr physActor = ent) { - zeus::CTransform xf = physActor->GetPrimitiveTransform(); + const CEntity* ent = mgr.GetObjectById(id); + if (const TCastToConstPtr physActor = ent) { + const zeus::CTransform xf = physActor->GetPrimitiveTransform(); const CCollisionPrimitive* prim = physActor->GetCollisionPrimitive(); - CRayCastResult res = prim->CastRay(pos, dir, bestT, filter, xf); + const CRayCastResult res = prim->CastRay(pos, dir, bestT, filter, xf); if (!res.IsInvalid() && res.GetT() < bestT) { bestT = res.GetT(); ret = res; @@ -312,19 +315,22 @@ bool CGameCollision::RayDynamicIntersectionBool(const CStateManager& mgr, const const zeus::CVector3f& dir, const CMaterialFilter& filter, const rstl::reserved_vector& nearList, const CActor* damagee, float length) { - if (length <= 0.f) + if (length <= 0.f) { length = 100000.f; + } for (TUniqueId id : nearList) { const CEntity* ent = mgr.GetObjectById(id); - if (TCastToConstPtr physActor = ent) { - if (damagee && physActor->GetUniqueId() == damagee->GetUniqueId()) + if (const TCastToConstPtr physActor = ent) { + if (damagee && physActor->GetUniqueId() == damagee->GetUniqueId()) { continue; - zeus::CTransform xf = physActor->GetPrimitiveTransform(); + } + const zeus::CTransform xf = physActor->GetPrimitiveTransform(); const CCollisionPrimitive* prim = physActor->GetCollisionPrimitive(); - CRayCastResult res = prim->CastRay(pos, dir, length, filter, xf); - if (!res.IsInvalid()) + const CRayCastResult res = prim->CastRay(pos, dir, length, filter, xf); + if (!res.IsInvalid()) { return false; + } } } @@ -469,13 +475,14 @@ bool CGameCollision::DetectStaticCollisionBoolean_Cached(const CStateManager& mg bool CGameCollision::DetectDynamicCollisionBoolean(const CCollisionPrimitive& prim, const zeus::CTransform& xf, const rstl::reserved_vector& nearList, const CStateManager& mgr) { - for (TUniqueId id : nearList) { - if (TCastToConstPtr actor = mgr.GetObjectById(id)) { - CInternalCollisionStructure::CPrimDesc p0(prim, CMaterialFilter::skPassEverything, xf); - CInternalCollisionStructure::CPrimDesc p1(*actor->GetCollisionPrimitive(), CMaterialFilter::skPassEverything, - actor->GetPrimitiveTransform()); - if (CCollisionPrimitive::CollideBoolean(p0, p1)) + for (const TUniqueId id : nearList) { + if (const TCastToConstPtr actor = mgr.GetObjectById(id)) { + const CInternalCollisionStructure::CPrimDesc p0(prim, CMaterialFilter::skPassEverything, xf); + const CInternalCollisionStructure::CPrimDesc p1( + *actor->GetCollisionPrimitive(), CMaterialFilter::skPassEverything, actor->GetPrimitiveTransform()); + if (CCollisionPrimitive::CollideBoolean(p0, p1)) { return true; + } } } @@ -638,11 +645,11 @@ bool CGameCollision::DetectStaticCollision_Cached_Moving(const CStateManager& mg bool CGameCollision::DetectDynamicCollision(const CCollisionPrimitive& prim, const zeus::CTransform& xf, const rstl::reserved_vector& nearList, TUniqueId& idOut, CCollisionInfoList& list, const CStateManager& mgr) { - for (TUniqueId id : nearList) { - if (TCastToConstPtr actor = mgr.GetObjectById(id)) { - CInternalCollisionStructure::CPrimDesc p0(prim, CMaterialFilter::skPassEverything, xf); - CInternalCollisionStructure::CPrimDesc p1(*actor->GetCollisionPrimitive(), CMaterialFilter::skPassEverything, - actor->GetPrimitiveTransform()); + for (const TUniqueId id : nearList) { + if (const TCastToConstPtr actor = mgr.GetObjectById(id)) { + const CInternalCollisionStructure::CPrimDesc p0(prim, CMaterialFilter::skPassEverything, xf); + const CInternalCollisionStructure::CPrimDesc p1( + *actor->GetCollisionPrimitive(), CMaterialFilter::skPassEverything, actor->GetPrimitiveTransform()); if (CCollisionPrimitive::Collide(p0, p1, list)) { idOut = actor->GetUniqueId(); return true; @@ -658,13 +665,13 @@ bool CGameCollision::DetectDynamicCollisionMoving(const CCollisionPrimitive& pri const zeus::CVector3f& dir, TUniqueId& idOut, CCollisionInfo& infoOut, double& dOut, const CStateManager& mgr) { bool ret = false; - for (TUniqueId id : nearList) { + for (const TUniqueId id : nearList) { double d = dOut; CCollisionInfo info; - if (TCastToConstPtr actor = mgr.GetObjectById(id)) { - CInternalCollisionStructure::CPrimDesc p0(prim, CMaterialFilter::skPassEverything, xf); - CInternalCollisionStructure::CPrimDesc p1(*actor->GetCollisionPrimitive(), CMaterialFilter::skPassEverything, - actor->GetPrimitiveTransform()); + if (const TCastToConstPtr actor = mgr.GetObjectById(id)) { + const CInternalCollisionStructure::CPrimDesc p0(prim, CMaterialFilter::skPassEverything, xf); + const CInternalCollisionStructure::CPrimDesc p1( + *actor->GetCollisionPrimitive(), CMaterialFilter::skPassEverything, actor->GetPrimitiveTransform()); if (CCollisionPrimitive::CollideMoving(p0, p1, dir, d, info) && d < dOut) { ret = true; infoOut = info; @@ -680,13 +687,17 @@ bool CGameCollision::DetectDynamicCollisionMoving(const CCollisionPrimitive& pri void CGameCollision::MakeCollisionCallbacks(CStateManager& mgr, CPhysicsActor& actor, TUniqueId id, const CCollisionInfoList& list) { actor.CollidedWith(id, list, mgr); - if (id != kInvalidUniqueId) { - if (TCastToPtr actor = mgr.ObjectById(id)) { - CCollisionInfoList swappedList = list; - for (CCollisionInfo& info : swappedList) - info.Swap(); - actor->CollidedWith(actor->GetUniqueId(), list, mgr); + + if (id == kInvalidUniqueId) { + return; + } + + if (const TCastToPtr physicalActor = mgr.ObjectById(id)) { + CCollisionInfoList swappedList = list; + for (CCollisionInfo& info : swappedList) { + info.Swap(); } + physicalActor->CollidedWith(physicalActor->GetUniqueId(), list, mgr); } } @@ -694,11 +705,13 @@ void CGameCollision::SendScriptMessages(CStateManager& mgr, CActor& a0, CActor* bool onFloor = false; bool platform = false; bool platform2 = false; + for (const CCollisionInfo& info : list) { if (IsFloor(info.GetMaterialLeft(), info.GetNormalLeft())) { onFloor = true; - if (info.GetMaterialLeft().HasMaterial(EMaterialTypes::Platform)) + if (info.GetMaterialLeft().HasMaterial(EMaterialTypes::Platform)) { platform = true; + } SendMaterialMessage(mgr, info.GetMaterialLeft(), a0); } } @@ -706,15 +719,16 @@ void CGameCollision::SendScriptMessages(CStateManager& mgr, CActor& a0, CActor* if (onFloor) { mgr.SendScriptMsg(&a0, kInvalidUniqueId, EScriptObjectMessage::OnFloor); if (platform) { - if (TCastToPtr plat = a1) { + if (const TCastToPtr plat = a1) { mgr.SendScriptMsg(plat.GetPtr(), a0.GetUniqueId(), EScriptObjectMessage::AddPlatformRider); } } else if (a1) { - if (TCastToPtr plat = a0) { + if (const TCastToPtr plat = a0) { for (const CCollisionInfo& info : list) { if (IsFloor(info.GetMaterialRight(), info.GetNormalRight())) { - if (info.GetMaterialRight().HasMaterial(EMaterialTypes::Platform)) + if (info.GetMaterialRight().HasMaterial(EMaterialTypes::Platform)) { platform2 = true; + } SendMaterialMessage(mgr, info.GetMaterialLeft(), a0); } } @@ -860,9 +874,10 @@ void CGameCollision::CollisionFailsafe(const CStateManager& mgr, CAreaCollisionC } } -std::optional CGameCollision::FindNonIntersectingVector( - const CStateManager& mgr, CAreaCollisionCache& cache, CPhysicsActor& actor, const CCollisionPrimitive& prim, - const rstl::reserved_vector& nearList) { +std::optional +CGameCollision::FindNonIntersectingVector(const CStateManager& mgr, CAreaCollisionCache& cache, CPhysicsActor& actor, + const CCollisionPrimitive& prim, + const rstl::reserved_vector& nearList) { zeus::CTransform xf = actor.GetPrimitiveTransform(); zeus::CVector3f origOrigin = xf.origin; zeus::CVector3f center = prim.CalculateAABox(xf).center(); @@ -967,4 +982,41 @@ std::optional CGameCollision::FindNonIntersectingVector( return {}; } + +void CGameCollision::AvoidStaticCollisionWithinRadius(const CStateManager& mgr, CPhysicsActor& actor, u32 iterations, + float dt, float height, float size, float mass, float radius) { + const zeus::CVector3f& actorPos = actor.GetTranslation(); + const zeus::CVector3f pos = actorPos + zeus::CVector3f{0.f, 0.f, height}; + const float largeRadius = 1.2f * radius; + const zeus::CVector3f diff{size + largeRadius, size + largeRadius, largeRadius}; + const zeus::CAABox aabb{pos - diff, pos + diff}; + CAreaCollisionCache cache{aabb}; + BuildAreaCollisionCache(mgr, cache); + + const CCollidableSphere prim{{pos, radius}, {EMaterialTypes::Solid}}; + if (!DetectStaticCollisionBoolean_Cached(mgr, cache, prim, {}, CMaterialFilter::MakeExclude(EMaterialTypes::Floor))) { + zeus::CVector3f velocity = zeus::skZero3f; + float seg = zeus::degToRad(360.f) / iterations; + for (u32 i = 0; i < iterations; ++i) { + const float angle = seg * i; + const zeus::CVector3f vec{std::sin(angle), std::cos(angle), 0.f}; + double out = size; + CCollisionInfo info{}; + if (cache.HasCacheOverflowed()) { + cache.ClearCache(); + zeus::CAABox aabb2{pos, pos}; + aabb2.accumulateBounds(actorPos + (size * vec)); + cache.SetCacheBounds(zeus::CAABox{aabb2.min - radius, aabb2.max + radius}); + BuildAreaCollisionCache(mgr, cache); + } + + if (DetectStaticCollision_Cached_Moving(mgr, cache, prim, {}, CMaterialFilter::MakeExclude(EMaterialTypes::Floor), + vec, info, out)) { + float force = static_cast((size - out) / size) / iterations; + velocity -= force * vec; + } + } + actor.SetVelocityWR(actor.GetVelocity() + (dt * (mass * velocity))); + } +} } // namespace urde diff --git a/Runtime/Collision/CGameCollision.hpp b/Runtime/Collision/CGameCollision.hpp index eb346c3e2..ac3b9e292 100644 --- a/Runtime/Collision/CGameCollision.hpp +++ b/Runtime/Collision/CGameCollision.hpp @@ -119,5 +119,7 @@ public: static std::optional FindNonIntersectingVector(const CStateManager& mgr, CAreaCollisionCache& cache, CPhysicsActor& actor, const CCollisionPrimitive& prim, const rstl::reserved_vector& nearList); + static void AvoidStaticCollisionWithinRadius(const CStateManager& mgr, CPhysicsActor& actor, u32 iterations, float dt, + float height, float size, float mass, float radius); }; } // namespace urde diff --git a/Runtime/Collision/CMetroidAreaCollider.cpp b/Runtime/Collision/CMetroidAreaCollider.cpp index 5e5ffed0b..3a914762e 100644 --- a/Runtime/Collision/CMetroidAreaCollider.cpp +++ b/Runtime/Collision/CMetroidAreaCollider.cpp @@ -11,12 +11,13 @@ u32 CMetroidAreaCollider::g_RejectedByClip = 0; u32 CMetroidAreaCollider::g_TrianglesProcessed = 0; u32 CMetroidAreaCollider::g_DupTrianglesProcessed = 0; u16 CMetroidAreaCollider::g_DupPrimitiveCheckCount = 0; -u16 CMetroidAreaCollider::g_DupVertexList[0x5000] = {}; -u16 CMetroidAreaCollider::g_DupEdgeList[0xC000] = {}; -u16 CMetroidAreaCollider::g_DupTriangleList[0x4000] = {}; +std::array CMetroidAreaCollider::g_DupVertexList{}; +std::array CMetroidAreaCollider::g_DupEdgeList{}; +std::array CMetroidAreaCollider::g_DupTriangleList{}; -CAABoxAreaCache::CAABoxAreaCache(const zeus::CAABox& aabb, const zeus::CPlane* pl, const CMaterialFilter& filter, - const CMaterialList& material, CCollisionInfoList& collisionList) +CAABoxAreaCache::CAABoxAreaCache(const zeus::CAABox& aabb, const std::array& pl, + const CMaterialFilter& filter, const CMaterialList& material, + CCollisionInfoList& collisionList) : x0_aabb(aabb) , x4_planes(pl) , x8_filter(filter) @@ -44,7 +45,7 @@ SBoxEdge::SBoxEdge(const zeus::CAABox& aabb, int idx, const zeus::CVector3f& dir , x70_coDir(x58_delta.cross(dir).asNormalized()) , x88_dirCoDirDot(x28_start.dot(x70_coDir)) {} -static void FlagEdgeIndicesForFace(int face, bool edgeFlags[12]) { +static void FlagEdgeIndicesForFace(int face, std::array& edgeFlags) { switch (face) { case 0: edgeFlags[10] = true; @@ -87,7 +88,7 @@ static void FlagEdgeIndicesForFace(int face, bool edgeFlags[12]) { } } -static void FlagVertexIndicesForFace(int face, bool vertFlags[8]) { +static void FlagVertexIndicesForFace(int face, std::array& vertFlags) { switch (face) { case 0: vertFlags[1] = true; @@ -131,26 +132,30 @@ static void FlagVertexIndicesForFace(int face, bool vertFlags[8]) { } CMovingAABoxComponents::CMovingAABoxComponents(const zeus::CAABox& aabb, const zeus::CVector3f& dir) : x6e8_aabb(aabb) { - bool edgeFlags[12] = {}; - bool vertFlags[8] = {}; + std::array edgeFlags{}; + std::array vertFlags{}; int useFaces = 0; for (int i = 0; i < 3; ++i) { if (dir[i] != 0.f) { - int face = i * 2 + (dir[i] < 0.f); + const int face = i * 2 + (dir[i] < 0.f); FlagEdgeIndicesForFace(face, edgeFlags); FlagVertexIndicesForFace(face, vertFlags); useFaces += 1; } } - for (int i = 0; i < 12; ++i) - if (edgeFlags[i]) - x0_edges.push_back(SBoxEdge(aabb, i, dir)); + for (size_t i = 0; i < edgeFlags.size(); ++i) { + if (edgeFlags[i]) { + x0_edges.emplace_back(aabb, s32(i), dir); + } + } - for (int i = 0; i < 8; ++i) - if (vertFlags[i]) - x6c4_vertIdxs.push_back(i); + for (size_t i = 0; i < vertFlags.size(); ++i) { + if (vertFlags[i]) { + x6c4_vertIdxs.push_back(u32(i)); + } + } if (useFaces == 1) { x6e8_aabb = zeus::CAABox(); @@ -194,9 +199,9 @@ static zeus::CVector3f ClipRayToPlane(const zeus::CVector3f& a, const zeus::CVec return (1.f - -plane.pointToPlaneDist(a) / (b - a).dot(plane.normal())) * (a - b) + b; } -bool CMetroidAreaCollider::ConvexPolyCollision(const zeus::CPlane* planes, const zeus::CVector3f* verts, - zeus::CAABox& aabb) { - rstl::reserved_vector vecs[2]; +bool CMetroidAreaCollider::ConvexPolyCollision(const std::array& planes, + const std::array& verts, zeus::CAABox& aabb) { + std::array, 2> vecs; g_CalledClip += 1; g_RejectedByClip -= 1; @@ -354,22 +359,24 @@ bool CMetroidAreaCollider::AABoxCollisionCheck_Cached(const COctreeLeafCache& le const CMaterialFilter& filter, const CMaterialList& matList, CCollisionInfoList& list) { bool ret = false; - zeus::CPlane planes[] = {{zeus::skRight, aabb.min.dot(zeus::skRight)}, - {zeus::skLeft, aabb.max.dot(zeus::skLeft)}, - {zeus::skForward, aabb.min.dot(zeus::skForward)}, - {zeus::skBack, aabb.max.dot(zeus::skBack)}, - {zeus::skUp, aabb.min.dot(zeus::skUp)}, - {zeus::skDown, aabb.max.dot(zeus::skDown)}}; + const std::array planes{{ + {zeus::skRight, aabb.min.dot(zeus::skRight)}, + {zeus::skLeft, aabb.max.dot(zeus::skLeft)}, + {zeus::skForward, aabb.min.dot(zeus::skForward)}, + {zeus::skBack, aabb.max.dot(zeus::skBack)}, + {zeus::skUp, aabb.min.dot(zeus::skUp)}, + {zeus::skDown, aabb.max.dot(zeus::skDown)}, + }}; CAABoxAreaCache cache(aabb, planes, filter, matList, list); ResetInternalCounters(); for (const CAreaOctTree::Node& node : leafCache.x4_nodeCache) { if (aabb.intersects(node.GetBoundingBox())) { - CAreaOctTree::TriListReference list = node.GetTriangleArray(); - for (int j = 0; j < list.GetSize(); ++j) { + CAreaOctTree::TriListReference listRef = node.GetTriangleArray(); + for (int j = 0; j < listRef.GetSize(); ++j) { ++g_TrianglesProcessed; - u16 triIdx = list.GetAt(j); + u16 triIdx = listRef.GetAt(j); if (g_DupPrimitiveCheckCount == g_DupTriangleList[triIdx]) { g_DupTrianglesProcessed += 1; } else { @@ -379,10 +386,10 @@ bool CMetroidAreaCollider::AABoxCollisionCheck_Cached(const COctreeLeafCache& le if (cache.x8_filter.Passes(material)) { if (CollisionUtil::TriBoxOverlap(cache.x14_center, cache.x20_halfExtent, surf.GetVert(0), surf.GetVert(1), surf.GetVert(2))) { - zeus::CAABox aabb = zeus::CAABox(); - if (ConvexPolyCollision(cache.x4_planes, surf.GetVerts(), aabb)) { + zeus::CAABox aabb2 = zeus::CAABox(); + if (ConvexPolyCollision(cache.x4_planes, surf.GetVerts(), aabb2)) { zeus::CPlane plane = surf.GetPlane(); - CCollisionInfo collision(aabb, cache.xc_material, material, plane.normal(), -plane.normal()); + CCollisionInfo collision(aabb2, cache.xc_material, material, plane.normal(), -plane.normal()); cache.x10_collisionList.Add(collision, false); ret = true; } @@ -448,17 +455,19 @@ bool CMetroidAreaCollider::AABoxCollisionCheck_Internal(const CAreaOctTree::Node bool CMetroidAreaCollider::AABoxCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb, const CMaterialFilter& filter, const CMaterialList& matList, CCollisionInfoList& list) { - zeus::CPlane planes[] = {{zeus::skRight, aabb.min.dot(zeus::skRight)}, - {zeus::skLeft, aabb.max.dot(zeus::skLeft)}, - {zeus::skForward, aabb.min.dot(zeus::skForward)}, - {zeus::skBack, aabb.max.dot(zeus::skBack)}, - {zeus::skUp, aabb.min.dot(zeus::skUp)}, - {zeus::skDown, aabb.max.dot(zeus::skDown)}}; - CAABoxAreaCache cache(aabb, planes, filter, matList, list); + const std::array planes{{ + {zeus::skRight, aabb.min.dot(zeus::skRight)}, + {zeus::skLeft, aabb.max.dot(zeus::skLeft)}, + {zeus::skForward, aabb.min.dot(zeus::skForward)}, + {zeus::skBack, aabb.max.dot(zeus::skBack)}, + {zeus::skUp, aabb.min.dot(zeus::skUp)}, + {zeus::skDown, aabb.max.dot(zeus::skDown)}, + }}; + const CAABoxAreaCache cache(aabb, planes, filter, matList, list); ResetInternalCounters(); - CAreaOctTree::Node node = octTree.GetRootNode(); + const CAreaOctTree::Node node = octTree.GetRootNode(); return AABoxCollisionCheck_Internal(node, cache); } @@ -674,8 +683,8 @@ bool CMetroidAreaCollider::MovingAABoxCollisionCheck_Cached(const COctreeLeafCac g_DupTriangleList[triIdx] = g_DupPrimitiveCheckCount; CMaterialList triMat(node.GetOwner().GetTriangleMaterial(triIdx)); if (filter.Passes(triMat)) { - u16 vertIndices[3]; - node.GetOwner().GetTriangleVertexIndices(triIdx, vertIndices); + std::array vertIndices; + node.GetOwner().GetTriangleVertexIndices(triIdx, vertIndices.data()); CCollisionSurface surf(node.GetOwner().GetVert(vertIndices[0]), node.GetOwner().GetVert(vertIndices[1]), node.GetOwner().GetVert(vertIndices[2]), triMat.GetValue()); @@ -690,8 +699,7 @@ bool CMetroidAreaCollider::MovingAABoxCollisionCheck_Cached(const COctreeLeafCac dOut = d; } - for (int k = 0; k < 3; ++k) { - u16 vertIdx = vertIndices[k]; + for (const u16 vertIdx : vertIndices) { zeus::CVector3f vtx = node.GetOwner().GetVert(vertIdx); if (g_DupPrimitiveCheckCount != g_DupVertexList[vertIdx]) { g_DupVertexList[vertIdx] = g_DupPrimitiveCheckCount; @@ -783,8 +791,8 @@ bool CMetroidAreaCollider::MovingSphereCollisionCheck_Cached(const COctreeLeafCa g_DupTriangleList[triIdx] = g_DupPrimitiveCheckCount; CMaterialList triMat(node.GetOwner().GetTriangleMaterial(triIdx)); if (filter.Passes(triMat)) { - u16 vertIndices[3]; - node.GetOwner().GetTriangleVertexIndices(triIdx, vertIndices); + std::array vertIndices; + node.GetOwner().GetTriangleVertexIndices(triIdx, vertIndices.data()); CCollisionSurface surf(node.GetOwner().GetVert(vertIndices[0]), node.GetOwner().GetVert(vertIndices[1]), node.GetOwner().GetVert(vertIndices[2]), triMat.GetValue()); @@ -796,11 +804,11 @@ bool CMetroidAreaCollider::MovingSphereCollisionCheck_Cached(const COctreeLeafCa float mag = (sphere.radius - (sphere.position - surf.GetVert(0)).dot(surfNormal)) / dir.dot(surfNormal); zeus::CVector3f intersectPoint = sphere.position + mag * dir; - bool outsideEdges[] = { + const std::array outsideEdges{ (intersectPoint - surf.GetVert(0)).dot(surfNormal.cross(surf.GetVert(1) - surf.GetVert(0))) < 0.f, (intersectPoint - surf.GetVert(1)).dot(surfNormal.cross(surf.GetVert(2) - surf.GetVert(1))) < 0.f, - (intersectPoint - surf.GetVert(2)).dot(surfNormal.cross(surf.GetVert(0) - surf.GetVert(2))) < - 0.f}; + (intersectPoint - surf.GetVert(2)).dot(surfNormal.cross(surf.GetVert(0) - surf.GetVert(2))) < 0.f, + }; if (mag >= 0.f && !outsideEdges[0] && !outsideEdges[1] && !outsideEdges[2] && mag < dOut) { infoOut = CCollisionInfo(intersectPoint - sphere.radius * surfNormal, matList, triMat, surfNormal); @@ -810,7 +818,7 @@ bool CMetroidAreaCollider::MovingSphereCollisionCheck_Cached(const COctreeLeafCa } bool intersects = (sphere.position - surf.GetVert(0)).dot(surfNormal) <= sphere.radius; - bool testVert[] = {true, true, true}; + std::array testVert{true, true, true}; const u16* edgeIndices = node.GetOwner().GetTriangleEdgeIndices(triIdx); for (int k = 0; k < 3; ++k) { if (intersects || outsideEdges[k]) { @@ -916,9 +924,9 @@ void CMetroidAreaCollider::ResetInternalCounters() { g_TrianglesProcessed = 0; g_DupTrianglesProcessed = 0; if (g_DupPrimitiveCheckCount == 0xffff) { - std::fill(std::begin(g_DupVertexList), std::end(g_DupVertexList), 0); - std::fill(std::begin(g_DupEdgeList), std::end(g_DupEdgeList), 0); - std::fill(std::begin(g_DupTriangleList), std::end(g_DupTriangleList), 0); + g_DupVertexList.fill(0); + g_DupEdgeList.fill(0); + g_DupTriangleList.fill(0); g_DupPrimitiveCheckCount += 1; } g_DupPrimitiveCheckCount += 1; diff --git a/Runtime/Collision/CMetroidAreaCollider.hpp b/Runtime/Collision/CMetroidAreaCollider.hpp index 621c02e1a..7f34f557c 100644 --- a/Runtime/Collision/CMetroidAreaCollider.hpp +++ b/Runtime/Collision/CMetroidAreaCollider.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "Runtime/RetroTypes.hpp" #include "Runtime/rstl.hpp" #include "Runtime/Collision/CAreaOctTree.hpp" @@ -17,7 +19,7 @@ class CMaterialList; class CAABoxAreaCache { friend class CMetroidAreaCollider; const zeus::CAABox& x0_aabb; - const zeus::CPlane* x4_planes; + const std::array& x4_planes; const CMaterialFilter& x8_filter; const CMaterialList& xc_material; CCollisionInfoList& x10_collisionList; @@ -25,7 +27,7 @@ class CAABoxAreaCache { zeus::CVector3f x20_halfExtent; public: - CAABoxAreaCache(const zeus::CAABox& aabb, const zeus::CPlane* pl, const CMaterialFilter& filter, + CAABoxAreaCache(const zeus::CAABox& aabb, const std::array& pl, const CMaterialFilter& filter, const CMaterialList& material, CCollisionInfoList& collisionList); }; @@ -91,9 +93,9 @@ class CMetroidAreaCollider { static u32 g_TrianglesProcessed; static u32 g_DupTrianglesProcessed; static u16 g_DupPrimitiveCheckCount; - static u16 g_DupVertexList[0x5000]; - static u16 g_DupEdgeList[0xC000]; - static u16 g_DupTriangleList[0x4000]; + static std::array g_DupVertexList; + static std::array g_DupEdgeList; + static std::array g_DupTriangleList; static bool AABoxCollisionCheckBoolean_Internal(const CAreaOctTree::Node& node, const CBooleanAABoxAreaCache& cache); static bool AABoxCollisionCheck_Internal(const CAreaOctTree::Node& node, const CAABoxAreaCache& cache); @@ -121,7 +123,7 @@ public: bool x908_24_overflow : 1; public: - COctreeLeafCache(const CAreaOctTree& octTree); + explicit COctreeLeafCache(const CAreaOctTree& octTree); void AddLeaf(const CAreaOctTree::Node& node); u32 GetNumLeaves() const { return x4_nodeCache.size(); } bool HasCacheOverflowed() const { return x908_24_overflow; } @@ -131,7 +133,8 @@ public: }; static void BuildOctreeLeafCache(const CAreaOctTree::Node& root, const zeus::CAABox& aabb, CMetroidAreaCollider::COctreeLeafCache& cache); - static bool ConvexPolyCollision(const zeus::CPlane* planes, const zeus::CVector3f* verts, zeus::CAABox& aabb); + static bool ConvexPolyCollision(const std::array& planes, + const std::array& verts, zeus::CAABox& aabb); static bool AABoxCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb, const CMaterialFilter& filter); @@ -179,7 +182,7 @@ class CAreaCollisionCache { }; public: - CAreaCollisionCache(const zeus::CAABox& aabb) : x0_aabb(aabb) {} + explicit CAreaCollisionCache(const zeus::CAABox& aabb) : x0_aabb(aabb) {} void ClearCache(); const zeus::CAABox& GetCacheBounds() const { return x0_aabb; } void SetCacheBounds(const zeus::CAABox& aabb) { x0_aabb = aabb; } diff --git a/Runtime/Collision/COBBTree.cpp b/Runtime/Collision/COBBTree.cpp index d543e8300..2849ca96f 100644 --- a/Runtime/Collision/COBBTree.cpp +++ b/Runtime/Collision/COBBTree.cpp @@ -1,13 +1,52 @@ #include "Runtime/Collision/COBBTree.hpp" +#include + #include "Runtime/Collision/CCollidableOBBTreeGroup.hpp" namespace urde { +namespace { +constexpr std::array DefaultEdgeMaterials{ + 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 2, 2, +}; + +constexpr std::array DefaultSurfaceMaterials{ + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, +}; + +constexpr std::array DefaultEdges{{ + {4, 1}, + {1, 5}, + {5, 4}, + {4, 0}, + {0, 1}, + {7, 2}, + {2, 6}, + {6, 7}, + {7, 3}, + {3, 2}, + {6, 0}, + {4, 6}, + {2, 0}, + {5, 3}, + {7, 5}, + {1, 3}, + {6, 5}, + {0, 3}, +}}; + +constexpr std::array DefaultSurfaceIndices{ + 0, 1, 2, 0, 3, 4, 5, 6, 7, 5, 8, 9, 10, 3, 11, 10, 6, 12, + 13, 8, 14, 13, 1, 15, 16, 14, 7, 16, 11, 2, 17, 15, 4, 17, 12, 9, +}; + + /* This is exactly what retro did >.< */ u32 verify_deaf_babe(CInputStream& in) { return in.readUint32Big(); } /* This is exactly what retro did >.< */ u32 verify_version(CInputStream& in) { return in.readUint32Big(); } +} // Anonymous namespace COBBTree::COBBTree(CInputStream& in) : x0_magic(verify_deaf_babe(in)) @@ -16,24 +55,6 @@ COBBTree::COBBTree(CInputStream& in) , x18_indexData(in) , x88_root(std::make_unique(in)) {} -static const u8 DefaultEdgeMaterials[] = { - 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 2, 2 -}; - -static const u8 DefaultSurfaceMaterials[] = { - 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 -}; - -static const CCollisionEdge DefaultEdges[] = { - {4, 1}, {1, 5}, {5, 4}, {4, 0}, {0, 1}, {7, 2}, {2, 6}, {6, 7}, {7, 3}, - {3, 2}, {6, 0}, {4, 6}, {2, 0}, {5, 3}, {7, 5}, {1, 3}, {6, 5}, {0, 3} -}; - -static const u16 DefaultSurfaceIndices[] = { - 0, 1, 2, 0, 3, 4, 5, 6, 7, 5, 8, 9, 10, 3, 11, 10, 6, 12, 13, - 8, 14, 13, 1, 15, 16, 14, 7, 16, 11, 2, 17, 15, 4, 17, 12, 9 -}; - std::unique_ptr COBBTree::BuildOrientedBoundingBoxTree(const zeus::CVector3f& extent, const zeus::CVector3f& center) { zeus::CAABox aabb(extent * -0.5f + center, extent * 0.5f + center); @@ -44,34 +65,37 @@ std::unique_ptr COBBTree::BuildOrientedBoundingBoxTree(const zeus::CVe idxData.x0_materials.push_back(0x42180000); idxData.x0_materials.push_back(0x41180000); idxData.x10_vertMaterials = std::vector(8, u8(0)); - idxData.x20_edgeMaterials = std::vector(std::begin(DefaultEdgeMaterials), std::end(DefaultEdgeMaterials)); - idxData.x30_surfaceMaterials = std::vector(std::begin(DefaultSurfaceMaterials), std::end(DefaultSurfaceMaterials)); - idxData.x40_edges = std::vector(std::begin(DefaultEdges), std::end(DefaultEdges)); - idxData.x50_surfaceIndices = std::vector(std::begin(DefaultSurfaceIndices), std::end(DefaultSurfaceIndices)); + idxData.x20_edgeMaterials = std::vector(DefaultEdgeMaterials.cbegin(), DefaultEdgeMaterials.cend()); + idxData.x30_surfaceMaterials = std::vector(DefaultSurfaceMaterials.cbegin(), DefaultSurfaceMaterials.cend()); + idxData.x40_edges = std::vector(DefaultEdges.cbegin(), DefaultEdges.cend()); + idxData.x50_surfaceIndices = std::vector(DefaultSurfaceIndices.cbegin(), DefaultSurfaceIndices.cend()); idxData.x60_vertices.reserve(8); - for (int i = 0; i < 8; ++i) + for (int i = 0; i < 8; ++i) { idxData.x60_vertices.push_back(aabb.getPoint(i)); + } std::vector surface; surface.reserve(12); - for (int i = 0; i < 12; ++i) + for (int i = 0; i < 12; ++i) { surface.push_back(i); - ret->x88_root = std::make_unique(zeus::CTransform::Translate(center), extent * 0.5f, - std::unique_ptr{}, std::unique_ptr{}, std::make_unique(std::move(surface))); + } + ret->x88_root = std::make_unique(zeus::CTransform::Translate(center), extent * 0.5f, nullptr, nullptr, + std::make_unique(std::move(surface))); return ret; } CCollisionSurface COBBTree::GetSurface(u16 idx) const { - int surfIdx = idx * 3; - CCollisionEdge e0 = x18_indexData.x40_edges[x18_indexData.x50_surfaceIndices[surfIdx]]; - CCollisionEdge e1 = x18_indexData.x40_edges[x18_indexData.x50_surfaceIndices[surfIdx + 1]]; - u16 vert1 = e0.GetVertIndex1(); - u16 vert2 = e0.GetVertIndex2(); + const auto surfIdx = size_t{idx} * 3; + const CCollisionEdge e0 = x18_indexData.x40_edges[x18_indexData.x50_surfaceIndices[surfIdx]]; + const CCollisionEdge e1 = x18_indexData.x40_edges[x18_indexData.x50_surfaceIndices[surfIdx + 1]]; + const u16 vert1 = e0.GetVertIndex1(); + const u16 vert2 = e0.GetVertIndex2(); u16 vert3 = e1.GetVertIndex1(); - if (vert3 == vert1 || vert3 == vert2) + if (vert3 == vert1 || vert3 == vert2) { vert3 = e1.GetVertIndex2(); + } - u32 mat = x18_indexData.x0_materials[x18_indexData.x30_surfaceMaterials[idx]]; + const u32 mat = x18_indexData.x0_materials[x18_indexData.x30_surfaceMaterials[idx]]; if ((mat & 0x2000000) != 0) { return CCollisionSurface(x18_indexData.x60_vertices[vert2], x18_indexData.x60_vertices[vert1], @@ -81,35 +105,41 @@ CCollisionSurface COBBTree::GetSurface(u16 idx) const { x18_indexData.x60_vertices[vert3], mat); } -void COBBTree::GetTriangleVertexIndices(u16 idx, u16 indicesOut[3]) const { - const CCollisionEdge& e0 = x18_indexData.x40_edges[x18_indexData.x50_surfaceIndices[idx * 3]]; - const CCollisionEdge& e1 = x18_indexData.x40_edges[x18_indexData.x50_surfaceIndices[idx * 3 + 1]]; - indicesOut[2] = (e1.GetVertIndex1() != e0.GetVertIndex1() && e1.GetVertIndex1() != e0.GetVertIndex2()) - ? e1.GetVertIndex1() - : e1.GetVertIndex2(); +std::array COBBTree::GetTriangleVertexIndices(u16 idx) const { + const auto surfIdx = size_t{idx} * 3; + const CCollisionEdge& e0 = x18_indexData.x40_edges[x18_indexData.x50_surfaceIndices[surfIdx]]; + const CCollisionEdge& e1 = x18_indexData.x40_edges[x18_indexData.x50_surfaceIndices[surfIdx + 1]]; + std::array indices{}; - u32 material = x18_indexData.x0_materials[x18_indexData.x30_surfaceMaterials[idx]]; - if (material & 0x2000000) { - indicesOut[0] = e0.GetVertIndex2(); - indicesOut[1] = e0.GetVertIndex1(); + indices[2] = (e1.GetVertIndex1() != e0.GetVertIndex1() && e1.GetVertIndex1() != e0.GetVertIndex2()) + ? e1.GetVertIndex1() + : e1.GetVertIndex2(); + + const u32 material = x18_indexData.x0_materials[x18_indexData.x30_surfaceMaterials[idx]]; + if ((material & 0x2000000) != 0) { + indices[0] = e0.GetVertIndex2(); + indices[1] = e0.GetVertIndex1(); } else { - indicesOut[0] = e0.GetVertIndex1(); - indicesOut[1] = e0.GetVertIndex2(); + indices[0] = e0.GetVertIndex1(); + indices[1] = e0.GetVertIndex2(); } + + return indices; } CCollisionSurface COBBTree::GetTransformedSurface(u16 idx, const zeus::CTransform& xf) const { - int surfIdx = idx * 3; - CCollisionEdge e0 = x18_indexData.x40_edges[x18_indexData.x50_surfaceIndices[surfIdx]]; - CCollisionEdge e1 = x18_indexData.x40_edges[x18_indexData.x50_surfaceIndices[surfIdx + 1]]; - u16 vert1 = e0.GetVertIndex1(); - u16 vert2 = e0.GetVertIndex2(); + const auto surfIdx = size_t{idx} * 3; + const CCollisionEdge e0 = x18_indexData.x40_edges[x18_indexData.x50_surfaceIndices[surfIdx]]; + const CCollisionEdge e1 = x18_indexData.x40_edges[x18_indexData.x50_surfaceIndices[surfIdx + 1]]; + const u16 vert1 = e0.GetVertIndex1(); + const u16 vert2 = e0.GetVertIndex2(); u16 vert3 = e1.GetVertIndex1(); - if (vert3 == vert1 || vert3 == vert2) + if (vert3 == vert1 || vert3 == vert2) { vert3 = e1.GetVertIndex2(); + } - u32 mat = x18_indexData.x0_materials[x18_indexData.x30_surfaceMaterials[idx]]; + const u32 mat = x18_indexData.x0_materials[x18_indexData.x30_surfaceMaterials[idx]]; if ((mat & 0x2000000) != 0) { return CCollisionSurface(xf * x18_indexData.x60_vertices[vert2], xf * x18_indexData.x60_vertices[vert1], @@ -122,45 +152,53 @@ CCollisionSurface COBBTree::GetTransformedSurface(u16 idx, const zeus::CTransfor zeus::CAABox COBBTree::CalculateLocalAABox() const { return CalculateAABox(zeus::CTransform()); } zeus::CAABox COBBTree::CalculateAABox(const zeus::CTransform& xf) const { - if (x88_root) + if (x88_root) { return x88_root->GetOBB().calculateAABox(xf); + } return zeus::CAABox(); } COBBTree::SIndexData::SIndexData(CInputStream& in) { u32 count = in.readUint32Big(); x0_materials.reserve(count); - for (u32 i = 0; i < count; i++) - x0_materials.push_back(in.readUint32Big()); + for (u32 i = 0; i < count; i++) { + x0_materials.emplace_back(in.readUint32Big()); + } count = in.readUint32Big(); - for (u32 i = 0; i < count; i++) - x10_vertMaterials.push_back(in.readUByte()); + for (u32 i = 0; i < count; i++) { + x10_vertMaterials.emplace_back(in.readUByte()); + } count = in.readUint32Big(); - for (u32 i = 0; i < count; i++) - x20_edgeMaterials.push_back(in.readUByte()); + for (u32 i = 0; i < count; i++) { + x20_edgeMaterials.emplace_back(in.readUByte()); + } count = in.readUint32Big(); - for (u32 i = 0; i < count; i++) - x30_surfaceMaterials.push_back(in.readUByte()); + for (u32 i = 0; i < count; i++) { + x30_surfaceMaterials.emplace_back(in.readUByte()); + } count = in.readUint32Big(); - for (u32 i = 0; i < count; i++) - x40_edges.push_back(in); + for (u32 i = 0; i < count; i++) { + x40_edges.emplace_back(in); + } count = in.readUint32Big(); - for (u32 i = 0; i < count; i++) - x50_surfaceIndices.push_back(in.readUint16Big()); + for (u32 i = 0; i < count; i++) { + x50_surfaceIndices.emplace_back(in.readUint16Big()); + } count = in.readUint32Big(); - for (u32 i = 0; i < count; i++) - x60_vertices.push_back(zeus::CVector3f::ReadBig(in)); + for (u32 i = 0; i < count; i++) { + x60_vertices.emplace_back(zeus::CVector3f::ReadBig(in)); + } } COBBTree::CNode::CNode(const zeus::CTransform& xf, const zeus::CVector3f& point, std::unique_ptr&& left, std::unique_ptr&& right, std::unique_ptr&& leaf) : x0_obb(xf, point) -, x3c_isLeaf(leaf.operator bool()) +, x3c_isLeaf(leaf != nullptr) , x40_left(std::move(left)) , x44_right(std::move(right)) , x48_leaf(std::move(leaf)) {} @@ -195,14 +233,15 @@ COBBTree::CLeafData::CLeafData(std::vector&& surface) : x0_surface(std::mov const std::vector& COBBTree::CLeafData::GetSurfaceVector() const { return x0_surface; } size_t COBBTree::CLeafData::GetMemoryUsage() const { - size_t ret = (x0_surface.size() * 2) + /*sizeof(CLeafData)*/ 16; + const size_t ret = (x0_surface.size() * 2) + /*sizeof(CLeafData)*/ 16; return (ret + 3) & ~3; } COBBTree::CLeafData::CLeafData(CInputStream& in) { - u32 edgeCount = in.readUint32Big(); - for (u32 i = 0; i < edgeCount; i++) - x0_surface.push_back(in.readUint16Big()); + const u32 edgeCount = in.readUint32Big(); + for (u32 i = 0; i < edgeCount; i++) { + x0_surface.emplace_back(in.readUint16Big()); + } } } // namespace urde diff --git a/Runtime/Collision/COBBTree.hpp b/Runtime/Collision/COBBTree.hpp index 480bcf790..58ef0ec4d 100644 --- a/Runtime/Collision/COBBTree.hpp +++ b/Runtime/Collision/COBBTree.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -24,7 +25,7 @@ public: std::vector x50_surfaceIndices; std::vector x60_vertices; SIndexData() = default; - SIndexData(CInputStream&); + explicit SIndexData(CInputStream&); }; class CLeafData { @@ -32,8 +33,8 @@ public: public: CLeafData() = default; - CLeafData(std::vector&& surface); - CLeafData(CInputStream&); + explicit CLeafData(std::vector&& surface); + explicit CLeafData(CInputStream&); const std::vector& GetSurfaceVector() const; size_t GetMemoryUsage() const; @@ -45,13 +46,13 @@ public: std::unique_ptr x40_left; std::unique_ptr x44_right; std::unique_ptr x48_leaf; - bool x4c_hit; + bool x4c_hit = false; public: CNode() = default; CNode(const zeus::CTransform&, const zeus::CVector3f&, std::unique_ptr&&, std::unique_ptr&&, std::unique_ptr&&); - CNode(CInputStream&); + explicit CNode(CInputStream&); bool WasHit() const { return x4c_hit; } void SetHit(bool h) { x4c_hit = h; } @@ -73,13 +74,16 @@ private: public: COBBTree() = default; - COBBTree(CInputStream&); + explicit COBBTree(CInputStream&); static std::unique_ptr BuildOrientedBoundingBoxTree(const zeus::CVector3f&, const zeus::CVector3f&); CCollisionSurface GetSurface(u16 idx) const; const u16* GetTriangleEdgeIndices(u16 idx) const { return &x18_indexData.x50_surfaceIndices[idx * 3]; } - void GetTriangleVertexIndices(u16 idx, u16 indicesOut[3]) const; + + // In the game binary, this used to use an out pointer for the indices after the index. + std::array GetTriangleVertexIndices(u16 idx) const; + const CCollisionEdge& GetEdge(int idx) const { return x18_indexData.x40_edges[idx]; } const zeus::CVector3f& GetVert(int idx) const { return x18_indexData.x60_vertices[idx]; } u32 GetVertMaterial(u16 idx) const { return x18_indexData.x0_materials[x18_indexData.x10_vertMaterials[idx]]; } diff --git a/Runtime/Collision/CollisionUtil.cpp b/Runtime/Collision/CollisionUtil.cpp index ee576456f..9ff424cb7 100644 --- a/Runtime/Collision/CollisionUtil.cpp +++ b/Runtime/Collision/CollisionUtil.cpp @@ -1,6 +1,7 @@ #include "Runtime/Collision/CollisionUtil.hpp" #include +#include #include #include "Runtime/Collision/CCollisionInfo.hpp" @@ -18,27 +19,32 @@ u32 RayAABoxIntersection(const zeus::CMRay& ray, const zeus::CAABox& aabb, float tMin = -999999.f; tMax = 999999.f; - for (int i = 0; i < 3; ++i) { + for (size_t i = 0; i < 3; ++i) { if (std::fabs(ray.dir[i]) < 0.00001f) { - if (ray.start[i] < aabb.min[i] || ray.start[i] > aabb.max[i]) + if (ray.start[i] < aabb.min[i] || ray.start[i] > aabb.max[i]) { return 0; + } } else { if (ray.dir[i] < 0.f) { - float startToMax = aabb.max[i] - ray.start[i]; - float startToMin = aabb.min[i] - ray.start[i]; - float dirRecip = 1.f / ray.dir[i]; - if (startToMax < tMin * ray.dir[i]) + const float startToMax = aabb.max[i] - ray.start[i]; + const float startToMin = aabb.min[i] - ray.start[i]; + const float dirRecip = 1.f / ray.dir[i]; + if (startToMax < tMin * ray.dir[i]) { tMin = startToMax * dirRecip; - if (startToMin > tMax * ray.dir[i]) + } + if (startToMin > tMax * ray.dir[i]) { tMax = startToMin * dirRecip; + } } else { - float startToMin = aabb.min[i] - ray.start[i]; - float startToMax = aabb.max[i] - ray.start[i]; - float dirRecip = 1.f / ray.dir[i]; - if (startToMin > tMin * ray.dir[i]) + const float startToMin = aabb.min[i] - ray.start[i]; + const float startToMax = aabb.max[i] - ray.start[i]; + const float dirRecip = 1.f / ray.dir[i]; + if (startToMin > tMin * ray.dir[i]) { tMin = startToMin * dirRecip; - if (startToMax < tMax * ray.dir[i]) + } + if (startToMax < tMax * ray.dir[i]) { tMax = startToMax * dirRecip; + } } } } @@ -47,7 +53,7 @@ u32 RayAABoxIntersection(const zeus::CMRay& ray, const zeus::CAABox& aabb, float } u32 RayAABoxIntersection(const zeus::CMRay& ray, const zeus::CAABox& aabb, zeus::CVector3f& norm, float& d) { - int sign[] = {2, 2, 2}; + std::array sign{2, 2, 2}; bool bad = true; zeus::CVector3f rayStart = ray.start; zeus::CVector3f rayDelta = ray.delta; @@ -58,7 +64,7 @@ u32 RayAABoxIntersection(const zeus::CMRay& ray, const zeus::CAABox& aabb, zeus: zeus::CVector3f vec1; if (rayDelta.x() != 0.f && rayDelta.y() != 0.f && rayDelta.z() != 0.f) { - for (int i = 0; i < 3; ++i) { + for (size_t i = 0; i < sign.size(); ++i) { if (rayStart[i] < aabbMin[i]) { sign[i] = 1; bad = false; @@ -76,7 +82,7 @@ u32 RayAABoxIntersection(const zeus::CMRay& ray, const zeus::CAABox& aabb, zeus: } } else { zeus::CVector3f end; - for (int i = 0; i < 3; ++i) { + for (size_t i = 0; i < sign.size(); ++i) { if (rayStart[i] < aabbMin[i]) { sign[i] = 1; bad = false; @@ -93,13 +99,15 @@ u32 RayAABoxIntersection(const zeus::CMRay& ray, const zeus::CAABox& aabb, zeus: return 1; } - for (int i = 0; i < 3; ++i) - if (sign[i] != 2 && rayDelta[i] != 0.f) + for (size_t i = 0; i < sign.size(); ++i) { + if (sign[i] != 2 && rayDelta[i] != 0.f) { vec0[i] = (end[i] - rayStart[i]) / rayDelta[i]; + } + } } float maxComp = vec0.x(); - int maxCompIdx = 0; + size_t maxCompIdx = 0; if (maxComp < vec0.y()) { maxComp = vec0.y(); maxCompIdx = 1; @@ -112,11 +120,12 @@ u32 RayAABoxIntersection(const zeus::CMRay& ray, const zeus::CAABox& aabb, zeus: if (maxComp < 0.f || maxComp > 1.f) return 0; - for (int i = 0; i < 3; ++i) { + for (size_t i = 0; i < 3; ++i) { if (maxCompIdx != i) { vec1[i] = maxComp * rayDelta[i] + rayStart[i]; - if (vec1[i] > aabbMax[i]) + if (vec1[i] > aabbMax[i]) { return 0; + } } } @@ -127,7 +136,7 @@ u32 RayAABoxIntersection(const zeus::CMRay& ray, const zeus::CAABox& aabb, zeus: } u32 RayAABoxIntersection_Double(const zeus::CMRay& ray, const zeus::CAABox& aabb, zeus::CVector3f& norm, double& d) { - int sign[] = {2, 2, 2}; + std::array sign{2, 2, 2}; bool bad = true; zeus::CVector3d rayStart = ray.start; zeus::CVector3d rayDelta = ray.delta; @@ -138,7 +147,7 @@ u32 RayAABoxIntersection_Double(const zeus::CMRay& ray, const zeus::CAABox& aabb zeus::CVector3d vec1; if (rayDelta.x() != 0.0 && rayDelta.y() != 0.0 && rayDelta.z() != 0.0) { - for (int i = 0; i < 3; ++i) { + for (size_t i = 0; i < sign.size(); ++i) { if (rayStart[i] < aabbMin[i]) { sign[i] = 1; bad = false; @@ -156,7 +165,7 @@ u32 RayAABoxIntersection_Double(const zeus::CMRay& ray, const zeus::CAABox& aabb } } else { zeus::CVector3d end; - for (int i = 0; i < 3; ++i) { + for (size_t i = 0; i < sign.size(); ++i) { if (rayStart[i] < aabbMin[i]) { sign[i] = 1; bad = false; @@ -173,13 +182,15 @@ u32 RayAABoxIntersection_Double(const zeus::CMRay& ray, const zeus::CAABox& aabb return 1; } - for (int i = 0; i < 3; ++i) - if (sign[i] != 2 && rayDelta[i] != 0.0) + for (size_t i = 0; i < sign.size(); ++i) { + if (sign[i] != 2 && rayDelta[i] != 0.0) { vec0[i] = (end[i] - rayStart[i]) / rayDelta[i]; + } + } } double maxComp = vec0.x(); - int maxCompIdx = 0; + size_t maxCompIdx = 0; if (maxComp < vec0.y()) { maxComp = vec0.y(); maxCompIdx = 1; @@ -192,11 +203,12 @@ u32 RayAABoxIntersection_Double(const zeus::CMRay& ray, const zeus::CAABox& aabb if (maxComp < 0.0 || maxComp > 1.0) return 0; - for (int i = 0; i < 3; ++i) { + for (size_t i = 0; i < 3; ++i) { if (maxCompIdx != i) { vec1[i] = maxComp * rayDelta[i] + rayStart[i]; - if (vec1[i] > aabbMax[i]) + if (vec1[i] > aabbMax[i]) { return 0; + } } } @@ -208,92 +220,117 @@ u32 RayAABoxIntersection_Double(const zeus::CMRay& ray, const zeus::CAABox& aabb bool RaySphereIntersection_Double(const zeus::CSphere& sphere, const zeus::CVector3f& pos, const zeus::CVector3f& dir, double& T) { - zeus::CVector3d sPosD = sphere.position; - zeus::CVector3d posD = pos; - zeus::CVector3d sphereToPos = posD - sPosD; - double f30 = sphereToPos.dot(zeus::CVector3d(dir)) * 2.0; - double f1 = f30 * f30 - 4.0 * (sphereToPos.magSquared() - sphere.radius * sphere.radius); + const zeus::CVector3d sPosD = sphere.position; + const zeus::CVector3d posD = pos; + const zeus::CVector3d sphereToPos = posD - sPosD; + const double f30 = sphereToPos.dot(zeus::CVector3d(dir)) * 2.0; + const double f1 = f30 * f30 - 4.0 * (sphereToPos.magSquared() - sphere.radius * sphere.radius); + if (f1 >= 0.0) { - double intersectT = 0.5 * (-f30 - std::sqrt(f1)); + const double intersectT = 0.5 * (-f30 - std::sqrt(f1)); if (T == 0 || intersectT < T) { T = intersectT; return true; } } + return false; } bool RaySphereIntersection(const zeus::CSphere& sphere, const zeus::CVector3f& pos, const zeus::CVector3f& dir, float mag, float& T, zeus::CVector3f& point) { - zeus::CVector3f rayToSphere = sphere.position - pos; - float magSq = rayToSphere.magSquared(); - float dirDot = rayToSphere.dot(dir); - float radSq = sphere.radius * sphere.radius; - if (dirDot < 0.f && magSq > radSq) + const zeus::CVector3f rayToSphere = sphere.position - pos; + const float magSq = rayToSphere.magSquared(); + const float dirDot = rayToSphere.dot(dir); + const float radSq = sphere.radius * sphere.radius; + + if (dirDot < 0.f && magSq > radSq) { return false; - float intersectSq = radSq - (magSq - dirDot * dirDot); - if (intersectSq < 0.f) + } + + const float intersectSq = radSq - (magSq - dirDot * dirDot); + if (intersectSq < 0.f) { return false; + } + T = magSq > radSq ? dirDot - std::sqrt(intersectSq) : dirDot + std::sqrt(intersectSq); if (T < mag || mag == 0.f) { point = pos + T * dir; return true; } + return false; } bool RayTriangleIntersection_Double(const zeus::CVector3f& point, const zeus::CVector3f& dir, - const zeus::CVector3f* verts, double& d) { - zeus::CVector3d v0tov1 = verts[1] - verts[0]; - zeus::CVector3d v0tov2 = verts[2] - verts[0]; - zeus::CVector3d cross0 = zeus::CVector3d(dir).cross(v0tov2); - double dot0 = v0tov1.dot(cross0); - if (dot0 < DBL_EPSILON) + const std::array& verts, double& d) { + const zeus::CVector3d v0tov1 = verts[1] - verts[0]; + const zeus::CVector3d v0tov2 = verts[2] - verts[0]; + const zeus::CVector3d cross0 = zeus::CVector3d(dir).cross(v0tov2); + const double dot0 = v0tov1.dot(cross0); + if (dot0 < DBL_EPSILON) { return false; - zeus::CVector3d v0toPoint = point - verts[0]; - double dot1 = v0toPoint.dot(cross0); - if (dot1 < 0.0 || dot1 > dot0) + } + + const zeus::CVector3d v0toPoint = point - verts[0]; + const double dot1 = v0toPoint.dot(cross0); + if (dot1 < 0.0 || dot1 > dot0) { return false; - zeus::CVector3d cross1 = v0toPoint.cross(v0tov1); - double dot2 = cross1.dot(dir); - if (dot2 < 0.0 || dot1 + dot2 > dot0) + } + + const zeus::CVector3d cross1 = v0toPoint.cross(v0tov1); + const double dot2 = cross1.dot(dir); + if (dot2 < 0.0 || dot1 + dot2 > dot0) { return false; - double final = 1.0 / dot0 * cross1.dot(v0tov2); - if (final < 0.0 || final >= d) + } + + const double final = 1.0 / dot0 * cross1.dot(v0tov2); + if (final < 0.0 || final >= d) { return false; + } + d = final; return true; } -bool RayTriangleIntersection(const zeus::CVector3f& point, const zeus::CVector3f& dir, const zeus::CVector3f* verts, - float& d) { - zeus::CVector3f v0tov1 = verts[1] - verts[0]; - zeus::CVector3f v0tov2 = verts[2] - verts[0]; - zeus::CVector3f cross0 = dir.cross(v0tov2); - float dot0 = v0tov1.dot(cross0); - if (dot0 < DBL_EPSILON) +bool RayTriangleIntersection(const zeus::CVector3f& point, const zeus::CVector3f& dir, + const std::array& verts, float& d) { + const zeus::CVector3f v0tov1 = verts[1] - verts[0]; + const zeus::CVector3f v0tov2 = verts[2] - verts[0]; + const zeus::CVector3f cross0 = dir.cross(v0tov2); + const float dot0 = v0tov1.dot(cross0); + if (dot0 < DBL_EPSILON) { return false; - zeus::CVector3f v0toPoint = point - verts[0]; - float dot1 = v0toPoint.dot(cross0); - if (dot1 < 0.f || dot1 > dot0) + } + + const zeus::CVector3f v0toPoint = point - verts[0]; + const float dot1 = v0toPoint.dot(cross0); + if (dot1 < 0.f || dot1 > dot0) { return false; - zeus::CVector3f cross1 = v0toPoint.cross(v0tov1); - float dot2 = cross1.dot(dir); - if (dot2 < 0.f || dot1 + dot2 > dot0) + } + + const zeus::CVector3f cross1 = v0toPoint.cross(v0tov1); + const float dot2 = cross1.dot(dir); + if (dot2 < 0.f || dot1 + dot2 > dot0) { return false; - float final = 1.f / dot0 * cross1.dot(v0tov2); - if (final < 0.f || final >= d) + } + + const float final = 1.f / dot0 * cross1.dot(v0tov2); + if (final < 0.f || final >= d) { return false; + } + d = final; return true; } void FilterOutBackfaces(const zeus::CVector3f& vec, const CCollisionInfoList& in, CCollisionInfoList& out) { if (vec.canBeNormalized()) { - zeus::CVector3f norm = vec.normalized(); + const zeus::CVector3f norm = vec.normalized(); for (const CCollisionInfo& info : in) { - if (info.GetNormalLeft().dot(norm) < 0.001f) + if (info.GetNormalLeft().dot(norm) < 0.001f) { out.Add(info, false); + } } } else { out = in; @@ -305,7 +342,7 @@ void FilterByClosestNormal(const zeus::CVector3f& norm, const CCollisionInfoList int idx = -1; int i = 0; for (const CCollisionInfo& info : in) { - float dot = info.GetNormalLeft().dot(norm); + const float dot = info.GetNormalLeft().dot(norm); if (dot > maxDot) { maxDot = dot; idx = i; @@ -313,26 +350,34 @@ void FilterByClosestNormal(const zeus::CVector3f& norm, const CCollisionInfoList ++i; } - if (idx != -1) + if (idx != -1) { out.Add(in.GetItem(idx), false); + } } -static const zeus::CVector3f AABBNormalTable[] = {{-1.f, 0.f, 0.f}, {1.f, 0.f, 0.f}, {0.f, -1.f, 0.f}, - {0.f, 1.f, 0.f}, {0.f, 0.f, -1.f}, {0.f, 0.f, 1.f}}; +constexpr std::array AABBNormalTable{{ + {-1.f, 0.f, 0.f}, + {1.f, 0.f, 0.f}, + {0.f, -1.f, 0.f}, + {0.f, 1.f, 0.f}, + {0.f, 0.f, -1.f}, + {0.f, 0.f, 1.f}, +}}; bool AABoxAABoxIntersection(const zeus::CAABox& aabb0, const CMaterialList& list0, const zeus::CAABox& aabb1, const CMaterialList& list1, CCollisionInfoList& infoList) { - zeus::CVector3f maxOfMin(std::max(aabb0.min.x(), aabb1.min.x()), std::max(aabb0.min.y(), aabb1.min.y()), - std::max(aabb0.min.z(), aabb1.min.z())); - zeus::CVector3f minOfMax(std::min(aabb0.max.x(), aabb1.max.x()), std::min(aabb0.max.y(), aabb1.max.y()), - std::min(aabb0.max.z(), aabb1.max.z())); + const zeus::CVector3f maxOfMin(std::max(aabb0.min.x(), aabb1.min.x()), std::max(aabb0.min.y(), aabb1.min.y()), + std::max(aabb0.min.z(), aabb1.min.z())); + const zeus::CVector3f minOfMax(std::min(aabb0.max.x(), aabb1.max.x()), std::min(aabb0.max.y(), aabb1.max.y()), + std::min(aabb0.max.z(), aabb1.max.z())); - if (maxOfMin.x() >= minOfMax.x() || maxOfMin.y() >= minOfMax.y() || maxOfMin.z() >= minOfMax.z()) + if (maxOfMin.x() >= minOfMax.x() || maxOfMin.y() >= minOfMax.y() || maxOfMin.z() >= minOfMax.z()) { return false; + } - zeus::CAABox boolAABB(maxOfMin, minOfMax); + const zeus::CAABox boolAABB(maxOfMin, minOfMax); - int ineqFlags[] = { + const std::array ineqFlags{ (aabb0.min.x() <= aabb1.min.x() ? 1 << 0 : 0) | (aabb0.min.x() <= aabb1.max.x() ? 1 << 1 : 0) | (aabb0.max.x() <= aabb1.min.x() ? 1 << 2 : 0) | (aabb0.max.x() <= aabb1.max.x() ? 1 << 3 : 0), (aabb0.min.y() <= aabb1.min.y() ? 1 << 0 : 0) | (aabb0.min.y() <= aabb1.max.y() ? 1 << 1 : 0) | @@ -341,17 +386,17 @@ bool AABoxAABoxIntersection(const zeus::CAABox& aabb0, const CMaterialList& list (aabb0.max.z() <= aabb1.min.z() ? 1 << 2 : 0) | (aabb0.max.z() <= aabb1.max.z() ? 1 << 3 : 0), }; - for (int i = 0; i < 3; ++i) { + for (size_t i = 0; i < ineqFlags.size(); ++i) { switch (ineqFlags[i]) { case 0x2: // aabb0.min <= aabb1.max { - CCollisionInfo info(boolAABB, list0, list1, AABBNormalTable[i * 2 + 1], -AABBNormalTable[i * 2 + 1]); + const CCollisionInfo info(boolAABB, list0, list1, AABBNormalTable[i * 2 + 1], -AABBNormalTable[i * 2 + 1]); infoList.Add(info, false); break; } case 0xB: // aabb0.min <= aabb1.min && aabb0.max <= aabb1.min && aabb0.max <= aabb1.max { - CCollisionInfo info(boolAABB, list0, list1, AABBNormalTable[i * 2], -AABBNormalTable[i * 2]); + const CCollisionInfo info(boolAABB, list0, list1, AABBNormalTable[i * 2], -AABBNormalTable[i * 2]); infoList.Add(info, false); break; } @@ -360,16 +405,17 @@ bool AABoxAABoxIntersection(const zeus::CAABox& aabb0, const CMaterialList& list } } - if (infoList.GetCount()) + if (infoList.GetCount() != 0) { return true; + } { - CCollisionInfo info(boolAABB, list0, list1, AABBNormalTable[4], -AABBNormalTable[4]); + const CCollisionInfo info(boolAABB, list0, list1, AABBNormalTable[4], -AABBNormalTable[4]); infoList.Add(info, false); } { - CCollisionInfo info(boolAABB, list0, list1, AABBNormalTable[5], -AABBNormalTable[5]); + const CCollisionInfo info(boolAABB, list0, list1, AABBNormalTable[5], -AABBNormalTable[5]); infoList.Add(info, false); } @@ -394,7 +440,9 @@ bool AABoxAABoxIntersection(const zeus::CAABox& aabb0, const zeus::CAABox& aabb1 /********************************************************/ static bool planeBoxOverlap(const zeus::CVector3f& normal, float d, const zeus::CVector3f& maxbox) { - zeus::CVector3f vmin, vmax; + zeus::CVector3f vmin; + zeus::CVector3f vmax; + for (int q = 0; q <= 2; q++) { if (normal[q] > 0.0f) { vmin[q] = -maxbox[q]; @@ -404,10 +452,14 @@ static bool planeBoxOverlap(const zeus::CVector3f& normal, float d, const zeus:: vmax[q] = -maxbox[q]; } } - if (normal.dot(vmin) + d > 0.0f) + + if (normal.dot(vmin) + d > 0.0f) { return false; - if (normal.dot(vmax) + d >= 0.0f) + } + + if (normal.dot(vmax) + d >= 0.0f) { return true; + } return false; } @@ -510,20 +562,18 @@ bool TriBoxOverlap(const zeus::CVector3f& boxcenter, const zeus::CVector3f& boxh /* 2) normal of the triangle */ /* 3) crossproduct(edge from tri, {x,y,z}-directin) */ /* this gives 3x3=9 more tests */ - zeus::CVector3f v0, v1, v2; float min, max, d, p0, p1, p2, rad, fex, fey, fez; - zeus::CVector3f normal, e0, e1, e2; /* This is the fastest branch on Sun */ /* move everything so that the boxcenter is in (0,0,0) */ - v0 = trivert0 - boxcenter; - v1 = trivert1 - boxcenter; - v2 = trivert2 - boxcenter; + const zeus::CVector3f v0 = trivert0 - boxcenter; + const zeus::CVector3f v1 = trivert1 - boxcenter; + const zeus::CVector3f v2 = trivert2 - boxcenter; /* compute triangle edges */ - e0 = v1 - v0; /* tri edge 0 */ - e1 = v2 - v1; /* tri edge 1 */ - e2 = v0 - v2; /* tri edge 2 */ + const zeus::CVector3f e0 = v1 - v0; // Tri edge 0 + const zeus::CVector3f e1 = v2 - v1; // Tri edge 1 + const zeus::CVector3f e2 = v0 - v2; // Tri edge 2 /* Bullet 3: */ /* test the 9 tests first (this was faster) */ @@ -556,44 +606,48 @@ bool TriBoxOverlap(const zeus::CVector3f& boxcenter, const zeus::CVector3f& boxh /* test in X-direction */ std::tie(min, max) = std::minmax({v0.x(), v1.x(), v2.x()}); - if (min > boxhalfsize.x() || max < -boxhalfsize.x()) + if (min > boxhalfsize.x() || max < -boxhalfsize.x()) { return false; + } /* test in Y-direction */ std::tie(min, max) = std::minmax({v0.y(), v1.y(), v2.y()}); - if (min > boxhalfsize.y() || max < -boxhalfsize.y()) + if (min > boxhalfsize.y() || max < -boxhalfsize.y()) { return false; + } /* test in Z-direction */ std::tie(min, max) = std::minmax({v0.z(), v1.z(), v2.z()}); - if (min > boxhalfsize.z() || max < -boxhalfsize.z()) + if (min > boxhalfsize.z() || max < -boxhalfsize.z()) { return false; + } /* Bullet 2: */ /* test if the box intersects the plane of the triangle */ /* compute plane equation of triangle: normal*x+d=0 */ - normal = e0.cross(e1); + const zeus::CVector3f normal = e0.cross(e1); d = -normal.dot(v0); /* plane eq: normal.x+d=0 */ - if (!planeBoxOverlap(normal, d, boxhalfsize)) + if (!planeBoxOverlap(normal, d, boxhalfsize)) { return false; + } return true; /* box and triangle overlaps */ } double TriPointSqrDist(const zeus::CVector3f& point, const zeus::CVector3f& trivert0, const zeus::CVector3f& trivert1, const zeus::CVector3f& trivert2, float* baryX, float* baryY) { - zeus::CVector3d A = trivert0 - point; - zeus::CVector3d B = trivert1 - trivert0; - zeus::CVector3d C = trivert2 - trivert0; + const zeus::CVector3d A = trivert0 - point; + const zeus::CVector3d B = trivert1 - trivert0; + const zeus::CVector3d C = trivert2 - trivert0; - double bMag = B.magSquared(); - double cMag = C.magSquared(); - double bDotC = B.dot(C); - double aDotB = A.dot(B); - double aDotC = A.dot(C); + const double bMag = B.magSquared(); + const double cMag = C.magSquared(); + const double bDotC = B.dot(C); + const double aDotB = A.dot(B); + const double aDotC = A.dot(C); double ret = A.magSquared(); - double rej = std::fabs(bMag * cMag - bDotC * bDotC); + const double rej = std::fabs(bMag * cMag - bDotC * bDotC); double retB = bDotC * aDotC - cMag * aDotB; double retA = bDotC * aDotB - bMag * aDotC; @@ -645,7 +699,7 @@ double TriPointSqrDist(const zeus::CVector3f& point, const zeus::CVector3f& triv ret += aDotB * retB; } } else { - float f3 = 1.0 / rej; + const float f3 = 1.0 / rej; retA *= f3; retB *= f3; ret += retB * (2.0 * aDotB + (bMag * retB + bDotC * retA)) + retA * (2.0 * aDotC + (bDotC * retB + cMag * retA)); @@ -734,10 +788,12 @@ double TriPointSqrDist(const zeus::CVector3f& point, const zeus::CVector3f& triv } } - if (baryX) - *baryX = retA; - if (baryY) - *baryY = retB; + if (baryX != nullptr) { + *baryX = float(retA); + } + if (baryY != nullptr) { + *baryY = float(retB); + } return ret; } @@ -751,17 +807,20 @@ bool TriSphereOverlap(const zeus::CSphere& sphere, const zeus::CVector3f& triver bool TriSphereIntersection(const zeus::CSphere& sphere, const zeus::CVector3f& trivert0, const zeus::CVector3f& trivert1, const zeus::CVector3f& trivert2, zeus::CVector3f& point, zeus::CVector3f& normal) { - float baryX, baryY; - if (TriPointSqrDist(sphere.position, trivert0, trivert1, trivert2, &baryX, &baryY) > sphere.radius * sphere.radius) + float baryX; + float baryY; + if (TriPointSqrDist(sphere.position, trivert0, trivert1, trivert2, &baryX, &baryY) > sphere.radius * sphere.radius) { return false; + } - zeus::CVector3f barys(baryX, baryY, 1.f - (baryX + baryY)); + const zeus::CVector3f barys(baryX, baryY, 1.f - (baryX + baryY)); point = zeus::baryToWorld(trivert2, trivert1, trivert0, barys); - if (baryX == 0.f || baryX == 1.f || baryY == 0.f || baryY == 1.f || barys.z() == 0.f || barys.z() == 1.f) + if (baryX == 0.f || baryX == 1.f || baryY == 0.f || baryY == 1.f || barys.z() == 0.f || barys.z() == 1.f) { normal = -sphere.getSurfaceNormal(point); - else + } else { normal = (trivert1 - trivert0).cross(trivert2 - trivert0).normalized(); + } return true; } @@ -771,13 +830,16 @@ bool BoxLineTest(const zeus::CAABox& aabb, const zeus::CVector3f& point, const z tMin = -999999.f; tMax = 999999.f; - for (int i = 0; i < 3; ++i) { - if (dir[i] == 0.f) - if (point[i] < aabb.min[i] || point[i] > aabb.max[i]) + for (size_t i = 0; i < 3; ++i) { + if (dir[i] == 0.f) { + if (point[i] < aabb.min[i] || point[i] > aabb.max[i]) { return false; + } + } - float dirRecip = 1.f / dir[i]; - float tmpMin, tmpMax; + const float dirRecip = 1.f / dir[i]; + float tmpMin; + float tmpMax; if (dir[i] < 0.f) { tmpMin = (aabb.max[i] - point[i]) * dirRecip; tmpMax = (aabb.min[i] - point[i]) * dirRecip; @@ -792,8 +854,9 @@ bool BoxLineTest(const zeus::CAABox& aabb, const zeus::CVector3f& point, const z tMin = tmpMin; } - if (tmpMax < tMax) + if (tmpMax < tMax) { tMax = tmpMax; + } } return tMin <= tMax; @@ -801,26 +864,29 @@ bool BoxLineTest(const zeus::CAABox& aabb, const zeus::CVector3f& point, const z bool LineCircleIntersection2d(const zeus::CVector3f& point, const zeus::CVector3f& dir, const zeus::CSphere& sphere, int axis1, int axis2, float& d) { - zeus::CVector3f delta = sphere.position - point; - zeus::CVector2f deltaVec(delta[axis1], delta[axis2]); - zeus::CVector2f dirVec(dir[axis1], dir[axis2]); + const zeus::CVector3f delta = sphere.position - point; + const zeus::CVector2f deltaVec(delta[axis1], delta[axis2]); + const zeus::CVector2f dirVec(dir[axis1], dir[axis2]); - float dirVecMag = dirVec.magnitude(); - if (dirVecMag < FLT_EPSILON) + const float dirVecMag = dirVec.magnitude(); + if (dirVecMag < FLT_EPSILON) { return false; + } - float deltaVecDot = deltaVec.dot(dirVec / dirVecMag); - float deltaVecMagSq = deltaVec.magSquared(); + const float deltaVecDot = deltaVec.dot(dirVec / dirVecMag); + const float deltaVecMagSq = deltaVec.magSquared(); - float sphereRadSq = sphere.radius * sphere.radius; - if (deltaVecDot < 0.f && deltaVecMagSq > sphereRadSq) + const float sphereRadSq = sphere.radius * sphere.radius; + if (deltaVecDot < 0.f && deltaVecMagSq > sphereRadSq) { return false; + } - float tSq = sphereRadSq - (deltaVecMagSq - deltaVecDot * deltaVecDot); - if (tSq < 0.f) + const float tSq = sphereRadSq - (deltaVecMagSq - deltaVecDot * deltaVecDot); + if (tSq < 0.f) { return false; + } - float t = std::sqrt(tSq); + const float t = std::sqrt(tSq); d = (deltaVecMagSq > sphereRadSq) ? deltaVecDot - t : deltaVecDot + t; d /= dirVecMag; @@ -830,35 +896,40 @@ bool LineCircleIntersection2d(const zeus::CVector3f& point, const zeus::CVector3 bool MovingSphereAABox(const zeus::CSphere& sphere, const zeus::CAABox& aabb, const zeus::CVector3f& dir, double& dOut, zeus::CVector3f& point, zeus::CVector3f& normal) { - zeus::CAABox expAABB(aabb.min - sphere.radius, aabb.max + sphere.radius); - float tMin, tMax; + const zeus::CAABox expAABB(aabb.min - sphere.radius, aabb.max + sphere.radius); + float tMin; + float tMax; int axis; bool sign; - if (!BoxLineTest(expAABB, sphere.position, dir, tMin, tMax, axis, sign)) + if (!BoxLineTest(expAABB, sphere.position, dir, tMin, tMax, axis, sign)) { return false; + } point = sphere.position + tMin * dir; - int nextAxis1 = (axis + 1) % 3; // r0 - int nextAxis2 = (axis + 2) % 3; // r5 + const int nextAxis1 = (axis + 1) % 3; // r0 + const int nextAxis2 = (axis + 2) % 3; // r5 - bool inMin1 = point[nextAxis1] >= aabb.min[nextAxis1]; // r6 - bool inMax1 = point[nextAxis1] <= aabb.max[nextAxis1]; // r8 - bool inBounds1 = inMin1 && inMax1; // r9 - bool inMin2 = point[nextAxis2] >= aabb.min[nextAxis2]; // r7 - bool inMax2 = point[nextAxis2] <= aabb.max[nextAxis2]; // r4 - bool inBounds2 = inMin2 && inMax2; // r8 + const bool inMin1 = point[nextAxis1] >= aabb.min[nextAxis1]; // r6 + const bool inMax1 = point[nextAxis1] <= aabb.max[nextAxis1]; // r8 + const bool inBounds1 = inMin1 && inMax1; // r9 + const bool inMin2 = point[nextAxis2] >= aabb.min[nextAxis2]; // r7 + const bool inMax2 = point[nextAxis2] <= aabb.max[nextAxis2]; // r4 + const bool inBounds2 = inMin2 && inMax2; // r8 if (inBounds1 && inBounds2) { - if (tMin < 0.f || tMin > dOut) + if (tMin < 0.f || tMin > dOut) { return false; + } normal[axis] = sign ? 1.f : -1.f; dOut = tMin; point -= normal * sphere.radius; return true; - } else if (!inBounds1 && !inBounds2) { - int pointFlags = (1 << axis) * sign | (1 << nextAxis1) * inMin1 | (1 << nextAxis2) * inMin2; - zeus::CVector3f aabbPoint = aabb.getPoint(pointFlags); + } + + if (!inBounds1 && !inBounds2) { + const int pointFlags = (1 << axis) * sign | (1 << nextAxis1) * inMin1 | (1 << nextAxis2) * inMin2; + const zeus::CVector3f aabbPoint = aabb.getPoint(pointFlags); float d; if (CollisionUtil::RaySphereIntersection(zeus::CSphere(aabbPoint, sphere.radius), sphere.position, dir, dOut, d, point)) { @@ -876,19 +947,20 @@ bool MovingSphereAABox(const zeus::CSphere& sphere, const zeus::CAABox& aabb, co return true; } - int useAxisNext1 = (useAxis + 1) % 3; - int useAxisNext2 = (useAxis + 2) % 3; + const int useAxisNext1 = (useAxis + 1) % 3; + const int useAxisNext2 = (useAxis + 2) % 3; float d; if (CollisionUtil::LineCircleIntersection2d(sphere.position, dir, zeus::CSphere(aabbPoint, sphere.radius), useAxisNext1, useAxisNext2, d) && d > 0.f && d < dOut) { if (point[useAxis] > aabb.max[useAxis]) { - int useAxisBit = 1 << useAxis; - if (pointFlags & useAxisBit) + const int useAxisBit = 1 << useAxis; + if (pointFlags & useAxisBit) { return false; + } - zeus::CVector3f aabbPoint1 = aabb.getPoint(pointFlags | useAxisBit); + const zeus::CVector3f aabbPoint1 = aabb.getPoint(pointFlags | useAxisBit); if (CollisionUtil::RaySphereIntersection(zeus::CSphere(aabbPoint1, sphere.radius), sphere.position, dir, dOut, d, point)) { dOut = d; @@ -899,11 +971,12 @@ bool MovingSphereAABox(const zeus::CSphere& sphere, const zeus::CAABox& aabb, co return false; } } else if (point[useAxis] < aabb.min[useAxis]) { - int useAxisBit = 1 << useAxis; - if (!(pointFlags & useAxisBit)) + const int useAxisBit = 1 << useAxis; + if (!(pointFlags & useAxisBit)) { return false; + } - zeus::CVector3f aabbPoint1 = aabb.getPoint(pointFlags ^ useAxisBit); + const zeus::CVector3f aabbPoint1 = aabb.getPoint(pointFlags ^ useAxisBit); if (CollisionUtil::RaySphereIntersection(zeus::CSphere(aabbPoint1, sphere.radius), sphere.position, dir, dOut, d, point)) { dOut = d; @@ -926,12 +999,13 @@ bool MovingSphereAABox(const zeus::CSphere& sphere, const zeus::CAABox& aabb, co int minAxis = 0; for (int i = 0; i < 3; ++i) { if (std::fabs(dir[i]) > FLT_EPSILON) { - bool pointMax = pointFlags & (1 << i); + const bool pointMax = (pointFlags & (1 << i)) != 0; if (pointMax != (dir[i] > 0.f)) { ++reverseCount; - float d = 1.f / dir[i] * ((pointMax ? aabb.max[i] : aabb.min[i]) - sphere.position[i]); - if (d < 0.f) + const float d = 1.f / dir[i] * ((pointMax ? aabb.max[i] : aabb.min[i]) - sphere.position[i]); + if (d < 0.f) { return false; + } if (d < dMin) { dMin = d; minAxis = i; @@ -940,20 +1014,23 @@ bool MovingSphereAABox(const zeus::CSphere& sphere, const zeus::CAABox& aabb, co } } - if (reverseCount < 2) + if (reverseCount < 2) { return false; + } - int useAxisNext1 = (minAxis + 1) % 3; - int useAxisNext2 = (minAxis + 2) % 3; + const int useAxisNext1 = (minAxis + 1) % 3; + const int useAxisNext2 = (minAxis + 2) % 3; float d; if (CollisionUtil::LineCircleIntersection2d(sphere.position, dir, zeus::CSphere(aabbPoint, sphere.radius), useAxisNext1, useAxisNext2, d) && d > 0.f && d < dOut) { point = sphere.position + d * dir; - if (point[minAxis] > aabb.max[minAxis]) + if (point[minAxis] > aabb.max[minAxis]) { return false; - if (point[minAxis] < aabb.min[minAxis]) + } + if (point[minAxis] < aabb.min[minAxis]) { return false; + } dOut = d; normal = point - aabbPoint; @@ -966,17 +1043,17 @@ bool MovingSphereAABox(const zeus::CSphere& sphere, const zeus::CAABox& aabb, co } } - bool useNextAxis1 = inBounds1 ? nextAxis2 : nextAxis1; - bool useNextAxis2 = inBounds1 ? nextAxis1 : nextAxis2; + const bool useNextAxis1 = inBounds1 ? nextAxis2 : nextAxis1; + const bool useNextAxis2 = inBounds1 ? nextAxis1 : nextAxis2; - int pointFlags = ((1 << int(useNextAxis1)) * (inBounds1 ? inMin2 : inMin1)) | ((1 << axis) * sign); - zeus::CVector3f aabbPoint2 = aabb.getPoint(pointFlags); + const int pointFlags = ((1 << int(useNextAxis1)) * (inBounds1 ? inMin2 : inMin1)) | ((1 << axis) * sign); + const zeus::CVector3f aabbPoint2 = aabb.getPoint(pointFlags); float d; if (LineCircleIntersection2d(sphere.position, dir, zeus::CSphere(aabbPoint2, sphere.radius), axis, useNextAxis1, d) && d > 0.f && d < dOut) { point = sphere.position + d * dir; if (point[useNextAxis2] > aabb.max[useNextAxis2]) { - zeus::CVector3f aabbPoint3 = aabb.getPoint(pointFlags | (1 << int(useNextAxis2))); + const zeus::CVector3f aabbPoint3 = aabb.getPoint(pointFlags | (1 << int(useNextAxis2))); if (point[useNextAxis2] < expAABB.max[useNextAxis2]) { if (RaySphereIntersection(zeus::CSphere(aabbPoint3, sphere.radius), sphere.position, dir, dOut, d, point)) { dOut = d; @@ -986,7 +1063,9 @@ bool MovingSphereAABox(const zeus::CSphere& sphere, const zeus::CAABox& aabb, co } } return false; - } else if (point[useNextAxis2] < aabb.min[useNextAxis2]) { + } + + if (point[useNextAxis2] < aabb.min[useNextAxis2]) { if (point[useNextAxis2] > expAABB.min[useNextAxis2]) { if (RaySphereIntersection(zeus::CSphere(aabbPoint2, sphere.radius), sphere.position, dir, dOut, d, point)) { dOut = d; @@ -1013,52 +1092,61 @@ bool AABox_AABox_Moving(const zeus::CAABox& aabb0, const zeus::CAABox& aabb1, co zeus::CVector3d vecMin(-FLT_MAX); zeus::CVector3d vecMax(FLT_MAX); - for (int i = 0; i < 3; ++i) { + for (size_t i = 0; i < 3; ++i) { if (std::fabs(dir[i]) < FLT_EPSILON) { - if (aabb0.min[i] >= aabb1.min[i] && aabb0.min[i] <= aabb1.max[i]) + if (aabb0.min[i] >= aabb1.min[i] && aabb0.min[i] <= aabb1.max[i]) { continue; - if (aabb0.max[i] >= aabb1.min[i] && aabb0.max[i] <= aabb1.max[i]) + } + if (aabb0.max[i] >= aabb1.min[i] && aabb0.max[i] <= aabb1.max[i]) { continue; - if (aabb0.min[i] < aabb1.min[i] && aabb0.max[i] > aabb1.max[i]) + } + if (aabb0.min[i] < aabb1.min[i] && aabb0.max[i] > aabb1.max[i]) { continue; + } return false; } else { - if (aabb0.max[i] < aabb1.min[i] && dir[i] > 0.f) + if (aabb0.max[i] < aabb1.min[i] && dir[i] > 0.f) { vecMin[i] = (aabb1.min[i] - aabb0.max[i]) / dir[i]; - else if (aabb1.max[i] < aabb0.min[i] && dir[i] < 0.f) + } else if (aabb1.max[i] < aabb0.min[i] && dir[i] < 0.f) { vecMin[i] = (aabb1.max[i] - aabb0.min[i]) / dir[i]; - else if (aabb1.max[i] > aabb0.min[i] && dir[i] < 0.f) + } else if (aabb1.max[i] > aabb0.min[i] && dir[i] < 0.f) { vecMin[i] = (aabb1.max[i] - aabb0.min[i]) / dir[i]; - else if (aabb0.max[i] > aabb1.min[i] && dir[i] > 0.f) + } else if (aabb0.max[i] > aabb1.min[i] && dir[i] > 0.f) { vecMin[i] = (aabb1.min[i] - aabb0.max[i]) / dir[i]; + } - if (aabb1.max[i] > aabb0.min[i] && dir[i] > 0.f) + if (aabb1.max[i] > aabb0.min[i] && dir[i] > 0.f) { vecMax[i] = (aabb1.max[i] - aabb0.min[i]) / dir[i]; - else if (aabb0.max[i] > aabb1.min[i] && dir[i] < 0.f) + } else if (aabb0.max[i] > aabb1.min[i] && dir[i] < 0.f) { vecMax[i] = (aabb1.min[i] - aabb0.max[i]) / dir[i]; - else if (aabb0.max[i] < aabb1.min[i] && dir[i] < 0.f) + } else if (aabb0.max[i] < aabb1.min[i] && dir[i] < 0.f) { vecMax[i] = (aabb1.min[i] - aabb0.max[i]) / dir[i]; - else if (aabb1.max[i] < aabb0.min[i] && dir[i] > 0.f) + } else if (aabb1.max[i] < aabb0.min[i] && dir[i] > 0.f) { vecMax[i] = (aabb1.max[i] - aabb0.min[i]) / dir[i]; + } } } int maxAxis = 0; - if (vecMin[1] > vecMin[0]) + if (vecMin[1] > vecMin[0]) { maxAxis = 1; - if (vecMin[2] > vecMin[maxAxis]) + } + if (vecMin[2] > vecMin[maxAxis]) { maxAxis = 2; + } - double minMax = std::min(std::min(vecMax[2], vecMax[1]), vecMax[0]); - if (vecMin[maxAxis] > minMax) + const double minMax = std::min(std::min(vecMax[2], vecMax[1]), vecMax[0]); + if (vecMin[maxAxis] > minMax) { return false; + } d = vecMin[maxAxis]; normal = zeus::skZero3f; normal[maxAxis] = dir[maxAxis] > 0.f ? -1.f : 1.f; - for (int i = 0; i < 3; ++i) + for (size_t i = 0; i < 3; ++i) { point[i] = dir[i] > 0.f ? aabb0.max[i] : aabb0.min[i]; + } point += float(d) * dir; return true; @@ -1066,7 +1154,8 @@ bool AABox_AABox_Moving(const zeus::CAABox& aabb0, const zeus::CAABox& aabb1, co void AddAverageToFront(const CCollisionInfoList& in, CCollisionInfoList& out) { if (in.GetCount() > 1) { - zeus::CVector3f pointAccum, normAccum; + zeus::CVector3f pointAccum; + zeus::CVector3f normAccum; for (const CCollisionInfo& info : in) { pointAccum += info.GetPoint(); @@ -1080,7 +1169,8 @@ void AddAverageToFront(const CCollisionInfoList& in, CCollisionInfoList& out) { } } - for (const CCollisionInfo& info : in) + for (const CCollisionInfo& info : in) { out.Add(info, false); + } } } // namespace urde::CollisionUtil diff --git a/Runtime/Collision/CollisionUtil.hpp b/Runtime/Collision/CollisionUtil.hpp index 8e6da6c8b..a0c4f179a 100644 --- a/Runtime/Collision/CollisionUtil.hpp +++ b/Runtime/Collision/CollisionUtil.hpp @@ -20,9 +20,9 @@ bool RaySphereIntersection_Double(const zeus::CSphere&, const zeus::CVector3f&, bool RaySphereIntersection(const zeus::CSphere& sphere, const zeus::CVector3f& pos, const zeus::CVector3f& dir, float mag, float& T, zeus::CVector3f& point); bool RayTriangleIntersection_Double(const zeus::CVector3f& point, const zeus::CVector3f& dir, - const zeus::CVector3f* verts, double& d); -bool RayTriangleIntersection(const zeus::CVector3f& point, const zeus::CVector3f& dir, const zeus::CVector3f* verts, - float& d); + const std::array& verts, double& d); +bool RayTriangleIntersection(const zeus::CVector3f& point, const zeus::CVector3f& dir, + const std::array& verts, float& d); void FilterOutBackfaces(const zeus::CVector3f& vec, const CCollisionInfoList& in, CCollisionInfoList& out); void FilterByClosestNormal(const zeus::CVector3f& norm, const CCollisionInfoList& in, CCollisionInfoList& out); bool AABoxAABoxIntersection(const zeus::CAABox& aabb0, const CMaterialList& list0, const zeus::CAABox& aabb1, diff --git a/Runtime/Collision/ICollisionFilter.hpp b/Runtime/Collision/ICollisionFilter.hpp index 3c09e7fa3..e0a7a0d53 100644 --- a/Runtime/Collision/ICollisionFilter.hpp +++ b/Runtime/Collision/ICollisionFilter.hpp @@ -8,9 +8,10 @@ class ICollisionFilter { CActor& x4_actor; protected: - ICollisionFilter(CActor& actor) : x4_actor(actor) {} + explicit ICollisionFilter(CActor& actor) : x4_actor(actor) {} public: + virtual ~ICollisionFilter() = default; virtual void Filter(const CCollisionInfoList& in, CCollisionInfoList& out) const = 0; }; diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index f71a5b2b1..1007d117c 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -72,8 +72,8 @@ public: static void Clear(); static void Sort(); static void InsertPlaneObject(float closeDist, float farDist, const zeus::CAABox& aabb, bool invertTest, - const zeus::CPlane& plane, bool zOnly, EDrawableType dtype, const void* data); - static void Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype, const void* data, + const zeus::CPlane& plane, bool zOnly, EDrawableType dtype, void* data); + static void Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype, void* data, const zeus::CPlane& plane, u16 extraSort); static void Shutdown(); static void Init(); @@ -173,14 +173,14 @@ void Buckets::Sort() { } void Buckets::InsertPlaneObject(float closeDist, float farDist, const zeus::CAABox& aabb, bool invertTest, - const zeus::CPlane& plane, bool zOnly, EDrawableType dtype, const void* data) { + const zeus::CPlane& plane, bool zOnly, EDrawableType dtype, void* data) { if (sPlaneObjectData->size() == sPlaneObjectData->capacity()) { return; } sPlaneObjectData->emplace_back(dtype, closeDist, farDist, aabb, invertTest, plane, zOnly, data); } -void Buckets::Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype, const void* data, +void Buckets::Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype, void* data, const zeus::CPlane& plane, u16 extraSort) { if (sData->size() == sData->capacity()) { Log.report(logvisor::Fatal, fmt("Rendering buckets filled to capacity")); @@ -220,7 +220,7 @@ CBooRenderer::CAreaListItem::CAreaListItem(const std::vector thisLights; @@ -291,12 +291,12 @@ void CBooRenderer::RenderBucketItems(CAreaListItem* item) { for (CDrawable* drawable : bucket) { switch (drawable->GetType()) { case EDrawableType::Particle: { - static_cast((void*)drawable->GetData())->Render(); + static_cast(drawable->GetData())->Render(); break; } case EDrawableType::WorldSurface: { // SetupRendererStates(); - CBooSurface* surf = static_cast((void*)drawable->GetData()); + auto* surf = static_cast(drawable->GetData()); CBooModel* model = surf->m_parent; if (model) { ActivateLightsForModel(item, *model); @@ -988,18 +988,18 @@ void CBooRenderer::PostRenderFogs() { void CBooRenderer::SetModelMatrix(const zeus::CTransform& xf) { CGraphics::SetModelMatrix(xf); } -void CBooRenderer::AddParticleGen(const CParticleGen& gen) { +void CBooRenderer::AddParticleGen(CParticleGen& gen) { if (auto bounds = gen.GetBounds()) { zeus::CVector3f pt = bounds.value().closestPointAlongVector(xb0_viewPlane.normal()); Buckets::Insert(pt, bounds.value(), EDrawableType::Particle, &gen, xb0_viewPlane, 0); } } -void CBooRenderer::AddParticleGen(const CParticleGen& gen, const zeus::CVector3f& pos, const zeus::CAABox& bounds) { +void CBooRenderer::AddParticleGen(CParticleGen& gen, const zeus::CVector3f& pos, const zeus::CAABox& bounds) { Buckets::Insert(pos, bounds, EDrawableType::Particle, &gen, xb0_viewPlane, 0); } -void CBooRenderer::AddPlaneObject(const void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, int type) { +void CBooRenderer::AddPlaneObject(void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, int type) { zeus::CVector3f closePoint = aabb.closestPointAlongVector(xb0_viewPlane.normal()); zeus::CVector3f farPoint = aabb.furthestPointAlongVector(xb0_viewPlane.normal()); float closeDist = xb0_viewPlane.pointToPlaneDist(closePoint); @@ -1015,7 +1015,7 @@ void CBooRenderer::AddPlaneObject(const void* obj, const zeus::CAABox& aabb, con } } -void CBooRenderer::AddDrawable(const void* obj, const zeus::CVector3f& pos, const zeus::CAABox& aabb, int mode, +void CBooRenderer::AddDrawable(void* obj, const zeus::CVector3f& pos, const zeus::CAABox& aabb, int mode, EDrawableSorting sorting) { if (sorting == EDrawableSorting::UnsortedCallback) xa8_drawableCallback(obj, xac_callbackContext, mode); @@ -1023,7 +1023,7 @@ void CBooRenderer::AddDrawable(const void* obj, const zeus::CVector3f& pos, cons Buckets::Insert(pos, aabb, EDrawableType(mode + 2), obj, xb0_viewPlane, 0); } -void CBooRenderer::SetDrawableCallback(TDrawableCallback cb, const void* ctx) { +void CBooRenderer::SetDrawableCallback(TDrawableCallback cb, void* ctx) { xa8_drawableCallback = cb; xac_callbackContext = ctx; } @@ -1056,9 +1056,9 @@ std::pair CBooRenderer::SetViewportOrtho(bool void CBooRenderer::SetClippingPlanes(const zeus::CFrustum& frustum) { x44_frustumPlanes = frustum; } -void CBooRenderer::SetViewport(int l, int b, int w, int h) { - CGraphics::SetViewport(l, b, w, h); - CGraphics::SetScissor(l, b, w, h); +void CBooRenderer::SetViewport(int left, int bottom, int width, int height) { + CGraphics::SetViewport(left, bottom, width, height); + CGraphics::SetScissor(left, bottom, width, height); } void CBooRenderer::SetDebugOption(EDebugOption, int) {} @@ -1352,12 +1352,14 @@ int CBooRenderer::DrawOverlappingWorldModelIDs(int alphaVal, const std::vector(model).UpdateUniformData(flags, nullptr, nullptr, 3); - const_cast(model).VerifyCurrentShader(0); - for (const CBooSurface* surf = model.x38_firstUnsortedSurface; surf; surf = surf->m_next) - if (surf->GetBounds().intersects(aabb)) + CBooModel& model = *item.x10_models[wordModel + j]; + model.UpdateUniformData(flags, nullptr, nullptr, 3); + model.VerifyCurrentShader(0); + for (const CBooSurface* surf = model.x38_firstUnsortedSurface; surf; surf = surf->m_next) { + if (surf->GetBounds().intersects(aabb)) { model.DrawSurface(*surf, flags); + } + } alphaVal += 4; } } diff --git a/Runtime/Graphics/CBooRenderer.hpp b/Runtime/Graphics/CBooRenderer.hpp index 321d8be4c..7c3016297 100644 --- a/Runtime/Graphics/CBooRenderer.hpp +++ b/Runtime/Graphics/CBooRenderer.hpp @@ -96,7 +96,7 @@ class CBooRenderer final : public IRenderer { zeus::CFrustum x44_frustumPlanes; TDrawableCallback xa8_drawableCallback; - const void* xac_callbackContext; + void* xac_callbackContext; zeus::CPlane xb0_viewPlane = {0.f, 1.f, 0.f, 0.f}; @@ -198,9 +198,9 @@ public: void AddWorldSurfaces(CBooModel& model); std::list::iterator FindStaticGeometry(const std::vector*); - void AddStaticGeometry(const std::vector*, const CAreaRenderOctTree*, int areaIdx, - const SShader* shaderSet) override; - void EnablePVS(const CPVSVisSet&, u32) override; + void AddStaticGeometry(const std::vector* geometry, const CAreaRenderOctTree* octTree, + int areaIdx, const SShader* shaderSet) override; + void EnablePVS(const CPVSVisSet& set, u32 areaIdx) override; void DisablePVS() override; void UpdateAreaUniforms(int areaIdx, EWorldShadowMode shadowMode = EWorldShadowMode::None, bool activateLights = true, int cubeFace = -1, const CModelFlags* ballShadowFlags = nullptr); @@ -212,17 +212,18 @@ public: void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly) override; void PostRenderFogs() override; void SetModelMatrix(const zeus::CTransform& xf) override; - void AddParticleGen(const CParticleGen&) override; - void AddParticleGen(const CParticleGen&, const zeus::CVector3f&, const zeus::CAABox&) override; - void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int) override; - void AddDrawable(void const*, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting) override; - void SetDrawableCallback(TDrawableCallback, const void*) override; - void SetWorldViewpoint(const zeus::CTransform&) override; - void SetPerspective(float, float, float, float, float) override; - void SetPerspective(float, float, float, float) override; - std::pair SetViewportOrtho(bool, float, float) override; + void AddParticleGen(CParticleGen& gen) override; + void AddParticleGen(CParticleGen& gen, const zeus::CVector3f& pos, const zeus::CAABox& bounds) override; + void AddPlaneObject(void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, int type) override; + void AddDrawable(void* obj, const zeus::CVector3f& pos, const zeus::CAABox& aabb, int mode, + EDrawableSorting sorting) override; + void SetDrawableCallback(TDrawableCallback cb, void* ctx) override; + void SetWorldViewpoint(const zeus::CTransform& xf) override; + void SetPerspective(float fovy, float width, float height, float znear, float zfar) override; + void SetPerspective(float fovy, float aspect, float znear, float zfar) override; + std::pair SetViewportOrtho(bool centered, float znear, float zfar) override; void SetClippingPlanes(const zeus::CFrustum& frustum) override; - void SetViewport(int, int, int, int) override; + void SetViewport(int left, int bottom, int width, int height) override; // void SetDepthReadWrite(bool, bool); // void SetBlendMode_AdditiveAlpha(); // void SetBlendMode_AlphaBlended(); @@ -246,18 +247,18 @@ public: // void PrimColor(float, float, float, float); // void PrimColor(const zeus::CColor&); // void EndPrimitive(); - void SetAmbientColor(const zeus::CColor&) override; - void DrawString(const char*, int, int) override; + void SetAmbientColor(const zeus::CColor& color) override; + void DrawString(const char* string, int, int) override; u32 GetFPS() override; - void CacheReflection(TReflectionCallback, void*, bool) override; - void DrawSpaceWarp(const zeus::CVector3f&, float) override; + void CacheReflection(TReflectionCallback cb, void* ctx, bool clearAfter) override; + void DrawSpaceWarp(const zeus::CVector3f& pt, float strength) override; void DrawThermalModel(const CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol) override; void DrawXRayOutline(const zeus::CAABox&) override; - void SetWireframeFlags(int) override; - void SetWorldFog(ERglFogMode, float, float, const zeus::CColor&) override; - void RenderFogVolume(const zeus::CColor&, const zeus::CAABox&, const TLockedToken*, - const CSkinnedModel*) override; - void SetThermal(bool, float, const zeus::CColor&) override; + void SetWireframeFlags(int flags) override; + void SetWorldFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color) override; + void RenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, const TLockedToken* model, + const CSkinnedModel* sModel) override; + void SetThermal(bool thermal, float level, const zeus::CColor& color) override; void SetThermalColdScale(float scale) override; void DoThermalBlendCold() override; void DoThermalBlendHot() override; diff --git a/Runtime/Graphics/CDrawable.hpp b/Runtime/Graphics/CDrawable.hpp index 8851b520d..5329fb267 100644 --- a/Runtime/Graphics/CDrawable.hpp +++ b/Runtime/Graphics/CDrawable.hpp @@ -9,17 +9,18 @@ enum class EDrawableType : u16 { WorldSurface, Particle, Actor, SimpleShadow, De class CDrawable { EDrawableType x0_type; u16 x2_extraSort; - const void* x4_data; + void* x4_data; zeus::CAABox x8_aabb; float x20_viewDist; public: - CDrawable(EDrawableType dtype, u16 extraSort, float planeDot, const zeus::CAABox& aabb, const void* data) + CDrawable(EDrawableType dtype, u16 extraSort, float planeDot, const zeus::CAABox& aabb, void* data) : x0_type(dtype), x2_extraSort(extraSort), x4_data(data), x8_aabb(aabb), x20_viewDist(planeDot) {} EDrawableType GetType() const { return x0_type; } const zeus::CAABox& GetBounds() const { return x8_aabb; } float GetDistance() const { return x20_viewDist; } + void* GetData() { return x4_data; } const void* GetData() const { return x4_data; } u16 GetExtraSort() const { return x2_extraSort; } }; diff --git a/Runtime/Graphics/CDrawablePlaneObject.hpp b/Runtime/Graphics/CDrawablePlaneObject.hpp index aa94540cb..eb20bc5fd 100644 --- a/Runtime/Graphics/CDrawablePlaneObject.hpp +++ b/Runtime/Graphics/CDrawablePlaneObject.hpp @@ -14,7 +14,7 @@ class CDrawablePlaneObject : public CDrawable { public: CDrawablePlaneObject(EDrawableType dtype, float closeDist, float farDist, const zeus::CAABox& aabb, bool invertTest, - const zeus::CPlane& plane, bool zOnly, const void* data) + const zeus::CPlane& plane, bool zOnly, void* data) : CDrawable(dtype, 0, closeDist, aabb, data), x24_targetBucket(0), x28_farDist(farDist), x2c_plane(plane) { x3c_24_invertTest = invertTest; x3c_25_zOnly = zOnly; diff --git a/Runtime/Graphics/CGraphics.cpp b/Runtime/Graphics/CGraphics.cpp index 678e5d17b..48171d31c 100644 --- a/Runtime/Graphics/CGraphics.cpp +++ b/Runtime/Graphics/CGraphics.cpp @@ -12,7 +12,7 @@ namespace urde { CGraphics::CProjectionState CGraphics::g_Proj; CGraphics::CFogState CGraphics::g_Fog; -zeus::CColor CGraphics::g_ColorRegs[3] = {}; +std::array CGraphics::g_ColorRegs{}; float CGraphics::g_ProjAspect = 1.f; u32 CGraphics::g_NumLightsActive = 0; u32 CGraphics::g_NumBreakpointsWaiting = 0; @@ -35,7 +35,7 @@ SViewport g_Viewport = { }; u32 CGraphics::g_FrameCounter = 0; -const zeus::CMatrix3f CGraphics::skCubeBasisMats[] = { +const std::array CGraphics::skCubeBasisMats{{ /* Right */ {0.f, 1.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, -1.f}, /* Left */ @@ -48,7 +48,7 @@ const zeus::CMatrix3f CGraphics::skCubeBasisMats[] = { {1.f, 0.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, -1.f}, /* Forward */ {-1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, -1.f}, -}; +}}; void CGraphics::DisableAllLights() { g_NumLightsActive = 0; @@ -158,10 +158,10 @@ void CGraphics::SetModelMatrix(const zeus::CTransform& xf) { SetViewMatrix(); } -static const zeus::CMatrix4f PlusOneZ(1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f); +constexpr zeus::CMatrix4f PlusOneZ(1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f); -static const zeus::CMatrix4f VulkanCorrect(1.f, 0.f, 0.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.5f, 0.5f + FLT_EPSILON, - 0.f, 0.f, 0.f, 1.f); +constexpr zeus::CMatrix4f VulkanCorrect(1.f, 0.f, 0.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.5f, 0.5f + FLT_EPSILON, + 0.f, 0.f, 0.f, 1.f); zeus::CMatrix4f CGraphics::CalculatePerspectiveMatrix(float fovy, float aspect, float znear, float zfar, bool forRenderer) { diff --git a/Runtime/Graphics/CGraphics.hpp b/Runtime/Graphics/CGraphics.hpp index 27e811e48..cf4eb982c 100644 --- a/Runtime/Graphics/CGraphics.hpp +++ b/Runtime/Graphics/CGraphics.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include "Runtime/RetroTypes.hpp" @@ -248,7 +249,7 @@ public: static CProjectionState g_Proj; static zeus::CVector2f g_CachedDepthRange; static CFogState g_Fog; - static zeus::CColor g_ColorRegs[3]; + static std::array g_ColorRegs; static float g_ProjAspect; static u32 g_NumLightsActive; static u32 g_NumBreakpointsWaiting; @@ -316,7 +317,7 @@ public: static boo::IGraphicsCommandQueue* g_BooMainCommandQueue; static boo::ObjToken g_SpareTexture; - static const zeus::CMatrix3f skCubeBasisMats[6]; + static const std::array skCubeBasisMats; static void InitializeBoo(boo::IGraphicsDataFactory* factory, boo::IGraphicsCommandQueue* cc, const boo::ObjToken& spareTex) { diff --git a/Runtime/Graphics/CGraphicsPalette.hpp b/Runtime/Graphics/CGraphicsPalette.hpp index 72e78b8b7..6c7b7e25b 100644 --- a/Runtime/Graphics/CGraphicsPalette.hpp +++ b/Runtime/Graphics/CGraphicsPalette.hpp @@ -21,8 +21,9 @@ class CGraphicsPalette { bool x1c_ = false; public: - CGraphicsPalette(EPaletteFormat fmt, int count) : x0_fmt(fmt), x8_entryCount(count), xc_entries(new u16[count]) {} - CGraphicsPalette(CInputStream& in) : x0_fmt(EPaletteFormat(in.readUint32Big())) { + explicit CGraphicsPalette(EPaletteFormat fmt, int count) + : x0_fmt(fmt), x8_entryCount(count), xc_entries(new u16[count]) {} + explicit CGraphicsPalette(CInputStream& in) : x0_fmt(EPaletteFormat(in.readUint32Big())) { u16 w = in.readUint16Big(); u16 h = in.readUint16Big(); x8_entryCount = w * h; diff --git a/Runtime/Graphics/CLight.cpp b/Runtime/Graphics/CLight.cpp index bea0df8b9..a5de5e03a 100644 --- a/Runtime/Graphics/CLight.cpp +++ b/Runtime/Graphics/CLight.cpp @@ -4,8 +4,8 @@ namespace urde { -static const zeus::CVector3f kDefaultPosition(0.f, 0.f, 0.f); -static const zeus::CVector3f kDefaultDirection(0.f, -1.f, 0.f); +constexpr zeus::CVector3f kDefaultPosition(0.f, 0.f, 0.f); +constexpr zeus::CVector3f kDefaultDirection(0.f, -1.f, 0.f); float CLight::CalculateLightRadius() const { if (x28_distL < FLT_EPSILON && x2c_distQ < FLT_EPSILON) @@ -27,20 +27,20 @@ float CLight::CalculateLightRadius() const { float CLight::GetIntensity() const { if (x4c_24_intensityDirty) { - const_cast(this)->x4c_24_intensityDirty = false; + x4c_24_intensityDirty = false; float coef = 1.f; - if (x1c_type == ELightType::Custom) + if (x1c_type == ELightType::Custom) { coef = x30_angleC; - const_cast(this)->x48_cachedIntensity = - coef * std::max(x18_color.r(), std::max(x18_color.g(), x18_color.b())); + } + x48_cachedIntensity = coef * std::max({x18_color.r(), x18_color.g(), x18_color.b()}); } return x48_cachedIntensity; } float CLight::GetRadius() const { if (x4c_25_radiusDirty) { - const_cast(this)->x44_cachedRadius = CalculateLightRadius(); - const_cast(this)->x4c_25_radiusDirty = false; + x44_cachedRadius = CalculateLightRadius(); + x4c_25_radiusDirty = false; } return x44_cachedRadius; } @@ -50,16 +50,12 @@ CLight::CLight(const zeus::CVector3f& pos, const zeus::CVector3f& dir, const zeu : x0_pos(pos) , xc_dir(dir) , x18_color(color) -, x1c_type(ELightType::Custom) -, x20_spotCutoff(0.f) , x24_distC(distC) , x28_distL(distL) , x2c_distQ(distQ) , x30_angleC(angleC) , x34_angleL(angleL) , x38_angleQ(angleQ) -, x44_cachedRadius(0.f) -, x48_cachedIntensity(0.f) , x4c_24_intensityDirty(true) , x4c_25_radiusDirty(true) {} @@ -70,22 +66,14 @@ CLight::CLight(ELightType type, const zeus::CVector3f& pos, const zeus::CVector3 , x18_color(color) , x1c_type(type) , x20_spotCutoff(cutoff) -, x24_distC(1.f) -, x28_distL(0.f) -, x2c_distQ(0.f) -, x30_angleC(1.f) -, x34_angleL(0.f) -, x38_angleQ(0.f) -, x44_cachedRadius(0.f) -, x48_cachedIntensity(0.f) , x4c_24_intensityDirty(true) , x4c_25_radiusDirty(true) { switch (type) { case ELightType::Spot: { - float cosCutoff = std::cos(zeus::degToRad(cutoff)); + const float cosCutoff = std::cos(zeus::degToRad(cutoff)); x30_angleC = 0.f; - x34_angleL = -cosCutoff / (1.0 - cosCutoff); - x38_angleQ = 1.f / (1.0 - cosCutoff); + x34_angleL = -cosCutoff / (1.0f - cosCutoff); + x38_angleQ = 1.f / (1.0f - cosCutoff); break; } case ELightType::Directional: { diff --git a/Runtime/Graphics/CLight.hpp b/Runtime/Graphics/CLight.hpp index 4fcc523b4..76747d52a 100644 --- a/Runtime/Graphics/CLight.hpp +++ b/Runtime/Graphics/CLight.hpp @@ -35,10 +35,10 @@ class CLight { float x38_angleQ = 0.f; u32 x3c_priority = 0; u32 x40_lightId = 0; // Serves as unique key - float x44_cachedRadius = 0.f; - float x48_cachedIntensity = 0.f; - bool x4c_24_intensityDirty : 1; - bool x4c_25_radiusDirty : 1; + mutable float x44_cachedRadius = 0.f; + mutable float x48_cachedIntensity = 0.f; + mutable bool x4c_24_intensityDirty : 1; + mutable bool x4c_25_radiusDirty : 1; float CalculateLightRadius() const; diff --git a/Runtime/Graphics/CLineRenderer.cpp b/Runtime/Graphics/CLineRenderer.cpp index 517f72a2a..d8b4b3472 100644 --- a/Runtime/Graphics/CLineRenderer.cpp +++ b/Runtime/Graphics/CLineRenderer.cpp @@ -40,10 +40,11 @@ CLineRenderer::CLineRenderer(boo::IGraphicsDataFactory::Context& ctx, EPrimitive break; } - if (bool(texture)) + if (texture) { m_vertBufTex = s_vertPoolTex.allocateBlock(CGraphics::g_BooFactory, maxTriVerts); - else + } else { m_vertBufNoTex = s_vertPoolNoTex.allocateBlock(CGraphics::g_BooFactory, maxTriVerts); + } m_uniformBuf = s_uniformPool.allocateBlock(CGraphics::g_BooFactory); @@ -70,10 +71,11 @@ CLineRenderer::CLineRenderer(EPrimitiveMode mode, u32 maxVerts, const boo::ObjTo break; } - if (bool(texture)) + if (texture) { m_vertBufTex = s_vertPoolTex.allocateBlock(CGraphics::g_BooFactory, maxTriVerts); - else + } else { m_vertBufNoTex = s_vertPoolNoTex.allocateBlock(CGraphics::g_BooFactory, maxTriVerts); + } m_uniformBuf = s_uniformPool.allocateBlock(CGraphics::g_BooFactory); diff --git a/Runtime/Graphics/CLineRenderer.hpp b/Runtime/Graphics/CLineRenderer.hpp index 07aa05879..c17ad69bf 100644 --- a/Runtime/Graphics/CLineRenderer.hpp +++ b/Runtime/Graphics/CLineRenderer.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "Runtime/RetroTypes.hpp" #include "Runtime/rstl.hpp" #include "Runtime/Graphics/CGraphics.hpp" @@ -68,7 +70,7 @@ public: hecl::VertexBufferPool::Token m_vertBufTex; hecl::VertexBufferPool::Token m_vertBufNoTex; hecl::UniformBufferPool::Token m_uniformBuf; - boo::ObjToken m_shaderBind[2]; + std::array, 2> m_shaderBind; CLineRenderer(boo::IGraphicsDataFactory::Context& ctx, EPrimitiveMode mode, u32 maxVerts, const boo::ObjToken& texture, bool additive, bool zTest = false, bool zGEqual = false); diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index ade74ffef..9460599f3 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -106,7 +106,7 @@ struct SShader { MaterialSet m_matSet; std::optional m_geomLayout; int m_matSetIdx; - SShader(int idx) : m_matSetIdx(idx) { + explicit SShader(int idx) : m_matSetIdx(idx) { x0_textures.clear(); m_shaders.clear(); } @@ -210,16 +210,16 @@ public: void DisableAllLights(); void RemapMaterialData(SShader& shader); void RemapMaterialData(SShader& shader, const std::unordered_map& pipelines); - bool TryLockTextures() const; - void UnlockTextures() const; - void SyncLoadTextures() const; - void Touch(int shaderIdx) const; + bool TryLockTextures(); + void UnlockTextures(); + void SyncLoadTextures(); + void Touch(int shaderIdx); void VerifyCurrentShader(int shaderIdx); boo::ObjToken UpdateUniformData(const CModelFlags& flags, const CSkinRules* cskr, - const CPoseAsTransforms* pose, int sharedLayoutBuf = -1) const; - void DrawAlpha(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose) const; - void DrawNormal(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose) const; - void Draw(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose) const; + const CPoseAsTransforms* pose, int sharedLayoutBuf = -1); + void DrawAlpha(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose); + void DrawNormal(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose); + void Draw(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose); void DrawFlat(ESurfaceSelection sel, EExtendedShader extendedIdx) const; void LockParent() { m_modelTok.Lock(); } diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index 715267e42..bb30f753e 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -468,13 +468,14 @@ void CBooModel::RemapMaterialData(SShader& shader, m_instances.clear(); } -bool CBooModel::TryLockTextures() const { +bool CBooModel::TryLockTextures() { if (!x40_24_texturesLoaded) { bool allLoad = true; - for (auto& tex : const_cast>&>(x1c_textures)) { + for (auto& tex : x1c_textures) { tex.second.Lock(); - if (!tex.second.IsLoaded()) + if (!tex.second.IsLoaded()) { allLoad = false; + } } if (allLoad) { @@ -485,30 +486,38 @@ bool CBooModel::TryLockTextures() const { break; } } - if (!allLoad) + if (!allLoad) { break; + } } } - const_cast(this)->x40_24_texturesLoaded = allLoad; + x40_24_texturesLoaded = allLoad; } return x40_24_texturesLoaded; } -void CBooModel::UnlockTextures() const { - const_cast(this)->m_instances.clear(); - for (auto& tex : const_cast>&>(x1c_textures)) +void CBooModel::UnlockTextures() { + m_instances.clear(); + + for (auto& tex : x1c_textures) { tex.second.Unlock(); - const_cast(this)->x40_24_texturesLoaded = false; + } + + x40_24_texturesLoaded = false; } -void CBooModel::SyncLoadTextures() const { - if (!x40_24_texturesLoaded) { - for (auto& tex : const_cast>&>(x1c_textures)) - tex.second.GetObj(); - const_cast(this)->x40_24_texturesLoaded = true; +void CBooModel::SyncLoadTextures() { + if (x40_24_texturesLoaded) { + return; } + + for (auto& tex : x1c_textures) { + tex.second.GetObj(); + } + + x40_24_texturesLoaded = true; } void CBooModel::DrawFlat(ESurfaceSelection sel, EExtendedShader extendedIdx) const { @@ -965,8 +974,7 @@ boo::ObjToken GeometryUniformLayout::GetSharedBuffer(int } boo::ObjToken CBooModel::UpdateUniformData(const CModelFlags& flags, const CSkinRules* cskr, - const CPoseAsTransforms* pose, - int sharedLayoutBuf) const { + const CPoseAsTransforms* pose, int sharedLayoutBuf) { if (!g_DummyTextures && !TryLockTextures()) return {}; @@ -974,47 +982,52 @@ boo::ObjToken CBooModel::UpdateUniformData(const CModelFl if ((flags.m_extendedShader == EExtendedShader::WorldShadow || flags.m_extendedShader == EExtendedShader::LightingCubeReflectionWorldShadow) && m_lastDrawnShadowMap != g_shadowMap) { - const_cast(this)->m_lastDrawnShadowMap = g_shadowMap; - const_cast(this)->m_instances.clear(); + m_lastDrawnShadowMap = g_shadowMap; + m_instances.clear(); } /* Invalidate instances if new one-texture being drawn */ if (flags.m_extendedShader == EExtendedShader::Disintegrate && m_lastDrawnOneTexture != g_disintegrateTexture) { - const_cast(this)->m_lastDrawnOneTexture = g_disintegrateTexture; - const_cast(this)->m_instances.clear(); + m_lastDrawnOneTexture = g_disintegrateTexture; + m_instances.clear(); } /* Invalidate instances if new reflection cube being drawn */ if (hecl::com_cubemaps->toBoolean() && (flags.m_extendedShader == EExtendedShader::LightingCubeReflection || flags.m_extendedShader == EExtendedShader::LightingCubeReflectionWorldShadow) && m_lastDrawnReflectionCube != g_reflectionCube) { - const_cast(this)->m_lastDrawnReflectionCube = g_reflectionCube; - const_cast(this)->m_instances.clear(); + m_lastDrawnReflectionCube = g_reflectionCube; + m_instances.clear(); } const ModelInstance* inst; if (sharedLayoutBuf >= 0) { if (m_instances.size() <= sharedLayoutBuf) { do { - inst = const_cast(this)->PushNewModelInstance(m_instances.size()); - if (!inst) + inst = PushNewModelInstance(m_instances.size()); + if (!inst) { return {}; + } } while (m_instances.size() <= sharedLayoutBuf); - } else + } else { inst = &m_instances[sharedLayoutBuf]; - const_cast(this)->m_uniUpdateCount = sharedLayoutBuf + 1; + } + m_uniUpdateCount = sharedLayoutBuf + 1; } else { if (m_instances.size() <= m_uniUpdateCount) { - inst = const_cast(this)->PushNewModelInstance(sharedLayoutBuf); - if (!inst) + inst = PushNewModelInstance(sharedLayoutBuf); + if (!inst) { return {}; - } else + } + } else { inst = &m_instances[m_uniUpdateCount]; - ++const_cast(this)->m_uniUpdateCount; + } + ++m_uniUpdateCount; } - if (inst->m_geomUniformBuffer) + if (inst->m_geomUniformBuffer) { m_geomLayout->Update(flags, cskr, pose, x4_matSet, inst->m_geomUniformBuffer, this); + } u8* dataOut = reinterpret_cast(inst->m_uniformBuffer->map(m_uniformDataSize)); u8* dataCur = dataOut; @@ -1042,9 +1055,7 @@ boo::ObjToken CBooModel::UpdateUniformData(const CModelFl } else { CModelShaders::LightingUniform& lightingOut = *reinterpret_cast(dataCur); lightingOut = m_lightingData; - lightingOut.colorRegs[0] = CGraphics::g_ColorRegs[0]; - lightingOut.colorRegs[1] = CGraphics::g_ColorRegs[1]; - lightingOut.colorRegs[2] = CGraphics::g_ColorRegs[2]; + lightingOut.colorRegs = CGraphics::g_ColorRegs; lightingOut.mulColor = flags.x4_color; lightingOut.addColor = flags.addColor; lightingOut.fog = CGraphics::g_Fog; @@ -1072,7 +1083,7 @@ boo::ObjToken CBooModel::UpdateUniformData(const CModelFl return inst->m_dynamicVbo; } -void CBooModel::DrawAlpha(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose) const { +void CBooModel::DrawAlpha(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose) { CModelFlags rFlags = flags; /* Check if we're overriding with RenderModelBlack */ if (g_RenderModelBlack) { @@ -1086,7 +1097,7 @@ void CBooModel::DrawAlpha(const CModelFlags& flags, const CSkinRules* cskr, cons } } -void CBooModel::DrawNormal(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose) const { +void CBooModel::DrawNormal(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose) { CModelFlags rFlags = flags; /* Check if we're overriding with RenderModelBlack */ if (g_RenderModelBlack) { @@ -1099,7 +1110,7 @@ void CBooModel::DrawNormal(const CModelFlags& flags, const CSkinRules* cskr, con } } -void CBooModel::Draw(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose) const { +void CBooModel::Draw(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose) { CModelFlags rFlags = flags; /* Check if we're overriding with RenderModelBlack */ if (g_RenderModelBlack) { @@ -1244,29 +1255,29 @@ void CBooModel::VerifyCurrentShader(int shaderIdx) { RemapMaterialData(m_model->x18_matSets[shaderIdx]); } -void CBooModel::Touch(int shaderIdx) const { - const_cast(this)->VerifyCurrentShader(shaderIdx); +void CBooModel::Touch(int shaderIdx) { + VerifyCurrentShader(shaderIdx); TryLockTextures(); } void CModel::DrawSortedParts(const CModelFlags& flags) const { - const_cast(*x28_modelInst).VerifyCurrentShader(flags.x1_matSetIdx); + x28_modelInst->VerifyCurrentShader(flags.x1_matSetIdx); x28_modelInst->DrawAlpha(flags, nullptr, nullptr); } void CModel::DrawUnsortedParts(const CModelFlags& flags) const { - const_cast(*x28_modelInst).VerifyCurrentShader(flags.x1_matSetIdx); + x28_modelInst->VerifyCurrentShader(flags.x1_matSetIdx); x28_modelInst->DrawNormal(flags, nullptr, nullptr); } void CModel::Draw(const CModelFlags& flags) const { - const_cast(*x28_modelInst).VerifyCurrentShader(flags.x1_matSetIdx); + x28_modelInst->VerifyCurrentShader(flags.x1_matSetIdx); x28_modelInst->Draw(flags, nullptr, nullptr); } bool CModel::IsLoaded(int shaderIdx) const { - const_cast(*x28_modelInst).VerifyCurrentShader(shaderIdx); - return const_cast(*x28_modelInst).TryLockTextures(); + x28_modelInst->VerifyCurrentShader(shaderIdx); + return x28_modelInst->TryLockTextures(); } size_t CModel::GetPoolVertexOffset(size_t idx) const { return m_hmdlMeta.vertStride * idx; } diff --git a/Runtime/Graphics/CPVSAreaSet.hpp b/Runtime/Graphics/CPVSAreaSet.hpp index 732ca0e0e..fcd1ee99c 100644 --- a/Runtime/Graphics/CPVSAreaSet.hpp +++ b/Runtime/Graphics/CPVSAreaSet.hpp @@ -25,7 +25,7 @@ class CPVSAreaSet { } public: - CPVSAreaSet(const u8* data, u32 len); + explicit CPVSAreaSet(const u8* data, u32 len); u32 GetNumFeatures() const { return x0_numFeatures; } u32 GetNumActors() const { return xc_numActors; } u32 Get1stLightIndex(u32 lightIdx) const { return x0_numFeatures + x8_num2ndLights + lightIdx; } diff --git a/Runtime/Graphics/CRainSplashGenerator.cpp b/Runtime/Graphics/CRainSplashGenerator.cpp index b43c43654..dd91613c3 100644 --- a/Runtime/Graphics/CRainSplashGenerator.cpp +++ b/Runtime/Graphics/CRainSplashGenerator.cpp @@ -75,8 +75,9 @@ CRainSplashGenerator::SSplashLine::SSplashLine(boo::IGraphicsDataFactory::Contex : m_renderer(ctx, CLineRenderer::EPrimitiveMode::LineStrip, 3, nullptr, false) {} CRainSplashGenerator::SRainSplash::SRainSplash(boo::IGraphicsDataFactory::Context& ctx) { - for (int i = 0; i < 4; ++i) + for (size_t i = 0; i < x0_lines.capacity(); ++i) { x0_lines.emplace_back(ctx); + } } void CRainSplashGenerator::SSplashLine::Update(float dt, CStateManager& mgr) { diff --git a/Runtime/Graphics/CRainSplashGenerator.hpp b/Runtime/Graphics/CRainSplashGenerator.hpp index 2978c3750..3f2ade690 100644 --- a/Runtime/Graphics/CRainSplashGenerator.hpp +++ b/Runtime/Graphics/CRainSplashGenerator.hpp @@ -46,9 +46,9 @@ class CRainSplashGenerator { std::vector x0_rainSplashes; CRandom16 x10_random = {99}; zeus::CVector3f x14_scale; - float x20_generateTimer = 0.f; - float x24_generateInterval; - float x28_dt = 0.f; + float x20_generateTimer = 0.0f; + float x24_generateInterval = 0.0f; + float x28_dt = 0.0f; float x2c_minZ; float x30_alpha; u32 x34_curPoint = 0; diff --git a/Runtime/Graphics/CSkinnedModel.hpp b/Runtime/Graphics/CSkinnedModel.hpp index cffc1a074..82dbdf89b 100644 --- a/Runtime/Graphics/CSkinnedModel.hpp +++ b/Runtime/Graphics/CSkinnedModel.hpp @@ -6,6 +6,7 @@ #include #include "Runtime/CToken.hpp" +#include "Runtime/Character/CSkinRules.hpp" #include "Runtime/Graphics/CModel.hpp" #include @@ -14,7 +15,6 @@ namespace urde { class CCharLayoutInfo; class CModel; class CPoseAsTransforms; -class CSkinRules; class CVertexMorphEffect; class IObjectStore; @@ -47,7 +47,7 @@ public: const std::optional& morphEffect, const float* morphMagnitudes); void Draw(const CModelFlags& drawFlags) const; - typedef void (*FPointGenerator)(void* item, const std::vector>& vn); + using FPointGenerator = void (*)(void* item, const std::vector>& vn); static void SetPointGeneratorFunc(void* ctx, FPointGenerator func) { g_PointGenFunc = func; g_PointGenCtx = ctx; diff --git a/Runtime/Graphics/IRenderer.hpp b/Runtime/Graphics/IRenderer.hpp index 83c2e9aef..4817183ca 100644 --- a/Runtime/Graphics/IRenderer.hpp +++ b/Runtime/Graphics/IRenderer.hpp @@ -27,7 +27,7 @@ struct SShader; class IRenderer { public: - typedef void (*TDrawableCallback)(const void*, const void*, int); + using TDrawableCallback = void (*)(void*, void*, int); using TReflectionCallback = std::function; enum class EDrawableSorting { SortedCallback, UnsortedCallback }; @@ -35,11 +35,11 @@ public: enum class EPrimitiveType {}; virtual ~IRenderer() = default; - virtual void AddStaticGeometry(const std::vector*, const CAreaRenderOctTree*, int, - const SShader*) = 0; - virtual void EnablePVS(const CPVSVisSet&, u32) = 0; + virtual void AddStaticGeometry(const std::vector* geometry, const CAreaRenderOctTree* octTree, + int areaIdx, const SShader* shaderSet) = 0; + virtual void EnablePVS(const CPVSVisSet& set, u32 areaIdx) = 0; virtual void DisablePVS() = 0; - virtual void RemoveStaticGeometry(const std::vector*) = 0; + virtual void RemoveStaticGeometry(const std::vector* geometry) = 0; virtual void DrawAreaGeometry(int areaIdx, int mask, int targetMask) = 0; virtual void DrawUnsortedGeometry(int areaIdx, int mask, int targetMask, bool shadowRender = false) = 0; virtual void DrawSortedGeometry(int areaIdx, int mask, int targetMask) = 0; @@ -47,17 +47,18 @@ public: virtual void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly) = 0; virtual void PostRenderFogs() = 0; virtual void SetModelMatrix(const zeus::CTransform& xf) = 0; - virtual void AddParticleGen(const CParticleGen&) = 0; - virtual void AddParticleGen(const CParticleGen&, const zeus::CVector3f&, const zeus::CAABox&) = 0; - virtual void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int) = 0; - virtual void AddDrawable(void const*, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting) = 0; - virtual void SetDrawableCallback(TDrawableCallback, const void*) = 0; - virtual void SetWorldViewpoint(const zeus::CTransform&) = 0; - virtual void SetPerspective(float, float, float, float, float) = 0; - virtual void SetPerspective(float, float, float, float) = 0; - virtual std::pair SetViewportOrtho(bool, float, float) = 0; - virtual void SetClippingPlanes(const zeus::CFrustum&) = 0; - virtual void SetViewport(int, int, int, int) = 0; + virtual void AddParticleGen(CParticleGen& gen) = 0; + virtual void AddParticleGen(CParticleGen& gen, const zeus::CVector3f& pos, const zeus::CAABox& bounds) = 0; + virtual void AddPlaneObject(void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, int type) = 0; + virtual void AddDrawable(void* obj, const zeus::CVector3f& pos, const zeus::CAABox& aabb, int mode, + EDrawableSorting sorting) = 0; + virtual void SetDrawableCallback(TDrawableCallback cb, void* ctx) = 0; + virtual void SetWorldViewpoint(const zeus::CTransform& xf) = 0; + virtual void SetPerspective(float fovy, float width, float height, float znear, float zfar) = 0; + virtual void SetPerspective(float fovy, float aspect, float znear, float zfar) = 0; + virtual std::pair SetViewportOrtho(bool centered, float znear, float zfar) = 0; + virtual void SetClippingPlanes(const zeus::CFrustum& frustum) = 0; + virtual void SetViewport(int left, int bottom, int width, int height) = 0; // virtual void SetDepthReadWrite(bool, bool)=0; // virtual void SetBlendMode_AdditiveAlpha()=0; // virtual void SetBlendMode_AlphaBlended()=0; @@ -81,18 +82,18 @@ public: // virtual void PrimColor(float, float, float, float)=0; // virtual void PrimColor(const zeus::CColor&)=0; // virtual void EndPrimitive()=0; - virtual void SetAmbientColor(const zeus::CColor&) = 0; - virtual void DrawString(const char*, int, int) = 0; + virtual void SetAmbientColor(const zeus::CColor& color) = 0; + virtual void DrawString(const char* string, int, int) = 0; virtual u32 GetFPS() = 0; - virtual void CacheReflection(TReflectionCallback, void*, bool) = 0; - virtual void DrawSpaceWarp(const zeus::CVector3f&, float) = 0; - virtual void DrawThermalModel(const CModel&, const zeus::CColor&, const zeus::CColor&) = 0; - virtual void DrawXRayOutline(const zeus::CAABox&) = 0; - virtual void SetWireframeFlags(int) = 0; - virtual void SetWorldFog(ERglFogMode, float, float, const zeus::CColor&) = 0; - virtual void RenderFogVolume(const zeus::CColor&, const zeus::CAABox&, const TLockedToken*, - const CSkinnedModel*) = 0; - virtual void SetThermal(bool, float, const zeus::CColor&) = 0; + virtual void CacheReflection(TReflectionCallback cb, void* ctx, bool clearAfter) = 0; + virtual void DrawSpaceWarp(const zeus::CVector3f& pt, float strength) = 0; + virtual void DrawThermalModel(const CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol) = 0; + virtual void DrawXRayOutline(const zeus::CAABox& aabb) = 0; + virtual void SetWireframeFlags(int flags) = 0; + virtual void SetWorldFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color) = 0; + virtual void RenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, const TLockedToken* model, + const CSkinnedModel* sModel) = 0; + virtual void SetThermal(bool thermal, float level, const zeus::CColor& color) = 0; virtual void SetThermalColdScale(float scale) = 0; virtual void DoThermalBlendCold() = 0; virtual void DoThermalBlendHot() = 0; diff --git a/Runtime/Graphics/Shaders/CAABoxShader.hpp b/Runtime/Graphics/Shaders/CAABoxShader.hpp index 26b6e3096..ff3785fd0 100644 --- a/Runtime/Graphics/Shaders/CAABoxShader.hpp +++ b/Runtime/Graphics/Shaders/CAABoxShader.hpp @@ -24,7 +24,7 @@ class CAABoxShader { public: static void Initialize(); static void Shutdown(); - CAABoxShader(bool zOnly = false); + explicit CAABoxShader(bool zOnly = false); void setAABB(const zeus::CAABox& aabb); void draw(const zeus::CColor& color); }; diff --git a/Runtime/Graphics/Shaders/CColoredQuadFilter.hpp b/Runtime/Graphics/Shaders/CColoredQuadFilter.hpp index e6a61e281..631a4ee68 100644 --- a/Runtime/Graphics/Shaders/CColoredQuadFilter.hpp +++ b/Runtime/Graphics/Shaders/CColoredQuadFilter.hpp @@ -28,8 +28,8 @@ public: static void Initialize(); static void Shutdown(); static const zeus::CRectangle DefaultRect; - CColoredQuadFilter(EFilterType type); - CColoredQuadFilter(EFilterType type, const TLockedToken&) : CColoredQuadFilter(type) {} + explicit CColoredQuadFilter(EFilterType type); + explicit CColoredQuadFilter(EFilterType type, const TLockedToken&) : CColoredQuadFilter(type) {} void draw(const zeus::CColor& color, const zeus::CRectangle& rect = DefaultRect); void DrawFilter(EFilterShape shape, const zeus::CColor& color, float t) { draw(color); } }; @@ -39,8 +39,8 @@ class CWideScreenFilter { CColoredQuadFilter m_bottom; public: - CWideScreenFilter(EFilterType type) : m_top(type), m_bottom(type) {} - CWideScreenFilter(EFilterType type, const TLockedToken&) : CWideScreenFilter(type) {} + explicit CWideScreenFilter(EFilterType type) : m_top(type), m_bottom(type) {} + explicit CWideScreenFilter(EFilterType type, const TLockedToken&) : CWideScreenFilter(type) {} void draw(const zeus::CColor& color, float t); void DrawFilter(EFilterShape shape, const zeus::CColor& color, float t); diff --git a/Runtime/Graphics/Shaders/CFogVolumeFilter.cpp b/Runtime/Graphics/Shaders/CFogVolumeFilter.cpp index 6c27cca8a..7c0c9f344 100644 --- a/Runtime/Graphics/Shaders/CFogVolumeFilter.cpp +++ b/Runtime/Graphics/Shaders/CFogVolumeFilter.cpp @@ -1,5 +1,7 @@ #include "Runtime/Graphics/Shaders/CFogVolumeFilter.hpp" +#include + #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Graphics/CBooRenderer.hpp" #include "Runtime/Graphics/CGraphics.hpp" @@ -28,24 +30,30 @@ CFogVolumeFilter::CFogVolumeFilter() { struct Vert { zeus::CVector2f m_pos; zeus::CVector2f m_uv; - } verts[4] = { + }; + constexpr std::array verts{{ {{-1.0, -1.0}, {0.0, 0.0}}, {{-1.0, 1.0}, {0.0, 1.0}}, {{1.0, -1.0}, {1.0, 0.0}}, {{1.0, 1.0}, {1.0, 1.0}}, - }; - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, sizeof(Vert), 4); + }}; + m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(Vert), verts.size()); m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CColor), 1); - boo::ObjToken texs[] = {CGraphics::g_SpareTexture.get(), CGraphics::g_SpareTexture.get(), - g_Renderer->GetFogRampTex().get()}; - int bindIdxs[] = {0, 1, 0}; - bool bindDepth[] = {true, true, false}; - boo::ObjToken ubufs[] = {m_uniBuf.get()}; + const std::array, 3> texs{ + CGraphics::g_SpareTexture.get(), + CGraphics::g_SpareTexture.get(), + g_Renderer->GetFogRampTex().get(), + }; + constexpr std::array bindIdxs{0, 1, 0}; + constexpr std::array bindDepth{true, true, false}; + const std::array, 1> ubufs{m_uniBuf.get()}; - m_dataBind1Way = ctx.newShaderDataBinding(s_1WayPipeline, m_vbo.get(), nullptr, nullptr, 1, ubufs, nullptr, nullptr, - nullptr, 3, texs, bindIdxs, bindDepth); - m_dataBind2Way = ctx.newShaderDataBinding(s_2WayPipeline, m_vbo.get(), nullptr, nullptr, 1, ubufs, nullptr, nullptr, - nullptr, 3, texs, bindIdxs, bindDepth); + m_dataBind1Way = + ctx.newShaderDataBinding(s_1WayPipeline, m_vbo.get(), nullptr, nullptr, ubufs.size(), ubufs.data(), nullptr, + nullptr, nullptr, texs.size(), texs.data(), bindIdxs.data(), bindDepth.data()); + m_dataBind2Way = + ctx.newShaderDataBinding(s_2WayPipeline, m_vbo.get(), nullptr, nullptr, ubufs.size(), ubufs.data(), nullptr, + nullptr, nullptr, texs.size(), texs.data(), bindIdxs.data(), bindDepth.data()); return true; } BooTrace); } diff --git a/Runtime/Graphics/Shaders/CLineRendererShaders.cpp b/Runtime/Graphics/Shaders/CLineRendererShaders.cpp index 414783b43..00428f1d8 100644 --- a/Runtime/Graphics/Shaders/CLineRendererShaders.cpp +++ b/Runtime/Graphics/Shaders/CLineRendererShaders.cpp @@ -111,7 +111,7 @@ void CLineRendererShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Con const std::array ubufOffs{size_t(ubufInfo.second)}; const std::array ubufSizes{sizeof(CLineRenderer::SDrawUniform)}; - for (size_t i = 0; i < std::size(renderer.m_shaderBind); ++i) { + for (size_t i = 0; i < renderer.m_shaderBind.size(); ++i) { renderer.m_shaderBind[i] = ctx.newShaderDataBinding( (*pipeline)[i], vbufInfo.first.get(), nullptr, nullptr, uniforms.size(), uniforms.data(), stages.data(), ubufOffs.data(), ubufSizes.data(), texCount, textures.data(), nullptr, nullptr, vbufInfo.second); diff --git a/Runtime/Graphics/Shaders/CRandomStaticFilter.hpp b/Runtime/Graphics/Shaders/CRandomStaticFilter.hpp index b48b224c8..858afe2b9 100644 --- a/Runtime/Graphics/Shaders/CRandomStaticFilter.hpp +++ b/Runtime/Graphics/Shaders/CRandomStaticFilter.hpp @@ -26,16 +26,16 @@ class CRandomStaticFilter { public: static void Initialize(); static void Shutdown(); - CRandomStaticFilter(EFilterType type, bool cookieCutter = false); - CRandomStaticFilter(EFilterType type, const TLockedToken&) : CRandomStaticFilter(type) {} + explicit CRandomStaticFilter(EFilterType type, bool cookieCutter = false); + explicit CRandomStaticFilter(EFilterType type, const TLockedToken&) : CRandomStaticFilter(type) {} void draw(const zeus::CColor& color, float t); void DrawFilter(EFilterShape, const zeus::CColor& color, float t) { draw(color, t); } }; class CCookieCutterDepthRandomStaticFilter : public CRandomStaticFilter { public: - CCookieCutterDepthRandomStaticFilter(EFilterType type) : CRandomStaticFilter(type, true) {} - CCookieCutterDepthRandomStaticFilter(EFilterType type, const TLockedToken&) + explicit CCookieCutterDepthRandomStaticFilter(EFilterType type) : CRandomStaticFilter(type, true) {} + explicit CCookieCutterDepthRandomStaticFilter(EFilterType type, const TLockedToken&) : CCookieCutterDepthRandomStaticFilter(type) {} }; diff --git a/Runtime/Graphics/Shaders/CScanLinesFilter.hpp b/Runtime/Graphics/Shaders/CScanLinesFilter.hpp index a789d957a..fd20fc785 100644 --- a/Runtime/Graphics/Shaders/CScanLinesFilter.hpp +++ b/Runtime/Graphics/Shaders/CScanLinesFilter.hpp @@ -23,21 +23,21 @@ class CScanLinesFilter { public: static void Initialize(); static void Shutdown(); - CScanLinesFilter(EFilterType type, bool even); + explicit CScanLinesFilter(EFilterType type, bool even); void draw(const zeus::CColor& color); void DrawFilter(EFilterShape, const zeus::CColor& color, float) { draw(color); } }; class CScanLinesFilterEven : public CScanLinesFilter { public: - CScanLinesFilterEven(EFilterType type) : CScanLinesFilter(type, true) {} - CScanLinesFilterEven(EFilterType type, const TLockedToken&) : CScanLinesFilterEven(type) {} + explicit CScanLinesFilterEven(EFilterType type) : CScanLinesFilter(type, true) {} + explicit CScanLinesFilterEven(EFilterType type, const TLockedToken&) : CScanLinesFilterEven(type) {} }; class CScanLinesFilterOdd : public CScanLinesFilter { public: - CScanLinesFilterOdd(EFilterType type) : CScanLinesFilter(type, false) {} - CScanLinesFilterOdd(EFilterType type, const TLockedToken&) : CScanLinesFilterOdd(type) {} + explicit CScanLinesFilterOdd(EFilterType type) : CScanLinesFilter(type, false) {} + explicit CScanLinesFilterOdd(EFilterType type, const TLockedToken&) : CScanLinesFilterOdd(type) {} }; } // namespace urde diff --git a/Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp b/Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp index 9a96f973d..a035394e5 100644 --- a/Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp +++ b/Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp @@ -35,7 +35,7 @@ protected: ZTest m_zTest; bool m_flipRect = false; - CTexturedQuadFilter(const boo::ObjToken& tex); + explicit CTexturedQuadFilter(const boo::ObjToken& tex); public: struct Vert { @@ -45,8 +45,8 @@ public: static void Initialize(); static void Shutdown(); static const zeus::CRectangle DefaultRect; - CTexturedQuadFilter(EFilterType type, TLockedToken tex, ZTest zTest = ZTest::None); - CTexturedQuadFilter(EFilterType type, const boo::ObjToken& tex, ZTest zTest = ZTest::None); + explicit CTexturedQuadFilter(EFilterType type, TLockedToken tex, ZTest zTest = ZTest::None); + explicit CTexturedQuadFilter(EFilterType type, const boo::ObjToken& tex, ZTest zTest = ZTest::None); CTexturedQuadFilter(const CTexturedQuadFilter&) = delete; CTexturedQuadFilter& operator=(const CTexturedQuadFilter&) = delete; CTexturedQuadFilter(CTexturedQuadFilter&&) = default; @@ -63,8 +63,8 @@ class CTexturedQuadFilterAlpha : public CTexturedQuadFilter { public: static void Initialize(); static void Shutdown(); - CTexturedQuadFilterAlpha(EFilterType type, TLockedToken tex); - CTexturedQuadFilterAlpha(EFilterType type, const boo::ObjToken& tex); + explicit CTexturedQuadFilterAlpha(EFilterType type, TLockedToken tex); + explicit CTexturedQuadFilterAlpha(EFilterType type, const boo::ObjToken& tex); }; } // namespace urde diff --git a/Runtime/Graphics/Shaders/CWorldShadowShader.hpp b/Runtime/Graphics/Shaders/CWorldShadowShader.hpp index 0e0c189b6..b63708481 100644 --- a/Runtime/Graphics/Shaders/CWorldShadowShader.hpp +++ b/Runtime/Graphics/Shaders/CWorldShadowShader.hpp @@ -30,7 +30,7 @@ class CWorldShadowShader { public: static void Initialize(); static void Shutdown(); - CWorldShadowShader(u32 w, u32 h); + explicit CWorldShadowShader(u32 w, u32 h); void bindRenderTarget(); void drawBase(float extent); void lightenShadow(); diff --git a/Runtime/Graphics/Shaders/CXRayBlurFilter.hpp b/Runtime/Graphics/Shaders/CXRayBlurFilter.hpp index 35b08d986..704f9b235 100644 --- a/Runtime/Graphics/Shaders/CXRayBlurFilter.hpp +++ b/Runtime/Graphics/Shaders/CXRayBlurFilter.hpp @@ -24,7 +24,7 @@ class CXRayBlurFilter { public: static void Initialize(); static void Shutdown(); - CXRayBlurFilter(TLockedToken& tex); + explicit CXRayBlurFilter(TLockedToken& tex); void draw(float amount); }; diff --git a/Runtime/GuiSys/CAuiEnergyBarT01.cpp b/Runtime/GuiSys/CAuiEnergyBarT01.cpp index f73b08bca..4da50045c 100644 --- a/Runtime/GuiSys/CAuiEnergyBarT01.cpp +++ b/Runtime/GuiSys/CAuiEnergyBarT01.cpp @@ -53,16 +53,17 @@ void CAuiEnergyBarT01::Update(float dt) { CGuiWidget::Update(dt); } -void CAuiEnergyBarT01::Draw(const CGuiWidgetDrawParms& drawParms) const { - if (!xbc_tex || !xbc_tex.IsLoaded() || !xd8_coordFunc) +void CAuiEnergyBarT01::Draw(const CGuiWidgetDrawParms& drawParms) { + if (!xbc_tex || !xbc_tex.IsLoaded() || !xd8_coordFunc) { return; + } SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(fmt("CAuiEnergyBarT01::Draw {}"), m_name).c_str(), zeus::skCyan); CGraphics::SetModelMatrix(x34_worldXF); - const_cast(m_energyBarShader).updateModelMatrix(); + m_energyBarShader.updateModelMatrix(); - float filledT = xe0_maxEnergy > 0.f ? xf8_filledEnergy / xe0_maxEnergy : 0.f; - float shadowT = xe0_maxEnergy > 0.f ? xfc_shadowEnergy / xe0_maxEnergy : 0.f; + const float filledT = xe0_maxEnergy > 0.f ? xf8_filledEnergy / xe0_maxEnergy : 0.f; + const float shadowT = xe0_maxEnergy > 0.f ? xfc_shadowEnergy / xe0_maxEnergy : 0.f; zeus::CColor filledColor = xd0_filledColor; filledColor.a() *= drawParms.x0_alphaMod; @@ -76,8 +77,8 @@ void CAuiEnergyBarT01::Draw(const CGuiWidgetDrawParms& drawParms) const { emptyColor.a() *= drawParms.x0_alphaMod; emptyColor *= xa8_color2; - for (int i = 0; i < 3; ++i) { - std::vector& verts = const_cast(*this).m_verts[i]; + for (size_t i = 0; i < m_verts.size(); ++i) { + std::vector& verts = m_verts[i]; verts.clear(); float start; @@ -98,8 +99,9 @@ void CAuiEnergyBarT01::Draw(const CGuiWidgetDrawParms& drawParms) const { break; } - if (start == end) + if (start == end) { continue; + } std::pair coords = xd8_coordFunc(start); while (start < end) { @@ -116,8 +118,7 @@ void CAuiEnergyBarT01::Draw(const CGuiWidgetDrawParms& drawParms) const { } } - const_cast(m_energyBarShader) - .draw(filledColor, m_verts[0], shadowColor, m_verts[1], emptyColor, m_verts[2], xbc_tex.GetObj()); + m_energyBarShader.draw(filledColor, m_verts[0], shadowColor, m_verts[1], emptyColor, m_verts[2], xbc_tex.GetObj()); } void CAuiEnergyBarT01::SetCurrEnergy(float e, ESetMode mode) { diff --git a/Runtime/GuiSys/CAuiEnergyBarT01.hpp b/Runtime/GuiSys/CAuiEnergyBarT01.hpp index 3c46af65e..6fca40fba 100644 --- a/Runtime/GuiSys/CAuiEnergyBarT01.hpp +++ b/Runtime/GuiSys/CAuiEnergyBarT01.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -16,7 +17,7 @@ class CSimplePool; class CAuiEnergyBarT01 : public CGuiWidget { public: - typedef std::pair (*FCoordFunc)(float t); + using FCoordFunc = std::pair (*)(float t); enum class ESetMode { Normal, Wrapped, Insta }; private: @@ -38,14 +39,14 @@ private: float xfc_shadowEnergy = 0.f; float x100_shadowDrainDelayTimer = 0.f; CEnergyBarShader m_energyBarShader; - std::vector m_verts[3]; + std::array, 3> m_verts; public: CAuiEnergyBarT01(const CGuiWidgetParms& parms, CSimplePool* sp, CAssetId txtrId); FourCC GetWidgetTypeID() const override { return FOURCC('ENRG'); } static std::pair DownloadBarCoordFunc(float t); void Update(float dt) override; - void Draw(const CGuiWidgetDrawParms& drawParms) const override; + void Draw(const CGuiWidgetDrawParms& drawParms) override; float GetActualFraction() const { return xe0_maxEnergy == 0.f ? 0.f : xf4_setEnergy / xe0_maxEnergy; } float GetSetEnergy() const { return xf4_setEnergy; } float GetMaxEnergy() const { return xe0_maxEnergy; } diff --git a/Runtime/GuiSys/CAuiImagePane.cpp b/Runtime/GuiSys/CAuiImagePane.cpp index 027b15306..996e1ad4f 100644 --- a/Runtime/GuiSys/CAuiImagePane.cpp +++ b/Runtime/GuiSys/CAuiImagePane.cpp @@ -54,9 +54,9 @@ void CAuiImagePane::Update(float dt) { CAuiImagePane::Filters::Filters(TLockedToken& tex) : m_texId(tex.GetObjectTag()->id) , m_darkenerQuad(EFilterType::Blend, tex) -, m_flashQuad{{EFilterType::Add, tex}, {EFilterType::Add, tex}} -, m_alphaQuad{{EFilterType::Blend, tex}, {EFilterType::Blend, tex}} -, m_addQuad{{EFilterType::Add, tex}, {EFilterType::Add, tex}} {} +, m_flashQuad{{CTexturedQuadFilterAlpha{EFilterType::Add, tex}, CTexturedQuadFilterAlpha{EFilterType::Add, tex}}} +, m_alphaQuad{{CTexturedQuadFilterAlpha{EFilterType::Blend, tex}, CTexturedQuadFilterAlpha{EFilterType::Blend, tex}}} +, m_addQuad{{CTexturedQuadFilterAlpha{EFilterType::Add, tex}, CTexturedQuadFilterAlpha{EFilterType::Add, tex}}} {} void CAuiImagePane::DoDrawImagePane(const zeus::CColor& color, const CTexture& tex, int frame, float alpha, bool noBlur, CTexturedQuadFilterAlpha& quad) const { @@ -66,13 +66,13 @@ void CAuiImagePane::DoDrawImagePane(const zeus::CColor& color, const CTexture& t rstl::reserved_vector vec; const rstl::reserved_vector* useUVs; if (x138_tileSize != zeus::skZero2f) { - zeus::CVector2f res(xb8_tex0Tok->GetWidth(), xb8_tex0Tok->GetHeight()); - zeus::CVector2f tmp = res / x138_tileSize; - zeus::CVector2f tmpRecip = x138_tileSize / res; - float x0 = tmpRecip.x() * (frame % int(tmp.x())); - float x1 = x0 + tmpRecip.x(); - float y0 = tmpRecip.y() * (frame % int(tmp.y())); - float y1 = y0 + tmpRecip.y(); + const zeus::CVector2f res(xb8_tex0Tok->GetWidth(), xb8_tex0Tok->GetHeight()); + const zeus::CVector2f tmp = res / x138_tileSize; + const zeus::CVector2f tmpRecip = x138_tileSize / res; + const float x0 = tmpRecip.x() * (frame % int(tmp.x())); + const float x1 = x0 + tmpRecip.x(); + const float y0 = tmpRecip.y() * (frame % int(tmp.y())); + const float y1 = y0 + tmpRecip.y(); vec.push_back(zeus::CVector2f(x0, y0)); vec.push_back(zeus::CVector2f(x0, y1)); vec.push_back(zeus::CVector2f(x1, y0)); @@ -82,32 +82,36 @@ void CAuiImagePane::DoDrawImagePane(const zeus::CColor& color, const CTexture& t useUVs = &x114_uvs; } - CTexturedQuadFilter::Vert verts[] = {{xe0_coords[0], (*useUVs)[0] + xd0_uvBias0}, - {xe0_coords[1], (*useUVs)[1] + xd0_uvBias0}, - {xe0_coords[3], (*useUVs)[3] + xd0_uvBias0}, - {xe0_coords[2], (*useUVs)[2] + xd0_uvBias0}}; + const std::array verts{{ + {xe0_coords[0], (*useUVs)[0] + xd0_uvBias0}, + {xe0_coords[1], (*useUVs)[1] + xd0_uvBias0}, + {xe0_coords[3], (*useUVs)[3] + xd0_uvBias0}, + {xe0_coords[2], (*useUVs)[2] + xd0_uvBias0}, + }}; if (noBlur) { - quad.drawVerts(useColor, verts); + quad.drawVerts(useColor, verts.data()); } else if ((x14c_deResFactor == 0.f && alpha == 1.f) || tex.GetNumMips() == 1) { - quad.drawVerts(useColor, verts, 0.f); + quad.drawVerts(useColor, verts.data(), 0.f); } else { - float tmp = (1.f - x14c_deResFactor) * alpha; - float tmp3 = 1.f - tmp * tmp * tmp; - float mip = tmp3 * (tex.GetNumMips() - 1); - quad.drawVerts(useColor, verts, mip); + const float tmp = (1.f - x14c_deResFactor) * alpha; + const float tmp3 = 1.f - tmp * tmp * tmp; + const float mip = tmp3 * (tex.GetNumMips() - 1); + quad.drawVerts(useColor, verts.data(), mip); } } -void CAuiImagePane::Draw(const CGuiWidgetDrawParms& params) const { +void CAuiImagePane::Draw(const CGuiWidgetDrawParms& params) { CGraphics::SetModelMatrix(x34_worldXF); - if (!GetIsVisible() || !xb8_tex0Tok.IsLoaded()) + if (!GetIsVisible() || !xb8_tex0Tok.IsLoaded()) { return; + } SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(fmt("CAuiImagePane::Draw {}"), m_name).c_str(), zeus::skCyan); GetIsFinishedLoadingWidgetSpecific(); - if (!m_filters || m_filters->m_texId != xb8_tex0Tok.GetObjectTag()->id) - const_cast(this)->m_filters.emplace(const_cast(this)->xb8_tex0Tok); - Filters& filters = const_cast(*m_filters); + if (!m_filters || m_filters->m_texId != xb8_tex0Tok.GetObjectTag()->id) { + m_filters.emplace(xb8_tex0Tok); + } + Filters& filters = *m_filters; zeus::CColor color = xa8_color2; color.a() *= params.x0_alphaMod; // SetZUpdate(xac_drawFlags == EGuiModelDrawFlags::Shadeless || xac_drawFlags == EGuiModelDrawFlags::Opaque); @@ -172,7 +176,7 @@ void CAuiImagePane::Draw(const CGuiWidgetDrawParms& params) const { } } -bool CAuiImagePane::GetIsFinishedLoadingWidgetSpecific() const { return !xb8_tex0Tok || xb8_tex0Tok.IsLoaded(); } +bool CAuiImagePane::GetIsFinishedLoadingWidgetSpecific() { return !xb8_tex0Tok || xb8_tex0Tok.IsLoaded(); } void CAuiImagePane::SetTextureID0(CAssetId tex, CSimplePool* sp) { xc8_tex0 = tex; diff --git a/Runtime/GuiSys/CAuiImagePane.hpp b/Runtime/GuiSys/CAuiImagePane.hpp index 528a83417..bf99786ad 100644 --- a/Runtime/GuiSys/CAuiImagePane.hpp +++ b/Runtime/GuiSys/CAuiImagePane.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "Runtime/CToken.hpp" #include "Runtime/rstl.hpp" #include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp" @@ -33,10 +35,10 @@ class CAuiImagePane : public CGuiWidget { struct Filters { CAssetId m_texId; CTexturedQuadFilterAlpha m_darkenerQuad; - CTexturedQuadFilterAlpha m_flashQuad[2]; - CTexturedQuadFilterAlpha m_alphaQuad[2]; - CTexturedQuadFilterAlpha m_addQuad[2]; - Filters(TLockedToken& tex); + std::array m_flashQuad; + std::array m_alphaQuad; + std::array m_addQuad; + explicit Filters(TLockedToken& tex); }; std::optional m_filters; void DoDrawImagePane(const zeus::CColor& color, const CTexture& tex, int frame, float blurAmt, bool noBlur, @@ -51,8 +53,8 @@ public: void Reset(ETraversalMode mode) override; void Update(float dt) override; - void Draw(const CGuiWidgetDrawParms& params) const override; - bool GetIsFinishedLoadingWidgetSpecific() const override; + void Draw(const CGuiWidgetDrawParms& params) override; + bool GetIsFinishedLoadingWidgetSpecific() override; void SetTextureID0(CAssetId tex, CSimplePool* sp); void SetAnimationParms(const zeus::CVector2f& vec, float interval, float duration); void SetDeResFactor(float d) { x14c_deResFactor = d; } diff --git a/Runtime/GuiSys/CCompoundTargetReticle.hpp b/Runtime/GuiSys/CCompoundTargetReticle.hpp index 06a6987a5..e1df8b7e0 100644 --- a/Runtime/GuiSys/CCompoundTargetReticle.hpp +++ b/Runtime/GuiSys/CCompoundTargetReticle.hpp @@ -59,7 +59,7 @@ public: float x10_rotAng = 0.f; float x14_baseAngle = 0.f; float x18_offshootAngleDelta = 0.f; - SOuterItemInfo(std::string_view); + explicit SOuterItemInfo(std::string_view); }; private: @@ -135,7 +135,7 @@ private: bool zEqual) const; public: - CCompoundTargetReticle(const CStateManager&); + explicit CCompoundTargetReticle(const CStateManager&); void SetLeadingOrientation(const zeus::CQuaternion& o) { x0_leadingOrientation = o; } bool CheckLoadComplete() { return true; } diff --git a/Runtime/GuiSys/CConsoleOutputWindow.cpp b/Runtime/GuiSys/CConsoleOutputWindow.cpp index 6348d0efe..f010c5de3 100644 --- a/Runtime/GuiSys/CConsoleOutputWindow.cpp +++ b/Runtime/GuiSys/CConsoleOutputWindow.cpp @@ -9,7 +9,7 @@ CIOWin::EMessageReturn CConsoleOutputWindow::OnMessage(const CArchitectureMessag return EMessageReturn::Normal; } -void CConsoleOutputWindow::Draw() const { +void CConsoleOutputWindow::Draw() { //SCOPED_GRAPHICS_DEBUG_GROUP("CConsoleOutputWindow::Draw", zeus::skGreen); } diff --git a/Runtime/GuiSys/CConsoleOutputWindow.hpp b/Runtime/GuiSys/CConsoleOutputWindow.hpp index 65fc0f862..40a8bb69f 100644 --- a/Runtime/GuiSys/CConsoleOutputWindow.hpp +++ b/Runtime/GuiSys/CConsoleOutputWindow.hpp @@ -8,7 +8,7 @@ class CConsoleOutputWindow : public CIOWin { public: CConsoleOutputWindow(int, float, float); EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&) override; - void Draw() const override; + void Draw() override; }; } // namespace urde diff --git a/Runtime/GuiSys/CDrawStringOptions.hpp b/Runtime/GuiSys/CDrawStringOptions.hpp index 43523df2f..749aa2882 100644 --- a/Runtime/GuiSys/CDrawStringOptions.hpp +++ b/Runtime/GuiSys/CDrawStringOptions.hpp @@ -18,7 +18,7 @@ class CDrawStringOptions { std::vector x4_colors; public: - CDrawStringOptions() { x4_colors.resize(16); } + CDrawStringOptions() : x4_colors(16) {} }; } // namespace urde diff --git a/Runtime/GuiSys/CErrorOutputWindow.cpp b/Runtime/GuiSys/CErrorOutputWindow.cpp index 4877135c7..04596dd20 100644 --- a/Runtime/GuiSys/CErrorOutputWindow.cpp +++ b/Runtime/GuiSys/CErrorOutputWindow.cpp @@ -15,7 +15,7 @@ CIOWin::EMessageReturn CErrorOutputWindow::OnMessage(const CArchitectureMessage& return EMessageReturn::Normal; } -void CErrorOutputWindow::Draw() const { +void CErrorOutputWindow::Draw() { //SCOPED_GRAPHICS_DEBUG_GROUP("CErrorOutputWindow::Draw", zeus::skGreen); } diff --git a/Runtime/GuiSys/CErrorOutputWindow.hpp b/Runtime/GuiSys/CErrorOutputWindow.hpp index 2189d77d2..85b2231d6 100644 --- a/Runtime/GuiSys/CErrorOutputWindow.hpp +++ b/Runtime/GuiSys/CErrorOutputWindow.hpp @@ -24,10 +24,10 @@ private: const wchar_t* x1c_msg; public: - CErrorOutputWindow(bool); + explicit CErrorOutputWindow(bool); EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&) override; bool GetIsContinueDraw() const override { return int(x14_state) < 2; } - void Draw() const override; + void Draw() override; }; } // namespace urde diff --git a/Runtime/GuiSys/CFontImageDef.cpp b/Runtime/GuiSys/CFontImageDef.cpp index 6cabc6d3c..e20b52403 100644 --- a/Runtime/GuiSys/CFontImageDef.cpp +++ b/Runtime/GuiSys/CFontImageDef.cpp @@ -8,13 +8,14 @@ CFontImageDef::CFontImageDef(const std::vector>& texs, float in const zeus::CVector2f& cropFactor) : x0_fps(interval), x14_cropFactor(cropFactor) { x4_texs.reserve(texs.size()); - for (const TToken& tok : texs) - x4_texs.push_back(tok); + for (const TToken& tok : texs) { + x4_texs.emplace_back(tok); + } } CFontImageDef::CFontImageDef(const TToken& tex, const zeus::CVector2f& cropFactor) : x0_fps(0.f), x14_cropFactor(cropFactor) { - x4_texs.push_back(tex); + x4_texs.emplace_back(tex); } bool CFontImageDef::IsLoaded() const { diff --git a/Runtime/GuiSys/CGuiCamera.cpp b/Runtime/GuiSys/CGuiCamera.cpp index 99354dce7..521fd7134 100644 --- a/Runtime/GuiSys/CGuiCamera.cpp +++ b/Runtime/GuiSys/CGuiCamera.cpp @@ -24,12 +24,13 @@ zeus::CVector3f CGuiCamera::ConvertToScreenSpace(const zeus::CVector3f& vec) con return mat.multiplyOneOverW(local); } -void CGuiCamera::Draw(const CGuiWidgetDrawParms& parms) const { - if (xb8_projtype == EProjection::Perspective) +void CGuiCamera::Draw(const CGuiWidgetDrawParms& parms) { + if (xb8_projtype == EProjection::Perspective) { CGraphics::SetPerspective(m_proj.xbc_fov, m_proj.xc0_aspect, m_proj.xc4_znear, m_proj.xc8_zfar); - else + } else { CGraphics::SetOrtho(m_proj.xbc_left, m_proj.xc0_right, m_proj.xc4_top, m_proj.xc8_bottom, m_proj.xcc_znear, m_proj.xd0_zfar); + } CGraphics::SetViewPointMatrix(GetGuiFrame()->GetAspectTransform() * zeus::CTransform::Translate(parms.x4_cameraOffset) * x34_worldXF); CGuiWidget::Draw(parms); diff --git a/Runtime/GuiSys/CGuiCamera.hpp b/Runtime/GuiSys/CGuiCamera.hpp index 053041699..824a55c7e 100644 --- a/Runtime/GuiSys/CGuiCamera.hpp +++ b/Runtime/GuiSys/CGuiCamera.hpp @@ -46,7 +46,7 @@ public: zeus::CVector3f ConvertToScreenSpace(const zeus::CVector3f& vec) const; const SProjection& GetProjection() const { return m_proj; } void SetFov(float fov) { m_proj.xbc_fov = fov; } - void Draw(const CGuiWidgetDrawParms& parms) const override; + void Draw(const CGuiWidgetDrawParms& parms) override; std::shared_ptr shared_from_this() { return std::static_pointer_cast(CGuiObject::shared_from_this()); diff --git a/Runtime/GuiSys/CGuiCompoundWidget.hpp b/Runtime/GuiSys/CGuiCompoundWidget.hpp index 9eaac99c4..97752f7fe 100644 --- a/Runtime/GuiSys/CGuiCompoundWidget.hpp +++ b/Runtime/GuiSys/CGuiCompoundWidget.hpp @@ -6,7 +6,7 @@ namespace urde { class CGuiCompoundWidget : public CGuiWidget { public: - CGuiCompoundWidget(const CGuiWidgetParms& parms); + explicit CGuiCompoundWidget(const CGuiWidgetParms& parms); FourCC GetWidgetTypeID() const override { return FourCC(-1); } void OnVisibleChange() override; diff --git a/Runtime/GuiSys/CGuiFrame.cpp b/Runtime/GuiSys/CGuiFrame.cpp index 52209eefe..1b1dd1329 100644 --- a/Runtime/GuiSys/CGuiFrame.cpp +++ b/Runtime/GuiSys/CGuiFrame.cpp @@ -107,7 +107,7 @@ bool CGuiFrame::GetIsFinishedLoading() const { continue; return false; } - const_cast(this)->x58_24_loaded = true; + x58_24_loaded = true; return true; } diff --git a/Runtime/GuiSys/CGuiFrame.hpp b/Runtime/GuiSys/CGuiFrame.hpp index bae374734..a5c49d2b1 100644 --- a/Runtime/GuiSys/CGuiFrame.hpp +++ b/Runtime/GuiSys/CGuiFrame.hpp @@ -41,7 +41,7 @@ private: int x4c_a; int x50_b; int x54_c; - bool x58_24_loaded : 1; + mutable bool x58_24_loaded : 1; zeus::CTransform m_aspectTransform; float m_aspectConstraint = -1.f; diff --git a/Runtime/GuiSys/CGuiHeadWidget.hpp b/Runtime/GuiSys/CGuiHeadWidget.hpp index 46abbac73..cd710fe2c 100644 --- a/Runtime/GuiSys/CGuiHeadWidget.hpp +++ b/Runtime/GuiSys/CGuiHeadWidget.hpp @@ -7,7 +7,7 @@ namespace urde { class CGuiHeadWidget : public CGuiWidget { public: FourCC GetWidgetTypeID() const override { return FOURCC('HWIG'); } - CGuiHeadWidget(const CGuiWidgetParms& parms); + explicit CGuiHeadWidget(const CGuiWidgetParms& parms); static std::shared_ptr Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp); std::shared_ptr shared_from_this() { diff --git a/Runtime/GuiSys/CGuiModel.cpp b/Runtime/GuiSys/CGuiModel.cpp index 07a0f992a..5a3846514 100644 --- a/Runtime/GuiSys/CGuiModel.cpp +++ b/Runtime/GuiSys/CGuiModel.cpp @@ -16,36 +16,45 @@ CGuiModel::CGuiModel(const CGuiWidgetParms& parms, CSimplePool* sp, CAssetId mod xb8_model = sp->GetObj({SBIG('CMDL'), modelId}); } -bool CGuiModel::GetIsFinishedLoadingWidgetSpecific() const { - if (!xb8_model) +bool CGuiModel::GetIsFinishedLoadingWidgetSpecific() { + if (!xb8_model) { return true; - if (!xb8_model.IsLoaded()) + } + if (!xb8_model.IsLoaded()) { return false; + } xb8_model->GetInstance().Touch(0); return xb8_model->IsLoaded(0); } -void CGuiModel::Touch() const { - const CModel* model = xb8_model.GetObj(); - if (model) - model->GetInstance().Touch(0); +void CGuiModel::Touch() { + CModel* const model = xb8_model.GetObj(); + + if (model == nullptr) { + return; + } + + model->GetInstance().Touch(0); } -void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) const { +void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) { CGraphics::SetModelMatrix(x34_worldXF); - if (!xb8_model) + if (!xb8_model) { return; - if (!GetIsFinishedLoading()) + } + if (!GetIsFinishedLoading()) { return; - const CModel* model = xb8_model.GetObj(); - if (!model) + } + CModel* const model = xb8_model.GetObj(); + if (!model) { return; + } if (GetIsVisible()) { SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(fmt("CGuiModel::Draw {}"), m_name).c_str(), zeus::skCyan); zeus::CColor moduCol = xa8_color2; moduCol.a() *= parms.x0_alphaMod; - xb0_frame->EnableLights(xcc_lightMask, const_cast(model->GetInstance())); + xb0_frame->EnableLights(xcc_lightMask, model->GetInstance()); // if (xb6_29_cullFaces) // CGraphics::SetCullMode(ERglCullMode::Front); diff --git a/Runtime/GuiSys/CGuiModel.hpp b/Runtime/GuiSys/CGuiModel.hpp index 0174ffd9c..024c9ba25 100644 --- a/Runtime/GuiSys/CGuiModel.hpp +++ b/Runtime/GuiSys/CGuiModel.hpp @@ -20,9 +20,9 @@ public: std::vector GetModelAssets() const { return {xc8_modelId}; } const TLockedToken& GetModel() const { return xb8_model; } - bool GetIsFinishedLoadingWidgetSpecific() const override; - void Touch() const override; - void Draw(const CGuiWidgetDrawParms& parms) const override; + bool GetIsFinishedLoadingWidgetSpecific() override; + void Touch() override; + void Draw(const CGuiWidgetDrawParms& parms) override; bool TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const override; static std::shared_ptr Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp); diff --git a/Runtime/GuiSys/CGuiObject.cpp b/Runtime/GuiSys/CGuiObject.cpp index a0f27fb11..c1af552e9 100644 --- a/Runtime/GuiSys/CGuiObject.cpp +++ b/Runtime/GuiSys/CGuiObject.cpp @@ -14,7 +14,7 @@ void CGuiObject::Update(float dt) { x6c_nextSibling->Update(dt); } -void CGuiObject::Draw(const CGuiWidgetDrawParms& parms) const { +void CGuiObject::Draw(const CGuiWidgetDrawParms& parms) { if (x68_child) x68_child->Draw(parms); if (x6c_nextSibling) diff --git a/Runtime/GuiSys/CGuiObject.hpp b/Runtime/GuiSys/CGuiObject.hpp index 06d7b2d11..298cd756d 100644 --- a/Runtime/GuiSys/CGuiObject.hpp +++ b/Runtime/GuiSys/CGuiObject.hpp @@ -21,7 +21,7 @@ protected: public: virtual ~CGuiObject() = default; virtual void Update(float dt); - virtual void Draw(const CGuiWidgetDrawParms& parms) const; + virtual void Draw(const CGuiWidgetDrawParms& parms); virtual bool TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const { return false; } virtual void Initialize() = 0; diff --git a/Runtime/GuiSys/CGuiSliderGroup.hpp b/Runtime/GuiSys/CGuiSliderGroup.hpp index f8a20235a..3c13f783b 100644 --- a/Runtime/GuiSys/CGuiSliderGroup.hpp +++ b/Runtime/GuiSys/CGuiSliderGroup.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -18,7 +19,7 @@ private: float xc0_roundedCurVal; float xc4_curVal; float xc8_increment; - CGuiWidget* xcc_sliderRangeWidgets[2] = {}; + std::array xcc_sliderRangeWidgets{}; std::function xd8_changeCallback; EState xf0_state = EState::None; union { diff --git a/Runtime/GuiSys/CGuiTextPane.cpp b/Runtime/GuiSys/CGuiTextPane.cpp index 3a54fad6d..681b89cf7 100644 --- a/Runtime/GuiSys/CGuiTextPane.cpp +++ b/Runtime/GuiSys/CGuiTextPane.cpp @@ -1,5 +1,7 @@ #include "Runtime/GuiSys/CGuiTextPane.hpp" +#include + #include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/Graphics/CGraphicsPalette.hpp" #include "Runtime/GuiSys/CFontImageDef.hpp" @@ -8,6 +10,19 @@ #include "Runtime/GuiSys/CGuiWidgetDrawParms.hpp" namespace urde { +namespace { +constexpr std::array NormalPoints{{ + {0.f, 0.f, -1.f}, + {1.f, 0.f, -1.f}, + {1.f, 0.f, 0.f}, + {0.f, 0.f, 0.f}, +}}; + +bool testProjectedLine(const zeus::CVector2f& a, const zeus::CVector2f& b, const zeus::CVector2f& point) { + const zeus::CVector2f normal = (b - a).perpendicularVector().normalized(); + return point.dot(normal) >= a.dot(normal); +} +} // Anonymous namespace CGuiTextPane::CGuiTextPane(const CGuiWidgetParms& parms, CSimplePool* sp, const zeus::CVector2f& dim, const zeus::CVector3f& vec, CAssetId fontId, const CGuiTextProperties& props, @@ -20,7 +35,7 @@ void CGuiTextPane::Update(float dt) { xd4_textSupport.Update(dt); } -bool CGuiTextPane::GetIsFinishedLoadingWidgetSpecific() const { +bool CGuiTextPane::GetIsFinishedLoadingWidgetSpecific() { return xd4_textSupport.GetIsTextSupportFinishedLoading(); } @@ -32,30 +47,33 @@ void CGuiTextPane::SetDimensions(const zeus::CVector2f& dim, bool initVBO) { void CGuiTextPane::ScaleDimensions(const zeus::CVector3f& scale) {} -void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) const { - if (!GetIsVisible()) +void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) { + if (!GetIsVisible()) { return; + } SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(fmt("CGuiTextPane::Draw {}"), m_name).c_str(), zeus::skCyan); zeus::CVector2f dims = GetDimensions(); - if (xd4_textSupport.x34_extentX) + if (xd4_textSupport.x34_extentX) { dims.x() /= float(xd4_textSupport.x34_extentX); - else + } else { dims.x() = 0.f; + } - if (xd4_textSupport.x38_extentY) + if (xd4_textSupport.x38_extentY) { dims.y() /= float(xd4_textSupport.x38_extentY); - else + } else { dims.y() = 0.f; + } - zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front().m_pos + xc8_scaleCenter) * - zeus::CTransform::Scale(dims.x(), 1.f, dims.y()); + const zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front().m_pos + xc8_scaleCenter) * + zeus::CTransform::Scale(dims.x(), 1.f, dims.y()); CGraphics::SetModelMatrix(x34_worldXF * local); zeus::CColor geomCol = xa8_color2; geomCol.a() *= parms.x0_alphaMod; - const_cast(this)->xd4_textSupport.SetGeometryColor(geomCol); + xd4_textSupport.SetGeometryColor(geomCol); #if 0 CGraphics::SetDepthWriteMode(xb6_31_depthTest, ERglEnum::LEqual, xb7_24_depthWrite); @@ -82,8 +100,7 @@ void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) const { CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear); xd4_textSupport.Render(); - const_cast(this)->xd4_textSupport.SetGeometryColor - (geomCol * zeus::CColor(geomCol.a, geomCol.a, geomCol.a, 1.f)); + xd4_textSupport.SetGeometryColor(geomCol * zeus::CColor(geomCol.a, geomCol.a, geomCol.a, 1.f)); CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One, ERglBlendFactor::One, ERglLogicOp::Clear); xd4_textSupport.Render(); @@ -94,32 +111,22 @@ void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) const { #endif } -static const zeus::CVector3f NormalPoints[] = { - {0.f, 0.f, -1.f}, - {1.f, 0.f, -1.f}, - {1.f, 0.f, 0.f}, - {0.f, 0.f, 0.f} -}; - -static bool testProjectedLine(const zeus::CVector2f& a, const zeus::CVector2f& b, const zeus::CVector2f& point) { - zeus::CVector2f normal = (b - a).perpendicularVector().normalized(); - return point.dot(normal) >= a.dot(normal); -} - bool CGuiTextPane::TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const { - zeus::CVector2f dims = GetDimensions(); - zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front().m_pos + xc8_scaleCenter) * - zeus::CTransform::Scale(dims.x(), 1.f, dims.y()); - zeus::CMatrix4f mvp = vp * (x34_worldXF * local).toMatrix4f(); + const zeus::CVector2f dims = GetDimensions(); + const zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front().m_pos + xc8_scaleCenter) * + zeus::CTransform::Scale(dims.x(), 1.f, dims.y()); + const zeus::CMatrix4f mvp = vp * (x34_worldXF * local).toMatrix4f(); - zeus::CVector2f projPoints[4]; - for (int i = 0; i < 4; ++i) + std::array projPoints; + for (size_t i = 0; i < projPoints.size(); ++i) { projPoints[i] = mvp.multiplyOneOverW(NormalPoints[i]).toVec2f(); + } - int j; + size_t j; for (j = 0; j < 3; ++j) { - if (!testProjectedLine(projPoints[j], projPoints[j + 1], point)) + if (!testProjectedLine(projPoints[j], projPoints[j + 1], point)) { break; + } } return j == 3 && testProjectedLine(projPoints[3], projPoints[0], point); } diff --git a/Runtime/GuiSys/CGuiTextPane.hpp b/Runtime/GuiSys/CGuiTextPane.hpp index 532d585f3..ba8281188 100644 --- a/Runtime/GuiSys/CGuiTextPane.hpp +++ b/Runtime/GuiSys/CGuiTextPane.hpp @@ -20,11 +20,11 @@ public: CGuiTextSupport& TextSupport() { return xd4_textSupport; } const CGuiTextSupport& GetTextSupport() const { return xd4_textSupport; } void Update(float dt) override; - bool GetIsFinishedLoadingWidgetSpecific() const override; + bool GetIsFinishedLoadingWidgetSpecific() override; std::vector GetFontAssets() const { return {xd4_textSupport.x5c_fontId}; } void SetDimensions(const zeus::CVector2f& dim, bool initVBO) override; void ScaleDimensions(const zeus::CVector3f& scale) override; - void Draw(const CGuiWidgetDrawParms& parms) const override; + void Draw(const CGuiWidgetDrawParms& parms) override; bool TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const override; static std::shared_ptr Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp); diff --git a/Runtime/GuiSys/CGuiTextSupport.cpp b/Runtime/GuiSys/CGuiTextSupport.cpp index e343d35a6..a2a6cb993 100644 --- a/Runtime/GuiSys/CGuiTextSupport.cpp +++ b/Runtime/GuiSys/CGuiTextSupport.cpp @@ -25,21 +25,47 @@ CGuiTextSupport::CGuiTextSupport(CAssetId fontId, const CGuiTextProperties& prop x2cc_font = store->GetObj({SBIG('FONT'), fontId}); } -CTextRenderBuffer* CGuiTextSupport::GetCurrentPageRenderBuffer() const { - if (x60_renderBuf && !x308_multipageFlag) - return const_cast(&*x60_renderBuf); - if (!x308_multipageFlag || x2ec_renderBufferPages.size() <= x304_pageCounter) +CTextRenderBuffer* CGuiTextSupport::GetCurrentPageRenderBuffer() { + if (x60_renderBuf && !x308_multipageFlag) { + return &*x60_renderBuf; + } + + if (!x308_multipageFlag || x2ec_renderBufferPages.size() <= x304_pageCounter) { return nullptr; + } + int idx = 0; - for (const CTextRenderBuffer& buf : x2ec_renderBufferPages) - if (idx++ == x304_pageCounter) - return const_cast(&buf); + for (CTextRenderBuffer& buf : x2ec_renderBufferPages) { + if (idx++ == x304_pageCounter) { + return &buf; + } + } + + return nullptr; +} + +const CTextRenderBuffer* CGuiTextSupport::GetCurrentPageRenderBuffer() const { + if (x60_renderBuf && !x308_multipageFlag) { + return &*x60_renderBuf; + } + + if (!x308_multipageFlag || x2ec_renderBufferPages.size() <= x304_pageCounter) { + return nullptr; + } + + int idx = 0; + for (const CTextRenderBuffer& buf : x2ec_renderBufferPages) { + if (idx++ == x304_pageCounter) { + return &buf; + } + } + return nullptr; } float CGuiTextSupport::GetCurrentAnimationOverAge() const { float ret = 0.f; - if (CTextRenderBuffer* buf = GetCurrentPageRenderBuffer()) { + if (const CTextRenderBuffer* buf = GetCurrentPageRenderBuffer()) { if (x50_typeEnable) { if (x40_primStartTimes.size()) { auto& lastTime = x40_primStartTimes.back(); @@ -53,16 +79,18 @@ float CGuiTextSupport::GetCurrentAnimationOverAge() const { } float CGuiTextSupport::GetNumCharsTotal() const { - if (CTextRenderBuffer* buf = GetCurrentPageRenderBuffer()) - if (x50_typeEnable) + if (const CTextRenderBuffer* buf = GetCurrentPageRenderBuffer()) { + if (x50_typeEnable) { return buf->GetPrimitiveCount(); + } + } return 0.f; } float CGuiTextSupport::GetNumCharsPrinted() const { - if (CTextRenderBuffer* buf = GetCurrentPageRenderBuffer()) { + if (const CTextRenderBuffer* buf = GetCurrentPageRenderBuffer()) { if (x50_typeEnable) { - float charsPrinted = x3c_curTime * x58_chRate; + const float charsPrinted = x3c_curTime * x58_chRate; return std::min(charsPrinted, float(buf->GetPrimitiveCount())); } } @@ -70,9 +98,11 @@ float CGuiTextSupport::GetNumCharsPrinted() const { } float CGuiTextSupport::GetTotalAnimationTime() const { - if (CTextRenderBuffer* buf = GetCurrentPageRenderBuffer()) - if (x50_typeEnable) + if (const CTextRenderBuffer* buf = GetCurrentPageRenderBuffer()) { + if (x50_typeEnable) { return buf->GetPrimitiveCount() / x58_chRate; + } + } return 0.f; } @@ -186,8 +216,8 @@ void CGuiTextSupport::AutoSetExtent() { x38_extentY = bounds.second.y; } -void CGuiTextSupport::Render() const { - const_cast(this)->CheckAndRebuildRenderBuffer(); +void CGuiTextSupport::Render() { + CheckAndRebuildRenderBuffer(); if (CTextRenderBuffer* buf = GetCurrentPageRenderBuffer()) { SCOPED_GRAPHICS_DEBUG_GROUP("CGuiTextSupport::Draw", zeus::skBlue); zeus::CTransform oldModel = CGraphics::g_GXModelMatrix; @@ -235,16 +265,23 @@ void CGuiTextSupport::SetText(std::u16string_view str, bool multipage) { void CGuiTextSupport::SetText(std::string_view str, bool multipage) { SetText(hecl::UTF8ToChar16(str), multipage); } -bool CGuiTextSupport::_GetIsTextSupportFinishedLoading() const { - for (const CToken& tok : x2bc_assets) { - const_cast(tok).Lock(); - if (!tok.IsLoaded()) +bool CGuiTextSupport::_GetIsTextSupportFinishedLoading() { + for (CToken& tok : x2bc_assets) { + tok.Lock(); + + if (!tok.IsLoaded()) { return false; + } } - if (!x2cc_font) + + if (!x2cc_font) { return true; - if (x2cc_font.IsLoaded()) + } + + if (x2cc_font.IsLoaded()) { return x2cc_font->IsFinishedLoading(); + } + return false; } @@ -269,8 +306,8 @@ void CGuiTextSupport::SetImageBaseline(bool b) { } } -bool CGuiTextSupport::GetIsTextSupportFinishedLoading() const { - const_cast(this)->CheckAndRebuildRenderBuffer(); +bool CGuiTextSupport::GetIsTextSupportFinishedLoading() { + CheckAndRebuildRenderBuffer(); return _GetIsTextSupportFinishedLoading(); } diff --git a/Runtime/GuiSys/CGuiTextSupport.hpp b/Runtime/GuiSys/CGuiTextSupport.hpp index fa7ecd1b6..6cc9c833f 100644 --- a/Runtime/GuiSys/CGuiTextSupport.hpp +++ b/Runtime/GuiSys/CGuiTextSupport.hpp @@ -84,8 +84,10 @@ class CGuiTextSupport { int x304_pageCounter = 0; bool x308_multipageFlag = false; - CTextRenderBuffer* GetCurrentPageRenderBuffer() const; - bool _GetIsTextSupportFinishedLoading() const; + CTextRenderBuffer* GetCurrentPageRenderBuffer(); + const CTextRenderBuffer* GetCurrentPageRenderBuffer() const; + + bool _GetIsTextSupportFinishedLoading(); public: CGuiTextSupport(CAssetId fontId, const CGuiTextProperties& props, const zeus::CColor& fontCol, @@ -104,7 +106,7 @@ public: const std::pair& GetBounds(); void AutoSetExtent(); - void Render() const; + void Render(); void SetGeometryColor(const zeus::CColor& col); void SetOutlineColor(const zeus::CColor& col); void SetFontColor(const zeus::CColor& col); @@ -114,7 +116,7 @@ public: void SetJustification(EJustification j); void SetVerticalJustification(EVerticalJustification j); void SetImageBaseline(bool b); - bool GetIsTextSupportFinishedLoading() const; + bool GetIsTextSupportFinishedLoading(); float GetCurTime() const { return x3c_curTime; } void SetCurTime(float t) { x3c_curTime = t; } std::u16string_view GetString() const { return x0_string; } diff --git a/Runtime/GuiSys/CGuiWidget.cpp b/Runtime/GuiSys/CGuiWidget.cpp index 3519aa36f..9d398a4f9 100644 --- a/Runtime/GuiSys/CGuiWidget.cpp +++ b/Runtime/GuiSys/CGuiWidget.cpp @@ -117,9 +117,9 @@ void CGuiWidget::Update(float dt) { sib->Update(dt); } -void CGuiWidget::Draw(const CGuiWidgetDrawParms&) const {} +void CGuiWidget::Draw(const CGuiWidgetDrawParms&) {} void CGuiWidget::ProcessUserInput(const CFinalInput& input) {} -void CGuiWidget::Touch() const {} +void CGuiWidget::Touch() {} bool CGuiWidget::GetIsVisible() const { return xb6_25_isVisible; } @@ -136,7 +136,7 @@ void CGuiWidget::InitializeRGBAFactor() { nextSib->InitializeRGBAFactor(); } -bool CGuiWidget::GetIsFinishedLoadingWidgetSpecific() const { return true; } +bool CGuiWidget::GetIsFinishedLoadingWidgetSpecific() { return true; } void CGuiWidget::SetTransform(const zeus::CTransform& xf) { x74_transform = xf; @@ -161,27 +161,30 @@ void CGuiWidget::AddChildWidget(CGuiWidget* widget, bool makeWorldLocal, bool at bool CGuiWidget::AddWorkerWidget(CGuiWidget* worker) { return false; } -void CGuiWidget::SetVisibility(bool vis, ETraversalMode mode) { +void CGuiWidget::SetVisibility(bool visible, ETraversalMode mode) { switch (mode) { case ETraversalMode::Children: { - CGuiWidget* child = static_cast(GetChildObject()); - if (child) - child->SetVisibility(vis, ETraversalMode::ChildrenAndSiblings); + auto* child = static_cast(GetChildObject()); + if (child) { + child->SetVisibility(visible, ETraversalMode::ChildrenAndSiblings); + } break; } case ETraversalMode::ChildrenAndSiblings: { - CGuiWidget* child = static_cast(GetChildObject()); - if (child) - child->SetVisibility(vis, ETraversalMode::ChildrenAndSiblings); - CGuiWidget* nextSib = static_cast(GetNextSibling()); - if (nextSib) - nextSib->SetVisibility(vis, ETraversalMode::ChildrenAndSiblings); + auto* child = static_cast(GetChildObject()); + if (child) { + child->SetVisibility(visible, ETraversalMode::ChildrenAndSiblings); + } + auto* nextSib = static_cast(GetNextSibling()); + if (nextSib) { + nextSib->SetVisibility(visible, ETraversalMode::ChildrenAndSiblings); + } break; } default: break; } - SetIsVisible(vis); + SetIsVisible(visible); } void CGuiWidget::RecalcWidgetColor(ETraversalMode mode) { @@ -227,7 +230,7 @@ CGuiWidget* CGuiWidget::FindWidget(s16 id) { return nullptr; } -bool CGuiWidget::GetIsFinishedLoading() const { return GetIsFinishedLoadingWidgetSpecific(); } +bool CGuiWidget::GetIsFinishedLoading() { return GetIsFinishedLoadingWidgetSpecific(); } void CGuiWidget::DispatchInitialize() { Initialize(); @@ -247,16 +250,18 @@ void CGuiWidget::SetColor(const zeus::CColor& color) { void CGuiWidget::OnActiveChange() {} void CGuiWidget::OnVisibleChange() {} -void CGuiWidget::SetIsVisible(bool vis) { - xb6_25_isVisible = vis; +void CGuiWidget::SetIsVisible(bool visible) { + xb6_25_isVisible = visible; OnVisibleChange(); } -void CGuiWidget::SetIsActive(bool a) { - if (a != xb6_26_isActive) { - xb6_26_isActive = a; - OnActiveChange(); +void CGuiWidget::SetIsActive(bool active) { + if (active == xb6_26_isActive) { + return; } + + xb6_26_isActive = active; + OnActiveChange(); } } // namespace urde diff --git a/Runtime/GuiSys/CGuiWidget.hpp b/Runtime/GuiSys/CGuiWidget.hpp index a59585fa9..08bd22c5a 100644 --- a/Runtime/GuiSys/CGuiWidget.hpp +++ b/Runtime/GuiSys/CGuiWidget.hpp @@ -90,24 +90,24 @@ protected: std::string m_name; public: - CGuiWidget(const CGuiWidgetParms& parms); + explicit CGuiWidget(const CGuiWidgetParms& parms); static CGuiWidgetParms ReadWidgetHeader(CGuiFrame* frame, CInputStream& in); static std::shared_ptr Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp); void Update(float dt) override; - void Draw(const CGuiWidgetDrawParms& drawParms) const override; + void Draw(const CGuiWidgetDrawParms& drawParms) override; void Initialize() override; virtual void Reset(ETraversalMode mode); virtual void ProcessUserInput(const CFinalInput& input); - virtual void Touch() const; + virtual void Touch(); virtual bool GetIsVisible() const; virtual bool GetIsActive() const; virtual bool GetMouseActive() const; virtual FourCC GetWidgetTypeID() const { return FOURCC('BWIG'); } virtual bool AddWorkerWidget(CGuiWidget* worker); - virtual bool GetIsFinishedLoadingWidgetSpecific() const; + virtual bool GetIsFinishedLoadingWidgetSpecific(); virtual void OnVisibleChange(); virtual void OnActiveChange(); @@ -122,24 +122,24 @@ public: const zeus::CColor& GetGeometryColor() const { return xa8_color2; } void SetIdlePosition(const zeus::CVector3f& pos, bool reapply); void ReapplyXform(); - virtual void SetIsVisible(bool); - void SetIsActive(bool); + virtual void SetIsVisible(bool visible); + void SetIsActive(bool active); bool GetIsSelectable() const { return xb6_27_isSelectable; } - void SetIsSelectable(bool v) { xb6_27_isSelectable = v; } - void SetMouseActive(bool v) { m_mouseActive = v; } + void SetIsSelectable(bool selectable) { xb6_27_isSelectable = selectable; } + void SetMouseActive(bool mouseActive) { m_mouseActive = mouseActive; } void ParseBaseInfo(CGuiFrame* frame, CInputStream& in, const CGuiWidgetParms& parms); void AddChildWidget(CGuiWidget* widget, bool makeWorldLocal, bool atEnd); - void SetVisibility(bool, ETraversalMode); - void RecalcWidgetColor(ETraversalMode); + void SetVisibility(bool visible, ETraversalMode mode); + void RecalcWidgetColor(ETraversalMode mode); void SetColor(const zeus::CColor& color); void InitializeRGBAFactor(); CGuiWidget* FindWidget(s16 id); - bool GetIsFinishedLoading() const; + bool GetIsFinishedLoading(); void DispatchInitialize(); - void SetDepthGreater(bool v) { xb6_30_depthGreater = v; } - void SetDepthTest(bool v) { xb6_31_depthTest = v; } - void SetDepthWrite(bool v) { xb7_24_depthWrite = v; } + void SetDepthGreater(bool depthGreater) { xb6_30_depthGreater = depthGreater; } + void SetDepthTest(bool depthTest) { xb6_31_depthTest = depthTest; } + void SetDepthWrite(bool depthWrite) { xb7_24_depthWrite = depthWrite; } CGuiFrame* GetGuiFrame() const { return xb0_frame; } }; diff --git a/Runtime/GuiSys/CGuiWidgetIdDB.cpp b/Runtime/GuiSys/CGuiWidgetIdDB.cpp index 162ee1351..075534f9b 100644 --- a/Runtime/GuiSys/CGuiWidgetIdDB.cpp +++ b/Runtime/GuiSys/CGuiWidgetIdDB.cpp @@ -21,7 +21,7 @@ s16 CGuiWidgetIdDB::AddWidget(std::string_view name, s16 id) { if (findId == -1) { if (id >= x14_lastPoolId) x14_lastPoolId = id; - x0_dbMap.emplace(std::make_pair(name, id)); + x0_dbMap.emplace(name, id); findId = id; } return findId; @@ -31,7 +31,7 @@ s16 CGuiWidgetIdDB::AddWidget(std::string_view name) { s16 findId = FindWidgetID(name); if (findId == -1) { ++x14_lastPoolId; - x0_dbMap.emplace(std::make_pair(name, x14_lastPoolId)); + x0_dbMap.emplace(name, x14_lastPoolId); findId = x14_lastPoolId; } return findId; diff --git a/Runtime/GuiSys/CHudBossEnergyInterface.hpp b/Runtime/GuiSys/CHudBossEnergyInterface.hpp index 1736f2935..71263c16f 100644 --- a/Runtime/GuiSys/CHudBossEnergyInterface.hpp +++ b/Runtime/GuiSys/CHudBossEnergyInterface.hpp @@ -20,7 +20,7 @@ class CHudBossEnergyInterface { CGuiTextPane* x1c_textpane_boss; public: - CHudBossEnergyInterface(CGuiFrame& selHud); + explicit CHudBossEnergyInterface(CGuiFrame& selHud); void Update(float dt); void SetAlpha(float a) { x0_alpha = a; } void SetBossParams(bool visible, std::u16string_view name, float curEnergy, float maxEnergy); diff --git a/Runtime/GuiSys/CHudDecoInterface.cpp b/Runtime/GuiSys/CHudDecoInterface.cpp index c173b7187..d85df6618 100644 --- a/Runtime/GuiSys/CHudDecoInterface.cpp +++ b/Runtime/GuiSys/CHudDecoInterface.cpp @@ -17,7 +17,7 @@ namespace urde { void IHudDecoInterface::SetReticuleTransform(const zeus::CMatrix3f& xf) {} void IHudDecoInterface::SetDecoRotation(float angle) {} void IHudDecoInterface::SetFrameColorValue(float v) {} -void IHudDecoInterface::Draw() const {} +void IHudDecoInterface::Draw() {} void IHudDecoInterface::ProcessInput(const CFinalInput& input) {} float IHudDecoInterface::GetHudTextAlpha() const { return 1.f; } @@ -325,10 +325,11 @@ void CHudDecoInterfaceScan::Update(float dt, const CStateManager& stateMgr) { UpdateScanDisplay(stateMgr, dt); } -void CHudDecoInterfaceScan::Draw() const { +void CHudDecoInterfaceScan::Draw() { x18_scanDisplay.Draw(); - if (x10_loadedScanHudFlat) + if (x10_loadedScanHudFlat) { x10_loadedScanHudFlat->Draw(CGuiWidgetDrawParms::Default); + } } void CHudDecoInterfaceScan::ProcessInput(const CFinalInput& input) { x18_scanDisplay.ProcessInput(input); } @@ -475,7 +476,7 @@ CHudDecoInterfaceThermal::CHudDecoInterfaceThermal(CGuiFrame& selHud) { if (CGuiWidget* w = selHud.FindWidget("basewidget_lock")) { for (CGuiWidget* c = static_cast(w->GetChildObject()); c; c = static_cast(c->GetNextSibling())) { - x84_lockonWidgets.push_back({c, c->GetLocalTransform()}); + x84_lockonWidgets.emplace_back(c, c->GetLocalTransform()); c->SetLocalTransform(c->GetLocalTransform() * zeus::CTransform::Scale(x68_lockonScale)); } } diff --git a/Runtime/GuiSys/CHudDecoInterface.hpp b/Runtime/GuiSys/CHudDecoInterface.hpp index ab4ab5c83..e6e8f301e 100644 --- a/Runtime/GuiSys/CHudDecoInterface.hpp +++ b/Runtime/GuiSys/CHudDecoInterface.hpp @@ -28,7 +28,7 @@ public: virtual void SetDamageTransform(const zeus::CMatrix3f& rotation, const zeus::CVector3f& position) = 0; virtual void SetFrameColorValue(float v); virtual void Update(float dt, const CStateManager& stateMgr) = 0; - virtual void Draw() const; + virtual void Draw(); virtual void ProcessInput(const CFinalInput& input); virtual void UpdateCameraDebugSettings(float fov, float y, float z) = 0; virtual void UpdateHudAlpha() = 0; @@ -53,7 +53,7 @@ class CHudDecoInterfaceCombat : public IHudDecoInterface { void UpdateVisibility(); public: - CHudDecoInterfaceCombat(CGuiFrame& selHud); + explicit CHudDecoInterfaceCombat(CGuiFrame& selHud); void SetIsVisibleDebug(bool v) override; void SetIsVisibleGame(bool v) override; void SetHudRotation(const zeus::CQuaternion& rot) override; @@ -104,7 +104,7 @@ class CHudDecoInterfaceScan : public IHudDecoInterface { void UpdateVisibility(); public: - CHudDecoInterfaceScan(CGuiFrame& selHud); + explicit CHudDecoInterfaceScan(CGuiFrame& selHud); void SetIsVisibleDebug(bool v) override; void SetIsVisibleGame(bool v) override; void SetHudRotation(const zeus::CQuaternion& rot) override; @@ -116,7 +116,7 @@ public: const CScannableObjectInfo* GetCurrScanInfo(const CStateManager& stateMgr) const; void UpdateScanDisplay(const CStateManager& stateMgr, float dt); void Update(float dt, const CStateManager& stateMgr) override; - void Draw() const override; + void Draw() override; void ProcessInput(const CFinalInput& input) override; void UpdateCameraDebugSettings(float fov, float y, float z) override; void UpdateHudAlpha() override; @@ -142,7 +142,7 @@ class CHudDecoInterfaceXRay : public IHudDecoInterface { void UpdateVisibility(); public: - CHudDecoInterfaceXRay(CGuiFrame& selHud); + explicit CHudDecoInterfaceXRay(CGuiFrame& selHud); void SetIsVisibleDebug(bool v) override; void SetIsVisibleGame(bool v) override; void SetHudRotation(const zeus::CQuaternion& rot) override; @@ -175,7 +175,7 @@ class CHudDecoInterfaceThermal : public IHudDecoInterface { void UpdateVisibility(); public: - CHudDecoInterfaceThermal(CGuiFrame& selHud); + explicit CHudDecoInterfaceThermal(CGuiFrame& selHud); void SetIsVisibleDebug(bool v) override; void SetIsVisibleGame(bool v) override; void SetHudRotation(const zeus::CQuaternion& rot) override; diff --git a/Runtime/GuiSys/CHudEnergyInterface.cpp b/Runtime/GuiSys/CHudEnergyInterface.cpp index f56fa4513..e664f2bed 100644 --- a/Runtime/GuiSys/CHudEnergyInterface.cpp +++ b/Runtime/GuiSys/CHudEnergyInterface.cpp @@ -1,5 +1,7 @@ #include "Runtime/GuiSys/CHudEnergyInterface.hpp" +#include + #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Audio/CSfxManager.hpp" #include "Runtime/GuiSys/CAuiEnergyBarT01.hpp" @@ -10,12 +12,15 @@ namespace urde { -static const CAuiEnergyBarT01::FCoordFunc CoordFuncs[] = { +constexpr std::array CoordFuncs{ CHudEnergyInterface::CombatEnergyCoordFunc, CHudEnergyInterface::CombatEnergyCoordFunc, - CHudEnergyInterface::XRayEnergyCoordFunc, CHudEnergyInterface::ThermalEnergyCoordFunc, - CHudEnergyInterface::BallEnergyCoordFunc}; + CHudEnergyInterface::XRayEnergyCoordFunc, CHudEnergyInterface::ThermalEnergyCoordFunc, + CHudEnergyInterface::BallEnergyCoordFunc, +}; -static const float Tesselations[] = {0.2f, 0.2f, 0.1f, 0.2f, 1.f}; +constexpr std::array Tesselations{ + 0.2f, 0.2f, 0.1f, 0.2f, 1.f, +}; CHudEnergyInterface::CHudEnergyInterface(CGuiFrame& selHud, float tankEnergy, int totalEnergyTanks, int numTanksFilled, bool energyLow, EHudType hudType) @@ -33,8 +38,8 @@ CHudEnergyInterface::CHudEnergyInterface(CGuiFrame& selHud, float tankEnergy, in x28_textpane_energywarning = static_cast(selHud.FindWidget("textpane_energywarning")); x2c_energybart01_energybar = static_cast(selHud.FindWidget("energybart01_energybar")); - x2c_energybart01_energybar->SetCoordFunc(CoordFuncs[int(hudType)]); - x2c_energybart01_energybar->SetTesselation(Tesselations[int(hudType)]); + x2c_energybart01_energybar->SetCoordFunc(CoordFuncs[size_t(hudType)]); + x2c_energybart01_energybar->SetTesselation(Tesselations[size_t(hudType)]); ITweakGuiColors::VisorEnergyBarColors barColors = g_tweakGuiColors->GetVisorEnergyBarColors(int(hudType)); ITweakGuiColors::VisorEnergyInitColors initColors = g_tweakGuiColors->GetVisorEnergyInitColors(int(hudType)); diff --git a/Runtime/GuiSys/CHudFreeLookInterface.cpp b/Runtime/GuiSys/CHudFreeLookInterface.cpp index 1fc050c4c..75d86e18b 100644 --- a/Runtime/GuiSys/CHudFreeLookInterface.cpp +++ b/Runtime/GuiSys/CHudFreeLookInterface.cpp @@ -84,13 +84,9 @@ void CHudFreeLookInterface::SetFreeLookState(bool inFreeLook, bool lookControlHe x8c_basewidget_outlinesb->SetColor(color); } - if (totalInterp == 0.f) { - x74_basewidget_freelookleft->SetVisibility(false, ETraversalMode::Children); - x80_basewidget_freelookright->SetVisibility(false, ETraversalMode::Children); - } else { - x74_basewidget_freelookleft->SetVisibility(true, ETraversalMode::Children); - x80_basewidget_freelookright->SetVisibility(true, ETraversalMode::Children); - } + const bool visible = totalInterp != 0.0f; + x74_basewidget_freelookleft->SetVisibility(visible, ETraversalMode::Children); + x80_basewidget_freelookright->SetVisibility(visible, ETraversalMode::Children); } CHudFreeLookInterfaceXRay::CHudFreeLookInterfaceXRay(CGuiFrame& selHud, bool inFreeLook, bool lookControlHeld, @@ -137,6 +133,9 @@ void CHudFreeLookInterfaceXRay::SetIsVisibleGame(bool v) { void CHudFreeLookInterfaceXRay::SetFreeLookState(bool inFreeLook, bool lookControlHeld, bool lockedOnObj, float vertLookAngle) { + x20_inFreeLook = inFreeLook; + x21_lookControlHeld = lookControlHeld; + x2c_model_freelookleft->SetLocalTransform( zeus::CTransform(zeus::CMatrix3f::RotateY(vertLookAngle), x4_freeLookLeftPos)); x30_model_freelookright->SetLocalTransform( @@ -146,10 +145,8 @@ void CHudFreeLookInterfaceXRay::SetFreeLookState(bool inFreeLook, bool lookContr color.a() = x1c_freeLookInterp; x24_basewidget_freelook->SetColor(color); - if (x1c_freeLookInterp == 0.f) - x24_basewidget_freelook->SetVisibility(false, ETraversalMode::Children); - else - x24_basewidget_freelook->SetVisibility(true, ETraversalMode::Children); + const bool visible = x1c_freeLookInterp != 0.0f; + x24_basewidget_freelook->SetVisibility(visible, ETraversalMode::Children); } } // namespace urde diff --git a/Runtime/GuiSys/CHudHelmetInterface.hpp b/Runtime/GuiSys/CHudHelmetInterface.hpp index fc987a420..534f02fce 100644 --- a/Runtime/GuiSys/CHudHelmetInterface.hpp +++ b/Runtime/GuiSys/CHudHelmetInterface.hpp @@ -30,7 +30,7 @@ class CHudHelmetInterface { void UpdateVisibility(); public: - CHudHelmetInterface(CGuiFrame& helmetFrame); + explicit CHudHelmetInterface(CGuiFrame& helmetFrame); void Update(float dt); void SetHudLagOffset(const zeus::CVector3f& off); void SetHudLagRotation(const zeus::CMatrix3f& rot); diff --git a/Runtime/GuiSys/CHudMissileInterface.cpp b/Runtime/GuiSys/CHudMissileInterface.cpp index 920d95e28..36b900a22 100644 --- a/Runtime/GuiSys/CHudMissileInterface.cpp +++ b/Runtime/GuiSys/CHudMissileInterface.cpp @@ -1,5 +1,7 @@ #include "Runtime/GuiSys/CHudMissileInterface.hpp" +#include + #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/GuiSys/CAuiEnergyBarT01.hpp" @@ -10,11 +12,14 @@ namespace urde { -static const CAuiEnergyBarT01::FCoordFunc CoordFuncs[] = {CHudMissileInterface::CombatMissileBarCoordFunc, nullptr, - CHudMissileInterface::XRayMissileBarCoordFunc, - CHudMissileInterface::ThermalMissileBarCoordFunc, nullptr}; +constexpr std::array CoordFuncs{ + CHudMissileInterface::CombatMissileBarCoordFunc, nullptr, CHudMissileInterface::XRayMissileBarCoordFunc, + CHudMissileInterface::ThermalMissileBarCoordFunc, nullptr, +}; -static const float IconTranslateRanges[] = {6.05f, 0.f, 0.f, 8.4f, 0.f}; +constexpr std::array IconTranslateRanges{ + 6.05f, 0.f, 0.f, 8.4f, 0.f, +}; CHudMissileInterface::CHudMissileInterface(CGuiFrame& selHud, int missileCapacity, int numMissiles, float chargeFactor, bool missilesActive, EHudType hudType, const CStateManager& mgr) @@ -45,7 +50,7 @@ CHudMissileInterface::CHudMissileInterface(CGuiFrame& selHud, int missileCapacit x64_energybart01_missilebar->SetEmptyColor(g_tweakGuiColors->GetMissileBarEmpty()); x64_energybart01_missilebar->SetFilledColor(g_tweakGuiColors->GetMissileBarFilled()); x64_energybart01_missilebar->SetShadowColor(g_tweakGuiColors->GetMissileBarShadow()); - x64_energybart01_missilebar->SetCoordFunc(CoordFuncs[int(hudType)]); + x64_energybart01_missilebar->SetCoordFunc(CoordFuncs[size_t(hudType)]); x64_energybart01_missilebar->SetTesselation(hudType == EHudType::Combat ? 1.f : 0.1f); x64_energybart01_missilebar->SetMaxEnergy(5.f); x64_energybart01_missilebar->SetFilledDrainSpeed(g_tweakGui->GetEnergyBarFilledSpeed()); @@ -121,8 +126,8 @@ void CHudMissileInterface::Update(float dt, const CStateManager& mgr) { if (x58_28_notXRay) { x74_basewidget_missileicon->SetLocalTransform( x10_missleIconXf * - zeus::CTransform::Translate(0.f, 0.f, - x8_numMissles * IconTranslateRanges[int(x0_hudType)] / float(x4_missileCapacity))); + zeus::CTransform::Translate( + 0.f, 0.f, x8_numMissles * IconTranslateRanges[size_t(x0_hudType)] / float(x4_missileCapacity))); } if (x58_27_hasArrows) { @@ -236,28 +241,30 @@ CHudMissileInterface::EInventoryStatus CHudMissileInterface::GetMissileInventory } std::pair CHudMissileInterface::CombatMissileBarCoordFunc(float t) { - float z = t * IconTranslateRanges[int(EHudType::Combat)]; + const float z = t * IconTranslateRanges[size_t(EHudType::Combat)]; return {zeus::CVector3f(0.f, 0.f, z), zeus::CVector3f(0.3f, 0.f, z)}; } std::pair CHudMissileInterface::XRayMissileBarCoordFunc(float t) { - float theta = 0.8f * (t - 0.5f); - float x = 9.55f * std::cos(theta); - float z = 9.55f * std::sin(theta); + const float theta = 0.8f * (t - 0.5f); + const float x = 9.55f * std::cos(theta); + const float z = 9.55f * std::sin(theta); return {zeus::CVector3f(x - 0.4f, 0.f, z), zeus::CVector3f(x, 0.f, z)}; } std::pair CHudMissileInterface::ThermalMissileBarCoordFunc(float t) { - float transRange = IconTranslateRanges[int(EHudType::Thermal)]; - float a = 0.08f * transRange; - float b = t * transRange; + const float transRange = IconTranslateRanges[size_t(EHudType::Thermal)]; + const float a = 0.08f * transRange; + const float b = t * transRange; + float c; - if (b < a) + if (b < a) { c = b / a; - else if (b < transRange - a) + } else if (b < transRange - a) { c = 1.f; - else + } else { c = 1.f - (b - (transRange - a)) / a; + } return {zeus::CVector3f(-0.5f * c - 0.1f, 0.f, b), zeus::CVector3f(-0.1f, 0.f, b)}; } diff --git a/Runtime/GuiSys/CHudThreatInterface.cpp b/Runtime/GuiSys/CHudThreatInterface.cpp index 1298fcabc..7a4235b19 100644 --- a/Runtime/GuiSys/CHudThreatInterface.cpp +++ b/Runtime/GuiSys/CHudThreatInterface.cpp @@ -1,5 +1,7 @@ #include "Runtime/GuiSys/CHudThreatInterface.hpp" +#include + #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/GuiSys/CAuiEnergyBarT01.hpp" #include "Runtime/GuiSys/CGuiFrame.hpp" @@ -10,11 +12,14 @@ namespace urde { -static const CAuiEnergyBarT01::FCoordFunc CoordFuncs[] = {CHudThreatInterface::CombatThreatBarCoordFunc, nullptr, - CHudThreatInterface::XRayThreatBarCoordFunc, - CHudThreatInterface::ThermalThreatBarCoordFunc, nullptr}; +constexpr std::array CoordFuncs{ + CHudThreatInterface::CombatThreatBarCoordFunc, nullptr, CHudThreatInterface::XRayThreatBarCoordFunc, + CHudThreatInterface::ThermalThreatBarCoordFunc, nullptr, +}; -static const float IconTranslateRanges[] = {6.05f, 0.f, 0.f, 8.4f, 0.f}; +constexpr std::array IconTranslateRanges{ + 6.05f, 0.f, 0.f, 8.4f, 0.f, +}; CHudThreatInterface::CHudThreatInterface(CGuiFrame& selHud, EHudType hudType, float threatDist) : x4_hudType(hudType), x10_threatDist(threatDist) { @@ -42,7 +47,7 @@ CHudThreatInterface::CHudThreatInterface(CGuiFrame& selHud, EHudType hudType, fl x6c_energybart01_threatbar->SetFilledColor(g_tweakGuiColors->GetThreatBarFilled()); x6c_energybart01_threatbar->SetShadowColor(g_tweakGuiColors->GetThreatBarShadow()); x6c_energybart01_threatbar->SetEmptyColor(g_tweakGuiColors->GetThreatBarEmpty()); - x6c_energybart01_threatbar->SetCoordFunc(CoordFuncs[int(hudType)]); + x6c_energybart01_threatbar->SetCoordFunc(CoordFuncs[size_t(hudType)]); x6c_energybart01_threatbar->SetTesselation(hudType == EHudType::Combat ? 1.f : 0.1f); x6c_energybart01_threatbar->SetMaxEnergy(g_tweakGui->GetThreatRange()); x6c_energybart01_threatbar->SetFilledDrainSpeed(9999.f); @@ -133,7 +138,7 @@ void CHudThreatInterface::Update(float dt) { x5c_basewidget_threaticon->SetLocalTransform( x18_threatIconXf * zeus::CTransform::Translate(0.f, 0.f, std::max(0.f, maxThreatEnergy - x10_threatDist) * - IconTranslateRanges[int(x4_hudType)] / maxThreatEnergy)); + IconTranslateRanges[size_t(x4_hudType)] / maxThreatEnergy)); } if (x68_textpane_threatwarning) { @@ -203,28 +208,30 @@ void CHudThreatInterface::Update(float dt) { } std::pair CHudThreatInterface::CombatThreatBarCoordFunc(float t) { - float z = IconTranslateRanges[int(EHudType::Combat)] * t; + const float z = IconTranslateRanges[size_t(EHudType::Combat)] * t; return {zeus::CVector3f(-0.3f, 0.f, z), zeus::CVector3f(0.f, 0.f, z)}; } std::pair CHudThreatInterface::XRayThreatBarCoordFunc(float t) { - float theta = 0.8f * (t - 0.5f); - float x = -9.55f * std::cos(theta); - float z = 9.55f * std::sin(theta); + const float theta = 0.8f * (t - 0.5f); + const float x = -9.55f * std::cos(theta); + const float z = 9.55f * std::sin(theta); return {zeus::CVector3f(0.4f + x, 0.f, z), zeus::CVector3f(x, 0.f, z)}; } std::pair CHudThreatInterface::ThermalThreatBarCoordFunc(float t) { - float transRange = IconTranslateRanges[int(EHudType::Thermal)]; - float a = 0.08f * transRange; - float b = t * transRange; + const float transRange = IconTranslateRanges[size_t(EHudType::Thermal)]; + const float a = 0.08f * transRange; + const float b = t * transRange; + float c; - if (b < a) + if (b < a) { c = b / a; - else if (b < transRange - a) + } else if (b < transRange - a) { c = 1.f; - else + } else { c = 1.f - (b - (transRange - a)) / a; + } return {zeus::CVector3f(0.1f, 0.f, b), zeus::CVector3f(0.5f * c + 0.1f, 0.f, b)}; } diff --git a/Runtime/GuiSys/CHudVisorBeamMenu.cpp b/Runtime/GuiSys/CHudVisorBeamMenu.cpp index bc7f016d1..3153cf848 100644 --- a/Runtime/GuiSys/CHudVisorBeamMenu.cpp +++ b/Runtime/GuiSys/CHudVisorBeamMenu.cpp @@ -1,5 +1,7 @@ #include "Runtime/GuiSys/CHudVisorBeamMenu.hpp" +#include + #include "Runtime/CGameState.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Audio/CSfxManager.hpp" @@ -10,22 +12,40 @@ namespace urde { -static const char* BaseMenuNames[] = {"BaseWidget_VisorMenu", "BaseWidget_BeamMenu"}; - -static const char* TextNames[] = {"TextPane_VisorMenu", "TextPane_BeamMenu"}; - -static const char* BaseTitleNames[] = {"basewidget_visormenutitle", "basewidget_beammenutitle"}; - -static const char* ModelNames[] = {"model_visor", "model_beam"}; - -static const char MenuItemOrders[2][4] = {{'1', '0', '3', '2'}, {'3', '2', '1', '0'}}; - -static const int MenuStringIdx[2][4] = { - {0, 2, 1, 3}, // Combat, XRay, Scan, Thermal - {4, 5, 6, 7} // Power, Ice, Wave, Plasma +constexpr std::array BaseMenuNames{ + "BaseWidget_VisorMenu", + "BaseWidget_BeamMenu", }; -static const u16 SelectionSfxs[] = {SFXui_select_visor, SFXui_select_beam}; +constexpr std::array TextNames{ + "TextPane_VisorMenu", + "TextPane_BeamMenu", +}; + +constexpr std::array BaseTitleNames{ + "basewidget_visormenutitle", + "basewidget_beammenutitle", +}; + +constexpr std::array ModelNames{ + "model_visor", + "model_beam", +}; + +constexpr std::array, 2> MenuItemOrders{{ + {'1', '0', '3', '2'}, + {'3', '2', '1', '0'}, +}}; + +constexpr std::array, 2> MenuStringIdx{{ + {0, 2, 1, 3}, // Combat, XRay, Scan, Thermal + {4, 5, 6, 7}, // Power, Ice, Wave, Plasma +}}; + +constexpr std::array SelectionSfxs{ + SFXui_select_visor, + SFXui_select_beam, +}; CHudVisorBeamMenu::CHudVisorBeamMenu(CGuiFrame& baseHud, EHudVisorBeamMenu type, const rstl::reserved_vector& enables) @@ -43,19 +63,23 @@ CHudVisorBeamMenu::CHudVisorBeamMenu(CGuiFrame& baseHud, EHudVisorBeamMenu type, else swappedType = x4_type; - x20_textpane_menu = static_cast(x0_baseHud.FindWidget(TextNames[int(swappedType)])); - x1c_basewidget_menutitle = x0_baseHud.FindWidget(BaseTitleNames[int(swappedType)]); - x18_basewidget_menu = x0_baseHud.FindWidget(BaseMenuNames[int(swappedType)]); + x20_textpane_menu = static_cast(x0_baseHud.FindWidget(TextNames[size_t(swappedType)])); + x1c_basewidget_menutitle = x0_baseHud.FindWidget(BaseTitleNames[size_t(swappedType)]); + x18_basewidget_menu = x0_baseHud.FindWidget(BaseMenuNames[size_t(swappedType)]); - x24_model_ghost = static_cast(x0_baseHud.FindWidget(fmt::format(fmt("{}ghost"), ModelNames[int(x4_type)]))); + x24_model_ghost = + static_cast(x0_baseHud.FindWidget(fmt::format(fmt("{}ghost"), ModelNames[size_t(x4_type)]))); x28_menuItems.resize(4); - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < x28_menuItems.size(); i++) { + const auto modelName = ModelNames[size_t(x4_type)]; + const auto menuItemOrder = MenuItemOrders[size_t(x4_type)][i]; + SMenuItem& item = x28_menuItems[i]; - item.x0_model_loz = static_cast( - x0_baseHud.FindWidget(fmt::format(fmt("{}loz{}"), ModelNames[int(x4_type)], MenuItemOrders[int(x4_type)][i]))); - item.x4_model_icon = static_cast( - x0_baseHud.FindWidget(fmt::format(fmt("{}icon{}"), ModelNames[int(x4_type)], MenuItemOrders[int(x4_type)][i]))); + item.x0_model_loz = + static_cast(x0_baseHud.FindWidget(fmt::format(fmt("{}loz{}"), modelName, menuItemOrder))); + item.x4_model_icon = + static_cast(x0_baseHud.FindWidget(fmt::format(fmt("{}icon{}"), modelName, menuItemOrder))); item.xc_opacity = enables[i] ? 1.f : 0.f; } @@ -71,9 +95,10 @@ CHudVisorBeamMenu::CHudVisorBeamMenu(CGuiFrame& baseHud, EHudVisorBeamMenu type, titleColor.a() = 0.f; x1c_basewidget_menutitle->SetColor(titleColor); - x20_textpane_menu->TextSupport().SetText(g_MainStringTable->GetString(MenuStringIdx[int(x4_type)][x8_selectedItem])); + x20_textpane_menu->TextSupport().SetText( + g_MainStringTable->GetString(MenuStringIdx[size_t(x4_type)][x8_selectedItem])); - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < x28_menuItems.size(); ++i) { SMenuItem& item = x28_menuItems[i]; item.x0_model_loz->SetColor(g_tweakGuiColors->GetVisorBeamMenuLozColor()); UpdateMenuWidgetTransform(i, *item.x0_model_loz, 1.f); @@ -82,20 +107,22 @@ CHudVisorBeamMenu::CHudVisorBeamMenu(CGuiFrame& baseHud, EHudVisorBeamMenu type, Update(0.f, true); } -void CHudVisorBeamMenu::UpdateMenuWidgetTransform(int idx, CGuiWidget& w, float t) { - float translate = t * g_tweakGui->GetVisorBeamMenuItemTranslate(); - float scale = +void CHudVisorBeamMenu::UpdateMenuWidgetTransform(size_t idx, CGuiWidget& w, float t) { + const float translate = t * g_tweakGui->GetVisorBeamMenuItemTranslate(); + const float scale = t * g_tweakGui->GetVisorBeamMenuItemInactiveScale() + (1.f - t) * g_tweakGui->GetVisorBeamMenuItemActiveScale(); if (x4_type == EHudVisorBeamMenu::Visor) { - if (idx == 2) + if (idx == 2) { idx = 3; - else if (idx == 3) + } else if (idx == 3) { idx = 2; + } } else { - if (idx == 1) + if (idx == 1) { idx = 2; - else if (idx == 2) + } else if (idx == 2) { idx = 1; + } } switch (idx) { @@ -130,42 +157,48 @@ void CHudVisorBeamMenu::Update(float dt, bool init) { else swappedType = x4_type; - x18_basewidget_menu = x0_baseHud.FindWidget(BaseMenuNames[int(swappedType)]); - x20_textpane_menu = static_cast(x0_baseHud.FindWidget(TextNames[int(swappedType)])); - x1c_basewidget_menutitle = x0_baseHud.FindWidget(BaseTitleNames[int(swappedType)]); + x18_basewidget_menu = x0_baseHud.FindWidget(BaseMenuNames[size_t(swappedType)]); + x20_textpane_menu = static_cast(x0_baseHud.FindWidget(TextNames[size_t(swappedType)])); + x1c_basewidget_menutitle = x0_baseHud.FindWidget(BaseTitleNames[size_t(swappedType)]); - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < x28_menuItems.size(); ++i) { SMenuItem& item = x28_menuItems[i]; UpdateMenuWidgetTransform(i, *item.x4_model_icon, item.x8_positioner); UpdateMenuWidgetTransform(i, *item.x0_model_loz, 1.f); } - UpdateMenuWidgetTransform(x8_selectedItem, *x24_model_ghost, x28_menuItems[x8_selectedItem].x8_positioner); + UpdateMenuWidgetTransform(size_t(x8_selectedItem), *x24_model_ghost, x28_menuItems[x8_selectedItem].x8_positioner); } zeus::CColor activeColor = g_tweakGuiColors->GetVisorBeamMenuItemActive(); zeus::CColor inactiveColor = g_tweakGuiColors->GetVisorBeamMenuItemInactive(); zeus::CColor lozColor = g_tweakGuiColors->GetVisorBeamMenuLozColor(); - zeus::CColor tmpColors[4]; + std::array tmpColors; - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < x28_menuItems.size(); ++i) { SMenuItem& item = x28_menuItems[i]; - if (item.xc_opacity > 0.f) + if (item.xc_opacity > 0.f) { item.xc_opacity = std::min(item.xc_opacity + dt, 1.f); + } tmpColors[i] = zeus::CColor::lerp(activeColor, zeus::skClear, item.xc_opacity); } switch (x6c_animPhase) { case EAnimPhase::Steady: - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < x28_menuItems.size(); ++i) { SMenuItem& item = x28_menuItems[i]; - zeus::CColor& color0 = (x8_selectedItem == i) ? activeColor : inactiveColor; - zeus::CColor& color1 = (x8_selectedItem == i) ? lozColor : inactiveColor; - zeus::CColor iconColor = (item.xc_opacity == 0.f) ? zeus::skClear : color0 + tmpColors[i]; - zeus::CColor lColor = (item.xc_opacity == 0.f) ? lozColor : color1 + tmpColors[i]; + + const bool isSelectedItem = x8_selectedItem == int(i); + const bool isClear = item.xc_opacity == 0.0f; + + const zeus::CColor& color0 = isSelectedItem ? activeColor : inactiveColor; + const zeus::CColor& color1 = isSelectedItem ? lozColor : inactiveColor; + const zeus::CColor iconColor = isClear ? zeus::skClear : color0 + tmpColors[i]; + const zeus::CColor lColor = isClear ? lozColor : color1 + tmpColors[i]; + item.x4_model_icon->SetColor(iconColor); item.x0_model_loz->SetColor(lColor); - item.x8_positioner = (x8_selectedItem == i) ? 0.f : 1.f; + item.x8_positioner = isSelectedItem ? 0.f : 1.f; } x24_model_ghost->SetColor(activeColor); break; @@ -185,20 +218,25 @@ void CHudVisorBeamMenu::Update(float dt, bool init) { item1.x4_model_icon->SetColor(color); item1.x0_model_loz->SetColor(lozColor); - for (int i = 0; i < 4; ++i) - x28_menuItems[i].x8_positioner = (x8_selectedItem == i) ? 1.f - x10_interp : 1.f; + for (size_t i = 0; i < x28_menuItems.size(); ++i) { + const bool isSelectedItem = x8_selectedItem == int(i); + x28_menuItems[i].x8_positioner = isSelectedItem ? 1.f - x10_interp : 1.f; + } x24_model_ghost->SetColor(zeus::CColor::lerp(activeColor, inactiveColor, item1.x8_positioner)); break; } case EAnimPhase::Animate: - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < x28_menuItems.size(); ++i) { SMenuItem& item = x28_menuItems[i]; - zeus::CColor& color0 = (x8_selectedItem == i) ? activeColor : inactiveColor; - zeus::CColor iconColor = (item.xc_opacity == 0.f) ? zeus::skClear : color0 + tmpColors[i]; + const bool isSelectedItem = x8_selectedItem == int(i); + const bool isClear = item.xc_opacity == 0.f; + const zeus::CColor& color0 = isSelectedItem ? activeColor : inactiveColor; + const zeus::CColor iconColor = isClear ? zeus::skClear : color0 + tmpColors[i]; + item.x4_model_icon->SetColor(iconColor); - item.x0_model_loz->SetColor((item.xc_opacity == 0.f || x8_selectedItem == i) ? lozColor : inactiveColor); - item.x8_positioner = (x8_selectedItem == i) ? 1.f - x10_interp : 1.f; + item.x0_model_loz->SetColor((isClear || isSelectedItem) ? lozColor : inactiveColor); + item.x8_positioner = isSelectedItem ? 1.f - x10_interp : 1.f; } x24_model_ghost->SetColor( zeus::CColor::lerp(activeColor, inactiveColor, x28_menuItems[x8_selectedItem].x8_positioner)); @@ -216,11 +254,11 @@ void CHudVisorBeamMenu::Update(float dt, bool init) { if (x14_26_dirty || init) { x14_26_dirty = false; - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < x28_menuItems.size(); ++i) { SMenuItem& item = x28_menuItems[i]; UpdateMenuWidgetTransform(i, *item.x4_model_icon, item.x8_positioner); } - UpdateMenuWidgetTransform(x8_selectedItem, *x24_model_ghost, x28_menuItems[x8_selectedItem].x8_positioner); + UpdateMenuWidgetTransform(size_t(x8_selectedItem), *x24_model_ghost, x28_menuItems[x8_selectedItem].x8_positioner); } if (!x14_24_visibleDebug || !x14_25_visibleGame) @@ -229,8 +267,7 @@ void CHudVisorBeamMenu::Update(float dt, bool init) { x1c_basewidget_menutitle->SetVisibility(x1c_basewidget_menutitle->GetGeometryColor().a() != 0.f, ETraversalMode::Children); - for (int i = 0; i < 4; ++i) { - SMenuItem& item = x28_menuItems[i]; + for (SMenuItem& item : x28_menuItems) { item.x4_model_icon->SetIsVisible(item.x4_model_icon->GetGeometryColor().a() != 0.f); } } @@ -250,10 +287,11 @@ void CHudVisorBeamMenu::SetIsVisibleGame(bool v) { } void CHudVisorBeamMenu::SetPlayerHas(const rstl::reserved_vector& enables) { - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < x28_menuItems.size(); ++i) { SMenuItem& item = x28_menuItems[i]; - if (item.xc_opacity == 0.f && enables[i]) + if (item.xc_opacity == 0.f && enables[i]) { item.xc_opacity = FLT_EPSILON; + } } } @@ -262,13 +300,14 @@ void CHudVisorBeamMenu::SetSelection(int selection, int pending, float interp) { return; if (pending != selection) { - if (x6c_animPhase != EAnimPhase::SelectFlash) - CSfxManager::SfxStart(SelectionSfxs[int(x4_type)], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); + if (x6c_animPhase != EAnimPhase::SelectFlash) { + CSfxManager::SfxStart(SelectionSfxs[size_t(x4_type)], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); + } x6c_animPhase = EAnimPhase::SelectFlash; } else if (interp < 1.f) { x6c_animPhase = EAnimPhase::Animate; x20_textpane_menu->TextSupport().SetText( - g_MainStringTable->GetString(MenuStringIdx[int(x4_type)][x8_selectedItem])); + g_MainStringTable->GetString(MenuStringIdx[size_t(x4_type)][x8_selectedItem])); x20_textpane_menu->TextSupport().SetTypeWriteEffectOptions(true, 0.1f, 16.f); } else { if (x6c_animPhase != EAnimPhase::Steady) diff --git a/Runtime/GuiSys/CHudVisorBeamMenu.hpp b/Runtime/GuiSys/CHudVisorBeamMenu.hpp index 3cf9b45a9..6306fd19f 100644 --- a/Runtime/GuiSys/CHudVisorBeamMenu.hpp +++ b/Runtime/GuiSys/CHudVisorBeamMenu.hpp @@ -45,7 +45,7 @@ private: float x7c_animDur; bool x80_24_swapBeamControls : 1; - void UpdateMenuWidgetTransform(int, CGuiWidget& w, float); + void UpdateMenuWidgetTransform(size_t idx, CGuiWidget& w, float t); public: CHudVisorBeamMenu(CGuiFrame& baseHud, EHudVisorBeamMenu type, const rstl::reserved_vector& enables); @@ -53,7 +53,7 @@ public: void UpdateHudAlpha(float alpha); void SetIsVisibleGame(bool v); void SetPlayerHas(const rstl::reserved_vector& enables); - void SetSelection(int, int, float); + void SetSelection(int selection, int pending, float interp); }; } // namespace urde diff --git a/Runtime/GuiSys/CInstruction.hpp b/Runtime/GuiSys/CInstruction.hpp index 9f8ecb589..79eb5c2f0 100644 --- a/Runtime/GuiSys/CInstruction.hpp +++ b/Runtime/GuiSys/CInstruction.hpp @@ -44,7 +44,7 @@ class CFontInstruction : public CInstruction { TLockedToken x4_font; public: - CFontInstruction(const TToken& font) : x4_font(font) {} + explicit CFontInstruction(const TToken& font) : x4_font(font) {} void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const override; void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const override; void GetAssets(std::vector& assetsOut) const override; @@ -55,7 +55,7 @@ class CLineExtraSpaceInstruction : public CInstruction { s32 x4_extraSpace; public: - CLineExtraSpaceInstruction(s32 extraSpace) : x4_extraSpace(extraSpace) {} + explicit CLineExtraSpaceInstruction(s32 extraSpace) : x4_extraSpace(extraSpace) {} void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const override; void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const override; }; @@ -107,7 +107,7 @@ class CLineSpacingInstruction : public CInstruction { float x4_lineSpacing; public: - CLineSpacingInstruction(float spacing) : x4_lineSpacing(spacing) {} + explicit CLineSpacingInstruction(float spacing) : x4_lineSpacing(spacing) {} void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const override; void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const override; }; @@ -128,7 +128,7 @@ class CRemoveColorOverrideInstruction : public CInstruction { int x4_idx; public: - CRemoveColorOverrideInstruction(int idx) : x4_idx(idx) {} + explicit CRemoveColorOverrideInstruction(int idx) : x4_idx(idx) {} void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const override; void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const override; }; @@ -137,7 +137,7 @@ class CImageInstruction : public CInstruction { CFontImageDef x4_image; public: - CImageInstruction(const CFontImageDef& image) : x4_image(image) {} + explicit CImageInstruction(const CFontImageDef& image) : x4_image(image) {} void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const override; void GetAssets(std::vector& assetsOut) const override; size_t GetAssetCount() const override; diff --git a/Runtime/GuiSys/CRasterFont.cpp b/Runtime/GuiSys/CRasterFont.cpp index 3f9af601d..35f60af6e 100644 --- a/Runtime/GuiSys/CRasterFont.cpp +++ b/Runtime/GuiSys/CRasterFont.cpp @@ -1,5 +1,7 @@ #include "Runtime/GuiSys/CRasterFont.hpp" +#include + #include "Runtime/CSimplePool.hpp" #include "Runtime/Graphics/CTexture.hpp" #include "Runtime/GuiSys/CDrawStringOptions.hpp" @@ -64,8 +66,8 @@ CRasterFont::CRasterFont(urde::CInputStream& in, urde::IObjectStore& store) { baseline = in.readByte(); kernStart = in.readInt16Big(); } - xc_glyphs.push_back(std::make_pair( - chr, CGlyph(a, b, c, startU, startV, endU, endV, cellWidth, cellHeight, baseline, kernStart, layer))); + xc_glyphs.emplace_back( + chr, CGlyph(a, b, c, startU, startV, endU, endV, cellWidth, cellHeight, baseline, kernStart, layer)); } std::sort(xc_glyphs.begin(), xc_glyphs.end(), [=](auto& a, auto& b) -> bool { return a.first < b.first; }); @@ -84,6 +86,17 @@ CRasterFont::CRasterFont(urde::CInputStream& in, urde::IObjectStore& store) { x0_initialized = true; } +const CGlyph* CRasterFont::InternalGetGlyph(char16_t chr) const { + const auto iter = + std::find_if(xc_glyphs.cbegin(), xc_glyphs.cend(), [chr](const auto& entry) { return entry.first == chr; }); + + if (iter == xc_glyphs.cend()) { + return nullptr; + } + + return &iter->second; +} + void CRasterFont::SinglePassDrawString(const CDrawStringOptions& opts, int x, int y, int& xout, int& yout, CTextRenderBuffer* renderBuf, const char16_t* str, s32 length) const { if (!x0_initialized) @@ -97,8 +110,10 @@ void CRasterFont::SinglePassDrawString(const CDrawStringOptions& opts, int x, in if (opts.x0_direction == ETextDirection::Horizontal) { x += glyph->GetLeftPadding(); - if (prevGlyph != 0) + if (prevGlyph != nullptr) { x += KernLookup(x1c_kerning, prevGlyph->GetKernStart(), *chr); + } + int left = 0; int top = 0; diff --git a/Runtime/GuiSys/CRasterFont.hpp b/Runtime/GuiSys/CRasterFont.hpp index 82db5d5d7..0b582792f 100644 --- a/Runtime/GuiSys/CRasterFont.hpp +++ b/Runtime/GuiSys/CRasterFont.hpp @@ -80,20 +80,16 @@ public: }; class CFontInfo { - bool x0_ = false; - bool x1_ = false; - s32 x4_ = 0; - s32 x8_fontSize = 0; - char xc_name[40]; + [[maybe_unused]] bool x0_ = false; + [[maybe_unused]] bool x1_ = false; + [[maybe_unused]] s32 x4_ = 0; + [[maybe_unused]] s32 x8_fontSize = 0; + char xc_name[64] = ""; public: CFontInfo() = default; CFontInfo(bool a, bool b, s32 c, s32 fontSize, const char* name) : x0_(a), x1_(b), x4_(c), x8_fontSize(fontSize) { - strcpy(xc_name, name); - (void)x0_; - (void)x1_; - (void)x4_; - (void)x8_fontSize; + std::strcpy(xc_name, name); } }; @@ -109,16 +105,7 @@ class CRasterFont { s32 x8c_baseline; s32 x90_lineMargin = 0; - const CGlyph* InternalGetGlyph(char16_t chr) const { - u32 i = 0; - for (; i < xc_glyphs.size(); ++i) - if (chr == xc_glyphs[i].first) - break; - - if (i == xc_glyphs.size()) - return nullptr; - return &xc_glyphs[i].second; - } + const CGlyph* InternalGetGlyph(char16_t chr) const; public: CRasterFont(CInputStream& in, IObjectStore& store); diff --git a/Runtime/GuiSys/CScanDisplay.cpp b/Runtime/GuiSys/CScanDisplay.cpp index 12dba9f4c..471f6ee18 100644 --- a/Runtime/GuiSys/CScanDisplay.cpp +++ b/Runtime/GuiSys/CScanDisplay.cpp @@ -35,20 +35,23 @@ void CScanDisplay::CDataDot::Update(float dt) { } } -void CScanDisplay::CDataDot::Draw(const zeus::CColor& col, float radius) const { - if (x24_alpha == 0.f) +void CScanDisplay::CDataDot::Draw(const zeus::CColor& col, float radius) { + if (x24_alpha == 0.f) { return; + } if (x0_dotState != EDotState::Hidden) { - zeus::CTransform xf = zeus::CTransform::Translate(xc_curPos.x(), 0.f, xc_curPos.y()); + const zeus::CTransform xf = zeus::CTransform::Translate(xc_curPos.x(), 0.f, xc_curPos.y()); CGraphics::SetModelMatrix(xf); zeus::CColor useColor = col; useColor.a() *= x24_alpha; - CTexturedQuadFilter::Vert verts[4] = {{{-radius, 0.f, radius}, {0.f, 1.f}}, - {{-radius, 0.f, -radius}, {0.f, 0.f}}, - {{radius, 0.f, radius}, {1.f, 1.f}}, - {{radius, 0.f, -radius}, {1.f, 0.f}}}; - const_cast(m_quad).drawVerts(useColor, verts); + const CTexturedQuadFilter::Vert verts[4] = { + {{-radius, 0.f, radius}, {0.f, 1.f}}, + {{-radius, 0.f, -radius}, {0.f, 0.f}}, + {{radius, 0.f, radius}, {1.f, 1.f}}, + {{radius, 0.f, -radius}, {1.f, 0.f}}, + }; + m_quad.drawVerts(useColor, verts); } } @@ -418,16 +421,18 @@ void CScanDisplay::Update(float dt, float scanningTime) { } } -void CScanDisplay::Draw() const { - if (!x0_dataDot.IsLoaded()) +void CScanDisplay::Draw() { + if (!x0_dataDot.IsLoaded()) { return; + } // No Z-test or write g_Renderer->SetViewportOrtho(true, -4096.f, 4096.f); // Additive alpha - float vpRatio = g_Viewport.xc_height / 480.f; - for (const CDataDot& dot : xbc_dataDots) + const float vpRatio = g_Viewport.xc_height / 480.f; + for (CDataDot& dot : xbc_dataDots) { dot.Draw(g_tweakGuiColors->GetScanDataDotColor(), g_tweakGui->GetScanDataDotRadius() * vpRatio); + } } } // namespace urde diff --git a/Runtime/GuiSys/CScanDisplay.hpp b/Runtime/GuiSys/CScanDisplay.hpp index b879767f6..7b9c60d83 100644 --- a/Runtime/GuiSys/CScanDisplay.hpp +++ b/Runtime/GuiSys/CScanDisplay.hpp @@ -43,9 +43,9 @@ public: CTexturedQuadFilter m_quad; public: - CDataDot(const TLockedToken& dataDotTex) : m_quad(EFilterType::Add, dataDotTex) {} + explicit CDataDot(const TLockedToken& dataDotTex) : m_quad(EFilterType::Add, dataDotTex) {} void Update(float dt); - void Draw(const zeus::CColor& color, float radius) const; + void Draw(const zeus::CColor& color, float radius); float GetTransitionFactor() const { return x1c_transDur > 0.f ? x20_remTime / x1c_transDur : 0.f; } void StartTransitionTo(const zeus::CVector2f&, float); void SetDestPosition(const zeus::CVector2f&); @@ -84,13 +84,13 @@ private: static void SetScanMessageTypeEffect(CGuiTextPane* pane, bool type); public: - CScanDisplay(const CGuiFrame& selHud); + explicit CScanDisplay(const CGuiFrame& selHud); void ProcessInput(const CFinalInput& input); void StartScan(TUniqueId id, const CScannableObjectInfo& scanInfo, CGuiTextPane* message, CGuiTextPane* scrollMessage, CGuiWidget* textGroup, CGuiModel* xmark, CGuiModel* abutton, CGuiModel* dash, float scanTime); void StopScan(); void Update(float dt, float scanningTime); - void Draw() const; + void Draw(); EScanState GetScanState() const { return xc_state; } TUniqueId ScanTarget() const { return x10_objId; } }; diff --git a/Runtime/GuiSys/CSplashScreen.cpp b/Runtime/GuiSys/CSplashScreen.cpp index 94938a13b..9c36cd163 100644 --- a/Runtime/GuiSys/CSplashScreen.cpp +++ b/Runtime/GuiSys/CSplashScreen.cpp @@ -48,19 +48,22 @@ CIOWin::EMessageReturn CSplashScreen::OnMessage(const CArchitectureMessage& msg, return EMessageReturn::Exit; } -void CSplashScreen::Draw() const { - if (!x25_textureLoaded) +void CSplashScreen::Draw() { + if (!x25_textureLoaded) { return; + } SCOPED_GRAPHICS_DEBUG_GROUP("CSplashScreen::Draw", zeus::skGreen); zeus::CColor color; - if (x14_which == ESplashScreen::Nintendo) + if (x14_which == ESplashScreen::Nintendo) { color = zeus::CColor{0.86f, 0.f, 0.f, 1.f}; + } - if (x18_splashTimeout > 1.5f) + if (x18_splashTimeout > 1.5f) { color.a() = 1.f - (x18_splashTimeout - 1.5f) * 2.f; - else if (x18_splashTimeout < 0.5f) + } else if (x18_splashTimeout < 0.5f) { color.a() = x18_splashTimeout * 2.f; + } zeus::CRectangle rect; rect.size.x() = m_quad.GetTex()->GetWidth() / (480.f * g_Viewport.aspect); @@ -68,7 +71,7 @@ void CSplashScreen::Draw() const { rect.position.x() = 0.5f - rect.size.x() / 2.f; rect.position.y() = 0.5f - rect.size.y() / 2.f; - const_cast(m_quad).draw(color, 1.f, rect); + m_quad.draw(color, 1.f, rect); } } // namespace urde diff --git a/Runtime/GuiSys/CSplashScreen.hpp b/Runtime/GuiSys/CSplashScreen.hpp index db4fd2e86..4737ea26b 100644 --- a/Runtime/GuiSys/CSplashScreen.hpp +++ b/Runtime/GuiSys/CSplashScreen.hpp @@ -22,9 +22,9 @@ private: CTexturedQuadFilterAlpha m_quad; public: - CSplashScreen(ESplashScreen); + explicit CSplashScreen(ESplashScreen); EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&) override; - void Draw() const override; + void Draw() override; }; } // namespace urde diff --git a/Runtime/GuiSys/CStringTable.hpp b/Runtime/GuiSys/CStringTable.hpp index 0e8461e5e..88d574b78 100644 --- a/Runtime/GuiSys/CStringTable.hpp +++ b/Runtime/GuiSys/CStringTable.hpp @@ -13,7 +13,7 @@ class CStringTable { u32 m_bufLen; public: - CStringTable(CInputStream& in); + explicit CStringTable(CInputStream& in); void LoadStringTable(CInputStream& in); const char16_t* GetString(s32) const; diff --git a/Runtime/GuiSys/CTargetingManager.hpp b/Runtime/GuiSys/CTargetingManager.hpp index 3f9a62ec0..58d383930 100644 --- a/Runtime/GuiSys/CTargetingManager.hpp +++ b/Runtime/GuiSys/CTargetingManager.hpp @@ -10,7 +10,7 @@ class CTargetingManager { COrbitPointMarker x21c_orbitPointMarker; public: - CTargetingManager(const CStateManager& stateMgr); + explicit CTargetingManager(const CStateManager& stateMgr); bool CheckLoadComplete(); void Update(float, const CStateManager& stateMgr); void Draw(const CStateManager& stateMgr, bool hideLockon) const; diff --git a/Runtime/GuiSys/CTextParser.cpp b/Runtime/GuiSys/CTextParser.cpp index f1852f15a..952e8b35d 100644 --- a/Runtime/GuiSys/CTextParser.cpp +++ b/Runtime/GuiSys/CTextParser.cpp @@ -188,7 +188,7 @@ CFontImageDef CTextParser::GetImage(const char16_t* str, int len, texs.reserve(commaCount - 1); do { AdvanceCommaPos(); - texs.push_back(x0_store.GetObj({SBIG('TXTR'), GetAssetIdFromString(&iterable[tokenPos], len, txtrMap)})); + texs.emplace_back(x0_store.GetObj({SBIG('TXTR'), GetAssetIdFromString(&iterable[tokenPos], len, txtrMap)})); AdvanceTokenPos(); } while (commaPos != iterable.size()); @@ -211,7 +211,7 @@ CFontImageDef CTextParser::GetImage(const char16_t* str, int len, texs.reserve(commaCount - 3); do { AdvanceCommaPos(); - texs.push_back(x0_store.GetObj({SBIG('TXTR'), GetAssetIdFromString(&iterable[tokenPos], len, txtrMap)})); + texs.emplace_back(x0_store.GetObj({SBIG('TXTR'), GetAssetIdFromString(&iterable[tokenPos], len, txtrMap)})); AdvanceTokenPos(); } while (commaPos != iterable.size()); diff --git a/Runtime/GuiSys/CTextParser.hpp b/Runtime/GuiSys/CTextParser.hpp index 6cf4370cc..39d574b70 100644 --- a/Runtime/GuiSys/CTextParser.hpp +++ b/Runtime/GuiSys/CTextParser.hpp @@ -27,7 +27,7 @@ class CTextParser { TToken GetFont(const char16_t* str, int len); public: - CTextParser(IObjectStore& store) : x0_store(store) {} + explicit CTextParser(IObjectStore& store) : x0_store(store) {} void ParseText(CTextExecuteBuffer& out, const char16_t* str, int len, const std::vector>* txtrMap); }; diff --git a/Runtime/GuiSys/CTextRenderBuffer.cpp b/Runtime/GuiSys/CTextRenderBuffer.cpp index 2688855fe..c389ca7fa 100644 --- a/Runtime/GuiSys/CTextRenderBuffer.cpp +++ b/Runtime/GuiSys/CTextRenderBuffer.cpp @@ -12,31 +12,64 @@ namespace urde { +struct CTextRenderBuffer::BooFontCharacters { + TLockedToken m_font; + hecl::VertexBufferPool::Token m_instBuf; + boo::ObjToken m_dataBinding; + boo::ObjToken m_dataBinding2; + std::vector m_charData; + u32 m_charCount = 0; + bool m_dirty = true; + + BooFontCharacters(const CToken& token) : m_font(token) {} +}; + +struct CTextRenderBuffer::BooImage { + CFontImageDef m_imageDef; + hecl::VertexBufferPool::Token m_instBuf; + std::vector> m_dataBinding; + std::vector> m_dataBinding2; + CTextSupportShader::ImageInstance m_imageData; + bool m_dirty = true; + + BooImage(const CFontImageDef& imgDef, const zeus::CVector2i& offset) : m_imageDef(imgDef) { + m_imageData.SetMetrics(imgDef, offset); + } +}; + +struct CTextRenderBuffer::BooPrimitiveMark { + Command m_cmd; + u32 m_bindIdx; + u32 m_instIdx; + + void SetOpacity(CTextRenderBuffer& rb, float opacity) { + switch (m_cmd) { + case Command::CharacterRender: { + BooFontCharacters& fc = rb.m_fontCharacters[m_bindIdx]; + CTextSupportShader::CharacterInstance& inst = fc.m_charData[m_instIdx]; + inst.m_mulColor.a() = opacity; + fc.m_dirty = true; + break; + } + case Command::ImageRender: { + BooImage& img = rb.m_images[m_bindIdx]; + img.m_imageData.m_color.a() = opacity; + img.m_dirty = true; + break; + } + default: + break; + } + } +}; + +CTextRenderBuffer::CTextRenderBuffer(CTextRenderBuffer&&) noexcept = default; + CTextRenderBuffer::CTextRenderBuffer(EMode mode, CGuiWidget::EGuiModelDrawFlags df) : x0_mode(mode), m_drawFlags(df) {} -CTextRenderBuffer::BooImage::BooImage(const CFontImageDef& imgDef, const zeus::CVector2i& offset) : m_imageDef(imgDef) { - m_imageData.SetMetrics(imgDef, offset); -} +CTextRenderBuffer::~CTextRenderBuffer() = default; -void CTextRenderBuffer::BooPrimitiveMark::SetOpacity(CTextRenderBuffer& rb, float opacity) { - switch (m_cmd) { - case Command::CharacterRender: { - BooFontCharacters& fc = rb.m_fontCharacters[m_bindIdx]; - CTextSupportShader::CharacterInstance& inst = fc.m_charData[m_instIdx]; - inst.m_mulColor.a() = opacity; - fc.m_dirty = true; - break; - } - case Command::ImageRender: { - BooImage& img = rb.m_images[m_bindIdx]; - img.m_imageData.m_color.a() = opacity; - img.m_dirty = true; - break; - } - default: - break; - } -} +CTextRenderBuffer& CTextRenderBuffer::operator=(CTextRenderBuffer&&) noexcept = default; void CTextRenderBuffer::CommitResources() { if (m_committed) @@ -125,26 +158,28 @@ void CTextRenderBuffer::SetPrimitiveOpacity(int idx, float opacity) { m_primitiveMarks[idx].SetOpacity(*this, opacity); } -void CTextRenderBuffer::Render(const zeus::CColor& col, float time) const { - const_cast(this)->CommitResources(); +u32 CTextRenderBuffer::GetPrimitiveCount() const { return m_primitiveMarks.size(); } - zeus::CMatrix4f mv = CGraphics::g_GXModelView.toMatrix4f(); - zeus::CMatrix4f proj = CGraphics::GetPerspectiveProjectionMatrix(true); - zeus::CMatrix4f mat = proj * mv; +void CTextRenderBuffer::Render(const zeus::CColor& col, float time) { + CommitResources(); - const_cast(this)->m_uniBuf.access() = CTextSupportShader::Uniform{mat, col}; + const zeus::CMatrix4f mv = CGraphics::g_GXModelView.toMatrix4f(); + const zeus::CMatrix4f proj = CGraphics::GetPerspectiveProjectionMatrix(true); + const zeus::CMatrix4f mat = proj * mv; + + m_uniBuf.access() = CTextSupportShader::Uniform{mat, col}; if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { zeus::CColor colPremul = col * col.a(); colPremul.a() = col.a(); - const_cast(this)->m_uniBuf2.access() = CTextSupportShader::Uniform{mat, colPremul}; + m_uniBuf2.access() = CTextSupportShader::Uniform{mat, colPremul}; } - for (const BooFontCharacters& chs : m_fontCharacters) { + for (BooFontCharacters& chs : m_fontCharacters) { if (chs.m_charData.size()) { if (chs.m_dirty) { - memmove(const_cast(chs).m_instBuf.access(), chs.m_charData.data(), - sizeof(CTextSupportShader::CharacterInstance) * chs.m_charData.size()); - const_cast(chs).m_dirty = false; + std::memmove(chs.m_instBuf.access(), chs.m_charData.data(), + sizeof(CTextSupportShader::CharacterInstance) * chs.m_charData.size()); + chs.m_dirty = false; } CGraphics::SetShaderDataBinding(chs.m_dataBinding); CGraphics::DrawInstances(0, 4, chs.m_charData.size()); @@ -155,12 +190,12 @@ void CTextRenderBuffer::Render(const zeus::CColor& col, float time) const { } } - for (const BooImage& img : m_images) { + for (BooImage& img : m_images) { if (img.m_dirty) { - *const_cast(img).m_instBuf.access() = img.m_imageData; - const_cast(img).m_dirty = false; + *img.m_instBuf.access() = img.m_imageData; + img.m_dirty = false; } - int idx = int(img.m_imageDef.x0_fps * time) % img.m_dataBinding.size(); + const int idx = int(img.m_imageDef.x0_fps * time) % img.m_dataBinding.size(); CGraphics::SetShaderDataBinding(img.m_dataBinding[idx]); CGraphics::DrawInstances(0, 4, 1); if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { @@ -174,7 +209,7 @@ void CTextRenderBuffer::AddImage(const zeus::CVector2i& offset, const CFontImage if (x0_mode == EMode::AllocTally) m_primitiveMarks.push_back({Command::ImageRender, m_imagesCount++, 0}); else - m_images.push_back({image, offset}); + m_images.emplace_back(image, offset); } void CTextRenderBuffer::AddCharacter(const zeus::CVector2i& offset, char16_t ch, const zeus::CColor& color) { @@ -209,7 +244,7 @@ void CTextRenderBuffer::AddFontChange(const TToken& font) { } m_activeFontCh = m_fontCharacters.size(); - m_fontCharacters.push_back({font}); + m_fontCharacters.emplace_back(font); } bool CTextRenderBuffer::HasSpaceAvailable(const zeus::CVector2i& origin, const zeus::CVector2i& extent) const { diff --git a/Runtime/GuiSys/CTextRenderBuffer.hpp b/Runtime/GuiSys/CTextRenderBuffer.hpp index b3ad6806b..12d1caa71 100644 --- a/Runtime/GuiSys/CTextRenderBuffer.hpp +++ b/Runtime/GuiSys/CTextRenderBuffer.hpp @@ -65,35 +65,13 @@ private: hecl::UniformBufferPool::Token m_uniBuf; hecl::UniformBufferPool::Token m_uniBuf2; - struct BooFontCharacters { - TLockedToken m_font; - hecl::VertexBufferPool::Token m_instBuf; - boo::ObjToken m_dataBinding; - boo::ObjToken m_dataBinding2; - std::vector m_charData; - u32 m_charCount = 0; - bool m_dirty = true; - BooFontCharacters(const CToken& token) : m_font(token) {} - }; + struct BooFontCharacters; std::vector m_fontCharacters; - struct BooImage { - CFontImageDef m_imageDef; - hecl::VertexBufferPool::Token m_instBuf; - std::vector> m_dataBinding; - std::vector> m_dataBinding2; - CTextSupportShader::ImageInstance m_imageData; - bool m_dirty = true; - BooImage(const CFontImageDef& imgDef, const zeus::CVector2i& offset); - }; + struct BooImage; std::vector m_images; - struct BooPrimitiveMark { - Command m_cmd; - u32 m_bindIdx; - u32 m_instIdx; - void SetOpacity(CTextRenderBuffer& rb, float opacity); - }; + struct BooPrimitiveMark; std::vector m_primitiveMarks; u32 m_imagesCount = 0; u32 m_activeFontCh = UINT32_MAX; @@ -108,7 +86,12 @@ private: #endif public: + CTextRenderBuffer(CTextRenderBuffer&& other) noexcept; CTextRenderBuffer(EMode mode, CGuiWidget::EGuiModelDrawFlags df); + ~CTextRenderBuffer(); + + CTextRenderBuffer& operator=(CTextRenderBuffer&& other) noexcept; + #if 0 void SetPrimitive(const Primitive&, int); Primitive GetPrimitive(int) const; @@ -119,10 +102,10 @@ public: void AddPaletteChange(const CGraphicsPalette& palette); #else void SetPrimitiveOpacity(int idx, float opacity); - u32 GetPrimitiveCount() const { return m_primitiveMarks.size(); } + u32 GetPrimitiveCount() const; #endif void SetMode(EMode mode); - void Render(const zeus::CColor& col, float) const; + void Render(const zeus::CColor& col, float time); void AddImage(const zeus::CVector2i& offset, const CFontImageDef& image); void AddCharacter(const zeus::CVector2i& offset, char16_t ch, const zeus::CColor& color); void AddPaletteChange(const zeus::CColor& main, const zeus::CColor& outline); diff --git a/Runtime/GuiSys/CWordBreakTables.cpp b/Runtime/GuiSys/CWordBreakTables.cpp index d1e377f57..f132bb4e5 100644 --- a/Runtime/GuiSys/CWordBreakTables.cpp +++ b/Runtime/GuiSys/CWordBreakTables.cpp @@ -1,28 +1,28 @@ #include "Runtime/GuiSys/CWordBreakTables.hpp" -#include +#include #include "Runtime/GCNTypes.hpp" #include "Runtime/rstl.hpp" namespace urde { - +namespace { struct CCharacterIdentifier { wchar_t chr; u32 rank; }; -static const CCharacterIdentifier gCantBeginChars[] = { - {L'!', 1}, {L')', 1}, {L',', 1}, {L'-', 1}, {L'.', 1}, {L':', 1}, {L';', 1}, {L'?', 1}, - {L']', 1}, {L'}', 1}, {0x92, 1}, {0x94, 1}, {0xBB, 1}, {0x3001, 1}, {0x3002, 1}, {0x3005, 1}, - {0x300D, 1}, {0x300F, 1}, {0x3011, 1}, {0x3015, 1}, {0x3017, 1}, {0x3019, 1}, {0x301B, 1}, {0x301C, 3}, - {0x301E, 1}, {0x302B, 3}, {0x3041, 2}, {0x3043, 2}, {0x3045, 2}, {0x3047, 2}, {0x3049, 2}, {0x3063, 2}, - {0x3083, 2}, {0x3085, 2}, {0x3087, 2}, {0x308E, 2}, {0x309D, 3}, {0x309E, 3}, {0x30A1, 2}, {0x30A3, 2}, - {0x30A5, 2}, {0x30A7, 2}, {0x30A9, 2}, {0x30C3, 2}, {0x30E3, 2}, {0x30E5, 2}, {0x30E7, 2}, {0x30EE, 2}, - {0x30F5, 2}, {0x30F6, 2}, {0x30FC, 2}, {0x30FD, 3}, {0x30FE, 3}, {0xFF01, 1}, {0xFF05, 3}, {0xFF09, 1}, - {0xFF0D, 1}, {0xFF3D, 1}, {0xFF5D, 1}, {0xFF61, 1}, {0xFF63, 1}, {0xFF64, 1}, {0xFF1F, 1}}; +constexpr std::array sCantBeginChars{{ + {L'!', 1}, {L')', 1}, {L',', 1}, {L'-', 1}, {L'.', 1}, {L':', 1}, {L';', 1}, {L'?', 1}, {L']', 1}, + {L'}', 1}, {0x92, 1}, {0x94, 1}, {0xBB, 1}, {0x3001, 1}, {0x3002, 1}, {0x3005, 1}, {0x300D, 1}, {0x300F, 1}, + {0x3011, 1}, {0x3015, 1}, {0x3017, 1}, {0x3019, 1}, {0x301B, 1}, {0x301C, 3}, {0x301E, 1}, {0x302B, 3}, {0x3041, 2}, + {0x3043, 2}, {0x3045, 2}, {0x3047, 2}, {0x3049, 2}, {0x3063, 2}, {0x3083, 2}, {0x3085, 2}, {0x3087, 2}, {0x308E, 2}, + {0x309D, 3}, {0x309E, 3}, {0x30A1, 2}, {0x30A3, 2}, {0x30A5, 2}, {0x30A7, 2}, {0x30A9, 2}, {0x30C3, 2}, {0x30E3, 2}, + {0x30E5, 2}, {0x30E7, 2}, {0x30EE, 2}, {0x30F5, 2}, {0x30F6, 2}, {0x30FC, 2}, {0x30FD, 3}, {0x30FE, 3}, {0xFF01, 1}, + {0xFF05, 3}, {0xFF09, 1}, {0xFF0D, 1}, {0xFF3D, 1}, {0xFF5D, 1}, {0xFF61, 1}, {0xFF63, 1}, {0xFF64, 1}, {0xFF1F, 1}, +}}; -static const CCharacterIdentifier gCantEndChars[] = { +constexpr std::array sCantEndChars{{ {L'#', 2}, {L'$', 2}, {L'(', 1}, {L'@', 2}, {L'B', 4}, {L'C', 4}, {L'D', 4}, {L'E', 4}, {L'F', 4}, {L'G', 4}, {L'J', 4}, {L'K', 4}, {L'L', 4}, {L'M', 4}, {L'N', 4}, {L'P', 4}, {L'Q', 4}, {L'R', 4}, {L'S', 4}, {L'T', 4}, {L'V', 4}, {L'W', 4}, {L'X', 4}, {L'Y', 4}, {L'Z', 4}, {L'b', 4}, {L'c', 4}, @@ -33,21 +33,24 @@ static const CCharacterIdentifier gCantEndChars[] = { {0x20A5, 2}, {0x20A6, 2}, {0x20A7, 2}, {0x20A8, 2}, {0x20A9, 2}, {0x20AA, 2}, {0x20AB, 2}, {0x20AC, 2}, {0x300C, 1}, {0x300E, 1}, {0x3010, 1}, {0x3012, 2}, {0x3014, 1}, {0x3016, 1}, {0x3018, 1}, {0x301A, 1}, {0xFF03, 2}, {0xFF04, 2}, {0xFF20, 2}, {0xFF3C, 1}, {0xFF5C, 1}, {0xFFE0, 2}, {0xFFE1, 2}, {0xFFEF, 2}, -}; +}}; +} // Anonymous namespace int CWordBreakTables::GetBeginRank(wchar_t ch) { - auto search = rstl::binary_find(std::cbegin(gCantBeginChars), std::cend(gCantBeginChars), ch, - [](const CCharacterIdentifier& item) { return item.chr; }); - if (search == std::cend(gCantBeginChars)) + const auto search = rstl::binary_find(sCantBeginChars.cbegin(), sCantBeginChars.cend(), ch, + [](const CCharacterIdentifier& item) { return item.chr; }); + if (search == sCantBeginChars.cend()) { return 5; + } return search->rank; } int CWordBreakTables::GetEndRank(wchar_t ch) { - auto search = rstl::binary_find(std::cbegin(gCantEndChars), std::cend(gCantEndChars), ch, - [](const CCharacterIdentifier& item) { return item.chr; }); - if (search == std::cend(gCantEndChars)) + const auto search = rstl::binary_find(sCantEndChars.cbegin(), sCantEndChars.cend(), ch, + [](const CCharacterIdentifier& item) { return item.chr; }); + if (search == sCantEndChars.cend()) { return 5; + } return search->rank; } diff --git a/Runtime/ITweak.hpp b/Runtime/ITweak.hpp index feb72aa9c..05aff8296 100644 --- a/Runtime/ITweak.hpp +++ b/Runtime/ITweak.hpp @@ -3,6 +3,6 @@ namespace urde { class ITweak { public: - virtual ~ITweak() {} + virtual ~ITweak() = default; }; } // namespace urde diff --git a/Runtime/Input/CInputGenerator.hpp b/Runtime/Input/CInputGenerator.hpp index 0126102d0..dd444dc1e 100644 --- a/Runtime/Input/CInputGenerator.hpp +++ b/Runtime/Input/CInputGenerator.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -82,9 +83,9 @@ public: * report thread. This class atomically exchanges that data to the * game thread as needed */ struct DolphinSmashAdapterCallback : boo::IDolphinSmashAdapterCallback { - std::atomic m_statusChanges[4]; - bool m_connected[4] = {}; - boo::DolphinControllerState m_states[4]; + std::array, 4> m_statusChanges; + std::array m_connected{}; + std::array m_states; std::mutex m_stateLock; void controllerConnected(unsigned idx, boo::EDolphinControllerType) override { /* Controller thread */ @@ -103,7 +104,7 @@ public: m_states[idx] = state; } - CFinalInput m_lastUpdates[4]; + std::array m_lastUpdates; const CFinalInput& getFinalInput(unsigned idx, float dt, float leftDiv, float rightDiv) { /* Game thread */ std::unique_lock lk(m_stateLock); @@ -159,9 +160,9 @@ public: } } } - void ControlAllMotors(const EMotorState* states) { + void ControlAllMotors(const std::array& states) { if (smashAdapter) { - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < states.size(); ++i) { switch (states[i]) { case EMotorState::Stop: smashAdapter->stopRumble(i); diff --git a/Runtime/Input/CRumbleGenerator.cpp b/Runtime/Input/CRumbleGenerator.cpp index f39c24212..7887c405d 100644 --- a/Runtime/Input/CRumbleGenerator.cpp +++ b/Runtime/Input/CRumbleGenerator.cpp @@ -30,8 +30,8 @@ void CRumbleGenerator::Update(float dt) { if (!xf0_24_disabled) { bool updated = false; - for (int i = 0; i < 4; ++i) { - float intensity = x0_voices[i].GetIntensity(); + for (size_t i = 0; i < x0_voices.size(); ++i) { + const float intensity = x0_voices[i].GetIntensity(); if (!x0_voices[i].Update(dt) || intensity <= 0.f) { xc0_periodTime[i] = 0.f; xd0_onTime[i] = 0.f; @@ -76,31 +76,36 @@ void CRumbleGenerator::Update(float dt) { } } -static const EMotorState HardStopCommands[] = {EMotorState::StopHard, EMotorState::StopHard, EMotorState::StopHard, - EMotorState::StopHard}; - void CRumbleGenerator::HardStopAll() { - for (int i = 0; i < 4; ++i) { - xc0_periodTime[i] = 0.f; - xd0_onTime[i] = 0.f; - xe0_commandArray[i] = EMotorState::Stop; - x0_voices[i].HardReset(); + static constexpr std::array HardStopCommands{ + EMotorState::StopHard, + EMotorState::StopHard, + EMotorState::StopHard, + EMotorState::StopHard, + }; + + xc0_periodTime.fill(0.0f); + xd0_onTime.fill(0.0f); + xe0_commandArray.fill(EMotorState::Stop); + for (auto& voice : x0_voices) { + voice.HardReset(); } + g_InputGenerator->ControlAllMotors(HardStopCommands); } s16 CRumbleGenerator::Rumble(const SAdsrData& adsr, float gain, ERumblePriority prio, EIOPort port) { - CRumbleVoice& vox = x0_voices[int(port)]; - s16 freeChan = vox.GetFreeChannel(); + CRumbleVoice& vox = x0_voices[size_t(port)]; + const s16 freeChan = vox.GetFreeChannel(); if (prio >= vox.GetPriority(freeChan)) { - xc0_periodTime[int(port)] = 0.f; + xc0_periodTime[size_t(port)] = 0.f; return vox.Activate(adsr, freeChan, gain, prio); } return -1; } void CRumbleGenerator::Stop(s16 id, EIOPort port) { - CRumbleVoice& vox = x0_voices[int(port)]; + CRumbleVoice& vox = x0_voices[size_t(port)]; vox.Deactivate(id, false); } diff --git a/Runtime/Input/CRumbleGenerator.hpp b/Runtime/Input/CRumbleGenerator.hpp index d280e0d6c..51818fa1d 100644 --- a/Runtime/Input/CRumbleGenerator.hpp +++ b/Runtime/Input/CRumbleGenerator.hpp @@ -1,15 +1,17 @@ #pragma once +#include + #include "Runtime/GCNTypes.hpp" #include "Runtime/Input/CInputGenerator.hpp" #include "Runtime/Input/CRumbleVoice.hpp" namespace urde { class CRumbleGenerator { - CRumbleVoice x0_voices[4]; - float xc0_periodTime[4]; - float xd0_onTime[4]; - EMotorState xe0_commandArray[4]; + std::array x0_voices; + std::array xc0_periodTime; + std::array xd0_onTime; + std::array xe0_commandArray; bool xf0_24_disabled : 1; public: diff --git a/Runtime/Input/CRumbleVoice.cpp b/Runtime/Input/CRumbleVoice.cpp index 49bf8a0f5..4c21805a1 100644 --- a/Runtime/Input/CRumbleVoice.cpp +++ b/Runtime/Input/CRumbleVoice.cpp @@ -2,9 +2,7 @@ namespace urde { -CRumbleVoice::CRumbleVoice() { - x0_datas.resize(4); - x10_deltas.resize(4, SAdsrDelta::Stopped()); +CRumbleVoice::CRumbleVoice() : x0_datas(4), x10_deltas(4, SAdsrDelta::Stopped()) { x20_handleIds.resize(4); } @@ -24,16 +22,17 @@ bool CRumbleVoice::OwnsSustained(s16 handle) const { } s16 CRumbleVoice::GetFreeChannel() const { - for (s16 i = 0; i < 4; ++i) - if (!((1 << i) & x2c_usedChannels)) + for (s16 i = 0; i < 4; ++i) { + if (!((1 << i) & x2c_usedChannels)) { return i; - return false; + } + } + return 0; } float CRumbleVoice::GetIntensity() const { - return std::min(2.f, std::max(x10_deltas[0].x0_curIntensity, - std::max(x10_deltas[1].x0_curIntensity, - std::max(x10_deltas[2].x0_curIntensity, x10_deltas[3].x0_curIntensity)))); + return std::min(2.f, std::max({x10_deltas[0].x0_curIntensity, x10_deltas[1].x0_curIntensity, + x10_deltas[2].x0_curIntensity, x10_deltas[3].x0_curIntensity})); } bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float dt) { diff --git a/Runtime/MP1/CCredits.cpp b/Runtime/MP1/CCredits.cpp index 72e4e73fa..1c229dbc7 100644 --- a/Runtime/MP1/CCredits.cpp +++ b/Runtime/MP1/CCredits.cpp @@ -10,7 +10,7 @@ CIOWin::EMessageReturn CCredits::OnMessage(const CArchitectureMessage& msg, CArc return EMessageReturn::Normal; } -void CCredits::Draw() const { +void CCredits::Draw() { SCOPED_GRAPHICS_DEBUG_GROUP("CCredits::Draw", zeus::skGreen); } diff --git a/Runtime/MP1/CCredits.hpp b/Runtime/MP1/CCredits.hpp index 624b00ee7..6648a8a83 100644 --- a/Runtime/MP1/CCredits.hpp +++ b/Runtime/MP1/CCredits.hpp @@ -9,7 +9,7 @@ public: CCredits(); EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&) override; bool GetIsContinueDraw() const override { return false; } - void Draw() const override; + void Draw() override; }; } // namespace urde::MP1 diff --git a/Runtime/MP1/CFaceplateDecoration.hpp b/Runtime/MP1/CFaceplateDecoration.hpp index 76518afd1..94891bfaa 100644 --- a/Runtime/MP1/CFaceplateDecoration.hpp +++ b/Runtime/MP1/CFaceplateDecoration.hpp @@ -18,7 +18,7 @@ class CFaceplateDecoration { std::optional m_texFilter; public: - CFaceplateDecoration(CStateManager& stateMgr); + explicit CFaceplateDecoration(CStateManager& stateMgr); void Update(float dt, CStateManager& stateMgr); void Draw(CStateManager& stateMgr); }; diff --git a/Runtime/MP1/CFrontEndUI.cpp b/Runtime/MP1/CFrontEndUI.cpp index 69aa28b0a..6fedaf6f3 100644 --- a/Runtime/MP1/CFrontEndUI.cpp +++ b/Runtime/MP1/CFrontEndUI.cpp @@ -1906,9 +1906,10 @@ void CFrontEndUI::CompleteStateTransition() { void CFrontEndUI::HandleDebugMenuReturnValue(CGameDebug::EReturnValue val, CArchitectureQueue& queue) {} -void CFrontEndUI::Draw() const { - if (x14_phase < EPhase::DisplayFrontEnd) +void CFrontEndUI::Draw() { + if (x14_phase < EPhase::DisplayFrontEnd) { return; + } SCOPED_GRAPHICS_DEBUG_GROUP("CFrontEndUI::Draw", zeus::skGreen); if (xec_emuFrme) { @@ -1948,12 +1949,13 @@ void CFrontEndUI::Draw() const { if (x64_pressStartAlpha > 0.f && x38_pressStart.IsLoaded() && m_pressStartQuad) { /* Render "Press Start" */ - zeus::CRectangle rect(0.5f - x38_pressStart->GetWidth() / 2.f / 640.f * hPad, - 0.5f + (x38_pressStart->GetHeight() / 2.f - 240.f + 72.f) / 480.f * vPad, - x38_pressStart->GetWidth() / 640.f * hPad, x38_pressStart->GetHeight() / 480.f * vPad); + const zeus::CRectangle rect(0.5f - x38_pressStart->GetWidth() / 2.f / 640.f * hPad, + 0.5f + (x38_pressStart->GetHeight() / 2.f - 240.f + 72.f) / 480.f * vPad, + x38_pressStart->GetWidth() / 640.f * hPad, + x38_pressStart->GetHeight() / 480.f * vPad); zeus::CColor color = zeus::skWhite; color.a() = x64_pressStartAlpha; - const_cast(*m_pressStartQuad).draw(color, 1.f, rect); + m_pressStartQuad->draw(color, 1.f, rect); } if (xc0_attractCount > 0) { @@ -1964,7 +1966,7 @@ void CFrontEndUI::Draw() const { /* To black */ zeus::CColor color = zeus::skBlack; color.a() = 1.f - x58_fadeBlackTimer; - const_cast(m_fadeToBlack).draw(color); + m_fadeToBlack.draw(color); } } @@ -1974,12 +1976,12 @@ void CFrontEndUI::Draw() const { /* To black */ zeus::CColor color = zeus::skBlack; color.a() = zeus::clamp(0.f, 1.f - x58_fadeBlackTimer, 1.f); - const_cast(m_fadeToBlack).draw(color); + m_fadeToBlack.draw(color); } else if (x50_curScreen == EScreen::Title && x54_nextScreen == EScreen::Title) { /* From black with 30-sec skip to title */ zeus::CColor color = zeus::skBlack; color.a() = 1.f - zeus::clamp(0.f, 30.f - x58_fadeBlackTimer, 1.f); - const_cast(m_fadeToBlack).draw(color); + m_fadeToBlack.draw(color); } } diff --git a/Runtime/MP1/CFrontEndUI.hpp b/Runtime/MP1/CFrontEndUI.hpp index 8bbc37798..b1c2aac75 100644 --- a/Runtime/MP1/CFrontEndUI.hpp +++ b/Runtime/MP1/CFrontEndUI.hpp @@ -203,7 +203,7 @@ public: bool m_gbaOverride = false; - SFusionBonusFrame(CFrontEndUITouchBar& touchBar); + explicit SFusionBonusFrame(CFrontEndUITouchBar& touchBar); void FinishedLoading(); bool PumpLoad(); void SetTableColors(CGuiTableGroup* tbgp) const; @@ -354,7 +354,7 @@ private: std::unique_ptr xf0_optionsFrme; CStaticAudioPlayer* xf4_curAudio = nullptr; - CColoredQuadFilter m_fadeToBlack = {EFilterType::Blend}; + CColoredQuadFilter m_fadeToBlack{EFilterType::Blend}; std::optional m_pressStartQuad; std::unique_ptr m_touchBar; @@ -385,7 +385,7 @@ public: void StartStateTransition(EScreen screen); void CompleteStateTransition(); void HandleDebugMenuReturnValue(CGameDebug::EReturnValue val, CArchitectureQueue& queue); - void Draw() const override; + void Draw() override; void UpdateMovies(float dt); bool PumpMovieLoad(); void ProcessUserInput(const CFinalInput& input, CArchitectureQueue& queue); diff --git a/Runtime/MP1/CFrontEndUITouchBar.cpp b/Runtime/MP1/CFrontEndUITouchBar.cpp index ccc5ccf2f..6afb30f10 100644 --- a/Runtime/MP1/CFrontEndUITouchBar.cpp +++ b/Runtime/MP1/CFrontEndUITouchBar.cpp @@ -2,7 +2,7 @@ namespace urde { -CFrontEndUITouchBar::~CFrontEndUITouchBar() {} +CFrontEndUITouchBar::~CFrontEndUITouchBar() = default; void CFrontEndUITouchBar::SetPhase(EPhase ph) { m_phase = ph; } CFrontEndUITouchBar::EPhase CFrontEndUITouchBar::GetPhase() { return m_phase; } void CFrontEndUITouchBar::SetFileSelectPhase(const SFileSelectDetail details[3], bool eraseGame, bool galleryActive) { diff --git a/Runtime/MP1/CInGameGuiManager.cpp b/Runtime/MP1/CInGameGuiManager.cpp index 2b138e9ce..effe4dd60 100644 --- a/Runtime/MP1/CInGameGuiManager.cpp +++ b/Runtime/MP1/CInGameGuiManager.cpp @@ -279,7 +279,7 @@ void CInGameGuiManager::OnNewPauseScreenState(CArchitectureQueue& archQueue) { x1bc_prevState = x1c0_nextState; } -void CInGameGuiManager::UpdateAutoMapper(float dt, const CStateManager& stateMgr) { +void CInGameGuiManager::UpdateAutoMapper(float dt, CStateManager& stateMgr) { x38_autoMapper->Update(dt, stateMgr); zeus::CTransform xf = x148_model_automapper->GetParent()->GetWorldTransform() * x144_basewidget_automapper->GetTransform(); diff --git a/Runtime/MP1/CInGameGuiManager.hpp b/Runtime/MP1/CInGameGuiManager.hpp index 367c0e8e4..76ba934f2 100644 --- a/Runtime/MP1/CInGameGuiManager.hpp +++ b/Runtime/MP1/CInGameGuiManager.hpp @@ -98,9 +98,9 @@ private: std::optional m_deathRenderTexQuad; std::optional m_deathDotQuad; - CRandomStaticFilter m_randomStatic = {EFilterType::Blend}; - CColoredQuadFilter m_deathWhiteout = {EFilterType::Blend}; - CColoredQuadFilter m_deathBlackout = {EFilterType::Blend}; + CRandomStaticFilter m_randomStatic{EFilterType::Blend}; + CColoredQuadFilter m_deathWhiteout{EFilterType::Blend}; + CColoredQuadFilter m_deathBlackout{EFilterType::Blend}; union { struct { @@ -121,12 +121,12 @@ private: void TryReloadAreaTextures(); bool IsInGameStateNotTransitioning() const; bool IsInPausedStateNotTransitioning() const; - void UpdateAutoMapper(float dt, const CStateManager& stateMgr); + void UpdateAutoMapper(float dt, CStateManager& stateMgr); void OnNewPauseScreenState(CArchitectureQueue& archQueue); void RefreshHudOptions(); public: - CInGameGuiManager(CStateManager& stateMgr, CArchitectureQueue& archQueue); + explicit CInGameGuiManager(CStateManager& stateMgr, CArchitectureQueue& archQueue); bool CheckLoadComplete(CStateManager& stateMgr); void Update(CStateManager& stateMgr, float dt, CArchitectureQueue& archQueue, bool useHud); void ProcessControllerInput(CStateManager& stateMgr, const CFinalInput& input, CArchitectureQueue& archQueue); diff --git a/Runtime/MP1/CMFGame.cpp b/Runtime/MP1/CMFGame.cpp index 5bfa54a36..affd3f57e 100644 --- a/Runtime/MP1/CMFGame.cpp +++ b/Runtime/MP1/CMFGame.cpp @@ -193,12 +193,13 @@ void CMFGame::Touch() { player.GetMorphBall()->TouchModel(*x14_stateManager); } -void CMFGame::Draw() const { - if (!x2a_24_initialized) +void CMFGame::Draw() { + if (!x2a_24_initialized) { return; + } SCOPED_GRAPHICS_DEBUG_GROUP("CMFGame::Draw", zeus::skGreen); - const_cast(*this).Touch(); + Touch(); if (x18_guiManager->GetIsGameDraw()) { static_cast(*g_Main).SetGameFrameDrawn(); x14_stateManager->PreRender(); @@ -210,8 +211,8 @@ void CMFGame::Draw() const { x18_guiManager->Draw(*x14_stateManager); if (x1c_flowState == EGameFlowState::CinematicSkip) { - float c = std::min(1.f, 1.f - x20_cineSkipTime); - const_cast(m_fadeToBlack).draw(zeus::CColor{c, c, c, c}); + const float c = std::min(1.f, 1.f - x20_cineSkipTime); + m_fadeToBlack.draw(zeus::CColor{c, c, c, c}); } } @@ -279,7 +280,7 @@ CMFGameLoader::CMFGameLoader() : CMFGameLoaderBase("CMFGameLoader") { } } -CMFGameLoader::~CMFGameLoader() {} +CMFGameLoader::~CMFGameLoader() = default; static const char* LoadDepPAKs[] = {"TestAnim", "SamusGun", "SamGunFx", nullptr}; @@ -364,7 +365,7 @@ CIOWin::EMessageReturn CMFGameLoader::OnMessage(const CArchitectureMessage& msg, return EMessageReturn::Exit; } -void CMFGameLoader::Draw() const { +void CMFGameLoader::Draw() { SCOPED_GRAPHICS_DEBUG_GROUP("CMFGameLoader::Draw", zeus::skGreen); g_GameState->GetWorldTransitionManager()->Draw(); } diff --git a/Runtime/MP1/CMFGame.hpp b/Runtime/MP1/CMFGame.hpp index 261bbba37..fe7d70ca3 100644 --- a/Runtime/MP1/CMFGame.hpp +++ b/Runtime/MP1/CMFGame.hpp @@ -31,7 +31,7 @@ class CMFGame : public CMFGameBase { u8 _dummy = 0; }; - CColoredQuadFilter m_fadeToBlack = {EFilterType::Multiply}; + CColoredQuadFilter m_fadeToBlack{EFilterType::Multiply}; bool IsCameraActiveFlow() const { return (x1c_flowState == EGameFlowState::InGame || x1c_flowState == EGameFlowState::SamusDied); @@ -43,7 +43,7 @@ public: ~CMFGame() override; CIOWin::EMessageReturn OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) override; void Touch(); - void Draw() const override; + void Draw() override; void PlayerDied(); void UnpauseGame(); void EnterMessageScreen(float time); @@ -72,7 +72,7 @@ public: CMFGameLoader(); ~CMFGameLoader() override; EMessageReturn OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) override; - void Draw() const override; + void Draw() override; }; } // namespace MP1 diff --git a/Runtime/MP1/CMainFlow.cpp b/Runtime/MP1/CMainFlow.cpp index 8822d8c9c..5cf040a5f 100644 --- a/Runtime/MP1/CMainFlow.cpp +++ b/Runtime/MP1/CMainFlow.cpp @@ -90,9 +90,9 @@ void CMainFlow::SetGameState(EClientFlowStates state, CArchitectureQueue& queue) } case EClientFlowStates::Game: { g_GameState->GameOptions().EnsureSettings(); - std::shared_ptr gameLoader = std::make_shared(); + auto gameLoader = std::make_shared(); main->SetFlowState(EFlowState::Default); - queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 10, 1000, gameLoader)); + queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 10, 1000, std::move(gameLoader))); break; } default: diff --git a/Runtime/MP1/CMainFlow.hpp b/Runtime/MP1/CMainFlow.hpp index ec2a5df57..04c0f0da1 100644 --- a/Runtime/MP1/CMainFlow.hpp +++ b/Runtime/MP1/CMainFlow.hpp @@ -14,7 +14,7 @@ public: void AdvanceGameState(CArchitectureQueue& queue) override; void SetGameState(EClientFlowStates state, CArchitectureQueue& queue) override; bool GetIsContinueDraw() const override { return false; } - void Draw() const override {} + void Draw() override {} }; } // namespace MP1 diff --git a/Runtime/MP1/CMemoryCardDriver.cpp b/Runtime/MP1/CMemoryCardDriver.cpp index 8f916ed80..0cf7076e4 100644 --- a/Runtime/MP1/CMemoryCardDriver.cpp +++ b/Runtime/MP1/CMemoryCardDriver.cpp @@ -1,11 +1,13 @@ #include "Runtime/MP1/CMemoryCardDriver.hpp" +#include + #include "Runtime/CCRC32.hpp" #include "Runtime/MP1/MP1.hpp" namespace urde::MP1 { -static const char* SaveFileNames[] = {"MetroidPrime A", "MetroidPrime B"}; +constexpr std::array SaveFileNames{"MetroidPrime A", "MetroidPrime B"}; using ECardResult = kabufuda::ECardResult; using ECardSlot = kabufuda::ECardSlot; @@ -100,19 +102,19 @@ ECardResult CMemoryCardDriver::SFileInfo::GetSaveDataOffset(u32& offOut) const { CMemoryCardDriver::SGameFileSlot::SGameFileSlot() { InitializeFromGameState(); } CMemoryCardDriver::SGameFileSlot::SGameFileSlot(CMemoryInStream& in) { - in.readBytesToBuf(x0_saveBuffer, 940); - x944_fileInfo = CGameState::LoadGameFileState(x0_saveBuffer); + in.readBytesToBuf(x0_saveBuffer.data(), x0_saveBuffer.size()); + x944_fileInfo = CGameState::LoadGameFileState(x0_saveBuffer.data()); } void CMemoryCardDriver::SGameFileSlot::InitializeFromGameState() { - CBitStreamWriter w(x0_saveBuffer, 940); + CBitStreamWriter w(x0_saveBuffer.data(), x0_saveBuffer.size()); g_GameState->PutTo(w); w.Flush(); - x944_fileInfo = CGameState::LoadGameFileState(x0_saveBuffer); + x944_fileInfo = CGameState::LoadGameFileState(x0_saveBuffer.data()); } void CMemoryCardDriver::SGameFileSlot::LoadGameState(u32 idx) { - CBitStreamReader r(x0_saveBuffer, 940); + CBitStreamReader r(x0_saveBuffer.data(), x0_saveBuffer.size()); static_cast(g_Main)->StreamNewGameState(r, idx); } @@ -146,8 +148,9 @@ const CGameState::GameFileStateInfo* CMemoryCardDriver::GetGameFileStateInfo(int CMemoryCardDriver::SSaveHeader CMemoryCardDriver::LoadSaveHeader(CMemoryInStream& in) { SSaveHeader ret; ret.x0_version = in.readUint32Big(); - for (int i = 0; i < 3; ++i) - ret.x4_savePresent[i] = in.readBool(); + for (bool& present : ret.x4_savePresent) { + present = in.readBool(); + } return ret; } @@ -167,27 +170,30 @@ void CMemoryCardDriver::ReadFinished() { x20_fileTime = stat.GetTime(); CMemoryInStream r(fileInfo.x34_saveData.data(), 3004); SSaveHeader header = LoadSaveHeader(r); - r.readBytesToBuf(x30_systemData, 174); + r.readBytesToBuf(x30_systemData.data(), x30_systemData.size()); - for (int i = 0; i < 3; ++i) - if (header.x4_savePresent[i]) + for (size_t i = 0; i < xe4_fileSlots.size(); ++i) { + if (header.x4_savePresent[i]) { xe4_fileSlots[i] = LoadSaveFile(r); + } + } - if (x19d_importPersistent) + if (x19d_importPersistent) { ImportPersistentOptions(); + } } void CMemoryCardDriver::ImportPersistentOptions() { - CBitStreamReader r(x30_systemData, 174); + CBitStreamReader r(x30_systemData.data(), x30_systemData.size()); CPersistentOptions opts(r); g_GameState->ImportPersistentOptions(opts); } void CMemoryCardDriver::ExportPersistentOptions() { - CBitStreamReader r(x30_systemData, 174); + CBitStreamReader r(x30_systemData.data(), x30_systemData.size()); CPersistentOptions opts(r); g_GameState->ExportPersistentOptions(opts); - CBitStreamWriter w(x30_systemData, 174); + CBitStreamWriter w(x30_systemData.data(), x30_systemData.size()); opts.PutTo(w); } @@ -635,7 +641,7 @@ void CMemoryCardDriver::BuildNewFileSlot(u32 saveIdx) { slot = std::make_unique(); slot->LoadGameState(saveIdx); - CBitStreamReader r(x30_systemData, 174); + CBitStreamReader r(x30_systemData.data(), x30_systemData.size()); g_GameState->ReadPersistentOptions(r); ImportPersistentOptions(); g_GameState->SetCardSerial(x28_cardSerial); @@ -653,7 +659,7 @@ void CMemoryCardDriver::BuildExistingFileSlot(u32 saveIdx) { else slot->InitializeFromGameState(); - CBitStreamWriter w(x30_systemData, 174); + CBitStreamWriter w(x30_systemData.data(), x30_systemData.size()); g_GameState->PutTo(w); } @@ -674,15 +680,18 @@ void CMemoryCardDriver::InitializeFileInfo() { CMemoryOutStream w = x198_fileInfo->BeginMemoryOut(3004); SSaveHeader header; - for (int i = 0; i < 3; ++i) - header.x4_savePresent[i] = xe4_fileSlots[i].operator bool(); + for (size_t i = 0; i < xe4_fileSlots.size(); ++i) { + header.x4_savePresent[i] = xe4_fileSlots[i] != nullptr; + } header.DoPut(w); - w.writeBytes(x30_systemData, 174); + w.writeBytes(x30_systemData.data(), x30_systemData.size()); - for (int i = 0; i < 3; ++i) - if (xe4_fileSlots[i]) - xe4_fileSlots[i]->DoPut(w); + for (auto& fileSlot : xe4_fileSlots) { + if (fileSlot) { + fileSlot->DoPut(w); + } + } } void CMemoryCardDriver::WriteBackupBuf() { diff --git a/Runtime/MP1/CMemoryCardDriver.hpp b/Runtime/MP1/CMemoryCardDriver.hpp index 2e89cdd2d..732e39181 100644 --- a/Runtime/MP1/CMemoryCardDriver.hpp +++ b/Runtime/MP1/CMemoryCardDriver.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -87,22 +88,25 @@ private: struct SSaveHeader { u32 x0_version = 0; - bool x4_savePresent[3]; + std::array x4_savePresent{}; + void DoPut(CMemoryOutStream& out) const { out.writeUint32Big(x0_version); - for (int i = 0; i < 3; ++i) - out.writeBool(x4_savePresent[i]); + for (const bool savePresent : x4_savePresent) { + out.writeBool(savePresent); + } } }; struct SGameFileSlot { - u8 x0_saveBuffer[940] = {}; + std::array x0_saveBuffer{}; CGameState::GameFileStateInfo x944_fileInfo; + SGameFileSlot(); - SGameFileSlot(CMemoryInStream& in); + explicit SGameFileSlot(CMemoryInStream& in); void InitializeFromGameState(); void LoadGameState(u32 idx); - void DoPut(CMemoryOutStream& w) const { w.writeBytes(x0_saveBuffer, 940); } + void DoPut(CMemoryOutStream& w) const { w.writeBytes(x0_saveBuffer.data(), x0_saveBuffer.size()); } }; enum class EFileState { Unknown, NoFile, File, BadFile }; @@ -117,8 +121,8 @@ private: s32 x1c_cardFreeFiles = 0; u32 x20_fileTime = 0; u64 x28_cardSerial = 0; - u8 x30_systemData[174] = {}; - std::unique_ptr xe4_fileSlots[3]; + std::array x30_systemData{}; + std::array, 3> xe4_fileSlots; std::vector> x100_mcFileInfos; u32 x194_fileIdx = -1; std::unique_ptr x198_fileInfo; diff --git a/Runtime/MP1/CMessageScreen.hpp b/Runtime/MP1/CMessageScreen.hpp index ea0b77b7e..8998cb06f 100644 --- a/Runtime/MP1/CMessageScreen.hpp +++ b/Runtime/MP1/CMessageScreen.hpp @@ -39,7 +39,7 @@ class CMessageScreen { bool x78_24_exit : 1; public: - CMessageScreen(CAssetId msg, float time); + explicit CMessageScreen(CAssetId msg, float time); void ProcessControllerInput(const CFinalInput& input); bool Update(float dt, float blurAmt); void Draw() const; diff --git a/Runtime/MP1/CPauseScreenBlur.hpp b/Runtime/MP1/CPauseScreenBlur.hpp index 7ea1e5080..e96b2eafc 100644 --- a/Runtime/MP1/CPauseScreenBlur.hpp +++ b/Runtime/MP1/CPauseScreenBlur.hpp @@ -20,8 +20,8 @@ class CPauseScreenBlur { EState x14_nextState = EState::InGame; float x18_blurAmt = 0.f; CCameraBlurPass x1c_camBlur; - CTexturedQuadFilter m_quarterFilter = {EFilterType::Multiply, x4_mapLightQuarter}; - CScanLinesFilterEven m_linesFilter = {EFilterType::Multiply}; + CTexturedQuadFilter m_quarterFilter{EFilterType::Multiply, x4_mapLightQuarter}; + CScanLinesFilterEven m_linesFilter{EFilterType::Multiply}; union { struct { diff --git a/Runtime/MP1/CPlayMovie.hpp b/Runtime/MP1/CPlayMovie.hpp index cb1d7199e..f881461e1 100644 --- a/Runtime/MP1/CPlayMovie.hpp +++ b/Runtime/MP1/CPlayMovie.hpp @@ -32,7 +32,7 @@ private: static bool IsResultsScreen(EWhichMovie which); public: - CPlayMovie(EWhichMovie which); + explicit CPlayMovie(EWhichMovie which); }; } // namespace urde::MP1 diff --git a/Runtime/MP1/CPlayerVisor.cpp b/Runtime/MP1/CPlayerVisor.cpp index ffd84babb..bf499de71 100644 --- a/Runtime/MP1/CPlayerVisor.cpp +++ b/Runtime/MP1/CPlayerVisor.cpp @@ -321,29 +321,30 @@ void CPlayerVisor::LockUnlockAssets() { #endif } -void CPlayerVisor::DrawScanEffect(const CStateManager& mgr, const CTargetingManager* tgtMgr) const { +void CPlayerVisor::DrawScanEffect(const CStateManager& mgr, const CTargetingManager* tgtMgr) { SCOPED_GRAPHICS_DEBUG_GROUP("CPlayerVisor::DrawScanEffect", zeus::skMagenta); - bool indicatorsDrawn = DrawScanObjectIndicators(mgr); + const bool indicatorsDrawn = DrawScanObjectIndicators(mgr); if (tgtMgr && indicatorsDrawn) { CGraphics::SetDepthRange(DEPTH_TARGET_MANAGER, DEPTH_TARGET_MANAGER); tgtMgr->Draw(mgr, false); CGraphics::SetDepthRange(DEPTH_SCREEN_ACTORS, DEPTH_GUN); } - float transFactor = mgr.GetPlayerState()->GetVisorTransitionFactor(); - float scanSidesDuration = g_tweakGui->GetScanSidesDuration(); - float scanSidesStart = g_tweakGui->GetScanSidesStartTime(); + const float transFactor = mgr.GetPlayerState()->GetVisorTransitionFactor(); + const float scanSidesDuration = g_tweakGui->GetScanSidesDuration(); + const float scanSidesStart = g_tweakGui->GetScanSidesStartTime(); float t; - if (x34_nextState == EScanWindowState::Scan) + if (x34_nextState == EScanWindowState::Scan) { t = 1.f - ((x3c_windowInterpTimer < scanSidesDuration) ? 0.f : (x3c_windowInterpTimer - scanSidesDuration) / scanSidesStart); - else + } else { t = (x3c_windowInterpTimer > scanSidesStart) ? 1.f : x3c_windowInterpTimer / scanSidesStart; + } - float vpScale = g_Viewport.xc_height / 448.f; + const float vpScale = g_Viewport.xc_height / 448.f; float divisor = (transFactor * ((1.f - t) * x58_scanMagInterp + t * g_tweakGui->GetScanWindowScanningAspect()) + (1.f - transFactor)); divisor = 1.f / divisor; @@ -353,35 +354,37 @@ void CPlayerVisor::DrawScanEffect(const CStateManager& mgr, const CTargetingMana vpH = zeus::clamp(0.f, vpH, 448.f) * vpScale; SClipScreenRect rect; - rect.x4_left = (g_Viewport.x8_width - vpW) / 2.f; - rect.x8_top = (g_Viewport.xc_height - vpH) / 2.f; - rect.xc_width = vpW; - rect.x10_height = vpH; + rect.x4_left = int((g_Viewport.x8_width - vpW) / 2.f); + rect.x8_top = int((g_Viewport.xc_height - vpH) / 2.f); + rect.xc_width = int(vpW); + rect.x10_height = int(vpH); CGraphics::ResolveSpareTexture(rect); x64_scanDim.Draw(); g_Renderer->SetViewportOrtho(true, -1.f, 1.f); - zeus::CTransform windowScale = zeus::CTransform::Scale(x48_interpWindowDims.x(), 1.f, x48_interpWindowDims.y()); - zeus::CTransform seventeenScale = zeus::CTransform::Scale(17.f * vpScale, 1.f, 17.f * vpScale); + const zeus::CTransform windowScale = zeus::CTransform::Scale(x48_interpWindowDims.x(), 1.f, x48_interpWindowDims.y()); + const zeus::CTransform seventeenScale = zeus::CTransform::Scale(17.f * vpScale, 1.f, 17.f * vpScale); CGraphics::SetModelMatrix(seventeenScale * windowScale); - float uvX0 = rect.x4_left / float(g_Viewport.x8_width); - float uvX1 = (rect.x4_left + rect.xc_width) / float(g_Viewport.x8_width); - float uvY0 = rect.x8_top / float(g_Viewport.xc_height); - float uvY1 = (rect.x8_top + rect.x10_height) / float(g_Viewport.xc_height); - CTexturedQuadFilter::Vert rttVerts[4] = {{{-5.f, 0.f, 4.45f}, {uvX0, uvY0}}, - {{5.f, 0.f, 4.45f}, {uvX1, uvY0}}, - {{-5.f, 0.f, -4.45f}, {uvX0, uvY1}}, - {{5.f, 0.f, -4.45f}, {uvX1, uvY1}}}; + const float uvX0 = float(rect.x4_left) / float(g_Viewport.x8_width); + const float uvX1 = float(rect.x4_left + rect.xc_width) / float(g_Viewport.x8_width); + const float uvY0 = float(rect.x8_top) / float(g_Viewport.xc_height); + const float uvY1 = float(rect.x8_top + rect.x10_height) / float(g_Viewport.xc_height); + CTexturedQuadFilter::Vert rttVerts[4] = { + {{-5.f, 0.f, 4.45f}, {uvX0, uvY0}}, + {{5.f, 0.f, 4.45f}, {uvX1, uvY0}}, + {{-5.f, 0.f, -4.45f}, {uvX0, uvY1}}, + {{5.f, 0.f, -4.45f}, {uvX1, uvY1}}, + }; if (CGraphics::g_BooPlatform == boo::IGraphicsDataFactory::Platform::OpenGL) { rttVerts[0].m_uv.y() = uvY1; rttVerts[1].m_uv.y() = uvY1; rttVerts[2].m_uv.y() = uvY0; rttVerts[3].m_uv.y() = uvY0; } - const_cast(x108_newScanPane).drawVerts(zeus::CColor(1.f, transFactor), rttVerts); + x108_newScanPane.drawVerts(zeus::CColor(1.f, transFactor), rttVerts); // No cull faces @@ -394,11 +397,11 @@ void CPlayerVisor::DrawScanEffect(const CStateManager& mgr, const CTargetingMana zeus::CColor(x550_scanFrameColorImpulseInterp, x550_scanFrameColorImpulseInterp)); flags.m_noCull = true; - zeus::CTransform verticalFlip = zeus::CTransform::Scale(1.f, 1.f, -1.f); - zeus::CTransform horizontalFlip = zeus::CTransform::Scale(-1.f, 1.f, 1.f); + const zeus::CTransform verticalFlip = zeus::CTransform::Scale(1.f, 1.f, -1.f); + const zeus::CTransform horizontalFlip = zeus::CTransform::Scale(-1.f, 1.f, 1.f); if (xe4_scanFrameCenterTop.IsLoaded()) { - zeus::CTransform modelXf = + const zeus::CTransform modelXf = seventeenScale * zeus::CTransform::Translate(windowScale * zeus::CVector3f(0.f, 0.f, 4.553f)); CGraphics::SetModelMatrix(modelXf); xe4_scanFrameCenterTop->Draw(flags); @@ -407,7 +410,7 @@ void CPlayerVisor::DrawScanEffect(const CStateManager& mgr, const CTargetingMana } if (xd8_scanFrameCenterSide.IsLoaded()) { - zeus::CTransform modelXf = + const zeus::CTransform modelXf = seventeenScale * zeus::CTransform::Translate(windowScale * zeus::CVector3f(-5.f, 0.f, 0.f)); CGraphics::SetModelMatrix(modelXf); xd8_scanFrameCenterSide->Draw(flags); @@ -416,7 +419,7 @@ void CPlayerVisor::DrawScanEffect(const CStateManager& mgr, const CTargetingMana } if (xcc_scanFrameCorner.IsLoaded()) { - zeus::CTransform modelXf = + const zeus::CTransform modelXf = seventeenScale * zeus::CTransform::Translate(windowScale * zeus::CVector3f(-5.f, 0.f, 4.553f)); CGraphics::SetModelMatrix(modelXf); xcc_scanFrameCorner->Draw(flags); @@ -429,9 +432,9 @@ void CPlayerVisor::DrawScanEffect(const CStateManager& mgr, const CTargetingMana } if (xfc_scanFrameStretchTop.IsLoaded()) { - zeus::CTransform modelXf = seventeenScale * - zeus::CTransform::Translate(-1.f, 0.f, 4.553f * windowScale.basis[2][2]) * - zeus::CTransform::Scale(5.f * windowScale.basis[0][0] - 1.f - 1.884f, 1.f, 1.f); + const zeus::CTransform modelXf = seventeenScale * + zeus::CTransform::Translate(-1.f, 0.f, 4.553f * windowScale.basis[2][2]) * + zeus::CTransform::Scale(5.f * windowScale.basis[0][0] - 1.f - 1.884f, 1.f, 1.f); CGraphics::SetModelMatrix(modelXf); xfc_scanFrameStretchTop->Draw(flags); CGraphics::SetModelMatrix(horizontalFlip * modelXf); @@ -443,8 +446,9 @@ void CPlayerVisor::DrawScanEffect(const CStateManager& mgr, const CTargetingMana } if (xf0_scanFrameStretchSide.IsLoaded()) { - zeus::CTransform modelXf = seventeenScale * zeus::CTransform::Translate(-5.f * windowScale.basis[0][0], 0.f, 1.f) * - zeus::CTransform::Scale(1.f, 1.f, 4.553f * windowScale.basis[2][2] - 1.f - 1.886f); + const zeus::CTransform modelXf = seventeenScale * + zeus::CTransform::Translate(-5.f * windowScale.basis[0][0], 0.f, 1.f) * + zeus::CTransform::Scale(1.f, 1.f, 4.553f * windowScale.basis[2][2] - 1.f - 1.886f); CGraphics::SetModelMatrix(modelXf); xf0_scanFrameStretchSide->Draw(flags); CGraphics::SetModelMatrix(horizontalFlip * modelXf); @@ -458,12 +462,12 @@ void CPlayerVisor::DrawScanEffect(const CStateManager& mgr, const CTargetingMana // cull faces } -void CPlayerVisor::DrawXRayEffect(const CStateManager&) const { +void CPlayerVisor::DrawXRayEffect(const CStateManager&) { SCOPED_GRAPHICS_DEBUG_GROUP("CPlayerVisor::DrawXRayEffect", zeus::skMagenta); - const_cast(x90_xrayBlur).Draw(); + x90_xrayBlur.Draw(); } -void CPlayerVisor::DrawThermalEffect(const CStateManager&) const { +void CPlayerVisor::DrawThermalEffect(const CStateManager&) { // Empty } @@ -641,7 +645,7 @@ void CPlayerVisor::Update(float dt, const CStateManager& mgr) { x58_scanMagInterp = std::max(x58_scanMagInterp - 2.f * dt, scanMag); } -void CPlayerVisor::Draw(const CStateManager& mgr, const CTargetingManager* tgtManager) const { +void CPlayerVisor::Draw(const CStateManager& mgr, const CTargetingManager* tgtManager) { CGraphics::SetAmbientColor(zeus::skWhite); CGraphics::DisableAllLights(); switch (mgr.GetPlayerState()->GetActiveVisor(mgr)) { diff --git a/Runtime/MP1/CPlayerVisor.hpp b/Runtime/MP1/CPlayerVisor.hpp index 46b19da3a..d502ba090 100644 --- a/Runtime/MP1/CPlayerVisor.hpp +++ b/Runtime/MP1/CPlayerVisor.hpp @@ -72,9 +72,9 @@ class CPlayerVisor { void UpdateScanWindow(float dt, const CStateManager& mgr); EScanWindowState GetDesiredScanWindowState(const CStateManager& mgr) const; void LockUnlockAssets(); - void DrawScanEffect(const CStateManager& mgr, const CTargetingManager* tgtMgr) const; - void DrawXRayEffect(const CStateManager& mgr) const; - void DrawThermalEffect(const CStateManager& mgr) const; + void DrawScanEffect(const CStateManager& mgr, const CTargetingManager* tgtMgr); + void DrawXRayEffect(const CStateManager& mgr); + void DrawThermalEffect(const CStateManager& mgr); void UpdateCurrentVisor(float transFactor); void FinishTransitionIn(); void BeginTransitionIn(const CStateManager& mgr); @@ -82,10 +82,10 @@ class CPlayerVisor { void BeginTransitionOut(); public: - CPlayerVisor(CStateManager& stateMgr); + explicit CPlayerVisor(CStateManager& stateMgr); ~CPlayerVisor(); void Update(float dt, const CStateManager& stateMgr); - void Draw(const CStateManager& stateMgr, const CTargetingManager* tgtManager) const; + void Draw(const CStateManager& stateMgr, const CTargetingManager* tgtManager); void Touch(); float GetDesiredViewportScaleX(const CStateManager& stateMgr) const; float GetDesiredViewportScaleY(const CStateManager& stateMgr) const; diff --git a/Runtime/MP1/CQuitGameScreen.hpp b/Runtime/MP1/CQuitGameScreen.hpp index c0c5424f0..ea339d06a 100644 --- a/Runtime/MP1/CQuitGameScreen.hpp +++ b/Runtime/MP1/CQuitGameScreen.hpp @@ -36,7 +36,7 @@ public: EQuitAction Update(float dt); void Draw(); void ProcessUserInput(const CFinalInput& input); - CQuitGameScreen(EQuitType type); + explicit CQuitGameScreen(EQuitType type); }; } // namespace MP1 diff --git a/Runtime/MP1/CSamusFaceReflection.hpp b/Runtime/MP1/CSamusFaceReflection.hpp index 76193664e..23674de17 100644 --- a/Runtime/MP1/CSamusFaceReflection.hpp +++ b/Runtime/MP1/CSamusFaceReflection.hpp @@ -19,7 +19,7 @@ class CSamusFaceReflection { bool x70_hidden = true; public: - CSamusFaceReflection(CStateManager& stateMgr); + explicit CSamusFaceReflection(CStateManager& stateMgr); void PreDraw(const CStateManager& stateMgr); void Draw(const CStateManager& stateMgr) const; void Update(float dt, const CStateManager& stateMgr, CRandom16& rand); diff --git a/Runtime/MP1/CSamusHud.cpp b/Runtime/MP1/CSamusHud.cpp index 0bc2a4279..5681b8c86 100644 --- a/Runtime/MP1/CSamusHud.cpp +++ b/Runtime/MP1/CSamusHud.cpp @@ -36,12 +36,15 @@ CSamusHud::CSamusHud(CStateManager& stateMgr) UpdateStateTransition(1.f, stateMgr); g_SamusHud = this; - for (int i = 0; i < 16; ++i) - x5ec_camFovTweaks[i] = 5.f * i + 40.f; - for (int i = 0; i < 64; ++i) - x62c_camYTweaks[i] = -0.5f * i; - for (int i = 0; i < 32; ++i) - x72c_camZTweaks[i] = 0.5f * i - 8.f; + for (size_t i = 0; i < x5ec_camFovTweaks.size(); ++i) { + x5ec_camFovTweaks[i] = 5.f * float(i) + 40.f; + } + for (size_t i = 0; i < x62c_camYTweaks.size(); ++i) { + x62c_camYTweaks[i] = -0.5f * float(i); + } + for (size_t i = 0; i < x72c_camZTweaks.size(); ++i) { + x72c_camZTweaks[i] = 0.5f * float(i) - 8.f; + } x264_loadedFrmeHelmet = x258_frmeHelmet.GetObj(); x264_loadedFrmeHelmet->Reset(); @@ -104,10 +107,11 @@ void CSamusHud::InitializeFrameGluePermanent(const CStateManager& mgr) { child->SetDepthTest(false); x59c_base_textpane_message = static_cast(x274_loadedFrmeBaseHud->FindWidget("textpane_message")); x5a0_base_model_abutton = static_cast(x274_loadedFrmeBaseHud->FindWidget("model_abutton")); - for (int i = 0; i < 4; ++i) - x5d8_guiLights[i] = x264_loadedFrmeHelmet->GetFrameLight(i); + for (size_t i = 0; i < x5d8_guiLights.size(); ++i) { + x5d8_guiLights[i] = x264_loadedFrmeHelmet->GetFrameLight(s32(i)); + } x5d8_guiLights[3]->SetColor(zeus::skBlack); - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < x5a4_videoBands.size(); ++i) { SVideoBand& band = x5a4_videoBands[i]; band.x0_videoband = static_cast(x274_loadedFrmeBaseHud->FindWidget(fmt::format(fmt("model_videoband{}"), i))); @@ -494,9 +498,11 @@ void CSamusHud::UpdateMissile(float dt, const CStateManager& mgr, bool init) { } void CSamusHud::UpdateVideoBands(float dt, const CStateManager& mgr) { - for (int i = 0; i < 4; ++i) - if (x5a4_videoBands[i].x0_videoband) - x5a4_videoBands[i].x0_videoband->SetIsVisible(false); + for (auto& videoBand : x5a4_videoBands) { + if (videoBand.x0_videoband) { + videoBand.x0_videoband->SetIsVisible(false); + } + } } void CSamusHud::UpdateBallMode(const CStateManager& mgr, bool init) { @@ -577,13 +583,15 @@ void CSamusHud::UpdateVisorAndBeamMenus(float dt, const CStateManager& mgr) { } void CSamusHud::UpdateCameraDebugSettings() { - float fov = x5ec_camFovTweaks[g_tweakGui->GetHudCamFovTweak()]; - float y = x62c_camYTweaks[g_tweakGui->GetHudCamYTweak()]; - float z = x72c_camZTweaks[g_tweakGui->GetHudCamZTweak()]; - if (x2a0_helmetIntf) + const float fov = x5ec_camFovTweaks[g_tweakGui->GetHudCamFovTweak()]; + const float y = x62c_camYTweaks[g_tweakGui->GetHudCamYTweak()]; + const float z = x72c_camZTweaks[g_tweakGui->GetHudCamZTweak()]; + if (x2a0_helmetIntf) { x2a0_helmetIntf->UpdateCameraDebugSettings(fov, y, z); - if (x29c_decoIntf) + } + if (x29c_decoIntf) { x29c_decoIntf->UpdateCameraDebugSettings(fov, y, z); + } x274_loadedFrmeBaseHud->GetFrameCamera()->SetFov(fov); x310_cameraPos.y() = y; x310_cameraPos.z() = z; @@ -705,9 +713,11 @@ bool CSamusHud::IsAreaLightInCachedLights(const CLight& light) const { } int CSamusHud::FindEmptyHudLightSlot(const CLight& light) const { - for (int i = 0; i < 3; ++i) - if (x340_hudLights[i].x1c_fader == 0.f) - return i; + for (size_t i = 0; i < x340_hudLights.size(); ++i) { + if (x340_hudLights[i].x1c_fader == 0.f) { + return int(i); + } + } return -1; } @@ -787,7 +797,7 @@ void CSamusHud::UpdateHudDynamicLights(float dt, const CStateManager& mgr) { auto lightIt = x5d8_guiLights.begin(); float maxIntensity = 0.f; int maxIntensityIdx = 0; - for (int i = 0; i < 3; ++i) { + for (size_t i = 0; i < x340_hudLights.size(); ++i) { SCachedHudLight& light = x340_hudLights[i]; CGuiLight* lightWidget = *lightIt++; zeus::CVector3f lightToCam = fpCam->GetTranslation() - light.x0_pos; @@ -806,7 +816,7 @@ void CSamusHud::UpdateHudDynamicLights(float dt, const CStateManager& mgr) { fadedFalloff * zeus::skForward.dot(-lightNormal) * lightAdd.rgbDot(zeus::CColor(0.3f, 0.6f, 0.1f)); if (greyscale > maxIntensity) { maxIntensity = greyscale; - maxIntensityIdx = i; + maxIntensityIdx = int(i); } } @@ -948,9 +958,9 @@ void CSamusHud::UpdateHudDamage(float dt, const CStateManager& mgr, DataSpec::IT float rotAng = rotMul * (2.f * M_PIF / 10.f); x44c_hudLagShakeRot.rotateX(rand() / float(RAND_MAX) * rotAng); x44c_hudLagShakeRot.rotateZ(rand() / float(RAND_MAX) * rotAng); - zeus::CVector3f vecs[] = {zeus::skRight, zeus::skForward, zeus::skUp}; + std::array vecs{zeus::skRight, zeus::skForward, zeus::skUp}; for (int i = 0; i < 4; ++i) { - int sel = rand() % 9; + const int sel = rand() % 9; vecs[sel % 3][sel / 3] += (rand() / float(RAND_MAX) - dt) * rotMul; } x428_decoShakeRotate = zeus::CMatrix3f(vecs[0], vecs[1], vecs[2]).transposed(); @@ -1164,9 +1174,9 @@ void CSamusHud::Update(float dt, const CStateManager& mgr, CInGameGuiManager::EH UpdateEnergyLow(dt, mgr); - for (int i = 0; i < 15; ++i) { - x7ac_[i].x0_ = 0; - x7ac_[i].x4_ = 0; + for (auto& entry : x7ac_) { + entry.x0_ = 0; + entry.x4_ = 0; } if (x2ac_radarIntf) @@ -1357,95 +1367,105 @@ void CSamusHud::Update(float dt, const CStateManager& mgr, CInGameGuiManager::EH x29c_decoIntf->Update(dt, mgr); } -void CSamusHud::DrawAttachedEnemyEffect(const CStateManager& mgr) const { - float drainTime = mgr.GetPlayer().GetEnergyDrain().GetEnergyDrainTime(); - if (drainTime <= 0.f) +void CSamusHud::DrawAttachedEnemyEffect(const CStateManager& mgr) { + const float drainTime = mgr.GetPlayer().GetEnergyDrain().GetEnergyDrainTime(); + if (drainTime <= 0.f) { return; + } - float modPeriod = g_tweakGui->GetEnergyDrainModPeriod(); + const float modPeriod = g_tweakGui->GetEnergyDrainModPeriod(); float alpha; if (g_tweakGui->GetEnergyDrainSinusoidalPulse()) { alpha = (std::sin(-0.25f * modPeriod + 2.f * M_PIF * drainTime / modPeriod) + 1.f) * 0.5f; } else { - float halfModPeriod = 0.5f * modPeriod; - float tmp = std::fabs(std::fmod(drainTime, modPeriod)); - if (tmp < halfModPeriod) + const float halfModPeriod = 0.5f * modPeriod; + const float tmp = std::fabs(std::fmod(drainTime, modPeriod)); + if (tmp < halfModPeriod) { alpha = tmp / halfModPeriod; - else + } else { alpha = (modPeriod - tmp) / halfModPeriod; + } } zeus::CColor filterColor = g_tweakGuiColors->GetEnergyDrainFilterColor(); filterColor.a() *= alpha; - const_cast(m_energyDrainFilter).draw(filterColor); + m_energyDrainFilter.draw(filterColor); } void CSamusHud::Draw(const CStateManager& mgr, float alpha, CInGameGuiManager::EHelmetVisMode helmetVis, bool hudVis, - bool targetingManager) const { - if (x2bc_nextState == EHudState::None) + bool targetingManager) { + if (x2bc_nextState == EHudState::None) { return; + } SCOPED_GRAPHICS_DEBUG_GROUP("CSamusHud::Draw", zeus::skBlue); x3a8_camFilter.Draw(); if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed) { DrawAttachedEnemyEffect(mgr); x51c_camFilter2.Draw(); - if (targetingManager) + if (targetingManager) { x8_targetingMgr.Draw(mgr, false); + } } if (helmetVis != CInGameGuiManager::EHelmetVisMode::ReducedUpdate && helmetVis < CInGameGuiManager::EHelmetVisMode::HelmetOnly) { - if (alpha < 1.f) - const_cast(m_cookieCutterStatic).draw(zeus::skWhite, 1.f - alpha); + if (alpha < 1.f) { + m_cookieCutterStatic.draw(zeus::skWhite, 1.f - alpha); + } if (x288_loadedSelectedHud) { if (mgr.GetPlayer().GetDeathTime() > 0.f) { if (mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Unmorphed) { - CGuiWidgetDrawParms parms(x2c8_transT * zeus::clamp(0.f, 1.f - mgr.GetPlayer().GetDeathTime() / 6.f, 1.f), - zeus::skZero3f); + const CGuiWidgetDrawParms parms( + x2c8_transT * zeus::clamp(0.f, 1.f - mgr.GetPlayer().GetDeathTime() / 6.f, 1.f), zeus::skZero3f); x288_loadedSelectedHud->Draw(parms); } else { - CGuiWidgetDrawParms parms(x2c8_transT, zeus::skZero3f); + const CGuiWidgetDrawParms parms(x2c8_transT, zeus::skZero3f); x288_loadedSelectedHud->Draw(parms); } } else { - CGuiWidgetDrawParms parms(x2c8_transT, zeus::skZero3f); + const CGuiWidgetDrawParms parms(x2c8_transT, zeus::skZero3f); x288_loadedSelectedHud->Draw(parms); } } - if (x274_loadedFrmeBaseHud) + if (x274_loadedFrmeBaseHud) { x274_loadedFrmeBaseHud->Draw(CGuiWidgetDrawParms::Default); + } } - if (x29c_decoIntf && !x2cc_preLoadCountdown) + if (x29c_decoIntf && !x2cc_preLoadCountdown) { x29c_decoIntf->Draw(); + } if (x2bc_nextState >= EHudState::Combat && x2bc_nextState <= EHudState::Scan) { if (hudVis && helmetVis != CInGameGuiManager::EHelmetVisMode::ReducedUpdate && helmetVis < CInGameGuiManager::EHelmetVisMode::HelmetOnly) { float t; - if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Combat) + if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Combat) { t = mgr.GetPlayerState()->GetVisorTransitionFactor(); - else + } else { t = 0.f; + } x2ac_radarIntf->Draw(mgr, t * alpha); } // Depth read/write enable } } -void CSamusHud::DrawHelmet(const CStateManager& mgr, float camYOff) const { +void CSamusHud::DrawHelmet(const CStateManager& mgr, float camYOff) { if (!x264_loadedFrmeHelmet || mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Unmorphed || - x2bc_nextState == EHudState::Ball) + x2bc_nextState == EHudState::Ball) { return; + } float t; - if (x2c4_activeTransState == ETransitionState::Transitioning && x2b8_curState == EHudState::Ball) + if (x2c4_activeTransState == ETransitionState::Transitioning && x2b8_curState == EHudState::Ball) { t = x2c8_transT; - else + } else { t = 1.f; + } x264_loadedFrmeHelmet->Draw(CGuiWidgetDrawParms(t, zeus::CVector3f(0.f, 15.f * camYOff, 0.f))); } diff --git a/Runtime/MP1/CSamusHud.hpp b/Runtime/MP1/CSamusHud.hpp index 25c76597e..47baf9248 100644 --- a/Runtime/MP1/CSamusHud.hpp +++ b/Runtime/MP1/CSamusHud.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -167,13 +168,13 @@ class CSamusHud { CGuiModel* x5a0_base_model_abutton; rstl::reserved_vector x5a4_videoBands; rstl::reserved_vector x5d8_guiLights; - float x5ec_camFovTweaks[16]; - float x62c_camYTweaks[64]; - float x72c_camZTweaks[32]; + std::array x5ec_camFovTweaks; + std::array x62c_camYTweaks; + std::array x72c_camZTweaks; rstl::reserved_vector x7ac_; CColoredQuadFilter m_energyDrainFilter; - CCookieCutterDepthRandomStaticFilter m_cookieCutterStatic = {EFilterType::NoColor}; + CCookieCutterDepthRandomStaticFilter m_cookieCutterStatic{EFilterType::NoColor}; static CSamusHud* g_SamusHud; static rstl::reserved_vector BuildPlayerHasVisors(const CStateManager& mgr); @@ -207,17 +208,17 @@ class CSamusHud { void ShowDamage(const zeus::CVector3f& position, float dam, float prevDam, const CStateManager& mgr); void EnterFirstPerson(const CStateManager& mgr); void LeaveFirstPerson(const CStateManager& mgr); - void DrawAttachedEnemyEffect(const CStateManager& mgr) const; + void DrawAttachedEnemyEffect(const CStateManager& mgr); static EHudState GetDesiredHudState(const CStateManager& mgr); public: - CSamusHud(CStateManager& stateMgr); + explicit CSamusHud(CStateManager& stateMgr); ~CSamusHud(); void Update(float dt, const CStateManager& mgr, CInGameGuiManager::EHelmetVisMode helmetVis, bool hudVis, bool targetingManager); void Draw(const CStateManager& mgr, float alpha, CInGameGuiManager::EHelmetVisMode helmetVis, bool hudVis, - bool targetingManager) const; - void DrawHelmet(const CStateManager& mgr, float camYOff) const; + bool targetingManager); + void DrawHelmet(const CStateManager& mgr, float camYOff); void ProcessControllerInput(const CFinalInput& input); void UpdateStateTransition(float time, const CStateManager& mgr); bool CheckLoadComplete(CStateManager& stateMgr); diff --git a/Runtime/MP1/CSaveGameScreen.hpp b/Runtime/MP1/CSaveGameScreen.hpp index b37fab7e0..ee5735383 100644 --- a/Runtime/MP1/CSaveGameScreen.hpp +++ b/Runtime/MP1/CSaveGameScreen.hpp @@ -108,7 +108,7 @@ public: const CGameState::GameFileStateInfo* GetGameData(int idx) const; EUIType GetUIType() const { return x10_uiType; } bool IsSavingDisabled() const { return x92_savingDisabled; } - CSaveGameScreen(ESaveContext saveCtx, u64 serial); + explicit CSaveGameScreen(ESaveContext saveCtx, u64 serial); }; } // namespace MP1 diff --git a/Runtime/MP1/CSlideShow.cpp b/Runtime/MP1/CSlideShow.cpp index 60a3c6e6d..40b0d9571 100644 --- a/Runtime/MP1/CSlideShow.cpp +++ b/Runtime/MP1/CSlideShow.cpp @@ -124,18 +124,19 @@ CIOWin::EMessageReturn CSlideShow::OnMessage(const CArchitectureMessage& msg, CA return EMessageReturn::Exit; } -void CSlideShow::SSlideData::Draw() const { - if (!IsLoaded()) +void CSlideShow::SSlideData::Draw() { + if (!IsLoaded()) { return; + } - zeus::CRectangle rect; - const_cast(*m_texQuad).draw(x30_mulColor, 1.f, rect); + const zeus::CRectangle rect; + m_texQuad->draw(x30_mulColor, 1.f, rect); - zeus::CVector2f centeredOffset((x28_canvasSize.x() - m_texQuad->GetTex()->GetWidth()) * 0.5f, - (x28_canvasSize.y() - m_texQuad->GetTex()->GetHeight()) * 0.5f); + const zeus::CVector2f centeredOffset((x28_canvasSize.x() - m_texQuad->GetTex()->GetWidth()) * 0.5f, + (x28_canvasSize.y() - m_texQuad->GetTex()->GetHeight()) * 0.5f); } -void CSlideShow::Draw() const { +void CSlideShow::Draw() { SCOPED_GRAPHICS_DEBUG_GROUP("CSlideShow::Draw", zeus::skGreen); if (x14_phase == Phase::Five) { x5c_slideA.Draw(); diff --git a/Runtime/MP1/CSlideShow.hpp b/Runtime/MP1/CSlideShow.hpp index ceed2212e..11087684f 100644 --- a/Runtime/MP1/CSlideShow.hpp +++ b/Runtime/MP1/CSlideShow.hpp @@ -33,11 +33,11 @@ public: zeus::CVector2f x28_canvasSize; zeus::CColor x30_mulColor = zeus::skWhite; - SSlideData(CSlideShow& parent) : x0_parent(parent) { x30_mulColor.a() = 0.f; } + explicit SSlideData(CSlideShow& parent) : x0_parent(parent) { x30_mulColor.a() = 0.f; } void SetTexture(const TLockedToken& tex) { m_texQuad.emplace(EFilterType::Blend, tex); } bool IsLoaded() const { return m_texQuad && m_texQuad->GetTex().IsLoaded(); } - void Draw() const; + void Draw(); }; private: @@ -110,7 +110,7 @@ public: CSlideShow(); EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&) override; bool GetIsContinueDraw() const override { return false; } - void Draw() const override; + void Draw() override; static u32 SlideShowGalleryFlags(); }; diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index 44e360e05..3c1735d0d 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -1,5 +1,7 @@ #include "Runtime/MP1/MP1.hpp" +#include + #include "NESEmulator/CNESShader.hpp" #include "Runtime/Graphics/Shaders/CAABoxShader.hpp" @@ -74,8 +76,21 @@ extern CVar* com_developer; extern CVar* com_cubemaps; }; // namespace hecl -namespace urde { -namespace MP1 { +namespace urde::MP1 { +namespace { +struct AudioGroupInfo { + const char* name; + u32 id; +}; + +constexpr std::array StaticAudioGroups{{ + {"Misc_AGSC", GRPmisc}, + {"MiscSamus_AGSC", GRPmiscSamus}, + {"UI_AGSC", GRPui}, + {"Weapons_AGSC", GRPweapons}, + {"ZZZ_AGSC", GRPzzz}, +}}; +} // Anonymous namespace CGameArchitectureSupport::CGameArchitectureSupport(CMain& parent, boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend) @@ -128,17 +143,6 @@ void CGameArchitectureSupport::Update(float dt) { x58_ioWinManager.PumpMessages(x4_archQueue); } -struct AudioGroupInfo { - const char* name; - u32 id; -}; - -static const AudioGroupInfo StaticAudioGroups[] = {{"Misc_AGSC", GRPmisc}, - {"MiscSamus_AGSC", GRPmiscSamus}, - {"UI_AGSC", GRPui}, - {"Weapons_AGSC", GRPweapons}, - {"ZZZ_AGSC", GRPzzz}}; - bool CGameArchitectureSupport::LoadAudio() { if (x88_audioLoadStatus == EAudioLoadStatus::Loaded) return true; @@ -170,26 +174,30 @@ bool CGameArchitectureSupport::LoadAudio() { } void CGameArchitectureSupport::PreloadAudio() { - if (x88_audioLoadStatus != EAudioLoadStatus::Uninitialized) + if (x88_audioLoadStatus != EAudioLoadStatus::Uninitialized) { return; + } + x8c_pendingAudioGroups.clear(); x8c_pendingAudioGroups.reserve(5); - for (int i = 0; i < 5; ++i) { + for (size_t i = 0; i < StaticAudioGroups.size(); ++i) { const AudioGroupInfo& info = StaticAudioGroups[i]; CToken grp = g_SimplePool->GetObj(info.name); - if (i == 0) /* Lock first group in sequence */ + + // Lock first group in sequence + if (i == 0) { grp.Lock(); - x8c_pendingAudioGroups.push_back(std::move(grp)); + } + + x8c_pendingAudioGroups.emplace_back(std::move(grp)); } x88_audioLoadStatus = EAudioLoadStatus::Loading; } void CGameArchitectureSupport::UnloadAudio() { - - for (int i = 0; i < 5; ++i) { - const AudioGroupInfo& info = StaticAudioGroups[i]; + for (const AudioGroupInfo& info : StaticAudioGroups) { const SObjectTag* tag = g_ResFactory->GetResourceIdByName(info.name); auto name = CAudioSys::SysGetGroupSetName(tag->id); CAudioSys::SysRemoveGroupFromAmuse(name); @@ -625,7 +633,7 @@ static u32 DiscordItemPercent = 0xffffffff; static std::string DiscordState; void CMain::InitializeDiscord() { - DiscordStartTime = time(0); + DiscordStartTime = std::time(nullptr); DiscordEventHandlers handlers = {}; handlers.ready = HandleDiscordReady; handlers.disconnected = HandleDiscordDisconnected; @@ -984,5 +992,4 @@ int CMain::appMain(boo::IApplication* app) { #endif -} // namespace MP1 -} // namespace urde +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CActorContraption.cpp b/Runtime/MP1/World/CActorContraption.cpp index 374d824e3..656b8c6f7 100644 --- a/Runtime/MP1/World/CActorContraption.cpp +++ b/Runtime/MP1/World/CActorContraption.cpp @@ -53,11 +53,12 @@ void MP1::CActorContraption::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId void MP1::CActorContraption::Think(float dt, CStateManager& mgr) { CScriptActor::Think(dt, mgr); - for (const std::pair& uid : x2e8_children) { - CFlameThrower* act = static_cast(mgr.ObjectById(uid.first)); + for (const auto& [uid, name] : x2e8_children) { + auto* act = static_cast(mgr.ObjectById(uid)); - if (act && act->GetActive()) - act->SetTransform(x34_transform * GetScaledLocatorTransform(uid.second), dt); + if (act && act->GetActive()) { + act->SetTransform(x34_transform * GetScaledLocatorTransform(name), dt); + } } } diff --git a/Runtime/MP1/World/CActorContraption.hpp b/Runtime/MP1/World/CActorContraption.hpp index 97df40615..ede6bba12 100644 --- a/Runtime/MP1/World/CActorContraption.hpp +++ b/Runtime/MP1/World/CActorContraption.hpp @@ -18,15 +18,16 @@ class CActorContraption : public CScriptActor { CDamageInfo x30c_dInfo; public: - CActorContraption(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, - const zeus::CAABox&, const CMaterialList&, float, float, const CHealthInfo&, - const CDamageVulnerability&, const CActorParameters&, CAssetId, const CDamageInfo&, bool); + CActorContraption(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const zeus::CAABox& aabox, const CMaterialList& matList, float mass, + float zMomentum, const CHealthInfo& hInfo, const CDamageVulnerability& dVuln, + const CActorParameters& aParams, CAssetId part, const CDamageInfo& dInfo, bool active); void Accept(IVisitor& visitor) override; - void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; - void Think(float, CStateManager&) override; - void DoUserAnimEvent(CStateManager&, const CInt32POINode&, EUserEventType, float dt) override; - CFlameThrower* CreateFlameThrower(std::string_view, CStateManager&); + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + void Think(float dt, CStateManager& mgr) override; + void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType evType, float dt) override; + CFlameThrower* CreateFlameThrower(std::string_view name, CStateManager& mgr); void ResetFlameThrowers(CStateManager& mgr); }; } // namespace MP1 diff --git a/Runtime/MP1/World/CAtomicAlpha.cpp b/Runtime/MP1/World/CAtomicAlpha.cpp index d3af41292..b01194626 100644 --- a/Runtime/MP1/World/CAtomicAlpha.cpp +++ b/Runtime/MP1/World/CAtomicAlpha.cpp @@ -50,7 +50,7 @@ void CAtomicAlpha::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta } } -void CAtomicAlpha::Render(const CStateManager& mgr) const { +void CAtomicAlpha::Render(CStateManager& mgr) { if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::XRay && x568_25_invisible) return; @@ -66,9 +66,10 @@ void CAtomicAlpha::Render(const CStateManager& mgr) const { x690_bombModel.Render(mgr, locatorXf, x90_actorLights.get(), flags); } } -void CAtomicAlpha::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { - if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::XRay && x568_25_invisible) +void CAtomicAlpha::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { + if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::XRay && x568_25_invisible) { return; + } CPatterned::AddToRenderer(frustum, mgr); } diff --git a/Runtime/MP1/World/CAtomicAlpha.hpp b/Runtime/MP1/World/CAtomicAlpha.hpp index 5f1a9e335..a0499941d 100644 --- a/Runtime/MP1/World/CAtomicAlpha.hpp +++ b/Runtime/MP1/World/CAtomicAlpha.hpp @@ -39,8 +39,8 @@ public: CAssetId, bool, bool); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; - void Render(const CStateManager&) const override; - void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; + void Render(CStateManager&) override; + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) override; void Think(float, CStateManager&) override; void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; diff --git a/Runtime/MP1/World/CBabygoth.cpp b/Runtime/MP1/World/CBabygoth.cpp index 2dd760946..1a831d151 100644 --- a/Runtime/MP1/World/CBabygoth.cpp +++ b/Runtime/MP1/World/CBabygoth.cpp @@ -708,7 +708,7 @@ void CBabygoth::FollowPattern(CStateManager& mgr, EStateMsg msg, float) { CBCStepCmd(pas::EStepDirection::Backward, pas::EStepType::Normal)); } else if (x568_stateProg == 3) { if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Step) - x450_bodyController->GetCommandMgr().SetTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); + x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); else x568_stateProg = 4; } diff --git a/Runtime/MP1/World/CBabygoth.hpp b/Runtime/MP1/World/CBabygoth.hpp index 634c77d33..706f0be2e 100644 --- a/Runtime/MP1/World/CBabygoth.hpp +++ b/Runtime/MP1/World/CBabygoth.hpp @@ -45,7 +45,7 @@ struct CBabygothData { CAssetId x174_flamePlayerIceTxtr; public: - CBabygothData(CInputStream&); + explicit CBabygothData(CInputStream&); const CDamageInfo& GetFireballDamage() const { return xc_fireballDamage; } CAssetId GetFireballResID() const { return x8_fireballWeapon; } float GetFireballAttackVariance() const { return x4_fireballAttackTimeVariance; } diff --git a/Runtime/MP1/World/CBeetle.cpp b/Runtime/MP1/World/CBeetle.cpp index 94a31f8c6..85764d1e0 100644 --- a/Runtime/MP1/World/CBeetle.cpp +++ b/Runtime/MP1/World/CBeetle.cpp @@ -151,7 +151,7 @@ void CBeetle::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { CPatterned::PreRender(mgr, frustum); } -void CBeetle::Render(const CStateManager& mgr) const { +void CBeetle::Render(CStateManager& mgr) { if (x3fc_flavor == EFlavorType::One && x400_25_alive) { zeus::CTransform tailXf = GetLctrTransform("Target_Tail"sv); if (x428_damageCooldownTimer >= 0.f && x42c_color.a() == 1.f) { diff --git a/Runtime/MP1/World/CBeetle.hpp b/Runtime/MP1/World/CBeetle.hpp index 55c146d9c..3e396b02e 100644 --- a/Runtime/MP1/World/CBeetle.hpp +++ b/Runtime/MP1/World/CBeetle.hpp @@ -67,7 +67,7 @@ public: void Think(float dt, CStateManager& mgr) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) override; void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; - void Render(const CStateManager& mgr) const override; + void Render(CStateManager& mgr) override; const CDamageVulnerability* GetDamageVulnerability() const override; const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir, diff --git a/Runtime/MP1/World/CBloodFlower.cpp b/Runtime/MP1/World/CBloodFlower.cpp index 7ffe40295..ce54a9ba9 100644 --- a/Runtime/MP1/World/CBloodFlower.cpp +++ b/Runtime/MP1/World/CBloodFlower.cpp @@ -143,7 +143,7 @@ void CBloodFlower::LaunchPollenProjectile(const zeus::CTransform& xf, CStateMana } } -void CBloodFlower::Render(const CStateManager& mgr) const { +void CBloodFlower::Render(CStateManager& mgr) { CPatterned::Render(mgr); x574_podEffect->Render(GetActorLights()); } diff --git a/Runtime/MP1/World/CBloodFlower.hpp b/Runtime/MP1/World/CBloodFlower.hpp index 3e42a9afc..8f8a519fb 100644 --- a/Runtime/MP1/World/CBloodFlower.hpp +++ b/Runtime/MP1/World/CBloodFlower.hpp @@ -54,7 +54,7 @@ public: void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float dt, CStateManager& mgr) override; void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; - void Render(const CStateManager& mgr) const override; + void Render(CStateManager& mgr) override; void Touch(CActor&, CStateManager&) override {} EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const CWeaponMode& weaponMode, diff --git a/Runtime/MP1/World/CBouncyGrenade.cpp b/Runtime/MP1/World/CBouncyGrenade.cpp new file mode 100644 index 000000000..bd88c8c2e --- /dev/null +++ b/Runtime/MP1/World/CBouncyGrenade.cpp @@ -0,0 +1,208 @@ +#include "Runtime/MP1/World/CBouncyGrenade.hpp" + +#include "Runtime/CPlayerState.hpp" +#include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/World/CPlayer.hpp" +#include "Runtime/Collision/CCollisionActor.hpp" + +namespace urde::MP1 { +CBouncyGrenade::CBouncyGrenade(TUniqueId uid, std::string_view name, const CEntityInfo& info, + const zeus::CTransform& xf, CModelData&& mData, const CActorParameters& actParams, + TUniqueId parentId, const SBouncyGrenadeData& data, float velocity, + float explodePlayerDistance) +: CPhysicsActor(uid, true, name, info, xf, std::move(mData), {EMaterialTypes::Projectile, EMaterialTypes::Solid}, + mData.GetBounds(), SMoverData{data.GetUnkStruct().GetMass()}, actParams, 0.3f, 0.1f) +, x258_data(data) +, x294_numBounces(data.GetNumBounces()) +, x298_parentId(parentId) +, x2a0_elementGen1(std::make_unique(g_SimplePool->GetObj({'PART', data.GetElementGenId1()}))) +, x2a4_elementGen2(std::make_unique(g_SimplePool->GetObj({'PART', data.GetElementGenId2()}))) +, x2a8_elementGen3(std::make_unique(g_SimplePool->GetObj({'PART', data.GetElementGenId3()}))) +, x2ac_elementGen4(std::make_unique(g_SimplePool->GetObj({'PART', data.GetElementGenId4()}))) +, x2b0_explodePlayerDistance(explodePlayerDistance) +, x2b4_24_exploded(false) +, x2b4_25_(false) { + SetMomentumWR({0.f, 0.f, -GravityConstant() * GetMass()}); + SetVelocityWR(velocity * xf.frontVector()); + x2a0_elementGen1->SetParticleEmission(false); + x2a4_elementGen2->SetParticleEmission(false); + x2a8_elementGen3->SetParticleEmission(false); + x2ac_elementGen4->SetParticleEmission(true); + CMaterialFilter filter = GetMaterialFilter(); + filter.ExcludeList().Add(EMaterialTypes::Character); + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(filter.IncludeList(), filter.ExcludeList())); +} + +void CBouncyGrenade::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { + CActor::AddToRenderer(frustum, mgr); + if (!x2b4_24_exploded) { + g_Renderer->AddParticleGen(*x2ac_elementGen4); + return; + } + const auto visor = mgr.GetPlayerState()->GetActiveVisor(mgr); + if (visor == CPlayerState::EPlayerVisor::Combat || visor == CPlayerState::EPlayerVisor::Scan) { + g_Renderer->AddParticleGen(*x2a0_elementGen1); + } else if (visor == CPlayerState::EPlayerVisor::XRay || visor == CPlayerState::EPlayerVisor::Thermal) { + g_Renderer->AddParticleGen(*x2a8_elementGen3); + } +} + +void CBouncyGrenade::CollidedWith(TUniqueId id, const CCollisionInfoList& list, CStateManager& mgr) { + constexpr auto matList = CMaterialList{ + EMaterialTypes::Solid, + EMaterialTypes::Ceiling, + EMaterialTypes::Floor, + EMaterialTypes::Character, + }; + + bool shouldExplode = false; + if (x298_parentId != id) { + const CEntity* const entity = mgr.GetObjectById(id); + if (entity != nullptr) { + if (TCastToConstPtr actor = entity) { + shouldExplode = actor->GetOwnerId() != x298_parentId; + } else { + shouldExplode = true; + } + } + } + if (shouldExplode) { + Explode(mgr, id); + } else { + for (const auto& info : list) { + if (info.GetMaterialLeft().SharesMaterials(matList)) { + if (x294_numBounces == 0) { + Explode(mgr, kInvalidUniqueId); + } else { + const zeus::CVector3f* normal = &info.GetNormalLeft(); + if (GetVelocity().dot(info.GetNormalLeft()) > 0.f) { + normal = &info.GetNormalRight(); + } + const zeus::CVector3f impulse = + (x258_data.GetUnkStruct().GetSpeed() * GetConstantForce().magnitude()) * *normal; + const zeus::CVector3f angle = -x258_data.GetUnkStruct().GetSpeed() * GetAngularMomentum(); + ApplyImpulseWR(impulse, angle); + CSfxManager::AddEmitter(x258_data.GetBounceSfx(), GetTranslation(), zeus::skUp, false, false, 0x7f, + GetAreaIdAlways()); + --x294_numBounces; + } + break; + } + } + } + CPhysicsActor::CollidedWith(id, list, mgr); +} + +std::optional CBouncyGrenade::GetTouchBounds() const { return GetModelData()->GetBounds(GetTransform()); } + +void CBouncyGrenade::Render(CStateManager& mgr) { + if (!x2b4_24_exploded) { + GetModelData()->Render(mgr, GetTransform(), nullptr, {0, 0, 3, zeus::skWhite}); + } else if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) { + CGraphics::SetFog(ERglFogMode::PerspLin, 0.f, 75.f, zeus::skBlack); + x2a4_elementGen2->Render(); + mgr.SetupFogForArea(GetAreaIdAlways()); + } +} + +void CBouncyGrenade::Think(float dt, CStateManager& mgr) { + if (GetActive()) { + const zeus::CTransform& orientation = GetTransform().getRotation(); + const zeus::CVector3f& translation = GetTranslation(); + const zeus::CVector3f& scale = GetModelData()->GetScale(); + auto UpdateElementGen = [ orientation, translation, scale, dt ](CElementGen & gen) constexpr { + gen.SetOrientation(orientation); + gen.SetGlobalTranslation(translation); + gen.SetGlobalScale(scale); + gen.Update(dt); + }; + if (x2b4_24_exploded) { + Stop(); + UpdateElementGen(*x2a0_elementGen1); + UpdateElementGen(*x2a4_elementGen2); + UpdateElementGen(*x2a8_elementGen3); + } else { + UpdateElementGen(*x2ac_elementGen4); + } + x29c_ += dt; + if (x29c_ > 0.3f) { + x2b4_25_ = true; + } + const zeus::CVector3f& playerDistance = mgr.GetPlayer().GetTranslation() + + zeus::CVector3f{0.f, 0.f, 0.5f * mgr.GetPlayer().GetEyeHeight()} - + translation; + if (playerDistance.magSquared() < x2b0_explodePlayerDistance * x2b0_explodePlayerDistance) { + Explode(mgr, kInvalidUniqueId); + } + } + if (x2a0_elementGen1->IsSystemDeletable() && x2a4_elementGen2->IsSystemDeletable() && + x2a8_elementGen3->IsSystemDeletable()) { + mgr.FreeScriptObject(GetUniqueId()); + } +} + +void CBouncyGrenade::Touch(CActor& act, CStateManager& mgr) { CActor::Touch(act, mgr); } + +void CBouncyGrenade::Explode(CStateManager& mgr, TUniqueId uid) { + if (x2b4_24_exploded) { + return; + } + + x2b4_24_exploded = true; + CSfxManager::AddEmitter(x258_data.GetExplodeSfx(), GetTranslation(), zeus::skUp, false, false, 0x7f, + GetAreaIdAlways()); + x2a0_elementGen1->SetParticleEmission(true); + x2a4_elementGen2->SetParticleEmission(true); + x2a8_elementGen3->SetParticleEmission(true); + x2ac_elementGen4->SetParticleEmission(false); + + const CDamageInfo& dInfo = x258_data.GetDamageInfo(); + { + bool isParent = x298_parentId == uid; + if (TCastToConstPtr actor = mgr.GetObjectById(uid)) { + isParent = x298_parentId == actor->GetOwnerId(); + } + if (uid != kInvalidUniqueId && !isParent) { + mgr.ApplyDamage(GetUniqueId(), uid, GetUniqueId(), dInfo, CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), + zeus::skZero3f); + } + } + + const float radius = dInfo.GetRadius(); + if (radius > 1.f) { + const zeus::CVector3f& pos = GetTranslation(); + const CMaterialFilter filter = CMaterialFilter::MakeInclude({EMaterialTypes::Player, EMaterialTypes::Character}); + rstl::reserved_vector nearList; + mgr.BuildNearList(nearList, {pos - radius, pos + radius}, filter, nullptr); + + for (const auto& id : nearList) { + bool isParent = x298_parentId == id; + if (TCastToConstPtr cActor = mgr.GetObjectById(id)) { + isParent = x298_parentId == cActor->GetOwnerId(); + } + if (isParent) { + continue; + } + + const auto* actor = static_cast(mgr.GetObjectById(id)); + if (actor == nullptr) { + continue; + } + + const float magnitude = (actor->GetTranslation() - GetTranslation()).magnitude(); + if (radius <= magnitude) { + continue; + } + + float scale = (radius - magnitude) / radius; + const CDamageInfo info{dInfo.GetWeaponMode(), scale * dInfo.GetDamage(), radius, + scale * dInfo.GetKnockBackPower()}; + mgr.ApplyDamage(GetUniqueId(), id, GetUniqueId(), info, CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), + zeus::skZero3f); + } + } +} +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CBouncyGrenade.hpp b/Runtime/MP1/World/CBouncyGrenade.hpp new file mode 100644 index 000000000..ab6cfa9d7 --- /dev/null +++ b/Runtime/MP1/World/CBouncyGrenade.hpp @@ -0,0 +1,90 @@ +#pragma once + +#include "Runtime/World/CPhysicsActor.hpp" +#include "Runtime/World/CDamageInfo.hpp" +#include "Runtime/Particle/CElementGen.hpp" + +#include "TCastTo.hpp" // Generated file, do not modify include path + +#include + +namespace urde::MP1 { +struct SGrenadeUnknownStruct { +private: + float x0_mass; + float x4_speed; // wrong name probably + +public: + explicit SGrenadeUnknownStruct(CInputStream& in) : x0_mass(in.readFloatBig()), x4_speed(in.readFloatBig()) {} + + [[nodiscard]] float GetMass() const { return x0_mass; } + [[nodiscard]] float GetSpeed() const { return x4_speed; } +}; + +struct SBouncyGrenadeData { +private: + SGrenadeUnknownStruct x0_; + CDamageInfo x8_damageInfo; + CAssetId x24_elementGenId1; + CAssetId x28_elementGenId2; + CAssetId x2c_elementGenId3; + CAssetId x30_elementGenId4; + u32 x34_numBounces; + u16 x38_bounceSfx; + u16 x3a_explodeSfx; + +public: + SBouncyGrenadeData(const SGrenadeUnknownStruct& unkStruct, const CDamageInfo& damageInfo, CAssetId w1, CAssetId w2, + CAssetId w3, CAssetId w4, u32 w5, u16 s1, u16 s2) + : x0_(unkStruct) + , x8_damageInfo(damageInfo) + , x24_elementGenId1(w1) + , x28_elementGenId2(w2) + , x2c_elementGenId3(w3) + , x30_elementGenId4(w4) + , x34_numBounces(w5) + , x38_bounceSfx(s1) + , x3a_explodeSfx(s2){}; + + [[nodiscard]] const SGrenadeUnknownStruct& GetUnkStruct() const { return x0_; } + [[nodiscard]] const CDamageInfo& GetDamageInfo() const { return x8_damageInfo; } + [[nodiscard]] CAssetId GetElementGenId1() const { return x24_elementGenId1; } + [[nodiscard]] CAssetId GetElementGenId2() const { return x28_elementGenId2; } + [[nodiscard]] CAssetId GetElementGenId3() const { return x2c_elementGenId3; } + [[nodiscard]] CAssetId GetElementGenId4() const { return x30_elementGenId4; } + [[nodiscard]] u32 GetNumBounces() const { return x34_numBounces; } + [[nodiscard]] u16 GetBounceSfx() const { return x38_bounceSfx; } + [[nodiscard]] u16 GetExplodeSfx() const { return x3a_explodeSfx; } +}; + +class CBouncyGrenade : public CPhysicsActor { +private: + SBouncyGrenadeData x258_data; + u32 x294_numBounces; + TUniqueId x298_parentId; + float x29c_ = 0.f; + std::unique_ptr x2a0_elementGen1; + std::unique_ptr x2a4_elementGen2; + std::unique_ptr x2a8_elementGen3; + std::unique_ptr x2ac_elementGen4; + float x2b0_explodePlayerDistance; + bool x2b4_24_exploded : 1; + bool x2b4_25_ : 1; + +public: + CBouncyGrenade(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CActorParameters& actParams, TUniqueId parentId, + const SBouncyGrenadeData& data, float velocity, float explodePlayerDistance); + + void Accept(IVisitor& visitor) override { visitor.Visit(this); } + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) override; + void CollidedWith(TUniqueId id, const CCollisionInfoList& list, CStateManager& mgr) override; + [[nodiscard]] std::optional GetTouchBounds() const override; + void Render(CStateManager& mgr) override; + void Think(float dt, CStateManager& mgr) override; + void Touch(CActor& act, CStateManager& mgr) override; + +private: + void Explode(CStateManager& mgr, TUniqueId uid); +}; +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CChozoGhost.cpp b/Runtime/MP1/World/CChozoGhost.cpp index 56ead1af0..6018129a0 100644 --- a/Runtime/MP1/World/CChozoGhost.cpp +++ b/Runtime/MP1/World/CChozoGhost.cpp @@ -212,7 +212,7 @@ void CChozoGhost::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { *GetBodyController()); } -void CChozoGhost::Render(const CStateManager& mgr) const { +void CChozoGhost::Render(CStateManager& mgr) { if (x6c8_spaceWarpTime > 0.f) mgr.DrawSpaceWarp(x6cc_spaceWarpPosition, std::sin((M_PIF * x6c8_spaceWarpTime) / x56c_fadeOutDelay)); @@ -446,7 +446,7 @@ void CChozoGhost::Attack(CStateManager& mgr, EStateMsg msg, float dt) { xfc_constantForce.zeroOut(); } else if (msg == EStateMsg::Update) { TryCommand(mgr, pas::EAnimationState::MeleeAttack, &CPatterned::TryMeleeAttack, x67c_attackType); - GetBodyController()->GetCommandMgr().SetTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); + GetBodyController()->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); if (x67c_attackType != 2) FloatToLevel(x678_floorLevel, dt); } else if (msg == EStateMsg::Deactivate) { diff --git a/Runtime/MP1/World/CChozoGhost.hpp b/Runtime/MP1/World/CChozoGhost.hpp index 410e69c4d..9252fac8b 100644 --- a/Runtime/MP1/World/CChozoGhost.hpp +++ b/Runtime/MP1/World/CChozoGhost.hpp @@ -25,7 +25,7 @@ public: u32 x1c_numBolts; public: - CBehaveChance(CInputStream&); + explicit CBehaveChance(CInputStream&); EBehaveType GetBehave(EBehaveType type, CStateManager& mgr) const; float GetLurk() const { return x4_lurk; } @@ -109,7 +109,7 @@ public: void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; void Think(float dt, CStateManager&) override; void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; - void Render(const CStateManager& mgr) const override; + void Render(CStateManager& mgr) override; void Touch(CActor& act, CStateManager& mgr) override; EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f& pos, const zeus::CVector3f& dir, const CWeaponMode& mode, diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index d0316d5e5..cf0e74303 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -1,48 +1,1214 @@ #include "Runtime/MP1/World/CElitePirate.hpp" +#include "Runtime/Collision/CCollisionActor.hpp" +#include "Runtime/Collision/CCollisionActorManager.hpp" +#include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/MP1/World/CGrenadeLauncher.hpp" +#include "Runtime/Weapon/CGameProjectile.hpp" +#include "Runtime/World/CExplosion.hpp" +#include "Runtime/World/CPatternedInfo.hpp" +#include "Runtime/World/CPlayer.hpp" +#include "Runtime/World/CWorld.hpp" #include "Runtime/World/ScriptLoader.hpp" +#include "TCastTo.hpp" // Generated file, do not modify include path + namespace urde::MP1 { +namespace { +constexpr std::array skLeftArmJointList{{ + {"L_shoulder", "L_elbow", 1.f, 1.5f}, + {"L_wrist", "L_elbow", 0.9f, 1.3f}, + {"L_knee", "L_ankle", 0.9f, 1.3f}, +}}; + +constexpr std::array skRightArmJointList{{ + {"R_shoulder", "R_elbow", 1.f, 1.5f}, + {"R_wrist", "R_elbow", 0.9f, 1.3f}, + {"R_knee", "R_ankle", 0.9f, 1.3f}, +}}; + +constexpr std::array skSphereJointList{{ + {"Head_1", 1.2f}, + {"L_Palm_LCTR", 1.5f}, + {"R_Palm_LCTR", 1.5f}, + {"Spine_1", 1.5f}, + {"Collar", 1.2f}, + {"L_Ball", 0.8f}, + {"R_Ball", 0.8f}, +}}; +} // namespace + CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount) -: x0_(in.readFloatBig()) -, x4_(in.readFloatBig()) +: x0_tauntInterval(in.readFloatBig()) +, x4_tauntVariance(in.readFloatBig()) , x8_(in.readFloatBig()) , xc_(in.readFloatBig()) -, x10_(in.readFloatBig()) -, x14_(in.readFloatBig()) -, x18_(in.readFloatBig()) +, x10_attackChance(in.readFloatBig()) +, x14_shotAtTime(in.readFloatBig()) +, x18_shotAtTimeVariance(in.readFloatBig()) , x1c_(in.readFloatBig()) , x20_(in) -, x24_(CSfxManager::TranslateSFXID(in.readUint32Big())) -, x28_(ScriptLoader::LoadActorParameters(in)) -, x90_(ScriptLoader::LoadAnimationParameters(in)) +, x24_sfxAbsorb(CSfxManager::TranslateSFXID(in.readUint32Big())) +, x28_launcherActParams(ScriptLoader::LoadActorParameters(in)) +, x90_launcherAnimParams(ScriptLoader::LoadAnimationParameters(in)) , x9c_(in) , xa0_(CSfxManager::TranslateSFXID(in.readUint32Big())) , xa4_(in) , xa8_(in) -, xc4_(in.readFloatBig()) +, xc4_launcherHp(in.readFloatBig()) , xc8_(in) , xcc_(in) , xd0_(in) , xd4_(in) -, xd8_(in.readFloatBig()) -, xdc_(in.readFloatBig()) -, xe0_(in.readFloatBig()) -, xe4_(in.readFloatBig()) -, xe8_(zeus::degToRad(in.readFloatBig())) -, xec_(zeus::degToRad(in.readFloatBig())) -, xf0_(in.readUint32Big()) +, xd8_(in) +, xe0_trajectoryInfo(in) +, xf0_grenadeNumBounces(in.readUint32Big()) , xf4_(CSfxManager::TranslateSFXID(in.readUint32Big())) +, xf6_(CSfxManager::TranslateSFXID(in.readUint32Big())) , xf8_(in) , xfc_(in) , x118_(in) , x11c_(CSfxManager::TranslateSFXID(in.readUint32Big())) , x11e_(in.readBool()) -, x11f_(propCount < 24 ? true : in.readBool()) {} +, x11f_(propCount < 42 ? true : in.readBool()) {} CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, - const CElitePirateData& eliteData) + CElitePirateData data) : CPatterned(ECharacter::ElitePirate, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, - EMovementType::Ground, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Large) {} + EMovementType::Ground, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Large) +, x56c_vulnerability(pInfo.GetDamageVulnerability()) +, x5d8_data(std::move(data)) +, x6f8_boneTracking(*GetModelData()->GetAnimationData(), "Head_1", zeus::degToRad(80.f), zeus::degToRad(180.f), + EBoneTrackingFlags::None) +, x738_collisionAabb(GetBoundingBox(), GetMaterialList()) +, x7a0_initialSpeed(x3b4_speed) +, x7d0_pathFindSearch(nullptr, 1, pInfo.GetPathfindingIndex(), 1.f, 1.f) +, x8c0_(5.f) +, x988_24_damageOn(false) +, x988_25_attackingRightClaw(false) +, x988_26_attackingLeftClaw(false) +, x988_27_shotAt(false) +, x988_28_alert(false) +, x988_29_shockWaveAnim(false) +, x988_30_calledForBackup(false) +, x988_31_running(false) +, x989_24_onPath(false) { + if (x5d8_data.GetX20().IsValid()) { + x760_energyAbsorbDesc = g_SimplePool->GetObj({SBIG('PART'), x5d8_data.GetX20()}); + } + + x460_knockBackController.SetEnableFreeze(false); + x460_knockBackController.SetAutoResetImpulse(false); + x460_knockBackController.SetEnableBurn(false); + x460_knockBackController.SetEnableExplodeDeath(false); + x460_knockBackController.SetEnableLaggedBurnDeath(false); + SetupPathFindSearch(); +} + +void CElitePirate::Accept(IVisitor& visitor) { visitor.Visit(this); } + +void CElitePirate::Think(float dt, CStateManager& mgr) { + if (GetActive()) { + CPatterned::Think(dt, mgr); + x6f8_boneTracking.Update(dt); + if (HasWeakPointHead()) { + x730_collisionActorMgrHead->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); + } + x5d4_collisionActorMgr->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); + if (IsAttractingEnergy() && x5d8_data.GetX11F()) { + x3b4_speed = 2.f * x7a0_initialSpeed; + } else { + x3b4_speed = x7a0_initialSpeed; + } + UpdateTimers(dt); + UpdatePositionHistory(); + UpdateActorTransform(mgr, x772_launcherId, "grenadeLauncher_LCTR"sv); + UpdateHealthInfo(mgr); + x328_31_energyAttractor = IsAttractingEnergy(); + } +} + +void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + bool shouldPass = true; + + switch (msg) { + case EScriptObjectMessage::Activate: { + if (HasWeakPointHead()) { + x730_collisionActorMgrHead->SetActive(mgr, true); + } + if (CEntity* ent = mgr.ObjectById(x772_launcherId)) { + ent->SetActive(true); + } + break; + } + case EScriptObjectMessage::Deactivate: { + if (HasWeakPointHead()) { + x730_collisionActorMgrHead->SetActive(mgr, false); + } + x5d4_collisionActorMgr->SetActive(mgr, false); + if (CEntity* ent = mgr.ObjectById(x772_launcherId)) { + ent->SetActive(false); + } + break; + } + case EScriptObjectMessage::Alert: + x988_28_alert = true; + break; + case EScriptObjectMessage::Touched: { + if (HealthInfo(mgr)->GetHP() <= 0.f) { + break; + } + const TCastToConstPtr actor = mgr.ObjectById(uid); + if (!actor) { + if (uid == x772_launcherId && x772_launcherId != kInvalidUniqueId) { + SetShotAt(true, mgr); + } + break; + } + const TUniqueId touchedUid = actor->GetLastTouchedObject(); + if (touchedUid != mgr.GetPlayer().GetUniqueId()) { + if (TCastToConstPtr(mgr.ObjectById(touchedUid))) { + SetShotAt(true, mgr); + } + break; + } + if (!x988_24_damageOn) { + if (x420_curDamageRemTime <= 0.f) { + CDamageInfo info = GetContactDamage(); + info.SetDamage(0.5f * info.GetDamage()); + mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), GetUniqueId(), info, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), zeus::skZero3f); + x420_curDamageRemTime = x424_damageWaitTime; + } + break; + } + if ((!x988_25_attackingRightClaw || !IsArmClawCollider(uid, x774_collisionRJointIds)) && + (!x988_26_attackingLeftClaw || !IsArmClawCollider(uid, x788_collisionLJointIds))) { + break; + } + mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), GetUniqueId(), GetContactDamage(), + CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), zeus::skZero3f); + x420_curDamageRemTime = x424_damageWaitTime; + x988_24_damageOn = false; + break; + } + case EScriptObjectMessage::Registered: { + x450_bodyController->Activate(mgr); + SetupCollisionManager(mgr); + x772_launcherId = mgr.AllocateUniqueId(); + CreateGrenadeLauncher(mgr, x772_launcherId); + const auto& bodyStateInfo = x450_bodyController->GetBodyStateInfo(); + if (bodyStateInfo.GetMaxSpeed() > 0.f) { + x7a4_steeringSpeed = (0.99f * bodyStateInfo.GetLocomotionSpeed(pas::ELocomotionAnim::Walk)) / bodyStateInfo.GetMaxSpeed(); + } + x450_bodyController->GetCommandMgr().SetSteeringBlendMode(ESteeringBlendMode::FullSpeed); + x450_bodyController->GetCommandMgr().SetSteeringSpeedRange(x7a4_steeringSpeed, x7a4_steeringSpeed); + break; + } + case EScriptObjectMessage::Deleted: + if (HasWeakPointHead()) { + x730_collisionActorMgrHead->Destroy(mgr); + } + x5d4_collisionActorMgr->Destroy(mgr); + mgr.FreeScriptObject(x772_launcherId); + break; + case EScriptObjectMessage::InitializedInArea: + x7d0_pathFindSearch.SetArea(mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways())->GetPostConstructed()->x10bc_pathArea); + break; + case EScriptObjectMessage::Damage: + shouldPass = false; + if (const TCastToConstPtr actor = mgr.ObjectById(uid)) { + if (const TCastToConstPtr projectile = mgr.ObjectById(actor->GetLastTouchedObject())) { + if (uid == x770_collisionHeadId) { + x428_damageCooldownTimer = 0.33f; + const auto& damageInfo = projectile->GetDamageInfo(); + KnockBack(projectile->GetTranslation() - projectile->GetPreviousPos(), mgr, damageInfo, + EKnockBackType::Radius, false, damageInfo.GetKnockBackPower()); + CPatterned::AcceptScriptMsg(msg, uid, mgr); + } else if (uid == x79c_ && x760_energyAbsorbDesc->IsLoaded()) { + CreateEnergyAbsorb(mgr, projectile->GetTransform()); + } + SetShotAt(true, mgr); + } + } else if (uid == x772_launcherId && x772_launcherId != kInvalidUniqueId) { + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCKnockBackCmd(GetTransform().frontVector(), pas::ESeverity::Eight)); + } else { + ApplyDamageToHead(mgr, uid); + } + break; + case EScriptObjectMessage::InvulnDamage: { + SetShotAt(true, mgr); + if (!TCastToConstPtr(mgr.ObjectById(uid))) { + ApplyDamageToHead(mgr, uid); + } + break; + } + default: + break; + } + + if (shouldPass) { + CPatterned::AcceptScriptMsg(msg, uid, mgr); + } +} + +void CElitePirate::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { + CPatterned::PreRender(mgr, frustum); + auto modelData = GetModelData(); + x6f8_boneTracking.PreRender(mgr, *modelData->GetAnimationData(), GetTransform(), modelData->GetScale(), + *x450_bodyController); + auto numMaterialSets = modelData->GetNumMaterialSets(); + xb4_drawFlags.x1_matSetIdx = + numMaterialSets - 1 < x7cc_activeMaterialSet ? numMaterialSets - 1 : x7cc_activeMaterialSet; +} + +const CDamageVulnerability* CElitePirate::GetDamageVulnerability() const { + return &CDamageVulnerability::PassThroughVulnerabilty(); +} + +const CDamageVulnerability* CElitePirate::GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir, + const CDamageInfo& dInfo) const { + return &CDamageVulnerability::PassThroughVulnerabilty(); +} + +zeus::CVector3f CElitePirate::GetOrbitPosition(const CStateManager& mgr) const { + if (x772_launcherId != kInvalidUniqueId && + mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Thermal) { + if (const auto* actor = static_cast(mgr.GetObjectById(x772_launcherId))) { + return GetLockOnPosition(actor); + } + } + if (HasWeakPointHead()) { + if (const TCastToConstPtr actor = mgr.GetObjectById(x770_collisionHeadId)) { + return actor->GetTranslation(); + } + } + return GetLctrTransform("lockon_target_LCTR").origin; +} + +zeus::CVector3f CElitePirate::GetAimPosition(const CStateManager& mgr, float) const { + const std::shared_ptr& playerState = mgr.GetPlayerState(); + if (x5d4_collisionActorMgr->GetActive() && playerState->IsFiringComboBeam() && + playerState->GetCurrentBeam() == CPlayerState::EBeamId::Wave) { + if (const TCastToConstPtr actor = mgr.GetObjectById(x79c_)) { + return actor->GetTranslation(); + } + } + return GetOrbitPosition(mgr); +} + +void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { + bool handled = false; + switch (type) { + case EUserEventType::Projectile: + if (x772_launcherId != kInvalidUniqueId) { + CEntity* launcher = mgr.ObjectById(x772_launcherId); + mgr.SendScriptMsg(launcher, GetUniqueId(), EScriptObjectMessage::Action); + } + handled = true; + break; + case EUserEventType::DamageOn: + handled = true; + x988_24_damageOn = true; + break; + case EUserEventType::DamageOff: + handled = true; + x988_24_damageOn = false; + break; + case EUserEventType::ScreenShake: + HasWeakPointHead(); + handled = true; + break; + case EUserEventType::BeginAction: { + const zeus::CVector3f origin = GetTranslation(); + const zeus::CVector3f front = GetTransform().frontVector(); + const float dot = (GetLctrTransform(node.GetLocatorName()).origin - origin).dot(front); + const zeus::CTransform xf = zeus::CTransform::Translate({ + origin.x() + dot * front.x(), + origin.y() + dot * front.y(), + origin.z(), + }); + mgr.AddObject(new CShockWave(mgr.AllocateUniqueId(), "Shock Wave", {GetAreaIdAlways(), CEntity::NullConnectionList}, + xf, GetUniqueId(), GetShockWaveData(), IsElitePirate() ? 2.f : 1.3f, + IsElitePirate() ? 0.4f : 0.5f)); + handled = true; + break; + } + case EUserEventType::BecomeShootThrough: + if (HasWeakPointHead()) { + const u32 numCollisionActors = x730_collisionActorMgrHead->GetNumCollisionActors(); + for (u32 i = 0; i < numCollisionActors; ++i) { + const auto& description = x730_collisionActorMgrHead->GetCollisionDescFromIndex(i); + if (TCastToPtr actor = mgr.ObjectById(description.GetCollisionActorId())) { + actor->AddMaterial(EMaterialTypes::ProjectilePassthrough, mgr); + } + } + } + handled = true; + break; + default: + break; + } + if (!handled) { + CPatterned::DoUserAnimEvent(mgr, node, type, dt); + } +} + +const CCollisionPrimitive* CElitePirate::GetCollisionPrimitive() const { return &x738_collisionAabb; } + +void CElitePirate::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, + EKnockBackType type, bool inDeferred, float magnitude) { + if (!CanKnockBack(info)) { + return; + } + CPatterned::KnockBack(pos, mgr, info, type, inDeferred, magnitude); + if (info.GetWeaponMode().IsComboed() && info.GetWeaponMode().GetType() == EWeaponType::Ice) { + Freeze(mgr, zeus::skZero3f, GetTransform().transposeRotate(pos), 1.5f); + } +} + +void CElitePirate::TakeDamage(const zeus::CVector3f& pos, float) {} + +void CElitePirate::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + x400_24_hitByPlayerProjectile = false; + x989_24_onPath = false; + } + CPatterned::Patrol(mgr, msg, dt); +} + +void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x989_24_onPath = true; + x988_28_alert = false; + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + x6f8_boneTracking.SetTarget(mgr.GetPlayer().GetUniqueId()); + x6f8_boneTracking.SetActive(true); + UpdateDestPos(mgr); + CPatterned::PathFind(mgr, msg, dt); + x7bc_tauntTimer = x5d8_data.GetTauntVariance() * mgr.GetActiveRandom()->Float() + x5d8_data.GetTauntInterval(); + if (TooClose(mgr, 0.f)) { + x450_bodyController->GetCommandMgr().ClearLocomotionCmds(); + } + } else if (msg == EStateMsg::Update) { + if (x7bc_tauntTimer > 0.f) { + x7bc_tauntTimer -= dt; + } + if (!TooClose(mgr, 0.f) && !PathShagged(mgr, 0.f)) { + CPatterned::PathFind(mgr, msg, dt); + } else if (PathShagged(mgr, 0.f)) { + const zeus::CVector3f move = x8c0_.GetValue(GetTranslation(), GetTransform().frontVector()); + if (move != zeus::skZero3f) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f)); + } + } else if (ShouldTurn(mgr, 0.f)) { + const zeus::CVector3f aim = + mgr.GetPlayer().GetAimPosition(mgr, 0.5f * GetModelData()->GetAnimationData()->GetSpeedScale()); + const zeus::CVector3f face = aim - GetTranslation(); + if (face.canBeNormalized()) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f)); + } + } + } else if (msg == EStateMsg::Deactivate) { + x6f8_boneTracking.SetActive(false); + } +} + +void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + if (HasPatrolPath(mgr, 0.f)) { + CPatterned::Patrol(mgr, msg, dt); + UpdateDest(mgr); + } else { + SetDestPos(x3a0_latestLeashPosition); + } + x8b4_targetDestPos = x2e0_destPos; + if (GetSearchPath() != nullptr) { + CPatterned::PathFind(mgr, msg, dt); + } + } else if (msg == EStateMsg::Update) { + if (PathShagged(mgr, 0.f)) { + const zeus::CVector3f move = x45c_steeringBehaviors.Arrival(*this, x8b4_targetDestPos, 25.f); + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f)); + } else { + CPatterned::PathFind(mgr, msg, dt); + } + } else if (msg == EStateMsg::Deactivate) { + x988_28_alert = false; + } +} + +void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk); + x989_24_onPath = false; + CMaterialFilter filter = GetMaterialFilter(); + filter.ExcludeList().Add( + {EMaterialTypes::Wall, EMaterialTypes::Ceiling, EMaterialTypes::AIBlock, EMaterialTypes::Character}); + SetMaterialFilter(filter); + } else if (msg == EStateMsg::Deactivate) { + CMaterialFilter filter = GetMaterialFilter(); + filter.ExcludeList().Remove( + {EMaterialTypes::Wall, EMaterialTypes::Ceiling, EMaterialTypes::AIBlock, EMaterialTypes::Character}); + SetMaterialFilter(filter); + } +} + +void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x988_31_running = true; + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + x450_bodyController->GetCommandMgr().SetSteeringSpeedRange(1.f, 1.f); + x6f8_boneTracking.SetTarget(mgr.GetPlayer().GetUniqueId()); + x6f8_boneTracking.SetActive(true); + UpdateDestPos(mgr); + CPatterned::PathFind(mgr, msg, dt); + } else if (msg == EStateMsg::Update) { + if (PathShagged(mgr, 0.f)) { + const auto move = x8c0_.GetValue(GetTranslation(), GetTransform().frontVector()); + if (move != zeus::skZero3f) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f)); + } else if (ShouldTurn(mgr, 0.f)) { + const zeus::CVector3f aim = + mgr.GetPlayer().GetAimPosition(mgr, 0.5f * GetModelData()->GetAnimationData()->GetSpeedScale()); + const auto face = aim - GetTranslation(); + if (face.canBeNormalized()) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f)); + } + } + } else { + CPatterned::PathFind(mgr, msg, dt); + } + } else if (msg == EStateMsg::Deactivate) { + x988_31_running = false; + x6f8_boneTracking.SetActive(false); + x450_bodyController->GetCommandMgr().SetSteeringSpeedRange(x7a4_steeringSpeed, x7a4_steeringSpeed); + } +} + +void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x568_state = EState::One; + } else if (msg == EStateMsg::Update) { + if (x568_state == EState::Zero) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate) { + x568_state = EState::Two; + } else { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Zero)); + } + } else if (x568_state == EState::One) { + if (ShouldTurn(mgr, 0.f)) { + const auto face = mgr.GetPlayer().GetTranslation() - GetTranslation(); + if (face.canBeNormalized()) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f)); + } + } else { + x568_state = EState::Zero; + } + } else if (x568_state == EState::Two && x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Generate) { + x568_state = EState::Over; + } + } else if (msg == EStateMsg::Deactivate) { + SetShotAt(false, mgr); + SetLaunchersActive(mgr, true); + } +} + +void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x568_state = EState::Zero; + ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::CVector3f(2.f)); + if (x64_modelData->GetNumMaterialSets() > 1) { + x7cc_activeMaterialSet = 1; + } + } else if (msg == EStateMsg::Update) { + if (x568_state == EState::Zero) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::MeleeAttack) { + x568_state = EState::One; + x988_25_attackingRightClaw = true; + x7c8_currAnimId = x450_bodyController->GetCurrentAnimId(); + } else { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCMeleeAttackCmd(pas::ESeverity::One)); + } + } else if (x568_state == EState::One) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::MeleeAttack) { + if (x7c8_currAnimId == x450_bodyController->GetCurrentAnimId()) { + x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); + if (ShouldAttack(mgr, 0.f)) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCMeleeAttackCmd(pas::ESeverity::Two)); + } + } else { + x568_state = EState::Two; + x988_25_attackingRightClaw = false; + x988_26_attackingLeftClaw = true; + ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::skZero3f); + ExtendTouchBounds(mgr, x788_collisionLJointIds, zeus::CVector3f(2.f)); + } + } else { + x568_state = EState::Over; + } + } else if (x568_state == EState::Two) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::MeleeAttack) { + x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); + } else { + x568_state = EState::Over; + } + } + } else if (msg == EStateMsg::Deactivate) { + CheckAttackChance(mgr); + x988_24_damageOn = false; + x988_26_attackingLeftClaw = false; + x988_25_attackingRightClaw = false; + x7c8_currAnimId = -1; + ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::skZero3f); + ExtendTouchBounds(mgr, x788_collisionLJointIds, zeus::skZero3f); + x7cc_activeMaterialSet = 0; + } +} + +void CElitePirate::Taunt(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Taunt(mgr, msg, dt); } + +void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x568_state = EState::Zero; + } else if (msg == EStateMsg::Update) { + const zeus::CVector3f& playerPos = mgr.GetPlayer().GetTranslation(); + if (x568_state == EState::Zero) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { + x568_state = EState::Two; + } else { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCProjectileAttackCmd(pas::ESeverity::One, playerPos, false)); + } + } else if (x568_state == EState::Two) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { + x450_bodyController->GetCommandMgr().DeliverTargetVector(playerPos - GetTranslation()); + } else { + x568_state = EState::Over; + } + } + } else if (msg == EStateMsg::Deactivate) { + CheckAttackChance(mgr); + } +} + +void CElitePirate::SpecialAttack(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x568_state = EState::Zero; + } else if (msg == EStateMsg::Update) { + if (x568_state == EState::Zero) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { + x568_state = EState::Two; + x988_29_shockWaveAnim = true; + } else { + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCProjectileAttackCmd(pas::ESeverity::Two, mgr.GetPlayer().GetTranslation(), false)); + } + } else if (x568_state == EState::Two) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { + x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation()); + } else { + x568_state = EState::Over; + } + } + } else if (msg == EStateMsg::Deactivate) { + CheckAttackChance(mgr); + x988_29_shockWaveAnim = false; + } +} + +void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x568_state = EState::Zero; + x988_30_calledForBackup = true; + SetShotAt(false, mgr); + } else if (msg == EStateMsg::Update) { + if (x568_state == EState::Zero) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate) { + x568_state = EState::Two; + } else { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Five, zeus::skZero3f)); + } + } else if (x568_state == EState::Two) { + if (x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Generate) { + x568_state = EState::Over; + } + } + } else if (msg == EStateMsg::Deactivate) { + SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); + } +} + +void CElitePirate::Cover(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch); + if (HasWeakPointHead()) { + if (TCastToPtr actor = mgr.ObjectById(x770_collisionHeadId)) { + actor->SetDamageVulnerability(CDamageVulnerability::ImmuneVulnerabilty()); + } + } + x5d4_collisionActorMgr->SetActive(mgr, true); + x6f8_boneTracking.SetTarget(mgr.GetPlayer().GetUniqueId()); + x6f8_boneTracking.SetActive(true); + UpdateDestPos(mgr); + CPatterned::PathFind(mgr, msg, dt); + if (TooClose(mgr, 0.f)) { + x450_bodyController->GetCommandMgr().ClearLocomotionCmds(); + } + } else if (msg == EStateMsg::Update) { + if (x988_27_shotAt) { + x7c0_shotAtTimer -= dt; + if (x7c0_shotAtTimer <= 0.f) { + x988_27_shotAt = false; + } + } + x7a8_pathShaggedTime = PathShagged(mgr, 0.f) ? x7a8_pathShaggedTime + dt : 0.f; + if (!TooClose(mgr, 0.f) && !PathShagged(mgr, 0.f)) { + CPatterned::PathFind(mgr, msg, dt); + } else if (PathShagged(mgr, 0.f)) { + const zeus::CVector3f move = x8c0_.GetValue(GetTranslation(), GetTransform().frontVector()); + if (move != zeus::skZero3f) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f)); + } + } else if (ShouldTurn(mgr, 0.f)) { + const zeus::CVector3f aim = + mgr.GetPlayer().GetAimPosition(mgr, 0.5f * GetModelData()->GetAnimationData()->GetSpeedScale()); + const zeus::CVector3f face = aim - GetTranslation(); + if (face.canBeNormalized()) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f)); + } + } + AttractProjectiles(mgr); + UpdateAbsorbBodyState(mgr, dt); + } else if (msg == EStateMsg::Deactivate) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + x6f8_boneTracking.SetActive(false); + if (HasWeakPointHead()) { + if (TCastToPtr actor = mgr.ObjectById(x770_collisionHeadId)) { + actor->SetDamageVulnerability(x56c_vulnerability); + } + } + x5d4_collisionActorMgr->SetActive(mgr, false); + } +} + +bool CElitePirate::TooClose(CStateManager& mgr, float) { + return x2fc_minAttackRange * x2fc_minAttackRange > (GetTranslation() - mgr.GetPlayer().GetTranslation()).magSquared(); +} + +bool CElitePirate::InDetectionRange(CStateManager& mgr, float arg) { + return x988_28_alert ? true : CPatterned::InDetectionRange(mgr, arg); +} + +bool CElitePirate::SpotPlayer(CStateManager& mgr, float arg) { + return x988_28_alert ? true : CPatterned::SpotPlayer(mgr, arg); +} + +bool CElitePirate::AnimOver(CStateManager& mgr, float) { return x568_state == EState::Over; } + +bool CElitePirate::ShouldAttack(CStateManager& mgr, float) { + if ((mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() > x2fc_minAttackRange * x2fc_minAttackRange) { + return false; + } + return !ShouldTurn(mgr, 0.f); +} + +bool CElitePirate::InPosition(CStateManager& mgr, float) { + return (x8b4_targetDestPos - GetTranslation()).magSquared() < 25.f; +} + +bool CElitePirate::ShouldTurn(CStateManager& mgr, float) { + return zeus::CVector2f::getAngleDiff((mgr.GetPlayer().GetTranslation() - GetTranslation()).toVec2f(), + GetTransform().frontVector().toVec2f()) > zeus::degToRad(15.f); +} + +bool CElitePirate::AggressionCheck(CStateManager& mgr, float arg) { + if (x772_launcherId == kInvalidUniqueId && !PathShagged(mgr, arg)) { + if (x988_31_running) { + return true; + } + return 4.f * x300_maxAttackRange * x300_maxAttackRange < + (mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared(); + } + return false; +} + +bool CElitePirate::ShouldTaunt(CStateManager& mgr, float) { return x7bc_tauntTimer <= 0.f; } + +bool CElitePirate::ShouldFire(CStateManager& mgr, float) { return ShouldFireFromLauncher(mgr, x772_launcherId); } + +bool CElitePirate::ShotAt(CStateManager& mgr, float) { return x988_27_shotAt; } + +bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float) { + if (x7b8_attackTimer <= 0.f && GetAreaIdAlways() == mgr.GetPlayer().GetAreaIdAlways()) { + const zeus::CVector3f dist = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation(); + const float magSquared = dist.magSquared(); + if (x2fc_minAttackRange * x2fc_minAttackRange <= magSquared && + magSquared <= x300_maxAttackRange * x300_maxAttackRange) { + return std::abs(dist.z()) < 3.f; + } + } + return false; +} + +bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float) { + return ShouldCallForBackupFromLauncher(mgr, x772_launcherId); +} + +CPathFindSearch* CElitePirate::GetSearchPath() { return &x7d0_pathFindSearch; } + +void CElitePirate::SetupHealthInfo(CStateManager& mgr) { + const CHealthInfo* const health = HealthInfo(mgr); + x7b4_hp = health->GetHP(); + if (HasWeakPointHead()) { + if (TCastToPtr actor = mgr.ObjectById(x770_collisionHeadId)) { + auto actHealth = actor->HealthInfo(mgr); + actHealth->SetHP(health->GetHP()); + actHealth->SetKnockbackResistance(health->GetKnockbackResistance()); + actor->SetDamageVulnerability(x56c_vulnerability); + } + } + SetupLauncherHealthInfo(mgr, x772_launcherId); +} + +void CElitePirate::SetLaunchersActive(CStateManager& mgr, bool val) { SetLauncherActive(mgr, val, x772_launcherId); } + +void CElitePirate::SetupPathFindSearch() { + const float scale = 1.5f * GetModelData()->GetScale().y(); + const float fVar1 = IsElitePirate() ? 5.f : 1.f; + const zeus::CAABox box{{-scale, -scale, 0.f}, {scale, scale, fVar1 * scale}}; + SetBoundingBox(box); + x738_collisionAabb.SetBox(box); + x7d0_pathFindSearch.SetCharacterRadius(scale); + x7d0_pathFindSearch.SetCharacterHeight(3.f * scale); +} + +void CElitePirate::SetShotAt(bool val, CStateManager& mgr) { + if (!IsElitePirate() || x7b4_hp <= 0.f || !val) { + x988_27_shotAt = val; + } else if (HealthInfo(mgr)->GetHP() / x7b4_hp <= x7b0_) { + x7b0_ -= 0.2f; + x988_27_shotAt = true; + } + if (x988_27_shotAt) { + x7c0_shotAtTimer = mgr.GetActiveRandom()->Float() * x5d8_data.GetShotAtTimeVariance() + x5d8_data.GetShotAtTime(); + } else { + x7c0_shotAtTimer = 0.f; + } +} + +bool CElitePirate::IsArmClawCollider(TUniqueId uid, const rstl::reserved_vector& vec) const { + return std::find(vec.begin(), vec.end(), uid) != vec.end(); +} + +void CElitePirate::AddCollisionList(const SJointInfo* joints, size_t count, + std::vector& outJoints) const { + const CAnimData* animData = GetModelData()->GetAnimationData(); + for (size_t i = 0; i < count; ++i) { + const auto& joint = joints[i]; + const CSegId from = animData->GetLocatorSegId(joint.from); + const CSegId to = animData->GetLocatorSegId(joint.to); + if (to.IsInvalid() || from.IsInvalid()) { + continue; + } + outJoints.emplace_back(CJointCollisionDescription::SphereSubdivideCollision( + to, from, joint.radius, joint.separation, CJointCollisionDescription::EOrientationType::One, joint.from, 10.f)); + } +} + +void CElitePirate::AddSphereCollisionList(const SSphereJointInfo* joints, size_t count, + std::vector& outJoints) const { + const CAnimData* animData = GetModelData()->GetAnimationData(); + for (size_t i = 0; i < count; ++i) { + const auto& joint = joints[i]; + const CSegId seg = animData->GetLocatorSegId(joint.name); + if (seg.IsInvalid()) { + continue; + } + outJoints.emplace_back(CJointCollisionDescription::SphereCollision(seg, joint.radius, joint.name, 10.f)); + } +} + +void CElitePirate::SetupCollisionManager(CStateManager& mgr) { + constexpr size_t jointInfoCount = skLeftArmJointList.size() + skRightArmJointList.size() + skSphereJointList.size(); + std::vector joints; + joints.reserve(jointInfoCount); + AddCollisionList(skLeftArmJointList.data(), skLeftArmJointList.size(), joints); + AddCollisionList(skRightArmJointList.data(), skLeftArmJointList.size(), joints); + AddSphereCollisionList(skSphereJointList.data(), skSphereJointList.size(), joints); + if (HasWeakPointHead()) { + x730_collisionActorMgrHead = + std::make_unique(mgr, GetUniqueId(), GetAreaIdAlways(), joints, true); + x730_collisionActorMgrHead->SetActive(mgr, GetActive()); + } + x774_collisionRJointIds.clear(); + x788_collisionLJointIds.clear(); + + const CAnimData* animData = GetModelData()->GetAnimationData(); + constexpr zeus::CVector3f bounds{4.f, 4.f, 2.f}; + joints.emplace_back(CJointCollisionDescription::OBBCollision(animData->GetLocatorSegId("L_Palm_LCTR"sv), bounds, + zeus::skZero3f, "Shield"sv, 10.f)); + x5d4_collisionActorMgr = + std::make_unique(mgr, GetUniqueId(), GetAreaIdAlways(), joints, false); + + SetupCollisionActorInfo(mgr); + SetupHealthInfo(mgr); + + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude( + {EMaterialTypes::Solid}, + {EMaterialTypes::CollisionActor, EMaterialTypes::AIPassthrough, EMaterialTypes::Player})); + AddMaterial(EMaterialTypes::ProjectilePassthrough, mgr); +} + +void CElitePirate::SetupCollisionActorInfo(CStateManager& mgr) { + if (HasWeakPointHead()) { + for (size_t i = 0; i < x730_collisionActorMgrHead->GetNumCollisionActors(); ++i) { + const auto& colDesc = x730_collisionActorMgrHead->GetCollisionDescFromIndex(i); + const TUniqueId uid = colDesc.GetCollisionActorId(); + if (TCastToPtr act = mgr.ObjectById(uid)) { + if (colDesc.GetName() == "Head_1"sv) { + x770_collisionHeadId = uid; + } else if (IsArmClawCollider(colDesc.GetName(), "R_Palm_LCTR"sv, skRightArmJointList.data(), + skRightArmJointList.size())) { + x774_collisionRJointIds.push_back(uid); + } else if (IsArmClawCollider(colDesc.GetName(), "L_Palm_LCTR"sv, skLeftArmJointList.data(), + skLeftArmJointList.size())) { + x788_collisionLJointIds.push_back(uid); + } + if (uid != x770_collisionHeadId) { + act->SetDamageVulnerability(CDamageVulnerability::ReflectVulnerabilty()); + } + } + } + x730_collisionActorMgrHead->AddMaterial( + mgr, {EMaterialTypes::AIJoint, EMaterialTypes::CameraPassthrough, EMaterialTypes::Immovable}); + } + + const CJointCollisionDescription& description = x5d4_collisionActorMgr->GetCollisionDescFromIndex(0); + x79c_ = description.GetCollisionActorId(); + if (TCastToPtr act = mgr.ObjectById(x79c_)) { + act->SetWeaponCollisionResponseType(EWeaponCollisionResponseTypes::None); + } + x5d4_collisionActorMgr->AddMaterial(mgr, {EMaterialTypes::AIJoint, EMaterialTypes::CameraPassthrough}); +} + +bool CElitePirate::IsArmClawCollider(std::string_view name, std::string_view locator, const SJointInfo* info, + size_t infoCount) const { + if (name == locator) { + return true; + } + for (size_t i = 0; i < infoCount; ++i) { + if (name == info[i].from) { + return true; + } + } + return false; +} + +void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) { + const CAnimationParameters& params = x5d8_data.GetLauncherAnimParams(); + if (!params.GetACSFile().IsValid()) { + return; + } + CModelData mData(CAnimRes(params.GetACSFile(), params.GetCharacter(), GetModelData()->GetScale(), + params.GetInitialAnimation(), true)); + const zeus::CAABox bounds = mData.GetBounds(GetTransform().getRotation()); + mgr.AddObject( + new CGrenadeLauncher(uid, "Grenade Launcher", {GetAreaIdAlways(), CEntity::NullConnectionList}, GetTransform(), + std::move(mData), bounds, CHealthInfo(x5d8_data.GetLauncherHP(), 10.f), x56c_vulnerability, + x5d8_data.GetLauncherActParams(), GetUniqueId(), x5d8_data.GetGrenadeLauncherData(), 0.f)); +} + +void CElitePirate::ApplyDamageToHead(CStateManager& mgr, TUniqueId uid) { + if (!HasWeakPointHead()) { + return; + } + if (const TCastToConstPtr weapon = mgr.ObjectById(uid)) { + CDamageInfo damageInfo = weapon->GetDamageInfo(); + damageInfo.SetRadius(0.f); + mgr.ApplyDamage(uid, x770_collisionHeadId, weapon->GetOwnerId(), damageInfo, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), zeus::skZero3f); + } +} + +void CElitePirate::CreateEnergyAbsorb(CStateManager& mgr, const zeus::CTransform& xf) { + if (x7ac_energyAbsorbCooldown > 0.f) { + return; + } + mgr.AddObject(new CExplosion(*x760_energyAbsorbDesc, mgr.AllocateUniqueId(), true, + {GetAreaIdAlways(), CEntity::NullConnectionList}, "Absorb energy Fx", xf, 0, + GetModelData()->GetScale(), zeus::skWhite)); + CSfxManager::AddEmitter(x5d8_data.GetSFXAbsorb(), GetTranslation(), zeus::skUp, false, false, 0x7f, + GetAreaIdAlways()); + x7ac_energyAbsorbCooldown = 0.25f; +} + +void CElitePirate::SetupLauncherHealthInfo(CStateManager& mgr, TUniqueId uid) { + const CHealthInfo* const health = HealthInfo(mgr); + if (uid != kInvalidUniqueId) { + if (TCastToPtr actor = mgr.ObjectById(uid)) { + auto actHealth = actor->HealthInfo(mgr); + actHealth->SetHP(x5d8_data.GetLauncherHP()); + actHealth->SetKnockbackResistance(health->GetKnockbackResistance()); + actor->SetDamageVulnerability(x56c_vulnerability); + } + } +} + +void CElitePirate::SetLauncherActive(CStateManager& mgr, bool val, TUniqueId uid) { + if (uid == kInvalidUniqueId) { + return; + } + if (auto entity = mgr.ObjectById(uid)) { + mgr.SendScriptMsg(entity, GetUniqueId(), val ? EScriptObjectMessage::Start : EScriptObjectMessage::Stop); + } +} + +zeus::CVector3f CElitePirate::GetLockOnPosition(const CActor* actor) const { + const zeus::CTransform targetTransform = actor->GetLocatorTransform("lockon_target_LCTR"sv); + return actor->GetTranslation() + actor->GetTransform().rotate(targetTransform.origin); +} + +bool CElitePirate::CanKnockBack(const CDamageInfo& info) const { + return !x400_25_alive || info.GetWeaponMode().IsComboed() || info.GetWeaponMode().GetType() != EWeaponType::Plasma; +} + +void CElitePirate::UpdateDestPos(CStateManager& mgr) { + x8b4_targetDestPos = GetTranslation(); + const zeus::CVector3f playerPos = mgr.GetPlayer().GetTranslation(); + const zeus::CVector3f dist = GetTranslation() - playerPos; + if (dist.canBeNormalized() && dist.magSquared() > x2fc_minAttackRange * x2fc_minAttackRange) { + x2e0_destPos = playerPos + (x2fc_minAttackRange * dist.normalized()); + x8b4_targetDestPos = x2e0_destPos; + } +} + +void CElitePirate::CheckAttackChance(CStateManager& mgr) { + if (mgr.GetActiveRandom()->Float() > x5d8_data.GetAttackChance()) { + x7b8_attackTimer = x308_attackTimeVariation * mgr.GetActiveRandom()->Float() + x304_averageAttackTime; + } +} + +void CElitePirate::AttractProjectiles(CStateManager& mgr) { + if (!IsAlive()) { + return; + } + const TCastToConstPtr actor = mgr.GetObjectById(x79c_); + if (!actor) { + return; + } + + float radius = x5d8_data.GetX1C(); + const zeus::CVector3f actorPos = actor->GetTranslation(); + const zeus::CVector3f pos = GetTranslation(); + rstl::reserved_vector projNearList; + const zeus::CAABox aabb{pos - radius, pos + radius}; + mgr.BuildNearList(projNearList, aabb, CMaterialFilter::MakeInclude({EMaterialTypes::Projectile}), nullptr); + if (projNearList.empty()) { + return; + } + + rstl::reserved_vector charNearList; + mgr.BuildNearList(charNearList, aabb, CMaterialFilter::MakeInclude({EMaterialTypes::Character}), nullptr); + for (const TUniqueId projId : projNearList) { + TCastToPtr projectile = mgr.ObjectById(projId); + if (!projectile || projectile->GetType() == EWeaponType::Missile || + projectile->GetOwnerId() != mgr.GetPlayer().GetUniqueId() || + projectile->GetAreaIdAlways() != GetAreaIdAlways()) { + continue; + } + + const zeus::CVector3f projectilePos = projectile->GetTranslation(); + const zeus::CVector3f actorProjDist = actorPos - projectilePos; + if (GetTransform().frontVector().dot(actorProjDist) < 0.f) { + const zeus::CVector3f projectileDir = projectilePos - projectile->GetPreviousPos(); + if (projectileDir.canBeNormalized() && IsClosestEnergyAttractor(mgr, charNearList, projectilePos)) { + const float actorProjMag = actorProjDist.magnitude(); + const zeus::CVector3f b = projectilePos + ((0.5f * actorProjMag) * projectileDir.normalized()); + const zeus::CVector3f c = actorPos + zeus::CVector3f{0.f, 0.f, 0.4f * 0.4f * actorProjMag}; + const zeus::CVector3f p1 = zeus::getBezierPoint(projectilePos, b, c, actorPos, 0.333f); + const zeus::CVector3f p2 = zeus::getBezierPoint(projectilePos, b, c, actorPos, 0.666f); + + const float magAdd = (p2 - p1).magnitude() + (p1 - projectilePos).magnitude() + (actorPos - p2).magnitude(); + const zeus::CVector3f p3 = + zeus::getBezierPoint(projectilePos, b, c, actorPos, projectileDir.magnitude() / magAdd); + + const zeus::CVector3f look = p3 - projectilePos; + if (look.canBeNormalized()) { + zeus::CTransform xf = zeus::lookAt(zeus::skZero3f, look); + xf.orthonormalize(); + CProjectileWeapon& weapon = projectile->ProjectileWeapon(); + weapon.SetWorldSpaceOrientation(xf); + const zeus::CVector3f scaledVelocity = 0.8f * weapon.GetVelocity().normalized(); + weapon.SetVelocity(weapon.GetVelocity() * 0.39999998f + (scaledVelocity * 0.6f)); + } + } + } + SetShotAt(true, mgr); + } +} + +void CElitePirate::UpdateAbsorbBodyState(CStateManager& mgr, float dt) { + if (!x988_27_shotAt || x450_bodyController->IsFrozen()) { + return; + } + x7c4_absorbUpdateTimer += dt; + if (x7c4_absorbUpdateTimer < 3.f) { + return; + } + if (x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Turn && + x450_bodyController->GetBodyStateInfo().GetCurrentState()->IsMoving()) { + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCAdditiveReactionCmd(pas::EAdditiveReactionType::Six, 1.f, false)); + } else { + bool b = false; + if (HasWeakPointHead()) { + if (const TCastToConstPtr actor = mgr.GetObjectById(x770_collisionHeadId)) { + const float z = actor->GetTranslation().z(); + b = z - 0.5f * (z - GetTranslation().z()) <= mgr.GetPlayer().GetTranslation().z(); + } + } + b = b || TooClose(mgr, 0.f); + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCAdditiveReactionCmd(b ? pas::EAdditiveReactionType::Seven : pas::EAdditiveReactionType::Five, 1.f, false)); + } + x7c4_absorbUpdateTimer = 0.f; +} + +bool CElitePirate::IsAttractingEnergy() const { + if (x450_bodyController->GetLocomotionType() == pas::ELocomotionType::Crouch) { + const auto state = x450_bodyController->GetCurrentStateId(); + return state == pas::EAnimationState::Locomotion || state == pas::EAnimationState::Turn; + } + return false; +} + +void CElitePirate::UpdateTimers(float dt) { + if (x7b8_attackTimer > 0.f) { + x7b8_attackTimer -= dt; + } + if (x7ac_energyAbsorbCooldown > 0.f) { + x7ac_energyAbsorbCooldown -= dt; + } +} + +void CElitePirate::UpdatePositionHistory() { + const zeus::CVector3f pos = GetTranslation(); + if (x7d0_pathFindSearch.OnPath(pos) == CPathFindSearch::EResult::Success) { + x8c0_.Clear(); + } + x8c0_.AddValue(pos); +} + +void CElitePirate::UpdateActorTransform(CStateManager& mgr, TUniqueId& uid, std::string_view name) { + if (uid == kInvalidUniqueId) { + return; + } + auto* actor = static_cast(mgr.ObjectById(uid)); + if (actor == nullptr) { + uid = kInvalidUniqueId; + return; + } + actor->SetTransform(GetLctrTransform(name)); +} + +void CElitePirate::UpdateHealthInfo(CStateManager& mgr) { + const float hp = HealthInfo(mgr)->GetHP(); + if (HasWeakPointHead()) { + if (TCastToPtr actor = mgr.ObjectById(x770_collisionHeadId)) { + const float headHp = actor->HealthInfo(mgr)->GetHP(); + HealthInfo(mgr)->SetHP(hp - (hp - headHp)); + *actor->HealthInfo(mgr) = *HealthInfo(mgr); // TODO does this work? + } + } + if (HealthInfo(mgr)->GetHP() <= 0.f) { + Death(mgr, zeus::skZero3f, EScriptObjectState::DeathRattle); + RemoveMaterial(EMaterialTypes::Orbit, EMaterialTypes::Target, mgr); + } +} + +void CElitePirate::ExtendTouchBounds(const CStateManager& mgr, const rstl::reserved_vector& uids, + const zeus::CVector3f& vec) const { + for (const TUniqueId uid : uids) { + if (TCastToPtr actor = mgr.ObjectById(uid)) { + actor->SetExtendedTouchBounds(vec); + } + } +} + +bool CElitePirate::ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcherId) { + if (x7b8_attackTimer > 0.f || launcherId == kInvalidUniqueId) { + return false; + } + const auto* launcher = static_cast(mgr.GetObjectById(launcherId)); + if (launcher == nullptr) { + return false; + } + const zeus::CVector3f aim = mgr.GetPlayer().GetAimPosition(mgr, 0.f); + if (x300_maxAttackRange * x300_maxAttackRange > (aim - GetTranslation()).magSquared() || ShouldTurn(mgr, 0.f)) { + return false; + } + const zeus::CVector3f origin = GetLockOnPosition(launcher); + if (IsPatternObstructed(mgr, origin, aim)) { + return false; + } + const zeus::CVector3f target = CGrenadeLauncher::GrenadeTarget(mgr); + float angleOut = x5d8_data.GetGrenadeTrajectoryInfo().GetAngleMin(); + float velocityOut = x5d8_data.GetGrenadeTrajectoryInfo().GetVelocityMin(); + CGrenadeLauncher::CalculateGrenadeTrajectory(target, origin, x5d8_data.GetGrenadeTrajectoryInfo(), angleOut, + velocityOut); + const zeus::CVector3f rot = GetTransform().rotate({0.f, std::cos(angleOut), std::sin(angleOut)}); + return !CPatterned::IsPatternObstructed(mgr, target, target + (7.5f * rot)); +} + +bool CElitePirate::ShouldCallForBackupFromLauncher(const CStateManager& mgr, TUniqueId uid) const { + if (x988_30_calledForBackup || uid != kInvalidUniqueId || !x5d8_data.GetX11E()) { + return false; + } + return x7a8_pathShaggedTime >= 3.f; +} + +bool CElitePirate::IsClosestEnergyAttractor(const CStateManager& mgr, + const rstl::reserved_vector& charNearList, + const zeus::CVector3f& projectilePos) const { + const float distance = (projectilePos - GetTranslation()).magSquared(); + for (const auto id : charNearList) { + if (const TCastToConstPtr actor = mgr.GetObjectById(id)) { + if (actor->GetUniqueId() != GetUniqueId() && actor->IsEnergyAttractor() && + (projectilePos - actor->GetTranslation()).magSquared() < distance) { + return false; + } + } + } + return true; +} + +zeus::CVector3f CElitePirate::SUnknownStruct::GetValue(const zeus::CVector3f& v1, const zeus::CVector3f& v2) { + while (!x4_.empty()) { + const zeus::CVector3f v = x4_.back() - v1; + if (v.dot(v2) > 0.f && v.isMagnitudeSafe()) { + return v.normalized(); + } + x4_.pop_back(); + } + return zeus::skZero3f; +} + +void CElitePirate::SUnknownStruct::AddValue(const zeus::CVector3f& vec) { + if (x4_.size() > 15) { + return; + } + if (x4_.empty()) { + x4_.emplace_back(vec); + return; + } + if (x4_.back().magSquared() > x0_) { + x4_.emplace_back(vec); + } +} } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index 0f7d31de0..6abacb4cb 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -1,59 +1,230 @@ #pragma once -#include - -#include "Runtime/RetroTypes.hpp" +#include "Runtime/Character/CBoneTracking.hpp" +#include "Runtime/Collision/CCollisionActorManager.hpp" +#include "Runtime/Collision/CJointCollisionDescription.hpp" +#include "Runtime/MP1/World/CGrenadeLauncher.hpp" +#include "Runtime/MP1/World/CShockWave.hpp" #include "Runtime/World/CActorParameters.hpp" #include "Runtime/World/CAnimationParameters.hpp" +#include "Runtime/World/CPathFindSearch.hpp" #include "Runtime/World/CPatterned.hpp" namespace urde::MP1 { class CElitePirateData { - float x0_; - float x4_; +private: + float x0_tauntInterval; + float x4_tauntVariance; float x8_; float xc_; - float x10_; - float x14_; - float x18_; + float x10_attackChance; + float x14_shotAtTime; + float x18_shotAtTimeVariance; float x1c_; CAssetId x20_; - s16 x24_; - CActorParameters x28_; - CAnimationParameters x90_; + u16 x24_sfxAbsorb; + CActorParameters x28_launcherActParams; + CAnimationParameters x90_launcherAnimParams; CAssetId x9c_; - s16 xa0_; + u16 xa0_; CAssetId xa4_; CDamageInfo xa8_; - float xc4_; + float xc4_launcherHp; CAssetId xc8_; CAssetId xcc_; CAssetId xd0_; CAssetId xd4_; - float xd8_; - float xdc_; - float xe0_; - float xe4_; - float xe8_; - float xec_; - u32 xf0_; - u32 xf4_; + SGrenadeUnknownStruct xd8_; + SGrenadeTrajectoryInfo xe0_trajectoryInfo; + u32 xf0_grenadeNumBounces; + u16 xf4_; + u16 xf6_; CAssetId xf8_; CDamageInfo xfc_; CAssetId x118_; - s16 x11c_; + u16 x11c_; bool x11e_; bool x11f_; public: CElitePirateData(CInputStream&, u32 propCount); + + [[nodiscard]] float GetTauntInterval() const { return x0_tauntInterval; } + [[nodiscard]] float GetTauntVariance() const { return x4_tauntVariance; } + [[nodiscard]] float GetAttackChance() const { return x10_attackChance; } + [[nodiscard]] float GetShotAtTime() const { return x14_shotAtTime; } + [[nodiscard]] float GetShotAtTimeVariance() const { return x18_shotAtTimeVariance; } + [[nodiscard]] float GetX1C() const { return x1c_; } + [[nodiscard]] CAssetId GetX20() const { return x20_; } + [[nodiscard]] u16 GetSFXAbsorb() const { return x24_sfxAbsorb; } + [[nodiscard]] const CActorParameters& GetLauncherActParams() const { return x28_launcherActParams; } + [[nodiscard]] const CAnimationParameters& GetLauncherAnimParams() const { return x90_launcherAnimParams; } + [[nodiscard]] float GetLauncherHP() const { return xc4_launcherHp; } + [[nodiscard]] const SGrenadeTrajectoryInfo& GetGrenadeTrajectoryInfo() const { return xe0_trajectoryInfo; } + [[nodiscard]] CAssetId GetXF8() const { return xf8_; } + [[nodiscard]] const CDamageInfo& GetXFC() const { return xfc_; } + [[nodiscard]] CAssetId GetX118() const { return x118_; } + [[nodiscard]] u16 GetX11C() const { return x11c_; } + [[nodiscard]] bool GetX11E() const { return x11e_; } + [[nodiscard]] bool GetX11F() const { return x11f_; } + + [[nodiscard]] SBouncyGrenadeData GetBouncyGrenadeData() const { + return {xd8_, xa8_, xc8_, xcc_, xd0_, xd4_, xf0_grenadeNumBounces, xf4_, xf6_}; + } + [[nodiscard]] SGrenadeLauncherData GetGrenadeLauncherData() const { + return {GetBouncyGrenadeData(), xa4_, x9c_, xa0_, xe0_trajectoryInfo}; + } }; class CElitePirate : public CPatterned { +private: + struct SUnknownStruct { + private: + float x0_; + rstl::reserved_vector x4_; + + public: + explicit SUnknownStruct(float f) : x0_(f * f) {} + zeus::CVector3f GetValue(const zeus::CVector3f& v1, const zeus::CVector3f& v2); + void AddValue(const zeus::CVector3f& vec); + void Clear() { x4_.clear(); } + }; + + enum class EState { + Invalid = -1, + Zero = 0, + One = 1, + Two = 2, + Over = 3, + }; + + EState x568_state = EState::Invalid; + CDamageVulnerability x56c_vulnerability; + std::unique_ptr x5d4_collisionActorMgr; + CElitePirateData x5d8_data; + CBoneTracking x6f8_boneTracking; + std::unique_ptr x730_collisionActorMgrHead; + // s32 x734_; + CCollidableAABox x738_collisionAabb; + std::optional> x760_energyAbsorbDesc; + TUniqueId x770_collisionHeadId = kInvalidUniqueId; + TUniqueId x772_launcherId = kInvalidUniqueId; + rstl::reserved_vector x774_collisionRJointIds; + rstl::reserved_vector x788_collisionLJointIds; + TUniqueId x79c_ = kInvalidUniqueId; + float x7a0_initialSpeed; + float x7a4_steeringSpeed = 1.f; + float x7a8_pathShaggedTime = 0.f; + float x7ac_energyAbsorbCooldown = 0.f; + float x7b0_ = 1.f; + float x7b4_hp = 0.f; + float x7b8_attackTimer = 0.f; + float x7bc_tauntTimer = 0.f; + float x7c0_shotAtTimer = 0.f; + float x7c4_absorbUpdateTimer = 0.f; + s32 x7c8_currAnimId = -1; + u32 x7cc_activeMaterialSet = 0; + CPathFindSearch x7d0_pathFindSearch; + zeus::CVector3f x8b4_targetDestPos; + SUnknownStruct x8c0_; + bool x988_24_damageOn : 1; + bool x988_25_attackingRightClaw : 1; + bool x988_26_attackingLeftClaw : 1; + bool x988_27_shotAt : 1; + bool x988_28_alert : 1; + bool x988_29_shockWaveAnim : 1; + bool x988_30_calledForBackup : 1; + bool x988_31_running : 1; + bool x989_24_onPath : 1; + public: DEFINE_PATTERNED(ElitePirate) - CElitePirate(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, - const CPatternedInfo&, const CActorParameters&, const CElitePirateData&); + CElitePirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, + CElitePirateData data); + + void Accept(IVisitor& visitor) override; + void Think(float dt, CStateManager& mgr) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; + const CDamageVulnerability* GetDamageVulnerability() const override; + const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir, + const CDamageInfo& dInfo) const override; + zeus::CVector3f GetOrbitPosition(const CStateManager& mgr) const override; + zeus::CVector3f GetAimPosition(const CStateManager& mgr, float) const override; + void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; + const CCollisionPrimitive* GetCollisionPrimitive() const override; + void KnockBack(const zeus::CVector3f&, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, + bool inDeferred, float magnitude) override; + void TakeDamage(const zeus::CVector3f&, float arg) override; + void Patrol(CStateManager& mgr, EStateMsg msg, float dt) override; + void PathFind(CStateManager& mgr, EStateMsg msg, float dt) override; + void TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) override; + void Halt(CStateManager& mgr, EStateMsg msg, float dt) override; + void Run(CStateManager& mgr, EStateMsg msg, float dt) override; + void Generate(CStateManager& mgr, EStateMsg msg, float dt) override; + void Attack(CStateManager& mgr, EStateMsg msg, float dt) override; + void Taunt(CStateManager& mgr, EStateMsg msg, float dt) override; + void ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) override; + void Cover(CStateManager& mgr, EStateMsg msg, float dt) override; + void SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) override; + void CallForBackup(CStateManager& mgr, EStateMsg msg, float dt) override; + bool TooClose(CStateManager& mgr, float arg) override; + bool InDetectionRange(CStateManager& mgr, float arg) override; + bool SpotPlayer(CStateManager& mgr, float arg) override; + bool AnimOver(CStateManager& mgr, float arg) override; + bool ShouldAttack(CStateManager& mgr, float arg) override; + bool InPosition(CStateManager& mgr, float arg) override; + bool ShouldTurn(CStateManager& mgr, float arg) override; + bool AggressionCheck(CStateManager& mgr, float arg) override; + bool ShouldTaunt(CStateManager& mgr, float arg) override; + bool ShouldFire(CStateManager& mgr, float arg) override; + bool ShotAt(CStateManager& mgr, float arg) override; + bool ShouldSpecialAttack(CStateManager& mgr, float arg) override; + bool ShouldCallForBackup(CStateManager& mgr, float arg) override; + CPathFindSearch* GetSearchPath() override; + virtual bool HasWeakPointHead() const { return true; } + virtual bool IsElitePirate() const { return true; } + virtual void SetupHealthInfo(CStateManager& mgr); + virtual void SetLaunchersActive(CStateManager& mgr, bool val); + virtual SShockWaveData GetShockWaveData() const { + return {x5d8_data.GetXF8(), x5d8_data.GetXFC(), x5d8_data.GetX118(), x5d8_data.GetX11C()}; + } + +private: + void SetupPathFindSearch(); + void SetShotAt(bool val, CStateManager& mgr); + bool IsArmClawCollider(TUniqueId uid, const rstl::reserved_vector& vec) const; + void AddSphereCollisionList(const SSphereJointInfo* joints, size_t count, + std::vector& outJoints) const; + void AddCollisionList(const SJointInfo* joints, size_t count, + std::vector& outJoints) const; + void SetupCollisionManager(CStateManager& mgr); + void SetupCollisionActorInfo(CStateManager& mgr); + bool IsArmClawCollider(std::string_view name, std::string_view locator, const SJointInfo* info, + size_t infoCount) const; + void CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid); + void ApplyDamageToHead(CStateManager& mgr, TUniqueId uid); + void CreateEnergyAbsorb(CStateManager& mgr, const zeus::CTransform& xf); + void SetupLauncherHealthInfo(CStateManager& mgr, TUniqueId uid); + void SetLauncherActive(CStateManager& mgr, bool val, TUniqueId uid); + zeus::CVector3f GetLockOnPosition(const CActor* actor) const; + bool CanKnockBack(const CDamageInfo& info) const; + void UpdateDestPos(CStateManager& mgr); + void CheckAttackChance(CStateManager& mgr); + void AttractProjectiles(CStateManager& mgr); + void UpdateAbsorbBodyState(CStateManager& mgr, float dt); + bool IsAttractingEnergy() const; + void UpdateTimers(float dt); + void UpdatePositionHistory(); + void UpdateActorTransform(CStateManager& mgr, TUniqueId& uid, std::string_view name); + void UpdateHealthInfo(CStateManager& mgr); + void ExtendTouchBounds(const CStateManager& mgr, const rstl::reserved_vector& uids, + const zeus::CVector3f& vec) const; + bool ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcherId); + bool ShouldCallForBackupFromLauncher(const CStateManager& mgr, TUniqueId uid) const; + bool IsClosestEnergyAttractor(const CStateManager& mgr, const rstl::reserved_vector& charNearList, + const zeus::CVector3f& projectilePos) const; }; -} // namespace urde::MP1 \ No newline at end of file +} // namespace urde diff --git a/Runtime/MP1/World/CFireFlea.cpp b/Runtime/MP1/World/CFireFlea.cpp index 2c74ac525..6171fc72d 100644 --- a/Runtime/MP1/World/CFireFlea.cpp +++ b/Runtime/MP1/World/CFireFlea.cpp @@ -8,11 +8,13 @@ #include "TCastTo.hpp" // Generated file, do not modify include path namespace urde::MP1 { +namespace { +constexpr zeus::CColor skEndFadeColor{1.f, 1.f, 0.5f, 1.f}; +constexpr zeus::CColor skStartFadeColor{1.f, 0.f, 0.f, 0.f}; +} // Anonymous namespace // region Fire Flea Death Camera -const zeus::CColor CFireFlea::CDeathCameraEffect::skEndFadeColor{1.f, 1.f, 0.5f, 1.f}; -const zeus::CColor CFireFlea::CDeathCameraEffect::skStartFadeColor{1.f, 0.f, 0.f, 0.f}; zeus::CColor CFireFlea::CDeathCameraEffect::sCurrentFadeColor = zeus::skClear; CFireFlea::CDeathCameraEffect::CDeathCameraEffect(TUniqueId uid, TAreaId areaId, std::string_view name) @@ -127,45 +129,46 @@ void CFireFlea::TargetPatrol(CStateManager& mgr, EStateMsg msg, float arg) { } zeus::CVector3f CFireFlea::FindSafeRoute(CStateManager& mgr, const zeus::CVector3f& forward) { - float mag = forward.magnitude(); - if (mag > 0.f) { - CRayCastResult res = mgr.RayStaticIntersection(GetTranslation(), forward.normalized(), 1.f, - CMaterialFilter::MakeInclude({EMaterialTypes::Solid})); - if (res.IsValid() || CheckNearWater(mgr, forward.normalized())) { - zeus::CVector3f right = forward.normalized().cross(zeus::skUp).normalized(); - CRayCastResult res1 = mgr.RayStaticIntersection(GetTranslation(), right, 1.f, - CMaterialFilter::MakeInclude({EMaterialTypes::Solid})); - if (res1.IsValid()) { - zeus::CVector3f left = -right; - CRayCastResult res2 = mgr.RayStaticIntersection(GetTranslation(), left, 1.f, - CMaterialFilter::MakeInclude({EMaterialTypes::Solid})); - if (res2.IsValid()) { - zeus::CVector3f up = right.cross(forward.normalized()); - CRayCastResult res3 = mgr.RayStaticIntersection(GetTranslation(), up, 1.f, - CMaterialFilter::MakeInclude({EMaterialTypes::Solid})); - if (res3.IsValid()) { - zeus::CVector3f down = -up; - CRayCastResult res4 = mgr.RayStaticIntersection(GetTranslation(), down, 1.f, - CMaterialFilter::MakeInclude({EMaterialTypes::Solid})); - if (res4.IsInvalid()) { - return mag * down; - } else { - return -forward; - } - } else { - return mag * up; - } - } else { - return mag * left; - } - } else { - return mag * right; - } - } else { - return forward; - } + const float mag = forward.magnitude(); + if (mag <= 0.f) { + return {}; } - return {}; + + const CRayCastResult res = mgr.RayStaticIntersection(GetTranslation(), forward.normalized(), 1.f, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid})); + if (res.IsInvalid() && !CheckNearWater(mgr, forward.normalized())) { + return forward; + } + + const zeus::CVector3f right = forward.normalized().cross(zeus::skUp).normalized(); + const CRayCastResult res1 = + mgr.RayStaticIntersection(GetTranslation(), right, 1.f, CMaterialFilter::MakeInclude({EMaterialTypes::Solid})); + if (res1.IsInvalid()) { + return mag * right; + } + + const zeus::CVector3f left = -right; + const CRayCastResult res2 = + mgr.RayStaticIntersection(GetTranslation(), left, 1.f, CMaterialFilter::MakeInclude({EMaterialTypes::Solid})); + if (res2.IsInvalid()) { + return mag * left; + } + + const zeus::CVector3f up = right.cross(forward.normalized()); + const CRayCastResult res3 = + mgr.RayStaticIntersection(GetTranslation(), up, 1.f, CMaterialFilter::MakeInclude({EMaterialTypes::Solid})); + if (res3.IsInvalid()) { + return mag * up; + } + + const zeus::CVector3f down = -up; + const CRayCastResult res4 = + mgr.RayStaticIntersection(GetTranslation(), down, 1.f, CMaterialFilter::MakeInclude({EMaterialTypes::Solid})); + if (res4.IsInvalid()) { + return mag * down; + } + + return -forward; } bool CFireFlea::CheckNearWater(const CStateManager& mgr, const zeus::CVector3f& dir) { diff --git a/Runtime/MP1/World/CFireFlea.hpp b/Runtime/MP1/World/CFireFlea.hpp index cd6a3dc70..ef9020ebc 100644 --- a/Runtime/MP1/World/CFireFlea.hpp +++ b/Runtime/MP1/World/CFireFlea.hpp @@ -18,8 +18,6 @@ class CFireFlea : public CPatterned { u32 x44_ = 0; public: - static const zeus::CColor skStartFadeColor; - static const zeus::CColor skEndFadeColor; static zeus::CColor sCurrentFadeColor; CDeathCameraEffect(TUniqueId, TAreaId, std::string_view); diff --git a/Runtime/MP1/World/CFlaahgra.cpp b/Runtime/MP1/World/CFlaahgra.cpp index 1ca620638..bc707b59c 100644 --- a/Runtime/MP1/World/CFlaahgra.cpp +++ b/Runtime/MP1/World/CFlaahgra.cpp @@ -56,11 +56,11 @@ CFlaahgraRenderer::CFlaahgraRenderer(TUniqueId uid, TUniqueId owner, std::string CActorParameters::None(), kInvalidUniqueId) , xe8_owner(owner) {} -void CFlaahgraRenderer::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { - +void CFlaahgraRenderer::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { if (const CActor* act = static_cast(mgr.GetObjectById(xe8_owner))) { - if (act->HasModelData() && (act->GetModelData()->HasAnimData() || act->GetModelData()->HasNormalModel())) + if (act->HasModelData() && (act->GetModelData()->HasAnimData() || act->GetModelData()->HasNormalModel())) { act->GetModelData()->RenderParticles(frustum); + } } } void CFlaahgraRenderer::Accept(IVisitor& visitor) { visitor.Visit(this); } @@ -254,14 +254,16 @@ void CFlaahgra::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateM CPatterned::AcceptScriptMsg(msg, uid, mgr); } -void CFlaahgra::AddToRenderer(const zeus::CFrustum& frustum, const urde::CStateManager& mgr) const { - if ((!GetModelData()->HasAnimData() && !GetModelData()->HasNormalModel()) || xe4_30_outOfFrustum) +void CFlaahgra::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { + if ((!GetModelData()->HasAnimData() && !GetModelData()->HasNormalModel()) || xe4_30_outOfFrustum) { return; + } - if (CanRenderUnsorted(mgr)) + if (CanRenderUnsorted(mgr)) { Render(mgr); - else + } else { EnsureRendered(mgr); + } } void CFlaahgra::Death(CStateManager& mgr, const zeus::CVector3f& dir, EScriptObjectState state) { @@ -785,7 +787,7 @@ void CFlaahgra::Growth(CStateManager& mgr, EStateMsg msg, float arg) { UpdateScale((x7c4_ > 0.f ? 1.f - (GetEndActionTime() / x7c4_) : 1.f), x81c_, x56c_.x4_); } - x450_bodyController->GetCommandMgr().SetTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); + x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); } } else if (msg == EStateMsg::Deactivate) { UpdateScale(1.f, x81c_, x56c_.x4_); @@ -983,7 +985,7 @@ void CFlaahgra::Attack(CStateManager& mgr, EStateMsg msg, float arg) { if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::MeleeAttack) x568_ = 4; else - x450_bodyController->GetCommandMgr().SetTargetVector(x78c_); + x450_bodyController->GetCommandMgr().DeliverTargetVector(x78c_); } } else if (msg == EStateMsg::Deactivate) { SetCollisionActorBounds(mgr, x79c_leftArmCollision, {}); @@ -1100,7 +1102,7 @@ void CFlaahgra::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float) { if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::ProjectileAttack) { x568_ = 4; } else { - x450_bodyController->GetCommandMgr().SetTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); + x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); } } } @@ -1135,7 +1137,7 @@ void CFlaahgra::Cover(CStateManager& mgr, EStateMsg msg, float) { if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::MeleeAttack) x568_ = 4; else if (TCastToConstPtr wp = mgr.GetObjectById(x77c_)) { - x450_bodyController->GetCommandMgr().SetTargetVector(wp->GetTranslation() - GetTranslation()); + x450_bodyController->GetCommandMgr().DeliverTargetVector(wp->GetTranslation() - GetTranslation()); } } } else if (msg == EStateMsg::Deactivate) { @@ -1270,7 +1272,7 @@ void CFlaahgraPlants::Think(float dt, CStateManager& mgr) { mgr.FreeScriptObject(GetUniqueId()); } -void CFlaahgraPlants::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { +void CFlaahgraPlants::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { g_Renderer->AddParticleGen(*xe8_elementGen.get()); CActor::AddToRenderer(frustum, mgr); } diff --git a/Runtime/MP1/World/CFlaahgra.hpp b/Runtime/MP1/World/CFlaahgra.hpp index 37c95062c..b8f0e32d0 100644 --- a/Runtime/MP1/World/CFlaahgra.hpp +++ b/Runtime/MP1/World/CFlaahgra.hpp @@ -4,6 +4,7 @@ #include #include +#include "Runtime/CDependencyGroup.hpp" #include "Runtime/rstl.hpp" #include "Runtime/Collision/CJointCollisionDescription.hpp" #include "Runtime/Weapon/CProjectileInfo.hpp" @@ -47,7 +48,7 @@ class CFlaahgraData { public: static constexpr u32 GetNumProperties() { return 23; } - CFlaahgraData(CInputStream&); + explicit CFlaahgraData(CInputStream&); const CAnimationParameters& GetAnimationParameters() const { return x14c_animationParameters; } }; @@ -58,7 +59,7 @@ class CFlaahgraRenderer : public CActor { public: CFlaahgraRenderer(TUniqueId, TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&); - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; void Accept(IVisitor&) override; std::optional GetTouchBounds() const override { return {}; } }; @@ -79,7 +80,7 @@ public: void Accept(IVisitor&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float, CStateManager&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; std::optional GetTouchBounds() const override { return x110_aabox; } void Touch(CActor&, CStateManager&) override; }; @@ -199,7 +200,7 @@ public: void Think(float, CStateManager&) override; void PreThink(float, CStateManager&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; bool CanRenderUnsorted(const CStateManager&) const override { return true; } zeus::CVector3f GetAimPosition(const CStateManager&, float) const override { return x820_; } void Death(CStateManager&, const zeus::CVector3f&, EScriptObjectState) override; diff --git a/Runtime/MP1/World/CFlaahgraTentacle.cpp b/Runtime/MP1/World/CFlaahgraTentacle.cpp index fcd97f228..7004b05f5 100644 --- a/Runtime/MP1/World/CFlaahgraTentacle.cpp +++ b/Runtime/MP1/World/CFlaahgraTentacle.cpp @@ -1,5 +1,7 @@ #include "Runtime/MP1/World/CFlaahgraTentacle.hpp" +#include + #include "Runtime/CStateManager.hpp" #include "Runtime/Collision/CCollisionActor.hpp" #include "Runtime/World/CPlayer.hpp" @@ -8,6 +10,15 @@ #include "TCastTo.hpp" // Generated file, do not modify include path namespace urde::MP1 { +namespace { +constexpr std::string_view skpTentacleTip = "Arm_12"sv; +constexpr std::array skJointList{{ + {"Arm_8", 2.f}, + {"Arm_10", 1.2f}, + {"Arm_12", 1.2f}, +}}; +} // Anonymous namespace + CFlaahgraTentacle::CFlaahgraTentacle(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms) @@ -28,13 +39,13 @@ void CFlaahgraTentacle::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, } case EScriptObjectMessage::Deleted: { x56c_collisionManager->Destroy(mgr); - if (TCastToPtr trigger = mgr.ObjectById(x58c_triggerId)) { + if (const TCastToPtr trigger = mgr.ObjectById(x58c_triggerId)) { trigger->SetForceVector(x580_forceVector); } break; } case EScriptObjectMessage::Touched: { - if (TCastToConstPtr colAct = mgr.GetObjectById(uid)) { + if (const TCastToConstPtr colAct = mgr.GetObjectById(uid)) { if (colAct->GetLastTouchedObject() == mgr.GetPlayer().GetUniqueId() && x420_curDamageRemTime <= 0.f) { mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), GetUniqueId(), GetContactDamage(), CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {}); @@ -71,24 +82,27 @@ void CFlaahgraTentacle::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, } void CFlaahgraTentacle::Think(float dt, CStateManager& mgr) { - if (!GetActive()) + if (!GetActive()) { return; + } CPatterned::Think(dt, mgr); x56c_collisionManager->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); - if (x574_ > 0.f) + if (x574_ > 0.f) { x574_ -= dt; + } - if (x578_ > 0.f) + if (x578_ > 0.f) { x578_ -= dt; + } } -void CFlaahgraTentacle::AddSphereCollisionList(const SSphereJointInfo* sphereJoints, s32 jointCount, +void CFlaahgraTentacle::AddSphereCollisionList(const SSphereJointInfo* sphereJoints, size_t jointCount, std::vector& outJoints) { const CAnimData* animData = GetModelData()->GetAnimationData(); - for (s32 i = 0; i < jointCount; ++i) { + for (size_t i = 0; i < jointCount; ++i) { const SSphereJointInfo& sphereJoint = sphereJoints[i]; const CSegId segId = animData->GetLocatorSegId(sphereJoint.name); @@ -100,17 +114,15 @@ void CFlaahgraTentacle::AddSphereCollisionList(const SSphereJointInfo* sphereJoi } } -const SSphereJointInfo CFlaahgraTentacle::skJointList[3] = {{"Arm_8", 2.f}, {"Arm_10", 1.2f}, {"Arm_12", 1.2f}}; - void CFlaahgraTentacle::SetupCollisionManager(CStateManager& mgr) { std::vector jointList; - AddSphereCollisionList(skJointList, 3, jointList); + AddSphereCollisionList(skJointList.data(), skJointList.size(), jointList); x56c_collisionManager = std::make_unique(mgr, GetUniqueId(), GetAreaIdAlways(), jointList, true); for (u32 i = 0; i < x56c_collisionManager->GetNumCollisionActors(); ++i) { const CJointCollisionDescription& desc = x56c_collisionManager->GetCollisionDescFromIndex(i); - if (TCastToPtr colAct = mgr.ObjectById(desc.GetCollisionActorId())) { + if (const TCastToPtr colAct = mgr.ObjectById(desc.GetCollisionActorId())) { colAct->SetMaterialFilter(CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Player}, {EMaterialTypes::Character, EMaterialTypes::CollisionActor, @@ -119,8 +131,9 @@ void CFlaahgraTentacle::SetupCollisionManager(CStateManager& mgr) { colAct->AddMaterial(EMaterialTypes::ScanPassthrough); colAct->SetDamageVulnerability(*GetDamageVulnerability()); - if (x57c_tentacleTipAct == kInvalidUniqueId && desc.GetName() == skpTentacleTip) + if (x57c_tentacleTipAct == kInvalidUniqueId && desc.GetName() == skpTentacleTip) { x57c_tentacleTipAct = desc.GetCollisionActorId(); + } } } @@ -129,35 +142,38 @@ void CFlaahgraTentacle::SetupCollisionManager(CStateManager& mgr) { } zeus::CVector3f CFlaahgraTentacle::GetAimPosition(const CStateManager& mgr, float dt) const { - if (TCastToConstPtr colAct = mgr.GetObjectById(x57c_tentacleTipAct)) + if (const TCastToConstPtr colAct = mgr.GetObjectById(x57c_tentacleTipAct)) { return colAct->GetTranslation(); + } return CPatterned::GetAimPosition(mgr, dt); } void CFlaahgraTentacle::ExtractTentacle(CStateManager& mgr) { - if (!Inside(mgr, 0.f)) + if (!Inside(mgr, 0.f)) { return; + } x58e_24_ = true; - if (TCastToPtr trigger = mgr.ObjectById(x58c_triggerId)) { + if (const TCastToPtr trigger = mgr.ObjectById(x58c_triggerId)) { trigger->SetForceVector(x580_forceVector); } } void CFlaahgraTentacle::RetractTentacle(CStateManager& mgr) { x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch); - if (TCastToPtr trigger = mgr.ObjectById(x58c_triggerId)) { + if (const TCastToPtr trigger = mgr.ObjectById(x58c_triggerId)) { trigger->SetForceVector({}); } } void CFlaahgraTentacle::SaveBombSlotInfo(CStateManager& mgr) { for (const SConnection& conn : GetConnectionList()) { - if (conn.x0_state != EScriptObjectState::Modify || conn.x4_msg != EScriptObjectMessage::ToggleActive) + if (conn.x0_state != EScriptObjectState::Modify || conn.x4_msg != EScriptObjectMessage::ToggleActive) { continue; + } - TUniqueId uid = mgr.GetIdForScript(conn.x8_objId); - if (TCastToConstPtr trigger = mgr.GetObjectById(uid)) { + const TUniqueId uid = mgr.GetIdForScript(conn.x8_objId); + if (const TCastToConstPtr trigger = mgr.GetObjectById(uid)) { x58c_triggerId = uid; x580_forceVector = trigger->GetForceVector(); return; @@ -166,14 +182,16 @@ void CFlaahgraTentacle::SaveBombSlotInfo(CStateManager& mgr) { } bool CFlaahgraTentacle::ShouldAttack(CStateManager& mgr, float) { - if (x578_ > 0.f) - return true; + if (x578_ > 0.f) { + return true; + } - if (x574_ > 0.f || mgr.GetPlayer().IsInWaterMovement()) + if (x574_ > 0.f || mgr.GetPlayer().IsInWaterMovement()) { return false; + } - if (TCastToConstPtr colAct = mgr.GetObjectById(x57c_tentacleTipAct)) { - float mag = (colAct->GetTranslation().toVec2f() - mgr.GetPlayer().GetTranslation().toVec2f()).magSquared(); + if (const TCastToConstPtr colAct = mgr.GetObjectById(x57c_tentacleTipAct)) { + const float mag = (colAct->GetTranslation().toVec2f() - mgr.GetPlayer().GetTranslation().toVec2f()).magSquared(); return mag >= (x2fc_minAttackRange * x2fc_minAttackRange) && mag <= (x300_maxAttackRange * x300_maxAttackRange); } @@ -185,11 +203,12 @@ void CFlaahgraTentacle::Attack(CStateManager& mgr, EStateMsg msg, float) { x568_ = 0; } else if (msg == EStateMsg::Update) { if (x568_ == 0) { - if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::MeleeAttack) + if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::MeleeAttack) { x568_ = 2; - else + } else { x450_bodyController->GetCommandMgr().DeliverCmd( CBCMeleeAttackCmd((x578_ > 0.f ? pas::ESeverity::Zero : pas::ESeverity::One), {})); + } } else if (x568_ == 2 && x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::MeleeAttack) { x568_ = 3; @@ -202,15 +221,18 @@ void CFlaahgraTentacle::Attack(CStateManager& mgr, EStateMsg msg, float) { } void CFlaahgraTentacle::Retreat(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Update) { - if (!x58e_24_) + if (!x58e_24_) { return; + } - if (x330_stateMachineState.GetTime() <= 1.f) + if (x330_stateMachineState.GetTime() <= 1.f) { return; + } - if (TCastToPtr trigger = mgr.ObjectById(x58c_triggerId)) { - if (trigger->IsPlayerTriggerProc()) + if (const TCastToConstPtr trigger = mgr.ObjectById(x58c_triggerId)) { + if (trigger->IsPlayerTriggerProc()) { x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + } } } else if (msg == EStateMsg::Deactivate) { x58e_24_ = false; @@ -220,16 +242,18 @@ void CFlaahgraTentacle::InActive(CStateManager& mgr, EStateMsg msg, float arg) { if (msg == EStateMsg::Activate) { x570_ = 0.f; } else if (msg == EStateMsg::Update) { - if (Inside(mgr, 0.f)) + if (Inside(mgr, 0.f)) { return; + } - if (TCastToPtr trigger = mgr.ObjectById(x58c_triggerId)) { + if (const TCastToConstPtr trigger = mgr.ObjectById(x58c_triggerId)) { if (trigger->IsPlayerTriggerProc()) { if (x570_ > 1.f) { RetractTentacle(mgr); ExtractTentacle(mgr); - } else + } else { x570_ += arg; + } } } } diff --git a/Runtime/MP1/World/CFlaahgraTentacle.hpp b/Runtime/MP1/World/CFlaahgraTentacle.hpp index 0308120b5..5c55392aa 100644 --- a/Runtime/MP1/World/CFlaahgraTentacle.hpp +++ b/Runtime/MP1/World/CFlaahgraTentacle.hpp @@ -11,8 +11,6 @@ namespace urde::MP1 { class CFlaahgraTentacle : public CPatterned { - static const SSphereJointInfo skJointList[3]; - static constexpr std::string_view skpTentacleTip = "Arm_12"sv; s32 x568_ = -1; std::unique_ptr x56c_collisionManager; float x570_ = 0.f; @@ -23,7 +21,8 @@ class CFlaahgraTentacle : public CPatterned { TUniqueId x58c_triggerId = kInvalidUniqueId; bool x58e_24_ : 1; - void AddSphereCollisionList(const SSphereJointInfo*, s32, std::vector&); + void AddSphereCollisionList(const SSphereJointInfo* sphereJoints, size_t jointCount, + std::vector& outJoints); void SetupCollisionManager(CStateManager&); void ExtractTentacle(CStateManager&); void RetractTentacle(CStateManager&); diff --git a/Runtime/MP1/World/CFlickerBat.cpp b/Runtime/MP1/World/CFlickerBat.cpp index 1ef1a2f24..6fc2c5696 100644 --- a/Runtime/MP1/World/CFlickerBat.cpp +++ b/Runtime/MP1/World/CFlickerBat.cpp @@ -96,7 +96,7 @@ void CFlickerBat::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); } -void CFlickerBat::Render(const CStateManager& mgr) const { +void CFlickerBat::Render(CStateManager& mgr) { if (!x580_24_wasInXray && x580_26_inLOS && (GetFlickerBatState() == EFlickerBatState::FadeIn || GetFlickerBatState() == EFlickerBatState::FadeOut)) { float strength = 0.f; diff --git a/Runtime/MP1/World/CFlickerBat.hpp b/Runtime/MP1/World/CFlickerBat.hpp index eb6d864a3..729bb9835 100644 --- a/Runtime/MP1/World/CFlickerBat.hpp +++ b/Runtime/MP1/World/CFlickerBat.hpp @@ -31,7 +31,7 @@ public: void Accept(IVisitor&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float, CStateManager&) override; - void Render(const CStateManager&) const override; + void Render(CStateManager&) override; void Touch(CActor&, CStateManager&) override; void DoUserAnimEvent(CStateManager&, const CInt32POINode&, EUserEventType, float dt) override; void Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) override; diff --git a/Runtime/MP1/World/CFlyingPirate.cpp b/Runtime/MP1/World/CFlyingPirate.cpp index 815a59883..6a561f026 100644 --- a/Runtime/MP1/World/CFlyingPirate.cpp +++ b/Runtime/MP1/World/CFlyingPirate.cpp @@ -1,10 +1,1727 @@ #include "Runtime/MP1/World/CFlyingPirate.hpp" +#include "Runtime/Character/CPASAnimParmData.hpp" +#include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/MP1/World/CSpacePirate.hpp" +#include "Runtime/Weapon/CEnergyProjectile.hpp" +#include "Runtime/Weapon/CGameProjectile.hpp" +#include "Runtime/World/CExplosion.hpp" +#include "Runtime/World/CPatternedInfo.hpp" +#include "Runtime/World/CPlayer.hpp" +#include "Runtime/World/CScriptCoverPoint.hpp" +#include "Runtime/World/CScriptWater.hpp" +#include "Runtime/World/CScriptWaypoint.hpp" +#include "Runtime/World/CTeamAiMgr.hpp" +#include "Runtime/World/CWorld.hpp" + +#include + namespace urde::MP1 { +namespace { +constexpr std::array skBurstsFlying{{ + {4, {3, 4, 11, 12, -1, 0, 0, 0}, 0.1f, 0.05f}, + {20, {2, 3, 4, 5, -1, 0, 0, 0}, 0.1f, 0.05f}, + {20, {10, 11, 12, 13, -1, 0, 0, 0}, 0.1f, 0.05f}, + {25, {15, 16, 1, 2, -1, 0, 0, 0}, 0.1f, 0.05f}, + {25, {5, 6, 7, 8, -1, 0, 0, 0}, 0.1f, 0.05f}, + {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000}, +}}; + +constexpr std::array skBurstsFlyingOutOfView{{ + {5, {3, 4, 8, 12, -1, 0, 0, 0}, 0.1f, 0.05f}, + {10, {2, 3, 4, 5, -1, 0, 0, 0}, 0.1f, 0.05f}, + {10, {10, 11, 12, 13, -1, 0, 0, 0}, 0.1f, 0.05f}, + {40, {15, 16, 1, 2, -1, 0, 0, 0}, 0.1f, 0.05f}, + {35, {5, 6, 7, 8, -1, 0, 0, 0}, 0.1f, 0.05f}, + {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000}, +}}; + +constexpr std::array skBurstsLanded{{ + {30, {3, 4, 5, 11, 12, 4, -1, 0}, 0.1f, 0.05f}, + {20, {2, 3, 4, 5, 4, 3, -1, 0}, 0.1f, 0.05f}, + {20, {5, 4, 3, 13, 12, 11, -1, 0}, 0.1f, 0.05f}, + {30, {1, 2, 3, 4, 5, 6, -1, 0}, 0.1f, 0.05f}, + {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000}, +}}; + +constexpr std::array skBurstsLandedOutOfView{{ + {10, {6, 5, 4, 14, 13, 12, -1, 0}, 0.1f, 0.05f}, + {20, {14, 13, 12, 11, 10, 9, -1, 0}, 0.1f, 0.05f}, + {20, {14, 15, 16, 11, 10, 9, -1, 0}, 0.1f, 0.05f}, + {50, {11, 10, 9, 8, 7, 6, -1, 0}, 0.1f, 0.05f}, + {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000}, +}}; + +constexpr std::array skBursts{ + skBurstsFlying.data(), + skBurstsFlyingOutOfView.data(), + skBurstsLanded.data(), + skBurstsLandedOutOfView.data(), + nullptr, +}; + +constexpr std::array skParts{ + "Collar"sv, "Head_1"sv, "R_shoulder"sv, "R_elbow"sv, "R_wrist"sv, "L_shoulder"sv, "L_elbow"sv, "L_wrist"sv, + "R_hip"sv, "R_knee"sv, "R_ankle"sv, "L_hip"sv, "L_knee"sv, "L_ankle"sv, "rocket_LCTR"sv, +}; + +constexpr std::array skRadii{ + 0.45f, 0.52f, 0.35f, 0.1f, 0.15f, 0.35f, 0.1f, 0.15f, 0.15f, 0.15f, 0.15f, 0.15f, 0.15f, 0.15f, 0.35f, +}; +} // namespace + +CFlyingPirate::CFlyingPirateData::CFlyingPirateData(CInputStream& in, u32 propCount) +: x0_maxCoverDistance(in.readFloatBig()) +, x4_hearingDistance(in.readFloatBig()) +, x8_type(EFlyingPirateType(in.readUint32Big())) +, xc_gunProjectileInfo(in) +, x34_gunSfx(CSfxManager::TranslateSFXID(in.readUint32Big())) +, x38_altProjectileInfo1(in) +, x60_altProjectileInfo2(CAssetId(in), {}) +, x88_knockBackDelay(in.readFloatBig()) +, x8c_flyingHeight(in.readFloatBig()) +, x90_particleGenDesc(g_SimplePool->GetObj({SBIG('PART'), CAssetId(in)})) +, x9c_dInfo(in) +, xb8_(in.readFloatBig()) +, xbc_(in.readFloatBig()) +, xc0_(in.readFloatBig()) +, xc4_(in.readFloatBig()) +, xc8_ragDollSfx1(CSfxManager::TranslateSFXID(in.readUint32Big())) +, xca_ragDollSfx2(CSfxManager::TranslateSFXID(in.readUint32Big())) +, xcc_coverCheckChance(in.readFloatBig()) +, xd0_(in.readFloatBig()) +, xd4_(in.readFloatBig()) +, xd8_particleGen1(in) +, xdc_particleGen2(in) +, xe0_particleGen3(in) +, xe4_knockBackSfx(CSfxManager::TranslateSFXID(in.readUint32Big())) +, xe6_deathSfx(CSfxManager::TranslateSFXID(in.readUint32Big())) +, xe8_aggressionChance(in.readFloatBig()) +, xec_(in.readFloatBig()) +, xf0_projectileHomingDistance(propCount < 36 ? 0.f : in.readFloatBig()) { + xc_gunProjectileInfo.Token().Lock(); + x38_altProjectileInfo1.Token().Lock(); + x60_altProjectileInfo2.Token().Lock(); +} + +CFlyingPirate::CFlyingPirateRagDoll::CFlyingPirateRagDoll(CStateManager& mgr, CFlyingPirate* actor, u16 w1, u16 w2) +: CRagDoll(-actor->GetGravityConstant(), 3.f, 8.f, 0) +, x6c_actor(actor) +, x88_sfx(w1) +, x9c_(w2) +, xa4_(actor->GetDestPos() - actor->GetTranslation()) +, xb0_24_(false) { + actor->RemoveMaterial(EMaterialTypes::Solid, EMaterialTypes::AIBlock, EMaterialTypes::GroundCollider, mgr); + actor->HealthInfo(mgr)->SetHP(-1.f); + SetNumParticles(skParts.size()); + SetNumLengthConstraints(45); + SetNumJointConstraints(4); + CModelData* modelData = actor->GetModelData(); + CAnimData* animData = modelData->GetAnimationData(); + const zeus::CVector3f& scale = modelData->GetScale(); + animData->BuildPose(); + const zeus::CVector3f& center = actor->GetBoundingBox().center(); + for (size_t i = 0; i < skParts.size(); ++i) { + const CSegId& id = animData->GetLocatorSegId(skParts[i]); + AddParticle(id, center, actor->GetTransform() * (scale * animData->GetPose().GetOffset(id)), + skRadii[i] * scale.z()); + } + SatisfyWorldConstraintsOnConstruction(mgr); + AddLengthConstraint(0, 1); + AddLengthConstraint(0, 2); + AddLengthConstraint(0, 8); + AddLengthConstraint(0, 11); + AddLengthConstraint(0, 5); + AddLengthConstraint(2, 3); + AddLengthConstraint(3, 4); + AddLengthConstraint(5, 6); + AddLengthConstraint(6, 7); + AddLengthConstraint(2, 5); + AddLengthConstraint(2, 8); + AddLengthConstraint(2, 11); + AddLengthConstraint(5, 8); + AddLengthConstraint(5, 11); + AddLengthConstraint(8, 11); + AddLengthConstraint(8, 9); + AddLengthConstraint(9, 10); + AddLengthConstraint(11, 12); + AddLengthConstraint(12, 13); + AddLengthConstraint(14, 0); + AddLengthConstraint(14, 2); + AddLengthConstraint(14, 5); + AddLengthConstraint(14, 8); + AddLengthConstraint(14, 11); + AddMinLengthConstraint(1, 8, x14_lengthConstraints[2].GetLength()); + AddMinLengthConstraint(1, 11, x14_lengthConstraints[3].GetLength()); + AddMinLengthConstraint(4, 2, x14_lengthConstraints[5].GetLength()); + AddMinLengthConstraint(7, 5, x14_lengthConstraints[7].GetLength()); + AddMinLengthConstraint(3, 5, 0.5f * x14_lengthConstraints[5].GetLength() + x14_lengthConstraints[9].GetLength()); + AddMinLengthConstraint(6, 2, 0.5f * x14_lengthConstraints[7].GetLength() + x14_lengthConstraints[9].GetLength()); + AddMinLengthConstraint(4, 5, 0.5f * x14_lengthConstraints[5].GetLength() + x14_lengthConstraints[9].GetLength()); + AddMinLengthConstraint(7, 2, 0.5f * x14_lengthConstraints[7].GetLength() + x14_lengthConstraints[9].GetLength()); + AddMinLengthConstraint(10, 8, x14_lengthConstraints[15].GetLength()); + AddMinLengthConstraint(13, 11, x14_lengthConstraints[17].GetLength()); + AddMinLengthConstraint(9, 2, 0.707f * x14_lengthConstraints[15].GetLength() + x14_lengthConstraints[10].GetLength()); + AddMinLengthConstraint(12, 5, 0.707f * x14_lengthConstraints[17].GetLength() + x14_lengthConstraints[13].GetLength()); + AddMinLengthConstraint(9, 11, x14_lengthConstraints[15].GetLength()); + AddMinLengthConstraint(12, 8, x14_lengthConstraints[17].GetLength()); + AddMinLengthConstraint(10, 0, x14_lengthConstraints[2].GetLength() + x14_lengthConstraints[15].GetLength()); + AddMinLengthConstraint(13, 0, x14_lengthConstraints[3].GetLength() + x14_lengthConstraints[17].GetLength()); + AddMinLengthConstraint(10, 13, x14_lengthConstraints[14].GetLength()); + AddMinLengthConstraint(9, 12, 0.5f * x14_lengthConstraints[14].GetLength()); + AddMinLengthConstraint(10, 12, 0.5f * x14_lengthConstraints[14].GetLength()); + AddMinLengthConstraint(13, 9, 0.5f * x14_lengthConstraints[14].GetLength()); + AddMinLengthConstraint(10, 13, 0.5f * x14_lengthConstraints[14].GetLength()); + AddJointConstraint(8, 2, 5, 8, 9, 10); + AddJointConstraint(11, 2, 5, 11, 12, 13); + AddJointConstraint(2, 11, 5, 2, 3, 4); + AddJointConstraint(5, 2, 8, 5, 6, 7); +} + +void CFlyingPirate::CFlyingPirateRagDoll::PreRender(const zeus::CVector3f& v, CModelData& mData) { + if (!x68_25_over) { + CAnimData* const animData = mData.GetAnimationData(); + const CCharLayoutInfo& layout = animData->GetCharLayoutInfo(); + CHierarchyPoseBuilder& poseBuilder = animData->PoseBuilder(); + for (const auto& id : layout.GetSegIdList().GetList()) { + if (layout.GetRootNode()->GetBoneMap()[id].x10_children.size() > 1) { + poseBuilder.GetTreeMap()[id].x4_rotation = zeus::CQuaternion(); + } + } + + CHierarchyPoseBuilder::CTreeNode& skeletonRoot = + poseBuilder.GetTreeMap()[animData->GetLocatorSegId("Skeleton_Root"sv)]; + const zeus::CVector3f& rHipPos = x4_particles[8].GetPosition(); // R_hip + const zeus::CVector3f& lHipPos = x4_particles[11].GetPosition(); // L_hip + const zeus::CVector3f& rShoulderPos = x4_particles[2].GetPosition(); // R_shoulder + const zeus::CVector3f& lShoulderPos = x4_particles[5].GetPosition(); // L_shoulder + const zeus::CVector3f& collarPos = x4_particles[0].GetPosition(); // Collar + skeletonRoot.x14_offset = (0.5f * (rHipPos + lHipPos) - v) / mData.GetScale(); + + const zeus::CVector3f& rootRight = rShoulderPos - lShoulderPos; + const zeus::CVector3f& rootUp = (collarPos - (rHipPos + lHipPos) * 0.5f).normalized(); + const zeus::CVector3f& rootFore = rootUp.cross(rootRight).normalized(); + const zeus::CQuaternion& rootRot = zeus::CMatrix3f(rootFore.cross(rootUp), rootFore, rootUp); + skeletonRoot.x4_rotation = rootRot; + + const CRagDollParticle& head = x4_particles[1]; // Head_1 + const zeus::CVector3f& headRestVec = layout.GetFromParentUnrotated(head.GetBone()); + poseBuilder.GetTreeMap()[head.GetBone()].x4_rotation = zeus::CQuaternion::shortestRotationArc( + headRestVec, rootRot.inverse().transform(head.GetPosition() - collarPos)); + + BoneAlign(poseBuilder, layout, 3, 4, rootRot * BoneAlign(poseBuilder, layout, 2, 3, rootRot)); + BoneAlign(poseBuilder, layout, 6, 7, rootRot * BoneAlign(poseBuilder, layout, 5, 6, rootRot)); + BoneAlign(poseBuilder, layout, 9, 10, rootRot * BoneAlign(poseBuilder, layout, 8, 9, rootRot)); + BoneAlign(poseBuilder, layout, 12, 13, rootRot * BoneAlign(poseBuilder, layout, 11, 12, rootRot)); + + animData->MarkPoseDirty(); + } +} + +void CFlyingPirate::CFlyingPirateRagDoll::Prime(CStateManager& mgr, const zeus::CTransform& xf, CModelData& mData) { + if (x6c_actor->x6a1_30_spinToDeath) { + xa0_ = CSfxManager::AddEmitter(x9c_, x6c_actor->GetTranslation(), zeus::skZero3f, true, true, 0x7f, kInvalidAreaId); + } + CRagDoll::Prime(mgr, xf, mData); +} + +void CFlyingPirate::CFlyingPirateRagDoll::Update(CStateManager& mgr, float dt, float waterTop) { + if (!x68_25_over) { + if (x6c_actor->x6a1_30_spinToDeath) { + x84_ -= dt; + const zeus::CVector3f& v9c = (x6c_actor->x2e0_destPos - x4_particles[14].GetPosition()).normalized(); + x74_ = zeus::CVector3f::slerp(x74_, v9c, zeus::degToRad(360.f * dt)); + x70_ = 25.f; + zeus::CVector3f mul = x70_ * x74_; + if (x84_ <= 0.f) { + x4_particles[14].Velocity() += 11.f * mul; + } else { + x4_particles[14].Velocity() += 25.f * mul; + } + zeus::CVector3f inv = -4 * mul; + x4_particles[4].Velocity() += -mul; + x4_particles[7].Velocity() += -mul; + x4_particles[10].Velocity() += inv; + x4_particles[10].Velocity() += inv; + x4_particles[1].Velocity() += -mul; + + x80_ = std::min(1000.f * dt + x80_, 1000.f); + + zeus::CVector3f vc0 = ((x4_particles[5].Position() - x4_particles[2].Position()) + .cross(x4_particles[8].Position() - x4_particles[2].Position()) + + 0.25f * (x4_particles[2].Position() - x4_particles[5].Position())) + .normalized() * + x80_; + x4_particles[2].Velocity() += vc0; + x4_particles[5].Velocity() += -vc0; + + x44_normalGravity = 0.f; + CSfxManager::UpdateEmitter(xa0_, x6c_actor->GetTranslation(), x58_averageVel, 1.f); + } + + // Collar-hips weighted center + zeus::CVector3f oldTorsoCenter = x4_particles[8].GetPosition() * 0.25f + x4_particles[11].GetPosition() * 0.25f + + x4_particles[0].GetPosition() * 0.5f; + oldTorsoCenter.z() = std::min({x4_particles[0].GetPosition().z() - x4_particles[0].GetRadius(), + x4_particles[8].GetPosition().z() - x4_particles[8].GetRadius(), + x4_particles[11].GetPosition().z() - x4_particles[11].GetRadius()}); + + CRagDoll::Update(mgr, dt, waterTop); + + // Collar-hips weighted center + zeus::CVector3f newTorsoCenter = x4_particles[8].GetPosition() * 0.25f + x4_particles[11].GetPosition() * 0.25f + + x4_particles[0].GetPosition() * 0.5f; + newTorsoCenter.z() = std::min({x4_particles[0].GetPosition().z() - x4_particles[0].GetRadius(), + x4_particles[8].GetPosition().z() - x4_particles[8].GetRadius(), + x4_particles[11].GetPosition().z() - x4_particles[11].GetRadius()}); + x6c_actor->SetTransform({zeus::CMatrix3f(false), newTorsoCenter}); + x6c_actor->SetVelocityWR((newTorsoCenter - oldTorsoCenter) * (1.f / dt)); + + if (x6c_actor->x6a1_30_spinToDeath) { + if ((newTorsoCenter - x6c_actor->GetDestPos()).magSquared() > 0.f) { + x6c_actor->x88c_ragDollTimer = 0.5f * dt; + } + } + + x8c_ -= dt; + if (x54_impactVel > 2.f && x8c_ < 0.f) { + if (xb0_24_ || (x6c_actor->GetTranslation() - x90_).magSquared() > 0.1f) { + float vol = std::min(10.f * x54_impactVel, 127.f) / 127.f; + CSfxManager::AddEmitter(x88_sfx, x6c_actor->GetTranslation(), zeus::skZero3f, vol, true, false, 0x7f, + kInvalidAreaId); + x8c_ = 0.222f * mgr.GetActiveRandom()->Float() + 0.222f; + xb0_24_ = false; + x90_ = x6c_actor->GetTranslation(); + } + } + } else { + x6c_actor->SetMomentumWR(zeus::skZero3f); + x6c_actor->Stop(); + } +} CFlyingPirate::CFlyingPirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo, CInputStream& in, u32 propCount) : CPatterned(ECharacter::FlyingPirate, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, - EMovementType::Flyer, EColliderType::One, EBodyType::NewFlyer, actParms, EKnockBackVariant::Medium) {} + EMovementType::Ground, EColliderType::One, EBodyType::NewFlyer, actParms, EKnockBackVariant::Medium) +, x568_data(in, propCount) +, x6a0_24_isFlyingPirate(x568_data.x8_type == EFlyingPirateType::FlyingPirate) +, x6a0_25_isAquaPirate(x568_data.x8_type == EFlyingPirateType::AquaPirate) +, x6a0_26_hearShot(false) +, x6a0_27_canPatrol(false) +, x6a0_28_(false) +, x6a0_29_checkForProjectiles(false) +, x6a0_30_(false) +, x6a0_31_canSeePlayer(true) +, x6a1_24_prevInCineCam(false) +, x6a1_25_(false) +, x6a1_26_isAttackingObject(false) +, x6a1_27_(false) +, x6a1_28_(false) +, x6a1_29_isMoving(false) +, x6a1_30_spinToDeath(false) +, x6a1_31_stopped(false) +, x6a2_24_aggressive(false) +, x6a2_25_aggressionChecked(false) +, x6a2_26_jetpackActive(false) +, x6a2_27_sparksActive(false) +, x6a2_28_(false) +, x6a8_pathFindSearch(nullptr, x6a0_25_isAquaPirate ? 2 : 3, pInfo.GetHalfExtent(), pInfo.GetHeight(), + pInfo.GetPathfindingIndex()) +, x7a0_boneTracking(*GetModelData()->GetAnimationData(), "Head_1"sv, zeus::degToRad(80.f), zeus::degToRad(180.f), + EBoneTrackingFlags::None) +, x7ec_burstFire(skBursts.data(), 0) { + const CModelData* modelData = GetModelData(); + const CAnimData* animData = modelData->GetAnimationData(); + x798_headSegId = animData->GetLocatorSegId("Head_1"sv); + x7e0_gunSegId = animData->GetLocatorSegId("L_gun_LCTR"sv); + x864_missileSegments.push_back(animData->GetLocatorSegId("L_Missile_LCTR"sv)); + x864_missileSegments.push_back(animData->GetLocatorSegId("R_Missile_LCTR"sv)); + x850_height = modelData->GetScale().x() * + GetAnimationDistance(CPASAnimParmData{3, CPASAnimParm::FromEnum(3), CPASAnimParm::FromEnum(1)}); + if (x568_data.xd8_particleGen1.IsValid() && x568_data.xdc_particleGen2.IsValid() && + x568_data.xe0_particleGen3.IsValid()) { + x65c_particleGenDescs.push_back(g_SimplePool->GetObj({SBIG('PART'), x568_data.xd8_particleGen1})); + x65c_particleGenDescs.push_back(g_SimplePool->GetObj({SBIG('PART'), x568_data.xdc_particleGen2})); + x65c_particleGenDescs.push_back(g_SimplePool->GetObj({SBIG('PART'), x568_data.xe0_particleGen3})); + for (const auto& desc : x65c_particleGenDescs) { + x684_particleGens.push_back(std::make_unique(desc)); + } + } + x460_knockBackController.SetLocomotionDuringElectrocution(true); +} + +void CFlyingPirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + if (msg == EScriptObjectMessage::Alert) { + if (GetActive()) { + x400_24_hitByPlayerProjectile = true; + } + } else if (msg == EScriptObjectMessage::Activate) { + AddToTeam(mgr); + } else if (msg == EScriptObjectMessage::Deleted) { + RemoveFromTeam(mgr); + } + CPatterned::AcceptScriptMsg(msg, uid, mgr); + switch (msg) { + case EScriptObjectMessage::SetToZero: + x6a2_28_ = true; + break; + case EScriptObjectMessage::Start: + x6a1_31_stopped = false; + break; + case EScriptObjectMessage::Stop: + x6a1_31_stopped = true; + break; + case EScriptObjectMessage::OnFloor: + x7ec_burstFire.SetBurstType(2); + break; + case EScriptObjectMessage::Falling: + if (x450_bodyController->GetPercentageFrozen() == 0.f && !x400_28_pendingMassiveDeath && !x6a1_30_spinToDeath) { + SetMomentumWR({0.f, 0.f, -GetGravityConstant() * xe8_mass}); + } + x7ec_burstFire.SetBurstType(0); + break; + case EScriptObjectMessage::Registered: + x86c_ = x568_data.xc0_ * mgr.GetActiveRandom()->Float() + x568_data.xbc_; + break; + case EScriptObjectMessage::InitializedInArea: + for (const auto& conn : x20_conns) { + if (conn.x0_state == EScriptObjectState::Retreat) { + if (TCastToPtr cover = mgr.ObjectById(mgr.GetIdForScript(conn.x8_objId))) { + cover->Reserve(x8_uid); + } + } else if (conn.x0_state == EScriptObjectState::Patrol && conn.x4_msg == EScriptObjectMessage::Follow) { + x6a0_27_canPatrol = true; + } else if (conn.x0_state == EScriptObjectState::Attack && conn.x4_msg == EScriptObjectMessage::Action) { + x85c_attackObjectId = mgr.GetIdForScript(conn.x8_objId); + } + } + x6a8_pathFindSearch.SetArea(mgr.GetWorld()->GetAreaAlways(x4_areaId)->GetPostConstructed()->x10bc_pathArea); + if (x30_24_active) { + AddToTeam(mgr); + } + UpdateParticleEffects(mgr, 0.f, x6a0_24_isFlyingPirate); + GetModelData()->GetAnimationData()->SetParticleEffectState("Eyes"sv, true, mgr); + break; + case EScriptObjectMessage::Jumped: + if (CScriptCoverPoint* cover = GetCoverPoint(mgr, x6a4_currentCoverPoint)) { + x328_25_verticalMovement = false; + SetMomentumWR({0.f, 0.f, -xe8_mass * GetGravityConstant()}); + AddMaterial(EMaterialTypes::GroundCollider, mgr); + SetDestPos(cover->GetTranslation()); + const zeus::CVector3f& dist = cover->GetTranslation() - GetTranslation(); + if (dist.z() < 0.f) { + zeus::CVector3f velocity = GetVelocity(); + const float gravity = GetGravityConstant(); + float fVar2 = -(2.f * gravity) * dist.z() - (velocity.z() * velocity.z()); + float fVar3 = fVar2 != 0.f ? fVar2 * (1.f / std::sqrt(fVar2)) : 0.f; + float dVar9 = (-velocity.z() + fVar3) / gravity; + if (0.f < dVar9) { + zeus::CVector2f dist2f(dist.x(), dist.y()); + const zeus::CVector2f& normal = dist2f.normalized(); + const float mag = dist2f.magnitude(); + velocity.x() = (mag / dVar9) * normal.x(); + velocity.y() = (mag / dVar9) * normal.y(); + SetVelocityWR(velocity); + + x870_.zeroOut(); + x87c_.zeroOut(); + x898_ = 1.f; + } + } + } + break; + default: + break; + } +} + +void CFlyingPirate::AddToTeam(CStateManager& mgr) { + if (x890_teamAiMgr == kInvalidUniqueId) { + x890_teamAiMgr = CTeamAiMgr::GetTeamAiMgr(*this, mgr); + } + if (x890_teamAiMgr != kInvalidUniqueId) { + if (TCastToPtr team = mgr.ObjectById(x890_teamAiMgr)) { + team->AssignTeamAiRole(*this, CTeamAiRole::ETeamAiRole::Melee, CTeamAiRole::ETeamAiRole::Ranged, + CTeamAiRole::ETeamAiRole::Invalid); + } + } +} + +void CFlyingPirate::RemoveFromTeam(CStateManager& mgr) { + if (x890_teamAiMgr != kInvalidUniqueId) { + if (TCastToPtr team = mgr.ObjectById(x890_teamAiMgr)) { + if (team->IsPartOfTeam(GetUniqueId())) { + team->RemoveTeamAiRole(GetUniqueId()); + x890_teamAiMgr = kInvalidUniqueId; + } + } + } +} + +void CFlyingPirate::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { + for (const auto& gen : x684_particleGens) { + if (frustum.aabbFrustumTest(GetBoundingBox())) { + g_Renderer->AddParticleGen(*gen); + } + } + CPatterned::AddToRenderer(frustum, mgr); +} + +bool CFlyingPirate::AggressionCheck(CStateManager& mgr, float) { return x6a2_24_aggressive; } + +bool CFlyingPirate::AnimOver(CStateManager& mgr, float arg) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Death) { + return true; + } + return CPatterned::AnimOver(mgr, arg); +} + +void CFlyingPirate::Attack(CStateManager& mgr, EStateMsg msg, float arg) { + switch (msg) { + case EStateMsg::Activate: + x32c_animState = EAnimState::Ready; + if (!x6a2_25_aggressionChecked) { + float fVar1; + if (3.f <= x858_) { + fVar1 = x568_data.xe8_aggressionChance; + } else { + fVar1 = 2.f * x568_data.xe8_aggressionChance; + } + x6a2_24_aggressive = mgr.GetActiveRandom()->Range(0.f, 100.f) < fVar1; + x6a2_25_aggressionChecked = true; + } + break; + case EStateMsg::Update: + TryCommand(mgr, pas::EAnimationState::ProjectileAttack, &CPatterned::TryProjectileAttack, 1); + x450_bodyController->FaceDirection((mgr.GetPlayer().GetTranslation() - GetTranslation()).normalized(), arg); + DeliverGetUp(); + UpdateCanSeePlayer(mgr); + break; + case EStateMsg::Deactivate: + x32c_animState = EAnimState::NotReady; + x6a2_24_aggressive = false; + break; + default: + break; + } +} + +bool CFlyingPirate::Attacked(CStateManager& mgr, float arg) { return x854_ < (arg != 0.f ? arg : 0.5f); } + +zeus::CVector3f CFlyingPirate::AvoidActors(CStateManager& mgr) { + const zeus::CVector3f& origin = GetTranslation(); + const zeus::CAABox box(origin - 8.f, origin + 8.f); + rstl::reserved_vector nearList; + mgr.BuildNearList(nearList, box, CMaterialFilter::MakeInclude(EMaterialTypes::Character), this); + + zeus::CVector3f ret; + for (const auto& id : nearList) { + if (TCastToConstPtr actor = mgr.GetObjectById(id)) { + ret += x45c_steeringBehaviors.Separation(*this, actor->GetTranslation(), 10.f); + } + } + const zeus::CVector3f& playerPos = mgr.GetPlayer().GetTranslation(); + return ret + x45c_steeringBehaviors.Separation(*this, {playerPos.x(), playerPos.y(), origin.z()}, 20.f); +} + +void CFlyingPirate::Bounce(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + CTeamAiMgr::ResetTeamAiRole(CTeamAiMgr::EAttackType::Ranged, mgr, x8_uid, x890_teamAiMgr, true); + } else if (msg == EStateMsg::Update) { + switch (x450_bodyController->GetCurrentStateId()) { + case pas::EAnimationState::Locomotion: + x330_stateMachineState.SetCodeTrigger(); + break; + case pas::EAnimationState::LieOnGround: + x450_bodyController->GetCommandMgr().DeliverCmd(CBCGetupCmd(pas::EGetupType::Zero)); + break; + case pas::EAnimationState::Hurled: + x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::ExitState)); + x328_25_verticalMovement = true; + break; + default: + break; + } + } +} + +void CFlyingPirate::CalculateRenderBounds() { + if (!x89c_ragDoll || !x89c_ragDoll->IsPrimed()) { + CActor::CalculateRenderBounds(); + } else { + const zeus::CAABox& bounds = x89c_ragDoll->CalculateRenderBounds(); + const zeus::CVector3f& scale = 0.25f * GetModelData()->GetScale(); + x9c_renderBounds = {bounds.min - scale, bounds.max + scale}; + } +} + +bool CFlyingPirate::CanFireMissiles(CStateManager& mgr) { + for (const auto& seg : x864_missileSegments) { + const zeus::CTransform& xf = GetLctrTransform(seg); + const zeus::CVector3f& dir = xf.origin + (3.f * xf.frontVector()); + CMaterialList matList(EMaterialTypes::Player, EMaterialTypes::ProjectilePassthrough); + if (!LineOfSightTest(mgr, xf.origin, dir, matList) || !LineOfSightTest(mgr, dir, GetTargetPos(mgr), matList)) { + x6a1_28_ = true; + return false; + } + } + return true; +} + +void CFlyingPirate::CheckForProjectiles(CStateManager& mgr) { + if (!x6a0_29_checkForProjectiles) + return; + + const zeus::CVector3f& playerPos = mgr.GetPlayer().GetTranslation(); + const zeus::CAABox box(playerPos - 5.f, playerPos + 5.f); + x6a0_30_ = false; + + rstl::reserved_vector nearList; + mgr.BuildNearList(nearList, box, CMaterialFilter::MakeInclude(EMaterialTypes::Projectile), this); + for (const auto& id : nearList) { + if (TCastToConstPtr proj = mgr.GetObjectById(id)) { + zeus::CVector3f dist = GetBoundingBox().center() - proj->GetTranslation(); + if (dist.isMagnitudeSafe()) { + if (GetTranslation().dot(dist) < 0.f) { + dist.normalize(); + zeus::CVector3f nv = proj->GetTranslation() - proj->GetPreviousPos(); + if (!nv.isMagnitudeSafe()) { + nv.normalize(); + if (0.939f < nv.dot(dist)) { + x6a0_30_ = true; + } + } + } + } else { + x6a0_30_ = true; + } + if (x6a0_30_) + break; + } + } + x6a0_29_checkForProjectiles = false; +} + +bool CFlyingPirate::CoverCheck(CStateManager& mgr, float) { + if (0.f < x888_) + return false; + x888_ = 10.f; + return mgr.GetActiveRandom()->Range(0.f, 100.f) < x568_data.xcc_coverCheckChance; +} + +bool CFlyingPirate::CoverFind(CStateManager& mgr, float) { + float closestMag = x568_data.x0_maxCoverDistance * x568_data.x0_maxCoverDistance; + CScriptCoverPoint* closest = nullptr; + for (const auto& entity : *mgr.ObjectListById(EGameObjectList::PlatformAndDoor)) { + if (TCastToPtr cover = entity) { + if (cover->GetActive() && cover->ShouldLandHere() && !cover->GetInUse(x8_uid) && + cover->GetAreaIdAlways() == x4_areaId) { + float mag = (GetTranslation() - cover->GetTranslation()).magSquared(); + if (mag < closestMag) { + closest = cover; + closestMag = mag; + } + } + } + } + if (closest != nullptr) { + ReleaseCoverPoint(mgr, x6a4_currentCoverPoint); + SetCoverPoint(closest, x6a4_currentCoverPoint); + x6a6_id2 = x6a4_currentCoverPoint; + return true; + } + return false; +} + +void CFlyingPirate::Deactivate(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x401_30_pendingDeath = true; + } +} + +void CFlyingPirate::Dead(CStateManager& mgr, EStateMsg msg, float arg) { + CPatterned::Dead(mgr, msg, arg); + if (msg == EStateMsg::Activate) { + x7a0_boneTracking.SetActive(false); + GetModelData()->GetAnimationData()->SetParticleEffectState("Eyes"sv, false, mgr); + CTeamAiMgr::ResetTeamAiRole(CTeamAiMgr::EAttackType::Ranged, mgr, x890_teamAiMgr, x8_uid, true); + } +} + +void CFlyingPirate::Dodge(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x32c_animState = EAnimState::Ready; + if ((x84c_dodgeDirection = GetDodgeDirection(mgr, x850_height)) == pas::EStepDirection::Invalid) { + x84c_dodgeDirection = + (mgr.GetActiveRandom()->Next() & 0x4000) == 0 ? pas::EStepDirection::Right : pas::EStepDirection::Left; + } + UpdateParticleEffects(mgr, 1.f, true); + } else if (msg == EStateMsg::Update) { + TryCommand(mgr, pas::EAnimationState::Step, &CPatterned::TryDodge, static_cast(x84c_dodgeDirection)); + UpdateCanSeePlayer(mgr); + x898_ = std::max(1.f, 2.f - x330_stateMachineState.GetTime()); + DeliverGetUp(); + } else if (msg == EStateMsg::Deactivate) { + x32c_animState = EAnimState::NotReady; + x6a1_28_ = false; + } +} + +void CFlyingPirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { + if (type == EUserEventType::DeGenerate || type == EUserEventType::BecomeRagDoll) { + if (!x89c_ragDoll && HealthInfo(mgr)->GetHP() <= 0.f) { + x89c_ragDoll = + std::make_unique(mgr, this, x568_data.xc8_ragDollSfx1, x568_data.xca_ragDollSfx2); + } + } else if (type == EUserEventType::Projectile) { + CProjectileInfo& pInfo = + x6a1_26_isAttackingObject ? x568_data.x60_altProjectileInfo2 : x568_data.x38_altProjectileInfo1; + if (pInfo.Token().IsLoaded() && mgr.CanCreateProjectile(x8_uid, EWeaponType::AI, 16)) { + const zeus::CTransform& xf = GetLctrTransform(node.GetLocatorName()); + TUniqueId target = x6a1_26_isAttackingObject ? x85c_attackObjectId : mgr.GetPlayer().GetUniqueId(); + CEnergyProjectile* projectile = + new CEnergyProjectile(true, pInfo.Token(), EWeaponType::AI, xf, EMaterialTypes::Character, pInfo.GetDamage(), + mgr.AllocateUniqueId(), x4_areaId, x8_uid, target, EProjectileAttrib::None, false, + zeus::skOne3f, std::nullopt, -1, false); + mgr.AddObject(projectile); + if (!x6a1_26_isAttackingObject) { + projectile->SetCameraShake( + CCameraShakeData::BuildPatternedExplodeShakeData(projectile->GetTranslation(), 0.3f, 0.2f, 50.f)); + if (x6a0_25_isAquaPirate) { + projectile->SetMinHomingDistance(x568_data.xf0_projectileHomingDistance); + } + } + } + } else { + CPatterned::DoUserAnimEvent(mgr, node, type, dt); + } +} + +void CFlyingPirate::Enraged(CStateManager& mgr, EStateMsg msg, float arg) { + if (msg != EStateMsg::Update) + return; + + x87c_ = (arg * arg * x568_data.xc4_) * zeus::skUp; + x898_ = 1.f; + x870_ += x87c_; + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCLocomotionCmd(zeus::skUp, (GetTargetPos(mgr) - GetTranslation()).normalized(), 1.f)); +} + +void CFlyingPirate::Explode(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, EMaterialTypes::GroundCollider, EMaterialTypes::Solid, + mgr); + x150_momentum.zeroOut(); + if (!x400_27_fadeToDeath) { + MassiveDeath(mgr); + } + } else if (msg == EStateMsg::Update) { + if (x330_stateMachineState.GetTime() > 0.1f) { + DeathDelete(mgr); + } + } +} + +void CFlyingPirate::MassiveDeath(CStateManager& mgr) { + CExplosion* explosion = new CExplosion( + static_cast>(x568_data.x90_particleGenDesc), mgr.AllocateUniqueId(), true, + {x4_areaId, CEntity::NullConnectionList}, "", GetTransform(), 0, zeus::CVector3f(1.5f), zeus::skWhite); + mgr.AddObject(explosion); + mgr.ApplyDamageToWorld(x8_uid, *this, GetTranslation(), x568_data.x9c_dInfo, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid})); + mgr.GetCameraManager()->AddCameraShaker(CCameraShakeData::BuildPatternedExplodeShakeData(0.5f, 0.3f), true); + CPatterned::MassiveDeath(mgr); +} + +void CFlyingPirate::FireProjectile(CStateManager& mgr, float dt) { + bool projectileFired = false; + const zeus::CTransform& xf = GetLctrTransform(x7e0_gunSegId); + if (!x400_25_alive) { + LaunchProjectile(xf, mgr, 8, EProjectileAttrib::None, false, std::nullopt, -1, false, zeus::skOne3f); + projectileFired = true; + } else { + if (TCastToPtr actor = mgr.ObjectById(x7e8_targetId)) { + zeus::CVector3f origin = actor->GetTranslation(); + const CPlayer& player = mgr.GetPlayer(); + if (x7e8_targetId == player.GetUniqueId()) { + origin = GetProjectileInfo()->PredictInterceptPos(xf.origin, player.GetAimPosition(mgr, 0.f), player, true, dt); + } + zeus::CVector3f dist = origin - xf.origin; + float mag = dist.magnitude(); + float fVar13 = xf.frontVector().dot(dist * (1.f / mag)); + if (0.707f < fVar13 || (mag < 6.f && 0.5f < fVar13)) { + if (LineOfSightTest(mgr, xf.origin, origin, {EMaterialTypes::Player, EMaterialTypes::ProjectilePassthrough})) { + origin += GetTransform().rotate(x7ec_burstFire.GetDistanceCompensatedError(mag, 6.f)); + LaunchProjectile(zeus::lookAt(xf.origin, origin, zeus::skUp), mgr, 8, EProjectileAttrib::None, false, + std::nullopt, -1, false, zeus::skOne3f); + projectileFired = true; + } + } + } + } + if (projectileFired) { + const std::pair& anim = x450_bodyController->GetPASDatabase().FindBestAnimation( + CPASAnimParmData{24, CPASAnimParm::FromEnum(2)}, *mgr.GetActiveRandom(), -1); + if (anim.first > 0.f) { + GetModelData()->GetAnimationData()->AddAdditiveAnimation(anim.second, 1.f, false, true); + } + CSfxManager::AddEmitter(x568_data.x34_gunSfx, GetTranslation(), zeus::skZero3f, true, false, 0x7f, kInvalidAreaId); + } +} + +pas::EStepDirection CFlyingPirate::GetDodgeDirection(CStateManager& mgr, float arg) { + float argSquared = arg * arg; + bool canDodgeLeft = true; + bool canDodgeRight = true; + bool canDodgeUp = true; + bool canDodgeDown = true; + pas::EStepDirection direction = pas::EStepDirection::Invalid; + for (const auto& entity : *mgr.ObjectListById(EGameObjectList::AiWaypoint)) { + if (entity == this) + continue; + if (TCastToPtr actor = entity) { + const zeus::CVector3f& dist = actor->GetTranslation() - GetTranslation(); + float distMagSquared = dist.magSquared(); + if (distMagSquared < argSquared) { + float rightVecMag = GetTransform().rightVector().magSquared(); + if ((0.866f * distMagSquared) < rightVecMag || (0.f < rightVecMag && distMagSquared < 3.f)) { + canDodgeRight = false; + } else if (rightVecMag < 0.866f * -distMagSquared || (rightVecMag < 0.f && distMagSquared < 3.f)) { + canDodgeLeft = false; + } + float upVecMag = GetTransform().upVector().magSquared(); + if ((0.866f * distMagSquared) < upVecMag || (0.f < upVecMag && distMagSquared < 3.f)) { + canDodgeUp = false; + } else if (upVecMag < 0.866f * -distMagSquared || (0.f < upVecMag && distMagSquared < 3.f)) { + canDodgeDown = false; + } + } + } + } + + const zeus::CVector3f& center = GetBoundingBox().center(); + if (canDodgeRight) { + canDodgeRight = LineOfSightTest(mgr, center, center + (arg * GetTransform().rightVector()), {}); + } + if (canDodgeLeft) { + canDodgeLeft = LineOfSightTest(mgr, center, center - (arg * GetTransform().rightVector()), {}); + } + if (canDodgeUp) { + canDodgeUp = LineOfSightTest(mgr, center, center + (arg * GetTransform().upVector()), {}); + } + if (canDodgeDown) { + canDodgeDown = LineOfSightTest(mgr, center, center - (arg * GetTransform().upVector()), {}); + } + + if ((canDodgeLeft || canDodgeRight) && (canDodgeUp || canDodgeDown)) { + if ((mgr.GetActiveRandom()->Next() & 0x4000) == 0) { + canDodgeUp = false; + canDodgeDown = false; + } else { + canDodgeLeft = false; + canDodgeRight = false; + } + } + if (canDodgeLeft && canDodgeRight) { + if ((mgr.GetActiveRandom()->Next() & 0x4000) == 0) { + canDodgeRight = false; + } else { + canDodgeLeft = false; + } + } + if (canDodgeUp && canDodgeDown) { + const zeus::CVector3f& target = GetTargetPos(mgr); + if (target.z() - (GetTranslation().z() + x568_data.x8c_flyingHeight) <= 0.f) { + canDodgeUp = false; + } else { + canDodgeDown = false; + } + } + + if (canDodgeUp) { + direction = pas::EStepDirection::Up; + } else if (canDodgeDown) { + direction = pas::EStepDirection::Down; + } else if (canDodgeLeft) { + direction = pas::EStepDirection::Left; + } else if (canDodgeRight) { + direction = pas::EStepDirection::Right; + } + return direction; +} + +zeus::CVector3f CFlyingPirate::GetTargetPos(CStateManager& mgr) { + const CPlayer& player = mgr.GetPlayer(); + const TUniqueId& playerUid = player.GetUniqueId(); + if (x7e8_targetId != playerUid) { + if (TCastToPtr actor = mgr.ObjectById(x7e8_targetId)) { + if (actor->GetActive()) { + return actor->GetTranslation(); + } + } + x7a0_boneTracking.SetTarget(playerUid); + x7e8_targetId = playerUid; + } + return player.GetAimPosition(mgr, 0.f); +} + +void CFlyingPirate::GetUp(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x32c_animState = EAnimState::Ready; + CTeamAiMgr::ResetTeamAiRole(CTeamAiMgr::EAttackType::Ranged, mgr, x890_teamAiMgr, x8_uid, true); + } else if (msg == EStateMsg::Update) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::LieOnGround) { + // will always return Success? + CPathFindSearch::EResult result = x6a8_pathFindSearch.Search(GetTranslation(), GetTranslation()); + if (result == CPathFindSearch::EResult::NoSourcePoint) { + x401_30_pendingDeath = true; + } + } + TryCommand(mgr, pas::EAnimationState::Getup, &CPatterned::TryGetUp, 0); + } else if (msg == EStateMsg::Deactivate) { + x32c_animState = EAnimState::NotReady; + } +} + +bool CFlyingPirate::HearPlayer(CStateManager& mgr, float) { + const CPlayer& player = mgr.GetPlayer(); + const float hearingDist = x568_data.x4_hearingDistance * x568_data.x4_hearingDistance; + return player.GetVelocity().magSquared() > 0.1f && + (player.GetTranslation() - GetTranslation()).magSquared() < hearingDist; +} + +bool CFlyingPirate::HearShot(CStateManager& mgr, float) { return x6a0_26_hearShot; } + +bool CFlyingPirate::InPosition(CStateManager& mgr, float) { + CScriptCoverPoint* const cover = GetCoverPoint(mgr, x6a4_currentCoverPoint); + if (cover == nullptr) { + return true; + } + const zeus::CVector3f& dist = cover->GetTranslation() - GetTranslation(); + return dist.z() < 0.f && dist.magnitude() < 4.f; +} + +bool CFlyingPirate::InRange(CStateManager& mgr, float) { + const CPlayer& player = mgr.GetPlayer(); + const zeus::CVector3f& playerPos = player.GetTranslation(); + return std::abs(playerPos.z()) < x2fc_minAttackRange && + playerPos.magSquared() < x300_maxAttackRange * x300_maxAttackRange; +} + +void CFlyingPirate::Jump(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Combat); + x328_25_verticalMovement = true; + x150_momentum.zeroOut(); + x888_ = 10.f; + UpdateParticleEffects(mgr, 1.f, true); + UpdateLandingSmoke(mgr, true); + x6a2_24_aggressive = x568_data.xec_ > mgr.GetActiveRandom()->Range(0.f, 100.f); + } else if (msg == EStateMsg::Deactivate) { + UpdateParticleEffects(mgr, 0.5f, true); + UpdateLandingSmoke(mgr, false); + x6a2_24_aggressive = false; + } +} + +void CFlyingPirate::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, + EKnockBackType type, bool inDeferred, float magnitude) { + if (x400_25_alive) { + x460_knockBackController.SetSeverity(x328_25_verticalMovement ? pas::ESeverity::Zero : pas::ESeverity::One); + } else if (!IsOnGround()) { + const float rand = mgr.GetActiveRandom()->Range(0.f, 100.f); + if (x568_data.xb8_ <= rand) { + UpdateParticleEffects(mgr, 0.f, false); + SetMomentumWR({0.f, 0.f, -GetGravityConstant() * xe8_mass}); + } else { + x6a1_30_spinToDeath = true; + x150_momentum.zeroOut(); + } + x460_knockBackController.SetAnimationStateRange(EKnockBackAnimationState::Hurled, EKnockBackAnimationState::Hurled); + x328_25_verticalMovement = false; + // const TUniqueId& waypointId = GetWaypointForState(mgr, EScriptObjectState::Retreat, EScriptObjectMessage::Next); + // if (waypointId != kInvalidUniqueId) { + // casts and then does nothing? + // } + const zeus::CVector3f& homingPosition = mgr.GetPlayer().GetHomingPosition(mgr, 0.f); + const zeus::CVector3f& homingDist = homingPosition - GetTranslation(); + zeus::CVector3f cross = homingDist.cross(zeus::skUp); + if (zeus::close_enough(cross, zeus::skZero3f, 1.0E-4f)) { + cross = homingDist.cross(zeus::skForward); + } + SetDestPos(homingPosition + (homingDist.y() * cross.normalized())); + x7a0_boneTracking.SetActive(false); + } + CPatterned::KnockBack(pos, mgr, info, type, inDeferred, magnitude); + if (x460_knockBackController.GetActiveParms().x0_animState == EKnockBackAnimationState::Hurled) { + if (x400_25_alive) { + if (!x450_bodyController->IsFrozen()) { + x330_stateMachineState.SetState(mgr, *this, GetStateMachine(), "GetUpNow"sv); + x330_stateMachineState.SetDelay(x568_data.x88_knockBackDelay); + } + x6a1_28_ = false; + x328_25_verticalMovement = false; + CSfxManager::AddEmitter(x568_data.xe4_knockBackSfx, GetTranslation(), zeus::skZero3f, 1.f, true, false, 0x7f, + kInvalidAreaId); + } else { + CSfxManager::AddEmitter(x568_data.xe6_deathSfx, GetTranslation(), zeus::skZero3f, 1.f, true, false, 0x7f, + kInvalidAreaId); + if (x400_27_fadeToDeath) { + x6a1_30_spinToDeath = false; + UpdateParticleEffects(mgr, 0.f, false); + SetMomentumWR({0.f, 0.f, -GetGravityConstant() * xe8_mass}); + } + } + } +} + +void CFlyingPirate::Land(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x32c_animState = EAnimState::Ready; + UpdateLandingSmoke(mgr, true); + UpdateParticleEffects(mgr, 1.f, true); + } else if (msg == EStateMsg::Update) { + TryCommand(mgr, pas::EAnimationState::Jump, &CPatterned::TryJump, 0); + if (x32c_animState == EAnimState::Repeat) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + } + } else if (msg == EStateMsg::Deactivate) { + x32c_animState = EAnimState::NotReady; + UpdateLandingSmoke(mgr, false); + UpdateParticleEffects(mgr, 0.f, false); + } +} + +bool CFlyingPirate::Landed(CStateManager& mgr, float) { + return x450_bodyController->GetCurrentStateId() == pas::EAnimationState::LieOnGround; +} + +bool CFlyingPirate::LineOfSight(CStateManager& mgr, float) { return !x6a0_31_canSeePlayer; } + +bool CFlyingPirate::LineOfSightTest(CStateManager& mgr, const zeus::CVector3f& start, const zeus::CVector3f& end, + CMaterialList exclude) { + return mgr.RayCollideWorld(start, end, CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, exclude), this); +} + +bool CFlyingPirate::Listen(const zeus::CVector3f& pos, EListenNoiseType type) { + bool ret = false; + if (x400_25_alive) { + float x4Squared = x568_data.x4_hearingDistance * x568_data.x4_hearingDistance; + const zeus::CVector3f& dist = pos - GetTranslation(); + if (dist.magSquared() < x4Squared && (x3c0_detectionHeightRange == 0.f || (dist.z() * dist.z() < x4Squared))) { + ret = true; + x6a0_26_hearShot = true; + } + if (type == EListenNoiseType::PlayerFire) { + x6a0_29_checkForProjectiles = true; + } + } + return ret; +} + +void CFlyingPirate::Lurk(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + ReleaseCoverPoint(mgr, x6a4_currentCoverPoint); + x6a0_31_canSeePlayer = true; + x7d8_ = 0.f; + x7dc_ = 0; + CTeamAiMgr::ResetTeamAiRole(CTeamAiMgr::EAttackType::Ranged, mgr, x890_teamAiMgr, x8_uid, true); + x330_stateMachineState.SetDelay(3.f); + UpdateParticleEffects(mgr, 0.f, true); + x6a2_25_aggressionChecked = false; + } else if (msg == EStateMsg::Update) { + UpdateCanSeePlayer(mgr); + if (x32c_animState != EAnimState::NotReady) { + TryCommand(mgr, pas::EAnimationState::Turn, &CPatterned::TryTurn, 0); + } + if (x32c_animState != EAnimState::Repeat) { + x2e0_destPos = GetTargetPos(mgr); + zeus::CVector3f dist = x2e0_destPos - GetTranslation(); + dist.z() = 0.f; + if (GetTransform().frontVector().dot(dist.normalized()) < 0.8f) { + x32c_animState = EAnimState::Ready; + } + } + } else if (msg == EStateMsg::Deactivate) { + x6a1_25_ = false; + x6a1_28_ = false; + x32c_animState = EAnimState::NotReady; + } +} + +void CFlyingPirate::PathFind(CStateManager& mgr, EStateMsg msg, float arg) { + if (msg == EStateMsg::Activate) { + zeus::CVector3f target = mgr.GetPlayer().GetAimPosition(mgr, 0.f); + if (!x6a1_29_isMoving) { + if (const CScriptCoverPoint* const cover = GetCoverPoint(mgr, x6a4_currentCoverPoint)) { + target = cover->GetTranslation(); + } + } else { + target = x2e0_destPos; + } + CPathFindSearch* search = GetSearchPath(); + CPathFindSearch::EResult result = search->Search(GetTranslation(), target); + if (result != CPathFindSearch::EResult::Success && + (result == CPathFindSearch::EResult::NoDestPoint || result == CPathFindSearch::EResult::NoPath)) { + result = search->FindClosestReachablePoint(GetTranslation(), target); + if (result == CPathFindSearch::EResult::Success) { + search->Search(GetTranslation(), target); + } + } + UpdateParticleEffects(mgr, 0.5f, true); + } else if (msg == EStateMsg::Update) { + zeus::CVector3f move = zeus::skZero3f; + CPathFindSearch* search = GetSearchPath(); + if (search->GetResult() == CPathFindSearch::EResult::Success && + search->GetCurrentWaypoint() < search->GetWaypoints().size() - 1) { + zeus::CVector3f out = GetTranslation(); + const zeus::CVector3f& front = out + GetTransform().frontVector(); + search->GetSplinePointWithLookahead(out, front, 3.f); + if (search->SegmentOver(out)) { + search->SetCurrentWaypoint(search->GetCurrentWaypoint() + 1); + } + move = front - GetTranslation(); + if (move.canBeNormalized()) { + move.normalize(); + } + } + move += 3.f * AvoidActors(mgr); + if (move.canBeNormalized()) { + move.normalize(); + } + + float fVar1 = 1.f; + if (x858_ < 2.f) { + fVar1 = 4.f; + } + float fVar2 = 1.5f * fVar1; + fVar1 = arg * (arg * (fVar1 * x568_data.xc4_)); + x87c_ = fVar1 * move; + x898_ = fVar2; + x870_ += x87c_; + + const zeus::CVector3f& face = (GetTargetPos(mgr) - GetTranslation()).normalized(); + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, face, 1.f)); + UpdateCanSeePlayer(mgr); + } else if (msg == EStateMsg::Deactivate) { + x6a1_29_isMoving = false; + } +} + +void CFlyingPirate::Patrol(CStateManager& mgr, EStateMsg msg, float arg) { + if (!x6a0_27_canPatrol) + return; + + CPatterned::Patrol(mgr, msg, arg); + if (msg == EStateMsg::Activate) { + x450_bodyController->GetCommandMgr().SetSteeringBlendMode(ESteeringBlendMode::FullSpeed); + x8a0_patrolTarget = x2dc_destObj; + x8a4_ = 0.f; + } else if (msg == EStateMsg::Update) { + if (x8a0_patrolTarget != x2dc_destObj) { + x8a0_patrolTarget = x2dc_destObj; + x8a4_ = 0.f; + } + if (x2d8_patrolState == EPatrolState::Patrol) { + float f78 = x3b0_moveSpeed * x568_data.xc4_; + x8a4_ = std::min(f78, arg * f78 + x8a4_); + x87c_ = (arg * x8a4_ * arg) * (x2e0_destPos - GetTranslation()).normalized(); + x898_ = 1.5f * x3b0_moveSpeed; + x870_ += x87c_; + } + if (x30c_behaviourOrient == EBehaviourOrient::Constant) { + x450_bodyController->GetCommandMgr().DeliverTargetVector(GetTargetPos(mgr) - GetTranslation()); + } + UpdateCanSeePlayer(mgr); + } else if (msg == EStateMsg::Deactivate) { + x450_bodyController->GetCommandMgr().SetSteeringBlendMode(ESteeringBlendMode::Normal); + } +} + +bool CFlyingPirate::PatternOver(CStateManager& mgr, float) { return x2dc_destObj == kInvalidUniqueId; } + +void CFlyingPirate::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { + CModelData* modelData = GetModelData(); + if (x89c_ragDoll && x89c_ragDoll->IsPrimed()) { + x89c_ragDoll->PreRender(GetTranslation(), *modelData); + } + CPatterned::PreRender(mgr, frustum); + x7a0_boneTracking.PreRender(mgr, *modelData->GetAnimationData(), GetTransform(), modelData->GetScale(), + *x450_bodyController); +} + +void CFlyingPirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x6a1_26_isAttackingObject = true; + x32c_animState = EAnimState::Ready; + } else if (msg == EStateMsg::Update) { + TryCommand(mgr, pas::EAnimationState::ProjectileAttack, &CPatterned::TryProjectileAttack, 0); + DeliverGetUp(); + } else if (msg == EStateMsg::Deactivate) { + x6a1_26_isAttackingObject = false; + x32c_animState = EAnimState::NotReady; + } +} + +void CFlyingPirate::Retreat(CStateManager& mgr, EStateMsg msg, float arg) { + if (msg == EStateMsg::Activate) { + const zeus::CVector3f& origin = GetTranslation(); + const zeus::CVector3f& playerOrigin = mgr.GetPlayer().GetTranslation(); + const zeus::CVector3f& dist = (playerOrigin - origin).normalized(); + zeus::CVector3f target{ + origin.x() - x2fc_minAttackRange * dist.x(), + origin.y() - x2fc_minAttackRange * dist.y(), + playerOrigin.z() + x568_data.x8c_flyingHeight, + }; + CPathFindSearch* const search = GetSearchPath(); + if (search->OnPath(target) == CPathFindSearch::EResult::NoSourcePoint) { + search->FindClosestReachablePoint(origin, target); + target.z() += x568_data.x8c_flyingHeight; + if ((playerOrigin - target).magSquared() < 0.25f * x2fc_minAttackRange * x2fc_minAttackRange) { + target.z() -= x568_data.x8c_flyingHeight; // can just subtract instead of recreating dist/target + if (search->OnPath(target) == CPathFindSearch::EResult::NoSourcePoint) { + search->FindClosestReachablePoint(origin, target); + target.z() += x568_data.x8c_flyingHeight; + } + } + } + search->Search(origin, target); + UpdateParticleEffects(mgr, 0.5f, true); + } else if (msg == EStateMsg::Update) { + zeus::CVector3f move = zeus::skZero3f; + CPathFindSearch* const search = GetSearchPath(); + if (search->GetCurrentWaypoint() < search->GetWaypoints().size() - 1) { + const zeus::CVector3f& origin = GetTranslation(); + zeus::CVector3f out = origin + GetTransform().frontVector(); + search->GetSplinePointWithLookahead(out, origin, 3.f); + if (search->SegmentOver(out)) { + search->SetCurrentWaypoint(search->GetCurrentWaypoint() + 1); + } + move = out - origin; + if (move.canBeNormalized()) { + move.normalize(); + } + } + move += 3.f * AvoidActors(mgr); + if (move.canBeNormalized()) { + move.normalize(); + } + + float fVar1 = 1.f; + if (x858_ < 2.f) { + fVar1 = 4.f; + } + float fVar2 = 1.5f * fVar1; + fVar1 = arg * (arg * (fVar1 * x568_data.xc4_)); + x87c_ = fVar1 * move; + x898_ = fVar2; + x870_ += x87c_; + + const zeus::CVector3f& face = (GetTargetPos(mgr) - GetTranslation()).normalized(); + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, face, 1.f)); + UpdateCanSeePlayer(mgr); + } +} + +bool CFlyingPirate::ShotAt(CStateManager& mgr, float arg) { return x858_ < (arg != 0.f ? arg : 0.5f); } + +bool CFlyingPirate::ShouldAttack(CStateManager& mgr, float) { + CTeamAiRole* const role = CTeamAiMgr::GetTeamAiRole(mgr, x890_teamAiMgr, x8_uid); + const CPlayer& player = mgr.GetPlayer(); + if ((role == nullptr || role->GetTeamAiRole() == CTeamAiRole::ETeamAiRole::Ranged) && + x7e8_targetId == player.GetUniqueId() && (x86c_ <= 0.f || x854_ < 1.f) && CanFireMissiles(mgr)) { + const zeus::CVector3f& dist = player.GetTranslation() - GetTranslation(); + if (dist.z() * dist.z() < dist.y() * dist.y() + dist.x() * dist.x()) { + if (x890_teamAiMgr != kInvalidUniqueId) { + if (!CTeamAiMgr::AddAttacker(CTeamAiMgr::EAttackType::Ranged, mgr, x890_teamAiMgr, x8_uid)) { + return false; + } + } + x86c_ = x568_data.xc0_ * mgr.GetActiveRandom()->Float() + x568_data.xbc_; + return true; + } + } + return false; +} + +bool CFlyingPirate::ShouldDodge(CStateManager& mgr, float) { + if (x6a1_28_ || x6a1_25_) + return false; + return 0.f < (GetTargetPos(mgr) - GetTranslation()).dot(GetTransform().frontVector()) && + (x854_ < 0.33f || x858_ < 0.33f) && x7d8_ < 0.5f; +} + +bool CFlyingPirate::ShouldMove(CStateManager& mgr, float) { + const CPlayer& player = mgr.GetPlayer(); + const zeus::CVector3f& origin = GetTranslation(); + const zeus::CVector3f& playerOrigin = player.GetTranslation(); + const zeus::CVector3f& dist = origin - playerOrigin; + + CRandom16* activeRandom = mgr.GetActiveRandom(); + float rand = activeRandom->Float(); + if (0.5f <= rand) { + rand = activeRandom->Range(15.f, 25.f); + } else { + rand = activeRandom->Range(-25.f, -15.f); + } + + const zeus::CVector3f& cross = dist.cross(zeus::skUp).normalized(); + SetDestPos({ + origin.x() + (rand * cross.x()), + origin.y() + (rand * cross.y()), + playerOrigin.z() + x568_data.x8c_flyingHeight, + }); + x6a1_29_isMoving = true; + return true; +} + +bool CFlyingPirate::ShouldRetreat(CStateManager& mgr, float) { + if (!x6a2_28_) + return false; + + TUniqueId id = GetWaypointForState(mgr, EScriptObjectState::Patrol, EScriptObjectMessage::Follow); + TCastToPtr waypoint = mgr.ObjectById(id); + if (!waypoint) { + id = GetWaypointForState(mgr, EScriptObjectState::Retreat, EScriptObjectMessage::Follow); + waypoint = mgr.ObjectById(id); + } + if (waypoint) { + x6a2_28_ = false; + x2dc_destObj = id; + SetDestPos(waypoint->GetTranslation()); + x2ec_reflectedDestPos = GetTranslation(); + x328_24_inPosition = false; + x6a1_29_isMoving = true; + x6a0_26_hearShot = false; + x6a0_28_ = false; + x400_24_hitByPlayerProjectile = false; + return true; + } + return false; +} + +bool CFlyingPirate::ShouldSpecialAttack(CStateManager& mgr, float) { + if (x3fc_flavor != EFlavorType::One || x85c_attackObjectId == kInvalidUniqueId || x860_ > 0.f) + return false; + + x860_ = 15.f * mgr.GetActiveRandom()->Float() + 15.f; + if (!mgr.GetPlayer().CheckOrbitDisableSourceList()) { + if (TCastToPtr actor = mgr.ObjectById(x85c_attackObjectId)) { + if (x890_teamAiMgr != kInvalidUniqueId) { + if (!CTeamAiMgr::AddAttacker(CTeamAiMgr::EAttackType::Ranged, mgr, x890_teamAiMgr, x8_uid)) { + return false; + } + } + SetDestPos(actor->GetTranslation() + (15.f * zeus::skDown)); + x6a1_29_isMoving = true; + return true; + } + } + return false; +} + +bool CFlyingPirate::SpotPlayer(CStateManager& mgr, float) { + const zeus::CVector3f& dir = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetGunEyePos(); + return dir.magnitude() * x3c4_detectionAngle < dir.dot(GetTransform().frontVector()); +} + +bool CFlyingPirate::Stuck(CStateManager& mgr, float arg) { + if (x330_stateMachineState.GetTime() < 0.5f) + return false; + return CPatterned::Stuck(mgr, arg) || GetSearchPath()->GetResult() != CPathFindSearch::EResult::Success; +} + +void CFlyingPirate::UpdateLandingSmoke(CStateManager& mgr, bool active) { + if (active) { + if (x684_particleGens.size()) { + const zeus::CVector3f& origin = GetTranslation(); + float particleLevel = origin.z() - 5.f; + CScriptCoverPoint* const cover = GetCoverPoint(mgr, x6a4_currentCoverPoint); + if (cover != nullptr) { + particleLevel = cover->GetTranslation().z() - 1.f; + } + const CRayCastResult& result = mgr.RayStaticIntersection(origin, zeus::skDown, origin.z() - particleLevel, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid})); + int idx = 1; + if (result.IsValid()) { + const CMaterialList& list = result.GetMaterial(); + if (!list.HasMaterial(EMaterialTypes::Ice) && !list.HasMaterial(EMaterialTypes::Snow)) { + if (list.HasMaterial(EMaterialTypes::Dirt) || list.HasMaterial(EMaterialTypes::MudSlow) || + list.HasMaterial(EMaterialTypes::Sand)) { + idx = 0; + } + } else { + idx = 2; + } + particleLevel = origin.z() - result.GetT(); + } + x684_particleGens[idx]->SetParticleEmission(true); + x684_particleGens[idx]->SetTranslation({origin.x(), origin.y(), particleLevel}); + } + GetModelData()->GetAnimationData()->SetParticleEffectState("LandingSmoke"sv, true, mgr); + } else { + for (const auto& gen : x684_particleGens) { + gen->SetParticleEmission(false); + } + GetModelData()->GetAnimationData()->SetParticleEffectState("LandingSmoke"sv, false, mgr); + } +} + +void CFlyingPirate::UpdateParticleEffects(CStateManager& mgr, float intensity, bool active) { + CAnimData* const animData = GetModelData()->GetAnimationData(); + std::string_view name = x6a0_25_isAquaPirate ? "ScubaGear"sv : "JetPack"sv; + if (active != x6a2_26_jetpackActive) { + animData->SetParticleEffectState(name, active, mgr); + if (x6a0_25_isAquaPirate) { + animData->SetParticleEffectState("ScubaBubbles"sv, active, mgr); + } + x6a2_26_jetpackActive = active; + } + if (active) { + animData->SetParticleCEXTValue(name, 0, 0.75f * intensity + 2.25f); + animData->SetParticleCEXTValue(name, 1, -0.13f * intensity + -0.1f); + } + if (!x6a0_25_isAquaPirate) { + const bool sparksActive = active && intensity > 0.8f; + if (sparksActive != x6a2_27_sparksActive) { + animData->SetParticleEffectState("Sparks"sv, sparksActive, mgr); + x6a2_27_sparksActive = sparksActive; + } + } +} + +void CFlyingPirate::DeliverGetUp() { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::LieOnGround) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCGetupCmd(pas::EGetupType::Zero)); + } +} + +void CFlyingPirate::UpdateCanSeePlayer(CStateManager& mgr) { + if (x7dc_ % 7 == 0) { + bool bVar4 = true; + const zeus::CVector3f& start = GetGunEyePos() - GetTransform().rightVector(); + const zeus::CVector3f& end = GetAimPosition(mgr, 0.f); + const CMaterialList matList(EMaterialTypes::Player, EMaterialTypes::ProjectilePassthrough); + if (LineOfSightTest(mgr, start, end, matList)) { + bVar4 = !LineOfSightTest(mgr, start, end, matList); + } + x6a0_31_canSeePlayer = bVar4; + } + x7dc_++; +} + +void CFlyingPirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float arg) { + CPatterned::Patrol(mgr, msg, arg); + + if (msg == EStateMsg::Activate) { + x450_bodyController->GetCommandMgr().SetSteeringBlendMode(ESteeringBlendMode::Normal); + x2dc_destObj = GetWaypointForState(mgr, EScriptObjectState::Attack, EScriptObjectMessage::Follow); + if (x2dc_destObj != kInvalidUniqueId) { + if (TCastToPtr waypoint = mgr.ObjectById(x2dc_destObj)) { + x30c_behaviourOrient = EBehaviourOrient(waypoint->GetBehaviourOrient()); + x3b0_moveSpeed = waypoint->GetSpeed(); + } + } + x8a0_patrolTarget = x2dc_destObj; + x8a4_ = 0.f; + } else if (msg == EStateMsg::Update) { + if (x2dc_destObj != x8a0_patrolTarget) { + x8a0_patrolTarget = x2dc_destObj; + x8a4_ = 0.f; + } + if (x2d8_patrolState == EPatrolState::Patrol) { + float f80 = x3b0_moveSpeed * x568_data.xc4_; + x8a4_ = std::min(arg * f80 + x8a4_, f80); + x87c_ = (arg * x8a4_ * arg) * (x2e0_destPos - GetTranslation()).normalized(); + x898_ = 1.5f * x3b0_moveSpeed; + x870_ += x87c_; + } + if (x30c_behaviourOrient == EBehaviourOrient::Constant) { + x450_bodyController->GetCommandMgr().DeliverTargetVector(GetTargetPos(mgr) - GetTranslation()); + } + UpdateCanSeePlayer(mgr); + } +} + +void CFlyingPirate::Taunt(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x6a0_28_ = true; + x7a0_boneTracking.SetActive(true); + const TUniqueId& playerUid = mgr.GetPlayer().GetUniqueId(); + x7a0_boneTracking.SetTarget(playerUid); + bool foundPirate = false; + for (const auto& obj : *mgr.ObjectListById(EGameObjectList::AiWaypoint)) { + if (const CSpacePirate* const pirate = CPatterned::CastTo(obj)) { + if (pirate->GetEnableAim() && pirate->IsAlive() && pirate->GetAreaIdAlways() == x4_areaId && + (pirate->GetTranslation() - GetTranslation()).magSquared() < + x568_data.x4_hearingDistance * x568_data.x4_hearingDistance) { + foundPirate = true; + } + } + } + x79c_ = foundPirate ? 0 : 1; + if (x7e8_targetId == kInvalidUniqueId) { + x7e8_targetId = playerUid; + } + } else if (msg == EStateMsg::Deactivate) { + if (x79c_ == 0) { + mgr.InformListeners(GetTranslation(), EListenNoiseType::PlayerFire); + } + } +} + +void CFlyingPirate::TurnAround(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x2e0_destPos = GetTargetPos(mgr); + zeus::CVector3f dist = x2e0_destPos - GetTranslation(); + dist.z() = 0.f; + if (GetTransform().frontVector().dot(dist.normalized()) < 0.8f) { + x32c_animState = EAnimState::Ready; + } + } else if (msg == EStateMsg::Update) { + TryCommand(mgr, pas::EAnimationState::Turn, &CPatterned::TryTurn, 0); + } else if (msg == EStateMsg::Deactivate) { + x32c_animState = EAnimState::NotReady; + } +} + +void CFlyingPirate::Walk(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + UpdateParticleEffects(mgr, 0.f, false); + } else if (msg == EStateMsg::Update) { + if (x32c_animState != EAnimState::NotReady) { + TryCommand(mgr, pas::EAnimationState::Turn, &CPatterned::TryTurn, 0); + } + if (x32c_animState != EAnimState::Repeat) { + x2e0_destPos = GetTargetPos(mgr); + zeus::CVector3f dist = x2e0_destPos - GetTranslation(); + dist.z() = 0.f; + if (GetTransform().frontVector().dot(dist.normalized()) < 0.8f) { + x32c_animState = EAnimState::Ready; + } + } + } else if (msg == EStateMsg::Deactivate) { + x32c_animState = EAnimState::NotReady; + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Combat); + x328_25_verticalMovement = true; + x150_momentum.zeroOut(); + } +} + +void CFlyingPirate::Think(float dt, CStateManager& mgr) { + if (!x30_24_active) + return; + + if (!x450_bodyController->GetActive()) { + x450_bodyController->Activate(mgr); + if (x6a0_24_isFlyingPirate) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Combat); + x328_25_verticalMovement = true; + } + } + + bool inCineCam = mgr.GetCameraManager()->IsInCinematicCamera(); + if (inCineCam && !x6a1_24_prevInCineCam) { + RemoveMaterial(EMaterialTypes::AIBlock, mgr); + CMaterialFilter filter = GetMaterialFilter(); + filter.IncludeList().Remove(EMaterialTypes::AIBlock); + SetMaterialFilter(filter); + } else if (!inCineCam && x6a1_24_prevInCineCam) { + AddMaterial(EMaterialTypes::AIBlock, mgr); + CMaterialFilter filter = GetMaterialFilter(); + filter.IncludeList().Add(EMaterialTypes::AIBlock); + SetMaterialFilter(filter); + } + x6a1_24_prevInCineCam = inCineCam; + + for (const auto& gen : x684_particleGens) { + gen->Update(dt); + } + + x78c_ = std::max(0.f, x78c_ - dt); + if (x400_25_alive) { + if (x6a0_30_) { + x858_ = 0.f; + x6a0_30_ = false; + } else { + x858_ += dt; + } + if (x400_24_hitByPlayerProjectile) { + x854_ = 0.f; + x400_24_hitByPlayerProjectile = false; + } else { + x854_ += dt; + } + if (!x6a0_25_isAquaPirate && xc4_fluidId != kInvalidUniqueId) { + if (TCastToPtr water = mgr.ObjectById(xc4_fluidId)) { + const zeus::CAABox& box = water->GetTriggerBoundsWR(); + if (2.f + GetTranslation().z() < box.max.z()) { + x401_30_pendingDeath = true; + } + } + } + } + + if (x450_bodyController->GetPercentageFrozen() == 0.f) { + x86c_ = std::max(0.f, x86c_ - dt); + x860_ = std::max(0.f, x860_ - dt); + x888_ = std::max(0.f, x888_ - dt); + if (x6a0_31_canSeePlayer) { + x7d8_ += dt; + } else { + x7d8_ = 0.f; + } + if (x400_25_alive) { + CheckForProjectiles(mgr); + } + if (!x6a0_25_isAquaPirate && + (!x400_25_alive || !(!x450_bodyController->GetBodyStateInfo().GetCurrentState()->CanShoot() || !x6a0_28_ || + x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack || + x6a1_31_stopped || x450_bodyController->IsElectrocuting()))) { + if (x7ec_burstFire.GetBurstType() != -1) { + x7e4_ -= dt; + if (x7e4_ < 0.f) { + s32 newType = x7ec_burstFire.GetBurstType() & ~1; + if (!PlayerSpot(mgr, 0.f)) { + newType += 1; + } + x7ec_burstFire.SetBurstType(newType); + x7ec_burstFire.Start(mgr); + if (x400_25_alive) { + x7e4_ = x308_attackTimeVariation * mgr.GetActiveRandom()->Float() + x304_averageAttackTime; + const zeus::CVector3f& dist = + (GetBoundingBox().center() - mgr.GetPlayer().GetAimPosition(mgr, 0.f)).normalized(); + if (dist.magSquared() < 0.9f) { + for (const auto& obj : *mgr.ObjectListById(EGameObjectList::AiWaypoint)) { + if (const CSpacePirate* pirate = CPatterned::CastTo(obj)) { + if (pirate->GetEnableAim() && pirate->GetAreaIdAlways() == x4_areaId) { + x7e4_ += 0.2f; + } + } + } + } + } else { + x7e4_ = 22050.f; + } + } + + x7ec_burstFire.Update(mgr, dt); + if (x7ec_burstFire.ShouldFire()) { + FireProjectile(mgr, dt); + if (0.f < x7ec_burstFire.GetTimeToNextShot()) { + x7ec_burstFire.SetTimeToNextShot(x568_data.xd4_ * (mgr.GetActiveRandom()->Float() - 0.5f) + x568_data.xd0_); + } + } + } + } + } + + if (x89c_ragDoll && x89c_ragDoll->IsPrimed()) { + UpdateAlphaDelta(dt, mgr); + UpdateDamageColor(dt); + } else { + if (!x400_25_alive || x450_bodyController->IsFrozen() || x450_bodyController->IsElectrocuting() || !x6a0_28_ || + x89c_ragDoll || x6a0_25_isAquaPirate) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::AdditiveIdle)); + } else { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCAdditiveAimCmd()); + x450_bodyController->GetCommandMgr().DeliverAdditiveTargetVector( + GetTransform().transposeRotate(GetTargetPos(mgr) - GetTranslation())); + } + if (0.f < x870_.magSquared()) { + float mag = x870_.magnitude(); + float fVar5 = 0.2f; + if (0.f == x87c_.magSquared()) { + fVar5 = 0.2f * 3.f; + } + float mul = -(dt * mag * fVar5 * mag - mag); + x870_ = mul * (1.f / mag) * x870_; + } + pas::EAnimationState state = x450_bodyController->GetCurrentStateId(); + if (!x400_25_alive || state == pas::EAnimationState::LoopReaction || state == pas::EAnimationState::Hurled || + state == pas::EAnimationState::LieOnGround || state == pas::EAnimationState::Getup) { + x870_.zeroOut(); + x87c_.zeroOut(); + } else { + ApplyImpulseWR(xe8_mass * x870_, {}); + } + + if (const auto& handle = GetSfxHandle()) { + x898_ = std::clamp(x898_, 1.f, 1.999f); + x894_pitchBend += std::clamp(x898_ - x894_pitchBend, -dt, dt); + CSfxManager::PitchBend(handle, x894_pitchBend); + } + + x87c_.zeroOut(); + x898_ = 1.f; + CPatterned::Think(dt, mgr); + + zeus::CVector3f vf8 = x87c_; + if (vf8.canBeNormalized()) { + vf8.normalize(); + } + zeus::CVector3f v1d0 = std::min(0.333f * x87c_.magnitude(), 0.333f) * vf8; + const zeus::CVector3f& v104 = (zeus::skUp + v1d0).normalized(); + const zeus::CVector3f& v110 = GetTransform().upVector(); + float f26c = std::abs(zeus::CVector3f::getAngleDiff(v110, v104)); + if (f26c > 0.f) { + float f1f4 = std::min(f26c, 30.f * zeus::degToRad(dt)); // ? + float f200 = f26c - f1f4; + zeus::CVector3f v1dc = (f1f4 * v104 + (f200 * v110)).normalized(); + zeus::CVector3f v128 = GetTransform().frontVector().cross(v1dc); + zeus::CVector3f v20c = v1dc.cross(v128).normalized(); + zeus::CVector3f v128_2 = v20c.cross(v1dc); + SetTransform({v128_2, v20c, v1dc, GetTranslation()}); + } + + if (!x450_bodyController->IsFrozen()) { + x7a0_boneTracking.Update(dt); + } + } + + if (x89c_ragDoll) { + if (x89c_ragDoll->IsPrimed()) { + float waterTop = -FLT_MAX; + if (xc4_fluidId != kInvalidUniqueId) { + if (TCastToPtr water = mgr.ObjectById(xc4_fluidId)) { + waterTop = water->GetTriggerBoundsWR().max.z(); + } + } + x89c_ragDoll->Update(mgr, dt * CalcDyingThinkRate(), waterTop); + x64_modelData->AdvanceParticles(GetTransform(), dt, mgr); + } else { + // SetMuted(true); ?? + SetMuted(false); + x89c_ragDoll->Prime(mgr, GetTransform(), *x64_modelData); + SetTransform(zeus::CTransform::Translate(GetTranslation())); + x450_bodyController->SetPlaybackRate(0.f); + } + + if (x89c_ragDoll->IsOver() && !x400_27_fadeToDeath) { + x400_27_fadeToDeath = true; + x3e8_alphaDelta = -1.f / 3.f; + SetVelocityWR(zeus::skZero3f); + x150_momentum.zeroOut(); + x870_.zeroOut(); + } + + bool wasGtZero = x88c_ragDollTimer > 0.f; + x88c_ragDollTimer -= dt; + if (x88c_ragDollTimer < 2.f) { + if (x89c_ragDoll->GetImpactCount() > 2) { + x88c_ragDollTimer = std::min(0.1f, x88c_ragDollTimer); + } + if (wasGtZero && x88c_ragDollTimer <= 0.f) { + x330_stateMachineState.SetState(mgr, *this, GetStateMachine(), "Explode"); + } + } + } +} + } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CFlyingPirate.hpp b/Runtime/MP1/World/CFlyingPirate.hpp index dc89c37c4..f705b1abc 100644 --- a/Runtime/MP1/World/CFlyingPirate.hpp +++ b/Runtime/MP1/World/CFlyingPirate.hpp @@ -1,13 +1,218 @@ #pragma once +#include "Runtime/Character/CBoneTracking.hpp" +#include "Runtime/Character/CRagDoll.hpp" +#include "Runtime/Particle/CElementGen.hpp" +#include "Runtime/Weapon/CBurstFire.hpp" +#include "Runtime/Weapon/CProjectileInfo.hpp" +#include "Runtime/World/CAi.hpp" +#include "Runtime/World/CPathFindSearch.hpp" #include "Runtime/World/CPatterned.hpp" namespace urde::MP1 { +enum class EFlyingPirateType : u32 { + FlyingPirate = 1, + AquaPirate = 2, +}; + class CFlyingPirate : public CPatterned { public: DEFINE_PATTERNED(FlyingPirate) +private: + class CFlyingPirateData { + friend class CFlyingPirate; + float x0_maxCoverDistance; + float x4_hearingDistance; + EFlyingPirateType x8_type; + CProjectileInfo xc_gunProjectileInfo; + u16 x34_gunSfx; + CProjectileInfo x38_altProjectileInfo1; + CProjectileInfo x60_altProjectileInfo2; + float x88_knockBackDelay; + float x8c_flyingHeight; + TCachedToken x90_particleGenDesc; + CDamageInfo x9c_dInfo; + float xb8_; + float xbc_; + float xc0_; + float xc4_; + u16 xc8_ragDollSfx1; + u16 xca_ragDollSfx2; + float xcc_coverCheckChance; + float xd0_; + float xd4_; + CAssetId xd8_particleGen1; + CAssetId xdc_particleGen2; + CAssetId xe0_particleGen3; + u16 xe4_knockBackSfx; + u16 xe6_deathSfx; + float xe8_aggressionChance; + float xec_; + float xf0_projectileHomingDistance; + + public: + CFlyingPirateData(CInputStream& in, u32 propCount); + }; + + class CFlyingPirateRagDoll : public CRagDoll { + private: + CFlyingPirate* x6c_actor; + float x70_ = 0.f; + zeus::CVector3f x74_ = zeus::skUp; + float x80_ = 0.f; + float x84_ = 5.f; + u16 x88_sfx; + float x8c_ = 0.f; + zeus::CVector3f x90_ = zeus::skZero3f; + u16 x9c_; + CSfxHandle xa0_; + zeus::CVector3f xa4_; + bool xb0_24_ : 1; + + public: + CFlyingPirateRagDoll(CStateManager& mgr, CFlyingPirate* actor, u16 w1, u16 w2); + + void PreRender(const zeus::CVector3f& v, CModelData& mData) override; + void Prime(CStateManager& mgr, const zeus::CTransform& xf, CModelData& mData) override; + void Update(CStateManager& mgr, float dt, float waterTop) override; + }; + +public: CFlyingPirate(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, const CActorParameters&, const CPatternedInfo&, CInputStream&, u32); + + void Accept(IVisitor& visitor) override { visitor.Visit(this); } + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) override; + bool AnimOver(CStateManager& mgr, float arg) override; + void CalculateRenderBounds() override; + void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; + void MassiveDeath(CStateManager& mgr) override; + float GetGravityConstant() const override { return x6a0_25_isAquaPirate ? 5.f : 50.f; } + CPathFindSearch* GetSearchPath() override { return &x6a8_pathFindSearch; } + bool IsListening() const override { return true; } + bool KnockbackWhenFrozen() const override { return false; } + bool Listen(const zeus::CVector3f& pos, EListenNoiseType type) override; + void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; + CProjectileInfo* GetProjectileInfo() override { return &x568_data.xc_gunProjectileInfo; } + void Think(float dt, CStateManager& mgr) override; + + void Attack(CStateManager& mgr, EStateMsg msg, float arg) override; + void Bounce(CStateManager& mgr, EStateMsg msg, float arg) override; + void Deactivate(CStateManager& mgr, EStateMsg msg, float arg) override; + void Dead(CStateManager& mgr, EStateMsg msg, float arg) override; + void Dodge(CStateManager& mgr, EStateMsg msg, float arg) override; + void Enraged(CStateManager& mgr, EStateMsg msg, float arg) override; + void Explode(CStateManager& mgr, EStateMsg msg, float arg) override; + void GetUp(CStateManager& mgr, EStateMsg msg, float arg) override; + void Jump(CStateManager& mgr, EStateMsg msg, float arg) override; + void KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, + bool inDeferred, float magnitude) override; + void Land(CStateManager& mgr, EStateMsg msg, float arg) override; + void Lurk(CStateManager& mgr, EStateMsg msg, float arg) override; + void PathFind(CStateManager& mgr, EStateMsg msg, float arg) override; + void Patrol(CStateManager& mgr, EStateMsg msg, float arg) override; + void ProjectileAttack(CStateManager& mgr, EStateMsg msg, float arg) override; + void Retreat(CStateManager& mgr, EStateMsg msg, float arg) override; + void TargetPatrol(CStateManager& mgr, EStateMsg msg, float arg) override; + void Taunt(CStateManager& mgr, EStateMsg msg, float arg) override; + void TurnAround(CStateManager& mgr, EStateMsg msg, float arg) override; + void Walk(CStateManager& mgr, EStateMsg msg, float arg) override; + + bool AggressionCheck(CStateManager& mgr, float arg) override; + bool Attacked(CStateManager& mgr, float arg) override; + bool CoverCheck(CStateManager& mgr, float arg) override; + bool CoverFind(CStateManager& mgr, float arg) override; + bool HearPlayer(CStateManager& mgr, float arg) override; + bool HearShot(CStateManager& mgr, float arg) override; + bool InPosition(CStateManager& mgr, float arg) override; + bool InRange(CStateManager& mgr, float arg) override; + bool Landed(CStateManager& mgr, float arg) override; + bool LineOfSight(CStateManager& mgr, float arg) override; + bool PatternOver(CStateManager& mgr, float arg) override; + bool ShotAt(CStateManager& mgr, float arg) override; + bool ShouldAttack(CStateManager& mgr, float arg) override; + bool ShouldDodge(CStateManager& mgr, float arg) override; + bool ShouldMove(CStateManager& mgr, float arg) override; + bool ShouldRetreat(CStateManager& mgr, float arg) override; + bool ShouldSpecialAttack(CStateManager& mgr, float arg) override; + bool SpotPlayer(CStateManager& mgr, float arg) override; + bool Stuck(CStateManager& mgr, float arg) override; + +private: + CFlyingPirateData x568_data; + rstl::reserved_vector, 3> x65c_particleGenDescs; + // was rstl::reserved_vector, 3> + rstl::reserved_vector, 3> x684_particleGens; + bool x6a0_24_isFlyingPirate : 1; + bool x6a0_25_isAquaPirate : 1; + bool x6a0_26_hearShot : 1; + bool x6a0_27_canPatrol : 1; + bool x6a0_28_ : 1; + bool x6a0_29_checkForProjectiles : 1; + bool x6a0_30_ : 1; + bool x6a0_31_canSeePlayer : 1; + bool x6a1_24_prevInCineCam : 1; + bool x6a1_25_ : 1; + bool x6a1_26_isAttackingObject : 1; + bool x6a1_27_ : 1; + bool x6a1_28_ : 1; + bool x6a1_29_isMoving : 1; + bool x6a1_30_spinToDeath : 1; + bool x6a1_31_stopped : 1; + bool x6a2_24_aggressive : 1; + bool x6a2_25_aggressionChecked : 1; + bool x6a2_26_jetpackActive : 1; + bool x6a2_27_sparksActive : 1; + bool x6a2_28_ : 1; + TUniqueId x6a4_currentCoverPoint = kInvalidUniqueId; + TUniqueId x6a6_id2 = kInvalidUniqueId; + CPathFindSearch x6a8_pathFindSearch; + float x78c_ = 0.f; // not initialized in constructor? + int x790_ = 0; + int x794_health; + CSegId x798_headSegId; + int x79c_ = -1; + CBoneTracking x7a0_boneTracking; + float x7d8_ = 0.f; + int x7dc_ = 0; + CSegId x7e0_gunSegId; + float x7e4_ = 1.f; + TUniqueId x7e8_targetId = kInvalidUniqueId; + CBurstFire x7ec_burstFire; + pas::EStepDirection x84c_dodgeDirection = pas::EStepDirection::Invalid; + float x850_height = 3.f; + float x854_ = FLT_MAX; + float x858_ = FLT_MAX; + TUniqueId x85c_attackObjectId = kInvalidUniqueId; + float x860_ = 15.f; + rstl::reserved_vector x864_missileSegments; + float x86c_ = 0.f; + zeus::CVector3f x870_ = zeus::skZero3f; + zeus::CVector3f x87c_ = zeus::skZero3f; + float x888_ = 10.f; + float x88c_ragDollTimer = 3.f; + TUniqueId x890_teamAiMgr = kInvalidUniqueId; + float x894_pitchBend = 1.f; + float x898_ = 1.f; + std::unique_ptr x89c_ragDoll; + TUniqueId x8a0_patrolTarget = kInvalidUniqueId; + float x8a4_ = 0.f; + + zeus::CVector3f AvoidActors(CStateManager& mgr); + bool CanFireMissiles(CStateManager& mgr); + void CheckForProjectiles(CStateManager& mgr); + void FireProjectile(CStateManager& mgr, float dt); + pas::EStepDirection GetDodgeDirection(CStateManager& mgr, float arg); + zeus::CVector3f GetTargetPos(CStateManager& mgr); + bool LineOfSightTest(CStateManager& mgr, const zeus::CVector3f& start, const zeus::CVector3f& end, + CMaterialList exclude); + void UpdateLandingSmoke(CStateManager& mgr, bool active); + void UpdateParticleEffects(CStateManager& mgr, float intensity, bool active); + void DeliverGetUp(); + void UpdateCanSeePlayer(CStateManager& mgr); + void AddToTeam(CStateManager& mgr); + void RemoveFromTeam(CStateManager& mgr); }; -} // namespace urde::MP1 \ No newline at end of file +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp new file mode 100644 index 000000000..b84047e5b --- /dev/null +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -0,0 +1,335 @@ +#include "Runtime/MP1/World/CGrenadeLauncher.hpp" + +#include "Runtime/Character/CPASAnimParm.hpp" +#include "Runtime/Character/CPASAnimParmData.hpp" +#include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Weapon/CGameProjectile.hpp" +#include "Runtime/World/CExplosion.hpp" +#include "Runtime/World/CPatterned.hpp" +#include "Runtime/World/CPlayer.hpp" + +namespace urde::MP1 { +CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const CEntityInfo& info, + const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& bounds, + const CHealthInfo& healthInfo, const CDamageVulnerability& vulnerability, + const CActorParameters& actParams, TUniqueId parentId, + const SGrenadeLauncherData& data, float f1) +: CPhysicsActor(uid, true, name, info, xf, std::move(mData), {EMaterialTypes::Character, EMaterialTypes::Solid}, bounds, + SMoverData{1000.f}, actParams, 0.3f, 0.1f) +, x25c_healthInfo(healthInfo) +, x264_vulnerability(vulnerability) +, x2cc_parentId(parentId) +, x2d0_data(data) +, x328_cSphere({{}, mData.GetScale().z()}, {EMaterialTypes::Character, EMaterialTypes::Solid}) +, x350_grenadeActorParams(actParams) +, x3e8_thermalMag(actParams.GetThermalMag()) +, x3f8_explodePlayerDistance(f1) { + if (data.GetExplosionGenDescId().IsValid()) { + x3b8_particleGenDesc = g_SimplePool->GetObj({SBIG('PART'), data.GetExplosionGenDescId()}); + } + GetModelData()->EnableLooping(true); + const CPASDatabase& pasDatabase = GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase(); + for (size_t i = 0; i < x3c8_animIds.size(); ++i) { + const auto result = pasDatabase.FindBestAnimation(CPASAnimParmData{22, CPASAnimParm::FromEnum(int(i))}, -1); + x3c8_animIds[i] = result.second; + } +} + +zeus::CVector3f CGrenadeLauncher::GrenadeTarget(const CStateManager& mgr) { + const zeus::CVector3f aim = mgr.GetPlayer().GetAimPosition(mgr, 1.f); + if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed) { + return aim - zeus::CVector3f{0.f, 0.f, 0.5f * mgr.GetPlayer().GetEyeHeight()}; + } + return aim; +} + +void CGrenadeLauncher::CalculateGrenadeTrajectory(const zeus::CVector3f& target, const zeus::CVector3f& origin, + const SGrenadeTrajectoryInfo& info, float& angleOut, + float& velocityOut) { + float angle = info.GetAngleMin(); + float velocity = info.GetVelocityMin(); + float delta = std::max(0.01f, 0.1f * (info.GetAngleMax() - info.GetAngleMin())); + zeus::CVector3f dist = target - origin; + float distXYMag = dist.toVec2f().magnitude(); + float velocityMinSq = info.GetVelocityMin() * info.GetVelocityMin(); + float velocityMaxSq = info.GetVelocityMax() * info.GetVelocityMax(); + float gravAdj = distXYMag * ((0.5f * CPhysicsActor::GravityConstant()) * distXYMag); + float currAngle = info.GetAngleMin(); + float leastResult = FLT_MAX; + while (info.GetAngleMax() >= currAngle) { + float cos = std::cos(currAngle); + float sin = std::sin(currAngle); + float result = (distXYMag * (cos * sin) - (dist.z() * (cos * cos))); + if (result > FLT_EPSILON) { + float div = gravAdj / result; + if (velocityMinSq <= result && result <= velocityMaxSq) { + angle = currAngle; + velocity = std::sqrt(div); + break; + } + if (result <= velocityMaxSq) { + result = velocityMinSq - result; + } else { + result = result - velocityMaxSq; + } + if (result < leastResult) { + angle = currAngle; + velocity = std::sqrt(div); + leastResult = result; + } + } + currAngle += delta; + } + angleOut = angle; + velocityOut = velocity; +} + +void CGrenadeLauncher::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + CActor::AcceptScriptMsg(msg, uid, mgr); + switch (msg) { + case EScriptObjectMessage::Start: + if (x2cc_parentId == uid && x258_started != 1) { + x258_started = 1; + sub_80230438(); + } + break; + case EScriptObjectMessage::Stop: + if (x2cc_parentId == uid && x258_started != 0) { + x258_started = 0; + sub_80230438(); + } + break; + case EScriptObjectMessage::Action: + if (x2cc_parentId == uid && x258_started == 1) { + x3fc_launchGrenade = true; + } + break; + case EScriptObjectMessage::Registered: + sub_80230438(); + break; + case EScriptObjectMessage::Damage: + x3ec_damageTimer = 0.33f; + break; + default: + break; + } +} + +void CGrenadeLauncher::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { + CActor::AddToRenderer(frustum, mgr); +} + +std::optional CGrenadeLauncher::GetTouchBounds() const { + return x328_cSphere.CalculateAABox(GetTransform()); +} + +void CGrenadeLauncher::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { + if (x3f4_color3.a() == 1.f) { + xb4_drawFlags = CModelFlags{2, 0, 3, zeus::skWhite}; + // Original code redundantly sets a() = 1.f + xb4_drawFlags.addColor = x3f4_color3; + } else { + xb4_drawFlags = CModelFlags{5, 0, 3, zeus::skWhite}; + xb4_drawFlags.addColor = x3f4_color3; + } + CActor::PreRender(mgr, frustum); +} + +void CGrenadeLauncher::Render(CStateManager& mgr) { + if (x3fd_visible) { + CPhysicsActor::Render(mgr); + } +} + +void CGrenadeLauncher::Think(float dt, CStateManager& mgr) { + if (GetActive()) { + if (x3fc_launchGrenade) { + LaunchGrenade(mgr); + x3fc_launchGrenade = false; + } + + UpdateCollision(); + UpdateColor(dt); + sub_8022f9e0(mgr, dt); + UpdateDamageTime(dt); + + const SAdvancementDeltas& deltas = CActor::UpdateAnimation(dt, mgr, true); + MoveToOR(deltas.x0_posDelta, dt); + RotateToOR(deltas.xc_rotDelta, dt); + + TCastToPtr parent = mgr.ObjectById(x2cc_parentId); + if (parent == nullptr || !parent->IsAlive() || parent->HealthInfo(mgr)->GetHP() <= 0.f) { + mgr.SendScriptMsg(parent, GetUniqueId(), EScriptObjectMessage::Damage); + CreateExplosion(mgr); + mgr.FreeScriptObject(GetUniqueId()); + } + } +} + +void CGrenadeLauncher::Touch(CActor& act, CStateManager& mgr) { + if (TCastToPtr projectile = act) { + if (projectile->GetOwnerId() == mgr.GetPlayer().GetUniqueId() && + GetDamageVulnerability()->WeaponHurts(CWeaponMode{projectile->GetType()}, false)) { + x348_shotTimer = 0.5f; + CEntity* parent = mgr.ObjectById(x2cc_parentId); + if (parent != nullptr) { + mgr.SendScriptMsg(parent, GetUniqueId(), EScriptObjectMessage::Touched); + } + } + } +} + +void CGrenadeLauncher::UpdateCollision() { + x328_cSphere.SetSphereCenter(GetLocatorTransform("lockon_target_LCTR"sv).origin); +} + +void CGrenadeLauncher::UpdateColor(float arg) { + if (x348_shotTimer > 0.f) { + x348_shotTimer = std::max(0.f, x348_shotTimer - arg); + x34c_color1 = zeus::CColor::lerp(zeus::skWhite, zeus::skRed, x348_shotTimer); + } +} + +void CGrenadeLauncher::UpdateDamageTime(float arg) { + if (x3ec_damageTimer <= 0.f) { + xd0_damageMag = x3e8_thermalMag; + } else { + x3ec_damageTimer = std::max(0.f, x3ec_damageTimer - arg); + x3f4_color3 = zeus::CColor::lerp(zeus::skBlack, x3f0_color2, std::clamp(x3ec_damageTimer / 0.33f, 0.f, 1.f)); + xd0_damageMag = 5.f * x3ec_damageTimer + x3e8_thermalMag; + } +} + +void CGrenadeLauncher::CreateExplosion(CStateManager& mgr) { + if (!x3b8_particleGenDesc) { + return; + } + mgr.AddObject(new CExplosion(*x3b8_particleGenDesc, mgr.AllocateUniqueId(), true, + {GetAreaIdAlways(), CEntity::NullConnectionList}, "Grenade Launcher Explode Fx"sv, + GetTransform(), 0, GetModelData()->GetScale(), zeus::skWhite)); + CSfxManager::SfxStart(x2d0_data.GetExplosionSfx(), 1.f, 1.f, false, 0x7f, false, kInvalidAreaId); +} + +void CGrenadeLauncher::sub_8022f9e0(CStateManager& mgr, float dt) { + CModelData* modelData = GetModelData(); + CAnimData* animData = nullptr; + + if (modelData != nullptr && (animData = modelData->GetAnimationData()) != nullptr && x258_started == 1 && x3fe_) { + const zeus::CVector3f target = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation(); + const zeus::CVector3f rot = GetTransform().rotate({target.x(), target.y(), 0.f}); // TODO double check + + if (rot.canBeNormalized()) { + constexpr float p36d = zeus::degToRad(36.476f); + constexpr float n45d = zeus::degToRad(-45.f); + constexpr float p45d = zeus::degToRad(45.f); + + float l84 = p36d * std::clamp(std::atan2(rot.x(), rot.y()), n45d, p45d); + float l88 = std::clamp((0.25f * (l84 - x3d8_)) / dt, -3.f, 3.f); + float l8c = std::clamp((l88 - x3dc_) / dt, -10.f, 10.f); + x3dc_ += dt * l8c; + + float l90 = p36d * std::clamp(std::atan2(rot.z(), rot.toVec2f().magnitude()), n45d, p45d); + l88 = std::clamp((0.25f * (l90 - x3e0_)) / dt, -3.f, 3.f); + l8c = std::clamp((l88 - x3e4_) / dt, -10.f, 10.f); + x3e4_ += dt * l8c; + + float dVar7 = std::clamp(dt * x3dc_ + x3d8_, -0.5f, 0.5f); + float dVar8 = std::clamp(dt * x3e4_ + x3e0_, -0.5f, 0.5f); + + if (dVar7 != x3d8_) { + if (std::abs(x3d8_) > 0.f && x3d8_ * dVar7 <= 0.f) { + animData->DelAdditiveAnimation(x3c8_animIds[x3d8_ >= 0.f ? 1 : 0]); + } + float weight = std::abs(dVar7); + if (weight > 0.f) { + animData->AddAdditiveAnimation(x3c8_animIds[dVar7 >= 0.f ? 1 : 0], weight, false, false); + } + } + if (dVar8 != x3e0_) { + if (std::abs(x3e0_) > 0.f && x3e0_ * dVar8 <= 0.f) { + animData->DelAdditiveAnimation(x3c8_animIds[x3e0_ <= 0.f ? 3 : 2]); + } + float weight = std::abs(dVar8); + if (weight > 0.f) { + animData->AddAdditiveAnimation(x3c8_animIds[dVar8 <= 0.f ? 3 : 2], weight, false, false); + } + } + x3d8_ = dVar7; + x3e0_ = dVar8; + } + } else { + if (x3d8_ != 0.f) { + if (animData != nullptr) { // Original code does not check + animData->DelAdditiveAnimation(x3c8_animIds[x3d8_ >= 0.f ? 1 : 0]); + } + x3d8_ = 0.f; + } + if (x3e0_ != 0.f) { + if (animData != nullptr) { // Original code does not check + animData->DelAdditiveAnimation(x3c8_animIds[x3e0_ <= 0.f ? 3 : 2]); + } + x3e0_ = 0.f; + } + } +} + +void CGrenadeLauncher::sub_80230438() { + CModelData* modelData = GetModelData(); + CAnimData* animData; + if (modelData == nullptr || (animData = modelData->GetAnimationData()) == nullptr || x258_started <= -1 || + x258_started >= 2) { + return; + } + + constexpr std::array arr{0, 3}; + const auto anim = animData->GetCharacterInfo().GetPASDatabase().FindBestAnimation( + CPASAnimParmData{5, CPASAnimParm::FromEnum(0), CPASAnimParm::FromEnum(arr[x258_started])}, -1); + if (anim.first > 0.f) { + animData->SetAnimation({anim.second, -1, 1.f, true}, false); + modelData->EnableLooping(true); + } +} + +void CGrenadeLauncher::LaunchGrenade(CStateManager& mgr) { + CModelData* modelData = GetModelData(); + CAnimData* animData; + if (modelData == nullptr || (animData = modelData->GetAnimationData()) == nullptr) { + return; + } + + const auto& anim = animData->GetCharacterInfo().GetPASDatabase().FindBestAnimation(CPASAnimParmData{23}, -1); + if (anim.first > 0.f) { + animData->AddAdditiveAnimation(anim.second, 1.f, false, true); + const zeus::CVector3f origin = + GetTranslation() + GetTransform().rotate(GetLocatorTransform("grenade_LCTR"sv).origin); + const zeus::CVector3f target = GrenadeTarget(mgr); + float angleOut = x2d0_data.GetGrenadeTrajectoryInfo().GetAngleMin(); + float velocityOut = x2d0_data.GetGrenadeTrajectoryInfo().GetVelocityMin(); + CalculateGrenadeTrajectory(target, origin, x2d0_data.GetGrenadeTrajectoryInfo(), angleOut, velocityOut); + + zeus::CVector3f dist = target - origin; + dist.z() = 0.f; + const zeus::CVector3f front = GetTransform().frontVector(); + if (dist.canBeNormalized()) { + dist.normalize(); + } else { + dist = front; + } + + constexpr float maxAngle = zeus::degToRad(45.f); + if (zeus::CVector3f::getAngleDiff(front, dist) > maxAngle) { + dist = zeus::CVector3f::slerp(front, dist, maxAngle); + } + + const zeus::CVector3f look = zeus::CVector3f::slerp(dist, zeus::skUp, angleOut); + const zeus::CTransform xf = zeus::lookAt(origin, origin + look, zeus::skUp); + CModelData mData{CStaticRes{x2d0_data.GetGrenadeModelId(), GetModelData()->GetScale()}}; + mgr.AddObject(new CBouncyGrenade(mgr.AllocateUniqueId(), "Bouncy Grenade"sv, + {GetAreaIdAlways(), CEntity::NullConnectionList}, xf, std::move(mData), + x350_grenadeActorParams, x2cc_parentId, x2d0_data.GetGrenadeData(), velocityOut, + x3f8_explodePlayerDistance)); + } +} +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CGrenadeLauncher.hpp b/Runtime/MP1/World/CGrenadeLauncher.hpp new file mode 100644 index 000000000..10cfa1d6e --- /dev/null +++ b/Runtime/MP1/World/CGrenadeLauncher.hpp @@ -0,0 +1,124 @@ +#pragma once + +#include "Runtime/Character/CModelData.hpp" +#include "Runtime/Collision/CCollidableSphere.hpp" +#include "Runtime/MP1/World/CBouncyGrenade.hpp" +#include "Runtime/Particle/CGenDescription.hpp" +#include "Runtime/World/CActorParameters.hpp" +#include "Runtime/World/CDamageInfo.hpp" +#include "Runtime/World/CDamageVulnerability.hpp" +#include "Runtime/World/CEntityInfo.hpp" +#include "Runtime/World/CHealthInfo.hpp" +#include "Runtime/World/CPhysicsActor.hpp" + +#include "TCastTo.hpp" // Generated file, do not modify include path + +#include +#include +#include +#include +#include + +namespace urde::MP1 { +struct SGrenadeTrajectoryInfo { +private: + float x0_velocityMin; + float x4_velocityMax; + float x8_angleMin; + float xc_angleMax; + +public: + explicit SGrenadeTrajectoryInfo(CInputStream& in) + : x0_velocityMin(in.readFloatBig()) + , x4_velocityMax(in.readFloatBig()) + , x8_angleMin(zeus::degToRad(in.readFloatBig())) + , xc_angleMax(zeus::degToRad(in.readFloatBig())) {} + + [[nodiscard]] float GetVelocityMin() const { return x0_velocityMin; } + [[nodiscard]] float GetVelocityMax() const { return x4_velocityMax; } + [[nodiscard]] float GetAngleMin() const { return x8_angleMin; } + [[nodiscard]] float GetAngleMax() const { return xc_angleMax; } +}; + +struct SGrenadeLauncherData { +private: + SBouncyGrenadeData x0_grenadeData; + CAssetId x3c_grenadeCmdl; + CAssetId x40_launcherExplodeGenDesc; + u16 x44_launcherExplodeSfx; + SGrenadeTrajectoryInfo x48_trajectoryInfo; + +public: + SGrenadeLauncherData(const SBouncyGrenadeData& data, CAssetId w1, CAssetId w2, u16 sfx, + const SGrenadeTrajectoryInfo& trajectoryInfo) + : x0_grenadeData(data) + , x3c_grenadeCmdl(w1) + , x40_launcherExplodeGenDesc(w2) + , x44_launcherExplodeSfx(sfx) + , x48_trajectoryInfo(trajectoryInfo){}; + + [[nodiscard]] const SBouncyGrenadeData& GetGrenadeData() const { return x0_grenadeData; } + [[nodiscard]] CAssetId GetGrenadeModelId() const { return x3c_grenadeCmdl; } + [[nodiscard]] CAssetId GetExplosionGenDescId() const { return x40_launcherExplodeGenDesc; } + [[nodiscard]] u16 GetExplosionSfx() const { return x44_launcherExplodeSfx; } + [[nodiscard]] const SGrenadeTrajectoryInfo& GetGrenadeTrajectoryInfo() const { return x48_trajectoryInfo; } +}; + +class CGrenadeLauncher : public CPhysicsActor { +private: + int x258_started = 0; + CHealthInfo x25c_healthInfo; + CDamageVulnerability x264_vulnerability; + TUniqueId x2cc_parentId; + SGrenadeLauncherData x2d0_data; + CCollidableSphere x328_cSphere; + float x348_shotTimer = -1.f; + zeus::CColor x34c_color1{1.f}; + CActorParameters x350_grenadeActorParams; + std::optional> x3b8_particleGenDesc; + std::array x3c8_animIds{}; + float x3d8_ = 0.f; + float x3dc_ = 0.f; + float x3e0_ = 0.f; + float x3e4_ = 0.f; + float x3e8_thermalMag; + float x3ec_damageTimer = 0.f; + zeus::CColor x3f0_color2{0.5f, 0.f, 0.f}; + zeus::CColor x3f4_color3{0.f}; + float x3f8_explodePlayerDistance; + bool x3fc_launchGrenade = false; + bool x3fd_visible = true; + bool x3fe_ = true; + +public: + CGrenadeLauncher(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const zeus::CAABox& bounds, const CHealthInfo& healthInfo, + const CDamageVulnerability& vulnerability, const CActorParameters& actParams, TUniqueId parentId, + const SGrenadeLauncherData& data, float f1); + + void Accept(IVisitor& visitor) override { visitor.Visit(this); } + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) override; + [[nodiscard]] const CCollisionPrimitive* GetCollisionPrimitive() const override { return &x328_cSphere; } + [[nodiscard]] const CDamageVulnerability* GetDamageVulnerability() const override { return &x264_vulnerability; } + [[nodiscard]] std::optional GetTouchBounds() const override; + CHealthInfo* HealthInfo(CStateManager& mgr) override { return &x25c_healthInfo; } + void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; + void Render(CStateManager& mgr) override; + void Think(float dt, CStateManager& mgr) override; + void Touch(CActor& act, CStateManager& mgr) override; + + static zeus::CVector3f GrenadeTarget(const CStateManager& mgr); + static void CalculateGrenadeTrajectory(const zeus::CVector3f& target, const zeus::CVector3f& origin, + const SGrenadeTrajectoryInfo& info, float& angleOut, float& velocityOut); + +private: + void UpdateCollision(); + void UpdateColor(float arg); + void UpdateDamageTime(float arg); + void CreateExplosion(CStateManager& mgr); + void sub_8022f9e0(CStateManager& mgr, float dt); + void sub_80230438(); + void LaunchGrenade(CStateManager& mgr); +}; +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CJellyZap.cpp b/Runtime/MP1/World/CJellyZap.cpp index fc333b99a..ec6e4fc4d 100644 --- a/Runtime/MP1/World/CJellyZap.cpp +++ b/Runtime/MP1/World/CJellyZap.cpp @@ -107,7 +107,7 @@ void CJellyZap::Suck(CStateManager& mgr, EStateMsg msg, float arg) { RemoveAllAttractors(mgr); } else if (msg == EStateMsg::Update) { TryCommand(mgr, pas::EAnimationState::LoopReaction, &CPatterned::TryLoopReaction, 0); - x450_bodyController->GetCommandMgr().SetTargetVector( + x450_bodyController->GetCommandMgr().DeliverTargetVector( (mgr.GetPlayer().GetTranslation() + zeus::CVector3f(0.f, 0.f, 1.f)) - GetTranslation()); float intensity = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit) ? 0.1f : 1.f; @@ -133,7 +133,7 @@ void CJellyZap::Active(CStateManager& mgr, EStateMsg msg, float arg) { } else if (msg == EStateMsg::Update) { zeus::CVector3f targetVector = GetTranslation() - (zeus::CVector3f(0.f, 0.f, 1.f) + mgr.GetPlayer().GetTranslation()); - x450_bodyController->GetCommandMgr().SetTargetVector(targetVector); + x450_bodyController->GetCommandMgr().DeliverTargetVector(targetVector); if (x5b8_26_) { zeus::CVector3f moveToImpulse = GetMoveToORImpulseWR(GetTransform().transposeRotate(arg * (zeus::CVector3f(0.f, 1.f, 0.f) * x598_)), arg); @@ -233,4 +233,4 @@ const CDamageVulnerability* CJellyZap::GetDamageVulnerability(const zeus::CVecto const CDamageInfo& info) const { return CActor::GetDamageVulnerability(pos, dir, info); } -} // namespace urde::MP1 \ No newline at end of file +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CMagdolite.hpp b/Runtime/MP1/World/CMagdolite.hpp index 5c61935ab..9346e6027 100644 --- a/Runtime/MP1/World/CMagdolite.hpp +++ b/Runtime/MP1/World/CMagdolite.hpp @@ -16,7 +16,7 @@ public: float x1c_; public: - CMagdoliteData(CInputStream&); + explicit CMagdoliteData(CInputStream&); }; private: diff --git a/Runtime/MP1/World/CMakeLists.txt b/Runtime/MP1/World/CMakeLists.txt index 4ac6f702a..e0c88ce2e 100644 --- a/Runtime/MP1/World/CMakeLists.txt +++ b/Runtime/MP1/World/CMakeLists.txt @@ -1,42 +1,47 @@ set(MP1_WORLD_SOURCES - CNewIntroBoss.hpp CNewIntroBoss.cpp - CBeetle.hpp CBeetle.cpp - CWarWasp.hpp CWarWasp.cpp - CElitePirate.hpp CElitePirate.cpp - CBloodFlower.hpp CBloodFlower.cpp - CChozoGhost.hpp CChozoGhost.cpp - CSpacePirate.hpp CSpacePirate.cpp - CParasite.hpp CParasite.cpp - CBabygoth.hpp CBabygoth.cpp - CTryclops.hpp CTryclops.cpp - CFireFlea.hpp CFireFlea.cpp - CEnergyBall.hpp CEnergyBall.cpp - CEyeball.hpp CEyeball.cpp + CActorContraption.hpp CActorContraption.cpp CAtomicAlpha.hpp CAtomicAlpha.cpp CAtomicBeta.hpp CAtomicBeta.cpp + CBabygoth.hpp CBabygoth.cpp + CBeetle.hpp CBeetle.cpp + CBloodFlower.hpp CBloodFlower.cpp + CBouncyGrenade.hpp CBouncyGrenade.cpp + CBurrower.hpp CBurrower.cpp + CChozoGhost.hpp CChozoGhost.cpp + CElitePirate.hpp CElitePirate.cpp + CEnergyBall.hpp CEnergyBall.cpp + CEyeball.hpp CEyeball.cpp + CFireFlea.hpp CFireFlea.cpp + CFlaahgra.hpp CFlaahgra.cpp + CFlaahgraProjectile.hpp CFlaahgraProjectile.cpp + CFlaahgraTentacle.hpp CFlaahgraTentacle.cpp CFlickerBat.hpp CFlickerBat.cpp - CJellyZap.hpp CJellyZap.cpp CFlyingPirate.hpp CFlyingPirate.cpp - CMetroidPrimeRelay.hpp CMetroidPrimeRelay.cpp + CGrenadeLauncher.hpp CGrenadeLauncher.cpp + CJellyZap.hpp CJellyZap.cpp + CMagdolite.hpp CMagdolite.cpp + CMetaree.hpp CMetaree.cpp + CMetroid.hpp CMetroid.cpp + CMetroidBeta.hpp CMetroidBeta.cpp CMetroidPrimeExo.hpp CMetroidPrimeExo.cpp CMetroidPrimeProjectile.hpp CMetroidPrimeProjectile.cpp - CActorContraption.hpp CActorContraption.cpp - CThardusRockProjectile.hpp CThardusRockProjectile.cpp - CMetroidBeta.hpp CMetroidBeta.cpp - CMetroid.hpp CMetroid.cpp - CMetaree.hpp CMetaree.cpp - CBurrower.hpp CBurrower.cpp - CPuffer.hpp CPuffer.cpp - CMagdolite.hpp CMagdolite.cpp - CSeedling.hpp CSeedling.cpp - CRidley.hpp CRidley.cpp - CPuddleToadGamma.hpp CPuddleToadGamma.cpp - CFlaahgra.hpp CFlaahgra.cpp - CFlaahgraTentacle.hpp CFlaahgraTentacle.cpp - CFlaahgraProjectile.hpp CFlaahgraProjectile.cpp - CSpankWeed.hpp CSpankWeed.cpp + CMetroidPrimeRelay.hpp CMetroidPrimeRelay.cpp + CNewIntroBoss.hpp CNewIntroBoss.cpp + COmegaPirate.hpp COmegaPirate.cpp + CParasite.hpp CParasite.cpp CPuddleSpore.hpp CPuddleSpore.cpp + CPuddleToadGamma.hpp CPuddleToadGamma.cpp + CPuffer.hpp CPuffer.cpp + CRidley.hpp CRidley.cpp CRipper.hpp CRipper.cpp - CThardus.hpp CThardus.cpp) + CSeedling.hpp CSeedling.cpp + CShockWave.hpp CShockWave.cpp + CSpacePirate.hpp CSpacePirate.cpp + CSpankWeed.hpp CSpankWeed.cpp + CThardus.hpp CThardus.cpp + CThardusRockProjectile.hpp CThardusRockProjectile.cpp + CTryclops.hpp CTryclops.cpp + CWarWasp.hpp CWarWasp.cpp +) runtime_add_list(World MP1_WORLD_SOURCES) diff --git a/Runtime/MP1/World/CMetaree.cpp b/Runtime/MP1/World/CMetaree.cpp index 69a5622aa..55697d0b6 100644 --- a/Runtime/MP1/World/CMetaree.cpp +++ b/Runtime/MP1/World/CMetaree.cpp @@ -144,7 +144,7 @@ void CMetaree::Active(CStateManager& mgr, EStateMsg msg, float) { x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Zero, x584_lookPos)); SetMomentumWR({0.f, 0.f, -GetGravityConstant() * GetMass()}); } else if (msg == EStateMsg::Update) { - x450_bodyController->GetCommandMgr().SetTargetVector( + x450_bodyController->GetCommandMgr().DeliverTargetVector( (mgr.GetPlayer().GetTranslation() - GetTranslation()).normalized()); } else if (msg == EStateMsg::Deactivate) { SetMomentumWR({}); diff --git a/Runtime/MP1/World/CMetroid.hpp b/Runtime/MP1/World/CMetroid.hpp index d9018c6a6..1a547f75c 100644 --- a/Runtime/MP1/World/CMetroid.hpp +++ b/Runtime/MP1/World/CMetroid.hpp @@ -25,7 +25,7 @@ class CMetroidData { bool x128_24_ : 1; public: - CMetroidData(CInputStream& in); + explicit CMetroidData(CInputStream& in); static u32 GetNumProperties() { return skNumProperties; } }; diff --git a/Runtime/MP1/World/CMetroidBeta.cpp b/Runtime/MP1/World/CMetroidBeta.cpp index 5405520de..fac634659 100644 --- a/Runtime/MP1/World/CMetroidBeta.cpp +++ b/Runtime/MP1/World/CMetroidBeta.cpp @@ -170,70 +170,106 @@ void CMetroidBeta::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta break; } } -void CMetroidBeta::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { + +void CMetroidBeta::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { CPatterned::AddToRenderer(frustum, mgr); } -void CMetroidBeta::Render(const CStateManager& mgr) const { CPatterned::Render(mgr); } + +void CMetroidBeta::Render(CStateManager& mgr) { CPatterned::Render(mgr); } + const CDamageVulnerability* CMetroidBeta::GetDamageVulnerability() const { return CAi::GetDamageVulnerability(); } + const CDamageVulnerability* CMetroidBeta::GetDamageVulnerability(const zeus::CVector3f& vec1, const zeus::CVector3f& vec2, const CDamageInfo& dInfo) const { return CActor::GetDamageVulnerability(vec1, vec2, dInfo); } + void CMetroidBeta::Touch(CActor& act, CStateManager& mgr) { CPatterned::Touch(act, mgr); } + zeus::CVector3f CMetroidBeta::GetAimPosition(const CStateManager& mgr, float dt) const { return CPatterned::GetAimPosition(mgr, dt); } + void CMetroidBeta::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType eType, float dt) { CPatterned::DoUserAnimEvent(mgr, node, eType, dt); } + const CCollisionPrimitive* CMetroidBeta::GetCollisionPrimitive() const { return CPhysicsActor::GetCollisionPrimitive(); } + void CMetroidBeta::CollidedWith(TUniqueId collidee, const CCollisionInfoList& info, CStateManager& mgr) { CPatterned::CollidedWith(collidee, info, mgr); } + zeus::CVector3f CMetroidBeta::GetOrigin(const CStateManager& mgr, const CTeamAiRole& role, const zeus::CVector3f& aimPos) const { return CAi::GetOrigin(mgr, role, aimPos); } + void CMetroidBeta::Patrol(CStateManager& mgr, EStateMsg msg, float arg) { CPatterned::Patrol(mgr, msg, arg); } + void CMetroidBeta::PathFind(CStateManager& mgr, EStateMsg msg, float arg) { CPatterned::PathFind(mgr, msg, arg); } + void CMetroidBeta::SelectTarget(CStateManager& mgr, EStateMsg msg, float arg) { CAi::SelectTarget(mgr, msg, arg); } + void CMetroidBeta::TargetPatrol(CStateManager& mgr, EStateMsg msg, float arg) { CPatterned::TargetPatrol(mgr, msg, arg); } + void CMetroidBeta::Generate(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Generate(mgr, msg, arg); } + void CMetroidBeta::Attack(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Attack(mgr, msg, arg); } + void CMetroidBeta::TurnAround(CStateManager& mgr, EStateMsg msg, float arg) { CAi::TurnAround(mgr, msg, arg); } + void CMetroidBeta::TelegraphAttack(CStateManager& mgr, EStateMsg msg, float arg) { CAi::TelegraphAttack(mgr, msg, arg); } + void CMetroidBeta::WallHang(CStateManager& mgr, EStateMsg msg, float arg) { CAi::WallHang(mgr, msg, arg); } + void CMetroidBeta::SpecialAttack(CStateManager& mgr, EStateMsg msg, float arg) { CAi::SpecialAttack(mgr, msg, arg); } + bool CMetroidBeta::InAttackPosition(CStateManager& mgr, float arg) { return CAi::InAttackPosition(mgr, arg); } + bool CMetroidBeta::Attacked(CStateManager& mgr, float arg) { return CPatterned::Attacked(mgr, arg); } + bool CMetroidBeta::PathShagged(CStateManager& mgr, float arg) { return CPatterned::PathShagged(mgr, arg); } + bool CMetroidBeta::InDetectionRange(CStateManager& mgr, float arg) { return CPatterned::InDetectionRange(mgr, arg); } + bool CMetroidBeta::AnimOver(CStateManager& mgr, float arg) { return CPatterned::AnimOver(mgr, arg); } + bool CMetroidBeta::ShouldAttack(CStateManager& mgr, float arg) { return CAi::ShouldAttack(mgr, arg); } + bool CMetroidBeta::InPosition(CStateManager& mgr, float arg) { return CPatterned::InPosition(mgr, arg); } + bool CMetroidBeta::ShouldTurn(CStateManager& mgr, float arg) { return CAi::ShouldTurn(mgr, arg); } + bool CMetroidBeta::AttackOver(CStateManager& mgr, float arg) { return CAi::AttackOver(mgr, arg); } + bool CMetroidBeta::ShotAt(CStateManager& mgr, float arg) { return CAi::ShotAt(mgr, arg); } + bool CMetroidBeta::ShouldWallHang(CStateManager& mgr, float arg) { return CAi::ShouldWallHang(mgr, arg); } + bool CMetroidBeta::StartAttack(CStateManager& mgr, float arg) { return CAi::StartAttack(mgr, arg); } + bool CMetroidBeta::BreakAttack(CStateManager& mgr, float arg) { return CAi::BreakAttack(mgr, arg); } + bool CMetroidBeta::ShouldSpecialAttack(CStateManager& mgr, float arg) { return CAi::ShouldSpecialAttack(mgr, arg); } void CMetroidBeta::RenderHitGunEffect() const {} void CMetroidBeta::RenderHitBallEffect() const {} + static SSphereJointInfo skPelvisInfo[1] { {"Pelvis", 1.5f}, }; + void CMetroidBeta::CreateCollisionActorManager(CStateManager& mgr) { std::vector joints; AddSphereJoints(skPelvisInfo, 1, joints); @@ -272,6 +308,7 @@ void CMetroidBeta::AddSphereJoints(SSphereJointInfo* sphereJoints, s32 count, joints.push_back(CJointCollisionDescription::SphereCollision(id, sphereJoint.radius, sphereJoint.name, 1000.0f)); } } + void CMetroidBeta::SetCollisionActorHealthAndVulnerability(CStateManager& mgr) { CHealthInfo* hInfo = HealthInfo(mgr); if (TCastToPtr colAct = mgr.ObjectById(x790_)) { @@ -279,6 +316,7 @@ void CMetroidBeta::SetCollisionActorHealthAndVulnerability(CStateManager& mgr) { colAct->SetDamageVulnerability(*GetDamageVulnerability()); } } + void CMetroidBeta::RemoveFromTeam(CStateManager& mgr) { if (x678_teamMgr == kInvalidUniqueId) return; @@ -288,6 +326,7 @@ void CMetroidBeta::RemoveFromTeam(CStateManager& mgr) { teamMgr->RemoveTeamAiRole(GetUniqueId()); } } + void CMetroidBeta::AddToTeam(CStateManager& mgr) { if (x678_teamMgr == kInvalidUniqueId) return; diff --git a/Runtime/MP1/World/CMetroidBeta.hpp b/Runtime/MP1/World/CMetroidBeta.hpp index 17386ab6e..5c421dcf6 100644 --- a/Runtime/MP1/World/CMetroidBeta.hpp +++ b/Runtime/MP1/World/CMetroidBeta.hpp @@ -38,7 +38,7 @@ class CMetroidBetaData { bool x108_24_ : 1; public: - CMetroidBetaData(CInputStream&); + explicit CMetroidBetaData(CInputStream&); }; class CMetroidBeta : public CPatterned { s32 x568_progState = -1; @@ -102,8 +102,8 @@ public: void Think(float dt, CStateManager& mgr) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; - void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; - void Render(const CStateManager& mgr) const override; + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) override; + void Render(CStateManager& mgr) override; const CDamageVulnerability* GetDamageVulnerability() const override; const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f& vec1, const zeus::CVector3f& vec2, const CDamageInfo& dInfo) const override; diff --git a/Runtime/MP1/World/CNewIntroBoss.cpp b/Runtime/MP1/World/CNewIntroBoss.cpp index d24dcd8ff..7678f004c 100644 --- a/Runtime/MP1/World/CNewIntroBoss.cpp +++ b/Runtime/MP1/World/CNewIntroBoss.cpp @@ -303,7 +303,7 @@ void CNewIntroBoss::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& nod } } -void CNewIntroBoss::AddToRenderer(const zeus::CFrustum&, const CStateManager& mgr) const { EnsureRendered(mgr); } +void CNewIntroBoss::AddToRenderer(const zeus::CFrustum&, CStateManager& mgr) { EnsureRendered(mgr); } float CNewIntroBoss::GetNextAttackTime(CStateManager& mgr) const { float attackTime = 2.f * mgr.GetActiveRandom()->Float() + 6.f; diff --git a/Runtime/MP1/World/CNewIntroBoss.hpp b/Runtime/MP1/World/CNewIntroBoss.hpp index 844d26f12..75c7c133a 100644 --- a/Runtime/MP1/World/CNewIntroBoss.hpp +++ b/Runtime/MP1/World/CNewIntroBoss.hpp @@ -61,7 +61,7 @@ public: void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager&) override; void Think(float dt, CStateManager& mgr) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; void OnScanStateChanged(EScanState, CStateManager&) override; CProjectileInfo* GetProjectileInfo() override { return &x5ac_projectileInfo; } zeus::CAABox GetSortingBounds(const CStateManager&) const override { diff --git a/Runtime/MP1/World/COmegaPirate.cpp b/Runtime/MP1/World/COmegaPirate.cpp new file mode 100644 index 000000000..16f462ec6 --- /dev/null +++ b/Runtime/MP1/World/COmegaPirate.cpp @@ -0,0 +1,12 @@ +#include "Runtime/MP1/World/COmegaPirate.hpp" + +namespace urde::MP1 { +COmegaPirate::CFlash::CFlash(TUniqueId uid, const CEntityInfo& info, const zeus::CVector3f& pos, CToken& p4, float p5) +: CActor(uid, true, "Omega Pirate Flash", info, zeus::CTransform::Translate(pos), CModelData::CModelDataNull(), {}, + CActorParameters::None(), kInvalidUniqueId) {} + +COmegaPirate::COmegaPirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, + CElitePirateData data, CAssetId w1, CAssetId w2, CAssetId w3) +: CElitePirate(uid, name, info, xf, std::move(mData), pInfo, actParms, data) {} +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/COmegaPirate.hpp b/Runtime/MP1/World/COmegaPirate.hpp new file mode 100644 index 000000000..369393aa5 --- /dev/null +++ b/Runtime/MP1/World/COmegaPirate.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "Runtime/MP1/World/CElitePirate.hpp" + +namespace urde::MP1 { +class COmegaPirate : public CElitePirate { +private: + class CFlash : public CActor { + private: + CToken xe8_; + int xf0_; + float xf4_; + float xf8_; + float xfc_; + + CFlash(TUniqueId uid, const CEntityInfo& info, const zeus::CVector3f& pos, CToken& p4, float p5); + }; + +public: + COmegaPirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, CElitePirateData data, + CAssetId w1, CAssetId w2, CAssetId w3); +}; +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CParasite.cpp b/Runtime/MP1/World/CParasite.cpp index b62efb09c..07fb97d61 100644 --- a/Runtime/MP1/World/CParasite.cpp +++ b/Runtime/MP1/World/CParasite.cpp @@ -303,7 +303,7 @@ void CParasite::Think(float dt, CStateManager& mgr) { x742_27_landed = false; } -void CParasite::Render(const CStateManager& mgr) const { CWallWalker::Render(mgr); } +void CParasite::Render(CStateManager& mgr) { CWallWalker::Render(mgr); } const CDamageVulnerability* CParasite::GetDamageVulnerability() const { switch (x5d0_walkerType) { diff --git a/Runtime/MP1/World/CParasite.hpp b/Runtime/MP1/World/CParasite.hpp index 22059d0b7..1e673d124 100644 --- a/Runtime/MP1/World/CParasite.hpp +++ b/Runtime/MP1/World/CParasite.hpp @@ -117,7 +117,7 @@ public: void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void PreThink(float, CStateManager&) override; void Think(float dt, CStateManager& mgr) override; - void Render(const CStateManager&) const override; + void Render(CStateManager&) override; const CDamageVulnerability* GetDamageVulnerability() const override; CDamageInfo GetContactDamage() const override; void Touch(CActor& actor, CStateManager&) override; diff --git a/Runtime/MP1/World/CPuddleSpore.cpp b/Runtime/MP1/World/CPuddleSpore.cpp index 663dc07c1..9ac5a7951 100644 --- a/Runtime/MP1/World/CPuddleSpore.cpp +++ b/Runtime/MP1/World/CPuddleSpore.cpp @@ -134,7 +134,7 @@ void CPuddleSpore::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); } -void CPuddleSpore::Render(const CStateManager& mgr) const { +void CPuddleSpore::Render(CStateManager& mgr) { CPatterned::Render(mgr); if (x56c_ > 0.01f) { for (const auto& elemGen : x5dc_elemGens) diff --git a/Runtime/MP1/World/CPuddleSpore.hpp b/Runtime/MP1/World/CPuddleSpore.hpp index 7d22c671d..9d37a99bf 100644 --- a/Runtime/MP1/World/CPuddleSpore.hpp +++ b/Runtime/MP1/World/CPuddleSpore.hpp @@ -46,7 +46,7 @@ public: void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; void PreThink(float, CStateManager&) override; void Think(float, CStateManager&) override; - void Render(const CStateManager&) const override; + void Render(CStateManager&) override; void Touch(CActor&, CStateManager&) override; void FluidFXThink(EFluidState, CScriptWater&, CStateManager&) override; void KnockBack(const zeus::CVector3f& dir, CStateManager& mgr, const CDamageInfo& dInfo, EKnockBackType type, diff --git a/Runtime/MP1/World/CRidley.cpp b/Runtime/MP1/World/CRidley.cpp index f4011ffe0..80dbe047e 100644 --- a/Runtime/MP1/World/CRidley.cpp +++ b/Runtime/MP1/World/CRidley.cpp @@ -301,10 +301,10 @@ CRidley::CRidley(TUniqueId uid, std::string_view name, const CEntityInfo& info, , xb94_(zeus::CTransform::RotateX(zeus::degToRad(-40.f))) , xc14_(x568_data.xac_, x568_data.xb0_) , xc3c_(x568_data.x1a0_, x568_data.x1a4_) -, xc8c_(GetContactDamage()) +, xc8c_(CPatterned::GetContactDamage()) , xcd0_(g_SimplePool->GetObj({SBIG('ELSC'), x568_data.x3f0_})) -, xce0_(new CParticleElectric(xcd0_)) -, xd10_(new CProjectedShadow(128, 128, true)) { +, xce0_(std::make_unique(xcd0_)) +, xd10_(std::make_unique(128, 128, true)) { xe7_30_doTargetDistanceTest = true; xb68_.Token().Lock(); xc14_.Token().Lock(); @@ -669,7 +669,7 @@ void CRidley::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { } } -void CRidley::Render(const CStateManager& mgr) const { +void CRidley::Render(CStateManager& mgr) { zeus::CColor multiplyColor = zeus::skBlack; if (xb24_ > 0.f) { multiplyColor = zeus::CColor::lerp(zeus::skWhite, x430_damageColor, xb24_ / 0.33f); @@ -697,7 +697,7 @@ void CRidley::Render(const CStateManager& mgr) const { CPatterned::Render(mgr); } -void CRidley::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { +void CRidley::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { CPatterned::AddToRenderer(frustum, mgr); if (xce0_ && frustum.aabbFrustumTest(*xce0_->GetBounds())) { g_Renderer->AddParticleGen(*xce0_); diff --git a/Runtime/MP1/World/CRidley.hpp b/Runtime/MP1/World/CRidley.hpp index 6460d7f6a..dc42688f7 100644 --- a/Runtime/MP1/World/CRidley.hpp +++ b/Runtime/MP1/World/CRidley.hpp @@ -206,8 +206,8 @@ public: void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; void Think(float dt, CStateManager& mgr) override; void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; - void Render(const CStateManager& mgr) const override; - void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; + void Render(CStateManager& mgr) override; + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) override; zeus::CAABox GetSortingBounds(const CStateManager&) const override { return GetBoundingBox(); } const CDamageVulnerability* GetDamageVulnerability() const override { return &CDamageVulnerability::ImmuneVulnerabilty(); diff --git a/Runtime/MP1/World/CSeedling.cpp b/Runtime/MP1/World/CSeedling.cpp index e22dd03a2..a8a98e5d9 100644 --- a/Runtime/MP1/World/CSeedling.cpp +++ b/Runtime/MP1/World/CSeedling.cpp @@ -107,7 +107,7 @@ void CSeedling::Think(float dt, CStateManager& mgr) { x71c_attackCoolOff -= dt; } -void CSeedling::Render(const CStateManager& mgr) const { +void CSeedling::Render(CStateManager& mgr) { if (x400_25_alive && x6bc_spikeData) { const size_t index = x722_24_renderOnlyClusterA ? 0 : size_t(x722_25_curNeedleCluster); CModelFlags flags; diff --git a/Runtime/MP1/World/CSeedling.hpp b/Runtime/MP1/World/CSeedling.hpp index 0996b20f2..fa07befbe 100644 --- a/Runtime/MP1/World/CSeedling.hpp +++ b/Runtime/MP1/World/CSeedling.hpp @@ -31,7 +31,7 @@ public: void Accept(IVisitor&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float, CStateManager&) override; - void Render(const CStateManager&) const override; + void Render(CStateManager&) override; void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; CProjectileInfo* GetProjectileInfo() override { return &x6c0_projectileInfo; } std::optional GetTouchBounds() const override; diff --git a/Runtime/MP1/World/CShockWave.cpp b/Runtime/MP1/World/CShockWave.cpp new file mode 100644 index 000000000..344cf5ffa --- /dev/null +++ b/Runtime/MP1/World/CShockWave.cpp @@ -0,0 +1,177 @@ +#include "Runtime/MP1/World/CShockWave.hpp" + +#include "Runtime/Collision/CCollisionActor.hpp" +#include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/World/CActorParameters.hpp" +#include "Runtime/World/CGameLight.hpp" +#include "Runtime/World/CHUDBillboardEffect.hpp" +#include "Runtime/World/CPlayer.hpp" + +#include "TCastTo.hpp" // Generated file, do not modify include path + +namespace urde::MP1 { +CShockWave::CShockWave(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + TUniqueId parent, const SShockWaveData& data, float minActiveTime, float knockback) +: CActor(uid, true, name, info, xf, CModelData::CModelDataNull(), {EMaterialTypes::Projectile}, + CActorParameters::None(), kInvalidUniqueId) +, xe8_id1(parent) +, xec_damageInfo(data.GetDamageInfo()) +, x108_elementGenDesc(g_SimplePool->GetObj({SBIG('PART'), data.GetParticleDescId()})) +, x110_elementGen(std::make_unique(x108_elementGenDesc)) +, x114_data(data) +, x150_(data.GetX24()) +, x154_(data.GetX2C()) +, x15c_minActiveTime(minActiveTime) +, x160_knockback(knockback) { + if (data.GetWeaponDescId().IsValid()) { + x974_electricDesc = g_SimplePool->GetObj({SBIG('ELSC'), data.GetWeaponDescId()}); + } + x110_elementGen->SetParticleEmission(true); + x110_elementGen->SetOrientation(GetTransform().getRotation()); + x110_elementGen->SetGlobalTranslation(GetTranslation()); + xe6_27_thermalVisorFlags = 2; +} + +void CShockWave::Accept(IVisitor& visitor) { visitor.Visit(this); } + +void CShockWave::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + if (msg == EScriptObjectMessage::Registered) { + if (x110_elementGen->SystemHasLight()) { + x980_id2 = mgr.AllocateUniqueId(); + mgr.AddObject(new CGameLight(x980_id2, GetAreaIdAlways(), GetActive(), "ShockWaveLight_" + x10_name, + GetTransform(), GetUniqueId(), x110_elementGen->GetLight(), + x114_data.GetParticleDescId().Value(), 1, 0.f)); + } + } else if (msg == EScriptObjectMessage::Deleted) { + mgr.FreeScriptObject(x980_id2); + x980_id2 = kInvalidUniqueId; + } + CActor::AcceptScriptMsg(msg, uid, mgr); + mgr.SendScriptMsgAlways(x980_id2, uid, msg); +} + +void CShockWave::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { + CActor::AddToRenderer(frustum, mgr); + g_Renderer->AddParticleGen(*x110_elementGen); +} + +std::optional CShockWave::GetTouchBounds() const { + if (x150_ <= 0.f) { + return std::nullopt; + } + return zeus::CAABox({-x150_, -x150_, 0.f}, {x150_, x150_, 1.f}).getTransformedAABox(GetTransform()); +} + +void CShockWave::Render(CStateManager& mgr) { + CActor::Render(mgr); + x110_elementGen->Render(); +} + +void CShockWave::Think(float dt, CStateManager& mgr) { + if (GetActive()) { + x110_elementGen->Update(dt); + x158_activeTime += dt; + x150_ += x154_ * dt; + x154_ += dt * x114_data.GetX30(); + x110_elementGen->SetExternalVar(0, x150_); + for (size_t i = 0; i < x110_elementGen->GetNumActiveChildParticles(); ++i) { + auto& particle = static_cast(x110_elementGen->GetActiveChildParticle(i)); + if (particle.Get4CharId() == SBIG('PART')) { + particle.SetExternalVar(0, x150_); + } + } + if (x16c_hitPlayerInAir) { + x164_timeSinceHitPlayerInAir += dt; + x16c_hitPlayerInAir = false; + } + if (x16d_hitPlayer) { + x168_timeSinceHitPlayer += dt; + x16d_hitPlayer = false; + } + } + if (x110_elementGen->IsSystemDeletable() && x15c_minActiveTime > 0.f && x158_activeTime >= x15c_minActiveTime) { + mgr.FreeScriptObject(GetUniqueId()); + } else if (x980_id2 != kInvalidUniqueId) { + if (TCastToPtr light = mgr.ObjectById(x980_id2)) { + if (light->GetActive()) { + light->SetLight(x110_elementGen->GetLight()); + } + } + } +} + +void CShockWave::Touch(CActor& actor, CStateManager& mgr) { + if (x158_activeTime >= x15c_minActiveTime) { + return; + } + + bool isParent = xe8_id1 == actor.GetUniqueId(); + if (TCastToConstPtr cactor = mgr.GetObjectById(actor.GetUniqueId())) { + isParent = xe8_id1 == cactor->GetOwnerId(); + } + if (isParent) { + return; + } + + float mmax = x150_ * x150_; + float mmin = mmax * x114_data.GetX28() * x114_data.GetX28(); + zeus::CVector3f dist = actor.GetTranslation() - GetTranslation(); + CDamageInfo damageInfo = xec_damageInfo; + float knockBackScale = std::max(0.f, 1.f - x160_knockback * x158_activeTime); + bool isPlayer = mgr.GetPlayer().GetUniqueId() == actor.GetUniqueId(); + bool isPlayerInAir = isPlayer && mgr.GetPlayer().GetPlayerMovementState() != CPlayer::EPlayerMovementState::OnGround; + float distXYMag = dist.toVec2f().magSquared(); + if (distXYMag < mmin || distXYMag > mmax) { + return; + } + + if (isPlayer) { + if (mgr.GetPlayer().GetPlayerMovementState() == CPlayer::EPlayerMovementState::OnGround) { + const zeus::CTransform& playerTransform = mgr.GetPlayer().GetTransform(); + zeus::CVector3f playerDir = GetTranslation() - playerTransform.origin; + if (playerDir.canBeNormalized()) { + playerDir.normalize(); + float dot = std::abs(playerDir.dot(playerTransform.frontVector())); + knockBackScale = std::max(0.12f, 0.88f * dot * dot); + } + } + if (mgr.GetPlayer().GetVelocity().magnitude() > 40.f) { + x168_timeSinceHitPlayer = 0.2666f; + } + } + damageInfo.SetKnockBackPower(knockBackScale * damageInfo.GetKnockBackPower()); + + if (isPlayer && (x164_timeSinceHitPlayerInAir >= 0.1333f || x168_timeSinceHitPlayer >= 0.2666f)) { + return; + } + if (!IsHit(actor.GetUniqueId())) { + mgr.ApplyDamage(GetUniqueId(), actor.GetUniqueId(), GetUniqueId(), damageInfo, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), zeus::skZero3f); + if (isPlayer && x974_electricDesc) { + mgr.AddObject(new CHUDBillboardEffect(std::nullopt, x974_electricDesc, mgr.AllocateUniqueId(), true, + "VisorElectricFx", CHUDBillboardEffect::GetNearClipDistance(mgr), + CHUDBillboardEffect::GetScaleForPOV(mgr), zeus::skWhite, zeus::skOne3f, + zeus::skZero3f)); + CSfxManager::SfxStart(x114_data.GetElectrocuteSfx(), 1.f, 1.f, false, 0x7f, false, kInvalidAreaId); + } + x170_hitIds.push_back(actor.GetUniqueId()); + } else { + damageInfo.SetDamage(0.f); + mgr.ApplyDamage(GetUniqueId(), actor.GetUniqueId(), GetUniqueId(), damageInfo, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), zeus::skZero3f); + } + if (isPlayerInAir) { + x16c_hitPlayerInAir = true; + } + if (isPlayer) { + x16d_hitPlayer = true; + } +} + +bool CShockWave::IsHit(TUniqueId id) const { + return std::find(x170_hitIds.begin(), x170_hitIds.end(), id) != x170_hitIds.end(); +} +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CShockWave.hpp b/Runtime/MP1/World/CShockWave.hpp new file mode 100644 index 000000000..0eb5589f5 --- /dev/null +++ b/Runtime/MP1/World/CShockWave.hpp @@ -0,0 +1,69 @@ +#pragma once + +#include "Runtime/World/CActor.hpp" +#include "Runtime/World/CDamageInfo.hpp" +#include "Runtime/Particle/CElementGen.hpp" + +namespace urde::MP1 { +struct SShockWaveData { +private: + u32 x0_ = 8; + CAssetId x4_particleDesc; + CDamageInfo x8_damageInfo; + float x24_ = 0.f; + float x28_ = 0.5f; + float x2c_ = 16.5217f; + float x30_ = 0.f; + CAssetId x34_weaponDesc; + u16 x38_electrocuteSfx; + +public: + SShockWaveData(CAssetId part, const CDamageInfo& dInfo, CAssetId weapon, u16 sfx) + : x4_particleDesc(part), x8_damageInfo(dInfo), x34_weaponDesc(weapon), x38_electrocuteSfx(sfx) {} + + [[nodiscard]] CAssetId GetParticleDescId() const { return x4_particleDesc; } + [[nodiscard]] const CDamageInfo& GetDamageInfo() const { return x8_damageInfo; } + [[nodiscard]] float GetX24() const { return x24_; } + [[nodiscard]] float GetX28() const { return x28_; } + [[nodiscard]] float GetX2C() const { return x2c_; } + [[nodiscard]] float GetX30() const { return x30_; } + [[nodiscard]] CAssetId GetWeaponDescId() const { return x34_weaponDesc; } + [[nodiscard]] u16 GetElectrocuteSfx() const { return x38_electrocuteSfx; } +}; + +class CShockWave : public CActor { +private: + TUniqueId xe8_id1; + CDamageInfo xec_damageInfo; + TToken x108_elementGenDesc; + std::unique_ptr x110_elementGen; + SShockWaveData x114_data; + float x150_; + float x154_; + float x158_activeTime = 0.f; + float x15c_minActiveTime; + float x160_knockback; + float x164_timeSinceHitPlayerInAir = 0.f; + float x168_timeSinceHitPlayer = 0.f; + bool x16c_hitPlayerInAir = false; + bool x16d_hitPlayer = false; + rstl::reserved_vector x170_hitIds; + std::optional> x974_electricDesc; + TUniqueId x980_id2 = kInvalidUniqueId; + +public: + CShockWave(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + TUniqueId parent, const SShockWaveData& data, float minActiveTime, float knockback); + + void Accept(IVisitor& visitor) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) override; + [[nodiscard]] std::optional GetTouchBounds() const override; + void Render(CStateManager& mgr) override; + void Think(float dt, CStateManager& mgr) override; + void Touch(CActor& actor, CStateManager& mgr) override; + +private: + [[nodiscard]] bool IsHit(TUniqueId id) const; +}; +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CSpacePirate.cpp b/Runtime/MP1/World/CSpacePirate.cpp index 99c6535bc..409a11e5b 100644 --- a/Runtime/MP1/World/CSpacePirate.cpp +++ b/Runtime/MP1/World/CSpacePirate.cpp @@ -466,20 +466,20 @@ CSpacePirate::CSpacePirate(TUniqueId uid, std::string_view name, const CEntityIn if (x634_29_onlyAttackInRange) x460_knockBackController.SetKnockBackVariant(EKnockBackVariant::Small); - else if (x636_24_trooper && GetDamageVulnerability()->WeaponHurts(CWeaponMode(EWeaponType::Plasma), false)) + else if (x636_24_trooper && x260_damageVulnerability.WeaponHurts(CWeaponMode(EWeaponType::Plasma), false)) x460_knockBackController.SetKnockBackVariant(EKnockBackVariant::Large); if (!x450_bodyController->HasBodyState(pas::EAnimationState::AdditiveAim)) x634_27_melee = true; if (x636_24_trooper) { - if (GetDamageVulnerability()->WeaponHurts(CWeaponMode(EWeaponType::Plasma), false)) + if (x260_damageVulnerability.WeaponHurts(CWeaponMode(EWeaponType::Plasma), false)) x8cc_trooperColor = zeus::CColor(0.996f, 0.f, 0.157f, 1.f); - else if (GetDamageVulnerability()->WeaponHurts(CWeaponMode(EWeaponType::Ice), false)) + else if (x260_damageVulnerability.WeaponHurts(CWeaponMode(EWeaponType::Ice), false)) x8cc_trooperColor = zeus::skWhite; - else if (GetDamageVulnerability()->WeaponHurts(CWeaponMode(EWeaponType::Power), false)) + else if (x260_damageVulnerability.WeaponHurts(CWeaponMode(EWeaponType::Power), false)) x8cc_trooperColor = zeus::CColor(0.992f, 0.937f, 0.337f, 1.f); - else if (GetDamageVulnerability()->WeaponHurts(CWeaponMode(EWeaponType::Wave), false)) + else if (x260_damageVulnerability.WeaponHurts(CWeaponMode(EWeaponType::Wave), false)) x8cc_trooperColor = zeus::CColor(0.776f, 0.054f, 1.f, 1.f); } @@ -618,10 +618,11 @@ bool CSpacePirate::FireProjectile(float dt, CStateManager& mgr) { } } if (ret) { - auto bestAnim = x450_bodyController->GetPASDatabase().FindBestAnimation({24, CPASAnimParm::FromEnum(2)}, - *mgr.GetActiveRandom(), -1); - if (bestAnim.first > 0.f) + const auto bestAnim = x450_bodyController->GetPASDatabase().FindBestAnimation( + CPASAnimParmData{24, CPASAnimParm::FromEnum(2)}, *mgr.GetActiveRandom(), -1); + if (bestAnim.first > 0.f) { x64_modelData->GetAnimationData()->AddAdditiveAnimation(bestAnim.second, 1.f, false, true); + } CSfxManager::AddEmitter(x568_pirateData.x48_Sound_Projectile, GetTranslation(), zeus::skZero3f, true, false, 0x7f, kInvalidAreaId); } @@ -1059,7 +1060,7 @@ void CSpacePirate::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) } } -void CSpacePirate::Render(const CStateManager& mgr) const { +void CSpacePirate::Render(CStateManager& mgr) { float time = x400_25_alive ? CGraphics::GetSecondsMod900() : 0.f; CTimeProvider prov(time); g_Renderer->SetGXRegister1Color(x8cc_trooperColor); @@ -1497,7 +1498,7 @@ void CSpacePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { } } if (r28) - x450_bodyController->GetCommandMgr().SetTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); + x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); } x828_patrolDestPos = x2e0_destPos; break; @@ -1553,7 +1554,7 @@ void CSpacePirate::Generate(CStateManager& mgr, EStateMsg msg, float dt) { TryCommand(mgr, pas::EAnimationState::Jump, &CPatterned::TryJump, x634_25_ceilingAmbush ? 2 : 0); if (x32c_animState == EAnimState::Repeat) x450_bodyController->SetLocomotionType(pas::ELocomotionType::Combat); - x450_bodyController->GetCommandMgr().SetTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); + x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); break; case EStateMsg::Deactivate: x32c_animState = EAnimState::NotReady; @@ -1609,7 +1610,7 @@ void CSpacePirate::Attack(CStateManager& mgr, EStateMsg msg, float dt) { case EStateMsg::Update: if (x636_26_enableMeleeAttack) { TryCommand(mgr, pas::EAnimationState::MeleeAttack, &CPatterned::TryMeleeAttack, 1); - x450_bodyController->GetCommandMgr().SetTargetVector(x648_targetDelta); + x450_bodyController->GetCommandMgr().DeliverTargetVector(x648_targetDelta); CheckBlade(mgr); if (x635_27_shadowPirate) { if (x32c_animState == EAnimState::Over) { @@ -1668,7 +1669,7 @@ void CSpacePirate::JumpBack(CStateManager& mgr, EStateMsg msg, float dt) { if (!x639_25_useJumpBackJump) { x450_bodyController->GetCommandMgr().DeliverCmd( CBCStepCmd(pas::EStepDirection::Backward, pas::EStepType::Normal)); - x450_bodyController->GetCommandMgr().SetTargetVector(GetTargetPos(mgr) - GetTranslation()); + x450_bodyController->GetCommandMgr().DeliverTargetVector(GetTargetPos(mgr) - GetTranslation()); } else { TryCommand(mgr, pas::EAnimationState::Jump, &CPatterned::TryJump, 0); } @@ -1713,7 +1714,7 @@ void CSpacePirate::DoubleSnap(CStateManager& mgr, EStateMsg msg, float dt) { } if (x639_30_closeMelee) x648_targetDelta = GetTargetPos(mgr) - GetTranslation(); - x450_bodyController->GetCommandMgr().SetTargetVector(x648_targetDelta); + x450_bodyController->GetCommandMgr().DeliverTargetVector(x648_targetDelta); if (x635_27_shadowPirate) { if (x32c_animState == EAnimState::Over) { x3e8_alphaDelta = -0.4f; @@ -1829,7 +1830,7 @@ void CSpacePirate::Crouch(CStateManager& mgr, EStateMsg msg, float dt) { x79c_coverDir = pas::ECoverDirection::Invalid; break; case EStateMsg::Update: - x450_bodyController->GetCommandMgr().SetTargetVector(x648_targetDelta); + x450_bodyController->GetCommandMgr().DeliverTargetVector(x648_targetDelta); UpdateCantSeePlayer(mgr); break; default: @@ -1876,8 +1877,8 @@ void CSpacePirate::Taunt(CStateManager& mgr, EStateMsg msg, float dt) { if (!x635_27_shadowPirate) { bool withOtherPirate = true; if (x634_27_melee) { - auto bestAnim = x450_bodyController->GetPASDatabase().FindBestAnimation({16, CPASAnimParm::FromEnum(2)}, - *mgr.GetActiveRandom(), -1); + const auto bestAnim = x450_bodyController->GetPASDatabase().FindBestAnimation( + CPASAnimParmData{16, CPASAnimParm::FromEnum(2)}, *mgr.GetActiveRandom(), -1); if (bestAnim.first > 0.f) { withOtherPirate = false; x760_taunt = pas::ETauntType::Two; @@ -2089,7 +2090,7 @@ void CSpacePirate::Cover(CStateManager& mgr, EStateMsg msg, float dt) { case EStateMsg::Update: TryCommand(mgr, pas::EAnimationState::Cover, &CPatterned::TryCover, int(x79c_coverDir)); if (CScriptCoverPoint* cp = GetCoverPoint(mgr, x640_coverPoint)) - x450_bodyController->GetCommandMgr().SetTargetVector(-cp->GetTransform().basis[1]); + x450_bodyController->GetCommandMgr().DeliverTargetVector(-cp->GetTransform().basis[1]); UpdateCantSeePlayer(mgr); break; case EStateMsg::Deactivate: @@ -2134,7 +2135,7 @@ void CSpacePirate::WallHang(CStateManager& mgr, EStateMsg msg, float dt) { break; case EStateMsg::Update: TryCommand(mgr, pas::EAnimationState::WallHang, &CSpacePirate::TryWallHang, 0); - x450_bodyController->GetCommandMgr().SetTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); + x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); x7c4_burstFire.SetBurstType(1); break; case EStateMsg::Deactivate: @@ -2173,7 +2174,7 @@ void CSpacePirate::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { case EStateMsg::Update: TryCommand(mgr, pas::EAnimationState::ProjectileAttack, &CPatterned::TryProjectileAttack, int(pas::ESeverity::One)); if (x32c_animState == EAnimState::Ready) - x450_bodyController->GetCommandMgr().SetTargetVector(x648_targetDelta); + x450_bodyController->GetCommandMgr().DeliverTargetVector(x648_targetDelta); break; case EStateMsg::Deactivate: x32c_animState = EAnimState::NotReady; diff --git a/Runtime/MP1/World/CSpacePirate.hpp b/Runtime/MP1/World/CSpacePirate.hpp index e057ef107..0663fd803 100644 --- a/Runtime/MP1/World/CSpacePirate.hpp +++ b/Runtime/MP1/World/CSpacePirate.hpp @@ -245,7 +245,7 @@ public: void Think(float dt, CStateManager& mgr) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) override; void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; - void Render(const CStateManager& mgr) const override; + void Render(CStateManager& mgr) override; void CalculateRenderBounds() override; void Touch(CActor& other, CStateManager& mgr) override; @@ -333,5 +333,6 @@ public: u8 GetModelAlphau8(const CStateManager& mgr) const override; float GetGravityConstant() const override; CProjectileInfo* GetProjectileInfo() override; + bool GetEnableAim() const { return x637_25_enableAim; } }; } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CSpankWeed.cpp b/Runtime/MP1/World/CSpankWeed.cpp index f361be72c..223d1dc20 100644 --- a/Runtime/MP1/World/CSpankWeed.cpp +++ b/Runtime/MP1/World/CSpankWeed.cpp @@ -109,8 +109,9 @@ void CSpankWeed::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CState CPatterned::AcceptScriptMsg(msg, uid, mgr); - if (GetActive() != oldActive) - x594_collisionMgr.reset(); + bool active = GetActive(); + if (active != oldActive && x594_collisionMgr) + x594_collisionMgr->SetActive(mgr, active); } void CSpankWeed::Think(float dt, CStateManager& mgr) { diff --git a/Runtime/MP1/World/CThardus.cpp b/Runtime/MP1/World/CThardus.cpp index f1959806b..d0f8f6763 100644 --- a/Runtime/MP1/World/CThardus.cpp +++ b/Runtime/MP1/World/CThardus.cpp @@ -111,7 +111,7 @@ CThardus::CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info gens.push_back(particle8); gens.push_back(particle9); GetModelData()->GetAnimationData()->GetParticleDB().CacheParticleDesc( - CCharacterInfo::CParticleResData(gens, {}, {}, {})); + CCharacterInfo::CParticleResData(std::move(gens), {}, {}, {})); x798_.reserve(6); x7a8_timers.reserve(16); UpdateThermalFrozenState(true); @@ -347,7 +347,7 @@ void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa CActorParameters(CLightParameters(false, 0.f, CLightParameters::EShadowTesselation::Invalid, 0.f, 0.f, zeus::skWhite, true, CLightParameters::EWorldLightingOptions::NoShadowCast, CLightParameters::ELightRecalculationOptions::LargeFrameCount, - zeus::skZero3f, -1, -1, 0, 0), + zeus::skZero3f, -1, -1, false, 0), {}, {}, {}, {}, true, true, false, false, 0.f, 0.f, 1.f), x5dc_[i], 0)); x610_destroyableRocks.push_back(rockId); @@ -443,7 +443,7 @@ void CThardus::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { xb4_drawFlags = CModelFlags(0, 0, 3, zeus::skWhite); } } -void CThardus::Render(const CStateManager& mgr) const { +void CThardus::Render(CStateManager& mgr) { CPatterned::Render(mgr); if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal && x7c4_ != 0) { RenderFlare(mgr, x7c0_); diff --git a/Runtime/MP1/World/CThardus.hpp b/Runtime/MP1/World/CThardus.hpp index 82aa78a85..1fdb108b3 100644 --- a/Runtime/MP1/World/CThardus.hpp +++ b/Runtime/MP1/World/CThardus.hpp @@ -177,7 +177,7 @@ public: void Think(float dt, CStateManager& mgr) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; - void Render(const CStateManager& mgr) const override; + void Render(CStateManager& mgr) override; bool CanRenderUnsorted(const CStateManager&) const override { return false; } void Touch(CActor& act, CStateManager& mgr) override; zeus::CVector3f GetOrbitPosition(const CStateManager& mgr) const override; diff --git a/Runtime/MP1/World/CTryclops.cpp b/Runtime/MP1/World/CTryclops.cpp index 16c32f7f1..da9539c6b 100644 --- a/Runtime/MP1/World/CTryclops.cpp +++ b/Runtime/MP1/World/CTryclops.cpp @@ -496,7 +496,7 @@ void CTryclops::LaunchPlayer(CStateManager& mgr, const zeus::CTransform& xf, flo player.Stop(); zeus::CTransform tmpXf = (xf * x64c_); tmpXf.origin += zeus::CVector3f(0.f, 0.f, -0.5f); - player.Teleport(xf, mgr, false); + player.Teleport(tmpXf, mgr, false); player.ApplyImpulseWR(f1 * (player.GetMass() * xf.basis[1].normalized()), zeus::CAxisAngle()); player.SetMoveState(CPlayer::EPlayerMovementState::ApplyJump, mgr); player.AddMaterial(EMaterialTypes::Solid, mgr); diff --git a/Runtime/Particle/CColorElement.cpp b/Runtime/Particle/CColorElement.cpp index 2e94b01e4..05489c698 100644 --- a/Runtime/Particle/CColorElement.cpp +++ b/Runtime/Particle/CColorElement.cpp @@ -19,10 +19,11 @@ CCEKeyframeEmitter::CCEKeyframeEmitter(CInputStream& in) { x10_loopEnd = in.readUint32Big(); x14_loopStart = in.readUint32Big(); - u32 count = in.readUint32Big(); + const u32 count = in.readUint32Big(); x18_keys.reserve(count); - for (u32 i = 0; i < count; ++i) - x18_keys.push_back(in.readVec4fBig()); + for (u32 i = 0; i < count; ++i) { + x18_keys.emplace_back(in.readVec4fBig()); + } } bool CCEKeyframeEmitter::GetValue(int frame, zeus::CColor& valOut) const { diff --git a/Runtime/Particle/CColorElement.hpp b/Runtime/Particle/CColorElement.hpp index 6939f5b01..1323aceef 100644 --- a/Runtime/Particle/CColorElement.hpp +++ b/Runtime/Particle/CColorElement.hpp @@ -20,7 +20,7 @@ class CCEKeyframeEmitter : public CColorElement { std::vector x18_keys; public: - CCEKeyframeEmitter(CInputStream& in); + explicit CCEKeyframeEmitter(CInputStream& in); bool GetValue(int frame, zeus::CColor& colorOut) const override; }; diff --git a/Runtime/Particle/CDecal.cpp b/Runtime/Particle/CDecal.cpp index 70ca59d45..c18156852 100644 --- a/Runtime/Particle/CDecal.cpp +++ b/Runtime/Particle/CDecal.cpp @@ -25,16 +25,17 @@ CDecal::CDecal(const TToken& desc, const zeus::CTransform& xf if (d->x50_DMRT) d->x50_DMRT->GetValue(0, x60_rotation); - } else + } else { x5c_29_modelInvalid = true; + } CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { - for (int i = 0; i < 2; ++i) { - CQuadDecal& decal = x3c_decalQuads[i]; - if (decal.m_desc->x14_TEX) + for (auto& decal : x3c_decalQuads) { + if (decal.m_desc->x14_TEX) { decal.m_instBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SParticleInstanceTex), 1); - else + } else { decal.m_instBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SParticleInstanceNoTex), 1); + } decal.m_uniformBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(SParticleUniforms), 1); CDecalShaders::BuildShaderDataBinding(ctx, decal); } @@ -163,7 +164,7 @@ void CDecal::RenderQuad(CQuadDecal& decal, const SQuadDescr& desc) const { } } -void CDecal::RenderMdl() const { +void CDecal::RenderMdl() { const CDecalDescription& desc = *x0_description; zeus::CColor color = zeus::skWhite; zeus::CVector3f dmop; @@ -178,7 +179,7 @@ void CDecal::RenderMdl() const { zeus::CTransform dmrtXf; if (dmrtIsConst) { - desc.x50_DMRT->GetValue(x58_frameIdx, const_cast(x60_rotation)); + desc.x50_DMRT->GetValue(x58_frameIdx, x60_rotation); dmrtXf = zeus::CTransform::RotateZ(zeus::degToRad(x60_rotation.z())); dmrtXf.rotateLocalY(zeus::degToRad(x60_rotation.y())); dmrtXf.rotateLocalX(zeus::degToRad(x60_rotation.x())); @@ -231,7 +232,7 @@ void CDecal::RenderMdl() const { } } -void CDecal::Render() const { +void CDecal::Render() { SCOPED_GRAPHICS_DEBUG_GROUP("CDecal::Render", zeus::skYellow); CGlobalRandom gr(sDecalRandom); if (x5c_29_modelInvalid && x5c_30_quad2Invalid && x5c_31_quad1Invalid) @@ -244,12 +245,12 @@ void CDecal::Render() const { if (desc.x0_Quads[0].x14_TEX && !x5c_31_quad1Invalid) { CParticleGlobals::instance()->SetParticleLifetime(x3c_decalQuads[0].x4_lifetime); CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(x58_frameIdx); - RenderQuad(const_cast(x3c_decalQuads[0]), desc.x0_Quads[0]); + RenderQuad(x3c_decalQuads[0], desc.x0_Quads[0]); } if (desc.x0_Quads[1].x14_TEX && !x5c_30_quad2Invalid) { CParticleGlobals::instance()->SetParticleLifetime(x3c_decalQuads[1].x4_lifetime); CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(x58_frameIdx); - RenderQuad(const_cast(x3c_decalQuads[1]), desc.x0_Quads[1]); + RenderQuad(x3c_decalQuads[1], desc.x0_Quads[1]); } if (desc.x38_DMDL && !x5c_29_modelInvalid) { CParticleGlobals::instance()->SetParticleLifetime(x54_modelLifetime); diff --git a/Runtime/Particle/CDecal.hpp b/Runtime/Particle/CDecal.hpp index ee571a535..224658da1 100644 --- a/Runtime/Particle/CDecal.hpp +++ b/Runtime/Particle/CDecal.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "Runtime/CRandom16.hpp" #include "Runtime/CToken.hpp" #include "Runtime/RetroTypes.hpp" @@ -36,7 +38,7 @@ class CDecal { TLockedToken x0_description; zeus::CTransform xc_transform; - CQuadDecal x3c_decalQuads[2]; + std::array x3c_decalQuads; s32 x54_modelLifetime = 0; s32 x58_frameIdx = 0; union { @@ -53,8 +55,8 @@ class CDecal { public: CDecal(const TToken& desc, const zeus::CTransform& xf); void RenderQuad(CQuadDecal& decal, const SQuadDescr& desc) const; - void RenderMdl() const; - void Render() const; + void RenderMdl(); + void Render(); void Update(float dt); static void SetGlobalSeed(u16); diff --git a/Runtime/Particle/CElementGen.hpp b/Runtime/Particle/CElementGen.hpp index 893211428..26ec47598 100644 --- a/Runtime/Particle/CElementGen.hpp +++ b/Runtime/Particle/CElementGen.hpp @@ -43,7 +43,7 @@ public: zeus::CVector3f x4_viewPoint; public: - CParticleListItem(s16 idx) : x0_partIdx(idx) {} + explicit CParticleListItem(s16 idx) : x0_partIdx(idx) {} }; static CParticle* g_currentParticle; diff --git a/Runtime/Particle/CFlameWarp.cpp b/Runtime/Particle/CFlameWarp.cpp index f87d44b76..23ea08edf 100644 --- a/Runtime/Particle/CFlameWarp.cpp +++ b/Runtime/Particle/CFlameWarp.cpp @@ -1,12 +1,15 @@ #include "Runtime/Particle/CFlameWarp.hpp" +#include + #include "Runtime/CStateManager.hpp" namespace urde { void CFlameWarp::ModifyParticles(std::vector& particles) { - if (x9c_stateMgr == 0 || particles.size() < 9) + if (x9c_stateMgr == nullptr || particles.size() < 9) { return; + } std::vector> vec; vec.reserve(particles.size()); @@ -64,14 +67,15 @@ void CFlameWarp::ModifyParticles(std::vector& particles) { std::sort(vec.begin(), vec.end(), [](auto& a, auto& b) { return a.first < b.first; }); - int pitch = particles.size() / 9; - for (int i = 0; i < 9; ++i) { - CParticle& part = particles[vec[i * pitch].second]; + const size_t pitch = particles.size() / 9; + for (size_t i = 0; i < x4_collisionPoints.size(); ++i) { + const CParticle& part = particles[vec[i * pitch].second]; x4_collisionPoints[i] = part.x4_pos; if (i > 0) { - zeus::CVector3f delta = x4_collisionPoints[i] - x4_collisionPoints[i - 1]; - if (delta.magnitude() < 0.0011920929f) + const zeus::CVector3f delta = x4_collisionPoints[i] - x4_collisionPoints[i - 1]; + if (delta.magnitude() < 0.0011920929f) { x4_collisionPoints[i] += delta.normalized() * 0.0011920929f; + } } } @@ -80,6 +84,11 @@ void CFlameWarp::ModifyParticles(std::vector& particles) { xa0_26_processed = true; } +void CFlameWarp::ResetPosition(const zeus::CVector3f& pos) { + std::fill(x4_collisionPoints.begin(), x4_collisionPoints.end(), pos); + xa0_26_processed = false; +} + zeus::CAABox CFlameWarp::CalculateBounds() const { zeus::CAABox ret; for (const auto& v : x4_collisionPoints) diff --git a/Runtime/Particle/CFlameWarp.hpp b/Runtime/Particle/CFlameWarp.hpp index 48faca6fb..74828d6ac 100644 --- a/Runtime/Particle/CFlameWarp.hpp +++ b/Runtime/Particle/CFlameWarp.hpp @@ -47,12 +47,7 @@ public: bool IsActivated() override { return xa0_24_activated; } bool IsProcessed() const { return xa0_26_processed; } FourCC Get4CharID() override { return FOURCC('FWRP'); } - void ResetPosition(const zeus::CVector3f& pos) { - for (auto& vec : x4_collisionPoints) { - vec = pos; - } - xa0_26_processed = false; - } + void ResetPosition(const zeus::CVector3f& pos); zeus::CAABox CalculateBounds() const; }; } // namespace urde diff --git a/Runtime/Particle/CIntElement.cpp b/Runtime/Particle/CIntElement.cpp index 654f874e2..591bf4d93 100644 --- a/Runtime/Particle/CIntElement.cpp +++ b/Runtime/Particle/CIntElement.cpp @@ -189,12 +189,12 @@ bool CIESampleAndHold::GetValue(int frame, int& valOut) const { int b, c; xc_waitFramesMin->GetValue(frame, b); x10_waitFramesMax->GetValue(frame, c); - /* const-correctness, who needs it? */ - const_cast(this)->x8_nextSampleFrame = CRandom16::GetRandomNumber()->Range(b, c) + frame; + x8_nextSampleFrame = CRandom16::GetRandomNumber()->Range(b, c) + frame; x4_sampleSource->GetValue(frame, valOut); - const_cast(this)->x14_holdVal = valOut; - } else + x14_holdVal = valOut; + } else { valOut = x14_holdVal; + } return false; } diff --git a/Runtime/Particle/CIntElement.hpp b/Runtime/Particle/CIntElement.hpp index 78602b998..f2a8a4267 100644 --- a/Runtime/Particle/CIntElement.hpp +++ b/Runtime/Particle/CIntElement.hpp @@ -19,7 +19,7 @@ class CIEKeyframeEmitter : public CIntElement { std::vector x18_keys; public: - CIEKeyframeEmitter(CInputStream& in); + explicit CIEKeyframeEmitter(CInputStream& in); bool GetValue(int frame, int& valOut) const override; int GetMaxValue() const override; }; @@ -73,7 +73,7 @@ class CIEConstant : public CIntElement { int x4_val; public: - CIEConstant(int val) : x4_val(val) {} + explicit CIEConstant(int val) : x4_val(val) {} bool GetValue(int frame, int& valOut) const override; int GetMaxValue() const override; }; @@ -82,7 +82,7 @@ class CIEImpulse : public CIntElement { std::unique_ptr x4_a; public: - CIEImpulse(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CIEImpulse(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, int& valOut) const override; int GetMaxValue() const override; }; @@ -91,7 +91,7 @@ class CIELifetimePercent : public CIntElement { std::unique_ptr x4_percentVal; public: - CIELifetimePercent(std::unique_ptr&& a) : x4_percentVal(std::move(a)) {} + explicit CIELifetimePercent(std::unique_ptr&& a) : x4_percentVal(std::move(a)) {} bool GetValue(int frame, int& valOut) const override; int GetMaxValue() const override; }; @@ -134,10 +134,10 @@ public: class CIESampleAndHold : public CIntElement { std::unique_ptr x4_sampleSource; - int x8_nextSampleFrame = 0; + mutable int x8_nextSampleFrame = 0; std::unique_ptr xc_waitFramesMin; std::unique_ptr x10_waitFramesMax; - int x14_holdVal; + mutable int x14_holdVal; public: CIESampleAndHold(std::unique_ptr&& a, std::unique_ptr&& b, std::unique_ptr&& c) @@ -161,7 +161,7 @@ class CIETimeScale : public CIntElement { std::unique_ptr x4_a; public: - CIETimeScale(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CIETimeScale(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, int& valOut) const override; int GetMaxValue() const override; }; diff --git a/Runtime/Particle/CModVectorElement.hpp b/Runtime/Particle/CModVectorElement.hpp index 53cb47670..f4270aedc 100644 --- a/Runtime/Particle/CModVectorElement.hpp +++ b/Runtime/Particle/CModVectorElement.hpp @@ -21,7 +21,7 @@ public: , x8_magScale(std::move(b)) , xc_maxMag(std::move(c)) , x10_minMag(std::move(d)) - , x14_enableMinMag(std::move(e)) {} + , x14_enableMinMag(e) {} bool GetValue(int frame, zeus::CVector3f& pVel, zeus::CVector3f& pPos) const override; }; @@ -39,7 +39,7 @@ public: , x8_magScale(std::move(b)) , xc_maxMag(std::move(c)) , x10_minMag(std::move(d)) - , x14_enableMinMag(std::move(e)) {} + , x14_enableMinMag(e) {} bool GetValue(int frame, zeus::CVector3f& pVel, zeus::CVector3f& pPos) const override; }; @@ -57,7 +57,7 @@ public: , x8_magScale(std::move(b)) , xc_maxMag(std::move(c)) , x10_minMag(std::move(d)) - , x14_enableMinMag(std::move(e)) {} + , x14_enableMinMag(e) {} bool GetValue(int frame, zeus::CVector3f& pVel, zeus::CVector3f& pPos) const override; }; @@ -112,7 +112,7 @@ class CMVEGravity : public CModVectorElement { std::unique_ptr x4_a; public: - CMVEGravity(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CMVEGravity(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, zeus::CVector3f& pVel, zeus::CVector3f& pPos) const override; }; @@ -130,7 +130,7 @@ class CMVESetPosition : public CModVectorElement { std::unique_ptr x4_a; public: - CMVESetPosition(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CMVESetPosition(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, zeus::CVector3f& pVel, zeus::CVector3f& pPos) const override; }; diff --git a/Runtime/Particle/CParticleDataFactory.cpp b/Runtime/Particle/CParticleDataFactory.cpp index 1bed811b2..cf0b89f2b 100644 --- a/Runtime/Particle/CParticleDataFactory.cpp +++ b/Runtime/Particle/CParticleDataFactory.cpp @@ -88,19 +88,20 @@ std::unique_ptr CParticleDataFactory::GetTextureElement(CInputStream return std::make_unique(std::move(txtr)); } case SBIG('ATEX'): { - FourCC subId = GetClassID(in); - if (subId == SBIG('NONE')) + const FourCC subId = GetClassID(in); + if (subId == SBIG('NONE')) { return nullptr; - CAssetId id = in.readUint32Big(); + } + const CAssetId id = in.readUint32Big(); auto a = GetIntElement(in); auto b = GetIntElement(in); auto c = GetIntElement(in); auto d = GetIntElement(in); auto e = GetIntElement(in); - bool f = GetBool(in); + const bool f = GetBool(in); TToken txtr = resPool->GetObj({FOURCC('TXTR'), id}); return std::make_unique(std::move(txtr), std::move(std::move(a)), std::move(b), std::move(c), - std::move(d), std::move(e), std::move(f)); + std::move(d), std::move(e), f); } default: break; @@ -174,17 +175,16 @@ std::unique_ptr CParticleDataFactory::GetModVectorElement(CIn auto b = GetRealElement(in); auto c = GetRealElement(in); auto d = GetRealElement(in); - bool e = GetBool(in); - return std::make_unique(std::move(a), std::move(b), std::move(c), std::move(d), std::move(e)); + const bool e = GetBool(in); + return std::make_unique(std::move(a), std::move(b), std::move(c), std::move(d), e); } case SBIG('EMPL'): { auto a = GetVectorElement(in); auto b = GetRealElement(in); auto c = GetRealElement(in); auto d = GetRealElement(in); - bool e = GetBool(in); - return std::make_unique(std::move(a), std::move(b), std::move(c), std::move(d), - std::move(e)); + const bool e = GetBool(in); + return std::make_unique(std::move(a), std::move(b), std::move(c), std::move(d), e); } case SBIG('CHAN'): { auto a = GetModVectorElement(in); @@ -197,8 +197,8 @@ std::unique_ptr CParticleDataFactory::GetModVectorElement(CIn auto b = GetVectorElement(in); auto c = GetRealElement(in); auto d = GetRealElement(in); - bool e = GetBool(in); - return std::make_unique(std::move(a), std::move(b), std::move(c), std::move(d), std::move(e)); + const bool e = GetBool(in); + return std::make_unique(std::move(a), std::move(b), std::move(c), std::move(d), e); } case SBIG('CNST'): { auto a = GetRealElement(in); @@ -232,8 +232,8 @@ std::unique_ptr CParticleDataFactory::GetModVectorElement(CIn auto b = GetRealElement(in); auto c = GetRealElement(in); auto d = GetRealElement(in); - bool e = GetBool(in); - return std::make_unique(std::move(a), std::move(b), std::move(c), std::move(d), std::move(e)); + const bool e = GetBool(in); + return std::make_unique(std::move(a), std::move(b), std::move(c), std::move(d), e); } case SBIG('PULS'): { auto a = GetIntElement(in); @@ -424,8 +424,8 @@ std::unique_ptr CParticleDataFactory::GetRealElement(CInputStream& return std::make_unique(std::move(a), std::move(b)); } case SBIG('CNST'): { - float a = GetReal(in); - return std::make_unique(std::move(a)); + const float a = GetReal(in); + return std::make_unique(a); } case SBIG('CHAN'): { auto a = GetRealElement(in); @@ -628,8 +628,8 @@ std::unique_ptr CParticleDataFactory::GetIntElement(CInputStream& i return std::make_unique(std::move(a), std::move(b)); } case SBIG('CNST'): { - int a = GetInt(in); - return std::make_unique(std::move(a)); + const int a = GetInt(in); + return std::make_unique(a); } case SBIG('IMPL'): { auto a = GetIntElement(in); diff --git a/Runtime/Particle/CParticleElectric.cpp b/Runtime/Particle/CParticleElectric.cpp index b560439cb..355b8aaaa 100644 --- a/Runtime/Particle/CParticleElectric.cpp +++ b/Runtime/Particle/CParticleElectric.cpp @@ -42,7 +42,7 @@ CParticleElectric::CParticleElectric(const TToken& token) if (desc->x40_SSWH) { x450_27_haveSSWH = true; for (int i = 0; i < x154_SCNT; ++i) { - x1e0_swooshGenerators.emplace_back(new CParticleSwoosh(desc->x40_SSWH.m_token, x150_SSEG)); + x1e0_swooshGenerators.emplace_back(std::make_unique(desc->x40_SSWH.m_token, x150_SSEG)); x1e0_swooshGenerators.back()->DoElectricWarmup(); } } @@ -56,7 +56,7 @@ CParticleElectric::CParticleElectric(const TToken& token) x450_25_haveGPSM = true; x400_gpsmGenerators.reserve(x154_SCNT); for (int i = 0; i < x154_SCNT; ++i) { - x400_gpsmGenerators.emplace_back(new CElementGen(desc->x50_GPSM.m_token)); + x400_gpsmGenerators.emplace_back(std::make_unique(desc->x50_GPSM.m_token)); x400_gpsmGenerators.back()->SetParticleEmission(false); } } @@ -65,15 +65,16 @@ CParticleElectric::CParticleElectric(const TToken& token) x450_26_haveEPSM = true; x410_epsmGenerators.reserve(x154_SCNT); for (int i = 0; i < x154_SCNT; ++i) { - x410_epsmGenerators.emplace_back(new CElementGen(desc->x60_EPSM.m_token)); + x410_epsmGenerators.emplace_back(std::make_unique(desc->x60_EPSM.m_token)); x410_epsmGenerators.back()->SetParticleEmission(false); } } if (x1c_elecDesc->x28_LWD1 || x1c_elecDesc->x2c_LWD2 || x1c_elecDesc->x30_LWD3) { x450_28_haveLWD = true; - for (int i = 0; i < x154_SCNT; ++i) - x2e4_lineManagers.emplace_back(new CLineManager()); + for (int i = 0; i < x154_SCNT; ++i) { + x2e4_lineManagers.emplace_back(std::make_unique()); + } } } @@ -333,7 +334,7 @@ void CParticleElectric::CreateNewParticles(int count) { if (CIntElement* slif = x1c_elecDesc->x4_SLIF.get()) slif->GetValue(x28_currentFrame, lifetime); - x3e8_electricManagers.push_back(CParticleElectricManager(allocIdx, lifetime, x28_currentFrame)); + x3e8_electricManagers.emplace_back(allocIdx, lifetime, x28_currentFrame); CParticleElectricManager& elec = x3e8_electricManagers.back(); CParticleGlobals::instance()->SetParticleLifetime(elec.xc_endFrame - elec.x8_startFrame); int frame = x28_currentFrame - elec.x8_startFrame; @@ -655,7 +656,7 @@ void CParticleElectric::SetLocalScale(const zeus::CVector3f& scale) { } } -void CParticleElectric::SetParticleEmission(bool e) { x450_24_emitting = e; } +void CParticleElectric::SetParticleEmission(bool emitting) { x450_24_emitting = emitting; } void CParticleElectric::SetModulationColor(const zeus::CColor& color) { x1b8_moduColor = color; } @@ -694,10 +695,11 @@ bool CParticleElectric::IsSystemDeletable() const { } std::optional CParticleElectric::GetBounds() const { - if (GetParticleCount() <= 0) - return {}; - else - return x160_systemBounds; + if (GetParticleCount() <= 0) { + return std::nullopt; + } + + return x160_systemBounds; } u32 CParticleElectric::GetParticleCount() const { diff --git a/Runtime/Particle/CParticleElectric.hpp b/Runtime/Particle/CParticleElectric.hpp index 9cc421928..880ec2be3 100644 --- a/Runtime/Particle/CParticleElectric.hpp +++ b/Runtime/Particle/CParticleElectric.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -29,8 +30,8 @@ public: class CLineManager { friend class CParticleElectric; std::vector x0_verts; - float x10_widths[3] = {1.f, 2.f, 3.f}; - zeus::CColor x1c_colors[3]; + std::array x10_widths = {1.f, 2.f, 3.f}; + std::array x1c_colors; zeus::CAABox x28_aabb = zeus::CAABox(); }; @@ -114,17 +115,17 @@ private: void BuildBounds(); public: - CParticleElectric(const TToken& desc); + explicit CParticleElectric(const TToken& desc); bool Update(double) override; - void Render(const CActorLights* = nullptr) override; - void SetOrientation(const zeus::CTransform&) override; - void SetTranslation(const zeus::CVector3f&) override; - void SetGlobalOrientation(const zeus::CTransform&) override; - void SetGlobalTranslation(const zeus::CVector3f&) override; - void SetGlobalScale(const zeus::CVector3f&) override; - void SetLocalScale(const zeus::CVector3f&) override; - void SetParticleEmission(bool) override; + void Render(const CActorLights* lights = nullptr) override; + void SetOrientation(const zeus::CTransform& orientation) override; + void SetTranslation(const zeus::CVector3f& translation) override; + void SetGlobalOrientation(const zeus::CTransform& orientation) override; + void SetGlobalTranslation(const zeus::CVector3f& translation) override; + void SetGlobalScale(const zeus::CVector3f& scale) override; + void SetLocalScale(const zeus::CVector3f& scale) override; + void SetParticleEmission(bool emitting) override; void SetModulationColor(const zeus::CColor&) override; void SetOverrideIPos(const zeus::CVector3f& vec) { x178_overrideIPos.emplace(vec); } void SetOverrideIVel(const zeus::CVector3f& vec) { x188_overrideIVel.emplace(vec); } diff --git a/Runtime/Particle/CParticleSwoosh.cpp b/Runtime/Particle/CParticleSwoosh.cpp index 1bf8c6219..6ab26b711 100644 --- a/Runtime/Particle/CParticleSwoosh.cpp +++ b/Runtime/Particle/CParticleSwoosh.cpp @@ -90,17 +90,19 @@ void CParticleSwoosh::UpdateBounds(const zeus::CVector3f& pos) { x1f0_aabbMin[2] = std::min(pos[2], float(x1f0_aabbMin[2])); } -float CParticleSwoosh::GetLeftRadius(int i) const { +float CParticleSwoosh::GetLeftRadius(size_t i) const { float ret = 0.f; - if (CRealElement* lrad = x1c_desc->x8_LRAD.get()) + if (CRealElement* lrad = x1c_desc->x8_LRAD.get()) { lrad->GetValue(x15c_swooshes[i].x68_frame, ret); + } return ret; } -float CParticleSwoosh::GetRightRadius(int i) const { +float CParticleSwoosh::GetRightRadius(size_t i) const { float ret = 0.f; - if (CRealElement* rrad = x1c_desc->xc_RRAD.get()) + if (CRealElement* rrad = x1c_desc->xc_RRAD.get()) { rrad->GetValue(x15c_swooshes[i].x68_frame, ret); + } return ret; } @@ -115,7 +117,7 @@ void CParticleSwoosh::UpdateTranslationAndOrientation() { CParticleGlobals::instance()->SetParticleLifetime(x1b4_LENG); CParticleGlobals::instance()->SetEmitterTime(x28_curFrame); - for (int i = 0; i < x15c_swooshes.size(); ++i) { + for (size_t i = 0; i < x15c_swooshes.size(); ++i) { SSwooshData& swoosh = x15c_swooshes[i]; if (!swoosh.x0_active) continue; @@ -298,7 +300,7 @@ void CParticleSwoosh::RenderNSidedSpline() { cros = false; int curIdx = x158_curParticle; - for (int i = 0; i < x15c_swooshes.size(); ++i) { + for (size_t i = 0; i < x15c_swooshes.size(); ++i) { bool a0 = x15c_swooshes[WrapIndex(curIdx - 1)].x0_active; bool a1 = x15c_swooshes[WrapIndex(curIdx)].x0_active; if (!a1 || (a1 && !a0)) { @@ -372,9 +374,9 @@ void CParticleSwoosh::RenderNSidedSpline() { if (x1c_desc->x3c_TEXR) { if (x1ec_TSPN > 0) - x1d4_uvs.xMin = (i % x1ec_TSPN) * x1e8_uvSpan; + x1d4_uvs.xMin = float((i % x1ec_TSPN) * x1e8_uvSpan); else - x1d4_uvs.xMin = i * x1e8_uvSpan; + x1d4_uvs.xMin = float(i * x1e8_uvSpan); } float segUvSpan = x1e8_uvSpan / float(x1b0_SPLN + 1); @@ -457,7 +459,7 @@ void CParticleSwoosh::Render3SidedSolidSpline() { int curIdx = x158_curParticle; float curUvSpan = -x1e8_uvSpan; zeus::CColor prevColor0 = zeus::skClear; - for (int i = 0; i < x15c_swooshes.size(); ++i) { + for (size_t i = 0; i < x15c_swooshes.size(); ++i) { SSwooshData& swoosh = x15c_swooshes[curIdx]; curIdx -= 1; @@ -584,7 +586,7 @@ void CParticleSwoosh::Render3SidedSolidNoSplineNoGaps() { bool lastActive = false; zeus::CColor c0 = zeus::skClear; float uv0 = -x1e8_uvSpan; - for (int i = 0; i < x15c_swooshes.size(); ++i) { + for (size_t i = 0; i < x15c_swooshes.size(); ++i) { SSwooshData& swoosh = x15c_swooshes[curIdx]; curIdx -= 1; @@ -662,7 +664,7 @@ void CParticleSwoosh::Render2SidedNoSplineGaps() { int drawStart = 0; bool streaming = false; int curIdx = x158_curParticle; - for (int i = 0; i < x15c_swooshes.size(); ++i) { + for (size_t i = 0; i < x15c_swooshes.size(); ++i) { SSwooshData& swoosh = x15c_swooshes[curIdx]; bool otherActive = x15c_swooshes[WrapIndex(curIdx - 1)].x0_active; @@ -732,7 +734,7 @@ void CParticleSwoosh::Render2SidedNoSplineNoGaps() { .origin; zeus::CVector3f dotVec = zeus::skZero3f; - for (int i = 0; i < x15c_swooshes.size(); ++i) { + for (size_t i = 0; i < x15c_swooshes.size(); ++i) { SSwooshData& swoosh = x15c_swooshes[curIdx]; curIdx -= 1; @@ -775,13 +777,13 @@ void CParticleSwoosh::Render2SidedNoSplineNoGaps() { if (x1ec_TSPN > 0) uvOffset += x1e8_uvSpan; else - uvOffset = i * x1e8_uvSpan; + uvOffset = float(i * x1e8_uvSpan); } } } } } else { - for (int i = 0; i < x15c_swooshes.size(); ++i) { + for (size_t i = 0; i < x15c_swooshes.size(); ++i) { SSwooshData& swoosh = x15c_swooshes[curIdx]; curIdx -= 1; @@ -826,12 +828,12 @@ void CParticleSwoosh::Render2SidedNoSplineNoGaps() { if (x1ec_TSPN > 0) uvOffset += x1e8_uvSpan; else - uvOffset = i * x1e8_uvSpan; + uvOffset = float(i* x1e8_uvSpan); } } } } else { - for (int i = 0; i < x15c_swooshes.size(); ++i) { + for (size_t i = 0; i < x15c_swooshes.size(); ++i) { SSwooshData& swoosh = x15c_swooshes[curIdx]; curIdx -= 1; diff --git a/Runtime/Particle/CParticleSwoosh.hpp b/Runtime/Particle/CParticleSwoosh.hpp index a2680198a..ed421eeca 100644 --- a/Runtime/Particle/CParticleSwoosh.hpp +++ b/Runtime/Particle/CParticleSwoosh.hpp @@ -119,8 +119,8 @@ class CParticleSwoosh : public CParticleGen { bool IsValid() const { return x1b4_LENG >= 2 && x1b8_SIDE >= 2; } void UpdateMaxRadius(float r); void UpdateBounds(const zeus::CVector3f& pos); - float GetLeftRadius(int i) const; - float GetRightRadius(int i) const; + float GetLeftRadius(size_t i) const; + float GetRightRadius(size_t i) const; void UpdateSwooshTranslation(const zeus::CVector3f& translation); void UpdateTranslationAndOrientation(); diff --git a/Runtime/Particle/CRealElement.hpp b/Runtime/Particle/CRealElement.hpp index 635d6c4db..034bc8447 100644 --- a/Runtime/Particle/CRealElement.hpp +++ b/Runtime/Particle/CRealElement.hpp @@ -20,7 +20,7 @@ class CREKeyframeEmitter : public CRealElement { std::vector x18_keys; public: - CREKeyframeEmitter(CInputStream& in); + explicit CREKeyframeEmitter(CInputStream& in); bool GetValue(int frame, float& valOut) const override; }; @@ -38,7 +38,7 @@ class CREConstant : public CRealElement { float x4_val; public: - CREConstant(float val) : x4_val(val) {} + explicit CREConstant(float val) : x4_val(val) {} bool GetValue(int frame, float& valOut) const override; bool IsConstant() const override { return true; } }; @@ -133,7 +133,7 @@ class CRETimeScale : public CRealElement { std::unique_ptr x4_a; public: - CRETimeScale(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CRETimeScale(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, float& valOut) const override; }; @@ -141,7 +141,7 @@ class CRELifetimePercent : public CRealElement { std::unique_ptr x4_percentVal; public: - CRELifetimePercent(std::unique_ptr&& a) : x4_percentVal(std::move(a)) {} + explicit CRELifetimePercent(std::unique_ptr&& a) : x4_percentVal(std::move(a)) {} bool GetValue(int frame, float& valOut) const override; }; @@ -256,7 +256,7 @@ class CREVectorMagnitude : public CRealElement { std::unique_ptr x4_a; public: - CREVectorMagnitude(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CREVectorMagnitude(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, float& valOut) const override; }; @@ -264,7 +264,7 @@ class CREVectorXToReal : public CRealElement { std::unique_ptr x4_a; public: - CREVectorXToReal(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CREVectorXToReal(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, float& valOut) const override; }; @@ -272,7 +272,7 @@ class CREVectorYToReal : public CRealElement { std::unique_ptr x4_a; public: - CREVectorYToReal(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CREVectorYToReal(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, float& valOut) const override; }; @@ -280,7 +280,7 @@ class CREVectorZToReal : public CRealElement { std::unique_ptr x4_a; public: - CREVectorZToReal(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CREVectorZToReal(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, float& valOut) const override; }; @@ -288,7 +288,7 @@ class CREExternalVar : public CRealElement { std::unique_ptr x4_a; public: - CREExternalVar(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CREExternalVar(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, float& valOut) const override; }; @@ -326,7 +326,7 @@ class CREGetComponentRed : public CRealElement { std::unique_ptr x4_a; public: - CREGetComponentRed(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CREGetComponentRed(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, float& valOut) const override; }; @@ -335,7 +335,7 @@ class CREGetComponentGreen : public CRealElement { std::unique_ptr x4_a; public: - CREGetComponentGreen(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CREGetComponentGreen(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, float& valOut) const override; }; @@ -344,7 +344,7 @@ class CREGetComponentBlue : public CRealElement { std::unique_ptr x4_a; public: - CREGetComponentBlue(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CREGetComponentBlue(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, float& valOut) const override; }; @@ -353,7 +353,7 @@ class CREGetComponentAlpha : public CRealElement { std::unique_ptr x4_a; public: - CREGetComponentAlpha(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CREGetComponentAlpha(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, float& valOut) const override; }; diff --git a/Runtime/Particle/CSpawnSystemKeyframeData.hpp b/Runtime/Particle/CSpawnSystemKeyframeData.hpp index f30d580e7..d254e14ad 100644 --- a/Runtime/Particle/CSpawnSystemKeyframeData.hpp +++ b/Runtime/Particle/CSpawnSystemKeyframeData.hpp @@ -24,7 +24,7 @@ public: void LoadToken(CSimplePool* pool); public: - CSpawnSystemKeyframeInfo(CInputStream& in); + explicit CSpawnSystemKeyframeInfo(CInputStream& in); TLockedToken& GetToken() { return x10_token; } }; @@ -36,7 +36,7 @@ private: std::vector>> x10_spawns; public: - CSpawnSystemKeyframeData(CInputStream& in); + explicit CSpawnSystemKeyframeData(CInputStream& in); void LoadAllSpawnedSystemTokens(CSimplePool* pool); std::vector& GetSpawnedSystemsAtFrame(u32 frame); }; diff --git a/Runtime/Particle/CUVElement.hpp b/Runtime/Particle/CUVElement.hpp index 1abb52e0b..8aa6fc566 100644 --- a/Runtime/Particle/CUVElement.hpp +++ b/Runtime/Particle/CUVElement.hpp @@ -29,7 +29,7 @@ struct CUVEConstant : public CUVElement { TLockedToken x4_tex; public: - CUVEConstant(TToken&& tex) : x4_tex(std::move(tex)) {} + explicit CUVEConstant(TToken&& tex) : x4_tex(std::move(tex)) {} TLockedToken GetValueTexture(int frame) const override { return TLockedToken(x4_tex); } void GetValueUV(int frame, SUVElementSet& valOut) const override { valOut = {0.f, 0.f, 1.f, 1.f}; } bool HasConstantTexture() const override { return true; } diff --git a/Runtime/Particle/CVectorElement.cpp b/Runtime/Particle/CVectorElement.cpp index 807f4ce02..27fd0531d 100644 --- a/Runtime/Particle/CVectorElement.cpp +++ b/Runtime/Particle/CVectorElement.cpp @@ -19,10 +19,11 @@ CVEKeyframeEmitter::CVEKeyframeEmitter(CInputStream& in) { x10_loopEnd = in.readUint32Big(); x14_loopStart = in.readUint32Big(); - u32 count = in.readUint32Big(); + const u32 count = in.readUint32Big(); x18_keys.reserve(count); - for (u32 i = 0; i < count; ++i) - x18_keys.push_back(in.readVec3fBig()); + for (u32 i = 0; i < count; ++i) { + x18_keys.emplace_back(in.readVec3fBig()); + } } bool CVEKeyframeEmitter::GetValue(int frame, zeus::CVector3f& valOut) const { diff --git a/Runtime/Particle/CVectorElement.hpp b/Runtime/Particle/CVectorElement.hpp index b0682a773..940326a10 100644 --- a/Runtime/Particle/CVectorElement.hpp +++ b/Runtime/Particle/CVectorElement.hpp @@ -22,7 +22,7 @@ class CVEKeyframeEmitter : public CVectorElement { std::vector x18_keys; public: - CVEKeyframeEmitter(CInputStream& in); + explicit CVEKeyframeEmitter(CInputStream& in); bool GetValue(int frame, zeus::CVector3f& valOut) const override; }; @@ -138,7 +138,7 @@ class CVERealToVector : public CVectorElement { std::unique_ptr x4_a; public: - CVERealToVector(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CVERealToVector(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, zeus::CVector3f& valOut) const override; }; @@ -204,7 +204,7 @@ class CVEColorToVector : public CVectorElement { std::unique_ptr x4_a; public: - CVEColorToVector(std::unique_ptr&& a) : x4_a(std::move(a)) {} + explicit CVEColorToVector(std::unique_ptr&& a) : x4_a(std::move(a)) {} bool GetValue(int frame, zeus::CVector3f& valOut) const override; }; diff --git a/Runtime/RetroTypes.hpp b/Runtime/RetroTypes.hpp index a3ecfe4cf..6c0c70628 100644 --- a/Runtime/RetroTypes.hpp +++ b/Runtime/RetroTypes.hpp @@ -33,14 +33,14 @@ public: constexpr CAssetId() noexcept = default; constexpr CAssetId(u64 v) noexcept { Assign(v); } explicit CAssetId(CInputStream& in); - constexpr bool IsValid() const noexcept { return id != UINT64_MAX; } - constexpr u64 Value() const noexcept { return id; } + [[nodiscard]] constexpr bool IsValid() const noexcept { return id != UINT64_MAX; } + [[nodiscard]] constexpr u64 Value() const noexcept { return id; } constexpr void Assign(u64 v) noexcept { id = (v == UINT32_MAX ? UINT64_MAX : (v == 0 ? UINT64_MAX : v)); } constexpr void Reset() noexcept { id = UINT64_MAX; } void PutTo(COutputStream& out); - constexpr bool operator==(const CAssetId& other) const noexcept { return id == other.id; } - constexpr bool operator!=(const CAssetId& other) const noexcept { return !operator==(other); } - constexpr bool operator<(const CAssetId& other) const noexcept { return id < other.id; } + [[nodiscard]] constexpr bool operator==(CAssetId other) const noexcept { return id == other.id; } + [[nodiscard]] constexpr bool operator!=(CAssetId other) const noexcept { return !operator==(other); } + [[nodiscard]] constexpr bool operator<(CAssetId other) const noexcept { return id < other.id; } }; //#define kInvalidAssetId CAssetId() @@ -50,12 +50,12 @@ struct SObjectTag { CAssetId id; constexpr explicit operator bool() const noexcept { return id.IsValid(); } - constexpr bool operator==(const SObjectTag& other) const noexcept { return id == other.id; } - constexpr bool operator!=(const SObjectTag& other) const noexcept { return !operator==(other); } - constexpr bool operator<(const SObjectTag& other) const noexcept { return id < other.id; } + [[nodiscard]] constexpr bool operator==(const SObjectTag& other) const noexcept { return id == other.id; } + [[nodiscard]] constexpr bool operator!=(const SObjectTag& other) const noexcept { return !operator==(other); } + [[nodiscard]] constexpr bool operator<(const SObjectTag& other) const noexcept { return id < other.id; } constexpr SObjectTag() noexcept = default; constexpr SObjectTag(FourCC tp, CAssetId rid) noexcept : type(tp), id(rid) {} - SObjectTag(CInputStream& in) { + explicit SObjectTag(CInputStream& in) { in.readBytesToBuf(&type, 4); id = CAssetId(in); } @@ -70,14 +70,14 @@ struct TEditorId { constexpr TEditorId() noexcept = default; constexpr TEditorId(u32 idin) noexcept : id(idin) {} - constexpr u8 LayerNum() const noexcept { return u8((id >> 26) & 0x3f); } - constexpr u16 AreaNum() const noexcept { return u16((id >> 16) & 0x3ff); } - constexpr u16 Id() const noexcept { return u16(id & 0xffff); } - constexpr bool operator<(const TEditorId& other) const noexcept { return (id & 0x3ffffff) < (other.id & 0x3ffffff); } - constexpr bool operator==(const TEditorId& other) const noexcept { + [[nodiscard]] constexpr u8 LayerNum() const noexcept { return u8((id >> 26) & 0x3f); } + [[nodiscard]] constexpr u16 AreaNum() const noexcept { return u16((id >> 16) & 0x3ff); } + [[nodiscard]] constexpr u16 Id() const noexcept { return u16(id & 0xffff); } + [[nodiscard]] constexpr bool operator<(TEditorId other) const noexcept { return (id & 0x3ffffff) < (other.id & 0x3ffffff); } + [[nodiscard]] constexpr bool operator==(TEditorId other) const noexcept { return (id & 0x3ffffff) == (other.id & 0x3ffffff); } - constexpr bool operator!=(const TEditorId& other) const noexcept { return !operator==(other); } + [[nodiscard]] constexpr bool operator!=(TEditorId other) const noexcept { return !operator==(other); } }; #define kInvalidEditorId TEditorId() @@ -87,11 +87,11 @@ struct TUniqueId { constexpr TUniqueId() noexcept = default; constexpr TUniqueId(u16 value, u16 version) noexcept : id(value | (version << 10)) {} - constexpr u16 Version() const noexcept { return u16((id >> 10) & 0x3f); } - constexpr u16 Value() const noexcept { return u16(id & 0x3ff); } - constexpr bool operator<(const TUniqueId& other) const noexcept { return id < other.id; } - constexpr bool operator==(const TUniqueId& other) const noexcept { return id == other.id; } - constexpr bool operator!=(const TUniqueId& other) const noexcept { return !operator==(other); } + [[nodiscard]] constexpr u16 Version() const noexcept { return u16((id >> 10) & 0x3f); } + [[nodiscard]] constexpr u16 Value() const noexcept { return u16(id & 0x3ff); } + [[nodiscard]] constexpr bool operator<(TUniqueId other) const noexcept { return id < other.id; } + [[nodiscard]] constexpr bool operator==(TUniqueId other) const noexcept { return id == other.id; } + [[nodiscard]] constexpr bool operator!=(TUniqueId other) const noexcept { return !operator==(other); } }; #define kInvalidUniqueId TUniqueId() @@ -122,7 +122,7 @@ public: #endif template -T GetAverage(const T* v, s32 count) noexcept { +[[nodiscard]] T GetAverage(const T* v, s32 count) noexcept { T r = v[0]; for (s32 i = 1; i < count; ++i) r += v[i]; @@ -146,22 +146,24 @@ public: } } - std::optional GetAverage() const { - if (this->empty()) - return {}; + [[nodiscard]] std::optional GetAverage() const { + if (this->empty()) { + return std::nullopt; + } return {urde::GetAverage(this->data(), this->size())}; } - std::optional GetEntry(int i) const { - if (i >= this->size()) - return {}; + [[nodiscard]] std::optional GetEntry(int i) const { + if (i >= this->size()) { + return std::nullopt; + } return this->operator[](i); } void Clear() { this->clear(); } - size_t Size() const { return this->size(); } + [[nodiscard]] size_t Size() const { return this->size(); } }; } // namespace urde diff --git a/Runtime/Weapon/CAuxWeapon.cpp b/Runtime/Weapon/CAuxWeapon.cpp index af2d5eeb2..64722caf8 100644 --- a/Runtime/Weapon/CAuxWeapon.cpp +++ b/Runtime/Weapon/CAuxWeapon.cpp @@ -1,5 +1,7 @@ #include "Runtime/Weapon/CAuxWeapon.hpp" +#include + #include "Runtime/CSimplePool.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Weapon/CEnergyProjectile.hpp" @@ -7,9 +9,27 @@ #include "Runtime/Weapon/CWaveBuster.hpp" namespace urde { +constexpr CCameraShakeData skHardShake{ + 0.3f, + 100.f, + 0, + zeus::skZero3f, + {}, + { + true, + {false, 0.f, 0.f, 0.3f, -2.f}, + {true, 0.f, 0.f, 0.05f, 0.5f}, + }, + {}, +}; -static const CCameraShakeData skHardShake = { - 0.3f, 100.f, 0, zeus::skZero3f, {}, {1, {0, 0.f, 0.f, 0.3f, -2.f}, {1, 0.f, 0.f, 0.05f, 0.5f}}, {}}; +constexpr std::array skComboNames{ + "SuperMissile", "IceCombo", "WaveBuster", "FlameThrower", "SuperMissile", +}; + +constexpr std::array skSoundId{ + 1810, 1837, 1847, 1842, 1810, +}; CAuxWeapon::CAuxWeapon(TUniqueId playerId) : x0_missile(g_SimplePool->GetObj("Missile")) @@ -23,11 +43,10 @@ CAuxWeapon::CAuxWeapon(TUniqueId playerId) InitComboData(); } -static const char* skComboNames[] = {"SuperMissile", "IceCombo", "WaveBuster", "FlameThrower", "SuperMissile"}; - void CAuxWeapon::InitComboData() { - for (int i = 0; i < 5; ++i) - x28_combos.push_back(g_SimplePool->GetObj(skComboNames[i])); + for (const auto comboName : skComboNames) { + x28_combos.push_back(g_SimplePool->GetObj(comboName)); + } } void CAuxWeapon::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) { @@ -242,8 +261,6 @@ void CAuxWeapon::CreateWaveBusterBeam(EProjectileAttrib attribs, TUniqueId homin x74_firingBeamId = CPlayerState::EBeamId::Wave; } -static const u16 skSoundId[] = {1810, 1837, 1847, 1842, 1810}; - void CAuxWeapon::LaunchMissile(float dt, bool underwater, bool charged, CPlayerState::EBeamId currentBeam, EProjectileAttrib attrib, const zeus::CTransform& xf, TUniqueId homingId, CStateManager& mgr) { diff --git a/Runtime/Weapon/CBeamInfo.hpp b/Runtime/Weapon/CBeamInfo.hpp index d87971799..8df00f49b 100644 --- a/Runtime/Weapon/CBeamInfo.hpp +++ b/Runtime/Weapon/CBeamInfo.hpp @@ -31,7 +31,7 @@ class CBeamInfo { zeus::CColor x40_outerColor; public: - CBeamInfo(CInputStream& in) + explicit CBeamInfo(CInputStream& in) : x0_(in.readUint32Big()) , x4_beamAttributes(in.readUint32Big()) , x8_contactFxId(in.readUint32Big()) diff --git a/Runtime/Weapon/CBeamProjectile.cpp b/Runtime/Weapon/CBeamProjectile.cpp index 523150811..66ec6059c 100644 --- a/Runtime/Weapon/CBeamProjectile.cpp +++ b/Runtime/Weapon/CBeamProjectile.cpp @@ -25,13 +25,16 @@ CBeamProjectile::CBeamProjectile(const TToken& wDesc, std::s } std::optional CBeamProjectile::GetTouchBounds() const { - if (!GetActive()) - return {}; + if (!GetActive()) { + return std::nullopt; + } + if (x464_25_enableTouchDamage) { - zeus::CVector3f pos = GetTranslation(); + const zeus::CVector3f pos = GetTranslation(); return {{pos - 0.1f, pos + 0.1f}}; } - return {}; + + return std::nullopt; } void CBeamProjectile::CalculateRenderBounds() { x9c_renderBounds = x354_.getTransformedAABox(x324_xf); } diff --git a/Runtime/Weapon/CBomb.cpp b/Runtime/Weapon/CBomb.cpp index 9f6216dfc..71b00a877 100644 --- a/Runtime/Weapon/CBomb.cpp +++ b/Runtime/Weapon/CBomb.cpp @@ -62,7 +62,7 @@ void CBomb::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManag CActor::AcceptScriptMsg(msg, uid, mgr); } -static CMaterialFilter kSolidFilter = +constexpr CMaterialFilter kSolidFilter = CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::Character, EMaterialTypes::Player, EMaterialTypes::ProjectilePassthrough}); void CBomb::Think(float dt, urde::CStateManager& mgr) { @@ -114,7 +114,7 @@ void CBomb::Think(float dt, urde::CStateManager& mgr) { x184_particle2->SetGlobalTranslation(GetTranslation()); } -void CBomb::AddToRenderer(const zeus::CFrustum& frustum, const urde::CStateManager& mgr) const { +void CBomb::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { zeus::CVector3f origin = GetTranslation(); float ballRadius = mgr.GetPlayer().GetMorphBall()->GetBallRadius(); diff --git a/Runtime/Weapon/CBomb.hpp b/Runtime/Weapon/CBomb.hpp index bde620c07..eaaf2f313 100644 --- a/Runtime/Weapon/CBomb.hpp +++ b/Runtime/Weapon/CBomb.hpp @@ -33,8 +33,8 @@ public: void Accept(IVisitor&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float, CStateManager&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager&) const override {} + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager&) override {} void Touch(CActor&, CStateManager&) override; void Explode(const zeus::CVector3f&, CStateManager&); void UpdateLight(float, CStateManager&); diff --git a/Runtime/Weapon/CEnergyProjectile.cpp b/Runtime/Weapon/CEnergyProjectile.cpp index 64933d2a7..cfc6e12d0 100644 --- a/Runtime/Weapon/CEnergyProjectile.cpp +++ b/Runtime/Weapon/CEnergyProjectile.cpp @@ -185,7 +185,7 @@ void CEnergyProjectile::Think(float dt, CStateManager& mgr) { mgr.FreeScriptObject(GetUniqueId()); } -void CEnergyProjectile::Render(const CStateManager& mgr) const { +void CEnergyProjectile::Render(CStateManager& mgr) { SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(fmt("CEnergyProjectile::Render WPSC_{}"), x2cc_wpscId).c_str(), zeus::skOrange); CPlayerState::EPlayerVisor visor = mgr.GetPlayerState()->GetActiveVisor(mgr); @@ -217,7 +217,7 @@ void CEnergyProjectile::Render(const CStateManager& mgr) const { } } -void CEnergyProjectile::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { +void CEnergyProjectile::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { auto bounds = x170_projectile.GetBounds(); if (bounds && !frustum.aabbFrustumTest(*bounds)) return; @@ -225,8 +225,9 @@ void CEnergyProjectile::AddToRenderer(const zeus::CFrustum& frustum, const CStat CPlayerState::EPlayerVisor visor = mgr.GetPlayerState()->GetActiveVisor(mgr); if (visor != CPlayerState::EPlayerVisor::XRay && ((xe8_projectileAttribs & EProjectileAttrib::Ice) != EProjectileAttrib::Ice || - mgr.GetThermalDrawFlag() != EThermalDrawFlag::Hot)) + mgr.GetThermalDrawFlag() != EThermalDrawFlag::Hot)) { x170_projectile.AddToRenderer(); + } EnsureRendered(mgr); } diff --git a/Runtime/Weapon/CEnergyProjectile.hpp b/Runtime/Weapon/CEnergyProjectile.hpp index e8289db5d..6156e0e0f 100644 --- a/Runtime/Weapon/CEnergyProjectile.hpp +++ b/Runtime/Weapon/CEnergyProjectile.hpp @@ -39,8 +39,8 @@ public: void ResolveCollisionWithWorld(const CRayCastResult& res, CStateManager& mgr); void ResolveCollisionWithActor(const CRayCastResult& res, CActor& act, CStateManager& mgr); void Think(float dt, CStateManager& mgr); - void Render(const CStateManager& mgr) const; - void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const; + void Render(CStateManager& mgr); + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr); void Touch(CActor& act, CStateManager& mgr); virtual bool Explode(const zeus::CVector3f& pos, const zeus::CVector3f& normal, EWeaponCollisionResponseTypes type, CStateManager& mgr, const CDamageVulnerability& dVuln, TUniqueId hitActor); diff --git a/Runtime/Weapon/CFlameThrower.cpp b/Runtime/Weapon/CFlameThrower.cpp index 9ca7b156c..154c80e31 100644 --- a/Runtime/Weapon/CFlameThrower.cpp +++ b/Runtime/Weapon/CFlameThrower.cpp @@ -90,12 +90,12 @@ void CFlameThrower::CreateFlameParticles(CStateManager& mgr) { CreateProjectileLight("FlameThrower_Light"sv, x348_flameGen->GetLight(), mgr); } -void CFlameThrower::AddToRenderer(const zeus::CFrustum&, const CStateManager& mgr) const { +void CFlameThrower::AddToRenderer(const zeus::CFrustum&, CStateManager& mgr) { g_Renderer->AddParticleGen(*x348_flameGen); EnsureRendered(mgr, x2e8_flameXf.origin, GetRenderBounds()); } -void CFlameThrower::Render(const CStateManager&) const {} +void CFlameThrower::Render(CStateManager&) {} std::optional CFlameThrower::GetTouchBounds() const { return std::nullopt; } @@ -139,49 +139,62 @@ CRayCastResult CFlameThrower::DoCollisionCheck(TUniqueId& idOut, const zeus::CAA rstl::reserved_vector nearList; mgr.BuildNearList(nearList, aabb, CMaterialFilter::skPassEverything, this); const auto& colPoints = x34c_flameWarp.GetCollisionPoints(); - if (x400_27_coneCollision && colPoints.size() > 0) { - float radiusPitch = (x34c_flameWarp.GetMaxSize() - x34c_flameWarp.GetMinSize()) / - float(colPoints.size()) * 0.5f; + + if (x400_27_coneCollision && !colPoints.empty()) { + const float radiusPitch = + (x34c_flameWarp.GetMaxSize() - x34c_flameWarp.GetMinSize()) / float(colPoints.size()) * 0.5f; float curRadius = radiusPitch; - for (int i = 1; i < colPoints.size(); ++i) { - zeus::CVector3f delta = colPoints[i] - colPoints[i - 1]; + + for (size_t i = 1; i < colPoints.size(); ++i) { + const zeus::CVector3f delta = colPoints[i] - colPoints[i - 1]; zeus::CTransform lookXf = zeus::lookAt(colPoints[i - 1], colPoints[i]); lookXf.origin = delta * 0.5f + colPoints[i - 1]; - zeus::COBBox obb(lookXf, {curRadius, delta.magnitude() * 0.5f, curRadius}); - for (TUniqueId id : nearList) { - if (CActor* act = static_cast(mgr.ObjectById(id))) { - CProjectileTouchResult tres = CanCollideWith(*act, mgr); - if (tres.GetActorId() == kInvalidUniqueId) + const zeus::COBBox obb(lookXf, {curRadius, delta.magnitude() * 0.5f, curRadius}); + + for (const TUniqueId id : nearList) { + if (auto* act = static_cast(mgr.ObjectById(id))) { + const CProjectileTouchResult tres = CanCollideWith(*act, mgr); + if (tres.GetActorId() == kInvalidUniqueId) { continue; - auto tb = act->GetTouchBounds(); - if (!tb) + } + + const auto tb = act->GetTouchBounds(); + if (!tb) { continue; + } + if (obb.AABoxIntersectsBox(*tb)) { - CCollidableAABox caabb(*tb, act->GetMaterialList()); - zeus::CVector3f flameToAct = act->GetAimPosition(mgr, 0.f) - x2e8_flameXf.origin; - float flameToActDist = flameToAct.magnitude(); - CInternalRayCastStructure rc(x2e8_flameXf.origin, flameToAct.normalized(), flameToActDist, - {}, CMaterialFilter::skPassEverything); - CRayCastResult cres = caabb.CastRayInternal(rc); - if (cres.IsInvalid()) + const CCollidableAABox caabb(*tb, act->GetMaterialList()); + const zeus::CVector3f flameToAct = act->GetAimPosition(mgr, 0.f) - x2e8_flameXf.origin; + const float flameToActDist = flameToAct.magnitude(); + const CInternalRayCastStructure rc(x2e8_flameXf.origin, flameToAct.normalized(), flameToActDist, {}, + CMaterialFilter::skPassEverything); + const CRayCastResult cres = caabb.CastRayInternal(rc); + if (cres.IsInvalid()) { continue; + } return cres; } } } + curRadius += radiusPitch; } } else { - for (int i = 0; i < colPoints.size() - 1; ++i) { - zeus::CVector3f delta = colPoints[i + 1] - colPoints[i]; - float deltaMag = delta.magnitude(); - if (deltaMag <= 0.f) + for (size_t i = 0; i < colPoints.size() - 1; ++i) { + const zeus::CVector3f delta = colPoints[i + 1] - colPoints[i]; + const float deltaMag = delta.magnitude(); + if (deltaMag <= 0.f) { break; - CRayCastResult cres = RayCollisionCheckWithWorld(idOut, colPoints[i], colPoints[i + 1], deltaMag, nearList, mgr); - if (cres.IsValid()) + } + + const CRayCastResult cres = RayCollisionCheckWithWorld(idOut, colPoints[i], colPoints[i + 1], deltaMag, nearList, mgr); + if (cres.IsValid()) { return cres; + } } } + return ret; } diff --git a/Runtime/Weapon/CFlameThrower.hpp b/Runtime/Weapon/CFlameThrower.hpp index 4a9890aca..423f8e7d4 100644 --- a/Runtime/Weapon/CFlameThrower.hpp +++ b/Runtime/Weapon/CFlameThrower.hpp @@ -56,8 +56,8 @@ public: void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float, CStateManager&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager& mgr) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager& mgr) override; std::optional GetTouchBounds() const override; void Touch(CActor& actor, CStateManager& mgr) override; void SetTransform(const zeus::CTransform& xf, float); diff --git a/Runtime/Weapon/CGameProjectile.cpp b/Runtime/Weapon/CGameProjectile.cpp index 62a8affdd..312c3cb32 100644 --- a/Runtime/Weapon/CGameProjectile.cpp +++ b/Runtime/Weapon/CGameProjectile.cpp @@ -25,7 +25,8 @@ CGameProjectile::CGameProjectile(bool active, const TToken& CMaterialFilter::MakeIncludeExclude( {EMaterialTypes::Solid, EMaterialTypes::NonSolidDamageable}, {EMaterialTypes::Projectile, EMaterialTypes::ProjectilePassthrough, excludeMat}), - CMaterialList(), dInfo, attribs | GetBeamAttribType(wType), CModelData::CModelDataNull()) + CMaterialList(EMaterialTypes::Projectile), dInfo, attribs | GetBeamAttribType(wType), + CModelData::CModelDataNull()) , x158_visorParticle(visorParticle) , x168_visorSfx(visorSfx) , x170_projectile(wDesc, xf.origin, xf.basis, scale, @@ -45,24 +46,35 @@ CGameProjectile::CGameProjectile(bool active, const TToken& void CGameProjectile::Accept(urde::IVisitor& visitor) { visitor.Visit(this); } void CGameProjectile::ResolveCollisionWithActor(const CRayCastResult& res, CActor& act, CStateManager& mgr) { - zeus::CVector3f revDir = -x34_transform.basis[1].normalized(); - if (TCastToPtr(act)) { - if (x158_visorParticle && mgr.GetPlayer().GetCameraState() == CPlayer::EPlayerCameraState::FirstPerson) { - if (zeus::radToDeg(std::acos( - mgr.GetCameraManager()->GetCurrentCameraTransform(mgr).basis[1].normalized().dot(revDir))) <= 45.f) { - /* Hit us head on! Draw Billboard! */ - std::optional> bb = {*x158_visorParticle}; - CHUDBillboardEffect* effect = new CHUDBillboardEffect( - bb, {}, mgr.AllocateUniqueId(), true, "VisorAcid", CHUDBillboardEffect::GetNearClipDistance(mgr), - CHUDBillboardEffect::GetScaleForPOV(mgr), zeus::skWhite, zeus::skOne3f, - zeus::skZero3f); - mgr.AddObject(effect); - CSfxManager::SfxStart(x168_visorSfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); - if (x2e4_28_sendProjectileCollideMsg) - mgr.SendScriptMsg(&mgr.GetPlayer(), GetUniqueId(), EScriptObjectMessage::ProjectileCollide); - } - } + const zeus::CVector3f revDir = -x34_transform.basis[1].normalized(); + const TCastToConstPtr player(act); + + if (!player) { + return; } + + if (!x158_visorParticle || mgr.GetPlayer().GetCameraState() != CPlayer::EPlayerCameraState::FirstPerson) { + return; + } + + if (zeus::radToDeg( + std::acos(mgr.GetCameraManager()->GetCurrentCameraTransform(mgr).basis[1].normalized().dot(revDir))) > 45.f) { + return; + } + + // Hit us head on! Draw Billboard! + std::optional> bb = {*x158_visorParticle}; + auto* effect = new CHUDBillboardEffect( + bb, {}, mgr.AllocateUniqueId(), true, "VisorAcid", CHUDBillboardEffect::GetNearClipDistance(mgr), + CHUDBillboardEffect::GetScaleForPOV(mgr), zeus::skWhite, zeus::skOne3f, zeus::skZero3f); + mgr.AddObject(effect); + CSfxManager::SfxStart(x168_visorSfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); + + if (!x2e4_28_sendProjectileCollideMsg) { + return; + } + + mgr.SendScriptMsg(&mgr.GetPlayer(), GetUniqueId(), EScriptObjectMessage::ProjectileCollide); } void CGameProjectile::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId /*uid*/, CStateManager& mgr) { @@ -114,14 +126,14 @@ void CGameProjectile::Chase(float dt, CStateManager& mgr) { if (!x170_projectile.IsProjectileActive() || x2c0_homingTargetId == kInvalidUniqueId) return; - if (TCastToConstPtr act = mgr.GetObjectById(x2c0_homingTargetId)) { + if (const TCastToConstPtr act = mgr.GetObjectById(x2c0_homingTargetId)) { if (!act->GetMaterialList().HasMaterial(EMaterialTypes::Target) && !act->GetMaterialList().HasMaterial(EMaterialTypes::Player)) { x2c0_homingTargetId = kInvalidUniqueId; } else { zeus::CVector3f homingPos = act->GetHomingPosition(mgr, 0.f); - TCastToConstPtr swarm = act.GetPtr(); + const TCastToConstPtr swarm = act.GetPtr(); if (swarm) { int lockOnId = swarm->GetCurrentLockOnId(); if (swarm->GetLockOnLocationValid(lockOnId)) { @@ -210,21 +222,23 @@ CRayCastResult CGameProjectile::DoCollisionCheck(TUniqueId& idOut, CStateManager void CGameProjectile::ApplyDamageToActors(CStateManager& mgr, const CDamageInfo& dInfo) { if (x2c6_pendingDamagee != kInvalidUniqueId) { - if (TCastToPtr act = mgr.ObjectById(x2c6_pendingDamagee)) { + if (const TCastToConstPtr act = mgr.ObjectById(x2c6_pendingDamagee)) { mgr.ApplyDamage(GetUniqueId(), act->GetUniqueId(), xec_ownerId, dInfo, xf8_filter, x34_transform.basis[1]); if ((xe8_projectileAttribs & EProjectileAttrib::PlayerUnFreeze) == EProjectileAttrib::PlayerUnFreeze && - mgr.GetPlayer().GetUniqueId() == act->GetUniqueId() && mgr.GetPlayer().GetFrozenState()) + mgr.GetPlayer().GetUniqueId() == act->GetUniqueId() && mgr.GetPlayer().GetFrozenState()) { mgr.GetPlayer().UnFreeze(mgr); + } } x2c6_pendingDamagee = kInvalidUniqueId; } - for (CProjectileTouchResult& res : x2d0_touchResults) { - if (TCastToConstPtr act = mgr.GetObjectById(res.GetActorId())) { + for (const CProjectileTouchResult& res : x2d0_touchResults) { + if (const TCastToConstPtr act = mgr.GetObjectById(res.GetActorId())) { mgr.ApplyDamage(GetUniqueId(), act->GetUniqueId(), xec_ownerId, dInfo, xf8_filter, x34_transform.basis[1]); if ((xe8_projectileAttribs & EProjectileAttrib::PlayerUnFreeze) == EProjectileAttrib::PlayerUnFreeze && - mgr.GetPlayer().GetUniqueId() == act->GetUniqueId() && mgr.GetPlayer().GetFrozenState()) + mgr.GetPlayer().GetUniqueId() == act->GetUniqueId() && mgr.GetPlayer().GetFrozenState()) { mgr.GetPlayer().UnFreeze(mgr); + } } } @@ -270,10 +284,10 @@ CRayCastResult CGameProjectile::RayCollisionCheckWithWorld(TUniqueId& idOut, con } } else { auto tb = ent->GetTouchBounds(); - CGameProjectile* projObj = nullptr; - if (TCastToPtr door = ent) { + const CGameProjectile* projObj = nullptr; + if (const TCastToConstPtr door = ent) { tb = door->GetProjectileBounds(); - } else if (TCastToPtr proj = ent) { + } else if (const TCastToConstPtr proj = ent) { tb.emplace(proj->GetProjectileBounds()); projObj = proj.GetPtr(); } @@ -308,112 +322,120 @@ CRayCastResult CGameProjectile::RayCollisionCheckWithWorld(TUniqueId& idOut, con CProjectileTouchResult CGameProjectile::CanCollideWith(CActor& act, CStateManager& mgr) const { if (act.GetDamageVulnerability()->GetVulnerability(x12c_curDamageInfo.GetWeaponMode(), false) == EVulnerability::PassThrough) { - return {kInvalidUniqueId, {}}; + return {kInvalidUniqueId, std::nullopt}; + } + + if (TCastToConstPtr(act)) { + return CanCollideWithTrigger(act, mgr); + } else if (TCastToConstPtr(act) || TCastToConstPtr(act) || + CPatterned::CastTo(&act)) { + return CanCollideWithComplexCollision(act, mgr); } else { - if (TCastToPtr(act)) { - return CanCollideWithTrigger(act, mgr); - } else if (TCastToPtr(act) || TCastToPtr(act) || - CPatterned::CastTo(&act)) { - return CanCollideWithComplexCollision(act, mgr); - } else { - return CanCollideWithGameObject(act, mgr); - } + return CanCollideWithGameObject(act, mgr); } } -CProjectileTouchResult CGameProjectile::CanCollideWithComplexCollision(CActor& act, CStateManager& mgr) const { - CPhysicsActor* useAct = nullptr; - if (TCastToPtr plat = act) { - if (plat->HasComplexCollision()) +CProjectileTouchResult CGameProjectile::CanCollideWithComplexCollision(const CActor& act, + const CStateManager& mgr) const { + const CPhysicsActor* useAct = nullptr; + if (const TCastToConstPtr plat = act) { + if (plat->HasComplexCollision()) { useAct = plat.GetPtr(); - } else if (MP1::CPuddleToadGamma* toad = CPatterned::CastTo(&act)) { + } + } else if (const MP1::CPuddleToadGamma* toad = CPatterned::CastTo(&act)) { useAct = toad; - } else if (TCastToPtr cact = act) { - if (cact->GetOwnerId() == xec_ownerId) - return {kInvalidUniqueId, {}}; + } else if (const TCastToConstPtr cact = act) { + if (cact->GetOwnerId() == xec_ownerId) { + return {kInvalidUniqueId, std::nullopt}; + } useAct = cact.GetPtr(); } - if (useAct) { - const CCollisionPrimitive* prim = useAct->GetCollisionPrimitive(); - zeus::CTransform xf = useAct->GetPrimitiveTransform(); - zeus::CVector3f deltaPos = GetTranslation() - x298_previousPos; - if (deltaPos.canBeNormalized()) { - zeus::CVector3f dir = deltaPos.normalized(); - float mag = deltaPos.magnitude(); - CRayCastResult res = prim->CastRayInternal( - {x298_previousPos, dir, mag, xf, - CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::ProjectilePassthrough})}); - if (!res.IsValid()) { - if (prim->GetPrimType() == FOURCC('SPHR')) { - mag *= 2.f; - CRayCastResult res2 = prim->CastRayInternal( - {x298_previousPos - dir * mag, dir, deltaPos.magnitude(), xf, - CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::ProjectilePassthrough})}); - if (res2.IsValid()) - return {act.GetUniqueId(), {res2}}; - } else if (TCastToPtr cAct = act) { - float rad = cAct->GetSphereRadius(); - if ((x298_previousPos - GetTranslation()).magSquared() < rad * rad) { - zeus::CVector3f point = x298_previousPos - dir * rad * 1.125f; - zeus::CUnitVector3f revDir(-dir); - return {act.GetUniqueId(), {{0.f, point, {revDir, point.dot(revDir)}, act.GetMaterialList()}}}; - } - } - return {kInvalidUniqueId, {}}; - } else { - return {act.GetUniqueId(), {res}}; - } - } else { - return {kInvalidUniqueId, {}}; - } - } else { - return {act.GetUniqueId(), {}}; + if (!useAct) { + return {act.GetUniqueId(), std::nullopt}; } + + const CCollisionPrimitive* prim = useAct->GetCollisionPrimitive(); + const zeus::CTransform xf = useAct->GetPrimitiveTransform(); + const zeus::CVector3f deltaPos = GetTranslation() - x298_previousPos; + if (!deltaPos.canBeNormalized()) { + return {kInvalidUniqueId, std::nullopt}; + } + + const zeus::CVector3f dir = deltaPos.normalized(); + float mag = deltaPos.magnitude(); + const CRayCastResult res = prim->CastRayInternal( + {x298_previousPos, dir, mag, xf, + CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::ProjectilePassthrough})}); + if (res.IsValid()) { + return {act.GetUniqueId(), {res}}; + } + + if (prim->GetPrimType() == FOURCC('SPHR')) { + mag *= 2.f; + const CRayCastResult res2 = prim->CastRayInternal( + {x298_previousPos - dir * mag, dir, deltaPos.magnitude(), xf, + CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::ProjectilePassthrough})}); + if (res2.IsValid()) { + return {act.GetUniqueId(), {res2}}; + } + } else if (const TCastToConstPtr cAct = act) { + const float rad = cAct->GetSphereRadius(); + if ((x298_previousPos - GetTranslation()).magSquared() < rad * rad) { + const zeus::CVector3f point = x298_previousPos - dir * rad * 1.125f; + const zeus::CUnitVector3f revDir(-dir); + return {act.GetUniqueId(), {{0.f, point, {revDir, point.dot(revDir)}, act.GetMaterialList()}}}; + } + } + + return {kInvalidUniqueId, std::nullopt}; } CProjectileTouchResult CGameProjectile::CanCollideWithGameObject(CActor& act, CStateManager& mgr) const { - TCastToPtr proj = act; + const TCastToConstPtr proj = act; if (!proj) { if (!act.GetMaterialList().HasMaterial(EMaterialTypes::Solid) && !act.HealthInfo(mgr)) { - return {kInvalidUniqueId, {}}; + return {kInvalidUniqueId, std::nullopt}; } else if (act.GetUniqueId() == xec_ownerId) { - return {kInvalidUniqueId, {}}; + return {kInvalidUniqueId, std::nullopt}; } else if (act.GetUniqueId() == x2c2_lastResolvedObj) { - return {kInvalidUniqueId, {}}; + return {kInvalidUniqueId, std::nullopt}; } else if (xf8_filter.GetExcludeList().Intersection(act.GetMaterialList())) { - return {kInvalidUniqueId, {}}; + return {kInvalidUniqueId, std::nullopt}; } else if (TCastToPtr ai = act) { - if (!ai->CanBeShot(mgr, int(xe8_projectileAttribs))) - return {kInvalidUniqueId, {}}; + if (!ai->CanBeShot(mgr, int(xe8_projectileAttribs))) { + return {kInvalidUniqueId, std::nullopt}; + } } } else if ((xe8_projectileAttribs & EProjectileAttrib::PartialCharge) == EProjectileAttrib::PartialCharge || (proj->xe8_projectileAttribs & EProjectileAttrib::PartialCharge) == EProjectileAttrib::PartialCharge) { - return {act.GetUniqueId(), {}}; + return {act.GetUniqueId(), std::nullopt}; } else if ((xe8_projectileAttribs & EProjectileAttrib::PartialCharge) != EProjectileAttrib::PartialCharge && (proj->xe8_projectileAttribs & EProjectileAttrib::PartialCharge) != EProjectileAttrib::PartialCharge) { - return {kInvalidUniqueId, {}}; + return {kInvalidUniqueId, std::nullopt}; } - return {act.GetUniqueId(), {}}; + return {act.GetUniqueId(), std::nullopt}; } -CProjectileTouchResult CGameProjectile::CanCollideWithTrigger(CActor& act, CStateManager& mgr) const { - bool isWater = TCastToPtr(act).operator bool(); +CProjectileTouchResult CGameProjectile::CanCollideWithTrigger(const CActor& act, const CStateManager& mgr) const { + const bool isWater = TCastToConstPtr(act).operator bool(); if (isWater) { bool enteredWater = false; if (isWater && !x2e4_25_startedUnderwater) { - if (!x170_projectile.GetWeaponDescription()->xa4_EWTR) + if (!x170_projectile.GetWeaponDescription()->xa4_EWTR) { enteredWater = true; + } } /* This case is logically unreachable */ bool leftWater = false; if (!isWater && x2e4_25_startedUnderwater) { - if (!x170_projectile.GetWeaponDescription()->xa5_LWTR) + if (!x170_projectile.GetWeaponDescription()->xa5_LWTR) { leftWater = true; + } } - return {(enteredWater || leftWater) ? act.GetUniqueId() : kInvalidUniqueId, {}}; + return {(enteredWater || leftWater) ? act.GetUniqueId() : kInvalidUniqueId, std::nullopt}; } - return {kInvalidUniqueId, {}}; + return {kInvalidUniqueId, std::nullopt}; } zeus::CAABox CGameProjectile::GetProjectileBounds() const { @@ -426,9 +448,10 @@ zeus::CAABox CGameProjectile::GetProjectileBounds() const { } std::optional CGameProjectile::GetTouchBounds() const { - if (x2e4_24_active) + if (x2e4_24_active) { return {GetProjectileBounds()}; - return {}; + } + return std::nullopt; } } // namespace urde diff --git a/Runtime/Weapon/CGameProjectile.hpp b/Runtime/Weapon/CGameProjectile.hpp index 752b097cf..c3ea5e75d 100644 --- a/Runtime/Weapon/CGameProjectile.hpp +++ b/Runtime/Weapon/CGameProjectile.hpp @@ -83,9 +83,9 @@ public: float mag, const rstl::reserved_vector& nearList, CStateManager& mgr); CProjectileTouchResult CanCollideWith(CActor& act, CStateManager& mgr) const; - CProjectileTouchResult CanCollideWithComplexCollision(CActor& act, CStateManager& mgr) const; + CProjectileTouchResult CanCollideWithComplexCollision(const CActor& act, const CStateManager& mgr) const; CProjectileTouchResult CanCollideWithGameObject(CActor& act, CStateManager& mgr) const; - CProjectileTouchResult CanCollideWithTrigger(CActor& act, CStateManager& mgr) const; + CProjectileTouchResult CanCollideWithTrigger(const CActor& act, const CStateManager& mgr) const; zeus::CAABox GetProjectileBounds() const; std::optional GetTouchBounds() const override; CProjectileWeapon& ProjectileWeapon() { return x170_projectile; } diff --git a/Runtime/Weapon/CGrappleArm.cpp b/Runtime/Weapon/CGrappleArm.cpp index 75d6d86ea..fc80cd45a 100644 --- a/Runtime/Weapon/CGrappleArm.cpp +++ b/Runtime/Weapon/CGrappleArm.cpp @@ -480,7 +480,7 @@ void CGrappleArm::RenderXRayModel(const CStateManager& mgr, const zeus::CTransfo // g_Renderer->SetAmbientColor(zeus::skWhite); CSkinnedModel& model = const_cast(*x50_grappleArmSkeletonModel->GetAnimationData()->GetModelData()); model.GetModelInst()->ActivateLights({CLight::BuildLocalAmbient({}, zeus::skWhite)}); - x0_grappleArmModel->GetAnimationData()->Render(model, flags, {}, nullptr); + x0_grappleArmModel->GetAnimationData()->Render(model, flags, std::nullopt, nullptr); // g_Renderer->SetAmbientColor(zeus::skWhite); // CGraphics::DisableAllLights(); } diff --git a/Runtime/Weapon/CGunController.hpp b/Runtime/Weapon/CGunController.hpp index 35f23dcec..85a7b24e0 100644 --- a/Runtime/Weapon/CGunController.hpp +++ b/Runtime/Weapon/CGunController.hpp @@ -19,7 +19,7 @@ class CGunController { bool x58_25_enteredComboFire : 1; public: - CGunController(CModelData& modelData) : x0_modelData(modelData) { + explicit CGunController(CModelData& modelData) : x0_modelData(modelData) { x58_24_animDone = true; x58_25_enteredComboFire = false; } diff --git a/Runtime/Weapon/CGunWeapon.cpp b/Runtime/Weapon/CGunWeapon.cpp index 617f5a783..5ff1215c1 100644 --- a/Runtime/Weapon/CGunWeapon.cpp +++ b/Runtime/Weapon/CGunWeapon.cpp @@ -254,7 +254,7 @@ void CGunWeapon::PointGenerator(void* ctx, const std::vectorGetScale())); // CGraphics::DisableAllLights(); // g_Renderer->SetAmbientColor(zeus::skWhite); - CSkinnedModel& model = const_cast(*x60_holoModelData->GetAnimationData()->GetModelData()); + CSkinnedModel& model = *x60_holoModelData->GetAnimationData()->GetModelData(); model.GetModelInst()->ActivateLights({CLight::BuildLocalAmbient({}, zeus::skWhite)}); - const_cast(this)->x10_solidModelData->GetAnimationData()->Render(model, flags, {}, nullptr); + x10_solidModelData->GetAnimationData()->Render(model, flags, std::nullopt, nullptr); // g_Renderer->SetAmbientColor(zeus::skWhite); // CGraphics::DisableAllLights(); } diff --git a/Runtime/Weapon/CGunWeapon.hpp b/Runtime/Weapon/CGunWeapon.hpp index 879548feb..30328d686 100644 --- a/Runtime/Weapon/CGunWeapon.hpp +++ b/Runtime/Weapon/CGunWeapon.hpp @@ -133,13 +133,13 @@ public: void Touch(const CStateManager& mgr); void TouchHolo(const CStateManager& mgr); virtual void Draw(bool drawSuitArm, const CStateManager& mgr, const zeus::CTransform& xf, const CModelFlags& flags, - const CActorLights* lights) const; + const CActorLights* lights); virtual void DrawMuzzleFx(const CStateManager& mgr) const; virtual void Update(float dt, CStateManager& mgr); virtual void Load(CStateManager& mgr, bool subtypeBasePose); virtual void Unload(CStateManager& mgr); virtual bool IsLoaded() const; - void DrawHologram(const CStateManager& mgr, const zeus::CTransform& xf, const CModelFlags& flags) const; + void DrawHologram(const CStateManager& mgr, const zeus::CTransform& xf, const CModelFlags& flags); void UpdateMuzzleFx(float dt, const zeus::CVector3f& scale, const zeus::CVector3f& pos, bool emitting); const CVelocityInfo& GetVelocityInfo() const { return x1d0_velInfo; } void SetRainSplashGenerator(CRainSplashGenerator* g) { x1bc_rainSplashGenerator = g; } diff --git a/Runtime/Weapon/CPhazonBeam.cpp b/Runtime/Weapon/CPhazonBeam.cpp index a91d00e39..3017a7fa1 100644 --- a/Runtime/Weapon/CPhazonBeam.cpp +++ b/Runtime/Weapon/CPhazonBeam.cpp @@ -167,18 +167,18 @@ void CPhazonBeam::Unload(CStateManager& mgr) { bool CPhazonBeam::IsLoaded() const { return CGunWeapon::IsLoaded() && x274_24_loaded; } -void CPhazonBeam::DrawClipScaleCube() const { +void CPhazonBeam::DrawClipScaleCube() { // Render AABB as completely transparent object, only modifying Z-buffer m_aaboxShaderScale.draw(zeus::skClear); } -void CPhazonBeam::DrawClipTranslateCube() const { +void CPhazonBeam::DrawClipTranslateCube() { // Render AABB as completely transparent object, only modifying Z-buffer m_aaboxShaderTranslate.draw(zeus::skClear); } void CPhazonBeam::Draw(bool drawSuitArm, const CStateManager& mgr, const zeus::CTransform& xf, const CModelFlags& flags, - const CActorLights* lights) const { + const CActorLights* lights) { CPlayerState::EPlayerVisor visor = mgr.GetPlayerState()->GetActiveVisor(mgr); bool drawIndirect = visor == CPlayerState::EPlayerVisor::Combat || visor == CPlayerState::EPlayerVisor::Scan; diff --git a/Runtime/Weapon/CPhazonBeam.hpp b/Runtime/Weapon/CPhazonBeam.hpp index 8de5486ab..7e123eec2 100644 --- a/Runtime/Weapon/CPhazonBeam.hpp +++ b/Runtime/Weapon/CPhazonBeam.hpp @@ -22,11 +22,11 @@ class CPhazonBeam final : public CGunWeapon { bool x274_26_veinsAlphaActive : 1; bool x274_27_phazonVeinsIdx : 1; float x278_fireTime = 1.f / 3.f; - mutable CAABoxShader m_aaboxShaderScale = {true}; - mutable CAABoxShader m_aaboxShaderTranslate = {true}; + CAABoxShader m_aaboxShaderScale{true}; + CAABoxShader m_aaboxShaderTranslate{true}; void ReInitVariables(); - void DrawClipScaleCube() const; - void DrawClipTranslateCube() const; + void DrawClipScaleCube(); + void DrawClipTranslateCube(); public: CPhazonBeam(CAssetId characterId, EWeaponType type, TUniqueId playerId, EMaterialTypes playerMaterial, @@ -49,7 +49,7 @@ public: void Unload(CStateManager& mgr) override; bool IsLoaded() const override; void Draw(bool drawSuitArm, const CStateManager& mgr, const zeus::CTransform& xf, const CModelFlags& flags, - const CActorLights* lights) const override; + const CActorLights* lights) override; void DrawMuzzleFx(const CStateManager& mgr) const override; }; diff --git a/Runtime/Weapon/CPlasmaBeam.cpp b/Runtime/Weapon/CPlasmaBeam.cpp index f48f98789..e9efb2df4 100644 --- a/Runtime/Weapon/CPlasmaBeam.cpp +++ b/Runtime/Weapon/CPlasmaBeam.cpp @@ -1,11 +1,17 @@ #include "Runtime/Weapon/CPlasmaBeam.hpp" +#include + #include "Runtime/CSimplePool.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/World/CPlayer.hpp" #include "Runtime/World/CWorld.hpp" namespace urde { +namespace { +constexpr CCameraShakeData CameraShaker{0.125f, 0.25f}; +constexpr std::array kSoundId{SFXwpn_fire_plasma_normal, SFXwpn_fire_plasma_charged}; +} // Anonymous namespace CPlasmaBeam::CPlasmaBeam(CAssetId characterId, EWeaponType type, TUniqueId playerId, EMaterialTypes playerMaterial, const zeus::CVector3f& scale) @@ -59,9 +65,6 @@ void CPlasmaBeam::UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr CGunWeapon::UpdateGunFx(shotSmoke, dt, mgr, xf); } -static const CCameraShakeData CameraShaker = {0.125f, 0.25f}; -static const u16 kSoundId[] = {SFXwpn_fire_plasma_normal, SFXwpn_fire_plasma_charged}; - void CPlasmaBeam::Fire(bool underwater, float dt, EChargeState chargeState, const zeus::CTransform& xf, CStateManager& mgr, TUniqueId homingTarget, float chargeFactor1, float chargeFactor2) { bool fired = false; @@ -81,8 +84,11 @@ void CPlasmaBeam::Fire(bool underwater, float dt, EChargeState chargeState, cons fired = true; } - if (fired) - NWeaponTypes::play_sfx(kSoundId[int(chargeState)], underwater, false, 0.165f); + if (!fired) { + return; + } + + NWeaponTypes::play_sfx(kSoundId[size_t(chargeState)], underwater, false, 0.165f); } void CPlasmaBeam::EnableSecondaryFx(ESecondaryFxType type) { diff --git a/Runtime/Weapon/CPlasmaProjectile.cpp b/Runtime/Weapon/CPlasmaProjectile.cpp index 8c4ce59db..7d25610d7 100644 --- a/Runtime/Weapon/CPlasmaProjectile.cpp +++ b/Runtime/Weapon/CPlasmaProjectile.cpp @@ -81,10 +81,9 @@ void CPlasmaProjectile::SetLightsActive(bool active, CStateManager& mgr) { void CPlasmaProjectile::CreatePlasmaLights(u32 sourceId, const CLight& l, CStateManager& mgr) { DeletePlasmaLights(mgr); x468_lights.reserve(3); - for (int i = 0; i < 3; ++i) { - TUniqueId lid = mgr.AllocateUniqueId(); - auto* light = - new CGameLight(lid, GetAreaId(), GetActive(), ""sv, GetTransform(), GetUniqueId(), l, sourceId, 0, 0.f); + for (size_t i = 0; i < x468_lights.capacity(); ++i) { + const TUniqueId lid = mgr.AllocateUniqueId(); + auto* light = new CGameLight(lid, GetAreaId(), GetActive(), "", GetTransform(), GetUniqueId(), l, sourceId, 0, 0.f); mgr.AddObject(light); x468_lights.push_back(lid); } @@ -141,16 +140,16 @@ void CPlasmaProjectile::RenderMotionBlur() const { zeus::CColor color2 = x494_outerColor; color1.a() = 63.f / 255.f; color2.a() = 0.f; - CColoredStripShader::Vert verts[16]; - for (int i = 0; i < 8; ++i) { + std::array verts; + for (size_t i = 0; i < verts.size() / 2; ++i) { auto& v1 = verts[i * 2]; auto& v2 = verts[i * 2 + 1]; v1.m_pos = GetBeamTransform().origin; - v1.m_color = zeus::CColor::lerp(color1, color2, i / 8.f); + v1.m_color = zeus::CColor::lerp(color1, color2, float(i) / 8.f); v2.m_pos = GetPointCache()[i]; v2.m_color = v1.m_color; } - m_renderObjs->m_motionBlurStrip.draw(zeus::skWhite, 16, verts); + m_renderObjs->m_motionBlurStrip.draw(zeus::skWhite, verts.size(), verts.data()); } void CPlasmaProjectile::RenderBeam(s32 subdivs, float width, const zeus::CColor& color, s32 flags, @@ -161,7 +160,7 @@ void CPlasmaProjectile::RenderBeam(s32 subdivs, float width, const zeus::CColor& float angIncrement = 2.f * M_PIF / float(subdivs); float uvY1 = -(x4cc_energyPulseStartY / 16.f); float uvY2 = (uvY1 + float((flags & 0x3) == 0x3) != 0.f) ? 2.f : 0.5f * GetCurrentLength(); - CColoredStripShader::Vert verts[18]; + std::array verts; s32 numNodes = subdivs + 1; float angle = 0.f; bool flip = false; @@ -186,7 +185,7 @@ void CPlasmaProjectile::RenderBeam(s32 subdivs, float width, const zeus::CColor& v1.m_uv = zeus::CVector2f(uvX, uvY2); angle += angIncrement; } - shader.draw(zeus::skWhite, numNodes * 2, verts); + shader.draw(zeus::skWhite, numNodes * 2, verts.data()); } } @@ -395,7 +394,7 @@ bool CPlasmaProjectile::CanRenderUnsorted(const CStateManager& mgr) const { return false; } -void CPlasmaProjectile::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { +void CPlasmaProjectile::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { if (GetActive()) { g_Renderer->AddParticleGen(*x518_contactGen); if (x478_beamAttributes & 0x2) { @@ -405,7 +404,7 @@ void CPlasmaProjectile::AddToRenderer(const zeus::CFrustum& frustum, const CStat EnsureRendered(mgr, GetBeamTransform().origin, GetSortingBounds(mgr)); } -void CPlasmaProjectile::Render(const CStateManager& mgr) const { +void CPlasmaProjectile::Render(CStateManager& mgr) { if (!GetActive()) return; SCOPED_GRAPHICS_DEBUG_GROUP("CPlasmaProjectile::Render", zeus::skOrange); diff --git a/Runtime/Weapon/CPlasmaProjectile.hpp b/Runtime/Weapon/CPlasmaProjectile.hpp index b2e7e7d8d..d9c249c5b 100644 --- a/Runtime/Weapon/CPlasmaProjectile.hpp +++ b/Runtime/Weapon/CPlasmaProjectile.hpp @@ -121,7 +121,7 @@ public: void Fire(const zeus::CTransform& xf, CStateManager& mgr, bool b) override; void Touch(CActor& other, CStateManager& mgr) override; bool CanRenderUnsorted(const CStateManager& mgr) const override; - void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; - void Render(const CStateManager& mgr) const override; + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) override; + void Render(CStateManager& mgr) override; }; } // namespace urde diff --git a/Runtime/Weapon/CPlayerGun.cpp b/Runtime/Weapon/CPlayerGun.cpp index f122ab73f..8a279abc3 100644 --- a/Runtime/Weapon/CPlayerGun.cpp +++ b/Runtime/Weapon/CPlayerGun.cpp @@ -1785,36 +1785,35 @@ void CPlayerGun::UpdateGunIdle(bool inStrikeCooldown, float camBobT, float dt, C void CPlayerGun::Update(float grappleSwingT, float cameraBobT, float dt, CStateManager& mgr) { CPlayer& player = mgr.GetPlayer(); CPlayerState& playerState = *mgr.GetPlayerState(); - bool isUnmorphed = player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed; + const bool isUnmorphed = player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed; - bool becameFrozen; - if (isUnmorphed) + bool becameFrozen = false; + if (isUnmorphed) { becameFrozen = !x834_29_frozen && player.GetFrozenState(); - else - becameFrozen = false; + } - bool becameThawed; - if (isUnmorphed) + bool becameThawed = false; + if (isUnmorphed) { becameThawed = x834_29_frozen && !player.GetFrozenState(); - else - becameThawed = false; + } x834_29_frozen = isUnmorphed && player.GetFrozenState(); - float advDt; - if (x834_29_frozen) + float advDt = dt; + if (x834_29_frozen) { advDt = 0.f; - else - advDt = dt; + } - bool r23 = x678_morph.GetGunState() != CGunMorph::EGunState::OutWipeDone; - if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::XRay || r23) + const bool r23 = x678_morph.GetGunState() != CGunMorph::EGunState::OutWipeDone; + if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::XRay || r23) { x6e0_rightHandModel.AdvanceAnimation(advDt, mgr, kInvalidAreaId, true); - if (r23 && x734_loadingBeam != 0 && x734_loadingBeam != x72c_currentBeam) { + } + if (r23 && x734_loadingBeam != nullptr && x734_loadingBeam != x72c_currentBeam) { x744_auxWeapon->LoadIdle(); x734_loadingBeam->Update(advDt, mgr); } - if (!x744_auxWeapon->IsLoaded()) + if (!x744_auxWeapon->IsLoaded()) { x744_auxWeapon->LoadIdle(); + } if (becameFrozen) { x72c_currentBeam->EnableSecondaryFx(CGunWeapon::ESecondaryFxType::None); @@ -2130,20 +2129,20 @@ void CPlayerGun::CopyScreenTex() { CGraphics::ResolveSpareTexture(g_Viewport); } -void CPlayerGun::DrawScreenTex(float z) const { +void CPlayerGun::DrawScreenTex(float z) { // Use CopyScreenTex rendering to draw over framebuffer pixels in front of `z` // This is accomplished using orthographic projection quad with sweeping `y` coordinates // Depth is set to GEQUAL to obscure pixels in front rather than behind m_screenQuad.draw(zeus::skWhite, 1.f, CTexturedQuadFilter::DefaultRect, z); } -void CPlayerGun::DrawClipCube(const zeus::CAABox& aabb) const { +void CPlayerGun::DrawClipCube(const zeus::CAABox& aabb) { // Render AABB as completely transparent object, only modifying Z-buffer // AABB has already been set in constructor (since it's constant) m_aaboxShader.draw(zeus::skClear); } -void CPlayerGun::Render(const CStateManager& mgr, const zeus::CVector3f& pos, const CModelFlags& flags) const { +void CPlayerGun::Render(const CStateManager& mgr, const zeus::CVector3f& pos, const CModelFlags& flags) { SCOPED_GRAPHICS_DEBUG_GROUP("CPlayerGun::Render", zeus::skMagenta); CGraphics::CProjectionState projState = CGraphics::GetProjectionState(); @@ -2267,12 +2266,12 @@ void CPlayerGun::DropBomb(EBWeapon weapon, CStateManager& mgr) { if (x308_bombCount <= 0) return; - zeus::CVector3f plPos = mgr.GetPlayer().GetTranslation(); - zeus::CTransform xf = + const zeus::CVector3f plPos = mgr.GetPlayer().GetTranslation(); + const zeus::CTransform xf = zeus::CTransform::Translate({plPos.x(), plPos.y(), plPos.z() + g_tweakPlayer->GetPlayerBallHalfExtent()}); - CBomb* bomb = - new CBomb(x784_bombEffects[u32(weapon)][0], x784_bombEffects[u32(weapon)][1], mgr.AllocateUniqueId(), - mgr.GetPlayer().GetAreaId(), x538_playerId, x354_bombFuseTime, xf, g_tweakPlayerGun->GetBombInfo()); + CBomb* bomb = new CBomb(x784_bombEffects[u32(weapon)][0], x784_bombEffects[u32(weapon)][1], mgr.AllocateUniqueId(), + mgr.GetPlayer().GetAreaId(), x538_playerId, x354_bombFuseTime, xf, + CDamageInfo{g_tweakPlayerGun->GetBombInfo()}); mgr.AddObject(bomb); if (x308_bombCount == 3) @@ -2288,8 +2287,8 @@ void CPlayerGun::DropBomb(EBWeapon weapon, CStateManager& mgr) { } TUniqueId CPlayerGun::DropPowerBomb(CStateManager& mgr) { - CDamageInfo dInfo = (mgr.GetPlayer().GetDeathTime() <= 0.f ? g_tweakPlayerGun->GetPowerBombInfo() - : CDamageInfo(CWeaponMode::PowerBomb(), 0.f, 0.f, 0.f)); + const auto dInfo = mgr.GetPlayer().GetDeathTime() <= 0.f ? CDamageInfo{g_tweakPlayerGun->GetPowerBombInfo()} + : CDamageInfo{CWeaponMode::PowerBomb(), 0.f, 0.f, 0.f}; TUniqueId uid = mgr.AllocateUniqueId(); zeus::CVector3f plVec = mgr.GetPlayer().GetTranslation(); diff --git a/Runtime/Weapon/CPlayerGun.hpp b/Runtime/Weapon/CPlayerGun.hpp index 8ecefbd63..8140fbb99 100644 --- a/Runtime/Weapon/CPlayerGun.hpp +++ b/Runtime/Weapon/CPlayerGun.hpp @@ -198,7 +198,7 @@ private: float x664_ = 0.f; float x668_aimVerticalSpeed; float x66c_aimHorizontalSpeed; - std::pair x670_animSfx = {0xffff, {}}; + std::pair x670_animSfx{0xffff, {}}; CGunMorph x678_morph; CMotionState x6a0_motionState; zeus::CAABox x6c8_hologramClipCube; @@ -266,9 +266,9 @@ private: u32 _dummy = 0; }; - mutable CTexturedQuadFilter m_screenQuad = {EFilterType::Blend, CGraphics::g_SpareTexture.get(), - CTexturedQuadFilter::ZTest::GEqualZWrite}; - mutable CAABoxShader m_aaboxShader = {true}; + CTexturedQuadFilter m_screenQuad{EFilterType::Blend, CGraphics::g_SpareTexture.get(), + CTexturedQuadFilter::ZTest::GEqualZWrite}; + CAABoxShader m_aaboxShader{true}; void InitBeamData(); void InitBombData(); @@ -322,8 +322,8 @@ private: void DrawArm(const CStateManager& mgr, const zeus::CVector3f& pos, const CModelFlags& flags) const; zeus::CVector3f ConvertToScreenSpace(const zeus::CVector3f& pos, const CGameCamera& cam) const; static void CopyScreenTex(); - void DrawScreenTex(float z) const; - void DrawClipCube(const zeus::CAABox& aabb) const; + void DrawScreenTex(float z); + void DrawClipCube(const zeus::CAABox& aabb); public: explicit CPlayerGun(TUniqueId playerId); @@ -358,7 +358,7 @@ public: void StopContinuousBeam(CStateManager& mgr, bool b1); void Update(float grappleSwingT, float cameraBobT, float dt, CStateManager& mgr); void PreRender(const CStateManager& mgr, const zeus::CFrustum& frustum, const zeus::CVector3f& camPos); - void Render(const CStateManager& mgr, const zeus::CVector3f& pos, const CModelFlags& flags) const; + void Render(const CStateManager& mgr, const zeus::CVector3f& pos, const CModelFlags& flags); void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const; u32 GetLastFireButtonStates() const { return x2ec_lastFireButtonStates; } void DropBomb(EBWeapon weapon, CStateManager& mgr); diff --git a/Runtime/Weapon/CPowerBeam.cpp b/Runtime/Weapon/CPowerBeam.cpp index de075e063..2d822bbcf 100644 --- a/Runtime/Weapon/CPowerBeam.cpp +++ b/Runtime/Weapon/CPowerBeam.cpp @@ -1,5 +1,7 @@ #include "Runtime/Weapon/CPowerBeam.hpp" +#include + #include "Runtime/CSimplePool.hpp" #include "Runtime/GameGlobalObjects.hpp" @@ -69,12 +71,15 @@ void CPowerBeam::UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr, CGunWeapon::UpdateGunFx(shotSmoke, dt, mgr, xf); } -static const u16 skSoundId[] = {SFXwpn_fire_power_normal, SFXwpn_fire_power_charged}; - void CPowerBeam::Fire(bool underwater, float dt, EChargeState chargeState, const zeus::CTransform& xf, CStateManager& mgr, TUniqueId homingTarget, float chargeFactor1, float chargeFactor2) { + static constexpr std::array skSoundId{ + SFXwpn_fire_power_normal, + SFXwpn_fire_power_charged, + }; + CGunWeapon::Fire(underwater, dt, chargeState, xf, mgr, homingTarget, chargeFactor1, chargeFactor2); - NWeaponTypes::play_sfx(skSoundId[int(chargeState)], underwater, false, 0.165f); + NWeaponTypes::play_sfx(skSoundId[size_t(chargeState)], underwater, false, 0.165f); } void CPowerBeam::EnableSecondaryFx(ESecondaryFxType type) { diff --git a/Runtime/Weapon/CPowerBomb.cpp b/Runtime/Weapon/CPowerBomb.cpp index abbf37a46..715a1f497 100644 --- a/Runtime/Weapon/CPowerBomb.cpp +++ b/Runtime/Weapon/CPowerBomb.cpp @@ -89,7 +89,7 @@ void CPowerBomb::Think(float dt, CStateManager& mgr) { x15c_curTime += dt; } -void CPowerBomb::AddToRenderer(const zeus::CFrustum&, const CStateManager&) const { +void CPowerBomb::AddToRenderer(const zeus::CFrustum&, CStateManager&) { g_Renderer->AddParticleGen(*x168_particle); } diff --git a/Runtime/Weapon/CPowerBomb.hpp b/Runtime/Weapon/CPowerBomb.hpp index 3a636448d..6a20fc052 100644 --- a/Runtime/Weapon/CPowerBomb.hpp +++ b/Runtime/Weapon/CPowerBomb.hpp @@ -27,9 +27,9 @@ public: void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float, CStateManager&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager&) const override {} - std::optional GetTouchBounds() const override { return {}; } + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager&) override {} + std::optional GetTouchBounds() const override { return std::nullopt; } void Touch(CActor&, CStateManager&) override { /*x158_24_canStartFilter; */ } float GetCurTime() const { return x15c_curTime; } diff --git a/Runtime/Weapon/CProjectileInfo.hpp b/Runtime/Weapon/CProjectileInfo.hpp index 14d28c20c..7f388c359 100644 --- a/Runtime/Weapon/CProjectileInfo.hpp +++ b/Runtime/Weapon/CProjectileInfo.hpp @@ -9,11 +9,11 @@ namespace urde { class CPlayer; class CProjectileInfo { - TToken x0_weaponDescription; + TCachedToken x0_weaponDescription; CDamageInfo xc_damageInfo; public: - CProjectileInfo(CInputStream&); + explicit CProjectileInfo(CInputStream&); CProjectileInfo(CAssetId, const CDamageInfo&); float GetProjectileSpeed() const; @@ -24,6 +24,6 @@ public: const CDamageInfo& GetDamage() const { return xc_damageInfo; } void SetDamage(const CDamageInfo& damageInfo) { xc_damageInfo = damageInfo; } - TToken& Token() { return x0_weaponDescription; } + TCachedToken& Token() { return x0_weaponDescription; } }; } // namespace urde diff --git a/Runtime/Weapon/CProjectileWeapon.cpp b/Runtime/Weapon/CProjectileWeapon.cpp index 69c49236c..31316e3b9 100644 --- a/Runtime/Weapon/CProjectileWeapon.cpp +++ b/Runtime/Weapon/CProjectileWeapon.cpp @@ -116,9 +116,10 @@ std::optional CProjectileWeapon::GetBounds() const { } } - if (ret) + if (ret) { return {aabb}; - return {}; + } + return std::nullopt; } float CProjectileWeapon::GetAudibleFallOff() const { @@ -135,8 +136,9 @@ float CProjectileWeapon::GetAudibleRange() const { std::optional> CProjectileWeapon::GetDecalForCollision(EWeaponCollisionResponseTypes type) const { - if (!x4_weaponDesc->x94_COLR) - return {}; + if (!x4_weaponDesc->x94_COLR) { + return std::nullopt; + } return x4_weaponDesc->x94_COLR.m_res->GetDecalDescription(type); } @@ -159,21 +161,27 @@ std::optional> CProjectileWeapon::CollisionOccured SetWorldSpaceOrientation( zeus::lookAt(zeus::skZero3f, xf.basis[1] - normal * (normal.dot(xf.basis[1]) * 2.f), normal)); } - return {}; + return std::nullopt; } else { x124_24_active = false; - if (xfc_APSMGen) + if (xfc_APSMGen) { xfc_APSMGen->SetParticleEmission(false); - if (x100_APS2Gen) + } + if (x100_APS2Gen) { x100_APS2Gen->SetParticleEmission(false); - if (x118_swoosh1) + } + if (x118_swoosh1) { x118_swoosh1->SetParticleEmission(false); - if (x11c_swoosh2) + } + if (x11c_swoosh2) { x11c_swoosh2->SetParticleEmission(false); - if (x120_swoosh3) + } + if (x120_swoosh3) { x120_swoosh3->SetParticleEmission(false); - if (!x4_weaponDesc->x94_COLR) - return {}; + } + if (!x4_weaponDesc->x94_COLR) { + return std::nullopt; + } return x4_weaponDesc->x94_COLR.m_res->GetParticleDescription(type); } } diff --git a/Runtime/Weapon/CWeapon.cpp b/Runtime/Weapon/CWeapon.cpp index 42bf34247..ef5934533 100644 --- a/Runtime/Weapon/CWeapon.cpp +++ b/Runtime/Weapon/CWeapon.cpp @@ -37,7 +37,7 @@ void CWeapon::Think(float dt, CStateManager& mgr) { CEntity::Think(dt, mgr); } -void CWeapon::Render(const CStateManager&) const { +void CWeapon::Render(CStateManager&) { // Empty } diff --git a/Runtime/Weapon/CWeapon.hpp b/Runtime/Weapon/CWeapon.hpp index 025e89ab6..3c4a475cc 100644 --- a/Runtime/Weapon/CWeapon.hpp +++ b/Runtime/Weapon/CWeapon.hpp @@ -45,7 +45,7 @@ public: void SetInterferenceDuration(float dur) { x154_interferenceDuration = dur; } void Think(float, CStateManager&) override; - void Render(const CStateManager&) const override; + void Render(CStateManager&) override; EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, const CWeaponMode&, EProjectileAttrib) const override; void FluidFXThink(EFluidState state, CScriptWater& water, CStateManager& mgr) override; diff --git a/Runtime/Weapon/CWeaponMgr.cpp b/Runtime/Weapon/CWeaponMgr.cpp index 86db9d2b4..28cfa89e0 100644 --- a/Runtime/Weapon/CWeaponMgr.cpp +++ b/Runtime/Weapon/CWeaponMgr.cpp @@ -3,47 +3,64 @@ namespace urde { void CWeaponMgr::Add(TUniqueId uid, EWeaponType type) { - x0_weapons.insert(std::make_pair(uid, rstl::reserved_vector())); - x0_weapons[uid].resize(15); - ++x0_weapons[uid][u32(type)]; + auto iter = x0_weapons.emplace(uid, rstl::reserved_vector()).first; + iter->second.resize(15); + ++iter->second[size_t(type)]; } void CWeaponMgr::Remove(TUniqueId uid) { - s32 totalActive = 0; - for (u32 i = 0; i < 10; ++i) - totalActive += x0_weapons[uid][i]; + const auto& weapon = x0_weapons[uid]; - if (totalActive == 0) - x0_weapons.erase(uid); + s32 totalActive = 0; + for (size_t i = 0; i < 10; ++i) { + totalActive += weapon[i]; + } + + if (totalActive != 0) { + return; + } + + x0_weapons.erase(uid); } void CWeaponMgr::IncrCount(TUniqueId uid, EWeaponType type) { - if (GetIndex(uid) < 0) + if (GetIndex(uid) < 0) { Add(uid, type); - else - x0_weapons[uid][u32(type)]++; + } else { + x0_weapons[uid][size_t(type)]++; + } } void CWeaponMgr::DecrCount(TUniqueId uid, EWeaponType type) { - if (GetIndex(uid) < 0) + if (GetIndex(uid) < 0) { return; + } - x0_weapons[uid][u32(type)]--; - if (x0_weapons[uid][u32(type)] <= 0) - Remove(uid); + auto& weapon = x0_weapons[uid]; + weapon[size_t(type)]--; + if (weapon[size_t(type)] > 0) { + return; + } + + Remove(uid); } s32 CWeaponMgr::GetNumActive(TUniqueId uid, EWeaponType type) const { - if (GetIndex(uid) < 0) + if (GetIndex(uid) < 0) { return 0; + } - return x0_weapons.at(uid)[u32(type)]; + return x0_weapons.at(uid)[size_t(type)]; } s32 CWeaponMgr::GetIndex(TUniqueId uid) const { - if (x0_weapons.find(uid) == x0_weapons.end()) + const auto iter = x0_weapons.find(uid); + + if (iter == x0_weapons.cend()) { return -1; - return s32(std::distance(x0_weapons.begin(), x0_weapons.find(uid))); + } + + return s32(std::distance(x0_weapons.cbegin(), iter)); } } // namespace urde diff --git a/Runtime/World/CActor.cpp b/Runtime/World/CActor.cpp index 32bba7477..37fa2b6d4 100644 --- a/Runtime/World/CActor.cpp +++ b/Runtime/World/CActor.cpp @@ -181,25 +181,29 @@ void CActor::PreRender(CStateManager& mgr, const zeus::CFrustum& planes) { } } -void CActor::AddToRenderer(const zeus::CFrustum& planes, const CStateManager& mgr) const { - if (!x64_modelData || x64_modelData->IsNull()) +void CActor::AddToRenderer(const zeus::CFrustum& planes, CStateManager& mgr) { + if (!x64_modelData || x64_modelData->IsNull()) { return; + } - if (xe6_29_renderParticleDBInside) + if (xe6_29_renderParticleDBInside) { x64_modelData->RenderParticles(planes); + } if (!xe4_30_outOfFrustum) { - if (CanRenderUnsorted(mgr)) + if (CanRenderUnsorted(mgr)) { Render(mgr); - else + } else { EnsureRendered(mgr); + } } if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::XRay && mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::Thermal && xe5_24_shadowEnabled && - x94_simpleShadow->Valid() && planes.aabbFrustumTest(x94_simpleShadow->GetBounds())) + x94_simpleShadow->Valid() && planes.aabbFrustumTest(x94_simpleShadow->GetBounds())) { g_Renderer->AddDrawable(x94_simpleShadow.get(), x94_simpleShadow->GetTransform().origin, x94_simpleShadow->GetBounds(), 1, CBooRenderer::EDrawableSorting::SortedCallback); + } } void CActor::DrawTouchBounds() const { @@ -253,7 +257,7 @@ bool CActor::IsModelOpaque(const CStateManager& mgr) const { return x64_modelData->IsDefinitelyOpaque(CModelData::GetRenderingModel(mgr)); } -void CActor::Render(const CStateManager& mgr) const { +void CActor::Render(CStateManager& mgr) { if (x64_modelData && !x64_modelData->IsNull()) { bool renderPrePostParticles = xe6_29_renderParticleDBInside && x64_modelData && x64_modelData->HasAnimData(); if (renderPrePostParticles) @@ -508,12 +512,12 @@ float CActor::GetPitch() const { return zeus::CQuaternion(x34_transform.buildMat float CActor::GetYaw() const { return zeus::CQuaternion(x34_transform.buildMatrix3f()).yaw(); } -void CActor::EnsureRendered(const CStateManager& mgr) const { - zeus::CAABox aabb = GetSortingBounds(mgr); +void CActor::EnsureRendered(const CStateManager& mgr) { + const zeus::CAABox aabb = GetSortingBounds(mgr); EnsureRendered(mgr, aabb.closestPointAlongVector(CGraphics::g_ViewMatrix.basis[1]), aabb); } -void CActor::EnsureRendered(const CStateManager& stateMgr, const zeus::CVector3f& pos, const zeus::CAABox& aabb) const { +void CActor::EnsureRendered(const CStateManager& stateMgr, const zeus::CVector3f& pos, const zeus::CAABox& aabb) { if (x64_modelData) { x64_modelData->RenderUnsortedParts(x64_modelData->GetRenderingModel(stateMgr), x34_transform, x90_actorLights.get(), xb4_drawFlags); diff --git a/Runtime/World/CActor.hpp b/Runtime/World/CActor.hpp index d479d0597..69e0abbd4 100644 --- a/Runtime/World/CActor.hpp +++ b/Runtime/World/CActor.hpp @@ -108,8 +108,8 @@ public: CEntity::SetActive(active); } virtual void PreRender(CStateManager&, const zeus::CFrustum&); - virtual void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const; - virtual void Render(const CStateManager&) const; + virtual void AddToRenderer(const zeus::CFrustum&, CStateManager&); + virtual void Render(CStateManager&); virtual bool CanRenderUnsorted(const CStateManager&) const; virtual void CalculateRenderBounds(); virtual CHealthInfo* HealthInfo(CStateManager&); @@ -168,8 +168,8 @@ public: float GetYaw() const; const CModelData* GetModelData() const { return x64_modelData.get(); } CModelData* GetModelData() { return x64_modelData.get(); } - void EnsureRendered(const CStateManager&) const; - void EnsureRendered(const CStateManager&, const zeus::CVector3f&, const zeus::CAABox&) const; + void EnsureRendered(const CStateManager&); + void EnsureRendered(const CStateManager&, const zeus::CVector3f&, const zeus::CAABox&); void ProcessSoundEvent(u32 sfxId, float weight, u32 flags, float falloff, float maxDist, float minVol, float maxVol, const zeus::CVector3f& toListener, const zeus::CVector3f& position, TAreaId aid, CStateManager& mgr, bool translateId); diff --git a/Runtime/World/CActorModelParticles.cpp b/Runtime/World/CActorModelParticles.cpp index e2db58c6e..ceb99f7d5 100644 --- a/Runtime/World/CActorModelParticles.cpp +++ b/Runtime/World/CActorModelParticles.cpp @@ -1,5 +1,6 @@ #include "Runtime/World/CActorModelParticles.hpp" +#include #include #include "Runtime/CDependencyGroup.hpp" @@ -380,23 +381,24 @@ void CActorModelParticles::IncrementDependency(EDependency d) { xe4_loadingDeps |= (1 << int(d)); } -constexpr std::array ParticleDGRPs{ - "Effect_OnFire_DGRP", "Effect_IceBreak_DGRP", "Effect_Ash_DGRP", - "Effect_FirePop_DGRP", "Effect_Electric_DGRP", "Effect_IcePop_DGRP", -}; - -CActorModelParticles::Dependency CActorModelParticles::GetParticleDGRPTokens(const char* name) { +CActorModelParticles::Dependency CActorModelParticles::GetParticleDGRPTokens(std::string_view name) const { Dependency ret = {}; TToken dgrp = g_SimplePool->GetObj(name); const auto& vector = dgrp->GetObjectTagVector(); ret.x0_tokens.reserve(vector.size()); - for (const SObjectTag& tag : vector) + for (const SObjectTag& tag : vector) { ret.x0_tokens.push_back(g_SimplePool->GetObj(tag)); + } return ret; } void CActorModelParticles::LoadParticleDGRPs() { - for (const char* dgrp : ParticleDGRPs) { + static constexpr std::array particleDGRPs{ + "Effect_OnFire_DGRP"sv, "Effect_IceBreak_DGRP"sv, "Effect_Ash_DGRP"sv, + "Effect_FirePop_DGRP"sv, "Effect_Electric_DGRP"sv, "Effect_IcePop_DGRP"sv, + }; + + for (const auto& dgrp : particleDGRPs) { x50_dgrps.push_back(GetParticleDGRPTokens(dgrp)); } } @@ -456,11 +458,12 @@ void CActorModelParticles::AddStragglersToRenderer(const CStateManager& mgr) { continue; } if (isNotCold) { - /* Hot Draw */ - for (int i = 0; i < 8; ++i) { - std::unique_ptr& gen = item.x8_onFireGens[i].first; - if (gen) + // Hot Draw + for (auto& entry : item.x8_onFireGens) { + std::unique_ptr& gen = entry.first; + if (gen) { g_Renderer->AddParticleGen(*gen); + } } if (mgr.GetThermalDrawFlag() != EThermalDrawFlag::Hot && item.x78_ashGen) g_Renderer->AddParticleGen(*item.x78_ashGen); @@ -485,19 +488,21 @@ void CActorModelParticles::AddStragglersToRenderer(const CStateManager& mgr) { } void CActorModelParticles::UpdateLoad() { - if (xe4_loadingDeps) { - xe5_justLoadedDeps = 0; - for (int i = 0; i < 6; ++i) { - if (xe4_loadingDeps & (1 << i)) { - x50_dgrps[i].UpdateLoad(); - if (x50_dgrps[i].x14_loaded) { - xe5_justLoadedDeps |= (1 << i); - xe4_loadingDeps &= ~(1 << i); - } + if (!xe4_loadingDeps) { + return; + } + + xe5_justLoadedDeps = 0; + for (size_t i = 0; i < x50_dgrps.size(); ++i) { + if ((xe4_loadingDeps & (1U << i)) != 0) { + x50_dgrps[i].UpdateLoad(); + if (x50_dgrps[i].x14_loaded) { + xe5_justLoadedDeps |= (1U << i); + xe4_loadingDeps &= ~(1U << i); } } - xe6_loadedDeps |= xe5_justLoadedDeps; } + xe6_loadedDeps |= xe5_justLoadedDeps; } void CActorModelParticles::Update(float dt, CStateManager& mgr) { @@ -515,20 +520,25 @@ void CActorModelParticles::Update(float dt, CStateManager& mgr) { void CActorModelParticles::PointGenerator(void* ctx, const std::vector>& vn) { - reinterpret_cast(ctx)->GeneratePoints(vn); + static_cast(ctx)->GeneratePoints(vn); } void CActorModelParticles::SetupHook(TUniqueId uid) { - auto search = FindSystem(uid); - if (search != x0_items.cend()) - CSkinnedModel::SetPointGeneratorFunc((void*)&*search, PointGenerator); + const auto search = FindSystem(uid); + + if (search == x0_items.cend()) { + return; + } + + CSkinnedModel::SetPointGeneratorFunc(&*search, PointGenerator); +} + +std::list::iterator CActorModelParticles::FindSystem(TUniqueId uid) { + return std::find_if(x0_items.begin(), x0_items.end(), [uid](const auto& entry) { return entry.x0_id == uid; }); } std::list::const_iterator CActorModelParticles::FindSystem(TUniqueId uid) const { - for (auto it = x0_items.cbegin(); it != x0_items.cend(); ++it) - if (it->x0_id == uid) - return it; - return x0_items.cend(); + return std::find_if(x0_items.begin(), x0_items.end(), [uid](const auto& entry) { return entry.x0_id == uid; }); } std::list::iterator CActorModelParticles::FindOrCreateSystem(CActor& act) { diff --git a/Runtime/World/CActorModelParticles.hpp b/Runtime/World/CActorModelParticles.hpp index 67ab400db..df191ab5d 100644 --- a/Runtime/World/CActorModelParticles.hpp +++ b/Runtime/World/CActorModelParticles.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -137,7 +138,7 @@ private: u8 xe5_justLoadedDeps = 0; u8 xe6_loadedDeps = 0; - Dependency GetParticleDGRPTokens(const char* name); + Dependency GetParticleDGRPTokens(std::string_view name) const; void LoadParticleDGRPs(); std::unique_ptr MakeOnFireGen() const; @@ -158,6 +159,7 @@ public: void AddStragglersToRenderer(const CStateManager& mgr); void Update(float dt, CStateManager& mgr); void SetupHook(TUniqueId uid); + std::list::iterator FindSystem(TUniqueId uid); std::list::const_iterator FindSystem(TUniqueId uid) const; std::list::iterator FindOrCreateSystem(CActor& act); void StartIce(CActor& actor); diff --git a/Runtime/World/CAi.hpp b/Runtime/World/CAi.hpp index 0f739769c..6ba2be1ca 100644 --- a/Runtime/World/CAi.hpp +++ b/Runtime/World/CAi.hpp @@ -55,7 +55,7 @@ public: virtual void TakeDamage(const zeus::CVector3f& direction, float magnitude) {} virtual bool CanBeShot(const CStateManager&, int) { return true; } virtual bool IsListening() const { return false; } - virtual bool Listen(const zeus::CVector3f&, EListenNoiseType) { return 0; } + virtual bool Listen(const zeus::CVector3f&, EListenNoiseType) { return false; } virtual zeus::CVector3f GetOrigin(const CStateManager& mgr, const CTeamAiRole& role, const zeus::CVector3f& aimPos) const { diff --git a/Runtime/World/CAnimationParameters.hpp b/Runtime/World/CAnimationParameters.hpp index bb66c7247..7cb29aedc 100644 --- a/Runtime/World/CAnimationParameters.hpp +++ b/Runtime/World/CAnimationParameters.hpp @@ -13,7 +13,7 @@ public: CAnimationParameters() = default; CAnimationParameters(CAssetId ancs, u32 charIdx, u32 defaultAnim) : x0_ancs(ancs), x4_charIdx(charIdx), x8_defaultAnim(defaultAnim) {} - CAnimationParameters(CInputStream& in) + explicit CAnimationParameters(CInputStream& in) : x0_ancs(in.readUint32Big()), x4_charIdx(in.readUint32Big()), x8_defaultAnim(in.readUint32Big()) {} CAssetId GetACSFile() const { return x0_ancs; } diff --git a/Runtime/World/CDamageInfo.hpp b/Runtime/World/CDamageInfo.hpp index d2591e92b..0e800520f 100644 --- a/Runtime/World/CDamageInfo.hpp +++ b/Runtime/World/CDamageInfo.hpp @@ -20,7 +20,7 @@ class CDamageInfo { public: constexpr CDamageInfo() = default; - CDamageInfo(CInputStream& in) { + explicit CDamageInfo(CInputStream& in) { in.readUint32Big(); x0_weaponMode = CWeaponMode(EWeaponType(in.readUint32Big())); x8_damage = in.readFloatBig(); @@ -38,7 +38,7 @@ public: constexpr CDamageInfo& operator=(CDamageInfo&&) = default; CDamageInfo(const CDamageInfo&, float); - CDamageInfo(const DataSpec::SShotParam& other); + explicit CDamageInfo(const DataSpec::SShotParam& other); CDamageInfo& operator=(const DataSpec::SShotParam& other); const CWeaponMode& GetWeaponMode() const { return x0_weaponMode; } diff --git a/Runtime/World/CDamageVulnerability.cpp b/Runtime/World/CDamageVulnerability.cpp index c0c367c52..cb48efc37 100644 --- a/Runtime/World/CDamageVulnerability.cpp +++ b/Runtime/World/CDamageVulnerability.cpp @@ -17,14 +17,14 @@ const CDamageVulnerability CDamageVulnerability::sImmuneVulnerability( EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::None); -/* LOL, thanks retro */ + const CDamageVulnerability CDamageVulnerability::sReflectVulnerability( EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, - EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::None); + EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::One); const CDamageVulnerability CDamageVulnerability::sPassThroughVulnerability( EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, diff --git a/Runtime/World/CDamageVulnerability.hpp b/Runtime/World/CDamageVulnerability.hpp index af83e8e03..b66f23ab5 100644 --- a/Runtime/World/CDamageVulnerability.hpp +++ b/Runtime/World/CDamageVulnerability.hpp @@ -47,7 +47,7 @@ class CDamageVulnerability { static const CDamageVulnerability sPassThroughVulnerability; public: - CDamageVulnerability(CInputStream& in); + explicit CDamageVulnerability(CInputStream& in); CDamageVulnerability(EVulnerability power, EVulnerability ice, EVulnerability wave, EVulnerability plasma, EVulnerability bomb, EVulnerability powerBomb, EVulnerability missile, EVulnerability boostBall, EVulnerability phazon, EVulnerability enemyWp1, EVulnerability wnemyWp2, EVulnerability enemyWp3, diff --git a/Runtime/World/CEffect.hpp b/Runtime/World/CEffect.hpp index ef3b7fea2..d43df85ee 100644 --- a/Runtime/World/CEffect.hpp +++ b/Runtime/World/CEffect.hpp @@ -8,8 +8,8 @@ class CEffect : public CActor { public: CEffect(TUniqueId uid, const CEntityInfo& info, bool active, std::string_view name, const zeus::CTransform& xf); - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override {} - void Render(const CStateManager&) const override {} + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override {} + void Render(CStateManager&) override {} }; } // namespace urde diff --git a/Runtime/World/CEntity.hpp b/Runtime/World/CEntity.hpp index 912126227..fd8dd406a 100644 --- a/Runtime/World/CEntity.hpp +++ b/Runtime/World/CEntity.hpp @@ -37,8 +37,8 @@ public: virtual ~CEntity() = default; CEntity(TUniqueId uid, const CEntityInfo& info, bool active, std::string_view name); virtual void Accept(IVisitor& visitor) = 0; - virtual void PreThink(float, CStateManager&) {} - virtual void Think(float, CStateManager&) {} + virtual void PreThink(float dt, CStateManager& mgr) {} + virtual void Think(float dt, CStateManager& mgr) {} virtual void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr); virtual void SetActive(bool active) { x30_24_active = active; } @@ -61,8 +61,8 @@ public: TEditorId GetEditorId() const { return xc_editorId; } void SendScriptMsgs(EScriptObjectState state, CStateManager& stateMgr, EScriptObjectMessage msg); + std::vector& GetConnectionList() { return x20_conns; } const std::vector& GetConnectionList() const { return x20_conns; } - std::vector& ConnectionList() { return x20_conns; } std::string_view GetName() const { return x10_name; } }; diff --git a/Runtime/World/CEnvFxManager.cpp b/Runtime/World/CEnvFxManager.cpp index 443cef1bd..0ec4437a2 100644 --- a/Runtime/World/CEnvFxManager.cpp +++ b/Runtime/World/CEnvFxManager.cpp @@ -23,11 +23,11 @@ namespace urde { static rstl::reserved_vector g_SnowForces; CEnvFxManagerGrid::CEnvFxManagerGrid(const zeus::CVector2i& position, const zeus::CVector2i& extent, - const std::vector& initialParticles, int reserve, - CEnvFxManager& parent, boo::IGraphicsDataFactory::Context& ctx) + std::vector initialParticles, int reserve, CEnvFxManager& parent, + boo::IGraphicsDataFactory::Context& ctx) : x4_position(position) , xc_extent(extent) -, x1c_particles(initialParticles) +, x1c_particles(std::move(initialParticles)) , m_instBuf(parent.m_instPool.allocateBlock(CGraphics::g_BooFactory, reserve)) , m_uniformBuf(parent.m_uniformPool.allocateBlock(CGraphics::g_BooFactory)) , m_lineRenderer(ctx, CLineRenderer::EPrimitiveMode::Lines, reserve * 2, parent.x40_txtrEnvGradient->GetBooTexture(), diff --git a/Runtime/World/CEnvFxManager.hpp b/Runtime/World/CEnvFxManager.hpp index 8fe12fc1d..02bc1f4e3 100644 --- a/Runtime/World/CEnvFxManager.hpp +++ b/Runtime/World/CEnvFxManager.hpp @@ -79,7 +79,7 @@ class CEnvFxManagerGrid { public: CEnvFxManagerGrid(const zeus::CVector2i& position, const zeus::CVector2i& extent, - const std::vector& initialParticles, int reserve, CEnvFxManager& parent, + std::vector initialParticles, int reserve, CEnvFxManager& parent, boo::IGraphicsDataFactory::Context& ctx); void Render(const zeus::CTransform& xf, const zeus::CTransform& invXf, const zeus::CTransform& camXf, float fxDensity, EEnvFxType fxType, const CEnvFxManager& parent) const; diff --git a/Runtime/World/CExplosion.cpp b/Runtime/World/CExplosion.cpp index 075a3b18a..4aa319553 100644 --- a/Runtime/World/CExplosion.cpp +++ b/Runtime/World/CExplosion.cpp @@ -89,20 +89,21 @@ void CExplosion::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { xe4_30_outOfFrustum = !xf4_25_ || !frustum.aabbFrustumTest(x9c_renderBounds); } -void CExplosion::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { - if (xe4_30_outOfFrustum) +void CExplosion::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { + if (xe4_30_outOfFrustum) { return; + } if (!(xf4_24_renderThermalHot && mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot) && !(xf4_26_renderXray && mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay)) { - g_Renderer->AddParticleGen(*xe8_particleGen.get()); + g_Renderer->AddParticleGen(*xe8_particleGen); return; } EnsureRendered(mgr); } -void CExplosion::Render(const CStateManager& mgr) const { +void CExplosion::Render(CStateManager& mgr) { if (mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot && xf4_24_renderThermalHot) { CElementGen::SetSubtractBlend(true); CBooModel::SetRenderModelBlack(true); diff --git a/Runtime/World/CExplosion.hpp b/Runtime/World/CExplosion.hpp index 8dd858bd4..dfdbc5c90 100644 --- a/Runtime/World/CExplosion.hpp +++ b/Runtime/World/CExplosion.hpp @@ -33,8 +33,8 @@ public: void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float, CStateManager&) override; void PreRender(CStateManager&, const zeus::CFrustum&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager&) override; bool CanRenderUnsorted(const CStateManager&) const override; }; diff --git a/Runtime/World/CFire.cpp b/Runtime/World/CFire.cpp index cde3c3726..713a1798f 100644 --- a/Runtime/World/CFire.cpp +++ b/Runtime/World/CFire.cpp @@ -84,7 +84,7 @@ void CFire::Touch(CActor& act, CStateManager& mgr) { CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {}); } -void CFire::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { +void CFire::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { bool drawParticles = true; if (!x148_27_) { using EPlayerVisor = CPlayerState::EPlayerVisor; diff --git a/Runtime/World/CFire.hpp b/Runtime/World/CFire.hpp index 6988fda22..f2471d3b2 100644 --- a/Runtime/World/CFire.hpp +++ b/Runtime/World/CFire.hpp @@ -42,6 +42,6 @@ public: } void Touch(CActor&, CStateManager&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; }; } // namespace urde \ No newline at end of file diff --git a/Runtime/World/CFishCloud.cpp b/Runtime/World/CFishCloud.cpp index 570b9ecc4..16f86f27d 100644 --- a/Runtime/World/CFishCloud.cpp +++ b/Runtime/World/CFishCloud.cpp @@ -518,11 +518,11 @@ void CFishCloud::RenderBoid(int idx, const CBoid& boid, u32& drawMask, CModelFlags thermFlags(0, 0, 3, zeus::skWhite); mData.RenderThermal(zeus::skWhite, zeus::CColor(0.f, 0.25f), thermFlags); } else { - mData.GetAnimationData()->Render(model, flags, {}, nullptr); + mData.GetAnimationData()->Render(model, flags, std::nullopt, nullptr); } } -void CFishCloud::Render(const CStateManager& mgr) const { +void CFishCloud::Render(CStateManager& mgr) { if (!GetActive()) return; SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(fmt("CFishCloud::Render {} {} {}"), diff --git a/Runtime/World/CFishCloud.hpp b/Runtime/World/CFishCloud.hpp index 036606ef0..f6c13f3bf 100644 --- a/Runtime/World/CFishCloud.hpp +++ b/Runtime/World/CFishCloud.hpp @@ -145,7 +145,7 @@ public: void Think(float dt, CStateManager& mgr) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) override; void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; - void Render(const CStateManager& mgr) const override; + void Render(CStateManager& mgr) override; void CalculateRenderBounds() override; std::optional GetTouchBounds() const override; void Touch(CActor& other, CStateManager& mgr) override; diff --git a/Runtime/World/CFluidPlane.cpp b/Runtime/World/CFluidPlane.cpp index f1ccb7ac6..aaf96d8ff 100644 --- a/Runtime/World/CFluidPlane.cpp +++ b/Runtime/World/CFluidPlane.cpp @@ -35,7 +35,7 @@ float CFluidPlane::ProjectRippleVelocity(float baseI, float velDot) const { } float CFluidPlane::CalculateRippleIntensity(float baseI) const { - float mul; + float mul = 0.0f; switch (x44_fluidType) { case EFluidType::NormalWater: mul = g_tweakGame->GetRippleIntensityNormal(); @@ -87,7 +87,7 @@ void CFluidPlane::RenderStripWithRipples(float curY, const CFluidPlaneRender::SH const u8 (&flags)[9][9], int startYDiv, const CFluidPlaneRender::SPatchInfo& info, std::vector& vOut, - std::vector& pvOut) const { + std::vector& pvOut) { m_shader->bindRegular(); int yTile = (startYDiv + CFluidPlaneRender::numSubdivisionsInTile - 1) / CFluidPlaneRender::numSubdivisionsInTile; @@ -313,7 +313,7 @@ void CFluidPlane::RenderStripWithRipples(float curY, const CFluidPlaneRender::SH void CFluidPlane::RenderPatch(const CFluidPlaneRender::SPatchInfo& info, const CFluidPlaneRender::SHFieldSample (&heights)[46][46], const u8 (&flags)[9][9], bool noRipples, bool flagIs1, std::vector& vOut, - std::vector& pvOut) const { + std::vector& pvOut) { if (noRipples) { m_shader->bindRegular(); diff --git a/Runtime/World/CFluidPlane.hpp b/Runtime/World/CFluidPlane.hpp index a4d848125..c5c70128e 100644 --- a/Runtime/World/CFluidPlane.hpp +++ b/Runtime/World/CFluidPlane.hpp @@ -128,9 +128,9 @@ protected: float x48_rippleIntensity; CFluidUVMotion x4c_uvMotion; - mutable std::vector m_verts; - mutable std::vector m_pVerts; - mutable std::optional m_shader; + std::vector m_verts; + std::vector m_pVerts; + std::optional m_shader; float ProjectRippleVelocity(float baseI, float velDot) const; float CalculateRippleIntensity(float baseI) const; @@ -138,10 +138,10 @@ protected: virtual void RenderStripWithRipples(float curY, const CFluidPlaneRender::SHFieldSample (&heights)[46][46], const u8 (&flags)[9][9], int startYDiv, const CFluidPlaneRender::SPatchInfo& info, std::vector& vOut, - std::vector& pvOut) const; + std::vector& pvOut); void RenderPatch(const CFluidPlaneRender::SPatchInfo& info, const CFluidPlaneRender::SHFieldSample (&heights)[46][46], const u8 (&flags)[9][9], bool noRipples, bool flagIs1, std::vector& vOut, - std::vector& pvOut) const; + std::vector& pvOut); public: virtual ~CFluidPlane() = default; @@ -162,7 +162,7 @@ public: virtual void Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf, const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum, const std::optional& rippleManager, TUniqueId waterId, - const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const {} + const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) {} float GetAlpha() const { return x40_alpha; } EFluidType GetFluidType() const { return x44_fluidType; } diff --git a/Runtime/World/CFluidPlaneCPU.cpp b/Runtime/World/CFluidPlaneCPU.cpp index e9349a5b8..f30ad5efc 100644 --- a/Runtime/World/CFluidPlaneCPU.cpp +++ b/Runtime/World/CFluidPlaneCPU.cpp @@ -125,7 +125,7 @@ static const float* InitializeSineWave() { CFluidPlaneShader::RenderSetupInfo CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::CTransform& xf, const zeus::CTransform& areaXf, const zeus::CAABox& aabb, - const CScriptWater* water) const { + const CScriptWater* water) { CFluidPlaneShader::RenderSetupInfo out; float uvT = mgr.GetFluidPlaneManager()->GetUVT(); @@ -740,7 +740,7 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum, const std::optional& rippleManager, TUniqueId waterId, const bool* gridFlags, u32 gridDimX, u32 gridDimY, - const zeus::CVector3f& areaCenter) const { + const zeus::CVector3f& areaCenter) { SCOPED_GRAPHICS_DEBUG_GROUP("CFluidPlaneCPU::Render", zeus::skCyan); TCastToConstPtr water = mgr.GetObjectById(waterId); CFluidPlaneShader::RenderSetupInfo setupInfo = RenderSetup(mgr, alpha, xf, areaXf, aabb, water.GetPtr()); diff --git a/Runtime/World/CFluidPlaneCPU.hpp b/Runtime/World/CFluidPlaneCPU.hpp index 35ef93eca..6572ad38e 100644 --- a/Runtime/World/CFluidPlaneCPU.hpp +++ b/Runtime/World/CFluidPlaneCPU.hpp @@ -60,8 +60,8 @@ protected: u32 m_maxVertCount; bool m_tessellation = false; - mutable bool m_cachedDoubleLightmapBlend; - mutable bool m_cachedAdditive; + bool m_cachedDoubleLightmapBlend; + bool m_cachedAdditive; static bool PrepareRipple(const CRipple& ripple, const CFluidPlaneRender::SPatchInfo& info, CFluidPlaneRender::SRippleInfo& rippleOut); @@ -96,11 +96,11 @@ public: zeus::CMatrix4f& mtxOut) const; CFluidPlaneShader::RenderSetupInfo RenderSetup(const CStateManager& mgr, float, const zeus::CTransform& xf, const zeus::CTransform& areaXf, const zeus::CAABox& aabb, - const CScriptWater* water) const; + const CScriptWater* water); void Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf, const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum, const std::optional& rippleManager, TUniqueId waterId, const bool* gridFlags, - u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const override; + u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) override; float GetReflectionBlend() const { return x114_reflectionBlend; } float GetSpecularMax() const { return x110_specularMax; } float GetSpecularMin() const { return x10c_specularMin; } diff --git a/Runtime/World/CFluidPlaneDoor.cpp b/Runtime/World/CFluidPlaneDoor.cpp index d91d52238..339d321bd 100644 --- a/Runtime/World/CFluidPlaneDoor.cpp +++ b/Runtime/World/CFluidPlaneDoor.cpp @@ -15,7 +15,7 @@ CFluidPlaneDoor::CFluidPlaneDoor(CAssetId patternTex1, CAssetId patternTex2, CAs CFluidPlaneShader::RenderSetupInfo CFluidPlaneDoor::RenderSetup(const CStateManager& mgr, float alpha, const zeus::CTransform& xf, const zeus::CAABox& aabb, - bool noNormals) const { + bool noNormals) { CFluidPlaneShader::RenderSetupInfo out; float uvT = mgr.GetFluidPlaneManager()->GetUVT(); @@ -62,7 +62,7 @@ void CFluidPlaneDoor::Render(const CStateManager& mgr, float alpha, const zeus:: const zeus::CFrustum& frustum, const std::optional& rippleManager, TUniqueId waterId, const bool* gridFlags, u32 gridDimX, u32 gridDimY, - const zeus::CVector3f& areaCenter) const { + const zeus::CVector3f& areaCenter) { SCOPED_GRAPHICS_DEBUG_GROUP("CFluidPlaneDoor::Render", zeus::skCyan); CFluidPlaneShader::RenderSetupInfo setupInfo = RenderSetup(mgr, alpha, xf, aabb, noNormals); diff --git a/Runtime/World/CFluidPlaneDoor.hpp b/Runtime/World/CFluidPlaneDoor.hpp index f3885b59d..32ca87014 100644 --- a/Runtime/World/CFluidPlaneDoor.hpp +++ b/Runtime/World/CFluidPlaneDoor.hpp @@ -12,7 +12,7 @@ class CFluidPlaneDoor final : public CFluidPlane { float xa8_rippleResolution; CFluidPlaneShader::RenderSetupInfo RenderSetup(const CStateManager& mgr, float alpha, const zeus::CTransform& xf, - const zeus::CAABox& aabb, bool noNormals) const; + const zeus::CAABox& aabb, bool noNormals); public: CFluidPlaneDoor(CAssetId patternTex1, CAssetId patternTex2, CAssetId colorTex, float tileSize, u32 tileSubdivisions, @@ -26,7 +26,7 @@ public: void Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf, const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum, const std::optional& rippleManager, TUniqueId waterId, const bool* gridFlags, - u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const override; + u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) override; }; } // namespace urde diff --git a/Runtime/World/CFluidPlaneGPU.cpp b/Runtime/World/CFluidPlaneGPU.cpp index 120bdcdb6..e83d494a3 100644 --- a/Runtime/World/CFluidPlaneGPU.cpp +++ b/Runtime/World/CFluidPlaneGPU.cpp @@ -21,7 +21,7 @@ void CFluidPlaneGPU::RenderStripWithRipples(float curY, const CFluidPlaneRender: const u8 (&flags)[9][9], int startYDiv, const CFluidPlaneRender::SPatchInfo& info, std::vector& vOut, - std::vector& pvOut) const { + std::vector& pvOut) { m_shader->bindTessellation(); int yTile = (startYDiv + CFluidPlaneRender::numSubdivisionsInTile - 1) / CFluidPlaneRender::numSubdivisionsInTile; diff --git a/Runtime/World/CFluidPlaneGPU.hpp b/Runtime/World/CFluidPlaneGPU.hpp index 958c97d38..00dc59121 100644 --- a/Runtime/World/CFluidPlaneGPU.hpp +++ b/Runtime/World/CFluidPlaneGPU.hpp @@ -20,7 +20,7 @@ public: void RenderStripWithRipples(float curY, const CFluidPlaneRender::SHFieldSample (&heights)[46][46], const u8 (&flags)[9][9], int startYDiv, const CFluidPlaneRender::SPatchInfo& info, std::vector& vOut, - std::vector& pvOut) const override; + std::vector& pvOut) override; }; } // namespace urde diff --git a/Runtime/World/CGameArea.cpp b/Runtime/World/CGameArea.cpp index 8172d8bc0..050adf9f7 100644 --- a/Runtime/World/CGameArea.cpp +++ b/Runtime/World/CGameArea.cpp @@ -353,28 +353,31 @@ CGameArea::CGameArea(CInputStream& in, int idx, int mlvlVersion) : x4_selfIdx(id else x88_areaId = -1; - u32 attachedCount = in.readUint32Big(); + const u32 attachedCount = in.readUint32Big(); x8c_attachedAreaIndices.reserve(attachedCount); - for (u32 i = 0; i < attachedCount; ++i) - x8c_attachedAreaIndices.push_back(in.readUint16Big()); + for (u32 i = 0; i < attachedCount; ++i) { + x8c_attachedAreaIndices.emplace_back(in.readUint16Big()); + } x9c_deps1 = ::urde::ReadDependencyList(in); xac_deps2 = ::urde::ReadDependencyList(in); - zeus::CAABox aabb = x6c_aabb.getTransformedAABox(xc_transform); + const zeus::CAABox aabb = x6c_aabb.getTransformedAABox(xc_transform); x6c_aabb = aabb; if (mlvlVersion > 13) { - u32 depCount = in.readUint32Big(); + const u32 depCount = in.readUint32Big(); xbc_layerDepOffsets.reserve(depCount); - for (u32 i = 0; i < depCount; ++i) - xbc_layerDepOffsets.push_back(in.readUint32Big()); + for (u32 i = 0; i < depCount; ++i) { + xbc_layerDepOffsets.emplace_back(in.readUint32Big()); + } } - u32 dockCount = in.readUint32Big(); + const u32 dockCount = in.readUint32Big(); xcc_docks.reserve(dockCount); - for (u32 i = 0; i < dockCount; ++i) - xcc_docks.push_back({in, xc_transform}); + for (u32 i = 0; i < dockCount; ++i) { + xcc_docks.emplace_back(in, xc_transform); + } ClearTokenList(); @@ -684,7 +687,7 @@ bool CGameArea::StartStreamingMainArea() { case EPhase::LoadHeader: { x110_mreaSecBufs.reserve(3); AllocNewAreaData(0, 96); - x12c_postConstructed.reset(new CPostConstructed()); + x12c_postConstructed = std::make_unique(); xf4_phase = EPhase::LoadSecSizes; break; } @@ -995,8 +998,8 @@ void CGameArea::PostConstructArea() { ++secIt; } - x12c_postConstructed->x10c0_areaObjs.reset(new CAreaObjectList(x4_selfIdx)); - x12c_postConstructed->x10c4_areaFog.reset(new CAreaFog()); + x12c_postConstructed->x10c0_areaObjs = std::make_unique(x4_selfIdx); + x12c_postConstructed->x10c4_areaFog = std::make_unique(); /* URDE addition: preemptively fill in area models so shaders may be polled for completion */ if (!x12c_postConstructed->x1108_25_modelsConstructed) diff --git a/Runtime/World/CGameArea.hpp b/Runtime/World/CGameArea.hpp index 30de66de8..31623d90b 100644 --- a/Runtime/World/CGameArea.hpp +++ b/Runtime/World/CGameArea.hpp @@ -86,7 +86,7 @@ struct CAreaRenderOctTree { const u32* x34_indirectionTable; const u8* x38_entries; - CAreaRenderOctTree(const u8* buf); + explicit CAreaRenderOctTree(const u8* buf); void FindOverlappingModels(std::vector& out, const zeus::CAABox& testAABB) const; void FindOverlappingModels(u32* out, const zeus::CAABox& testAABB) const; @@ -131,10 +131,11 @@ class CGameArea final : public IGameArea { public: class CChainIterator { - CGameArea* m_area; + CGameArea* m_area = nullptr; public: - CChainIterator(CGameArea* area) : m_area(area) {} + constexpr CChainIterator() = default; + explicit constexpr CChainIterator(CGameArea* area) : m_area(area) {} CGameArea& operator*() const { return *m_area; } CGameArea* operator->() const { return m_area; } CChainIterator& operator++() { @@ -146,10 +147,11 @@ public: }; class CConstChainIterator { - const CGameArea* m_area; + const CGameArea* m_area = nullptr; public: - CConstChainIterator(const CGameArea* area) : m_area(area) {} + constexpr CConstChainIterator() = default; + explicit constexpr CConstChainIterator(const CGameArea* area) : m_area(area) {} const CGameArea& operator*() const { return *m_area; } const CGameArea* operator->() const { return m_area; } CConstChainIterator& operator++() { @@ -165,7 +167,7 @@ public: TAreaId x200c_areaIdx = 0; public: - CAreaObjectList(TAreaId areaIdx) : CObjectList(EGameObjectList::Invalid), x200c_areaIdx(areaIdx) {} + explicit CAreaObjectList(TAreaId areaIdx) : CObjectList(EGameObjectList::Invalid), x200c_areaIdx(areaIdx) {} bool IsQualified(const CEntity& ent) const override; }; @@ -197,7 +199,7 @@ public: u32 x8_collisionSize = 0; std::optional xc_octTree; std::vector x4c_insts; - SShader m_materialSet = {0}; + SShader m_materialSet{0}; // std::unique_ptr x5c_; std::vector x60_lightsA; std::vector x70_gfxLightsA; @@ -267,8 +269,8 @@ private: void UpdateWeaponWorldLighting(float dt); public: - CGameArea(CInputStream& in, int idx, int mlvlVersion); - CGameArea(CAssetId mreaId); // Warmup constructor + explicit CGameArea(CInputStream& in, int idx, int mlvlVersion); + explicit CGameArea(CAssetId mreaId); // Warmup constructor ~CGameArea(); bool IsFinishedOccluding() const; diff --git a/Runtime/World/CGameLight.cpp b/Runtime/World/CGameLight.cpp index c5acc0a48..e03019125 100644 --- a/Runtime/World/CGameLight.cpp +++ b/Runtime/World/CGameLight.cpp @@ -8,14 +8,14 @@ namespace urde { CGameLight::CGameLight(TUniqueId uid, TAreaId aid, bool active, std::string_view name, const zeus::CTransform& xf, - TUniqueId parentId, const CLight& light, u32 sourceId, u32 w2, float f1) + TUniqueId parentId, const CLight& light, u32 sourceId, u32 priority, float lifeTime) : CActor(uid, active, name, CEntityInfo(aid, CEntity::NullConnectionList), xf, CModelData::CModelDataNull(), CMaterialList(), CActorParameters::None(), kInvalidUniqueId) , xe8_parentId(parentId) , xec_light(light) , x13c_lightId(sourceId) -, x140_priority(w2) -, x144_lifeTime(f1) { +, x140_priority(priority) +, x144_lifeTime(lifeTime) { xec_light.GetRadius(); xec_light.GetIntensity(); SetLightPriorityAndId(); diff --git a/Runtime/World/CGameLight.hpp b/Runtime/World/CGameLight.hpp index f64c850a0..d840a8bc9 100644 --- a/Runtime/World/CGameLight.hpp +++ b/Runtime/World/CGameLight.hpp @@ -15,13 +15,13 @@ class CGameLight : public CActor { float x144_lifeTime; public: - CGameLight(TUniqueId, TAreaId, bool, std::string_view, const zeus::CTransform&, TUniqueId, const CLight&, - u32 sourceId, u32, float); + CGameLight(TUniqueId uid, TAreaId aid, bool active, std::string_view name, const zeus::CTransform& xf, + TUniqueId parentId, const CLight& light, u32 sourceId, u32 priority, float lifeTime); void Accept(IVisitor& visitor) override; - void Think(float, CStateManager&) override; + void Think(float dt, CStateManager& mgr) override; void SetLightPriorityAndId(); - void SetLight(const CLight&); + void SetLight(const CLight& light); CLight GetLight() const; TUniqueId GetParentId() const { return xe8_parentId; } }; diff --git a/Runtime/World/CHUDBillboardEffect.cpp b/Runtime/World/CHUDBillboardEffect.cpp index 20a4a442d..f7b86cd37 100644 --- a/Runtime/World/CHUDBillboardEffect.cpp +++ b/Runtime/World/CHUDBillboardEffect.cpp @@ -78,7 +78,7 @@ void CHUDBillboardEffect::Think(float dt, CStateManager& mgr) { } } -void CHUDBillboardEffect::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { +void CHUDBillboardEffect::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { if (x104_25_enableRender && x104_24_renderAsParticleGen) { g_Renderer->AddParticleGen(*xe8_generator); } @@ -96,7 +96,7 @@ void CHUDBillboardEffect::PreRender(CStateManager& mgr, const zeus::CFrustum& fr x104_24_renderAsParticleGen = !mgr.RenderLast(GetUniqueId()); } -void CHUDBillboardEffect::Render(const CStateManager& mgr) const { +void CHUDBillboardEffect::Render(CStateManager& mgr) { if (x104_25_enableRender && !x104_24_renderAsParticleGen) { SCOPED_GRAPHICS_DEBUG_GROUP("CHUDBillboardEffect::Render", zeus::skPurple); xe8_generator->Render(); diff --git a/Runtime/World/CHUDBillboardEffect.hpp b/Runtime/World/CHUDBillboardEffect.hpp index cba72ef0d..4cc9ed779 100644 --- a/Runtime/World/CHUDBillboardEffect.hpp +++ b/Runtime/World/CHUDBillboardEffect.hpp @@ -37,9 +37,9 @@ public: ~CHUDBillboardEffect() override; void Accept(IVisitor& visitor) override; void Think(float dt, CStateManager& mgr) override; - void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) override; void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; - void Render(const CStateManager& mgr) const override; + void Render(CStateManager& mgr) override; bool IsElementGen() const { return x104_26_isElementGen; } void SetRunIndefinitely(bool b) { x104_27_runIndefinitely = b; } CParticleGen* GetParticleGen() const { return xe8_generator.get(); } diff --git a/Runtime/World/CHUDMemoParms.hpp b/Runtime/World/CHUDMemoParms.hpp index 61e3b678a..761f8a00b 100644 --- a/Runtime/World/CHUDMemoParms.hpp +++ b/Runtime/World/CHUDMemoParms.hpp @@ -14,7 +14,7 @@ public: CHUDMemoParms() = default; CHUDMemoParms(float dispTime, bool clearMemoWindow, bool fadeOutOnly, bool hintMemo) : x0_dispTime(dispTime), x4_clearMemoWindow(clearMemoWindow), x5_fadeOutOnly(fadeOutOnly), x6_hintMemo(hintMemo) {} - CHUDMemoParms(CInputStream& in) { + explicit CHUDMemoParms(CInputStream& in) { x0_dispTime = in.readFloatBig(); x4_clearMemoWindow = in.readBool(); } diff --git a/Runtime/World/CHealthInfo.hpp b/Runtime/World/CHealthInfo.hpp index c8d890a58..a69b52035 100644 --- a/Runtime/World/CHealthInfo.hpp +++ b/Runtime/World/CHealthInfo.hpp @@ -9,11 +9,11 @@ class CHealthInfo { float x4_knockbackResistance; public: - CHealthInfo(float hp) : x0_health(hp), x4_knockbackResistance(0.f) {} + explicit CHealthInfo(float hp) : x0_health(hp), x4_knockbackResistance(0.f) {} CHealthInfo(float hp, float resist) : x0_health(hp), x4_knockbackResistance(resist) {} - CHealthInfo(CInputStream& in); + explicit CHealthInfo(CInputStream& in); void SetHP(float hp) { x0_health = hp; } float GetHP() const { return x0_health; } float GetKnockbackResistance() const { return x4_knockbackResistance; } diff --git a/Runtime/World/CKnockBackController.hpp b/Runtime/World/CKnockBackController.hpp index 3c3180832..e3f4339ac 100644 --- a/Runtime/World/CKnockBackController.hpp +++ b/Runtime/World/CKnockBackController.hpp @@ -130,6 +130,7 @@ public: void Update(float dt, CStateManager& mgr, CPatterned& parent); void KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, CPatterned& parent, const CDamageInfo& info, EKnockBackType type, float magnitude); + void SetSeverity(pas::ESeverity v) { x7c_severity = v; } void SetEnableFreeze(bool b) { x81_25_enableFreeze = b; } void SetEnableShock(bool b) { x81_26_enableShock = b; } void SetEnableBurn(bool b) { x81_27_enableBurn = b; } @@ -146,4 +147,4 @@ public: bool TestAvailableState(EKnockBackAnimationState s) const { return x80_availableStates.test(size_t(s)); } }; -} // namespace urde \ No newline at end of file +} // namespace urde diff --git a/Runtime/World/CMorphBall.hpp b/Runtime/World/CMorphBall.hpp index c0f7e8b90..bc52fcc17 100644 --- a/Runtime/World/CMorphBall.hpp +++ b/Runtime/World/CMorphBall.hpp @@ -233,7 +233,7 @@ public: void RenderMorphBallTransitionFlash(const CStateManager&) const; void UpdateIceBreakEffect(float dt); void RenderIceBreakEffect(const CStateManager& mgr) const; - bool IsMorphBallTransitionFlashValid() const { return x19dc_morphBallTransitionFlashGen != 0; } + bool IsMorphBallTransitionFlashValid() const { return x19dc_morphBallTransitionFlashGen != nullptr; } void RenderDamageEffects(const CStateManager& mgr, const zeus::CTransform& xf) const; void UpdateHalfPipeStatus(CStateManager& mgr, float dt); bool GetIsInHalfPipeMode() const { return x1df8_24_inHalfPipeMode; } diff --git a/Runtime/World/CMorphBallShadow.cpp b/Runtime/World/CMorphBallShadow.cpp index 780d5efd8..0d60b55e0 100644 --- a/Runtime/World/CMorphBallShadow.cpp +++ b/Runtime/World/CMorphBallShadow.cpp @@ -73,8 +73,8 @@ void CMorphBallShadow::RenderIdBuffer(const zeus::CAABox& aabb, const CStateMana CModelFlags flags(0, 0, 3, zeus::CColor{1.f, 1.f, 1.f, alphaVal / 255.f}); flags.m_extendedShader = EExtendedShader::SolidColor; // Do solid color draw - const CBooModel& model = *modelData->PickStaticModel(CModelData::EWhichModel::Normal); - const_cast(model).VerifyCurrentShader(flags.x1_matSetIdx); + CBooModel& model = *modelData->PickStaticModel(CModelData::EWhichModel::Normal); + model.VerifyCurrentShader(flags.x1_matSetIdx); model.DrawNormal(flags, nullptr, nullptr); alphaVal += 4; } @@ -128,8 +128,8 @@ void CMorphBallShadow::Render(const CStateManager& mgr, float alpha) { CGraphics::SetModelMatrix(modelXf); flags.x4_color.r() = alphaVal / 255.f; - const CBooModel& model = *modelData->PickStaticModel(CModelData::EWhichModel::Normal); - const_cast(model).VerifyCurrentShader(flags.x1_matSetIdx); + CBooModel& model = *modelData->PickStaticModel(CModelData::EWhichModel::Normal); + model.VerifyCurrentShader(flags.x1_matSetIdx); model.DrawNormal(flags, nullptr, nullptr); alphaVal += 4; } diff --git a/Runtime/World/CPathFindArea.hpp b/Runtime/World/CPathFindArea.hpp index 89897d0f2..0f586702d 100644 --- a/Runtime/World/CPathFindArea.hpp +++ b/Runtime/World/CPathFindArea.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -17,16 +18,13 @@ class CVParamTransfer; class CObjectReference; class CPFBitSet { - u32 x0_bitmap[16] = {}; + std::bitset<512> x0_bitmap; public: - void Clear() { - for (u32& w : x0_bitmap) - w = 0; - } - void Add(s32 i) { x0_bitmap[i / 32] |= (1 << (i % 32)); } - bool Test(s32 i) const { return (x0_bitmap[i / 32] & (1 << (i % 32))) != 0; } - void Rmv(s32 i) { x0_bitmap[i / 32] &= ~(1 << (i % 32)); } + void Clear() { x0_bitmap.reset(); } + void Add(s32 i) { x0_bitmap.set(i); } + bool Test(s32 i) const { return x0_bitmap.test(i); } + void Rmv(s32 i) { x0_bitmap.reset(i); } }; class CPFAreaOctree { diff --git a/Runtime/World/CPathFindRegion.hpp b/Runtime/World/CPathFindRegion.hpp index b126f230e..a0cc8509e 100644 --- a/Runtime/World/CPathFindRegion.hpp +++ b/Runtime/World/CPathFindRegion.hpp @@ -17,7 +17,7 @@ class CPFNode { zeus::CVector3f xc_normal; public: - CPFNode(CMemoryInStream& in); + explicit CPFNode(CMemoryInStream& in); const zeus::CVector3f& GetPos() const { return x0_position; } const zeus::CVector3f& GetNormal() const { return xc_normal; } }; @@ -29,7 +29,7 @@ class CPFLink { float xc_oo2dWidth; public: - CPFLink(CMemoryInStream& in); + explicit CPFLink(CMemoryInStream& in); u32 GetNode() const { return x0_node; } u32 GetRegion() const { return x4_region; } float Get2dWidth() const { return x8_2dWidth; } @@ -51,7 +51,7 @@ class CPFRegion { public: CPFRegion() = default; - CPFRegion(CMemoryInStream& in); + explicit CPFRegion(CMemoryInStream& in); void SetData(CPFRegionData* data) { x4c_regionData = data; } CPFRegionData* Data() const { return x4c_regionData; } u32 GetIndex() const { return x24_regionIdx; } diff --git a/Runtime/World/CPathFindSearch.hpp b/Runtime/World/CPathFindSearch.hpp index 62adc4133..ce5a37d6e 100644 --- a/Runtime/World/CPathFindSearch.hpp +++ b/Runtime/World/CPathFindSearch.hpp @@ -14,6 +14,7 @@ class CPathFindSearch; class CPathFindVisualizer { CLineRenderer m_spline = {CLineRenderer::EPrimitiveMode::LineStrip, 16, {}, true}; + public: void Draw(const CPathFindSearch& path); }; @@ -56,6 +57,8 @@ public: void SetArea(CPFArea* area) { x0_area = area; } float GetCharacterHeight() const { return xd0_chHeight; } void SetCharacterHeight(float h) { xd0_chHeight = h; } + float GetCharacterRadius() const { return xd4_chRadius; } + void SetCharacterRadius(float r) { xd4_chRadius = r; } void SetPadding(float padding) { xd8_padding = padding; } float RemainingPathDistance(const zeus::CVector3f& pos) const; void DebugDraw() const; diff --git a/Runtime/World/CPatterned.cpp b/Runtime/World/CPatterned.cpp index 100fc1b27..1360075e3 100644 --- a/Runtime/World/CPatterned.cpp +++ b/Runtime/World/CPatterned.cpp @@ -1570,13 +1570,14 @@ void CPatterned::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { CActor::PreRender(mgr, frustum); } -void CPatterned::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { +void CPatterned::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { if (x402_29_drawParticles) { if (x64_modelData && !x64_modelData->IsNull()) { int mask, target; mgr.GetCharacterRenderMaskAndTarget(x402_31_thawed, mask, target); - if (CAnimData* aData = x64_modelData->GetAnimationData()) + if (CAnimData* aData = x64_modelData->GetAnimationData()) { aData->GetParticleDB().AddToRendererClippedMasked(frustum, mask, target); + } } } CActor::AddToRenderer(frustum, mgr); @@ -1586,11 +1587,11 @@ void CPatterned::RenderIceModelWithFlags(const CModelFlags& flags) const { CModelFlags useFlags = flags; useFlags.x1_matSetIdx = 0; CAnimData* animData = x64_modelData->GetAnimationData(); - if (CMorphableSkinnedModel* iceModel = animData->IceModel().GetObj()) + if (CMorphableSkinnedModel* iceModel = animData->GetIceModel().GetObj()) animData->Render(*iceModel, useFlags, {*x510_vertexMorph}, iceModel->GetMorphMagnitudes()); } -void CPatterned::Render(const CStateManager& mgr) const { +void CPatterned::Render(CStateManager& mgr) { int mask = 0; int target = 0; if (x402_29_drawParticles) { diff --git a/Runtime/World/CPatterned.hpp b/Runtime/World/CPatterned.hpp index 612eec1be..812675b6e 100644 --- a/Runtime/World/CPatterned.hpp +++ b/Runtime/World/CPatterned.hpp @@ -26,7 +26,8 @@ namespace urde { class CPatternedInfo; class CProjectileInfo; class CPathFindSearch; -typedef void (CPatterned::*CPatternedTryFunc)(CStateManager&, int); + +using CPatternedTryFunc = void (CPatterned::*)(CStateManager&, int); class CPatterned : public CAi { public: @@ -133,7 +134,7 @@ protected: bool x328_28_prevOnGround : 1; bool x328_29_noPatternShagging : 1; bool x328_30_lookAtDeathDir : 1; - bool x328_31_ : 1; + bool x328_31_energyAttractor : 1; bool x329_24_ : 1; }; u32 _dummy = 0; @@ -272,8 +273,8 @@ public: } void Think(float, CStateManager&) override; void PreRender(CStateManager&, const zeus::CFrustum&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager& mgr) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager& mgr) override; void CollidedWith(TUniqueId, const CCollisionInfoList&, CStateManager& mgr) override; void Touch(CActor& act, CStateManager& mgr) override; @@ -366,6 +367,7 @@ public: } float GetDamageDuration() const { return x504_damageDur; } zeus::CVector3f GetGunEyePos() const; + bool IsEnergyAttractor() const { return x328_31_energyAttractor; } bool IsAlive() const { return x400_25_alive; } void BuildBodyController(EBodyType); @@ -379,6 +381,7 @@ public: bool sendCollideMsg, const zeus::CVector3f& scale); void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; + const zeus::CVector3f& GetDestPos() const { return x2e0_destPos; } void SetDestPos(const zeus::CVector3f& pos) { x2e0_destPos = pos; } void UpdateAlphaDelta(float dt, CStateManager& mgr); void SetModelAlpha(float a) { x42c_color.a() = a; } diff --git a/Runtime/World/CPhysicsActor.cpp b/Runtime/World/CPhysicsActor.cpp index 9bf2343a6..b894a6b6a 100644 --- a/Runtime/World/CPhysicsActor.cpp +++ b/Runtime/World/CPhysicsActor.cpp @@ -25,7 +25,7 @@ CPhysicsActor::CPhysicsActor(TUniqueId uid, bool active, std::string_view name, ComputeDerivedQuantities(); } -void CPhysicsActor::Render(const CStateManager& mgr) const { CActor::Render(mgr); } +void CPhysicsActor::Render(CStateManager& mgr) { CActor::Render(mgr); } zeus::CVector3f CPhysicsActor::GetOrbitPosition(const CStateManager&) const { return GetBoundingBox().center(); } diff --git a/Runtime/World/CPhysicsActor.hpp b/Runtime/World/CPhysicsActor.hpp index a4aa4b46f..887ae123c 100644 --- a/Runtime/World/CPhysicsActor.hpp +++ b/Runtime/World/CPhysicsActor.hpp @@ -21,7 +21,7 @@ struct SMoverData { zeus::CAxisAngle x24_; float x30_mass; - SMoverData(float mass) : x30_mass(mass) {} + explicit SMoverData(float mass) : x30_mass(mass) {} }; struct CMotionState { @@ -48,18 +48,19 @@ class CPhysicsState { zeus::CAxisAngle x64_angularImpulse; public: - CPhysicsState(const zeus::CVector3f& translation, const zeus::CQuaternion& orient, const zeus::CVector3f& v2, - const zeus::CAxisAngle& a1, const zeus::CVector3f& v3, const zeus::CVector3f& v4, - const zeus::CVector3f& v5, const zeus::CAxisAngle& a2, const zeus::CAxisAngle& a3) + CPhysicsState(const zeus::CVector3f& translation, const zeus::CQuaternion& orient, + const zeus::CVector3f& constantForce, const zeus::CAxisAngle& angularMomentum, + const zeus::CVector3f& momentum, const zeus::CVector3f& force, const zeus::CVector3f& impulse, + const zeus::CAxisAngle& torque, const zeus::CAxisAngle& angularImpulse) : x0_translation(translation) , xc_orientation(orient) - , x1c_constantForce(v2) - , x28_angularMomentum(a1) - , x34_momentum(v3) - , x40_force(v4) - , x4c_impulse(v5) - , x58_torque(a2) - , x64_angularImpulse(a3) {} + , x1c_constantForce(constantForce) + , x28_angularMomentum(angularMomentum) + , x34_momentum(momentum) + , x40_force(force) + , x4c_impulse(impulse) + , x58_torque(torque) + , x64_angularImpulse(angularImpulse) {} void SetTranslation(const zeus::CVector3f& tr) { x0_translation = tr; } void SetOrientation(const zeus::CQuaternion& orient) { xc_orientation = orient; } @@ -116,15 +117,16 @@ protected: u32 x250_numTicksPartialUpdate = 0; public: - CPhysicsActor(TUniqueId, bool, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, - const CMaterialList&, const zeus::CAABox&, const SMoverData&, const CActorParameters&, float, float); + CPhysicsActor(TUniqueId uid, bool active, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CMaterialList& matList, const zeus::CAABox& box, const SMoverData& moverData, + const CActorParameters& actorParms, float stepUp, float stepDown); - void Render(const CStateManager& mgr) const override; - zeus::CVector3f GetOrbitPosition(const CStateManager&) const override; - zeus::CVector3f GetAimPosition(const CStateManager&, float val) const override; + void Render(CStateManager& mgr) override; + zeus::CVector3f GetOrbitPosition(const CStateManager& mgr) const override; + zeus::CVector3f GetAimPosition(const CStateManager& mgr, float val) const override; virtual const CCollisionPrimitive* GetCollisionPrimitive() const; virtual zeus::CTransform GetPrimitiveTransform() const; - virtual void CollidedWith(TUniqueId, const CCollisionInfoList&, CStateManager&); + virtual void CollidedWith(TUniqueId id, const CCollisionInfoList& list, CStateManager& mgr); virtual float GetStepUpHeight() const; virtual float GetStepDownHeight() const; virtual float GetWeight() const; @@ -144,7 +146,7 @@ public: void SetLastNonCollidingState(const CMotionState& mst) { x1f4_lastNonCollidingState = mst; } void SetMotionState(const CMotionState& mst); float GetMaximumCollisionVelocity() const { return x238_maximumCollisionVelocity; } - void SetMaximumCollisionVelocity(float v) { x238_maximumCollisionVelocity = v; } + void SetMaximumCollisionVelocity(float velocity) { x238_maximumCollisionVelocity = velocity; } void SetInertiaTensorScalar(float tensor); void SetMass(float mass); void SetAngularVelocityOR(const zeus::CAxisAngle& angVel); @@ -156,14 +158,15 @@ public: const zeus::CVector3f& GetMoveImpulseOR() const { return x18c_moveImpulse; } void SetVelocityWR(const zeus::CVector3f& vel); void SetVelocityOR(const zeus::CVector3f& vel); - void SetMomentumWR(const zeus::CVector3f& m) { x150_momentum = m; } + void SetMomentumWR(const zeus::CVector3f& momentum) { x150_momentum = momentum; } const zeus::CVector3f& GetConstantForce() const { return xfc_constantForce; } - void SetConstantForce(const zeus::CVector3f& f) { xfc_constantForce = f; } - void SetAngularMomentum(const zeus::CAxisAngle& m) { x108_angularMomentum = m; } + void SetConstantForce(const zeus::CVector3f& force) { xfc_constantForce = force; } + const zeus::CVector3f& GetAngularMomentum() const { return x108_angularMomentum; } + void SetAngularMomentum(const zeus::CAxisAngle& momentum) { x108_angularMomentum = momentum; } const zeus::CVector3f& GetMomentum() const { return x150_momentum; } const zeus::CVector3f& GetVelocity() const { return x138_velocity; } const zeus::CAxisAngle& GetAngularImpulse() const { return x180_angularImpulse; } - void SetAngularImpulse(const zeus::CAxisAngle& i) { x180_angularImpulse = i; } + void SetAngularImpulse(const zeus::CAxisAngle& impulse) { x180_angularImpulse = impulse; } zeus::CVector3f GetTotalForcesWR() const; void RotateInOneFrameOR(const zeus::CQuaternion& q, float d); void MoveInOneFrameOR(const zeus::CVector3f& trans, float d); @@ -177,26 +180,26 @@ public: void ClearForcesAndTorques(); void Stop(); void ComputeDerivedQuantities(); - bool WillMove(const CStateManager&) const; + bool WillMove(const CStateManager& mgr) const; void SetPhysicsState(const CPhysicsState& state); CPhysicsState GetPhysicsState() const; bool IsMovable() const { return xf8_24_movable; } - void SetMovable(bool m) { xf8_24_movable = m; } + void SetMovable(bool movable) { xf8_24_movable = movable; } bool IsAngularEnabled() const { return xf8_25_angularEnabled; } - void SetAngularEnabled(bool e) { xf8_25_angularEnabled = e; } + void SetAngularEnabled(bool enabled) { xf8_25_angularEnabled = enabled; } float GetCollisionAccuracyModifier() const { return x248_collisionAccuracyModifier; } - void SetCollisionAccuracyModifier(float m) { x248_collisionAccuracyModifier = m; } + void SetCollisionAccuracyModifier(float modifier) { x248_collisionAccuracyModifier = modifier; } float GetCoefficientOfRestitutionModifier() const { return x244_restitutionCoefModifier; } - void SetCoefficientOfRestitutionModifier(float m) { x244_restitutionCoefModifier = m; } + void SetCoefficientOfRestitutionModifier(float modifier) { x244_restitutionCoefModifier = modifier; } bool IsUseStandardCollider() const { return xf9_standardCollider; } u32 GetNumTicksPartialUpdate() const { return x250_numTicksPartialUpdate; } - void SetNumTicksPartialUpdate(u32 t) { x250_numTicksPartialUpdate = t; } + void SetNumTicksPartialUpdate(u32 ticks) { x250_numTicksPartialUpdate = ticks; } u32 GetNumTicksStuck() const { return x24c_numTicksStuck; } - void SetNumTicksStuck(u32 t) { x24c_numTicksStuck = t; } + void SetNumTicksStuck(u32 ticks) { x24c_numTicksStuck = ticks; } const std::optional& GetLastFloorPlaneNormal() const { return x228_lastFloorPlaneNormal; } - void SetLastFloorPlaneNormal(const std::optional& n) { x228_lastFloorPlaneNormal = n; } + void SetLastFloorPlaneNormal(const std::optional& normal) { x228_lastFloorPlaneNormal = normal; } CMotionState PredictMotion_Internal(float) const; CMotionState PredictMotion(float dt) const; diff --git a/Runtime/World/CPlayer.cpp b/Runtime/World/CPlayer.cpp index 5088641a3..812085fe1 100644 --- a/Runtime/World/CPlayer.cpp +++ b/Runtime/World/CPlayer.cpp @@ -185,7 +185,7 @@ constexpr std::array(uid); x49c_gunHolsterRemTime = g_tweakPlayerGun->GetGunNotFiringTime(); x4a0_failsafeTest = std::make_unique(); - x76c_cameraBob.reset(new CPlayerCameraBob(CPlayerCameraBob::ECameraBobType::One, - CPlayerCameraBob::GetCameraBobExtent(), - CPlayerCameraBob::GetCameraBobPeriod())); + x76c_cameraBob = + std::make_unique(CPlayerCameraBob::ECameraBobType::One, CPlayerCameraBob::GetCameraBobExtent(), + CPlayerCameraBob::GetCameraBobPeriod()); x9c4_26_ = true; x9c4_27_canEnterMorphBall = true; x9c4_28_canLeaveMorphBall = true; x9c5_31_stepCameraZBiasDirty = true; - CAssetId beamId = g_tweakPlayerRes->GetBeamBallTransitionModel(x7ec_beam); + const CAssetId beamId = g_tweakPlayerRes->GetBeamBallTransitionModel(x7ec_beam); x7f0_ballTransitionBeamModel = std::make_unique(CStaticRes(beamId, playerScale)); x730_transitionModels.reserve(3); x768_morphball = std::make_unique(*this, ballRadius); @@ -243,15 +243,16 @@ CPlayer::CPlayer(TUniqueId uid, const zeus::CTransform& xf, const zeus::CAABox& x490_gun->GetGrappleArm().SetTransform(x34_transform); InitializeBallTransition(); - zeus::CAABox ballTransAABB = x64_modelData->GetBounds(); + const zeus::CAABox ballTransAABB = x64_modelData->GetBounds(); x2f0_ballTransHeight = ballTransAABB.max.z() - ballTransAABB.min.z(); SetCalculateLighting(true); x90_actorLights->SetCastShadows(true); x50c_moveDir.z() = 0.f; - if (x50c_moveDir.canBeNormalized()) + if (x50c_moveDir.canBeNormalized()) { x50c_moveDir.normalize(); + } x2b4_accelerationTable.push_back(20.f); x2b4_accelerationTable.push_back(80.f); x2b4_accelerationTable.push_back(80.f); @@ -268,52 +269,61 @@ CPlayer::CPlayer(TUniqueId uid, const zeus::CTransform& xf, const zeus::CAABox& } void CPlayer::InitializeBallTransition() { - if (x64_modelData && x64_modelData->HasAnimData()) + if (x64_modelData && x64_modelData->HasAnimData()) { x64_modelData->GetAnimationData()->SetAnimation(CAnimPlaybackParms(2, -1, 1.f, true), false); + } } bool CPlayer::IsTransparent() const { return x588_alpha < 1.f; } float CPlayer::GetTransitionAlpha(const zeus::CVector3f& camPos, float zNear) const { - float zLimit = (x2d8_fpBounds.max.x() - x2d8_fpBounds.min.x()) * 0.5f + zNear; - float zStart = 1.f + zLimit; - float dist = (camPos - GetEyePosition()).magnitude(); - if (dist >= zLimit && dist <= zStart) + const float zLimit = (x2d8_fpBounds.max.x() - x2d8_fpBounds.min.x()) * 0.5f + zNear; + const float zStart = 1.f + zLimit; + const float dist = (camPos - GetEyePosition()).magnitude(); + + if (dist >= zLimit && dist <= zStart) { return (dist - zLimit) / (zStart - zLimit); - else if (dist > zStart) + } + + if (dist > zStart) { return 1.f; - else - return 0.f; + } + + return 0.f; } s32 CPlayer::ChooseTransitionToAnimation(float dt, CStateManager& mgr) const { - if (x258_movementState == EPlayerMovementState::ApplyJump) + if (x258_movementState == EPlayerMovementState::ApplyJump) { return 3; // B_airposetoball_samus - zeus::CVector3f localVel = x34_transform.transposeRotate(x138_velocity); + } + + const zeus::CVector3f localVel = x34_transform.transposeRotate(x138_velocity); zeus::CVector3f localVelFlat = localVel; localVelFlat.z() = 0.f; - float localVelFlatMag = localVelFlat.magnitude(); - if (localVelFlatMag > 1.f) { - zeus::CRelAngle velAng = std::atan2(localVelFlat.x(), localVelFlat.y()); - float velDeg = velAng.asDegrees(); - if (velDeg < 45.f || velDeg > 315.f) { - if (localVelFlatMag < 0.5f * GetActualFirstPersonMaxVelocity(dt)) - return 0; // B_forwardtoballforward_samus - else - return 4; // B_runtoballfoward_samus - } else { - return 1; // B_readytostationarybackwards_samus - } - } else { + const float localVelFlatMag = localVelFlat.magnitude(); + if (localVelFlatMag <= 1.f) { return 2; // B_readytoball_samus } + + const zeus::CRelAngle velAng = std::atan2(localVelFlat.x(), localVelFlat.y()); + const float velDeg = velAng.asDegrees(); + if (velDeg >= 45.f && velDeg <= 315.f) { + return 1; // B_readytostationarybackwards_samus + } + + if (localVelFlatMag < 0.5f * GetActualFirstPersonMaxVelocity(dt)) { + return 0; // B_forwardtoballforward_samus + } + + return 4; // B_runtoballfoward_samus + } void CPlayer::TransitionToMorphBallState(float dt, CStateManager& mgr) { x584_ballTransitionAnim = ChooseTransitionToAnimation(dt, mgr); x58c_transitionVel = x138_velocity.magnitude(); if (x64_modelData && x64_modelData->HasAnimData()) { - CAnimPlaybackParms parms(x584_ballTransitionAnim, -1, 1.f, true); + const CAnimPlaybackParms parms(x584_ballTransitionAnim, -1, 1.f, true); x64_modelData->GetAnimationData()->SetAnimation(parms, false); x64_modelData->GetAnimationData()->SetAnimDir(CAnimData::EAnimDir::Forward); } @@ -340,7 +350,7 @@ void CPlayer::TransitionToMorphBallState(float dt, CStateManager& mgr) { } else { ballCam->SetState(CBallCamera::EBallCameraState::Default, mgr); SetCameraState(EPlayerCameraState::Ball, mgr); - zeus::CTransform newXf = mgr.GetCameraManager()->GetFirstPersonCamera()->GetTransform(); + const zeus::CTransform newXf = mgr.GetCameraManager()->GetFirstPersonCamera()->GetTransform(); ballCam->SetTransform(newXf); ballCam->TeleportCamera(newXf.origin, mgr); mgr.GetCameraManager()->SetupBallCamera(mgr); @@ -355,16 +365,19 @@ void CPlayer::TransitionToMorphBallState(float dt, CStateManager& mgr) { void CPlayer::TransitionFromMorphBallState(CStateManager& mgr) { x584_ballTransitionAnim = 14; // B_ball_unfurl x58c_transitionVel = zeus::CVector2f(x138_velocity.x(), x138_velocity.y()).magnitude(); - if (x58c_transitionVel < 1.f) + if (x58c_transitionVel < 1.f) { x584_ballTransitionAnim = 5; // ballstationarytoready_random + } + if (x258_movementState != EPlayerMovementState::OnGround) { - zeus::CVector3f ballPos = GetBallPosition(); - if (mgr.RayCollideWorld(ballPos, ballPos + zeus::CVector3f(0.f, 0.f, -7.f), BallTransitionCollide, this)) + const zeus::CVector3f ballPos = GetBallPosition(); + if (mgr.RayCollideWorld(ballPos, ballPos + zeus::CVector3f(0.f, 0.f, -7.f), BallTransitionCollide, this)) { x584_ballTransitionAnim = 7; // B_balljumptoairpose + } } if (x64_modelData && x64_modelData->HasAnimData()) { - CAnimPlaybackParms parms(x584_ballTransitionAnim, -1, 1.f, true); + const CAnimPlaybackParms parms(x584_ballTransitionAnim, -1, 1.f, true); x64_modelData->GetAnimationData()->SetAnimation(parms, false); x64_modelData->GetAnimationData()->SetAnimDir(CAnimData::EAnimDir::Forward); } @@ -374,6 +387,7 @@ void CPlayer::TransitionFromMorphBallState(CStateManager& mgr) { SetMorphBallState(EPlayerMorphBallState::Unmorphing, mgr); x768_morphball->LeaveMorphBallState(mgr); mgr.GetCameraManager()->SetPlayerCamera(mgr, mgr.GetCameraManager()->GetFirstPersonCamera()->GetUniqueId()); + zeus::CVector3f camToPlayer = GetTranslation() - mgr.GetCameraManager()->GetBallCamera()->GetTranslation(); if (camToPlayer.canBeNormalized()) { camToPlayer.normalize(); @@ -381,23 +395,26 @@ void CPlayer::TransitionFromMorphBallState(CStateManager& mgr) { vecFlat.z() = 0.f; zeus::CVector3f f31 = vecFlat.canBeNormalized() && vecFlat.magnitude() >= 0.1f ? x518_leaveMorphDir : camToPlayer; if (x9c6_26_outOfBallLookAtHint) { - if (TCastToConstPtr hint = mgr.GetObjectById(x830_playerHint)) { + if (const TCastToConstPtr hint = mgr.GetObjectById(x830_playerHint)) { zeus::CVector3f deltaFlat = hint->GetTranslation() - GetTranslation(); deltaFlat.z() = 0.f; - if (deltaFlat.canBeNormalized()) + if (deltaFlat.canBeNormalized()) { f31 = deltaFlat.normalized(); - } - } - if (x9c7_25_outOfBallLookAtHintActor) { - if (TCastToConstPtr hint = mgr.GetObjectById(x830_playerHint)) { - if (TCastToConstPtr act = mgr.GetObjectById(hint->GetActorId())) { - zeus::CVector3f deltaFlat = act->GetOrbitPosition(mgr) - GetTranslation(); - deltaFlat.z() = 0.f; - if (deltaFlat.canBeNormalized()) - f31 = deltaFlat.normalized(); } } } + if (x9c7_25_outOfBallLookAtHintActor) { + if (const TCastToConstPtr hint = mgr.GetObjectById(x830_playerHint)) { + if (const TCastToConstPtr act = mgr.GetObjectById(hint->GetActorId())) { + zeus::CVector3f deltaFlat = act->GetOrbitPosition(mgr) - GetTranslation(); + deltaFlat.z() = 0.f; + if (deltaFlat.canBeNormalized()) { + f31 = deltaFlat.normalized(); + } + } + } + } + if (std::acos(zeus::clamp(-1.f, camToPlayer.dot(f31), 1.f)) < M_PIF / 1.2f || x9c7_25_outOfBallLookAtHintActor) { SetTransform(zeus::lookAt(GetTranslation(), GetTranslation() + f31)); } else { @@ -409,7 +426,7 @@ void CPlayer::TransitionFromMorphBallState(CStateManager& mgr) { } CBallCamera* ballCam = mgr.GetCameraManager()->GetBallCamera(); - if (TCastToConstPtr act = mgr.GetObjectById(ballCam->GetTooCloseActorId())) { + if (const TCastToConstPtr act = mgr.GetObjectById(ballCam->GetTooCloseActorId())) { if (ballCam->GetTooCloseActorDistance() < 20.f && ballCam->GetTooCloseActorDistance() > 1.f) { zeus::CVector3f deltaFlat = act->GetTranslation() - GetTranslation(); deltaFlat.z() = 0.f; @@ -447,17 +464,25 @@ void CPlayer::TransitionFromMorphBallState(CStateManager& mgr) { s32 CPlayer::GetNextBallTransitionAnim(float dt, bool& loopOut, CStateManager& mgr) { loopOut = false; - zeus::CVector2f vel(x138_velocity.x(), x138_velocity.y()); - if (!vel.canBeNormalized()) + + const zeus::CVector2f vel(x138_velocity.x(), x138_velocity.y()); + if (!vel.canBeNormalized()) { return 12; // B_ball_ready_samus - float velMag = vel.magnitude(); - float maxVel = GetActualFirstPersonMaxVelocity(dt); - if (velMag <= 0.2f * maxVel) + } + + const float velMag = vel.magnitude(); + const float maxVel = GetActualFirstPersonMaxVelocity(dt); + if (velMag <= 0.2f * maxVel) { return 12; // B_ball_ready_samus + } + loopOut = true; - s32 ret = velMag >= maxVel ? 13 : 15; // B_ball_runloop_samus : B_ball_walkloop_samus - if (x50c_moveDir.dot(mgr.GetCameraManager()->GetBallCamera()->GetTransform().basis[1]) < -0.5f) + + const s32 ret = velMag >= maxVel ? 13 : 15; // B_ball_runloop_samus : B_ball_walkloop_samus + if (x50c_moveDir.dot(mgr.GetCameraManager()->GetBallCamera()->GetTransform().basis[1]) < -0.5f) { return 12; // B_ball_ready_samus + } + return ret; } @@ -466,8 +491,10 @@ void CPlayer::UpdateMorphBallTransition(float dt, CStateManager& mgr) { case EPlayerMorphBallState::Unmorphed: case EPlayerMorphBallState::Morphed: { CPlayerState::EPlayerSuit suit = mgr.GetPlayerState()->GetCurrentSuitRaw(); - if (mgr.GetPlayerState()->IsFusionEnabled()) + if (mgr.GetPlayerState()->IsFusionEnabled()) { suit = CPlayerState::EPlayerSuit(int(suit) + 4); + } + if (x7cc_transitionSuit != suit) { x7cc_transitionSuit = suit; CAnimRes useRes = x7d0_animRes; @@ -480,13 +507,13 @@ void CPlayer::UpdateMorphBallTransition(float dt, CStateManager& mgr) { case EPlayerMorphBallState::Unmorphing: if (x584_ballTransitionAnim == 14) // B_ball_unfurl { - float dur = x64_modelData->GetAnimationData()->GetAnimationDuration(x584_ballTransitionAnim); - float facRemaining = x64_modelData->GetAnimationData()->GetAnimTimeRemaining("Whole Body") / dur; + const float dur = x64_modelData->GetAnimationData()->GetAnimationDuration(x584_ballTransitionAnim); + const float facRemaining = x64_modelData->GetAnimationData()->GetAnimTimeRemaining("Whole Body") / dur; if (facRemaining < 0.5f) { bool loop = false; x584_ballTransitionAnim = GetNextBallTransitionAnim(dt, loop, mgr); if (x64_modelData && x64_modelData->HasAnimData()) { - CAnimPlaybackParms parms(x584_ballTransitionAnim, -1, 1.f, true); + const CAnimPlaybackParms parms(x584_ballTransitionAnim, -1, 1.f, true); x64_modelData->GetAnimationData()->SetAnimation(parms, false); x64_modelData->GetAnimationData()->EnableLooping(loop); } @@ -494,14 +521,14 @@ void CPlayer::UpdateMorphBallTransition(float dt, CStateManager& mgr) { } else if (x584_ballTransitionAnim != 5 && x584_ballTransitionAnim != 7) // ballstationarytoready_random, B_balljumptoairpose { - float velMag = zeus::CVector2f(x138_velocity.x(), x138_velocity.y()).magnitude(); + const float velMag = zeus::CVector2f(x138_velocity.x(), x138_velocity.y()).magnitude(); if (std::fabs(x58c_transitionVel - velMag) > 0.04f * GetActualFirstPersonMaxVelocity(dt) || velMag < 1.f) { bool loop = false; - s32 nextAnim = GetNextBallTransitionAnim(dt, loop, mgr); + const s32 nextAnim = GetNextBallTransitionAnim(dt, loop, mgr); if (x64_modelData && x64_modelData->HasAnimData() && x584_ballTransitionAnim != nextAnim && x584_ballTransitionAnim != 7) { x584_ballTransitionAnim = nextAnim; - CAnimPlaybackParms parms(x584_ballTransitionAnim, -1, 1.f, true); + const CAnimPlaybackParms parms(x584_ballTransitionAnim, -1, 1.f, true); x64_modelData->GetAnimationData()->SetAnimation(parms, false); x64_modelData->GetAnimationData()->EnableLooping(loop); x58c_transitionVel = velMag; @@ -513,28 +540,31 @@ void CPlayer::UpdateMorphBallTransition(float dt, CStateManager& mgr) { break; } - SAdvancementDeltas deltas = UpdateAnimation(dt, mgr, true); + const SAdvancementDeltas deltas = UpdateAnimation(dt, mgr, true); MoveInOneFrameOR(deltas.x0_posDelta, dt); RotateInOneFrameOR(deltas.xc_rotDelta, dt); x574_morphTime = std::min(x574_morphTime + dt, x578_morphDuration); - float morphT = x574_morphTime / x578_morphDuration; - if ((morphT >= 0.7f || x574_morphTime <= 2.f * dt) && x730_transitionModels.size() != 0) + const float morphT = x574_morphTime / x578_morphDuration; + if ((morphT >= 0.7f || x574_morphTime <= 2.f * dt) && x730_transitionModels.size() != 0) { x730_transitionModels.erase(x730_transitionModels.begin()); + } - for (auto& m : x730_transitionModels) + for (auto& m : x730_transitionModels) { m->AdvanceAnimation(dt, mgr, kInvalidAreaId, true); + } - CGameCamera* cam = mgr.GetCameraManager()->GetCurrentCamera(mgr); + const CGameCamera* cam = mgr.GetCameraManager()->GetCurrentCamera(mgr); x588_alpha = GetTransitionAlpha(cam->GetTranslation(), cam->GetNearClipDistance()); if (x2f8_morphBallState == EPlayerMorphBallState::Morphing && morphT > 0.93f) { x588_alpha *= std::min(1.f, 1.f - (morphT - 0.93f) / 0.07f + 0.2f); xb4_drawFlags = CModelFlags(5, 0, 1, zeus::CColor(1.f, x588_alpha)); } else if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphing && x588_alpha < 1.f) { - if (x588_alpha > 0.05f) + if (x588_alpha > 0.05f) { xb4_drawFlags = CModelFlags(5, 0, 0x21, zeus::CColor(1.f, x588_alpha)); - else + } else { xb4_drawFlags = CModelFlags(5, 0, 1, zeus::CColor(1.f, x588_alpha)); + } } else { xb4_drawFlags = CModelFlags(5, 0, 3, zeus::CColor(1.f, x588_alpha)); } @@ -577,8 +607,9 @@ void CPlayer::UpdateMorphBallTransition(float dt, CStateManager& mgr) { } if (x578_morphDuration != 0.f) { if (zeus::clamp(0.f, x574_morphTime, 1.f) >= 0.5f) { - if (!x768_morphball->IsMorphBallTransitionFlashValid()) + if (!x768_morphball->IsMorphBallTransitionFlashValid()) { x768_morphball->ResetMorphBallTransitionFlash(); + } } } break; @@ -605,13 +636,17 @@ void CPlayer::UpdateGunAlpha() { } void CPlayer::UpdatePlayerSounds(float dt) { - if (x784_damageSfxTimer > 0.f) { - x784_damageSfxTimer -= dt; - if (x784_damageSfxTimer <= 0.f) { - CSfxManager::SfxStop(x770_damageLoopSfx); - x770_damageLoopSfx.reset(); - } + if (x784_damageSfxTimer <= 0.f) { + return; } + + x784_damageSfxTimer -= dt; + if (x784_damageSfxTimer > 0.f) { + return; + } + + CSfxManager::SfxStop(x770_damageLoopSfx); + x770_damageLoopSfx.reset(); } void CPlayer::Update(float dt, CStateManager& mgr) { @@ -635,11 +670,12 @@ void CPlayer::Update(float dt, CStateManager& mgr) { } } - float prevDeathTime = x9f4_deathTime; + const float prevDeathTime = x9f4_deathTime; x9f4_deathTime += dt; if (x2f8_morphBallState != EPlayerMorphBallState::Unmorphed) { - if (x9f4_deathTime >= 1.f && prevDeathTime < 1.f) + if (x9f4_deathTime >= 1.f && prevDeathTime < 1.f) { xa00_deathPowerBomb = x490_gun->DropPowerBomb(mgr); + } if (x9f4_deathTime >= 4.f && prevDeathTime < 4.f) { CSfxHandle hnd = CSfxManager::SfxStart(SFXsam_death, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); ApplySubmergedPitchBend(hnd); @@ -663,38 +699,44 @@ void CPlayer::Update(float dt, CStateManager& mgr) { UpdateOrbitModeTimer(dt); } UpdateOrbitPreventionTimer(dt); - if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) + if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) { x768_morphball->Update(dt, mgr); - else + } else { x768_morphball->StopSounds(); + } if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphing || - x2f8_morphBallState == EPlayerMorphBallState::Morphing) + x2f8_morphBallState == EPlayerMorphBallState::Morphing) { x768_morphball->UpdateEffects(dt, mgr); + } UpdateGunAlpha(); UpdateDebugCamera(mgr); UpdateVisorTransition(dt, mgr); mgr.SetActorAreaId(*this, mgr.GetWorld()->GetCurrentAreaId()); UpdatePlayerSounds(dt); - if (x26c_attachedActor != kInvalidUniqueId) + if (x26c_attachedActor != kInvalidUniqueId) { x270_attachedActorTime += dt; + } x740_staticTimer = std::max(0.f, x740_staticTimer - dt); - if (x740_staticTimer > 0.f) + if (x740_staticTimer > 0.f) { x74c_visorStaticAlpha = std::max(0.f, x74c_visorStaticAlpha - x744_staticOutSpeed * dt); - else + } else { x74c_visorStaticAlpha = std::min(1.f, x74c_visorStaticAlpha + x748_staticInSpeed * dt); + } x274_energyDrain.ProcessEnergyDrain(mgr, dt); x4a4_moveSpeedAvg.AddValue(x4f8_moveSpeed); mgr.GetPlayerState()->UpdateStaticInterference(mgr, dt); - if (!ShouldSampleFailsafe(mgr)) + if (!ShouldSampleFailsafe(mgr)) { CPhysicsActor::Stop(); + } - if (IsEnergyLow(mgr)) + if (IsEnergyLow(mgr)) { xa30_samusExhaustedVoiceTimer -= dt; - else + } else { xa30_samusExhaustedVoiceTimer = 4.f; + } if (!mgr.GetCameraManager()->IsInCinematicCamera() && xa30_samusExhaustedVoiceTimer <= 0.f) { StartSamusVoiceSfx(SFXsam_vox_exhausted, 1.f, 7); @@ -705,7 +747,7 @@ void CPlayer::Update(float dt, CStateManager& mgr) { float CPlayer::UpdateCameraBob(float dt, CStateManager& mgr) { float bobMag = 0.f; CPlayerCameraBob::ECameraBobState state; - zeus::CVector3f backupVel = x138_velocity; + const zeus::CVector3f backupVel = x138_velocity; if (x304_orbitState == EPlayerOrbitState::NoOrbit) { bobMag = std::fabs(backupVel.dot(x34_transform.basis[1]) / GetActualFirstPersonMaxVelocity(dt)); state = CPlayerCameraBob::ECameraBobState::Walk; @@ -723,8 +765,9 @@ float CPlayer::UpdateCameraBob(float dt, CStateManager& mgr) { bobMag = std::min(std::sqrt(f30 * f30 + f29 * f29) / std::sqrt(strafeDist * strafeDist + maxVel * maxVel) * CPlayerCameraBob::GetOrbitBobScale(), CPlayerCameraBob::GetMaxOrbitBobScale()); - if (bobMag < 0.01f) + if (bobMag < 0.01f) { bobMag = 0.f; + } } if (x258_movementState != EPlayerMovementState::OnGround) { @@ -757,12 +800,14 @@ float CPlayer::UpdateCameraBob(float dt, CStateManager& mgr) { if (x38c_doneSidewaysDashing) { bobMag *= 0.1f; state = CPlayerCameraBob::ECameraBobState::FreeLookNoBob; - if (x258_movementState == EPlayerMovementState::OnGround) + if (x258_movementState == EPlayerMovementState::OnGround) { x38c_doneSidewaysDashing = false; + } } - if (mgr.GetCameraManager()->IsInCinematicCamera()) + if (mgr.GetCameraManager()->IsInCinematicCamera()) { bobMag = 0.f; + } bobMag *= mgr.GetCameraManager()->GetCameraBobMagnitude(); @@ -777,8 +822,9 @@ float CPlayer::UpdateCameraBob(float dt, CStateManager& mgr) { } float CPlayer::GetAcceleration() const { - if (x2d0_curAcceleration >= x2b4_accelerationTable.size()) + if (x2d0_curAcceleration >= x2b4_accelerationTable.size()) { return x2b4_accelerationTable.back(); + } return x2b4_accelerationTable[x2d0_curAcceleration]; } @@ -791,10 +837,11 @@ void CPlayer::PostUpdate(float dt, CStateManager& mgr) { UpdateArmAndGunTransforms(dt, mgr); float grappleSwingT; - if (x3b8_grappleState != EGrappleState::Swinging) + if (x3b8_grappleState != EGrappleState::Swinging) { grappleSwingT = 0.f; - else + } else { grappleSwingT = x3bc_grappleSwingTimer / g_tweakPlayer->GetGrappleSwingPeriod(); + } float cameraBobT = 0.f; if (mgr.GetCameraManager()->IsInCinematicCamera()) { @@ -811,8 +858,10 @@ void CPlayer::PostUpdate(float dt, CStateManager& mgr) { } bool CPlayer::StartSamusVoiceSfx(u16 sfx, float vol, int prio) { - if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) + if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) { return false; + } + bool started = true; if (x77c_samusVoiceSfx) { if (CSfxManager::IsPlaying(x77c_samusVoiceSfx)) { @@ -822,19 +871,24 @@ bool CPlayer::StartSamusVoiceSfx(u16 sfx, float vol, int prio) { started = true; } } + if (started) { x77c_samusVoiceSfx = CSfxManager::SfxStart(sfx, vol, 0.f, false, 0x7f, false, kInvalidAreaId); x780_samusVoicePriority = prio; } } + return started; } bool CPlayer::IsPlayerDeadEnough() const { - if (x2f8_morphBallState == CPlayer::EPlayerMorphBallState::Unmorphed) + if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphed) { return x9f4_deathTime > 2.5f; - if (x2f8_morphBallState == CPlayer::EPlayerMorphBallState::Morphed) + } + + if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) { return x9f4_deathTime > 6.f; + } return false; } @@ -846,8 +900,9 @@ void CPlayer::LoadAnimationTokens() { CDependencyGroup& group = *transGroup; x25c_ballTransitionsRes.reserve(group.GetObjectTagVector().size()); for (const SObjectTag& tag : group.GetObjectTagVector()) { - if (tag.type == FOURCC('CMDL') || tag.type == FOURCC('CSKR') || tag.type == FOURCC('TXTR')) + if (tag.type == FOURCC('CMDL') || tag.type == FOURCC('CSKR') || tag.type == FOURCC('TXTR')) { continue; + } x25c_ballTransitionsRes.push_back(g_SimplePool->GetObj(tag)); } } @@ -860,8 +915,9 @@ bool CPlayer::CanRenderUnsorted(const CStateManager& mgr) const { return false; const CDamageVulnerability* CPlayer::GetDamageVulnerability(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const CDamageInfo& info) const { - if (x2f8_morphBallState == EPlayerMorphBallState::Morphed && x570_immuneTimer > 0.f && !info.NoImmunity()) + if (x2f8_morphBallState == EPlayerMorphBallState::Morphed && x570_immuneTimer > 0.f && !info.NoImmunity()) { return &CDamageVulnerability::ImmuneVulnerabilty(); + } return &CDamageVulnerability::NormalVulnerabilty(); } @@ -871,24 +927,27 @@ const CDamageVulnerability* CPlayer::GetDamageVulnerability() const { } zeus::CVector3f CPlayer::GetHomingPosition(const CStateManager& mgr, float dt) const { - if (dt > 0.f) + if (dt > 0.f) { return x34_transform.origin + PredictMotion(dt).x0_translation; + } return x34_transform.origin; } zeus::CVector3f CPlayer::GetAimPosition(const CStateManager& mgr, float dt) const { zeus::CVector3f ret = x34_transform.origin; if (dt > 0.f) { - if (x304_orbitState == EPlayerOrbitState::NoOrbit) + if (x304_orbitState == EPlayerOrbitState::NoOrbit) { ret += PredictMotion(dt).x0_translation; - else + } else { ret = CSteeringBehaviors::ProjectOrbitalPosition(ret, x138_velocity, x314_orbitPoint, dt, xa04_preThinkDt); + } } - if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) + if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) { ret.z() += g_tweakPlayer->GetPlayerBallHalfExtent(); - else + } else { ret.z() += GetEyeHeight(); + } return ret; } @@ -896,8 +955,9 @@ zeus::CVector3f CPlayer::GetAimPosition(const CStateManager& mgr, float dt) cons void CPlayer::FluidFXThink(EFluidState state, CScriptWater& water, CStateManager& mgr) { if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) { x768_morphball->FluidFXThink(state, water, mgr); - if (state == EFluidState::InFluid) + if (state == EFluidState::InFluid) { x9c5_30_selectFluidBallSound = true; + } } else if (x2f8_morphBallState != EPlayerMorphBallState::Unmorphed) { if (mgr.GetFluidPlaneManager()->GetLastSplashDeltaTime(x8_uid) >= 0.2f) { zeus::CVector3f position(x34_transform.origin); @@ -907,24 +967,26 @@ void CPlayer::FluidFXThink(EFluidState state, CScriptWater& water, CStateManager } else { if (mgr.GetFluidPlaneManager()->GetLastSplashDeltaTime(x8_uid) >= 0.2f) { zeus::CVector3f posOffset = x50c_moveDir; - if (posOffset.canBeNormalized()) + if (posOffset.canBeNormalized()) { posOffset = posOffset.normalized() * zeus::CVector3f(1.2f, 1.2f, 0.f); + } switch (state) { case EFluidState::EnteredFluid: { bool doSplash = true; if (x4fc_flatMoveSpeed > 12.5f) { - zeus::CVector3f lookDir = x34_transform.basis[1].normalized(); + const zeus::CVector3f lookDir = x34_transform.basis[1].normalized(); zeus::CVector3f dcVel = GetDampedClampedVelocityWR(); dcVel.z() = 0.f; - if (lookDir.dot(dcVel.normalized()) > 0.75f) + if (lookDir.dot(dcVel.normalized()) > 0.75f) { doSplash = false; + } } if (doSplash) { zeus::CVector3f position = x34_transform.origin + posOffset; position.z() = float(water.GetTriggerBoundsWR().max.z()); mgr.GetFluidPlaneManager()->CreateSplash(x8_uid, mgr, water, position, 0.3f, true); if (water.GetFluidPlane().GetFluidType() == EFluidType::NormalWater) { - float velMag = mgr.GetPlayer().GetVelocity().magnitude() / 10.f; + const float velMag = mgr.GetPlayer().GetVelocity().magnitude() / 10.f; mgr.GetEnvFxManager()->SetSplashRate(10.f * std::max(1.f, velMag)); } } @@ -953,8 +1015,10 @@ void CPlayer::FluidFXThink(EFluidState state, CScriptWater& water, CStateManager void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location, float dam, EWeaponType type, CStateManager& mgr) { - if (!significant) + if (!significant) { return; + } + if (dam >= 0.f) { x570_immuneTimer = 0.5f; x55c_damageAmt = dam; @@ -963,7 +1027,9 @@ void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location, floa x558_wasDamaged = true; bool doRumble = false; - u16 suitDamageSfx = 0, damageLoopSfx = 0, damageSamusVoiceSfx = 0; + u16 suitDamageSfx = 0; + u16 damageLoopSfx = 0; + u16 damageSamusVoiceSfx = 0; switch (type) { case EWeaponType::Phazon: @@ -983,41 +1049,44 @@ void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location, floa break; default: if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphed) { - if (dam > 30.f) + if (dam > 30.f) { damageSamusVoiceSfx = SFXsam_vox_damage30; - else if (dam > 15.f) + } else if (dam > 15.f) { damageSamusVoiceSfx = SFXsam_vox_damage15; - else + } else { damageSamusVoiceSfx = SFXsam_vox_damage; + } suitDamageSfx = SFXsam_suit_damage; } else { - if (dam > 30.f) + if (dam > 30.f) { suitDamageSfx = SFXsam_ball_damage30; - else if (dam > 15.f) + } else if (dam > 15.f) { suitDamageSfx = SFXsam_ball_damage15; - else + } else { suitDamageSfx = SFXsam_ball_damage; + } } break; } - if (damageSamusVoiceSfx && x774_samusVoiceTimeout <= 0.f) { + if (damageSamusVoiceSfx != 0 && x774_samusVoiceTimeout <= 0.f) { StartSamusVoiceSfx(damageSamusVoiceSfx, 1.f, 8); x774_samusVoiceTimeout = mgr.GetActiveRandom()->Range(3.f, 4.f); doRumble = true; } - if (damageLoopSfx && !x9c7_24_noDamageLoopSfx && xa2c_damageLoopSfxDelayTicks >= 2) { + if (damageLoopSfx != 0 && !x9c7_24_noDamageLoopSfx && xa2c_damageLoopSfxDelayTicks >= 2) { if (!x770_damageLoopSfx || x788_damageLoopSfxId != damageLoopSfx) { - if (x770_damageLoopSfx && x788_damageLoopSfxId != damageLoopSfx) + if (x770_damageLoopSfx && x788_damageLoopSfxId != damageLoopSfx) { CSfxManager::SfxStop(x770_damageLoopSfx); + } x770_damageLoopSfx = CSfxManager::SfxStart(damageLoopSfx, 1.f, 0.f, false, 0x7f, true, kInvalidAreaId); x788_damageLoopSfxId = damageLoopSfx; } x784_damageSfxTimer = 0.5f; } - if (suitDamageSfx) { + if (suitDamageSfx != 0) { if (x770_damageLoopSfx) { CSfxManager::SfxStop(x770_damageLoopSfx); x770_damageLoopSfx.reset(); @@ -1029,11 +1098,15 @@ void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location, floa } if (doRumble) { - if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphed) + if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphed) { x490_gun->DamageRumble(location, dam, mgr); + } + float tmp = x55c_damageAmt / 25.f; - if (std::fabs(tmp) > 1.f) + if (std::fabs(tmp) > 1.f) { tmp = tmp > 0.f ? 1.f : -1.f; + } + mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerBump, tmp, ERumblePriority::One); } @@ -1043,42 +1116,49 @@ void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location, floa } } - if (x3b8_grappleState != EGrappleState::None) + if (x3b8_grappleState != EGrappleState::None) { BreakGrapple(EPlayerOrbitRequest::DamageOnGrapple, mgr); + } } void CPlayer::Accept(IVisitor& visitor) { visitor.Visit(this); } -CHealthInfo* CPlayer::HealthInfo(CStateManager& mgr) { return &mgr.GetPlayerState()->HealthInfo(); } +CHealthInfo* CPlayer::HealthInfo(CStateManager& mgr) { return &mgr.GetPlayerState()->GetHealthInfo(); } bool CPlayer::IsUnderBetaMetroidAttack(const CStateManager& mgr) const { if (x274_energyDrain.GetEnergyDrainIntensity() > 0.f) { - for (const CEnergyDrainSource& source : x274_energyDrain.GetEnergyDrainSources()) - if (CPatterned::CastTo(mgr.GetObjectById(source.GetEnergyDrainSourceId()))) + for (const CEnergyDrainSource& source : x274_energyDrain.GetEnergyDrainSources()) { + if (CPatterned::CastTo(mgr.GetObjectById(source.GetEnergyDrainSourceId()))) { return true; + } + } } + return false; } std::optional CPlayer::GetTouchBounds() const { - if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) { - float ballTouchRad = x768_morphball->GetBallTouchRadius(); - zeus::CVector3f ballCenter = GetTranslation() + zeus::CVector3f(0.f, 0.f, x768_morphball->GetBallRadius()); - return zeus::CAABox(ballCenter - ballTouchRad, ballCenter + ballTouchRad); + if (x2f8_morphBallState != EPlayerMorphBallState::Morphed) { + return GetBoundingBox(); } - return GetBoundingBox(); + + const float ballTouchRad = x768_morphball->GetBallTouchRadius(); + const zeus::CVector3f ballCenter = GetTranslation() + zeus::CVector3f(0.f, 0.f, x768_morphball->GetBallRadius()); + return zeus::CAABox(ballCenter - ballTouchRad, ballCenter + ballTouchRad); } void CPlayer::DoPreThink(float dt, CStateManager& mgr) { PreThink(dt, mgr); - if (CEntity* ent = mgr.ObjectById(xa00_deathPowerBomb)) + if (CEntity* ent = mgr.ObjectById(xa00_deathPowerBomb)) { ent->PreThink(dt, mgr); + } } void CPlayer::DoThink(float dt, CStateManager& mgr) { Think(dt, mgr); - if (CEntity* ent = mgr.ObjectById(xa00_deathPowerBomb)) + if (CEntity* ent = mgr.ObjectById(xa00_deathPowerBomb)) { ent->Think(dt, mgr); + } } void CPlayer::UpdateScanningState(const CFinalInput& input, CStateManager& mgr, float dt) { @@ -1088,13 +1168,14 @@ void CPlayer::UpdateScanningState(const CFinalInput& input, CStateManager& mgr, } if (x3a8_scanState != EPlayerScanState::NotScanning && x3b4_scanningObject != x310_orbitTargetId && - x310_orbitTargetId != kInvalidUniqueId) + x310_orbitTargetId != kInvalidUniqueId) { SetScanningState(EPlayerScanState::NotScanning, mgr); + } switch (x3a8_scanState) { case EPlayerScanState::NotScanning: if (ValidateScanning(input, mgr)) { - if (TCastToPtr act = mgr.ObjectById(x310_orbitTargetId)) { + if (const TCastToConstPtr act = mgr.ObjectById(x310_orbitTargetId)) { const CScannableObjectInfo* scanInfo = act->GetScannableObjectInfo(); float scanTime = mgr.GetPlayerState()->GetScanTime(scanInfo->GetScannableObjectId()); if (scanTime >= 1.f) { @@ -1112,15 +1193,16 @@ void CPlayer::UpdateScanningState(const CFinalInput& input, CStateManager& mgr, break; case EPlayerScanState::Scanning: if (ValidateScanning(input, mgr)) { - if (TCastToPtr act = mgr.ObjectById(x310_orbitTargetId)) { + if (const TCastToConstPtr act = mgr.ObjectById(x310_orbitTargetId)) { if (const CScannableObjectInfo* scanInfo = act->GetScannableObjectInfo()) { x3ac_scanningTime = std::min(scanInfo->GetTotalDownloadTime(), x3ac_scanningTime + dt); x3b0_curScanTime += dt; mgr.GetPlayerState()->SetScanTime(scanInfo->GetScannableObjectId(), x3ac_scanningTime / scanInfo->GetTotalDownloadTime()); if (x3ac_scanningTime >= scanInfo->GetTotalDownloadTime() && - x3b0_curScanTime >= g_tweakGui->GetScanSidesStartTime()) + x3b0_curScanTime >= g_tweakGui->GetScanSidesStartTime()) { SetScanningState(EPlayerScanState::ScanComplete, mgr); + } } } else { SetScanningState(EPlayerScanState::NotScanning, mgr); @@ -1130,8 +1212,9 @@ void CPlayer::UpdateScanningState(const CFinalInput& input, CStateManager& mgr, } break; case EPlayerScanState::ScanComplete: - if (!ValidateScanning(input, mgr)) + if (!ValidateScanning(input, mgr)) { SetScanningState(EPlayerScanState::NotScanning, mgr); + } break; } } @@ -1139,11 +1222,12 @@ void CPlayer::UpdateScanningState(const CFinalInput& input, CStateManager& mgr, bool CPlayer::ValidateScanning(const CFinalInput& input, const CStateManager& mgr) const { if (ControlMapper::GetDigitalInput(ControlMapper::ECommands::ScanItem, input)) { if (x304_orbitState == EPlayerOrbitState::OrbitObject) { - if (TCastToPtr act = mgr.ObjectById(x310_orbitTargetId)) { + if (const TCastToConstPtr act = mgr.ObjectById(x310_orbitTargetId)) { if (act->GetMaterialList().HasMaterial(EMaterialTypes::Scannable)) { - zeus::CVector3f targetToPlayer = GetTranslation() - act->GetTranslation(); - if (targetToPlayer.canBeNormalized() && targetToPlayer.magnitude() < g_tweakPlayer->GetScanningRange()) + const zeus::CVector3f targetToPlayer = GetTranslation() - act->GetTranslation(); + if (targetToPlayer.canBeNormalized() && targetToPlayer.magnitude() < g_tweakPlayer->GetScanningRange()) { return true; + } } } } @@ -1153,9 +1237,11 @@ bool CPlayer::ValidateScanning(const CFinalInput& input, const CStateManager& mg } static bool IsDataLoreResearchScan(CAssetId id) { - auto it = g_MemoryCardSys->LookupScanState(id); - if (it == g_MemoryCardSys->GetScanStates().cend()) + const auto it = g_MemoryCardSys->LookupScanState(id); + if (it == g_MemoryCardSys->GetScanStates().cend()) { return false; + } + switch (it->second) { case CSaveWorld::EScanCategory::Data: case CSaveWorld::EScanCategory::Lore: @@ -1195,50 +1281,79 @@ static CAssetId UpdatePersistentScanPercent(u32 prevLogScans, u32 logScans, u32 } void CPlayer::FinishNewScan(CStateManager& mgr) { - if (TCastToPtr act = mgr.ObjectById(x310_orbitTargetId)) - if (act->GetMaterialList().HasMaterial(EMaterialTypes::Scannable)) - if (auto scanInfo = act->GetScannableObjectInfo()) - if (mgr.GetPlayerState()->GetScanTime(scanInfo->GetScannableObjectId()) >= 1.f) - if (IsDataLoreResearchScan(scanInfo->GetScannableObjectId())) { - auto scanCompletion = mgr.CalculateScanCompletionRate(); - CAssetId message = UpdatePersistentScanPercent(mgr.GetPlayerState()->GetLogScans(), scanCompletion.first, - scanCompletion.second); - if (message.IsValid()) - mgr.ShowPausedHUDMemo(message, 0.f); - mgr.GetPlayerState()->SetScanCompletionRate(scanCompletion); - } + const TCastToConstPtr act = mgr.ObjectById(x310_orbitTargetId); + + if (!act) { + return; + } + + if (!act->GetMaterialList().HasMaterial(EMaterialTypes::Scannable)) { + return; + } + + const auto* const scanInfo = act->GetScannableObjectInfo(); + if (!scanInfo) { + return; + } + + if (mgr.GetPlayerState()->GetScanTime(scanInfo->GetScannableObjectId()) < 1.f) { + return; + } + + if (!IsDataLoreResearchScan(scanInfo->GetScannableObjectId())) { + return; + } + + const auto scanCompletion = mgr.CalculateScanCompletionRate(); + const CAssetId message = UpdatePersistentScanPercent(mgr.GetPlayerState()->GetLogScans(), scanCompletion.first, + scanCompletion.second); + if (message.IsValid()) { + mgr.ShowPausedHUDMemo(message, 0.f); + } + mgr.GetPlayerState()->SetScanCompletionRate(scanCompletion); } void CPlayer::SetScanningState(EPlayerScanState state, CStateManager& mgr) { - if (x3a8_scanState == state) + if (x3a8_scanState == state) { return; + } mgr.SetGameState(CStateManager::EGameState::Running); - if (x3a8_scanState == EPlayerScanState::ScanComplete) - if (TCastToPtr act = mgr.ObjectById(x3b4_scanningObject)) + if (x3a8_scanState == EPlayerScanState::ScanComplete) { + if (TCastToPtr act = mgr.ObjectById(x3b4_scanningObject)) { act->OnScanStateChanged(EScanState::Done, mgr); + } + } switch (state) { case EPlayerScanState::NotScanning: - if (x3a8_scanState == EPlayerScanState::Scanning || x3a8_scanState == EPlayerScanState::ScanComplete) - if (x9c6_30_newScanScanning) + if (x3a8_scanState == EPlayerScanState::Scanning || x3a8_scanState == EPlayerScanState::ScanComplete) { + if (x9c6_30_newScanScanning) { FinishNewScan(mgr); + } + } x3ac_scanningTime = 0.f; x3b0_curScanTime = 0.f; - if (!g_tweakPlayer->GetScanRetention()) - if (TCastToPtr act = mgr.ObjectById(x310_orbitTargetId)) - if (act->GetMaterialList().HasMaterial(EMaterialTypes::Scannable)) - if (auto scanInfo = act->GetScannableObjectInfo()) - if (mgr.GetPlayerState()->GetScanTime(scanInfo->GetScannableObjectId()) < 1.f) + if (!g_tweakPlayer->GetScanRetention()) { + if (const TCastToConstPtr act = mgr.ObjectById(x310_orbitTargetId)) { + if (act->GetMaterialList().HasMaterial(EMaterialTypes::Scannable)) { + if (const auto* scanInfo = act->GetScannableObjectInfo()) { + if (mgr.GetPlayerState()->GetScanTime(scanInfo->GetScannableObjectId()) < 1.f) { mgr.GetPlayerState()->SetScanTime(scanInfo->GetScannableObjectId(), 0.f); + } + } + } + } + } x3b4_scanningObject = kInvalidUniqueId; break; case EPlayerScanState::Scanning: x3b4_scanningObject = x310_orbitTargetId; break; case EPlayerScanState::ScanComplete: - if (g_tweakPlayer->GetScanFreezesGame()) + if (g_tweakPlayer->GetScanFreezesGame()) { mgr.SetGameState(CStateManager::EGameState::SoftPaused); + } x3b4_scanningObject = x310_orbitTargetId; break; } @@ -1267,15 +1382,19 @@ bool CPlayer::GetCombatMode() const { } void CPlayer::RenderGun(const CStateManager& mgr, const zeus::CVector3f& pos) const { - if (mgr.GetCameraManager()->IsInCinematicCamera()) + if (mgr.GetCameraManager()->IsInCinematicCamera()) { return; + } - if (x490_gun->GetGrappleArm().GetActive() && x490_gun->GetGrappleArm().GetAnimState() != CGrappleArm::EArmState::Done) + if (x490_gun->GetGrappleArm().GetActive() && + x490_gun->GetGrappleArm().GetAnimState() != CGrappleArm::EArmState::Done) { x490_gun->GetGrappleArm().RenderGrappleBeam(mgr, pos); + } if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Scan && - mgr.GetPlayerState()->GetVisorTransitionFactor() >= 1.f) + mgr.GetPlayerState()->GetVisorTransitionFactor() >= 1.f) { return; + } if ((mgr.GetCameraManager()->IsInFirstPersonCamera() && x2f4_cameraState == EPlayerCameraState::FirstPerson) || (x2f8_morphBallState == EPlayerMorphBallState::Morphing && @@ -1287,11 +1406,14 @@ void CPlayer::RenderGun(const CStateManager& mgr, const zeus::CVector3f& pos) co } } -void CPlayer::Render(const CStateManager& mgr) const { +void CPlayer::Render(CStateManager& mgr) { bool doRender = x2f4_cameraState != EPlayerCameraState::Spawned; - if (!doRender) - if (TCastToConstPtr cam = mgr.GetCameraManager()->GetCurrentCamera(mgr)) + if (!doRender) { + if (TCastToConstPtr cam = mgr.GetCameraManager()->GetCurrentCamera(mgr)) { doRender = (x2f8_morphBallState == EPlayerMorphBallState::Morphed && cam->GetFlags() & 0x40); + } + } + if (x2f4_cameraState != EPlayerCameraState::FirstPerson && doRender) { SCOPED_GRAPHICS_DEBUG_GROUP("CPlayer::Render", zeus::skOrange); CBooModel::SetReflectionCube(m_reflectionCube); @@ -1335,19 +1457,20 @@ void CPlayer::Render(const CStateManager& mgr) const { float morphFactor = x574_morphTime / x578_morphDuration; float transitionAlpha; - if (morphFactor < 0.05f) + if (morphFactor < 0.05f) { transitionAlpha = 0.f; - else if (morphFactor < 0.1f) + } else if (morphFactor < 0.1f) { transitionAlpha = (morphFactor - 0.05f) / 0.05f; - else if (morphFactor < 0.8f) + } else if (morphFactor < 0.8f) { transitionAlpha = 1.f; - else + } else { transitionAlpha = 1.f - (morphFactor - 0.8f) / 0.2f; + } - auto mdsp1 = int(x730_transitionModels.size() + 1); + const auto mdsp1 = int(x730_transitionModels.size() + 1); for (int i = 0; i < x730_transitionModels.size(); ++i) { - int ni = i + 1; - float alpha = transitionAlpha * (1.f - (ni + 1) / float(mdsp1)) * *x71c_transitionModelAlphas.GetEntry(ni); + const int ni = i + 1; + const float alpha = transitionAlpha * (1.f - (ni + 1) / float(mdsp1)) * *x71c_transitionModelAlphas.GetEntry(ni); if (alpha != 0.f) { CModelData& data = *x730_transitionModels[i]; CModelFlags flags(5, 0, 3, zeus::CColor(1.f, alpha)); @@ -1355,10 +1478,10 @@ void CPlayer::Render(const CStateManager& mgr) const { data.Render(CModelData::GetRenderingModel(mgr), *x658_transitionModelXfs.GetEntry(ni), x90_actorLights.get(), flags); if (HasTransitionBeamModel()) { - CModelFlags flags(5, 0, 3, zeus::CColor(1.f, alpha)); - flags.m_extendedShader = EExtendedShader::LightingCubeReflection; + CModelFlags transFlags(5, 0, 3, zeus::CColor(1.f, alpha)); + transFlags.m_extendedShader = EExtendedShader::LightingCubeReflection; x7f0_ballTransitionBeamModel->Render(CModelData::EWhichModel::Normal, *x594_transisionBeamXfs.GetEntry(ni), - x90_actorLights.get(), flags); + x90_actorLights.get(), transFlags); } } } @@ -1387,16 +1510,17 @@ void CPlayer::Render(const CStateManager& mgr) const { float rotate = 1.f - tmp; float scale = 0.75f * rotate + 1.f; float ballAlpha; - if (tmp < 0.1f) + if (tmp < 0.1f) { ballAlpha = 0.f; - else if (tmp < 0.2f) + } else if (tmp < 0.2f) { ballAlpha = (tmp - 0.1f) / 0.1f; - else if (tmp < 0.9f) + } else if (tmp < 0.9f) { ballAlpha = 1.f; - else + } else { ballAlpha = 1.f - (morphFactor - 0.9f) / 0.1f; + } - float theta = zeus::degToRad(360.f * rotate); + const float theta = zeus::degToRad(360.f * rotate); ballAlpha *= 0.5f; if (ballAlpha > 0.f) { CModelFlags flags(7, 0, 3, zeus::CColor(1.f, ballAlpha)); @@ -1415,17 +1539,18 @@ void CPlayer::Render(const CStateManager& mgr) const { } void CPlayer::RenderReflectedPlayer(CStateManager& mgr) { - zeus::CFrustum frustum; switch (x2f8_morphBallState) { case EPlayerMorphBallState::Unmorphed: case EPlayerMorphBallState::Morphing: case EPlayerMorphBallState::Unmorphing: SetCalculateLighting(true); - if (x2f4_cameraState == EPlayerCameraState::FirstPerson) + if (x2f4_cameraState == EPlayerCameraState::FirstPerson) { + const zeus::CFrustum frustum; CActor::PreRender(mgr, frustum); + } CPhysicsActor::Render(mgr); if (HasTransitionBeamModel()) { - CModelFlags flags(0, 0, 3, zeus::skWhite); + const CModelFlags flags(0, 0, 3, zeus::skWhite); x7f0_ballTransitionBeamModel->Render(mgr, x7f4_gunWorldXf, nullptr, flags); } break; @@ -1453,16 +1578,18 @@ void CPlayer::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { x768_morphball->RenderToShadowTex(mgr); } - for (auto& model : x730_transitionModels) + for (auto& model : x730_transitionModels) { model->GetAnimationData()->PreRender(); + } - if (x2f4_cameraState != EPlayerCameraState::FirstPerson) + if (x2f4_cameraState != EPlayerCameraState::FirstPerson) { CActor::PreRender(mgr, frustum); + } } void CPlayer::CalculateRenderBounds() { if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) { - float rad = x768_morphball->GetBallRadius(); + const float rad = x768_morphball->GetBallRadius(); x9c_renderBounds = zeus::CAABox(GetTranslation() - zeus::CVector3f(rad, rad, 0.f), GetTranslation() + zeus::CVector3f(rad, rad, rad * 2.f)); } else { @@ -1470,12 +1597,13 @@ void CPlayer::CalculateRenderBounds() { } } -void CPlayer::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { +void CPlayer::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { if (x2f4_cameraState != EPlayerCameraState::FirstPerson && x2f8_morphBallState == EPlayerMorphBallState::Morphed) { - if (x768_morphball->IsInFrustum(frustum)) + if (x768_morphball->IsInFrustum(frustum)) { CActor::AddToRenderer(frustum, mgr); - else + } else { x768_morphball->TouchModel(mgr); + } } else { x490_gun->AddToRenderer(frustum, mgr); CActor::AddToRenderer(frustum, mgr); @@ -1483,8 +1611,8 @@ void CPlayer::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& } void CPlayer::ComputeFreeLook(const CFinalInput& input) { - float lookLeft = ControlMapper::GetAnalogInput(ControlMapper::ECommands::LookLeft, input); - float lookRight = ControlMapper::GetAnalogInput(ControlMapper::ECommands::LookRight, input); + const float lookLeft = ControlMapper::GetAnalogInput(ControlMapper::ECommands::LookLeft, input); + const float lookRight = ControlMapper::GetAnalogInput(ControlMapper::ECommands::LookRight, input); float lookUp = ControlMapper::GetAnalogInput(ControlMapper::ECommands::LookUp, input); float lookDown = ControlMapper::GetAnalogInput(ControlMapper::ECommands::LookDown, input); @@ -1547,7 +1675,7 @@ void CPlayer::UpdateFreeLookState(const CFinalInput& input, float dt, CStateMana (ControlMapper::GetDigitalInput(ControlMapper::ECommands::LookHold1, input) || ControlMapper::GetDigitalInput(ControlMapper::ECommands::LookHold2, input)))) { if (!x3dd_lookButtonHeld) { - zeus::CVector3f lookDir = mgr.GetCameraManager()->GetFirstPersonCamera()->GetTransform().basis[1]; + const zeus::CVector3f lookDir = mgr.GetCameraManager()->GetFirstPersonCamera()->GetTransform().basis[1]; zeus::CVector3f lookDirFlat = lookDir; lookDirFlat.z() = 0.f; x3e4_freeLookYawAngle = 0.f; @@ -1597,26 +1725,35 @@ void CPlayer::UpdateFreeLookState(const CFinalInput& input, float dt, CStateMana } void CPlayer::UpdateFreeLook(float dt) { - if (GetFrozenState()) + if (GetFrozenState()) { return; + } + float lookDeltaAngle = dt * g_tweakPlayer->GetFreeLookSpeed(); - if (!x3de_lookAnalogHeld) + if (!x3de_lookAnalogHeld) { lookDeltaAngle = dt * g_tweakPlayer->GetFreeLookSnapSpeed(); + } + float angleVelP = x3f0_vertFreeLookAngleVel - x3ec_freeLookPitchAngle; - float vertLookDamp = zeus::clamp(0.f, std::fabs(angleVelP / 1.0471976f), 1.f); + const float vertLookDamp = zeus::clamp(0.f, std::fabs(angleVelP / 1.0471976f), 1.f); float dx = lookDeltaAngle * (2.f * vertLookDamp - std::sin((M_PIF / 2.f) * vertLookDamp)); - if (0.f <= angleVelP) + if (0.f <= angleVelP) { x3ec_freeLookPitchAngle += dx; - else + } else { x3ec_freeLookPitchAngle -= dx; + } + angleVelP = x3e8_horizFreeLookAngleVel - x3e4_freeLookYawAngle; dx = lookDeltaAngle * zeus::clamp(0.f, std::fabs(angleVelP / g_tweakPlayer->GetHorizontalFreeLookAngleVel()), 1.f); - if (0.f <= angleVelP) + if (0.f <= angleVelP) { x3e4_freeLookYawAngle += dx; - else + } else { x3e4_freeLookYawAngle -= dx; - if (g_tweakPlayer->GetFreeLookTurnsPlayer()) + } + + if (g_tweakPlayer->GetFreeLookTurnsPlayer()) { x3e4_freeLookYawAngle = 0.f; + } } float CPlayer::GetMaximumPlayerPositiveVerticalVelocity(CStateManager& mgr) const { @@ -1638,7 +1775,7 @@ void CPlayer::ProcessFrozenInput(float dt, CStateManager& mgr) { if (x764_controlsFrozenTimeout <= 0.f) { EndLandingControlFreeze(); } else { - CFinalInput dummy; + const CFinalInput dummy; if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) { x768_morphball->ComputeBallMovement(dummy, mgr, dt); x768_morphball->UpdateBallDynamics(mgr, dt); @@ -1649,27 +1786,33 @@ void CPlayer::ProcessFrozenInput(float dt, CStateManager& mgr) { } void CPlayer::ProcessInput(const CFinalInput& input, CStateManager& mgr) { - if (input.ControllerIdx() != 0) + if (input.ControllerIdx() != 0) { return; + } - if (x2f8_morphBallState != EPlayerMorphBallState::Morphed) + if (x2f8_morphBallState != EPlayerMorphBallState::Morphed) { UpdateScanningState(input, mgr, input.DeltaTime()); + } - if (mgr.GetGameState() != CStateManager::EGameState::Running) + if (mgr.GetGameState() != CStateManager::EGameState::Running) { return; + } - if (!mgr.GetPlayerState()->IsPlayerAlive()) + if (!mgr.GetPlayerState()->IsPlayerAlive()) { return; + } - if (GetFrozenState()) + if (GetFrozenState()) { UpdateFrozenState(input, mgr); + } if (GetFrozenState()) { if (x258_movementState == EPlayerMovementState::OnGround || - x258_movementState == EPlayerMovementState::FallingMorphed) + x258_movementState == EPlayerMovementState::FallingMorphed) { return; + } - CFinalInput dummyInput; + const CFinalInput dummyInput; if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) { x768_morphball->ComputeBallMovement(dummyInput, mgr, input.DeltaTime()); x768_morphball->UpdateBallDynamics(mgr, input.DeltaTime()); @@ -1686,7 +1829,7 @@ void CPlayer::ProcessInput(const CFinalInput& input, CStateManager& mgr) { } if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphed && x4a0_failsafeTest->Passes()) { - auto* prim = static_cast(GetCollisionPrimitive()); + const auto* prim = static_cast(GetCollisionPrimitive()); const zeus::CAABox tmpAABB(prim->GetBox().min - 0.2f, prim->GetBox().max + 0.2f); const CCollidableAABox tmpBox(tmpAABB, prim->GetMaterial()); CPhysicsActor::Stop(); @@ -1707,10 +1850,11 @@ void CPlayer::ProcessInput(const CFinalInput& input, CStateManager& mgr) { UpdateGrappleState(input, mgr); if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) { float leftDiv = g_tweakBall->GetLeftStickDivisor(); - float rightDiv = g_tweakBall->GetRightStickDivisor(); - if (x26c_attachedActor != kInvalidUniqueId || IsUnderBetaMetroidAttack(mgr)) + const float rightDiv = g_tweakBall->GetRightStickDivisor(); + if (x26c_attachedActor != kInvalidUniqueId || IsUnderBetaMetroidAttack(mgr)) { leftDiv = 2.f; - CFinalInput scaledInput = input.ScaleAnalogueSticks(leftDiv, rightDiv); + } + const CFinalInput scaledInput = input.ScaleAnalogueSticks(leftDiv, rightDiv); x768_morphball->ComputeBallMovement(scaledInput, mgr, input.DeltaTime()); x768_morphball->UpdateBallDynamics(mgr, input.DeltaTime()); x4a0_failsafeTest->Reset(); @@ -1718,16 +1862,17 @@ void CPlayer::ProcessInput(const CFinalInput& input, CStateManager& mgr) { if (x304_orbitState == EPlayerOrbitState::Grapple) { ApplyGrappleForces(input, mgr, input.DeltaTime()); } else { - CFinalInput scaledInput = input.ScaleAnalogueSticks(IsUnderBetaMetroidAttack(mgr) ? 3.f : 1.f, 1.f); + const CFinalInput scaledInput = input.ScaleAnalogueSticks(IsUnderBetaMetroidAttack(mgr) ? 3.f : 1.f, 1.f); ComputeMovement(scaledInput, mgr, input.DeltaTime()); } if (ShouldSampleFailsafe(mgr)) { CFailsafeTest::EInputState inputState = CFailsafeTest::EInputState::Moving; - if (x258_movementState == EPlayerMovementState::ApplyJump) + if (x258_movementState == EPlayerMovementState::ApplyJump) { inputState = CFailsafeTest::EInputState::StartingJump; - else if (x258_movementState == EPlayerMovementState::Jump) + } else if (x258_movementState == EPlayerMovementState::Jump) { inputState = CFailsafeTest::EInputState::Jump; + } x4a0_failsafeTest->AddSample(inputState, GetTranslation(), x138_velocity, zeus::CVector2f(input.ALeftX(), input.ALeftY())); } @@ -1750,13 +1895,15 @@ void CPlayer::ProcessInput(const CFinalInput& input, CStateManager& mgr) { ControlMapper::GetPressInput(ControlMapper::ECommands::Backward, input) || ControlMapper::GetPressInput(ControlMapper::ECommands::JumpOrBoost, input)) { xa28_attachedActorStruggle += input.DeltaTime() * 600.f * input.DeltaTime(); - if (xa28_attachedActorStruggle > 1.f) + if (xa28_attachedActorStruggle > 1.f) { xa28_attachedActorStruggle = 1.f; + } } else { - float tmp = 7.5f * input.DeltaTime(); + const float tmp = 7.5f * input.DeltaTime(); xa28_attachedActorStruggle -= input.DeltaTime() * std::min(1.f, xa28_attachedActorStruggle * tmp + tmp); - if (xa28_attachedActorStruggle < 0.f) + if (xa28_attachedActorStruggle < 0.f) { xa28_attachedActorStruggle = 0.f; + } } } } @@ -1767,18 +1914,20 @@ void CPlayer::ProcessInput(const CFinalInput& input, CStateManager& mgr) { UpdateFootstepSounds(input, mgr, input.DeltaTime()); x2a8_timeSinceJump += input.DeltaTime(); - if (CheckSubmerged()) + if (CheckSubmerged()) { SetSoundEventPitchBend(0); - else + } else { SetSoundEventPitchBend(8192); + } CalculateLeaveMorphBallDirection(input); } bool CPlayer::ShouldSampleFailsafe(CStateManager& mgr) const { - TCastToPtr cineCam = mgr.GetCameraManager()->GetCurrentCamera(mgr); - if (!mgr.GetPlayerState()->IsPlayerAlive()) + const TCastToConstPtr cineCam = mgr.GetCameraManager()->GetCurrentCamera(mgr); + if (!mgr.GetPlayerState()->IsPlayerAlive()) { return false; + } return x2f4_cameraState != EPlayerCameraState::Spawned || !cineCam || (cineCam->GetFlags() & 0x80) == 0; } @@ -1790,8 +1939,9 @@ void CPlayer::CalculateLeaveMorphBallDirection(const CFinalInput& input) { ControlMapper::GetAnalogInput(ControlMapper::ECommands::Backward, input) > 0.3f || ControlMapper::GetAnalogInput(ControlMapper::ECommands::TurnLeft, input) > 0.3f || ControlMapper::GetAnalogInput(ControlMapper::ECommands::TurnRight, input) > 0.3f) { - if (x138_velocity.magnitude() > 0.5f) + if (x138_velocity.magnitude() > 0.5f) { x518_leaveMorphDir = x50c_moveDir; + } } } } @@ -1802,15 +1952,16 @@ void CPlayer::CalculatePlayerControlDirection(CStateManager& mgr) { x540_controlDir = x9d8_controlDirOverrideDir.normalized(); x54c_controlDirFlat = x9d8_controlDirOverrideDir; x54c_controlDirFlat.z() = 0.f; - if (x54c_controlDirFlat.canBeNormalized()) + if (x54c_controlDirFlat.canBeNormalized()) { x54c_controlDirFlat.normalize(); - else + } else { x540_controlDir = x54c_controlDirFlat = zeus::skForward; + } } else { x540_controlDir = x54c_controlDirFlat = zeus::skForward; } } else { - zeus::CVector3f camToPlayer = GetTranslation() - mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTranslation(); + const zeus::CVector3f camToPlayer = GetTranslation() - mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTranslation(); if (!camToPlayer.canBeNormalized()) { x540_controlDir = x54c_controlDirFlat = zeus::skForward; } else { @@ -1828,14 +1979,16 @@ void CPlayer::CalculatePlayerControlDirection(CStateManager& mgr) { x540_controlDir = GetTransform().basis[1]; x54c_controlDirFlat = x540_controlDir; x54c_controlDirFlat.z() = 0.f; - if (x54c_controlDirFlat.canBeNormalized()) + if (x54c_controlDirFlat.canBeNormalized()) { x54c_controlDirFlat.normalize(); + } } } else if (x2f8_morphBallState != EPlayerMorphBallState::Morphed) { x540_controlDir = GetTransform().basis[1]; x54c_controlDirFlat.z() = 0.f; - if (x54c_controlDirFlat.canBeNormalized()) + if (x54c_controlDirFlat.canBeNormalized()) { x54c_controlDirFlat.normalize(); + } } } else { if (x4fc_flatMoveSpeed < 0.25f) { @@ -1844,8 +1997,9 @@ void CPlayer::CalculatePlayerControlDirection(CStateManager& mgr) { } else if (x2f8_morphBallState != EPlayerMorphBallState::Morphed) { x540_controlDir = GetTransform().basis[1]; x54c_controlDirFlat.z() = 0.f; - if (x54c_controlDirFlat.canBeNormalized()) + if (x54c_controlDirFlat.canBeNormalized()) { x54c_controlDirFlat.normalize(); + } } } } @@ -1855,10 +2009,11 @@ void CPlayer::CalculatePlayerControlDirection(CStateManager& mgr) { void CPlayer::CalculatePlayerMovementDirection(float dt) { if (x2f8_morphBallState == EPlayerMorphBallState::Morphing || - x2f8_morphBallState == EPlayerMorphBallState::Unmorphing) + x2f8_morphBallState == EPlayerMorphBallState::Unmorphing) { return; + } - zeus::CVector3f delta = GetTranslation() - x524_lastPosForDirCalc; + const zeus::CVector3f delta = GetTranslation() - x524_lastPosForDirCalc; if (delta.canBeNormalized() && delta.magnitude() > 0.02f) { x53c_timeMoving += dt; x4f8_moveSpeed = std::fabs(delta.magnitude() / dt); @@ -1869,8 +2024,9 @@ void CPlayer::CalculatePlayerMovementDirection(float dt) { flatDelta.normalize(); switch (x2f8_morphBallState) { case EPlayerMorphBallState::Morphed: - if (x4fc_flatMoveSpeed > 0.25f) + if (x4fc_flatMoveSpeed > 0.25f) { x50c_moveDir = flatDelta; + } x530_gunDir = x50c_moveDir; x524_lastPosForDirCalc = GetTranslation(); break; @@ -1878,8 +2034,9 @@ void CPlayer::CalculatePlayerMovementDirection(float dt) { x500_lookDir = GetTransform().basis[1]; x50c_moveDir = x500_lookDir; x50c_moveDir.z() = 0.f; - if (x50c_moveDir.canBeNormalized()) + if (x50c_moveDir.canBeNormalized()) { x50c_moveDir.normalize(); + } x530_gunDir = x50c_moveDir; x524_lastPosForDirCalc = GetTranslation(); break; @@ -1889,8 +2046,9 @@ void CPlayer::CalculatePlayerMovementDirection(float dt) { x500_lookDir = GetTransform().basis[1]; x50c_moveDir = x500_lookDir; x50c_moveDir.z() = 0.f; - if (x50c_moveDir.canBeNormalized()) + if (x50c_moveDir.canBeNormalized()) { x50c_moveDir.normalize(); + } x530_gunDir = x50c_moveDir; x524_lastPosForDirCalc = GetTranslation(); } @@ -1908,8 +2066,9 @@ void CPlayer::CalculatePlayerMovementDirection(float dt) { x500_lookDir = GetTransform().basis[1]; x50c_moveDir = x500_lookDir; x50c_moveDir.z() = 0.f; - if (x50c_moveDir.canBeNormalized()) + if (x50c_moveDir.canBeNormalized()) { x50c_moveDir.normalize(); + } x530_gunDir = x50c_moveDir; x524_lastPosForDirCalc = GetTranslation(); break; @@ -1919,46 +2078,52 @@ void CPlayer::CalculatePlayerMovementDirection(float dt) { } x50c_moveDir.z() = 0.f; - if (x50c_moveDir.canBeNormalized()) + if (x50c_moveDir.canBeNormalized()) { x500_lookDir.normalize(); -} - -void CPlayer::UnFreeze(CStateManager& stateMgr) { - if (GetFrozenState()) { - x750_frozenTimeout = 0.f; - x754_iceBreakJumps = 0; - CPhysicsActor::Stop(); - ClearForcesAndTorques(); - RemoveMaterial(EMaterialTypes::Immovable, stateMgr); - if (!stateMgr.GetCameraManager()->IsInCinematicCamera() && xa0c_iceTextureId.IsValid()) { - std::optional> gpsm; - gpsm.emplace(g_SimplePool->GetObj(SObjectTag(FOURCC('PART'), xa0c_iceTextureId))); - CHUDBillboardEffect* effect = new CHUDBillboardEffect( - gpsm, {}, stateMgr.AllocateUniqueId(), true, "FrostExplosion", - CHUDBillboardEffect::GetNearClipDistance(stateMgr), CHUDBillboardEffect::GetScaleForPOV(stateMgr), - zeus::skWhite, zeus::skOne3f, zeus::skZero3f); - stateMgr.AddObject(effect); - CSfxHandle hnd = CSfxManager::SfxStart(SFXcrk_break_final, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); - ApplySubmergedPitchBend(hnd); - } - x768_morphball->Stop(); - SetVisorSteam(0.f, 6.f / 14.f, 1.f / 14.f, xa08_steamTextureId, false); } } -void CPlayer::Freeze(CStateManager& stateMgr, CAssetId steamTxtr, u16 sfx, CAssetId iceTxtr) { - if (stateMgr.GetCameraManager()->IsInCinematicCamera() || GetFrozenState()) +void CPlayer::UnFreeze(CStateManager& stateMgr) { + if (!GetFrozenState()) { return; + } + + x750_frozenTimeout = 0.f; + x754_iceBreakJumps = 0; + CPhysicsActor::Stop(); + ClearForcesAndTorques(); + RemoveMaterial(EMaterialTypes::Immovable, stateMgr); + if (!stateMgr.GetCameraManager()->IsInCinematicCamera() && xa0c_iceTextureId.IsValid()) { + std::optional> gpsm; + gpsm.emplace(g_SimplePool->GetObj(SObjectTag(FOURCC('PART'), xa0c_iceTextureId))); + auto* effect = new CHUDBillboardEffect(gpsm, {}, stateMgr.AllocateUniqueId(), true, "FrostExplosion", + CHUDBillboardEffect::GetNearClipDistance(stateMgr), + CHUDBillboardEffect::GetScaleForPOV(stateMgr), zeus::skWhite, zeus::skOne3f, + zeus::skZero3f); + stateMgr.AddObject(effect); + CSfxHandle hnd = CSfxManager::SfxStart(SFXcrk_break_final, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); + ApplySubmergedPitchBend(hnd); + } + + x768_morphball->Stop(); + SetVisorSteam(0.f, 6.f / 14.f, 1.f / 14.f, xa08_steamTextureId, false); +} + +void CPlayer::Freeze(CStateManager& stateMgr, CAssetId steamTxtr, u16 sfx, CAssetId iceTxtr) { + if (stateMgr.GetCameraManager()->IsInCinematicCamera() || GetFrozenState()) { + return; + } bool showMsg; - if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphed) + if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphed) { showMsg = g_GameState->SystemOptions().GetShowFrozenFpsMessage(); - else + } else { showMsg = g_GameState->SystemOptions().GetShowFrozenBallMessage(); + } if (showMsg) { const char16_t* msg = g_MainStringTable->GetString(int(x2f8_morphBallState >= EPlayerMorphBallState::Morphed) + 19); - CHUDMemoParms parms(5.f, true, false, false); + const CHUDMemoParms parms(5.f, true, false, false); MP1::CSamusHud::DisplayHudMemo(msg, parms); } @@ -1967,10 +2132,11 @@ void CPlayer::Freeze(CStateManager& stateMgr, CAssetId steamTxtr, u16 sfx, CAsse CPhysicsActor::Stop(); ClearForcesAndTorques(); - if (x3b8_grappleState != EGrappleState::None) + if (x3b8_grappleState != EGrappleState::None) { BreakGrapple(EPlayerOrbitRequest::Freeze, stateMgr); - else + } else { SetOrbitRequest(EPlayerOrbitRequest::Freeze, stateMgr); + } AddMaterial(EMaterialTypes::Immovable, stateMgr); xa08_steamTextureId = steamTxtr; @@ -2017,7 +2183,7 @@ void CPlayer::UpdateFrozenState(const CFinalInput& input, CStateManager& mgr) { x754_iceBreakJumps += 1; if (x754_iceBreakJumps > g_tweakPlayer->GetIceBreakJumpCount()) { g_GameState->SystemOptions().IncrementFrozenFpsCount(); - CHUDMemoParms info(0.f, true, true, true); + const CHUDMemoParms info(0.f, true, true, true); MP1::CSamusHud::DisplayHudMemo(u"", info); UnFreeze(mgr); } @@ -2029,20 +2195,22 @@ void CPlayer::UpdateFrozenState(const CFinalInput& input, CStateManager& mgr) { void CPlayer::UpdateStepCameraZBias(float dt) { float newBias = GetTranslation().z() + GetUnbiasedEyeHeight(); if (x258_movementState == EPlayerMovementState::OnGround && !IsMorphBallTransitioning()) { - float oldBias = newBias; + const float oldBias = newBias; if (!x9c5_31_stepCameraZBiasDirty) { - float delta = newBias - x9cc_stepCameraZBias; + const float delta = newBias - x9cc_stepCameraZBias; float newDelta = 5.f * dt; if (delta > 0.f) { if (delta > dt * x138_velocity.z() && delta > newDelta) { - if (delta > GetStepUpHeight()) + if (delta > GetStepUpHeight()) { newDelta += delta - GetStepUpHeight(); + } newBias = x9cc_stepCameraZBias + newDelta; } } else { if (delta < dt * x138_velocity.z() && delta < -newDelta) { - if (delta < -GetStepDownHeight()) + if (delta < -GetStepDownHeight()) { newDelta += -delta - GetStepDownHeight(); + } newBias = x9cc_stepCameraZBias - newDelta; } } @@ -2056,61 +2224,74 @@ void CPlayer::UpdateStepCameraZBias(float dt) { } void CPlayer::UpdateWaterSurfaceCameraBias(CStateManager& mgr) { - if (TCastToConstPtr water = mgr.GetObjectById(xc4_fluidId)) { - float waterZ = water->GetTriggerBoundsWR().max.z(); - float biasToEyeDelta = GetEyePosition().z() - x9c8_eyeZBias; - float waterToDeltaDelta = biasToEyeDelta - waterZ; - if (biasToEyeDelta >= waterZ && waterToDeltaDelta <= 0.25f) - x9c8_eyeZBias += waterZ + 0.25f - biasToEyeDelta; - else if (biasToEyeDelta < waterZ && waterToDeltaDelta >= -0.2f) - x9c8_eyeZBias += waterZ - 0.2f - biasToEyeDelta; + const TCastToConstPtr water = mgr.GetObjectById(xc4_fluidId); + if (!water) { + return; + } + + const float waterZ = water->GetTriggerBoundsWR().max.z(); + const float biasToEyeDelta = GetEyePosition().z() - x9c8_eyeZBias; + const float waterToDeltaDelta = biasToEyeDelta - waterZ; + + if (biasToEyeDelta >= waterZ && waterToDeltaDelta <= 0.25f) { + x9c8_eyeZBias += waterZ + 0.25f - biasToEyeDelta; + } else if (biasToEyeDelta < waterZ && waterToDeltaDelta >= -0.2f) { + x9c8_eyeZBias += waterZ - 0.2f - biasToEyeDelta; } } void CPlayer::UpdateEnvironmentDamageCameraShake(float dt, CStateManager& mgr) { xa2c_damageLoopSfxDelayTicks = std::min(2, xa2c_damageLoopSfxDelayTicks + 1); - if (xa10_envDmgCounter != 0) { - if (xa14_envDmgCameraShakeTimer == 0.f) - mgr.GetCameraManager()->AddCameraShaker(CCameraShakeData::BuildPhazonCameraShakeData(1.f, 0.075f), false); - xa14_envDmgCameraShakeTimer += dt; - if (xa14_envDmgCameraShakeTimer > 2.f) - xa14_envDmgCameraShakeTimer = 0.f; + + if (xa10_envDmgCounter == 0) { + return; + } + + if (xa14_envDmgCameraShakeTimer == 0.f) { + mgr.GetCameraManager()->AddCameraShaker(CCameraShakeData::BuildPhazonCameraShakeData(1.f, 0.075f), false); + } + xa14_envDmgCameraShakeTimer += dt; + if (xa14_envDmgCameraShakeTimer > 2.f) { + xa14_envDmgCameraShakeTimer = 0.f; } } void CPlayer::UpdatePhazonDamage(float dt, CStateManager& mgr) { - if (x4_areaId == kInvalidAreaId) + if (x4_areaId == kInvalidAreaId) { return; + } const CGameArea* area = mgr.GetWorld()->GetAreaAlways(x4_areaId); - if (!area->IsPostConstructed()) + if (!area->IsPostConstructed()) { return; + } bool touchingPhazon = false; EPhazonType phazonType; - if (const CScriptAreaAttributes* attr = area->GetPostConstructed()->x10d8_areaAttributes) + if (const CScriptAreaAttributes* attr = area->GetPostConstructed()->x10d8_areaAttributes) { phazonType = attr->GetPhazonType(); - else + } else { phazonType = EPhazonType::None; + } if (phazonType == EPhazonType::Orange || (!mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PhazonSuit) && phazonType == EPhazonType::Blue)) { - CMaterialFilter filter = CMaterialFilter::MakeInclude({EMaterialTypes::Phazon}); + constexpr CMaterialFilter filter = CMaterialFilter::MakeInclude({EMaterialTypes::Phazon}); if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) { touchingPhazon = x768_morphball->BallCloseToCollision(mgr, 2.9f, filter); } else { - CMaterialList primMaterial(EMaterialTypes::Player, EMaterialTypes::Solid); - CCollidableSphere prim(zeus::CSphere(GetCollisionPrimitive()->CalculateAABox(x34_transform).center(), 4.25f), - primMaterial); + constexpr CMaterialList primMaterial(EMaterialTypes::Player, EMaterialTypes::Solid); + const CCollidableSphere prim( + zeus::CSphere(GetCollisionPrimitive()->CalculateAABox(x34_transform).center(), 4.25f), primMaterial); rstl::reserved_vector nearList; mgr.BuildColliderList(nearList, *this, prim.CalculateLocalAABox()); if (CGameCollision::DetectStaticCollisionBoolean(mgr, prim, zeus::CTransform(), filter)) { touchingPhazon = true; } else { - for (TUniqueId id : nearList) { - if (TCastToConstPtr act = mgr.GetObjectById(id)) { - CInternalCollisionStructure::CPrimDesc prim0(prim, filter, zeus::CTransform()); - CInternalCollisionStructure::CPrimDesc prim1( + for (const TUniqueId id : nearList) { + if (const TCastToConstPtr act = mgr.GetObjectById(id)) { + const CInternalCollisionStructure::CPrimDesc prim0(prim, filter, zeus::CTransform()); + const CInternalCollisionStructure::CPrimDesc prim1( *act->GetCollisionPrimitive(), CMaterialFilter::skPassEverything, act->GetPrimitiveTransform()); if (CCollisionPrimitive::CollideBoolean(prim0, prim1)) { touchingPhazon = true; @@ -2126,8 +2307,8 @@ void CPlayer::UpdatePhazonDamage(float dt, CStateManager& mgr) { xa18_phazonDamageLag += dt; xa18_phazonDamageLag = std::min(xa18_phazonDamageLag, 3.f); if (xa18_phazonDamageLag > 0.2f) { - float damage = (xa18_phazonDamageLag - 0.2f) / 3.f * 60.f * dt; - CDamageInfo dInfo( + const float damage = (xa18_phazonDamageLag - 0.2f) / 3.f * 60.f * dt; + const CDamageInfo dInfo( CWeaponMode(phazonType == EPhazonType::Orange ? EWeaponType::OrangePhazon : EWeaponType::Phazon), damage, 0.f, 0.f); mgr.ApplyDamage(kInvalidUniqueId, GetUniqueId(), kInvalidUniqueId, dInfo, @@ -2161,8 +2342,9 @@ bool CPlayer::SetAreaPlayerHint(const CScriptPlayerHint& hint, CStateManager& mg x9c4_27_canEnterMorphBall = (hint.GetOverrideFlags() & 0x40) == 0; x9c4_28_canLeaveMorphBall = (hint.GetOverrideFlags() & 0x20) == 0; x9c4_30_controlDirOverride = (hint.GetOverrideFlags() & 0x2) != 0; - if (x9c4_30_controlDirOverride) + if (x9c4_30_controlDirOverride) { x9d8_controlDirOverrideDir = hint.GetTransform().basis[1]; + } x9c6_24_extendTargetDistance = (hint.GetOverrideFlags() & 0x4) != 0; x9c6_26_outOfBallLookAtHint = (hint.GetOverrideFlags() & 0x8) != 0; x9c4_29_spiderBallControlXY = (hint.GetOverrideFlags() & 0x10) != 0; @@ -2171,53 +2353,68 @@ bool CPlayer::SetAreaPlayerHint(const CScriptPlayerHint& hint, CStateManager& mg x768_morphball->SetBoostEnabed((hint.GetOverrideFlags() & 0x100) == 0); bool switchedVisor = false; if ((hint.GetOverrideFlags() & 0x200) != 0) { - if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::CombatVisor)) + if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::CombatVisor)) { mgr.GetPlayerState()->StartTransitionToVisor(CPlayerState::EPlayerVisor::Combat); + } switchedVisor = true; } if ((hint.GetOverrideFlags() & 0x400) != 0) { - if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::ScanVisor)) + if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::ScanVisor)) { mgr.GetPlayerState()->StartTransitionToVisor(CPlayerState::EPlayerVisor::Scan); + } switchedVisor = true; } if ((hint.GetOverrideFlags() & 0x800) != 0) { - if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::ThermalVisor)) + if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::ThermalVisor)) { mgr.GetPlayerState()->StartTransitionToVisor(CPlayerState::EPlayerVisor::Thermal); + } switchedVisor = true; } if ((hint.GetOverrideFlags() & 0x1000) != 0) { - if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::XRayVisor)) + if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::XRayVisor)) { mgr.GetPlayerState()->StartTransitionToVisor(CPlayerState::EPlayerVisor::XRay); + } switchedVisor = true; } return switchedVisor; } void CPlayer::AddToPlayerHintRemoveList(TUniqueId id, CStateManager& mgr) { - if (TCastToPtr hint = mgr.ObjectById(id)) { - for (TUniqueId existId : x93c_playerHintsToRemove) - if (id == existId) + if (const TCastToConstPtr hint = mgr.ObjectById(id)) { + for (const TUniqueId existId : x93c_playerHintsToRemove) { + if (id == existId) { return; - if (x93c_playerHintsToRemove.size() != 32) + } + } + + if (x93c_playerHintsToRemove.size() != 32) { x93c_playerHintsToRemove.push_back(id); + } } } void CPlayer::AddToPlayerHintAddList(TUniqueId id, CStateManager& mgr) { - if (TCastToPtr hint = mgr.ObjectById(id)) { - for (TUniqueId existId : x980_playerHintsToAdd) - if (id == existId) + if (const TCastToConstPtr hint = mgr.ObjectById(id)) { + for (const TUniqueId existId : x980_playerHintsToAdd) { + if (id == existId) { return; - if (x980_playerHintsToAdd.size() != 32) + } + } + + if (x980_playerHintsToAdd.size() != 32) { x980_playerHintsToAdd.push_back(id); + } } } void CPlayer::DeactivatePlayerHint(TUniqueId id, CStateManager& mgr) { if (TCastToPtr hint = mgr.ObjectById(id)) { - for (TUniqueId existId : x93c_playerHintsToRemove) - if (id == existId) + for (const TUniqueId existId : x93c_playerHintsToRemove) { + if (id == existId) { return; + } + } + if (x93c_playerHintsToRemove.size() != 32) { x93c_playerHintsToRemove.push_back(id); hint->ClearObjectList(); @@ -2230,7 +2427,7 @@ void CPlayer::UpdatePlayerHints(CStateManager& mgr) { bool removedHint = false; for (auto it = x838_playerHints.begin(); it != x838_playerHints.end();) { auto& p = *it; - TCastToPtr hint = mgr.ObjectById(p.second); + const TCastToConstPtr hint = mgr.ObjectById(p.second); if (!hint) { it = x838_playerHints.erase(it); removedHint = true; @@ -2240,12 +2437,13 @@ void CPlayer::UpdatePlayerHints(CStateManager& mgr) { } bool needsNewHint = false; - for (TUniqueId id : x93c_playerHintsToRemove) { + for (const TUniqueId id : x93c_playerHintsToRemove) { for (auto it = x838_playerHints.begin(); it != x838_playerHints.end();) { if (it->second == id) { it = x838_playerHints.erase(it); - if (id == x830_playerHint) + if (id == x830_playerHint) { needsNewHint = true; + } break; } ++it; @@ -2254,14 +2452,15 @@ void CPlayer::UpdatePlayerHints(CStateManager& mgr) { x93c_playerHintsToRemove.clear(); bool addedHint = false; - for (TUniqueId id : x980_playerHintsToAdd) { - if (TCastToPtr hint = mgr.ObjectById(id)) { + for (const TUniqueId id : x980_playerHintsToAdd) { + if (const TCastToConstPtr hint = mgr.ObjectById(id)) { bool exists = false; - for (auto& p : x838_playerHints) + for (auto& p : x838_playerHints) { if (p.second == id) { exists = true; break; } + } if (!exists) { x838_playerHints.emplace_back(hint->GetPriority(), id); addedHint = true; @@ -2281,10 +2480,10 @@ void CPlayer::UpdatePlayerHints(CStateManager& mgr) { return; } - CScriptPlayerHint* foundHint = nullptr; + const CScriptPlayerHint* foundHint = nullptr; bool foundHintInArea = false; - for (auto& p : x838_playerHints) { - if (TCastToPtr hint = mgr.ObjectById(p.second)) { + for (const auto& p : x838_playerHints) { + if (const TCastToConstPtr hint = mgr.ObjectById(p.second)) { foundHint = hint.GetPtr(); if (hint->GetAreaIdAlways() == mgr.GetNextAreaId()) { foundHintInArea = true; @@ -2302,23 +2501,28 @@ void CPlayer::UpdatePlayerHints(CStateManager& mgr) { if (foundHint != nullptr && foundHintInArea && x830_playerHint != foundHint->GetUniqueId()) { x830_playerHint = foundHint->GetUniqueId(); x834_playerHintPriority = foundHint->GetPriority(); - if (SetAreaPlayerHint(*foundHint, mgr)) + if (SetAreaPlayerHint(*foundHint, mgr)) { DeactivatePlayerHint(x830_playerHint, mgr); + } } } } void CPlayer::UpdateBombJumpStuff() { - if (x9d0_bombJumpCount == 0) + if (x9d0_bombJumpCount == 0) { return; + } x9d4_bombJumpCheckDelayFrames -= 1; - if (x9d4_bombJumpCheckDelayFrames > 0) + if (x9d4_bombJumpCheckDelayFrames > 0) { return; + } zeus::CVector3f velFlat = x138_velocity; velFlat.z() = 0.f; - if (x258_movementState == EPlayerMovementState::OnGround || (velFlat.canBeNormalized() && velFlat.magnitude() > 6.f)) + if (x258_movementState == EPlayerMovementState::OnGround || + (velFlat.canBeNormalized() && velFlat.magnitude() > 6.f)) { x9d0_bombJumpCount = 0; + } } void CPlayer::UpdateTransitionFilter(float dt, CStateManager& mgr) { @@ -2334,17 +2538,19 @@ void CPlayer::UpdateTransitionFilter(float dt, CStateManager& mgr) { return; } - if (x824_transitionFilterTimer < 0.95f) + if (x824_transitionFilterTimer < 0.95f) { return; + } - float time = x824_transitionFilterTimer - 0.95f; + const float time = x824_transitionFilterTimer - 0.95f; zeus::CColor color(1.f, 0.87f, 0.54f, 1.f); - if (time < 0.1f) + if (time < 0.1f) { color.a() = 0.3f * time / 0.1f; - else if (time >= 0.15f) + } else if (time >= 0.15f) { color.a() = 1.f - zeus::clamp(-1.f, (time - 0.15f) / 0.15f, 1.f) * 0.3f; - else + } else { color.a() = 0.3f; + } mgr.GetCameraFilterPass(8).SetFilter(EFilterType::Add, EFilterShape::ScanLinesEven, 0.f, color, {}); } @@ -2361,19 +2567,23 @@ void CPlayer::SetControlDirectionInterpolation(float time) { } void CPlayer::UpdatePlayerControlDirection(float dt, CStateManager& mgr) { - zeus::CVector3f oldControlDir = x540_controlDir; - zeus::CVector3f oldControlDirFlat = x54c_controlDirFlat; + const zeus::CVector3f oldControlDir = x540_controlDir; + const zeus::CVector3f oldControlDirFlat = x54c_controlDirFlat; CalculatePlayerControlDirection(mgr); - if (x9c6_25_interpolatingControlDir && x2f8_morphBallState == EPlayerMorphBallState::Morphed) { - x9f8_controlDirInterpTime += dt; - if (x9f8_controlDirInterpTime > x9fc_controlDirInterpDur) { - x9f8_controlDirInterpTime = x9fc_controlDirInterpDur; - ResetControlDirectionInterpolation(); - } - float t = zeus::clamp(-1.f, x9f8_controlDirInterpTime / x9fc_controlDirInterpDur, 1.f); - x540_controlDir = zeus::CVector3f::lerp(oldControlDir, x540_controlDir, t); - x54c_controlDirFlat = zeus::CVector3f::lerp(oldControlDirFlat, x540_controlDir, t); + + if (!x9c6_25_interpolatingControlDir || x2f8_morphBallState != EPlayerMorphBallState::Morphed) { + return; } + + x9f8_controlDirInterpTime += dt; + if (x9f8_controlDirInterpTime > x9fc_controlDirInterpDur) { + x9f8_controlDirInterpTime = x9fc_controlDirInterpDur; + ResetControlDirectionInterpolation(); + } + + const float t = zeus::clamp(-1.f, x9f8_controlDirInterpTime / x9fc_controlDirInterpDur, 1.f); + x540_controlDir = zeus::CVector3f::lerp(oldControlDir, x540_controlDir, t); + x54c_controlDirFlat = zeus::CVector3f::lerp(oldControlDirFlat, x540_controlDir, t); } void CPlayer::Think(float dt, CStateManager& mgr) { @@ -2384,8 +2594,9 @@ void CPlayer::Think(float dt, CStateManager& mgr) { UpdateFreeLook(dt); UpdatePlayerHints(mgr); - if (x2b0_outOfWaterTicks < 2) + if (x2b0_outOfWaterTicks < 2) { x2b0_outOfWaterTicks += 1; + } x9c5_24_ = x9c4_24_visorChangeRequested; x9c4_31_inWaterMovement = x9c5_25_splashUpdated; @@ -2394,23 +2605,29 @@ void CPlayer::Think(float dt, CStateManager& mgr) { if (0.f < x288_startingJumpTimeout) { x288_startingJumpTimeout -= dt; - if (0.f >= x288_startingJumpTimeout) + if (0.f >= x288_startingJumpTimeout) { SetMoveState(EPlayerMovementState::ApplyJump, mgr); + } } - if (x2a0_ > 0.f) + if (x2a0_ > 0.f) { x2a0_ += dt; - if (x774_samusVoiceTimeout > 0.f) + } + if (x774_samusVoiceTimeout > 0.f) { x774_samusVoiceTimeout -= dt; - if (0.f < x28c_sjTimer) + } + if (0.f < x28c_sjTimer) { x28c_sjTimer -= dt; + } x300_fallingTime += dt; - if (x258_movementState == EPlayerMovementState::FallingMorphed && x300_fallingTime > 0.4f) + if (x258_movementState == EPlayerMovementState::FallingMorphed && x300_fallingTime > 0.4f) { SetMoveState(EPlayerMovementState::ApplyJump, mgr); + } - if (x570_immuneTimer > 0.f) + if (x570_immuneTimer > 0.f) { x570_immuneTimer -= dt; + } Update(dt, mgr); UpdateTransitionFilter(dt, mgr); @@ -2418,20 +2635,20 @@ void CPlayer::Think(float dt, CStateManager& mgr) { UpdatePlayerControlDirection(dt, mgr); #if 0 - if (g_factoryManager == 4) + if (g_factoryManager == 4) { x2b0_ = 0; - else + } else { x2ac_surfaceRestraint = ESurfaceRestraints::Normal; + } #endif if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphed && x9c5_27_camSubmerged && mgr.GetCameraManager()->GetFluidCounter() == 0) { - if (auto water = GetVisorRunoffEffect(mgr)) { + if (const auto* water = GetVisorRunoffEffect(mgr)) { if (const auto& effect = water->GetVisorRunoffEffect()) { - CHUDBillboardEffect* sheets = new CHUDBillboardEffect( + auto* sheets = new CHUDBillboardEffect( *effect, {}, mgr.AllocateUniqueId(), true, "WaterSheets", CHUDBillboardEffect::GetNearClipDistance(mgr), - CHUDBillboardEffect::GetScaleForPOV(mgr), zeus::skWhite, zeus::skOne3f, - zeus::skZero3f); + CHUDBillboardEffect::GetScaleForPOV(mgr), zeus::skWhite, zeus::skOne3f, zeus::skZero3f); mgr.AddObject(sheets); } CSfxHandle hnd = CSfxManager::SfxStart(water->GetVisorRunoffSfx(), 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); @@ -2442,8 +2659,8 @@ void CPlayer::Think(float dt, CStateManager& mgr) { if (x2f8_morphBallState != EPlayerMorphBallState::Morphed) { if (std::fabs(x34_transform.basis[0].z()) > FLT_EPSILON || std::fabs(x34_transform.basis[1].z()) > FLT_EPSILON) { - zeus::CVector3f backupTranslation = GetTranslation(); - zeus::CVector3f lookDirFlat(x34_transform.basis[1].x(), x34_transform.basis[1].y(), 0.f); + const zeus::CVector3f backupTranslation = GetTranslation(); + const zeus::CVector3f lookDirFlat(x34_transform.basis[1].x(), x34_transform.basis[1].y(), 0.f); if (lookDirFlat.canBeNormalized()) { SetTransform(zeus::lookAt(zeus::skZero3f, lookDirFlat.normalized())); } else { @@ -2491,8 +2708,9 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState float rumbleMag = -x794_lastVelocity.z() / 110.f; if (rumbleMag > 0.f) { - if (std::fabs(rumbleMag) > 0.8f) + if (std::fabs(rumbleMag) > 0.8f) { rumbleMag = (rumbleMag > 0.f) ? 0.8f : -0.8f; + } mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerLand, rumbleMag, ERumblePriority::One); } @@ -2501,20 +2719,23 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState } else if (x258_movementState != EPlayerMovementState::OnGround && x2f8_morphBallState == EPlayerMorphBallState::Morphed) { if (x138_velocity.z() < -40.f && !x768_morphball->GetIsInHalfPipeMode() && - x258_movementState == EPlayerMovementState::ApplyJump && x300_fallingTime > 0.75f) + x258_movementState == EPlayerMovementState::ApplyJump && x300_fallingTime > 0.75f) { SetCoefficientOfRestitutionModifier(0.2f); + } x768_morphball->StartLandingSfx(); if (x138_velocity.z() < -5.f) { float rumbleMag = -x138_velocity.z() / 110.f * 0.5f; - if (std::fabs(rumbleMag) > 0.8f) + if (std::fabs(rumbleMag) > 0.8f) { rumbleMag = (rumbleMag > 0.f) ? 0.8f : -0.8f; + } mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerLand, rumbleMag, ERumblePriority::One); x2a0_ = 0.f; } if (x138_velocity.z() < -30.f) { float rumbleMag = -x138_velocity.z() / 110.f; - if (std::fabs(rumbleMag) > 0.8f) + if (std::fabs(rumbleMag) > 0.8f) { rumbleMag = (rumbleMag > 0.f) ? 0.8f : -0.8f; + } mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerLand, rumbleMag, ERumblePriority::One); x2a0_ = 0.f; } @@ -2523,19 +2744,23 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState SetMoveState(EPlayerMovementState::OnGround, mgr); break; case EScriptObjectMessage::Falling: - if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) - if (x768_morphball->GetSpiderBallState() == CMorphBall::ESpiderBallState::Active) + if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) { + if (x768_morphball->GetSpiderBallState() == CMorphBall::ESpiderBallState::Active) { break; - if (x2f8_morphBallState != EPlayerMorphBallState::Morphed) + } + } + if (x2f8_morphBallState != EPlayerMorphBallState::Morphed) { SetMoveState(EPlayerMovementState::Falling, mgr); - else if (x258_movementState == EPlayerMovementState::OnGround) + } else if (x258_movementState == EPlayerMovementState::OnGround) { SetMoveState(EPlayerMovementState::FallingMorphed, mgr); + } break; case EScriptObjectMessage::LandOnNotFloor: if (x2f8_morphBallState == EPlayerMorphBallState::Morphed && x768_morphball->GetSpiderBallState() == CMorphBall::ESpiderBallState::Active && - x258_movementState != EPlayerMovementState::ApplyJump) + x258_movementState != EPlayerMovementState::ApplyJump) { SetMoveState(EPlayerMovementState::ApplyJump, mgr); + } break; case EScriptObjectMessage::OnIceSurface: x2ac_surfaceRestraint = ESurfaceRestraints::Ice; @@ -2552,8 +2777,8 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState case EScriptObjectMessage::AddSplashInhabitant: { SetInFluid(true, sender); UpdateSubmerged(mgr); - CRayCastResult result = mgr.RayStaticIntersection(x34_transform.origin, zeus::skDown, - 0.5f * GetEyeHeight(), SolidMaterialFilter); + const CRayCastResult result = + mgr.RayStaticIntersection(x34_transform.origin, zeus::skDown, 0.5f * GetEyeHeight(), SolidMaterialFilter); if (result.IsInvalid()) { SetVelocityWR(x138_velocity * 0.095f); xfc_constantForce *= zeus::CVector3f(0.095f); @@ -2563,7 +2788,7 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState case EScriptObjectMessage::UpdateSplashInhabitant: UpdateSubmerged(mgr); if (CheckSubmerged() && !mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit)) { - if (TCastToPtr water = mgr.ObjectById(xc4_fluidId)) { + if (const TCastToConstPtr water = mgr.ObjectById(xc4_fluidId)) { switch (water->GetFluidPlane().GetFluidType()) { case EFluidType::NormalWater: x2b0_outOfWaterTicks = 0; @@ -2597,7 +2822,7 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState x82e_ridingPlatform = sender; break; case EScriptObjectMessage::Damage: - if (TCastToPtr energ = mgr.ObjectById(sender)) { + if (const TCastToConstPtr energ = mgr.ObjectById(sender)) { if (True(energ->GetAttribField() & EProjectileAttrib::StaticInterference)) { mgr.GetPlayerState()->GetStaticInterference().AddSource(GetUniqueId(), 0.3f, energ->GetInterferenceDuration()); } @@ -2623,21 +2848,23 @@ void CPlayer::SetVisorSteam(float targetAlpha, float alphaInDur, float alphaOutD void CPlayer::UpdateFootstepSounds(const CFinalInput& input, CStateManager& mgr, float dt) { if (x2f8_morphBallState != EPlayerMorphBallState::Unmorphed || x258_movementState != EPlayerMovementState::OnGround || - x3dc_inFreeLook || x3dd_lookButtonHeld) + x3dc_inFreeLook || x3dd_lookButtonHeld) { return; + } float sfxVol = 1.f; x78c_footstepSfxTimer += dt; float turn = TurnInput(input); - float forward = std::fabs(ForwardInput(input, turn)); + const float forward = std::fabs(ForwardInput(input, turn)); turn = std::fabs(turn); float sfxDelay = 0.f; if (forward > 0.05f || x304_orbitState != EPlayerOrbitState::NoOrbit) { - float vel = std::min(1.f, x138_velocity.magnitude() / GetActualFirstPersonMaxVelocity(dt)); + const float vel = std::min(1.f, x138_velocity.magnitude() / GetActualFirstPersonMaxVelocity(dt)); if (vel > 0.05f) { sfxDelay = -0.475f * vel + 0.85f; - if (x790_footstepSfxSel == EFootstepSfx::None) + if (x790_footstepSfxSel == EFootstepSfx::None) { x790_footstepSfxSel = EFootstepSfx::Left; + } } else { x78c_footstepSfxTimer = 0.f; x790_footstepSfxSel = EFootstepSfx::None; @@ -2645,10 +2872,11 @@ void CPlayer::UpdateFootstepSounds(const CFinalInput& input, CStateManager& mgr, sfxVol = 0.3f * vel + 0.7f; } else if (turn > 0.05f) { - if (x790_footstepSfxSel == EFootstepSfx::Left) + if (x790_footstepSfxSel == EFootstepSfx::Left) { sfxDelay = -0.813f * turn + 1.f; - else + } else { sfxDelay = -2.438f * turn + 3.f; + } if (x790_footstepSfxSel == EFootstepSfx::None) { x790_footstepSfxSel = EFootstepSfx::Left; sfxDelay = x78c_footstepSfxTimer; @@ -2691,10 +2919,11 @@ void CPlayer::UpdateFootstepSounds(const CFinalInput& input, CStateManager& mgr, } x78c_footstepSfxTimer = 0.f; - if (x790_footstepSfxSel == EFootstepSfx::Left) + if (x790_footstepSfxSel == EFootstepSfx::Left) { x790_footstepSfxSel = EFootstepSfx::Right; - else + } else { x790_footstepSfxSel = EFootstepSfx::Left; + } } } @@ -2705,18 +2934,20 @@ u16 CPlayer::GetMaterialSoundUnderPlayer(const CStateManager& mgr, const u16* ta rstl::reserved_vector nearList; mgr.BuildNearList(nearList, aabb, SolidMaterialFilter, nullptr); TUniqueId collideId = kInvalidUniqueId; - CRayCastResult result = mgr.RayWorldIntersection(collideId, x34_transform.origin, zeus::skDown, 1.5f, - SolidMaterialFilter, nearList); - if (result.IsValid()) + const CRayCastResult result = + mgr.RayWorldIntersection(collideId, x34_transform.origin, zeus::skDown, 1.5f, SolidMaterialFilter, nearList); + if (result.IsValid()) { ret = SfxIdFromMaterial(result.GetMaterial(), table, length, defId); + } return ret; } u16 CPlayer::SfxIdFromMaterial(const CMaterialList& mat, const u16* idList, size_t tableLen, u16 defId) { u16 id = defId; for (size_t i = 0; i < tableLen; ++i) { - if (mat.HasMaterial(EMaterialTypes(i)) && idList[i] != 0xFFFF) + if (mat.HasMaterial(EMaterialTypes(i)) && idList[i] != 0xFFFF) { id = idList[i]; + } } return id; } @@ -2726,20 +2957,23 @@ void CPlayer::UpdateCrosshairsState(const CFinalInput& input) { } void CPlayer::UpdateVisorTransition(float dt, CStateManager& mgr) { - if (mgr.GetPlayerState()->GetIsVisorTransitioning()) + if (mgr.GetPlayerState()->GetIsVisorTransitioning()) { mgr.GetPlayerState()->UpdateVisorTransition(dt); + } } void CPlayer::UpdateVisorState(const CFinalInput& input, float dt, CStateManager& mgr) { x7a0_visorSteam.Update(dt); - if (x7a0_visorSteam.AffectsThermal()) + if (x7a0_visorSteam.AffectsThermal()) { mgr.SetThermalColdScale2(mgr.GetThermalColdScale2() + x7a0_visorSteam.GetAlpha()); + } if (x304_orbitState == EPlayerOrbitState::Grapple || TCastToPtr(mgr.ObjectById(x310_orbitTargetId)) || x2f8_morphBallState != EPlayerMorphBallState::Unmorphed || mgr.GetPlayerState()->GetIsVisorTransitioning() || - x3a8_scanState != EPlayerScanState::NotScanning) + x3a8_scanState != EPlayerScanState::NotScanning) { return; + } if (mgr.GetPlayerState()->GetTransitioningVisor() == CPlayerState::EPlayerVisor::Scan && (ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input) || @@ -2773,28 +3007,32 @@ void CPlayer::UpdateGunState(const CFinalInput& input, CStateManager& mgr) { case EGunHolsterState::Drawn: { bool needsHolster = false; if (g_tweakPlayer->GetGunButtonTogglesHolster()) { - if (ControlMapper::GetPressInput(ControlMapper::ECommands::ToggleHolster, input)) + if (ControlMapper::GetPressInput(ControlMapper::ECommands::ToggleHolster, input)) { needsHolster = true; + } if (!ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input) && !ControlMapper::GetDigitalInput(ControlMapper::ECommands::MissileOrPowerBomb, input) && g_tweakPlayer->GetGunNotFiringHolstersGun()) { x49c_gunHolsterRemTime -= input.DeltaTime(); - if (x49c_gunHolsterRemTime <= 0.f) + if (x49c_gunHolsterRemTime <= 0.f) { needsHolster = true; + } } } else { if (!ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input) && !ControlMapper::GetDigitalInput(ControlMapper::ECommands::MissileOrPowerBomb, input) && x490_gun->IsFidgeting()) { - if (g_tweakPlayer->GetGunNotFiringHolstersGun()) + if (g_tweakPlayer->GetGunNotFiringHolstersGun()) { x49c_gunHolsterRemTime -= input.DeltaTime(); + } } else { x49c_gunHolsterRemTime = g_tweakPlayerGun->GetGunNotFiringTime(); } } - if (needsHolster) + if (needsHolster) { HolsterGun(mgr); + } break; } case EGunHolsterState::Drawing: { @@ -2812,23 +3050,27 @@ void CPlayer::UpdateGunState(const CFinalInput& input, CStateManager& mgr) { ControlMapper::GetDigitalInput(ControlMapper::ECommands::MissileOrPowerBomb, input) || x3b8_grappleState == EGrappleState::None || (g_tweakPlayer->GetGunButtonTogglesHolster() && - ControlMapper::GetPressInput(ControlMapper::ECommands::ToggleHolster, input))) + ControlMapper::GetPressInput(ControlMapper::ECommands::ToggleHolster, input))) { needsDraw = true; + } if (x3b8_grappleState == EGrappleState::None && (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Scan || - mgr.GetPlayerState()->GetTransitioningVisor() == CPlayerState::EPlayerVisor::Scan)) + mgr.GetPlayerState()->GetTransitioningVisor() == CPlayerState::EPlayerVisor::Scan)) { needsDraw = false; + } - if (needsDraw) + if (needsDraw) { DrawGun(mgr); + } break; } case EGunHolsterState::Holstering: - if (x49c_gunHolsterRemTime > 0.f) + if (x49c_gunHolsterRemTime > 0.f) { x49c_gunHolsterRemTime -= input.DeltaTime(); - else + } else { x498_gunHolsterState = EGunHolsterState::Holstered; + } break; } } @@ -2887,20 +3129,25 @@ void CPlayer::UpdateCameraTimers(float dt, const CFinalInput& input) { } } - if (ControlMapper::GetPressInput(ControlMapper::ECommands::JumpOrBoost, input)) + if (ControlMapper::GetPressInput(ControlMapper::ECommands::JumpOrBoost, input)) { ++x298_jumpPresses; + } if (ControlMapper::GetDigitalInput(ControlMapper::ECommands::JumpOrBoost, input) && x294_jumpCameraTimer > 0.f && - !x2a4_cancelCameraPitch && x298_jumpPresses <= 2) + !x2a4_cancelCameraPitch && x298_jumpPresses <= 2) { x294_jumpCameraTimer += dt; + } - if (x29c_fallCameraTimer > 0.f && !x2a4_cancelCameraPitch) + if (x29c_fallCameraTimer > 0.f && !x2a4_cancelCameraPitch) { x29c_fallCameraTimer += dt; + } } void CPlayer::UpdateMorphBallState(float dt, const CFinalInput& input, CStateManager& mgr) { - if (!ControlMapper::GetPressInput(ControlMapper::ECommands::Morph, input)) + if (!ControlMapper::GetPressInput(ControlMapper::ECommands::Morph, input)) { return; + } + switch (x2f8_morphBallState) { case EPlayerMorphBallState::Unmorphed: if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::MorphBall) && CanEnterMorphBallState(mgr, 0.f)) { @@ -2935,22 +3182,23 @@ CFirstPersonCamera& CPlayer::GetFirstPersonCamera(CStateManager& mgr) { } void CPlayer::UpdateGunTransform(const zeus::CVector3f& gunPos, CStateManager& mgr) { - float eyeHeight = GetEyeHeight(); - zeus::CTransform camXf = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr); + const float eyeHeight = GetEyeHeight(); + const zeus::CTransform camXf = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr); zeus::CTransform gunXf = camXf; zeus::CVector3f viewGunPos; - if (x2f8_morphBallState == EPlayerMorphBallState::Morphing) + if (x2f8_morphBallState == EPlayerMorphBallState::Morphing) { viewGunPos = camXf * (gunPos - zeus::CVector3f(0.f, 0.f, eyeHeight)); - else + } else { viewGunPos = camXf.rotate(gunPos - zeus::CVector3f(0.f, 0.f, eyeHeight)) + GetEyePosition(); + } - zeus::CUnitVector3f rightDir(gunXf.basis[0]); + const zeus::CUnitVector3f rightDir(gunXf.basis[0]); gunXf.origin = viewGunPos; switch (x498_gunHolsterState) { case EGunHolsterState::Drawing: { - float liftAngle = zeus::clamp(-1.f, x49c_gunHolsterRemTime / 0.45f, 1.f); + const float liftAngle = zeus::clamp(-1.f, x49c_gunHolsterRemTime / 0.45f, 1.f); if (liftAngle > 0.01f) { gunXf = zeus::CQuaternion::fromAxisAngle(rightDir, -liftAngle * g_tweakPlayerGun->GetFixedVerticalAim()) .toTransform() * @@ -2967,8 +3215,9 @@ void CPlayer::UpdateGunTransform(const zeus::CVector3f& gunPos, CStateManager& m } case EGunHolsterState::Holstering: { float liftAngle = 1.f - zeus::clamp(-1.f, x49c_gunHolsterRemTime / g_tweakPlayerGun->GetGunHolsterTime(), 1.f); - if (x2f8_morphBallState == EPlayerMorphBallState::Morphing) + if (x2f8_morphBallState == EPlayerMorphBallState::Morphing) { liftAngle = 1.f - zeus::clamp(-1.f, x49c_gunHolsterRemTime / 0.1f, 1.f); + } if (liftAngle > 0.01f) { gunXf = zeus::CQuaternion::fromAxisAngle(rightDir, -liftAngle * g_tweakPlayerGun->GetFixedVerticalAim()) .toTransform() * @@ -2992,10 +3241,10 @@ void CPlayer::UpdateAssistedAiming(const zeus::CTransform& xf, const CStateManag zeus::CVector3f gunToTarget = x480_assistedTargetAim - xf.origin; zeus::CVector3f gunToTargetFlat = gunToTarget; gunToTargetFlat.z() = 0.f; - float gunToTargetFlatMag = gunToTargetFlat.magnitude(); + const float gunToTargetFlatMag = gunToTargetFlat.magnitude(); zeus::CVector3f gunDirFlat = xf.basis[1]; gunDirFlat.z() = 0.f; - float gunDirFlatMag = gunDirFlat.magnitude(); + const float gunDirFlatMag = gunDirFlat.magnitude(); if (gunToTargetFlat.canBeNormalized() && gunDirFlat.canBeNormalized()) { gunToTargetFlat = gunToTargetFlat / gunToTargetFlatMag; gunDirFlat = gunDirFlat / gunDirFlatMag; @@ -3012,7 +3261,7 @@ void CPlayer::UpdateAssistedAiming(const zeus::CTransform& xf, const CStateManag } } - bool targetToLeft = gunDirFlat.cross(gunToTargetFlat).z() > 0.f; + const bool targetToLeft = gunDirFlat.cross(gunToTargetFlat).z() > 0.f; float hAngleDelta = std::acos(zeus::clamp(-1.f, gunDirFlat.dot(gunToTargetFlat), 1.f)); bool hasHAngleDelta = true; if (!x9c6_27_aimingAtProjectile && std::fabs(hAngleDelta) > g_tweakPlayer->GetAimAssistHorizontalAngle()) { @@ -3043,49 +3292,66 @@ void CPlayer::UpdateAssistedAiming(const zeus::CTransform& xf, const CStateManag } void CPlayer::UpdateAimTargetPrediction(const zeus::CTransform& xf, const CStateManager& mgr) { - if (x3f4_aimTarget != kInvalidUniqueId) { - if (TCastToConstPtr target = mgr.GetObjectById(x3f4_aimTarget)) { - x9c6_27_aimingAtProjectile = TCastToConstPtr(target.GetPtr()); - zeus::CVector3f instantTarget = target->GetAimPosition(mgr, 0.f); - zeus::CVector3f gunToTarget = instantTarget - xf.origin; - float timeToTarget = gunToTarget.magnitude() / x490_gun->GetBeamVelocity(); - zeus::CVector3f predictTarget = target->GetAimPosition(mgr, timeToTarget); - zeus::CVector3f predictOffset = predictTarget - instantTarget; - x3f8_targetAimPosition = instantTarget; - if (predictOffset.magnitude() < 0.1f) - x404_aimTargetAverage.AddValue(zeus::skZero3f); - else - x404_aimTargetAverage.AddValue(predictOffset); - if (auto avg = x404_aimTargetAverage.GetAverage()) - x480_assistedTargetAim = instantTarget + *avg; - else - x480_assistedTargetAim = predictTarget; - } + if (x3f4_aimTarget == kInvalidUniqueId) { + return; + } + + const TCastToConstPtr target = mgr.GetObjectById(x3f4_aimTarget); + if (!target) { + return; + } + + x9c6_27_aimingAtProjectile = TCastToConstPtr(target.GetPtr()); + const zeus::CVector3f instantTarget = target->GetAimPosition(mgr, 0.f); + const zeus::CVector3f gunToTarget = instantTarget - xf.origin; + const float timeToTarget = gunToTarget.magnitude() / x490_gun->GetBeamVelocity(); + const zeus::CVector3f predictTarget = target->GetAimPosition(mgr, timeToTarget); + const zeus::CVector3f predictOffset = predictTarget - instantTarget; + x3f8_targetAimPosition = instantTarget; + + if (predictOffset.magnitude() < 0.1f) { + x404_aimTargetAverage.AddValue(zeus::skZero3f); + } else { + x404_aimTargetAverage.AddValue(predictOffset); + } + + if (auto avg = x404_aimTargetAverage.GetAverage()) { + x480_assistedTargetAim = instantTarget + *avg; + } else { + x480_assistedTargetAim = predictTarget; } } void CPlayer::ResetAimTargetPrediction(TUniqueId target) { - if (target == kInvalidUniqueId || x3f4_aimTarget != target) + if (target == kInvalidUniqueId || x3f4_aimTarget != target) { x404_aimTargetAverage.Clear(); + } x3f4_aimTarget = target; } void CPlayer::DrawGun(CStateManager& mgr) { - if (x498_gunHolsterState != EGunHolsterState::Holstered || InGrappleJumpCooldown()) + if (x498_gunHolsterState != EGunHolsterState::Holstered || InGrappleJumpCooldown()) { return; + } + x498_gunHolsterState = EGunHolsterState::Drawing; x49c_gunHolsterRemTime = 0.45f; x490_gun->ResetIdle(mgr); } void CPlayer::HolsterGun(CStateManager& mgr) { - if (x498_gunHolsterState == EGunHolsterState::Holstered || x498_gunHolsterState == EGunHolsterState::Holstering) + if (x498_gunHolsterState == EGunHolsterState::Holstered || x498_gunHolsterState == EGunHolsterState::Holstering) { return; - float time = x2f8_morphBallState == EPlayerMorphBallState::Morphing ? 0.1f : g_tweakPlayerGun->GetGunHolsterTime(); - if (x498_gunHolsterState == EGunHolsterState::Drawing) + } + + const float time = + x2f8_morphBallState == EPlayerMorphBallState::Morphing ? 0.1f : g_tweakPlayerGun->GetGunHolsterTime(); + if (x498_gunHolsterState == EGunHolsterState::Drawing) { x49c_gunHolsterRemTime = time * (1.f - x49c_gunHolsterRemTime / 0.45f); - else + } else { x49c_gunHolsterRemTime = time; + } + x498_gunHolsterState = EGunHolsterState::Holstering; x490_gun->CancelFiring(mgr); ResetAimTargetPrediction(kInvalidUniqueId); @@ -3105,6 +3371,7 @@ void CPlayer::UpdateGrappleArmTransform(const zeus::CVector3f& offset, CStateMan zeus::CTransform armXf = x34_transform; zeus::CVector3f armPosition = x34_transform.rotate(offset) + x34_transform.origin; armXf.origin = armPosition; + if (x2f8_morphBallState != EPlayerMorphBallState::Unmorphed) { x490_gun->GetGrappleArm().SetTransform(armXf); } else if (!x490_gun->GetGrappleArm().IsArmMoving()) { @@ -3113,18 +3380,21 @@ void CPlayer::UpdateGrappleArmTransform(const zeus::CVector3f& offset, CStateMan if (lookDir.canBeNormalized()) { lookDir.normalize(); if (x3b8_grappleState != EGrappleState::None) { - if (TCastToPtr target = mgr.ObjectById(x310_orbitTargetId)) { + if (const TCastToConstPtr target = mgr.ObjectById(x310_orbitTargetId)) { armToTarget = target->GetTranslation() - armPosition; zeus::CVector3f armToTargetFlat = armToTarget; armToTargetFlat.z() = 0.f; - if (armToTarget.canBeNormalized()) + if (armToTarget.canBeNormalized()) { armToTarget.normalize(); + } if (armToTargetFlat.canBeNormalized() && x3b8_grappleState != EGrappleState::Firing) { - zeus::CQuaternion adjRot = zeus::CQuaternion::lookAt(armToTargetFlat.normalized(), lookDir, 2.f * M_PIF); + const zeus::CQuaternion adjRot = + zeus::CQuaternion::lookAt(armToTargetFlat.normalized(), lookDir, 2.f * M_PIF); armToTarget = adjRot.transform(armToTarget); if (x3bc_grappleSwingTimer >= 0.25f * g_tweakPlayer->GetGrappleSwingPeriod() && - x3bc_grappleSwingTimer < 0.75f * g_tweakPlayer->GetGrappleSwingPeriod()) + x3bc_grappleSwingTimer < 0.75f * g_tweakPlayer->GetGrappleSwingPeriod()) { armToTarget = x490_gun->GetGrappleArm().GetTransform().basis[1]; + } } } } @@ -3136,27 +3406,31 @@ void CPlayer::UpdateGrappleArmTransform(const zeus::CVector3f& offset, CStateMan } float CPlayer::GetGravity() const { - if (!g_GameState->GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit) && CheckSubmerged()) + if (!g_GameState->GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit) && CheckSubmerged()) { return g_tweakPlayer->GetFluidGravAccel(); - if (x37c_sidewaysDashing) + } + + if (x37c_sidewaysDashing) { return -100.f; + } + return g_tweakPlayer->GetNormalGravAccel(); } void CPlayer::ApplyGrappleForces(const CFinalInput& input, CStateManager& mgr, float dt) { - if (TCastToPtr point = mgr.ObjectById(x310_orbitTargetId)) { + if (const TCastToConstPtr point = mgr.ObjectById(x310_orbitTargetId)) { switch (x3b8_grappleState) { case EGrappleState::Pull: { - zeus::CVector3f playerToPoint = point->GetTranslation() - GetTranslation(); + const zeus::CVector3f playerToPoint = point->GetTranslation() - GetTranslation(); if (playerToPoint.canBeNormalized()) { zeus::CVector3f playerToSwingLow = point->GetTranslation() + zeus::CVector3f(0.f, 0.f, -g_tweakPlayer->GetGrappleSwingLength()) - GetTranslation(); if (playerToSwingLow.canBeNormalized()) { - float distToSwingLow = playerToSwingLow.magnitude(); + const float distToSwingLow = playerToSwingLow.magnitude(); playerToSwingLow.normalize(); - float timeToLow = zeus::clamp(-1.f, distToSwingLow / g_tweakPlayer->GetGrapplePullSpeedProportion(), 1.f); - float pullSpeed = + const float timeToLow = zeus::clamp(-1.f, distToSwingLow / g_tweakPlayer->GetGrapplePullSpeedProportion(), 1.f); + const float pullSpeed = timeToLow * (g_tweakPlayer->GetGrapplePullSpeedMax() - g_tweakPlayer->GetGrapplePullSpeedMin()) + g_tweakPlayer->GetGrapplePullSpeedMin(); SetVelocityWR(playerToSwingLow * pullSpeed); @@ -3167,24 +3441,28 @@ void CPlayer::ApplyGrappleForces(const CFinalInput& input, CStateManager& mgr, f x3d8_grappleJumpTimeout = 0.f; x9c6_28_aligningGrappleSwingTurn = point->GetGrappleParameters().GetLockSwingTurn(); } else { - CMotionState mState = PredictMotion(dt); + const CMotionState mState = PredictMotion(dt); zeus::CVector3f lookDirFlat = x34_transform.basis[1]; lookDirFlat.z() = 0.f; zeus::CVector3f newPlayerToPointFlat = point->GetTranslation() - (GetTranslation() + mState.x0_translation); newPlayerToPointFlat.z() = 0.f; - if (lookDirFlat.canBeNormalized()) + if (lookDirFlat.canBeNormalized()) { lookDirFlat.normalize(); - if (newPlayerToPointFlat.canBeNormalized()) + } + if (newPlayerToPointFlat.canBeNormalized()) { newPlayerToPointFlat.normalize(); - float lookToPointAngle = std::acos(zeus::clamp(-1.f, lookDirFlat.dot(newPlayerToPointFlat), 1.f)); + } + const float lookToPointAngle = std::acos(zeus::clamp(-1.f, lookDirFlat.dot(newPlayerToPointFlat), 1.f)); if (lookToPointAngle > 0.001f) { float deltaAngle = dt * g_tweakPlayer->GetGrappleLookCenterSpeed(); if (lookToPointAngle >= deltaAngle) { zeus::CVector3f leftDirFlat(lookDirFlat.y(), -lookDirFlat.x(), 0.f); - if (leftDirFlat.canBeNormalized()) + if (leftDirFlat.canBeNormalized()) { leftDirFlat.normalize(); - if (newPlayerToPointFlat.dot(leftDirFlat) >= 0.f) + } + if (newPlayerToPointFlat.dot(leftDirFlat) >= 0.f) { deltaAngle = -deltaAngle; + } RotateToOR(zeus::CQuaternion::fromAxisAngle(zeus::skUp, deltaAngle), dt); } else if (std::fabs(lookToPointAngle - M_PIF) > 0.001f) { RotateToOR(zeus::CQuaternion::shortestRotationArc(lookDirFlat, newPlayerToPointFlat), dt); @@ -3204,10 +3482,11 @@ void CPlayer::ApplyGrappleForces(const CFinalInput& input, CStateManager& mgr, f } case EGrappleState::Swinging: { float turnAngleSpeed = zeus::degToRad(g_tweakPlayer->GetMaxGrappleTurnSpeed()); - if (g_tweakPlayer->GetInvertGrappleTurn()) + if (g_tweakPlayer->GetInvertGrappleTurn()) { turnAngleSpeed *= -1.f; - zeus::CVector3f pointToPlayer = GetTranslation() - point->GetTranslation(); - float pointToPlayerZProj = zeus::clamp(-1.f, std::fabs(pointToPlayer.z() / pointToPlayer.magnitude()), 1.f); + } + const zeus::CVector3f pointToPlayer = GetTranslation() - point->GetTranslation(); + const float pointToPlayerZProj = zeus::clamp(-1.f, std::fabs(pointToPlayer.z() / pointToPlayer.magnitude()), 1.f); bool enableTurn = false; if (!point->GetGrappleParameters().GetLockSwingTurn()) { @@ -3224,14 +3503,16 @@ void CPlayer::ApplyGrappleForces(const CFinalInput& input, CStateManager& mgr, f } x3bc_grappleSwingTimer += dt; - if (x3bc_grappleSwingTimer > g_tweakPlayer->GetGrappleSwingPeriod()) + if (x3bc_grappleSwingTimer > g_tweakPlayer->GetGrappleSwingPeriod()) { x3bc_grappleSwingTimer -= g_tweakPlayer->GetGrappleSwingPeriod(); + } zeus::CVector3f swingAxis = x3c0_grappleSwingAxis; - if (x3bc_grappleSwingTimer < 0.5f * g_tweakPlayer->GetGrappleSwingPeriod()) + if (x3bc_grappleSwingTimer < 0.5f * g_tweakPlayer->GetGrappleSwingPeriod()) { swingAxis *= zeus::skNegOne3f; + } - float pullSpeed = + const float pullSpeed = std::fabs(zeus::clamp( -1.f, std::cos(2.f * M_PIF * (x3bc_grappleSwingTimer / g_tweakPlayer->GetGrappleSwingPeriod()) + (M_PIF / 2.f)), @@ -3244,43 +3525,48 @@ void CPlayer::ApplyGrappleForces(const CFinalInput& input, CStateManager& mgr, f g_tweakPlayer->GetGrappleSwingLength(), 1.f) * -32.f * pointToPlayerZProj; - zeus::CVector3f backupVel = x138_velocity; + const zeus::CVector3f backupVel = x138_velocity; SetVelocityWR(pullVec); - zeus::CTransform backupXf = x34_transform; - CMotionState predMotion = PredictMotion(dt); - zeus::CVector3f newPos = x34_transform.origin + predMotion.x0_translation; + const zeus::CTransform backupXf = x34_transform; + const CMotionState predMotion = PredictMotion(dt); + const zeus::CVector3f newPos = x34_transform.origin + predMotion.x0_translation; if (ValidateFPPosition(newPos, mgr)) { if (enableTurn) { zeus::CQuaternion turnRot; turnRot.rotateZ(turnAngleSpeed * dt); if (point->GetGrappleParameters().GetLockSwingTurn() && x9c6_28_aligningGrappleSwingTurn) { zeus::CVector3f pointDir = point->GetTransform().basis[1].normalized(); - zeus::CVector3f playerDir = x34_transform.basis[1].normalized(); + const zeus::CVector3f playerDir = x34_transform.basis[1].normalized(); float playerPointProj = zeus::clamp(-1.f, playerDir.dot(pointDir), 1.f); - if (std::fabs(playerPointProj) == 1.f) + if (std::fabs(playerPointProj) == 1.f) { x9c6_28_aligningGrappleSwingTurn = false; + } if (playerPointProj < 0.f) { playerPointProj = -playerPointProj; pointDir = -pointDir; } - float turnAngleAdj = std::acos(playerPointProj) * dt; + + const float turnAngleAdj = std::acos(playerPointProj) * dt; turnRot = zeus::CQuaternion::lookAt(playerDir, pointDir, turnAngleAdj); } + if (pointToPlayer.magSquared() > 0.04f) { zeus::CVector3f pointToPlayerFlat = pointToPlayer; pointToPlayerFlat.z() = 0.f; zeus::CVector3f pointAtPlayerHeight = point->GetTranslation(); pointAtPlayerHeight.z() = GetTranslation().z(); - zeus::CVector3f playerToGrapplePlane = + const zeus::CVector3f playerToGrapplePlane = pointAtPlayerHeight + turnRot.transform(pointToPlayerFlat) - GetTranslation(); - if (playerToGrapplePlane.canBeNormalized()) + if (playerToGrapplePlane.canBeNormalized()) { pullVec += playerToGrapplePlane / dt; + } } - zeus::CVector3f swingAxisBackup = x3c0_grappleSwingAxis; + + const zeus::CVector3f swingAxisBackup = x3c0_grappleSwingAxis; x3c0_grappleSwingAxis = turnRot.transform(x3c0_grappleSwingAxis); x3c0_grappleSwingAxis.normalize(); - zeus::CVector3f swingForward(-x3c0_grappleSwingAxis.y(), x3c0_grappleSwingAxis.x(), 0.f); + const zeus::CVector3f swingForward(-x3c0_grappleSwingAxis.y(), x3c0_grappleSwingAxis.x(), 0.f); SetTransform(zeus::CTransform(x3c0_grappleSwingAxis, swingForward, zeus::skUp, GetTranslation())); SetVelocityWR(pullVec); @@ -3296,7 +3582,7 @@ void CPlayer::ApplyGrappleForces(const CFinalInput& input, CStateManager& mgr, f break; } case EGrappleState::JumpOff: { - zeus::CVector3f gravForce = {0.f, 0.f, GetGravity() * xe8_mass}; + const zeus::CVector3f gravForce = {0.f, 0.f, GetGravity() * xe8_mass}; ApplyForceOR(gravForce, zeus::CAxisAngle()); break; } @@ -3305,16 +3591,16 @@ void CPlayer::ApplyGrappleForces(const CFinalInput& input, CStateManager& mgr, f } } - zeus::CVector3f newAngVel = {0.f, 0.f, 0.9f * GetAngularVelocityOR().getVector().z()}; + const zeus::CVector3f newAngVel = {0.f, 0.f, 0.9f * GetAngularVelocityOR().getVector().z()}; SetAngularVelocityOR(newAngVel); } bool CPlayer::ValidateFPPosition(const zeus::CVector3f& pos, const CStateManager& mgr) const { - CMaterialFilter solidFilter = CMaterialFilter::MakeInclude({EMaterialTypes::Solid}); - zeus::CAABox aabb(x2d8_fpBounds.min - 1.f + pos, x2d8_fpBounds.max + 1.f + pos); + constexpr CMaterialFilter solidFilter = CMaterialFilter::MakeInclude({EMaterialTypes::Solid}); + const zeus::CAABox aabb(x2d8_fpBounds.min - 1.f + pos, x2d8_fpBounds.max + 1.f + pos); rstl::reserved_vector nearList; mgr.BuildColliderList(nearList, *this, aabb); - CCollidableAABox colAABB({GetBaseBoundingBox().min + pos, GetBaseBoundingBox().max + pos}, {}); + const CCollidableAABox colAABB({GetBaseBoundingBox().min + pos, GetBaseBoundingBox().max + pos}, {}); return !CGameCollision::DetectCollisionBoolean(mgr, colAABB, zeus::CTransform(), solidFilter, nearList); } @@ -3322,8 +3608,9 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr) { if (!mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GrappleBeam) || x2f8_morphBallState == EPlayerMorphBallState::Morphed || mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Scan || - mgr.GetPlayerState()->GetTransitioningVisor() == CPlayerState::EPlayerVisor::Scan) + mgr.GetPlayerState()->GetTransitioningVisor() == CPlayerState::EPlayerVisor::Scan) { return; + } if (x310_orbitTargetId == kInvalidUniqueId) { x3b8_grappleState = EGrappleState::None; @@ -3331,9 +3618,9 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr) { return; } - TCastToPtr point = mgr.ObjectById(x310_orbitTargetId); + const TCastToConstPtr point = mgr.ObjectById(x310_orbitTargetId); if (point) { - zeus::CVector3f eyePosition = GetEyePosition(); + const zeus::CVector3f eyePosition = GetEyePosition(); zeus::CVector3f playerToPoint = point->GetTranslation() - eyePosition; zeus::CVector3f playerToPointFlat = playerToPoint; playerToPointFlat.z() = 0.f; @@ -3344,7 +3631,7 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr) { case 0: case 1: if (ControlMapper::GetPressInput(ControlMapper::ECommands::FireOrBomb, input)) { - if (TCastToPtr point2 = mgr.ObjectById(x33c_orbitNextTargetId)) { + if (const TCastToConstPtr point2 = mgr.ObjectById(x33c_orbitNextTargetId)) { playerToPoint = point2->GetTranslation() - eyePosition; playerToPoint.z() = 0.f; if (playerToPoint.canBeNormalized()) { @@ -3359,8 +3646,9 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr) { x490_gun->GetGrappleArm().GrappleBeamConnected(); } } else { - if (g_tweakPlayer->GetGrappleJumpMode() == 0 && x3d8_grappleJumpTimeout <= 0.f) + if (g_tweakPlayer->GetGrappleJumpMode() == 0 && x3d8_grappleJumpTimeout <= 0.f) { ApplyGrappleJump(mgr); + } BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr); } } @@ -3372,8 +3660,8 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr) { break; case EPlayerOrbitState::OrbitObject: if (playerToPoint.canBeNormalized()) { - CRayCastResult result = mgr.RayStaticIntersection(eyePosition, playerToPoint.normalized(), - playerToPoint.magnitude(), LineOfSightFilter); + const CRayCastResult result = mgr.RayStaticIntersection(eyePosition, playerToPoint.normalized(), + playerToPoint.magnitude(), LineOfSightFilter); if (result.IsInvalid()) { HolsterGun(mgr); switch (x3b8_grappleState) { @@ -3383,8 +3671,9 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr) { case 0: switch (x490_gun->GetGrappleArm().GetAnimState()) { case CGrappleArm::EArmState::IntoGrappleIdle: - if (ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input)) + if (ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input)) { x490_gun->GetGrappleArm().SetAnimState(CGrappleArm::EArmState::FireGrapple); + } break; case CGrappleArm::EArmState::Connected: BeginGrapple(playerToPoint, mgr); @@ -3441,10 +3730,12 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr) { } if (x304_orbitState != EPlayerOrbitState::Grapple) { - if (x304_orbitState >= EPlayerOrbitState::Grapple) + if (x304_orbitState >= EPlayerOrbitState::Grapple) { return; - if (x304_orbitState != EPlayerOrbitState::OrbitObject) + } + if (x304_orbitState != EPlayerOrbitState::OrbitObject) { return; + } } else { if (!point) { BreakGrapple(EPlayerOrbitRequest::Default, mgr); @@ -3484,8 +3775,9 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr) { break; case EGrappleState::Firing: case EGrappleState::Pull: - if (!ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input)) + if (!ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input)) { BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr); + } break; default: break; @@ -3495,10 +3787,10 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr) { break; } - zeus::CVector3f eyePos = GetEyePosition(); - zeus::CVector3f playerToPoint = point->GetTranslation() - eyePos; + const zeus::CVector3f eyePos = GetEyePosition(); + const zeus::CVector3f playerToPoint = point->GetTranslation() - eyePos; if (playerToPoint.canBeNormalized()) { - CRayCastResult result = + const CRayCastResult result = mgr.RayStaticIntersection(eyePos, playerToPoint.normalized(), playerToPoint.magnitude(), LineOfSightFilter); if (result.IsValid()) { BreakGrapple(EPlayerOrbitRequest::LostGrappleLineOfSight, mgr); @@ -3508,23 +3800,30 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr) { } if (x490_gun->GetGrappleArm().BeamActive() && g_tweakPlayer->GetGrappleJumpMode() == 1 && - !ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input)) + !ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input)) { BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr); + } } void CPlayer::ApplyGrappleJump(CStateManager& mgr) { - if (TCastToPtr point = mgr.ObjectById(x310_orbitTargetId)) { - zeus::CVector3f tmp = x3c0_grappleSwingAxis; - if (x3bc_grappleSwingTimer < 0.5f * g_tweakPlayer->GetGrappleSwingPeriod()) - tmp *= zeus::skNegOne3f; - zeus::CVector3f pointToPlayer = GetTranslation() - point->GetTranslation(); - zeus::CVector3f cross = pointToPlayer.normalized().cross(tmp); - zeus::CVector3f pointToPlayerFlat(pointToPlayer.x(), pointToPlayer.y(), 0.f); - float dot = 1.f; - if (pointToPlayerFlat.canBeNormalized() && cross.canBeNormalized()) - dot = zeus::clamp(-1.f, std::fabs(cross.normalized().dot(pointToPlayerFlat.normalized())), 1.f); - ApplyForceWR(g_tweakPlayer->GetGrappleJumpForce() * cross * 10000.f * dot, zeus::CAxisAngle()); + const TCastToConstPtr point = mgr.ObjectById(x310_orbitTargetId); + + if (!point) { + return; } + + zeus::CVector3f tmp = x3c0_grappleSwingAxis; + if (x3bc_grappleSwingTimer < 0.5f * g_tweakPlayer->GetGrappleSwingPeriod()) { + tmp *= zeus::skNegOne3f; + } + const zeus::CVector3f pointToPlayer = GetTranslation() - point->GetTranslation(); + const zeus::CVector3f cross = pointToPlayer.normalized().cross(tmp); + const zeus::CVector3f pointToPlayerFlat(pointToPlayer.x(), pointToPlayer.y(), 0.f); + float dot = 1.f; + if (pointToPlayerFlat.canBeNormalized() && cross.canBeNormalized()) { + dot = zeus::clamp(-1.f, std::fabs(cross.normalized().dot(pointToPlayerFlat.normalized())), 1.f); + } + ApplyForceWR(g_tweakPlayer->GetGrappleJumpForce() * cross * 10000.f * dot, zeus::CAxisAngle()); } void CPlayer::BeginGrapple(zeus::CVector3f& vec, CStateManager& mgr) { @@ -3552,8 +3851,9 @@ void CPlayer::BreakGrapple(EPlayerOrbitRequest req, CStateManager& mgr) { x3b8_grappleState = EGrappleState::None; AddMaterial(EMaterialTypes::GroundCollider, mgr); x490_gun->GetGrappleArm().SetAnimState(CGrappleArm::EArmState::OutOfGrapple); - if (!InGrappleJumpCooldown() && x3b8_grappleState != EGrappleState::JumpOff) + if (!InGrappleJumpCooldown() && x3b8_grappleState != EGrappleState::JumpOff) { DrawGun(mgr); + } } void CPlayer::SetOrbitRequest(EPlayerOrbitRequest req, CStateManager& mgr) { @@ -3587,8 +3887,9 @@ void CPlayer::SetOrbitRequestForTarget(TUniqueId id, EPlayerOrbitRequest req, CS } bool CPlayer::InGrappleJumpCooldown() const { - if (x258_movementState == EPlayerMovementState::OnGround) + if (x258_movementState == EPlayerMovementState::OnGround) { return false; + } return x3d8_grappleJumpTimeout > 0.f || x294_jumpCameraTimer == 0.f; } @@ -3599,10 +3900,12 @@ void CPlayer::PreventFallingCameraPitch() { } void CPlayer::OrbitCarcass(CStateManager& mgr) { - if (x304_orbitState == EPlayerOrbitState::OrbitObject) { - x308_orbitType = EPlayerOrbitType::Default; - SetOrbitState(EPlayerOrbitState::OrbitCarcass, mgr); + if (x304_orbitState != EPlayerOrbitState::OrbitObject) { + return; } + + x308_orbitType = EPlayerOrbitType::Default; + SetOrbitState(EPlayerOrbitState::OrbitCarcass, mgr); } void CPlayer::OrbitPoint(EPlayerOrbitType type, CStateManager& mgr) { @@ -3622,19 +3925,21 @@ void CPlayer::SetOrbitState(EPlayerOrbitState state, CStateManager& mgr) { case EPlayerOrbitState::OrbitObject: #ifndef NDEBUG if (x310_orbitTargetId != kInvalidUniqueId) { - if (const CEntity* ent = mgr.GetObjectById(x310_orbitTargetId)) + if (const CEntity* ent = mgr.GetObjectById(x310_orbitTargetId)) { Log.report(logvisor::Info, fmt("Orbiting {} {}"), ent->GetEditorId(), ent->GetName()); + } } #endif cam->SetLockCamera(false); break; case EPlayerOrbitState::OrbitCarcass: { cam->SetLockCamera(true); - zeus::CVector3f playerToPoint = x314_orbitPoint - GetTranslation(); - if (playerToPoint.canBeNormalized()) + const zeus::CVector3f playerToPoint = x314_orbitPoint - GetTranslation(); + if (playerToPoint.canBeNormalized()) { x340_ = playerToPoint.magnitude(); - else + } else { x340_ = 0.f; + } SetOrbitTargetId(kInvalidUniqueId, mgr); x33c_orbitNextTargetId = kInvalidUniqueId; break; @@ -3663,8 +3968,9 @@ void CPlayer::SetOrbitTargetId(TUniqueId id, CStateManager& mgr) { } x310_orbitTargetId = id; - if (x310_orbitTargetId == kInvalidUniqueId) + if (x310_orbitTargetId == kInvalidUniqueId) { x374_orbitLockEstablished = false; + } } void CPlayer::UpdateOrbitPosition(float dist, CStateManager& mgr) { @@ -3676,9 +3982,11 @@ void CPlayer::UpdateOrbitPosition(float dist, CStateManager& mgr) { case EPlayerOrbitState::OrbitObject: case EPlayerOrbitState::ForcedOrbitObject: case EPlayerOrbitState::Grapple: - if (TCastToPtr act = mgr.ObjectById(x310_orbitTargetId)) - if (x310_orbitTargetId != kInvalidUniqueId) + if (const TCastToConstPtr act = mgr.ObjectById(x310_orbitTargetId)) { + if (x310_orbitTargetId != kInvalidUniqueId) { x314_orbitPoint = act->GetOrbitPosition(mgr); + } + } break; default: break; @@ -3686,10 +3994,15 @@ void CPlayer::UpdateOrbitPosition(float dist, CStateManager& mgr) { } void CPlayer::UpdateOrbitZPosition() { - if (x304_orbitState == EPlayerOrbitState::OrbitPoint) { - if (std::fabs(x320_orbitVector.z()) < g_tweakPlayer->GetOrbitZRange()) - x314_orbitPoint.z() = x320_orbitVector.z() + x34_transform.origin.z() + GetEyeHeight(); + if (x304_orbitState != EPlayerOrbitState::OrbitPoint) { + return; } + + if (std::fabs(x320_orbitVector.z()) >= g_tweakPlayer->GetOrbitZRange()) { + return; + } + + x314_orbitPoint.z() = x320_orbitVector.z() + x34_transform.origin.z() + GetEyeHeight(); } void CPlayer::UpdateOrbitFixedPosition() { @@ -3698,19 +4011,24 @@ void CPlayer::UpdateOrbitFixedPosition() { void CPlayer::SetOrbitPosition(float dist, CStateManager& mgr) { zeus::CTransform camXf = GetFirstPersonCameraTransform(mgr); - if (x304_orbitState == EPlayerOrbitState::OrbitPoint && x30c_orbitRequest == EPlayerOrbitRequest::BadVerticalAngle) + if (x304_orbitState == EPlayerOrbitState::OrbitPoint && x30c_orbitRequest == EPlayerOrbitRequest::BadVerticalAngle) { camXf = x34_transform; - zeus::CVector3f fwd = camXf.basis[1]; + } + + const zeus::CVector3f fwd = camXf.basis[1]; float dot = fwd.normalized().dot(fwd); - if (std::fabs(dot) > 1.f) + if (std::fabs(dot) > 1.f) { dot = (dot > 0.f) ? 1.f : -1.f; + } + x314_orbitPoint = camXf.rotate(zeus::CVector3f(0.f, dist / dot, 0.f)) + camXf.origin; x320_orbitVector = zeus::CVector3f(0.f, dist, x314_orbitPoint.z() - camXf.origin.z()); } void CPlayer::UpdateAimTarget(CStateManager& mgr) { - if (!ValidateAimTargetId(x3f4_aimTarget, mgr)) + if (!ValidateAimTargetId(x3f4_aimTarget, mgr)) { ResetAimTargetPrediction(kInvalidUniqueId); + } if (!GetCombatMode()) { ResetAimTargetPrediction(kInvalidUniqueId); @@ -3724,47 +4042,60 @@ void CPlayer::UpdateAimTarget(CStateManager& mgr) { ResetAimTargetPrediction(kInvalidUniqueId); x48c_aimTargetTimer = 0.f; if (x304_orbitState == EPlayerOrbitState::One || - x304_orbitState == EPlayerOrbitState::Four) - if (!ValidateOrbitTargetId(x310_orbitTargetId, mgr)) + x304_orbitState == EPlayerOrbitState::Four) { + if (!ValidateOrbitTargetId(x310_orbitTargetId, mgr)) { ResetAimTargetPrediction(x310_orbitTargetId); + } + } return; } #endif bool needsReset = false; - TCastToPtr act = mgr.ObjectById(x3f4_aimTarget); - CActor* actp = act.GetPtr(); - if (act) - if (!act->GetMaterialList().HasMaterial(EMaterialTypes::Target)) + const TCastToConstPtr act = mgr.ObjectById(x3f4_aimTarget); + const CActor* actp = act.GetPtr(); + if (act) { + if (!act->GetMaterialList().HasMaterial(EMaterialTypes::Target)) { actp = nullptr; + } + } if (g_tweakPlayer->GetAimWhenOrbitingPoint()) { if (x304_orbitState == EPlayerOrbitState::OrbitObject || x304_orbitState == EPlayerOrbitState::ForcedOrbitObject) { - if (ValidateOrbitTargetId(x310_orbitTargetId, mgr) == EOrbitValidationResult::OK) + if (ValidateOrbitTargetId(x310_orbitTargetId, mgr) == EOrbitValidationResult::OK) { ResetAimTargetPrediction(x310_orbitTargetId); - else + } else { needsReset = true; + } } else { needsReset = true; } } else { - if (x304_orbitState == EPlayerOrbitState::NoOrbit) + if (x304_orbitState == EPlayerOrbitState::NoOrbit) { needsReset = true; + } } - if (needsReset) { - if (actp && ValidateObjectForMode(x3f4_aimTarget, mgr)) - ResetAimTargetPrediction(kInvalidUniqueId); - else - ResetAimTargetPrediction(FindAimTargetId(mgr)); + if (!needsReset) { + return; + } + + if (actp && ValidateObjectForMode(x3f4_aimTarget, mgr)) { + ResetAimTargetPrediction(kInvalidUniqueId); + } else { + ResetAimTargetPrediction(FindAimTargetId(mgr)); } } void CPlayer::UpdateAimTargetTimer(float dt) { - if (x3f4_aimTarget == kInvalidUniqueId) + if (x3f4_aimTarget == kInvalidUniqueId) { return; - if (x48c_aimTargetTimer <= 0.f) + } + + if (x48c_aimTargetTimer <= 0.f) { return; + } + x48c_aimTargetTimer -= dt; } @@ -3775,9 +4106,10 @@ bool CPlayer::ValidateAimTargetId(TUniqueId uid, CStateManager& mgr) { return false; } - TCastToPtr act = mgr.ObjectById(uid); - if (!act || !act->GetMaterialList().HasMaterial(EMaterialTypes::Target) || !act->GetIsTargetable()) + const TCastToConstPtr act = mgr.ObjectById(uid); + if (!act || !act->GetMaterialList().HasMaterial(EMaterialTypes::Target) || !act->GetIsTargetable()) { return false; + } if (x304_orbitState == EPlayerOrbitState::OrbitObject || x304_orbitState == EPlayerOrbitState::ForcedOrbitObject) { if (ValidateOrbitTargetId(x310_orbitTargetId, mgr) != EOrbitValidationResult::OK) { @@ -3790,24 +4122,24 @@ bool CPlayer::ValidateAimTargetId(TUniqueId uid, CStateManager& mgr) { if (act->GetMaterialList().HasMaterial(EMaterialTypes::Target) && uid != kInvalidUniqueId && ValidateObjectForMode(uid, mgr)) { - float vpWHalf = g_Viewport.x8_width / 2; - float vpHHalf = g_Viewport.xc_height / 2; - zeus::CVector3f aimPos = act->GetAimPosition(mgr, 0.f); - zeus::CVector3f eyePos = GetEyePosition(); + const float vpWHalf = g_Viewport.x8_width / 2; + const float vpHHalf = g_Viewport.xc_height / 2; + const zeus::CVector3f aimPos = act->GetAimPosition(mgr, 0.f); + const zeus::CVector3f eyePos = GetEyePosition(); zeus::CVector3f eyeToAim = aimPos - eyePos; - zeus::CVector3f screenPos = mgr.GetCameraManager()->GetFirstPersonCamera()->ConvertToScreenSpace(aimPos); - zeus::CVector3f posInBox(vpWHalf + screenPos.x() * vpWHalf, vpHHalf + screenPos.y() * vpHHalf, screenPos.z()); + const zeus::CVector3f screenPos = mgr.GetCameraManager()->GetFirstPersonCamera()->ConvertToScreenSpace(aimPos); + const zeus::CVector3f posInBox(vpWHalf + screenPos.x() * vpWHalf, vpHHalf + screenPos.y() * vpHHalf, screenPos.z()); if (WithinOrbitScreenBox(posInBox, x330_orbitZoneMode, x334_orbitType) || (x330_orbitZoneMode != EPlayerZoneInfo::Targeting && WithinOrbitScreenBox(posInBox, EPlayerZoneInfo::Targeting, x334_orbitType))) { - float eyeToAimMag = eyeToAim.magnitude(); + const float eyeToAimMag = eyeToAim.magnitude(); if (eyeToAimMag <= g_tweakPlayer->GetAimMaxDistance()) { rstl::reserved_vector nearList; TUniqueId intersectId = kInvalidUniqueId; eyeToAim.normalize(); mgr.BuildNearList(nearList, eyePos, eyeToAim, eyeToAimMag, OccluderFilter, act); eyeToAim.normalize(); - CRayCastResult result = + const CRayCastResult result = mgr.RayWorldIntersection(intersectId, eyePos, eyeToAim, eyeToAimMag, LineOfSightFilter, nearList); if (result.IsInvalid()) { x48c_aimTargetTimer = g_tweakPlayer->GetAimTargetTimer(); @@ -3816,8 +4148,9 @@ bool CPlayer::ValidateAimTargetId(TUniqueId uid, CStateManager& mgr) { } } - if (x48c_aimTargetTimer > 0.f) + if (x48c_aimTargetTimer > 0.f) { return true; + } } ResetAimTargetPrediction(kInvalidUniqueId); @@ -3826,36 +4159,42 @@ bool CPlayer::ValidateAimTargetId(TUniqueId uid, CStateManager& mgr) { } bool CPlayer::ValidateObjectForMode(TUniqueId uid, CStateManager& mgr) const { - TCastToPtr act = mgr.ObjectById(uid); - if (!act || uid == kInvalidUniqueId) + const TCastToPtr act = mgr.ObjectById(uid); + if (!act || uid == kInvalidUniqueId) { return false; + } - if (TCastToPtr(mgr.ObjectById(uid))) + if (TCastToConstPtr(mgr.ObjectById(uid))) { return true; + } if (GetCombatMode()) { - if (CHealthInfo* hInfo = act->HealthInfo(mgr)) { - if (hInfo->GetHP() > 0.f) + if (const CHealthInfo* hInfo = act->HealthInfo(mgr)) { + if (hInfo->GetHP() > 0.f) { return true; + } } else { if (act->GetMaterialList().HasMaterial(EMaterialTypes::Projectile) || - act->GetMaterialList().HasMaterial(EMaterialTypes::Scannable)) + act->GetMaterialList().HasMaterial(EMaterialTypes::Scannable)) { return true; + } - if (TCastToPtr point = mgr.ObjectById(uid)) { - zeus::CVector3f playerToPoint = point->GetTranslation() - GetTranslation(); - if (playerToPoint.canBeNormalized() && playerToPoint.magnitude() < g_tweakPlayer->GetOrbitDistanceMax()) + if (const TCastToConstPtr point = mgr.ObjectById(uid)) { + const zeus::CVector3f playerToPoint = point->GetTranslation() - GetTranslation(); + if (playerToPoint.canBeNormalized() && playerToPoint.magnitude() < g_tweakPlayer->GetOrbitDistanceMax()) { return true; + } } } } if (GetExplorationMode()) { if (!act->HealthInfo(mgr)) { - if (TCastToPtr point = mgr.ObjectById(uid)) { - zeus::CVector3f playerToPoint = point->GetTranslation() - GetTranslation(); - if (playerToPoint.canBeNormalized() && playerToPoint.magnitude() < g_tweakPlayer->GetOrbitDistanceMax()) + if (const TCastToConstPtr point = mgr.ObjectById(uid)) { + const zeus::CVector3f playerToPoint = point->GetTranslation() - GetTranslation(); + if (playerToPoint.canBeNormalized() && playerToPoint.magnitude() < g_tweakPlayer->GetOrbitDistanceMax()) { return true; + } } else { return true; } @@ -3868,16 +4207,17 @@ bool CPlayer::ValidateObjectForMode(TUniqueId uid, CStateManager& mgr) const { } static zeus::CAABox BuildNearListBox(bool cropBottom, const zeus::CTransform& xf, float x, float z, float y) { - zeus::CAABox aabb(-x, cropBottom ? 0.f : -y, -z, x, y, z); + const zeus::CAABox aabb(-x, cropBottom ? 0.f : -y, -z, x, y, z); return aabb.getTransformedAABox(xf); } TUniqueId CPlayer::FindAimTargetId(CStateManager& mgr) const { float dist = g_tweakPlayer->GetAimMaxDistance(); - if (x9c6_24_extendTargetDistance) + if (x9c6_24_extendTargetDistance) { dist *= 5.f; - zeus::CAABox aabb = BuildNearListBox(true, GetFirstPersonCameraTransform(mgr), g_tweakPlayer->GetAimBoxWidth(), - g_tweakPlayer->GetAimBoxHeight(), dist); + } + const zeus::CAABox aabb = BuildNearListBox(true, GetFirstPersonCameraTransform(mgr), g_tweakPlayer->GetAimBoxWidth(), + g_tweakPlayer->GetAimBoxHeight(), dist); rstl::reserved_vector nearList; mgr.BuildNearList(nearList, aabb, CMaterialFilter::MakeInclude({EMaterialTypes::Target}), this); return CheckEnemiesAgainstOrbitZone(nearList, EPlayerZoneInfo::Targeting, EPlayerZoneType::Ellipse, mgr); @@ -3889,25 +4229,25 @@ const zeus::CTransform& CPlayer::GetFirstPersonCameraTransform(const CStateManag TUniqueId CPlayer::CheckEnemiesAgainstOrbitZone(const rstl::reserved_vector& list, EPlayerZoneInfo info, EPlayerZoneType zone, CStateManager& mgr) const { - zeus::CVector3f eyePos = GetEyePosition(); + const zeus::CVector3f eyePos = GetEyePosition(); float minEyeToAimMag = 10000.f; float minPosInBoxMagSq = 10000.f; TUniqueId bestId = kInvalidUniqueId; - float vpWHalf = g_Viewport.x8_width / 2; - float vpHHalf = g_Viewport.xc_height / 2; - float boxLeft = (GetOrbitZoneIdealXScaled(int(info)) - vpWHalf) / vpWHalf; - float boxTop = (GetOrbitZoneIdealYScaled(int(info)) - vpHHalf) / vpHHalf; - CFirstPersonCamera* fpCam = mgr.GetCameraManager()->GetFirstPersonCamera(); + const float vpWHalf = g_Viewport.x8_width / 2; + const float vpHHalf = g_Viewport.xc_height / 2; + const float boxLeft = (GetOrbitZoneIdealXScaled(int(info)) - vpWHalf) / vpWHalf; + const float boxTop = (GetOrbitZoneIdealYScaled(int(info)) - vpHHalf) / vpHHalf; + const CFirstPersonCamera* fpCam = mgr.GetCameraManager()->GetFirstPersonCamera(); - for (TUniqueId id : list) { - if (CActor* act = static_cast(mgr.ObjectById(id))) { + for (const TUniqueId id : list) { + if (const auto* act = static_cast(mgr.ObjectById(id))) { if (act->GetUniqueId() != GetUniqueId() && ValidateObjectForMode(act->GetUniqueId(), mgr)) { - zeus::CVector3f aimPos = act->GetAimPosition(mgr, 0.f); - zeus::CVector3f screenPos = fpCam->ConvertToScreenSpace(aimPos); - zeus::CVector3f posInBox(vpWHalf + screenPos.x() * vpWHalf, vpHHalf + screenPos.y() * vpHHalf, screenPos.z()); + const zeus::CVector3f aimPos = act->GetAimPosition(mgr, 0.f); + const zeus::CVector3f screenPos = fpCam->ConvertToScreenSpace(aimPos); + const zeus::CVector3f posInBox(vpWHalf + screenPos.x() * vpWHalf, vpHHalf + screenPos.y() * vpHHalf, screenPos.z()); if (WithinOrbitScreenBox(posInBox, info, zone)) { zeus::CVector3f eyeToAim = aimPos - eyePos; - float eyeToAimMag = eyeToAim.magnitude(); + const float eyeToAimMag = eyeToAim.magnitude(); if (eyeToAimMag <= g_tweakPlayer->GetAimMaxDistance()) { if (minEyeToAimMag - eyeToAimMag > g_tweakPlayer->GetAimThresholdDistance()) { rstl::reserved_vector nearList; @@ -3915,26 +4255,26 @@ TUniqueId CPlayer::CheckEnemiesAgainstOrbitZone(const rstl::reserved_vectorGetUniqueId(); - float posInBoxLeft = posInBox.x() - boxLeft; - float posInBoxTop = posInBox.y() - boxTop; + const float posInBoxLeft = posInBox.x() - boxLeft; + const float posInBoxTop = posInBox.y() - boxTop; minEyeToAimMag = eyeToAimMag; minPosInBoxMagSq = posInBoxLeft * posInBoxLeft + posInBoxTop * posInBoxTop; } } else if (std::fabs(eyeToAimMag - minEyeToAimMag) < g_tweakPlayer->GetAimThresholdDistance()) { - float posInBoxLeft = posInBox.x() - boxLeft; - float posInBoxTop = posInBox.y() - boxTop; - float posInBoxMagSq = posInBoxLeft * posInBoxLeft + posInBoxTop * posInBoxTop; + const float posInBoxLeft = posInBox.x() - boxLeft; + const float posInBoxTop = posInBox.y() - boxTop; + const float posInBoxMagSq = posInBoxLeft * posInBoxLeft + posInBoxTop * posInBoxTop; if (posInBoxMagSq < minPosInBoxMagSq) { rstl::reserved_vector nearList; TUniqueId intersectId = kInvalidUniqueId; eyeToAim.normalize(); mgr.BuildNearList(nearList, eyePos, eyeToAim, eyeToAimMag, OccluderFilter, act); eyeToAim.normalize(); - CRayCastResult result = + const CRayCastResult result = mgr.RayWorldIntersection(intersectId, eyePos, eyeToAim, eyeToAimMag, LineOfSightFilter, nearList); if (result.IsInvalid()) { bestId = act->GetUniqueId(); @@ -3961,18 +4301,20 @@ void CPlayer::UpdateOrbitableObjects(CStateManager& mgr) { x344_nearbyOrbitObjects.clear(); x364_offScreenOrbitObjects.clear(); - if (CheckOrbitDisableSourceList(mgr)) + if (CheckOrbitDisableSourceList(mgr)) { return; + } float dist = GetOrbitMaxTargetDistance(mgr); - if (x9c6_24_extendTargetDistance) + if (x9c6_24_extendTargetDistance) { dist *= 5.f; - zeus::CAABox nearAABB = BuildNearListBox(true, GetFirstPersonCameraTransform(mgr), g_tweakPlayer->GetOrbitNearX(), - g_tweakPlayer->GetOrbitNearZ(), dist); + } + const zeus::CAABox nearAABB = BuildNearListBox(true, GetFirstPersonCameraTransform(mgr), + g_tweakPlayer->GetOrbitNearX(), g_tweakPlayer->GetOrbitNearZ(), dist); - CMaterialFilter filter = mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Scan - ? CMaterialFilter::MakeInclude({EMaterialTypes::Scannable}) - : CMaterialFilter::MakeInclude({EMaterialTypes::Orbit}); + const CMaterialFilter filter = mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Scan + ? CMaterialFilter::MakeInclude({EMaterialTypes::Scannable}) + : CMaterialFilter::MakeInclude({EMaterialTypes::Orbit}); rstl::reserved_vector nearList; mgr.BuildNearList(nearList, nearAABB, filter, nullptr); @@ -3983,26 +4325,26 @@ void CPlayer::UpdateOrbitableObjects(CStateManager& mgr) { TUniqueId CPlayer::FindBestOrbitableObject(const std::vector& ids, EPlayerZoneInfo info, CStateManager& mgr) const { - zeus::CVector3f eyePos = GetEyePosition(); + const zeus::CVector3f eyePos = GetEyePosition(); float minEyeToOrbitMag = 10000.f; float minPosInBoxMagSq = 10000.f; TUniqueId bestId = kInvalidUniqueId; - float vpWidthHalf = g_Viewport.x8_width / 2; - float vpHeightHalf = g_Viewport.xc_height / 2; - float boxLeft = (GetOrbitZoneIdealXScaled(int(info)) - vpWidthHalf) / vpWidthHalf; - float boxTop = (GetOrbitZoneIdealYScaled(int(info)) - vpHeightHalf) / vpHeightHalf; + const float vpWidthHalf = g_Viewport.x8_width / 2; + const float vpHeightHalf = g_Viewport.xc_height / 2; + const float boxLeft = (GetOrbitZoneIdealXScaled(int(info)) - vpWidthHalf) / vpWidthHalf; + const float boxTop = (GetOrbitZoneIdealYScaled(int(info)) - vpHeightHalf) / vpHeightHalf; - CFirstPersonCamera* fpCam = mgr.GetCameraManager()->GetFirstPersonCamera(); + const CFirstPersonCamera* fpCam = mgr.GetCameraManager()->GetFirstPersonCamera(); - for (TUniqueId id : ids) { - if (TCastToPtr act = mgr.ObjectById(id)) { - zeus::CVector3f orbitPos = act->GetOrbitPosition(mgr); + for (const TUniqueId id : ids) { + if (const TCastToConstPtr act = mgr.ObjectById(id)) { + const zeus::CVector3f orbitPos = act->GetOrbitPosition(mgr); zeus::CVector3f eyeToOrbit = orbitPos - eyePos; - float eyeToOrbitMag = eyeToOrbit.magnitude(); - zeus::CVector3f orbitPosScreen = fpCam->ConvertToScreenSpace(orbitPos); + const float eyeToOrbitMag = eyeToOrbit.magnitude(); + const zeus::CVector3f orbitPosScreen = fpCam->ConvertToScreenSpace(orbitPos); if (orbitPosScreen.z() >= 0.f) { if (x310_orbitTargetId != id) { - if (TCastToPtr point = act.GetPtr()) { + if (const TCastToConstPtr point = act.GetPtr()) { if (x310_orbitTargetId != point->GetUniqueId()) { if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GrappleBeam) && eyeToOrbitMag < minEyeToOrbitMag && eyeToOrbitMag < g_tweakPlayer->GetOrbitDistanceMax()) { @@ -4011,22 +4353,23 @@ TUniqueId CPlayer::FindBestOrbitableObject(const std::vector& ids, EP eyeToOrbit.normalize(); mgr.BuildNearList(nearList, eyePos, eyeToOrbit, eyeToOrbitMag, OccluderFilter, act.GetPtr()); eyeToOrbit.normalize(); - CRayCastResult result = mgr.RayWorldIntersection(intersectId, eyePos, eyeToOrbit, eyeToOrbitMag, - LineOfSightFilter, nearList); + const CRayCastResult result = mgr.RayWorldIntersection(intersectId, eyePos, eyeToOrbit, eyeToOrbitMag, + LineOfSightFilter, nearList); if (result.IsInvalid()) { if (point->GetGrappleParameters().GetLockSwingTurn()) { zeus::CVector3f pointToPlayer = GetTranslation() - point->GetTranslation(); if (pointToPlayer.canBeNormalized()) { pointToPlayer.z() = 0.f; if (std::fabs(point->GetTransform().basis[1].normalized().dot(pointToPlayer.normalized())) <= - M_SQRT1_2F) + M_SQRT1_2F) { continue; + } } } bestId = act->GetUniqueId(); - float posInBoxLeft = orbitPosScreen.x() - boxLeft; - float posInBoxTop = orbitPosScreen.y() - boxTop; + const float posInBoxLeft = orbitPosScreen.x() - boxLeft; + const float posInBoxTop = orbitPosScreen.y() - boxTop; minEyeToOrbitMag = eyeToOrbitMag; minPosInBoxMagSq = posInBoxLeft * posInBoxLeft + posInBoxTop * posInBoxTop; } @@ -4042,11 +4385,11 @@ TUniqueId CPlayer::FindBestOrbitableObject(const std::vector& ids, EP eyeToOrbit.normalize(); mgr.BuildNearList(nearList, eyePos, eyeToOrbit, eyeToOrbitMag, OccluderFilter, act.GetPtr()); for (auto it = nearList.begin(); it != nearList.end();) { - if (CEntity* obj = mgr.ObjectById(*it)) { + if (const CEntity* obj = mgr.ObjectById(*it)) { if (obj->GetAreaIdAlways() != kInvalidAreaId) { if (mgr.GetNextAreaId() != obj->GetAreaIdAlways()) { const CGameArea* area = mgr.GetWorld()->GetAreaAlways(obj->GetAreaIdAlways()); - CGameArea::EOcclusionState state = + const CGameArea::EOcclusionState state = area->IsPostConstructed() ? area->GetOcclusionState() : CGameArea::EOcclusionState::Occluded; if (state == CGameArea::EOcclusionState::Occluded) { it = nearList.erase(it); @@ -4062,12 +4405,12 @@ TUniqueId CPlayer::FindBestOrbitableObject(const std::vector& ids, EP } eyeToOrbit.normalize(); - CRayCastResult result = + const CRayCastResult result = mgr.RayWorldIntersection(idOut, eyePos, eyeToOrbit, eyeToOrbitMag, LineOfSightFilter, nearList); if (result.IsInvalid()) { bestId = act->GetUniqueId(); - float posInBoxLeft = orbitPosScreen.x() - boxLeft; - float posInBoxTop = orbitPosScreen.y() - boxTop; + const float posInBoxLeft = orbitPosScreen.x() - boxLeft; + const float posInBoxTop = orbitPosScreen.y() - boxTop; minEyeToOrbitMag = eyeToOrbitMag; minPosInBoxMagSq = posInBoxLeft * posInBoxLeft + posInBoxTop * posInBoxTop; } @@ -4076,20 +4419,20 @@ TUniqueId CPlayer::FindBestOrbitableObject(const std::vector& ids, EP if (std::fabs(eyeToOrbitMag - minEyeToOrbitMag) < g_tweakPlayer->GetOrbitDistanceThreshold() || mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Scan) { - float posInBoxLeft = orbitPosScreen.x() - boxLeft; - float posInBoxTop = orbitPosScreen.y() - boxTop; - float posInBoxMagSq = posInBoxLeft * posInBoxLeft + posInBoxTop * posInBoxTop; + const float posInBoxLeft = orbitPosScreen.x() - boxLeft; + const float posInBoxTop = orbitPosScreen.y() - boxTop; + const float posInBoxMagSq = posInBoxLeft * posInBoxLeft + posInBoxTop * posInBoxTop; if (posInBoxMagSq < minPosInBoxMagSq) { rstl::reserved_vector nearList; TUniqueId idOut = kInvalidUniqueId; eyeToOrbit.normalize(); mgr.BuildNearList(nearList, eyePos, eyeToOrbit, eyeToOrbitMag, OccluderFilter, act.GetPtr()); for (auto it = nearList.begin(); it != nearList.end();) { - if (CEntity* obj = mgr.ObjectById(*it)) { + if (const CEntity* obj = mgr.ObjectById(*it)) { if (obj->GetAreaIdAlways() != kInvalidAreaId) { if (mgr.GetNextAreaId() != obj->GetAreaIdAlways()) { const CGameArea* area = mgr.GetWorld()->GetAreaAlways(obj->GetAreaIdAlways()); - CGameArea::EOcclusionState state = + const CGameArea::EOcclusionState state = area->IsPostConstructed() ? area->GetOcclusionState() : CGameArea::EOcclusionState::Occluded; if (state == CGameArea::EOcclusionState::Occluded) { it = nearList.erase(it); @@ -4105,7 +4448,7 @@ TUniqueId CPlayer::FindBestOrbitableObject(const std::vector& ids, EP } eyeToOrbit.normalize(); - CRayCastResult result = + const CRayCastResult result = mgr.RayWorldIntersection(idOut, eyePos, eyeToOrbit, eyeToOrbitMag, LineOfSightFilter, nearList); if (result.IsInvalid()) { bestId = act->GetUniqueId(); @@ -4125,40 +4468,46 @@ TUniqueId CPlayer::FindBestOrbitableObject(const std::vector& ids, EP void CPlayer::FindOrbitableObjects(const rstl::reserved_vector& nearObjects, std::vector& listOut, EPlayerZoneInfo zone, EPlayerZoneType type, CStateManager& mgr, bool onScreenTest) const { - CFirstPersonCamera* fpCam = mgr.GetCameraManager()->GetFirstPersonCamera(); - zeus::CVector3f eyePos = GetEyePosition(); + const CFirstPersonCamera* fpCam = mgr.GetCameraManager()->GetFirstPersonCamera(); + const zeus::CVector3f eyePos = GetEyePosition(); - for (TUniqueId id : nearObjects) { - if (TCastToConstPtr act = mgr.GetObjectById(id)) { - if (GetUniqueId() == act->GetUniqueId()) + for (const TUniqueId id : nearObjects) { + if (const TCastToConstPtr act = mgr.GetObjectById(id)) { + if (GetUniqueId() == act->GetUniqueId()) { continue; - if (ValidateOrbitTargetId(act->GetUniqueId(), mgr) != EOrbitValidationResult::OK) + } + if (ValidateOrbitTargetId(act->GetUniqueId(), mgr) != EOrbitValidationResult::OK) { continue; - zeus::CVector3f orbitPos = act->GetOrbitPosition(mgr); + } + const zeus::CVector3f orbitPos = act->GetOrbitPosition(mgr); zeus::CVector3f screenPos = fpCam->ConvertToScreenSpace(orbitPos); screenPos.x() = g_Viewport.x8_width * screenPos.x() / 2.f + g_Viewport.x8_width / 2.f; screenPos.y() = g_Viewport.xc_height * screenPos.y() / 2.f + g_Viewport.xc_height / 2.f; bool pass = false; if (onScreenTest) { - if (WithinOrbitScreenBox(screenPos, zone, type)) + if (WithinOrbitScreenBox(screenPos, zone, type)) { pass = true; + } } else { - if (!WithinOrbitScreenBox(screenPos, zone, type)) + if (!WithinOrbitScreenBox(screenPos, zone, type)) { pass = true; + } } if (pass && - (!act->GetDoTargetDistanceTest() || (orbitPos - eyePos).magnitude() <= GetOrbitMaxTargetDistance(mgr))) + (!act->GetDoTargetDistanceTest() || (orbitPos - eyePos).magnitude() <= GetOrbitMaxTargetDistance(mgr))) { listOut.push_back(id); + } } } } bool CPlayer::WithinOrbitScreenBox(const zeus::CVector3f& screenCoords, EPlayerZoneInfo zone, EPlayerZoneType type) const { - if (screenCoords.z() >= 1.f) + if (screenCoords.z() >= 1.f) { return false; + } switch (type) { case EPlayerZoneType::Box: @@ -4167,26 +4516,24 @@ bool CPlayer::WithinOrbitScreenBox(const zeus::CVector3f& screenCoords, EPlayerZ std::fabs(screenCoords.y() - GetOrbitScreenBoxCenterYScaled(int(zone))) < GetOrbitScreenBoxHalfExtentYScaled(int(zone)) && screenCoords.z() < 1.f; - break; case EPlayerZoneType::Ellipse: return WithinOrbitScreenEllipse(screenCoords, zone); default: return true; } - - return false; } bool CPlayer::WithinOrbitScreenEllipse(const zeus::CVector3f& screenCoords, EPlayerZoneInfo zone) const { - if (screenCoords.z() >= 1.f) + if (screenCoords.z() >= 1.f) { return false; + } float heYSq = GetOrbitScreenBoxHalfExtentYScaled(int(zone)); heYSq *= heYSq; float heXSq = GetOrbitScreenBoxHalfExtentXScaled(int(zone)); heXSq *= heXSq; - float tmpY = std::fabs(screenCoords.y() - GetOrbitScreenBoxCenterYScaled(int(zone))); - float tmpX = std::fabs(screenCoords.x() - GetOrbitScreenBoxCenterXScaled(int(zone))); + const float tmpY = std::fabs(screenCoords.y() - GetOrbitScreenBoxCenterYScaled(int(zone))); + const float tmpX = std::fabs(screenCoords.x() - GetOrbitScreenBoxCenterXScaled(int(zone))); return tmpX * tmpX <= (1.f - tmpY * tmpY / heYSq) * heXSq; } @@ -4212,20 +4559,29 @@ void CPlayer::RemoveOrbitDisableSource(TUniqueId uid) { } void CPlayer::AddOrbitDisableSource(CStateManager& mgr, TUniqueId addId) { - if (x9e4_orbitDisableList.size() >= 5) + if (x9e4_orbitDisableList.size() >= 5) { return; - for (TUniqueId uid : x9e4_orbitDisableList) - if (uid == addId) + } + + for (const TUniqueId uid : x9e4_orbitDisableList) { + if (uid == addId) { return; + } + } + x9e4_orbitDisableList.push_back(addId); ResetAimTargetPrediction(kInvalidUniqueId); - if (!TCastToConstPtr(mgr.GetObjectById(x310_orbitTargetId))) + if (!TCastToConstPtr(mgr.GetObjectById(x310_orbitTargetId))) { SetOrbitTargetId(kInvalidUniqueId, mgr); + } } void CPlayer::UpdateOrbitPreventionTimer(float dt) { - if (x378_orbitPreventionTimer > 0.f) - x378_orbitPreventionTimer -= dt; + if (x378_orbitPreventionTimer <= 0.f) { + return; + } + + x378_orbitPreventionTimer -= dt; } void CPlayer::UpdateOrbitModeTimer(float dt) { @@ -4249,12 +4605,14 @@ void CPlayer::UpdateOrbitZone(CStateManager& mgr) { } void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr) { - if (x2f8_morphBallState != EPlayerMorphBallState::Unmorphed || x378_orbitPreventionTimer > 0.f) + if (x2f8_morphBallState != EPlayerMorphBallState::Unmorphed || x378_orbitPreventionTimer > 0.f) { return; + } UpdateOrbitableObjects(mgr); - if (x304_orbitState == EPlayerOrbitState::NoOrbit) + if (x304_orbitState == EPlayerOrbitState::NoOrbit) { x33c_orbitNextTargetId = FindOrbitTargetId(mgr); + } if (ControlMapper::GetDigitalInput(ControlMapper::ECommands::OrbitClose, input) || ControlMapper::GetDigitalInput(ControlMapper::ECommands::OrbitFar, input) || @@ -4266,8 +4624,9 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr) { if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitObject, input)) { SetOrbitTargetId(x33c_orbitNextTargetId, mgr); if (x310_orbitTargetId != kInvalidUniqueId) { - if (ValidateAimTargetId(x310_orbitTargetId, mgr)) + if (ValidateAimTargetId(x310_orbitTargetId, mgr)) { ResetAimTargetPrediction(x310_orbitTargetId); + } SetOrbitState(EPlayerOrbitState::OrbitObject, mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); } @@ -4275,34 +4634,39 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr) { #else m_deferredOrbitObject = ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitObject, input); #endif - if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitFar, input)) + if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitFar, input)) { OrbitPoint(EPlayerOrbitType::Far, mgr); - if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitClose, input)) + } + if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitClose, input)) { OrbitPoint(EPlayerOrbitType::Close, mgr); + } #if 0 } #endif break; case EPlayerOrbitState::Grapple: - if (x310_orbitTargetId == kInvalidUniqueId) + if (x310_orbitTargetId == kInvalidUniqueId) { BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr); + } break; case EPlayerOrbitState::OrbitObject: - if (TCastToConstPtr point = mgr.GetObjectById(x310_orbitTargetId)) { - if (ValidateCurrentOrbitTargetId(mgr) == EOrbitValidationResult::OK) + if (const TCastToConstPtr point = mgr.GetObjectById(x310_orbitTargetId)) { + if (ValidateCurrentOrbitTargetId(mgr) == EOrbitValidationResult::OK) { UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); - else + } else { BreakGrapple(EPlayerOrbitRequest::InvalidateTarget, mgr); + } } else { - EOrbitValidationResult result = ValidateCurrentOrbitTargetId(mgr); - if (result == EOrbitValidationResult::OK) + const EOrbitValidationResult result = ValidateCurrentOrbitTargetId(mgr); + if (result == EOrbitValidationResult::OK) { UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); - else if (result == EOrbitValidationResult::BrokenLookAngle) + } else if (result == EOrbitValidationResult::BrokenLookAngle) { OrbitPoint(EPlayerOrbitType::Far, mgr); - else if (result == EOrbitValidationResult::ExtremeHorizonAngle) + } else if (result == EOrbitValidationResult::ExtremeHorizonAngle) { SetOrbitRequest(EPlayerOrbitRequest::BadVerticalAngle, mgr); - else + } else { ActivateOrbitSource(mgr); + } } UpdateOrbitSelection(input, mgr); break; @@ -4311,8 +4675,9 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr) { m_deferredOrbitObject = false; SetOrbitTargetId(FindOrbitTargetId(mgr), mgr); if (x310_orbitTargetId != kInvalidUniqueId) { - if (ValidateAimTargetId(x310_orbitTargetId, mgr)) + if (ValidateAimTargetId(x310_orbitTargetId, mgr)) { ResetAimTargetPrediction(x310_orbitTargetId); + } SetOrbitState(EPlayerOrbitState::OrbitObject, mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); } @@ -4342,8 +4707,9 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr) { m_deferredOrbitObject = false; SetOrbitTargetId(FindOrbitTargetId(mgr), mgr); if (x310_orbitTargetId != kInvalidUniqueId) { - if (ValidateAimTargetId(x310_orbitTargetId, mgr)) + if (ValidateAimTargetId(x310_orbitTargetId, mgr)) { ResetAimTargetPrediction(x310_orbitTargetId); + } SetOrbitState(EPlayerOrbitState::OrbitObject, mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); } @@ -4358,24 +4724,27 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr) { if (x304_orbitState == EPlayerOrbitState::Grapple) { x33c_orbitNextTargetId = FindOrbitTargetId(mgr); - if (x33c_orbitNextTargetId == x310_orbitTargetId) + if (x33c_orbitNextTargetId == x310_orbitTargetId) { x33c_orbitNextTargetId = kInvalidUniqueId; + } } } else { switch (x304_orbitState) { case EPlayerOrbitState::NoOrbit: break; case EPlayerOrbitState::OrbitObject: - if (TCastToConstPtr point = mgr.GetObjectById(x310_orbitTargetId)) + if (TCastToConstPtr point = mgr.GetObjectById(x310_orbitTargetId)) { BreakGrapple(EPlayerOrbitRequest::Default, mgr); - else + } else { SetOrbitRequest(EPlayerOrbitRequest::StopOrbit, mgr); + } break; case EPlayerOrbitState::Grapple: if (!g_tweakPlayer->GetOrbitReleaseBreaksGrapple()) { x33c_orbitNextTargetId = FindOrbitTargetId(mgr); - if (x33c_orbitNextTargetId == x310_orbitTargetId) + if (x33c_orbitNextTargetId == x310_orbitTargetId) { x33c_orbitNextTargetId = kInvalidUniqueId; + } } else { BreakGrapple(EPlayerOrbitRequest::StopOrbit, mgr); } @@ -4400,18 +4769,19 @@ void CPlayer::ActivateOrbitSource(CStateManager& mgr) { SetOrbitRequest(EPlayerOrbitRequest::InvalidateTarget, mgr); break; case 2: - if (x394_orbitingEnemy) + if (x394_orbitingEnemy) { OrbitPoint(EPlayerOrbitType::Far, mgr); - else + } else { OrbitCarcass(mgr); + } break; } } void CPlayer::UpdateOrbitSelection(const CFinalInput& input, CStateManager& mgr) { x33c_orbitNextTargetId = FindOrbitTargetId(mgr); - TCastToConstPtr curPoint = mgr.GetObjectById(x310_orbitTargetId); - TCastToConstPtr nextPoint = mgr.GetObjectById(x33c_orbitNextTargetId); + const TCastToConstPtr curPoint = mgr.GetObjectById(x310_orbitTargetId); + const TCastToConstPtr nextPoint = mgr.GetObjectById(x33c_orbitNextTargetId); if (curPoint || (x304_orbitState == EPlayerOrbitState::Grapple && !nextPoint)) { x33c_orbitNextTargetId = kInvalidUniqueId; return; @@ -4420,28 +4790,32 @@ void CPlayer::UpdateOrbitSelection(const CFinalInput& input, CStateManager& mgr) if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitObject, input) && x33c_orbitNextTargetId != kInvalidUniqueId) { SetOrbitTargetId(x33c_orbitNextTargetId, mgr); - if (ValidateAimTargetId(x310_orbitTargetId, mgr)) + if (ValidateAimTargetId(x310_orbitTargetId, mgr)) { ResetAimTargetPrediction(x310_orbitTargetId); + } SetOrbitState(EPlayerOrbitState::OrbitObject, mgr); UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); } } void CPlayer::UpdateOrbitOrientation(CStateManager& mgr) { - if (x2f8_morphBallState != EPlayerMorphBallState::Unmorphed) + if (x2f8_morphBallState != EPlayerMorphBallState::Unmorphed) { return; + } switch (x304_orbitState) { case EPlayerOrbitState::OrbitPoint: - if (x3dc_inFreeLook) + if (x3dc_inFreeLook) { return; + } [[fallthrough]]; case EPlayerOrbitState::OrbitObject: case EPlayerOrbitState::OrbitCarcass: case EPlayerOrbitState::ForcedOrbitObject: { zeus::CVector3f playerToPoint = x314_orbitPoint - GetTranslation(); - if (!x374_orbitLockEstablished) + if (!x374_orbitLockEstablished) { playerToPoint = mgr.GetCameraManager()->GetFirstPersonCamera()->GetTransform().basis[1]; + } playerToPoint.z() = 0.f; if (playerToPoint.canBeNormalized()) { zeus::CTransform xf = zeus::lookAt(zeus::skZero3f, playerToPoint); @@ -4456,23 +4830,27 @@ void CPlayer::UpdateOrbitOrientation(CStateManager& mgr) { } void CPlayer::UpdateOrbitTarget(CStateManager& mgr) { - if (!ValidateOrbitTargetIdAndPointer(x310_orbitTargetId, mgr)) + if (!ValidateOrbitTargetIdAndPointer(x310_orbitTargetId, mgr)) { SetOrbitTargetId(kInvalidUniqueId, mgr); - if (!ValidateOrbitTargetIdAndPointer(x33c_orbitNextTargetId, mgr)) + } + if (!ValidateOrbitTargetIdAndPointer(x33c_orbitNextTargetId, mgr)) { x33c_orbitNextTargetId = kInvalidUniqueId; + } + zeus::CVector3f playerToPoint = x314_orbitPoint - GetTranslation(); playerToPoint.z() = 0.f; - float playerToPointMag = playerToPoint.magnitude(); + const float playerToPointMag = playerToPoint.magnitude(); switch (x304_orbitState) { case EPlayerOrbitState::OrbitObject: - if (auto* ent = static_cast(mgr.GetObjectById(x310_orbitTargetId))) { + if (const auto* ent = static_cast(mgr.GetObjectById(x310_orbitTargetId))) { if (ent->GetDoTargetDistanceTest() && (playerToPointMag >= GetOrbitMaxLockDistance(mgr) || playerToPointMag < 0.5f)) { - if (playerToPointMag < 0.5f) + if (playerToPointMag < 0.5f) { SetOrbitRequest(EPlayerOrbitRequest::BadVerticalAngle, mgr); - else + } else { ActivateOrbitSource(mgr); + } } } UpdateOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); @@ -4483,28 +4861,33 @@ void CPlayer::UpdateOrbitTarget(CStateManager& mgr) { UpdateOrbitFixedPosition(); return; } - if (playerToPointMag < CalculateOrbitMinDistance(x308_orbitType)) + if (playerToPointMag < CalculateOrbitMinDistance(x308_orbitType)) { UpdateOrbitPosition(CalculateOrbitMinDistance(x308_orbitType), mgr); - float maxDist = g_tweakPlayer->GetOrbitMaxDistance(int(x308_orbitType)); - if (playerToPointMag > maxDist) + } + const float maxDist = g_tweakPlayer->GetOrbitMaxDistance(int(x308_orbitType)); + if (playerToPointMag > maxDist) { UpdateOrbitPosition(maxDist, mgr); - if (x3dd_lookButtonHeld) + } + if (x3dd_lookButtonHeld) { SetOrbitPosition(g_tweakPlayer->GetOrbitNormalDistance(int(x308_orbitType)), mgr); - zeus::CVector3f eyeToPoint = x314_orbitPoint - GetEyePosition(); - float angleToPoint = std::asin(zeus::clamp(-1.f, std::fabs(eyeToPoint.z()) / eyeToPoint.magnitude(), 1.f)); + } + const zeus::CVector3f eyeToPoint = x314_orbitPoint - GetEyePosition(); + const float angleToPoint = std::asin(zeus::clamp(-1.f, std::fabs(eyeToPoint.z()) / eyeToPoint.magnitude(), 1.f)); if ((eyeToPoint.z() >= 0.f && angleToPoint >= g_tweakPlayer->GetOrbitUpperAngle()) || - (eyeToPoint.z() < 0.f && angleToPoint >= g_tweakPlayer->GetOrbitLowerAngle())) + (eyeToPoint.z() < 0.f && angleToPoint >= g_tweakPlayer->GetOrbitLowerAngle())) { SetOrbitRequest(EPlayerOrbitRequest::BadVerticalAngle, mgr); + } break; } case EPlayerOrbitState::OrbitCarcass: { - if (x3dd_lookButtonHeld) + if (x3dd_lookButtonHeld) { SetOrbitPosition(x340_, mgr); + } if (playerToPointMag < CalculateOrbitMinDistance(x308_orbitType)) { UpdateOrbitPosition(CalculateOrbitMinDistance(x308_orbitType), mgr); x340_ = CalculateOrbitMinDistance(x308_orbitType); } - float maxDist = g_tweakPlayer->GetOrbitMaxDistance(int(x308_orbitType)); + const float maxDist = g_tweakPlayer->GetOrbitMaxDistance(int(x308_orbitType)); if (playerToPointMag > maxDist) { UpdateOrbitPosition(maxDist, mgr); x340_ = g_tweakPlayer->GetOrbitMaxDistance(int(x308_orbitType)); @@ -4533,74 +4916,88 @@ float CPlayer::GetOrbitMaxTargetDistance(CStateManager& mgr) const { } CPlayer::EOrbitValidationResult CPlayer::ValidateOrbitTargetId(TUniqueId uid, CStateManager& mgr) const { - if (uid == kInvalidUniqueId) + if (uid == kInvalidUniqueId) { return EOrbitValidationResult::InvalidTarget; + } - TCastToConstPtr act = mgr.GetObjectById(uid); - if (!act || !act->GetIsTargetable() || !act->GetActive()) + const TCastToConstPtr act = mgr.GetObjectById(uid); + if (!act || !act->GetIsTargetable() || !act->GetActive()) { return EOrbitValidationResult::InvalidTarget; + } - if (x740_staticTimer != 0.f) + if (x740_staticTimer != 0.f) { return EOrbitValidationResult::PlayerNotReadyToTarget; + } - zeus::CVector3f eyePos = GetEyePosition(); - zeus::CVector3f eyeToOrbit = act->GetOrbitPosition(mgr) - eyePos; + const zeus::CVector3f eyePos = GetEyePosition(); + const zeus::CVector3f eyeToOrbit = act->GetOrbitPosition(mgr) - eyePos; zeus::CVector3f eyeToOrbitFlat = eyeToOrbit; eyeToOrbitFlat.z() = 0.f; if (eyeToOrbitFlat.canBeNormalized() && eyeToOrbitFlat.magnitude() > 1.f) { - float angleFromHorizon = std::asin(zeus::clamp(-1.f, std::fabs(eyeToOrbit.z()) / eyeToOrbit.magnitude(), 1.f)); + const float angleFromHorizon = std::asin(zeus::clamp(-1.f, std::fabs(eyeToOrbit.z()) / eyeToOrbit.magnitude(), 1.f)); if ((eyeToOrbit.z() >= 0.f && angleFromHorizon >= g_tweakPlayer->GetOrbitUpperAngle()) || - (eyeToOrbit.z() < 0.f && angleFromHorizon >= g_tweakPlayer->GetOrbitLowerAngle())) + (eyeToOrbit.z() < 0.f && angleFromHorizon >= g_tweakPlayer->GetOrbitLowerAngle())) { return EOrbitValidationResult::ExtremeHorizonAngle; + } } else { return EOrbitValidationResult::ExtremeHorizonAngle; } - CPlayerState::EPlayerVisor visor = mgr.GetPlayerState()->GetCurrentVisor(); - u8 flags = act->GetTargetableVisorFlags(); - if (visor == CPlayerState::EPlayerVisor::Combat && (flags & 1) == 0) + const CPlayerState::EPlayerVisor visor = mgr.GetPlayerState()->GetCurrentVisor(); + const u8 flags = act->GetTargetableVisorFlags(); + if (visor == CPlayerState::EPlayerVisor::Combat && (flags & 1) == 0) { return EOrbitValidationResult::PlayerNotReadyToTarget; - if (visor == CPlayerState::EPlayerVisor::Scan && (flags & 2) == 0) + } + if (visor == CPlayerState::EPlayerVisor::Scan && (flags & 2) == 0) { return EOrbitValidationResult::PlayerNotReadyToTarget; - if (visor == CPlayerState::EPlayerVisor::Thermal && (flags & 4) == 0) + } + if (visor == CPlayerState::EPlayerVisor::Thermal && (flags & 4) == 0) { return EOrbitValidationResult::PlayerNotReadyToTarget; - if (visor == CPlayerState::EPlayerVisor::XRay && (flags & 8) == 0) + } + if (visor == CPlayerState::EPlayerVisor::XRay && (flags & 8) == 0) { return EOrbitValidationResult::PlayerNotReadyToTarget; + } - if (visor == CPlayerState::EPlayerVisor::Scan && act->GetAreaIdAlways() != GetAreaIdAlways()) + if (visor == CPlayerState::EPlayerVisor::Scan && act->GetAreaIdAlways() != GetAreaIdAlways()) { return EOrbitValidationResult::TargetingThroughDoor; + } return EOrbitValidationResult::OK; } CPlayer::EOrbitValidationResult CPlayer::ValidateCurrentOrbitTargetId(CStateManager& mgr) { - TCastToConstPtr act = mgr.GetObjectById(x310_orbitTargetId); - if (!act || !act->GetIsTargetable() || !act->GetActive()) + const TCastToConstPtr act = mgr.GetObjectById(x310_orbitTargetId); + if (!act || !act->GetIsTargetable() || !act->GetActive()) { return EOrbitValidationResult::InvalidTarget; - - if (!act->GetMaterialList().HasMaterial(EMaterialTypes::Orbit)) { - if (!act->GetMaterialList().HasMaterial(EMaterialTypes::Scannable)) - return EOrbitValidationResult::NonTargetableTarget; - if (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::Scan) - return EOrbitValidationResult::NonTargetableTarget; } - EOrbitValidationResult type = ValidateOrbitTargetId(x310_orbitTargetId, mgr); - if (type != EOrbitValidationResult::OK) + if (!act->GetMaterialList().HasMaterial(EMaterialTypes::Orbit)) { + if (!act->GetMaterialList().HasMaterial(EMaterialTypes::Scannable)) { + return EOrbitValidationResult::NonTargetableTarget; + } + if (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::Scan) { + return EOrbitValidationResult::NonTargetableTarget; + } + } + + const EOrbitValidationResult type = ValidateOrbitTargetId(x310_orbitTargetId, mgr); + if (type != EOrbitValidationResult::OK) { return type; + } if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Scan && - act->GetAreaIdAlways() != GetAreaIdAlways()) + act->GetAreaIdAlways() != GetAreaIdAlways()) { return EOrbitValidationResult::TargetingThroughDoor; + } - TCastToConstPtr point = mgr.GetObjectById(x310_orbitTargetId); + const TCastToConstPtr point = mgr.GetObjectById(x310_orbitTargetId); if ((mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Scan && g_tweakPlayer->GetOrbitWhileScanning()) || point || act->GetAreaIdAlways() != GetAreaIdAlways()) { - zeus::CVector3f eyePos = GetEyePosition(); + const zeus::CVector3f eyePos = GetEyePosition(); TUniqueId bestId = kInvalidUniqueId; - zeus::CVector3f eyeToOrbit = act->GetOrbitPosition(mgr) - eyePos; + const zeus::CVector3f eyeToOrbit = act->GetOrbitPosition(mgr) - eyePos; if (eyeToOrbit.canBeNormalized()) { rstl::reserved_vector nearList; mgr.BuildNearList(nearList, eyePos, eyeToOrbit.normalized(), eyeToOrbit.magnitude(), OccluderFilter, @@ -4610,8 +5007,9 @@ CPlayer::EOrbitValidationResult CPlayer::ValidateCurrentOrbitTargetId(CStateMana if (ent->GetAreaIdAlways() != mgr.GetNextAreaId()) { const CGameArea* area = mgr.GetWorld()->GetAreaAlways(ent->GetAreaIdAlways()); CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::Occluded; - if (area->IsPostConstructed()) + if (area->IsPostConstructed()) { occState = area->GetOcclusionState(); + } if (occState == CGameArea::EOcclusionState::Occluded) { it = nearList.erase(it); continue; @@ -4621,24 +5019,28 @@ CPlayer::EOrbitValidationResult CPlayer::ValidateCurrentOrbitTargetId(CStateMana ++it; } - CRayCastResult result = mgr.RayWorldIntersection(bestId, eyePos, eyeToOrbit.normalized(), eyeToOrbit.magnitude(), - LineOfSightFilter, nearList); - if (result.IsValid()) - if (TCastToPtr(mgr.ObjectById(bestId)) || point) + const CRayCastResult result = mgr.RayWorldIntersection(bestId, eyePos, eyeToOrbit.normalized(), + eyeToOrbit.magnitude(), LineOfSightFilter, nearList); + if (result.IsValid()) { + if (TCastToConstPtr(mgr.ObjectById(bestId)) || point) { return EOrbitValidationResult::TargetingThroughDoor; + } + } } zeus::CVector3f eyeToOrbitFlat = eyeToOrbit; eyeToOrbitFlat.z() = 0.f; if (eyeToOrbitFlat.canBeNormalized()) { - float lookToOrbitAngle = + const float lookToOrbitAngle = std::acos(zeus::clamp(-1.f, eyeToOrbitFlat.normalized().dot(GetTransform().basis[1]), 1.f)); if (x374_orbitLockEstablished) { - if (lookToOrbitAngle >= g_tweakPlayer->GetOrbitHorizAngle()) + if (lookToOrbitAngle >= g_tweakPlayer->GetOrbitHorizAngle()) { return EOrbitValidationResult::BrokenLookAngle; + } } else { - if (lookToOrbitAngle <= M_PIF / 180.f) + if (lookToOrbitAngle <= M_PIF / 180.f) { x374_orbitLockEstablished = true; + } } } else { return EOrbitValidationResult::BrokenLookAngle; @@ -4649,8 +5051,9 @@ CPlayer::EOrbitValidationResult CPlayer::ValidateCurrentOrbitTargetId(CStateMana } bool CPlayer::ValidateOrbitTargetIdAndPointer(TUniqueId uid, CStateManager& mgr) const { - if (uid == kInvalidUniqueId) + if (uid == kInvalidUniqueId) { return false; + } return TCastToConstPtr(mgr.GetObjectById(uid)); } @@ -4665,16 +5068,19 @@ float CPlayer::GetEyeHeight() const { return x9c8_eyeZBias + (x2d8_fpBounds.max. float CPlayer::GetUnbiasedEyeHeight() const { return x2d8_fpBounds.max.z() - g_tweakPlayer->GetEyeOffset(); } float CPlayer::GetStepUpHeight() const { - if (x258_movementState == EPlayerMovementState::Jump || x258_movementState == EPlayerMovementState::ApplyJump) + if (x258_movementState == EPlayerMovementState::Jump || x258_movementState == EPlayerMovementState::ApplyJump) { return 0.3f; + } return CPhysicsActor::GetStepUpHeight(); } float CPlayer::GetStepDownHeight() const { - if (x258_movementState == EPlayerMovementState::Jump) + if (x258_movementState == EPlayerMovementState::Jump) { return -1.f; - if (x258_movementState == EPlayerMovementState::ApplyJump) + } + if (x258_movementState == EPlayerMovementState::ApplyJump) { return 0.1f; + } return CPhysicsActor::GetStepDownHeight(); } @@ -4706,8 +5112,9 @@ void CPlayer::Teleport(const zeus::CTransform& xf, CStateManager& mgr, bool rese zeus::CTransform eyeXf = x34_transform; eyeXf.origin = GetEyePosition(); mgr.GetCameraManager()->GetFirstPersonCamera()->Reset(eyeXf, mgr); - if (resetBallCam) + if (resetBallCam) { mgr.GetCameraManager()->GetBallCamera()->Reset(eyeXf, mgr); + } ForceGunOrientation(x34_transform, mgr); SetOrbitRequest(EPlayerOrbitRequest::Respawn, mgr); } @@ -4715,9 +5122,9 @@ void CPlayer::Teleport(const zeus::CTransform& xf, CStateManager& mgr, bool rese void CPlayer::BombJump(const zeus::CVector3f& pos, CStateManager& mgr) { if (x2f8_morphBallState == EPlayerMorphBallState::Morphed && x768_morphball->GetBombJumpState() != CMorphBall::EBombJumpState::BombJumpDisabled) { - zeus::CVector3f posToBall = + const zeus::CVector3f posToBall = GetTranslation() + zeus::CVector3f(0.f, 0.f, g_tweakPlayer->GetPlayerBallHalfExtent()) - pos; - float maxJump = g_tweakPlayer->GetBombJumpHeight(); + const float maxJump = g_tweakPlayer->GetBombJumpHeight(); if (posToBall.magSquared() < maxJump * maxJump && posToBall.dot(zeus::skUp) >= -g_tweakPlayer->GetPlayerBallHalfExtent()) { float upVel = @@ -4748,7 +5155,7 @@ void CPlayer::BombJump(const zeus::CVector3f& pos, CStateManager& mgr) { ++x9d0_bombJumpCount; } } else { - CBallCamera* ballCam = mgr.GetCameraManager()->GetBallCamera(); + const CBallCamera* ballCam = mgr.GetCameraManager()->GetBallCamera(); if (ballCam->GetTooCloseActorId() != kInvalidUniqueId && ballCam->GetTooCloseActorDistance() < 5.f) { x9d0_bombJumpCount = 1; x9d4_bombJumpCheckDelayFrames = 2; @@ -4763,10 +5170,11 @@ void CPlayer::BombJump(const zeus::CVector3f& pos, CStateManager& mgr) { zeus::CTransform CPlayer::CreateTransformFromMovementDirection() const { zeus::CVector3f moveDir = x50c_moveDir; - if (moveDir.canBeNormalized()) + if (moveDir.canBeNormalized()) { moveDir.normalize(); - else + } else { moveDir = zeus::skForward; + } return {zeus::CVector3f(moveDir.y(), -moveDir.x(), 0.f), moveDir, zeus::skUp, GetTranslation()}; } @@ -4785,8 +5193,11 @@ const CCollidableSphere* CPlayer::GetCollidableSphere() const { return &x768_mor zeus::CTransform CPlayer::GetPrimitiveTransform() const { return CPhysicsActor::GetPrimitiveTransform(); } void CPlayer::CollidedWith(TUniqueId id, const CCollisionInfoList& list, CStateManager& mgr) { - if (x2f8_morphBallState != EPlayerMorphBallState::Unmorphed) - x768_morphball->CollidedWith(id, list, mgr); + if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphed) { + return; + } + + x768_morphball->CollidedWith(id, list, mgr); } float CPlayer::GetBallMaxVelocity() const { @@ -4794,18 +5205,18 @@ float CPlayer::GetBallMaxVelocity() const { } float CPlayer::GetActualBallMaxVelocity(float dt) const { - ESurfaceRestraints surf = GetSurfaceRestraint(); - float friction = g_tweakBall->GetBallTranslationFriction(int(surf)); - float maxSpeed = g_tweakBall->GetBallTranslationMaxSpeed(int(surf)); - float acceleration = g_tweakBall->GetMaxBallTranslationAcceleration(int(surf)); + const ESurfaceRestraints surf = GetSurfaceRestraint(); + const float friction = g_tweakBall->GetBallTranslationFriction(int(surf)); + const float maxSpeed = g_tweakBall->GetBallTranslationMaxSpeed(int(surf)); + const float acceleration = g_tweakBall->GetMaxBallTranslationAcceleration(int(surf)); return -(friction * xe8_mass * maxSpeed / (acceleration * dt) - maxSpeed - friction); } float CPlayer::GetActualFirstPersonMaxVelocity(float dt) const { - ESurfaceRestraints surf = GetSurfaceRestraint(); - float friction = g_tweakPlayer->GetPlayerTranslationFriction(int(surf)); - float maxSpeed = g_tweakPlayer->GetPlayerTranslationMaxSpeed(int(surf)); - float acceleration = g_tweakPlayer->GetMaxTranslationalAcceleration(int(surf)); + const ESurfaceRestraints surf = GetSurfaceRestraint(); + const float friction = g_tweakPlayer->GetPlayerTranslationFriction(int(surf)); + const float maxSpeed = g_tweakPlayer->GetPlayerTranslationMaxSpeed(int(surf)); + const float acceleration = g_tweakPlayer->GetMaxTranslationalAcceleration(int(surf)); return -(friction * xe8_mass * maxSpeed / (acceleration * dt) - maxSpeed - friction); } @@ -4825,10 +5236,11 @@ void CPlayer::SetMoveState(EPlayerMovementState newState, CStateManager& mgr) { x2a0_ = 0.01f; x288_startingJumpTimeout = g_tweakPlayer->GetAllowedJumpTime(); x290_minJumpTimeout = g_tweakPlayer->GetAllowedJumpTime() - g_tweakPlayer->GetMinJumpTime(); - if (mgr.GetPlayerState()->GetItemAmount(CPlayerState::EItemType::SpaceJumpBoots) != 0) + if (mgr.GetPlayerState()->GetItemAmount(CPlayerState::EItemType::SpaceJumpBoots) != 0) { x28c_sjTimer = g_tweakPlayer->GetMaxDoubleJumpWindow(); - else + } else { x28c_sjTimer = 0.f; + } if (x294_jumpCameraTimer <= 0.f && x29c_fallCameraTimer <= 0.f && !x3dc_inFreeLook && !x3dd_lookButtonHeld) { x294_jumpCameraTimer = 0.01f; x2a4_cancelCameraPitch = false; @@ -4843,10 +5255,11 @@ void CPlayer::SetMoveState(EPlayerMovementState newState, CStateManager& mgr) { x288_startingJumpTimeout = g_tweakPlayer->GetAllowedLedgeTime(); x258_movementState = EPlayerMovementState::Falling; x2a0_ = 0.01f; - if (g_tweakPlayer->GetFallingDoubleJump()) + if (g_tweakPlayer->GetFallingDoubleJump()) { x28c_sjTimer = g_tweakPlayer->GetMaxDoubleJumpWindow(); - else + } else { x28c_sjTimer = 0.f; + } } break; case EPlayerMovementState::FallingMorphed: @@ -4859,8 +5272,9 @@ void CPlayer::SetMoveState(EPlayerMovementState newState, CStateManager& mgr) { x288_startingJumpTimeout = 0.f; x28c_sjTimer = 0.f; x2ac_surfaceRestraint = ESurfaceRestraints::Normal; - if (x2f8_morphBallState != EPlayerMorphBallState::Morphed) + if (x2f8_morphBallState != EPlayerMorphBallState::Morphed) { AddMaterial(EMaterialTypes::GroundCollider); + } x294_jumpCameraTimer = 0.f; x29c_fallCameraTimer = 0.f; x2a4_cancelCameraPitch = false; @@ -4882,11 +5296,13 @@ void CPlayer::SetMoveState(EPlayerMovementState newState, CStateManager& mgr) { } float CPlayer::JumpInput(const CFinalInput& input, CStateManager& mgr) { - if (IsMorphBallTransitioning()) + if (IsMorphBallTransitioning()) { return GetGravity() * xe8_mass; + } + float jumpFactor = 1.f; if (!mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit)) { - ESurfaceRestraints restraints = GetSurfaceRestraint(); + const ESurfaceRestraints restraints = GetSurfaceRestraint(); switch (restraints) { case ESurfaceRestraints::Water: jumpFactor = g_tweakPlayer->GetWaterJumpFactor(); @@ -4902,8 +5318,8 @@ float CPlayer::JumpInput(const CFinalInput& input, CStateManager& mgr) { } } - float vJumpAccel = g_tweakPlayer->GetVerticalJumpAccel(); - float hJumpAccel = g_tweakPlayer->GetHorizontalJumpAccel(); + const float vJumpAccel = g_tweakPlayer->GetVerticalJumpAccel(); + const float hJumpAccel = g_tweakPlayer->GetHorizontalJumpAccel(); float doubleJumpImpulse = g_tweakPlayer->GetDoubleJumpImpulse(); float vDoubleJumpAccel = g_tweakPlayer->GetVerticalDoubleJumpAccel(); float hDoubleJumpAccel = g_tweakPlayer->GetHorizontalDoubleJumpAccel(); @@ -4914,8 +5330,9 @@ float CPlayer::JumpInput(const CFinalInput& input, CStateManager& mgr) { hDoubleJumpAccel = g_tweakPlayer->GetSidewaysHorizontalDoubleJumpAccel(); } - if (x828_distanceUnderWater >= 0.8f * GetEyeHeight()) + if (x828_distanceUnderWater >= 0.8f * GetEyeHeight()) { doubleJumpImpulse *= jumpFactor; + } if (x258_movementState == EPlayerMovementState::ApplyJump) { if (g_tweakPlayer->GetMaxDoubleJumpWindow() - g_tweakPlayer->GetMinDoubleJumpWindow() >= x28c_sjTimer && @@ -4924,14 +5341,15 @@ float CPlayer::JumpInput(const CFinalInput& input, CStateManager& mgr) { x384_dashTimer = 0.f; x380_strafeInputAtDash = StrafeInput(input); if (g_tweakPlayer->GetImpulseDoubleJump()) { - zeus::CVector3f impulse(0.f, 0.f, (doubleJumpImpulse - x138_velocity.z()) * xe8_mass); + const zeus::CVector3f impulse(0.f, 0.f, (doubleJumpImpulse - x138_velocity.z()) * xe8_mass); ApplyImpulseWR(impulse, zeus::CAxisAngle()); } float forwards = ControlMapper::GetAnalogInput(ControlMapper::ECommands::Forward, input); - float backwards = ControlMapper::GetAnalogInput(ControlMapper::ECommands::Backward, input); - if (forwards < backwards) + const float backwards = ControlMapper::GetAnalogInput(ControlMapper::ECommands::Backward, input); + if (forwards < backwards) { forwards = ControlMapper::GetAnalogInput(ControlMapper::ECommands::Backward, input); + } return ((vDoubleJumpAccel - (vDoubleJumpAccel - hDoubleJumpAccel) * forwards) * xe8_mass) * jumpFactor; } @@ -4948,23 +5366,27 @@ float CPlayer::JumpInput(const CFinalInput& input, CStateManager& mgr) { return 0.f; } float forwards = ControlMapper::GetAnalogInput(ControlMapper::ECommands::Forward, input); - float backwards = ControlMapper::GetAnalogInput(ControlMapper::ECommands::Backward, input); - if (forwards < backwards) + const float backwards = ControlMapper::GetAnalogInput(ControlMapper::ECommands::Backward, input); + if (forwards < backwards) { forwards = ControlMapper::GetAnalogInput(ControlMapper::ECommands::Backward, input); + } return ((vJumpAccel - (vJumpAccel - hJumpAccel) * forwards) * xe8_mass) * jumpFactor; } - if (x258_movementState == EPlayerMovementState::Jump) + if (x258_movementState == EPlayerMovementState::Jump) { SetMoveState(EPlayerMovementState::ApplyJump, mgr); + } return 0.f; } float CPlayer::TurnInput(const CFinalInput& input) const { - if (x304_orbitState == EPlayerOrbitState::OrbitObject || x304_orbitState == EPlayerOrbitState::Grapple) + if (x304_orbitState == EPlayerOrbitState::OrbitObject || x304_orbitState == EPlayerOrbitState::Grapple) { return 0.f; - if (IsMorphBallTransitioning()) + } + if (IsMorphBallTransitioning()) { return 0.f; + } float left = ControlMapper::GetAnalogInput(ControlMapper::ECommands::TurnLeft, input); float right = ControlMapper::GetAnalogInput(ControlMapper::ECommands::TurnRight, input); @@ -4979,23 +5401,26 @@ float CPlayer::TurnInput(const CFinalInput& input) const { } else { if (!g_tweakPlayer->GetHoldButtonsForFreeLook() || x3dd_lookButtonHeld) { if (left < 0.01f && right < 0.01f) { - float f31 = ControlMapper::GetAnalogInput(ControlMapper::ECommands::LookLeft, input); - float f1 = ControlMapper::GetAnalogInput(ControlMapper::ECommands::LookRight, input); - if (f31 > 0.01f || f1 > 0.01f) + const float f31 = ControlMapper::GetAnalogInput(ControlMapper::ECommands::LookLeft, input); + const float f1 = ControlMapper::GetAnalogInput(ControlMapper::ECommands::LookRight, input); + if (f31 > 0.01f || f1 > 0.01f) { return 0.f; + } } } } right = left - right; - if (x32c_orbitModeTimer > 0.f) + if (x32c_orbitModeTimer > 0.f) { right *= (1.f - zeus::clamp(0.f, x32c_orbitModeTimer / g_tweakPlayer->GetOrbitModeTimer(), 1.f) * 0.5f); + } return zeus::clamp(-1.f, right, 1.f); } float CPlayer::StrafeInput(const CFinalInput& input) const { - if (IsMorphBallTransitioning() || x304_orbitState == EPlayerOrbitState::NoOrbit) + if (IsMorphBallTransitioning() || x304_orbitState == EPlayerOrbitState::NoOrbit) { return 0.f; + } return ControlMapper::GetAnalogInput(ControlMapper::ECommands::StrafeRight, input) - ControlMapper::GetAnalogInput(ControlMapper::ECommands::StrafeLeft, input); } @@ -5003,35 +5428,46 @@ float CPlayer::StrafeInput(const CFinalInput& input) const { float CPlayer::ForwardInput(const CFinalInput& input, float turnInput) const { float forwards = ControlMapper::GetAnalogInput(ControlMapper::ECommands::Forward, input); float backwards = ControlMapper::GetAnalogInput(ControlMapper::ECommands::Backward, input); - if (x2f8_morphBallState != EPlayerMorphBallState::Unmorphed || InGrappleJumpCooldown()) + + if (x2f8_morphBallState != EPlayerMorphBallState::Unmorphed || InGrappleJumpCooldown()) { backwards = 0.f; - if (x2f8_morphBallState == EPlayerMorphBallState::Morphing && x584_ballTransitionAnim == 2) + } + + if (x2f8_morphBallState == EPlayerMorphBallState::Morphing && x584_ballTransitionAnim == 2) { forwards = 0.f; - if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphing && x584_ballTransitionAnim == 5) + } + + if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphing && x584_ballTransitionAnim == 5) { forwards = 0.f; + } + if (forwards >= 0.001f) { forwards = zeus::clamp(-1.f, forwards / 0.8f, 1.f); if (std::fabs(std::atan2(std::fabs(turnInput), forwards)) < M_PIF / 3.6f) { - zeus::CVector3f x50(std::fabs(turnInput), forwards, 0.f); - if (x50.canBeNormalized()) + const zeus::CVector3f x50(std::fabs(turnInput), forwards, 0.f); + if (x50.canBeNormalized()) { forwards = x50.magnitude(); + } } } if (backwards >= 0.001f) { backwards = zeus::clamp(-1.f, backwards / 0.8f, 1.f); if (std::fabs(std::atan2(std::fabs(turnInput), backwards)) < M_PIF / 3.6f) { - zeus::CVector3f x5c(std::fabs(turnInput), backwards, 0.f); - if (x5c.canBeNormalized()) + const zeus::CVector3f x5c(std::fabs(turnInput), backwards, 0.f); + if (x5c.canBeNormalized()) { backwards = x5c.magnitude(); + } } } if (!g_tweakPlayer->GetMoveDuringFreeLook()) { zeus::CVector3f velFlat = x138_velocity; velFlat.z() = 0.f; - if (x3dc_inFreeLook || x3dd_lookButtonHeld) - if (x258_movementState == EPlayerMovementState::OnGround || std::fabs(velFlat.magnitude()) < 0.00001f) + if (x3dc_inFreeLook || x3dd_lookButtonHeld) { + if (x258_movementState == EPlayerMovementState::OnGround || std::fabs(velFlat.magnitude()) < 0.00001f) { return 0.f; + } + } } return zeus::clamp(-1.f, forwards - backwards * g_tweakPlayer->GetBackwardsForceMultiplier(), 1.f); @@ -5047,17 +5483,19 @@ zeus::CVector3f CPlayer::CalculateLeftStickEdgePosition(float strafeInput, float f30 = -f30; } - if (forwardInput < 0.f) + if (forwardInput < 0.f) { f29 = -0.555f; + } - float f4 = zeus::clamp(-1.f, std::atan(std::fabs(forwardInput) / std::fabs(strafeInput)) / (M_PIF / 4.f), 1.f); + const float f4 = zeus::clamp(-1.f, std::atan(std::fabs(forwardInput) / std::fabs(strafeInput)) / (M_PIF / 4.f), 1.f); return zeus::CVector3f(f30 - f31, f29, 0.f) * f4 + zeus::CVector3f(f31, 0.f, 0.f); } bool CPlayer::SidewaysDashAllowed(float strafeInput, float forwardInput, const CFinalInput& input, CStateManager& mgr) const { - if (x9c5_28_slidingOnWall || x9c5_29_hitWall || x304_orbitState != EPlayerOrbitState::OrbitObject) + if (x9c5_28_slidingOnWall || x9c5_29_hitWall || x304_orbitState != EPlayerOrbitState::OrbitObject) { return false; + } if (g_tweakPlayer->GetDashOnButtonRelease()) { if (x304_orbitState != EPlayerOrbitState::NoOrbit && g_tweakPlayer->GetDashEnabled() && @@ -5065,17 +5503,19 @@ bool CPlayer::SidewaysDashAllowed(float strafeInput, float forwardInput, const C !ControlMapper::GetDigitalInput(ControlMapper::ECommands::JumpOrBoost, input) && x388_dashButtonHoldTime < g_tweakPlayer->GetDashButtonHoldCancelTime() && std::fabs(strafeInput) >= std::fabs(forwardInput) && - std::fabs(strafeInput) > g_tweakPlayer->GetDashStrafeInputThreshold()) + std::fabs(strafeInput) > g_tweakPlayer->GetDashStrafeInputThreshold()) { return true; + } } else { if (x304_orbitState != EPlayerOrbitState::NoOrbit && g_tweakPlayer->GetDashEnabled() && ControlMapper::GetPressInput(ControlMapper::ECommands::JumpOrBoost, input) && x288_startingJumpTimeout > 0.f && std::fabs(strafeInput) >= std::fabs(forwardInput) && std::fabs(strafeInput) > 0.01f) { - float threshold = std::sqrt(strafeInput * strafeInput + forwardInput * forwardInput) / - CalculateLeftStickEdgePosition(strafeInput, forwardInput).magnitude(); - if (threshold >= g_tweakPlayer->GetDashStrafeInputThreshold()) + const float threshold = std::sqrt(strafeInput * strafeInput + forwardInput * forwardInput) / + CalculateLeftStickEdgePosition(strafeInput, forwardInput).magnitude(); + if (threshold >= g_tweakPlayer->GetDashStrafeInputThreshold()) { return true; + } } } @@ -5083,8 +5523,9 @@ bool CPlayer::SidewaysDashAllowed(float strafeInput, float forwardInput, const C } void CPlayer::FinishSidewaysDash() { - if (x37c_sidewaysDashing) + if (x37c_sidewaysDashing) { x38c_doneSidewaysDashing = true; + } x37c_sidewaysDashing = false; x380_strafeInputAtDash = 0.f; x384_dashTimer = 0.f; @@ -5162,74 +5603,85 @@ void CPlayer::ComputeDash(const CFinalInput& input, float dt, CStateManager& mgr const zeus::CVector3f velDelta(newVelocity.x() - x138_velocity.x(), newVelocity.y() - x138_velocity.y(), 0.f); strafeVel = velDelta.magnitude(); - if (strafeVel > FLT_EPSILON) { - const float accel = dt * GetAcceleration(); - newVelocity = velDelta / strafeVel * accel * zeus::clamp(-1.f, strafeVel / accel, 1.f) + x138_velocity; - if (!x9c5_28_slidingOnWall) { - SetVelocityWR(newVelocity); - } + if (strafeVel <= FLT_EPSILON) { + return; } + + const float accel = dt * GetAcceleration(); + newVelocity = velDelta / strafeVel * accel * zeus::clamp(-1.f, strafeVel / accel, 1.f) + x138_velocity; + if (x9c5_28_slidingOnWall) { + return; + } + + SetVelocityWR(newVelocity); } void CPlayer::ComputeMovement(const CFinalInput& input, CStateManager& mgr, float dt) { ESurfaceRestraints restraints = GetSurfaceRestraint(); - float jumpInput = JumpInput(input, mgr); + const float jumpInput = JumpInput(input, mgr); float zRotateInput = TurnInput(input); - float forwardInput = ForwardInput(input, zRotateInput); + const float forwardInput = ForwardInput(input, zRotateInput); SetVelocityWR(GetDampedClampedVelocityWR()); float turnSpeedMul = g_tweakPlayer->GetTurnSpeedMultiplier(); - if (g_tweakPlayer->GetFreeLookTurnsPlayer()) - if (!g_tweakPlayer->GetHoldButtonsForFreeLook() || x3dd_lookButtonHeld) + if (g_tweakPlayer->GetFreeLookTurnsPlayer()) { + if (!g_tweakPlayer->GetHoldButtonsForFreeLook() || x3dd_lookButtonHeld) { turnSpeedMul = g_tweakPlayer->GetFreeLookTurnSpeedMultiplier(); + } + } if (x304_orbitState == EPlayerOrbitState::NoOrbit || (x3dd_lookButtonHeld && x304_orbitState != EPlayerOrbitState::OrbitObject && x304_orbitState != EPlayerOrbitState::Grapple)) { if (std::fabs(zRotateInput) < 0.00001f) { - float frictionZAngVel = + const float frictionZAngVel = g_tweakPlayer->GetPlayerRotationFriction(int(restraints)) * GetAngularVelocityOR().getVector().z(); SetAngularVelocityOR({0.f, 0.f, frictionZAngVel}); } - float curZAngVel = GetAngularVelocityOR().getVector().z(); - float maxZAngVel = g_tweakPlayer->GetPlayerRotationMaxSpeed(int(restraints)) * turnSpeedMul; - if (curZAngVel > maxZAngVel) + const float curZAngVel = GetAngularVelocityOR().getVector().z(); + const float maxZAngVel = g_tweakPlayer->GetPlayerRotationMaxSpeed(int(restraints)) * turnSpeedMul; + if (curZAngVel > maxZAngVel) { SetAngularVelocityOR({0.f, 0.f, maxZAngVel}); - else if (-curZAngVel > maxZAngVel) + } else if (-curZAngVel > maxZAngVel) { SetAngularVelocityOR({0.f, 0.f, -maxZAngVel}); + } } float f26 = g_tweakPlayer->GetPlayerRotationMaxSpeed(int(restraints)) * zRotateInput * turnSpeedMul; f26 -= GetAngularVelocityOR().getVector().z(); - float remainVel = zeus::clamp( + const float remainVel = zeus::clamp( 0.f, std::fabs(f26) / (turnSpeedMul * g_tweakPlayer->GetPlayerRotationMaxSpeed(int(restraints))), 1.f); - if (f26 < 0.f) + if (f26 < 0.f) { zRotateInput = remainVel * -g_tweakPlayer->GetMaxRotationalAcceleration(int(restraints)); - else + } else { zRotateInput = remainVel * g_tweakPlayer->GetMaxRotationalAcceleration(int(restraints)); + } float forwardForce; if (std::fabs(forwardInput) >= 0.00001f) { - float maxSpeed = g_tweakPlayer->GetPlayerTranslationMaxSpeed(int(restraints)); - float calcSpeed = g_tweakPlayer->GetPlayerTranslationFriction(int(restraints)) * xe8_mass / - (dt * g_tweakPlayer->GetMaxTranslationalAcceleration(int(restraints))) * maxSpeed; - float f28 = (forwardInput > 0.f ? 1.f : -1.f) * calcSpeed + (maxSpeed - calcSpeed) * forwardInput; + const float maxSpeed = g_tweakPlayer->GetPlayerTranslationMaxSpeed(int(restraints)); + const float calcSpeed = g_tweakPlayer->GetPlayerTranslationFriction(int(restraints)) * xe8_mass / + (dt * g_tweakPlayer->GetMaxTranslationalAcceleration(int(restraints))) * maxSpeed; + const float f28 = (forwardInput > 0.f ? 1.f : -1.f) * calcSpeed + (maxSpeed - calcSpeed) * forwardInput; forwardForce = zeus::clamp(-1.f, (f28 - x34_transform.transposeRotate(x138_velocity).y()) / maxSpeed, 1.f) * g_tweakPlayer->GetMaxTranslationalAcceleration(int(restraints)); } else { forwardForce = 0.f; } - if (x304_orbitState != EPlayerOrbitState::NoOrbit && x3dd_lookButtonHeld) + if (x304_orbitState != EPlayerOrbitState::NoOrbit && x3dd_lookButtonHeld) { forwardForce = 0.f; + } if (x304_orbitState == EPlayerOrbitState::NoOrbit || x3dd_lookButtonHeld) { ApplyForceOR({0.f, forwardForce, jumpInput}, zeus::CAxisAngle()); - if (zRotateInput != 0.f) + if (zRotateInput != 0.f) { ApplyForceOR(zeus::skZero3f, zeus::CAxisAngle({0.f, 0.f, 1.f}, zRotateInput)); - if (x37c_sidewaysDashing) + } + if (x37c_sidewaysDashing) { x38c_doneSidewaysDashing = true; + } x37c_sidewaysDashing = false; x380_strafeInputAtDash = 0.f; x384_dashTimer = 0.f; @@ -5239,8 +5691,9 @@ void CPlayer::ComputeMovement(const CFinalInput& input, CStateManager& mgr, floa case EPlayerOrbitState::OrbitPoint: case EPlayerOrbitState::OrbitCarcass: case EPlayerOrbitState::ForcedOrbitObject: - if (!InGrappleJumpCooldown()) + if (!InGrappleJumpCooldown()) { ComputeDash(input, dt, mgr); + } break; default: break; @@ -5250,21 +5703,22 @@ void CPlayer::ComputeMovement(const CFinalInput& input, CStateManager& mgr, floa if (x3dc_inFreeLook || x3dd_lookButtonHeld) { if (!x9c5_28_slidingOnWall && x258_movementState == EPlayerMovementState::OnGround) { - zeus::CVector3f revVelFlat(-x138_velocity.x(), -x138_velocity.y(), 0.f); - float revVelFlatMag = revVelFlat.magnitude(); + const zeus::CVector3f revVelFlat(-x138_velocity.x(), -x138_velocity.y(), 0.f); + const float revVelFlatMag = revVelFlat.magnitude(); if (revVelFlatMag > FLT_EPSILON) { - float accel = 0.2f * dt * GetAcceleration(); - float damp = zeus::clamp(-1.f, revVelFlatMag / accel, 1.f); + const float accel = 0.2f * dt * GetAcceleration(); + const float damp = zeus::clamp(-1.f, revVelFlatMag / accel, 1.f); SetVelocityWR(revVelFlat / revVelFlatMag * accel * damp + x138_velocity); } } } x9c5_29_hitWall = false; - if (x2d4_accelerationChangeTimer > 0.f) + if (x2d4_accelerationChangeTimer > 0.f) { x2d0_curAcceleration = 0; - else + } else { x2d0_curAcceleration += 1; + } x2d4_accelerationChangeTimer -= dt; x2d4_accelerationChangeTimer = std::max(0.f, x2d4_accelerationChangeTimer); } @@ -5275,33 +5729,38 @@ zeus::CVector3f CPlayer::GetDampedClampedVelocityWR() const { zeus::CVector3f localVel = x34_transform.transposeRotate(x138_velocity); if ((x258_movementState != EPlayerMovementState::ApplyJump || GetSurfaceRestraint() != ESurfaceRestraints::Air) && x304_orbitState == EPlayerOrbitState::NoOrbit) { - float friction = g_tweakPlayer->GetPlayerTranslationFriction(int(GetSurfaceRestraint())); - if (localVel.y() > 0.f) + const float friction = g_tweakPlayer->GetPlayerTranslationFriction(int(GetSurfaceRestraint())); + if (localVel.y() > 0.f) { localVel.y() = std::max(0.f, localVel.y() - friction); - else + } else { localVel.y() = std::min(0.f, localVel.y() + friction); - if (localVel.x() > 0.f) + } + if (localVel.x() > 0.f) { localVel.x() = std::max(0.f, localVel.x() - friction); - else + } else { localVel.x() = std::min(0.f, localVel.x() + friction); + } } - float maxSpeed = g_tweakPlayer->GetPlayerTranslationMaxSpeed(int(GetSurfaceRestraint())); + const float maxSpeed = g_tweakPlayer->GetPlayerTranslationMaxSpeed(int(GetSurfaceRestraint())); localVel.y() = zeus::clamp(-maxSpeed, float(localVel.y()), maxSpeed); - if (x258_movementState == EPlayerMovementState::OnGround) + if (x258_movementState == EPlayerMovementState::OnGround) { localVel.z() = 0.f; + } return x34_transform.rotate(localVel); } const CScriptWater* CPlayer::GetVisorRunoffEffect(const CStateManager& mgr) const { - if (xc4_fluidId == kInvalidUniqueId) + if (xc4_fluidId == kInvalidUniqueId) { return nullptr; + } return TCastToConstPtr(mgr.GetObjectById(xc4_fluidId)).GetPtr(); } void CPlayer::SetMorphBallState(EPlayerMorphBallState state, CStateManager& mgr) { - if (x2f8_morphBallState == EPlayerMorphBallState::Morphed && state != EPlayerMorphBallState::Morphed) + if (x2f8_morphBallState == EPlayerMorphBallState::Morphed && state != EPlayerMorphBallState::Morphed) { x9c5_26_ = x9c4_31_inWaterMovement; + } x2f8_morphBallState = state; xf9_standardCollider = state == EPlayerMorphBallState::Morphed; @@ -5309,12 +5768,11 @@ void CPlayer::SetMorphBallState(EPlayerMorphBallState state, CStateManager& mgr) switch (x2f8_morphBallState) { case EPlayerMorphBallState::Unmorphed: if (x9c5_26_ && mgr.GetCameraManager()->GetFluidCounter() == 0) { - if (auto water = GetVisorRunoffEffect(mgr)) { + if (const auto* water = GetVisorRunoffEffect(mgr)) { if (const auto& effect = water->GetUnmorphVisorRunoffEffect()) { - CHUDBillboardEffect* sheets = new CHUDBillboardEffect( + auto* sheets = new CHUDBillboardEffect( *effect, {}, mgr.AllocateUniqueId(), true, "WaterSheets", CHUDBillboardEffect::GetNearClipDistance(mgr), - CHUDBillboardEffect::GetScaleForPOV(mgr), zeus::skWhite, zeus::skOne3f, - zeus::skZero3f); + CHUDBillboardEffect::GetScaleForPOV(mgr), zeus::skWhite, zeus::skOne3f, zeus::skZero3f); mgr.AddObject(sheets); } CSfxHandle hnd = @@ -5334,24 +5792,31 @@ void CPlayer::SetMorphBallState(EPlayerMorphBallState state, CStateManager& mgr) bool CPlayer::CanLeaveMorphBallState(CStateManager& mgr, zeus::CVector3f& pos) const { if (x768_morphball->IsProjectile() || !x590_leaveMorphballAllowed || - (IsUnderBetaMetroidAttack(mgr) && x2f8_morphBallState == EPlayerMorphBallState::Morphed)) + (IsUnderBetaMetroidAttack(mgr) && x2f8_morphBallState == EPlayerMorphBallState::Morphed)) { return false; - if (!x9c4_28_canLeaveMorphBall) + } + + if (!x9c4_28_canLeaveMorphBall) { return false; - CMaterialFilter filter = CMaterialFilter::MakeInclude({EMaterialTypes::Solid}); - zeus::CAABox aabb(x2d8_fpBounds.min - zeus::CVector3f(1.f) + GetTranslation(), - x2d8_fpBounds.max + zeus::CVector3f(1.f) + GetTranslation()); + } + + constexpr CMaterialFilter filter = CMaterialFilter::MakeInclude({EMaterialTypes::Solid}); + const zeus::CAABox aabb(x2d8_fpBounds.min - zeus::CVector3f(1.f) + GetTranslation(), + x2d8_fpBounds.max + zeus::CVector3f(1.f) + GetTranslation()); rstl::reserved_vector nearList; mgr.BuildColliderList(nearList, *this, aabb); const zeus::CAABox& baseAABB = GetBaseBoundingBox(); pos = zeus::skZero3f; + for (int i = 0; i < 8; ++i) { - zeus::CAABox aabb(baseAABB.min + pos + GetTranslation(), baseAABB.max + pos + GetTranslation()); - CCollidableAABox cAABB(aabb, CMaterialList()); - if (!CGameCollision::DetectCollisionBoolean(mgr, cAABB, zeus::CTransform(), filter, nearList)) + const zeus::CAABox aabb2(baseAABB.min + pos + GetTranslation(), baseAABB.max + pos + GetTranslation()); + const CCollidableAABox cAABB(aabb2, CMaterialList()); + if (!CGameCollision::DetectCollisionBoolean(mgr, cAABB, zeus::CTransform(), filter, nearList)) { return true; + } pos.z() += 0.1f; } + return false; } @@ -5359,16 +5824,20 @@ void CPlayer::SetHudDisable(float staticTimer, float outSpeed, float inSpeed) { x740_staticTimer = staticTimer; x744_staticOutSpeed = outSpeed; x748_staticInSpeed = inSpeed; - if (x744_staticOutSpeed != 0.f) + + if (x744_staticOutSpeed != 0.f) { return; - if (x740_staticTimer == 0.f) + } + + if (x740_staticTimer == 0.f) { x74c_visorStaticAlpha = 1.f; - else + } else { x74c_visorStaticAlpha = 0.f; + } } void CPlayer::SetIntoBallReadyAnimation(CStateManager& mgr) { - CAnimPlaybackParms parms(2, -1, 1.f, true); + const CAnimPlaybackParms parms(2, -1, 1.f, true); x64_modelData->GetAnimationData()->SetAnimation(parms, false); x64_modelData->GetAnimationData()->EnableLooping(false); x64_modelData->AdvanceAnimation(0.f, mgr, kInvalidAreaId, true); @@ -5400,8 +5869,9 @@ void CPlayer::LeaveMorphBallState(CStateManager& mgr) { bool CPlayer::CanEnterMorphBallState(CStateManager& mgr, float f1) const { if (x3b8_grappleState != EGrappleState::None || - (IsUnderBetaMetroidAttack(mgr) && x2f8_morphBallState == EPlayerMorphBallState::Unmorphed)) + (IsUnderBetaMetroidAttack(mgr) && x2f8_morphBallState == EPlayerMorphBallState::Unmorphed)) { return false; + } return x9c4_27_canEnterMorphBall; } @@ -5426,10 +5896,12 @@ void CPlayer::UpdateCinematicState(CStateManager& mgr) { if (mgr.GetCameraManager()->IsInCinematicCamera()) { if (x2f4_cameraState != EPlayerCameraState::Spawned) { x2fc_spawnedMorphBallState = x2f8_morphBallState; - if (x2fc_spawnedMorphBallState == EPlayerMorphBallState::Unmorphing) + if (x2fc_spawnedMorphBallState == EPlayerMorphBallState::Unmorphing) { x2fc_spawnedMorphBallState = EPlayerMorphBallState::Unmorphed; - if (x2fc_spawnedMorphBallState == EPlayerMorphBallState::Morphing) + } + if (x2fc_spawnedMorphBallState == EPlayerMorphBallState::Morphing) { x2fc_spawnedMorphBallState = EPlayerMorphBallState::Morphed; + } SetCameraState(EPlayerCameraState::Spawned, mgr); } } else { @@ -5479,9 +5951,12 @@ void CPlayer::UpdateCinematicState(CStateManager& mgr) { } void CPlayer::SetCameraState(EPlayerCameraState camState, CStateManager& stateMgr) { - if (x2f4_cameraState == camState) + if (x2f4_cameraState == camState) { return; + } + x2f4_cameraState = camState; + CCameraManager* camMgr = stateMgr.GetCameraManager(); switch (camState) { case EPlayerCameraState::FirstPerson: @@ -5497,8 +5972,9 @@ void CPlayer::SetCameraState(EPlayerCameraState camState, CStateManager& stateMg break; case EPlayerCameraState::Spawned: { bool ballLight = false; - if (TCastToPtr cineCam = camMgr->GetCurrentCamera(stateMgr)) + if (const TCastToConstPtr cineCam = camMgr->GetCurrentCamera(stateMgr)) { ballLight = x2f8_morphBallState == EPlayerMorphBallState::Morphed && cineCam->GetFlags() & 0x40; + } x768_morphball->SetBallLightActive(stateMgr, ballLight); break; } @@ -5506,16 +5982,18 @@ void CPlayer::SetCameraState(EPlayerCameraState camState, CStateManager& stateMg } bool CPlayer::IsEnergyLow(const CStateManager& mgr) const { - float lowThreshold = mgr.GetPlayerState()->GetItemCapacity(CPlayerState::EItemType::EnergyTanks) < 4 ? 30.f : 100.f; + const float lowThreshold = + mgr.GetPlayerState()->GetItemCapacity(CPlayerState::EItemType::EnergyTanks) < 4 ? 30.f : 100.f; return GetHealthInfo(mgr)->GetHP() < lowThreshold; } bool CPlayer::ObjectInScanningRange(TUniqueId id, const CStateManager& mgr) const { const CEntity* ent = mgr.GetObjectById(id); - if (TCastToConstPtr act = ent) { - zeus::CVector3f delta = act->GetTranslation() - GetTranslation(); - if (delta.canBeNormalized()) + if (const TCastToConstPtr act = ent) { + const zeus::CVector3f delta = act->GetTranslation() - GetTranslation(); + if (delta.canBeNormalized()) { return delta.magnitude() < g_tweakPlayer->GetScanningRange(); + } } return false; } @@ -5526,8 +6004,11 @@ void CPlayer::SetPlayerHitWallDuringMove() { } void CPlayer::Touch(CActor& actor, CStateManager& mgr) { - if (x2f8_morphBallState == EPlayerMorphBallState::Morphed) - x768_morphball->Touch(actor, mgr); + if (x2f8_morphBallState != EPlayerMorphBallState::Morphed) { + return; + } + + x768_morphball->Touch(actor, mgr); } void CPlayer::CVisorSteam::SetSteam(float targetAlpha, float alphaInDur, float alphaOutDur, CAssetId txtr, @@ -5554,29 +6035,34 @@ void CPlayer::CVisorSteam::Update(float dt) { } x1c_txtr.Reset(); - if (zeus::close_enough(x20_alpha, x0_curTargetAlpha) && zeus::close_enough(x20_alpha, 0.f)) + if (zeus::close_enough(x20_alpha, x0_curTargetAlpha) && zeus::close_enough(x20_alpha, 0.f)) { return; + } if (x20_alpha > x0_curTargetAlpha) { if (x24_delayTimer <= 0.f) { x20_alpha -= dt / x8_curAlphaOutDur; - if (x20_alpha < x0_curTargetAlpha) + if (x20_alpha < x0_curTargetAlpha) { x20_alpha = x0_curTargetAlpha; + } } else { x24_delayTimer -= dt; - if (x24_delayTimer < 0.f) + if (x24_delayTimer < 0.f) { x24_delayTimer = 0.f; + } } return; } - CToken tmpTex = g_SimplePool->GetObj({SBIG('TXTR'), xc_tex}); - if (!tmpTex) + const CToken tmpTex = g_SimplePool->GetObj({SBIG('TXTR'), xc_tex}); + if (!tmpTex) { return; + } x20_alpha += dt / x4_curAlphaInDur; - if (x20_alpha > x0_curTargetAlpha) + if (x20_alpha > x0_curTargetAlpha) { x20_alpha = x0_curTargetAlpha; + } x24_delayTimer = 0.1f; } @@ -5590,23 +6076,32 @@ void CPlayer::CFailsafeTest::Reset() { void CPlayer::CFailsafeTest::AddSample(EInputState state, const zeus::CVector3f& pos, const zeus::CVector3f& vel, const zeus::CVector2f& input) { - if (x0_stateSamples.size() >= 20) + if (x0_stateSamples.size() >= 20) { x0_stateSamples.resize(19); + } x0_stateSamples.insert(x0_stateSamples.begin(), state); - if (x54_posSamples.size() >= 20) + + if (x54_posSamples.size() >= 20) { x54_posSamples.resize(19); + } x54_posSamples.insert(x54_posSamples.begin(), pos); - if (x148_velSamples.size() >= 20) + + if (x148_velSamples.size() >= 20) { x148_velSamples.resize(19); + } x148_velSamples.insert(x148_velSamples.begin(), vel); - if (x23c_inputSamples.size() >= 20) + + if (x23c_inputSamples.size() >= 20) { x23c_inputSamples.resize(19); + } x23c_inputSamples.insert(x23c_inputSamples.begin(), input); } bool CPlayer::CFailsafeTest::Passes() const { - if (x0_stateSamples.size() != 20) + if (x0_stateSamples.size() != 20) { return false; + } + float posMag = 0.f; zeus::CAABox velAABB(x148_velSamples[0], x148_velSamples[0]); @@ -5619,34 +6114,38 @@ bool CPlayer::CFailsafeTest::Passes() const { u32 notEqualStates = 0; for (int i = 1; i < 20; ++i) { - float mag = (x54_posSamples[i - 1] - x54_posSamples[i]).magSquared(); - if (mag > FLT_EPSILON) + const float mag = (x54_posSamples[i - 1] - x54_posSamples[i]).magSquared(); + if (mag > FLT_EPSILON) { posMag += std::sqrt(mag); + } posAABB.accumulateBounds(x54_posSamples[i]); velAABB.accumulateBounds(x148_velSamples[i]); - float velMag = x148_velSamples[i].magnitude(); + const float velMag = x148_velSamples[i].magnitude(); minVelMag = std::min(minVelMag, velMag); maxVelMag = std::max(maxVelMag, velMag); - zeus::CVector3f inputVec2(x23c_inputSamples[i].x(), x23c_inputSamples[i].y(), 0.f); + const zeus::CVector3f inputVec2(x23c_inputSamples[i].x(), x23c_inputSamples[i].y(), 0.f); inputAABB.accumulateBounds(inputVec2); - if (x0_stateSamples[i] != x0_stateSamples[i - 1]) + if (x0_stateSamples[i] != x0_stateSamples[i - 1]) { notEqualStates += 1; + } } bool test1 = true; - if (posMag >= 1.f / 30.f && posMag >= minVelMag / 30.f) + if (posMag >= 1.f / 30.f && posMag >= minVelMag / 30.f) { test1 = false; + } if (notEqualStates == 0 && x0_stateSamples[0] == EInputState::StartingJump) { - float inputMag = (inputAABB.max - inputAABB.min).magnitude(); + const float inputMag = (inputAABB.max - inputAABB.min).magnitude(); zeus::CAABox inputFrom0AABB(inputAABB); inputFrom0AABB.accumulateBounds(zeus::skZero3f); bool test2 = true; - if ((inputFrom0AABB.max - inputFrom0AABB.min).magnitude() >= 0.01f && inputMag <= 1.5f) + if ((inputFrom0AABB.max - inputFrom0AABB.min).magnitude() >= 0.01f && inputMag <= 1.5f) { test2 = false; + } return test1 && test2; } @@ -5683,22 +6182,25 @@ void CPlayer::SetSpawnedMorphBallState(EPlayerMorphBallState state, CStateManage } void CPlayer::DecrementEnvironmentDamage() { - if (xa10_envDmgCounter == 0) + if (xa10_envDmgCounter == 0) { return; + } xa10_envDmgCounter--; } void CPlayer::IncrementEnvironmentDamage() { - if (xa10_envDmgCounter != 0) + if (xa10_envDmgCounter != 0) { xa10_envDmgCounter++; - else + } else { xa14_envDmgCameraShakeTimer = 0.f; + } } bool CPlayer::CheckSubmerged() const { - if (xe6_24_fluidCounter == 0) + if (xe6_24_fluidCounter == 0) { return false; + } return x828_distanceUnderWater >= (x2f8_morphBallState == EPlayerMorphBallState::Morphed ? 2.f * g_tweakPlayer->GetPlayerBallHalfExtent() @@ -5708,20 +6210,25 @@ bool CPlayer::CheckSubmerged() const { void CPlayer::UpdateSubmerged(CStateManager& mgr) { x82c_inLava = false; x828_distanceUnderWater = 0.f; - if (xe6_24_fluidCounter != 0) { - if (TCastToPtr water = mgr.ObjectById(xc4_fluidId)) { - x828_distanceUnderWater = - -(zeus::skUp.dot(x34_transform.origin) - water->GetTriggerBoundsWR().max.z()); - EFluidType fluidType = water->GetFluidPlane().GetFluidType(); - x82c_inLava = (fluidType == EFluidType::Lava || fluidType == EFluidType::ThickLava); - CheckSubmerged(); - } + + if (xe6_24_fluidCounter == 0) { + return; + } + + if (const TCastToConstPtr water = mgr.ObjectById(xc4_fluidId)) { + x828_distanceUnderWater = -(zeus::skUp.dot(x34_transform.origin) - water->GetTriggerBoundsWR().max.z()); + const EFluidType fluidType = water->GetFluidPlane().GetFluidType(); + x82c_inLava = (fluidType == EFluidType::Lava || fluidType == EFluidType::ThickLava); + CheckSubmerged(); } } void CPlayer::ApplySubmergedPitchBend(CSfxHandle& sfx) { - if (CheckSubmerged()) - CSfxManager::PitchBend(sfx, -1.f); + if (!CheckSubmerged()) { + return; + } + + CSfxManager::PitchBend(sfx, -1.f); } void CPlayer::DetachActorFromPlayer() { @@ -5732,22 +6239,25 @@ void CPlayer::DetachActorFromPlayer() { } bool CPlayer::AttachActorToPlayer(TUniqueId id, bool disableGun) { - if (x26c_attachedActor == kInvalidUniqueId) { - if (disableGun) - x490_gun->SetActorAttached(true); - x26c_attachedActor = id; - x270_attachedActorTime = 0.f; - xa28_attachedActorStruggle = 0.f; - x768_morphball->StopEffects(); - return true; + if (x26c_attachedActor != kInvalidUniqueId) { + return false; } - return false; + if (disableGun) { + x490_gun->SetActorAttached(true); + } + + x26c_attachedActor = id; + x270_attachedActorTime = 0.f; + xa28_attachedActorStruggle = 0.f; + x768_morphball->StopEffects(); + return true; } float CPlayer::GetAverageSpeed() const { - if (auto avg = x4a4_moveSpeedAvg.GetAverage()) + if (const auto avg = x4a4_moveSpeedAvg.GetAverage()) { return *avg; + } return x4f8_moveSpeed; } diff --git a/Runtime/World/CPlayer.hpp b/Runtime/World/CPlayer.hpp index ea6b8b169..bbe098bd5 100644 --- a/Runtime/World/CPlayer.hpp +++ b/Runtime/World/CPlayer.hpp @@ -367,8 +367,8 @@ public: void UpdateMorphBallTransition(float dt, CStateManager& mgr); void UpdateGunAlpha(); void UpdatePlayerSounds(float dt); - void Update(float, CStateManager& mgr); - void PostUpdate(float, CStateManager& mgr); + void Update(float dt, CStateManager& mgr); + void PostUpdate(float dt, CStateManager& mgr); bool StartSamusVoiceSfx(u16 sfx, float vol, int prio); bool IsPlayerDeadEnough() const; void AsyncLoadSuit(CStateManager& mgr); @@ -378,14 +378,14 @@ public: const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const CDamageInfo& info) const override; const CDamageVulnerability* GetDamageVulnerability() const override; - zeus::CVector3f GetHomingPosition(const CStateManager& mgr, float) const override; - zeus::CVector3f GetAimPosition(const CStateManager& mgr, float) const override; - void FluidFXThink(CActor::EFluidState, CScriptWater& water, CStateManager& mgr) override; + zeus::CVector3f GetHomingPosition(const CStateManager& mgr, float dt) const override; + zeus::CVector3f GetAimPosition(const CStateManager& mgr, float dt) const override; + void FluidFXThink(EFluidState state, CScriptWater& water, CStateManager& mgr) override; zeus::CVector3f GetDamageLocationWR() const { return x564_damageLocation; } float GetPrevDamageAmount() const { return x560_prevDamageAmt; } float GetDamageAmount() const { return x55c_damageAmt; } bool WasDamaged() const { return x558_wasDamaged; } - void TakeDamage(bool, const zeus::CVector3f&, float, EWeaponType, CStateManager& mgr); + void TakeDamage(bool significant, const zeus::CVector3f& location, float dam, EWeaponType type, CStateManager& mgr); void Accept(IVisitor& visitor) override; CHealthInfo* HealthInfo(CStateManager& mgr) override; bool IsUnderBetaMetroidAttack(const CStateManager& mgr) const; @@ -393,24 +393,24 @@ public: void Touch(CActor& actor, CStateManager& mgr) override; void DoPreThink(float dt, CStateManager& mgr); void DoThink(float dt, CStateManager& mgr); - void UpdateScanningState(const CFinalInput& input, CStateManager& mgr, float); + void UpdateScanningState(const CFinalInput& input, CStateManager& mgr, float dt); bool ValidateScanning(const CFinalInput& input, const CStateManager& mgr) const; void FinishNewScan(CStateManager& mgr); - void SetScanningState(EPlayerScanState, CStateManager& mgr); - void SetSpawnedMorphBallState(EPlayerMorphBallState, CStateManager&); + void SetScanningState(EPlayerScanState state, CStateManager& mgr); + void SetSpawnedMorphBallState(EPlayerMorphBallState state, CStateManager& mgr); bool GetExplorationMode() const; bool GetCombatMode() const; - void RenderGun(const CStateManager& mgr, const zeus::CVector3f&) const; - void Render(const CStateManager& mgr) const override; + void RenderGun(const CStateManager& mgr, const zeus::CVector3f& pos) const; + void Render(CStateManager& mgr) override; void RenderReflectedPlayer(CStateManager& mgr); - void PreRender(CStateManager& mgr, const zeus::CFrustum&) override; + void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; void CalculateRenderBounds() override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) override; void ComputeFreeLook(const CFinalInput& input); - void UpdateFreeLookState(const CFinalInput&, float dt, CStateManager&); + void UpdateFreeLookState(const CFinalInput& input, float dt, CStateManager& mgr); void UpdateFreeLook(float dt); - float GetMaximumPlayerPositiveVerticalVelocity(CStateManager&) const; - void ProcessInput(const CFinalInput&, CStateManager&); + float GetMaximumPlayerPositiveVerticalVelocity(CStateManager& mgr) const; + void ProcessInput(const CFinalInput& input, CStateManager& mgr); bool ShouldSampleFailsafe(CStateManager& mgr) const; void CalculateLeaveMorphBallDirection(const CFinalInput& input); void CalculatePlayerControlDirection(CStateManager& mgr); @@ -434,17 +434,17 @@ public: void ResetControlDirectionInterpolation(); void SetControlDirectionInterpolation(float time); void UpdatePlayerControlDirection(float dt, CStateManager& mgr); - void Think(float, CStateManager&) override; - void PreThink(float, CStateManager&) override; - void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; - void SetVisorSteam(float, float, float, CAssetId, bool); - void UpdateFootstepSounds(const CFinalInput& input, CStateManager&, float); + void Think(float dt, CStateManager& mgr) override; + void PreThink(float dt, CStateManager& mgr) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) override; + void SetVisorSteam(float targetAlpha, float alphaInDur, float alphaOutDir, CAssetId txtr, bool affectsThermal); + void UpdateFootstepSounds(const CFinalInput& input, CStateManager& mgr, float dt); u16 GetMaterialSoundUnderPlayer(const CStateManager& mgr, const u16* idList, size_t length, u16 defId) const; static u16 SfxIdFromMaterial(const CMaterialList& mat, const u16* idList, size_t tableLen, u16 defId); - void UpdateCrosshairsState(const CFinalInput&); + void UpdateCrosshairsState(const CFinalInput& input); void UpdateVisorTransition(float, CStateManager& mgr); - void UpdateVisorState(const CFinalInput&, float, CStateManager& mgr); - void UpdateGunState(const CFinalInput&, CStateManager& mgr); + void UpdateVisorState(const CFinalInput& input, float dt, CStateManager& mgr); + void UpdateGunState(const CFinalInput& input, CStateManager& mgr); void ResetGun(CStateManager& mgr); void UpdateArmAndGunTransforms(float dt, CStateManager& mgr); void ForceGunOrientation(const zeus::CTransform&, CStateManager& mgr); @@ -453,7 +453,7 @@ public: void UpdateCameraTimers(float dt, const CFinalInput& input); void UpdateMorphBallState(float dt, const CFinalInput&, CStateManager& mgr); CFirstPersonCamera& GetFirstPersonCamera(CStateManager& mgr); - void UpdateGunTransform(const zeus::CVector3f&, CStateManager& mgr); + void UpdateGunTransform(const zeus::CVector3f& gunPos, CStateManager& mgr); void UpdateAssistedAiming(const zeus::CTransform& xf, const CStateManager& mgr); void UpdateAimTargetPrediction(const zeus::CTransform& xf, const CStateManager& mgr); void ResetAimTargetPrediction(TUniqueId target); @@ -464,48 +464,48 @@ public: EGunHolsterState GetGunHolsterState() const { return x498_gunHolsterState; } EPlayerMovementState GetPlayerMovementState() const { return x258_movementState; } bool IsMorphBallTransitioning() const; - void UpdateGrappleArmTransform(const zeus::CVector3f&, CStateManager& mgr, float); + void UpdateGrappleArmTransform(const zeus::CVector3f& offset, CStateManager& mgr, float dt); float GetGravity() const; - void ApplyGrappleForces(const CFinalInput& input, CStateManager& mgr, float); + void ApplyGrappleForces(const CFinalInput& input, CStateManager& mgr, float dt); bool ValidateFPPosition(const zeus::CVector3f& pos, const CStateManager& mgr) const; void UpdateGrappleState(const CFinalInput& input, CStateManager& mgr); void ApplyGrappleJump(CStateManager& mgr); - void BeginGrapple(zeus::CVector3f&, CStateManager& mgr); - void BreakGrapple(EPlayerOrbitRequest, CStateManager& mgr); + void BeginGrapple(zeus::CVector3f& vec, CStateManager& mgr); + void BreakGrapple(EPlayerOrbitRequest req, CStateManager& mgr); void SetOrbitRequest(EPlayerOrbitRequest req, CStateManager& mgr); void SetOrbitRequestForTarget(TUniqueId id, EPlayerOrbitRequest req, CStateManager& mgr); bool InGrappleJumpCooldown() const; void PreventFallingCameraPitch(); - void OrbitCarcass(CStateManager&); - void OrbitPoint(EPlayerOrbitType, CStateManager& mgr); + void OrbitCarcass(CStateManager& mgr); + void OrbitPoint(EPlayerOrbitType type, CStateManager& mgr); zeus::CVector3f GetHUDOrbitTargetPosition() const; - void SetOrbitState(EPlayerOrbitState, CStateManager& mgr); - void SetOrbitTargetId(TUniqueId, CStateManager& mgr); - void UpdateOrbitPosition(float, CStateManager& mgr); + void SetOrbitState(EPlayerOrbitState state, CStateManager& mgr); + void SetOrbitTargetId(TUniqueId id, CStateManager& mgr); + void UpdateOrbitPosition(float dist, CStateManager& mgr); void UpdateOrbitZPosition(); void UpdateOrbitFixedPosition(); - void SetOrbitPosition(float, CStateManager& mgr); + void SetOrbitPosition(float dist, CStateManager& mgr); void UpdateAimTarget(CStateManager& mgr); - void UpdateAimTargetTimer(float); - bool ValidateAimTargetId(TUniqueId, CStateManager& mgr); - bool ValidateObjectForMode(TUniqueId, CStateManager& mgr) const; + void UpdateAimTargetTimer(float dt); + bool ValidateAimTargetId(TUniqueId uid, CStateManager& mgr); + bool ValidateObjectForMode(TUniqueId uid, CStateManager& mgr) const; TUniqueId FindAimTargetId(CStateManager& mgr) const; TUniqueId GetAimTarget() const { return x3f4_aimTarget; } - TUniqueId CheckEnemiesAgainstOrbitZone(const rstl::reserved_vector&, EPlayerZoneInfo, - EPlayerZoneType, CStateManager& mgr) const; + TUniqueId CheckEnemiesAgainstOrbitZone(const rstl::reserved_vector& list, EPlayerZoneInfo info, + EPlayerZoneType zone, CStateManager& mgr) const; TUniqueId FindOrbitTargetId(CStateManager& mgr) const; void UpdateOrbitableObjects(CStateManager& mgr); - TUniqueId FindBestOrbitableObject(const std::vector&, EPlayerZoneInfo, CStateManager& mgr) const; - void FindOrbitableObjects(const rstl::reserved_vector&, std::vector&, EPlayerZoneInfo, - EPlayerZoneType, CStateManager& mgr, bool) const; - bool WithinOrbitScreenBox(const zeus::CVector3f&, EPlayerZoneInfo, EPlayerZoneType) const; - bool WithinOrbitScreenEllipse(const zeus::CVector3f&, EPlayerZoneInfo) const; + TUniqueId FindBestOrbitableObject(const std::vector& ids, EPlayerZoneInfo info, CStateManager& mgr) const; + void FindOrbitableObjects(const rstl::reserved_vector& nearObjects, std::vector& listOut, + EPlayerZoneInfo zone, EPlayerZoneType type, CStateManager& mgr, bool onScreenTest) const; + bool WithinOrbitScreenBox(const zeus::CVector3f& screenCoords, EPlayerZoneInfo zone, EPlayerZoneType type) const; + bool WithinOrbitScreenEllipse(const zeus::CVector3f& screenCoords, EPlayerZoneInfo zone) const; bool CheckOrbitDisableSourceList(CStateManager& mgr); bool CheckOrbitDisableSourceList() const { return !x9e4_orbitDisableList.empty(); } - void RemoveOrbitDisableSource(TUniqueId); - void AddOrbitDisableSource(CStateManager& mgr, TUniqueId); - void UpdateOrbitPreventionTimer(float); - void UpdateOrbitModeTimer(float); + void RemoveOrbitDisableSource(TUniqueId uid); + void AddOrbitDisableSource(CStateManager& mgr, TUniqueId addId); + void UpdateOrbitPreventionTimer(float dt); + void UpdateOrbitModeTimer(float dt); void UpdateOrbitZone(CStateManager& mgr); void UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr); void ActivateOrbitSource(CStateManager& mgr); @@ -516,7 +516,7 @@ public: float GetOrbitMaxTargetDistance(CStateManager& mgr) const; EOrbitValidationResult ValidateOrbitTargetId(TUniqueId uid, CStateManager& mgr) const; EOrbitValidationResult ValidateCurrentOrbitTargetId(CStateManager& mgr); - bool ValidateOrbitTargetIdAndPointer(TUniqueId, CStateManager& mgr) const; + bool ValidateOrbitTargetIdAndPointer(TUniqueId uid, CStateManager& mgr) const; zeus::CVector3f GetBallPosition() const; zeus::CVector3f GetEyePosition() const; float GetEyeHeight() const; @@ -529,15 +529,15 @@ public: const CCollisionPrimitive* GetCollisionPrimitive() const override; const CCollidableSphere* GetCollidableSphere() const; zeus::CTransform GetPrimitiveTransform() const override; - void CollidedWith(TUniqueId, const CCollisionInfoList&, CStateManager& mgr) override; + void CollidedWith(TUniqueId id, const CCollisionInfoList& list, CStateManager& mgr) override; float GetBallMaxVelocity() const; float GetActualBallMaxVelocity(float dt) const; float GetActualFirstPersonMaxVelocity(float dt) const; - void SetMoveState(EPlayerMovementState, CStateManager& mgr); + void SetMoveState(EPlayerMovementState newState, CStateManager& mgr); float JumpInput(const CFinalInput& input, CStateManager& mgr); float TurnInput(const CFinalInput& input) const; float StrafeInput(const CFinalInput& input) const; - float ForwardInput(const CFinalInput& input, float) const; + float ForwardInput(const CFinalInput& input, float turnInput) const; zeus::CVector3f CalculateLeftStickEdgePosition(float strafeInput, float forwardInput) const; bool SidewaysDashAllowed(float strafeInput, float forwardInput, const CFinalInput& input, CStateManager& mgr) const; void FinishSidewaysDash(); diff --git a/Runtime/World/CPlayerEnergyDrain.cpp b/Runtime/World/CPlayerEnergyDrain.cpp index c4b51ebfd..602217c30 100644 --- a/Runtime/World/CPlayerEnergyDrain.cpp +++ b/Runtime/World/CPlayerEnergyDrain.cpp @@ -1,5 +1,7 @@ #include "Runtime/World/CPlayerEnergyDrain.hpp" +#include + #include "Runtime/CStateManager.hpp" namespace urde { @@ -16,12 +18,8 @@ void CPlayerEnergyDrain::RemoveEnergyDrainSource(TUniqueId id) { } float CPlayerEnergyDrain::GetEnergyDrainIntensity() const { - float intensity = 0.f; - - for (const CEnergyDrainSource& src : x0_sources) - intensity += src.GetEnergyDrainIntensity(); - - return intensity; + return std::accumulate(x0_sources.cbegin(), x0_sources.cend(), 0.0f, + [](float value, const auto& src) { return value + src.GetEnergyDrainIntensity(); }); } void CPlayerEnergyDrain::ProcessEnergyDrain(const CStateManager& mgr, float dt) { diff --git a/Runtime/World/CRippleManager.hpp b/Runtime/World/CRippleManager.hpp index be1b2f2e2..2de208590 100644 --- a/Runtime/World/CRippleManager.hpp +++ b/Runtime/World/CRippleManager.hpp @@ -15,7 +15,7 @@ class CRippleManager { public: CRippleManager(int maxRipples, float alpha); void Init(int maxRipples); - std::vector& Ripples() { return x4_ripples; } + std::vector& GetRipples() { return x4_ripples; } const std::vector& GetRipples() const { return x4_ripples; } void Update(float dt); float GetLastRippleDeltaTime(TUniqueId rippler) const; diff --git a/Runtime/World/CScannableParameters.hpp b/Runtime/World/CScannableParameters.hpp index 93a6a4739..8977a0e42 100644 --- a/Runtime/World/CScannableParameters.hpp +++ b/Runtime/World/CScannableParameters.hpp @@ -8,8 +8,8 @@ class CScannableParameters { CAssetId x0_scanId; public: - CScannableParameters() = default; - CScannableParameters(CAssetId id) : x0_scanId(id) {} - CAssetId GetScanId() const { return x0_scanId; } + constexpr CScannableParameters() = default; + constexpr explicit CScannableParameters(CAssetId id) : x0_scanId(id) {} + [[nodiscard]] constexpr CAssetId GetScanId() const { return x0_scanId; } }; } // namespace urde diff --git a/Runtime/World/CScriptAiJumpPoint.hpp b/Runtime/World/CScriptAiJumpPoint.hpp index 31dfce661..1f62259a8 100644 --- a/Runtime/World/CScriptAiJumpPoint.hpp +++ b/Runtime/World/CScriptAiJumpPoint.hpp @@ -29,8 +29,8 @@ public: void Accept(IVisitor& visitor) override; void Think(float, CStateManager&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override {} - void Render(const CStateManager&) const override {} + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override {} + void Render(CStateManager&) override {} std::optional GetTouchBounds() const override; bool GetInUse(TUniqueId uid) const; TUniqueId GetJumpPoint() const { return x10c_currentWaypoint; } diff --git a/Runtime/World/CScriptCameraHint.cpp b/Runtime/World/CScriptCameraHint.cpp index 520ba94c8..973174ff9 100644 --- a/Runtime/World/CScriptCameraHint.cpp +++ b/Runtime/World/CScriptCameraHint.cpp @@ -40,7 +40,7 @@ void CScriptCameraHint::InitializeInArea(CStateManager& mgr) { continue; TUniqueId id = mgr.GetIdForScript(conn2.x8_objId); if (TCastToPtr(mgr.ObjectById(id)) || TCastToPtr(mgr.ObjectById((id)))) { - it = ent->ConnectionList().erase(it); + it = ent->GetConnectionList().erase(it); if (x164_delegatedCamera != id) x164_delegatedCamera = id; break; diff --git a/Runtime/World/CScriptCameraWaypoint.hpp b/Runtime/World/CScriptCameraWaypoint.hpp index 26f8d9c51..014037d73 100644 --- a/Runtime/World/CScriptCameraWaypoint.hpp +++ b/Runtime/World/CScriptCameraWaypoint.hpp @@ -17,8 +17,8 @@ public: void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override {} - void Render(const CStateManager&) const override {} + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override {} + void Render(CStateManager&) override {} TUniqueId GetRandomNextWaypointId(CStateManager& mgr) const; float GetHFov() const { return xe8_hfov; } }; diff --git a/Runtime/World/CScriptCoverPoint.hpp b/Runtime/World/CScriptCoverPoint.hpp index c644d3832..176636db9 100644 --- a/Runtime/World/CScriptCoverPoint.hpp +++ b/Runtime/World/CScriptCoverPoint.hpp @@ -40,9 +40,9 @@ public: void Accept(IVisitor& visitor) override; void Think(float, CStateManager&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override {} + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override {} void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; - void Render(const CStateManager&) const override {} + void Render(CStateManager&) override {} std::optional GetTouchBounds() const override; void SetInUse(bool inUse); bool GetInUse(TUniqueId uid) const; diff --git a/Runtime/World/CScriptDamageableTrigger.cpp b/Runtime/World/CScriptDamageableTrigger.cpp index 59b0796df..3b0a6040b 100644 --- a/Runtime/World/CScriptDamageableTrigger.cpp +++ b/Runtime/World/CScriptDamageableTrigger.cpp @@ -105,7 +105,7 @@ EWeaponCollisionResponseTypes CScriptDamageableTrigger::GetCollisionResponseType : EWeaponCollisionResponseTypes::Unknown15; } -void CScriptDamageableTrigger::Render(const CStateManager& mgr) const { +void CScriptDamageableTrigger::Render(CStateManager& mgr) { if (x30_24_active && x1dc_faceFlag != 0 && std::fabs(x1e0_alpha) >= 0.00001f) { zeus::CAABox aabb = x14c_bounds.getTransformedAABox(x214_faceDirInv); zeus::CTransform xf = x34_transform * zeus::CTransform::Translate(x244_faceTranslate) * x1e4_faceDir; @@ -116,9 +116,11 @@ void CScriptDamageableTrigger::Render(const CStateManager& mgr) const { CActor::Render(mgr); } -void CScriptDamageableTrigger::AddToRenderer(const zeus::CFrustum& /*frustum*/, const CStateManager& mgr) const { - if (x300_26_outOfFrustum) +void CScriptDamageableTrigger::AddToRenderer(const zeus::CFrustum& /*frustum*/, CStateManager& mgr) { + if (x300_26_outOfFrustum) { return; + } + EnsureRendered(mgr, GetTranslation() - x244_faceTranslate, GetSortingBounds(mgr)); } diff --git a/Runtime/World/CScriptDamageableTrigger.hpp b/Runtime/World/CScriptDamageableTrigger.hpp index 2f7bead29..590cff53b 100644 --- a/Runtime/World/CScriptDamageableTrigger.hpp +++ b/Runtime/World/CScriptDamageableTrigger.hpp @@ -17,12 +17,7 @@ namespace urde { class CVisorParameters; class CScriptDamageableTrigger : public CActor { -public: - enum class ECanOrbit { - NoOrbit, - Orbit, - }; - +private: zeus::CFrustum xe8_frustum; zeus::CAABox x14c_bounds; CHealthInfo x164_origHInfo; @@ -34,7 +29,7 @@ public: zeus::CTransform x214_faceDirInv; zeus::CVector3f x244_faceTranslate; float x250_alphaTimer = 0.f; - CFluidPlaneDoor x254_fluidPlane; + mutable CFluidPlaneDoor x254_fluidPlane; union { struct { bool x300_24_notOccluded : 1; @@ -49,6 +44,11 @@ public: float GetPuddleAlphaScale() const; public: + enum class ECanOrbit { + NoOrbit, + Orbit, + }; + CScriptDamageableTrigger(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CVector3f& position, const zeus::CVector3f& extent, const CHealthInfo& hInfo, const CDamageVulnerability& dVuln, u32 faceFlag, CAssetId patternTex1, CAssetId patternTex2, @@ -58,8 +58,8 @@ public: void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, const CWeaponMode&, EProjectileAttrib) const override; - void Render(const CStateManager& mgr) const override; - void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; + void Render(CStateManager& mgr) override; + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) override; void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; const CDamageVulnerability* GetDamageVulnerability() const override { return &x174_dVuln; } CHealthInfo* HealthInfo(CStateManager&) override { return &x16c_hInfo; } diff --git a/Runtime/World/CScriptDebris.cpp b/Runtime/World/CScriptDebris.cpp index 5c7c669e7..740c2bda1 100644 --- a/Runtime/World/CScriptDebris.cpp +++ b/Runtime/World/CScriptDebris.cpp @@ -143,21 +143,28 @@ CScriptDebris::CScriptDebris(TUniqueId uid, std::string_view name, const CEntity void CScriptDebris::Accept(IVisitor& visitor) { visitor.Visit(this); } -void CScriptDebris::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { - if (x2d4_particleGens[0]) - if (x270_curTime < x274_duration || x281_26_deferDeleteTillParticle1Done) +void CScriptDebris::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { + 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) + if (x2d4_particleGens[1]) { + if (x270_curTime < x274_duration || x281_28_deferDeleteTillParticle2Done) { g_Renderer->AddParticleGen(*x2d4_particleGens[1]); + } + } - if (x281_29_particle3Active) + if (x281_29_particle3Active) { g_Renderer->AddParticleGen(*x2d4_particleGens[2]); + } - if (x64_modelData && !x64_modelData->IsNull()) - if (x270_curTime < x274_duration) + 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) { @@ -372,7 +379,7 @@ void CScriptDebris::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) xb4_drawFlags = CModelFlags(5, 0, 3, zeus::CColor::lerp(zeus::skWhite, x268_endsColor, t)); } -void CScriptDebris::Render(const CStateManager& mgr) const { CPhysicsActor::Render(mgr); } +void CScriptDebris::Render(CStateManager& mgr) { CPhysicsActor::Render(mgr); } void CScriptDebris::CollidedWith(TUniqueId, const CCollisionInfoList& colList, CStateManager&) { if (colList.GetCount() == 0) diff --git a/Runtime/World/CScriptDebris.hpp b/Runtime/World/CScriptDebris.hpp index 8121c352d..bf7ca8cfa 100644 --- a/Runtime/World/CScriptDebris.hpp +++ b/Runtime/World/CScriptDebris.hpp @@ -78,13 +78,13 @@ public: bool noBounce, bool active); void Accept(IVisitor& visitor) override; - void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) override; void Think(float dt, CStateManager& mgr) override; void Touch(CActor& other, CStateManager& mgr) override; std::optional GetTouchBounds() const override; void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; - void Render(const CStateManager& mgr) const override; + void Render(CStateManager& mgr) override; void CollidedWith(TUniqueId uid, const CCollisionInfoList&, CStateManager&) override; }; diff --git a/Runtime/World/CScriptDoor.cpp b/Runtime/World/CScriptDoor.cpp index 0d392dacb..f58c5dda8 100644 --- a/Runtime/World/CScriptDoor.cpp +++ b/Runtime/World/CScriptDoor.cpp @@ -197,9 +197,12 @@ void CScriptDoor::Think(float dt, CStateManager& mgr) { xe7_31_targetable = mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Scan; } -void CScriptDoor::AddToRenderer(const zeus::CFrustum& /*frustum*/, const CStateManager& mgr) const { - if (!xe4_30_outOfFrustum) - CPhysicsActor::Render(mgr); +void CScriptDoor::AddToRenderer(const zeus::CFrustum& /*frustum*/, CStateManager& mgr) { + if (xe4_30_outOfFrustum) { + return; + } + + CPhysicsActor::Render(mgr); } /* ORIGINAL 0-00 OFFSET: 8007E0BC */ @@ -314,7 +317,7 @@ CScriptDoor::EDoorOpenCondition CScriptDoor::GetDoorOpenCondition(CStateManager& if (connArea == kInvalidAreaId) return EDoorOpenCondition::NotReady; - const CWorld* world = mgr.GetWorld(); + CWorld* world = mgr.GetWorld(); const CGameArea* area = world->GetAreaAlways(connArea); if (!area->IsPostConstructed()) { diff --git a/Runtime/World/CScriptDoor.hpp b/Runtime/World/CScriptDoor.hpp index e87f15267..5ae6d6324 100644 --- a/Runtime/World/CScriptDoor.hpp +++ b/Runtime/World/CScriptDoor.hpp @@ -51,8 +51,8 @@ public: void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; void Think(float, CStateManager& mgr) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager& mgr) const override; - void Render(const CStateManager&) const override {} + void AddToRenderer(const zeus::CFrustum&, CStateManager& mgr) override; + void Render(CStateManager&) override {} void ForceClosed(CStateManager&); bool IsConnectedToArea(const CStateManager& mgr, TAreaId area) const; void OpenDoor(TUniqueId, CStateManager&); diff --git a/Runtime/World/CScriptEMPulse.cpp b/Runtime/World/CScriptEMPulse.cpp index 6ba18efdc..34e45251a 100644 --- a/Runtime/World/CScriptEMPulse.cpp +++ b/Runtime/World/CScriptEMPulse.cpp @@ -55,10 +55,11 @@ void CScriptEMPulse::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CS } } -void CScriptEMPulse::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { +void CScriptEMPulse::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { CActor::AddToRenderer(frustum, mgr); - if (GetActive()) + if (GetActive()) { g_Renderer->AddParticleGen(*x114_particleGen); + } } void CScriptEMPulse::CalculateRenderBounds() { x9c_renderBounds = CalculateBoundingBox(); } diff --git a/Runtime/World/CScriptEMPulse.hpp b/Runtime/World/CScriptEMPulse.hpp index 6f8e4d5be..4a3bcbcab 100644 --- a/Runtime/World/CScriptEMPulse.hpp +++ b/Runtime/World/CScriptEMPulse.hpp @@ -27,7 +27,7 @@ public: void Accept(IVisitor&) override; void Think(float, CStateManager&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; void CalculateRenderBounds() override; std::optional GetTouchBounds() const override; void Touch(CActor&, CStateManager&) override; diff --git a/Runtime/World/CScriptEffect.cpp b/Runtime/World/CScriptEffect.cpp index 80c45fadb..523ae2ace 100644 --- a/Runtime/World/CScriptEffect.cpp +++ b/Runtime/World/CScriptEffect.cpp @@ -207,37 +207,39 @@ void CScriptEffect::PreRender(CStateManager& mgr, const zeus::CFrustum&) { x13c_triggerId = kInvalidUniqueId; } -void CScriptEffect::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { +void CScriptEffect::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { if (!x111_26_canRender) { - const_cast(*this).x12c_remTime = zeus::max(x12c_remTime, x134_durationResetWhileVisible); + x12c_remTime = zeus::max(x12c_remTime, x134_durationResetWhileVisible); return; } - if (!frustum.aabbFrustumTest(x9c_renderBounds)) + if (!frustum.aabbFrustumTest(x9c_renderBounds)) { return; - const_cast(*this).x12c_remTime = zeus::max(x12c_remTime, x134_durationResetWhileVisible); + } + x12c_remTime = zeus::max(x12c_remTime, x134_durationResetWhileVisible); if (x110_31_anyVisorVisible) { bool visible = false; const CPlayerState::EPlayerVisor visor = mgr.GetPlayerState()->GetActiveVisor(mgr); - if (visor == CPlayerState::EPlayerVisor::Combat || visor == CPlayerState::EPlayerVisor::Scan) + if (visor == CPlayerState::EPlayerVisor::Combat || visor == CPlayerState::EPlayerVisor::Scan) { visible = x110_28_combatVisorVisible; - else if (visor == CPlayerState::EPlayerVisor::XRay) + } else if (visor == CPlayerState::EPlayerVisor::XRay) { visible = x110_30_xrayVisorVisible; - else if (visor == CPlayerState::EPlayerVisor::Thermal) + } else if (visor == CPlayerState::EPlayerVisor::Thermal) { visible = x110_29_thermalVisorVisible; + } if (visible && x138_actorLights) { const CGameArea* area = mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways()); - const_cast(*this).x138_actorLights->BuildAreaLightList( + x138_actorLights->BuildAreaLightList( mgr, *area, zeus::CAABox{x9c_renderBounds.center(), x9c_renderBounds.center()}); - const_cast(*this).x138_actorLights->BuildDynamicLightList(mgr, x9c_renderBounds); + x138_actorLights->BuildDynamicLightList(mgr, x9c_renderBounds); } EnsureRendered(mgr); } } -void CScriptEffect::Render(const CStateManager& mgr) const { +void CScriptEffect::Render(CStateManager& mgr) { /* The following code is kept for reference, this is now performed in CElementGen if (x138_actorLights) x138_actorLights->ActivateLights(); diff --git a/Runtime/World/CScriptEffect.hpp b/Runtime/World/CScriptEffect.hpp index c01f617cb..384b62130 100644 --- a/Runtime/World/CScriptEffect.hpp +++ b/Runtime/World/CScriptEffect.hpp @@ -60,8 +60,8 @@ public: void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void PreRender(CStateManager&, const zeus::CFrustum&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager&) override; void Think(float, CStateManager&) override; bool CanRenderUnsorted(const CStateManager&) const override { return false; } void SetActive(bool active) override { diff --git a/Runtime/World/CScriptGrapplePoint.cpp b/Runtime/World/CScriptGrapplePoint.cpp index 67cf77195..7d96927c4 100644 --- a/Runtime/World/CScriptGrapplePoint.cpp +++ b/Runtime/World/CScriptGrapplePoint.cpp @@ -40,13 +40,13 @@ void CScriptGrapplePoint::Think(float, CStateManager&) { // Empty } -void CScriptGrapplePoint::Render(const CStateManager&) const { +void CScriptGrapplePoint::Render(CStateManager&) { // Empty } std::optional CScriptGrapplePoint::GetTouchBounds() const { return {xe8_touchBounds}; } -void CScriptGrapplePoint::AddToRenderer(const zeus::CFrustum&, const CStateManager& mgr) const { +void CScriptGrapplePoint::AddToRenderer(const zeus::CFrustum&, CStateManager& mgr) { CActor::EnsureRendered(mgr); } diff --git a/Runtime/World/CScriptGrapplePoint.hpp b/Runtime/World/CScriptGrapplePoint.hpp index 13a616670..eb67176f5 100644 --- a/Runtime/World/CScriptGrapplePoint.hpp +++ b/Runtime/World/CScriptGrapplePoint.hpp @@ -19,9 +19,9 @@ public: void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float, CStateManager&) override; - void Render(const CStateManager&) const override; + void Render(CStateManager&) override; std::optional GetTouchBounds() const override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; const CGrappleParameters& GetGrappleParameters() const { return x100_parameters; } }; } // namespace urde diff --git a/Runtime/World/CScriptGunTurret.cpp b/Runtime/World/CScriptGunTurret.cpp index 1ebc061fa..774a4319e 100644 --- a/Runtime/World/CScriptGunTurret.cpp +++ b/Runtime/World/CScriptGunTurret.cpp @@ -444,11 +444,12 @@ void CScriptGunTurret::PlayAdditiveFlinchAnimation(CStateManager& mgr) { GetModelData()->GetAnimationData()->AddAdditiveAnimation(pair.second, 1.f, false, true); } -void CScriptGunTurret::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { +void CScriptGunTurret::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { CActor::AddToRenderer(frustum, mgr); - if (x258_type != ETurretComponent::Gun) + if (x258_type != ETurretComponent::Gun) { return; + } if (!x560_25_frozen) { switch (x520_state) { @@ -471,8 +472,9 @@ void CScriptGunTurret::AddToRenderer(const zeus::CFrustum& frustum, const CState case ETurretState::ExitTargeting: case ETurretState::Frenzy: g_Renderer->AddParticleGen(*x478_targettingLight); - if (x520_state == ETurretState::Firing || x520_state == ETurretState::Frenzy) + if (x520_state == ETurretState::Firing || x520_state == ETurretState::Frenzy) { g_Renderer->AddParticleGen(*x488_chargingEffect); + } break; default: break; @@ -482,7 +484,7 @@ void CScriptGunTurret::AddToRenderer(const zeus::CFrustum& frustum, const CState } } -void CScriptGunTurret::Render(const CStateManager& mgr) const { +void CScriptGunTurret::Render(CStateManager& mgr) { CPhysicsActor::Render(mgr); if (x258_type == ETurretComponent::Gun) { diff --git a/Runtime/World/CScriptGunTurret.hpp b/Runtime/World/CScriptGunTurret.hpp index 0a786761d..779005a86 100644 --- a/Runtime/World/CScriptGunTurret.hpp +++ b/Runtime/World/CScriptGunTurret.hpp @@ -227,8 +227,8 @@ public: void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float, CStateManager&) override; void Touch(CActor&, CStateManager&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager&) override; std::optional GetTouchBounds() const override; zeus::CVector3f GetOrbitPosition(const CStateManager&) const override; zeus::CVector3f GetAimPosition(const CStateManager&, float) const override; diff --git a/Runtime/World/CScriptHUDMemo.hpp b/Runtime/World/CScriptHUDMemo.hpp index 78a96f55e..75949946a 100644 --- a/Runtime/World/CScriptHUDMemo.hpp +++ b/Runtime/World/CScriptHUDMemo.hpp @@ -4,11 +4,11 @@ #include #include "Runtime/CToken.hpp" +#include "Runtime/GuiSys/CStringTable.hpp" #include "Runtime/World/CEntity.hpp" #include "Runtime/World/CHUDMemoParms.hpp" namespace urde { -class CStringTable; class CScriptHUDMemo : public CEntity { public: diff --git a/Runtime/World/CScriptPickupGenerator.cpp b/Runtime/World/CScriptPickupGenerator.cpp index ed7d72add..684384f66 100644 --- a/Runtime/World/CScriptPickupGenerator.cpp +++ b/Runtime/World/CScriptPickupGenerator.cpp @@ -89,10 +89,10 @@ float CScriptPickupGenerator::GetPickupTemplates(CStateManager& mgr, doAlways = true; break; } - bool thirtyPercTest = mgr.GetActiveRandom()->Float() < 0.3f; + const bool thirtyPercTest = mgr.GetActiveRandom()->Float() < 0.3f; if ((doAlways || (doThirtyPerc && thirtyPercTest)) && possibility > 0.f) { totalPossibility += possibility * multiplier; - idsOut.push_back(std::make_pair(possibility, conn.x8_objId)); + idsOut.emplace_back(possibility, conn.x8_objId); } } } diff --git a/Runtime/World/CScriptPlatform.cpp b/Runtime/World/CScriptPlatform.cpp index bfdf77335..dbc12d10a 100644 --- a/Runtime/World/CScriptPlatform.cpp +++ b/Runtime/World/CScriptPlatform.cpp @@ -293,7 +293,7 @@ void CScriptPlatform::PreRender(CStateManager& mgr, const zeus::CFrustum& frustu x354_boundsTrigger = kInvalidUniqueId; } -void CScriptPlatform::Render(const CStateManager& mgr) const { +void CScriptPlatform::Render(CStateManager& mgr) { bool xray = mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay; if (xray && !x356_31_xrayFog) g_Renderer->SetWorldFog(ERglFogMode::None, 0.f, 1.f, zeus::skBlack); diff --git a/Runtime/World/CScriptPlatform.hpp b/Runtime/World/CScriptPlatform.hpp index d2dcdcfa8..5891b5875 100644 --- a/Runtime/World/CScriptPlatform.hpp +++ b/Runtime/World/CScriptPlatform.hpp @@ -91,7 +91,7 @@ public: void PreThink(float, CStateManager&) override; void Think(float, CStateManager&) override; void PreRender(CStateManager&, const zeus::CFrustum&) override; - void Render(const CStateManager&) const override; + void Render(CStateManager&) override; std::optional GetTouchBounds() const override; zeus::CTransform GetPrimitiveTransform() const override; const CCollisionPrimitive* GetCollisionPrimitive() const override; diff --git a/Runtime/World/CScriptPlayerActor.cpp b/Runtime/World/CScriptPlayerActor.cpp index 21712affb..206d1f3d4 100644 --- a/Runtime/World/CScriptPlayerActor.cpp +++ b/Runtime/World/CScriptPlayerActor.cpp @@ -368,13 +368,14 @@ void CScriptPlayerActor::PreRender(CStateManager& mgr, const zeus::CFrustum& fru CScriptActor::PreRender(mgr, frustum); } -void CScriptPlayerActor::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { - const_cast(this)->TouchModels_Internal(mgr); - if (GetActive()) +void CScriptPlayerActor::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { + TouchModels_Internal(mgr); + if (GetActive()) { CActor::AddToRenderer(frustum, mgr); + } } -void CScriptPlayerActor::Render(const CStateManager& mgr) const { +void CScriptPlayerActor::Render(CStateManager& mgr) { CBooModel::SetReflectionCube(m_reflectionCube); bool phazonSuit = x2e8_suitRes.GetCharacterNodeId() == 3; diff --git a/Runtime/World/CScriptPlayerActor.hpp b/Runtime/World/CScriptPlayerActor.hpp index bbd4d910f..041f1a05a 100644 --- a/Runtime/World/CScriptPlayerActor.hpp +++ b/Runtime/World/CScriptPlayerActor.hpp @@ -67,8 +67,8 @@ public: void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void SetActive(bool active) override; void PreRender(CStateManager&, const zeus::CFrustum&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager& mgr) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager& mgr) override; void TouchModels(const CStateManager& mgr) const; }; } // namespace urde diff --git a/Runtime/World/CScriptPointOfInterest.cpp b/Runtime/World/CScriptPointOfInterest.cpp index d40a5c5c8..fe60339ea 100644 --- a/Runtime/World/CScriptPointOfInterest.cpp +++ b/Runtime/World/CScriptPointOfInterest.cpp @@ -26,9 +26,9 @@ void CScriptPointOfInterest::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId CActor::AcceptScriptMsg(msg, uid, mgr); } -void CScriptPointOfInterest::AddToRenderer(const zeus::CFrustum&, const CStateManager&) const {} +void CScriptPointOfInterest::AddToRenderer(const zeus::CFrustum&, CStateManager&) {} -void CScriptPointOfInterest::Render(const CStateManager&) const {} +void CScriptPointOfInterest::Render(CStateManager&) {} void CScriptPointOfInterest::CalculateRenderBounds() { if (xe8_pointSize == 0.f) diff --git a/Runtime/World/CScriptPointOfInterest.hpp b/Runtime/World/CScriptPointOfInterest.hpp index 89ee604e8..e7bb74eb5 100644 --- a/Runtime/World/CScriptPointOfInterest.hpp +++ b/Runtime/World/CScriptPointOfInterest.hpp @@ -17,8 +17,8 @@ public: void Accept(IVisitor& visitor) override; void Think(float, CStateManager&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager&) override; void CalculateRenderBounds() override; std::optional GetTouchBounds() const override; }; diff --git a/Runtime/World/CScriptShadowProjector.hpp b/Runtime/World/CScriptShadowProjector.hpp index 188369b7e..54a521def 100644 --- a/Runtime/World/CScriptShadowProjector.hpp +++ b/Runtime/World/CScriptShadowProjector.hpp @@ -37,7 +37,7 @@ public: void Think(float, CStateManager&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void PreRender(CStateManager&, const zeus::CFrustum&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override {} + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override {} void CreateProjectedShadow(); }; } // namespace urde diff --git a/Runtime/World/CScriptSound.hpp b/Runtime/World/CScriptSound.hpp index 030a3c1d4..63e33e989 100644 --- a/Runtime/World/CScriptSound.hpp +++ b/Runtime/World/CScriptSound.hpp @@ -53,7 +53,7 @@ public: bool worldSfx, bool allowDuplicates, s32 pitch); void Accept(IVisitor& visitor) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override {} + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override {} void PreThink(float, CStateManager&) override; void Think(float, CStateManager&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; diff --git a/Runtime/World/CScriptSpecialFunction.cpp b/Runtime/World/CScriptSpecialFunction.cpp index e15b55b52..29cf53849 100644 --- a/Runtime/World/CScriptSpecialFunction.cpp +++ b/Runtime/World/CScriptSpecialFunction.cpp @@ -191,7 +191,7 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId } case ESpecialFunction::MissileStation: { if (msg == EScriptObjectMessage::Action) { - CPlayerState& pState = *mgr.GetPlayerState().get(); + CPlayerState& pState = *mgr.GetPlayerState(); pState.ResetAndIncrPickUp(CPlayerState::EItemType::Missiles, pState.GetItemCapacity(CPlayerState::EItemType::Missiles)); } @@ -199,7 +199,7 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId } case ESpecialFunction::PowerBombStation: { if (msg == EScriptObjectMessage::Action) { - CPlayerState& pState = *mgr.GetPlayerState().get(); + CPlayerState& pState = *mgr.GetPlayerState(); pState.ResetAndIncrPickUp(CPlayerState::EItemType::PowerBombs, pState.GetItemCapacity(CPlayerState::EItemType::PowerBombs)); } @@ -254,7 +254,7 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId auto search = mgr.GetIdListForScript(conn.x8_objId); for (auto it = search.first; it != search.second; ++it) { if (TCastToPtr act = mgr.ObjectById(it->second)) { - x198_ringControllers.push_back(SRingController(it->second, 0.f, false)); + x198_ringControllers.emplace_back(it->second, 0.f, false); act->RemoveMaterial(EMaterialTypes::Occluder, mgr); } } @@ -396,12 +396,13 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId } case ESpecialFunction::RedundantHintSystem: { CHintOptions& hintOptions = g_GameState->HintOptions(); - if (msg == EScriptObjectMessage::Action) - hintOptions.ActivateContinueDelayHintTimer(xec_locatorName.c_str()); - else if (msg == EScriptObjectMessage::Increment) - hintOptions.ActivateImmediateHintTimer(xec_locatorName.c_str()); - else if (msg == EScriptObjectMessage::Decrement) - hintOptions.DelayHint(xec_locatorName.c_str()); + if (msg == EScriptObjectMessage::Action) { + hintOptions.ActivateContinueDelayHintTimer(xec_locatorName); + } else if (msg == EScriptObjectMessage::Increment) { + hintOptions.ActivateImmediateHintTimer(xec_locatorName); + } else if (msg == EScriptObjectMessage::Decrement) { + hintOptions.DelayHint(xec_locatorName); + } break; } case ESpecialFunction::Billboard: { @@ -480,15 +481,17 @@ void CScriptSpecialFunction::PreRender(CStateManager&, const zeus::CFrustum& fru x1e4_28_frustumEntered = true; } -void CScriptSpecialFunction::AddToRenderer(const zeus::CFrustum&, const CStateManager& mgr) const { - if (!GetActive()) +void CScriptSpecialFunction::AddToRenderer(const zeus::CFrustum&, CStateManager& mgr) { + if (!GetActive()) { return; + } - if (xe8_function == ESpecialFunction::FogVolume && x1e4_30_) + if (xe8_function == ESpecialFunction::FogVolume && x1e4_30_) { EnsureRendered(mgr); + } } -void CScriptSpecialFunction::Render(const CStateManager& mgr) const { +void CScriptSpecialFunction::Render(CStateManager& mgr) { if (xe8_function == ESpecialFunction::FogVolume) { float z = mgr.IntegrateVisorFog(xfc_float1 * std::sin(CGraphics::GetSecondsMod900())); if (z > 0.f) { diff --git a/Runtime/World/CScriptSpecialFunction.hpp b/Runtime/World/CScriptSpecialFunction.hpp index 8e190f73e..0d5dc7935 100644 --- a/Runtime/World/CScriptSpecialFunction.hpp +++ b/Runtime/World/CScriptSpecialFunction.hpp @@ -125,8 +125,8 @@ public: void Think(float, CStateManager&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void PreRender(CStateManager&, const zeus::CFrustum&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager&) override; std::optional GetTouchBounds() const override { return x1c8_touchBounds; } void SkipCinematic(CStateManager&); diff --git a/Runtime/World/CScriptSpiderBallWaypoint.hpp b/Runtime/World/CScriptSpiderBallWaypoint.hpp index 7fb1e7ba2..32d209bcf 100644 --- a/Runtime/World/CScriptSpiderBallWaypoint.hpp +++ b/Runtime/World/CScriptSpiderBallWaypoint.hpp @@ -19,8 +19,8 @@ public: CScriptSpiderBallWaypoint(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, bool, u32); void Accept(IVisitor&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; - void Render(const CStateManager& mgr) const override { CActor::Render(mgr); } - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override {} + void Render(CStateManager& mgr) override { CActor::Render(mgr); } + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override {} std::optional GetTouchBounds() const override { return xfc_aabox; } void AccumulateBounds(const zeus::CVector3f& v); void BuildWaypointListAndBounds(CStateManager& mgr); diff --git a/Runtime/World/CScriptSpindleCamera.cpp b/Runtime/World/CScriptSpindleCamera.cpp index db2aa728d..a8dc0b06f 100644 --- a/Runtime/World/CScriptSpindleCamera.cpp +++ b/Runtime/World/CScriptSpindleCamera.cpp @@ -337,7 +337,7 @@ void CScriptSpindleCamera::Think(float dt, CStateManager& mgr) { } } -void CScriptSpindleCamera::Render(const CStateManager&) const { +void CScriptSpindleCamera::Render(CStateManager&) { // Empty } diff --git a/Runtime/World/CScriptSpindleCamera.hpp b/Runtime/World/CScriptSpindleCamera.hpp index 8a494b7a0..5f6fe7983 100644 --- a/Runtime/World/CScriptSpindleCamera.hpp +++ b/Runtime/World/CScriptSpindleCamera.hpp @@ -29,7 +29,7 @@ struct SSpindleProperty { float x10_lowIn; float x14_highIn; - SSpindleProperty(CInputStream& in); + explicit SSpindleProperty(CInputStream& in); void FixupAngles() { x8_lowOut = zeus::degToRad(x8_lowOut); xc_highOut = zeus::degToRad(xc_highOut); @@ -105,7 +105,7 @@ public: void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float, CStateManager&) override; - void Render(const CStateManager&) const override; + void Render(CStateManager&) override; void Reset(const zeus::CTransform& xf, CStateManager& mgr) override; void ProcessInput(const CFinalInput& input, CStateManager& mgr) override; }; diff --git a/Runtime/World/CScriptTargetingPoint.hpp b/Runtime/World/CScriptTargetingPoint.hpp index 92b61fe12..672f7366e 100644 --- a/Runtime/World/CScriptTargetingPoint.hpp +++ b/Runtime/World/CScriptTargetingPoint.hpp @@ -23,7 +23,7 @@ public: void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float, CStateManager&) override; - void Render(const CStateManager&) const override {} + void Render(CStateManager&) override {} bool GetLocked() const; }; diff --git a/Runtime/World/CScriptTrigger.cpp b/Runtime/World/CScriptTrigger.cpp index bd84015e6..666c990ec 100644 --- a/Runtime/World/CScriptTrigger.cpp +++ b/Runtime/World/CScriptTrigger.cpp @@ -61,11 +61,13 @@ void CScriptTrigger::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CS CScriptTrigger::CObjectTracker* CScriptTrigger::FindObject(TUniqueId id) { auto& inhabitants = GetInhabitants(); - const auto& iter = std::find(inhabitants.begin(), inhabitants.end(), id); + const auto iter = std::find(inhabitants.begin(), inhabitants.end(), CObjectTracker{id}); - if (iter != inhabitants.end()) - return &(*iter); - return nullptr; + if (iter == inhabitants.end()) { + return nullptr; + } + + return &*iter; } void CScriptTrigger::UpdateInhabitants(float dt, CStateManager& mgr) { @@ -242,7 +244,7 @@ void CScriptTrigger::Touch(CActor& act, CStateManager& mgr) { } if (True(testFlags & x12c_flags)) { - xe8_inhabitants.push_back(act.GetUniqueId()); + xe8_inhabitants.emplace_back(act.GetUniqueId()); InhabitantAdded(act, mgr); if (pl) { diff --git a/Runtime/World/CScriptTrigger.hpp b/Runtime/World/CScriptTrigger.hpp index 3fe57b9ac..038ab41f0 100644 --- a/Runtime/World/CScriptTrigger.hpp +++ b/Runtime/World/CScriptTrigger.hpp @@ -41,7 +41,7 @@ public: TUniqueId x0_id; public: - CObjectTracker(TUniqueId id) : x0_id(id) {} + explicit CObjectTracker(TUniqueId id) : x0_id(id) {} TUniqueId GetObjectId() const { return x0_id; } bool operator==(const CObjectTracker& other) const { return x0_id == other.x0_id; } diff --git a/Runtime/World/CScriptVisorFlare.cpp b/Runtime/World/CScriptVisorFlare.cpp index a71b6df82..a1e87afb9 100644 --- a/Runtime/World/CScriptVisorFlare.cpp +++ b/Runtime/World/CScriptVisorFlare.cpp @@ -11,11 +11,10 @@ namespace urde { CScriptVisorFlare::CScriptVisorFlare(TUniqueId uid, std::string_view name, const CEntityInfo& info, bool active, const zeus::CVector3f& pos, CVisorFlare::EBlendMode blendMode, bool b1, float f1, - float f2, float f3, u32 w1, u32 w2, - const std::vector& flares) + float f2, float f3, u32 w1, u32 w2, std::vector flares) : CActor(uid, active, name, info, zeus::CTransform::Translate(pos), CModelData::CModelDataNull(), CMaterialList(EMaterialTypes::NoStepLogic), CActorParameters::None(), kInvalidUniqueId) -, xe8_flare(blendMode, b1, f1, f2, f3, w1, w2, flares) { +, xe8_flare(blendMode, b1, f1, f2, f3, w1, w2, std::move(flares)) { xe6_27_thermalVisorFlags = 2; } @@ -34,11 +33,12 @@ void CScriptVisorFlare::PreRender(CStateManager& stateMgr, const zeus::CFrustum& x11c_notInRenderLast = !stateMgr.RenderLast(x8_uid); } -void CScriptVisorFlare::AddToRenderer(const zeus::CFrustum&, const CStateManager& stateMgr) const { - if (x11c_notInRenderLast) +void CScriptVisorFlare::AddToRenderer(const zeus::CFrustum&, CStateManager& stateMgr) { + if (x11c_notInRenderLast) { EnsureRendered(stateMgr, stateMgr.GetPlayer().GetTranslation(), GetSortingBounds(stateMgr)); + } } -void CScriptVisorFlare::Render(const CStateManager& stateMgr) const { xe8_flare.Render(GetTranslation(), stateMgr); } +void CScriptVisorFlare::Render(CStateManager& stateMgr) { xe8_flare.Render(GetTranslation(), stateMgr); } } // namespace urde diff --git a/Runtime/World/CScriptVisorFlare.hpp b/Runtime/World/CScriptVisorFlare.hpp index 718ccb7d4..0cda8755c 100644 --- a/Runtime/World/CScriptVisorFlare.hpp +++ b/Runtime/World/CScriptVisorFlare.hpp @@ -12,16 +12,16 @@ class CScriptVisorFlare : public CActor { bool x11c_notInRenderLast = true; public: - CScriptVisorFlare(TUniqueId, std::string_view name, const CEntityInfo& info, bool, const zeus::CVector3f&, - CVisorFlare::EBlendMode blendMode, bool, float, float, float, u32, u32, - const std::vector& flares); + CScriptVisorFlare(TUniqueId uid, std::string_view name, const CEntityInfo& info, bool active, + const zeus::CVector3f& pos, CVisorFlare::EBlendMode blendMode, bool, float, float, float, u32, u32, + std::vector flares); void Accept(IVisitor& visitor) override; void Think(float, CStateManager& stateMgr) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) override; void PreRender(CStateManager&, const zeus::CFrustum&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager&) override; }; } // namespace urde diff --git a/Runtime/World/CScriptVisorGoo.cpp b/Runtime/World/CScriptVisorGoo.cpp index 298ba9cd2..ee559fbb6 100644 --- a/Runtime/World/CScriptVisorGoo.cpp +++ b/Runtime/World/CScriptVisorGoo.cpp @@ -101,11 +101,11 @@ void CScriptVisorGoo::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CActor::AcceptScriptMsg(msg, objId, mgr); } -void CScriptVisorGoo::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { +void CScriptVisorGoo::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { // Empty } -void CScriptVisorGoo::Render(const CStateManager& mgr) const { +void CScriptVisorGoo::Render(CStateManager& mgr) { // Empty } diff --git a/Runtime/World/CScriptVisorGoo.hpp b/Runtime/World/CScriptVisorGoo.hpp index df683ca51..e53bcf58f 100644 --- a/Runtime/World/CScriptVisorGoo.hpp +++ b/Runtime/World/CScriptVisorGoo.hpp @@ -30,8 +30,8 @@ public: void Accept(IVisitor& visitor) override; void Think(float, CStateManager& stateMgr) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager&) override; std::optional GetTouchBounds() const override; void Touch(CActor&, CStateManager&) override; }; diff --git a/Runtime/World/CScriptWater.cpp b/Runtime/World/CScriptWater.cpp index a76e87b9c..92e1ba2d0 100644 --- a/Runtime/World/CScriptWater.cpp +++ b/Runtime/World/CScriptWater.cpp @@ -1,5 +1,7 @@ #include "Runtime/World/CScriptWater.hpp" +#include + #include "Runtime/CSimplePool.hpp" #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" @@ -11,8 +13,9 @@ #include "TCastTo.hpp" // Generated file, do not modify include path namespace urde { - -const float CScriptWater::kSplashScales[6] = {1.0f, 3.0f, 0.709f, 1.19f, 0.709f, 1.f}; +constexpr std::array kSplashScales{ + 1.0f, 3.0f, 0.709f, 1.19f, 0.709f, 1.f, +}; CScriptWater::CScriptWater( CStateManager& mgr, TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CVector3f& pos, @@ -410,15 +413,17 @@ void CScriptWater::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) } } -void CScriptWater::AddToRenderer(const zeus::CFrustum& /*frustum*/, const CStateManager& mgr) const { - if (!xe4_30_outOfFrustum) { - zeus::CPlane plane(zeus::skUp, x34_transform.origin.z() + x130_bounds.max.z()); - zeus::CAABox renderBounds = GetSortingBounds(mgr); - mgr.AddDrawableActorPlane(*this, plane, renderBounds); +void CScriptWater::AddToRenderer(const zeus::CFrustum& /*frustum*/, CStateManager& mgr) { + if (xe4_30_outOfFrustum) { + return; } + + const zeus::CPlane plane(zeus::skUp, x34_transform.origin.z() + x130_bounds.max.z()); + const zeus::CAABox renderBounds = GetSortingBounds(mgr); + mgr.AddDrawableActorPlane(*this, plane, renderBounds); } -void CScriptWater::Render(const CStateManager& mgr) const { +void CScriptWater::Render(CStateManager& mgr) { if (x30_24_active && !xe4_30_outOfFrustum) { float zOffset = 0.5f * (x9c_renderBounds.max.z() + x9c_renderBounds.min.z()) - x34_transform.origin.z(); zeus::CAABox aabb = x9c_renderBounds.getTransformedAABox(zeus::CTransform::Translate( diff --git a/Runtime/World/CScriptWater.hpp b/Runtime/World/CScriptWater.hpp index 938c2be12..3751aef0a 100644 --- a/Runtime/World/CScriptWater.hpp +++ b/Runtime/World/CScriptWater.hpp @@ -20,7 +20,6 @@ class CDamageInfo; class CFluidUVMotion; class CScriptWater : public CScriptTrigger { - static const float kSplashScales[6]; zeus::CFrustum x150_frustum; std::unique_ptr x1b4_fluidPlane; zeus::CVector3f x1b8_positionMorphed; @@ -105,8 +104,8 @@ public: void Think(float, CStateManager&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void PreRender(CStateManager&, const zeus::CFrustum&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager&) override; void Touch(CActor&, CStateManager&) override; void CalculateRenderBounds() override; zeus::CAABox GetSortingBounds(const CStateManager&) const override; diff --git a/Runtime/World/CScriptWaypoint.cpp b/Runtime/World/CScriptWaypoint.cpp index 681a76b81..52c41f327 100644 --- a/Runtime/World/CScriptWaypoint.cpp +++ b/Runtime/World/CScriptWaypoint.cpp @@ -33,7 +33,7 @@ void CScriptWaypoint::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender SendScriptMsgs(EScriptObjectState::Arrived, mgr, EScriptObjectMessage::None); } -void CScriptWaypoint::AddToRenderer(const zeus::CFrustum&, const CStateManager&) const { +void CScriptWaypoint::AddToRenderer(const zeus::CFrustum&, CStateManager&) { // Empty } diff --git a/Runtime/World/CScriptWaypoint.hpp b/Runtime/World/CScriptWaypoint.hpp index 101fb526e..0963963a5 100644 --- a/Runtime/World/CScriptWaypoint.hpp +++ b/Runtime/World/CScriptWaypoint.hpp @@ -25,7 +25,7 @@ public: void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; TUniqueId FollowWaypoint(CStateManager& mgr) const; TUniqueId NextWaypoint(CStateManager& mgr) const; float GetSpeed() const { return xe8_speed; } diff --git a/Runtime/World/CSnakeWeedSwarm.cpp b/Runtime/World/CSnakeWeedSwarm.cpp index 69630023f..76609926a 100644 --- a/Runtime/World/CSnakeWeedSwarm.cpp +++ b/Runtime/World/CSnakeWeedSwarm.cpp @@ -139,14 +139,17 @@ void CSnakeWeedSwarm::PreRender(CStateManager& mgr, const zeus::CFrustum& frustu } } -void CSnakeWeedSwarm::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { - if (xe4_30_outOfFrustum) +void CSnakeWeedSwarm::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { + if (xe4_30_outOfFrustum) { return; + } - if (x1ec_particleGen1) + if (x1ec_particleGen1) { g_Renderer->AddParticleGen(*x1ec_particleGen1); - if (x1f4_particleGen2) + } + if (x1f4_particleGen2) { g_Renderer->AddParticleGen(*x1f4_particleGen2); + } if (x90_actorLights) { for (const auto& modelData : x1b0_modelData) { @@ -158,8 +161,9 @@ void CSnakeWeedSwarm::AddToRenderer(const zeus::CFrustum& frustum, const CStateM } u32 posesToBuild = -1; - for (u32 i = 0; i < x134_boids.size(); ++i) + for (u32 i = 0; i < x134_boids.size(); ++i) { RenderBoid(i, x134_boids[i], posesToBuild); + } CGraphics::DisableAllLights(); } @@ -276,14 +280,14 @@ void CSnakeWeedSwarm::Think(float dt, CStateManager& mgr) { x140_26_playerTouching = false; } -zeus::CAABox CSnakeWeedSwarm::GetBoidBox() { - const auto& scale = xe8_scale * 0.75f; +zeus::CAABox CSnakeWeedSwarm::GetBoidBox() const { + const auto scale = xe8_scale * 0.75f; return {GetTransform().origin - scale, GetTransform().origin + scale}; } void CSnakeWeedSwarm::FindGround(const CStateManager& mgr) { - const auto& box = GetBoidBox(); - const auto& result = + const auto box = GetBoidBox(); + const auto result = mgr.RayStaticIntersection(box.center(), zeus::skDown, box.max.z() - box.min.z(), skMaterialFilter); if (result.IsValid()) { int ct = GetNumBoidsX() * GetNumBoidsY(); @@ -295,13 +299,13 @@ void CSnakeWeedSwarm::FindGround(const CStateManager& mgr) { } } -int CSnakeWeedSwarm::GetNumBoidsY() { - const auto& box = GetBoidBox(); +int CSnakeWeedSwarm::GetNumBoidsY() const { + const auto box = GetBoidBox(); return static_cast((box.max.y() - box.min.y()) / xf4_boidSpacing) + 1; } -int CSnakeWeedSwarm::GetNumBoidsX() { - const auto& box = GetBoidBox(); +int CSnakeWeedSwarm::GetNumBoidsX() const { + const auto box = GetBoidBox(); return static_cast((box.max.x() - box.min.x()) / xf4_boidSpacing) + 1; } @@ -330,31 +334,31 @@ void CSnakeWeedSwarm::CreateBoids(CStateManager& mgr, int num) { } } -zeus::CVector2i CSnakeWeedSwarm::GetBoidIndex(const zeus::CVector3f& pos) { - const auto& box = GetBoidBox(); +zeus::CVector2i CSnakeWeedSwarm::GetBoidIndex(const zeus::CVector3f& pos) const { + const auto box = GetBoidBox(); return {static_cast((pos.x() - box.min.x()) / xf4_boidSpacing), static_cast((pos.y() - box.min.y()) / xf4_boidSpacing)}; } bool CSnakeWeedSwarm::CreateBoid(const zeus::CVector3f& vec, CStateManager& mgr) { - const auto& pos = vec + zeus::CVector3f(GetBoidOffsetX(vec), GetBoidOffsetY(vec), xf8_height); - const auto& result = mgr.RayStaticIntersection(pos, zeus::skDown, 2.f * xf8_height, skMaterialFilter); + const auto pos = vec + zeus::CVector3f(GetBoidOffsetX(vec), GetBoidOffsetY(vec), xf8_height); + const auto result = mgr.RayStaticIntersection(pos, zeus::skDown, 2.f * xf8_height, skMaterialFilter); if (result.IsValid() && result.GetPlane().normal().dot(zeus::skUp) > x11c_) { - const auto& boidPosition = result.GetPoint() - zeus::CVector3f(0.f, 0.f, x128_distanceBelowGround); - x134_boids.push_back({boidPosition, x110_maxZOffset, x114_speed + x118_speedVariation, - (x124_scaleMax - x120_scaleMin) * mgr.GetActiveRandom()->Float() + x120_scaleMin}); + const auto boidPosition = result.GetPoint() - zeus::CVector3f(0.f, 0.f, x128_distanceBelowGround); + x134_boids.emplace_back(boidPosition, x110_maxZOffset, x114_speed + x118_speedVariation, + (x124_scaleMax - x120_scaleMin) * mgr.GetActiveRandom()->Float() + x120_scaleMin); return true; } return false; } -float CSnakeWeedSwarm::GetBoidOffsetY(const zeus::CVector3f& pos) { - float f = 2.4729404f * pos.y() + 0.3478602f * pos.x() * pos.x(); +float CSnakeWeedSwarm::GetBoidOffsetY(const zeus::CVector3f& pos) const { + const float f = 2.4729404f * pos.y() + 0.3478602f * pos.x() * pos.x(); return xfc_ * (2.f * std::abs(f - std::trunc(f)) - 1.f); } -float CSnakeWeedSwarm::GetBoidOffsetX(const zeus::CVector3f& pos) { - float f = 8.21395f * pos.x() + 0.112869f * pos.y() * pos.y(); +float CSnakeWeedSwarm::GetBoidOffsetX(const zeus::CVector3f& pos) const { + const float f = 8.21395f * pos.x() + 0.112869f * pos.y() * pos.y(); return xfc_ * (2.f * std::abs(f - std::trunc(f)) - 1.f); } diff --git a/Runtime/World/CSnakeWeedSwarm.hpp b/Runtime/World/CSnakeWeedSwarm.hpp index 495187f95..03ae8e944 100644 --- a/Runtime/World/CSnakeWeedSwarm.hpp +++ b/Runtime/World/CSnakeWeedSwarm.hpp @@ -80,7 +80,7 @@ private: u16 x1d0_sfx1; u16 x1d2_sfx2; u16 x1d4_sfx3; - CSfxHandle x1d8_sfxHandle = 0; + CSfxHandle x1d8_sfxHandle; TLockedToken x1dc_particleGenDesc; // TLockedToken x1e4_; both assign to x1dc_ std::unique_ptr x1ec_particleGen1; @@ -103,7 +103,7 @@ public: std::optional GetTouchBounds() const override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void PreRender(CStateManager&, const zeus::CFrustum&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; void Touch(CActor&, CStateManager&) override; void Think(float, CStateManager&) override; @@ -111,14 +111,14 @@ private: void AllocateSkinnedModels(CStateManager& mgr, CModelData::EWhichModel which); void HandleRadiusDamage(float radius, CStateManager& mgr, const zeus::CVector3f& pos); void FindGround(const CStateManager& mgr); - zeus::CAABox GetBoidBox(); - int GetNumBoidsY(); - int GetNumBoidsX(); + zeus::CAABox GetBoidBox() const; + int GetNumBoidsY() const; + int GetNumBoidsX() const; void CreateBoids(CStateManager& mgr, int num); - zeus::CVector2i GetBoidIndex(const zeus::CVector3f& pos); + zeus::CVector2i GetBoidIndex(const zeus::CVector3f& pos) const; bool CreateBoid(const zeus::CVector3f& vec, CStateManager& mgr); - float GetBoidOffsetY(const zeus::CVector3f& pos); - float GetBoidOffsetX(const zeus::CVector3f& pos); + float GetBoidOffsetY(const zeus::CVector3f& pos) const; + float GetBoidOffsetX(const zeus::CVector3f& pos) const; void AddBoidPosition(const zeus::CVector3f& pos); void CalculateTouchBounds(); void EmitParticles1(const zeus::CVector3f& pos); diff --git a/Runtime/World/CStateMachine.hpp b/Runtime/World/CStateMachine.hpp index 1c2ee71a5..0ddecca84 100644 --- a/Runtime/World/CStateMachine.hpp +++ b/Runtime/World/CStateMachine.hpp @@ -75,7 +75,7 @@ class CStateMachine { std::vector x10_triggers; public: - CStateMachine(CInputStream& in); + explicit CStateMachine(CInputStream& in); s32 GetStateIndex(std::string_view state) const; const std::vector& GetStateVector() const { return x0_states; } diff --git a/Runtime/World/CTeamAiMgr.hpp b/Runtime/World/CTeamAiMgr.hpp index 79e6aa5e7..3bd69e85b 100644 --- a/Runtime/World/CTeamAiMgr.hpp +++ b/Runtime/World/CTeamAiMgr.hpp @@ -64,10 +64,10 @@ private: std::vector x58_roles; std::vector x68_meleeAttackers; std::vector x78_rangedAttackers; - float x88_timeDirty = 0.f; + float x88_timeDirty = 0.0f; TUniqueId x8c_teamCaptainId = kInvalidUniqueId; - float x90_timeSinceMelee; - float x94_timeSinceRanged; + float x90_timeSinceMelee = 0.0f; + float x94_timeSinceRanged = 0.0f; void UpdateTeamCaptain(); bool ShouldUpdateRoles(float dt); diff --git a/Runtime/World/CVisorFlare.cpp b/Runtime/World/CVisorFlare.cpp index 06c7bd13e..1be3c4a63 100644 --- a/Runtime/World/CVisorFlare.cpp +++ b/Runtime/World/CVisorFlare.cpp @@ -27,9 +27,9 @@ std::optional CVisorFlare::LoadFlareDef(CInputStream& in } CVisorFlare::CVisorFlare(EBlendMode blendMode, bool b1, float f1, float f2, float f3, u32 w1, u32 w2, - const std::vector& flares) + std::vector flares) : x0_blendMode(blendMode) -, x4_flareDefs(flares) +, x4_flareDefs(std::move(flares)) , x14_b1(b1) , x18_f1(std::max(f1, FLT_EPSILON)) , x1c_f2(f2) diff --git a/Runtime/World/CVisorFlare.hpp b/Runtime/World/CVisorFlare.hpp index ff70aff6e..b1c084de2 100644 --- a/Runtime/World/CVisorFlare.hpp +++ b/Runtime/World/CVisorFlare.hpp @@ -49,7 +49,7 @@ private: u32 x30_w2; public: - CVisorFlare(EBlendMode blendMode, bool, float, float, float, u32, u32, const std::vector& flares); + CVisorFlare(EBlendMode blendMode, bool, float, float, float, u32, u32, std::vector flares); void Update(float dt, const zeus::CVector3f& pos, const CActor* act, CStateManager& mgr); void Render(const zeus::CVector3f& pos, const CStateManager& mgr) const; static std::optional LoadFlareDef(CInputStream& in); diff --git a/Runtime/World/CWallCrawlerSwarm.cpp b/Runtime/World/CWallCrawlerSwarm.cpp index 5063552a0..57f9658bb 100644 --- a/Runtime/World/CWallCrawlerSwarm.cpp +++ b/Runtime/World/CWallCrawlerSwarm.cpp @@ -1,5 +1,7 @@ #include "Runtime/World/CWallCrawlerSwarm.hpp" +#include + #include "Runtime/CSimplePool.hpp" #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" @@ -91,23 +93,29 @@ CWallCrawlerSwarm::CWallCrawlerSwarm(TUniqueId uid, bool active, std::string_vie x4b0_modelDatas.emplace_back(std::make_unique(launchAnimRes)); x4b0_modelDatas.emplace_back(std::make_unique(animRes)); if (aParams.GetXRayAssets().first.IsValid()) { - for (int i = 0; i < 9; ++i) + for (size_t i = 0; i < 9; ++i) { x4b0_modelDatas[i]->SetXRayModel(aParams.GetXRayAssets()); + } x560_26_modelAssetDirty = true; } if (aParams.GetThermalAssets().first.IsValid()) { - for (int i = 0; i < 9; ++i) + for (size_t i = 0; i < 9; ++i) { x4b0_modelDatas[i]->SetInfraModel(aParams.GetThermalAssets()); + } x560_26_modelAssetDirty = true; } - if (part1.IsValid()) + if (part1.IsValid()) { x4f0_particleDescs.push_back(g_SimplePool->GetObj({FOURCC('PART'), part1})); - if (part2.IsValid()) + } + if (part2.IsValid()) { x4f0_particleDescs.push_back(g_SimplePool->GetObj({FOURCC('PART'), part2})); - if (part3.IsValid()) + } + if (part3.IsValid()) { x4f0_particleDescs.push_back(g_SimplePool->GetObj({FOURCC('PART'), part3})); - if (part4.IsValid()) + } + if (part4.IsValid()) { x4f0_particleDescs.push_back(g_SimplePool->GetObj({FOURCC('PART'), part4})); + } for (const auto& t : x4f0_particleDescs) { x524_particleGens.emplace_back(new CElementGen(t)); x524_particleGens.back()->SetParticleEmission(false); @@ -118,12 +126,12 @@ void CWallCrawlerSwarm::Accept(IVisitor& visitor) { visitor.Visit(this); } void CWallCrawlerSwarm::AllocateSkinnedModels(CStateManager& mgr, CModelData::EWhichModel which) { //x430_.clear(); - for (int i = 0; i < 9; ++i) { + for (size_t i = 0; i < 9; ++i) { //x430_.push_back(x4b0_[i]->PickAnimatedModel(which).Clone()); x4b0_modelDatas[i]->EnableLooping(true); - x4b0_modelDatas[i]->AdvanceAnimation( - x4b0_modelDatas[i]->GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) * (i * 0.0625f), - mgr, x4_areaId, true); + x4b0_modelDatas[i]->AdvanceAnimation(x4b0_modelDatas[i]->GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) * + (float(i) * 0.0625f), + mgr, x4_areaId, true); } //x430_.push_back(x4b0_.back()->PickAnimatedModel(which).Clone()); x4dc_whichModel = which; @@ -131,17 +139,22 @@ void CWallCrawlerSwarm::AllocateSkinnedModels(CStateManager& mgr, CModelData::EW void CWallCrawlerSwarm::AddDoorRepulsors(CStateManager& mgr) { size_t doorCount = 0; - for (CEntity* ent : mgr.GetPhysicsActorObjectList()) { - if (TCastToPtr door = ent) - if (door->GetAreaIdAlways() == x4_areaId) - ++doorCount; - } - x4e0_doorRepulsors.reserve(doorCount); - for (CEntity* ent : mgr.GetPhysicsActorObjectList()) { - if (TCastToPtr door = ent) { + for (const CEntity* ent : mgr.GetPhysicsActorObjectList()) { + if (const TCastToConstPtr door = ent) { if (door->GetAreaIdAlways() == x4_areaId) { - if (auto tb = door->GetTouchBounds()) + ++doorCount; + } + } + } + + x4e0_doorRepulsors.reserve(doorCount); + + for (const CEntity* ent : mgr.GetPhysicsActorObjectList()) { + if (const TCastToConstPtr door = ent) { + if (door->GetAreaIdAlways() == x4_areaId) { + if (const auto tb = door->GetTouchBounds()) { x4e0_doorRepulsors.emplace_back(tb->center(), (tb->min - tb->max).magnitude() * 0.75f); + } } } } @@ -152,8 +165,9 @@ void CWallCrawlerSwarm::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId send switch (msg) { case EScriptObjectMessage::Registered: x108_boids.reserve(size_t(x548_numBoids)); - for (int i = 0; i < x548_numBoids; ++i) + for (int i = 0; i < x548_numBoids; ++i) { x108_boids.emplace_back(zeus::CTransform(), i); + } AllocateSkinnedModels(mgr, CModelData::EWhichModel::Normal); AddDoorRepulsors(mgr); CreateShadow(false); @@ -164,41 +178,44 @@ void CWallCrawlerSwarm::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId send } void CWallCrawlerSwarm::UpdateParticles(float dt) { - for (auto& p : x524_particleGens) + for (auto& p : x524_particleGens) { p->Update(dt); + } } int CWallCrawlerSwarm::SelectLockOnIdx(CStateManager& mgr) const { - zeus::CTransform fpCamXf = mgr.GetCameraManager()->GetFirstPersonCamera()->GetTransform(); + const zeus::CTransform fpCamXf = mgr.GetCameraManager()->GetFirstPersonCamera()->GetTransform(); if (x42c_lockOnIdx != -1) { const CBoid& b = x108_boids[x42c_lockOnIdx]; if (b.GetActive()) { zeus::CVector3f dir = b.GetTranslation() - fpCamXf.origin; - float mag = dir.magnitude(); + const float mag = dir.magnitude(); dir = dir / mag; if (fpCamXf.basis[1].dot(dir) > 0.92388f) { - if (mgr.RayStaticIntersection(fpCamXf.origin, dir, mag, - CMaterialFilter::MakeInclude(EMaterialTypes::Solid)).IsInvalid()) + if (mgr.RayStaticIntersection(fpCamXf.origin, dir, mag, CMaterialFilter::MakeInclude(EMaterialTypes::Solid)) + .IsInvalid()) { return x42c_lockOnIdx; + } } } return -1; } int ret = -1; - float omtd = mgr.GetPlayer().GetOrbitMaxTargetDistance(mgr); - float omtdSq = omtd * omtd; + const float omtd = mgr.GetPlayer().GetOrbitMaxTargetDistance(mgr); + const float omtdSq = omtd * omtd; float maxDot = 0.5f; - for (int i = 0; i < x108_boids.size(); ++i) { + for (size_t i = 0; i < x108_boids.size(); ++i) { const CBoid& b = x108_boids[i]; if (b.GetActive()) { zeus::CVector3f delta = b.GetTranslation() - fpCamXf.origin; - if (delta.magSquared() > omtdSq) + if (delta.magSquared() > omtdSq) { continue; + } if (delta.canBeNormalized()) { - float thisDot = fpCamXf.basis[1].dot(delta.normalized()); + const float thisDot = fpCamXf.basis[1].dot(delta.normalized()); if (thisDot > maxDot) { - ret = i; + ret = static_cast(i); maxDot = thisDot; } } @@ -208,24 +225,26 @@ int CWallCrawlerSwarm::SelectLockOnIdx(CStateManager& mgr) const { } zeus::CAABox CWallCrawlerSwarm::GetBoundingBox() const { - zeus::CVector3f he = x118_boundingBoxExtent * 0.75f; + const zeus::CVector3f he = x118_boundingBoxExtent * 0.75f; return zeus::CAABox(-he, he).getTransformedAABox(x34_transform); } TUniqueId CWallCrawlerSwarm::GetWaypointForState(EScriptObjectState state, CStateManager& mgr) const { for (const auto& c : GetConnectionList()) { - if (c.x0_state == state && c.x4_msg == EScriptObjectMessage::Follow) + if (c.x0_state == state && c.x4_msg == EScriptObjectMessage::Follow) { return mgr.GetIdForScript(c.x8_objId); + } } return kInvalidUniqueId; } bool CWallCrawlerSwarm::PointOnSurface(const CCollisionSurface& surf, const zeus::CVector3f& pos, const zeus::CPlane& plane) const { - zeus::CVector3f projPt = ProjectPointToPlane(pos, surf.GetVert(0), plane.normal()); + const zeus::CVector3f projPt = ProjectPointToPlane(pos, surf.GetVert(0), plane.normal()); for (int i = 0; i < 3; ++i) { - if (plane.normal().dot((projPt - surf.GetVert(i)).cross(surf.GetVert((i + 2) % 3) - surf.GetVert(i))) < 0.f) + if (plane.normal().dot((projPt - surf.GetVert(i)).cross(surf.GetVert((i + 2) % 3) - surf.GetVert(i))) < 0.f) { return false; + } } return true; } @@ -233,20 +252,21 @@ bool CWallCrawlerSwarm::PointOnSurface(const CCollisionSurface& surf, const zeus bool CWallCrawlerSwarm::FindBestSurface(const CAreaCollisionCache& ccache, const zeus::CVector3f& pos, float radius, CCollisionSurface& out) const { bool ret = false; - float radiusSq = radius * radius; + const float radiusSq = radius * radius; zeus::CSphere sphere(pos, radius); for (const auto& c : ccache) { for (const auto& n : c) { if (CCollidableSphere::Sphere_AABox_Bool(sphere, n.GetBoundingBox())) { - auto triList = n.GetTriangleArray(); + const auto triList = n.GetTriangleArray(); for (int i = 0; i < triList.GetSize(); ++i) { CCollisionSurface surf = n.GetOwner().GetMasterListTriangle(triList.GetAt(i)); - zeus::CPlane plane = surf.GetPlane(); - float distSq = std::fabs(plane.pointToPlaneDist(pos)); + const zeus::CPlane plane = surf.GetPlane(); + const float distSq = std::fabs(plane.pointToPlaneDist(pos)); if (distSq < radiusSq && PointOnSurface(surf, pos, plane)) { float dist = 0.f; - if (distSq != 0.f) + if (distSq != 0.f) { dist = std::sqrt(distSq); + } sphere.radius = dist; out = surf; ret = true; @@ -260,40 +280,45 @@ bool CWallCrawlerSwarm::FindBestSurface(const CAreaCollisionCache& ccache, const CCollisionSurface CWallCrawlerSwarm::FindBestCollisionInBox(CStateManager& mgr, const zeus::CVector3f& wpPos) const { CCollisionSurface ret(zeus::skRight, zeus::skForward, zeus::skUp, 0xffffffff); - zeus::CVector3f aabbExtents = GetBoundingBox().extents(); + const zeus::CVector3f aabbExtents = GetBoundingBox().extents(); float f25 = 0.1f; while (f25 < 1.f) { - zeus::CVector3f scaledExtents = aabbExtents * f25; + const zeus::CVector3f scaledExtents = aabbExtents * f25; CAreaCollisionCache ccache(zeus::CAABox(wpPos - scaledExtents, wpPos + scaledExtents)); CGameCollision::BuildAreaCollisionCache(mgr, ccache); - if (FindBestSurface(ccache, wpPos, 2.f * scaledExtents.magnitude(), ret)) + if (FindBestSurface(ccache, wpPos, 2.f * scaledExtents.magnitude(), ret)) { return ret; + } f25 += 0.1f; } return ret; } static zeus::CTransform LookAt(const zeus::CUnitVector3f& a, const zeus::CUnitVector3f& b, const zeus::CRelAngle& ang) { - float dot = a.dot(b); - if (zeus::close_enough(dot, 1.f)) + const float dot = a.dot(b); + if (zeus::close_enough(dot, 1.f)) { return zeus::CTransform(); - if (dot > -0.99981f) + } + if (dot > -0.99981f) { return zeus::CQuaternion::clampedRotateTo(a, b, ang).toTransform(); - if (a != zeus::skRight && b != zeus::skRight) + } + if (a != zeus::skRight && b != zeus::skRight) { return zeus::CQuaternion::fromAxisAngle(a.cross(zeus::skRight), ang).toTransform(); + } return zeus::CQuaternion::fromAxisAngle(a.cross(zeus::skUp), ang).toTransform(); } void CWallCrawlerSwarm::CreateBoid(CStateManager& mgr, int idx) { //zeus::CAABox aabb = GetBoundingBox(); - TUniqueId wpId = GetWaypointForState(EScriptObjectState::Patrol, mgr); + const TUniqueId wpId = GetWaypointForState(EScriptObjectState::Patrol, mgr); if (TCastToConstPtr wp = mgr.GetObjectById(wpId)) { - CCollisionSurface surf = FindBestCollisionInBox(mgr, wp->GetTranslation()); - x108_boids[idx].Transform() = zeus::CTransform::Translate( - ProjectPointToPlane(wp->GetTranslation(), surf.GetVert(0), surf.GetNormal()) + surf.GetNormal() * x374_boidRadius); + const CCollisionSurface surf = FindBestCollisionInBox(mgr, wp->GetTranslation()); + x108_boids[idx].Transform() = + zeus::CTransform::Translate(ProjectPointToPlane(wp->GetTranslation(), surf.GetVert(0), surf.GetNormal()) + + surf.GetNormal() * x374_boidRadius); if (zeus::close_enough(zeus::skUp.dot(surf.GetNormal()), -1.f)) { - x108_boids[idx].Transform().setRotation(zeus::CTransform( - zeus::skRight, zeus::skBack, zeus::skDown, zeus::skZero3f)); + x108_boids[idx].Transform().setRotation( + zeus::CTransform(zeus::skRight, zeus::skBack, zeus::skDown, zeus::skZero3f)); } else { x108_boids[idx].Transform().setRotation(LookAt(zeus::skUp, surf.GetNormal(), M_PIF)); } @@ -310,30 +335,33 @@ void CWallCrawlerSwarm::CreateBoid(CStateManager& mgr, int idx) { void CWallCrawlerSwarm::ExplodeBoid(CBoid& boid, CStateManager& mgr) { KillBoid(boid, mgr, 0.f, 1.f); mgr.ApplyDamageToWorld(GetUniqueId(), *this, boid.GetTranslation(), x3a0_scarabExplodeDamage, - CMaterialFilter::MakeInclude({EMaterialTypes::Player})); + CMaterialFilter::MakeInclude({EMaterialTypes::Player})); } void CWallCrawlerSwarm::SetExplodeTimers(const zeus::CVector3f& pos, float radius, float minTime, float maxTime) { - float radiusSq = radius * radius; - float range = maxTime - minTime; + const float radiusSq = radius * radius; + const float range = maxTime - minTime; + for (auto& b : x108_boids) { if (b.GetActive() && b.x48_timeToDie <= 0.f) { - float dist = (b.GetTranslation() - pos).magSquared(); + const float dist = (b.GetTranslation() - pos).magSquared(); if (dist < radiusSq) { - float fac = dist / radiusSq * range + minTime; - if (b.x4c_timeToExplode > fac || b.x4c_timeToExplode == 0.f) + const float fac = dist / radiusSq * range + minTime; + if (b.x4c_timeToExplode > fac || b.x4c_timeToExplode == 0.f) { b.x4c_timeToExplode = fac; + } } } } } CWallCrawlerSwarm::CBoid* CWallCrawlerSwarm::GetListAt(const zeus::CVector3f& pos) { - zeus::CAABox aabb = GetBoundingBox(); - zeus::CVector3f ints = (pos - aabb.min) / ((aabb.max - aabb.min) / 5.f); - int idx = int(ints.x()) + int(ints.y()) * 5 + int(ints.z()) * 25; - if (idx < 0 || idx >= 125) + const zeus::CAABox aabb = GetBoundingBox(); + const zeus::CVector3f ints = (pos - aabb.min) / ((aabb.max - aabb.min) / 5.f); + const int idx = int(ints.x()) + int(ints.y()) * 5 + int(ints.z()) * 25; + if (idx < 0 || idx >= 125) { return x360_outlierBoidList; + } return x168_partitionedBoidLists[idx]; } @@ -341,48 +369,54 @@ void CWallCrawlerSwarm::BuildBoidNearList(const CBoid& boid, float radius, rstl::reserved_vector& nearList) { CBoid* b = GetListAt(boid.GetTranslation()); while (b && nearList.size() < 50) { - float distSq = (b->GetTranslation() - boid.GetTranslation()).magSquared(); - if (distSq != 0.f && distSq < radius) + const float distSq = (b->GetTranslation() - boid.GetTranslation()).magSquared(); + if (distSq != 0.f && distSq < radius) { nearList.push_back(b); + } b = b->x44_next; } } void CWallCrawlerSwarm::ApplySeparation(const CBoid& boid, const rstl::reserved_vector& nearList, zeus::CVector3f& aheadVec) const { - if (nearList.empty()) + if (nearList.empty()) { return; + } + float minDist = FLT_MAX; zeus::CVector3f pos; - for (CBoid* b : nearList) { - float dist = (boid.GetTranslation() - b->GetTranslation()).magSquared(); + for (const CBoid* b : nearList) { + const float dist = (boid.GetTranslation() - b->GetTranslation()).magSquared(); if (dist != 0.f && dist < minDist) { minDist = dist; pos = b->GetTranslation(); } } + ApplySeparation(boid, pos, x13c_separationRadius, x148_separationMagnitude, aheadVec); } -void CWallCrawlerSwarm::ApplySeparation(const CBoid& boid, const zeus::CVector3f& separateFrom, - float separationRadius, float separationMagnitude, - zeus::CVector3f& aheadVec) const { - zeus::CVector3f delta = boid.GetTranslation() - separateFrom; - if (delta.canBeNormalized()) { - float deltaDistSq = delta.magSquared(); - float capDeltaDistSq = separationRadius * separationRadius; - if (deltaDistSq < capDeltaDistSq) - aheadVec += (1.f - deltaDistSq / capDeltaDistSq) * delta.normalized() * separationMagnitude; +void CWallCrawlerSwarm::ApplySeparation(const CBoid& boid, const zeus::CVector3f& separateFrom, float separationRadius, + float separationMagnitude, zeus::CVector3f& aheadVec) const { + const zeus::CVector3f delta = boid.GetTranslation() - separateFrom; + if (!delta.canBeNormalized()) { + return; + } + + const float deltaDistSq = delta.magSquared(); + const float capDeltaDistSq = separationRadius * separationRadius; + if (deltaDistSq < capDeltaDistSq) { + aheadVec += (1.f - deltaDistSq / capDeltaDistSq) * delta.normalized() * separationMagnitude; } } void CWallCrawlerSwarm::ScatterScarabBoid(CBoid& boid, CStateManager& mgr) const { - zeus::CVector3f oldDir = boid.Transform().basis[1]; + const zeus::CVector3f oldDir = boid.GetTransform().basis[1]; boid.Transform().setRotation(zeus::CTransform()); - boid.Transform() = LookAt(boid.Transform().basis[1], oldDir, M_PIF).multiplyIgnoreTranslation(boid.Transform()); + boid.Transform() = LookAt(boid.GetTransform().basis[1], oldDir, M_PIF).multiplyIgnoreTranslation(boid.GetTransform()); boid.x30_velocity = zeus::skZero3f; - float angle = mgr.GetActiveRandom()->Float() * (2.f * M_PIF); - float mag = mgr.GetActiveRandom()->Float() * x158_scarabScatterXYVelocity; + const float angle = mgr.GetActiveRandom()->Float() * (2.f * M_PIF); + const float mag = mgr.GetActiveRandom()->Float() * x158_scarabScatterXYVelocity; boid.x30_velocity.x() = mag * std::cos(angle); boid.x30_velocity.y() = mag * std::sin(angle); boid.x80_26_launched = true; @@ -391,8 +425,8 @@ void CWallCrawlerSwarm::ScatterScarabBoid(CBoid& boid, CStateManager& mgr) const } void CWallCrawlerSwarm::MoveToWayPoint(CBoid& boid, CStateManager& mgr, zeus::CVector3f& aheadVec) const { - if (TCastToPtr wp = mgr.ObjectById(boid.x3c_targetWaypoint)) { - CScriptWaypoint* useWp = wp.GetPtr(); + if (const TCastToConstPtr wp = mgr.ObjectById(boid.x3c_targetWaypoint)) { + const CScriptWaypoint* useWp = wp.GetPtr(); if ((useWp->GetTranslation() - boid.GetTranslation()).magSquared() < x164_waypointGoalRadius * x164_waypointGoalRadius) { boid.x3c_targetWaypoint = useWp->NextWaypoint(mgr); @@ -404,7 +438,7 @@ void CWallCrawlerSwarm::MoveToWayPoint(CBoid& boid, CStateManager& mgr, zeus::CV return; } } else { - useWp = TCastToPtr(mgr.ObjectById(boid.x3c_targetWaypoint)).GetPtr(); + useWp = TCastToConstPtr(mgr.ObjectById(boid.x3c_targetWaypoint)).GetPtr(); } } aheadVec += (useWp->GetTranslation() - boid.GetTranslation()).normalized() * x14c_moveToWaypointWeight; @@ -413,60 +447,71 @@ void CWallCrawlerSwarm::MoveToWayPoint(CBoid& boid, CStateManager& mgr, zeus::CV void CWallCrawlerSwarm::ApplyCohesion(const CBoid& boid, const rstl::reserved_vector& nearList, zeus::CVector3f& aheadVec) const { - if (nearList.empty()) + if (nearList.empty()) { return; + } + zeus::CVector3f avg; - for (CBoid* b : nearList) + for (const CBoid* b : nearList) { avg += b->GetTranslation(); + } + avg = avg / float(nearList.size()); ApplyCohesion(boid, avg, x13c_separationRadius, x140_cohesionMagnitude, aheadVec); } -void CWallCrawlerSwarm::ApplyCohesion(const CBoid& boid, const zeus::CVector3f& cohesionFrom, - float cohesionRadius, float cohesionMagnitude, - zeus::CVector3f& aheadVec) const { - zeus::CVector3f delta = cohesionFrom - boid.GetTranslation(); - if (delta.canBeNormalized()) { - float distSq = delta.magSquared(); - float capDistSq = cohesionRadius * cohesionRadius; - aheadVec += ((distSq > capDistSq) ? 1.f : distSq / capDistSq) * delta.normalized() * cohesionMagnitude; +void CWallCrawlerSwarm::ApplyCohesion(const CBoid& boid, const zeus::CVector3f& cohesionFrom, float cohesionRadius, + float cohesionMagnitude, zeus::CVector3f& aheadVec) const { + const zeus::CVector3f delta = cohesionFrom - boid.GetTranslation(); + if (!delta.canBeNormalized()) { + return; } + + const float distSq = delta.magSquared(); + const float capDistSq = cohesionRadius * cohesionRadius; + aheadVec += ((distSq > capDistSq) ? 1.f : distSq / capDistSq) * delta.normalized() * cohesionMagnitude; } void CWallCrawlerSwarm::ApplyAlignment(const CBoid& boid, const rstl::reserved_vector& nearList, zeus::CVector3f& aheadVec) const { - if (nearList.empty()) + if (nearList.empty()) { return; + } + zeus::CVector3f avg; - for (CBoid* b : nearList) - avg += b->Transform().basis[1]; + for (const CBoid* b : nearList) { + avg += b->GetTransform().basis[1]; + } + avg = avg / float(nearList.size()); aheadVec += zeus::CVector3f::getAngleDiff(boid.GetTransform().basis[1], avg) / M_PIF * (avg * x144_alignmentWeight); } -void CWallCrawlerSwarm::ApplyAttraction(const CBoid& boid, const zeus::CVector3f& attractTo, - float attractionRadius, float attractionMagnitude, - zeus::CVector3f& aheadVec) const { - zeus::CVector3f delta = attractTo - boid.GetTranslation(); - if (delta.canBeNormalized()) { - float distSq = delta.magSquared(); - float capDistSq = attractionRadius * attractionRadius; - aheadVec += ((distSq > capDistSq) ? 0.f : (1.f - distSq / capDistSq)) * delta.normalized() * attractionMagnitude; +void CWallCrawlerSwarm::ApplyAttraction(const CBoid& boid, const zeus::CVector3f& attractTo, float attractionRadius, + float attractionMagnitude, zeus::CVector3f& aheadVec) const { + const zeus::CVector3f delta = attractTo - boid.GetTranslation(); + if (!delta.canBeNormalized()) { + return; } + + const float distSq = delta.magSquared(); + const float capDistSq = attractionRadius * attractionRadius; + aheadVec += ((distSq > capDistSq) ? 0.f : (1.f - distSq / capDistSq)) * delta.normalized() * attractionMagnitude; } void CWallCrawlerSwarm::UpdateBoid(const CAreaCollisionCache& ccache, CStateManager& mgr, float dt, CBoid& boid) { if (boid.x80_27_scarabExplodeTimerEnabled) { if (x558_flavor == EFlavor::Scarab && boid.x4c_timeToExplode > 0.f) { boid.x4c_timeToExplode -= 2.f * dt; - if (boid.x4c_timeToExplode <= 0.f) + if (boid.x4c_timeToExplode <= 0.f) { ExplodeBoid(boid, mgr); + } } } else if (boid.x80_26_launched) { - float radius = 2.f * x374_boidRadius; - float boidMag = boid.x30_velocity.magnitude(); + const float radius = 2.f * x374_boidRadius; + const float boidMag = boid.x30_velocity.magnitude(); float f20 = boidMag * dt; - zeus::CVector3f f25 = (-boid.x30_velocity / boidMag) * x374_boidRadius; + const zeus::CVector3f f25 = (-boid.x30_velocity / boidMag) * x374_boidRadius; zeus::CVector3f f28 = boid.GetTranslation(); bool found = false; while (f20 >= 0.f && !found) { @@ -474,12 +519,12 @@ void CWallCrawlerSwarm::UpdateBoid(const CAreaCollisionCache& ccache, CStateMana if (FindBestSurface(ccache, boid.x30_velocity * dt * 1.5f + f28, radius, surf) && boid.x7c_remainingLaunchNotOnSurfaceFrames == 0) { if (x558_flavor != EFlavor::Scarab) { - boid.Transform() = - LookAt(boid.Transform().basis[2], surf.GetNormal(), M_PIF).multiplyIgnoreTranslation(boid.Transform()); + boid.Transform() = LookAt(boid.GetTransform().basis[2], surf.GetNormal(), M_PIF) + .multiplyIgnoreTranslation(boid.GetTransform()); } - auto plane = surf.GetPlane(); + const auto plane = surf.GetPlane(); boid.Translation() += - -(plane.pointToPlaneDist(boid.GetTranslation()) - x374_boidRadius - 0.01f) * plane.normal(); + -(plane.pointToPlaneDist(boid.GetTranslation()) - x374_boidRadius - 0.01f) * plane.normal(); boid.x7c_framesNotOnSurface = 0; boid.x80_26_launched = false; if (x558_flavor == EFlavor::Scarab) { @@ -493,23 +538,26 @@ void CWallCrawlerSwarm::UpdateBoid(const CAreaCollisionCache& ccache, CStateMana f28 += f25; } if (!found) { - boid.x30_velocity += zeus::CVector3f(0.f, 0.f, -(x558_flavor == EFlavor::Scarab ? 3.f * CPhysicsActor::GravityConstant() : CPhysicsActor::GravityConstant())) * dt; - if (boid.x7c_remainingLaunchNotOnSurfaceFrames) + boid.x30_velocity += zeus::CVector3f(0.f, 0.f, + -(x558_flavor == EFlavor::Scarab ? 3.f * CPhysicsActor::GravityConstant() + : CPhysicsActor::GravityConstant())) * + dt; + if (boid.x7c_remainingLaunchNotOnSurfaceFrames) { boid.x7c_remainingLaunchNotOnSurfaceFrames -= 1; + } } } else if (boid.x7c_framesNotOnSurface >= 30) { boid.x80_24_active = false; } else { - float radius = 2.f * x374_boidRadius; + const float radius = 2.f * x374_boidRadius; bool found = false; CCollisionSurface surf(zeus::skRight, zeus::skForward, zeus::skUp, 0xffffffff); if (FindBestSurface(ccache, boid.GetTranslation() + boid.x30_velocity * dt * 1.5f, radius, surf)) { boid.x50_surface = surf; - boid.Transform() = - LookAt(boid.Transform().basis[2], surf.GetNormal(), zeus::degToRad(180.f * dt)). - multiplyIgnoreTranslation(boid.Transform()); - auto plane = surf.GetPlane(); - float dist = plane.pointToPlaneDist(boid.GetTranslation()); + boid.Transform() = LookAt(boid.GetTransform().basis[2], surf.GetNormal(), zeus::degToRad(180.f * dt)) + .multiplyIgnoreTranslation(boid.GetTransform()); + const auto plane = surf.GetPlane(); + const float dist = plane.pointToPlaneDist(boid.GetTranslation()); if (dist <= 1.5f * x374_boidRadius) { boid.Translation() += -(dist - x374_boidRadius - 0.01f) * plane.normal(); boid.x7c_framesNotOnSurface = 0; @@ -517,21 +565,21 @@ void CWallCrawlerSwarm::UpdateBoid(const CAreaCollisionCache& ccache, CStateMana } } if (!found) { - boid.Transform() = - LookAt(boid.Transform().basis[2], boid.Transform().basis[1], - boid.x30_velocity.magnitude() / x374_boidRadius * dt). - multiplyIgnoreTranslation(boid.Transform()); + boid.Transform() = LookAt(boid.GetTransform().basis[2], boid.GetTransform().basis[1], + boid.x30_velocity.magnitude() / x374_boidRadius * dt) + .multiplyIgnoreTranslation(boid.GetTransform()); boid.x7c_framesNotOnSurface += 1; } rstl::reserved_vector nearList; BuildBoidNearList(boid, x13c_separationRadius, nearList); - zeus::CVector3f aheadVec = boid.Transform().basis[1] * 0.3f; + zeus::CVector3f aheadVec = boid.GetTransform().basis[1] * 0.3f; for (int r26 = 0; r26 < 8; ++r26) { switch (r26) { case 0: - for (auto& rep : x4e0_doorRepulsors) { - if ((rep.x0_center - boid.GetTranslation()).magSquared() < rep.xc_mag * rep.xc_mag) + for (const auto& rep : x4e0_doorRepulsors) { + if ((rep.x0_center - boid.GetTranslation()).magSquared() < rep.xc_mag * rep.xc_mag) { ApplySeparation(boid, rep.x0_center, rep.xc_mag, 4.5f, aheadVec); + } } break; case 4: @@ -553,38 +601,41 @@ void CWallCrawlerSwarm::UpdateBoid(const CAreaCollisionCache& ccache, CStateMana default: break; } - if (aheadVec.magSquared() >= 9.f) + if (aheadVec.magSquared() >= 9.f) { break; + } } - boid.Transform() = LookAt(boid.Transform().basis[1], - ProjectVectorToPlane(aheadVec, boid.Transform().basis[2]).normalized(), M_PIF * dt). - multiplyIgnoreTranslation(boid.Transform()); + boid.Transform() = LookAt(boid.GetTransform().basis[1], + ProjectVectorToPlane(aheadVec, boid.GetTransform().basis[2]).normalized(), M_PIF * dt) + .multiplyIgnoreTranslation(boid.GetTransform()); } } void CWallCrawlerSwarm::LaunchBoid(CBoid& boid, const zeus::CVector3f& dir) { - zeus::CVector3f pos = boid.GetTranslation(); + const zeus::CVector3f pos = boid.GetTranslation(); static float skAttackTime = std::sqrt(2.5f / CPhysicsActor::GravityConstant()) * 2.f; static float skAttackVelocity = 15.f / skAttackTime; zeus::CVector3f deltaFlat = dir - pos; - float deltaZ = deltaFlat.z(); + const float deltaZ = deltaFlat.z(); deltaFlat.z() = 0.f; - float deltaMag = deltaFlat.magnitude(); + const float deltaMag = deltaFlat.magnitude(); boid.Transform().setRotation(zeus::CTransform()); - boid.Transform() = - LookAt(boid.Transform().basis[1], deltaFlat.normalized(), M_PIF).multiplyIgnoreTranslation(boid.Transform()); - zeus::CVector3f vec(skAttackVelocity * boid.Transform().basis[1].toVec2f(), 0.5f * skAttackVelocity); + boid.Transform() = LookAt(boid.GetTransform().basis[1], deltaFlat.normalized(), M_PIF) + .multiplyIgnoreTranslation(boid.GetTransform()); + zeus::CVector3f vec(skAttackVelocity * boid.GetTransform().basis[1].toVec2f(), 0.5f * skAttackVelocity); if (deltaMag > FLT_EPSILON) { deltaFlat = deltaFlat / deltaMag; - float dot = deltaFlat.dot(vec); + const float dot = deltaFlat.dot(vec); if (dot > FLT_EPSILON) { - bool r29 = deltaZ < 0.f; + const bool r29 = deltaZ < 0.f; float _12c, _130; float f25 = 0.f; - if (CSteeringBehaviors::SolveQuadratic(-CPhysicsActor::GravityConstant(), vec.z(), -deltaZ, _12c, _130)) + if (CSteeringBehaviors::SolveQuadratic(-CPhysicsActor::GravityConstant(), vec.z(), -deltaZ, _12c, _130)) { f25 = r29 ? _130 : _12c; - if (!r29) + } + if (!r29) { f25 += deltaMag / dot; + } if (f25 < 10.f) { vec.x() = deltaMag / f25 * deltaFlat.x() * 0.6f; vec.y() = deltaMag / f25 * deltaFlat.y() * 0.6f; @@ -598,14 +649,14 @@ void CWallCrawlerSwarm::LaunchBoid(CBoid& boid, const zeus::CVector3f& dir) { CSfxManager::AddEmitter(x55c_launchSfx, pos, zeus::skZero3f, true, false, 0x7f, x4_areaId); } -static const int kParticleCounts[] = {8, 2, 0, 0}; - void CWallCrawlerSwarm::AddParticle(const zeus::CTransform& xf) { - int i = 0; + static constexpr std::array particleCounts{8, 2, 0, 0}; + + size_t i = 0; for (auto& p : x524_particleGens) { p->SetParticleEmission(true); p->SetTranslation(xf.origin); - p->ForceParticleCreation(kParticleCounts[i]); + p->ForceParticleCreation(particleCounts[i]); p->SetParticleEmission(false); ++i; } @@ -613,29 +664,33 @@ void CWallCrawlerSwarm::AddParticle(const zeus::CTransform& xf) { void CWallCrawlerSwarm::KillBoid(CBoid& boid, CStateManager& mgr, float deathRattleChance, float deadChance) { x130_lastKilledOffset = boid.GetTranslation(); - AddParticle(boid.Transform()); + AddParticle(boid.GetTransform()); boid.x80_24_active = false; - float sendDeadRoll = mgr.GetActiveRandom()->Float(); - float sendDeathRattleRoll = mgr.GetActiveRandom()->Float(); - if (sendDeathRattleRoll < deathRattleChance) + + const float sendDeadRoll = mgr.GetActiveRandom()->Float(); + const float sendDeathRattleRoll = mgr.GetActiveRandom()->Float(); + if (sendDeathRattleRoll < deathRattleChance) { SendScriptMsgs(EScriptObjectState::DeathRattle, mgr, EScriptObjectMessage::None); - if (sendDeadRoll < deadChance) + } + if (sendDeadRoll < deadChance) { SendScriptMsgs(EScriptObjectState::Dead, mgr, EScriptObjectMessage::None); + } } void CWallCrawlerSwarm::UpdatePartition() { x168_partitionedBoidLists.clear(); x168_partitionedBoidLists.resize(125); x360_outlierBoidList = nullptr; - zeus::CAABox aabb = GetBoundingBox(); - zeus::CVector3f vec = (aabb.max - aabb.min) / 5.f; + + const zeus::CAABox aabb = GetBoundingBox(); + const zeus::CVector3f vec = (aabb.max - aabb.min) / 5.f; for (auto& b : x108_boids) { if (b.GetActive()) { - zeus::CVector3f divVec = (b.Translation() - aabb.min) / vec; - int xIdx = int(divVec.x()); - int yIdx = int(divVec.y()); - int zIdx = int(divVec.z()); - int idx = xIdx + yIdx * 5 + zIdx * 25; + const zeus::CVector3f divVec = (b.GetTranslation() - aabb.min) / vec; + const int xIdx = int(divVec.x()); + const int yIdx = int(divVec.y()); + const int zIdx = int(divVec.z()); + const int idx = xIdx + yIdx * 5 + zIdx * 25; if (idx < 0 || idx >= 125 || xIdx < 0 || xIdx >= 5 || yIdx < 0 || yIdx >= 5 || zIdx < 0 || zIdx >= 5) { b.x44_next = x360_outlierBoidList; x360_outlierBoidList = &b; @@ -653,8 +708,8 @@ zeus::CVector3f CWallCrawlerSwarm::FindClosestCell(const zeus::CVector3f& pos) c for (int r28 = 0; r28 < 5; ++r28) { for (int r29 = 0; r29 < 5; ++r29) { for (int r25 = 0; r25 < 5; ++r25) { - zeus::CAABox aabb = BoxForPosition(r28, r29, r25, 0.1f); - float dist = (aabb.center() - pos).magSquared(); + const zeus::CAABox aabb = BoxForPosition(r28, r29, r25, 0.1f); + const float dist = (aabb.center() - pos).magSquared(); if (dist < minDist) { minDist = dist; ret = aabb.center(); @@ -666,48 +721,56 @@ zeus::CVector3f CWallCrawlerSwarm::FindClosestCell(const zeus::CVector3f& pos) c } void CWallCrawlerSwarm::UpdateEffects(CStateManager& mgr, CAnimData& aData, int vol) { - if (aData.GetPassedSoundPOICount() > 0 && !CAnimData::g_SoundPOINodes.empty()) { - for (int i = 0; i < aData.GetPassedSoundPOICount(); ++i) { - const CSoundPOINode& n = CAnimData::g_SoundPOINodes[i]; - if (n.GetPoiType() == EPOIType::Sound && - (n.GetCharacterIndex() == -1 || n.GetCharacterIndex() == aData.GetCharacterIndex())) { - u16 sfx = CSfxManager::TranslateSFXID(u16(n.GetSfxId() & 0xffff)); - bool loop = bool(n.GetSfxId() >> 31); - if (!loop) { - CAudioSys::C3DEmitterParmData parmData; - parmData.x0_pos = FindClosestCell(mgr.GetPlayer().GetTranslation()); - static float maxDist = n.GetMaxDist(); - static float falloff = n.GetFalloff(); - parmData.x18_maxDist = maxDist; - parmData.x1c_distComp = falloff; - parmData.x20_flags = 0x1; - parmData.x24_sfxId = sfx; - parmData.x26_maxVol = zeus::clamp(0, vol, 127) / 127.f; - parmData.x27_minVol = 20.f / 127.f; - parmData.x28_important = false; - parmData.x29_prio = 0x7f; - CSfxManager::AddEmitter(parmData, true, 0x7f, false, x4_areaId); - } - } + if (aData.GetPassedSoundPOICount() == 0 || CAnimData::g_SoundPOINodes.empty()) { + return; + } + + for (size_t i = 0; i < aData.GetPassedSoundPOICount(); ++i) { + const CSoundPOINode& n = CAnimData::g_SoundPOINodes[i]; + if (n.GetPoiType() != EPOIType::Sound || + (n.GetCharacterIndex() != -1 && n.GetCharacterIndex() != aData.GetCharacterIndex())) { + continue; } + + const u16 sfx = CSfxManager::TranslateSFXID(u16(n.GetSfxId() & 0xffff)); + const bool loop = bool(n.GetSfxId() >> 31); + if (loop) { + continue; + } + + CAudioSys::C3DEmitterParmData parmData; + parmData.x0_pos = FindClosestCell(mgr.GetPlayer().GetTranslation()); + static float maxDist = n.GetMaxDist(); + static float falloff = n.GetFalloff(); + parmData.x18_maxDist = maxDist; + parmData.x1c_distComp = falloff; + parmData.x20_flags = 0x1; + parmData.x24_sfxId = sfx; + parmData.x26_maxVol = zeus::clamp(0, vol, 127) / 127.f; + parmData.x27_minVol = 20.f / 127.f; + parmData.x28_important = false; + parmData.x29_prio = 0x7f; + CSfxManager::AddEmitter(parmData, true, 0x7f, false, x4_areaId); } } zeus::CAABox CWallCrawlerSwarm::BoxForPosition(int x, int y, int z, float f) const { - zeus::CAABox aabb = GetBoundingBox(); - zeus::CVector3f vec = (aabb.max - aabb.min) / 5.f; + const zeus::CAABox aabb = GetBoundingBox(); + const zeus::CVector3f vec = (aabb.max - aabb.min) / 5.f; return zeus::CAABox(zeus::CVector3f(x, y, z) * vec + aabb.min - f, zeus::CVector3f(x + 1, y + 1, z + 1) * vec + aabb.min + f); } void CWallCrawlerSwarm::Think(float dt, CStateManager& mgr) { - if (!GetActive()) + if (!GetActive()) { return; + } if (x560_26_modelAssetDirty && CModelData::GetRenderingModel(mgr) != x4dc_whichModel) { - auto which = CModelData::GetRenderingModel(mgr); - if (which != x4dc_whichModel) + const auto which = CModelData::GetRenderingModel(mgr); + if (which != x4dc_whichModel) { AllocateSkinnedModels(mgr, which); + } } xe4_27_notInSortedLists = true; @@ -715,15 +778,18 @@ void CWallCrawlerSwarm::Think(float dt, CStateManager& mgr) { x36c_crabDamageCooldownTimer -= dt; ++x100_thinkCounter; const CGameArea* area = mgr.GetWorld()->GetAreaAlways(x4_areaId); - auto occState = + const auto occState = area->IsPostConstructed() ? area->GetOcclusionState() : CGameArea::EOcclusionState::Occluded; if (occState != CGameArea::EOcclusionState::Visible) { - if (x104_occludedTimer > 0.f) + if (x104_occludedTimer > 0.f) { x104_occludedTimer -= dt; - if (x104_occludedTimer <= 0.f) + } + if (x104_occludedTimer <= 0.f) { return; - if (x100_thinkCounter & 0x2) + } + if (x100_thinkCounter & 0x2) { return; + } } else { x104_occludedTimer = 7.f; } @@ -732,15 +798,17 @@ void CWallCrawlerSwarm::Think(float dt, CStateManager& mgr) { x42c_lockOnIdx = SelectLockOnIdx(mgr); xe7_31_targetable = x42c_lockOnIdx != -1; - if (x42c_lockOnIdx == -1) + if (x42c_lockOnIdx == -1) { RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr); - else + } else { AddMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr); + } + while ((x54c_maxCreatedBoids == 0 || x550_createdBoids < x54c_maxCreatedBoids) && x368_boidGenCooldownTimer <= 0.f) { int idx = 0; bool madeBoid = false; - for (auto& b : x108_boids) { + for (const auto& b : x108_boids) { if (!b.GetActive()) { CreateBoid(mgr, idx); x550_createdBoids += 1; @@ -762,24 +830,25 @@ void CWallCrawlerSwarm::Think(float dt, CStateManager& mgr) { for (int r26 = 0; r26 < 5; ++r26) { for (int r27 = 0; r27 < 5; ++r27) { for (int r20 = 0; r20 < 5; ++r20) { - int idx = r20 * 25 + r27 * 5 + r26; + const int idx = r20 * 25 + r27 * 5 + r26; if (CBoid* boid = x168_partitionedBoidLists[idx]) { - zeus::CAABox aabb = BoxForPosition(r26, r27, r20, x374_boidRadius + 0.5f); + const zeus::CAABox aabb = BoxForPosition(r26, r27, r20, x374_boidRadius + 0.5f); CAreaCollisionCache ccache(aabb); CGameCollision::BuildAreaCollisionCache(mgr, ccache); while (boid) { r21 += 1; if (boid->GetActive()) { if (x558_flavor == EFlavor::Scarab) { - xe8_aabox.accumulateBounds(boid->Translation() + x37c_scarabBoxMargin); - xe8_aabox.accumulateBounds(boid->Translation() - x37c_scarabBoxMargin); + xe8_aabox.accumulateBounds(boid->GetTranslation() + x37c_scarabBoxMargin); + xe8_aabox.accumulateBounds(boid->GetTranslation() - x37c_scarabBoxMargin); } else { - xe8_aabox.accumulateBounds(boid->Translation()); + xe8_aabox.accumulateBounds(boid->GetTranslation()); } } if (((x100_thinkCounter & 0x1) == (r21 & 0x1) && boid->GetActive() && boid->x48_timeToDie < 0.1f) || - boid->x80_26_launched) + boid->x80_26_launched) { UpdateBoid(ccache, mgr, dt, *boid); + } boid = boid->x44_next; } } @@ -789,12 +858,13 @@ void CWallCrawlerSwarm::Think(float dt, CStateManager& mgr) { for (CBoid* boid = x360_outlierBoidList; boid; boid = boid->x44_next) { r21 += 1; - if (boid->GetActive()) - xe8_aabox.accumulateBounds(boid->Translation()); + if (boid->GetActive()) { + xe8_aabox.accumulateBounds(boid->GetTranslation()); + } if (((x100_thinkCounter & 0x1) == (r21 & 0x1) && boid->GetActive() && boid->x48_timeToDie < 0.1f) || boid->x80_26_launched) { - float margin = 1.5f + x374_boidRadius + 0.5f; - zeus::CAABox aabb(boid->Translation() - margin, boid->Translation() + margin); + const float margin = 1.5f + x374_boidRadius + 0.5f; + const zeus::CAABox aabb(boid->GetTranslation() - margin, boid->GetTranslation() + margin); CAreaCollisionCache ccache(aabb); CGameCollision::BuildAreaCollisionCache(mgr, ccache); UpdateBoid(ccache, mgr, dt, *boid); @@ -809,8 +879,8 @@ void CWallCrawlerSwarm::Think(float dt, CStateManager& mgr) { int r9 = 0; int r3 = 0; int r8 = 0; - bool _38F8[4] = {}; - bool _38F4[4] = {}; + std::array _38F8{}; + std::array _38F4{}; for (const auto& b : x108_boids) { if (b.GetActive() && !b.x80_26_launched) { if (b.x80_27_scarabExplodeTimerEnabled || b.x80_28_nearPlayer) { @@ -824,29 +894,32 @@ void CWallCrawlerSwarm::Think(float dt, CStateManager& mgr) { ++r9; } - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < _38F4.size(); ++i) { x4b0_modelDatas[i]->GetAnimationData()->SetPlaybackRate(x160_animPlaybackSpeed); deltas1 = x4b0_modelDatas[i]->AdvanceAnimation(dt, mgr, x4_areaId, true); - x4b0_modelDatas[i+4]->GetAnimationData()->SetPlaybackRate(x160_animPlaybackSpeed); - deltas2 = x4b0_modelDatas[i+4]->AdvanceAnimation(dt, mgr, x4_areaId, true); - if (x4b0_modelDatas[i]->HasAnimData() && _38F4[i]) + x4b0_modelDatas[i + 4]->GetAnimationData()->SetPlaybackRate(x160_animPlaybackSpeed); + deltas2 = x4b0_modelDatas[i + 4]->AdvanceAnimation(dt, mgr, x4_areaId, true); + if (x4b0_modelDatas[i]->HasAnimData() && _38F4[i]) { UpdateEffects(mgr, *x4b0_modelDatas[i]->GetAnimationData(), r8 * 44 / x548_numBoids + 0x53); - if (x4b0_modelDatas[i+4]->HasAnimData() && _38F8[i]) - UpdateEffects(mgr, *x4b0_modelDatas[i+4]->GetAnimationData(), r3 * 44 / x548_numBoids + 0x53); - for (int r20 = i; r20 < x108_boids.size(); r20 += 4) { + } + if (x4b0_modelDatas[i + 4]->HasAnimData() && _38F8[i]) { + UpdateEffects(mgr, *x4b0_modelDatas[i + 4]->GetAnimationData(), r3 * 44 / x548_numBoids + 0x53); + } + for (size_t r20 = i; r20 < x108_boids.size(); r20 += 4) { CBoid& b = x108_boids[r20]; if (b.GetActive()) { if (b.x80_26_launched) { b.Translation() += b.x30_velocity * dt; } else if (b.x48_timeToDie > 0.f) { b.x48_timeToDie -= dt; - if (b.x48_timeToDie < 0.7f * mgr.GetActiveRandom()->Float()) + if (b.x48_timeToDie < 0.7f * mgr.GetActiveRandom()->Float()) { KillBoid(b, mgr, 1.f, 0.05f); + } } else if (b.x80_27_scarabExplodeTimerEnabled || b.x80_28_nearPlayer) { - b.x30_velocity = b.Transform().rotate(deltas2.x0_posDelta) * 1.5f / dt; + b.x30_velocity = b.GetTransform().rotate(deltas2.x0_posDelta) * 1.5f / dt; b.Translation() += b.x30_velocity * dt; } else { - b.x30_velocity = b.Transform().rotate(deltas1.x0_posDelta) * 1.5f / dt; + b.x30_velocity = b.GetTransform().rotate(deltas1.x0_posDelta) * 1.5f / dt; b.Translation() += b.x30_velocity * dt; } } @@ -854,29 +927,32 @@ void CWallCrawlerSwarm::Think(float dt, CStateManager& mgr) { } if (x558_flavor == EFlavor::Crab) { - zeus::CVector3f playerPos = mgr.GetPlayer().GetTranslation(); + const zeus::CVector3f playerPos = mgr.GetPlayer().GetTranslation(); for (auto& b : x108_boids) { - if (b.GetActive() && zeus::close_enough(b.x48_timeToDie, 0.f) && !b.x80_26_launched) - b.x80_28_nearPlayer = (playerPos - b.Translation()).magnitude() < x154_attractionRadius; + if (b.GetActive() && zeus::close_enough(b.x48_timeToDie, 0.f) && !b.x80_26_launched) { + b.x80_28_nearPlayer = (playerPos - b.GetTranslation()).magnitude() < x154_attractionRadius; + } } } if (x558_flavor == EFlavor::Parasite && x554_maxLaunches > 0) { - zeus::CVector3f _383c = mgr.GetPlayer().GetTranslation() + zeus::skUp; - static const CMaterialFilter filter = CMaterialFilter::MakeInclude(EMaterialTypes::Solid); + const zeus::CVector3f _383c = mgr.GetPlayer().GetTranslation() + zeus::skUp; + static constexpr auto filter = CMaterialFilter::MakeInclude(EMaterialTypes::Solid); int numLaunched = 0; - for (auto& b : x108_boids) { - if (b.GetActive() && b.x80_26_launched) + for (const auto& b : x108_boids) { + if (b.GetActive() && b.x80_26_launched) { ++numLaunched; + } } + for (auto it = x108_boids.begin(); it != x108_boids.end() && numLaunched < x554_maxLaunches; ++it) { CBoid& b = *it; if (b.GetActive() && zeus::close_enough(b.x48_timeToDie, 0.f) && !b.x80_26_launched && - (b.Translation() - _383c).magSquared() < 18.f * 18.f && mgr.GetActiveRandom()->Float() <= 0.02f) { - zeus::CVector3f dir = _383c - b.Translation(); - float mag = dir.magnitude(); + (b.GetTranslation() - _383c).magSquared() < 18.f * 18.f && mgr.GetActiveRandom()->Float() <= 0.02f) { + zeus::CVector3f dir = _383c - b.GetTranslation(); + const float mag = dir.magnitude(); dir = dir / mag; - if (mgr.RayStaticIntersection(b.Translation(), dir, mag, filter).IsInvalid()) { + if (mgr.RayStaticIntersection(b.GetTranslation(), dir, mag, filter).IsInvalid()) { LaunchBoid(b, _383c); ++numLaunched; } @@ -886,8 +962,9 @@ void CWallCrawlerSwarm::Think(float dt, CStateManager& mgr) { } void CWallCrawlerSwarm::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { - for (int i = 0; i < 5; ++i) + for (size_t i = 0; i < 5; ++i) { x4b0_modelDatas[i]->GetAnimationData()->PreRender(); + } bool activeBoid = false; for (auto& b : x108_boids) { if (b.GetActive()) { @@ -901,19 +978,26 @@ void CWallCrawlerSwarm::PreRender(CStateManager& mgr, const zeus::CFrustum& frus } void CWallCrawlerSwarm::RenderParticles() const { - for (const auto& p : x524_particleGens) + for (const auto& p : x524_particleGens) { g_Renderer->AddParticleGen(*p); + } } -void CWallCrawlerSwarm::AddToRenderer(const zeus::CFrustum&, const CStateManager& mgr) const { - if (GetActive()) { - RenderParticles(); - if (!xe4_30_outOfFrustum) { - if (CanRenderUnsorted(mgr)) - Render(mgr); - else - EnsureRendered(mgr); - } +void CWallCrawlerSwarm::AddToRenderer(const zeus::CFrustum&, CStateManager& mgr) { + if (!GetActive()) { + return; + } + + RenderParticles(); + + if (xe4_30_outOfFrustum) { + return; + } + + if (CanRenderUnsorted(mgr)) { + Render(mgr); + } else { + EnsureRendered(mgr); } } @@ -926,14 +1010,13 @@ zeus::CColor CWallCrawlerSwarm::SoftwareLight(const CStateManager& mgr, const ze lights.BuildDynamicLightList(mgr, aabb); zeus::CColor ret = lights.GetAmbientColor(); ret.a() = 1.f; - zeus::CVector3f center = aabb.center(); - u32 lightCount = lights.GetActiveLightCount(); + const zeus::CVector3f center = aabb.center(); + const u32 lightCount = lights.GetActiveLightCount(); for (u32 i = 0; i < lightCount; ++i) { const CLight& light = lights.GetLight(i); - float dist = (light.GetPosition() - center).magnitude(); - float att = 1.f / (dist * dist * light.GetAttenuationQuadratic() + - dist * light.GetAttenuationLinear() + - light.GetAttenuationConstant()); + const float dist = (light.GetPosition() - center).magnitude(); + const float att = 1.f / (dist * dist * light.GetAttenuationQuadratic() + dist * light.GetAttenuationLinear() + + light.GetAttenuationConstant()); ret += zeus::CColor::lerp(zeus::skBlack, light.GetColor(), 0.8f * std::min(att, 1.f)); } return ret; @@ -946,78 +1029,89 @@ void CWallCrawlerSwarm::HardwareLight(const CStateManager& mgr, const zeus::CAAB lights.SetFindShadowLight(false); lights.BuildAreaLightList(mgr, *mgr.GetWorld()->GetAreaAlways(x4_areaId), aabb); lights.BuildDynamicLightList(mgr, aabb); - for (auto& m : x4b0_modelDatas) { + for (const auto& m : x4b0_modelDatas) { lights.ActivateLights(*m->PickAnimatedModel(x4dc_whichModel).GetModelInst()); - if (auto iceModel = m->GetAnimationData()->GetIceModel()) + if (const auto iceModel = m->GetAnimationData()->GetIceModel()) { lights.ActivateLights(*iceModel->GetModelInst()); + } } } void CWallCrawlerSwarm::RenderBoid(const CBoid* boid, u32& drawMask, bool thermalHot, const CModelFlags& flags) const { u32 modelIndex = 0x0; - if (boid->x80_26_launched) + if (boid->x80_26_launched) { modelIndex = 0x8; - else if (boid->x48_timeToDie > 0.f) + } else if (boid->x48_timeToDie > 0.f) { modelIndex = 0x9; - else if (boid->x80_27_scarabExplodeTimerEnabled || boid->x80_28_nearPlayer) + } else if (boid->x80_27_scarabExplodeTimerEnabled || boid->x80_28_nearPlayer) { modelIndex += 0x4; + } + CModelData& mData = *x4b0_modelDatas[modelIndex]; CSkinnedModel& model = mData.PickAnimatedModel(x4dc_whichModel); - if (!model.GetModelInst()->TryLockTextures()) + if (!model.GetModelInst()->TryLockTextures()) { return; - u32 thisDrawMask = 1u << modelIndex; + } + + const u32 thisDrawMask = 1u << modelIndex; if (drawMask & thisDrawMask) { drawMask &= ~thisDrawMask; mData.GetAnimationData()->BuildPose(); } + model.GetModelInst()->SetAmbientColor(boid->x40_ambientLighting); CGraphics::SetModelMatrix(boid->GetTransform()); if (boid->x48_timeToDie > 0.f && !thermalHot) { - CModelFlags useFlags(0, 0, 3, zeus::skWhite); - mData.GetAnimationData()->Render(model, useFlags, {}, nullptr); + const CModelFlags useFlags(0, 0, 3, zeus::skWhite); + mData.GetAnimationData()->Render(model, useFlags, std::nullopt, nullptr); if (auto iceModel = mData.GetAnimationData()->GetIceModel()) { - if (!iceModel->GetModelInst()->TryLockTextures()) + if (!iceModel->GetModelInst()->TryLockTextures()) { return; + } iceModel->GetModelInst()->SetAmbientColor(zeus::skWhite); - float alpha = 1.f - boid->x48_timeToDie; - zeus::CColor color(1.f, alpha > 0.f ? boid->x48_timeToDie : 1.f); - CModelFlags iceFlags(5, 0, 3, color); - mData.GetAnimationData()->Render(*iceModel, iceFlags, {}, nullptr); + const float alpha = 1.f - boid->x48_timeToDie; + const zeus::CColor color(1.f, alpha > 0.f ? boid->x48_timeToDie : 1.f); + const CModelFlags iceFlags(5, 0, 3, color); + mData.GetAnimationData()->Render(*iceModel, iceFlags, std::nullopt, nullptr); } } else if (thermalHot) { - CModelFlags thermFlags(5, 0, 3, zeus::skWhite); + const CModelFlags thermFlags(5, 0, 3, zeus::skWhite); mData.RenderThermal(zeus::skWhite, zeus::CColor(0.f, 0.25f), thermFlags); } else { - mData.GetAnimationData()->Render(model, flags, {}, nullptr); + mData.GetAnimationData()->Render(model, flags, std::nullopt, nullptr); } } -void CWallCrawlerSwarm::Render(const CStateManager& mgr) const { +void CWallCrawlerSwarm::Render(CStateManager& mgr) { SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(fmt("CWallCrawlerSwarm::Render {} {} {}"), x8_uid, xc_editorId, x10_name).c_str(), zeus::skOrange); u32 drawMask = 0xffffffff; - bool r24 = x560_24_enableLighting; - bool r23 = x560_25_useSoftwareLight; + const bool r24 = x560_24_enableLighting; + const bool r23 = x560_25_useSoftwareLight; if (!r24) { // Ambient 50% grey } - bool thermalHot = mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot; + + const bool thermalHot = mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot; CModelFlags flags(0, 0, 3, zeus::skWhite); - if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) + if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) { flags = CModelFlags(5, 0, 3, zeus::CColor(1.f, 0.3f)); + } + for (int r27 = 0; r27 < 5; ++r27) { for (int r28 = 0; r28 < 5; ++r28) { for (int r21 = 0; r21 < 5; ++r21) { - int idx = r21 * 25 + r28 * 5 + r27; + const int idx = r21 * 25 + r28 * 5 + r27; if (CBoid* b = x168_partitionedBoidLists[idx]) { if (r24) { - zeus::CAABox aabb = BoxForPosition(r27, r28, r21, 0.f); + const zeus::CAABox aabb = BoxForPosition(r27, r28, r21, 0.f); if (r23) { if ((idx & 0x3) == (x100_thinkCounter & 0x3)) { - zeus::CColor color = SoftwareLight(mgr, aabb); + const zeus::CColor color = SoftwareLight(mgr, aabb); for (CBoid* b2 = b; b2; b2 = b2->x44_next) { - if (b2->GetActive()) + if (b2->GetActive()) { b2->x40_ambientLighting = zeus::CColor::lerp(b2->x40_ambientLighting, color, 0.3f); + } } } } else { @@ -1025,23 +1119,26 @@ void CWallCrawlerSwarm::Render(const CStateManager& mgr) const { } } for (CBoid* b2 = b; b2; b2 = b2->x44_next) { - if (b2->x80_25_inFrustum && b2->GetActive()) + if (b2->x80_25_inFrustum && b2->GetActive()) { RenderBoid(b2, drawMask, thermalHot, flags); + } } } } } } + CBoid* b = x360_outlierBoidList; for (int i = 1; b; ++i, b = b->x44_next) { if (b->x80_25_inFrustum && b->GetActive()) { if (r24) { - zeus::CAABox aabb(b->GetTranslation() - x374_boidRadius, b->GetTranslation() + x374_boidRadius); + const zeus::CAABox aabb(b->GetTranslation() - x374_boidRadius, b->GetTranslation() + x374_boidRadius); if (r23) { if ((i & 0x3) == (x100_thinkCounter & 0x3)) { zeus::CColor color = SoftwareLight(mgr, aabb); - if (b->GetActive()) + if (b->GetActive()) { b->x40_ambientLighting = zeus::CColor::lerp(b->x40_ambientLighting, color, 0.3f); + } } } else { HardwareLight(mgr, aabb); @@ -1067,37 +1164,40 @@ std::optional CWallCrawlerSwarm::GetTouchBounds() const { void CWallCrawlerSwarm::Touch(CActor& other, CStateManager& mgr) { CActor::Touch(other, mgr); - if (TCastToPtr proj = other) { + if (TCastToConstPtr proj = other) { if (x3c4_dVuln.WeaponHurts(proj->GetDamageInfo().GetWeaponMode(), false)) { if (auto projTb = proj->GetTouchBounds()) { - float f0 = 0.1f + x378_touchRadius; - float f30 = f0 * f0; + const float f0 = 0.1f + x378_touchRadius; + const float f30 = f0 * f0; for (auto& b : x108_boids) { if (b.GetActive()) { - zeus::CAABox aabb(b.GetTranslation() - f30, b.GetTranslation() + f30); + const zeus::CAABox aabb(b.GetTranslation() - f30, b.GetTranslation() + f30); if (aabb.intersects(*projTb)) { b.x78_health -= proj->GetDamageInfo().GetDamage(x3c4_dVuln); - if (b.x78_health <= 0.f) + if (b.x78_health <= 0.f) { KillBoid(b, mgr, 1.f, 0.1f); + } } } } } } } - if (TCastToPtr player = other) { - float radius = zeus::close_enough(x380_playerTouchRadius, 0.f) ? x378_touchRadius : x380_playerTouchRadius; + + if (TCastToConstPtr player = other) { + const float radius = zeus::close_enough(x380_playerTouchRadius, 0.f) ? x378_touchRadius : x380_playerTouchRadius; if (auto playerTb = player->GetTouchBounds()) { for (auto& b : x108_boids) { if (b.GetActive() && b.x48_timeToDie <= 0.f) { if (x558_flavor == EFlavor::Scarab && b.x80_27_scarabExplodeTimerEnabled) { - zeus::CAABox aabb(b.GetTranslation() - x37c_scarabBoxMargin, b.GetTranslation() + x37c_scarabBoxMargin); + const zeus::CAABox aabb(b.GetTranslation() - x37c_scarabBoxMargin, + b.GetTranslation() + x37c_scarabBoxMargin); if (playerTb->intersects(aabb)) { ExplodeBoid(b, mgr); SetExplodeTimers(b.GetTranslation(), 0.5f, 0.5f, 2.5f); } } - zeus::CAABox aabb(b.GetTranslation() - radius, b.GetTranslation() + radius); + const zeus::CAABox aabb(b.GetTranslation() - radius, b.GetTranslation() + radius); if (playerTb->intersects(aabb)) { if (b.GetActive() && x558_flavor == EFlavor::Parasite) { constexpr CDamageInfo dInfo(CWeaponMode(EWeaponType::AI), 2.0e-05f, 0.f, 0.f); @@ -1120,15 +1220,19 @@ void CWallCrawlerSwarm::Touch(CActor& other, CStateManager& mgr) { } zeus::CVector3f CWallCrawlerSwarm::GetOrbitPosition(const CStateManager&) const { - if (x42c_lockOnIdx == -1) + if (x42c_lockOnIdx == -1) { return x124_lastOrbitPosition; + } + x124_lastOrbitPosition = x108_boids[x42c_lockOnIdx].GetTranslation(); return x124_lastOrbitPosition; } zeus::CVector3f CWallCrawlerSwarm::GetAimPosition(const CStateManager&, float dt) const { - if (x42c_lockOnIdx == -1) + if (x42c_lockOnIdx == -1) { return x124_lastOrbitPosition; + } + return x108_boids[x42c_lockOnIdx].x30_velocity * dt + x124_lastOrbitPosition; } diff --git a/Runtime/World/CWallCrawlerSwarm.hpp b/Runtime/World/CWallCrawlerSwarm.hpp index f88871b9c..a7c934f2a 100644 --- a/Runtime/World/CWallCrawlerSwarm.hpp +++ b/Runtime/World/CWallCrawlerSwarm.hpp @@ -195,8 +195,8 @@ public: void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void Think(float, CStateManager&) override; void PreRender(CStateManager&, const zeus::CFrustum&) override; - void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; - void Render(const CStateManager&) const override; + void AddToRenderer(const zeus::CFrustum&, CStateManager&) override; + void Render(CStateManager&) override; bool CanRenderUnsorted(const CStateManager&) const override; void CalculateRenderBounds() override; std::optional GetTouchBounds() const override; diff --git a/Runtime/World/CWallWalker.cpp b/Runtime/World/CWallWalker.cpp index df83a32f2..e76ae0432 100644 --- a/Runtime/World/CWallWalker.cpp +++ b/Runtime/World/CWallWalker.cpp @@ -164,7 +164,7 @@ void CWallWalker::Think(float dt, CStateManager& mgr) { } } -void CWallWalker::Render(const CStateManager& mgr) const { CPatterned::Render(mgr); } +void CWallWalker::Render(CStateManager& mgr) { CPatterned::Render(mgr); } void CWallWalker::UpdateWPDestination(CStateManager& mgr) { if (TCastToPtr wp = mgr.ObjectById(x2dc_destObj)) { diff --git a/Runtime/World/CWallWalker.hpp b/Runtime/World/CWallWalker.hpp index ab51512d6..133af55b2 100644 --- a/Runtime/World/CWallWalker.hpp +++ b/Runtime/World/CWallWalker.hpp @@ -55,7 +55,7 @@ public: void PreThink(float, CStateManager&) override; void Think(float, CStateManager&) override; - void Render(const CStateManager&) const override; + void Render(CStateManager&) override; const CCollisionPrimitive* GetCollisionPrimitive() const override { return &x590_colSphere; } void UpdateWPDestination(CStateManager&); }; diff --git a/Runtime/World/CWorld.cpp b/Runtime/World/CWorld.cpp index 272ae9fd9..f2499f3ca 100644 --- a/Runtime/World/CWorld.cpp +++ b/Runtime/World/CWorld.cpp @@ -37,7 +37,7 @@ CAssetId CDummyWorld::IGetSaveWorldAssetId() const { return x14_savwId; } const CMapWorld* CDummyWorld::IGetMapWorld() const { return x2c_mapWorld.GetObj(); } -CMapWorld* CDummyWorld::IMapWorld() { return x2c_mapWorld.GetObj(); } +CMapWorld* CDummyWorld::IGetMapWorld() { return x2c_mapWorld.GetObj(); } const IGameArea* CDummyWorld::IGetAreaAlways(TAreaId id) const { return &x18_areas.at(id); } @@ -210,7 +210,7 @@ CAssetId CWorld::IGetSaveWorldAssetId() const { return x10_savwId; } const CMapWorld* CWorld::IGetMapWorld() const { return const_cast(this)->GetMapWorld(); } -CMapWorld* CWorld::IMapWorld() { return const_cast(GetMapWorld()); } +CMapWorld* CWorld::IGetMapWorld() { return const_cast(GetMapWorld()); } const CGameArea* CWorld::GetAreaAlways(TAreaId id) const { return x18_areas.at(id).get(); } @@ -233,15 +233,18 @@ TAreaId CWorld::IGetAreaId(CAssetId id) const { } void CWorld::MoveToChain(CGameArea* area, EChain chain) { - if (area->x138_curChain == chain) + if (area->x138_curChain == chain) { return; + } - if (area->x138_curChain != EChain::Invalid) - if (x4c_chainHeads[int(area->x138_curChain)] == area) - x4c_chainHeads[int(area->x138_curChain)] = area->x130_next; + if (area->x138_curChain != EChain::Invalid) { + if (x4c_chainHeads[size_t(area->x138_curChain)] == area) { + x4c_chainHeads[size_t(area->x138_curChain)] = area->x130_next; + } + } - area->SetChain(x4c_chainHeads[int(chain)], chain); - x4c_chainHeads[int(chain)] = area; + area->SetChain(x4c_chainHeads[size_t(chain)], chain); + x4c_chainHeads[size_t(chain)] = area; } void CWorld::MoveAreaToAliveChain(TAreaId aid) { MoveToChain(x18_areas[aid].get(), EChain::Alive); } @@ -307,13 +310,15 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId) r.readUint32Big(); x18_areas.reserve(areaCount); - for (u32 i = 0; i < areaCount; ++i) + for (u32 i = 0; i < areaCount; ++i) { x18_areas.push_back(std::make_unique(r, i, version)); + } - if (x48_chainCount < 5) { - for (int i = x48_chainCount; i < 5; ++i) + if (x48_chainCount < x4c_chainHeads.size()) { + for (size_t i = x48_chainCount; i < x4c_chainHeads.size(); ++i) { x4c_chainHeads[i] = nullptr; - x48_chainCount = 5; + } + x48_chainCount = x4c_chainHeads.size(); } for (std::unique_ptr& area : x18_areas) @@ -567,7 +572,7 @@ void CWorld::Update(float dt) { u32 areaCount = 0; - for (CGameArea* head = x4c_chainHeads[3]; head != skGlobalNonConstEnd; head = head->x130_next, ++areaCount) { + for (auto head = GetChainHead(EChain::Alive); head != AliveAreasEnd(); ++head, ++areaCount) { head->AliveUpdate(dt); if (head->DoesAreaNeedSkyNow()) { @@ -625,7 +630,7 @@ void CWorld::Update(float dt) { } void CWorld::PreRender() { - for (CGameArea* head = x4c_chainHeads[3]; head != skGlobalNonConstEnd; head = head->x130_next) { + for (auto head = GetChainHead(EChain::Alive); head != AliveAreasEnd(); ++head) { head->PreRender(); } } diff --git a/Runtime/World/CWorld.hpp b/Runtime/World/CWorld.hpp index 7ad576d33..2b662179d 100644 --- a/Runtime/World/CWorld.hpp +++ b/Runtime/World/CWorld.hpp @@ -1,11 +1,13 @@ #pragma once +#include #include #include #include #include "Runtime/RetroTypes.hpp" #include "Runtime/rstl.hpp" +#include "Runtime/Audio/CAudioGroupSet.hpp" #include "Runtime/Audio/CSfxManager.hpp" #include "Runtime/AutoMapper/CMapWorld.hpp" #include "Runtime/Graphics/CModel.hpp" @@ -14,7 +16,6 @@ #include "Runtime/World/ScriptObjectSupport.hpp" namespace urde { -class CAudioGroupSet; class CGameArea; class CResFactory; class IGameArea; @@ -27,7 +28,7 @@ public: virtual CAssetId IGetStringTableAssetId() const = 0; virtual CAssetId IGetSaveWorldAssetId() const = 0; virtual const CMapWorld* IGetMapWorld() const = 0; - virtual CMapWorld* IMapWorld() = 0; + virtual CMapWorld* IGetMapWorld() = 0; virtual const IGameArea* IGetAreaAlways(TAreaId id) const = 0; virtual TAreaId IGetCurrentAreaId() const = 0; virtual TAreaId IGetAreaId(CAssetId id) const = 0; @@ -62,7 +63,7 @@ public: CAssetId IGetStringTableAssetId() const override; CAssetId IGetSaveWorldAssetId() const override; const CMapWorld* IGetMapWorld() const override; - CMapWorld* IMapWorld() override; + CMapWorld* IGetMapWorld() override; const IGameArea* IGetAreaAlways(TAreaId id) const override; TAreaId IGetCurrentAreaId() const override; TAreaId IGetAreaId(CAssetId id) const override; @@ -83,7 +84,7 @@ public: public: CRelay() = default; - CRelay(CInputStream& in); + explicit CRelay(CInputStream& in); TEditorId GetRelayId() const { return x0_relay; } TEditorId GetTargetId() const { return x4_target; } @@ -104,8 +105,6 @@ public: }; private: - static constexpr CGameArea* skGlobalEnd = nullptr; - static constexpr CGameArea* skGlobalNonConstEnd = nullptr; enum class Phase { Loading, LoadingMap, @@ -125,7 +124,7 @@ private: std::unique_ptr x40_loadBuf; u32 x44_bufSz; u32 x48_chainCount = 0; - CGameArea* x4c_chainHeads[5] = {}; + std::array x4c_chainHeads{}; IObjectStore& x60_objectStore; IFactory& x64_resFactory; @@ -158,14 +157,18 @@ public: void MoveToChain(CGameArea* area, EChain chain); void MoveAreaToAliveChain(TAreaId aid); bool CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId); - CGameArea::CChainIterator GetChainHead(EChain chain) { return {x4c_chainHeads[int(chain)]}; } - CGameArea::CConstChainIterator GetChainHead(EChain chain) const { return {x4c_chainHeads[int(chain)]}; } - CGameArea::CChainIterator begin() { return GetChainHead(EChain::Alive); } - CGameArea::CChainIterator end() { return AliveAreasEnd(); } - CGameArea::CConstChainIterator begin() const { return GetChainHead(EChain::Alive); } - CGameArea::CConstChainIterator end() const { return GetAliveAreasEnd(); } + + [[nodiscard]] auto GetChainHead(EChain chain) { return CGameArea::CChainIterator{x4c_chainHeads[size_t(chain)]}; } + [[nodiscard]] auto GetChainHead(EChain chain) const { + return CGameArea::CConstChainIterator{x4c_chainHeads[size_t(chain)]}; + } + [[nodiscard]] auto begin() { return GetChainHead(EChain::Alive); } + [[nodiscard]] auto end() { return AliveAreasEnd(); } + [[nodiscard]] auto begin() const { return GetChainHead(EChain::Alive); } + [[nodiscard]] auto end() const { return GetAliveAreasEnd(); } + bool ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr); - void TravelToArea(TAreaId aid, CStateManager& mgr, bool); + void TravelToArea(TAreaId aid, CStateManager& mgr, bool skipLoadOther); void SetLoadPauseState(bool paused); void CycleLoadPauseState(); @@ -174,7 +177,9 @@ public: bool DoesAreaExist(TAreaId area) const; const std::vector>& GetGameAreas() const { return x18_areas; } + CMapWorld* GetMapWorld() { return x28_mapWorld.GetObj(); } const CMapWorld* GetMapWorld() const { return x28_mapWorld.GetObj(); } + u32 GetRelayCount() const { return x2c_relays.size(); } CRelay GetRelay(u32 idx) const { return x2c_relays[idx]; } @@ -182,8 +187,8 @@ public: CAssetId IGetStringTableAssetId() const override; CAssetId IGetSaveWorldAssetId() const override; const CMapWorld* IGetMapWorld() const override; - CMapWorld* IMapWorld() override; - const CGameArea* GetAreaAlways(TAreaId) const; + CMapWorld* IGetMapWorld() override; + const CGameArea* GetAreaAlways(TAreaId id) const; CGameArea* GetArea(TAreaId); s32 GetNumAreas() const { return x18_areas.size(); } const IGameArea* IGetAreaAlways(TAreaId id) const override; @@ -194,9 +199,9 @@ public: std::string IGetDefaultAudioTrack() const override; int IGetAreaCount() const override; - static void PropogateAreaChain(CGameArea::EOcclusionState, CGameArea*, CWorld*); - static CGameArea::CConstChainIterator GetAliveAreasEnd() { return {skGlobalEnd}; } - static CGameArea::CChainIterator AliveAreasEnd() { return {skGlobalNonConstEnd}; } + static void PropogateAreaChain(CGameArea::EOcclusionState occlusionState, CGameArea* area, CWorld* world); + static constexpr CGameArea::CConstChainIterator GetAliveAreasEnd() { return CGameArea::CConstChainIterator{}; } + static constexpr CGameArea::CChainIterator AliveAreasEnd() { return CGameArea::CChainIterator{}; } void Update(float dt); void PreRender(); diff --git a/Runtime/World/CWorldLight.hpp b/Runtime/World/CWorldLight.hpp index eccf6ffab..4302617c2 100644 --- a/Runtime/World/CWorldLight.hpp +++ b/Runtime/World/CWorldLight.hpp @@ -29,8 +29,14 @@ private: float x40_ = 0.f; public: + explicit CWorldLight(CInputStream& in); + CWorldLight(const CWorldLight&) = default; - CWorldLight(CInputStream& in); + CWorldLight& operator=(const CWorldLight&) = default; + + CWorldLight(CWorldLight&&) = default; + CWorldLight& operator=(CWorldLight&&) = default; + EWorldLightType GetLightType() const { return x0_type; } const zeus::CVector3f& GetDirection() const { return x1c_direction; } const zeus::CVector3f& GetPosition() const { return x10_position; } diff --git a/Runtime/World/CWorldTransManager.cpp b/Runtime/World/CWorldTransManager.cpp index 68127594a..067978fe8 100644 --- a/Runtime/World/CWorldTransManager.cpp +++ b/Runtime/World/CWorldTransManager.cpp @@ -44,11 +44,12 @@ CWorldTransManager::SModelDatas::SModelDatas(const CAnimRes& samusRes) : x0_samu } void CWorldTransManager::UpdateLights(float dt) { - if (!x4_modelData) + if (!x4_modelData) { return; + } x4_modelData->x1a0_lights.clear(); - zeus::CVector3f lightPos(0.f, 10.f, 0.f); + constexpr zeus::CVector3f lightPos(0.f, 10.f, 0.f); CLight spot = CLight::BuildSpot(lightPos, zeus::skBack, zeus::skWhite, 90.f); spot.SetAttenuation(1.f, 0.f, 0.f); @@ -349,7 +350,7 @@ void CWorldTransManager::TouchModels() { if (x4_modelData->x68_beamModelData.IsNull() && x4_modelData->x14c_beamModel.IsLoaded() && x4_modelData->x14c_beamModel.GetObj()) { - x4_modelData->x68_beamModelData = { + x4_modelData->x68_beamModelData = CModelData{ CStaticRes(x4_modelData->x14c_beamModel.GetObjectTag()->id, x4_modelData->x0_samusRes.GetScale()), 2}; } @@ -358,7 +359,7 @@ void CWorldTransManager::TouchModels() { x4_modelData->x164_suitSkin.GetObj()) { CAnimRes animRes(x4_modelData->x0_samusRes.GetId(), GetSuitCharIdx(), x4_modelData->x0_samusRes.GetScale(), x4_modelData->x0_samusRes.GetDefaultAnim(), true); - x4_modelData->x1c_samusModelData = {animRes, 2}; + x4_modelData->x1c_samusModelData = CModelData{animRes, 2}; CAnimPlaybackParms aData(animRes.GetDefaultAnim(), -1, 1.f, true); x4_modelData->x1c_samusModelData.GetAnimationData()->SetAnimation(aData, false); @@ -408,22 +409,23 @@ void CWorldTransManager::EnableTransition(const CAnimRes& samusRes, CAssetId pla x4_modelData->x164_suitSkin = g_SimplePool->GetObj(SObjectTag{FOURCC('CSKR'), info.GetSkinRulesId()}); if (platRes.IsValid()) { - x4_modelData->xb4_platformModelData = {CStaticRes(platRes, platScale), 2}; + x4_modelData->xb4_platformModelData = CModelData{CStaticRes(platRes, platScale), 2}; x4_modelData->xb4_platformModelData.Touch(CModelData::EWhichModel::Normal, 0); } if (bgRes.IsValid()) { - CStaticRes bg(bgRes, bgScale); - x4_modelData->x100_bgModelData[0] = bg; + const CStaticRes bg(bgRes, bgScale); + x4_modelData->x100_bgModelData[0] = CModelData{bg}; x4_modelData->x100_bgModelData[0].Touch(CModelData::EWhichModel::Normal, 0); - x4_modelData->x100_bgModelData[1] = bg; + x4_modelData->x100_bgModelData[1] = CModelData{bg}; x4_modelData->x100_bgModelData[1].Touch(CModelData::EWhichModel::Normal, 0); - x4_modelData->x100_bgModelData[2] = bg; + x4_modelData->x100_bgModelData[2] = CModelData{bg}; x4_modelData->x100_bgModelData[2].Touch(CModelData::EWhichModel::Normal, 0); - zeus::CAABox bounds = x4_modelData->x100_bgModelData[0].GetBounds(); + const zeus::CAABox bounds = x4_modelData->x100_bgModelData[0].GetBounds(); x1c_bgHeight = (bounds.max.z() - bounds.min.z()) * bgScale.z(); - } else + } else { x1c_bgHeight = 0.f; + } StartTransition(); TouchModels(); diff --git a/Runtime/World/CWorldTransManager.hpp b/Runtime/World/CWorldTransManager.hpp index 5cc678eff..978d0f447 100644 --- a/Runtime/World/CWorldTransManager.hpp +++ b/Runtime/World/CWorldTransManager.hpp @@ -48,7 +48,7 @@ public: float x1d8_transCompleteTime = 99999.f; bool x1dc_dissolveStarted = false; - SModelDatas(const CAnimRes& samusRes); + explicit SModelDatas(const CAnimRes& samusRes); }; private: @@ -80,9 +80,9 @@ private: u8 dummy = 0; }; - CColoredQuadFilter m_fadeToBlack = {EFilterType::Blend}; - CTexturedQuadFilter m_dissolve = {EFilterType::Blend, CGraphics::g_SpareTexture.get()}; - CWideScreenFilter m_widescreen = {EFilterType::Blend}; + CColoredQuadFilter m_fadeToBlack{EFilterType::Blend}; + CTexturedQuadFilter m_dissolve{EFilterType::Blend, CGraphics::g_SpareTexture.get()}; + CWideScreenFilter m_widescreen{EFilterType::Blend}; CCameraBlurFilter m_camblur; boo::ObjToken m_reflectionCube[2]; diff --git a/Runtime/World/IGameArea.hpp b/Runtime/World/IGameArea.hpp index 2a4cce25a..9eb2c870b 100644 --- a/Runtime/World/IGameArea.hpp +++ b/Runtime/World/IGameArea.hpp @@ -58,6 +58,13 @@ public: virtual const zeus::CTransform& IGetTM() const = 0; }; -enum class EChain { Invalid = -1, ToDeallocate, Deallocated, Loading, Alive, AliveJudgement }; +enum class EChain { + Invalid = -1, + ToDeallocate, + Deallocated, + Loading, + Alive, + AliveJudgement, +}; } // namespace urde diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index 09244251f..1f2ad0087 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -31,6 +31,7 @@ #include "Runtime/MP1/World/CMetroidBeta.hpp" #include "Runtime/MP1/World/CMetroidPrimeRelay.hpp" #include "Runtime/MP1/World/CNewIntroBoss.hpp" +#include "Runtime/MP1/World/COmegaPirate.hpp" #include "Runtime/MP1/World/CParasite.hpp" #include "Runtime/MP1/World/CPuddleSpore.hpp" #include "Runtime/MP1/World/CPuddleToadGamma.hpp" @@ -127,6 +128,8 @@ static logvisor::Module Log("urde::ScriptLoader"); constexpr SObjectTag MorphballDoorANCS = {FOURCC('ANCS'), 0x1F9DA858}; +constexpr int skElitePiratePropCount = 41; + static bool EnsurePropertyCount(int count, int expected, const char* structName) { if (count < expected) { Log.report(logvisor::Warning, fmt("Insufficient number of props ({}/{}) for {} entity"), count, expected, @@ -434,10 +437,12 @@ CEntity* ScriptLoader::LoadActor(CStateManager& mgr, CInputStream& in, int propC list.Add(EMaterialTypes::CameraPassthrough); CModelData data; - if (animType == SBIG('ANCS')) - data = CAnimRes(aParms.GetACSFile(), aParms.GetCharacter(), head.x40_scale, aParms.GetInitialAnimation(), false); - else - data = CStaticRes(staticId, head.x40_scale); + if (animType == SBIG('ANCS')) { + data = CModelData{ + CAnimRes(aParms.GetACSFile(), aParms.GetCharacter(), head.x40_scale, aParms.GetInitialAnimation(), false)}; + } else { + data = CModelData{CStaticRes(staticId, head.x40_scale)}; + } if ((collisionExtent.x() < 0.f || collisionExtent.y() < 0.f || collisionExtent.z() < 0.f) || collisionExtent.isZero()) aabb = data.GetBounds(head.x10_transform.getRotation()); @@ -494,7 +499,7 @@ CEntity* ScriptLoader::LoadDoor(CStateManager& mgr, CInputStream& in, int propCo if (!g_ResFactory->GetResourceTypeById(aParms.GetACSFile()).IsValid()) return nullptr; - CModelData mData = CAnimRes(aParms.GetACSFile(), aParms.GetCharacter(), head.x40_scale, 0, false); + CModelData mData{CAnimRes(aParms.GetACSFile(), aParms.GetCharacter(), head.x40_scale, 0, false)}; if (collisionExtent.isZero()) aabb = mData.GetBounds(head.x10_transform.getRotation()); @@ -654,10 +659,12 @@ CEntity* ScriptLoader::LoadPlatform(CStateManager& mgr, CInputStream& in, int pr } CModelData data; - if (animType == SBIG('ANCS')) - data = CAnimRes(aParms.GetACSFile(), aParms.GetCharacter(), head.x40_scale, aParms.GetInitialAnimation(), true); - else - data = CStaticRes(staticId, head.x40_scale); + if (animType == SBIG('ANCS')) { + data = CModelData{ + CAnimRes(aParms.GetACSFile(), aParms.GetCharacter(), head.x40_scale, aParms.GetInitialAnimation(), true)}; + } else { + data = CModelData{CStaticRes(staticId, head.x40_scale)}; + } if (extent.isZero()) aabb = data.GetBounds(head.x10_transform.getRotation()); @@ -813,9 +820,9 @@ CEntity* ScriptLoader::LoadNewIntroBoss(CStateManager& mgr, CInputStream& in, in CAnimRes res(aParms.GetACSFile(), aParms.GetCharacter(), head.x40_scale, aParms.GetInitialAnimation(), true); - return new MP1::CNewIntroBoss(mgr.AllocateUniqueId(), head.x0_name, info, head.x10_transform, res, pInfo, actParms, - minTurnAngle, projectile, dInfo, beamContactFxId, beamPulseFxId, beamTextureId, - beamGlowTextureId); + return new MP1::CNewIntroBoss(mgr.AllocateUniqueId(), head.x0_name, info, head.x10_transform, CModelData{res}, pInfo, + actParms, minTurnAngle, projectile, dInfo, beamContactFxId, beamPulseFxId, + beamTextureId, beamGlowTextureId); } CEntity* ScriptLoader::LoadSpawnPoint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { @@ -831,7 +838,7 @@ CEntity* ScriptLoader::LoadSpawnPoint(CStateManager& mgr, CInputStream& in, int rotation.readBig(in); rstl::reserved_vector itemCounts; - itemCounts.resize(size_t(CPlayerState::EItemType::Max)); + itemCounts.resize(size_t(CPlayerState::EItemType::Max), 0); for (int i = 0; i < propCount - 6; ++i) itemCounts[i] = in.readUint32Big(); @@ -921,14 +928,16 @@ CEntity* ScriptLoader::LoadPickup(CStateManager& mgr, CInputStream& in, int prop CModelData data; - if (acsType == SBIG('ANCS')) - data = CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), head.x40_scale, animParms.GetInitialAnimation(), - true); - else - data = CStaticRes(staticModel, head.x40_scale); + if (acsType == SBIG('ANCS')) { + data = CModelData{CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), head.x40_scale, + animParms.GetInitialAnimation(), true)}; + } else { + data = CModelData{CStaticRes(staticModel, head.x40_scale)}; + } - if (extent.isZero()) + if (extent.isZero()) { aabb = data.GetBounds(head.x10_transform.getRotation()); + } return new CScriptPickup(mgr.AllocateUniqueId(), head.x0_name, info, head.x10_transform, std::move(data), actorParms, aabb, itemType, amount, capacity, pickupEffect, possibility, lifeTime, fadeInTime, @@ -1007,21 +1016,24 @@ CEntity* ScriptLoader::LoadBeetle(CStateManager& mgr, CInputStream& in, int prop const CAnimationParameters& animParams = pInfo.GetAnimationParameters(); CAnimRes animRes(animParams.GetACSFile(), animParams.GetCharacter(), scale, animParams.GetInitialAnimation(), true); - return new MP1::CBeetle(mgr.AllocateUniqueId(), name, info, xfrm, animRes, pInfo, flavor, entranceType, touchDamage, - platingVuln, tailAimReference, initialAttackDelay, retreatTime, unused, tailVuln, aParams, - tailRes); + return new MP1::CBeetle(mgr.AllocateUniqueId(), name, info, xfrm, CModelData{animRes}, pInfo, flavor, entranceType, + touchDamage, platingVuln, tailAimReference, initialAttackDelay, retreatTime, unused, tailVuln, + aParams, tailRes); } CEntity* ScriptLoader::LoadHUDMemo(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - if (propCount != 5 && !EnsurePropertyCount(propCount, 6, "HUDMemo")) - return 0; - std::string name = mgr.HashInstanceName(in); - CHUDMemoParms hParms(in); - CScriptHUDMemo::EDisplayType displayType = CScriptHUDMemo::EDisplayType::MessageBox; - if (propCount == 6) + if (propCount != 5 && !EnsurePropertyCount(propCount, 6, "HUDMemo")) { + return nullptr; + } + + const std::string name = mgr.HashInstanceName(in); + const CHUDMemoParms hParms(in); + auto displayType = CScriptHUDMemo::EDisplayType::MessageBox; + if (propCount == 6) { displayType = CScriptHUDMemo::EDisplayType(in.readUint32Big()); - CAssetId message = in.readUint32Big(); - bool active = in.readBool(); + } + const CAssetId message = in.readUint32Big(); + const bool active = in.readBool(); return new CScriptHUDMemo(mgr.AllocateUniqueId(), name, info, hParms, displayType, message, active); } @@ -1125,28 +1137,30 @@ CEntity* ScriptLoader::LoadDebris(CStateManager& mgr, CInputStream& in, int prop if (!EnsurePropertyCount(propCount, 18, "Debris")) return nullptr; - SScaledActorHead head = LoadScaledActorHead(in, mgr); - float zImpulse = in.readFloatBig(); - zeus::CVector3f velocity = zeus::CVector3f::ReadBig(in); + const SScaledActorHead head = LoadScaledActorHead(in, mgr); + const float zImpulse = in.readFloatBig(); + const 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 randomAngImpulse = in.readBool(); - CAssetId model = in.readUint32Big(); - CActorParameters aParams = LoadActorParameters(in); - CAssetId particleId = in.readUint32Big(); - zeus::CVector3f particleScale = zeus::CVector3f::ReadBig(in); - bool b1 = in.readBool(); - bool active = in.readBool(); + const float mass = in.readFloatBig(); + const float restitution = in.readFloatBig(); + const float duration = in.readFloatBig(); + const auto scaleType = CScriptDebris::EScaleType(in.readUint32Big()); + const bool randomAngImpulse = in.readBool(); + const CAssetId model = in.readUint32Big(); + const CActorParameters aParams = LoadActorParameters(in); + const CAssetId particleId = in.readUint32Big(); + const zeus::CVector3f particleScale = zeus::CVector3f::ReadBig(in); + const bool b1 = in.readBool(); + const bool active = in.readBool(); - if (!g_ResFactory->GetResourceTypeById(model).IsValid()) + if (!g_ResFactory->GetResourceTypeById(model).IsValid()) { 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); + CModelData{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) { @@ -1365,7 +1379,7 @@ CEntity* ScriptLoader::LoadFlyingPirate(CStateManager& mgr, CInputStream& in, in SScaledActorHead actHead = LoadScaledActorHead(in, mgr); auto pair = CPatternedInfo::HasCorrectParameterCount(in); - if (pair.first) + if (!pair.first) return nullptr; CPatternedInfo pInfo(in, pair.second); @@ -1383,7 +1397,7 @@ CEntity* ScriptLoader::LoadFlyingPirate(CStateManager& mgr, CInputStream& in, in } CEntity* ScriptLoader::LoadElitePirate(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - if (!EnsurePropertyCount(propCount, 41, "ElitePirate")) + if (!EnsurePropertyCount(propCount, skElitePiratePropCount, "ElitePirate")) return nullptr; SScaledActorHead actHead = LoadScaledActorHead(in, mgr); @@ -2339,25 +2353,30 @@ CEntity* ScriptLoader::LoadFishCloudModifier(CStateManager& mgr, CInputStream& i } CEntity* ScriptLoader::LoadVisorFlare(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - if (!EnsurePropertyCount(propCount, 14, "VisorFlare")) + if (!EnsurePropertyCount(propCount, 14, "VisorFlare")) { return nullptr; + } + + const std::string name = mgr.HashInstanceName(in); + const zeus::CVector3f pos = zeus::CVector3f::ReadBig(in); + const bool b1 = in.readBool(); + const auto w1 = CVisorFlare::EBlendMode(in.readUint32Big()); + const bool b2 = in.readBool(); + const float f1 = in.readFloatBig(); + const float f2 = in.readFloatBig(); + const float f3 = in.readFloatBig(); + const u32 w2 = in.readUint32Big(); - std::string name = mgr.HashInstanceName(in); - zeus::CVector3f pos = zeus::CVector3f::ReadBig(in); - bool b1 = in.readBool(); - CVisorFlare::EBlendMode w1 = CVisorFlare::EBlendMode(in.readUint32Big()); - bool b2 = in.readBool(); - float f1 = in.readFloatBig(); - float f2 = in.readFloatBig(); - float f3 = in.readFloatBig(); - u32 w2 = in.readUint32Big(); std::vector flares; flares.reserve(5); - for (int i = 0; i < 5; ++i) - if (auto flare = CVisorFlare::LoadFlareDef(in)) + for (size_t i = 0; i < flares.capacity(); ++i) { + if (auto flare = CVisorFlare::LoadFlareDef(in)) { flares.push_back(*flare); + } + } - return new CScriptVisorFlare(mgr.AllocateUniqueId(), name, info, b1, pos, w1, b2, f1, f2, f3, 2, w2, flares); + return new CScriptVisorFlare(mgr.AllocateUniqueId(), name, info, b1, pos, w1, b2, f1, f2, f3, 2, w2, + std::move(flares)); } CEntity* ScriptLoader::LoadWorldTeleporter(CStateManager& mgr, CInputStream& in, int propCount, @@ -3622,7 +3641,33 @@ CEntity* ScriptLoader::LoadMazeNode(CStateManager& mgr, CInputStream& in, int pr } CEntity* ScriptLoader::LoadOmegaPirate(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { + if (!EnsurePropertyCount(propCount, skElitePiratePropCount + 1, "OmegaPirate")) { + return nullptr; + } + +#if 0 + SScaledActorHead actHead = LoadScaledActorHead(in, mgr); + auto pair = CPatternedInfo::HasCorrectParameterCount(in); + if (!pair.first) { + return nullptr; + } + + CPatternedInfo pInfo(in, pair.second); + CActorParameters actParms = LoadActorParameters(in); + MP1::CElitePirateData elitePirateData(in, propCount); + + if (!pInfo.GetAnimationParameters().GetACSFile().IsValid()) { + return nullptr; + } + + CModelData mData(CAnimRes(pInfo.GetAnimationParameters().GetACSFile(), pInfo.GetAnimationParameters().GetCharacter(), + actHead.x40_scale, pInfo.GetAnimationParameters().GetInitialAnimation(), true)); + + return new MP1::COmegaPirate(mgr.AllocateUniqueId(), actHead.x0_name, info, actHead.x10_transform, std::move(mData), + pInfo, actParms, elitePirateData, CAssetId(in), CAssetId(in), CAssetId(in)); +#else return nullptr; +#endif } CEntity* ScriptLoader::LoadPhazonPool(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { diff --git a/Runtime/World/ScriptLoader.hpp b/Runtime/World/ScriptLoader.hpp index e0a84d55e..86d6cea48 100644 --- a/Runtime/World/ScriptLoader.hpp +++ b/Runtime/World/ScriptLoader.hpp @@ -18,7 +18,7 @@ class CScannableParameters; class CStateManager; class CVisorParameters; -typedef CEntity* (*FScriptLoader)(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info); +using FScriptLoader = CEntity* (*)(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info); class ScriptLoader { public: diff --git a/Runtime/rstl.hpp b/Runtime/rstl.hpp index c7f6135f1..eaf42903e 100644 --- a/Runtime/rstl.hpp +++ b/Runtime/rstl.hpp @@ -522,32 +522,36 @@ public: x0_size = 0; } - size_t size() const noexcept { return x0_size; } - bool empty() const noexcept { return x0_size == 0; } - constexpr size_t capacity() const noexcept { return N; } - const T* data() const noexcept { return std::addressof(_value(0)); } - T* data() noexcept { return std::addressof(_value(0)); } + [[nodiscard]] size_t size() const noexcept { return x0_size; } + [[nodiscard]] bool empty() const noexcept { return x0_size == 0; } + [[nodiscard]] constexpr size_t capacity() const noexcept { return N; } + [[nodiscard]] const T* data() const noexcept { return std::addressof(_value(0)); } + [[nodiscard]] T* data() noexcept { return std::addressof(_value(0)); } - T& back() { return _value(x0_size - 1); } - T& front() { return _value(0); } - const T& back() const { return _value(x0_size - 1); } - const T& front() const { return _value(0); } + [[nodiscard]] T& back() { return _value(x0_size - 1); } + [[nodiscard]] T& front() { return _value(0); } + [[nodiscard]] const T& back() const { return _value(x0_size - 1); } + [[nodiscard]] const T& front() const { return _value(0); } - const_iterator begin() const noexcept { return const_iterator(std::addressof(_value(0))); } - const_iterator end() const noexcept { return const_iterator(std::addressof(_value(x0_size))); } - iterator begin() noexcept { return iterator(std::addressof(_value(0))); } - iterator end() noexcept { return iterator(std::addressof(_value(x0_size))); } - const_iterator cbegin() const noexcept { return begin(); } - const_iterator cend() const noexcept { return end(); } + [[nodiscard]] const_iterator begin() const noexcept { return const_iterator(std::addressof(_value(0))); } + [[nodiscard]] const_iterator end() const noexcept { return const_iterator(std::addressof(_value(x0_size))); } + [[nodiscard]] iterator begin() noexcept { return iterator(std::addressof(_value(0))); } + [[nodiscard]] iterator end() noexcept { return iterator(std::addressof(_value(x0_size))); } + [[nodiscard]] const_iterator cbegin() const noexcept { return begin(); } + [[nodiscard]] const_iterator cend() const noexcept { return end(); } - const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(std::addressof(_value(x0_size - 1))); } - const_reverse_iterator rend() const noexcept { return const_reverse_iterator(std::addressof(_value(-1))); } - reverse_iterator rbegin() noexcept { return reverse_iterator(std::addressof(_value(x0_size - 1))); } - reverse_iterator rend() noexcept { return reverse_iterator(std::addressof(_value(-1))); } - const_reverse_iterator crbegin() const noexcept { return rbegin(); } - const_reverse_iterator crend() const noexcept { return rend(); } + [[nodiscard]] const_reverse_iterator rbegin() const noexcept { + return const_reverse_iterator(std::addressof(_value(x0_size - 1))); + } + [[nodiscard]] const_reverse_iterator rend() const noexcept { + return const_reverse_iterator(std::addressof(_value(-1))); + } + [[nodiscard]] reverse_iterator rbegin() noexcept { return reverse_iterator(std::addressof(_value(x0_size - 1))); } + [[nodiscard]] reverse_iterator rend() noexcept { return reverse_iterator(std::addressof(_value(-1))); } + [[nodiscard]] const_reverse_iterator crbegin() const noexcept { return rbegin(); } + [[nodiscard]] const_reverse_iterator crend() const noexcept { return rend(); } - T& operator[](size_t idx) { + [[nodiscard]] T& operator[](size_t idx) { #ifndef NDEBUG if (idx >= x0_size) { Log.report(logvisor::Fatal, fmt("out of bounds access on reserved_vector.")); @@ -555,7 +559,7 @@ public: #endif return _value(idx); } - const T& operator[](size_t idx) const { + [[nodiscard]] const T& operator[](size_t idx) const { #ifndef NDEBUG if (idx >= x0_size) { Log.report(logvisor::Fatal, fmt("out of bounds access on reserved_vector.")); @@ -587,32 +591,36 @@ public: void set_size(size_t n) { x0_size = n; } void set_data(T* data) { x4_data = data; } - size_t size() const noexcept { return x0_size; } - bool empty() const noexcept { return x0_size == 0; } - const T* data() const noexcept { return x4_data; } - T* data() noexcept { return x4_data; } + [[nodiscard]] size_t size() const noexcept { return x0_size; } + [[nodiscard]] bool empty() const noexcept { return x0_size == 0; } + [[nodiscard]] const T* data() const noexcept { return x4_data; } + [[nodiscard]] T* data() noexcept { return x4_data; } - T& back() { return _value(x0_size - 1); } - T& front() { return _value(0); } - const T& back() const { return _value(x0_size - 1); } - const T& front() const { return _value(0); } + [[nodiscard]] T& back() { return _value(x0_size - 1); } + [[nodiscard]] T& front() { return _value(0); } + [[nodiscard]] const T& back() const { return _value(x0_size - 1); } + [[nodiscard]] const T& front() const { return _value(0); } - const_iterator begin() const noexcept { return const_iterator(std::addressof(_value(0))); } - const_iterator end() const noexcept { return const_iterator(std::addressof(_value(x0_size))); } - iterator begin() noexcept { return iterator(std::addressof(_value(0))); } - iterator end() noexcept { return iterator(std::addressof(_value(x0_size))); } - const_iterator cbegin() const noexcept { return begin(); } - const_iterator cend() const noexcept { return end(); } + [[nodiscard]] const_iterator begin() const noexcept { return const_iterator(std::addressof(_value(0))); } + [[nodiscard]] const_iterator end() const noexcept { return const_iterator(std::addressof(_value(x0_size))); } + [[nodiscard]] iterator begin() noexcept { return iterator(std::addressof(_value(0))); } + [[nodiscard]] iterator end() noexcept { return iterator(std::addressof(_value(x0_size))); } + [[nodiscard]] const_iterator cbegin() const noexcept { return begin(); } + [[nodiscard]] const_iterator cend() const noexcept { return end(); } - const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(std::addressof(_value(x0_size - 1))); } - const_reverse_iterator rend() const noexcept { return const_reverse_iterator(std::addressof(_value(-1))); } - reverse_iterator rbegin() noexcept { return reverse_iterator(std::addressof(_value(x0_size - 1))); } - reverse_iterator rend() noexcept { return reverse_iterator(std::addressof(_value(-1))); } - const_reverse_iterator crbegin() const noexcept { return rbegin(); } - const_reverse_iterator crend() const noexcept { return rend(); } + [[nodiscard]] const_reverse_iterator rbegin() const noexcept { + return const_reverse_iterator(std::addressof(_value(x0_size - 1))); + } + [[nodiscard]] const_reverse_iterator rend() const noexcept { + return const_reverse_iterator(std::addressof(_value(-1))); + } + [[nodiscard]] reverse_iterator rbegin() noexcept { return reverse_iterator(std::addressof(_value(x0_size - 1))); } + [[nodiscard]] reverse_iterator rend() noexcept { return reverse_iterator(std::addressof(_value(-1))); } + [[nodiscard]] const_reverse_iterator crbegin() const noexcept { return rbegin(); } + [[nodiscard]] const_reverse_iterator crend() const noexcept { return rend(); } - T& operator[](size_t idx) { return _value(idx); } - const T& operator[](size_t idx) const { return _value(idx); } + [[nodiscard]] T& operator[](size_t idx) { return _value(idx); } + [[nodiscard]] const T& operator[](size_t idx) const { return _value(idx); } }; template