public float EffectiveMinRange(LocalTargetInfo target, Thing caster) { return(EffectiveMinRange(VerbUtility.AllowAdjacentShot(target, caster))); }
private static void DoTablesInternalMelee(ThingDef stuff, bool doRaces = false) { Func <Def, float> meleeDamageGetter = delegate(Def d) { List <Verb> concreteExampleVerbs5 = VerbUtility.GetConcreteExampleVerbs(d, stuff); if (concreteExampleVerbs5.OfType <Verb_MeleeAttack>().Any()) { return(concreteExampleVerbs5.OfType <Verb_MeleeAttack>().AverageWeighted((Verb_MeleeAttack v) => v.verbProps.AdjustedMeleeSelectionWeight(v, null), (Verb_MeleeAttack v) => v.verbProps.AdjustedMeleeDamageAmount(v, null))); } return(-1f); }; Func <Def, float> rangedDamageGetter = delegate(Def d) { List <Verb> concreteExampleVerbs4 = VerbUtility.GetConcreteExampleVerbs(d, stuff); Verb_LaunchProjectile verb_LaunchProjectile = concreteExampleVerbs4.OfType <Verb_LaunchProjectile>().FirstOrDefault(); if (verb_LaunchProjectile != null && verb_LaunchProjectile.GetProjectile() != null) { return((float)verb_LaunchProjectile.GetProjectile().projectile.GetDamageAmount(null)); } return(-1f); }; Func <Def, float> rangedWarmupGetter = delegate(Def d) { List <Verb> concreteExampleVerbs3 = VerbUtility.GetConcreteExampleVerbs(d, stuff); return(concreteExampleVerbs3.OfType <Verb_LaunchProjectile>().FirstOrDefault()?.verbProps.warmupTime ?? (-1f)); }; Func <Def, float> meleeCooldownGetter = delegate(Def d) { List <Verb> concreteExampleVerbs2 = VerbUtility.GetConcreteExampleVerbs(d, stuff); if (concreteExampleVerbs2.OfType <Verb_MeleeAttack>().Any()) { return(concreteExampleVerbs2.OfType <Verb_MeleeAttack>().AverageWeighted((Verb_MeleeAttack v) => v.verbProps.AdjustedMeleeSelectionWeight(v, null), (Verb_MeleeAttack v) => v.verbProps.AdjustedCooldown(v, null))); } return(-1f); }; Func <Def, float> rangedCooldownGetter = delegate(Def d) { List <Verb> concreteExampleVerbs = VerbUtility.GetConcreteExampleVerbs(d, stuff); return(concreteExampleVerbs.OfType <Verb_LaunchProjectile>().FirstOrDefault()?.verbProps.defaultCooldownTime ?? (-1f)); }; Func <Def, float> meleeDpsGetter = (Def d) => meleeDamageGetter(d) * 0.82f / meleeCooldownGetter(d); Func <Def, float> marketValueGetter = delegate(Def d) { ThingDef thingDef3 = d as ThingDef; if (thingDef3 != null) { return(thingDef3.GetStatValueAbstract(StatDefOf.MarketValue, stuff)); } HediffDef hediffDef = d as HediffDef; if (hediffDef != null) { if (hediffDef.spawnThingOnRemoved == null) { return(0f); } return(hediffDef.spawnThingOnRemoved.GetStatValueAbstract(StatDefOf.MarketValue)); } return(-1f); }; IEnumerable <Def> enumerable = (from d in DefDatabase <ThingDef> .AllDefs where d.IsWeapon select d).Cast <Def>().Concat((from h in DefDatabase <HediffDef> .AllDefs where h.CompProps <HediffCompProperties_VerbGiver>() != null select h).Cast <Def>()); if (doRaces) { enumerable = enumerable.Concat((from d in DefDatabase <ThingDef> .AllDefs where d.race != null select d).Cast <Def>()); } enumerable = from h in enumerable orderby meleeDpsGetter(h) descending select h; DebugTables.MakeTablesDialog(enumerable, new TableDataGetter <Def>("defName", (Def d) => d.defName), new TableDataGetter <Def>("melee\ndamage\naverage", (Def d) => meleeDamageGetter(d).ToString("F2")), new TableDataGetter <Def>("melee\ncooldown\naverage", (Def d) => meleeCooldownGetter(d).ToString("F2")), new TableDataGetter <Def>("melee\nDPS", (Def d) => meleeDpsGetter(d).ToString("F2")), new TableDataGetter <Def>("ranged\ndamage", (Def d) => rangedDamageGetter(d).ToString()), new TableDataGetter <Def>("ranged\nwarmup", (Def d) => rangedWarmupGetter(d).ToString("F2")), new TableDataGetter <Def>("ranged\ncooldown", (Def d) => rangedCooldownGetter(d).ToString("F2")), new TableDataGetter <Def>("market value", (Def d) => marketValueGetter(d).ToStringMoney()), new TableDataGetter <Def>("work to make", delegate(Def d) { ThingDef thingDef2 = d as ThingDef; if (thingDef2 == null) { return("-"); } return(thingDef2.GetStatValueAbstract(StatDefOf.WorkToMake, stuff).ToString("F0")); }), new TableDataGetter <Def>((stuff == null) ? "CanMake" : (stuff.defName + " CanMake"), delegate(Def d) { if (stuff == null) { return("n/a"); } ThingDef thingDef = d as ThingDef; if (thingDef == null) { return("-"); } return(stuff.stuffProps.CanMake(thingDef).ToStringCheckBlank()); }), new TableDataGetter <Def>("assumed\nmelee\nhit chance", (Def d) => 0.82f.ToStringPercent())); }
private void ImpactSomething() { if (def.projectile.flyOverhead) { RoofDef roofDef = base.Map.roofGrid.RoofAt(base.Position); if (roofDef != null) { if (roofDef.isThickRoof) { ThrowDebugText("hit-thick-roof", base.Position); def.projectile.soundHitThickRoof.PlayOneShot(new TargetInfo(base.Position, base.Map)); Destroy(); return; } if (base.Position.GetEdifice(base.Map) == null || base.Position.GetEdifice(base.Map).def.Fillage != FillCategory.Full) { RoofCollapserImmediate.DropRoofInCells(base.Position, base.Map); } } } if (usedTarget.HasThing && CanHit(usedTarget.Thing)) { Pawn pawn = usedTarget.Thing as Pawn; if (pawn != null && pawn.GetPosture() != 0 && (origin - destination).MagnitudeHorizontalSquared() >= 20.25f && !Rand.Chance(0.2f)) { ThrowDebugText("miss-laying", base.Position); Impact(null); } else { Impact(usedTarget.Thing); } return; } cellThingsFiltered.Clear(); List <Thing> thingList = base.Position.GetThingList(base.Map); for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if ((thing.def.category == ThingCategory.Building || thing.def.category == ThingCategory.Pawn || thing.def.category == ThingCategory.Item || thing.def.category == ThingCategory.Plant) && CanHit(thing)) { cellThingsFiltered.Add(thing); } } cellThingsFiltered.Shuffle(); for (int j = 0; j < cellThingsFiltered.Count; j++) { Thing thing2 = cellThingsFiltered[j]; Pawn pawn2 = thing2 as Pawn; float num; if (pawn2 != null) { num = 0.5f * Mathf.Clamp(pawn2.BodySize, 0.1f, 2f); if (pawn2.GetPosture() != 0 && (origin - destination).MagnitudeHorizontalSquared() >= 20.25f) { num *= 0.2f; } if (launcher != null && pawn2.Faction != null && launcher.Faction != null && !pawn2.Faction.HostileTo(launcher.Faction)) { num *= VerbUtility.InterceptChanceFactorFromDistance(origin, base.Position); } } else { num = 1.5f * thing2.def.fillPercent; } if (Rand.Chance(num)) { ThrowDebugText("hit-" + num.ToStringPercent(), base.Position); Impact(cellThingsFiltered.RandomElement()); return; } ThrowDebugText("miss-" + num.ToStringPercent(), base.Position); } Impact(null); }
private bool CheckForFreeIntercept(IntVec3 c) { if (destination.ToIntVec3() == c) { return(false); } float num = VerbUtility.InterceptChanceFactorFromDistance(origin, c); if (num <= 0f) { return(false); } bool flag = false; List <Thing> thingList = c.GetThingList(base.Map); for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (!CanHit(thing)) { continue; } bool flag2 = false; if (thing.def.Fillage == FillCategory.Full) { Building_Door building_Door = thing as Building_Door; if (building_Door == null || !building_Door.Open) { ThrowDebugText("int-wall", c); Impact(thing); return(true); } flag2 = true; } float num2 = 0f; Pawn pawn = thing as Pawn; if (pawn != null) { num2 = 0.4f * Mathf.Clamp(pawn.BodySize, 0.1f, 2f); if (pawn.GetPosture() != 0) { num2 *= 0.1f; } if (launcher != null && pawn.Faction != null && launcher.Faction != null && !pawn.Faction.HostileTo(launcher.Faction)) { num2 *= Find.Storyteller.difficultyValues.friendlyFireChanceFactor; } } else if (thing.def.fillPercent > 0.2f) { num2 = (flag2 ? 0.05f : ((!DestinationCell.AdjacentTo8Way(c)) ? (thing.def.fillPercent * 0.15f) : (thing.def.fillPercent * 1f))); } num2 *= num; if (num2 > 1E-05f) { if (Rand.Chance(num2)) { ThrowDebugText("int-" + num2.ToStringPercent(), c); Impact(thing); return(true); } flag = true; ThrowDebugText(num2.ToStringPercent(), c); } } if (!flag) { ThrowDebugText("o", c); } return(false); }
private bool CheckForFreeInterceptBetween(Vector3 lastExactPos, Vector3 newExactPos) { if (lastExactPos == newExactPos) { return(false); } List <Thing> list = base.Map.listerThings.ThingsInGroup(ThingRequestGroup.ProjectileInterceptor); for (int i = 0; i < list.Count; i++) { if (list[i].TryGetComp <CompProjectileInterceptor>().CheckIntercept(this, lastExactPos, newExactPos)) { Destroy(); return(true); } } IntVec3 intVec = lastExactPos.ToIntVec3(); IntVec3 intVec2 = newExactPos.ToIntVec3(); if (intVec2 == intVec) { return(false); } if (!intVec.InBounds(base.Map) || !intVec2.InBounds(base.Map)) { return(false); } if (intVec2.AdjacentToCardinal(intVec)) { return(CheckForFreeIntercept(intVec2)); } if (VerbUtility.InterceptChanceFactorFromDistance(origin, intVec2) <= 0f) { return(false); } Vector3 vect = lastExactPos; Vector3 v = newExactPos - lastExactPos; Vector3 vector = v.normalized * 0.2f; int num = (int)(v.MagnitudeHorizontal() / 0.2f); checkedCells.Clear(); int num2 = 0; IntVec3 intVec3; do { vect += vector; intVec3 = vect.ToIntVec3(); if (!checkedCells.Contains(intVec3)) { if (CheckForFreeIntercept(intVec3)) { return(true); } checkedCells.Add(intVec3); } num2++; if (num2 > num) { return(false); } }while (!(intVec3 == intVec2)); return(false); }
protected override bool TryCastShot() { if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map) { return(false); } ThingDef projectile = Projectile; if (projectile == null) { return(false); } ShootLine resultingLine; bool flag = TryFindShootLineFromTo(caster.Position, currentTarget, out resultingLine); if (verbProps.stopBurstWithoutLos && !flag) { return(false); } if (base.EquipmentSource != null) { base.EquipmentSource.GetComp <CompChangeableProjectile>()?.Notify_ProjectileLaunched(); } Thing launcher = caster; Thing equipment = base.EquipmentSource; CompMannable compMannable = caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = caster; } Vector3 drawPos = caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, resultingLine.Source, caster.Map); if (verbProps.forcedMissRadius > 0.5f) { float num = VerbUtility.CalculateAdjustedForcedMiss(verbProps.forcedMissRadius, currentTarget.Cell - caster.Position); if (num > 0.5f) { int max = GenRadial.NumCellsInRadius(num); int num2 = Rand.Range(0, max); if (num2 > 0) { IntVec3 c = currentTarget.Cell + GenRadial.RadialPattern[num2]; ThrowDebugText("ToRadius"); ThrowDebugText("Rad\nDest", c); ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.All; } if (!canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, drawPos, c, currentTarget, projectileHitFlags, equipment); return(true); } } } ShotReport shotReport = ShotReport.HitReportFor(caster, this, currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = randomCoverToMissInto?.def; if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture)) { resultingLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); ThrowDebugText("ToWild" + ((!canHitNonTargetPawnsNow) ? string.Empty : "\nchntp")); ThrowDebugText("Wild\nDest", resultingLine.Dest); ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f) && canHitNonTargetPawnsNow) { projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, drawPos, resultingLine.Dest, currentTarget, projectileHitFlags2, equipment, targetCoverDef); return(true); } if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance)) { ThrowDebugText("ToCover" + ((!canHitNonTargetPawnsNow) ? string.Empty : "\nchntp")); ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position); ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, drawPos, randomCoverToMissInto, currentTarget, projectileHitFlags3, equipment, targetCoverDef); return(true); } ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } ThrowDebugText("ToHit" + ((!canHitNonTargetPawnsNow) ? string.Empty : "\nchntp")); if (currentTarget.Thing != null) { projectile2.Launch(launcher, drawPos, currentTarget, currentTarget, projectileHitFlags4, equipment, targetCoverDef); ThrowDebugText("Hit\nDest", currentTarget.Cell); } else { projectile2.Launch(launcher, drawPos, resultingLine.Dest, currentTarget, projectileHitFlags4, equipment, targetCoverDef); ThrowDebugText("Hit\nDest", resultingLine.Dest); } return(true); }