Beispiel #1
0
 public DamageInfo(DamageDef def, float amount, float armorPenetration = 0f, float angle = -1f, Thing instigator = null, BodyPartRecord hitPart = null, ThingDef weapon = null, SourceCategory category = SourceCategory.ThingOrUnknown, Thing intendedTarget = null)
 {
     defInt              = def;
     amountInt           = amount;
     armorPenetrationInt = armorPenetration;
     if (angle < 0f)
     {
         angleInt = Rand.RangeInclusive(0, 359);
     }
     else
     {
         angleInt = angle;
     }
     instigatorInt                  = instigator;
     categoryInt                    = category;
     hitPartInt                     = hitPart;
     heightInt                      = BodyPartHeight.Undefined;
     depthInt                       = BodyPartDepth.Undefined;
     weaponInt                      = weapon;
     weaponBodyPartGroupInt         = null;
     weaponHediffInt                = null;
     instantPermanentInjuryInt      = false;
     allowDamagePropagationInt      = true;
     ignoreArmorInt                 = false;
     ignoreInstantKillProtectionInt = false;
     intendedTargetInt              = intendedTarget;
 }
Beispiel #2
0
        public BodyPartRecord GetRandomNotMissingPart(DamageDef damDef, BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined, BodyPartRecord partParent = null)
        {
            IEnumerable <BodyPartRecord> enumerable = null;
            BodyPartHeight height2 = height;
            BodyPartDepth  depth2  = depth;

            if (GetNotMissingParts(height2, depth2, null, partParent).Any())
            {
                height2    = height;
                depth2     = depth;
                enumerable = GetNotMissingParts(height2, depth2, null, partParent);
            }
            else
            {
                depth2 = depth;
                if (!GetNotMissingParts(BodyPartHeight.Undefined, depth2, null, partParent).Any())
                {
                    return(null);
                }
                height2    = BodyPartHeight.Undefined;
                depth2     = depth;
                enumerable = GetNotMissingParts(height2, depth2, null, partParent);
            }
            if (enumerable.TryRandomElementByWeight((BodyPartRecord x) => x.coverageAbs * x.def.GetHitChanceFactorFor(damDef), out BodyPartRecord result))
            {
                return(result);
            }
            if (enumerable.TryRandomElementByWeight((BodyPartRecord x) => x.coverageAbs, out result))
            {
                return(result);
            }
            throw new InvalidOperationException();
        }
        public BodyPartRecord GetRandomNotMissingPart(DamageDef damDef, BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined)
        {
            IEnumerable <BodyPartRecord> enumerable = null;

            if (this.GetNotMissingParts(height, depth).Any())
            {
                enumerable = this.GetNotMissingParts(height, depth);
                goto IL_0053;
            }
            if (this.GetNotMissingParts(BodyPartHeight.Undefined, depth).Any())
            {
                enumerable = this.GetNotMissingParts(BodyPartHeight.Undefined, depth);
                goto IL_0053;
            }
            return(null);

IL_0053:
            BodyPartRecord result = default(BodyPartRecord);

            if (enumerable.TryRandomElementByWeight <BodyPartRecord>((Func <BodyPartRecord, float>)((BodyPartRecord x) => x.coverageAbs * x.def.GetHitChanceFactorFor(damDef)), out result))
            {
                return(result);
            }
            if (enumerable.TryRandomElementByWeight <BodyPartRecord>((Func <BodyPartRecord, float>)((BodyPartRecord x) => x.coverageAbs), out result))
            {
                return(result);
            }
            throw new InvalidOperationException();
        }
Beispiel #4
0
        public BodyPartRecord GetRandomNotMissingPart(DamageDef damDef, BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined)
        {
            IEnumerable <BodyPartRecord> notMissingParts;

            if (this.GetNotMissingParts(height, depth).Any <BodyPartRecord>())
            {
                notMissingParts = this.GetNotMissingParts(height, depth);
            }
            else
            {
                if (!this.GetNotMissingParts(BodyPartHeight.Undefined, depth).Any <BodyPartRecord>())
                {
                    return(null);
                }
                notMissingParts = this.GetNotMissingParts(BodyPartHeight.Undefined, depth);
            }
            BodyPartRecord result;

            if (notMissingParts.TryRandomElementByWeight((BodyPartRecord x) => x.coverageAbs * x.def.GetHitChanceFactorFor(damDef), out result))
            {
                return(result);
            }
            if (notMissingParts.TryRandomElementByWeight((BodyPartRecord x) => x.coverageAbs, out result))
            {
                return(result);
            }
            throw new InvalidOperationException();
        }
