mirror of
https://github.com/correl/mage.git
synced 2025-01-13 19:11:33 +00:00
Merge branch 'master' of https://github.com/magefree/mage
This commit is contained in:
commit
93ba2c4c9f
16 changed files with 276 additions and 72 deletions
|
@ -1,14 +1,7 @@
|
|||
|
||||
package mage.view;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.cards.Card;
|
||||
|
@ -32,8 +25,10 @@ import mage.players.Player;
|
|||
import mage.watchers.common.CastSpellLastTurnWatcher;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class GameView implements Serializable {
|
||||
|
@ -90,7 +85,7 @@ public class GameView implements Serializable {
|
|||
if (object != null) {
|
||||
if (object instanceof Permanent) {
|
||||
boolean controlled = ((Permanent) object).getControllerId().equals(createdForPlayerId);
|
||||
stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, ((Permanent) object).getName(), new CardView(((Permanent) object), game, controlled, false, false)));
|
||||
stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, object.getName(), new CardView(((Permanent) object), game, controlled, false, false)));
|
||||
} else {
|
||||
stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, card.getName(), new CardView(card, game, false, false, false)));
|
||||
}
|
||||
|
@ -109,14 +104,14 @@ public class GameView implements Serializable {
|
|||
} else if (object instanceof Emblem) {
|
||||
CardView cardView = new CardView(new EmblemView((Emblem) object));
|
||||
// Card sourceCard = (Card) ((Emblem) object).getSourceObject();
|
||||
((StackAbility) stackObject).setName(((Emblem) object).getName());
|
||||
stackObject.setName(object.getName());
|
||||
// ((StackAbility) stackObject).setExpansionSetCode(sourceCard.getExpansionSetCode());
|
||||
stack.put(stackObject.getId(),
|
||||
new StackAbilityView(game, (StackAbility) stackObject, object.getName(), cardView));
|
||||
checkPaid(stackObject.getId(), ((StackAbility) stackObject));
|
||||
} else if (object instanceof Plane) {
|
||||
CardView cardView = new CardView(new PlaneView((Plane) object));
|
||||
((StackAbility) stackObject).setName(((Plane) object).getName());
|
||||
stackObject.setName(object.getName());
|
||||
stack.put(stackObject.getId(),
|
||||
new StackAbilityView(game, (StackAbility) stackObject, object.getName(), cardView));
|
||||
checkPaid(stackObject.getId(), ((StackAbility) stackObject));
|
||||
|
@ -131,7 +126,7 @@ public class GameView implements Serializable {
|
|||
} else if (object instanceof StackAbility) {
|
||||
StackAbility stackAbility = ((StackAbility) object);
|
||||
stackAbility.newId();
|
||||
stack.put(stackObject.getId(), new CardView(((StackAbility) stackObject)));
|
||||
stack.put(stackObject.getId(), new CardView(stackObject));
|
||||
checkPaid(stackObject.getId(), ((StackAbility) stackObject));
|
||||
} else {
|
||||
LOGGER.fatal("Object can't be cast to StackAbility: " + object.getName() + ' ' + object.toString() + ' ' + object.getClass().toString());
|
||||
|
@ -182,7 +177,7 @@ public class GameView implements Serializable {
|
|||
this.special = false;
|
||||
}
|
||||
|
||||
CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName());
|
||||
CastSpellLastTurnWatcher watcher = game.getState().getWatcher(CastSpellLastTurnWatcher.class);
|
||||
if (watcher != null) {
|
||||
spellsCastCurrentTurn = watcher.getAmountOfSpellsAllPlayersCastOnCurrentTurn();
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import mage.MageObject;
|
||||
|
@ -92,8 +91,7 @@ class AbeyanceEffect extends ContinuousRuleModifyingEffectImpl {
|
|||
}
|
||||
if (event.getType() == GameEvent.EventType.ACTIVATE_ABILITY) {
|
||||
Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId());
|
||||
return ability != null && ability.isPresent()
|
||||
&& !(ability.get() instanceof ActivatedManaAbilityImpl);
|
||||
return ability.isPresent() && !(ability.get() instanceof ActivatedManaAbilityImpl);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import mage.constants.Zone;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -62,9 +63,9 @@ class AngrathsMaraudersEffect extends ReplacementEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean checksEventType(GameEvent event, Game game) {
|
||||
return event.getType().equals(EventType.DAMAGED_PLAYER)
|
||||
|| event.getType().equals(EventType.DAMAGED_CREATURE)
|
||||
|| event.getType().equals(EventType.DAMAGED_PLANESWALKER);
|
||||
return event.getType().equals(EventType.DAMAGE_PLAYER)
|
||||
|| event.getType().equals(EventType.DAMAGE_CREATURE)
|
||||
|| event.getType().equals(EventType.DAMAGE_PLANESWALKER);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -74,7 +75,7 @@ class AngrathsMaraudersEffect extends ReplacementEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
event.setAmount(event.getAmount() * 2);
|
||||
event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
53
Mage.Sets/src/mage/cards/a/ArchwayAngel.java
Normal file
53
Mage.Sets/src/mage/cards/a/ArchwayAngel.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public final class ArchwayAngel extends CardImpl {
|
||||
|
||||
|
||||
private static final FilterPermanent filter = new FilterControlledPermanent("Gate you control");
|
||||
|
||||
static {
|
||||
filter.add(new SubtypePredicate(SubType.GATE));
|
||||
}
|
||||
|
||||
public ArchwayAngel(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}");
|
||||
this.subtype.add(SubType.ANGEL);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// When Archway Angel enters the battlefield, you gain 2 life for each Gate you control.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new GainLifeEffect(new PermanentsOnBattlefieldCount(filter, 2)));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
public ArchwayAngel(final ArchwayAngel card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArchwayAngel copy() {
|
||||
return new ArchwayAngel(this);
|
||||
}
|
||||
}
|
54
Mage.Sets/src/mage/cards/c/CultGuildmage.java
Normal file
54
Mage.Sets/src/mage/cards/c/CultGuildmage.java
Normal file
|
@ -0,0 +1,54 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.effects.common.discard.DiscardTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.target.TargetPlayer;
|
||||
import mage.target.common.TargetOpponentOrPlaneswalker;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public final class CultGuildmage extends CardImpl {
|
||||
|
||||
public CultGuildmage(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{R}");
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.SHAMAN);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
// {3}{B}, {T}: Target player discards a card. Activate this ability only any time you could cast a sorcery.
|
||||
Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new DiscardTargetEffect(1), new ManaCostsImpl("{3}{B}"));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addTarget(new TargetPlayer());
|
||||
this.addAbility(ability);
|
||||
|
||||
// {R}, {T}: Cult Guildmage deals 1 damage to target opponent or planeswalker.
|
||||
ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{R}"));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addTarget(new TargetOpponentOrPlaneswalker());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
public CultGuildmage(final CultGuildmage card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CultGuildmage copy() {
|
||||
return new CultGuildmage(this);
|
||||
}
|
||||
}
|
|
@ -60,7 +60,7 @@ class KayasWrathEffect extends OneShotEffect {
|
|||
source.getControllerId(), source.getSourceId(), game
|
||||
)) {
|
||||
boolean isMine = permanent != null && permanent.getControllerId().equals(source.getControllerId());
|
||||
if (permanent.destroy(source.getSourceId(), game, false) && isMine) {
|
||||
if (isMine && permanent.destroy(source.getSourceId(), game, false)) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
package mage.cards.s;
|
||||
|
||||
import mage.MageInt;
|
||||
|
@ -34,6 +32,7 @@ public final class SamuraiOfThePaleCurtain extends CardImpl {
|
|||
|
||||
// Bushido 1 (When this blocks or becomes blocked, it gets +1/+1 until end of turn.)
|
||||
this.addAbility(new BushidoAbility(1));
|
||||
|
||||
// If a permanent would be put into a graveyard, exile it instead.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SamuraiOfThePaleCurtainEffect()));
|
||||
}
|
||||
|
@ -71,7 +70,7 @@ class SamuraiOfThePaleCurtainEffect extends ReplacementEffectImpl {
|
|||
Permanent permanent = ((ZoneChangeEvent) event).getTarget();
|
||||
if (permanent != null) {
|
||||
Player player = game.getPlayer(permanent.getControllerId());
|
||||
if (player == null) {
|
||||
if (player != null) {
|
||||
return player.moveCards(permanent, Zone.EXILED, source, game);
|
||||
}
|
||||
}
|
||||
|
|
49
Mage.Sets/src/mage/cards/s/SenateGuildmage.java
Normal file
49
Mage.Sets/src/mage/cards/s/SenateGuildmage.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.DrawDiscardControllerEffect;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public final class SenateGuildmage extends CardImpl {
|
||||
|
||||
public SenateGuildmage(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{U}");
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.WIZARD);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
// {W}, {T}: You gain 2 life.
|
||||
Ability ability1 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(2), new ManaCostsImpl<>("{W}"));
|
||||
ability1.addCost(new TapSourceCost());
|
||||
this.addAbility(ability1);
|
||||
|
||||
// {U}, {T}: Draw a card, then discard a card.
|
||||
Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawDiscardControllerEffect(), new ManaCostsImpl("{U}"));
|
||||
ability2.addCost(new TapSourceCost());
|
||||
this.addAbility(ability2);
|
||||
}
|
||||
|
||||
public SenateGuildmage(final SenateGuildmage card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SenateGuildmage copy() {
|
||||
return new SenateGuildmage(this);
|
||||
}
|
||||
}
|
47
Mage.Sets/src/mage/cards/w/WarrantWarden.java
Normal file
47
Mage.Sets/src/mage/cards/w/WarrantWarden.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
package mage.cards.w;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.VigilanceAbility;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.game.permanent.token.custom.CreatureToken;
|
||||
import mage.target.common.TargetAttackingOrBlockingCreature;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public final class WarrantWarden extends SplitCard {
|
||||
|
||||
public WarrantWarden(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, new CardType[]{CardType.SORCERY}, "{W/U}{W/U}", "{3}{W}{U}", SpellAbilityType.SPLIT);
|
||||
|
||||
// Warrant
|
||||
// Put target attacking or blocking creature on top of its owner’s library.
|
||||
this.getLeftHalfCard().getSpellAbility().addEffect(new PutOnLibraryTargetEffect(true));
|
||||
this.getLeftHalfCard().getSpellAbility().addTarget(new TargetAttackingOrBlockingCreature());
|
||||
|
||||
// Warden
|
||||
// Create a 4/4 white and blue Sphinx creature token with flying and vigilance.
|
||||
this.getRightHalfCard().getSpellAbility().addEffect(new CreateTokenEffect(
|
||||
new CreatureToken(4, 4, "4/4 white and blue Sphinx creature token with flying and vigilance")
|
||||
.withColor("WU")
|
||||
.withAbility(FlyingAbility.getInstance())
|
||||
.withAbility(VigilanceAbility.getInstance())
|
||||
));
|
||||
}
|
||||
|
||||
private WarrantWarden(final WarrantWarden card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WarrantWarden copy() {
|
||||
return new WarrantWarden(this);
|
||||
}
|
||||
}
|
|
@ -123,6 +123,7 @@ public final class GuildsOfRavnicaGuildKits extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Selesnya Guildmage", 119, Rarity.UNCOMMON, mage.cards.s.SelesnyaGuildmage.class));
|
||||
cards.add(new SetCardInfo("Selesnya Sanctuary", 125, Rarity.COMMON, mage.cards.s.SelesnyaSanctuary.class));
|
||||
cards.add(new SetCardInfo("Selesnya Signet", 123, Rarity.COMMON, mage.cards.s.SelesnyaSignet.class));
|
||||
cards.add(new SetCardInfo("Senate Guildmage", 204, Rarity.UNCOMMON, mage.cards.s.SenateGuildmage.class));
|
||||
cards.add(new SetCardInfo("Shambling Shell", 70, Rarity.COMMON, mage.cards.s.ShamblingShell.class));
|
||||
cards.add(new SetCardInfo("Shattering Spree", 34, Rarity.UNCOMMON, mage.cards.s.ShatteringSpree.class));
|
||||
cards.add(new SetCardInfo("Sisters of Stone Death", 71, Rarity.RARE, mage.cards.s.SistersOfStoneDeath.class));
|
||||
|
|
|
@ -36,6 +36,7 @@ public final class RavnicaAllegiance extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Aeromunculus", 152, Rarity.COMMON, mage.cards.a.Aeromunculus.class));
|
||||
cards.add(new SetCardInfo("Amplifire", 92, Rarity.RARE, mage.cards.a.Amplifire.class));
|
||||
cards.add(new SetCardInfo("Angelic Exaltation", 2, Rarity.UNCOMMON, mage.cards.a.AngelicExaltation.class));
|
||||
cards.add(new SetCardInfo("Archway Angel", 3, Rarity.UNCOMMON, mage.cards.a.ArchwayAngel.class));
|
||||
cards.add(new SetCardInfo("Azorius Guildgate", 243, Rarity.COMMON, mage.cards.a.AzoriusGuildgate.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Azorius Guildgate", 244, Rarity.COMMON, mage.cards.a.AzoriusGuildgate.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Azorius Locket", 231, Rarity.COMMON, mage.cards.a.AzoriusLocket.class));
|
||||
|
@ -54,6 +55,7 @@ public final class RavnicaAllegiance extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Combine Guildmage", 163, Rarity.UNCOMMON, mage.cards.c.CombineGuildmage.class));
|
||||
cards.add(new SetCardInfo("Consecrate // Consume", 224, Rarity.UNCOMMON, mage.cards.c.ConsecrateConsume.class));
|
||||
cards.add(new SetCardInfo("Cry of the Carnarium", 70, Rarity.UNCOMMON, mage.cards.c.CryOfTheCarnarium.class));
|
||||
cards.add(new SetCardInfo("Cult Guildmage", 164, Rarity.UNCOMMON, mage.cards.c.CultGuildmage.class));
|
||||
cards.add(new SetCardInfo("Depose // Deploy", 225, Rarity.UNCOMMON, mage.cards.d.DeposeDeploy.class));
|
||||
cards.add(new SetCardInfo("Deputy of Detention", 165, Rarity.RARE, mage.cards.d.DeputyOfDetention.class));
|
||||
cards.add(new SetCardInfo("Domri, Chaos Bringer", 166, Rarity.MYTHIC, mage.cards.d.DomriChaosBringer.class));
|
||||
|
@ -137,6 +139,7 @@ public final class RavnicaAllegiance extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Tithe Taker", 27, Rarity.RARE, mage.cards.t.TitheTaker.class));
|
||||
cards.add(new SetCardInfo("Trollbred Guardian", 148, Rarity.UNCOMMON, mage.cards.t.TrollbredGuardian.class));
|
||||
cards.add(new SetCardInfo("Verity Circle", 58, Rarity.RARE, mage.cards.v.VerityCircle.class));
|
||||
cards.add(new SetCardInfo("Warrant // Warden", 230, Rarity.RARE, mage.cards.w.WarrantWarden.class));
|
||||
cards.add(new SetCardInfo("Wilderness Reclamation", 149, Rarity.UNCOMMON, mage.cards.w.WildernessReclamation.class));
|
||||
cards.add(new SetCardInfo("Zegana, Utopian Speaker", 214, Rarity.RARE, mage.cards.z.ZeganaUtopianSpeaker.class));
|
||||
cards.add(new SetCardInfo("Zhur-Taa Goblin", 215, Rarity.UNCOMMON, mage.cards.z.ZhurTaaGoblin.class));
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package mage.game;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import mage.MageException;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.*;
|
||||
|
@ -65,10 +61,14 @@ import mage.util.GameLog;
|
|||
import mage.util.MessageToClient;
|
||||
import mage.util.RandomUtil;
|
||||
import mage.util.functions.ApplyToPermanent;
|
||||
import mage.watchers.Watchers;
|
||||
import mage.watchers.common.*;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public abstract class GameImpl implements Game, Serializable {
|
||||
|
||||
private static final int ROLLBACK_TURNS_MAX = 4;
|
||||
|
@ -150,6 +150,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
this.state = new GameState();
|
||||
this.startLife = startLife;
|
||||
this.executingRollback = false;
|
||||
initGameDefaultWatchers();
|
||||
}
|
||||
|
||||
public GameImpl(final GameImpl game) {
|
||||
|
@ -259,6 +260,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
public void addPlayer(Player player, Deck deck) {
|
||||
player.useDeck(deck, this);
|
||||
state.addPlayer(player);
|
||||
initPlayerDefaultWatchers(player.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -504,7 +506,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
return Optional.empty();
|
||||
}
|
||||
|
||||
// @Override
|
||||
// @Override
|
||||
// public Zone getZone(UUID objectId) {
|
||||
// return state.getZone(objectId);
|
||||
// }
|
||||
|
@ -532,7 +534,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// /**
|
||||
// * Starts check if game is over or if playerId is given let the player
|
||||
// * concede.
|
||||
// *
|
||||
|
@ -1012,20 +1014,6 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
}
|
||||
getState().setChoosingPlayerId(null);
|
||||
state.resetWatchers(); // watcher objects from cards are reused during match so reset all card watchers already added
|
||||
// add default watchers
|
||||
for (UUID playerId : state.getPlayerList(startingPlayerId)) {
|
||||
getState().addWatcher(new PlayerDamagedBySourceWatcher(playerId));
|
||||
getState().addWatcher(new BloodthirstWatcher(playerId));
|
||||
}
|
||||
getState().addWatcher(new MorbidWatcher());
|
||||
getState().addWatcher(new CastSpellLastTurnWatcher());
|
||||
getState().addWatcher(new CastSpellYourLastTurnWatcher());
|
||||
getState().addWatcher(new PlayerLostLifeWatcher());
|
||||
getState().addWatcher(new PlayerLostLifeNonCombatWatcher());
|
||||
getState().addWatcher(new BlockedAttackerWatcher());
|
||||
getState().addWatcher(new DamageDoneWatcher());
|
||||
getState().addWatcher(new PlanarRollWatcher());
|
||||
getState().addWatcher(new PlayersAttackedThisTurnWatcher());
|
||||
|
||||
//20100716 - 103.5
|
||||
for (UUID playerId : state.getPlayerList(startingPlayerId)) {
|
||||
|
@ -1074,6 +1062,24 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void initGameDefaultWatchers() {
|
||||
getState().addWatcher(new MorbidWatcher());
|
||||
getState().addWatcher(new CastSpellLastTurnWatcher());
|
||||
getState().addWatcher(new CastSpellYourLastTurnWatcher());
|
||||
getState().addWatcher(new PlayerLostLifeWatcher());
|
||||
getState().addWatcher(new PlayerLostLifeNonCombatWatcher());
|
||||
getState().addWatcher(new BlockedAttackerWatcher());
|
||||
getState().addWatcher(new DamageDoneWatcher());
|
||||
getState().addWatcher(new PlanarRollWatcher());
|
||||
getState().addWatcher(new PlayersAttackedThisTurnWatcher());
|
||||
}
|
||||
|
||||
private void initPlayerDefaultWatchers(UUID playerId) {
|
||||
getState().addWatcher(new PlayerDamagedBySourceWatcher(playerId));
|
||||
getState().addWatcher(new BloodthirstWatcher(playerId));
|
||||
}
|
||||
|
||||
protected void sendStartMessage(Player choosingPlayer, Player startingPlayer) {
|
||||
StringBuilder message = new StringBuilder();
|
||||
if (choosingPlayer != null) {
|
||||
|
@ -1205,7 +1211,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
fireInformEvent(new StringBuilder(player.getLogName())
|
||||
.append(" mulligans")
|
||||
.append(deduction == 0 ? " for free and draws " : " down to ")
|
||||
.append(Integer.toString(numCards - deduction))
|
||||
.append((numCards - deduction))
|
||||
.append(numCards - deduction == 1 ? " card" : " cards").toString());
|
||||
player.drawCards(numCards - deduction, this);
|
||||
}
|
||||
|
@ -1542,10 +1548,9 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param emblem
|
||||
* @param sourceObject
|
||||
* @param toPlayerId controller and owner of the emblem
|
||||
* @param toPlayerId controller and owner of the emblem
|
||||
*/
|
||||
@Override
|
||||
public void addEmblem(Emblem emblem, MageObject sourceObject, UUID toPlayerId) {
|
||||
|
@ -1561,11 +1566,10 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param plane
|
||||
* @param sourceObject
|
||||
* @param toPlayerId controller and owner of the plane (may only be one per
|
||||
* game..)
|
||||
* @param toPlayerId controller and owner of the plane (may only be one per
|
||||
* game..)
|
||||
* @return boolean - whether the plane was added successfully or not
|
||||
*/
|
||||
@Override
|
||||
|
@ -1794,7 +1798,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
break;
|
||||
}
|
||||
// triggered abilities that don't use the stack have to be executed first (e.g. Banisher Priest Return exiled creature
|
||||
for (Iterator<TriggeredAbility> it = abilities.iterator(); it.hasNext();) {
|
||||
for (Iterator<TriggeredAbility> it = abilities.iterator(); it.hasNext(); ) {
|
||||
TriggeredAbility triggeredAbility = it.next();
|
||||
if (!triggeredAbility.isUsesStack()) {
|
||||
state.removeTriggeredAbility(triggeredAbility);
|
||||
|
@ -1979,7 +1983,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
if ((ability instanceof SpellAbility)
|
||||
&& SpellAbilityType.BASE_ALTERNATE == ((SpellAbility) ability).getSpellAbilityType()
|
||||
&& !ability.getTargets().isEmpty()) {
|
||||
spellAbility = (SpellAbility) ability;
|
||||
spellAbility = ability;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2529,7 +2533,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
}
|
||||
//20100423 - 800.4a
|
||||
Set<Card> toOutside = new HashSet<>();
|
||||
for (Iterator<Permanent> it = getBattlefield().getAllPermanents().iterator(); it.hasNext();) {
|
||||
for (Iterator<Permanent> it = getBattlefield().getAllPermanents().iterator(); it.hasNext(); ) {
|
||||
Permanent perm = it.next();
|
||||
if (perm.isOwnedBy(playerId)) {
|
||||
if (perm.getAttachedTo() != null) {
|
||||
|
@ -2572,7 +2576,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
player.moveCards(toOutside, Zone.OUTSIDE, null, this);
|
||||
// triggered abilities that don't use the stack have to be executed
|
||||
List<TriggeredAbility> abilities = state.getTriggered(player.getId());
|
||||
for (Iterator<TriggeredAbility> it = abilities.iterator(); it.hasNext();) {
|
||||
for (Iterator<TriggeredAbility> it = abilities.iterator(); it.hasNext(); ) {
|
||||
TriggeredAbility triggeredAbility = it.next();
|
||||
if (!triggeredAbility.isUsesStack()) {
|
||||
state.removeTriggeredAbility(triggeredAbility);
|
||||
|
@ -2592,7 +2596,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
|
||||
// Remove cards from the player in all exile zones
|
||||
for (ExileZone exile : this.getExile().getExileZones()) {
|
||||
for (Iterator<UUID> it = exile.iterator(); it.hasNext();) {
|
||||
for (Iterator<UUID> it = exile.iterator(); it.hasNext(); ) {
|
||||
Card card = this.getCard(it.next());
|
||||
if (card != null && card.isOwnedBy(playerId)) {
|
||||
it.remove();
|
||||
|
@ -2602,7 +2606,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
|
||||
//Remove all commander/emblems/plane the player controls
|
||||
boolean addPlaneAgain = false;
|
||||
for (Iterator<CommandObject> it = this.getState().getCommand().iterator(); it.hasNext();) {
|
||||
for (Iterator<CommandObject> it = this.getState().getCommand().iterator(); it.hasNext(); ) {
|
||||
CommandObject obj = it.next();
|
||||
if (obj.isControlledBy(playerId)) {
|
||||
if (obj instanceof Emblem) {
|
||||
|
@ -2738,7 +2742,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
}
|
||||
if (!game.isSimulation()) {
|
||||
StringBuilder message = new StringBuilder(preventionSource.getLogName()).append(": Prevented ");
|
||||
message.append(Integer.toString(result.getPreventedDamage())).append(" damage from ").append(damageSource.getLogName());
|
||||
message.append(result.getPreventedDamage()).append(" damage from ").append(damageSource.getLogName());
|
||||
if (!targetName.isEmpty()) {
|
||||
message.append(" to ").append(targetName);
|
||||
}
|
||||
|
@ -2773,7 +2777,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
* Gets last known information about object in the zone. At the moment
|
||||
* doesn't take into account zone (it is expected that it doesn't really
|
||||
* matter, if not, then Map<UUID, Map<Zone, Card>> should be used instead).
|
||||
*
|
||||
* <p>
|
||||
* Can return null.
|
||||
*
|
||||
* @param objectId
|
||||
|
@ -3128,7 +3132,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
public void saveRollBackGameState() {
|
||||
if (gameOptions.rollbackTurnsAllowed) {
|
||||
int toDelete = getTurnNum() - ROLLBACK_TURNS_MAX;
|
||||
if (toDelete > 0 && gameStatesRollBack.containsKey(toDelete)) {
|
||||
if (toDelete > 0) {
|
||||
gameStatesRollBack.remove(toDelete);
|
||||
}
|
||||
gameStatesRollBack.put(getTurnNum(), state.copy());
|
||||
|
@ -3180,9 +3184,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
@Override
|
||||
public void setEnterWithCounters(UUID sourceId, Counters counters) {
|
||||
if (counters == null) {
|
||||
if (enterWithCounters.containsKey(sourceId)) {
|
||||
enterWithCounters.remove(sourceId);
|
||||
}
|
||||
enterWithCounters.remove(sourceId);
|
||||
return;
|
||||
}
|
||||
enterWithCounters.put(sourceId, counters);
|
||||
|
|
|
@ -298,8 +298,8 @@ public class Table implements Serializable {
|
|||
.setGameType(this.getGameType())
|
||||
.setDeckType(this.getDeckType())
|
||||
.setControllerName(this.getControllerName())
|
||||
.setStartTimeMs(this.getStartTime().getTime())
|
||||
.setEndTimeMs(this.getEndTime().getTime())
|
||||
.setStartTimeMs(this.getStartTime() != null ? this.getStartTime().getTime() : 0L)
|
||||
.setEndTimeMs(this.getEndTime() != null ? this.getEndTime().getTime() : 0L)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package mage.util;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.net.URL;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
|
@ -19,6 +20,7 @@ public class JarVersion {
|
|||
|
||||
public static String getBuildTime(Class clazz) {
|
||||
// build time info inserted by maven on jar build phase (see root pom.xml)
|
||||
String resultFormat = "uuuu-MM-dd HH:mm";
|
||||
String className = clazz.getSimpleName() + ".class";
|
||||
String classPath = clazz.getResource(className).toString();
|
||||
|
||||
|
@ -38,10 +40,11 @@ public class JarVersion {
|
|||
Manifest manifest = new Manifest(new URL(manifestPath).openStream());
|
||||
Attributes attr = manifest.getMainAttributes();
|
||||
String buildTime = attr.getValue("Build-Time");
|
||||
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("uuuuMMdd-HHmm").withZone(ZoneOffset.UTC);
|
||||
// default maven format: yyyy-MM-dd'T'HH:mm:ss'Z' or see maven.build.timestamp.format in pom file
|
||||
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss'Z'").withZone(ZoneOffset.UTC);
|
||||
TemporalAccessor ta = sourceFormatter.parse(buildTime);
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm").withZone(ZoneOffset.UTC);
|
||||
return formatter.format(ta);
|
||||
DateTimeFormatter resultFormatter = DateTimeFormatter.ofPattern(resultFormat).withZone(ZoneOffset.UTC);
|
||||
return resultFormatter.format(ta);
|
||||
} catch (Throwable e) {
|
||||
logger.error("Can't read build time in jar manifest for class " + clazz.getName() + " and path " + manifestPath, e);
|
||||
return JAR_BUILD_TIME_ERROR;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.watchers;
|
||||
|
||||
import mage.game.Game;
|
||||
|
@ -7,7 +6,6 @@ import org.apache.log4j.LogManager;
|
|||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
@ -50,7 +48,7 @@ public class Watchers extends HashMap<String, Watcher> {
|
|||
if (containsKey(key)) {
|
||||
return super.get(key);
|
||||
}
|
||||
logger.info(key + " not found in watchers");
|
||||
logger.error(key + " not found in watchers", new Throwable());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
1
pom.xml
1
pom.xml
|
@ -90,6 +90,7 @@
|
|||
<properties>
|
||||
<mage-version>1.4.32</mage-version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'</maven.build.timestamp.format>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
|
|
Loading…
Reference in a new issue