Removed MyObservable, components now recieve updates from game event bus.

Please report UI not updating on time
This commit is contained in:
Maxmtg
2013-07-02 23:30:26 +00:00
parent 077e4916fc
commit 2a49c009c0
72 changed files with 1031 additions and 907 deletions

16
.gitattributes vendored
View File

@@ -14499,31 +14499,32 @@ src/main/java/forge/game/combat/AttackingBand.java -text
src/main/java/forge/game/combat/Combat.java svneol=native#text/plain
src/main/java/forge/game/combat/CombatLki.java -text
src/main/java/forge/game/combat/CombatUtil.java svneol=native#text/plain
src/main/java/forge/game/event/EventValueChangeType.java -text
src/main/java/forge/game/event/GameEvent.java -text
src/main/java/forge/game/event/GameEventAnteCardsSelected.java -text
src/main/java/forge/game/event/GameEventAttackersDeclared.java -text
src/main/java/forge/game/event/GameEventBlockerAssigned.java -text
src/main/java/forge/game/event/GameEventBlockersDeclared.java -text
src/main/java/forge/game/event/GameEventCardAttachment.java -text
src/main/java/forge/game/event/GameEventCardChangeZone.java -text
src/main/java/forge/game/event/GameEventCardCounters.java -text
src/main/java/forge/game/event/GameEventCardDamaged.java -text
src/main/java/forge/game/event/GameEventCardDestroyed.java -text
src/main/java/forge/game/event/GameEventCardEquipped.java -text
src/main/java/forge/game/event/GameEventCardRegenerated.java -text
src/main/java/forge/game/event/GameEventCardSacrificed.java -text
src/main/java/forge/game/event/GameEventCardStatsChanged.java -text
src/main/java/forge/game/event/GameEventCardTapped.java -text
src/main/java/forge/game/event/GameEventCounterAdded.java -text
src/main/java/forge/game/event/GameEventCounterRemoved.java -text
src/main/java/forge/game/event/GameEventFlipCoin.java -text
src/main/java/forge/game/event/GameEventGameFinished.java -text
src/main/java/forge/game/event/GameEventGameOutcome.java -text
src/main/java/forge/game/event/GameEventGameRestarted.java -text
src/main/java/forge/game/event/GameEventGameStarted.java -text
src/main/java/forge/game/event/GameEventLandPlayed.java -text
src/main/java/forge/game/event/GameEventLifeLoss.java -text
src/main/java/forge/game/event/GameEventManaBurn.java -text
src/main/java/forge/game/event/GameEventManaPool.java -text
src/main/java/forge/game/event/GameEventMulligan.java -text
src/main/java/forge/game/event/GameEventPlayerControl.java -text
src/main/java/forge/game/event/GameEventPlayerDamaged.java -text
src/main/java/forge/game/event/GameEventPlayerLivesChanged.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
@@ -14648,6 +14649,9 @@ src/main/java/forge/gui/download/GuiDownloadQuestImages.java -text
src/main/java/forge/gui/download/GuiDownloadSetPicturesLQ.java svneol=native#text/plain
src/main/java/forge/gui/download/GuiDownloader.java -text
src/main/java/forge/gui/download/package-info.java -text
src/main/java/forge/gui/events/IUiEventVisitor.java -text
src/main/java/forge/gui/events/UiEvent.java -text
src/main/java/forge/gui/events/UiEventBlockerAssigned.java -text
src/main/java/forge/gui/framework/DragCell.java -text
src/main/java/forge/gui/framework/DragTab.java -text
src/main/java/forge/gui/framework/EDocID.java -text
@@ -14810,6 +14814,7 @@ src/main/java/forge/gui/toolbox/special/DeckLister.java -text
src/main/java/forge/gui/toolbox/special/FDeckChooser.java -text
src/main/java/forge/gui/toolbox/special/PhaseIndicator.java -text
src/main/java/forge/gui/toolbox/special/PhaseLabel.java -text
src/main/java/forge/gui/toolbox/special/PlayerDetailsPanel.java -text
src/main/java/forge/gui/toolbox/special/package-info.java -text
src/main/java/forge/item/BoosterPack.java -text
src/main/java/forge/item/FatPack.java -text
@@ -14937,7 +14942,6 @@ src/main/java/forge/util/IgnoringXStream.java -text
src/main/java/forge/util/Lang.java -text
src/main/java/forge/util/LineReader.java -text
src/main/java/forge/util/MultiplexOutputStream.java svneol=native#text/plain
src/main/java/forge/util/MyObservable.java svneol=native#text/plain
src/main/java/forge/util/MyRandom.java svneol=native#text/plain
src/main/java/forge/util/PredicateString.java -text
src/main/java/forge/util/ReflectionUtil.java -text

View File

