AI vs AI playback now catches spell-cast event

This commit is contained in:
Maxmtg
2013-05-30 14:08:35 +00:00
parent 406a87a347
commit 55d1aae94d
6 changed files with 84 additions and 42 deletions

1
.gitattributes vendored
View File

@@ -14245,6 +14245,7 @@ src/main/java/forge/game/event/GameEventPlayerDamaged.java -text
src/main/java/forge/game/event/GameEventPlayerPoisoned.java -text
src/main/java/forge/game/event/GameEventPlayerPriority.java -text
src/main/java/forge/game/event/GameEventShuffle.java -text
src/main/java/forge/game/event/GameEventSpellAbilityCast.java -text
src/main/java/forge/game/event/GameEventSpellResolved.java -text
src/main/java/forge/game/event/GameEventTokenCreated.java -text
src/main/java/forge/game/event/GameEventTurnBegan.java -text

View File

@@ -6,12 +6,15 @@ import java.util.Map.Entry;
import com.google.common.eventbus.Subscribe;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.TargetChoices;
import forge.game.GameOutcome;
import forge.game.event.GameEventCardDamaged;
import forge.game.event.GameEventCardDamaged.DamageType;
import forge.game.event.GameEventLandPlayed;
import forge.game.event.GameEventPlayerDamaged;
import forge.game.event.GameEventPlayerPoisoned;
import forge.game.event.GameEventSpellAbilityCast;
import forge.game.event.GameEventSpellResolved;
import forge.game.event.GameEventTurnBegan;
import forge.game.event.IGameEventVisitor;
@@ -59,6 +62,41 @@ public class GameLogFormatter extends IGameEventVisitor.Base<GameLogEntry> {
return new GameLogEntry(GameLogEntryType.STACK_RESOLVE, messageForLog);
}
@Override
public GameLogEntry visit(GameEventSpellAbilityCast event) {
SpellAbility sp = event.sa;
final List<TargetChoices> chosenTargets = sp.getAllTargetChoices();
StringBuilder sb = new StringBuilder();
sb.append(sp.getActivatingPlayer());
if (sp.isSpell()) {
sb.append(" cast ");
}
else if (sp.isAbility()) {
sb.append(" activated ");
}
if (sp.getStackDescription().startsWith("Morph ")) {
sb.append("Morph");
} else {
sb.append(sp.getSourceCard());
}
if (sp.getTarget() != null) {
sb.append(" targeting ");
for (TargetChoices ch : chosenTargets) {
if (null != ch) {
sb.append(ch.getTargetedString());
}
}
}
sb.append(".");
return new GameLogEntry(GameLogEntryType.STACK_ADD, sb.toString());
}
private GameLogEntry generateSummary(List<GameOutcome> gamesPlayed) {
GameOutcome outcome1 = gamesPlayed.get(0);
int[] wins = new int[outcome1.getNumPlayers()];

View File

@@ -13,6 +13,7 @@ import forge.game.event.GameEventGameFinished;
import forge.game.event.GameEventGameStarted;
import forge.game.event.GameEventLandPlayed;
import forge.game.event.GameEventPlayerPriority;
import forge.game.event.GameEventSpellAbilityCast;
import forge.game.event.GameEventSpellResolved;
import forge.game.event.GameEventTurnPhase;
import forge.game.event.IGameEventVisitor;
@@ -36,7 +37,8 @@ public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
private int phasesDelay = 200;
private int combatDelay = 400;
private int resolveDelay = 600;
private int castDelay = 400;
private int resolveDelay = 400;
private void pauseForEvent(int delay) {
try {
@@ -103,17 +105,21 @@ public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
@Override
public Void visit(final GameEventSpellResolved event) {
FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override
public void run() {
CMatchUI.SINGLETON_INSTANCE.setCard(event.spell.getSourceCard());
}
});
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { CMatchUI.SINGLETON_INSTANCE.setCard(event.spell.getSourceCard()); } });
pauseForEvent(resolveDelay);
return null;
}
/* (non-Javadoc)
* @see forge.game.event.IGameEventVisitor.Base#visit(forge.game.event.GameEventSpellAbilityCast)
*/
@Override
public Void visit(final GameEventSpellAbilityCast event) {
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { CMatchUI.SINGLETON_INSTANCE.setCard(event.sa.getSourceCard()); } });
pauseForEvent(castDelay);
return null;
}
/* (non-Javadoc)
* @see forge.game.event.IGameEventVisitor.Base#visit(forge.game.event.GameEventPlayerPriority)
*/

