diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index 7fb10c8bec..ce03353582 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -905,6 +905,15 @@ public class HumanPlayer extends PlayerImpl { attackedDefender, attacker.getId(), attacker.getControllerId()), game)) { continue; } + // if attacker needs a specific defender to attack so select that one instead + if (game.getCombat().getCreaturesForcedToAttack().containsKey(attacker.getId())) { + Set possibleDefenders = game.getCombat().getCreaturesForcedToAttack().get(attacker.getId()); + if (!possibleDefenders.isEmpty() && !possibleDefenders.contains(attackedDefender)) { + declareAttacker(attacker.getId(), possibleDefenders.iterator().next(), game, false); + continue; + } + } + // attack selected default defender declareAttacker(attacker.getId(), attackedDefender, game, false); } } else if (response.getBoolean() != null) { @@ -926,14 +935,18 @@ public class HumanPlayer extends PlayerImpl { } else { Permanent creature = game.getPermanent(creatureId); if (creature != null) { - sb.append(creature.getName()).append(" "); + sb.append(creature.getIdName()).append(" "); } } } if (game.getCombat().getMaxAttackers() > forcedAttackers) { - game.informPlayer(this, sb.insert(0, " more attacker(s) that are forced to attack.\nCreatures forced to attack: ") - .insert(0, Math.min(game.getCombat().getMaxAttackers() - forcedAttackers, game.getCombat().getCreaturesForcedToAttack().size() - forcedAttackers)) + int requireToAttack = Math.min(game.getCombat().getMaxAttackers() - forcedAttackers, game.getCombat().getCreaturesForcedToAttack().size() - forcedAttackers); + String message = (requireToAttack == 1 ? " more attacker that is " : " more attackers that are ") + + "forced to attack.\nCreature" + + (requireToAttack == 1 ? "" : "s") + " forced to attack: "; + game.informPlayer(this, sb.insert(0, message) + .insert(0, requireToAttack) .insert(0, "You have to attack with ").toString()); continue; } @@ -989,7 +1002,7 @@ public class HumanPlayer extends PlayerImpl { possibleDefender = defenders; } if (possibleDefender.size() == 1) { - declareAttacker(attackerId, defenders.iterator().next(), game, true); + declareAttacker(attackerId, possibleDefender.iterator().next(), game, true); return true; } else { TargetDefender target = new TargetDefender(possibleDefender, attackerId); diff --git a/Mage.Sets/src/mage/sets/gatecrash/GideonChampionOfJustice.java b/Mage.Sets/src/mage/sets/gatecrash/GideonChampionOfJustice.java index ddff7d8363..60ce90daee 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/GideonChampionOfJustice.java +++ b/Mage.Sets/src/mage/sets/gatecrash/GideonChampionOfJustice.java @@ -32,10 +32,8 @@ import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.CountersCount; import mage.abilities.dynamicvalue.common.PermanentsTargetOpponentControlsCount; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.PreventAllDamageToSourceEffect; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; diff --git a/Mage.Sets/src/mage/sets/magicorigins/GideonBattleForged.java b/Mage.Sets/src/mage/sets/magicorigins/GideonBattleForged.java index 67c718987c..926b6fab83 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/GideonBattleForged.java +++ b/Mage.Sets/src/mage/sets/magicorigins/GideonBattleForged.java @@ -62,27 +62,27 @@ import mage.target.common.TargetCreaturePermanent; public class GideonBattleForged extends CardImpl { private final static FilterCreaturePermanent filter = new FilterCreaturePermanent(); - + static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); } - + public GideonBattleForged(UUID ownerId) { super(ownerId, 23, "Gideon, Battle-Forged", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, ""); this.expansionSetCode = "ORI"; this.subtype.add("Gideon"); - + this.color.setWhite(true); - + this.nightCard = true; this.canTransform = true; - + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); - - // +2: Up to one target creature an opponent controls attacks Gideon, Battle-Forged during its controller's next turn if able. + + // +2: Up to one target creature an opponent controls attacks Gideon, Battle-Forged during its controller's next turn if able. LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new GideonBattleForgedAttacksIfAbleTargetEffect(Duration.Custom), 2); - loyaltyAbility.addTarget(new TargetCreaturePermanent(0,1,filter, false)); - this.addAbility(loyaltyAbility); + loyaltyAbility.addTarget(new TargetCreaturePermanent(0, 1, filter, false)); + this.addAbility(loyaltyAbility); // +1: Until your next turn, target creature gains indestructible. Untap that creature. Effect effect = new GainAbilityTargetEffect(IndestructibleAbility.getInstance(), Duration.UntilYourNextTurn); @@ -92,14 +92,14 @@ public class GideonBattleForged extends CardImpl { effect = new UntapTargetEffect(); effect.setText("Untap that creature"); loyaltyAbility.addEffect(effect); - this.addAbility(loyaltyAbility); + this.addAbility(loyaltyAbility); // 0: Until end of turn, Gideon, Battle-Forged becomes a 4/4 Human Soldier creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn. LoyaltyAbility ability3 = new LoyaltyAbility(new BecomesCreatureSourceEffect(new GideonBattleForgedToken(), "planeswalker", Duration.EndOfTurn), 0); effect = new PreventAllDamageToSourceEffect(Duration.EndOfTurn); effect.setText("Prevent all damage that would be dealt to him this turn"); ability3.addEffect(effect); - this.addAbility(ability3); + this.addAbility(ability3); } @@ -131,7 +131,7 @@ class GideonBattleForgedAttacksIfAbleTargetEffect extends RequirementEffect { int nextTurnTargetController = 0; protected MageObjectReference targetPermanentReference; - + public GideonBattleForgedAttacksIfAbleTargetEffect(Duration duration) { super(duration); staticText = "Up to one target creature an opponent controls attacks {this} during its controller's next turn if able"; @@ -147,7 +147,7 @@ class GideonBattleForgedAttacksIfAbleTargetEffect extends RequirementEffect { public GideonBattleForgedAttacksIfAbleTargetEffect copy() { return new GideonBattleForgedAttacksIfAbleTargetEffect(this); } - + @Override public boolean isInactive(Ability source, Game game) { if (targetPermanentReference == null) { @@ -160,10 +160,7 @@ class GideonBattleForgedAttacksIfAbleTargetEffect extends RequirementEffect { if (nextTurnTargetController == 0 && startingTurn != game.getTurnNum() && game.getActivePlayerId().equals(targetPermanent.getControllerId())) { nextTurnTargetController = game.getTurnNum(); } - if (game.getPhase().getType() == TurnPhase.END && nextTurnTargetController > 0 && game.getTurnNum() > nextTurnTargetController) { - return true; - } - return false; + return game.getPhase().getType() == TurnPhase.END && nextTurnTargetController > 0 && game.getTurnNum() > nextTurnTargetController; } @Override @@ -175,7 +172,7 @@ class GideonBattleForgedAttacksIfAbleTargetEffect extends RequirementEffect { targetPermanentReference = new MageObjectReference(getTargetPointer().getFirst(game, source), game); } } - + @Override public boolean applies(Permanent permanent, Ability source, Game game) { if (permanent.getId().equals(getTargetPointer().getFirst(game, source))) { diff --git a/Mage/src/mage/game/combat/Combat.java b/Mage/src/mage/game/combat/Combat.java index b07f052ff3..1aa89433f7 100644 --- a/Mage/src/mage/game/combat/Combat.java +++ b/Mage/src/mage/game/combat/Combat.java @@ -294,9 +294,9 @@ public class Combat implements Serializable, Copyable { } // force attack only if a defender can be attacked without paying a cost if (!defendersCostlessAttackable.isEmpty()) { + creaturesForcedToAttack.put(creature.getId(), defendersForcedToAttack); // No need to attack a special defender if (defendersForcedToAttack.isEmpty()) { - creaturesForcedToAttack.put(creature.getId(), defendersForcedToAttack); if (defendersForcedToAttack.isEmpty()) { if (defendersCostlessAttackable.size() == 1) { player.declareAttacker(creature.getId(), defenders.iterator().next(), game, false);