/// <summary>
 /// Increment TimesTraded count of dictionary by one for this faction.
 /// </summary>
 private static void IncidentFired_TradeCounter_Postfix(ref FiringIncident fi)
 {
     if (fi.parms.target is Map map && fi.def == IncidentDefOf.TraderCaravanArrival && fi.parms.faction != null)
     {
         map.GetComponent <MapComponent_GoodWillTrader>().TimesTraded[key : fi.parms.faction]++;
     }
 }
예제 #2
0
        public override IEnumerable <FiringIncident> MakeIntervalIncidents(IIncidentTarget target)
        {
            if (VoteHandler.voteActive)
            {
                yield break;
            }
            float acceptFraction = 1f;

            if (this.Props.acceptFractionByDaysPassedCurve != null)
            {
                acceptFraction *= this.Props.acceptFractionByDaysPassedCurve.Evaluate(GenDate.DaysPassedFloat);
            }
            if (this.Props.acceptPercentFactorPerThreatPointsCurve != null)
            {
                acceptFraction *= this.Props.acceptPercentFactorPerThreatPointsCurve.Evaluate(StorytellerUtility.DefaultThreatPointsNow(target));
            }
            int incCount = IncidentCycleUtility.IncidentCountThisInterval(target, Find.Storyteller.storytellerComps.IndexOf(this), this.Props.minDaysPassed, this.Props.onDays, this.Props.offDays, this.Props.minSpacingDays, this.Props.numIncidentsRange.min, this.Props.numIncidentsRange.max, acceptFraction);

            for (int i = 0; i < incCount; i++)
            {
                Helper.Log("Trying to gen OFC Inc");
                FiringIncident fi = this.GenerateIncident(target);
                if (fi != null)
                {
                    yield return(fi);
                }
            }
            yield break;
        }
예제 #3
0
        public void SendRaid()
        {
            raidTimer = ticksBetweenRaids;

            if (camp.PlayerSiegeMap == null)
            {
                return;
            }

            if (!TryFindSpawnSpot(camp.PlayerSiegeMap, out IntVec3 spawnSpot))
            {
                return;
            }

            float points = totalThreat * 0.5f;

            if (totalThreat <= 0)
            {
                points = totalThreat;
            }

            IncidentParms raidParms = StorytellerUtility.DefaultParmsNow(IncidentCategoryDefOf.ThreatBig, camp.PlayerSiegeMap);

            raidParms.forced             = true;
            raidParms.faction            = camp.Faction;
            raidParms.raidStrategy       = RaidStrategyDefOf.ImmediateAttack;
            raidParms.raidArrivalMode    = PawnsArrivalModeDefOf.EdgeWalkIn;
            raidParms.spawnCenter        = spawnSpot;
            raidParms.points             = points;
            raidParms.pawnGroupMakerSeed = Rand.Int;
            var incident = new FiringIncident(IncidentDefOf.RaidEnemy, null, raidParms);

            Find.Storyteller.TryFire(incident);
        }
        public override IEnumerable <FiringIncident> MakeIntervalIncidents(IIncidentTarget target)
        {
            float curCycleDays = (GenDate.DaysPassedFloat - this.Props.minDaysPassed) % this.Props.ThreatCycleTotalDays;

            if (curCycleDays > this.Props.threatOffDays)
            {
                float daysSinceThreatBig = (float)(Find.TickManager.TicksGame - target.StoryState.LastThreatBigTick) / 60000f;
                if (daysSinceThreatBig > this.Props.minDaysBetweenThreatBigs && ((daysSinceThreatBig > this.Props.ThreatCycleTotalDays * 0.9f && curCycleDays > this.Props.ThreatCycleTotalDays * 0.95f) || Rand.MTBEventOccurs(this.Props.mtbDaysThreatBig, 60000f, 1000f)))
                {
                    FiringIncident st = this.GenerateQueuedThreatBig(target);
                    if (st != null)
                    {
                        yield return(st);
                    }
                }

                if (Rand.MTBEventOccurs(this.Props.mtbDaysThreatSmall, 60000f, 1000f))
                {
                    FiringIncident st = this.GenerateQueuedThreatSmall(target);
                    if (st != null)
                    {
                        yield return(st);
                    }
                }
            }
        }
        public void QueueIncident(FiringIncident incident, float afterDays)
        {
            var qi = new QueuedIncident(incident, (int)(Find.TickManager.TicksGame + GenDate.TicksPerDay * afterDays));

            incidentQueue.Add(qi);
            //Log.Message("Queued Hospitality incident after " + afterDays + " days. Queue has now " + incidentQueue.Count + " items.");
        }
