Exemplo n.º 1
0
    public static void MakeDecision(CharacterBase self)
    {
        //sort list so that the singleEnemyActionConsiderations are all at the front of the list, custom CompareTo function within the ActionConsideration Class should changes need to be made to order or new child class is created.
        actionConsiderationList.Sort((ActionConsideration val1, ActionConsideration val2) =>
        {
            return(val1.CompareTo(val2));
        });

        for (int i = 0; i < actionConsiderationList.Count; i++)
        {
            if (self.enemiesInSight.Count != 0)
            {
                foreach (KeyValuePair <CharacterBase, int> EnemyHitChancePair in self.enemiesInSight)
                {
                    //foreach enemy, calculate the cover from and for the agent (could be expensive hence this is calculated once and the actions are the more commonly calculated part.
                    ECoverValue agentCoverFromEnemy = self.occupiedTile.ProvidesCoverInDirection(EnemyHitChancePair.Key.gameObject.transform.position - self.transform.position);
                    ECoverValue enemyCoverFromAgent = self.occupiedTile.ProvidesCoverInDirection(self.transform.position - EnemyHitChancePair.Key.gameObject.transform.position);
                    int         firstSingleEnemyActionConsiderationIndex = i;
                    while (actionConsiderationList[i] is SingleEnemyActionConsideration)
                    {
                        (actionConsiderationList[i] as SingleEnemyActionConsideration).ConsiderAction(self, EnemyHitChancePair.Key, agentCoverFromEnemy, enemyCoverFromAgent);
                        i++;
                    }
                    i = EnemyHitChancePair.Key != self.enemiesInSight.ElementAt(self.enemiesInSight.Count - 1).Key ? firstSingleEnemyActionConsiderationIndex // if not the end of the enemies then reset the i counter;
                                                                        : i;
                }
            }
            else
            {
                while (actionConsiderationList[i] is SingleEnemyActionConsideration)
                {
                    (actionConsiderationList[i] as SingleEnemyActionConsideration).ConsiderActionWithNoEnemyInSight(self);
                    i++;
                }
            }
            if (i <= actionConsiderationList.Count && actionConsiderationList[i] is NoEnemyActionConsideration)
            {
                (actionConsiderationList[i] as NoEnemyActionConsideration).ConsiderAction(self);
            }
        }
        //actions all evaluated by this point
        actionConsiderationList.Sort((ActionConsideration consideration1, ActionConsideration consideration2) =>
        {
            return(consideration2.FinalValue.CompareTo(consideration1.FinalValue));
        }); //order list by value descending;
        actionConsiderationList[UnityEngine.Random.Range(0, (self as EnemyCharacter).actionVariance)].Enact(self);
        foreach (ActionConsideration ac in actionConsiderationList)
        {
            ac.ResetValue();
        }
    }
    public override void ConsiderAction(CharacterBase self, CharacterBase enemy, ECoverValue agentLevelOfCoverFromEnemy, ECoverValue enemyLevelOfCoverFromAgent)
    {
        #region Remaining Pips Check
        actionValue += self.actionPips > 1 ? ((int)Weighting.SuperHeavy / self.enemiesInSight.Count) : 0;
        #endregion

        #region Proximity To Players Check
        float distanceBetween = Vector3.Distance(self.transform.position, enemy.transform.position);
        if (distanceBetween <= self.closeDistanceCap)
        {
            actionValue -= ((int)Weighting.Heavy / self.enemiesInSight.Count);
        }
        else if (distanceBetween <= self.middleDistanceCap)
        {
            actionValue += ((int)Weighting.Light / self.enemiesInSight.Count);
        }
        else
        {
            actionValue += ((int)Weighting.Heavy / self.enemiesInSight.Count);
        }
        #endregion

        #region Enemy Overwatch Check
        if (enemy.isOverwatching)
        {
            actionValue -= ((int)Weighting.Heavy / self.enemiesInSight.Count);
        }
        #endregion

        #region Agent Cover Check
        switch (agentLevelOfCoverFromEnemy)
        {
        case ECoverValue.None:
            actionValue += ((int)Weighting.SuperHeavy / self.enemiesInSight.Count);
            break;

        case ECoverValue.Half:
            actionValue += ((int)Weighting.Heavy / self.enemiesInSight.Count);
            break;

        case ECoverValue.Full:
            actionValue -= ((int)Weighting.Light / self.enemiesInSight.Count);
            break;

        default:
            break;
        }
        #endregion
        //actionValue += self.enemiesInSight.Count < 2 ? (int)Weighting.Medium : -(int)Weighting.Low;
    }
    public override void ConsiderAction(CharacterBase self, CharacterBase enemy, ECoverValue agentLevelOfCoverFromEnemy, ECoverValue enemyLevelOfCoverFromAgent)
    {
        int thisEnemyShootValue = 0;

        #region Agent Cover Check
        switch (agentLevelOfCoverFromEnemy)
        {
        case ECoverValue.None:
            thisEnemyShootValue -= (int)Weighting.Heavy;
            break;

        case ECoverValue.Half:
            thisEnemyShootValue += (int)Weighting.Heavy;
            break;

        case ECoverValue.Full:
            thisEnemyShootValue += (int)Weighting.SuperHeavy;
            break;

        default:
            Debug.LogError("issue with cover Value returned");
            break;
        }
        #endregion

        #region PlayerCharacter Hit Chance Check
        int chanceToHit = self.enemiesInSight.Find((characterHitChancePair) => { return(characterHitChancePair.Key == enemy); }).Value;
        if (chanceToHit > 70)
        {
            actionValue += (int)Weighting.SuperHeavy;
        }
        else if (chanceToHit > 50)
        {
            actionValue += (int)Weighting.Heavy;
        }
        else
        {
            actionValue -= (int)Weighting.Light;
        }
        #endregion

        #region Evaluate Whether This Shot Represents the Shooting Action
        if (thisEnemyShootValue > actionValue || enemyToAttack == null)
        {
            enemyToAttack = enemy;
            actionValue   = thisEnemyShootValue;
        }
        #endregion
        //why is there no chanceToHitCalculation in here?
    }
 public abstract void ConsiderAction(CharacterBase self, CharacterBase enemy, ECoverValue agentLevelOfCoverFromEnemy, ECoverValue enemyLevelOfCoverFromAgent);
    public override void ConsiderAction(CharacterBase self, CharacterBase enemy, ECoverValue agentLevelOfCoverFromEnemy, ECoverValue enemyLevelOfCoverFromAgent)
    {
        #region Agent Cover Check
        switch (agentLevelOfCoverFromEnemy)
        {
        case ECoverValue.None:
            actionValue -= ((int)Weighting.SuperHeavy / self.enemiesInSight.Count);
            break;

        case ECoverValue.Half:
            actionValue += ((int)Weighting.SuperHeavy / self.enemiesInSight.Count);
            break;

        case ECoverValue.Full:
            actionValue += ((int)Weighting.Light / self.enemiesInSight.Count);
            break;

        default:
            break;
        }
        #endregion

        #region Player Character Cover Check
        switch (enemyLevelOfCoverFromAgent)
        {
        case ECoverValue.None:
            actionValue += (int)Weighting.SuperHeavy / self.enemiesInSight.Count;
            break;

        case ECoverValue.Half:
            actionValue += (int)Weighting.Heavy / self.enemiesInSight.Count;
            break;

        case ECoverValue.Full:
            actionValue -= (int)Weighting.Light / self.enemiesInSight.Count;
            break;

        default:
            break;
        }
        #endregion

        #region Chance To Hit Player Check
        int chanceToHit = self.enemiesInSight.Find((characterHitChancePair) => { return(characterHitChancePair.Key == enemy); }).Value;
        if (chanceToHit > 70)
        {
            actionValue -= (int)Weighting.SuperHeavy / self.enemiesInSight.Count;
        }
        else if (chanceToHit > 50)
        {
            actionValue += (int)Weighting.Light / self.enemiesInSight.Count;
        }
        else
        {
            actionValue += (int)Weighting.SuperHeavy / self.enemiesInSight.Count;
        }
        #endregion

        #region Number of Players In Sight Check
        actionValue += self.enemiesInSight.Count > 2 ? ((int)Weighting.Light / self.enemiesInSight.Count) : -((int)Weighting.Heavy / self.enemiesInSight.Count);
        #endregion
    }
    public override void ConsiderAction(CharacterBase self, CharacterBase enemy, ECoverValue agentLevelOfCoverFromEnemy, ECoverValue enemyLevelOfCoverFromAgent)
    {
        #region Agent Cover Check
        switch (agentLevelOfCoverFromEnemy)
        {
        case ECoverValue.None:
            actionValue -= ((int)Weighting.SuperHeavy / self.enemiesInSight.Count);
            break;

        case ECoverValue.Half:
            actionValue += ((int)Weighting.Light / self.enemiesInSight.Count);
            break;

        case ECoverValue.Full:
            actionValue += ((int)Weighting.SuperHeavy / self.enemiesInSight.Count);
            break;

        default:
            break;
        }
        #endregion

        #region PlayerCharacter Cover Check
        switch (enemyLevelOfCoverFromAgent)
        {
        case ECoverValue.None:
            actionValue += ((int)Weighting.SuperHeavy / self.enemiesInSight.Count);
            break;

        case ECoverValue.Half:
            actionValue += ((int)Weighting.Light / self.enemiesInSight.Count);
            break;

        case ECoverValue.Full:
            actionValue -= ((int)Weighting.Heavy / self.enemiesInSight.Count);
            break;

        default:
            break;
        }
        #endregion

        #region Ammo Check
        actionValue += self.ammunition >= (self.MaximumAmmunition >> 1) ? ((int)Weighting.Heavy / self.enemiesInSight.Count) : -((int)Weighting.Heavy / self.enemiesInSight.Count);
        #endregion

        #region Proximity To Players Check
        float distanceBetween = Vector3.Distance(self.transform.position, enemy.transform.position);
        if (distanceBetween <= self.closeDistanceCap)
        {
            actionValue -= ((int)Weighting.Heavy / self.enemiesInSight.Count);
        }
        else if (distanceBetween <= self.middleDistanceCap)
        {
            actionValue += ((int)Weighting.Heavy / self.enemiesInSight.Count);
        }
        else
        {
            actionValue += ((int)Weighting.Light / self.enemiesInSight.Count);
        }
        #endregion
    }