Merge branch 'damagedeal' into 'master'

DamageDealAi: Improve mandatory targeting with stuff like Fury, so AI less masochistic

See merge request core-developers/forge!5522
This commit is contained in:
Michael Kamensky
2021-10-08 09:24:05 +00:00
4 changed files with 23 additions and 15 deletions

View File

@@ -344,7 +344,7 @@ public class DamageDealAi extends DamageAiBase {
final Player activator = sa.getActivatingPlayer(); final Player activator = sa.getActivatingPlayer();
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
final Game game = source.getGame(); final Game game = source.getGame();
List<Card> hPlay = getTargetableCards(mandatory ? pl : ai, sa, pl, tgt, activator, source, game); List<Card> hPlay = getTargetableCards(ai, sa, pl, tgt, activator, source, game);
// Filter MustTarget requirements // Filter MustTarget requirements
StaticAbilityMustTarget.filterMustTargetCards(ai, hPlay, sa); StaticAbilityMustTarget.filterMustTargetCards(ai, hPlay, sa);
@@ -381,15 +381,20 @@ public class DamageDealAi extends DamageAiBase {
return null; return null;
} }
// try unfiltered now
hPlay = getTargetableCards(pl, sa, pl, tgt, activator, source, game);
List<Card> controlledByOpps = CardLists.filterControlledBy(hPlay, ai.getOpponents());
if (!hPlay.isEmpty()) { if (!hPlay.isEmpty()) {
if (pl.isOpponentOf(ai) && activator.equals(ai)) { if (pl.isOpponentOf(ai) && activator.equals(ai)) {
if (sa.getTargetRestrictions().canTgtPlaneswalker()) { if (sa.getTargetRestrictions().canTgtPlaneswalker()) {
targetCard = ComputerUtilCard.getBestPlaneswalkerAI(hPlay); targetCard = ComputerUtilCard.getBestPlaneswalkerAI(controlledByOpps);
} }
if (targetCard == null) { if (targetCard == null) {
targetCard = ComputerUtilCard.getBestCreatureAI(hPlay); targetCard = ComputerUtilCard.getBestCreatureAI(controlledByOpps);
} }
} else { }
if (targetCard == null) {
targetCard = ComputerUtilCard.getWorstCreatureAI(hPlay); targetCard = ComputerUtilCard.getWorstCreatureAI(hPlay);
} }
@@ -714,7 +719,6 @@ public class DamageDealAi extends DamageAiBase {
break; break;
} }
} }
} else if (tgt.canTgtCreature() || tgt.canTgtPlaneswalker()) { } else if (tgt.canTgtCreature() || tgt.canTgtPlaneswalker()) {
final Card c = dealDamageChooseTgtC(ai, sa, dmg, noPrevention, enemy, mandatory); final Card c = dealDamageChooseTgtC(ai, sa, dmg, noPrevention, enemy, mandatory);
if (c != null) { if (c != null) {
@@ -726,7 +730,13 @@ public class DamageDealAi extends DamageAiBase {
} }
tcs.add(c); tcs.add(c);
if (divided) { if (divided) {
final int assignedDamage = ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention); // if only other legal targets hurt own stuff just dump all dmg into this
final Card nextTarget = dealDamageChooseTgtC(ai, sa, dmg, noPrevention, enemy, mandatory);
boolean dump = false;
if (nextTarget != null && nextTarget.getController().equals(ai)) {
dump = true;
}
final int assignedDamage = dump ? dmg : ComputerUtilCombat.getEnoughDamageToKill(c, dmg, source, false, noPrevention);
if (assignedDamage <= dmg) { if (assignedDamage <= dmg) {
sa.addDividedAllocation(c, assignedDamage); sa.addDividedAllocation(c, assignedDamage);
} else { } else {

View File

@@ -2541,7 +2541,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|| keyword.equals("Split second")) { || keyword.equals("Split second")) {
sbBefore.append(keyword).append(" (").append(inst.getReminderText()).append(")"); sbBefore.append(keyword).append(" (").append(inst.getReminderText()).append(")");
sbBefore.append("\r\n"); sbBefore.append("\r\n");
} else if(keyword.equals("Conspire") || keyword.equals("Epic") } else if (keyword.equals("Conspire") || keyword.equals("Epic")
|| keyword.equals("Suspend") || keyword.equals("Jump-start") || keyword.equals("Suspend") || keyword.equals("Jump-start")
|| keyword.equals("Fuse")) { || keyword.equals("Fuse")) {
sbAfter.append(keyword).append(" (").append(inst.getReminderText()).append(")"); sbAfter.append(keyword).append(" (").append(inst.getReminderText()).append(")");
@@ -5918,9 +5918,9 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
if (sa.isSpell()) { if (sa.isSpell()) {
// TODO replace with Static Ability // TODO replace with Static Ability
for(KeywordInterface inst : source.getKeywords()) { for (KeywordInterface inst : source.getKeywords()) {
String kw = inst.getOriginal(); String kw = inst.getOriginal();
if(!kw.startsWith("SpellCantTarget")) { if (!kw.startsWith("SpellCantTarget")) {
continue; continue;
} }
final String[] k = kw.split(":"); final String[] k = kw.split(":");

View File

@@ -259,8 +259,7 @@ public class CardView extends GameEntityView {
//store alternate type for oathbreaker or signature spell for display in card text //store alternate type for oathbreaker or signature spell for display in card text
if (c.getPaperCard().getRules().canBeSignatureSpell()) { if (c.getPaperCard().getRules().canBeSignatureSpell()) {
set(TrackableProperty.CommanderAltType, "Signature Spell"); set(TrackableProperty.CommanderAltType, "Signature Spell");
} } else {
else {
set(TrackableProperty.CommanderAltType, "Oathbreaker"); set(TrackableProperty.CommanderAltType, "Oathbreaker");
} }
} else { } else {
@@ -768,7 +767,7 @@ public class CardView extends GameEntityView {
Set<String> cantHaveKeyword = this.getCantHaveKeyword(); Set<String> cantHaveKeyword = this.getCantHaveKeyword();
if (cantHaveKeyword != null && !cantHaveKeyword.isEmpty()) { if (cantHaveKeyword != null && !cantHaveKeyword.isEmpty()) {
sb.append("\r\n\r\n"); sb.append("\r\n\r\n");
for(String k : cantHaveKeyword) { for (String k : cantHaveKeyword) {
sb.append("CARDNAME can't have or gain ".replaceAll("CARDNAME", getName())); sb.append("CARDNAME can't have or gain ".replaceAll("CARDNAME", getName()));
sb.append(k); sb.append(k);
sb.append("."); sb.append(".");
@@ -945,8 +944,7 @@ public class CardView extends GameEntityView {
if (alternateState == null) { if (alternateState == null) {
set(TrackableProperty.AlternateState, null); set(TrackableProperty.AlternateState, null);
} } else {
else {
CardStateView alternateStateView = alternateState.getView(); CardStateView alternateStateView = alternateState.getView();
if (getAlternateState() != alternateStateView) { if (getAlternateState() != alternateStateView) {
set(TrackableProperty.AlternateState, alternateStateView); set(TrackableProperty.AlternateState, alternateStateView);

View File

@@ -2890,7 +2890,7 @@ public class Player extends GameEntity implements Comparable<Player> {
// Vanguard // Vanguard
if (registeredPlayer.getVanguardAvatars() != null) { if (registeredPlayer.getVanguardAvatars() != null) {
for(PaperCard avatar:registeredPlayer.getVanguardAvatars()) { for (PaperCard avatar:registeredPlayer.getVanguardAvatars()) {
com.add(Card.fromPaperCard(avatar, this)); com.add(Card.fromPaperCard(avatar, this));
} }
} }