package com.galvarez.ttw.model; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.artemis.Aspect; import com.artemis.ComponentMapper; import com.artemis.Entity; import com.artemis.annotations.Wire; import com.artemis.systems.EntityProcessingSystem; import com.galvarez.ttw.model.components.AIControlled; import com.galvarez.ttw.model.components.Army; import com.galvarez.ttw.model.components.Destination; import com.galvarez.ttw.model.map.GameMap; import com.galvarez.ttw.model.map.MapPosition; import com.galvarez.ttw.rendering.components.Description; import com.galvarez.ttw.screens.overworld.OverworldScreen; /** * Send the army to the tile with smallest difference between ours and second * influence. * * @author Guillaume Alvarez */ @Wire public final class AIArmyMovementSystem extends EntityProcessingSystem { private static final Logger log = LoggerFactory.getLogger(AIArmyMovementSystem.class); private ComponentMapper<Destination> destinations; private ComponentMapper<MapPosition> positions; private ComponentMapper<Army> armies; private ComponentMapper<AIControlled> intelligences; private DestinationSystem destinationSystem; private final OverworldScreen screen; private final GameMap map; @SuppressWarnings("unchecked") public AIArmyMovementSystem(GameMap map, OverworldScreen screen) { super(Aspect.getAspectForAll(AIControlled.class, Army.class)); this.map = map; this.screen = screen; } @Override protected boolean checkProcessing() { return true; } @Override protected void process(Entity e) { Destination dest = destinations.getSafe(e); if (dest == null) return; AIControlled ai = intelligences.get(e); // no need to also check if destination is still influenced by army // controller: worst case is it is recreated at capital if (dest.target == null) { setNewTarget(e, ai); } else { // check we are not stuck MapPosition current = positions.get(e); if (current.equals(ai.lastPosition)) { // are we stuck for 3 turns? if (screen.getTurnNumber() - ai.lastMove > 3) setNewTarget(e, ai); } else { ai.lastMove = screen.getTurnNumber(); ai.lastPosition = current; } } } private void setNewTarget(Entity army, AIControlled ai) { AIControlled empire = intelligences.get(armies.get(army).source); for (int i = 0; i < empire.armiesTargets.size(); i++) { MapPosition pos = empire.armiesTargets.get(i); if (!pos.equals(positions.get(army)) && !map.hasEntity(pos)) { List<MapPosition> path = destinationSystem.computePath(army, pos); if (path != null) { ai.lastMove = screen.getTurnNumber(); ai.lastPosition = positions.get(army); empire.armiesTargets.remove(i); return; } } } log.warn("Cannot find a destination for {}", army.getComponent(Description.class)); } }