コード例 #1
0
        private Tile AnalyseCoverSystem(Unit unit, List <Tile> walkableTilesInRange, List <Unit> allHostileInSight)
        {
            List <Tile> walkableTilesInRangeAlt = new List <Tile>();    //for cover system, secondary tiles with less cover

            List <Tile> halfCoveredList = new List <Tile>();            //a list for all the tiles with half Cover
            List <Tile> fullCoveredList = new List <Tile>();            //a list for all the tiles with full Cover

            if (allHostileInSight.Count == 0)
            {
                fullCoveredList = walkableTilesInRange;
            }
            else                //if there are hostile in sight
                                //loop through all the walkable, record their score based on
            {
                for (int i = 0; i < walkableTilesInRange.Count; i++)
                {
                    Tile tile = walkableTilesInRange[i];
                    tile.hostileCount = 0;
                    tile.coverScore   = 0;

                    //iterate through all hostile, add the count, and cover type to the tile, this will then be used in tile.GetCoverRating() when this loop is complete
                    for (int n = 0; n < allHostileInSight.Count; n++)
                    {
                        // if the hostile is out of range, ignore it
                        int hostileRange = allHostileInSight[n].GetMoveRange() + allHostileInSight[n].GetAttackRange();
                        if (GridManager.GetDistance(allHostileInSight[n].tile, tile) > hostileRange)
                        {
                            continue;
                        }

                        tile.hostileCount += 1;

                        CoverSystem._CoverType coverType = CoverSystem.GetCoverType(allHostileInSight[n].tile, walkableTilesInRange[i]);
                        if (coverType == CoverSystem._CoverType.Half)
                        {
                            tile.coverScore += 1;
                        }
                        else if (coverType == CoverSystem._CoverType.Full)
                        {
                            tile.coverScore += 2;
                        }
                    }

                    //get cover rating for the tile
                    //if score is >=2, the tile has full cover from all hostile, so add it to fullCoveredList
                    //if score is >=1 && <2, the tile has half cover from all hostile, so add it to halfCoveredList
                    //if anything <1, the tile is exposed to hostile in some manner
                    if (tile.GetCoverRating() >= 2)
                    {
                        fullCoveredList.Add(tile);
                    }
                    else if (tile.GetCoverRating() >= 1)
                    {
                        halfCoveredList.Add(tile);
                    }
                }
            }

            //if either of the CoveredList is not empty, replace walkableTilesInRange with that since there's no need to consider to move into tiles without cover
            if (fullCoveredList.Count != 0)
            {
                walkableTilesInRange    = fullCoveredList;
                walkableTilesInRangeAlt = halfCoveredList;
            }
            else if (halfCoveredList.Count != 0)
            {
                walkableTilesInRange = halfCoveredList;
            }

            //if there are hostile
            if (allHostileInSight.Count > 0)
            {
                //fill up the walkableTilesInRange hostile list
                //then filter thru walkableTilesInRange, those that have a hostile in range will be add to a tilesWithHostileInRange
                List <Tile> tilesWithHostileInRange = new List <Tile>();
                GridManager.SetupHostileInRangeforTile(unit, walkableTilesInRange);
                for (int i = 0; i < walkableTilesInRange.Count; i++)
                {
                    if (walkableTilesInRange[i].GetHostileInRange().Count > 0)
                    {
                        tilesWithHostileInRange.Add(walkableTilesInRange[i]);
                    }
                }

                if (tilesWithHostileInRange.Count == 0)
                {
                    GridManager.SetupHostileInRangeforTile(unit, walkableTilesInRangeAlt);
                    for (int i = 0; i < walkableTilesInRangeAlt.Count; i++)
                    {
                        if (walkableTilesInRangeAlt[i].GetHostileInRange().Count > 0)
                        {
                            tilesWithHostileInRange.Add(walkableTilesInRangeAlt[i]);
                        }
                    }
                }

                //if the tilesWithHostileInRange is not empty after the process, means there's tiles which the unit can move into and attack
                //return one of those in the tilesWithHostileInRange so the unit can attack
                if (tilesWithHostileInRange.Count > 0)
                {
                    //if the unit current tile is one of those tiles with hostile, just stay put and attack
                    if (tilesWithHostileInRange.Contains(unit.tile))
                    {
                        //randomize it a bit so the unit do move around but not stay in place all the time
                        if (Random.Range(0f, 1f) > 0.25f)
                        {
                            return(unit.tile);
                        }
                    }
                    return(tilesWithHostileInRange[Random.Range(0, tilesWithHostileInRange.Count)]);
                }
            }

            return(null);
        }
コード例 #2
0
        private void CalculateChance()
        {
            if (calculated)
            {
                return;
            }
            calculated = true;

            float coverDodgeBonus  = 0;
            float exposedCritBonus = 0;

            //if cover system is enabled, get the dodge and crit bonus
            if (GameControl.EnableCover())
            {
                coverType = CoverSystem.GetCoverType(srcUnit.tile, tgtUnit.tile);
                if (coverType == CoverSystem._CoverType.Half)
                {
                    coverDodgeBonus = CoverSystem.GetHalfCoverDodgeBonus();
                }
                else if (coverType == CoverSystem._CoverType.Full)
                {
                    coverDodgeBonus = CoverSystem.GetFullCoverDodgeBonus();
                }
                else
                {
                    exposedCritBonus = CoverSystem.GetExposedCritChanceBonus();
                }
            }

            //calculate the hit chance
            float hit = !isMelee?srcUnit.GetHitChance() : srcUnit.GetHitChanceMelee();

            float dodge = tgtUnit.GetDodgeChance() + coverDodgeBonus;

            hitChance = Mathf.Clamp(hit - dodge, 0f, 1f);

            //calculate the critical chance
            float critHit   = (!isMelee ? srcUnit.GetCritChance() : srcUnit.GetCritChanceMelee()) + exposedCritBonus;
            float critAvoid = tgtUnit.GetCritAvoidance();

            critChance = Mathf.Clamp(critHit - critAvoid, 0f, 1f);

            //calculate stun chance
            float stunHit   = srcUnit.GetStunChance();
            float stunAvoid = tgtUnit.GetStunAvoidance();

            stunChance = Mathf.Clamp(stunHit - stunAvoid, 0f, 1f);

            //calculate silent chance
            float silentHit   = srcUnit.GetSilentChance();
            float silentAvoid = tgtUnit.GetSilentAvoidance();

            silentChance = Mathf.Clamp(silentHit - silentAvoid, 0f, 1f);

            if (isOverwatch)
            {
                hitChance -= GameControl.GetOverwatchHitPenalty();
                critHit   -= GameControl.GetOverwatchCritPenalty();
            }

            //check if flanking is enabled an applicable in this instance
            if (GameControl.EnableFlanking())
            {
                //Vector2 dir=new Vector2(srcUnit.tile.pos.x-tgtUnit.tile.pos.x, srcUnit.tile.pos.z-tgtUnit.tile.pos.z);
                float      angleTH        = 180 - Mathf.Min(180, GameControl.GetFlankingAngle());
                Quaternion attackRotation = Quaternion.LookRotation(tgtUnit.tile.GetPos() - srcUnit.tile.GetPos());
                //Debug.Log(Quaternion.Angle(attackRotation, tgtUnit.thisT.rotation)+"    "+angleTH);
                if (Quaternion.Angle(attackRotation, tgtUnit.thisT.rotation) < angleTH)
                {
                    flanked = true;
                }
            }
        }