예제 #1
0
        private static float GetAccuracy(Thing weapon, VerbProperties verb, ProjectileProperties projectile, float dist, Pawn pawn = null)
        {
            float forcedMissRadius = CalculateAdjustedForcedMissDist(verb.ForcedMissRadius, dist);
            float baseAimOn        = verb.GetHitChanceFactor(weapon, dist);

            if (pawn != null)
            {
                baseAimOn *= ShotReport.HitFactorFromShooter(pawn, dist);
            }
            int affectedCellCount = (verb.CausesExplosion) ? GenRadial.NumCellsInRadius(projectile.explosionRadius) : 1;

            float accuracy;

            if (forcedMissRadius > 0.5f)
            {
                int affectableCellCount = GenRadial.NumCellsInRadius(forcedMissRadius);
                accuracy = (float)affectedCellCount / affectableCellCount;
            }
            else
            {
                float medianToWildRadius = ShootTuning.MissDistanceFromAimOnChanceCurves.Evaluate(baseAimOn, 0.5f);
                float indirectHitChance  = (float)(affectedCellCount - 1) / GenRadial.NumCellsInRadius(medianToWildRadius);
                accuracy = baseAimOn + (1f - baseAimOn) * indirectHitChance;
            }
            return(Mathf.Clamp01(accuracy));
        }
예제 #2
0
        private static float VerbScore(Pawn p, Verb verb, LocalTargetInfo target, bool debug = false)
        {
            if (debug)
            {
                Log.Message("Getting score of " + verb + " with target " + target);
            }
            if (verb is IVerbScore score)
            {
                return(score.GetScore(p, target));
            }
            var accuracy = 0f;

            if (p.Map != null)
            {
                accuracy = ShotReport.HitReportFor(p, verb, target).TotalEstimatedHitChance;
            }
            else if (verb.TryFindShootLineFromTo(p.Position, target, out var line))
            {
                accuracy = verb.verbProps.GetHitChanceFactor(verb.EquipmentSource,
                                                             p.Position.DistanceTo(target.Cell));
            }

            var damage    = accuracy * verb.verbProps.burstShotCount * GetDamage(verb);
            var timeSpent = verb.verbProps.AdjustedCooldownTicks(verb, p) + verb.verbProps.warmupTime.SecondsToTicks();

            if (debug)
            {
                Log.Message("Accuracy: " + accuracy);
                Log.Message("Damage: " + damage);
                Log.Message("timeSpent: " + timeSpent);
                Log.Message("Score of " + verb + " on target " + target + " is " + damage / timeSpent);
            }

            return(damage / timeSpent);
        }
예제 #3
0
        public static bool ShotCalculationTipStringPrefix(ref string __result, Thing target)
        {
            StringBuilder stringBuilder = new StringBuilder();

            if (Find.Selector.SingleSelectedThing != null)
            {
                Thing singleSelectedThing = Find.Selector.SingleSelectedThing;
                Verb  verb = null;
                Pawn  pawn = singleSelectedThing as Pawn;
                if (pawn != null && pawn != target && pawn.equipment != null && pawn.equipment.Primary != null)
                {
                    Comp_VerbSaveable compsav = pawn.equipment.Primary.GetComp <Comp_VerbSaveable>();
                    if (compsav != null && compsav.tempVerb != null && compsav.tempVerb is Verb_LaunchProjectile)
                    {
                        verb = compsav.tempVerb;
                    }
                    else
                    {
                        verb = pawn.equipment.PrimaryEq.PrimaryVerb;
                    }
                }
                Building_TurretGun building_TurretGun = singleSelectedThing as Building_TurretGun;
                if (building_TurretGun != null && building_TurretGun != target)
                {
                    verb = building_TurretGun.AttackVerb;
                }
                if (verb != null)
                {
                    stringBuilder.Append("ShotBy".Translate(Find.Selector.SingleSelectedThing.LabelShort, Find.Selector.SingleSelectedThing) + ": ");
                    if (verb.CanHitTarget(target))
                    {
                        stringBuilder.Append(ShotReport.HitReportFor(verb.caster, verb, target).GetTextReadout());
                    }
                    else
                    {
                        stringBuilder.AppendLine("CannotHit".Translate());
                    }
                    Pawn pawn2 = target as Pawn;
                    if (pawn2 != null && pawn2.Faction == null && !pawn2.InAggroMentalState)
                    {
                        float manhunterOnDamageChance;
                        if (verb.IsMeleeAttack)
                        {
                            manhunterOnDamageChance = PawnUtility.GetManhunterOnDamageChance(pawn2, 0f, singleSelectedThing);
                        }
                        else
                        {
                            manhunterOnDamageChance = PawnUtility.GetManhunterOnDamageChance(pawn2, singleSelectedThing);
                        }
                        if (manhunterOnDamageChance > 0f)
                        {
                            stringBuilder.AppendLine();
                            stringBuilder.AppendLine(string.Format("{0}: {1}", "ManhunterPerHit".Translate(), manhunterOnDamageChance.ToStringPercent()));
                        }
                    }
                }
            }
            __result = stringBuilder.ToString();
            return(false);
        }
            public static void Prefix(ref ShotReport __result, Thing caster, Verb verb, LocalTargetInfo target)
            {
                var projectileClass = verb.GetProjectile()?.thingClass;

                if (projectileClass != null && typeof(TeslaProjectile).IsAssignableFrom(projectileClass))
                {
                    accuracy = true;
                }
            }
        // Token: 0x06002252 RID: 8786 RVA: 0x000D128C File Offset: 0x000CF48C
        protected override bool TryCastShot()
        {
            if (this.currentTarget.HasThing && this.currentTarget.Thing.Map != this.caster.Map)
            {
                return(false);
            }
            ThingDef projectile = this.Projectile;

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

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

            if (compMannable != null && compMannable.ManningPawn != null)
            {
                launcher  = compMannable.ManningPawn;
                equipment = this.caster;
            }
            Vector3            drawPos               = this.caster.DrawPos;
            Projectile         projectile2           = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, this.caster.Map, WipeMode.Vanish);
            ShotReport         shotReport            = ShotReport.HitReportFor(this.caster, this, this.currentTarget);
            Thing              randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
            ThingDef           targetCoverDef        = (randomCoverToMissInto != null) ? randomCoverToMissInto.def : null;
            ProjectileHitFlags projectileHitFlags4   = ProjectileHitFlags.IntendedTarget;

            this.ThrowDebugText("ToHit" + (this.canHitNonTargetPawnsNow ? "\nchntp" : ""));
            if (this.currentTarget.Thing != null)
            {
                projectile2.Launch(launcher, drawPos, this.currentTarget, this.currentTarget, projectileHitFlags4, false, equipment, targetCoverDef);
                this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell);
            }
            else
            {
                projectile2.Launch(launcher, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags4, false, equipment, targetCoverDef);
                this.ThrowDebugText("Hit\nDest", shootLine.Dest);
            }
            return(true);
        }
        /// <summary>
        /// Gets the adjusted hit chance factor of a shot.  This is equivalent to shootVerb.GetHitChanceFactor() unless
        /// a shooter is provided, in which case it will also be adjusted based on the shooter's hit chance.
        ///
        /// This value can be greater than 1.0 in the case of weapons with overcapped accuracy.
        /// </summary>
        /// <returns>The adjusted hit chance factor.</returns>
        /// <param name="range">The range of the shot.</param>
        /// <param name="shooter">(Optional) The turret or pawn shooting the weapon.</param>
        public float GetAdjustedHitChanceFactor(float range, Thing shooter = null)
        {
            float hitChance = shootVerb.GetHitChanceFactor(weapon, range);

            if (shooter != null)
            {
                hitChance *= ShotReport.HitFactorFromShooter(shooter, range);
            }

            return(hitChance);
        }
예제 #7
0
파일: PawnVerbUtility.cs 프로젝트: Ecu/MVCF
        private static float VerbScore(Pawn p, Verb verb, LocalTargetInfo target, bool debug = false)
        {
            if (debug)
            {
                Log.Message("Getting score of " + verb + " with target " + target);
            }
            var report    = ShotReport.HitReportFor(p, verb, target);
            var damage    = report.TotalEstimatedHitChance * verb.verbProps.burstShotCount * GetDamage(verb);
            var timeSpent = verb.verbProps.AdjustedCooldownTicks(verb, p) + verb.verbProps.warmupTime.SecondsToTicks();

            return(damage / timeSpent);
        }
