#include "CharacterManager.h" #include "Animator.h" #include "Character.h" #include "CharacterTemplate.h" #include "Rig.h" #include "Hitbox.h" CharacterManager::CharacterManager() = default; CharacterManager::~CharacterManager() = default; Rig* CharacterManager::LoadRig(const std::string& name, const std::string& path) { auto existing = rigs.find(name); if (existing != rigs.end()) return existing->second.get(); auto rig = std::make_unique(path); Rig* result = rig.get(); rigs.emplace(name, std::move(rig)); return result; } Animation* CharacterManager::LoadAnimation(const std::string& name, const std::string& path, const std::string& rigName) { auto existing = animations.find(name); if (existing != animations.end()) return existing->second.get(); auto animation = std::make_unique(path, GetRig(rigName)); Animation* result = animation.get(); animations.emplace(name, std::move(animation)); return result; } Character* CharacterManager::CreateCharacter(const std::string& name, const std::string& rigName, const std::string& animationName) { Character* existing = GetCharacter(name); if (existing) return existing; auto character = std::make_unique(); character->name = name; if (!rigName.empty()) character->body->SetRig(GetRig(rigName)); if (!animationName.empty()) character->body->SetAnimation(GetAnimation(animationName)); Character* result = character.get(); characters.emplace(name, std::move(character)); characterOrder.push_back(result); return result; } CharacterTemplate* CharacterManager::AddTemplate(const std::string& name) { if (CharacterTemplate* existing = GetTemplate(name)) return existing; auto characterTemplate = std::make_unique(); characterTemplate->name = name; CharacterTemplate* result = characterTemplate.get(); templates.emplace(name, std::move(characterTemplate)); templateOrder.push_back(result); return result; } CharacterTemplate* CharacterManager::GetTemplate(const std::string& name) const { auto it = templates.find(name); return it != templates.end() ? it->second.get() : nullptr; } Character* CharacterManager::CreateCharacterFromTemplate(const std::string& name, const std::string& templateName) { const CharacterTemplate* characterTemplate = GetTemplate(templateName); if (!characterTemplate) return nullptr; if (Character* existing = GetCharacter(name)) return existing; Character* character = CreateCharacter(name); character->ApplyTemplate(*characterTemplate); return character; } Rig* CharacterManager::GetRig(const std::string& name) const { auto it = rigs.find(name); return it != rigs.end() ? it->second.get() : nullptr; } Animation* CharacterManager::GetAnimation(const std::string& name) const { auto it = animations.find(name); return it != animations.end() ? it->second.get() : nullptr; } Character* CharacterManager::GetCharacter(const std::string& name) const { auto it = characters.find(name); return it != characters.end() ? it->second.get() : nullptr; } void CharacterManager::Think() { for (Character* character : characterOrder) character->Think(); } void CharacterManager::Step(float dt) { for (Character* character : characterOrder) character->Step(dt); } void CharacterManager::AddAttackHitboxes(HitboxSystem& hitboxes) { for (Character* attacker : characterOrder) { if (attacker->IsDead() || attacker->ragdoll) continue; const CharacterCombat& combat = attacker->body->combat; if (!combat.IsHitting()) continue; const AttackMove& move = *combat.GetCurrentMove(); // In front of it, turned the way it faces const glm::vec3 forward = attacker->GetForwardDirection(); const glm::vec3 up(0.0f, 1.0f, 0.0f); const glm::vec3 right = glm::normalize(glm::cross(forward, up)); const glm::vec3 position = attacker->body->t.GetTranslation() + right * move.hitboxOffset.x + up * move.hitboxOffset.y + forward * move.hitboxOffset.z; Hitbox hitbox; hitbox.owner = attacker; hitbox.swing = combat.GetSwingId(); hitbox.box.ScaleTo(move.hitboxSize); hitbox.box.RotateToQuaternion(attacker->body->t.GetRotationQuaternion()); hitbox.box.TranslateTo(position); hitbox.damage = move.damage; hitbox.knockback = move.knockback; hitbox.knockbackUp = move.knockbackUp; hitbox.stun = move.stun; hitbox.hitsKnockedDown = move.hitsKnockedDown; hitboxes.Add(hitbox); } }