protected override bool TryCastShot()
        {
            var result = base.TryCastShot();

            try
            {
                if (compBuffM == null)
                {
                    compBuffM  = EquipmentSource.GetComp <CompBuffManager>();
                    properties = (NegativeRecoilProperties)verbProps;
                }

                //네거티브 리코일 버프가 없다면
                if (!(compBuffM.FindWithDef(properties.weaponBuffDef) is NegativeRecoilBuff nRWBuff))
                {
                    compBuffM.AddBuff(properties.weaponBuffDef, EquipmentSource);
                }
                else
                {
                    nRWBuff.AddOverlapLevel(1);
                }

                if (!(compBuffM.FindWithDef(properties.pawnBuffDef) is NegativeRecoilBuff nRPBuff))
                {
                    compBuffM.AddBuff(properties.pawnBuffDef, EquipmentSource);
                }
Пример #2
0
 protected override bool TryCastShot()
 {
     if (burstShotsLeft > 1)
     {
         RatkinSoundDefOf.RK_Charge.PlayOneShot(new TargetInfo(caster.Position, caster.Map, false));
         if (verbProps.consumeFuelPerShot > 0f)
         {
             CompRefuelable compGunlance = EquipmentSource.TryGetComp <CompGunlanceFuel>();
             if (compGunlance != null)
             {
                 compGunlance.ConsumeFuel(verbProps.consumeFuelPerShot);
             }
         }
         AttachableThing_GunlanceIgnition ignition = ThingMaker.MakeThing(GunlanceDefOf.GunlancePreIgnition, null) as AttachableThing_GunlanceIgnition;
         ignition.AttachTo(CasterPawn);
         GenSpawn.Spawn(ignition, CasterPawn.Position, CasterPawn.Map, caster.Rotation, WipeMode.Vanish, false);
     }
     else
     {
         CasterPawn.GetAttachment(GunlanceDefOf.GunlancePreIgnition).Destroy();
         AttachableThing_AfterIgnition ignition = ThingMaker.MakeThing(GunlanceDefOf.GunlanceAfterIgnition, null) as AttachableThing_AfterIgnition;
         ignition.AttachTo(CasterPawn);
         GenSpawn.Spawn(ignition, CasterPawn.Position, CasterPawn.Map, caster.Rotation, WipeMode.Vanish, false);
         RatkinSoundDefOf.RK_WyvernFire.PlayOneShot(new TargetInfo(caster.Position, caster.Map, false));
         MakeExplosion();
     }
     return(true);
 }
Пример #3
0
 internal Equipment(EquipmentId id,
                    EquipmentClass eClass,
                    BonusType bonusType,
                    EquipmentRarity rarity,
                    double attributeBase,
                    double attributeBaseInc,
                    double attributeExp1,
                    double attributeExp2,
                    double attributeExpBase,
                    EquipmentSource source,
                    double[] _1163,
                    double[] _2095,
                    double[] _4450,
                    string fileVersion,
                    Func <string, ValueTask <Bitmap> > imageGetter = null)
 {
     Id               = id;
     Class            = eClass;
     BonusType        = bonusType;
     Rarity           = rarity;
     AttributeBase    = attributeBase;
     AttributeBaseInc = attributeBaseInc;
     AttributeExp1    = attributeExp1;
     AttributeExp2    = attributeExp2;
     AttributeExpBase = attributeExpBase;
     Source           = source;
     this._1163       = _1163;
     this._2095       = _2095;
     this._4450       = _4450;
     FileVersion      = fileVersion;
     ImageGetter      = imageGetter;
 }
Пример #4
0
        public virtual ShiftVecReport ShiftVecReportFor(LocalTargetInfo target)
        {
            IntVec3        targetCell = target.Cell;
            ShiftVecReport report     = new ShiftVecReport();

            report.target           = target;
            report.aimingAccuracy   = AimingAccuracy;
            report.sightsEfficiency = SightsEfficiency;
            report.shotDist         = (targetCell - caster.Position).LengthHorizontal;
            report.maxRange         = verbProps.range;

            report.lightingShift = 1 - caster.Map.glowGrid.GameGlowAt(targetCell);
            if (!caster.Position.Roofed(caster.Map) || !targetCell.Roofed(caster.Map))  //Change to more accurate algorithm?
            {
                report.weatherShift = 1 - caster.Map.weatherManager.CurWeatherAccuracyMultiplier;
            }
            report.shotSpeed   = ShotSpeed;
            report.swayDegrees = SwayAmplitude;
            var spreadmult = projectilePropsCE != null ? projectilePropsCE.spreadMult : 0f;

            report.spreadDegrees = (EquipmentSource?.GetStatValue(StatDef.Named("ShotSpread")) ?? 0) * spreadmult;
            Thing cover;
            float smokeDensity;

            GetHighestCoverAndSmokeForTarget(target, out cover, out smokeDensity);
            report.cover        = cover;
            report.smokeDensity = smokeDensity;

            return(report);
        }
Пример #5
0
        protected override bool TryCastShot()
        {
            Log.Message("test3");
            AERIALChangeableProjectile comp = EquipmentSource.GetComp <AERIALChangeableProjectile>();
            Thing    launcher   = caster;
            ThingDef projectile = Projectile;

            if (projectile == null)
            {
                return(false);
            }
            Log.Message("test");
            Thing     equipment = EquipmentSource;
            Vector3   drawPos   = this.caster.DrawPos;
            ShootLine shootLine;
            bool      flag = base.TryFindShootLineFromTo(caster.Position, currentTarget, out shootLine);
            float     num  = VerbUtility.CalculateAdjustedForcedMiss(this.verbProps.forcedMissRadius, this.currentTarget.Cell - this.caster.Position);
            int       max  = GenRadial.NumCellsInRadius(num);
            int       num2 = Rand.Range(0, max);
            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;
            }
            IntVec3 pos = shootLine.Source;

            pos.x += 20;
            pos.z += 20;
            Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, pos, this.caster.Map, WipeMode.Vanish);

            projectile2.Launch(launcher, drawPos, c, this.currentTarget, projectileHitFlags, equipment, null);
            comp.loadedShells.RemoveAt(comp.loadedShells.Count - 1);

            if (!comp.loadedShells.NullOrEmpty())
            {
                pos         = shootLine.Source;
                pos.z      -= 20;
                pos.x      -= 20;
                projectile  = Projectile;
                projectile2 = (Projectile)GenSpawn.Spawn(projectile, pos, this.caster.Map, WipeMode.Vanish);
                projectile2.Launch(launcher, drawPos, c, this.currentTarget, projectileHitFlags, equipment, null);
                comp.loadedShells.RemoveAt(comp.loadedShells.Count - 1);
            }

            Log.Message($"{comp.loadedShells.Count}");
            return(true);
        }