예제 #8
0
        public override string GetExplanationFinalizePart(StatRequest req, ToStringNumberSense numberSense, float finalVal)
        {
            StringBuilder stringBuilder = new StringBuilder();

            for (int i = 5; i <= 45; i += 5)
            {
                float f = ShotReport.HitFactorFromShooter(finalVal, i);
                stringBuilder.AppendLine("distance".Translate().CapitalizeFirst() + " " + i.ToString() + ": " + f.ToStringPercent("F1"));
            }
            stringBuilder.AppendLine(base.GetExplanationFinalizePart(req, numberSense, finalVal));
            return(stringBuilder.ToString());
        }
        public static void HitReportFor_Postfix(
            ref ShotReport __result,
            Thing caster,
            Verb verb,
            LocalTargetInfo target
            )
        {
            if (caster is Pawn pawn && pawn.TryGetComp <Comp_NightVision>() is Comp_NightVision comp)
            {
                CurrentShot.Caster = caster;
                CurrentShot.Verb   = verb;

                CurrentShot.GlowFactor = CombatHelpers.GlowFactorForPawnAtTarget(pawn, target, comp);
            }
예제 #10
0
        private static float FriendlyFireConeTargetScoreOffset(
            IAttackTarget target,
            IAttackTargetSearcher searcher,
            Verb verb)
        {
            if (!(searcher.Thing is Pawn thing) || thing.RaceProps.intelligence < Intelligence.ToolUser || (thing.RaceProps.IsMechanoid || !(verb is Verb_Shoot verbShoot)))
            {
                return(0.0f);
            }
            ThingDef defaultProjectile = verbShoot.verbProps.defaultProjectile;

            if (defaultProjectile == null || defaultProjectile.projectile.flyOverhead)
            {
                return(0.0f);
            }
            Map        map              = thing.Map;
            ShotReport report           = ShotReport.HitReportFor((Thing)thing, verb, (LocalTargetInfo)(Thing)target);
            double     forcedMissRadius = (double)verb.verbProps.forcedMissRadius;
            IntVec3    dest1            = report.ShootLine.Dest;
            ShootLine  shootLine        = report.ShootLine;
            IntVec3    source           = shootLine.Source;
            IntVec3    vector           = dest1 - source;
            float      radius           = Mathf.Max(VerbUtility.CalculateAdjustedForcedMiss((float)forcedMissRadius, vector), 1.5f);

            shootLine = report.ShootLine;
            IEnumerable <IntVec3> intVec3s = GenRadial.RadialCellsAround(shootLine.Dest, radius, true).Where <IntVec3>((Func <IntVec3, bool>)(dest => dest.InBounds(map))).Select <IntVec3, ShootLine>((Func <IntVec3, ShootLine>)(dest => new ShootLine(report.ShootLine.Source, dest))).SelectMany <ShootLine, IntVec3>((Func <ShootLine, IEnumerable <IntVec3> >)(line => line.Points().Concat <IntVec3>(line.Dest).TakeWhile <IntVec3>((Func <IntVec3, bool>)(pos => pos.CanBeSeenOverFast(map))))).Distinct <IntVec3>();
            float num1 = 0.0f;

            foreach (IntVec3 c in intVec3s)
            {
                shootLine = report.ShootLine;
                float num2 = VerbUtility.InterceptChanceFactorFromDistance(shootLine.Source.ToVector3Shifted(), c);
                if ((double)num2 > 0.0)
                {
                    List <Thing> thingList = c.GetThingList(map);
                    for (int index = 0; index < thingList.Count; ++index)
                    {
                        Thing b = thingList[index];
                        if (b is IAttackTarget && b != target)
                        {
                            float num3 = (b != searcher ? (!(b is Pawn) ? 10f : (b.def.race.Animal ? 7f : 18f)) : 40f) * num2;
                            float num4 = !searcher.Thing.HostileTo(b) ? num3 * -1f : num3 * 0.6f;
                            num1 += num4;
                        }
                    }
                }
            }
            return(num1);
        }
예제 #11
0
        public float GetAimOnTargetChance()
        {
            var distance = (Target - Origin).LengthHorizontal;

            var factorFromShooterAndDist = ShotReport.HitFactorFromShooter(Caster, distance);

            var factorFromEquipment = _weaponVerb.verbProps.GetHitChanceFactor(
                _weaponVerb.EquipmentSource, distance);

            var factorFromWeather = 1f;

            if (!Caster.Position.Roofed(CasterMap) || !Target.Roofed(CasterMap))
            {
                factorFromWeather = CasterMap.weatherManager.CurWeatherAccuracyMultiplier;
            }

            ThingDef coveringGas = null;

            foreach (var point in GenSight.PointsOnLineOfSight(Origin, Target))
            {
                if (!point.CanBeSeenOver(CasterMap))
                {
                    break;
                }

                Thing gas = point.GetGas(CasterMap);
                if (IsThisGasMorePenalisingThan(gas, coveringGas))
                {
                    coveringGas = gas.def;
                }
            }

            var factorFromCoveringGas = 1f - (coveringGas?.gas.accuracyPenalty ?? 0f);

            var result = factorFromShooterAndDist * factorFromEquipment * factorFromWeather *
                         factorFromCoveringGas;

            if (result < 0.0201f)
            {
                result = 0.0201f;
            }

            return(result);
        }
예제 #12
0
        public override float GetValueUnfinalized(StatRequest req, bool applyPostProcess = true)
        {
            if (!(req.Def is ThingDef def))
            {
                return(0.0f);
            }

            CompEquippable         equipComp = null;
            CompLootAffixableThing lootComp  = null;

            if (req.HasThing)
            {
                var thing = (ThingWithComps)req.Thing;
                equipComp = thing.TryGetComp <CompEquippable>();
                lootComp  = thing.TryGetComp <CompLootAffixableThing>();
            }

            Verb           verb      = equipComp?.AllVerbs.First(v => v.verbProps.isPrimary);
            VerbProperties verbProps = verb != null ? verb.verbProps : def.Verbs.First(vp => vp.isPrimary);
            Pawn           attacker  = req.HasThing ? GetCurrentWeaponUser(req.Thing) : null;
            var            projProps = verbProps.defaultProjectile.projectile;

            var projModifier = (LootAffixModifier_VerbPropertiesChange_Def)lootComp?.AllModifiers.FirstOrFallback(
                lam => lam.AppliesTo == ModifierTarget.VerbProperties && lam is LootAffixModifier_VerbPropertiesChange_Def lamVPCD && lamVPCD.affectedField == "defaultProjectile"
                );
            ThingDef modProjectile = projModifier != null ? (ThingDef)projModifier.resolvedDef : null;
            var      modProjProps  = modProjectile?.projectile;

            float chance = modProjProps != null ? 1f - projModifier.GetRealChance(lootComp.parent) : 1f;

            if (chance <= 0.05f)
            {
                chance = 1f;                   // already permanently set to "base" verbProps
            }
            float baseDamage =
                projProps.damageDef.harmsHealth == false ? 0f :
                req.HasThing         ? projProps.GetDamageAmount(req.Thing) :
                req.StuffDef != null?projProps.GetDamageAmount(def.GetStatValueAbstract(StatDefOf.RangedWeapon_DamageMultiplier, req.StuffDef)) :
                    projProps.GetDamageAmount(def.GetStatValueAbstract(StatDefOf.RangedWeapon_DamageMultiplier))
            ;

            float damage = baseDamage * verbProps.burstShotCount * chance;

            if (chance < 1f)
            {
                float modChance     = 1f - chance;
                float modBaseDamage =
                    modProjProps.damageDef.harmsHealth == false ? 0f :
                    modProjProps.GetDamageAmount(req.Thing)
                ;

                damage += modBaseDamage * verbProps.burstShotCount * modChance;
            }

            // FIXME: Confirm warmupTime (and AimingDelayFactor) is used in a full shot cycle
            // FIXME: warmupTime * this.CasterPawn.GetStatValue(StatDefOf.AimingDelayFactor, true)).SecondsToTicks()
            float secondsSpent = 0;

            if (verb != null)
            {
                secondsSpent = verbProps.AdjustedFullCycleTime(verb, attacker);
            }
            else
            {
                secondsSpent  = verbProps.warmupTime + ((verbProps.burstShotCount - 1) * verbProps.ticksBetweenBurstShots).TicksToSeconds();
                secondsSpent +=
                    req.HasThing         ? req.Thing.GetStatValue(StatDefOf.RangedWeapon_Cooldown, true) :
                    req.StuffDef != null?def.GetStatValueAbstract(StatDefOf.RangedWeapon_Cooldown, req.StuffDef) :
                        def.GetStatValueAbstract(StatDefOf.RangedWeapon_Cooldown)
                ;
            }

            // Every integer range possible as an average
            float avgAccuracy = 0;

            for (int i = 3; i <= verbProps.range; i++)
            {
                float rngAccuracy = verbProps.GetHitChanceFactor(req.Thing, i);
                if (attacker != null)
                {
                    rngAccuracy *= ShotReport.HitFactorFromShooter(attacker, i);
                }
                avgAccuracy += rngAccuracy;
            }
            if (verbProps.range >= 3)
            {
                avgAccuracy /= verbProps.range - 2;
            }

            return(secondsSpent == 0 ? 0.0f : damage / secondsSpent * avgAccuracy);
        }
예제 #13
0
        public bool TryCastShot_V1Vanilla_Modified()
        {
            if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map)
            {
                return(false);
            }
            var flag = TryFindShootLineFromTo(caster.Position, currentTarget, out var shootLine);

            if (verbProps.stopBurstWithoutLos && !flag)
            {
                return(false);
            }
            var drawPos    = caster.DrawPos;
            var projectile = (Projectile)GenSpawn.Spawn(verbProps.defaultProjectile, shootLine.Source, caster.Map);

            ///MODIFIED SECTION
            ////////////////////////////////////////////

            if (lastShotReflected)
            {
                ////Log.Message("lastShotReflected Called");
                projectile.Launch(caster, currentTarget, currentTarget, ProjectileHitFlags.IntendedTarget, preventFriendlyFire, EquipmentSource);
                return(true);
            }

            ////////////////////////////////////////////
            //

            //projectile.FreeIntercept = canFreeInterceptNow && !projectile.def.projectile.flyOverhead;
            var forcedMissRadius = verbProps.ForcedMissRadius;

            if (forcedMissRadius > 0.5f)
            {
                var num = VerbUtility.CalculateAdjustedForcedMiss(forcedMissRadius,
                                                                  currentTarget.Cell - caster.Position);
                if (num > 0.5f)
                {
                    var max  = GenRadial.NumCellsInRadius(forcedMissRadius);
                    var num2 = Rand.Range(0, max);
                    if (num2 > 0)
                    {
                        if (DebugViewSettings.drawShooting)
                        {
                            MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToForRad"); // TODO: Translate()?
                        }
                        var c = currentTarget.Cell + GenRadial.RadialPattern[num2];
                        ProjectileHitFlags projectileHitFlags;
                        if (Rand.Chance(0.5f))
                        {
                            projectileHitFlags = ProjectileHitFlags.NonTargetWorld;
                        }
                        else
                        {
                            projectileHitFlags = ProjectileHitFlags.All;
                        }
                        if (!canHitNonTargetPawnsNow)
                        {
                            projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns;
                        }
                        projectile.Launch(caster, currentTarget, c, projectileHitFlags, preventFriendlyFire, EquipmentSource);
                        return(true);
                    }
                }
            }
            var shotReport            = ShotReport.HitReportFor(caster, this, currentTarget);
            var randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
            var targetCoverDef        = randomCoverToMissInto?.def;

            if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture))
            {
                if (DebugViewSettings.drawShooting)
                {
                    MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToWild"); // TODO: Translate()?
                }
                shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget);
                ProjectileHitFlags projectileHitFlags2;
                if (Rand.Chance(0.5f))
                {
                    projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld;
                }
                else
                {
                    projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld;
                    if (canHitNonTargetPawnsNow)
                    {
                        projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns;
                    }
                }
                projectile.Launch(caster, currentTarget, shootLine.Dest, projectileHitFlags2,
                                  preventFriendlyFire, EquipmentSource);
                return(true);
            }
            if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance))
            {
                if (DebugViewSettings.drawShooting)
                {
                    MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToCover"); // TODO: Translate()?
                }
                if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn)
                {
                    var projectileHitFlags5 = ProjectileHitFlags.NonTargetWorld;
                    if (canHitNonTargetPawnsNow)
                    {
                        projectileHitFlags5 |= ProjectileHitFlags.NonTargetPawns;
                    }
                    projectile.Launch(caster, currentTarget, randomCoverToMissInto, projectileHitFlags5,
                                      preventFriendlyFire, EquipmentSource);
                    return(true);
                }
            }
            else
            {
                if (!Rand.Chance(shotReport.PassCoverChance))
                {
                    if (DebugViewSettings.drawShooting)
                    {
                        MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToCover"); // TODO: Translate()?
                    }
                    if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn)
                    {
                        var projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld;
                        if (canHitNonTargetPawnsNow)
                        {
                            projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns;
                        }
                        projectile.Launch(caster, drawPos, randomCoverToMissInto, currentTarget,
                                          projectileHitFlags3, preventFriendlyFire, EquipmentSource, targetCoverDef);
                        return(true);
                    }
                }
                if (DebugViewSettings.drawShooting)
                {
                    MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToHit"); // TODO: Translate()?
                }
                var projectileHitFlags4 = ProjectileHitFlags.IntendedTarget;
                if (canHitNonTargetPawnsNow)
                {
                    projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns;
                }
                if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full)
                {
                    projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld;
                }
                if (currentTarget.Thing != null)
                {
                    projectile.Launch(caster, drawPos, currentTarget, currentTarget, projectileHitFlags4,
                                      preventFriendlyFire, EquipmentSource, targetCoverDef);
                }
                else
                {
                    projectile.Launch(caster, drawPos, shootLine.Dest, currentTarget, projectileHitFlags4,
                                      preventFriendlyFire, EquipmentSource, targetCoverDef);
                }
                return(true);
            }
            return(false);
        }
