载入中...
搜索中...
未找到
VitalsSystem.cpp
浏览该文件的文档.
1#include "rpg/VitalsSystem.h"
2
4#include "rpg/RPGActor.h"
5
6#include <algorithm>
7
8namespace eve::rpg {
9
10namespace {
11std::vector<VitalsEvent> &vitalsEvents() {
12 static std::vector<VitalsEvent> events;
13 return events;
14}
15
16void emit(RPGActor *actor, std::string resource, std::string action, double amount,
17 std::string source, double current, double max) {
18 VitalsEvent ev;
19 ev.actor = actor;
20 ev.resource = std::move(resource);
21 ev.action = std::move(action);
22 ev.amount = amount;
23 ev.source = std::move(source);
24 ev.current = current;
25 ev.max = max;
26 vitalsEvents().push_back(std::move(ev));
27}
28} // namespace
29
30double VitalsSystem::getCurrent(RPGActor *actor, const std::string &resource) {
31 if (!actor) return 0.0;
32 auto it = actor->vitals()->current.find(resource);
33 return it == actor->vitals()->current.end() ? 0.0 : it->second;
34}
35
36double VitalsSystem::getMax(RPGActor *actor, const std::string &resource) {
37 return actor ? AttributeSystem::getFinal(actor, resource) : 0.0;
38}
39
40void VitalsSystem::setCurrent(RPGActor *actor, const std::string &resource, double value) {
41 if (!actor) return;
42 const double max = getMax(actor, resource);
43 actor->vitals()->current[resource] = std::clamp(value, 0.0, max);
44}
45
46double VitalsSystem::takeDamage(RPGActor *actor, const std::string &resource, double amount,
47 const std::string &source) {
48 if (!actor || amount <= 0.0) return 0.0;
49 auto &current = actor->vitals()->current;
50 const double max = getMax(actor, resource);
51 const double cur = getCurrent(actor, resource);
52 if (cur <= 0.0) return 0.0; // 已死,不再受伤
53 const double applied = std::min(amount, cur);
54 current[resource] = cur - applied;
55 emit(actor, resource, "damage", applied, source, cur - applied, max);
56 if (cur - applied <= 0.0) {
57 emit(actor, resource, "death", applied, source, 0.0, max);
58 }
59 return applied;
60}
61
62double VitalsSystem::heal(RPGActor *actor, const std::string &resource, double amount) {
63 if (!actor || amount <= 0.0) return 0.0;
64 auto &current = actor->vitals()->current;
65 const double max = getMax(actor, resource);
66 const double cur = getCurrent(actor, resource);
67 const double applied = std::min(amount, max - cur);
68 if (applied <= 0.0) return 0.0;
69 current[resource] = cur + applied;
70 emit(actor, resource, "heal", applied, "", cur + applied, max);
71 return applied;
72}
73
74void VitalsSystem::publishSettledChange(RPGActor *actor, const std::string &resource,
75 const std::string &action, double amount,
76 const std::string &source) {
77 if (!actor || amount <= 0.0 || (action != "damage" && action != "heal")) return;
78 const double current = getCurrent(actor, resource);
79 const double maximum = getMax(actor, resource);
80 emit(actor, resource, action, amount, source, current, maximum);
81 if (action == "damage" && current <= 0.0)
82 emit(actor, resource, "death", amount, source, current, maximum);
83}
84
85void VitalsSystem::revive(RPGActor *actor, const std::string &resource, double amount) {
86 if (!actor) return;
87 auto &current = actor->vitals()->current;
88 const double max = getMax(actor, resource);
89 const double value = amount >= 0.0 ? std::min(amount, max) : max;
91 emit(actor, resource, "revive", value, "", value, max);
92}
93
94bool VitalsSystem::isDead(RPGActor *actor, const std::string &resource) {
95 const double max = getMax(actor, resource);
96 return max > 0.0 && getCurrent(actor, resource) <= 0.0;
97}
98
99void VitalsSystem::pollEvents(std::vector<VitalsEvent> &out) {
100 out.clear();
101 out = std::move(vitalsEvents());
102 vitalsEvents().clear();
103}
104
105} // namespace eve::rpg
double value
RPG's thin compatibility facade over the attributes module.
float maximum[3]
std::string action
Definition PlayHost.cpp:117
double current
std::string resource
Battle::Events events
const UnitySourceAsset & source
当前资源(hp/mana...)的受伤 / 治疗 / 复活 / 死亡。
static double getFinal(RPGActor *actor, const std::string &attribute)
Compute the final value through the canonical attributes engine.
属性 / 状态 / 技能三表合一的 ECS 实体。
Definition RPGActor.h:34
static double getCurrent(RPGActor *actor, const std::string &resource)
当前值(无 vitals/资源时 0)。
static double takeDamage(RPGActor *actor, const std::string &resource, double amount, const std::string &source="")
造成伤害:current -= amount,下限 0;归零时发 death 事件。
static void revive(RPGActor *actor, const std::string &resource, double amount=-1.0)
复活:把资源设为 amount(默认当前上限),并清掉死亡状态。
static void setCurrent(RPGActor *actor, const std::string &resource, double value)
直接设定当前值,夹在 [0, max]。
static void pollEvents(std::vector< VitalsEvent > &out)
取出并清空自上次调用以来累积的资源事件(push/poll 风格)。
static double heal(RPGActor *actor, const std::string &resource, double amount)
治疗:current += amount,上限 max。返回实际治疗量。
static double getMax(RPGActor *actor, const std::string &resource)
上限:取 actor 同名最终属性(getFinalAttribute),无则 0。
static void publishSettledChange(RPGActor *actor, const std::string &resource, const std::string &action, double amount, const std::string &source="")
Publish resource events for a state change already committed by Settlement.
static bool isDead(RPGActor *actor, const std::string &resource)
是否死亡:max > 0 且 current <= 0。
RPG 模块的基础实体:把属性 / 状态 / 技能三张表挂到一个 ECS 实体上。