载入中...
搜索中...
未找到
RpgStateProvider.cpp
浏览该文件的文档.
1#include "rpg/RpgState.h"
2
3#include "common/Capability.h"
5#include "rpg/RPGActor.h"
6#include "rpg/SkillSystem.h"
7#include "rpg/SkillTypes.h"
8
9#include <algorithm>
10#include <string>
11#include <utility>
12
13namespace eve::rpg {
14namespace {
15
16double toNumber(const StateValue& v) { return v.isInt() ? double(v.asInt()) : v.asDouble(); }
17
19class RpgStateProvider : public eve::caps::IStateProvider {
20public:
21 const char* stateKind() const override { return "rpg"; }
22
23 bool captureState(StateValue& out) override { return captureRpgState(out); }
24 bool restoreState(const StateValue& in, std::string* err) override { return restoreRpgState(in, err); }
25 bool resetToDefaults() override { return resetRpgState(); }
26};
27
28struct Register {
29 Register() {
30 static RpgStateProvider provider;
32 }
33} g_register;
34
35} // namespace
36
39 for (RPGActor* actor : RPGActor::liveActors()) {
41
43 for (const auto& kv : actor->skills()->known) {
44 skills.set(kv.first, StateValue::number(kv.second.cooldownRemaining));
45 }
46 entry.set("skills", std::move(skills));
47
49 const CastingState& c = actor->skills()->casting;
50 casting.set("active", StateValue::boolean(c.active));
51 casting.set("skillId", StateValue::string(c.skillId));
52 casting.set("remaining", StateValue::number(c.remaining));
53 casting.set("totalCastTime", StateValue::number(c.totalCastTime));
54 entry.set("casting", std::move(casting));
55
56 actors.pushBack(std::move(entry));
57 }
58 out = std::move(actors);
59 return true;
60}
61
62bool restoreRpgState(const StateValue& in, std::string* err) {
63 if (!in.isArray()) {
64 if (err) *err = "rpg: expected array of actors";
65 return false;
66 }
67 const std::vector<RPGActor*>& actors = RPGActor::liveActors();
68 const size_t n = std::min(in.arraySize(), actors.size());
69 for (size_t i = 0; i < n; ++i) {
70 const StateValue& entry = in.at(i);
71 if (!entry.isObject()) {
72 if (err) *err = "rpg: actor state is not an object";
73 return false;
74 }
75 RPGActor* actor = actors[i];
76
77 if (const StateValue* skills = entry.find("skills"); skills && skills->isObject()) {
78 for (const auto& key : skills->keys()) {
79 const StateValue* v = skills->find(key);
80 if (!v || !(v->isInt() || v->isFloat())) continue;
81 if (SkillSystem::knows(actor, key)) {
82 SkillSystem::setCooldownRemaining(actor, key, static_cast<float>(toNumber(*v)));
83 }
84 }
85 }
86
87 CastingState& casting = actor->skills()->casting;
88 casting = CastingState();
89 if (const StateValue* c = entry.find("casting"); c && c->isObject()) {
90 const StateValue* active = c->find("active");
91 if (active && active->isBool() && active->asBool()) {
92 const StateValue* skillId = c->find("skillId");
93 const std::string id = skillId && skillId->isString() ? skillId->asString() : "";
94 if (!id.empty() && SkillSystem::knows(actor, id)) {
95 casting.active = true;
96 casting.skillId = id;
97 casting.remaining = 0.f;
98 casting.totalCastTime = 0.f;
99 if (const StateValue* r = c->find("remaining"); r && (r->isInt() || r->isFloat()))
100 casting.remaining = static_cast<float>(toNumber(*r));
101 if (const StateValue* t = c->find("totalCastTime"); t && (t->isInt() || t->isFloat()))
102 casting.totalCastTime = static_cast<float>(toNumber(*t));
103 casting.target = nullptr; // pointers are not serializable
104 }
105 }
106 }
107 }
108 return true;
109}
110
113 return true;
114}
115
116} // namespace eve::rpg
bool active
Definition CardTypes.cpp:34
std::string id
glm::vec3 n
Definition Grass.cpp:64
uint32_t c
int v
JSON-compatible state value tree used by state hot reload.
Definition StateValue.h:20
static StateValue object()
Empty object.
Definition StateValue.h:39
static StateValue boolean(bool v)
Boolean value.
static StateValue array()
Empty array.
Definition StateValue.h:37
void pushBack(StateValue v)
Append an element; only valid on arrays.
size_t arraySize() const
Element count; only valid on arrays.
Definition StateValue.h:64
bool isString() const
Definition StateValue.h:48
bool isObject() const
Definition StateValue.h:49
bool isArray() const
Definition StateValue.h:50
const std::string & asString() const
String payload; only valid when kind() == Kind::String.
Definition StateValue.h:59
static StateValue number(double v)
Floating-point value.
const StateValue * find(const std::string &key) const
Look up key; nullptr when absent.
StateValue & at(size_t index)
Indexed element (bounds-checked); only valid on arrays.
Definition StateValue.h:66
static StateValue string(std::string v)
String value.
void set(const std::string &key, StateValue v)
Insert or replace key; only valid on objects.
Runtime-state serialization for state hot reload.
属性 / 状态 / 技能三表合一的 ECS 实体。
Definition RPGActor.h:28
static const std::vector< RPGActor * > & liveActors()
返回所有通过 createActor() 创建、且当前仍存活的 actor。 StatusSystem::update / SkillSystem::update 用它遍历所有 actor 逐帧推进。 ...
Definition RPGActor.cpp:33
static void cancelCast(RPGActor *actor)
打断当前读条(不退还已扣除的消耗/冷却)。
static void setCooldownRemaining(RPGActor *actor, const std::string &skillId, float seconds)
static bool knows(RPGActor *actor, const std::string &skillId)
I * query()
Definition Capability.h:77
RPG 模块入口:属性 / 效果 / 状态 / 技能 / 结算五套系统的脚本绑定与帧调度点。
bool captureRpgState(StateValue &out)
RPGActor skill-state serialization for state hot reload.
bool restoreRpgState(const StateValue &in, std::string *err=nullptr)
施法状态:同一时间每个 actor 只有一个进行中的引导/读条(可按需扩展为多槽)。
Definition SkillTypes.h:16
class RPGActor * target
Definition SkillTypes.h:21