예제 #1
0
 protected virtual bool Attack(unitScript unit, unitScript clickedUnit)
 {
     //determine attack type
     if (unit.getCurrentWeapon().type == WeaponType.melee)
     {
         return(MeleeAttack(unit, clickedUnit));
     }
     if (unit.getCurrentWeapon().type == WeaponType.ranged)
     {
         return(RangedAttack(unit, clickedUnit));
     }
     return(false);
 }
예제 #2
0
    protected bool RangedAttack(unitScript unit, unitScript clickedUnit, bool initialAttack = true)
    {
        // Check LoS
        if (!canSee(unit, clickedUnit))
        {
            return(false);
        }

        if (hitShield(unit, clickedUnit))
        {
            return(true);
        }

        //Resolve Attack

        float roll        = UnityEngine.Random.Range(0.0f, 1.0f);
        float chanceToHit = rangedChanceToHit(unit, clickedUnit);

        print(roll + " " + chanceToHit);
        if (roll < chanceToHit)
        {
            clickedUnit.takeDamage(unit.getCurrentWeapon().damage);
        }
        else
        {
            clickedUnit.displayMiss();
        }
        unit.activateAttack();
        if (initialAttack && clickedUnit.getStrikeback() == false)
        {
            bool result;
            if (clickedUnit.getCurrentWeapon().type == WeaponType.melee)
            {
                result = MeleeAttack(clickedUnit, unit, false);
            }
            else if (clickedUnit.getCurrentWeapon().type == WeaponType.ranged)
            {
                result = RangedAttack(clickedUnit, unit, false);
            }
            else
            {
                result = false;
            }
            if (result)
            {
                clickedUnit.useStrikeback();
            }
        }
        return(true);
    }
예제 #3
0
    protected float meleeChanceToHit(unitScript unit, unitScript clickedUnit)
    {
        if (unit.getCurrentWeapon().type == WeaponType.ranged)
        {
            return(0);
        }

        // Check outflank bonus
        int     flankBonus    = 0;  // Flank Check
        Vector2 enemyPosition = clickedUnit.GetComponent <GridItem>().getPos();

        foreach (unitScript u in playerUnitList)
        {
            if (u != null)
            {
                Vector2 unitPosition = u.GetComponent <GridItem>().getPos();
                if (u.getOwner() == controllerID && u != unit && Vector2.Distance(unitPosition, enemyPosition) < 2)
                {
                    flankBonus = 2;
                    print("Flanked Bitches");
                }
            }
        }


        // return chance to hit
        return((5.0f + (unit.getSkill() + flankBonus) - clickedUnit.getSkill()) / 10.0f);
    }
    public void loadWeaponData(unitScript u, bool ally)
    {
        var WeaponPanel = transform.FindChild(ally?"WeaponPanel":"EnemyWeaponPanel");

        WeaponPanel.gameObject.SetActive(true);
        var weapon = u.getCurrentWeapon();

        WeaponPanel.transform.Find("Weapon").GetComponent <Text>().text = weapon.name;
        WeaponPanel.transform.Find("Damage").GetComponent <Text>().text = weapon.damage.ToString();

        var rangedPanel = WeaponPanel.transform.Find("Ranged");

        switch (weapon.type)
        {
        case WeaponType.ranged:
            rangedPanel.gameObject.SetActive(true);
            RangedWeapon current = (RangedWeapon)weapon;

            rangedPanel.Find("ShortRange").GetComponent <Text>().text = current.minRange.ToString();
            rangedPanel.Find("LongRange").GetComponent <Text>().text  = current.maxRange.ToString();

            break;

        default:
            rangedPanel.gameObject.SetActive(false);
            break;
        }
    }
예제 #5
0
    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);
    }
예제 #6
0
    protected bool activateShield(unitScript unit, GridItem position)
    {
        if (!(unit.getCurrentWeapon().type == WeaponType.shield))
        {
            return(false);
        }
        Shield currentShield = (Shield)unit.getCurrentWeapon();

        if (currentShield.isBroken(unit.GetInstanceID()))
        {
            return(false);
        }

        if (currentShield.getShield(unit.GetInstanceID()) != null)
        {
            Destroy(currentShield.getShield(unit.GetInstanceID()));
        }

        //Check position is within range
        if (currentShield == null || Vector2.Distance(unit.GetComponent <GridItem>().getPos(), position.getPos()) > currentShield.range)
        {
            return(false);
        }
        //Create the game object
        //TODO- Fix the roation and shape of shields to be frontal not surround
        Vector3 toPosition = position.getVectorPostion() - unit.GetComponent <GridItem>().getVectorPostion();
        float   rotation   = Vector3.Angle(new Vector3(0, 0, 1), Vector3.Cross(toPosition, new Vector3(0, 1, 0)));

        print(rotation);
        GameObject newShield = Instantiate <GameObject>(Resources.Load <GameObject>("Units/Shield"), position.getVectorPostion(), Quaternion.Euler(0, rotation, 0));

        currentShield.setShield(unit.GetInstanceID(), newShield);

        newShield.GetComponent <shieldScript>().setStats(controllerID, unit.getSmarts() * 3);
        //Check it's collisions with other shields
        currentShield.shieldBreakCheck();


        unit.activateAttack();

        print("ACTIVATE SHIELD");
        map.UnHilightMap();



        return(true);
    }
