예제 #1
0
        private Vector3 whereToMove(Unit squaddie, IHittable target, HashSet <IHittable> enemiesList, Unit.ClassType type)
        {
            switch (type)
            {
            case Unit.ClassType.Artillary:
                float     smallestDistance = float.PositiveInfinity;
                IHittable closestThreat    = null;
                //first, check if there are enemies closer than ArtillaryDesesperoRadius
                foreach (var enemy in enemiesList)
                {
                    float currentDistance = Vector3.Distance(enemy.position, squaddie.position);
                    if (currentDistance < smallestDistance)
                    {
                        smallestDistance = currentDistance;
                        closestThreat    = enemy;
                    }
                }
                if (smallestDistance < ArtillaryDeseperoRadius)     // if there are enemies whoa re too close
                {
                    Vector3 result = (closestThreat.position - squaddie.position);
                    result.Normalize();
                    //maybe we should multiply result for something here, if it is too small.
                    return(result);
                }
                else
                {
                    if (smallestDistance < ArtillaryDeseperoRadius + ArtillaryStillThreshold)
                    {
                        //this is to prevent archers from dancing in position.
                        return(squaddie.position);
                    }
                    else
                    {
                        return(target.position);
                    }
                }
                break;

            case Unit.ClassType.Infantry:
            case Unit.ClassType.Cavalry:
                return(target.position);

            default:
                return(squaddie.position);

                break;
            }
        }
예제 #2
0
        private IHittable defineEnemy(Unit.ClassType squaddieType, HashSet <IHittable> enemiesList, Dictionary <IHittable, MeeleOrRanged> numberOfSiblingsOnEnemy, Unit squaddie)
        {
            IHittable currentTarget = null;
            //First, let's try to ignore the buildings
            HashSet <IHittable> buildingsList = new HashSet <IHittable>();

            if (squaddieType != Unit.ClassType.Siege) // the following is for "human" troops only
            {
                foreach (var enemy in enemiesList)
                {
                    if (enemy.getType() == RTS.HitType.Building)
                    {
                        buildingsList.Add(enemy);
                    }
                }
                if (buildingsList.Count() == enemiesList.Count()) //if all enemies are buildings
                {
                    enemiesList = buildingsList;
                }
                else
                {
                    foreach (var building in buildingsList)
                    {
                        enemiesList.Remove(building); //focus on troops first
                    }
                }
            }
            switch (squaddieType)
            {
            case Unit.ClassType.Infantry:
                float smallestDistance = float.PositiveInfinity;
                foreach (var enemy in enemiesList)
                {
                    if (numberOfSiblingsOnEnemy[enemy].Meele < numberOfMeeleUnitsOnOneEnemy)     //só atacar se tiver poucos "irmãos" atacando
                    {
                        float currentDistance = Vector3.Distance(enemy.position, squaddie.position);
                        if (currentDistance < smallestDistance)
                        {
                            smallestDistance = currentDistance;
                            currentTarget    = enemy;
                        }
                    }
                }
                break;

            case Unit.ClassType.Artillary:
                float smallestHp = float.PositiveInfinity;
                foreach (var enemy in enemiesList)
                {
                    if (numberOfSiblingsOnEnemy[enemy].Meele + numberOfSiblingsOnEnemy[enemy].Ranged < numberOfTotalUnitsOnOneEnemy)         //não queremos arqueiros disperdiçando tiros e dando one-shot. 6 é um tanto arbitrário
                    {
                        if (enemy.getHp() < smallestHp)
                        {
                            smallestDistance = enemy.getHp();
                            currentTarget    = enemy;
                        }
                    }
                }
                break;

            case Unit.ClassType.Cavalry:
                HashSet <IHittable> oldEnemiesList = enemiesList;
                HashSet <IHittable> archersList    = new HashSet <IHittable>();
                foreach (var enemy in enemiesList)
                {
                    if (enemy.getType() == RTS.HitType.ArtillaryUnit)
                    {
                        archersList.Add(enemy);
                    }
                }
                if (archersList.Count() > 0)      //if there are archers
                {
                    enemiesList = archersList;
                }
                float largestDistance = float.NegativeInfinity;
                foreach (var enemy in enemiesList)
                {
                    if (numberOfSiblingsOnEnemy[enemy].Meele < numberOfMeeleUnitsOnOneEnemy)     //só atacar se tiver poucos "irmãos" atacando
                    {
                        float currentDistance = Vector3.Distance(enemy.position, squaddie.position);
                        if (currentDistance > largestDistance)
                        {
                            largestDistance = currentDistance;
                            currentTarget   = enemy;
                        }
                    }
                }
                if (currentTarget == null)    //then none of the archers are avaiable (maybe because there are too many meele units around them
                {
                    enemiesList = oldEnemiesList;
                    foreach (var archer in archersList)
                    {
                        enemiesList.Remove(archer);
                    }
                    foreach (var enemy in enemiesList)
                    {
                        if (numberOfSiblingsOnEnemy[enemy].Meele < numberOfMeeleUnitsOnOneEnemy)     //só atacar se tiver poucos "irmãos" atacando
                        {
                            float currentDistance = Vector3.Distance(enemy.position, squaddie.position);
                            if (currentDistance > largestDistance)
                            {
                                largestDistance = currentDistance;
                                currentTarget   = enemy;
                            }
                        }
                    }
                }
                break;

            default:
                currentTarget = null;
                break;
            }
            return(currentTarget);
        }
예제 #3
0
        private bool AttackOrMove(Unit squaddie, IHittable target, HashSet <IHittable> enemiesList, Unit.ClassType type)
        {
            //true means attack, false means move
            switch (type)
            {
            case Unit.ClassType.Artillary:
                float smallestDistance = float.PositiveInfinity;
                //first, check if there are enemies closer than ArtillaryDesesperoRadius
                foreach (var enemy in enemiesList)
                {
                    float currentDistance = Vector3.Distance(enemy.position, squaddie.position);
                    if (currentDistance < smallestDistance)
                    {
                        smallestDistance = currentDistance;
                    }
                }
                if (smallestDistance > ArtillaryDeseperoRadius)     //then we are relatively safe, let's find the most weakened enemy
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
                break;

            case Unit.ClassType.Infantry:
            case Unit.ClassType.Cavalry:
                float targetDistance = Vector3.Distance(target.position, squaddie.position);
                if (targetDistance < squaddie.Range)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }

            default:
                return(false);

                break;
            }
        }