try to prevent constructing Strings during simulations

This commit is contained in:
betasteward 2015-01-22 22:01:24 -05:00
parent 74255eb808
commit a0085673be
65 changed files with 372 additions and 241 deletions

View file

@ -296,6 +296,7 @@ public abstract class AbilityImpl implements Ability {
} }
if (getTargets().size() > 0 && getTargets().chooseTargets(getEffects().get(0).getOutcome(), this.controllerId, this, game) == false) { if (getTargets().size() > 0 && getTargets().chooseTargets(getEffects().get(0).getOutcome(), this.controllerId, this, game) == false) {
if (variableManaCost != null || announceString != null) { if (variableManaCost != null || announceString != null) {
if (!game.isSimulation())
game.informPlayer(controller, new StringBuilder(sourceObject != null ? sourceObject.getLogName(): "").append(": no valid targets with this value of X").toString()); game.informPlayer(controller, new StringBuilder(sourceObject != null ? sourceObject.getLogName(): "").append(": no valid targets with this value of X").toString());
} }
return false; // when activation of ability is canceled during target selection return false; // when activation of ability is canceled during target selection
@ -345,6 +346,7 @@ public abstract class AbilityImpl implements Ability {
return false; return false;
} }
// inform about x costs now, so canceled announcements are not shown in the log // inform about x costs now, so canceled announcements are not shown in the log
if (!game.isSimulation()) {
if (announceString != null) { if (announceString != null) {
game.informPlayers(announceString); game.informPlayers(announceString);
} }
@ -352,6 +354,7 @@ public abstract class AbilityImpl implements Ability {
int xValue = getManaCostsToPay().getX(); int xValue = getManaCostsToPay().getX();
game.informPlayers(new StringBuilder(controller.getName()).append(" announces a value of ").append(xValue).append(" for ").append(variableManaCost.getText()).toString()); game.informPlayers(new StringBuilder(controller.getName()).append(" announces a value of ").append(xValue).append(" for ").append(variableManaCost.getText()).toString());
} }
}
activated = true; activated = true;
// fire if tapped for mana (may only fire now because else costs of ability itself can be payed with mana of abilities that trigger for that event // fire if tapped for mana (may only fire now because else costs of ability itself can be payed with mana of abilities that trigger for that event
if (this.getAbilityType().equals(AbilityType.MANA)) { if (this.getAbilityType().equals(AbilityType.MANA)) {

View file

@ -89,6 +89,7 @@ class TurnFaceUpEffect extends OneShotEffect {
Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent != null) { if (sourcePermanent != null) {
if (sourcePermanent.turnFaceUp(game, source.getControllerId())) { if (sourcePermanent.turnFaceUp(game, source.getControllerId())) {
if (!game.isSimulation())
game.informPlayers(controller.getName() + " pays the costs of " + card.getLogName() + " to turn it face up"); game.informPlayers(controller.getName() + " pays the costs of " + card.getLogName() + " to turn it face up");
return true; return true;

View file

@ -63,7 +63,7 @@ public class ExileFromStackCost extends CostImpl {
return false; return false;
} }
paid |= spellToExile.moveToExile(null, "", ability.getSourceId(), game); paid |= spellToExile.moveToExile(null, "", ability.getSourceId(), game);
if (paid) { if (paid && !game.isSimulation()) {
game.informPlayers(player.getName() + " exiles " + spellToExile.getName() +" (as costs)"); game.informPlayers(player.getName() + " exiles " + spellToExile.getName() +" (as costs)");
} }
} }

View file

@ -130,6 +130,7 @@ public class RemoveCounterCost extends CostImpl {
permanent.getCounters().removeCounter(counterName); permanent.getCounters().removeCounter(counterName);
} }
countersRemoved += numberOfCountersSelected; countersRemoved += numberOfCountersSelected;
if (!game.isSimulation())
game.informPlayers(new StringBuilder(controller.getName()) game.informPlayers(new StringBuilder(controller.getName())
.append(" removes ").append(numberOfCountersSelected == 1 ? "a":numberOfCountersSelected).append(" ") .append(" removes ").append(numberOfCountersSelected == 1 ? "a":numberOfCountersSelected).append(" ")
.append(counterName).append(numberOfCountersSelected == 1 ? " counter from ":" counters from ") .append(counterName).append(numberOfCountersSelected == 1 ? " counter from ":" counters from ")

View file

@ -644,7 +644,7 @@ public class ContinuousEffects implements Serializable {
if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) { if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
effect.setValue("targetAbility", targetAbility); effect.setValue("targetAbility", targetAbility);
if (effect.applies(event, sourceAbility, game)) { if (effect.applies(event, sourceAbility, game)) {
if (!checkPlayableMode) { if (!checkPlayableMode && !game.isSimulation()) {
String message = effect.getInfoMessage(sourceAbility, event, game); String message = effect.getInfoMessage(sourceAbility, event, game);
if (message != null && !message.isEmpty()) { if (message != null && !message.isEmpty()) {
if (effect.sendMessageToUser()) { if (effect.sendMessageToUser()) {

View file

@ -82,6 +82,7 @@ public class PlaneswalkerRedirectionEffect extends RedirectionEffect {
else { else {
player.choose(Outcome.Damage, redirectTarget, null, game); player.choose(Outcome.Damage, redirectTarget, null, game);
} }
if (!game.isSimulation())
game.informPlayers(new StringBuilder(player.getName()).append(" redirects ") game.informPlayers(new StringBuilder(player.getName()).append(" redirects ")
.append(event.getAmount()) .append(event.getAmount())
.append(" damage to ") .append(" damage to ")

View file

@ -76,12 +76,14 @@ public class CastCardFromOutsideTheGameEffect extends OneShotEffect {
while (player.chooseUse(Outcome.Benefit, choiceText, game)) { while (player.chooseUse(Outcome.Benefit, choiceText, game)) {
Cards cards = player.getSideboard(); Cards cards = player.getSideboard();
if (cards.isEmpty()) { if (cards.isEmpty()) {
if (!game.isSimulation())
game.informPlayer(player, "You have no cards outside the game."); game.informPlayer(player, "You have no cards outside the game.");
return false; return false;
} }
Set<Card> filtered = cards.getCards(filterCard, source.getSourceId(), source.getControllerId(), game); Set<Card> filtered = cards.getCards(filterCard, source.getSourceId(), source.getControllerId(), game);
if (filtered.isEmpty()) { if (filtered.isEmpty()) {
if (!game.isSimulation())
game.informPlayer(player, "You have no " + filterCard.getMessage() + " outside the game."); game.informPlayer(player, "You have no " + filterCard.getMessage() + " outside the game.");
return false; return false;
} }

View file

@ -63,6 +63,7 @@ public class ChooseColorEffect extends OneShotEffect {
return false; return false;
} }
} }
if (!game.isSimulation())
game.informPlayers(new StringBuilder(permanent.getLogName()).append(": ").append(controller.getName()).append(" has chosen ").append(choice.getChoice()).toString()); game.informPlayers(new StringBuilder(permanent.getLogName()).append(": ").append(controller.getName()).append(" has chosen ").append(choice.getChoice()).toString());
game.getState().setValue(source.getSourceId() + "_color", choice.getColor()); game.getState().setValue(source.getSourceId() + "_color", choice.getColor());
permanent.addInfo("chosen color", "<font color = 'blue'>Chosen color: " + choice.getColor().getDescription() + "</font>", game); permanent.addInfo("chosen color", "<font color = 'blue'>Chosen color: " + choice.getColor().getDescription() + "</font>", game);

View file

@ -67,6 +67,7 @@ public class ChooseCreatureTypeEffect extends OneShotEffect {
return false; return false;
} }
} }
if (!game.isSimulation())
game.informPlayers(permanent.getName() + ": " + controller.getName() + " has chosen " + typeChoice.getChoice()); game.informPlayers(permanent.getName() + ": " + controller.getName() + " has chosen " + typeChoice.getChoice());
game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice()); game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice());
permanent.addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game); permanent.addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game);

View file

@ -80,6 +80,7 @@ public class ChooseModeEffect extends OneShotEffect {
controller.choose(Outcome.Neutral, choice, game); controller.choose(Outcome.Neutral, choice, game);
} }
if (choice.isChosen()) { if (choice.isChosen()) {
if (!game.isSimulation())
game.informPlayers(new StringBuilder(sourcePermanent.getLogName()).append(": ").append(controller.getName()).append(" has chosen ").append(choice.getChoice()).toString()); game.informPlayers(new StringBuilder(sourcePermanent.getLogName()).append(": ").append(controller.getName()).append(" has chosen ").append(choice.getChoice()).toString());
game.getState().setValue(source.getSourceId() + "_modeChoice", choice.getChoice()); game.getState().setValue(source.getSourceId() + "_modeChoice", choice.getChoice());
sourcePermanent.addInfo("_modeChoice", "<font color = 'blue'>Chosen mode: " + choice.getChoice() + "</font>", game); sourcePermanent.addInfo("_modeChoice", "<font color = 'blue'>Chosen mode: " + choice.getChoice() + "</font>", game);

View file

@ -99,6 +99,7 @@ public class CipherEffect extends OneShotEffect {
ContinuousEffect effect = new GainAbilityTargetEffect(ability, Duration.Custom); ContinuousEffect effect = new GainAbilityTargetEffect(ability, Duration.Custom);
effect.setTargetPointer(new FixedTarget(target.getFirstTarget())); effect.setTargetPointer(new FixedTarget(target.getFirstTarget()));
game.addEffect(effect, source); game.addEffect(effect, source);
if (!game.isSimulation())
game.informPlayers(new StringBuilder(sourceCard.getLogName()).append(": Spell ciphered to ").append(targetCreature.getLogName()).toString()); game.informPlayers(new StringBuilder(sourceCard.getLogName()).append(": Spell ciphered to ").append(targetCreature.getLogName()).toString());
return sourceCard.moveToExile(null, "", source.getSourceId(), game); return sourceCard.moveToExile(null, "", source.getSourceId(), game);
} else { } else {

View file

@ -128,6 +128,7 @@ public class ClashEffect extends OneShotEffect implements MageSingleton {
} else { } else {
message.append(" no card"); message.append(" no card");
} }
if (!game.isSimulation()) {
message.append(" - "); message.append(" - ");
if (cmcController > cmcOpponent) { if (cmcController > cmcOpponent) {
message.append(controller.getName()).append(" won the clash"); message.append(controller.getName()).append(" won the clash");
@ -139,6 +140,7 @@ public class ClashEffect extends OneShotEffect implements MageSingleton {
message.append(" no winner "); message.append(" no winner ");
} }
game.informPlayers(message.toString()); game.informPlayers(message.toString());
}
// decide to put the cards on top or on the buttom of library in turn order beginning with the active player in turn order // decide to put the cards on top or on the buttom of library in turn order beginning with the active player in turn order
PlayerList playerList = game.getPlayerList().copy(); PlayerList playerList = game.getPlayerList().copy();

View file

@ -64,12 +64,14 @@ public class CopyTargetSpellEffect extends OneShotEffect {
copy.setCopiedSpell(true); copy.setCopiedSpell(true);
game.getStack().push(copy); game.getStack().push(copy);
copy.chooseNewTargets(game, source.getControllerId()); copy.chooseNewTargets(game, source.getControllerId());
if (!game.isSimulation()) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
String activateMessage = copy.getActivatedMessage(game); String activateMessage = copy.getActivatedMessage(game);
if (activateMessage.startsWith(" casts ")) { if (activateMessage.startsWith(" casts ")) {
activateMessage = activateMessage.substring(6); activateMessage = activateMessage.substring(6);
} }
game.informPlayers(player.getName() + " copies " + activateMessage); game.informPlayers(player.getName() + " copies " + activateMessage);
}
return true; return true;
} }
return false; return false;

View file

@ -73,6 +73,7 @@ public class DetainAllEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
List<FixedTarget> detainedObjects = new ArrayList<>(); List<FixedTarget> detainedObjects = new ArrayList<>();
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (!game.isSimulation())
game.informPlayers("Detained permanent: " + permanent.getName()); game.informPlayers("Detained permanent: " + permanent.getName());
FixedTarget fixedTarget = new FixedTarget(permanent.getId()); FixedTarget fixedTarget = new FixedTarget(permanent.getId());
fixedTarget.init(game, source); fixedTarget.init(game, source);

View file

@ -79,12 +79,14 @@ public class DetainTargetEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
if (!game.isSimulation()) {
for (UUID target: this.getTargetPointer().getTargets(game, source)) { for (UUID target: this.getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(target); Permanent permanent = game.getPermanent(target);
if (permanent != null) { if (permanent != null) {
game.informPlayers("Detained permanent: " + permanent.getName()); game.informPlayers("Detained permanent: " + permanent.getName());
} }
} }
}
DetainRestrictionEffect effect = new DetainRestrictionEffect(); DetainRestrictionEffect effect = new DetainRestrictionEffect();
game.addEffect(effect, source); game.addEffect(effect, source);
return true; return true;

View file

@ -141,6 +141,7 @@ public class DevourEffect extends ReplacementEffectImpl {
if (target.getTargets().size() > 0) { if (target.getTargets().size() > 0) {
List<ArrayList<String>> cardSubtypes = new ArrayList<>(); List<ArrayList<String>> cardSubtypes = new ArrayList<>();
int devouredCreatures = target.getTargets().size(); int devouredCreatures = target.getTargets().size();
if (!game.isSimulation())
game.informPlayers(new StringBuilder(creature.getName()).append(" devours ").append(devouredCreatures).append(" creatures").toString()); game.informPlayers(new StringBuilder(creature.getName()).append(" devours ").append(devouredCreatures).append(" creatures").toString());
for (UUID targetId: target.getTargets()) { for (UUID targetId: target.getTargets()) {
Permanent targetCreature = game.getPermanent(targetId); Permanent targetCreature = game.getPermanent(targetId);

View file

@ -95,6 +95,7 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect {
if (player != null && cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, message, game)) { if (player != null && cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, message, game)) {
cost.clearPaid(); cost.clearPaid();
if (cost.pay(source, game, source.getSourceId(), player.getId(), false)) { if (cost.pay(source, game, source.getSourceId(), player.getId(), false)) {
if (!game.isSimulation())
game.informPlayers(player.getName() + " pays the cost to prevent the effect"); game.informPlayers(player.getName() + " pays the cost to prevent the effect");
doEffect = false; doEffect = false;
break; break;

View file

@ -67,6 +67,7 @@ public class FightTargetSourceEffect extends OneShotEffect {
} }
} }
} }
if (!game.isSimulation())
game.informPlayers(originalPermanent.getLogName() + ": Fighting effect has been fizzled."); game.informPlayers(originalPermanent.getLogName() + ": Fighting effect has been fizzled.");
} }
return false; return false;

View file

@ -67,6 +67,7 @@ public class FightTargetsEffect extends OneShotEffect {
} }
} }
} }
if (!game.isSimulation())
game.informPlayers(card.getName() + " has been fizzled."); game.informPlayers(card.getName() + " has been fizzled.");
} }
return false; return false;

View file

@ -38,6 +38,7 @@ public class FlipSourceEffect extends OneShotEffect {
if (permanent.flip(game)) { if (permanent.flip(game)) {
ContinuousEffect effect = new ConditionalContinousEffect(new CopyTokenEffect(flipToken), FlippedCondition.getInstance(), ""); ContinuousEffect effect = new ConditionalContinousEffect(new CopyTokenEffect(flipToken), FlippedCondition.getInstance(), "");
game.addEffect(effect, source); game.addEffect(effect, source);
if (!game.isSimulation())
game.informPlayers(new StringBuilder(controller.getName()).append(" flips ").append(permanent.getName()).toString()); game.informPlayers(new StringBuilder(controller.getName()).append(" flips ").append(permanent.getName()).toString());
return true; return true;
} }

View file

@ -141,6 +141,7 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff
player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId());
} else { } else {
card.moveToZone(targetPickedCards, source.getSourceId(), game, false); card.moveToZone(targetPickedCards, source.getSourceId(), game, false);
if (!game.isSimulation())
game.informPlayers(player.getName() + " moves a card to " + targetPickedCards.toString().toLowerCase()); game.informPlayers(player.getName() + " moves a card to " + targetPickedCards.toString().toLowerCase());
} }
if (revealPickedCards) { if (revealPickedCards) {

View file

@ -93,6 +93,7 @@ public class NameACardEffect extends OneShotEffect {
} }
} }
String cardName = cardChoice.getChoice(); String cardName = cardChoice.getChoice();
if (!game.isSimulation())
game.informPlayers(sourceObject.getLogName() + ", named card: [" + cardName + "]"); game.informPlayers(sourceObject.getLogName() + ", named card: [" + cardName + "]");
game.getState().setValue(source.getSourceId().toString() + INFO_KEY, cardName); game.getState().setValue(source.getSourceId().toString() + INFO_KEY, cardName);
if (sourceObject instanceof Permanent) { if (sourceObject instanceof Permanent) {

View file

@ -94,6 +94,7 @@ public class PopulateEffect extends OneShotEffect {
player.choose(Outcome.Copy, target, source.getSourceId(), game); player.choose(Outcome.Copy, target, source.getSourceId(), game);
Permanent tokenToCopy = game.getPermanent(target.getFirstTarget()); Permanent tokenToCopy = game.getPermanent(target.getFirstTarget());
if (tokenToCopy != null) { if (tokenToCopy != null) {
if (!game.isSimulation())
game.informPlayers("Token selected for populate: " + tokenToCopy.getLogName()); game.informPlayers("Token selected for populate: " + tokenToCopy.getLogName());
Effect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); Effect effect = new PutTokenOntoBattlefieldCopyTargetEffect();
effect.setTargetPointer(new FixedTarget(target.getFirstTarget())); effect.setTargetPointer(new FixedTarget(target.getFirstTarget()));

View file

@ -80,6 +80,7 @@ public class PreventDamageToTargetMultiAmountEffect extends PreventionEffectImpl
player = game.getPlayer(targetId); player = game.getPlayer(targetId);
} }
targetAmountMap.put(targetId, multiTarget.getTargetAmount(targetId)); targetAmountMap.put(targetId, multiTarget.getTargetAmount(targetId));
if (!game.isSimulation()) {
StringBuilder sb = new StringBuilder(sourceObject.getName()).append(": Prevent the next "); StringBuilder sb = new StringBuilder(sourceObject.getName()).append(": Prevent the next ");
sb.append(multiTarget.getTargetAmount(targetId)).append(" damage to "); sb.append(multiTarget.getTargetAmount(targetId)).append(" damage to ");
if (player != null) { if (player != null) {
@ -88,7 +89,7 @@ public class PreventDamageToTargetMultiAmountEffect extends PreventionEffectImpl
sb.append(permanent.getName()); sb.append(permanent.getName());
} }
game.informPlayers(sb.toString()); game.informPlayers(sb.toString());
}
} }
} }
} }

