mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Backup Plan with hot swappable Input
This commit is contained in:
@@ -31,6 +31,7 @@ import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.card.*;
|
||||
import forge.game.event.*;
|
||||
import forge.game.extrahands.BackupPlanService;
|
||||
import forge.game.keyword.Keyword;
|
||||
import forge.game.keyword.KeywordInterface;
|
||||
import forge.game.mulligan.MulliganService;
|
||||
@@ -2074,7 +2075,10 @@ public class GameAction {
|
||||
p1.drawCards(p1.getStartingHandSize());
|
||||
}
|
||||
|
||||
// If pl has Backup Plan as a Conspiracy draw that many extra hands
|
||||
BackupPlanService backupPlans = new BackupPlanService(p1);
|
||||
if (backupPlans.initializeExtraHands()) {
|
||||
backupPlans.chooseHand();
|
||||
}
|
||||
}
|
||||
|
||||
// Choose starting hand for each player with multiple hands
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package forge.game.extrahands;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.PlayerZone;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BackupPlanService {
|
||||
private final Player player;
|
||||
private boolean multipleHands = false;
|
||||
List<PlayerZone> hands = Lists.newArrayList();
|
||||
private PlayerZone hand;
|
||||
|
||||
public BackupPlanService(Player p1) {
|
||||
this.player = p1;
|
||||
}
|
||||
|
||||
public boolean initializeExtraHands() {
|
||||
hand = player.getZone(ZoneType.Hand);
|
||||
hands.add(hand);
|
||||
|
||||
// If pl has Backup Plan as a Conspiracy draw that many extra hands
|
||||
if (player.getExtraZones() == null) {
|
||||
return multipleHands;
|
||||
}
|
||||
for(PlayerZone extraHand : player.getExtraZones()) {
|
||||
if (extraHand.getZoneType() == ZoneType.ExtraHand) {
|
||||
player.drawCards(7, extraHand);
|
||||
multipleHands = true;
|
||||
hands.add(extraHand);
|
||||
// If we figure out how to render the zone in the UI, do it here
|
||||
}
|
||||
}
|
||||
|
||||
player.updateZoneForView(hand);
|
||||
return multipleHands;
|
||||
}
|
||||
|
||||
public void chooseHand() {
|
||||
if (!multipleHands) {
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerZone library = player.getZone(ZoneType.Library);
|
||||
// Choose one of the starting hands and recycle the rest
|
||||
PlayerZone startingHand = player.getController().chooseStartingHand(hands);
|
||||
if (startingHand == hand) {
|
||||
for(PlayerZone extraHand : player.getExtraZones()) {
|
||||
if (extraHand.getZoneType() == ZoneType.ExtraHand) {
|
||||
for (Card c : Lists.newArrayList(extraHand.getCards().iterator())) {
|
||||
player.getGame().getAction().moveTo(library, c, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Card c : Lists.newArrayList(hand.getCards().iterator())) {
|
||||
player.getGame().getAction().moveTo(library, c, null);
|
||||
}
|
||||
|
||||
for(PlayerZone extraHand : player.getExtraZones()) {
|
||||
boolean starting = startingHand.equals(extraHand);
|
||||
for (Card c : Lists.newArrayList(extraHand.getCards().iterator())) {
|
||||
if (starting) {
|
||||
player.getGame().getAction().moveTo(hand, c, null);
|
||||
} else {
|
||||
player.getGame().getAction().moveTo(library, c, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
player.resetExtraZones(ZoneType.ExtraHand);
|
||||
player.updateZoneForView(player.getZone(ZoneType.Hand));
|
||||
}
|
||||
}
|
||||
@@ -156,6 +156,8 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
private List<Card> completedDungeons = new ArrayList<>();
|
||||
|
||||
private final Map<ZoneType, PlayerZone> zones = Maps.newEnumMap(ZoneType.class);
|
||||
private List<PlayerZone> extraZones = null;
|
||||
|
||||
private final Map<Long, Integer> adjustLandPlays = Maps.newHashMap();
|
||||
private final Set<Long> adjustLandPlaysInfinite = Sets.newHashSet();
|
||||
private Map<Card, Card> maingameCardsMap = Maps.newHashMap();
|
||||
@@ -1198,9 +1200,18 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
|
||||
public final CardCollectionView drawCards(final int n) {
|
||||
return drawCards(n, null, AbilityKey.newMap());
|
||||
return drawCards(n, null, AbilityKey.newMap(), this.getZone(ZoneType.Hand));
|
||||
}
|
||||
|
||||
public final CardCollectionView drawCards(final int n, PlayerZone zone) {
|
||||
return drawCards(n, null, AbilityKey.newMap(), zone);
|
||||
}
|
||||
|
||||
public final CardCollectionView drawCards(final int n, SpellAbility cause, Map<AbilityKey, Object> params) {
|
||||
return drawCards(n, cause, params, this.getZone(ZoneType.Hand));
|
||||
}
|
||||
|
||||
public final CardCollectionView drawCards(final int n, SpellAbility cause, Map<AbilityKey, Object> params, PlayerZone zone) {
|
||||
final CardCollection drawn = new CardCollection();
|
||||
if (n <= 0) {
|
||||
return drawn;
|
||||
@@ -1225,7 +1236,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
if (gameStarted && !canDraw()) {
|
||||
return drawn;
|
||||
}
|
||||
drawn.addAll(doDraw(toReveal, cause, params));
|
||||
drawn.addAll(doDraw(toReveal, cause, params, zone));
|
||||
}
|
||||
|
||||
// reveal multiple drawn cards when playing with the top of the library revealed
|
||||
@@ -1240,7 +1251,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
/**
|
||||
* @return a CardCollectionView of cards actually drawn
|
||||
*/
|
||||
private CardCollectionView doDraw(Map<Player, CardCollection> revealed, SpellAbility sa, Map<AbilityKey, Object> params) {
|
||||
private CardCollectionView doDraw(Map<Player, CardCollection> revealed, SpellAbility sa, Map<AbilityKey, Object> params, PlayerZone hand) {
|
||||
final CardCollection drawn = new CardCollection();
|
||||
final PlayerZone library = getZone(ZoneType.Library);
|
||||
|
||||
@@ -1275,7 +1286,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
}
|
||||
|
||||
c = game.getAction().moveToHand(c, cause, params);
|
||||
c = game.getAction().moveTo(hand, c, cause, params);
|
||||
drawn.add(c);
|
||||
|
||||
// CR 121.6c additional actions can't be performed when draw gets replaced
|
||||
@@ -1341,6 +1352,15 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
}
|
||||
|
||||
public final List<PlayerZone> getExtraZones() {
|
||||
return extraZones;
|
||||
}
|
||||
|
||||
public void resetExtraZones(ZoneType type) {
|
||||
extraZones.removeIf(z -> z.getZoneType().equals(type));
|
||||
}
|
||||
|
||||
|
||||
public final CardCollectionView getCardsIn(final ZoneType zoneType) {
|
||||
return getCardsIn(zoneType, true);
|
||||
}
|
||||
@@ -2964,6 +2984,15 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (Objects.equals(conspire.getName(), "Backup Plan")) {
|
||||
PlayerZone hand = new PlayerZone(ZoneType.ExtraHand, this);
|
||||
if (this.extraZones == null) {
|
||||
this.extraZones = new ArrayList<>();
|
||||
}
|
||||
this.extraZones.add(hand);
|
||||
}
|
||||
|
||||
com.add(conspire);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,9 @@
|
||||
package forge.game.player;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import forge.game.*;
|
||||
import forge.game.mana.ManaCostBeingPaid;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.ICardFace;
|
||||
@@ -22,12 +11,9 @@ import forge.card.mana.ManaCost;
|
||||
import forge.card.mana.ManaCostShard;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.game.*;
|
||||
import forge.game.GameOutcome.AnteResult;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.card.*;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.cost.Cost;
|
||||
import forge.game.cost.CostPart;
|
||||
@@ -35,18 +21,23 @@ import forge.game.cost.CostPartMana;
|
||||
import forge.game.keyword.KeywordInterface;
|
||||
import forge.game.mana.Mana;
|
||||
import forge.game.mana.ManaConversionMatrix;
|
||||
import forge.game.mana.ManaCostBeingPaid;
|
||||
import forge.game.replacement.ReplacementEffect;
|
||||
import forge.game.spellability.AbilitySub;
|
||||
import forge.game.spellability.OptionalCostValue;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.spellability.TargetChoices;
|
||||
import forge.game.spellability.*;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
import forge.game.trigger.WrappedAbility;
|
||||
import forge.game.zone.PlayerZone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.collect.FCollectionView;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A prototype for player controller class
|
||||
@@ -192,6 +183,7 @@ public abstract class PlayerController {
|
||||
public abstract CardCollectionView chooseCardsToDelve(int genericAmount, CardCollection grave);
|
||||
public abstract CardCollectionView chooseCardsToRevealFromHand(int min, int max, CardCollectionView valid);
|
||||
public abstract List<SpellAbility> chooseSaToActivateFromOpeningHand(List<SpellAbility> usableFromOpeningHand);
|
||||
public abstract PlayerZone chooseStartingHand(List<PlayerZone> zones);
|
||||
public abstract Mana chooseManaFromPool(List<Mana> manaChoices);
|
||||
|
||||
public abstract String chooseSomeType(String kindOfType, SpellAbility sa, Collection<String> validTypes, List<String> invalidTypes, boolean isOptional);
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package forge.game.zone;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import forge.util.Localizer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import forge.util.Localizer;
|
||||
|
||||
/**
|
||||
* The Enum Zone.
|
||||
*/
|
||||
@@ -26,6 +25,8 @@ public enum ZoneType {
|
||||
SchemeDeck(true, "lblSchemeDeckZone"),
|
||||
PlanarDeck(true, "lblPlanarDeckZone"),
|
||||
Subgame(true, "lblSubgameZone"),
|
||||
// ExtraHand is used for Backup Plan for temporary extra hands
|
||||
ExtraHand(true, "lblHandZone"),
|
||||
None(true, "lblNoneZone");
|
||||
|
||||
public static final List<ZoneType> STATIC_ABILITIES_SOURCE_ZONES = Arrays.asList(Battlefield, Graveyard, Exile, Command, Stack/*, Hand*/);
|
||||
|
||||
Reference in New Issue
Block a user