コード例 #1
0
        private bool TryFindAmmoInInventory(out Thing ammoThing)
        {
            ammoThing = null;
            if (CompInventory == null)
            {
                return(false);
            }

            // Try finding suitable ammoThing for currently set ammo first
            ammoThing = CompInventory.ammoList.Find(thing => thing.def == selectedAmmo);
            if (ammoThing != null)
            {
                return(true);
            }

            // Try finding ammo from different type
            foreach (AmmoLink link in Props.ammoSet.ammoTypes)
            {
                ammoThing = CompInventory.ammoList.Find(thing => thing.def == link.ammo);
                if (ammoThing != null)
                {
                    selectedAmmo = (AmmoDef)link.ammo;
                    return(true);
                }
            }
            return(false);
        }
コード例 #2
0
        public override void Initialize(CompProperties vprops)
        {
            base.Initialize(vprops);

            //spawnUnloaded checks have all been moved to methods calling ResetAmmoCount.
            //curMagCountInt = Props.spawnUnloaded && UseAmmo ? 0 : Props.magazineSize;

            // Initialize ammo with default if none is set
            if (UseAmmo)
            {
                if (Props.ammoSet.ammoTypes.NullOrEmpty())
                {
                    Log.Error(parent.Label + " has no available ammo types");
                }
                else
                {
                    if (currentAmmoInt == null)
                    {
                        currentAmmoInt = (AmmoDef)Props.ammoSet.ammoTypes[0].ammo;
                    }
                    if (selectedAmmo == null)
                    {
                        selectedAmmo = currentAmmoInt;
                    }
                }
            }
        }
コード例 #3
0
        public override void Initialize(CompProperties vprops)
        {
            base.Initialize(vprops);

            curMagCountInt = Props.spawnUnloaded ? 0 : Props.magazineSize;

            // Initialize ammo with default if none is set
            if (useAmmo)
            {
                if (Props.ammoSet.ammoTypes.NullOrEmpty())
                {
                    Log.Error(parent.Label + " has no available ammo types");
                }
                else
                {
                    if (currentAmmoInt == null)
                    {
                        currentAmmoInt = (AmmoDef)Props.ammoSet.ammoTypes[0];
                    }
                    if (selectedAmmo == null)
                    {
                        selectedAmmo = currentAmmoInt;
                    }
                }
            }
        }
コード例 #4
0
        public bool TryFindAmmoInInventory(out Thing ammoThing)
        {
            ammoThing = null;
            if (CompInventory == null)
            {
                return(false);
            }

            // Try finding suitable ammoThing for currently set ammo first
            ammoThing = CompInventory.ammoList.Find(thing => thing.def == selectedAmmo);
            if (ammoThing != null)
            {
                return(true);
            }

            if (Props.reloadOneAtATime && CurMagCount > 0)
            {
                //Current mag already has a few rounds in, and the inventory doesn't have any more of that type.
                //If we let this method pick a new selectedAmmo below, it would convert the already loaded rounds to a different type,
                //so for OneAtATime weapons, we stop the process here here.
                return(false);
            }

            // Try finding ammo from different type
            foreach (AmmoLink link in Props.ammoSet.ammoTypes)
            {
                ammoThing = CompInventory.ammoList.Find(thing => thing.def == link.ammo);
                if (ammoThing != null)
                {
                    selectedAmmo = (AmmoDef)link.ammo;
                    return(true);
                }
            }
            return(false);
        }
コード例 #5
0
 public static bool IsAmmoSystemActive(AmmoDef def)
 {
     if (Controller.settings.EnableAmmoSystem)
     {
         return(true);
     }
     return(def != null && def.isMortarAmmo);
 }
コード例 #6
0
 /// <summary>
 /// Resets current ammo count to a full magazine. Intended use is pawn/turret generation where we want raiders/enemy turrets to spawn with loaded magazines. DO NOT
 /// use for regular reloads, those should be handled through LoadAmmo() instead.
 /// </summary>
 /// <param name="newAmmo">Currently loaded ammo type will be set to this, null will load currently selected type.</param>
 public void ResetAmmoCount(AmmoDef newAmmo = null)
 {
     if (newAmmo != null)
     {
         currentAmmoInt = newAmmo;
     }
     curMagCountInt = Props.magazineSize;
 }