Пример #6
0
 private void SelfConsume()
 {
     if (remainBullet > 0)
     {
         remainBullet--;
     }
     else
     {
         EquipmentSource.GetComp <CompEquippable>().AllVerbs.Remove(this);
     }
 }
Пример #7
0
 internal Equipment(EquipmentStatic staticData, EquipmentClass eClass, BonusType bonusType, EquipmentRarity rarity, double bonusBase, double bonusIncrease, EquipmentSource source, Bitmap image, string fileVersion)
 {
     _staticData   = staticData;
     Class         = eClass;
     BonusType     = bonusType;
     Rarity        = rarity;
     BonusBase     = bonusBase;
     BonusIncrease = bonusIncrease;
     Source        = source;
     Image         = image;
     FileVersion   = fileVersion;
 }
Пример #8
0
        protected override bool TryCastShot()
        {
            if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map)
            {
                return(false);
            }
            Map     target  = caster.Map;
            IntVec3 intVec3 = currentTarget.Cell;

            DropPodUtility.DropThingsNear(intVec3, target, _emergencyResourcesList, 110, false, true);
            if (EquipmentSource != null && !EquipmentSource.Destroyed)
            {
                EquipmentSource.Destroy();
            }
            return(true);
        }
Пример #9
0
 public override bool Available()
 {
     if (burstShotsLeft > 0)
     {
         return(true);
     }
     if (verbProps.consumeFuelPerShot > 0f)
     {
         CompGunlanceFuel compGunlance = EquipmentSource.TryGetComp <CompGunlanceFuel>();
         if ((compGunlance != null && compGunlance.Fuel < verbProps.consumeFuelPerShot))
         {
             return(false);
         }
     }
     return(true);
 }
Пример #10
0
        public virtual bool Available()
        {
            if (verbProps.consumeFuelPerShot > 0f)
            {
                CompRefuelable compRefuelable = caster.TryGetComp <CompRefuelable>();
                if (compRefuelable != null && compRefuelable.Fuel < verbProps.consumeFuelPerShot)
                {
                    return(false);
                }
            }
            CompReloadable compReloadable = EquipmentSource?.GetComp <CompReloadable>();

            if (compReloadable != null && !compReloadable.CanBeUsed)
            {
                return(false);
            }
            return(true);
        }
Пример #11
0
        protected override bool TryCastShot()
        {
            if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map)
            {
                return(false);
            }

            var mechfall = (MechFall)GenSpawn.Spawn(ThingDefOf.MechFallBeam, currentTarget.Cell, caster.Map);

            mechfall.duration   = 450;
            mechfall.instigator = caster;
            mechfall.weaponDef  = EquipmentSource?.def;
            mechfall.StartStrike();
            if (EquipmentSource != null && !EquipmentSource.Destroyed)
            {
                EquipmentSource.Destroy();
            }
            return(true);
        }
