private static float GetComparativeChanceAgainst(Pawn attacker, Pawn defender, StatDef stat, float baseChance, float defenderSkillMult = 1)
        {
            if (attacker == null || defender == null)
            {
                return(0);
            }
            var offSkill = stat.Worker.IsDisabledFor(attacker) ? 0 : attacker.GetStatValue(stat);
            var defSkill = stat.Worker.IsDisabledFor(defender) ? 0 : defender.GetStatValue(stat) * defenderSkillMult;
            var chance   = Mathf.Clamp01(baseChance + offSkill - defSkill);

            return(chance);
        }
Beispiel #2
0
        internal static void GenerateStartingOutfits(OutfitDatabase db, bool vanilla = true)
        {
            if (vanilla)
            {
                ConfigureWorkerOutfit(MakeOutfit(db, "Anything"), new Dictionary <StatDef, float> {
                    { StatDefOf.MoveSpeed, Priority.Desired },
                    { StatDefOf.WorkSpeedGlobal, Priority.Wanted },
                    { StatDefOf.ArmorRating_Blunt, Priority.Desired },
                    { StatDefOf.ArmorRating_Sharp, Priority.Desired },
                });

                ConfigureWorkerOutfit(MakeOutfit(db, "Worker"), new Dictionary <StatDef, float> {
                    { StatDefOf.MoveSpeed, Priority.Neutral },
                    { StatDefOf.WorkSpeedGlobal, Priority.Desired },
                });
            }

            ConfigureWorkerOutfit(MakeOutfit(db, "Doctor"), new Dictionary <StatDef, float> {
                { StatDefOf.MedicalSurgerySuccessChance, Priority.Wanted },
                { StatDef.Named("MedicalOperationSpeed"), Priority.Wanted },
                { StatDefOf.MedicalTendQuality, Priority.Wanted },
                { StatDefOf.MedicalTendSpeed, Priority.Desired },
                { StatDefOf.WorkSpeedGlobal, Priority.Desired },
            });

            ConfigureWorkerOutfit(MakeOutfit(db, "Warden"), new Dictionary <StatDef, float> {
                { StatDefOf.NegotiationAbility, Priority.Wanted },
                { StatDefOf.SocialImpact, Priority.Desired },
                { StatDefOf.TradePriceImprovement, Priority.Wanted },
            });

            ConfigureWorkerOutfit(MakeOutfit(db, "Handler"), new Dictionary <StatDef, float> {
                { StatDefOf.TrainAnimalChance, Priority.Wanted },
                { StatDefOf.TameAnimalChance, Priority.Wanted },
                { StatDefOf.ArmorRating_Sharp, Priority.Neutral },
                { StatDefOf.MeleeDodgeChance, Priority.Desired },
                { StatDefOf.MeleeHitChance, Priority.Neutral },
                { StatDefOf.MoveSpeed, Priority.Neutral },
                { StatDefOf.MeleeDPS, Priority.Neutral },
                { StatDefOf.AccuracyTouch, Priority.Neutral },
                { StatDefOf.MeleeWeapon_CooldownMultiplier, Priority.Unwanted },
                { StatDefOf.MeleeWeapon_DamageMultiplier, Priority.Neutral },
                { StatDefOf.PainShockThreshold, Priority.Wanted },
                { StatDefOf.AnimalGatherYield, Priority.Wanted },
                { StatDefOf.AnimalGatherSpeed, Priority.Wanted },
            });

            ConfigureWorkerOutfit(MakeOutfit(db, "Cook"), new Dictionary <StatDef, float> {
                { StatDef.Named("DrugCookingSpeed"), Priority.Wanted },
                { StatDef.Named("ButcheryFleshSpeed"), Priority.Wanted },
                { StatDef.Named("ButcheryFleshEfficiency"), Priority.Wanted },
                { StatDef.Named("CookSpeed"), Priority.Wanted },
                { StatDefOf.FoodPoisonChance, Priority.Unwanted },
                { StatDefOf.MoveSpeed, Priority.Desired },
                { StatDefOf.WorkSpeedGlobal, Priority.Desired },
            });

            ConfigureSoldierOutfit(MakeOutfit(db, "Hunter"), new Dictionary <StatDef, float> {
                { StatDefOf.ShootingAccuracyPawn, Priority.Wanted },
                { StatDefOf.MoveSpeed, Priority.Desired },
                { StatDefOf.AccuracyShort, Priority.Desired },
                { StatDefOf.AccuracyMedium, Priority.Desired },
                { StatDefOf.AccuracyLong, Priority.Desired },
                { StatDefOf.MeleeDPS, Priority.Neutral },
                { StatDefOf.MeleeHitChance, Priority.Neutral },
                { StatDefOf.ArmorRating_Blunt, Priority.Neutral },
                { StatDefOf.ArmorRating_Sharp, Priority.Neutral },
                { StatDefOf.RangedWeapon_Cooldown, Priority.Unwanted },
                { StatDefOf.AimingDelayFactor, Priority.Unwanted },
                { StatDefOf.PainShockThreshold, Priority.Wanted },
            });

            ConfigureWorkerOutfit(MakeOutfit(db, "Builder"), new Dictionary <StatDef, float> {
                { StatDefOf.FixBrokenDownBuildingSuccessChance, Priority.Wanted },
                { StatDefOf.ConstructionSpeed, Priority.Wanted },
                { StatDefOf.ConstructSuccessChance, Priority.Wanted },
                { StatDefOf.SmoothingSpeed, Priority.Wanted },
                { StatDefOf.MoveSpeed, Priority.Neutral },
                { StatDefOf.WorkSpeedGlobal, Priority.Neutral },
            });

            ConfigureWorkerOutfit(MakeOutfit(db, "Grower"), new Dictionary <StatDef, float> {
                { StatDefOf.PlantHarvestYield, Priority.Wanted },
                { StatDefOf.PlantWorkSpeed, Priority.Wanted },
                { StatDefOf.MoveSpeed, Priority.Neutral },
                { StatDefOf.WorkSpeedGlobal, Priority.Desired },
            });

            ConfigureWorkerOutfit(MakeOutfit(db, "Miner"), new Dictionary <StatDef, float> {
                { StatDefOf.MiningYield, Priority.Wanted },
                { StatDefOf.MiningSpeed, Priority.Wanted },
                { StatDefOf.MoveSpeed, Priority.Neutral },
                { StatDefOf.WorkSpeedGlobal, Priority.Desired },
            });

            ConfigureWorkerOutfit(MakeOutfit(db, "Smith"), new Dictionary <StatDef, float> {
                { StatDef.Named("SmithingSpeed"), Priority.Wanted },
                { StatDefOf.WorkSpeedGlobal, Priority.Desired },
            });

            ConfigureWorkerOutfit(MakeOutfit(db, "Tailor"), new Dictionary <StatDef, float> {
                { StatDef.Named("TailoringSpeed"), Priority.Wanted },
                { StatDefOf.WorkSpeedGlobal, Priority.Desired },
            });

            ConfigureWorkerOutfit(MakeOutfit(db, "Artist"), new Dictionary <StatDef, float> {
                { StatDef.Named("SculptingSpeed"), Priority.Wanted },
                { StatDefOf.WorkSpeedGlobal, Priority.Desired },
            });

            ConfigureWorkerOutfit(MakeOutfit(db, "Crafter"), new Dictionary <StatDef, float> {
                { StatDef.Named("SmeltingSpeed"), Priority.Wanted },
                { StatDef.Named("ButcheryMechanoidSpeed"), Priority.Wanted },
                { StatDef.Named("ButcheryMechanoidEfficiency"), Priority.Wanted },
                { StatDefOf.WorkSpeedGlobal, Priority.Wanted },
            });

            ConfigureWorkerOutfit(MakeOutfit(db, "Hauler"), new Dictionary <StatDef, float> {
                { StatDefOf.MoveSpeed, Priority.Wanted },
                { StatDefOf.CarryingCapacity, Priority.Wanted },
            });

            ConfigureWorkerOutfit(MakeOutfit(db, "Cleaner"), new Dictionary <StatDef, float> {
                { StatDefOf.MoveSpeed, Priority.Wanted },
                { StatDefOf.WorkSpeedGlobal, Priority.Wanted },
            });

            ConfigureWorkerOutfit(MakeOutfit(db, "Researcher"), new Dictionary <StatDef, float> {
                { StatDefOf.ResearchSpeed, Priority.Wanted },
                { StatDefOf.WorkSpeedGlobal, Priority.Desired },
            });

            ConfigureSoldierOutfit(MakeOutfit(db, "Brawler"), new Dictionary <StatDef, float> {
                { StatDefOf.MoveSpeed, Priority.Wanted },
                { StatDefOf.AimingDelayFactor, Priority.Unwanted },
                { StatDefOf.MeleeDPS, Priority.Wanted },
                { StatDefOf.MeleeHitChance, Priority.Wanted },
                { StatDefOf.MeleeDodgeChance, Priority.Wanted },
                { StatDefOf.ArmorRating_Blunt, Priority.Neutral },
                { StatDefOf.ArmorRating_Sharp, Priority.Desired },
                { StatDefOf.AccuracyTouch, Priority.Wanted },
                { StatDefOf.MeleeWeapon_DamageMultiplier, Priority.Wanted },
                { StatDefOf.MeleeWeapon_CooldownMultiplier, Priority.Unwanted },
                { StatDefOf.PainShockThreshold, Priority.Wanted },
            });

            if (vanilla)
            {
                ConfigureSoldierOutfit(MakeOutfit(db, "Soldier"), new Dictionary <StatDef, float> {
                    { StatDefOf.ShootingAccuracyPawn, Priority.Wanted },
                    { StatDefOf.AccuracyShort, Priority.Desired },
                    { StatDefOf.AccuracyMedium, Priority.Desired },
                    { StatDefOf.AccuracyLong, Priority.Desired },
                    { StatDefOf.MoveSpeed, Priority.Desired },
                    { StatDefOf.ArmorRating_Blunt, Priority.Neutral },
                    { StatDefOf.ArmorRating_Sharp, Priority.Desired },
                    { StatDefOf.MeleeDodgeChance, Priority.Neutral },
                    { StatDefOf.AimingDelayFactor, Priority.Unwanted },
                    { StatDefOf.RangedWeapon_Cooldown, Priority.Unwanted },
                    { StatDefOf.PainShockThreshold, Priority.Wanted },
                });
                ConfigureNudistOutfit(MakeOutfit(db, "Nudist"), new Dictionary <StatDef, float> {
                    { StatDefOf.MoveSpeed, Priority.Desired },
                    { StatDefOf.WorkSpeedGlobal, Priority.Wanted },
                });
            }
        }
