#ifndef _DNAMP3_CHAR_HPP_ #define _DNAMP3_CHAR_HPP_ #include #include "../DNACommon/DNACommon.hpp" #include "../DNACommon/ANCS.hpp" #include "CMDLMaterials.hpp" #include "hecl/Blender/BlenderConnection.hpp" #include "CINF.hpp" #include "CSKR.hpp" #include "ANIM.hpp" #include "../DNAMP2/ANCS.hpp" namespace DataSpec { namespace DNAMP3 { struct CHAR : BigYAML { using CINFType = CINF; using CSKRType = CSKR; using ANIMType = ANIM; DECL_YAML Value version; struct CharacterInfo : BigYAML { DECL_YAML String<-1> name; UniqueID64 cmdl; UniqueID64 cskr; Value overlayCount; struct Overlay : BigYAML { DECL_YAML DNAFourCC type; UniqueID64 cmdl; UniqueID64 cskr; }; Vector overlays; UniqueID64 cinf; UniqueID64 sand; using MP1CharacterInfo = DNAMP1::ANCS::CharacterSet::CharacterInfo; MP1CharacterInfo::PASDatabase pasDatabase; struct ParticleResData : BigYAML { DECL_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 : BigYAML { DECL_YAML struct EVNT : BigYAML { DECL_YAML Value eventIdx; String<-1> eventName; struct EventBase : BigYAML { DECL_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 { DECL_YAML DNAFourCC effectType; UniqueID64 effectId; Value scale; Value parentMode; }; Value effectCount; Vector effectEvents; struct SFXEvent : EventBase { DECL_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 : BigYAML { Delete expl; virtual ~IMetaAnim() {} 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 : BigYAML { DECL_YAML Delete expl; std::unique_ptr m_anim; }; struct MetaAnimPrimitive : IMetaAnim { MetaAnimPrimitive() : IMetaAnim(Type::Primitive, "Primitive") {} DECL_YAML 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") {} DECL_YAML 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") {} DECL_YAML 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") {} DECL_YAML Value animCount; struct Child : BigYAML { DECL_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") {} DECL_YAML Value animCount; Vector children; void gatherPrimitives(std::map>& out) { for (const auto& child : children) child.m_anim->gatherPrimitives(out); } }; struct Animation : BigYAML { DECL_YAML String<-1> name; MetaAnimFactory metaAnim; }; Value animationCount; Vector animations; struct ActionAABB : BigYAML { DECL_YAML UniqueID64 animId; Value aabb[2]; }; Value animAABBCount; Vector animAABBs; Value unkByte; Value additiveMapCount; Vector additiveMap; } animationInfo; struct HitboxSet : BigYAML { DECL_YAML String<-1> name; Value hitboxCount; struct Hitbox : BigYAML { DECL_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(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::BlenderToken& 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()); aChar.toYAMLStream(writer); } if (force || blendType == hecl::ProjectPath::Type::None) { hecl::BlenderConnection& 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_