shadow-over-bishkek001/src/CharacterState.cpp
2026-06-18 21:48:27 +03:00

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