Пример #12
0
        public virtual ShiftVecReport ShiftVecReportFor(LocalTargetInfo target)
        {
            IntVec3        targetCell = target.Cell;
            ShiftVecReport report     = new ShiftVecReport();

            report.target           = target;
            report.aimingAccuracy   = AimingAccuracy;
            report.sightsEfficiency = SightsEfficiency;
            report.shotDist         = (targetCell - caster.Position).LengthHorizontal;
            report.maxRange         = verbProps.range;
            report.lightingShift    = CE_Utility.GetLightingShift(caster, LightingTracker.CombatGlowAtFor(caster.Position, targetCell));

            if (!caster.Position.Roofed(caster.Map) || !targetCell.Roofed(caster.Map))  //Change to more accurate algorithm?
            {
                report.weatherShift = 1 - caster.Map.weatherManager.CurWeatherAccuracyMultiplier;
            }
            report.shotSpeed   = ShotSpeed;
            report.swayDegrees = SwayAmplitude;
            var spreadmult = projectilePropsCE != null ? projectilePropsCE.spreadMult : 0f;

            report.spreadDegrees = (EquipmentSource?.GetStatValue(StatDef.Named("ShotSpread")) ?? 0) * spreadmult;
            Thing cover;
            float smokeDensity;

            GetHighestCoverAndSmokeForTarget(target, out cover, out smokeDensity);
            report.cover        = cover;
            report.smokeDensity = smokeDensity;

            if (Controller.settings.DebugVerbose)
            {
                Log.Message($"<color=red>CE</color>: <color=orange>{caster}</color> shooting <color=orange>{target.Thing}</color> <color=yellow>ShiftVecReport</color>\n" +
                            $"1- aimingAccuracy:{report.aimingAccuracy}\n" +
                            $"2- sightsEfficiency:{report.sightsEfficiency}\n" +
                            $"3- maxRange:{report.maxRange}\n" +
                            $"4- lightingShift:{report.lightingShift}\n" +
                            $"5- spreadDegrees:{report.spreadDegrees}\n" +
                            $"6- smokeDensity:{report.smokeDensity}\n" +
                            $"7- swayDegrees:{report.swayDegrees}\n" +
                            $"8- shotSpeed:{report.shotSpeed}\n" +
                            $"9- shotDist:{report.shotDist}\n");
            }
            return(report);
        }
        private NSEquipmentDetail HandlerQueue_NationalStandard(EquipmentSource datare)
        {
            byte[] data = datare.RawData;
            if (data.Length < 15)
            {
                return(null);
            }

            NSEquipmentDetail equipmentDetail = new NSEquipmentDetail();

            try
            {
                log.Info("开始解析数据-" + data.Length);

                string outMsg; //返回的错误信息,正确解析则返回空
                var    detail = EquipmentHelper.HandleData_NS(data, out outMsg);

                if (detail != null && string.IsNullOrWhiteSpace(outMsg))
                {
                    #region 解析EquipmentDetail
                    foreach (var key in detail.Keys)
                    {
                        var proInfo = typeof(NSEquipmentDetail).GetProperty(key.ToString());
                        if (null != proInfo)
                        {
                            var eqValue = EquipmentHelper.GetNSEquipmentValue(key, detail[key], equipmentDetail);
                            proInfo.SetValue(equipmentDetail, eqValue, null);
                        }
                    }
                    #endregion
                }
                else
                {
                    equipmentDetail = null;
                }
            }
            catch (Exception ex)
            {
                log.Error("设备详细信息解析异常", ex);
                equipmentDetail = null;
            }
            return(equipmentDetail);
        }
Пример #14
0
        public void Explosion()
        {
            Map map2 = EquipmentSource.Map;

            GenExplosion.DoExplosion
            (
                center: currentTarget.Thing.Position,
                map: CasterPawn.Map,
                radius: 2f,
                damType: RatkinDamageDefOf.DemoBomb,
                instigator: EquipmentSource,
                damAmount: 15,
                armorPenetration: 0.60f,
                explosionSound: null,
                weapon: EquipmentSource.def,
                projectile: null,
                intendedTarget: currentTarget.Thing,
                chanceToStartFire: 0,
                damageFalloff: true
            );
            if (CasterPawn != null && CasterPawn.inventory != null)
            {
                Thing magicWand = CasterPawn.inventory.innerContainer.FirstOrDefault((Thing t) => t != null && t.def == RatkinWeaponDefOf.RK_MagicWand);
                if (magicWand != null)
                {
                    magicWand.stackCount -= 1;
                    if (magicWand.stackCount <= 0)
                    {
                        CasterPawn.inventory.innerContainer.Remove(magicWand);
                        CasterPawn.inventory.Notify_ItemRemoved(magicWand);
                        magicWand.Destroy(DestroyMode.Vanish);
                    }
                }
                else
                {
                    if (EquipmentSource != null && !EquipmentSource.Destroyed)
                    {
                        EquipmentSource.Destroy(DestroyMode.Vanish);
                    }
                }
            }
        }
Пример #15
0
        protected override bool TryCastShot()
        {
            bool result = base.TryCastShot();

            try
            {
                if (compBuffM == null)
                {
                    compBuffM  = EquipmentSource.GetComp <CompBuffManager>();
                    properties = (NegativeRecoilProperties)verbProps;
                }
                NegativeRecoilBuff nRWBuff = compBuffM.FindWithDef(properties.weaponBuffDef) as NegativeRecoilBuff;
                NegativeRecoilBuff nRPBuff = compBuffM.FindWithDef(properties.pawnBuffDef) as NegativeRecoilBuff;
                //네거티브 리코일 버프가 없다면
                if (nRWBuff == null)
                {
                    compBuffM.AddBuff(properties.weaponBuffDef, EquipmentSource);
                }
                else
                {
                    nRWBuff.AddOverlapLevel(1);
                }

                if (nRPBuff == null)
                {
                    compBuffM.AddBuff(properties.pawnBuffDef, EquipmentSource);
                }
                else
                {
                    nRPBuff.AddOverlapLevel(1);
                }
            }
            catch (Exception ee)
            {
                Log.Error("Error : " + ee.ToString());
            }

            return(result);
        }
