138 lines
4.8 KiB
C++
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);
|
|
}
|
|
}
|