예제 #14
0
        // Token: 0x0600640C RID: 25612 RVA: 0x001B4770 File Offset: 0x001B2B70
        protected override bool TryCastShot()
        {
            if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map)
            {
                return(false);
            }

            var shootLine = new ShootLine();

            if (verbProps.stopBurstWithoutLos && !TryFindShootLineFromTo(caster.Position, currentTarget, out shootLine))
            {
                return(false);
            }

            var comp = EquipmentSource?.GetComp <CompChangeableProjectile>();

            comp?.Notify_ProjectileLaunched();

            var compMannable = caster.TryGetComp <CompMannable>();

            if (compMannable?.ManningPawn != null)
            {
            }


            SpawnBeam();
            hitThing();


            var shotReport            = ShotReport.HitReportFor(caster, this, currentTarget);
            var randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
            var unused = randomCoverToMissInto?.def;

            if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture))
            {
                shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget);

                var nonTargetWorld = ProjectileHitFlags.NonTargetWorld;
                if (Rand.Chance(0.5f) && canHitNonTargetPawnsNow)
                {
                    nonTargetWorld |= ProjectileHitFlags.NonTargetPawns;
                }

                return(true);
            }

            if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn &&
                !Rand.Chance(shotReport.PassCoverChance))
            {
                var projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld;
                if (canHitNonTargetPawnsNow)
                {
                    projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns;
                }

                return(true);
            }


            var projectileHitFlags4 = ProjectileHitFlags.IntendedTarget;

            if (canHitNonTargetPawnsNow)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns;
            }

            if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld;
            }

            return(true);
        }
예제 #15
0
        internal static string ShotCalculationTipString(Thing target)
        {
            StringBuilder stringBuilder = new StringBuilder();

            if (Find.Selector.SingleSelectedThing != null)
            {
                Verb verb   = null;
                Verb verbCR = null;
                Pawn pawn   = Find.Selector.SingleSelectedThing as Pawn;
                if (pawn != null && pawn != target && pawn.equipment != null && pawn.equipment.Primary != null && pawn.equipment.PrimaryEq.PrimaryVerb is Verb_LaunchProjectile)
                {
                    verb = pawn.equipment.PrimaryEq.PrimaryVerb;
                }
                Building_TurretGun building_TurretGun = Find.Selector.SingleSelectedThing as Building_TurretGun;
                if (building_TurretGun != null && building_TurretGun != target)
                {
                    verb = building_TurretGun.AttackVerb;
                }
                if (verb != null)
                {
                    stringBuilder.AppendLine();
                    stringBuilder.Append("ShotBy".Translate(new object[]
                    {
                        Find.Selector.SingleSelectedThing.LabelShort
                    }) + ": ");
                    if (verb.CanHitTarget(target))
                    {
                        stringBuilder.Append(ShotReport.HitReportFor(verb.caster, verb, target).GetTextReadout());
                    }
                    else
                    {
                        stringBuilder.Append("CannotHit".Translate());
                    }
                }
                // Append CR tooltip
                else
                {
                    if (pawn != null && pawn != target && pawn.equipment != null &&
                        pawn.equipment.Primary != null && pawn.equipment.PrimaryEq.PrimaryVerb is Verb_LaunchProjectileCR)
                    {
                        verbCR = pawn.equipment.PrimaryEq.PrimaryVerb;
                    }
                    Building_TurretGun building_TurretGun2 = Find.Selector.SingleSelectedThing as Building_TurretGun;
                    if (building_TurretGun != null && building_TurretGun != target)
                    {
                        verbCR = building_TurretGun.AttackVerb;
                    }
                    if (verbCR != null)
                    {
                        stringBuilder.AppendLine();
                        //   stringBuilder.Append("ShotBy".Translate(new object[] { pawn.LabelShort }) + ":\n");
                        stringBuilder.Append("Shot stat. temporarily unavailable!");
                        if (verbCR.CanHitTarget(target))
                        {
                            //       stringBuilder.Append(ShiftVecReportFor(target).GetTextReadout());
                        }
                        else
                        {
                            stringBuilder.Append("CannotHit".Translate());
                        }
                    }
                }
            }
            return(stringBuilder.ToString());
        }
        protected new bool?TryLaunchProjectile(ThingDef projectileDef, LocalTargetInfo launchTarget)
        {
            ShootLine shootLine;
            bool      flag  = base.TryFindShootLineFromTo(this.caster.Position, launchTarget, out shootLine);
            bool      flag2 = this.verbProps.stopBurstWithoutLos && !flag;
            bool?     result;

            if (flag2)
            {
                result = new bool?(false);
            }
            else
            {
                Vector3    drawPos    = this.caster.DrawPos;
                Projectile projectile = (Projectile)GenSpawn.Spawn(projectileDef, shootLine.Source, this.caster.Map, WipeMode.Vanish);
                SoundDef   soundCast  = this.verbProps.soundCast;
                if (soundCast != null)
                {
                    soundCast.PlayOneShot(new TargetInfo(this.caster.Position, this.caster.Map, false));
                }
                SoundDef soundCastTail = this.verbProps.soundCastTail;
                if (soundCastTail != null)
                {
                    soundCastTail.PlayOneShotOnCamera(null);
                }
                bool drawShooting = DebugViewSettings.drawShooting;
                if (drawShooting)
                {
                    MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToHit", -1f);
                }
                ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.IntendedTarget;
                bool canHitNonTargetPawnsNow          = this.canHitNonTargetPawnsNow;
                if (canHitNonTargetPawnsNow)
                {
                    projectileHitFlags |= ProjectileHitFlags.NonTargetPawns;
                }
                bool flag3 = !this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full;
                if (flag3)
                {
                    projectileHitFlags |= ProjectileHitFlags.NonTargetWorld;
                }

                // miss chance
                ShotReport shotReport            = ShotReport.HitReportFor(this.caster, this, this.currentTarget);
                Thing      randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
                ThingDef   targetCoverDef        = (randomCoverToMissInto == null) ? null : randomCoverToMissInto.def;
                if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture) && !((VerbProperties_Ability)verbProps).AlwaysHits)
                {
                    shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget);
                    ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld;
                    if (Rand.Chance(0.5f) && this.canHitNonTargetPawnsNow)
                    {
                        projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns;
                    }
                    projectile.Launch(caster, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags2, null, targetCoverDef);
                    return(true);
                }
                if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance) && !((VerbProperties_Ability)verbProps).AlwaysHits)
                {
                    ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld;
                    if (this.canHitNonTargetPawnsNow)
                    {
                        projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns;
                    }
                    projectile.Launch(caster, drawPos, randomCoverToMissInto, this.currentTarget, projectileHitFlags3, null, targetCoverDef);
                    return(true);
                }
                // miss chance end

                projectile.Launch(caster, launchTarget, launchTarget, projectileHitFlags, null);
                result = new bool?(true);
            }
            return(result);
        }
