Major refactoring - internal server state machine implemented
This commit is contained in:
1 parent
71c654e5b6
commit
66e93d46f4
48 files changed
+3948
-3696
No files matched your search
+33
-46
@@ -11,30 +11,25 @@
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include "dialogue/TranslationDatabase.h"
|
||||
#include "AudioPlayerAsync.h"
|
||||
|
||||
namespace FRG {
|
||||
|
||||
class TextRenderer;
|
||||
class IGameServer;
|
||||
|
||||
class Character {
|
||||
public:
|
||||
Character(const CharacterState& boundState, IGameServer& server,
|
||||
std::string locationId, std::string entityId)
|
||||
: characterState(boundState), gameServer_(server),
|
||||
locationId_(std::move(locationId)), entityId_(std::move(entityId)){}
|
||||
const std::string& entityId() const { return entityId_; }
|
||||
void bindToLocation(std::string locationId) { locationId_ = std::move(locationId); }
|
||||
static constexpr float kAttackRange = 1.25f;
|
||||
|
||||
// Resolves a character index to a live Character pointer.
|
||||
// kNoTarget (-1) → nullptr, kPlayerIndex (-2) → Location::player, 0..n → npcs[n].
|
||||
using CharacterResolver = std::function<Character*(int index)>;
|
||||
|
||||
using PathPlanner = std::function<std::vector<Eigen::Vector3f>(
|
||||
const Eigen::Vector3f& start,
|
||||
const Eigen::Vector3f& end)>;
|
||||
|
||||
// All serializable game state (position, hp, flags, pathfinding, etc.)
|
||||
CharacterState state;
|
||||
|
||||
int index = CharacterState::kNoTarget;
|
||||
|
||||
// ---- Asset loading ----
|
||||
void loadAnimation(AnimationState animState, const std::string& filename, const std::string& zipFile = "");
|
||||
void loadBinaryAnimation(AnimationState animState, const std::string& filename, const std::string& zipFile = "");
|
||||
@@ -46,31 +41,19 @@ public:
|
||||
|
||||
// Creates a fully-loaded Character from a CharacterState (including its creationInfo).
|
||||
// Loads all animations, textures, and weapon mesh/texture from the paths stored in creationInfo.
|
||||
static std::unique_ptr<Character> createFromState(CharacterState st, Renderer& renderer, const char* zipFile);
|
||||
static std::unique_ptr<Character> createFromState(
|
||||
const CharacterState& initialState, IGameServer& server,
|
||||
const std::string& locationId, const std::string& entityId,
|
||||
Renderer& renderer, const char* zipFile);
|
||||
|
||||
// ---- Per-frame update ----
|
||||
// resolver maps character indices to live pointers so attackTargetIndex / faceTargetIndex
|
||||
// can be dereferenced inside update(). Pass nullptr only if no targets are set.
|
||||
void update(int64_t deltaMs, const CharacterResolver& resolver = nullptr);
|
||||
|
||||
void setPathPlanner(PathPlanner planner);
|
||||
|
||||
// ---- Navigation (path data lives in state; pathPlanner lives here) ----
|
||||
// callbackName, if given, is the global Lua function name backing onArrived —
|
||||
// stored in state.onArrivedCallbackName so it survives save/load (see ScriptEngine::rehydrateNamedCallback).
|
||||
void setTarget(const Eigen::Vector3f& target, std::function<void()> onArrived = nullptr, std::string callbackName = "");
|
||||
void stopAndRotateToTarget(int npcId);
|
||||
|
||||
void forceReplan();
|
||||
void stopInPlace() { state.stopInPlace(); }
|
||||
|
||||
// ---- Reset ----
|
||||
void resetPlayerAfterDeath();
|
||||
|
||||
void tryAttackCombo();
|
||||
// Applies authoritative animation state to runtime resources and consumes
|
||||
// presentation-only events emitted by CharacterState::update.
|
||||
void update(int64_t deltaMs, const CharacterUpdateEvents* events = nullptr);
|
||||
|
||||
// ---- Damage ----
|
||||
void applyDamage(float damageAmount, const Eigen::Vector3f& attackDirection = Eigen::Vector3f::Zero(), int attackerIndex = CharacterState::kNoTarget);
|
||||
void presentDamage(float hp, float maxHp, const Eigen::Vector3f& attackDirection,
|
||||
const std::string& attackerId);
|
||||
|
||||
// ---- Spark setup ----
|
||||
void setupHitSparks(std::shared_ptr<Texture> sparkTexture);
|
||||
@@ -102,13 +85,10 @@ public:
|
||||
const float* ambientColor, const float* fogColor);
|
||||
|
||||
// ---- Query helpers (delegate to state) ----
|
||||
bool isMoving() const { return state.isMoving(); }
|
||||
const Eigen::Vector3f& getRequestedWalkTarget() const { return state.getRequestedWalkTarget(); }
|
||||
Eigen::Vector3f getCurrentNavigationTarget() const { return state.getCurrentNavigationTarget(); }
|
||||
float getHp() const { return state.getHp(); }
|
||||
void setHp(float newHp) { state.setHp(newHp); }
|
||||
|
||||
float getSpeedMultiplier(float transitionProgress) const;
|
||||
bool isMoving() const { return characterState.isMoving(); }
|
||||
const Eigen::Vector3f& getRequestedWalkTarget() const { return characterState.getRequestedWalkTarget(); }
|
||||
Eigen::Vector3f getCurrentNavigationTarget() const { return characterState.getCurrentNavigationTarget(); }
|
||||
float getHp() const { return characterState.getHp(); }
|
||||
|
||||
// ---- Weapon rendering data (initialized from state.creationInfo by createFromState) ----
|
||||
VertexRenderStruct weaponMesh;
|
||||
@@ -123,16 +103,23 @@ public:
|
||||
static Dialogue::TranslationDatabase nameTranslations;
|
||||
|
||||
private:
|
||||
friend class Game;
|
||||
friend class Location;
|
||||
friend class ScriptEngine;
|
||||
friend class LocationEditor;
|
||||
friend class PathVisualization;
|
||||
friend class InternalGameServer;
|
||||
const CharacterState& characterState; // private non-owning binding to server-owned storage
|
||||
IGameServer& gameServer_;
|
||||
std::string locationId_;
|
||||
std::string entityId_;
|
||||
std::function<void()> onDeathAnimComplete;
|
||||
std::function<void(float, float, const std::string&)> onHpChanged;
|
||||
std::map<AnimationState, BoneAnimationDataNew> animations;
|
||||
VertexRenderStruct modelMutable;
|
||||
VertexRenderStruct healthBarMesh;
|
||||
std::unordered_map<std::string, std::shared_ptr<Texture>> meshTextures;
|
||||
|
||||
PathPlanner pathPlanner;
|
||||
|
||||
static constexpr float TARGET_REPLAN_THRESHOLD = 0.25f;
|
||||
static constexpr float HOME_DRIFT_CHECK_INTERVAL = 5.0f;
|
||||
|
||||
AnimationState resolveActiveState() const;
|
||||
bool prepareGpuSkinning();
|
||||
void drawAttachedWeapon(Renderer& renderer);
|
||||
|
||||
Reference in new issue
Block a user