Merge branch 'target-other-zones' into 'master'

Show ZoneAreas when targeting non-Stack zones

See merge request core-developers/forge!2492
This commit is contained in:
Michael Kamensky
2020-02-14 15:01:02 +00:00
13 changed files with 337 additions and 290 deletions

View File

@@ -1,11 +1,6 @@
package forge.interfaces;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import com.google.common.base.Function;
import forge.LobbyPlayer;
import forge.assets.FSkinProp;
import forge.deck.CardPool;
@@ -22,9 +17,14 @@ import forge.game.spellability.SpellAbilityView;
import forge.game.zone.ZoneType;
import forge.item.PaperCard;
import forge.player.PlayerZoneUpdate;
import forge.player.PlayerZoneUpdates;
import forge.trackable.TrackableCollection;
import forge.util.ITriggerEvent;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public interface IGuiGame {
void setGameView(GameView gameView);
GameView getGameView();
@@ -107,7 +107,6 @@ public interface IGuiGame {
* @return null if choices is missing, empty, or if the users' choices are
* empty; otherwise, returns the first item in the List returned by
* getChoices.
* @see #getChoices(String, int, int, Object...)
*/
<T> T oneOrNone(String message, List<T> choices);
@@ -158,8 +157,8 @@ public interface IGuiGame {
void setCard(CardView card);
void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi);
boolean openZones(Collection<ZoneType> zones, Map<PlayerView, Object> players);
void restoreOldZones(Map<PlayerView, Object> playersToRestoreZonesFor);
PlayerZoneUpdates openZones(PlayerView controller, Collection<ZoneType> zones, Map<PlayerView, Object> players);
void restoreOldZones(PlayerView playerView, PlayerZoneUpdates playerZoneUpdates);
void setHighlighted(PlayerView pv, boolean b);
void setUsedToPay(CardView card, boolean value);
void setSelectables(final Iterable<CardView> cards);

View File

@@ -1,23 +1,22 @@
package forge.match.input;
import java.util.Collection;
import java.util.List;
import java.util.ArrayList;
import forge.FThreads;
import forge.game.GameEntity;
import forge.game.card.Card;
import forge.game.card.CardView;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.zone.Zone;
import forge.player.PlayerControllerHuman;
import forge.util.collect.FCollection;
import forge.util.collect.FCollectionView;
import forge.util.ITriggerEvent;
import forge.player.PlayerZoneUpdate;
import forge.player.PlayerZoneUpdates;
import forge.game.zone.Zone;
import forge.FThreads;
import forge.util.ITriggerEvent;
import forge.util.collect.FCollection;
import forge.util.collect.FCollectionView;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSelectManyBase<T> {
private static final long serialVersionUID = -6609493252672573139L;
@@ -31,31 +30,32 @@ public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSele
}
public InputSelectEntitiesFromList(final PlayerControllerHuman controller, final int min, final int max, final FCollectionView<T> validChoices0, final SpellAbility sa0) {
super(controller, Math.min(min, validChoices0.size()), Math.min(max, validChoices0.size()),sa0);
super(controller, Math.min(min, validChoices0.size()), Math.min(max, validChoices0.size()), sa0);
validChoices = validChoices0;
if (min > validChoices.size()) { // pfps does this really do anything useful??
System.out.println(String.format("Trying to choose at least %d things from a list with only %d things!", min, validChoices.size()));
}
ArrayList<CardView> vCards = new ArrayList<>();
for ( T c : validChoices0 ) {
if ( c instanceof Card ) {
vCards.add(((Card)c).getView()) ;
}
}
getController().getGui().setSelectables(vCards);
final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates();
for (final GameEntity c : validChoices) {
final Zone cz = (c instanceof Card) ? ((Card) c).getZone() : null ;
if ( cz != null ) {
zonesToUpdate.add(new PlayerZoneUpdate(cz.getPlayer().getView(),cz.getZoneType()));
}
}
FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override public void run() {
getController().getGui().updateZones(zonesToUpdate);
zonesShown = getController().getGui().tempShowZones(controller.getPlayer().getView(),zonesToUpdate);
ArrayList<CardView> vCards = new ArrayList<>();
for (T c : validChoices0) {
if (c instanceof Card) {
vCards.add(((Card) c).getView());
}
});
}
getController().getGui().setSelectables(vCards);
final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates();
for (final GameEntity c : validChoices) {
final Zone cz = (c instanceof Card) ? ((Card) c).getZone() : null;
if (cz != null) {
zonesToUpdate.add(new PlayerZoneUpdate(cz.getPlayer().getView(), cz.getZoneType()));
}
}
FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override
public void run() {
getController().getGui().updateZones(zonesToUpdate);
zonesShown = getController().getGui().tempShowZones(controller.getPlayer().getView(), zonesToUpdate);
}
});
}
@Override