コード例 #7
0
        /// <summary>
        /// <para>Reduces ammo count and updates inventory if necessary, call this whenever ammo is consumed by the gun (e.g. firing a shot, clearing a jam). </para>
        /// <para>Has an optional argument for the amount of ammo to consume per shot, which defaults to 1; this caters for special cases such as different sci-fi weapons using up different amounts of the same energy cell ammo type per shot, or a double-barrelled shotgun that fires both cartridges at the same time (projectile treated as a single, more powerful bullet)</para>
        /// </summary>
        public bool TryReduceAmmoCount(int ammoConsumedPerShot = 1)
        {
            ammoConsumedPerShot = (ammoConsumedPerShot > 0) ? ammoConsumedPerShot : 1;

            if (Wielder == null && turret == null)
            {
                Log.Error(parent.ToString() + " tried reducing its ammo count without a wielder");
            }

            // Mag-less weapons feed directly from inventory
            if (!HasMagazine)
            {
                if (UseAmmo)
                {
                    if (!TryFindAmmoInInventory(out ammoToBeDeleted))
                    {
                        return(false);
                    }
                    if (ammoToBeDeleted.def != CurrentAmmo)
                    {
                        currentAmmoInt = ammoToBeDeleted.def as AmmoDef;
                    }

                    if (ammoToBeDeleted.stackCount > 1)
                    {
                        ammoToBeDeleted = ammoToBeDeleted.SplitOff(1);
                    }
                }
                return(true);
            }
            // If magazine is empty, return false
            if (curMagCountInt <= 0)
            {
                CurMagCount = 0;
                return(false);
            }
            // Reduce ammo count and update inventory
            CurMagCount = (curMagCountInt - ammoConsumedPerShot < 0) ? 0 : curMagCountInt - ammoConsumedPerShot;


            /*if (curMagCountInt - ammoConsumedPerShot < 0)
             * {
             *  curMagCountInt = 0;
             * } else
             * {
             *  curMagCountInt = curMagCountInt - ammoConsumedPerShot;
             * }*/


            // Original: curMagCountInt--;

            if (curMagCountInt < 0)
            {
                TryStartReload();
            }
            return(true);
        }
コード例 #8
0
        protected override float GetWeightForDef(ThingDef def)
        {
            float   weight = 1;
            AmmoDef ammo   = def as AmmoDef;

            if (ammo != null && ammo.ammoClass.advanced)
            {
                weight *= 0.2f;
            }
            return(weight);
        }
コード例 #9
0
        /// <summary>
        /// Reduces ammo count and updates inventory if necessary, call this whenever ammo is consumed by the gun (e.g. firing a shot, clearing a jam)
        /// </summary>
        public bool TryReduceAmmoCount()
        {
            if (Wielder == null && turret == null)
            {
                Log.Error(parent.ToString() + " tried reducing its ammo count without a wielder");
            }

            // Mag-less weapons feed directly from inventory
            if (!HasMagazine)
            {
                if (UseAmmo)
                {
                    if (!TryFindAmmoInInventory(out ammoToBeDeleted))
                    {
                        return(false);
                    }
                    if (ammoToBeDeleted.def != CurrentAmmo)
                    {
                        currentAmmoInt = ammoToBeDeleted.def as AmmoDef;
                    }

                    if (ammoToBeDeleted.stackCount > 1)
                    {
                        ammoToBeDeleted = ammoToBeDeleted.SplitOff(1);
                    }
                }
                return(true);
            }
            // If magazine is empty, return false
            if (curMagCountInt <= 0)
            {
                curMagCountInt = 0;
                return(false);
            }
            // Reduce ammo count and update inventory
            curMagCountInt--;
            if (CompInventory != null)
            {
                CompInventory.UpdateInventory();
            }
            if (curMagCountInt < 0)
            {
                TryStartReload();
            }
            return(true);
        }
