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);
                }
            }
        }
예제 #2
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++;
        }
예제 #4
0
        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);
        }
예제 #5
0
        /// <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);
        }
예제 #7
0
 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));
                }
            }
        }
예제 #9
0
        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();
        }
예제 #10
0
 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));
 }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        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]);
                    }
                }
            }
        }
예제 #15
0
        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);
        }
예제 #18
0
        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}");
            }
        }
예제 #19
0
        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);
            }
        }
예제 #20
0
        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);
        }
예제 #21
0
        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);
        }
예제 #22
0
        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);
                    }
                }
            }
        }
예제 #25
0
 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();
                             }
                         }
                     }
                 }
             }
         }
     }
 }
예제 #26
0
        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++;
            }
        }
예제 #29
0
        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);
            }
        }
예제 #30
0
        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);
        }