예제 #17
0
파일: Tag.cs 프로젝트: ying636/Pawnmorpher
        /// <summary>
        /// Tries the cast shot.
        /// </summary>
        /// <returns></returns>
        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];
                        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;
            //never miss

            ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget;

            if (currentTarget.Thing != null)
            {
                projectile2.Launch(launcher, drawPos, currentTarget, currentTarget, projectileHitFlags4, equipment, targetCoverDef);
            }
            else
            {
                projectile2.Launch(launcher, drawPos, resultingLine.Dest, currentTarget, projectileHitFlags4, equipment, targetCoverDef);
            }
            return(true);
        }
        // Token: 0x0600651E RID: 25886 RVA: 0x001B8BC0 File Offset: 0x001B6FC0
        public static bool TryCastExtraShot(ref AbilitesExtended.Verb_EquipmentLaunchProjectile __instance, LocalTargetInfo currentTarget, bool canHitNonTargetPawnsNow)
        {
            if (currentTarget.HasThing && currentTarget.Thing.Map != __instance.caster.Map)
            {
                return(false);
            }
            ThingDef projectile = __instance.Projectile;

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

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

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

            if (__instance.verbProps.forcedMissRadius > 0.5f)
            {
                float num = VerbUtility.CalculateAdjustedForcedMiss(__instance.verbProps.forcedMissRadius, currentTarget.Cell - __instance.caster.Position);
                if (num > 0.5f)
                {
                    int max = GenRadial.NumCellsInRadius(num);
                    Rand.PushState();
                    int num2 = Rand.Range(0, max);
                    Rand.PopState();
                    if (num2 > 0)
                    {
                        IntVec3 c = currentTarget.Cell + GenRadial.RadialPattern[num2];

                        ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld;
                        Rand.PushState();
                        if (Rand.Chance(0.5f))
                        {
                            projectileHitFlags = ProjectileHitFlags.All;
                        }
                        Rand.PopState();
                        if (!canHitNonTargetPawnsNow)
                        {
                            projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns;
                        }
                        projectile2.Launch(launcher, drawPos, c, currentTarget, projectileHitFlags, equipment, null);
                        return(true);
                    }
                }
            }
            ShotReport shotReport            = ShotReport.HitReportFor(__instance.caster, __instance, currentTarget);
            Thing      randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
            ThingDef   targetCoverDef        = randomCoverToMissInto?.def;

            Rand.PushState();
            bool f1 = !Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture);

            Rand.PopState();
            if (f1)
            {
                shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget);
                ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld;
                Rand.PushState();
                if (Rand.Chance(0.5f) && canHitNonTargetPawnsNow)
                {
                    projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns;
                }
                Rand.PopState();
                projectile2.Launch(launcher, drawPos, shootLine.Dest, currentTarget, projectileHitFlags2, equipment, targetCoverDef);
                return(true);
            }
            Rand.PushState();
            bool f2 = !Rand.Chance(shotReport.PassCoverChance);

            Rand.PopState();
            if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && f2)
            {
                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;
            }
            if (currentTarget.Thing != null)
            {
                projectile2.Launch(launcher, drawPos, currentTarget, currentTarget, projectileHitFlags4, equipment, targetCoverDef);
            }
            else
            {
                projectile2.Launch(launcher, drawPos, shootLine.Dest, currentTarget, projectileHitFlags4, equipment, targetCoverDef);
            }
            return(true);
        }
        // Token: 0x060057CC RID: 22476 RVA: 0x0017B880 File Offset: 0x00179C80
        protected override bool TryCastShot()
        {
            //If we are aiming at something real on the map
            if (this.currentTarget.HasThing && this.currentTarget.Thing.Map != this.caster.Map)
            {
                return(false);
            }
            ThingDef projectile = this.Projectile;

            if (projectile == null)
            {
                return(false);
            }
            //Check to see if we have line of sight
            ShootLine shootLine;
            bool      flag = base.TryFindShootLineFromTo(this.caster.Position, this.currentTarget, out shootLine);

            if (this.verbProps.stopBurstWithoutLos && !flag)
            {
                return(false);
            }
            if (this.ownerEquipment != null)
            {
                CompChangeableProjectile comp = this.ownerEquipment.GetComp <CompChangeableProjectile>();
                if (comp != null)
                {
                    //!!!!!!!!!!!!!!!! This could be used to subtract from a battery pack
                    comp.Notify_ProjectileLaunched();
                }
            }
            //Launcher is the user; equipment is what is being used to shoot
            Thing        launcher     = this.caster;
            Thing        equipment    = this.ownerEquipment;
            CompMannable compMannable = this.caster.TryGetComp <CompMannable>();

            if (compMannable != null && compMannable.ManningPawn != null)
            {
                launcher  = compMannable.ManningPawn;
                equipment = this.caster;
            }
            //This drawPos may need to be modified so that the beam emerges from the weapon and not the user
            Vector3    drawPos     = this.caster.DrawPos;
            Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, this.caster.Map);

            //Can the projectile strike something on its flightpath?
            projectile2.FreeIntercept = (this.canFreeInterceptNow && !projectile2.def.projectile.flyOverhead);
            //ShotReport gives us our chance that the shot actual hit
            ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, this.currentTarget);

            //If the shot was a miss...
            if (Rand.Value > shotReport.ChanceToNotGoWild_IgnoringPosture)
            {
                if (DebugViewSettings.drawShooting)
                {
                    MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToWild", -1f);
                }
                //Modify the shoot line to hit something else
                shootLine.ChangeDestToMissWild();
                if (this.currentTarget.HasThing)
                {
                    //Ensure that the projectile actually hits something else
                    projectile2.ThingToNeverIntercept = this.currentTarget.Thing;
                }
                if (!projectile2.def.projectile.flyOverhead)
                {
                    projectile2.InterceptWalls = true;
                }
                //Launch doomed projectile for shootLine's bad destination
                //Consider giving the beam projectile a function to switch destinations when something gets between launcher and shootLine.Dest
                projectile2.Launch(launcher, drawPos, shootLine.Dest, equipment, this.currentTarget.Thing);
                return(true);
            }
            if (Rand.Value > shotReport.ChanceToNotHitCover)
            {
                if (DebugViewSettings.drawShooting)
                {
                    MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToCover", -1f);
                }
                if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn)
                {
                    Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
                    if (!projectile2.def.projectile.flyOverhead)
                    {
                        projectile2.InterceptWalls = true;
                    }
                    projectile2.Launch(launcher, drawPos, randomCoverToMissInto, equipment, this.currentTarget.Thing);
                    return(true);
                }
            }
            if (DebugViewSettings.drawShooting)
            {
                MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToHit", -1f);
            }
            if (!projectile2.def.projectile.flyOverhead)
            {
                projectile2.InterceptWalls = (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full);
            }
            if (this.currentTarget.Thing != null)
            {
                projectile2.Launch(launcher, drawPos, this.currentTarget, equipment, this.currentTarget.Thing);
            }
            else
            {
                projectile2.Launch(launcher, drawPos, shootLine.Dest, equipment, this.currentTarget.Thing);
            }
            return(true);
        }
