Files
goon-game/app/src/main/java/com/projectsacrifice/game/GameSessionSnapshot.java
T

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; }
}