mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 03:38:01 +00:00
Butcher Orgg!!!
This commit is contained in:
@@ -1133,6 +1133,7 @@ public class CardView extends GameEntityView {
|
||||
public boolean hasDeathtouch() { return get(TrackableProperty.HasDeathtouch); }
|
||||
public boolean hasDevoid() { return get(TrackableProperty.HasDevoid); }
|
||||
public boolean hasDefender() { return get(TrackableProperty.HasDefender); }
|
||||
public boolean hasDivideDamage() { return get(TrackableProperty.HasDivideDamage); }
|
||||
public boolean hasDoubleStrike() { return get(TrackableProperty.HasDoubleStrike); }
|
||||
public boolean hasFirstStrike() { return get(TrackableProperty.HasFirstStrike); }
|
||||
public boolean hasFlying() { return get(TrackableProperty.HasFlying); }
|
||||
@@ -1173,6 +1174,8 @@ public class CardView extends GameEntityView {
|
||||
set(TrackableProperty.HasDeathtouch, c.hasKeyword(Keyword.DEATHTOUCH, state));
|
||||
set(TrackableProperty.HasDevoid, c.hasKeyword(Keyword.DEVOID, state));
|
||||
set(TrackableProperty.HasDefender, c.hasKeyword(Keyword.DEFENDER, state));
|
||||
set(TrackableProperty.HasDivideDamage, c.hasKeyword("You may assign CARDNAME's combat damage divided as " +
|
||||
"you choose among defending player and/or any number of creatures they control."));
|
||||
set(TrackableProperty.HasDoubleStrike, c.hasKeyword(Keyword.DOUBLE_STRIKE, state));
|
||||
set(TrackableProperty.HasFirstStrike, c.hasKeyword(Keyword.FIRST_STRIKE, state));
|
||||
set(TrackableProperty.HasFlying, c.hasKeyword(Keyword.FLYING, state));
|
||||
|
||||
@@ -20,21 +20,18 @@ package forge.game.combat;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.*;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.GameEntityCounterTable;
|
||||
import forge.game.GameLogEntryType;
|
||||
import forge.game.GameObjectMap;
|
||||
import forge.game.*;
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardDamageMap;
|
||||
import forge.game.card.*;
|
||||
import forge.game.keyword.Keyword;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.trigger.TriggerType;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.CardTranslation;
|
||||
import forge.util.collect.FCollection;
|
||||
import forge.util.collect.FCollectionView;
|
||||
import forge.util.Localizer;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.*;
|
||||
@@ -64,6 +61,7 @@ public class Combat {
|
||||
private Map<Card, CardCollection> blockersOrderedForDamageAssignment = Maps.newHashMap();
|
||||
private Map<GameEntity, CombatLki> lkiCache = Maps.newHashMap();
|
||||
private CardDamageMap dealtDamageTo = new CardDamageMap();
|
||||
private boolean dividedToPlayer = false;
|
||||
|
||||
// List holds creatures who have dealt 1st strike damage to disallow them deal damage on regular basis (unless they have double-strike KW)
|
||||
private CardCollection combatantsThatDealtFirstStrikeDamage = new CardCollection();
|
||||
@@ -373,7 +371,7 @@ public class Combat {
|
||||
blocker.updateBlockingForView();
|
||||
}
|
||||
|
||||
// remove blocked from specific attacker
|
||||
// remove blocker from specific attacker
|
||||
public final void removeBlockAssignment(final Card attacker, final Card blocker) {
|
||||
AttackingBand band = getBandOfAttackerNotNull(attacker);
|
||||
Collection<Card> cc = blockedBands.get(band);
|
||||
@@ -400,6 +398,15 @@ public class Combat {
|
||||
return result;
|
||||
}
|
||||
|
||||
public final CardCollection getDefendersCreatures() {
|
||||
CardCollection result = new CardCollection();
|
||||
for (Card attacker : getAttackers()) {
|
||||
CardCollection cc = getDefenderPlayerByAttacker(attacker).getCreaturesInPlay();
|
||||
result.addAll(cc);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public final CardCollection getBlockers(final AttackingBand band) {
|
||||
Collection<Card> blockers = blockedBands.get(band);
|
||||
return blockers == null ? new CardCollection() : new CardCollection(blockers);
|
||||
@@ -716,8 +723,26 @@ public class Combat {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean divideCombatDamageAsChoose = (getDefendersCreatures().size() > 0 &&
|
||||
attacker.hasKeyword("You may assign CARDNAME's combat damage divided as you choose among " +
|
||||
"defending player and/or any number of creatures they control.")
|
||||
&& attacker.getController().getController().confirmAction(null, null,
|
||||
Localizer.getInstance().getMessage("lblAssignCombatDamageAsChoose",
|
||||
CardTranslation.getTranslatedName(attacker.getName()))));
|
||||
boolean trampler = attacker.hasKeyword(Keyword.TRAMPLE);
|
||||
orderedBlockers = blockersOrderedForDamageAssignment.get(attacker);
|
||||
if (divideCombatDamageAsChoose) {
|
||||
if (orderedBlockers == null || orderedBlockers.isEmpty()) {
|
||||
orderedBlockers = getDefendersCreatures();
|
||||
}
|
||||
else {
|
||||
for (Card c : getDefendersCreatures()) {
|
||||
if (!orderedBlockers.contains(c)) {
|
||||
orderedBlockers.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
assignedDamage = true;
|
||||
// If the Attacker is unblocked, or it's a trampler and has 0 blockers, deal damage to defender
|
||||
if (orderedBlockers == null || orderedBlockers.isEmpty()) {
|
||||
@@ -730,6 +755,10 @@ public class Combat {
|
||||
Player assigningPlayer = getAttackingPlayer();
|
||||
// Defensive Formation is very similar to Banding with Blockers
|
||||
// It allows the defending player to assign damage instead of the attacking player
|
||||
if (defender instanceof Card && divideCombatDamageAsChoose) {
|
||||
defender = getDefenderPlayerByAttacker(attacker);
|
||||
dividedToPlayer = true;
|
||||
}
|
||||
if (defender instanceof Player && defender.hasKeyword("You assign combat damage of each creature attacking you.")) {
|
||||
assigningPlayer = (Player)defender;
|
||||
}
|
||||
@@ -737,7 +766,8 @@ public class Combat {
|
||||
assigningPlayer = orderedBlockers.get(0).getController();
|
||||
}
|
||||
|
||||
Map<Card, Integer> map = assigningPlayer.getController().assignCombatDamage(attacker, orderedBlockers, damageDealt, defender, getAttackingPlayer() != assigningPlayer);
|
||||
Map<Card, Integer> map = assigningPlayer.getController().assignCombatDamage(attacker, orderedBlockers,
|
||||
damageDealt, defender, divideCombatDamageAsChoose || getAttackingPlayer() != assigningPlayer);
|
||||
for (Entry<Card, Integer> dt : map.entrySet()) {
|
||||
if (dt.getKey() == null) {
|
||||
if (dt.getValue() > 0)
|
||||
@@ -767,7 +797,7 @@ public class Combat {
|
||||
private final void addDefendingDamage(final int n, final Card source) {
|
||||
final GameEntity ge = getDefenderByAttacker(source);
|
||||
|
||||
if (ge instanceof Card) {
|
||||
if (ge instanceof Card && !dividedToPlayer) {
|
||||
final Card planeswalker = (Card) ge;
|
||||
planeswalker.addAssignedDamage(n, source);
|
||||
return;
|
||||
@@ -805,6 +835,9 @@ public class Combat {
|
||||
// This function handles both Regular and First Strike combat assignment
|
||||
for (final Entry<Card, Integer> entry : defendingDamageMap.entrySet()) {
|
||||
GameEntity defender = getDefenderByAttacker(entry.getKey());
|
||||
if (dividedToPlayer) {
|
||||
defender = getDefenderPlayerByAttacker(entry.getKey());
|
||||
}
|
||||
if (defender instanceof Player) { // player
|
||||
defender.addCombatDamage(entry.getValue(), entry.getKey(), dealtDamageTo, preventMap, counterTable);
|
||||
}
|
||||
@@ -819,6 +852,7 @@ public class Combat {
|
||||
combatants.addAll(getAttackers());
|
||||
combatants.addAll(getAllBlockers());
|
||||
combatants.addAll(getDefendingPlaneswalkers());
|
||||
combatants.addAll(getDefendersCreatures());
|
||||
|
||||
for (final Card c : combatants) {
|
||||
// if no assigned damage to resolve, move to next
|
||||
|
||||
@@ -100,6 +100,7 @@ public enum TrackableProperty {
|
||||
HasDeathtouch(TrackableTypes.BooleanType),
|
||||
HasDevoid(TrackableTypes.BooleanType),
|
||||
HasDefender(TrackableTypes.BooleanType),
|
||||
HasDivideDamage(TrackableTypes.BooleanType),
|
||||
HasDoubleStrike(TrackableTypes.BooleanType),
|
||||
HasFirstStrike(TrackableTypes.BooleanType),
|
||||
HasFlying(TrackableTypes.BooleanType),
|
||||
|
||||
Reference in New Issue
Block a user