Combat panel updates as you click on cards to attack

Log panel is also updated correctly
This commit is contained in:
Maxmtg
2013-04-23 14:21:39 +00:00
parent 168bbe0ebf
commit 5fff16db45
8 changed files with 129 additions and 103 deletions

View File

@@ -88,13 +88,16 @@ public class InputAttack extends InputBase {
} }
} }
private void showCombat() {
player.getZone(ZoneType.Battlefield).updateObservers(); // redraw sword icons
game.getPhaseHandler().setCombat(!game.getCombat().getAttackers().isEmpty());
CombatUtil.showCombat(game);
}
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public final void selectButtonOK() { public final void selectButtonOK() {
if (!game.getCombat().getAttackers().isEmpty()) { // Propaganda costs could have been paid here.
game.getPhaseHandler().setCombat();
}
setCurrentDefender(null); // remove highlights setCurrentDefender(null); // remove highlights
game.getPhaseHandler().setPlayersPriorityPermission(false); game.getPhaseHandler().setPlayersPriorityPermission(false);
Singletons.getModel().getMatch().getInput().updateObservers(); Singletons.getModel().getMatch().getInput().updateObservers();
@@ -114,8 +117,7 @@ public class InputAttack extends InputBase {
final List<Card> att = game.getCombat().getAttackers(); final List<Card> att = game.getCombat().getAttackers();
if (isMetaDown && att.contains(card) && !card.hasKeyword("CARDNAME attacks each turn if able.")) { if (isMetaDown && att.contains(card) && !card.hasKeyword("CARDNAME attacks each turn if able.")) {
game.getCombat().removeFromCombat(card); game.getCombat().removeFromCombat(card);
player.getZone(ZoneType.Battlefield).updateObservers(); showCombat();
CombatUtil.showCombat(game);
return; return;
} }
@@ -132,21 +134,11 @@ public class InputAttack extends InputBase {
Zone zone = game.getZoneOf(card); Zone zone = game.getZoneOf(card);
if (zone.is(ZoneType.Battlefield, player) && CombatUtil.canAttack(card, currentDefender, game.getCombat())) { if (zone.is(ZoneType.Battlefield, player) && CombatUtil.canAttack(card, currentDefender, game.getCombat())) {
// TODO add the propaganda code here and remove it in
// Phase.nextPhase()
// if (!CombatUtil.checkPropagandaEffects(card))
// return;
if( game.getCombat().isAttacking(card)) { if( game.getCombat().isAttacking(card)) {
game.getCombat().removeFromCombat(card); game.getCombat().removeFromCombat(card);
} }
game.getCombat().addAttacker(card, currentDefender); game.getCombat().addAttacker(card, currentDefender);
showCombat();
// just to make sure the attack symbol is marked
player.getZone(ZoneType.Battlefield).updateObservers();
CombatUtil.showCombat(game);
ButtonUtil.enableOnlyOk();
} }
else { else {
SDisplayUtil.remind(VMessage.SINGLETON_INSTANCE); SDisplayUtil.remind(VMessage.SINGLETON_INSTANCE);

View File

@@ -30,6 +30,7 @@ import forge.gui.framework.SDisplayUtil;
import forge.gui.match.CMatchUI; import forge.gui.match.CMatchUI;
import forge.gui.match.VMatchUI; import forge.gui.match.VMatchUI;
import forge.gui.match.ViewWinLose; import forge.gui.match.ViewWinLose;
import forge.gui.match.controllers.CCombat;
import forge.gui.match.controllers.CDock; import forge.gui.match.controllers.CDock;
import forge.gui.match.controllers.CLog; import forge.gui.match.controllers.CLog;
import forge.gui.match.controllers.CMessage; import forge.gui.match.controllers.CMessage;
@@ -166,6 +167,12 @@ public class MatchController {
FControl.SINGLETON_INSTANCE.setPlayer(localHuman); FControl.SINGLETON_INSTANCE.setPlayer(localHuman);
CMatchUI.SINGLETON_INSTANCE.initMatch(currentGame.getRegisteredPlayers(), localHuman); CMatchUI.SINGLETON_INSTANCE.initMatch(currentGame.getRegisteredPlayers(), localHuman);
CDock.SINGLETON_INSTANCE.onGameStarts(currentGame, localHuman); CDock.SINGLETON_INSTANCE.onGameStarts(currentGame, localHuman);
CLog.SINGLETON_INSTANCE.init(currentGame.getGameLog());
currentGame.getGameLog().addObserver(CLog.SINGLETON_INSTANCE);
CCombat.SINGLETON_INSTANCE.setModel(currentGame);
Singletons.getModel().getPreferences().actuateMatchPreferences(); Singletons.getModel().getPreferences().actuateMatchPreferences();
Singletons.getControl().changeState(FControl.Screens.MATCH_SCREEN); Singletons.getControl().changeState(FControl.Screens.MATCH_SCREEN);
SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc()); SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc());
@@ -174,10 +181,11 @@ public class MatchController {
inputControl.setMatch(this); inputControl.setMatch(this);
input.addObserver(inputControl); input.addObserver(inputControl);
currentGame.getStack().addObserver(inputControl); currentGame.getStack().addObserver(inputControl);
currentGame.getStack().addObserver(CStack.SINGLETON_INSTANCE);
currentGame.getPhaseHandler().addObserver(inputControl); currentGame.getPhaseHandler().addObserver(inputControl);
currentGame.getGameLog().addObserver(CLog.SINGLETON_INSTANCE);
currentGame.getStack().addObserver(CStack.SINGLETON_INSTANCE);
// some observers are set in CMatchUI.initMatch // some observers are set in CMatchUI.initMatch
final boolean canRandomFoil = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL) && gameType == GameType.Constructed; final boolean canRandomFoil = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL) && gameType == GameType.Constructed;

View File

@@ -834,9 +834,8 @@ public class AiController {
game.setCombat(new AiAttackController(player, player.getOpponent()).getAttackers()); game.setCombat(new AiAttackController(player, player.getOpponent()).getAttackers());
final List<Card> att = game.getCombat().getAttackers(); final List<Card> att = game.getCombat().getAttackers();
if (!att.isEmpty()) { game.getPhaseHandler().setCombat(!att.isEmpty());
game.getPhaseHandler().setCombat();
}
for (final Card element : att) { for (final Card element : att) {
// tapping of attackers happens after Propaganda is paid for // tapping of attackers happens after Propaganda is paid for

View File

@@ -58,7 +58,7 @@ import forge.gui.GuiChoose;
import forge.gui.GuiDialog; import forge.gui.GuiDialog;
import forge.gui.framework.EDocID; import forge.gui.framework.EDocID;
import forge.gui.framework.SDisplayUtil; import forge.gui.framework.SDisplayUtil;
import forge.gui.match.views.VCombat; import forge.gui.match.controllers.CCombat;
/** /**
@@ -1041,46 +1041,6 @@ public class CombatUtil {
return sb.toString(); return sb.toString();
} }
private static String getCombatDescription(Combat combat) {
final StringBuilder display = new StringBuilder();
// Loop through Defenders
// Append Defending Player/Planeswalker
final List<GameEntity> defenders = combat.getDefenders();
final List<List<Card>> attackers = combat.sortAttackerByDefender();
// Not a big fan of the triple nested loop here
for (int def = 0; def < defenders.size(); def++) {
List<Card> atk = attackers.get(def);
if ((atk == null) || (atk.size() == 0)) {
continue;
}
if (def > 0) {
display.append("\n");
}
display.append("Defender - ");
display.append(defenders.get(def).toString());
display.append("\n");
for (final Card c : atk) {
// loop through attackers
display.append("-> ");
display.append(CombatUtil.combatantToString(c)).append("\n");
List<Card> blockers = combat.getBlockers(c);
// loop through blockers
for (final Card element : blockers) {
display.append(" [ ");
display.append(CombatUtil.combatantToString(element)).append("\n");
}
} // loop through attackers
}
return display.toString().trim();
}
/** /**
* <p> * <p>
@@ -1088,35 +1048,12 @@ public class CombatUtil {
* </p> * </p>
*/ */
public static void showCombat(GameState game) { public static void showCombat(GameState game) {
// TODO(sol) ShowCombat seems to be resetting itself when switching away and switching back?
String text = "";
if (game.getPhaseHandler().inCombat()) { if (game.getPhaseHandler().inCombat()) {
text = getCombatDescription(game.getCombat());
SDisplayUtil.showTab(EDocID.REPORT_COMBAT.getDoc()); SDisplayUtil.showTab(EDocID.REPORT_COMBAT.getDoc());
} }
VCombat.SINGLETON_INSTANCE.updateCombat(game.getCombat().getAttackers().size(), text); CCombat.SINGLETON_INSTANCE.update();
} // showBlockers() } // showBlockers()
/**
* <p>
* combatantToString.
* </p>
*
* @param c
* a {@link forge.Card} object.
* @return a {@link java.lang.String} object.
*/
private static String combatantToString(final Card c) {
final StringBuilder sb = new StringBuilder();
final String name = (c.isFaceDown()) ? "Morph" : c.getName();
sb.append(name);
sb.append(" (").append(c.getUniqueNumber()).append(") ");
sb.append(c.getNetAttack()).append("/").append(c.getNetDefense());
return sb.toString();
}
/** /**
* <p> * <p>

View File

@@ -215,8 +215,8 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
* @param b * @param b
* a boolean. * a boolean.
*/ */
public final void setCombat() { public final void setCombat(boolean value) {
this.bCombat.set(true); this.bCombat.set(value);
} }
/** /**

View File

@@ -1,6 +1,12 @@
package forge.gui.match.controllers; package forge.gui.match.controllers;
import java.util.List;
import forge.Card;
import forge.Command; import forge.Command;
import forge.GameEntity;
import forge.game.GameState;
import forge.game.phase.Combat;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.match.views.VCombat; import forge.gui.match.views.VCombat;
@@ -14,6 +20,8 @@ public enum CCombat implements ICDoc {
/** */ /** */
SINGLETON_INSTANCE; SINGLETON_INSTANCE;
private GameState game;
/* (non-Javadoc) /* (non-Javadoc)
* @see forge.gui.framework.ICDoc#getCommandOnSelect() * @see forge.gui.framework.ICDoc#getCommandOnSelect()
*/ */
@@ -34,6 +42,76 @@ public enum CCombat implements ICDoc {
*/ */
@Override @Override
public void update() { public void update() {
VCombat.SINGLETON_INSTANCE.updateCombat(0, ""); if (!game.getPhaseHandler().inCombat())
VCombat.SINGLETON_INSTANCE.updateCombat(0, "");
else
VCombat.SINGLETON_INSTANCE.updateCombat(game.getCombat().getAttackers().size(), getCombatDescription(game.getCombat()));
}
public void setModel(GameState game)
{
this.game = game;
}
private static String getCombatDescription(Combat combat) {
final StringBuilder display = new StringBuilder();
// Loop through Defenders
// Append Defending Player/Planeswalker
final List<GameEntity> defenders = combat.getDefenders();
final List<List<Card>> attackers = combat.sortAttackerByDefender();
// Not a big fan of the triple nested loop here
for (int def = 0; def < defenders.size(); def++) {
List<Card> atk = attackers.get(def);
if ((atk == null) || (atk.size() == 0)) {
continue;
}
if (def > 0) {
display.append("\n");
}
display.append("Defender - ");
display.append(defenders.get(def).toString());
display.append("\n");
for (final Card c : atk) {
// loop through attackers
display.append("-> ");
display.append(combatantToString(c)).append("\n");
List<Card> blockers = combat.getBlockers(c);
// loop through blockers
for (final Card element : blockers) {
display.append(" [ ");
display.append(combatantToString(element)).append("\n");
}
} // loop through attackers
}
return display.toString().trim();
}
/**
* <p>
* combatantToString.
* </p>
*
* @param c
* a {@link forge.Card} object.
* @return a {@link java.lang.String} object.
*/
private static String combatantToString(final Card c) {
final StringBuilder sb = new StringBuilder();
final String name = (c.isFaceDown()) ? "Morph" : c.getName();
sb.append(name);
sb.append(" (").append(c.getUniqueNumber()).append(") ");
sb.append(c.getNetAttack()).append("/").append(c.getNetDefense());
return sb.toString();
} }
} }

View File

@@ -19,6 +19,7 @@ public enum CLog implements ICDoc, Observer {
/** */ /** */
SINGLETON_INSTANCE; SINGLETON_INSTANCE;
private GameLog model;
/* (non-Javadoc) /* (non-Javadoc)
* @see forge.gui.framework.ICDoc#getCommandOnSelect() * @see forge.gui.framework.ICDoc#getCommandOnSelect()
*/ */
@@ -35,24 +36,35 @@ public enum CLog implements ICDoc, Observer {
} }
private final Runnable r = new Runnable() {
@Override
public void run() {
VLog.SINGLETON_INSTANCE.updateConsole(model);
}
};
@Override /**
public void update() {} * TODO: Write javadoc for this method.
* @param gameLog
*/
public void init(GameLog gameLog) {
model = gameLog;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see java.util.Observer#update(java.util.Observable, java.lang.Object) * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
*/ */
@Override @Override
public void update(final Observable model, Object arg1) { public void update(Observable o, Object arg) {
if( model instanceof GameLog ) { update();
FThreads.invokeInEdtNowOrLater(new Runnable() { }
@Override /* (non-Javadoc)
public void run() { * @see forge.gui.framework.ICDoc#update()
VLog.SINGLETON_INSTANCE.updateConsole((GameLog)model); */
} @Override
}); public void update() {
} FThreads.invokeInEdtNowOrLater(r);
} }
} }

View File

@@ -110,7 +110,7 @@ public enum VCombat implements IVDoc<CCombat> {
// No need to update this unless it's showing // No need to update this unless it's showing
if (!this.equals(parentCell.getSelected())) { return; } if (!this.equals(parentCell.getSelected())) { return; }
tab.setText("Combat : " + cntAttackers); tab.setText(cntAttackers > 0 ? ("Combat : " + cntAttackers) : "Combat");
tar.setText(desc); tar.setText(desc);
} }
} }