added optimization for simulations - don't construct Strings for messages that will never be used

This commit is contained in:
betasteward 2015-03-31 09:44:22 -04:00
parent 9f834bc6f7
commit a878d4879b
67 changed files with 313 additions and 205 deletions

View file

@ -312,7 +312,7 @@ public abstract class AbilityImpl implements Ability {
sourceObject.adjustTargets(this, game);
}
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) && !game.isSimulation()) {
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
@ -370,13 +370,15 @@ public abstract class AbilityImpl implements Ability {
logger.debug("activate failed - non mana costs");
return false;
}
// inform about x costs now, so canceled announcements are not shown in the log
if (announceString != null) {
game.informPlayers(announceString);
}
if (variableManaCost != null) {
int xValue = getManaCostsToPay().getX();
game.informPlayers(new StringBuilder(controller.getName()).append(" announces a value of ").append(xValue).append(" for ").append(variableManaCost.getText()).toString());
if (!game.isSimulation()) {
// inform about x costs now, so canceled announcements are not shown in the log
if (announceString != null) {
game.informPlayers(announceString);
}
if (variableManaCost != null) {
int xValue = getManaCostsToPay().getX();
game.informPlayers(new StringBuilder(controller.getName()).append(" announces a value of ").append(xValue).append(" for ").append(variableManaCost.getText()).toString());
}
}
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

View file

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

View file

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

View file

@ -668,11 +668,11 @@ public class ContinuousEffects implements Serializable {
if (message != null && !message.isEmpty()) {
if (effect.sendMessageToUser()) {
Player player = game.getPlayer(event.getPlayerId());
if (player != null) {
if (player != null && !game.isSimulation()) {
game.informPlayer(player, message);
}
}
if (effect.sendMessageToGameLog()) {
if (effect.sendMessageToGameLog() && !game.isSimulation()) {
game.informPlayers(message);
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -132,17 +132,18 @@ public class ClashEffect extends OneShotEffect implements MageSingleton {
message.append(" no card");
}
message.append(" - ");
if (cmcController > cmcOpponent) {
message.append(controller.getName()).append(" won the clash");
game.informPlayer(controller, "You won the clash!");
} else if (cmcController < cmcOpponent) {
message.append(opponent.getName()).append(" won the clash");
game.informPlayer(controller, opponent.getName() + " won the clash!");
} else {
message.append(" no winner ");
}
game.informPlayers(message.toString());
if (!game.isSimulation()) {
if (cmcController > cmcOpponent) {
message.append(controller.getName()).append(" won the clash");
game.informPlayer(controller, "You won the clash!");
} else if (cmcController < cmcOpponent) {
message.append(opponent.getName()).append(" won the clash");
game.informPlayer(controller, opponent.getName() + " won the clash!");
} else {
message.append(" no winner ");
}
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
PlayerList playerList = game.getPlayerList().copy();
playerList.setCurrent(game.getActivePlayerId());

View file

@ -69,7 +69,8 @@ public class CopyTargetSpellEffect extends OneShotEffect {
if (activateMessage.startsWith(" casts ")) {
activateMessage = activateMessage.substring(6);
}
game.informPlayers(player.getName() + " copies " + activateMessage);
if (!game.isSimulation())
game.informPlayers(player.getName() + " copies " + activateMessage);
return true;
}
return false;

View file

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

View file

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

View file

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

View file

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

View file

@ -46,7 +46,8 @@ public class EndTurnEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
game.informPlayers("The current turn ends");
if (!game.isSimulation())
game.informPlayers("The current turn ends");
return game.endTurn();
}

View file

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

View file

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

View file

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

View file

@ -74,7 +74,7 @@ public class HideawayPlayEffect extends OneShotEffect {
card.setFaceDown(false, game);
return controller.playLand(card, game);
}
} else {
} else if (!game.isSimulation()) {
game.informPlayer(controller, "You're not able to play the land now due to regular restrictions.");
}
} else {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -80,10 +80,12 @@ public class TransformSourceEffect extends OneShotEffect {
} else {
permanent.transform(game);
}
if (fromDayToNight) {
game.informPlayers(new StringBuilder(permanent.getName()).append(" transforms into ").append(permanent.getSecondCardFace().getName()).toString());
} else {
game.informPlayers(new StringBuilder(permanent.getSecondCardFace().getName()).append(" transforms into ").append(permanent.getName()).toString());
if (!game.isSimulation()) {
if (fromDayToNight) {
game.informPlayers(new StringBuilder(permanent.getName()).append(" transforms into ").append(permanent.getSecondCardFace().getName()).toString());
} else {
game.informPlayers(new StringBuilder(permanent.getSecondCardFace().getName()).append(" transforms into ").append(permanent.getName()).toString());
}
}
}
}

View file

@ -81,7 +81,8 @@ public class BecomesColorOrColorsTargetEffect extends OneShotEffect {
if (!controller.isInGame()) {
return false;
}
game.informPlayers(target.getName() + ": " + controller.getName() + " has chosen " + choiceColor.getChoice());
if (!game.isSimulation())
game.informPlayers(target.getName() + ": " + controller.getName() + " has chosen " + choiceColor.getChoice());
if (choiceColor.getColor().isBlack()) {
sb.append("B");
} else if (choiceColor.getColor().isBlue()) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -98,7 +98,7 @@ public class SearchLibraryPutOnLibraryEffect extends SearchEffect {
if (forceShuffle) {
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");
}
for (Card card: cards) {

View file

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

View file

@ -251,7 +251,8 @@ class ConvokeEffect extends OneShotEffect {
manaPool.unlockManaType(ManaType.COLORLESS);
manaName = "colorless";
}
game.informPlayers("Convoke: " + controller.getName() + " taps " + perm.getLogName() + " to pay one " + manaName + " mana");
if (!game.isSimulation())
game.informPlayers("Convoke: " + controller.getName() + " taps " + perm.getLogName() + " to pay one " + manaName + " mana");
}
}

View file

@ -99,7 +99,8 @@ class DredgeEffect extends ReplacementEffectImpl {
if (player != null && player.getLibrary().size() >= amount
&& player.chooseUse(outcome, new StringBuilder("Dredge ").append(sourceCard.getName()).
append("? (").append(amount).append(" cards go from top of library to graveyard)").toString(), game)) {
game.informPlayers(new StringBuilder(player.getName()).append(" dreges ").append(sourceCard.getName()).toString());
if (!game.isSimulation())
game.informPlayers(new StringBuilder(player.getName()).append(" dreges ").append(sourceCard.getName()).toString());
Cards cardsToGrave = new CardsImpl();
cardsToGrave.addAll(player.getLibrary().getTopCards(game, amount));
player.moveCardsToGraveyardWithInfo(cardsToGrave, source, game, Zone.LIBRARY);

View file

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

View file

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

View file

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

View file

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

View file

@ -218,7 +218,8 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
// 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);
// kicker variable X costs handled internally as multikicker with {1} cost (no multikicker on card)
game.informPlayers(new StringBuilder(game.getPlayer(this.controllerId).getName()).append(" announced a value of ").append(xManaValue).append(" for ").append(" kicker X ").toString());
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());
ability.getManaCostsToPay().add(new GenericManaCost(xManaValue));
} else {
ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy());

View file

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

View file

@ -104,7 +104,8 @@ class StormEffect extends OneShotEffect {
int stormCount = watcher.getSpellOrder(spell, game) - 1;
if (stormCount > 0) {
game.informPlayers("Storm: " + spell.getName() + " will be copied " + stormCount + " time" + (stormCount > 1 ?"s":""));
if (!game.isSimulation())
game.informPlayers("Storm: " + spell.getName() + " will be copied " + stormCount + " time" + (stormCount > 1 ?"s":""));
for (int i = 0; i < stormCount; i++) {
Spell copy = spell.copySpell();
copy.setControllerId(source.getControllerId());

View file

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

View file

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

View file

@ -119,11 +119,13 @@ class TributeEffect extends OneShotEffect {
sb.append(" (add ").append(CardUtil.numberToText(tributeValue)).append(" +1/+1 counter");
sb.append(tributeValue > 1 ? "s":"").append(" to it)?");
if (opponent.chooseUse(outcome, sb.toString(), game)) {
game.informPlayers(new StringBuilder(opponent.getName()).append(" pays tribute to ").append(sourcePermanent.getName()).toString());
if (!game.isSimulation())
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");
return new AddCountersSourceEffect(CounterType.P1P1.createInstance(tributeValue), true).apply(game, source);
} else {
game.informPlayers(new StringBuilder(opponent.getName()).append(" does not pay tribute to ").append(sourcePermanent.getName()).toString());
if (!game.isSimulation())
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");
}
return true;

View file

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

View file

@ -31,7 +31,8 @@ public class MageLoseGameAction extends MageAction {
if (oldLosingPlayer == null && player.canLose(game)) {
setScore(player, ArtificialScoringSystem.inst.getLoseGameScore(game));
game.setLosingPlayer(player);
game.informPlayer(player, reason);
if (!game.isSimulation())
game.informPlayer(player, reason);
}
return 0;
}

View file

@ -695,7 +695,8 @@ public abstract class GameImpl implements Game, Serializable {
if (extraPlayer != null && extraPlayer.isInGame()) {
state.setExtraTurn(true);
state.setTurnId(extraTurn.getId());
informPlayers(extraPlayer.getName() + " takes an extra turn");
if (!this.isSimulation())
informPlayers(extraPlayer.getName() + " takes an extra turn");
playTurn(extraPlayer);
state.setTurnNum(state.getTurnNum() + 1);
}
@ -820,7 +821,7 @@ public abstract class GameImpl implements Game, Serializable {
}
message.append(" takes the first turn");
this.informPlayers(message.toString());
this.informPlayers(message.toString());
} else {
// not possible to choose starting player, stop here
return;
@ -1704,7 +1705,8 @@ public abstract class GameImpl implements Game, Serializable {
private boolean movePermanentToGraveyardWithInfo(Permanent permanent) {
boolean result = false;
if (permanent.moveToZone(Zone.GRAVEYARD, null, this, false)) {
this.informPlayers(new StringBuilder(permanent.getLogName())
if (!this.isSimulation())
this.informPlayers(new StringBuilder(permanent.getLogName())
.append(" is put into graveyard from battlefield").toString());
result = true;
}
@ -2113,12 +2115,14 @@ public abstract class GameImpl implements Game, Serializable {
} else {
targetName = targetObject.getLogName();
}
StringBuilder message = new StringBuilder(preventionSource.getLogName()).append(": Prevented ");
message.append(Integer.toString(result.getPreventedDamage())).append(" damage from ").append(damageSource.getName());
if (!targetName.isEmpty()) {
message.append(" to ").append(targetName);
if (!game.isSimulation()) {
StringBuilder message = new StringBuilder(preventionSource.getLogName()).append(": Prevented ");
message.append(Integer.toString(result.getPreventedDamage())).append(" damage from ").append(damageSource.getName());
if (!targetName.isEmpty()) {
message.append(" to ").append(targetName);
}
game.informPlayers(message.toString());
}
game.informPlayers(message.toString());
}
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, damageEvent.getTargetId(), source.getSourceId(), source.getControllerId(), result.getPreventedDamage()));
return result;

View file

@ -229,7 +229,8 @@ public class Combat implements Serializable, Copyable<Combat> {
}
}
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, attackerId, attackerId));
game.informPlayers(new StringBuilder(player.getName()).append(" attacks with ").append(groups.size()).append(groups.size() == 1 ? " creature":" creatures").toString());
if (!game.isSimulation())
game.informPlayers(new StringBuilder(player.getName()).append(" attacks with ").append(groups.size()).append(groups.size() == 1 ? " creature":" creatures").toString());
}
protected void checkAttackRequirements(Player player, Game game) {
@ -282,7 +283,8 @@ public class Combat implements Serializable, Copyable<Combat> {
for (UUID attackingCreatureId : group.getAttackers()) {
Permanent attacker = game.getPermanent(attackingCreatureId);
if (count > 1 && attacker != null && attacker.getAbilities().containsKey(CanAttackOnlyAloneAbility.getInstance().getId())) {
game.informPlayers(attacker.getLogName() + " can only attack alone. Removing it from combat.");
if (!game.isSimulation())
game.informPlayers(attacker.getLogName() + " can only attack alone. Removing it from combat.");
tobeRemoved.add(attackingCreatureId);
count--;
}
@ -299,7 +301,8 @@ public class Combat implements Serializable, Copyable<Combat> {
for (UUID attackingCreatureId : group.getAttackers()) {
Permanent attacker = game.getPermanent(attackingCreatureId);
if (attacker != null && attacker.getAbilities().containsKey(CantAttackAloneAbility.getInstance().getId())) {
game.informPlayers(attacker.getLogName() + " can't attack alone. Removing it from combat.");
if (!game.isSimulation())
game.informPlayers(attacker.getLogName() + " can't attack alone. Removing it from combat.");
tobeRemoved.add(attackingCreatureId);
}
}
@ -357,7 +360,8 @@ public class Combat implements Serializable, Copyable<Combat> {
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, defenderId, defenderId));
// add info about attacker blocked by blocker to the game log
this.logBlockerInfo(defender, game);
if (!game.isSimulation())
this.logBlockerInfo(defender, game);
}
}
// tool to catch the bug about flyers blocked by non flyers or intimidate blocked by creatures with other colors
@ -597,7 +601,9 @@ public class Combat implements Serializable, Copyable<Combat> {
// if so inform human player or set block for AI player
if (mayBlock) {
if (controller.isHuman()) {
game.informPlayer(controller, "Creature should block this turn: " + creature.getLogName());
if (!game.isSimulation()) {
game.informPlayer(controller, "Creature should block this turn: " + creature.getLogName());
}
} else {
Player defender = game.getPlayer(creature.getControllerId());
if (defender != null) {
@ -665,7 +671,8 @@ public class Combat implements Serializable, Copyable<Combat> {
}
}
if (possibleBlockerAvailable) {
game.informPlayer(controller, new StringBuilder(toBeBlockedCreature.getLogName()).append(" has to be blocked by at least one creature.").toString());
if (!game.isSimulation())
game.informPlayer(controller, new StringBuilder(toBeBlockedCreature.getLogName()).append(" has to be blocked by at least one creature.").toString());
return false;
}
}
@ -728,9 +735,11 @@ public class Combat implements Serializable, Copyable<Combat> {
}
}
if (sb.length() > 0) {
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.");
game.informPlayer(controller, sb.toString());
if (!game.isSimulation()) {
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.");
game.informPlayer(controller, sb.toString());
}
return false;
}
return true;
@ -871,7 +880,7 @@ public class Combat implements Serializable, Copyable<Combat> {
}
if (defenderAttackedBy.size() >= defendingPlayer.getMaxAttackedBy()) {
Player attackingPlayer = game.getPlayer(game.getControllerId(attackerId));
if (attackingPlayer != null) {
if (attackingPlayer != null && !game.isSimulation()) {
game.informPlayer(attackingPlayer, new StringBuilder("No more than ")
.append(CardUtil.numberToText(defendingPlayer.getMaxAttackedBy()))
.append(" creatures can attack ")

View file

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

View file

@ -508,7 +508,8 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
if (!phasedIn) {
if (!replaceEvent(EventType.PHASE_IN, game)) {
this.phasedIn = true;
game.informPlayers(getLogName() + " phased in");
if (!game.isSimulation())
game.informPlayers(getLogName() + " phased in");
fireEvent(EventType.PHASED_IN, game);
return true;
}
@ -521,7 +522,8 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
if (phasedIn) {
if (!replaceEvent(EventType.PHASE_OUT, game)) {
this.phasedIn = false;
game.informPlayers(getLogName() + " phased out");
if (!game.isSimulation())
game.informPlayers(getLogName() + " phased out");
fireEvent(EventType.PHASED_OUT, game);
return true;
}
@ -955,17 +957,19 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
if (!game.replaceEvent(GameEvent.getEvent(EventType.DESTROY_PERMANENT, objectId, sourceId, controllerId, noRegen ? 1 : 0))) {
if (moveToZone(Zone.GRAVEYARD, sourceId, game, false)) {
String logName;
Card card = game.getCard(this.getId());
if (card != null) {
logName = card.getLogName();
} else {
logName = this.getLogName();
}
if (this.getCardType().contains(CardType.CREATURE)) {
game.informPlayers(logName +" died");
} else {
game.informPlayers(logName + " was destroyed");
if (!game.isSimulation()) {
String logName;
Card card = game.getCard(this.getId());
if (card != null) {
logName = card.getLogName();
} else {
logName = this.getLogName();
}
if (this.getCardType().contains(CardType.CREATURE)) {
game.informPlayers(logName +" died");
} else {
game.informPlayers(logName + " was destroyed");
}
}
game.fireEvent(GameEvent.getEvent(EventType.DESTROYED_PERMANENT, objectId, sourceId, controllerId));
return true;
@ -982,7 +986,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
// so the return value of the moveToZone is not taken into account here
moveToZone(Zone.GRAVEYARD, sourceId, game, false);
Player player = game.getPlayer(getControllerId());
if (player != null) {
if (player != null && !game.isSimulation()) {
game.informPlayers(new StringBuilder(player.getName()).append(" sacrificed ").append(this.getLogName()).toString());
}
game.fireEvent(GameEvent.getEvent(EventType.SACRIFICED_PERMANENT, objectId, sourceId, controllerId));
@ -1181,7 +1185,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
@Override
public boolean removeFromCombat(Game game, boolean withInfo) {
if (this.isAttacking() || this.blocking > 0) {
if (game.getCombat().removeFromCombat(objectId, game) && withInfo) {
if (game.getCombat().removeFromCombat(objectId, game) && withInfo && !game.isSimulation()) {
game.informPlayers(new StringBuilder(this.getLogName()).append(" removed from combat").toString());
}
}

View file

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

View file

@ -207,7 +207,8 @@ public class Spell implements StackObject, Card {
return result;
}
//20091005 - 608.2b
game.informPlayers(getName() + " has been fizzled.");
if (!game.isSimulation())
game.informPlayers(getName() + " has been fizzled.");
counter(null, game);
return false;
} else if (this.getCardType().contains(CardType.ENCHANTMENT) && this.getSubtype().contains("Aura")) {
@ -248,7 +249,8 @@ public class Spell implements StackObject, Card {
return result;
} else {
//20091005 - 608.2b
game.informPlayers(getName() + " has been fizzled.");
if (!game.isSimulation())
game.informPlayers(getName() + " has been fizzled.");
counter(null, game);
return false;
}
@ -399,7 +401,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());
}
return true;
@ -430,7 +432,7 @@ public class Spell implements StackObject, Card {
if (forceChange && target.possibleTargets(this.getSourceId(), getControllerId(), game).size() > 1) { // controller of spell must be used (e.g. TargetOpponent)
int iteration = 0;
do {
if (iteration > 0) {
if (iteration > 0 && !game.isSimulation()) {
game.informPlayer(player, "You may only select exactly one target that must be different from the origin target!");
}
iteration++;

View file

@ -100,9 +100,10 @@ public class SpellStack extends ArrayDeque<StackObject> {
}
this.remove(stackObject);
stackObject.counter(sourceId, game); // tries to move to graveyard
game.informPlayers(counteredObjectName + " is countered by " + sourceObject.getLogName());
if (!game.isSimulation())
game.informPlayers(counteredObjectName + " is countered by " + sourceObject.getLogName());
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());
}
return true;

View file

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

View file

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

View file

@ -644,7 +644,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public void discardToMax(Game game) {
if (hand.size() > this.maxHandSize) {
game.informPlayers(new StringBuilder(getName()).append(" discards down to ").append(this.maxHandSize).append(this.maxHandSize == 1 ? " hand card" : " hand cards").toString());
if (!game.isSimulation())
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);
}
}
@ -735,7 +736,8 @@ public abstract class PlayerImpl implements Player, Serializable {
*/
if (card != null) {
// write info to game log first so game log infos from triggered or replacement effects follow in the game log
game.informPlayers(new StringBuilder(name).append(" discards ").append(card.getName()).toString());
if (!game.isSimulation())
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
* when a card is discarded (such as madness) still work, even though that card never reaches
* a graveyard. In addition, spells or abilities that check the characteristics of a discarded
@ -929,7 +931,8 @@ public abstract class PlayerImpl implements Player, Serializable {
GameEvent event = GameEvent.getEvent(GameEvent.EventType.SPELL_CAST, spell.getSpellAbility().getId(), spell.getSpellAbility().getSourceId(), playerId);
event.setZone(fromZone);
game.fireEvent(event);
game.informPlayers(new StringBuilder(name).append(spell.getActivatedMessage(game)).toString());
if (!game.isSimulation())
game.informPlayers(new StringBuilder(name).append(spell.getActivatedMessage(game)).toString());
game.removeBookmark(bookmark);
resetStoredBookmark(game);
return true;
@ -1018,7 +1021,8 @@ public abstract class PlayerImpl implements Player, Serializable {
game.getStack().push(new StackAbility(ability, playerId));
if (ability.activate(game, false)) {
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ACTIVATED_ABILITY, ability.getId(), ability.getSourceId(), playerId));
game.informPlayers(new StringBuilder(name).append(ability.getGameLogMessage(game)).toString());
if (!game.isSimulation())
game.informPlayers(new StringBuilder(name).append(ability.getGameLogMessage(game)).toString());
game.removeBookmark(bookmark);
resetStoredBookmark(game);
return true;
@ -1044,7 +1048,8 @@ public abstract class PlayerImpl implements Player, Serializable {
int bookmark = game.bookmarkState();
if (action.activate(game, false)) {
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ACTIVATED_ABILITY, action.getSourceId(), action.getId(), playerId));
game.informPlayers(new StringBuilder(name).append(action.getGameLogMessage(game)).toString());
if (!game.isSimulation())
game.informPlayers(new StringBuilder(name).append(action.getGameLogMessage(game)).toString());
if (action.resolve(game)) {
game.removeBookmark(bookmark);
resetStoredBookmark(game);
@ -1114,7 +1119,7 @@ public abstract class PlayerImpl implements Player, Serializable {
game.getStack().push(new StackAbility(ability, playerId));
}
if (ability.activate(game, false)) {
if (ability.isUsesStack() || ability.getRuleVisible()) {
if ((ability.isUsesStack() || ability.getRuleVisible()) && !game.isSimulation()) {
game.informPlayers(ability.getGameLogMessage(game));
}
if (!ability.isUsesStack()) {
@ -1269,7 +1274,8 @@ public abstract class PlayerImpl implements Player, Serializable {
public void shuffleLibrary(Game game) {
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.SHUFFLE_LIBRARY, playerId, playerId))) {
this.library.shuffle();
game.informPlayers(new StringBuilder(this.name).append(" shuffles his or her library.").toString());
if (!game.isSimulation())
game.informPlayers(new StringBuilder(this.name).append(" shuffles his or her library.").toString());
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LIBRARY_SHUFFLED, playerId, playerId));
}
}
@ -1282,7 +1288,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public void revealCards(String name, Cards cards, Game game, boolean postToLog) {
game.getState().getRevealed().add(name, cards);
if (postToLog) {
if (postToLog && !game.isSimulation()) {
StringBuilder sb = new StringBuilder(this.getName()).append(" reveals ");
int current = 0, last = cards.size();
for (Card card : cards.getCards(game)) {
@ -1397,7 +1403,7 @@ public abstract class PlayerImpl implements Player, Serializable {
} else {
// player selected an permanent that is restricted by another effect, disallow it (so AI can select another one)
filter.add(Predicates.not(new PermanentIdPredicate(selectedPermanent.getId())));
if (this.isHuman()) {
if (this.isHuman() && !game.isSimulation()) {
game.informPlayer(this, "This permanent can't be untapped because of other restricting effect.");
}
}
@ -1408,9 +1414,11 @@ public abstract class PlayerImpl implements Player, Serializable {
} while (isInGame() && playerCanceledSelection);
// show in log which permanents were selected to untap
for (Permanent permanent : selectedToUntap) {
game.informPlayers(new StringBuilder(this.getName()).append(" untapped ").append(permanent.getName()).toString());
if (!game.isSimulation()) {
// show in log which permanents were selected to untap
for (Permanent permanent : selectedToUntap) {
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
for (Permanent permanent : canBeUntapped) {
@ -1559,7 +1567,8 @@ public abstract class PlayerImpl implements Player, Serializable {
GameEvent event = new GameEvent(GameEvent.EventType.LOSE_LIFE, playerId, playerId, playerId, amount, false);
if (!game.replaceEvent(event)) {
this.life -= event.getAmount();
game.informPlayers(new StringBuilder(this.getName()).append(" loses ").append(event.getAmount()).append(" life").toString());
if (!game.isSimulation())
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));
return amount;
}
@ -1584,7 +1593,8 @@ public abstract class PlayerImpl implements Player, Serializable {
GameEvent event = new GameEvent(GameEvent.EventType.GAIN_LIFE, playerId, playerId, playerId, amount, false);
if (!game.replaceEvent(event)) {
this.life += event.getAmount();
game.informPlayers(new StringBuilder(this.getName()).append(" gains ").append(event.getAmount()).append(" life").toString());
if (!game.isSimulation())
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()));
return event.getAmount();
}
@ -1995,7 +2005,7 @@ public abstract class PlayerImpl implements Player, Serializable {
group.addBlocker(blockerId, playerId, game);
game.getCombat().addBlockingGroup(blockerId, attackerId, playerId, game);
} else {
if (this.isHuman()) {
if (this.isHuman() && !game.isSimulation()) {
game.informPlayer(this, "You can't block this creature.");
}
}
@ -2026,7 +2036,8 @@ public abstract class PlayerImpl implements Player, Serializable {
}
GameEvent event = GameEvent.getEvent(GameEvent.EventType.SEARCH_LIBRARY, targetPlayerId, playerId, playerId, Integer.MAX_VALUE);
if (!game.replaceEvent(event)) {
game.informPlayers(searchInfo);
if (!game.isSimulation())
game.informPlayers(searchInfo);
TargetCardInLibrary newTarget = target.copy();
int count;
int librarySearchLimit = event.getAmount();
@ -2066,7 +2077,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean flipCoin(Game game, ArrayList<UUID> appliedEffects) {
boolean result = rnd.nextBoolean();
game.informPlayers("[Flip a coin] " + getName() + (result ? " won (head)." : " lost (tail)."));
if (!game.isSimulation())
game.informPlayers("[Flip a coin] " + getName() + (result ? " won (head)." : " lost (tail)."));
GameEvent event = new GameEvent(GameEvent.EventType.FLIP_COIN, playerId, null, playerId, 0, result);
event.setAppliedEffects(appliedEffects);
game.replaceEvent(event);
@ -2772,7 +2784,8 @@ public abstract class PlayerImpl implements Player, Serializable {
if (card instanceof PermanentCard) {
card = game.getCard(card.getId());
}
game.informPlayers(new StringBuilder(this.getName())
if (!game.isSimulation())
game.informPlayers(new StringBuilder(this.getName())
.append(" puts ")
.append(withName ? card.getLogName() : "a face down card")
.append(" ")
@ -2849,18 +2862,20 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean moveCardToGraveyardWithInfo(Card card, UUID sourceId, Game game, Zone fromZone) {
boolean result = false;
if (card.moveToZone(Zone.GRAVEYARD, sourceId, game, fromZone != null ? fromZone.equals(Zone.BATTLEFIELD) : false)) {
if (card instanceof PermanentCard) {
card = game.getCard(card.getId());
if (!game.isSimulation()) {
if (card instanceof PermanentCard) {
card = game.getCard(card.getId());
}
StringBuilder sb = new StringBuilder(this.getName())
.append(" puts ").append(card.getLogName()).append(" ")
.append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ") : "");
if (card.getOwnerId().equals(getId())) {
sb.append("into his or her graveyard");
} else {
sb.append("it into its owner's graveyard");
}
game.informPlayers(sb.toString());
}
StringBuilder sb = new StringBuilder(this.getName())
.append(" puts ").append(card.getLogName()).append(" ")
.append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ") : "");
if (card.getOwnerId().equals(getId())) {
sb.append("into his or her graveyard");
} else {
sb.append("it into its owner's graveyard");
}
game.informPlayers(sb.toString());
result = true;
}
return result;
@ -2870,28 +2885,30 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId, Game game, Zone fromZone, boolean toTop, boolean withName) {
boolean result = false;
if (card.moveToZone(Zone.LIBRARY, sourceId, game, toTop)) {
if (card instanceof PermanentCard) {
card = game.getCard(card.getId());
}
StringBuilder sb = new StringBuilder(this.getName())
.append(" puts ").append(withName ? card.getLogName() : "a card").append(" ");
if (fromZone != null) {
if (fromZone.equals(Zone.PICK)) {
sb.append("a picked card ");
if (!game.isSimulation()) {
if (card instanceof PermanentCard) {
card = game.getCard(card.getId());
}
StringBuilder sb = new StringBuilder(this.getName())
.append(" puts ").append(withName ? card.getLogName() : "a card").append(" ");
if (fromZone != null) {
if (fromZone.equals(Zone.PICK)) {
sb.append("a picked card ");
} else {
sb.append("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ");
}
}
sb.append("to the ").append(toTop ? "top" : "bottom");
if (card.getOwnerId().equals(getId())) {
sb.append(" of his or her library");
} else {
sb.append("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ");
Player player = game.getPlayer(card.getOwnerId());
if (player != null) {
sb.append(" of ").append(player.getName()).append("'s library");
}
}
game.informPlayers(sb.toString());
}
sb.append("to the ").append(toTop ? "top" : "bottom");
if (card.getOwnerId().equals(getId())) {
sb.append(" of his or her library");
} else {
Player player = game.getPlayer(card.getOwnerId());
if (player != null) {
sb.append(" of ").append(player.getName()).append("'s library");
}
}
game.informPlayers(sb.toString());
result = true;
}
return result;
@ -2901,13 +2918,15 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean moveCardToExileWithInfo(Card card, UUID exileId, String exileName, UUID sourceId, Game game, Zone fromZone) {
boolean result = false;
if (card.moveToExile(exileId, exileName, sourceId, game)) {
if (card instanceof PermanentCard) {
card = game.getCard(card.getId());
if (!game.isSimulation()) {
if (card instanceof PermanentCard) {
card = game.getCard(card.getId());
}
game.informPlayers(new StringBuilder(this.getName())
.append(" moves ").append(card.getLogName()).append(" ")
.append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ") : "")
.append("to exile").toString());
}
game.informPlayers(new StringBuilder(this.getName())
.append(" moves ").append(card.getLogName()).append(" ")
.append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ") : "")
.append("to exile").toString());
result = true;
}
return result;
@ -2927,7 +2946,8 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped, boolean facedown) {
boolean result = false;
if (card.putOntoBattlefield(game, fromZone, sourceId, this.getId(), tapped, facedown)) {
game.informPlayers(new StringBuilder(this.getName())
if (!game.isSimulation())
game.informPlayers(new StringBuilder(this.getName())
.append(" puts ").append(facedown ? "a card face down ":card.getLogName())
.append(" from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ")
.append("onto the Battlefield").toString());

View file

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

View file

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

View file

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