根据向量相似度分析,与 'AddHumanlikeOrders, FloatMenuMakerMap' 最相关的代码定义如下: --- **文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\FloatMenuMakerMap.txt` ```csharp public static class FloatMenuMakerMap { private static List providers; public static FloatMenuOptionProvider currentProvider; public static Pawn makingFor; public static void Init() { providers = new List(); foreach (Type item in typeof(FloatMenuOptionProvider).AllSubclassesNonAbstract()) { providers.Add((FloatMenuOptionProvider)Activator.CreateInstance(item)); } } public static List GetOptions(List selectedPawns, Vector3 clickPos, out FloatMenuContext context) { List list = new List(); context = null; if (!clickPos.InBounds(Find.CurrentMap)) { return list; } context = new FloatMenuContext(selectedPawns, clickPos, Find.CurrentMap); if (!context.allSelectedPawns.Any()) { return list; } if (!context.ClickedCell.IsValid || !context.ClickedCell.InBounds(Find.CurrentMap)) { return list; } if (!context.IsMultiselect) { AcceptanceReport acceptanceReport = ShouldGenerateFloatMenuForPawn(context.FirstSelectedPawn); if (!acceptanceReport.Accepted) { if (!acceptanceReport.Reason.NullOrEmpty()) { Messages.Message(acceptanceReport.Reason, context.FirstSelectedPawn, MessageTypeDefOf.RejectInput, historical: false); } return list; } } else { context.allSelectedPawns.RemoveAll((Pawn selectedPawn) => !ShouldGenerateFloatMenuForPawn(selectedPawn)); if (!context.allSelectedPawns.Any()) { return list; } } if (!context.IsMultiselect) { makingFor = context.FirstSelectedPawn; } GetProviderOptions(context, list); makingFor = null; return list; } private static void GetProviderOptions(FloatMenuContext context, List options) { foreach (FloatMenuOptionProvider provider in providers) { try { currentProvider = provider; if (!context.ValidSelectedPawns.Any() || !provider.Applies(context)) { continue; } options.AddRange(provider.GetOptions(context)); foreach (Thing clickedThing in context.ClickedThings) { if (!provider.TargetThingValid(clickedThing, context)) { continue; } Thing thing = clickedThing; if (thing.TryGetComp(out CompSelectProxy comp) && comp.thingToSelect != null) { thing = comp.thingToSelect; } foreach (FloatMenuOption item in provider.GetOptionsFor(thing, context)) { FloatMenuOption floatMenuOption = item; if (floatMenuOption.iconThing == null) { floatMenuOption.iconThing = thing; } item.targetsDespawned = !thing.Spawned; options.Add(item); } } foreach (Pawn clickedPawn in context.ClickedPawns) { if (!provider.TargetPawnValid(clickedPawn, context)) { continue; } foreach (FloatMenuOption item2 in provider.GetOptionsFor(clickedPawn, context)) { FloatMenuOption floatMenuOption = item2; if (floatMenuOption.iconThing == null) { floatMenuOption.iconThing = clickedPawn; } item2.targetsDespawned = !clickedPawn.Spawned; options.Add(item2); } } } catch (Exception arg) { Log.Error($"Error in FloatMenuWorker {provider.GetType().Name}: {arg}"); } } currentProvider = null; } public static AcceptanceReport ShouldGenerateFloatMenuForPawn(Pawn pawn) { if (pawn.Map != Find.CurrentMap) { return false; } if (pawn.Downed) { return "IsIncapped".Translate(pawn.LabelCap, pawn); } if (ModsConfig.BiotechActive && pawn.Deathresting) { return "IsDeathresting".Translate(pawn.Named("PAWN")); } Lord lord = pawn.GetLord(); if (lord != null) { AcceptanceReport result = lord.AllowsFloatMenu(pawn); if (!result.Accepted) { return result; } } return true; } public static FloatMenuOption GetAutoTakeOption(List options) { bool flag = true; FloatMenuOption floatMenuOption = null; foreach (FloatMenuOption option in options) { if (option.Disabled || !option.autoTakeable) { flag = false; break; } if (floatMenuOption == null || option.autoTakeablePriority > floatMenuOption.autoTakeablePriority) { floatMenuOption = option; } } if (!flag || floatMenuOption == null) { return null; } return floatMenuOption; } } ``` --- **文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\FloatMenuContext.txt` **相似度:** 0.5788 ```csharp public class FloatMenuContext { public List allSelectedPawns; public Vector3 clickPosition; public Map map; private IntVec3 cachedClickedCell; private List cachedClickedThings; private List cachedClickedPawns; private Room cachedClickedRoom; private Zone cachedClickedZone; public IntVec3 ClickedCell => cachedClickedCell; public Room ClickedRoom => cachedClickedRoom; public Zone ClickedZone => cachedClickedZone; public List ClickedThings => cachedClickedThings; public List ClickedPawns => cachedClickedPawns; public bool IsMultiselect => allSelectedPawns.Count > 1; public Pawn FirstSelectedPawn { get { foreach (Pawn allSelectedPawn in allSelectedPawns) { if (FloatMenuMakerMap.currentProvider == null || FloatMenuMakerMap.currentProvider.SelectedPawnValid(allSelectedPawn, this)) { return allSelectedPawn; } } return null; } } public IEnumerable ValidSelectedPawns { get { foreach (Pawn allSelectedPawn in allSelectedPawns) { if (FloatMenuMakerMap.currentProvider == null || FloatMenuMakerMap.currentProvider.SelectedPawnValid(allSelectedPawn, this)) { yield return allSelectedPawn; } } } } public FloatMenuContext(List selectedPawns, Vector3 clickPosition, Map map) { allSelectedPawns = selectedPawns; this.clickPosition = clickPosition; this.map = map; cachedClickedCell = IntVec3.FromVector3(clickPosition); cachedClickedRoom = cachedClickedCell.GetRoom(map); cachedClickedZone = cachedClickedCell.GetZone(map); cachedClickedThings = GenUI.ThingsUnderMouse(clickPosition, 0.8f, TargetingParameters.ForThing()); cachedClickedPawns = GenUI.ThingsUnderMouse(clickPosition, 0.8f, TargetingParameters.ForPawns()).OfType().ToList(); selectedPawns.RemoveAll((Pawn pawn) => !pawn.CanTakeOrder); } } ``` --- **文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse\FloatMenuMap.txt` **相似度:** 0.5739 ```csharp public class FloatMenuMap : FloatMenu { private Vector3 clickPos; private static Dictionary> cachedChoices = new Dictionary>(); private List lastOptionsForRevalidation; private int nextOptionToRevalidate; public const int RevalidateEveryFrame = 4; public FloatMenuMap(List options, string title, Vector3 clickPos) : base(options, title) { this.clickPos = clickPos; } public override void DoWindowContents(Rect inRect) { if (!Find.Selector.AnyPawnSelected) { Find.WindowStack.TryRemove(this); return; } bool flag = options.Count >= 3; if (Time.frameCount % 4 == 0 || lastOptionsForRevalidation == null) { lastOptionsForRevalidation = FloatMenuMakerMap.GetOptions(Find.Selector.SelectedPawns, clickPos, out var _); cachedChoices.Clear(); cachedChoices.Add(clickPos, lastOptionsForRevalidation); if (!flag) { for (int i = 0; i < options.Count; i++) { RevalidateOption(options[i]); } } } else if (flag) { if (nextOptionToRevalidate >= options.Count) { nextOptionToRevalidate = 0; } int num = Mathf.CeilToInt((float)options.Count / 3f); int num2 = nextOptionToRevalidate; int num3 = 0; while (num2 < options.Count && num3 < num) { RevalidateOption(options[num2]); nextOptionToRevalidate++; num2++; num3++; } } base.DoWindowContents(inRect); void RevalidateOption(FloatMenuOption option) { if (!option.Disabled && !StillValid(option, lastOptionsForRevalidation)) { option.Disabled = true; } } } private static bool StillValid(FloatMenuOption opt, List curOpts) { if (opt.revalidateClickTarget == null) { for (int i = 0; i < curOpts.Count; i++) { if (OptionsMatch(opt, curOpts[i])) { return true; } } } else { if (!opt.targetsDespawned && !opt.revalidateClickTarget.Spawned) { return false; } Vector3 key = opt.revalidateClickTarget.PositionHeld.ToVector3Shifted(); if (!cachedChoices.TryGetValue(key, out var value)) { FloatMenuContext context; List list = FloatMenuMakerMap.GetOptions(Find.Selector.SelectedPawns, key, out context); cachedChoices.Add(key, list); value = list; } for (int j = 0; j < value.Count; j++) { if (OptionsMatch(opt, value[j])) { return !value[j].Disabled; } } } return false; } public override void PreOptionChosen(FloatMenuOption opt) { base.PreOptionChosen(opt); if (!opt.Disabled && !StillValid(opt, FloatMenuMakerMap.GetOptions(Find.Selector.SelectedPawns, clickPos, out var _))) { opt.Disabled = true; } } private static bool OptionsMatch(FloatMenuOption a, FloatMenuOption b) { if (a.Label == b.Label) { return true; } return false; } } ``` --- **文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\FloatMenuOptionProvider.txt` **相似度:** 0.5483 ```csharp public abstract class FloatMenuOptionProvider { protected abstract bool Drafted { get; } protected abstract bool Undrafted { get; } protected abstract bool Multiselect { get; } protected virtual bool RequiresManipulation => false; protected virtual bool MechanoidCanDo => false; protected virtual bool CanSelfTarget => false; public virtual bool CanTargetDespawned => false; protected virtual bool IgnoreFogged => true; public virtual bool SelectedPawnValid(Pawn pawn, FloatMenuContext context) { if (pawn.IsMutant && pawn.mutant.Def.whitelistedFloatMenuProviders != null && !pawn.mutant.Def.whitelistedFloatMenuProviders.Contains(FloatMenuMakerMap.currentProvider.GetType())) { return false; } if (!Drafted && pawn.Drafted) { return false; } if (!Undrafted && !pawn.Drafted) { return false; } if (!MechanoidCanDo && pawn.RaceProps.IsMechanoid) { return false; } if (RequiresManipulation && !pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { return false; } return true; } public virtual bool TargetThingValid(Thing thing, FloatMenuContext context) { if (!CanTargetDespawned && !thing.Spawned) { return false; } if (thing is Pawn pawn && !TargetPawnValid(pawn, context)) { return false; } return true; } public virtual bool TargetPawnValid(Pawn pawn, FloatMenuContext context) { if (!CanSelfTarget && pawn == context.FirstSelectedPawn) { return false; } return true; } public virtual bool Applies(FloatMenuContext context) { if (!Multiselect && context.IsMultiselect) { return false; } if (IgnoreFogged && context.ClickedCell.Fogged(context.map)) { return false; } if (!AppliesInt(context)) { return false; } return true; } protected virtual bool AppliesInt(FloatMenuContext context) { return true; } public virtual IEnumerable GetOptions(FloatMenuContext context) { FloatMenuOption singleOption = GetSingleOption(context); if (singleOption != null) { yield return singleOption; } } public virtual IEnumerable GetOptionsFor(Thing clickedThing, FloatMenuContext context) { FloatMenuOption singleOptionFor = GetSingleOptionFor(clickedThing, context); if (singleOptionFor != null) { yield return singleOptionFor; } } public virtual IEnumerable GetOptionsFor(Pawn clickedPawn, FloatMenuContext context) { FloatMenuOption singleOptionFor = GetSingleOptionFor(clickedPawn, context); if (singleOptionFor != null) { yield return singleOptionFor; } } protected virtual FloatMenuOption GetSingleOption(FloatMenuContext context) { return null; } protected virtual FloatMenuOption GetSingleOptionFor(Thing clickedThing, FloatMenuContext context) { return null; } protected virtual FloatMenuOption GetSingleOptionFor(Pawn clickedPawn, FloatMenuContext context) { return null; } } ```