Beispiel #3
0
        public static readonly DamageDef absorbDamageDef = DamageDefOf.Blunt;   //The damage def to convert absorbed shots into

        /// <summary>
        /// Calculates deflection chance and damage through armor
        /// </summary>
        public static int GetAfterArmorDamage(Pawn pawn, int amountInt, BodyPartRecord part, DamageInfo dinfo, bool damageArmor, ref bool deflected)
        {
            DamageDef damageDef = dinfo.Def;

            if (damageDef.armorCategory == DamageArmorCategory.IgnoreArmor)
            {
                return(amountInt);
            }

            float   damageAmount   = (float)amountInt;
            StatDef deflectionStat = damageDef.armorCategory.DeflectionStat();
            float   pierceAmount   = 0f;

            //Check if the projectile has the armor-piercing comp
            CompProperties_AP props = null;

            if (dinfo.Source != null)
            {
                VerbProperties verbProps = dinfo.Source.Verbs.Where(x => x.isPrimary).First();
                if (verbProps != null)
                {
                    ThingDef projectile = verbProps.projectileDef;
                    if (projectile != null && projectile.HasComp(typeof(CompAP)))
                    {
                        props = (CompProperties_AP)projectile.GetCompProperties(typeof(CompAP));
                    }
                }

                //Check weapon for comp if projectile doesn't have it
                if (props == null && dinfo.Source.HasComp(typeof(CompAP)))
                {
                    props = (CompProperties_AP)dinfo.Source.GetCompProperties(typeof(CompAP));
                }
            }

            if (props != null)
            {
                pierceAmount = props.armorPenetration;
            }

            //Run armor calculations on all apparel
            if (pawn.apparel != null)
            {
                List <Apparel> wornApparel = new List <Apparel>(pawn.apparel.WornApparel);
                for (int i = wornApparel.Count - 1; i >= 0; i--)
                {
                    if (wornApparel[i].def.apparel.CoversBodyPart(part))
                    {
                        Thing armorThing = damageArmor ? wornApparel[i] : null;

                        //Check for deflection
                        if (Utility.ApplyArmor(ref damageAmount, ref pierceAmount, wornApparel[i].GetStatValue(deflectionStat, true), armorThing, damageDef))
                        {
                            deflected = true;
                            if (damageDef != absorbDamageDef)
                            {
                                damageDef      = absorbDamageDef;
                                deflectionStat = damageDef.armorCategory.DeflectionStat();
                                i++;
                            }
                        }
                        if (damageAmount < 0.001)
                        {
                            return(0);
                        }
                    }
                }
            }
            //Check for pawn racial armor
            if (Utility.ApplyArmor(ref damageAmount, ref pierceAmount, pawn.GetStatValue(deflectionStat, true), null, damageDef))
            {
                deflected = true;
                if (damageAmount < 0.001)
                {
                    return(0);
                }
                damageDef      = absorbDamageDef;
                deflectionStat = damageDef.armorCategory.DeflectionStat();
                Utility.ApplyArmor(ref damageAmount, ref pierceAmount, pawn.GetStatValue(deflectionStat, true), pawn, damageDef);
            }
            return(Mathf.RoundToInt(damageAmount));
        }
