Fix: all JavaDOC completed
This commit is contained in:
@@ -18,7 +18,10 @@ public class ClientLauncherGUI {
|
||||
System.setProperty("glass.win.uiScale", "1.0");
|
||||
Application.launch(GUIApp.class, args);
|
||||
}
|
||||
//TODO
|
||||
/**
|
||||
* Inner {@link Application} subclass that wires the GUI to the client controller
|
||||
* and hands off control to {@link GUI#start(Stage)}.
|
||||
*/
|
||||
public static class GUIApp extends Application {
|
||||
@Override
|
||||
public void start(Stage stage) throws Exception {
|
||||
|
||||
@@ -25,13 +25,13 @@ import static org.jline.builtins.Completers.TreeCompleter.node;
|
||||
* Handles login, connects to the server, and drives the JLine-powered command loop.
|
||||
*/
|
||||
public class ClientLauncherTUI {
|
||||
//TODO
|
||||
/** TUI view shared with the client controller. */
|
||||
private TUI view;
|
||||
//TODO
|
||||
/** JLine terminal used for all input/output. */
|
||||
private Terminal terminal;
|
||||
//TODO
|
||||
/** Line reader used during active gameplay, with tab-completion wired. */
|
||||
private LineReader gameReader;
|
||||
//TODO
|
||||
/** Username of the currently logged-in player; empty string before login. */
|
||||
private String currentUsername = "";
|
||||
|
||||
private static final String BUILDING_DETAILS =
|
||||
@@ -81,7 +81,12 @@ public class ClientLauncherTUI {
|
||||
"HUNTERS — Adding a Hunter without the \uD83C\uDF56 icon: nothing. Adding a Hunter WITH the \uD83C\uDF56 icon:\n" +
|
||||
" immediately take 1 \uD83C\uDF56 for each Hunter in your tribe (with or without the icon).\n" +
|
||||
" During Hunt Event, take \uD83C\uDF56 and gain PP based on your Hunter count (see 'details events').";
|
||||
//TODO
|
||||
/**
|
||||
* Launches the TUI client.
|
||||
*
|
||||
* @param args command-line arguments (unused).
|
||||
* @throws InterruptedException if the thread is interrupted during startup.
|
||||
*/
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
new ClientLauncherTUI().start();
|
||||
}
|
||||
@@ -132,7 +137,12 @@ public class ClientLauncherTUI {
|
||||
}
|
||||
}
|
||||
}
|
||||
//TODO
|
||||
/**
|
||||
* Prompts for username, player count, network type, and server IP, then connects.
|
||||
*
|
||||
* @param controller the client controller to connect.
|
||||
* @return {@code true} on successful connection; {@code false} if input is invalid or connection fails.
|
||||
*/
|
||||
private boolean doLogin(ClientController controller) {
|
||||
LineReader loginReader = LineReaderBuilder.builder()
|
||||
.terminal(terminal)
|
||||
@@ -202,7 +212,12 @@ public class ClientLauncherTUI {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//TODO
|
||||
/**
|
||||
* Builds the JLine {@link LineReader} used during gameplay, with tab-completion
|
||||
* for all valid commands.
|
||||
*
|
||||
* @return the configured {@link LineReader}.
|
||||
*/
|
||||
private LineReader buildGameReader() {
|
||||
Completer completer = new TreeCompleter(
|
||||
node("slot"),
|
||||
@@ -227,7 +242,12 @@ public class ClientLauncherTUI {
|
||||
.option(LineReader.Option.DISABLE_EVENT_EXPANSION, true)
|
||||
.build();
|
||||
}
|
||||
//TODO
|
||||
/**
|
||||
* Returns the command-line prompt string showing the current username.
|
||||
*
|
||||
* @param controller the client controller (reserved for future use).
|
||||
* @return the prompt string.
|
||||
*/
|
||||
private String buildPrompt(ClientController controller) {
|
||||
return currentUsername.isEmpty() ? "> " : currentUsername + "> ";
|
||||
}
|
||||
@@ -279,7 +299,12 @@ public class ClientLauncherTUI {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//TODO
|
||||
/**
|
||||
* Handles the {@code draw} command, dispatching to the appropriate controller draw method.
|
||||
*
|
||||
* @param parts the tokenised command: {@code [draw, upper|lower, tribe|building, pos]}.
|
||||
* @param controller the client controller to invoke.
|
||||
*/
|
||||
private void handleDraw(String[] parts, ClientController controller) {
|
||||
if (parts.length < 4) {
|
||||
view.showError(ErrorType.GENERIC_ERROR, "Usage: draw upper|lower tribe|building <pos>");
|
||||
@@ -295,11 +320,21 @@ public class ClientLauncherTUI {
|
||||
else if (tribe) controller.drawLowerTribeCard(pos);
|
||||
else controller.drawLowerBuildingCard(pos);
|
||||
}
|
||||
//TODO
|
||||
/**
|
||||
* Handles the {@code clear} command by triggering a full board re-render.
|
||||
*
|
||||
* @param parts the tokenised command (only the command token is used).
|
||||
*/
|
||||
private void handleRender(String[] parts) {
|
||||
view.renderBoard();
|
||||
}
|
||||
//TODO
|
||||
/**
|
||||
* Parses an integer position argument at {@code idx} in {@code parts}.
|
||||
*
|
||||
* @param parts the tokenised command array.
|
||||
* @param idx index of the position argument.
|
||||
* @return the parsed integer, or {@code -1} if missing or malformed.
|
||||
*/
|
||||
private int parsePos(String[] parts, int idx) {
|
||||
if (parts.length <= idx) {
|
||||
view.showError(ErrorType.GENERIC_ERROR, "Missing position argument.");
|
||||
@@ -313,7 +348,11 @@ public class ClientLauncherTUI {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
//TODO
|
||||
/**
|
||||
* Disconnects the client if one is currently connected; safe to call when already disconnected.
|
||||
*
|
||||
* @param controller the client controller to disconnect.
|
||||
*/
|
||||
private void safeQuit(ClientController controller) {
|
||||
if (controller.getClient() != null) controller.disconnect();
|
||||
}
|
||||
|
||||
@@ -2,19 +2,39 @@ package it.polimi.ingsw.gc14;
|
||||
|
||||
/** Enumeration of error types that can be returned by server-side operations. */
|
||||
public enum ErrorType {
|
||||
/** The requested user does not exist. */
|
||||
USER_NOT_FOUND("User not found"),
|
||||
/** The chosen username is already taken by another connected player. */
|
||||
USERNAME_ALREADY_USED("Username is already in use"),
|
||||
/** The user is already connected to the server. */
|
||||
USER_ALREADY_CONNECTED("User is already connected"),
|
||||
/** The requested number of players is outside the allowed range. */
|
||||
WRONG_PLAYER_NUMBER("Wrong player number"),
|
||||
/** The server has crashed or become unreachable. */
|
||||
SERVER_CRASHED("Server crashed"),
|
||||
/** A generic, unclassified error occurred. */
|
||||
GENERIC_ERROR("Generic error"),
|
||||
/** The game has already started and cannot accept new players. */
|
||||
GAME_ALREADY_STARTED("Game already started"),
|
||||
/** The action attempted is not valid in the current game state. */
|
||||
WRONG_ACTION("Wrong action");
|
||||
//TODO
|
||||
/** Human-readable description of this error, returned by {@link #toString()}. */
|
||||
private final String description;
|
||||
|
||||
/**
|
||||
* Creates an error type constant with the given human-readable description.
|
||||
*
|
||||
* @param description the message returned by {@link #toString()}.
|
||||
*/
|
||||
ErrorType(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the human-readable description of this error.
|
||||
*
|
||||
* @return the error description string.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return description;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class GameEventProcessor {
|
||||
|
||||
/**
|
||||
* Handle to the running forfeit timer, or {@code null} when no timer is active.
|
||||
* A non-null value signals that the game is in the {@em suspended} state.
|
||||
* A non-null value signals that the game is in the suspended state.
|
||||
*/
|
||||
private ScheduledFuture<?> disconnectionTimer;
|
||||
|
||||
|
||||
+10
-2
@@ -21,13 +21,21 @@ public class ShamanicRitual extends EventCard {
|
||||
/** Prestige points awarded to the player with the most shaman icons. */
|
||||
private int prestigeToAdd;
|
||||
|
||||
// TODO
|
||||
/**
|
||||
* Returns the prestige points awarded to the player with the most shaman icons.
|
||||
*
|
||||
* @return prestige points to award.
|
||||
*/
|
||||
int getPrestigeToAdd() { return prestigeToAdd; }
|
||||
|
||||
/** Prestige points removed from the player with the fewest shaman icons. */
|
||||
private int prestigeToRemove;
|
||||
|
||||
// TODO
|
||||
/**
|
||||
* Returns the prestige points removed from the player with the fewest shaman icons.
|
||||
*
|
||||
* @return prestige points to remove.
|
||||
*/
|
||||
int getPrestigeToRemove() { return prestigeToRemove; }
|
||||
|
||||
/**
|
||||
|
||||
@@ -72,7 +72,7 @@ public class Board implements Serializable {
|
||||
*/
|
||||
public List<BuildingCard> getLowerListBuilding() { return lowerListBuilding; }
|
||||
|
||||
// TODO
|
||||
/** All building card lists grouped by era; index 0 = era 1, index 1 = era 2, etc. */
|
||||
private final ArrayList<List<BuildingCard>> buildingCardsAllEras;
|
||||
/** Number of players */
|
||||
private int nTotem;
|
||||
|
||||
@@ -200,7 +200,12 @@ public class CurrentState implements Serializable {
|
||||
|
||||
}
|
||||
|
||||
// TODO
|
||||
/**
|
||||
* Returns a formatted ASCII table representation of the current game state.
|
||||
* Columns: Player, Round, Era, GameStage.
|
||||
*
|
||||
* @return a {@code String} containing the ASCII table.
|
||||
*/
|
||||
@Override
|
||||
public String toString(){
|
||||
var table= new AsciiTable(BorderStyle.ROUNDED,4);
|
||||
|
||||
@@ -67,9 +67,17 @@ public abstract class PlayableCard implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the compact representation shown in the player hand panel. */
|
||||
/**
|
||||
* Returns the compact representation shown in the player hand panel.
|
||||
*
|
||||
* @return the player-hand string representation of this card.
|
||||
*/
|
||||
public abstract String toStringPlayer();
|
||||
|
||||
/** Returns the representation shown on the board (offer track cards). */
|
||||
/**
|
||||
* Returns the representation shown on the board (offer track cards).
|
||||
*
|
||||
* @return the board string representation of this card.
|
||||
*/
|
||||
public abstract String toStringBoard();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class Player implements Serializable {
|
||||
// region Getters
|
||||
/**
|
||||
* Unique string identifier for players; must not be {@code null} and must not
|
||||
* exceed {@link #MAX_VALUE} otherwise an {@link IllegalArgumentException} will be thrown
|
||||
* exceed {@link #MAX_USERNAME_LENGTH} otherwise an {@link IllegalArgumentException} will be thrown
|
||||
* when the {@link #Player(String) constructor} is called.
|
||||
*/
|
||||
private final String userName;
|
||||
@@ -224,7 +224,13 @@ public class Player implements Serializable {
|
||||
|
||||
// region Functions
|
||||
|
||||
// TODO
|
||||
/**
|
||||
* Checks equality between this {@code Player} and another object.
|
||||
* Two players are equal if and only if they share the same {@code userName}.
|
||||
*
|
||||
* @param obj the object to compare with.
|
||||
* @return {@code true} if {@code obj} is a {@code Player} with the same username; {@code false} otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
|
||||
@@ -178,7 +178,13 @@ public class Slot implements Serializable {
|
||||
|
||||
// Functions
|
||||
|
||||
// TODO
|
||||
/**
|
||||
* Checks equality between this {@code Slot} and another object.
|
||||
* Two slots are equal if and only if they share the same {@code slotId}.
|
||||
*
|
||||
* @param obj the object to compare with.
|
||||
* @return {@code true} if {@code obj} is a {@code Slot} with the same identifier; {@code false} otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
@@ -186,7 +192,11 @@ public class Slot implements Serializable {
|
||||
return slotId == ((Slot) obj).slotId;
|
||||
}
|
||||
|
||||
// TODO
|
||||
/**
|
||||
* Returns the hash code for this {@code Slot}, derived from {@link #slotId}.
|
||||
*
|
||||
* @return the hash code of the slot identifier.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Character.hashCode(slotId);
|
||||
|
||||
@@ -30,6 +30,8 @@ public class CompositeClientBroadcaster {
|
||||
* Forwards the event to both the RMI and the TCP server.
|
||||
* Each server is responsible for filtering error events to the
|
||||
* requesting player only.
|
||||
*
|
||||
* @param event the network event to broadcast.
|
||||
*/
|
||||
public void notifyAll(NetworkEvent event) {
|
||||
rmiServer.notifyAll(event);
|
||||
@@ -38,6 +40,8 @@ public class CompositeClientBroadcaster {
|
||||
|
||||
/**
|
||||
* Forwards the model snapshot to every client on both transports.
|
||||
*
|
||||
* @param model the mini model snapshot to broadcast.
|
||||
*/
|
||||
public void notifyAll(MiniModel model) {
|
||||
rmiServer.notifyAll(model);
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.util.List;
|
||||
* during totem selection may free a totem for other players.
|
||||
*/
|
||||
public class DisconnectedPlayer extends NetworkEvent {
|
||||
//TODO
|
||||
/** Updated list of totems available after the disconnection frees any previously chosen totem. */
|
||||
private List<Totems> availableTotems;
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public class ClientCallbackImpl extends UnicastRemoteObject implements IClientCa
|
||||
/**
|
||||
* Called by the server when the game is initialized.
|
||||
* Sets the client game model in the {@link ClientController}.
|
||||
* @param model the initialized {@link Game} model
|
||||
* @param model the initialized {@link it.polimi.ingsw.gc14.Model.Game Game} model
|
||||
* @throws RemoteException if any RMI error occurs
|
||||
*/
|
||||
@Override
|
||||
|
||||
@@ -68,7 +68,7 @@ public class TCPClient implements IClient {
|
||||
* Otherwise, a listener thread is started.
|
||||
* @param user The username of the player
|
||||
* @param proposedNPlayers The desired number of players for the game
|
||||
* @return true if the connection is successful, false otherwise.
|
||||
* @return null if the connection is successful, GENERIC_ERROR otherwise.
|
||||
*/
|
||||
public ErrorType connect(String user, int proposedNPlayers) {
|
||||
try {
|
||||
|
||||
@@ -11,23 +11,53 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
//TODO ALL JAVADOC
|
||||
/**
|
||||
* Ambient fire-particle effect rendered on a transparent overlay pane.
|
||||
*
|
||||
* <p>Three particle types float from the screen corners toward the centre:
|
||||
* <ul>
|
||||
* <li><b>embers</b> (type 0) — slow, glowing orange circles with a soft halo.</li>
|
||||
* <li><b>sparks</b> (type 1) — fast, short-lived bright particles.</li>
|
||||
* <li><b>dust</b> (type 2) — large, translucent brown drifting circles.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Call {@link #start()} after adding {@link #getPane()} to the scene graph,
|
||||
* and {@link #stop()} when the scene is hidden.
|
||||
*/
|
||||
public class FireParticleSystem {
|
||||
|
||||
/** Maximum number of live particles at any given time. */
|
||||
private static final int MAX_PARTICLES = 30;
|
||||
/** Minimum nanoseconds between particle spawn batches. */
|
||||
private static final long SPAWN_INTERVAL_NS = 100_000_000L;
|
||||
private static final long FRAME_INTERVAL_NS = 1_000_000_000L / 30; // 30 fps cap
|
||||
private static final int STEPS_PER_FRAME = 3; // physics steps per frame → 3× speed
|
||||
/** Minimum nanoseconds between rendered frames (30 fps cap). */
|
||||
private static final long FRAME_INTERVAL_NS = 1_000_000_000L / 30;
|
||||
/** Physics update steps applied per rendered frame (multiplies effective speed). */
|
||||
private static final int STEPS_PER_FRAME = 3;
|
||||
|
||||
/** Mouse-transparent overlay pane that hosts all particle nodes. */
|
||||
private final Pane pane;
|
||||
/** The scene whose dimensions are used to position and fade particles. */
|
||||
private final Scene scene;
|
||||
/** Currently live particles. */
|
||||
private final List<Particle> particles = new ArrayList<>();
|
||||
/** Shared random source for particle initialisation and physics noise. */
|
||||
private final Random rnd = new Random();
|
||||
/** The JavaFX animation timer driving the particle loop. */
|
||||
private AnimationTimer timer;
|
||||
/** Timestamp (ns) of the last particle spawn batch. */
|
||||
private long lastSpawn = 0;
|
||||
/** Timestamp (ns) of the last rendered frame. */
|
||||
private long lastFrame = 0;
|
||||
/** {@code true} after the first tick pre-populates the particle pool. */
|
||||
private boolean warmedUp = false;
|
||||
|
||||
/**
|
||||
* Creates the particle system bound to the given scene.
|
||||
* The internal overlay pane is transparent and mouse-transparent.
|
||||
*
|
||||
* @param scene the scene whose dimensions are used for particle positioning and fading.
|
||||
*/
|
||||
public FireParticleSystem(Scene scene) {
|
||||
this.scene = scene;
|
||||
pane = new Pane();
|
||||
@@ -35,7 +65,11 @@ public class FireParticleSystem {
|
||||
pane.setPickOnBounds(false);
|
||||
}
|
||||
|
||||
/** Returns the transparent overlay pane that holds all particle nodes. */
|
||||
/**
|
||||
* Returns the transparent overlay pane that holds all particle nodes.
|
||||
*
|
||||
* @return the mouse-transparent {@link Pane} overlay.
|
||||
*/
|
||||
public Pane getPane() { return pane; }
|
||||
|
||||
/** Starts the animation timer. */
|
||||
@@ -56,6 +90,12 @@ public class FireParticleSystem {
|
||||
if (timer != null) timer.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances the simulation by one frame: pre-warms on first call, spawns new particles,
|
||||
* steps existing ones, removes dead ones, and updates their visual state.
|
||||
*
|
||||
* @param now the current timestamp in nanoseconds from the animation timer.
|
||||
*/
|
||||
private void tick(long now) {
|
||||
double w = scene.getWidth();
|
||||
double h = scene.getHeight();
|
||||
@@ -98,6 +138,13 @@ public class FireParticleSystem {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new particle starting near one of the four screen corners.
|
||||
*
|
||||
* @param w scene width in pixels.
|
||||
* @param h scene height in pixels.
|
||||
* @return the newly constructed {@link Particle}.
|
||||
*/
|
||||
private Particle spawnParticle(double w, double h) {
|
||||
int corner = rnd.nextInt(4);
|
||||
double margin = 0.12;
|
||||
@@ -113,18 +160,51 @@ public class FireParticleSystem {
|
||||
|
||||
// ── Particle ──────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* A single fire particle with position, velocity, wobble, and JavaFX visual nodes.
|
||||
* Particles are typed: 0 = ember, 1 = spark, 2 = dust.
|
||||
*/
|
||||
private static class Particle {
|
||||
|
||||
double x, y, vx, vy;
|
||||
/** Current X position in scene pixels. */
|
||||
double x;
|
||||
/** Current Y position in scene pixels. */
|
||||
double y;
|
||||
/** Horizontal velocity component. */
|
||||
double vx;
|
||||
/** Vertical velocity component. */
|
||||
double vy;
|
||||
/** Remaining life fraction (1.0 = full, 0.0 = dead); only decrements for sparks. */
|
||||
double life;
|
||||
/** Visual radius of the particle's core circle. */
|
||||
double size;
|
||||
double wobblePhase, wobbleSpeed, wobbleAmp;
|
||||
/** Current phase of the sinusoidal wobble. */
|
||||
double wobblePhase;
|
||||
/** Angular speed of the wobble oscillation. */
|
||||
double wobbleSpeed;
|
||||
/** Amplitude factor of the wobble displacement. */
|
||||
double wobbleAmp;
|
||||
/** Particle type: 0 = ember, 1 = spark, 2 = dust. */
|
||||
final int type;
|
||||
/** Shared random source used during physics updates. */
|
||||
final Random rnd;
|
||||
|
||||
/** Primary visible circle node. */
|
||||
final Circle core;
|
||||
final Circle glow; // non-null only for embers
|
||||
/** Soft glow halo circle behind {@link #core}; non-null only for embers (type 0). */
|
||||
final Circle glow;
|
||||
|
||||
/**
|
||||
* Initialises the particle at position ({@code x}, {@code y}) with velocity
|
||||
* aimed roughly from the given {@code corner} toward the scene centre.
|
||||
*
|
||||
* @param x spawn X coordinate.
|
||||
* @param y spawn Y coordinate.
|
||||
* @param w scene width (used to compute target direction).
|
||||
* @param h scene height (used to compute target direction).
|
||||
* @param corner spawn corner index: 0 = bottom-left, 1 = bottom-right, 2 = top-left, 3 = top-right.
|
||||
* @param rnd shared random source.
|
||||
*/
|
||||
Particle(double x, double y, double w, double h, int corner, Random rnd) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
@@ -163,6 +243,12 @@ public class FireParticleSystem {
|
||||
wobbleAmp = 0.1 + rnd.nextDouble() * 0.4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a particle type weighted toward embers (55% ember, 23% spark, 22% dust).
|
||||
*
|
||||
* @param rnd the random source.
|
||||
* @return particle type: 0, 1, or 2.
|
||||
*/
|
||||
private static int weightedType(Random rnd) {
|
||||
double r = rnd.nextDouble();
|
||||
if (r < 0.55) return 0;
|
||||
@@ -170,16 +256,27 @@ public class FireParticleSystem {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds this particle's visual nodes to {@code pane} (glow first so core renders on top).
|
||||
*
|
||||
* @param pane the overlay pane to add nodes to.
|
||||
*/
|
||||
void addTo(Pane pane) {
|
||||
if (glow != null) pane.getChildren().add(glow);
|
||||
pane.getChildren().add(core);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes this particle's visual nodes from {@code pane}.
|
||||
*
|
||||
* @param pane the overlay pane to remove nodes from.
|
||||
*/
|
||||
void removeFrom(Pane pane) {
|
||||
pane.getChildren().remove(core);
|
||||
if (glow != null) pane.getChildren().remove(glow);
|
||||
}
|
||||
|
||||
/** Advances this particle by one physics step: applies wobble, moves, and decrements spark life. */
|
||||
void update() {
|
||||
wobblePhase += wobbleSpeed;
|
||||
vx += Math.sin(wobblePhase) * wobbleAmp * 0.05;
|
||||
@@ -189,12 +286,26 @@ public class FireParticleSystem {
|
||||
if (type == 1) life -= 0.008 + rnd.nextDouble() * 0.006;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} when this particle has left the scene bounds or, for sparks, its life reached zero.
|
||||
*
|
||||
* @param w scene width.
|
||||
* @param h scene height.
|
||||
* @return {@code true} if the particle should be removed.
|
||||
*/
|
||||
boolean isDead(double w, double h) {
|
||||
double pad = size * 4;
|
||||
return x < -pad || x > w + pad || y < -pad || y > h + pad
|
||||
|| (type == 1 && life <= 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates color, opacity, and translate position of this particle's visual nodes
|
||||
* based on distance from scene edges and remaining life.
|
||||
*
|
||||
* @param w scene width.
|
||||
* @param h scene height.
|
||||
*/
|
||||
void updateVisual(double w, double h) {
|
||||
double edge = Math.min(w, h) * 0.05;
|
||||
double fadeX = Math.min(x / edge, Math.min((w - x) / edge, 1.0));
|
||||
|
||||
@@ -33,43 +33,41 @@ import static it.polimi.ingsw.gc14.Model.GamePackage.GameStages.TOTEM_CHOICE;
|
||||
* main game, and leaderboard scenes based on the current game state.
|
||||
*/
|
||||
public class GUI extends Application implements IView {
|
||||
//TODO
|
||||
/** The primary JavaFX stage. */
|
||||
private Stage primaryStage;
|
||||
//TODO
|
||||
/** Latest mini model received from the server. */
|
||||
private volatile MiniModel miniModel;
|
||||
//TODO
|
||||
/** FXML loader for the login scene. */
|
||||
private FXMLLoader loaderLogin;
|
||||
//TODO
|
||||
/** The login scene. */
|
||||
private Scene loginScene;
|
||||
//TODO
|
||||
/** Controller for the login FXML scene. */
|
||||
private LoginFXMLController controllerLogin;
|
||||
//TODO
|
||||
/** FXML loader for the totem selection scene. */
|
||||
private FXMLLoader loaderTotem;
|
||||
//TODO
|
||||
/** The totem selection scene. */
|
||||
private Scene totemScene;
|
||||
//TODO
|
||||
/** Controller for the totem FXML scene. */
|
||||
private TotemFXMLController controllerTotem;
|
||||
//TODO
|
||||
/** FXML loader for the main game scene. */
|
||||
private FXMLLoader loaderMain;
|
||||
|
||||
//TODO
|
||||
/** The main game scene. */
|
||||
private Scene mainScene;
|
||||
//TODO
|
||||
/** Controller for the main FXML scene. */
|
||||
private MainFXMLController controllerMain;
|
||||
//TODO
|
||||
/** FXML loader for the leaderboard scene. */
|
||||
private FXMLLoader loaderLeaderboard;
|
||||
//TODO
|
||||
/** The end-of-game leaderboard scene. */
|
||||
private Scene leaderboardScene;
|
||||
//TODO
|
||||
/** Controller for the leaderboard FXML scene. */
|
||||
private LeaderboardFXMLController controllerLeaderboard;
|
||||
|
||||
//TODO
|
||||
/** Client controller injected before JavaFX startup. */
|
||||
private ClientController controller;
|
||||
//TODO
|
||||
/** When {@code true}, the app re-enters fullscreen automatically after ESC is pressed. */
|
||||
private boolean autoReenterFullscreen = true;
|
||||
//TODO
|
||||
/** Guards against overlapping fade transitions. */
|
||||
private boolean isFading = false;
|
||||
//TODO
|
||||
/** Background music player looping indefinitely. */
|
||||
private MediaPlayer bgMusic;
|
||||
|
||||
|
||||
@@ -208,12 +206,22 @@ public class GUI extends Application implements IView {
|
||||
}
|
||||
});
|
||||
}
|
||||
//TODO
|
||||
/**
|
||||
* Wraps the current root of {@code scene} in a {@link StackPane} so that
|
||||
* fade overlay rectangles can be layered over it during scene transitions.
|
||||
*
|
||||
* @param scene the scene whose root to wrap.
|
||||
*/
|
||||
private void wrapScene(Scene scene) {
|
||||
Parent root = scene.getRoot();
|
||||
scene.setRoot(new StackPane(root));
|
||||
}
|
||||
//TODO
|
||||
/**
|
||||
* Performs a black-overlay crossfade from the current scene to {@code newScene}.
|
||||
* No-op if already fading or if {@code newScene} is already displayed.
|
||||
*
|
||||
* @param newScene the scene to transition to.
|
||||
*/
|
||||
private void fadeToScene(Scene newScene) {
|
||||
Scene currentScene = primaryStage.getScene();
|
||||
if (currentScene == newScene || isFading) return;
|
||||
|
||||
@@ -41,18 +41,17 @@ public class LeaderboardFXMLController {
|
||||
@FXML private VBox mainVBox;
|
||||
@FXML private VBox rankingList;
|
||||
// title label removed; outcome text is added dynamically in render()
|
||||
//TODO
|
||||
/** Client controller for fetching game state and sending actions. */
|
||||
private ClientController controller;
|
||||
//TODO
|
||||
/** Auto-hiding popup that shows detailed player card information. */
|
||||
private Popup popup;
|
||||
//TODO
|
||||
/** Content container inside {@link #popup}. */
|
||||
private VBox popupContent;
|
||||
//TODO
|
||||
/** Shared image cache to avoid reloading resources multiple times. */
|
||||
private static final Map<String, Image> imageCache = new HashMap<>();
|
||||
//TODO
|
||||
/** The login scene shown when the player starts a new game. */
|
||||
private Scene loginScene;
|
||||
|
||||
//TODO
|
||||
/** Action run when the player returns to the login screen (disconnect + scene switch). */
|
||||
private Runnable action;
|
||||
|
||||
/** Returns a cached {@link Image} for the given classpath {@code path}, loading it on first access. */
|
||||
|
||||
@@ -29,33 +29,33 @@ import java.util.Enumeration;
|
||||
* and initiates the connection to the server.
|
||||
*/
|
||||
public class LoginFXMLController {
|
||||
//TODO
|
||||
/** Background image displayed behind the login form. */
|
||||
@FXML private ImageView backgroundImage;
|
||||
//TODO
|
||||
/** Text field for the player's username. */
|
||||
@FXML private TextField campoNome;
|
||||
//TODO
|
||||
/** Text field for the desired number of players. */
|
||||
@FXML private TextField campoNumPlayers;
|
||||
//TODO
|
||||
/** Text field for the server IP address. */
|
||||
@FXML private TextField campoIP;
|
||||
//TODO
|
||||
/** Button that submits the login form. */
|
||||
@FXML private Button btnAccedi;
|
||||
//TODO
|
||||
/** Label used to show error or success messages. */
|
||||
@FXML private Label labelErrore;
|
||||
//TODO
|
||||
/** VBox containing the login form controls. */
|
||||
@FXML private VBox formPanel;
|
||||
//TODO
|
||||
/** Toggle container for switching between RMI and TCP. */
|
||||
@FXML private StackPane protocolToggle;
|
||||
//TODO
|
||||
/** Sliding thumb inside the protocol toggle. */
|
||||
@FXML private Region toggleThumb;
|
||||
//TODO
|
||||
/** Label for the RMI side of the protocol toggle. */
|
||||
@FXML private Label labelRMI;
|
||||
//TODO
|
||||
/** Label for the TCP side of the protocol toggle. */
|
||||
@FXML private Label labelTCP;
|
||||
//TODO
|
||||
/** {@code true} when RMI is selected; {@code false} for TCP. */
|
||||
private boolean isRMI = true;
|
||||
//TODO
|
||||
/** Client controller used to initiate the connection. */
|
||||
private ClientController controller;
|
||||
//TODO
|
||||
/** CSS pseudo-class applied to the active protocol label. */
|
||||
private final PseudoClass activeProtocolPseudo = PseudoClass.getPseudoClass("active-protocol");
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,47 +46,51 @@ import java.util.*;
|
||||
* the player's hand, and action buttons (skip, details).
|
||||
*/
|
||||
public class MainFXMLController {
|
||||
//TODO
|
||||
/** Left column grid used for the board slots layout. */
|
||||
@FXML private GridPane leftGrid;
|
||||
//TODO
|
||||
/** Scrollable container holding all player side-panel cards. */
|
||||
@FXML private ScrollPane playerSide;
|
||||
//TODO
|
||||
/** Root HBox containing all main scene elements. */
|
||||
@FXML private HBox mainHBox;
|
||||
//TODO
|
||||
/** Background image view for the main scene. */
|
||||
@FXML private ImageView backgroundImage;
|
||||
//TODO
|
||||
/** HBox holding the board slot and order cards. */
|
||||
@FXML private HBox board;
|
||||
//TODO
|
||||
/** HBox holding the upper tribe card row (and upper building stack). */
|
||||
@FXML private HBox upperList;
|
||||
//TODO
|
||||
/** HBox holding the lower tribe card row (and lower building stack). */
|
||||
@FXML private HBox lowerList;
|
||||
//TODO
|
||||
/** HBox displaying the local player's card piles. */
|
||||
@FXML private HBox myHand;
|
||||
//TODO
|
||||
/** Button that sends a skip-turn command. */
|
||||
@FXML private Button skipBtn;
|
||||
//TODO
|
||||
/** Button that opens the game details popup. */
|
||||
@FXML private Button detailsBtn;
|
||||
//TODO
|
||||
/** Label showing the current round number and game stage. */
|
||||
@FXML private Label infoText;
|
||||
//TODO
|
||||
/** Maps each player's username to their current food-value label in the side panel. */
|
||||
private final Map<String, Label> foodLabels = new HashMap<>();
|
||||
//TODO
|
||||
/** Maps each player's username to their current prestige-value label in the side panel. */
|
||||
private final Map<String, Label> prestigeLabels = new HashMap<>();
|
||||
//TODO
|
||||
/** Maps each player's username to their player-card VBox in the side panel. */
|
||||
private final Map<String, VBox> playerCards = new HashMap<>();
|
||||
//TODO
|
||||
/** Maps each player's username to their ordered list of card-type icon ImageViews. */
|
||||
private final Map<String, List<ImageView>> iconViews = new HashMap<>();
|
||||
//TODO
|
||||
/** Shared popup used for card previews and building selection. */
|
||||
private Popup popup;
|
||||
//TODO
|
||||
/** HBox inside {@link #popup} that holds the displayed card images. */
|
||||
private HBox popupCards;
|
||||
//TODO
|
||||
/** Client controller for fetching game state and sending player actions. */
|
||||
private ClientController controller;
|
||||
|
||||
/** {@code true} when the last received event was an error response. */
|
||||
private boolean isError;
|
||||
|
||||
/** Sets the error flag; called by {@link GUI} before delegating to {@link #render()}. */
|
||||
/**
|
||||
* Sets the error flag; called by {@link GUI} before delegating to {@link #render()}.
|
||||
*
|
||||
* @param error {@code true} if the last received event was an error response.
|
||||
*/
|
||||
public void setError(boolean error) { this.isError = error; }
|
||||
|
||||
// ==== IMAGE CACHE ====
|
||||
|
||||
@@ -24,20 +24,20 @@ import java.util.Locale;
|
||||
* other players see a waiting banner.
|
||||
*/
|
||||
public class TotemFXMLController {
|
||||
//TODO
|
||||
/** Background image displayed behind the totem selection grid. */
|
||||
@FXML private ImageView backgroundImage;
|
||||
//TODO
|
||||
/** HBox containing the totem card widgets. */
|
||||
@FXML private HBox mainHBox;
|
||||
//TODO
|
||||
/** Banner label showing whose turn it is to choose a totem. */
|
||||
@FXML private Label turnBanner;
|
||||
//TODO
|
||||
/** Button that submits the selected totem to the server. */
|
||||
@FXML private Button confirmButton;
|
||||
|
||||
//TODO
|
||||
/** Client controller for sending the totem choice. */
|
||||
private ClientController controller;
|
||||
//TODO
|
||||
/** Index of the currently selected totem, or {@code -1} if none selected. */
|
||||
private int selectedIndex = -1;
|
||||
//TODO
|
||||
/** The {@link StackPane} frame of the currently selected totem card, or {@code null}. */
|
||||
private StackPane selectedFrame = null;
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,33 +21,62 @@ import java.util.*;
|
||||
* }</pre>
|
||||
*/
|
||||
public class AsciiTable {
|
||||
//TODO
|
||||
/** Border style used to draw corners, lines, and junctions. */
|
||||
private final BorderStyle s;
|
||||
//TODO
|
||||
|
||||
/** Number of columns in this table. */
|
||||
private final int cols;
|
||||
//TODO
|
||||
|
||||
/** All rows of the table, in insertion order. */
|
||||
private final List<List<String>> rows = new ArrayList<>();
|
||||
//TODO
|
||||
|
||||
/** Indices of rows after which a horizontal separator line is drawn. */
|
||||
private final List<Integer> separators = new ArrayList<>();
|
||||
//TODO
|
||||
|
||||
/**
|
||||
* Creates a new empty table with the given border style and column count.
|
||||
*
|
||||
* @param s the border style to use when rendering.
|
||||
* @param cols the number of columns.
|
||||
*/
|
||||
public AsciiTable(BorderStyle s, int cols) {
|
||||
this.s = s; this.cols = cols;
|
||||
}
|
||||
//TODO
|
||||
|
||||
/**
|
||||
* Appends a row using varargs cells.
|
||||
*
|
||||
* @param cells one value per column.
|
||||
*/
|
||||
public void addRow(String... cells) { rows.add(Arrays.asList(cells)); }
|
||||
//TODO
|
||||
|
||||
/**
|
||||
* Appends a row from an existing list.
|
||||
*
|
||||
* @param cells one value per column.
|
||||
*/
|
||||
public void addRow(List<String> cells) { rows.add(cells); }
|
||||
//TODO
|
||||
|
||||
/**
|
||||
* Inserts a header row at position 0 and marks it with a separator line below it.
|
||||
*
|
||||
* @param cells one header label per column.
|
||||
*/
|
||||
public void addHeader(String... cells) {
|
||||
rows.add(0, Arrays.asList(cells));
|
||||
separators.add(0);
|
||||
}
|
||||
//TODO
|
||||
|
||||
/**
|
||||
* Marks a separator line to be drawn after the last row added so far.
|
||||
*/
|
||||
public void addSeparator() { separators.add(rows.size() - 1); }
|
||||
|
||||
/**
|
||||
* Renders the table to a multi-line string.
|
||||
* Column width is the widest cell in display columns (wide chars = 2), plus 1.
|
||||
*
|
||||
* @return the fully rendered table as a multi-line string.
|
||||
*/
|
||||
public String build() {
|
||||
var sb = new StringBuilder();
|
||||
@@ -67,7 +96,15 @@ public class AsciiTable {
|
||||
sb.append(hline(s.bl(), s.mb(), s.br(), maxWidth));
|
||||
return sb.toString();
|
||||
}
|
||||
//TODO
|
||||
/**
|
||||
* Builds a single horizontal border line across all columns.
|
||||
*
|
||||
* @param l left-end character.
|
||||
* @param m middle junction character (between columns).
|
||||
* @param r right-end character.
|
||||
* @param maxWidth width in display columns of each cell (including padding).
|
||||
* @return the rendered horizontal line string.
|
||||
*/
|
||||
private String hline(String l, String m, String r, int maxWidth) {
|
||||
var sb = new StringBuilder(l);
|
||||
for (int i = 0; i < cols; i++) {
|
||||
@@ -91,6 +128,11 @@ public class AsciiTable {
|
||||
* Places two pre-rendered text blocks side by side, separated by a gap.
|
||||
* Left-block lines are padded to a uniform display width so the right block
|
||||
* always starts at the same column. Uses {@link #displayWidth} for measurement.
|
||||
*
|
||||
* @param left lines of the left block.
|
||||
* @param right lines of the right block.
|
||||
* @param gap number of space characters between the two blocks.
|
||||
* @return the combined multi-line string.
|
||||
*/
|
||||
public static String sideBySide(List<String> left, List<String> right, int gap) {
|
||||
int leftWidth = left.stream().mapToInt(AsciiTable::displayWidth).max().orElse(0);
|
||||
@@ -112,6 +154,9 @@ public class AsciiTable {
|
||||
/**
|
||||
* Returns the number of terminal columns required to display {@code s}.
|
||||
* Wide characters (emoji, CJK, full-width) count as 2; all others as 1.
|
||||
*
|
||||
* @param s the string to measure; ANSI escape sequences are stripped before counting.
|
||||
* @return the display width in terminal columns.
|
||||
*/
|
||||
public static int displayWidth(String s) {
|
||||
s = s.replaceAll("\033\\[[^m]*m", "");
|
||||
|
||||
@@ -9,16 +9,6 @@ package it.polimi.ingsw.gc14.View.TUI;
|
||||
*/
|
||||
public enum BorderStyle {
|
||||
|
||||
/**
|
||||
* Unicode box-drawing border style.
|
||||
*/
|
||||
UNICODE("╔","╗","╚","╝","═","║","╠","╣","╦","╩","╬","├","┤","┼"),
|
||||
|
||||
/**
|
||||
* Plain ASCII border style.
|
||||
*/
|
||||
ASCII ("+","+","+","+","-","|","+","+","+","+","+","+","+","+"),
|
||||
|
||||
/**
|
||||
* Rounded Unicode border style.
|
||||
*/
|
||||
@@ -70,16 +60,6 @@ public enum BorderStyle {
|
||||
*/
|
||||
public String v() { return v; }
|
||||
|
||||
/**
|
||||
* @return the middle-left junction character.
|
||||
*/
|
||||
public String ml() { return ml; }
|
||||
|
||||
/**
|
||||
* @return the middle-right junction character.
|
||||
*/
|
||||
public String mr() { return mr; }
|
||||
|
||||
/**
|
||||
* @return the top-middle junction character.
|
||||
*/
|
||||
@@ -90,11 +70,6 @@ public enum BorderStyle {
|
||||
*/
|
||||
public String mb() { return mb; }
|
||||
|
||||
/**
|
||||
* @return the center junction character.
|
||||
*/
|
||||
public String x() { return x; }
|
||||
|
||||
/**
|
||||
* @return the separator-left junction character.
|
||||
*/
|
||||
|
||||
@@ -48,12 +48,20 @@ public class TUI implements IView {
|
||||
|
||||
// ── Setters ───────────────────────────────────────────────────────────────
|
||||
|
||||
/** Sets the username of the local player. */
|
||||
/**
|
||||
* Sets the username of the local player.
|
||||
*
|
||||
* @param username the username to assign.
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/** Updates the model stored in this view. */
|
||||
/**
|
||||
* Updates the model stored in this view.
|
||||
*
|
||||
* @param model the latest mini model to display.
|
||||
*/
|
||||
@Override
|
||||
public void setModel(MiniModel model) {
|
||||
this.model = model;
|
||||
@@ -63,6 +71,8 @@ public class TUI implements IView {
|
||||
* Registers the active JLine {@link LineReader}.
|
||||
* Once set, all output routes through {@link LineReader#printAbove} so the
|
||||
* prompt survives background-thread renders.
|
||||
*
|
||||
* @param lineReader the JLine reader to use for output; also provides the terminal reference.
|
||||
*/
|
||||
public void setLineReader(LineReader lineReader) {
|
||||
this.lineReader = lineReader;
|
||||
|
||||
@@ -245,7 +245,7 @@ class BuildingCardTest {
|
||||
assertEquals(food, p2.getFoodValue());
|
||||
assertTrue(bc.buy(p2));
|
||||
|
||||
int discount = p2.getBuilders().stream().mapToInt(x -> x.getReductionValue()).sum();
|
||||
p2.getBuilders().stream().mapToInt(x -> x.getReductionValue()).sum();
|
||||
assertEquals(food, p2.getFoodValue());
|
||||
|
||||
p2.removeFood(p2.getFoodValue());
|
||||
|
||||
Reference in New Issue
Block a user