Exemple #1
0
        public virtual bool CanHitTarget(LocalTargetInfo target, bool sightCheck)
        {
            if (target.IsValid && target.Cell.DistanceTo(this.pawn.Position) < this.GetRangeForPawn())
            {
                if ((this.targetParams.canTargetLocations && this.targetParams.CanTarget(new TargetInfo(target.Cell, this.Caster.Map))) ||
                    this.targetParams.CanTarget(target.ToTargetInfo(this.Caster.Map)))
                {
                    if (!sightCheck)
                    {
                        return(true);
                    }

                    if (GenSight.LineOfSight(this.pawn.Position, target.Cell, this.pawn.Map))
                    {
                        return(true);
                    }
                    List <IntVec3> tempSourceList = new List <IntVec3>();
                    ShootLeanUtility.LeanShootingSourcesFromTo(this.pawn.Position, target.Cell, this.pawn.Map, tempSourceList);
                    if (tempSourceList.Any(ivc => GenSight.LineOfSight(ivc, target.Cell, this.pawn.Map)))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemple #2
0
        public static bool CanSee(ref bool __result, Thing seer, Thing target, Func <IntVec3, bool> validator = null)
        {
            List <IntVec3> tempDestList   = new List <IntVec3>();
            List <IntVec3> tempSourceList = new List <IntVec3>();

            ShootLeanUtility.CalcShootableCellsOf(tempDestList, target);
            for (int index = 0; index < tempDestList.Count; ++index)
            {
                if (GenSight.LineOfSight(seer.Position, tempDestList[index], seer.Map, true, validator, 0, 0))
                {
                    __result = true;
                    return(false);
                }
            }
            ShootLeanUtility.LeanShootingSourcesFromTo(seer.Position, target.Position, seer.Map, tempSourceList);
            for (int index1 = 0; index1 < tempSourceList.Count; ++index1)
            {
                for (int index2 = 0; index2 < tempDestList.Count; ++index2)
                {
                    if (GenSight.LineOfSight(tempSourceList[index1], tempDestList[index2], seer.Map, true, validator, 0, 0))
                    {
                        __result = true;
                        return(false);
                    }
                }
            }
            __result = false;
            return(false);
        }
        /// <summary>
        /// LocalTargetInfo friendly variant of AttackTargetFinder.CanSee()
        /// </summary>
        /// <param name="caster">Line caster source.</param>
        /// <param name="target">Target we want to check whether we can see or not.</param>
        /// <param name="skipFirstCell">Skip the first cell from source?</param>
        /// <param name="validator">Validator for obstacles, presumably.</param>
        /// <returns>True if we got Line of Sight, false if not.</returns>
        public static bool LineOfSightLocalTarget(Thing caster, LocalTargetInfo target, bool skipFirstCell = false, Func <IntVec3, bool> validator = null)
        {
            //Use default function if we has a Thing.
            //To-do: Get this to work without null errors.

            /*if (target.HasThing && caster != null && target != null)
             * {
             *  if (target.Thing == caster)
             *      return true;
             *
             *  //Log.Message("AttackTargetFinder.CanSee(" + caster?.Map.GetUniqueLoadID() + ", " + target.Thing?.Map.GetUniqueLoadID() + ")");
             *
             *  return AttackTargetFinder.CanSee(caster, target.Thing);
             * }*/


            //Use homebrewed cariant for just a position.
            ShootLeanUtility.LeanShootingSourcesFromTo(caster.Position, target.Cell, caster.Map, tempSourceList);

            //See if we can get target from any source cell.
            if (tempSourceList.Count > 0)
            {
                foreach (IntVec3 sourceCell in tempSourceList)
                {
                    if (GenSight.LineOfSight(sourceCell, target.Cell, caster.Map, skipFirstCell, validator))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
 public new bool CanHitFromCellIgnoringRange(IntVec3 sourceCell, LocalTargetInfo targ, out IntVec3 goodDest)
 {
     if (targ.Thing != null)
     {
         if (targ.Thing.Map != this.Caster.Map)
         {
             goodDest = IntVec3.Invalid;
             return(false);
         }
         ShootLeanUtility.CalcShootableCellsOf(Verb_ShootCompMountedCE.tempDestList, targ.Thing);
         for (int i = 0; i < Verb_ShootCompMountedCE.tempDestList.Count; i++)
         {
             if (this.CanHitCellFromCellIgnoringRange(sourceCell, Verb_ShootCompMountedCE.tempDestList[i], targ.Thing.def.Fillage == FillCategory.Full))
             {
                 goodDest = Verb_ShootCompMountedCE.tempDestList[i];
                 return(true);
             }
         }
     }
     else if (this.CanHitCellFromCellIgnoringRange(sourceCell, targ.Cell, false))
     {
         goodDest = targ.Cell;
         return(true);
     }
     goodDest = IntVec3.Invalid;
     return(false);
 }
Exemple #5
0
        private static bool CanHitFromCellIgnoringRange2(Verb __instance, IntVec3 sourceCell, LocalTargetInfo targ, out IntVec3 goodDest)
        {
            if (targ.Thing != null)
            {
                if (targ.Thing.Map != __instance.caster.Map)
                {
                    goodDest = IntVec3.Invalid;
                    return(false);
                }
                List <IntVec3> tempDestList = new List <IntVec3>();
                ShootLeanUtility.CalcShootableCellsOf(tempDestList, targ.Thing);
                for (int i = 0; i < tempDestList.Count; i++)
                {
                    if (CanHitCellFromCellIgnoringRange(__instance, sourceCell, tempDestList[i], targ.Thing.def.Fillage == FillCategory.Full))
                    {
                        goodDest = tempDestList[i];
                        return(true);
                    }
                }
            }
            else if (CanHitCellFromCellIgnoringRange(__instance, sourceCell, targ.Cell))
            {
                goodDest = targ.Cell;
                return(true);
            }

            goodDest = IntVec3.Invalid;
            return(false);
        }
Exemple #6
0
 public static bool CanHitFromCellIgnoringRange(Verb __instance, ref bool __result,
                                                IntVec3 sourceCell,
                                                LocalTargetInfo targ,
                                                out IntVec3 goodDest)
 {
     if (targ.Thing != null)
     {
         if (targ.Thing.Map != __instance.caster.Map)
         {
             goodDest = IntVec3.Invalid;
             __result = false;
             return(false);
         }
         List <IntVec3> tempDestList = new List <IntVec3>();
         ShootLeanUtility.CalcShootableCellsOf(tempDestList, targ.Thing);
         for (int index = 0; index < tempDestList.Count; ++index)
         {
             if (CanHitCellFromCellIgnoringRange(__instance, sourceCell, tempDestList[index], targ.Thing.def.Fillage == FillCategory.Full))
             {
                 goodDest = tempDestList[index];
                 __result = true;
                 return(false);
             }
         }
     }
     else if (CanHitCellFromCellIgnoringRange(__instance, sourceCell, targ.Cell, false))
     {
         goodDest = targ.Cell;
         __result = true;
         return(false);
     }
     goodDest = IntVec3.Invalid;
     __result = false;
     return(false);
 }
        // Verse.Verb
        // Token: 0x060022E2 RID: 8930 RVA: 0x000D4A4C File Offset: 0x000D2C4C
        public new bool TryFindShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine)
        {
            if (targ.HasThing && targ.Thing.Map != this.Caster.Map)
            {
                resultingLine = default(ShootLine);
                return(false);
            }
            if (this.verbProps.IsMeleeAttack || this.EffectiveRange <= 1.42f)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(ReachabilityImmediate.CanReachImmediate(root, targ, this.Caster.Map, PathEndMode.Touch, null));
            }
            CellRect cellRect = targ.HasThing ? targ.Thing.OccupiedRect() : CellRect.SingleCell(targ.Cell);
            float    num      = this.verbProps.EffectiveMinRange(targ, this.Caster);
            float    num2     = cellRect.ClosestDistSquaredTo(root);

            if (num2 > this.EffectiveRange * this.EffectiveRange || num2 < num * num)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(false);
            }
            if (!this.verbProps.requireLineOfSight)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(true);
            }
            if (this.CasterIsPawn)
            {
                if (this.CanHitFromCellIgnoringRange(root, targ, out IntVec3 dest))
                {
                    resultingLine = new ShootLine(root, dest);
                    return(true);
                }
                ShootLeanUtility.LeanShootingSourcesFromTo(root, cellRect.ClosestCellTo(root), this.Caster.Map, Verb_ShootCompMountedCE.tempLeanShootSources);
                for (int i = 0; i < Verb_ShootCompMountedCE.tempLeanShootSources.Count; i++)
                {
                    IntVec3 intVec = Verb_ShootCompMountedCE.tempLeanShootSources[i];
                    if (this.CanHitFromCellIgnoringRange(intVec, targ, out dest))
                    {
                        resultingLine = new ShootLine(intVec, dest);
                        return(true);
                    }
                }
            }
            else
            {
                IntVec2 size = new IntVec2(Caster.def.size.x + 1, Caster.def.size.z + 1);
                foreach (IntVec3 intVec2 in GenAdj.OccupiedRect(Caster.Position, Caster.Rotation, size))
                {
                    if (this.CanHitFromCellIgnoringRange(intVec2, targ, out IntVec3 dest))
                    {
                        resultingLine = new ShootLine(intVec2, dest);
                        return(true);
                    }
                }
            }
            resultingLine = new ShootLine(root, targ.Cell);
            return(false);
        }
Exemple #8
0
        public bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine)
        {
            if (targ.HasThing && targ.Thing.Map != caster.Map)
            {
                resultingLine = default(ShootLine);
                return(false);
            }
            if (verbProps.range <= ShootTuning.MeleeRange) // If this verb has a MAX range up to melee range (NOT a MIN RANGE!)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(ReachabilityImmediate.CanReachImmediate(root, targ, caster.Map, PathEndMode.Touch, null));
            }
            CellRect cellRect = (!targ.HasThing) ? CellRect.SingleCell(targ.Cell) : targ.Thing.OccupiedRect();
            float    num      = cellRect.ClosestDistSquaredTo(root);

            if (num > verbProps.range * verbProps.range || num < verbProps.minRange * verbProps.minRange)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(false);
            }
            //if (!this.verbProps.NeedsLineOfSight) This method doesn't consider the currently loaded projectile
            if (Projectile.projectile.flyOverhead)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(true);
            }

            // First check current cell for early opt-out
            IntVec3 dest;
            var     shotSource = root.ToVector3Shifted();

            shotSource.y = ShotHeight;
            if (CanHitFromCellIgnoringRange(shotSource, targ, out dest))
            {
                resultingLine = new ShootLine(root, dest);
                return(true);
            }
            // For pawns, calculate possible lean locations
            if (CasterIsPawn)
            {
                // Next check lean sources
                ShootLeanUtility.LeanShootingSourcesFromTo(root, cellRect.ClosestCellTo(root), caster.Map, tempLeanShootSources);
                foreach (var leanLoc in tempLeanShootSources)
                {
                    var leanOffset = (leanLoc - root).ToVector3() * 0.5f;

                    if (CanHitFromCellIgnoringRange(shotSource + leanOffset, targ, out dest))
                    {
                        resultingLine = new ShootLine(leanLoc, dest);
                        return(true);
                    }
                }
            }

            resultingLine = new ShootLine(root, targ.Cell);
            return(false);
        }
        private bool CanHitFromCellIgnoringRange(IntVec3 sourceCell, LocalTargetInfo targ, out IntVec3 goodDest)
        {
            if (targ.Thing != null)
            {
                if (targ.Thing.Map != this.caster.Map)
                {
                    goodDest = IntVec3.Invalid;
                    return(false);
                }
                // (ProfoundDarkness) I only ever see this code execute for the target, not the shooter...
                // (ProfoundDarkness) I don't know what I'm doing here so basically if the target has a structure next to them assume they will lean, rather than a more precise and accurate
                // test.

                // If the target is near something they might have to lean around to shoot then calculate their leans.
                // NOTE: CellsAdjacent8Way includes the check for if a location is in map bounds so can use CanBeSeenOverFast.  The alternative is fast 8way and slow (bounds checking) CanBeSeenOver.
                if ((targ.Thing as Pawn)?.CurJob?.def != CE_JobDefOf.HunkerDown && GenAdjFast.AdjacentCells8Way(targ.Thing).FirstOrDefault(c => !c.CanBeSeenOver(targ.Thing.Map)) != null)
                {
                    ShootLeanUtility.CalcShootableCellsOf(tempDestList, targ.Thing);
                }
                else   // otherwise just assume that the target won't lean...
                {
                    tempDestList.Clear();
                    tempDestList.Add(targ.Cell);
                }

                for (int i = 0; i < tempDestList.Count; i++)
                {
                    if (this.CanHitCellFromCellIgnoringRange(sourceCell, tempDestList[i], targ.Thing, targ.Thing.def.Fillage == FillCategory.Full))
                    {   // if any of the locations the target is at or can lean to for shooting can be shot by the shooter then lets have the shooter shoot.
                        goodDest = tempDestList[i];
                        return(true);
                    }
                }
            }
            else if (this.CanHitCellFromCellIgnoringRange(sourceCell, targ.Cell, targ.Thing))
            {
                goodDest = targ.Cell;
                return(true);
            }
            goodDest = IntVec3.Invalid;
            return(false);
        }
