/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.petah.spring.bai.tasks.standard; import com.springrts.ai.oo.AIFloat3; import org.petah.spring.bai.Strategy; import org.petah.spring.bai.cache.CachedUnit; import org.petah.spring.bai.cache.CachedUnitDef; import org.petah.spring.bai.delegate.AIDelegate; import org.petah.spring.bai.delegate.GlobalDelegate; import org.petah.spring.bai.group.UnitGroup; import org.petah.spring.bai.map.metal.MetalSpot; import org.petah.spring.bai.unit.Faction; import org.petah.spring.bai.unit.UnitInfo; import org.petah.spring.bai.unit.UnitType; import org.petah.spring.bai.util.BuilderUtil; import org.petah.spring.bai.util.CommandUtil; /** * * @author Petah */ public class DefaultCommands { public static final float FACTORY_RANDOM_FACTOR = 0.5f; public static final int DEFAULT_FACTORY_DISTANCE = 450; public static final int DEFAULT_SPACING = 10; public static final int DEFAULT_SEARCH_RADIUS = 500; public static final int DEFAULT_T2_FACTORY_SPACING = 8; public static final int DEFAULT_T2_FACTORY_SEARCH_RADIUS = 100; public static final int DEFAULT_METAL_EXTRACTOR_SPACING = 0; // public static final int DEFAULT_METAL_EXTRACTOR_SEARCH_RADIUS = 70; public static final int DEFAULT_ENERGY_DISTANCE = 10; public static final int DEFAULT_ENERGY_SPACING = 6; public static final int DEFAULT_ENERGY_SEARCH_RADIUS = 1000; // TODO: make nanos, scavengers use this, and make mexes redundant (from the closest to the base cetner) public static void findReclaimableBuildings(AIDelegate aiDelegate) { for (CachedUnit building : aiDelegate.getGroupManager().getGroup("Factorys")) { String name = building.getUnitInfo().getName(); if (name.equals("KbotFactory") || name.equals("AircraftFactory") || name.equals("VehicleFactory") || name.equals("ShipFactory")) { aiDelegate.getAIOvermind().addReclaimableUnit(building); } } for (CachedUnit building : aiDelegate.getGroupManager().getGroup("EnergyGenerators")) { String name = building.getUnitInfo().getName(); if (name.equals("Solar") || name.equals("Wind")) { aiDelegate.getAIOvermind().addReclaimableUnit(building); } } } public static void guardFactory(AIDelegate aiDelegate, CachedUnit builder) { if (aiDelegate.getGroupManager().getGroup("Factorys").size() > 0) { builder.guard(aiDelegate.getGroupManager().getGroup("Factorys").getUnit(0).getUnit()); } } public static void queueAdvSolar(AIDelegate aiDelegate, CachedUnit builder) { CachedUnitDef building = getBuildDef("ASolar", builder); builder.build(building.getUnitDef(), getEnergyBuildPos(aiDelegate, builder, building, DEFAULT_ENERGY_SEARCH_RADIUS, DEFAULT_ENERGY_SPACING)); } public static void queueFusion(AIDelegate aiDelegate, CachedUnit builder) { CachedUnitDef building = getBuildDef("Fusion", builder); builder.build(building.getUnitDef(), getEnergyBuildPos(aiDelegate, builder, building, DEFAULT_ENERGY_SEARCH_RADIUS, DEFAULT_ENERGY_SPACING)); } public static void queueNano(AIDelegate aiDelegate, CachedUnit builder) { UnitGroup group = aiDelegate.getGroupManager().getGroup("Factorys"); if (group.size() > 0) { CachedUnitDef nano = getBuildDef("Nano", builder); AIFloat3 pos = aiDelegate.findClosestBuildSite(nano, group.getUnit(0).getPos(), DEFAULT_SEARCH_RADIUS, DEFAULT_SPACING, 0); builder.build(nano.getUnitDef(), pos); } } private static CachedUnitDef getBuildDef(String name, CachedUnit builder) { return GlobalDelegate.getUnitDef(name, Faction.getFaction(builder.getDef())); } public static void queueFactory(AIDelegate aiDelegate, CachedUnit builder) { CachedUnitDef factory; if (aiDelegate.getTeamDelegate().getTeamOvermind().getStrategyAmount(Strategy.Kbot) == 0) { factory = getBuildDef("KbotFactory", builder); aiDelegate.addStrategy(Strategy.Kbot); } else if (aiDelegate.getTeamDelegate().getTeamOvermind().getStrategyAmount(Strategy.Vehicle) == 0) { factory = getBuildDef("VehicleFactory", builder); aiDelegate.addStrategy(Strategy.Vehicle); } else if (aiDelegate.getTeamDelegate().getTeamOvermind().getStrategyAmount(Strategy.Aircraft) == 0) { factory = getBuildDef("AircraftFactory", builder); aiDelegate.addStrategy(Strategy.Aircraft); } else { if (Math.random() < FACTORY_RANDOM_FACTOR) { factory = getBuildDef("KbotFactory", builder); aiDelegate.addStrategy(Strategy.Kbot); } else { factory = getBuildDef("VehicleFactory", builder); aiDelegate.addStrategy(Strategy.Vehicle); } } AIFloat3 pos = BuilderUtil.moveTowardsMapCenter(aiDelegate.getBaseCenter(), DEFAULT_FACTORY_DISTANCE); int facing = CommandUtil.getMapCenterFacing(aiDelegate, builder); // System.err.println("facing: " + facing); pos = aiDelegate.findClosestBuildSite(factory, pos, DEFAULT_SEARCH_RADIUS, DEFAULT_SPACING, facing); builder.build(factory.getUnitDef(), pos, facing); } public static void queueT2Factory(AIDelegate aiDelegate, CachedUnit builder) { CachedUnitDef factory = null; if (builder.getUnitInfo().isType(UnitType.Kbot)) { factory = getBuildDef("AKbotFactory", builder); } else if (builder.getUnitInfo().isType(UnitType.Vehicle)) { factory = getBuildDef("AVehicleFactory", builder); } if (factory != null) { AIFloat3 pos = BuilderUtil.moveTowardsMapCenter(aiDelegate.getBaseCenter(), DEFAULT_FACTORY_DISTANCE); int facing = CommandUtil.getMapCenterFacing(aiDelegate, builder); pos = aiDelegate.findClosestBuildSite(factory, pos, DEFAULT_T2_FACTORY_SEARCH_RADIUS, DEFAULT_T2_FACTORY_SPACING, facing); if (aiDelegate.isPossibleToBuildAt(factory, pos, facing)) { builder.build(factory.getUnitDef(), pos, facing); } } } public static void queueEnergyGenerator(AIDelegate aiDelegate, CachedUnit builder) { CachedUnitDef energyGen = BuilderUtil.getBestT1Energy(Faction.getFaction(builder.getDef())); // AIFloat3 pos = getEnergyBuildPos(aiDelegate, builder, energyGen, DEFAULT_ENERGY_SEARCH_RADIUS, DEFAULT_ENERGY_SPACING); AIFloat3 pos = aiDelegate.findClosestBuildSite(energyGen, builder.getPos(), DEFAULT_ENERGY_SEARCH_RADIUS, DEFAULT_ENERGY_SPACING, 0); builder.build(energyGen.getUnitDef(), pos); } public static boolean queueClosestMetalExtractor(AIDelegate aiDelegate, CachedUnit builder) { CachedUnitDef mexDef; // TODO: improve metal extractor selection if (builder.getUnitInfo().isType(UnitType.Level2)) { mexDef = getBuildDef("AMetalExtractor", builder); } else { mexDef = getBuildDef("MetalExtractor", builder); } return queueClosestMetalExtractor(aiDelegate, builder, mexDef, builder.getPos()); } public static boolean queueClosestMetalExtractor(AIDelegate aiDelegate, CachedUnit builder, CachedUnitDef mexDef, AIFloat3 pos) { for (MetalSpot metalSpot : aiDelegate.getMetalSpotManager().getMetalSpotDistance(pos, aiDelegate.getCachedUnitManager()).values()) { AIFloat3 metalSpotPos = aiDelegate.findClosestBuildSite(mexDef, new AIFloat3(metalSpot.getTerrainX(), 1, metalSpot.getTerrainZ()), GlobalDelegate.getMetalExtractorTerrainRadius(), DEFAULT_METAL_EXTRACTOR_SPACING, 0); builder.build(mexDef.getUnitDef(), metalSpotPos); return true; } return false; } // public static boolean queueClosestMetalExtractor(AIDelegate aiDelegate, CachedUnit builder, CachedUnitDef mexDef, AIFloat3 pos) { // MetalSpot metalSpot = aiDelegate.getTeamDelegate().getMetalMap().findFreeMetalSpot(pos); // if (metalSpot != null) { // AIFloat3 metalSpotPos = aiDelegate.findClosestBuildSite(mexDef, new AIFloat3(metalSpot.getTerrainX(), 1, metalSpot.getTerrainZ()), // CachedMetalMap.getMetalExtractorRadius(), DEFAULT_METAL_EXTRACTOR_SPACING, 0); // builder.queueUnit(mexDef, metalSpotPos); // return true; // } else { // aiDelegate.sendMessage("No avalible metal spots"); // return false; // } // } /** * TODO: get best metal extractor base on the y pos of the metalSpot for under water etc * @param aiDelegate * @param builder * @return */ public static CachedUnitDef getBestMetalExtractor(AIDelegate aiDelegate, MetalSpot metalSpot, CachedUnit builder) { UnitInfo info = builder.getUnitInfo(); if (info.isType(UnitType.Level2)) { if (info.isType(UnitType.Submarine) || info.isType(UnitType.SeaPlane)) { return getBuildDef("AWMetalExtractor", builder); } if (aiDelegate.getResourceManager().isEnergyOver(0.5f, 150) && aiDelegate.getResourceManager().isMetalOver(0.5f, 10) && Faction.getFaction(builder.getDef()) == Faction.Core) { return getBuildDef("ATMetalExtractor", builder); } return getBuildDef("AMetalExtractor", builder); } else { if (info.isType(UnitType.Ship) || info.isType(UnitType.Hovercraft)) { return getBuildDef("WMetalExtractor", builder); } if (aiDelegate.getResourceManager().isEnergyOver(0.5f, 150) && aiDelegate.getResourceManager().isMetalOver(0.5f, 10)) { if (Faction.getFaction(builder.getDef()) == Faction.Arm) { return getBuildDef("CMetalExtractor", builder); } else { return getBuildDef("TMetalExtractor", builder); } } return getBuildDef("MetalExtractor", builder); } } // @Deprecated // public static boolean queueClosestMetalExtractor(AIDelegate aiDelegate, CachedUnit builder) { // CachedUnitDef mex; // UnitInfo info = builder.getUnitInfo(); // if (info.isType(UnitType.Level2)) { // mex = getBuildDef("AMetalExtractor", builder); // } else { // mex = getBuildDef("MetalExtractor", builder); // } // return queueClosestMetalExtractor(aiDelegate, builder, mex, builder.getPos()); // } public static AIFloat3 getEnergyBuildPos(AIDelegate aiDelegate, CachedUnit builder, CachedUnitDef building, int searchRadius, int spacing) { AIFloat3 pos = BuilderUtil.moveAwayFromMapCenter(aiDelegate.getBaseCenter(), DEFAULT_ENERGY_DISTANCE); if (!aiDelegate.isPossibleToBuildAt(building, pos, 0)) { pos = aiDelegate.findClosestBuildSite(building, pos, searchRadius, spacing, 0); } return pos; } public static void queueRadar(AIDelegate aiDelegate, CachedUnit builder) { CachedUnitDef building = getBuildDef("Radar", builder); AIFloat3 pos = aiDelegate.findClosestBuildSite(building, builder.getPos(), DEFAULT_SEARCH_RADIUS, DEFAULT_SPACING, 0); builder.build(building.getUnitDef(), pos); } }