载入中...
搜索中...
未找到
CombatTarget.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5#include <utility>
6
7namespace eve::combat {
8namespace {
9
10std::vector<CombatTargetCandidate> sortedUnique(std::vector<CombatTargetCandidate> candidates, SubjectRef owner) {
11 candidates.erase(std::remove_if(candidates.begin(), candidates.end(),
12 [&](const CombatTargetCandidate& candidate) {
13 return !candidate.subject.isValid() || candidate.subject == owner ||
14 !std::isfinite(candidate.score);
15 }),
16 candidates.end());
17 std::stable_sort(candidates.begin(), candidates.end(),
18 [](const CombatTargetCandidate& a, const CombatTargetCandidate& b) {
19 if (a.score != b.score) return a.score > b.score;
20 return a.subject.format() < b.subject.format();
21 });
22 return candidates;
23}
24
25} // namespace
26
28 if (!owner.isValid()) return Result<void>::failure(
29 Diagnostic::error(DiagnosticCode::InvalidArgument, "owner is nil", "owner"));
30 locks_.emplace(owner.format(), CombatLockState{owner, std::nullopt, false});
32}
33
40
42 const std::vector<CombatTargetCandidate>& candidates) {
43 auto found = locks_.find(owner.format());
44 if (found == locks_.end())
46 Diagnostic::error(DiagnosticCode::NotFound, "lock owner was not found", owner.format()));
47 const auto ranked = sortedUnique(candidates, owner);
48 found->second.hardLock = false;
49 if (ranked.empty()) {
50 found->second.target.reset();
51 } else {
52 found->second.target = ranked.front().subject;
53 }
55}
56
58 auto found = locks_.find(owner.format());
59 if (found == locks_.end())
61 Diagnostic::error(DiagnosticCode::NotFound, "lock owner was not found", owner.format()));
62 if (!target.isValid() || target == owner)
64 Diagnostic::error(DiagnosticCode::InvalidArgument, "hard-lock target is invalid", "target"));
65 found->second.target = target;
66 found->second.hardLock = true;
68}
69
71 const std::vector<CombatTargetCandidate>& candidates) {
72 auto found = locks_.find(owner.format());
73 if (found == locks_.end())
75 Diagnostic::error(DiagnosticCode::NotFound, "lock owner was not found", owner.format()));
76 const auto ranked = sortedUnique(candidates, owner);
77 found->second.hardLock = false;
78 if (ranked.empty()) {
79 found->second.target.reset();
81 }
82 std::size_t index = 0;
83 if (found->second.target) {
84 for (std::size_t i = 0; i < ranked.size(); ++i) {
85 if (ranked[i].subject == *found->second.target) {
86 index = (i + 1) % ranked.size();
87 break;
88 }
89 }
90 }
91 found->second.target = ranked[index].subject;
93}
94
96 auto found = locks_.find(owner.format());
97 if (found == locks_.end())
99 Diagnostic::error(DiagnosticCode::NotFound, "lock owner was not found", owner.format()));
100 found->second.target.reset();
101 found->second.hardLock = false;
103}
104
106 if (!target.isValid()) return Result<void>::failure(
107 Diagnostic::error(DiagnosticCode::InvalidArgument, "target is nil", "target"));
108 for (auto& [key, lock] : locks_) {
109 (void)key;
110 if (lock.target && *lock.target == target) {
111 lock.target.reset();
112 lock.hardLock = false;
113 }
114 }
116}
117
119 const auto found = locks_.find(owner.format());
120 if (found == locks_.end())
122 Diagnostic::error(DiagnosticCode::NotFound, "lock owner was not found", owner.format()));
124}
125
126} // namespace eve::combat
LogicalId target
int subject
Definition AnimSmr.cpp:163
Soft/hard lock-on ownership for action combat.
std::uint32_t key
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
bool found
uint32_t index
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 success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
Strong, domain-neutral reference to a runtime subject.
Definition SubjectRef.h:26
std::string format() const
Return the canonical lower-case UUID spelling.
Definition SubjectRef.h:44
bool isValid() const noexcept
Return whether this reference is valid and non-nil.
Definition SubjectRef.h:38
Result< void > forgetTarget(SubjectRef target)
Forget a subject wherever it appears as a target.
Result< void > registerOwner(SubjectRef owner)
Ensure an owner exists with no target.
Result< CombatLockState > cycle(SubjectRef owner, const std::vector< CombatTargetCandidate > &candidates)
Cycle soft-lock to the next candidate after the current target.
Result< CombatLockState > hardLock(SubjectRef owner, SubjectRef target)
Hard-lock onto an explicit target; rejects nil or self.
Result< CombatLockState > softLock(SubjectRef owner, const std::vector< CombatTargetCandidate > &candidates)
Soft-select the highest-score candidate that is not the owner.
Result< CombatLockState > clear(SubjectRef owner)
Clear the current target while keeping the owner registered.
Result< void > unregisterOwner(SubjectRef owner)
Remove one owner and its lock.
Result< CombatLockState > state(SubjectRef owner) const
Return owning lock state or NotFound.
Owning lock-on state for one fighter.