Files
DNF_DEV/source_game/Asset/Character/Chr_Animation.cpp
2026-02-08 16:20:50 +08:00

115 lines
4.1 KiB
C++

#include "Chr_Animation.h"
#include "Global/Global_Game.h"
#include "Actor/Object/CharacterObject.h"
#include "Asset/Character/Chr_Equipment.h"
std::string Chr_Animation::FormatImgPath(std::string ImgPath, Animation::ReplaceData data)
{
size_t pos = ImgPath.find("%04d");
if (pos != std::string::npos)
{
ImgPath.replace(pos, 4, "%02d%02d");
}
char buffer[256];
snprintf(buffer, sizeof(buffer), ImgPath.c_str(), data.Param1, data.Param2);
std::string newPath = buffer;
return newPath;
}
void Chr_Animation::CreateSkinmationBySlot(std::string actionName, std::string slotName, std::string path)
{
// 皮肤在没有穿戴的情况下 格式化参数为0
if (slotName == "skin_avatar")
{
// 如果穿戴了皮肤时装 读取variation
RefPtr<Equipment> Equip = ((CharacterObject *)GetParent())->_EquipmentManager->GetEquip(slotName);
if (Equip)
{
Animation::ReplaceData Data(0, 0);
for (auto &Variation : Equip->JobAni[this->chr_parent->Job])
{
Data.Param1 = Variation.ImgFormat[0];
Data.Param2 = Variation.ImgFormat[1];
// 构造Ani
RefPtr<Animation> Ani = new Animation(path, FormatImgPath, Data);
Ani->SetZOrder(Variation.Layer);
// 将构造好的Ani 添加进AniMap
ActionAnis[actionName]->AddAnimation(Ani);
// 构造一下阴影对象 //TODO
// RefPtr<Animation> ShadowAni = new Animation(path, FormatImgPath, Data);
// ShadowAni->SetVisible(false);
// chr_parent->_Shadow->AddChild(ShadowAni);
// chr_parent->_Shadow->ActionAnis[actionName].push_back(ShadowAni);
}
}
}
else
{
RefPtr<Equipment> Equip = ((CharacterObject *)GetParent())->_EquipmentManager->GetEquip(slotName);
if (Equip)
{
Animation::ReplaceData Data(0, 0);
for (auto &Variation : Equip->JobAni[this->chr_parent->Job])
{
Data.Param1 = Variation.ImgFormat[0];
Data.Param2 = Variation.ImgFormat[1];
// 读取装备路径
std::string EquipPath = Tool_TruncatePath(Equip->m_EquipmentPath);
// 组装动画路径
std::string AniPath = EquipPath + Variation.AnimationGroup + path.substr(path.find_last_of("/"), path.length());
// 构造Ani
RefPtr<Animation> Ani = new Animation(AniPath, FormatImgPath, Data);
Ani->SetZOrder(Variation.Layer);
// 将构造好的Ani 添加进AniMap
ActionAnis[actionName]->AddAnimation(Ani);
}
}
}
}
void Chr_Animation::Init(CharacterObject *parent)
{
parent->AddChild(this);
chr_parent = parent;
GlobalCharacterScript::CharacterConfig Config = Global_Game::GetInstance().CharacterConfigs[parent->Job];
// 遍历所有动作Ani路径
for (const auto &pair : Config.animationPath)
{
std::string ActionName = pair.first;
std::string Path = std::string("character/" + Config.jobTag + "/" + Tool_toLowerCase(pair.second));
//以动作为Key构造AniMap
ActionAnis[ActionName] = new AnimationMap();
ActionAnis[ActionName]->SetVisible(false);
// 遍历所有时装部位构造Ani
for (auto &AvatarPartPair : AvatarPart)
{
std::string AvatarPartName = AvatarPartPair.first;
CreateSkinmationBySlot(ActionName, AvatarPartName, Path);
}
// 将所有时装部位的Ani添加到动作AniMap以后完成构造
ActionAnis[ActionName]->CompleteConstruction();
this->AddChild(ActionAnis[ActionName]);
}
// 设置初始动作
SetAction("rest");
}
void Chr_Animation::SetAction(std::string actionName)
{
// 先将原动作的Ani设置为不可见
ActionAnis[CurrentActionTag]->Reset();
ActionAnis[CurrentActionTag]->SetVisible(false);
// 再将新动作的Ani设置为可见
ActionAnis[actionName]->SetVisible(true);
CurrentActionTag = actionName;
}