package de.zelosfan.timedstrategy.ai;
import com.badlogic.gdx.utils.ObjectMap;
import de.zelosfan.framework.Algorithms.Pathable;
import de.zelosfan.framework.Util.RandomUtil;
import de.zelosfan.timedstrategy.Game;
import de.zelosfan.timedstrategy.Main;
import de.zelosfan.timedstrategy.Repository;
import de.zelosfan.timedstrategy.algorithms.AStarCus;
import de.zelosfan.timedstrategy.entity.Entity;
import de.zelosfan.timedstrategy.entity.Entitytyp;
import de.zelosfan.timedstrategy.world.Building;
import de.zelosfan.timedstrategy.world.Tile;
import de.zelosfan.timedstrategy.world.Tiletyp;
import de.zelosfan.timedstrategy.world.buildingtypes.BuildingFactory;
import de.zelosfan.timedstrategy.world.buildingtypes.BuildingHeadquarter;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* User: Simon "Zelosfan" Herfert
* Date: 25.08.13
* Time: 12:26
*/
public class Ai {
//Constants
public static int COVER_WEALTH = 10;
public static int WAYCOST_COST = 1;
public static int BUILDING_WEALTH_MULTIPLIER = 4;
public static int HIGHEST_BUILDING_WEALTH_LEVEL = 5;
public static int MAX_BUILDING_WEALTH = BUILDING_WEALTH_MULTIPLIER * 2 * HIGHEST_BUILDING_WEALTH_LEVEL;
//#########
public static ObjectMap<Entity, Entity> targetedEntities = new ObjectMap<>();
public static ObjectMap<Entity, Tile> targetedTiles = new ObjectMap<>();
public static void buildUnit(Building building) {
if (building.tiletyp instanceof BuildingFactory) {
Entitytyp entitytyp = Repository.entitytypObjectMap.values().toArray().get((RandomUtil.getNanoRandom().nextInt(Repository.entitytypObjectMap.size)));
if (Game.redTeam.moneydeduct(entitytyp.cost)) {
building.obj = entitytyp;
}
}
}
public static void checkRadius(Entity entity) {
if (entity.target != null) {
if (entity.target.equals(entity.tile)) {
entity.target = null;
if (targetedTiles.containsKey(entity)) {
targetedTiles.remove(entity);
} else {
Entity targeted = targetedEntities.get(entity);
if (targeted.health > 0 && (Main.game.calculateFightCost(entity, entity.tile, targeted) <= -5 || Game.redTeam.hq.getPositionV2().dst(targeted.tile.getPositionV2()) < 14)) {
entity.target = (Tile) targeted.waypoints.getLast();
} else {
targetedEntities.remove(entity);
}
}
}
}
if (Game.redTeam.hq.entity == null && !targetedTiles.containsValue(Game.redTeam.hq, true)) {
entity.target = Game.redTeam.hq;
targetedTiles.put(entity, Game.redTeam.hq);
}
if (entity.target == null) {
ArrayList<Pathable> avaible = AStarCus.expandPath(Main.game.world.tiles, entity.tile, entity.entitytyp.speed * 3);
for (Pathable pathable: avaible) {
Tile tile = (Tile) pathable;
if (tile.entity != null) {
Entity entity1 = tile.entity;
if (!tile.entity.team.equals(entity.team)) {
if (Main.game.calculateFightCost(entity, entity.tile, entity1) <= -5 || Game.redTeam.hq.getPositionV2().dst(entity1.tile.getPositionV2()) < 14) {
if (targetedEntities.containsValue(entity1, true)) {
if (Main.game.calculateFightCost(targetedEntities.findKey(entity1, true), entity.tile, entity1) > Main.game.calculateFightCost(entity, entity.tile, entity1)) {
targetedEntities.findKey(entity1, true).target = null;
entity.target = entity1.tile;
targetedEntities.put(entity, entity1);
}
} else {
entity.target = entity1.tile;
targetedEntities.put(entity, entity1);
}
}
}
}
if (tile instanceof Building && entity.target == null) {
Building building = (Building) tile;
if (building.team == null && !(building.tiletyp instanceof BuildingHeadquarter)) {
boolean allowed = false;
if (building.entity == null) {
allowed = true;
} else {
if (Main.game.calculateFightCost(entity, entity.tile, building.entity) <= -5) {
allowed = true;
}
}
if (allowed) {
if (targetedTiles.containsValue(building, true)) {
if (worth(targetedTiles.findKey(building, true)) > worth(entity)) {
targetedTiles.findKey(building, true).target = null;
entity.target = building;
targetedTiles.put(entity, building);
} else {
entity.target = building;
targetedTiles.put(entity, building);
}
} else {
entity.target = building;
targetedTiles.put(entity, building);
}
}
}
}
}
}
}
public static float worth(Entity entity) {
return entity.entitytyp.cost * entity.health;
}
public static LinkedList<Pathable> getAiPath(Tile[][] nodes, Entity entity, Tile start, Tile goal) {
ArrayList<Pathable> closedList = new ArrayList<>();
LinkedList<Pathable> openList = new LinkedList<>();
ObjectMap<Pathable, Pathable> came_from = new ObjectMap<>();
ObjectMap<Pathable, Integer> g_score = new ObjectMap<>(nodes.length + nodes[0].length);
ObjectMap<Pathable, Integer> f_score = new ObjectMap<>(nodes.length + nodes[0].length);
g_score.put(start, 0);
f_score.put(start, g_score.get(start));
openList.add(start);
while (openList.size() != 0) {
Pathable current = openList.getFirst();
int lowestscore = f_score.get(openList.getFirst());
for (Pathable node : openList) {
if (f_score.get(node) < lowestscore) {
current = node;
lowestscore = f_score.get(node);
}
}
if (current.equals(goal)) {
return AStarCus.reconstructPath(came_from, goal);
}
openList.remove(current);
closedList.add(current);
for (int i = -1; i <= 1; i++) {
for (int l = -1; l <= 1; l++) {
if (current.getPositionV2().x + i < nodes.length && current.getPositionV2().y + l < nodes[0].length && current.getPositionV2().x + i >= 0 && current.getPositionV2().y + l >= 0) {
if (current.isWalkable(current.equals(start))) {
if (Math.abs(i) != Math.abs(l)) {
Tile neighbor = nodes[((int) current.getPositionV2().x + i)][((int) current.getPositionV2().y + l)];
int additionalResistance = Main.game.world.getIntelligentWaycost(neighbor, entity);
int tentative_g_score = g_score.get(current) + additionalResistance;
if (closedList.contains(neighbor) && tentative_g_score >= g_score.get(neighbor)) {
continue;
}
if (!openList.contains(neighbor) || tentative_g_score < g_score.get(neighbor)) {
came_from.put(neighbor, current);
g_score.put(neighbor, tentative_g_score);
f_score.put(neighbor, g_score.get(neighbor));
if (!openList.contains(neighbor)) {
openList.add(neighbor);
}
}
}
} else {
closedList.add(current);
}
}
}
}
}
return null;
}
}