Beispiel #4
0
            static string AgregateApparelBreakDown(IEnumerable <BodyPartRecord> bodyParts, IEnumerable <Apparel> apparels, StatDef stat, float natValue, string unit)
            {
                string text = "";

                foreach (BodyPartRecord bodyPartRecord in bodyParts)
                {
                    float num = bodyPartRecord.isNaturalArmor() ? natValue : 0f;
                    if (bodyPartRecord.depth == BodyPartDepth.Outside &&
                        (bodyPartRecord.coverage >= 0.1 || bodyPartRecord.def == BodyPartDefOf.Eye || bodyPartRecord.def == BodyPartDefOf.Neck))
                    {
                        text = text + bodyPartRecord.LabelCap + ": ";
                        if (!apparels.EnumerableNullOrEmpty())
                        {
                            foreach (Apparel apparel in apparels)
                            {
                                if (apparel.def.apparel.CoversBodyPart(bodyPartRecord))
                                {
                                    num += apparel.GetStatValue(stat, true);
                                }
                            }
                        }
                        text = text + FormatArmorValue(num, unit) + "\n";
                    }
                }
                return(text);
            }
        public static float?GetStatOffsetValue(this ThingDef stuff, StatDef statDef)
        {
            StatModifier?factorFromDef = stuff.stuffProps?.statOffsets?.FirstOrDefault(fa => fa.stat == statDef);

            return(factorFromDef?.value);
        }
Beispiel #6
0
 static bool Prefix(StatWorker __instance, StatRequest req, ref bool __result, ref StatDef ___stat)
 {
     if (___stat.category == WTH_DefOf.WTH_StatCategory_HackedMechanoid && req.Thing is Pawn pawn)
     {
         __result = pawn.IsHacked();
         return(false);
     }
     if (___stat.category == WTH_DefOf.WTH_StatCategory_Colonist && req.Thing is Pawn pawn2)
     {
         __result = pawn2.IsColonistPlayerControlled;
         return(false);
     }
     if (___stat.category == WTH_DefOf.WTH_StatCategory_Platform && req.Thing is Building_BaseMechanoidPlatform)
     {
         __result = true;
         return(false);
     }
     if (___stat.category == WTH_DefOf.WTH_StatCategory_HackedMechanoid || ___stat.category == WTH_DefOf.WTH_StatCategory_Colonist || ___stat.category == WTH_DefOf.WTH_StatCategory_Platform)
     {
         __result = false;
         return(false);
     }
     return(true);
 }
Beispiel #7
0
 public Jumps()
 {
     Definition = StatDef.Register(token, recordType, dataType, 0, null);
     FullText   = fullText;
 }
 public static string GetName(Thing thing, StatDef stat)
 {
     return(GetValDetour ? null :
            ByDef ? $"{stat.defName} for {thing.def.defName}" : stat.defName);
 }
Beispiel #9
0
        public static bool UserEffect(this Verb verb, out float Chance, out HediffDef Effect, out StatDef ResistStat, out List <string> ImmuneList)
        {
            Chance     = 0;
            Effect     = null;
            ResistStat = null;
            ImmuneList = new List <string>();
            bool result = verb.SpecialRules() != null && verb.SpecialRules().EffectsUser&& AMSettings.Instance.AllowUserEffects;

            if (result)
            {
                Effect     = verb.SpecialRules().UserEffect;
                ResistStat = verb.SpecialRules().ResistEffectStat;
                Chance     = verb.SpecialRules().EffectsUserChance;
                ImmuneList = verb.SpecialRules().UserEffectImmuneList;
                if (verb.SpecialRules().UserEffectImmuneList.Contains(verb.caster.def.defName) || verb.caster == null || !verb.CasterIsPawn)
                {
                    return(false);
                }
            }
            return(result);
        }
Beispiel #10
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);
        }
Beispiel #11
0
 public StatPriority(StatDef stat, float priority, StatAssignment assignment = StatAssignment.Automatic)
 {
     Stat       = stat;
     Weight     = priority;
     Assignment = assignment;
 }
Beispiel #12
0
 private static string FinalValue(StatDef stat, float value)
 {
     return("StatsReport_FinalValue".Translate() + ": " + stat.ValueToString(val: value, numberSense: stat.toStringNumberSense) + "\n\n");
 }
 public StatPriority( StatDef stat, float priority, StatAssignment assignment = StatAssignment.Automatic )
 {
     Stat = stat;
     Weight = priority;
     Assignment = assignment;
 }
        public static void Patch_StatWorker_GetExplanationUnfinalized(StatWorker __instance, ref string __result, ref StatRequest req, ToStringNumberSense numberSense, StatDef ___stat)
        {
            Pawn pawn = req.Thing as Pawn;

            if (pawn != null && pawn.GetJobsComp() is DivineJobsComp jobsComp)
            {
                StringBuilder builder = new StringBuilder(__result);

                if (jobsComp.StatOffsets.FirstOrDefault(mod => mod.stat == ___stat) is StatModifier statModifer)
                {
                    builder.AppendLine();
                    builder.AppendLine();
                    builder.AppendLine("DivineJobs_Stats_JobTitle".Translate());

                    builder.AppendLine("    " + "DivineJobs_Stats_FromJobs".Translate() + ": " + statModifer.value.ToStringByStyle(statModifer.stat.ToStringStyleUnfinalized, ToStringNumberSense.Offset));
                    __result = builder.ToString().TrimEndNewlines();
                }
            }
        }
Beispiel #15
0
 public DamageBlocked()
 {
     Definition = StatDef.Register(token, StatRecordType.Sum, StatDataType.ULong, 0, null);
     FullText   = fullText;
 }
Beispiel #16
0
 public static float GetStatValue(this Thing thing, StatDef stat, bool applyPostProcess = true)
 {
     return stat.Worker.GetValue(thing, applyPostProcess);
 }
