MCPcopy Create free account
hub / github.com/Card-Forge/forge / canFight

Method canFight

forge-ai/src/main/java/forge/ai/ability/FightAi.java:183–274  ·  view source on GitHub ↗

Logic for evaluating fight effects @param ai controlling player @param sa host SpellAbility @param toughness bonus to toughness @param power bonus to power @return true if fight effect should be played, false otherwise

(final Player ai, final SpellAbility sa, int power, int toughness)

Source from the content-addressed store, hash-verified

181 * @return true if fight effect should be played, false otherwise
182 */
183 public static AiAbilityDecision canFight(final Player ai, final SpellAbility sa, int power, int toughness) {
184 final Card source = sa.getHostCard();
185 final String sourceName = ComputerUtilAbility.getAbilitySourceName(sa);
186 AbilitySub tgtFight = sa.getSubAbility();
187 while (tgtFight != null && tgtFight.getApi() != ApiType.Fight && tgtFight.getApi() != ApiType.DealDamage && tgtFight.getApi() != ApiType.EachDamage) {
188 // Search for the Fight/DealDamage subability (matters e.g. for Ent's Fury where the Fight SA is not an immediate child of Pump)
189 tgtFight = tgtFight.getSubAbility();
190 }
191 if (tgtFight == null) {
192 System.out.println("Warning: couldn't find a Fight/DealDamage subability from FightAi.canFightAi for card " + source.toString());
193 tgtFight = sa.getSubAbility(); // at least avoid a NPE, although this will most likely fail
194 }
195 final boolean isChandrasIgnition = "Chandra's Ignition".equals(sourceName); // TODO: generalize this for other "fake Fight" cases that do not target
196 if ("Savage Punch".equals(sourceName) && !ai.hasFerocious()) {
197 power = 0;
198 toughness = 0;
199 }
200 // Get sorted creature lists
201 CardCollection aiCreatures = ai.getCreaturesInPlay();
202 CardCollection humCreatures = ai.getOpponents().getCreaturesInPlay();
203 if ("Time to Feed".equals(sourceName)) { // flip sa
204 aiCreatures = CardLists.getTargetableCards(aiCreatures, tgtFight);
205 aiCreatures = ComputerUtil.getSafeTargets(ai, tgtFight, aiCreatures);
206 humCreatures = CardLists.getTargetableCards(humCreatures, sa);
207 } else {
208 aiCreatures = CardLists.getTargetableCards(aiCreatures, sa);
209 aiCreatures = ComputerUtil.getSafeTargets(ai, sa, aiCreatures);
210 humCreatures = CardLists.getTargetableCards(humCreatures, tgtFight);
211 }
212 ComputerUtilCard.sortByEvaluateCreature(aiCreatures);
213 ComputerUtilCard.sortByEvaluateCreature(humCreatures);
214 if (humCreatures.isEmpty() || aiCreatures.isEmpty()) {
215 return new AiAbilityDecision(0, AiPlayDecision.MissingNeededCards);
216 }
217 // Evaluate creature pairs
218 for (Card humanCreature : humCreatures) {
219 for (Card aiCreature : aiCreatures) {
220 if (source.isSpell()) { // heroic triggers adding counters and prowess
221 final int bonus = getSpellBonus(aiCreature);
222 power += bonus;
223 toughness += bonus;
224 }
225 if ("PowerDmg".equals(sa.getParam("AILogic"))) {
226 if ("2".equals(sa.getParam("TargetMax"))) {
227 // Band Together, uses up to two targets to deal damage to a single target
228 // TODO: Generalize this so that other TargetMax values can be properly accounted for
229 CardCollection aiCreaturesByPower = new CardCollection(aiCreatures);
230 CardLists.sortByPowerDesc(aiCreaturesByPower);
231 Card maxPower = aiCreaturesByPower.getFirst();
232 if (maxPower != aiCreature) {
233 power += maxPower.getNetPower(); // potential bonus from adding a second target
234 }
235 else if ("2".equals(sa.getParam("TargetMin"))) {
236 continue;
237 }
238 if (canKill(aiCreature, humanCreature, power)) {
239 sa.getTargets().add(aiCreature);
240 sa.getTargets().add(maxPower);

Callers 4

checkApiLogicMethod · 0.95
doTriggerNoCostMethod · 0.95
pumpTgtAIMethod · 0.95
checkApiLogicMethod · 0.95

Calls 15

getAbilitySourceNameMethod · 0.95
toStringMethod · 0.95
getTargetableCardsMethod · 0.95
getSafeTargetsMethod · 0.95
isSpellMethod · 0.95
getSpellBonusMethod · 0.95
sortByPowerDescMethod · 0.95
getNetPowerMethod · 0.95
canKillMethod · 0.95
shouldFightMethod · 0.95
hasFerociousMethod · 0.80

Tested by

no test coverage detected