예제 #6
0
        private void NextWave()
        {
            Map map = Bomb.Map;

            if (!TryFindSpawnSpot(map, out IntVec3 spawnSpot))
            {
                return;
            }

            if (!TryFindEnemyFaction(out Faction enemyFac))
            {
                return;
            }

            int           @int      = Rand.Int;
            IncidentParms raidParms = StorytellerUtility.DefaultParmsNow(IncidentCategoryDefOf.ThreatBig, map);

            raidParms.forced             = true;
            raidParms.faction            = enemyFac;
            raidParms.raidStrategy       = RaidStrategyDefOf.ImmediateAttack;
            raidParms.raidArrivalMode    = PawnsArrivalModeDefOf.EdgeWalkIn;
            raidParms.spawnCenter        = spawnSpot;
            raidParms.points             = threatsMap[currentWave];
            raidParms.pawnGroupMakerSeed = @int;
            var incident = new FiringIncident(IncidentDefOf.RaidEnemy, null, raidParms);

            Find.Storyteller.TryFire(incident);

            currentWave++;
        }
예제 #7
0
        public static void ResetInterval(Map map)
        {
            FiringIncident fi = new FiringIncident();

            fi = new FiringIncident(IncidentDef.Named("ZTrib_TribbleArrival"), null, null);
            map.StoryState.Notify_IncidentFired(fi);
        }
        public override IEnumerable <FiringIncident> MakeIntervalIncidents(IIncidentTarget target)
        {
            if (VoteHandler.currentVote is Vote_Milasandra)
            {
                yield break;
            }

            if (GenDate.DaysPassed <= Props.minDaysPassed)
            {
                yield break;
            }

            float acceptFraction = 1f;

            if (this.Props.acceptFractionByDaysPassedCurve != null)
            {
                acceptFraction *= this.Props.acceptFractionByDaysPassedCurve.Evaluate(GenDate.DaysPassedFloat);
            }
            if (this.Props.acceptPercentFactorPerThreatPointsCurve != null)
            {
                acceptFraction *= this.Props.acceptPercentFactorPerThreatPointsCurve.Evaluate(StorytellerUtility.DefaultThreatPointsNow(target));
            }
            int rand = Rand.Range(1, 25);
            //Helper.Log($"{rand} {this.Props.minDaysPassed} {this.Props.onDays} {this.Props.offDays} {this.Props.minSpacingDays}");
            int incCount = IncidentCycleUtility.IncidentCountThisInterval(target, rand, this.Props.minDaysPassed, this.Props.onDays, this.Props.offDays, this.Props.minSpacingDays, this.Props.numIncidentsRange.min, this.Props.numIncidentsRange.max, acceptFraction);

            for (int i = 0; i < incCount; i++)
            {
                FiringIncident fi = this.GenerateIncident(target);
            }
            // will never return an incident because it has to be voted on

            yield break;
        }
예제 #9
0
        public override void PostMapGenerate(Map map)
        {
            foreach (var data in MapDefOfLocal.Camp.MapData)
            {
                if (data.key.Kind != null)
                {
                    data.key.Kind = Faction.RandomPawnKind();
                }
            }

            MapGeneratorHandler.GenerateMap(MapDefOfLocal.Camp, map, out savedPawns, fog: false, unFogRoom: true, spawnPawns: true, createRoof: true, forceFaction: Faction.OfPlayer);

            if (TryGetEnemyFaction(Faction, out Faction enemyFac))
            {
                int           @int      = Rand.Int;
                IncidentParms raidParms = StorytellerUtility.DefaultParmsNow(IncidentCategoryDefOf.ThreatBig, map);
                raidParms.forced             = true;
                raidParms.faction            = enemyFac;
                raidParms.raidStrategy       = RaidStrategyDefOf.ImmediateAttack;
                raidParms.raidArrivalMode    = PawnsArrivalModeDefOf.EdgeWalkIn;
                raidParms.points             = Rand.Range(400, 1000);
                raidParms.pawnGroupMakerSeed = @int;
                var incident = new FiringIncident(IncidentDefOf.RaidEnemy, null, raidParms);
                Find.Storyteller.TryFire(incident);
            }
        }
예제 #10
0
 public static bool Prefix(FiringIncident fi)
 {
     if (fi.def == null)
     {
         return(false);
     }
     return(true);
 }
