- Added an option to make planeswalker attacker targeting arrows somewhat darker to make them easier to see on the battlefield.

- Added code support to differentiate stack targeting arrows in color as well (currently not used).
This commit is contained in:
Agetian
2017-08-24 05:48:17 +00:00
parent 2851e51af8
commit 3e4efc22a6
7 changed files with 122 additions and 41 deletions

View File

@@ -106,6 +106,7 @@ public enum CSubmenuPreferences implements ICDoc {
lstControls.add(Pair.of(view.getCbAltSoundSystem(), FPref.UI_ALT_SOUND_SYSTEM)); lstControls.add(Pair.of(view.getCbAltSoundSystem(), FPref.UI_ALT_SOUND_SYSTEM));
lstControls.add(Pair.of(view.getCbUiForTouchScreen(), FPref.UI_FOR_TOUCHSCREN)); lstControls.add(Pair.of(view.getCbUiForTouchScreen(), FPref.UI_FOR_TOUCHSCREN));
lstControls.add(Pair.of(view.getCbTimedTargOverlay(), FPref.UI_TIMED_TARGETING_OVERLAY_UPDATES)); lstControls.add(Pair.of(view.getCbTimedTargOverlay(), FPref.UI_TIMED_TARGETING_OVERLAY_UPDATES));
lstControls.add(Pair.of(view.getCbTargOverlayDarkArrows(), FPref.UI_TARGETING_DARKER_PW_ARROWS));
lstControls.add(Pair.of(view.getCbCompactMainMenu(), FPref.UI_COMPACT_MAIN_MENU)); lstControls.add(Pair.of(view.getCbCompactMainMenu(), FPref.UI_COMPACT_MAIN_MENU));
lstControls.add(Pair.of(view.getCbPromptFreeBlocks(), FPref.MATCHPREF_PROMPT_FREE_BLOCKS)); lstControls.add(Pair.of(view.getCbPromptFreeBlocks(), FPref.MATCHPREF_PROMPT_FREE_BLOCKS));
lstControls.add(Pair.of(view.getCbPauseWhileMinimized(), FPref.UI_PAUSE_WHILE_MINIMIZED)); lstControls.add(Pair.of(view.getCbPauseWhileMinimized(), FPref.UI_PAUSE_WHILE_MINIMIZED));

View File

@@ -80,6 +80,7 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
private final JCheckBox cbAltSoundSystem = new OptionsCheckBox("Use Alternate Sound System"); private final JCheckBox cbAltSoundSystem = new OptionsCheckBox("Use Alternate Sound System");
private final JCheckBox cbUiForTouchScreen = new OptionsCheckBox("Enhance UI for Touchscreens"); private final JCheckBox cbUiForTouchScreen = new OptionsCheckBox("Enhance UI for Touchscreens");
private final JCheckBox cbTimedTargOverlay = new OptionsCheckBox("Enable Targeting Overlay Optimization"); private final JCheckBox cbTimedTargOverlay = new OptionsCheckBox("Enable Targeting Overlay Optimization");
private final JCheckBox cbTargOverlayDarkArrows = new OptionsCheckBox("Darker Arrows for Planeswalker Attackers");
private final JCheckBox cbCompactMainMenu = new OptionsCheckBox("Use Compact Main Sidebar Menu"); private final JCheckBox cbCompactMainMenu = new OptionsCheckBox("Use Compact Main Sidebar Menu");
private final JCheckBox cbDetailedPaymentDesc = new OptionsCheckBox("Spell Description in Payment Prompt"); private final JCheckBox cbDetailedPaymentDesc = new OptionsCheckBox("Spell Description in Payment Prompt");
private final JCheckBox cbPromptFreeBlocks = new OptionsCheckBox("Free Block Handling"); private final JCheckBox cbPromptFreeBlocks = new OptionsCheckBox("Free Block Handling");
@@ -276,7 +277,10 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
pnlPrefs.add(new NoteLabel("Stacks identical creatures on the battlefield like lands, artifacts, and enchantments."), descriptionConstraints); pnlPrefs.add(new NoteLabel("Stacks identical creatures on the battlefield like lands, artifacts, and enchantments."), descriptionConstraints);
pnlPrefs.add(cbTimedTargOverlay, titleConstraints); pnlPrefs.add(cbTimedTargOverlay, titleConstraints);
pnlPrefs.add(new NoteLabel("Enables throttling-based optimization of targeting overlay to reduce CPU use (only disable if you experience choppiness on older hardware, requires starting a new match)"), descriptionConstraints); pnlPrefs.add(new NoteLabel("Enables throttling-based optimization of targeting overlay to reduce CPU use (only disable if you experience choppiness on older hardware, requires starting a new match)."), descriptionConstraints);
pnlPrefs.add(cbTargOverlayDarkArrows, titleConstraints);
pnlPrefs.add(new NoteLabel("Makes the targeting overlay arrows darker for creatures attacking planeswalkers, to make those arrows easier to distinguish from the blocker arrows."), descriptionConstraints);
pnlPrefs.add(cbpCounterDisplayType, comboBoxConstraints); pnlPrefs.add(cbpCounterDisplayType, comboBoxConstraints);
pnlPrefs.add(new NoteLabel("Selects the style of the in-game counter display for cards. Text-based is a new tab-like display on the cards. Image-based is the old counter image. Hybrid displays both at once."), descriptionConstraints); pnlPrefs.add(new NoteLabel("Selects the style of the in-game counter display for cards. Text-based is a new tab-like display on the cards. Image-based is the old counter image. Hybrid displays both at once."), descriptionConstraints);
@@ -640,6 +644,11 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
return cbTimedTargOverlay; return cbTimedTargOverlay;
} }
/** @return {@link javax.swing.JCheckBox} */
public JCheckBox getCbTargOverlayDarkArrows() {
return cbTargOverlayDarkArrows;
}
public final JCheckBox getCbUiForTouchScreen() { public final JCheckBox getCbUiForTouchScreen() {
return cbUiForTouchScreen; return cbUiForTouchScreen;
} }

