public static float Replacemant(StatWorker statWorker, StatRequest req, bool applyPostProcess) { var tick = GenTicks.TicksGame; if (true && Finder.enabled && Current.Game != null && tick >= 600) { int key = Tools.GetKey(statWorker, req, applyPostProcess); int signature = -1; if (req.HasThing && req.Thing is Pawn pawn && pawn != null && !signatures.TryGetValue(pawn.thingIDNumber, out signature)) { signatures[pawn.thingIDNumber] = signature = Rand.Int.GetHashCode(); return(UpdateCache(key, statWorker, req, applyPostProcess, tick, null)); } if (!cache.TryGetValue(key, out var store)) { return(UpdateCache(key, statWorker, req, applyPostProcess, tick, store)); } if (tick - store.Item2 > Finder.statExpiry[statWorker.stat.index] || signature != store.Item3) { if (Finder.debug && signature != store.Item3) { Log.Message(string.Format("ROCKETMAN: Invalidated pawn cache with old sig:{0} and new {1}", store.Item3, signature)); } return(UpdateCache(key, statWorker, req, applyPostProcess, tick, store)); } return(store.Item1); } else { return(statWorker.GetValueUnfinalized(req, applyPostProcess)); } }
internal static float UpdateCache(int key, StatWorker statWorker, StatRequest req, bool applyPostProcess, int tick, Tuple <float, int, int> store) { var value = statWorker.GetValueUnfinalized(req, applyPostProcess); if (Finder.statLogging && !Finder.learning) { Log.Message(string.Format("ROCKETMAN: state {0} for {1} took {2} with key {3}", statWorker.stat.defName, req.thingInt, tick - (store?.Item2 ?? 0), key)); } else if (Finder.learning) { requests.Add(new Tuple <int, int, float>(statWorker.stat.index, tick - (store?.Item2 ?? tick), Mathf.Abs(value - (store?.Item1 ?? value)))); if (Rand.Chance(0.1f)) { ProcessExpiryCache(); } } int signature = -1; if (req.HasThing && req.Thing is Pawn pawn && pawn != null && !signatures.TryGetValue(pawn.thingIDNumber, out signature)) { signatures[pawn.thingIDNumber] = signature = Rand.Int.GetHashCode(); } cache[key] = new Tuple <float, int, int>(value, tick, signature); return(value); }
public static float Replacemant(StatWorker statWorker, StatRequest req, bool applyPostProcess) { if (Finder.enabled && Current.Game != null) { var key = Tools.GetKey(statWorker, req, applyPostProcess); var tick = GenTicks.TicksGame; if (!cache.TryGetValue(key, out var store)) { return(UpdateCache(key, statWorker, req, applyPostProcess, tick, store)); } if (tick - store.Second > Finder.statExpiry[statWorker.stat.index]) { return(UpdateCache(key, statWorker, req, applyPostProcess, tick, store)); } return(store.First); } else { return(statWorker.GetValueUnfinalized(req, applyPostProcess)); } }
internal static float UpdateCache(int key, StatWorker statWorker, StatRequest req, bool applyPostProcess, int tick, Pair <float, int> store) { var value = statWorker.GetValueUnfinalized(req, applyPostProcess); if (Finder.debug && !Finder.learning) { Log.Message(string.Format("ROCKETMAN: state {0} for {1} took {2} with key {3}", statWorker.stat.defName, req.thingInt, tick - store.second, key)); } if (Finder.learning) { requests.Add(new Tuple <int, int, float>(statWorker.stat.index, tick - store.second, Mathf.Abs(value - store.first))); } if (req.HasThing && req.Thing is Pawn pawn && pawn != null) { List <int> keys = null; if (!pawnCachedKeys.TryGetValue(pawn.thingIDNumber, out keys)) { pawnCachedKeys[pawn.thingIDNumber] = (keys = new List <int>()); } keys.Add(key); } cache[key] = new Pair <float, int>(value, tick); return(value); }
public static bool RocketMan_Replacemant(StatWorker statWorker, StatRequest req, bool applyPostProcess, ref float __result) { if (!UnityData.IsInMainThread) { // return not cached __result = statWorker.GetValueUnfinalized(req, applyPostProcess); return(false); } if (req.thingInt == null && req.stuffDefInt == null && req.defInt == null) { Log.ErrorOnce($"Try get value from Empty StatRequest!", "rocketman.patch".GetHashCode()); __result = 0; return(false); } return(true); }
public override IEnumerable <StatDrawEntry> SpecialDisplayStatsForThing(ThingWithComps parentThing, string preLabel) { // Add additional Equipped Stat Offsets modifiers var statDrawEntry = new StatDrawEntry( category: StatCategoryDefOf.EquippedStatOffsets, label: affectedStat.LabelCap, valueString: ModifierChangeString, // much more flexible than value reportText: affectedStat.description, displayPriorityWithinCategory: 10 ); StatRequest req = StatRequest.For(parentThing); // Extra properties, since we're overriding the typical stat value display statDrawEntry.stat = affectedStat; statDrawEntry.hasOptionalReq = true; statDrawEntry.optionalReq = req; // Calculate an example value StatWorker worker = affectedStat.Worker; float exampleValue = parentThing.ParentHolder != null && parentThing.ParentHolder is Pawn pawn? worker.GetValueUnfinalized(StatRequest.For(pawn)) : affectedStat.defaultBaseValue ; // Use the Thing-tied StatRequest to hit our StatPart worker.FinalizeValue(req, ref exampleValue, true); // And finally, another private we need to dodge around to install both kinds of StatDrawEntry fields. // [Reflection] statDrawEntry.value = exampleValue; FieldInfo valueField = AccessTools.Field(typeof(StatDrawEntry), "value"); valueField.SetValue(statDrawEntry, exampleValue); yield return(statDrawEntry); }