示例#1
0
        private void SendDrop()
        {
            Map map = Current.Game.CurrentMap;

            GenDate.DayOfYear(ticks, Find.WorldGrid.LongLatOf(map.Tile).x);
            List <Thing> thingList = new List <Thing>
            {
                ThingMaker.MakeThing(AvaliDefs.AvaliNexus)
            };

            Scribe_Values.Look(ref hasDropped, "hasDropped", false);
            Map            target      = map;
            List <Faction> newFactions = new List <Faction>();
            IntVec3        intVec3     = DropCellFinder.TradeDropSpot(target);

            if (map.IsPlayerHome)
            {
                hasDropped = true;
                foreach (Faction faction in Find.FactionManager.AllFactions.Where(x => x.def == AvaliDefs.AvaliFaction))
                {
                    faction.SetRelationDirect(Faction.OfPlayer, FactionRelationKind.Ally);
                    newFactions.Add(faction);
                }
                DropPodUtility.DropThingsNear(intVec3, target, (IEnumerable <Thing>)thingList);
                ChoiceLetter choiceLetter = LetterMaker.MakeLetter("IlluminateAirdrop".Translate(), "AirdropEventDesc".Translate(), AvaliMod.AvaliDefs.IlluminateAirdrop);
                Find.LetterStack.ReceiveLetter(choiceLetter, null);
            }
            else
            {
                SetupDrop();
            }
        }
示例#2
0
        private void SendDrop()
        {
            GenDate.DayOfYear(ticks, Find.WorldGrid.LongLatOf(map.Tile).x);
            List <Thing> thingList = new List <Thing>();

            thingList.Add(ThingMaker.MakeThing(AvaliDefs.AvaliNexus));
            Scribe_Values.Look(ref hasDropped, "hasDropped", false);
            Map            target      = map;
            List <Faction> newFactions = new List <Faction>();
            IntVec3        intVec3     = DropCellFinder.TradeDropSpot(target);

            if (RimValiUtility.PawnOfRaceCount(Faction.OfPlayer, AvaliDefs.RimVali) >= 5 && !hasDropped)
            {
                hasDropped = true;
                for (int a = 0; a < random.Next(2, 5); a++)
                {
                    Faction faction = FactionGenerator.NewGeneratedFaction(AvaliDefs.AvaliFaction);
                    faction.Name = "IlluminateFactionName".Translate() + ": #" + a.ToString();
                    faction.SetRelationDirect(Faction.OfPlayer, FactionRelationKind.Ally);
                    newFactions.Add(faction);
                }
                DropPodUtility.DropThingsNear(intVec3, target, (IEnumerable <Thing>)thingList);
                ChoiceLetter choiceLetter = LetterMaker.MakeLetter("IlluminateAirdrop".Translate(), "AirdropEventDesc".Translate(), AvaliMod.AvaliDefs.IlluminateAirdrop, newFactions[random.Next(newFactions.Count)]);
                Find.LetterStack.ReceiveLetter(choiceLetter, null);
            }
        }
示例#3
0
 public override void PawnDied(Corpse corpse)
 {
     if (enableDebug)
     {
         Log.Message("Death detected");
     }
     if (corpse.InnerPawn.def.race == AvaliDefs.RimVali.race)
     {
         if (!(AvaliPackDriver.packs == null) && AvaliPackDriver.packs.Count > 0)
         {
             if (enableDebug)
             {
                 Log.Message("I got here, packs exist.");
             }
             Pawn pawn = corpse.InnerPawn;
             foreach (AvaliPack pack in AvaliPackDriver.packs)
             {
                 if (pack.pawns.Contains(pawn))
                 {
                     if (enableDebug)
                     {
                         Log.Message("The pawn had a pack");
                     }
                     DeathDate deathDate = new DeathDate();
                     Log.Message(GenDate.DayOfYear(1, Find.WorldGrid.LongLatOf(corpse.Map.Tile).x).ToString());
                     deathDate.day = GenDate.DayOfYear(1, Find.WorldGrid.LongLatOf(corpse.Map.Tile).x);
                     if (corpse.InnerPawn != null && enableDebug)
                     {
                         Log.Message("Pawn is not null");
                     }
                     deathDate.deadPawn = pawn;
                     if (enableDebug)
                     {
                         Log.Message("I got the deathdate");
                         Log.Message(deathDate.day.ToString());
                     }
                     pack.deathDates.Add(deathDate);
                     pack.size--;
                     if (enableDebug)
                     {
                         Log.Message(pack.size.ToString());
                     }
                     foreach (Pawn packmate in pack.pawns)
                     {
                         if (!(pawn == packmate) && !pawn.Dead)
                         {
                             PackComp comp = packmate.TryGetComp <PackComp>();
                             if (comp.Props.deathThought != null)
                             {
                                 packmate.needs.mood.thoughts.memories.TryGainMemory(comp.Props.deathThought);
                             }
                         }
                     }
                     break;
                 }
             }
         }
     }
 }