Пример #16
0
        protected override bool TryCastShot()
        {
            // 水チェック
            var comp = EquipmentSource.GetComp <CompWaterTool>();

            if (comp.StoredWaterVolumePercent < NeedWaterPercentage)
            {
                return(false);
            }

            // 通常の投擲チェック
            if (base.TryCastShot() == false)
            {
                return(false);
            }

            // 投擲できた場合は水を減らす
            comp.StoredWaterVolume = 0f;

            // グラフィック更新
            EquipmentSource.Tick();

            return(true);
        }
Пример #17
0
        protected void TryCastNextBurstShot()
        {
            LocalTargetInfo localTargetInfo = currentTarget;

            if (Available() && TryCastShot())
            {
                if (verbProps.muzzleFlashScale > 0.01f)
                {
                    MoteMaker.MakeStaticMote(caster.Position, caster.Map, ThingDefOf.Mote_ShotFlash, verbProps.muzzleFlashScale);
                }
                if (verbProps.soundCast != null)
                {
                    verbProps.soundCast.PlayOneShot(new TargetInfo(caster.Position, caster.Map));
                }
                if (verbProps.soundCastTail != null)
                {
                    verbProps.soundCastTail.PlayOneShotOnCamera(caster.Map);
                }
                if (CasterIsPawn)
                {
                    if (CasterPawn.thinker != null)
                    {
                        CasterPawn.mindState.Notify_EngagedTarget();
                    }
                    if (CasterPawn.mindState != null)
                    {
                        CasterPawn.mindState.Notify_AttackedTarget(localTargetInfo);
                    }
                    if (CasterPawn.MentalState != null)
                    {
                        CasterPawn.MentalState.Notify_AttackedTarget(localTargetInfo);
                    }
                    if (TerrainDefSource != null)
                    {
                        CasterPawn.meleeVerbs.Notify_UsedTerrainBasedVerb();
                    }
                    if (CasterPawn.health != null)
                    {
                        CasterPawn.health.Notify_UsedVerb(this, localTargetInfo);
                    }
                    if (EquipmentSource != null)
                    {
                        EquipmentSource.Notify_UsedWeapon(CasterPawn);
                    }
                    if (!CasterPawn.Spawned)
                    {
                        return;
                    }
                }
                if (verbProps.consumeFuelPerShot > 0f)
                {
                    caster.TryGetComp <CompRefuelable>()?.ConsumeFuel(verbProps.consumeFuelPerShot);
                }
                burstShotsLeft--;
            }
            else
            {
                burstShotsLeft = 0;
            }
            if (burstShotsLeft > 0)
            {
                ticksToNextBurstShot = verbProps.ticksBetweenBurstShots;
                if (CasterIsPawn)
                {
                    CasterPawn.stances.SetStance(new Stance_Cooldown(verbProps.ticksBetweenBurstShots + 1, currentTarget, this));
                }
                return;
            }
            state = VerbState.Idle;
            if (CasterIsPawn)
            {
                CasterPawn.stances.SetStance(new Stance_Cooldown(verbProps.AdjustedCooldownTicks(this, CasterPawn), currentTarget, this));
            }
            if (castCompleteCallback != null)
            {
                castCompleteCallback();
            }
        }
        /// <summary>
        /// 解析终端设备工作状态
        /// </summary>
        /// <param name="data"></param>
        /// <returns>设备状态</returns>
        private EquipmentDetail HandlerQueue(EquipmentSource datare)
        {
            byte[] data = datare.RawData;
            if (data.Length < 13)
            {
                return(null);
            }

            EquipmentDetail equipmentDetail = new EquipmentDetail();

            try
            {
                equipmentDetail.IPAddressTmpFormat = datare.RemoteIPTmp;
                equipmentDetail.RemotePortTmp      = (ushort)datare.RemotePortTmp;
                log.Info("开始解析数据-" + data.Length);
                equipmentDetail.SrvTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                FeaturesCode fc;
                string       outMsg; //返回的错误信息,正确解析则返回空
                var          detail = EquipmentHelper.HandleData(data, out fc, out outMsg);

                if (detail != null && string.IsNullOrWhiteSpace(outMsg) && detail.ContainsKey(Equipment.PhysicalAddress))
                {
                    var msgType = Convert.ToChar(data[0]);
                    if (msgType == '&')
                    {
                        //帧头占12字节
                        equipmentDetail.HeaderData = data.Take(12).ToArray();
                    }
                    else if (msgType == '%')
                    {
                        //帧头占18字节
                        equipmentDetail.HeaderData = data.Take(18).ToArray();
                    }
                    byte[] address = detail[Equipment.PhysicalAddress];//每个包必须有物理码

                    string pp = "";
                    for (int i = 0; i < address.Length; i++)
                    {
                        pp += address[i].ToString("X2");// bytes[i].ToString("X2").PadLeft(2, '0');
                    }


                    clientsConn.AddOrUpdate(pp, datare.ConnId, (key, value) => { return(value = datare.ConnId); });

                    clientsHeadData.AddOrUpdate(pp, equipmentDetail.HeaderData, (key, value) => { return(value = equipmentDetail.HeaderData); });
                    #region 解析EquipmentDetail
                    foreach (var key in detail.Keys)
                    {
                        if (key.ToString() == "RemoteControlCenterIPAddress")
                        {
                            int ppr = 0;
                            int ffp = 1;
                            int fs  = ppr + ffp;
                            Console.Write("");
                        }
                        var proInfo = typeof(EquipmentDetail).GetProperty(key.ToString());
                        if (null != proInfo)
                        {
                            var eqValue = EquipmentHelper.GetEquipmentValue(key, detail[key], equipmentDetail);
                            proInfo.SetValue(equipmentDetail, eqValue, null);
                            typeof(EquipmentDetail).GetProperty(key.ToString() + "Format").SetValue(equipmentDetail,
                                                                                                    EquipmentHelper.GetEquipmentValueString(key, eqValue), null);
                        }
                    }
                    #endregion

                    var dataHeader = EquipmentHelper.HandleHeader(EquipmentHelper.GetFrameHeader(data));
                    if (dataHeader != null)
                    {
                        equipmentDetail.FactoryName = dataHeader[FrameHeaderEnum.FactoryNumber];
                    }
                }
                else
                {
                    equipmentDetail = null;
                }
            }
            catch (Exception ex)
            {
                log.Error("设备详细信息解析异常", ex);
                equipmentDetail = null;
            }
            return(equipmentDetail);
        }
