コード例 #1
0
ファイル: Utility.cs プロジェクト: RimWorldMod/CombatRealism
 /// <summary>
 /// For use with misc DamageWorker functions
 /// </summary>
 public static int GetAfterArmorDamage(Pawn pawn, int amountInt, BodyPartRecord part, DamageInfo dinfo)
 {
     bool flag = false;
     return Utility.GetAfterArmorDamage(pawn, amountInt, part, dinfo, false, ref flag);
 }
コード例 #2
0
 protected abstract void PostSuccessfulApply(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill);
コード例 #3
0
        public override void CompPostTick(ref float severityAdjustment)
        {
            base.CompPostTick(ref severityAdjustment);
            if (base.Pawn != null & base.parent != null)
            {
                if (!initialized)
                {
                    initialized = true;
                    this.Initialize();
                }
            }
            this.age++;
            if (!this.Pawn.DestroyedOrNull() && !this.Pawn.Dead)
            {
                if (age > lastRegen + regenRate)
                {
                    HealthUtility.AdjustSeverity(base.Pawn, this.Def, -0.3f);
                    this.lastRegen = this.age;
                    Pawn pawn = this.Pawn;

                    TM_MoteMaker.ThrowRegenMote(pawn.DrawPos, pawn.Map, 1f);
                    bool flag = TM_Calc.IsUndead(pawn);
                    if (!flag)
                    {
                        ModOptions.SettingsRef settingsRef = new ModOptions.SettingsRef();
                        int num = 1; // + ver.level;
                        if (settingsRef.AIHardMode && !pawn.IsColonist)
                        {
                            num = 2;
                        }

                        using (IEnumerator <BodyPartRecord> enumerator = pawn.health.hediffSet.GetInjuredParts().GetEnumerator())
                        {
                            while (enumerator.MoveNext())
                            {
                                BodyPartRecord rec   = enumerator.Current;
                                bool           flag2 = num > 0;

                                if (flag2)
                                {
                                    int num2 = 1; // + ver.level;
                                    if (settingsRef.AIHardMode && !pawn.IsColonist)
                                    {
                                        num2 = 2;
                                    }
                                    IEnumerable <Hediff_Injury> arg_BB_0 = pawn.health.hediffSet.GetHediffs <Hediff_Injury>();
                                    Func <Hediff_Injury, bool>  arg_BB_1;

                                    arg_BB_1 = ((Hediff_Injury injury) => injury.Part == rec);

                                    foreach (Hediff_Injury current in arg_BB_0.Where(arg_BB_1))
                                    {
                                        bool flag4 = num2 > 0;
                                        if (flag4)
                                        {
                                            bool flag5 = current.CanHealNaturally() && !current.IsPermanent();
                                            if (flag5)
                                            {
                                                if (!pawn.IsColonist)
                                                {
                                                    current.Heal(10f + (1.5f * hediffPwr));
                                                }
                                                else
                                                {
                                                    current.Heal(4f + (.5f * hediffPwr));
                                                }
                                                num--;
                                                num2--;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        TM_Action.DamageUndead(pawn, (2f + 1f * hediffPwr), null);
                    }
                }
            }
        }
コード例 #4
0
        /// <summary>Tries to apply the given hediff to the given pawn</summary>
        /// <param name="pawn">The pawn.</param>
        /// <param name="hediff">The hediff.</param>
        /// <param name="partsToAffect">The parts to affect.</param>
        /// <param name="canAffectAnyLivePart">if set to <c>true</c> [can affect any live part].</param>
        /// <param name="countToAffect">The count to affect.</param>
        /// <param name="outAddedHediffs">The out added hediffs.</param>
        /// <returns></returns>
        public static bool TryApply(Pawn pawn, HediffDef hediff, List <BodyPartDef> partsToAffect = null, bool canAffectAnyLivePart = false, int countToAffect = 1, List <Hediff> outAddedHediffs = null)
        {
            try
            {
                if (canAffectAnyLivePart || partsToAffect != null)
                {
                    bool result = false;
                    for (int i = 0; i < countToAffect; i++)
                    {
                        IEnumerable <BodyPartRecord> source = pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined, null, null);

                        if (partsToAffect != null)
                        {
                            source = from p in source
                                     where partsToAffect.Contains(p.def)
                                     select p;
                        }

                        if (canAffectAnyLivePart)
                        {
                            source = from p in source
                                     where p.def.alive
                                     select p;
                        }

                        source = from p in source
                                 where !pawn.health.hediffSet.HasHediff(hediff, p, false) &&
                                 !pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(p)
                                 select p;
                        _scratchList.Clear();
                        _scratchList.AddRange(source); //use a scratch list here, can't enumerate over IEnumerable more then once in all cases

                        if (_scratchList.Count == 0)
                        {
                            break;
                        }

                        BodyPartRecord partRecord = _scratchList[0];
                        Hediff         hediff2    = HediffMaker.MakeHediff(hediff, pawn, partRecord);
                        pawn.health.AddHediff(hediff2, null, null, null);
                        if (outAddedHediffs != null)
                        {
                            outAddedHediffs.Add(hediff2);
                        }

                        result = true;
                    }

                    return(result);
                }

                if (!pawn.health.hediffSet.HasHediff(hediff, false))
                {
                    Hediff hediff3 = HediffMaker.MakeHediff(hediff, pawn, null);
                    pawn.health.AddHediff(hediff3, null, null, null);
                    if (outAddedHediffs != null)
                    {
                        outAddedHediffs.Add(hediff3);
                    }

                    return(true);
                }

                return(false);
            }
            catch (Exception exception)
            {
                Log.Warning($"exception {exception.GetType().Name} caught while giving {hediff.defName} to {pawn.Name}, message follows \n{exception}");

                return(false);
            }
        }
コード例 #5
0
 public override string GetLabelWhenUsedOn(Pawn pawn, BodyPartRecord part)
 {
     return(recipe.label);
 }
コード例 #6
0
            private static bool Prefix(HediffDef diseaseDef, out HediffDef immunityCause, BodyPartRecord part, ref float __result, Pawn ___pawn)
            {
                immunityCause = null;
                var diseaseImmunity = ___pawn.GetPawnExtensions()?.diseaseImmunity;

                if (diseaseImmunity != null && diseaseImmunity.hediffs.Contains(diseaseDef) != diseaseImmunity.restrict)
                {
                    __result = 0f;
                    return(false);
                }

                return(true);
            }
コード例 #7
0
        public void DrawAddButton()
        {
            if (RectButtonAdd.Contains(Event.current.mousePosition))
            {
                GUI.color = Style.ColorButtonHighlight;
            }
            else
            {
                GUI.color = Style.ColorButton;
            }
            GUI.DrawTexture(RectButtonAdd, Textures.TextureButtonAdd);

            // Add button.
            if (Widgets.ButtonInvisible(RectButtonAdd, false))
            {
                CustomPawn customPawn = PrepareCarefully.Instance.State.CurrentPawn;

                Action addEntryAction = () => { };

                OptionsHealth  healthOptions             = PrepareCarefully.Instance.Providers.Health.GetOptions(customPawn);
                string         selectedHediffType        = this.selectedHediffType;
                RecipeDef      selectedRecipe            = null;
                InjuryOption   selectedInjury            = null;
                BodyPartRecord selectedBodyPart          = null;
                bool           bodyPartSelectionRequired = true;
                InjurySeverity selectedSeverity          = null;

                Dialog_Options <InjurySeverity> severityDialog;
                Dialog_Options <BodyPartRecord> bodyPartDialog;
                Dialog_Options <InjuryOption>   injuryOptionDialog;
                //Dialog_Options<RecipeDef> implantRecipeDialog;
                DialogManageImplants    manageImplantsDialog;
                Dialog_Options <string> hediffTypeDialog;

                ResetDisabledInjuryOptions(customPawn);

                Action addInjuryAction = () => {
                    if (bodyPartSelectionRequired)
                    {
                        AddInjuryToPawn(selectedInjury, selectedSeverity, selectedBodyPart);
                    }
                    else
                    {
                        if (selectedInjury.ValidParts != null && selectedInjury.ValidParts.Count > 0)
                        {
                            foreach (var p in selectedInjury.ValidParts)
                            {
                                var part = healthOptions.FindBodyPartsForDef(p).FirstOrDefault();
                                if (part != null)
                                {
                                    AddInjuryToPawn(selectedInjury, selectedSeverity, part.Record);
                                }
                                else
                                {
                                    Log.Warning("Could not find body part record for definition: " + p.defName);
                                }
                            }
                        }
                        else
                        {
                            AddInjuryToPawn(selectedInjury, selectedSeverity, null);
                        }
                    }
                };

                severityDialog = new Dialog_Options <InjurySeverity>(severityOptions)
                {
                    ConfirmButtonLabel = "EdB.PC.Common.Add".Translate(),
                    CancelButtonLabel  = "EdB.PC.Common.Cancel".Translate(),
                    HeaderLabel        = "EdB.PC.Panel.Health.SelectSeverity".Translate(),
                    NameFunc           = (InjurySeverity option) => {
                        if (!string.IsNullOrEmpty(option.Label))
                        {
                            return(option.Label);
                        }
                        else
                        {
                            return(selectedInjury.HediffDef.LabelCap);
                        }
                    },
                    SelectedFunc = (InjurySeverity option) => {
                        return(option == selectedSeverity);
                    },
                    SelectAction = (InjurySeverity option) => {
                        selectedSeverity = option;
                    },
                    ConfirmValidation = () => {
                        if (selectedSeverity == null)
                        {
                            return("EdB.PC.Error.MustSelectSeverity");
                        }
                        else
                        {
                            return(null);
                        }
                    },
                    CloseAction = () => {
                        addInjuryAction();
                    }
                };

                bodyPartDialog = new Dialog_Options <BodyPartRecord>(null)
                {
                    ConfirmButtonLabel = "EdB.PC.Common.Add".Translate(),
                    CancelButtonLabel  = "EdB.PC.Common.Cancel".Translate(),
                    HeaderLabel        = "EdB.PC.Dialog.BodyPart.Header".Translate(),
                    NameFunc           = (BodyPartRecord option) => {
                        return(option.LabelCap);
                    },
                    SelectedFunc = (BodyPartRecord option) => {
                        return(option == selectedBodyPart);
                    },
                    SelectAction = (BodyPartRecord option) => {
                        selectedBodyPart = option;
                    },
                    EnabledFunc = (BodyPartRecord option) => {
                        return(!disabledBodyParts.Contains(option));
                    },
                    ConfirmValidation = () => {
                        if (selectedBodyPart == null)
                        {
                            return("EdB.PC.Dialog.BodyPart.Error.Required");
                        }
                        else
                        {
                            return(null);
                        }
                    },
                    CloseAction = () => {
                        if (selectedHediffType == HediffTypeInjury)
                        {
                            if (this.severityOptions.Count > 1)
                            {
                                Find.WindowStack.Add(severityDialog);
                            }
                            else
                            {
                                if (severityOptions.Count > 0)
                                {
                                    selectedSeverity = this.severityOptions[0];
                                }
                                addInjuryAction();
                            }
                        }
                        else if (selectedHediffType == HediffTypeImplant)
                        {
                            ImplantAdded(new Implant(selectedBodyPart, selectedRecipe));
                        }
                    }
                };

                injuryOptionDialog = new Dialog_Options <InjuryOption>(healthOptions.InjuryOptions)
                {
                    ConfirmButtonLabel = "EdB.PC.Common.Next".Translate(),
                    CancelButtonLabel  = "EdB.PC.Common.Cancel".Translate(),
                    HeaderLabel        = "EdB.PC.Dialog.Injury.Header".Translate(),
                    NameFunc           = (InjuryOption option) => {
                        return(option.Label);
                    },
                    SelectedFunc = (InjuryOption option) => {
                        return(selectedInjury == option);
                    },
                    SelectAction = (InjuryOption option) => {
                        selectedInjury = option;
                        if (option.ValidParts == null && !option.WholeBody)
                        {
                            bodyPartSelectionRequired = true;
                        }
                        else
                        {
                            bodyPartSelectionRequired = false;
                        }
                    },
                    EnabledFunc = (InjuryOption option) => {
                        return(!disabledInjuryOptions.Contains(option));
                    },
                    ConfirmValidation = () => {
                        if (selectedInjury == null)
                        {
                            return("EdB.PC.Dialog.Injury.Error.Required");
                        }
                        else
                        {
                            return(null);
                        }
                    },
                    CloseAction = () => {
                        ResetSeverityOptions(selectedInjury);
                        if (bodyPartSelectionRequired)
                        {
                            bodyPartDialog.Options = healthOptions.BodyPartsForInjury(selectedInjury);
                            ResetDisabledBodyParts(bodyPartDialog.Options, customPawn);
                            Find.WindowStack.Add(bodyPartDialog);
                        }
                        else if (severityOptions.Count > 1)
                        {
                            Find.WindowStack.Add(severityDialog);
                        }
                        else
                        {
                            if (severityOptions.Count > 0)
                            {
                                selectedSeverity = this.severityOptions[0];
                            }
                            addInjuryAction();
                        }
                    }
                };

                hediffTypeDialog = new Dialog_Options <string>(new string[] { HediffTypeInjury, HediffTypeImplant })
                {
                    ConfirmButtonLabel = "EdB.PC.Common.Next".Translate(),
                    CancelButtonLabel  = "EdB.PC.Common.Cancel".Translate(),
                    NameFunc           = (string type) => {
                        return(("EdB.PC.Panel.Health." + type).Translate());
                    },
                    SelectedFunc = (string type) => {
                        return(selectedHediffType == type);
                    },
                    SelectAction = (string type) => {
                        selectedHediffType = type;
                    },
                    ConfirmValidation = () => {
                        if (selectedHediffType == null)
                        {
                            return("EdB.PC.Panel.Health.Error.MustSelectOption");
                        }
                        else
                        {
                            return(null);
                        }
                    },
                    CloseAction = () => {
                        this.selectedHediffType = selectedHediffType;
                        if (selectedHediffType == HediffTypeInjury)
                        {
                            Find.WindowStack.Add(injuryOptionDialog);
                        }
                        else
                        {
                            ResetDisabledImplantRecipes(customPawn);
                            manageImplantsDialog = new DialogManageImplants(customPawn)
                            {
                                HeaderLabel = "EdB.PC.Dialog.Implant.Header".Translate(),
                                CloseAction = (List <Implant> implants) => {
                                    ApplyImplantsToPawn(customPawn, implants);
                                }
                            };
                            Find.WindowStack.Add(manageImplantsDialog);
                        }
                    }
                };
                Find.WindowStack.Add(hediffTypeDialog);
            }
        }
コード例 #8
0
 private static float GetListPriority([CanBeNull] BodyPartRecord record) =>
 record == null ? 9999999f : (float)record.height * 10000 + record.coverageAbsWithChildren;
コード例 #9
0
        // Token: 0x0600001F RID: 31 RVA: 0x000033AC File Offset: 0x000015AC
        internal static bool HediffEffect(HediffDef hediffdef, float SeverityToApply, Pawn pawn, BodyPartRecord part,
                                          out bool immune)
        {
            immune = false;
            if (pawn.RaceProps.IsMechanoid || hediffdef == null)
            {
                return(false);
            }

            if (!ImmuneTo(pawn, hediffdef, out _))
            {
                if (pawn.health.WouldDieAfterAddingHediff(hediffdef, part, SeverityToApply))
                {
                    return(false);
                }

                var    health = pawn.health;
                Hediff hediff;
                if (health == null)
                {
                    hediff = null;
                }
                else
                {
                    var hediffSet = health.hediffSet;
                    hediff = hediffSet?.GetFirstHediffOfDef(hediffdef);
                }

                var hashediff = hediff;
                if (hashediff != null)
                {
                    hashediff.Severity += SeverityToApply;
                    return(true);
                }

                var addhediff = HediffMaker.MakeHediff(hediffdef, pawn, part);
                addhediff.Severity = SeverityToApply;
                pawn.health.AddHediff(addhediff, part);
                return(true);
            }

            immune = true;

            return(false);
        }
コード例 #10
0
        public static void DamageInfosToApply_ForceWeapon_Postfix(ref Verb_MeleeAttackDamage __instance, LocalTargetInfo target, ref IEnumerable <DamageInfo> __result)
        {
            if (__instance.EquipmentSource != null)
            {
                if (!__instance.EquipmentSource.AllComps.NullOrEmpty())
                {
                    if (__instance.EquipmentSource.GetComp <CompWeapon_MeleeSpecialRules>() != null)
                    {
                        if (__instance.EquipmentSource.GetComp <CompWeapon_MeleeSpecialRules>() is CompWeapon_MeleeSpecialRules WeaponRules)
                        {
                            if (AMSettings.Instance.AllowForceWeaponEffect)
                            {
                                bool ForceAttack = __result.Any(x => x.Def.forceWeapon());
                                if (WeaponRules.ForceWeapon && ForceAttack && __instance.CasterPawn is Pawn Caster)
                                {
                                    bool casterPsychiclySensitive = Caster.RaceProps.Humanlike ? Caster.story.traits.HasTrait(TraitDefOf.PsychicSensitivity) : false;
                                    bool Activate = false;
                                    if ((casterPsychiclySensitive || !WeaponRules.ForceEffectRequiresPsyker) && target.Thing.def.category == ThingCategory.Pawn && target.Thing is Pawn Victim)
                                    {
                                        int casterPsychiclySensitiveDegree = casterPsychiclySensitive ? Caster.story.traits.DegreeOfTrait(TraitDefOf.PsychicSensitivity) : 0;
                                        if ((casterPsychiclySensitiveDegree >= 1 || !WeaponRules.ForceEffectRequiresPsyker))
                                        {
                                            float?casterPsychicSensitivity = Caster.GetStatValue(StatDefOf.PsychicSensitivity, true) * 100f;
                                            bool  targetPsychiclySensitive = Victim.RaceProps.Humanlike ? Victim.story.traits.HasTrait(TraitDefOf.PsychicSensitivity) : false;
                                            float?targetPsychicSensitivity = Victim.GetStatValue(StatDefOf.PsychicSensitivity, true) * 100f;
                                            if (targetPsychiclySensitive == true)
                                            {
                                                int targetPsychiclySensitiveDegree = Victim.story.traits.DegreeOfTrait(TraitDefOf.PsychicSensitivity);
                                                if (targetPsychiclySensitiveDegree == -1)
                                                {
                                                    targetPsychicSensitivity = Victim.def.statBases.GetStatValueFromList(StatDefOf.PsychicSensitivity, 1.5f) * 100f;
                                                }
                                                else if (targetPsychiclySensitiveDegree == -2)
                                                {
                                                    targetPsychicSensitivity = Victim.def.statBases.GetStatValueFromList(StatDefOf.PsychicSensitivity, 2f) * 100f;
                                                }
                                            }
                                            else
                                            {
                                                int targetPsychiclySensitiveDegree = 0;
                                            }
                                            if (__result.Any(x => x.Def.forceWeapon()))
                                            {
                                                Log.Message(string.Format("1"));
                                                float CasterMood = Caster.needs.mood.CurLevelPercentage;
                                                float VictimMood = Victim?.needs?.mood != null ? Victim.needs.mood.CurLevelPercentage : 1;
                                                foreach (var item in __result.Where(x => x.Def.forceWeapon()))
                                                {
                                                    float?casterRoll = Rand.Range(0, (int)casterPsychicSensitivity) * CasterMood;
                                                    float?targetRoll = Rand.Range(0, (int)targetPsychicSensitivity) * VictimMood;
                                                    casterRoll = (casterRoll - (targetPsychicSensitivity / 2));
                                                    Activate   = (casterRoll > targetRoll);
                                                    Log.Message(string.Format("Caster:{0}, Victim:{1}", casterRoll, targetRoll));
                                                    if (Activate)
                                                    {
                                                        DamageDef        damDef           = WeaponRules.ForceWeaponEffect;
                                                        float            damAmount        = __instance.verbProps.AdjustedMeleeDamageAmount(__instance, __instance.CasterPawn);
                                                        float            armorPenetration = __instance.verbProps.AdjustedArmorPenetration(__instance, __instance.CasterPawn);
                                                        BodyPartRecord   bodyPart         = Rand.Chance(0.05f) && Victim.RaceProps.body.AllParts.Any(x => x.def.defName.Contains("Brain")) ? Victim.RaceProps.body.AllParts.Find(x => x.def.defName.Contains("Brain")) : null;
                                                        BodyPartGroupDef bodyPartGroupDef = null;
                                                        HediffDef        hediffDef        = WeaponRules.ForceWeaponHediff;
                                                        damAmount = Rand.Range(damAmount * 0.1f, damAmount * 0.5f);
                                                        ThingDef   source    = __instance.EquipmentSource.def;
                                                        Thing      caster    = __instance.caster;
                                                        Vector3    direction = (target.Thing.Position - __instance.CasterPawn.Position).ToVector3();
                                                        float      num       = damAmount;
                                                        float      num2      = armorPenetration;
                                                        DamageInfo mainDinfo = new DamageInfo(damDef, num, num2, -1f, caster, bodyPart, source, DamageInfo.SourceCategory.ThingOrUnknown, null);
                                                        mainDinfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside);
                                                        mainDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
                                                        mainDinfo.SetWeaponHediff(hediffDef);
                                                        mainDinfo.SetAngle(direction);
                                                        Victim.TakeDamage(mainDinfo);
                                                        Map      map             = Caster.Map;
                                                        IntVec3  position        = target.Cell;
                                                        Map      map2            = map;
                                                        float    explosionRadius = 0f;
                                                        Thing    launcher        = __instance.EquipmentSource;
                                                        SoundDef soundExplode    = WeaponRules.ForceWeaponTriggerSound;
                                                        Thing    thing           = target.Thing;
                                                        GenExplosion.DoExplosion(position, map2, explosionRadius, damDef, launcher, (int)damAmount, armorPenetration, soundExplode, source, null, thing, null, 0f, 0, false, null, 0, 0, 0, false);
                                                        float KillChance = WeaponRules.ForceWeaponKillChance;
                                                        if (KillChance != 0)
                                                        {
                                                            float KillRoll = Rand.Range(0, 100);
                                                            if (Rand.Chance(WeaponRules.ForceWeaponKillChance))
                                                            {
                                                                string msg = string.Format("{0} was slain by a force strike", target.Thing.LabelCap);
                                                                target.Thing.Kill(mainDinfo);
                                                                if (target.Thing.Faction == Faction.OfPlayer)
                                                                {
                                                                    Messages.Message(msg, MessageTypeDefOf.PawnDeath);
                                                                }
                                                            }
                                                        }

                                                        /*
                                                         */
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #11
0
        private void AddPartMutations()
        {
            var mutationsAdded = 0;

            while (_curIndex < _checkList.Count)
            {
                BodyPartRecord part = _checkList[_curIndex];
                if (!pawn.RaceProps.body.AllParts.Contains(part))
                {
                    //if the pawn's race changes the mutation order may no longer be valid
                    //need to reset it and try again later
                    break;
                }

                var lst = _scratchDict.TryGetValue(part.def);

                if (lst == null) //end check early if there are no parts that can be added
                {
                    _curIndex++;
                    _curMutationIndex = 0;
                    continue;
                }
                //make sure we try each mutation per part

                while (_curMutationIndex < lst.Count)
                {
                    var mutation = lst[_curMutationIndex];

                    //check if the mutation can actually be added
                    if (!mutation.mutation.CanApplyMutations(pawn, part))
                    {
                        _curMutationIndex++;
                        continue;
                    }
                    else if (Rand.Value < mutation.addChance)
                    {
                        var result = MutationUtilities.AddMutation(pawn, mutation.mutation, part);
                        if (result) //make sure the mutation was actually added before doing this
                        {
                            var mutagen = def.GetMutagenDef();
                            mutagen.TryApplyAspects(pawn);
                            mutationsAdded++;
                        }
                    }
                    else if (mutation.blocks)
                    {
                        return; //wait here until the blocking mutation is added
                    }

                    _curMutationIndex++;

                    //check if we added enough mutations to break early
                    if (mutationsAdded >= MinMutationsPerCheck)
                    {
                        goto loopBreak;//break both loops
                    }
                }

                _curIndex++;           //increment after so mutations can 'block'
                _curMutationIndex = 0; //reset the mutation index every time we move up a part

                //check if we have added enough mutations to end the loop early
                if (mutationsAdded >= MinMutationsPerCheck)
                {
                    break;
                }
            }

loopBreak:  //label so we can break both loops

            if (mutationsAdded > 0)
            {
                OnMutationsAdded(mutationsAdded);
            }
        }
コード例 #12
0
 public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill)
 {
     base.ApplyOnPawn(pawn, part, billDoer, ingredients, bill);
 }
コード例 #13
0
 public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill)
 {
     HealthUtility.AdjustSeverity(pawn, HediffDefOf.BloodLoss, -0.20f);
 }
コード例 #14
0
        /// <summary>
        /// Calculates damage through armor, depending on damage type, target and natural resistance. Also calculates deflection and adjusts damage type and impacted body part accordingly.
        /// </summary>
        /// <param name="originalDinfo">The pre-armor damage info</param>
        /// <param name="pawn">The damaged pawn</param>
        /// <param name="hitPart">The pawn's body part that has been hit</param>
        /// <param name="armorReduced">Whether sharp damage was deflected by armor</param>
        /// <param name="shieldAbsorbed">Returns true if attack did not penetrate pawn's melee shield</param>
        /// <param name="armorDeflected">Whether the attack was completely absorbed by the armor</param>
        /// <returns>If shot is deflected returns a new dinfo cloned from the original with damage amount, Def and ForceHitPart adjusted for deflection, otherwise a clone with only the damage adjusted</returns>
        public static DamageInfo GetAfterArmorDamage(DamageInfo originalDinfo, Pawn pawn, BodyPartRecord hitPart, out bool armorDeflected, out bool armorReduced, out bool shieldAbsorbed)
        {
            shieldAbsorbed = false;
            armorDeflected = false;
            armorReduced   = false;

            if (originalDinfo.Def.armorCategory == null ||
                (!(originalDinfo.Weapon?.projectile is ProjectilePropertiesCE) &&
                 Verb_MeleeAttackCE.LastAttackVerb == null &&
                 originalDinfo.Weapon == null &&
                 originalDinfo.Instigator == null))
            {
                return(originalDinfo);
            }

            var  dinfo           = new DamageInfo(originalDinfo);
            var  dmgAmount       = dinfo.Amount;
            var  involveArmor    = dinfo.Def.harmAllLayersUntilOutside || hitPart.depth == BodyPartDepth.Outside;
            bool isAmbientDamage = dinfo.IsAmbientDamage();

            // In case of ambient damage (fire, electricity) we apply a percentage reduction formula based on the sum of all applicable armor
            if (isAmbientDamage)
            {
                dinfo.SetAmount(Mathf.CeilToInt(GetAmbientPostArmorDamage(dmgAmount, originalDinfo.Def.armorCategory.armorRatingStat, pawn, hitPart)));
                armorDeflected = dinfo.Amount <= 0;
                return(dinfo);
            }

            var penAmount = originalDinfo.ArmorPenetrationInt; //GetPenetrationValue(originalDinfo);

            // Apply worn armor
            if (involveArmor && pawn.apparel != null && !pawn.apparel.WornApparel.NullOrEmpty())
            {
                var apparel = pawn.apparel.WornApparel;

                // Check for shields first
                var shield = apparel.FirstOrDefault(x => x is Apparel_Shield);
                if (shield != null)
                {
                    // Determine whether the hit is blocked by the shield
                    var blockedByShield = false;
                    if (!(dinfo.Weapon?.IsMeleeWeapon ?? false))
                    {
                        var shieldDef = shield.def.GetModExtension <ShieldDefExtension>();
                        if (shieldDef == null)
                        {
                            Log.ErrorOnce("Combat Extended :: shield " + shield.def.ToString() + " is Apparel_Shield but has no ShieldDefExtension", shield.def.GetHashCode() + 12748102);
                        }
                        else
                        {
                            var hasCoverage = shieldDef.PartIsCoveredByShield(hitPart, pawn);
                            if (hasCoverage)
                            {
                                // Right arm is vulnerable during warmup/attack/cooldown
                                blockedByShield = !((pawn.stances?.curStance as Stance_Busy)?.verb != null && hitPart.IsInGroup(CE_BodyPartGroupDefOf.RightArm));
                            }
                        }
                    }
                    // Try to penetrate the shield
                    if (blockedByShield && !TryPenetrateArmor(dinfo.Def, shield.GetStatValue(dinfo.Def.armorCategory.armorRatingStat), ref penAmount, ref dmgAmount, shield))
                    {
                        shieldAbsorbed = true;
                        armorDeflected = true;
                        dinfo.SetAmount(0);

                        // Apply secondary damage to shield
                        if (dinfo.Weapon?.projectile is ProjectilePropertiesCE props && !props.secondaryDamage.NullOrEmpty())
                        {
                            foreach (var sec in props.secondaryDamage)
                            {
                                if (shield.Destroyed || !Rand.Chance(sec.chance))
                                {
                                    break;
                                }
                                var secDinfo = sec.GetDinfo();
                                var pen      = secDinfo.ArmorPenetrationInt; //GetPenetrationValue(originalDinfo);
                                var dmg      = (float)secDinfo.Amount;
                                TryPenetrateArmor(secDinfo.Def, shield.GetStatValue(secDinfo.Def.armorCategory.armorRatingStat), ref pen, ref dmg, shield);
                            }
                        }

                        return(dinfo);
                    }
                }

                // Apparel is arranged in draw order, we run through reverse to go from Shell -> OnSkin
                for (var i = apparel.Count - 1; i >= 0; i--)
                {
                    var app = apparel[i];

                    if (app != null &&
                        app.def.apparel.CoversBodyPart(hitPart) &&
                        !TryPenetrateArmor(dinfo.Def, app.GetStatValue(dinfo.Def.armorCategory.armorRatingStat), ref penAmount, ref dmgAmount, app))
                    {
                        // Hit was deflected, convert damage type
                        //armorReduced = true;
                        dinfo = GetDeflectDamageInfo(dinfo, hitPart, ref dmgAmount, ref penAmount);
                        if (app == apparel.ElementAtOrDefault(i)) //Check whether the "deflecting" apparel is still in the WornApparel - if not, the next loop checks again and errors out because the index is out of range
                        {
                            i++;                                  // We apply this piece of apparel twice on conversion, this means we can't use deflection on Blunt or else we get an infinite loop of eternal deflection
                        }
                    }
                    if (dmgAmount <= 0)
                    {
                        dinfo.SetAmount(0);
                        armorDeflected = true;
                        return(dinfo);
                    }
                }
            }

            // Apply natural armor
            var partsToHit = new List <BodyPartRecord>()
            {
                hitPart
            };

            if (dinfo.Def.harmAllLayersUntilOutside)
            {
                var curPart = hitPart;
                while (curPart.parent != null && curPart.depth == BodyPartDepth.Inside)
                {
                    curPart = curPart.parent;
                    partsToHit.Add(curPart);
                }
            }

            var isSharp         = dinfo.Def.armorCategory.armorRatingStat == StatDefOf.ArmorRating_Sharp;
            var partDensityStat = isSharp
                ? CE_StatDefOf.BodyPartSharpArmor
                : CE_StatDefOf.BodyPartBluntArmor;
            var partDensity = pawn.GetStatValue(partDensityStat);   // How much armor is provided by sheer meat

            for (var i = partsToHit.Count - 1; i >= 0; i--)
            {
                var curPart        = partsToHit[i];
                var coveredByArmor = curPart.IsInGroup(CE_BodyPartGroupDefOf.CoveredByNaturalArmor);
                var armorAmount    = coveredByArmor ? pawn.GetStatValue(dinfo.Def.armorCategory.armorRatingStat) : 0;

                // Only apply damage reduction when penetrating armored body parts
                if (!TryPenetrateArmor(dinfo.Def, armorAmount, ref penAmount, ref dmgAmount, null, partDensity))
                {
                    dinfo.SetHitPart(curPart);
                    if (isSharp && coveredByArmor)
                    {
                        // For Mechanoid natural armor, apply deflection and blunt armor
                        dinfo = GetDeflectDamageInfo(dinfo, curPart, ref dmgAmount, ref penAmount);

                        // Fetch armor rating stat again in case of deflection conversion to blunt
                        TryPenetrateArmor(dinfo.Def, pawn.GetStatValue(dinfo.Def.armorCategory.armorRatingStat), ref penAmount, ref dmgAmount, null, partDensity);
                    }
                    break;
                }
                if (dmgAmount <= 0)
                {
                    dinfo.SetAmount(0);
                    armorDeflected = true;
                    return(dinfo);
                }
            }

            // Applies blunt damage from partial penetrations.
            if (isSharp && (dinfo.Amount > Mathf.CeilToInt(dmgAmount)))
            {
                pawn.TakeDamage(GetDeflectDamageInfo(dinfo, hitPart, ref dmgAmount, ref penAmount, true));
            }
            // Return damage info.
            dinfo.SetAmount(Mathf.CeilToInt(dmgAmount));
            return(dinfo);
        }
コード例 #15
0
 public void ApplyHediffDefOn( Pawn pawn, HediffDef hediffDef, BodyPartRecord bodyPartRecord )
 {
     if(
         ( pawn == null )||
         ( hediffDef == null )||
         ( bodyPartRecord == null )
     )
     {
         return;
     }
     if( pawn.health.hediffSet.HasHediff( hediffDef, bodyPartRecord ) )
     {
         return;
     }
     pawn.health.AddHediff( hediffDef, bodyPartRecord );
 }
コード例 #16
0
        public override void CompPostTick(ref float severityAdjustment)
        {
            base.CompPostTick(ref severityAdjustment);
            bool flag = base.Pawn != null;

            if (flag)
            {
                if (initializing)
                {
                    initializing = false;
                    this.Initialize();
                }
            }
            bool flag4 = Find.TickManager.TicksGame % 600 == 0;

            if (flag4)
            {
                Pawn pawn = base.Pawn;
                int  num  = 1;
                int  num2 = 1;

                using (IEnumerator <BodyPartRecord> enumerator = pawn.health.hediffSet.GetInjuredParts().GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        BodyPartRecord rec   = enumerator.Current;
                        bool           flag2 = num > 0;

                        if (flag2)
                        {
                            IEnumerable <Hediff_Injury> arg_BB_0 = pawn.health.hediffSet.GetHediffs <Hediff_Injury>();
                            Func <Hediff_Injury, bool>  arg_BB_1;

                            arg_BB_1 = ((Hediff_Injury injury) => injury.Part == rec);

                            foreach (Hediff_Injury current in arg_BB_0.Where(arg_BB_1))
                            {
                                bool flag3 = num2 > 0;
                                if (flag3)
                                {
                                    bool flag5 = current.CanHealNaturally() && !current.IsPermanent();
                                    if (flag5)
                                    {
                                        current.Heal(1.0f + this.parent.Severity / 3f);
                                        num--;
                                        num2--;
                                    }
                                    else
                                    {
                                        current.Heal(.2f);
                                        num--;
                                        num2--;
                                    }
                                }
                            }
                        }
                    }
                }
                if (this.bonderPawn != null && !this.bonderPawn.Destroyed && !this.bonderPawn.Dead)
                {
                    RefreshBond();
                    UpdateBond();
                }
                else
                {
                    this.Pawn.health.RemoveHediff(this.Pawn.health.hediffSet.GetFirstHediffOfDef(this.parent.def));
                    if (this.Pawn.def.thingClass == typeof(TMPawnSummoned))
                    {
                        if (this.Pawn.Map != null)
                        {
                            FleckMaker.ThrowSmoke(this.Pawn.DrawPos, this.Pawn.Map, 1f);
                            TM_MoteMaker.ThrowGenericMote(TorannMagicDefOf.Mote_Ghost, this.Pawn.DrawPos, this.Pawn.Map, 1.3f, .25f, .1f, .45f, 0, Rand.Range(1f, 2f), 0, 0);
                        }
                        this.Pawn.Destroy(DestroyMode.Vanish);
                    }
                    //this.Pawn.SetFactionDirect(null);
                }
            }
        }
コード例 #17
0
        /// <summary>
        /// Creates a new DamageInfo from a deflected one. Changes damage type to Blunt and hit part to the outermost parent of the originally hit part.
        /// </summary>
        /// <param name="dinfo">The dinfo that was deflected</param>
        /// <param name="hitPart">The originally hit part</param>
        /// <param name="partialPen">Is this is supposed to be a partial penetration</param>
        /// <returns>DamageInfo copied from dinfo with Def and forceHitPart adjusted</returns>
        private static DamageInfo GetDeflectDamageInfo(DamageInfo dinfo, BodyPartRecord hitPart, ref float dmgAmount, ref float penAmount, bool partialPen = false)
        {
            if (dinfo.Def.armorCategory != DamageArmorCategoryDefOf.Sharp)
            {
                if (!partialPen)
                {
                    dmgAmount = 0;
                    penAmount = 0;
                }
                dinfo.SetAmount(0);
                return(dinfo);
            }

            //Creating local variables as we don't want to edit the pass-by-reference parameters in the case of partial penetrations.
            float localDmgAmount = dmgAmount;
            float localPenAmount = penAmount;

            //Calculating blunt damage from sharp damage: if it's a deflected sharp attack, then the penetration amount is directly localPenAmount.
            //However, if it's a partially-penetrating sharp attack, then we're using the blocked values of penetration amount and damage amount instead
            //and because localPenAmount is the sharp attack's remaining penetration amount and localDmgAmount is the sharp attack's remaining damage amount,
            //we have to take that amount away from the base penetration amount and damage amount.
            float penMulti = (partialPen ? ((dinfo.ArmorPenetrationInt - localPenAmount) * (dinfo.Amount - Mathf.CeilToInt(localDmgAmount)) / dinfo.Amount) : localPenAmount) / dinfo.ArmorPenetrationInt;

            if (dinfo.Weapon?.projectile is ProjectilePropertiesCE projectile)
            {
                localPenAmount = projectile.armorPenetrationBlunt * penMulti;
            }
            else if (dinfo.Instigator.def.thingClass == typeof(Building_TrapDamager))
            {
                //Temporarily deriving spike trap blunt AP based on their vanilla stats, just so they're not entirely broken
                //TODO proper integration
                var trapAP = dinfo.Instigator.GetStatValue(StatDefOf.TrapMeleeDamage, true) * SpikeTrapAPModifierBlunt;
                localPenAmount = trapAP * penMulti;
            }
            else
            {
                if (Verb_MeleeAttackCE.LastAttackVerb != null)
                {
                    localPenAmount = Verb_MeleeAttackCE.LastAttackVerb.ArmorPenetrationBlunt;
                }
                else
                {
                    //LastAttackVerb is already checked in GetAfterArmorDamage(). Only known case of code arriving here is with the ancient soldiers
                    //spawned at the start of the game: their wounds are usually applied with Weapon==null and Instigator==null, so they skip CE's armor system,
                    //but on rare occasions, one of the soldiers gets Bite injuries with with Weapon==null and the instigator set as *himself*.
                    //Warning message below to identify any other situations where this might be happening. -LX7
                    Log.Warning($"[CE] Deflection for Instigator:{dinfo.Instigator} Target:{dinfo.IntendedTarget} DamageDef:{dinfo.Def} Weapon:{dinfo.Weapon} has null verb, overriding AP.");
                    localPenAmount = 50;
                }
            }
            localDmgAmount = Mathf.Pow(localPenAmount * 10000, 1 / 3f) / 10;
            var newDinfo = new DamageInfo(DamageDefOf.Blunt,
                                          localDmgAmount,
                                          localPenAmount,
                                          dinfo.Angle,
                                          dinfo.Instigator,
                                          GetOuterMostParent(hitPart),
                                          partialPen ? null : dinfo.Weapon); //To not apply the secondary damage twice on partial penetrations.

            newDinfo.SetBodyRegion(dinfo.Height, dinfo.Depth);
            newDinfo.SetWeaponBodyPartGroup(dinfo.WeaponBodyPartGroup);
            newDinfo.SetWeaponHediff(dinfo.WeaponLinkedHediff);
            newDinfo.SetInstantPermanentInjury(dinfo.InstantPermanentInjury);
            newDinfo.SetAllowDamagePropagation(dinfo.AllowDamagePropagation);
            if (!partialPen) //If it was a deflect, update dmgAmount and penAmount.
            {
                dmgAmount = localDmgAmount;
                penAmount = localPenAmount;
            }
            return(newDinfo);
        }
コード例 #18
0
 public static bool IsCleanAndDroppable(Pawn pawn, BodyPartRecord part)
 {
     return(!pawn.RaceProps.Animal && !pawn.RaceProps.IsMechanoid && part.def.spawnThingOnRemoved != null &&
            !pawn.health.hediffSet.hediffs.Any(x => x.Part == part));
 }
コード例 #19
0
        public override void CompPostTick(ref float severityAdjustment)
        {
            base.CompPostTick(ref severityAdjustment);
            bool flag = base.Pawn != null;

            if (flag)
            {
                if (initializing)
                {
                    initializing = false;
                    this.Initialize();
                }
            }


            if (Find.TickManager.TicksGame % 16 == 0)
            {
                IEnumerable <Hediff> hdEnum = this.Pawn.health.hediffSet.GetHediffs <Hediff>();
                foreach (Hediff hd in hdEnum)
                {
                    if (hd.def.defName == "SpaceHypoxia")
                    {
                        this.Pawn.health.RemoveHediff(hd);
                        break;
                    }
                }
            }

            bool flag4 = Find.TickManager.TicksGame % 600 == 0;

            if (flag4)
            {
                List <Need> needs = base.Pawn.needs.AllNeeds;
                for (int i = 0; i < needs.Count; i++)
                {
                    if (needs[i].def.defName != "Joy" && needs[i].def.defName != "Mood" && needs[i].def.defName != "TM_Mana" && needs[i].def.defName != "TM_Stamina" && needs[i].def.defName != "ROMV_Blood")
                    {
                        needs[i].CurLevel = needs[i].MaxLevel;
                    }
                }
                Pawn pawn = base.Pawn;
                int  num  = 1;
                int  num2 = 1;
                using (IEnumerator <BodyPartRecord> enumerator = pawn.health.hediffSet.GetInjuredParts().GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        BodyPartRecord rec   = enumerator.Current;
                        bool           flag2 = num > 0;

                        if (flag2)
                        {
                            IEnumerable <Hediff_Injury> arg_BB_0 = pawn.health.hediffSet.GetHediffs <Hediff_Injury>();
                            Func <Hediff_Injury, bool>  arg_BB_1;

                            arg_BB_1 = (Hediff_Injury injury) => injury.Part == rec;

                            foreach (Hediff_Injury current in arg_BB_0.Where(arg_BB_1))
                            {
                                bool flag3 = num2 > 0;
                                if (flag3)
                                {
                                    bool flag5 = current.CanHealNaturally() && !current.IsPermanent();
                                    if (flag5)
                                    {
                                        current.Heal(2.0f);
                                        num--;
                                        num2--;
                                    }
                                    else
                                    {
                                        current.Heal(1.0f);
                                        num--;
                                        num2--;
                                    }
                                }
                            }
                        }
                    }
                }

                using (IEnumerator <Hediff> enumerator = pawn.health.hediffSet.GetHediffsTendable().GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        Hediff rec = enumerator.Current;
                        if (rec.TendableNow()) // && !currentTendable.IsPermanent()
                        {
                            rec.Tended(1, 1);
                        }
                    }
                }

                using (IEnumerator <Hediff> enumerator = pawn.health.hediffSet.GetHediffs <Hediff>().GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        Hediff rec = enumerator.Current;
                        if (!rec.IsPermanent())
                        {
                            if (rec.def.defName == "Cataract" || rec.def.defName == "HearingLoss" || rec.def.defName.Contains("ToxicBuildup"))
                            {
                                pawn.health.RemoveHediff(rec);
                            }
                            if (rec.def.defName == "Blindness" || rec.def.defName.Contains("Asthma") || rec.def.defName == "Cirrhosis" || rec.def.defName == "ChemicalDamageModerate")
                            {
                                pawn.health.RemoveHediff(rec);
                            }
                            if (rec.def.defName == "Frail" || rec.def.defName == "BadBack" || rec.def.defName.Contains("Carcinoma") || rec.def.defName == "ChemicalDamageSevere")
                            {
                                pawn.health.RemoveHediff(rec);
                            }
                            if (rec.def.defName.Contains("Alzheimers") || rec.def.defName == "Dementia" || rec.def.defName.Contains("HeartArteryBlockage") || rec.def.defName == "CatatonicBreakdown")
                            {
                                pawn.health.RemoveHediff(rec);
                            }
                        }
                        if (rec.def.makesSickThought)
                        {
                            pawn.health.RemoveHediff(rec);
                        }
                    }
                }
            }
        }
コード例 #20
0
            /// <summary>
            /// Checks if the given source mutation blocks the given otherMutation being added at the given part
            /// </summary>
            /// <param name="sourceMutation">The source mutation.</param>
            /// <param name="otherMutation">The other mutation.</param>
            /// <param name="addPart">The add part.</param>
            /// <returns></returns>
            public bool Blocks([NotNull] Hediff_AddedMutation sourceMutation, [NotNull] MutationDef otherMutation, [CanBeNull] BodyPartRecord addPart)
            {
                if (sourceMutation == null)
                {
                    throw new ArgumentNullException(nameof(sourceMutation));
                }
                if (otherMutation == null)
                {
                    throw new ArgumentNullException(nameof(otherMutation));
                }

                if (otherMutation != mutation)
                {
                    return(false);
                }

                return(blockOnAnyPart || addPart == sourceMutation.Part);
            }
コード例 #21
0
 public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill)
 {
     CompUseEffect_HealCPUSerum.Apply(pawn);
 }
コード例 #22
0
        private static void CheckPart(List <BodyPartRecord> body, Hediff hediff, [CanBeNull] CompFace face,
                                      [CanBeNull]                                           CompBodyAnimator anim, bool missing)
        {
            if (body.NullOrEmpty() || hediff.def == null)
            {
                Log.Message("Body list or hediff.def is null or empty");
                return;
            }

            if (!hediff.Visible)
            {
                return;
            }

            BodyPartRecord leftEye  = body.Find(x => x.customLabel == "left eye");
            BodyPartRecord rightEye = body.Find(x => x.customLabel == "right eye");
            BodyPartRecord jaw      = body.Find(x => x.def == BodyPartDefOf.Jaw);


            //BodyPartRecord leftArm = body.Find(x => x.def == BodyPartDefOf.LeftArm);
            //BodyPartRecord rightArm = body.Find(x => x.def == DefDatabase<BodyPartDef>.GetNamed("RightShoulder"));
            BodyPartRecord leftHand  = body.Find(x => x.customLabel == "left hand");
            BodyPartRecord rightHand = body.Find(x => x.customLabel == "right hand");

            BodyPartRecord leftFoot  = body.Find(x => x.customLabel == "left foot");
            BodyPartRecord rightFoot = body.Find(x => x.customLabel == "right foot");

            BodyPartRecord leftArm  = body.Find(x => x.customLabel == "left arm");
            BodyPartRecord rightArm = body.Find(x => x.customLabel == "right arm");

            BodyPartRecord leftLeg  = body.Find(x => x.customLabel == "left foot");
            BodyPartRecord rightLeg = body.Find(x => x.customLabel == "right foot");

            if (missing)
            {
                CheckMissingParts(new BodyProps(hediff, face, anim, leftEye, rightEye, leftHand, rightHand, leftFoot,
                                                rightFoot));
                return;
            }

            // Missing parts first, hands and feet can be replaced by arms/legs
            //  Log.Message("Checking missing parts.");
            AddedBodyPartProps addedPartProps = hediff.def?.addedPartProps;

            if (addedPartProps == null)
            {
                //    Log.Message("No added parts found.");
                return;
            }

            if (hediff.def?.defName == null)
            {
                return;
            }

            //  Log.Message("Checking face for added parts.");
            if (anim != null && anim.Pawn.RaceProps.Humanlike && face != null)
            {
                CheckFaceForAddedParts(hediff, face, leftEye, rightEye, jaw);
            }

            //  Log.Message("Checking body for added parts.");

            CheckBodyForAddedParts(hediff, anim, leftHand, leftArm, rightHand, rightArm, leftFoot, leftLeg, rightFoot,
                                   rightLeg);
        }
コード例 #23
0
 public override bool IsViolationOnPawn(Pawn pawn, BodyPartRecord part, Faction billDoerFaction)
 {
     return(false);
 }
コード例 #24
0
 public BodyProps(Hediff hediff, CompFace face, CompBodyAnimator anim, BodyPartRecord leftEye, BodyPartRecord rightEye, BodyPartRecord leftHand, BodyPartRecord rightHand, BodyPartRecord leftFoot, BodyPartRecord rightFoot)
 {
     this._hediff    = hediff;
     this._face      = face;
     this._anim      = anim;
     this._leftEye   = leftEye;
     this._rightEye  = rightEye;
     this._leftHand  = leftHand;
     this._rightHand = rightHand;
     this._leftFoot  = leftFoot;
     this._rightFoot = rightFoot;
 }
コード例 #25
0
 protected virtual void HackingFailEvent(Pawn hacker, Pawn hackee, BodyPartRecord part, System.Random r)
 {
 }
コード例 #26
0
        private static void CheckBodyForAddedParts(Hediff hediff, CompBodyAnimator anim, BodyPartRecord leftHand, BodyPartRecord leftArm,
                                                   BodyPartRecord rightHand, BodyPartRecord rightArm, BodyPartRecord leftFoot, BodyPartRecord leftLeg, BodyPartRecord rightFoot, BodyPartRecord rightLeg)
        {
            if (anim == null)
            {
                return;
            }

            if (anim.Props.bipedWithHands)
            {
                if (hediff.Part.parts.Contains(leftHand) || hediff.Part.parts.Contains(leftArm))
                {
                    anim.BodyStat.HandLeft = PartStatus.Artificial;
                }

                if (hediff.Part.parts.Contains(rightHand) || hediff.Part.parts.Contains(rightArm))
                {
                    anim.BodyStat.HandRight = PartStatus.Artificial;
                }
            }

            if (hediff.Part.parts.Contains(leftFoot) || hediff.Part.parts.Contains(leftLeg))
            {
                anim.BodyStat.FootLeft = PartStatus.Artificial;
            }

            if (hediff.Part.parts.Contains(rightFoot) || hediff.Part.parts.Contains(rightLeg))
            {
                anim.BodyStat.FootRight = PartStatus.Artificial;
            }
        }
        static bool RulesForBodyPartRecordPrefix(ref IEnumerable <Rule> __result, string prefix, BodyPartRecord part)
        {
            // if the current language is not the target, do nothing
            if (!LanguageWorkerPatcher.IsTargetLanguage(LanguageDatabase.activeLanguage.FriendlyNameEnglish))
            {
                return(true);
            }

            // Rewrite the method entirely since it is short enough
            __result = LanguageWorker_Spanish.FixRulesForBodyPartRecord(prefix, part);

#if DEBUG
            LanguageWorkerPatcher.LogMessage("--RulesForBodyPartRecordPrefix called...");
            LanguageWorkerPatcher.LogMessage("result: " + __result);
            foreach (Rule r in __result)
            {
                LanguageWorkerPatcher.LogMessage(r.ToString());
            }
#endif
            // DO NOT CONTINUE to the original GrammarUtility.RulesforPawn
            return(false);
        }
コード例 #28
0
ファイル: Verb_BloodGift.cs プロジェクト: hodldeeznuts/TMagic
        protected override bool TryCastShot()
        {
            bool result = false;
            bool arg_40_0;

            Pawn pawn = this.CasterPawn;
            Map  map  = this.CasterPawn.Map;
            CompAbilityUserMagic comp = pawn.GetComp <CompAbilityUserMagic>();
            int verVal    = pawn.GetComp <CompAbilityUserMagic>().MagicData.MagicPowerSkill_BloodGift.FirstOrDefault((MagicPowerSkill x) => x.label == "TM_BloodGift_ver").level;
            int bloodGain = 0;
            List <BodyPartRecord> bodyparts = new List <BodyPartRecord>();

            bodyparts.Clear();
            bodyparts = this.CasterPawn.def.race.body.AllParts;
            List <ThingDef> bloodDefs = TM_Calc.GetAllRaceBloodTypes();

            ModOptions.SettingsRef settingsRef = new ModOptions.SettingsRef();
            if (pawn != null && !pawn.Downed && bodyparts != null && bloodDefs != null)
            {
                if (verVal > 0)
                {
                    List <IntVec3> cellList = GenRadial.RadialCellsAround(this.CasterPawn.Position, (2 * verVal) - 1, true).ToList();
                    for (int i = 0; i < cellList.Count; i++)
                    {
                        IntVec3      curcell   = cellList[i];
                        List <Thing> thingList = curcell.GetThingList(this.CasterPawn.Map);
                        for (int j = 0; j < thingList.Count; j++)
                        {
                            if (thingList[j].def == ThingDefOf.Filth_Blood || (settingsRef.unrestrictedBloodTypes && bloodDefs.Contains(thingList[j].def)))
                            {
                                bloodGain += thingList[j].stackCount;
                                thingList[j].Destroy(DestroyMode.Vanish);
                            }
                        }
                    }
                }

                List <BodyPartRecord> validParts = new List <BodyPartRecord>();
                validParts.Clear();
                for (int i = 0; i < bodyparts.Count; i++)
                {
                    if (bodyparts[i].def.bleedRate != 0 && bodyparts[i].depth == BodyPartDepth.Outside && bodyparts[i].coverageAbs > 0)
                    {
                        validParts.Add(bodyparts[i]);
                    }
                }
                if (validParts.Count > 0)
                {
                    if (this.CasterPawn.RaceProps.BloodDef != null && (this.CasterPawn.RaceProps.BloodDef == ThingDefOf.Filth_Blood || settingsRef.unrestrictedBloodTypes))
                    {
                        BodyPartRecord damagePart = validParts.RandomElement();
                        TM_Action.DamageEntities(this.CasterPawn, damagePart, 4f, 10f, TMDamageDefOf.DamageDefOf.TM_BloodyCut, this.CasterPawn);
                        damagePart = validParts.RandomElement();
                        TM_Action.DamageEntities(this.CasterPawn, damagePart, 2f, 10f, TMDamageDefOf.DamageDefOf.TM_BloodyCut, this.CasterPawn);
                        bloodGain += 18;
                        List <Need> needs = this.CasterPawn.needs.AllNeeds;
                        for (int n = 0; n < needs.Count; n++)
                        {
                            Need need = needs[n];
                            if (need.def.defName == "ROMV_Blood")
                            {
                                need.CurLevel--;
                            }
                        }
                        TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_CrossStrike"), this.CasterPawn.DrawPos, this.CasterPawn.Map, Rand.Range(.4f, 0.6f), .45f, .05f, .20f, 0, 0, 0, Rand.Range(0, 360));
                        for (int j = 0; j < 4; j++)
                        {
                            IntVec3 rndPos = this.CasterPawn.Position;
                            rndPos.x += Mathf.RoundToInt(Rand.Range(-1.5f, 1.5f));
                            rndPos.z += Mathf.RoundToInt(Rand.Range(-1.5f, 1.5f));
                            FilthMaker.MakeFilth(rndPos, this.CasterPawn.Map, this.CasterPawn.RaceProps.BloodDef, Rand.RangeInclusive(1, 2));
                            TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_BloodSquirt"), this.CasterPawn.DrawPos, this.CasterPawn.Map, Rand.Range(.7f, 1.1f), .15f, .05f, .66f, Rand.Range(-100, 100), Rand.Range(1, 2), Rand.Range(0, 360), Rand.Range(0, 360));
                        }
                    }
                }
                else
                {
                    if (bloodGain == 0)
                    {
                        Messages.Message("TM_NoExternalBodyPartsCanBleed".Translate(this.CasterPawn.LabelShort), MessageTypeDefOf.RejectInput, false);
                    }
                }
                HealthUtility.AdjustSeverity(this.CasterPawn, HediffDef.Named("TM_BloodHD"), bloodGain * (1 + (.1f * verVal)));
                arg_40_0 = true;
            }
            else
            {
                arg_40_0 = false;
            }
            bool flag = arg_40_0;

            if (flag)
            {
            }
            else
            {
                Log.Warning("failed to TryCastShot");
            }
            this.burstShotsLeft = 0;

            return(result);
        }
コード例 #29
0
        private void RemoveHediffsAddictionsAndPermanentInjuries(Pawn pawn)
        {
            List <Hediff> removeList = new List <Hediff>();

            removeList.Clear();
            using (IEnumerator <BodyPartRecord> enumerator = pawn.health.hediffSet.GetInjuredParts().GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    BodyPartRecord rec = enumerator.Current;

                    IEnumerable <Hediff_Injury> arg_BB_0 = pawn.health.hediffSet.GetHediffs <Hediff_Injury>();
                    Func <Hediff_Injury, bool>  arg_BB_1;

                    arg_BB_1 = ((Hediff_Injury injury) => injury.Part == rec);

                    foreach (Hediff_Injury current in arg_BB_0.Where(arg_BB_1))
                    {
                        bool flag5 = !current.CanHealNaturally() && current.IsPermanent();
                        if (flag5)
                        {
                            removeList.Add(current);
                        }
                    }
                }
            }
            if (removeList.Count > 0)
            {
                for (int i = 0; i < removeList.Count; i++)
                {
                    pawn.health.RemoveHediff(removeList[i]);
                }
            }
            removeList.Clear();

            using (IEnumerator <Hediff_Addiction> enumerator = pawn.health.hediffSet.GetHediffs <Hediff_Addiction>().GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    Hediff_Addiction rec = enumerator.Current;
                    removeList.Add(rec);
                }
            }

            if (removeList.Count > 0)
            {
                for (int i = 0; i < removeList.Count; i++)
                {
                    pawn.health.RemoveHediff(removeList[i]);
                }
            }
            removeList.Clear();

            using (IEnumerator <Hediff> enumerator = pawn.health.hediffSet.GetHediffs <Hediff>().GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    Hediff hd = enumerator.Current;
                    if (hd.IsPermanent() || (hd.IsTended() || hd.TendableNow()) || (hd.source == null && hd.sourceBodyPartGroup == null))
                    {
                        removeList.Add(hd);
                    }
                }
            }

            if (removeList.Count > 0)
            {
                for (int i = 0; i < removeList.Count; i++)
                {
                    pawn.health.RemoveHediff(removeList[i]);
                }
            }
            removeList.Clear();
        }
コード例 #30
0
        static void Postfix(Pawn_HealthTracker __instance)
        {
            Pawn pawn = Traverse.Create(__instance).Field("pawn").GetValue <Pawn>();

            if (!pawn.RaceProps.IsMechanoid)
            {
                return;
            }

            ExtendedPawnData pawnData = Base.Instance.GetExtendedDataStorage().GetExtendedDataFor(pawn);

            if (pawnData.shouldExplodeNow)
            {
                GenExplosion.DoExplosion(pawn.Position, pawn.Map, 4.5f, DamageDefOf.Bomb, pawn, DamageDefOf.Bomb.defaultDamage, DamageDefOf.Bomb.defaultArmorPenetration, DamageDefOf.Bomb.soundExplosion, null, null, null, null, 0f, 1, false, null, 0f, 1, 0f, false);
                pawn.jobs.startingNewJob = false;
                BodyPartRecord reactorPart = pawn.health.hediffSet.GetNotMissingParts().FirstOrDefault((BodyPartRecord r) => r.def.defName == "Reactor");
                pawn.TakeDamage(new DamageInfo(DamageDefOf.Bomb, reactorPart.def.GetMaxHealth(pawn), 9999, -1, null, reactorPart));
                pawnData.shouldExplodeNow = false;
            }


            if (pawn.HasValidCaravanPlatform() && pawn.GetCaravan() != null && pawn.GetCaravan().HasFuel())
            {
                float powerPerTick = 0.5f * WTH_DefOf.WTH_PortableChargingPlatform.GetCompProperties <CompProperties_Refuelable>().fuelConsumptionRate * 15 / GenDate.TicksPerDay; //TODO: no magic number
                RechargeMechanoid(pawn, pawn.needs.TryGetNeed(WTH_DefOf.WTH_Mechanoid_Power), powerPerTick);
            }
            if (pawn.health.hediffSet.HasHediff(WTH_DefOf.WTH_VanometricModule))
            {
                RechargeMechanoid(pawn, pawn.needs.TryGetNeed(WTH_DefOf.WTH_Mechanoid_Power), 0.0085f);//TODO: no magic number
            }

            if (pawn.health.hediffSet.HasHediff(WTH_DefOf.WTH_Repairing))
            {
                if (pawn.IsHashIntervalTick(10))
                {
                    TryHealRandomInjury(__instance, pawn, 4000f / RimWorld.GenDate.TicksPerDay);
                }
            }

            if (!(pawn.CurrentBed() is Building_BaseMechanoidPlatform))
            {
                return;
            }

            Building_BaseMechanoidPlatform platform = (Building_BaseMechanoidPlatform)pawn.CurrentBed();

            if (platform.RepairActive && __instance.hediffSet.HasNaturallyHealingInjury() && !pawn.health.hediffSet.HasHediff(WTH_DefOf.WTH_Repairing))
            {
                if (pawn.IsHashIntervalTick(10) && platform.CanHealNow())
                {
                    TryHealRandomInjury(__instance, pawn, WTH_DefOf.WTH_MechanoidPlatform.building.bed_healPerDay * 10 / RimWorld.GenDate.TicksPerDay, platform);
                }
            }
            if (!__instance.hediffSet.HasNaturallyHealingInjury() && platform.RegenerateActive && pawn.IsHashIntervalTick(100) && platform.refuelableComp.Fuel > 4f) //TODO: no magic number
            {
                TryRegeneratePart(pawn, platform);
                RegainWeapon(pawn);
            }

            if (platform.HasPowerNow())
            {
                Need  powerNeed    = pawn.needs.TryGetNeed(WTH_DefOf.WTH_Mechanoid_Power);
                float powerPerTick = 0;
                if (platform.PowerComp != null)
                {
                    powerPerTick = 0.75f * platform.PowerComp.Props.basePowerConsumption / GenDate.TicksPerDay; //TODO: no magic number
                }
                else
                {
                    platform.refuelableComp.ConsumeFuel(platform.refuelableComp.Props.fuelConsumptionRate / GenDate.TicksPerDay);
                    powerPerTick = 0.75f * platform.refuelableComp.Props.fuelConsumptionRate * 15 / GenDate.TicksPerDay; //TODO: no magic number
                }

                RechargeMechanoid(pawn, powerNeed, powerPerTick);
            }
        }
コード例 #31
0
ファイル: Utility.cs プロジェクト: RimWorldMod/CombatRealism
        /// <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);
        }
コード例 #32
0
        public static bool HasDirectlyAddedPartFor(HediffSet __instance, ref bool __result, BodyPartRecord part)
        {
            List <Hediff> hediffs = __instance.hediffs;

            for (int index = 0; index < hediffs.Count; ++index)
            {
                Hediff hediff = hediffs[index];
                if (hediff != null && hediff.Part == part && hediff is Hediff_AddedPart)
                {
                    __result = true;
                    return(false);
                }
            }
            __result = false;
            return(false);
        }
コード例 #33
0
 public void RemoveHediffDefOn( Pawn pawn, HediffDef hediffDef, BodyPartRecord bodyPartRecord )
 {
     if(
         ( pawn == null )||
         ( hediffDef == null )||
         ( bodyPartRecord == null )
     )
     {
         return;
     }
     var hediff = pawn.health.hediffSet.hediffs.FirstOrDefault( diff => (
         ( diff.Part == bodyPartRecord )&&
         ( diff.def == hediffDef )
     ) );
     if( hediff == null )
     {
         return;
     }
     pawn.health.hediffSet.hediffs.Remove( hediff );
 }
コード例 #34
0
        /// <summary>
        /// Calculates damage reduction for ambient damage types (fire, electricity) versus natural and worn armor of a pawn. Adds up the total armor percentage (clamped at 0-100%) and multiplies damage by that amount.
        /// </summary>
        /// <param name="dmgAmount">The original amount of damage</param>
        /// <param name="armorRatingStat">The armor stat to use for damage reduction</param>
        /// <param name="pawn">The damaged pawn</param>
        /// <param name="part">The body part affected</param>
        /// <returns>The post-armor damage ranging from 0 to the original amount</returns>
        private static float GetAmbientPostArmorDamage(float dmgAmount, StatDef armorRatingStat, Pawn pawn, BodyPartRecord part)
        {
            var dmgMult = 1f;

            if (part.IsInGroup(CE_BodyPartGroupDefOf.CoveredByNaturalArmor))
            {
                dmgMult -= pawn.GetStatValue(armorRatingStat);
            }

            if (dmgMult <= 0)
            {
                return(0);
            }
            if (pawn.apparel != null && !pawn.apparel.WornApparel.NullOrEmpty())
            {
                var apparelList = pawn.apparel.WornApparel;
                foreach (var apparel in apparelList)
                {
                    if (apparel.def.apparel.CoversBodyPart(part))
                    {
                        dmgMult -= apparel.GetStatValue(armorRatingStat);
                    }
                    if (dmgMult <= 0)
                    {
                        dmgMult = 0;
                        break;
                    }
                }
            }
            return(dmgAmount * dmgMult);
        }