Skip to content

Commit

Permalink
Pass discovery system through events (and thus happen every turn until
Browse files Browse the repository at this point in the history
other events compete). Follow ideas from #47
  • Loading branch information
guillaume-alvarez committed Oct 10, 2015
1 parent f0fd259 commit 8068884
Showing 8 changed files with 166 additions and 85 deletions.
4 changes: 3 additions & 1 deletion core/src/com/galvarez/ttw/EntityFactory.java
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import com.galvarez.ttw.model.components.Destination;
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.Policies;
import com.galvarez.ttw.model.components.Score;
@@ -66,7 +67,8 @@ public static Entity createEmpire(World world, int x, int y, String name, Empire
EntityEdit edit = e.edit();

ArmyCommand command = new ArmyCommand();
edit.add(empire).add(new Discoveries()).add(new Policies()).add(new Diplomacy()).add(command).add(new Score());
edit.add(empire).add(new EventsCount()).add(new Discoveries()).add(new Policies()).add(new Diplomacy())
.add(command).add(new Score());

Sprite sprite = new Sprite();
sprite.name = "cylinderwide";
153 changes: 75 additions & 78 deletions core/src/com/galvarez/ttw/model/DiscoverySystem.java
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@
import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.ObjectFloatMap;
import com.galvarez.ttw.EntityFactory;
import com.galvarez.ttw.model.EventsSystem.EventHandler;
import com.galvarez.ttw.model.components.AIControlled;
import com.galvarez.ttw.model.components.Diplomacy;
import com.galvarez.ttw.model.components.Discoveries;
@@ -58,13 +59,10 @@
* @author Guillaume Alvarez
*/
@Wire
public final class DiscoverySystem extends EntitySystem {
public final class DiscoverySystem extends EntitySystem implements EventHandler {

private static final Logger log = LoggerFactory.getLogger(DiscoverySystem.class);

/** This value permits to display values as percentages. */
private static final int DISCOVERY_THRESHOLD = 100;

/** Increase to speed progress up. */
private static final int PROGRESS_PER_TILE = 1;

@@ -132,6 +130,8 @@ protected void initialize() {
if (b.previous != null && !buildings.containsKey(b.previous))
log.warn("Cannot find previous {} for building {}", b.previous, b);
}

world.getSystem(EventsSystem.class).addEventType(this);
}

private ObjectFloatMap<Faction> getFactionsScores(Discovery discovery) {
@@ -157,84 +157,11 @@ protected void inserted(Entity e) {
super.inserted(e);
Discoveries d = empires.get(e);
d.nextPossible = possibleDiscoveries(e, d);
d.progress = DISCOVERY_THRESHOLD;
}

@Override
protected void processEntities(ImmutableBag<Entity> entities) {
for (Entity entity : entities) {
Discoveries discovery = empires.get(entity);
if (discovery.last != null) {
if (progressNext(discovery, influences.get(entity)))
discoverNext(entity, discovery);
else
discovery.nextPossible = null;
} else
discoverNext(entity, discovery);
}
}

private boolean progressNext(Discoveries discovery, InfluenceSource influence) {
int progress = discovery.progressPerTurn;
Set<Terrain> terrains = discovery.last.target.terrains;
if (terrains != null && !terrains.isEmpty()) {
for (MapPosition pos : influence.influencedTiles) {
if (terrains.contains(map.getTerrainAt(pos)))
progress += PROGRESS_PER_TILE;
}
}
discovery.progress += progress;
return discovery.progress >= DISCOVERY_THRESHOLD;
}

private void discoverNext(Entity empire, Discoveries discovery) {
discovery.nextPossible = possibleDiscoveries(empire, discovery);

if (!ai.has(empire) && !discovery.nextPossible.isEmpty()) {
Research last = discovery.last;
notifications.addNotification(screen::askDiscovery, () -> discovery.last != last, Type.DISCOVERY,
"We can make a new discovery!");
}
}

/** Called when the next discovery is chosen. */
public void discoverNew(Entity empire, Discoveries discovery, Research research) {
Discovery target = research.target;
log.info("{} discovered {} from {}.", empire.getComponent(Name.class), target, research.previous);
discovery.done.add(target);
discovery.progress = 0;
discovery.nextPossible.clear();

if (!ai.has(empire)) {
Set<Policy> policies = PoliciesSystem.getPolicies(target);
if (policies != null) {
for (Policy policy : policies)
notifications
.addNotification(screen::policiesMenu, null, Type.DISCOVERY, "New %s policy: %s", policy, target);
}
}

// Once an empire made a discovery, none other can research it. Those
// already researching it can continue. It makes sure starting discoveries
// are not found only by a single empire.
if (!target.previous.isEmpty())
toDiscover.remove(target.name);

// remove last discovery 2x bonus (to keep only the basic effect)
if (discovery.last != null)
effects.apply(discovery.last.target.effects, empire, true);
discovery.last = research;

// apply new discovery
effects.apply(target.effects, empire, false);
// ... and bonus time until next discovery!
effects.apply(target.effects, empire, false);

// may be some 'special discovery'
special.apply(empire, target, discovery);

MapPosition pos = empire.getComponent(MapPosition.class);
EntityFactory.createFadingTileLabel(world, target.name, empire.getComponent(Empire.class).color, pos.x, pos.y, 3f);
// progress toward next discovery is triggered by EventsSystem
}

/**
@@ -356,4 +283,74 @@ public void copyDiscoveries(Entity from, Entity to) {
}
}

@Override
public int getProgress(Entity e) {
Discoveries discovery = empires.get(e);
InfluenceSource influence = influences.get(e);

int progress = discovery.progressPerTurn;
Set<Terrain> terrains = discovery.last != null ? discovery.last.target.terrains : null;
if (terrains != null && !terrains.isEmpty()) {
for (MapPosition pos : influence.influencedTiles) {
if (terrains.contains(map.getTerrainAt(pos)))
progress += PROGRESS_PER_TILE;
}
}
return progress;
}

@Override
public void execute(Entity e) {
discoverNext(e, empires.get(e));
}

private void discoverNext(Entity empire, Discoveries discovery) {
discovery.nextPossible = possibleDiscoveries(empire, discovery);

if (!ai.has(empire) && !discovery.nextPossible.isEmpty()) {
Research last = discovery.last;
notifications.addNotification(screen::askDiscovery, () -> discovery.last != last, Type.DISCOVERY,
"We can make a new discovery!");
}
}

/** Called when the next discovery is chosen. */
public void discoverNew(Entity empire, Discoveries discovery, Research research) {
Discovery target = research.target;
log.info("{} discovered {} from {}.", empire.getComponent(Name.class), target, research.previous);
discovery.done.add(target);
discovery.nextPossible.clear();

if (!ai.has(empire)) {
Set<Policy> policies = PoliciesSystem.getPolicies(target);
if (policies != null) {
for (Policy policy : policies)
notifications
.addNotification(screen::policiesMenu, null, Type.DISCOVERY, "New %s policy: %s", policy, target);
}
}

// Once an empire made a discovery, none other can research it. Those
// already researching it can continue. It makes sure starting discoveries
// are not found only by a single empire.
if (!target.previous.isEmpty())
toDiscover.remove(target.name);

// remove last discovery 2x bonus (to keep only the basic effect)
if (discovery.last != null)
effects.apply(discovery.last.target.effects, empire, true);
discovery.last = research;

// apply new discovery
effects.apply(target.effects, empire, false);
// ... and bonus time until next discovery!
effects.apply(target.effects, empire, false);

// may be some 'special discovery'
special.apply(empire, target, discovery);

MapPosition pos = empire.getComponent(MapPosition.class);
EntityFactory.createFadingTileLabel(world, target.name, empire.getComponent(Empire.class).color, pos.x, pos.y, 3f);
}

}
67 changes: 67 additions & 0 deletions core/src/com/galvarez/ttw/model/EventsSystem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.galvarez.ttw.model;

import java.util.ArrayList;
import java.util.List;

import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.EntitySystem;
import com.artemis.annotations.Wire;
import com.artemis.utils.ImmutableBag;
import com.galvarez.ttw.model.components.EventsCount;

@Wire
public final class EventsSystem extends EntitySystem {

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

}

private ComponentMapper<EventsCount> counts;

private final List<EventHandler> types = new ArrayList<>();

public EventsSystem() {
super(Aspect.getAspectForAll(EventsCount.class));
}

public void addEventType(EventHandler type) {
types.add(type);
}

@Override
protected void inserted(Entity e) {
super.inserted(e);
for (EventHandler type : types)
counts.get(e).scores.put(type, 0);
}

@Override
protected void processEntities(ImmutableBag<Entity> entities) {
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;
}
}
if (selected != null) {
selected.execute(e);
// also reset score
count.scores.put(selected, 0);
}
}
}
}
2 changes: 0 additions & 2 deletions core/src/com/galvarez/ttw/model/components/Discoveries.java
Original file line number Diff line number Diff line change
@@ -20,8 +20,6 @@ public final class Discoveries extends Component {

public Research last;

public int progress = 0;

public Discoveries() {
}

14 changes: 14 additions & 0 deletions core/src/com/galvarez/ttw/model/components/EventsCount.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.galvarez.ttw.model.components;

import com.artemis.Component;
import com.badlogic.gdx.utils.ObjectIntMap;
import com.galvarez.ttw.model.EventsSystem.EventHandler;

public class EventsCount extends Component {

public final ObjectIntMap<EventHandler> scores = new ObjectIntMap<>();

public EventsCount() {
}

}
3 changes: 1 addition & 2 deletions core/src/com/galvarez/ttw/screens/DiscoveryMenuScreen.java
Original file line number Diff line number Diff line change
@@ -73,8 +73,7 @@ protected void initMenu() {
terrains.addToStage(stage, 30, lastDiscovery.getY() - 30, false);

discoveryChoices.clear();
discoveryChoices.addButton("Progress toward next discovery: " + empire.progress + "% (+" + empire.progressPerTurn
+ "%/turn)", gameScreen::askDiscovery);
discoveryChoices.addButton("Next discovery?", gameScreen::askDiscovery);
discoveryChoices.addLabel(" ");
discoveryChoices.addToStage(stage, 30, terrains.getY() - 30, false);
}
3 changes: 1 addition & 2 deletions core/src/com/galvarez/ttw/screens/overworld/MenuBuilder.java
Original file line number Diff line number Diff line change
@@ -158,8 +158,7 @@ public void buildEmpireMenu() {

// here present a sub-menu to see current discovery and be able to change it
Discoveries discoveries = screen.player.getComponent(Discoveries.class);
empireMenu.addButton("Discovery " + (discoveries != null ? "(" + discoveries.progress + "%)" : "(NONE)"),
screen::discoveryMenu);
empireMenu.addButton("Discoveries", screen::discoveryMenu);

// here present a new screen to choose policies
int instability = screen.revoltSystem.getInstabilityPercent(screen.player);
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@
import com.galvarez.ttw.model.DisasterSystem;
import com.galvarez.ttw.model.DiscoverySystem;
import com.galvarez.ttw.model.EffectsSystem;
import com.galvarez.ttw.model.EventsSystem;
import com.galvarez.ttw.model.InfluenceSystem;
import com.galvarez.ttw.model.PoliciesSystem;
import com.galvarez.ttw.model.RevoltSystem;
@@ -90,6 +91,8 @@ public final class OverworldScreen extends AbstractScreen {

private final EffectsSystem effectsSystem;

private final EventsSystem eventsSystem;

private final DiscoverySystem discoverySystem;

private final BuildingsSystem buildingsSystem;
@@ -174,6 +177,7 @@ public OverworldScreen(ThingsThatWereGame game, SpriteBatch batch, World world,

iconsSystem = world.setSystem(new IconsSystem(), true);
notificationsSystem = world.setSystem(new NotificationsSystem(), true);
eventsSystem = world.setSystem(new EventsSystem(), true);
effectsSystem = world.setSystem(new EffectsSystem(), true);
world.setSystem(new SpecialDiscoveriesSystem(this), true);
discoverySystem = world.setSystem(new DiscoverySystem(settings, map, this), true);
@@ -383,6 +387,7 @@ private void processTurn() {
revoltSystem.process();
disasterSystem.process();
scoreSystem.process();
eventsSystem.process();

world.setDelta(0);
world.process();

0 comments on commit 8068884

Please sign in to comment.