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; }
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(); }
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(); }
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; } } }
/// <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++; } }
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); } }
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); } }
/// <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); } }
/// <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; }
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); } }