mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 03:08:02 +00:00
- Fixed preventRunAwayActivations to work with temporary abilities.
- AI updates and code cleanup.
This commit is contained in:
@@ -4,7 +4,7 @@ Types:Enchantment Aura
|
|||||||
K:Enchant creature
|
K:Enchant creature
|
||||||
A:SP$ Attach | Cost$ 2 R R | ValidTgts$ Creature | AILogic$ Pump
|
A:SP$ Attach | Cost$ 2 R R | ValidTgts$ Creature | AILogic$ Pump
|
||||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddAbility$ ABCopy | Description$ Enchanted creature has "{T}: Put a token that's a copy of this creature onto the battlefield. That token has haste. Exile it at the beginning of the next end step."
|
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddAbility$ ABCopy | Description$ Enchanted creature has "{T}: Put a token that's a copy of this creature onto the battlefield. That token has haste. Exile it at the beginning of the next end step."
|
||||||
SVar:ABCopy:AB$CopyPermanent | Cost$ T | Defined$ Self | Keywords$ Haste | AtEOT$ Exile | SpellDescription$ Put a token that's a copy of this creature onto the battlefield. That token has haste. Exile it at the beginning of the next end step.
|
SVar:ABCopy:AB$ CopyPermanent | Cost$ T | Defined$ Self | Keywords$ Haste | AtEOT$ Exile | SpellDescription$ Put a token that's a copy of this creature onto the battlefield. That token has haste. Exile it at the beginning of the next end step.
|
||||||
SVar:NonStackingAttachEffect:True
|
SVar:NonStackingAttachEffect:True
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/splinter_twin.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/splinter_twin.jpg
|
||||||
Oracle:Enchant creature\nEnchanted creature has "{T}: Put a token that's a copy of this creature onto the battlefield. That token has haste. Exile it at the beginning of the next end step."
|
Oracle:Enchant creature\nEnchanted creature has "{T}: Put a token that's a copy of this creature onto the battlefield. That token has haste. Exile it at the beginning of the next end step."
|
||||||
@@ -1136,13 +1136,19 @@ public class ComputerUtil {
|
|||||||
* @return a boolean (returns true if the AI should stop using the ability).
|
* @return a boolean (returns true if the AI should stop using the ability).
|
||||||
*/
|
*/
|
||||||
public static boolean preventRunAwayActivations(final SpellAbility sa) {
|
public static boolean preventRunAwayActivations(final SpellAbility sa) {
|
||||||
final int activations = sa.getRestrictions().getNumberTurnActivations();
|
int activations = sa.getRestrictions().getNumberTurnActivations();
|
||||||
|
|
||||||
|
if (sa.isTemporary()) {
|
||||||
|
final Random r = MyRandom.getRandom();
|
||||||
|
return r.nextFloat() >= .95; // Abilities created by static abilities have no memory
|
||||||
|
}
|
||||||
|
|
||||||
if (activations < 10) { //10 activations per turn should still be acceptable
|
if (activations < 10) { //10 activations per turn should still be acceptable
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final Random r = MyRandom.getRandom();
|
|
||||||
|
|
||||||
return r.nextFloat() <= Math.pow(.95, activations);
|
final Random r = MyRandom.getRandom();
|
||||||
|
return r.nextFloat() >= Math.pow(.95, activations);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ package forge.ai.ability;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
|
||||||
|
import forge.ai.ComputerUtil;
|
||||||
import forge.ai.ComputerUtilCard;
|
import forge.ai.ComputerUtilCard;
|
||||||
import forge.ai.SpellAbilityAi;
|
import forge.ai.SpellAbilityAi;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
@@ -18,7 +18,6 @@ import forge.game.player.PlayerActionConfirmMode;
|
|||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.TargetRestrictions;
|
import forge.game.spellability.TargetRestrictions;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.MyRandom;
|
|
||||||
|
|
||||||
public class CopyPermanentAi extends SpellAbilityAi {
|
public class CopyPermanentAi extends SpellAbilityAi {
|
||||||
|
|
||||||
@@ -30,20 +29,14 @@ public class CopyPermanentAi extends SpellAbilityAi {
|
|||||||
// Card source = sa.getSourceCard();
|
// Card source = sa.getSourceCard();
|
||||||
// TODO - I'm sure someone can do this AI better
|
// TODO - I'm sure someone can do this AI better
|
||||||
|
|
||||||
|
if (ComputerUtil.preventRunAwayActivations(sa)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (sa.hasParam("AtEOT") && !aiPlayer.getGame().getPhaseHandler().is(PhaseType.MAIN1)) {
|
if (sa.hasParam("AtEOT") && !aiPlayer.getGame().getPhaseHandler().is(PhaseType.MAIN1)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
double chance = .4; // 40 percent chance with instant speed stuff
|
return this.doTriggerAINoCost(aiPlayer, sa, false);
|
||||||
if (SpellAbilityAi.isSorcerySpeed(sa)) {
|
|
||||||
chance = .667; // 66.7% chance for sorcery speed (since it will
|
|
||||||
// never activate EOT)
|
|
||||||
}
|
|
||||||
final Random r = MyRandom.getRandom();
|
|
||||||
if (r.nextFloat() <= Math.pow(chance, sa.getActivationsThisTurn() + 1)) {
|
|
||||||
return this.doTriggerAINoCost(aiPlayer, sa, false);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -118,15 +118,12 @@ public class TokenAi extends SpellAbilityAi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ph.isPlayerTurn(ai)
|
if ((ph.isPlayerTurn(ai) || ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS))
|
||||||
|| ph.getPhase().isBefore(
|
|
||||||
PhaseType.COMBAT_DECLARE_ATTACKERS))
|
|
||||||
&& !sa.hasParam("ActivationPhases") && !sa.hasParam("PlayerTurn")
|
&& !sa.hasParam("ActivationPhases") && !sa.hasParam("PlayerTurn")
|
||||||
&& !SpellAbilityAi.isSorcerySpeed(sa) && !haste) {
|
&& !SpellAbilityAi.isSorcerySpeed(sa) && !haste) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((ph.getPhase().isAfter(PhaseType.COMBAT_BEGIN) || game.getPhaseHandler().isPlayerTurn(
|
if ((ph.getPhase().isAfter(PhaseType.COMBAT_BEGIN) || game.getPhaseHandler().isPlayerTurn(opp))
|
||||||
opp))
|
|
||||||
&& oneShot) {
|
&& oneShot) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -191,7 +188,7 @@ public class TokenAi extends SpellAbilityAi {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (sa.isAbility()) {
|
if (sa.isAbility()) {
|
||||||
return (r.nextFloat() < .9);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (r.nextFloat() < .8);
|
return (r.nextFloat() < .8);
|
||||||
|
|||||||
Reference in New Issue
Block a user