Files
combattest/CharacterManager.cpp
T
2026-11-08 07:45:01 -05:00

138 lines
4.8 KiB
C++

#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<Rig>(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<Animation>(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>();
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>();
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);
}
}