145 lines
5.4 KiB
C++
145 lines
5.4 KiB
C++
#pragma once
|
|
#include <string>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
#include <functional>
|
|
#include <Eigen/Core>
|
|
#include <Eigen/Geometry>
|
|
#include "external/nlohmann/json.hpp"
|
|
#include "ISaveable.h"
|
|
|
|
namespace FRG {
|
|
|
|
constexpr float VISIBLE_RANGE = 6.f;
|
|
|
|
enum class AnimationState {
|
|
STAND = 0,
|
|
WALK = 1,
|
|
STAND_TO_ACTION = 2,
|
|
ACTION_ATTACK = 3,
|
|
ACTION_ATTACK_2 = 4,
|
|
ACTION_IDLE = 5,
|
|
ACTION_TO_STAND = 6,
|
|
ACTION_TO_DEATH = 7,
|
|
DEATH_IDLE = 8,
|
|
};
|
|
|
|
// Paths and fixed parameters needed to recreate a Character's visual assets
|
|
// from scratch (e.g. after loading a saved game).
|
|
struct CharacterCreationInfo {
|
|
// Each entry is (AnimationState, filepath). Binary .anim format is auto-detected.
|
|
std::vector<std::pair<AnimationState, std::string>> animationPaths;
|
|
// Per-mesh texture paths (mesh name → path); takes priority over singleTexturePath.
|
|
std::unordered_map<std::string, std::string> meshTexturePaths;
|
|
// Single shared texture path (used when setTexture(shared_ptr) was called on all meshes).
|
|
std::string singleTexturePath;
|
|
// Weapon asset paths and attachment setup
|
|
std::string weaponMeshPath;
|
|
std::string weaponTexturePath;
|
|
std::string weaponAttachBoneName = "RightHand";
|
|
Eigen::Vector3f weaponInitialPosition = Eigen::Vector3f::Zero();
|
|
// Weapon orientation stored as a quaternion (serializable as 4 floats).
|
|
Eigen::Quaternionf weaponInitialRotation = Eigen::Quaternionf::Identity();
|
|
// Optional mesh-space transformations applied after loading the weapon mesh.
|
|
Eigen::Vector3f weaponMeshMove = Eigen::Vector3f::Zero();
|
|
float weaponMeshScale = 1.0f;
|
|
};
|
|
|
|
// All serializable game state for a character.
|
|
// This is a member of Character; rendering-only data lives in Character itself.
|
|
class CharacterState : public ISaveable {
|
|
public:
|
|
// Special index values for attackTargetIndex / faceTargetIndex
|
|
static constexpr int kNoTarget = -1; // no target (was nullptr)
|
|
static constexpr int kPlayerIndex = -2; // refers to Location::player
|
|
|
|
// Distance below which the character is considered to have reached its target.
|
|
static constexpr float kWalkThreshold = 0.05f;
|
|
|
|
// --- Identity ---
|
|
std::string npcId;
|
|
std::string npcName;
|
|
bool isPlayer = false;
|
|
bool enabled = true;
|
|
bool canAttack = false;
|
|
|
|
// --- Position / orientation ---
|
|
Eigen::Vector3f position = Eigen::Vector3f::Zero();
|
|
float facingAngle = 0.0f;
|
|
float targetFacingAngle = 0.0f;
|
|
|
|
// --- Health ---
|
|
float hp = 200.f;
|
|
float initialHp = 200.f;
|
|
|
|
float visibleRange = VISIBLE_RANGE;
|
|
|
|
// --- Combat flags ---
|
|
int battle_state = 0;
|
|
bool resetAnim = false;
|
|
int attack = 0;
|
|
AnimationState currentState = AnimationState::STAND;
|
|
float attack_cooldown = 0.f;
|
|
|
|
// Weapon visibility toggle (changes during animation)
|
|
bool showWeapon = true;
|
|
|
|
// --- Index-based character references (replace raw pointers) ---
|
|
int attackTargetIndex = kNoTarget;
|
|
int faceTargetIndex = kNoTarget;
|
|
|
|
// --- Home position for drift recovery ---
|
|
Eigen::Vector3f homePosition = Eigen::Vector3f::Zero();
|
|
float maxHomeDrift = 3.0f;
|
|
|
|
// --- Slow-motion effect ---
|
|
float slowMoTimeRemaining = 0.0f;
|
|
float slowMoActiveTime = 6.0f;
|
|
float slowMoTransitionTime = 0.5f;
|
|
|
|
// --- Movement / visual parameters ---
|
|
float walkSpeed = 3.0f;
|
|
float rotationSpeed = 4.0f;
|
|
float modelScale = 0.12f;
|
|
Eigen::Quaternionf modelCorrectionRotation = Eigen::Quaternionf::Identity();
|
|
bool useGpuSkinning = true;
|
|
float collisionRadius = 0.45f;
|
|
float interactionRadius = 0.0f;
|
|
|
|
// --- Pathfinding data (serializable parts) ---
|
|
Eigen::Vector3f walkTarget = Eigen::Vector3f::Zero();
|
|
Eigen::Vector3f requestedWalkTarget = Eigen::Vector3f::Zero();
|
|
std::vector<Eigen::Vector3f> pathWaypoints;
|
|
size_t currentWaypointIndex = 0;
|
|
|
|
// Internal drift-check timer (serializable so it survives save/load).
|
|
float homeDriftCheckTimer = 5.0f;
|
|
|
|
// --- Non-serializable callbacks (re-wired after each load) ---
|
|
std::function<void()> onArrivedCallback;
|
|
std::function<void()> onDeathAnimComplete;
|
|
std::function<void(float, float, int)> onHpChanged;
|
|
|
|
// Global Lua function name backing onArrivedCallback, if it was sourced from a
|
|
// script (see ScriptEngine::rehydrateNamedCallback). Serialized so the callback
|
|
// can be re-looked-up by name after a save/load; empty if none or non-Lua.
|
|
std::string onArrivedCallbackName;
|
|
|
|
// --- Asset / creation info (used to reload visuals from a saved state) ---
|
|
CharacterCreationInfo creationInfo;
|
|
|
|
// --- Pure-state methods ---
|
|
bool isMoving() const;
|
|
const Eigen::Vector3f& getRequestedWalkTarget() const { return requestedWalkTarget; }
|
|
Eigen::Vector3f getCurrentNavigationTarget() const;
|
|
void stopInPlace();
|
|
float getHp() const { return hp; }
|
|
void setHp(float newHp);
|
|
|
|
// --- Serialisation (runtime mutable fields only; creation info is reloaded from config) ---
|
|
void save(nlohmann::json& out) const override;
|
|
void load(const nlohmann::json& in) override;
|
|
};
|
|
|
|
} // namespace FRG
|