载入中...
搜索中...
未找到
CardAttributes.cpp
浏览该文件的文档.
2
3#include "card/CardTypes.h"
4
5#include <array>
6#include <cmath>
7#include <limits>
8#include <string>
9#include <utility>
10
11namespace eve::card {
12namespace {
13
14bool selected(std::string_view name) noexcept {
16}
17
18std::array<std::string_view, 2> selectedAttributes() {
20}
21
22} // namespace
23
25 auto bound = card.attributes()->values.bindOwner(ecs::handle_of(&card));
26 if (!bound) return eve::Result<void>::failure(
27 eve::Status::failure(bound.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "card attribute owner could not be bound", "owner", {}, "card.attributes")));
28 if (!card.attributes()->values.initialized()) {
29 const std::array<eve::attributes::AttributeSnapshotBase, 2> bases = {
31 static_cast<double>(card.stats()->attack)},
33 static_cast<double>(card.stats()->health)}};
34 auto initialized = card.attributes()->values.initialize(bases);
35 if (!initialized)
37 eve::Status::failure(initialized.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "card attribute state could not be initialized", "attributes", {}, "card.attributes")));
38 }
40}
41
43 auto ready = ensure(card);
44 if (!ready) return eve::Result<void>::failure(
45 eve::Status::failure(ready.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "card attributes are not available", "attributes", {}, "card.attributes")));
46
47 auto attack = card.attributes()->values.getFinal(attackAttribute);
48 if (!attack) return eve::Result<void>::failure(
49 eve::Status::failure(attack.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "card attack attribute could not be read", "attack", {}, "card.attributes")));
50 auto health = card.attributes()->values.getFinal(healthAttribute);
51 if (!health) return eve::Result<void>::failure(
52 eve::Status::failure(health.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "card health attribute could not be read", "health", {}, "card.attributes")));
53 const double values[] = {attack.value(), health.value()};
54 for (const double value : values) {
55 if (!std::isfinite(value) || value < static_cast<double>(std::numeric_limits<int>::min()) ||
56 value > static_cast<double>(std::numeric_limits<int>::max()))
58 eve::Diagnostic::error(eve::DiagnosticCode::InvariantViolation, "card attribute cannot be represented by the legacy integer projection", "stats", {}, "card.attributes"));
59 }
60 card.stats()->attack = static_cast<int>(std::llround(attack.value()));
61 card.stats()->health = static_cast<int>(std::llround(health.value()));
63}
64
65eve::Result<double> CardAttributeAdapter::read(CardData& card, std::string_view attribute) {
66 if (!selected(attribute))
68 eve::DiagnosticCode::Unsupported, "card attribute is outside the selective combat projection", "attribute",
69 {}, "card.attributes"));
70 auto projected = project(card);
71 if (!projected)
73 projected.code(),
74 eve::Diagnostic::error(eve::DiagnosticCode::Failed, "card compatibility projection failed", "stats", {},
75 "card.attributes")));
76 auto value = card.attributes()->values.getFinal(attribute);
77 if (!value)
79 value.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "card attribute read failed", "attribute",
80 {}, "card.attributes")));
81 return eve::Result<double>::success(value.value());
82}
83
84eve::Result<void> CardAttributeAdapter::setBase(CardData& card, std::string_view attribute, double value) {
85 if (!selected(attribute))
87 eve::Diagnostic::error(eve::DiagnosticCode::Unsupported, "card attribute is outside the selective combat projection", "attribute", {}, "card.attributes"));
88 auto ready = ensure(card);
89 if (!ready) return eve::Result<void>::failure(
90 eve::Status::failure(ready.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "card attributes are not available", "attributes", {}, "card.attributes")));
91 auto changed = card.attributes()->values.setBase(attribute, value);
92 if (!changed) return changed;
93 return project(card);
94}
95
97 CardData& card, std::string id, std::string_view attribute, std::string source,
99 if (!selected(attribute) || source.empty())
101 eve::DiagnosticCode::InvalidArgument, "card modifier requires a selected attribute and non-empty source",
102 "modifier", {}, "card.attributes"));
103 auto ready = ensure(card);
104 if (!ready)
106 ready.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "card attributes are not available",
107 "attributes", {}, "card.attributes")));
108 auto added = card.attributes()->values.addModifier(eve::attributes::AttributeModifier(
109 std::move(id), std::string(attribute), std::move(source), operation, value, priority));
110 if (!added) return added;
111 auto projected = project(card);
112 if (!projected)
114 projected.code(),
115 eve::Diagnostic::error(eve::DiagnosticCode::Failed, "card compatibility projection failed", "stats", {},
116 "card.attributes")));
117 return added;
118}
119
121 auto ready = ensure(card);
122 if (!ready)
124 ready.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "card attributes are not available",
125 "attributes", {}, "card.attributes")));
126 const auto names = selectedAttributes();
127 return card.attributes()->values.snapshot(names);
128}
129
132 eve::Revision expectedRevision) {
133 auto ready = ensure(card);
134 if (!ready) return eve::Result<void>::failure(
135 eve::Status::failure(ready.code(), eve::Diagnostic::error(eve::DiagnosticCode::Failed, "card attributes are not available", "attributes", {}, "card.attributes")));
136 auto restored = card.attributes()->values.restore(snapshotValue, expectedRevision);
137 if (!restored) return restored;
138 return project(card);
139}
140
141} // namespace eve::card
ActionParameterOperation operation
double value
int priority
Selective canonical attributes for card combat values.
Vec3 projected
Definition CaveMesh.cpp:122
std::map< std::string, Var > values
std::string name
const UnitySourceAsset & source
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 constexpr std::string_view attackAttribute
static eve::Result< void > ensure(CardData &card)
Bind and seed the card's selected attributes exactly once.
static constexpr std::string_view healthAttribute
static eve::Result< void > project(CardData &card)
Project canonical values into the legacy integer Stats fields.
static eve::Result< eve::attributes::AttributeProjectionSnapshot > snapshot(CardData &card)
Capture attack/health with the owning ECS generation and revision.
static eve::Result< double > read(CardData &card, std::string_view attribute)
Read a selected final card attribute and refresh compatibility fields.
static eve::Result< eve::attributes::ModifierId > addModifier(CardData &card, 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 attribute operation ordering.
static eve::Result< void > restore(CardData &card, const eve::attributes::AttributeProjectionSnapshot &snapshot, eve::Revision expectedRevision)
Restore a card snapshot only when owner and revision still match.
static eve::Result< void > setBase(CardData &card, std::string_view attribute, double value)
Set a selected canonical base and refresh the legacy projection.
单张卡牌:ECS 实体,数据拆成 Identity / Stats / Visual / Layout / State。
Definition CardTypes.h:94
AttributeOperation
Built-in calculation operation for an attribute modifier.
std::int32_t ModifierPriority
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.