package com.galvarez.ttw.screens;
import static com.badlogic.gdx.math.MathUtils.PI;
import static com.badlogic.gdx.math.MathUtils.cos;
import static com.badlogic.gdx.math.MathUtils.sin;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.artemis.Entity;
import com.artemis.World;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.galvarez.ttw.ThingsThatWereGame;
import com.galvarez.ttw.model.DiplomaticSystem;
import com.galvarez.ttw.model.DiplomaticSystem.Action;
import com.galvarez.ttw.model.components.Diplomacy;
import com.galvarez.ttw.rendering.components.Name;
import com.galvarez.ttw.rendering.ui.FramedMenu;
/**
* This screen appears when user selects the diplomacy menu. It displays
* relations with neighbors and possible actions.
*
* @author Guillaume Alvarez
*/
public final class DiplomacyMenuScreen extends AbstractPausedScreen<AbstractScreen> {
@SuppressWarnings("unused")
private static final Logger log = LoggerFactory.getLogger(DiplomacyMenuScreen.class);
private final FramedMenu topMenu;
private FramedMenu actionMenu;
private final List<Entity> empires;
private final Entity player;
private final DiplomaticSystem diplomaticSystem;
private final List<FramedMenu> menus = new ArrayList<>();
public DiplomacyMenuScreen(ThingsThatWereGame game, World world, SpriteBatch batch, AbstractScreen gameScreen,
List<Entity> empires, Entity player, DiplomaticSystem diplomaticSystem) {
super(game, world, batch, gameScreen);
this.empires = empires;
this.player = player;
this.diplomaticSystem = diplomaticSystem;
topMenu = new FramedMenu(skin, 800, 600);
}
@Override
protected void initMenu() {
if (actionMenu != null)
actionMenu.clear();
topMenu.clear();
topMenu.addButton("Resume game", this::resumeGame);
topMenu.addToStage(stage, 30, stage.getHeight() - 30, false);
menus.forEach(m -> m.clear());
menus.clear();
int maxWidth = 128;
float centerX = (Gdx.graphics.getWidth() - maxWidth) * 0.5f;
float centerY = topMenu.getY() * 0.5f;
float radiusX = Gdx.graphics.getWidth() * 0.4f;
float radiusY = topMenu.getY() * 0.4f;
float angle = 2f * PI / (player != null ? empires.size() - 1 : empires.size());
float angle1 = 0f;
Diplomacy playerDiplo = player != null ? player.getComponent(Diplomacy.class) : null;
for (Entity empire : playerDiplo != null ? playerDiplo.relations.keySet() : empires) {
if (empire != player) {
FramedMenu menu = new FramedMenu(skin, maxWidth, 128);
menu.addLabel(empire.getComponent(Name.class).name);
if (playerDiplo != null) {
menu.addButton(playerDiplo.getRelationWith(empire).toString(),
() -> displayActionsMenu(menu, playerDiplo, empire));
// TODO needs a smaller font for these labels
Action mine = playerDiplo.getProposalTo(empire);
if (mine != Action.NO_CHANGE)
menu.addLabel(">" + mine.str);
Action yours = empire.getComponent(Diplomacy.class).getProposalTo(player);
if (yours != Action.NO_CHANGE)
menu.addLabel("<" + yours.str);
}
menu.addToStage(stage, centerX + radiusX * cos(angle1), centerY + radiusY * sin(angle1), false);
menus.add(menu);
angle1 += angle;
}
}
// draw player at the center of the screen, so that it is easier for him to
// understand the screen contents
FramedMenu menu = new FramedMenu(skin, maxWidth, 36);
menu.addLabel(player.getComponent(Name.class).name);
menu.addToStage(stage, centerX, centerY, false);
menus.add(menu);
}
private void displayActionsMenu(FramedMenu parent, Diplomacy diplo, Entity target) {
if (actionMenu != null)
actionMenu.clear();
actionMenu = new FramedMenu(skin, 256, 128, parent);
boolean hasActions = false;
for (Action action : diplomaticSystem.getPossibleActions(diplo, target)) {
hasActions = true;
actionMenu.addButton(action.str, new Runnable() {
@Override
public void run() {
if (action != Action.NO_CHANGE)
diplo.proposals.put(target, action);
actionMenu.clear();
initMenu();
}
});
}
if (!hasActions)
actionMenu.addLabel("No possible actions!");
if (actionMenu.getTable().getPrefHeight() > parent.getY()) {
if (actionMenu.getTable().getPrefWidth() <= parent.getX())
// display on BOTTOM LEFT
actionMenu.addToStage(stage, parent.getX() - actionMenu.getTable().getPrefWidth(), parent.getY() - 10, true);
else
// display on BOTTOM RIGHT
actionMenu.addToStage(stage, parent.getX() + parent.getWidth(), parent.getY() - 10, true);
} else {
if (actionMenu.getTable().getPrefWidth() <= parent.getX())
// display on TOP LEFT
actionMenu.addToStage(stage, parent.getX() - actionMenu.getTable().getPrefWidth(),
parent.getY() + parent.getHeight() - 10, true);
else
// display on TOP RIGHT
actionMenu.addToStage(stage, parent.getX() + parent.getWidth(), parent.getY() + parent.getHeight() - 10, true);
}
}
}