227 lines
10 KiB
Java
227 lines
10 KiB
Java
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, crushed, burned;
|
|
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, y, width, height, velocityX, velocityY, frozen, conductive,
|
|
pinned, grounded, false, false, supportIndex, deathType);
|
|
}
|
|
|
|
public BodyData(float x, float y, float width, float height,
|
|
float velocityX, float velocityY, boolean frozen,
|
|
boolean conductive, boolean pinned, boolean grounded,
|
|
boolean crushed, boolean burned,
|
|
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.crushed = crushed;
|
|
this.burned = burned;
|
|
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 boolean crushed() { return crushed; }
|
|
public boolean burned() { return burned; }
|
|
public int supportIndex() { return supportIndex; }
|
|
public String deathType() { return deathType; }
|
|
}
|
|
|
|
public static final class ObjectData {
|
|
private final LevelDefinition.PhysicalObjectType type;
|
|
private final float x, y, width, height, velocityX, velocityY;
|
|
private final int mass;
|
|
private final boolean grounded;
|
|
private final int supportIndex;
|
|
|
|
public ObjectData(LevelDefinition.PhysicalObjectType type,
|
|
float x, float y, float width, float height,
|
|
float velocityX, float velocityY, int mass,
|
|
boolean grounded, int supportIndex) {
|
|
this.type = type;
|
|
this.x = x;
|
|
this.y = y;
|
|
this.width = width;
|
|
this.height = height;
|
|
this.velocityX = velocityX;
|
|
this.velocityY = velocityY;
|
|
this.mass = mass;
|
|
this.grounded = grounded;
|
|
this.supportIndex = supportIndex;
|
|
}
|
|
|
|
public LevelDefinition.PhysicalObjectType type() { return type; }
|
|
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 int mass() { return mass; }
|
|
public boolean grounded() { return grounded; }
|
|
public int supportIndex() { return supportIndex; }
|
|
}
|
|
|
|
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 boolean collectibleFound;
|
|
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<ObjectData> objects = 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 collectibleFound(boolean value) { collectibleFound = value; return this; }
|
|
public Builder player(PlayerData value) { player = value; return this; }
|
|
public Builder addBody(BodyData value) { bodies.add(value); return this; }
|
|
public Builder addObject(ObjectData value) { objects.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 boolean collectibleFound;
|
|
private final PlayerData player;
|
|
private final List<BodyData> bodies;
|
|
private final List<ObjectData> objects;
|
|
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;
|
|
collectibleFound = builder.collectibleFound;
|
|
player = builder.player;
|
|
bodies = Collections.unmodifiableList(new ArrayList<>(builder.bodies));
|
|
objects = Collections.unmodifiableList(new ArrayList<>(builder.objects));
|
|
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 boolean collectibleFound() { return collectibleFound; }
|
|
public PlayerData player() { return player; }
|
|
public List<BodyData> bodies() { return bodies; }
|
|
public List<ObjectData> objects() { return objects; }
|
|
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; }
|
|
}
|