载入中...
搜索中...
未找到
WeaponAttributes.cpp
浏览该文件的文档.
2
4
5#include <algorithm>
6#include <array>
7#include <cmath>
8#include <limits>
9#include <string>
10#include <utility>
11
12namespace eve::weapon {
13namespace {
14
15bool selected(std::string_view name) noexcept {
18}
19
20std::array<std::string_view, 4> selectedAttributes() {
23}
24
25bool isManaOrStamina(ResourceKind kind) noexcept { return kind == ResourceKind::Mana || kind == ResourceKind::Stamina; }
26
27std::string_view currentAttribute(ResourceKind kind) noexcept {
30}
31
32std::string_view maxAttribute(ResourceKind kind) noexcept {
35}
36
37} // namespace
38
40 auto bound = weapon.attributes()->values.bindOwner(ecs::handle_of(&weapon));
41 if (!bound) return eve::Result<void>::failure(
42 eve::Status::failure(bound.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon attribute owner could not be bound", "owner", {}, "weapon.attributes")));
43 if (!weapon.attributes()->values.initialized()) {
44 const Resource& resource = weapon.state()->resource;
45 const double mana = resource.kind == ResourceKind::Mana ? resource.value : 0.0;
46 const double maxMana = resource.kind == ResourceKind::Mana ? resource.max : 0.0;
47 const double stamina = resource.kind == ResourceKind::Stamina ? resource.value : 0.0;
48 const double maxStamina = resource.kind == ResourceKind::Stamina ? resource.max : 0.0;
49 const std::array<eve::attributes::AttributeSnapshotBase, 4> bases = {
54 auto initialized = weapon.attributes()->values.initialize(bases);
55 if (!initialized)
57 eve::Status::failure(initialized.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon attribute state could not be initialized", "attributes", {}, "weapon.attributes")));
58 }
60}
61
63 auto ready = ensure(weapon);
64 if (!ready) return eve::Result<void>::failure(
65 eve::Status::failure(ready.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon attributes are not available", "attributes", {}, "weapon.attributes")));
66 Resource& resource = weapon.state()->resource;
68 auto current = weapon.attributes()->values.getFinal(currentAttribute(resource.kind));
70 eve::Status::failure(current.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon resource attribute could not be read", "resource", {}, "weapon.attributes")));
71 auto maximum = weapon.attributes()->values.getFinal(maxAttribute(resource.kind));
73 eve::Status::failure(maximum.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon maximum resource attribute could not be read", "resource", {}, "weapon.attributes")));
74 if (!std::isfinite(current.value()) || !std::isfinite(maximum.value()) || current.value() < 0.0 ||
75 maximum.value() < 0.0 || current.value() > maximum.value() ||
76 maximum.value() > static_cast<double>(std::numeric_limits<float>::max()))
78 eve::Diagnostic::error(eve::DiagnosticCode::InvariantViolation, "weapon mana/stamina attributes are outside validated bounds", "resource", {}, "weapon.attributes"));
79 resource.value = static_cast<float>(current.value());
80 resource.max = static_cast<float>(maximum.value());
82}
83
85 if (!selected(attribute))
87 eve::DiagnosticCode::Unsupported, "weapon attribute is outside the mana/stamina projection", "attribute",
88 {}, "weapon.attributes"));
89 auto projected = project(weapon);
90 if (!projected)
92 projected.code(),
93 eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon compatibility projection failed", "resource",
94 {}, "weapon.attributes")));
95 auto value = weapon.attributes()->values.getFinal(attribute);
96 if (!value)
98 value.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon attribute read failed",
99 "attribute", {}, "weapon.attributes")));
100 return eve::Result<double>::success(value.value());
101}
102
103eve::Result<void> WeaponAttributeAdapter::setBase(WeaponEntity& weapon, std::string_view attribute, double value) {
104 if (!selected(attribute))
106 eve::Diagnostic::error(eve::DiagnosticCode::Unsupported, "weapon attribute is outside the mana/stamina projection", "attribute", {}, "weapon.attributes"));
107 auto ready = ensure(weapon);
108 if (!ready) return eve::Result<void>::failure(
109 eve::Status::failure(ready.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon attributes are not available", "attributes", {}, "weapon.attributes")));
110 auto changed = weapon.attributes()->values.setBase(attribute, value);
111 if (!changed) return changed;
112 return project(weapon);
113}
114
116 auto ready = ensure(weapon);
117 if (!ready) return eve::Result<void>::failure(
118 eve::Status::failure(ready.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon attributes are not available", "attributes", {}, "weapon.attributes")));
119 const Resource& resource = weapon.state()->resource;
120 if (!isManaOrStamina(resource.kind))
122 eve::Diagnostic::error(eve::DiagnosticCode::Unsupported, "weapon trigger resource is not mana or stamina", "resource.kind", {}, "weapon.attributes"));
123 const auto currentName = currentAttribute(resource.kind);
124 auto current = weapon.attributes()->values.getFinal(currentName);
126 eve::Status::failure(current.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon trigger resource could not be read", "resource", {}, "weapon.attributes")));
127 if (!resource.infinite && current.value() < static_cast<double>(resource.cost))
129 eve::Diagnostic::error(eve::DiagnosticCode::Conflict, "weapon does not have enough mana or stamina", "resource", {}, "weapon.attributes"));
131 auto changed = weapon.attributes()->values.setBase(
132 currentName, std::max(0.0, current.value() - static_cast<double>(resource.cost)));
133 if (!changed) return changed;
134 return project(weapon);
135}
136
138 WeaponEntity& weapon, std::string id, std::string_view attribute, std::string source,
140 if (!selected(attribute) || source.empty())
142 eve::DiagnosticCode::InvalidArgument, "weapon modifier requires a selected attribute and non-empty source",
143 "modifier", {}, "weapon.attributes"));
144 auto ready = ensure(weapon);
145 if (!ready)
147 ready.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon attributes are not available",
148 "attributes", {}, "weapon.attributes")));
149 auto added = weapon.attributes()->values.addModifier(eve::attributes::AttributeModifier(
150 std::move(id), std::string(attribute), std::move(source), operation, value, priority));
151 if (!added) return added;
152 auto projected = project(weapon);
153 if (!projected)
155 projected.code(),
156 eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon compatibility projection failed", "resource",
157 {}, "weapon.attributes")));
158 return added;
159}
160
162 auto ready = ensure(weapon);
163 if (!ready)
165 ready.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon attributes are not available",
166 "attributes", {}, "weapon.attributes")));
167 const auto names = selectedAttributes();
168 return weapon.attributes()->values.snapshot(names);
169}
170
173 eve::Revision expectedRevision) {
174 auto ready = ensure(weapon);
175 if (!ready) return eve::Result<void>::failure(
176 eve::Status::failure(ready.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "weapon attributes are not available", "attributes", {}, "weapon.attributes")));
177 auto restored = weapon.attributes()->values.restore(snapshotValue, expectedRevision);
178 if (!restored) return restored;
179 return project(weapon);
180}
181
182} // namespace eve::weapon
ActionParameterOperation operation
double value
int priority
Vec3 projected
Definition CaveMesh.cpp:122
float maximum[3]
TokenKind kind
std::string name
double current
std::string resource
const UnitySourceAsset & source
Selective canonical mana/stamina adapter for weapons.
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
static Status failure(StatusCode code, Diagnostic diagnostic)
Construct a failed status with one diagnostic.
Definition Status.h:84
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
static eve::Result< void > setBase(WeaponEntity &weapon, std::string_view attribute, double value)
Set a selected canonical base and refresh Resource compatibility fields.
static eve::Result< void > project(WeaponEntity &weapon)
Project canonical Mana/Stamina values into the legacy Resource component.
static eve::Result< double > read(WeaponEntity &weapon, std::string_view attribute)
Read a selected final mana/stamina attribute.
static eve::Result< eve::attributes::AttributeProjectionSnapshot > snapshot(WeaponEntity &weapon)
Capture selected resource attributes with owner generation and revision.
static constexpr std::string_view manaAttribute
static eve::Result< eve::attributes::ModifierId > addModifier(WeaponEntity &weapon, std::string id, std::string_view attribute, std::string source, eve::attributes::AttributeOperation operation, double value, eve::attributes::ModifierPriority priority=eve::attributes::priority::runtime)
Add a modifier using the shared operation/priority/sequence contract.
static constexpr std::string_view staminaAttribute
static constexpr std::string_view maxManaAttribute
static eve::Result< void > ensure(WeaponEntity &weapon)
Bind and seed the selected resource attributes exactly once.
static constexpr std::string_view maxStaminaAttribute
static eve::Result< void > consumeTriggerResource(WeaponEntity &weapon)
Consume the current weapon's canonical Mana/Stamina trigger cost.
static eve::Result< void > restore(WeaponEntity &weapon, const eve::attributes::AttributeProjectionSnapshot &snapshot, eve::Revision expectedRevision)
Restore selected resource attributes after owner/revision checks.
武器实体:数据全部在组件里,行为在 WeaponSystem。
AttributeOperation
Built-in calculation operation for an attribute modifier.
std::int32_t ModifierPriority
载具模块入口(eve.Vehicle):定义注册 / 实体工厂 / RTS 命令 / 帧调度。 设计文档:docs/dev/通用载具系统设计.md
ResourceKind
触发资源的类型。
Definition WeaponTypes.h:50
One canonical runtime modifier applied to one named attribute.
Transaction-safe snapshot of selected attributes and their modifiers.
One base value captured by an attribute projection snapshot.
运行时触发资源(实体组件)。