mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
Dependency tab (#7013)
This commit is contained in:
@@ -707,7 +707,7 @@ public class GameAction {
|
||||
// needed for ETB lookahead like Bronzehide Lion
|
||||
stAb.putParam("AffectedZone", "All");
|
||||
SpellAbilityEffect.addForgetOnMovedTrigger(eff, "Battlefield");
|
||||
game.getAction().moveToCommand(eff, cause);
|
||||
eff.getOwner().getZone(ZoneType.Command).add(eff);
|
||||
}
|
||||
|
||||
eff.addRemembered(copied);
|
||||
@@ -1112,6 +1112,10 @@ public class GameAction {
|
||||
// search for cards with static abilities
|
||||
final FCollection<StaticAbility> staticAbilities = new FCollection<>();
|
||||
final CardCollection staticList = new CardCollection();
|
||||
Table<StaticAbility, StaticAbility, Set<StaticAbilityLayer>> dependencies = null;
|
||||
if (preList.isEmpty()) {
|
||||
dependencies = HashBasedTable.create();
|
||||
}
|
||||
|
||||
game.forEachCardInGame(new Visitor<Card>() {
|
||||
@Override
|
||||
@@ -1146,7 +1150,7 @@ public class GameAction {
|
||||
StaticAbility stAb = staticsForLayer.get(0);
|
||||
// dependency with CDA seems unlikely
|
||||
if (!stAb.isCharacteristicDefining()) {
|
||||
stAb = findStaticAbilityToApply(layer, staticsForLayer, preList, affectedPerAbility);
|
||||
stAb = findStaticAbilityToApply(layer, staticsForLayer, preList, affectedPerAbility, dependencies);
|
||||
}
|
||||
staticsForLayer.remove(stAb);
|
||||
final CardCollectionView previouslyAffected = affectedPerAbility.get(stAb);
|
||||
@@ -1233,6 +1237,8 @@ public class GameAction {
|
||||
game.getTriggerHandler().runTrigger(TriggerType.Always, runParams, false);
|
||||
|
||||
game.getTriggerHandler().runTrigger(TriggerType.Immediate, runParams, false);
|
||||
|
||||
game.getView().setDependencies(dependencies);
|
||||
}
|
||||
|
||||
// Update P/T and type in the view only once after all the cards have been processed, to avoid flickering
|
||||
@@ -1251,7 +1257,8 @@ public class GameAction {
|
||||
game.getTracker().unfreeze();
|
||||
}
|
||||
|
||||
private StaticAbility findStaticAbilityToApply(StaticAbilityLayer layer, List<StaticAbility> staticsForLayer, CardCollectionView preList, Map<StaticAbility, CardCollectionView> affectedPerAbility) {
|
||||
private StaticAbility findStaticAbilityToApply(StaticAbilityLayer layer, List<StaticAbility> staticsForLayer, CardCollectionView preList, Map<StaticAbility, CardCollectionView> affectedPerAbility,
|
||||
Table<StaticAbility, StaticAbility, Set<StaticAbilityLayer>> dependencies) {
|
||||
if (staticsForLayer.size() == 1) {
|
||||
return staticsForLayer.get(0);
|
||||
}
|
||||
@@ -1309,6 +1316,13 @@ public class GameAction {
|
||||
if (dependency) {
|
||||
dependencyGraph.addVertex(otherStAb);
|
||||
dependencyGraph.addEdge(stAb, otherStAb);
|
||||
if (dependencies != null) {
|
||||
if (dependencies.contains(stAb, otherStAb)) {
|
||||
dependencies.get(stAb, otherStAb).add(layer);
|
||||
} else {
|
||||
dependencies.put(stAb, otherStAb, EnumSet.of(layer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// undo changes and check next pair
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package forge.game;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Table;
|
||||
import com.google.common.collect.Table.Cell;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.deck.Deck;
|
||||
import forge.game.GameOutcome.AnteResult;
|
||||
@@ -16,6 +20,8 @@ import forge.game.phase.PhaseType;
|
||||
import forge.game.player.PlayerView;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.game.spellability.StackItemView;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
import forge.game.staticability.StaticAbilityLayer;
|
||||
import forge.game.zone.MagicStack;
|
||||
import forge.trackable.TrackableCollection;
|
||||
import forge.trackable.TrackableObject;
|
||||
@@ -200,15 +206,36 @@ public class GameView extends TrackableObject {
|
||||
public TrackableCollection<CardView> getRevealedCollection() {
|
||||
return get(TrackableProperty.RevealedCardsCollection);
|
||||
}
|
||||
|
||||
public void updateRevealedCards(TrackableCollection<CardView> collection) {
|
||||
set(TrackableProperty.RevealedCardsCollection, collection);
|
||||
}
|
||||
|
||||
public String getDependencies() {
|
||||
return get(TrackableProperty.Dependencies);
|
||||
}
|
||||
public void setDependencies(Table<StaticAbility, StaticAbility, Set<StaticAbilityLayer>> dependencies) {
|
||||
if (dependencies.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StaticAbilityLayer layer = null;
|
||||
for (StaticAbilityLayer sal : StaticAbilityLayer.CONTINUOUS_LAYERS_WITH_DEPENDENCY) {
|
||||
for (Cell<StaticAbility, StaticAbility, Set<StaticAbilityLayer>> dep : dependencies.cellSet()) {
|
||||
if (dep.getValue().contains(sal)) {
|
||||
if (layer != sal) {
|
||||
layer = sal;
|
||||
sb.append("Layer " + layer.num).append(": ");
|
||||
}
|
||||
sb.append(dep.getColumnKey().getHostCard().toString()).append(" <- ").append(dep.getRowKey().getHostCard().toString()).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
set(TrackableProperty.Dependencies, sb.toString());
|
||||
}
|
||||
|
||||
public CombatView getCombat() {
|
||||
return get(TrackableProperty.CombatView);
|
||||
}
|
||||
|
||||
public void updateCombatView(CombatView combatView) {
|
||||
set(TrackableProperty.CombatView, combatView);
|
||||
}
|
||||
|
||||
@@ -3,35 +3,44 @@ package forge.game.staticability;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
public enum StaticAbilityLayer {
|
||||
/** Layer 1 for control-changing effects. */
|
||||
COPY,
|
||||
/** Layer 1 for copiable values. */
|
||||
COPY("1"),
|
||||
|
||||
/** Layer 2 for control-changing effects. */
|
||||
CONTROL,
|
||||
CONTROL("2"),
|
||||
|
||||
/** Layer 3 for text-changing effects. */
|
||||
TEXT,
|
||||
TEXT("3"),
|
||||
|
||||
/** Layer 4 for type-changing effects. */
|
||||
TYPE,
|
||||
TYPE("4"),
|
||||
|
||||
/** Layer 5 for color-changing effects. */
|
||||
COLOR,
|
||||
COLOR("5"),
|
||||
|
||||
/** Layer 6 for ability effects. */
|
||||
ABILITIES,
|
||||
ABILITIES("6"),
|
||||
|
||||
/** Layer 7a for characteristic-defining power/toughness effects. */
|
||||
CHARACTERISTIC,
|
||||
CHARACTERISTIC("7a"),
|
||||
|
||||
/** Layer 7b for power- and/or toughness-setting effects. */
|
||||
SETPT,
|
||||
SETPT("7b"),
|
||||
|
||||
/** Layer 7c for power- and/or toughness-modifying effects. */
|
||||
MODIFYPT,
|
||||
MODIFYPT("7c"),
|
||||
|
||||
/** Layer 7d for power- and/or toughness-switching effects. */
|
||||
//SWITCHPT("7d"),
|
||||
|
||||
/** Layer for game rule-changing effects. */
|
||||
RULES;
|
||||
RULES("8");
|
||||
|
||||
public final String num;
|
||||
|
||||
StaticAbilityLayer(String n) {
|
||||
num = n;
|
||||
}
|
||||
|
||||
public final static ImmutableList<StaticAbilityLayer> CONTINUOUS_LAYERS =
|
||||
ImmutableList.of(COPY, CONTROL, TEXT, TYPE, COLOR, ABILITIES, CHARACTERISTIC, SETPT, MODIFYPT, RULES);
|
||||
|
||||
@@ -301,7 +301,8 @@ public enum TrackableProperty {
|
||||
GameLog(TrackableTypes.StringType),
|
||||
NeedsPhaseRedrawn(TrackableTypes.BooleanType),
|
||||
PlayerTurn(TrackableTypes.PlayerViewType, FreezeMode.IgnoresFreeze),
|
||||
Phase(TrackableTypes.EnumType(PhaseType.class), FreezeMode.IgnoresFreeze);
|
||||
Phase(TrackableTypes.EnumType(PhaseType.class), FreezeMode.IgnoresFreeze),
|
||||
Dependencies(TrackableTypes.StringType);
|
||||
|
||||
public enum FreezeMode {
|
||||
IgnoresFreeze,
|
||||
|
||||
@@ -87,6 +87,7 @@ public enum EDocID {
|
||||
REPORT_MESSAGE (),
|
||||
REPORT_STACK (),
|
||||
REPORT_COMBAT (),
|
||||
REPORT_DEPENDENCIES (),
|
||||
REPORT_LOG (),
|
||||
|
||||
DEV_MODE (),
|
||||
|
||||
@@ -104,6 +104,7 @@ import forge.player.PlayerZoneUpdate;
|
||||
import forge.player.PlayerZoneUpdates;
|
||||
import forge.screens.match.controllers.CAntes;
|
||||
import forge.screens.match.controllers.CCombat;
|
||||
import forge.screens.match.controllers.CDependencies;
|
||||
import forge.screens.match.controllers.CDetailPicture;
|
||||
import forge.screens.match.controllers.CDev;
|
||||
import forge.screens.match.controllers.CDock;
|
||||
@@ -167,6 +168,7 @@ public final class CMatchUI
|
||||
|
||||
private final CAntes cAntes = new CAntes(this);
|
||||
private final CCombat cCombat = new CCombat();
|
||||
private final CDependencies cDependencies = new CDependencies(this);
|
||||
private final CDetailPicture cDetailPicture = new CDetailPicture(this);
|
||||
private final CDev cDev = new CDev(this);
|
||||
private final CDock cDock = new CDock(this);
|
||||
@@ -190,6 +192,7 @@ public final class CMatchUI
|
||||
this.myDocs.put(EDocID.REPORT_MESSAGE, getCPrompt().getView());
|
||||
this.myDocs.put(EDocID.REPORT_STACK, getCStack().getView());
|
||||
this.myDocs.put(EDocID.REPORT_COMBAT, cCombat.getView());
|
||||
this.myDocs.put(EDocID.REPORT_DEPENDENCIES, cDependencies.getView());
|
||||
this.myDocs.put(EDocID.REPORT_LOG, cLog.getView());
|
||||
this.myDocs.put(EDocID.DEV_MODE, getCDev().getView());
|
||||
this.myDocs.put(EDocID.BUTTON_DOCK, getCDock().getView());
|
||||
@@ -410,6 +413,11 @@ public final class CMatchUI
|
||||
cCombat.update();
|
||||
} // showCombat(CombatView)
|
||||
|
||||
@Override
|
||||
public void updateDependencies() {
|
||||
cDependencies.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDayTime(String daytime) {
|
||||
super.updateDayTime(daytime);
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package forge.screens.match.controllers;
|
||||
|
||||
import forge.game.GameView;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.screens.match.views.VDependencies;
|
||||
|
||||
/**
|
||||
* Controls the combat panel in the match UI.
|
||||
*
|
||||
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
|
||||
*
|
||||
*/
|
||||
public class CDependencies implements ICDoc {
|
||||
|
||||
private final CMatchUI matchUI;
|
||||
private final VDependencies view;
|
||||
public CDependencies(CMatchUI cMatchUI) {
|
||||
view = new VDependencies(this);
|
||||
matchUI = cMatchUI;
|
||||
}
|
||||
|
||||
public VDependencies getView() {
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#initialize()
|
||||
*/
|
||||
@Override
|
||||
public void initialize() {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#update()
|
||||
*/
|
||||
@Override
|
||||
public void update() {
|
||||
GameView game = matchUI.getGameView();
|
||||
if (game == null || game.getDependencies() == null) {
|
||||
return;
|
||||
}
|
||||
String dependencies = game.getDependencies();
|
||||
view.updateDependencies(dependencies.lines().count(), dependencies);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Nate
|
||||
*
|
||||
* 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.screens.match.views;
|
||||
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
import forge.gui.framework.EDocID;
|
||||
import forge.gui.framework.IVDoc;
|
||||
import forge.screens.match.controllers.CDependencies;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinnedTextArea;
|
||||
import forge.util.Localizer;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
/**
|
||||
* Assembles Swing components of layer dependencies.
|
||||
*
|
||||
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
|
||||
*/
|
||||
public class VDependencies implements IVDoc<CDependencies> {
|
||||
|
||||
// Fields used with interface IVDoc
|
||||
private DragCell parentCell;
|
||||
private final DragTab tab = new DragTab(Localizer.getInstance().getMessage("lblDependenciesTab"));
|
||||
|
||||
private final SkinnedTextArea tar = new SkinnedTextArea();
|
||||
|
||||
private final CDependencies controller;
|
||||
public VDependencies(final CDependencies controller) {
|
||||
this.controller = controller;
|
||||
tar.setOpaque(false);
|
||||
tar.setBorder(new FSkin.MatteSkinBorder(0, 0, 0, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS)));
|
||||
tar.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT));
|
||||
tar.setFocusable(false);
|
||||
tar.setLineWrap(true);
|
||||
}
|
||||
|
||||
//========== Overridden methods
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#populate()
|
||||
*/
|
||||
@Override
|
||||
public void populate() {
|
||||
parentCell.getBody().removeAll();
|
||||
parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0, wrap"));
|
||||
parentCell.getBody().add(tar, "w 95%!, gapleft 3%, gaptop 1%, h 95%");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#setParentCell()
|
||||
*/
|
||||
@Override
|
||||
public void setParentCell(final DragCell cell0) {
|
||||
this.parentCell = cell0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#getParentCell()
|
||||
*/
|
||||
@Override
|
||||
public DragCell getParentCell() {
|
||||
return this.parentCell;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#getDocumentID()
|
||||
*/
|
||||
@Override
|
||||
public EDocID getDocumentID() {
|
||||
return EDocID.REPORT_DEPENDENCIES;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#getTabLabel()
|
||||
*/
|
||||
@Override
|
||||
public DragTab getTabLabel() {
|
||||
return tab;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#getLayoutControl()
|
||||
*/
|
||||
@Override
|
||||
public CDependencies getLayoutControl() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
//========= Observer update methods
|
||||
|
||||
public void updateDependencies(final long cntDependencies, final String desc) {
|
||||
tab.setText(cntDependencies > 0 ? (Localizer.getInstance().getMessage("lblDependenciesTab") + " : " + cntDependencies) : Localizer.getInstance().getMessage("lblDependenciesTab"));
|
||||
|
||||
// No need to update this unless it's showing
|
||||
if (parentCell == null || !this.equals(parentCell.getSelected())) { return; }
|
||||
|
||||
tar.setText(desc);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
<doc>REPORT_STACK</doc>
|
||||
<doc>REPORT_COMBAT</doc>
|
||||
<doc>REPORT_LOG</doc>
|
||||
<doc>REPORT_DEPENDENCIES</doc>
|
||||
</cell>
|
||||
<cell x="0.0" y="0.643" w="0.2" h="0.357">
|
||||
<doc>REPORT_MESSAGE</doc>
|
||||
|
||||
@@ -1105,6 +1105,7 @@ lblPlayers=Spieler
|
||||
lblLog=Bericht
|
||||
lblDev=Entw.
|
||||
lblCombatTab=Kampf
|
||||
lblDependenciesTab=Dependencies
|
||||
lblStack=Stapel
|
||||
lblMustWaitPriority=Warte auf Priorität...
|
||||
#FDeckEditor.java
|
||||
|
||||
@@ -1118,6 +1118,7 @@ lblPlayers=Players
|
||||
lblLog=Log
|
||||
lblDev=Dev
|
||||
lblCombatTab=Combat
|
||||
lblDependenciesTab=Dependencies
|
||||
lblStack=Stack
|
||||
lblMustWaitPriority=Must wait for priority...
|
||||
#FDeckEditor.java
|
||||
|
||||
@@ -1111,6 +1111,7 @@ lblPlayers=Jugadores
|
||||
lblLog=Log
|
||||
lblDev=Dev
|
||||
lblCombatTab=Combate
|
||||
lblDependenciesTab=Dependencies
|
||||
lblStack=Pila
|
||||
lblMustWaitPriority=Debes esperar debido a la prioridad...
|
||||
#FDeckEditor.java
|
||||
|
||||
@@ -1109,6 +1109,7 @@ lblPlayers=Joueurs
|
||||
lblLog=Journal
|
||||
lblDev=Dev
|
||||
lblCombatTab=Combat
|
||||
lblDependenciesTab=Dependencies
|
||||
lblStack=Empiler
|
||||
lblMustWaitPriority=Doit attendre la priorité...
|
||||
#FDeckEditor.java
|
||||
|
||||
@@ -1106,6 +1106,7 @@ lblPlayers=Giocatori
|
||||
lblLog=Registro
|
||||
lblDev=Sviluppo
|
||||
lblCombatTab=Combattimento
|
||||
lblDependenciesTab=Dependencies
|
||||
lblStack=Pila
|
||||
lblMustWaitPriority=Devi aspettare la priorità ...
|
||||
#FDeckEditor.java
|
||||
|
||||
@@ -1108,6 +1108,7 @@ lblPlayers=プレイヤー
|
||||
lblLog=ログ
|
||||
lblDev=開発者
|
||||
lblCombatTab=戦闘
|
||||
lblDependenciesTab=Dependencies
|
||||
lblStack=スタック
|
||||
lblMustWaitPriority=優先権を待つ必要があります...
|
||||
#FDeckEditor.java
|
||||
|
||||
@@ -1133,6 +1133,7 @@ lblPlayers=Jogadores
|
||||
lblLog=Registros
|
||||
lblDev=Desenv.
|
||||
lblCombatTab=Batalha
|
||||
lblDependenciesTab=Dependencies
|
||||
lblStack=Pilha
|
||||
lblMustWaitPriority=Deve esperar pela prioridade...
|
||||
#FDeckEditor.java
|
||||
|
||||
@@ -1112,6 +1112,7 @@ lblPlayers=玩家列表
|
||||
lblLog=日志
|
||||
lblDev=开发者工具
|
||||
lblCombatTab=战斗
|
||||
lblDependenciesTab=Dependencies
|
||||
lblStack=堆叠
|
||||
lblMustWaitPriority=等待获得优先权
|
||||
#FDeckEditor.java
|
||||
|
||||
@@ -846,5 +846,8 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
}
|
||||
daytime = null;
|
||||
}
|
||||
|
||||
public void updateDependencies() {
|
||||
}
|
||||
// End of Choice code
|
||||
}
|
||||
|
||||
@@ -203,6 +203,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
@Override
|
||||
public Void visit(final GameEventPlayerPriority event) {
|
||||
needCombatUpdate = true;
|
||||
matchController.updateDependencies();
|
||||
return processEvent();
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,8 @@ public interface IGuiGame {
|
||||
void updateLives(Iterable<PlayerView> livesUpdate);
|
||||
void updateShards(Iterable<PlayerView> shardsUpdate);
|
||||
|
||||
void updateDependencies();
|
||||
|
||||
void setPanelSelection(CardView hostCard);
|
||||
|
||||
SpellAbilityView getAbilityToPlay(CardView hostCard, List<SpellAbilityView> abilities, ITriggerEvent triggerEvent);
|
||||
|
||||
Reference in New Issue
Block a user