Пример #19
0
        private IEnumerable <DamageInfo> DamageInfosToApply(LocalTargetInfo target)
        {
            float            damAmount2       = verbProps.AdjustedMeleeDamageAmount(this, base.CasterPawn);
            float            armorPenetration = verbProps.AdjustedArmorPenetration(this, base.CasterPawn);
            DamageDef        damDef           = verbProps.meleeDamageDef;
            BodyPartGroupDef bodyPartGroupDef = null;
            HediffDef        hediffDef        = null;

            float additionalMultiplier = 1f;

            if (target.Thing != null)
            {
                if (target.Thing is Pawn pawn)
                {
                    if (pawn.RaceProps.IsMechanoid)
                    {
                        additionalMultiplier = 5f;
                    }
                }
                if (target.Thing is Building building)
                {
                    if (building.Stuff != null && building.Stuff.stuffProps != null)
                    {
                        StuffCategoryDef stuffCategoryDef = building.Stuff.stuffProps.categories.FirstOrDefault();
                        if (stuffCategoryDef != null)
                        {
                            if (stuffCategoryDef == StuffCategoryDefOf.Metallic)
                            {
                                additionalMultiplier = 4f;
                            }
                        }
                    }
                }
            }

            if (EquipmentSource != null)
            {
                CompChargeableWeapon compChargeableWeapon = EquipmentSource.TryGetComp <CompChargeableWeapon>();
                if (compChargeableWeapon != null)
                {
                    if (compChargeableWeapon.Charge < compChargeableWeapon.Props.ChargePerShot)
                    {
                        additionalMultiplier = 1f;
                    }
                    else
                    {
                        compChargeableWeapon.Used();
                    }
                }
            }

            damAmount2 = Rand.Range(damAmount2 * 0.8f, damAmount2 * 1.2f) * additionalMultiplier;

            if (base.CasterIsPawn)
            {
                bodyPartGroupDef = verbProps.AdjustedLinkedBodyPartsGroup(tool);
                if (damAmount2 >= 1f)
                {
                    if (base.HediffCompSource != null)
                    {
                        hediffDef = base.HediffCompSource.Def;
                    }
                }
                else
                {
                    damAmount2 = 1f;
                    damDef     = DamageDefOf.Blunt;
                }
            }
            ThingDef   source            = (base.EquipmentSource == null) ? base.CasterPawn.def : base.EquipmentSource.def;
            Vector3    direction         = (target.Thing.Position - base.CasterPawn.Position).ToVector3();
            DamageDef  def               = damDef;
            float      amount            = damAmount2;
            float      armorPenetration2 = armorPenetration;
            Thing      caster            = base.caster;
            DamageInfo mainDinfo         = new DamageInfo(def, amount, armorPenetration2, -1f, caster, null, source);

            mainDinfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside);
            mainDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
            mainDinfo.SetWeaponHediff(hediffDef);
            mainDinfo.SetAngle(direction);
            yield return(mainDinfo);

            if (surpriseAttack && ((verbProps.surpriseAttack != null && !verbProps.surpriseAttack.extraMeleeDamages.NullOrEmpty()) || (tool != null && tool.surpriseAttack != null && !tool.surpriseAttack.extraMeleeDamages.NullOrEmpty())))
            {
                IEnumerable <ExtraDamage> extraDamages = Enumerable.Empty <ExtraDamage>();
                if (verbProps.surpriseAttack != null && verbProps.surpriseAttack.extraMeleeDamages != null)
                {
                    extraDamages = extraDamages.Concat(verbProps.surpriseAttack.extraMeleeDamages);
                }
                if (tool != null && tool.surpriseAttack != null && !tool.surpriseAttack.extraMeleeDamages.NullOrEmpty())
                {
                    extraDamages = extraDamages.Concat(tool.surpriseAttack.extraMeleeDamages);
                }
                foreach (ExtraDamage extraDamage in extraDamages)
                {
                    int   extraDamageAmount           = GenMath.RoundRandom(extraDamage.AdjustedDamageAmount(this, base.CasterPawn));
                    float extraDamageArmorPenetration = extraDamage.AdjustedArmorPenetration(this, base.CasterPawn);
                    def = extraDamage.def;
                    armorPenetration2 = extraDamageAmount;
                    amount            = extraDamageArmorPenetration;
                    caster            = base.caster;
                    DamageInfo extraDinfo = new DamageInfo(def, armorPenetration2, amount, -1f, caster, null, source);
                    extraDinfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside);
                    extraDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
                    extraDinfo.SetWeaponHediff(hediffDef);
                    extraDinfo.SetAngle(direction);
                    yield return(extraDinfo);
                }
            }
        }
