move HumanPlay, PlayerControllerHuman to forge.gui.player package

This commit is contained in:
Maxmtg
2013-12-20 00:22:20 +00:00
parent 93c7d28714
commit ef332e4568
18 changed files with 228 additions and 119 deletions

7
.gitattributes vendored
View File

@@ -15072,16 +15072,13 @@ forge-gui/src/main/java/forge/game/phase/Untap.java -text
forge-gui/src/main/java/forge/game/phase/Upkeep.java svneol=native#text/plain forge-gui/src/main/java/forge/game/phase/Upkeep.java svneol=native#text/plain
forge-gui/src/main/java/forge/game/phase/package-info.java svneol=native#text/plain forge-gui/src/main/java/forge/game/phase/package-info.java svneol=native#text/plain
forge-gui/src/main/java/forge/game/player/GameLossReason.java -text forge-gui/src/main/java/forge/game/player/GameLossReason.java -text
forge-gui/src/main/java/forge/game/player/HumanPlay.java -text
forge-gui/src/main/java/forge/game/player/LobbyPlayer.java -text forge-gui/src/main/java/forge/game/player/LobbyPlayer.java -text
forge-gui/src/main/java/forge/game/player/LobbyPlayerAi.java -text forge-gui/src/main/java/forge/game/player/LobbyPlayerAi.java -text
forge-gui/src/main/java/forge/game/player/LobbyPlayerHuman.java -text
forge-gui/src/main/java/forge/game/player/LobbyPlayerRemote.java -text forge-gui/src/main/java/forge/game/player/LobbyPlayerRemote.java -text
forge-gui/src/main/java/forge/game/player/Player.java svneol=native#text/plain forge-gui/src/main/java/forge/game/player/Player.java svneol=native#text/plain
forge-gui/src/main/java/forge/game/player/PlayerActionConfirmMode.java -text forge-gui/src/main/java/forge/game/player/PlayerActionConfirmMode.java -text
forge-gui/src/main/java/forge/game/player/PlayerController.java -text forge-gui/src/main/java/forge/game/player/PlayerController.java -text
forge-gui/src/main/java/forge/game/player/PlayerControllerAi.java -text forge-gui/src/main/java/forge/game/player/PlayerControllerAi.java -text
forge-gui/src/main/java/forge/game/player/PlayerControllerHuman.java -text
forge-gui/src/main/java/forge/game/player/PlayerOutcome.java -text forge-gui/src/main/java/forge/game/player/PlayerOutcome.java -text
forge-gui/src/main/java/forge/game/player/PlayerStatistics.java -text forge-gui/src/main/java/forge/game/player/PlayerStatistics.java -text
forge-gui/src/main/java/forge/game/player/PlayerType.java svneol=native#text/plain forge-gui/src/main/java/forge/game/player/PlayerType.java svneol=native#text/plain
@@ -15421,6 +15418,10 @@ forge-gui/src/main/java/forge/gui/menus/IMenuProvider.java -text
forge-gui/src/main/java/forge/gui/menus/LayoutMenu.java -text forge-gui/src/main/java/forge/gui/menus/LayoutMenu.java -text
forge-gui/src/main/java/forge/gui/menus/MenuUtil.java -text forge-gui/src/main/java/forge/gui/menus/MenuUtil.java -text
forge-gui/src/main/java/forge/gui/package-info.java svneol=native#text/plain forge-gui/src/main/java/forge/gui/package-info.java svneol=native#text/plain
forge-gui/src/main/java/forge/gui/player/HumanPlay.java -text
forge-gui/src/main/java/forge/gui/player/LobbyPlayerHuman.java -text
forge-gui/src/main/java/forge/gui/player/PlayerControllerHuman.java -text
forge-gui/src/main/java/forge/gui/player/package-info.java -text
forge-gui/src/main/java/forge/gui/toolbox/CardFaceSymbols.java svneol=native#text/plain forge-gui/src/main/java/forge/gui/toolbox/CardFaceSymbols.java svneol=native#text/plain
forge-gui/src/main/java/forge/gui/toolbox/FAbsolutePositioner.java -text forge-gui/src/main/java/forge/gui/toolbox/FAbsolutePositioner.java -text
forge-gui/src/main/java/forge/gui/toolbox/FButton.java -text forge-gui/src/main/java/forge/gui/toolbox/FButton.java -text