예제 #20
0
        protected new bool?TryLaunchProjectile(ThingDef projectileDef, LocalTargetInfo launchTarget)
        {
            DebugMessage(launchTarget.ToString());
            var flag = TryFindShootLineFromTo(caster.Position, launchTarget, out var shootLine);

            if (verbProps.stopBurstWithoutLos && !flag)
            {
                DebugMessage("Targeting cancelled");
                return(false);
            }
            var drawPos     = caster.DrawPos;
            var projectile2 = (Projectile_AbilityBase)GenSpawn.Spawn(projectileDef, shootLine.Source, caster.Map);

            projectile2.extraDamages     = UseAbilityProps.extraDamages;
            projectile2.localSpawnThings = UseAbilityProps.thingsToSpawn;
            verbProps.soundCast?.PlayOneShot(new TargetInfo(caster.Position, caster.Map, false));
            verbProps.soundCastTail?.PlayOneShotOnCamera();
            if (DebugViewSettings.drawShooting)
            {
                MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToHit", -1f);
            }


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

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

            if (this.canHitNonTargetPawnsNow)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns;
            }
            if (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld;
            }
            this.ThrowDebugText("ToHit" + ((!this.canHitNonTargetPawnsNow) ? string.Empty : "\nchntp"));
            if (this.currentTarget.Thing != null)
            {
                //    projectile2.Launch(CasterPawn, drawPos, this.currentTarget, this.currentTarget, projectileHitFlags4, caster, targetCoverDef);
                projectile2.Launch(caster, Ability.Def, drawPos, currentTarget, projectileHitFlags4, null,
                                   UseAbilityProps.hediffsToApply,
                                   UseAbilityProps.mentalStatesToApply, UseAbilityProps.thingsToSpawn);
                this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell);
            }
            else
            {
                //    projectile2.Launch(CasterPawn, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags4, caster, targetCoverDef);
                projectile2.Launch(caster, Ability.Def, drawPos, shootLine.Dest, projectileHitFlags4, null,
                                   UseAbilityProps.hediffsToApply,
                                   UseAbilityProps.mentalStatesToApply, UseAbilityProps.thingsToSpawn);
                this.ThrowDebugText("Hit\nDest", shootLine.Dest);
            }

            /*
             * ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget;
             * if (this.canHitNonTargetPawnsNow)
             * {
             * projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns;
             * }
             * if (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full)
             * {
             * projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld;
             * }
             * DebugMessage(launchTarget.ToString());
             * projectile2.Launch(caster, Ability.Def, drawPos, launchTarget, projectileHitFlags4, null,
             * UseAbilityProps.hediffsToApply,
             * UseAbilityProps.mentalStatesToApply, UseAbilityProps.thingsToSpawn);
             */
            return(true);
        }
        private static float FriendlyFireConeTargetScoreOffset(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb)
        {
            if (!(searcher.Thing is Pawn pawn))
            {
                return(0f);
            }
            if (pawn.RaceProps.intelligence < Intelligence.ToolUser)
            {
                return(0f);
            }
            if (pawn.RaceProps.IsMechanoid)
            {
                return(0f);
            }
            if (!(verb is Verb_Shoot verb_Shoot))
            {
                return(0f);
            }
            ThingDef defaultProjectile = verb_Shoot.verbProps.defaultProjectile;

            if (defaultProjectile == null)
            {
                return(0f);
            }
            if (defaultProjectile.projectile.flyOverhead)
            {
                return(0f);
            }
            Map                     map        = pawn.Map;
            ShotReport              report     = ShotReport.HitReportFor(pawn, verb, (Thing)target);
            float                   a          = VerbUtility.CalculateAdjustedForcedMiss(verb.verbProps.forcedMissRadius, report.ShootLine.Dest - report.ShootLine.Source);
            float                   radius     = Mathf.Max(a, 1.5f);
            IntVec3                 dest2      = report.ShootLine.Dest;
            IEnumerable <IntVec3>   source     = from dest in GenRadial.RadialCellsAround(dest2, radius, true) where dest.InBounds(map) select dest;
            IEnumerable <ShootLine> source2    = from dest in source select new ShootLine(report.ShootLine.Source, dest);
            IEnumerable <IntVec3>   source3    = source2.SelectMany((ShootLine line) => line.Points().Concat(line.Dest).TakeWhile((IntVec3 pos) => pos.CanBeSeenOverFast(map)));
            IEnumerable <IntVec3>   enumerable = source3.Distinct <IntVec3>();
            float                   num        = 0f;

            foreach (IntVec3 c in enumerable)
            {
                float num2 = VerbUtility.InterceptChanceFactorFromDistance(report.ShootLine.Source.ToVector3Shifted(), c);
                if (num2 > 0f)
                {
                    List <Thing> thingList = c.GetThingList(map);
                    for (int i = 0; i < thingList.Count; i++)
                    {
                        Thing thing = thingList[i];
                        if (thing is IAttackTarget && thing != target)
                        {
                            float num3;
                            if (thing == searcher)
                            {
                                num3 = 40f;
                            }
                            else if (thing is Pawn)
                            {
                                num3 = ((!thing.def.race.Animal) ? 18f : 7f);
                            }
                            else
                            {
                                num3 = 10f;
                            }
                            num3 *= num2;
                            if (searcher.Thing.HostileTo(thing))
                            {
                                num3 *= 0.6f;
                            }
                            else
                            {
                                num3 *= -1f;
                            }
                            num += num3;
                        }
                    }
                }
            }
            return(num);
        }
예제 #22
0
        protected bool?TryLaunchProjectile(ThingDef projectileDef, LocalTargetInfo launchTarget)
        {
            DebugMessage(launchTarget.ToString());
            var flag = TryFindShootLineFromTo(caster.Position, launchTarget, out var shootLine);

            if (verbProps.stopBurstWithoutLos && !flag)
            {
                DebugMessage("Targeting cancelled");
                return(false);
            }
            var drawPos    = caster.DrawPos;
            var projectile = (Projectile_AbilityBase)GenSpawn.Spawn(projectileDef, shootLine.Source, caster.Map);

            projectile.extraDamages     = UseAbilityProps.extraDamages;
            projectile.localSpawnThings = UseAbilityProps.thingsToSpawn;

            //projectile. FreeIntercept = canFreeInterceptNow && !projectile.def.projectile.flyOverhead;
            var shotReport = ShotReport.HitReportFor(caster, this, launchTarget);

            verbProps.soundCast?.PlayOneShot(new TargetInfo(caster.Position, caster.Map, false));
            verbProps.soundCastTail?.PlayOneShotOnCamera();
//            if (!UseAbilityProps.AlwaysHits)
//            {
//                Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
//                ThingDef targetCoverDef = (randomCoverToMissInto == null) ? null : randomCoverToMissInto.def;
//                if (!Rand.Chance(shotReport.ChanceToNotGoWild_IgnoringPosture))
//                {
//                    if (DebugViewSettings.drawShooting)
//                        MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToWild", -1f);
//                    shootLine.ChangeDestToMissWild();
//                    ProjectileHitFlags projectileHitFlags2;
//                    if (Rand.Chance(0.5f))
//                    {
//                        projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld;
//                    }
//                    else
//                    {
//                        projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld;
//                        if (this.canHitNonTargetPawnsNow)
//                        {
//                            projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns;
//                        }
//                    }
//                    projectile.Launch(caster, Ability.Def, drawPos, shootLine.Dest, projectileHitFlags2, EquipmentSource,
//                        UseAbilityProps.hediffsToApply, UseAbilityProps.mentalStatesToApply,
//                        UseAbilityProps.thingsToSpawn);
//                    return true;
//                }
//                if (!Rand.Chance(shotReport.ChanceToNotHitCover))
//                {
//                    if (DebugViewSettings.drawShooting)
//                        MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToCover", -1f);
//                    if (launchTarget.Thing != null && launchTarget.Thing.def.category == ThingCategory.Pawn)
//                    {
//                        randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
//                        ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld;
//                        if (this.canHitNonTargetPawnsNow)
//                        {
//                            projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns;
//                        }
//                        projectile.Launch(caster, Ability.Def, drawPos, randomCoverToMissInto, projectileHitFlags3, null,
//                            UseAbilityProps.hediffsToApply, UseAbilityProps.mentalStatesToApply,
//                            UseAbilityProps.thingsToSpawn);
//                        return true;
//                    }
//                }
//            }
            if (DebugViewSettings.drawShooting)
            {
                MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToHit", -1f);
            }
            ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget;

            if (this.canHitNonTargetPawnsNow)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns;
            }
            if (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld;
            }
            DebugMessage(launchTarget.ToString());
            projectile.Launch(caster, Ability.Def, drawPos, launchTarget, projectileHitFlags4, null, UseAbilityProps.hediffsToApply,
                              UseAbilityProps.mentalStatesToApply, UseAbilityProps.thingsToSpawn);
            return(true);
        }
