コード例 #1
0
        static TransformerUtility()
        {
            PossiblePawnKinds = new[]
            {
                PawnKindDefOf.Slave,
                PawnKindDefOf.Colonist,
                PawnKindDefOf.SpaceRefugee,
                PawnKindDefOf.Villager,
                PawnKindDefOf.Drifter,
                PawnKindDefOf.AncientSoldier
            };


            DefaultDamageValues = new MutagenDamageProperties();
        }
コード例 #2
0
        /// <summary>
        /// applies damage to all apparel the pawn is wearing based on
        /// </summary>
        /// <param name="pawn">The pawn.</param>
        /// <param name="newRace">The new race.</param>
        /// <param name="mutagen">the mutagen that caused the transformation, if null uses default values for <see cref="MutagenDamageProperties"/></param>
        /// <exception cref="System.ArgumentNullException">
        /// pawn
        /// or
        /// newRace
        /// </exception>
        public static void ApplyTfDamageToApparel([NotNull] Pawn pawn, [NotNull] ThingDef newRace, [CanBeNull] MutagenDef mutagen)
        {
            if (pawn == null)
            {
                throw new ArgumentNullException(nameof(pawn));
            }
            if (newRace == null)
            {
                throw new ArgumentNullException(nameof(newRace));
            }
            Pawn_ApparelTracker apparelTracker = pawn.apparel;
            List <Apparel>      cachedApparel  = apparelTracker?.WornApparel?.ToList(); //make a copy of all worn apparel

            if (cachedApparel == null || cachedApparel.Count == 0)
            {
                return;
            }

            MutagenDamageProperties damageProps = mutagen?.damageProperties ?? DefaultDamageValues;

            float oldSize = pawn.RaceProps.baseBodySize;
            float newSize = newRace.race.baseBodySize;
            float percentDiff;

            if (oldSize < EPSILON && newSize < EPSILON) //prevent division by zero
            {
                percentDiff = 0;                        //if they're both really small say no change
            }
            else if (oldSize < EPSILON)
            {
                percentDiff = MAX_APPAREL_PDIFF; //if just old size is small then completely destroy the apparel
            }
            else
            {
                percentDiff  = (newSize - oldSize) / oldSize; //signed percent difference between
                percentDiff += APPAREL_PDIFF_OFFSET;          //add a little offset so if the body size is the same or slightly smaller we still apply some damage
                //trying to account for differences in 'body shape'
            }


            float percentDamage =
                Mathf.Clamp(percentDiff, 0,
                            MAX_APPAREL_PDIFF); //clamp pDiff between [0, Max], if they shrink don't damage apparel

            percentDamage /= MAX_APPAREL_PDIFF; //normalize the percentDifference to get a percentage to damage apparel by
            int totalStuffProduced = 0;

            foreach (Apparel apparel in cachedApparel)
            {
                int damage = Mathf.CeilToInt(apparel.MaxHitPoints * percentDamage * damageProps.apparelDamageMultiplier)
                             + damageProps.apparelDamageOffset;
                int newHitPoints = Mathf.Max(apparel.HitPoints - damage, 0);
                var damageDone   = apparel.HitPoints - newHitPoints; //save the actual damage done

                apparel.HitPoints = newHitPoints;
                if (apparel.HitPoints == 0)
                {
                    apparelTracker.Remove(apparel);
                    apparelTracker.Notify_ApparelRemoved(apparel);
                    apparel.Destroy();
                }

                var stuffProduced = Mathf.FloorToInt(damageDone * damageProps.spawnedBiproductMult);
                totalStuffProduced += Mathf.Min(stuffProduced, MAX_APPAREL_DAMAGE_PRODUCT_PER_APPAREL);
            }

            if (damageProps.biproduct != null && damageProps.spawnedBiproductMult > EPSILON)
            {
                Thing thing = ThingMaker.MakeThing(damageProps.biproduct);
                thing.stackCount = totalStuffProduced;

                if (pawn.Spawned)
                {
                    GenPlace.TryPlaceThing(thing, pawn.PositionHeld, pawn.MapHeld, ThingPlaceMode.Near);
                }
                else
                {
                    Caravan caravan = pawn.GetCaravan();
                    caravan?.AddPawnOrItem(thing, false);
                }
            }
        }