View File

@@ -46,7 +46,7 @@ import forge.game.Match;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.player.LobbyPlayer; import forge.game.player.LobbyPlayer;
import forge.game.player.LobbyPlayerAi; import forge.game.player.LobbyPlayerAi;
import forge.game.player.LobbyPlayerHuman; import forge.gui.player.LobbyPlayerHuman;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.RegisteredPlayer; import forge.game.player.RegisteredPlayer;
import forge.gui.GuiDialog; import forge.gui.GuiDialog;

View File

@@ -3,8 +3,6 @@ package forge.game.ability;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import forge.ai.ComputerUtil;
import forge.ai.ComputerUtilCost;
import forge.card.MagicColor; import forge.card.MagicColor;
import forge.card.mana.ManaCostShard; import forge.card.mana.ManaCostShard;
@@ -21,10 +19,7 @@ import forge.game.card.CardUtil;
import forge.game.card.CounterType; import forge.game.card.CounterType;
import forge.game.cost.Cost; import forge.game.cost.Cost;
import forge.game.mana.ManaCostBeingPaid; import forge.game.mana.ManaCostBeingPaid;
import forge.game.player.HumanPlay;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.Ability;
import forge.game.spellability.AbilityStatic;
import forge.game.spellability.AbilitySub; import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance; import forge.game.spellability.SpellAbilityStackInstance;
@@ -1198,7 +1193,7 @@ public class AbilityUtils {
// The player who has the chance to cancel the ability // The player who has the chance to cancel the ability
final String pays = sa.hasParam("UnlessPayer") ? sa.getParam("UnlessPayer") : "TargetedController"; final String pays = sa.hasParam("UnlessPayer") ? sa.getParam("UnlessPayer") : "TargetedController";
final List<Player> payers = getDefinedPlayers(sa.getSourceCard(), pays, sa); final List<Player> allPayers = getDefinedPlayers(sa.getSourceCard(), pays, sa);
final String resolveSubs = sa.getParam("UnlessResolveSubs"); // no value means 'Always' final String resolveSubs = sa.getParam("UnlessResolveSubs"); // no value means 'Always'
final boolean execSubsWhenPaid = "WhenPaid".equals(resolveSubs) || StringUtils.isBlank(resolveSubs); final boolean execSubsWhenPaid = "WhenPaid".equals(resolveSubs) || StringUtils.isBlank(resolveSubs);
final boolean execSubsWhenNotPaid = "WhenNotPaid".equals(resolveSubs) || StringUtils.isBlank(resolveSubs); final boolean execSubsWhenNotPaid = "WhenNotPaid".equals(resolveSubs) || StringUtils.isBlank(resolveSubs);
@@ -1233,27 +1228,16 @@ public class AbilityUtils {
cost = new Cost(unlessCost, true); cost = new Cost(unlessCost, true);
} }
boolean paid = false; boolean alreadyPaid = false;
for (Player payer : payers) { for (Player payer : allPayers) {
final Ability ability = new AbilityStatic(source, cost, sa.getTargetRestrictions()) { @Override public void resolve() { } }; alreadyPaid |= payer.getController().payCostToPreventEffect(cost, sa, alreadyPaid, allPayers);
ability.setActivatingPlayer(payer);
if (payer.isComputer()) {
if (ComputerUtilCost.willPayUnlessCost(sa, payer, cost, paid, payers) && ComputerUtilCost.canPayCost(ability, payer)) {
ComputerUtil.playNoStack(payer, ability, game); // Unless cost was payed - no resolve
paid = true;
}
}
else {
// if it's paid by the AI already the human can pay, but it won't change anything
paid |= HumanPlay.payCostDuringAbilityResolve(payer, source, cost, sa, null);
}
} }
if (paid == isSwitched) { if (alreadyPaid == isSwitched) {
sa.resolve(); sa.resolve();
} }
if (paid && execSubsWhenPaid || !paid && execSubsWhenNotPaid) { // switched refers only to main ability! if (alreadyPaid && execSubsWhenPaid || !alreadyPaid && execSubsWhenNotPaid) { // switched refers only to main ability!
resolveSubAbilities(sa, game); resolveSubAbilities(sa, game);
} }
} }