View file

@ -69,6 +69,7 @@ public class PutTokenOntoBattlefieldCopySource extends OneShotEffect {
EmptyToken token = new EmptyToken(); EmptyToken token = new EmptyToken();
CardUtil.copyTo(token).from((Permanent)thisCard); CardUtil.copyTo(token).from((Permanent)thisCard);
if (token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId())) { if (token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId())) {
if (!game.isSimulation())
game.informPlayers(new StringBuilder(controller.getName()) game.informPlayers(new StringBuilder(controller.getName())
.append(" puts a ").append(token.getName()).append(" token ").append("onto the Battlefield").toString()); .append(" puts a ").append(token.getName()).append(" token ").append("onto the Battlefield").toString());
return true; return true;
@ -79,6 +80,7 @@ public class PutTokenOntoBattlefieldCopySource extends OneShotEffect {
EmptyToken token = new EmptyToken(); EmptyToken token = new EmptyToken();
CardUtil.copyTo(token).from(permanent); CardUtil.copyTo(token).from(permanent);
if (token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId())) { if (token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId())) {
if (!game.isSimulation())
game.informPlayers(new StringBuilder(controller.getName()) game.informPlayers(new StringBuilder(controller.getName())
.append(" puts a ").append(token.getName()).append(" token ").append("onto the Battlefield").toString()); .append(" puts a ").append(token.getName()).append(" token ").append("onto the Battlefield").toString());
return true; return true;

View file

@ -92,6 +92,7 @@ public class ReturnFromExileEffect extends OneShotEffect {
switch (zone) { switch (zone) {
case BATTLEFIELD: case BATTLEFIELD:
card.moveToZone(zone, source.getSourceId(), game, tapped); card.moveToZone(zone, source.getSourceId(), game, tapped);
if (!game.isSimulation())
game.informPlayers(new StringBuilder(controller.getName()).append(" moves ").append(card.getName()).append(" to ").append(zone.toString()).toString()); game.informPlayers(new StringBuilder(controller.getName()).append(" moves ").append(card.getName()).append(" to ").append(zone.toString()).toString());
break; break;
case HAND: case HAND:
@ -105,6 +106,7 @@ public class ReturnFromExileEffect extends OneShotEffect {
break; break;
default: default:
card.moveToZone(zone, source.getSourceId(), game, tapped); card.moveToZone(zone, source.getSourceId(), game, tapped);
if (!game.isSimulation())
game.informPlayers(new StringBuilder(controller.getName()).append(" moves ").append(card.getName()).append(" to ").append(zone.toString()).toString()); game.informPlayers(new StringBuilder(controller.getName()).append(" moves ").append(card.getName()).append(" to ").append(zone.toString()).toString());
} }
} }

View file

@ -86,6 +86,7 @@ public class ReturnFromExileForSourceEffect extends OneShotEffect {
if (card == null) { if (card == null) {
return false; return false;
} }
if (!game.isSimulation())
game.informPlayers(controller.getName() + " moves " + card.getLogName() + " to " + zone.toString().toLowerCase()); game.informPlayers(controller.getName() + " moves " + card.getLogName() + " to " + zone.toString().toLowerCase());
card.moveToZone(zone, source.getSourceId(), game, tapped); card.moveToZone(zone, source.getSourceId(), game, tapped);
} }

View file

@ -80,6 +80,7 @@ public class TransformSourceEffect extends OneShotEffect {
} else { } else {
permanent.transform(game); permanent.transform(game);
} }
if (!game.isSimulation()) {
if (fromDayToNight) { if (fromDayToNight) {
game.informPlayers(new StringBuilder(permanent.getName()).append(" transforms into ").append(permanent.getSecondCardFace().getName()).toString()); game.informPlayers(new StringBuilder(permanent.getName()).append(" transforms into ").append(permanent.getSecondCardFace().getName()).toString());
} else { } else {
@ -87,6 +88,7 @@ public class TransformSourceEffect extends OneShotEffect {
} }
} }
} }
}
return true; return true;
} }
return false; return false;

