diff --git a/core/src/com/galvarez/ttw/model/DisasterSystem.java b/core/src/com/galvarez/ttw/model/DisasterSystem.java index fb20cea..6dd08a4 100644 --- a/core/src/com/galvarez/ttw/model/DisasterSystem.java +++ b/core/src/com/galvarez/ttw/model/DisasterSystem.java @@ -45,6 +45,11 @@ public DisasterSystem(OverworldScreen screen) { this.screen = screen; } + @Override + public String getType() { + return "Disaster"; + } + @Override protected void initialize() { super.initialize(); @@ -70,13 +75,15 @@ public int getProgress(Entity e) { } @Override - public void execute(Entity e) { + public boolean execute(Entity e) { InfluenceSource source = sources.get(e); source.setPower(source.health / 2); fadingSystem.createFadingIcon(Type.DISEASE, empires.get(e).color, positions.get(e), 3f); notifications.addNotification(() -> screen.select(e, false), null, Type.DISEASE, "Mortal disease strikes %s!", e.getComponent(Description.class)); + + return true; } } diff --git a/core/src/com/galvarez/ttw/model/DiscoverySystem.java b/core/src/com/galvarez/ttw/model/DiscoverySystem.java index cbb17a9..4169083 100644 --- a/core/src/com/galvarez/ttw/model/DiscoverySystem.java +++ b/core/src/com/galvarez/ttw/model/DiscoverySystem.java @@ -99,6 +99,11 @@ public DiscoverySystem(SessionSettings s, GameMap map, OverworldScreen screen) { this.screen = screen; } + @Override + public String getType() { + return "Discovery"; + } + @Override protected void initialize() { super.initialize(); @@ -189,6 +194,11 @@ private Map possibleDiscoveries(Entity empire, Discoveries la Map res = new EnumMap<>(Faction.class); for (Faction f : Faction.values()) { + if (possible.isEmpty()) { + log.debug("Found no {} research among {} for {}", f, possible, empire.getComponent(Description.class)); + continue; + } + Collections.sort(possible, new Comparator() { @Override public int compare(Research d1, Research d2) { @@ -197,9 +207,6 @@ public int compare(Research d1, Research d2) { } }); - if (possible.isEmpty()) - continue; - Research selected = null; for (int i = rand.nextInt(min(2, possible.size())); i >= 0 && selected == null; i--) if (possible.get(i).factions.get(f, 0f) >= 0f) @@ -287,18 +294,22 @@ public int getProgress(Entity e) { } @Override - public void execute(Entity e) { - discoverNext(e, empires.get(e)); + public boolean execute(Entity e) { + return discoverNext(e, empires.get(e)); } - private void discoverNext(Entity empire, Discoveries discovery) { + private boolean discoverNext(Entity empire, Discoveries discovery) { discovery.nextPossible = possibleDiscoveries(empire, discovery); - if (!ai.has(empire) && !discovery.nextPossible.isEmpty()) { + if (discovery.nextPossible.isEmpty()) + return false; + + if (!ai.has(empire)) { Research last = discovery.last; notifications.addNotification(screen::askDiscovery, () -> discovery.last != last, Type.DISCOVERY, "We can make a new discovery!"); } + return true; } /** Called when the next discovery is chosen. */ diff --git a/core/src/com/galvarez/ttw/model/EventsSystem.java b/core/src/com/galvarez/ttw/model/EventsSystem.java index 87ad0b5..5ff975b 100644 --- a/core/src/com/galvarez/ttw/model/EventsSystem.java +++ b/core/src/com/galvarez/ttw/model/EventsSystem.java @@ -19,8 +19,16 @@ public interface EventHandler { /** Get the score progress toward next event of this type. */ int getProgress(Entity e); - /** Execute the event on the entity. */ - void execute(Entity e); + /** + * Execute the event on the entity. + * + * @return true if it could execute the event (false if some system + * condition prevented it) + */ + boolean execute(Entity e); + + /** A pretty printing name for the event. */ + String getType(); } @@ -39,29 +47,39 @@ public void addEventType(EventHandler type) { @Override protected void inserted(Entity e) { super.inserted(e); - for (EventHandler type : types) - counts.get(e).scores.put(type, 0); + EventsCount count = counts.get(e); + for (EventHandler type : types) { + count.scores.put(type, 0); + } + count.increment.putAll(count.scores); + count.display.putAll(count.scores); } @Override protected void processEntities(ImmutableBag entities) { + for (Entity e : entities) + checkEvents(e); + } + + private void checkEvents(Entity e) { int maxScore = Integer.MIN_VALUE; EventHandler selected = null; - for (Entity e : entities) { - EventsCount count = counts.get(e); - for (EventHandler type : count.scores.keys()) { - int newScore = type.getProgress(e) + count.scores.get(type, 0); - count.scores.put(type, newScore); - if (newScore > maxScore) { - selected = type; - maxScore = newScore; - } + EventsCount count = counts.get(e); + for (EventHandler type : count.scores.keys()) { + int progress = type.getProgress(e); + int newScore = progress + count.scores.get(type, 0); + count.increment.put(type, progress); + count.display.put(type, newScore); + count.scores.put(type, newScore); + if (newScore > maxScore) { + selected = type; + maxScore = newScore; } - if (selected != null) { - selected.execute(e); + } + if (selected != null) { + if (selected.execute(e)) // also reset score count.scores.put(selected, 0); - } } } } diff --git a/core/src/com/galvarez/ttw/model/RevoltSystem.java b/core/src/com/galvarez/ttw/model/RevoltSystem.java index 317e009..ed75410 100644 --- a/core/src/com/galvarez/ttw/model/RevoltSystem.java +++ b/core/src/com/galvarez/ttw/model/RevoltSystem.java @@ -78,6 +78,11 @@ public RevoltSystem(GameMap gameMap, SessionSettings settings, OverworldScreen s this.screen = screen; } + @Override + public String getType() { + return "Revolt"; + } + @Override protected void initialize() { super.initialize(); @@ -108,39 +113,37 @@ public int getInstabilityPercent(Entity empire) { return (int) (((float) missingStability / (float) totalStability) * 100f); } - @Override - public void execute(Entity empire) { - checkRevolt(empire); - } - /** * Cities revolt when the source power is above its stability. The higher it * is the higher chance it will revolt. */ - private void checkRevolt(Entity empire) { + @Override + public boolean execute(Entity empire) { int instability = getInstabilityPercent(empire); - if (instability > 0) { - InfluenceSource source = sources.get(empire); - // revolt happens, select the tile! - Optional tile = source.influencedTiles.stream() // - .filter(p -> isValidRevoltTile(empire, p, instability)) // - .map(p -> map.getInfluenceAt(p)) // - .min(comparingInt(Influence::getSecondInfluenceDiff)); - - if (tile.isPresent()) { - updateEmpireAfterRevolt(empire, instability, source); - - createRevoltingEmpire(empire, instability, tile.get()); - } else if (instability > 50) { - updateEmpireAfterRevolt(empire, instability, source); - - log.warn("Found no tile to revolt for {} with instability at {}%, decrease power to {}", - empire.getComponent(Name.class), instability, source.power()); - if (!ai.has(empire)) - notifications.addNotification(() -> screen.select(empire, false), null, Type.REVOLT, - "Instability decrease %s power to %s!", empire.getComponent(Description.class), source.power()); - } + if (instability <= 0) + return false; + + InfluenceSource source = sources.get(empire); + // revolt happens, select the tile! + Optional tile = source.influencedTiles.stream() // + .filter(p -> isValidRevoltTile(empire, p, instability)) // + .map(p -> map.getInfluenceAt(p)) // + .min(comparingInt(Influence::getSecondInfluenceDiff)); + + if (tile.isPresent()) { + updateEmpireAfterRevolt(empire, instability, source); + + createRevoltingEmpire(empire, instability, tile.get()); + } else if (instability > 50) { + updateEmpireAfterRevolt(empire, instability, source); + + log.warn("Found no tile to revolt for {} with instability at {}%, decrease power to {}", + empire.getComponent(Name.class), instability, source.power()); + if (!ai.has(empire)) + notifications.addNotification(() -> screen.select(empire, false), null, Type.REVOLT, + "Instability decrease %s power to %s!", empire.getComponent(Description.class), source.power()); } + return true; } private void updateEmpireAfterRevolt(Entity empire, int instability, InfluenceSource source) { diff --git a/core/src/com/galvarez/ttw/model/components/EventsCount.java b/core/src/com/galvarez/ttw/model/components/EventsCount.java index 4b9ee50..6006d29 100644 --- a/core/src/com/galvarez/ttw/model/components/EventsCount.java +++ b/core/src/com/galvarez/ttw/model/components/EventsCount.java @@ -8,6 +8,10 @@ public class EventsCount extends Component { public final ObjectIntMap scores = new ObjectIntMap<>(); + public final ObjectIntMap increment = new ObjectIntMap<>(); + + public final ObjectIntMap display = new ObjectIntMap<>(); + public EventsCount() { } diff --git a/core/src/com/galvarez/ttw/screens/overworld/MenuBuilder.java b/core/src/com/galvarez/ttw/screens/overworld/MenuBuilder.java index 10951f3..47dc17b 100644 --- a/core/src/com/galvarez/ttw/screens/overworld/MenuBuilder.java +++ b/core/src/com/galvarez/ttw/screens/overworld/MenuBuilder.java @@ -2,6 +2,7 @@ import static com.galvarez.ttw.utils.Colors.markup; import static java.lang.Math.min; +import static java.lang.String.format; import java.util.List; @@ -17,12 +18,14 @@ import com.badlogic.gdx.scenes.scene2d.utils.Align; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.utils.IntIntMap; +import com.badlogic.gdx.utils.ObjectIntMap.Entry; import com.galvarez.ttw.model.DiplomaticSystem; import com.galvarez.ttw.model.DiplomaticSystem.Action; +import com.galvarez.ttw.model.EventsSystem.EventHandler; import com.galvarez.ttw.model.InfluenceSystem; import com.galvarez.ttw.model.components.ArmyCommand; import com.galvarez.ttw.model.components.Diplomacy; -import com.galvarez.ttw.model.components.Discoveries; +import com.galvarez.ttw.model.components.EventsCount; import com.galvarez.ttw.model.components.InfluenceSource; import com.galvarez.ttw.model.components.Score; import com.galvarez.ttw.model.data.Empire; @@ -51,6 +54,8 @@ public class MenuBuilder { private final FramedMenu selectionMenu; + private final FramedMenu eventsMenu; + private FramedMenu actionMenu, mapMenu; private final World world; @@ -77,6 +82,7 @@ public MenuBuilder(Stage stage, World world, GameMap map, OverworldScreen screen indicationMenu = new FramedMenu(skin, 512, 512); empireMenu = new FramedMenu(skin, 256, 256).nbColumns(1); selectionMenu = new FramedMenu(skin, 256, 512); + eventsMenu = new FramedMenu(skin, 256, 1024); notifMenu = new FramedMenu(skin, 400, 512); } @@ -128,7 +134,7 @@ public void buildIndicationMenu() { List indications = screen.getIndications(); if (indications != null && !indications.isEmpty()) { // set width before for better layout - indicationMenu.setWidth(stage.getWidth() - (turnMenu.getWidth() + MENU_PADDING * 3)); + indicationMenu.setWidth(stage.getWidth() - (turnMenu.getWidth() + eventsMenu.getWidth() + MENU_PADDING * 3)); for (String i : indications) indicationMenu.addLabel(i); @@ -151,7 +157,6 @@ public void buildEmpireMenu() { + ")", screen::armiesMenu); // here present a sub-menu to see current discovery and be able to change it - Discoveries discoveries = screen.player.getComponent(Discoveries.class); empireMenu.addButton("Discoveries", screen::discoveryMenu); // here present a new screen to choose policies @@ -270,6 +275,19 @@ private void displayDiplomaticActionMenu(FramedMenu parent, Diplomacy diplo, Ent } } + public void buildEventsMenu() { + eventsMenu.clear(); + + EventsCount events = screen.player.getComponent(EventsCount.class); + if (events != null) { + eventsMenu.addLabel("Possible events in " + screen.player.getComponent(Name.class)); + for (Entry evt : events.display) + eventsMenu.addLabel(format(" %s: %d (+%d)", evt.key.getType(), evt.value, events.increment.get(evt.key, 0))); + + eventsMenu.addToStage(stage, stage.getWidth() - 256, stage.getHeight() - MENU_PADDING, false); + } + } + public void buildNotificationMenu() { List notifs = notifications.getNotifications(); notifMenu.clear(); diff --git a/core/src/com/galvarez/ttw/screens/overworld/controls/InputManager.java b/core/src/com/galvarez/ttw/screens/overworld/controls/InputManager.java index 134fdd4..dd2de54 100644 --- a/core/src/com/galvarez/ttw/screens/overworld/controls/InputManager.java +++ b/core/src/com/galvarez/ttw/screens/overworld/controls/InputManager.java @@ -77,6 +77,7 @@ public void reloadMenus() { menuBuilder.buildIndicationMenu(); menuBuilder.buildEmpireMenu(); menuBuilder.buildNotificationMenu(); + menuBuilder.buildEventsMenu(); if (screen.selectedTile != null) menuBuilder.buildSelectionMenu(screen.selectedTile, selectedEntity);