Beispiel #17
0
        public static string Postfix(string __result, StatRequest req, StatDef ___stat)
        {
            if (!req.HasThing || !PsiTechCachingUtility.CachedAffectedStats.Contains(___stat))
            {
                return(__result);
            }

            if (req.Thing is Pawn pawn)
            {
                var sb        = new StringBuilder();
                var abilities = pawn.PsiTracker().Abilities;

                if (abilities.Count > 0)
                {
                    sb.AppendLine("PsiTech.PsionicAbilitiesReport".Translate() + ":");
                }

                var didHaveEffect = false;
                foreach (var ability in abilities)
                {
                    var offset = ability.GetOffsetOfStat(___stat);
                    var factor = ability.GetFactorOfStat(___stat);

                    if (offset != 0)
                    {
                        didHaveEffect = true;
                        sb.AppendLine("    " + ability.Def.label + ": " +
                                      offset.ToStringByStyle(___stat.ToStringStyleUnfinalized,
                                                             ToStringNumberSense.Offset));
                    }

                    if (factor != 1)
                    {
                        didHaveEffect = true;
                        sb.AppendLine("    " + ability.Def.label + ": " +
                                      factor.ToStringByStyle(___stat.ToStringStyleUnfinalized,
                                                             ToStringNumberSense.Factor));
                    }
                }

                if (didHaveEffect)
                {
                    __result += "\n\n" + sb;
                }

                if (___stat != StatDefOf.PsychicSensitivity)
                {
                    return(__result);
                }

                var field = pawn.Map?.GetComponent <SuppressionFieldManager>().GetEffectOnCell(pawn.Position) ?? 0f;
                if (field == 0f)
                {
                    return(__result);
                }

                __result += "\n" + "PsiTech.SuppressionFieldEffect".Translate(
                    field.ToStringByStyle(___stat.ToStringStyleUnfinalized, ToStringNumberSense.Offset));
            }
            else if (req.Thing.PsiEquipmentTracker()?.IsPsychic ?? false)
            {
                var equip = req.Thing.TryGetComp <CompEquippable>();
                if (equip == null || !(equip.PrimaryVerb.caster is Pawn caster))
                {
                    return(__result);
                }

                var factor = req.Thing.PsiEquipmentTracker().GetTotalFactorOfStat(___stat, caster);
                if (factor != 1)
                {
                    __result += "\n\n" + "PsiTech.PsychicWeaponReport".Translate() +
                                factor.ToStringByStyle(___stat.toStringStyle, ToStringNumberSense.Factor);
                }
            }

            return(__result);
        }
        public static void PrefixAbility(MethodBase __originalMethod, AbilityDef def, StatDef stat, ref Profiler __state)
        {
            if (Active && !GetValDetour)
            {
                string state = string.Empty;
                if (ByDef)
                {
                    state = $"{stat.defName} abstract for {def.defName}";
                }
                else
                {
                    state = $"{stat.defName} abstract";
                }

                __state = ProfileController.Start(state, null, null, __originalMethod);
            }
        }
Beispiel #19
0
        public static readonly DamageDef absorbDamageDef = DamageDefOf.Blunt;   //The damage def to convert absorbed shots into

        /// <summary>
        /// Calculates deflection chance and damage through armor
        /// </summary>
        public static int GetAfterArmorDamage(Pawn pawn, int damAmountInt, BodyPartRecord part, DamageInfo dinfo, bool damageArmor, ref bool deflected)
        {
            DamageDef damageDef = dinfo.Def;

            if (damageDef.armorCategory == DamageArmorCategory.IgnoreArmor)
            {
                return(damAmountInt);
            }

            float   damageAmount   = (float)damAmountInt;
            StatDef deflectionStat = damageDef.armorCategory.DeflectionStat();

            // Get armor penetration value
            float pierceAmount = 0f;

            if (dinfo.Source != null)
            {
                ProjectilePropertiesCR projectileProps = dinfo.Source.projectile as ProjectilePropertiesCR;
                if (projectileProps != null)
                {
                    pierceAmount = projectileProps.armorPenetration;
                }
                else if (dinfo.Instigator != null)
                {
                    Pawn instigatorPawn = dinfo.Instigator as Pawn;
                    if (instigatorPawn != null)
                    {
                        if (instigatorPawn.equipment != null && instigatorPawn.equipment.Primary != null)
                        {
                            pierceAmount = instigatorPawn.equipment.Primary.GetStatValue(StatDef.Named("ArmorPenetration"));
                        }
                        else
                        {
                            pierceAmount = instigatorPawn.GetStatValue(StatDef.Named("ArmorPenetration"));
                        }
                    }
                }
            }

            // Run armor calculations on all apparel
            if (pawn.apparel != null)
            {
                List <Apparel> wornApparel = new List <Apparel>(pawn.apparel.WornApparel);
                for (int i = wornApparel.Count - 1; i >= 0; i--)
                {
                    if (wornApparel[i].def.apparel.CoversBodyPart(part))
                    {
                        Thing armorThing = damageArmor ? wornApparel[i] : null;

                        //Check for deflection
                        if (Utility.ApplyArmor(ref damageAmount, ref pierceAmount, wornApparel[i].GetStatValue(deflectionStat, true), armorThing, damageDef))
                        {
                            deflected = true;
                            if (damageDef != absorbDamageDef)
                            {
                                damageDef      = absorbDamageDef;
                                deflectionStat = damageDef.armorCategory.DeflectionStat();
                                i++;
                            }
                        }
                        if (damageAmount < 0.001)
                        {
                            return(0);
                        }
                    }
                }
            }
            float pawnArmorAmount    = 0f;
            bool  partCoveredByArmor = false;

            if (part.IsInGroup(DefDatabase <BodyPartGroupDef> .GetNamed("CoveredByNaturalArmor")))
            {
                partCoveredByArmor = true;
            }
            else
            {
                BodyPartRecord outerPart = part;
                while (outerPart.parent != null && outerPart.depth != BodyPartDepth.Outside)
                {
                    outerPart = outerPart.parent;
                }
                partCoveredByArmor = outerPart != part && outerPart.IsInGroup(DefDatabase <BodyPartGroupDef> .GetNamed("CoveredByNaturalArmor"));
            }
            if (partCoveredByArmor)
            {
                pawnArmorAmount = pawn.GetStatValue(deflectionStat);
            }

            if (pawnArmorAmount > 0 && Utility.ApplyArmor(ref damageAmount, ref pierceAmount, pawnArmorAmount, null, damageDef))
            {
                deflected = true;
                if (damageAmount < 0.001)
                {
                    return(0);
                }
                damageDef      = absorbDamageDef;
                deflectionStat = damageDef.armorCategory.DeflectionStat();
                Utility.ApplyArmor(ref damageAmount, ref pierceAmount, pawn.GetStatValue(deflectionStat, true), pawn, damageDef);
            }
            return(Mathf.RoundToInt(damageAmount));
        }
 public static float GetValueFromComp(Pawn pawn, StatDef stat) =>
 pawn.TryGetComp <CompHybrid>()?.GetStatFactor(stat) ?? 1f;
        public override string GetStatDrawEntryLabel(StatDef stat, float value, ToStringNumberSense numberSense, StatRequest optionalReq)
        {
            var ammoProps = (optionalReq.Def as ThingDef)?.GetCompProperties <CompProperties_AmmoUser>();

            return(ammoProps.magazineSize + " / " + GenText.ToStringByStyle((ammoProps.reloadTime), ToStringStyle.FloatTwo) + " s");
        }
