public override void ExposeData() { base.ExposeData(); Scribe_Values.Look <int>(ref beamColorIndex, "beamColorIndex", -1, false); if (GetComp <CompWeapon_GunSpecialRules>() != null) { CompWeapon_GunSpecialRules specialRules = GetComp <CompWeapon_GunSpecialRules>(); if (specialRules.GetsHot || specialRules.Jams) { string reliabilityString; float jamsOn; StatPart_Reliability.GetReliability(GetComp <CompWeapon_GunSpecialRules>(), out reliabilityString, out jamsOn); Scribe_Values.Look <string>(ref reliabilityString, "reliability", "NA", false); } } if (GetComp <CompWeapon_GunSpecialRules>() != null) { CompWeapon_GunSpecialRules specialRules = GetComp <CompWeapon_GunSpecialRules>(); if (specialRules.GetsHot || specialRules.Jams) { string reliabilityString; float jamsOn; StatPart_Reliability.GetReliability(GetComp <CompWeapon_GunSpecialRules>(), out reliabilityString, out jamsOn); Scribe_Values.Look <string>(ref reliabilityString, "reliability", "NA", false); } } }
public override void ExposeData() { base.ExposeData(); string reliabilityString; float jamsOn; StatPart_Reliability.GetReliability(this, out reliabilityString, out jamsOn); Scribe_Values.Look <string>(ref reliabilityString, "reliability", "NA", false); }
public override string GetInspectString() { string result = base.GetInspectString(); string reliabilityString; float jamsOn; StatPart_Reliability.GetReliability(this, out reliabilityString, out jamsOn); result += string.Format("\r\nReliability: {0}\r\nChance of jam: {1}%", reliabilityString, jamsOn); return(result); }
public virtual float FailChance(Thing gun, out string reliabilityString) { float failChance = 0; reliabilityString = string.Empty; if (GetsHot || Jams) { StatPart_Reliability.GetReliability(this, gun, out reliabilityString, out failChance); failChance *= (GetsHot ? 0.1f : 0.01f); } if (debug) { Log.Message("FailChance for" + reliabilityString + " " + gun + ": " + failChance); } return(failChance); }
/* * public override void Tick() * { * base.Tick(); * CompWargearWeaponSecondry comp = base.GetComp<CompWargearWeaponSecondry>(); * if (comp != null) * { * comp.CompTick(); * } * } */ public override string GetInspectString() { string result = base.GetInspectString(); if (GetComp <CompWeapon_GunSpecialRules>() != null) { CompWeapon_GunSpecialRules specialRules = GetComp <CompWeapon_GunSpecialRules>(); if (specialRules.GetsHot || specialRules.Jams) { string reliabilityString; float jamsOn; StatPart_Reliability.GetReliability(GetComp <CompWeapon_GunSpecialRules>(), out reliabilityString, out jamsOn); string cause = specialRules.GetsHot ? "Overheat" : "Jam"; float chance = specialRules.GetsHot ? jamsOn / 10 : jamsOn / 100; result += string.Format("\r\nReliability: {0}\r\n" + cause + " chance: {1}", reliabilityString, chance.ToStringPercent()); } } return(result); }
protected override bool TryCastShot() { // Log.Message("Try Cast Shot Called"); //Log.Message("Cast"); bool GetsHot = this.UseAbilityProps.GetsHot; bool Jams = this.UseAbilityProps.Jams; bool GetsHotCrit = this.UseAbilityProps.GetsHotCrit; float GetsHotCritChance = this.UseAbilityProps.GetsHotCritChance; bool GetsHotCritExplosion = this.UseAbilityProps.GetsHotCritExplosion; float GetsHotCritExplosionChance = this.UseAbilityProps.GetsHotCritExplosionChance; bool canDamageWeapon = this.UseAbilityProps.HotDamageWeapon || this.UseAbilityProps.JamsDamageWeapon; float extraWeaponDamage = (Jams && this.UseAbilityProps.JamsDamageWeapon) ? this.UseAbilityProps.JamDamage : (GetsHot && this.UseAbilityProps.HotDamageWeapon) ? this.UseAbilityProps.HotDamage : 0f; bool TwinLinked = this.UseAbilityProps.TwinLinked; bool Multishot = this.UseAbilityProps.Multishot; int ScattershotCount = this.UseAbilityProps.ScattershotCount; bool UserEffect = this.UseAbilityProps.EffectsUser; HediffDef UserHediff = this.UseAbilityProps.UserEffect; float AddHediffChance = this.UseAbilityProps.EffectsUserChance; List <string> Immunitylist = this.UseAbilityProps.UserEffectImmuneList; var result = false; TargetsAoE.Clear(); UpdateTargets(); var burstShots = ShotsPerBurst; if (UseAbilityProps.AbilityTargetCategory != AbilityTargetCategory.TargetAoE && TargetsAoE.Count > 1) { TargetsAoE.RemoveRange(0, TargetsAoE.Count - 1); } if (UseAbilityProps.mustHaveTarget && TargetsAoE.Count == 0) { Messages.Message("AU_NoTargets".Translate(), MessageTypeDefOf.RejectInput); Ability.Notify_AbilityFailed(true); return(false); } for (var i = 0; i < TargetsAoE.Count; i++) { // for (int j = 0; j < burstshots; j++) // { if (verbProps.defaultProjectile != null) //ranged attacks WILL have projectiles { if ((GetsHot && AMASettings.Instance.AllowGetsHot) || (Jams && AMASettings.Instance.AllowJams)) { string msg = string.Format(""); string reliabilityString; float failChance; StatPart_Reliability.GetReliability(this.UseAbilityProps, out reliabilityString, out failChance); failChance = GetsHot ? (failChance / 10) : (failChance / 100); if (Rand.Chance(failChance)) { if (GetsHot) { DamageDef damageDef = this.Projectile.projectile.damageDef; HediffDef HediffToAdd = damageDef.hediff; float ArmorPenetration = this.Projectile.projectile.GetArmorPenetration(this.EquipmentSource, null); float DamageAmount = 0; Pawn launcherPawn = this.caster as Pawn; if (Rand.Chance(GetsHotCritChance)) { DamageAmount = this.Projectile.projectile.GetDamageAmount(this.EquipmentSource, null); msg = string.Format("{0}'s {1} critically overheated. ({2} chance) causing {3} damage", this.caster.LabelCap, this.EquipmentSource.LabelCap, failChance.ToStringPercent(), DamageAmount); if (GetsHotCritExplosion && Rand.Chance(GetsHotCritExplosionChance)) { CriticalOverheatExplosion(); } } else { DamageAmount = this.Projectile.projectile.GetDamageAmount(this.EquipmentSource, null); msg = string.Format("{0}'s {1} overheated. ({2} chance) causing {3} damage", this.caster.LabelCap, this.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)", this.caster.LabelCap, this.EquipmentSource.LabelCap, failChance.ToStringPercent()); Messages.Message(msg, MessageTypeDefOf.SilentInput); } float defaultCooldownTime = this.verbProps.defaultCooldownTime * 2; this.verbProps.defaultCooldownTime = defaultCooldownTime; if (canDamageWeapon) { if (extraWeaponDamage != 0f) { if (this.EquipmentSource != null) { if (this.EquipmentSource.HitPoints - (int)extraWeaponDamage >= 0) { this.EquipmentSource.HitPoints = this.EquipmentSource.HitPoints - (int)extraWeaponDamage; } else if (this.EquipmentSource.HitPoints - (int)extraWeaponDamage < 0) { this.EquipmentSource.HitPoints = 0; this.EquipmentSource.Destroy(); } } if (this.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 (this.EquipmentSource != null) { if (this.EquipmentSource.HitPoints > 0) { this.EquipmentSource.HitPoints--; } } } } if (Jams) { if (this.EquipmentSource != null) { SpinningLaserGun spinner = (SpinningLaserGun)this.EquipmentSource; if (spinner != null) { spinner.state = SpinningLaserGunBase.State.Idle; spinner.ReachRotationSpeed(0, 0); } } return(false); } } } var attempt = TryLaunchProjectile(verbProps.defaultProjectile, TargetsAoE[i]); if (ScattershotCount > 0 && Multishot && AMASettings.Instance.AllowMultiShot) { // Log.Message(string.Format("AllowMultiShot: {0} Projectile Count: {1}", AMASettings.Instance.AllowMultiShot && Multishot, ScattershotCount)); for (int ii = 0; ii < ScattershotCount; ii++) { // Log.Message(string.Format("Launching extra projectile {0} / {1}", i+1, ScattershotCount)); // AccessTools.Method(typeof(Verb_Shoot).BaseType, "TryCastShot", null, null).Invoke(__instance, null); TryLaunchProjectile(verbProps.defaultProjectile, TargetsAoE[i]); } } else if (TwinLinked) { TryLaunchProjectile(verbProps.defaultProjectile, TargetsAoE[i]); } if (UserEffect && AMASettings.Instance.AllowUserEffects) { if (caster.def.category == ThingCategory.Pawn) { bool Immunityflag = false; Pawn launcherPawn = this.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); } } } } } ////Log.Message(TargetsAoE[i].ToString()); if (attempt != null) { if (attempt == true) { result = true; } if (attempt == false) { result = false; } } } else //melee attacks WON'T have projectiles { // Log.Message("No Projectile"); var victim = TargetsAoE[i].Thing; if (victim != null) { // Log.Message("Yes victim"); if (victim is Pawn pawnVictim) { // Log.Message("Yes victim is pawn"); AbilityEffectUtility.ApplyMentalStates(pawnVictim, CasterPawn, UseAbilityProps.mentalStatesToApply, UseAbilityProps.abilityDef, null); AbilityEffectUtility.ApplyHediffs(pawnVictim, CasterPawn, UseAbilityProps.hediffsToApply, null); AbilityEffectUtility.SpawnSpawnables(UseAbilityProps.thingsToSpawn, pawnVictim, victim.MapHeld, victim.PositionHeld); } } else { // Log.Message("Victim is null"); AbilityEffectUtility.SpawnSpawnables(UseAbilityProps.thingsToSpawn, CasterPawn, CasterPawn.MapHeld, CasterPawn.PositionHeld); } } // } } PostCastShot(result, out result); if (result == false) { Ability.Notify_AbilityFailed(UseAbilityProps.refundsPointsAfterFailing); } return(result); }
protected override bool TryCastShot() { int logcount = 0; bool logging = VerbPropsOG.logging; bool canDamageWeapon = VerbPropsOG.canDamageWeapon; float extraWeaponDamage = VerbPropsOG.extraWeaponDamage; bool canJam = VerbPropsOG.canJam; logcount++; string msg = string.Format(""); string lmsg = string.Format("log {0}", logcount); //bool rapidfire = VerbPropsCP.rapidfire; string reliabilityString; float jamsOn; StatPart_Reliability.GetReliability((ThingDef_GunOG)EquipmentSource, out reliabilityString, out jamsOn); logcount++; lmsg = string.Format("log {0} reliabilityString {1}", logcount, reliabilityString); if (logging == true) { Log.Message(lmsg); } jamsOn = jamsOn++; float jamRoll = 0; logcount++; lmsg = string.Format("log {0} jamsOn {1}", logcount, jamsOn); if (logging == true) { Log.Message(lmsg); } if (VerbPropsOG.overheat == true) { jamRoll = (Rand.Range(0, 100)); } else { jamRoll = (Rand.Range(0, 1000)) / 10f; } logcount++; lmsg = string.Format("log {0} jamRoll {1}", logcount, jamRoll); if (logging == true) { Log.Message(lmsg); } if (jamRoll < jamsOn && canJam == true) { logcount++; lmsg = string.Format("log {0} VerbPropsCP.overheat {1}", logcount, VerbPropsOG.overheat); if (logging == true) { Log.Message(lmsg); } if (VerbPropsOG.overheat == true) { DamageDef damageDef = Projectile.projectile.damageDef; HediffDef HediffToAdd = damageDef.hediff; float ArmorPenetration = Projectile.projectile.GetArmorPenetration(EquipmentSource, null); float overheatsOn = VerbPropsOG.overheatsOn; logcount++; lmsg = string.Format("log {0} overheatsOn {1}", logcount, overheatsOn); if (logging == true) { Log.Message(lmsg); } int DamageAmount = 0; float overheatRoll = (Rand.Range(0, 1000)) / 10f; logcount++; lmsg = string.Format("log {0} overheatRoll {1}", logcount, overheatRoll); if (logging == true) { Log.Message(lmsg); } Pawn launcherPawn = caster as Pawn; if (overheatRoll < overheatsOn) { DamageAmount = Projectile.projectile.GetDamageAmount(EquipmentSource, null); msg = string.Format("{0}'s {1} critically overheated. ({2}/{3}) causing {4} damage", caster.LabelCap, EquipmentSource.LabelCap, jamRoll, jamsOn, DamageAmount); if (VerbPropsOG.criticaloverheatExplosion == true) { CriticalOverheatExplosion(); } } else { DamageAmount = Projectile.projectile.GetDamageAmount(EquipmentSource, null) / 10; msg = string.Format("{0}'s {1} overheated. ({2}/{3}) causing {4} damage", caster.LabelCap, EquipmentSource.LabelCap, jamRoll, jamsOn, DamageAmount); } var overheatOnPawn = launcherPawn?.health?.hediffSet?.GetFirstHediffOfDef(HediffToAdd); if (overheatOnPawn != null) { overheatOnPawn.Severity += DamageAmount; } else { foreach (var part in launcherPawn.RaceProps.body.AllParts.Where(x => x.def.labelShort == "Hand")) { logcount++; lmsg = string.Format("log {0} part.def.hitPoints {1}", logcount, launcherPawn.health.hediffSet.PartIsMissing(part)); if (logging == true) { Log.Message(lmsg); } if (launcherPawn.health.hediffSet.PartIsMissing(part) == false) { logcount++; lmsg = string.Format("log {0} part.customLabel {1}", logcount, part.def.hitPoints); if (logging == true) { Log.Message(lmsg); } Hediff hediff = HediffMaker.MakeHediff(HediffToAdd, launcherPawn, null); hediff.Severity = Rand.Range(0, DamageAmount); launcherPawn.health.AddHediff(hediff, part, null); } } } Messages.Message(msg, MessageTypeDefOf.NegativeHealthEvent); } else { msg = string.Format("{0}'s {1} had a weapon jam. ({2}/{3})", caster.LabelCap, EquipmentSource.LabelCap, jamRoll, jamsOn); Messages.Message(msg, MessageTypeDefOf.SilentInput); } if (EquipmentSource.HitPoints > 0) { EquipmentSource.HitPoints--; } float defaultCooldownTime = this.verbProps.defaultCooldownTime * 2; return(false); } if (canDamageWeapon) { if (extraWeaponDamage != 0f) { if (EquipmentSource.HitPoints - (int)extraWeaponDamage >= 0) { EquipmentSource.HitPoints = EquipmentSource.HitPoints - (int)extraWeaponDamage; } else if (EquipmentSource.HitPoints - (int)extraWeaponDamage < 0) { EquipmentSource.HitPoints = 0; } } else { if (EquipmentSource.HitPoints > 0) { EquipmentSource.HitPoints--; } } } return(base.TryCastShot()); }
public override string GetDescriptionPart() { string str = string.Empty; str = str + "Special Rules:"; if (DualFireMode) { str = str + string.Format("\nDual Fire Modes: \n Primary: {0}, Secondary: {1}", parent.def.Verbs[0].defaultProjectile.label, SecondaryMode.defaultProjectile.label); str = str + string.Format("\n Current Mode: {0} \n", compEquippable.VerbTracker.PrimaryVerb.verbProps.defaultProjectile.label); } if (RapidFire) { str = str + string.Format("\n RapidFire: warmup halved ({0} seconds) and Shots per burst increased to {1} when firing at targets within {2} cells. \n", (OriginalwarmupTime / 2), compEquippable.VerbTracker.PrimaryVerb.verbProps.burstShotCount * 2, compEquippable.VerbTracker.PrimaryVerb.verbProps.range / 2); } if (GetsHot) { string reliabilityString; float failChance; StatPart_Reliability.GetReliability(this, out reliabilityString, out failChance); str = str + string.Format("\n Gets Hot: This {0} is {1} and has a {2} chance to overheat per shot fired.", parent.Label, reliabilityString, (failChance / 100).ToStringPercent()); if (HotDamageWeapon) { str = str + string.Format(" Overheats cause {0} damage to the {1}.", HotDamage, parent.def.label); } if (GetsHotCrit) { str = str + string.Format("it has a {0} chance to critically overheat, causing more damage to user and weapon.", (GetsHotCritChance / 100).ToStringPercent()); if (GetsHotCritExplosion) { str = str + string.Format("Critical overheats have a {0} chance of cuasing the weapon to explode.", (GetsHotCritExplosionChance / 100).ToStringPercent()); } } str = str + "\n"; } if (Jams) { string reliabilityString; float failChance; StatPart_Reliability.GetReliability(this, out reliabilityString, out failChance); str = str + string.Format("\n Jams: This {0} is {1} and has a {2} chance to jam per shot fired.", parent.Label, reliabilityString, (failChance / 100).ToStringPercent()); if (JamsDamageWeapon) { str = str + string.Format(" Jamming causes {0} damage to the {1}.", JamDamage, parent.def.label); } str = str + "\n"; } if (TwinLinked) { str = str + "\n Twin-Linked: Fires two projectiles per shot"; } if (Multishot) { str = str + string.Format("\n Scatter-Shot: Fires {0} perjectiles per shot", ScattershotCount); } if (Rending) { str = str + string.Format("\n Rending: has a {0} chance to ignore all armour", RendingChance); } if (MeltaWeapon) { str = str + string.Format("\n Melta: Damage Vs Buildings and AP doubled when firing at targets within {0} cells. \n", compEquippable.VerbTracker.PrimaryVerb.verbProps.range / 2); } if (VolkiteWeapon) { str = str + string.Format("\n Volite: AP begins to drop off when firing at targets over {0} cells. \n", compEquippable.VerbTracker.PrimaryVerb.verbProps.range / 2); } if (ConversionWeapon) { str = str + string.Format("\n Conversion: Damage and AP increase the further the target is away. \n"); } if (HaywireWeapon) { str = str + "\n Haywire Weapon"; str = str + string.Format("\n Haywire: additional EMP damage. \n"); } /* * if (GaussWeapon) * { * str = str + "\n Gauss Weapon"; * str = str + string.Format("\n Conversion: Damage and AP increase the further the target is away. \n"); * } */ if (TeslaWeapon) { str = str + "\n Tesla Weapon"; str = str + string.Format("\n Tesla: Bolt can arc to up to 3 nearby targets. \n"); } return(str); return(base.GetDescriptionPart()); }