Exemple #10
0
        public void AdjustForLeaning()
        {
            if (HasClearShotFrom(Origin))
            {
                return;
            }

            // If we got this far the shot is possible, but there is no straight LoS.
            // Must be shooting around a corner, so we need to use a different origin.
            var leaningPositions = new List <IntVec3>();

            ShootLeanUtility.LeanShootingSourcesFromTo(Origin, Target, CasterMap, leaningPositions);
            foreach (var leaningPosition in leaningPositions)
            {
                if (HasClearShotFrom(leaningPosition))
                {
                    Origin = leaningPosition;
                    return;
                }
            }
        }
 public bool CanHitTarget(LocalTargetInfo target)
 {
     if (def.royalAid.targetingRequireLOS && !GenSight.LineOfSight(caller.Position, target.Cell, map, skipFirstCell: true))
     {
         bool flag = false;
         ShootLeanUtility.LeanShootingSourcesFromTo(caller.Position, target.Cell, map, tempSourceList);
         for (int i = 0; i < tempSourceList.Count; i++)
         {
             if (GenSight.LineOfSight(tempSourceList[i], target.Cell, map, skipFirstCell: true))
             {
                 flag = true;
                 break;
             }
         }
         if (!flag)
         {
             return(false);
         }
     }
     return(true);
 }
