Ejemplo n.º 1
0
        public override bool ActivateOn(Lord lord, TriggerSignal signal)
        {
            if (signal.type == TriggerSignalType.Tick && Find.TickManager.TicksGame% GenTicks.TickRareInterval == 0)
            {
                var tradeCenters =
                    Find.ListerBuildings.AllBuildingsColonistOfClass<TradeCenter>()
                        .Where(building => building.trader == null);
                var trader = TraderCaravanUtility.FindTrader(lord);
                var carrier = lord.ownedPawns.FirstOrDefault(pawn => pawn.GetCaravanRole() == TraderCaravanRole.Carrier);

                if (tradeCenters.Any() && trader != null && carrier != null)
                {
                    if (trader.CanReach(tradeCenters.FirstOrDefault(), PathEndMode.InteractionCell, trader.NormalMaxDanger()) &&
                        carrier.CanReach(tradeCenters.FirstOrDefault(), PathEndMode.InteractionCell, trader.NormalMaxDanger()))
                        return true;
                }
            }
            return false;
        }
Ejemplo n.º 2
0
 public void AddObserver(IObserver obs)
 {
     Signal += new TriggerSignal(obs.Trigger);
 }
Ejemplo n.º 3
0
        private async Task ProcessMultiKeySelectionResult(
            IList <Timestamped <PointAndKeyValue> > pointsAndKeyValues,
            TriggerSignal startSelectionTriggerSignal)
        {
            Log.DebugFormat("Multi-key selection captured a set of '{0}' PointAndKeyValues.", pointsAndKeyValues.Count);

            RequestSuspend(); //Pause everything (i.e. processing new points) while we perform the (CPU bound) word matching

            try
            {
                if (pointsAndKeyValues.Any())
                {
                    var timeSpan = pointsAndKeyValues.Last().Timestamp.Subtract(pointsAndKeyValues.First().Timestamp);

                    var sequenceThreshold = (int)Math.Round(
                        ((double)pointsAndKeyValues.Count / (double)timeSpan.TotalMilliseconds)
                        * Settings.Default.MultiKeySelectionFixationMinDwellTime.TotalMilliseconds);

                    Log.DebugFormat(
                        "Multi-key selection capture lasted {0}ms. Minimum dwell time is {1}ms, or {2} points.",
                        timeSpan.TotalMilliseconds,
                        Settings.Default.MultiKeySelectionFixationMinDwellTime.TotalMilliseconds,
                        sequenceThreshold);

                    //Always assume the start trigger is reliable if it occurs on a letter
                    string reliableFirstLetter =
                        startMultiKeySelectionTriggerSignal != null &&
                        startMultiKeySelectionTriggerSignal.Value.PointAndKeyValue != null &&
                        startMultiKeySelectionTriggerSignal.Value.PointAndKeyValue.Value.StringIsLetter
                            ? startMultiKeySelectionTriggerSignal.Value.PointAndKeyValue.Value.String
                            : null;

                    Log.DebugFormat(
                        "First letter ('{0}') of multi-key selection capture {1} reliable.",
                        reliableFirstLetter,
                        reliableFirstLetter != null ? "IS" : "IS NOT");

                    //If we are using a fixation trigger and the stop trigger has occurred on a letter then it is reliable - use it
                    string reliableLastLetter = selectionTriggerSource is IFixationTriggerSource &&
                                                stopMultiKeySelectionTriggerSignal != null &&
                                                stopMultiKeySelectionTriggerSignal.Value.PointAndKeyValue != null &&
                                                stopMultiKeySelectionTriggerSignal.Value.PointAndKeyValue.Value.StringIsLetter
                            ? stopMultiKeySelectionTriggerSignal.Value.PointAndKeyValue.Value.String
                            : null;

                    Log.DebugFormat(
                        "Last letter ('{0}') of multi-key selection capture {1} reliable.",
                        reliableLastLetter,
                        reliableLastLetter != null ? "IS" : "IS NOT");

                    if (reliableLastLetter != null)
                    {
                        Log.Debug("Publishing selection event on last letter of multi-key selection capture.");

                        PublishSelection(stopMultiKeySelectionTriggerSignal.Value.PointAndKeyValue.Value);
                    }

                    //Why am I wrapping this call in a Task.Run? Internally the MapCaptureToEntries method uses PLINQ which also blocks the UI thread - this frees it up.
                    //This cannot be done inside the MapCaptureToEntries method as the method takes a ref param, which cannot be used inside an anonymous delegate or lambda.
                    //The method cannot be made awaitable as async/await also does not support ref params.
                    Tuple <List <Point>, FunctionKeys?, string, List <string> > result = null;
                    await Task.Run(() =>
                    {
                        result = dictionaryService.MapCaptureToEntries(
                            pointsAndKeyValues.ToList(), sequenceThreshold,
                            reliableFirstLetter, reliableLastLetter,
                            ref mapToDictionaryMatchesCancellationTokenSource,
                            exception => PublishError(this, exception));
                    });

                    if (result != null)
                    {
                        if (result.Item2 == null && result.Item3 == null &&
                            (result.Item4 == null || !result.Item4.Any()))
                        {
                            //Nothing useful in the result - play error message. Publish anyway as the points can be rendered in debugging mode.
                            audioService.PlaySound(Settings.Default.ErrorSoundFile, Settings.Default.ErrorSoundVolume);
                        }

                        PublishSelectionResult(result);
                    }
                }
            }
            finally
            {
                RequestResume();
            }
        }