Beispiel #5
0
        public IEnumerable <BodyPartRecord> GetNotMissingParts(BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined, BodyPartTagDef tag = null, BodyPartRecord partParent = null)
        {
            List <BodyPartRecord> allPartsList = this.pawn.def.race.body.AllParts;

            for (int i = 0; i < allPartsList.Count; i++)
            {
                BodyPartRecord part = allPartsList[i];
                if (!this.PartIsMissing(part))
                {
                    if (height == BodyPartHeight.Undefined || part.height == height)
                    {
                        if (depth == BodyPartDepth.Undefined || part.depth == depth)
                        {
                            if (tag == null || part.def.tags.Contains(tag))
                            {
                                if (partParent == null || part.parent == partParent)
                                {
                                    yield return(part);
                                }
                            }
                        }
                    }
                }
            }
        }
 public DamageInfo(DamageDef def, float amount, float armorPenetration = 0f, float angle = -1f, Thing instigator = null, BodyPartRecord hitPart = null, ThingDef weapon = null, DamageInfo.SourceCategory category = DamageInfo.SourceCategory.ThingOrUnknown, Thing intendedTarget = null)
 {
     this.defInt              = def;
     this.amountInt           = amount;
     this.armorPenetrationInt = armorPenetration;
     if (angle < 0f)
     {
         this.angleInt = (float)Rand.RangeInclusive(0, 359);
     }
     else
     {
         this.angleInt = angle;
     }
     this.instigatorInt             = instigator;
     this.categoryInt               = category;
     this.hitPartInt                = hitPart;
     this.heightInt                 = BodyPartHeight.Undefined;
     this.depthInt                  = BodyPartDepth.Undefined;
     this.weaponInt                 = weapon;
     this.weaponBodyPartGroupInt    = null;
     this.weaponHediffInt           = null;
     this.instantPermanentInjuryInt = false;
     this.allowDamagePropagationInt = true;
     this.intendedTargetInt         = intendedTarget;
 }
        public IEnumerable <BodyPartRecord> GetNotMissingParts(BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined)
        {
            List <BodyPartRecord> allPartsList = this.pawn.def.race.body.AllParts;
            int            i = 0;
            BodyPartRecord part;

            while (true)
            {
                if (i < allPartsList.Count)
                {
                    part = allPartsList[i];
                    if (!this.PartIsMissing(part) && (height == BodyPartHeight.Undefined || part.height == height))
                    {
                        if (depth == BodyPartDepth.Undefined)
                        {
                            break;
                        }
                        if (part.depth == depth)
                        {
                            break;
                        }
                    }
                    i++;
                    continue;
                }
                yield break;
            }
            yield return(part);

            /*Error: Unable to find new state assignment for yield return*/;
        }
        // Token: 0x0600001E RID: 30 RVA: 0x00002BAC File Offset: 0x00000DAC
        public void addAcidDamage(Pawn p)
        {
            List <BodyPartRecord> list        = new List <BodyPartRecord>();
            List <Apparel>        wornApparel = new List <Apparel>();

            if (p.RaceProps.Humanlike)
            {
                wornApparel = p.apparel.WornApparel;
            }
            int        num        = Mathf.RoundToInt((float)this.AcidDamage * Rand.Range(0.5f, 1.25f));
            DamageInfo damageInfo = default(DamageInfo);

            MoteMaker.ThrowDustPuff(p.Position, base.Map, 0.2f);
            BodyPartHeight bodyPartHeight = p.Downed ? BodyPartHeight.Undefined : BodyPartHeight.Bottom;

            foreach (BodyPartRecord bodyPartRecord in p.health.hediffSet.GetNotMissingParts(bodyPartHeight, BodyPartDepth.Outside, null, null))
            {
                bool flag = wornApparel.Count > 0;
                if (flag)
                {
                    bool flag2 = false;
                    for (int i = 0; i < wornApparel.Count; i++)
                    {
                        bool flag3 = wornApparel[i].def.apparel.CoversBodyPart(bodyPartRecord);
                        if (flag3)
                        {
                            flag2 = true;
                            break;
                        }
                    }
                    bool flag4 = !flag2;
                    if (flag4)
                    {
                        list.Add(bodyPartRecord);
                    }
                }
                else
                {
                    list.Add(bodyPartRecord);
                }
            }
            for (int k = 0; k < list.Count; k++)
            {
                damageInfo = new DamageInfo(XenomorphDefOf.RRY_AcidBurn, (float)Mathf.RoundToInt(((float)num * list[k].coverage) * 10), 0f, -1f, this, list[k], null, 0, null);
                if (Rand.Chance(list[k].coverage))
                {
                    for (int j = 0; j < wornApparel.Count; j++)
                    {
                        bool flag3 = wornApparel[j].def.apparel.CoversBodyPart(list[k]);
                        if (flag3)
                        {
                            this.damageEntities(wornApparel[j], num);
                        }
                    }
                    p.TakeDamage(damageInfo);
                    break;
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Selects a random BodyPartHeight out of the ones our CasterPawn can hit, depending on our body size vs the target's. So a rabbit can hit top height of another rabbit, but not of a human.
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        private BodyPartHeight GetBodyPartHeightFor(LocalTargetInfo target)
        {
            Pawn pawn = target.Thing as Pawn;

            if (pawn == null || CasterPawn == null)
            {
                return(BodyPartHeight.Undefined);
            }
            var            casterReach  = new CollisionVertical(CasterPawn).Max * 1.2f;
            var            targetHeight = new CollisionVertical(pawn);
            BodyPartHeight maxHeight    = targetHeight.GetRandWeightedBodyHeightBelow(casterReach);
            BodyPartHeight height       = (BodyPartHeight)Rand.RangeInclusive(1, (int)maxHeight);

            return(height);
        }
 public DamageInfo(DamageInfo cloneSource)
 {
     this.defInt                    = cloneSource.defInt;
     this.amountInt                 = cloneSource.amountInt;
     this.angleInt                  = cloneSource.angleInt;
     this.instigatorInt             = cloneSource.instigatorInt;
     this.categoryInt               = cloneSource.categoryInt;
     this.hitPartInt                = cloneSource.hitPartInt;
     this.heightInt                 = cloneSource.heightInt;
     this.depthInt                  = cloneSource.depthInt;
     this.weaponInt                 = cloneSource.weaponInt;
     this.weaponBodyPartGroupInt    = cloneSource.weaponBodyPartGroupInt;
     this.weaponHediffInt           = cloneSource.weaponHediffInt;
     this.instantOldInjuryInt       = cloneSource.instantOldInjuryInt;
     this.allowDamagePropagationInt = cloneSource.allowDamagePropagationInt;
 }
        private void DamagePawn(Pawn p)
        {
            BodyPartHeight height        = (BodyPartHeight)((!(Rand.Value < 0.66600000858306885)) ? 2 : 3);
            int            num           = Mathf.RoundToInt(this.GetStatValue(StatDefOf.TrapMeleeDamage, true) * Building_TrapRearmable.TrapDamageFactor.RandomInRange);
            int            randomInRange = Building_TrapRearmable.DamageCount.RandomInRange;
            int            num2          = 0;

            while (num2 < randomInRange && num > 0)
            {
                int num3 = Mathf.Max(1, Mathf.RoundToInt(Rand.Value * (float)num));
                num -= num3;
                DamageInfo dinfo = new DamageInfo(DamageDefOf.Stab, num3, -1f, this, null, null, DamageInfo.SourceCategory.ThingOrUnknown);
                dinfo.SetBodyRegion(height, BodyPartDepth.Outside);
                p.TakeDamage(dinfo);
                num2++;
            }
        }
Beispiel #12
0
 public DamageInfo(DamageInfo cloneSource)
 {
     defInt                    = cloneSource.defInt;
     amountInt                 = cloneSource.amountInt;
     armorPenetrationInt       = cloneSource.armorPenetrationInt;
     angleInt                  = cloneSource.angleInt;
     instigatorInt             = cloneSource.instigatorInt;
     categoryInt               = cloneSource.categoryInt;
     hitPartInt                = cloneSource.hitPartInt;
     heightInt                 = cloneSource.heightInt;
     depthInt                  = cloneSource.depthInt;
     weaponInt                 = cloneSource.weaponInt;
     weaponBodyPartGroupInt    = cloneSource.weaponBodyPartGroupInt;
     weaponHediffInt           = cloneSource.weaponHediffInt;
     instantPermanentInjuryInt = cloneSource.instantPermanentInjuryInt;
     allowDamagePropagationInt = cloneSource.allowDamagePropagationInt;
     intendedTargetInt         = cloneSource.intendedTargetInt;
 }
        private void DamagePawn(Pawn p)
        {
            BodyPartHeight height        = (Rand.Value >= 0.666f) ? BodyPartHeight.Middle : BodyPartHeight.Top;
            int            num           = Mathf.RoundToInt(this.GetStatValue(StatDefOf.TrapMeleeDamage, true) * Building_TrapRearmable.TrapDamageFactor.RandomInRange);
            int            randomInRange = Building_TrapRearmable.DamageCount.RandomInRange;

            for (int i = 0; i < randomInRange; i++)
            {
                if (num <= 0)
                {
                    break;
                }
                int num2 = Mathf.Max(1, Mathf.RoundToInt(Rand.Value * (float)num));
                num -= num2;
                DamageInfo dinfo = new DamageInfo(DamageDefOf.Stab, (float)num2, 0f, -1f, this, null, null, DamageInfo.SourceCategory.ThingOrUnknown, null);
                dinfo.SetBodyRegion(height, BodyPartDepth.Outside);
                p.TakeDamage(dinfo);
            }
        }
Beispiel #14
0
        public IEnumerable <BodyPartRecord> GetNotMissingParts(BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined, BodyPartTagDef tag = null, BodyPartRecord partParent = null)
        {
            List <BodyPartRecord> allPartsList = pawn.def.race.body.AllParts;
            int            i = 0;
            BodyPartRecord part;

            while (true)
            {
                if (i >= allPartsList.Count)
                {
                    yield break;
                }
                part = allPartsList[i];
                if (!PartIsMissing(part) && (height == BodyPartHeight.Undefined || part.height == height) && (depth == BodyPartDepth.Undefined || part.depth == depth) && (tag == null || part.def.tags.Contains(tag)) && (partParent == null || part.parent == partParent))
                {
                    break;
                }
                i++;
            }
            yield return(part);

            /*Error: Unable to find new state assignment for yield return*/;
        }
        private void DamagePawn(Pawn p)
        {
            BodyPartHeight height = (Rand.Value >= 0.666f) ? BodyPartHeight.Middle : BodyPartHeight.Top;
            float          num    = this.GetStatValue(StatDefOf.TrapMeleeDamage, true) * Building_TrapRearmable.TrapDamageFactor.RandomInRange;
            float          num2   = num / Building_TrapRearmable.DamageCount.RandomInRange;



            float armorPenetration = num2 * ArmorPenetrationAmount;
            int   num3             = 0;

            while ((float)num3 < Building_TrapRearmable.DamageCount.RandomInRange)
            {
                DamageInfo dinfo = new DamageInfo(DamageDefOf.Stab, num2, armorPenetration, -1f, this, null, null, DamageInfo.SourceCategory.ThingOrUnknown, null);
                DamageWorker.DamageResult damageResult = p.TakeDamage(dinfo);
                if (num3 == 0)
                {
                    BattleLogEntry_DamageTaken battleLogEntry_DamageTaken = new BattleLogEntry_DamageTaken(p, RulePackDefOf.DamageEvent_TrapSpike, null);
                    Find.BattleLog.Add(battleLogEntry_DamageTaken);
                    damageResult.AssociateWithLog(battleLogEntry_DamageTaken);
                }
                num3++;
            }
        }
        /// <summary>
        /// Calculates primary DamageInfo from verb, as well as secondary DamageInfos to apply (i.e. surprise attack stun damage).
        /// Also calculates the maximum body height an attack can target, so we don't get rabbits biting out a colonist's eye or something.
        /// </summary>
        /// <param name="target">The target damage is to be applied to</param>
        /// <returns>Collection with primary DamageInfo, followed by secondary types</returns>
        private IEnumerable <DamageInfo> DamageInfosToApply(LocalTargetInfo target, bool isCrit = false)
        {
            float            damAmount        = (float)this.verbProps.AdjustedMeleeDamageAmount(this, base.CasterPawn, this.ownerEquipment);
            var              critDamDef       = CritDamageDef;
            DamageDef        damDef           = isCrit && critDamDef != DamageDefOf.Stun ? critDamDef : verbProps.meleeDamageDef;
            BodyPartGroupDef bodyPartGroupDef = tool?.linkedBodyPartsGroup;
            HediffDef        hediffDef        = null;

            damAmount = UnityEngine.Random.Range(damAmount * 0.8f, damAmount * 1.2f);
            if (base.CasterIsPawn)
            {
                if (damAmount >= 1f)
                {
                    if (this.ownerHediffComp != null)
                    {
                        hediffDef = this.ownerHediffComp.Def;
                    }
                }
                else
                {
                    damAmount = 1f;
                    damDef    = DamageDefOf.Blunt;
                }
            }
            ThingDef source;

            if (this.ownerEquipment != null)
            {
                source = this.ownerEquipment.def;
            }
            else
            {
                source = base.CasterPawn.def;
            }
            Vector3        direction  = (target.Thing.Position - base.CasterPawn.Position).ToVector3();
            Thing          caster     = this.caster;
            BodyPartHeight bodyRegion = GetBodyPartHeightFor(target);   // Add check for body height
            DamageInfo     mainDinfo  = new DamageInfo(damDef, GenMath.RoundRandom(damAmount), -1f, caster, null, source);

            mainDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside);
            mainDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
            mainDinfo.SetWeaponHediff(hediffDef);
            mainDinfo.SetAngle(direction);
            yield return(mainDinfo);

            // Apply secondary damage on surprise attack
            if (!surpriseAttack ||
                ((verbProps.surpriseAttack == null || verbProps.surpriseAttack.extraMeleeDamages.NullOrEmpty <ExtraMeleeDamage>()) &&
                 tool != null &&
                 tool.surpriseAttack != null &&
                 !tool.surpriseAttack.extraMeleeDamages.NullOrEmpty <ExtraMeleeDamage>())
                )
            {
                IEnumerable <ExtraMeleeDamage> extraDamages = Enumerable.Empty <ExtraMeleeDamage>();
                if (verbProps.surpriseAttack != null && verbProps.surpriseAttack.extraMeleeDamages != null)
                {
                    extraDamages = extraDamages.Concat(tool.surpriseAttack.extraMeleeDamages);
                }
                if (tool != null && tool.surpriseAttack != null && !tool.surpriseAttack.extraMeleeDamages.NullOrEmpty <ExtraMeleeDamage>())
                {
                    extraDamages = extraDamages.Concat(tool.surpriseAttack.extraMeleeDamages);
                }
                foreach (ExtraMeleeDamage extraDamage in extraDamages)
                {
                    int        amount     = GenMath.RoundRandom((float)extraDamage.amount * base.GetDamageFactorFor(base.CasterPawn));
                    DamageInfo extraDinfo = new DamageInfo(extraDamage.def, amount, -1f, this.caster, null, source);
                    extraDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside);
                    extraDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
                    extraDinfo.SetWeaponHediff(hediffDef);
                    extraDinfo.SetAngle(direction);
                    yield return(extraDinfo);
                }
            }

            // Apply critical damage
            if (isCrit && critDamDef == DamageDefOf.Stun)
            {
                var critAmount = GenMath.RoundRandom(mainDinfo.Amount * 0.25f);
                var critDinfo  = new DamageInfo(critDamDef, critAmount, -1, caster, null, source);
                critDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside);
                critDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
                critDinfo.SetWeaponHediff(hediffDef);
                critDinfo.SetAngle(direction);
                yield return(critDinfo);
            }
        }