View File

@@ -11,7 +11,6 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import forge.Singletons; import forge.Singletons;
import forge.ai.ComputerUtil;
import forge.card.CardCharacteristicName; import forge.card.CardCharacteristicName;
import forge.card.CardRulesPredicates; import forge.card.CardRulesPredicates;
import forge.game.Game; import forge.game.Game;
@@ -19,7 +18,6 @@ import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect; import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.cost.Cost; import forge.game.cost.Cost;
import forge.game.player.HumanPlay;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.Spell; import forge.game.spellability.Spell;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
@@ -218,21 +216,8 @@ public class PlayEffect extends SpellAbilityEffect {
tgtSA.getTargetRestrictions().setMandatory(true); tgtSA.getTargetRestrictions().setMandatory(true);
} }
if (controller.isHuman()) {
HumanPlay.playSpellAbility(activator, tgtSA); remember = controller.getController().playSaFromPlayEffect(tgtSA);
} else {
if (tgtSA instanceof Spell) { // Isn't it ALWAYS a spell?
Spell spell = (Spell) tgtSA;
if (spell.canPlayFromEffectAI(controller, !optional, noManaCost) || !optional) {
if (noManaCost) {
ComputerUtil.playSpellAbilityWithoutPayingManaCost(controller, tgtSA, game);
} else {
ComputerUtil.playStack(tgtSA, controller, game);
}
} else
remember = false; // didn't play spell
}
}
if (remember) { if (remember) {
source.addRemembered(tgtSA.getSourceCard()); source.addRemembered(tgtSA.getSourceCard());
} }

View File

@@ -30,6 +30,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance; import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.TargetChoices; import forge.game.spellability.TargetChoices;
import forge.game.trigger.Trigger; import forge.game.trigger.Trigger;
import forge.game.trigger.WrappedAbility;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -197,4 +198,11 @@ public abstract class PlayerController {
public abstract boolean confirmPayment(CostPart costPart, String string); public abstract boolean confirmPayment(CostPart costPart, String string);
public abstract ReplacementEffect chooseSingleReplacementEffect(String prompt, List<ReplacementEffect> possibleReplacers, HashMap<String, Object> runParams); public abstract ReplacementEffect chooseSingleReplacementEffect(String prompt, List<ReplacementEffect> possibleReplacers, HashMap<String, Object> runParams);
public abstract String chooseProtectionType(String string, SpellAbility sa, List<String> choices); public abstract String chooseProtectionType(String string, SpellAbility sa, List<String> choices);
// these 4 need some refining.
public abstract boolean payCostToPreventEffect(Cost cost, SpellAbility sa, boolean alreadyPaid, List<Player> allPayers);
public abstract void orderAndPlaySimultaneousSa(List<SpellAbility> activePlayerSAs);
public abstract void playTrigger(Card host, WrappedAbility wrapperAbility, boolean isMandatory);
public abstract boolean playSaFromPlayEffect(SpellAbility tgtSA);
} }

View File

