diff --git a/AllowTool.csproj b/AllowTool.csproj
index bf2575b..53ae930 100644
--- a/AllowTool.csproj
+++ b/AllowTool.csproj
@@ -77,12 +77,14 @@
+
+
diff --git a/AllowTool.csproj.DotSettings b/AllowTool.csproj.DotSettings
index 6bf57c2..71d87e5 100644
--- a/AllowTool.csproj.DotSettings
+++ b/AllowTool.csproj.DotSettings
@@ -1,4 +1,5 @@
True
True
- True
\ No newline at end of file
+ True
+ True
\ No newline at end of file
diff --git a/Mods/AllowTool/About/About.xml b/Mods/AllowTool/About/About.xml
index 71ff411..25efb40 100644
--- a/Mods/AllowTool/About/About.xml
+++ b/Mods/AllowTool/About/About.xml
@@ -4,7 +4,7 @@
UnlimitedHugs
0.17.0
https://ludeon.com/forums/index.php?topic=17218.0
- Version: 3.1.1
+ Version: 3.1.2
A set of tools to make your life on the Rim a bit easier.
Easily forbid and unforbid items, select similar things, have things hauled urgently and affect the entire map with powerful new tool extensions.
diff --git a/Mods/AllowTool/Assemblies/AllowTool.dll b/Mods/AllowTool/Assemblies/AllowTool.dll
index 1309eed..52b9a14 100644
Binary files a/Mods/AllowTool/Assemblies/AllowTool.dll and b/Mods/AllowTool/Assemblies/AllowTool.dll differ
diff --git a/Mods/AllowTool/Defs/ReverseDesignatorDefs/ReverseDesignators.xml b/Mods/AllowTool/Defs/ReverseDesignatorDefs/ReverseDesignators.xml
new file mode 100644
index 0000000..9c72089
--- /dev/null
+++ b/Mods/AllowTool/Defs/ReverseDesignatorDefs/ReverseDesignators.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ ReverseHaulUrgently
+
+ HaulUrgentlyDesignator
+
+ AllowTool.Designator_HaulUrgently
+
+
+
+ ReverseSelectSimilar
+ AllowTool.Designator_SelectSimilarReverse
+ SelectSimilarDesignator
+
+
+
\ No newline at end of file
diff --git a/Mods/AllowTool/Languages/English/Keyed/AllowToolStrings.xml b/Mods/AllowTool/Languages/English/Keyed/AllowToolStrings.xml
index 1956cfa..8e6eb0a 100644
--- a/Mods/AllowTool/Languages/English/Keyed/AllowToolStrings.xml
+++ b/Mods/AllowTool/Languages/English/Keyed/AllowToolStrings.xml
@@ -22,11 +22,17 @@
Displays an AllowTool watermark in tool context menus when enabled.
Right click icon on tools
When enabled, displays a small icon on designator tools that have a context menu.
+ Extended "Context action" hotkey
+ When no tool is selected, the "Context action" hotkey will activate the context action on the first visible tool when items are selected.
+ Pick tool from selected items
+ Holding the Shift key and clicking on a tool while having items selected will pick that tool up instead of activating it on the items.
Enable: {0}
When enabled, adds a right-click menu to the tool that allows it to affect the entire map.
▼ Show settings ▼
Enable or disable tools
Enable or disable context menus
+ Tools on selected things
+ When enabled, shows this tool when supported things are selected. Load or start a game for this setting to take effect.
Show "Haul+" work type
When enabled, shows the work type for the "Haul urgently" tool in the Work tab.\nThe game must be restarted for this setting to take effect.
@@ -46,6 +52,7 @@
Haul visible items urgently
Haul all map items urgently
{0} items marked for urgent hauling.
+ {0} visible items marked for urgent hauling.
Found no new items to haul.
Strip all enemies
{0} bodies designated for stripping.
diff --git a/Mods/AllowTool/Languages/Russian/Keyed/AllowToolStrings.xml b/Mods/AllowTool/Languages/Russian/Keyed/AllowToolStrings.xml
index f39a808..5fa8ee1 100644
--- a/Mods/AllowTool/Languages/Russian/Keyed/AllowToolStrings.xml
+++ b/Mods/AllowTool/Languages/Russian/Keyed/AllowToolStrings.xml
@@ -6,12 +6,12 @@
Запрещено {0} предметов.
Не найдено предметов для запрещения.
-
+
Разрешено {0} предметов по всей карте.
Не найдено запрещенных предметов.
-
+
Выделено {0} {1} по всей карте.
-
+
Отображать: {0}
Если настройка включена, инструмент будет отображаться в меню.
Глобальные быстрые клавиши
@@ -22,27 +22,36 @@
Отображает логотип AllowTool в контекстном меню инструментов.
Иконка контекстного меню на инструментах
Отображает иконку "правый клик" на инструментах, у которых есть контекстное меню.
+ Расширенная клавиша "Действие контекстного меню"
+ Когда не выбран ни одни инструмент, клавиша "Действие контекстного меню" активирует действие контекстного меню первого инструмента на выделенных предметах.
+ Выбор инструментов с выделенных предметов
+ Когда выделены предметы, удерживая клавишу Shift и нажав на инструмент, можно выбрать этот инструмент для дальнейшей работы вместо того чтобы активировать его на выделенных предметах.
Включить: {0}
Добавляет контекстное меню этому инструменту, позволяющее воздействовать на всю карту сразу.
▼ Открыть настройки ▼
Включить или отключить инструменты
Включить или отключить контекстные меню
- Отображать тип работы "Перенос+"
- Если включено, панель настроек работ отображает дополнительный тип работы для инструмента срочного переноса. Требуется перезапуск.
-
+ Инструменты на выделенных предметах
+ Tools on selected things
+ Если включено, отображает этот инструмент на поддерживаемых выделенных предметах. Вступает в силу после загрузки сохраненной игры.
+ Отображать тип работы "Перенос+"
+ Если включено, панель настроек работ отображает дополнительный тип работы для инструмента срочного переноса. Требуется перезапуск.
+
Клик для выделения предмета
Будет выделено только: {0}
Выделено максимум предметов
(еще {0})
-
+
{0} предметов будут перенесены срочно.
Не найдено предметов нуждающихся в переносе.
-
+
Выделить схожие предметы на карте
Выделено {0} схожих предметов на карте.
Выделено {0} из доступных {1} схожих предметов на карте.
Что-нибудь должно быть уже выделено чтобы найти и выделить схожие предметов.
- Срочно перенести видимые предметы
+ Срочно перенести предметы
+ Срочно перенести видимые предметы
+ Срочно перенести все предметы на карте
{0} предметов отмечено для срочного переноса.
Не найдено предметов нуждающихся в переносе.
Снять одежду со всех врагов
@@ -71,5 +80,5 @@
Не найдено планов для отмены.
Отменить все указания на карте
Отменено {0} указаний на предметах и {1} на ландшафте.
-
+
diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs
index e97f870..89be726 100644
--- a/Properties/AssemblyInfo.cs
+++ b/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("3.1.1")]
-[assembly: AssemblyFileVersion("3.1.1")]
+[assembly: AssemblyVersion("3.1.2")]
+[assembly: AssemblyFileVersion("3.1.2")]
diff --git a/Source/AllowToolController.cs b/Source/AllowToolController.cs
index 0ec5b23..d9ca6b6 100644
--- a/Source/AllowToolController.cs
+++ b/Source/AllowToolController.cs
@@ -18,28 +18,36 @@ namespace AllowTool {
public class AllowToolController : ModBase {
internal const string ModId = "AllowTool";
internal const string DesignatorHandleNamePrefix = "show";
+ internal const string ReverseDesignatorHandleNamePrefix = "showrev";
internal const string HarmonyInstanceId = "HugsLib.AllowTool";
private const string HaulWorktypeSettingName = "haulUrgentlyWorktype";
public static FieldInfo ResolvedDesignatorsField;
public static FieldInfo ReverseDesignatorDatabaseDesListField;
+ public static FieldInfo GizmoGridGizmoListField;
public static AllowToolController Instance { get; private set; }
internal static HarmonyInstance HarmonyInstance { get; set; }
// called before implied def generation
public static void HideHaulUrgentlyWorkTypeIfDisabled() {
- var peekValue = HugsLibController.SettingsManager.GetModSettings(ModId).PeekValue(HaulWorktypeSettingName); // handles will be created later- just peek for now
- if (peekValue == "False") {
- AllowToolDefOf.HaulingUrgent.visible = false;
+ try {
+ var peekValue = HugsLibController.SettingsManager.GetModSettings(ModId).PeekValue(HaulWorktypeSettingName); // handles will be created later- just peek for now
+ if (peekValue == "False") {
+ AllowToolDefOf.HaulingUrgent.visible = false;
+ }
+ } catch (Exception e) {
+ Log.Error("AllowTool failed to modify work type visibility: "+e);
}
}
private readonly List activeDesignators = new List();
private readonly Dictionary> designatorToggleHandles = new Dictionary>();
+ private readonly Dictionary> reverseDesignatorToggleHandles = new Dictionary>();
private SettingHandle settingGlobalHotkeys;
private bool expandToolSettings;
private bool expandProviderSettings;
+ private bool expandReverseToolSettings;
public override string ModIdentifier {
get { return ModId; }
@@ -59,6 +67,10 @@ protected override bool HarmonyAutoPatch {
internal SettingHandle ContextWatermarkSetting { get; private set; }
+ public SettingHandle ExtendedContextActionSetting { get; set; }
+
+ public SettingHandle ReverseDesignatorPickSetting { get; set; }
+
public UnlimitedDesignationDragger Dragger { get; private set; }
private AllowToolController() {
@@ -113,9 +125,11 @@ public override void SettingsChanged() {
}
public bool IsDesignatorEnabledInSettings(ThingDesignatorDef def) {
- SettingHandle handle;
- designatorToggleHandles.TryGetValue(DesignatorHandleNamePrefix + def.defName, out handle);
- return handle == null || handle.Value;
+ return GetToolHandleSettingValue(designatorToggleHandles, DesignatorHandleNamePrefix + def.defName);
+ }
+
+ public bool IsReverseDesignatorEnabledInSettings(ReverseDesignatorDef def) {
+ return GetToolHandleSettingValue(reverseDesignatorToggleHandles, ReverseDesignatorHandleNamePrefix + def.defName);
}
public Designator_SelectableThings TryGetDesignator(ThingDesignatorDef def) {
@@ -127,6 +141,8 @@ private void PrepareSettingsHandles() {
ContextOverlaySetting = Settings.GetHandle("contextOverlay", "setting_contextOverlay_label".Translate(), "setting_contextOverlay_desc".Translate(), true);
ContextWatermarkSetting = Settings.GetHandle("contextWatermark", "setting_contextWatermark_label".Translate(), "setting_contextWatermark_desc".Translate(), true);
Settings.GetHandle(HaulWorktypeSettingName, "setting_haulUrgentlyWorktype_label".Translate(), "setting_haulUrgentlyWorktype_desc".Translate(), true);
+ ExtendedContextActionSetting = Settings.GetHandle("extendedContextActionKey", "setting_extendedContextHotkey_label".Translate(), "setting_extendedContextHotkey_desc".Translate(), true);
+ ReverseDesignatorPickSetting = Settings.GetHandle("reverseDesignatorPick", "setting_reverseDesignatorPick_label".Translate(), "setting_reverseDesignatorPick_desc".Translate(), true);
SelectionLimitSetting = Settings.GetHandle("selectionLimit", "setting_selectionLimit_label".Translate(), "setting_selectionLimit_desc".Translate(), 200, Validators.IntRangeValidator(50, 100000));
SelectionLimitSetting.SpinnerIncrement = 50;
// designators
@@ -144,6 +160,14 @@ private void PrepareSettingsHandles() {
provider.ProviderHandle = Settings.GetHandle(provider.SettingId, "setting_providerPrefix".Translate(provider.EntryTextKey.Translate()), "setting_provider_desc".Translate(), true);
provider.ProviderHandle.VisibilityPredicate = () => expandProviderSettings;
}
+ // reverse designators
+ MakeSettingsCategoryToggle("setting_showReverseToggles_label", () => expandReverseToolSettings = !expandReverseToolSettings);
+ foreach (var reverseDef in DefDatabase.AllDefs) {
+ var handleName = ReverseDesignatorHandleNamePrefix + reverseDef.defName;
+ var handle = Settings.GetHandle(handleName, "setting_showTool_label".Translate(reverseDef.designatorDef.label), "setting_reverseDesignator_desc".Translate(), true);
+ handle.VisibilityPredicate = () => expandReverseToolSettings;
+ reverseDesignatorToggleHandles[handleName] = handle;
+ }
}
private void MakeSettingsCategoryToggle(string labelId, Action buttonAction) {
@@ -155,6 +179,15 @@ private void MakeSettingsCategoryToggle(string labelId, Action buttonAction) {
};
}
+ public Designator_SelectableThings InstantiateDesignator(Type designatorType, ThingDesignatorDef designatorDef) {
+ try {
+ return (Designator_SelectableThings) Activator.CreateInstance(designatorType, designatorDef);
+ } catch (Exception e) {
+ Logger.ReportException(e, null, false, string.Format("instantiation of {0} with Def {1}", (designatorType != null ? designatorType.FullName : "(null)"), designatorDef));
+ }
+ return null;
+ }
+
private void InjectDesignators() {
var numDesignatorsInjected = 0;
foreach (var designatorDef in DefDatabase.AllDefs) {
@@ -167,7 +200,7 @@ private void InjectDesignators() {
break;
}
if (insertIndex >= 0) {
- var designator = (Designator_SelectableThings)Activator.CreateInstance(designatorDef.designatorClass, designatorDef);
+ var designator = InstantiateDesignator(designatorDef.designatorClass, designatorDef);
resolvedDesignators.Insert(insertIndex + 1, designator);
designator.SetVisible(IsDesignatorEnabledInSettings(designatorDef));
activeDesignators.Add(new DesignatorEntry(designator, designatorDef.hotkeyDef));
@@ -185,16 +218,23 @@ private void InjectDesignators() {
private void PrepareReflection() {
ResolvedDesignatorsField = typeof(DesignationCategoryDef).GetField("resolvedDesignators", HugsLibUtility.AllBindingFlags);
ReverseDesignatorDatabaseDesListField = typeof(ReverseDesignatorDatabase).GetField("desList", HugsLibUtility.AllBindingFlags);
+ var gizmoGridType = GenTypes.GetTypeInAnyAssembly("RimWorld.InspectGizmoGrid");
+ if (gizmoGridType != null) {
+ GizmoGridGizmoListField = gizmoGridType.GetField("gizmoList", HugsLibUtility.AllBindingFlags);
+ }
if (ResolvedDesignatorsField == null || ResolvedDesignatorsField.FieldType != typeof(List)
- || ReverseDesignatorDatabaseDesListField == null || ReverseDesignatorDatabaseDesListField.FieldType != typeof(List)) {
+ || ReverseDesignatorDatabaseDesListField == null || ReverseDesignatorDatabaseDesListField.FieldType != typeof(List)
+ || GizmoGridGizmoListField == null || GizmoGridGizmoListField.FieldType != typeof(List)) {
Logger.Error("Failed to reflect required members");
}
}
+
+
private void CheckForHotkeyPresses() {
if (Event.current.keyCode == KeyCode.None) return;
if (AllowToolDefOf.ToolContextMenuAction.JustPressed) {
- DesignatorContextMenuController.DoContextMenuActionForActiveDesignator();
+ DesignatorContextMenuController.ProcessContextActionHotkeyPress();
}
if (!settingGlobalHotkeys || Find.VisibleMap == null) return;
for (int i = 0; i < activeDesignators.Count; i++) {
@@ -213,5 +253,11 @@ public DesignatorEntry(Designator_SelectableThings designator, KeyBindingDef key
this.key = key;
}
}
+
+ private bool GetToolHandleSettingValue(Dictionary> handleDict, string handleName) {
+ SettingHandle handle;
+ handleDict.TryGetValue(handleName, out handle);
+ return handle == null || handle.Value;
+ }
}
}
\ No newline at end of file
diff --git a/Source/AllowToolEarlyInit.cs b/Source/AllowToolEarlyInit.cs
index e91ff52..6ae401c 100644
--- a/Source/AllowToolEarlyInit.cs
+++ b/Source/AllowToolEarlyInit.cs
@@ -1,4 +1,5 @@
-using Harmony;
+using System;
+using Harmony;
using Verse;
namespace AllowTool {
@@ -7,8 +8,13 @@ namespace AllowTool {
///
public class AllowToolEarlyInit : Mod {
public AllowToolEarlyInit(ModContentPack content) : base(content) {
- AllowToolController.HarmonyInstance = HarmonyInstance.Create(AllowToolController.HarmonyInstanceId);
- AllowToolController.HarmonyInstance.PatchAll(typeof(AllowToolController).Assembly);
+ try {
+ AllowToolController.HarmonyInstance = HarmonyInstance.Create(AllowToolController.HarmonyInstanceId);
+ AllowToolController.HarmonyInstance.PatchAll(typeof(AllowToolController).Assembly);
+ } catch (Exception e) {
+ // Resharper disable once
+ Log.Error("AllowTool failed to apply Harmony patches: "+e);
+ }
}
}
}
\ No newline at end of file
diff --git a/Source/Context/BaseDesignatorMenuProvider.cs b/Source/Context/BaseDesignatorMenuProvider.cs
index 868e301..884e08f 100644
--- a/Source/Context/BaseDesignatorMenuProvider.cs
+++ b/Source/Context/BaseDesignatorMenuProvider.cs
@@ -13,8 +13,8 @@ namespace AllowTool.Context {
public abstract class BaseDesignatorMenuProvider {
protected delegate void MenuActionMethod(Designator designator, Map map);
- private const string SuccessMessageStringIdSuffix = "_succ";
- private const string FailureMessageStringIdSuffix = "_fail";
+ protected const string SuccessMessageStringIdSuffix = "_succ";
+ protected const string FailureMessageStringIdSuffix = "_fail";
// the toogle for this provider, assigned automatically by AllotToolController
public virtual SettingHandle ProviderHandle { get; set; }
diff --git a/Source/Context/DesignatorContextMenuController.cs b/Source/Context/DesignatorContextMenuController.cs
index 202c441..261158d 100644
--- a/Source/Context/DesignatorContextMenuController.cs
+++ b/Source/Context/DesignatorContextMenuController.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using HugsLib.Utils;
+using RimWorld;
using UnityEngine;
using Verse;
@@ -10,9 +12,29 @@ namespace AllowTool.Context {
/// Instantiates individual handlers, processess input events and draws overlay icons.
///
public static class DesignatorContextMenuController {
+ private enum MouseButtons {
+ Left = 0, Right = 1
+ }
+
private static readonly Dictionary designatorMenuProviders = new Dictionary();
- private static readonly List reverseDesignatorsForRemoval = new List();
+ private static readonly List> currentDrawnReverseDesignators = new List>();
private static readonly Vector2 overlayIconOffset = new Vector2(59f, 2f);
+ private static readonly HashSet reversePickingSupportedDesignators = new HashSet {
+ typeof(Designator_Cancel),
+ typeof(Designator_Claim),
+ typeof(Designator_Deconstruct),
+ typeof(Designator_Uninstall),
+ typeof(Designator_Haul),
+ typeof(Designator_Hunt),
+ typeof(Designator_Slaughter),
+ typeof(Designator_Tame),
+ typeof(Designator_PlantsCut),
+ typeof(Designator_PlantsHarvest),
+ typeof(Designator_Mine),
+ typeof(Designator_Strip),
+ typeof(Designator_RearmTrap),
+ typeof(Designator_Open)
+ };
private static List _providers;
public static List MenuProviderInstances {
@@ -59,11 +81,14 @@ public static void DrawCommandOverlayIfNeeded(Command gizmo, Vector2 topLeft) {
// try catch a right click on a supported designator. Left clicks should return false.
public static bool TryProcessDesignatorInput(Designator designator) {
try {
- if (Event.current.button != 1) return false;
- foreach (var provider in MenuProviderInstances) {
- if (provider.HandledDesignatorType.IsInstanceOfType(designator)) {
- provider.OpenContextMenu(designator);
- return true;
+ if (Event.current.button == (int)MouseButtons.Left && HugsLibUtility.ShiftIsHeld && AllowToolController.Instance.ReverseDesignatorPickSetting) {
+ return TryPickDesignatorFromReverseDesignator(designator);
+ } else if (Event.current.button == (int)MouseButtons.Right) {
+ foreach (var provider in MenuProviderInstances) {
+ if (provider.HandledDesignatorType.IsInstanceOfType(designator)) {
+ provider.OpenContextMenu(designator);
+ return true;
+ }
}
}
} catch (Exception e) {
@@ -72,20 +97,28 @@ public static bool TryProcessDesignatorInput(Designator designator) {
return false;
}
- // called when a designator is selected and the context action key is pressed
- public static void DoContextMenuActionForActiveDesignator() {
+ public static void ProcessContextActionHotkeyPress() {
var selectedDesignator = Find.DesignatorManager.SelectedDesignator;
- if (selectedDesignator == null || !designatorMenuProviders.ContainsKey(selectedDesignator)) return;
- designatorMenuProviders[selectedDesignator].HotkeyAction(selectedDesignator);
+ if (selectedDesignator != null && designatorMenuProviders.ContainsKey(selectedDesignator)) {
+ designatorMenuProviders[selectedDesignator].HotkeyAction(selectedDesignator);
+ } else if(AllowToolController.Instance.ExtendedContextActionSetting.Value) {
+ // activate hotkey action for first visible reverse designator
+ foreach (var pair in currentDrawnReverseDesignators) {
+ if (designatorMenuProviders.ContainsKey(pair.Key)) {
+ designatorMenuProviders[pair.Key].HotkeyAction(pair.Value);
+ break;
+ }
+ }
+ }
}
// called every OnGUI- Commands for reverse designators are instantiated each time they are drawn, so we need to discard the old ones
public static void ClearReverseDesignatorPairs() {
- if (reverseDesignatorsForRemoval.Count > 0) {
- foreach (var command in reverseDesignatorsForRemoval) {
- if (designatorMenuProviders.ContainsKey(command)) designatorMenuProviders.Remove(command);
+ if (currentDrawnReverseDesignators.Count > 0) {
+ foreach (var pair in currentDrawnReverseDesignators) {
+ if (designatorMenuProviders.ContainsKey(pair.Key)) designatorMenuProviders.Remove(pair.Key);
}
- reverseDesignatorsForRemoval.Clear();
+ currentDrawnReverseDesignators.Clear();
}
}
@@ -100,7 +133,7 @@ public static void RegisterReverseDesignatorPair(Designator designator, Command_
};
var providers = MenuProviderInstances;
TryBindDesignatorToHandler(designator, designatorButton, providers);
- reverseDesignatorsForRemoval.Add(designatorButton);
+ currentDrawnReverseDesignators.Add(new KeyValuePair(designatorButton, designator));
}
public static void CheckForMemoryLeak() {
@@ -110,6 +143,14 @@ public static void CheckForMemoryLeak() {
}
}
+ private static bool TryPickDesignatorFromReverseDesignator(Designator designator) {
+ if (designator is Designator_SelectableThings || (designator!=null && reversePickingSupportedDesignators.Contains(designator.GetType()))) {
+ Find.DesignatorManager.Select(designator);
+ return true;
+ }
+ return false;
+ }
+
private static List InstantiateProviders() {
var providers = new List();
try {
diff --git a/Source/Context/MenuProvider_HaulUrgently.cs b/Source/Context/MenuProvider_HaulUrgently.cs
index f3120c0..54832a1 100644
--- a/Source/Context/MenuProvider_HaulUrgently.cs
+++ b/Source/Context/MenuProvider_HaulUrgently.cs
@@ -34,14 +34,14 @@ public override void ContextMenuAction(Designator designator, Map map) {
// skip rock chunks in designation, select only visible on screen
private void HaulVisibleAction(Designator designator, Map map) {
var visibleRect = GetVisibleMapRect();
- DesignateWithPredicate(designator,map, thing => visibleRect.Contains(thing.Position));
+ DesignateWithPredicate(designator, map, thing => visibleRect.Contains(thing.Position), "Designator_context_urgent_visible_succ");
}
private void HaulEverythingAction(Designator designator, Map map) {
DesignateWithPredicate(designator, map);
}
- private void DesignateWithPredicate(Designator designator, Map map, Func shouldDesignateThing = null) {
+ private void DesignateWithPredicate(Designator designator, Map map, Func shouldDesignateThing = null, string successMessageKey = null) {
int hitCount = 0;
foreach (var thing in map.listerThings.ThingsInGroup(DesingatorRequestGroup)) {
if (ValidForDesignation(thing) &&
@@ -53,7 +53,14 @@ private void DesignateWithPredicate(Designator designator, Map map, Func 0) {
+ Messages.Message(successMessageKey.Translate(hitCount), MessageSound.Benefit);
+ } else {
+ Messages.Message((EntryTextKey + FailureMessageStringIdSuffix).Translate(), MessageSound.RejectInput);
+ }
}
// code swiped from ThingSelectionUtility
diff --git a/Source/Context/MenuProvider_SelectSimilar.cs b/Source/Context/MenuProvider_SelectSimilar.cs
index f1a867d..f0af4ab 100644
--- a/Source/Context/MenuProvider_SelectSimilar.cs
+++ b/Source/Context/MenuProvider_SelectSimilar.cs
@@ -21,7 +21,10 @@ public override Type HandledDesignatorType {
public override void ContextMenuAction(Designator designator, Map map) {
var des = (Designator_SelectSimilar) designator;
- des = des.GetNonReverseVersion();
+ var reverse = des as Designator_SelectSimilarReverse;
+ if (reverse != null) {
+ des = reverse.GetNonReverseVersion();
+ }
if (Find.Selector.NumSelected == 0) {
Messages.Message("Designator_context_similar_fail".Translate(), MessageSound.RejectInput);
return;
diff --git a/Source/Designators/Designator_SelectSimilar.cs b/Source/Designators/Designator_SelectSimilar.cs
index ba6aed3..2a7aecb 100644
--- a/Source/Designators/Designator_SelectSimilar.cs
+++ b/Source/Designators/Designator_SelectSimilar.cs
@@ -19,14 +19,8 @@ public class Designator_SelectSimilar : Designator_SelectableThings {
private const int MaxNumListedConstraints = 5;
private readonly Dictionary selectionConstraints = new Dictionary();
- private readonly bool reverseDesignatorMode;
private bool constraintsNeedReindexing;
private string readableConstraintList;
-
- private Selector selectorRef;
- private Selector Selector { // cache selector to avoid lots of unnecessary routing calls
- get { return selectorRef ?? (selectorRef = Find.Selector); }
- }
private int numDesignated;
public override int GetNumDesigantedThings() {
@@ -40,48 +34,24 @@ private bool AnySelectionContstraints {
public Designator_SelectSimilar(ThingDesignatorDef def) : base(def) {
}
- public Designator_SelectSimilar(ThingDesignatorDef def, bool reverseDesignatorMode) : base(def) {
- this.reverseDesignatorMode = reverseDesignatorMode;
- }
-
public override void Selected() {
base.Selected();
ReindexSelectionConstraints();
}
-
- // ensure we used the proper designator for the context action, that does not have its constraints removed
- public Designator_SelectSimilar GetNonReverseVersion() {
- return !reverseDesignatorMode ? this : (Designator_SelectSimilar) AllowToolController.Instance.TryGetDesignator(AllowToolDefOf.SelectSimilarDesignator);
- }
-
- // used by dragger and reverse designator. We want the reverse designator to always show, but ignoring constraints breaks the context action
+
public override AcceptanceReport CanDesignateThing(Thing thing) {
return thing.def != null &&
thing.def.selectable &&
thing.def.label != null &&
!BlockedByFog(thing.Position, thing.Map) &&
- (reverseDesignatorMode || ThingMatchesSelectionConstraints(thing) || AllowToolController.Instance.Dragger.SelectingSingleCell) && // this allows us to select items that don't match the selection conststraints if we are not dragging, only clicking
- (reverseDesignatorMode || SelectionLimitAllowsAdditionalThing());
+ (ThingMatchesSelectionConstraints(thing) || AllowToolController.Instance.Dragger.SelectingSingleCell) && // this allows us to select items that don't match the selection conststraints if we are not dragging, only clicking
+ SelectionLimitAllowsAdditionalThing();
}
public override void DesignateThing(Thing t) {
TrySelectThing(t);
}
- protected override void FinalizeDesignationSucceeded() {
- if (reverseDesignatorMode) {
- Log.Message("xx");
- // intercept call from the reverse designator button
- // activate the regualar select similar designator for the player to select more items
- var selectSimilarNonReverse = GetNonReverseVersion();
- if (Find.DesignatorManager.SelectedDesignator != selectSimilarNonReverse) {
- // debounce multiple selected items
- Find.DesignatorManager.Select(selectSimilarNonReverse);
- }
- }
- base.FinalizeDesignationSucceeded();
- }
-
public override void DesignateSingleCell(IntVec3 cell) {
var map = Find.VisibleMap;
var cellThings = map.thingGrid.ThingsListAtFast(cell);
@@ -118,18 +88,19 @@ public override void SelectedOnGUI() {
}
public bool SelectionLimitAllowsAdditionalThing() {
- return Selector.NumSelected < AllowToolController.Instance.SelectionLimitSetting.Value || AllowToolController.Instance.Dragger.SelectingSingleCell || HugsLibUtility.AltIsHeld;
+ return Find.Selector.NumSelected < AllowToolController.Instance.SelectionLimitSetting.Value || AllowToolController.Instance.Dragger.SelectingSingleCell || HugsLibUtility.AltIsHeld;
}
// generate an index of defs to compare other things against, based on currently selected things
public void ReindexSelectionConstraints() {
try {
+ var selector = Find.Selector;
constraintsNeedReindexing = false;
selectionConstraints.Clear();
readableConstraintList = "";
- if (Selector.NumSelected == 0) return;
+ if (selector.NumSelected == 0) return;
// get defs of selected objects, count duplicates
- foreach (var selectedObject in Selector.SelectedObjects) {
+ foreach (var selectedObject in selector.SelectedObjects) {
var thing = selectedObject as Thing;
if (thing == null || thing.def == null || !thing.def.selectable) continue;
int constraintHash = GetConstraintHashForThing(thing);
@@ -164,8 +135,9 @@ public void ReindexSelectionConstraints() {
}
public bool TrySelectThing(Thing thing) {
- if (!CanDesignateThing(thing).Accepted || Selector.IsSelected(thing)) return false;
- Selector.SelectedObjects.Add(thing); // manually adding objects to the selection list gets around the stock selection limit
+ var selector = Find.Selector;
+ if (!CanDesignateThing(thing).Accepted || selector.IsSelected(thing)) return false;
+ selector.SelectedObjects.Add(thing); // manually adding objects to the selection list gets around the stock selection limit
SelectionDrawer.Notify_Selected(thing);
if (!AnySelectionContstraints) {
ReindexSelectionConstraints();
@@ -177,7 +149,7 @@ public bool TrySelectThing(Thing thing) {
private void ProcessSingleCellClick(IntVec3 cell) {
if (!HugsLibUtility.ShiftIsHeld) {
- Selector.ClearSelection();
+ Find.Selector.ClearSelection();
ReindexSelectionConstraints();
}
if (cell.IsValid) {
@@ -195,9 +167,9 @@ private bool BlockedByFog(IntVec3 cell, Map map) {
return map.fogGrid.IsFogged(cell) && !DebugSettings.godMode;
}
- // close architect menu if anything wa selected
+ // close architect menu if anything was selected
private void TryCloseArchitectMenu() {
- if (Selector.NumSelected == 0) return;
+ if (Find.Selector.NumSelected == 0) return;
if (Find.MainTabsRoot.OpenTab != MainButtonDefOf.Architect) return;
Find.MainTabsRoot.EscapeCurrentTab();
}
diff --git a/Source/Patches/Designator_ProcessInput_Patch.cs b/Source/Patches/Designator_ProcessInput_Patch.cs
index 5816c9d..aa2a2d9 100644
--- a/Source/Patches/Designator_ProcessInput_Patch.cs
+++ b/Source/Patches/Designator_ProcessInput_Patch.cs
@@ -4,7 +4,7 @@
namespace AllowTool.Patches {
///
- /// Intercepts right clicks on supported designators, ignores other interactions
+ /// Intercepts right clicks and shift-left clicks on supported designators, ignores other interactions
///
[HarmonyPatch(typeof(Designator))]
[HarmonyPatch("ProcessInput")]
diff --git a/Source/Reverse/Designator_SelectSimilarReverse.cs b/Source/Reverse/Designator_SelectSimilarReverse.cs
new file mode 100644
index 0000000..a5e91d4
--- /dev/null
+++ b/Source/Reverse/Designator_SelectSimilarReverse.cs
@@ -0,0 +1,36 @@
+using System;
+using Verse;
+
+namespace AllowTool {
+ ///
+ /// A stub for use as a reverse designator.
+ /// We can't use the regular one, because the selection constraints mess with the visibility of the reverse designator.
+ /// Instead of designating, picks up the actual SelectSimilar designator.
+ ///
+ public class Designator_SelectSimilarReverse : Designator_SelectSimilar {
+ public Designator_SelectSimilarReverse(ThingDesignatorDef def) : base(def) {
+ }
+
+ public Designator_SelectSimilar GetNonReverseVersion() {
+ var des = (Designator_SelectSimilar) AllowToolController.Instance.TryGetDesignator(AllowToolDefOf.SelectSimilarDesignator);
+ if (des == null) {
+ throw new Exception("Could not get Designator_SelectSimilar from AllowToolController");
+ }
+ return des;
+ }
+
+ public override AcceptanceReport CanDesignateThing(Thing thing) {
+ return thing.def != null &&
+ thing.def.selectable &&
+ thing.def.label != null &&
+ thing.Map != null &&
+ !thing.Map.fogGrid.IsFogged(thing.Position);
+ }
+
+ protected override void FinalizeDesignationSucceeded() {
+ var selectSimilarNonReverse = GetNonReverseVersion();
+ Find.DesignatorManager.Select(selectSimilarNonReverse);
+ base.FinalizeDesignationSucceeded();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Reverse/ReverseDesignatorDef.cs b/Source/Reverse/ReverseDesignatorDef.cs
new file mode 100644
index 0000000..b21c304
--- /dev/null
+++ b/Source/Reverse/ReverseDesignatorDef.cs
@@ -0,0 +1,13 @@
+using System;
+using Verse;
+
+namespace AllowTool {
+ ///
+ /// Def for AllowTool designators to be used as reverse designators (designators shown on selected items).
+ /// These are automatically instantiated and injected.
+ ///
+ public class ReverseDesignatorDef : Def {
+ public ThingDesignatorDef designatorDef;
+ public Type designatorClass;
+ }
+}
\ No newline at end of file
diff --git a/Source/ReverseDesignatorProvider.cs b/Source/ReverseDesignatorProvider.cs
index a705f37..7c6bb1c 100644
--- a/Source/ReverseDesignatorProvider.cs
+++ b/Source/ReverseDesignatorProvider.cs
@@ -8,17 +8,13 @@ namespace AllowTool {
public static class ReverseDesignatorProvider {
public static void OnReverseDesignatorInit(ReverseDesignatorDatabase database) {
var designatorsList = (List)AllowToolController.ReverseDesignatorDatabaseDesListField.GetValue(database);
- if (AllowToolController.Instance.IsDesignatorEnabledInSettings(AllowToolDefOf.HaulUrgentlyDesignator)) {
- var haulUrgently = new Designator_HaulUrgently(AllowToolDefOf.HaulUrgentlyDesignator);
- if (Current.Game.Rules.DesignatorAllowed(haulUrgently)) {
- designatorsList.Add(haulUrgently);
- }
- }
- if (AllowToolController.Instance.IsDesignatorEnabledInSettings(AllowToolDefOf.SelectSimilarDesignator)) {
- var selectSimilar = new Designator_SelectSimilar(AllowToolDefOf.SelectSimilarDesignator, true);
- if (Current.Game.Rules.DesignatorAllowed(selectSimilar)) {
- designatorsList.Add(selectSimilar);
- }
+ foreach (var def in DefDatabase.AllDefs) {
+ if (AllowToolController.Instance.IsReverseDesignatorEnabledInSettings(def)) {
+ var des = AllowToolController.Instance.InstantiateDesignator(def.designatorClass, def.designatorDef);
+ if (Current.Game.Rules.DesignatorAllowed(des)) {
+ designatorsList.Add(des);
+ }
+ }
}
}
}