mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
- Fixed a little loophole in the MustBlock code.
- First steps towards an AI for AF MustBlock.
This commit is contained in:
@@ -651,7 +651,8 @@ public class ComputerUtil_Block2 {
|
|||||||
if (!blocker.getMustBlockCards().isEmpty()) {
|
if (!blocker.getMustBlockCards().isEmpty()) {
|
||||||
ArrayList<Card> blocks = blocker.getMustBlockCards();
|
ArrayList<Card> blocks = blocker.getMustBlockCards();
|
||||||
for (Card attacker : blocks) {
|
for (Card attacker : blocks) {
|
||||||
if (attacker.isAttacking() && CombatUtil.canBlock(attacker, blocker)) {
|
if (attacker.isAttacking() && CombatUtil.canBlock(attacker, blocker, combat)
|
||||||
|
&& getBlockersLeft().contains(blocker)) {
|
||||||
combat.addBlocker(attacker, blocker);
|
combat.addBlocker(attacker, blocker);
|
||||||
getBlockersLeft().remove(blocker);
|
getBlockersLeft().remove(blocker);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,13 @@ import java.util.HashMap;
|
|||||||
|
|
||||||
import forge.AllZone;
|
import forge.AllZone;
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
|
import forge.CardList;
|
||||||
|
import forge.CardListFilter;
|
||||||
import forge.CombatUtil;
|
import forge.CombatUtil;
|
||||||
import forge.ComputerUtil;
|
import forge.ComputerUtil;
|
||||||
import forge.Constant;
|
import forge.Constant;
|
||||||
import forge.Player;
|
import forge.Player;
|
||||||
|
import forge.Constant.Zone;
|
||||||
import forge.card.cardFactory.CardFactoryUtil;
|
import forge.card.cardFactory.CardFactoryUtil;
|
||||||
import forge.card.spellability.Ability_Activated;
|
import forge.card.spellability.Ability_Activated;
|
||||||
import forge.card.spellability.Ability_Sub;
|
import forge.card.spellability.Ability_Sub;
|
||||||
@@ -835,17 +838,46 @@ public final class AbilityFactory_Combat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean mustBlockDoTriggerAI(final AbilityFactory af, final SpellAbility sa,
|
private static boolean mustBlockDoTriggerAI(final AbilityFactory af, final SpellAbility sa,
|
||||||
final boolean mandatory)
|
final boolean mandatory) {
|
||||||
{
|
final Card source = sa.getSourceCard();
|
||||||
|
Target abTgt = sa.getTarget();
|
||||||
|
|
||||||
// If there is a cost payment it's usually not mandatory
|
// If there is a cost payment it's usually not mandatory
|
||||||
if (!ComputerUtil.canPayCost(sa) && !mandatory) {
|
if (!ComputerUtil.canPayCost(sa) && !mandatory) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//only use on creatures that attack
|
||||||
|
if (!source.isAttacking())
|
||||||
|
return false;
|
||||||
|
|
||||||
boolean chance;
|
boolean chance = false;
|
||||||
|
|
||||||
//TODO - implement AI
|
CardList list = AllZone.getHumanPlayer().getCardsIn(Zone.Battlefield).getType("Creature");
|
||||||
chance = false;
|
list = list.getTargetableCards(source);
|
||||||
|
|
||||||
|
if (abTgt != null) {
|
||||||
|
list = list.getValidCards(abTgt.getValidTgts(), source.getController(), source);
|
||||||
|
list = list.filter(new CardListFilter() {
|
||||||
|
public boolean addCard(Card c) {
|
||||||
|
if (!CombatUtil.canBlock(source, c, AllZone.getCombat()))
|
||||||
|
return false;
|
||||||
|
if (CombatUtil.canDestroyAttacker(source, c, AllZone.getCombat(), false))
|
||||||
|
return false;
|
||||||
|
if (!CombatUtil.canDestroyBlocker(c, source, AllZone.getCombat(), false))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!list.isEmpty()) {
|
||||||
|
Card blocker = CardFactoryUtil.AI_getBestCreature(list);
|
||||||
|
if (blocker == null)
|
||||||
|
return false;
|
||||||
|
abTgt.addTarget(CardFactoryUtil.AI_getBestCreature(list));
|
||||||
|
chance = false; //TODO:change this to true, once the human input takes mustblocks into account
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
|
||||||
// check SubAbilities DoTrigger?
|
// check SubAbilities DoTrigger?
|
||||||
Ability_Sub abSub = sa.getSubAbility();
|
Ability_Sub abSub = sa.getSubAbility();
|
||||||
|
|||||||
@@ -4973,13 +4973,13 @@ public class CardFactoryUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(card.hasKeyword("Provoke")) {
|
if(card.hasKeyword("Provoke")) {
|
||||||
String actualTrigger = "Mode$ Attacks | ValidCard$ Card.Self | OptionalDecider$ You | Execute$ UntapAbility | Secondary$ True | TriggerDescription$ When this attacks, you may have target creature defending player controls untap and block it if able.";
|
String actualTrigger = "Mode$ Attacks | ValidCard$ Card.Self | OptionalDecider$ You | Execute$ ProvokeAbility | Secondary$ True | TriggerDescription$ When this attacks, you may have target creature defending player controls untap and block it if able.";
|
||||||
String abString = "AB$ Untap | Cost$ 0 | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature defending player controls | SubAbility$ DBProvoke";
|
String abString = "DB$ MustBlock | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature defending player controls | SubAbility$ DBUntap";
|
||||||
String dbString = "DB$ MustBlock | Defined$ Targeted";
|
String dbString = "DB$ Untap | Defined$ Targeted";
|
||||||
Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, card, false);
|
Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, card, false);
|
||||||
card.addTrigger(parsedTrigger);
|
card.addTrigger(parsedTrigger);
|
||||||
card.setSVar("UntapAbility", abString);
|
card.setSVar("ProvokeAbility", abString);
|
||||||
card.setSVar("DBProvoke", dbString);
|
card.setSVar("DBUntap", dbString);
|
||||||
}
|
}
|
||||||
|
|
||||||
return card;
|
return card;
|
||||||
|
|||||||
Reference in New Issue
Block a user