#ifndef _DNAMP3_CHAR_HPP_ #define _DNAMP3_CHAR_HPP_ #include #include "DataSpec/DNACommon/DNACommon.hpp" #include "DataSpec/DNACommon/ANCS.hpp" #include "CMDLMaterials.hpp" #include "CINF.hpp" #include "CSKR.hpp" #include "ANIM.hpp" #include "../DNAMP2/ANCS.hpp" namespace DataSpec::DNAMP3 { struct CHAR : BigDNA { using CINFType = CINF; using CSKRType = CSKR; using ANIMType = ANIM; AT_DECL_DNA_YAML Value version; struct CharacterInfo : BigDNA { AT_DECL_DNA_YAML String<-1> name; UniqueID64 cmdl; UniqueID64 cskr; Value overlayCount; struct Overlay : BigDNA { AT_DECL_DNA_YAML DNAFourCC type; UniqueID64 cmdl; UniqueID64 cskr; }; Vector overlays; UniqueID64 cinf; UniqueID64 sand; using MP1CharacterInfo = DNAMP1::ANCS::CharacterSet::CharacterInfo; MP1CharacterInfo::PASDatabase pasDatabase; struct ParticleResData : BigDNA { AT_DECL_DNA_YAML Value partCount; Vector part; Value swhcCount; Vector swhc; Value unkCount; Vector unk; Value elscCount; Vector elsc; Value spscCount; Vector spsc; Value unk2Count; Vector unk2; } partResData; } characterInfo; struct AnimationInfo : BigDNA { AT_DECL_DNA_YAML struct EVNT : BigDNA { AT_DECL_DNA_YAML Value eventIdx; String<-1> eventName; struct EventBase : BigDNA { AT_DECL_DNA_YAML String<-1> name1; Value unk0; String<-1> name2; Value type; Value unk1; Value unk2; Value unk3; Value unk4; Value unk5; Value unk6; Value unk7; Value unk8; Value unk9; Value unk10; Value unk11; Value unk12; Value unk13; }; struct EffectEvent : EventBase { AT_DECL_DNA_YAML DNAFourCC effectType; UniqueID64 effectId; Value scale; Value parentMode; }; Value effectCount; Vector effectEvents; struct SFXEvent : EventBase { AT_DECL_DNA_YAML Delete expl; UniqueID64 caudId; Value unk1_; Value unk2_; Value unk3_; std::vector unk3Vals; Value extraType; Value extraFloat; }; Value sfxCount; Vector sfxEvents; }; Value evntCount; Vector evnts; struct IMetaAnim : BigDNAVYaml { Delete expl; enum class Type { Primitive = 0, Blend = 1, PhaseBlend = 2, Random = 3, Sequence = 4 } m_type; const char* m_typeStr; IMetaAnim(Type type, const char* typeStr) : m_type(type), m_typeStr(typeStr) {} virtual void gatherPrimitives(std::map>& out)=0; }; struct MetaAnimFactory : BigDNA { AT_DECL_DNA_YAML Delete expl; std::unique_ptr m_anim; }; struct MetaAnimPrimitive : IMetaAnim { MetaAnimPrimitive() : IMetaAnim(Type::Primitive, "Primitive") {} AT_DECL_DNA_YAML AT_DECL_DNAV UniqueID64 animId; Value animIdx; String<-1> animName; Value unk1; Value unk2; void gatherPrimitives(std::map>& out) { out[animIdx] = {animName, animId, UniqueID64(), false}; } }; struct MetaAnimBlend : IMetaAnim { MetaAnimBlend() : IMetaAnim(Type::Blend, "Blend") {} AT_DECL_DNA_YAML AT_DECL_DNAV MetaAnimFactory animA; MetaAnimFactory animB; Value unkFloat; Value unk; void gatherPrimitives(std::map>& out) { animA.m_anim->gatherPrimitives(out); animB.m_anim->gatherPrimitives(out); } }; struct MetaAnimPhaseBlend : IMetaAnim { MetaAnimPhaseBlend() : IMetaAnim(Type::PhaseBlend, "PhaseBlend") {} AT_DECL_DNA_YAML AT_DECL_DNAV MetaAnimFactory animA; MetaAnimFactory animB; Value unkFloat; Value unk; void gatherPrimitives(std::map>& out) { animA.m_anim->gatherPrimitives(out); animB.m_anim->gatherPrimitives(out); } }; struct MetaAnimRandom : IMetaAnim { MetaAnimRandom() : IMetaAnim(Type::Random, "Random") {} AT_DECL_DNA_YAML AT_DECL_DNAV Value animCount; struct Child : BigDNA { AT_DECL_DNA_YAML MetaAnimFactory anim; Value probability; }; Vector children; void gatherPrimitives(std::map>& out) { for (const auto& child : children) child.anim.m_anim->gatherPrimitives(out); } }; struct MetaAnimSequence : IMetaAnim { MetaAnimSequence() : IMetaAnim(Type::Sequence, "Sequence") {} AT_DECL_DNA_YAML AT_DECL_DNAV Value animCount; Vector children; void gatherPrimitives(std::map>& out) { for (const auto& child : children) child.m_anim->gatherPrimitives(out); } }; struct Animation : BigDNA { AT_DECL_DNA_YAML String<-1> name; MetaAnimFactory metaAnim; }; Value animationCount; Vector animations; struct ActionAABB : BigDNA { AT_DECL_DNA_YAML UniqueID64 animId; Value aabb[2]; }; Value animAABBCount; Vector animAABBs; Value unkByte; Value additiveMapCount; Vector additiveMap; } animationInfo; struct HitboxSet : BigDNA { AT_DECL_DNA_YAML String<-1> name; Value hitboxCount; struct Hitbox : BigDNA { AT_DECL_DNA_YAML Value unk1; Value unk2; Value unk3; Value unk4; Value unk5; Value unk6; Value unk7; Value unk8; Value unk9; Value unk10; Value unk11; Value unk12; Value unk13; String<-1> boneName; Value unk14; }; Vector hitboxes; }; Value hitboxSetCount; Vector hitboxSets; void getCharacterResInfo(std::vector>& out) const { out.clear(); out.reserve(1); out.emplace_back(); DNAANCS::CharacterResInfo& chOut = out.back(); chOut.name = characterInfo.name; chOut.cmdl = characterInfo.cmdl; chOut.cskr = characterInfo.cskr; chOut.cinf = characterInfo.cinf; for (const CharacterInfo::Overlay& overlay : characterInfo.overlays) chOut.overlays.emplace_back(overlay.type, std::make_pair(overlay.cmdl, overlay.cskr)); } void getAnimationResInfo(PAKRouter* pakRouter, std::map>& out) const { out.clear(); for (const AnimationInfo::Animation& ai : animationInfo.animations) ai.metaAnim.m_anim->gatherPrimitives(out); for (auto& animRes : out) animRes.second.additive = animationInfo.additiveMap.at(animRes.first); } static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, std::function fileChanged) { hecl::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml"), true); hecl::ProjectPath::Type yamlType = yamlPath.getPathType(); hecl::ProjectPath blendPath = outPath.getWithExtension(_S(".blend"), true); hecl::ProjectPath::Type blendType = blendPath.getPathType(); if (force || yamlType == hecl::ProjectPath::Type::None || blendType == hecl::ProjectPath::Type::None) { CHAR aChar; aChar.read(rs); if (force || yamlType == hecl::ProjectPath::Type::None) { athena::io::FileWriter writer(yamlPath.getAbsolutePath()); athena::io::ToYAMLStream(aChar, writer); } if (force || blendType == hecl::ProjectPath::Type::None) { hecl::blender::Connection& conn = btok.getBlenderConnection(); DNAANCS::ReadANCSToBlender, CHAR, MaterialSet, DNACMDL::SurfaceHeader_3, 4> (conn, aChar, blendPath, pakRouter, entry, dataSpec, fileChanged, force); } } return true; } }; } #endif // _DNAMP3_CHAR_HPP_