예제 #23
0
        // Token: 0x06002252 RID: 8786 RVA: 0x000D128C File Offset: 0x000CF48C
        protected bool base_TryCastShot()
        {
            if (this.currentTarget.HasThing && this.currentTarget.Thing.Map != this.caster.Map)
            {
                return(false);
            }
            ThingDef projectile = this.Projectile;

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

            if (this.verbProps.stopBurstWithoutLos && !flag)
            {
                return(false);
            }
            if (base.EquipmentSource != null)
            {
                CompChangeableProjectile comp = base.EquipmentSource.GetComp <CompChangeableProjectile>();
                if (comp != null)
                {
                    comp.Notify_ProjectileLaunched();
                }
                //修改精度
                if (CompShootMode != null)
                {
                    CompShootMode.PostPreEachShoot(this);
                }
            }
            Thing        launcher     = this.caster;
            Thing        equipment    = base.EquipmentSource;
            CompMannable compMannable = this.caster.TryGetComp <CompMannable>();

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

            //强制误差半径,无视技能等级(原版迫击炮)
            if (this.verbProps.forcedMissRadius > 0.5f)
            {
                float num = VerbUtility.CalculateAdjustedForcedMiss(this.verbProps.forcedMissRadius, this.currentTarget.Cell - this.caster.Position);
                if (num > 0.5f)
                {
                    int max  = GenRadial.NumCellsInRadius(num);
                    int num2 = Rand.Range(0, max);
                    if (num2 > 0)
                    {
                        IntVec3 c = this.currentTarget.Cell + GenRadial.RadialPattern[num2];
                        this.ThrowDebugText("ToRadius");
                        this.ThrowDebugText("Rad\nDest", c);
                        ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld;
                        if (Rand.Chance(0.5f))
                        {
                            projectileHitFlags = ProjectileHitFlags.All;
                        }
                        if (!this.canHitNonTargetPawnsNow)
                        {
                            projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns;
                        }
                        LanuchWithDamageMultiplier(projectile2, launcher, drawPos, c, this.currentTarget, projectileHitFlags, equipment, null);

                        return(true);
                    }
                }
            }


            ShotReport shotReport            = ShotReport.HitReportFor(this.caster, this, this.currentTarget);
            Thing      randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
            ThingDef   targetCoverDef        = (randomCoverToMissInto != null) ? randomCoverToMissInto.def : null;

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

            if (this.canHitNonTargetPawnsNow)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns;
            }
            if (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld;
            }
            this.ThrowDebugText("ToHit" + (this.canHitNonTargetPawnsNow ? "\nchntp" : ""));
            if (this.currentTarget.Thing != null)
            {
                LanuchWithDamageMultiplier(projectile2, launcher, drawPos, this.currentTarget, this.currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell);
            }
            else
            {
                LanuchWithDamageMultiplier(projectile2, launcher, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                this.ThrowDebugText("Hit\nDest", shootLine.Dest);
            }
            return(true);
        }
예제 #24
0
        protected bool?TryLaunchProjectile(ThingDef projectileDef, LocalTargetInfo launchTarget)
        {
            bool flag = base.TryFindShootLineFromTo(this.caster.Position, launchTarget, out ShootLine shootLine);

            if (this.verbProps.stopBurstWithoutLos && !flag)
            {
                return(false);
            }
            Vector3 drawPos = this.caster.DrawPos;
            Projectile_AbilityBase projectile = (Projectile_AbilityBase)GenSpawn.Spawn(projectileDef, shootLine.Source, this.caster.Map);

            projectile.extraDamages     = this.UseAbilityProps.extraDamages;
            projectile.localSpawnThings = this.UseAbilityProps.thingsToSpawn;
            projectile.FreeIntercept    = (this.canFreeInterceptNow && !projectile.def.projectile.flyOverhead);
            ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, launchTarget);

            if (this.verbProps.soundCast != null)
            {
                this.verbProps.soundCast.PlayOneShot(new TargetInfo(this.caster.Position, this.caster.Map, false));
            }
            if (this.verbProps.soundCastTail != null)
            {
                this.verbProps.soundCastTail.PlayOneShotOnCamera();
            }
            if (!this.UseAbilityProps.AlwaysHits)
            {
                if (Rand.Value > shotReport.ChanceToNotGoWild_IgnoringPosture)
                {
                    if (DebugViewSettings.drawShooting)
                    {
                        MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToWild", -1f);
                    }
                    shootLine.ChangeDestToMissWild();
                    if (launchTarget.HasThing)
                    {
                        projectile.ThingToNeverIntercept = launchTarget.Thing;
                    }
                    if (!projectile.def.projectile.flyOverhead)
                    {
                        projectile.InterceptWalls = true;
                    }
                    //              //Log.Message("LaunchingIntoWild");
                    projectile.Launch(this.caster, drawPos, shootLine.Dest, this.ownerEquipment, this.UseAbilityProps.hediffsToApply, this.UseAbilityProps.mentalStatesToApply, this.UseAbilityProps.thingsToSpawn);
                    return(true);
                }
                if (Rand.Value > shotReport.ChanceToNotHitCover)
                {
                    if (DebugViewSettings.drawShooting)
                    {
                        MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToCover", -1f);
                    }
                    if (launchTarget.Thing != null && launchTarget.Thing.def.category == ThingCategory.Pawn)
                    {
                        Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
                        if (!projectile.def.projectile.flyOverhead)
                        {
                            projectile.InterceptWalls = true;
                        }
                        //            //Log.Message("LaunchingINtoCover");
                        projectile.Launch(this.caster, drawPos, randomCoverToMissInto, this.ownerEquipment, this.UseAbilityProps.hediffsToApply, this.UseAbilityProps.mentalStatesToApply, this.UseAbilityProps.thingsToSpawn);
                        return(true);
                    }
                }
            }
            if (DebugViewSettings.drawShooting)
            {
                MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToHit", -1f);
            }
            if (!projectile.def.projectile.flyOverhead)
            {
                projectile.InterceptWalls = (!launchTarget.HasThing || launchTarget.Thing.def.Fillage == FillCategory.Full);
            }
            projectile.Launch(this.caster, drawPos, launchTarget, null, this.UseAbilityProps.hediffsToApply, this.UseAbilityProps.mentalStatesToApply, this.UseAbilityProps.thingsToSpawn);
            return(true);
        }
