载入中...
搜索中...
未找到
VehicleEffects.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5#include <utility>
6
7namespace eve::vehicle {
8namespace {
9
10const char* kindTag(VehicleEffectKind kind) {
11 switch (kind) {
12 case VehicleEffectKind::Damage: return "vehicle:damage";
13 case VehicleEffectKind::Repair: return "vehicle:repair";
14 case VehicleEffectKind::Disable: return "vehicle:disable";
15 }
16 return "vehicle:unknown";
17}
18
19double zoneMultiplier(const VehicleEffectTarget& target, const std::vector<std::string>& tags) {
20 const auto has = [&tags](const std::string& tag) { return std::find(tags.begin(), tags.end(), tag) != tags.end(); };
21 if (has("vehicle:zone:front")) return target.frontArmorMultiplier;
22 if (has("vehicle:zone:rear")) return target.rearArmorMultiplier;
23 return target.sideArmorMultiplier;
24}
25
26} // namespace
27
29 if (!std::isfinite(target.hull) || !std::isfinite(target.maxHull) || target.maxHull <= 0.0 || target.hull < 0.0 ||
30 target.hull > target.maxHull || target.frontArmorMultiplier < 0.0 || target.sideArmorMultiplier < 0.0 ||
31 target.rearArmorMultiplier < 0.0)
33 "vehicle effect target state is invalid", "target"));
35}
36
44
46 effects::EffectUpdateSummary lifecycle) const {
47 auto valid = validate(target);
50 result.lifecycle = std::move(lifecycle);
51 for (const auto& tick : result.lifecycle.periodicTicks) {
52 if (tick.stackCount == 0 || tick.magnitude < 0.0 || !std::isfinite(tick.magnitude))
54 eve::DiagnosticCode::InvalidArgument, "vehicle periodic effect value is invalid", "periodic"));
55 const double amount = tick.magnitude * static_cast<double>(tick.stackCount);
56 if (!std::isfinite(amount))
58 eve::DiagnosticCode::InvalidArgument, "vehicle periodic settlement overflows", "periodic"));
59 const auto has = [&tick](const char* tag) {
60 return std::find(tick.tags.begin(), tick.tags.end(), tag) != tick.tags.end();
61 };
62 if (has("vehicle:repair")) {
63 target.hull = std::min(target.maxHull, target.hull + amount);
64 } else if (has("vehicle:disable")) {
65 target.disabled = true;
66 } else {
67 const double damage = amount * zoneMultiplier(target, tick.tags);
68 if (!std::isfinite(damage))
70 eve::DiagnosticCode::InvalidArgument, "vehicle armor settlement overflows", "periodic"));
71 target.hull = std::max(0.0, target.hull - damage);
72 if (damage >= target.maxHull * 0.5) {
73 ++target.criticalHits;
74 ++result.criticalHits;
75 }
76 }
77 ++result.settled;
78 }
80}
81
84 if (definition.id.empty() || !subject.isValid() || definition.armorZone.empty())
86 eve::DiagnosticCode::InvalidArgument, "vehicle effect requires id, zone and valid subject", "effect"));
88 common.id = definition.id;
89 common.stackKey = definition.id;
90 common.duration = definition.duration;
91 common.period = definition.period;
92 common.magnitude = definition.magnitude;
93 common.policy = definition.policy;
94 common.tags = definition.tags;
95 common.tags.push_back(kindTag(definition.kind));
96 common.tags.push_back("vehicle:zone:" + definition.armorZone);
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, "vehicle 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<VehicleEffectUpdate>::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
137VehicleEffectSnapshot VehicleEffectAdapter::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::vehicle
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
Vehicle-domain effect adapter and armor-zone 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.
VehicleEffectSnapshot snapshot() const
Capture effects and target state.
eve::Result< void > restore(const VehicleEffectSnapshot &snapshot)
Restore a snapshot and invalidate prior handles.
eve::Result< const effects::EffectInstance * > resolve(effects::EffectHandle handle) const
Resolve a live handle as a borrowed observation.
eve::Result< VehicleEffectUpdate > advance(const eve::SimulationStep &step)
Advance and settle vehicle effects atomically.
eve::Result< effects::EffectHandle > apply(const VehicleEffectDefinition &definition, eve::SubjectRef subject)
Apply one typed vehicle effect to a stable subject.
eve::Result< void > remove(effects::EffectHandle handle)
Remove one generation-qualified effect handle.
eve::Result< VehicleEffectUpdate > settle(VehicleEffectTarget &target, effects::EffectUpdateSummary lifecycle) const
Settle common periodic triggers through vehicle armor policy.
eve::Result< void > validate(const VehicleEffectTarget &target) const
Validate hull and armor invariants.
eve::Result< void > applyImmediate(VehicleEffectTarget &target, const effects::EffectInstance &effect) const
Apply an immediate disable strategy to a staged target.
驾驶者接口与玩家控制状态。
VehicleEffectKind
Vehicle-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.
Strong vehicle definition projected into the common lifecycle.
In-memory vehicle effect snapshot.
effects::EffectContainer effects
Mutable vehicle state changed by the effect executor.
Result of one vehicle lifecycle step and armor settlement.
effects::EffectUpdateSummary lifecycle