예제 #11
0
 public bool TryFire(FiringIncident fi)
 {
     if (fi.def.Worker.CanFireNow(fi.parms) && fi.def.Worker.TryExecute(fi.parms))
     {
         fi.parms.target.StoryState.Notify_IncidentFired(fi);
         return(true);
     }
     return(false);
 }
        public override void RemoveNow()
        {
            IncidentParms parms = StorytellerUtility.DefaultParmsNow(IncidentCategoryDefOf.ThreatBig, Find.World);

            parms.forced = true;

            var incident = new FiringIncident(MoreEvents.IncidentDefOfLocal.HighMutantPopulation, null, parms);

            Find.Storyteller.TryFire(incident);

            base.RemoveNow();
        }
예제 #13
0
        public override void EndQuest(Caravan caravan = null, EndCondition condition = EndCondition.None)
        {
            if (condition == EndCondition.Timeout)
            {
                IncidentParms parms = StorytellerUtility.DefaultParmsNow(IncidentCategoryDefOf.ThreatBig, Find.World);
                parms.forced = true;

                var incident = new FiringIncident(MoreEvents.IncidentDefOfLocal.HighMutantPopulation, null, parms);
                Find.Storyteller.TryFire(incident);
            }

            base.EndQuest(caravan, condition);
        }
        public void ThreadProc()
        {
            var result = MakeIntervalIncidentsThread();

            if (result == typeof(FiringIncident))
            {
                singleIncident = result as FiringIncident;
            }
            else if (incidentOptions != null)
            {
                makeIncidentOptions = true;
            }
        }
예제 #15
0
        public static void PlanNewVisit(IIncidentTarget map, float afterDays, Faction faction = null)
        {
            IncidentParms incidentParms = StorytellerUtility.DefaultParmsNow(Find.Storyteller.def, IncidentCategory.AllyArrival, map);

            if (faction != null)
            {
                incidentParms.faction = faction;
            }
            var            incident = new FiringIncident(IncidentDefOf.VisitorGroup, null, incidentParms);
            QueuedIncident qi       = new QueuedIncident(incident, (int)(Find.TickManager.TicksGame + GenDate.TicksPerDay * afterDays));

            Find.Storyteller.incidentQueue.Add(qi);
        }
예제 #16
0
        private void SendRaid()
        {
            int           @int      = Rand.Int;
            IncidentParms raidParms = StorytellerUtility.DefaultParmsNow(IncidentCategoryDefOf.ThreatBig, Map);

            raidParms.forced          = true;
            raidParms.faction         = Faction;
            raidParms.raidStrategy    = RaidStrategyDefOf.ImmediateAttack;
            raidParms.raidArrivalMode = PawnsArrivalModeDefOf.EdgeWalkIn;
            CellFinder.TryFindRandomEdgeCellWith(x => !x.Fogged(Map) && x.Standable(Map) && x.Walkable(Map), Map, 0f, out raidParms.spawnCenter);
            raidParms.points             = Rand.Range(500, 1000);
            raidParms.pawnGroupMakerSeed = @int;
            var incident = new FiringIncident(IncidentDefOf.RaidEnemy, null, raidParms);

            Find.Storyteller.TryFire(incident);
        }
예제 #17
0
        private static void ProcessNextIncident()
        {
            if (Ticker.FiringIncidents.Count <= 0)
            {
                return;
            }

            FiringIncident incident = Ticker.FiringIncidents.Dequeue();

            try
            {
                incident.def.Worker.TryExecute(incident.parms);
            }
            catch (Exception e)
            {
                TkUtils.Logger.Error($@"The incident ""{incident.def.defName}"" raised an exception", e);
            }
        }
예제 #18
0
        public static void PlanNewVisit(IIncidentTarget map, float afterDays, Faction faction = null)
        {
            if (!(map is Map realMap))
            {
                return;
            }

            var incidentParms = StorytellerUtility.DefaultParmsNow(IncidentCategoryDefOf.FactionArrival, realMap);

            if (faction == null)
            {
                return;
            }

            incidentParms.faction = faction;
            var incident = new FiringIncident(IncidentDefOf.VisitorGroup, null, incidentParms);

            GetMapComponent(realMap).QueueIncident(incident, afterDays);
        }
