space-game001/src/Character.h

98 lines
3.0 KiB
C++

#pragma once
#include "BoneAnimatedModel.h"
#include "render/Renderer.h"
#include "render/TextureManager.h"
#include "items/Item.h"
#include <functional>
#include <memory>
#include <map>
#include <string>
#include <cstdint>
#include <vector>
namespace ZL {
enum class AnimationState {
STAND = 0,
WALK = 1,
STAND_TO_ACTION = 2,
ACTION_ATTACK = 3,
ACTION_IDLE = 4,
ACTION_TO_STAND = 5
};
class Character {
public:
using PathPlanner = std::function<std::vector<Eigen::Vector3f>(
const Eigen::Vector3f& start,
const Eigen::Vector3f& end)>;
void loadAnimation(AnimationState state, const std::string& filename, const std::string& zipFile = "");
// void setTexture(std::shared_ptr<Texture> texture);
void setTexture(std::shared_ptr<Texture> texture) {
this->texture = texture;
}
void update(int64_t deltaMs);
// onArrived is called once when the character reaches this target.
// From Python you can chain further commands (walk, wait, trigger others).
void setTarget(const Eigen::Vector3f& target,
std::function<void()> onArrived = nullptr);
void setPathPlanner(PathPlanner planner);
void draw(Renderer& renderer);
// Public: read by Game for camera tracking and ray-cast origin
Eigen::Vector3f position = Eigen::Vector3f(0.f, 0.f, 0.f);
float facingAngle = 0.0f;
// Per-character tuning — set after construction, before first update
float walkSpeed = 3.0f;
float rotationSpeed = 4.0f;
float modelScale = 0.12f;
// Applied after scale, fixes model-space orientation (e.g. Blender Z-up exports)
Eigen::Quaternionf modelCorrectionRotation = Eigen::Quaternionf::Identity();
// NPC Gift
Item giftItem;
std::string npcId;
std::string npcName;
bool giftReceived = false;
int battle_state = 0;
bool resetAnim = false;
int attack = 0;
AnimationState currentState = AnimationState::STAND;
float attack_cooldown = 0.f;
bool canAttack = false;
Character* attackTarget = nullptr;
bool isPlayer = false;
private:
struct AnimationData {
BoneSystem model;
VertexRenderStruct modelMutable;
float currentFrame = 0.f;
int lastFrame = -1;
int totalFrames = 1;
};
std::map<AnimationState, AnimationData> animations;
std::shared_ptr<Texture> texture;
Eigen::Vector3f walkTarget = Eigen::Vector3f(0.f, 0.f, 0.f);
Eigen::Vector3f requestedWalkTarget = Eigen::Vector3f(0.f, 0.f, 0.f);
std::vector<Eigen::Vector3f> pathWaypoints;
size_t currentWaypointIndex = 0;
PathPlanner pathPlanner;
float targetFacingAngle = 0.0f;
std::function<void()> onArrivedCallback;
static constexpr float WALK_THRESHOLD = 0.05f;
static constexpr float TARGET_REPLAN_THRESHOLD = 0.25f;
// Returns the animation state to actually play/draw, falling back to IDLE
// if the requested state has no loaded animation.
AnimationState resolveActiveState() const;
};
} // namespace ZL