예제 #7
0
    protected bool MeleeAttack(unitScript unit, unitScript clickedUnit, bool initialAttack = true)
    {
        // Check attack can occur
        if (unit.getCurrentWeapon().type == WeaponType.ranged || unit == null || clickedUnit == null)
        {
            return(false);
        }

        float distance = Vector2.Distance(unit.GetComponent <GridItem>().getPos(), clickedUnit.GetComponent <GridItem>().getPos());

        if (!(unit.getCurrentWeapon().type == WeaponType.melee) || distance > ((MeleeWeapon)unit.getCurrentWeapon()).range)
        {
            return(false);
        }

        // Given it can roll the dice
        float roll = UnityEngine.Random.Range(0.0f, 1.0f);

        float chanceToHit = meleeChanceToHit(unit, clickedUnit);

        print(roll + " " + chanceToHit);
        if (roll < chanceToHit)
        {
            clickedUnit.takeDamage(unit.getStrength() + unit.getCurrentWeapon().damage);
        }
        else
        {
            clickedUnit.displayMiss();
        }
        unit.activateAttack();
        if (initialAttack && clickedUnit.getStrikeback() == false)
        {
            bool result = MeleeAttack(clickedUnit, unit, false);
            if (result)
            {
                clickedUnit.useStrikeback();
            }
        }
        return(true);
    }
    public void loadCombatData(unitScript attacker, unitScript defender, float AttackerChanceToHit, float defenderChanceToHit)
    {
        Transform combatPanel = transform.Find("CombatPanel");
        Transform EnemyPanel  = combatPanel.Find("EnemyPanel");

        var targetText = EnemyPanel.Find("Target").GetComponent <UnityEngine.UI.Text>();

        targetText.text = defender.getName();

        var classText = EnemyPanel.Find("Class").GetComponent <UnityEngine.UI.Text>();

        classText.text = defender.getClass();

        var healthText = EnemyPanel.Find("Health").GetComponent <UnityEngine.UI.Text>();

        healthText.text = defender.getHealth().ToString() + " : " + defender.getMaxHealth().ToString();

        var strikeBack = EnemyPanel.Find("StrikeBack").GetComponent <Text>();

        strikeBack.text = (!defender.getStrikeback()).ToString();

        var strikebackChanceText = EnemyPanel.Find("ChanceText").GetComponent <Text>();
        var strikebackDamageText = EnemyPanel.Find("DamageText").GetComponent <Text>();

        var strikebackChance = EnemyPanel.Find("Chance").GetComponent <Text>();
        var strikebackDamage = EnemyPanel.Find("Damage").GetComponent <Text>();


        if (!defender.getStrikeback())
        {
            strikebackChance.enabled     = true;
            strikebackDamage.enabled     = true;
            strikebackChanceText.enabled = true;
            strikebackDamageText.enabled = true;

            strikebackChance.text = defenderChanceToHit.ToString();

            strikebackDamage.text = defender.getCurrentWeapon().damage.ToString();
        }
        else
        {
            strikebackChance.enabled     = false;
            strikebackDamage.enabled     = false;
            strikebackChanceText.enabled = false;
            strikebackDamageText.enabled = false;
        }
        int chance = (int)Mathf.Max(0, Mathf.Min(100, AttackerChanceToHit * 100));

        combatPanel.Find("ChanceToHit").GetComponent <UnityEngine.UI.Text>().text = (chance).ToString() + "%";
        combatPanel.Find("Damage").GetComponent <UnityEngine.UI.Text>().text      = unit.getCurrentWeapon().damage.ToString();
    }
    // Update is called once per frame
    void Update()
    {
        if (unit != null)
        {
            if (unit.canOpenDoor())
            {
                transform.FindChild("CharacterPanel").FindChild("DoorButton").GetComponent <Button>().interactable = true;
            }
            else
            {
                transform.FindChild("CharacterPanel").FindChild("DoorButton").GetComponent <Button>().interactable = false;
            }


            if (unit.getCurrentWeapon().type != lastWeaponType)
            {
                Transform attackButton = transform.Find("CharacterPanel").FindChild("AttackButton");

                attackButton.FindChild("CrossHair").gameObject.SetActive(false);
                attackButton.FindChild("Sword").gameObject.SetActive(false);
                attackButton.FindChild("Shield").gameObject.SetActive(false);

                if (unit.getCurrentWeapon().type == WeaponType.ranged)
                {
                    attackButton.FindChild("CrossHair").gameObject.SetActive(true);
                }

                else if (unit.getCurrentWeapon().type == WeaponType.melee)
                {
                    attackButton.FindChild("Sword").gameObject.SetActive(true);
                }

                else if (unit.getCurrentWeapon().type == WeaponType.shield)
                {
                    attackButton.FindChild("Shield").gameObject.SetActive(true);
                }


                lastWeaponType = unit.getCurrentWeapon().type;
            }
            if (unit.hasAttacked() || unit.isMoving() || (unit.getCurrentWeapon().type == WeaponType.shield && ((Shield)unit.getCurrentWeapon()).isBroken(unit.GetInstanceID())))
            {
                Transform attackButton = transform.Find("CharacterPanel").FindChild("AttackButton");
                attackButton.GetComponent <Button>().interactable = false;
            }
            else
            {
                Transform attackButton = transform.Find("CharacterPanel").FindChild("AttackButton");
                attackButton.GetComponent <Button>().interactable = true;
            }
        }
    }