Пример #20
0
 public static LocalisedString Localisable(EquipmentSource source)
 => new LocalisedString(BASE_PATH + source.ToString().ToUpper());
Пример #21
0
 public static ILocalisable <string> ToLocalisable(this EquipmentSource equipSource)
 => EquipmentSourceText.Localisable(equipSource);
Пример #22
0
        /// <summary>
        /// Performs the actual melee attack part. Awards XP, calculates and applies whether an attack connected and the outcome.
        /// </summary>
        /// <returns>True if the attack connected, false otherwise</returns>
        protected override bool TryCastShot()
        {
            Pawn casterPawn = CasterPawn;

            if (casterPawn.stances.FullBodyBusy)
            {
                return(false);
            }
            Thing targetThing = currentTarget.Thing;

            if (!CanHitTarget(targetThing))
            {
                Log.Warning(string.Concat(new object[]
                {
                    casterPawn,
                    " meleed ",
                    targetThing,
                    " from out of melee position."
                }));
            }
            casterPawn.rotationTracker.Face(targetThing.DrawPos);

            // Award XP as per vanilla
            bool targetImmobile = IsTargetImmobile(currentTarget);

            if (!targetImmobile && casterPawn.skills != null)
            {
                casterPawn.skills.Learn(SkillDefOf.Melee, HitXP, false);
            }

            // Hit calculations
            bool     result;
            string   moteText = "";
            SoundDef soundDef;
            Pawn     defender = targetThing as Pawn;

            //var hitRoll = Rand.Value;
            if (Rand.Chance(GetHitChance(targetThing)))
            {
                // Check for dodge
                if (!targetImmobile && !surpriseAttack && Rand.Chance(defender.GetStatValue(StatDefOf.MeleeDodgeChance)))
                {
                    // Attack is evaded
                    result   = false;
                    soundDef = SoundMiss();
                    CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesDodge, false);

                    moteText = "TextMote_Dodge".Translate();
                    defender.skills?.Learn(SkillDefOf.Melee, DodgeXP, false);
                }
                else
                {
                    // Attack connects, calculate resolution
                    //var resultRoll = Rand.Value;
                    var parryBonus  = 1 / EquipmentSource?.GetStatValue(CE_StatDefOf.MeleeCounterParryBonus) ?? 1;
                    var parryChance = GetComparativeChanceAgainst(defender, casterPawn, CE_StatDefOf.MeleeParryChance, BaseParryChance, parryBonus);
                    if (!surpriseAttack && defender != null && CanDoParry(defender) && Rand.Chance(parryChance))
                    {
                        // Attack is parried
                        Apparel shield        = defender.apparel.WornApparel.FirstOrDefault(x => x is Apparel_Shield);
                        bool    isShieldBlock = shield != null && Rand.Chance(ShieldBlockChance);
                        Thing   parryThing    = isShieldBlock ? shield
                            : defender.equipment?.Primary ?? defender;

                        if (Rand.Chance(GetComparativeChanceAgainst(defender, casterPawn, CE_StatDefOf.MeleeCritChance, BaseCritChance)))
                        {
                            // Do a riposte
                            DoParry(defender, parryThing, true);
                            moteText = "CE_TextMote_Riposted".Translate();
                            CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesDeflect, false); //placeholder

                            defender.skills?.Learn(SkillDefOf.Melee, CritXP + ParryXP, false);
                        }
                        else
                        {
                            // Do a parry
                            DoParry(defender, parryThing);
                            moteText = "CE_TextMote_Parried".Translate();
                            CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesMiss, false); //placeholder

                            defender.skills?.Learn(SkillDefOf.Melee, ParryXP, false);
                        }

                        result   = false;
                        soundDef = SoundMiss(); // TODO Set hit sound to something more appropriate
                    }
                    else
                    {
                        BattleLogEntry_MeleeCombat log = this.CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesHit, false);

                        // Attack connects
                        if (surpriseAttack || Rand.Chance(GetComparativeChanceAgainst(casterPawn, defender, CE_StatDefOf.MeleeCritChance, BaseCritChance)))
                        {
                            // Do a critical hit
                            isCrit = true;
                            ApplyMeleeDamageToTarget(currentTarget).AssociateWithLog(log);
                            moteText = casterPawn.def.race.Animal ? "CE_TextMote_Knockdown".Translate() : "CE_TextMote_CriticalHit".Translate();
                            casterPawn.skills?.Learn(SkillDefOf.Melee, CritXP, false);
                        }
                        else
                        {
                            // Do a regular hit as per vanilla
                            ApplyMeleeDamageToTarget(currentTarget).AssociateWithLog(log);
                        }
                        result   = true;
                        soundDef = targetThing.def.category == ThingCategory.Building ? SoundHitBuilding() : SoundHitPawn();
                    }
                }
            }
            else
            {
                // Attack missed
                result   = false;
                soundDef = SoundMiss();
                CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesMiss, false);
            }
            if (!moteText.NullOrEmpty())
            {
                MoteMaker.ThrowText(targetThing.PositionHeld.ToVector3Shifted(), targetThing.MapHeld, moteText);
            }
            soundDef.PlayOneShot(new TargetInfo(targetThing.PositionHeld, targetThing.MapHeld));
            casterPawn.Drawer.Notify_MeleeAttackOn(targetThing);
            if (defender != null && !defender.Dead)
            {
                defender.stances.StaggerFor(95);
                if (casterPawn.MentalStateDef != MentalStateDefOf.SocialFighting || defender.MentalStateDef != MentalStateDefOf.SocialFighting)
                {
                    defender.mindState.meleeThreat             = casterPawn;
                    defender.mindState.lastMeleeThreatHarmTick = Find.TickManager.TicksGame;
                }
            }
            casterPawn.rotationTracker.FaceCell(targetThing.Position);
            if (casterPawn.caller != null)
            {
                casterPawn.caller.Notify_DidMeleeAttack();
            }
            return(result);
        }