@@ -32,6 +32,7 @@ import forge.game.Game;
import forge.game.GameEntity; import forge.game.GameEntity;
import forge.game.GameObject; import forge.game.GameObject;
import forge.game.GameType; import forge.game.GameType;
import forge.game.ability.AbilityUtils;
import forge.game.ability.ApiType; import forge.game.ability.ApiType;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardLists; import forge.game.card.CardLists;
@@ -49,7 +50,9 @@ import forge.game.spellability.Spell;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance; import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.TargetChoices; import forge.game.spellability.TargetChoices;
import forge.game.spellability.TargetSelection;
import forge.game.trigger.Trigger; import forge.game.trigger.Trigger;
import forge.game.trigger.WrappedAbility;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.util.Aggregates; import forge.util.Aggregates;
@@ -604,4 +607,63 @@ public class PlayerControllerAi extends PlayerController {
} }
return choice; return choice;
} }
@Override
public boolean payCostToPreventEffect(Cost cost, SpellAbility sa, boolean alreadyPaid, List<Player> allPayers) {
final Card source = sa.getSourceCard();
final Ability emptyAbility = new AbilityStatic(source, cost, sa.getTargetRestrictions()) { @Override public void resolve() { } };
emptyAbility.setActivatingPlayer(player);
if (ComputerUtilCost.willPayUnlessCost(sa, player, cost, alreadyPaid, allPayers) && ComputerUtilCost.canPayCost(emptyAbility, player)) {
ComputerUtil.playNoStack(player, emptyAbility, game); // AI needs something to resolve to pay that cost
return true;
}
return false;
}
@Override
public void orderAndPlaySimultaneousSa(List<SpellAbility> activePlayerSAs) {
for (final SpellAbility sa : activePlayerSAs) {
prepareSingleSa(sa.getSourceCard(),sa,true);
ComputerUtil.playStack(sa, player, game);
}
}
private void prepareSingleSa(final Card host, final SpellAbility sa, boolean isMandatory){
if (sa.hasParam("TargetingPlayer")) {
Player targetingPlayer = AbilityUtils.getDefinedPlayers(host, sa.getParam("TargetingPlayer"), sa).get(0);
if (targetingPlayer.isHuman()) {
final TargetSelection select = new TargetSelection(sa);
select.chooseTargets(null);
} else { //AI
sa.doTrigger(true, targetingPlayer);
}
} else {
sa.doTrigger(isMandatory, player);
}
}
@Override
public void playTrigger(Card host, WrappedAbility wrapperAbility, boolean isMandatory) {
prepareSingleSa(host, wrapperAbility, isMandatory);
ComputerUtil.playNoStack(wrapperAbility.getActivatingPlayer(), wrapperAbility, game);
}
@Override
public boolean playSaFromPlayEffect(SpellAbility tgtSA) {
boolean optional = tgtSA.hasParam("Optional");
boolean noManaCost = tgtSA.hasParam("WithoutManaCost");
if (tgtSA instanceof Spell) { // Isn't it ALWAYS a spell?
Spell spell = (Spell) tgtSA;
if (spell.canPlayFromEffectAI(player, !optional, noManaCost) || !optional) {
if (noManaCost) {
ComputerUtil.playSpellAbilityWithoutPayingManaCost(player, tgtSA, game);
} else {
ComputerUtil.playStack(tgtSA, player, game);
}
} else
return false; // didn't play spell
}
return true;
}
} }

View File

