mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
- Added "withoutAbilities" parameter to damageIfUnblocked function (fixes AI not pumping Killer Bees).
This commit is contained in:
@@ -196,7 +196,7 @@ public class AiAttackController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final Player opp = this.defendingOpponent;
|
final Player opp = this.defendingOpponent;
|
||||||
if (ComputerUtilCombat.damageIfUnblocked(attacker, opp, combat) > 0) {
|
if (ComputerUtilCombat.damageIfUnblocked(attacker, opp, combat, false) > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (ComputerUtilCombat.poisonIfUnblocked(attacker, opp) > 0) {
|
if (ComputerUtilCombat.poisonIfUnblocked(attacker, opp) > 0) {
|
||||||
@@ -401,7 +401,7 @@ public class AiAttackController {
|
|||||||
blockersLeft--;
|
blockersLeft--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
totalAttack += ComputerUtilCombat.damageIfUnblocked(attacker, ai, null);
|
totalAttack += ComputerUtilCombat.damageIfUnblocked(attacker, ai, null, false);
|
||||||
totalPoison += ComputerUtilCombat.poisonIfUnblocked(attacker, ai);
|
totalPoison += ComputerUtilCombat.poisonIfUnblocked(attacker, ai);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,7 +696,7 @@ public class AiAttackController {
|
|||||||
if (ComputerUtil.canAttackNextTurn(pCard)) {
|
if (ComputerUtil.canAttackNextTurn(pCard)) {
|
||||||
candidateAttackers.add(pCard);
|
candidateAttackers.add(pCard);
|
||||||
if (pCard.getNetCombatDamage() > 0) {
|
if (pCard.getNetCombatDamage() > 0) {
|
||||||
candidateUnblockedDamage += ComputerUtilCombat.damageIfUnblocked(pCard, opp, null);
|
candidateUnblockedDamage += ComputerUtilCombat.damageIfUnblocked(pCard, opp, null, false);
|
||||||
computerForces += 1;
|
computerForces += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -784,7 +784,7 @@ public class AiAttackController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isUnblockableCreature) {
|
if (isUnblockableCreature) {
|
||||||
unblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, opp, combat);
|
unblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, opp, combat, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (final Card attacker : nextTurnAttackers) {
|
for (final Card attacker : nextTurnAttackers) {
|
||||||
@@ -798,7 +798,7 @@ public class AiAttackController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isUnblockableCreature) {
|
if (isUnblockableCreature) {
|
||||||
nextUnblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, opp, null);
|
nextUnblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, opp, null, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unblockableDamage > 0 && !opp.cantLoseForZeroOrLessLife()
|
if (unblockableDamage > 0 && !opp.cantLoseForZeroOrLessLife()
|
||||||
@@ -872,7 +872,7 @@ public class AiAttackController {
|
|||||||
CardLists.sortByPowerAsc(attacking);
|
CardLists.sortByPowerAsc(attacking);
|
||||||
for (Card atta : attacking) {
|
for (Card atta : attacking) {
|
||||||
if (attackNum >= blockNum || !CombatUtil.canBeBlocked(attacker, this.blockers, combat)) {
|
if (attackNum >= blockNum || !CombatUtil.canBeBlocked(attacker, this.blockers, combat)) {
|
||||||
damage += ComputerUtilCombat.damageIfUnblocked(atta, opp, null);
|
damage += ComputerUtilCombat.damageIfUnblocked(atta, opp, null, false);
|
||||||
} else if (CombatUtil.canBeBlocked(attacker, this.blockers, combat)) {
|
} else if (CombatUtil.canBeBlocked(attacker, this.blockers, combat)) {
|
||||||
attackNum++;
|
attackNum++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1002,7 +1002,7 @@ public class ComputerUtilCard {
|
|||||||
float threat = 0;
|
float threat = 0;
|
||||||
if (c.isCreature()) {
|
if (c.isCreature()) {
|
||||||
Combat combat = ai.getGame().getCombat();
|
Combat combat = ai.getGame().getCombat();
|
||||||
threat = 1.0f * ComputerUtilCombat.damageIfUnblocked(c, opp, combat) / ai.getLife();
|
threat = 1.0f * ComputerUtilCombat.damageIfUnblocked(c, opp, combat, true) / ai.getLife();
|
||||||
//TODO:add threat from triggers and other abilities (ie. Master of Cruelties)
|
//TODO:add threat from triggers and other abilities (ie. Master of Cruelties)
|
||||||
} else {
|
} else {
|
||||||
for (final StaticAbility stAb : c.getStaticAbilities()) {
|
for (final StaticAbility stAb : c.getStaticAbilities()) {
|
||||||
|
|||||||
@@ -118,13 +118,13 @@ public class ComputerUtilCombat {
|
|||||||
* a {@link forge.game.combat.Combat} object.
|
* a {@link forge.game.combat.Combat} object.
|
||||||
* @return a int.
|
* @return a int.
|
||||||
*/
|
*/
|
||||||
public static int damageIfUnblocked(final Card attacker, final Player attacked, final Combat combat) {
|
public static int damageIfUnblocked(final Card attacker, final Player attacked, final Combat combat, boolean withoutAbilities) {
|
||||||
int damage = attacker.getNetCombatDamage();
|
int damage = attacker.getNetCombatDamage();
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
if (!attacked.canLoseLife()) {
|
if (!attacked.canLoseLife()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
damage += ComputerUtilCombat.predictPowerBonusOfAttacker(attacker, null, combat, false);
|
damage += ComputerUtilCombat.predictPowerBonusOfAttacker(attacker, null, combat, withoutAbilities);
|
||||||
if (!attacker.hasKeyword("Infect")) {
|
if (!attacker.hasKeyword("Infect")) {
|
||||||
sum = ComputerUtilCombat.predictDamageTo(attacked, damage, attacker, true);
|
sum = ComputerUtilCombat.predictDamageTo(attacked, damage, attacker, true);
|
||||||
if (attacker.hasKeyword("Double Strike")) {
|
if (attacker.hasKeyword("Double Strike")) {
|
||||||
@@ -179,7 +179,7 @@ public class ComputerUtilCombat {
|
|||||||
public static int sumDamageIfUnblocked(final List<Card> attackers, final Player attacked) {
|
public static int sumDamageIfUnblocked(final List<Card> attackers, final Player attacked) {
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for (final Card attacker : attackers) {
|
for (final Card attacker : attackers) {
|
||||||
sum += ComputerUtilCombat.damageIfUnblocked(attacker, attacked, null);
|
sum += ComputerUtilCombat.damageIfUnblocked(attacker, attacked, null, false);
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
@@ -293,7 +293,7 @@ public class ComputerUtilCombat {
|
|||||||
for(Card c : combat.getAttackers()) {
|
for(Card c : combat.getAttackers()) {
|
||||||
if(c.isCommander()) {
|
if(c.isCommander()) {
|
||||||
int currentCommanderDamage = ai.getCommanderDamage().containsKey(c) ? ai.getCommanderDamage().get(c) : 0;
|
int currentCommanderDamage = ai.getCommanderDamage().containsKey(c) ? ai.getCommanderDamage().get(c) : 0;
|
||||||
if (damageIfUnblocked(c, ai, combat) + currentCommanderDamage >= 21)
|
if (damageIfUnblocked(c, ai, combat, false) + currentCommanderDamage >= 21)
|
||||||
res.add(c);
|
res.add(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public class ChooseCardAi extends SpellAbilityAi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int ref = host.getName().equals("Forcefield") ? 1 : 0;
|
int ref = host.getName().equals("Forcefield") ? 1 : 0;
|
||||||
return ComputerUtilCombat.damageIfUnblocked(c, ai, combat) > ref;
|
return ComputerUtilCombat.damageIfUnblocked(c, ai, combat, true) > ref;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (choices.isEmpty()) {
|
if (choices.isEmpty()) {
|
||||||
@@ -157,7 +157,7 @@ public class ChooseCardAi extends SpellAbilityAi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int ref = host.getName().equals("Forcefield") ? 1 : 0;
|
int ref = host.getName().equals("Forcefield") ? 1 : 0;
|
||||||
return ComputerUtilCombat.damageIfUnblocked(c, ai, combat) > ref;
|
return ComputerUtilCombat.damageIfUnblocked(c, ai, combat, true) > ref;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!better.isEmpty()) {
|
if (!better.isEmpty()) {
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public class ChooseSourceAi extends SpellAbilityAi {
|
|||||||
if (combat == null || !combat.isAttacking(c, ai) || !combat.isUnblocked(c)) {
|
if (combat == null || !combat.isAttacking(c, ai) || !combat.isUnblocked(c)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return ComputerUtilCombat.damageIfUnblocked(c, ai, combat) > 0;
|
return ComputerUtilCombat.damageIfUnblocked(c, ai, combat, true) > 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (choices.isEmpty()) {
|
if (choices.isEmpty()) {
|
||||||
@@ -144,7 +144,7 @@ public class ChooseSourceAi extends SpellAbilityAi {
|
|||||||
|| combat == null || !combat.isAttacking(c, ai) || !combat.isUnblocked(c)) {
|
|| combat == null || !combat.isAttacking(c, ai) || !combat.isUnblocked(c)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return ComputerUtilCombat.damageIfUnblocked(c, ai, combat) > 0;
|
return ComputerUtilCombat.damageIfUnblocked(c, ai, combat, true) > 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return ComputerUtilCard.getBestCreatureAI(permanentSources);
|
return ComputerUtilCard.getBestCreatureAI(permanentSources);
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ public class ProtectAi extends SpellAbilityAi {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
Combat combat = ai.getGame().getCombat();
|
Combat combat = ai.getGame().getCombat();
|
||||||
int dmg = ComputerUtilCombat.damageIfUnblocked(c, ai.getOpponent(), combat);
|
int dmg = ComputerUtilCombat.damageIfUnblocked(c, ai.getOpponent(), combat, true);
|
||||||
float ratio = 1.0f * dmg / ai.getOpponent().getLife();
|
float ratio = 1.0f * dmg / ai.getOpponent().getLife();
|
||||||
Random r = MyRandom.getRandom();
|
Random r = MyRandom.getRandom();
|
||||||
return r.nextFloat() < ratio;
|
return r.nextFloat() < ratio;
|
||||||
|
|||||||
@@ -484,7 +484,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
if (phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && phase.isPlayerTurn(ai)) {
|
if (phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && phase.isPlayerTurn(ai)) {
|
||||||
//1. become attacker for whatever reason
|
//1. become attacker for whatever reason
|
||||||
if (!ComputerUtilCard.doesCreatureAttackAI(ai, c) && ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, pumped)) {
|
if (!ComputerUtilCard.doesCreatureAttackAI(ai, c) && ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, pumped)) {
|
||||||
float threat = 1.0f * ComputerUtilCombat.damageIfUnblocked(pumped, opp, combat) / opp.getLife();
|
float threat = 1.0f * ComputerUtilCombat.damageIfUnblocked(pumped, opp, combat, true) / opp.getLife();
|
||||||
if (CardLists.filter(oppCreatures, CardPredicates.possibleBlockers(pumped)).isEmpty()) {
|
if (CardLists.filter(oppCreatures, CardPredicates.possibleBlockers(pumped)).isEmpty()) {
|
||||||
threat *= 2;
|
threat *= 2;
|
||||||
}
|
}
|
||||||
@@ -495,7 +495,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
if (keywords.contains("Haste") && c.hasSickness() && !c.isTapped()) {
|
if (keywords.contains("Haste") && c.hasSickness() && !c.isTapped()) {
|
||||||
chance += 0.5f;
|
chance += 0.5f;
|
||||||
if (ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, pumped)) {
|
if (ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, pumped)) {
|
||||||
chance += 0.5f * ComputerUtilCombat.damageIfUnblocked(pumped, opp, combat) / opp.getLife();
|
chance += 0.5f * ComputerUtilCombat.damageIfUnblocked(pumped, opp, combat, true) / opp.getLife();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,7 +503,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
if (!CardLists.filter(oppCreatures, CardPredicates.possibleBlockers(c)).isEmpty()) {
|
if (!CardLists.filter(oppCreatures, CardPredicates.possibleBlockers(c)).isEmpty()) {
|
||||||
if (CardLists.filter(oppCreatures, CardPredicates.possibleBlockers(pumped)).isEmpty()
|
if (CardLists.filter(oppCreatures, CardPredicates.possibleBlockers(pumped)).isEmpty()
|
||||||
&& ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, pumped)) {
|
&& ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, pumped)) {
|
||||||
chance += 0.5f * ComputerUtilCombat.damageIfUnblocked(pumped, opp, combat) / opp.getLife();
|
chance += 0.5f * ComputerUtilCombat.damageIfUnblocked(pumped, opp, combat, true) / opp.getLife();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -566,8 +566,8 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
|
|
||||||
//3. buff attacker
|
//3. buff attacker
|
||||||
if (combat.isAttacking(c)) {
|
if (combat.isAttacking(c)) {
|
||||||
int dmg = ComputerUtilCombat.damageIfUnblocked(c, opp, combat);
|
int dmg = ComputerUtilCombat.damageIfUnblocked(c, opp, combat, true);
|
||||||
int pumpedDmg = ComputerUtilCombat.damageIfUnblocked(pumped, opp, pumpedCombat);
|
int pumpedDmg = ComputerUtilCombat.damageIfUnblocked(pumped, opp, pumpedCombat, true);
|
||||||
if (combat.isBlocked(c)) {
|
if (combat.isBlocked(c)) {
|
||||||
if (!c.hasKeyword("Trample")) {
|
if (!c.hasKeyword("Trample")) {
|
||||||
dmg = 0;
|
dmg = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user