mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
- Basic SurveilAi logic, largely inspired with the ScryAi logic.
This commit is contained in:
@@ -1,9 +1,13 @@
|
|||||||
package forge.ai.ability;
|
package forge.ai.ability;
|
||||||
|
|
||||||
import forge.ai.SpellAbilityAi;
|
import forge.ai.SpellAbilityAi;
|
||||||
|
import forge.game.phase.PhaseHandler;
|
||||||
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.player.PlayerActionConfirmMode;
|
import forge.game.player.PlayerActionConfirmMode;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.zone.ZoneType;
|
||||||
|
import forge.util.MyRandom;
|
||||||
|
|
||||||
public class SurveilAi extends SpellAbilityAi {
|
public class SurveilAi extends SpellAbilityAi {
|
||||||
|
|
||||||
@@ -14,10 +18,8 @@ public class SurveilAi extends SpellAbilityAi {
|
|||||||
@Override
|
@Override
|
||||||
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
||||||
|
|
||||||
if (sa.usesTargeting()) { // It doesn't appear that Scry ever targets
|
if (sa.usesTargeting()) { // TODO: It doesn't appear that Surveil ever targets, is this necessary?
|
||||||
// ability is targeted
|
|
||||||
sa.resetTargets();
|
sa.resetTargets();
|
||||||
|
|
||||||
sa.getTargets().add(ai);
|
sa.getTargets().add(ai);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,10 +35,68 @@ public class SurveilAi extends SpellAbilityAi {
|
|||||||
return doTriggerAINoCost(ai, sa, false);
|
return doTriggerAINoCost(ai, sa, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* (non-Javadoc)
|
* Checks if the AI will play a SpellAbility based on its phase restrictions
|
||||||
* @see forge.ai.SpellAbilityAi#confirmAction(forge.game.player.Player, forge.game.spellability.SpellAbility, forge.game.player.PlayerActionConfirmMode, java.lang.String)
|
|
||||||
*/
|
*/
|
||||||
|
@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
|
@Override
|
||||||
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user