Exemple #1
0
 public float EffectiveMinRange(LocalTargetInfo target, Thing caster)
 {
     return(EffectiveMinRange(VerbUtility.AllowAdjacentShot(target, caster)));
 }
        private static void DoTablesInternalMelee(ThingDef stuff, bool doRaces = false)
        {
            Func <Def, float> meleeDamageGetter = delegate(Def d)
            {
                List <Verb> concreteExampleVerbs5 = VerbUtility.GetConcreteExampleVerbs(d, stuff);
                if (concreteExampleVerbs5.OfType <Verb_MeleeAttack>().Any())
                {
                    return(concreteExampleVerbs5.OfType <Verb_MeleeAttack>().AverageWeighted((Verb_MeleeAttack v) => v.verbProps.AdjustedMeleeSelectionWeight(v, null), (Verb_MeleeAttack v) => v.verbProps.AdjustedMeleeDamageAmount(v, null)));
                }
                return(-1f);
            };
            Func <Def, float> rangedDamageGetter = delegate(Def d)
            {
                List <Verb>           concreteExampleVerbs4 = VerbUtility.GetConcreteExampleVerbs(d, stuff);
                Verb_LaunchProjectile verb_LaunchProjectile = concreteExampleVerbs4.OfType <Verb_LaunchProjectile>().FirstOrDefault();
                if (verb_LaunchProjectile != null && verb_LaunchProjectile.GetProjectile() != null)
                {
                    return((float)verb_LaunchProjectile.GetProjectile().projectile.GetDamageAmount(null));
                }
                return(-1f);
            };
            Func <Def, float> rangedWarmupGetter = delegate(Def d)
            {
                List <Verb> concreteExampleVerbs3 = VerbUtility.GetConcreteExampleVerbs(d, stuff);
                return(concreteExampleVerbs3.OfType <Verb_LaunchProjectile>().FirstOrDefault()?.verbProps.warmupTime ?? (-1f));
            };
            Func <Def, float> meleeCooldownGetter = delegate(Def d)
            {
                List <Verb> concreteExampleVerbs2 = VerbUtility.GetConcreteExampleVerbs(d, stuff);
                if (concreteExampleVerbs2.OfType <Verb_MeleeAttack>().Any())
                {
                    return(concreteExampleVerbs2.OfType <Verb_MeleeAttack>().AverageWeighted((Verb_MeleeAttack v) => v.verbProps.AdjustedMeleeSelectionWeight(v, null), (Verb_MeleeAttack v) => v.verbProps.AdjustedCooldown(v, null)));
                }
                return(-1f);
            };
            Func <Def, float> rangedCooldownGetter = delegate(Def d)
            {
                List <Verb> concreteExampleVerbs = VerbUtility.GetConcreteExampleVerbs(d, stuff);
                return(concreteExampleVerbs.OfType <Verb_LaunchProjectile>().FirstOrDefault()?.verbProps.defaultCooldownTime ?? (-1f));
            };
            Func <Def, float> meleeDpsGetter    = (Def d) => meleeDamageGetter(d) * 0.82f / meleeCooldownGetter(d);
            Func <Def, float> marketValueGetter = delegate(Def d)
            {
                ThingDef thingDef3 = d as ThingDef;
                if (thingDef3 != null)
                {
                    return(thingDef3.GetStatValueAbstract(StatDefOf.MarketValue, stuff));
                }
                HediffDef hediffDef = d as HediffDef;
                if (hediffDef != null)
                {
                    if (hediffDef.spawnThingOnRemoved == null)
                    {
                        return(0f);
                    }
                    return(hediffDef.spawnThingOnRemoved.GetStatValueAbstract(StatDefOf.MarketValue));
                }
                return(-1f);
            };
            IEnumerable <Def> enumerable = (from d in DefDatabase <ThingDef> .AllDefs
                                            where d.IsWeapon
                                            select d).Cast <Def>().Concat((from h in DefDatabase <HediffDef> .AllDefs
                                                                           where h.CompProps <HediffCompProperties_VerbGiver>() != null
                                                                           select h).Cast <Def>());

            if (doRaces)
            {
                enumerable = enumerable.Concat((from d in DefDatabase <ThingDef> .AllDefs
                                                where d.race != null
                                                select d).Cast <Def>());
            }
            enumerable = from h in enumerable
                         orderby meleeDpsGetter(h) descending
                         select h;

            DebugTables.MakeTablesDialog(enumerable, new TableDataGetter <Def>("defName", (Def d) => d.defName), new TableDataGetter <Def>("melee\ndamage\naverage", (Def d) => meleeDamageGetter(d).ToString("F2")), new TableDataGetter <Def>("melee\ncooldown\naverage", (Def d) => meleeCooldownGetter(d).ToString("F2")), new TableDataGetter <Def>("melee\nDPS", (Def d) => meleeDpsGetter(d).ToString("F2")), new TableDataGetter <Def>("ranged\ndamage", (Def d) => rangedDamageGetter(d).ToString()), new TableDataGetter <Def>("ranged\nwarmup", (Def d) => rangedWarmupGetter(d).ToString("F2")), new TableDataGetter <Def>("ranged\ncooldown", (Def d) => rangedCooldownGetter(d).ToString("F2")), new TableDataGetter <Def>("market value", (Def d) => marketValueGetter(d).ToStringMoney()), new TableDataGetter <Def>("work to make", delegate(Def d)
            {
                ThingDef thingDef2 = d as ThingDef;
                if (thingDef2 == null)
                {
                    return("-");
                }
                return(thingDef2.GetStatValueAbstract(StatDefOf.WorkToMake, stuff).ToString("F0"));
            }), new TableDataGetter <Def>((stuff == null) ? "CanMake" : (stuff.defName + " CanMake"), delegate(Def d)
            {
                if (stuff == null)
                {
                    return("n/a");
                }
                ThingDef thingDef = d as ThingDef;
                if (thingDef == null)
                {
                    return("-");
                }
                return(stuff.stuffProps.CanMake(thingDef).ToStringCheckBlank());
            }), new TableDataGetter <Def>("assumed\nmelee\nhit chance", (Def d) => 0.82f.ToStringPercent()));
        }
        private void ImpactSomething()
        {
            if (def.projectile.flyOverhead)
            {
                RoofDef roofDef = base.Map.roofGrid.RoofAt(base.Position);
                if (roofDef != null)
                {
                    if (roofDef.isThickRoof)
                    {
                        ThrowDebugText("hit-thick-roof", base.Position);
                        def.projectile.soundHitThickRoof.PlayOneShot(new TargetInfo(base.Position, base.Map));
                        Destroy();
                        return;
                    }
                    if (base.Position.GetEdifice(base.Map) == null || base.Position.GetEdifice(base.Map).def.Fillage != FillCategory.Full)
                    {
                        RoofCollapserImmediate.DropRoofInCells(base.Position, base.Map);
                    }
                }
            }
            if (usedTarget.HasThing && CanHit(usedTarget.Thing))
            {
                Pawn pawn = usedTarget.Thing as Pawn;
                if (pawn != null && pawn.GetPosture() != 0 && (origin - destination).MagnitudeHorizontalSquared() >= 20.25f && !Rand.Chance(0.2f))
                {
                    ThrowDebugText("miss-laying", base.Position);
                    Impact(null);
                }
                else
                {
                    Impact(usedTarget.Thing);
                }
                return;
            }
            cellThingsFiltered.Clear();
            List <Thing> thingList = base.Position.GetThingList(base.Map);

            for (int i = 0; i < thingList.Count; i++)
            {
                Thing thing = thingList[i];
                if ((thing.def.category == ThingCategory.Building || thing.def.category == ThingCategory.Pawn || thing.def.category == ThingCategory.Item || thing.def.category == ThingCategory.Plant) && CanHit(thing))
                {
                    cellThingsFiltered.Add(thing);
                }
            }
            cellThingsFiltered.Shuffle();
            for (int j = 0; j < cellThingsFiltered.Count; j++)
            {
                Thing thing2 = cellThingsFiltered[j];
                Pawn  pawn2  = thing2 as Pawn;
                float num;
                if (pawn2 != null)
                {
                    num = 0.5f * Mathf.Clamp(pawn2.BodySize, 0.1f, 2f);
                    if (pawn2.GetPosture() != 0 && (origin - destination).MagnitudeHorizontalSquared() >= 20.25f)
                    {
                        num *= 0.2f;
                    }
                    if (launcher != null && pawn2.Faction != null && launcher.Faction != null && !pawn2.Faction.HostileTo(launcher.Faction))
                    {
                        num *= VerbUtility.InterceptChanceFactorFromDistance(origin, base.Position);
                    }
                }
                else
                {
                    num = 1.5f * thing2.def.fillPercent;
                }
                if (Rand.Chance(num))
                {
                    ThrowDebugText("hit-" + num.ToStringPercent(), base.Position);
                    Impact(cellThingsFiltered.RandomElement());
                    return;
                }
                ThrowDebugText("miss-" + num.ToStringPercent(), base.Position);
            }
            Impact(null);
        }
        private bool CheckForFreeIntercept(IntVec3 c)
        {
            if (destination.ToIntVec3() == c)
            {
                return(false);
            }
            float num = VerbUtility.InterceptChanceFactorFromDistance(origin, c);

            if (num <= 0f)
            {
                return(false);
            }
            bool         flag      = false;
            List <Thing> thingList = c.GetThingList(base.Map);

            for (int i = 0; i < thingList.Count; i++)
            {
                Thing thing = thingList[i];
                if (!CanHit(thing))
                {
                    continue;
                }
                bool flag2 = false;
                if (thing.def.Fillage == FillCategory.Full)
                {
                    Building_Door building_Door = thing as Building_Door;
                    if (building_Door == null || !building_Door.Open)
                    {
                        ThrowDebugText("int-wall", c);
                        Impact(thing);
                        return(true);
                    }
                    flag2 = true;
                }
                float num2 = 0f;
                Pawn  pawn = thing as Pawn;
                if (pawn != null)
                {
                    num2 = 0.4f * Mathf.Clamp(pawn.BodySize, 0.1f, 2f);
                    if (pawn.GetPosture() != 0)
                    {
                        num2 *= 0.1f;
                    }
                    if (launcher != null && pawn.Faction != null && launcher.Faction != null && !pawn.Faction.HostileTo(launcher.Faction))
                    {
                        num2 *= Find.Storyteller.difficultyValues.friendlyFireChanceFactor;
                    }
                }
                else if (thing.def.fillPercent > 0.2f)
                {
                    num2 = (flag2 ? 0.05f : ((!DestinationCell.AdjacentTo8Way(c)) ? (thing.def.fillPercent * 0.15f) : (thing.def.fillPercent * 1f)));
                }
                num2 *= num;
                if (num2 > 1E-05f)
                {
                    if (Rand.Chance(num2))
                    {
                        ThrowDebugText("int-" + num2.ToStringPercent(), c);
                        Impact(thing);
                        return(true);
                    }
                    flag = true;
                    ThrowDebugText(num2.ToStringPercent(), c);
                }
            }
            if (!flag)
            {
                ThrowDebugText("o", c);
            }
            return(false);
        }
        private bool CheckForFreeInterceptBetween(Vector3 lastExactPos, Vector3 newExactPos)
        {
            if (lastExactPos == newExactPos)
            {
                return(false);
            }
            List <Thing> list = base.Map.listerThings.ThingsInGroup(ThingRequestGroup.ProjectileInterceptor);

            for (int i = 0; i < list.Count; i++)
            {
                if (list[i].TryGetComp <CompProjectileInterceptor>().CheckIntercept(this, lastExactPos, newExactPos))
                {
                    Destroy();
                    return(true);
                }
            }
            IntVec3 intVec  = lastExactPos.ToIntVec3();
            IntVec3 intVec2 = newExactPos.ToIntVec3();

            if (intVec2 == intVec)
            {
                return(false);
            }
            if (!intVec.InBounds(base.Map) || !intVec2.InBounds(base.Map))
            {
                return(false);
            }
            if (intVec2.AdjacentToCardinal(intVec))
            {
                return(CheckForFreeIntercept(intVec2));
            }
            if (VerbUtility.InterceptChanceFactorFromDistance(origin, intVec2) <= 0f)
            {
                return(false);
            }
            Vector3 vect   = lastExactPos;
            Vector3 v      = newExactPos - lastExactPos;
            Vector3 vector = v.normalized * 0.2f;
            int     num    = (int)(v.MagnitudeHorizontal() / 0.2f);

            checkedCells.Clear();
            int     num2 = 0;
            IntVec3 intVec3;

            do
            {
                vect   += vector;
                intVec3 = vect.ToIntVec3();
                if (!checkedCells.Contains(intVec3))
                {
                    if (CheckForFreeIntercept(intVec3))
                    {
                        return(true);
                    }
                    checkedCells.Add(intVec3);
                }
                num2++;
                if (num2 > num)
                {
                    return(false);
                }
            }while (!(intVec3 == intVec2));
            return(false);
        }
        protected override bool TryCastShot()
        {
            if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map)
            {
                return(false);
            }
            ThingDef projectile = Projectile;

            if (projectile == null)
            {
                return(false);
            }
            ShootLine resultingLine;
            bool      flag = TryFindShootLineFromTo(caster.Position, currentTarget, out resultingLine);

            if (verbProps.stopBurstWithoutLos && !flag)
            {
                return(false);
            }
            if (base.EquipmentSource != null)
            {
                base.EquipmentSource.GetComp <CompChangeableProjectile>()?.Notify_ProjectileLaunched();
            }
            Thing        launcher     = caster;
            Thing        equipment    = base.EquipmentSource;
            CompMannable compMannable = caster.TryGetComp <CompMannable>();

            if (compMannable != null && compMannable.ManningPawn != null)
            {
                launcher  = compMannable.ManningPawn;
                equipment = caster;
            }
            Vector3    drawPos     = caster.DrawPos;
            Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, resultingLine.Source, caster.Map);

            if (verbProps.forcedMissRadius > 0.5f)
            {
                float num = VerbUtility.CalculateAdjustedForcedMiss(verbProps.forcedMissRadius, currentTarget.Cell - caster.Position);
                if (num > 0.5f)
                {
                    int max  = GenRadial.NumCellsInRadius(num);
                    int num2 = Rand.Range(0, max);
                    if (num2 > 0)
                    {
                        IntVec3 c = currentTarget.Cell + GenRadial.RadialPattern[num2];
                        ThrowDebugText("ToRadius");
                        ThrowDebugText("Rad\nDest", c);
                        ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld;
                        if (Rand.Chance(0.5f))
                        {
                            projectileHitFlags = ProjectileHitFlags.All;
                        }
                        if (!canHitNonTargetPawnsNow)
                        {
                            projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns;
                        }
                        projectile2.Launch(launcher, drawPos, c, currentTarget, projectileHitFlags, equipment);
                        return(true);
                    }
                }
            }
            ShotReport shotReport            = ShotReport.HitReportFor(caster, this, currentTarget);
            Thing      randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
            ThingDef   targetCoverDef        = randomCoverToMissInto?.def;

            if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture))
            {
                resultingLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget);
                ThrowDebugText("ToWild" + ((!canHitNonTargetPawnsNow) ? string.Empty : "\nchntp"));
                ThrowDebugText("Wild\nDest", resultingLine.Dest);
                ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld;
                if (Rand.Chance(0.5f) && canHitNonTargetPawnsNow)
                {
                    projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns;
                }
                projectile2.Launch(launcher, drawPos, resultingLine.Dest, currentTarget, projectileHitFlags2, equipment, targetCoverDef);
                return(true);
            }
            if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance))
            {
                ThrowDebugText("ToCover" + ((!canHitNonTargetPawnsNow) ? string.Empty : "\nchntp"));
                ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position);
                ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld;
                if (canHitNonTargetPawnsNow)
                {
                    projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns;
                }
                projectile2.Launch(launcher, drawPos, randomCoverToMissInto, currentTarget, projectileHitFlags3, equipment, targetCoverDef);
                return(true);
            }
            ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget;

            if (canHitNonTargetPawnsNow)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns;
            }
            if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld;
            }
            ThrowDebugText("ToHit" + ((!canHitNonTargetPawnsNow) ? string.Empty : "\nchntp"));
            if (currentTarget.Thing != null)
            {
                projectile2.Launch(launcher, drawPos, currentTarget, currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                ThrowDebugText("Hit\nDest", currentTarget.Cell);
            }
            else
            {
                projectile2.Launch(launcher, drawPos, resultingLine.Dest, currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                ThrowDebugText("Hit\nDest", resultingLine.Dest);
            }
            return(true);
        }