载入中...
搜索中...
未找到
WeaponEffects.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5#include <limits>
6#include <utility>
7
8namespace eve::weapon {
9namespace {
10
11const char* kindTag(WeaponEffectKind kind) {
12 switch (kind) {
13 case WeaponEffectKind::Heat: return "weapon:heat";
14 case WeaponEffectKind::Jam: return "weapon:jam";
15 case WeaponEffectKind::Recoil: return "weapon:recoil";
16 }
17 return "weapon:unknown";
18}
19
20bool has(const effects::EffectPeriodicTick& tick, const char* tag) {
21 return std::find(tick.tags.begin(), tick.tags.end(), tag) != tick.tags.end();
22}
23
24} // namespace
25
27 if (!std::isfinite(target.heat) || !std::isfinite(target.maxHeat) || !std::isfinite(target.recoil) ||
28 target.maxHeat <= 0.0 || target.heat < 0.0 || target.heat > target.maxHeat || target.recoil < 0.0)
30 "weapon effect target state is invalid", "target"));
32}
33
35 const effects::EffectInstance& effect) const {
36 auto valid = validate(target);
37 if (!valid) return valid;
38 if (effect.hasTag("weapon:jam")) target.jammed = true;
39 if (effect.hasTag("weapon:recoil")) {
40 if (effect.magnitude > std::numeric_limits<double>::max() - target.recoil)
42 "weapon recoil overflows", "target.recoil"));
43 target.recoil += effect.magnitude;
44 }
46}
47
49 effects::EffectUpdateSummary lifecycle) const {
50 auto valid = validate(target);
52 WeaponEffectUpdate result;
53 result.lifecycle = std::move(lifecycle);
54 for (const auto& tick : result.lifecycle.periodicTicks) {
55 if (tick.stackCount == 0 || !std::isfinite(tick.magnitude) || tick.magnitude < 0.0)
57 eve::DiagnosticCode::InvalidArgument, "weapon periodic effect value is invalid", "periodic"));
58 const double amount = tick.magnitude * static_cast<double>(tick.stackCount);
59 if (!std::isfinite(amount))
61 eve::DiagnosticCode::InvalidArgument, "weapon periodic effect overflows", "periodic"));
62 if (has(tick, "weapon:recoil")) {
63 if (amount > std::numeric_limits<double>::max() - target.recoil)
65 eve::DiagnosticCode::InvalidArgument, "weapon recoil settlement overflows", "target.recoil"));
66 target.recoil += amount;
67 } else if (has(tick, "weapon:jam")) {
68 target.jammed = true;
69 } else {
70 target.heat = std::min(target.maxHeat, target.heat + amount);
71 if (target.heat >= target.maxHeat) {
72 target.jammed = true;
73 ++target.blockedShots;
74 result.jammed = true;
75 }
76 }
77 ++result.settled;
78 }
79 result.jammed = result.jammed || target.jammed;
81}
82
85 if (definition.id.empty() || !subject.isValid())
87 eve::DiagnosticCode::InvalidArgument, "weapon effect requires an id and valid subject", "effect"));
89 common.id = definition.id;
90 common.stackKey = definition.id;
91 common.duration = definition.duration;
92 common.period = definition.period;
93 common.magnitude = definition.magnitude;
94 common.policy = definition.policy;
95 common.tags = definition.tags;
96 common.tags.push_back(kindTag(definition.kind));
97 auto valid = common.validate();
99 auto candidate = container_.clone();
100 auto applied = candidate.apply(common, subject.format(), definition.source);
101 if (!applied) return eve::Result<effects::EffectHandle>::failure(applied.status());
102 const std::string id = std::move(applied).takeValue();
103 const auto* instance = candidate.find(id);
104 if (!instance)
106 eve::DiagnosticCode::InvariantViolation, "weapon effect candidate disappeared", "effect"));
107 auto targetCandidate = target_;
108 auto immediate = executor_.applyImmediate(targetCandidate, *instance);
109 if (!immediate) return eve::Result<effects::EffectHandle>::failure(immediate.status());
110 auto handle = candidate.handleFor(id);
112 target_ = std::move(targetCandidate);
113 container_ = std::move(candidate);
114 return eve::Result<effects::EffectHandle>::success(std::move(handle).takeValue(),
116}
117
119 auto resolved = container_.resolve(handle);
120 if (!resolved) return eve::Result<void>::failure(resolved.status());
121 return container_.remove(handle.instanceId);
122}
123
125 auto candidate = container_.clone();
126 auto lifecycle = effects::EffectExecutor{}.advance(candidate, step);
127 if (!lifecycle) return eve::Result<WeaponEffectUpdate>::failure(lifecycle.status());
128 auto targetCandidate = target_;
129 auto settled = executor_.settle(targetCandidate, std::move(lifecycle).takeValue());
130 if (!settled) return settled;
131 auto result = std::move(settled).takeValue();
132 target_ = std::move(targetCandidate);
133 container_ = std::move(candidate);
135}
136
137WeaponEffectSnapshot WeaponEffectAdapter::snapshot() const { return {container_.snapshot(), target_}; }
138
140 auto valid = executor_.validate(snapshotValue.target);
141 if (!valid) return valid;
142 auto restored = container_.restore(snapshotValue.effects);
143 if (!restored) return restored;
144 target_ = snapshotValue.target;
146}
147
151
152} // namespace eve::weapon
LogicalId target
int subject
Definition AnimSmr.cpp:163
TokenKind kind
bool valid
const std::string * tag
std::unique_ptr< ParticleEffect > effect
PrimitiveHandle handle
SimulationTick tick
float step
Definition TreeMesh.cpp:314
Weapon-domain effect adapter and heat/jam executor.
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
EffectContainer snapshot() const
Capture an independent lifecycle snapshot for staging/restore.
eve::Result< const EffectInstance * > resolve(EffectHandle handle) const
Resolve a generation-qualified handle for this call.
eve::Result< void > remove(const std::string &id, const std::string &reason="removed")
Removes one active instance and emits a Removed event.
EffectContainer clone() const
Create an independent deep copy suitable for ECS staging.
eve::Result< void > restore(const EffectContainer &snapshot)
Restore a previously captured snapshot as one observable commit.
Executes lifecycle time progression for an EffectContainer.
eve::Result< EffectUpdateSummary > advance(EffectContainer &container, double dtSeconds) const
Advances one container by a legacy seconds delta.
eve::Result< void > remove(effects::EffectHandle handle)
Remove one generation-qualified effect handle.
eve::Result< const effects::EffectInstance * > resolve(effects::EffectHandle handle) const
Resolve a live handle as a borrowed observation.
eve::Result< WeaponEffectUpdate > advance(const eve::SimulationStep &step)
Advance and settle weapon effects atomically.
eve::Result< effects::EffectHandle > apply(const WeaponEffectDefinition &definition, eve::SubjectRef subject)
Apply one typed weapon effect to a stable subject.
eve::Result< void > restore(const WeaponEffectSnapshot &snapshot)
Restore a snapshot and invalidate prior handles.
WeaponEffectSnapshot snapshot() const
Capture effects and target state.
eve::Result< void > applyImmediate(WeaponEffectTarget &target, const effects::EffectInstance &effect) const
Apply an immediate jam/recoil strategy to a staged target.
eve::Result< void > validate(const WeaponEffectTarget &target) const
Validate heat and recoil invariants.
eve::Result< WeaponEffectUpdate > settle(WeaponEffectTarget &target, effects::EffectUpdateSummary lifecycle) const
Settle common periodic triggers through weapon policy.
载具模块入口(eve.Vehicle):定义注册 / 实体工厂 / RTS 命令 / 帧调度。 设计文档:docs/dev/通用载具系统设计.md
WeaponEffectKind
Weapon-specific effect strategy.
One deterministic fixed-step emitted by SimulationClock.
Definition Time.h:158
Immutable-by-convention template used to create effect instances.
std::vector< std::string > tags
double period
Period in seconds for domain executor settlement; zero disables periodic ticks.
eve::Result< void > validate() const
Validates definition fields without changing any state.
Generation-qualified local reference to a canonical effect instance.
One owned runtime effect fact.
Summary returned by the lifecycle executor after one simulation step.
std::vector< EffectPeriodicTick > periodicTicks
Periodic triggers in deterministic container order.
Typed weapon definition projected into the common lifecycle.
In-memory weapon effect snapshot.
effects::EffectContainer effects
Mutable weapon state interpreted by the typed executor.
Result of one weapon lifecycle step and domain settlement.
effects::EffectUpdateSummary lifecycle