/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.petah.spring.bai.tasks.plan; import com.springrts.ai.oo.AIFloat3; import java.util.LinkedList; import java.util.List; import org.petah.common.option.Option; import org.petah.common.option.OptionsManager; import org.petah.spring.bai.GlobalOptions; 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.util.CommandUtil; import org.petah.spring.bai.util.MapUtil; /** * * @author Petah */ public class PlanCommands { // Options private static Option<Integer> blockMaxAttempts = OptionsManager.getOption( new Option<Integer>("PlanCommands.blockMaxAttempts", 20)); private static Option<Integer> blockJiggleSize = OptionsManager.getOption( new Option<Integer>("PlanCommands.blockMaxAttempts", 300)); public static void markBuilding(AIDelegate aiDelegate, CachedUnitDef def, AIFloat3 pos) { aiDelegate.getCallback().getMap().getDrawer().addPoint(pos, def.getHumanName()); } public static void outlineBuilding(AIDelegate aiDelegate, CachedUnitDef def, AIFloat3 pos) { AIFloat3 from, to; int width = MapUtil.mapToTerrain(def.getXSize()); int height = MapUtil.mapToTerrain(def.getZSize()); from = new AIFloat3(pos.x - width / 2, 0, pos.z - height / 2); to = new AIFloat3(pos.x + width / 2, 0, pos.z - height / 2); aiDelegate.getCallback().getMap().getDrawer().addLine(from, to); from = new AIFloat3(pos.x + width / 2, 0, pos.z - height / 2); to = new AIFloat3(pos.x + width / 2, 0, pos.z + height / 2); aiDelegate.getCallback().getMap().getDrawer().addLine(from, to); from = new AIFloat3(pos.x + width / 2, 0, pos.z + height / 2); to = new AIFloat3(pos.x - width / 2, 0, pos.z + height / 2); aiDelegate.getCallback().getMap().getDrawer().addLine(from, to); from = new AIFloat3(pos.x - width / 2, 0, pos.z + height / 2); to = new AIFloat3(pos.x - width / 2, 0, pos.z - height / 2); aiDelegate.getCallback().getMap().getDrawer().addLine(from, to); } public static List<AIFloat3> getBlock(AIDelegate aiDelegate, CachedUnitDef building, AIFloat3 pos, int xSize, int zSize) { return getBlock(aiDelegate, building, pos, xSize, zSize, 0); } public static List<AIFloat3> getBlock(AIDelegate aiDelegate, CachedUnitDef building, AIFloat3 pos, int xSize, int zSize, int facing) { List<AIFloat3> list = new LinkedList<AIFloat3>(); AIFloat3 currentPos = new AIFloat3(pos); int count = 0; int breakWhile = blockMaxAttempts.getValue(); while (count < xSize * zSize && breakWhile > 0) { boolean breakFor = false; for (int z = 0; z < zSize && !breakFor; z++) { for (int x = 0; x < xSize && !breakFor; x++) { if (!aiDelegate.isPossibleToBuildAt(building, currentPos, facing)) { currentPos = new AIFloat3((float) (pos.x + Math.random() * blockJiggleSize.getValue()), 0, (float) (pos.z + Math.random() * blockJiggleSize.getValue())); list.clear(); count = 0; breakWhile--; breakFor = true; break; } count++; list.add(new AIFloat3(currentPos)); if (GlobalOptions.isDebug()) { outlineBuilding(aiDelegate, building, currentPos); } if (count >= xSize * zSize) { breakFor = true; break; } currentPos.x += MapUtil.mapToTerrain(building.getXSize()); } currentPos.x -= MapUtil.mapToTerrain(building.getXSize()) * xSize; currentPos.z += MapUtil.mapToTerrain(building.getZSize()); } } return list; } public static boolean blockQueue(AIDelegate aiDelegate, CachedUnit builder, CachedUnitDef building, AIFloat3 pos, int xSize, int zSize) { return blockQueue(aiDelegate, builder, building, pos, xSize, zSize, 0); } public static boolean blockQueue(AIDelegate aiDelegate, CachedUnit builder, CachedUnitDef building, AIFloat3 pos, int xSize, int zSize, int facing) { List<AIFloat3> list = getBlock(aiDelegate, building, pos, xSize, zSize, facing); if (list.size() > 0) { for (AIFloat3 buildPos : list) { if (GlobalOptions.isDebug()) { markBuilding(aiDelegate, building, buildPos); } builder.build(building.getUnitDef(), buildPos, facing, true); } return true; } return false; } }