public BattleLogEntry_ExplosionImpact(Thing initiator, Thing recipient, ThingDef weaponDef, ThingDef projectileDef, DamageDef damageDef) { if (initiator is Pawn) { this.initiatorPawn = (initiator as Pawn); } else if (initiator != null) { this.initiatorThing = initiator.def; } if (recipient is Pawn) { this.recipientPawn = (recipient as Pawn); } else if (recipient != null) { this.recipientThing = recipient.def; } this.weaponDef = weaponDef; this.projectileDef = projectileDef; this.damageDef = damageDef; }
public static void DamageUntilDead(Pawn p) { HediffSet hediffSet = p.health.hediffSet; int num = 0; while (!p.Dead && num < 200 && HealthUtility.HittablePartsViolence(hediffSet).Any()) { num++; BodyPartRecord bodyPartRecord = HealthUtility.HittablePartsViolence(hediffSet).RandomElementByWeight((BodyPartRecord x) => x.coverageAbs); int num2 = Rand.RangeInclusive(8, 25); DamageDef damageDef = (bodyPartRecord.depth != BodyPartDepth.Outside) ? DamageDefOf.Blunt : HealthUtility.RandomViolenceDamageType(); DamageDef def = damageDef; int amount = num2; BodyPartRecord hitPart = bodyPartRecord; DamageInfo dinfo = new DamageInfo(def, amount, -1f, null, hitPart, null, DamageInfo.SourceCategory.ThingOrUnknown); p.TakeDamage(dinfo); } if (!p.Dead) { Log.Error(p + " not killed during GiveInjuriesToKill"); } }
private static List <DebugMenuOption> Options_Damage_BodyParts(Pawn p, DamageDef def) { if (p == null) { throw new ArgumentNullException("p"); } List <DebugMenuOption> list = new List <DebugMenuOption>(); list.Add(new DebugMenuOption("(no body part)", DebugMenuOptionMode.Action, delegate { p.TakeDamage(new DamageInfo(def, 5f)); })); foreach (BodyPartRecord allPart in p.RaceProps.body.AllParts) { BodyPartRecord localPart = allPart; list.Add(new DebugMenuOption(localPart.LabelCap, DebugMenuOptionMode.Action, delegate { p.TakeDamage(new DamageInfo(def, 5f, 0f, -1f, null, localPart)); })); } return(list); }
public float GetHitChanceFactorFor(DamageDef damage) { float result; float num; if (this.conceptual) { result = 0f; } else if (this.hitChanceFactors == null) { result = 1f; } else if (this.hitChanceFactors.TryGetValue(damage, out num)) { result = num; } else { result = 1f; } return(result); }
public static void DamageUntilDead(Pawn p) { HediffSet hediffSet = p.health.hediffSet; int num = 0; while (!p.Dead && num < 200 && HittablePartsViolence(hediffSet).Any()) { num++; BodyPartRecord bodyPartRecord = HittablePartsViolence(hediffSet).RandomElementByWeight((BodyPartRecord x) => x.coverageAbs); int num2 = Rand.RangeInclusive(8, 25); DamageDef damageDef = (bodyPartRecord.depth != BodyPartDepth.Outside) ? DamageDefOf.Blunt : RandomViolenceDamageType(); DamageDef def = damageDef; float amount = (float)num2; float armorPenetration = 999f; BodyPartRecord hitPart = bodyPartRecord; DamageInfo dinfo = new DamageInfo(def, amount, armorPenetration, -1f, null, hitPart); p.TakeDamage(dinfo); } if (!p.Dead) { Log.Error(p + " not killed during GiveInjuriesToKill"); } }
public DamageInfo(DamageDef def, int amount, float angle = -1f, Thing instigator = null, BodyPartRecord hitPart = null, ThingDef weapon = null, SourceCategory category = SourceCategory.ThingOrUnknown) { this.defInt = def; this.amountInt = amount; if (angle < 0.0) { 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.instantOldInjuryInt = false; this.allowDamagePropagationInt = true; }
public static void DamageLegsUntilIncapableOfMoving(Pawn p, bool allowBleedingWounds = true) { int num = 0; p.health.forceIncap = true; while (p.health.capacities.CapableOf(PawnCapacityDefOf.Moving) && num < 300) { num++; IEnumerable <BodyPartRecord> source = from x in p.health.hediffSet.GetNotMissingParts() where x.def.tags.Contains(BodyPartTagDefOf.MovingLimbCore) && p.health.hediffSet.GetPartHealth(x) >= 2f select x; if (!source.Any()) { break; } BodyPartRecord bodyPartRecord = source.RandomElement(); float maxHealth = bodyPartRecord.def.GetMaxHealth(p); float partHealth = p.health.hediffSet.GetPartHealth(bodyPartRecord); int min = Mathf.Clamp(Mathf.RoundToInt(maxHealth * 0.12f), 1, (int)partHealth - 1); int max = Mathf.Clamp(Mathf.RoundToInt(maxHealth * 0.27f), 1, (int)partHealth - 1); int num2 = Rand.RangeInclusive(min, max); DamageDef damageDef = (allowBleedingWounds || !(bodyPartRecord.def.bleedRate > 0f)) ? RandomViolenceDamageType() : DamageDefOf.Blunt; HediffDef hediffDefFromDamage = GetHediffDefFromDamage(damageDef, p, bodyPartRecord); if (p.health.WouldDieAfterAddingHediff(hediffDefFromDamage, bodyPartRecord, (float)num2)) { break; } DamageDef def = damageDef; float amount = (float)num2; float armorPenetration = 999f; BodyPartRecord hitPart = bodyPartRecord; DamageInfo dinfo = new DamageInfo(def, amount, armorPenetration, -1f, null, hitPart); dinfo.SetAllowDamagePropagation(val: false); p.TakeDamage(dinfo); } p.health.forceIncap = false; }
public static int GetPostArmorDamage(Pawn pawn, int amountInt, BodyPartRecord part, DamageDef damageDef) { float num = (float)amountInt; if (damageDef.armorCategory == null) { return(amountInt); } StatDef deflectionStat = damageDef.armorCategory.deflectionStat; if (pawn.apparel != null) { List <Apparel> wornApparel = pawn.apparel.WornApparel; for (int i = 0; i < wornApparel.Count; i++) { Apparel apparel = wornApparel[i]; if (apparel.def.apparel.CoversBodyPart(part)) { ArmorUtility.ApplyArmor(ref num, apparel.GetStatValue(deflectionStat, true), apparel, damageDef); if (num < 0.001f) { return(0); } } } } ArmorUtility.ApplyArmor(ref num, pawn.GetStatValue(deflectionStat, true), null, damageDef); return(GenMath.RoundRandom(num)); }
private static void ApplyArmor(ref float damAmount, float armorRating, Thing armorThing, DamageDef damageDef) { float num; float num2; if ((double)armorRating <= 0.5) { num = armorRating; num2 = 0f; } else if (armorRating < 1f) { num = 0.5f; num2 = armorRating - 0.5f; } else { num = 0.5f + (armorRating - 1f) * 0.25f; num2 = 0.5f + (armorRating - 1f) * 0.25f; } if (num > 0.9f) { num = 0.9f; } if (num2 > 0.9f) { num2 = 0.9f; } float num3; if (Rand.Value < num2) { num3 = damAmount; } else { num3 = damAmount * num; } if (armorThing != null) { float f = damAmount * 0.25f; armorThing.TakeDamage(new DamageInfo(damageDef, GenMath.RoundRandom(f), -1f, null, null, null, DamageInfo.SourceCategory.ThingOrUnknown)); } damAmount -= num3; }
private static void DropRoofInCellPhaseOne(IntVec3 c, Map map, List <Thing> outCrushedThings) { RoofDef roofDef = map.roofGrid.RoofAt(c); if (roofDef == null) { return; } if (roofDef.collapseLeavingThingDef != null && roofDef.collapseLeavingThingDef.passability == Traversability.Impassable) { for (int i = 0; i < 2; i++) { List <Thing> thingList = c.GetThingList(map); for (int j = thingList.Count - 1; j >= 0; j--) { Thing thing = thingList[j]; RoofCollapserImmediate.TryAddToCrushedThingsList(thing, outCrushedThings); Pawn pawn = thing as Pawn; DamageInfo dinfo; if (pawn != null) { DamageDef crush = DamageDefOf.Crush; float amount = 99999f; float armorPenetration = 999f; BodyPartRecord brain = pawn.health.hediffSet.GetBrain(); dinfo = new DamageInfo(crush, amount, armorPenetration, -1f, null, brain, null, DamageInfo.SourceCategory.Collapse, null); } else { dinfo = new DamageInfo(DamageDefOf.Crush, 99999f, 999f, -1f, null, null, null, DamageInfo.SourceCategory.Collapse, null); dinfo.SetBodyRegion(BodyPartHeight.Top, BodyPartDepth.Outside); } BattleLogEntry_DamageTaken battleLogEntry_DamageTaken = null; if (i == 0 && pawn != null) { battleLogEntry_DamageTaken = new BattleLogEntry_DamageTaken(pawn, RulePackDefOf.DamageEvent_Ceiling, null); Find.BattleLog.Add(battleLogEntry_DamageTaken); } thing.TakeDamage(dinfo).AssociateWithLog(battleLogEntry_DamageTaken); if (!thing.Destroyed && thing.def.destroyable) { thing.Kill(new DamageInfo?(new DamageInfo(DamageDefOf.Crush, 99999f, 999f, -1f, null, null, null, DamageInfo.SourceCategory.Collapse, null)), null); } } } } else { List <Thing> thingList2 = c.GetThingList(map); for (int k = thingList2.Count - 1; k >= 0; k--) { Thing thing2 = thingList2[k]; if (thing2.def.category == ThingCategory.Item || thing2.def.category == ThingCategory.Plant || thing2.def.category == ThingCategory.Building || thing2.def.category == ThingCategory.Pawn) { RoofCollapserImmediate.TryAddToCrushedThingsList(thing2, outCrushedThings); float num = (float)RoofCollapserImmediate.ThinRoofCrushDamageRange.RandomInRange; if (thing2.def.building != null) { num *= thing2.def.building.roofCollapseDamageMultiplier; } BattleLogEntry_DamageTaken battleLogEntry_DamageTaken2 = null; if (thing2 is Pawn) { battleLogEntry_DamageTaken2 = new BattleLogEntry_DamageTaken((Pawn)thing2, RulePackDefOf.DamageEvent_Ceiling, null); Find.BattleLog.Add(battleLogEntry_DamageTaken2); } DamageInfo dinfo2 = new DamageInfo(DamageDefOf.Crush, (float)GenMath.RoundRandom(num), 0f, -1f, null, null, null, DamageInfo.SourceCategory.Collapse, null); dinfo2.SetBodyRegion(BodyPartHeight.Top, BodyPartDepth.Outside); thing2.TakeDamage(dinfo2).AssociateWithLog(battleLogEntry_DamageTaken2); } } } if (roofDef.collapseLeavingThingDef != null) { Thing thing3 = GenSpawn.Spawn(roofDef.collapseLeavingThingDef, c, map, WipeMode.Vanish); if (thing3.def.rotatable) { thing3.Rotation = Rot4.Random; } } for (int l = 0; l < 1; l++) { Vector3 vector = c.ToVector3Shifted(); vector += Gen.RandomHorizontalVector(0.6f); MoteMaker.ThrowDustPuff(vector, map, 2f); } }
public static void DamageUntilDowned(Pawn p, bool allowBleedingWounds = true) { if (p.health.Downed) { return; } HediffSet hediffSet = p.health.hediffSet; p.health.forceIncap = true; IEnumerable <BodyPartRecord> source = from x in HealthUtility.HittablePartsViolence(hediffSet) where !p.health.hediffSet.hediffs.Any((Hediff y) => y.Part == x && y.CurStage != null && y.CurStage.partEfficiencyOffset < 0f) select x; int num = 0; while (num < 300 && !p.Downed && source.Any <BodyPartRecord>()) { num++; BodyPartRecord bodyPartRecord = source.RandomElementByWeight((BodyPartRecord x) => x.coverageAbs); int num2 = Mathf.RoundToInt(hediffSet.GetPartHealth(bodyPartRecord)) - 3; if (num2 >= 8) { DamageDef damageDef; if (bodyPartRecord.depth == BodyPartDepth.Outside) { if (!allowBleedingWounds && bodyPartRecord.def.bleedRate > 0f) { damageDef = DamageDefOf.Blunt; } else { damageDef = HealthUtility.RandomViolenceDamageType(); } } else { damageDef = DamageDefOf.Blunt; } int num3 = Rand.RangeInclusive(Mathf.RoundToInt((float)num2 * 0.65f), num2); HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(damageDef, p, bodyPartRecord); if (!p.health.WouldDieAfterAddingHediff(hediffDefFromDamage, bodyPartRecord, (float)num3)) { DamageDef def = damageDef; float amount = (float)num3; float armorPenetration = 999f; BodyPartRecord hitPart = bodyPartRecord; DamageInfo dinfo = new DamageInfo(def, amount, armorPenetration, -1f, null, hitPart, null, DamageInfo.SourceCategory.ThingOrUnknown, null); dinfo.SetAllowDamagePropagation(false); p.TakeDamage(dinfo); } } } if (p.Dead) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(p + " died during GiveInjuriesToForceDowned"); for (int i = 0; i < p.health.hediffSet.hediffs.Count; i++) { stringBuilder.AppendLine(" -" + p.health.hediffSet.hediffs[i].ToString()); } Log.Error(stringBuilder.ToString(), false); } p.health.forceIncap = false; }
public static bool HarmsHealth(this Verb verb) { DamageDef damageDef = verb.GetDamageDef(); return(damageDef != null && damageDef.harmsHealth); }
private static void ApplyArmor(ref float damAmount, float armorRating, Thing armorThing, DamageDef damageDef) { float num; float num2; if ((double)armorRating <= 0.5) { num = armorRating; num2 = 0f; } else if (armorRating < 1.0) { num = 0.5f; num2 = (float)(armorRating - 0.5); } else { num = (float)(0.5 + (armorRating - 1.0) * 0.25); num2 = (float)(0.5 + (armorRating - 1.0) * 0.25); } if (num > 0.89999997615814209) { num = 0.9f; } if (num2 > 0.89999997615814209) { num2 = 0.9f; } float num3 = (!(Rand.Value < num2)) ? (damAmount * num) : damAmount; if (armorThing != null) { float f = (float)(damAmount * 0.25); armorThing.TakeDamage(new DamageInfo(damageDef, GenMath.RoundRandom(f), -1f, null, null, null, DamageInfo.SourceCategory.ThingOrUnknown)); } damAmount -= num3; }
public float AdjustedBaseMeleeDamageAmount_NewTmp(ThingDef ownerEquipment, ThingDef ownerEquipmentStuff, DamageDef damageDef) { float num = power; if (ownerEquipmentStuff != null) { num *= ownerEquipment.GetStatValueAbstract(StatDefOf.MeleeWeapon_DamageMultiplier, ownerEquipmentStuff); if (ownerEquipmentStuff != null && damageDef != null) { num *= ownerEquipmentStuff.GetStatValueAbstract(damageDef.armorCategory.multStat); } } return(num); }
protected virtual void ExplosionDamageThing(Explosion explosion, Thing t, List <Thing> damagedThings, IntVec3 cell) { if (t.def.category == ThingCategory.Mote || t.def.category == ThingCategory.Ethereal) { return; } if (damagedThings.Contains(t)) { return; } damagedThings.Add(t); if (this.def == DamageDefOf.Bomb && t.def == ThingDefOf.Fire && !t.Destroyed) { t.Destroy(DestroyMode.Vanish); return; } float num; if (t.Position == explosion.Position) { num = (float)Rand.RangeInclusive(0, 359); } else { num = (t.Position - explosion.Position).AngleFlat; } DamageDef damageDef = this.def; float amount = (float)explosion.GetDamageAmountAt(cell); float armorPenetrationAt = explosion.GetArmorPenetrationAt(cell); float angle = num; Thing instigator = explosion.instigator; ThingDef weapon = explosion.weapon; DamageInfo dinfo = new DamageInfo(damageDef, amount, armorPenetrationAt, angle, instigator, null, weapon, DamageInfo.SourceCategory.ThingOrUnknown, explosion.intendedTarget); if (this.def.explosionAffectOutsidePartsOnly) { dinfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside); } if (t.def.category == ThingCategory.Building) { int num2 = Mathf.RoundToInt(dinfo.Amount * this.def.explosionBuildingDamageFactor); dinfo.SetAmount((float)num2); } else if (t.def.category == ThingCategory.Plant) { int num3 = Mathf.RoundToInt(dinfo.Amount * this.def.explosionPlantDamageFactor); dinfo.SetAmount((float)num3); } BattleLogEntry_ExplosionImpact battleLogEntry_ExplosionImpact = null; Pawn pawn = t as Pawn; if (pawn != null) { battleLogEntry_ExplosionImpact = new BattleLogEntry_ExplosionImpact(explosion.instigator, t, explosion.weapon, explosion.projectile, this.def); Find.BattleLog.Add(battleLogEntry_ExplosionImpact); } DamageWorker.DamageResult damageResult = t.TakeDamage(dinfo); damageResult.AssociateWithLog(battleLogEntry_ExplosionImpact); if (pawn != null && damageResult.wounded && pawn.stances != null) { pawn.stances.StaggerFor(95); } }
public static float GetPostArmorDamage(Pawn pawn, float amount, float armorPenetration, BodyPartRecord part, ref DamageDef damageDef, out bool deflectedByMetalArmor, out bool diminishedByMetalArmor) { deflectedByMetalArmor = false; diminishedByMetalArmor = false; float result; if (damageDef.armorCategory == null) { result = amount; } else { StatDef armorRatingStat = damageDef.armorCategory.armorRatingStat; if (pawn.apparel != null) { List <Apparel> wornApparel = pawn.apparel.WornApparel; for (int i = wornApparel.Count - 1; i >= 0; i--) { Apparel apparel = wornApparel[i]; if (apparel.def.apparel.CoversBodyPart(part)) { float num = amount; bool flag; ArmorUtility.ApplyArmor(ref amount, armorPenetration, apparel.GetStatValue(armorRatingStat, true), apparel, ref damageDef, pawn, out flag); if (amount < 0.001f) { deflectedByMetalArmor = flag; return(0f); } if (amount < num && flag) { diminishedByMetalArmor = true; } } } } float num2 = amount; bool flag2; ArmorUtility.ApplyArmor(ref amount, armorPenetration, pawn.GetStatValue(armorRatingStat, true), null, ref damageDef, pawn, out flag2); if (amount < 0.001f) { deflectedByMetalArmor = flag2; result = 0f; } else { if (amount < num2 && flag2) { diminishedByMetalArmor = true; } result = amount; } } return(result); }
private static void ApplyArmor(ref float damAmount, float armorPenetration, float armorRating, Thing armorThing, ref DamageDef damageDef, Pawn pawn, out bool metalArmor) { if (armorThing != null) { metalArmor = (armorThing.def.apparel.useDeflectMetalEffect || (armorThing.Stuff != null && armorThing.Stuff.IsMetal)); } else { metalArmor = pawn.RaceProps.IsMechanoid; } if (armorThing != null) { float f = damAmount * 0.25f; armorThing.TakeDamage(new DamageInfo(damageDef, GenMath.RoundRandom(f))); } float num = Mathf.Max(armorRating - armorPenetration, 0f); float value = Rand.Value; float num2 = num * 0.5f; float num3 = num; if (value < num2) { damAmount = 0f; } else if (value < num3) { damAmount = GenMath.RoundRandom(damAmount / 2f); if (damageDef.armorCategory == DamageArmorCategoryDefOf.Sharp) { damageDef = DamageDefOf.Blunt; } } }
public static float GetPostArmorDamage(Pawn pawn, float amount, float armorPenetration, BodyPartRecord part, ref DamageDef damageDef, out bool deflectedByMetalArmor, out bool diminishedByMetalArmor) { deflectedByMetalArmor = false; diminishedByMetalArmor = false; if (damageDef.armorCategory == null) { return(amount); } StatDef armorRatingStat = damageDef.armorCategory.armorRatingStat; if (pawn.apparel != null) { List <Apparel> wornApparel = pawn.apparel.WornApparel; for (int num = wornApparel.Count - 1; num >= 0; num--) { Apparel apparel = wornApparel[num]; if (apparel.def.apparel.CoversBodyPart(part)) { float num2 = amount; ApplyArmor(ref amount, armorPenetration, apparel.GetStatValue(armorRatingStat), apparel, ref damageDef, pawn, out bool metalArmor); if (amount < 0.001f) { deflectedByMetalArmor = metalArmor; return(0f); } if (amount < num2 && metalArmor) { diminishedByMetalArmor = true; } } } } float num3 = amount; ApplyArmor(ref amount, armorPenetration, pawn.GetStatValue(armorRatingStat), null, ref damageDef, pawn, out bool metalArmor2); if (amount < 0.001f) { deflectedByMetalArmor = metalArmor2; return(0f); } if (amount < num3 && metalArmor2) { diminishedByMetalArmor = true; } return(amount); }
private static void DropRoofInCellPhaseOne(IntVec3 c, Map map) { RoofDef roofDef = map.roofGrid.RoofAt(c); if (roofDef != null) { if (roofDef.collapseLeavingThingDef != null && roofDef.collapseLeavingThingDef.passability == Traversability.Impassable) { for (int i = 0; i < 2; i++) { List <Thing> thingList = c.GetThingList(map); for (int num = thingList.Count - 1; num >= 0; num--) { Thing thing = thingList[num]; map.roofCollapseBuffer.Notify_Crushed(thing); Pawn pawn = thing as Pawn; DamageInfo dinfo = default(DamageInfo); if (pawn != null) { DamageDef crush = DamageDefOf.Crush; int amount = 99999; BodyPartRecord brain = pawn.health.hediffSet.GetBrain(); dinfo = new DamageInfo(crush, amount, -1f, null, brain, null, DamageInfo.SourceCategory.Collapse); } else { dinfo = new DamageInfo(DamageDefOf.Crush, 99999, -1f, null, null, null, DamageInfo.SourceCategory.Collapse); dinfo.SetBodyRegion(BodyPartHeight.Top, BodyPartDepth.Outside); } BattleLogEntry_DamageTaken battleLogEntry_DamageTaken = null; if (i == 0 && pawn != null) { battleLogEntry_DamageTaken = new BattleLogEntry_DamageTaken(pawn, RulePackDefOf.DamageEvent_Ceiling, null); Find.BattleLog.Add(battleLogEntry_DamageTaken); } thing.TakeDamage(dinfo).InsertIntoLog(battleLogEntry_DamageTaken); if (!thing.Destroyed && thing.def.destroyable) { thing.Destroy(DestroyMode.Vanish); } } } } else { List <Thing> thingList2 = c.GetThingList(map); for (int num2 = thingList2.Count - 1; num2 >= 0; num2--) { Thing thing2 = thingList2[num2]; if (thing2.def.category == ThingCategory.Item || thing2.def.category == ThingCategory.Plant || thing2.def.category == ThingCategory.Building || thing2.def.category == ThingCategory.Pawn) { map.roofCollapseBuffer.Notify_Crushed(thing2); float num3 = (float)RoofCollapserImmediate.ThinRoofCrushDamageRange.RandomInRange; if (thing2.def.building != null) { num3 *= thing2.def.building.roofCollapseDamageMultiplier; } BattleLogEntry_DamageTaken battleLogEntry_DamageTaken2 = null; if (thing2 is Pawn) { battleLogEntry_DamageTaken2 = new BattleLogEntry_DamageTaken(thing2 as Pawn, RulePackDefOf.DamageEvent_Ceiling, null); Find.BattleLog.Add(battleLogEntry_DamageTaken2); } DamageInfo dinfo2 = new DamageInfo(DamageDefOf.Crush, GenMath.RoundRandom(num3), -1f, null, null, null, DamageInfo.SourceCategory.Collapse); dinfo2.SetBodyRegion(BodyPartHeight.Top, BodyPartDepth.Outside); thing2.TakeDamage(dinfo2).InsertIntoLog(battleLogEntry_DamageTaken2); } } } if (roofDef.collapseLeavingThingDef != null) { Thing thing3 = GenSpawn.Spawn(roofDef.collapseLeavingThingDef, c, map); if (thing3.def.rotatable) { thing3.Rotation = Rot4.Random; } } for (int j = 0; j < 1; j++) { Vector3 a = c.ToVector3Shifted(); a += Gen.RandomHorizontalVector(0.6f); MoteMaker.ThrowDustPuff(a, map, 2f); } } }