- Basic SurveilAi logic, largely inspired with the ScryAi logic.

This commit is contained in:
Agetian
2018-09-13 11:27:56 +03:00
parent e1d34ef9d5
commit 6d599d2b8c

View File

@@ -1,9 +1,13 @@
package forge.ai.ability;
import forge.ai.SpellAbilityAi;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.MyRandom;
public class SurveilAi extends SpellAbilityAi {
@@ -14,10 +18,8 @@ public class SurveilAi extends SpellAbilityAi {
@Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
if (sa.usesTargeting()) { // It doesn't appear that Scry ever targets
// ability is targeted
if (sa.usesTargeting()) { // TODO: It doesn't appear that Surveil ever targets, is this necessary?
sa.resetTargets();
sa.getTargets().add(ai);
}
@@ -33,10 +35,68 @@ public class SurveilAi extends SpellAbilityAi {
return doTriggerAINoCost(ai, sa, false);
}
/*
* (non-Javadoc)
* @see forge.ai.SpellAbilityAi#confirmAction(forge.game.player.Player, forge.game.spellability.SpellAbility, forge.game.player.PlayerActionConfirmMode, java.lang.String)
/**
* Checks if the AI will play a SpellAbility based on its phase restrictions
*/
@Override
protected boolean checkPhaseRestrictions(final Player ai, final SpellAbility sa, final PhaseHandler ph) {
// if the Surveil ability requires tapping and has a mana cost, it's best done at the end of opponent's turn
// and right before the beginning of AI's turn, if possible, to avoid mana locking the AI and also to
// try to scry right before drawing a card. Also, avoid tapping creatures in the AI's turn, if possible,
// even if there's no mana cost.
if (sa.getPayCosts() != null) {
if (sa.getPayCosts().hasTapCost()
&& (sa.getPayCosts().hasManaCost() || (sa.getHostCard() != null && sa.getHostCard().isCreature()))
&& !SpellAbilityAi.isSorcerySpeed(sa)) {
return ph.getNextTurn() == ai && ph.is(PhaseType.END_OF_TURN);
}
}
// in the player's turn Surveil should only be done in Main1 or in Upkeep if able
if (ph.isPlayerTurn(ai)) {
if (SpellAbilityAi.isSorcerySpeed(sa)) {
return ph.is(PhaseType.MAIN1) || sa.hasParam("Planeswalker");
} else {
return ph.is(PhaseType.UPKEEP);
}
}
return true;
}
/**
* Checks if the AI will play a SpellAbility with the specified AiLogic
*/
@Override
protected boolean checkAiLogic(final Player ai, final SpellAbility sa, final String aiLogic) {
if ("Never".equals(aiLogic)) {
return false;
}
// TODO: add card-specific Surveil AI logic here when/if necessary
return true;
}
@Override
protected boolean checkApiLogic(Player ai, SpellAbility sa) {
// Makes no sense to do Surveil when there's nothing in the library
if (ai.getCardsIn(ZoneType.Library).isEmpty()) {
return false;
}
double chance = .4; // 40 percent chance for instant speed
if (SpellAbilityAi.isSorcerySpeed(sa)) {
chance = .667; // 66.7% chance for sorcery speed (since it will never activate EOT)
}
boolean randomReturn = MyRandom.getRandom().nextFloat() <= Math.pow(chance, sa.getActivationsThisTurn() + 1);
if (SpellAbilityAi.playReusable(ai, sa)) {
randomReturn = true;
}
return randomReturn;
}
@Override
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
return true;