mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 10:18:01 +00:00
Merge branch 'goad' into 'master'
Goad doesn't stack See merge request core-developers/forge!6074
This commit is contained in:
@@ -624,7 +624,7 @@ public class AiAttackController {
|
||||
|
||||
// Attempt to see if there's a defined entity that must be attacked strictly this turn...
|
||||
GameEntity entity = ai.getMustAttackEntityThisTurn();
|
||||
if (entity == null) {
|
||||
if (nextTurn || entity == null) {
|
||||
// ...or during the attacking creature controller's turn
|
||||
entity = ai.getMustAttackEntity();
|
||||
}
|
||||
@@ -720,6 +720,7 @@ public class AiAttackController {
|
||||
continue;
|
||||
}
|
||||
boolean mustAttack = false;
|
||||
// TODO for nextTurn check if it was temporary
|
||||
if (attacker.isGoaded()) {
|
||||
mustAttack = true;
|
||||
} else if (attacker.getSVar("MustAttack").equals("True")) {
|
||||
@@ -736,7 +737,7 @@ public class AiAttackController {
|
||||
mustAttack = true;
|
||||
}
|
||||
}
|
||||
if (mustAttack || attacker.getController().getMustAttackEntity() != null || attacker.getController().getMustAttackEntityThisTurn() != null) {
|
||||
if (mustAttack || (attacker.getController().getMustAttackEntity() != null && nextTurn) || (attacker.getController().getMustAttackEntityThisTurn() != null && !nextTurn)) {
|
||||
combat.addAttacker(attacker, defender);
|
||||
attackersLeft.remove(attacker);
|
||||
numForcedAttackers++;
|
||||
|
||||
@@ -3040,11 +3040,11 @@ public class ComputerUtil {
|
||||
public static boolean aiLifeInDanger(Player ai, boolean serious, int payment) {
|
||||
// TODO should also consider them as teams
|
||||
for (Player opponent: ai.getOpponents()) {
|
||||
// test whether the human can kill the ai next turn
|
||||
Combat combat = new Combat(opponent);
|
||||
boolean containsAttacker = false;
|
||||
boolean thisCombat = ai.getGame().getPhaseHandler().isPlayerTurn(opponent) && ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_BEGIN);
|
||||
for (Card att : opponent.getCreaturesInPlay()) {
|
||||
if (ComputerUtilCombat.canAttackNextTurn(att, ai)) {
|
||||
if ((thisCombat && CombatUtil.canAttack(att, ai)) || (!thisCombat && ComputerUtilCombat.canAttackNextTurn(att, ai))) {
|
||||
combat.addAttacker(att, ai);
|
||||
containsAttacker = true;
|
||||
}
|
||||
@@ -3052,6 +3052,8 @@ public class ComputerUtil {
|
||||
if (!containsAttacker) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO if it's next turn ignore mustBlockCards
|
||||
AiBlockController block = new AiBlockController(ai, false);
|
||||
block.assignBlockersForCombat(combat);
|
||||
|
||||
|
||||
@@ -39,6 +39,10 @@ public class GoadAi extends SpellAbilityAi {
|
||||
if (ComputerUtilCard.isUselessCreature(ai, c)) {
|
||||
return false;
|
||||
}
|
||||
// useless
|
||||
if (c.isGoadedBy(ai)) {
|
||||
return false;
|
||||
}
|
||||
// select creatures which can attack an Opponent other than ai
|
||||
for (Player o : ai.getOpponents()) {
|
||||
if (ComputerUtilCombat.canAttackNextTurn(c, o)) {
|
||||
@@ -64,6 +68,10 @@ public class GoadAi extends SpellAbilityAi {
|
||||
if (ComputerUtilCard.isUselessCreature(ai, c)) {
|
||||
return false;
|
||||
}
|
||||
// useless
|
||||
if (c.isGoadedBy(ai)) {
|
||||
return false;
|
||||
}
|
||||
// select only creatures AI can block
|
||||
return ComputerUtilCard.canBeBlockedProfitably(ai, c, false);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,11 @@ public class GoadEffect extends SpellAbilityEffect {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 701.38d
|
||||
if (tgtC.isGoadedBy(player)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if pump is a target, make sure we can still target now
|
||||
if (sa.usesTargeting() && !sa.getTargetRestrictions().canTgtPlayer() && !tgtC.canBeTargetedBy(sa)) {
|
||||
continue;
|
||||
|
||||
@@ -70,7 +70,7 @@ public class MustAttackEffect extends SpellAbilityEffect {
|
||||
// TODO these should not override but add another requirement
|
||||
for (final Player p : tgtPlayers) {
|
||||
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
||||
if (thisTurn) {
|
||||
if (thisTurn || !p.getGame().getPhaseHandler().isPlayerTurn(p)) {
|
||||
p.setMustAttackEntityThisTurn(entity);
|
||||
} else {
|
||||
p.setMustAttackEntity(entity);
|
||||
|
||||
@@ -35,10 +35,6 @@ public class AttackRequirement {
|
||||
|
||||
this.causesToAttack = causesToAttack;
|
||||
|
||||
final GameEntity mustAttack = attacker.getController().getMustAttackEntity();
|
||||
if (mustAttack != null) {
|
||||
defenderSpecific.add(mustAttack);
|
||||
}
|
||||
final GameEntity mustAttackThisTurn = attacker.getController().getMustAttackEntityThisTurn();
|
||||
if (mustAttackThisTurn != null) {
|
||||
defenderSpecific.add(mustAttackThisTurn);
|
||||
@@ -47,6 +43,7 @@ public class AttackRequirement {
|
||||
int nAttackAnything = 0;
|
||||
|
||||
if (attacker.isGoaded()) {
|
||||
// Goad has two requirements but the other is handled by CombatUtil currently
|
||||
nAttackAnything += attacker.getGoaded().size();
|
||||
}
|
||||
|
||||
@@ -71,10 +68,6 @@ public class AttackRequirement {
|
||||
}
|
||||
}
|
||||
|
||||
final GameEntity mustAttack3 = attacker.getMustAttackEntity();
|
||||
if (mustAttack3 != null) {
|
||||
defenderSpecific.add(mustAttack3);
|
||||
}
|
||||
final GameEntity mustAttackThisTurn3 = attacker.getMustAttackEntityThisTurn();
|
||||
if (mustAttackThisTurn3 != null) {
|
||||
defenderSpecific.add(mustAttackThisTurn3);
|
||||
|
||||
@@ -825,6 +825,7 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
private Player handleNextTurn() {
|
||||
game.getStack().onNextTurn();
|
||||
// reset mustAttackEntity
|
||||
playerTurn.setMustAttackEntityThisTurn(playerTurn.getMustAttackEntity());
|
||||
playerTurn.setMustAttackEntity(null);
|
||||
|
||||
game.getTriggerHandler().clearThisTurnDelayedTrigger();
|
||||
|
||||
@@ -906,7 +906,7 @@ public final class StaticAbilityContinuous {
|
||||
}
|
||||
|
||||
// add Types
|
||||
if ((addTypes != null) || (removeTypes != null) || addAllCreatureTypes
|
||||
if (addTypes != null || removeTypes != null || addAllCreatureTypes
|
||||
|| removeSuperTypes || removeCardTypes || removeLandTypes || removeCreatureTypes || removeArtifactTypes || removeEnchantmentTypes) {
|
||||
affectedCard.addChangedCardTypes(addTypes, removeTypes, addAllCreatureTypes, removeSuperTypes, removeCardTypes, removeSubTypes,
|
||||
removeLandTypes, removeCreatureTypes, removeArtifactTypes, removeEnchantmentTypes,
|
||||
@@ -919,7 +919,7 @@ public final class StaticAbilityContinuous {
|
||||
}
|
||||
|
||||
if (layer == StaticAbilityLayer.RULES) {
|
||||
if (params.containsKey("Goad")) {
|
||||
if (params.containsKey("Goad") && !affectedCard.isGoadedBy(hostCard.getController())) {
|
||||
affectedCard.addGoad(se.getTimestamp(), hostCard.getController());
|
||||
}
|
||||
if (params.containsKey("CanBlockAny")) {
|
||||
|
||||
@@ -2,7 +2,6 @@ Name:Avalanche Tusker
|
||||
ManaCost:2 G U R
|
||||
Types:Creature Elephant Warrior
|
||||
PT:6/4
|
||||
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigCantBlock | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, target creature defending player controls blocks this combat if able.
|
||||
SVar:TrigCantBlock:DB$ MustBlock | ValidTgts$ Creature.DefenderCtrl | TgtPrompt$ Select target creature | SpellDescription$ Target creature blocks CARDNAME this turn if able.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/avalanche_tusker.jpg
|
||||
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigCantBlock | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, target creature defending player controls blocks it this combat if able.
|
||||
SVar:TrigCantBlock:DB$ MustBlock | ValidTgts$ Creature.DefenderCtrl | TgtPrompt$ Select target creature
|
||||
Oracle:Whenever Avalanche Tusker attacks, target creature defending player controls blocks it this combat if able.
|
||||
|
||||
@@ -5,10 +5,9 @@ PT:6/1
|
||||
K:Haste
|
||||
K:Trample
|
||||
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigProvoke | TriggerDescription$ When CARDNAME attacks, up to one target creature defending player controls blocks it this combat if able.
|
||||
SVar:TrigProvoke:DB$ MustBlock | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature.DefenderCtrl | Duration$ UntilEndOfCombat | TgtPrompt$ Select up to one target creature defending player controls
|
||||
SVar:TrigProvoke:DB$ MustBlock | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature.DefenderCtrl | TgtPrompt$ Select up to one target creature defending player controls
|
||||
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ At the beginning of the end step, sacrifice CARDNAME.
|
||||
SVar:TrigSac:DB$ Sacrifice | SacValid$ Self
|
||||
SVar:EndOfTurnLeavePlay:True
|
||||
SVar:PlayMain1:TRUE
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/impetuous_devils.jpg
|
||||
Oracle:Trample, haste\nWhen Impetuous Devils attacks, up to one target creature defending player controls blocks it this combat if able.\nAt the beginning of the end step, sacrifice Impetuous Devils.
|
||||
|
||||
Reference in New Issue
Block a user