@@ -23,7 +23,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import forge.ai.ComputerUtil;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.game.Game; import forge.game.Game;
import forge.game.GlobalRuleChange; import forge.game.GlobalRuleChange;
@@ -33,12 +32,10 @@ import forge.game.ability.ApiType;
import forge.game.ability.effects.CharmEffect; import forge.game.ability.effects.CharmEffect;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.HumanPlay;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.Ability; import forge.game.spellability.Ability;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions; import forge.game.spellability.TargetRestrictions;
import forge.game.spellability.TargetSelection;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
public class TriggerHandler { public class TriggerHandler {
@@ -413,23 +410,7 @@ public class TriggerHandler {
wrapperAbility.setDescription(wrapperAbility.getStackDescription()); wrapperAbility.setDescription(wrapperAbility.getStackDescription());
if (regtrig.isStatic()) { if (regtrig.isStatic()) {
if (wrapperAbility.getActivatingPlayer().isHuman()) { wrapperAbility.getActivatingPlayer().getController().playTrigger(host, wrapperAbility, isMandatory);
HumanPlay.playSpellAbilityNoStack(wrapperAbility.getActivatingPlayer(), wrapperAbility);
} else {
if (wrapperAbility.hasParam("TargetingPlayer")) {
Player targetingPlayer = AbilityUtils.getDefinedPlayers(host, wrapperAbility.getParam("TargetingPlayer"), wrapperAbility).get(0);
if (targetingPlayer.isHuman()) {
wrapperAbility.resetTargets();
final TargetSelection select = new TargetSelection(wrapperAbility);
select.chooseTargets(null);
} else { //AI
wrapperAbility.doTrigger(true, targetingPlayer);
}
} else {
wrapperAbility.doTrigger(isMandatory, wrapperAbility.getActivatingPlayer());
}
ComputerUtil.playNoStack(wrapperAbility.getActivatingPlayer(), wrapperAbility, game);
}
} else { } else {
game.getStack().addSimultaneousStackEntry(wrapperAbility); game.getStack().addSimultaneousStackEntry(wrapperAbility);
} }

View File

@@ -31,7 +31,6 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import forge.FThreads; import forge.FThreads;
import forge.ai.ComputerUtil;
import forge.ai.ComputerUtilCard; import forge.ai.ComputerUtilCard;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.game.Game; import forge.game.Game;
@@ -50,7 +49,6 @@ import forge.game.event.GameEventCardStatsChanged;
import forge.game.event.GameEventSpellAbilityCast; import forge.game.event.GameEventSpellAbilityCast;
import forge.game.event.GameEventSpellRemovedFromStack; import forge.game.event.GameEventSpellRemovedFromStack;
import forge.game.event.GameEventSpellResolved; import forge.game.event.GameEventSpellResolved;
import forge.game.player.HumanPlay;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerController.ManaPaymentPurpose; import forge.game.player.PlayerController.ManaPaymentPurpose;
import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementEffect;
@@ -65,10 +63,8 @@ import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance; import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.TargetChoices; import forge.game.spellability.TargetChoices;
import forge.game.spellability.TargetRestrictions; import forge.game.spellability.TargetRestrictions;
import forge.game.spellability.TargetSelection;
import forge.game.trigger.Trigger; import forge.game.trigger.Trigger;
import forge.game.trigger.TriggerType; import forge.game.trigger.TriggerType;
import forge.gui.GuiChoose;
import forge.gui.input.InputSelectCards; import forge.gui.input.InputSelectCards;
import forge.gui.input.InputSelectCardsFromList; import forge.gui.input.InputSelectCardsFromList;
@@ -865,37 +861,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
return; return;
} }
if (activePlayer.isComputer()) { activePlayer.getController().orderAndPlaySimultaneousSa(activePlayerSAs);
for (final SpellAbility sa : activePlayerSAs) {
if (sa.hasParam("TargetingPlayer")) {
Player targetingPlayer = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("TargetingPlayer"), sa).get(0);
if (targetingPlayer.isHuman()) {
final TargetSelection select = new TargetSelection(sa);
select.chooseTargets(null);
} else { //AI
sa.doTrigger(true, targetingPlayer);
}
} else {
sa.doTrigger(true, activePlayer);
}
ComputerUtil.playStack(sa, activePlayer, game);
}
} else {
List<SpellAbility> orderedSAs = activePlayerSAs;
if (activePlayerSAs.size() > 1) { // give a dual list form to create instead of needing to do it one at a time
orderedSAs = GuiChoose.order("Select order for Simultaneous Spell Abilities", "Resolve first", 0, activePlayerSAs, null, null);
}
int size = orderedSAs.size();
for (int i = size - 1; i >= 0; i--) {
SpellAbility next = orderedSAs.get(i);
if (next.isTrigger()) {
HumanPlay.playSpellAbility(activePlayer, next);
} else {
this.add(next);
}
}
}
} }
/** /**

View File

@@ -46,7 +46,7 @@ import forge.game.card.CardLists;
import forge.game.card.CardPredicates; import forge.game.card.CardPredicates;
import forge.game.card.CounterType; import forge.game.card.CounterType;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.HumanPlay; import forge.gui.player.HumanPlay;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.AbilityManaPart; import forge.game.spellability.AbilityManaPart;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;

View File

@@ -17,7 +17,7 @@ import forge.game.ability.ApiType;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardUtil; import forge.game.card.CardUtil;
import forge.game.mana.ManaCostBeingPaid; import forge.game.mana.ManaCostBeingPaid;
import forge.game.player.HumanPlay; import forge.gui.player.HumanPlay;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerControllerAi; import forge.game.player.PlayerControllerAi;
import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementEffect;

View File

@@ -30,7 +30,7 @@ import forge.Singletons;
import forge.Constant.Preferences; import forge.Constant.Preferences;
import forge.game.Game; import forge.game.Game;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.player.HumanPlay; import forge.gui.player.HumanPlay;
import forge.game.player.LobbyPlayer; import forge.game.player.LobbyPlayer;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;

View File

@@ -1,4 +1,4 @@
package forge.game.player; package forge.gui.player;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -47,6 +47,7 @@ import forge.game.cost.CostReveal;
import forge.game.cost.CostSacrifice; import forge.game.cost.CostSacrifice;
import forge.game.cost.CostTapType; import forge.game.cost.CostTapType;
import forge.game.mana.ManaCostBeingPaid; import forge.game.mana.ManaCostBeingPaid;
import forge.game.player.Player;
import forge.game.spellability.Ability; import forge.game.spellability.Ability;
import forge.game.spellability.HumanPlaySpellAbility; import forge.game.spellability.HumanPlaySpellAbility;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
@@ -343,16 +344,9 @@ public class HumanPlay {
return false; return false;
} }
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder("Do you want to ");
sb.append("Do you want to ");
sb.append(res.contains(p) ? "" : "let that player "); sb.append(res.contains(p) ? "" : "let that player ");
sb.append("draw " + amount); sb.append("draw " + Lang.nounWithAmount(amount, " card") + "?" + orString);
sb.append(" card");
if (amount != 1) {
sb.append("s");
}
sb.append("?" + orString);
if (!p.getController().confirmPayment(part, sb.toString())) { if (!p.getController().confirmPayment(part, sb.toString())) {
return false; return false;

View File

@@ -1,6 +1,10 @@
package forge.game.player; package forge.gui.player;
import forge.game.Game; import forge.game.Game;
import forge.game.player.LobbyPlayer;
import forge.game.player.Player;
import forge.game.player.PlayerController;
import forge.game.player.PlayerType;
import forge.gui.FNetOverlay; import forge.gui.FNetOverlay;
public class LobbyPlayerHuman extends LobbyPlayer { public class LobbyPlayerHuman extends LobbyPlayer {

View File

@@ -1,4 +1,4 @@
package forge.game.player; package forge.gui.player;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
@@ -44,6 +44,10 @@ import forge.game.cost.Cost;
import forge.game.cost.CostPart; import forge.game.cost.CostPart;
import forge.game.mana.Mana; import forge.game.mana.Mana;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.LobbyPlayer;
import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
import forge.game.player.PlayerController;
import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementEffect;
import forge.game.spellability.AbilitySub; import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
@@ -51,6 +55,7 @@ import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.TargetChoices; import forge.game.spellability.TargetChoices;
import forge.game.spellability.TargetSelection; import forge.game.spellability.TargetSelection;
import forge.game.trigger.Trigger; import forge.game.trigger.Trigger;
import forge.game.trigger.WrappedAbility;
import forge.game.zone.Zone; import forge.game.zone.Zone;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
@@ -948,4 +953,39 @@ public class PlayerControllerHuman extends PlayerController {
public String chooseProtectionType(String string, SpellAbility sa, List<String> choices) { public String chooseProtectionType(String string, SpellAbility sa, List<String> choices) {
return GuiChoose.one(string, choices); return GuiChoose.one(string, choices);
} }
@Override
public boolean payCostToPreventEffect(Cost cost, SpellAbility sa, boolean alreadyPaid, List<Player> allPayers) {
// if it's paid by the AI already the human can pay, but it won't change anything
final Card source = sa.getSourceCard();
return HumanPlay.payCostDuringAbilityResolve(player, source, cost, sa, null);
}
@Override
public void orderAndPlaySimultaneousSa(List<SpellAbility> activePlayerSAs) {
List<SpellAbility> orderedSAs = activePlayerSAs;
if (activePlayerSAs.size() > 1) { // give a dual list form to create instead of needing to do it one at a time
orderedSAs = GuiChoose.order("Select order for Simultaneous Spell Abilities", "Resolve first", 0, activePlayerSAs, null, null);
}
int size = orderedSAs.size();
for (int i = size - 1; i >= 0; i--) {
SpellAbility next = orderedSAs.get(i);
if (next.isTrigger()) {
HumanPlay.playSpellAbility(player, next);
} else {
player.getGame().getStack().add(next);
}
}
}
@Override
public void playTrigger(Card host, WrappedAbility wrapperAbility, boolean isMandatory) {
HumanPlay.playSpellAbilityNoStack(player, wrapperAbility);
}
@Override
public boolean playSaFromPlayEffect(SpellAbility tgtSA) {
HumanPlay.playSpellAbility(player, tgtSA);
return true;
}
} }

View File

@@ -0,0 +1,8 @@
/**
*
*/
/**
* @author Max
*
*/
package forge.gui.player;