コード例 #10
0
        private void LoadWeaponWithRandAmmo(ThingWithComps gun)
        {
            CompAmmoUser compAmmo = gun.TryGetComp <CompAmmoUser>();

            if (compAmmo == null)
            {
                return;
            }
            if (!compAmmo.UseAmmo)
            {
                compAmmo.ResetAmmoCount();
                return;
            }
            // Determine ammo
            IEnumerable <AmmoDef> availableAmmo = compAmmo.Props.ammoSet.ammoTypes.Where(a => a.ammo.alwaysHaulable).Select(a => a.ammo); //Running out of options. alwaysHaulable does exist in xml.
            AmmoDef ammoToLoad = availableAmmo.RandomElementByWeight(a => a.generateCommonality);

            compAmmo.ResetAmmoCount(ammoToLoad);
        }
コード例 #11
0
        private FloatMenu MakeAmmoMenu()
        {
            List <ThingDef> ammoList = new List <ThingDef>();      // List of all ammo types the gun can use and the pawn has in his inventory

            if (compAmmo.turret != null)
            {
                // If we have no inventory available (e.g. manned turret), add all possible ammo types to the selection
                ammoList.AddRange(compAmmo.Props.ammoSet.ammoTypes);
            }
            else
            {
                // Iterate through all suitable ammo types and check if they're in our inventory
                foreach (ThingDef curAmmoDef in compAmmo.Props.ammoSet.ammoTypes)
                {
                    if (compAmmo.compInventory.ammoList.Any(x => x.def == curAmmoDef))
                    {
                        ammoList.Add(curAmmoDef);
                    }
                }
            }

            // Append float menu options for every available ammo type
            List <FloatMenuOption> floatOptionList = new List <FloatMenuOption>();

            if (ammoList.NullOrEmpty())
            {
                floatOptionList.Add(new FloatMenuOption("CE_OutOfAmmo".Translate(), null));
            }
            else
            {
                foreach (ThingDef curDef in ammoList)
                {
                    AmmoDef ammoDef = (AmmoDef)curDef;
                    floatOptionList.Add(new FloatMenuOption(ammoDef.ammoClass.LabelCap, new Action(delegate { compAmmo.selectedAmmo = ammoDef; })));
                }
            }
            return(new FloatMenu(floatOptionList));
        }
コード例 #12
0
        public void LoadAmmo(Thing ammo = null)
        {
            if (Holder == null && turret == null)
            {
                Log.Error(parent.ToString() + " tried loading ammo with no owner");
                return;
            }

            int newMagCount;

            if (UseAmmo)
            {
                Thing ammoThing;
                bool  ammoFromInventory = false;
                if (ammo == null)
                {
                    if (!TryFindAmmoInInventory(out ammoThing))
                    {
                        DoOutOfAmmoAction();
                        return;
                    }
                    ammoFromInventory = true;
                }
                else
                {
                    ammoThing = ammo;
                }
                currentAmmoInt = (AmmoDef)ammoThing.def;
                if (Props.magazineSize < ammoThing.stackCount)
                {
                    newMagCount           = Props.magazineSize;
                    ammoThing.stackCount -= Props.magazineSize;
                    if (CompInventory != null)
                    {
                        CompInventory.UpdateInventory();
                    }
                }
                else
                {
                    newMagCount = ammoThing.stackCount;
                    if (ammoFromInventory)
                    {
                        CompInventory.container.Remove(ammoThing);
                    }
                    else if (!ammoThing.Destroyed)
                    {
                        ammoThing.Destroy();
                    }
                }
            }
            else
            {
                newMagCount = Props.magazineSize;
            }
            curMagCountInt = newMagCount;
            if (turret != null)
            {
                turret.isReloading = false;
            }
            if (parent.def.soundInteract != null)
            {
                parent.def.soundInteract.PlayOneShot(new TargetInfo(Position, Find.VisibleMap, false));
            }
        }
