feat(02-01): add GravityFlipRegion POJO + BuilderCodec with round-trip tests
- GravityFlipRegion holds Name (String) + Box (Hytale AABB) + Enabled (boolean), serialised through a BuilderCodec keyed on "Name"/"Box"/"Enabled". - Validators.nonNull() applied to Name and Box (correct package is com.hypixel.hytale.codec.validation.Validators, not codec.builder). - Server jar 2026.03.26 uses com.hypixel.hytale.math.vector.Vector3d for Box.min/max (NOT org.joml.Vector3d, which only appeared in newer builds). - 3 JUnit 5 round-trip tests cover name/box/enabled, enabled=false, and empty name. - testImplementation added for the Server artifact so codec encode/decode is reachable from unit tests.
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
package com.mythlane.gravityflip.region;
|
||||
|
||||
import com.hypixel.hytale.codec.Codec;
|
||||
import com.hypixel.hytale.codec.KeyedCodec;
|
||||
import com.hypixel.hytale.codec.builder.BuilderCodec;
|
||||
import com.hypixel.hytale.codec.validation.Validators;
|
||||
import com.hypixel.hytale.math.shape.Box;
|
||||
import com.hypixel.hytale.math.vector.Vector3d;
|
||||
|
||||
/**
|
||||
* A named axis-aligned region in which gravity is inverted for any entity inside.
|
||||
*
|
||||
* <p>Persisted as part of {@code GravityFlipConfig} via {@link #CODEC}. The region
|
||||
* is stored on disk as three keys:
|
||||
* <ul>
|
||||
* <li>{@code Name} — non-null string identifier</li>
|
||||
* <li>{@code Box} — non-null AABB (composed of two {@code Vector3d} corners)</li>
|
||||
* <li>{@code Enabled} — boolean toggle, default {@code true}</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Note: this build pins {@code com.hypixel.hytale:Server:2026.03.26-89796e57b}, in which
|
||||
* {@code Box.min}/{@code Box.max} are {@code com.hypixel.hytale.math.vector.Vector3d}
|
||||
* (Hytale's own type — NOT {@code org.joml.Vector3d}, which only appeared in later builds).
|
||||
*
|
||||
* <p>Fields are package-private mutable so the codec can write into them directly,
|
||||
* mirroring the canonical {@code MythLoggerConfig} pattern. Public getters/setters
|
||||
* are provided for runtime callers (Phase 4 commands).
|
||||
*/
|
||||
public final class GravityFlipRegion {
|
||||
|
||||
public static final BuilderCodec<GravityFlipRegion> CODEC =
|
||||
BuilderCodec.builder(GravityFlipRegion.class, GravityFlipRegion::new)
|
||||
.append(new KeyedCodec<>("Name", Codec.STRING),
|
||||
(r, v) -> r.name = v, r -> r.name)
|
||||
.addValidator(Validators.nonNull()).add()
|
||||
.append(new KeyedCodec<>("Box", Box.CODEC),
|
||||
(r, v) -> r.box = v, r -> r.box)
|
||||
.addValidator(Validators.nonNull()).add()
|
||||
.append(new KeyedCodec<>("Enabled", Codec.BOOLEAN),
|
||||
(r, v) -> r.enabled = v, r -> r.enabled).add()
|
||||
.build();
|
||||
|
||||
// Package-private mutable fields written directly by the codec setters.
|
||||
String name = "";
|
||||
Box box = new Box(new Vector3d(), new Vector3d());
|
||||
boolean enabled = true;
|
||||
|
||||
public GravityFlipRegion() {}
|
||||
|
||||
public GravityFlipRegion(String name, Box box, boolean enabled) {
|
||||
this.name = name;
|
||||
this.box = box;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getName() { return name; }
|
||||
public Box getBox() { return box; }
|
||||
public Vector3d getMin() { return box.min; }
|
||||
public Vector3d getMax() { return box.max; }
|
||||
public boolean isEnabled() { return enabled; }
|
||||
|
||||
public void setName(String n) { this.name = n; }
|
||||
public void setBox(Box b) { this.box = b; }
|
||||
public void setEnabled(boolean v) { this.enabled = v; }
|
||||
|
||||
/** Convenience accessor for tick-loop / physics consumers in Phase 02-02. */
|
||||
public Box asBox() { return box; }
|
||||
}
|
||||
Reference in New Issue
Block a user