// Token: 0x0600651E RID: 25886 RVA: 0x001B8BC0 File Offset: 0x001B6FC0
        public static bool TryCastExtraShot(ref Verb_Shoot __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.TryGetComp <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, false, equipment, null);
                        return(true);
                    }
                }
            }
            ShotReport shotReport            = ShotReport.HitReportFor(__instance.caster, __instance, currentTarget);
            Thing      randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
            ThingDef   targetCoverDef        = (randomCoverToMissInto == null) ? null : randomCoverToMissInto.def;

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

            Rand.PopState();
            if (!chance)
            {
                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, false, equipment, targetCoverDef);
                return(true);
            }
            Rand.PushState();
            chance = Rand.Chance(shotReport.PassCoverChance);
            Rand.PopState();
            if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && !chance)
            {
                ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld;
                if (canHitNonTargetPawnsNow)
                {
                    projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns;
                }
                projectile2.Launch(launcher, drawPos, randomCoverToMissInto, currentTarget, projectileHitFlags3, false, 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, false, equipment, targetCoverDef);
            }
            else
            {
                projectile2.Launch(launcher, drawPos, shootLine.Dest, currentTarget, projectileHitFlags4, false, equipment, targetCoverDef);
            }
            return(true);
        }
Пример #2
0
 private float CalculateAdjustedForcedMiss()
 {
     return(ForcedMissRadius <= 0.5f
         ? 0f
         : VerbUtility.CalculateAdjustedForcedMiss(ForcedMissRadius, Target - Origin));
 }
Пример #3
0
        public override void HandleNetMessage(INetChannel channel, EntitySystemMessage message)
        {
            base.HandleNetMessage(channel, message);

            switch (message)
            {
            case RequestVerbsMessage req:
            {
                if (!_entityManager.TryGetEntity(req.EntityUid, out var entity))
                {
                    return;
                }

                var session    = _playerManager.GetSessionByChannel(channel);
                var userEntity = session.AttachedEntity;

                var data = new List <VerbsResponseMessage.VerbData>();
                //Get verbs, component dependent.
                foreach (var(component, verb) in VerbUtility.GetVerbs(entity))
                {
                    if (verb.RequireInteractionRange && !VerbUtility.InVerbUseRange(userEntity, entity))
                    {
                        continue;
                    }
                    if (VerbUtility.IsVerbInvisible(verb, userEntity, component, out var vis))
                    {
                        continue;
                    }

                    // TODO: These keys being giant strings is inefficient as hell.
                    data.Add(new VerbsResponseMessage.VerbData(verb.GetText(userEntity, component),
                                                               $"{component.GetType()}:{verb.GetType()}",
                                                               vis == VerbVisibility.Visible));
                }
                //Get global verbs. Visible for all entities regardless of their components.
                foreach (var globalVerb in VerbUtility.GetGlobalVerbs(Assembly.GetExecutingAssembly()))
                {
                    if (globalVerb.RequireInteractionRange && !VerbUtility.InVerbUseRange(userEntity, entity))
                    {
                        continue;
                    }
                    if (VerbUtility.IsVerbInvisible(globalVerb, userEntity, entity, out var vis))
                    {
                        continue;
                    }

                    data.Add(new VerbsResponseMessage.VerbData(globalVerb.GetText(userEntity, entity),
                                                               globalVerb.GetType().ToString(), vis == VerbVisibility.Visible));
                }

                var response = new VerbsResponseMessage(data, req.EntityUid);
                RaiseNetworkEvent(response, channel);
                break;
            }


            case UseVerbMessage use:
            {
                if (!_entityManager.TryGetEntity(use.EntityUid, out var entity))
                {
                    return;
                }

                var session    = _playerManager.GetSessionByChannel(channel);
                var userEntity = session.AttachedEntity;

                foreach (var(component, verb) in VerbUtility.GetVerbs(entity))
                {
                    if ($"{component.GetType()}:{verb.GetType()}" != use.VerbKey)
                    {
                        continue;
                    }

                    if (verb.RequireInteractionRange)
                    {
                        var distanceSquared = (userEntity.Transform.WorldPosition - entity.Transform.WorldPosition)
                                              .LengthSquared;
                        if (distanceSquared > VerbUtility.InteractionRangeSquared)
                        {
                            break;
                        }
                    }

                    verb.Activate(userEntity, component);
                    break;
                }

                foreach (var globalVerb in VerbUtility.GetGlobalVerbs(Assembly.GetExecutingAssembly()))
                {
                    if (globalVerb.GetType().ToString() != use.VerbKey)
                    {
                        continue;
                    }

                    if (globalVerb.RequireInteractionRange)
                    {
                        var distanceSquared = (userEntity.Transform.WorldPosition - entity.Transform.WorldPosition)
                                              .LengthSquared;
                        if (distanceSquared > VerbUtility.InteractionRangeSquared)
                        {
                            break;
                        }
                    }

                    globalVerb.Activate(userEntity, entity);
                    break;
                }

                break;
            }
            }
        }
        public override void HandleNetMessage(INetChannel channel, EntitySystemMessage message)
        {
            base.HandleNetMessage(channel, message);

            switch (message)
            {
            case RequestVerbsMessage req:
            {
                if (!_entityManager.TryGetEntity(req.EntityUid, out var entity))
                {
                    return;
                }

                var session    = _playerManager.GetSessionByChannel(channel);
                var userEntity = session.AttachedEntity;

                var data = new List <VerbsResponseMessage.VerbData>();
                foreach (var(component, verb) in VerbUtility.GetVerbs(entity))
                {
                    if (verb.RequireInteractionRange)
                    {
                        var distanceSquared = (userEntity.Transform.WorldPosition - entity.Transform.WorldPosition)
                                              .LengthSquared;
                        if (distanceSquared > Verb.InteractionRangeSquared)
                        {
                            continue;
                        }
                    }

                    // TODO: These keys being giant strings is inefficient as hell.
                    data.Add(new VerbsResponseMessage.VerbData(verb.GetText(userEntity, component),
                                                               $"{component.GetType()}:{verb.GetType()}",
                                                               !verb.IsDisabled(userEntity, component)));
                }

                var response = new VerbsResponseMessage(data, req.EntityUid);
                RaiseNetworkEvent(response, channel);
                break;
            }


            case UseVerbMessage use:
            {
                if (!_entityManager.TryGetEntity(use.EntityUid, out var entity))
                {
                    return;
                }

                var session    = _playerManager.GetSessionByChannel(channel);
                var userEntity = session.AttachedEntity;

                foreach (var(component, verb) in VerbUtility.GetVerbs(entity))
                {
                    if ($"{component.GetType()}:{verb.GetType()}" != use.VerbKey)
                    {
                        continue;
                    }

                    if (verb.RequireInteractionRange)
                    {
                        var distanceSquared = (userEntity.Transform.WorldPosition - entity.Transform.WorldPosition)
                                              .LengthSquared;
                        if (distanceSquared > Verb.InteractionRangeSquared)
                        {
                            break;
                        }
                    }

                    verb.Activate(userEntity, component);
                    break;
                }

                break;
            }
            }
        }