コード例 #13
0
        public void LoadAmmo(Thing ammo = null)
        {
            if (Holder == null && turret == null)
            {
                Log.Error(parent.ToString() + " tried loading ammo with no owner");
                return;
            }

            int newMagCount;

            if (UseAmmo)
            {
                Thing ammoThing;
                bool  ammoFromInventory = false;
                if (ammo == null)
                {
                    if (!TryFindAmmoInInventory(out ammoThing))
                    {
                        DoOutOfAmmoAction();
                        return;
                    }
                    ammoFromInventory = true;
                }
                else
                {
                    ammoThing = ammo;
                }
                currentAmmoInt = (AmmoDef)ammoThing.def;

                // If there's more ammo in inventory than the weapon can hold, or if there's greater than 1 bullet in inventory if reloading one at a time
                if ((Props.reloadOneAtATime ? 1 : Props.magazineSize) < ammoThing.stackCount)
                {
                    if (Props.reloadOneAtATime)
                    {
                        newMagCount = curMagCountInt + 1;
                        ammoThing.stackCount--;
                    }
                    else
                    {
                        newMagCount           = Props.magazineSize;
                        ammoThing.stackCount -= Props.magazineSize;
                    }
                }

                // If there's less ammo in inventory than the weapon can hold, or if there's only one bullet left if reloading one at a time
                else
                {
                    newMagCount = (Props.reloadOneAtATime) ? curMagCountInt + 1 : ammoThing.stackCount;
                    if (ammoFromInventory)
                    {
                        CompInventory.container.Remove(ammoThing);
                    }
                    else if (!ammoThing.Destroyed)
                    {
                        ammoThing.Destroy();
                    }
                }
            }
            else
            {
                newMagCount = (Props.reloadOneAtATime) ? (curMagCountInt + 1) : Props.magazineSize;
            }
            CurMagCount = newMagCount;
            if (turret != null)
            {
                turret.isReloading = false;
            }
            if (parent.def.soundInteract != null)
            {
                parent.def.soundInteract.PlayOneShot(new TargetInfo(Position, Find.CurrentMap, false));
            }
        }
コード例 #14
0
 /// <summary>
 /// Similar to ThingContainer.TotalStackCountOfDef(), returns the count of all matching AmmoDefs in AmmoList cache.
 /// </summary>
 /// <param name="def">ThingDef to count.</param>
 /// <returns>int amount of AmmoDef found in AmmoList.</returns>
 public int AmmoCountOfDef(AmmoDef def)
 {
     return(ammoListCached.Where(t => t.def == def).Sum(t => t.stackCount));
 }