@@ -73,10 +73,10 @@ import forge.game.GlobalRuleChange;
import forge.game.combat.AttackingBand;
import forge.game.combat.Combat;
import forge.game.event.GameEventCardDamaged;
import forge.game.event.GameEventCardAttachment.AttachMethod;
import forge.game.event.GameEventCardDamaged.DamageType;
import forge.game.event.GameEventCardEquipped;
import forge.game.event.GameEventCounterAdded;
import forge.game.event.GameEventCounterRemoved;
import forge.game.event.GameEventCardAttachment;
import forge.game.event.GameEventCardCounters;
import forge.game.event.GameEventCardTapped;
import forge.game.player.Player;
import forge.game.zone.Zone;
@@ -1134,6 +1134,9 @@ public class Card extends GameEntity implements Comparable<Card> {
int newValue = addAmount + (oldValue == null ? 0 : oldValue.intValue());
this.counters.put(counterType, Integer.valueOf(newValue));
// play the Add Counter sound
getGame().fireEvent(new GameEventCardCounters(this, counterType, oldValue == null ? 0 : oldValue.intValue(), newValue));
// Run triggers
final Map<String, Object> runParams = new TreeMap<String, Object>();
runParams.put("Card", this);
@@ -1141,11 +1144,6 @@ public class Card extends GameEntity implements Comparable<Card> {
for (int i = 0; i < addAmount; i++) {
getGame().getTriggerHandler().runTrigger(TriggerType.CounterAdded, runParams, false);
}
// play the Add Counter sound
getGame().fireEvent(new GameEventCounterAdded(addAmount));
this.updateObservers();
}
/**
@@ -1205,6 +1203,9 @@ public class Card extends GameEntity implements Comparable<Card> {
this.counters.remove(counterName);
}
// Play the Subtract Counter sound
getGame().fireEvent(new GameEventCardCounters(this, counterName, oldValue == null ? 0 : oldValue.intValue(), newValue));
// Run triggers
final Map<String, Object> runParams = new TreeMap<String, Object>();
runParams.put("Card", this);
@@ -1223,10 +1224,6 @@ public class Card extends GameEntity implements Comparable<Card> {
}
// Play the Subtract Counter sound
getGame().fireEvent(new GameEventCounterRemoved(delta));
this.updateObservers();
}
/**
@@ -3296,112 +3293,6 @@ public class Card extends GameEntity implements Comparable<Card> {
return !this.fortifying.isEmpty();
}
/**
* <p>
* addEquippedBy.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void addEquippedBy(final Card c) {
this.equippedBy.add(c);
this.updateObservers();
}
/**
* <p>
* addFortifiedBy.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void addFortifiedBy(final Card c) {
this.fortifiedBy.add(c);
this.updateObservers();
}
/**
* <p>
* removeEquippedBy.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void removeEquippedBy(final Card c) {
this.equippedBy.remove(c);
this.updateObservers();
}
/**
* <p>
* removeFortifiedBy.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void removeFortifiedBy(final Card c) {
this.fortifiedBy.remove(c);
this.updateObservers();
}
/**
* <p>
* addEquipping.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void addEquipping(final Card c) {
this.equipping.add(c);
this.setTimestamp(getGame().getNextTimestamp());
this.updateObservers();
}
/**
* <p>
* addFortifying.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void addFortifying(final Card c) {
this.fortifying.add(c);
this.setTimestamp(getGame().getNextTimestamp());
this.updateObservers();
}
/**
* <p>
* removeFortifying.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void removeFortifying(final Card c) {
this.fortifying.remove(c);
this.updateObservers();
}
/**
* <p>
* removeEquipping.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void removeEquipping(final Card c) {
this.equipping.remove(c);
this.updateObservers();
}
/**
* <p>
* equipCard.
@@ -3426,14 +3317,21 @@ public class Card extends GameEntity implements Comparable<Card> {
return;
}
}
Card oldTarget = null;
if (this.isEquipping()) {
this.unEquipCard(this.getEquipping().get(0));
oldTarget = this.getEquipping().get(0);
this.unEquipCard(oldTarget);
}
this.addEquipping(c);
c.addEquippedBy(this);
// They use double links... it's doubtful
this.equipping.add(c);
this.setTimestamp(this.getGame().getNextTimestamp());
c.equippedBy.add(this);
// Play the Equip sound
getGame().fireEvent(new GameEventCardEquipped());
getGame().fireEvent(new GameEventCardAttachment(this, oldTarget, c, AttachMethod.Equip));
// run trigger
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("AttachSource", this);
@@ -3451,14 +3349,18 @@ public class Card extends GameEntity implements Comparable<Card> {
* a {@link forge.Card} object.
*/
public final void fortifyCard(final Card c) {
Card oldTarget = null;
if (this.isFortifying()) {
this.unFortifyCard(this.getFortifying().get(0));
oldTarget = this.getFortifying().get(0);
this.unFortifyCard(oldTarget);
}
this.addFortifying(c);
c.addFortifiedBy(this);
this.fortifying.add(c);
this.setTimestamp(this.getGame().getNextTimestamp());
c.fortifiedBy.add(this);
// Play the Equip sound
getGame().fireEvent(new GameEventCardEquipped());
getGame().fireEvent(new GameEventCardAttachment(this, oldTarget, c, AttachMethod.Fortify));
// run trigger
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("AttachSource", this);
@@ -3477,7 +3379,9 @@ public class Card extends GameEntity implements Comparable<Card> {
public final void unEquipCard(final Card c) // equipment.unEquipCard(equippedCard);
{
this.equipping.remove(c);
c.removeEquippedBy(this);
c.equippedBy.remove(this);
getGame().fireEvent(new GameEventCardAttachment(this, c, null, AttachMethod.Equip));
// Run triggers
final Map<String, Object> runParams = new TreeMap<String, Object>();
@@ -3496,7 +3400,9 @@ public class Card extends GameEntity implements Comparable<Card> {
*/
public final void unFortifyCard(final Card c) { // fortification.unEquipCard(fortifiedCard);
this.fortifying.remove(c);
c.removeFortifiedBy(this);
c.fortifiedBy.remove(this);
getGame().fireEvent(new GameEventCardAttachment(this, c, null, AttachMethod.Fortify));
}
/**
@@ -3613,20 +3519,6 @@ public class Card extends GameEntity implements Comparable<Card> {
return false;
}
/**
* <p>
* addEnchanting.
* </p>
*
* @param e
* a {@link forge.GameEntity} object.
*/
public final void addEnchanting(final GameEntity e) {
this.enchanting = e;
this.setTimestamp(getGame().getNextTimestamp());
this.updateObservers();
}
/**
* <p>
* removeEnchanting.
@@ -3638,7 +3530,6 @@ public class Card extends GameEntity implements Comparable<Card> {
public final void removeEnchanting(final GameEntity e) {
if (this.enchanting.equals(e)) {
this.enchanting = null;
this.updateObservers();
}
}
@@ -3656,8 +3547,12 @@ public class Card extends GameEntity implements Comparable<Card> {
+ " but it can't be enchanted.");
return;
}
this.addEnchanting(entity);
this.enchanting = entity;
this.setTimestamp(this.getGame().getNextTimestamp());
entity.addEnchantedBy(this);
getGame().fireEvent(new GameEventCardAttachment(this, null, entity, AttachMethod.Enchant));
// run trigger
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("AttachSource", this);
@@ -3673,12 +3568,15 @@ public class Card extends GameEntity implements Comparable<Card> {
* @param gameEntity
* a {@link forge.GameEntity} object.
*/
public final void unEnchantEntity(final GameEntity gameEntity) {
if ((this.enchanting != null) && this.enchanting.equals(gameEntity)) {
public final void unEnchantEntity(final GameEntity entity) {
if (this.enchanting == null || !this.enchanting.equals(entity))
return;
this.enchanting = null;
gameEntity.removeEnchantedBy(this);
}
entity.removeEnchantedBy(this);
getGame().fireEvent(new GameEventCardAttachment(this, entity, null, AttachMethod.Enchant));
}
/**
* <p>
* Setter for the field <code>type</code>.
@@ -4313,7 +4211,6 @@ public class Card extends GameEntity implements Comparable<Card> {
*/
public final void setTapped(final boolean b) {
this.tapped = b;
this.updateObservers();
}
/**
@@ -4322,15 +4219,15 @@ public class Card extends GameEntity implements Comparable<Card> {
* </p>
*/
public final void tap() {
if (this.isUntapped()) {
if (this.isTapped())
return;
// Run triggers
final Map<String, Object> runParams = new TreeMap<String, Object>();
runParams.put("Card", this);
getGame().getTriggerHandler().runTrigger(TriggerType.Taps, runParams, false);
}
this.setTapped(true);
// Play the Tap sound
this.setTapped(true);
getGame().fireEvent(new GameEventCardTapped(this, true));
}
@@ -4340,21 +4237,19 @@ public class Card extends GameEntity implements Comparable<Card> {
* </p>
*/
public final void untap() {
if (this.isTapped()) {
if (this.isUntapped())
return;
// Run triggers
final Map<String, Object> runParams = new TreeMap<String, Object>();
runParams.put("Card", this);
getGame().getTriggerHandler().runTrigger(TriggerType.Untaps, runParams, false);
// Play the Untap sound
getGame().fireEvent(new GameEventCardTapped(this, false));
}
for (final Command var : this.untapCommandList) {
var.run();
}
this.setTapped(false);
getGame().fireEvent(new GameEventCardTapped(this, false));
}
// keywords are like flying, fear, first strike, etc...

View File

@@ -22,8 +22,9 @@ import java.util.Map;
import java.util.TreeMap;
import forge.game.Game;
import forge.game.event.GameEventCardAttachment;
import forge.game.event.GameEventCardAttachment.AttachMethod;
import forge.game.player.Player;
import forge.util.MyObservable;
/**
* <p>
@@ -33,7 +34,7 @@ import forge.util.MyObservable;
* @author Forge
* @version $Id: Player.java 10091 2011-08-30 16:11:21Z Sloth $
*/
public abstract class GameEntity extends MyObservable implements ITargetable {
public abstract class GameEntity implements ITargetable {
private String name = "";
private int preventNextDamage = 0;
private TreeMap<Card, Map<String, String>> preventionShieldsWithEffects = new TreeMap<Card, Map<String, String>>();
@@ -438,7 +439,7 @@ public abstract class GameEntity extends MyObservable implements ITargetable {
*/
public final void addEnchantedBy(final Card c) {
this.enchantedBy.add(c);
this.updateObservers();
getGame().fireEvent(new GameEventCardAttachment(c, null, this, AttachMethod.Enchant));
}
/**
@@ -451,7 +452,7 @@ public abstract class GameEntity extends MyObservable implements ITargetable {
*/
public final void removeEnchantedBy(final Card c) {
this.enchantedBy.remove(c);
this.updateObservers();
getGame().fireEvent(new GameEventCardAttachment(c, this, null, AttachMethod.Enchant));
}
/**

View File

@@ -18,6 +18,9 @@ import forge.card.staticability.StaticAbility;
import forge.card.trigger.Trigger;
import forge.card.trigger.TriggerHandler;
import forge.game.Game;
import forge.game.event.GameEvent;
import forge.game.event.GameEventCardStatsChanged;
import forge.game.event.IGameEventVisitor;
public class AnimateEffect extends AnimateEffectBase {
@@ -291,6 +294,8 @@ public class AnimateEffect extends AnimateEffectBase {
game.getEndOfTurn().addUntil(unanimate);
}
}
game.fireEvent(new GameEventCardStatsChanged(c));
}
} // animateResolve extends SpellEffect {

View File

@@ -467,13 +467,15 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
} else if (tgtC.isEquipment()) { //Equipment
if (tgtC.isEquipping()) {
final Card oldEquiped = tgtC.getEquippingCard();
tgtC.removeEquipping(oldEquiped);
if ( null != oldEquiped )
tgtC.unEquipCard(oldEquiped);
}
tgtC.equipCard(attachedTo);
} else { // fortification
if (tgtC.isFortifying()) {
final Card oldFortified = tgtC.getFortifyingCard();
tgtC.removeFortifying(oldFortified);
if( oldFortified != null )
tgtC.unFortifyCard(oldFortified);
}
tgtC.fortifyCard(attachedTo);
}
@@ -806,13 +808,15 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
} else if (c.isEquipment()) { //Equipment
if (c.isEquipping()) {
final Card oldEquiped = c.getEquippingCard();
c.removeEquipping(oldEquiped);
if ( null != oldEquiped )
c.unEquipCard(oldEquiped);
}
c.equipCard(attachedTo);
} else {
if (c.isFortifying()) {
final Card oldFortified = c.getFortifyingCard();
c.removeFortifying(oldFortified);
if ( null != oldFortified )
c.unFortifyCard(oldFortified);
}
c.fortifyCard(attachedTo);
}

View File

@@ -36,7 +36,7 @@ public class ControlPlayerEffect extends SpellAbilityEffect {
game.getUntap().addUntil(pTarget, new Command() {
@Override
public void run() {
pTarget.obeyNewMaster(activator.getLobbyPlayer().createControllerFor(pTarget));
pTarget.setControllingPlayerController(activator.getLobbyPlayer().createControllerFor(pTarget));
// on following cleanup release control
game.getEndOfTurn().addUntil(new Command() {

View File

@@ -5,7 +5,6 @@ import forge.Card;
import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility;
import forge.game.Game;
import forge.game.player.Player;
public class EndTurnEffect extends SpellAbilityEffect {
@@ -39,12 +38,6 @@ public class EndTurnEffect extends SpellAbilityEffect {
// 4) The current phase and/or step ends. The game skips straight to the
// cleanup step. The cleanup step happens in its entirety.
game.getPhaseHandler().endTurnByEffect();
// Update observers
for (Player p : game.getPlayers()) {
p.updateObservers();
p.updateLabelObservers();
}
}

View File

@@ -74,7 +74,7 @@ public class RestartGameEffect extends SpellAbilityEffect {
RegisteredPlayer psc = game.getMatch().getPlayers().get(i);
player.setStartingLife(psc.getStartingLife());
player.setPoisonCounters(0);
player.setPoisonCounters(0, sa.getSourceCard());
player.setNumLandsPlayed(0);
player.setNumBasicForestsPlayed(0);
GameNew.putCardsOnBattlefield(player, psc.getCardsOnBattlefield(player));
@@ -86,9 +86,6 @@ public class RestartGameEffect extends SpellAbilityEffect {
}
player.shuffle();
player.getZone(ZoneType.Battlefield).updateObservers();
player.updateObservers();
player.getZone(ZoneType.Hand).updateObservers();
}
trigHandler.clearSuppression(TriggerType.ChangesZone);

View File

@@ -324,8 +324,6 @@ public class CardFactoryCreatures {
intermSumToughness += c.getBaseDefense();
game.getAction().exile(c);
}
// is this needed?
card.getController().getZone(ZoneType.Battlefield).updateObservers();
}
}
card.setBaseAttack(intermSumPower);

View File

@@ -30,6 +30,8 @@ import forge.card.MagicColor;
import forge.card.spellability.AbilityManaPart;
import forge.card.spellability.SpellAbility;
import forge.game.GlobalRuleChange;
import forge.game.event.EventValueChangeType;
import forge.game.event.GameEventManaPool;
import forge.game.player.Player;
import forge.util.maps.MapOfLists;
import forge.util.maps.TreeMapOfLists;
@@ -72,7 +74,7 @@ public class ManaPool {
private void addMana(final Mana mana) {
floatingMana.add(mana.getColorCode(), mana);
owner.updateObservers();
owner.getGame().fireEvent(new GameEventManaPool(owner, EventValueChangeType.Added, mana));
}
/**
@@ -87,8 +89,9 @@ public class ManaPool {
for (final Mana m : manaList) {
this.addMana(m);
}
owner.getGame().getAction().checkStateEffects();
owner.updateObservers();
// check state effects replaced by checkStaticAbilities
owner.getGame().getAction().checkStaticAbilities();
}
/**
@@ -117,6 +120,7 @@ public class ManaPool {
numRemoved += floatingMana.get(b).size();
floatingMana.get(b).clear();
}
owner.getGame().fireEvent(new GameEventManaPool(owner, EventValueChangeType.Cleared, null));
return numRemoved;
}
@@ -228,7 +232,7 @@ public class ManaPool {
private void removeMana(final Mana mana) {
Collection<Mana> cm = floatingMana.get(mana.getColorCode());
if (cm.remove(mana)) {
owner.updateObservers();
owner.getGame().fireEvent(new GameEventManaPool(owner, EventValueChangeType.Removed, mana));
}
}
@@ -319,9 +323,9 @@ public class ManaPool {
this.addMana(m);
}
}
manaPaid.clear();
this.owner.updateObservers();
owner.getGame().fireEvent(new GameEventManaPool(owner, EventValueChangeType.ComplexUpdate, null));
}

View File

@@ -32,8 +32,6 @@ import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import forge.Card;
import forge.Constant.Preferences;
import forge.Singletons;
@@ -433,12 +431,10 @@ public enum FControl {
game.subscribeToEvents(playbackControl);
}
VAntes.SINGLETON_INSTANCE.setModel(game.getRegisteredPlayers());
for (final VField field : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) {
field.getLblLibrary().setHoverable(Preferences.DEV_MODE);
field.getDetailsPanel().getLblLibrary().setHoverable(Preferences.DEV_MODE);
}
// per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch
@@ -446,7 +442,5 @@ public enum FControl {
VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(game.getPlayers().get(0));
SDisplayUtil.showTab(nextField);
}
}

View File

@@ -1,5 +1,7 @@
package forge.control;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.lang3.tuple.Pair;
@@ -11,9 +13,17 @@ import forge.FThreads;
import forge.game.Game;
import forge.game.event.GameEvent;
import forge.game.event.GameEventAnteCardsSelected;
import forge.game.event.GameEventCardChangeZone;
import forge.game.event.GameEventCardCounters;
import forge.game.event.GameEventCardDamaged;
import forge.game.event.GameEventCardStatsChanged;
import forge.game.event.GameEventCardTapped;
import forge.game.event.GameEventGameFinished;
import forge.game.event.GameEventGameOutcome;
import forge.game.event.GameEventManaPool;
import forge.game.event.GameEventPlayerControl;
import forge.game.event.GameEventPlayerLivesChanged;
import forge.game.event.GameEventPlayerPoisoned;
import forge.game.event.GameEventPlayerPriority;
import forge.game.event.GameEventSpellAbilityCast;
import forge.game.event.GameEventSpellRemovedFromStack;
@@ -24,6 +34,7 @@ import forge.game.event.IGameEventVisitor;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.zone.PlayerZone;
import forge.gui.GuiDialog;
import forge.gui.SOverlayUtils;
import forge.gui.match.CMatchUI;
@@ -40,8 +51,14 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
this.fc = fc;
}
private final boolean LOG_EVENTS = false;
@Subscribe
public void receiveGameEvent(final GameEvent ev) { ev.visit(this); }
public void receiveGameEvent(final GameEvent ev) {
if ( LOG_EVENTS )
System.out.println("GE: " + ev.toString());
ev.visit(this);
}
private final AtomicBoolean phaseUpdPlanned = new AtomicBoolean(false);
@Override
@@ -111,6 +128,9 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
@Override
public Void visit(GameEventPlayerControl ev) {
if ( fc.getObservedGame().isGameOver() )
return null;
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() {
CMatchUI.SINGLETON_INSTANCE.initHandViews(fc.getLobby().getGuiPlayer());
VMatchUI.SINGLETON_INSTANCE.populate();
@@ -121,11 +141,13 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
return null;
}
private final Runnable unlockGameThreadOnGameOver = new Runnable() { @Override public void run() {
fc.getInputQueue().onGameOver(); // this will unlock any game threads waiting for inputs to complete
} };
@Override
public Void visit(GameEventGameOutcome ev) {
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() {
fc.getInputQueue().onGameOver(); // this will unlock any game threads waiting for inputs to complete
} });
FThreads.invokeInEdtNowOrLater(unlockGameThreadOnGameOver);
return null;
}
@@ -163,4 +185,140 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
FThreads.invokeInEdtNowOrLater(updStack);
return null;
}
private final List<PlayerZone> zonesToUpdate = new Vector<PlayerZone>();
private final Runnable updZones = new Runnable() {
@Override public void run() {
synchronized (zonesToUpdate) {
CMatchUI.SINGLETON_INSTANCE.updateZones(zonesToUpdate);
zonesToUpdate.clear();
}
}
};
@Override
public Void visit(GameEventCardChangeZone event) {
boolean needUpdate = false;
synchronized (zonesToUpdate) {
needUpdate = zonesToUpdate.isEmpty();
if ( event.from instanceof PlayerZone && !zonesToUpdate.contains(event.from) ) {
zonesToUpdate.add((PlayerZone)event.from);
}
if ( event.to instanceof PlayerZone && !zonesToUpdate.contains(event.to) ) {
zonesToUpdate.add((PlayerZone)event.to);
}
}
if( needUpdate )
FThreads.invokeInEdtNowOrLater(updZones);
return null;
}
@Override
public Void visit(GameEventCardTapped event) {
// TODO Smart partial updates
PlayerZone z = (PlayerZone) event.card.getGame().getZoneOf(event.card);
return updateZone(z);
}
@Override
public Void visit(GameEventCardDamaged event) {
PlayerZone z = (PlayerZone) event.damaged.getGame().getZoneOf(event.damaged);
return updateZone(z);
}
@Override
public Void visit(GameEventCardCounters event) {
PlayerZone z = (PlayerZone) event.target.getGame().getZoneOf(event.target);
return updateZone(z);
}
private Void updateZone(PlayerZone z) {
boolean needUpdate = false;
synchronized (zonesToUpdate) {
needUpdate = zonesToUpdate.isEmpty();
if ( !zonesToUpdate.contains(z) ) {
zonesToUpdate.add(z);
}
}
if( needUpdate )
FThreads.invokeInEdtNowOrLater(updZones);
return null;
}
/* (non-Javadoc)
* @see forge.game.event.IGameEventVisitor.Base#visit(forge.game.event.GameEventCardStatsChanged)
*/
@Override
public Void visit(GameEventCardStatsChanged event) {
// TODO Smart partial updates
PlayerZone z = (PlayerZone) event.card.getGame().getZoneOf(event.card);
return updateZone(z);
}
// Update manapool
private final List<Player> manaPoolUpdate = new Vector<Player>();
private final Runnable updManaPool = new Runnable() {
@Override public void run() {
synchronized (manaPoolUpdate) {
CMatchUI.SINGLETON_INSTANCE.updateManaPool(manaPoolUpdate);
manaPoolUpdate.clear();
}
}
};
@Override
public Void visit(GameEventManaPool event) {
boolean invokeUpdate = false;
synchronized (manaPoolUpdate) {
if( !manaPoolUpdate.contains(event.player) ) {
invokeUpdate = manaPoolUpdate.isEmpty();
manaPoolUpdate.add(event.player);
}
}
if (invokeUpdate)
FThreads.invokeInEdtNowOrLater(updManaPool);
return null;
}
// Update lives counters
private final List<Player> livesUpdate = new Vector<Player>();
private final Runnable updLives = new Runnable() {
@Override public void run() {
synchronized (livesUpdate) {
CMatchUI.SINGLETON_INSTANCE.updateLives(livesUpdate);
livesUpdate.clear();
}
}
};
@Override
public Void visit(GameEventPlayerLivesChanged event) {
boolean invokeUpdate = false;
synchronized (livesUpdate) {
if( !livesUpdate.contains(event.player) ) {
invokeUpdate = livesUpdate.isEmpty();
livesUpdate.add(event.player);
}
}
if (invokeUpdate)
FThreads.invokeInEdtNowOrLater(updLives);
return null;
}
@Override
public Void visit(GameEventPlayerPoisoned event) {
boolean invokeUpdate = false;
synchronized (livesUpdate) {
if( !livesUpdate.contains(event.receiver) ) {
invokeUpdate = livesUpdate.isEmpty();
livesUpdate.add(event.receiver);
}
}
if (invokeUpdate)
FThreads.invokeInEdtNowOrLater(updLives);
return null;
}
}

View File

@@ -8,7 +8,7 @@ import com.google.common.eventbus.Subscribe;
import forge.FThreads;
import forge.game.event.GameEvent;
import forge.game.event.GameEventBlockerAssigned;
import forge.game.event.GameEventBlockersDeclared;
import forge.game.event.GameEventGameFinished;
import forge.game.event.GameEventGameStarted;
import forge.game.event.GameEventLandPlayed;
@@ -53,7 +53,7 @@ public class FControlGamePlayback extends IGameEventVisitor.Base<Void> {
@Override
public Void visit(GameEventBlockerAssigned event) {
public Void visit(GameEventBlockersDeclared event) {
pauseForEvent(combatDelay);
return super.visit(event);
}

View File

@@ -17,6 +17,7 @@
*/
package forge.control;
import java.util.Observable;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
@@ -24,7 +25,6 @@ import forge.game.Game;
import forge.gui.input.Input;
import forge.gui.input.InputLockUI;
import forge.gui.input.InputSynchronized;
import forge.util.MyObservable;
/**
* <p>
@@ -34,7 +34,7 @@ import forge.util.MyObservable;
* @author Forge
* @version $Id$
*/
public class InputQueue extends MyObservable {
public class InputQueue extends Observable {
private final BlockingDeque<InputSynchronized> inputStack = new LinkedBlockingDeque<InputSynchronized>();
private final InputLockUI inputLock;
@@ -44,6 +44,12 @@ public class InputQueue extends MyObservable {
inputLock = new InputLockUI(this);
}
public final void updateObservers() {
this.setChanged();
this.notifyObservers();
}
public final Input getInput() {
return inputStack.isEmpty() ? null : this.inputStack.peek();
}

View File

@@ -66,8 +66,8 @@ public class Game {
public final Phase endOfCombat;
public final Untap untap;
public final Upkeep upkeep;
private final PhaseHandler phaseHandler;
public final MagicStack stack;
private final PhaseHandler phaseHandler;
private final StaticEffects staticEffects = new StaticEffects();
private final TriggerHandler triggerHandler = new TriggerHandler(this);
private final ReplacementHandler replacementHandler = new ReplacementHandler(this);

View File

@@ -137,7 +137,7 @@ public class GameAction {
zoneTo.add(c, position);
}
zoneTo.updateLabelObservers();
game.fireEvent(new GameEventCardChangeZone(c, zoneFrom, zoneTo));
return c;
}
@@ -199,9 +199,6 @@ public class GameAction {
}
}
// play the change zone sound
game.fireEvent(new GameEventCardChangeZone(c, zoneFrom, zoneTo));
copied.getOwner().removeInboundToken(copied);
if (c.wasSuspendCast()) {
@@ -236,7 +233,8 @@ public class GameAction {
zoneFrom.remove(c);
}
zoneTo.updateLabelObservers();
// play the change zone sound
game.fireEvent(new GameEventCardChangeZone(c, zoneFrom, zoneTo));
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", lastKnownInfo);
@@ -672,17 +670,11 @@ public class GameAction {
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", lastKnownInfo);
if (p != null) {
runParams.put("Origin", p.getZoneType().name());
} else {
runParams.put("Origin", null);
}
runParams.put("Origin", p == null ? null : p.getZoneType().name());
runParams.put("Destination", ZoneType.Library.name());
game.getTriggerHandler().runTrigger(TriggerType.ChangesZone, runParams, false);
if (p != null) {
p.updateLabelObservers();
}
game.fireEvent(new GameEventCardChangeZone(c, p, library));
// Soulbond unpairing
if (c.isPaired()) {
@@ -1445,7 +1437,7 @@ public class GameAction {
// FControl should determine now if there are any human players.
// Where there are none, it should bring up speed controls
game.fireEvent(new GameEventGameStarted(first, game.getPlayers()));
game.fireEvent(new GameEventGameStarted(game.getType(), first, game.getPlayers()));
game.setAge(GameAge.Mulligan);
for (final Player p1 : game.getPlayers())

View File

@@ -55,7 +55,6 @@ import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityRestriction;
import forge.game.ai.AiController;
import forge.game.player.HumanPlay;
import forge.game.event.GameEventLifeLoss;
import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
import forge.game.player.PlayerControllerAi;
@@ -422,9 +421,6 @@ public final class GameActionUtil {
}
c.getDamageHistory().registerCombatDamage(player);
// Play the Life Loss sound
player.getGame().fireEvent(new GameEventLifeLoss());
} // executeCombatDamageToPlayerEffects
/**

View File

@@ -285,12 +285,6 @@ public class GameNew {
rAICards.addAll(getCardsAiCantPlayWell(myDeck));
}
player.updateObservers();
player.getZone(ZoneType.Battlefield).updateObservers();
player.getZone(ZoneType.Hand).updateObservers();
player.getZone(ZoneType.Command).updateObservers();
player.getZone(ZoneType.Battlefield).updateObservers();
if( myRemovedAnteCards != null && !myRemovedAnteCards.isEmpty() )
removedAnteCards.addAll(player, myRemovedAnteCards);
}

View File

@@ -6,7 +6,6 @@ import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.collect.Lists;
import forge.Card;
import forge.Singletons;
import forge.game.event.GameEventAnteCardsSelected;
@@ -95,13 +94,11 @@ public class Match {
currentGame.getAction().invoke(new Runnable() {
@Override
public void run() {
if (useAnte) { // Deciding which cards go to ante
List<Pair<Player, Card>> list = GameNew.chooseCardsForAnte(currentGame);
GameNew.moveCardsToAnte(list);
currentGame.fireEvent(new GameEventAnteCardsSelected(list));
}
currentGame.getAction().startGame();
}
});

View File

@@ -760,8 +760,6 @@ public class AiController {
Log.debug(sb.toString());
}
attacker.getZone(ZoneType.Battlefield).updateObservers();
// ai is about to attack, cancel all phase skipping
for (Player p : game.getPlayers()) {
p.getController().autoPassCancel();

View File

@@ -430,7 +430,6 @@ public class Combat {
Map<Card, Integer> map = assigningPlayer.getController().assignCombatDamage(blocker, attackers, damage, null, assigningPlayer != blocker.getController());
for (Entry<Card, Integer> dt : map.entrySet()) {
dt.getKey().addAssignedDamage(dt.getValue(), blocker);
dt.getKey().updateObservers();
}
}
}
@@ -488,7 +487,6 @@ public class Combat {
addDefendingDamage(dt.getValue(), attacker);
} else {
dt.getKey().addAssignedDamage(dt.getValue(), attacker);
dt.getKey().updateObservers();
}
}

View File

@@ -0,0 +1,12 @@
package forge.game.event;
/**
* TODO: Write javadoc for this type.
*
*/
public enum EventValueChangeType {
Added,
Removed,
Cleared,
ComplexUpdate
}

View File

@@ -1,11 +0,0 @@
package forge.game.event;
public class GameEventBlockerAssigned extends GameEvent {
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
}

View File

@@ -0,0 +1,30 @@
package forge.game.event;
import forge.Card;
import forge.GameEntity;
public class GameEventCardAttachment extends GameEvent {
public enum AttachMethod {
Equip,
Fortify,
Enchant;
}
public final Card equipment;
public final GameEntity newTarget; // can enchant player, I'm ssaving a class to enchants - it could be incorrect.
public final GameEntity oldEntiy;
public final AttachMethod method;
public GameEventCardAttachment(Card attachment, GameEntity formerEntity, GameEntity newEntity, AttachMethod method) {
this.equipment = attachment;
this.newTarget = newEntity;
this.oldEntiy = formerEntity;
this.method = method;
}
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
}

View File

@@ -20,5 +20,13 @@ public class GameEventCardChangeZone extends GameEvent {
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return String.format("%s : [%s] -> [%s]", card, from, to);
}
}

View File

@@ -0,0 +1,23 @@
package forge.game.event;
import forge.Card;
import forge.CounterType;
public class GameEventCardCounters extends GameEvent {
public final Card target;
public final CounterType type;
public final int oldValue;
public final int newValue;
public GameEventCardCounters(Card card, CounterType counterType, int old, int newValue) {
target = card;
type = counterType;
this.oldValue = old;
this.newValue = newValue;
}
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
}

View File

@@ -1,9 +0,0 @@
package forge.game.event;
public class GameEventCardEquipped extends GameEvent {
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
}

View File

@@ -0,0 +1,24 @@
package forge.game.event;
import forge.Card;
/**
* This means card's characteristics have changed on server, clients must re-request them
*/
public class GameEventCardStatsChanged extends GameEvent {
public final Card card;
public GameEventCardStatsChanged(Card affected) {
card = affected;
}
/* (non-Javadoc)
* @see forge.game.event.GameEvent#visit(forge.game.event.IGameEventVisitor)
*/
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {
// TODO Auto-generated method stub
return visitor.visit(this);
}
}

View File

@@ -1,14 +0,0 @@
package forge.game.event;
public class GameEventCounterAdded extends GameEvent {
public final int Amount;
public GameEventCounterAdded(int n) {
Amount = n;
}
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
}

View File

@@ -1,18 +0,0 @@
package forge.game.event;
/**
*
*
*/
public class GameEventCounterRemoved extends GameEvent {
public final int Amount;
public GameEventCounterRemoved(int n) {
Amount = n;
}
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
}

View File

@@ -1,6 +1,8 @@
package forge.game.event;
import forge.game.GameType;
import forge.game.player.Player;
import forge.util.Lang;
/**
* TODO: Write javadoc for this type.
@@ -10,9 +12,11 @@ public class GameEventGameStarted extends GameEvent {
public final Player firstTurn;
public final Iterable<Player> players;
public final GameType gameType;
public GameEventGameStarted(Player firstTurn, Iterable<Player> players) {
public GameEventGameStarted(GameType type, Player firstTurn, Iterable<Player> players) {
super();
this.gameType = type;
this.firstTurn = firstTurn;
this.players = players;
}
@@ -23,4 +27,12 @@ public class GameEventGameStarted extends GameEvent {
return visitor.visit(this);
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return String.format("%s game between %s started. %s goes first ", gameType, Lang.joinHomogenous(players), firstTurn) ;
}
}

View File

@@ -1,9 +0,0 @@
package forge.game.event;
public class GameEventLifeLoss extends GameEvent {
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
}

View File

@@ -1,7 +1,20 @@
package forge.game.event;
// This special event denotes loss of mana due to phase end
public class GameEventManaBurn extends GameEvent {
public final boolean causedLifeLoss;
public final int amount;
/**
* TODO: Write javadoc for Constructor.
* @param dealDamage
* @param burn
*/
public GameEventManaBurn(int burn, boolean dealDamage) {
amount = burn;
causedLifeLoss = dealDamage;
}
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {

View File

@@ -0,0 +1,38 @@
package forge.game.event;
import forge.card.mana.Mana;
import forge.game.player.Player;
import forge.util.Lang;
/**
* TODO: Write javadoc for this type.
*
*/
public class GameEventManaPool extends GameEvent {
public final Player player;
public final EventValueChangeType mode;
public final Mana mana;
public GameEventManaPool(Player owner, EventValueChangeType changeMode, Mana mana) {
this.mana = mana;
player = owner;
mode = changeMode;
}
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return String.format("%s mana pool %s - %s ", Lang.getPossesive(player.getName()), mode, mana);
}
}

View File

@@ -0,0 +1,21 @@
package forge.game.event;
import forge.game.player.Player;
public class GameEventPlayerLivesChanged extends GameEvent {
public final Player player;
public final int oldLives;
public final int newLives;
public GameEventPlayerLivesChanged(Player who, int oldValue, int newValue) {
player = who;
oldLives = oldValue;
newLives = newValue;
}
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
}

View File

@@ -10,16 +10,14 @@ import forge.game.player.Player;
public class GameEventPlayerPoisoned extends GameEvent {
public final Player receiver;
public final Card source;
public final int oldValue;
public final int amount;
public GameEventPlayerPoisoned(Player recv, Card src, int n) {
public GameEventPlayerPoisoned(Player recv, Card src, int old, int num) {
receiver = recv;
source = src;
amount = n;
}
public GameEventPlayerPoisoned(Player recv, Card src) {
this(recv, src, 1);
oldValue = old;
amount = num;
}

View File

@@ -1,9 +1,26 @@
package forge.game.event;
import forge.game.player.Player;
import forge.util.Lang;
public class GameEventShuffle extends GameEvent {
public final Player player;
public GameEventShuffle(Player player) {
this.player = player;
}
@Override
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return String.format("%s %s his/her/its library", player, Lang.joinVerb(player.getName(), "shuffle"));
}
}

View File

@@ -17,4 +17,12 @@ public class GameEventTurnBegan extends GameEvent {
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return String.format("Turn %d (%s)", turnNumber, turnOwner);
}
}

View File

@@ -2,6 +2,7 @@ package forge.game.event;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.util.Lang;
/**
* TODO: Write javadoc for this type.
@@ -24,4 +25,9 @@ public class GameEventTurnPhase extends GameEvent {
public <T> T visit(IGameEventVisitor<T> visitor) {
return visitor.visit(this);
}
@Override
public String toString() {
return String.format("%s turn, %s%s phase", Lang.getPossesive(playerTurn.getName()), phaseDesc, phase.nameForUi );
}
}

View File

@@ -5,26 +5,26 @@ package forge.game.event;
*
*/
public interface IGameEventVisitor<T> {
T visit(GameEventAnteCardsSelected event);
T visit(GameEventAttackersDeclared event);
T visit(GameEventBlockersDeclared event);
T visit(GameEventBlockerAssigned event);
T visit(GameEventCardDamaged event);
T visit(GameEventCardDestroyed event);
T visit(GameEventCardEquipped event);
T visit(GameEventCardAttachment event);
T visit(GameEventCardChangeZone event);
T visit(GameEventCardRegenerated event);
T visit(GameEventCardSacrificed event);
T visit(GameEventAnteCardsSelected event);
T visit(GameEventCardTapped event);
T visit(GameEventCounterAdded event);
T visit(GameEventCounterRemoved event);
T visit(GameEventCardStatsChanged event);
T visit(GameEventCardCounters event);
T visit(GameEventGameFinished event);
T visit(GameEventGameOutcome event);
T visit(GameEventFlipCoin event);
T visit(GameEventGameStarted event);
T visit(GameEventGameRestarted event);
T visit(GameEventLandPlayed event);
T visit(GameEventLifeLoss event);
T visit(GameEventPlayerLivesChanged event);
T visit(GameEventManaPool event);
T visit(GameEventManaBurn event);
T visit(GameEventMulligan event);
T visit(GameEventPlayerControl event);
@@ -43,26 +43,26 @@ public interface IGameEventVisitor<T> {
// This is base class for all visitors.
public static class Base<T> implements IGameEventVisitor<T>{
public T visit(GameEventAnteCardsSelected event) { return null; }
public T visit(GameEventAttackersDeclared event) { return null; }
public T visit(GameEventBlockersDeclared event) { return null; }
public T visit(GameEventBlockerAssigned event) { return null; }
public T visit(GameEventCardDamaged event) { return null; }
public T visit(GameEventCardDestroyed event) { return null; }
public T visit(GameEventCardEquipped event) { return null; }
public T visit(GameEventCardAttachment event) { return null; }
public T visit(GameEventCardChangeZone event) { return null; }
public T visit(GameEventCardRegenerated event) { return null; }
public T visit(GameEventCardSacrificed event) { return null; }
public T visit(GameEventAnteCardsSelected event) { return null; }
public T visit(GameEventCardTapped event) { return null; }
public T visit(GameEventCounterAdded event) { return null; }
public T visit(GameEventCounterRemoved event) { return null; }
public T visit(GameEventCardStatsChanged event) { return null; }
public T visit(GameEventCardCounters event) { return null; }
public T visit(GameEventGameFinished event) { return null; }
public T visit(GameEventGameOutcome event) { return null; }
public T visit(GameEventFlipCoin event) { return null; }
public T visit(GameEventGameStarted event) { return null; }
public T visit(GameEventGameRestarted event) { return null; }
public T visit(GameEventLandPlayed event) { return null; }
public T visit(GameEventLifeLoss event) { return null; }
public T visit(GameEventPlayerLivesChanged event) { return null; }
public T visit(GameEventManaPool event) { return null; }
public T visit(GameEventManaBurn event) { return null; }
public T visit(GameEventMulligan event) { return null; }
public T visit(GameEventPlayerControl event) { return null; }
@@ -79,5 +79,8 @@ public interface IGameEventVisitor<T> {
public T visit(GameEventPlayerDamaged event) { return null; }
}
}

View File

@@ -42,7 +42,6 @@ import forge.game.GameType;
import forge.game.combat.Combat;
import forge.game.combat.CombatUtil;
import forge.game.event.GameEventAttackersDeclared;
import forge.game.event.GameEventBlockerAssigned;
import forge.game.event.GameEventBlockersDeclared;
import forge.game.event.GameEventPlayerPriority;
import forge.game.event.GameEventTurnBegan;
@@ -431,13 +430,14 @@ public class PhaseHandler implements java.io.Serializable {
for (Player p : game.getPlayers()) {
int burn = p.getManaPool().clearPool(true);
if (Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_MANABURN)) {
p.loseLife(burn);
boolean dealDamage = Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_MANABURN);
// Play the Mana Burn sound
game.fireEvent(new GameEventManaBurn());
if (dealDamage) {
p.loseLife(burn);
}
p.updateObservers();
// Play the Mana Burn sound
if ( burn > 0 )
game.fireEvent(new GameEventManaBurn(burn, dealDamage));
}
switch (this.phase) {
@@ -523,7 +523,6 @@ public class PhaseHandler implements java.io.Serializable {
Player whoDeclaresBlockers = playerDeclaresBlockers == null || playerDeclaresBlockers.hasLost() ? p : playerDeclaresBlockers;
if ( combat.isPlayerAttacked(p) ) {
whoDeclaresBlockers.getController().declareBlockers(p, combat);
game.fireEvent(new GameEventBlockerAssigned()); //
}
if ( game.isGameOver() ) // they just like to close window at any moment
@@ -843,6 +842,7 @@ public class PhaseHandler implements java.io.Serializable {
if( DEBUG_PHASES )
sw.start();
game.getAction().checkStateEffects();
game.fireEvent(new GameEventPlayerPriority(getPlayerTurn(), getPhase(), getPriorityPlayer()));
pPlayerPriority.getController().takePriority();

View File

@@ -209,16 +209,19 @@ public class Untap extends Phase {
final List<Card> landList = CardLists.filter(player.getLandsInPlay(), tappedCanUntap);
if (!landList.isEmpty()) {
Card toUntap = null;
if (player.isComputer()) {
// search for lands the computer has and only untap 1
landList.get(0).untap();
toUntap = landList.get(0);
} else {
final InputSelectCards target = new InputSelectCardsFromList(1,1, landList);
target.setMessage("Select one tapped land to untap");
Singletons.getControl().getInputQueue().setInputAndWait(target);
if( !target.hasCancelled() && !target.getSelected().isEmpty())
target.getSelected().get(0).untap();
toUntap = target.getSelected().get(0);
}
if ( toUntap != null )
toUntap.untap();
}
}
if (game.isCardInPlay("Damping Field") || game.isCardInPlay("Imi Statue")) {

View File

@@ -57,7 +57,7 @@ import forge.game.Game;
import forge.game.GameAge;
import forge.game.GlobalRuleChange;
import forge.game.event.GameEventLandPlayed;
import forge.game.event.GameEventLifeLoss;
import forge.game.event.GameEventPlayerLivesChanged;
import forge.game.event.GameEventMulligan;
import forge.game.event.GameEventPlayerControl;
import forge.game.event.GameEventPlayerDamaged;
@@ -379,7 +379,6 @@ public class Player extends GameEntity implements Comparable<Player> {
// life == newLife
change = false;
}
this.updateObservers();
return change;
}
@@ -417,19 +416,6 @@ public class Player extends GameEntity implements Comparable<Player> {
return this.startingLife;
}
/**
* <p>
* addLife.
* </p>
*
* @param toAdd
* a int.
*/
private void addLife(final int toAdd) {
this.life += toAdd;
this.updateObservers();
}
/**
* <p>
* gainLife.
@@ -460,9 +446,9 @@ public class Player extends GameEntity implements Comparable<Player> {
final int lifeGain = toGain;
if (lifeGain > 0) {
this.addLife(lifeGain);
int oldLife = life;
this.life += lifeGain;
newLifeSet = true;
this.updateObservers();
this.lifeGainedThisTurn += lifeGain;
// Run triggers
@@ -470,6 +456,8 @@ public class Player extends GameEntity implements Comparable<Player> {
runParams.put("Player", this);
runParams.put("LifeAmount", lifeGain);
game.getTriggerHandler().runTrigger(TriggerType.LifeGained, runParams, false);
game.fireEvent(new GameEventPlayerLivesChanged(this, oldLife, life));
} else {
System.out.println("Player - trying to gain negative or 0 life");
}
@@ -506,10 +494,10 @@ public class Player extends GameEntity implements Comparable<Player> {
return 0;
}
if (toLose > 0) {
this.subtractLife(toLose);
int oldLife = life;
this.life -= toLose;
lifeLost = toLose;
game.fireEvent(new GameEventLifeLoss());
this.updateObservers();
game.fireEvent(new GameEventPlayerLivesChanged(this, oldLife, life));
} else if (toLose == 0) {
// Rule 118.4
// this is for players being able to pay 0 life
@@ -544,19 +532,6 @@ public class Player extends GameEntity implements Comparable<Player> {
return true;
}
/**
* <p>
* subtractLife.
* </p>
*
* @param toSub
* a int.
*/
private void subtractLife(final int toSub) {
this.life -= toSub;
this.updateObservers();
}
/**
* <p>
* canPayLife.
@@ -651,7 +626,6 @@ public class Player extends GameEntity implements Comparable<Player> {
source.getController().gainLife(amount, source);
}
source.getDamageHistory().registerDamage(this);
this.getGame().fireEvent(new GameEventLifeLoss());
if (isCombat) {
final ArrayList<String> types = source.getType();
@@ -1079,10 +1053,7 @@ public class Player extends GameEntity implements Comparable<Player> {
*/
public final void addPoisonCounters(final int num, final Card source) {
if (!this.hasKeyword("You can't get poison counters")) {
this.poisonCounters += num;
game.fireEvent(new GameEventPlayerPoisoned(this, source, num));
this.updateObservers();
setPoisonCounters(poisonCounters + num, source);
}
}
@@ -1093,10 +1064,12 @@ public class Player extends GameEntity implements Comparable<Player> {
*
* @param num
* a int.
* @param source
*/
public final void setPoisonCounters(final int num) {
public final void setPoisonCounters(final int num, Card source) {
int oldPoison = poisonCounters;
this.poisonCounters = num;
this.updateObservers();
game.fireEvent(new GameEventPlayerPoisoned(this, source, oldPoison, num));
}
/**
@@ -1110,19 +1083,6 @@ public class Player extends GameEntity implements Comparable<Player> {
return this.poisonCounters;
}
/**
* <p>
* subtractPoisonCounters.
* </p>
*
* @param num
* a int.
*/
public final void subtractPoisonCounters(final int num) {
this.poisonCounters -= num;
this.updateObservers();
}
/**
* Gets the keywords.
*
@@ -1814,7 +1774,7 @@ public class Player extends GameEntity implements Comparable<Player> {
game.getTriggerHandler().runTrigger(TriggerType.Shuffled, runParams, false);
// Play the shuffle sound
game.fireEvent(new GameEventShuffle());
game.fireEvent(new GameEventShuffle(this));
} // shuffle
// //////////////////////////////
@@ -2671,13 +2631,6 @@ public class Player extends GameEntity implements Comparable<Player> {
return this.mustAttackEntity;
}
/**
* Update label observers.
*/
public final void updateLabelObservers() {
this.getZone(ZoneType.Hand).updateObservers();
}
// //////////////////////////////
//
// generic Object overrides
@@ -2766,11 +2719,14 @@ public class Player extends GameEntity implements Comparable<Player> {
}
public final void releaseControl() {
if ( controller == controllerCreator )
return;
controller = controllerCreator;
game.fireEvent(new GameEventPlayerControl(this, getLobbyPlayer(), null));
}
public final void obeyNewMaster(PlayerController pc) {
public final void setControllingPlayerController(PlayerController pc) {
LobbyPlayer oldController = getLobbyPlayer();
controller = pc;
game.fireEvent(new GameEventPlayerControl(this, oldController, pc.getLobbyPlayer()));
@@ -3166,12 +3122,6 @@ public class Player extends GameEntity implements Comparable<Player> {
}
}
// These are used by UI to mark the player currently being attacked or targeted
// Very bad practice! Someone blame on me.
private boolean highlited = false;
public final void setHighlited(boolean value) { highlited = value; }
public final boolean isHighlited() { return highlited; }
/**
* TODO: Write javadoc for this method.
*/

View File

@@ -532,7 +532,6 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
}
this.finishResolving(sa, thisHasFizzled);
game.fireEvent(new GameEventSpellResolved(sa, thisHasFizzled));
if (source.hasStartOfKeyword("Haunt") && !source.isCreature() && game.getZoneOf(source).is(ZoneType.Graveyard)) {

View File

@@ -26,6 +26,7 @@ import com.google.common.collect.Lists;
import forge.Card;
import forge.card.spellability.SpellAbility;
import forge.game.player.Player;
import forge.util.Lang;
/**
* <p>
@@ -98,8 +99,9 @@ public class PlayerZone extends Zone {
*/
public PlayerZone(final ZoneType zone, final Player inPlayer) {
super(zone);
if ( inPlayer == null )
throw new IllegalArgumentException("Player zone must be initialized with correct player");
this.player = inPlayer;
}
// ************ BEGIN - these methods fire updateObservers() *************
@@ -135,14 +137,11 @@ public class PlayerZone extends Zone {
return;
}
c.addObserver(this);
c.setTurnInZone(c.getGame().getPhaseHandler().getTurn());
this.cardList.add(c);
if (!this.is(ZoneType.Battlefield)) {
c.setTapped(false);
} else if (update) { // setTapped has already called update once
this.update();
}
}
@@ -157,7 +156,7 @@ public class PlayerZone extends Zone {
* @return a boolean
*/
public final boolean is(final ZoneType zone, final Player player) {
return (zone == this.zoneName && this.player.equals(player));
return (zone == this.zoneType && this.player.equals(player));
}
/**
@@ -180,16 +179,7 @@ public class PlayerZone extends Zone {
*/
@Override
public final String toString() {
return this.player != null ? String.format("%s %s", this.player, this.zoneName) : this.zoneName.toString();
}
/**
* TODO: Write javadoc for this method.
*/
@Override
public void updateLabelObservers() {
getPlayer().updateLabelObservers();
return String.format("%s %s", Lang.getPossesive(this.player.toString()), this.zoneType);
}
public List<Card> getCardsPlayerCanActivate(Player who) {

View File

@@ -21,8 +21,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.CopyOnWriteArrayList;
import com.google.common.base.Predicate;
@@ -30,7 +28,6 @@ import com.google.common.collect.Iterables;
import forge.Card;
import forge.game.player.Player;
import forge.util.MyObservable;
/**
* <p>
@@ -40,15 +37,14 @@ import forge.util.MyObservable;
* @author Forge
* @version $Id: PlayerZone.java 17582 2012-10-19 22:39:09Z Max mtg $
*/
public class Zone extends MyObservable implements IZone, Observer, java.io.Serializable, Iterable<Card> {
public class Zone implements IZone, java.io.Serializable, Iterable<Card> {
/** Constant <code>serialVersionUID=-5687652485777639176L</code>. */
private static final long serialVersionUID = -5687652485777639176L;
/** The cards. */
protected final transient List<Card> cardList = new CopyOnWriteArrayList<Card>();
protected final transient List<Card> roCardList;
protected final ZoneType zoneName;
protected boolean update = true;
protected final ZoneType zoneType;
protected final transient List<Card> cardsAddedThisTurn = new ArrayList<Card>();
protected final ArrayList<ZoneType> cardsAddedThisTurnSource = new ArrayList<ZoneType>();
@@ -66,14 +62,12 @@ public class Zone extends MyObservable implements IZone, Observer, java.io.Seria
* a {@link forge.game.player.Player} object.
*/
public Zone(final ZoneType zone) {
this.zoneName = zone;
this.zoneType = zone;
this.roCardList = Collections.unmodifiableList(cardList);
//System.out.println(zoneName + " (ct) " + Integer.toHexString(System.identityHashCode(roCardList)));
}
// ************ BEGIN - these methods fire updateObservers() *************
@Override
public void add(final Object o, boolean update) {
final Card c = (Card) o;
@@ -90,15 +84,10 @@ public class Zone extends MyObservable implements IZone, Observer, java.io.Seria
}
}
c.addObserver(this);
c.setTurnInZone(c.getGame().getPhaseHandler().getTurn());
c.setTapped(false);
this.cardList.add(c);
if (update) {
this.update();
}
}
@@ -113,19 +102,6 @@ public class Zone extends MyObservable implements IZone, Observer, java.io.Seria
this.add(o, true);
}
/**
* Update.
*
* @param ob
* an Observable
* @param object
* an Object
*/
@Override
public final void update(final Observable ob, final Object object) {
this.update();
}
/**
* Adds the.
*
@@ -154,7 +130,6 @@ public class Zone extends MyObservable implements IZone, Observer, java.io.Seria
this.cardList.add(index, c);
c.setTurnInZone(c.getGame().getPhaseHandler().getTurn());
this.update();
}
/*
@@ -191,7 +166,6 @@ public class Zone extends MyObservable implements IZone, Observer, java.io.Seria
@Override
public void remove(final Card c) {
this.cardList.remove(c);
this.update();
}
/**
@@ -208,7 +182,6 @@ public class Zone extends MyObservable implements IZone, Observer, java.io.Seria
for (Card c : cards) {
cardList.add(c);
}
this.update();
}
// ************ END - these methods fire updateObservers() *************
@@ -222,7 +195,7 @@ public class Zone extends MyObservable implements IZone, Observer, java.io.Seria
*/
@Override
public final boolean is(final ZoneType zone) {
return zone == this.zoneName;
return zone == this.zoneType;
}
// PlayerZone should override it with a correct implementation
@@ -237,7 +210,7 @@ public class Zone extends MyObservable implements IZone, Observer, java.io.Seria
*/
@Override
public final boolean is(final List<ZoneType> zones) {
return zones.contains(this.zoneName);
return zones.contains(this.zoneType);
}
/**
@@ -249,7 +222,7 @@ public class Zone extends MyObservable implements IZone, Observer, java.io.Seria
*/
@Override
public final ZoneType getZoneType() {
return this.zoneName;
return this.zoneType;
}
/**
@@ -310,17 +283,6 @@ public class Zone extends MyObservable implements IZone, Observer, java.io.Seria
return this.cardList.isEmpty();
}
/**
* <p>
* update.
* </p>
*/
public final void update() {
if (this.update) {
this.updateObservers();
}
}
/**
* <p>
* toString.
@@ -330,7 +292,7 @@ public class Zone extends MyObservable implements IZone, Observer, java.io.Seria
*/
@Override
public String toString() {
return this.zoneName.toString();
return this.zoneType.toString();
}
/**
@@ -373,14 +335,10 @@ public class Zone extends MyObservable implements IZone, Observer, java.io.Seria
return roCardList.iterator();
}
/**
* TODO: Write javadoc for this method.
*/
public void updateLabelObservers() {
}
public void shuffle()
{
Collections.shuffle(cardList);
}
}

View File

@@ -160,10 +160,6 @@ public final class GuiDisplayUtil {
game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
game.getAction().checkStateEffects();
for (Player p : game.getRegisteredPlayers()) {
p.getZone(ZoneType.Battlefield).updateObservers();
}
}
});
}

View File

@@ -0,0 +1,6 @@
package forge.gui.events;
public interface IUiEventVisitor<T> {
T visit(UiEventBlockerAssigned event);
}

View File

@@ -0,0 +1,7 @@
package forge.gui.events;
public abstract class UiEvent {
public abstract <T> T visit(IUiEventVisitor<T> visitor);
}

View File

@@ -0,0 +1,11 @@
package forge.gui.events;
public class UiEventBlockerAssigned extends UiEvent {
@Override
public <T> T visit(IUiEventVisitor<T> visitor) {
return visitor.visit(this);
}
}

View File

@@ -17,10 +17,7 @@
*/
package forge.gui.input;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.google.common.collect.Iterables;
import forge.Card;
@@ -32,7 +29,6 @@ import forge.game.combat.CombatUtil;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
import forge.gui.match.CMatchUI;
import forge.util.MyObservable;
import forge.view.ButtonUtil;
/**
@@ -92,7 +88,7 @@ public class InputAttack extends InputSyncronizedBase {
}
private void showCombat() {
playerAttacks.getZone(ZoneType.Battlefield).updateObservers(); // redraw sword icons
// redraw sword icons
CMatchUI.SINGLETON_INSTANCE.showCombat(combat);
}
@@ -121,7 +117,7 @@ public class InputAttack extends InputSyncronizedBase {
if (isMetaDown && att.contains(card) && !card.hasKeyword("CARDNAME attacks each turn if able.")) {
// TODO Is there no way to attacks each turn cards to attack Planeswalkers?
combat.removeFromCombat(card);
card.setUsedToPay(false);
CMatchUI.SINGLETON_INSTANCE.setUsedToPay(card, false);
showCombat();
// When removing an attacker clear the attacking band
this.activateBand(null);
@@ -180,48 +176,36 @@ public class InputAttack extends InputSyncronizedBase {
} // selectCard()
private final void setCurrentDefender(GameEntity def) {
Set<MyObservable> toUpdate = new HashSet<MyObservable>();
currentDefender = def;
for( GameEntity ge: defenders ) {
if ( ge instanceof Card) {
((Card) ge).setUsedToPay(ge == def);
toUpdate.add(((Card) ge).getController().getZone(ZoneType.Battlefield));
CMatchUI.SINGLETON_INSTANCE.setUsedToPay((Card)ge, ge == def);
}
else if (ge instanceof Player) {
((Player) ge).setHighlited(ge == def);
toUpdate.add(ge);
CMatchUI.SINGLETON_INSTANCE.setHighLited((Player) ge, ge == def);
}
}
updateMessage();
// This will instantly highlight targets
for(MyObservable updateable : toUpdate) {
updateable.updateObservers();
}
// update UI
}
private final void activateBand(AttackingBand band) {
Set<MyObservable> toUpdate = new HashSet<MyObservable>();
if (this.activeBand != null) {
for(Card card : this.activeBand.getAttackers()) {
card.setUsedToPay(false);
toUpdate.add(card.getController().getZone(ZoneType.Battlefield));
CMatchUI.SINGLETON_INSTANCE.setUsedToPay(card, false);
}
}
this.activeBand = band;
if (this.activeBand != null) {
for(Card card : this.activeBand.getAttackers()) {
card.setUsedToPay(true);
toUpdate.add(card.getController().getZone(ZoneType.Battlefield));
CMatchUI.SINGLETON_INSTANCE.setUsedToPay(card, true);
}
}
// This will instantly highlight targets
for(MyObservable updateable : toUpdate) {
updateable.updateObservers();
}
// update UI
}
private void updateMessage() {

View File

@@ -137,11 +137,10 @@ public class InputBlock extends InputSyncronizedBase {
currentAttacker = card;
Player attacker = null;
for(Card c : combat.getAttackers()) {
c.setUsedToPay(card == c);
CMatchUI.SINGLETON_INSTANCE.setUsedToPay(c, card == c);
if ( attacker == null )
attacker = c.getController();
}
// request redraw from here
attacker.getZone(ZoneType.Battlefield).updateObservers();
}
}

View File

@@ -25,6 +25,7 @@ import forge.game.Game;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
import forge.gui.GuiDialog;
import forge.gui.match.CMatchUI;
import forge.util.Lang;
import forge.view.ButtonUtil;
/**
@@ -120,10 +121,10 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
if ( isCommander ) { // allow to choose cards for partial paris
if(selected.contains(c0)) {
c0.setUsedToPay(false);
CMatchUI.SINGLETON_INSTANCE.setUsedToPay(c0, false);
selected.remove(c0);
} else {
c0.setUsedToPay(true);
CMatchUI.SINGLETON_INSTANCE.setUsedToPay(c0, true);
selected.add(c0);
}
if( selected.isEmpty())

View File

@@ -20,7 +20,6 @@ package forge.gui.input;
import forge.Card;
import forge.card.spellability.SpellAbility;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
import forge.view.ButtonUtil;
/**
@@ -45,9 +44,6 @@ public class InputPassPriority extends InputSyncronizedBase {
/** {@inheritDoc} */
@Override
public final void showMessage() {
for (Player p : player.getGame().getRegisteredPlayers()) {
p.getZone(ZoneType.Battlefield).updateObservers();
}
showMessage(getTurnPhasePriorityMessage(player.getGame()));
chosenSa = null;
ButtonUtil.enableOnlyOk();

View File

@@ -18,7 +18,6 @@ import forge.card.spellability.SpellAbility;
import forge.game.Game;
import forge.game.player.HumanPlay;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
import forge.gui.GuiChoose;
import forge.view.ButtonUtil;
@@ -235,8 +234,6 @@ public abstract class InputPayMana extends InputSyncronizedBase {
player.getManaPool().payManaFromAbility(saPaidFor, manaCost, saPaymentSrc);
onManaAbilityPaid();
if ( saPaymentSrc != null )
player.getZone(ZoneType.Battlefield).updateObservers();
}
protected boolean isAlreadyPaid() {

View File

@@ -22,7 +22,6 @@ import forge.card.mana.ManaCostBeingPaid;
import forge.card.spellability.SpellAbility;
import forge.game.Game;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
import forge.view.ButtonUtil;
//pays the cost of a card played from the player's hand
@@ -96,7 +95,7 @@ public class InputPayManaSimple extends InputPayMana {
@Override
protected final void onCancel() {
player.getManaPool().refundManaPaid(this.saPaidFor, true);
player.getZone(ZoneType.Battlefield).updateObservers(); // DO
// Update UI
this.stop();
}

View File

@@ -5,6 +5,7 @@ import java.util.List;
import forge.Card;
import forge.GameEntity;
import forge.gui.match.CMatchUI;
import forge.view.ButtonUtil;
public abstract class InputSelectManyBase<T extends GameEntity> extends InputSyncronizedBase implements InputSelectMany<T> {
@@ -118,14 +119,14 @@ public abstract class InputSelectManyBase<T extends GameEntity> extends InputSyn
protected void onSelectStateChanged(T c, boolean newState) {
if( c instanceof Card )
((Card)c).setUsedToPay(newState); // UI supports card highlighting though this abstraction-breaking mechanism
CMatchUI.SINGLETON_INSTANCE.setUsedToPay((Card)c, newState); // UI supports card highlighting though this abstraction-breaking mechanism
}
protected void afterStop() {
for(T c : selected)
if( c instanceof Card)
((Card)c).setUsedToPay(false);
CMatchUI.SINGLETON_INSTANCE.setUsedToPay((Card)c, false);
}

View File

@@ -12,6 +12,7 @@ import forge.card.spellability.SpellAbility;
import forge.card.spellability.TargetRestrictions;
import forge.game.player.Player;
import forge.gui.GuiChoose;
import forge.gui.match.CMatchUI;
import forge.view.ButtonUtil;
/**
@@ -202,7 +203,7 @@ public final class InputSelectTargets extends InputSyncronizedBase {
private void addTarget(GameEntity ge) {
sa.getTargets().add(ge);
if(ge instanceof Card) {
((Card) ge).setUsedToPay(true);
CMatchUI.SINGLETON_INSTANCE.setUsedToPay((Card) ge, true);
}
Integer val = targetDepth.get(ge);
targetDepth.put(ge, val == null ? Integer.valueOf(1) : Integer.valueOf(val.intValue() + 1) );
@@ -218,7 +219,7 @@ public final class InputSelectTargets extends InputSyncronizedBase {
private void done() {
for(GameEntity c : targetDepth.keySet())
if( c instanceof Card)
((Card)c).setUsedToPay(false);
CMatchUI.SINGLETON_INSTANCE.setUsedToPay((Card)c, false);
this.stop();
}

View File

@@ -19,8 +19,10 @@ package forge.gui.match;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.ImageIcon;
@@ -91,7 +93,6 @@ public enum CMatchUI {
*/
public void initMatch(final List<Player> players, LobbyPlayer localPlayer) {
view = VMatchUI.SINGLETON_INSTANCE;
// TODO fix for use with multiplayer
final String[] indices = Singletons.getModel().getPreferences().getPref(FPref.UI_AVATARS).split(",");
@@ -130,15 +131,9 @@ public enum CMatchUI {
public void initHandViews(LobbyPlayer localPlayer) {
final List<VHand> hands = new ArrayList<VHand>();
final Iterable<VHand> oldHands = view.getHands();
int i = 0;
for (Player p : sortedPlayers) {
PlayerZone hand = p.getZone(ZoneType.Hand);
for(VHand vh : oldHands)
hand.deleteObserver(vh.getLayoutControl());
if (p.getLobbyPlayer() == localPlayer) {
VHand newHand = new VHand(EDocID.Hands[i], p);
newHand.getLayoutControl().initialize();
@@ -193,6 +188,17 @@ public enum CMatchUI {
return idx < 0 ? null :view.getFieldViews().get(idx);
}
public VCommand getCommandFor(Player p) {
int idx = getPlayerIndex(p);
return idx < 0 ? null :view.getCommandViews().get(idx);
}
public VHand getHandFor(Player p) {
int idx = getPlayerIndex(p);
List<VHand> allHands = view.getHands();
return idx < 0 || idx >= allHands.size() ? null : allHands.get(idx);
}
/**
*
* Fires up trample dialog. Very old code, due for refactoring with new UI.
@@ -269,4 +275,70 @@ public enum CMatchUI {
CCombat.SINGLETON_INSTANCE.update();
} // showBlockers()
Set<Player> highlitedPlayers = new HashSet<Player>();
public void setHighLited(Player ge, boolean b) {
if (b) highlitedPlayers.add(ge);
else highlitedPlayers.remove(ge);
}
public boolean isHighlited(Player player) {
return highlitedPlayers.contains(player);
}
Set<Card> highlitedCards = new HashSet<Card>();
// used to highlight cards in UI
public void setUsedToPay(Card card, boolean value) {
if (value) highlitedCards.add(card);
else highlitedCards.remove(card);
}
public boolean isUsedToPay(Card card) {
return highlitedCards.contains(card);
}
public void updateZones(List<PlayerZone> zonesToUpdate) {
//System.out.println("updateZones " + zonesToUpdate);
for(PlayerZone z : zonesToUpdate) {
Player owner = z.getPlayer();
if ( z.is(ZoneType.Command) )
getCommandFor(owner).getTabletop().setupPlayZone();
else if ( z.is(ZoneType.Hand) ) {
VHand vHand = getHandFor(owner);
if (null != vHand)
vHand.getLayoutControl().updateHand();
getFieldViewFor(owner).getDetailsPanel().updateZones();
} else if ( z.is(ZoneType.Battlefield) )
getFieldViewFor(owner).getTabletop().setupPlayZone();
else
getFieldViewFor(owner).getDetailsPanel().updateZones();
}
}
/**
* TODO: Write javadoc for this method.
* @param manaPoolUpdate
*/
public void updateManaPool(List<Player> manaPoolUpdate) {
for(Player p : manaPoolUpdate) {
getFieldViewFor(p).getDetailsPanel().updateManaPool();
}
}
/**
* TODO: Write javadoc for this method.
* @param livesUpdate
*/
public void updateLives(List<Player> livesUpdate) {
for(Player p : livesUpdate) {
getFieldViewFor(p).updateDetails();
}
}
}

View File

@@ -163,11 +163,7 @@ public enum VMatchUI implements IVTopLevelUI {
this.lstCommands = lstCommands0;
}
/**
* TODO: Write javadoc for this method.
* @return
*/
public Iterable<VHand> getHands() {
public List<VHand> getHands() {
return lstHands;
}
}

View File

@@ -23,9 +23,6 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.util.Observable;
import java.util.Observer;
import forge.Card;
import forge.Command;
import forge.game.player.Player;
@@ -49,14 +46,6 @@ public class CCommand implements ICDoc {
public void mousePressed(final MouseEvent e) {
cardclickAction(e); } };
// Card play area, attached to battlefield zone.
private final Observer observerPlay = new Observer() {
@Override
public void update(final Observable a, final Object b) {
CCommand.this.view.getTabletop().setupPlayZone();
}
};
/**
* Controls Swing components of a player's command instance.
*
@@ -73,9 +62,6 @@ public class CCommand implements ICDoc {
if (initializedAlready) { return; }
initializedAlready = true;
// Observers
CCommand.this.player.getZone(ZoneType.Command).addObserver(observerPlay);
// Listeners
// Battlefield card clicks
this.view.getTabletop().addMouseListener(madCardClick);

View File

@@ -17,20 +17,17 @@
*/
package forge.gui.match.nonsingleton;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.base.Function;
import forge.Card;
import forge.Command;
import forge.FThreads;
import forge.Singletons;
import forge.Constant.Preferences;
import forge.card.spellability.SpellAbility;
@@ -45,7 +42,6 @@ import forge.gui.input.Input;
import forge.gui.input.InputPayMana;
import forge.gui.match.CMatchUI;
import forge.gui.match.controllers.CMessage;
import forge.gui.toolbox.FLabel;
/**
* Controls Swing components of a player's field instance.
@@ -62,64 +58,14 @@ public class CField implements ICDoc {
public void mouseMoved(final MouseEvent e) {
cardoverAction(e); } };
private final MouseListener madHand = new MouseAdapter() { @Override
public void mousePressed(final MouseEvent e) {
handClicked(); } };
private final MouseListener madAvatar = new MouseAdapter() { @Override
public void mousePressed(final MouseEvent e) {
CMessage.SINGLETON_INSTANCE.getInputControl().selectPlayer(player); } };
private final MouseListener madExiled = new MouseAdapter() { @Override
public void mousePressed(final MouseEvent e) { exileAction.actionPerformed(null); } };
private final MouseListener madLibrary = new MouseAdapter() { @Override
public void mousePressed(final MouseEvent e) { if (Preferences.DEV_MODE) libraryAction.actionPerformed(null); } };
private final MouseListener madGraveyard = new MouseAdapter() { @Override
public void mousePressed(final MouseEvent e) { graveAction.actionPerformed(null); } };
private final MouseListener madFlashback = new MouseAdapter() { @Override
public void mousePressed(final MouseEvent e) { flashBackAction.actionPerformed(null); } };
private final MouseListener madCardClick = new MouseAdapter() { @Override
public void mousePressed(final MouseEvent e) { cardclickAction(e); } };
private final Runnable updateZonesRunnable = new Runnable() { @Override public void run() { CField.this.view.updateZones(CField.this.player); } };
private final Runnable updateDetailsRunnable = new Runnable() { @Override public void run() { CField.this.view.updateDetails(CField.this.player); } };
// Life total, poison total, and keywords, attached directly to Player.
private final Observer observerDetails = new Observer() {
@Override
public void update(final Observable a, final Object b) {
FThreads.invokeInEdtNowOrLater(updateDetailsRunnable);
}
};
// Hand, Graveyard, Library, Flashback, Exile zones, attached to hand.
private final Observer observerZones = new Observer() {
@Override
public void update(final Observable a, final Object b) {
FThreads.invokeInEdtNowOrLater(updateZonesRunnable);
}
};
// Card play area, attached to battlefield zone.
private final Observer observerPlay = new Observer() {
@Override
public void update(final Observable a, final Object b) {
//FThreads.checkEDT("observerPlay.update", true);
CField.this.view.getTabletop().setupPlayZone();
}
};
private final ZoneAction handAction;
private final ZoneAction libraryAction;
private final ZoneAction exileAction;
private final ZoneAction graveAction;
private final ZoneAction flashBackAction;
/**
* Controls Swing components of a player's field instance.
*
@@ -133,11 +79,25 @@ public class CField implements ICDoc {
this.viewer = playerViewer;
this.view = v0;
handAction = new ZoneAction(player.getZone(ZoneType.Hand), MatchConstants.HUMANHAND);
libraryAction = new ZoneAction(player.getZone(ZoneType.Library), MatchConstants.HUMANLIBRARY);
exileAction = new ZoneAction(player.getZone(ZoneType.Exile), MatchConstants.HUMANEXILED);
graveAction = new ZoneAction(player.getZone(ZoneType.Graveyard), MatchConstants.HUMANGRAVEYARD);
flashBackAction = new ZoneAction(player.getZone(ZoneType.Graveyard), MatchConstants.HUMANFLASHBACK) {
ZoneAction handAction = new ZoneAction(player.getZone(ZoneType.Hand), MatchConstants.HUMANHAND) {
@Override
public void actionPerformed(ActionEvent e) {
if ( player.getLobbyPlayer() == viewer || Preferences.DEV_MODE || player.hasKeyword("Play with your hand revealed."))
super.actionPerformed(e);
}
};
ZoneAction libraryAction = new ZoneAction(player.getZone(ZoneType.Library), MatchConstants.HUMANLIBRARY) {
@Override
public void actionPerformed(ActionEvent e) {
if (Preferences.DEV_MODE)
super.actionPerformed(e);
}
};
ZoneAction exileAction = new ZoneAction(player.getZone(ZoneType.Exile), MatchConstants.HUMANEXILED);
ZoneAction graveAction = new ZoneAction(player.getZone(ZoneType.Graveyard), MatchConstants.HUMANGRAVEYARD);
ZoneAction flashBackAction = new ZoneAction(player.getZone(ZoneType.Graveyard), MatchConstants.HUMANFLASHBACK) {
@Override
protected List<Card> getCardsAsIterable() {
return player.getCardsActivableInExternalZones();
@@ -161,13 +121,25 @@ public class CField implements ICDoc {
}
}
};
}
private void handClicked() {
if ( player.getLobbyPlayer() == viewer || Preferences.DEV_MODE || player.hasKeyword("Play with your hand revealed.")) {
handAction.actionPerformed(null);
Function<Byte, Void> manaAction = new Function<Byte, Void>() {
public Void apply(Byte colorCode) {
if (CField.this.player.getLobbyPlayer() == CField.this.viewer) {
final Input in = Singletons.getControl().getInputQueue().getInput();
if (in instanceof InputPayMana) {
// Do something
((InputPayMana) in).selectManaPool(colorCode);
}
}
return null;
}
};
view.getDetailsPanel().setupMouseActions(handAction, libraryAction, exileAction, graveAction, flashBackAction, manaAction);
}
/** */
private void cardoverAction(MouseEvent e) {
@@ -192,26 +164,15 @@ public class CField implements ICDoc {
CMessage.SINGLETON_INSTANCE.getInputControl().selectCard(c, e.isMetaDown());
}
/** */
private void manaAction(byte colorCode) {
if (CField.this.player.getLobbyPlayer() == CField.this.viewer) {
final Input in = Singletons.getControl().getInputQueue().getInput();
if (in instanceof InputPayMana) {
// Do something
((InputPayMana) in).selectManaPool(colorCode);
}
}
}
@Override
public void initialize() {
if (initializedAlready) { return; }
initializedAlready = true;
// Observers
CField.this.player.getZone(ZoneType.Hand).addObserver(observerZones);
CField.this.player.getZone(ZoneType.Battlefield).addObserver(observerPlay);
CField.this.player.addObserver(observerDetails);
// CField.this.player.getZone(ZoneType.Hand).addObserver(observerZones);
// CField.this.player.getZone(ZoneType.Battlefield).addObserver(observerPlay);
// CField.this.player.addObserver(observerDetails);
// Listeners
// Battlefield card clicks
@@ -223,31 +184,6 @@ public class CField implements ICDoc {
// Player select
this.view.getAvatarArea().addMouseListener(madAvatar);
// Detail label listeners
((FLabel) this.view.getLblGraveyard()).setHoverable(true);
this.view.getLblGraveyard().addMouseListener(madGraveyard);
((FLabel) this.view.getLblExile()).setHoverable(true);
this.view.getLblExile().addMouseListener(madExiled);
if (Preferences.DEV_MODE) {
((FLabel) this.view.getLblLibrary()).setHoverable(true);
}
this.view.getLblLibrary().addMouseListener(madLibrary);
((FLabel) this.view.getLblHand()).setHoverable(true);
this.view.getLblHand().addMouseListener(madHand);
((FLabel) this.view.getLblFlashback()).setHoverable(true);
this.view.getLblFlashback().addMouseListener(madFlashback);
for(final Pair<FLabel, Byte> labelPair : this.view.getManaLabels()) {
labelPair.getLeft().setHoverable(true);
labelPair.getLeft().addMouseListener(new MouseAdapter() { @Override
public void mousePressed(final MouseEvent e) {
manaAction(labelPair.getRight()); } }
);
}
}
@Override

View File

@@ -25,8 +25,6 @@ import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JLayeredPane;
import javax.swing.SwingUtilities;
@@ -47,7 +45,7 @@ import forge.view.arcane.util.Animation;
* Controls Swing components of a player's hand instance.
*
*/
public class CHand implements ICDoc, Observer {
public class CHand implements ICDoc {
private final Player player;
private final VHand view;
private boolean initializedAlready = false;
@@ -73,8 +71,8 @@ public class CHand implements ICDoc, Observer {
if (initializedAlready) { return; }
initializedAlready = true;
if (player != null)
player.getZone(ZoneType.Hand).addObserver(this);
// if (player != null)
// player.getZone(ZoneType.Hand).addObserver(this);
HandArea area = view.getHandArea();
area.addMouseListener(madCardClick);
@@ -134,7 +132,7 @@ public class CHand implements ICDoc, Observer {
final HandArea p = view.getHandArea();
VField vf = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(player);
final Rectangle rctLibraryLabel = vf.getLblLibrary().getBounds();
final Rectangle rctLibraryLabel = vf.getDetailsPanel().getLblLibrary().getBounds();
final List<Card> cc = player.getZone(ZoneType.Hand).getCards();
// Animation starts from the library label and runs to the hand panel.
@@ -164,7 +162,7 @@ public class CHand implements ICDoc, Observer {
JLayeredPane layeredPane = Singletons.getView().getFrame().getLayeredPane();
int fromZoneX = 0, fromZoneY = 0;
final Point zoneLocation = SwingUtilities.convertPoint(vf.getLblLibrary(),
final Point zoneLocation = SwingUtilities.convertPoint(vf.getDetailsPanel().getLblLibrary(),
Math.round(rctLibraryLabel.width / 2.0f), Math.round(rctLibraryLabel.height / 2.0f), layeredPane);
fromZoneX = zoneLocation.x;
fromZoneY = zoneLocation.y;
@@ -200,10 +198,8 @@ public class CHand implements ICDoc, Observer {
return null;
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#update()
*/
@Override
public void update() {
updateHand();
}
}

View File

@@ -21,10 +21,6 @@ import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
@@ -32,11 +28,7 @@ import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.border.MatteBorder;
import org.apache.commons.lang3.tuple.Pair;
import net.miginfocom.swing.MigLayout;
import forge.card.MagicColor;
import forge.card.mana.ManaPool;
import forge.game.player.LobbyPlayer;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
@@ -44,11 +36,11 @@ import forge.gui.framework.DragCell;
import forge.gui.framework.DragTab;
import forge.gui.framework.EDocID;
import forge.gui.framework.IVDoc;
import forge.gui.match.controllers.CPlayers;
import forge.gui.match.CMatchUI;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FSkin.SkinProp;
import forge.gui.toolbox.special.PhaseIndicator;
import forge.gui.toolbox.special.PlayerDetailsPanel;
import forge.view.arcane.PlayArea;
/**
@@ -71,20 +63,12 @@ public class VField implements IVDoc<CField> {
private final PlayArea tabletop;
private final JPanel avatarArea = new JPanel();
private final JPanel pnlDetails = new JPanel();
private final PlayerDetailsPanel detailsPanel;
// Avatar area
private final FLabel lblAvatar = new FLabel.Builder().fontAlign(SwingConstants.CENTER).iconScaleFactor(1.0f).build();
private final FLabel lblLife = new FLabel.Builder().fontAlign(SwingConstants.CENTER).fontStyle(Font.BOLD).build();
// Info labels
private FLabel lblHand = getBuiltFLabel(FSkin.ZoneImages.ICO_HAND, "99", "Cards in hand");
private FLabel lblGraveyard = getBuiltFLabel(FSkin.ZoneImages.ICO_GRAVEYARD, "99", "Cards in graveyard");
private FLabel lblLibrary = getBuiltFLabel(FSkin.ZoneImages.ICO_LIBRARY, "99", "Cards in library");
private FLabel lblExile = getBuiltFLabel(FSkin.ZoneImages.ICO_EXILE, "99", "Exiled cards");
private FLabel lblFlashback = getBuiltFLabel(FSkin.ZoneImages.ICO_FLASHBACK, "99", "Flashback cards");
private FLabel lblPoison = getBuiltFLabel(FSkin.ZoneImages.ICO_POISON, "99", "Poison counters");
private final List<Pair<FLabel, Byte>> manaLabels = new ArrayList<Pair<FLabel,Byte>>();
private final PhaseIndicator phaseInidicator = new PhaseIndicator();
@@ -108,12 +92,8 @@ public class VField implements IVDoc<CField> {
if (playerOnwer != null) { tab.setText(playerOnwer.getName() + " Field"); }
else { tab.setText("NO PLAYER FOR " + docID.toString()); }
manaLabels.add(Pair.of(getBuiltFLabel(FSkin.ManaImages.IMG_BLACK, "99", "Black mana"), MagicColor.BLACK));
manaLabels.add(Pair.of(getBuiltFLabel(FSkin.ManaImages.IMG_BLUE, "99", "Blue mana"), MagicColor.BLUE));
manaLabels.add(Pair.of(getBuiltFLabel(FSkin.ManaImages.IMG_GREEN, "99", "Green mana"), MagicColor.GREEN));
manaLabels.add(Pair.of(getBuiltFLabel(FSkin.ManaImages.IMG_RED, "99", "Red mana"), MagicColor.RED));
manaLabels.add(Pair.of(getBuiltFLabel(FSkin.ManaImages.IMG_WHITE, "99", "White mana"), MagicColor.WHITE));
manaLabels.add(Pair.of(getBuiltFLabel(FSkin.ManaImages.IMG_COLORLESS, "99", "Colorless mana"), (byte)0));
detailsPanel = new PlayerDetailsPanel(player);
// TODO player is hard-coded into tabletop...should be dynamic
// (haven't looked into it too deeply). Doublestrike 12-04-12
@@ -132,14 +112,14 @@ public class VField implements IVDoc<CField> {
@Override
public void mouseEntered(final MouseEvent e) {
avatarArea.setOpaque(true);
if (!player.isHighlited())
if (!isHighlited())
avatarArea.setBorder(borderAvatarHover);
}
@Override
public void mouseExited(final MouseEvent e) {
avatarArea.setOpaque(false);
if (!player.isHighlited())
if (!isHighlited())
avatarArea.setBorder(borderAvatarSimple);
}
});
@@ -153,9 +133,7 @@ public class VField implements IVDoc<CField> {
scroller.getViewport().setOpaque(false);
scroller.setBorder(null);
pnlDetails.setOpaque(false);
pnlDetails.setLayout(new MigLayout("insets 0, gap 0, wrap"));
populateDetails();
updateDetails();
}
//========= Overridden methods
@@ -171,7 +149,7 @@ public class VField implements IVDoc<CField> {
pnl.add(avatarArea, "w 10%!, h 30%!");
pnl.add(phaseInidicator, "w 5%!, h 100%!, span 1 2");
pnl.add(scroller, "w 85%!, h 100%!, span 1 2, wrap");
pnl.add(pnlDetails, "w 10%!, h 69%!, gapleft 1px");
pnl.add(detailsPanel, "w 10%!, h 69%!, gapleft 1px");
}
/* (non-Javadoc)
@@ -217,114 +195,7 @@ public class VField implements IVDoc<CField> {
//========= Populate helper methods
/** Adds various labels to pool area JPanel container. */
private void populateDetails() {
final JPanel row1 = new JPanel(new MigLayout("insets 0, gap 0"));
final JPanel row2 = new JPanel(new MigLayout("insets 0, gap 0"));
final JPanel row3 = new JPanel(new MigLayout("insets 0, gap 0"));
final JPanel row4 = new JPanel(new MigLayout("insets 0, gap 0"));
final JPanel row5 = new JPanel(new MigLayout("insets 0, gap 0"));
final JPanel row6 = new JPanel(new MigLayout("insets 0, gap 0"));
row1.setBackground(FSkin.getColor(FSkin.Colors.CLR_ZEBRA));
row2.setOpaque(false);
row3.setBackground(FSkin.getColor(FSkin.Colors.CLR_ZEBRA));
row4.setOpaque(false);
row5.setBackground(FSkin.getColor(FSkin.Colors.CLR_ZEBRA));
row6.setOpaque(false);
// Hand, library, graveyard, exile, flashback, poison labels
final String constraintsCell = "w 45%!, h 100%!, gap 0 5% 2px 2px";
row1.add(lblHand, constraintsCell);
row1.add(lblLibrary, constraintsCell);
row2.add(lblGraveyard, constraintsCell);
row2.add(lblExile, constraintsCell);
row3.add(lblFlashback, constraintsCell);
row3.add(lblPoison, constraintsCell);
row4.add(manaLabels.get(0).getLeft(), constraintsCell);
row4.add(manaLabels.get(1).getLeft(), constraintsCell);
row5.add(manaLabels.get(2).getLeft(), constraintsCell);
row5.add(manaLabels.get(3).getLeft(), constraintsCell);
row6.add(manaLabels.get(4).getLeft(), constraintsCell);
row6.add(manaLabels.get(5).getLeft(), constraintsCell);
final String constraintsRow = "w 100%!, h 16%!";
pnlDetails.add(row1, constraintsRow + ", gap 0 0 4% 0");
pnlDetails.add(row2, constraintsRow);
pnlDetails.add(row3, constraintsRow);
pnlDetails.add(row4, constraintsRow);
pnlDetails.add(row5, constraintsRow);
pnlDetails.add(row6, constraintsRow);
}
private FLabel getBuiltFLabel(SkinProp p0, String s0, String s1) {
return new FLabel.Builder().icon(new ImageIcon(FSkin.getImage(p0)))
.opaque(false).fontSize(14)
.fontStyle(Font.BOLD).iconInBackground()
.text(s0).tooltip(s1).fontAlign(SwingConstants.RIGHT).build();
}
// ========== Observer update methods
/**
* Handles observer update of player Zones - hand, graveyard, etc.
*
* @param p0 &emsp; {@link forge.game.player.Player}
*/
public void updateZones(final Player p0) {
this.getLblHand().setText("" + p0.getZone(ZoneType.Hand).size());
final String handMaxToolTip = p0.isUnlimitedHandSize()
? "no maximum hand size" : String.valueOf(p0.getMaxHandSize());
this.getLblHand().setToolTipText("Cards in hand (max: " + handMaxToolTip + ")");
this.getLblGraveyard().setText("" + p0.getZone(ZoneType.Graveyard).size());
this.getLblLibrary().setText("" + p0.getZone(ZoneType.Library).size());
this.getLblFlashback().setText("" + p0.getCardsActivableInExternalZones().size());
this.getLblExile().setText("" + p0.getZone(ZoneType.Exile).size());
}
/**
* Handles observer update of non-Zone details - life, poison, etc. Also
* updates "players" panel in tabber for this player.
*
* @param p0 &emsp; {@link forge.game.player.Player}
*/
public void updateDetails(final Player p0) {
// "Players" panel update
CPlayers.SINGLETON_INSTANCE.update();
// Mana pool update
updateManaPool(p0);
// Poison/life
this.getLblLife().setText("" + p0.getLife());
this.getLblPoison().setText("" + p0.getPoisonCounters());
Color lifeFg = p0.getLife() <= 5 ? Color.red : FSkin.getColor(FSkin.Colors.CLR_TEXT);
this.getLblLife().setForeground(lifeFg);
Color poisonFg = p0.getPoisonCounters() >= 8 ? Color.red : FSkin.getColor(FSkin.Colors.CLR_TEXT);
this.getLblPoison().setForeground(poisonFg);
this.avatarArea.setBorder(p0.isHighlited() ? borderAvatarHighlited : borderAvatarSimple );
this.avatarArea.setOpaque(p0.isHighlited());
}
/**
* Handles observer update of the mana pool.
*
* @param p0 &emsp; {@link forge.game.player.Player}
*/
public void updateManaPool(final Player p0) {
ManaPool m = p0.getManaPool();
for(Pair<FLabel, Byte> label : manaLabels)
label.getKey().setText(Integer.toString(m.getAmountOfColor(label.getRight())));
}
//========= Retrieval methods
/**
@@ -363,40 +234,6 @@ public class VField implements IVDoc<CField> {
return this.lblLife;
}
/** @return {@link javax.swing.JLabel} */
public FLabel getLblHand() {
return this.lblHand;
}
/** @return {@link javax.swing.JLabel} */
public FLabel getLblLibrary() {
return this.lblLibrary;
}
public final Iterable<Pair<FLabel, Byte>> getManaLabels() {
return manaLabels;
}
/** @return {@link javax.swing.JLabel} */
public JLabel getLblGraveyard() {
return this.lblGraveyard;
}
/** @return {@link javax.swing.JLabel} */
public JLabel getLblExile() {
return this.lblExile;
}
/** @return {@link javax.swing.JLabel} */
public JLabel getLblFlashback() {
return this.lblFlashback;
}
/** @return {@link javax.swing.JLabel} */
public JLabel getLblPoison() {
return this.lblPoison;
}
/**
* TODO: Write javadoc for this method.
* @return
@@ -405,5 +242,32 @@ public class VField implements IVDoc<CField> {
return phaseInidicator;
}
/**
* @return the detailsPanel
*/
public PlayerDetailsPanel getDetailsPanel() {
return detailsPanel;
}
public boolean isHighlited() {
return CMatchUI.SINGLETON_INSTANCE.isHighlited(player);
}
/**
* TODO: Write javadoc for this method.
* @param player2
*/
public void updateDetails() {
detailsPanel.updateDetails();
this.getLblLife().setText("" + player.getLife());
Color lifeFg = player.getLife() <= 5 ? Color.red : FSkin.getColor(FSkin.Colors.CLR_TEXT);
this.getLblLife().setForeground(lifeFg);
boolean highlited = isHighlited();
this.avatarArea.setBorder(highlited ? borderAvatarHighlited : borderAvatarSimple );
this.avatarArea.setOpaque(highlited);
}
}

View File

@@ -18,8 +18,6 @@
package forge.gui.match.views;
import java.awt.Dimension;
import java.util.Observable;
import java.util.Observer;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -45,7 +43,7 @@ import forge.gui.toolbox.FLabel;
*
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
*/
public enum VAntes implements IVDoc<CAntes>, Observer {
public enum VAntes implements IVDoc<CAntes> {
/** */
SINGLETON_INSTANCE;
@@ -80,10 +78,7 @@ public enum VAntes implements IVDoc<CAntes>, Observer {
public final void setModel(Iterable<Player> playerz) {
players = playerz;
for(Player p: players) {
p.getZone(ZoneType.Ante).addObserver(this);
}
update(null, null);
update();
}
/* (non-Javadoc)
@@ -126,9 +121,7 @@ public enum VAntes implements IVDoc<CAntes>, Observer {
return CAntes.SINGLETON_INSTANCE;
}
//========== Setters / getters
@Override
public void update(Observable o, Object arg) {
public void update() {
allAntes.clear();
pnl.removeAll();

View File

@@ -143,7 +143,7 @@ public enum VPlayers implements IVDoc<CPlayers> {
/** @param p0 {@link forge.game.player.Player} */
public void update() {
// No need to update if this panel isn't showing
if (!this.equals(parentCell.getSelected())) { return; }
if (parentCell == null || !this.equals(parentCell.getSelected())) { return; }
for(Entry<Player, JLabel[]> rr : infoLBLs.entrySet()) {
Player p0 = rr.getKey();

View File

@@ -0,0 +1,246 @@
package forge.gui.toolbox.special;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import net.miginfocom.swing.MigLayout;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.base.Function;
import forge.Constant.Preferences;
import forge.card.MagicColor;
import forge.card.mana.ManaPool;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
import forge.gui.ForgeAction;
import forge.gui.match.controllers.CPlayers;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FSkin.SkinProp;
/**
* TODO: Write javadoc for this type.
*
*/
public class PlayerDetailsPanel extends JPanel {
private static final long serialVersionUID = 8444559244193214459L;
private Player player;
// Info labels
private FLabel lblHand = getBuiltFLabel(FSkin.ZoneImages.ICO_HAND, "99", "Cards in hand");
private FLabel lblGraveyard = getBuiltFLabel(FSkin.ZoneImages.ICO_GRAVEYARD, "99", "Cards in graveyard");
private FLabel lblLibrary = getBuiltFLabel(FSkin.ZoneImages.ICO_LIBRARY, "99", "Cards in library");
private FLabel lblExile = getBuiltFLabel(FSkin.ZoneImages.ICO_EXILE, "99", "Exiled cards");
private FLabel lblFlashback = getBuiltFLabel(FSkin.ZoneImages.ICO_FLASHBACK, "99", "Flashback cards");
private FLabel lblPoison = getBuiltFLabel(FSkin.ZoneImages.ICO_POISON, "99", "Poison counters");
private final List<Pair<FLabel, Byte>> manaLabels = new ArrayList<Pair<FLabel,Byte>>();
private FLabel getBuiltFLabel(SkinProp p0, String s0, String s1) {
return new FLabel.Builder().icon(new ImageIcon(FSkin.getImage(p0)))
.opaque(false).fontSize(14)
.fontStyle(Font.BOLD).iconInBackground()
.text(s0).tooltip(s1).fontAlign(SwingConstants.RIGHT).build();
}
public PlayerDetailsPanel(Player player) {
this.player = player;
manaLabels.add(Pair.of(getBuiltFLabel(FSkin.ManaImages.IMG_BLACK, "99", "Black mana"), MagicColor.BLACK));
manaLabels.add(Pair.of(getBuiltFLabel(FSkin.ManaImages.IMG_BLUE, "99", "Blue mana"), MagicColor.BLUE));
manaLabels.add(Pair.of(getBuiltFLabel(FSkin.ManaImages.IMG_GREEN, "99", "Green mana"), MagicColor.GREEN));
manaLabels.add(Pair.of(getBuiltFLabel(FSkin.ManaImages.IMG_RED, "99", "Red mana"), MagicColor.RED));
manaLabels.add(Pair.of(getBuiltFLabel(FSkin.ManaImages.IMG_WHITE, "99", "White mana"), MagicColor.WHITE));
manaLabels.add(Pair.of(getBuiltFLabel(FSkin.ManaImages.IMG_COLORLESS, "99", "Colorless mana"), (byte)0));
setOpaque(false);
setLayout(new MigLayout("insets 0, gap 0, wrap"));
populateDetails();
updateZones();
updateManaPool();
//updateDetails();
}
/** Adds various labels to pool area JPanel container. */
private void populateDetails() {
final JPanel row1 = new JPanel(new MigLayout("insets 0, gap 0"));
final JPanel row2 = new JPanel(new MigLayout("insets 0, gap 0"));
final JPanel row3 = new JPanel(new MigLayout("insets 0, gap 0"));
final JPanel row4 = new JPanel(new MigLayout("insets 0, gap 0"));
final JPanel row5 = new JPanel(new MigLayout("insets 0, gap 0"));
final JPanel row6 = new JPanel(new MigLayout("insets 0, gap 0"));
row1.setBackground(FSkin.getColor(FSkin.Colors.CLR_ZEBRA));
row2.setOpaque(false);
row3.setBackground(FSkin.getColor(FSkin.Colors.CLR_ZEBRA));
row4.setOpaque(false);
row5.setBackground(FSkin.getColor(FSkin.Colors.CLR_ZEBRA));
row6.setOpaque(false);
// Hand, library, graveyard, exile, flashback, poison labels
final String constraintsCell = "w 45%!, h 100%!, gap 0 5% 2px 2px";
row1.add(lblHand, constraintsCell);
row1.add(lblLibrary, constraintsCell);
row2.add(lblGraveyard, constraintsCell);
row2.add(lblExile, constraintsCell);
row3.add(lblFlashback, constraintsCell);
row3.add(lblPoison, constraintsCell);
row4.add(manaLabels.get(0).getLeft(), constraintsCell);
row4.add(manaLabels.get(1).getLeft(), constraintsCell);
row5.add(manaLabels.get(2).getLeft(), constraintsCell);
row5.add(manaLabels.get(3).getLeft(), constraintsCell);
row6.add(manaLabels.get(4).getLeft(), constraintsCell);
row6.add(manaLabels.get(5).getLeft(), constraintsCell);
final String constraintsRow = "w 100%!, h 16%!";
this.add(row1, constraintsRow + ", gap 0 0 4% 0");
this.add(row2, constraintsRow);
this.add(row3, constraintsRow);
this.add(row4, constraintsRow);
this.add(row5, constraintsRow);
this.add(row6, constraintsRow);
}
/**
* Handles observer update of player Zones - hand, graveyard, etc.
*
* @param p0 &emsp; {@link forge.game.player.Player}
*/
public void updateZones() {
this.getLblHand().setText("" + player.getZone(ZoneType.Hand).size());
final String handMaxToolTip = player.isUnlimitedHandSize()
? "no maximum hand size" : String.valueOf(player.getMaxHandSize());
this.getLblHand().setToolTipText("Cards in hand (max: " + handMaxToolTip + ")");
this.getLblGraveyard().setText("" + player.getZone(ZoneType.Graveyard).size());
this.getLblLibrary().setText("" + player.getZone(ZoneType.Library).size());
this.getLblFlashback().setText("" + player.getCardsActivableInExternalZones().size());
this.getLblExile().setText("" + player.getZone(ZoneType.Exile).size());
}
/**
* Handles observer update of non-Zone details - life, poison, etc. Also
* updates "players" panel in tabber for this player.
*
* @param p0 &emsp; {@link forge.game.player.Player}
*/
public void updateDetails() {
// "Players" panel update
CPlayers.SINGLETON_INSTANCE.update();
// Poison/life
this.getLblPoison().setText("" + player.getPoisonCounters());
Color poisonFg = player.getPoisonCounters() >= 8 ? Color.red : FSkin.getColor(FSkin.Colors.CLR_TEXT);
this.getLblPoison().setForeground(poisonFg);
}
/**
* Handles observer update of the mana pool.
*
* @param p0 &emsp; {@link forge.game.player.Player}
*/
public void updateManaPool() {
ManaPool m = player.getManaPool();
for(Pair<FLabel, Byte> label : manaLabels)
label.getKey().setText(Integer.toString(m.getAmountOfColor(label.getRight())));
}
/** @return {@link javax.swing.JLabel} */
public FLabel getLblHand() {
return this.lblHand;
}
/** @return {@link javax.swing.JLabel} */
public FLabel getLblLibrary() {
return this.lblLibrary;
}
public final Iterable<Pair<FLabel, Byte>> getManaLabels() {
return manaLabels;
}
/** @return {@link javax.swing.JLabel} */
public JLabel getLblGraveyard() {
return this.lblGraveyard;
}
/** @return {@link javax.swing.JLabel} */
public JLabel getLblExile() {
return this.lblExile;
}
/** @return {@link javax.swing.JLabel} */
public JLabel getLblFlashback() {
return this.lblFlashback;
}
/** @return {@link javax.swing.JLabel} */
public JLabel getLblPoison() {
return this.lblPoison;
}
/**
* TODO: Write javadoc for this method.
* @param handAction
* @param libraryAction
* @param exileAction
* @param graveAction
* @param flashBackAction
* @param manaAction
*/
public void setupMouseActions(final ForgeAction handAction, final ForgeAction libraryAction, final ForgeAction exileAction,
final ForgeAction graveAction, final ForgeAction flashBackAction, final Function<Byte, Void> manaAction) {
// Detail label listeners
lblGraveyard.setHoverable(true);
lblGraveyard.addMouseListener(new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) { graveAction.actionPerformed(null); } } );
lblExile.setHoverable(true);
lblExile.addMouseListener(new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) { exileAction.actionPerformed(null); } } );
if (Preferences.DEV_MODE) {
lblLibrary.setHoverable(true);
lblLibrary.addMouseListener(new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) { libraryAction.actionPerformed(null); } } );
}
lblHand.setHoverable(true);
lblHand.addMouseListener(new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) { handAction.actionPerformed(null); } } );
lblFlashback.setHoverable(true);
lblFlashback.addMouseListener(new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) {flashBackAction.actionPerformed(null); } } );
for(final Pair<FLabel, Byte> labelPair : getManaLabels()) {
labelPair.getLeft().setHoverable(true);
labelPair.getLeft().addMouseListener(new MouseAdapter() { @Override
public void mousePressed(final MouseEvent e) {
manaAction.apply(labelPair.getRight()); } }
);
}
}
}

View File

@@ -6,17 +6,16 @@ import forge.card.spellability.SpellAbility;
import forge.game.event.GameEventCardChangeZone;
import forge.game.event.GameEventCardDamaged;
import forge.game.event.GameEventCardDestroyed;
import forge.game.event.GameEventCardEquipped;
import forge.game.event.GameEventCardAttachment;
import forge.game.event.GameEventCardRegenerated;
import forge.game.event.GameEventCardSacrificed;
import forge.game.event.GameEventCounterAdded;
import forge.game.event.GameEventCounterRemoved;
import forge.game.event.GameEventCardCounters;
import forge.game.event.GameEventGameOutcome;
import forge.game.event.GameEventTurnEnded;
import forge.game.event.GameEvent;
import forge.game.event.GameEventFlipCoin;
import forge.game.event.GameEventLandPlayed;
import forge.game.event.GameEventLifeLoss;
import forge.game.event.GameEventPlayerLivesChanged;
import forge.game.event.GameEventPlayerPoisoned;
import forge.game.event.GameEventCardTapped;
import forge.game.event.GameEventShuffle;
@@ -33,7 +32,7 @@ public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> {
public SoundEffectType visit(GameEventCardDamaged event) { return SoundEffectType.Damage; }
public SoundEffectType visit(GameEventCardDestroyed event) { return SoundEffectType.Destroy; }
public SoundEffectType visit(GameEventCardEquipped event) { return SoundEffectType.Equip; }
public SoundEffectType visit(GameEventCardAttachment event) { return SoundEffectType.Equip; }
public SoundEffectType visit(GameEventCardChangeZone event) {
ZoneType from = event.from == null ? null : event.from.getZoneType();
ZoneType to = event.to.getZoneType();
@@ -46,11 +45,10 @@ public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> {
}
public SoundEffectType visit(GameEventCardRegenerated event) { return SoundEffectType.Regen; }
public SoundEffectType visit(GameEventCardSacrificed event) { return SoundEffectType.Sacrifice; }
public SoundEffectType visit(GameEventCounterAdded event) { return event.Amount > 0 ? SoundEffectType.AddCounter : null; }
public SoundEffectType visit(GameEventCounterRemoved event) { return event.Amount > 0 ? SoundEffectType.RemoveCounter : null; }
public SoundEffectType visit(GameEventCardCounters event) { return event.newValue > event.oldValue ? SoundEffectType.AddCounter : event.newValue < event.oldValue ? SoundEffectType.RemoveCounter : null; }
public SoundEffectType visit(GameEventTurnEnded event) { return SoundEffectType.EndOfTurn; }
public SoundEffectType visit(GameEventFlipCoin event) { return SoundEffectType.FlipCoin; }
public SoundEffectType visit(GameEventLifeLoss event) { return SoundEffectType.LifeLoss; }
public SoundEffectType visit(GameEventPlayerLivesChanged event) { return SoundEffectType.LifeLoss; }
public SoundEffectType visit(GameEventPlayerPoisoned event) { return SoundEffectType.Poison; }
public SoundEffectType visit(GameEventShuffle event) { return SoundEffectType.Shuffle; }
public SoundEffectType visit(GameEventTokenCreated event) { return SoundEffectType.Token; }

View File

@@ -7,6 +7,7 @@ import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
/**
* TODO: Write javadoc for this type.
@@ -37,6 +38,7 @@ public class Lang {
return has1 ? (has2 ? s1 + " and " + s2 : s1) : (has2 ? s2 : "");
}
public static <T> String joinHomogenous(Iterable<T> objects) { return joinHomogenous(Lists.newArrayList(objects)); }
public static <T> String joinHomogenous(Collection<T> objects) { return joinHomogenous(objects, null, "and"); }
public static <T> String joinHomogenous(Collection<T> objects, Function<T, String> accessor) {
return joinHomogenous(objects, accessor, "and");

View File

@@ -1,40 +0,0 @@
/*
* Forge: Play Magic: the Gathering.
* Copyright (C) 2011 Forge Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package forge.util;
import java.util.Observable;
/**
* <p>
* MyObservable class.
* </p>
*
* @author Forge
* @version $Id$
*/
public class MyObservable extends Observable {
/**
* <p>
* updateObservers.
* </p>
*/
public final void updateObservers() {
this.setChanged();
this.notifyObservers();
}
}

View File

@@ -44,6 +44,7 @@ import forge.card.CardEdition;
import forge.card.mana.ManaCost;
import forge.game.combat.Combat;
import forge.gui.CardContainer;
import forge.gui.match.CMatchUI;
import forge.gui.toolbox.CardFaceSymbols;
import forge.properties.ForgePreferences.FPref;
import forge.view.arcane.util.OutlinedLabel;
@@ -321,7 +322,7 @@ public class CardPanel extends JPanel implements CardContainer {
final int offset = this.isTapped() ? 1 : 0;
// Magenta outline for when card was chosen to pay
if (this.getCard().isUsedToPay()) {
if (CMatchUI.SINGLETON_INSTANCE.isUsedToPay(this.getCard())) {
g2d.setColor(Color.magenta);
final int n2 = Math.max(1, Math.round(2 * this.cardWidth * CardPanel.SELECTED_BORDER_SIZE));
g2d.fillRoundRect(this.cardXOffset - n2, (this.cardYOffset - n2) + offset, this.cardWidth + (n2 * 2), this.cardHeight + (n2 * 2), cornerSize + n2, cornerSize + n2);
@@ -424,7 +425,7 @@ public class CardPanel extends JPanel implements CardContainer {
CardFaceSymbols.drawSymbol("phasing", g, stateXSymbols, ySymbols);
}
if (card.isUsedToPay()) {
if (CMatchUI.SINGLETON_INSTANCE.isUsedToPay(card)) {
CardFaceSymbols.drawSymbol("sacrifice", g, (this.cardXOffset + (this.cardWidth / 2)) - 20,
(this.cardYOffset + (this.cardHeight / 2)) - 20);
}

View File

@@ -24,8 +24,6 @@ import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.JScrollPane;
import forge.Card;
@@ -499,18 +497,10 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
* @param newList
* an array of {@link forge.Card} objects.
*/
private final AtomicBoolean wantRedraw = new AtomicBoolean(false);
public void setupPlayZone() {
boolean wasSet = wantRedraw.getAndSet(true);
if(wasSet) return;
FThreads.delayInEDT(50, new Runnable() { // postpone play area update per 50ms
@Override
public void run() {
wantRedraw.set(false);
FThreads.assertExecutedByEdt(true);
setupPlayZone(model);
}
});
}
public void setupPlayZone(final List<Card> model) {