Ejemplo n.º 4
0
        private void ProcessSelectionTrigger(TriggerSignal triggerSignal)
        {
            if (triggerSignal.Signal >= 1 &&
                !CapturingMultiKeySelection)
            {
                //We are not currently capturing a multikey selection and have received a high (start) trigger signal
                if (triggerSignal.PointAndKeyValue != null)
                {
                    Log.Debug("Selection trigger signal (with relevent PointAndKeyValue) detected.");

                    if (SelectionMode == SelectionModes.Key)
                    {
                        if (triggerSignal.PointAndKeyValue.Value.KeyValue != null &&
                            (keyStateService.KeyEnabledStates == null || keyStateService.KeyEnabledStates[triggerSignal.PointAndKeyValue.Value.KeyValue.Value]))
                        {
                            Log.Debug("Selection mode is KEY and the key on which the trigger occurred is enabled.");

                            if (MultiKeySelectionSupported &&
                                keyStateService.KeyDownStates[KeyValues.MultiKeySelectionIsOnKey].Value.IsDownOrLockedDown() &&
                                triggerSignal.PointAndKeyValue.Value.KeyValue != null &&
                                KeyValues.MultiKeySelectionKeys.Contains(triggerSignal.PointAndKeyValue.Value.KeyValue.Value) &&
                                !KeyValues.CombiningKeys.Any(key => keyStateService.KeyDownStates[key].Value.IsDownOrLockedDown()))    //Do not start if any combining ("dead") keys are down
                            {
                                Log.Debug("Multi-key selection is currently enabled and the key on which the trigger occurred is a letter. Publishing the selection and beginning a new multi-key selection capture.");

                                //Multi-key selection is allowed and the trigger occurred on a letter - start a capture
                                startMultiKeySelectionTriggerSignal = triggerSignal;
                                stopMultiKeySelectionTriggerSignal  = null;

                                CapturingMultiKeySelection = true;

                                PublishSelection(triggerSignal.PointAndKeyValue.Value);

                                multiKeySelectionSubscription =
                                    CreateMultiKeySelectionSubscription()
                                    .ObserveOnDispatcher()
                                    .Subscribe(
                                        async pointsAndKeyValues => await ProcessMultiKeySelectionResult(pointsAndKeyValues, triggerSignal),
                                        (exception =>
                                {
                                    PublishError(this, exception);

                                    stopMultiKeySelectionTriggerSignal = null;
                                    CapturingMultiKeySelection = false;
                                }),
                                        () =>
                                {
                                    Log.Debug("Multi-key selection capture has completed.");

                                    stopMultiKeySelectionTriggerSignal = null;
                                    CapturingMultiKeySelection         = false;
                                });
                            }
                            else
                            {
                                PublishSelection(triggerSignal.PointAndKeyValue.Value);

                                PublishSelectionResult(new Tuple <List <Point>, FunctionKeys?, string, List <string> >(
                                                           new List <Point> {
                                    triggerSignal.PointAndKeyValue.Value.Point
                                },
                                                           triggerSignal.PointAndKeyValue.Value.KeyValue.Value.FunctionKey,
                                                           triggerSignal.PointAndKeyValue.Value.KeyValue.Value.String,
                                                           null));
                            }
                        }
                        else
                        {
                            Log.Debug("Selection mode is KEY, but the trigger occurred away from a key or over a disabled key.");
                        }
                    }
                    else if (SelectionMode == SelectionModes.Point)
                    {
                        PublishSelection(triggerSignal.PointAndKeyValue.Value);

                        PublishSelectionResult(new Tuple <List <Point>, FunctionKeys?, string, List <string> >(
                                                   new List <Point> {
                            triggerSignal.PointAndKeyValue.Value.Point
                        }, null, null, null));
                    }
                }
                else
                {
                    Log.Error("TriggerSignal.Signal==1, but TriggerSignal.PointAndKeyValue is null. "
                              + "Discarding trigger as point source is down, or producing stale points. "
                              + "Publishing error instead.");

                    PublishError(this, new ApplicationException(Resources.TRIGGER_WITHOUT_POSITION_ERROR));
                }
            }
            else if (CapturingMultiKeySelection)
            {
                //We are capturing and may have received the stop capturing signal
                if ((triggerSignal.Signal >= 1 && Settings.Default.MultiKeySelectionTriggerStopSignal == TriggerStopSignals.NextHigh) ||
                    (triggerSignal.Signal <= -1 && Settings.Default.MultiKeySelectionTriggerStopSignal == TriggerStopSignals.NextLow))
                {
                    //If we are using a fixation trigger source then the stop signal must occur on a letter
                    if (!(selectionTriggerSource is IFixationTriggerSource) ||
                        (triggerSignal.PointAndKeyValue != null && triggerSignal.PointAndKeyValue.Value.StringIsLetter))
                    {
                        Log.Debug("Trigger signal to stop the current multi-key selection capture detected.");

                        stopMultiKeySelectionTriggerSignal = triggerSignal;
                    }
                }
            }
        }
