90 lines
3.9 KiB
C++
90 lines
3.9 KiB
C++
#include "CharacterState.h"
|
|
|
|
namespace ZL {
|
|
|
|
bool CharacterState::isMoving() const {
|
|
Eigen::Vector3f toTarget = walkTarget - position;
|
|
toTarget.y() = 0.f;
|
|
return !pathWaypoints.empty() || toTarget.norm() > kWalkThreshold;
|
|
}
|
|
|
|
Eigen::Vector3f CharacterState::getCurrentNavigationTarget() const {
|
|
if (!pathWaypoints.empty() && currentWaypointIndex < pathWaypoints.size()) {
|
|
return pathWaypoints[currentWaypointIndex];
|
|
}
|
|
return walkTarget;
|
|
}
|
|
|
|
void CharacterState::stopInPlace() {
|
|
walkTarget = Eigen::Vector3f(position.x(), 0.f, position.z());
|
|
requestedWalkTarget = walkTarget;
|
|
pathWaypoints.clear();
|
|
currentWaypointIndex = 0;
|
|
onArrivedCallback = nullptr;
|
|
}
|
|
|
|
void CharacterState::setHp(float newHp) {
|
|
hp = newHp;
|
|
if (hp < 0.f) hp = 0.f;
|
|
if (onHpChanged) onHpChanged(hp, initialHp);
|
|
}
|
|
|
|
void CharacterState::save(nlohmann::json& out) const
|
|
{
|
|
out["position"] = { position.x(), position.y(), position.z() };
|
|
out["facingAngle"] = facingAngle;
|
|
out["targetFacingAngle"] = targetFacingAngle;
|
|
out["hp"] = hp;
|
|
out["enabled"] = enabled;
|
|
out["battle_state"] = battle_state;
|
|
out["currentState"] = static_cast<int>(currentState);
|
|
out["attack_cooldown"] = attack_cooldown;
|
|
out["showWeapon"] = showWeapon;
|
|
out["attackTargetIndex"] = attackTargetIndex;
|
|
out["faceTargetIndex"] = faceTargetIndex;
|
|
out["homePosition"] = { homePosition.x(), homePosition.y(), homePosition.z() };
|
|
out["walkTarget"] = { walkTarget.x(), walkTarget.y(), walkTarget.z() };
|
|
out["requestedWalkTarget"] = { requestedWalkTarget.x(), requestedWalkTarget.y(), requestedWalkTarget.z() };
|
|
nlohmann::json wpArr = nlohmann::json::array();
|
|
for (const auto& wp : pathWaypoints) {
|
|
wpArr.push_back({ wp.x(), wp.y(), wp.z() });
|
|
}
|
|
out["pathWaypoints"] = std::move(wpArr);
|
|
out["currentWaypointIndex"] = currentWaypointIndex;
|
|
out["homeDriftCheckTimer"] = homeDriftCheckTimer;
|
|
}
|
|
|
|
void CharacterState::load(const nlohmann::json& in)
|
|
{
|
|
auto readVec3 = [](const nlohmann::json& j, Eigen::Vector3f def) -> Eigen::Vector3f {
|
|
if (j.is_array() && j.size() == 3)
|
|
return { j[0].get<float>(), j[1].get<float>(), j[2].get<float>() };
|
|
return def;
|
|
};
|
|
|
|
if (in.contains("position")) position = readVec3(in["position"], position);
|
|
facingAngle = in.value("facingAngle", facingAngle);
|
|
targetFacingAngle = in.value("targetFacingAngle", targetFacingAngle);
|
|
hp = in.value("hp", hp);
|
|
enabled = in.value("enabled", enabled);
|
|
battle_state = in.value("battle_state", battle_state);
|
|
currentState = static_cast<AnimationState>(in.value("currentState", static_cast<int>(currentState)));
|
|
attack_cooldown = in.value("attack_cooldown", attack_cooldown);
|
|
showWeapon = in.value("showWeapon", showWeapon);
|
|
attackTargetIndex = in.value("attackTargetIndex", attackTargetIndex);
|
|
faceTargetIndex = in.value("faceTargetIndex", faceTargetIndex);
|
|
if (in.contains("homePosition")) homePosition = readVec3(in["homePosition"], homePosition);
|
|
if (in.contains("walkTarget")) walkTarget = readVec3(in["walkTarget"], walkTarget);
|
|
if (in.contains("requestedWalkTarget")) requestedWalkTarget = readVec3(in["requestedWalkTarget"], requestedWalkTarget);
|
|
pathWaypoints.clear();
|
|
if (in.contains("pathWaypoints") && in["pathWaypoints"].is_array()) {
|
|
for (const auto& wp : in["pathWaypoints"]) {
|
|
pathWaypoints.push_back(readVec3(wp, Eigen::Vector3f::Zero()));
|
|
}
|
|
}
|
|
currentWaypointIndex = in.value("currentWaypointIndex", currentWaypointIndex);
|
|
homeDriftCheckTimer = in.value("homeDriftCheckTimer", homeDriftCheckTimer);
|
|
}
|
|
|
|
} // namespace ZL
|