- Converted Old Man of the Sea

- Added Rootwater Matriarch
This commit is contained in:
swordshine
2014-01-09 13:46:14 +00:00
parent 561d4deb32
commit f10ec1751f
11 changed files with 75 additions and 261 deletions

1
.gitattributes vendored
View File

@@ -9593,6 +9593,7 @@ forge-gui/res/cardsfolder/r/rootwater_commando.txt svneol=native#text/plain
forge-gui/res/cardsfolder/r/rootwater_depths.txt svneol=native#text/plain
forge-gui/res/cardsfolder/r/rootwater_diver.txt svneol=native#text/plain
forge-gui/res/cardsfolder/r/rootwater_hunter.txt svneol=native#text/plain
forge-gui/res/cardsfolder/r/rootwater_matriarch.txt -text
forge-gui/res/cardsfolder/r/rootwater_mystic.txt svneol=native#text/plain
forge-gui/res/cardsfolder/r/rootwater_shaman.txt -text
forge-gui/res/cardsfolder/r/rootwater_thief.txt svneol=native#text/plain

View File

@@ -3,7 +3,9 @@ ManaCost:1 U U
Types:Creature Djinn
PT:2/3
K:You may choose not to untap CARDNAME during your untap step.
A:AB$ GainControl | Cost$ T | ValidTgts$ Creature.powerLEX | References$ X | TgtPrompt$ Select target creature with power less than or equal to Old Man's. | LoseControl$ Untap,LeavesPlay,LoseControl | SpellDescription$ Gain control of target creature with power less than or equal to Old Man of the Sea's power for as long as Old Man of the Sea remains tapped and that creature's power remains less than or equal to Old Man of the Sea's power.
A:AB$ GainControl | Cost$ T | ValidTgts$ Creature.powerLEX | TgtPrompt$ Select target creature with power less than or equal to Old Man's. | LoseControl$ Untap,LeavesPlay,LoseControl,StaticCommandCheck | StaticCommandCheckSVar$ Y | StaticCommandSVarCompare$ GTX | References$ X,Y | SpellDescription$ Gain control of target creature with power less than or equal to Old Man of the Sea's power for as long as Old Man of the Sea remains tapped and that creature's power remains less than or equal to Old Man of the Sea's power.
SVar:X:Count$CardPower
# the hostcard of SVar Y is the controlled card
SVar:Y:Count$CardPower
SVar:Picture:http://www.wizards.com/global/images/magic/general/old_man_of_the_sea.jpg
Oracle:You may choose not to untap Old Man of the Sea during your untap step.\n{T}: Gain control of target creature with power less than or equal to Old Man of the Sea's power for as long as Old Man of the Sea remains tapped and that creature's power remains less than or equal to Old Man of the Sea's power.

View File

@@ -0,0 +1,11 @@
Name:Rootwater Matriarch
ManaCost:2 U U
Types:Creature Merfolk
PT:2/3
A:AB$ GainControl | Cost$ T | ValidTgts$ Creature | References$ X,Y | AITgts$ Creature.enchanted | LoseControl$ StaticCommandCheck | StaticCommandCheckSVar$ X | StaticCommandSVarCompare$ EQ0 | ConditionCheckSVar$ Y | ContionSVarCompare$ GE1 | SpellDescription$ Gain control of target creature for as long as that creature is enchanted.
# the hostcard of SVar X is the controlled card
SVar:X:Count$Valid Card.Self+enchanted
SVar:Y:Targeted$Valid Card.enchanted
SVar:RemRandomDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/rootwater_matriarch.jpg
Oracle:{T}: Gain control of target creature for as long as that creature is enchanted.

View File

@@ -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");

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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>
@@ -49,8 +46,6 @@ public class StaticEffects {
//Global rule changes
private final EnumSet<GlobalRuleChange> ruleChanges = EnumSet.noneOf(GlobalRuleChange.class);
private final Game game;
public final Set<Card> clearStaticEffects() {
ruleChanges.clear();
Set<Card> clearedCards = new HashSet<Card>();
@@ -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

View File

@@ -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
}

View File

@@ -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);
}
/**
@@ -8708,4 +8672,14 @@ public class Card extends GameEntity implements Comparable<Card> {
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

View File

@@ -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.")) {

View File

@@ -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);
}
}
}