Ejemplo n.º 5
0
 static bool Prefix(ref Trigger_ChanceOnTickInteval __instance, ref bool __result, ref Lord lord, ref TriggerSignal signal)
 {
     __result = signal.type == TriggerSignalType.Tick &&
                Find.TickManager.TicksGame % __instance.interval < RefcellRespeedConfig.currentTimeMultiplier &&
                (double)Rand.Value < (double)__instance.chancePerInterval;
     return(false);
 }
Ejemplo n.º 6
0
 static bool Prefix(ref Trigger_WoundedGuestPresent __instance, ref bool __result, ref Lord lord, ref TriggerSignal signal)
 {
     if (signal.type == TriggerSignalType.Tick && Find.TickManager.TicksGame % 800 < RefcellRespeedConfig.currentTimeMultiplier)
     {
         TriggerData_PawnCycleInd data = __instance.Data;
         ++data.pawnCycleInd;
         if (data.pawnCycleInd >= lord.ownedPawns.Count)
         {
             data.pawnCycleInd = 0;
         }
         if (lord.ownedPawns.Any <Pawn>())
         {
             Pawn ownedPawn = lord.ownedPawns[data.pawnCycleInd];
             if (ownedPawn.Spawned && !ownedPawn.Downed && (!ownedPawn.InMentalState && KidnapAIUtility.ReachableWoundedGuest(ownedPawn) != null))
             {
                 __result = true;
                 return(false);
             }
         }
     }
     __result = false;
     return(false);
 }
Ejemplo n.º 7
0
 static bool Prefix(ref Trigger_KidnapVictimPresent __instance, ref bool __result, ref Lord lord, ref TriggerSignal signal)
 {
     if (signal.type == TriggerSignalType.Tick && Find.TickManager.TicksGame % 120 < RefcellRespeedConfig.currentTimeMultiplier)
     {
         if (__instance.data == null || !(__instance.data is TriggerData_PawnCycleInd))
         {
             BackCompatibility.TriggerDataPawnCycleIndNull(__instance);
         }
         if (Find.TickManager.TicksGame - lord.lastPawnHarmTick > 300)
         {
             TriggerData_PawnCycleInd data = __instance.Data;
             ++data.pawnCycleInd;
             if (data.pawnCycleInd >= lord.ownedPawns.Count)
             {
                 data.pawnCycleInd = 0;
             }
             if (lord.ownedPawns.Any <Pawn>())
             {
                 Pawn ownedPawn = lord.ownedPawns[data.pawnCycleInd];
                 if (ownedPawn.Spawned && !ownedPawn.Downed && (ownedPawn.MentalStateDef == null && KidnapAIUtility.TryFindGoodKidnapVictim(ownedPawn, 8f, out Pawn _)) && !GenAI.InDangerousCombat(ownedPawn))
                 {
                     __result = true;
                     return(false);
                 }
             }
         }
     }
     __result = false;
     return(false);
 }