示例#4
0
        public static void PlanFuneral(Building_Grave __instance, Pawn worker)
        {
            Pawn planner;

            (from c in worker.Map.mapPawns.FreeColonistsSpawned
             where c.relations.OpinionOf(__instance.Corpse.InnerPawn) >= 20
             select c).TryRandomElementByWeight((c) => Mathf.Max(0f, c.relations.OpinionOf(__instance.Corpse.InnerPawn) - (PsycheHelper.PsychologyEnabled(c) ? 100f * (1f - PsycheHelper.Comp(c).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Nostalgic)) : 0f)), out planner);
            if (planner != null && PsycheHelper.PsychologyEnabled(__instance.Corpse.InnerPawn) && !PsycheHelper.Comp(__instance.Corpse.InnerPawn).AlreadyBuried)
            {
                Func <int, float> timeAssignmentFactor = delegate(int h)
                {
                    if (planner.timetable.GetAssignment(h) == TimeAssignmentDefOf.Joy)
                    {
                        return(1.25f);
                    }
                    if (planner.timetable.GetAssignment(h) == TimeAssignmentDefOf.Anything)
                    {
                        return(0.9f);
                    }
                    return(0f);
                };
                int hour = -1;
                if (Enumerable.Range(0, GenDate.HoursPerDay).TryRandomElementByWeight(h => timeAssignmentFactor(h), out hour))
                {
                    int date       = Find.TickManager.TicksGame + Mathf.RoundToInt(GenDate.TicksPerDay * (2f + (PsycheHelper.PsychologyEnabled(planner) ? 3f - (5f * PsycheHelper.Comp(planner).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Spontaneous)) : 0f)));
                    int currentDay = GenDate.DayOfYear(GenDate.TickGameToAbs(date), Find.WorldGrid.LongLatOf(planner.Map.Tile).x);
                    if (currentDay <= GenLocalDate.DayOfYear(planner.Map) && GenDate.HourOfDay(GenDate.TickGameToAbs(date), Find.WorldGrid.LongLatOf(planner.Map.Tile).x) > hour)
                    {
                        date += GenDate.TicksPerDay * (currentDay - GenLocalDate.DayOfYear(planner.Map));
                    }
                    Hediff_Funeral planFuneral = HediffMaker.MakeHediff(HediffDefOfPsychology.PlannedFuneral, planner) as Hediff_Funeral;
                    planFuneral.date  = date;
                    planFuneral.hour  = hour;
                    planFuneral.day   = GenDate.DayOfYear(GenDate.TickGameToAbs(date), Find.WorldGrid.LongLatOf(planner.Map.Tile).x);
                    planFuneral.grave = __instance;
                    planFuneral.spot  = __instance.Position;
                    planner.health.AddHediff(planFuneral);
                    PsycheHelper.Comp(__instance.Corpse.InnerPawn).AlreadyBuried = true;
                }
            }
        }
