示例#1
0
        public override bool Available()
        {
            // This part copied from vanilla Verb_LaunchProjectile
            if (!base.Available())
            {
                return(false);
            }

            if (CasterIsPawn)
            {
                if (CasterPawn.Faction != Faction.OfPlayer &&
                    CasterPawn.mindState.MeleeThreatStillThreat &&
                    CasterPawn.mindState.meleeThreat.AdjacentTo8WayOrInside(CasterPawn))
                {
                    return(false);
                }
            }

            // Add check for reload
            if (Projectile == null || (IsAttacking && CompAmmo != null && !CompAmmo.CanBeFiredNow))
            {
                CompAmmo?.TryStartReload();
                return(false);
            }
            return(true);
        }
        // TryCastShotFrom(muzzlePos)
        public bool TryCastShotFrom(Vector3 muzzlePos)
        {
            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);
            }
            ShiftVecReport report = ShiftVecReportFor(currentTarget);
            bool           pelletMechanicsOnly = false;

            numShotsFired = (int)AccessTools.Field(typeof(Verb_LaunchProjectileCE), "numShotsFired").GetValue(this);
            shotAngle     = (float)AccessTools.Field(typeof(Verb_LaunchProjectileCE), "shotAngle").GetValue(this);
            shotRotation  = (float)AccessTools.Field(typeof(Verb_LaunchProjectileCE), "shotRotation").GetValue(this);
            shotSpeed     = (float)AccessTools.Field(typeof(Verb_LaunchProjectileCE), "shotSpeed").GetValue(this);
            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);

                //New aiming algorithm
                projectile.canTargetSelf = false;

                var targDist = (muzzlePos.ToIntVec3().ToIntVec2.ToVector2Shifted() - currentTarget.Cell.ToIntVec2.ToVector2Shifted()).magnitude;
                if (targDist <= 2)
                {
                    targDist *= 2;                      // Double to account for divide by 4 in ProjectileCE minimum collision distance calculations
                }
                //	projectile.minCollisionSqr = Mathf.Pow(targDist, 2);
                projectile.intendedTarget = currentTarget.Thing;
                projectile.mount          = caster.Position.GetThingList(caster.Map).FirstOrDefault(t => t is Pawn && t != caster);
                projectile.AccuracyFactor = report.accuracyFactor * report.swayDegrees * ((numShotsFired + 1) * 0.75f);
                projectile.Launch(
                    Shooter,                        //Shooter instead of caster to give turret operators' records the damage/kills obtained
                    new Vector2(muzzlePos.x, muzzlePos.z),
                    shotAngle,
                    shotRotation,
                    ShotHeight,
                    ShotSpeed,
                    EquipmentSource
                    );
                pelletMechanicsOnly = true;
            }
            /// Log.Message("Fired from "+caster.ThingID+" at "+ShotHeight); ///
            pelletMechanicsOnly = false;
            numShotsFired++;
            if (CompAmmo != null && !CompAmmo.CanBeFiredNow)
            {
                CompAmmo?.TryStartReload();
            }
            if (CompReloadable != null)
            {
                CompReloadable.UsedOnce();
            }
            return(true);
        }
示例#3
0
 protected override bool TryCastShot()
 {
     //Reduce ammunition
     if (CompAmmo != null)
     {
         if (!CompAmmo.TryReduceAmmoCount())
         {
             if (CompAmmo.HasMagazine)
             {
                 CompAmmo.TryStartReload();
             }
             return(false);
         }
     }
     if (base.TryCastShot())
     {
         //Required since Verb_Shoot does this but Verb_LaunchProjectileCE doesn't when calling base.TryCastShot() because Shoot isn't its base
         if (ShooterPawn != null)
         {
             ShooterPawn.records.Increment(RecordDefOf.ShotsFired);
         }
         //Drop casings
         if (VerbPropsCE.ejectsCasings && projectilePropsCE.dropsCasings)
         {
             CE_Utility.ThrowEmptyCasing(caster.DrawPos, caster.Map, ThingDef.Named(projectilePropsCE.casingMoteDefname));
         }
         // This needs to here for weapons without magazine to ensure their last shot plays sounds
         if (CompAmmo != null && !CompAmmo.HasMagazine && CompAmmo.UseAmmo)
         {
             if (!CompAmmo.Notify_ShotFired())
             {
                 if (VerbPropsCE.muzzleFlashScale > 0.01f)
                 {
                     MoteMaker.MakeStaticMote(caster.Position, caster.Map, ThingDefOf.Mote_ShotFlash, VerbPropsCE.muzzleFlashScale);
                 }
                 if (VerbPropsCE.soundCast != null)
                 {
                     VerbPropsCE.soundCast.PlayOneShot(new TargetInfo(caster.Position, caster.Map));
                 }
                 if (VerbPropsCE.soundCastTail != null)
                 {
                     VerbPropsCE.soundCastTail.PlayOneShotOnCamera();
                 }
                 if (ShooterPawn != null)
                 {
                     if (ShooterPawn.thinker != null)
                     {
                         ShooterPawn.mindState.lastEngageTargetTick = Find.TickManager.TicksGame;
                     }
                 }
             }
             return(CompAmmo.Notify_PostShotFired());
         }
         return(true);
     }
     return(false);
 }
