mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
Start refactoring Planar Conquest to support new mobile friendly format
This commit is contained in:
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -1331,8 +1331,8 @@ forge-gui-mobile/src/forge/screens/match/winlose/GauntletWinLose.java -text
|
|||||||
forge-gui-mobile/src/forge/screens/match/winlose/LimitedWinLose.java -text
|
forge-gui-mobile/src/forge/screens/match/winlose/LimitedWinLose.java -text
|
||||||
forge-gui-mobile/src/forge/screens/match/winlose/QuestWinLose.java -text
|
forge-gui-mobile/src/forge/screens/match/winlose/QuestWinLose.java -text
|
||||||
forge-gui-mobile/src/forge/screens/match/winlose/ViewWinLose.java -text
|
forge-gui-mobile/src/forge/screens/match/winlose/ViewWinLose.java -text
|
||||||
forge-gui-mobile/src/forge/screens/planarconquest/CommandCenterScreen.java -text
|
|
||||||
forge-gui-mobile/src/forge/screens/planarconquest/ConquestDeckEditor.java -text
|
forge-gui-mobile/src/forge/screens/planarconquest/ConquestDeckEditor.java -text
|
||||||
|
forge-gui-mobile/src/forge/screens/planarconquest/ConquestMapScreen.java -text
|
||||||
forge-gui-mobile/src/forge/screens/planarconquest/ConquestMenu.java -text
|
forge-gui-mobile/src/forge/screens/planarconquest/ConquestMenu.java -text
|
||||||
forge-gui-mobile/src/forge/screens/planarconquest/ConquestPrefsScreen.java -text
|
forge-gui-mobile/src/forge/screens/planarconquest/ConquestPrefsScreen.java -text
|
||||||
forge-gui-mobile/src/forge/screens/planarconquest/LoadConquestScreen.java -text
|
forge-gui-mobile/src/forge/screens/planarconquest/LoadConquestScreen.java -text
|
||||||
@@ -17482,7 +17482,6 @@ forge-gui/src/main/java/forge/planarconquest/ConquestDataIO.java -text
|
|||||||
forge-gui/src/main/java/forge/planarconquest/ConquestDeckMap.java -text
|
forge-gui/src/main/java/forge/planarconquest/ConquestDeckMap.java -text
|
||||||
forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java -text
|
forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java -text
|
||||||
forge-gui/src/main/java/forge/planarconquest/ConquestPlaneData.java -text
|
forge-gui/src/main/java/forge/planarconquest/ConquestPlaneData.java -text
|
||||||
forge-gui/src/main/java/forge/planarconquest/ConquestPlaneMap.java -text
|
|
||||||
forge-gui/src/main/java/forge/planarconquest/ConquestPreferences.java -text
|
forge-gui/src/main/java/forge/planarconquest/ConquestPreferences.java -text
|
||||||
forge-gui/src/main/java/forge/planarconquest/ConquestUtil.java -text
|
forge-gui/src/main/java/forge/planarconquest/ConquestUtil.java -text
|
||||||
forge-gui/src/main/java/forge/planarconquest/IVCommandCenter.java -text
|
forge-gui/src/main/java/forge/planarconquest/IVCommandCenter.java -text
|
||||||
|
|||||||
@@ -1,704 +0,0 @@
|
|||||||
package forge.screens.planarconquest;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
|
||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
|
|
||||||
|
|
||||||
import forge.FThreads;
|
|
||||||
import forge.Forge;
|
|
||||||
import forge.Graphics;
|
|
||||||
import forge.achievement.PlaneswalkerAchievements;
|
|
||||||
import forge.assets.FImage;
|
|
||||||
import forge.assets.FSkin;
|
|
||||||
import forge.assets.FSkinFont;
|
|
||||||
import forge.assets.FSkinImage;
|
|
||||||
import forge.assets.TextRenderer;
|
|
||||||
import forge.card.CardRarity;
|
|
||||||
import forge.card.CardRenderer;
|
|
||||||
import forge.card.CardZoom;
|
|
||||||
import forge.card.CardRenderer.CardStackPosition;
|
|
||||||
import forge.card.CardZoom.ActivateHandler;
|
|
||||||
import forge.deck.FDeckViewer;
|
|
||||||
import forge.game.card.Card;
|
|
||||||
import forge.game.card.CardView;
|
|
||||||
import forge.model.FModel;
|
|
||||||
import forge.planarconquest.ConquestAction;
|
|
||||||
import forge.planarconquest.ConquestCommander;
|
|
||||||
import forge.planarconquest.ConquestData;
|
|
||||||
import forge.planarconquest.ConquestController.GameRunner;
|
|
||||||
import forge.planarconquest.ConquestPlane;
|
|
||||||
import forge.planarconquest.ConquestPlane.Region;
|
|
||||||
import forge.planarconquest.ConquestPlaneData;
|
|
||||||
import forge.planarconquest.ConquestPlaneData.RegionData;
|
|
||||||
import forge.planarconquest.ConquestPlaneMap;
|
|
||||||
import forge.planarconquest.ConquestPlaneMap.HexagonTile;
|
|
||||||
import forge.planarconquest.ConquestPlaneMap.IPlaneMapRenderer;
|
|
||||||
import forge.planarconquest.ConquestPreferences.CQPref;
|
|
||||||
import forge.planarconquest.IVCommandCenter;
|
|
||||||
import forge.screens.FScreen;
|
|
||||||
import forge.screens.LoadingOverlay;
|
|
||||||
import forge.screens.match.TargetingOverlay;
|
|
||||||
import forge.toolbox.FCardPanel;
|
|
||||||
import forge.toolbox.FContainer;
|
|
||||||
import forge.toolbox.FDisplayObject;
|
|
||||||
import forge.toolbox.FEvent;
|
|
||||||
import forge.toolbox.FScrollPane;
|
|
||||||
import forge.toolbox.FEvent.FEventHandler;
|
|
||||||
import forge.toolbox.FLabel;
|
|
||||||
import forge.util.Utils;
|
|
||||||
|
|
||||||
public class CommandCenterScreen extends FScreen implements IVCommandCenter {
|
|
||||||
private static final float BORDER_THICKNESS = Utils.scale(1);
|
|
||||||
private static final FSkinFont REGION_STATS_FONT = FSkinFont.get(12);
|
|
||||||
private static final FSkinFont REGION_NAME_FONT = FSkinFont.get(15);
|
|
||||||
private static final FSkinFont PLANE_NAME_FONT = FSkinFont.get(16);
|
|
||||||
private static final FSkinFont UNLOCK_WINS_FONT = FSkinFont.get(18);
|
|
||||||
private static final float COMMANDER_ROW_PADDING = Utils.scale(16);
|
|
||||||
private static final float COMMANDER_GAP = Utils.scale(12);
|
|
||||||
private static final float REGION_FRAME_THICKNESS_MULTIPLIER = 15f / 443f;
|
|
||||||
private static final float REGION_FRAME_BASE_HEIGHT_MULTIPLIER = 25f / 317f;
|
|
||||||
|
|
||||||
private final PlaneMap map = add(new PlaneMap());
|
|
||||||
private final RegionDisplay regionDisplay = add(new RegionDisplay());
|
|
||||||
private final CommanderRow commanderRow = add(new CommanderRow());
|
|
||||||
private final FLabel btnEndDay = add(new FLabel.ButtonBuilder().font(FSkinFont.get(14)).build());
|
|
||||||
|
|
||||||
private ConquestData model;
|
|
||||||
private String unlockRatio, winRatio;
|
|
||||||
|
|
||||||
public CommandCenterScreen() {
|
|
||||||
super("", ConquestMenu.getMenu());
|
|
||||||
|
|
||||||
btnEndDay.setCommand(new FEventHandler() {
|
|
||||||
@Override
|
|
||||||
public void handleEvent(FEvent e) {
|
|
||||||
FModel.getConquest().endDay(CommandCenterScreen.this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void onActivate() {
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update() {
|
|
||||||
model = FModel.getConquest().getModel();
|
|
||||||
setHeaderCaption(model.getName());
|
|
||||||
map.revalidate();
|
|
||||||
updateCurrentDay();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateCurrentDay() {
|
|
||||||
ConquestPlane plane = model.getCurrentPlane();
|
|
||||||
ConquestPlaneData planeData = model.getCurrentPlaneData();
|
|
||||||
|
|
||||||
btnEndDay.setText("End Day " + model.getDay());
|
|
||||||
|
|
||||||
//update unlock and win ratios for plane
|
|
||||||
unlockRatio = planeData.getUnlockedCount() + "/" + plane.getCardPool().size();
|
|
||||||
winRatio = planeData.getWins() + "-" + planeData.getLosses();
|
|
||||||
|
|
||||||
commanderRow.selectedIndex = 0; //select first commander at the beginning of each day
|
|
||||||
ConquestCommander commander = commanderRow.panels[0].commander;
|
|
||||||
if (commander != null && commander.getDeployedRegion() != null) {
|
|
||||||
model.setCurrentRegion(commander.getDeployedRegion());
|
|
||||||
}
|
|
||||||
regionDisplay.onRegionChanged(); //simulate region change when day changes to ensure everything is updated, even if region didn't changed
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConquestCommander getSelectedCommander() {
|
|
||||||
return model.getCurrentPlaneData().getCommanders().get(commanderRow.selectedIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setSelectedCommander(ConquestCommander commander) {
|
|
||||||
int newIndex = model.getCurrentPlaneData().getCommanders().indexOf(commander);
|
|
||||||
boolean changed = commanderRow.selectedIndex != newIndex;
|
|
||||||
commanderRow.selectedIndex = newIndex;
|
|
||||||
if (commander.getDeployedRegion() != null) {
|
|
||||||
if (model.setCurrentRegion(commander.getDeployedRegion())) {
|
|
||||||
regionDisplay.onRegionChanged();
|
|
||||||
changed = true; //if region changed, always return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startGame(final GameRunner gameRunner) {
|
|
||||||
LoadingOverlay.show("Loading new game...", new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
gameRunner.finishStartingGame();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void drawOverlay(Graphics g) {
|
|
||||||
ConquestCommander commander = regionDisplay.deployedCommander.commander;
|
|
||||||
if (commander == null || commander.getCurrentDayAction() == null) { return; }
|
|
||||||
|
|
||||||
int idx;
|
|
||||||
switch (commander.getCurrentDayAction()) {
|
|
||||||
case Attack1:
|
|
||||||
TargetingOverlay.drawArrow(g, regionDisplay.deployedCommander, regionDisplay.opponents[0], true);
|
|
||||||
break;
|
|
||||||
case Attack2:
|
|
||||||
TargetingOverlay.drawArrow(g, regionDisplay.deployedCommander, regionDisplay.opponents[1], true);
|
|
||||||
break;
|
|
||||||
case Attack3:
|
|
||||||
TargetingOverlay.drawArrow(g, regionDisplay.deployedCommander, regionDisplay.opponents[2], true);
|
|
||||||
break;
|
|
||||||
case Deploy:
|
|
||||||
idx = model.getCurrentPlaneData().getCommanders().indexOf(regionDisplay.deployedCommander.commander);
|
|
||||||
if (idx != -1) {
|
|
||||||
TargetingOverlay.drawArrow(g, commanderRow.panels[idx], regionDisplay.deployedCommander, false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Undeploy:
|
|
||||||
idx = model.getCurrentPlaneData().getCommanders().indexOf(regionDisplay.deployedCommander.commander);
|
|
||||||
if (idx != -1) {
|
|
||||||
TargetingOverlay.drawArrow(g, regionDisplay.deployedCommander, commanderRow.panels[idx], false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doLayout(float startY, float width, float height) {
|
|
||||||
//btnEndDay.setSize(width / 2, btnEndDay.getAutoSizeBounds().height);
|
|
||||||
//btnEndDay.setPosition((width - btnEndDay.getWidth()) / 2, height - btnEndDay.getHeight());
|
|
||||||
|
|
||||||
//float numCommanders = commanderRow.panels.length;
|
|
||||||
//float commanderWidth = (width - (numCommanders + 3) * COMMANDER_GAP) / numCommanders;
|
|
||||||
//float commanderRowHeight = commanderWidth * FCardPanel.ASPECT_RATIO + 2 * COMMANDER_ROW_PADDING;
|
|
||||||
//commanderRow.setBounds(0, btnEndDay.getTop() - PLANE_NAME_FONT.getLineHeight() - 2 * FLabel.DEFAULT_INSETS - commanderRowHeight, width, commanderRowHeight);
|
|
||||||
|
|
||||||
map.setBounds(0, startY, width, height - startY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PlaneMap extends FScrollPane implements IPlaneMapRenderer {
|
|
||||||
private float zoom = 1;
|
|
||||||
private FImage walker = (FImage)PlaneswalkerAchievements.getTrophyImage("Ajani Goldmane");
|
|
||||||
private Graphics g;
|
|
||||||
private ConquestPlaneMap mapData;
|
|
||||||
|
|
||||||
public PlaneMap() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) {
|
|
||||||
if (model == null) {
|
|
||||||
mapData = null;
|
|
||||||
return new ScrollBounds(visibleWidth, visibleHeight);
|
|
||||||
}
|
|
||||||
mapData = model.getCurrentPlaneData().getMap();
|
|
||||||
mapData.setTileWidth(Math.round(visibleWidth / 4 * zoom));
|
|
||||||
return new ScrollBounds(mapData.getWidth(), mapData.getHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean zoom(float x, float y, float amount) {
|
|
||||||
float oldScrollLeft = getScrollLeft();
|
|
||||||
float oldScrollTop = getScrollTop();
|
|
||||||
float oldScrollWidth = getScrollWidth();
|
|
||||||
float oldScrollHeight = getScrollHeight();
|
|
||||||
|
|
||||||
x += oldScrollLeft;
|
|
||||||
y += oldScrollTop;
|
|
||||||
|
|
||||||
if (amount > 0) {
|
|
||||||
zoom *= 1.1f;
|
|
||||||
if (zoom > 4f) {
|
|
||||||
zoom = 4f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
zoom /= 1.1f;
|
|
||||||
if (zoom < 0.25f) {
|
|
||||||
zoom = 0.25f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
revalidate(); //apply change in height to all scroll panes
|
|
||||||
|
|
||||||
//adjust scroll positions to keep x, y in the same spot
|
|
||||||
float newScrollWidth = getScrollWidth();
|
|
||||||
float xAfter = x * newScrollWidth / oldScrollWidth;
|
|
||||||
setScrollLeft(oldScrollLeft + xAfter - x);
|
|
||||||
|
|
||||||
float newScrollHeight = getScrollHeight();
|
|
||||||
float yAfter = y * newScrollHeight / oldScrollHeight;
|
|
||||||
setScrollTop(oldScrollTop + yAfter - y);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void drawBackground(Graphics g0) {
|
|
||||||
if (mapData == null) { return; }
|
|
||||||
g = g0;
|
|
||||||
mapData.draw(this, Math.round(getScrollLeft()), Math.round(getScrollTop()), Math.round(getWidth()), Math.round(getHeight()));
|
|
||||||
g = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(HexagonTile tile, int x, int y, int w, int h) {
|
|
||||||
FSkinImage tileImage;
|
|
||||||
switch (tile.getColorIndex()) {
|
|
||||||
case 0:
|
|
||||||
tileImage = FSkinImage.WHITE_TILE;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
tileImage = FSkinImage.BLUE_TILE;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
tileImage = FSkinImage.BLACK_TILE;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
tileImage = FSkinImage.RED_TILE;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
tileImage = FSkinImage.GREEN_TILE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
tileImage = FSkinImage.COLORLESS_TILE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
g.drawImage(tileImage, x, y, w, h);
|
|
||||||
g.drawImage(FSkinImage.HEXAGON_TILE, x, y, w, h);
|
|
||||||
|
|
||||||
/*if (x < getWidth() / 2 && x + w > getWidth() / 2 && y < getHeight() / 2 && y + h > getHeight() / 2) {
|
|
||||||
float pedestalWidth = w * 0.8f;
|
|
||||||
float pedestalHeight = pedestalWidth * walker.getHeight() / walker.getWidth();
|
|
||||||
g.drawImage(walker, x + (w - pedestalWidth) / 2, y + h / 2 - pedestalHeight * 0.8f, pedestalWidth, pedestalHeight);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RegionDisplay extends FContainer {
|
|
||||||
private final TextRenderer textRenderer = new TextRenderer();
|
|
||||||
private final CommanderPanel[] opponents = new CommanderPanel[3];
|
|
||||||
private final CommanderPanel deployedCommander;
|
|
||||||
private final ActionPanel[] actions = new ActionPanel[4];
|
|
||||||
private String unlockRatio, winRatio;
|
|
||||||
private RegionData data;
|
|
||||||
|
|
||||||
private RegionDisplay() {
|
|
||||||
opponents[0] = add(new CommanderPanel(-1)); //use negative indices to represent cards in region
|
|
||||||
opponents[1] = add(new CommanderPanel(-2));
|
|
||||||
opponents[2] = add(new CommanderPanel(-3));
|
|
||||||
deployedCommander = add(new CommanderPanel(-4));
|
|
||||||
actions[0] = add(new ActionPanel(ConquestAction.Undeploy));
|
|
||||||
actions[1] = add(new ActionPanel(ConquestAction.Defend));
|
|
||||||
actions[2] = add(new ActionPanel(ConquestAction.Recruit));
|
|
||||||
actions[3] = add(new ActionPanel(ConquestAction.Study));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean fling(float velocityX, float velocityY) {
|
|
||||||
//switch to next/previous region when flung left or right
|
|
||||||
if (Math.abs(velocityX) > Math.abs(velocityY)) {
|
|
||||||
if (velocityX < 0) {
|
|
||||||
model.incrementRegion(1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
model.incrementRegion(-1);
|
|
||||||
}
|
|
||||||
onRegionChanged();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onRegionChanged() {
|
|
||||||
data = model.getCurrentPlaneData().getRegionData(model.getCurrentRegion());
|
|
||||||
for (int i = 0; i < opponents.length; i++) {
|
|
||||||
opponents[i].setCommander(data.getOpponent(i));
|
|
||||||
}
|
|
||||||
deployedCommander.setCommander(data.getDeployedCommander());
|
|
||||||
unlockRatio = data.getUnlockedCount() + "/" + data.getRegion().getCardPool().size();
|
|
||||||
winRatio = data.getWins() + "-" + data.getLosses();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doLayout(float width, float height) {
|
|
||||||
/*float x = COMMANDER_GAP / 2;
|
|
||||||
float y = COMMANDER_GAP;
|
|
||||||
float w = width - 2 * x;
|
|
||||||
float h = height - y;
|
|
||||||
float regionFrameThickness = w * REGION_FRAME_THICKNESS_MULTIPLIER;
|
|
||||||
float regionFrameBaseHeight = h * REGION_FRAME_BASE_HEIGHT_MULTIPLIER;
|
|
||||||
x += regionFrameThickness;
|
|
||||||
y += regionFrameThickness;
|
|
||||||
w -= 2 * regionFrameThickness;
|
|
||||||
h -= regionFrameThickness + regionFrameBaseHeight;
|
|
||||||
|
|
||||||
float padding = COMMANDER_GAP;
|
|
||||||
float panelHeight = (h - 5 * padding) / 2;
|
|
||||||
float panelWidth = panelHeight / FCardPanel.ASPECT_RATIO;
|
|
||||||
|
|
||||||
opponents[0].setBounds(x + padding, y + padding, panelWidth, panelHeight);
|
|
||||||
opponents[1].setBounds(x + (w - panelWidth) / 2, y + padding, panelWidth, panelHeight);
|
|
||||||
opponents[2].setBounds(x + w - padding - panelWidth, y + padding, panelWidth, panelHeight);
|
|
||||||
deployedCommander.setBounds(x + (w - panelWidth) / 2, y + h - padding - panelHeight, panelWidth, panelHeight);
|
|
||||||
|
|
||||||
float actionPanelSize = (w - panelWidth - 6 * padding) / 4;
|
|
||||||
x += padding;
|
|
||||||
y += h - padding - actionPanelSize;
|
|
||||||
actions[0].setBounds(x, y, actionPanelSize, actionPanelSize);
|
|
||||||
x += actionPanelSize + padding;
|
|
||||||
actions[1].setBounds(x, y, actionPanelSize, actionPanelSize);
|
|
||||||
x = deployedCommander.getRight() + padding;
|
|
||||||
actions[2].setBounds(x, y, actionPanelSize, actionPanelSize);
|
|
||||||
x += actionPanelSize + padding;
|
|
||||||
actions[3].setBounds(x, y, actionPanelSize, actionPanelSize);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drawBackground(Graphics g) {
|
|
||||||
if (model == null) { return; }
|
|
||||||
Region region = model.getCurrentRegion();
|
|
||||||
|
|
||||||
float x = COMMANDER_GAP / 2;
|
|
||||||
float y = COMMANDER_GAP;
|
|
||||||
float w = getWidth() - 2 * x;
|
|
||||||
float h = getHeight() - y;
|
|
||||||
float regionFrameThickness = w * REGION_FRAME_THICKNESS_MULTIPLIER;
|
|
||||||
float regionFrameBaseHeight = h * REGION_FRAME_BASE_HEIGHT_MULTIPLIER;
|
|
||||||
|
|
||||||
g.startClip(x + regionFrameThickness, y + regionFrameThickness, w - 2 * regionFrameThickness, h - regionFrameThickness - regionFrameBaseHeight);
|
|
||||||
g.drawImage((FImage)region.getArt(), x, y, w, h); //TODO: Maximize in frame while retaining proportions
|
|
||||||
g.endClip();
|
|
||||||
|
|
||||||
y += h - regionFrameBaseHeight;
|
|
||||||
h = regionFrameBaseHeight * 0.9f;
|
|
||||||
g.drawText(unlockRatio, REGION_STATS_FONT, Color.BLACK, 2 * x, y, w, h, false, HAlignment.LEFT, true);
|
|
||||||
textRenderer.drawText(g, region.getName(), REGION_NAME_FONT, Color.BLACK, x, y, w, h, y, h, false, HAlignment.CENTER, true);
|
|
||||||
g.drawText(winRatio, REGION_STATS_FONT, Color.BLACK, x, y, w - x, h, false, HAlignment.RIGHT, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void activate(CommanderPanel panel) {
|
|
||||||
int index = panel.index;
|
|
||||||
if (index >= 0) { //commander row panel
|
|
||||||
if (panel.card != null) {
|
|
||||||
commanderRow.selectedIndex = index;
|
|
||||||
ConquestCommander commander = commanderRow.panels[commanderRow.selectedIndex].commander;
|
|
||||||
if (commander.getDeployedRegion() != null) {
|
|
||||||
if (model.setCurrentRegion(commander.getDeployedRegion())) {
|
|
||||||
regionDisplay.onRegionChanged();
|
|
||||||
}
|
|
||||||
else if (commander.getCurrentDayAction() == null) {
|
|
||||||
//if already on commander's region, change action to undeploy if no action currently set
|
|
||||||
commander.setCurrentDayAction(ConquestAction.Undeploy);
|
|
||||||
}
|
|
||||||
else if (commander.getCurrentDayAction() == ConquestAction.Undeploy) {
|
|
||||||
commander.setCurrentDayAction(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (model.getCurrentPlaneData().getWins() >= panel.getWinsToUnlock()) {
|
|
||||||
FThreads.invokeInBackgroundThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
FModel.getConquest().unlockCommander();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (index >= -regionDisplay.opponents.length) { //opponent panel
|
|
||||||
ConquestCommander commander = regionDisplay.deployedCommander.commander;
|
|
||||||
if (commander != null && commander.getCurrentDayAction() != ConquestAction.Deploy) {
|
|
||||||
ConquestAction action;
|
|
||||||
switch (index) {
|
|
||||||
case -1:
|
|
||||||
action = ConquestAction.Attack1;
|
|
||||||
break;
|
|
||||||
case -2:
|
|
||||||
action = ConquestAction.Attack2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
action = ConquestAction.Attack3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (commander.getCurrentDayAction() == action) {
|
|
||||||
action = null; //toggle off set to attack this opponent
|
|
||||||
}
|
|
||||||
commander.setCurrentDayAction(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { //deploy panel - toggle whether selected commander is deployed to current region
|
|
||||||
ConquestCommander commander = regionDisplay.deployedCommander.commander;
|
|
||||||
if (commander == null) {
|
|
||||||
commander = commanderRow.panels[commanderRow.selectedIndex].commander;
|
|
||||||
if (commander.getCurrentDayAction() == null && commander.getDeployedRegion() == null) {
|
|
||||||
regionDisplay.deployedCommander.setCommander(commander);
|
|
||||||
regionDisplay.data.setDeployedCommander(commander);
|
|
||||||
commander.setCurrentDayAction(ConquestAction.Deploy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (commander.getCurrentDayAction() == ConquestAction.Deploy) {
|
|
||||||
regionDisplay.deployedCommander.setCommander(null);
|
|
||||||
regionDisplay.data.setDeployedCommander(null);
|
|
||||||
commander.setCurrentDayAction(null);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
commander.setCurrentDayAction(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class CommanderRow extends FContainer {
|
|
||||||
private int selectedIndex;
|
|
||||||
private CommanderPanel[] panels = new CommanderPanel[4];
|
|
||||||
|
|
||||||
private CommanderRow() {
|
|
||||||
for (int i = 0; i < panels.length; i++) {
|
|
||||||
panels[i] = add(new CommanderPanel(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doLayout(float width, float height) {
|
|
||||||
float panelHeight = height - 2 * COMMANDER_ROW_PADDING;
|
|
||||||
float panelWidth = panelHeight / FCardPanel.ASPECT_RATIO;
|
|
||||||
float dx = panelWidth + COMMANDER_GAP;
|
|
||||||
float x = 2 * COMMANDER_GAP;
|
|
||||||
float y = COMMANDER_ROW_PADDING;
|
|
||||||
|
|
||||||
for (int i = 0; i < panels.length; i++) {
|
|
||||||
panels[i].setBounds(x, y, panelWidth, panelHeight);
|
|
||||||
x += dx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class CommanderPanel extends FDisplayObject {
|
|
||||||
private final int index;
|
|
||||||
private CardView card;
|
|
||||||
private ConquestCommander commander;
|
|
||||||
|
|
||||||
private CommanderPanel(int index0) {
|
|
||||||
index = index0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setCommander(ConquestCommander commander0) {
|
|
||||||
if (commander == commander0) { return; }
|
|
||||||
commander = commander0;
|
|
||||||
card = commander != null ? Card.getCardForUi(commander.getCard()).getView() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean tap(float x, float y, int count) {
|
|
||||||
if (count == 2 && index >= 0 && commander != null) {
|
|
||||||
Forge.openScreen(new ConquestDeckEditor(commander));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
activate(this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean longPress(float x, float y) {
|
|
||||||
if (card == null) { return false; }
|
|
||||||
|
|
||||||
if (index >= 0) {
|
|
||||||
FDeckViewer.show(commander.getDeck());
|
|
||||||
}
|
|
||||||
else if (index >= -regionDisplay.opponents.length) {
|
|
||||||
List<CardView> cards = new ArrayList<CardView>();
|
|
||||||
for (CommanderPanel panel : regionDisplay.opponents) {
|
|
||||||
if (panel.card == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cards.add(panel.card);
|
|
||||||
}
|
|
||||||
CardZoom.show(cards, -index - 1, new ActivateHandler() {
|
|
||||||
@Override
|
|
||||||
public String getActivateAction(int idx) {
|
|
||||||
if (regionDisplay.deployedCommander.card == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return "play against opponent";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void activate(int idx) {
|
|
||||||
CommandCenterScreen.this.activate(regionDisplay.opponents[idx]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
CardZoom.show(card);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(Graphics g) {
|
|
||||||
float w = getWidth();
|
|
||||||
float h = getHeight();
|
|
||||||
|
|
||||||
float borderThickness = BORDER_THICKNESS;
|
|
||||||
Color color = Color.WHITE;
|
|
||||||
|
|
||||||
ConquestPlaneData planeData = model.getCurrentPlaneData();
|
|
||||||
if (commander == null) {
|
|
||||||
if (index >= 0) {
|
|
||||||
List<ConquestCommander> commanders = planeData.getCommanders();
|
|
||||||
if (index < commanders.size()) {
|
|
||||||
setCommander(commanders.get(index));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (card != null) {
|
|
||||||
boolean needAlpha;
|
|
||||||
if (index >= 0) {
|
|
||||||
//fade out card in commander row if its deployed and not in the process of being undeployed
|
|
||||||
needAlpha = commander.getDeployedRegion() != null && commander.getCurrentDayAction() != ConquestAction.Undeploy;
|
|
||||||
}
|
|
||||||
else if (index >= -regionDisplay.opponents.length) {
|
|
||||||
//fade out opponent if another opponent is being attacked
|
|
||||||
if (regionDisplay.deployedCommander.commander == null || regionDisplay.deployedCommander.commander.getCurrentDayAction() == null) {
|
|
||||||
needAlpha = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
switch (regionDisplay.deployedCommander.commander.getCurrentDayAction()) {
|
|
||||||
case Attack1:
|
|
||||||
needAlpha = (index != -1);
|
|
||||||
break;
|
|
||||||
case Attack2:
|
|
||||||
needAlpha = (index != -2);
|
|
||||||
break;
|
|
||||||
case Attack3:
|
|
||||||
needAlpha = (index != -3);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
needAlpha = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//fade out card in deployed commander spot if its being undeployed
|
|
||||||
needAlpha = commander.getCurrentDayAction() == ConquestAction.Undeploy;
|
|
||||||
}
|
|
||||||
if (needAlpha) {
|
|
||||||
g.setAlphaComposite(0.7f); //use alpha composite if commander deployed
|
|
||||||
}
|
|
||||||
CardRenderer.drawCardWithOverlays(g, card, 0, 0, w, h, CardStackPosition.Top);
|
|
||||||
|
|
||||||
if (commander.getCurrentDayAction() != null) {
|
|
||||||
float padding = w * CardRenderer.PADDING_MULTIPLIER; //adjust for card border
|
|
||||||
w -= 2 * padding;
|
|
||||||
h -= 2 * padding;
|
|
||||||
float actionIconSize = w / 2;
|
|
||||||
float x = (padding + (w / 4)) - actionIconSize / 2;
|
|
||||||
float y = (padding + h) - (h / 8) - actionIconSize / 2;
|
|
||||||
g.drawImage(FSkin.getImages().get(commander.getCurrentDayAction().getIcon()), x, y, actionIconSize, actionIconSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needAlpha) {
|
|
||||||
g.resetAlphaComposite();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == commanderRow.selectedIndex) {
|
|
||||||
borderThickness *= 2;
|
|
||||||
color = Color.GREEN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (index > 0) {
|
|
||||||
int winsToUnlock = getWinsToUnlock();
|
|
||||||
if (planeData.getWins() < winsToUnlock) {
|
|
||||||
g.setAlphaComposite(0.25f);
|
|
||||||
float imageSize = w * 0.75f;
|
|
||||||
g.drawImage(FSkinImage.LOCK, (w - imageSize) / 2, (h - imageSize) / 2, imageSize, imageSize);
|
|
||||||
g.resetAlphaComposite();
|
|
||||||
float y = (h + imageSize) / 2;
|
|
||||||
g.drawText(String.valueOf(winsToUnlock), UNLOCK_WINS_FONT, Color.WHITE, 0, y, w, h - y, false, HAlignment.CENTER, true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
borderThickness *= 2; //double border thickness and make it gold to indicate it's been unlocked
|
|
||||||
color = CardRenderer.getRarityColor(CardRarity.Rare);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g.drawRect(borderThickness, color, -borderThickness, -borderThickness, getWidth() + 2 * borderThickness, getHeight() + 2 * borderThickness);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getWinsToUnlock() {
|
|
||||||
CQPref unlockPref;
|
|
||||||
switch (index) {
|
|
||||||
case 1:
|
|
||||||
unlockPref = CQPref.WINS_TO_UNLOCK_COMMANDER_2;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
unlockPref = CQPref.WINS_TO_UNLOCK_COMMANDER_3;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
unlockPref = CQPref.WINS_TO_UNLOCK_COMMANDER_4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return FModel.getConquestPreferences().getPrefInt(unlockPref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ActionPanel extends FDisplayObject {
|
|
||||||
private final ConquestAction action;
|
|
||||||
|
|
||||||
public ActionPanel(ConquestAction action0) {
|
|
||||||
action = action0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean tap(float x, float y, int count) {
|
|
||||||
ConquestCommander commander = regionDisplay.deployedCommander.commander;
|
|
||||||
if (commander == null || commander.getCurrentDayAction() == ConquestAction.Deploy) {
|
|
||||||
return false; //don't draw if commander just deployed or not deployed in current region
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action == commander.getCurrentDayAction()) {
|
|
||||||
commander.setCurrentDayAction(null);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
commander.setCurrentDayAction(action);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(Graphics g) {
|
|
||||||
ConquestCommander commander = regionDisplay.deployedCommander.commander;
|
|
||||||
if (commander == null || commander.getCurrentDayAction() == ConquestAction.Deploy) {
|
|
||||||
return; //don't draw if commander just deployed or not deployed in current region
|
|
||||||
}
|
|
||||||
|
|
||||||
float w = getWidth();
|
|
||||||
float h = getHeight();
|
|
||||||
|
|
||||||
boolean needAlpha = commander.getCurrentDayAction() != action && commander.getCurrentDayAction() != null;
|
|
||||||
if (needAlpha) {
|
|
||||||
g.setAlphaComposite(0.4f); //use alpha composite if another action was selected
|
|
||||||
}
|
|
||||||
|
|
||||||
float iconSize = w * 0.8f;
|
|
||||||
g.drawImage(FSkin.getImages().get(action.getIcon()), (w - iconSize) / 2, (h - iconSize) / 2, iconSize, iconSize);
|
|
||||||
|
|
||||||
if (needAlpha) {
|
|
||||||
g.resetAlphaComposite();
|
|
||||||
return; //don't draw border if another action was selected
|
|
||||||
}
|
|
||||||
|
|
||||||
float borderThickness = BORDER_THICKNESS;
|
|
||||||
Color color = Color.WHITE;
|
|
||||||
g.drawRect(borderThickness, color, -borderThickness, -borderThickness, w + 2 * borderThickness, h + 2 * borderThickness);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
package forge.screens.planarconquest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
|
||||||
|
import forge.Graphics;
|
||||||
|
import forge.assets.FImage;
|
||||||
|
import forge.assets.FSkinColor;
|
||||||
|
import forge.assets.FSkinFont;
|
||||||
|
import forge.card.CardDetailUtil;
|
||||||
|
import forge.card.CardRenderer;
|
||||||
|
import forge.card.CardDetailUtil.DetailColors;
|
||||||
|
import forge.model.FModel;
|
||||||
|
import forge.planarconquest.ConquestData;
|
||||||
|
import forge.planarconquest.ConquestPlane;
|
||||||
|
import forge.planarconquest.ConquestPlane.Region;
|
||||||
|
import forge.screens.FScreen;
|
||||||
|
import forge.toolbox.FList;
|
||||||
|
import forge.toolbox.FList.ListItemRenderer;
|
||||||
|
import forge.util.FCollectionView;
|
||||||
|
|
||||||
|
public class ConquestMapScreen extends FScreen {
|
||||||
|
private final FList<Region> lstRegions;
|
||||||
|
private ConquestData model;
|
||||||
|
|
||||||
|
public ConquestMapScreen() {
|
||||||
|
super("", ConquestMenu.getMenu());
|
||||||
|
|
||||||
|
lstRegions = add(new FList<Region>() {
|
||||||
|
@Override
|
||||||
|
protected void drawBackground(Graphics g) {
|
||||||
|
//draw no background
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void drawOverlay(Graphics g) {
|
||||||
|
//draw no overlay
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected FSkinColor getItemFillColor(int index) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected boolean drawLineSeparators() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected float getPadding() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
lstRegions.setListItemRenderer(new PlaneRenderer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivate() {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doLayout(float startY, float width, float height) {
|
||||||
|
lstRegions.setBounds(0, startY, width, height - startY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
model = FModel.getConquest().getModel();
|
||||||
|
setHeaderCaption(model.getCurrentPlane().getName() + " - Map");
|
||||||
|
|
||||||
|
FCollectionView<Region> regions = model.getCurrentPlane().getRegions();
|
||||||
|
lstRegions.clear();
|
||||||
|
for (int i = regions.size() - 1; i >= 0; i--) {
|
||||||
|
lstRegions.addItem(regions.get(i));
|
||||||
|
}
|
||||||
|
lstRegions.revalidate();
|
||||||
|
lstRegions.scrollToBottom(); //start at bottom and move up
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PlaneRenderer extends ListItemRenderer<ConquestPlane.Region> {
|
||||||
|
@Override
|
||||||
|
public float getItemHeight() {
|
||||||
|
return ConquestMapScreen.this.getWidth() / CardRenderer.CARD_ART_RATIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tap(Integer index, Region region, float x, float y, int count) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawValue(Graphics g, Integer index, Region region,
|
||||||
|
FSkinFont font, FSkinColor foreColor, FSkinColor backColor,
|
||||||
|
boolean pressed, float x, float y, float w, float h) {
|
||||||
|
|
||||||
|
FImage art = (FImage)region.getArt();
|
||||||
|
if (art != null) {
|
||||||
|
g.drawImage(art, x, y, w, h);
|
||||||
|
}
|
||||||
|
else { //draw fallback background color if needed
|
||||||
|
List<DetailColors> colors = CardDetailUtil.getBorderColors(region.getColorSet());
|
||||||
|
DetailColors dc = colors.get(0);
|
||||||
|
Color color1 = FSkinColor.fromRGB(dc.r, dc.g, dc.b);
|
||||||
|
Color color2 = null;
|
||||||
|
if (colors.size() > 1) {
|
||||||
|
dc = colors.get(1);
|
||||||
|
color2 = FSkinColor.fromRGB(dc.r, dc.g, dc.b);
|
||||||
|
}
|
||||||
|
if (color2 == null) {
|
||||||
|
g.fillRect(color1, x, y, w, h);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g.fillGradientRect(color1, color2, false, x, y, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,13 +20,13 @@ import forge.toolbox.FEvent.FEventHandler;
|
|||||||
|
|
||||||
public class ConquestMenu extends FPopupMenu {
|
public class ConquestMenu extends FPopupMenu {
|
||||||
private static final ConquestMenu conquestMenu = new ConquestMenu();
|
private static final ConquestMenu conquestMenu = new ConquestMenu();
|
||||||
private static final CommandCenterScreen commanderCenterScreen = new CommandCenterScreen();
|
private static final ConquestMapScreen mapScreen = new ConquestMapScreen();
|
||||||
private static final ConquestPrefsScreen prefsScreen = new ConquestPrefsScreen();
|
private static final ConquestPrefsScreen prefsScreen = new ConquestPrefsScreen();
|
||||||
|
|
||||||
private static final FMenuItem mapItem = new FMenuItem("Command Center", FSkinImage.QUEST_MAP, new FEventHandler() {
|
private static final FMenuItem mapItem = new FMenuItem("Command Center", FSkinImage.QUEST_MAP, new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
Forge.openScreen(commanderCenterScreen);
|
Forge.openScreen(mapScreen);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -56,14 +56,14 @@ public class ConquestMenu extends FPopupMenu {
|
|||||||
FModel.getConquest().load(ConquestDataIO.loadData(data));
|
FModel.getConquest().load(ConquestDataIO.loadData(data));
|
||||||
((DeckController<Deck>)EditorType.PlanarConquest.getController()).setRootFolder(FModel.getConquest().getDecks());
|
((DeckController<Deck>)EditorType.PlanarConquest.getController()).setRootFolder(FModel.getConquest().getDecks());
|
||||||
if (reason == LaunchReason.StartPlanarConquest) {
|
if (reason == LaunchReason.StartPlanarConquest) {
|
||||||
Forge.openScreen(commanderCenterScreen);
|
Forge.openScreen(mapScreen);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
commanderCenterScreen.update();
|
mapScreen.update();
|
||||||
if (reason == LaunchReason.LoadConquest) {
|
if (reason == LaunchReason.LoadConquest) {
|
||||||
Forge.back();
|
Forge.back();
|
||||||
if (Forge.onHomeScreen()) { //open map screen if Load Conquest screen was opening direct from home screen
|
if (Forge.onHomeScreen()) { //open map screen if Load Conquest screen was opening direct from home screen
|
||||||
Forge.openScreen(commanderCenterScreen);
|
Forge.openScreen(mapScreen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -72,7 +72,7 @@ public class ConquestMenu extends FPopupMenu {
|
|||||||
Forge.back(); //remove LoadConquestScreen from screen stack
|
Forge.back(); //remove LoadConquestScreen from screen stack
|
||||||
}
|
}
|
||||||
if (Forge.onHomeScreen()) { //open map screen if New Conquest screen was opening direct from home screen
|
if (Forge.onHomeScreen()) { //open map screen if New Conquest screen was opening direct from home screen
|
||||||
Forge.openScreen(commanderCenterScreen);
|
Forge.openScreen(mapScreen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ public class ConquestMenu extends FPopupMenu {
|
|||||||
@Override
|
@Override
|
||||||
protected void buildMenu() {
|
protected void buildMenu() {
|
||||||
FScreen currentScreen = Forge.getCurrentScreen();
|
FScreen currentScreen = Forge.getCurrentScreen();
|
||||||
addItem(mapItem); mapItem.setSelected(currentScreen == commanderCenterScreen);
|
addItem(mapItem); mapItem.setSelected(currentScreen == mapScreen);
|
||||||
addItem(new FMenuItem("New Conquest", FSkinImage.NEW, new FEventHandler() {
|
addItem(new FMenuItem("New Conquest", FSkinImage.NEW, new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
|
|||||||
@@ -194,8 +194,9 @@ public class FList<T> extends FScrollPane implements Iterable<T> {
|
|||||||
boolean drawSeparators = drawLineSeparators();
|
boolean drawSeparators = drawLineSeparators();
|
||||||
|
|
||||||
float y = Math.round(getItemTop(startIndex)); //round y so items don't flicker from rounding error
|
float y = Math.round(getItemTop(startIndex)); //round y so items don't flicker from rounding error
|
||||||
float valueWidth = w - 2 * PADDING;
|
float padding = getPadding();
|
||||||
float valueHeight = itemHeight - 2 * PADDING;
|
float valueWidth = w - 2 * padding;
|
||||||
|
float valueHeight = itemHeight - 2 * padding;
|
||||||
|
|
||||||
for (int i = startIndex; i < items.size(); i++) {
|
for (int i = startIndex; i < items.size(); i++) {
|
||||||
if (y > h) { break; }
|
if (y > h) { break; }
|
||||||
@@ -205,7 +206,7 @@ public class FList<T> extends FScrollPane implements Iterable<T> {
|
|||||||
g.fillRect(fillColor, 0, y, w, itemHeight);
|
g.fillRect(fillColor, 0, y, w, itemHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.drawValue(g, i, items.get(i), font, FORE_COLOR, fillColor, pressedIndex == i, PADDING, y + PADDING, valueWidth, valueHeight);
|
renderer.drawValue(g, i, items.get(i), font, FORE_COLOR, fillColor, pressedIndex == i, padding, y + padding, valueWidth, valueHeight);
|
||||||
|
|
||||||
y += itemHeight;
|
y += itemHeight;
|
||||||
|
|
||||||
@@ -231,6 +232,10 @@ public class FList<T> extends FScrollPane implements Iterable<T> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected float getPadding() {
|
||||||
|
return PADDING;
|
||||||
|
}
|
||||||
|
|
||||||
public static abstract class ListItemRenderer<V> {
|
public static abstract class ListItemRenderer<V> {
|
||||||
public abstract float getItemHeight();
|
public abstract float getItemHeight();
|
||||||
public abstract boolean tap(Integer index, V value, float x, float y, int count);
|
public abstract boolean tap(Integer index, V value, float x, float y, int count);
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ public class CardDetailUtil {
|
|||||||
}
|
}
|
||||||
return getBorderColors(card.getColors(), card.isLand(), canShow, true);
|
return getBorderColors(card.getColors(), card.isLand(), canShow, true);
|
||||||
}
|
}
|
||||||
|
public static List<DetailColors> getBorderColors(final ColorSet colorSet) {
|
||||||
|
return getBorderColors(colorSet, false, true, true);
|
||||||
|
}
|
||||||
private static List<DetailColors> getBorderColors(final ColorSet cardColors, final boolean isLand, boolean canShow, boolean supportMultiple) {
|
private static List<DetailColors> getBorderColors(final ColorSet cardColors, final boolean isLand, boolean canShow, boolean supportMultiple) {
|
||||||
List<DetailColors> borderColors = new ArrayList<DetailColors>();
|
List<DetailColors> borderColors = new ArrayList<DetailColors>();
|
||||||
|
|
||||||
|
|||||||
@@ -3,20 +3,14 @@ package forge.planarconquest;
|
|||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.generation.DeckGenPool;
|
import forge.deck.generation.DeckGenPool;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.planarconquest.ConquestPlane.Region;
|
|
||||||
|
|
||||||
public class ConquestCommander {
|
public class ConquestCommander {
|
||||||
private final PaperCard card;
|
private final PaperCard card;
|
||||||
private final Deck deck;
|
private final Deck deck;
|
||||||
|
|
||||||
private int stars; //think 1-star/4-star general
|
public ConquestCommander(PaperCard card0, DeckGenPool cardPool0, boolean forAi) {
|
||||||
private Region deployedRegion;
|
|
||||||
private ConquestAction currentDayAction;
|
|
||||||
|
|
||||||
public ConquestCommander(PaperCard card0, DeckGenPool cardPool0, boolean forAi, Region deployedRegion0) {
|
|
||||||
card = card0;
|
card = card0;
|
||||||
deck = ConquestUtil.generateDeck(card0, cardPool0, forAi);
|
deck = ConquestUtil.generateDeck(card0, cardPool0, forAi);
|
||||||
deployedRegion = deployedRegion0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@@ -43,24 +37,6 @@ public class ConquestCommander {
|
|||||||
return deck;
|
return deck;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Region getDeployedRegion() {
|
|
||||||
return deployedRegion;
|
|
||||||
}
|
|
||||||
public void setDeployedRegion(Region deployedRegion0) {
|
|
||||||
deployedRegion = deployedRegion0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConquestAction getCurrentDayAction() {
|
|
||||||
return currentDayAction;
|
|
||||||
}
|
|
||||||
public void setCurrentDayAction(ConquestAction currentDayAction0) {
|
|
||||||
currentDayAction = currentDayAction0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStars() {
|
|
||||||
return stars;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return card.getName();
|
return card.getName();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ import forge.interfaces.IWinLoseView;
|
|||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.match.HostedMatch;
|
import forge.match.HostedMatch;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.planarconquest.ConquestPlaneData.RegionData;
|
|
||||||
import forge.planarconquest.ConquestPreferences.CQPref;
|
import forge.planarconquest.ConquestPreferences.CQPref;
|
||||||
import forge.player.GamePlayerUtil;
|
import forge.player.GamePlayerUtil;
|
||||||
import forge.player.LobbyPlayerHuman;
|
import forge.player.LobbyPlayerHuman;
|
||||||
@@ -112,86 +111,12 @@ public class ConquestController {
|
|||||||
SGuiChoose.reveal(commander.getName() + " brought along " + Lang.nounWithAmount(newCards.size(), "new card"), newCards);
|
SGuiChoose.reveal(commander.getName() + " brought along " + Lang.nounWithAmount(newCards.size(), "new card"), newCards);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void endDay(final IVCommandCenter commandCenter) {
|
|
||||||
FThreads.invokeInBackgroundThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
//prompt user if any commander hasn't taken an action
|
|
||||||
final List<ConquestCommander> commanders = model.getCurrentPlaneData().getCommanders();
|
|
||||||
for (ConquestCommander commander : commanders) {
|
|
||||||
if (commander.getCurrentDayAction() == null) {
|
|
||||||
if (!SOptionPane.showConfirmDialog(commander.getName() + " has not taken an action today. End day anyway?", "Action Not Taken", "End Day", "Cancel")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
model.getNewCards().clear(); //reset new cards list before more new cards unlocked
|
|
||||||
|
|
||||||
//perform all commander actions
|
|
||||||
for (ConquestCommander commander : commanders) {
|
|
||||||
if (commandCenter.setSelectedCommander(commander)) {
|
|
||||||
try {
|
|
||||||
//sleep if selection changed so user can see it take effect
|
|
||||||
Thread.sleep(500);
|
|
||||||
}
|
|
||||||
catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch (commander.getCurrentDayAction()) {
|
|
||||||
case Attack1:
|
|
||||||
playGame(commander, 0, false, commandCenter);
|
|
||||||
break;
|
|
||||||
case Attack2:
|
|
||||||
playGame(commander, 1, false, commandCenter);
|
|
||||||
break;
|
|
||||||
case Attack3:
|
|
||||||
playGame(commander, 2, false, commandCenter);
|
|
||||||
break;
|
|
||||||
case Defend:
|
|
||||||
playGame(commander, Aggregates.randomInt(0, 2), true, commandCenter); //defend against random opponent
|
|
||||||
break;
|
|
||||||
case Recruit:
|
|
||||||
recruit(commander);
|
|
||||||
break;
|
|
||||||
case Study:
|
|
||||||
study(commander);
|
|
||||||
break;
|
|
||||||
case Undeploy:
|
|
||||||
model.getCurrentPlaneData().getRegionData(commander.getDeployedRegion()).setDeployedCommander(null);
|
|
||||||
break;
|
|
||||||
default: //remaining actions don't need to do anything more
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
commander.setCurrentDayAction(null);
|
|
||||||
try {
|
|
||||||
Thread.sleep(500);
|
|
||||||
}
|
|
||||||
catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//update UI for new day
|
|
||||||
FThreads.invokeInEdtLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
model.incrementDay();
|
|
||||||
commandCenter.updateCurrentDay();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void playGame(final ConquestCommander commander, final int opponentIndex, final boolean isHumanDefending, final IVCommandCenter commandCenter) {
|
private void playGame(final ConquestCommander commander, final int opponentIndex, final boolean isHumanDefending, final IVCommandCenter commandCenter) {
|
||||||
gameRunner = new GameRunner(commander, opponentIndex, isHumanDefending, commandCenter);
|
gameRunner = new GameRunner(commander, opponentIndex, isHumanDefending, commandCenter);
|
||||||
gameRunner.invokeAndWait();
|
gameRunner.invokeAndWait();
|
||||||
|
|
||||||
//after game finished
|
//after game finished
|
||||||
if (gameRunner.wonGame) {
|
if (gameRunner.wonGame) {
|
||||||
RegionData regionData = model.getCurrentPlaneData().getRegionData(commander.getDeployedRegion());
|
|
||||||
regionData.replaceOpponent(opponentIndex);
|
|
||||||
}
|
}
|
||||||
gameRunner = null;
|
gameRunner = null;
|
||||||
}
|
}
|
||||||
@@ -209,8 +134,7 @@ public class ConquestController {
|
|||||||
|
|
||||||
private GameRunner(final ConquestCommander commander0, final int opponentIndex, final boolean isHumanDefending0, final IVCommandCenter commandCenter0) {
|
private GameRunner(final ConquestCommander commander0, final int opponentIndex, final boolean isHumanDefending0, final IVCommandCenter commandCenter0) {
|
||||||
commander = commander0;
|
commander = commander0;
|
||||||
RegionData regionData = model.getCurrentPlaneData().getRegionData(commander.getDeployedRegion());
|
opponent = null; //model.getCurrentPlaneData().getOpponent(opponentIndex);
|
||||||
opponent = regionData.getOpponent(opponentIndex);
|
|
||||||
isHumanDefending = isHumanDefending0;
|
isHumanDefending = isHumanDefending0;
|
||||||
commandCenter = commandCenter0;
|
commandCenter = commandCenter0;
|
||||||
}
|
}
|
||||||
@@ -345,14 +269,14 @@ public class ConquestController {
|
|||||||
|
|
||||||
private boolean recruit(ConquestCommander commander) {
|
private boolean recruit(ConquestCommander commander) {
|
||||||
boolean bonusCard = Aggregates.randomInt(1, 100) <= FModel.getConquestPreferences().getPrefInt(CQPref.RECRUIT_BONUS_CARD_ODDS);
|
boolean bonusCard = Aggregates.randomInt(1, 100) <= FModel.getConquestPreferences().getPrefInt(CQPref.RECRUIT_BONUS_CARD_ODDS);
|
||||||
return awardNewCards(commander.getDeployedRegion().getCardPool().getAllCards(),
|
return awardNewCards(model.getCurrentPlane().getCardPool().getAllCards(),
|
||||||
commander.getName() + " recruited", "new creature", null, null,
|
commander.getName() + " recruited", "new creature", null, null,
|
||||||
CardRulesPredicates.Presets.IS_CREATURE, bonusCard ? 2 : 1);
|
CardRulesPredicates.Presets.IS_CREATURE, bonusCard ? 2 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean study(ConquestCommander commander) {
|
private boolean study(ConquestCommander commander) {
|
||||||
boolean bonusCard = Aggregates.randomInt(1, 100) <= FModel.getConquestPreferences().getPrefInt(CQPref.STUDY_BONUS_CARD_ODDS);
|
boolean bonusCard = Aggregates.randomInt(1, 100) <= FModel.getConquestPreferences().getPrefInt(CQPref.STUDY_BONUS_CARD_ODDS);
|
||||||
return awardNewCards(commander.getDeployedRegion().getCardPool().getAllCards(),
|
return awardNewCards(model.getCurrentPlane().getCardPool().getAllCards(),
|
||||||
commander.getName() + " unlocked", "new spell", null, null,
|
commander.getName() + " unlocked", "new spell", null, null,
|
||||||
CardRulesPredicates.Presets.IS_NON_CREATURE_SPELL, bonusCard ? 2 : 1);
|
CardRulesPredicates.Presets.IS_NON_CREATURE_SPELL, bonusCard ? 2 : 1);
|
||||||
}
|
}
|
||||||
@@ -619,7 +543,7 @@ public class ConquestController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void awardBooster(final IWinLoseView<? extends IButton> view) {
|
private void awardBooster(final IWinLoseView<? extends IButton> view) {
|
||||||
Iterable<PaperCard> cardPool = gameRunner.commander.getDeployedRegion().getCardPool().getAllCards();
|
Iterable<PaperCard> cardPool = model.getCurrentPlane().getCardPool().getAllCards();
|
||||||
|
|
||||||
ConquestPreferences prefs = FModel.getConquestPreferences();
|
ConquestPreferences prefs = FModel.getConquestPreferences();
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public final class ConquestData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<PaperCard> addCommander(PaperCard card) {
|
public List<PaperCard> addCommander(PaperCard card) {
|
||||||
ConquestCommander commander = new ConquestCommander(card, currentPlane.getCardPool(), false, null);
|
ConquestCommander commander = new ConquestCommander(card, currentPlane.getCardPool(), false);
|
||||||
getCurrentPlaneData().getCommanders().add(commander);
|
getCurrentPlaneData().getCommanders().add(commander);
|
||||||
decks.put(commander.getDeck().getName(), commander.getDeck());
|
decks.put(commander.getDeck().getName(), commander.getDeck());
|
||||||
|
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ public enum ConquestPlane {
|
|||||||
Iterables.addAll(cards, FModel.getConquest().getModel().getCurrentPlane().getCommanders());
|
Iterables.addAll(cards, FModel.getConquest().getModel().getCurrentPlane().getCommanders());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ConquestCommander(Aggregates.random(cards), cardPool, true, this);
|
return new ConquestCommander(Aggregates.random(cards), cardPool, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|||||||
@@ -8,15 +8,12 @@ import java.util.Map;
|
|||||||
|
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.planarconquest.ConquestPlane.Region;
|
|
||||||
|
|
||||||
public class ConquestPlaneData {
|
public class ConquestPlaneData {
|
||||||
private final List<ConquestCommander> commanders = new ArrayList<ConquestCommander>();
|
private final List<ConquestCommander> commanders = new ArrayList<ConquestCommander>();
|
||||||
private final Map<Region, RegionData> regionDataLookup = new HashMap<Region, RegionData>();
|
|
||||||
private final Map<String, Integer> winsPerOpponent = new HashMap<String, Integer>();
|
private final Map<String, Integer> winsPerOpponent = new HashMap<String, Integer>();
|
||||||
private final Map<String, Integer> lossesPerOpponent = new HashMap<String, Integer>();
|
private final Map<String, Integer> lossesPerOpponent = new HashMap<String, Integer>();
|
||||||
private final ConquestPlane plane;
|
private final ConquestPlane plane;
|
||||||
private final ConquestPlaneMap map;
|
|
||||||
|
|
||||||
private int wins, losses;
|
private int wins, losses;
|
||||||
private int winStreakBest = 0;
|
private int winStreakBest = 0;
|
||||||
@@ -24,7 +21,6 @@ public class ConquestPlaneData {
|
|||||||
|
|
||||||
public ConquestPlaneData(ConquestPlane plane0) {
|
public ConquestPlaneData(ConquestPlane plane0) {
|
||||||
plane = plane0;
|
plane = plane0;
|
||||||
map = new ConquestPlaneMap(plane0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ConquestCommander> getCommanders() {
|
public List<ConquestCommander> getCommanders() {
|
||||||
@@ -56,14 +52,12 @@ public class ConquestPlaneData {
|
|||||||
if (winStreakCurrent > winStreakBest) {
|
if (winStreakCurrent > winStreakBest) {
|
||||||
winStreakBest = winStreakCurrent;
|
winStreakBest = winStreakCurrent;
|
||||||
}
|
}
|
||||||
getRegionData(opponent.getDeployedRegion()).wins++;
|
|
||||||
winsPerOpponent.put(opponent.getName(), getWinsAgainst(opponent.getCard()) + 1);
|
winsPerOpponent.put(opponent.getName(), getWinsAgainst(opponent.getCard()) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLoss(ConquestCommander opponent) {
|
public void addLoss(ConquestCommander opponent) {
|
||||||
losses++;
|
losses++;
|
||||||
winStreakCurrent = 0;
|
winStreakCurrent = 0;
|
||||||
getRegionData(opponent.getDeployedRegion()).losses++;
|
|
||||||
lossesPerOpponent.put(opponent.getName(), getLossesAgainst(opponent.getCard()) + 1);
|
lossesPerOpponent.put(opponent.getName(), getLossesAgainst(opponent.getCard()) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,75 +87,4 @@ public class ConquestPlaneData {
|
|||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConquestPlaneMap getMap() {
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RegionData getRegionData(Region region) {
|
|
||||||
RegionData regionData = regionDataLookup.get(region);
|
|
||||||
if (regionData == null) {
|
|
||||||
regionData = new RegionData(region);
|
|
||||||
regionDataLookup.put(region, regionData);
|
|
||||||
}
|
|
||||||
return regionData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RegionData {
|
|
||||||
private final Region region;
|
|
||||||
private final ConquestCommander[] opponents = new ConquestCommander[3];
|
|
||||||
private ConquestCommander deployedCommander;
|
|
||||||
private int wins, losses;
|
|
||||||
|
|
||||||
private RegionData(Region region0) {
|
|
||||||
region = region0;
|
|
||||||
opponents[0] = region.getRandomOpponent(opponents);
|
|
||||||
opponents[1] = region.getRandomOpponent(opponents);
|
|
||||||
opponents[2] = region.getRandomOpponent(opponents);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Region getRegion() {
|
|
||||||
return region;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWins() {
|
|
||||||
return wins;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLosses() {
|
|
||||||
return losses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConquestCommander getOpponent(int index) {
|
|
||||||
return opponents[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void replaceOpponent(int index) {
|
|
||||||
opponents[index] = region.getRandomOpponent(opponents);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConquestCommander getDeployedCommander() {
|
|
||||||
return deployedCommander;
|
|
||||||
}
|
|
||||||
public void setDeployedCommander(ConquestCommander commander) {
|
|
||||||
if (deployedCommander != null && deployedCommander.getDeployedRegion() == region) {
|
|
||||||
deployedCommander.setDeployedRegion(null);
|
|
||||||
}
|
|
||||||
deployedCommander = commander;
|
|
||||||
if (deployedCommander != null) {
|
|
||||||
deployedCommander.setDeployedRegion(region);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getUnlockedCount() {
|
|
||||||
int count = 0;
|
|
||||||
HashSet<PaperCard> collection = FModel.getConquest().getModel().getCollection();
|
|
||||||
for (PaperCard pc : region.getCardPool().getAllCards()) {
|
|
||||||
if (collection.contains(pc)) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,204 +0,0 @@
|
|||||||
package forge.planarconquest;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import forge.assets.FSkinProp;
|
|
||||||
import forge.card.MagicColor;
|
|
||||||
import forge.planarconquest.ConquestPlane.Region;
|
|
||||||
import forge.util.Aggregates;
|
|
||||||
import forge.util.FCollectionView;
|
|
||||||
|
|
||||||
public class ConquestPlaneMap {
|
|
||||||
private static final double sqrt3 = (float)Math.sqrt(3);
|
|
||||||
|
|
||||||
//use 2 dimensional array to represent tile grid
|
|
||||||
private final int gridSize;
|
|
||||||
private final HexagonTile[][] grid;
|
|
||||||
private int tileWidth, tileHeight, padding;
|
|
||||||
|
|
||||||
public ConquestPlaneMap(ConquestPlane plane) {
|
|
||||||
int size = (int)Math.round(Math.sqrt(plane.getCardPool().size() / 2)); //use card pool size to determine grid size
|
|
||||||
if (size % 2 == 0) {
|
|
||||||
size++; //ensure grid size is an odd number
|
|
||||||
}
|
|
||||||
gridSize = size;
|
|
||||||
grid = new HexagonTile[gridSize][gridSize];
|
|
||||||
generateRandomGrid(plane);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTileWidth(int tileWidth0) {
|
|
||||||
if (tileWidth == tileWidth0) { return; }
|
|
||||||
tileWidth = tileWidth0;
|
|
||||||
tileHeight = Math.round((float)tileWidth * (float)FSkinProp.IMG_HEXAGON_TILE.getHeight() / (float)FSkinProp.IMG_HEXAGON_TILE.getWidth());
|
|
||||||
padding = tileWidth / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWidth() {
|
|
||||||
return tileWidth * gridSize + tileWidth / 2 + 2 * padding;
|
|
||||||
}
|
|
||||||
public int getHeight() {
|
|
||||||
return tileHeight * 3 / 4 * (gridSize - 1) + tileHeight + 2 * padding;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HexagonTile getTileAtPoint(float x, float y) {
|
|
||||||
//convert pixel to axial coordinates
|
|
||||||
x = (x - tileWidth / 2) / tileWidth - padding;
|
|
||||||
double t1 = y / (tileWidth / 2), t2 = Math.floor(x + t1);
|
|
||||||
int r = (int)Math.floor((Math.floor(t1 - x) + t2) / 3);
|
|
||||||
int q = (int)Math.floor((Math.floor(2 * x + 1) + t2) / 3) - r;
|
|
||||||
|
|
||||||
//convert axial to offset coordinates
|
|
||||||
r += (q - (q & 1)) / 2;
|
|
||||||
|
|
||||||
if (r < 0 || q < 0 || q >= gridSize || r >= gridSize) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return grid[q][r];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(IPlaneMapRenderer renderer, int scrollLeft, int scrollTop, int visibleWidth, int visibleHeight) {
|
|
||||||
scrollLeft -= padding;
|
|
||||||
scrollTop -= padding;
|
|
||||||
|
|
||||||
int dy = tileHeight * 3 / 4;
|
|
||||||
int startQ = getIndexInRange((int)Math.floor((float)(scrollLeft - tileWidth * 1.5f) / (float)tileWidth) + 1);
|
|
||||||
int startR = getIndexInRange((int)Math.floor((float)(scrollTop - tileHeight) / (float)dy) + 1);
|
|
||||||
int endQ = getIndexInRange((int)Math.floor((float)(scrollLeft + visibleWidth - tileWidth * 1.5f) / (float)tileWidth) + 2);
|
|
||||||
int endR = getIndexInRange((int)Math.floor((float)(scrollTop + visibleHeight - tileHeight) / (float)dy) + 2);
|
|
||||||
|
|
||||||
int x;
|
|
||||||
int y = startR * dy - scrollTop;
|
|
||||||
int startX = startQ * tileWidth - scrollLeft;
|
|
||||||
for (int r = startR; r <= endR; r++) {
|
|
||||||
x = startX;
|
|
||||||
if (r % 2 == 1) {
|
|
||||||
x += tileWidth / 2; //odd columns start lower
|
|
||||||
}
|
|
||||||
for (int q = startQ; q <= endQ; q++) {
|
|
||||||
HexagonTile tile = grid[q][r];
|
|
||||||
if (tile != null) {
|
|
||||||
renderer.draw(tile, x, y, tileWidth, tileHeight);
|
|
||||||
}
|
|
||||||
x += tileWidth;
|
|
||||||
}
|
|
||||||
y += dy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getIndexInRange(int index) {
|
|
||||||
if (index < 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (index >= gridSize) {
|
|
||||||
return gridSize - 1;
|
|
||||||
}
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static interface IPlaneMapRenderer {
|
|
||||||
void draw(HexagonTile tile, int x, int y, int w, int h);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateRandomGrid(ConquestPlane plane) {
|
|
||||||
int center = gridSize / 2; //player will start at center of grid always
|
|
||||||
|
|
||||||
//divide the grid into regions
|
|
||||||
FCollectionView<Region> regions = plane.getRegions();
|
|
||||||
int regionCount = regions.size();
|
|
||||||
double regionAngle = 2 * Math.PI / regionCount;
|
|
||||||
|
|
||||||
//these assume a tile width of 2, radius of 1
|
|
||||||
double centerX = sqrt3 * (center + 0.5f * (center & 1));
|
|
||||||
double centerY = 1.5 * center;
|
|
||||||
double maxDist = (centerX + centerY) / 2;
|
|
||||||
|
|
||||||
//create a circular map, divided into regions
|
|
||||||
for (int r = 0; r < gridSize; r++) {
|
|
||||||
for (int q = 0; q < gridSize; q++) {
|
|
||||||
double x = sqrt3 * (q + 0.5f * (r & 1));
|
|
||||||
double y = 1.5 * r;
|
|
||||||
double dx = x - centerX;
|
|
||||||
double dy = y - centerY;
|
|
||||||
double dist = Math.sqrt(dx * dx + dy * dy);
|
|
||||||
if (dist > maxDist) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double angle = Math.atan2(dy, dx) + Math.PI;
|
|
||||||
int regionIndex = (int)Math.floor(angle / regionAngle);
|
|
||||||
if (regionIndex >= regionCount) {
|
|
||||||
regionIndex = 0;
|
|
||||||
}
|
|
||||||
grid[q][r] = new HexagonTile(q, r, regions.get(regionIndex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class HexagonTile {
|
|
||||||
private final int q, r;
|
|
||||||
private final Region region;
|
|
||||||
private final int colorIndex;
|
|
||||||
|
|
||||||
private HexagonTile(int q0, int r0, Region region0) {
|
|
||||||
q = q0;
|
|
||||||
r = r0;
|
|
||||||
region = region0;
|
|
||||||
if (region.getColorSet().isColorless()) {
|
|
||||||
colorIndex = -1;
|
|
||||||
}
|
|
||||||
else if (region.getColorSet().isMonoColor()) {
|
|
||||||
int index;
|
|
||||||
byte color = region.getColorSet().getColor();
|
|
||||||
for (index = 0; index < 5; index++) {
|
|
||||||
if (MagicColor.WUBRG[index] == color) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
colorIndex = index;
|
|
||||||
}
|
|
||||||
else { //for multicolor regions, choose one of the colors at random
|
|
||||||
int index;
|
|
||||||
while (true) {
|
|
||||||
index = Aggregates.randomInt(0, 4);
|
|
||||||
if (region.getColorSet().hasAnyColor(MagicColor.WUBRG[index])) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
colorIndex = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColorIndex() {
|
|
||||||
return colorIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<HexagonTile> getNeighbors() {
|
|
||||||
List<HexagonTile> neighbors = new ArrayList<HexagonTile>();
|
|
||||||
addToList(q, r - 1, neighbors); //tile above
|
|
||||||
addToList(q, r + 1, neighbors); //tile below
|
|
||||||
if (q % 2 == 0) {
|
|
||||||
addToList(q - 1, r - 1, neighbors); //tile left and up
|
|
||||||
addToList(q - 1, r, neighbors); //tile left and down
|
|
||||||
addToList(q + 1, r - 1, neighbors); //tile right and up
|
|
||||||
addToList(q + 1, r, neighbors); //tile right and down
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addToList(q - 1, r, neighbors); //tile left and up
|
|
||||||
addToList(q - 1, r + 1, neighbors); //tile left and down
|
|
||||||
addToList(q + 1, r, neighbors); //tile right and up
|
|
||||||
addToList(q + 1, r + 1, neighbors); //tile right and down
|
|
||||||
}
|
|
||||||
return neighbors;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addToList(int q, int r, List<HexagonTile> list) {
|
|
||||||
if (r < 0 || q < 0 || q >= gridSize || r >= gridSize) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
HexagonTile tile = grid[q][r];
|
|
||||||
if (tile != null) {
|
|
||||||
list.add(tile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user