feat(03-05): ajoute 4 champs Visual* optionnels + round-trip tests (Task 1)
- GravityFlipRegion: VisualColor/VisualMode/VisualRefreshMs/VisualOpacity avec defaults (#00FFFF, Outline, 1000, 0.5), getters/setters, javadoc. - CODEC: 4 KeyedCodec optionnels (pas de validator nonNull) => back-compat legacy regions.json. - 2 tests round-trip (custom + defaults quand champs absents).
This commit is contained in:
@@ -29,6 +29,16 @@ import com.hypixel.hytale.math.vector.Vector3d;
|
|||||||
* NPCs in-region are NOT flipped / seeded.</li>
|
* NPCs in-region are NOT flipped / seeded.</li>
|
||||||
* <li>{@code AffectItems} — <b>optional</b>, default {@code true}. If {@code false},
|
* <li>{@code AffectItems} — <b>optional</b>, default {@code true}. If {@code false},
|
||||||
* item {@code PhysicsValues.invertedGravity} is NOT mutated.</li>
|
* item {@code PhysicsValues.invertedGravity} is NOT mutated.</li>
|
||||||
|
* <li>{@code VisualColor} — <b>optional</b> (Plan 03-05). Default {@code "#00FFFF"} (cyan).
|
||||||
|
* Hex string {@code #RRGGBB} rendered as debug cube color. Fallback to cyan on invalid hex
|
||||||
|
* (parsing + validation lives in {@code RegionVisualizer}, NOT here).</li>
|
||||||
|
* <li>{@code VisualMode} — <b>optional</b>, default {@code "Outline"}. One of
|
||||||
|
* {@code "Outline"} / {@code "Faces"} / {@code "Both"} / {@code "None"}. Unknown value
|
||||||
|
* falls back to {@code "Outline"}.</li>
|
||||||
|
* <li>{@code VisualRefreshMs} — <b>optional</b>, default {@code 1000}. Emission period in ms
|
||||||
|
* for the debug shape (refresh cadence ; TTL = refreshMs * 1.2 to avoid flicker).</li>
|
||||||
|
* <li>{@code VisualOpacity} — <b>optional</b>, default {@code 0.5}. Cube opacity in
|
||||||
|
* {@code [0.0, 1.0]} (clamped in {@code RegionVisualizer}).</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p><b>Back-compat :</b> a legacy {@code regions.json} containing only Name+Box+Enabled
|
* <p><b>Back-compat :</b> a legacy {@code regions.json} containing only Name+Box+Enabled
|
||||||
@@ -69,6 +79,15 @@ public final class GravityFlipRegion {
|
|||||||
(r, v) -> r.affectNpcs = v, r -> r.affectNpcs).add()
|
(r, v) -> r.affectNpcs = v, r -> r.affectNpcs).add()
|
||||||
.append(new KeyedCodec<>("AffectItems", Codec.BOOLEAN),
|
.append(new KeyedCodec<>("AffectItems", Codec.BOOLEAN),
|
||||||
(r, v) -> r.affectItems = v, r -> r.affectItems).add()
|
(r, v) -> r.affectItems = v, r -> r.affectItems).add()
|
||||||
|
// --- Plan 03-05 : 4 optional visualization fields ---
|
||||||
|
.append(new KeyedCodec<>("VisualColor", Codec.STRING),
|
||||||
|
(r, v) -> r.visualColor = v, r -> r.visualColor).add()
|
||||||
|
.append(new KeyedCodec<>("VisualMode", Codec.STRING),
|
||||||
|
(r, v) -> r.visualMode = v, r -> r.visualMode).add()
|
||||||
|
.append(new KeyedCodec<>("VisualRefreshMs", Codec.INTEGER),
|
||||||
|
(r, v) -> r.visualRefreshMs = v, r -> r.visualRefreshMs).add()
|
||||||
|
.append(new KeyedCodec<>("VisualOpacity", Codec.DOUBLE),
|
||||||
|
(r, v) -> r.visualOpacity = v, r -> r.visualOpacity).add()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Package-private mutable fields written directly by the codec setters.
|
// Package-private mutable fields written directly by the codec setters.
|
||||||
@@ -84,6 +103,12 @@ public final class GravityFlipRegion {
|
|||||||
boolean affectNpcs = true;
|
boolean affectNpcs = true;
|
||||||
boolean affectItems = true;
|
boolean affectItems = true;
|
||||||
|
|
||||||
|
// Plan 03-05 : visualization fields — defaults applied when key absent in BSON.
|
||||||
|
String visualColor = "#00FFFF";
|
||||||
|
String visualMode = "Outline";
|
||||||
|
int visualRefreshMs = 1000;
|
||||||
|
double visualOpacity = 0.5;
|
||||||
|
|
||||||
public GravityFlipRegion() {}
|
public GravityFlipRegion() {}
|
||||||
|
|
||||||
public GravityFlipRegion(String name, Box box, boolean enabled) {
|
public GravityFlipRegion(String name, Box box, boolean enabled) {
|
||||||
@@ -118,6 +143,18 @@ public final class GravityFlipRegion {
|
|||||||
public void setAffectNpcs(boolean v) { this.affectNpcs = v; }
|
public void setAffectNpcs(boolean v) { this.affectNpcs = v; }
|
||||||
public void setAffectItems(boolean v) { this.affectItems = v; }
|
public void setAffectItems(boolean v) { this.affectItems = v; }
|
||||||
|
|
||||||
|
// --- Plan 03-05 getters / setters ---
|
||||||
|
|
||||||
|
public String getVisualColor() { return visualColor; }
|
||||||
|
public String getVisualMode() { return visualMode; }
|
||||||
|
public int getVisualRefreshMs() { return visualRefreshMs; }
|
||||||
|
public double getVisualOpacity() { return visualOpacity; }
|
||||||
|
|
||||||
|
public void setVisualColor(String v) { this.visualColor = v; }
|
||||||
|
public void setVisualMode(String v) { this.visualMode = v; }
|
||||||
|
public void setVisualRefreshMs(int v) { this.visualRefreshMs = v; }
|
||||||
|
public void setVisualOpacity(double v) { this.visualOpacity = v; }
|
||||||
|
|
||||||
/** Convenience accessor for tick-loop / physics consumers in Phase 02-02. */
|
/** Convenience accessor for tick-loop / physics consumers in Phase 02-02. */
|
||||||
public Box asBox() { return box; }
|
public Box asBox() { return box; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,6 +144,41 @@ class GravityFlipRegionCodecTest {
|
|||||||
assertFalse(decoded.isAffectItems());
|
assertFalse(decoded.isAffectItems());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- Plan 03-05 : 4 visualization fields ----------
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void roundTripPreservesVisualFields() {
|
||||||
|
GravityFlipRegion src = baseRegion();
|
||||||
|
src.setVisualColor("#FF8800");
|
||||||
|
src.setVisualMode("Faces");
|
||||||
|
src.setVisualRefreshMs(500);
|
||||||
|
src.setVisualOpacity(0.75);
|
||||||
|
|
||||||
|
GravityFlipRegion decoded = roundTrip(src);
|
||||||
|
|
||||||
|
assertEquals("#FF8800", decoded.getVisualColor());
|
||||||
|
assertEquals("Faces", decoded.getVisualMode());
|
||||||
|
assertEquals(500, decoded.getVisualRefreshMs());
|
||||||
|
assertEquals(0.75, decoded.getVisualOpacity(), 1e-9);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void roundTripPreservesVisualDefaultsWhenFieldsAbsent() {
|
||||||
|
// Region construite via constructeur legacy 3-arg — simule un regions.json legacy
|
||||||
|
// (ni 03-04 ni 03-05 présents).
|
||||||
|
GravityFlipRegion src = new GravityFlipRegion(
|
||||||
|
"legacy-viz",
|
||||||
|
new Box(new Vector3d(0, 0, 0), new Vector3d(1, 1, 1)),
|
||||||
|
true);
|
||||||
|
|
||||||
|
GravityFlipRegion decoded = roundTrip(src);
|
||||||
|
|
||||||
|
assertEquals("#00FFFF", decoded.getVisualColor(), "default VisualColor=#00FFFF (cyan)");
|
||||||
|
assertEquals("Outline", decoded.getVisualMode(), "default VisualMode=Outline");
|
||||||
|
assertEquals(1000, decoded.getVisualRefreshMs(), "default VisualRefreshMs=1000");
|
||||||
|
assertEquals(0.5, decoded.getVisualOpacity(), 1e-9, "default VisualOpacity=0.5");
|
||||||
|
}
|
||||||
|
|
||||||
private static GravityFlipRegion baseRegion() {
|
private static GravityFlipRegion baseRegion() {
|
||||||
return new GravityFlipRegion(
|
return new GravityFlipRegion(
|
||||||
"r",
|
"r",
|
||||||
|
|||||||
Reference in New Issue
Block a user