Beispiel #22
0
        // Modified PathGrid.CalculatedCostAt()
        public static int PathGrid_CalculatedCostAt(Pawn Pawn, IntVec3 c)
        {
            IntVec3 prevCell = Pawn.Position;

            // Modified beahaviour:
            // - Apply CountersIcePenalty and CountersSnowPenalty stats
            // - When snow it's medium or thicker, terrain does not apply anymore.

            TerrainDef terrainDef = Pawn.Map.terrainGrid.TerrainAt(c);

            if (terrainDef == null || terrainDef.passability == Traversability.Impassable)
            {
                return(10000);
            }

            // Get terrain path cost
            int pcTerrain = terrainDef.pathCost;

            if (terrainDef == TerrainDefOf.Ice)
            {
                // Apply counter ice penalty
                pcTerrain = (int)Math.Ceiling((double)((float)pcTerrain * (1f - Pawn.GetStatValue(StatDef.Named("CountersIcePenalty"), true))));
            }
            // Get snow path cost
            int pcSnow = SnowUtility.MovementTicksAddOn(Pawn.Map.snowGrid.GetCategory(c));

            // Apply counter snow penalty
            pcSnow = (int)Math.Ceiling((double)((float)pcSnow * (1f - Pawn.GetStatValue(StatDef.Named("CountersSnowPenalty"), true))));

            int pc = 0;

            if (Pawn.Map.snowGrid.GetCategory(c) >= SnowCategory.Medium)
            {
                // Snow is thick, we don't consider terrain path cost
                pc = pcSnow;
            }
            else
            {
                // Snow is thin, we apply the highest path cost
                pc = pcTerrain > pcSnow ? pcTerrain : pcSnow;
            }

            bool         flagDoor = false;
            List <Thing> list     = Pawn.Map.thingGrid.ThingsListAt(c);

            for (int i = 0; i < list.Count; i++)
            {
                Thing thing = list[i];
                if (thing.def.passability == Traversability.Impassable)
                {
                    return(10000);
                }
                if (!PathGrid_IsPathCostIgnoreRepeater(thing.def) || !prevCell.IsValid || !PathGrid_ContainsPathCostIgnoreRepeater(Pawn.Map, prevCell))
                {
                    int pcThing = thing.def.pathCost;
                    if (pcThing > pc)
                    {
                        pc = pcThing;
                    }
                }
                if (thing is Building_Door && prevCell.IsValid)
                {
                    Building edifice = prevCell.GetEdifice(Pawn.Map);
                    if (edifice != null && edifice is Building_Door)
                    {
                        flagDoor = true;
                    }
                }
            }

            if (flagDoor)
            {
                pc += 45;
            }
            return(pc);
        }
Beispiel #23
0
        /// <summary>
        /// Refreshes the cached bulk and weight. Call this whenever items are added/removed from inventory
        /// </summary>
        public void UpdateInventory()
        {
            if (parentPawn == null)
            {
                Log.Error("CompInventory on non-pawn " + this.parent.ToString());
                return;
            }
            float newBulk   = 0f;
            float newWeight = 0f;

            // Add equipped weapon
            if (parentPawn.equipment != null && parentPawn.equipment.Primary != null)
            {
                GetEquipmentStats(parentPawn.equipment.Primary, out newWeight, out newBulk);
            }

            // Add apparel
            if (parentPawn.apparel != null && parentPawn.apparel.WornApparelCount > 0)
            {
                foreach (Thing apparel in parentPawn.apparel.WornApparel)
                {
                    float apparelBulk   = apparel.GetStatValue(StatDef.Named("WornBulk"));
                    float apparelWeight = apparel.GetStatValue(StatDef.Named("WornWeight"));
                    newBulk   += apparelBulk;
                    newWeight += apparelWeight;
                }
            }

            // Add inventory items
            if (parentPawn.inventory != null && parentPawn.inventory.container != null)
            {
                ammoListCached.Clear();
                meleeWeaponListCached.Clear();
                rangedWeaponListCached.Clear();
                foreach (Thing thing in parentPawn.inventory.container)
                {
                    // Check for weapons
                    ThingWithComps eq     = thing as ThingWithComps;
                    CompEquippable compEq = thing.TryGetComp <CompEquippable>();
                    if (eq != null && compEq != null)
                    {
                        if (compEq.PrimaryVerb != null)
                        {
                            rangedWeaponListCached.Add(eq);
                        }
                        else
                        {
                            meleeWeaponListCached.Add(eq);
                        }
                        // Calculate equipment weight
                        float eqWeight;
                        float eqBulk;
                        GetEquipmentStats(eq, out eqWeight, out eqBulk);
                        newWeight += eqWeight * thing.stackCount;
                        newBulk   += eqBulk * thing.stackCount;
                    }
                    else
                    {
                        // Add item weight
                        newBulk   += thing.GetStatValue(StatDef.Named("Bulk")) * thing.stackCount;
                        newWeight += thing.GetStatValue(StatDef.Named("Weight")) * thing.stackCount;
                    }
                    // Update ammo list
                    if (thing.def is AmmoDef)
                    {
                        ammoListCached.Add(thing);
                    }
                }
            }
            this.currentBulkCached   = newBulk;
            this.currentWeightCached = newWeight;
        }
Beispiel #24
0
            static void TryDrawOverallArmor1(object tab, ref float top, float left, float width, StatDef stat, string label, string unit, Texture image)
            {
                Pawn pawn = (Pawn)LSelPawnForGear.GetValue(tab);
                //
                float statValue             = pawn.GetStatValue(stat, true);
                float num                   = statValue;
                Pawn_ApparelTracker apparel = pawn.apparel;
                List <Apparel>      list    = pawn?.apparel.WornApparel;

                num += AgregateApparelStat(list, stat);
                //
                if (num > 0.0001f)
                {
                    float  statIconSize      = (float)LstatIconSize.GetValue(null);
                    float  stdThingIconSize  = (float)LstdThingIconSize.GetValue(null);
                    float  stdThingRowHeight = (float)LstdThingRowHeight.GetValue(null);
                    string text = AgregateApparelBreakDown(pawn.RaceProps.body.AllParts, list, stat, statValue, unit);
                    Rect   rect = new Rect(left, top, width, statIconSize);
                    Sandy_Utility.LabelWithIcon(rect, image, statIconSize, statIconSize, label, FormatArmorValue(num, unit), text);
                    top += stdThingRowHeight;
                }
            }