Пример #5
0
        public 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);
            }
            bool flag = base.TryFindShootLineFromTo(this.Caster.Position, this.currentTarget, out ShootLine shootLine);

            if (this.verbProps.stopBurstWithoutLos && !flag)
            {
                return(false);
            }
            Vector3 muzzlePos;

            if (turretGun != null)
            {
                if (turretGun.UseAmmo)
                {
                    bool playerpawn = this.CasterIsPawn && this.Caster.Faction == Faction.OfPlayer;
                    if (turretGun.HasAmmo)
                    {
                        turretGun.UsedOnce();
                    }
                    else
                    {
                        return(false);
                    }
                    if (turretGun.RemainingCharges == 0)
                    {
                        if (turretGun.Props.soundEmptyWarning != null && playerpawn)
                        {
                            turretGun.Props.soundEmptyWarning.PlayOneShot(new TargetInfo(this.Caster.Position, this.Caster.Map, false));
                        }
                        if (!turretGun.Props.messageEmptyWarning.NullOrEmpty() && playerpawn)
                        {
                            MoteMaker.ThrowText(Caster.Position.ToVector3(), Caster.Map, turretGun.Props.messageEmptyWarning.Translate(EquipmentSource.LabelCap, Caster.LabelShortCap), 3f);
                        }
                    }
                    float a         = turretGun.RemainingCharges;
                    float b         = turretGun.MaxCharges;
                    int   remaining = (int)(a / b * 100f);
                    if (remaining == 50 && warningticks == 0)
                    {
                        warningticks = this.verbProps.ticksBetweenBurstShots + 1;
                        if (turretGun.Props.soundHalfRemaningWarning != null && playerpawn)
                        {
                            turretGun.Props.soundHalfRemaningWarning.PlayOneShot(new TargetInfo(this.Caster.Position, this.Caster.Map, false));
                        }
                        if (!turretGun.Props.messageHalfRemaningWarning.NullOrEmpty() && playerpawn)
                        {
                            MoteMaker.ThrowText(Caster.Position.ToVector3(), Caster.Map, turretGun.Props.messageHalfRemaningWarning.Translate(EquipmentSource.LabelCap, Caster.LabelShortCap, remaining), 3f);
                        }
                    }
                    if (remaining == 25 && warningticks == 0)
                    {
                        warningticks = this.verbProps.ticksBetweenBurstShots + 1;
                        if (turretGun.Props.soundQuaterRemaningWarning != null && playerpawn)
                        {
                            turretGun.Props.soundQuaterRemaningWarning.PlayOneShot(new TargetInfo(this.Caster.Position, this.Caster.Map, false));
                        }
                        if (!turretGun.Props.messageQuaterRemaningWarning.NullOrEmpty() && playerpawn)
                        {
                            MoteMaker.ThrowText(Caster.Position.ToVector3(), Caster.Map, turretGun.Props.messageQuaterRemaningWarning.Translate(EquipmentSource.LabelCap, Caster.LabelShortCap, remaining), 3f);
                        }
                    }
                    muzzlePos = MuzzlePosition(this.Caster, this.currentTarget, offset);
                }
            }
            else
            {
                Log.Error(Caster + "'s " + this + " has no Comp_Turret");
                return(false);
            }
            Thing      launcher    = this.Caster;
            Thing      equipment   = base.EquipmentSource;
            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;
                        }
                        muzzlePos = MuzzlePosition(this.Caster, this.currentTarget, offset);
                        projectile2.Launch(launcher, muzzlePos, c, this.currentTarget, projectileHitFlags, this.preventFriendlyFire, equipment, null);
                        if (this.CasterIsPawn)
                        {
                            this.CasterPawn.records.Increment(RecordDefOf.ShotsFired);
                        }
                        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 f = !Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture);

            Rand.PopState();
            if (f)
            {
                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();
                muzzlePos = MuzzlePosition(this.Caster, this.currentTarget, offset);
                projectile2.Launch(launcher, muzzlePos, shootLine.Dest, this.currentTarget, projectileHitFlags2, this.preventFriendlyFire, equipment, targetCoverDef);
                if (this.CasterIsPawn)
                {
                    this.CasterPawn.records.Increment(RecordDefOf.ShotsFired);
                }
                return(true);
            }
            Rand.PushState();
            bool f2 = !Rand.Chance(shotReport.PassCoverChance);

            Rand.PopState();
            if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn && f2)
            {
                this.ThrowDebugText("ToCover" + (this.canHitNonTargetPawnsNow ? "\nchntp" : ""));
                this.ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position);
                ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld;
                if (this.canHitNonTargetPawnsNow)
                {
                    projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns;
                }
                muzzlePos = MuzzlePosition(this.Caster, this.currentTarget, offset);
                projectile2.Launch(launcher, muzzlePos, randomCoverToMissInto, this.currentTarget, projectileHitFlags3, this.preventFriendlyFire, equipment, targetCoverDef);
                if (this.CasterIsPawn)
                {
                    this.CasterPawn.records.Increment(RecordDefOf.ShotsFired);
                }
                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" : ""));
            muzzlePos = MuzzlePosition(this.Caster, this.currentTarget, offset);
            if (this.currentTarget.Thing != null)
            {
                projectile2.Launch(launcher, muzzlePos, this.currentTarget, this.currentTarget, projectileHitFlags4, this.preventFriendlyFire, equipment, targetCoverDef);
                this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell);
            }
            else
            {
                projectile2.Launch(launcher, muzzlePos, shootLine.Dest, this.currentTarget, projectileHitFlags4, this.preventFriendlyFire, equipment, targetCoverDef);
                this.ThrowDebugText("Hit\nDest", shootLine.Dest);
            }

            if (this.CasterIsPawn)
            {
                this.CasterPawn.records.Increment(RecordDefOf.ShotsFired);
            }
            return(true);
        }