Beispiel #17
0
        /// <summary>
        /// Calculates primary DamageInfo from verb, as well as secondary DamageInfos to apply (i.e. surprise attack stun damage).
        /// Also calculates the maximum body height an attack can target, so we don't get rabbits biting out a colonist's eye or something.
        /// </summary>
        /// <param name="target">The target damage is to be applied to</param>
        /// <returns>Collection with primary DamageInfo, followed by secondary types</returns>
        private IEnumerable <DamageInfo> DamageInfosToApply(LocalTargetInfo target, bool isCrit = false)
        {
            //START 1:1 COPY Verb_MeleeAttack.DamageInfosToApply
            float            damAmount        = this.verbProps.AdjustedMeleeDamageAmount(this, base.CasterPawn);
            float            armorPenetration = (isCrit && verbProps.meleeDamageDef.armorCategory == DamageArmorCategoryDefOf.Sharp && !CasterPawn.def.race.Animal ? 2 : 1) * this.verbProps.AdjustedArmorPenetration(this, base.CasterPawn);
            DamageDef        damDef           = verbProps.meleeDamageDef;
            BodyPartGroupDef bodyPartGroupDef = null;
            HediffDef        hediffDef        = null;

            damAmount = Rand.Range(damAmount * 0.8f, damAmount * 1.2f);
            if (base.CasterIsPawn)
            {
                bodyPartGroupDef = this.verbProps.AdjustedLinkedBodyPartsGroup(this.tool);
                if (damAmount >= 1f)
                {
                    if (base.HediffCompSource != null)
                    {
                        hediffDef = base.HediffCompSource.Def;
                    }
                }
                else
                {
                    damAmount = 1f;
                    damDef    = DamageDefOf.Blunt;
                }
            }
            ThingDef source;

            if (base.EquipmentSource != null)
            {
                source = base.EquipmentSource.def;
            }
            else
            {
                source = base.CasterPawn.def;
            }
            Vector3   direction = (target.Thing.Position - base.CasterPawn.Position).ToVector3();
            DamageDef def       = damDef;
            //END 1:1 COPY
            BodyPartHeight bodyRegion = GetBodyPartHeightFor(target);   //Custom // Add check for body height
            //START 1:1 COPY
            Thing      caster    = this.caster;
            DamageInfo mainDinfo = new DamageInfo(def, damAmount, armorPenetration, -1f, caster, null, source, DamageInfo.SourceCategory.ThingOrUnknown, null); //Alteration

            mainDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside);                                                                                         //Alteration
            mainDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
            mainDinfo.SetWeaponHediff(hediffDef);
            mainDinfo.SetAngle(direction);
            yield return(mainDinfo);

            // Apply secondary damage on surprise attack

            /*
             * if (this.surpriseAttack && ((this.verbProps.surpriseAttack != null && !this.verbProps.surpriseAttack.extraMeleeDamages.NullOrEmpty<ExtraMeleeDamage>()) || this.tool == null || this.tool.surpriseAttack == null || this.tool.surpriseAttack.extraMeleeDamages.NullOrEmpty<ExtraMeleeDamage>()))
             *          {
             *                  IEnumerable<ExtraMeleeDamage> extraDamages = Enumerable.Empty<ExtraMeleeDamage>();
             *                  if (this.verbProps.surpriseAttack != null && this.verbProps.surpriseAttack.extraMeleeDamages != null)
             *                  {
             *                          extraDamages = extraDamages.Concat(this.verbProps.surpriseAttack.extraMeleeDamages);
             *                  }
             *                  if (this.tool != null && this.tool.surpriseAttack != null && !this.tool.surpriseAttack.extraMeleeDamages.NullOrEmpty<ExtraMeleeDamage>())
             *                  {
             *                          extraDamages = extraDamages.Concat(this.tool.surpriseAttack.extraMeleeDamages);
             *                  }
             *                  foreach (ExtraMeleeDamage extraDamage in extraDamages)
             *                  {
             *                          int extraDamageAmount = GenMath.RoundRandom(extraDamage.AdjustedDamageAmount(this, base.CasterPawn));
             *                          float extraDamageArmorPenetration = extraDamage.AdjustedArmorPenetration(this, base.CasterPawn);
             *                          def = extraDamage.def;
             *                          num2 = (float)extraDamageAmount;
             *                          num = extraDamageArmorPenetration;
             *                          caster = this.caster;
             *                          DamageInfo extraDinfo = new DamageInfo(def, num2, num, -1f, caster, null, source, DamageInfo.SourceCategory.ThingOrUnknown, null);
             *                          extraDinfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside);
             *                          extraDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
             *                          extraDinfo.SetWeaponHediff(hediffDef);
             *                          extraDinfo.SetAngle(direction);
             *                          yield return extraDinfo;
             *                  }
             *          }
             */
            //END 1:1 COPY
            // Apply critical damage
            if (isCrit && !CasterPawn.def.race.Animal && !(verbProps.meleeDamageDef.armorCategory == DamageArmorCategoryDefOf.Sharp))
            {
                var critAmount = GenMath.RoundRandom(mainDinfo.Amount * 0.25f);
                var critDinfo  = new DamageInfo(DamageDefOf.Stun, critAmount, armorPenetration, //Ignore armor //armorPenetration, //Armor Penetration
                                                -1, caster, null, source);
                critDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside);
                critDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
                critDinfo.SetWeaponHediff(hediffDef);
                critDinfo.SetAngle(direction);
                yield return(critDinfo);
            }
        }