View file

@ -96,6 +96,7 @@ public class BecomesColorTargetEffect extends ContinuousEffectImpl {
} else { } else {
return false; return false;
} }
if (!game.isSimulation())
game.informPlayers(controller.getName() + " has chosen the color: " + objectColor.toString()); game.informPlayers(controller.getName() + " has chosen the color: " + objectColor.toString());
} else { } else {
objectColor = this.setColor; objectColor = this.setColor;

View file

@ -88,6 +88,7 @@ public class CommanderReplacementEffect extends ReplacementEffectImpl {
Player player = game.getPlayer(permanent.getOwnerId()); Player player = game.getPlayer(permanent.getOwnerId());
if (player != null && player.chooseUse(Outcome.Benefit, "Move commander to command zone?", game)){ if (player != null && player.chooseUse(Outcome.Benefit, "Move commander to command zone?", game)){
boolean result = permanent.moveToZone(Zone.COMMAND, source.getSourceId(), game, false); boolean result = permanent.moveToZone(Zone.COMMAND, source.getSourceId(), game, false);
if (!game.isSimulation())
game.informPlayers(player.getName() + " has moved his or her commander to the command zone"); game.informPlayers(player.getName() + " has moved his or her commander to the command zone");
return result; return result;
} }
@ -107,6 +108,7 @@ public class CommanderReplacementEffect extends ReplacementEffectImpl {
Player player = game.getPlayer(card.getOwnerId()); Player player = game.getPlayer(card.getOwnerId());
if (player != null && player.chooseUse(Outcome.Benefit, "Move commander to command zone?", game)){ if (player != null && player.chooseUse(Outcome.Benefit, "Move commander to command zone?", game)){
boolean result = card.moveToZone(Zone.COMMAND, source.getSourceId(), game, false); boolean result = card.moveToZone(Zone.COMMAND, source.getSourceId(), game, false);
if (!game.isSimulation())
game.informPlayers(player.getName() + " has moved his or her commander to the command zone"); game.informPlayers(player.getName() + " has moved his or her commander to the command zone");
return result; return result;
} }

View file

@ -77,7 +77,7 @@ public class GainProtectionFromColorTargetEffect extends GainAbilityTargetEffect
return; return;
} }
} }
if (choice.isChosen()) { if (!game.isSimulation() && choice.isChosen()) {
game.informPlayers(sourceObject.getLogName() + ": " + controller.getName() + " has chosen protection from " + choice.getChoice()); game.informPlayers(sourceObject.getLogName() + ": " + controller.getName() + " has chosen protection from " + choice.getChoice());
} }
} }

View file