Пример #6
0
        private bool CheckForFreeIntercept(IntVec3 c)
        {
            if (destination.ToIntVec3() == c)
            {
                return(false);
            }
            float        num       = VerbUtility.InterceptChanceFactorFromDistance(origin, c);
            bool         flag      = false;
            List <Thing> thingList = c.GetThingList(Map);

            for (int i = 0; i < thingList.Count; i++)
            {
                Thing thing = thingList[i];
                if (CanHit(thing))
                {
                    bool flag2 = false;
                    if (thing.def.Fillage == FillCategory.Full)
                    {
                        Building_Door building_Door = thing as Building_Door;
                        if (building_Door == null || !building_Door.Open)
                        {
                            ThrowDebugText("int-wall", c);
                            Impact(thing);
                            return(true);
                        }
                        flag2 = true;
                    }
                    float num2 = 0f;
                    Pawn  pawn = thing as Pawn;
                    if (pawn != null)
                    {
                        num2 = 0.8f * Mathf.Clamp(pawn.BodySize, 0.1f, 2f);
                        if (pawn.GetPosture() != PawnPosture.Standing)
                        {
                            num2 *= 0.1f;
                        }
                        if (launcher != null && pawn.Faction != null && launcher.Faction != null && !pawn.Faction.HostileTo(launcher.Faction))//아군 적중률
                        {
                            num2 *= 0.4f;
                        }
                    }
                    else if (thing.def.fillPercent > 0.2f)
                    {
                        if (flag2)
                        {
                            num2 = 0.05f;
                        }
                        else if (DestinationCell.AdjacentTo8Way(c))
                        {
                            num2 = thing.def.fillPercent * 1f;
                        }
                        else
                        {
                            num2 = thing.def.fillPercent * 0.15f;
                        }
                    }
                    num2 *= num;
                    if (num2 > 1E-05f)
                    {
                        if (Rand.Chance(num2))
                        {
                            ThrowDebugText("int-" + num2.ToStringPercent(), c);
                            Impact(thing);
                            return(true);
                        }
                        flag = true;
                        ThrowDebugText(num2.ToStringPercent(), c);
                    }
                }
            }
            if (!flag)
            {
                ThrowDebugText("o", c);
            }
            return(false);
        }
        // Token: 0x0600000F RID: 15 RVA: 0x000026FC File Offset: 0x000008FC
        private void ImpactSomething()
        {
            bool flyOverhead = this.def.projectile.flyOverhead;

            if (flyOverhead)
            {
                RoofDef roofDef = base.Map.roofGrid.RoofAt(base.Position);
                bool    flag    = roofDef != null;
                if (flag)
                {
                    bool isThickRoof = roofDef.isThickRoof;
                    if (isThickRoof)
                    {
                        this.def.projectile.soundHitThickRoof.PlayOneShot(new TargetInfo(base.Position, base.Map, false));
                        this.Destroy(DestroyMode.Vanish);
                        return;
                    }
                    bool flag2 = base.Position.GetEdifice(base.Map) == null || base.Position.GetEdifice(base.Map).def.Fillage != FillCategory.Full;
                    if (flag2)
                    {
                        RoofCollapserImmediate.DropRoofInCells(base.Position, base.Map, null);
                    }
                }
            }
            bool flag3 = !this.usedTarget.HasThing || !base.CanHit(this.usedTarget.Thing);

            if (flag3)
            {
                List <Thing> list = new List <Thing>();
                list.Clear();
                List <Thing> thingList = base.Position.GetThingList(base.Map);
                for (int i = 0; i < thingList.Count; i++)
                {
                    Thing thing = thingList[i];
                    bool  flag4 = (thing.def.category == ThingCategory.Building || thing.def.category == ThingCategory.Pawn || thing.def.category == ThingCategory.Item || thing.def.category == ThingCategory.Plant) && base.CanHit(thing);
                    if (flag4)
                    {
                        list.Add(thing);
                    }
                }
                list.Shuffle <Thing>();
                for (int j = 0; j < list.Count; j++)
                {
                    Thing thing2 = list[j];
                    Pawn  pawn   = thing2 as Pawn;
                    bool  flag5  = pawn != null;
                    float num;
                    if (flag5)
                    {
                        num = 0.5f * Mathf.Clamp(pawn.BodySize, 0.1f, 2f);
                        bool flag6 = pawn.GetPosture() != PawnPosture.Standing && GenGeo.MagnitudeHorizontalSquared(this.origin - this.destination) >= 20.25f;
                        if (flag6)
                        {
                            num *= 0.2f;
                        }
                        bool flag7 = this.launcher != null && pawn.Faction != null && this.launcher.Faction != null && !pawn.Faction.HostileTo(this.launcher.Faction);
                        if (flag7)
                        {
                            num *= VerbUtility.InterceptChanceFactorFromDistance(this.origin, base.Position);
                        }
                    }
                    else
                    {
                        num = 1.5f * thing2.def.fillPercent;
                    }
                    bool flag8 = Rand.Chance(num);
                    if (flag8)
                    {
                        this.Impact(list.RandomElement <Thing>());
                        return;
                    }
                }
                this.Impact(null);
            }
            else
            {
                Pawn pawn2 = this.usedTarget.Thing as Pawn;
                bool flag9 = pawn2 != null && pawn2.GetPosture() != PawnPosture.Standing && GenGeo.MagnitudeHorizontalSquared(this.origin - this.destination) >= 20.25f && !Rand.Chance(0.2f);
                if (flag9)
                {
                    this.Impact(null);
                }
                else
                {
                    this.Impact(this.usedTarget.Thing);
                }
            }
        }
        public override string GetExplanationUnfinalized(StatRequest req, ToStringNumberSense numberSense)
        {
            ThingDef thingDef = req.Def as ThingDef;

            if (thingDef == null)
            {
                return(null);
            }
            GetVerbsAndTools(thingDef, out var verbs, out var tools);
            Pawn currentWeaponUser = GetCurrentWeaponUser(req.Thing);
            IEnumerable <VerbUtility.VerbPropertiesWithSource> enumerable = from x in VerbUtility.GetAllVerbProperties(verbs, tools)
                                                                            where x.verbProps.IsMeleeAttack
                                                                            select x;
            StringBuilder stringBuilder = new StringBuilder();

            foreach (VerbUtility.VerbPropertiesWithSource item in enumerable)
            {
                float num  = item.verbProps.AdjustedMeleeDamageAmount(item.tool, currentWeaponUser, req.Thing, null);
                float num2 = item.verbProps.AdjustedCooldown(item.tool, currentWeaponUser, req.Thing);
                if (item.tool != null)
                {
                    stringBuilder.AppendLine($"  {item.tool.LabelCap} ({item.ToolCapacity.label})");
                }
                else
                {
                    stringBuilder.AppendLine(string.Format("  {0}:", "StatsReport_NonToolAttack".Translate()));
                }
                stringBuilder.AppendLine(string.Format("    {0} {1}", num.ToString("F1"), "DamageLower".Translate()));
                stringBuilder.AppendLine(string.Format("    {0} {1}", num2.ToString("F2"), "SecondsPerAttackLower".Translate()));
            }
            return(stringBuilder.ToString());
        }
