Завершить инженерный кандидат Stage 5

This commit is contained in:
2026-08-19 02:04:45 +03:00
parent b840684ef3
commit cde886ca96
45 changed files with 3236 additions and 98 deletions
@@ -0,0 +1,168 @@
package com.projectsacrifice.game;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/** Immutable puzzle-critical state used by versioned activity restoration. */
public final class GameSessionSnapshot {
public static final class PlayerData {
private final float x, y, velocityX, velocityY;
private final boolean alive, onGround;
private final float coyoteSeconds, jumpBufferSeconds;
private final int supportIndex, facing;
public PlayerData(float x, float y, float velocityX, float velocityY,
boolean alive, boolean onGround, float coyoteSeconds,
float jumpBufferSeconds, int supportIndex, int facing) {
this.x = x;
this.y = y;
this.velocityX = velocityX;
this.velocityY = velocityY;
this.alive = alive;
this.onGround = onGround;
this.coyoteSeconds = coyoteSeconds;
this.jumpBufferSeconds = jumpBufferSeconds;
this.supportIndex = supportIndex;
this.facing = facing < 0 ? -1 : 1;
}
public float x() { return x; }
public float y() { return y; }
public float velocityX() { return velocityX; }
public float velocityY() { return velocityY; }
public boolean alive() { return alive; }
public boolean onGround() { return onGround; }
public float coyoteSeconds() { return coyoteSeconds; }
public float jumpBufferSeconds() { return jumpBufferSeconds; }
public int supportIndex() { return supportIndex; }
public int facing() { return facing; }
}
public static final class BodyData {
private final float x, y, width, height, velocityX, velocityY;
private final boolean frozen, conductive, pinned, grounded;
private final int supportIndex;
private final String deathType;
public BodyData(float x, float y, float width, float height,
float velocityX, float velocityY, boolean frozen,
boolean conductive, boolean pinned, boolean grounded,
int supportIndex, String deathType) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.velocityX = velocityX;
this.velocityY = velocityY;
this.frozen = frozen;
this.conductive = conductive;
this.pinned = pinned;
this.grounded = grounded;
this.supportIndex = supportIndex;
this.deathType = deathType == null ? "SPIKE" : deathType;
}
public float x() { return x; }
public float y() { return y; }
public float width() { return width; }
public float height() { return height; }
public float velocityX() { return velocityX; }
public float velocityY() { return velocityY; }
public boolean frozen() { return frozen; }
public boolean conductive() { return conductive; }
public boolean pinned() { return pinned; }
public boolean grounded() { return grounded; }
public int supportIndex() { return supportIndex; }
public String deathType() { return deathType; }
}
public static final class Builder {
private int saveVersion = VersionedSessionCodec.CURRENT_VERSION;
private final int levelNumber;
private float elapsedSeconds;
private int deaths;
private float respawnSeconds;
private PlayerData player = new PlayerData(
0f, 0f, 0f, 0f, true, false, 0f, 0f, -1, 1);
private final ArrayList<BodyData> bodies = new ArrayList<>();
private final ArrayList<Float> platformMotionTimes = new ArrayList<>();
private final LinkedHashMap<String, Boolean> toggleSignals = new LinkedHashMap<>();
private final LinkedHashMap<String, Float> timedSignals = new LinkedHashMap<>();
private final LinkedHashMap<String, Boolean> previousSwitchContacts =
new LinkedHashMap<>();
private Builder(int levelNumber) {
this.levelNumber = levelNumber;
}
Builder saveVersion(int version) { saveVersion = version; return this; }
public Builder elapsedSeconds(float value) { elapsedSeconds = value; return this; }
public Builder deaths(int value) { deaths = value; return this; }
public Builder respawnSeconds(float value) { respawnSeconds = value; return this; }
public Builder player(PlayerData value) { player = value; return this; }
public Builder addBody(BodyData value) { bodies.add(value); return this; }
public Builder platformMotionTimes(List<Float> values) {
platformMotionTimes.clear();
if (values != null) platformMotionTimes.addAll(values);
return this;
}
public Builder toggleSignal(String key, boolean value) {
toggleSignals.put(key, value);
return this;
}
public Builder timedSignal(String key, float value) {
timedSignals.put(key, value);
return this;
}
public Builder previousSwitchContact(String key, boolean value) {
previousSwitchContacts.put(key, value);
return this;
}
public GameSessionSnapshot build() { return new GameSessionSnapshot(this); }
}
private final int saveVersion;
private final int levelNumber;
private final float elapsedSeconds;
private final int deaths;
private final float respawnSeconds;
private final PlayerData player;
private final List<BodyData> bodies;
private final List<Float> platformMotionTimes;
private final Map<String, Boolean> toggleSignals;
private final Map<String, Float> timedSignals;
private final Map<String, Boolean> previousSwitchContacts;
private GameSessionSnapshot(Builder builder) {
saveVersion = builder.saveVersion;
levelNumber = builder.levelNumber;
elapsedSeconds = builder.elapsedSeconds;
deaths = builder.deaths;
respawnSeconds = builder.respawnSeconds;
player = builder.player;
bodies = Collections.unmodifiableList(new ArrayList<>(builder.bodies));
platformMotionTimes = Collections.unmodifiableList(
new ArrayList<>(builder.platformMotionTimes));
toggleSignals = Collections.unmodifiableMap(
new LinkedHashMap<>(builder.toggleSignals));
timedSignals = Collections.unmodifiableMap(new LinkedHashMap<>(builder.timedSignals));
previousSwitchContacts = Collections.unmodifiableMap(
new LinkedHashMap<>(builder.previousSwitchContacts));
}
public static Builder builder(int levelNumber) { return new Builder(levelNumber); }
public int saveVersion() { return saveVersion; }
public int levelNumber() { return levelNumber; }
public float elapsedSeconds() { return elapsedSeconds; }
public int deaths() { return deaths; }
public float respawnSeconds() { return respawnSeconds; }
public PlayerData player() { return player; }
public List<BodyData> bodies() { return bodies; }
public List<Float> platformMotionTimes() { return platformMotionTimes; }
public Map<String, Boolean> toggleSignals() { return toggleSignals; }
public Map<String, Float> timedSignals() { return timedSignals; }
public Map<String, Boolean> previousSwitchContacts() { return previousSwitchContacts; }
}