Ejemplo n.º 8
0
 static bool Prefix(ref Trigger_TicksPassedAfterConditionMet __instance, ref bool __result, ref Lord lord, ref TriggerSignal signal)
 {
     if (!__instance.Data.conditionMet && signal.type == TriggerSignalType.Tick && Find.TickManager.TicksGame % __instance.checkEveryTicks == 0)
     {
         __instance.Data.conditionMet = __instance.condition();
     }
     __result = __instance.Data.conditionMet && ActivateOn(__instance, lord, signal);
     return(false);
 }
Ejemplo n.º 9
0
 static bool ActivateOn(Trigger_TicksPassedAfterConditionMet __instance, Lord lord, TriggerSignal signal)
 {
     return(false);
 }
Ejemplo n.º 10
0
 static bool Prefix(ref Trigger_HighValueThingsAround __instance, ref bool __result, ref Lord lord, ref TriggerSignal signal)
 {
     __result = signal.type == TriggerSignalType.Tick && Find.TickManager.TicksGame % 120 < RefcellRespeedConfig.currentTimeMultiplier &&
                (!TutorSystem.TutorialMode && Find.TickManager.TicksGame - lord.lastPawnHarmTick > 300) &&
                (double)StealAIUtility.TotalMarketValueAround(lord.ownedPawns) > (double)StealAIUtility.StartStealingMarketValueThreshold(lord);
     return(false);
 }
Ejemplo n.º 11
0
 static bool Prefix(ref Trigger_TickCondition __instance, ref bool __result, ref Lord lord, ref TriggerSignal signal)
 {
     __result = signal.type == TriggerSignalType.Tick &&
                Find.TickManager.TicksGame % __instance.checkEveryTicks < RefcellRespeedConfig.currentTimeMultiplier &&
                __instance.condition();
     return(false);
 }
Ejemplo n.º 12
0
 static bool Prefix(ref Trigger_PawnExperiencingDangerousTemperatures __instance, ref bool __result, ref Lord lord, ref TriggerSignal signal)
 {
     if (signal.type == TriggerSignalType.Tick && Find.TickManager.TicksGame % 197 < RefcellRespeedConfig.currentTimeMultiplier)
     {
         for (int index = 0; index < lord.ownedPawns.Count; ++index)
         {
             Pawn ownedPawn = lord.ownedPawns[index];
             if (ownedPawn.Spawned && !ownedPawn.Dead && !ownedPawn.Downed)
             {
                 Hediff firstHediffOfDef1 = ownedPawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Heatstroke);
                 if (firstHediffOfDef1 != null && (double)firstHediffOfDef1.Severity > (double)__instance.temperatureHediffThreshold)
                 {
                     __result = true;
                     return(false);
                 }
                 Hediff firstHediffOfDef2 = ownedPawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Hypothermia);
                 if (firstHediffOfDef2 != null && (double)firstHediffOfDef2.Severity > (double)__instance.temperatureHediffThreshold)
                 {
                     __result = true;
                     return(false);
                 }
             }
         }
     }
     __result = false;
     return(false);
 }
Ejemplo n.º 13
0
 static bool Prefix(ref Trigger_PawnCanReachMapEdge __instance, ref bool __result, ref Lord lord, ref TriggerSignal signal)
 {
     if (signal.type != TriggerSignalType.Tick || Find.TickManager.TicksGame % 193 > RefcellRespeedConfig.currentTimeMultiplier - 1)
     {
         __result = false;
         return(false);
     }
     for (int index = 0; index < lord.ownedPawns.Count; ++index)
     {
         Pawn ownedPawn = lord.ownedPawns[index];
         if (ownedPawn.Spawned && !ownedPawn.Dead && (!ownedPawn.Downed && !ownedPawn.CanReachMapEdge()))
         {
             __result = false;
             return(false);
         }
     }
     __result = true;
     return(false);
 }