Пример #9
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);
        }
        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();
                }
                CompReloadable comp2 = base.EquipmentSource.GetComp <CompReloadable>();
                if (comp2 != null)
                {
                    comp2.UsedOnce();
                }
            }
            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;
            var     casterTurret = caster as Building_TurretGun;
            Thing   gun          = null;

            if (casterTurret != null)
            {
                gun = casterTurret.gun;
            }
            var        newSource    = ApplyOffset(shootLine.Source, shootLine.Dest);
            var        newSourceVec = newSource.ToVector3();
            Projectile projectile2  = (Projectile)GenSpawn.Spawn(projectile, this.caster.Position, 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;
                        }
                        projectile2.Launch(launcher, newSourceVec, c, this.currentTarget, projectileHitFlags, false, 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;
                }
                projectile2.Launch(launcher, newSourceVec, shootLine.Dest, this.currentTarget, projectileHitFlags2, false, 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;
                }
                projectile2.Launch(launcher, newSourceVec, randomCoverToMissInto, this.currentTarget, projectileHitFlags3, false, 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)
            {
                projectile2.Launch(launcher, newSourceVec, this.currentTarget, this.currentTarget, projectileHitFlags4, false, equipment, targetCoverDef);
                this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell);
            }
            else
            {
                projectile2.Launch(launcher, newSourceVec, shootLine.Dest, this.currentTarget, projectileHitFlags4, false, equipment, targetCoverDef);
                this.ThrowDebugText("Hit\nDest", shootLine.Dest);
            }
            return(true);
        }