예제 #19
0
        public static void PlanNewVisit(IIncidentTarget map, float afterDays, Faction faction = null)
        {
            var realMap = map as Map;

            if (realMap == null)
            {
                return;
            }

            IncidentParms incidentParms = StorytellerUtility.DefaultParmsNow(Find.Storyteller.def, IncidentCategory.AllyArrival, realMap);

            if (faction != null)
            {
                incidentParms.faction = faction;
            }
            var incident = new FiringIncident(IncidentDefOf.VisitorGroup, null, incidentParms);

            Hospitality_MapComponent.Instance(realMap).QueueIncident(incident, afterDays);
        }
예제 #20
0
        public static bool TryGiveQuestTo(Pawn pawn, QuestDef questDef)
        {
            Quest quest = (Quest)Activator.CreateInstance(questDef.Quest);

            if (quest.TryGiveQuestTo(pawn, questDef))
            {
                FiringIncident inc = new FiringIncident
                {
                    def   = questDef.Incident,
                    parms = new IncidentParms()
                    {
                        forced = false,
                        target = Find.World
                    }
                };
                Find.World.StoryState.Notify_IncidentFired(inc);

                return(true);
            }

            return(false);
        }
        private void SendRaid()
        {
            if (!Site.HasMap)
            {
                return;
            }

            Map map = Site.Map;

            int           @int      = Rand.Int;
            IncidentParms raidParms = StorytellerUtility.DefaultParmsNow(IncidentCategoryDefOf.ThreatBig, map);

            raidParms.forced             = true;
            raidParms.faction            = Faction;
            raidParms.raidStrategy       = RaidStrategyDefOf.ImmediateAttack;
            raidParms.raidArrivalMode    = PawnsArrivalModeDefOf.EdgeWalkIn;
            raidParms.points             = Rand.Range(200, 450);
            raidParms.pawnGroupMakerSeed = @int;
            var incident = new FiringIncident(IncidentDefOf.RaidEnemy, null, raidParms);

            Find.Storyteller.TryFire(incident);
        }
예제 #22
0
        //StoryState
        public static void Postfix(StoryState __instance, FiringIncident fi, IIncidentTarget ___target, ref int ___lastThreatBigTick)
        {
            if (fi.parms.forced || fi.parms.target != ___target)
            {
                return;
            }

            if (fi.parms.target is Map map)
            {
                bool ally = fi.def.category == IncidentCategoryDefOf.FactionArrival;
                bool raid = fi.def.category == IncidentCategoryDefOf.ThreatBig;
                if (ally || raid)
                {
                    float delayDays = ally ? DelayDays.DelayAllyDays(map) : DelayDays.DelayRaidDays(map);

                    string eventDesc = ally ? "visitors" : "threats";

                    if (delayDays > 0)
                    {
                        __instance.lastFireTicks[fi.def] += (int)(delayDays * GenDate.TicksPerDay);

                        if (Mod.settings.logResults)
                        {
                            string date = GenDate.QuadrumDateStringAt(GenTicks.TicksGame, 0);
                            Verse.Log.Message($"On {date}, Safely Hidden Away delayed {eventDesc} to {map.info.parent.LabelShortCap} by {delayDays:0.0} days.");
                        }

                        if (raid)
                        {
                            int last = ___lastThreatBigTick + ((int)(delayDays * GenDate.TicksPerDay));

                            ___lastThreatBigTick = last;
                        }
                    }
                }
            }
        }