View File

@@ -0,0 +1,25 @@
package forge.game.event;
import forge.card.spellability.SpellAbility;
/**
* TODO: Write javadoc for this type.
*
*/
public class GameEventSpellAbilityCast extends GameEvent {
public final SpellAbility sa;
public GameEventSpellAbilityCast(SpellAbility sp) {
sa = sp;
}
/* (non-Javadoc)
* @see forge.game.event.GameEvent#visit(forge.game.event.IGameEventVisitor)
*/
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
}

View File

@@ -31,6 +31,7 @@ public interface IGameEventVisitor<T> {
T visit(GameEventPlayerPoisoned event);
T visit(GameEventPlayerPriority event);
T visit(GameEventShuffle event);
T visit(GameEventSpellAbilityCast gameEventSpellAbilityCast);
T visit(GameEventSpellResolved event);
T visit(GameEventTokenCreated event);
T visit(GameEventTurnBegan gameEventTurnBegan);
@@ -66,15 +67,12 @@ public interface IGameEventVisitor<T> {
public T visit(GameEventPlayerPriority event) { return null; }
public T visit(GameEventShuffle event) { return null; }
public T visit(GameEventSpellResolved event) { return null; }
public T visit(GameEventSpellAbilityCast event) { return null; }
public T visit(GameEventTokenCreated event) { return null; }
public T visit(GameEventTurnBegan event) { return null; }
public T visit(GameEventTurnEnded event) { return null; }
public T visit(GameEventTurnPhase event) { return null; }
public T visit(GameEventPlayerDamaged event) { return null; }
}
}

View File

@@ -55,6 +55,7 @@ import forge.game.Game;
import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCost;
import forge.game.event.GameEventSpellAbilityCast;
import forge.game.event.GameEventSpellResolved;
import forge.game.player.HumanPlay;
import forge.game.player.Player;
@@ -306,7 +307,6 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
*/
public final void add(final SpellAbility sp) {
FThreads.assertExecutedByEdt(false);
final ArrayList<TargetChoices> chosenTargets = sp.getAllTargetChoices();
if (sp.isManaAbility()) { // Mana Abilities go straight through
AbilityUtils.resolve(sp, false);
@@ -330,34 +330,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
return;
}
//============= GameLog ======================
StringBuilder sb = new StringBuilder();
sb.append(sp.getActivatingPlayer());
if (sp.isSpell()) {
sb.append(" cast ");
}
else if (sp.isAbility()) {
sb.append(" activated ");
}
if (sp.getStackDescription().startsWith("Morph ")) {
sb.append("Morph");
} else {
sb.append(sp.getSourceCard());
}
if (sp.getTarget() != null) {
sb.append(" targeting ");
for (TargetChoices ch : chosenTargets) {
if (null != ch) {
sb.append(ch.getTargetedString());
}
}
}
sb.append(".");
game.getGameLog().add(GameLogEntryType.STACK_ADD, sb.toString());
//============= GameLog ======================
game.fireEvent(new GameEventSpellAbilityCast(sp));
// if activating player slips through the cracks, assign activating
// Player to the controller here
@@ -488,6 +461,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
// Run BecomesTarget triggers
// Create a new object, since the triggers aren't happening right away
final List<TargetChoices> chosenTargets = sp.getAllTargetChoices();
runParams = new HashMap<String, Object>();
runParams.put("SourceSA", sp);
if (!chosenTargets.isEmpty()) {