コード例 #15
0
        /* Rough Algorithm
         * Need Things so the collection of ammo users that use magazines.  Also need a collection of ammo (ThingDef is OK here).
         * For each weapon (that fits above),
         * -If we have no ammo in inventory that the gun is loaded with, check loadouts/holdtracker for a clip's worth of ammo that the gun contains.
         * --Find ammo the gun uses that we have a clip's worth in inventory (should check it against loadout/holdtracker as well)
         * -If weapon is low on ammo and we have enough in inventory to fill it up.
         *
         * If either of the above are true, trigger a reload.
         */
        /// <summary>
        /// Check's the pawn's equipment and inventory for weapons that could use a reload.
        /// </summary>
        /// <param name="pawn">Pawn to check the equipment and inventory of.</param>
        /// <param name="reloadWeapon">Thing weapon which needs to be reloaded.</param>
        /// <param name="reloadAmmo">AmmoDef ammo to reload the gun with.</param>
        /// <returns>Bool value indicating if the job needs to be done.</returns>
        private bool DoReloadCheck(Pawn pawn, out ThingWithComps reloadWeapon, out AmmoDef reloadAmmo)
        {
            reloadWeapon = null;
            reloadAmmo   = null;

            // First need to create the collections that will be searched.
            List <ThingWithComps> guns      = new List <ThingWithComps>();
            CompInventory         inventory = pawn.TryGetComp <CompInventory>();
            CompAmmoUser          tmpComp;
            Loadout loadout        = pawn.GetLoadout();
            bool    pawnHasLoadout = loadout != null && !loadout.Slots.NullOrEmpty();

            if (inventory == null)
            {
                return(false);                // There isn't any work to do since the pawn doesn't have a CE Inventory.
            }
            if ((tmpComp = pawn.equipment?.Primary?.TryGetComp <CompAmmoUser>()) != null && tmpComp.HasMagazine)
            {
                guns.Add(pawn.equipment.Primary);
            }

            // CompInventory doesn't track equipment and it's desired to check the pawn's equipped weapon before inventory items so need to copy stuff from Inventory Cache.
            guns.AddRange(inventory.rangedWeaponList.Where(t => t.TryGetComp <CompAmmoUser>() != null && t.GetComp <CompAmmoUser>().HasMagazine));

            if (guns.NullOrEmpty())
            {
                return(false);                // There isn't any work to do since the pawn doesn't have any ammo using guns.
            }
            // look at each gun...
            foreach (ThingWithComps gun in guns)
            {
                // Get key stats of the weapon.
                tmpComp = gun.TryGetComp <CompAmmoUser>();
                AmmoDef ammoType     = tmpComp.CurrentAmmo;
                int     ammoAmount   = tmpComp.CurMagCount;
                int     magazineSize = tmpComp.Props.magazineSize;

                // Is the gun loaded with ammo not in a Loadout/HoldTracker?
                if (tmpComp.UseAmmo && pawnHasLoadout && !TrackingSatisfied(pawn, ammoType, magazineSize))
                {
                    // Do we have ammo in the inventory that the gun uses which satisfies requirements? (expensive)
                    AmmoDef matchAmmo = tmpComp.Props.ammoSet.ammoTypes
                                        .Where(al => al.ammo != ammoType)
                                        .Select(al => al.ammo)
                                        .FirstOrDefault(ad => TrackingSatisfied(pawn, ad, magazineSize) &&
                                                        inventory.AmmoCountOfDef(ad) >= magazineSize);

                    if (matchAmmo != null)
                    {
                        reloadWeapon = gun;
                        reloadAmmo   = matchAmmo;
                        return(true);
                    }
                }

                // Is the gun low on ammo?
                if (tmpComp.CurMagCount < magazineSize)
                {
                    // Do we have enough ammo in the inventory to top it off?
                    if (!tmpComp.UseAmmo || inventory.AmmoCountOfDef(ammoType) >= (magazineSize - tmpComp.CurMagCount))
                    {
                        reloadWeapon = gun;
                        reloadAmmo   = ammoType;
                        return(true);
                        //} else {  // (ProfoundDarkness) I think the idea of this branch was that the JobGiver might initiate fetching ammo but it actually runs AFTER the one that fetches ammo for loadout.
                        // There wasn't enough in the inventory to top it off.  At this point we know the loadout is satisfied for this ammo...
                        // We could do a more strict check to see if the pawn's loadout is satisfied to pick up ammo and if not swap to another ammo...?
                    }
                }
            }

            return(false);
        }