예제 #23
0
 public override void Tick(int currentTick)
 {
     //Performance reporting tick
     if (EnablePerformanceTesting() && currentTick % GenDate.TicksPerDay == 0 && PerformanceSetup.performanceTotals.Keys.Count > 0)
     {
         Dictionary <string, float> averages = PerformanceSetup.performanceTotals.ToDictionary(x => x.Key, x => (float)x.Value / (float)PerformanceSetup.performanceCalls[x.Key]);
         int topAmt = Math.Min(10, averages.Count);
         List <KeyValuePair <string, float> > avgTicks = (from avg in averages orderby avg.Value descending select avg).Take(topAmt).ToList();
         List <KeyValuePair <string, float> > topTicks = (from avg in averages orderby avg.Value * PerformanceSetup.performanceCalls[avg.Key] descending select avg).Take(topAmt).ToList();
         StringBuilder avgString = new StringBuilder();
         foreach (KeyValuePair <string, float> t in avgTicks)
         {
             avgString.AppendLine(t.Key + " (" + t.Value + ")");
         }
         StringBuilder topString = new StringBuilder();
         foreach (KeyValuePair <string, float> t in topTicks)
         {
             topString.AppendLine(t.Key + " (" + avgTicks.Find(x => x.Key == t.Key).Value + ")");
         }
         Log.Message("Psychology :: Performance Report :: Top " + topAmt + " average tick consumers:\n" + avgString.ToString() + "\nTop " + topAmt + " weighted tick consumers: " + topString.ToString());
     }
     //Constituent tick
     if (currentTick % GenDate.TicksPerHour * 2 == 0)
     {
         Map playerFactionMap            = Find.WorldObjects.SettlementBases.Find(b => b.Faction.IsPlayer).Map;
         IEnumerable <Pawn> constituents = (from p in playerFactionMap.mapPawns.FreeColonistsSpawned
                                            where !p.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) && p.GetLord() == null && p.GetTimeAssignment() != TimeAssignmentDefOf.Work && p.Awake()
                                            select p);
         if (constituents.Count() > 0)
         {
             Pawn potentialConstituent       = constituents.RandomElementByWeight(p => 0.0001f + Mathf.Pow(Mathf.Abs(0.7f - p.needs.mood.CurLevel), 2));
             IEnumerable <Pawn> activeMayors = (from m in playerFactionMap.mapPawns.FreeColonistsSpawned
                                                where !m.Dead && m.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) && ((Hediff_Mayor)m.health.hediffSet.GetFirstHediffOfDef(HediffDefOfPsychology.Mayor)).worldTileElectedOn == potentialConstituent.Map.Tile &&
                                                m.GetTimeAssignment() != TimeAssignmentDefOf.Work && m.GetTimeAssignment() != TimeAssignmentDefOf.Sleep && m.GetLord() == null && m.Awake() && m.GetLord() == null
                                                select m);
             if (potentialConstituent != null && !potentialConstituent.Downed && !potentialConstituent.Drafted && potentialConstituent.health.summaryHealth.SummaryHealthPercent >= 1f && potentialConstituent.GetTimeAssignment() != TimeAssignmentDefOf.Work && activeMayors.Count() > 0)
             {
                 Pawn    mayor  = activeMayors.RandomElement(); //There should only be one.
                 IntVec3 gather = default(IntVec3);
                 String  found  = null;
                 if (mayor.Map.GetComponent <OfficeTableMapComponent>().officeTable != null)
                 {
                     gather = mayor.Map.GetComponent <OfficeTableMapComponent>().officeTable.parent.Position;
                     found  = "office";
                 }
                 else if (mayor.ownership != null && mayor.ownership.OwnedBed != null)
                 {
                     gather = mayor.ownership.OwnedBed.Position;
                     found  = "bed";
                 }
                 if (PsycheHelper.PsychologyEnabled(potentialConstituent) && Rand.Chance((1f - PsycheHelper.Comp(potentialConstituent).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Independent)) / 5f) && (found != null || RCellFinder.TryFindPartySpot(mayor, out gather)) &&
                     (!mayor.Drafted && !mayor.Downed && mayor.health.summaryHealth.SummaryHealthPercent >= 1f && mayor.GetTimeAssignment() != TimeAssignmentDefOf.Work && (mayor.CurJob == null || mayor.CurJob.def != JobDefOf.TendPatient)))
                 {
                     List <Pawn> pawns = new List <Pawn>();
                     pawns.Add(mayor);
                     pawns.Add(potentialConstituent);
                     Lord meeting = LordMaker.MakeNewLord(mayor.Faction, new LordJob_VisitMayor(gather, potentialConstituent, mayor, (potentialConstituent.needs.mood.CurLevel < (potentialConstituent.mindState.mentalBreaker.BreakThresholdMinor * 1.25f))), mayor.Map, pawns);
                     mayor.jobs.EndCurrentJob(Verse.AI.JobCondition.InterruptForced);
                     potentialConstituent.jobs.EndCurrentJob(Verse.AI.JobCondition.InterruptForced);
                     if (found == "bed")
                     {
                         mayor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfPsychology.MayorNoOffice);
                     }
                     else if (found == null)
                     {
                         mayor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfPsychology.MayorNoBedroom);
                     }
                 }
             }
         }
     }
     //Election tick
     if (currentTick % (GenDate.TicksPerDay / 4f) == 0)
     {
         foreach (Settlement settlement in Find.WorldObjects.Settlements)
         {
             //Self-explanatory.
             if (!PsychologyBase.ActivateElections())
             {
                 continue;
             }
             //If the base isn't owned or named by the player, no election can be held.
             if (!settlement.Faction.IsPlayer || !settlement.namedByPlayer)
             {
                 continue;
             }
             //If the base is not at least a year old, no election will be held.
             if ((Find.TickManager.TicksGame - settlement.creationGameTicks) / GenDate.TicksPerYear < 1)
             {
                 continue;
             }
             //A base must have at least 7 people in it to hold an election.
             if (settlement.Map.mapPawns.FreeColonistsSpawnedCount < 7)
             {
                 continue;
             }
             //If an election is already being held, don't start a new one.
             if (settlement.Map.gameConditionManager.ConditionIsActive(GameConditionDefOfPsychology.Election) || settlement.Map.lordManager.lords.Find(l => l.LordJob is LordJob_Joinable_Election) != null)
             {
                 continue;
             }
             //Elections are held in Septober (because I guess some maps don't have fall?) and during the day.
             if (GenDate.Quadrum(Find.TickManager.TicksAbs, Find.WorldGrid.LongLatOf(settlement.Tile).x) != Quadrum.Septober || (GenLocalDate.HourOfDay(settlement.Map) < 7 || GenLocalDate.HourOfDay(settlement.Map) > 20))
             {
                 continue;
             }
             //If an election has already been completed this year, don't start a new one.
             IEnumerable <Pawn> activeMayors = (from m in settlement.Map.mapPawns.FreeColonistsSpawned
                                                where !m.Dead && m.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) && ((Hediff_Mayor)m.health.hediffSet.GetFirstHediffOfDef(HediffDefOfPsychology.Mayor)).worldTileElectedOn == settlement.Map.Tile && ((Hediff_Mayor)m.health.hediffSet.GetFirstHediffOfDef(HediffDefOfPsychology.Mayor)).yearElected == GenLocalDate.Year(settlement.Map.Tile)
                                                select m);
             if (activeMayors.Count() > 0)
             {
                 continue;
             }
             //Try to space out the elections so they don't all proc at once.
             if (Rand.RangeInclusive(1, 15 - GenLocalDate.DayOfQuadrum(settlement.Map.Tile)) > 1)
             {
                 continue;
             }
             IncidentParms parms = new IncidentParms();
             parms.target  = settlement.Map;
             parms.faction = settlement.Faction;
             FiringIncident fi = new FiringIncident(IncidentDefOfPsychology.Election, null, parms);
             Find.Storyteller.TryFire(fi);
         }
     }
 }