Beispiel #18
0
        /// <summary>
        /// Calculates primary DamageInfo from verb, as well as secondary DamageInfos to apply (i.e. surprise attack stun damage).
        /// Also calculates the maximum body height an attack can target, so we don't get rabbits biting out a colonist's eye or something.
        /// </summary>
        /// <param name="target">The target damage is to be applied to</param>
        /// <returns>Collection with primary DamageInfo, followed by secondary types</returns>
        private IEnumerable <DamageInfo> DamageInfosToApply(LocalTargetInfo target, bool isCrit = false)
        {
            //START 1:1 COPY Verb_MeleeAttack.DamageInfosToApply
            float damAmount    = this.verbProps.AdjustedMeleeDamageAmount(this, base.CasterPawn);
            var   critModifier = isCrit && verbProps.meleeDamageDef.armorCategory == DamageArmorCategoryDefOf.Sharp &&
                                 !CasterPawn.def.race.Animal
                ? 2
                : 1;
            var              armorPenetration = verbProps.AdjustedArmorPenetration(this, CasterPawn) * (EquipmentSource?.GetStatValue(CE_StatDefOf.MeleePenetrationFactor) ?? 1) * critModifier;
            DamageDef        damDef           = verbProps.meleeDamageDef;
            BodyPartGroupDef bodyPartGroupDef = null;
            HediffDef        hediffDef        = null;

            damAmount = Rand.Range(damAmount * 0.8f, damAmount * 1.2f);
            if (base.CasterIsPawn)
            {
                bodyPartGroupDef = this.verbProps.AdjustedLinkedBodyPartsGroup(this.tool);
                if (damAmount >= 1f)
                {
                    if (base.HediffCompSource != null)
                    {
                        hediffDef = base.HediffCompSource.Def;
                    }
                }
                else
                {
                    damAmount = 1f;
                    damDef    = DamageDefOf.Blunt;
                }
            }
            ThingDef source;

            if (base.EquipmentSource != null)
            {
                source = base.EquipmentSource.def;
            }
            else
            {
                source = base.CasterPawn.def;
            }
            Vector3   direction = (target.Thing.Position - base.CasterPawn.Position).ToVector3();
            DamageDef def       = damDef;
            //END 1:1 COPY
            BodyPartHeight bodyRegion = GetBodyPartHeightFor(target);                                                                                           //Custom // Add check for body height
            //START 1:1 COPY
            DamageInfo mainDinfo = new DamageInfo(def, damAmount, armorPenetration, -1f, caster, null, source, DamageInfo.SourceCategory.ThingOrUnknown, null); //Alteration

            mainDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside);                                                                                         //Alteration
            mainDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
            mainDinfo.SetWeaponHediff(hediffDef);
            mainDinfo.SetAngle(direction);
            yield return(mainDinfo);

            // Apply critical damage
            if (isCrit && !CasterPawn.def.race.Animal && verbProps.meleeDamageDef.armorCategory != DamageArmorCategoryDefOf.Sharp)
            {
                var critAmount = GenMath.RoundRandom(mainDinfo.Amount * 0.25f);
                var critDinfo  = new DamageInfo(DamageDefOf.Stun, critAmount, armorPenetration, //Ignore armor //armorPenetration, //Armor Penetration
                                                -1, caster, null, source);
                critDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside);
                critDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
                critDinfo.SetWeaponHediff(hediffDef);
                critDinfo.SetAngle(direction);
                yield return(critDinfo);
            }
        }
 public void SetBodyRegion(BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined)
 {
     this.heightInt = height;
     this.depthInt  = depth;
 }