Exemple #12
0
        public static bool HasLoSFromTo(IntVec3 root, LocalTargetInfo targ, Thing caster, float minRange, float maxRange)
        {
            float range = (targ.Cell - root).LengthHorizontal;

            if (targ.HasThing && targ.Thing.Map != caster.Map)
            {
                return(false);
            }
            if (range <= minRange || range >= maxRange)
            {
                return(false);
            }
            CellRect cellRect = (!targ.HasThing) ? CellRect.SingleCell(targ.Cell) : targ.Thing.OccupiedRect();

            if (caster is Pawn)
            {
                if (GenSight.LineOfSight(caster.Position, targ.Cell, caster.Map, skipFirstCell: true))
                {
                    return(true);
                }
                List <IntVec3> tempLeanShootSources = new List <IntVec3>();
                ShootLeanUtility.LeanShootingSourcesFromTo(root, cellRect.ClosestCellTo(root), caster.Map, tempLeanShootSources);
                for (int i = 0; i < tempLeanShootSources.Count; i++)
                {
                    IntVec3 intVec = tempLeanShootSources[i];
                    if (GenSight.LineOfSight(intVec, targ.Cell, caster.Map, skipFirstCell: true))
                    {
                        return(true);
                    }
                }
            }
            else
            {
                if (GenSight.LineOfSight(root, targ.Cell, caster.Map, skipFirstCell: true))
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #13
0
 public static bool CanSee(this Thing seer, Thing target, Func <IntVec3, bool> validator = null)
 {
     ShootLeanUtility.CalcShootableCellsOf(tempDestList, target);
     for (int i = 0; i < tempDestList.Count; i++)
     {
         if (GenSight.LineOfSight(seer.Position, tempDestList[i], seer.Map, skipFirstCell: true, validator))
         {
             return(true);
         }
     }
     ShootLeanUtility.LeanShootingSourcesFromTo(seer.Position, target.Position, seer.Map, tempSourceList);
     for (int j = 0; j < tempSourceList.Count; j++)
     {
         for (int k = 0; k < tempDestList.Count; k++)
         {
             if (GenSight.LineOfSight(tempSourceList[j], tempDestList[k], seer.Map, skipFirstCell: true, validator))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
 public static bool CanSee(this Thing seer, Thing target, Func <IntVec3, bool> validator = null)
 {
     //	Log.Messageage(seer+" CanSee "+ target+"?");
     ShootLeanUtility.CalcShootableCellsOf(tempDestList, target);
     for (int i = 0; i < tempDestList.Count; i++)
     {
         if (GenSight.LineOfSight(seer.Position, tempDestList[i], seer.Map, skipFirstCell: true, validator))
         {
             return(true);
         }
     }
     ShootLeanUtility.LeanShootingSourcesFromTo(seer.Position, target.Position, seer.Map, tempSourceList);
     if (seer is Building)
     {
         IntVec2 size = new IntVec2(seer.def.Size.x + 2, seer.def.Size.z + 2);
         foreach (IntVec3 intVec2 in GenAdj.OccupiedRect(seer.Position, seer.Rotation, size))
         {
             if (!tempSourceList.Contains(intVec2))
             {
                 tempSourceList.Add(intVec2);
             }
         }
     }
     for (int j = 0; j < tempSourceList.Count; j++)
     {
         for (int k = 0; k < tempDestList.Count; k++)
         {
             if (GenSight.LineOfSight(tempSourceList[j], tempDestList[k], seer.Map, skipFirstCell: true, validator))
             {
                 return(true);
             }
         }
     }
     //	Log.Messageage(seer + " CanSee " + target + ": FALSE");
     return(false);
 }
        /*
         * public bool CanSeeTarget(LocalTargetInfo targ)
         * {
         *  var glow = targ.Thing.Map.glowGrid.GameGlowAt(targ.Cell);
         *  var glowmultiplier = Mathf.Lerp(1, 5, Mathf.Clamp(glow * 5f, 0f, 1f));
         *
         *  float lengthToTarget = Mathf.Abs((targ.Cell - caster.Position).LengthHorizontal);
         *  if (targ.Thing.Map.glowGrid.GameGlowAt(targ.Cell) <= 0.2f)
         *  {
         *      Log.Message("target: " + targ.Thing +  " glow: " + glow.ToString() + " glowmult: " + glowmultiplier.ToString());
         *      if (lengthToTarget > glowmultiplier)
         *      {
         *          Log.Message("cant see: " + targ.Thing.ToString());
         *          return false;
         *      }
         *  }
         *  return true;
         * }
         */

        public bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine)
        {
            //    Log.Message("root: " + root.ToString() + " target: " + targ.Thing.ToString() + " pos: " + targ.Cell.ToString());
            if (targ.HasThing && targ.Thing.Map != this.caster.Map)
            {
                resultingLine = default(ShootLine);
                //        Log.Message("shootline false: 1" + " line: " + resultingLine.ToString());
                return(false);
            }
            //    Log.Message("effminrange: " + this.verbProps.EffectiveMinRange(targ, this.caster).ToString() + " meleerange: " + ShootTuning.MeleeRange);

            if (this.verbProps.IsMeleeAttack)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                var ri = ReachabilityImmediate.CanReachImmediate(root, targ, this.caster.Map, PathEndMode.Touch, null);
                //        Log.Message("ri: " + ri.ToString() + " line: " + resultingLine.ToString());
                return(ri);
            }

            CellRect cellRect = (!targ.HasThing) ? CellRect.SingleCell(targ.Cell) : targ.Thing.OccupiedRect();
            float    num      = cellRect.ClosestDistSquaredTo(root);

            if (num > this.verbProps.range * this.verbProps.range || num < this.verbProps.minRange * this.verbProps.minRange)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                //        Log.Message("shootline false: 2" + " line: " + resultingLine.ToString());
                return(false);
            }

            //if (!this.verbProps.NeedsLineOfSight) This method doesn't consider the currently loaded projectile
            if (Projectile.projectile.flyOverhead)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                //        Log.Message("shootline true: 3" + " line: " + resultingLine.ToString());
                return(true);
            }

            if (this.CasterIsPawn)
            {
                IntVec3 dest;
                ShootLeanUtility.LeanShootingSourcesFromTo(root, cellRect.ClosestCellTo(root), this.caster.Map, tempLeanShootSources);

                if (tempLeanShootSources.Count < 2)
                {
                    if (this.CanHitFromCellIgnoringRange(root, root, targ, out dest))
                    {
                        resultingLine = new ShootLine(root, dest);
                        //              Log.Message("shootline true: 4" + " line: " + resultingLine.ToString());
                        return(true);
                    }
                }

                if (tempLeanShootSources.Count >= 2)
                {
                    int bestZ    = 0;
                    int bestX    = 0;
                    int cachedbz = -1;
                    int cachedbx = -1;

                    //    Log.Message("pawn: " + CasterPawn.ToString() + " pawn pos: " + root.ToString() + " target: " + targ.Thing.ToString() + " target pos: " + targ.Cell.ToString());
                    foreach (var bsp in tempLeanShootSources)
                    {
                        var bz = Mathf.Abs(bsp.z - targ.Cell.z);
                        if (cachedbz < 0 || (bz < cachedbz))
                        {
                            cachedbz = bz;
                            bestZ    = bsp.z;
                        }

                        var bx = Mathf.Abs(bsp.x - targ.Cell.x);
                        if (cachedbx < 0 || (bx < cachedbx))
                        {
                            cachedbx = bx;
                            bestX    = bsp.x;
                        }
                    }
                    bestshootposition = new IntVec3(bestX, root.y, bestZ);
                    //    Log.Message("bestshootposition: " + bestshootposition.ToString());

                    if (this.CanHitFromCellIgnoringRange(bestshootposition, root, targ, out dest))
                    {
                        resultingLine = new ShootLine(bestshootposition, dest);
                        //        Log.Message("shootline true: 5" + " line: " + resultingLine.ToString());
                        return(true);
                    }
                }
                else
                {
                    for (int i = 0; i < tempLeanShootSources.Count; i++)
                    {
                        IntVec3 intVec = tempLeanShootSources[i];
                        if (this.CanHitFromCellIgnoringRange(intVec, root, targ, out dest))
                        {
                            resultingLine = new ShootLine(intVec, dest);
                            //            Log.Message("shootline true: 6" + " line: " + resultingLine.ToString());
                            return(true);
                        }
                    }
                }
            }
            else
            {
                CellRect.CellRectIterator iterator = this.caster.OccupiedRect().GetIterator();
                while (!iterator.Done())
                {
                    IntVec3 current = iterator.Current;
                    IntVec3 dest;
                    if (this.CanHitFromCellIgnoringRange(current, root, targ, out dest))
                    {
                        resultingLine = new ShootLine(current, dest);
                        //            Log.Message("shootline true: 7: " + " line: " + resultingLine.ToString());
                        return(true);
                    }
                    iterator.MoveNext();
                }
            }
            resultingLine = new ShootLine(root, targ.Cell);
            //    Log.Message("shootline false: 8" + " line: " + resultingLine.ToString());
            return(false);
        }
Exemple #16
0
        public static bool TryFindShootLineFromTo(Verb __instance, ref bool __result, IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine)
        {
            if (targ.HasThing && targ.Thing.Map != __instance.caster.Map)
            {
                resultingLine = default;
                __result      = false;
                return(false);
            }

            if (__instance.verbProps.IsMeleeAttack || __instance.verbProps.range <= 1.42f)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                __result      = ReachabilityImmediate.CanReachImmediate(root, targ, __instance.caster.Map, PathEndMode.Touch, null);
                return(false);
            }

            CellRect cellRect = targ.HasThing ? targ.Thing.OccupiedRect() : CellRect.SingleCell(targ.Cell);
            float    num      = __instance.verbProps.EffectiveMinRange(targ, __instance.caster);
            float    num2     = cellRect.ClosestDistSquaredTo(root);

            if (num2 > __instance.verbProps.range * __instance.verbProps.range || num2 < num * num)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                __result      = false;
                return(false);
            }

            if (!__instance.verbProps.requireLineOfSight)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                __result      = true;
                return(false);
            }

            IntVec3 goodDest;

            if (__instance.CasterIsPawn)
            {
                if (CanHitFromCellIgnoringRange2(__instance, root, targ, out goodDest))
                {
                    resultingLine = new ShootLine(root, goodDest);
                    __result      = true;
                    return(false);
                }
                List <IntVec3> tempLeanShootSources = new List <IntVec3>();                           //ADDED
                ShootLeanUtility.LeanShootingSourcesFromTo(
                    root, cellRect.ClosestCellTo(root), __instance.caster.Map, tempLeanShootSources); //CHANGED tempLeanShootSources
                for (int i = 0; i < tempLeanShootSources.Count; i++)                                  //CHANGED tempLeanShootSources
                {
                    IntVec3 intVec = tempLeanShootSources[i];                                         //CHANGED tempLeanShootSources
                    if (CanHitFromCellIgnoringRange2(__instance, intVec, targ, out goodDest))
                    {
                        resultingLine = new ShootLine(intVec, goodDest);
                        __result      = true;
                        return(false);
                    }
                }
            }
            else
            {
                foreach (IntVec3 item in __instance.caster.OccupiedRect())
                {
                    if (CanHitFromCellIgnoringRange2(__instance, item, targ, out goodDest))
                    {
                        resultingLine = new ShootLine(item, goodDest);
                        __result      = true;
                        return(false);
                    }
                }
            }

            resultingLine = new ShootLine(root, targ.Cell);
            __result      = false;
            return(false);
        }
        public new bool TryFindShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine)
        {
            //	Log.Message("Verb_MeleeAttackDamage_Polearm TryFindShootLineFromTo");
            if (targ.HasThing && targ.Thing.Map != this.caster.Map)
            {
                resultingLine = default(ShootLine);
                return(false);
            }

            /*
             * if (this.verbProps.IsMeleeAttack || this.EffectiveRange <= 1.42f)
             * {
             *      resultingLine = new ShootLine(root, targ.Cell);
             *
             *      return this.CanReachImmediate(root, targ, this.caster.Map, PathEndMode.Touch, null);
             * }
             */
            CellRect cellRect = targ.HasThing ? targ.Thing.OccupiedRect() : CellRect.SingleCell(targ.Cell);
            float    num      = this.verbProps.EffectiveMinRange(targ, this.caster);
            float    num2     = cellRect.ClosestDistSquaredTo(root);

            if (num2 > this.EffectiveRange * this.EffectiveRange || num2 < num * num)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(false);
            }
            if (!this.verbProps.requireLineOfSight)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(true);
            }
            if (this.CasterIsPawn)
            {
                if (this.CanHitFromCellIgnoringRange(root, targ, out IntVec3 dest))
                {
                    resultingLine = new ShootLine(root, dest);
                    return(true);
                }
                ShootLeanUtility.LeanShootingSourcesFromTo(root, cellRect.ClosestCellTo(root), this.caster.Map, Verb_MeleeAttackDamage_Polearm.tempLeanShootSources);
                for (int i = 0; i < Verb_MeleeAttackDamage_Polearm.tempLeanShootSources.Count; i++)
                {
                    IntVec3 intVec = Verb_MeleeAttackDamage_Polearm.tempLeanShootSources[i];
                    if (this.CanHitFromCellIgnoringRange(intVec, targ, out dest))
                    {
                        resultingLine = new ShootLine(intVec, dest);
                        return(true);
                    }
                }
            }
            else
            {
                foreach (IntVec3 intVec2 in this.caster.OccupiedRect())
                {
                    if (this.CanHitFromCellIgnoringRange(intVec2, targ, out IntVec3 dest))
                    {
                        resultingLine = new ShootLine(intVec2, dest);
                        return(true);
                    }
                }
            }
            resultingLine = new ShootLine(root, targ.Cell);
            return(false);
        }
        public bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine)
        {
            if (targ.HasThing && targ.Thing.Map != caster.Map)
            {
                resultingLine = default(ShootLine);
                return(false);
            }
            if (verbProps.range <= ShootTuning.MeleeRange) // If this verb has a MAX range up to melee range (NOT a MIN RANGE!)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(ReachabilityImmediate.CanReachImmediate(root, targ, caster.Map, PathEndMode.Touch, null));
            }
            CellRect cellRect = (!targ.HasThing) ? CellRect.SingleCell(targ.Cell) : targ.Thing.OccupiedRect();
            float    num      = cellRect.ClosestDistSquaredTo(root);

            if (num > verbProps.range * verbProps.range || num < verbProps.minRange * verbProps.minRange)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(false);
            }
            //if (!this.verbProps.NeedsLineOfSight) This method doesn't consider the currently loaded projectile
            if (Projectile.projectile.flyOverhead)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(true);
            }

            // First check current cell for early opt-out
            IntVec3 dest;
            var     shotSource = root.ToVector3Shifted();

            shotSource.y = ShotHeight;

            // Adjust for multi-tile turrets
            if (caster.def.building?.IsTurret ?? false)
            {
                shotSource = ShotSource;
            }

            if (CanHitFromCellIgnoringRange(shotSource, targ, out dest))
            {
                resultingLine = new ShootLine(root, dest);
                return(true);
            }

            // For pawns, calculate possible lean locations
            if (CasterIsPawn)
            {
                ShootLeanUtility.LeanShootingSourcesFromTo(root, cellRect.ClosestCellTo(root), caster.Map, tempLeanShootSources);
                foreach (var leanLoc in tempLeanShootSources.OrderBy(c => c.DistanceTo(targ.Cell)))
                {
                    var leanOffset = (leanLoc - root).ToVector3() * 0.51f;  //using exactly 0.5f makes it always round up, which causes issues if offset is negative, when adding leanOffset to shotSource. Setting to 0.51f to fix.
                    if (CanHitFromCellIgnoringRange(shotSource + leanOffset, targ, out dest))
                    {
                        resultingLine = new ShootLine(leanLoc, dest);
                        return(true);
                    }
                }
            }

            resultingLine = new ShootLine(root, targ.Cell);
            return(false);
        }