示例#4
0
        /// <summary>
        /// Fires a projectile using the new aiming system
        /// </summary>
        /// <returns>True for successful shot, false otherwise</returns>
        protected 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);
            }
            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);

                //New aiming algorithm
                projectile.canTargetSelf = false;

                var targDist = (sourceLoc - currentTarget.Cell.ToIntVec2.ToVector2Shifted()).magnitude;
                if (targDist <= 2)
                {
                    targDist *= 2;  // Double to account for divide by 4 in ProjectileCE minimum collision distance calculations
                }
                projectile.minCollisionSqr = Mathf.Pow(targDist, 2);
                projectile.intendedTarget  = currentTarget.Thing;
                projectile.mount           = caster.Position.GetThingList(caster.Map).FirstOrDefault(t => t is Pawn && t != caster);
                projectile.AccuracyFactor  = report.accuracyFactor * report.swayDegrees * ((numShotsFired + 1) * 0.75f);
                projectile.Launch(
                    Shooter,    //Shooter instead of caster to give turret operators' records the damage/kills obtained
                    sourceLoc,
                    shotAngle,
                    shotRotation,
                    ShotHeight,
                    ShotSpeed,
                    EquipmentSource
                    );
                pelletMechanicsOnly = true;
            }
            pelletMechanicsOnly = false;
            numShotsFired++;
            if (CompAmmo != null && !CompAmmo.CanBeFiredNow)
            {
                CompAmmo?.TryStartReload();
            }
            return(true);
        }
