mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
- Merge: Merge the latest trunk into SplitCards (did not work properly last time).
This commit is contained in:
@@ -6876,10 +6876,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
for (final Object rem : source.getRemembered()) {
|
||||
if (rem instanceof Card) {
|
||||
final Card card = (Card) rem;
|
||||
System.out.println(this + " vs " + card);
|
||||
System.out.println(this.getOwner().equals(card.getOwner()));
|
||||
System.out.println(this.getOwner());
|
||||
System.out.println(card.getOwner());
|
||||
if (!this.getOwner().equals(card.getOwner())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -294,8 +294,6 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
|
||||
chance &= (r.nextFloat() < .8);
|
||||
|
||||
final AbilitySub subAb = sa.getSubAbility();
|
||||
chance &= subAb == null || subAb.getAi().chkDrawbackWithSubs(ai, subAb);
|
||||
|
||||
|
||||
@@ -4,11 +4,12 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.ability.effects.CharmEffect;
|
||||
import org.apache.commons.lang.math.RandomUtils;
|
||||
import forge.card.ability.SpellAbilityAi;import forge.card.ability.effects.CharmEffect;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
public class CharmAi extends SpellAbilityAi {
|
||||
@@ -22,7 +23,7 @@ public class CharmAi extends SpellAbilityAi {
|
||||
boolean timingRight = sa.isTrigger(); //is there a reason to play the charm now?
|
||||
|
||||
List<AbilitySub> chooseFrom = CharmEffect.makePossibleOptions(sa);
|
||||
List<AbilitySub> chosenList = chooseOptionsAi(ai, timingRight, chooseFrom, num, min);
|
||||
List<AbilitySub> chosenList = chooseOptionsAi(ai, timingRight, chooseFrom, num, min, false);
|
||||
|
||||
if (chosenList == null || chosenList.isEmpty()) {
|
||||
return false;
|
||||
@@ -32,9 +33,17 @@ public class CharmAi extends SpellAbilityAi {
|
||||
return r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
|
||||
}
|
||||
|
||||
public static List<AbilitySub> chooseOptionsAi(final AIPlayer ai, boolean playNow, List<AbilitySub> choices, int num, int min) {
|
||||
public static List<AbilitySub> chooseOptionsAi(final AIPlayer ai, boolean playNow, List<AbilitySub> choices, int num, int min, boolean opponentChoser) {
|
||||
List<AbilitySub> chosenList = new ArrayList<AbilitySub>();
|
||||
|
||||
if (opponentChoser) {
|
||||
// This branch is for "An Opponent chooses" Charm spells from Alliances
|
||||
// Current just choose the first available spell, which seem generally less disastrous for the AI.
|
||||
//return choices.subList(0, 1);
|
||||
return choices.subList(1, choices.size());
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
AbilitySub thisPick = null;
|
||||
for (SpellAbility sub : choices) {
|
||||
@@ -57,4 +66,9 @@ public class CharmAi extends SpellAbilityAi {
|
||||
}
|
||||
return chosenList.size() >= min ? chosenList : null;
|
||||
}
|
||||
|
||||
public static Player determineOpponentChooser(AIPlayer ai, SpellAbility sa, List<Player> opponents) {
|
||||
return opponents.get(RandomUtils.nextInt(opponents.size()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,9 +2,12 @@ package forge.card.ability.ai;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import forge.Card;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilMana;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -14,6 +17,7 @@ public class DigUntilAi extends SpellAbilityAi {
|
||||
|
||||
@Override
|
||||
protected boolean canPlayAI(AIPlayer ai, SpellAbility sa) {
|
||||
Card source = sa.getSourceCard();
|
||||
double chance = .4; // 40 percent chance with instant speed stuff
|
||||
if (SpellAbilityAi.isSorcerySpeed(sa)) {
|
||||
chance = .667; // 66.7% chance for sorcery speed (since it will
|
||||
@@ -36,6 +40,18 @@ public class DigUntilAi extends SpellAbilityAi {
|
||||
libraryOwner = opp;
|
||||
}
|
||||
|
||||
final String num = sa.getParam("Amount");
|
||||
if ((num != null) && num.equals("X") && source.getSVar(num).equals("Count$xPaid")) {
|
||||
// Set PayX here to maximum value.
|
||||
if (!(sa instanceof AbilitySub) || source.getSVar("PayX").equals("")) {
|
||||
int numCards = ComputerUtilMana.determineLeftoverMana(sa, ai);
|
||||
if (numCards <= 0) {
|
||||
return false;
|
||||
}
|
||||
source.setSVar("PayX", Integer.toString(numCards));
|
||||
}
|
||||
}
|
||||
|
||||
// return false if nothing to dig into
|
||||
if (libraryOwner.getCardsIn(ZoneType.Library).isEmpty()) {
|
||||
return false;
|
||||
|
||||
@@ -50,17 +50,37 @@ public class CharmEffect extends SpellAbilityEffect {
|
||||
final List<AbilitySub> choices = makePossibleOptions(sa);
|
||||
|
||||
List<AbilitySub> chosen = null;
|
||||
|
||||
Card source = sa.getSourceCard();
|
||||
Player activator = sa.getActivatingPlayer();
|
||||
if (activator.isHuman()) {
|
||||
Player chooser = sa.getActivatingPlayer();
|
||||
|
||||
if (sa.hasParam("Chooser")) {
|
||||
// Three modal cards require you to choose a player to make the modal choice'
|
||||
// Two of these also reference the chosen player during the spell effect
|
||||
String choose = sa.getParam("Chooser");
|
||||
List<Player> opponents = activator.getOpponents();
|
||||
int numOpps = opponents.size();
|
||||
if (numOpps == 1) {
|
||||
chooser = opponents.get(0);
|
||||
} else {
|
||||
if (activator.isComputer()) {
|
||||
chooser = CharmAi.determineOpponentChooser((AIPlayer)activator, sa, opponents);
|
||||
} else {
|
||||
chooser = GuiChoose.one("Choose an opponent", opponents);
|
||||
}
|
||||
}
|
||||
source.setChosenPlayer(chooser);
|
||||
}
|
||||
|
||||
if (chooser.isHuman()) {
|
||||
String modeTitle = String.format("%s activated %s - Choose a mode", activator, source);
|
||||
chosen = new ArrayList<AbilitySub>();
|
||||
for (int i = 0; i < num; i++) {
|
||||
AbilitySub a;
|
||||
if (i < min) {
|
||||
a = GuiChoose.one("Choose a mode", choices);
|
||||
a = GuiChoose.one(modeTitle, choices);
|
||||
} else {
|
||||
a = GuiChoose.oneOrNone("Choose a mode", choices);
|
||||
a = GuiChoose.oneOrNone(modeTitle, choices);
|
||||
}
|
||||
if (null == a) {
|
||||
break;
|
||||
@@ -70,7 +90,7 @@ public class CharmEffect extends SpellAbilityEffect {
|
||||
chosen.add(a);
|
||||
}
|
||||
} else {
|
||||
chosen = CharmAi.chooseOptionsAi((AIPlayer)activator, sa.isTrigger(), choices, num, min);
|
||||
chosen = CharmAi.chooseOptionsAi((AIPlayer)chooser, sa.isTrigger(), choices, num, min, !chooser.equals(activator));
|
||||
}
|
||||
|
||||
chainAbilities(sa, chosen);
|
||||
|
||||
@@ -200,8 +200,7 @@ public class SpellAbilityCondition extends SpellAbilityVariables {
|
||||
}
|
||||
}
|
||||
if (this.isAllTargetsLegal()) {
|
||||
SpellAbility root = sa.getRootAbility();
|
||||
for (Card c : root.getTarget().getTargetCards()) {
|
||||
for (Card c : sa.getTarget().getTargetCards()) {
|
||||
if (!CardFactoryUtil.isTargetStillValid(sa, c)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -62,10 +62,19 @@ public class InputMulligan extends Input {
|
||||
ButtonUtil.setButtonText("No", "Yes");
|
||||
ButtonUtil.enableAllFocusOk();
|
||||
|
||||
final String str =
|
||||
(Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn().equals(Singletons.getControl().getPlayer())
|
||||
? "You're going first. " : "The computer is going first. ");
|
||||
CMatchUI.SINGLETON_INSTANCE.showMessage(str + "Do you want to Mulligan?");
|
||||
GameState game = Singletons.getModel().getGame();
|
||||
Player startingPlayer = game.getPhaseHandler().getPlayerTurn();
|
||||
Player localPlayer = Singletons.getControl().getPlayer();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(startingPlayer.getName()).append(" is going first. ");
|
||||
|
||||
if (!startingPlayer.equals(localPlayer)) {
|
||||
sb.append("You are going ").append(game.getOrdinalPosition(localPlayer, startingPlayer)).append(". ");
|
||||
}
|
||||
|
||||
sb.append("Do you want to Mulligan?");
|
||||
CMatchUI.SINGLETON_INSTANCE.showMessage(sb.toString());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
|
||||
@@ -478,6 +478,21 @@ public class GameState {
|
||||
return roIngamePlayers.get(iPlayer);
|
||||
|
||||
}
|
||||
|
||||
public String getOrdinalPosition(Player player, Player startingPlayer) {
|
||||
int startPosition = roIngamePlayers.indexOf(startingPlayer);
|
||||
int position = roIngamePlayers.indexOf(player) + startPosition + 1;
|
||||
String[] sufixes = new String[] { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" };
|
||||
switch (position % 100) {
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
return position + "th";
|
||||
default:
|
||||
return position + sufixes[position % 10];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only game knows how to get suitable players out of just connected clients.
|
||||
|
||||
@@ -2522,6 +2522,10 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
||||
if (!source.getRemembered().contains(this)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("IsNotRemembered")) {
|
||||
if (source.getRemembered().contains(this)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.startsWith("EnchantedBy")) {
|
||||
if (!this.getEnchantedBy().contains(source)) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user