Beispiel #25
0
 public RandomNumber()
 {
     random     = new Random();
     Definition = StatDef.Register(token, StatRecordType.Newest, StatDataType.ULong, 0);
     FullText   = fulltext;
 }
 public static IEnumerable <Dialog_InfoCard.Hyperlink> Postfix(IEnumerable <Dialog_InfoCard.Hyperlink> original, StatRequest req, StatDef ___apparelStat)
 {
     if (req.HasThing && req.Thing != null)
     {
         Pawn pawn = req.Thing as Pawn;
         if (pawn != null && pawn.InBed())
         {
             yield return(new Dialog_InfoCard.Hyperlink(pawn.CurrentBed(), -1));
         }
     }
     yield break;
 }
Beispiel #27
0
 public Seed()
 {
     Definition = StatDef.Register(token, StatRecordType.Newest, StatDataType.ULong, 0);
     FullText   = fulltext;
 }
Beispiel #28
0
        public void Draw(Rect rect, ThingWithComps ownerPawn)
        {
            Text.Font = GameFont.Small;
            string value = "-";

            switch (oType)
            {
            case objectType.Stat:
                Text.Anchor = TextAnchor.MiddleCenter;
                StatDef stat      = (StatDef)displayObject;
                string  statValue = (stat.ValueToString(ownerPawn.GetStatValue((StatDef)displayObject, true)));
                Widgets.Label(rect, statValue);
                if (Mouse.IsOver(rect))
                {
                    GUI.DrawTexture(rect, TexUI.HighlightTex);
                }

                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.AppendLine(stat.LabelCap);
                stringBuilder.AppendLine();
                stringBuilder.AppendLine(stat.description);
                TooltipHandler.TipRegion(rect, new TipSignal(stringBuilder.ToString(), rect.GetHashCode()));
                break;

            case objectType.Skill:
                if ((ownerPawn is Pawn) && (ownerPawn as Pawn).RaceProps.Humanlike)
                {
                    DrawSkill(rect, ownerPawn as Pawn);
                }
                break;

            case objectType.Need:
                if (ownerPawn is Pawn)
                {
                    DrawNeed(rect, ownerPawn as Pawn);
                }
                break;

            case objectType.Capacity:
                Text.Anchor = TextAnchor.MiddleCenter;
                if (ownerPawn is Pawn)
                {
                    Pawn            p   = (Pawn)ownerPawn;
                    PawnCapacityDef cap = (PawnCapacityDef)displayObject;

                    Pair <string, Color> effLabel = HealthCardUtility.GetEfficiencyLabel(p, cap);
                    string pawnCapTip             = HealthCardUtility.GetPawnCapacityTip(p, cap);


                    // I stole this one line from Fluffy's Medical Tab. THANKS FLUFFY!
                    string capValue = (p.health.capacities.GetEfficiency(cap) * 100f).ToString("F0") + "%";
                    GUI.color = effLabel.Second;
                    Widgets.Label(rect, capValue);
                    GUI.color = Color.white;

                    if (Mouse.IsOver(rect))
                    {
                        GUI.DrawTexture(rect, TexUI.HighlightTex);
                    }

                    StringBuilder stringBuilder2 = new StringBuilder();
                    stringBuilder2.AppendLine(cap.LabelCap);
                    stringBuilder2.AppendLine();
                    stringBuilder2.AppendLine(cap.description);
                    TooltipHandler.TipRegion(rect, new TipSignal(stringBuilder2.ToString(), rect.GetHashCode()));
                }
                break;

            case objectType.MentalState:
                Text.Font   = GameFont.Tiny;
                Text.Anchor = TextAnchor.MiddleCenter;
                if (ownerPawn is Pawn && (ownerPawn as Pawn).MentalState != null)
                {
                    string ms = ((ownerPawn as Pawn).MentalState.InspectLine);
                    Widgets.Label(rect, ms);
                    if (Mouse.IsOver(rect))
                    {
                        GUI.DrawTexture(rect, TexUI.HighlightTex);
                    }
                }
                Text.Font = GameFont.Medium;
                break;

            case objectType.Age:
                Text.Anchor = TextAnchor.MiddleCenter;
                string ageValue = ((ownerPawn as Pawn).ageTracker.AgeBiologicalYears.ToString());
                Widgets.Label(rect, ageValue);
                if (Mouse.IsOver(rect))
                {
                    GUI.DrawTexture(rect, TexUI.HighlightTex);
                }
                break;

            case objectType.Gear:
                DrawGear(rect, ownerPawn);
                break;

            case objectType.ControlPrisonerGetsFood:
                if (ownerPawn is Pawn)
                {
                    if (Mouse.IsOver(rect))
                    {
                        GUI.DrawTexture(rect, TexUI.HighlightTex);
                    }
                    bool getsFood = (ownerPawn as Pawn).guest.GetsFood;
                    Widgets.CheckboxLabeled(new Rect(rect.x + 8f, rect.y + 3f, 27f, 27f), "", ref getsFood, false);
                    (ownerPawn as Pawn).guest.GetsFood = getsFood;
                }
                break;

            case objectType.ControlPrisonerInteraction:
                if (ownerPawn is Pawn)
                {
                    if (Mouse.IsOver(rect))
                    {
                        GUI.DrawTexture(rect, TexUI.HighlightTex);
                    }
                    float x = 8f;

                    GUI.BeginGroup(rect);
                    IEnumerator enumerator = Enum.GetValues(typeof(PrisonerInteractionMode)).GetEnumerator();
                    try
                    {
                        while (enumerator.MoveNext())
                        {
                            PrisonerInteractionMode prisonerInteractionMode = (PrisonerInteractionMode)((byte)enumerator.Current);
                            if (Widgets.RadioButton(new Vector2(x, 3f), (ownerPawn as Pawn).guest.interactionMode == prisonerInteractionMode))
                            {
                                (ownerPawn as Pawn).guest.interactionMode = prisonerInteractionMode;
                            }
                            TooltipHandler.TipRegion(new Rect(x, 0f, 30f, 30f), new TipSignal(prisonerInteractionMode.GetLabel()));
                            x += 30f;
                        }
                    }
                    finally
                    {
                        IDisposable disposable = enumerator as IDisposable;
                        if (disposable != null)
                        {
                            disposable.Dispose();
                        }
                    }
                    GUI.EndGroup();
                }
                break;

            case objectType.ControlMedicalCare:
                if (ownerPawn is Pawn)
                {
                    MedicalCareSetter(rect, ref (ownerPawn as Pawn).playerSettings.medCare);
                }
                break;

            case objectType.AnimalMilkFullness:
                Text.Anchor = TextAnchor.MiddleCenter;
                if (ownerPawn is Pawn && ((Pawn)ownerPawn).ageTracker.CurLifeStage.milkable)
                {
                    var comp = ((Pawn)ownerPawn).AllComps.Where <ThingComp>(x => x is CompMilkable).FirstOrDefault();
                    if (comp != null)
                    {
                        value = ((CompMilkable)comp).Fullness.ToStringPercent();
                    }
                }

                Widgets.Label(rect, value);
                break;

            case objectType.AnimalWoolGrowth:
                Text.Anchor = TextAnchor.MiddleCenter;
                if (ownerPawn is Pawn && ((Pawn)ownerPawn).ageTracker.CurLifeStage.shearable)
                {
                    var comp = ((Pawn)ownerPawn).AllComps.Where <ThingComp>(x => x is CompShearable).FirstOrDefault();
                    if (comp != null)
                    {
                        value = ((CompShearable)comp).Fullness.ToStringPercent();
                    }
                }

                Widgets.Label(rect, value);
                break;

            case objectType.CurrentJob:
                if (ownerPawn is Pawn && ((Pawn)ownerPawn).jobs.curDriver != null)
                {
                    string text = ((Pawn)ownerPawn).jobs.curDriver.GetReport();
                    Text.Anchor = TextAnchor.MiddleLeft;
                    Rect tRect = new Rect(rect.xMin + 2, rect.yMin + 3, rect.width - 2, rect.height);
                    GenText.SetTextSizeToFit(text, tRect);

                    if (Text.Font == GameFont.Tiny)
                    {
                        Widgets.Label(tRect, text);
                    }
                    else
                    {
                        Rect sRect = new Rect(rect.xMin + 2, rect.yMin, rect.width - 2, rect.height);
                        Widgets.Label(sRect, text);
                    }

                    if (Mouse.IsOver(rect))
                    {
                        GUI.DrawTexture(rect, TexUI.HighlightTex);
                    }
                }
                break;
            }
        }
