载入中...
搜索中...
未找到
ThunderStrike.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5
6namespace eve::weather {
7namespace {
8std::uint32_t next(std::uint32_t& state) { state = state * 1664525u + 1013904223u; return state; }
9float unit(std::uint32_t& state) { return float(next(state) >> 8u) * (1.f / 16777216.f); }
10float range(std::uint32_t& state, float a, float b) { return a + (b - a) * unit(state); }
11}
12
14 const ThunderStrikeSettings& settings, float px, float py, float pz, std::uint32_t seed) {
15 if (state.playing) return Result<ThunderStrikeReceipt>::failure(Diagnostic::error(DiagnosticCode::Conflict, "thunder strike is already playing", "weather.thunderStrike"));
16 if (!std::isfinite(px) || !std::isfinite(py) || !std::isfinite(pz) ||
17 !std::isfinite(settings.intensity) || !std::isfinite(settings.radius) ||
18 !std::isfinite(settings.volume) || settings.intensity < 0.f || settings.radius < 0.f ||
19 settings.volume < 0.f || settings.audioClipCount < 0)
20 return Result<ThunderStrikeReceipt>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "thunder strike inputs must be finite and non-negative", "weather.thunderStrike"));
21 std::uint32_t rng = seed;
22 const bool positive = unit(rng) > 0.5f;
24 receipt.x = range(rng, px, px + (positive ? 700.f : -700.f));
25 receipt.y = range(rng, py + 50.f, py + 250.f);
26 receipt.z = range(rng, pz, pz + (positive ? 700.f : -700.f));
27 receipt.intensity = settings.intensity; receipt.radius = settings.radius; receipt.volume = settings.volume;
28 if (settings.audioClipCount > 1)
29 receipt.audioClipIndex = 1 + int(next(rng) % std::uint32_t(settings.audioClipCount - 1));
30 state.playing = true;
31 state.intensity = settings.intensity;
33}
34
36 if (!std::isfinite(dt) || dt < 0.f)
37 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "thunder strike dt must be finite and non-negative", "weather.thunderStrike"));
38 if (!state.playing) return Result<void>::success();
39 state.intensity += (0.f - state.intensity) * std::clamp(dt * 2.f, 0.f, 1.f);
40 if (state.intensity < 0.15f) { state.intensity = 0.f; state.playing = false; }
41 return Result<void>::success();
42}
43} // namespace eve::weather
float py
float pz
std::vector< Colorf > px
Range range
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
std::uint32_t seed
Definition PointSet.cpp:807
TacticalUnit * unit
TerrainThermalSettings settings
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
constexpr HexDirection next(HexDirection d) noexcept
The next direction clockwise (NW wraps to NE).
Definition HexMetrics.h:76
Result< ThunderStrikeReceipt > triggerThunderStrike(ThunderStrikeState &state, const ThunderStrikeSettings &settings, float px, float py, float pz, std::uint32_t seed)
Start a Pcg-style strike around the supplied player position.
Result< void > advanceThunderStrike(ThunderStrikeState &state, float dt)
Apply Pcg's clamped Lerp(intensity,0,dt*2) decay and 0.15 stop threshold.
Deterministic strike command consumed by scene, light and audio providers.
Pcg ThunderStrike parameters independent of renderer and audio providers.
Caller-owned thunder flash state.