예제 #10
0
    protected float rangedChanceToHit(unitScript unit, unitScript clickedUnit)
    {
        if (unit.getCurrentWeapon().type == WeaponType.melee)
        {
            return(0.0f);
        }
        //Calculate range penalty
        float distance = Vector2.Distance(unit.GetComponent <GridItem>().getPos(), clickedUnit.GetComponent <GridItem>().getPos());

        float rangedPenalty = getRangePenalty(unit, distance);

        //Calculate cover penalty
        float coverPenalty = getCoverPenalty(unit, clickedUnit, distance);

        //Get base shooting skill
        float shootingSkill = getBaseHitChance(unit);

        //Return formula
        return(shootingSkill - (rangedPenalty + coverPenalty) / 10);
    }
예제 #11
0
    protected bool hitShield(unitScript unit, unitScript clickedUnit)
    {
        Ray   ray      = new Ray(unit.transform.position + new Vector3(0, 1, 0), (clickedUnit.transform.position + new Vector3(0, 1, 0) - unit.transform.position + new Vector3(0, 1, 0)));
        float distance = Vector3.Distance(unit.transform.position, clickedUnit.transform.position);

        RaycastHit[] hits = Physics.RaycastAll(ray, distance).OrderBy(h => h.distance).ToArray();

        foreach (RaycastHit hit in hits)
        {
            if (hit.transform.gameObject.layer == 11)
            {
                shieldScript shield = hit.transform.gameObject.GetComponent <shieldScript>();
                if (shield.owner != controllerID)
                {
                    shield.takeDamage(unit.getCurrentWeapon().damage);
                }
                return(true);
            }
        }
        return(false);
    }
    void unitSelectedRightClick(RaycastHit hit, unitScript unit)
    {
        clickableTile tile = hit.collider.gameObject.GetComponent <clickableTile>();

        if (tile)
        {
            GridItem tilePos = tile.GetComponent <GridItem>();
            GridItem pos     = selected.GetComponent <GridItem>();

            if (!unit.hasMoved())
            {
                //draw path only if not in attack mode
                Vector2[] path = pathFinder.drawPath(tilePos.getPos(), !attackMode);


                if (path != null)
                {
                    if (!attackMode && !unit.hasMoved())
                    {
                        map.UnHilightMap();
                        //map.toggleHighlight(false, Color.white, pos.getX(), pos.getY(), unit.getSpeed());
                        unit.setPath(path);
                        pathFinder.setPathfinding(false);
                    }
                }
            }
            if (attackMode && unit.getCurrentWeapon().type == WeaponType.shield)
            {
                activateShield(unit, tilePos);
            }
        }
        //If not tile may be unit
        unitScript clickedUnit = hit.collider.gameObject.GetComponent <unitScript>();

        // if is enemy unit
        if (attackMode && !unit.hasAttacked() && clickedUnit && clickedUnit.getOwner() != 0)
        {
            Attack(unit, clickedUnit);
        }
    }