예제 #25
0
        protected override bool TryCastShot()
        {
            if (this.currentTarget.HasThing && this.currentTarget.Thing.Map != this.caster.Map)
            {
                return(false);
            }
            ThingDef projectile = this.Projectile;

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

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

            if (compMannable != null && compMannable.ManningPawn != null)
            {
                launcher  = compMannable.ManningPawn;
                equipment = this.caster;
            }

            /*
             * if (equipment == null)
             * {
             *  Log.Message("equipment==null");
             * }
             * else
             * {
             *  Log.Message(equipment.LabelShortCap);
             * }
             */
            Vector3    drawPos     = this.caster.DrawPos;
            Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, this.caster.Map, WipeMode.Vanish);

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

            Rand.PushState();
            bool AimOnTarget = Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture);

            Rand.PopState();
            if (!AimOnTarget)
            {
                shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget);
                this.ThrowDebugText("ToWild" + (this.canHitNonTargetPawnsNow ? "\nchntp" : ""));
                this.ThrowDebugText("Wild\nDest", shootLine.Dest);
                ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld;
                Rand.PushState();
                if (Rand.Chance(0.5f) && this.canHitNonTargetPawnsNow)
                {
                    projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns;
                }
                Rand.PopState();
                projectile2.Launch(launcher, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags2, equipment, targetCoverDef);
                //    Log.Message("EquipmentAbility projectile2.Launch OffTarget");
                return(true);
            }
            Rand.PushState();
            bool PassCover = Rand.Chance(shotReport.PassCoverChance);

            Rand.PopState();
            if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn && !PassCover)
            {
                this.ThrowDebugText("ToCover" + (this.canHitNonTargetPawnsNow ? "\nchntp" : ""));
                this.ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position);
                ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld;
                if (this.canHitNonTargetPawnsNow)
                {
                    projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns;
                }
                projectile2.Launch(launcher, drawPos, randomCoverToMissInto, this.currentTarget, projectileHitFlags3, equipment, targetCoverDef);
                //    Log.Message("EquipmentAbility projectile2.Launch IntoCover");
                return(true);
            }
            ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget;

            if (this.canHitNonTargetPawnsNow)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns;
            }
            if (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld;
            }
            this.ThrowDebugText("ToHit" + (this.canHitNonTargetPawnsNow ? "\nchntp" : ""));
            if (this.currentTarget.Thing != null)
            {
                projectile2.Launch(launcher, drawPos, this.currentTarget, this.currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                //    Log.Message("EquipmentAbility projectile2.Launch NoThing");
                this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell);
            }
            else
            {
                projectile2.Launch(launcher, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                //    Log.Message("EquipmentAbility projectile2.Launch AtThing");
                this.ThrowDebugText("Hit\nDest", shootLine.Dest);
            }
            return(true);
            //    return this.ability.Activate(this.currentTarget, this.currentDestination);
        }
        protected override bool TryCastShot()
        {
            //     Log.Message("TryCastShot");
            this.TargetsAoE.Clear();
            UpdateTargets();
            int burstshots = this.ShotsPerBurst;

            if (this.warpverbprops.PsykerPowerCategory != PsykerPowerTargetCategory.TargetAoE && this.TargetsAoE.Count > 1)
            {
                this.TargetsAoE.RemoveRange(0, TargetsAoE.Count - 1);
            }
            //         Log.Message("Targeting: " + TargetsAoE.Count.ToString());
            for (int i = 0; i < TargetsAoE.Count; i++)
            {
                //         Log.Message(TargetsAoE[i].Thing.Label);
                for (int j = 0; j < burstshots; j++)
                {
                    ShootLine shootLine;
                    bool      flag = base.TryFindShootLineFromTo(this.caster.Position, TargetsAoE[i], out shootLine);
                    if (this.verbProps.stopBurstWithoutLos && !flag)
                    {
                        return(false);
                    }
                    Vector3    drawPos    = this.caster.DrawPos;
                    Projectile projectile = (Projectile)GenSpawn.Spawn(this.verbProps.projectileDef, shootLine.Source, this.caster.Map);
                    projectile.FreeIntercept = (this.canFreeInterceptNow && !projectile.def.projectile.flyOverhead);
                    ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, TargetsAoE[i]);
                    if (!this.warpverbprops.AlwaysHits)
                    {
                        if (Rand.Value > shotReport.ChanceToNotGoWild_IgnoringPosture)
                        {
                            if (DebugViewSettings.drawShooting)
                            {
                                MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToWild", -1f);
                            }
                            shootLine.ChangeDestToMissWild();
                            if (TargetsAoE[i].HasThing)
                            {
                                projectile.ThingToNeverIntercept = TargetsAoE[i].Thing;
                            }
                            if (!projectile.def.projectile.flyOverhead)
                            {
                                projectile.InterceptWalls = true;
                            }
                            //              Log.Message("LaunchingIntoWild");
                            projectile.Launch(this.caster, drawPos, shootLine.Dest, this.ownerEquipment);
                            return(true);
                        }
                        if (Rand.Value > shotReport.ChanceToNotHitCover)
                        {
                            if (DebugViewSettings.drawShooting)
                            {
                                MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToCover", -1f);
                            }
                            if (TargetsAoE[i].Thing != null && TargetsAoE[i].Thing.def.category == ThingCategory.Pawn)
                            {
                                Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
                                if (!projectile.def.projectile.flyOverhead)
                                {
                                    projectile.InterceptWalls = true;
                                }
                                //            Log.Message("LaunchingINtoCover");
                                projectile.Launch(this.caster, drawPos, randomCoverToMissInto, this.ownerEquipment);
                                return(true);
                            }
                        }
                    }
                    if (DebugViewSettings.drawShooting)
                    {
                        MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToHit", -1f);
                    }
                    if (!projectile.def.projectile.flyOverhead)
                    {
                        projectile.InterceptWalls = (!TargetsAoE[i].HasThing || TargetsAoE[i].Thing.def.Fillage == FillCategory.Full);
                    }
                    if (TargetsAoE[i].Thing != null)
                    {
                        //                Log.Message("Release Shot at: " + TargetsAoE[i].Thing.Label);

                        if (this.warpverbprops.DrawProjectileOnTarget)
                        {
                            Projectile_WarpPower wprojectile = projectile as Projectile_WarpPower;
                            if (wprojectile != null)
                            {
                                //                      Log.Message("Launched Warpprojectile");
                                wprojectile.selectedTarget = TargetsAoE[i].Thing;
                                wprojectile.Caster         = this.CasterPawn;
                                wprojectile.Launch(this.caster, drawPos, TargetsAoE[i]);
                            }
                        }
                        else
                        {
                            //              Log.Message("Launched Projectile");
                            projectile.Launch(this.caster, drawPos, TargetsAoE[i]);
                        }
                    }
                    else
                    {
                        if (this.warpverbprops.DrawProjectileOnTarget)
                        {
                            Projectile_WarpPower wprojectile = projectile as Projectile_WarpPower;
                            wprojectile.targetVec = shootLine.Dest.ToVector3();
                            wprojectile.Launch(this.caster, drawPos, TargetsAoE[i]);
                        }
                        //                   Log.Message("LaunchingWild");
                        projectile.Launch(this.caster, drawPos, shootLine.Dest);
                    }
                }

                psycomp.TicksToCast    = this.warpverbprops.TicksToRecharge;
                psycomp.TicksToCastMax = this.warpverbprops.TicksToRecharge;
            }
            this.burstShotsLeft = 0;
            if (soul != null)
            {
                soul.GainNeed(0.01f * (-warpverbprops.CorruptionFactor));
            }
            //    PsykerUtility.PsykerShockEvents(psycomp, psycomp.curPower.PowerLevel);
            return(true);
        }
예제 #27
0
        private static float FriendlyFireConeTargetScoreOffset(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb)
        {
            Pawn pawn = searcher.Thing as Pawn;

            if (pawn == null)
            {
                return(0f);
            }
            if ((int)pawn.RaceProps.intelligence < 1)
            {
                return(0f);
            }
            if (pawn.RaceProps.IsMechanoid)
            {
                return(0f);
            }
            Verb_Shoot verb_Shoot = verb as Verb_Shoot;

            if (verb_Shoot == null)
            {
                return(0f);
            }
            ThingDef defaultProjectile = verb_Shoot.verbProps.defaultProjectile;

            if (defaultProjectile == null)
            {
                return(0f);
            }
            if (defaultProjectile.projectile.flyOverhead)
            {
                return(0f);
            }
            Map                   map        = pawn.Map;
            ShotReport            report     = ShotReport.HitReportFor(pawn, verb, (Thing)target);
            float                 radius     = Mathf.Max(VerbUtility.CalculateAdjustedForcedMiss(verb.verbProps.forcedMissRadius, report.ShootLine.Dest - report.ShootLine.Source), 1.5f);
            IEnumerable <IntVec3> enumerable = (from dest in GenRadial.RadialCellsAround(report.ShootLine.Dest, radius, useCenter: true)
                                                where dest.InBounds(map)
                                                select new ShootLine(report.ShootLine.Source, dest)).SelectMany((ShootLine line) => line.Points().Concat(line.Dest).TakeWhile((IntVec3 pos) => pos.CanBeSeenOverFast(map))).Distinct();
            float num = 0f;

            foreach (IntVec3 item in enumerable)
            {
                float num2 = VerbUtility.InterceptChanceFactorFromDistance(report.ShootLine.Source.ToVector3Shifted(), item);
                if (!(num2 <= 0f))
                {
                    List <Thing> thingList = item.GetThingList(map);
                    for (int i = 0; i < thingList.Count; i++)
                    {
                        Thing thing = thingList[i];
                        if (thing is IAttackTarget && thing != target)
                        {
                            float num3 = (thing == searcher) ? 40f : ((!(thing is Pawn)) ? 10f : (thing.def.race.Animal ? 7f : 18f));
                            num3 *= num2;
                            num3  = ((!searcher.Thing.HostileTo(thing)) ? (num3 * -1f) : (num3 * 0.6f));
                            num  += num3;
                        }
                    }
                }
            }
            return(num);
        }