Beispiel #20
0
        public static IEnumerable <BodyPartRecord> GetNotMissingParts(this HediffSet set, BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined, List <BodyPartTagDef> tags = null, BodyPartRecord partParent = null)
        {
            List <BodyPartRecord> allPartsList = set.pawn.def.race.body.AllParts;
            int num;

            for (int i = 0; i < allPartsList.Count; i = num + 1)
            {
                BodyPartRecord bodyPartRecord = allPartsList[i];
                if (!set.PartIsMissing(bodyPartRecord) && (height == BodyPartHeight.Undefined || bodyPartRecord.height == height) && (depth == BodyPartDepth.Undefined || bodyPartRecord.depth == depth) && (tags == null || bodyPartRecord.def.tags.Any(x => tags.Contains(x))) && (partParent == null || bodyPartRecord.parent == partParent))
                {
                    yield return(bodyPartRecord);
                }
                num = i;
            }
            yield break;
        }
 public static BodyPartRecord RerollBodyPart(TargetingModeDef targetingMode, BodyPartRecord bodyPart, DamageDef damDef, BodyPartHeight height, BodyPartDepth depth, Pawn pawn, Thing instigator)
 {
     for (int i = 0; i < targetingMode.RerollCount(pawn, instigator); i++)
     {
         BodyPartRecord newPart = pawn.health.hediffSet.GetRandomNotMissingPart(damDef, height, depth);
         if (newPart.IsPrioritizedPart(targetingMode))
         {
             return(newPart);
         }
     }
     return(bodyPart);
 }
        /// <summary>
        /// Calculates primary DamageInfo from verb, as well as secondary DamageInfos to apply (i.e. surprise attack stun damage).
        /// Also calculates the maximum body height an attack can target, so we don't get rabbits biting out a colonist's eye or something.
        /// </summary>
        /// <param name="target">The target damage is to be applied to</param>
        /// <returns>Collection with primary DamageInfo, followed by secondary types</returns>
        private IEnumerable <DamageInfo> DamageInfosToApply(LocalTargetInfo target, bool isCrit = false)
        {
            float            damAmount        = (float)this.verbProps.AdjustedMeleeDamageAmount(this, base.CasterPawn);
            float            armorPenetration = this.verbProps.AdjustedArmorPenetration(this, base.CasterPawn);
            var              critDamDef       = CritDamageDef;
            DamageDef        damDef           = isCrit && critDamDef != DamageDefOf.Stun ? critDamDef : verbProps.meleeDamageDef; //Added isCrit check
            BodyPartGroupDef bodyPartGroupDef = null;
            HediffDef        hediffDef        = null;

            damAmount = UnityEngine.Random.Range(damAmount * 0.8f, damAmount * 1.2f);

            var verbpropsCE = this.verbProps as VerbPropertiesCE;

            if (base.CasterIsPawn)
            {
                bodyPartGroupDef = verbpropsCE.AdjustedLinkedBodyPartsGroupCE(this.tool as ToolCE);
                if (damAmount >= 1f)
                {
                    if (this.HediffCompSource != null)
                    {
                        hediffDef = this.HediffCompSource.Def;
                    }
                }
                else
                {
                    damAmount = 1f;
                    damDef    = DamageDefOf.Blunt;
                }
            }
            ThingDef source;

            if (this.EquipmentSource != null)
            {
                source = this.EquipmentSource.def;
            }
            else
            {
                source = base.CasterPawn.def;
            }
            Vector3        direction  = (target.Thing.Position - base.CasterPawn.Position).ToVector3();
            Thing          caster     = this.caster;
            float          num        = GenMath.RoundRandom(damAmount);
            float          num2       = isCrit ? armorPenetration * 2: armorPenetration;
            BodyPartHeight bodyRegion = GetBodyPartHeightFor(target);   // Add check for body height
            DamageInfo     mainDinfo  = new DamageInfo(damDef, num, num2, -1f, caster, null, source, DamageInfo.SourceCategory.ThingOrUnknown, null);

            mainDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside);
            mainDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
            mainDinfo.SetWeaponHediff(hediffDef);
            mainDinfo.SetAngle(direction);
            yield return(mainDinfo);

            // Apply secondary damage on surprise attack

            /*
             * if (!surpriseAttack
             || ((verbProps.surpriseAttack == null || verbProps.surpriseAttack.extraMeleeDamages.NullOrEmpty<ExtraMeleeDamage>())
             ||         && tool != null
             ||         && tool.surpriseAttack != null
             ||         && !tool.surpriseAttack.extraMeleeDamages.NullOrEmpty<ExtraMeleeDamage>())
             ||)
             ||{
             || IEnumerable<ExtraMeleeDamage> extraDamages = Enumerable.Empty<ExtraMeleeDamage>();
             || if (verbProps.surpriseAttack != null && verbProps.surpriseAttack.extraMeleeDamages != null)
             || {
             ||     extraDamages = extraDamages.Concat(tool.surpriseAttack.extraMeleeDamages);
             || }
             || if (tool != null && tool.surpriseAttack != null && !tool.surpriseAttack.extraMeleeDamages.NullOrEmpty<ExtraMeleeDamage>())
             || {
             ||     extraDamages = extraDamages.Concat(tool.surpriseAttack.extraMeleeDamages);
             || }
             || foreach (ExtraMeleeDamage extraDamage in extraDamages)
             || {
             ||     int amount = GenMath.RoundRandom((float)extraDamage.amount * base.GetDamageFactorFor(base.CasterPawn));
             ||     DamageInfo extraDinfo = new DamageInfo(extraDamage.def, amount, -1f, this.caster, null, source);
             ||     extraDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside);
             ||     extraDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
             ||     extraDinfo.SetWeaponHediff(hediffDef);
             ||     extraDinfo.SetAngle(direction);
             ||     yield return extraDinfo;
             || }
             ||}
             */

            // Apply critical damage
            if (isCrit && critDamDef == DamageDefOf.Stun)
            {
                var critAmount = GenMath.RoundRandom(mainDinfo.Amount * 0.25f);
                var critDinfo  = new DamageInfo(critDamDef, critAmount, armorPenetration, -1, caster, null, source);
                critDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside);
                critDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
                critDinfo.SetWeaponHediff(hediffDef);
                critDinfo.SetAngle(direction);
                yield return(critDinfo);
            }
        }
        /// <summary>
        /// Calculates primary DamageInfo from verb, as well as secondary DamageInfos to apply (i.e. surprise attack stun damage).
        /// Also calculates the maximum body height an attack can target, so we don't get rabbits biting out a colonist's eye or something.
        /// </summary>
        /// <param name="target">The target damage is to be applied to</param>
        /// <returns>Collection with primary DamageInfo, followed by secondary types</returns>
        private IEnumerable <DamageInfo> DamageInfosToApply(LocalTargetInfo target, bool isCrit = false)
        {
            //START 1:1 COPY Verb_MeleeAttack.DamageInfosToApply
            float damAmount    = verbProps.AdjustedMeleeDamageAmount(this, CasterPawn);
            var   critModifier = isCrit && verbProps.meleeDamageDef.armorCategory == DamageArmorCategoryDefOf.Sharp &&
                                 !CasterPawn.def.race.Animal
                ? 2
                : 1;
            var              armorPenetration = (verbProps.meleeDamageDef.armorCategory == DamageArmorCategoryDefOf.Sharp ? ArmorPenetrationSharp : ArmorPenetrationBlunt) * critModifier;
            DamageDef        damDef           = verbProps.meleeDamageDef;
            BodyPartGroupDef bodyPartGroupDef = null;
            HediffDef        hediffDef        = null;

            if (EquipmentSource != null)
            {
                //melee weapon damage variation
                damAmount *= Rand.Range(StatWorker_MeleeDamage.GetDamageVariationMin(CasterPawn), StatWorker_MeleeDamage.GetDamageVariationMax(CasterPawn));
            }
            else if (!CE_StatDefOf.UnarmedDamage.Worker.IsDisabledFor(CasterPawn))  //ancient soldiers can punch even if non-violent, this prevents the disabled stat from being used
            {
                //unarmed damage bonus offset
                damAmount += CasterPawn.GetStatValue(CE_StatDefOf.UnarmedDamage);
            }

            if (CasterIsPawn)
            {
                bodyPartGroupDef = verbProps.AdjustedLinkedBodyPartsGroup(tool);
                if (damAmount >= 1f)
                {
                    if (HediffCompSource != null)
                    {
                        hediffDef = HediffCompSource.Def;
                    }
                }
                else
                {
                    damAmount = 1f;
                    damDef    = DamageDefOf.Blunt;
                }
            }

            var       source    = EquipmentSource != null ? EquipmentSource.def : CasterPawn.def;
            Vector3   direction = (target.Thing.Position - CasterPawn.Position).ToVector3();
            DamageDef def       = damDef;
            //END 1:1 COPY
            BodyPartHeight bodyRegion = GetBodyPartHeightFor(target);                                                                                           //Custom // Add check for body height
            //START 1:1 COPY
            DamageInfo mainDinfo = new DamageInfo(def, damAmount, armorPenetration, -1f, caster, null, source, DamageInfo.SourceCategory.ThingOrUnknown, null); //Alteration

            // Predators get a neck bite on immobile targets
            if (caster.def.race.predator && IsTargetImmobile(target) && target.Thing is Pawn pawn)
            {
                var neck = pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Top, BodyPartDepth.Outside)
                           .FirstOrDefault(r => r.def == BodyPartDefOf.Neck);
                mainDinfo.SetHitPart(neck);
            }

            mainDinfo.SetBodyRegion(bodyRegion); //Alteration
            mainDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
            mainDinfo.SetWeaponHediff(hediffDef);
            mainDinfo.SetAngle(direction);
            yield return(mainDinfo);

            DamageInfo damageInfo = new DamageInfo(def, damAmount, armorPenetration, -1f, this.caster, null, source, DamageInfo.SourceCategory.ThingOrUnknown, null);

            damageInfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside);
            damageInfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
            damageInfo.SetWeaponHediff(hediffDef);
            damageInfo.SetAngle(direction);
            yield return(damageInfo);

            if (this.tool != null && this.tool.extraMeleeDamages != null)
            {
                foreach (ExtraDamage extraDamage in this.tool.extraMeleeDamages)
                {
                    if (Rand.Chance(extraDamage.chance))
                    {
                        damAmount  = extraDamage.amount;
                        damAmount  = Rand.Range(damAmount * 0.8f, damAmount * 1.2f);
                        damageInfo = new DamageInfo(extraDamage.def, damAmount, extraDamage.AdjustedArmorPenetration(this, this.CasterPawn), -1f, this.caster, null, source, DamageInfo.SourceCategory.ThingOrUnknown, null);
                        damageInfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside);
                        damageInfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
                        damageInfo.SetWeaponHediff(hediffDef);
                        damageInfo.SetAngle(direction);
                        yield return(damageInfo);
                    }
                }
                List <ExtraDamage> .Enumerator enumerator = default(List <ExtraDamage> .Enumerator);
            }

            // Apply critical damage
            if (isCrit && !CasterPawn.def.race.Animal && verbProps.meleeDamageDef.armorCategory != DamageArmorCategoryDefOf.Sharp && target.Thing.def.race.IsFlesh)
            {
                var critAmount = GenMath.RoundRandom(mainDinfo.Amount * 0.25f);
                var critDinfo  = new DamageInfo(DamageDefOf.Stun, critAmount, armorPenetration,
                                                -1, caster, null, source);
                critDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside);
                critDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef);
                critDinfo.SetWeaponHediff(hediffDef);
                critDinfo.SetAngle(direction);
                yield return(critDinfo);
            }
        }