mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Merge pull request #2100 from tool4ever/somefixes
Improve damage check logic for losing + performance
This commit is contained in:
@@ -814,9 +814,6 @@ public class AiController {
|
||||
}
|
||||
|
||||
public AiPlayDecision canPlaySa(SpellAbility sa) {
|
||||
final Card card = sa.getHostCard();
|
||||
final boolean isRightTiming = sa.canCastTiming(player);
|
||||
|
||||
if (!checkAiSpecificRestrictions(sa)) {
|
||||
return AiPlayDecision.CantPlayAi;
|
||||
}
|
||||
@@ -824,6 +821,12 @@ public class AiController {
|
||||
return canPlaySa(((WrappedAbility) sa).getWrappedAbility());
|
||||
}
|
||||
|
||||
if (!sa.canCastTiming(player)) {
|
||||
return AiPlayDecision.AnotherTime;
|
||||
}
|
||||
|
||||
final Card card = sa.getHostCard();
|
||||
|
||||
// Trying to play a card that has Buyback without a Buyback cost, look for possible additional considerations
|
||||
if (getBooleanProperty(AiProps.TRY_TO_PRESERVE_BUYBACK_SPELLS)) {
|
||||
if (card.hasKeyword(Keyword.BUYBACK) && !sa.isBuyBackAbility() && !canPlaySpellWithoutBuyback(card, sa)) {
|
||||
@@ -898,9 +901,6 @@ public class AiController {
|
||||
return AiPlayDecision.AnotherTime;
|
||||
}
|
||||
if (sa instanceof SpellPermanent) {
|
||||
if (!isRightTiming) {
|
||||
return AiPlayDecision.AnotherTime;
|
||||
}
|
||||
return canPlayFromEffectAI((SpellPermanent)sa, false, true);
|
||||
}
|
||||
if (sa.usesTargeting()) {
|
||||
@@ -912,18 +912,13 @@ public class AiController {
|
||||
}
|
||||
}
|
||||
if (sa instanceof Spell) {
|
||||
if (ComputerUtil.getDamageForPlaying(player, sa) >= player.getLife()
|
||||
&& !player.cantLoseForZeroOrLessLife() && player.canLoseLife()) {
|
||||
if (!player.cantLoseForZeroOrLessLife() && player.canLoseLife() &&
|
||||
ComputerUtil.getDamageForPlaying(player, sa) >= player.getLife()) {
|
||||
return AiPlayDecision.CurseEffects;
|
||||
}
|
||||
if (!isRightTiming) {
|
||||
return AiPlayDecision.AnotherTime;
|
||||
}
|
||||
return canPlaySpellBasic(card, sa);
|
||||
}
|
||||
if (!isRightTiming) {
|
||||
return AiPlayDecision.AnotherTime;
|
||||
}
|
||||
|
||||
return AiPlayDecision.WillPlay;
|
||||
}
|
||||
|
||||
@@ -1411,8 +1406,8 @@ public class AiController {
|
||||
if (!checkETBEffects(card, spell, null)) {
|
||||
return AiPlayDecision.BadEtbEffects;
|
||||
}
|
||||
if (damage + ComputerUtil.getDamageFromETB(player, card) >= player.getLife()
|
||||
&& !player.cantLoseForZeroOrLessLife() && player.canLoseLife()) {
|
||||
if (!player.cantLoseForZeroOrLessLife() && player.canLoseLife()
|
||||
&& damage + ComputerUtil.getDamageFromETB(player, card) >= player.getLife()) {
|
||||
return AiPlayDecision.BadEtbEffects;
|
||||
}
|
||||
}
|
||||
@@ -1496,35 +1491,33 @@ public class AiController {
|
||||
if (landsWannaPlay != null && !landsWannaPlay.isEmpty()) {
|
||||
// TODO search for other land it might want to play?
|
||||
Card land = chooseBestLandToPlay(landsWannaPlay);
|
||||
if (ComputerUtil.getDamageFromETB(player, land) < player.getLife() || !player.canLoseLife()
|
||||
|| player.cantLoseForZeroOrLessLife() ) {
|
||||
if (!game.getPhaseHandler().is(PhaseType.MAIN1) || !isSafeToHoldLandDropForMain2(land)) {
|
||||
final List<SpellAbility> abilities = Lists.newArrayList();
|
||||
if ((!player.canLoseLife() || player.cantLoseForZeroOrLessLife() || ComputerUtil.getDamageFromETB(player, land) < player.getLife())
|
||||
&& (!game.getPhaseHandler().is(PhaseType.MAIN1) || !isSafeToHoldLandDropForMain2(land))) {
|
||||
final List<SpellAbility> abilities = Lists.newArrayList();
|
||||
|
||||
// TODO extend this logic to evaluate MDFC with both sides land
|
||||
// this can only happen if its a MDFC land
|
||||
if (!land.isLand()) {
|
||||
land.setState(CardStateName.Modal, true);
|
||||
land.setBackSide(true);
|
||||
}
|
||||
// TODO extend this logic to evaluate MDFC with both sides land
|
||||
// this can only happen if its a MDFC land
|
||||
if (!land.isLand()) {
|
||||
land.setState(CardStateName.Modal, true);
|
||||
land.setBackSide(true);
|
||||
}
|
||||
|
||||
LandAbility la = new LandAbility(land, player, null);
|
||||
LandAbility la = new LandAbility(land, player, null);
|
||||
la.setCardState(land.getCurrentState());
|
||||
if (la.canPlay()) {
|
||||
abilities.add(la);
|
||||
}
|
||||
|
||||
// add mayPlay option
|
||||
for (CardPlayOption o : land.mayPlay(player)) {
|
||||
la = new LandAbility(land, player, o.getAbility());
|
||||
la.setCardState(land.getCurrentState());
|
||||
if (la.canPlay()) {
|
||||
abilities.add(la);
|
||||
}
|
||||
|
||||
// add mayPlay option
|
||||
for (CardPlayOption o : land.mayPlay(player)) {
|
||||
la = new LandAbility(land, player, o.getAbility());
|
||||
la.setCardState(land.getCurrentState());
|
||||
if (la.canPlay()) {
|
||||
abilities.add(la);
|
||||
}
|
||||
}
|
||||
if (!abilities.isEmpty()) {
|
||||
return abilities;
|
||||
}
|
||||
}
|
||||
if (!abilities.isEmpty()) {
|
||||
return abilities;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,20 +100,19 @@ public abstract class DamageAiBase extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!enemy.canLoseLife()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!noPrevention) {
|
||||
restDamage = ComputerUtilCombat.predictDamageTo(enemy, restDamage, hostcard, false);
|
||||
} else {
|
||||
restDamage = enemy.staticReplaceDamage(restDamage, hostcard, false);
|
||||
}
|
||||
|
||||
if (restDamage == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!enemy.canLoseLife()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final CardCollectionView hand = comp.getCardsIn(ZoneType.Hand);
|
||||
|
||||
if ((enemy.getLife() - restDamage) < 5) {
|
||||
|
||||
Reference in New Issue
Block a user