Beispiel #29
0
        /// <summary>
        /// Inserts the extra mining yield multiplier into the mining yield detailed description
        /// </summary>
        /// <param name="__result">The description we are adding onto.</param>
        /// <param name="__instance">The StatWorker</param>
        /// <param name="___stat">The StatDef of the StatWorker</param>
        /// <param name="req">The item requesting the stat.</param>
        /// <param name="numberSense">Unused</param>
        private static void CuteboldGetExplanationUnfinalizedPostfix(ref string __result, StatDef ___stat, StatRequest req, ToStringNumberSense numberSense)
        {
            Pawn pawn = req.Pawn ?? (req.Thing is Pawn ? (Pawn)req.Thing : null);

            if (pawn?.def != Cutebold_Assemblies.AlienRaceDef || ___stat != StatDefOf.MiningYield)
            {
                return;
            }

            float         rawPercent    = CuteboldCalculateExtraPercent(___stat, req, false);
            float         multiplier    = MiningMultiplier(pawn);
            StringBuilder stringBuilder = new StringBuilder(__result);

            stringBuilder.AppendLine("Cutebold_DarkAdaptation_StatString".Translate());
            stringBuilder.AppendLine("Cutebold_DarkAdaptation_StatPercentString".Translate(rawPercent.ToStringPercent(), multiplier.ToStringPercent(), (rawPercent * multiplier).ToStringPercent()));

            __result = stringBuilder.ToString();
        }
        public static void Patch_StatWorker_GetValueUnfinalized(StatWorker __instance, ref float __result, ref StatRequest req, bool applyPostProcess, StatDef ___stat)
        {
            Pawn pawn = req.Thing as Pawn;

            if (pawn != null && pawn.GetJobsComp() is DivineJobsComp jobsComp)
            {
                if (jobsComp.StatOffsets.FirstOrDefault(mod => mod.stat == ___stat) is StatModifier statModifer)
                {
                    __result += statModifer.value;
                }
            }
        }