Пример #11
0
        public List <VerbEntry> GetUpdatedAvailableVerbsList(bool terrainTools)
        {
            meleeVerbs.Clear();
            verbsToAdd.Clear();
            if (!terrainTools)
            {
                List <Verb> allVerbs = pawn.verbTracker.AllVerbs;
                for (int i = 0; i < allVerbs.Count; i++)
                {
                    if (IsUsableMeleeVerb(allVerbs[i]))
                    {
                        verbsToAdd.Add(allVerbs[i]);
                    }
                }
                if (pawn.equipment != null)
                {
                    List <ThingWithComps> allEquipmentListForReading = pawn.equipment.AllEquipmentListForReading;
                    for (int j = 0; j < allEquipmentListForReading.Count; j++)
                    {
                        CompEquippable comp = allEquipmentListForReading[j].GetComp <CompEquippable>();
                        if (comp == null)
                        {
                            continue;
                        }
                        List <Verb> allVerbs2 = comp.AllVerbs;
                        if (allVerbs2 == null)
                        {
                            continue;
                        }
                        for (int k = 0; k < allVerbs2.Count; k++)
                        {
                            if (IsUsableMeleeVerb(allVerbs2[k]))
                            {
                                verbsToAdd.Add(allVerbs2[k]);
                            }
                        }
                    }
                }
                if (pawn.apparel != null)
                {
                    List <Apparel> wornApparel = pawn.apparel.WornApparel;
                    for (int l = 0; l < wornApparel.Count; l++)
                    {
                        CompEquippable comp2 = wornApparel[l].GetComp <CompEquippable>();
                        if (comp2 == null)
                        {
                            continue;
                        }
                        List <Verb> allVerbs3 = comp2.AllVerbs;
                        if (allVerbs3 == null)
                        {
                            continue;
                        }
                        for (int m = 0; m < allVerbs3.Count; m++)
                        {
                            if (IsUsableMeleeVerb(allVerbs3[m]))
                            {
                                verbsToAdd.Add(allVerbs3[m]);
                            }
                        }
                    }
                }
                foreach (Verb hediffsVerb in pawn.health.hediffSet.GetHediffsVerbs())
                {
                    if (IsUsableMeleeVerb(hediffsVerb))
                    {
                        verbsToAdd.Add(hediffsVerb);
                    }
                }
            }
            else if (pawn.Spawned)
            {
                TerrainDef terrain = pawn.Position.GetTerrain(pawn.Map);
                if (terrainVerbs == null || terrainVerbs.def != terrain)
                {
                    terrainVerbs = Pawn_MeleeVerbs_TerrainSource.Create(this, terrain);
                }
                List <Verb> allVerbs4 = terrainVerbs.tracker.AllVerbs;
                for (int n = 0; n < allVerbs4.Count; n++)
                {
                    Verb verb = allVerbs4[n];
                    if (IsUsableMeleeVerb(verb))
                    {
                        verbsToAdd.Add(verb);
                    }
                }
            }
            float num = 0f;

            foreach (Verb item in verbsToAdd)
            {
                float num2 = VerbUtility.InitialVerbWeight(item, pawn);
                if (num2 > num)
                {
                    num = num2;
                }
            }
            foreach (Verb item2 in verbsToAdd)
            {
                meleeVerbs.Add(new VerbEntry(item2, pawn, verbsToAdd, num));
            }
            return(meleeVerbs);

            bool IsUsableMeleeVerb(Verb v)
            {
                if (v.IsStillUsableBy(pawn))
                {
                    return(v.IsMeleeAttack);
                }
                return(false);
            }
        }
Пример #12
0
        public static bool GetUpdatedAvailableVerbsList(Pawn_MeleeVerbs __instance, ref List <VerbEntry> __result, bool terrainTools)
        {
            Pawn this_pawn = pawn(__instance);
            //meleeVerbs.Clear();
            //verbsToAdd.Clear();
            List <VerbEntry> meleeVerbs = new List <VerbEntry>();
            List <Verb>      verbsToAdd = new List <Verb>();

            if (!terrainTools)
            {
                List <Verb> allVerbs1 = this_pawn.verbTracker.AllVerbs;
                for (int index = 0; index < allVerbs1.Count; ++index)
                {
                    if (IsUsableMeleeVerb(allVerbs1[index]))
                    {
                        verbsToAdd.Add(allVerbs1[index]);
                    }
                }
                if (this_pawn.equipment != null)
                {
                    List <ThingWithComps> equipmentListForReading = this_pawn.equipment.AllEquipmentListForReading;
                    for (int index1 = 0; index1 < equipmentListForReading.Count; ++index1)
                    {
                        CompEquippable comp = equipmentListForReading[index1].GetComp <CompEquippable>();
                        if (comp != null)
                        {
                            List <Verb> allVerbs2 = comp.AllVerbs;
                            if (allVerbs2 != null)
                            {
                                for (int index2 = 0; index2 < allVerbs2.Count; ++index2)
                                {
                                    if (IsUsableMeleeVerb(allVerbs2[index2]))
                                    {
                                        verbsToAdd.Add(allVerbs2[index2]);
                                    }
                                }
                            }
                        }
                    }
                }
                if (this_pawn.apparel != null)
                {
                    List <Apparel> wornApparel = this_pawn.apparel.WornApparel;
                    for (int index1 = 0; index1 < wornApparel.Count; ++index1)
                    {
                        CompEquippable comp = wornApparel[index1].GetComp <CompEquippable>();
                        if (comp != null)
                        {
                            List <Verb> allVerbs2 = comp.AllVerbs;
                            if (allVerbs2 != null)
                            {
                                for (int index2 = 0; index2 < allVerbs2.Count; ++index2)
                                {
                                    if (IsUsableMeleeVerb(allVerbs2[index2]))
                                    {
                                        verbsToAdd.Add(allVerbs2[index2]);
                                    }
                                }
                            }
                        }
                    }
                }
                foreach (Verb hediffsVerb in this_pawn.health.hediffSet.GetHediffsVerbs())
                {
                    if (IsUsableMeleeVerb(hediffsVerb))
                    {
                        verbsToAdd.Add(hediffsVerb);
                    }
                }
            }
            else if (this_pawn.Spawned)
            {
                TerrainDef terrain = this_pawn.Position.GetTerrain(this_pawn.Map);
                if (terrainVerbs(__instance) == null || terrainVerbs(__instance).def != terrain)
                {
                    terrainVerbs(__instance) = Pawn_MeleeVerbs_TerrainSource.Create(__instance, terrain);
                }
                List <Verb> allVerbs = terrainVerbs(__instance).tracker.AllVerbs;
                for (int index = 0; index < allVerbs.Count; ++index)
                {
                    Verb v = allVerbs[index];
                    if (IsUsableMeleeVerb(v))
                    {
                        verbsToAdd.Add(v);
                    }
                }
            }
            float highestSelWeight = 0.0f;

            foreach (Verb v in verbsToAdd)
            {
                float num = VerbUtility.InitialVerbWeight(v, this_pawn);
                if ((double)num > (double)highestSelWeight)
                {
                    highestSelWeight = num;
                }
            }
            foreach (Verb verb in verbsToAdd)
            {
                meleeVerbs.Add(new VerbEntry(verb, this_pawn, verbsToAdd, highestSelWeight));
            }
            __result = meleeVerbs;
            return(false);

            bool IsUsableMeleeVerb(Verb v)
            {
                return(v.IsStillUsableBy(this_pawn) && v.IsMeleeAttack);
            }
        }
