public static void AdjustedCooldown_RapidFire_Postfix(ref Verb_Shoot __instance, Verb ownerVerb, Pawn attacker, ref float __result) { bool RapidFire = false; if (ownerVerb.EquipmentSource != null) { // Log.Message("ownerVerb.EquipmentSource"); if (!ownerVerb.EquipmentSource.AllComps.NullOrEmpty()) { if (ownerVerb.EquipmentSource.GetComp <CompWeapon_GunSpecialRules>() != null) { if (ownerVerb.EquipmentSource.GetComp <CompWeapon_GunSpecialRules>() is CompWeapon_GunSpecialRules GunExt) { RapidFire = GunExt.RapidFire; } } } } if (ownerVerb.HediffCompSource != null && !ownerVerb.IsMeleeAttack) { // Log.Message("ownerVerb.HediffCompSource"); HediffComp_VerbGiverExtra _VGE = (HediffComp_VerbGiverExtra)ownerVerb.HediffCompSource; RapidFire = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(ownerVerb.verbProps)].RapidFire; } if (RapidFire && AMASettings.Instance.AllowRapidFire) { if (ownerVerb.caster.Position.InHorDistOf(((Pawn)ownerVerb.caster).TargetCurrentlyAimingAt.Cell, ownerVerb.verbProps.range / 2)) { __result = __result / 2; } } }
public static void ShotsPerBurst_RapidFire_Postfix(ref Verb_Shoot __instance, ref int __result) { bool RapidFire = false; float RapidFireRange = 0; bool BodyBurstSize = false; if (__instance.EquipmentSource != null) { if (!__instance.EquipmentSource.AllComps.NullOrEmpty()) { if (__instance.EquipmentSource.GetComp <CompWeapon_GunSpecialRules>() != null) { if (__instance.EquipmentSource.GetComp <CompWeapon_GunSpecialRules>() is CompWeapon_GunSpecialRules GunExt) { RapidFire = GunExt.RapidFire; RapidFireRange = __instance.verbProps.range / 2; BodyBurstSize = GunExt.TyranidBurstBodySize; } } } } if (__instance.HediffCompSource != null) { HediffComp_VerbGiverExtra _VGE = (HediffComp_VerbGiverExtra)__instance.HediffCompSource; RapidFire = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].RapidFire; RapidFireRange = __instance.verbProps.range / 2; BodyBurstSize = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].TyranidBurstBodySize; } if (RapidFire && AMASettings.Instance.AllowRapidFire) { if (__instance.caster.Position.InHorDistOf(((Pawn)__instance.caster).TargetCurrentlyAimingAt.Cell, RapidFireRange)) { __result = __instance.verbProps.burstShotCount * 2; } } if (BodyBurstSize) { __result = __instance.verbProps.burstShotCount * (int)__instance.CasterPawn.BodySize; } }
public static bool Prefix(ProjectileCE __instance, Thing ___launcher, IntVec3 ___originInt, Vector2 ___origin, Vector2 ___destinationInt, int ___startingTicksToImpactInt, int ___ticksToImpact, int ___intTicksToImpact, ThingDef ___equipmentDef, ref float ___suppressionAmount, Thing hitThing) { if (hitThing != null) { bool Rending = false; float RendingChance = 0.167f; Pawn caster = ___launcher as Pawn; Thing Launcher = ___launcher; if (caster != null) { if (caster.equipment != null) { // Log.Warning(string.Format("___launcher: {0}", ___launcher)); if (caster.equipment.Primary != null) { // Log.Warning(string.Format("caster.equipment != null")); Launcher = caster.equipment.Primary; // Log.Warning(string.Format("Launcher = caster.equipment.Primary")); CompWeapon_GunSpecialRules _GunSpecialRules = Launcher.TryGetCompFast <CompWeapon_GunSpecialRules>(); if (_GunSpecialRules != null) { // Log.Warning(string.Format("_GunSpecialRules != null")); Rending = _GunSpecialRules.Rending; RendingChance = _GunSpecialRules.RendingChance; } } else { // Log.Warning(string.Format("caster.equipment == null")); if (caster.health.hediffSet.hediffs.Any(x => x.TryGetCompFast <HediffComp_VerbGiverExtra>() != null)) { // Log.Warning(string.Format("HediffComp_VerbGiverExtra: {0}", ___launcher)); HediffComp_VerbGiverExtra _VGE = caster.health.hediffSet.hediffs.Find(x => x.TryGetCompFast <HediffComp_VerbGiverExtra>() is HediffComp_VerbGiverExtra z && z.verbTracker.AllVerbs.Any(y => y.verbProps.defaultProjectile == __instance.def)).TryGetCompFast <HediffComp_VerbGiverExtra>(); if (_VGE != null) { // Log.Warning(string.Format("_VGE != null: {0}", _VGE.parent.LabelCap)); GunVerbEntry entry = _VGE.Props.verbEntrys.Find(x => x.VerbProps.defaultProjectile == __instance.def); if (entry != null) { // Log.Warning(string.Format("{0}, Rending: {1}, Chance: {2}", entry.VerbProps.label, entry.Rending, entry.RendingChance)); Rending = entry.Rending; RendingChance = entry.RendingChance; } } } } } } if (Rending) { // Log.Warning(string.Format("Rending: {0}", ___launcher)); Rand.PushState(); bool RendingEffect = Rand.Chance(RendingChance); Rand.PopState(); if (RendingEffect) { DamageDef damageDef = __instance.def.projectile.damageDef; DamageArmorCategoryDef armorCategory = damageDef.armorCategory != null ? damageDef.armorCategory: null; StatDef armorcatdef = damageDef.armorCategory != null ? armorCategory.armorRatingStat : null; float num = 0f; float num2 = Mathf.Clamp01((armorcatdef != null ? hitThing.GetStatValue(armorcatdef, true) : 0f) / 2f); if (hitThing is Pawn hitPawn) { List <BodyPartRecord> allParts = hitPawn.RaceProps.body.AllParts; List <Apparel> list = (hitPawn.apparel == null) ? null : hitPawn.apparel.WornApparel; for (int i = 0; i < allParts.Count; i++) { float num3 = 1f - num2; if (list != null) { for (int j = 0; j < list.Count; j++) { if (list[j].def.apparel.CoversBodyPart(allParts[i])) { float num4 = Mathf.Clamp01((armorcatdef != null ? list[j].GetStatValue(armorcatdef, true) : 0f) / 2f); num3 *= 1f - num4; } } } num += allParts[i].coverageAbs * (1f - num3); } } num = Mathf.Clamp(num * 2f, 0f, 2f); float armorPenetration = num; MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, "AdeptusMechanicus.Rending_Shot".Translate(__instance.LabelCap, hitThing.LabelShortCap), 3f); // Log.Warning(string.Format("ArmorPenetration: {0}", ArmorPenetration)); bool flag = ___launcher is AmmoThing; Map map = __instance.Map; LogEntry_DamageResult logEntry_DamageResult = null; bool flag2 = __instance.logMisses || (!__instance.logMisses && hitThing != null && (hitThing is Pawn || hitThing is Building_Turret)); if (flag2) { bool flag3 = !flag; if (flag3) { LogImpact(__instance, ___launcher, ___equipmentDef, hitThing, out logEntry_DamageResult); } } bool flag4 = hitThing != null; if (flag4) { int damageAmount = __instance.def.projectile.GetDamageAmount(1f, null); DamageDefExtensionCE damageDefExtensionCE = __instance.def.projectile.damageDef.GetModExtension <DamageDefExtensionCE>() ?? new DamageDefExtensionCE(); ProjectilePropertiesCE projectilePropertiesCE = (ProjectilePropertiesCE)__instance.def.projectile; // float armorPenetration = (this.def.projectile.damageDef.armorCategory == DamageArmorCategoryDefOf.Sharp) ? projectilePropertiesCE.armorPenetrationSharp : projectilePropertiesCE.armorPenetrationBlunt; DamageInfo damageInfo = new DamageInfo(__instance.def.projectile.damageDef, (float)damageAmount, armorPenetration, __instance.ExactRotation.eulerAngles.y, ___launcher, null, __instance.def, DamageInfo.SourceCategory.ThingOrUnknown, null); BodyPartDepth depth = (damageDefExtensionCE != null && damageDefExtensionCE.harmOnlyOutsideLayers) ? BodyPartDepth.Outside : BodyPartDepth.Undefined; BodyPartHeight collisionBodyHeight = new CollisionVertical(hitThing).GetCollisionBodyHeight(__instance.ExactPosition.y); damageInfo.SetBodyRegion(collisionBodyHeight, depth); bool flag5 = damageDefExtensionCE != null && damageDefExtensionCE.harmOnlyOutsideLayers; if (flag5) { damageInfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside); } bool flag6 = flag && hitThing is Pawn; if (flag6) { logEntry_DamageResult = new BattleLogEntry_DamageTaken((Pawn)hitThing, DefDatabase <RulePackDef> .GetNamed("DamageEvent_CookOff", true), null); Find.BattleLog.Add(logEntry_DamageResult); } try { hitThing.TakeDamage(damageInfo).AssociateWithLog(logEntry_DamageResult); bool flag7 = !(hitThing is Pawn) && projectilePropertiesCE != null && !projectilePropertiesCE.secondaryDamage.NullOrEmpty <SecondaryDamage>(); if (flag7) { foreach (SecondaryDamage secondaryDamage in projectilePropertiesCE.secondaryDamage) { bool destroyed = hitThing.Destroyed; if (destroyed) { break; } DamageInfo dinfo = secondaryDamage.GetDinfo(damageInfo); hitThing.TakeDamage(dinfo).AssociateWithLog(logEntry_DamageResult); } } } catch (Exception ex) { Log.Error("CombatExtended :: BulletCE impacting thing " + hitThing.LabelCap + " of def " + hitThing.def.LabelCap + " added by mod " + hitThing.def.modContentPack.Name + ". See following stacktrace for information.", false); throw ex; } finally { Impact(__instance, ___launcher, ___equipmentDef, hitThing, ___originInt, ___origin, ___destinationInt, ___startingTicksToImpactInt, ___ticksToImpact, ___intTicksToImpact, ref ___suppressionAmount); } } else { SoundDefOf.BulletImpact_Ground.PlayOneShot(new TargetInfo(__instance.Position, map, false)); bool castShadow = __instance.castShadow; if (castShadow) { FleckMaker.Static(__instance.ExactPosition, map, FleckDefOf.ShotHit_Dirt, 1f); bool takeSplashes = __instance.Position.GetTerrain(map).takeSplashes; if (takeSplashes) { FleckMaker.WaterSplash(__instance.ExactPosition, map, Mathf.Sqrt((float)__instance.def.projectile.GetDamageAmount(___launcher, null)) * 1f, 4f); } } Impact(__instance, ___launcher, ___equipmentDef, hitThing, ___originInt, ___origin, ___destinationInt, ___startingTicksToImpactInt, ___ticksToImpact, ___intTicksToImpact, ref ___suppressionAmount); } NotifyImpact(__instance, ___launcher, hitThing, map, __instance.Position); } return(false); } } return(true); }
static bool Prefix(ref JobGiver_AIFightEnemy __instance, ref Job __result, ref Pawn pawn) { // Log.Warning(string.Format("Tame animal job detected: {0}", pawn.LabelCap)); if (pawn.RaceProps.Humanlike) { return(true); } if (pawn.equipment != null) { if (pawn.equipment.Primary != null) { if (pawn.equipment.PrimaryEq != null) { if (pawn.equipment.PrimaryEq.verbTracker.PrimaryVerb.verbProps.range > 1.5) { return(true); } } } } bool hasRangedVerb = false; List <Verb> verbList = pawn.verbTracker.AllVerbs; List <Verb> rangeList = new List <Verb>(); for (int i = 0; i < verbList.Count; i++) { // Log.Warning("Checkity"); // Log.Warning(string.Format("verbList: {0}, Name: {1} RangeMax: {2}", i, verbList[i].verbProps.label, verbList[i].verbProps.range)); //It corresponds with verbs anyway if (verbList[i].verbProps.range > 1.5f) { rangeList.Add(verbList[i]); hasRangedVerb = true; } //Log.Warning("Added Ranged Verb"); } if (pawn.equipment?.PrimaryEq != null) { for (int i = 0; i < pawn.equipment.PrimaryEq.AllVerbs.Count; i++) { // Log.Warning("Checkity"); // Log.Warning(string.Format("verbList: {0}, Name: {1} RangeMax: {2}", i, verbList[i].verbProps.label, verbList[i].verbProps.range)); //It corresponds with verbs anyway if (pawn.equipment.PrimaryEq.AllVerbs[i].verbProps.range > 1.5f) { if (!rangeList.Contains(pawn.equipment.PrimaryEq.AllVerbs[i])) { rangeList.Add(pawn.equipment.PrimaryEq.AllVerbs[i]); hasRangedVerb = true; } } //Log.Warning("Added Ranged Verb"); } } if (pawn.health.hediffSet.hediffs.Any(x => x.TryGetComp <HediffComp_VerbGiverExtra>() != null)) { List <Hediff> list = pawn.health.hediffSet.hediffs.FindAll(x => x.TryGetComp <HediffComp_VerbGiverExtra>() != null); foreach (Hediff item in list) { HediffComp_VerbGiverExtra _VerbGiver = item.TryGetComp <HediffComp_VerbGiverExtra>(); if (_VerbGiver != null) { for (int i = 0; i < _VerbGiver.verbTracker.AllVerbs.Count; i++) { // Log.Warning("Checkity"); // Log.Warning(string.Format("verbList: {0}, Name: {1} RangeMax: {2}", i, verbList[i].verbProps.label, verbList[i].verbProps.range)); //It corresponds with verbs anyway if (_VerbGiver.verbTracker.AllVerbs[i].verbProps.range > 1.5f) { if (!rangeList.Contains(_VerbGiver.verbTracker.AllVerbs[i])) { rangeList.Add(_VerbGiver.verbTracker.AllVerbs[i]); hasRangedVerb = true; } } //Log.Warning("Added Ranged Verb"); } } } if (hasRangedVerb == false) { Log.Warning("I don't have range verb"); return(true); } } // this.SetCurMeleeVerb(updatedAvailableVerbsList.RandomElementByWeight((VerbEntry ve) => ve.SelectionWeight).verb); // Log.Warning(string.Format("rangeVerbs: {0}", rangeList.Count)); Verb rangeVerb; if (rangeList.Count > 1) { rangeVerb = rangeList.RandomElementByWeightWithDefault((Verb rangeItem) => rangeItem.verbProps.commonality, 0.5f); } else if (rangeList.Count == 1) { rangeVerb = rangeList.First(); } else { rangeVerb = null; } if (rangeVerb == null) { // Log.Warning("Can't get random range verb"); return(true); } else { // Log.Warning(string.Format("rangeVerb: {0}, Range Max: {1}, Min: {2}, Burst: {3}, Projectile: {4}", rangeVerb.verbProps.label, rangeVerb.verbProps.range, rangeVerb.verbProps.minRange, rangeVerb.verbProps.burstShotCount, rangeVerb.verbProps.defaultProjectile)); } Thing enemyTarget = (Thing)AttackTargetFinder.BestAttackTarget((IAttackTargetSearcher)pawn, TargetScanFlags.NeedThreat, (Predicate <Thing>)(x => x is Pawn || x is Building), 0.0f, rangeVerb.verbProps.range, new IntVec3(), float.MaxValue, false); if (enemyTarget == null) { // Log.Warning("I can't find anything to fight."); return(true); } bool useranged = Rand.Chance(rangeVerb.verbProps.commonality); // Log.Warning(string.Format("useranged: {0}", useranged)); if (!useranged) { //If adjacent melee attack if (enemyTarget.Position.AdjacentTo8Way(pawn.Position)) { __result = new Job(JobDefOf.AttackMelee, enemyTarget) { maxNumMeleeAttacks = 1, expiryInterval = Rand.Range(420, 900), attackDoorIfTargetLost = false }; return(false); } //Only go if I am to be released. This prevent animal running off. if (pawn.CanReach(enemyTarget, PathEndMode.Touch, Danger.Deadly, false)) { // Log.Warning("Melee Attack"); __result = new Job(JobDefOf.AttackMelee, enemyTarget) { maxNumMeleeAttacks = 1, expiryInterval = Rand.Range(420, 900), attackDoorIfTargetLost = false }; return(false); } else { return(true); } } //Log.Warning("got list of ranged verb"); // Log.Warning("Attempting flag"); bool flag1 = (double)CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.00999999977648258; bool flag2 = pawn.Position.Standable(pawn.Map); bool flag3 = rangeVerb.CanHitTarget(enemyTarget); bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; if (flag1 && flag2 && flag3 || flag4 && flag3) { // Log.Warning("Shooting"); __result = new Job(DefDatabase <JobDef> .GetNamed("AnimalRangeAttack"), enemyTarget, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true) { verbToUse = rangeVerb }; return(false); } IntVec3 dest; bool canShootCondition = false; // Log.Warning("Try casting"); //Animals with training seek cover /* * if (pawn.training.IsCompleted(TrainableDefOf.Release) && (double)verb.verbProps.range > 7.0) * Log.Warning("Attempting cover"); * Log.Warning("Try get flag radius :" + Traverse.Create(__instance).Method("GetFlagRadius", pawn).GetValue<float>()); * Log.Warning("Checking cast condition"); */ //Don't find new position if animal not released. canShootCondition = CastPositionFinder.TryFindCastPosition(new CastPositionRequest { caster = pawn, target = enemyTarget, verb = rangeVerb, maxRangeFromTarget = rangeVerb.verbProps.range, wantCoverFromTarget = (double)rangeVerb.verbProps.range > 7.0, locus = pawn.Position, maxRangeFromLocus = Traverse.Create(__instance).Method("GetFlagRadius", pawn).GetValue <float>(), maxRegions = 50 }, out dest); if (!canShootCondition) { // Log.Warning("I can't move to shooting position"); return(true); } if (dest == pawn.Position) { // Log.Warning("I will stay here and attack"); __result = new Job(DefDatabase <JobDef> .GetNamed("AnimalRangeAttack"), enemyTarget, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true) { verbToUse = rangeVerb }; return(false); } // Log.Warning("Going to new place"); __result = new Job(JobDefOf.Goto, (LocalTargetInfo)dest) { expiryInterval = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }; return(false); }
public static void Projectile_ArmorPenetration_Rending_Postfix(Projectile __instance, ref LocalTargetInfo ___usedTarget, ref Thing ___launcher, ref float __result) { if (___usedTarget.HasThing) { bool Rending = false; float RendingChance = 0.167f; Pawn caster = ___launcher as Pawn; Thing hitThing = ___usedTarget.Thing; Thing Launcher = ___launcher; if (caster != null) { if (caster.equipment != null) { // Log.Warning(string.Format("___launcher: {0}", ___launcher)); if (caster.equipment.Primary != null) { // Log.Warning(string.Format("caster.equipment != null")); Launcher = caster.equipment.Primary; // Log.Warning(string.Format("Launcher = caster.equipment.Primary")); CompWeapon_GunSpecialRules _GunSpecialRules = Launcher.TryGetComp <CompWeapon_GunSpecialRules>(); if (_GunSpecialRules != null) { // Log.Warning(string.Format("_GunSpecialRules != null")); Rending = _GunSpecialRules.Rending; RendingChance = _GunSpecialRules.RendingChance; } } else { // Log.Warning(string.Format("caster.equipment == null")); if (caster.health.hediffSet.hediffs.Any(x => x.TryGetComp <HediffComp_VerbGiverExtra>() != null)) { // Log.Warning(string.Format("HediffComp_VerbGiverExtra: {0}", ___launcher)); HediffComp_VerbGiverExtra _VGE = caster.health.hediffSet.hediffs.Find(x => x.TryGetComp <HediffComp_VerbGiverExtra>() is HediffComp_VerbGiverExtra z && z.verbTracker.AllVerbs.Any(y => y.verbProps.defaultProjectile == __instance.def)).TryGetComp <HediffComp_VerbGiverExtra>(); if (_VGE != null) { // Log.Warning(string.Format("_VGE != null: {0}", _VGE.parent.LabelCap)); GunVerbEntry entry = _VGE.Props.verbEntrys.Find(x => x.VerbProps.defaultProjectile == __instance.def); if (entry != null) { // Log.Warning(string.Format("{0}, Rending: {1}, Chance: {2}", entry.VerbProps.label, entry.Rending, entry.RendingChance)); Rending = entry.Rending; RendingChance = entry.RendingChance; } } } } } } if (Rending) { // Log.Warning(string.Format("Rending: {0}", ___launcher)); bool RendingEffect = Rand.Chance(RendingChance); if (RendingEffect) { // Log.Warning(string.Format("RendingEffect: {0}", ___launcher)); DamageDef damageDef = __instance.def.projectile.damageDef; // Log.Warning(string.Format("damageDef: {0}", damageDef.LabelCap)); DamageArmorCategoryDef armorCategory = damageDef.armorCategory != null ? damageDef.armorCategory: null; // Log.Warning(string.Format("armorCategory: {0}", armorCategory)); StatDef armorcatdef = damageDef.armorCategory != null ? armorCategory.armorRatingStat : null; // Log.Warning(string.Format("armorcatdef: {0}", armorcatdef)); float num = 0f; float num2 = Mathf.Clamp01((armorcatdef != null ? hitThing.GetStatValue(armorcatdef, true) : 0f) / 2f); // Log.Warning(string.Format("num2: {0}", num2)); if (hitThing is Pawn hitPawn) { List <BodyPartRecord> allParts = hitPawn.RaceProps.body.AllParts; // Log.Warning(string.Format("allParts: {0}", allParts.Count)); List <Apparel> list = (hitPawn.apparel == null) ? null : hitPawn.apparel.WornApparel; // Log.Warning(string.Format("list: {0}", list.Count)); for (int i = 0; i < allParts.Count; i++) { float num3 = 1f - num2; if (list != null) { for (int j = 0; j < list.Count; j++) { if (list[j].def.apparel.CoversBodyPart(allParts[i])) { float num4 = Mathf.Clamp01((armorcatdef != null ? list[j].GetStatValue(armorcatdef, true) : 0f) / 2f); num3 *= 1f - num4; } } } num += allParts[i].coverageAbs * (1f - num3); } } num = Mathf.Clamp(num * 2f, 0f, 2f); float ArmorPenetration = num; MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, "AMA_Rending_Shot".Translate(__instance.LabelCap, hitThing.LabelShortCap), 3f); // Log.Warning(string.Format("ArmorPenetration: {0}", ArmorPenetration)); __result = ArmorPenetration; } } } }
public static bool TryCastShot_Prefix(ref Verb_Shoot __instance) { // Log.Warning("TryCastShot"); bool GetsHot = false; bool Jams = false; bool GetsHotCrit = false; float GetsHotCritChance = 0f; bool GetsHotCritExplosion = false; float GetsHotCritExplosionChance = 0f; bool canDamageWeapon = false; float extraWeaponDamage = 0f; bool TwinLinked = false; bool Multishot = false; int ScattershotCount = 0; bool UserEffect = false; HediffDef UserHediff = null; float AddHediffChance = 0f; List <string> Immunitylist = new List <string>(); if (__instance.EquipmentSource != null) { if (!__instance.EquipmentSource.AllComps.NullOrEmpty()) { if (__instance.EquipmentSource.GetComp <CompWeapon_GunSpecialRules>() != null) { if (__instance.EquipmentSource.GetComp <CompWeapon_GunSpecialRules>() is CompWeapon_GunSpecialRules GunExt) { GetsHot = GunExt.GetsHot; Jams = GunExt.Jams; GetsHotCrit = GunExt.GetsHotCrit; GetsHotCritChance = GunExt.GetsHotCritChance; GetsHotCritExplosion = GunExt.GetsHotCritExplosion; GetsHotCritExplosionChance = GunExt.GetsHotCritExplosionChance; canDamageWeapon = (Jams && GunExt.JamsDamageWeapon) || (GetsHot && GunExt.HotDamageWeapon); extraWeaponDamage = (Jams && GunExt.JamsDamageWeapon) ? GunExt.JamDamage : (GetsHot && GunExt.HotDamageWeapon) ? GunExt.HotDamage : 0f; Multishot = GunExt.Multishot; ScattershotCount = GunExt.ScattershotCount; TwinLinked = GunExt.TwinLinked; UserEffect = GunExt.EffectsUser; UserHediff = GunExt.UserEffect; Immunitylist = GunExt.UserEffectImmuneList; AddHediffChance = GunExt.ResistEffectStat != null?GunExt.EffectsUserChance *__instance.caster.GetStatValue(GunExt.ResistEffectStat, true) : GunExt.EffectsUserChance; } } } } if (__instance.HediffCompSource != null) { HediffComp_VerbGiverExtra _VGE = (HediffComp_VerbGiverExtra)__instance.HediffCompSource; GetsHot = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].GetsHot; Jams = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].Jams; GetsHotCrit = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].GetsHotCrit; GetsHotCritChance = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].GetsHotCritChance; GetsHotCritExplosion = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].GetsHotCritExplosion; GetsHotCritExplosionChance = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].GetsHotCritExplosionChance; canDamageWeapon = (_VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].Jams && _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].JamsDamageWeapon) || (GetsHot && _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].HotDamageWeapon); extraWeaponDamage = (_VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].Jams && _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].JamsDamageWeapon) ? _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].JamDamage : (GetsHot && _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].HotDamageWeapon) ? _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].HotDamage : 0f; Multishot = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].Multishot; ScattershotCount = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].ScattershotCount; TwinLinked = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].TwinLinked; UserEffect = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].EffectsUser; UserHediff = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].UserEffect; Immunitylist = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].UserEffectImmuneList; AddHediffChance = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].ResistEffectStat != null ? _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].EffectsUserChance * __instance.caster.GetStatValue(_VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].ResistEffectStat, true) : _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].EffectsUserChance; } if ((GetsHot && AMASettings.Instance.AllowGetsHot) || (Jams && AMASettings.Instance.AllowJams)) { string msg = string.Format(""); string reliabilityString; float failChance; StatPart_Reliability.GetReliability(__instance.EquipmentSource.TryGetComp <CompWeapon_GunSpecialRules>(), out reliabilityString, out failChance); failChance = GetsHot ? (failChance / 10) : (failChance / 100); if (Rand.Chance(failChance)) { if (GetsHot) { DamageDef damageDef = __instance.Projectile.projectile.damageDef; HediffDef HediffToAdd = damageDef.hediff; float ArmorPenetration = __instance.Projectile.projectile.GetArmorPenetration(__instance.EquipmentSource, null); float DamageAmount = 0; Pawn launcherPawn = __instance.caster as Pawn; if (Rand.Chance(GetsHotCritChance)) { DamageAmount = __instance.Projectile.projectile.GetDamageAmount(__instance.EquipmentSource, null); msg = string.Format("{0}'s {1} critically overheated. ({2} chance) causing {3} damage", __instance.caster.LabelCap, __instance.EquipmentSource.LabelCap, failChance.ToStringPercent(), DamageAmount); if (GetsHotCritExplosion && Rand.Chance(GetsHotCritExplosionChance)) { CriticalOverheatExplosion(ref __instance); } } else { DamageAmount = __instance.Projectile.projectile.GetDamageAmount(__instance.EquipmentSource, null); msg = string.Format("{0}'s {1} overheated. ({2} chance) causing {3} damage", __instance.caster.LabelCap, __instance.EquipmentSource.LabelCap, failChance.ToStringPercent(), DamageAmount); } float maxburndmg = DamageAmount / 10; while (DamageAmount > 0f) { List <BodyPartRecord> list = launcherPawn.health.hediffSet.GetNotMissingParts().Where(x => x.def.defName.Contains("Finger") || x.def.defName.Contains("Hand")).ToList <BodyPartRecord>(); if (list.NullOrEmpty()) { list = launcherPawn.health.hediffSet.GetNotMissingParts().Where(x => x.def.defName.Contains("Arm") || x.def.defName.Contains("Shoulder")).ToList <BodyPartRecord>(); } if (list.NullOrEmpty()) { list = launcherPawn.health.hediffSet.GetNotMissingParts().Where(x => x.def.tags.Contains(BodyPartTagDefOf.ManipulationLimbCore) || x.def.tags.Contains(BodyPartTagDefOf.ManipulationLimbSegment) || x.def.tags.Contains(BodyPartTagDefOf.ManipulationLimbDigit)).ToList <BodyPartRecord>(); } if (list.NullOrEmpty()) { break; } else { BodyPartRecord part = list.RandomElement(); Hediff hediff; float severity = Rand.Range(Math.Min(0.1f, DamageAmount), Math.Min(DamageAmount, maxburndmg)); hediff = HediffMaker.MakeHediff(HediffToAdd, launcherPawn, null); hediff.Severity = severity; launcherPawn.health.AddHediff(hediff, part, null); DamageAmount -= severity; } } Messages.Message(msg, MessageTypeDefOf.NegativeHealthEvent); } else { msg = string.Format("{0}'s {1} had a weapon jam. ({2} chance)", __instance.caster.LabelCap, __instance.EquipmentSource.LabelCap, failChance.ToStringPercent()); Messages.Message(msg, MessageTypeDefOf.SilentInput); } float defaultCooldownTime = __instance.verbProps.defaultCooldownTime * 2; __instance.verbProps.defaultCooldownTime = defaultCooldownTime; if (canDamageWeapon) { if (extraWeaponDamage != 0f) { if (__instance.EquipmentSource != null) { if (__instance.EquipmentSource.HitPoints - (int)extraWeaponDamage >= 0) { __instance.EquipmentSource.HitPoints = __instance.EquipmentSource.HitPoints - (int)extraWeaponDamage; } else if (__instance.EquipmentSource.HitPoints - (int)extraWeaponDamage < 0) { __instance.EquipmentSource.HitPoints = 0; __instance.EquipmentSource.Destroy(); } } if (__instance.HediffCompSource != null) { /* * if (__instance.HediffCompSource.parent.Part..HitPoints - (int)extraWeaponDamage >= 0) * { * __instance.HediffCompSource.HitPoints = __instance.HediffCompSource.HitPoints - (int)extraWeaponDamage; * } * else if (__instance.HediffCompSource.HitPoints - (int)extraWeaponDamage < 0) * { * __instance.HediffCompSource.HitPoints = 0; * __instance.HediffCompSource.Destroy(); * } */ } } else { if (__instance.EquipmentSource != null) { if (__instance.EquipmentSource.HitPoints > 0) { __instance.EquipmentSource.HitPoints--; } } } } if (Jams) { if (__instance.EquipmentSource != null) { SpinningLaserGun spinner = (SpinningLaserGun)__instance.EquipmentSource; if (spinner != null) { spinner.state = SpinningLaserGunBase.State.Idle; spinner.ReachRotationSpeed(0, 0); } } return(false); } } } if (ScattershotCount > 0 && Multishot && AMASettings.Instance.AllowMultiShot) { // Log.Message(string.Format("AllowMultiShot: {0} Projectile Count: {1}", AMASettings.Instance.AllowMultiShot && Multishot, ScattershotCount)); for (int i = 0; i < ScattershotCount; i++) { // Log.Message(string.Format("Launching extra projectile {0} / {1}", i+1, ScattershotCount)); // AccessTools.Method(typeof(Verb_Shoot).BaseType, "TryCastShot", null, null).Invoke(__instance, null); TryCastExtraShot(ref __instance); } } else if (TwinLinked) { TryCastExtraShot(ref __instance); } if (UserEffect && AMASettings.Instance.AllowUserEffects) { if (__instance.caster.def.category == ThingCategory.Pawn) { bool Immunityflag = false; Pawn launcherPawn = __instance.caster as Pawn; if (!Immunitylist.NullOrEmpty()) { foreach (var item in Immunitylist) { Immunityflag = launcherPawn.def.defName.Contains(item); if (Immunityflag) { // Log.Message(string.Format("{0} is immune to their {1}'s UseEffect", launcherPawn.LabelShortCap, __instance.EquipmentSource.LabelShortCap)); } } /* * List<string> list = GunExt.UserEffectImmuneList.Where(x => DefDatabase<ThingDef>.GetNamedSilentFail(x) != null).ToList(); * bool Immunityflag = list.Contains(launcherPawn.def.defName); * if (Immunityflag) * { * return; * } */ } if (!Immunityflag) { var rand = Rand.Value; // This is a random percentage between 0% and 100% // Log.Message(string.Format("GunExt.EffectsUser Effect: {0}, Chance: {1}, Roll: {2}, Result: {3}" + GunExt.ResistEffectStat != null ? ", Resist Stat: "+GunExt.ResistEffectStat.LabelCap+", Resist Amount"+ __instance.caster.GetStatValue(GunExt.ResistEffectStat, true) : null, GunExt.UserEffect.LabelCap, AddHediffChance, rand, rand <= AddHediffChance)); if (rand <= AddHediffChance) // If the percentage falls under the chance, success! { var randomSeverity = Rand.Range(0.05f, 0.15f); var effectOnPawn = launcherPawn?.health?.hediffSet?.GetFirstHediffOfDef(UserHediff); if (effectOnPawn != null) { effectOnPawn.Severity += randomSeverity; } else { Hediff hediff = HediffMaker.MakeHediff(UserHediff, launcherPawn, null); hediff.Severity = randomSeverity; launcherPawn.health.AddHediff(hediff, null, null); } } } } } return(true); }