View File

@@ -1,13 +1,7 @@
package forge.match.input;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.ImmutableList;
import forge.FThreads;
import forge.game.GameEntity;
import forge.game.GameObject;
import forge.game.ability.ApiType;
@@ -18,13 +12,18 @@ import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.model.FModel;
import forge.player.PlayerControllerHuman;
import forge.player.PlayerZoneUpdate;
import forge.player.PlayerZoneUpdates;
import forge.properties.ForgeConstants;
import forge.properties.ForgePreferences;
import forge.util.ITriggerEvent;
import forge.util.TextUtil;
import forge.player.PlayerZoneUpdate;
import forge.player.PlayerZoneUpdates;
import forge.FThreads;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public final class InputSelectTargets extends InputSyncronizedBase {
private final List<Card> choices;
@@ -47,16 +46,17 @@ public final class InputSelectTargets extends InputSyncronizedBase {
this.tgt = sa.getTargetRestrictions();
this.sa = sa;
this.mandatory = mandatory;
controller.getGui().setSelectables(CardView.getCollection(choices));
final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates();
for (final Card c : choices) {
zonesToUpdate.add(new PlayerZoneUpdate(c.getZone().getPlayer().getView(),c.getZone().getZoneType()));
}
FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override public void run() {
controller.getGui().updateZones(zonesToUpdate);
controller.getGui().setSelectables(CardView.getCollection(choices));
final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates();
for (final Card c : choices) {
zonesToUpdate.add(new PlayerZoneUpdate(c.getZone().getPlayer().getView(), c.getZone().getZoneType()));
}
FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override
public void run() {
controller.getGui().updateZones(zonesToUpdate);
}
});
});
}
@Override

View File

