Commit Graph

4 Commits

Author SHA1 Message Date
kayjaydee ddc08fb14c feat(04-01): add VolumeCurve with hardcoded VFX-02 spec curve
- VolumeCurve.volumeFor(int) returns spec values [1.0, 0.8, 0.6, 0.5, 0.4]
- High indices clamp to 0.4f (last value)
- Negative indices throw IllegalArgumentException
- 3 JUnit cases (specValues, indexClamp, negativeIndexThrows), all green
- Zero Hytale imports — chain/ frontier preserved
2026-04-27 13:01:38 +02:00
kayjaydee 8d868a28ca feat(04-01): add Vec3.lerp and ParticleTrail sampler with JUnit suite
- Vec3.lerp(other, t) for linear interpolation between two points
- ParticleTrail.sample(from, to, density) emits density-based interpolated
  points strictly between endpoints (endpoints excluded by construction)
- TRAIL_DENSITY = 4.0 particles per block
- 6 ParticleTrail tests + 3 Vec3.lerp tests, all green
- Zero Hytale imports — chain/ frontier preserved
2026-04-27 13:00:47 +02:00
kayjaydee 8725b8a1c7 feat(phase-3): runtime integration — chain damage application + cooldown
Wires the pure ChainResolver (Phase 2) to the live Hytale runtime via
four sceptre/ adapters:
- HytaleEntityAdapter — eager snapshot Ref<EntityStore> -> ChainEntity
  via TransformComponent.getPosition() and EntityStatMap.get(health) > 0
- HytalePlayerRayCaster — captures playerRef, delegates to
  TargetUtil.getTargetEntity (auto eye-origin + head-rotation)
- HytaleEntitySource — wraps TargetUtil.getAllEntitiesInSphere
- ChainDamageApplier — fires DamageSystems.executeDamage per hit;
  injectable DamageExecutor SAM keeps the helper unit-testable.

ChainLightningSceptreInteraction.firstRun is rewritten end-to-end:
cooldown gate (hasCooldown(false) -> deductCharge() only on success),
ray-cast -> BFS -> damage application, structured logging, try/catch
wrapper to keep a runtime fault from killing the server tick.

API corrections discovered against the decompiled jar:
- Ref has no uuid() — use "ref:" + getIndex() for the chain id
- DamageCause.PHYSICAL is @Nullable until runtime — use the int-index
  overload of Damage with index 0
- Static mock of DamageSystems crashes class init — abstracted behind
  a DamageExecutor SAM with a default lazy holder

Tests: 33/33 green (25 from Phase 2 + 4 ChainDamageApplier tests +
4 fixture sanity). ./gradlew build SUCCESSFUL, JAR auto-deployed.
MANUAL UAT (10 items) pending in-game.
2026-04-27 12:14:58 +02:00
kayjaydee cd5d0bedd3 feat(phase-2): pure-Java chain resolution algorithm
Adds com.mythlane.chainlightning.chain package with 7 types (Vec3,
ChainEntity, EntitySource, RayCaster, ChainParameters, ChainHit,
ChainResolver). Algorithm: ray-cast primary target then BFS hops with
distanceSquared closest-neighbor selection, deterministic lexicographic
tie-breaker on entity id, max 5 targets, 8-block radius, damage curve
[8,6,4,3,2]. Strict no-Hytale-imports boundary — runtime adapters land
in Phase 3.

JUnit 5 suite: 25 tests green (Vec3 5 + ChainParameters 10 +
ChainResolver 10). All 10 mandatory cases covered (no primary,
primary-only, full chain, overflow, out-of-radius, no-double-hit,
closest, tie-breaker determinism, dead entity, custom maxTargets).
2026-04-26 19:29:20 +02:00