protected float getRangePenalty(unitScript unit, float distance) { RangedWeapon weapon; float rangedPenalty = 0.0f; try { weapon = (RangedWeapon)unit.getCurrentWeapon(); } catch (InvalidCastException e) { return(distance > unit.getMovementDistance() + 2 ? 0 : 100); } if (weapon.minRange > distance) { rangedPenalty = weapon.minRange - distance; } else if (weapon.maxRange < distance) { rangedPenalty = distance - weapon.maxRange; } else { rangedPenalty = 0; } return(rangedPenalty); }
public void selectUnit(unitScript unit) { GUIController cont = gui.GetComponent <GUIController>(); DeselectCurrent(); selected = unit.gameObject; cont.setCharacterPanelVisibility(true, unit); if (unit.getOwner() == 0) { unit.SendMessage("select"); // IF unit has not moved if (unit != null && !unit.hasMoved()) { // Allow them to if (unit.getOwner() == 0 && unit.hasMoved() == false) { GridItem pos = selected.GetComponent <GridItem>(); pathFinder.getMovementPaths(pos.getPos(), unit.getMovementDistance(), true); //map.toggleHighlight(true, Color.cyan, pos.getX(), pos.getY(), unit.getMovementDistance()); } } } }
void fallBack(unitScript unit) { pathFinder.getMovementPaths(unit.GetComponent <GridItem>().getPos(), unit.getMovementDistance(), false); //run away from enemy //Calculate vector //if has shield switch to it and deploy if (swapTo(unit, WeaponType.shield)) { activateShield(unit, unit.GetComponent <GridItem>()); } }
void testMove(unitScript unit) { pathFinder.getMovementPaths(unit.GetComponent <GridItem>().getPos(), unit.getMovementDistance(), false); var locations = pathFinder.getReachableLocations(); bool f = true; foreach (Vector2 location in locations) { float chance = Random.Range(0.0f, 1.0f); if (!f && chance > 0.5) { if (!unit.hasMoved()) { Vector2[] path = pathFinder.drawPath(location, false); unit.setPath(path); } } if (f) { f = !f; } } }
void hunt(unitScript unit) { pathFinder.getMovementPaths(unit.GetComponent <GridItem>().getPos(), 100, false); //var locations = pathFinder.getReachableLocations(); if (unit.getCurrentWeapon().type == WeaponType.melee) { if (!unit.GetComponent <AIUnitController>().moved) { //get position of all enemies unitScript[] units = getAllUnits(); List <unitScript> targetList = new List <unitScript>(units); //Pick target unitScript target = targetPrioritisation(unit, targetList); if (target == null) { unit.GetComponent <AIUnitController>().moved = true; unit.GetComponent <AIUnitController>().attacked = true; return; } unit.GetComponent <AIUnitController>().moved = true; //Get the positions one short of target var oneShort = target.GetComponent <GridItem>().getPos() - unit.GetComponent <GridItem>().getPos(); var targetPosXclose = target.GetComponent <GridItem>().getPos() - new Vector2(Mathf.Sign(oneShort.x), 0); var targetPosYclose = target.GetComponent <GridItem>().getPos() - new Vector2(0, Mathf.Sign(oneShort.y)); var targetPosXfar = target.GetComponent <GridItem>().getPos() + new Vector2(Mathf.Sign(oneShort.x), 0); var targetPosYfar = target.GetComponent <GridItem>().getPos() + new Vector2(0, Mathf.Sign(oneShort.y)); List <Vector2[]> paths = new List <Vector2[]>(); paths.Add(pathFinder.drawPath(targetPosXclose, false, true)); paths.Add(pathFinder.drawPath(targetPosYclose, false, true)); paths.Add(pathFinder.drawPath(targetPosXfar, false, true)); paths.Add(pathFinder.drawPath(targetPosYfar, false, true)); //For each potential places try to move there foreach (var path in paths) { if (path != null) { //if the path is not null attack Vector2[] newPath = new Vector2[Mathf.Min(path.Length, unit.getMovementDistance())]; for (int i = 0; i < newPath.Length; i++) { newPath[i] = path[i]; } unit.setPath(newPath); break; } } unit.GetComponent <AIUnitController>().moved = true; } else if (unit.canEndTurn()) { //Attack target MeleeAttack(unit, unit.GetComponent <AIUnitController>().target); unit.GetComponent <AIUnitController>().attacked = true; } } else if (unit.getCurrentWeapon().type == WeaponType.ranged) { if (!unit.GetComponent <AIUnitController>().moved) { Vector2 initialPosition = unit.GetComponent <GridItem>().getPos(); //Initialise heursticmap var locations = pathFinder.getReachableLocations(); Dictionary <Vector2, float> heuristicMap = new Dictionary <Vector2, float>(); RangedWeapon currentGun = (RangedWeapon)unit.getCurrentWeapon(); var enemyUnits = getEnemyUnits(); foreach (Vector2 pos in locations.Where(p => Mathf.Abs(p.x - unit.GetComponent <GridItem>().getPos().x) + Mathf.Abs(p.y - unit.GetComponent <GridItem>().getPos().y) < unit.getMovementDistance())) { unit.setPosition((int)pos.x, (int)pos.y); float h = 0.0f; //Get all cover tiles around the current var neighboringTiles = this.map.getAllNeighbours(pos).Where(p => this.map.getTileData(p).coverValue != 0); //How much will this tile hurt? h += enemyUnits.Where(e => getRangePenalty(e, Vector3.Distance(e.GetComponent <GridItem>().getVectorPostion(), unit.GetComponent <GridItem>().getVectorPostion())) == 0) .Aggregate(0, (subHeuristic, enemy) => subHeuristic - 1); //Add back all values from cover foreach (Vector2 cover in neighboringTiles) { //Direction of cover Vector2 vectorToCover = cover - pos; //If the cover is between me and an enemy then increase heurstic h += enemyUnits .Where( e => // The enemy is not melee or shield e.getCurrentWeapon().type == WeaponType.ranged && //I am within enemy range getRangePenalty(e, Vector3.Distance(e.GetComponent <GridItem>().getVectorPostion(), unit.GetComponent <GridItem>().getVectorPostion())) == 0 && //And cover is between the enemy and myself (Vector2.Angle(e.GetComponent <GridItem>().getPos() - pos, vectorToCover) < 45) ).Aggregate(0, (subHeurstic, e) => subHeurstic + (this.map.getTileData(cover).coverValue + 2)); } // How much damage can I do from this position h += enemyUnits.Select(e => getRangePenalty(unit, Vector3.Distance(e.GetComponent <GridItem>().getVectorPostion(), unit.GetComponent <GridItem>().getVectorPostion())) == 0) .Aggregate(0, (subHeurisitic, e) => subHeurisitic + (e?1:-1));//unit.getCurrentWeapon().damage); heuristicMap[pos] = h; this.map.displayDebugData((int)pos.x, (int)pos.y, h.ToString()); unit.setPosition((int)initialPosition.x, (int)initialPosition.y); } unit.setPosition((int)initialPosition.x, (int)initialPosition.y); //Pick location with highest score Vector2 moveLocation = heuristicMap.Aggregate((l, r) => l.Value >= r.Value ? l : r).Key; print("KEY/Value " + moveLocation + " " + heuristicMap[moveLocation]); //Move there var path = pathFinder.drawPath(moveLocation, false, true); //if the path is not null attack Vector2[] newPath = new Vector2[Mathf.Min(path.Length, unit.getMovementDistance())]; for (int i = 0; i < newPath.Length; i++) { newPath[i] = path[i]; } unit.setPath(newPath); unit.GetComponent <AIUnitController>().moved = true; //If an attack can be made make it } if (unit.canEndTurn()) { //Find best target unitScript target = targetPrioritisation(unit, getEnemyUnits()); if (target == null) { unit.GetComponent <AIUnitController>().attacked = true; return; } //Attack target RangedAttack(unit, unit.GetComponent <AIUnitController>().target); unit.GetComponent <AIUnitController>().attacked = true; } } else if (unit.getCurrentWeapon().type == WeaponType.shield) { if (swapTo(unit, WeaponType.melee)) { print("ready Sword"); } else if (swapTo(unit, WeaponType.ranged)) { print("ready Gun"); } } }