Exemplo n.º 1
0
    public void EquipIntoSlot(GearData gear, LoadoutSlots slot)
    {
        if (!CanEquipIntoSlot(gear, slot))
        {
            throw new ArgumentException("Cannot equip " + gear + " into " + slot.ToString());
        }

        LoadoutSlot slotcontainer = slots[slot];

        slotcontainer.contains = gear;
    }
Exemplo n.º 2
0
    public bool CanEquipIntoSlot(GearData gear, LoadoutSlots slot)
    {
        if (!SlotIsFree(slot))
        {
            return(false);
        }

        LoadoutSlot slotcontainer = slots[slot];

        if (slotcontainer.type != gear.requiredSlot)
        {
            return(false);
        }

        return(true);
    }
        /// <summary>
        /// This starts the work of finding something lacking that the pawn should pickup.
        /// </summary>
        /// <param name="pawn">Pawn who's inventory and loadout should be considered.</param>
        /// <param name="priority">Priority value for how important doing this job is.</param>
        /// <param name="closestThing">The thing found to be picked up.</param>
        /// <param name="count">The amount of closestThing to pickup.  Already checked if inventory can hold it.</param>
        /// <param name="carriedBy">If unable to find something on the ground to pickup, the pawn (pack animal/prisoner) which has the item to take.</param>
        /// <returns>LoadoutSlot which has something that can be picked up.</returns>
        private LoadoutSlot GetPrioritySlot(Pawn pawn, out ItemPriority priority, out Thing closestThing, out int count, out Pawn carriedBy)
        {
            priority = ItemPriority.None;
            LoadoutSlot slot = null;

            closestThing = null;
            count        = 0;
            carriedBy    = null;

            CompInventory inventory = pawn.TryGetComp <CompInventory>();

            if (inventory?.container != null)
            {
            }

            return(slot);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Similar to GetExcessThing though narrower in scope.  If there is NOT a loadout which covers the equipped item, it should be dropped.
        /// </summary>
        /// <param name="pawn"></param>
        /// <param name="dropEquipment">Thing which should be unequiped.</param>
        /// <returns>bool, true if there is equipment that should be unequipped.</returns>
        static public bool GetExcessEquipment(this Pawn pawn, out ThingWithComps dropEquipment)
        {
            Loadout loadout = pawn.GetLoadout();

            dropEquipment = null;
            if (loadout == null || (loadout != null && loadout.Slots.NullOrEmpty()) || pawn.equipment?.Primary == null)
            {
                return(false);
            }

            LoadoutSlot eqSlot = loadout.Slots.FirstOrDefault(s => s.count >= 1 && ((s.thingDef != null && s.thingDef == pawn.equipment.Primary.def) ||
                                                                                    (s.genericDef != null && s.genericDef.lambda(pawn.equipment.Primary.def))));

            if (eqSlot == null)
            {
                dropEquipment = pawn.equipment.Primary;
                return(true);
            }
            return(false);
        }
        /// <summary>
        /// Tries to give the pawn a job related to picking up or dropping an item from their inventory.
        /// </summary>
        /// <param name="pawn">Pawn to which the job is given.</param>
        /// <returns>Job that the pawn was instructed to do, be it hauling a dropped Thing or going and getting a Thing.</returns>
        protected override Job TryGiveJob(Pawn pawn)
        {
            // Get inventory
            CompInventory inventory = pawn.TryGetComp <CompInventory>();

            if (inventory == null)
            {
                return(null);
            }

            RPGILoadout loadout = pawn.GetLoadout();

            if (loadout != null)
            {
                ThingWithComps dropEq;
                ThingWithComps droppedEq;
                if (pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out droppedEq, pawn.Position, false))
                {
                    if (droppedEq != null)
                    {
                        return(HaulAIUtility.HaulToStorageJob(pawn, droppedEq));
                    }
                }
                Thing dropThing = new Thing();
                int   dropCount = 0;
                Thing droppedThing;
                if (inventory.container.TryDrop(dropThing, pawn.Position, pawn.Map, ThingPlaceMode.Near, dropCount, out droppedThing))
                {
                    if (droppedThing != null)
                    {
                        return(HaulAIUtility.HaulToStorageJob(pawn, droppedThing));
                    }
                    Log.Error(string.Concat(pawn, " tried dropping ", dropThing, " from loadout but resulting thing is null"));
                }

                // Find missing items
                ItemPriority priority;
                Thing        closestThing;
                int          count;
                Pawn         carriedBy;
                bool         doEquip      = false;
                LoadoutSlot  prioritySlot = GetPrioritySlot(pawn, out priority, out closestThing, out count, out carriedBy);
                // moved logic to detect if should equip vs put in inventory here...
                if (closestThing != null)
                {
                    if (closestThing.TryGetComp <CompEquippable>() != null &&
                        !(pawn.story != null && pawn.story.WorkTagIsDisabled(WorkTags.Violent)) &&
                        (pawn.health != null && pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) &&
                        (pawn.equipment == null || pawn.equipment.Primary == null || !loadout.Any(s => s.def == pawn.equipment.Primary.def)))
                    {
                        doEquip = true;
                    }
                    if (carriedBy == null)
                    {
                        // Equip gun if unarmed or current gun is not in loadout
                        if (doEquip)
                        {
                            return(new Job(JobDefOf.Equip, closestThing));
                        }
                        return(new Job(JobDefOf.TakeInventory, closestThing)
                        {
                            count = Mathf.Min(closestThing.stackCount, count)
                        });
                    }
                    else
                    {
                        // TODO Implement Take from Others
                        //return new Job(CE_JobDefOf.TakeFromOther, closestThing, carriedBy, doEquip ? pawn : null)
                        //{
                        //    count = doEquip ? 1 : Mathf.Min(closestThing.stackCount, count)
                        //};
                        return(null);
                    }
                }
            }
            return(null);
        }
        /// <summary>
        /// Used by GetPrioritySlot, actually finds a requested thing.
        /// </summary>
        /// <param name="pawn">Pawn to be considered.  Used in checking equipment and position when looking for nearby things.</param>
        /// <param name="curSlot">Pawn's LoadoutSlot being considered.</param>
        /// <param name="findCount">Amount of Thing of ThingDef to try and pickup.</param>
        /// <param name="curPriority">Priority of the job.</param>
        /// <param name="curThing">Thing found near pawn for potential pickup.</param>
        /// <param name="curCarrier">Pawn that is holding the curThing that 'pawn' wants.</param>
        /// <remarks>Was split off into a sepearate method so the code could be run from multiple places in caller but that is no longer needed.</remarks>
        private void FindPickup(Pawn pawn, LoadoutSlot curSlot, int findCount, out ItemPriority curPriority, out Thing curThing, out Pawn curCarrier)
        {
            curPriority = ItemPriority.None;
            curThing    = null;
            curCarrier  = null;

            Predicate <Thing> isFoodInPrison = (Thing t) => (t.GetRoom()?.isPrisonCell ?? false) && t.def.IsNutritionGivingIngestible && pawn.Faction.IsPlayer;
            // Hint: The following block defines how to find items... pay special attention to the Predicates below.
            ThingRequest req;

            if (curSlot.genericDef != null)
            {
                req = ThingRequest.ForGroup(curSlot.genericDef.thingRequestGroup);
            }
            else
            {
                req = curSlot.thingDef.Minifiable ? ThingRequest.ForGroup(ThingRequestGroup.MinifiedThing) : ThingRequest.ForDef(curSlot.thingDef);
            }
            Predicate <Thing> findItem;

            if (curSlot.genericDef != null)
            {
                findItem = t => curSlot.genericDef.lambda(t.GetInnerIfMinified().def);
            }
            else
            {
                findItem = t => t.GetInnerIfMinified().def == curSlot.thingDef;
            }
            Predicate <Thing> search = t => findItem(t) && !t.IsForbidden(pawn) && pawn.CanReserve(t) && !isFoodInPrison(t);

            // look for a thing near the pawn.
            curThing = GenClosest.ClosestThingReachable(
                pawn.Position,
                pawn.Map,
                req,
                PathEndMode.ClosestTouch,
                TraverseParms.For(pawn, Danger.None, TraverseMode.ByPawn),
                ProximitySearchRadius,
                search);
            if (curThing != null)
            {
                curPriority = ItemPriority.Proximity;
            }
            else
            {
                // look for a thing basically anywhere on the map.
                curThing = GenClosest.ClosestThingReachable(
                    pawn.Position,
                    pawn.Map,
                    req,
                    PathEndMode.ClosestTouch,
                    TraverseParms.For(pawn, Danger.None, TraverseMode.ByPawn),
                    MaximumSearchRadius,
                    search);
                if (curThing == null && pawn.Map != null)
                {
                    // look for a thing inside caravan pack animals and prisoners.  EXCLUDE other colonists to avoid looping state.
                    List <Pawn> carriers = pawn.Map.mapPawns.AllPawns.Where(
                        p => (p.inventory?.innerContainer?.InnerListForReading?.Any() ?? false) && (p.RaceProps.packAnimal && p.Faction == pawn.Faction || p.IsPrisoner && p.HostFaction == pawn.Faction) &&
                        pawn.CanReserveAndReach(p, PathEndMode.ClosestTouch, Danger.Deadly, int.MaxValue, 0)).ToList();
                    foreach (Pawn carrier in carriers)
                    {
                        Thing thing = carrier.inventory.innerContainer.FirstOrDefault(t => findItem(t));
                        if (thing != null)
                        {
                            curThing   = thing;
                            curCarrier = carrier;
                            break;
                        }
                    }
                }
                if (curThing != null)
                {
                    if (!curThing.def.IsNutritionGivingIngestible && (float)findCount / curSlot.count >= 0.5f)
                    {
                        curPriority = ItemPriority.LowStock;
                    }
                    else
                    {
                        curPriority = ItemPriority.Low;
                    }
                }
            }
        }
Exemplo n.º 7
0
    public bool SlotIsFree(LoadoutSlots slot)
    {
        LoadoutSlot slotcontainer = slots[slot];

        return(!slotcontainer.hidden && slotcontainer.contains == null);
    }
Exemplo n.º 8
0
    public void UnequipFromSlot(LoadoutSlots slot)
    {
        LoadoutSlot slotcontainer = slots[slot];

        slotcontainer.contains = null;
    }