载入中...
搜索中...
未找到
HitFeel.cpp
浏览该文件的文档.
1#include "combat/HitFeel.h"
2
3#include <algorithm>
4#include <utility>
5
6namespace eve::combat {
7namespace {
8
9Duration maxDuration(Duration a, Duration b) { return a < b ? b : a; }
10
11} // namespace
12
15 Diagnostic::error(DiagnosticCode::InvalidArgument, "attacker is nil", "attacker"));
17 Diagnostic::error(DiagnosticCode::InvalidArgument, "victim is nil", "victim"));
21 Diagnostic::error(DiagnosticCode::InvalidArgument, "hit-feel durations must be non-negative", "duration"));
22 return Result<void>::success();
23}
24
26 auto valid = request.validate();
27 if (!valid) return valid;
28 auto& attacker = states_[request.attacker.format()];
29 attacker.subject = request.attacker;
30 attacker.hitstopRemaining = maxDuration(attacker.hitstopRemaining, request.attackerHitstop);
31 attacker.timeFrozen = attacker.hitstopRemaining > Duration::zero();
32
33 auto& victim = states_[request.victim.format()];
34 victim.subject = request.victim;
35 victim.hitstopRemaining = maxDuration(victim.hitstopRemaining, request.victimHitstop);
36 victim.hitstunRemaining = maxDuration(victim.hitstunRemaining, request.victimHitstun);
37 victim.timeFrozen = victim.hitstopRemaining > Duration::zero();
39}
40
43 request.attacker = outcome.source;
44 request.victim = outcome.target;
45 switch (outcome.reaction) {
47 request.attackerHitstop = Duration::fromNanoseconds(16000000);
48 request.victimHitstop = Duration::fromNanoseconds(16000000);
49 break;
51 request.attackerHitstop = Duration::fromNanoseconds(33000000);
52 request.victimHitstop = Duration::fromNanoseconds(33000000);
53 request.victimHitstun = Duration::fromNanoseconds(120000000);
54 break;
56 request.attackerHitstop = Duration::fromNanoseconds(50000000);
57 request.victimHitstop = Duration::fromNanoseconds(50000000);
58 request.victimHitstun = Duration::fromNanoseconds(350000000);
59 break;
61 request.attackerHitstop = Duration::fromNanoseconds(66000000);
62 request.victimHitstop = Duration::fromNanoseconds(66000000);
63 request.victimHitstun = Duration::fromNanoseconds(800000000);
64 break;
66 request.attackerHitstop = Duration::fromNanoseconds(80000000);
67 request.victimHitstop = Duration::fromNanoseconds(100000000);
68 request.victimHitstun = Duration::fromNanoseconds(1000000000);
69 break;
70 }
71 request.reaction = outcome.reaction;
72 return apply(std::move(request));
73}
74
76 if (step.tick.value() < lastTick_.value())
78 Diagnostic::error(DiagnosticCode::InvalidArgument, "hit-feel tick must be non-decreasing", "tick"));
79 if (step.delta < Duration::zero())
81 Diagnostic::error(DiagnosticCode::InvalidArgument, "hit-feel delta is invalid", "delta"));
82
84 advance.tick = step.tick;
85 for (auto it = states_.begin(); it != states_.end();) {
86 auto& state = it->second;
87 const bool hadHitstop = state.hitstopRemaining > Duration::zero();
88 const bool hadHitstun = state.hitstunRemaining > Duration::zero();
93 step.delta.nanoseconds());
94 }
99 step.delta.nanoseconds());
100 }
102 if (hadHitstop && state.hitstopRemaining.isZero())
103 advance.events.push_back({state.subject, HitFeelEventKind::HitstopEnded, step.tick});
104 if (hadHitstun && state.hitstunRemaining.isZero())
105 advance.events.push_back({state.subject, HitFeelEventKind::HitstunEnded, step.tick});
107 it = states_.erase(it);
108 else
109 ++it;
110 }
111 lastTick_ = step.tick;
113}
114
116 const auto found = states_.find(subject.format());
117 if (found == states_.end()) return HitFeelState{subject, Duration::zero(), Duration::zero(), false};
118 return found->second;
119}
120
122 const auto found = states_.find(subject.format());
123 return found != states_.end() && found->second.hitstopRemaining > Duration::zero();
124}
125
127 const auto found = states_.find(subject.format());
128 return found != states_.end() && found->second.hitstunRemaining > Duration::zero();
129}
130
131} // namespace eve::combat
int subject
Definition AnimSmr.cpp:163
const GltfImportRequest & request
Deterministic hitstop and hitstun ownership for combat.
bool valid
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
bool found
float step
Definition TreeMesh.cpp:314
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
constexpr std::int64_t nanoseconds() const noexcept
Return the exact signed nanosecond representation.
Definition Time.h:69
static constexpr Duration fromNanoseconds(std::int64_t nanoseconds) noexcept
Construct an exact duration from nanoseconds.
Definition Time.h:55
static constexpr Duration zero() noexcept
Return zero duration.
Definition Time.h:60
constexpr bool isZero() const noexcept
Whether this duration is exactly zero.
Definition Time.h:75
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
bool isValid() const noexcept
Return whether this reference is valid and non-nil.
Definition SubjectRef.h:38
HitFeelState state(SubjectRef subject) const
Return an owning snapshot, or empty defaults when the subject has no feel state.
Definition HitFeel.cpp:115
Result< HitFeelAdvance > advance(const SimulationStep &step)
Advance remaining timers with the supplied deterministic step.
Definition HitFeel.cpp:75
bool isFrozen(SubjectRef subject) const noexcept
Whether the subject currently has positive hitstop remaining.
Definition HitFeel.cpp:121
bool isStunned(SubjectRef subject) const noexcept
Whether the subject currently has positive hitstun remaining.
Definition HitFeel.cpp:126
Result< void > apply(HitFeelRequest request)
Apply one validated feel request; overlapping windows take the max remaining.
Definition HitFeel.cpp:25
Result< void > applyFromOutcome(const DamageOutcome &outcome)
Derive a feel request from a damage outcome using fixed reaction tables.
Definition HitFeel.cpp:41
constexpr std::uint64_t value() const noexcept
Returns the underlying value at an explicit protocol boundary.
One deterministic fixed-step emitted by SimulationClock.
Definition Time.h:158
Complete owning audit result of one committed damage transaction.
Definition Damage.h:98
Complete owning result of one feel advance.
Definition HitFeel.h:50
SimulationTick tick
Definition HitFeel.h:51
Authored freeze/stun durations applied after a damage outcome.
Definition HitFeel.h:19
Result< void > validate() const
Validate subjects and finite non-negative durations.
Definition HitFeel.cpp:13
Per-subject freeze or stun remaining after the last commit.
Definition HitFeel.h:32