示例#5
0
        private void PlaceProduct()
        {
            if (this.HitPoints <= this.HealthToEmpty)
            {
                for (int i = 0; i < innerContainer.Count; ++i)
                {
                    innerContainer[i].stackCount = innerContainer[i].stackCount / 2 - 1;

                    if (innerContainer[i].stackCount <= 0)
                    {
                        innerContainer.RemoveAt(i);
                        continue;
                    }
                    ++i;
                }

                return;
            }

            if (Rand.Value <= 0.25)
            {
                int damage = Rand.RangeInclusive(0, 4);
                if (Rand.Value < 0.5)
                {
                    damage += Rand.RangeInclusive(0, 6);
                }

                this.TakeDamage(new DamageInfo(DamageDefOf.Blunt, damage, 0f, -1f, null, null, null, DamageInfo.SourceCategory.ThingOrUnknown));
            }

            string eventText = "";

            if (this.HitPoints <= 0)
            {
                this.Destroy(DestroyMode.Vanish);
                eventText = ResourceBank.Strings.TrapDestroyedTest.Translate();
            }
            else if (fishByWeight.Count > 0)
            {
                var fishDefToCatch = fishByWeight.RandomElementByWeight(item => item.Item1).Item2;

                bool roeFish = false;
                if (fishDefToCatch.fishProperties.HasRoe && fishDefToCatch.fishProperties.RoeDef != null && fishDefToCatch.fishProperties.SpawningYearRange != null)
                {
                    int day = GenDate.DayOfYear(Find.TickManager.TicksAbs, Find.WorldGrid.LongLatOf(this.Map.Tile).x);
                    if (fishDefToCatch.fishProperties.SpawningYearRange.min <= day && day <= fishDefToCatch.fishProperties.SpawningYearRange.max)
                    {
                        if (Rand.Value < ModController.Settings.roeChance)
                        {
                            roeFish = true;
                        }
                    }
                }

                Thing trapCatchItem;
                if (roeFish)
                {
                    trapCatchItem = ThingMaker.MakeThing(fishDefToCatch.fishProperties.RoeDef, null);
                }
                else
                {
                    trapCatchItem = ThingMaker.MakeThing(fishDefToCatch, null);
                }

                trapCatchItem.stackCount = 1;

                if (!innerContainer.TryAdd(trapCatchItem))
                {
                    trapCatchItem.Destroy();
                }

                eventText = string.Format(ResourceBank.Strings.TrapCaughtStuffLabel.Translate(), fishDefToCatch.label);
            }

            if (ModController.Settings.SuccessLevel < 1)
            {
            }
            else if (ModController.Settings.SuccessLevel < 2)
            {
                Messages.Message(eventText, new TargetInfo(base.Position, base.Map, false), MessageTypeDefOf.SilentInput);
            }
            else if (ModController.Settings.SuccessLevel < 3)
            {
                Messages.Message(eventText, new TargetInfo(base.Position, base.Map, false), MessageTypeDefOf.PositiveEvent);
            }
            else
            {
                Find.LetterStack.ReceiveLetter(ResourceBank.Strings.FishingSuccessTitle.Translate(), eventText, LetterDefOf.PositiveEvent);
            }
        }
        public static int EstimatedTicksToArrive(int from, int to, WorldPath path, float nextTileCostLeft, int caravanTicksPerMove, int curTicksAbs)
        {
            int num  = 0;
            int num2 = from;
            int num3 = 0;
            int num4 = Mathf.CeilToInt(20000f) - 1;
            int num5 = 60000 - num4;
            int num6 = 0;
            int num7 = 0;
            int num8;

            if (CaravanRestUtility.WouldBeRestingAt(from, (long)curTicksAbs))
            {
                num += CaravanRestUtility.LeftRestTicksAt(from, (long)curTicksAbs);
                num8 = num5;
            }
            else
            {
                num8 = CaravanRestUtility.LeftNonRestTicksAt(from, (long)curTicksAbs);
            }
            while (true)
            {
                num7++;
                if (num7 >= 10000)
                {
                    break;
                }
                if (num6 <= 0)
                {
                    if (num2 == to)
                    {
                        return(num);
                    }
                    bool flag  = num3 == 0;
                    int  start = num2;
                    num2 = path.Peek(num3);
                    num3++;
                    float num9;
                    if (flag)
                    {
                        num9 = nextTileCostLeft;
                    }
                    else
                    {
                        int   num10       = curTicksAbs + num;
                        float yearPercent = (float)GenDate.DayOfYear((long)num10, 0f) / 60f;
                        num9 = (float)Caravan_PathFollower.CostToMove(caravanTicksPerMove, start, num2, yearPercent);
                    }
                    num6 = Mathf.CeilToInt(num9 / 1f);
                }
                if (num8 < num6)
                {
                    num  += num8;
                    num6 -= num8;
                    num  += num4;
                    num8  = num5;
                }
                else
                {
                    num  += num6;
                    num8 -= num6;
                    num6  = 0;
                }
            }
            Log.ErrorOnce("Could not calculate estimated ticks to arrive. Too many iterations.", 1837451324);
            return(num);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Building_FishingSpot fishingSpot = this.job.GetTarget(FishingSpotIndex).Thing as Building_FishingSpot;

            int fishingDuration = (int)(baseFishingDuration * Rand.Range(0.2f, 1.8f) * fishingSpot.MapFishTracker.DifficultyMultiplier / (ModController.Settings.FishingEfficiency));

            Thing thingCaught = null;

            yield return(Toils_Goto.GotoThing(FishingSpotIndex, fishingSpot.InteractionCell)
                         .FailOnDespawnedNullOrForbidden(FishingSpotIndex));

            Toil fishToil = new Toil()
            {
                initAction = () =>
                {
                    if (Find.TickManager.TicksGame > fishingSpot.lastFishingStartTick + 60000 * fishingSpot.FishingFrequency)
                    {
                        fishingSpot.lastFishingStartTick = Find.TickManager.TicksGame;
                    }
                },
                tickAction = () => {
                    this.pawn.skills.Learn(job.def.joySkill, job.def.joyXpPerTick);

                    if (pawn.CurJob.GetTarget(FishingSpotIndex).IsValid)
                    {
                        pawn.rotationTracker.FaceCell(pawn.CurJob.GetTarget(FishingSpotIndex).Cell);
                    }
                },
                handlingFacing      = true,
                defaultDuration     = fishingDuration,
                defaultCompleteMode = ToilCompleteMode.Delay
            };

            yield return(fishToil.FailOnDespawnedNullOrForbidden(FishingSpotIndex));

            Toil catchFishToil = new Toil()
            {
                initAction = () =>
                {
                    string eventText;
                    if (Rand.Value < pawn.GetStatValue(ResourceBank.StatDefOf.FishingChance))
                    {
                        if (fishingSpot.FishStock > 0 && fishingSpot.FishByWeight.Count > 0)
                        {
                            FishDef fishDefToCatch = fishingSpot.FishByWeight.RandomElementByWeight(item => item.Item1).Item2;


                            if (fishDefToCatch.fishProperties.CanBite && Rand.Value < pawn.GetStatValue(ResourceBank.StatDefOf.FishBiteChance))
                            {
                                float damage = Rand.Range(fishDefToCatch.fishProperties.BiteDamageRange.min, fishDefToCatch.fishProperties.BiteDamageRange.max);

                                eventText = string.Format(ResourceBank.Strings.FishingTradegyText.Translate(), this.pawn.Name.ToStringShort.CapitalizeFirst(), fishDefToCatch.label);
                                Find.LetterStack.ReceiveLetter(ResourceBank.Strings.FishingTradegyTitle.Translate(), eventText, LetterDefOf.NegativeEvent, this.pawn);
                                this.pawn.TakeDamage(new DamageInfo(fishDefToCatch.fishProperties.BiteDamageDef, damage, 0f, -1f, this.pawn, null, null, DamageInfo.SourceCategory.ThingOrUnknown, this.pawn));
                                return;
                            }

                            fishingSpot.FishCaught();

                            bool roeFish = false;
                            if (fishDefToCatch.fishProperties.HasRoe && fishDefToCatch.fishProperties.RoeDef != null && fishDefToCatch.fishProperties.SpawningYearRange != null)
                            {
                                int day = GenDate.DayOfYear(Find.TickManager.TicksAbs, Find.WorldGrid.LongLatOf(this.Map.Tile).x);
                                if (fishDefToCatch.fishProperties.SpawningYearRange.min <= day && day <= fishDefToCatch.fishProperties.SpawningYearRange.max)
                                {
                                    if (Rand.Value < ModController.Settings.roeChance)
                                    {
                                        roeFish = true;
                                    }
                                }
                            }

                            if (roeFish)
                            {
                                thingCaught = ThingMaker.MakeThing(fishDefToCatch.fishProperties.RoeDef, null);
                            }
                            else
                            {
                                thingCaught = ThingMaker.MakeThing(fishDefToCatch, null);
                            }

                            thingCaught.stackCount = 1;
                            eventText = ResourceBank.Strings.FishingSuccess.Translate(this.pawn.Name.ToStringShort.CapitalizeFirst(), fishDefToCatch.label);

                            NotifyFishingSuccess(eventText);
                        }
                        else
                        if (Rand.Value < ModController.Settings.junkChance)
                        {
                            //catch non-fish
                            float treasureChance = ModController.Settings.treasureChanceStandart;
                            if (fishingSpot.DeepTerrain)
                            {
                                treasureChance *= treasureDeepAdditionalChance;
                            }

                            ThingSetMakerParams parms = default(ThingSetMakerParams);
                            parms.countRange = new IntRange(1, 1);

                            if (Rand.Value <= treasureChance)
                            {
                                parms.maxTotalMass          = ModController.Settings.MaxTreasureMass;
                                parms.totalMarketValueRange = new FloatRange(100.0f, ModController.Settings.treasureMaxValue);
                                parms.qualityGenerator      = QualityGenerator.Reward;

                                List <Thing> list = ThingSetMakerDefOf.Reward_ItemsStandard.root.Generate(parms);
                                thingCaught = list.RandomElement();

                                eventText = ResourceBank.Strings.FishingCaughtTreasureText.Translate(this.pawn.Name.ToStringShort.CapitalizeFirst(), thingCaught.def.label);
                                NotifyCaughtTreasure(eventText);
                            }
                            else
                            {
                                parms.maxTotalMass     = ModController.Settings.MaxJunkMass;
                                parms.qualityGenerator = QualityGenerator.BaseGen;

                                List <Thing> list = ResourceBank.ThingSetMakerDefOf.Fishing_ItemJunk.root.Generate(parms);
                                thingCaught = list.RandomElement();

                                eventText = ResourceBank.Strings.FishingCaughtJunkText.Translate(this.pawn.Name.ToStringShort.CapitalizeFirst(), thingCaught.def.label);
                                NotifyCaughtJunk(eventText);
                            }
                        }
                    }
                    else
                    {
                        eventText = ResourceBank.Strings.FishingCaughtNothingText.Translate(this.pawn.Name.ToStringShort.CapitalizeFirst());
                        MoteMaker.ThrowMetaIcon(this.pawn.Position, this.Map, ThingDefOf.Mote_IncapIcon);
                        NotifyCaughtNothing(eventText);
                        this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
                        return;
                    }
                }
            };

            yield return(catchFishToil);

            //yield return FinishAndStartHaul(fishingCatch);

            Toil toilFinishAndStartHaul = new Toil();

            toilFinishAndStartHaul.initAction = delegate
            {
                Pawn actor  = toilFinishAndStartHaul.actor;
                Job  curJob = actor.jobs.curJob;
                Bill bill   = curJob.bill;

                Log.Message(bill.recipe.defName);
                Log.Message(thingCaught.def.defName);

                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor)
                {
                    if (!GenPlace.TryPlaceThing(thingCaught, actor.Position, actor.Map, ThingPlaceMode.Near))
                    {
                        Log.Error(actor + " could not drop recipe product " + thingCaught + " near " + actor.Position);
                    }

                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                }
                else
                {
                    IntVec3 foundCell = IntVec3.Invalid;
                    if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile)
                    {
                        StoreUtility.TryFindBestBetterStoreCellFor(thingCaught, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out foundCell);
                    }
                    else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.SpecificStockpile)
                    {
                        if (curJob.bill.GetStoreZone().Accepts(thingCaught))
                        {
                            StoreUtility.TryFindBestBetterStoreCellForIn(thingCaught, actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetStoreZone().slotGroup, out foundCell);
                        }
                        else
                        {
                            if (!GenPlace.TryPlaceThing(thingCaught, actor.Position, actor.Map, ThingPlaceMode.Near))
                            {
                                Log.Error(actor + " could not drop recipe product " + thingCaught + " near " + actor.Position);
                            }
                            actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                        }
                    }
                    else
                    {
                        Log.ErrorOnce("Unknown store mode", 9158246);
                    }

                    if (foundCell.IsValid)
                    {
                        actor.carryTracker.TryStartCarry(thingCaught);
                        curJob.SetTarget(HaulableInd, thingCaught);
                        curJob.SetTarget(StoreCellInd, foundCell);
                        curJob.count = 99999;
                    }
                    else
                    {
                        if (!GenPlace.TryPlaceThing(thingCaught, actor.Position, actor.Map, ThingPlaceMode.Near))
                        {
                            Log.Error("Bill doer could not drop product " + thingCaught + " near " + actor.Position);
                        }
                        actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                    }
                }
            };
            yield return(toilFinishAndStartHaul);

            yield return(Toils_Reserve.Reserve(StoreCellInd));

            Toil carryToCell = Toils_Haul.CarryHauledThingToCell(StoreCellInd);

            yield return(carryToCell);

            yield return(Toils_Haul.PlaceHauledThingInCell(StoreCellInd, carryToCell, storageMode: true, tryStoreInSameStorageIfSpotCantHoldWholeStack: true));

            Toil recount = new Toil();

            recount.initAction = delegate
            {
                Bill_Production bill_Production = recount.actor.jobs.curJob.bill as Bill_Production;
                if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount)
                {
                    Map.resourceCounter.UpdateResourceCounts();
                }
            };
            yield return(recount);
        }