Пример #13
0
        public override string GetExplanationUnfinalized(StatRequest req, ToStringNumberSense numberSense)
        {
            ThingDef thingDef = req.Def as ThingDef;

            if (thingDef == null)
            {
                return(null);
            }
            Pawn currentWeaponUser = StatWorker_MeleeAverageDPS.GetCurrentWeaponUser(req.Thing);
            IEnumerable <VerbUtility.VerbPropertiesWithSource> enumerable = from x in VerbUtility.GetAllVerbProperties(thingDef.Verbs, thingDef.tools)
                                                                            where x.verbProps.IsMeleeAttack
                                                                            select x;
            StringBuilder stringBuilder = new StringBuilder();

            foreach (VerbUtility.VerbPropertiesWithSource verbPropertiesWithSource in enumerable)
            {
                float num  = verbPropertiesWithSource.verbProps.AdjustedMeleeDamageAmount(verbPropertiesWithSource.tool, currentWeaponUser, req.Thing, null);
                float num2 = verbPropertiesWithSource.verbProps.AdjustedCooldown(verbPropertiesWithSource.tool, currentWeaponUser, req.Thing);
                if (verbPropertiesWithSource.tool != null)
                {
                    stringBuilder.AppendLine(string.Format("  {0}: {1} ({2})", "Tool".Translate(), verbPropertiesWithSource.tool.LabelCap, verbPropertiesWithSource.ToolCapacity.defName));
                }
                else
                {
                    stringBuilder.AppendLine(string.Format("  {0}:", "StatsReport_NonToolAttack".Translate()));
                }
                stringBuilder.AppendLine(string.Format("    {0} {1}", num.ToString("F1"), "DamageLower".Translate()));
                stringBuilder.AppendLine(string.Format("    {0} {1}", num2.ToString("F2"), "SecondsPerAttackLower".Translate()));
                stringBuilder.AppendLine();
            }
            return(stringBuilder.ToString());
        }
Пример #14
0
        public bool TryCastShot_V1Vanilla_Modified()
        {
            var result = false;

            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, EquipmentSource); //TODO
                return(true);
            }

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

            //projectile.FreeIntercept = canFreeInterceptNow && !projectile.def.projectile.flyOverhead;
            if (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(this.verbProps.forcedMissRadius);
                    int num2 = Rand.Range(0, max);
                    if (num2 > 0)
                    {
                        if (DebugViewSettings.drawShooting)
                        {
                            MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToForRad", -1f);
                        }
                        var c = currentTarget.Cell + GenRadial.RadialPattern[num2];
                        ProjectileHitFlags projectileHitFlags;
                        if (Rand.Chance(0.5f))
                        {
                            projectileHitFlags = ProjectileHitFlags.NonTargetWorld;
                        }
                        else
                        {
                            projectileHitFlags = ProjectileHitFlags.All;
                        }
                        if (!this.canHitNonTargetPawnsNow)
                        {
                            projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns;
                        }
                        projectile.Launch(caster, currentTarget, c, projectileHitFlags, EquipmentSource); //TODO
                        return(true);
                    }
                }
            }
            var      shotReport            = ShotReport.HitReportFor(caster, this, currentTarget);
            Thing    randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
            ThingDef targetCoverDef        = (randomCoverToMissInto == null) ? null : randomCoverToMissInto.def;

            if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture))
            {
                if (DebugViewSettings.drawShooting)
                {
                    MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToWild", -1f);
                }
                shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget);
                ProjectileHitFlags projectileHitFlags2;
                if (Rand.Chance(0.5f))
                {
                    projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld;
                }
                else
                {
                    projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld;
                    if (this.canHitNonTargetPawnsNow)
                    {
                        projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns;
                    }
                }
                projectile.Launch(caster, currentTarget, shootLine.Dest, projectileHitFlags2, EquipmentSource); //TODO
                return(true);
            }
            if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance))
            {
                if (DebugViewSettings.drawShooting)
                {
                    MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToCover", -1f);
                }
                if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn)
                {
                    ProjectileHitFlags projectileHitFlags5 = ProjectileHitFlags.NonTargetWorld;
                    if (this.canHitNonTargetPawnsNow)
                    {
                        projectileHitFlags5 |= ProjectileHitFlags.NonTargetPawns;
                    }
                    projectile.Launch(caster, currentTarget, randomCoverToMissInto, projectileHitFlags5, EquipmentSource);
                    return(true);
                }
            }
            else
            {
                if (!Rand.Chance(shotReport.PassCoverChance))
                {
                    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)
                    {
                        ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld;
                        if (this.canHitNonTargetPawnsNow)
                        {
                            projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns;
                        }
                        projectile.Launch(caster, drawPos, randomCoverToMissInto, this.currentTarget,
                                          projectileHitFlags3, EquipmentSource, targetCoverDef);
                        return(true);
                    }
                }
                if (DebugViewSettings.drawShooting)
                {
                    MoteMaker.ThrowText(this.caster.DrawPos, this.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;
                }
                if (this.currentTarget.Thing != null)
                {
                    projectile.Launch(caster, drawPos, this.currentTarget, this.currentTarget, projectileHitFlags4,
                                      EquipmentSource, targetCoverDef);
                }
                else
                {
                    projectile.Launch(caster, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags4,
                                      EquipmentSource, targetCoverDef);
                }
                result = true;
            }
            return(result);
        }
        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);

            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(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) ? 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(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) ? string.Empty : "\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);
                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(launcher, drawPos, this.currentTarget, this.currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell);
            }
            else
            {
                projectile2.Launch(launcher, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                this.ThrowDebugText("Hit\nDest", shootLine.Dest);
            }
            if (this.CasterIsPawn)
            {
                VEF_ReflectionData.FI_Bullet_WeaponDamageMultiplier.SetValue(projectile2, (float)VEF_ReflectionData.FI_Bullet_WeaponDamageMultiplier.GetValue(projectile2) + ((this.caster.def.race.baseBodySize - 1f) * 0.5f));
            }
            return(true);
        }
