载入中...
搜索中...
未找到
TraitSystem.cpp
浏览该文件的文档.
1#include "rpg/TraitSystem.h"
2
4#include "rpg/RPGActor.h"
5#include "rpg/Trait.h"
6
7#include <algorithm>
8
9namespace eve::rpg {
10
11namespace {
12
13const TraitDefinition *findDef(const std::string &id) { return TraitRegistry::find(id); }
14
15bool matches(const TraitSpec &spec, const std::string &target) {
16 return spec.target.empty() || spec.target == target;
17}
18
19} // namespace
20
21int TraitSystem::apply(RPGActor *actor, const std::string &traitId, const std::string &source) {
22 if (!actor) return 0;
23 const TraitDefinition *def = findDef(traitId);
24 if (!def) return 0;
25 auto &ts = *actor->traits();
27 inst.instanceId = ts.nextInstanceId++;
28 inst.traitId = traitId;
29 inst.source = source;
30 // paramRate → 属性修改器(mulAdd 倍率),source="trait:<instanceId>"
31 for (const auto &spec : def->traits) {
32 if (spec.kind != "paramRate" || spec.target.empty()) continue;
33 AttributeSystem::addModifier(actor, spec.target,
34 "trait:" + std::to_string(inst.instanceId), "mulAdd",
35 spec.value - 1.0, 0);
36 }
37 ts.active.push_back(std::move(inst));
38 return inst.instanceId;
39}
40
41bool TraitSystem::remove(RPGActor *actor, int instanceId) {
42 if (!actor) return false;
43 auto &ts = *actor->traits();
44 for (auto it = ts.active.begin(); it != ts.active.end(); ++it) {
45 if (it->instanceId != instanceId) continue;
47 actor, "trait:" + std::to_string(instanceId));
48 ts.active.erase(it);
49 return true;
50 }
51 return false;
52}
53
54int TraitSystem::removeBySource(RPGActor *actor, const std::string &source) {
55 if (!actor) return 0;
56 auto &ts = *actor->traits();
57 int n = 0;
58 for (auto it = ts.active.begin(); it != ts.active.end();) {
59 if (it->source == source) {
61 actor, "trait:" + std::to_string(it->instanceId));
62 it = ts.active.erase(it);
63 ++n;
64 } else {
65 ++it;
66 }
67 }
68 return n;
69}
70
71int TraitSystem::removeByTrait(RPGActor *actor, const std::string &traitId) {
72 if (!actor) return 0;
73 auto &ts = *actor->traits();
74 int n = 0;
75 for (auto it = ts.active.begin(); it != ts.active.end();) {
76 if (it->traitId == traitId) {
78 actor, "trait:" + std::to_string(it->instanceId));
79 it = ts.active.erase(it);
80 ++n;
81 } else {
82 ++it;
83 }
84 }
85 return n;
86}
87
89 if (!actor) return;
90 auto &ts = *actor->traits();
91 for (const auto &inst : ts.active) {
93 "trait:" + std::to_string(inst.instanceId));
94 }
95 ts.active.clear();
96}
97
98bool TraitSystem::hasTrait(RPGActor *actor, const std::string &traitId) {
99 if (!actor) return false;
100 for (const auto &inst : actor->traits()->active) {
101 if (inst.traitId == traitId) return true;
102 }
103 return false;
104}
105
107 return actor ? int(actor->traits()->active.size()) : 0;
108}
109
111 if (!actor || index < 0 || size_t(index) >= actor->traits()->active.size()) return 0;
112 return actor->traits()->active[size_t(index)].instanceId;
113}
114
115std::string TraitSystem::getTraitIdAt(RPGActor *actor, int index) {
116 if (!actor || index < 0 || size_t(index) >= actor->traits()->active.size()) return {};
117 return actor->traits()->active[size_t(index)].traitId;
118}
119
120std::string TraitSystem::getSourceAt(RPGActor *actor, int index) {
121 if (!actor || index < 0 || size_t(index) >= actor->traits()->active.size()) return {};
122 return actor->traits()->active[size_t(index)].source;
123}
124
125double TraitSystem::getParamRate(RPGActor *actor, const std::string &param) {
126 if (!actor) return 1.0;
127 double product = 1.0;
128 for (const auto &inst : actor->traits()->active) {
129 const TraitDefinition *def = findDef(inst.traitId);
130 if (!def) continue;
131 for (const auto &spec : def->traits) {
132 if (spec.kind == "paramRate" && spec.target == param) product *= spec.value;
133 }
134 }
135 return product;
136}
137
138double TraitSystem::getElementRate(RPGActor *actor, const std::string &element) {
139 if (!actor) return 1.0;
140 double product = 1.0;
141 for (const auto &inst : actor->traits()->active) {
142 const TraitDefinition *def = findDef(inst.traitId);
143 if (!def) continue;
144 for (const auto &spec : def->traits) {
145 if (spec.kind == "elementRate" && matches(spec, element)) product *= spec.value;
146 }
147 }
148 return product;
149}
150
151double TraitSystem::getStateRate(RPGActor *actor, const std::string &stateId) {
152 if (!actor) return 1.0;
153 double product = 1.0;
154 for (const auto &inst : actor->traits()->active) {
155 const TraitDefinition *def = findDef(inst.traitId);
156 if (!def) continue;
157 for (const auto &spec : def->traits) {
158 if (spec.kind == "stateRate" && matches(spec, stateId)) product *= spec.value;
159 }
160 }
161 return product;
162}
163
164bool TraitSystem::isStateResist(RPGActor *actor, const std::string &stateId) {
165 if (!actor) return false;
166 for (const auto &inst : actor->traits()->active) {
167 const TraitDefinition *def = findDef(inst.traitId);
168 if (!def) continue;
169 for (const auto &spec : def->traits) {
170 if (spec.kind == "stateResist" && matches(spec, stateId)) return true;
171 }
172 }
173 return false;
174}
175
176double TraitSystem::getExParam(RPGActor *actor, const std::string &exParam) {
177 if (!actor) return 0.0;
178 double sum = 0.0;
179 for (const auto &inst : actor->traits()->active) {
180 const TraitDefinition *def = findDef(inst.traitId);
181 if (!def) continue;
182 for (const auto &spec : def->traits) {
183 if (spec.kind == "exParam" && spec.target == exParam) sum += spec.value;
184 }
185 }
186 return sum;
187}
188
189std::vector<std::string> TraitSystem::getAttackElements(RPGActor *actor) {
190 std::vector<std::string> out;
191 if (!actor) return out;
192 for (const auto &inst : actor->traits()->active) {
193 const TraitDefinition *def = findDef(inst.traitId);
194 if (!def) continue;
195 for (const auto &spec : def->traits) {
196 if (spec.kind == "attackElement" && !spec.target.empty()) {
197 if (std::find(out.begin(), out.end(), spec.target) == out.end())
198 out.push_back(spec.target);
199 }
200 }
201 }
202 return out;
203}
204
205std::vector<std::string> TraitSystem::getAttackStates(RPGActor *actor) {
206 std::vector<std::string> out;
207 if (!actor) return out;
208 for (const auto &inst : actor->traits()->active) {
209 const TraitDefinition *def = findDef(inst.traitId);
210 if (!def) continue;
211 for (const auto &spec : def->traits) {
212 if (spec.kind == "attackState" && !spec.target.empty()) {
213 if (std::find(out.begin(), out.end(), spec.target) == out.end())
214 out.push_back(spec.target);
215 }
216 }
217 }
218 return out;
219}
220
222 if (!actor) return 0.0;
223 double sum = 0.0;
224 for (const auto &inst : actor->traits()->active) {
225 const TraitDefinition *def = findDef(inst.traitId);
226 if (!def) continue;
227 for (const auto &spec : def->traits) {
228 if (spec.kind == "attackSpeed") sum += spec.value;
229 }
230 }
231 return sum;
232}
233
235 if (!actor) return 0;
236 int sum = 0;
237 for (const auto &inst : actor->traits()->active) {
238 const TraitDefinition *def = findDef(inst.traitId);
239 if (!def) continue;
240 for (const auto &spec : def->traits) {
241 if (spec.kind == "attackTimes") sum += static_cast<int>(spec.value);
242 }
243 }
244 return sum;
245}
246
247} // namespace eve::rpg
LogicalId target
RPG's thin compatibility facade over the attributes module.
glm::vec3 n
Definition Grass.cpp:63
std::string element
特征系统:施加/移除运行时特征,并提供耐性/特殊参数/攻击附加等查询。
特征(Trait):RPG Maker 式数据驱动的能力/特性模板与进程级注册表。
uint32_t index
const UnitySourceAsset & source
static int removeAllModifiersBySource(RPGActor *actor, const std::string &source)
Compatibility all-attribute source removal facade.
static eve::Result< ModifierId > addModifier(RPGActor *actor, AttributeModifier modifier)
Add one canonical modifier to an actor.
属性 / 状态 / 技能三表合一的 ECS 实体。
Definition RPGActor.h:34
static const TraitDefinition * find(const std::string &id)
Find a registered trait definition by id.
Definition Trait.cpp:32
static int removeBySource(RPGActor *actor, const std::string &source)
移除该 actor 上所有来自 source 的特征;返回移除数。
static bool hasTrait(RPGActor *actor, const std::string &traitId)
是否已施加某特征。
static double getElementRate(RPGActor *actor, const std::string &element)
元素耐性乘积(1 = 无修正,0.5 = 减半)。
static int getAttackTimesAdd(RPGActor *actor)
攻击次数附加(整数加值)。
static double getExParam(RPGActor *actor, const std::string &exParam)
特殊参数加值(hit/evasion/critRate/critEvade/magicEvade/magicReflect/...)。
static double getAttackSpeed(RPGActor *actor)
攻击速度修正(加值)。
static std::string getSourceAt(RPGActor *actor, int index)
Returns the source at.
static void removeAll(RPGActor *actor)
移除全部特征。
static std::string getTraitIdAt(RPGActor *actor, int index)
Returns the trait id at.
static bool remove(RPGActor *actor, int instanceId)
按实例 id 移除(compatibility facade (脚本兼容门面);成功返回 true)。
static std::vector< std::string > getAttackStates(RPGActor *actor)
攻击附加状态列表。
static double getParamRate(RPGActor *actor, const std::string &param)
参数倍率乘积(如 attack → 1.5 表示 +50)。
static bool isStateResist(RPGActor *actor, const std::string &stateId)
是否免疫某状态(stateResist 命中;target 空 = 全部免疫)。
static int apply(RPGActor *actor, const std::string &traitId, const std::string &source="")
施加一个特征。
static int getCount(RPGActor *actor)
Returns the count.
static std::vector< std::string > getAttackElements(RPGActor *actor)
攻击附加元素列表。
static int getInstanceIdAt(RPGActor *actor, int index)
Returns the instance id at.
static double getStateRate(RPGActor *actor, const std::string &stateId)
状态施加率乘积(1 = 正常)。
static int removeByTrait(RPGActor *actor, const std::string &traitId)
移除该 actor 上所有 traitId 匹配的特征;返回移除数。
RPG 模块的基础实体:把属性 / 状态 / 技能三张表挂到一个 ECS 实体上。
已施加的运行时特征实例。
Definition RPGActor.h:88
数据驱动的特征模板。
Definition Trait.h:32
std::vector< TraitSpec > traits
Definition Trait.h:34