Пример #23
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);
        }
Пример #24
0
 public Equipment Build(EquipmentClass eClass, BonusType bonusType, EquipmentRarity rarity, double bonusBase, double bonusIncrease, EquipmentSource source, Bitmap image, string fileVersion)
 {
     return(new Equipment(this, eClass, bonusType, rarity, bonusBase, bonusIncrease, source, image, fileVersion));
 }
Пример #25
0
        /// <summary>
        /// Calculates primary DamageInfo from verb, as well as secondary DamageInfos to apply (i.e. surprise attack stun damage).
        /// Also calculates the maximum body height an attack can target, so we don't get rabbits biting out a colonist's eye or something.
        /// </summary>
        /// <param name="target">The target damage is to be applied to</param>
        /// <returns>Collection with primary DamageInfo, followed by secondary types</returns>
        private IEnumerable <DamageInfo> DamageInfosToApply(LocalTargetInfo target, bool isCrit = false)
        {
            //START 1:1 COPY Verb_MeleeAttack.DamageInfosToApply
            float damAmount    = this.verbProps.AdjustedMeleeDamageAmount(this, base.CasterPawn);
            var   critModifier = isCrit && verbProps.meleeDamageDef.armorCategory == DamageArmorCategoryDefOf.Sharp &&
                                 !CasterPawn.def.race.Animal
                ? 2
                : 1;
            var              armorPenetration = verbProps.AdjustedArmorPenetration(this, CasterPawn) * (EquipmentSource?.GetStatValue(CE_StatDefOf.MeleePenetrationFactor) ?? 1) * critModifier;
            DamageDef        damDef           = verbProps.meleeDamageDef;
            BodyPartGroupDef bodyPartGroupDef = null;
            HediffDef        hediffDef        = null;

            damAmount = Rand.Range(damAmount * 0.8f, damAmount * 1.2f);
            if (base.CasterIsPawn)
            {
                bodyPartGroupDef = this.verbProps.AdjustedLinkedBodyPartsGroup(this.tool);
                if (damAmount >= 1f)
                {
                    if (base.HediffCompSource != null)
                    {
                        hediffDef = base.HediffCompSource.Def;
                    }
                }
                else
                {
                    damAmount = 1f;
                    damDef    = DamageDefOf.Blunt;
                }
            }
            ThingDef source;

            if (base.EquipmentSource != null)
            {
                source = base.EquipmentSource.def;
            }
            else
            {
                source = base.CasterPawn.def;
            }
            Vector3   direction = (target.Thing.Position - base.CasterPawn.Position).ToVector3();
            DamageDef def       = damDef;
            //END 1:1 COPY
            BodyPartHeight bodyRegion = GetBodyPartHeightFor(target);                                                                                           //Custom // Add check for body height
            //START 1:1 COPY
            DamageInfo mainDinfo = new DamageInfo(def, damAmount, armorPenetration, -1f, caster, null, source, DamageInfo.SourceCategory.ThingOrUnknown, null); //Alteration

            mainDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside);                                                                                         //Alteration
            mainDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
            mainDinfo.SetWeaponHediff(hediffDef);
            mainDinfo.SetAngle(direction);
            yield return(mainDinfo);

            // Apply critical damage
            if (isCrit && !CasterPawn.def.race.Animal && verbProps.meleeDamageDef.armorCategory != DamageArmorCategoryDefOf.Sharp)
            {
                var critAmount = GenMath.RoundRandom(mainDinfo.Amount * 0.25f);
                var critDinfo  = new DamageInfo(DamageDefOf.Stun, critAmount, armorPenetration, //Ignore armor //armorPenetration, //Armor Penetration
                                                -1, caster, null, source);
                critDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside);
                critDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
                critDinfo.SetWeaponHediff(hediffDef);
                critDinfo.SetAngle(direction);
                yield return(critDinfo);
            }
        }
