载入中...
搜索中...
未找到
ActionStateWindowBlock.cpp
浏览该文件的文档.
2
3#include <limits>
4#include <utility>
5
6namespace eve::action {
7namespace {
8
9Result<std::optional<std::size_t>> parseTargetIndex(const Value::Object& payload) {
10 const auto found = payload.find("targetIndex");
11 if (found == payload.end()) return Result<std::optional<std::size_t>>::success(std::nullopt);
12 const auto* value = found->second.getIf<std::int64_t>();
13 if (!value || *value < 0 || static_cast<std::uint64_t>(*value) > std::numeric_limits<std::uint32_t>::max())
14 return Result<std::optional<std::size_t>>::failure(
16 "state window target index must be an unsigned 32-bit integer", "targetIndex"));
17 return Result<std::optional<std::size_t>>::success(static_cast<std::size_t>(*value));
18}
19
20Result<std::string> requiredString(const Value::Object& payload, const char* field) {
21 const auto found = payload.find(field);
22 const auto* value = found == payload.end() ? nullptr : found->second.getIf<std::string>();
23 if (!value || value->empty())
25 Diagnostic::error(DiagnosticCode::InvalidArgument, "state window resource must be non-empty", field));
27}
28
29} // namespace
30
32 const Value::Object& payload) {
34 auto target = parseTargetIndex(payload);
36 candidate.targetIndex = target.value();
37 const auto priorityFound = payload.find("priority");
38 if (priorityFound != payload.end()) {
39 const auto* priority = priorityFound->second.getIf<std::int64_t>();
40 if (!priority || *priority < std::numeric_limits<std::int32_t>::min() ||
41 *priority > std::numeric_limits<std::int32_t>::max())
43 DiagnosticCode::InvalidArgument, "state window priority must be a signed 32-bit integer", "priority"));
44 candidate.priority = static_cast<std::int32_t>(*priority);
45 }
46 const char* field = nullptr;
47 if (type == "combat:hitbox-window") {
49 field = "hitbox";
50 } else if (type == "combat:invulnerability-window") {
52 } else if (type == "input:combo-window") {
54 field = "input";
55 } else if (type == "collision:ignore-window") {
57 field = "channel";
58 } else if (type == "input:cancel-window") {
60 field = "allows";
61 } else if (type == "combat:guard-window") {
63 field = "mode";
64 } else {
66 Diagnostic::error(DiagnosticCode::InvalidArgument, "unknown built-in state window type", "type"));
67 }
68 if (field) {
69 auto resource = requiredString(payload, field);
71 candidate.resource = std::move(resource).takeValue();
72 if (candidate.kind == ActionStateWindowKind::Guard && candidate.resource != "block" &&
73 candidate.resource != "parry")
75 Diagnostic::error(DiagnosticCode::InvalidArgument, "guard mode must be block or parry", "mode"));
76 }
77 return Result<ActionStateWindowBinding>::success(std::move(candidate));
78}
79
80} // namespace eve::action
LogicalId target
double value
Typed combat/input/collision action-state window contracts.
Value::Object payload
bool found
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
std::map< std::string, Value > Object
Definition Value.h:34
Owning validated state-window request authored on an action timeline.
std::optional< std::size_t > targetIndex
Optional target index; absence selects ActionNotifyContext::source.
static Result< ActionStateWindowBinding > fromPayload(std::string_view type, const Value::Object &payload)
Decode one known state-window payload without mutating domain state.
std::int32_t priority
Optional cancel priority; higher wins when multiple windows match.
std::string resource
Hitbox, input action, collision channel, cancel allow-list, or guard mode.