122 lines
3.9 KiB
C++
122 lines
3.9 KiB
C++
#include "CharacterManager.h"
|
|
#include "Animator.h"
|
|
#include "Character.h"
|
|
#include "Physics.h"
|
|
#include "Rig.h"
|
|
#include "tFunctions.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;
|
|
}
|
|
|
|
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::SetControlledCharacter(const std::string& name) {
|
|
controlledCharacter = GetCharacter(name);
|
|
}
|
|
|
|
void CharacterManager::PressInput(char letter) {
|
|
if (controlledCharacter)
|
|
controlledCharacter->PressInput(letter);
|
|
}
|
|
|
|
void CharacterManager::ReleaseInput(char letter) {
|
|
if (controlledCharacter)
|
|
controlledCharacter->ReleaseInput(letter);
|
|
}
|
|
|
|
void CharacterManager::ClearInput() {
|
|
if (controlledCharacter)
|
|
controlledCharacter->ClearInput();
|
|
}
|
|
|
|
void CharacterManager::Step(float dt) {
|
|
for (Character* character : characterOrder)
|
|
character->Step(dt);
|
|
}
|
|
|
|
void CharacterManager::ResolveCombat(Physics& physics) {
|
|
for (Character* attacker : characterOrder) {
|
|
Hitbox& hitbox = attacker->punchHitbox;
|
|
if (!hitbox.active || hitbox.damage <= 0)
|
|
continue;
|
|
|
|
for (Character* target : characterOrder) {
|
|
if (target == attacker || !hitbox.CanHit(target))
|
|
continue;
|
|
|
|
if (!BoundingBoxInBoundingBox(hitbox.transform.GetAABB(), target->body->t.GetAABB()))
|
|
continue;
|
|
|
|
hitbox.RegisterHit(target);
|
|
target->body->Health = std::max(0, target->body->Health - hitbox.damage);
|
|
|
|
glm::vec3 knockback = target->body->t.GetTranslation() -
|
|
attacker->body->t.GetTranslation();
|
|
knockback.y = 0.0f;
|
|
if (glm::length(knockback) > 0.0001f)
|
|
knockback = glm::normalize(knockback) * hitbox.knockback;
|
|
knockback.y = 1.5f;
|
|
if (p* targetBody = physics.PPointerOfObject(target->body)) {
|
|
targetBody->linearvelocity += knockback;
|
|
targetBody->WakeUp();
|
|
}
|
|
}
|
|
}
|
|
}
|