View File

@@ -8,13 +8,17 @@ import java.util.concurrent.CountDownLatch;
import org.apache.commons.lang3.time.StopWatch; import org.apache.commons.lang3.time.StopWatch;
import com.google.common.base.Supplier;
import forge.Singletons; import forge.Singletons;
import forge.deck.Deck; import forge.deck.Deck;
import forge.game.Game; import forge.game.Game;
import forge.game.GameLogEntry; import forge.game.GameLogEntry;
import forge.game.GameType; import forge.game.GameType;
import forge.game.Match; import forge.game.Match;
import forge.game.player.LobbyPlayer;
import forge.game.player.RegisteredPlayer; import forge.game.player.RegisteredPlayer;
import forge.gui.player.LobbyPlayerHuman;
import forge.util.Lang; import forge.util.Lang;
@@ -30,7 +34,14 @@ public enum FServer {
public Lobby getLobby() { public Lobby getLobby() {
if (lobby == null) { if (lobby == null) {
lobby = new Lobby(); //not a very good solution still
lobby = new Lobby(new Supplier<LobbyPlayer>() {
@Override
public LobbyPlayer get() {
// TODO Auto-generated method stub
return new LobbyPlayerHuman("Human");
}
});
} }
return lobby; return lobby;
} }

View File

@@ -4,10 +4,11 @@ import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import com.google.common.base.Supplier;
import forge.control.ChatArea; import forge.control.ChatArea;
import forge.game.player.LobbyPlayer; import forge.game.player.LobbyPlayer;
import forge.game.player.LobbyPlayerAi; import forge.game.player.LobbyPlayerAi;
import forge.game.player.LobbyPlayerHuman;
import forge.game.player.LobbyPlayerRemote; import forge.game.player.LobbyPlayerRemote;
import forge.gui.GuiDisplayUtil; import forge.gui.GuiDisplayUtil;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
@@ -20,7 +21,6 @@ import forge.util.MyRandom;
*/ */
public class Lobby { public class Lobby {
private final String[] opponentNames = new String[] { private final String[] opponentNames = new String[] {
"Abigail", "Ada", "Adeline", "Adriana", "Agatha", "Agnes", "Aileen", "Alba", "Alcyon", "Abigail", "Ada", "Adeline", "Adriana", "Agatha", "Agnes", "Aileen", "Alba", "Alcyon",
"Alethea", "Alice", "Alicia", "Alison", "Amanda", "Amelia", "Amy", "Andrea", "Angelina", "Alethea", "Alice", "Alicia", "Alison", "Amanda", "Amelia", "Amy", "Andrea", "Angelina",
@@ -62,8 +62,14 @@ public class Lobby {
"Walter", "Wilfred", "William", "Winston" "Walter", "Wilfred", "William", "Winston"
}; };
private final LobbyPlayer guiPlayer;
public Lobby(Supplier<LobbyPlayer> humanFactory){
guiPlayer = humanFactory.get();
}
private Map<String, LobbyPlayerRemote> remotePlayers = new ConcurrentHashMap<String, LobbyPlayerRemote>(); private Map<String, LobbyPlayerRemote> remotePlayers = new ConcurrentHashMap<String, LobbyPlayerRemote>();
private final LobbyPlayerHuman guiPlayer = new LobbyPlayerHuman("Human");
private final LobbyPlayerAi system = new LobbyPlayerAi("System"); private final LobbyPlayerAi system = new LobbyPlayerAi("System");
public final LobbyPlayer getGuiPlayer() { public final LobbyPlayer getGuiPlayer() {

View File

@@ -14,6 +14,7 @@ import org.apache.commons.lang3.tuple.Pair;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import forge.ai.ComputerUtil;
import forge.ai.ability.ChangeZoneAi; import forge.ai.ability.ChangeZoneAi;
import forge.ai.ability.DrawAi; import forge.ai.ability.DrawAi;
import forge.ai.ability.GameWinAi; import forge.ai.ability.GameWinAi;
@@ -24,6 +25,7 @@ import forge.game.Game;
import forge.game.GameEntity; import forge.game.GameEntity;
import forge.game.GameObject; import forge.game.GameObject;
import forge.game.GameType; import forge.game.GameType;
import forge.game.ability.AbilityUtils;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CounterType; import forge.game.card.CounterType;
import forge.game.combat.Combat; import forge.game.combat.Combat;
@@ -31,17 +33,20 @@ import forge.game.combat.CombatUtil;
import forge.game.cost.Cost; import forge.game.cost.Cost;
import forge.game.cost.CostPart; import forge.game.cost.CostPart;
import forge.game.mana.Mana; import forge.game.mana.Mana;
import forge.game.player.HumanPlay; import forge.gui.player.HumanPlay;
import forge.game.player.LobbyPlayer; import forge.game.player.LobbyPlayer;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode; import forge.game.player.PlayerActionConfirmMode;
import forge.game.player.PlayerController; import forge.game.player.PlayerController;
import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementEffect;
import forge.game.spellability.AbilitySub; import forge.game.spellability.AbilitySub;
import forge.game.spellability.Spell;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance; import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.TargetChoices; import forge.game.spellability.TargetChoices;
import forge.game.spellability.TargetSelection;
import forge.game.trigger.Trigger; import forge.game.trigger.Trigger;
import forge.game.trigger.WrappedAbility;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gamesimulationtests.util.card.CardSpecification; import forge.gamesimulationtests.util.card.CardSpecification;
import forge.gamesimulationtests.util.card.CardSpecificationHandler; import forge.gamesimulationtests.util.card.CardSpecificationHandler;
@@ -473,4 +478,58 @@ public class PlayerControllerForTests extends PlayerController {
public String chooseProtectionType(String string, SpellAbility sa, List<String> choices) { public String chooseProtectionType(String string, SpellAbility sa, List<String> choices) {
return choices.get(0); return choices.get(0);
} }
@Override
public boolean payCostToPreventEffect(Cost cost, SpellAbility sa, boolean alreadyPaid, List<Player> allPayers) {
// TODO Auto-generated method stub
return false;
}
@Override
public void orderAndPlaySimultaneousSa(List<SpellAbility> activePlayerSAs) {
for (final SpellAbility sa : activePlayerSAs) {
prepareSingleSa(sa.getSourceCard(),sa,true);
ComputerUtil.playStack(sa, player, game);
}
}
private void prepareSingleSa(final Card host, final SpellAbility sa, boolean isMandatory){
if (sa.hasParam("TargetingPlayer")) {
Player targetingPlayer = AbilityUtils.getDefinedPlayers(host, sa.getParam("TargetingPlayer"), sa).get(0);
if (targetingPlayer.isHuman()) {
final TargetSelection select = new TargetSelection(sa);
select.chooseTargets(null);
} else { //AI
sa.doTrigger(true, targetingPlayer);
}
} else {
sa.doTrigger(isMandatory, player);
}
}
@Override
public void playTrigger(Card host, WrappedAbility wrapperAbility, boolean isMandatory) {
prepareSingleSa(host, wrapperAbility, isMandatory);
ComputerUtil.playNoStack(wrapperAbility.getActivatingPlayer(), wrapperAbility, game);
}
@Override
public boolean playSaFromPlayEffect(SpellAbility tgtSA) {
// TODO Auto-generated method stub
boolean optional = tgtSA.hasParam("Optional");
boolean noManaCost = tgtSA.hasParam("WithoutManaCost");
if (tgtSA instanceof Spell) { // Isn't it ALWAYS a spell?
Spell spell = (Spell) tgtSA;
if (spell.canPlayFromEffectAI(player, !optional, noManaCost) || !optional) {
if (noManaCost) {
ComputerUtil.playSpellAbilityWithoutPayingManaCost(player, tgtSA, game);
} else {
ComputerUtil.playStack(tgtSA, player, game);
}
} else
return false; // didn't play spell
}
return true;
}
} }