예제 #24
0
 public static void Postfix(FiringIncident fi, bool __result)
 {
     StoryHandler.Notify_IncidentFired(fi.def);
 }
예제 #25
0
        void _timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                Helper.Log("Timer Elapsed");
                _timerElapsed = DateTime.Now;

                if (_paused || _client == null || !Helper.ModActive)
                {
                    return;
                }

                if (_eventsPossible == null)
                {
                    if (Current.Game.tickManager.Paused)
                    {
                        _paused = true;
                        return;
                    }

                    if (_extraWait > 0)
                    {
                        return;
                    }
                }

                Helper.Log("Checking Voting Stage");


                _extraWait = 0;

                if (_votingStage == 0)
                {
                    if (_eventsPossible.Count() <= 0)
                    {
                        return;
                    }
                    _voteActive = true;
                    _voteAnswers.Clear();

                    List <IncidentDef> eventTest = _eventsPossible.ToList();
                    Helper.Log("Playing event lottery, total events " + eventTest.Count());

                    int eventsTotal  = eventTest.Count();
                    int eventsNeeded = Settings.VoteOptions;
                    if (eventsTotal < eventsNeeded)
                    {
                        eventsNeeded = eventsTotal;
                    }
                    _eventsPossibleChosen = new IncidentDef[eventsNeeded];
                    System.Random rnd = new System.Random();
                    for (int i = 0; i < eventTest.Count(); i++)
                    {
                        if (eventsNeeded == 0)
                        {
                            break;
                        }

                        int    win  = rnd.Next(1, 101);
                        double perc = ((double)eventsNeeded / eventsTotal) * 100;
                        if (win <= perc)
                        {
                            _eventsPossibleChosen[eventsNeeded - 1] = eventTest[i];
                            eventsNeeded--;
                        }
                        eventsTotal--;
                    }
                    Helper.Log("Chose events to vote with " + _eventsPossibleChosen.Count());

                    if (!Find.WindowStack.TryRemove(typeof(VoteDuelWindow), true) && _eventsPossibleChosen.Count() == 200)
                    {
                        Find.WindowStack.Add(new VoteDuelWindow(_eventsPossibleChosen, this));
                    }
                    else if (!Find.WindowStack.TryRemove(typeof(VoteWindow), true))
                    {
                        Find.WindowStack.Add(new VoteWindow(_eventsPossibleChosen, this));
                    }

                    //_client.SendMessage("TwitchStoriesChatMessageNewVote".Translate() + ": " + "TwitchToolKitVoteInstructions".Translate());
                    //for (int i = 0; i < _eventsPossibleChosen.Count(); i++)
                    //{
                    //    Helper.Log("Event " + _eventsPossibleChosen.ToString());
                    //    string msg = "[" + (i + 1) + "] ";
                    //    msg += (_eventsPossibleChosen[i].LabelCap);
                    //    _client.SendMessage(msg);
                    //}

                    _votingStage = 1;
                }
                else if (_votingStage == 1)
                {
                    Helper.Log("Starting Votes Count");
                    if (_eventsPossibleChosen.Length <= 0)
                    {
                        return;
                    }
                    Helper.Log("Counting Votes");
                    int[] votekeys = new int[_eventsPossibleChosen.Count()];
                    foreach (KeyValuePair <string, int> vote in _voteAnswers)
                    {
                        if (_eventsPossibleChosen.Length < vote.Value)
                        {
                            continue;
                        }
                        Helper.Log($"Trying to register vote for {votekeys[vote.Value - 1]}");
                        votekeys[vote.Value - 1] += 1;
                        Helper.Log($"New Count {votekeys[vote.Value - 1]}");
                    }
                    int evt       = 0;
                    int voteCount = 0;
                    for (int i = 0; i < votekeys.Count(); i++)
                    {
                        Helper.Log($"{votekeys[i]}:{_eventsPossibleChosen[i]} vs {votekeys[evt]}:{_eventsPossibleChosen[evt]}");
                        if (votekeys[i] > votekeys[evt])
                        {
                            evt = i;
                        }
                        else if (votekeys[i] == votekeys[evt] && _rand.Next(0, 2) == 1)
                        {
                            Helper.Log("Tied, picking random winner");
                            evt = i;
                        }
                        voteCount += votekeys[i];
                    }

                    double wonPercentage = ((double)evt / (double)(voteCount == 0 ? 1 : voteCount));

                    string msg = "TwitchStoriesChatMessageVoteEnd".Translate() + " ";

                    msg += $"{_eventsPossibleChosen[evt].LabelCap}";


                    _client.SendMessage(msg);

                    FiringIncident chosen = new FiringIncident(_eventsPossibleChosen[evt], _currentVote.storytellerComp_CustomStoryTeller, _currentVote.parms);
                    Ticker.FiringIncidents.Enqueue(chosen);

                    Helper.Log("Vote: " + _eventsPossibleChosen[evt].LabelCap + " won");
                    Find.WindowStack.TryRemove(typeof(VoteDuelWindow), true);
                    Find.WindowStack.TryRemove(typeof(VoteWindow), true);

                    _voteActive           = false;
                    _voteEvents           = null;
                    _eventsPossibleChosen = null;
                    _eventsPossible       = null;
                    _votingStage          = 2;
                }
            }
            catch (Exception exception)
            {
                Helper.Log("Exception: " + exception.Message + " " + exception.StackTrace);
            }
            finally
            {
                Helper.Log("Starting Timer Back up");
                StartTimer();
            }
        }
