protected override void Impact(Thing hitThing) { base.Impact(hitThing); if (!this.initialized) { this.caster = this.launcher as Pawn; CompAbilityUserMight comp = caster.GetComp <CompAbilityUserMight>(); //pwrVal = caster.GetComp<CompAbilityUserMight>().MightData.MightPowerSkill_GraveBlade.FirstOrDefault((MightPowerSkill x) => x.label == "TM_GraveBlade_pwr").level; //verVal = caster.GetComp<CompAbilityUserMight>().MightData.MightPowerSkill_GraveBlade.FirstOrDefault((MightPowerSkill x) => x.label == "TM_GraveBlade_ver").level; verVal = TM_Calc.GetMightSkillLevel(caster, comp.MightData.MightPowerSkill_GraveBlade, "TM_GraveBlade", "_ver", true); pwrVal = TM_Calc.GetMightSkillLevel(caster, comp.MightData.MightPowerSkill_GraveBlade, "TM_GraveBlade", "_pwr", true); //ModOptions.SettingsRef settingsRef = new ModOptions.SettingsRef(); this.arcaneDmg = comp.mightPwr; //if (settingsRef.AIHardMode && !caster.IsColonist) //{ // pwrVal = 3; // verVal = 3; //} this.radius = this.def.projectile.explosionRadius; this.duration = 10 + (int)(this.radius * 20); this.innerCellList = GenRadial.RadialCellsAround(base.Position, this.radius, true).ToList(); this.ringCellList = GenRadial.RadialCellsAround(base.Position, this.radius + 1, false).Except(innerCellList).ToList(); this.effectIndex2 = ringCellList.Count / 2; this.initialized = true; } if (this.Map != null) { if (Find.TickManager.TicksGame % this.effectDelay == 0) { Vector3 drawIndex1 = this.ringCellList[effectIndex1].ToVector3Shifted(); drawIndex1.x += Rand.Range(-.35f, .35f); drawIndex1.z += Rand.Range(-.35f, .35f); Vector3 drawIndex2 = this.ringCellList[effectIndex2].ToVector3Shifted(); drawIndex2.x += Rand.Range(-.35f, .35f); drawIndex2.z += Rand.Range(-.35f, .35f); TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_SpiritFlame"), drawIndex1, this.Map, Rand.Range(.4f, .8f), .1f, 0, .6f, 0, Rand.Range(.4f, 1f), Rand.Range(-20, 20), Rand.Range(-20, 20)); TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_SpiritFlame"), drawIndex2, this.Map, Rand.Range(.4f, .8f), .1f, 0, .6f, 0, Rand.Range(.4f, 1f), Rand.Range(-20, 20), Rand.Range(-20, 20)); this.effectIndex1++; this.effectIndex2++; if (this.effectIndex1 >= ringCellList.Count) { this.effectIndex1 = 0; } if (this.effectIndex2 >= ringCellList.Count) { this.effectIndex2 = 0; } } if (Find.TickManager.TicksGame % this.strikeDelay == 0 && !this.caster.DestroyedOrNull()) { IntVec3 centerCell = innerCellList.RandomElement(); IEnumerable <IntVec3> targetCells = GenRadial.RadialCellsAround(centerCell, 2f, true); foreach (var target in targetCells) { IntVec3 curCell = target; Pawn victim = curCell.GetFirstPawn(this.Map); if (victim != null && !victim.Destroyed && !victim.Dead && victim != this.caster) { TM_Action.DamageEntities(victim, null, (Rand.Range(10, 16) + (2 * pwrVal)) * this.arcaneDmg, TMDamageDefOf.DamageDefOf.TM_Spirit, this.launcher); if (!this.caster.DestroyedOrNull() && !this.caster.Dead && Rand.Chance(verVal)) { TM_Action.DoAction_HealPawn(this.caster, this.caster, 1, (Rand.Range(6, 10) + (2 * verVal)) * this.arcaneDmg); TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_SpiritRetaliation"), this.caster.DrawPos, this.caster.Map, Rand.Range(1f, 1.2f), Rand.Range(.1f, .15f), 0, Rand.Range(.1f, .2f), -600, 0, 0, Rand.Range(0, 360)); TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_SpiritRetaliation"), this.caster.DrawPos, this.caster.Map, Rand.Range(1f, 1.2f), Rand.Range(.1f, .15f), 0, Rand.Range(.1f, .2f), 600, 0, 0, Rand.Range(0, 360)); } if (Rand.Chance(verVal)) { if (!victim.IsWildMan() && victim.RaceProps.Humanlike && victim.mindState != null && !victim.InMentalState) { try { Job job = new Job(JobDefOf.FleeAndCower); //victim.mindState.mentalStateHandler.TryStartMentalState(TorannMagicDefOf.TM_PanicFlee); } catch (NullReferenceException) { } } } } } TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_GraveBlade"), centerCell.ToVector3Shifted(), this.Map, Rand.Range(1f, 1.6f), .15f, .1f, .2f, 0, Rand.Range(4f, 6f), 0, 0); } } }
private static void Impact(ProjectileCE __instance, Thing launcher, ThingDef equipmentDef, Thing hitThing, IntVec3 OriginIV3, Vector2 origin, Vector2 Destination, int StartingTicksToImpact, int ticksToImpact, int IntTicksToImpact, ref float suppressionAmount) { List <Thing> list = new List <Thing>(); if (__instance.Position.IsValid && __instance.def.projectile.preExplosionSpawnChance > 0f && __instance.def.projectile.preExplosionSpawnThingDef != null && (Controller.settings.EnableAmmoSystem || !(__instance.def.projectile.preExplosionSpawnThingDef is AmmoDef)) && Rand.Value < __instance.def.projectile.preExplosionSpawnChance) { ThingDef preExplosionSpawnThingDef = __instance.def.projectile.preExplosionSpawnThingDef; if (preExplosionSpawnThingDef.IsFilth && __instance.Position.Walkable(__instance.Map)) { FilthMaker.TryMakeFilth(__instance.Position, __instance.Map, preExplosionSpawnThingDef, 1, FilthSourceFlags.None); } else { bool reuseNeolithicProjectiles = Controller.settings.ReuseNeolithicProjectiles; if (reuseNeolithicProjectiles) { Thing thing = ThingMaker.MakeThing(preExplosionSpawnThingDef, null); thing.stackCount = 1; thing.SetForbidden(true, false); GenPlace.TryPlaceThing(thing, __instance.Position, __instance.Map, ThingPlaceMode.Near, null, null, default(Rot4)); LessonAutoActivator.TeachOpportunity(CE_ConceptDefOf.CE_ReusableNeolithicProjectiles, thing, OpportunityType.GoodToKnow); list.Add(thing); } } } Vector3 vector = (hitThing != null) ? hitThing.DrawPos : __instance.ExactPosition; bool flag3 = !vector.ToIntVec3().IsValid; if (flag3) { __instance.Destroy(DestroyMode.Vanish); } else { CompExplosiveCE compExplosiveCE = __instance.TryGetCompFast <CompExplosiveCE>(); if (compExplosiveCE == null) { CompFragments compFragments = __instance.TryGetCompFast <CompFragments>(); if (compFragments != null) { compFragments.Throw(vector, __instance.Map, launcher, 1f); } } if (compExplosiveCE != null || __instance.def.projectile.explosionRadius > 0f) { if (hitThing is Pawn && (hitThing as Pawn).Dead) { list.Add((hitThing as Pawn).Corpse); } List <Pawn> list2 = new List <Pawn>(); float? direction = new float?(origin.AngleTo(Vec2Position(__instance, origin, Destination, StartingTicksToImpact, ticksToImpact, IntTicksToImpact, -1f))); bool flag7 = __instance.def.projectile.explosionRadius > 0f; if (flag7) { GenExplosionCE.DoExplosion(vector.ToIntVec3(), __instance.Map, __instance.def.projectile.explosionRadius, __instance.def.projectile.damageDef, launcher, __instance.def.projectile.GetDamageAmount(1f, null), GenExplosionCE.GetExplosionAP(__instance.def.projectile), __instance.def.projectile.soundExplode, equipmentDef, __instance.def, null, __instance.def.projectile.postExplosionSpawnThingDef, __instance.def.projectile.postExplosionSpawnChance, __instance.def.projectile.postExplosionSpawnThingCount, __instance.def.projectile.applyDamageToExplosionCellsNeighbors, __instance.def.projectile.preExplosionSpawnThingDef, __instance.def.projectile.preExplosionSpawnChance, __instance.def.projectile.preExplosionSpawnThingCount, __instance.def.projectile.explosionChanceToStartFire, __instance.def.projectile.explosionDamageFalloff, direction, list, vector.y, 1f, false, null); bool flag8 = vector.y < 3f; if (flag8) { list2.AddRange(from x in GenRadial.RadialDistinctThingsAround(vector.ToIntVec3(), __instance.Map, 3f + __instance.def.projectile.explosionRadius, true) where x is Pawn select x as Pawn); } } bool flag9 = compExplosiveCE != null; if (flag9) { compExplosiveCE.Explode(__instance, vector, __instance.Map, 1f, direction, list); bool flag10 = vector.y < 3f; if (flag10) { list2.AddRange(from x in GenRadial.RadialDistinctThingsAround(vector.ToIntVec3(), __instance.Map, 3f + (compExplosiveCE.props as CompProperties_ExplosiveCE).explosiveRadius, true) where x is Pawn select x as Pawn); } } foreach (Pawn pawn in list2) { ApplySuppression(__instance, OriginIV3, pawn, launcher, ref suppressionAmount); } } __instance.Destroy(DestroyMode.Vanish); } }
public void SearchForTargets(IntVec3 center, float radius) { Pawn curPawnTarg = null; Building curBldgTarg = null; IntVec3 curCell; IEnumerable <IntVec3> targets = GenRadial.RadialCellsAround(center, radius, true); for (int i = 0; i < targets.Count(); i++) { curCell = targets.ToArray <IntVec3>()[i]; if (curCell.InBounds(base.Map) && curCell.IsValid) { curPawnTarg = curCell.GetFirstPawn(base.Map); curBldgTarg = curCell.GetFirstBuilding(base.Map); } if (curPawnTarg != null && curPawnTarg != launcher) { bool newTarg = false; if (this.age > this.lastStrike + (this.maxStrikeDelay - (int)Rand.Range(0 + (pwrVal * 20), 40 + (pwrVal * 15)))) { if (Rand.Chance(.1f)) { newTarg = true; } if (newTarg) { CellRect cellRect = CellRect.CenteredOn(curCell, 2); cellRect.ClipInsideMap(base.Map); DrawStrike(center, curPawnTarg.Position.ToVector3()); for (int k = 0; k < Rand.Range(1, 8); k++) { IntVec3 randomCell = cellRect.RandomCell; GenExplosion.DoExplosion(randomCell, base.Map, Rand.Range(.4f, .8f), TMDamageDefOf.DamageDefOf.TM_Lightning, this.launcher, Rand.Range(3 + 3 * pwrVal, 7 + 5 * pwrVal), SoundDefOf.Thunder_OnMap, null, null, null, 0f, 1, false, null, 0f, 1, 0.1f, true); } GenExplosion.DoExplosion(curPawnTarg.Position, base.Map, 1f, TMDamageDefOf.DamageDefOf.TM_Lightning, this.launcher, Rand.Range(3 + 3 * pwrVal, 7 + 5 * pwrVal), SoundDefOf.Thunder_OffMap, null, null, null, 0f, 1, false, null, 0f, 1, 0.1f, true); this.lastStrike = this.age; } } } if (curBldgTarg != null) { bool newTarg = false; if (this.age > this.lastStrikeBldg + (this.maxStrikeDelayBldg - (int)Rand.Range(0 + (pwrVal * 10), (pwrVal * 15)))) { if (Rand.Chance(.1f)) { newTarg = true; } if (newTarg) { CellRect cellRect = CellRect.CenteredOn(curCell, 1); cellRect.ClipInsideMap(base.Map); DrawStrike(center, curBldgTarg.Position.ToVector3()); for (int k = 0; k < Rand.Range(1, 8); k++) { IntVec3 randomCell = cellRect.RandomCell; GenExplosion.DoExplosion(randomCell, base.Map, Rand.Range(.2f, .6f), TMDamageDefOf.DamageDefOf.TM_Lightning, this.launcher, Rand.Range(3 + 3 * pwrVal, 7 + 5 * pwrVal), SoundDefOf.Thunder_OffMap, null, null, null, 0f, 1, false, null, 0f, 1, 0.1f, true); } GenExplosion.DoExplosion(curBldgTarg.Position, base.Map, 1f, TMDamageDefOf.DamageDefOf.TM_Lightning, this.launcher, Rand.Range(5 + 5 * pwrVal, 10 + 10 * pwrVal), SoundDefOf.Thunder_OffMap, null, null, null, 0f, 1, false, null, 0f, 1, 0.1f, true); this.lastStrikeBldg = this.age; } } } targets.GetEnumerator().MoveNext(); } DrawStrikeFading(); age++; }
protected override void Impact(Thing hitThing) { base.Impact(hitThing); ThingDef def = this.def; if (!this.initialized) { this.casterPawn = this.launcher as Pawn; CompAbilityUserMagic comp = casterPawn.GetComp <CompAbilityUserMagic>(); MagicPowerSkill pwr = comp.MagicData.MagicPowerSkill_ChronostaticField.FirstOrDefault((MagicPowerSkill x) => x.label == "TM_ChronostaticField_pwr"); MagicPowerSkill ver = comp.MagicData.MagicPowerSkill_ChronostaticField.FirstOrDefault((MagicPowerSkill x) => x.label == "TM_ChronostaticField_ver"); ModOptions.SettingsRef settingsRef = new ModOptions.SettingsRef(); pwrVal = pwr.level; verVal = ver.level; if (this.casterPawn.story.traits.HasTrait(TorannMagicDefOf.Faceless)) { MightPowerSkill mpwr = casterPawn.GetComp <CompAbilityUserMight>().MightData.MightPowerSkill_Mimic.FirstOrDefault((MightPowerSkill x) => x.label == "TM_Mimic_pwr"); MightPowerSkill mver = casterPawn.GetComp <CompAbilityUserMight>().MightData.MightPowerSkill_Mimic.FirstOrDefault((MightPowerSkill x) => x.label == "TM_Mimic_ver"); pwrVal = mpwr.level; verVal = mver.level; } this.arcaneDmg = comp.arcaneDmg; if (settingsRef.AIHardMode && !casterPawn.IsColonist) { pwrVal = 3; verVal = 3; } this.strikeDelay = this.strikeDelay - verVal; this.radius = this.def.projectile.explosionRadius; this.duration = Mathf.RoundToInt(this.radius * this.strikeDelay); this.initialized = true; //this.targets = GenRadial.RadialCellsAround(base.Position, this.radius, true); //cellList = targets.ToList<IntVec3>(); } cellList = new List <IntVec3>(); cellList.Clear(); cellList = GenRadial.RadialCellsAround(base.Position, this.radius, true).ToList(); //this.radius instead of 2 for (int i = 0; i < cellList.Count; i++) { if (cellList[i].IsValid && cellList[i].InBounds(this.Map)) { List <Thing> thingList = cellList[i].GetThingList(this.Map); if (thingList != null && thingList.Count > 0) { for (int j = 0; j < thingList.Count; j++) { Pawn pawn = thingList[j] as Pawn; if (pawn != null) { RemoveFireAt(thingList[j].Position); if (Rand.Chance(TM_Calc.GetSpellSuccessChance(this.casterPawn, pawn, false) * (.6f + (.1f * verVal)))) { IntVec3 targetCell = pawn.Position; targetCell.z++; LaunchFlyingObect(targetCell, pawn, 1, Mathf.RoundToInt(Rand.Range(1400, 1800) * (1f + (.2f * pwrVal)) * this.arcaneDmg)); } else { MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, "TM_ResistedSpell".Translate(), -1); } } } } } } this.age = this.duration; this.Destroy(DestroyMode.Vanish); }
/// <summary> /// Gets the best food source on the map for the given getter and eater pawns /// </summary> /// this function gets the best food source on the map for the given pawns, making sure to optimize for the case where /// a humanoid pawn can eat plants /// <param name="getter">The getter.</param> /// <param name="eater">The eater.</param> /// <param name="desperate">if set to <c>true</c> [desperate].</param> /// <param name="foodDef">The food definition.</param> /// <param name="maxPref">The maximum preference.</param> /// <param name="allowPlant">if set to <c>true</c> [allow plant].</param> /// <param name="allowDrug">if set to <c>true</c> [allow drug].</param> /// <param name="allowCorpse">if set to <c>true</c> [allow corpse].</param> /// <param name="allowDispenserFull">if set to <c>true</c> [allow dispenser full].</param> /// <param name="allowDispenserEmpty">if set to <c>true</c> [allow dispenser empty].</param> /// <param name="allowForbidden">if set to <c>true</c> [allow forbidden].</param> /// <param name="allowSociallyImproper">if set to <c>true</c> [allow socially improper].</param> /// <param name="allowHarvest">if set to <c>true</c> [allow harvest].</param> /// <param name="forceScanWholeMap">if set to <c>true</c> [force scan whole map].</param> /// <param name="ignoreReservations">if set to <c>true</c> [ignore reservations].</param> /// <param name="minPrefOverride">The minimum preference override.</param> /// <returns></returns> public static Thing BestFoodSourceOnMapOptimized( [NotNull] Pawn getter, [NotNull] Pawn eater, bool desperate, out ThingDef foodDef, FoodPreferability maxPref = FoodPreferability.MealLavish, bool allowPlant = true, bool allowDrug = true, bool allowCorpse = true, bool allowDispenserFull = true, bool allowDispenserEmpty = true, bool allowForbidden = false, bool allowSociallyImproper = false, bool allowHarvest = false, bool forceScanWholeMap = false, bool ignoreReservations = false, FoodPreferability minPrefOverride = FoodPreferability.Undefined) { if (getter == null) { throw new ArgumentNullException(nameof(getter)); } if (eater == null) { throw new ArgumentNullException(nameof(eater)); } foodDef = null; HungerCategory foodCurCategory = eater.needs.food.CurCategory; bool getterCanManipulate = getter.IsToolUser() && getter.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation); if (!getterCanManipulate && getter != eater) { Log.Error(getter + " tried to find food to bring to " + eater + " but " + getter + " is incapable of Manipulation."); return(null); } FoodPreferability minPref; if (minPrefOverride != FoodPreferability.Undefined) { minPref = minPrefOverride; } else if (!eater.NonHumanlikeOrWildMan()) //with the new patch, to 'recruit' sapient former humans pawns will need { if (!desperate) { if (foodCurCategory >= HungerCategory.UrgentlyHungry) { minPref = FoodPreferability.RawBad; } else { minPref = FoodPreferability.MealAwful; } } else { minPref = FoodPreferability.DesperateOnly; } } else { minPref = FoodPreferability.NeverForNutrition; } bool FoodValidator(Thing t) { if (allowDispenserFull && getterCanManipulate && t is Building_NutrientPasteDispenser nutrientPDispenser) { if (ThingDefOf.MealNutrientPaste.ingestible.preferability < minPref || ThingDefOf.MealNutrientPaste.ingestible.preferability > maxPref || !eater.WillEat(ThingDefOf.MealNutrientPaste, getter) || t.Faction != getter.Faction && t.Faction != getter.HostFaction || !allowForbidden && t.IsForbidden(getter) || !nutrientPDispenser.powerComp.PowerOn || !allowDispenserEmpty && !nutrientPDispenser.HasEnoughFeedstockInHoppers() || !t.InteractionCell.Standable(t.Map) || !IsFoodSourceOnMapSociallyProper(t, getter, eater, allowSociallyImproper) || !getter.Map.reachability.CanReachNonLocal(getter.Position, new TargetInfo(t.InteractionCell, t.Map), PathEndMode.OnCell, TraverseParms.For(getter, Danger.Some))) { return(false); } } else { FoodPreferability pref = GetAdjustedPreferability(eater, t); if (pref < minPref || pref > maxPref) { return(false); } if (!eater.WillEat(t, getter)) { return(false); } if (!t.def.IsNutritionGivingIngestible || !t.IngestibleNow) { return(false); } if (!allowCorpse && t is Corpse || !allowDrug && t.def.IsDrug || !allowForbidden && t.IsForbidden(getter) || !desperate && t.IsNotFresh() || t.IsDessicated() || !IsFoodSourceOnMapSociallyProper(t, getter, eater, allowSociallyImproper) || !getter.AnimalAwareOf(t) && !forceScanWholeMap || !ignoreReservations && !getter.CanReserve((LocalTargetInfo)t, 10, 1)) { return(false); } } return(true); } ThingRequest thingRequest; if (!CanEatPlants(eater, allowPlant, foodCurCategory)) { thingRequest = ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree); } else { thingRequest = ThingRequest.ForGroup(ThingRequestGroup.FoodSource); } Thing bestThing; if (getter.IsHumanlike()) { //TODO split up search for hungry humanlike into 2 phases //whole map search for good food //small search for good plants bestThing = SpawnedFoodSearchInnerScan(eater, getter.Position, getter.Map.listerThings.ThingsMatching(thingRequest), PathEndMode.ClosestTouch, TraverseParms.For(getter), 9999f, FoodValidator); if (allowHarvest & getterCanManipulate) { int searchRegionsMax = !forceScanWholeMap || bestThing != null ? 30 : -1; bool HarvestValidator(Thing x) { var t = (Plant)x; if (!t.HarvestableNow) { return(false); } ThingDef harvestedThingDef = t.def.plant.harvestedThingDef; return(harvestedThingDef.IsNutritionGivingIngestible && eater.WillEat(harvestedThingDef, getter) && getter.CanReserve((LocalTargetInfo)t) && (allowForbidden || !t.IsForbidden(getter)) && (bestThing == null || FoodUtility.GetFinalIngestibleDef(bestThing) .ingestible.preferability < harvestedThingDef.ingestible.preferability)); } Thing foodSource = GenClosest.ClosestThingReachable(getter.Position, getter.Map, ThingRequest.ForGroup(ThingRequestGroup.HarvestablePlant), PathEndMode.Touch, TraverseParms.For(getter), 9999f, HarvestValidator, null, 0, searchRegionsMax); if (foodSource != null) { bestThing = foodSource; foodDef = FoodUtility.GetFinalIngestibleDef(foodSource, true); } } if (foodDef == null && bestThing != null) { foodDef = FoodUtility.GetFinalIngestibleDef(bestThing); } } else { int maxRegionsToScan = GetMaxRegionsToScan(getter, forceScanWholeMap, foodCurCategory); //this is where the lag comes from //humanlikes alwayse scan the whole map filtered.Clear(); foreach (Thing thing in GenRadial.RadialDistinctThingsAround(getter.Position, getter.Map, 2f, true)) { var pawn = thing as Pawn; if (pawn != null && pawn != getter && pawn.RaceProps.Animal && pawn.CurJob != null && pawn.CurJob.def == JobDefOf.Ingest && pawn.CurJob.GetTarget(TargetIndex.A).HasThing) { filtered.Add(pawn.CurJob.GetTarget(TargetIndex.A).Thing); } } bool ignoreEntirelyForbiddenRegions = !allowForbidden && ForbidUtility.CaresAboutForbidden(getter, true) && getter.playerSettings?.EffectiveAreaRestrictionInPawnCurrentMap != null; var validator = (Predicate <Thing>)(t => FoodValidator(t) && !filtered.Contains(t) && (t is Building_NutrientPasteDispenser || t.def.ingestible.preferability > FoodPreferability.DesperateOnly) && !t.IsNotFresh()); bestThing = GenClosest.ClosestThingReachable(getter.Position, getter.Map, thingRequest, PathEndMode.ClosestTouch, TraverseParms.For(getter), 9999f, validator, null, 0, maxRegionsToScan, false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions); filtered.Clear(); if (bestThing == null) { desperate = true; bestThing = GenClosest.ClosestThingReachable(getter.Position, getter.Map, thingRequest, PathEndMode.ClosestTouch, TraverseParms.For(getter), 9999f, FoodValidator, null, 0, maxRegionsToScan, false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions); } if (bestThing != null) { foodDef = FoodUtility.GetFinalIngestibleDef(bestThing); } } return(bestThing); }
protected override bool TryCastShot() { if (this.currentTarget.HasThing && this.currentTarget.Thing.Map != this.caster.Map) { return(false); } ThingDef projectile = this.Projectile; if (projectile == null) { return(false); } ShootLine shootLine; bool flag = base.TryFindShootLineFromTo(this.caster.Position, this.currentTarget, out shootLine); if (this.verbProps.stopBurstWithoutLos && !flag) { return(false); } if (base.EquipmentSource != null) { CompChangeableProjectile comp = base.EquipmentSource.GetComp <CompChangeableProjectile>(); if (comp != null) { comp.Notify_ProjectileLaunched(); } } Thing launcher = this.caster; Thing equipment = base.EquipmentSource; CompMannable compMannable = this.caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = this.caster; } Vector3 drawPos = this.caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, this.caster.Map, WipeMode.Vanish); if (this.verbProps.forcedMissRadius > 0.5f) { float num = VerbUtility.CalculateAdjustedForcedMiss(this.verbProps.forcedMissRadius, this.currentTarget.Cell - this.caster.Position); if (num > 0.5f) { int max = GenRadial.NumCellsInRadius(num); int num2 = Rand.Range(0, max); if (num2 > 0) { IntVec3 c = this.currentTarget.Cell + GenRadial.RadialPattern[num2]; this.ThrowDebugText("ToRadius"); this.ThrowDebugText("Rad\nDest", c); ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.All; } if (!this.canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, drawPos, c, this.currentTarget, projectileHitFlags, equipment, null); return(true); } } } ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, this.currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = (randomCoverToMissInto == null) ? null : randomCoverToMissInto.def; if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture)) { shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); this.ThrowDebugText("ToWild" + ((!this.canHitNonTargetPawnsNow) ? string.Empty : "\nchntp")); this.ThrowDebugText("Wild\nDest", shootLine.Dest); ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f) && this.canHitNonTargetPawnsNow) { projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags2, equipment, targetCoverDef); return(true); } if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance)) { this.ThrowDebugText("ToCover" + ((!this.canHitNonTargetPawnsNow) ? string.Empty : "\nchntp")); this.ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position); ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (this.canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, drawPos, randomCoverToMissInto, this.currentTarget, projectileHitFlags3, equipment, targetCoverDef); return(true); } ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (this.canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } this.ThrowDebugText("ToHit" + ((!this.canHitNonTargetPawnsNow) ? string.Empty : "\nchntp")); if (this.currentTarget.Thing != null) { projectile2.Launch(launcher, drawPos, this.currentTarget, this.currentTarget, projectileHitFlags4, equipment, targetCoverDef); this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell); } else { projectile2.Launch(launcher, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags4, equipment, targetCoverDef); this.ThrowDebugText("Hit\nDest", shootLine.Dest); } if (this.CasterIsPawn) { VEF_ReflectionData.FI_Bullet_WeaponDamageMultiplier.SetValue(projectile2, (float)VEF_ReflectionData.FI_Bullet_WeaponDamageMultiplier.GetValue(projectile2) + ((this.caster.def.race.baseBodySize - 1f) * 0.5f)); } return(true); }
public IEnumerable <IntVec3> CellsWithinRange(IntVec3 center) { return(GenRadial.RadialCellsAround(center, this.range, true)); }
protected override void Impact(Thing hitThing) { Map map = base.Map; base.Impact(hitThing); ThingDef def = this.def; if (!this.initialized) { this.bloodCircleOuterCells = new List <IntVec3>(); this.bloodCircleOuterCells.Clear(); this.victimHitTick = new List <int>(); this.victimHitTick.Clear(); this.victims = new List <Pawn>(); this.victims.Clear(); this.wolfDmg = new List <float>(); this.wolfDmg.Clear(); caster = this.launcher as Pawn; CompAbilityUserMagic comp = caster.GetComp <CompAbilityUserMagic>(); MagicPowerSkill bpwr = comp.MagicData.MagicPowerSkill_BloodGift.FirstOrDefault((MagicPowerSkill x) => x.label == "TM_BloodGift_pwr"); pwrVal = caster.GetComp <CompAbilityUserMagic>().MagicData.MagicPowerSkill_BloodMoon.FirstOrDefault((MagicPowerSkill x) => x.label == "TM_BloodMoon_pwr").level; verVal = caster.GetComp <CompAbilityUserMagic>().MagicData.MagicPowerSkill_BloodMoon.FirstOrDefault((MagicPowerSkill x) => x.label == "TM_BloodMoon_ver").level; effVal = caster.GetComp <CompAbilityUserMagic>().MagicData.MagicPowerSkill_BloodMoon.FirstOrDefault((MagicPowerSkill x) => x.label == "TM_BloodMoon_eff").level; this.arcaneDmg = comp.arcaneDmg; this.arcaneDmg *= 1f + (.1f * bpwr.level); this.attackFrequency *= 1 - (.05f * effVal); this.duration = Mathf.RoundToInt(this.duration + (this.duration * .1f * verVal)); this.angle = Rand.Range(-2f, 2f); this.radius = this.def.projectile.explosionRadius; IntVec3 curCell = base.Position; this.CheckSpawnSustainer(); if (curCell.InBounds(map) && curCell.IsValid) { IEnumerable <IntVec3> cellList = GenRadial.RadialCellsAround(base.Position, this.radius, true); foreach (var cell in cellList) { curCell = cell; if (curCell.InBounds(map) && curCell.IsValid) { this.bloodCircleCells.Add(curCell); } } cellList = GenRadial.RadialCellsAround(base.Position, this.radius + 1, true); List <IntVec3> outerRing = new List <IntVec3>(); foreach (var cell in cellList) { curCell = cell; if (curCell.InBounds(map) && curCell.IsValid) { outerRing.Add(curCell); } } this.bloodCircleOuterCells = outerRing.Except(this.bloodCircleCells).ToList(); } TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_BloodCircle"), base.Position.ToVector3Shifted(), caster.Map, this.radius + 2, this.duration / 60 * .9f, this.duration / 60 * .06f, this.duration / 60 * .08f, Rand.Range(-50, -50), 0, 0, Rand.Range(0, 360)); TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_BloodCircle"), base.Position.ToVector3Shifted(), caster.Map, this.radius + 2, this.duration / 60 * .9f, this.duration / 60 * .06f, this.duration / 60 * .08f, Rand.Range(50, 50), 0, 0, Rand.Range(0, 360)); TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_BloodCircle"), base.Position.ToVector3Shifted(), caster.Map, this.radius + 2, this.duration / 60 * .9f, this.duration / 60 * .06f, this.duration / 60 * .08f, Rand.Range(-50, 50), 0, 0, Rand.Range(0, 360)); caster.Map.weatherManager.eventHandler.AddEvent(new TM_WeatherEvent_BloodMoon(caster.Map, this.duration, 2f - (this.pwrVal * .1f))); this.initialized = true; } if (this.initialized && this.Map != null && this.age > 15) { if (this.victims.Count > 0) { for (int i = 0; i < this.victims.Count; i++) { if (this.victimHitTick[i] < this.age) { TM_Action.DamageEntities(victims[i], null, Mathf.RoundToInt(Rand.Range(5, 8) * this.wolfDmg[i] * this.arcaneDmg), DamageDefOf.Bite, this.launcher); TM_MoteMaker.ThrowBloodSquirt(victims[i].DrawPos, victims[i].Map, Rand.Range(.6f, 1f)); this.victims.Remove(this.victims[i]); this.victimHitTick.Remove(this.victimHitTick[i]); this.wolfDmg.Remove(this.wolfDmg[i]); } } } if (Find.TickManager.TicksGame % this.bloodFrequency == 0) { Filth filth = (Filth)ThingMaker.MakeThing(ThingDefOf.Filth_Blood); GenSpawn.Spawn(filth, this.bloodCircleOuterCells.RandomElement(), this.Map); } if (this.nextAttack < this.age && !this.caster.DestroyedOrNull() && !this.caster.Dead) { Pawn victim = TM_Calc.FindNearbyEnemy(base.Position, this.Map, this.caster.Faction, this.radius, 0); if (victim != null) { IntVec3 rndPos = victim.Position; while (rndPos == victim.Position) { rndPos = this.bloodCircleCells.RandomElement(); } Vector3 wolf = rndPos.ToVector3Shifted(); Vector3 direction = TM_Calc.GetVector(wolf, victim.DrawPos); float angle = direction.ToAngleFlat(); float fadeIn = .1f; float fadeOut = .25f; float solidTime = .10f; float drawSize = Rand.Range(.7f, 1.2f) + (this.pwrVal * .1f); float velocity = (victim.DrawPos - wolf).MagnitudeHorizontal(); if (angle >= -135 && angle < -45) //north { TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_BloodWolfNorth"), wolf, this.Map, drawSize, solidTime, fadeIn, fadeOut, 0, 2 * velocity, (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 0); } else if (angle >= 45 && angle < 135) //south { TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_BloodWolfSouth"), wolf, this.Map, drawSize, solidTime, fadeIn, fadeOut, 0, 2 * velocity, (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 0); } else if (angle >= -45 && angle < 45) //east { TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_BloodWolfEast"), wolf, this.Map, drawSize, solidTime, fadeIn, fadeOut, 0, 2 * velocity, (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 0); } else //west { TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_BloodWolfWest"), wolf, this.Map, drawSize, solidTime, fadeIn, fadeOut, 0, 2 * velocity, (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 0); } int hitDelay = this.age + this.delayTicks; Effecter BloodShieldEffect = TorannMagicDefOf.TM_BloodShieldEffecter.Spawn(); BloodShieldEffect.Trigger(new TargetInfo(wolf.ToIntVec3(), this.Map, false), new TargetInfo(wolf.ToIntVec3(), this.Map, false)); BloodShieldEffect.Cleanup(); this.victims.Add(victim); this.victimHitTick.Add(hitDelay); this.wolfDmg.Add(drawSize); if (Rand.Chance(.1f)) { if (Rand.Chance(.65f)) { SoundInfo info = SoundInfo.InMap(new TargetInfo(wolf.ToIntVec3(), this.Map, false), MaintenanceType.None); SoundDef.Named("TM_DemonCallHigh").PlayOneShot(info); } else { SoundInfo info = SoundInfo.InMap(new TargetInfo(wolf.ToIntVec3(), this.Map, false), MaintenanceType.None); info.pitchFactor = .8f; info.volumeFactor = .8f; SoundDef.Named("TM_DemonPain").PlayOneShot(info); } } } this.nextAttack = this.age + Mathf.RoundToInt(Rand.Range(.4f * (float)this.attackFrequency, .8f * (float)this.attackFrequency)); } } }
public override void Tick() { if (this.triggered) { if (this.age >= this.lastStrike + this.strikeDelay) { try { IntVec3 curCell; IEnumerable <IntVec3> targets = GenRadial.RadialCellsAround(base.Position, this.radius, true); foreach (var cell in targets) { curCell = cell; if (curCell.InBounds(base.Map) && curCell.IsValid) { Pawn victim = curCell.GetFirstPawn(base.Map); if (victim != null && !victim.Dead && victim.RaceProps.IsFlesh) { BodyPartRecord bpr = null; bpr = victim.def.race.body.AllParts.InRandomOrder().FirstOrDefault <BodyPartRecord>((BodyPartRecord x) => x.def.tags.Contains(BodyPartTagDefOf.BreathingSource)); TM_Action.DamageEntities(victim, bpr, Rand.Range(1f, 2f), 2f, TMDamageDefOf.DamageDefOf.TM_Poison, this); } } } } catch { Log.Message("Debug: poison trap failed to process triggered event - terminating poison trap"); this.Destroy(DestroyMode.Vanish); } this.lastStrike = this.age; } this.age++; if (this.age > this.duration) { CheckForAgent(); if (destroyAfterUse) { Destroy(); } else { this.age = 0; triggered = false; rearming = true; this.lastStrike = 0; } } } else if (rearming) { this.age++; if (this.age > this.ticksTillReArm) { this.age = 0; rearming = false; triggered = false; } } else { try { if (this.Armed) { IntVec3 curCell; IEnumerable <IntVec3> targets = GenRadial.RadialCellsAround(base.Position, 2, true); foreach (var cell in targets) { curCell = cell; List <Thing> thingList = curCell.GetThingList(base.Map); for (int j = 0; j < thingList.Count; j++) { Pawn pawn = thingList[j] as Pawn; if (pawn != null && !this.touchingPawns.Contains(pawn)) { if (!pawn.RaceProps.Animal && pawn.Faction != null && pawn.Faction != this.Faction && pawn.HostileTo(this.Faction)) { this.touchingPawns.Add(pawn); this.CheckSpring(pawn); } } } } } this.touchingPawns.RemoveAll(pawn2 => !pawn2.Spawned || pawn2.Position != base.Position); } catch { Log.Message("Debug: poison trap failed to process armed event - terminating poison trap"); this.Destroy(DestroyMode.Vanish); } } base.Tick(); }
static public IEnumerable <Thing> FindItemThingsNearBuilding(Map map, Thing centerBuilding, int radius) { return(GenRadial.RadialDistinctThingsAround(centerBuilding.Position, map, radius, true).Where(x => x.def.category == ThingCategory.Item)); }
public void StartExplosionCE(SoundDef explosionSound, List <Thing> ignoredThings) //Removed cellsToAffect by Worker { if (Controller.settings.MergeExplosions) { ExplosionCE existingExplosion = Position.GetThingList(Map).FirstOrDefault(x => x.def == CE_ThingDefOf.ExplosionCE && x != this && !(x as ExplosionCE).toBeMerged) as ExplosionCE; if (existingExplosion == null) { var i = 1; var num = GenRadial.NumCellsInRadius(MaxMergeRange); while (i < num && existingExplosion == null) { IntVec3 c = Position + GenRadial.RadialPattern[i]; if (c.InBounds(Map)) { existingExplosion = c.GetThingList(Map).FirstOrDefault(x => x.def == CE_ThingDefOf.ExplosionCE && x != this && !(x as ExplosionCE).toBeMerged) as ExplosionCE; } i++; } } if (existingExplosion != null) { if (MergeWith(existingExplosion, out var merged, out var nonMerged)) { nonMerged.toBeMerged = true; //Was possible to merge, destroy nonmerged (later) and start merged. merged.RestartAfterMerge(explosionSound); return; } } } if (!Spawned) { Log.Error("Called StartExplosion() on unspawned thing."); return; } if (this.ignoredThings.NullOrEmpty()) { this.ignoredThings = ignoredThings; } startTick = Find.TickManager.TicksGame; cellsToAffect.Clear(); damagedThings.Clear(); addedCellsAffectedOnlyByDamage.Clear(); //this.cellsToAffect.AddRange(this.damType.Worker.ExplosionCellsToHit(this)); cellsToAffect.AddRange(ExplosionCellsToHit); if (applyDamageToExplosionCellsNeighbors) { AddCellsNeighbors(cellsToAffect); } damType.Worker.ExplosionStart(this, cellsToAffect); PlayExplosionSound(explosionSound); MoteMaker.MakeWaterSplash(Position.ToVector3Shifted(), Map, radius * 6f, 20f); cellsToAffect.Sort((IntVec3 a, IntVec3 b) => GetCellAffectTick(b).CompareTo(GetCellAffectTick(a))); RegionTraverser.BreadthFirstTraverse(Position, Map, (Region from, Region to) => true, delegate(Region x) { var list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn); for (var i = list.Count - 1; i >= 0; i--) { ((Pawn)list[i]).mindState.Notify_Explosion(this); } return(false); }, 25, RegionType.Set_Passable); }
public static bool CanSpawnAt(IntVec3 c, Map map, int minProximityToArtificialStructures = 40, int minProximityToCenter = 0, int minFertileUnroofedCells = 22, int maxFertileUnroofedCellRadius = 10) { if (!c.Standable(map) || c.Fogged(map) || !c.GetRoom(map).PsychologicallyOutdoors) { return(false); } Plant plant = c.GetPlant(map); if (plant != null && plant.def.plant.growDays > 10f) { return(false); } List <Thing> thingList = c.GetThingList(map); for (int i = 0; i < thingList.Count; i++) { if (thingList[i].def == ThingDefOf.Plant_TreeAnima) { return(false); } } if (minProximityToCenter > 0 && map.Center.InHorDistOf(c, minProximityToCenter)) { return(false); } if (!map.reachability.CanReachFactionBase(c, map.ParentFaction)) { return(false); } TerrainDef terrain = c.GetTerrain(map); if (terrain.avoidWander || terrain.fertility <= 0f) { return(false); } if (c.Roofed(map)) { return(false); } if (minProximityToArtificialStructures != 0 && GenRadial.RadialDistinctThingsAround(c, map, minProximityToArtificialStructures, useCenter: false).Any(MeditationUtility.CountsAsArtificialBuilding)) { return(false); } int num = GenRadial.NumCellsInRadius(maxFertileUnroofedCellRadius); int num2 = 0; for (int j = 0; j < num; j++) { IntVec3 intVec = c + GenRadial.RadialPattern[j]; if (WanderUtility.InSameRoom(intVec, c, map)) { if (intVec.InBounds(map) && !intVec.Roofed(map) && intVec.GetTerrain(map).fertility > 0f) { num2++; } if (num2 >= minFertileUnroofedCells) { return(true); } } } return(false); }
public override bool TryCastShot() { if (this.currentTarget.HasThing && this.currentTarget.Thing.Map != this.Caster.Map) { return(false); } ThingDef projectile = this.Projectile; if (projectile == null) { return(false); } bool flag = base.TryFindShootLineFromTo(this.Caster.Position, this.currentTarget, out ShootLine shootLine); if (this.verbProps.stopBurstWithoutLos && !flag) { return(false); } Vector3 muzzlePos; if (turretGun != null) { if (turretGun.UseAmmo) { bool playerpawn = this.CasterIsPawn && this.Caster.Faction == Faction.OfPlayer; if (turretGun.HasAmmo) { turretGun.UsedOnce(); } else { return(false); } if (turretGun.RemainingCharges == 0) { if (turretGun.Props.soundEmptyWarning != null && playerpawn) { turretGun.Props.soundEmptyWarning.PlayOneShot(new TargetInfo(this.Caster.Position, this.Caster.Map, false)); } if (!turretGun.Props.messageEmptyWarning.NullOrEmpty() && playerpawn) { MoteMaker.ThrowText(Caster.Position.ToVector3(), Caster.Map, turretGun.Props.messageEmptyWarning.Translate(EquipmentSource.LabelCap, Caster.LabelShortCap), 3f); } } float a = turretGun.RemainingCharges; float b = turretGun.MaxCharges; int remaining = (int)(a / b * 100f); if (remaining == 50 && warningticks == 0) { warningticks = this.verbProps.ticksBetweenBurstShots + 1; if (turretGun.Props.soundHalfRemaningWarning != null && playerpawn) { turretGun.Props.soundHalfRemaningWarning.PlayOneShot(new TargetInfo(this.Caster.Position, this.Caster.Map, false)); } if (!turretGun.Props.messageHalfRemaningWarning.NullOrEmpty() && playerpawn) { MoteMaker.ThrowText(Caster.Position.ToVector3(), Caster.Map, turretGun.Props.messageHalfRemaningWarning.Translate(EquipmentSource.LabelCap, Caster.LabelShortCap, remaining), 3f); } } if (remaining == 25 && warningticks == 0) { warningticks = this.verbProps.ticksBetweenBurstShots + 1; if (turretGun.Props.soundQuaterRemaningWarning != null && playerpawn) { turretGun.Props.soundQuaterRemaningWarning.PlayOneShot(new TargetInfo(this.Caster.Position, this.Caster.Map, false)); } if (!turretGun.Props.messageQuaterRemaningWarning.NullOrEmpty() && playerpawn) { MoteMaker.ThrowText(Caster.Position.ToVector3(), Caster.Map, turretGun.Props.messageQuaterRemaningWarning.Translate(EquipmentSource.LabelCap, Caster.LabelShortCap, remaining), 3f); } } muzzlePos = MuzzlePosition(this.Caster, this.currentTarget, offset); } } else { Log.Error(Caster + "'s " + this + " has no Comp_Turret"); return(false); } Thing launcher = this.Caster; Thing equipment = base.EquipmentSource; Vector3 drawPos = this.Caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, this.Caster.Map, WipeMode.Vanish); if (this.verbProps.forcedMissRadius > 0.5f) { float num = VerbUtility.CalculateAdjustedForcedMiss(this.verbProps.forcedMissRadius, this.currentTarget.Cell - this.Caster.Position); if (num > 0.5f) { int max = GenRadial.NumCellsInRadius(num); Rand.PushState(); int num2 = Rand.Range(0, max); Rand.PopState(); if (num2 > 0) { IntVec3 c = this.currentTarget.Cell + GenRadial.RadialPattern[num2]; this.ThrowDebugText("ToRadius"); this.ThrowDebugText("Rad\nDest", c); ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; Rand.PushState(); if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.All; } Rand.PopState(); if (!this.canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } muzzlePos = MuzzlePosition(this.Caster, this.currentTarget, offset); projectile2.Launch(launcher, muzzlePos, c, this.currentTarget, projectileHitFlags, this.preventFriendlyFire, equipment, null); if (this.CasterIsPawn) { this.CasterPawn.records.Increment(RecordDefOf.ShotsFired); } return(true); } } } ShotReport shotReport = ShotReport.HitReportFor(this.Caster, this, this.currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = (randomCoverToMissInto != null) ? randomCoverToMissInto.def : null; Rand.PushState(); bool f = !Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture); Rand.PopState(); if (f) { shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); this.ThrowDebugText("ToWild" + (this.canHitNonTargetPawnsNow ? "\nchntp" : "")); this.ThrowDebugText("Wild\nDest", shootLine.Dest); ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; Rand.PushState(); if (Rand.Chance(0.5f) && this.canHitNonTargetPawnsNow) { projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; } Rand.PopState(); muzzlePos = MuzzlePosition(this.Caster, this.currentTarget, offset); projectile2.Launch(launcher, muzzlePos, shootLine.Dest, this.currentTarget, projectileHitFlags2, this.preventFriendlyFire, equipment, targetCoverDef); if (this.CasterIsPawn) { this.CasterPawn.records.Increment(RecordDefOf.ShotsFired); } return(true); } Rand.PushState(); bool f2 = !Rand.Chance(shotReport.PassCoverChance); Rand.PopState(); if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn && f2) { this.ThrowDebugText("ToCover" + (this.canHitNonTargetPawnsNow ? "\nchntp" : "")); this.ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position); ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (this.canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } muzzlePos = MuzzlePosition(this.Caster, this.currentTarget, offset); projectile2.Launch(launcher, muzzlePos, randomCoverToMissInto, this.currentTarget, projectileHitFlags3, this.preventFriendlyFire, equipment, targetCoverDef); if (this.CasterIsPawn) { this.CasterPawn.records.Increment(RecordDefOf.ShotsFired); } return(true); } ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (this.canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } this.ThrowDebugText("ToHit" + (this.canHitNonTargetPawnsNow ? "\nchntp" : "")); muzzlePos = MuzzlePosition(this.Caster, this.currentTarget, offset); if (this.currentTarget.Thing != null) { projectile2.Launch(launcher, muzzlePos, this.currentTarget, this.currentTarget, projectileHitFlags4, this.preventFriendlyFire, equipment, targetCoverDef); this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell); } else { projectile2.Launch(launcher, muzzlePos, shootLine.Dest, this.currentTarget, projectileHitFlags4, this.preventFriendlyFire, equipment, targetCoverDef); this.ThrowDebugText("Hit\nDest", shootLine.Dest); } if (this.CasterIsPawn) { this.CasterPawn.records.Increment(RecordDefOf.ShotsFired); } return(true); }
private void Initialize() { caster = this.launcher as Pawn; CompAbilityUserMagic comp = caster.GetComp <CompAbilityUserMagic>(); pwrVal = caster.GetComp <CompAbilityUserMagic>().MagicData.MagicPowerSkill_EarthernHammer.FirstOrDefault((MagicPowerSkill x) => x.label == "TM_EarthernHammer_pwr").level; verVal = caster.GetComp <CompAbilityUserMagic>().MagicData.MagicPowerSkill_EarthernHammer.FirstOrDefault((MagicPowerSkill x) => x.label == "TM_EarthernHammer_ver").level; ModOptions.SettingsRef settingsRef = new ModOptions.SettingsRef(); if (caster.story.traits.HasTrait(TorannMagicDefOf.Faceless)) { pwrVal = caster.GetComp <CompAbilityUserMight>().MightData.MightPowerSkill_Mimic.FirstOrDefault((MightPowerSkill x) => x.label == "TM_Mimic_pwr").level; verVal = caster.GetComp <CompAbilityUserMight>().MightData.MightPowerSkill_Mimic.FirstOrDefault((MightPowerSkill x) => x.label == "TM_Mimic_ver").level; } this.arcaneDmg = comp.arcaneDmg; if (settingsRef.AIHardMode && !caster.IsColonist) { pwrVal = 3; verVal = 3; } this.gravityPoints = this.baseGravityPoints + (pwrVal * 2); this.launchCells = new List <IntVec3>(); this.launchCells.Clear(); this.launchCells = GenRadial.RadialCellsAround(caster.Position, this.radius, false).ToList(); for (int i = 0; i < launchCells.Count(); i++) { if (launchCells[i].IsValid && launchCells[i].InBounds(caster.Map)) { List <Thing> cellList = launchCells[i].GetThingList(caster.Map); bool invalidCell = false; for (int j = 0; j < cellList.Count(); j++) { try { if (cellList[j].def.designationCategory != null) { if (cellList[j].def.designationCategory == DesignationCategoryDefOf.Structure || cellList[j].def.altitudeLayer == AltitudeLayer.Building || cellList[j].def.altitudeLayer == AltitudeLayer.Item || cellList[j].def.altitudeLayer == AltitudeLayer.ItemImportant) { invalidCell = true; } } if (cellList[j].def.thingCategories != null) { if (cellList[j].def.thingCategories.Contains(ThingCategoryDefOf.StoneChunks) || cellList[j].def.thingCategories.Contains(ThingCategoryDefOf.StoneBlocks)) { this.launchableThings.Add(cellList[j]); } } } catch (NullReferenceException ex) { //Log.Message("threw exception " + ex); } } if (invalidCell) { launchCells.Remove(launchCells[i]); } } } }
protected virtual void Impact(Thing hitThing) { var ignoredThings = new List <Thing>(); //Spawn things from preExplosionSpawnThingDef != null if (Position.IsValid && def.projectile.preExplosionSpawnChance > 0 && def.projectile.preExplosionSpawnThingDef != null && (Controller.settings.EnableAmmoSystem || !(def.projectile.preExplosionSpawnThingDef is AmmoDef)) && Rand.Value < def.projectile.preExplosionSpawnChance) { var thingDef = def.projectile.preExplosionSpawnThingDef; if (thingDef.IsFilth && Position.Walkable(Map)) { FilthMaker.TryMakeFilth(Position, Map, thingDef); } else if (Controller.settings.ReuseNeolithicProjectiles) { var reusableAmmo = ThingMaker.MakeThing(thingDef); reusableAmmo.stackCount = 1; reusableAmmo.SetForbidden(true, false); GenPlace.TryPlaceThing(reusableAmmo, Position, Map, ThingPlaceMode.Near); LessonAutoActivator.TeachOpportunity(CE_ConceptDefOf.CE_ReusableNeolithicProjectiles, reusableAmmo, OpportunityType.GoodToKnow); ignoredThings.Add(reusableAmmo); } } var explodePos = hitThing?.DrawPos ?? ExactPosition; if (!explodePos.ToIntVec3().IsValid) { Destroy(); return; } var explodingComp = this.TryGetComp <CompExplosiveCE>(); if (explodingComp == null) { this.TryGetComp <CompFragments>()?.Throw(explodePos, Map, launcher); } //If the comp exists, it'll already call CompFragments if (explodingComp != null || def.projectile.explosionRadius > 0) { //Handle anything explosive if (hitThing is Pawn && (hitThing as Pawn).Dead) { ignoredThings.Add((hitThing as Pawn).Corpse); } var suppressThings = new List <Pawn>(); var dir = new float?(origin.AngleTo(Vec2Position())); // Opt-out for things without explosionRadius if (def.projectile.explosionRadius > 0) { GenExplosionCE.DoExplosion(explodePos.ToIntVec3(), Map, def.projectile.explosionRadius, def.projectile.damageDef, launcher, def.projectile.GetDamageAmount(1), def.projectile.GetDamageAmount(1) * 0.1f, def.projectile.soundExplode, equipmentDef, def, null, def.projectile.postExplosionSpawnThingDef, def.projectile.postExplosionSpawnChance, def.projectile.postExplosionSpawnThingCount, def.projectile.applyDamageToExplosionCellsNeighbors, def.projectile.preExplosionSpawnThingDef, def.projectile.preExplosionSpawnChance, def.projectile.preExplosionSpawnThingCount, def.projectile.explosionChanceToStartFire, def.projectile.explosionDamageFalloff, dir, ignoredThings, explodePos.y); // Apply suppression around impact area if (explodePos.y < SuppressionRadius) { suppressThings.AddRange(GenRadial.RadialDistinctThingsAround(explodePos.ToIntVec3(), Map, SuppressionRadius + def.projectile.explosionRadius, true) .Where(x => x is Pawn).Select(x => x as Pawn)); } } if (explodingComp != null) { explodingComp.Explode(this, explodePos, Map, 1f, dir, ignoredThings); if (explodePos.y < SuppressionRadius) { suppressThings.AddRange(GenRadial.RadialDistinctThingsAround(explodePos.ToIntVec3(), Map, SuppressionRadius + (explodingComp.props as CompProperties_ExplosiveCE).explosiveRadius, true) .Where(x => x is Pawn).Select(x => x as Pawn)); } } foreach (var thing in suppressThings) { ApplySuppression(thing as Pawn); } } Destroy(); }
// Token: 0x0600651E RID: 25886 RVA: 0x001B8BC0 File Offset: 0x001B6FC0 public static bool TryCastExtraShot(ref Verb_Shoot __instance, LocalTargetInfo currentTarget, bool canHitNonTargetPawnsNow) { if (currentTarget.HasThing && currentTarget.Thing.Map != __instance.caster.Map) { return(false); } ThingDef projectile = __instance.Projectile; if (projectile == null) { return(false); } ShootLine shootLine; bool flag = __instance.TryFindShootLineFromTo(__instance.caster.Position, currentTarget, out shootLine); if (__instance.verbProps.stopBurstWithoutLos && !flag) { return(false); } if (__instance.EquipmentSource != null) { CompChangeableProjectile comp = __instance.EquipmentSource.GetComp <CompChangeableProjectile>(); if (comp != null) { comp.Notify_ProjectileLaunched(); } } Thing launcher = __instance.caster; Thing equipment = __instance.EquipmentSource; CompMannable compMannable = __instance.caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = __instance.caster; } Vector3 drawPos = __instance.caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, __instance.caster.Map, WipeMode.Vanish); if (__instance.verbProps.ForcedMissRadius > 0.5f) { float num = VerbUtility.CalculateAdjustedForcedMiss(__instance.verbProps.ForcedMissRadius, currentTarget.Cell - __instance.caster.Position); if (num > 0.5f) { int max = GenRadial.NumCellsInRadius(num); Rand.PushState(); int num2 = Rand.Range(0, max); Rand.PopState(); if (num2 > 0) { IntVec3 c = currentTarget.Cell + GenRadial.RadialPattern[num2]; ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; Rand.PushState(); if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.All; } Rand.PopState(); if (!canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, drawPos, c, currentTarget, projectileHitFlags, false, equipment, null); return(true); } } } ShotReport shotReport = ShotReport.HitReportFor(__instance.caster, __instance, currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = (randomCoverToMissInto == null) ? null : randomCoverToMissInto.def; Rand.PushState(); bool chance = Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture); Rand.PopState(); if (!chance) { shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; Rand.PushState(); if (Rand.Chance(0.5f) && canHitNonTargetPawnsNow) { projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; } Rand.PopState(); projectile2.Launch(launcher, drawPos, shootLine.Dest, currentTarget, projectileHitFlags2, false, equipment, targetCoverDef); return(true); } Rand.PushState(); chance = Rand.Chance(shotReport.PassCoverChance); Rand.PopState(); if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && !chance) { ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, drawPos, randomCoverToMissInto, currentTarget, projectileHitFlags3, false, 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; } if (currentTarget.Thing != null) { projectile2.Launch(launcher, drawPos, currentTarget, currentTarget, projectileHitFlags4, false, equipment, targetCoverDef); } else { projectile2.Launch(launcher, drawPos, shootLine.Dest, currentTarget, projectileHitFlags4, false, equipment, targetCoverDef); } return(true); }
// Token: 0x06003684 RID: 13956 RVA: 0x001A082C File Offset: 0x0019EC2C public static bool TryFindDropSpotNear(IntVec3 center, Map map, out IntVec3 result, bool allowFogged, bool canRoofPunch) { if (DebugViewSettings.drawDestSearch) { map.debugDrawer.FlashCell(center, 1f, "center", 50); } Predicate <IntVec3> validator = (IntVec3 c) => DropThoughRoofCellFinder.IsGoodDropSpot(c, map, allowFogged, canRoofPunch) && map.reachability.CanReach(center, c, PathEndMode.OnCell, TraverseMode.NoPassClosedDoors, Danger.Deadly) && GenRadial.RadialCellsAround(c, 1, true).Any(x => x.Roofed(map)); int num = 5; while (!CellFinder.TryFindRandomCellNear(center, map, num, validator, out result, -1)) { num += 3; if (num > 16) { result = center; return(false); } } return(true); }
public void FireTurretCannon(CannonHandler cannon, ref SPTuple2 <int, int> data) { if (cannon is null) { return; } TryFindShootLineFromTo(cannon.TurretLocation.ToIntVec3(), cannon.cannonTarget, out ShootLine shootLine); IntVec3 c = cannon.cannonTarget.Cell + GenRadial.RadialPattern[Rand.Range(0, GenRadial.NumCellsInRadius(cannon.cannonDef.spreadRadius * (Range / cannon.cannonDef.maxRange)))]; if (data.Second >= cannon.cannonDef.projectileShifting.Count) { data.Second = 0; } float horizontalOffset = cannon.cannonDef.projectileShifting.AnyNullified() ? cannon.cannonDef.projectileShifting[data.Second] : 0; Vector3 launchCell = cannon.TurretLocation + new Vector3(horizontalOffset, 1f, cannon.cannonDef.projectileOffset).RotatedBy(cannon.TurretRotation); ThingDef projectile; if (!cannon.cannonDef.ammoAllowed.NullOrEmpty()) { projectile = cannon.loadedAmmo?.projectileWhenLoaded; } else { projectile = cannon.cannonDef.projectile; } try { Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, Pawn.Position, Pawn.Map, WipeMode.Vanish); if (!cannon.cannonDef.ammoAllowed.NullOrEmpty()) { cannon.ConsumeShellChambered(); } if (cannon.cannonDef.cannonSound is null) { SoundDefOf_Ships.Explosion_PirateCannon.PlayOneShot(new TargetInfo(Pawn.Position, Pawn.Map, false)); } else { cannon.cannonDef.cannonSound.PlayOneShot(new TargetInfo(Pawn.Position, Pawn.Map, false)); } if (cannon.cannonDef.moteFlash != null) { MoteMaker.MakeStaticMote(launchCell, Pawn.Map, cannon.cannonDef.moteFlash, 2); } if (cannon.cannonDef.moteCannon != null) { MoteThrown mote = (MoteThrown)ThingMaker.MakeThing(cannon.cannonDef.moteCannon, null); mote.exactPosition = launchCell; mote.Scale = 1f; mote.rotationRate = 15f; mote.SetVelocity(cannon.TurretRotation, cannon.cannonDef.moteSpeedThrown); HelperMethods.ThrowMoteEnhanced(launchCell, Pawn.Map, mote); } projectile2.Launch(Pawn, launchCell, c, cannon.cannonTarget, cannon.cannonDef.hitFlags, parent); if (cannon.cannonDef.graphicData.graphicClass == typeof(Graphic_Animate)) { cannon.StartAnimation(2, 1, AnimationWrapperType.Reset); } } catch (Exception ex) { Log.Error($"Exception when firing Cannon: {cannon.cannonDef.LabelCap} on Pawn: {Pawn.LabelCap}. Exception: {ex.Message}"); } }
protected override void Impact(Thing hitThing) { base.Impact(hitThing); ThingDef def = this.def; if (!this.initialized) { this.pawn = this.launcher as Pawn; this.map = this.pawn.Map; CompAbilityUserMagic comp = pawn.GetComp <CompAbilityUserMagic>(); MagicPowerSkill pwr = pawn.GetComp <CompAbilityUserMagic>().MagicData.MagicPowerSkill_Scorn.FirstOrDefault((MagicPowerSkill x) => x.label == "TM_Scorn_pwr"); MagicPowerSkill ver = pawn.GetComp <CompAbilityUserMagic>().MagicData.MagicPowerSkill_Scorn.FirstOrDefault((MagicPowerSkill x) => x.label == "TM_Scorn_ver"); ModOptions.SettingsRef settingsRef = new ModOptions.SettingsRef(); pwrVal = pwr.level; verVal = ver.level; this.arcaneDmg = comp.arcaneDmg; if (settingsRef.AIHardMode && !pawn.IsColonist) { pwrVal = 1; verVal = 1; } this.radius = this.def.projectile.explosionRadius + verVal; //this.duration = Mathf.RoundToInt(this.radius * this.strikeDelay); this.initialized = true; } if (!launchedFlag) { ModOptions.Constants.SetPawnInFlight(true); if (ModCheck.Validate.GiddyUp.Core_IsInitialized()) { ModCheck.GiddyUp.ForceDismount(pawn); } skyfaller = SkyfallerMaker.SpawnSkyfaller(ThingDef.Named("TM_ScornLeaving"), pawn.Position, this.map); if (base.Position.x < pawn.Position.x) { this.angle = Rand.Range(20, 40); } else { this.angle = Rand.Range(-40, -20); } skyfaller.angle = this.angle; launchedFlag = true; pawn.DeSpawn(); } if (skyfaller.DestroyedOrNull() && !pivotFlag) { safePos = base.Position; if (safePos.x > this.map.Size.x - 5) { safePos.x = this.map.Size.x - 5; } else if (safePos.x < 5) { safePos.x = 5; } if (safePos.z > this.map.Size.z - 5) { safePos.z = this.map.Size.z - 5; } else if (safePos.z < 5) { safePos.z = 5; } skyfaller2 = SkyfallerMaker.SpawnSkyfaller(ThingDef.Named("TM_ScornIncoming"), safePos, this.map); skyfaller2.angle = this.angle; pivotFlag = true; } if (skyfaller2.DestroyedOrNull() && pivotFlag && launchedFlag && !landedFlag) { landedFlag = true; GenSpawn.Spawn(pawn, safePos, this.map); if (pawn.drafter != null) { pawn.drafter.Drafted = true; } ModOptions.Constants.SetPawnInFlight(false); if (verVal == 0) { HealthUtility.AdjustSeverity(pawn, TorannMagicDefOf.TM_DemonScornHD, 60f + (pwrVal * 15)); } else if (verVal == 1) { HealthUtility.AdjustSeverity(pawn, TorannMagicDefOf.TM_DemonScornHD_I, 60f + (pwrVal * 15)); } else if (verVal == 2) { HealthUtility.AdjustSeverity(pawn, TorannMagicDefOf.TM_DemonScornHD_II, 60f + (pwrVal * 15)); } else { HealthUtility.AdjustSeverity(pawn, TorannMagicDefOf.TM_DemonScornHD_III, 60f + (pwrVal * 15)); } } if (landedFlag) { if (Find.TickManager.TicksGame % strikeDelay == 0) { if (safePos.DistanceToEdge(this.map) > strikeNum) { List <IntVec3> targets; if (strikeNum == 1) { targets = GenRadial.RadialCellsAround(safePos, this.strikeNum, false).ToList(); } else { IEnumerable <IntVec3> oldTargets = GenRadial.RadialCellsAround(base.Position, this.strikeNum - 1, false); targets = GenRadial.RadialCellsAround(safePos, this.strikeNum, false).Except(oldTargets).ToList(); } for (int j = 0; j < targets.Count(); j++) { IntVec3 curCell = targets[j]; if (this.map != null && curCell.IsValid && curCell.InBounds(this.map)) { GenExplosion.DoExplosion(curCell, this.Map, .4f, TMDamageDefOf.DamageDefOf.TM_Shadow, this.pawn, (int)((this.def.projectile.GetDamageAmount(1, null) * (1 + .15 * pwrVal)) * this.arcaneDmg * Rand.Range(.75f, 1.25f)), 0, TorannMagicDefOf.TM_SoftExplosion, def, null, null, null, 0f, 1, false, null, 0f, 1, 0f, false); } } this.strikeNum++; } else { strikeNum = (int)this.radius + 1; } } } if (this.strikeNum > this.radius) { this.age = this.duration; this.Destroy(DestroyMode.Vanish); } }
public void FireCannonBroadside(CannonHandler cannon, int i) { if (cannon is null) { return; } float initialOffset; float offset; bool mirrored = false; if (this.Pawn.Rotation == Rot4.South || Pawn.Rotation == Rot4.West) { mirrored = true; } if (cannon.cannonDef.splitCannonGroups) { int group = cannon.CannonGroup(i); float groupOffset = cannon.cannonDef.centerPoints[group]; initialOffset = ((cannon.cannonDef.spacing * (cannon.cannonDef.cannonsPerPoint[group] - 1)) / 2f) + groupOffset; // s(n-1) / 2 offset = (cannon.cannonDef.spacing * i - initialOffset) * (mirrored ? -1 : 1); //s*i - x } else { initialOffset = ((cannon.cannonDef.spacing * (cannon.cannonDef.numberCannons - 1)) / 2f) + cannon.cannonDef.offset; // s(n-1) / 2 offset = (cannon.cannonDef.spacing * i - initialOffset) * (mirrored ? -1 : 1); //s*i - x } float projectileOffset = (this.Pawn.def.size.x / 2f) + cannon.cannonDef.projectileOffset; // (s/2) SPTuple2 <float, float> angleOffset = AngleRotationProjectileOffset(offset, projectileOffset); ThingDef projectile = cannon.cannonDef.projectile; IntVec3 targetCell = IntVec3.Invalid; Vector3 launchCell = this.Pawn.DrawPos; switch (cannon.cannonDef.weaponLocation) { case WeaponLocation.Port: if (this.CompVehicle.Angle == 0) { if (this.Pawn.Rotation == Rot4.North) { launchCell.x -= projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)this.Range; } else if (this.Pawn.Rotation == Rot4.East) { launchCell.x += offset; launchCell.z += projectileOffset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.South) { launchCell.x += projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.West) { launchCell.x += offset; launchCell.z -= projectileOffset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z -= (int)this.Range; } } else { if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == -45) { launchCell.x += angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == 45) { launchCell.x += angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == -45) { launchCell.x -= angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == 45) { launchCell.x -= angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } } break; case WeaponLocation.Starboard: if (this.CompVehicle.Angle == 0) { if (this.Pawn.Rotation == Rot4.North) { launchCell.x += projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.East) { launchCell.z -= projectileOffset; launchCell.x += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z -= (int)this.Range; } else if (this.Pawn.Rotation == Rot4.South) { launchCell.x -= projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)this.Range; } else if (this.Pawn.Rotation == Rot4.West) { launchCell.z += projectileOffset; launchCell.x += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z += (int)this.Range; } } else { if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == -45) { launchCell.x += angleOffset.Second; launchCell.z += angleOffset.First; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == 45) { launchCell.x -= angleOffset.Second; launchCell.z -= angleOffset.First; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == -45) { launchCell.x += angleOffset.Second; launchCell.z -= angleOffset.First; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == 45) { launchCell.x -= angleOffset.Second; launchCell.z += angleOffset.First; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } } break; case WeaponLocation.Bow: if (this.CompVehicle.Angle == 0) { if (this.Pawn.Rotation == Rot4.North) { launchCell.x -= projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)this.Range; } else if (this.Pawn.Rotation == Rot4.East) { launchCell.x += offset; launchCell.z += projectileOffset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.South) { launchCell.x += projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.West) { launchCell.x += offset; launchCell.z -= projectileOffset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z -= (int)this.Range; } } else { if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == -45) { launchCell.x += angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == 45) { launchCell.x += angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == -45) { launchCell.x -= angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == 45) { launchCell.x -= angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } } break; case WeaponLocation.Stern: if (this.CompVehicle.Angle == 0) { if (this.Pawn.Rotation == Rot4.North) { launchCell.x -= projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)this.Range; } else if (this.Pawn.Rotation == Rot4.East) { launchCell.x += offset; launchCell.z += projectileOffset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.South) { launchCell.x += projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.West) { launchCell.x += offset; launchCell.z -= projectileOffset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z -= (int)this.Range; } } else { if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == -45) { launchCell.x += angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == 45) { launchCell.x += angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == -45) { launchCell.x -= angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == 45) { launchCell.x -= angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } } break; } LocalTargetInfo target = new LocalTargetInfo(targetCell); ShootLine shootLine; bool flag = TryFindShootLineFromTo(this.Pawn.Position, target, out shootLine); //FIX FOR MULTIPLAYER IntVec3 c = target.Cell + GenRadial.RadialPattern[Rand.Range(0, GenRadial.NumCellsInRadius(cannon.cannonDef.spreadRadius * (this.Range / cannon.cannonDef.maxRange)))]; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, this.Pawn.Position, this.Pawn.Map, WipeMode.Vanish); if (cannon.cannonDef.cannonSound is null) { SoundDefOf_Ships.Explosion_PirateCannon.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map, false)); } else { cannon.cannonDef.cannonSound.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map, false)); } if (cannon.cannonDef.moteCannon != null) { MoteMaker.MakeStaticMote(launchCell, this.Pawn.Map, cannon.cannonDef.moteCannon, 1f); } projectile2.Launch(this.Pawn, launchCell, c, target, cannon.cannonDef.hitFlags); }
protected new void Impact(Thing hitThing) { bool flag = hitThing == null; if (flag) { Pawn pawn; bool flag2 = (pawn = (base.Position.GetThingList(base.Map).FirstOrDefault((Thing x) => x == this.assignedTarget) as Pawn)) != null; if (flag2) { hitThing = pawn; } } if (hitThing != null) { damageEntities(hitThing, Mathf.RoundToInt(Rand.Range(this.def.projectile.GetDamageAmount(1, null) * .75f, this.def.projectile.GetDamageAmount(1, null) * 1.25f) * this.arcaneDmg)); } TM_MoteMaker.ThrowShadowCleaveMote(this.ExactPosition, this.Map, 2f + (.4f * pwrVal), .05f, .1f, .3f, 0, (5f + pwrVal), this.directionAngle); TorannMagicDefOf.TM_SoftExplosion.PlayOneShot(new TargetInfo(this.ExactPosition.ToIntVec3(), this.pawn.Map, false)); int num = GenRadial.NumCellsInRadius(1 + (.4f * pwrVal)); Vector3 cleaveVector; IntVec3 intVec; for (int i = 0; i < num; i++) { cleaveVector = this.ExactPosition + (Quaternion.AngleAxis(-45, Vector3.up) * ((1.5f + (.5f * pwrVal)) * this.direction)); intVec = cleaveVector.ToIntVec3() + GenRadial.RadialPattern[i]; //GenExplosion.DoExplosion(intVec, base.Map, .4f, TMDamageDefOf.DamageDefOf.TM_Shadow, this.launcher as Pawn, Mathf.RoundToInt((Rand.Range(.6f * this.def.projectile.GetDamageAmount(1,null), 1.1f * this.def.projectile.GetDamageAmount(1,null)) + (5f * pwrVal)) * this.arcaneDmg), this.def.projectile.soundExplode, def, null, null, 0f, 1, false, null, 0f, 0, 0.0f, true); if (intVec.IsValid && intVec.InBounds(this.Map)) { List <Thing> hitList = new List <Thing>(); hitList = intVec.GetThingList(base.Map); for (int j = 0; j < hitList.Count; j++) { if (hitList[j] is Pawn && hitList[j] != this.pawn) { damageEntities(hitList[j], Mathf.RoundToInt((Rand.Range(this.def.projectile.GetDamageAmount(1, null) * .6f, this.def.projectile.GetDamageAmount(1, null) * .8f) * (float)(1f + .1 * pwrVal) * this.arcaneDmg))); } } } cleaveVector = this.ExactPosition + (Quaternion.AngleAxis(45, Vector3.up) * ((1.5f + (.5f * pwrVal)) * this.direction)); intVec = cleaveVector.ToIntVec3() + GenRadial.RadialPattern[i]; //GenExplosion.DoExplosion(intVec, base.Map, .4f, TMDamageDefOf.DamageDefOf.TM_Shadow, this.launcher as Pawn, Mathf.RoundToInt((Rand.Range(.6f * this.def.projectile.GetDamageAmount(1,null), 1.1f * this.def.projectile.GetDamageAmount(1,null)) + (5f * pwrVal)) * this.arcaneDmg), this.def.projectile.soundExplode, def, null, null, 0f, 1, false, null, 0f, 0, 0.0f, true); if (intVec.IsValid && intVec.InBounds(this.Map)) { List <Thing> hitList = new List <Thing>(); hitList = intVec.GetThingList(base.Map); for (int j = 0; j < hitList.Count; j++) { if (hitList[j] is Pawn && hitList[j] != this.pawn) { damageEntities(hitList[j], Mathf.RoundToInt((Rand.Range(this.def.projectile.GetDamageAmount(1, null) * .5f, this.def.projectile.GetDamageAmount(1, null) * .7f) * (float)(1f + .1 * pwrVal) * this.arcaneDmg))); } } } cleaveVector = this.ExactPosition + ((2 + (.3f * (float)pwrVal)) * this.direction); intVec = cleaveVector.ToIntVec3() + GenRadial.RadialPattern[i]; //GenExplosion.DoExplosion(intVec, base.Map, .4f, TMDamageDefOf.DamageDefOf.TM_Shadow, this.launcher as Pawn, Mathf.RoundToInt((Rand.Range(.6f*this.def.projectile.GetDamageAmount(1,null), 1.1f*this.def.projectile.GetDamageAmount(1,null)) + (5f * pwrVal)) * this.arcaneDmg), this.def.projectile.soundExplode, def, null, null, 0f, 1, false, null, 0f, 0, 0.0f, true); if (intVec.IsValid && intVec.InBounds(this.Map)) { List <Thing> hitList = new List <Thing>(); hitList = intVec.GetThingList(base.Map); for (int j = 0; j < hitList.Count; j++) { if (hitList[j] is Pawn && hitList[j] != this.pawn) { damageEntities(hitList[j], Mathf.RoundToInt((Rand.Range(this.def.projectile.GetDamageAmount(1, null) * .5f, this.def.projectile.GetDamageAmount(1, null) * .7f) * (float)(1f + .1 * pwrVal) * this.arcaneDmg))); } } } } this.Destroy(DestroyMode.Vanish); //GenExplosion.DoExplosion(base.Position, base.Map, this.radius, TMDamageDefOf.DamageDefOf.TM_DeathBolt, this.launcher as Pawn, Mathf.RoundToInt((Rand.Range(.6f*this.def.projectile.GetDamageAmount(1,null), 1.1f*this.def.projectile.GetDamageAmount(1,null)) + (5f * pwrVal)) * this.arcaneDmg), this.def.projectile.soundExplode, def, null, null, 0f, 1, false, null, 0f, 0, 0.0f, true); }
public Thing BestFoodSourceOnMap(Pawn getter, Pawn eater, bool desperate, out ThingDef foodDef, FoodPreferability maxPref = FoodPreferability.MealLavish, bool allowPlant = true, bool allowDrug = true, bool allowCorpse = true, bool allowDispenserFull = true, bool allowDispenserEmpty = true, bool allowForbidden = false, bool allowSociallyImproper = false, bool allowHarvest = false, bool forceScanWholeMap = false, bool ignoreReservations = false, bool calculateWantedStackCount = false, FoodPreferability minPrefOverride = FoodPreferability.Undefined, float?minNutrition = null) { foodDef = null; FoodPreferability minPref; if (minPrefOverride == FoodPreferability.Undefined) { if (eater.NonHumanlikeOrWildMan()) { minPref = FoodPreferability.NeverForNutrition; } else if (desperate) { minPref = FoodPreferability.DesperateOnly; } else { minPref = (((int)eater.needs.food.CurCategory >= 2) ? FoodPreferability.RawBad : FoodPreferability.MealAwful); } } else { minPref = minPrefOverride; } Predicate <Thing> foodValidator = delegate(Thing t) { Building_NutrientPasteDispenser building_NutrientPasteDispenser = t as Building_NutrientPasteDispenser; if (building_NutrientPasteDispenser != null) { if (!allowDispenserFull || (int)ThingDefOf.MealNutrientPaste.ingestible.preferability < (int)minPref || (int)ThingDefOf.MealNutrientPaste.ingestible.preferability > (int)maxPref || !eater.WillEat(ThingDefOf.MealNutrientPaste, getter) || (t.Faction != getter.Faction && t.Faction != getter.HostFaction) || (!allowForbidden && t.IsForbidden(getter)) || !building_NutrientPasteDispenser.powerComp.PowerOn || (!allowDispenserEmpty && !building_NutrientPasteDispenser.HasEnoughFeedstockInHoppers()) || !t.InteractionCell.Standable(t.Map) || !IsFoodSourceOnMapSociallyProper(t, getter, eater, allowSociallyImproper) || !getter.Map.reachability.CanReachNonLocal(getter.Position, new TargetInfo(t.InteractionCell, t.Map), PathEndMode.OnCell, TraverseParms.For(getter, Danger.Some))) { return(false); } } else { int stackCount = 1; float statValue = t.GetStatValue(StatDefOf.Nutrition); if (minNutrition.HasValue) { stackCount = FoodUtility.StackCountForNutrition(minNutrition.Value, statValue); } else if (calculateWantedStackCount) { stackCount = FoodUtility.WillIngestStackCountOf(eater, t.def, statValue); } if ((int)t.def.ingestible.preferability < (int)minPref || (int)t.def.ingestible.preferability > (int)maxPref || !eater.WillEat(t, getter) || !t.def.IsNutritionGivingIngestible || !t.IngestibleNow || (!allowCorpse && t is Corpse) || (!allowDrug && t.def.IsDrug) || (!allowForbidden && t.IsForbidden(getter)) || (!desperate && t.IsNotFresh()) || t.IsDessicated() || !IsFoodSourceOnMapSociallyProper(t, getter, eater, allowSociallyImproper) || (!getter.AnimalAwareOf(t) && !forceScanWholeMap) || (!ignoreReservations && !getter.CanReserve(t, 10, stackCount))) { return(false); } } return(true); }; ThingRequest thingRequest = ((eater.RaceProps.foodType & (FoodTypeFlags.Plant | FoodTypeFlags.Tree)) == 0 || !allowPlant) ? ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree) : ThingRequest.ForGroup(ThingRequestGroup.FoodSource); Thing bestThing; if (getter.RaceProps.Humanlike) { bestThing = SpawnedFoodSearchInnerScan(eater, getter.Position, getter.Map.listerThings.ThingsMatching(thingRequest), PathEndMode.ClosestTouch, TraverseParms.For(getter), 9999f, foodValidator); if (allowHarvest) { Thing thing = GenClosest.ClosestThingReachable(searchRegionsMax : (!forceScanWholeMap || bestThing != null) ? 30 : (-1), root : getter.Position, map : getter.Map, thingReq : ThingRequest.ForGroup(ThingRequestGroup.HarvestablePlant), peMode : PathEndMode.Touch, traverseParams : TraverseParms.For(getter), maxDistance : 9999f, validator : delegate(Thing x) { Plant plant = (Plant)x; if (!plant.HarvestableNow) { return(false); } ThingDef harvestedThingDef = plant.def.plant.harvestedThingDef; if (!harvestedThingDef.IsNutritionGivingIngestible) { return(false); } if (!eater.WillEat(harvestedThingDef, getter)) { return(false); } if (!getter.CanReserve(plant)) { return(false); } if (!allowForbidden && plant.IsForbidden(getter)) { return(false); } return((bestThing == null || (int)FoodUtility.GetFinalIngestibleDef(bestThing).ingestible.preferability < (int)harvestedThingDef.ingestible.preferability) ? true : false); }); if (thing != null) { bestThing = thing; foodDef = FoodUtility.GetFinalIngestibleDef(thing, harvest: true); } } if (foodDef == null && bestThing != null) { foodDef = FoodUtility.GetFinalIngestibleDef(bestThing); } } else { int maxRegionsToScan = GetMaxRegionsToScan(getter, forceScanWholeMap); filtered.Clear(); foreach (Thing item in GenRadial.RadialDistinctThingsAround(getter.Position, getter.Map, 2f, useCenter: true)) { Pawn pawn = item as Pawn; if (pawn != null && pawn != getter && pawn.RaceProps.Animal && pawn.CurJob != null && pawn.CurJob.def == JobDefOf.Ingest && pawn.CurJob.GetTarget(TargetIndex.A).HasThing) { filtered.Add(pawn.CurJob.GetTarget(TargetIndex.A).Thing); } } bool ignoreEntirelyForbiddenRegions = !allowForbidden && ForbidUtility.CaresAboutForbidden(getter, cellTarget: true) && getter.playerSettings != null && getter.playerSettings.EffectiveAreaRestrictionInPawnCurrentMap != null; Predicate <Thing> validator = delegate(Thing t) { if (!foodValidator(t)) { return(false); } if (filtered.Contains(t)) { return(false); } if (!(t is Building_NutrientPasteDispenser) && (int)t.def.ingestible.preferability <= 2) { return(false); } return((!t.IsNotFresh()) ? true : false); }; bestThing = GenClosest.ClosestThingReachable(getter.Position, getter.Map, thingRequest, PathEndMode.ClosestTouch, TraverseParms.For(getter), 9999f, validator, null, 0, maxRegionsToScan, forceAllowGlobalSearch: false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions); filtered.Clear(); if (bestThing == null) { desperate = true; bestThing = GenClosest.ClosestThingReachable(getter.Position, getter.Map, thingRequest, PathEndMode.ClosestTouch, TraverseParms.For(getter), 9999f, foodValidator, null, 0, maxRegionsToScan, forceAllowGlobalSearch: false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions); } if (bestThing != null) { foodDef = FoodUtility.GetFinalIngestibleDef(bestThing); } } return(bestThing); }
protected override void Impact(Thing hitThing) { Map map = base.Map; base.Impact(hitThing); ThingDef def = this.def; int raisedPawns = 0; Pawn pawn = this.launcher as Pawn; Pawn victim = hitThing as Pawn; CompAbilityUserMagic comp = pawn.GetComp <CompAbilityUserMagic>(); pwr = pawn.GetComp <CompAbilityUserMagic>().MagicData.MagicPowerSkill_RaiseUndead.FirstOrDefault((MagicPowerSkill x) => x.label == "TM_RaiseUndead_pwr"); ver = pawn.GetComp <CompAbilityUserMagic>().MagicData.MagicPowerSkill_RaiseUndead.FirstOrDefault((MagicPowerSkill x) => x.label == "TM_RaiseUndead_ver"); Thing corpseThing = null; IntVec3 curCell; IEnumerable <IntVec3> targets = GenRadial.RadialCellsAround(base.Position, this.def.projectile.explosionRadius, true); for (int i = 0; i < targets.Count(); i++) { curCell = targets.ToArray <IntVec3>()[i]; TM_MoteMaker.ThrowPoisonMote(curCell.ToVector3Shifted(), map, .3f); if (curCell.InBounds(map)) { Corpse corpse = null; List <Thing> thingList; thingList = curCell.GetThingList(map); int z = 0; while (z < thingList.Count) { corpseThing = thingList[z]; if (corpseThing != null) { bool validator = corpseThing is Corpse; if (validator) { corpse = corpseThing as Corpse; Pawn undeadPawn = corpse.InnerPawn; CompRottable compRottable = corpse.GetComp <CompRottable>(); float rotStage = 0; if (compRottable != null && compRottable.Stage == RotStage.Dessicated) { rotStage = 1f; } if (compRottable != null) { rotStage += compRottable.RotProgressPct; } bool flag_SL = false; if (undeadPawn.def.defName == "SL_Runner" || undeadPawn.def.defName == "SL_Peon" || undeadPawn.def.defName == "SL_Archer" || undeadPawn.def.defName == "SL_Hero") { PawnGenerationRequest pgr = new PawnGenerationRequest(PawnKindDef.Named("Tribesperson"), pawn.Faction, PawnGenerationContext.NonPlayer, -1, true, false, false, false, false, true, 0, false, false, false, false, false, false, false, null, null, null, null, null, null, null, "Undead"); Pawn newUndeadPawn = PawnGenerator.GeneratePawn(pgr); GenSpawn.Spawn(newUndeadPawn, corpse.Position, corpse.Map, WipeMode.Vanish); corpse.Strip(); corpse.Destroy(DestroyMode.Vanish); rotStage = 1f; flag_SL = true; undeadPawn = newUndeadPawn; } if (!undeadPawn.def.defName.Contains("ROM_") && undeadPawn.RaceProps.IsFlesh && (undeadPawn.Dead || flag_SL) && undeadPawn.def.thingClass.FullName != "TorannMagic.TMPawnSummoned") { bool wasVampire = false; IEnumerable <ThingDef> enumerable = from hd in DefDatabase <HediffDef> .AllDefs where (def.defName == "ROM_Vampirism") select def; if (enumerable.Count() > 0) { bool hasVampHediff = undeadPawn.health.hediffSet.HasHediff(HediffDef.Named("ROM_Vampirism")) || undeadPawn.health.hediffSet.HasHediff(HediffDef.Named("ROM_GhoulHediff")); if (hasVampHediff) { wasVampire = true; } } if (!wasVampire) { undeadPawn.SetFaction(pawn.Faction); if (undeadPawn.Dead) { ResurrectionUtility.Resurrect(undeadPawn); } raisedPawns++; if (!undeadPawn.kindDef.RaceProps.Animal && undeadPawn.kindDef.RaceProps.Humanlike) { CompAbilityUserMagic compMagic = undeadPawn.GetComp <CompAbilityUserMagic>(); if (TM_Calc.IsMagicUser(undeadPawn)) //(compMagic.IsMagicUser && !undeadPawn.story.traits.HasTrait(TorannMagicDefOf.Faceless)) || { compMagic.Initialize(); compMagic.RemovePowers(); } CompAbilityUserMight compMight = undeadPawn.GetComp <CompAbilityUserMight>(); if (TM_Calc.IsMightUser(undeadPawn)) //compMight.IsMightUser || { compMight.Initialize(); compMight.RemovePowers(); } HealthUtility.AdjustSeverity(undeadPawn, TorannMagicDefOf.TM_UndeadHD, -4f); HealthUtility.AdjustSeverity(undeadPawn, TorannMagicDefOf.TM_UndeadHD, .5f + ver.level); HealthUtility.AdjustSeverity(undeadPawn, HediffDef.Named("TM_UndeadStageHD"), -2f); HealthUtility.AdjustSeverity(undeadPawn, HediffDef.Named("TM_UndeadStageHD"), rotStage); RedoSkills(undeadPawn); RemoveTraits(undeadPawn, undeadPawn.story.traits.allTraits); undeadPawn.story.traits.GainTrait(new Trait(TraitDef.Named("Undead"), 0, false)); undeadPawn.story.traits.GainTrait(new Trait(TraitDef.Named("Psychopath"), 0, false)); undeadPawn.needs.AddOrRemoveNeedsAsAppropriate(); RemoveClassHediff(undeadPawn); //Color undeadColor = new Color(.2f, .4f, 0); //undeadPawn.story.hairColor = undeadColor; //CompAbilityUserMagic undeadComp = undeadPawn.GetComp<CompAbilityUserMagic>(); //if (undeadComp.IsMagicUser) //{ // undeadComp.ClearPowers(); //} List <SkillRecord> skills = undeadPawn.skills.skills; for (int j = 0; j < skills.Count; j++) { skills[j].passion = Passion.None; } undeadPawn.playerSettings.hostilityResponse = HostilityResponseMode.Attack; undeadPawn.playerSettings.medCare = MedicalCareCategory.NoMeds; for (int h = 0; h < 24; h++) { undeadPawn.timetable.SetAssignment(h, TimeAssignmentDefOf.Work); } } } else { Messages.Message("Vampiric powers have prevented undead reanimation of " + undeadPawn.LabelShort, MessageTypeDefOf.RejectInput); } if (undeadPawn.kindDef.RaceProps.Animal) { HealthUtility.AdjustSeverity(undeadPawn, TorannMagicDefOf.TM_UndeadAnimalHD, -4f); HealthUtility.AdjustSeverity(undeadPawn, TorannMagicDefOf.TM_UndeadAnimalHD, .5f + ver.level); HealthUtility.AdjustSeverity(undeadPawn, HediffDef.Named("TM_UndeadStageHD"), -2f); HealthUtility.AdjustSeverity(undeadPawn, HediffDef.Named("TM_UndeadStageHD"), rotStage); if (undeadPawn.training.CanAssignToTrain(TrainableDefOf.Tameness).Accepted) { while (!undeadPawn.training.HasLearned(TrainableDefOf.Tameness)) { undeadPawn.training.Train(TrainableDefOf.Tameness, pawn); } } if (undeadPawn.training.CanAssignToTrain(TrainableDefOf.Obedience).Accepted) { while (!undeadPawn.training.HasLearned(TrainableDefOf.Obedience)) { undeadPawn.training.Train(TrainableDefOf.Obedience, pawn); } } if (undeadPawn.training.CanAssignToTrain(TrainableDefOf.Release).Accepted) { while (!undeadPawn.training.HasLearned(TrainableDefOf.Release)) { undeadPawn.training.Train(TrainableDefOf.Release, pawn); } } if (undeadPawn.training.CanAssignToTrain(TorannMagicDefOf.Haul).Accepted) { while (!undeadPawn.training.HasLearned(TorannMagicDefOf.Haul)) { undeadPawn.training.Train(TorannMagicDefOf.Haul, pawn); } } if (undeadPawn.training.CanAssignToTrain(TorannMagicDefOf.Rescue).Accepted) { while (!undeadPawn.training.HasLearned(TorannMagicDefOf.Rescue)) { undeadPawn.training.Train(TorannMagicDefOf.Rescue, pawn); } } undeadPawn.playerSettings.medCare = MedicalCareCategory.NoMeds; undeadPawn.def.tradeability = Tradeability.None; } } } } z++; } } if (raisedPawns > pwr.level + 1) { i = targets.Count(); } } }
private void TryExpandSnow() { if (parent.Map.mapTemperature.OutdoorTemp > 10f) { snowRadius = 0f; return; } if (snowNoise == null) { snowNoise = new Perlin(0.054999999701976776, 2.0, 0.5, 5, Rand.Range(0, 651431), QualityMode.Medium); } if (snowRadius < 8f) { snowRadius += 1.3f; } else if (snowRadius < 17f) { snowRadius += 0.7f; } else if (snowRadius < 30f) { snowRadius += 0.4f; } else { snowRadius += 0.1f; } snowRadius = Mathf.Min(snowRadius, Props.maxRadius); CellRect occupiedRect = parent.OccupiedRect(); reachableCells.Clear(); parent.Map.floodFiller.FloodFill(parent.Position, delegate(IntVec3 x) { if ((float)x.DistanceToSquared(parent.Position) > snowRadius * snowRadius) { return(false); } return(occupiedRect.Contains(x) || !x.Filled(parent.Map)); }, delegate(IntVec3 x) { reachableCells.Add(x); }); int num = GenRadial.NumCellsInRadius(snowRadius); for (int i = 0; i < num; i++) { IntVec3 intVec = parent.Position + GenRadial.RadialPattern[i]; if (intVec.InBounds(parent.Map) && reachableCells.Contains(intVec)) { float value = snowNoise.GetValue(intVec); value += 1f; value *= 0.5f; if (value < 0.1f) { value = 0.1f; } if (!(parent.Map.snowGrid.GetDepth(intVec) > value)) { float lengthHorizontal = (intVec - parent.Position).LengthHorizontal; float num2 = 1f - lengthHorizontal / snowRadius; parent.Map.snowGrid.AddDepth(intVec, num2 * Props.addAmount * value); } } } }
public override void CompTick() { base.CompTick(); if (this.Pawn.Spawned) { if (Find.TickManager.TicksGame % 10 == 0) { if (this.Pawn.Downed && !this.Pawn.Dead) { Rand.PushState(); GenExplosion.DoExplosion(this.Pawn.Position, this.Pawn.Map, Rand.Range(this.explosionRadius * 0.5f, this.explosionRadius * 1.5f), DamageDefOf.Burn, this.Pawn, Rand.Range(6, 10), 0f, null, null, null, null, null, 0f, 1, false, null, 0f, 1, 0f, false); Rand.PopState(); this.Pawn.Kill(null, null); } } if (Find.TickManager.TicksGame % this.nextLeap == 0 && !this.Pawn.Downed && !this.Pawn.Dead && Find.TickManager.TicksGame - this.Pawn.mindState.lastAttackTargetTick > Props.combatCooldown) { LocalTargetInfo a = null; if (this.Pawn.CurJob != null && this.Pawn.CurJob.targetA != null) { a = this.Pawn.jobs.curJob.targetA.Thing; } if (a != null && a.Thing != null) { Thing thing = a.Thing; if (thing is Pawn && thing.Spawned) { float lengthHorizontal = (thing.Position - this.Pawn.Position).LengthHorizontal; if (lengthHorizontal <= this.Props.leapRangeMax && lengthHorizontal > this.Props.leapRangeMin) { Rand.PushState(); bool leap = Rand.Chance(this.Props.GetLeapChance); Rand.PopState(); if (leap) { if (this.CanHitTargetFrom(this.Pawn.Position, thing)) { this.LeapAttack(thing); } } else { if (this.Props.textMotes) { Rand.PushState(); if (!this.Props.moteStrings.NullOrEmpty()) { MoteMaker.ThrowText(this.Pawn.DrawPos, this.Pawn.Map, this.Props.moteStrings.RandomElement(), -1f); } else { if (Rand.Chance(0.5f)) { MoteMaker.ThrowText(this.Pawn.DrawPos, this.Pawn.Map, "grrr", -1f); } else { MoteMaker.ThrowText(this.Pawn.DrawPos, this.Pawn.Map, "hsss", -1f); } } Rand.PopState(); } } } else { if (this.Props.bouncingLeaper) { Faction faction = null; if (thing != null && thing.Faction != null) { faction = thing.Faction; } IEnumerable <IntVec3> enumerable = GenRadial.RadialCellsAround(this.Pawn.Position, this.Props.leapRangeMax, false); for (int i = 0; i < enumerable.Count <IntVec3>(); i++) { Pawn pawn = null; IntVec3 c = enumerable.ToArray <IntVec3>()[i]; if (c.InBounds(this.Pawn.Map) && c.IsValid) { pawn = c.GetFirstPawn(this.Pawn.Map); if (pawn != null && pawn != thing && !pawn.Downed && !pawn.Dead && pawn.RaceProps != null) { if (pawn.Faction != null && pawn.Faction == faction) { Rand.PushState(); if (Rand.Chance(1f - this.Props.leapChance)) { i = enumerable.Count <IntVec3>(); } else { pawn = null; } Rand.PopState(); } else { pawn = null; } } else { pawn = null; } } if (pawn != null) { if (this.CanHitTargetFrom(this.Pawn.Position, thing)) { if (!pawn.Downed && !pawn.Dead) { this.LeapAttack(pawn); } this.LeapAttack(pawn); break; } } enumerable.GetEnumerator().MoveNext(); } } } } } } } }
protected override void Impact(Thing hitThing) { Map map = base.Map; ThingDef def = this.def; if (!this.initialized) { caster = this.launcher as Pawn; CompAbilityUserMagic comp = caster.GetComp <CompAbilityUserMagic>(); verVal = TM_Calc.GetMagicSkillLevel(caster, comp.MagicData.MagicPowerSkill_Custom, "TM_Explosion", "_ver", true); pwrVal = TM_Calc.GetMagicSkillLevel(caster, comp.MagicData.MagicPowerSkill_Custom, "TM_Explosion", "_pwr", true); this.arcaneDmg = comp.arcaneDmg; this.CheckSpawnSustainer(); this.strikePos = base.Position; this.duration = 360 - (verVal * 3); this.damage = this.DamageAmount * this.arcaneDmg * (1f + (.02f * pwrVal)); this.radius = this.def.projectile.explosionRadius + (int)(verVal / 10); this.initialized = true; this.outerRing = TM_Calc.GetOuterRing(this.strikePos, radius - 1, radius); Color color = colorInt.ToColor; Projectile_Explosion.MatPropertyBlock.SetColor(ShaderPropertyIDs.Color, color); } if (this.sustainer != null) { this.sustainer.info.volumeFactor = (this.age) / (this.duration); this.sustainer.Maintain(); if (this.TicksLeft <= 0) { this.sustainer.End(); this.sustainer = null; } } //there are 6 + 3 phases to explosion (this is no simple matter) //phase 1 - warmup and power collection; depicted by wind drawing into a focal point //phase 2 - pause (for dramatic effect) //phase 3 - initial explosion, ie the "shockwave" //phase 4 - ripping winds (the debris launched by the explosion) //phase 5 - burning winds (heat and flame - scorched earth) //phase 6 - aftershock //training adds 3 phases //phase 3a - emp //phase 4a - secondary explosions //phase 5a - radiation //warmup 2 seconds if (this.age <= (int)(this.duration * .4f) && this.outerRing.Count > 0) { for (int i = 0; i < 3; i++) { Vector3 startPos = outerRing.RandomElement().ToVector3Shifted(); Vector3 direction = TM_Calc.GetVector(startPos, strikePos.ToVector3Shifted()); TM_MoteMaker.ThrowGenericMote(ThingDefOf.Mote_Smoke, startPos, this.Map, .8f, .3f, .05f, .6f, 0, 12f, (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 0); } } else if (this.age <= (int)(this.duration * .6f)) { //pause } else if (this.age > (int)(this.duration * .6f) && !phase3Flag) { if (!phase2Flag) { TargetInfo ti = new TargetInfo(this.strikePos, map, false); TM_MoteMaker.MakeOverlay(ti, TorannMagicDefOf.TM_Mote_PsycastAreaEffect, map, Vector3.zero, 2, 0f, .1f, .4f, 0, 15f); Effecter igniteED = TorannMagicDefOf.TM_ExplosionED.Spawn(); igniteED.Trigger(new TargetInfo(this.strikePos, map, false), new TargetInfo(this.strikePos, map, false)); igniteED.Cleanup(); SoundInfo info = SoundInfo.InMap(new TargetInfo(this.strikePos, map, false), MaintenanceType.None); info.pitchFactor = .75f; info.volumeFactor = 2.6f; TorannMagicDefOf.TM_FireWooshSD.PlayOneShot(info); this.phase2Flag = true; } this.expandingTick++; if (expandingTick <= this.radius) { IntVec3 centerCell = base.Position; if (this.expandingTick <= 1 || oldExplosionCells.Count() <= 0) { oldExplosionCells = GenRadial.RadialCellsAround(centerCell, expandingTick - 1, true); } else { oldExplosionCells = newExplosionCells; } newExplosionCells = GenRadial.RadialCellsAround(centerCell, expandingTick, true); IEnumerable <IntVec3> explosionCells = newExplosionCells.Except(oldExplosionCells); foreach (IntVec3 cell in explosionCells) { if (cell.InBounds(map)) { Vector3 heading = (cell - centerCell).ToVector3(); float distance = heading.magnitude; Vector3 direction = TM_Calc.GetVector(centerCell, cell); float angle = (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(); if (this.expandingTick >= 6 && this.expandingTick < 8) { TM_MoteMaker.ThrowGenericMote(TorannMagicDefOf.Mote_DirectionalDirt, cell.ToVector3Shifted(), map, .8f, .2f, .15f, .5f, 0, 7f, angle, angle); TM_MoteMaker.ThrowGenericMote(TorannMagicDefOf.Mote_ExpandingFlame, cell.ToVector3Shifted(), map, 1.1f, .3f, .02f, .25f, 0, 15f, angle, angle); } List <Thing> hitList = cell.GetThingList(map); Thing burnThing = null; for (int j = 0; j < hitList.Count; j++) { burnThing = hitList[j]; DamageInfo dinfo = new DamageInfo(DamageDefOf.Flame, Mathf.RoundToInt(Rand.Range(this.damage * .25f, this.damage * .35f)), 1, -1, this.launcher, null, null, DamageInfo.SourceCategory.ThingOrUnknown); burnThing.TakeDamage(dinfo); } } } } else { TargetInfo ti = new TargetInfo(this.strikePos, map, false); TM_MoteMaker.MakeOverlay(ti, TorannMagicDefOf.TM_Mote_PsycastAreaEffect, map, Vector3.zero, 4, 0f, .1f, .4f, .5f, 2f); this.expandingTick = 0; this.phase3Flag = true; } } else if (phase3Flag) { this.expandingTick++; if (expandingTick < 4) { float energy = 80000 * this.arcaneDmg; GenTemperature.PushHeat(this.strikePos, this.Map, energy); GenExplosion.DoExplosion(this.strikePos, this.Map, this.radius / (4 - this.expandingTick), DamageDefOf.Bomb, this.launcher, Mathf.RoundToInt(Rand.Range(this.damage * .7f, this.damage * .9f)), 1, DamageDefOf.Bomb.soundExplosion, null, null, null, null, 0, 0, false, null, 0, 0, .4f, true); } } this.Destroy(DestroyMode.Vanish); }
public void SpawnCycle() { float wealthMultiplier = .7f; float wealth = this.Map.PlayerWealthForStoryteller; if (wealth > 20000) { wealthMultiplier = .8f; } if (wealth > 50000) { wealthMultiplier = 1f; } if (wealth > 100000) { wealthMultiplier = 1.25f; } if (wealth > 250000) { wealthMultiplier = 1.5f; } if (wealth > 500000) { wealthMultiplier = 2f; } if (wealth > 1000000) { wealthMultiplier = 2.5f; } ModOptions.SettingsRef settingsRef = new ModOptions.SettingsRef(); float geChance = 0.007f * wealthMultiplier; float riftChallenge = Mathf.Min(settingsRef.riftChallenge, 1f); if (settingsRef.riftChallenge > 1) { geChance *= .75f * riftChallenge; } else { geChance = 0; } float eChance = 0.035f * riftChallenge * (.75f * wealthMultiplier); float leChance = 0.12f * riftChallenge * (.75f * wealthMultiplier); IntVec3 curCell; IEnumerable <IntVec3> targets = GenRadial.RadialCellsAround(this.Position, 3, true); foreach (var cell in targets) { curCell = cell; if (curCell.InBounds(this.Map) && curCell.IsValid && curCell.Walkable(this.Map)) { SpawnThings rogueElemental = new SpawnThings(); if (rnd < 2) { if (Rand.Chance(geChance)) { MoteMaker.ThrowSmoke(curCell.ToVector3(), this.Map, 1f); MoteMaker.ThrowMicroSparks(curCell.ToVector3(), this.Map); SoundDefOf.Ambient_AltitudeWind.sustainFadeoutTime.Equals(30.0f); rogueElemental.def = TorannMagicDefOf.TM_GreaterEarth_ElementalR; rogueElemental.kindDef = PawnKindDef.Named("TM_GreaterEarth_Elemental"); } else if (Rand.Chance(eChance)) { MoteMaker.ThrowSmoke(curCell.ToVector3(), this.Map, 1f); MoteMaker.ThrowMicroSparks(curCell.ToVector3(), this.Map); SoundDefOf.Ambient_AltitudeWind.sustainFadeoutTime.Equals(30.0f); rogueElemental.def = TorannMagicDefOf.TM_Earth_ElementalR; rogueElemental.kindDef = PawnKindDef.Named("TM_Earth_Elemental"); } else if (Rand.Chance(leChance)) { MoteMaker.ThrowSmoke(curCell.ToVector3(), this.Map, 1f); MoteMaker.ThrowMicroSparks(curCell.ToVector3(), this.Map); SoundDefOf.Ambient_AltitudeWind.sustainFadeoutTime.Equals(30.0f); rogueElemental.def = TorannMagicDefOf.TM_LesserEarth_ElementalR; rogueElemental.kindDef = PawnKindDef.Named("TM_LesserEarth_Elemental"); } else { rogueElemental = null; } } else if (rnd >= 2 && rnd < 4) { if (Rand.Chance(geChance)) { MoteMaker.ThrowSmoke(curCell.ToVector3(), this.Map, 1); MoteMaker.ThrowMicroSparks(curCell.ToVector3(), this.Map); MoteMaker.ThrowFireGlow(curCell, this.Map, 1); MoteMaker.ThrowHeatGlow(curCell, this.Map, 1); rogueElemental.def = TorannMagicDefOf.TM_GreaterFire_ElementalR; rogueElemental.kindDef = PawnKindDef.Named("TM_GreaterFire_Elemental"); } else if (Rand.Chance(eChance)) { MoteMaker.ThrowSmoke(curCell.ToVector3(), this.Map, 1); MoteMaker.ThrowMicroSparks(curCell.ToVector3(), this.Map); MoteMaker.ThrowFireGlow(curCell, this.Map, 1); MoteMaker.ThrowHeatGlow(curCell, this.Map, 1); rogueElemental.def = TorannMagicDefOf.TM_Fire_ElementalR; rogueElemental.kindDef = PawnKindDef.Named("TM_Fire_Elemental"); } else if (Rand.Chance(leChance)) { MoteMaker.ThrowSmoke(curCell.ToVector3(), this.Map, 1); MoteMaker.ThrowMicroSparks(curCell.ToVector3(), this.Map); MoteMaker.ThrowFireGlow(curCell, this.Map, 1); MoteMaker.ThrowHeatGlow(curCell, this.Map, 1); rogueElemental.def = TorannMagicDefOf.TM_LesserFire_ElementalR; rogueElemental.kindDef = PawnKindDef.Named("TM_LesserFire_Elemental"); } else { rogueElemental = null; } } else if (rnd >= 4 && rnd < 6) { if (Rand.Chance(geChance)) { MoteMaker.ThrowSmoke(curCell.ToVector3(), this.Map, 1); SoundDefOf.Ambient_AltitudeWind.sustainFadeoutTime.Equals(30.0f); MoteMaker.ThrowTornadoDustPuff(curCell.ToVector3(), this.Map, 1, Color.blue); MoteMaker.ThrowTornadoDustPuff(curCell.ToVector3(), this.Map, 1, Color.blue); MoteMaker.ThrowTornadoDustPuff(curCell.ToVector3(), this.Map, 1, Color.blue); rogueElemental.def = TorannMagicDefOf.TM_GreaterWater_ElementalR; rogueElemental.kindDef = PawnKindDef.Named("TM_GreaterWater_Elemental"); } else if (Rand.Chance(eChance)) { MoteMaker.ThrowSmoke(curCell.ToVector3(), this.Map, 1); SoundDefOf.Ambient_AltitudeWind.sustainFadeoutTime.Equals(30.0f); MoteMaker.ThrowTornadoDustPuff(curCell.ToVector3(), this.Map, 1, Color.blue); MoteMaker.ThrowTornadoDustPuff(curCell.ToVector3(), this.Map, 1, Color.blue); MoteMaker.ThrowTornadoDustPuff(curCell.ToVector3(), this.Map, 1, Color.blue); rogueElemental.def = TorannMagicDefOf.TM_Water_ElementalR; rogueElemental.kindDef = PawnKindDef.Named("TM_Water_Elemental"); } else if (Rand.Chance(leChance)) { MoteMaker.ThrowSmoke(curCell.ToVector3(), this.Map, 1); SoundDefOf.Ambient_AltitudeWind.sustainFadeoutTime.Equals(30.0f); MoteMaker.ThrowTornadoDustPuff(curCell.ToVector3(), this.Map, 1, Color.blue); MoteMaker.ThrowTornadoDustPuff(curCell.ToVector3(), this.Map, 1, Color.blue); MoteMaker.ThrowTornadoDustPuff(curCell.ToVector3(), this.Map, 1, Color.blue); rogueElemental.def = TorannMagicDefOf.TM_LesserWater_ElementalR; rogueElemental.kindDef = PawnKindDef.Named("TM_LesserWater_Elemental"); } else { rogueElemental = null; } } else { if (Rand.Chance(geChance)) { rogueElemental.def = TorannMagicDefOf.TM_GreaterWind_ElementalR; rogueElemental.kindDef = PawnKindDef.Named("TM_GreaterWind_Elemental"); MoteMaker.ThrowSmoke(curCell.ToVector3(), this.Map, 1 + (1 * 2)); SoundDefOf.Ambient_AltitudeWind.sustainFadeoutTime.Equals(30.0f); MoteMaker.ThrowTornadoDustPuff(curCell.ToVector3(), this.Map, 1, Color.white); } else if (Rand.Chance(eChance)) { rogueElemental.def = TorannMagicDefOf.TM_Wind_ElementalR; rogueElemental.kindDef = PawnKindDef.Named("TM_Wind_Elemental"); MoteMaker.ThrowSmoke(curCell.ToVector3(), this.Map, 1 + (1 * 2)); SoundDefOf.Ambient_AltitudeWind.sustainFadeoutTime.Equals(30.0f); MoteMaker.ThrowTornadoDustPuff(curCell.ToVector3(), this.Map, 1, Color.white); } else if (Rand.Chance(leChance)) { rogueElemental.def = TorannMagicDefOf.TM_LesserWind_ElementalR; rogueElemental.kindDef = PawnKindDef.Named("TM_LesserWind_Elemental"); MoteMaker.ThrowSmoke(curCell.ToVector3(), this.Map, 1 + (1 * 2)); SoundDefOf.Ambient_AltitudeWind.sustainFadeoutTime.Equals(30.0f); MoteMaker.ThrowTornadoDustPuff(curCell.ToVector3(), this.Map, 1, Color.white); } else { rogueElemental = null; } } if (rogueElemental != null) { SingleSpawnLoop(rogueElemental, curCell, this.Map); } } } }
private void Dig(IntVec3 start, float dir, float width, List <IntVec3> group, Map map, bool closed, HashSet <IntVec3> visited = null) { Vector3 vector = start.ToVector3Shifted(); IntVec3 intVec = start; float num = 0f; MapGenFloatGrid elevation = MapGenerator.Elevation; MapGenFloatGrid caves = MapGenerator.Caves; bool flag = false; bool flag2 = false; if (visited == null) { visited = new HashSet <IntVec3>(); } GenStep_ElevateEvelationForUnderground.tmpGroupSet.Clear(); GenStep_ElevateEvelationForUnderground.tmpGroupSet.AddRange(group); int num2 = 0; for (; ;) { if (closed) { int num3 = GenRadial.NumCellsInRadius(width / 2f + 1.5f); for (int i = 0; i < num3; i++) { IntVec3 intVec2 = intVec + GenRadial.RadialPattern[i]; if (!visited.Contains(intVec2)) { if (!GenStep_ElevateEvelationForUnderground.tmpGroupSet.Contains(intVec2) || caves[intVec2] > 0f) { return; } } } } if (num2 >= 15 && width > 1.4f + GenStep_ElevateEvelationForUnderground.BranchedTunnelWidthOffset.max) { if (!flag && Rand.Chance(BranchChance)) { this.DigInBestDirection(intVec, dir, new FloatRange(40f, 90f), width - GenStep_ElevateEvelationForUnderground.BranchedTunnelWidthOffset.RandomInRange, group, map, closed, visited); flag = true; } if (!flag2 && Rand.Chance(BranchChance)) { this.DigInBestDirection(intVec, dir, new FloatRange(-90f, -40f), width - GenStep_ElevateEvelationForUnderground.BranchedTunnelWidthOffset.RandomInRange, group, map, closed, visited); flag2 = true; } } bool flag3; this.SetCaveAround(intVec, width, map, visited, out flag3); if (flag3) { return; } while (vector.ToIntVec3() == intVec) { vector += Vector3Utility.FromAngleFlat(dir) * 0.5f; num += 0.5f; } if (!GenStep_ElevateEvelationForUnderground.tmpGroupSet.Contains(vector.ToIntVec3())) { return; } IntVec3 intVec3 = new IntVec3(intVec.x, 0, vector.ToIntVec3().z); if (this.IsRock(intVec3, elevation, map)) { caves[intVec3] = Mathf.Max(caves[intVec3], width); visited.Add(intVec3); } intVec = vector.ToIntVec3(); dir += (float)this.directionNoise.GetValue((double)(num * 60f), (double)((float)start.x * 200f), (double)((float)start.z * 200f)) * 8f; width -= 0.034f; if (width < 1.4f) { return; } num2++; } }
protected virtual void Impact(Thing hitThing) { bool flag = hitThing == null; if (flag) { Pawn pawn; bool flag2 = (pawn = (base.Position.GetThingList(base.Map).FirstOrDefault((Thing x) => x == this.assignedTarget) as Pawn)) != null; if (flag2) { hitThing = pawn; } } bool hasValue = this.impactDamage.HasValue; if (hasValue) { hitThing.TakeDamage(this.impactDamage.Value); } if (this.flyingThing is Pawn) { try { SoundDefOf.Ambient_AltitudeWind.sustainFadeoutTime.Equals(30.0f); GenSpawn.Spawn(this.flyingThing, base.Position, base.Map); Pawn p = this.flyingThing as Pawn; if (this.earlyImpact) { DamageEntities(p, this.impactForce, DamageDefOf.Blunt); DamageEntities(p, 2 * this.impactForce, DamageDefOf.Stun); } this.Destroy(DestroyMode.Vanish); } catch { GenSpawn.Spawn(this.flyingThing, base.Position, base.Map); Pawn p = this.flyingThing as Pawn; this.Destroy(DestroyMode.Vanish); } } else { if (this.impactRadius > 0) { if (this.isExplosive) { GenExplosion.DoExplosion(this.ExactPosition.ToIntVec3(), this.Map, this.impactRadius, this.impactDamageType, this.launcher as Pawn, this.explosionDamage, -1, this.impactDamageType.soundExplosion, def, null, null, null, 0f, 1, false, null, 0f, 0, 0.0f, true); } else { int num = GenRadial.NumCellsInRadius(this.impactRadius); IntVec3 curCell; for (int i = 0; i < num; i++) { curCell = this.ExactPosition.ToIntVec3() + GenRadial.RadialPattern[i]; List <Thing> hitList = new List <Thing>(); hitList = curCell.GetThingList(this.Map); for (int j = 0; j < hitList.Count; j++) { if (hitList[j] is Pawn && hitList[j] != this.pawn) { DamageEntities(hitList[j], this.explosionDamage, this.impactDamageType); } } } } } this.Destroy(DestroyMode.Vanish); } }
internal static List <FloatMenuOption> ChoicesAtFor(Vector3 clickPos, Pawn pawn) { IntVec3 clickCell = IntVec3.FromVector3(clickPos); DangerUtility.NotifyDirectOrderingThisFrame(pawn); List <FloatMenuOption> list = new List <FloatMenuOption>(); if (!clickCell.InBounds()) { return(list); } // ***** Beginning of drafted options ***** if (pawn.Drafted) { foreach (TargetInfo attackTarg in GenUI.TargetsAt(clickPos, TargetingParameters.ForAttackHostile(), true)) { // *** Fire at option *** if (pawn.equipment.Primary != null && !pawn.equipment.PrimaryEq.PrimaryVerb.verbProps.MeleeRange) { string str; Action rangedAct = FloatMenuUtility.GetRangedAttackAction(pawn, attackTarg, out str); string text = "FireAt".Translate(new object[] { attackTarg.Thing.LabelCap }); FloatMenuOption floatMenuOption = new FloatMenuOption(); floatMenuOption.priority = MenuOptionPriority.High; if (rangedAct == null) { text = text + " (" + str + ")"; } else { floatMenuOption.autoTakeable = true; floatMenuOption.action = new Action(delegate { MoteThrower.ThrowStatic(attackTarg.Thing.DrawPos, ThingDefOf.Mote_FeedbackAttack, 1f); rangedAct(); }); } floatMenuOption.label = text; list.Add(floatMenuOption); } // *** Melee attack option *** string str2; Action meleeAct = FloatMenuUtility.GetMeleeAttackAction(pawn, attackTarg, out str2); Pawn pawn2 = attackTarg.Thing as Pawn; string text2; if (pawn2 != null && pawn2.Downed) { text2 = "MeleeAttackToDeath".Translate(new object[] { attackTarg.Thing.LabelCap }); } else { text2 = "MeleeAttack".Translate(new object[] { attackTarg.Thing.LabelCap }); } Thing thing = attackTarg.Thing; FloatMenuOption floatMenuOption2 = new FloatMenuOption(string.Empty, null, MenuOptionPriority.High, null, thing); if (meleeAct == null) { text2 = text2 + " (" + str2 + ")"; } else { floatMenuOption2.action = new Action(delegate { MoteThrower.ThrowStatic(attackTarg.Thing.DrawPos, ThingDefOf.Mote_FeedbackAttack, 1f); meleeAct(); }); } floatMenuOption2.label = text2; list.Add(floatMenuOption2); } // *** Arrest option *** if (pawn.RaceProps.Humanlike && !pawn.Downed) { foreach (TargetInfo current2 in GenUI.TargetsAt(clickPos, TargetingParameters.ForArrest(pawn), true)) { TargetInfo dest = current2; if (!pawn.CanReach(dest, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)) { list.Add(new FloatMenuOption("CannotArrest".Translate() + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null)); } else if (!pawn.CanReserve(dest.Thing, 1)) { list.Add(new FloatMenuOption("CannotArrest".Translate() + ": " + "Reserved".Translate(), null, MenuOptionPriority.Medium, null, null)); } else { Pawn pTarg = (Pawn)dest.Thing; Action action = new Action(delegate { Building_Bed building_Bed = RestUtility.FindBedFor(pTarg, pawn, true, false, false); if (building_Bed == null) { Messages.Message("CannotArrest".Translate() + ": " + "NoPrisonerBed".Translate(), pTarg, MessageSound.RejectInput); return; } Job job = new Job(JobDefOf.Arrest, pTarg, building_Bed); job.playerForced = true; job.maxNumToCarry = 1; pawn.drafter.TakeOrderedJob(job); TutorUtility.DoModalDialogIfNotKnown(ConceptDefOf.ArrestingCreatesEnemies); }); List <FloatMenuOption> arg_3F1_0 = list; Thing thing = dest.Thing; arg_3F1_0.Add(new FloatMenuOption("TryToArrest".Translate(new object[] { dest.Thing.LabelCap }), action, MenuOptionPriority.Medium, null, thing)); } } } // *** Goto option *** int num = GenRadial.NumCellsInRadius(2.9f); for (int i = 0; i < num; i++) { IntVec3 curLoc = GenRadial.RadialPattern[i] + clickCell; if (curLoc.Standable()) { if (curLoc != pawn.Position) { if (!pawn.CanReach(curLoc, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)) { FloatMenuOption item = new FloatMenuOption("CannotGoNoPath".Translate(), null, MenuOptionPriority.Low, null, null); list.Add(item); } else { Action action2 = new Action(delegate { IntVec3 dest = Pawn_DraftController.BestGotoDestNear(curLoc, pawn); Job job = new Job(JobDefOf.Goto, dest); job.playerForced = true; pawn.drafter.TakeOrderedJob(job); MoteThrower.ThrowStatic(dest, ThingDefOf.Mote_FeedbackGoto, 1f); }); list.Add(new FloatMenuOption("GoHere".Translate(), action2, MenuOptionPriority.Low, null, null) { autoTakeable = true }); } } break; } } } // *** End of drafted options *** // *** Beginning of humanlike options *** if (pawn.RaceProps.Humanlike) { int num2 = 0; if (pawn.story != null) { num2 = pawn.story.traits.DegreeOfTrait(TraitDefOf.DrugDesire); } // *** Consume option *** foreach (Thing current3 in clickCell.GetThingList()) { Thing t = current3; if (t.def.ingestible != null && pawn.RaceProps.CanEverEat(t) && t.IngestibleNow) { FloatMenuOption item2; if (t.def.ingestible.isPleasureDrug && num2 < 0) { item2 = new FloatMenuOption("ConsumeThing".Translate(new object[] { t.LabelBaseShort }) + " (" + "Teetotaler".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else if (!pawn.CanReach(t, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)) { item2 = new FloatMenuOption("ConsumeThing".Translate(new object[] { t.LabelBaseShort }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else if (!pawn.CanReserve(t, 1)) { item2 = new FloatMenuOption("ConsumeThing".Translate(new object[] { t.LabelBaseShort }) + " (" + "ReservedBy".Translate(new object[] { Find.Reservations.FirstReserverOf(t, pawn.Faction).LabelBaseShort }) + ")", null, MenuOptionPriority.Medium, null, null); } else { item2 = new FloatMenuOption("ConsumeThing".Translate(new object[] { t.LabelBaseShort }), new Action(delegate { t.SetForbidden(false, true); Job job = new Job(JobDefOf.Ingest, t); job.maxNumToCarry = t.def.ingestible.maxNumToIngestAtOnce; pawn.drafter.TakeOrderedJob(job); }), MenuOptionPriority.Medium, null, null); } list.Add(item2); } } // *** Rescue/Capture downed option *** foreach (TargetInfo current4 in GenUI.TargetsAt(clickPos, TargetingParameters.ForRescue(pawn), true)) { Pawn victim = (Pawn)current4.Thing; if (!victim.InBed() && pawn.CanReserveAndReach(victim, PathEndMode.OnCell, Danger.Deadly, 1) && !victim.IsPrisonerOfColony) { if ((victim.Faction == Faction.OfColony && victim.MentalStateDef == null) || (victim.Faction != Faction.OfColony && victim.MentalStateDef == null && !victim.IsPrisonerOfColony && (victim.Faction == null || !victim.Faction.HostileTo(Faction.OfColony)))) { List <FloatMenuOption> arg_8E1_0 = list; Pawn victim2 = victim; arg_8E1_0.Add(new FloatMenuOption("Rescue".Translate(new object[] { victim2.LabelCap }), new Action(delegate { Building_Bed building_Bed = RestUtility.FindBedFor(victim, pawn, false, false, false); if (building_Bed == null) { string str; if (victim.RaceProps.Animal) { str = "NoAnimalBed".Translate(); } else { str = "NoNonPrisonerBed".Translate(); } Messages.Message("CannotRescue".Translate() + ": " + str, victim, MessageSound.RejectInput); return; } Job job = new Job(JobDefOf.Rescue, victim, building_Bed); job.maxNumToCarry = 1; job.playerForced = true; pawn.drafter.TakeOrderedJob(job); ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.Rescuing, KnowledgeAmount.Total); }), MenuOptionPriority.Medium, null, victim2)); } if (victim.MentalStateDef != null || (victim.RaceProps.Humanlike && victim.Faction != Faction.OfColony)) { List <FloatMenuOption> arg_962_0 = list; Pawn victim2 = victim; arg_962_0.Add(new FloatMenuOption("Capture".Translate(new object[] { victim2.LabelCap }), new Action(delegate { Building_Bed building_Bed = RestUtility.FindBedFor(victim, pawn, true, false, false); if (building_Bed == null) { Messages.Message("CannotCapture".Translate() + ": " + "NoPrisonerBed".Translate(), victim, MessageSound.RejectInput); return; } Job job = new Job(JobDefOf.Capture, victim, building_Bed); job.maxNumToCarry = 1; job.playerForced = true; pawn.drafter.TakeOrderedJob(job); ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.Capturing, KnowledgeAmount.Total); }), MenuOptionPriority.Medium, null, victim2)); } } } // *** Carry to cryosleep option *** foreach (TargetInfo current5 in GenUI.TargetsAt(clickPos, TargetingParameters.ForRescue(pawn), true)) { TargetInfo targetInfo = current5; Pawn victim = (Pawn)targetInfo.Thing; if (victim.Downed && pawn.CanReserveAndReach(victim, PathEndMode.OnCell, Danger.Deadly, 1) && Building_CryptosleepCasket.FindCryptosleepCasketFor(victim, pawn) != null) { string label = "CarryToCryptosleepCasket".Translate(new object[] { targetInfo.Thing.LabelCap }); JobDef jDef = JobDefOf.CarryToCryptosleepCasket; Action action3 = new Action(delegate { Building_CryptosleepCasket building_CryptosleepCasket = Building_CryptosleepCasket.FindCryptosleepCasketFor(victim, pawn); if (building_CryptosleepCasket == null) { Messages.Message("CannotCarryToCryptosleepCasket".Translate() + ": " + "NoCryptosleepCasket".Translate(), victim, MessageSound.RejectInput); return; } Job job = new Job(jDef, victim, building_CryptosleepCasket); job.maxNumToCarry = 1; job.playerForced = true; pawn.drafter.TakeOrderedJob(job); }); List <FloatMenuOption> arg_A80_0 = list; Pawn victim2 = victim; arg_A80_0.Add(new FloatMenuOption(label, action3, MenuOptionPriority.Medium, null, victim2)); } } // *** Strip option *** foreach (TargetInfo current6 in GenUI.TargetsAt(clickPos, TargetingParameters.ForStrip(pawn), true)) { TargetInfo stripTarg = current6; FloatMenuOption item3; if (!pawn.CanReach(stripTarg, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn)) { item3 = new FloatMenuOption("CannotStrip".Translate(new object[] { stripTarg.Thing.LabelCap }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else if (!pawn.CanReserveAndReach(stripTarg, PathEndMode.ClosestTouch, Danger.Deadly, 1)) { item3 = new FloatMenuOption("CannotStrip".Translate(new object[] { stripTarg.Thing.LabelCap }) + " (" + "ReservedBy".Translate(new object[] { Find.Reservations.FirstReserverOf(stripTarg, pawn.Faction).LabelBaseShort }) + ")", null, MenuOptionPriority.Medium, null, null); } else { item3 = new FloatMenuOption("Strip".Translate(new object[] { stripTarg.Thing.LabelCap }), new Action(delegate { stripTarg.Thing.SetForbidden(false, false); Job job = new Job(JobDefOf.Strip, stripTarg); job.playerForced = true; pawn.drafter.TakeOrderedJob(job); }), MenuOptionPriority.Medium, null, null); } list.Add(item3); } // *** Equip option *** CompInventory compInventory = pawn.TryGetComp <CompInventory>(); // Need compInventory here for equip and wear options if (pawn.equipment != null) { ThingWithComps equipment = null; List <Thing> thingList = clickCell.GetThingList(); for (int j = 0; j < thingList.Count; j++) { if (thingList[j].TryGetComp <CompEquippable>() != null) { equipment = (ThingWithComps)thingList[j]; break; } } if (equipment != null) { string eqLabel = GenLabel.ThingLabel(equipment.def, equipment.Stuff, 1); FloatMenuOption equipOption; if (!pawn.CanReach(equipment, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn)) { equipOption = new FloatMenuOption("CannotEquip".Translate(new object[] { eqLabel }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else if (!pawn.CanReserve(equipment, 1)) { equipOption = new FloatMenuOption("CannotEquip".Translate(new object[] { eqLabel }) + " (" + "ReservedBy".Translate(new object[] { Find.Reservations.FirstReserverOf(equipment, pawn.Faction).LabelBaseShort }) + ")", null, MenuOptionPriority.Medium, null, null); } else if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { equipOption = new FloatMenuOption("CannotEquip".Translate(new object[] { eqLabel }) + " (" + "Incapable".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else { // Added check for inventory space here int count; if (compInventory != null && !compInventory.CanFitInInventory(equipment, out count, true)) { equipOption = new FloatMenuOption("CannotEquip".Translate(new object[] { eqLabel }) + " (" + "CR_InventoryFull".Translate() + ")", null); } else { string equipOptionLabel = "Equip".Translate(new object[] { eqLabel }); if (equipment.def.IsRangedWeapon && pawn.story != null && pawn.story.traits.HasTrait(TraitDefOf.Brawler)) { equipOptionLabel = equipOptionLabel + " " + "EquipWarningBrawler".Translate(); } equipOption = new FloatMenuOption(equipOptionLabel, new Action(delegate { equipment.SetForbidden(false, true); Job job = new Job(JobDefOf.Equip, equipment); job.playerForced = true; pawn.drafter.TakeOrderedJob(job); MoteThrower.ThrowStatic(equipment.DrawPos, ThingDefOf.Mote_FeedbackEquip, 1f); ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.EquippingWeapons, KnowledgeAmount.Total); }), MenuOptionPriority.Medium, null, null); } } list.Add(equipOption); } } // *** Wear option *** if (pawn.apparel != null) { Apparel apparel = Find.ThingGrid.ThingAt <Apparel>(clickCell); if (apparel != null) { FloatMenuOption wearOption; if (!pawn.CanReach(apparel, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn)) { wearOption = new FloatMenuOption("CannotWear".Translate(new object[] { apparel.Label }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else if (!pawn.CanReserve(apparel, 1)) { Pawn pawn3 = Find.Reservations.FirstReserverOf(apparel, pawn.Faction); wearOption = new FloatMenuOption("CannotWear".Translate(new object[] { apparel.Label }) + " (" + "ReservedBy".Translate(new object[] { pawn3.LabelBaseShort }) + ")", null, MenuOptionPriority.Medium, null, null); } else if (!ApparelUtility.HasPartsToWear(pawn, apparel.def)) { wearOption = new FloatMenuOption("CannotWear".Translate(new object[] { apparel.Label }) + " (" + "CannotWearBecauseOfMissingBodyParts".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else { // Added check for inventory capacity int count; if (compInventory != null && !compInventory.CanFitInInventory(apparel, out count, false, true)) { wearOption = new FloatMenuOption("CannotWear".Translate(new object[] { apparel.Label }) + " (" + "CR_InventoryFull".Translate() + ")", null); } else { wearOption = new FloatMenuOption("ForceWear".Translate(new object[] { apparel.LabelBaseShort }), new Action(delegate { apparel.SetForbidden(false, true); Job job = new Job(JobDefOf.Wear, apparel); job.playerForced = true; pawn.drafter.TakeOrderedJob(job); }), MenuOptionPriority.Medium, null, null); } } list.Add(wearOption); } } // *** NEW: Pick up option *** if (compInventory != null) { List <Thing> thingList = clickCell.GetThingList(); if (!thingList.NullOrEmpty <Thing>()) { Thing item = thingList.FirstOrDefault(thing => thing.def.alwaysHaulable && !(thing is Corpse)); if (item != null) { FloatMenuOption pickUpOption; int count = 0; if (!pawn.CanReach(item, PathEndMode.Touch, Danger.Deadly)) { pickUpOption = new FloatMenuOption("CR_CannotPickUp".Translate() + " " + item.LabelBaseShort + " (" + "NoPath".Translate() + ")", null); } else if (!pawn.CanReserve(item)) { pickUpOption = new FloatMenuOption("CR_CannotPickUp".Translate() + " " + item.LabelBaseShort + " (" + "ReservedBy".Translate(new object[] { Find.Reservations.FirstReserverOf(item, pawn.Faction) }), null); } else if (!compInventory.CanFitInInventory(item, out count)) { pickUpOption = new FloatMenuOption("CR_CannotPickUp".Translate() + " " + item.LabelBaseShort + " (" + "CR_InventoryFull".Translate() + ")", null); } else { pickUpOption = new FloatMenuOption("CR_PickUp".Translate() + " " + item.LabelBaseShort, new Action(delegate { item.SetForbidden(false); Job job = new Job(JobDefOf.TakeInventory, item) { maxNumToCarry = 1 }; job.playerForced = true; pawn.drafter.TakeOrderedJob(job); })); } list.Add(pickUpOption); if (count > 1 && item.stackCount > 1) { int numToCarry = Math.Min(count, item.stackCount); FloatMenuOption pickUpStackOption = new FloatMenuOption("CR_PickUp".Translate() + " " + item.LabelBaseShort + " x" + numToCarry.ToString(), new Action(delegate { item.SetForbidden(false); Job job = new Job(JobDefOf.TakeInventory, item) { maxNumToCarry = numToCarry }; job.playerForced = true; pawn.drafter.TakeOrderedJob(job); })); list.Add(pickUpStackOption); } } } } // *** Deposit/drop equipment options *** if (pawn.equipment != null && pawn.equipment.Primary != null) { Thing thing2 = Find.ThingGrid.ThingAt(clickCell, ThingDefOf.EquipmentRack); if (thing2 != null) { if (!pawn.CanReach(thing2, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn)) { list.Add(new FloatMenuOption("CannotDeposit".Translate(new object[] { pawn.equipment.Primary.LabelCap, thing2.def.label }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null)); } else { using (IEnumerator <IntVec3> enumerator7 = GenAdj.CellsOccupiedBy(thing2).GetEnumerator()) { while (enumerator7.MoveNext()) { IntVec3 c = enumerator7.Current; if (c.GetStorable() == null && pawn.CanReserveAndReach(c, PathEndMode.ClosestTouch, Danger.Deadly, 1)) { Action action4 = new Action(delegate { ThingWithComps t; if (pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out t, pawn.Position, true)) { t.SetForbidden(false, true); Job job = new Job(JobDefOf.HaulToCell, t, c); job.haulMode = HaulMode.ToCellStorage; job.maxNumToCarry = 1; job.playerForced = true; pawn.drafter.TakeOrderedJob(job); } }); list.Add(new FloatMenuOption("Deposit".Translate(new object[] { pawn.equipment.Primary.LabelCap, thing2.def.label }), action4, MenuOptionPriority.Medium, null, null)); break; } } } } } if (pawn.equipment != null && GenUI.TargetsAt(clickPos, TargetingParameters.ForSelf(pawn), true).Any <TargetInfo>()) { Action action5 = new Action(delegate { ThingWithComps thingWithComps; pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out thingWithComps, pawn.Position, true); pawn.drafter.TakeOrderedJob(new Job(JobDefOf.Wait, 20, false)); } ); list.Add(new FloatMenuOption("Drop".Translate(new object[] { pawn.equipment.Primary.LabelCap }), action5, MenuOptionPriority.Medium, null, null)); } } // *** Trade with option *** foreach (TargetInfo current7 in GenUI.TargetsAt(clickPos, TargetingParameters.ForTrade(), true)) { TargetInfo dest2 = current7; if (!pawn.CanReach(dest2, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)) { list.Add(new FloatMenuOption("CannotTrade".Translate() + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null)); } else if (!pawn.CanReserve(dest2.Thing, 1)) { list.Add(new FloatMenuOption("CannotTrade".Translate() + " (" + "Reserved".Translate() + ")", null, MenuOptionPriority.Medium, null, null)); } else { Pawn pTarg = (Pawn)dest2.Thing; Action action6 = new Action(delegate { Job job = new Job(JobDefOf.TradeWithPawn, pTarg); job.playerForced = true; pawn.drafter.TakeOrderedJob(job); ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.InteractingWithTraders, KnowledgeAmount.Total); }); string str3 = string.Empty; if (pTarg.Faction != null) { str3 = " (" + pTarg.Faction.name + ")"; } List <FloatMenuOption> arg_142E_0 = list; Thing thing = dest2.Thing; arg_142E_0.Add(new FloatMenuOption("TradeWith".Translate(new object[] { pTarg.LabelBaseShort }) + str3, action6, MenuOptionPriority.Medium, null, thing)); } } foreach (Thing current8 in Find.ThingGrid.ThingsAt(clickCell)) { foreach (FloatMenuOption current9 in current8.GetFloatMenuOptions(pawn)) { list.Add(current9); } } } // *** End of humanlike options *** // *** Beginning of non-drafted options *** if (!pawn.Drafted) { bool flag = false; bool flag2 = false; foreach (Thing current10 in Find.ThingGrid.ThingsAt(clickCell)) { flag2 = true; if (pawn.CanReach(current10, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)) { flag = true; break; } } if (flag2 && !flag) { list.Add(new FloatMenuOption("(" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null)); return(list); } foreach (Thing current11 in Find.ThingGrid.ThingsAt(clickCell)) { Pawn pawn4 = Find.Reservations.FirstReserverOf(current11, pawn.Faction); if (pawn4 != null && pawn4 != pawn) { list.Add(new FloatMenuOption("IsReservedBy".Translate(new object[] { current11.LabelBaseShort.CapitalizeFirst(), pawn4.LabelBaseShort }), null, MenuOptionPriority.Medium, null, null)); } else { JobGiver_Work jobGiver_Work = pawn.thinker.TryGetMainTreeThinkNode <JobGiver_Work>(); if (jobGiver_Work != null) { foreach (WorkTypeDef current12 in DefDatabase <WorkTypeDef> .AllDefsListForReading) { for (int k = 0; k < current12.workGiversByPriority.Count; k++) { WorkGiver_Scanner workGiver_Scanner = current12.workGiversByPriority[k].Worker as WorkGiver_Scanner; if (workGiver_Scanner != null) { if (workGiver_Scanner.def.directOrderable) { if (!workGiver_Scanner.ShouldSkip(pawn)) { JobFailReason.Clear(); Job job; if (!workGiver_Scanner.HasJobOnThingForced(pawn, current11)) { job = null; } else { job = workGiver_Scanner.JobOnThingForced(pawn, current11); } if (workGiver_Scanner.PotentialWorkThingRequest.Accepts(current11) || (workGiver_Scanner.PotentialWorkThingsGlobal(pawn) != null && workGiver_Scanner.PotentialWorkThingsGlobal(pawn).Contains(current11))) { if (job == null) { if (JobFailReason.HaveReason) { string label2 = "CannotGenericWork".Translate(new object[] { workGiver_Scanner.def.verb, current11.LabelBaseShort }) + " (" + JobFailReason.Reason + ")"; list.Add(new FloatMenuOption(label2, null, MenuOptionPriority.Medium, null, null)); } } else { string label; WorkTypeDef workType = workGiver_Scanner.def.workType; Action action7 = null; PawnCapacityDef pawnCapacityDef = workGiver_Scanner.MissingRequiredCapacity(pawn); if (pawnCapacityDef != null) { label = "CannotMissingHealthActivities".Translate(new object[] { pawnCapacityDef.label }); } else if (pawn.jobs.curJob != null && pawn.jobs.curJob.JobIsSameAs(job)) { label = "CannotGenericAlreadyAm".Translate(new object[] { workType.gerundLabel, current11.LabelBaseShort }); } else if (pawn.workSettings.GetPriority(workType) == 0) { label = "CannotPrioritizeIsNotA".Translate(new object[] { pawn.NameStringShort, workType.pawnLabel }); } else if (job.def == JobDefOf.Research && current11 is Building_ResearchBench) { label = "CannotPrioritizeResearch".Translate(); } else if (current11.IsForbidden(pawn)) { label = "CannotPrioritizeForbidden".Translate(new object[] { current11.Label }); } else if (!pawn.CanReach(current11, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)) { label = current11.Label + ": " + "NoPath".Translate(); } else { label = "PrioritizeGeneric".Translate(new object[] { workGiver_Scanner.def.gerund, current11.Label }); Job localJob = job; WorkTypeDef localWorkTypeDef = workType; action7 = new Action(delegate { pawn.thinker.GetMainTreeThinkNode <JobGiver_Work>().TryStartPrioritizedWorkOn(pawn, localJob, localWorkTypeDef); }); } if (!list.Any(op => op.label == label)) { list.Add(new FloatMenuOption(label, action7, MenuOptionPriority.Medium, null, null)); } } } } } } } } } } } } // *** End of non-drafted options *** foreach (FloatMenuOption current13 in pawn.GetExtraFloatMenuOptionsFor(clickCell)) { list.Add(current13); } DangerUtility.DoneDirectOrdering(); return(list); }