示例#5
0
        public override IEnumerable <Gizmo> GetGizmos()              // Modified
        {
            foreach (Gizmo gizmo in base.GetGizmos())
            {
                yield return(gizmo);
            }
            // Ammo gizmos
            if (CompAmmo != null && (PlayerControlled || Prefs.DevMode))
            {
                foreach (Command com in CompAmmo.CompGetGizmosExtra())
                {
                    if (!PlayerControlled && Prefs.DevMode && com is GizmoAmmoStatus)
                    {
                        (com as GizmoAmmoStatus).prefix = "DEV: ";
                    }

                    yield return(com);
                }
            }
            // Don't show CONTROL gizmos on enemy turrets (even with dev mode enabled)
            if (PlayerControlled)
            {
                // Fire mode gizmos
                if (CompFireModes != null)
                {
                    foreach (Command com in CompFireModes.GenerateGizmos())
                    {
                        yield return(com);
                    }
                }
                // Set forced target gizmo
                if (CanSetForcedTarget)
                {
                    var vt = new Command_VerbTarget
                    {
                        defaultLabel = "CommandSetForceAttackTarget".Translate(),
                        defaultDesc  = "CommandSetForceAttackTargetDesc".Translate(),
                        icon         = ContentFinder <Texture2D> .Get("UI/Commands/Attack", true),
                        verb         = GunCompEq.PrimaryVerb,
                        hotKey       = KeyBindingDefOf.Misc4
                    };
                    if (Spawned && IsMortarOrProjectileFliesOverhead && Position.Roofed(Map))
                    {
                        vt.Disable("CannotFire".Translate() + ": " + "Roofed".Translate().CapitalizeFirst());
                    }
                    yield return(vt);
                }
                // Stop forced attack gizmo
                if (forcedTarget.IsValid)
                {
                    Command_Action stop = new Command_Action();
                    stop.defaultLabel = "CommandStopForceAttack".Translate();
                    stop.defaultDesc  = "CommandStopForceAttackDesc".Translate();
                    stop.icon         = ContentFinder <Texture2D> .Get("UI/Commands/Halt", true);

                    stop.action = delegate
                    {
                        ResetForcedTarget();
                        SoundDefOf.Tick_Low.PlayOneShotOnCamera(null);
                    };
                    if (!this.forcedTarget.IsValid)
                    {
                        stop.Disable("CommandStopAttackFailNotForceAttacking".Translate());
                    }
                    stop.hotKey = KeyBindingDefOf.Misc5;
                    yield return(stop);
                }
                // Toggle fire gizmo
                if (CanToggleHoldFire)
                {
                    yield return(new Command_Toggle
                    {
                        defaultLabel = "CommandHoldFire".Translate(),
                        defaultDesc = "CommandHoldFireDesc".Translate(),
                        icon = ContentFinder <Texture2D> .Get("UI/Commands/HoldFire", true),
                        hotKey = KeyBindingDefOf.Misc6,
                        toggleAction = delegate
                        {
                            holdFire = !holdFire;
                            if (holdFire)
                            {
                                ResetForcedTarget();
                            }
                        },
                        isActive = (() => holdFire)
                    });
                }
            }
        }
        public override IEnumerable <Gizmo> GetGizmos()
        {
            foreach (Gizmo gizmo in base.GetGizmos())
            {
                yield return(gizmo);
            }
            // Don't show gizmos on enemy turrets
            if (Faction == Faction.OfPlayer || MannedByColonist)
            {
                // Ammo gizmos
                if (CompAmmo != null)
                {
                    foreach (Command com in CompAmmo.CompGetGizmosExtra())
                    {
                        yield return(com);
                    }
                }
                // Fire mode gizmos
                if (CompFireModes != null)
                {
                    foreach (Command com in CompFireModes.GenerateGizmos())
                    {
                        yield return(com);
                    }
                }
                // Set forced target gizmo
                if (CanSetForcedTarget)
                {
                    yield return(new Command_VerbTarget
                    {
                        defaultLabel = "CommandSetForceAttackTarget".Translate(),
                        defaultDesc = "CommandSetForceAttackTargetDesc".Translate(),
                        icon = ContentFinder <Texture2D> .Get("UI/Commands/Attack", true),
                        verb = GunCompEq.PrimaryVerb,
                        hotKey = KeyBindingDefOf.Misc4
                    });
                }
                // Stop forced attack gizmo
                if (forcedTarget.IsValid)
                {
                    Command_Action stop = new Command_Action();
                    stop.defaultLabel = "CommandStopForceAttack".Translate();
                    stop.defaultDesc  = "CommandStopForceAttackDesc".Translate();
                    stop.icon         = ContentFinder <Texture2D> .Get("UI/Commands/Halt", true);

                    stop.action = delegate
                    {
                        ResetForcedTarget();
                        SoundDefOf.Tick_Low.PlayOneShotOnCamera(null);
                    };
                    if (!this.forcedTarget.IsValid)
                    {
                        stop.Disable("CommandStopAttackFailNotForceAttacking".Translate());
                    }
                    stop.hotKey = KeyBindingDefOf.Misc5;
                    yield return(stop);
                }
                // Toggle fire gizmo
                if (CanToggleHoldFire)
                {
                    yield return(new Command_Toggle
                    {
                        defaultLabel = "CommandHoldFire".Translate(),
                        defaultDesc = "CommandHoldFireDesc".Translate(),
                        icon = ContentFinder <Texture2D> .Get("UI/Commands/HoldFire", true),
                        hotKey = KeyBindingDefOf.Misc6,
                        toggleAction = delegate
                        {
                            holdFire = !holdFire;
                            if (holdFire)
                            {
                                ResetForcedTarget();
                            }
                        },
                        isActive = (() => holdFire)
                    });
                }
            }
        }
        public override bool TryCastShot()
        {
            //Reduce ammunition
            if (CompAmmo != null)
            {
                if (!CompAmmo.TryReduceAmmoCount(VerbPropsCE.ammoConsumedPerShotCount))
                {
                    return(false);
                }
            }
            Vector3 muzzlePos = Caster.DrawPos;

            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);
                }
            }
            //	if (base.TryCastShot())
            if (TryCastShotFrom(muzzlePos))
            {
                //Required since Verb_Shoot does this but Verb_LaunchProjectileCE doesn't when calling base.TryCastShot() because Shoot isn't its base
                if (ShooterPawn != null)
                {
                    ShooterPawn.records.Increment(RecordDefOf.ShotsFired);
                }
                //Drop casings
                if (VerbPropsCE.ejectsCasings && projectilePropsCE.dropsCasings)
                {
                    ThrowEmptyCasing(caster.DrawPos, caster.Map, ThingDef.Named(projectilePropsCE.casingMoteDefname));
                }
                // This needs to here for weapons without magazine to ensure their last shot plays sounds
                if (CompAmmo != null && !CompAmmo.HasMagazine && CompAmmo.UseAmmo)
                {
                    if (!CompAmmo.Notify_ShotFired())
                    {
                        if (VerbPropsCE.muzzleFlashScale > 0.01f)
                        {
                            MoteMaker.MakeStaticMote(caster.Position, caster.Map, ThingDefOf.Mote_ShotFlash, VerbPropsCE.muzzleFlashScale);
                        }
                        if (VerbPropsCE.soundCast != null)
                        {
                            VerbPropsCE.soundCast.PlayOneShot(new TargetInfo(caster.Position, caster.Map));
                        }
                        if (VerbPropsCE.soundCastTail != null)
                        {
                            VerbPropsCE.soundCastTail.PlayOneShotOnCamera();
                        }
                        if (ShooterPawn != null)
                        {
                            if (ShooterPawn.thinker != null)
                            {
                                ShooterPawn.mindState.lastEngageTargetTick = Find.TickManager.TicksGame;
                            }
                        }
                    }
                    return(CompAmmo.Notify_PostShotFired());
                }
                return(true);
            }
            return(false);
        }
示例#8
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);
        }