Merge pull request #310 from tool4ever/cleanstuff

Cleanup some scripts
This commit is contained in:
Agetian
2022-05-10 08:42:31 +03:00
committed by GitHub
19 changed files with 58 additions and 65 deletions

View File

@@ -46,6 +46,7 @@ import forge.game.combat.GlobalAttackRestrictions;
import forge.game.cost.Cost;
import forge.game.keyword.Keyword;
import forge.game.player.Player;
import forge.game.player.PlayerCollection;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityPredicates;
import forge.game.trigger.Trigger;
@@ -71,7 +72,7 @@ public class AiAttackController {
// possible attackers and blockers
private List<Card> attackers;
private final List<Card> blockers;
private List<Card> blockers;
private List<Card> oppList; // holds human player creatures
private List<Card> myList; // holds computer creatures
@@ -95,11 +96,9 @@ public class AiAttackController {
public AiAttackController(final Player ai, boolean nextTurn) {
this.ai = ai;
defendingOpponent = choosePreferredDefenderPlayer(ai);
this.oppList = getOpponentCreatures(defendingOpponent);
myList = ai.getCreaturesInPlay();
this.nextTurn = nextTurn;
refreshAttackers(defendingOpponent);
this.blockers = getPossibleBlockers(oppList, this.attackers, this.nextTurn);
refreshCombatants(defendingOpponent);
} // overloaded constructor to evaluate attackers that should attack next turn
public AiAttackController(final Player ai, Card attacker) {
@@ -115,13 +114,15 @@ public class AiAttackController {
this.blockers = getPossibleBlockers(oppList, this.attackers, this.nextTurn);
} // overloaded constructor to evaluate single specified attacker
private void refreshAttackers(GameEntity defender) {
private void refreshCombatants(GameEntity defender) {
this.oppList = getOpponentCreatures(defendingOpponent);
this.attackers = new ArrayList<>();
for (Card c : myList) {
if (canAttackWrapper(c, defender)) {
attackers.add(c);
}
}
this.blockers = getPossibleBlockers(oppList, this.attackers, this.nextTurn);
}
public static List<Card> getOpponentCreatures(final Player defender) {
@@ -149,6 +150,7 @@ public class AiAttackController {
public void removeBlocker(Card blocker) {
this.oppList.remove(blocker);
this.blockers.remove(blocker);
}
private boolean canAttackWrapper(final Card attacker, final GameEntity defender) {
@@ -708,12 +710,24 @@ public class AiAttackController {
* @return a {@link forge.game.combat.Combat} object.
*/
public final int declareAttackers(final Combat combat) {
// something prevents attacking, try another
if (this.attackers.isEmpty() && ai.getOpponents().size() > 1) {
final PlayerCollection opps = ai.getOpponents();
opps.remove(defendingOpponent);
defendingOpponent = Aggregates.random(opps);
refreshCombatants(defendingOpponent);
}
final boolean bAssault = doAssault();
// Determine who will be attacked
GameEntity defender = chooseDefender(combat, bAssault);
// decided to attack another defender so related lists need to be updated
// (though usually rather try to avoid this situation for performance reasons)
if (defender != defendingOpponent) {
refreshAttackers(defender);
defendingOpponent = defender instanceof Player ? (Player) defender : ((Card)defender).getController();
refreshCombatants(defender);
}
if (this.attackers.isEmpty()) {
return aiAggression;
@@ -910,8 +924,6 @@ public class AiAttackController {
final List<Card> nextTurnAttackers = new ArrayList<>();
int candidateCounterAttackDamage = 0;
final Player opp = defender instanceof Player ? (Player) defender : ((Card)defender).getController();
this.oppList = getOpponentCreatures(opp);
// get the potential damage and strength of the AI forces
final List<Card> candidateAttackers = new ArrayList<>();
int candidateUnblockedDamage = 0;
@@ -920,7 +932,7 @@ public class AiAttackController {
// turn, assume summoning sickness creatures will be able to
if (ComputerUtilCombat.canAttackNextTurn(pCard) && pCard.getNetCombatDamage() > 0) {
candidateAttackers.add(pCard);
candidateUnblockedDamage += ComputerUtilCombat.damageIfUnblocked(pCard, opp, null, false);
candidateUnblockedDamage += ComputerUtilCombat.damageIfUnblocked(pCard, defendingOpponent, null, false);
computerForces++;
}
}
@@ -962,7 +974,7 @@ public class AiAttackController {
// find the potential damage ratio the AI can cause
double humanLifeToDamageRatio = 1000000;
if (candidateUnblockedDamage > 0) {
humanLifeToDamageRatio = (double) (opp.getLife() - ComputerUtil.possibleNonCombatDamage(ai, opp)) / candidateUnblockedDamage;
humanLifeToDamageRatio = (double) (defendingOpponent.getLife() - ComputerUtil.possibleNonCombatDamage(ai, defendingOpponent)) / candidateUnblockedDamage;
}
// determine if the ai outnumbers the player
@@ -987,7 +999,7 @@ public class AiAttackController {
// get list of attackers ordered from low power to high
CardLists.sortByPowerAsc(this.attackers);
// get player life total
int humanLife = opp.getLife();
int humanLife = defendingOpponent.getLife();
// get the list of attackers up to the first blocked one
final List<Card> attritionalAttackers = new ArrayList<>();
for (int x = 0; x < (this.attackers.size() - humanForces); x++) {
@@ -1037,7 +1049,7 @@ public class AiAttackController {
}
}
if (isUnblockableCreature) {
unblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, opp, combat, false);
unblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, defendingOpponent, combat, false);
}
}
for (final Card attacker : nextTurnAttackers) {
@@ -1051,13 +1063,13 @@ public class AiAttackController {
}
}
if (isUnblockableCreature) {
nextUnblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, opp, null, false);
nextUnblockableDamage += ComputerUtilCombat.damageIfUnblocked(attacker, defendingOpponent, null, false);
}
}
if (unblockableDamage > 0 && !opp.cantLoseForZeroOrLessLife() && opp.canLoseLife()) {
turnsUntilDeathByUnblockable = 1 + (opp.getLife() - unblockableDamage) / nextUnblockableDamage;
if (unblockableDamage > 0 && !defendingOpponent.cantLoseForZeroOrLessLife() && defendingOpponent.canLoseLife()) {
turnsUntilDeathByUnblockable = 1 + (defendingOpponent.getLife() - unblockableDamage) / nextUnblockableDamage;
}
if (opp.canLoseLife()) {
if (defendingOpponent.canLoseLife()) {
doUnblockableAttack = true;
}
// *****************
@@ -1114,8 +1126,8 @@ public class AiAttackController {
if ( LOG_AI_ATTACKS )
System.out.println("attackersLeft = " + attackersLeft);
FCollection<GameEntity> possibleDefenders = new FCollection<>(opp);
possibleDefenders.addAll(opp.getPlaneswalkersInPlay());
FCollection<GameEntity> possibleDefenders = new FCollection<>(defendingOpponent);
possibleDefenders.addAll(defendingOpponent.getPlaneswalkersInPlay());
while (!attackersLeft.isEmpty()) {
CardCollection attackersAssigned = new CardCollection();
@@ -1164,7 +1176,7 @@ public class AiAttackController {
if (pwDefending.isEmpty()) {
// TODO for now only looks at same player as we'd have to check the others from start too
//defender = new PlayerCollection(Iterables.filter(possibleDefenders, Player.class)).min(PlayerPredicates.compareByLife());
defender = opp;
defender = defendingOpponent;
} else {
final Card pwNearUlti = ComputerUtilCard.getBestPlaneswalkerToDamage(pwDefending);
defender = pwNearUlti != null ? pwNearUlti : ComputerUtilCard.getBestPlaneswalkerAI(pwDefending);

View File

@@ -88,6 +88,13 @@ public class AiController {
private SpellAbilityPicker simPicker;
private int lastAttackAggression;
public AiController(final Player computerPlayer, final Game game0) {
player = computerPlayer;
game = game0;
memory = new AiCardMemory();
simPicker = new SpellAbilityPicker(game, player);
}
public boolean canCheatShuffle() {
return cheatShuffle;
}
@@ -141,13 +148,6 @@ public class AiController {
return predictedCombatNextTurn;
}
public AiController(final Player computerPlayer, final Game game0) {
player = computerPlayer;
game = game0;
memory = new AiCardMemory();
simPicker = new SpellAbilityPicker(game, player);
}
private List<SpellAbility> getPossibleETBCounters() {
CardCollection all = new CardCollection(player.getCardsIn(ZoneType.Hand));
CardCollectionView ccvPlayerLibrary = player.getCardsIn(ZoneType.Library);

View File

@@ -341,7 +341,7 @@ public class CountersPutAi extends CountersAi {
if (sa.hasParam("Bolster")) {
CardCollection creatsYouCtrl = ai.getCreaturesInPlay();
CardCollection leastToughness = new CardCollection(Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetDefense));
CardCollection leastToughness = new CardCollection(Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetNetToughness));
if (leastToughness.isEmpty()) {
return false;
}

View File

@@ -2347,9 +2347,6 @@ public class AbilityUtils {
if (sq[0].equals("BloodthirstAmount")) {
return doXMath(player.getBloodthirstAmount(), expr, c, ctb);
}
if (sq[0].equals("YourLandsPlayed")) {
return doXMath(player.getLandsPlayedThisTurn(), expr, c, ctb);
}
if (sq[0].startsWith("YourCounters")) {
// "YourCountersExperience" or "YourCountersPoison"
@@ -2835,16 +2832,10 @@ public class AbilityUtils {
return Aggregates.max(list, CardPredicates.Accessors.fnGetCmc);
}
if (sq[0].startsWith("DifferentPower_")) {
final List<Integer> powers = Lists.newArrayList();
final String restriction = l[0].substring(15);
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), restriction, player, c, ctb);
for (final Card card : list) {
Integer pow = card.getNetPower();
if (!powers.contains(pow)) {
powers.add(pow);
}
}
return doXMath(powers.size(), expr, c, ctb);
final Iterable<Card> powers = Aggregates.uniqueByLast(list, CardPredicates.Accessors.fnGetNetPower);
return doXMath(Iterables.size(powers), expr, c, ctb);
}
if (sq[0].startsWith("DifferentCounterKinds_")) {
final List<CounterType> kinds = Lists.newArrayList();

View File

@@ -183,7 +183,7 @@ public class CountersPutEffect extends SpellAbilityEffect {
if (sa.hasParam("Bolster")) {
CardCollection creatsYouCtrl = activator.getCreaturesInPlay();
CardCollection leastToughness = new CardCollection(
Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetDefense));
Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetNetToughness));
Map<String, Object> params = Maps.newHashMap();
params.put("CounterType", counterType);

View File

@@ -733,13 +733,6 @@ public final class CardPredicates {
}
public static class Accessors {
public static final Function<Card, Integer> fnGetDefense = new Function<Card, Integer>() {
@Override
public Integer apply(Card a) {
return a.getNetToughness();
}
};
public static final Function<Card, Integer> fnGetNetPower = new Function<Card, Integer>() {
@Override
public Integer apply(Card a) {

View File

@@ -268,7 +268,7 @@ public class CombatUtil {
}
return true;
} // canAttack(Card, GameEntity)
}
public static boolean isAttackerSick(final Card attacker, final GameEntity defender) {
final Game game = attacker.getGame();
@@ -1158,7 +1158,7 @@ public class CombatUtil {
}
return true;
} // canBlock()
}
public static boolean canAttackerBeBlockedWithAmount(Card attacker, int amount, Combat combat) {
return canAttackerBeBlockedWithAmount(attacker, amount, combat != null ? combat.getDefenderPlayerByAttacker(attacker) : null);

View File

@@ -4,6 +4,6 @@ Types:Creature Orc Shaman
PT:2/2
K:Dash:3 B
T:Mode$ ChangesZone | ValidCard$ Card.Self,Creature.YouCtrl | Origin$ Any | Destination$ Battlefield | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME or another creature enters the battlefield under your control, that creature gets +2/+2.
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCard | NumAtt$ +2 | NumDef$ +2
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCardLKICopy | NumAtt$ +2 | NumDef$ +2
SVar:BuffedBy:Creature
Oracle:Whenever Ambuscade Shaman or another creature enters the battlefield under your control, that creature gets +2/+2 until end of turn.\nDash {3}{B} (You may cast this spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.)

View File

@@ -3,6 +3,5 @@ ManaCost:2 W
Types:Creature Kor Wizard
PT:3/3
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters the battlefield, you and target opponent each draw a card.
SVar:TrigDraw:DB$ Draw | ValidTgts$ Opponent | NumCards$ 1 | SubAbility$ DBDraw
SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1
SVar:TrigDraw:DB$ Draw | ValidTgts$ Opponent | Defined$ TargetedAndYou | NumCards$ 1
Oracle:When Farsight Adept enters the battlefield, you and target opponent each draw a card.

View File

@@ -5,6 +5,5 @@ PT:0/4
K:Defender
K:Flying
T:Mode$ DamageDoneOnce | Execute$ TrigDraw | ValidTarget$ Card.Self | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME is dealt damage, you and target opponent each draw a card.
SVar:TrigDraw:DB$ Draw | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | NumCards$ 1 | SubAbility$ DBDraw
SVar:DBDraw:DB$ Draw | NumCards$ 1
SVar:TrigDraw:DB$ Draw | ValidTgts$ Opponent | Defined$ TargetedAndYou | NumCards$ 1
Oracle:Defender, flying\nWhenever Flumph is dealt damage, you and target opponent each draw a card.

View File

@@ -2,6 +2,6 @@ Name:In the Web of War
ManaCost:3 R R
Types:Enchantment
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever a creature enters the battlefield under your control, it gets +2/+0 and gains haste until end of turn.
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCard | NumAtt$ +2 | KW$ Haste
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCardLKICopy | NumAtt$ +2 | KW$ Haste
SVar:BuffedBy:Creature
Oracle:Whenever a creature enters the battlefield under your control, it gets +2/+0 and gains haste until end of turn.

View File

@@ -4,7 +4,7 @@ Types:Creature Dinosaur
PT:2/3
S:Mode$ ReduceCost | ValidCard$ Creature | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Creature spells you cast cost {1} less to cast.
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever another creature enters the battlefield under your control, CARDNAME deals 2 damage to it. If a Dinosaur is dealt damage this way, CARDNAME gets +2/+0 until end of turn.
SVar:TrigDmg:DB$ DealDamage | Defined$ TriggeredCard | NumDmg$ 2 | RememberDamaged$ True | SubAbility$ DBPump
SVar:TrigDmg:DB$ DealDamage | Defined$ TriggeredCardLKICopy | NumDmg$ 2 | RememberDamaged$ True | SubAbility$ DBPump
SVar:DBPump:DB$ Pump | Defined$ Self | NumAtt$ 2 | ConditionDefined$ Remembered | ConditionPresent$ Creature.Dinosaur | ConditionCompare$ EQ1 | ConditionDescription$ If a Dinosaur is dealt damage this way, CARDNAME gets +2/+0 until end of turn. | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
AI:RemoveDeck:All

View File

@@ -3,5 +3,5 @@ ManaCost:5
Types:Artifact
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | Execute$ AtlasDraw | CheckSVar$ X | SVarCompare$ EQ0 | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your end step, if you didn't play a land this turn, you may draw a card.
SVar:AtlasDraw:DB$ Draw | Defined$ You | NumCards$ 1
SVar:X:Count$YourLandsPlayed
SVar:X:PlayerCountPropertyYou$LandsPlayed
Oracle:At the beginning of your end step, if you didn't play a land this turn, you may draw a card.

View File

@@ -3,6 +3,6 @@ ManaCost:2 R R
Types:Creature Ogre Warrior
PT:3/3
T:Mode$ ChangesZone | ValidCard$ Creature.Other+YouCtrl | Origin$ Any | Destination$ Battlefield | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever another creature enters the battlefield under your control, that creature gets +2/+0 and haste until end of turn.
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCard | NumAtt$ +2 | NumDef$ +0 | KW$ Haste
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCardLKICopy | NumAtt$ +2 | NumDef$ +0 | KW$ Haste
SVar:BuffedBy:Creature
Oracle:Whenever another creature enters the battlefield under your control, that creature gets +2/+0 and gains haste until end of turn. (It can attack and {T} this turn.)

View File

@@ -5,5 +5,5 @@ A:AB$ Mana | Cost$ T | Produced$ U | ConditionCheckSVar$ X | ConditionSVarCompar
SVar:ManaB:DB$ Mana | Produced$ B | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1
AI:RemoveDeck:Random
DeckHints:Color$Blue|Black
SVar:X:Count$YourLandsPlayed
SVar:X:PlayerCountPropertyYou$LandsPlayed
Oracle:{T}: Add {U}. If you played a land this turn, add {B} instead.

View File

@@ -4,6 +4,6 @@ Types:Creature Goblin
PT:3/3
S:Mode$ CantBeCast | Caster$ You | ValidCard$ Card.Self | CheckSVar$ XJockey | SVarCompare$ GE1 | EffectZone$ All | Description$ You can't cast this spell if you've played a land this turn.
S:Mode$ CantPlayLand | Player$ You | CheckSVar$ RockyX | SVarCompare$ GE1 | Description$ You can't play lands if you've cast CARDNAME this turn.
SVar:XJockey:Count$YourLandsPlayed
SVar:XJockey:PlayerCountPropertyYou$LandsPlayed
SVar:RockyX:Count$ThisTurnCast_Card.Self
Oracle:You can't cast this spell if you've played a land this turn.\nYou can't play lands if you've cast Rock Jockey this turn.

View File

@@ -1,6 +1,5 @@
Name:Secret Rendezvous
ManaCost:1 W W
Types:Sorcery
A:SP$ Draw | Cost$ 1 W W | NumCards$ 3 | SubAbility$ DBDraw | SpellDescription$ You and target opponent each draw three cards.
SVar:DBDraw:DB$ Draw | NumCards$ 3 | ValidTgts$ Opponent | TgtPrompt$ Select target opponent
A:SP$ Draw | Cost$ 1 W W | NumCards$ 3 | ValidTgts$ Opponent | Defined$ TargetedAndYou | SpellDescription$ You and target opponent each draw three cards.
Oracle:You and target opponent each draw three cards.

View File

@@ -5,9 +5,9 @@ PT:2/4
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ At the beginning of your upkeep, put a shield counter on target creature an opponent controls.
SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | CounterType$ SHIELD | AILogic$ Curse
T:Mode$ CounterAddedOnce | ValidCard$ Creature.YouDontCtrl | ValidSource$ You | TriggerZones$ Battlefield | Execute$ TrigTap | TriggerDescription$ Whenever you put one or more counters on a creature you don't control, tap that creature and goad it. It gains trample until your next turn. (Until your next turn, that creature attacks each combat if able and attacks a player other than you if able.)
SVar:TrigTap:DB$ Tap | Defined$ TriggeredCard | SubAbility$ DBGoad
SVar:DBGoad:DB$ Goad | Defined$ TriggeredCard | SubAbility$ DBPump
SVar:DBPump:DB$ Pump | Defined$ TriggeredCard | KW$ Trample | Duration$ UntilYourNextTurn
SVar:TrigTap:DB$ Tap | Defined$ TriggeredCardLKICopy | SubAbility$ DBGoad
SVar:DBGoad:DB$ Goad | Defined$ TriggeredCardLKICopy | SubAbility$ DBPump
SVar:DBPump:DB$ Pump | Defined$ TriggeredCardLKICopy | KW$ Trample | Duration$ UntilYourNextTurn
#Card doesn't make sense to run unless you have 2 or more opponents
AI:RemoveDeck:Random
Oracle:At the beginning of your upkeep, put a shield counter on target creature an opponent controls.\nWhenever you put one or more counters on a creature you don't control, tap that creature and goad it. It gains trample until your next turn. (Until your next turn, that creature attacks each combat if able and attacks a player other than you if able.)

View File

@@ -6,5 +6,5 @@ K:Trample
T:Mode$ TapsForMana | ValidCard$ Land | Activator$ You | Execute$ TrigMana | TriggerZones$ Battlefield | Static$ True | TriggerDescription$ Whenever you tap a land for mana, add one mana of any type that land produced.
SVar:TrigMana:DB$ ManaReflected | ColorOrType$ Type | ReflectProperty$ Produced | Defined$ You
T:Mode$ TapsForMana | ValidCard$ Land.OppCtrl | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever an opponent taps a land for mana, that land doesn't untap during its controller's next untap step.
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCard | Duration$ Permanent | KW$ HIDDEN This card doesn't untap during your next untap step.
SVar:TrigPump:DB$ Pump | Defined$ TriggeredCardLKICopy | Duration$ Permanent | KW$ HIDDEN This card doesn't untap during your next untap step.
Oracle:Trample\nWhenever you tap a land for mana, add one mana of any type that land produced.\nWhenever an opponent taps a land for mana, that land doesn't untap during its controller's next untap step.