예제 #13
0
    //Assisting functions
    unitScript targetPrioritisation(unitScript unit, List <unitScript> enemyList)
    {
        AIUnitController unitControl = unit.GetComponent <AIUnitController>();

        List <float> priorites = new List <float>();

        foreach (unitScript otherUnit in enemyList)
        {
            //Add factors
            float priority = 0;

            if (otherUnit == null || otherUnit.getOwner() == controllerID || otherUnit.getHealth() <= 0)
            {
                priorites.Add(-1000000);
                break;
            }
            //distance - wrecklessness (negative if over wrecklessness
            priority -= Mathf.Max(0, Vector2.Distance(unit.GetComponent <GridItem>().getPos(), otherUnit.GetComponent <GridItem>().getPos()) - unitControl.wrecklessness);
            //deuling preference
            bool weaponsMatch = unit.getCurrentWeapon().type == otherUnit.getCurrentWeapon().type;
            if ((weaponsMatch && unitControl.deulingPreference) || (!weaponsMatch && !unitControl.deulingPreference))
            {
                priority += 2;
            }
            //Agro multiplied by anger
            if (unitControl.agroTarget == otherUnit)
            {
                priority += 10 * unitControl.anger;
            }
            priorites.Add(priority);
        }
        priorites.ForEach(e => print("Inlist" + e));
        int maxIndex = priorites.IndexOf(priorites.Max());

        unitControl.target = enemyList[maxIndex];
        print("Selected : " + enemyList[maxIndex]);
        return(enemyList[maxIndex]);
    }
    void AttackCommand()
    {
        if (attackMode)
        {
            attackMode            = false;
            rangeRenderer.enabled = false;
            map.UnHilightMap();
            selectUnit(selected.GetComponent <unitScript>());
        }
        else
        {
            unitScript unit = selected.GetComponent <unitScript>();
            if (unit.hasAttacked())
            {
                return;
            }
            Weapon   currentWeapon = unit.getCurrentWeapon();
            GridItem pos           = selected.GetComponent <GridItem>();

            map.UnHilightMap();

            if (currentWeapon.type == WeaponType.melee)
            {
                MeleeWeapon currentMeleeWeapon = (MeleeWeapon)currentWeapon;
                map.toggleHighlight(true, Color.red, pos.getX(), pos.getY(), currentMeleeWeapon.range);
            }
            else if (currentWeapon.type == WeaponType.shield)
            {
                Shield currentShield = (Shield)currentWeapon;
                map.toggleHighlight(true, Color.yellow, pos.getX(), pos.getY(), currentShield.range);
            }

            attackMode = true;
            pathFinder.setPathfinding(false);
        }
    }
    void mouseOver()
    {
        //Mouse over tile while unit selected
        if (selected)
        {
            unitScript unit = selected.GetComponent <unitScript>();
            if (unit != null && unit.getOwner() == 0)
            {
                RaycastHit hit;
                var        ray = Camera.main.ScreenPointToRay(Input.mousePosition);

                if (Physics.Raycast(ray, out hit, Mathf.Infinity, (1 << 8)))
                {
                    clickableTile tile = hit.collider.gameObject.GetComponent <clickableTile>();

                    if (tile && !unit.hasMoved() && !attackMode)
                    {
                        GridItem tilePos = tile.GetComponent <GridItem>();
                        //print(tilePos);
                        if (pathFinder != null)
                        {
                            pathFinder.drawPath(tilePos.getPos());
                        }
                        else
                        {
                            print("pathfinder dead");
                        }
                    }

                    unitScript enemyUnit = hit.collider.GetComponent <unitScript>();

                    if (enemyUnit && attackMode == true && enemyUnit.getOwner() != 0)
                    {
                        GridItem playerPos = unit.GetComponent <GridItem>();
                        GridItem enemyPos  = hit.collider.GetComponent <GridItem>();

                        MeleeWeapon currentMeleeWeapon = null;
                        if (unit.getCurrentWeapon().type == WeaponType.melee)
                        {
                            currentMeleeWeapon = (MeleeWeapon)unit.getCurrentWeapon();


                            bool withinMeleeRange = currentMeleeWeapon != null && Vector2.Distance(enemyPos.getPos(), playerPos.getPos()) <= currentMeleeWeapon.range;
                            if (withinMeleeRange || currentMeleeWeapon == null)
                            {
                                GUIController cont = gui.GetComponent <GUIController>();

                                cont.setCombatPanelVisibility(true, unit, enemyUnit, meleeChanceToHit(unit, enemyUnit));
                            }
                        }
                        else if (unit.getCurrentWeapon().type == WeaponType.ranged)
                        {
                            if (canSee(unit, enemyUnit))
                            {
                                rangeRenderer.enabled = true;
                                updateRangefinder(unit, enemyUnit.GetComponent <GridItem>());
                                GUIController cont     = gui.GetComponent <GUIController>();
                                float         distance = Vector2.Distance(unit.GetComponent <GridItem>().getPos(), enemyUnit.GetComponent <GridItem>().getPos());

                                cont.setCombatPanelVisibility(true, unit, enemyUnit, rangedChanceToHit(unit, enemyUnit));
                                cont.loadRangedData(isShielded(unit, enemyUnit), getBaseHitChance(unit), getRangePenalty(unit, distance), getCoverPenalty(unit, enemyUnit, distance));
                            }
                            else if (rangeRenderer.enabled == true)
                            {
                                rangeRenderer.enabled = false;
                            }
                        }
                    }
                    else
                    {
                        GUIController cont = gui.GetComponent <GUIController>();

                        cont.setCombatPanelVisibility(false);
                        rangeRenderer.enabled = false;
                    }
                }
            }
        }

        //We also want to set the enemyStatPanel

        RaycastHit result;
        Ray        line = Camera.main.ScreenPointToRay(Input.mousePosition);

        if (Physics.Raycast(line, out result, Mathf.Infinity, (1 << 8)))
        {
            //set selected to hit
            GameObject enemy = result.collider.gameObject;

            //Select new unit
            if (enemy)
            {
                var        guiCont = gui.GetComponent <GUIController>();
                unitScript unit    = enemy.GetComponent <unitScript>();

                if (unit != null && unit.getOwner() == 1)
                {
                    guiCont.setCharacterPanelVisibility(true, unit, false);
                }
                else
                {
                    guiCont.setCharacterPanelVisibility(false, null, false);
                }
            }
        }
    }
