mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Update stability and fix issues in lobby and network games.
- Fix closing the lobby/client so that it notifies the clients/server. - Improve deck selection in lobby (no longer adds Planes to deck and saves) - Improve responsiveness of lobby over network - In 2-player game over network, always assign local player to slot 0 - Warn when starting a commander deck without a commander - Put poison counters next to life total (frees up space in the details panel)
This commit is contained in:
@@ -5,4 +5,5 @@ import forge.match.GameLobby.GameLobbyData;
|
||||
public interface ILobbyListener {
|
||||
void message(String source, String message);
|
||||
void update(GameLobbyData state, int slot);
|
||||
void close();
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ public abstract class GameLobby {
|
||||
private final static int MAX_PLAYERS = 8;
|
||||
|
||||
private GameLobbyData data = new GameLobbyData();
|
||||
private GameType currentGameType = GameType.Constructed;
|
||||
private int lastArchenemy = 0;
|
||||
|
||||
private IUpdateable listener;
|
||||
@@ -69,10 +70,10 @@ public abstract class GameLobby {
|
||||
}
|
||||
|
||||
public GameType getGameType() {
|
||||
return data.currentGameMode;
|
||||
return currentGameType;
|
||||
}
|
||||
public void setGameType(final GameType type) {
|
||||
data.currentGameMode = type;
|
||||
currentGameType = type;
|
||||
}
|
||||
|
||||
public boolean hasVariant(final GameType variant) {
|
||||
@@ -90,7 +91,7 @@ public abstract class GameLobby {
|
||||
}
|
||||
public void applyToSlot(final int index, final UpdateLobbyPlayerEvent event) {
|
||||
final LobbySlot slot = getSlot(index);
|
||||
if (slot == null) {
|
||||
if (slot == null || event == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
@@ -130,10 +131,10 @@ public abstract class GameLobby {
|
||||
}
|
||||
|
||||
public abstract boolean hasControl();
|
||||
public abstract boolean mayEdit(final int index);
|
||||
public abstract boolean mayControl(final int index);
|
||||
public abstract boolean mayRemove(final int index);
|
||||
protected abstract IGuiGame getGui(final int index);
|
||||
public abstract boolean mayEdit(int index);
|
||||
public abstract boolean mayControl(int index);
|
||||
public abstract boolean mayRemove(int index);
|
||||
protected abstract IGuiGame getGui(int index);
|
||||
protected abstract void onGameStarted();
|
||||
|
||||
public void addSlot() {
|
||||
@@ -142,6 +143,9 @@ public abstract class GameLobby {
|
||||
addSlot(new LobbySlot(type, null, newIndex, newIndex, false, !allowNetworking, Collections.<AIOption>emptySet()));
|
||||
}
|
||||
protected final void addSlot(final LobbySlot slot) {
|
||||
if (slot == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (data.slots.size() >= MAX_PLAYERS) {
|
||||
return;
|
||||
}
|
||||
@@ -197,7 +201,7 @@ public abstract class GameLobby {
|
||||
}
|
||||
|
||||
public void applyVariant(final GameType variant) {
|
||||
data.currentGameMode = variant;
|
||||
setGameType(variant);
|
||||
data.appliedVariants.add(variant);
|
||||
|
||||
//ensure other necessary variants are unchecked
|
||||
@@ -231,17 +235,21 @@ public abstract class GameLobby {
|
||||
}
|
||||
|
||||
public void removeVariant(final GameType variant) {
|
||||
data.appliedVariants.remove(variant);
|
||||
final boolean changed = data.appliedVariants.remove(variant);
|
||||
if (!changed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.appliedVariants.isEmpty()) {
|
||||
data.appliedVariants.add(GameType.Constructed);
|
||||
}
|
||||
if (variant == data.currentGameMode) {
|
||||
if (variant == currentGameType) {
|
||||
if (hasVariant(GameType.Commander)) {
|
||||
data.currentGameMode = GameType.Commander;
|
||||
currentGameType = GameType.Commander;
|
||||
} else if (hasVariant(GameType.TinyLeaders)) {
|
||||
data.currentGameMode = GameType.TinyLeaders;
|
||||
currentGameType = GameType.TinyLeaders;
|
||||
} else {
|
||||
data.currentGameMode = GameType.Constructed;
|
||||
currentGameType = GameType.Constructed;
|
||||
}
|
||||
}
|
||||
updateView(true);
|
||||
@@ -275,7 +283,7 @@ public abstract class GameLobby {
|
||||
}
|
||||
|
||||
final List<LobbySlot> activeSlots = Lists.newArrayListWithCapacity(getNumberOfSlots());
|
||||
for (final LobbySlot slot : data.getSlots()) {
|
||||
for (final LobbySlot slot : data.slots) {
|
||||
if (slot.getType() != LobbySlotType.OPEN) {
|
||||
activeSlots.add(slot);
|
||||
}
|
||||
@@ -290,6 +298,12 @@ public abstract class GameLobby {
|
||||
SOptionPane.showMessageDialog(String.format("Please specify a deck for %s", slot.getName()));
|
||||
return;
|
||||
}
|
||||
if (hasVariant(GameType.Commander) || hasVariant(GameType.TinyLeaders)) {
|
||||
if (!slot.getDeck().has(DeckSection.Commander)) {
|
||||
SOptionPane.showMessageDialog(String.format("%s doesn't have a commander", slot.getName()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Set<GameType> variantTypes = data.appliedVariants;
|
||||
@@ -391,7 +405,7 @@ public abstract class GameLobby {
|
||||
return;
|
||||
}
|
||||
}
|
||||
schemes = schemePool.toFlatList();
|
||||
schemes = schemePool == null ? Collections.<PaperCard>emptyList() : schemePool.toFlatList();
|
||||
}
|
||||
|
||||
//Planechase
|
||||
@@ -404,7 +418,7 @@ public abstract class GameLobby {
|
||||
return;
|
||||
}
|
||||
}
|
||||
planes = planePool.toFlatList();
|
||||
planes = planePool == null ? Collections.<PaperCard>emptyList() : planePool.toFlatList();
|
||||
}
|
||||
|
||||
//Vanguard
|
||||
@@ -441,23 +455,12 @@ public abstract class GameLobby {
|
||||
}
|
||||
|
||||
public final static class GameLobbyData implements Serializable {
|
||||
private static final long serialVersionUID = -9038854736144187540L;
|
||||
private static final long serialVersionUID = 9184758307999646864L;
|
||||
|
||||
private transient GameType currentGameMode = GameType.Constructed;
|
||||
private final Set<GameType> appliedVariants = EnumSet.of(GameType.Constructed);
|
||||
private final List<LobbySlot> slots = Lists.newArrayList();
|
||||
|
||||
public GameType getCurrentGameMode() {
|
||||
return currentGameMode;
|
||||
}
|
||||
public void setCurrentGameMode(GameType currentGameMode) {
|
||||
this.currentGameMode = currentGameMode;
|
||||
}
|
||||
public Set<GameType> getAppliedVariants() {
|
||||
return Collections.unmodifiableSet(appliedVariants);
|
||||
}
|
||||
public List<LobbySlot> getSlots() {
|
||||
return Collections.unmodifiableList(slots);
|
||||
public GameLobbyData() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,10 +62,11 @@ public final class LobbySlot implements Serializable {
|
||||
setAiOptions(data.getAiOptions());
|
||||
changed = true;
|
||||
}
|
||||
final Deck oldDeck = getDeck();
|
||||
if (data.getDeck() != null) {
|
||||
setDeck(data.getDeck());
|
||||
} else if (getDeck() != null && data.getSection() != null && data.getCards() != null) {
|
||||
getDeck().putSection(data.getSection(), data.getCards());
|
||||
} else if (oldDeck != null && data.getSection() != null && data.getCards() != null) {
|
||||
oldDeck.putSection(data.getSection(), data.getCards());
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
@@ -104,6 +104,10 @@ public class FGameClient implements IToServer {
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
channel.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(final NetEvent event) {
|
||||
System.out.println("Client sent " + event);
|
||||
@@ -382,5 +386,13 @@ public class FGameClient implements IToServer {
|
||||
}
|
||||
super.channelRead(ctx, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
|
||||
for (final ILobbyListener listener : lobbyListeners) {
|
||||
listener.close();
|
||||
}
|
||||
super.channelInactive(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.google.common.collect.Maps;
|
||||
public final class FServerManager {
|
||||
private static FServerManager instance = null;
|
||||
|
||||
private boolean isHosting = false;
|
||||
private final EventLoopGroup bossGroup = new NioEventLoopGroup(1);
|
||||
private final EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||
private final Map<Channel, RemoteClient> clients = Maps.newTreeMap();
|
||||
@@ -102,6 +103,7 @@ public final class FServerManager {
|
||||
|
||||
}
|
||||
}).start();
|
||||
isHosting = true;
|
||||
} catch (final InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -110,6 +112,11 @@ public final class FServerManager {
|
||||
public void stopServer() {
|
||||
bossGroup.shutdownGracefully();
|
||||
workerGroup.shutdownGracefully();
|
||||
isHosting = false;
|
||||
}
|
||||
|
||||
public boolean isHosting() {
|
||||
return isHosting;
|
||||
}
|
||||
|
||||
public void broadcast(final NetEvent event) {
|
||||
|
||||
Reference in New Issue
Block a user