コード例 #16
0
        public static bool InjectAmmos()
        {
            // Initialize list of all weapons so we don't have to iterate through all the defs, all the time
            CE_Utility.allWeaponDefs.Clear();
            foreach (ThingDef def in DefDatabase <ThingDef> .AllDefsListForReading)
            {
                if (def.IsWeapon && (def.canBeSpawningInventory || def.tradeability == Tradeability.Stockable || def.weaponTags.Contains("TurretGun")))
                {
                    CE_Utility.allWeaponDefs.Add(def);
                }
            }
            if (CE_Utility.allWeaponDefs.NullOrEmpty())
            {
                Log.Warning("CE Ammo Injector found no weapon defs");
                return(true);
            }

            // Find all ammo using guns
            foreach (ThingDef weaponDef in CE_Utility.allWeaponDefs)
            {
                CompProperties_AmmoUser props = weaponDef.GetCompProperties <CompProperties_AmmoUser>();
                if (props != null && props.ammoSet != null && !props.ammoSet.ammoTypes.NullOrEmpty())
                {
                    foreach (ThingDef curDef in props.ammoSet.ammoTypes)
                    {
                        AmmoDef ammoDef = curDef as AmmoDef;
                        if (ammoDef != null)
                        {
                            // Enable trading
                            if (ammoDef.tradeTags.Contains(enableTradeTag))
                            {
                                ammoDef.tradeability = Tradeability.Stockable;
                            }

                            // Enable recipe
                            if (ammoDef.tradeTags.Contains(enableCraftingTag))
                            {
                                RecipeDef recipe = DefDatabase <RecipeDef> .GetNamed(("Make" + ammoDef.defName), false);

                                if (recipe == null)
                                {
                                    Log.Error("CE ammo injector found no recipe named Make" + ammoDef.defName);
                                }
                                else
                                {
                                    if (ammoCraftingStation == null)
                                    {
                                        Log.ErrorOnce("CE ammo injector crafting station is null", 84653201);
                                    }
                                    else
                                    {
                                        if (!recipe.recipeUsers.Contains(ammoCraftingStation))
                                        {
                                            recipe.recipeUsers.Add(ammoCraftingStation);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(true);
        }
コード例 #17
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            // Error checking/input validation.
            if (turret == null)
            {
                Log.Error(string.Concat(errorBase, "TargetThingA isn't a Building_TurretGunCE"));
                yield return(null);
            }
            if (compReloader == null)
            {
                Log.Error(string.Concat(errorBase, "TargetThingA (Building_TurretGunCE) is missing its CompAmmoUser."));
                yield return(null);
            }
            if (compReloader.UseAmmo && ammo == null)
            {
                Log.Error(string.Concat(errorBase, "TargetThingB is either null or not an AmmoThing."));
                yield return(null);
            }

            AddEndCondition(delegate
            {
                return((pawn.Downed || pawn.Dead || pawn.InMentalState || pawn.IsBurning()) ? JobCondition.Incompletable : JobCondition.Ongoing);
            });

            this.FailOnIncapable(PawnCapacityDefOf.Manipulation);

            // Set fail condition on turret.
            if (pawn.Faction != Faction.OfPlayer)
            {
                this.FailOnDestroyedOrNull(TargetIndex.A);
            }
            else
            {
                this.FailOnDestroyedNullOrForbidden(TargetIndex.A);
            }

            // Perform ammo system specific activities, failure condition and hauling
            if (compReloader.UseAmmo)
            {
                var toilGoToCell   = Toils_Goto.GotoCell(ammo.Position, PathEndMode.Touch).FailOnBurningImmobile(TargetIndex.B);
                var toilCarryThing = Toils_Haul.StartCarryThing(TargetIndex.B).FailOnBurningImmobile(TargetIndex.B);

                if (TargetThingB is AmmoThing)
                {
                    toilGoToCell.AddEndCondition(delegate { return((TargetThingB as AmmoThing).IsCookingOff ? JobCondition.Incompletable : JobCondition.Ongoing); });
                    toilCarryThing.AddEndCondition(delegate { return((TargetThingB as AmmoThing).IsCookingOff ? JobCondition.Incompletable : JobCondition.Ongoing); });
                }

                if (pawn.Faction != Faction.OfPlayer)
                {
                    ammo.SetForbidden(true, false);
                    toilGoToCell.FailOnDestroyedOrNull(TargetIndex.B);
                    toilCarryThing.FailOnDestroyedOrNull(TargetIndex.B);
                }
                else
                {
                    toilGoToCell.FailOnDestroyedNullOrForbidden(TargetIndex.B);
                    toilCarryThing.FailOnDestroyedNullOrForbidden(TargetIndex.B);
                }

                //yield return Toils_Reserve.Reserve(TargetIndex.B, Mathf.Max(1, TargetThingB.stackCount - job.count), job.count);
                yield return(toilGoToCell);

                yield return(toilCarryThing);
                //yield return Toils_Haul.PlaceHauledThingInCell(TargetIndex.A, null, false);
            }

            // If ammo system is turned off we just need to go to the turret.
            yield return(Toils_Goto.GotoCell(turret.Position, PathEndMode.Touch));

            //If pawn fails reloading from this point, reset isReloading
            this.AddFinishAction(delegate { turret.isReloading = false; });

            // Wait in place
            Toil waitToil = new Toil()
            {
                actor = pawn
            };

            waitToil.initAction = delegate
            {
                // Initial relaod process activities.
                turret.isReloading = true;
                waitToil.actor.pather.StopDead();
                if (compReloader.ShouldThrowMote)
                {
                    MoteMaker.ThrowText(turret.Position.ToVector3Shifted(), turret.Map, string.Format("CE_ReloadingTurretMote".Translate(), TargetThingA.LabelCapNoCount));
                }
                //Thing newAmmo;
                //compReloader.TryUnload(out newAmmo);
                //if (newAmmo?.CanStackWith(ammo) ?? false)
                //{
                //    pawn.carryTracker.TryStartCarry(newAmmo, Mathf.Min(newAmmo.stackCount, compReloader.Props.magazineSize - ammo.stackCount));
                //}
                AmmoDef currentAmmo = compReloader.CurrentAmmo;
                if (currentAmmo != ammo?.def)    //Turrets are reloaded without unloading the mag first (if using same ammo type), to support very high capacity magazines
                {
                    compReloader.TryUnload(out Thing newAmmo);
                }
            };
            waitToil.defaultCompleteMode = ToilCompleteMode.Delay;
            waitToil.defaultDuration     = Mathf.CeilToInt(compReloader.Props.reloadTime.SecondsToTicks() / pawn.GetStatValue(CE_StatDefOf.ReloadSpeed));
            yield return(waitToil.WithProgressBarToilDelay(TargetIndex.A));

            //Actual reloader
            Toil reloadToil = new Toil();

            reloadToil.defaultCompleteMode = ToilCompleteMode.Instant;
            reloadToil.initAction          = delegate
            {
                compReloader.LoadAmmo(ammo);
                turret.isReloading = false;
            };
            //if (compReloader.useAmmo) reloadToil.EndOnDespawnedOrNull(TargetIndex.B);
            yield return(reloadToil);
        }
コード例 #18
0
        private FloatMenu MakeAmmoMenu()
        {
            List <ThingDef> ammoList = new List <ThingDef>();      // List of all ammo types the gun can use and the pawn has in his inventory

            if (compAmmo.turret != null)
            {
                // If we have no inventory available (e.g. manned turret), add all possible ammo types to the selection
                foreach (AmmoLink link in compAmmo.Props.ammoSet.ammoTypes)
                {
                    ammoList.Add(link.ammo);
                }
            }
            else
            {
                // Iterate through all suitable ammo types and check if they're in our inventory
                foreach (AmmoLink curLink in compAmmo.Props.ammoSet.ammoTypes)
                {
                    if (compAmmo.CompInventory.ammoList.Any(x => x.def == curLink.ammo))
                    {
                        ammoList.Add(curLink.ammo);
                    }
                }
            }

            // Append float menu options for every available ammo type
            List <FloatMenuOption> floatOptionList = new List <FloatMenuOption>();

            if (ammoList.NullOrEmpty())
            {
                floatOptionList.Add(new FloatMenuOption("CE_OutOfAmmo".Translate(), null));
            }
            else
            {
                // Append all available ammo types
                foreach (ThingDef curDef in ammoList)
                {
                    AmmoDef ammoDef = (AmmoDef)curDef;
                    floatOptionList.Add(new FloatMenuOption(ammoDef.ammoClass.LabelCap, new Action(delegate {
                        bool shouldReload     = Controller.settings.AutoReloadOnChangeAmmo && (compAmmo.SelectedAmmo != ammoDef || compAmmo.CurMagCount < compAmmo.Props.magazineSize) && compAmmo.turret?.MannableComp == null;
                        compAmmo.SelectedAmmo = ammoDef;
                        if (shouldReload)
                        {
                            if (compAmmo.turret != null)
                            {
                                compAmmo.turret.TryOrderReload();
                            }
                            else
                            {
                                compAmmo.TryStartReload();
                            }
                        }
                    })));
                }
            }
            // Append unload command
            var hasOperator = compAmmo.Wielder != null || (compAmmo.turret?.MannableComp?.MannedNow ?? false);

            if (compAmmo.UseAmmo && hasOperator && compAmmo.HasMagazine && compAmmo.CurMagCount > 0)
            {
                floatOptionList.Add(new FloatMenuOption("CE_UnloadLabel".Translate(), new Action(delegate { compAmmo.TryUnload(); })));
            }
            // Append reload command
            if (compAmmo.HasMagazine && hasOperator)
            {
                floatOptionList.Add(new FloatMenuOption("CE_ReloadLabel".Translate(), new Action(action)));
            }
            return(new FloatMenu(floatOptionList));
        }
コード例 #19
0
 public AmmoLink(AmmoDef ammo, ThingDef projectile)
 {
     this.ammo       = ammo;
     this.projectile = projectile;
 }