예제 #26
0
 public override void Tick(int currentTick)
 {
     //Constituent tick
     if (currentTick % GenDate.TicksPerHour * 2 == 0)
     {
         Map playerFactionMap            = Find.WorldObjects.FactionBases.Find(b => b.Faction.IsPlayer).Map;
         IEnumerable <Pawn> constituents = (from p in playerFactionMap.mapPawns.FreeColonistsSpawned
                                            where !p.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) && p.GetTimeAssignment() != TimeAssignmentDefOf.Work && p.Awake()
                                            select p);
         if (constituents.Count() > 0)
         {
             Pawn potentialConstituent       = constituents.RandomElementByWeight(p => 0.0001f + Mathf.Pow(Mathf.Abs(0.7f - p.needs.mood.CurLevel), 2));
             IEnumerable <Pawn> activeMayors = (from m in playerFactionMap.mapPawns.FreeColonistsSpawned
                                                where !m.Dead && m.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) && ((Hediff_Mayor)m.health.hediffSet.GetFirstHediffOfDef(HediffDefOfPsychology.Mayor)).worldTileElectedOn == potentialConstituent.Map.Tile &&
                                                m.GetTimeAssignment() != TimeAssignmentDefOf.Work && m.GetTimeAssignment() != TimeAssignmentDefOf.Sleep && m.GetLord() == null && m.Awake()
                                                select m);
             if (potentialConstituent != null && activeMayors.Count() > 0)
             {
                 Pawn           mayor = activeMayors.RandomElement(); //There should only be one.
                 PsychologyPawn psychologyConstituent = potentialConstituent as PsychologyPawn;
                 IntVec3        gather   = default(IntVec3);
                 bool           foundBed = false;
                 if (mayor.ownership != null && mayor.ownership.OwnedBed != null)
                 {
                     gather   = mayor.ownership.OwnedBed.Position;
                     foundBed = true;
                 }
                 if ((psychologyConstituent == null || Rand.Value < (1f - psychologyConstituent.psyche.GetPersonalityRating(PersonalityNodeDefOf.Independent)) / 5f) && (foundBed || RCellFinder.TryFindPartySpot(mayor, out gather)))
                 {
                     List <Pawn> pawns = new List <Pawn>();
                     pawns.Add(mayor);
                     pawns.Add(potentialConstituent);
                     Lord meeting = LordMaker.MakeNewLord(mayor.Faction, new LordJob_VisitMayor(gather, potentialConstituent, mayor, (potentialConstituent.needs.mood.CurLevel < 0.4f)), mayor.Map, pawns);
                     if (!foundBed)
                     {
                         mayor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfPsychology.MayorNoBedroom);
                     }
                 }
             }
         }
     }
     //Election tick
     if (currentTick % (GenDate.TicksPerDay / 4f) == 0)
     {
         foreach (FactionBase factionBase in Find.WorldObjects.FactionBases)
         {
             //If the base isn't owned or named by the player, no election can be held.
             if (!factionBase.Faction.IsPlayer || !factionBase.namedByPlayer)
             {
                 continue;
             }
             //Self-explanatory.
             if (!PsychologyBase.ActivateElections())
             {
                 continue;
             }
             //If the base is not at least a year old, no election will be held.
             if ((Find.TickManager.TicksGame - factionBase.creationGameTicks) / GenDate.TicksPerYear < 1)
             {
                 continue;
             }
             //A base must have at least 7 people in it to hold an election.
             if (factionBase.Map.mapPawns.FreeColonistsSpawnedCount < 7)
             {
                 continue;
             }
             //If an election is already being held, don't start a new one.
             if (factionBase.Map.gameConditionManager.ConditionIsActive(GameConditionDefOfPsychology.Election) || factionBase.Map.lordManager.lords.Find(l => l.LordJob is LordJob_Joinable_Election) != null)
             {
                 continue;
             }
             //Elections are held in the fall and during the day.
             if (GenLocalDate.Season(factionBase.Map) != Season.Fall || (GenLocalDate.HourOfDay(factionBase.Map) < 7 || GenLocalDate.HourOfDay(factionBase.Map) > 20))
             {
                 continue;
             }
             //If an election has already been completed this year, don't start a new one.
             IEnumerable <Pawn> activeMayors = (from m in factionBase.Map.mapPawns.FreeColonistsSpawned
                                                where !m.Dead && m.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) && ((Hediff_Mayor)m.health.hediffSet.GetFirstHediffOfDef(HediffDefOfPsychology.Mayor)).worldTileElectedOn == factionBase.Map.Tile && ((Hediff_Mayor)m.health.hediffSet.GetFirstHediffOfDef(HediffDefOfPsychology.Mayor)).yearElected == GenLocalDate.Year(factionBase.Map.Tile)
                                                select m);
             if (activeMayors.Count() > 0)
             {
                 continue;
             }
             //Try to space out the elections so they don't all proc at once.
             if (Rand.RangeInclusive(1, 15 - GenLocalDate.DayOfSeason(factionBase.Map.Tile)) > 1)
             {
                 continue;
             }
             IncidentParms parms = new IncidentParms();
             parms.target  = factionBase.Map;
             parms.faction = factionBase.Faction;
             FiringIncident fi = new FiringIncident(IncidentDefOfPsychology.Election, null, parms);
             Find.Storyteller.TryFire(fi);
         }
     }
 }