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); }
public static bool Prefix(ref Verb_ShootCE __instance) { // Log.Warning("CE_TryCastShot_WeaponSpecialRules_Patch WarmupComplete "); IAdvancedVerb entry = __instance.SpecialRules(); if (entry == null) { // Log.Message("no SpecialRules detected"); return(true); } bool canDamageWeapon; float extraWeaponDamage; bool TwinLinked = entry.TwinLinked; bool Multishot = entry.Multishot; int ScattershotCount = entry.ScattershotCount; bool UserEffect = entry.EffectsUser; HediffDef UserHediff = entry.UserEffect; float AddHediffChance = entry.EffectsUserChance; List <string> Immunitylist = entry.UserEffectImmuneList; string msg = string.Format(""); string reliabilityString; float failChance; StatPart_Reliability.GetReliability(entry, __instance.EquipmentSource, out reliabilityString, out failChance); failChance = (__instance.GetsHot()) ? (failChance / 10) : (failChance / 100); bool failed = false; if (__instance.GetsHot() || __instance.Jams()) { // Log.Message("failChance: "+failChance); Rand.PushState(); failed = Rand.Chance(failChance); Rand.PopState(); // Log.Message("failed: "+failed); } if (__instance.GetsHot(out bool GetsHotCrit, out float GetsHotCritChance, out bool GetsHotCritExplosion, out float GetsHotCritExplosionChance, out canDamageWeapon, out extraWeaponDamage)) { if (failed) { 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; Rand.PushState(); 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); } Rand.PopState(); 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.parent.def.defName.Contains("Arm")).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; Rand.PushState(); float severity = Rand.Range(Math.Min(0.1f, DamageAmount), Math.Min(DamageAmount, maxburndmg)); Rand.PopState(); hediff = HediffMaker.MakeHediff(HediffToAdd, launcherPawn, part); hediff.Severity = severity; launcherPawn.health.AddHediff(hediff, part, null); DamageAmount -= severity; } } Messages.Message(msg, MessageTypeDefOf.NegativeHealthEvent); } } if (__instance.Jams(out canDamageWeapon, out extraWeaponDamage)) { if (failed) { if (!__instance.GetsHot()) { 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 (__instance.EquipmentSource != null) { SpinningLaserGun spinner = (SpinningLaserGun)__instance.EquipmentSource; if (spinner != null) { spinner.state = SpinningLaserGunBase.State.Idle; spinner.ReachRotationSpeed(0, 0); } } return(false); } } if (__instance.MultiShot() || __instance.TwinLinked()) { if (__instance.TwinLinked()) { } else { } } if (__instance.UserEffect(out float Chance, out HediffDef Effect, out StatDef ResistStat, out List <string> ImmuneList)) { 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) { Rand.PushState(); var rand = Rand.Value; // This is a random percentage between 0% and 100% Rand.PopState(); // 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! { Rand.PushState(); var randomSeverity = Rand.Range(0.05f, 0.15f); Rand.PopState(); 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); }