Exemple #19
0
        public bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine)
        {
            if (targ.HasThing && targ.Thing.Map != this.caster.Map)
            {
                resultingLine = default(ShootLine);
                return(false);
            }
            if (this.verbProps.range <= ShootTuning.MeleeRange) // If this verb has a MAX range up to melee range (NOT a MIN RANGE!)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(ReachabilityImmediate.CanReachImmediate(root, targ, this.caster.Map, PathEndMode.Touch, null));
            }
            CellRect cellRect = (!targ.HasThing) ? CellRect.SingleCell(targ.Cell) : targ.Thing.OccupiedRect();
            float    num      = cellRect.ClosestDistSquaredTo(root);

            if (num > this.verbProps.range * this.verbProps.range || num < this.verbProps.minRange * this.verbProps.minRange)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(false);
            }
            //if (!this.verbProps.NeedsLineOfSight) This method doesn't consider the currently loaded projectile
            if (Projectile.projectile.flyOverhead)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(true);
            }
            if (this.CasterIsPawn)
            {
                IntVec3 dest;
                if (this.CanHitFromCellIgnoringRange(root, targ, out dest))
                {
                    resultingLine = new ShootLine(root, dest);
                    return(true);
                }
                ShootLeanUtility.LeanShootingSourcesFromTo(root, cellRect.ClosestCellTo(root), this.caster.Map, tempLeanShootSources);
                for (int i = 0; i < tempLeanShootSources.Count; i++)
                {
                    IntVec3 intVec = tempLeanShootSources[i];
                    if (this.CanHitFromCellIgnoringRange(intVec, targ, out dest))
                    {
                        resultingLine = new ShootLine(intVec, dest);
                        return(true);
                    }
                }
            }
            else
            {
                CellRect.CellRectIterator iterator = this.caster.OccupiedRect().GetIterator();
                while (!iterator.Done())
                {
                    IntVec3 current = iterator.Current;
                    IntVec3 dest;
                    if (this.CanHitFromCellIgnoringRange(current, targ, out dest))
                    {
                        resultingLine = new ShootLine(current, dest);
                        return(true);
                    }
                    iterator.MoveNext();
                }
            }
            resultingLine = new ShootLine(root, targ.Cell);

            return(false);
        }