Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FDN New Combat Rules #13279

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Mage.Common/src/main/java/mage/view/CombatGroupView.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public CombatGroupView(CombatGroup combatGroup, Game game) {
attackers.put(id, new PermanentView(attacker, game.getCard(attacker.getId()),null, game));
}
}
for (UUID id: combatGroup.getBlockerOrder()) {
for (UUID id: combatGroup.getBlockers()) {
Permanent blocker = game.getPermanent(id);
if (blocker != null) {
blockers.put(id, new PermanentView(blocker, game.getCard(blocker.getId()), null, game));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@
import mage.constants.Outcome;
import mage.constants.RangeOfInfluence;
import mage.game.Game;
import mage.game.combat.CombatGroup;
import mage.game.draft.Draft;
import mage.game.match.Match;
import mage.game.permanent.Permanent;
import mage.game.tournament.Tournament;
import mage.players.Player;
import mage.target.Target;
Expand Down Expand Up @@ -287,24 +285,6 @@ public void selectBlockers(Ability source, Game game, UUID defendingPlayerId) {
}
}

@Override
public UUID chooseAttackerOrder(java.util.List<Permanent> attackers, Game game) {
if (isUnderMe(game)) {
return super.chooseAttackerOrder(attackers, game);
} else {
return getControllingPlayer(game).chooseAttackerOrder(attackers, game);
}
}

@Override
public UUID chooseBlockerOrder(java.util.List<Permanent> blockers, CombatGroup combatGroup, java.util.List<UUID> blockerOrder, Game game) {
if (isUnderMe(game)) {
return super.chooseBlockerOrder(blockers, combatGroup, blockerOrder, game);
} else {
return getControllingPlayer(game).chooseBlockerOrder(blockers, combatGroup, blockerOrder, game);
}
}

@Override
public int getAmount(int min, int max, String message, Game game) {
if (isUnderMe(game)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2165,9 +2165,6 @@ public TriggeredAbility chooseTriggeredAbility(List<TriggeredAbility> abilities,
// TODO: add AI support with outcome and replace random with min/max
public int getAmount(int min, int max, String message, Game game) {
log.debug("getAmount");
if (message.startsWith("Assign damage to ")) {
return min;
}
if (min < max && min == 0) {
return RandomUtil.nextInt(CardUtil.overflowInc(max, 1));
}
Expand All @@ -2180,7 +2177,7 @@ public List<Integer> getMultiAmountWithIndividualConstraints(Outcome outcome, Li
log.debug("getMultiAmount");

int needCount = messages.size();
List<Integer> defaultList = MultiAmountType.prepareDefaltValues(messages, totalMin, totalMax);
List<Integer> defaultList = MultiAmountType.prepareDefaultValues(messages, totalMin, totalMax);
if (needCount == 0) {
return defaultList;
}
Expand All @@ -2198,18 +2195,6 @@ public List<Integer> getMultiAmountWithIndividualConstraints(Outcome outcome, Li
return MultiAmountType.prepareMaxValues(messages, totalMin, totalMax);
}

@Override
public UUID chooseAttackerOrder(List<Permanent> attackers, Game game) {
//TODO: improve this
return attackers.iterator().next().getId();
}

@Override
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) {
//TODO: improve this
return blockers.iterator().next().getId();
}

@Override
public List<MageObject> getAvailableManaProducers(Game game) {
return super.getAvailableManaProducers(game);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,22 +374,6 @@ public Mode chooseMode(Modes modes, Ability source, Game game) {
return super.chooseMode(modes, source, game);
}

@Override
public UUID chooseAttackerOrder(List<Permanent> attackers, Game game) {
if (this.isHuman()) {
return attackers.get(RandomUtil.nextInt(attackers.size())).getId();
}
return super.chooseAttackerOrder(attackers, game);
}

@Override
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) {
if (this.isHuman()) {
return blockers.get(RandomUtil.nextInt(blockers.size())).getId();
}
return super.chooseBlockerOrder(blockers, combatGroup, blockerOrder, game);
}

@Override
public int getAmount(int min, int max, String message, Game game) {
if (this.isHuman()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2122,56 +2122,6 @@ public void selectBlockers(Ability source, Game game, UUID defendingPlayerId) {
}
}

@Override
public UUID chooseAttackerOrder(java.util.List<Permanent> attackers, Game game) {
if (gameInCheckPlayableState(game)) {
return null;
}

while (canRespond()) {
prepareForResponse(game);
if (!isExecutingMacro()) {
game.fireSelectTargetEvent(playerId, "Pick attacker", attackers, true);
}
waitForResponse(game);

UUID responseId = getFixedResponseUUID(game);
if (responseId != null) {
for (Permanent perm : attackers) {
if (perm.getId().equals(responseId)) {
return perm.getId();
}
}
}
}
return null;
}

@Override
public UUID chooseBlockerOrder(java.util.List<Permanent> blockers, CombatGroup combatGroup, java.util.List<UUID> blockerOrder, Game game) {
if (gameInCheckPlayableState(game)) {
return null;
}

while (canRespond()) {
prepareForResponse(game);
if (!isExecutingMacro()) {
game.fireSelectTargetEvent(playerId, "Pick blocker", blockers, true);
}
waitForResponse(game);

UUID responseId = getFixedResponseUUID(game);
if (responseId != null) {
for (Permanent perm : blockers) {
if (perm.getId().equals(responseId)) {
return perm.getId();
}
}
}
}
return null;
}

protected void selectCombatGroup(UUID defenderId, UUID blockerId, Game game) {
if (gameInCheckPlayableState(game)) {
return;
Expand Down Expand Up @@ -2260,7 +2210,7 @@ public List<Integer> getMultiAmountWithIndividualConstraints(
Game game
) {
int needCount = messages.size();
List<Integer> defaultList = MultiAmountType.prepareDefaltValues(messages, totalMin, totalMax);
List<Integer> defaultList = MultiAmountType.prepareDefaultValues(messages, totalMin, totalMax);
if (needCount == 0 || (needCount == 1 && totalMin == totalMax)
|| messages.stream().map(m -> m.min == m.max).reduce(true, Boolean::logicalAnd)) {
// nothing to choose
Expand Down
15 changes: 0 additions & 15 deletions Mage.Sets/src/mage/cards/b/BalduvianWarlord.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,26 +153,11 @@ public boolean apply(Game game, Ability source) {
game.fireEvent(new BlockerDeclaredEvent(chosenPermanent.getId(), permanent.getId(), permanent.getControllerId()));
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKS, permanent.getId(), source, null));
}
CombatGroup blockGroup = findBlockingGroup(permanent, game); // a new blockingGroup is formed, so it's necessary to find it again
if (blockGroup != null) {
blockGroup.pickAttackerOrder(permanent.getControllerId(), game);
}
}
}
return true;
}
}
return false;
}

private CombatGroup findBlockingGroup(Permanent blocker, Game game) {
if (game.getCombat().blockingGroupsContains(blocker.getId())) { // if (blocker.getBlocking() > 1) {
for (CombatGroup group : game.getCombat().getBlockingGroups()) {
if (group.getBlockers().contains(blocker.getId())) {
return group;
}
}
}
return null;
}
}
4 changes: 2 additions & 2 deletions Mage.Sets/src/mage/cards/b/BrimazKingOfOreskos.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

package mage.cards.b;

import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
Expand All @@ -22,6 +21,8 @@
import mage.game.permanent.token.Token;
import mage.players.Player;

import java.util.UUID;

/**
*
* @author LevelX2
Expand Down Expand Up @@ -99,7 +100,6 @@ public boolean apply(Game game, Ability source) {
combatGroup.addBlocker(tokenId, source.getControllerId(), game);
game.getCombat().addBlockingGroup(tokenId, attackingCreature.getId(), controller.getId(), game);
}
combatGroup.pickBlockerOrder(attackingCreature.getControllerId(), game);

return true;
}
Expand Down
15 changes: 0 additions & 15 deletions Mage.Sets/src/mage/cards/f/FalseOrders.java
Original file line number Diff line number Diff line change
Expand Up @@ -169,21 +169,6 @@ public boolean apply(Game game, Ability source) {
game.fireEvent(new BlockerDeclaredEvent(chosenPermanent.getId(), permanent.getId(), permanent.getControllerId()));
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKS, permanent.getId(), source, null));
}
CombatGroup blockGroup = findBlockingGroup(permanent, game); // a new blockingGroup is formed, so it's necessary to find it again
if (blockGroup != null) {
blockGroup.pickAttackerOrder(permanent.getControllerId(), game);
}
return true;
}

private CombatGroup findBlockingGroup(Permanent blocker, Game game) {
if (game.getCombat().blockingGroupsContains(blocker.getId())) { // if (blocker.getBlocking() > 1) {
for (CombatGroup group : game.getCombat().getBlockingGroups()) {
if (group.getBlockers().contains(blocker.getId())) {
return group;
}
}
}
return null;
}
}
1 change: 0 additions & 1 deletion Mage.Sets/src/mage/cards/f/FlashFoliage.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ public boolean apply(Game game, Ability source) {
game.getCombat().addBlockingGroup(tokenId, attackingCreature.getId(), controller.getId(), game);
}
}
combatGroup.pickBlockerOrder(attackingCreature.getControllerId(), game);
}
}
return true;
Expand Down
19 changes: 6 additions & 13 deletions Mage.Sets/src/mage/cards/g/GeneralJarkeld.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@

package mage.cards.g;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.condition.common.IsStepCondition;
Expand All @@ -13,18 +9,18 @@
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.constants.*;
import mage.game.Game;
import mage.game.combat.CombatGroup;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetAttackingCreature;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
*
* @author L_J
Expand Down Expand Up @@ -138,11 +134,9 @@ public boolean apply(Game game, Ability source) {
// the ability doesn't unblock a group that loses all blockers, however it will newly block a previously unblocked group if it gains a blocker this way
if (!(chosenGroup1.getBlockers().isEmpty())) {
chosenGroup1.setBlocked(true, game);
chosenGroup1.pickBlockerOrder(attacker1.getControllerId(), game);
}
if (!(chosenGroup2.getBlockers().isEmpty())) {
chosenGroup2.setBlocked(true, game);
chosenGroup2.pickBlockerOrder(attacker2.getControllerId(), game);
}
return true;
}
Expand Down Expand Up @@ -197,7 +191,6 @@ private void handleMultiBlockers(Set<Permanent> blockers, CombatGroup chosenGrou
// 10/4/2004 The new blocker does not trigger any abilities which trigger on creatures becoming blockers, because the creatures were already blockers and the simple change of who is blocking does not trigger such abilities.
game.getCombat().addBlockingGroup(blocker.getId(), attacker, controller.getId(), game);
}
blockGroup.pickAttackerOrder(blocker.getControllerId(), game);
}
}
}
Expand Down
10 changes: 3 additions & 7 deletions Mage.Sets/src/mage/cards/m/MirrorMatch.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@

package mage.cards.m;

import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility;
import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
Expand All @@ -20,6 +19,8 @@
import mage.target.targetpointer.FixedTarget;
import mage.target.targetpointer.FixedTargets;

import java.util.UUID;

/**
*
* @author LevelX2
Expand Down Expand Up @@ -75,20 +76,15 @@ public boolean apply(Game game, Ability source) {
effect.setTargetPointer(new FixedTarget(attacker, game));
effect.apply(game, source);
CombatGroup group = game.getCombat().findGroup(attacker.getId());
boolean isCreature = false;
if (group != null) {
for (Permanent addedToken : effect.getAddedPermanents()) {
if (addedToken.isCreature(game)) {
group.addBlockerToGroup(addedToken.getId(), attackerId, game);
isCreature = true;
}
}
ExileTargetEffect exileEffect = new ExileTargetEffect("Exile those tokens at end of combat");
exileEffect.setTargetPointer(new FixedTargets(effect.getAddedPermanents(), game));
game.addDelayedTriggeredAbility(new AtTheEndOfCombatDelayedTriggeredAbility(exileEffect), source);
if (isCreature) {
group.pickBlockerOrder(attacker.getControllerId(), game);
}
}
}
}
Expand Down
6 changes: 0 additions & 6 deletions Mage.Sets/src/mage/cards/s/SorrowsPath.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,8 @@ private void reassignBlocker(Permanent blocker, Set<Permanent> attackers, Game g
group.addBlockerToGroup(blocker.getId(), blocker.getControllerId(), game);
game.getCombat().addBlockingGroup(blocker.getId(), attacker.getId(), blocker.getControllerId(), game);
game.fireEvent(new BlockerDeclaredEvent(attacker.getId(), blocker.getId(), blocker.getControllerId()));
group.pickBlockerOrder(attacker.getControllerId(), game);
}
}
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKS, blocker.getId(), source, null));
CombatGroup blockGroup = findBlockingGroup(blocker, game); // a new blockingGroup is formed, so it's necessary to find it again
if (blockGroup != null) {
blockGroup.pickAttackerOrder(blocker.getControllerId(), game);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public void testBecomesDoubleBlocked() {
attack(1, playerA, khenra);
block(1, playerB, elves + ":0", khenra);
block(1, playerB, elves + ":1", khenra);
setChoice(playerA, "X=1"); // assign damage

setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ public void testMultipleBlocker() {
attack(2, playerB, "Isao, Enlightened Bushi");
block(2, playerA, "Llanowar Elves", "Isao, Enlightened Bushi");
block(2, playerA, "Elvish Mystic", "Isao, Enlightened Bushi");
setChoice(playerB, "X=1"); // assign damage
setChoice(playerB, "X=1"); // assign damage

setStopAt(2, PhaseStep.END_COMBAT);
execute();
Expand Down
Loading