Beispiel #31
0
        /// Changed into a transpiler.
        /// <summary>
        /// Replaces the plant harvest toil of a cutebold to allow them to harvest over 100%.
        /// </summary>
        /// <param name="__result">The previous output from the original toil generator.</param>
        /// <param name="__instance">The plant job.</param>
        /// <returns>A headache. (The new toils)</returns>
        private static IEnumerable <Toil> CuteboldMakeNewToilsPlantWorkPostfix(IEnumerable <Toil> __result, JobDriver_PlantWork __instance)
        {
            //Log.Message("CuteboldMakeNewToilsPlantWorkPostfix");

            foreach (Toil toil in __result)
            {
                if (toil.tickAction != null && __instance.pawn?.def.defName == Cutebold_Assemblies.RaceName)
                {
                    //Log.Message("  Edit Toil");

                    // Shamelessly taken from the base code and modified to allow cutebolds to harvest just that little bit more with their small, delicate hands.
                    // Two Traverses are used to access protected methods that are overwritten by classes that overwrite the defaults.
                    toil.tickAction = delegate()
                    {
                        Pawn  actor     = toil.actor;
                        Map   map       = actor.Map;
                        float xpPerTick = (float)Traverse.Create(__instance).Field("xpPerTick").GetValue();

                        if (actor.skills != null)
                        {
                            actor.skills.Learn(SkillDefOf.Plants, xpPerTick);
                        }

                        float workSpeed = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true);
                        Plant plant     = (Plant)__instance.job.targetA.Thing;

                        workSpeed *= UnityEngine.Mathf.Lerp(3.3f, 1f, plant.Growth);
                        var   workDoneVariable = Traverse.Create(__instance).Field("workDone");
                        float workDone         = (float)workDoneVariable.GetValue() + workSpeed;
                        workDoneVariable.SetValue(workDone);

                        if ((workDone) >= plant.def.plant.harvestWork)
                        {
                            if (plant.def.plant.harvestedThingDef != null)
                            {
                                StatDef stat = (plant.def.plant.harvestedThingDef.IsDrug ? StatDefOf.DrugHarvestYield : StatDefOf.PlantHarvestYield);
// 1.1                          StatDef stat = StatDefOf.PlantHarvestYield;
                                float yieldMultiplier = (1f + CuteboldCalculateExtraPercent(stat, StatRequest.For(actor)));
                                if (actor.RaceProps.Humanlike && plant.def.plant.harvestFailable && !plant.Blighted && Rand.Value > yieldMultiplier)
                                {
                                    MoteMaker.ThrowText((__instance.pawn.DrawPos + plant.DrawPos) / 2f, map, "TextMote_HarvestFailed".Translate(), 3.65f);
                                }
                                else
                                {
                                    int currentYield = GenMath.RoundRandom(plant.YieldNow() * yieldMultiplier);

                                    //Log.Message("  Pawn Additional Harvest Percent=" + calculateExtraPercent(StatDefOf.PlantHarvestYield, StatRequest.For(actor)));
                                    //Log.Message("  Plant Yield Before=" + plant.YieldNow() + " Plant Yield After=" + currentYield);

                                    if (currentYield > 0)
                                    {
                                        Thing product = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef, null);

                                        product.stackCount = currentYield;

                                        if (actor.Faction != Faction.OfPlayer)
                                        {
                                            product.SetForbidden(true);
                                        }

                                        Find.QuestManager.Notify_PlantHarvested(actor, product);
                                        GenPlace.TryPlaceThing(product, actor.Position, map, ThingPlaceMode.Near);
                                        actor.records.Increment(RecordDefOf.PlantsHarvested);
                                    }
                                }
                            }
                            plant.def.plant.soundHarvestFinish.PlayOneShot(actor);
                            plant.PlantCollected(__instance.pawn);
// 1.1                      plant.PlantCollected();
                            workDoneVariable.SetValue(0f);
                            __instance.ReadyForNextToil();
                            return;
                        }
                    };
                }
                yield return(toil);
            }
        }
        public override void DoWindowContents(Rect canvas)
        {
            // fix weird zooming bug
            Text.Font = GameFont.Small;

            // SET UP RECTS
            // top buttons
            Rect selectRect = new Rect(0f, 0f, canvas.width * .2f, _topAreaHeight);
            Rect newRect    = new Rect(selectRect.xMax + _margin, 0f, canvas.width * .2f, _topAreaHeight);
            Rect deleteRect = new Rect(newRect.xMax + _margin, 0f, canvas.width * .2f, _topAreaHeight);

            // main areas
            Rect nameRect = new Rect(
                0f,
                _topAreaHeight + _margin * 2,
                (canvas.width - _margin) / 2f,
                24f);

            Rect slotListRect = new Rect(
                0f,
                nameRect.yMax + _margin,
                (canvas.width - _margin) / 2f,
                canvas.height - _topAreaHeight - nameRect.height - _barHeight * 2 - _margin * 5);

            Rect weightBarRect = new Rect(slotListRect.xMin, slotListRect.yMax + _margin, slotListRect.width, _barHeight);
            Rect bulkBarRect   = new Rect(weightBarRect.xMin, weightBarRect.yMax + _margin, weightBarRect.width, _barHeight);

            Rect sourceButtonRect = new Rect(
                slotListRect.xMax + _margin,
                _topAreaHeight + _margin * 2,
                (canvas.width - _margin) / 2f,
                24f);

            Rect selectionRect = new Rect(
                slotListRect.xMax + _margin,
                sourceButtonRect.yMax + _margin,
                (canvas.width - _margin) / 2f,
                canvas.height - 24f - _topAreaHeight - _margin * 3);

            var loadouts = LoadoutManager.Loadouts;

            // DRAW CONTENTS
            // buttons
            // select loadout
            if (Widgets.ButtonText(selectRect, "CR.SelectLoadout".Translate()))
            {
                List <FloatMenuOption> options = new List <FloatMenuOption>();

                if (loadouts.Count == 0)
                {
                    options.Add(new FloatMenuOption("CR.NoLoadouts".Translate(), null));
                }
                else
                {
                    for (int i = 0; i < loadouts.Count; i++)
                    {
                        int local_i = i;
                        options.Add(new FloatMenuOption(loadouts[i].LabelCap, delegate
                                                        { CurrentLoadout = loadouts[local_i]; }));
                    }
                }

                Find.WindowStack.Add(new FloatMenu(options));
            }
            // create loadout
            if (Widgets.ButtonText(newRect, "CR.NewLoadout".Translate()))
            {
                var loadout = new Loadout();
                LoadoutManager.AddLoadout(loadout);
                CurrentLoadout = loadout;
            }
            // delete loadout
            if (loadouts.Any(l => l.canBeDeleted) && Widgets.ButtonText(deleteRect, "CR.DeleteLoadout".Translate()))
            {
                List <FloatMenuOption> options = new List <FloatMenuOption>();

                for (int i = 0; i < loadouts.Count; i++)
                {
                    int local_i = i;

                    // don't allow deleting the default loadout
                    if (!loadouts[i].canBeDeleted)
                    {
                        continue;
                    }
                    options.Add(new FloatMenuOption(loadouts[i].LabelCap,
                                                    delegate
                    {
                        if (CurrentLoadout == loadouts[local_i])
                        {
                            CurrentLoadout = null;
                        }
                        loadouts.Remove(loadouts[local_i]);
                    }));
                }

                Find.WindowStack.Add(new FloatMenu(options));
            }

            // draw notification if no loadout selected
            if (CurrentLoadout == null)
            {
                Text.Anchor = TextAnchor.MiddleCenter;
                GUI.color   = Color.grey;
                Widgets.Label(canvas, "CR.NoLoadoutSelected".Translate());
                GUI.color   = Color.white;
                Text.Anchor = TextAnchor.UpperLeft;

                // and stop further drawing
                return;
            }

            // name
            DrawNameField(nameRect);

            // source selection
            DrawSourceSelection(sourceButtonRect);

            // selection area
            DrawSlotSelection(selectionRect);

            // current slots
            DrawSlotList(slotListRect);

            // bars
            if (CurrentLoadout != null)
            {
                Utility_Loadouts.DrawBar(weightBarRect, CurrentLoadout.Weight, StatDef.Named("CarryWeight").defaultBaseValue, "CR.Weight".Translate(), CurrentLoadout.GetWeightTip());
                Utility_Loadouts.DrawBar(bulkBarRect, CurrentLoadout.Bulk, StatDef.Named("CarryBulk").defaultBaseValue, "CR.Bulk".Translate(), CurrentLoadout.GetBulkTip());
            }

            // done!
        }
Beispiel #33
0
 public static void DoApparelScoreRawStatsHandlers(Pawn pawn, Apparel apparel, StatDef statDef, ref float num)
 {
     if (PawnCalcForApparel.ApparelScoreRawStatsHandlers != null)
         PawnCalcForApparel.ApparelScoreRawStatsHandlers(pawn, apparel, statDef, ref num);
 }