示例#8
0
        private IEnumerable <Building> GetWastingFuelGenerators()
        {
            prevAlertThings.Clear();
            prevAlertThings.Concat(alertThings);
            alertThings.Clear();
            prevBatteryLow.Clear();
            prevBatteryLow.Concat(batteryLow);
            batteryLow.Clear();
            Map     map       = Find.Maps.FirstOrDefault(m => m.IsPlayerHome);
            Vector2 longLat   = Find.WorldGrid.LongLatOf(map.Tile);
            int     gameTicks = Find.TickManager.TicksGame;
            int     absTicks  = Find.TickManager.TicksAbs;
            int     dayOfYear = GenDate.DayOfYear((long)absTicks, longLat.x);

            if (dayOfYear != CurrentDayOfYear)
            {
                CurrentAverageGlow = GenCelestial.AverageGlow(longLat.y, dayOfYear);
                CurrentDayOfYear   = dayOfYear;
            }
            float glow = CurrentAverageGlow;

            if (map.gameConditionManager.ConditionIsActive(GameConditionDefOf.Eclipse))
            {
                glow = 0.0f;
            }
            if (map.gameConditionManager.ConditionIsActive(GameConditionDefOf.VolcanicWinter))
            {
                glow *= 0.5f;
            }
            float averageWind = 0.55f;

            foreach (PowerNet powerNet in map.powerNetManager.AllNetsListForReading.Where(pn =>
                                                                                          (pn.batteryComps.Count() > 0 || pn.powerComps.Any(pc => pc != null && pc.PowerOn && pc.Props.basePowerConsumption > 0.0f)) &&
                                                                                          pn.powerComps.Any(pc => pc != null && pc.PowerOn && pc.parent.GetComp <CompRefuelable>() != null)))
            {
                if (powerNet.batteryComps.Count() > 0)
                {
                    float batteryPercent = powerNet.batteryComps.Sum(bc => bc.StoredEnergy) / powerNet.batteryComps.Sum(bc => bc.Props.storedEnergyMax);
                    if (prevBatteryLow.Contains(powerNet))
                    {
                        if (batteryPercent < batteryLowToHighThreshold)
                        {
                            batteryLow.Add(powerNet);
                            continue;
                        }
                    }
                    else
                    {
                        if (batteryPercent < batteryHighToLowThreshold)
                        {
                            batteryLow.Add(powerNet);
                            continue;
                        }
                    }
                }

                float deltaPower = powerNet.powerComps.OfType <CompPowerPlantSolar>().Where(pc => pc.PowerOn).Sum(pc => glow * 1700 - pc.PowerOutput) +
                                   powerNet.powerComps.OfType <CompPowerPlantWind>().Sum(pc => averageWind * -pc.Props.basePowerConsumption - pc.PowerOutput) -
                                   powerNet.powerComps.Select(pc => pc.parent.GetComp <CompSchedule>()).Where(cs => cs != null).Sum(cs => GetScheduledPowerDelta(cs));

                float excess = powerNet.CurrentEnergyGainRate() / CompPower.WattsToWattDaysPerTick + deltaPower;
                if (excess > 0)
                {
                    foreach (CompPowerTrader cpt in powerNet.powerComps.Where(pc => pc != null && pc.PowerOn))
                    {
                        CompRefuelable cr = cpt.parent.GetComp <CompRefuelable>();
                        if (cpt.Props.basePowerConsumption < 0.0f && cr != null)
                        {
                            if (prevAlertThings.Contains(cpt.parent as Building))
                            {
                                if (excess < -cpt.Props.basePowerConsumption * powerCompAlertOnToOffThreshold)
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                if (excess < -cpt.Props.basePowerConsumption * powerCompAlertOffToOnThreshold)
                                {
                                    continue;
                                }
                            }

                            alertThings.Add(cpt.parent as Building);
                        }
                    }
                }
            }

            return(alertThings);
        }