예제 #28
0
        public bool TryCastShot_A16Vanilla_Modified()
        {
            if (this.currentTarget.HasThing && this.currentTarget.Thing.Map != this.caster.Map)
            {
                return(false);
            }
            bool flag = base.TryFindShootLineFromTo(this.caster.Position, this.currentTarget, out ShootLine shootLine);

            if (this.verbProps.stopBurstWithoutLos && !flag)
            {
                return(false);
            }
            Vector3    drawPos    = this.caster.DrawPos;
            Projectile projectile = (Projectile)GenSpawn.Spawn(this.verbProps.defaultProjectile, shootLine.Source, this.caster.Map);

            ///MODIFIED SECTION
            ////////////////////////////////////////////

            if (this.lastShotReflected)
            {
                ////Log.Message("lastShotReflected Called");
                projectile.Launch(this.caster, drawPos, this.currentTarget, this.ownerEquipment);
                return(true);
            }

            ////////////////////////////////////////////
            //

            projectile.FreeIntercept = (this.canFreeInterceptNow && !projectile.def.projectile.flyOverhead);
            if (this.verbProps.forcedMissRadius > 0.5f)
            {
                float lengthHorizontalSquared = (this.currentTarget.Cell - this.caster.Position).LengthHorizontalSquared;
                float num;
                if (lengthHorizontalSquared < 9f)
                {
                    num = 0f;
                }
                else if (lengthHorizontalSquared < 25f)
                {
                    num = this.verbProps.forcedMissRadius * 0.5f;
                }
                else if (lengthHorizontalSquared < 49f)
                {
                    num = this.verbProps.forcedMissRadius * 0.8f;
                }
                else
                {
                    num = this.verbProps.forcedMissRadius * 1f;
                }
                if (num > 0.5f)
                {
                    int max  = GenRadial.NumCellsInRadius(this.verbProps.forcedMissRadius);
                    int num2 = Rand.Range(0, max);
                    if (num2 > 0)
                    {
                        if (DebugViewSettings.drawShooting)
                        {
                            MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToForRad", -1f);
                        }
                        IntVec3 c = this.currentTarget.Cell + GenRadial.RadialPattern[num2];
                        if (this.currentTarget.HasThing)
                        {
                            projectile.ThingToNeverIntercept = this.currentTarget.Thing;
                        }
                        if (!projectile.def.projectile.flyOverhead)
                        {
                            projectile.InterceptWalls = true;
                        }
                        projectile.Launch(this.caster, drawPos, c, this.ownerEquipment);
                        return(true);
                    }
                }
            }
            ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, this.currentTarget);

            if (Rand.Value > shotReport.ChanceToNotGoWild_IgnoringPosture)
            {
                if (DebugViewSettings.drawShooting)
                {
                    MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToWild", -1f);
                }
                shootLine.ChangeDestToMissWild();
                if (this.currentTarget.HasThing)
                {
                    projectile.ThingToNeverIntercept = this.currentTarget.Thing;
                }
                if (!projectile.def.projectile.flyOverhead)
                {
                    projectile.InterceptWalls = true;
                }
                projectile.Launch(this.caster, drawPos, shootLine.Dest, this.ownerEquipment);
                return(true);
            }
            if (Rand.Value > shotReport.ChanceToNotHitCover)
            {
                if (DebugViewSettings.drawShooting)
                {
                    MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToCover", -1f);
                }
                if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn)
                {
                    Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
                    if (!projectile.def.projectile.flyOverhead)
                    {
                        projectile.InterceptWalls = true;
                    }
                    projectile.Launch(this.caster, drawPos, randomCoverToMissInto, this.ownerEquipment);
                    return(true);
                }
            }
            if (DebugViewSettings.drawShooting)
            {
                MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToHit", -1f);
            }
            if (!projectile.def.projectile.flyOverhead)
            {
                projectile.InterceptWalls = (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full);
            }
            if (this.currentTarget.Thing != null)
            {
                projectile.Launch(this.caster, drawPos, this.currentTarget, this.ownerEquipment);
            }
            else
            {
                projectile.Launch(this.caster, drawPos, shootLine.Dest, this.ownerEquipment);
            }
            return(true);
        }
        public bool FireProjectile()
        {
            if (base.currentTarget.HasThing && base.currentTarget.Thing.Map != base.caster.Map)
            {
                return(false);
            }
            ThingDef projectile = this.Projectile;

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

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

            if (compMannable != null && compMannable.ManningPawn != null)
            {
                launcher  = compMannable.ManningPawn;
                equipment = base.caster;
                // Earn skills
                if (compMannable.ManningPawn.skills != null)
                {
                    int skillsAffectingAccuracy = 0;
                    if (Settings.intellectualAffectsMortarAccuracy)
                    {
                        skillsAffectingAccuracy++;
                    }
                    if (Settings.shootingAffectsMortarAccuracy)
                    {
                        skillsAffectingAccuracy++;
                    }

                    float skillXP = verbProps.AdjustedFullCycleTime(this, CasterPawn) * 100;
                    skillXP /= skillsAffectingAccuracy;

                    if (Settings.intellectualAffectsMortarAccuracy)
                    {
                        compMannable.ManningPawn.skills.Learn(SkillDefOf.Intellectual, skillXP, false);
                    }
                    if (Settings.shootingAffectsMortarAccuracy)
                    {
                        compMannable.ManningPawn.skills.Learn(SkillDefOf.Shooting, skillXP, false);
                    }
                }
            }
            Vector3    drawPos     = base.caster.DrawPos;
            Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, base.caster.Map, WipeMode.Vanish);

            // If targetting a pawn
            if (Settings.targetLeading)
            {
                if (currentTarget != null && currentTarget.Thing != null && currentTarget.Thing is Pawn targetPawn && targetPawn.pather.curPath != null)
                {
                    List <IntVec3> nodes = new List <IntVec3>(targetPawn.pather.curPath.NodesReversed);
                    nodes.Reverse();
                    // Purge outdated nodes from list
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        if (nodes[i] == targetPawn.Position)
                        {
                            // Remove all previous nodes
                            nodes.RemoveRange(0, i);
                            //Log.Message("Removed " + i + " entries. First node is now " + nodes[0].ToString());
                            break;
                        }
                    }
                    // Path of target pawn from current to destination
                    // Need travel speed of pawn, estimate Vec3 they will be in based on travel speed of our projectile
                    float targetMoveSpeed     = targetPawn.GetStatValue(StatDefOf.MoveSpeed);
                    float projectileMoveSpeed = projectile.projectile.speed;

                    // Estimate position target will be in after this amount of time
                    IntVec3 bestTarget     = targetPawn.Position;
                    float   bestTimeOffset = float.MaxValue;
                    //Log.Message("Default time offset = " + Mathf.Abs(((targetPawn.Position - caster.Position).LengthHorizontal) / projectileMoveSpeed));
                    float accumulatedTargetTime = 0f;

                    IntVec3 previousPosition = targetPawn.Position;
                    foreach (IntVec3 pathPosition in nodes)
                    {
                        float projectileDistanceFromTarget     = (pathPosition - caster.Position).LengthHorizontal;
                        float timeForProjectileToReachPosition = projectileDistanceFromTarget / projectileMoveSpeed;

                        //float pawnDistanceFromTarget = (pathPosition - targetPawn.Position).LengthHorizontal;
                        //float timeForPawnToReachPosition = pawnDistanceFromTarget / targetMoveSpeed;

                        float pawnDistanceFromLastPositionToHere         = (pathPosition - previousPosition).LengthHorizontal;
                        float timeForPawnToReachPositionFromLastPosition = pawnDistanceFromLastPositionToHere / targetMoveSpeed;
                        accumulatedTargetTime += timeForPawnToReachPositionFromLastPosition;

                        float timeOffset = Mathf.Abs(timeForProjectileToReachPosition - accumulatedTargetTime);
                        if (timeOffset < bestTimeOffset)
                        {
                            bestTarget     = pathPosition;
                            bestTimeOffset = timeOffset;
                            //Log.Message("Position " + pathPosition.ToString() + " is better. Time offset is " + timeOffset);
                        }
                        else
                        {
                            //Log.Message("Position " + pathPosition.ToString() + " is not better. Time offset is " + timeOffset);
                        }

                        previousPosition = pathPosition;
                    }
                    //Log.Message("Initial target cell = " + currentTarget.Cell.ToString() + " and new target is " + bestTarget.ToString());
                    currentTarget = new LocalTargetInfo(bestTarget);
                }
            }

            if (base.verbProps.forcedMissRadius > 0.5f)
            {
                float adjustedForcedMissRadius        = GetAdjustedForcedMissRadius();
                ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.All;
                IntVec3            c = currentTarget.Cell;
                if (adjustedForcedMissRadius > 0.5f)
                {
                    int max  = GenRadial.NumCellsInRadius(adjustedForcedMissRadius);
                    int num2 = Rand.Range(0, max);
                    c = base.currentTarget.Cell + GenRadial.RadialPattern[num2];

                    /*if (num2 > 0)
                     * {
                     *  this.ThrowDebugText("ToRadius");
                     *  this.ThrowDebugText("Rad\nDest", c);
                     *  ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld;
                     *  if (Rand.Chance(0.5f))
                     *  {
                     *      projectileHitFlags = ProjectileHitFlags.All;
                     *  }
                     *  if (!base.canHitNonTargetPawnsNow)
                     *  {
                     *      projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns;
                     *  }
                     *  projectile2.Launch(launcher, drawPos, c, base.currentTarget, projectileHitFlags, equipment, null);
                     *  return true;
                     * }*/
                }

                //Log.Message("Final target is " + c.ToString());
                projectile2.Launch(launcher, drawPos, c, base.currentTarget, projectileHitFlags, equipment, null);
                return(true);
            }
            ShotReport shotReport            = ShotReport.HitReportFor(base.caster, this, base.currentTarget);
            Thing      randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
            ThingDef   targetCoverDef        = (randomCoverToMissInto == null) ? null : randomCoverToMissInto.def;

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

            if (base.canHitNonTargetPawnsNow)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns;
            }
            if (!base.currentTarget.HasThing || base.currentTarget.Thing.def.Fillage == FillCategory.Full)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld;
            }
            this.ThrowDebugText("ToHit" + ((!base.canHitNonTargetPawnsNow) ? string.Empty : "\nchntp"));
            if (base.currentTarget.Thing != null)
            {
                projectile2.Launch(launcher, drawPos, base.currentTarget, base.currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                this.ThrowDebugText("Hit\nDest", base.currentTarget.Cell);
            }
            else
            {
                projectile2.Launch(launcher, drawPos, shootLine.Dest, base.currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                this.ThrowDebugText("Hit\nDest", shootLine.Dest);
            }
            return(true);
        }
예제 #30
0
 public static void Postfix(ShotReport report, ref float __result)
 {
     var traverse = Traverse.Create(report);
     var pawn     = traverse.Field("");
 }