mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
- Converted Old Man of the Sea
- Added Rootwater Matriarch
This commit is contained in:
@@ -72,7 +72,7 @@ public class Game {
|
||||
public final Upkeep upkeep;
|
||||
public final MagicStack stack;
|
||||
private final PhaseHandler phaseHandler;
|
||||
private final StaticEffects staticEffects = new StaticEffects(this);
|
||||
private final StaticEffects staticEffects = new StaticEffects();
|
||||
private final TriggerHandler triggerHandler = new TriggerHandler(this);
|
||||
private final ReplacementHandler replacementHandler = new ReplacementHandler(this);
|
||||
private final EventBus events = new EventBus("game events");
|
||||
|
||||
@@ -27,7 +27,6 @@ import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -38,6 +37,7 @@ import forge.FThreads;
|
||||
import forge.card.CardCharacteristicName;
|
||||
import forge.card.CardType;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.ability.effects.AttachEffect;
|
||||
import forge.game.card.Card;
|
||||
@@ -71,6 +71,7 @@ import forge.game.zone.ZoneType;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.CollectionSuppliers;
|
||||
import forge.util.Expressions;
|
||||
import forge.util.ThreadUtil;
|
||||
import forge.util.maps.HashMapOfLists;
|
||||
import forge.util.maps.MapOfLists;
|
||||
@@ -473,6 +474,7 @@ public class GameAction {
|
||||
for (Player p : game.getPlayers()) {
|
||||
((PlayerZoneBattlefield) p.getZone(ZoneType.Battlefield)).setTriggers(true);
|
||||
}
|
||||
c.runChangeControllerCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -701,6 +703,7 @@ public class GameAction {
|
||||
// search for cards with static abilities
|
||||
final List<Card> allCards = game.getCardsInGame();
|
||||
final ArrayList<StaticAbility> staticAbilities = new ArrayList<StaticAbility>();
|
||||
final List<Card> staticList = new ArrayList<Card>();
|
||||
for (final Card c : allCards) {
|
||||
for (int i = 0; i < c.getStaticAbilities().size(); i++) {
|
||||
StaticAbility stAb = c.getCharacteristics().getStaticAbilities().get(i);
|
||||
@@ -712,6 +715,9 @@ public class GameAction {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (!c.getStaticCommandList().isEmpty()) {
|
||||
staticList.add(c);
|
||||
}
|
||||
}
|
||||
|
||||
final Comparator<StaticAbility> comp = new Comparator<StaticAbility>() {
|
||||
@@ -733,14 +739,33 @@ public class GameAction {
|
||||
}
|
||||
|
||||
// card state effects like Glorious Anthem
|
||||
for (final String effect : game.getStaticEffects().getStateBasedMap().keySet()) {
|
||||
final Function<Game, ?> com = GameActionUtil.getCommands().get(effect);
|
||||
com.apply(game);
|
||||
}
|
||||
// for (final String effect : game.getStaticEffects().getStateBasedMap().keySet()) {
|
||||
// final Function<Game, ?> com = GameActionUtil.getCommands().get(effect);
|
||||
// com.apply(game);
|
||||
// }
|
||||
|
||||
List<Card> lands = game.getCardsIn(ZoneType.Battlefield);
|
||||
GameActionUtil.grantBasicLandsManaAbilities(CardLists.filter(lands, CardPredicates.Presets.LANDS));
|
||||
|
||||
for (final Card c : staticList) {
|
||||
for (int i = 0; i < c.getStaticCommandList().size(); i++) {
|
||||
final Object[] staticCheck = c.getStaticCommandList().get(i);
|
||||
final String leftVar = (String) staticCheck[0];
|
||||
final String rightVar = (String) staticCheck[1];
|
||||
final Card affected = (Card) staticCheck[2];
|
||||
// calculate the affected card
|
||||
final int sVar = AbilityUtils.calculateAmount(affected, leftVar, null);
|
||||
final String svarOperator = rightVar.substring(0, 2);
|
||||
final String svarOperand = rightVar.substring(2);
|
||||
final int operandValue = AbilityUtils.calculateAmount(c, svarOperand, null);
|
||||
if (Expressions.compare(sVar, svarOperator, operandValue)) {
|
||||
((Command) staticCheck[3]).run();
|
||||
c.getStaticCommandList().remove(i);
|
||||
i--;
|
||||
affectedCards.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Exclude cards in hidden zones from update
|
||||
Iterator<Card> it = affectedCards.iterator();
|
||||
while (it.hasNext()) {
|
||||
@@ -753,6 +778,7 @@ public class GameAction {
|
||||
if (!affectedCards.isEmpty()) {
|
||||
game.fireEvent(new GameEventCardStatsChanged(affectedCards));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -796,9 +822,8 @@ public class GameAction {
|
||||
|
||||
for (Player p : game.getPlayers()) {
|
||||
for (Card c : p.getCardsIn(ZoneType.Battlefield)) {
|
||||
if (!c.getController().equals(p)) {
|
||||
if (!c.getController().equals(p)) { // should not be here
|
||||
controllerChangeZoneCorrection(c);
|
||||
c.runChangeControllerCommands();
|
||||
checkAgain = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,17 +18,14 @@
|
||||
package forge.game;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.Command;
|
||||
import forge.card.MagicColor;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
@@ -114,47 +111,6 @@ public final class GameActionUtil {
|
||||
c.getDamageHistory().registerCombatDamage(player);
|
||||
} // executeCombatDamageToPlayerEffects
|
||||
|
||||
/** Constant <code>oldManOfTheSea</code>. */
|
||||
private static Function<Game, ?> oldManOfTheSea = new Function<Game, Object>() {
|
||||
|
||||
@Override
|
||||
public Object apply(Game game) {
|
||||
final List<Card> list = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Old Man of the Sea"));
|
||||
for (final Card oldman : list) {
|
||||
if (!oldman.getGainControlTargets().isEmpty()) {
|
||||
if (oldman.getNetAttack() < oldman.getGainControlTargets().get(0).getNetAttack()) {
|
||||
final List<Command> coms = oldman.getGainControlReleaseCommands();
|
||||
for (int i = 0; i < coms.size(); i++) {
|
||||
coms.get(i).run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}; // Old Man of the Sea
|
||||
|
||||
|
||||
/** Constant <code>commands</code>. */
|
||||
private final static HashMap<String, Function<Game, ?>> commands = new HashMap<String, Function<Game, ?>>();
|
||||
|
||||
static {
|
||||
// Please add cards in alphabetical order so they are easier to find
|
||||
|
||||
GameActionUtil.getCommands().put("Old_Man_of_the_Sea", GameActionUtil.oldManOfTheSea);
|
||||
|
||||
// The commands above are in alphabetical order by cardname.
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the commands.
|
||||
*
|
||||
* @return the commands
|
||||
*/
|
||||
public static Map<String, Function<Game, ?>> getCommands() {
|
||||
return GameActionUtil.commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the st land mana abilities.
|
||||
* @param game
|
||||
|
||||
@@ -25,14 +25,11 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -48,8 +45,6 @@ public class StaticEffects {
|
||||
private final ArrayList<StaticEffect> staticEffects = new ArrayList<StaticEffect>();
|
||||
//Global rule changes
|
||||
private final EnumSet<GlobalRuleChange> ruleChanges = EnumSet.noneOf(GlobalRuleChange.class);
|
||||
|
||||
private final Game game;
|
||||
|
||||
public final Set<Card> clearStaticEffects() {
|
||||
ruleChanges.clear();
|
||||
@@ -256,123 +251,5 @@ public class StaticEffects {
|
||||
|
||||
// **************** End StaticAbility system **************************
|
||||
|
||||
// this is used to keep track of all state-based effects in play:
|
||||
private final HashMap<String, Integer> stateBasedMap = new HashMap<String, Integer>();
|
||||
|
||||
// this is used to define all cards that are state-based effects, and map
|
||||
// the
|
||||
// corresponding commands to their cardnames
|
||||
/** Constant <code>cardToEffectsList</code>. */
|
||||
private static HashMap<String, String[]> cardToEffectsList = new HashMap<String, String[]>();
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Constructor for StaticEffects.
|
||||
* </p>
|
||||
*/
|
||||
public StaticEffects(Game game) {
|
||||
this.game = game;
|
||||
this.initStateBasedEffectsList();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* initStateBasedEffectsList.
|
||||
* </p>
|
||||
*/
|
||||
public final void initStateBasedEffectsList() {
|
||||
// value has to be an array, since certain cards have multiple commands
|
||||
// associated with them
|
||||
StaticEffects.cardToEffectsList.put("Old Man of the Sea", new String[] { "Old_Man_of_the_Sea" });
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Getter for the field <code>cardToEffectsList</code>.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link java.util.HashMap} object.
|
||||
*/
|
||||
public final HashMap<String, String[]> getCardToEffectsList() {
|
||||
return StaticEffects.cardToEffectsList;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* addStateBasedEffect.
|
||||
* </p>
|
||||
*
|
||||
* @param s
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
public final void addStateBasedEffect(final String s) {
|
||||
if (this.stateBasedMap.containsKey(s)) {
|
||||
this.stateBasedMap.put(s, this.stateBasedMap.get(s) + 1);
|
||||
} else {
|
||||
this.stateBasedMap.put(s, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* removeStateBasedEffect.
|
||||
* </p>
|
||||
*
|
||||
* @param s
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
public final void removeStateBasedEffect(final String s) {
|
||||
if (this.stateBasedMap.containsKey(s)) {
|
||||
this.stateBasedMap.put(s, this.stateBasedMap.get(s) - 1);
|
||||
if (this.stateBasedMap.get(s) == 0) {
|
||||
this.stateBasedMap.remove(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Getter for the field <code>stateBasedMap</code>.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link java.util.HashMap} object.
|
||||
*/
|
||||
public final HashMap<String, Integer> getStateBasedMap() {
|
||||
return this.stateBasedMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* reset.
|
||||
* </p>
|
||||
*/
|
||||
public final void reset() {
|
||||
this.stateBasedMap.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* rePopulateStateBasedList.
|
||||
* </p>
|
||||
* @param game
|
||||
*/
|
||||
public final void rePopulateStateBasedList() {
|
||||
this.reset();
|
||||
|
||||
final List<Card> cards = game.getCardsIn(ZoneType.Battlefield);
|
||||
|
||||
Log.debug("== Start add state effects ==");
|
||||
for (Card c : cards) {
|
||||
if (StaticEffects.cardToEffectsList.containsKey(c.getName())) {
|
||||
final String[] effects = this.getCardToEffectsList().get(c.getName());
|
||||
for (final String effect : effects) {
|
||||
this.addStateBasedEffect(effect);
|
||||
Log.debug("Added " + effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.debug("== End add state effects ==");
|
||||
|
||||
}
|
||||
|
||||
} // end class StaticEffects
|
||||
|
||||
@@ -61,8 +61,8 @@ public class ControlGainEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
} // if
|
||||
host.clearGainControlTargets();
|
||||
host.clearGainControlReleaseCommands();
|
||||
host.removeGainControlTargets(c);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,12 +103,12 @@ public class ControlGainEffect extends SpellAbilityEffect {
|
||||
|
||||
for (Card tgtC : tgtCards) {
|
||||
|
||||
if (!tgtC.equals(sa.getSourceCard()) && !sa.getSourceCard().getGainControlTargets().contains(tgtC)) {
|
||||
sa.getSourceCard().addGainControlTarget(tgtC);
|
||||
if (!tgtC.isInPlay()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!tgtC.isInPlay()) {
|
||||
return;
|
||||
if (!tgtC.equals(sa.getSourceCard()) && !sa.getSourceCard().getGainControlTargets().contains(tgtC)) {
|
||||
sa.getSourceCard().addGainControlTarget(tgtC);
|
||||
}
|
||||
|
||||
long tStamp = game.getNextTimestamp();
|
||||
@@ -150,6 +150,12 @@ public class ControlGainEffect extends SpellAbilityEffect {
|
||||
game.getEndOfTurn().addUntil(this.getLoseControlCommand(tgtC, tStamp, bTapOnLose, source, kws));
|
||||
tgtC.setSVar("SacMe", "6");
|
||||
}
|
||||
if (lose.contains("StaticCommandCheck")) {
|
||||
String leftVar = sa.getSVar(sa.getParam("StaticCommandCheckSVar"));
|
||||
String rightVar = sa.getParam("StaticCommandSVarCompare");
|
||||
sa.getSourceCard().addStaticCommandList(new Object[]{leftVar, rightVar, tgtC,
|
||||
this.getLoseControlCommand(tgtC, tStamp, bTapOnLose, source, kws)});
|
||||
}
|
||||
}
|
||||
|
||||
if (destroyOn != null) {
|
||||
@@ -164,10 +170,7 @@ public class ControlGainEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
sa.getSourceCard().clearGainControlReleaseCommands();
|
||||
sa.getSourceCard().addGainControlReleaseCommand(this.getLoseControlCommand(tgtC, tStamp, bTapOnLose, source, kws));
|
||||
game.getAction().controllerChangeZoneCorrection(tgtC);
|
||||
tgtC.runChangeControllerCommands();
|
||||
|
||||
} // end foreach target
|
||||
}
|
||||
|
||||
@@ -234,11 +234,11 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
private Card cloneOrigin = null;
|
||||
private final List<Card> clones = new ArrayList<Card>();
|
||||
private final List<Card> gainControlTargets = new ArrayList<Card>();
|
||||
private final List<Command> gainControlReleaseCommands = new ArrayList<Command>();
|
||||
|
||||
private final List<AbilityTriggered> zcTriggers = new ArrayList<AbilityTriggered>();
|
||||
private final List<Command> untapCommandList = new ArrayList<Command>();
|
||||
private final List<Command> changeControllerCommandList = new ArrayList<Command>();
|
||||
private final List<Object[]> staticCommandList = new ArrayList<Object[]>();
|
||||
|
||||
private final static ImmutableList<String> storableSVars = ImmutableList.of("ChosenX");
|
||||
|
||||
@@ -1762,44 +1762,8 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
* <p/>
|
||||
* used primarily with AbilityFactory_GainControl
|
||||
*/
|
||||
public final void clearGainControlTargets() {
|
||||
this.gainControlTargets.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* get the commands to be executed to lose control of Cards this card has
|
||||
* gained control of.
|
||||
* <p/>
|
||||
* used primarily with AbilityFactory_GainControl (Old Man of the Sea
|
||||
* specifically)
|
||||
*
|
||||
* @return a {@link java.util.ArrayList} object.
|
||||
*/
|
||||
public final List<Command> getGainControlReleaseCommands() {
|
||||
return this.gainControlReleaseCommands;
|
||||
}
|
||||
|
||||
/**
|
||||
* set a command to be executed to lose control of Cards this card has
|
||||
* gained control of.
|
||||
* <p/>
|
||||
* used primarily with AbilityFactory_GainControl (Old Man of the Sea
|
||||
* specifically)
|
||||
*
|
||||
* @param c
|
||||
* the Command to be executed
|
||||
*/
|
||||
public final void addGainControlReleaseCommand(final Command c) {
|
||||
this.gainControlReleaseCommands.add(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* clearGainControlReleaseCommands.
|
||||
* </p>
|
||||
*/
|
||||
public final void clearGainControlReleaseCommands() {
|
||||
this.gainControlReleaseCommands.clear();
|
||||
public final void removeGainControlTargets(final Card c) {
|
||||
this.gainControlTargets.remove(c);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8703,9 +8667,19 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
* @param pc
|
||||
*/
|
||||
public static void updateCard(PaperCard pc) {
|
||||
Card res = cp2card.get(pc);
|
||||
Card res = cp2card.get(pc);
|
||||
if (res != null) {
|
||||
cp2card.put(pc, fromPaperCard(pc, null));
|
||||
cp2card.put(pc, fromPaperCard(pc, null));
|
||||
}
|
||||
}
|
||||
|
||||
/** return staticCommanderList */
|
||||
public List<Object[]> getStaticCommandList() {
|
||||
return staticCommandList;
|
||||
}
|
||||
|
||||
/** return staticCommanderList */
|
||||
public void addStaticCommandList(Object[] objects) {
|
||||
this.staticCommandList.add(objects);
|
||||
}
|
||||
} // end Card class
|
||||
|
||||
@@ -54,7 +54,6 @@ public class EndOfTurn extends Phase {
|
||||
public final void executeAt() {
|
||||
// reset mustAttackEntity for me
|
||||
game.getPhaseHandler().getPlayerTurn().setMustAttackEntity(null);
|
||||
game.getStaticEffects().rePopulateStateBasedList();
|
||||
|
||||
for (final Card c : game.getCardsIn(ZoneType.Battlefield)) {
|
||||
if (!c.isFaceDown() && c.hasKeyword("At the beginning of the end step, sacrifice CARDNAME.")) {
|
||||
|
||||
@@ -19,13 +19,10 @@ package forge.game.zone;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.game.GameActionUtil;
|
||||
import forge.game.Game;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
@@ -82,28 +79,8 @@ public class PlayerZoneBattlefield extends PlayerZone {
|
||||
c.setSickness(true); // summoning sickness
|
||||
c.executeTrigger(ZCTrigger.ENTERFIELD);
|
||||
|
||||
/*if (c.isLand()) {
|
||||
|
||||
|
||||
for( Player opp : c.getOwner().getOpponents())
|
||||
for( Card le : opp.getCardsIn(ZoneType.Battlefield, "Land Equilibrium") ) {
|
||||
final List<Card> pLands = c.getOwner().getLandsInPlay();
|
||||
final List<Card> oLands = opp.getLandsInPlay();
|
||||
|
||||
if (oLands.size() <= (pLands.size() - 1)) {
|
||||
SpellAbility abSac = AbilityFactory.getAbility(le.getSVar("SacLand"), le);
|
||||
game.getStack().addSimultaneousStackEntry(abSac);
|
||||
}
|
||||
}
|
||||
} // isLand()*/
|
||||
}
|
||||
|
||||
if (game.getStaticEffects().getCardToEffectsList().containsKey(c.getName())) {
|
||||
final String[] effects = game.getStaticEffects().getCardToEffectsList().get(c.getName());
|
||||
for (final String effect : effects) {
|
||||
game.getStaticEffects().addStateBasedEffect(effect);
|
||||
}
|
||||
}
|
||||
} // end add()
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@@ -115,17 +92,6 @@ public class PlayerZoneBattlefield extends PlayerZone {
|
||||
c.executeTrigger(ZCTrigger.LEAVEFIELD);
|
||||
}
|
||||
|
||||
if (game.getStaticEffects().getCardToEffectsList().containsKey(c.getName())) {
|
||||
final String[] effects = game.getStaticEffects().getCardToEffectsList().get(c.getName());
|
||||
String tempEffect = "";
|
||||
for (final String effect : effects) {
|
||||
tempEffect = effect;
|
||||
game.getStaticEffects().removeStateBasedEffect(effect);
|
||||
// this is to make sure cards reset correctly
|
||||
final Function<Game, ?> comm = GameActionUtil.getCommands().get(tempEffect);
|
||||
comm.apply(game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user