Пример #26
0
        protected override (bool success, Vector3 launchPos, float angle) TryCastShotInternal()
        {
            IntVec3 exitTarget = caster.Position.CellFromDistAngle(Building_Artillery.MaxMapDistance, heading);

            if (!target.HasWorldObject && !target.HasThing)
            {
                return(false, Vector3.zero, 0);
            }
            ThingDef projectile = Projectile;

            if (projectile is null)
            {
                return(false, Vector3.zero, 0);
            }
            bool flag = TryFindShootLineFromTo(caster.Position, exitTarget, out ShootLine 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;
            Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, caster.Position, caster.Map, WipeMode.Vanish);

            if (projectile2.AllComps.NullOrEmpty())
            {
                AccessTools.Field(typeof(ThingWithComps), "comps").SetValue(projectile2, new List <ThingComp>());
            }

            projectile2.AllComps.Add(new CompProjectileExitMap(CasterTWC)
            {
                airDefenseDef = AntiAircraftDefOf.FlakProjectile,
                target        = target.WorldObject as AerialVehicleInFlight,
                spawnPos      = Building_Artillery.RandomWorldPosition(caster.Map.Tile, 1).FirstOrDefault()
            });
            if (caster.def.GetModExtension <ProjectilePropertiesDefModExtension>() is ProjectilePropertiesDefModExtension projectileProps)
            {
                projectile2.AllComps.Add(new CompTurretProjectileProperties(CasterTWC)
                {
                    speed    = projectileProps.speed > 0 ? projectileProps.speed : projectile2.def.projectile.speed,
                    hitflag  = ProjectileHitFlags.IntendedTarget,
                    hitflags = null
                });
            }
            ThrowDebugText("ToHit" + (canHitNonTargetPawnsNow ? "\nchntp" : ""));
            launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(heading);
            projectile2.Launch(launcher, launchPos, exitTarget, exitTarget, ProjectileHitFlags.IntendedTarget, equipment);
            ThrowDebugText("Hit\nDest", shootLine.Dest);
            return(true, launchPos, heading);
        }
Пример #27
0
        /// <summary>
        /// Fires a projectile using the new aiming system
        /// </summary>
        /// <returns>True for successful shot, false otherwise</returns>
        public override bool TryCastShot()
        {
            if (!TryFindCEShootLineFromTo(caster.Position, currentTarget, out var shootLine))
            {
                return(false);
            }
            if (projectilePropsCE.pelletCount < 1)
            {
                Log.Error(EquipmentSource.LabelCap + " tried firing with pelletCount less than 1.");
                return(false);
            }
            bool instant = false;

            float spreadDegrees = 0;
            float aperatureSize = 0;

            if (Projectile.projectile is ProjectilePropertiesCE pprop)
            {
                instant       = pprop.isInstant;
                spreadDegrees = (EquipmentSource?.GetStatValue(StatDef.Named("ShotSpread")) ?? 0) * pprop.spreadMult;
                aperatureSize = 0.03f;
            }

            ShiftVecReport report = ShiftVecReportFor(currentTarget);
            bool           pelletMechanicsOnly = false;

            for (int i = 0; i < projectilePropsCE.pelletCount; i++)
            {
                ProjectileCE projectile = (ProjectileCE)ThingMaker.MakeThing(Projectile, null);
                GenSpawn.Spawn(projectile, shootLine.Source, caster.Map);
                ShiftTarget(report, pelletMechanicsOnly, instant);

                //New aiming algorithm
                projectile.canTargetSelf = false;

                var targetDistance = (sourceLoc - currentTarget.Cell.ToIntVec2.ToVector2Shifted()).magnitude;
                projectile.minCollisionDistance = GetMinCollisionDistance(targetDistance);
                projectile.intendedTarget       = currentTarget;
                projectile.mount          = caster.Position.GetThingList(caster.Map).FirstOrDefault(t => t is Pawn && t != caster);
                projectile.AccuracyFactor = report.accuracyFactor * report.swayDegrees * ((numShotsFired + 1) * 0.75f);

                if (instant)
                {
                    var   shotHeight = ShotHeight;
                    float tsa        = AdjustShotHeight(caster, currentTarget, ref shotHeight);
                    projectile.RayCast(
                        Shooter,
                        verbProps,
                        sourceLoc,
                        shotAngle + tsa,
                        shotRotation,
                        shotHeight,
                        ShotSpeed,
                        spreadDegrees,
                        aperatureSize,
                        EquipmentSource);
                }
                else
                {
                    projectile.Launch(
                        Shooter,                  //Shooter instead of caster to give turret operators' records the damage/kills obtained
                        sourceLoc,
                        shotAngle,
                        shotRotation,
                        ShotHeight,
                        ShotSpeed,
                        EquipmentSource);
                }
                pelletMechanicsOnly = true;
            }

            /*
             * Notify the lighting tracker that shots fired with muzzle flash value of VerbPropsCE.muzzleFlashScale
             */
            LightingTracker.Notify_ShotsFiredAt(caster.Position, intensity: VerbPropsCE.muzzleFlashScale);

            pelletMechanicsOnly = false;
            numShotsFired++;
            if (CompAmmo != null && !CompAmmo.CanBeFiredNow)
            {
                CompAmmo?.TryStartReload();
            }
            if (CompReloadable != null)
            {
                CompReloadable.UsedOnce();
            }
            return(true);
        }
Пример #28
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);
        }