Start refactoring Planar Conquest to support new mobile friendly format

This commit is contained in:
drdev
2015-03-12 02:15:10 +00:00
parent 5f7dd38164
commit ebf40b96cc
12 changed files with 142 additions and 1104 deletions

3
.gitattributes vendored
View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}
}
}

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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>();

View File

@@ -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();
} }

View File

@@ -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();

View File

@@ -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());

View File

@@ -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() {

View File

@@ -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;
}
}
} }

View File

@@ -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);
}
}
}