예제 #16
0
    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");
            }
        }
    }
    void updateRangefinder(unitScript unit, GridItem position)
    {
        RangedWeapon weapon = (RangedWeapon)unit.getCurrentWeapon();

        // Set line data
        Vector3[] positions = new Vector3[4];
        positions[0] = new Vector3(unit.GetComponent <GridItem>().getX(), 1.0f, unit.GetComponent <GridItem>().getY());
        positions[3] = new Vector3(position.getX(), 1.0f, position.getY());

        float distance = Vector3.Distance(positions[0], positions[3]);

        positions[1] = Vector3.Lerp(positions[0], positions[3], Mathf.Max(0.001f, weapon.minRange / distance));
        positions[2] = Vector3.Lerp(positions[0], positions[3], Mathf.Min(0.9999f, (float)weapon.maxRange / distance));

        rangeRenderer.numPositions = 4;
        rangeRenderer.SetPositions(positions);



        GradientColorKey[] colorKey = new GradientColorKey[4];
        GradientAlphaKey[] alphaKey = new GradientAlphaKey[2];

        //Set ends to red and red
        colorKey[2] = new GradientColorKey(new Color(1, 0, 0), 0.0f);


        Color endColor;

        if (distance < weapon.minRange || distance > weapon.maxRange)
        {
            endColor = new Color(1, 0, 0);
        }
        else
        {
            endColor = new Color(0, 0, 0);
        }

        colorKey[3] = new GradientColorKey(endColor, 1.0f);

        //Set alphaKeys
        alphaKey[0] = new GradientAlphaKey(1.0f, 0.0f);
        alphaKey[1] = new GradientAlphaKey(1.0f, 1.0f);
        //Set color key's two and three according to range

        GradientColorKey minKey, maxKey;

        if (distance > weapon.minRange)
        {
            minKey = new GradientColorKey(new Color(0, 0, 0), (float)weapon.minRange / distance);
        }
        else
        {
            minKey = new GradientColorKey(new Color(1, 0, 0), 0.2f);
        }

        colorKey[0] = minKey;

        if (distance > weapon.minRange)
        {
            maxKey = new GradientColorKey(new Color(0, 0, 0), Mathf.Min(0.99999f, (float)weapon.maxRange / distance));
        }
        else
        {
            maxKey = new GradientColorKey(new Color(1, 0, 0), 0.5f);
        }

        colorKey[1] = maxKey;

        Gradient grad = new Gradient();

        grad.mode = GradientMode.Blend;
        grad.SetKeys(colorKey, alphaKey);

        rangeRenderer.colorGradient = grad;
    }