Пример #16
0
        protected virtual (bool success, Vector3 launchPos, float angle) TryCastShotInternal()
        {
            if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map)
            {
                return(false, Vector3.zero, 0);
            }
            ThingDef projectile = Projectile;

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

            if (verbProps.stopBurstWithoutLos && !flag)
            {
                return(false, Vector3.zero, 0);
            }
            if (EquipmentSource != null)
            {
                CompChangeableProjectile comp = EquipmentSource.GetComp <CompChangeableProjectile>();
                if (comp != null)
                {
                    comp.Notify_ProjectileLaunched();
                }
                CompReloadable comp2 = EquipmentSource.GetComp <CompReloadable>();
                if (comp2 != null)
                {
                    comp2.UsedOnce();
                }
            }
            Thing        launcher     = caster;
            Thing        equipment    = EquipmentSource;
            CompMannable compMannable = caster.TryGetComp <CompMannable>();

            if (compMannable != null && compMannable.ManningPawn != null)
            {
                launcher  = compMannable.ManningPawn;
                equipment = caster;
            }
            Vector3    launchPos   = caster.DrawPos;
            float      angle       = launchPos.AngleToPoint(currentTarget.CenterVector3);
            Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, caster.Map, WipeMode.Vanish);

            if (caster.def.GetModExtension <ProjectilePropertiesDefModExtension>() is ProjectilePropertiesDefModExtension projectileProps)
            {
                projectile2.AllComps.Insert(0, new CompTurretProjectileProperties(CasterTWC)
                {
                    speed    = projectileProps.speed > 0 ? projectileProps.speed : projectile2.def.projectile.speed,
                    hitflag  = projectileProps.projectileHitFlag,
                    hitflags = projectileProps.hitFlagDef
                });
            }
            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];
                        launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(angle);
                        ThrowDebugText("ToRadius");
                        ThrowDebugText("Rad\nDest", c);
                        ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld;
                        if (Rand.Chance(0.5f))
                        {
                            projectileHitFlags = ProjectileHitFlags.All;
                        }
                        if (!canHitNonTargetPawnsNow)
                        {
                            projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns;
                        }
                        projectile2.Launch(launcher, launchPos, c, currentTarget, projectileHitFlags, equipment, null);
                        return(true, launchPos, angle);
                    }
                }
            }
            ShotReport shotReport            = ShotReport.HitReportFor(caster, this, currentTarget);
            Thing      randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
            ThingDef   targetCoverDef        = (randomCoverToMissInto != null) ? randomCoverToMissInto.def : null;

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

            if (canHitNonTargetPawnsNow)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns;
            }
            if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld;
            }
            ThrowDebugText("ToHit" + (canHitNonTargetPawnsNow ? "\nchntp" : ""));

            if (currentTarget.Thing != null)
            {
                angle      = launchPos.AngleToPoint(currentTarget.CenterVector3);
                launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(angle);
                projectile2.Launch(launcher, launchPos, currentTarget, currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                ThrowDebugText("Hit\nDest", currentTarget.Cell);
            }
            else
            {
                angle      = launchPos.AngleToPoint(shootLine.Dest.ToVector3Shifted());
                launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(angle);
                projectile2.Launch(launcher, launchPos, shootLine.Dest, currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                ThrowDebugText("Hit\nDest", shootLine.Dest);
            }
            return(true, launchPos, angle);
        }
        public override string GetExplanationUnfinalized(StatRequest req, ToStringNumberSense numberSense)
        {
            ThingDef thingDef = req.Def as ThingDef;

            if (thingDef == null)
            {
                return(null);
            }
            Pawn currentWeaponUser = StatWorker_MeleeAverageDPS.GetCurrentWeaponUser(req.Thing);
            IEnumerable <VerbUtility.VerbPropertiesWithSource> enumerable = from x in VerbUtility.GetAllVerbProperties(thingDef.Verbs, thingDef.tools)
                                                                            where x.verbProps.IsMeleeAttack
                                                                            select x;
            StringBuilder stringBuilder = new StringBuilder();

            foreach (VerbUtility.VerbPropertiesWithSource item in enumerable)
            {
                VerbUtility.VerbPropertiesWithSource current = item;
                float f = current.verbProps.AdjustedArmorPenetration(current.tool, currentWeaponUser, req.Thing, null);
                if (current.tool != null)
                {
                    stringBuilder.AppendLine(string.Format("  {0}: {1} ({2})", "Tool".Translate(), current.tool.LabelCap, current.ToolCapacity.defName));
                }
                else
                {
                    stringBuilder.AppendLine(string.Format("  {0}:", "StatsReport_NonToolAttack".Translate()));
                }
                stringBuilder.AppendLine("    " + f.ToStringPercent());
                stringBuilder.AppendLine();
            }
            return(stringBuilder.ToString());
        }
        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);
        }