@@ -1,14 +1,6 @@
package forge.net;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.Map;
import com.google.common.base.Function;
import forge.GuiBase;
import forge.assets.FSkinProp;
import forge.deck.CardPool;
@@ -22,11 +14,19 @@ import forge.game.spellability.SpellAbilityView;
import forge.interfaces.IGameController;
import forge.interfaces.IGuiGame;
import forge.match.NextGameDecision;
import forge.player.PlayerZoneUpdates;
import forge.trackable.TrackableCollection;
import forge.util.ITriggerEvent;
import forge.util.ReflectionUtil;
import org.apache.commons.lang3.SerializationUtils;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.Map;
/**
* The methods that can be sent through this protocol.
*/
@@ -75,8 +75,8 @@ public enum ProtocolMethod {
clearSelectables (Mode.SERVER),
refreshField (Mode.SERVER),
// TODO case "setPlayerAvatar":
openZones (Mode.SERVER, Boolean.TYPE, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class),
restoreOldZones (Mode.SERVER, Void.TYPE, Map/*PlayerView,Object*/.class),
openZones (Mode.SERVER, PlayerZoneUpdates.class, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class),
restoreOldZones (Mode.SERVER, Void.TYPE, PlayerView.class, PlayerZoneUpdates.class),
isUiSetToSkipPhase (Mode.SERVER, Boolean.TYPE, PlayerView.class, PhaseType.class),
setRememberedActions(Mode.SERVER, Void.TYPE),
nextRememberedAction(Mode.SERVER, Void.TYPE),

View File

@@ -1,11 +1,6 @@
package forge.net.server;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import com.google.common.base.Function;
import forge.LobbyPlayer;
import forge.assets.FSkinProp;
import forge.deck.CardPool;
@@ -23,9 +18,14 @@ import forge.match.AbstractGuiGame;
import forge.net.GameProtocolSender;
import forge.net.ProtocolMethod;
import forge.player.PlayerZoneUpdate;
import forge.player.PlayerZoneUpdates;
import forge.trackable.TrackableCollection;
import forge.util.ITriggerEvent;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class NetGuiGame extends AbstractGuiGame {
private final GameProtocolSender sender;
@@ -283,14 +283,14 @@ public class NetGuiGame extends AbstractGuiGame {
}
@Override
public boolean openZones(final Collection<ZoneType> zones, final Map<PlayerView, Object> players) {
public PlayerZoneUpdates openZones(PlayerView controller, final Collection<ZoneType> zones, final Map<PlayerView, Object> players) {
updateGameView();
return sendAndWait(ProtocolMethod.openZones, zones, players);
return sendAndWait(ProtocolMethod.openZones, controller, zones, players);
}
@Override
public void restoreOldZones(final Map<PlayerView, Object> playersToRestoreZonesFor) {
send(ProtocolMethod.restoreOldZones, playersToRestoreZonesFor);
public void restoreOldZones(PlayerView playerView, PlayerZoneUpdates playerZoneUpdates) {
send(ProtocolMethod.restoreOldZones, playerView, playerZoneUpdates);
}
@Override

View File

@@ -14,11 +14,15 @@ public class PlayerZoneUpdate implements Serializable {
private final Set<ZoneType> zones;
public PlayerZoneUpdate(final PlayerView player, final ZoneType zone) {
if (player == null || zone == null) {
if (player == null ) {
throw new NullPointerException();
}
this.player = player;
this.zones = EnumSet.of(zone);
if (zone != null) {
this.zones = EnumSet.of(zone);
} else {
this.zones = EnumSet.noneOf(ZoneType.class);
}
}
public PlayerView getPlayer() {
@@ -30,13 +34,13 @@ public class PlayerZoneUpdate implements Serializable {
void addZone(final ZoneType zone) {
if (zone == null) {
throw new NullPointerException();
return;
}
zones.add(zone);
}
void add(final PlayerZoneUpdate other) {
if (other == null) {
throw new NullPointerException();
return;
}
zones.addAll(other.getZones());
}

View File

@@ -100,7 +100,7 @@ public class TargetSelection {
return true;
}
final List<ZoneType> zone = tgt.getZone();
final List<ZoneType> zones = tgt.getZone();
final boolean mandatory = tgt.getMandatory() && hasCandidates;
final boolean choiceResult;
@@ -110,7 +110,7 @@ public class TargetSelection {
final GameObject choice = Aggregates.random(candidates);
return ability.getTargets().add(choice);
}
else if (zone.size() == 1 && zone.get(0) == ZoneType.Stack) {
else if (zones.size() == 1 && zones.get(0) == ZoneType.Stack) {
// If Zone is Stack, the choices are handled slightly differently.
// Handle everything inside function due to interaction with StackInstance
return this.chooseCardFromStack(mandatory);
@@ -152,12 +152,15 @@ public class TargetSelection {
for (Card card : validTargets) {
playersWithValidTargets.put(PlayerView.get(card.getController()), null);
}
if (controller.getGui().openZones(zone, playersWithValidTargets)) {
PlayerView playerView = controller.getLocalPlayerView();
PlayerZoneUpdates playerZoneUpdates = controller.getGui().openZones(playerView, zones, playersWithValidTargets);
if (!zones.contains(ZoneType.Stack)) {
InputSelectTargets inp = new InputSelectTargets(controller, validTargets, ability, mandatory);
inp.showAndWait();
choiceResult = !inp.hasCancelled();
bTargetingDone = inp.hasPressedOk();
controller.getGui().restoreOldZones(playersWithValidTargets);
controller.getGui().restoreOldZones(playerView, playerZoneUpdates);
}
else {
// for every other case an all-purpose GuiChoose