@ -72,6 +72,7 @@ public class AddCountersAllEffect extends OneShotEffect {
for (Permanent permanent : permanents) { for (Permanent permanent : permanents) {
if (filter.match(permanent, source.getSourceId(), controllerId, game)) { if (filter.match(permanent, source.getSourceId(), controllerId, game)) {
permanent.addCounters(counter.copy(), game); permanent.addCounters(counter.copy(), game);
if (!game.isSimulation())
game.informPlayers(new StringBuilder(sourceObject.getName()).append(": ") game.informPlayers(new StringBuilder(sourceObject.getName()).append(": ")
.append(controller.getName()).append(" puts ") .append(controller.getName()).append(" puts ")
.append(counter.getCount()).append(" ").append(counter.getName().toLowerCase()) .append(counter.getCount()).append(" ").append(counter.getName().toLowerCase())

View file

@ -103,7 +103,7 @@ public class AddCountersSourceEffect extends OneShotEffect {
} }
newCounter.add(countersToAdd); newCounter.add(countersToAdd);
card.addCounters(newCounter, game); card.addCounters(newCounter, game);
if (informPlayers) { if (informPlayers && !game.isSimulation()) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player != null) { if (player != null) {
game.informPlayers(new StringBuilder(player.getName()).append(" puts ").append(newCounter.getCount()).append(" ").append(newCounter.getName().toLowerCase()).append(" counter on ").append(card.getLogName()).toString()); game.informPlayers(new StringBuilder(player.getName()).append(" puts ").append(newCounter.getCount()).append(" ").append(newCounter.getName().toLowerCase()).append(" counter on ").append(card.getLogName()).toString());
@ -125,7 +125,7 @@ public class AddCountersSourceEffect extends OneShotEffect {
int before = permanent.getCounters().getCount(newCounter.getName()); int before = permanent.getCounters().getCount(newCounter.getName());
permanent.addCounters(newCounter, game); permanent.addCounters(newCounter, game);
int amountAdded = permanent.getCounters().getCount(newCounter.getName()) - before; int amountAdded = permanent.getCounters().getCount(newCounter.getName()) - before;
if (informPlayers) { if (informPlayers && !game.isSimulation()) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player != null) { if (player != null) {
game.informPlayers(player.getName()+" puts "+amountAdded+" "+newCounter.getName().toLowerCase()+" counter on "+permanent.getLogName()); game.informPlayers(player.getName()+" puts "+amountAdded+" "+newCounter.getName().toLowerCase()+" counter on "+permanent.getLogName());

View file

@ -95,6 +95,7 @@ public class AddCountersTargetEffect extends OneShotEffect {
permanent.addCounters(newCounter, game); permanent.addCounters(newCounter, game);
int numberAdded = permanent.getCounters().getCount(counter.getName()) - before; int numberAdded = permanent.getCounters().getCount(counter.getName()) - before;
affectedTargets ++; affectedTargets ++;
if (!game.isSimulation())
game.informPlayers(sourceObject.getLogName() +": "+ controller.getName()+ " puts " + game.informPlayers(sourceObject.getLogName() +": "+ controller.getName()+ " puts " +
numberAdded + " " + counter.getName().toLowerCase() + " counter on " + permanent.getLogName()); numberAdded + " " + counter.getName().toLowerCase() + " counter on " + permanent.getLogName());
} }
@ -105,6 +106,7 @@ public class AddCountersTargetEffect extends OneShotEffect {
newCounter.add(amount.calculate(game, source, this)); newCounter.add(amount.calculate(game, source, this));
player.addCounters(newCounter, game); player.addCounters(newCounter, game);
affectedTargets ++; affectedTargets ++;
if (!game.isSimulation())
game.informPlayers(new StringBuilder(sourceObject.getLogName()).append(": ") game.informPlayers(new StringBuilder(sourceObject.getLogName()).append(": ")
.append(controller.getName()).append(" puts ") .append(controller.getName()).append(" puts ")
.append(counter.getCount()).append(" ").append(counter.getName().toLowerCase()) .append(counter.getCount()).append(" ").append(counter.getName().toLowerCase())

View file

@ -60,6 +60,7 @@ public class RemoveCounterSourceEffect extends OneShotEffect {
Permanent p = game.getPermanent(source.getSourceId()); Permanent p = game.getPermanent(source.getSourceId());
if (p != null && p.getCounters().getCount(counter.getName()) >= counter.getCount()) { if (p != null && p.getCounters().getCount(counter.getName()) >= counter.getCount()) {
p.removeCounters(counter.getName(), counter.getCount(), game); p.removeCounters(counter.getName(), counter.getCount(), game);
if (!game.isSimulation())
game.informPlayers(new StringBuilder("Removed ").append(counter.getCount()).append(" ").append(counter.getName()) game.informPlayers(new StringBuilder("Removed ").append(counter.getCount()).append(" ").append(counter.getName())
.append(" counter from ").append(p.getName()).toString()); .append(" counter from ").append(p.getName()).toString());
return true; return true;
@ -67,6 +68,7 @@ public class RemoveCounterSourceEffect extends OneShotEffect {
Card c = game.getCard(source.getSourceId()); Card c = game.getCard(source.getSourceId());
if (c != null && c.getCounters(game).getCount(counter.getName()) >= counter.getCount()) { if (c != null && c.getCounters(game).getCount(counter.getName()) >= counter.getCount()) {
c.removeCounters(counter.getName(), counter.getCount(), game); c.removeCounters(counter.getName(), counter.getCount(), game);
if (!game.isSimulation())
game.informPlayers(new StringBuilder("Removed ").append(counter.getCount()).append(" ").append(counter.getName()) game.informPlayers(new StringBuilder("Removed ").append(counter.getCount()).append(" ").append(counter.getName())
.append(" counter from ").append(c.getName()) .append(" counter from ").append(c.getName())
.append(" (").append(c.getCounters(game).getCount(counter.getName())).append(" left)").toString()); .append(" (").append(c.getCounters(game).getCount(counter.getName())).append(" left)").toString());

View file

@ -61,6 +61,7 @@ public class RemoveCounterTargetEffect extends OneShotEffect {
Permanent p = game.getPermanent(targetPointer.getFirst(game, source)); Permanent p = game.getPermanent(targetPointer.getFirst(game, source));
if (p != null && p.getCounters().getCount(counter.getName()) >= counter.getCount()) { if (p != null && p.getCounters().getCount(counter.getName()) >= counter.getCount()) {
p.removeCounters(counter.getName(), counter.getCount(), game); p.removeCounters(counter.getName(), counter.getCount(), game);
if (!game.isSimulation())
game.informPlayers(new StringBuilder("Removed ").append(counter.getCount()).append(" ").append(counter.getName()) game.informPlayers(new StringBuilder("Removed ").append(counter.getCount()).append(" ").append(counter.getName())
.append(" counter from ").append(p.getName()).toString()); .append(" counter from ").append(p.getName()).toString());
return true; return true;
@ -68,6 +69,7 @@ public class RemoveCounterTargetEffect extends OneShotEffect {
Card c = game.getCard(targetPointer.getFirst(game, source)); Card c = game.getCard(targetPointer.getFirst(game, source));
if (c != null && c.getCounters(game).getCount(counter.getName()) >= counter.getCount()) { if (c != null && c.getCounters(game).getCount(counter.getName()) >= counter.getCount()) {
c.removeCounters(counter.getName(), counter.getCount(), game); c.removeCounters(counter.getName(), counter.getCount(), game);
if (!game.isSimulation())
game.informPlayers(new StringBuilder("Removed ").append(counter.getCount()).append(" ").append(counter.getName()) game.informPlayers(new StringBuilder("Removed ").append(counter.getCount()).append(" ").append(counter.getName())
.append(" counter from ").append(c.getName()) .append(" counter from ").append(c.getName())
.append(" (").append(c.getCounters(game).getCount(counter.getName())).append(" left)").toString()); .append(" (").append(c.getCounters(game).getCount(counter.getName())).append(" left)").toString());

View file

@ -98,7 +98,7 @@ public class SearchLibraryPutOnLibraryEffect extends SearchEffect {
if (forceShuffle) { if (forceShuffle) {
controller.shuffleLibrary(game); controller.shuffleLibrary(game);
} }
if (cards.size() > 0) { if (cards.size() > 0 && !game.isSimulation()) {
game.informPlayers(controller.getName() + " moves " + cards.size() + " card" + (cards.size() == 1 ? " ":"s ") + "on top of his or her library"); game.informPlayers(controller.getName() + " moves " + cards.size() + " card" + (cards.size() == 1 ? " ":"s ") + "on top of his or her library");
} }
for (Card card: cards) { for (Card card: cards) {

View file

@ -165,7 +165,7 @@ public class ConvokeAbility extends SimpleStaticAbility implements AdjustingSour
if (costBefore == ability.getManaCostsToPay().convertedManaCost()) { if (costBefore == ability.getManaCostsToPay().convertedManaCost()) {
// creature could not reduce mana costs so tap must be reverted // creature could not reduce mana costs so tap must be reverted
perm.untap(game); perm.untap(game);
} else { } else if (!game.isSimulation()) {
game.informPlayers("Convoke: " + player.getName() + " taps " + perm.getLogName() + " to reduce mana costs by " + manaCostsToReduce.getText()); game.informPlayers("Convoke: " + player.getName() + " taps " + perm.getLogName() + " to reduce mana costs by " + manaCostsToReduce.getText());
} }
} }

View file

@ -109,6 +109,7 @@ import mage.util.CardUtil;
player.moveCardToExileWithInfo(card, null, "", getSourceId(), game, Zone.GRAVEYARD); player.moveCardToExileWithInfo(card, null, "", getSourceId(), game, Zone.GRAVEYARD);
++adjCost; ++adjCost;
} }
if (!game.isSimulation())
game.informPlayers(new StringBuilder("Delve: ").append(player.getName()).append(" exiled ") game.informPlayers(new StringBuilder("Delve: ").append(player.getName()).append(" exiled ")
.append(adjCost).append(" card").append(adjCost != 1?"s":"").append(" from his or her graveyard").toString()); .append(adjCost).append(" card").append(adjCost != 1?"s":"").append(" from his or her graveyard").toString());
CardUtil.adjustCost((SpellAbility)ability, adjCost); CardUtil.adjustCost((SpellAbility)ability, adjCost);

View file

@ -97,6 +97,7 @@ class DredgeEffect extends ReplacementEffectImpl {
if (player != null && player.getLibrary().size() >= amount if (player != null && player.getLibrary().size() >= amount
&& player.chooseUse(outcome, new StringBuilder("Dredge ").append(sourceCard.getName()). && player.chooseUse(outcome, new StringBuilder("Dredge ").append(sourceCard.getName()).
append("? (").append(amount).append(" cards go from top of library to graveyard)").toString(), game)) { append("? (").append(amount).append(" cards go from top of library to graveyard)").toString(), game)) {
if (!game.isSimulation())
game.informPlayers(new StringBuilder(player.getName()).append(" dreges ").append(sourceCard.getName()).toString()); game.informPlayers(new StringBuilder(player.getName()).append(" dreges ").append(sourceCard.getName()).toString());
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
Card card = player.getLibrary().removeFromTop(game); Card card = player.getLibrary().removeFromTop(game);

View file

@ -109,6 +109,7 @@ class ExtortEffect extends OneShotEffect {
if (loseLife > 0) { if (loseLife > 0) {
game.getPlayer(source.getControllerId()).gainLife(loseLife, game); game.getPlayer(source.getControllerId()).gainLife(loseLife, game);
} }
if (!game.isSimulation())
game.informPlayers(new StringBuilder(permanent.getName()).append(" extorted opponents ").append(loseLife).append(" life").toString()); game.informPlayers(new StringBuilder(permanent.getName()).append(" extorted opponents ").append(loseLife).append(" life").toString());
} }
} }

View file

@ -201,6 +201,7 @@ class FlashbackEffect extends OneShotEffect {
} }
spellAbility.getManaCostsToPay().setX(amount); spellAbility.getManaCostsToPay().setX(amount);
} }
if (!game.isSimulation())
game.informPlayers(new StringBuilder(controller.getName()).append(" flashbacks ").append(card.getName()).toString()); game.informPlayers(new StringBuilder(controller.getName()).append(" flashbacks ").append(card.getName()).toString());
spellAbility.setCostModificationActive(false); // prevents to apply cost modification twice for flashbacked spells spellAbility.setCostModificationActive(false); // prevents to apply cost modification twice for flashbacked spells
return controller.cast(spellAbility, game, true); return controller.cast(spellAbility, game, true);

View file

@ -170,8 +170,10 @@ class GraftDistributeCounterEffect extends OneShotEffect {
if (targetCreature != null) { if (targetCreature != null) {
sourcePermanent.removeCounters(CounterType.P1P1.getName(), 1, game); sourcePermanent.removeCounters(CounterType.P1P1.getName(), 1, game);
targetCreature.addCounters(CounterType.P1P1.createInstance(1), game); targetCreature.addCounters(CounterType.P1P1.createInstance(1), game);
if (!game.isSimulation()) {
StringBuilder sb = new StringBuilder("Moved one +1/+1 counter from ").append(sourcePermanent.getName()).append(" to ").append(targetCreature.getName()); StringBuilder sb = new StringBuilder("Moved one +1/+1 counter from ").append(sourcePermanent.getName()).append(" to ").append(targetCreature.getName());
game.informPlayers(sb.toString()); game.informPlayers(sb.toString());
}
return true; return true;
} }
} }

View file

@ -179,6 +179,7 @@ class HauntEffect extends OneShotEffect {
game.getState().setValue(key, new FixedTarget(targetPointer.getFirst(game, source))); game.getState().setValue(key, new FixedTarget(targetPointer.getFirst(game, source)));
card.addInfo("hauntinfo", new StringBuilder("Haunting ").append(hauntedCreature.getLogName()).toString(), game); card.addInfo("hauntinfo", new StringBuilder("Haunting ").append(hauntedCreature.getLogName()).toString(), game);
hauntedCreature.addInfo("hauntinfo", new StringBuilder("Haunted by ").append(card.getLogName()).toString(), game); hauntedCreature.addInfo("hauntinfo", new StringBuilder("Haunted by ").append(card.getLogName()).toString(), game);
if (!game.isSimulation())
game.informPlayers(new StringBuilder(card.getName()).append(" haunting ").append(hauntedCreature.getLogName()).toString()); game.informPlayers(new StringBuilder(card.getName()).append(" haunting ").append(hauntedCreature.getLogName()).toString());
} }
return true; return true;

View file

@ -212,6 +212,7 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
// use only first variable cost // use only first variable cost
xManaValue = game.getPlayer(this.controllerId).announceXMana(varCosts.get(0).getMinX(), Integer.MAX_VALUE, "Announce kicker value for " + varCosts.get(0).getText(), game, this); xManaValue = game.getPlayer(this.controllerId).announceXMana(varCosts.get(0).getMinX(), Integer.MAX_VALUE, "Announce kicker value for " + varCosts.get(0).getText(), game, this);
// kicker variable X costs handled internally as multikicker with {1} cost (no multikicker on card) // kicker variable X costs handled internally as multikicker with {1} cost (no multikicker on card)
if (!game.isSimulation())
game.informPlayers(new StringBuilder(game.getPlayer(this.controllerId).getName()).append(" announced a value of ").append(xManaValue).append(" for ").append(" kicker X ").toString()); game.informPlayers(new StringBuilder(game.getPlayer(this.controllerId).getName()).append(" announced a value of ").append(xManaValue).append(" for ").append(" kicker X ").toString());
ability.getManaCostsToPay().add(new GenericManaCost(xManaValue)); ability.getManaCostsToPay().add(new GenericManaCost(xManaValue));
} else { } else {

View file

@ -249,6 +249,7 @@ class ReplicateCopyEffect extends OneShotEffect {
copy.setCopiedSpell(true); copy.setCopiedSpell(true);
game.getStack().push(copy); game.getStack().push(copy);
copy.chooseNewTargets(game, source.getControllerId()); copy.chooseNewTargets(game, source.getControllerId());
if (!game.isSimulation())
game.informPlayers(new StringBuilder(controller.getName()).append(copy.getActivatedMessage(game)).toString()); game.informPlayers(new StringBuilder(controller.getName()).append(copy.getActivatedMessage(game)).toString());
} }
return true; return true;

View file

@ -107,12 +107,14 @@ class SunburstEffect extends OneShotEffect {
permanent.addCounters(counter, game); permanent.addCounters(counter, game);
if (!game.isSimulation()) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player != null) { if (player != null) {
game.informPlayers(player.getName()+ " puts " + counter.getCount() + " " + counter.getName() + " counter on " + permanent.getName()); game.informPlayers(player.getName()+ " puts " + counter.getCount() + " " + counter.getName() + " counter on " + permanent.getName());
} }
} }
} }
}
return true; return true;
} }

View file

@ -258,6 +258,7 @@ class SuspendExileEffect extends OneShotEffect {
suspend = source.getManaCostsToPay().getX(); suspend = source.getManaCostsToPay().getX();
} }
card.addCounters(CounterType.TIME.createInstance(suspend), game); card.addCounters(CounterType.TIME.createInstance(suspend), game);
if (!game.isSimulation())
game.informPlayers(new StringBuilder(controller.getName()).append(" suspends (").append(suspend).append(") ").append(card.getName()).toString()); game.informPlayers(new StringBuilder(controller.getName()).append(" suspends (").append(suspend).append(") ").append(card.getName()).toString());
return true; return true;
} }

View file

@ -119,10 +119,12 @@ class TributeEffect extends OneShotEffect {
sb.append(" (add ").append(CardUtil.numberToText(tributeValue)).append(" +1/+1 counter"); sb.append(" (add ").append(CardUtil.numberToText(tributeValue)).append(" +1/+1 counter");
sb.append(tributeValue > 1 ? "s":"").append(" to it)?"); sb.append(tributeValue > 1 ? "s":"").append(" to it)?");
if (opponent.chooseUse(outcome, sb.toString(), game)) { if (opponent.chooseUse(outcome, sb.toString(), game)) {
if (!game.isSimulation())
game.informPlayers(new StringBuilder(opponent.getName()).append(" pays tribute to ").append(sourcePermanent.getName()).toString()); game.informPlayers(new StringBuilder(opponent.getName()).append(" pays tribute to ").append(sourcePermanent.getName()).toString());
game.getState().setValue(new StringBuilder("tributeValue").append(source.getSourceId()).toString(), "yes"); game.getState().setValue(new StringBuilder("tributeValue").append(source.getSourceId()).toString(), "yes");
return new AddCountersSourceEffect(CounterType.P1P1.createInstance(tributeValue), true).apply(game, source); return new AddCountersSourceEffect(CounterType.P1P1.createInstance(tributeValue), true).apply(game, source);
} else { } else {
if (!game.isSimulation())
game.informPlayers(new StringBuilder(opponent.getName()).append(" does not pay tribute to ").append(sourcePermanent.getName()).toString()); game.informPlayers(new StringBuilder(opponent.getName()).append(" does not pay tribute to ").append(sourcePermanent.getName()).toString());
game.getState().setValue(new StringBuilder("tributeValue").append(source.getSourceId()).toString(), "no"); game.getState().setValue(new StringBuilder("tributeValue").append(source.getSourceId()).toString(), "no");
} }

View file

@ -112,6 +112,7 @@ class UnleashReplacementEffect extends ReplacementEffectImpl {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (creature != null && controller != null) { if (creature != null && controller != null) {
if (controller.chooseUse(outcome, "Unleash "+ creature.getName() +"?", game)) { if (controller.chooseUse(outcome, "Unleash "+ creature.getName() +"?", game)) {
if (!game.isSimulation())
game.informPlayers(controller.getName() + " unleashes " + creature.getName()); game.informPlayers(controller.getName() + " unleashes " + creature.getName());
creature.addCounters(CounterType.P1P1.createInstance(), game); creature.addCounters(CounterType.P1P1.createInstance(), game);
} }

View file

@ -53,7 +53,7 @@ public class MageDrawAction extends MageAction {
numDrawn++; numDrawn++;
score += value; score += value;
} }
if (!player.isTopCardRevealed() && numDrawn > 0) { if (!game.isSimulation() && !player.isTopCardRevealed() && numDrawn > 0) {
game.fireInformEvent(player.getName() + " draws " + CardUtil.numberToText(numDrawn, "a") + " card" + (numDrawn > 1 ? "s" : "")); game.fireInformEvent(player.getName() + " draws " + CardUtil.numberToText(numDrawn, "a") + " card" + (numDrawn > 1 ? "s" : ""));
} }
if (player.isEmptyDraw()) { if (player.isEmptyDraw()) {
@ -81,7 +81,7 @@ public class MageDrawAction extends MageAction {
if (card != null) { if (card != null) {
drawnCards.add(card); drawnCards.add(card);
card.moveToZone(Zone.HAND, null, game, false); card.moveToZone(Zone.HAND, null, game, false);
if (player.isTopCardRevealed()) { if (!game.isSimulation() && player.isTopCardRevealed()) {
game.fireInformEvent(player.getName() + " draws a revealed card (" + card.getLogName() + ")"); game.fireInformEvent(player.getName() + " draws a revealed card (" + card.getLogName() + ")");
} }

View file

@ -156,6 +156,7 @@ public abstract class GameCommanderImpl extends GameImpl {
} }
} }
player.drawCards(numCards - deduction, this); player.drawCards(numCards - deduction, this);
if (!isSimulation())
fireInformEvent(new StringBuilder(player.getName()) fireInformEvent(new StringBuilder(player.getName())
.append(" mulligans ") .append(" mulligans ")
.append(numCards) .append(numCards)

View file

@ -632,6 +632,7 @@ public abstract class GameImpl implements Game, Serializable {
boolean wasPaused = state.isPaused(); boolean wasPaused = state.isPaused();
state.resume(); state.resume();
if (!gameOver(null)) { if (!gameOver(null)) {
if (!isSimulation())
fireInformEvent(new StringBuilder("Turn ").append(state.getTurnNum()).toString()); fireInformEvent(new StringBuilder("Turn ").append(state.getTurnNum()).toString());
if (checkStopOnTurnOption()) { if (checkStopOnTurnOption()) {
return; return;
@ -694,6 +695,7 @@ public abstract class GameImpl implements Game, Serializable {
if (extraPlayer != null && extraPlayer.isInGame()) { if (extraPlayer != null && extraPlayer.isInGame()) {
state.setExtraTurn(true); state.setExtraTurn(true);
state.setTurnId(extraTurn.getId()); state.setTurnId(extraTurn.getId());
if (!isSimulation())
informPlayers(extraPlayer.getName() + " takes an extra turn"); informPlayers(extraPlayer.getName() + " takes an extra turn");
playTurn(extraPlayer); playTurn(extraPlayer);
state.setTurnNum(state.getTurnNum() + 1); state.setTurnNum(state.getTurnNum() + 1);
@ -723,6 +725,7 @@ public abstract class GameImpl implements Game, Serializable {
} }
private boolean playTurn(Player player) { private boolean playTurn(Player player) {
if (!isSimulation())
this.logStartOfTurn(player); this.logStartOfTurn(player);
if (checkStopOnTurnOption()) { if (checkStopOnTurnOption()) {
return false; return false;
@ -809,6 +812,7 @@ public abstract class GameImpl implements Game, Serializable {
} }
if (choosingPlayer != null && choosingPlayer.choose(Outcome.Benefit, targetPlayer, null, this)) { if (choosingPlayer != null && choosingPlayer.choose(Outcome.Benefit, targetPlayer, null, this)) {
if (!isSimulation()) {
startingPlayerId = targetPlayer.getTargets().get(0); startingPlayerId = targetPlayer.getTargets().get(0);
Player startingPlayer = state.getPlayer(startingPlayerId); Player startingPlayer = state.getPlayer(startingPlayerId);
StringBuilder message = new StringBuilder(choosingPlayer.getName()).append(" chooses that "); StringBuilder message = new StringBuilder(choosingPlayer.getName()).append(" chooses that ");
@ -820,6 +824,7 @@ public abstract class GameImpl implements Game, Serializable {
message.append(" takes the first turn"); message.append(" takes the first turn");
this.informPlayers(message.toString()); this.informPlayers(message.toString());
}
} else { } else {
// not possible to choose starting player, stop here // not possible to choose starting player, stop here
return; return;
@ -1698,6 +1703,7 @@ public abstract class GameImpl implements Game, Serializable {
private boolean movePermanentToGraveyardWithInfo(Permanent permanent) { private boolean movePermanentToGraveyardWithInfo(Permanent permanent) {
boolean result = false; boolean result = false;
if (permanent.moveToZone(Zone.GRAVEYARD, null, this, false)) { if (permanent.moveToZone(Zone.GRAVEYARD, null, this, false)) {
if (!isSimulation())
this.informPlayers(new StringBuilder(permanent.getLogName()) this.informPlayers(new StringBuilder(permanent.getLogName())
.append(" is put into graveyard from battlefield").toString()); .append(" is put into graveyard from battlefield").toString());
result = true; result = true;
@ -2097,6 +2103,7 @@ public abstract class GameImpl implements Game, Serializable {
MageObject preventionSource = game.getObject(source.getSourceId()); MageObject preventionSource = game.getObject(source.getSourceId());
if (damageSource != null && preventionSource != null) { if (damageSource != null && preventionSource != null) {
if (!game.isSimulation()) {
MageObject targetObject = game.getObject(event.getTargetId()); MageObject targetObject = game.getObject(event.getTargetId());
String targetName = ""; String targetName = "";
if (targetObject == null) { if (targetObject == null) {
@ -2114,6 +2121,7 @@ public abstract class GameImpl implements Game, Serializable {
} }
game.informPlayers(message.toString()); game.informPlayers(message.toString());
} }
}
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, damageEvent.getTargetId(), source.getSourceId(), source.getControllerId(), result.getPreventedDamage())); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, damageEvent.getTargetId(), source.getSourceId(), source.getControllerId(), result.getPreventedDamage()));
return result; return result;

View file

@ -215,6 +215,7 @@ public class Combat implements Serializable, Copyable<Combat> {
} }
} }
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, attackerId, attackerId)); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, attackerId, attackerId));
if (!game.isSimulation())
game.informPlayers(new StringBuilder(player.getName()).append(" attacks with ").append(groups.size()).append(groups.size() == 1 ? " creature":" creatures").toString()); game.informPlayers(new StringBuilder(player.getName()).append(" attacks with ").append(groups.size()).append(groups.size() == 1 ? " creature":" creatures").toString());
} }
@ -268,6 +269,7 @@ public class Combat implements Serializable, Copyable<Combat> {
for (UUID attackingCreatureId : group.getAttackers()) { for (UUID attackingCreatureId : group.getAttackers()) {
Permanent attacker = game.getPermanent(attackingCreatureId); Permanent attacker = game.getPermanent(attackingCreatureId);
if (count > 1 && attacker != null && attacker.getAbilities(game).containsKey(CanAttackOnlyAloneAbility.getInstance().getId())) { if (count > 1 && attacker != null && attacker.getAbilities(game).containsKey(CanAttackOnlyAloneAbility.getInstance().getId())) {
if (!game.isSimulation())
game.informPlayers(attacker.getLogName() + " can only attack alone. Removing it from combat."); game.informPlayers(attacker.getLogName() + " can only attack alone. Removing it from combat.");
tobeRemoved.add(attackingCreatureId); tobeRemoved.add(attackingCreatureId);
count--; count--;
@ -285,6 +287,7 @@ public class Combat implements Serializable, Copyable<Combat> {
for (UUID attackingCreatureId : group.getAttackers()) { for (UUID attackingCreatureId : group.getAttackers()) {
Permanent attacker = game.getPermanent(attackingCreatureId); Permanent attacker = game.getPermanent(attackingCreatureId);
if (attacker != null && attacker.getAbilities(game).containsKey(CantAttackAloneAbility.getInstance().getId())) { if (attacker != null && attacker.getAbilities(game).containsKey(CantAttackAloneAbility.getInstance().getId())) {
if (!game.isSimulation())
game.informPlayers(attacker.getLogName() + " can't attack alone. Removing it from combat."); game.informPlayers(attacker.getLogName() + " can't attack alone. Removing it from combat.");
tobeRemoved.add(attackingCreatureId); tobeRemoved.add(attackingCreatureId);
} }
@ -356,6 +359,8 @@ public class Combat implements Serializable, Copyable<Combat> {
* *
*/ */
private void logBlockerInfo(Player defender, Game game) { private void logBlockerInfo(Player defender, Game game) {
if (game.isSimulation())
return;
boolean shownDefendingPlayer = game.getPlayers().size() < 3; // only two players no ned to sow the attacked player boolean shownDefendingPlayer = game.getPlayers().size() < 3; // only two players no ned to sow the attacked player
for (CombatGroup group : this.getGroups()) { for (CombatGroup group : this.getGroups()) {
if (group.defendingPlayerId.equals(defender.getId())) { if (group.defendingPlayerId.equals(defender.getId())) {
@ -566,6 +571,7 @@ public class Combat implements Serializable, Copyable<Combat> {
// if so inform human player or set block for AI player // if so inform human player or set block for AI player
if (mayBlock) { if (mayBlock) {
if (controller.isHuman()) { if (controller.isHuman()) {
if (!game.isSimulation())
game.informPlayer(controller, "Creature should block this turn: " + creature.getLogName()); game.informPlayer(controller, "Creature should block this turn: " + creature.getLogName());
} else { } else {
Player defender = game.getPlayer(creature.getControllerId()); Player defender = game.getPlayer(creature.getControllerId());
@ -634,6 +640,7 @@ public class Combat implements Serializable, Copyable<Combat> {
} }
} }
if (possibleBlockerAvailable) { if (possibleBlockerAvailable) {
if (!game.isSimulation())
game.informPlayer(controller, new StringBuilder(toBeBlockedCreature.getLogName()).append(" has to be blocked by at least one creature.").toString()); game.informPlayer(controller, new StringBuilder(toBeBlockedCreature.getLogName()).append(" has to be blocked by at least one creature.").toString());
return false; return false;
} }
@ -697,9 +704,11 @@ public class Combat implements Serializable, Copyable<Combat> {
} }
} }
if (sb.length() > 0) { if (sb.length() > 0) {
if (!game.isSimulation()) {
sb.insert(0, "Some creatures are forced to block certain attacker(s):\n"); sb.insert(0, "Some creatures are forced to block certain attacker(s):\n");
sb.append("\nPlease block with each of these creatures an appropriate attacker."); sb.append("\nPlease block with each of these creatures an appropriate attacker.");
game.informPlayer(controller, sb.toString()); game.informPlayer(controller, sb.toString());
}
return false; return false;
} }
return true; return true;
@ -723,6 +732,7 @@ public class Combat implements Serializable, Copyable<Combat> {
for (Ability ability : entry.getValue()) { for (Ability ability : entry.getValue()) {
if (!effect.canBeBlockedCheckAfter(attackingCreature, ability, game)) { if (!effect.canBeBlockedCheckAfter(attackingCreature, ability, game)) {
if (controller.isHuman()) { if (controller.isHuman()) {
if (!game.isSimulation())
game.informPlayer(controller, new StringBuilder(attackingCreature.getLogName()).append(" can't be blocked this way.").toString()); game.informPlayer(controller, new StringBuilder(attackingCreature.getLogName()).append(" can't be blocked this way.").toString());
return false; return false;
} else { } else {
@ -839,6 +849,7 @@ public class Combat implements Serializable, Copyable<Combat> {
numberCreaturesDefenderAttackedBy.put(defendingPlayer.getId(), defenderAttackedBy); numberCreaturesDefenderAttackedBy.put(defendingPlayer.getId(), defenderAttackedBy);
} }
if (defenderAttackedBy.size() >= defendingPlayer.getMaxAttackedBy()) { if (defenderAttackedBy.size() >= defendingPlayer.getMaxAttackedBy()) {
if (!game.isSimulation()) {
Player attackingPlayer = game.getPlayer(game.getControllerId(attackerId)); Player attackingPlayer = game.getPlayer(game.getControllerId(attackerId));
if (attackingPlayer != null) { if (attackingPlayer != null) {
game.informPlayer(attackingPlayer, new StringBuilder("No more than ") game.informPlayer(attackingPlayer, new StringBuilder("No more than ")
@ -846,6 +857,7 @@ public class Combat implements Serializable, Copyable<Combat> {
.append(" creatures can attack ") .append(" creatures can attack ")
.append(defendingPlayer.getName()).toString()); .append(defendingPlayer.getName()).toString());
} }
}
return false; return false;
} }
defenderAttackedBy.add(attackerId); defenderAttackedBy.add(attackerId);

View file

@ -540,6 +540,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
Permanent blocker = game.getPermanent(blockerId); Permanent blocker = game.getPermanent(blockerId);
if (blocker != null && blocker.getAbilities(game).containsKey(CantBlockAloneAbility.getInstance().getId())) { if (blocker != null && blocker.getAbilities(game).containsKey(CantBlockAloneAbility.getInstance().getId())) {
blockWasLegal = false; blockWasLegal = false;
if (!game.isSimulation())
game.informPlayers(blocker.getLogName() + " can't block alone. Removing it from combat."); game.informPlayers(blocker.getLogName() + " can't block alone. Removing it from combat.");
toBeRemoved.add(blockerId); toBeRemoved.add(blockerId);
} }
@ -566,6 +567,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
blockers.clear(); blockers.clear();
blockerOrder.clear(); blockerOrder.clear();
this.blocked = false; this.blocked = false;
if (!game.isSimulation())
game.informPlayers(attacker.getLogName() + " can't be blocked except by " + attacker.getMinBlockedBy() + " or more creatures. Blockers discarded."); game.informPlayers(attacker.getLogName() + " can't be blocked except by " + attacker.getMinBlockedBy() + " or more creatures. Blockers discarded.");
blockWasLegal = false; blockWasLegal = false;
} }
@ -580,6 +582,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
blockers.clear(); blockers.clear();
blockerOrder.clear(); blockerOrder.clear();
this.blocked = false; this.blocked = false;
if (!game.isSimulation())
game.informPlayers(new StringBuilder(attacker.getLogName()) game.informPlayers(new StringBuilder(attacker.getLogName())
.append(" can't be blocked by more than ").append(attacker.getMaxBlockedBy()) .append(" can't be blocked by more than ").append(attacker.getMaxBlockedBy())
.append(attacker.getMaxBlockedBy()==1?" creature.":" creatures.") .append(attacker.getMaxBlockedBy()==1?" creature.":" creatures.")

View file

@ -447,6 +447,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
if (!phasedIn) { if (!phasedIn) {
if (!replaceEvent(EventType.PHASE_IN, game)) { if (!replaceEvent(EventType.PHASE_IN, game)) {
this.phasedIn = true; this.phasedIn = true;
if (!game.isSimulation())
game.informPlayers(getLogName() + " phased in"); game.informPlayers(getLogName() + " phased in");
fireEvent(EventType.PHASED_IN, game); fireEvent(EventType.PHASED_IN, game);
return true; return true;
@ -460,6 +461,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
if (phasedIn) { if (phasedIn) {
if (!replaceEvent(EventType.PHASE_OUT, game)) { if (!replaceEvent(EventType.PHASE_OUT, game)) {
this.phasedIn = false; this.phasedIn = false;
if (!game.isSimulation())
game.informPlayers(getLogName() + " phased out"); game.informPlayers(getLogName() + " phased out");
fireEvent(EventType.PHASED_OUT, game); fireEvent(EventType.PHASED_OUT, game);
return true; return true;
@ -864,6 +866,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
if (!game.replaceEvent(GameEvent.getEvent(EventType.DESTROY_PERMANENT, objectId, sourceId, controllerId, noRegen ? 1 : 0))) { if (!game.replaceEvent(GameEvent.getEvent(EventType.DESTROY_PERMANENT, objectId, sourceId, controllerId, noRegen ? 1 : 0))) {
if (moveToZone(Zone.GRAVEYARD, sourceId, game, false)) { if (moveToZone(Zone.GRAVEYARD, sourceId, game, false)) {
if (!game.isSimulation()) {
String logName; String logName;
Card card = game.getCard(this.getId()); Card card = game.getCard(this.getId());
if (card != null) { if (card != null) {
@ -876,6 +879,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
} else { } else {
game.informPlayers(logName + " was destroyed"); game.informPlayers(logName + " was destroyed");
} }
}
game.fireEvent(GameEvent.getEvent(EventType.DESTROYED_PERMANENT, objectId, sourceId, controllerId)); game.fireEvent(GameEvent.getEvent(EventType.DESTROYED_PERMANENT, objectId, sourceId, controllerId));
return true; return true;
} }
@ -889,10 +893,12 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
if (!game.replaceEvent(GameEvent.getEvent(EventType.SACRIFICE_PERMANENT, objectId, sourceId, controllerId))) { if (!game.replaceEvent(GameEvent.getEvent(EventType.SACRIFICE_PERMANENT, objectId, sourceId, controllerId))) {
// Commander replacement effect or Rest in Peace (exile instead of graveyard) in play does not prevent successful sacrifice // Commander replacement effect or Rest in Peace (exile instead of graveyard) in play does not prevent successful sacrifice
moveToZone(Zone.GRAVEYARD, sourceId, game, false); moveToZone(Zone.GRAVEYARD, sourceId, game, false);
if (!game.isSimulation()) {
Player player = game.getPlayer(getControllerId()); Player player = game.getPlayer(getControllerId());
if (player != null) { if (player != null) {
game.informPlayers(new StringBuilder(player.getName()).append(" sacrificed ").append(this.getLogName()).toString()); game.informPlayers(new StringBuilder(player.getName()).append(" sacrificed ").append(this.getLogName()).toString());
} }
}
game.fireEvent(GameEvent.getEvent(EventType.SACRIFICED_PERMANENT, objectId, sourceId, controllerId)); game.fireEvent(GameEvent.getEvent(EventType.SACRIFICED_PERMANENT, objectId, sourceId, controllerId));
return true; return true;
} }
@ -1090,6 +1096,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
public boolean removeFromCombat(Game game, boolean withInfo) { public boolean removeFromCombat(Game game, boolean withInfo) {
if (this.isAttacking() || this.blocking > 0) { if (this.isAttacking() || this.blocking > 0) {
if (game.getCombat().removeFromCombat(objectId, game) && withInfo) { if (game.getCombat().removeFromCombat(objectId, game) && withInfo) {
if (!game.isSimulation())
game.informPlayers(new StringBuilder(this.getLogName()).append(" removed from combat").toString()); game.informPlayers(new StringBuilder(this.getLogName()).append(" removed from combat").toString());
} }
} }

View file

@ -161,6 +161,7 @@ public class Token extends MageObjectImpl {
game.getCombat().addAttackingCreature(newToken.getId(), game); game.getCombat().addAttackingCreature(newToken.getId(), game);
} }
} }
if (!game.isSimulation())
game.informPlayers(new StringBuilder(controller.getName()).append(" puts ") game.informPlayers(new StringBuilder(controller.getName()).append(" puts ")
.append(CardUtil.numberToText(amount, "a")).append(" ").append(this.getName()).append(" token").append(amount==1?"":"s") .append(CardUtil.numberToText(amount, "a")).append(" ").append(this.getName()).append(" token").append(amount==1?"":"s")
.append(" onto the battlefield").toString()); .append(" onto the battlefield").toString());

View file

@ -212,6 +212,7 @@ public class Spell implements StackObject, Card {
return result; return result;
} }
//20091005 - 608.2b //20091005 - 608.2b
if (!game.isSimulation())
game.informPlayers(getName() + " has been fizzled."); game.informPlayers(getName() + " has been fizzled.");
counter(null, game); counter(null, game);
return false; return false;
@ -247,6 +248,7 @@ public class Spell implements StackObject, Card {
return result; return result;
} else { } else {
//20091005 - 608.2b //20091005 - 608.2b
if (!game.isSimulation())
game.informPlayers(getName() + " has been fizzled."); game.informPlayers(getName() + " has been fizzled.");
counter(null, game); counter(null, game);
return false; return false;
@ -377,7 +379,7 @@ public class Spell implements StackObject, Card {
} }
} }
if (newTargetDescription.length() > 0) { if (newTargetDescription.length() > 0 && !game.isSimulation()) {
game.informPlayers(this.getName() + " is now " + newTargetDescription.toString()); game.informPlayers(this.getName() + " is now " + newTargetDescription.toString());
} }
return true; return true;

View file

@ -100,9 +100,11 @@ public class SpellStack extends ArrayDeque<StackObject> {
} }
this.remove(stackObject); this.remove(stackObject);
stackObject.counter(sourceId, game); // tries to move to graveyard stackObject.counter(sourceId, game); // tries to move to graveyard
if (!game.isSimulation())
game.informPlayers(counteredObjectName + " is countered by " + sourceObject.getLogName()); game.informPlayers(counteredObjectName + " is countered by " + sourceObject.getLogName());
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COUNTERED, objectId, sourceId, stackObject.getControllerId())); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COUNTERED, objectId, sourceId, stackObject.getControllerId()));
} else { } else {
if (!game.isSimulation())
game.informPlayers(counteredObjectName + " could not be countered by " + sourceObject.getLogName()); game.informPlayers(counteredObjectName + " could not be countered by " + sourceObject.getLogName());
} }
return true; return true;

View file

@ -100,6 +100,7 @@ public class StackAbility implements StackObject, Ability {
if (ability.getTargets().stillLegal(ability, game)) { if (ability.getTargets().stillLegal(ability, game)) {
return ability.resolve(game); return ability.resolve(game);
} }
if (!game.isSimulation())
game.informPlayers("Ability has been fizzled: " + getRule()); game.informPlayers("Ability has been fizzled: " + getRule());
counter(null, game); counter(null, game);
return false; return false;

View file

@ -234,10 +234,12 @@ public class Turn implements Serializable {
} }
currentPhase = phase; currentPhase = phase;
game.fireEvent(new GameEvent(GameEvent.EventType.PHASE_CHANGED, activePlayerId, extraPhaseTurnMod.getId(), activePlayerId)); game.fireEvent(new GameEvent(GameEvent.EventType.PHASE_CHANGED, activePlayerId, extraPhaseTurnMod.getId(), activePlayerId));
if (!game.isSimulation()) {
Player activePlayer = game.getPlayer(activePlayerId); Player activePlayer = game.getPlayer(activePlayerId);
if (activePlayer != null) { if (activePlayer != null) {
game.informPlayers(new StringBuilder(activePlayer.getName()).append(" starts an additional ").append(phase.getType().toString()).append(" phase").toString()); game.informPlayers(new StringBuilder(activePlayer.getName()).append(" starts an additional ").append(phase.getType().toString()).append(" phase").toString());
} }
}
phase.play(game, activePlayerId); phase.play(game, activePlayerId);
return true; return true;

View file

@ -642,6 +642,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public void discardToMax(Game game) { public void discardToMax(Game game) {
if (hand.size() > this.maxHandSize) { if (hand.size() > this.maxHandSize) {
if (!game.isSimulation())
game.informPlayers(new StringBuilder(getName()).append(" discards down to ").append(this.maxHandSize).append(this.maxHandSize == 1?" hand card":" hand cards").toString()); game.informPlayers(new StringBuilder(getName()).append(" discards down to ").append(this.maxHandSize).append(this.maxHandSize == 1?" hand card":" hand cards").toString());
discard(hand.size() - this.maxHandSize, null, game); discard(hand.size() - this.maxHandSize, null, game);
} }
@ -733,6 +734,7 @@ public abstract class PlayerImpl implements Player, Serializable {
*/ */
if (card != null) { if (card != null) {
// write info to game log first so game log infos from triggered or replacement effects follow in the game log // write info to game log first so game log infos from triggered or replacement effects follow in the game log
if (!game.isSimulation())
game.informPlayers(new StringBuilder(name).append(" discards ").append(card.getName()).toString()); game.informPlayers(new StringBuilder(name).append(" discards ").append(card.getName()).toString());
/* If a card is discarded while Rest in Peace is on the battlefield, abilities that function /* If a card is discarded while Rest in Peace is on the battlefield, abilities that function
* when a card is discarded (such as madness) still work, even though that card never reaches * when a card is discarded (such as madness) still work, even though that card never reaches
@ -936,6 +938,7 @@ public abstract class PlayerImpl implements Player, Serializable {
GameEvent event = GameEvent.getEvent(GameEvent.EventType.SPELL_CAST, spell.getSpellAbility().getId(), spell.getSpellAbility().getSourceId(), playerId); GameEvent event = GameEvent.getEvent(GameEvent.EventType.SPELL_CAST, spell.getSpellAbility().getId(), spell.getSpellAbility().getSourceId(), playerId);
event.setZone(fromZone); event.setZone(fromZone);
game.fireEvent(event); game.fireEvent(event);
if (!game.isSimulation())
game.informPlayers(new StringBuilder(name).append(spell.getActivatedMessage(game)).toString()); game.informPlayers(new StringBuilder(name).append(spell.getActivatedMessage(game)).toString());
game.removeBookmark(bookmark); game.removeBookmark(bookmark);
resetStoredBookmark(game); resetStoredBookmark(game);
@ -987,6 +990,7 @@ public abstract class PlayerImpl implements Player, Serializable {
if (card.putOntoBattlefield(game, zone, null, playerId)) { if (card.putOntoBattlefield(game, zone, null, playerId)) {
landsPlayed++; landsPlayed++;
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED, card.getId(), card.getId(), playerId)); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED, card.getId(), card.getId(), playerId));
if (!game.isSimulation())
game.fireInformEvent(name + " plays " + card.getName()); game.fireInformEvent(name + " plays " + card.getName());
// game.removeBookmark(bookmark); // game.removeBookmark(bookmark);
resetStoredBookmark(game); resetStoredBookmark(game);
@ -1025,6 +1029,7 @@ public abstract class PlayerImpl implements Player, Serializable {
game.getStack().push(new StackAbility(ability, playerId)); game.getStack().push(new StackAbility(ability, playerId));
if (ability.activate(game, false)) { if (ability.activate(game, false)) {
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ACTIVATED_ABILITY, ability.getId(), ability.getSourceId(), playerId)); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ACTIVATED_ABILITY, ability.getId(), ability.getSourceId(), playerId));
if (!game.isSimulation())
game.informPlayers(new StringBuilder(name).append(ability.getGameLogMessage(game)).toString()); game.informPlayers(new StringBuilder(name).append(ability.getGameLogMessage(game)).toString());
game.removeBookmark(bookmark); game.removeBookmark(bookmark);
resetStoredBookmark(game); resetStoredBookmark(game);
@ -1051,6 +1056,7 @@ public abstract class PlayerImpl implements Player, Serializable {
int bookmark = game.bookmarkState(); int bookmark = game.bookmarkState();
if (action.activate(game, false)) { if (action.activate(game, false)) {
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ACTIVATED_ABILITY, action.getSourceId(), action.getId(), playerId)); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ACTIVATED_ABILITY, action.getSourceId(), action.getId(), playerId));
if (!game.isSimulation())
game.informPlayers(new StringBuilder(name).append(action.getGameLogMessage(game)).toString()); game.informPlayers(new StringBuilder(name).append(action.getGameLogMessage(game)).toString());
if (action.resolve(game)) { if (action.resolve(game)) {
game.removeBookmark(bookmark); game.removeBookmark(bookmark);
@ -1119,6 +1125,7 @@ public abstract class PlayerImpl implements Player, Serializable {
} }
if (ability.activate(game, false)) { if (ability.activate(game, false)) {
if (ability.isUsesStack() || ability.getRuleVisible()) { if (ability.isUsesStack() || ability.getRuleVisible()) {
if (!game.isSimulation())
game.informPlayers(ability.getGameLogMessage(game)); game.informPlayers(ability.getGameLogMessage(game));
} }
if (!ability.isUsesStack()) { if (!ability.isUsesStack()) {
@ -1272,6 +1279,7 @@ public abstract class PlayerImpl implements Player, Serializable {
public void shuffleLibrary(Game game) { public void shuffleLibrary(Game game) {
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.SHUFFLE_LIBRARY, playerId, playerId))) { if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.SHUFFLE_LIBRARY, playerId, playerId))) {
this.library.shuffle(); this.library.shuffle();
if (!game.isSimulation())
game.informPlayers(new StringBuilder(this.name).append(" shuffles his or her library.").toString()); game.informPlayers(new StringBuilder(this.name).append(" shuffles his or her library.").toString());
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LIBRARY_SHUFFLED, playerId, playerId)); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LIBRARY_SHUFFLED, playerId, playerId));
} }
@ -1285,7 +1293,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public void revealCards(String name, Cards cards, Game game, boolean postToLog) { public void revealCards(String name, Cards cards, Game game, boolean postToLog) {
game.getState().getRevealed().add(name, cards); game.getState().getRevealed().add(name, cards);
if (postToLog) { if (postToLog && !game.isSimulation()) {
StringBuilder sb = new StringBuilder(this.getName()).append(" reveals "); StringBuilder sb = new StringBuilder(this.getName()).append(" reveals ");
int current = 0, last = cards.size(); int current = 0, last = cards.size();
for (Card card :cards.getCards(game)) { for (Card card :cards.getCards(game)) {
@ -1412,9 +1420,11 @@ public abstract class PlayerImpl implements Player, Serializable {
} while (isInGame() && playerCanceledSelection); } while (isInGame() && playerCanceledSelection);
// show in log which permanents were selected to untap // show in log which permanents were selected to untap
if (!game.isSimulation()) {
for(Permanent permanent :selectedToUntap) { for(Permanent permanent :selectedToUntap) {
game.informPlayers(new StringBuilder(this.getName()).append(" untapped ").append(permanent.getName()).toString()); game.informPlayers(new StringBuilder(this.getName()).append(" untapped ").append(permanent.getName()).toString());
} }
}
// untap if permanent is not concerned by notMoreThan effects or is included in the selectedToUntapList // untap if permanent is not concerned by notMoreThan effects or is included in the selectedToUntapList
for (Permanent permanent: canBeUntapped) { for (Permanent permanent: canBeUntapped) {
boolean doUntap = true; boolean doUntap = true;
@ -1563,6 +1573,7 @@ public abstract class PlayerImpl implements Player, Serializable {
GameEvent event = new GameEvent(GameEvent.EventType.LOSE_LIFE, playerId, playerId, playerId, amount, false); GameEvent event = new GameEvent(GameEvent.EventType.LOSE_LIFE, playerId, playerId, playerId, amount, false);
if (!game.replaceEvent(event)) { if (!game.replaceEvent(event)) {
this.life -= event.getAmount(); this.life -= event.getAmount();
if (!game.isSimulation())
game.informPlayers(new StringBuilder(this.getName()).append(" loses ").append(event.getAmount()).append(" life").toString()); game.informPlayers(new StringBuilder(this.getName()).append(" loses ").append(event.getAmount()).append(" life").toString());
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LOST_LIFE, playerId, playerId, playerId, amount)); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LOST_LIFE, playerId, playerId, playerId, amount));
return amount; return amount;
@ -1588,6 +1599,7 @@ public abstract class PlayerImpl implements Player, Serializable {
GameEvent event = new GameEvent(GameEvent.EventType.GAIN_LIFE, playerId, playerId, playerId, amount, false); GameEvent event = new GameEvent(GameEvent.EventType.GAIN_LIFE, playerId, playerId, playerId, amount, false);
if (!game.replaceEvent(event)) { if (!game.replaceEvent(event)) {
this.life += event.getAmount(); this.life += event.getAmount();
if (!game.isSimulation())
game.informPlayers(new StringBuilder(this.getName()).append(" gains ").append(event.getAmount()).append(" life").toString()); game.informPlayers(new StringBuilder(this.getName()).append(" gains ").append(event.getAmount()).append(" life").toString());
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.GAINED_LIFE, playerId, playerId, playerId, event.getAmount())); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.GAINED_LIFE, playerId, playerId, playerId, event.getAmount()));
return event.getAmount(); return event.getAmount();
@ -1759,6 +1771,7 @@ public abstract class PlayerImpl implements Player, Serializable {
quit = true; quit = true;
this.concede(game); this.concede(game);
logger.debug(getName() + " quits the match."); logger.debug(getName() + " quits the match.");
if (!game.isSimulation())
game.informPlayers(getName() + " quits the match."); game.informPlayers(getName() + " quits the match.");
} }
@ -1767,6 +1780,7 @@ public abstract class PlayerImpl implements Player, Serializable {
quit = true; quit = true;
timerTimeout = true; timerTimeout = true;
this.concede(game); this.concede(game);
if (!game.isSimulation())
game.informPlayers(getName() + " has run out of time. Loosing the Match."); game.informPlayers(getName() + " has run out of time. Loosing the Match.");
} }
@ -1775,6 +1789,7 @@ public abstract class PlayerImpl implements Player, Serializable {
quit = true; quit = true;
idleTimeout = true; idleTimeout = true;
this.concede(game); this.concede(game);
if (!game.isSimulation())
game.informPlayers(new StringBuilder(getName()).append(" was idle for too long. Loosing the Match.").toString()); game.informPlayers(new StringBuilder(getName()).append(" was idle for too long. Loosing the Match.").toString());
} }
@ -1879,6 +1894,7 @@ public abstract class PlayerImpl implements Player, Serializable {
if (!this.wins) { if (!this.wins) {
this.loses = true; this.loses = true;
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LOST, null, null, playerId)); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LOST, null, null, playerId));
if (!game.isSimulation())
game.informPlayers(this.getName()+ " has lost the game."); game.informPlayers(this.getName()+ " has lost the game.");
} else { } else {
logger.debug(this.getName() + " has already won - stop lost"); logger.debug(this.getName() + " has already won - stop lost");
@ -1919,6 +1935,7 @@ public abstract class PlayerImpl implements Player, Serializable {
} }
if (opponentsAlive == 0 && !hasWon()) { if (opponentsAlive == 0 && !hasWon()) {
logger.debug("player won -> No more opponents alive game won: " + this.getName()); logger.debug("player won -> No more opponents alive game won: " + this.getName());
if (!game.isSimulation())
game.informPlayers(new StringBuilder(this.getName()).append(" has won the game").toString()); game.informPlayers(new StringBuilder(this.getName()).append(" has won the game").toString());
this.wins = true; this.wins = true;
game.end(); game.end();
@ -1985,11 +2002,13 @@ public abstract class PlayerImpl implements Player, Serializable {
//20091005 - 701.14c //20091005 - 701.14c
Library searchedLibrary = null; Library searchedLibrary = null;
if (targetPlayerId.equals(playerId)) { if (targetPlayerId.equals(playerId)) {
if (!game.isSimulation())
game.informPlayers(new StringBuilder(getName()).append(" searches his or her library").toString()); game.informPlayers(new StringBuilder(getName()).append(" searches his or her library").toString());
searchedLibrary = library; searchedLibrary = library;
} else { } else {
Player targetPlayer = game.getPlayer(targetPlayerId); Player targetPlayer = game.getPlayer(targetPlayerId);
if (targetPlayer != null) { if (targetPlayer != null) {
if (!game.isSimulation())
game.informPlayers(new StringBuilder(getName()).append(" searches the library of ").append(targetPlayer.getName()).toString()); game.informPlayers(new StringBuilder(getName()).append(" searches the library of ").append(targetPlayer.getName()).toString());
searchedLibrary = targetPlayer.getLibrary(); searchedLibrary = targetPlayer.getLibrary();
} }
@ -2039,6 +2058,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean flipCoin(Game game, ArrayList<UUID> appliedEffects) { public boolean flipCoin(Game game, ArrayList<UUID> appliedEffects) {
boolean result = rnd.nextBoolean(); boolean result = rnd.nextBoolean();
if (!game.isSimulation())
game.informPlayers("[Flip a coin] " + getName() + (result ? " won (head)." : " lost (tail).")); game.informPlayers("[Flip a coin] " + getName() + (result ? " won (head)." : " lost (tail)."));
GameEvent event = new GameEvent(GameEvent.EventType.FLIP_COIN, playerId, null, playerId, 0, result); GameEvent event = new GameEvent(GameEvent.EventType.FLIP_COIN, playerId, null, playerId, 0, result);
event.setAppliedEffects(appliedEffects); event.setAppliedEffects(appliedEffects);
@ -2726,6 +2746,7 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, Zone fromZone) { public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, Zone fromZone) {
boolean result = false; boolean result = false;
if (card.moveToZone(Zone.HAND, sourceId, game, false)) { if (card.moveToZone(Zone.HAND, sourceId, game, false)) {
if (!game.isSimulation()) {
if (card instanceof PermanentCard) { if (card instanceof PermanentCard) {
card = game.getCard(card.getId()); card = game.getCard(card.getId());
} }
@ -2733,6 +2754,7 @@ public abstract class PlayerImpl implements Player, Serializable {
.append(" puts ").append(card.getLogName()).append(" ") .append(" puts ").append(card.getLogName()).append(" ")
.append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" "):"") .append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" "):"")
.append(card.getOwnerId().equals(this.getId()) ? "into his or her hand":"into its owner's hand").toString()); .append(card.getOwnerId().equals(this.getId()) ? "into his or her hand":"into its owner's hand").toString());
}
result = true; result = true;
} }
return result; return result;
@ -2742,6 +2764,7 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean moveCardToGraveyardWithInfo(Card card, UUID sourceId, Game game, Zone fromZone) { public boolean moveCardToGraveyardWithInfo(Card card, UUID sourceId, Game game, Zone fromZone) {
boolean result = false; boolean result = false;
if (card.moveToZone(Zone.GRAVEYARD, sourceId, game, fromZone != null ? fromZone.equals(Zone.BATTLEFIELD) : false)) { if (card.moveToZone(Zone.GRAVEYARD, sourceId, game, fromZone != null ? fromZone.equals(Zone.BATTLEFIELD) : false)) {
if (!game.isSimulation()) {
if (card instanceof PermanentCard) { if (card instanceof PermanentCard) {
card = game.getCard(card.getId()); card = game.getCard(card.getId());
} }
@ -2754,6 +2777,7 @@ public abstract class PlayerImpl implements Player, Serializable {
sb.append("it into its owner's graveyard"); sb.append("it into its owner's graveyard");
} }
game.informPlayers(sb.toString()); game.informPlayers(sb.toString());
}
result = true; result = true;
} }
return result; return result;
@ -2763,6 +2787,7 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId, Game game, Zone fromZone, boolean toTop, boolean withName) { public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId, Game game, Zone fromZone, boolean toTop, boolean withName) {
boolean result = false; boolean result = false;
if (card.moveToZone(Zone.LIBRARY, sourceId, game, toTop)) { if (card.moveToZone(Zone.LIBRARY, sourceId, game, toTop)) {
if (!game.isSimulation()) {
if (card instanceof PermanentCard) { if (card instanceof PermanentCard) {
card = game.getCard(card.getId()); card = game.getCard(card.getId());
} }
@ -2785,6 +2810,7 @@ public abstract class PlayerImpl implements Player, Serializable {
} }
} }
game.informPlayers(sb.toString()); game.informPlayers(sb.toString());
}
result = true; result = true;
} }
return result; return result;
@ -2794,6 +2820,7 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean moveCardToExileWithInfo(Card card, UUID exileId, String exileName, UUID sourceId, Game game, Zone fromZone) { public boolean moveCardToExileWithInfo(Card card, UUID exileId, String exileName, UUID sourceId, Game game, Zone fromZone) {
boolean result = false; boolean result = false;
if (card.moveToExile(exileId, exileName, sourceId, game)) { if (card.moveToExile(exileId, exileName, sourceId, game)) {
if (!game.isSimulation()) {
if (card instanceof PermanentCard) { if (card instanceof PermanentCard) {
card = game.getCard(card.getId()); card = game.getCard(card.getId());
} }
@ -2801,6 +2828,7 @@ public abstract class PlayerImpl implements Player, Serializable {
.append(" moves ").append(card.getLogName()).append(" ") .append(" moves ").append(card.getLogName()).append(" ")
.append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" "):"") .append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" "):"")
.append("to exile").toString()); .append("to exile").toString());
}
result = true; result = true;
} }
return result; return result;
@ -2815,6 +2843,7 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped) { public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped) {
boolean result = false; boolean result = false;
if (card.putOntoBattlefield(game, fromZone, sourceId, this.getId(), tapped)) { if (card.putOntoBattlefield(game, fromZone, sourceId, this.getId(), tapped)) {
if (!game.isSimulation())
game.informPlayers(new StringBuilder(this.getName()) game.informPlayers(new StringBuilder(this.getName())
.append(" puts ").append(card.getLogName()) .append(" puts ").append(card.getLogName())
.append(" from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ") .append(" from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ")

View file

@ -93,7 +93,7 @@ public class TargetSource extends TargetObject {
else { else {
addTarget(id, source, game, notTarget); addTarget(id, source, game, notTarget);
} }
if (object != null) { if (object != null && !game.isSimulation()) {
game.informPlayers("Selected " + object.getLogName() + " as source"); game.informPlayers("Selected " + object.getLogName() + " as source");
} }
} }

View file

@ -84,6 +84,7 @@ public class CommanderCombatDamageWatcher extends Watcher {
Player player = game.getPlayer(playerUUID); Player player = game.getPlayer(playerUUID);
MageObject commander = game.getObject(sourceId); MageObject commander = game.getObject(sourceId);
if (player != null && commander != null){ if (player != null && commander != null){
if (!game.isSimulation())
game.informPlayers(commander.getLogName() + " did " + damage + " combat damage to " + player.getName() + " during the game."); game.informPlayers(commander.getLogName() + " did " + damage + " combat damage to " + player.getName() + " during the game.");
this.addCardInfoToCommander(game); this.addCardInfoToCommander(game);
} }

View file

@ -88,6 +88,7 @@ public class SoulbondWatcher extends Watcher {
if (chosen != null) { if (chosen != null) {
chosen.setPairedCard(permanent.getId()); chosen.setPairedCard(permanent.getId());
permanent.setPairedCard(chosen.getId()); permanent.setPairedCard(chosen.getId());
if (!game.isSimulation())
game.informPlayers(new StringBuilder(controller.getName()).append(" souldbonds ").append(permanent.getLogName()).append(" with ").append(chosen.getName()).toString()); game.informPlayers(new StringBuilder(controller.getName()).append(" souldbonds ").append(permanent.getLogName()).append(" with ").append(chosen.getName()).toString());
} }
} }
@ -112,6 +113,7 @@ public class SoulbondWatcher extends Watcher {
if (controller.chooseUse(Outcome.Benefit, "Use Soulbond for recent " + permanent.getLogName() + "?", game)) { if (controller.chooseUse(Outcome.Benefit, "Use Soulbond for recent " + permanent.getLogName() + "?", game)) {
chosen.setPairedCard(permanent.getId()); chosen.setPairedCard(permanent.getId());
permanent.setPairedCard(chosen.getId()); permanent.setPairedCard(chosen.getId());
if (!game.isSimulation())
game.informPlayers(new StringBuilder(controller.getName()).append(" souldbonds ").append(permanent.getLogName()).append(" with ").append(chosen.getName()).toString()); game.informPlayers(new StringBuilder(controller.getName()).append(" souldbonds ").append(permanent.getLogName()).append(" with ").append(chosen.getName()).toString());
break; break;
} }