Files
forge/forge-gui-mobile/src/forge/card/CardZoom.java
Grimm f6bec79a28 changed road algo
added WaveFunctionCollapse to create biome structures
changed world generation.
added overworld collision for enemies.
2022-08-06 21:10:18 +02:00

384 lines
15 KiB
Java

package forge.card;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.utils.Align;
import forge.Forge;
import forge.Graphics;
import forge.assets.FSkinImage;
import forge.deck.ArchetypeDeckGenerator;
import forge.deck.CardThemedDeckGenerator;
import forge.deck.CommanderDeckGenerator;
import forge.deck.DeckProxy;
import forge.game.GameView;
import forge.game.card.CardView;
import forge.gamemodes.planarconquest.ConquestCommander;
import forge.item.IPaperCard;
import forge.item.InventoryItem;
import forge.localinstance.properties.ForgePreferences;
import forge.localinstance.properties.ForgePreferences.FPref;
import forge.model.FModel;
import forge.screens.match.MatchController;
import forge.toolbox.FCardPanel;
import forge.toolbox.FDialog;
import forge.toolbox.FOverlay;
import forge.util.Utils;
import forge.util.collect.FCollectionView;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
public class CardZoom extends FOverlay {
private static final float REQ_AMOUNT = Utils.AVG_FINGER_WIDTH;
private static final CardZoom cardZoom = new CardZoom();
private static final ForgePreferences prefs = FModel.getPreferences();
private static List<?> items;
private static int currentIndex, initialIndex;
private static CardView currentCard, prevCard, nextCard;
private static boolean zoomMode = true;
private static boolean oneCardView = prefs.getPrefBoolean(FPref.UI_SINGLE_CARD_ZOOM);
private float totalZoomAmount;
private static ActivateHandler activateHandler;
private static String currentActivateAction;
private static Rectangle flipIconBounds;
private static Rectangle mutateIconBounds;
private static boolean showAltState;
private static boolean showBackSide = false;
private static boolean showMerged = false;
public static void show(Object item) {
show(item, false);
}
public static void show(Object item, boolean showbackside) {
List<Object> items0 = new ArrayList<>();
items0.add(item);
showBackSide = showbackside; //reverse the displayed zoomed card for the choice list
show(items0, 0, null);
}
public static void show(FCollectionView<?> items0, int currentIndex0, ActivateHandler activateHandler0) {
show((List<?>)items0, currentIndex0, activateHandler0);
}
public static void show(final List<?> items0, int currentIndex0, ActivateHandler activateHandler0) {
items = items0;
activateHandler = activateHandler0;
currentIndex = currentIndex0;
initialIndex = currentIndex0;
currentCard = getCardView(items.get(currentIndex));
prevCard = currentIndex > 0 ? getCardView(items.get(currentIndex - 1)) : null;
nextCard = currentIndex < items.size() - 1 ? getCardView(items.get(currentIndex + 1)) : null;
onCardChanged();
cardZoom.show();
}
public static boolean isOpen() {
return cardZoom.isVisible();
}
public static void hideZoom() {
cardZoom.hide();
}
private CardZoom() {
}
@Override
public void setVisible(boolean visible0) {
if (this.isVisible() == visible0) { return; }
super.setVisible(visible0);
//update selected index when hidden if current index is different than initial index
if (!visible0 && activateHandler != null && currentIndex != initialIndex) {
activateHandler.setSelectedIndex(currentIndex);
}
}
private static void incrementCard(int dir) {
if (dir > 0) {
if (currentIndex == items.size() - 1) { return; }
currentIndex++;
prevCard = currentCard;
currentCard = nextCard;
nextCard = currentIndex < items.size() - 1 ? getCardView(items.get(currentIndex + 1)) : null;
}
else {
if (currentIndex == 0) { return; }
currentIndex--;
nextCard = currentCard;
currentCard = prevCard;
prevCard = currentIndex > 0 ? getCardView(items.get(currentIndex - 1)) : null;
}
onCardChanged();
}
private static void onCardChanged() {
mutateIconBounds = null;
if (activateHandler != null) {
currentActivateAction = activateHandler.getActivateAction(currentIndex);
}
if (MatchController.instance.mayFlip(currentCard)) {
flipIconBounds = new Rectangle();
} else {
flipIconBounds = null;
}
if (currentCard != null) {
if (currentCard.getMergedCardsCollection() != null )
if (currentCard.getMergedCardsCollection().size() > 0)
mutateIconBounds = new Rectangle();
}
showAltState = false;
}
private static CardView getCardView(Object item) {
if (item instanceof Entry) {
item = ((Entry<?, ?>)item).getKey();
}
if (item instanceof CardView) {
return (CardView)item;
}
if (item instanceof DeckProxy) {
if (item instanceof CardThemedDeckGenerator){
return CardView.getCardForUi(((CardThemedDeckGenerator)item).getPaperCard());
}else if (item instanceof CommanderDeckGenerator){
return CardView.getCardForUi(((CommanderDeckGenerator)item).getPaperCard());
}else if (item instanceof ArchetypeDeckGenerator){
return CardView.getCardForUi(((ArchetypeDeckGenerator)item).getPaperCard());
}else{
DeckProxy deck = ((DeckProxy)item);
return new CardView(-1, null, deck.getName(), null, deck.getImageKey(false));
}
}
if (item instanceof IPaperCard) {
return CardView.getCardForUi((IPaperCard)item);
}
if (item instanceof ConquestCommander) {
return CardView.getCardForUi(((ConquestCommander)item).getCard());
}
if (item instanceof InventoryItem) {
InventoryItem ii = (InventoryItem)item;
return new CardView(-1, null, ii.getName(), null, ii.getImageKey(false));
}
return new CardView(-1, null, item.toString());
}
@Override
public boolean tap(float x, float y, int count) {
if (mutateIconBounds != null && mutateIconBounds.contains(x, y)) {
if(showMerged) {
showMerged = false;
} else {
showMerged = true;
show(currentCard.getMergedCardsCollection(), 0, null);
}
return true;
}
if (flipIconBounds != null && flipIconBounds.contains(x, y)) {
if (currentCard.isFaceDown() && currentCard.getBackup() != null) {
if (currentCard.getBackup().hasBackSide() || currentCard.getBackup().isFlipCard() || currentCard.getBackup().isAdventureCard()) {
show(currentCard.getBackup());
return true;
}
}
if (!showBackSide)
showAltState = !showAltState;
else
showBackSide = !showBackSide;
return true;
}
hide();
showBackSide = false;
showAltState = false;
showMerged = false;
return true;
}
@Override
public boolean fling(float velocityX, float velocityY) {
if (Math.abs(velocityX) > Math.abs(velocityY)) {
incrementCard(velocityX > 0 ? -1 : 1);
showBackSide = false;
showAltState = false;
return true;
}
if (velocityY > 0) {
zoomMode = !zoomMode;
showBackSide = false;
showAltState = false;
return true;
}
if (currentActivateAction != null && activateHandler != null) {
hide();
showBackSide = false;
showAltState = false;
activateHandler.activate(currentIndex);
return true;
}
return false;
}
private void setOneCardView(boolean oneCardView0) {
if (oneCardView == oneCardView0 || Forge.isLandscapeMode()) { return; } //don't allow changing this when in landscape mode
oneCardView = oneCardView0;
prefs.setPref(FPref.UI_SINGLE_CARD_ZOOM, oneCardView0);
prefs.save();
}
@Override
public boolean zoom(float x, float y, float amount) {
totalZoomAmount += amount;
if (totalZoomAmount >= REQ_AMOUNT) {
setOneCardView(true);
totalZoomAmount = 0;
}
else if (totalZoomAmount <= -REQ_AMOUNT) {
setOneCardView(false);
totalZoomAmount = 0;
}
return true;
}
@Override
public boolean longPress(float x, float y) {
setOneCardView(!oneCardView);
return true;
}
@Override
public void drawOverlay(Graphics g) {
final GameView gameView = MatchController.instance.getGameView();
float w = getWidth();
float h = getHeight();
float messageHeight = FDialog.MSG_HEIGHT;
float AspectRatioMultiplier;
switch (Forge.extrawide) {
case "default":
AspectRatioMultiplier = 3; //good for tablets with 16:10 or similar
break;
case "wide":
AspectRatioMultiplier = 2.5f;
break;
case "extrawide":
AspectRatioMultiplier = 2; //good for tall phones with 21:9 or similar
break;
default:
AspectRatioMultiplier = 3;
break;
}
float maxCardHeight = h - AspectRatioMultiplier * messageHeight; //maxheight of currently zoomed card
float cardWidth, cardHeight, y;
if (oneCardView && !Forge.isLandscapeMode()) {
cardWidth = w;
cardHeight = FCardPanel.ASPECT_RATIO * cardWidth;
boolean rotateSplit = FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ROTATE_SPLIT_CARDS);
if (currentCard != null && currentCard.isSplitCard() && rotateSplit) {
// card will be rotated. Make sure that the height does not exceed the width of the view
if (cardHeight > Gdx.graphics.getWidth())
{
cardHeight = Gdx.graphics.getWidth();
cardWidth = cardHeight / FCardPanel.ASPECT_RATIO;
}
}
}
else {
cardWidth = w * 0.5f;
cardHeight = FCardPanel.ASPECT_RATIO * cardWidth;
float maxSideCardHeight = maxCardHeight * 5 / 7;
if (cardHeight > maxSideCardHeight) { //prevent card overlapping message bars
cardHeight = maxSideCardHeight;
cardWidth = cardHeight / FCardPanel.ASPECT_RATIO;
}
y = (h - cardHeight) / 2;
if (prevCard != null) {
CardImageRenderer.drawZoom(g, prevCard, gameView, false, 0, y, cardWidth, cardHeight, getWidth(), getHeight(), false);
}
if (nextCard != null) {
CardImageRenderer.drawZoom(g, nextCard, gameView, false, w - cardWidth, y, cardWidth, cardHeight, getWidth(), getHeight(), false);
}
cardWidth = w * 0.7f;
cardHeight = FCardPanel.ASPECT_RATIO * cardWidth;
}
if (cardHeight > maxCardHeight) { //prevent card overlapping message bars
cardHeight = maxCardHeight;
cardWidth = cardHeight / FCardPanel.ASPECT_RATIO;
}
float x = (w - cardWidth) / 2;
y = (h - cardHeight) / 2;
if (zoomMode) {
CardImageRenderer.drawZoom(g, currentCard, gameView, showBackSide? showBackSide : showAltState, x, y, cardWidth, cardHeight, getWidth(), getHeight(), true);
} else {
CardImageRenderer.drawDetails(g, currentCard, gameView, showBackSide? showBackSide : showAltState, x, y, cardWidth, cardHeight);
}
if (!showMerged) {
if (mutateIconBounds != null) {
float oldAlpha = g.getfloatAlphaComposite();
try {
g.setAlphaComposite(0.6f);
drawIconBounds(g, mutateIconBounds, Forge.hdbuttons ? FSkinImage.HDLIBRARY : FSkinImage.LIBRARY, x, y, cardWidth, cardHeight);
g.setAlphaComposite(oldAlpha);
} catch (Exception e) {
mutateIconBounds = null;
g.setAlphaComposite(oldAlpha);
}
} else if (flipIconBounds != null) {
drawIconBounds(g, flipIconBounds, Forge.hdbuttons ? FSkinImage.HDFLIPCARD : FSkinImage.FLIPCARD, x, y, cardWidth, cardHeight);
}
} else if (flipIconBounds != null) {
drawIconBounds(g, flipIconBounds, Forge.hdbuttons ? FSkinImage.HDFLIPCARD : FSkinImage.FLIPCARD, x, y, cardWidth, cardHeight);
}
if (currentActivateAction != null) {
g.fillRect(FDialog.MSG_BACK_COLOR, 0, 0, w, messageHeight);
g.drawText(Forge.getLocalizer().getMessage("lblSwipeUpTo").replace("%s", currentActivateAction), FDialog.MSG_FONT, FDialog.MSG_FORE_COLOR, 0, 0, w, messageHeight, false, Align.center, true);
}
g.fillRect(FDialog.MSG_BACK_COLOR, 0, h - messageHeight, w, messageHeight);
g.drawText(zoomMode ? Forge.getLocalizer().getMessage("lblSwipeDownDetailView") : Forge.getLocalizer().getMessage("lblSwipeDownPictureView"), FDialog.MSG_FONT, FDialog.MSG_FORE_COLOR, 0, h - messageHeight, w, messageHeight, false, Align.center, true);
interrupt(false);
}
private void drawIconBounds(Graphics g, Rectangle iconBounds, FSkinImage skinImage, float x, float y, float cardWidth, float cardHeight) {
float imageWidth = cardWidth / 2;
float imageHeight = imageWidth * skinImage.getHeight() / skinImage.getWidth();
iconBounds.set(x + (cardWidth - imageWidth) / 2, y + (cardHeight - imageHeight) / 2, imageWidth, imageHeight);
g.drawImage(skinImage, iconBounds.x, iconBounds.y, iconBounds.width, iconBounds.height);
}
@Override
protected void doLayout(float width, float height) {
}
public interface ActivateHandler {
String getActivateAction(int index);
void setSelectedIndex(int index);
void activate(int index);
}
public void interrupt(boolean resume) {
if (MatchController.instance.hasLocalPlayers())
return;
if(resume && MatchController.instance.isGamePaused()) {
MatchController.instance.resumeMatch();
return;
}
if(!MatchController.instance.isGamePaused())
MatchController.instance.pauseMatch();
}
}