View File

@@ -64,7 +64,8 @@ public class TargetingOverlay {
private final CMatchUI matchUI; private final CMatchUI matchUI;
private final OverlayPanel pnl = new OverlayPanel(); private final OverlayPanel pnl = new OverlayPanel();
private final List<CardPanel> cardPanels = new ArrayList<CardPanel>(); private final List<CardPanel> cardPanels = new ArrayList<CardPanel>();
private final List<Arc> arcsFoe = new ArrayList<Arc>(); private final List<Arc> arcsFoeAtk = new ArrayList<Arc>();
private final List<Arc> arcsFoeDef = new ArrayList<Arc>();
private final List<Arc> arcsFriend = new ArrayList<Arc>(); private final List<Arc> arcsFriend = new ArrayList<Arc>();
private final ArcAssembler assembler = new ArcAssembler(); private final ArcAssembler assembler = new ArcAssembler();
private final Set<Integer> stackItemIDs = new HashSet<Integer>(); private final Set<Integer> stackItemIDs = new HashSet<Integer>();
@@ -87,6 +88,14 @@ public class TargetingOverlay {
private int allowedUpdates = 0; private int allowedUpdates = 0;
private final int MAX_CONSECUTIVE_UPDATES = 1; private final int MAX_CONSECUTIVE_UPDATES = 1;
private enum ArcConnection {
Friends,
FoesAttacking,
FoesBlocking,
FriendsStackTargeting,
FoesStackTargeting
}
/** /**
* Semi-transparent overlay panel. Should be used with layered panes. * Semi-transparent overlay panel. Should be used with layered panes.
*/ */
@@ -107,7 +116,8 @@ public class TargetingOverlay {
// Re-added as the new version was causing issues for at least one user. // Re-added as the new version was causing issues for at least one user.
private void assembleArcs(final CombatView combat) { private void assembleArcs(final CombatView combat) {
//List<VField> fields = VMatchUI.SINGLETON_INSTANCE.getFieldViews(); //List<VField> fields = VMatchUI.SINGLETON_INSTANCE.getFieldViews();
arcsFoe.clear(); arcsFoeAtk.clear();
arcsFoeDef.clear();
arcsFriend.clear(); arcsFriend.clear();
cardPanels.clear(); cardPanels.clear();
cardsVisualized.clear(); cardsVisualized.clear();
@@ -183,12 +193,14 @@ public class TargetingOverlay {
PlayerView activator = instance.getActivatingPlayer(); PlayerView activator = instance.getActivatingPlayer();
while (instance != null) { while (instance != null) {
for (CardView c : instance.getTargetCards()) { for (CardView c : instance.getTargetCards()) {
addArc(endpoints.get(c.getId()), itemLocOnScreen, activator.isOpponentOf(c.getController())); addArc(endpoints.get(c.getId()), itemLocOnScreen, activator.isOpponentOf(c.getController()) ?
ArcConnection.FoesStackTargeting : ArcConnection.FriendsStackTargeting);
} }
for (PlayerView p : instance.getTargetPlayers()) { for (PlayerView p : instance.getTargetPlayers()) {
Point point = getPlayerTargetingArrowPoint(p, locOnScreen); Point point = getPlayerTargetingArrowPoint(p, locOnScreen);
if(point != null) { if(point != null) {
addArc(point, itemLocOnScreen, activator.isOpponentOf(p)); addArc(point, itemLocOnScreen, activator.isOpponentOf(p) ?
ArcConnection.FoesStackTargeting : ArcConnection.FriendsStackTargeting);
} }
} }
instance = instance.getSubInstance(); instance = instance.getSubInstance();
@@ -232,7 +244,8 @@ public class TargetingOverlay {
} }
} }
//List<VField> fields = VMatchUI.SINGLETON_INSTANCE.getFieldViews(); //List<VField> fields = VMatchUI.SINGLETON_INSTANCE.getFieldViews();
arcsFoe.clear(); arcsFoeAtk.clear();
arcsFoeDef.clear();
arcsFriend.clear(); arcsFriend.clear();
cardPanels.clear(); cardPanels.clear();
cardsVisualized.clear(); cardsVisualized.clear();
@@ -339,12 +352,14 @@ public class TargetingOverlay {
PlayerView activator = instance.getActivatingPlayer(); PlayerView activator = instance.getActivatingPlayer();
while (instance != null) { while (instance != null) {
for (CardView c : instance.getTargetCards()) { for (CardView c : instance.getTargetCards()) {
addArc(endpoints.get(c.getId()), itemLocOnScreen, activator.isOpponentOf(c.getController())); addArc(endpoints.get(c.getId()), itemLocOnScreen, activator.isOpponentOf(c.getController()) ?
ArcConnection.FoesStackTargeting : ArcConnection.FriendsStackTargeting);
} }
for (PlayerView p : instance.getTargetPlayers()) { for (PlayerView p : instance.getTargetPlayers()) {
Point point = getPlayerTargetingArrowPoint(p, locOnScreen); Point point = getPlayerTargetingArrowPoint(p, locOnScreen);
if (point != null) { if (point != null) {
addArc(point, itemLocOnScreen, activator.isOpponentOf(p)); addArc(point, itemLocOnScreen, activator.isOpponentOf(p) ?
ArcConnection.FoesStackTargeting : ArcConnection.FriendsStackTargeting);
} }
} }
instance = instance.getSubInstance(); instance = instance.getSubInstance();
@@ -365,16 +380,22 @@ public class TargetingOverlay {
return point; return point;
} }
private void addArc(Point end, Point start, boolean connectsFoes) { private void addArc(Point end, Point start, ArcConnection connects) {
if (start == null || end == null) { if (start == null || end == null) {
return; return;
} }
if (connectsFoes) { switch (connects) {
arcsFoe.add(new Arc(end, start)); case Friends:
} case FriendsStackTargeting:
else {
arcsFriend.add(new Arc(end, start)); arcsFriend.add(new Arc(end, start));
break;
case FoesAttacking:
arcsFoeAtk.add(new Arc(end, start));
break;
case FoesBlocking:
case FoesStackTargeting:
arcsFoeDef.add(new Arc(end, start));
} }
} }
@@ -393,26 +414,26 @@ public class TargetingOverlay {
if (null != enchanting) { if (null != enchanting) {
if (enchanting.getController() != null && !enchanting.getController().equals(c.getController())) { if (enchanting.getController() != null && !enchanting.getController().equals(c.getController())) {
addArc(endpoints.get(enchanting.getId()), endpoints.get(c.getId()), false); addArc(endpoints.get(enchanting.getId()), endpoints.get(c.getId()), ArcConnection.Friends);
cardsVisualized.add(enchanting); cardsVisualized.add(enchanting);
} }
} }
if (null != equipping) { if (null != equipping) {
if (equipping.getController() != null && !equipping.getController().equals(c.getController())) { if (equipping.getController() != null && !equipping.getController().equals(c.getController())) {
addArc(endpoints.get(equipping.getId()), endpoints.get(c.getId()), false); addArc(endpoints.get(equipping.getId()), endpoints.get(c.getId()), ArcConnection.Friends);
cardsVisualized.add(equipping); cardsVisualized.add(equipping);
} }
} }
if (null != fortifying) { if (null != fortifying) {
if (fortifying.getController() != null && !fortifying.getController().equals(c.getController())) { if (fortifying.getController() != null && !fortifying.getController().equals(c.getController())) {
addArc(endpoints.get(fortifying.getId()), endpoints.get(c.getId()), false); addArc(endpoints.get(fortifying.getId()), endpoints.get(c.getId()), ArcConnection.Friends);
cardsVisualized.add(fortifying); cardsVisualized.add(fortifying);
} }
} }
if (null != enchantedBy) { if (null != enchantedBy) {
for (final CardView enc : enchantedBy) { for (final CardView enc : enchantedBy) {
if (enc.getController() != null && !enc.getController().equals(c.getController())) { if (enc.getController() != null && !enc.getController().equals(c.getController())) {
addArc(endpoints.get(c.getId()), endpoints.get(enc.getId()), false); addArc(endpoints.get(c.getId()), endpoints.get(enc.getId()), ArcConnection.Friends);
cardsVisualized.add(enc); cardsVisualized.add(enc);
} }
} }
@@ -420,7 +441,7 @@ public class TargetingOverlay {
if (null != equippedBy) { if (null != equippedBy) {
for (final CardView eq : equippedBy) { for (final CardView eq : equippedBy) {
if (eq.getController() != null && !eq.getController().equals(c.getController())) { if (eq.getController() != null && !eq.getController().equals(c.getController())) {
addArc(endpoints.get(c.getId()), endpoints.get(eq.getId()), false); addArc(endpoints.get(c.getId()), endpoints.get(eq.getId()), ArcConnection.Friends);
cardsVisualized.add(eq); cardsVisualized.add(eq);
} }
} }
@@ -428,31 +449,31 @@ public class TargetingOverlay {
if (null != fortifiedBy) { if (null != fortifiedBy) {
for (final CardView eq : fortifiedBy) { for (final CardView eq : fortifiedBy) {
if (eq.getController() != null && !eq.getController().equals(c.getController())) { if (eq.getController() != null && !eq.getController().equals(c.getController())) {
addArc(endpoints.get(c.getId()), endpoints.get(eq.getId()), false); addArc(endpoints.get(c.getId()), endpoints.get(eq.getId()), ArcConnection.Friends);
cardsVisualized.add(eq); cardsVisualized.add(eq);
} }
} }
} }
if (null != paired) { if (null != paired) {
addArc(endpoints.get(paired.getId()), endpoints.get(c.getId()), false); addArc(endpoints.get(paired.getId()), endpoints.get(c.getId()), ArcConnection.Friends);
cardsVisualized.add(paired); cardsVisualized.add(paired);
} }
if (null != combat) { if (null != combat) {
final GameEntityView defender = combat.getDefender(c); final GameEntityView defender = combat.getDefender(c);
// if c is attacking a planeswalker // if c is attacking a planeswalker
if (defender instanceof CardView) { if (defender instanceof CardView) {
addArc(endpoints.get(defender.getId()), endpoints.get(c.getId()), true); addArc(endpoints.get(defender.getId()), endpoints.get(c.getId()), ArcConnection.FoesAttacking);
} }
// if c is a planeswalker that's being attacked // if c is a planeswalker that's being attacked
for (final CardView pwAttacker : combat.getAttackersOf(c)) { for (final CardView pwAttacker : combat.getAttackersOf(c)) {
addArc(endpoints.get(c.getId()), endpoints.get(pwAttacker.getId()), true); addArc(endpoints.get(c.getId()), endpoints.get(pwAttacker.getId()), ArcConnection.FoesAttacking);
} }
for (final CardView attackingCard : combat.getAttackers()) { for (final CardView attackingCard : combat.getAttackers()) {
final Iterable<CardView> cards = combat.getPlannedBlockers(attackingCard); final Iterable<CardView> cards = combat.getPlannedBlockers(attackingCard);
if (cards == null) continue; if (cards == null) continue;
for (final CardView blockingCard : cards) { for (final CardView blockingCard : cards) {
if (!attackingCard.equals(c) && !blockingCard.equals(c)) { continue; } if (!attackingCard.equals(c) && !blockingCard.equals(c)) { continue; }
addArc(endpoints.get(attackingCard.getId()), endpoints.get(blockingCard.getId()), true); addArc(endpoints.get(attackingCard.getId()), endpoints.get(blockingCard.getId()), ArcConnection.FoesBlocking);
cardsVisualized.add(blockingCard); cardsVisualized.add(blockingCard);
} }
cardsVisualized.add(attackingCard); cardsVisualized.add(attackingCard);
@@ -552,6 +573,7 @@ public class TargetingOverlay {
super.paintComponent(g); super.paintComponent(g);
final ArcState overlaystate = matchUI.getCDock().getArcState(); final ArcState overlaystate = matchUI.getCDock().getArcState();
final boolean darkerPWArrows = FModel.getPreferences().getPrefBoolean(FPref.UI_TARGETING_DARKER_PW_ARROWS);
// Arcs are off // Arcs are off
if (overlaystate == ArcState.OFF) { return; } if (overlaystate == ArcState.OFF) { return; }
@@ -568,7 +590,7 @@ public class TargetingOverlay {
} }
} }
if (arcsFoe.isEmpty() && arcsFriend.isEmpty()) { if (arcsFoeAtk.isEmpty() && arcsFoeDef.isEmpty() && arcsFriend.isEmpty()) {
if (assembled) { if (assembled) {
// We still need to repaint to get rid of visual artifacts // We still need to repaint to get rid of visual artifacts
// The original (non-throttled) code did not do this repaint. // The original (non-throttled) code did not do this repaint.
@@ -589,9 +611,12 @@ public class TargetingOverlay {
if (colorCombat.getAlpha() == 0) { if (colorCombat.getAlpha() == 0) {
colorCombat = new Color(255, 0, 0, 153); colorCombat = new Color(255, 0, 0, 153);
} }
// For planeswalker attackers, use a somewhat darker shade if the player opts in
Color colorCombatAtk = darkerPWArrows ? colorCombat.darker() : colorCombat;
drawArcs(g2d, colorOther, arcsFriend); drawArcs(g2d, colorOther, arcsFriend);
drawArcs(g2d, colorCombat, arcsFoe); drawArcs(g2d, colorCombatAtk, arcsFoeAtk);
drawArcs(g2d, colorCombat, arcsFoeDef);
if (assembled || !useThrottling) { if (assembled || !useThrottling) {
FView.SINGLETON_INSTANCE.getFrame().repaint(); // repaint the match UI FView.SINGLETON_INSTANCE.getFrame().repaint(); // repaint the match UI

View File

@@ -22,6 +22,8 @@ import forge.assets.FSkinColor;
import forge.assets.FSkinColor.Colors; import forge.assets.FSkinColor.Colors;
import forge.game.card.CardView; import forge.game.card.CardView;
import forge.game.player.PlayerView; import forge.game.player.PlayerView;
import forge.model.FModel;
import forge.properties.ForgePreferences;
import forge.screens.match.views.VCardDisplayArea.CardAreaPanel; import forge.screens.match.views.VCardDisplayArea.CardAreaPanel;
import forge.toolbox.FDisplayObject; import forge.toolbox.FDisplayObject;
import forge.util.Utils; import forge.util.Utils;
@@ -33,47 +35,84 @@ public class TargetingOverlay {
private static final float BORDER_THICKNESS = Utils.scale(1); private static final float BORDER_THICKNESS = Utils.scale(1);
private static final float ARROW_THICKNESS = Utils.scale(5); private static final float ARROW_THICKNESS = Utils.scale(5);
private static final float ARROW_SIZE = 3 * ARROW_THICKNESS; private static final float ARROW_SIZE = 3 * ARROW_THICKNESS;
private static FSkinColor friendColor, foeColor; private static FSkinColor friendColor, foeAtkColor, foeDefColor;
public enum ArcConnection {
Friends,
FoesAttacking,
FoesBlocking,
FriendsStackTargeting,
FoesStackTargeting
}
public static void updateColors() { public static void updateColors() {
final boolean darkerPWArrows = FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_TARGETING_DARKER_PW_ARROWS);
friendColor = FSkinColor.get(Colors.CLR_NORMAL_TARGETING_ARROW); friendColor = FSkinColor.get(Colors.CLR_NORMAL_TARGETING_ARROW);
if (friendColor.getAlpha() == 0) { if (friendColor.getAlpha() == 0) {
friendColor = FSkinColor.get(Colors.CLR_ACTIVE).alphaColor(153f / 255f); friendColor = FSkinColor.get(Colors.CLR_ACTIVE).alphaColor(153f / 255f);
} }
foeColor = FSkinColor.get(Colors.CLR_COMBAT_TARGETING_ARROW); foeDefColor = FSkinColor.get(Colors.CLR_COMBAT_TARGETING_ARROW);
if (foeColor.getAlpha() == 0) { if (foeDefColor.getAlpha() == 0) {
foeColor = FSkinColor.getStandardColor(new Color(1, 0, 0, 153 / 255f)); foeDefColor = FSkinColor.getStandardColor(new Color(1, 0, 0, 153 / 255f));
} }
foeAtkColor = darkerPWArrows ? foeDefColor.darker().stepColor(-60) : foeDefColor;
} }
private TargetingOverlay() { private TargetingOverlay() {
} }
public static void drawArrow(Graphics g, CardView startCard, CardView endCard) { public static void drawArrow(Graphics g, CardView startCard, CardView endCard) {
ArcConnection connects;
if (startCard.getOwner().isOpponentOf((endCard.getOwner()))) {
if (startCard.isAttacking()) {
connects = ArcConnection.FoesAttacking;
} else {
connects = ArcConnection.FoesBlocking;
}
} else {
connects = ArcConnection.Friends;
}
drawArrow(g, CardAreaPanel.get(startCard).getTargetingArrowOrigin(), drawArrow(g, CardAreaPanel.get(startCard).getTargetingArrowOrigin(),
CardAreaPanel.get(endCard).getTargetingArrowOrigin(), CardAreaPanel.get(endCard).getTargetingArrowOrigin(),
startCard.getOwner().isOpponentOf(endCard.getOwner())); connects);
} }
public static void drawArrow(Graphics g, Vector2 start, CardView targetCard, boolean connectsFoes) { public static void drawArrow(Graphics g, Vector2 start, CardView targetCard, ArcConnection connects) {
drawArrow(g, start, drawArrow(g, start,
CardAreaPanel.get(targetCard).getTargetingArrowOrigin(), CardAreaPanel.get(targetCard).getTargetingArrowOrigin(),
connectsFoes); connects);
} }
public static void drawArrow(Graphics g, Vector2 start, PlayerView targetPlayer, boolean connectsFoes) { public static void drawArrow(Graphics g, Vector2 start, PlayerView targetPlayer, ArcConnection connects) {
drawArrow(g, start, drawArrow(g, start,
MatchController.getView().getPlayerPanel(targetPlayer).getAvatar().getTargetingArrowOrigin(), MatchController.getView().getPlayerPanel(targetPlayer).getAvatar().getTargetingArrowOrigin(),
connectsFoes); connects);
} }
public static void drawArrow(Graphics g, FDisplayObject startCardDisplay, FDisplayObject endCardDisplay, boolean connectsFoes) { public static void drawArrow(Graphics g, FDisplayObject startCardDisplay, FDisplayObject endCardDisplay, ArcConnection connects) {
drawArrow(g, CardAreaPanel.getTargetingArrowOrigin(startCardDisplay, false), drawArrow(g, CardAreaPanel.getTargetingArrowOrigin(startCardDisplay, false),
CardAreaPanel.getTargetingArrowOrigin(endCardDisplay, false), CardAreaPanel.getTargetingArrowOrigin(endCardDisplay, false),
connectsFoes); connects);
} }
public static void drawArrow(Graphics g, Vector2 start, Vector2 end, boolean connectsFoes) { public static void drawArrow(Graphics g, Vector2 start, Vector2 end, ArcConnection connects) {
if (start == null || end == null) { return; } if (start == null || end == null) { return; }
FSkinColor color = connectsFoes ? foeColor : friendColor; FSkinColor color = foeDefColor;
switch (connects) {
case Friends:
case FriendsStackTargeting:
color = friendColor;
break;
case FoesAttacking:
color = foeAtkColor;
break;
case FoesBlocking:
case FoesStackTargeting:
color = foeDefColor;
}
g.drawArrow(BORDER_THICKNESS, ARROW_THICKNESS, ARROW_SIZE, color, start.x, start.y, end.x, end.y); g.drawArrow(BORDER_THICKNESS, ARROW_THICKNESS, ARROW_SIZE, color, start.x, start.y, end.x, end.y);
} }
} }

View File

@@ -213,10 +213,12 @@ public class VStack extends FDropDown {
StackItemView instance = activeStackInstance; StackItemView instance = activeStackInstance;
while (instance != null) { while (instance != null) {
for (CardView c : instance.getTargetCards()) { for (CardView c : instance.getTargetCards()) {
TargetingOverlay.drawArrow(g, arrowOrigin, c, activator.isOpponentOf(c.getController())); TargetingOverlay.ArcConnection conn = activator.isOpponentOf(c.getController()) ? TargetingOverlay.ArcConnection.FoesStackTargeting : TargetingOverlay.ArcConnection.FriendsStackTargeting;
TargetingOverlay.drawArrow(g, arrowOrigin, c, conn);
} }
for (PlayerView p : instance.getTargetPlayers()) { for (PlayerView p : instance.getTargetPlayers()) {
TargetingOverlay.drawArrow(g, arrowOrigin, p, activator.isOpponentOf(p)); TargetingOverlay.ArcConnection conn = activator.isOpponentOf(p) ? TargetingOverlay.ArcConnection.FoesStackTargeting : TargetingOverlay.ArcConnection.FriendsStackTargeting;
TargetingOverlay.drawArrow(g, arrowOrigin, p, conn);
} }
instance = instance.getSubInstance(); instance = instance.getSubInstance();
} }

View File

@@ -139,6 +139,10 @@ public class SettingsPage extends TabPage<SettingsScreen> {
"Use Escape Key To End Turn", "Use Escape Key To End Turn",
"Allows to use Esc keyboard shortcut to end turn prematurely"), "Allows to use Esc keyboard shortcut to end turn prematurely"),
1); 1);
lstSettings.addItem(new BooleanSetting(FPref.UI_TARGETING_DARKER_PW_ARROWS,
"Darker Arrows for Planeswalker Attackers",
"Makes targeting arrows darker for creatures attacking planeswalkers."),
1);
//Random Deck Generation //Random Deck Generation
lstSettings.addItem(new BooleanSetting(FPref.DECKGEN_NOSMALL, lstSettings.addItem(new BooleanSetting(FPref.DECKGEN_NOSMALL,

View File

@@ -72,6 +72,7 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
UI_PREFERRED_AVATARS_ONLY ("false"), UI_PREFERRED_AVATARS_ONLY ("false"),
UI_TARGETING_OVERLAY ("0"), UI_TARGETING_OVERLAY ("0"),
UI_TIMED_TARGETING_OVERLAY_UPDATES ("true"), UI_TIMED_TARGETING_OVERLAY_UPDATES ("true"),
UI_TARGETING_DARKER_PW_ARROWS ("true"),
UI_ENABLE_SOUNDS ("true"), UI_ENABLE_SOUNDS ("true"),
UI_ENABLE_MUSIC ("true"), UI_ENABLE_MUSIC ("true"),
UI_ALT_SOUND_SYSTEM ("false"), UI_ALT_SOUND_SYSTEM ("false"),