diff --git a/forge-game/src/main/java/forge/game/card/CardView.java b/forge-game/src/main/java/forge/game/card/CardView.java index 9dd21fd33ca..6855e97581a 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -854,6 +854,16 @@ public class CardView extends GameEntityView { public void updateNeedsTransformAnimation(boolean value) { set(TrackableProperty.NeedsTransformAnimation, value); } + public Float getTargetingOriginVectorX() { + return get(TrackableProperty.TargetingOriginVectorX); + } + public Float getTargetingOriginVectorY() { + return get(TrackableProperty.TargetingOriginVectorY); + } + public void setTargetingOriginVector(float x, float y) { + set(TrackableProperty.TargetingOriginVectorX, x); + set(TrackableProperty.TargetingOriginVectorY, y); + } void updateState(Card c) { updateName(c); updateZoneText(c); diff --git a/forge-game/src/main/java/forge/trackable/TrackableProperty.java b/forge-game/src/main/java/forge/trackable/TrackableProperty.java index 0e1b823b698..ac0a6457dd3 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableProperty.java +++ b/forge-game/src/main/java/forge/trackable/TrackableProperty.java @@ -83,6 +83,8 @@ public enum TrackableProperty { NeedsTransformAnimation(TrackableTypes.BooleanType, FreezeMode.IgnoresFreeze), NeedsUntapAnimation(TrackableTypes.BooleanType, FreezeMode.IgnoresFreeze), NeedsTapAnimation(TrackableTypes.BooleanType, FreezeMode.IgnoresFreeze), + TargetingOriginVectorX(TrackableTypes.FloatType, FreezeMode.IgnoresFreeze), + TargetingOriginVectorY(TrackableTypes.FloatType, FreezeMode.IgnoresFreeze), ImprintedCards(TrackableTypes.CardViewCollectionType), HauntedBy(TrackableTypes.CardViewCollectionType), diff --git a/forge-game/src/main/java/forge/trackable/TrackableTypes.java b/forge-game/src/main/java/forge/trackable/TrackableTypes.java index 00e0349acc5..c2d3c19b07d 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableTypes.java +++ b/forge-game/src/main/java/forge/trackable/TrackableTypes.java @@ -162,6 +162,22 @@ public class TrackableTypes { ts.write(value); } }; + public static final TrackableType FloatType = new TrackableType() { + @Override + public Float getDefaultValue() { + return 0f; + } + + @Override + public Float deserialize(TrackableDeserializer td, Float oldValue) { + return td.readFloat(); + } + + @Override + public void serialize(TrackableSerializer ts, Float value) { + ts.write(value); + } + }; public static final TrackableType StringType = new TrackableType() { @Override public String getDefaultValue() { diff --git a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java index 45197857506..83d7220a749 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java @@ -3,6 +3,7 @@ package forge.screens.match; import java.util.*; import java.util.Map.Entry; +import com.badlogic.gdx.math.Vector2; import forge.animation.ForgeAnimation; import forge.assets.FImage; import forge.game.spellability.StackItemView; @@ -405,14 +406,13 @@ public class MatchScreen extends FScreen { } //draw arrows for paired cards - Set pairedCards = new HashSet<>(); for (VPlayerPanel playerPanel : playerPanels.values()) { for (CardView card : playerPanel.getField().getRow1().getOrderedCards()) { - if (pairedCards.contains(card)) { continue; } //prevent arrows going both ways - if (card != null) { if (card.getPairedWith() != null) { - TargetingOverlay.drawArrow(g, card, card.getPairedWith()); + final Vector2 vCard = new Vector2(card.getTargetingOriginVectorX(), card.getTargetingOriginVectorY()); + final Vector2 vPairedWith = new Vector2(card.getPairedWith().getTargetingOriginVectorX(), card.getPairedWith().getTargetingOriginVectorY()); + TargetingOverlay.drawArrow(g, vCard, vPairedWith, TargetingOverlay.ArcConnection.Friends); } } } @@ -425,28 +425,36 @@ public class MatchScreen extends FScreen { //connect each attacker with planeswalker it's attacking if applicable final GameEntityView defender = combat.getDefender(attacker); if (defender instanceof CardView) { - TargetingOverlay.drawArrow(g, attacker, (CardView) defender); + final Vector2 vDefender = new Vector2(((CardView) defender).getTargetingOriginVectorX(), ((CardView) defender).getTargetingOriginVectorY()); + final Vector2 vAttacker = new Vector2(attacker.getTargetingOriginVectorX(), attacker.getTargetingOriginVectorY()); + TargetingOverlay.drawArrow(g, vAttacker, vDefender, TargetingOverlay.ArcConnection.FoesAttacking); } final Iterable blockers = combat.getBlockers(attacker); if (blockers != null) { //connect each blocker with the attacker it's blocking for (final CardView blocker : blockers) { - TargetingOverlay.drawArrow(g, blocker, attacker); + final Vector2 vBlocker = new Vector2(blocker.getTargetingOriginVectorX(), blocker.getTargetingOriginVectorY()); + final Vector2 vAttacker = new Vector2(attacker.getTargetingOriginVectorX(), attacker.getTargetingOriginVectorY()); + TargetingOverlay.drawArrow(g, vBlocker, vAttacker, TargetingOverlay.ArcConnection.FoesBlocking); } } final Iterable plannedBlockers = combat.getPlannedBlockers(attacker); if (plannedBlockers != null) { //connect each planned blocker with the attacker it's blocking for (final CardView blocker : plannedBlockers) { - TargetingOverlay.drawArrow(g, blocker, attacker); + final Vector2 vBlocker = new Vector2(blocker.getTargetingOriginVectorX(), blocker.getTargetingOriginVectorY()); + final Vector2 vAttacker = new Vector2(attacker.getTargetingOriginVectorX(), attacker.getTargetingOriginVectorY()); + TargetingOverlay.drawArrow(g, vBlocker, vAttacker, TargetingOverlay.ArcConnection.FoesBlocking); } } //player if (is4Player() || is3Player()) { - int numplayers = is3Player() ? 3 : 4; for (final PlayerView p : game.getPlayers()) { - if (combat.getAttackersOf(p).contains(attacker)) - TargetingOverlay.drawArrow(g, attacker, p, numplayers); + if (combat.getAttackersOf(p).contains(attacker)) { + final Vector2 vAttacker = new Vector2(attacker.getTargetingOriginVectorX(), attacker.getTargetingOriginVectorY()); + final Vector2 vPlayer = MatchController.getView().getPlayerPanel(p).getAvatar().getTargetingArrowOrigin(); + TargetingOverlay.drawArrow(g, vAttacker, vPlayer, TargetingOverlay.ArcConnection.FoesAttacking); + } } } } diff --git a/forge-gui-mobile/src/forge/screens/match/TargetingOverlay.java b/forge-gui-mobile/src/forge/screens/match/TargetingOverlay.java index 4b7ef65b30b..1092385e5cc 100644 --- a/forge-gui-mobile/src/forge/screens/match/TargetingOverlay.java +++ b/forge-gui-mobile/src/forge/screens/match/TargetingOverlay.java @@ -63,42 +63,6 @@ public class TargetingOverlay { private TargetingOverlay() { } - 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(), - CardAreaPanel.get(endCard).getTargetingArrowOrigin(), - connects); - } - public static void drawArrow(Graphics g, CardView startCard, PlayerView targetPlayer, int numplayers) { - drawArrow(g, CardAreaPanel.get(startCard).getTargetingArrowOrigin(), - MatchController.getView().getPlayerPanel(targetPlayer).getAvatar().getTargetingArrowOrigin(numplayers), - ArcConnection.FoesAttacking); - } - public static void drawArrow(Graphics g, Vector2 start, CardView targetCard, ArcConnection connects) { - drawArrow(g, start, - CardAreaPanel.get(targetCard).getTargetingArrowOrigin(), - connects); - } - public static void drawArrow(Graphics g, Vector2 start, PlayerView targetPlayer, ArcConnection connects) { - drawArrow(g, start, - MatchController.getView().getPlayerPanel(targetPlayer).getAvatar().getTargetingArrowOrigin(), - connects); - } - public static void drawArrow(Graphics g, FDisplayObject startCardDisplay, FDisplayObject endCardDisplay, ArcConnection connects) { - drawArrow(g, CardAreaPanel.getTargetingArrowOrigin(startCardDisplay, false), - CardAreaPanel.getTargetingArrowOrigin(endCardDisplay, false), - connects); - } public static void drawArrow(Graphics g, Vector2 start, Vector2 end, ArcConnection connects) { if (start == null || end == null) { return; } diff --git a/forge-gui-mobile/src/forge/screens/match/views/VAvatar.java b/forge-gui-mobile/src/forge/screens/match/views/VAvatar.java index b8ab4262e57..564fb19b36b 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VAvatar.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VAvatar.java @@ -106,21 +106,9 @@ public class VAvatar extends FDisplayObject { } public Vector2 getTargetingArrowOrigin() { - return getTargetingArrowOrigin(2); - } - public Vector2 getTargetingArrowOrigin(int numplayers) { - Vector2 origin = new Vector2(screenPos.x, screenPos.y); - - float modx = numplayers > 2 ? 0.25f : 0.75f; - - origin.x += WIDTH * modx; - if (origin.y < MatchController.getView().getHeight() / numplayers) { - origin.y += HEIGHT * 0.75f; //target bottom right corner if on top half of screen - } - else { - origin.y += HEIGHT * 0.25f; //target top right corner if on bottom half of screen - } - + Vector2 origin = new Vector2(this.screenPos.x, this.screenPos.y); + origin.x += getWidth()/2f; + origin.y += getWidth()/2f; return origin; } diff --git a/forge-gui-mobile/src/forge/screens/match/views/VStack.java b/forge-gui-mobile/src/forge/screens/match/views/VStack.java index c06f2aad178..a011fae1505 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VStack.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VStack.java @@ -229,11 +229,11 @@ public class VStack extends FDropDown { while (instance != null) { for (CardView c : instance.getTargetCards()) { TargetingOverlay.ArcConnection conn = activator.isOpponentOf(c.getController()) ? TargetingOverlay.ArcConnection.FoesStackTargeting : TargetingOverlay.ArcConnection.FriendsStackTargeting; - TargetingOverlay.drawArrow(g, arrowOrigin, c, conn); + TargetingOverlay.drawArrow(g, arrowOrigin, new Vector2(c.getTargetingOriginVectorX(), c.getTargetingOriginVectorY()), conn); } for (PlayerView p : instance.getTargetPlayers()) { TargetingOverlay.ArcConnection conn = activator.isOpponentOf(p) ? TargetingOverlay.ArcConnection.FoesStackTargeting : TargetingOverlay.ArcConnection.FriendsStackTargeting; - TargetingOverlay.drawArrow(g, arrowOrigin, p, conn); + TargetingOverlay.drawArrow(g, arrowOrigin, MatchController.getView().getPlayerPanel(p).getAvatar().getTargetingArrowOrigin(), conn); } instance = instance.getSubInstance(); } diff --git a/forge-gui-mobile/src/forge/toolbox/FCardPanel.java b/forge-gui-mobile/src/forge/toolbox/FCardPanel.java index 195990253d5..dd000a2dde0 100644 --- a/forge-gui-mobile/src/forge/toolbox/FCardPanel.java +++ b/forge-gui-mobile/src/forge/toolbox/FCardPanel.java @@ -101,12 +101,16 @@ public class FCardPanel extends FDisplayObject { float x = padding-mod/2; float y = padding-mod/2; float w = (getWidth() - 2 * padding)+mod; + float xoffset = w / 2f; float h = (getHeight() - 2 * padding)+mod; + float yoffset = h / 2f; if (w == h) { //adjust width if needed to make room for tapping w = h / ASPECT_RATIO; } float edgeOffset = w / 2f; + card.setTargetingOriginVector(tapped? this.screenPos.x + yoffset : this.screenPos.x + edgeOffset, tapped ? this.screenPos.y + h - yoffset/1.5f : this.screenPos.y + h - xoffset); + if (!ZoneType.Battlefield.equals(card.getZone())) { rotateTransform(g, x, y, w, h, edgeOffset, false); return;