Пример #19
0
        private void ImpactSomething()
        {
            if (def.projectile.flyOverhead)
            {
                RoofDef roofDef = base.Map.roofGrid.RoofAt(base.Position);
                if (roofDef != null)
                {
                    if (roofDef.isThickRoof)
                    {
                        ThrowDebugText("hit-thick-roof", Position);
                        def.projectile.soundHitThickRoof.PlayOneShot(new TargetInfo(Position, Map, false));
                        Destroy(DestroyMode.Vanish);
                        return;
                    }
                    if (Position.GetEdifice(Map) == null || Position.GetEdifice(Map).def.Fillage != FillCategory.Full)
                    {
                        RoofCollapserImmediate.DropRoofInCells(Position, Map, null);
                    }
                }
            }
            if (!usedTarget.HasThing || !CanHit(usedTarget.Thing))
            {
                cellThingsFiltered.Clear();
                List <Thing> thingList = Position.GetThingList(Map);
                for (int i = 0; i < thingList.Count; i++)
                {
                    Thing thing = thingList[i];
                    if ((thing.def.category == ThingCategory.Building || thing.def.category == ThingCategory.Pawn || thing.def.category == ThingCategory.Item || thing.def.category == ThingCategory.Plant) && this.CanHit(thing))
                    {
                        cellThingsFiltered.Add(thing);
                    }
                }
                cellThingsFiltered.Shuffle();
                for (int j = 0; j < cellThingsFiltered.Count; j++)
                {
                    Thing thing2 = cellThingsFiltered[j];
                    Pawn  pawn   = thing2 as Pawn;
                    float num;
                    if (pawn != null)
                    {
                        num = 0.5f * Mathf.Clamp(pawn.BodySize, 0.1f, 2f);
                        if (pawn.GetPosture() != PawnPosture.Standing && (origin - destination).MagnitudeHorizontalSquared() >= 20.25f)
                        {
                            num *= 0.2f;
                        }
                        if (launcher != null && pawn.Faction != null && launcher.Faction != null && !pawn.Faction.HostileTo(launcher.Faction))
                        {
                            num *= VerbUtility.InterceptChanceFactorFromDistance(origin, Position);
                        }
                    }
                    else
                    {
                        num = 1.5f * thing2.def.fillPercent;
                    }
                    if (Rand.Chance(num))
                    {
                        ThrowDebugText("hit-" + num.ToStringPercent(), base.Position);
                        Impact(cellThingsFiltered.RandomElement <Thing>());
                        return;
                    }
                    ThrowDebugText("miss-" + num.ToStringPercent(), base.Position);
                }
                Impact(null);
                return;
            }
            Pawn pawn2 = usedTarget.Thing as Pawn;

            if (pawn2 != null && pawn2.GetPosture() != PawnPosture.Standing && (this.origin - this.destination).MagnitudeHorizontalSquared() >= 20.25f && !Rand.Chance(0.2f))
            {
                ThrowDebugText("miss-laying", base.Position);
                Impact(null);
                return;
            }
            Impact(usedTarget.Thing);
        }
Пример #20
0
        private void RequestVerbs(RequestVerbsMessage req, EntitySessionEventArgs eventArgs)
        {
            var player = (IPlayerSession)eventArgs.SenderSession;

            if (!_entityManager.TryGetEntity(req.EntityUid, out var entity))
            {
                Logger.Warning($"{nameof(RequestVerbs)} called on a nonexistant entity with id {req.EntityUid} by player {player}.");
                return;
            }

            var userEntity = player.AttachedEntity;

            if (userEntity == null)
            {
                Logger.Warning($"{nameof(UseVerb)} called by player {player} with no attached entity.");
                return;
            }

            if (!TryGetContextEntities(userEntity, entity.Transform.MapPosition, out var entities, true) || !entities.Contains(entity))
            {
                return;
            }

            var data = new List <VerbsResponseMessage.NetVerbData>();

            //Get verbs, component dependent.
            foreach (var(component, verb) in VerbUtility.GetVerbs(entity))
            {
                if (!VerbUtility.VerbAccessChecks(userEntity, entity, verb))
                {
                    continue;
                }

                var verbData = verb.GetData(userEntity, component);
                if (verbData.IsInvisible)
                {
                    continue;
                }

                // TODO: These keys being giant strings is inefficient as hell.
                data.Add(new VerbsResponseMessage.NetVerbData(verbData, $"{component.GetType()}:{verb.GetType()}"));
            }

            //Get global verbs. Visible for all entities regardless of their components.
            foreach (var globalVerb in VerbUtility.GetGlobalVerbs(Assembly.GetExecutingAssembly()))
            {
                if (!VerbUtility.VerbAccessChecks(userEntity, entity, globalVerb))
                {
                    continue;
                }

                var verbData = globalVerb.GetData(userEntity, entity);
                if (verbData.IsInvisible)
                {
                    continue;
                }

                data.Add(new VerbsResponseMessage.NetVerbData(verbData, globalVerb.GetType().ToString()));
            }

            var response = new VerbsResponseMessage(data.ToArray(), req.EntityUid);

            RaiseNetworkEvent(response, player.ConnectedClient);
        }