├── LICENSE ├── README.md ├── autoactions ├── AutoActionContainer.cs └── actions │ ├── AbstractAutoAction.cs │ ├── general │ └── AutoStartGame.cs │ ├── rift │ ├── AutoItemPickup.cs │ └── Potion.cs │ └── town │ ├── AcceptSalvageDialog.cs │ ├── AutoMainstat.cs │ ├── Kadala.cs │ ├── OpenRift.cs │ └── SalvageYBW.cs ├── forms ├── Settings.Designer.cs ├── Settings.cs ├── Settings.resx ├── autoaction │ ├── AutoActionEditor.Designer.cs │ ├── AutoActionEditor.cs │ └── AutoActionEditor.resx ├── definitions │ ├── AddMasterProfile.Designer.cs │ ├── AddMasterProfile.cs │ ├── AddMasterProfile.resx │ ├── DefinitionEditor.Designer.cs │ ├── DefinitionEditor.cs │ ├── DefinitionEditor.resx │ ├── DefinitionGroupEditor.Designer.cs │ ├── DefinitionGroupEditor.cs │ └── DefinitionGroupEditor.resx └── hotkeys │ ├── HotkeyEditor.Designer.cs │ ├── HotkeyEditor.cs │ ├── HotkeyEditor.resx │ ├── HotkeyPopup.Designer.cs │ ├── HotkeyPopup.cs │ └── HotkeyPopup.resx ├── hotkeys ├── HotkeyContainer.cs ├── HotkeyType.cs └── actions │ ├── AbstractHotkeyAction.cs │ ├── general │ ├── LeaveGame.cs │ └── LowerDifficulty.cs │ ├── settings │ ├── ToggleActive.cs │ ├── ToggleActivePowerOverlay.cs │ ├── ToggleLeftSkill.cs │ ├── ToggleRightSkill.cs │ ├── ToggleSkill1.cs │ ├── ToggleSkill2.cs │ ├── ToggleSkill3.cs │ └── ToggleSkill4.cs │ └── teleport │ ├── Act1.cs │ ├── Act2.cs │ ├── Act3.cs │ ├── Act4.cs │ └── Act5.cs ├── pHelper.cs ├── parameters ├── AbstractParameter.cs ├── ParameterType.cs └── types │ ├── ContextParameter.cs │ └── SimpleParameter.cs ├── resource ├── donate.jpg └── icon.ico ├── skills ├── DefinitionGroup.cs ├── DefinitionGroupsForSkill.cs ├── SkillExecutor.cs ├── SnoPowerList.cs ├── castactions │ ├── AbstractCastAction.cs │ └── actions │ │ └── DefaultCastAction.cs ├── definitions │ ├── AbstractDefinition.cs │ ├── DefinitionType.cs │ ├── itemspecific │ │ ├── CoeRotation.cs │ │ └── CoeRotationOnHeroClass.cs │ ├── party │ │ ├── AllPartyMembersInRange.cs │ │ ├── AllPlayersAlive.cs │ │ ├── BuffStacksOnHeroClass.cs │ │ ├── BuffTimeLeftOnHeroClass.cs │ │ ├── HeroClassCountInParty.cs │ │ ├── HeroClassHasSkillEquipped.cs │ │ ├── IsBuffActiveOnHeroClass.cs │ │ ├── IsSkillBuffActiveOnHeroClass.cs │ │ ├── PartyIsBuffable.cs │ │ └── PlayerCountInParty.cs │ ├── player │ │ ├── BuffStacks.cs │ │ ├── BuffTimeLeft.cs │ │ ├── CoolExampleDefinitionType.cs │ │ ├── CurrentAnimationState.cs │ │ ├── EliteInFocus.cs │ │ ├── HasSkillEquipped.cs │ │ ├── IsBuffActive.cs │ │ ├── IsSkillBuffActive.cs │ │ ├── MinimumHealthPercent.cs │ │ └── MinimumResource.cs │ ├── skill │ │ ├── ForceCastInterval.cs │ │ ├── HasRuneEquipped.cs │ │ └── MinimumResourcePercent.cs │ └── world │ │ ├── BossSpawned.cs │ │ ├── CorpsesInRange.cs │ │ ├── CurrentSpecialArea.cs │ │ ├── EliteInRange.cs │ │ └── MonstersInRange.cs └── util │ └── CompareWithOperator.cs └── util ├── Misc.cs ├── config ├── ConfigPersistence.cs └── jsonconverter │ ├── AutoActionConverter.cs │ ├── CastActionConverter.cs │ ├── DefinitionConverter.cs │ └── HotkeyConverter.cs ├── diablo ├── D3Client.cs └── UiPathConstants.cs ├── executors ├── ThreadedExecutor.cs └── TimedRetryExecutor.cs ├── input ├── InputSimulator.cs └── InputUtil.cs ├── logger ├── LogLevel.cs └── Logger.cs ├── thud ├── ActivePowerOverlay.cs ├── MethodExtensions.cs └── RenderControllerMethodExtensions.cs └── winformutil ├── ControlHelper.cs └── DgvFormUtil.cs /README.md: -------------------------------------------------------------------------------- 1 | # pHelperPlugin for TurboHUD! 2 | 3 | ## This is heavy WIP and might still contain bugs! 4 | 5 | ## Usage 6 | 7 | To use this plugin, either clone or download and copy into `TurboHUD/plugins/patrick`.\ 8 | Currently no preconfigured definitions exist, but it should not be much of an effort to add your own.\ 9 | 10 | ## Definitions 11 | 12 | This helper uses a plugin based definition type system. To add definition types check existing examples in `skills/definitions`. Classes which inherit from `AbstractDefinition.cs` will automatically be added to the UI. 13 | 14 | ## Hotkeys / AutoActions 15 | 16 | Works the same way as definitions. Inherit from `hotkeys/actions/AbstractHotkeyAction.cs` or `autoactions/actions/AbstractAutoAction.cs`. 17 | 18 | ## Known Bugs / Issues 19 | - Some weird exception randomly thrown in TurboHUD. Can't replicate and can't catch it 20 | - Some ComboBox settings are not set properly when editing a definition 21 | 22 | ## Bugs / Feature Requests / Feedback / Donations 23 | 24 | To report bugs/weird behavior or just have a feature request, just [create an issue](https://github.com/petikk/pHelperPlugin/issues/new) and I will answer asap.\ 25 | If there's any questions you would like to directly discuss with me, you can message me on Discord: `patrick#7777` or [join my discord server](https://discord.gg/8fRxTDM66q) 26 | 27 | If you'd like to support my work you can donate here and buy me a coffee, I'd really appreciate that:\ 28 | [![](https://i.imgur.com/qHzwSC7.png)](https://www.buymeacoffee.com/phelper) 29 | 30 | ## Contribute 31 | 32 | I am very happy if you'd like to contribute! Just open a PR and I will check it out asap :) 33 | -------------------------------------------------------------------------------- /autoactions/AutoActionContainer.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.Plugins.Patrick.autoactions 2 | { 3 | using System.Collections.Generic; 4 | using Newtonsoft.Json; 5 | using plugins.patrick.autoactions.actions; 6 | using plugins.patrick.util.executors; 7 | using util.config.jsonconverter; 8 | 9 | public class AutoActionContainer 10 | { 11 | [JsonProperty(ItemConverterType = typeof(AutoActionConverter))] 12 | public List autoActions; 13 | 14 | [JsonIgnore] private readonly ThreadedExecutor executor = new ThreadedExecutor(); 15 | 16 | public AutoActionContainer() 17 | { 18 | autoActions = new List(); 19 | } 20 | 21 | public AutoActionContainer(List autoActions) 22 | { 23 | this.autoActions = autoActions; 24 | } 25 | 26 | public void ExecuteAutoActions(IController hud) 27 | { 28 | autoActions.ForEach(action => 29 | { 30 | if (!action.active || !action.Applicable(hud)) 31 | return; 32 | 33 | executor.Execute(() => action.Invoke(hud), action.GetType().ToString(), action.minimumExecutionDelta); 34 | }); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /autoactions/actions/AbstractAutoAction.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.autoactions.actions 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using Newtonsoft.Json; 7 | using parameters; 8 | using Plugins; 9 | using Plugins.Patrick.util; 10 | 11 | public abstract class AbstractAutoAction 12 | { 13 | public static readonly List AutoActionTypes = Misc.GetAllSubTypesFromType(typeof(AbstractAutoAction)); 14 | 15 | public bool active { get; set; } 16 | 17 | [JsonIgnore] public string action { get { return GetType().Name; } } 18 | 19 | [JsonIgnore] public string attributes { get { return GetAttributes(); } } 20 | 21 | [JsonIgnore] 22 | [Browsable(false)] 23 | public virtual long minimumExecutionDelta => 1000; 24 | 25 | [JsonIgnore] [Browsable(false)] public virtual string tooltip => "No tooltip available for this auto action!"; 26 | 27 | public abstract string GetAttributes(); 28 | 29 | public abstract List GetParameters(); 30 | 31 | public abstract bool Applicable(IController hud); 32 | 33 | public abstract void Invoke(IController hud); 34 | } 35 | } -------------------------------------------------------------------------------- /autoactions/actions/general/AutoStartGame.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.autoactions.actions.town 2 | { 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using parameters; 6 | using Plugins; 7 | using util.diablo; 8 | using util.thud; 9 | 10 | public class AutoStartGame : AbstractAutoAction 11 | { 12 | public override string tooltip => "Automatically starts game in the lobby."; 13 | 14 | public override string GetAttributes() => ""; 15 | 16 | public override long minimumExecutionDelta => 500; 17 | 18 | public override List GetParameters() 19 | { 20 | return new List(); 21 | } 22 | 23 | public override bool Applicable(IController hud) 24 | { 25 | return !hud.Game.IsInGame 26 | && !hud.Game.IsLoading 27 | && hud.Render.IsUiElementVisible(UiPathConstants.Buttons.START_GAME) 28 | && hud.Render.GetUiElement(UiPathConstants.Buttons.START_GAME) 29 | .ReadText(Encoding.ASCII, true).Contains("Start"); 30 | } 31 | 32 | public override void Invoke(IController hud) 33 | { 34 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Buttons.START_GAME); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /autoactions/actions/rift/AutoItemPickup.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.autoactions.actions.rift 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using System.Linq; 7 | using Newtonsoft.Json; 8 | using parameters.types; 9 | using parameters; 10 | using Plugins; 11 | using util.thud; 12 | 13 | public class AutoItemPickup : AbstractAutoAction 14 | { 15 | public bool CraftingMats { get; set; } 16 | 17 | public bool Legendaries { get; set; } 18 | 19 | public bool Jewels { get; set; } 20 | 21 | public int PickupRange { get; set; } = 10; 22 | 23 | [JsonIgnore] 24 | [Browsable(false)] 25 | private static readonly HashSet ItemPickitSet = new HashSet 26 | { 27 | 2087837753, // Death's Breath 28 | 2709165134, // Arcane Dust 29 | 3689019703, // Veiled Crystal 30 | 3931359676, // Reusable Parts 31 | 2835237830, // Greater Rift Keystone 32 | 2073430088 // Forgotten Soul 33 | }; 34 | 35 | [JsonIgnore] 36 | [Browsable(false)] 37 | private bool twoUnitSlotAvailable = true; 38 | 39 | public override string tooltip => "Automatically picks up configured items."; 40 | 41 | public override string GetAttributes() 42 | { 43 | return $"[ {nameof(CraftingMats)}: {CraftingMats}, {nameof(Legendaries)}: {Legendaries}, {nameof(PickupRange)}: {PickupRange} ]"; 44 | } 45 | 46 | public override long minimumExecutionDelta => 64; 47 | 48 | public override List GetParameters() 49 | { 50 | return new List 51 | { 52 | SimpleParameter.of(nameof(CraftingMats), x => CraftingMats = x), 53 | SimpleParameter.of(nameof(Legendaries), x => Legendaries = x), 54 | SimpleParameter.of(nameof(Jewels), x => Jewels = x), 55 | SimpleParameter.of(nameof(PickupRange), x => PickupRange = x), 56 | }; 57 | } 58 | 59 | public override bool Applicable(IController hud) 60 | { 61 | CheckInventorySpace(hud); 62 | 63 | return hud.Game.Me.IsInGame && !hud.Game.Me.IsDead && hud.Game.Items.ToList().Any(item => item.CentralXyDistanceToMe < PickupRange && !item.AccountBound && !item.SeenInInventory); 64 | } 65 | 66 | public override void Invoke(IController hud) 67 | { 68 | hud.Game.Items.ToList() 69 | .Where(x => x.Location == ItemLocation.Floor && Matches(x) && x.CentralXyDistanceToMe < PickupRange && !x.AccountBound && !x.SeenInInventory) 70 | .OrderBy(x => x.CentralXyDistanceToMe) 71 | .FirstOrDefault(item => !item.IsLegendary || (item.SnoItem.ItemHeight == 1 && hud.Game.Me.InventorySpaceTotal - hud.Game.InventorySpaceUsed > 1) || twoUnitSlotAvailable)?.Click(); 72 | } 73 | 74 | private bool Matches(IItem item) 75 | { 76 | var matches = false; 77 | 78 | if (CraftingMats) 79 | matches |= ItemPickitSet.Contains(item.SnoItem.Sno); 80 | 81 | if (Legendaries) 82 | matches |= item.IsLegendary; 83 | 84 | if (Jewels) 85 | matches |= item.SnoItem.Kind == ItemKind.gem; 86 | 87 | return matches; 88 | } 89 | 90 | private void CheckInventorySpace(IController hud) 91 | { 92 | if (!Legendaries || (hud.Game.Me.InventorySpaceTotal - hud.Game.InventorySpaceUsed > 30)) 93 | { 94 | twoUnitSlotAvailable = true; 95 | return; 96 | } 97 | 98 | var inventoryCoords = new Dictionary>(); 99 | hud.Inventory.ItemsInInventory.ToList().ForEach(item => 100 | { 101 | if (inventoryCoords.ContainsKey(item.InventoryX)) 102 | inventoryCoords[item.InventoryX].Add(item.InventoryY); 103 | else 104 | inventoryCoords.Add(item.InventoryX, new List{item.InventoryY}); 105 | 106 | if (item.SnoItem.ItemHeight == 2) 107 | inventoryCoords[item.InventoryX].Add(item.InventoryY + 1); 108 | }); 109 | 110 | twoUnitSlotAvailable = inventoryCoords.Count < 10; 111 | 112 | if (!twoUnitSlotAvailable) 113 | twoUnitSlotAvailable = inventoryCoords.Any(item => 114 | { 115 | for (var i = 0; i < 5; i++) 116 | if (!item.Value.Contains(i) && !item.Value.Contains(i + 1)) 117 | return true; 118 | 119 | return false; 120 | }); 121 | } 122 | } 123 | } -------------------------------------------------------------------------------- /autoactions/actions/rift/Potion.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.autoactions.actions.rift 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using parameters.types; 6 | using Plugins; 7 | using util.thud; 8 | 9 | public class Potion : AbstractAutoAction 10 | { 11 | public int HealthPercent { get; set; } = 40; 12 | 13 | public override string GetAttributes() => $"[ HealthPercent: {HealthPercent} ]"; 14 | 15 | public override List GetParameters() 16 | { 17 | return new List 18 | { 19 | SimpleParameter.of(nameof(HealthPercent), x => HealthPercent = x) 20 | }; 21 | } 22 | 23 | public override bool Applicable(IController hud) 24 | { 25 | var shouldHeal = hud.Game.IsInGame 26 | && !hud.Game.IsInTown 27 | && !hud.Game.IsLoading 28 | && hud.Game.MapMode == MapMode.Minimap 29 | && !hud.Game.Me.IsDead 30 | && hud.Game.Me.AnimationState != AcdAnimationState.CastingPortal; 31 | 32 | return shouldHeal && !hud.Game.Me.Powers.HealthPotionSkill.IsOnCooldown && hud.Game.Me.Defense.HealthPct <= HealthPercent; 33 | } 34 | 35 | public override void Invoke(IController hud) 36 | { 37 | hud.Game.Me.Powers.HealthPotionSkill.Cast(); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /autoactions/actions/town/AcceptSalvageDialog.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.autoactions.actions.town 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using Plugins; 6 | using util.diablo; 7 | using util.thud; 8 | 9 | public class AcceptSalvageDialog : AbstractAutoAction 10 | { 11 | public override string tooltip => "CAREFUL! Will automatically accept blacksmith's salvage dialog."; 12 | 13 | public override string GetAttributes() => ""; 14 | 15 | public override long minimumExecutionDelta => 72; 16 | 17 | public override List GetParameters() 18 | { 19 | return new List(); 20 | } 21 | 22 | public override bool Applicable(IController hud) 23 | { 24 | if (!hud.Game.Me.IsInTown || !hud.Render.IsUiElementVisible(UiPathConstants.Blacksmith.SALVAGE_DIALOG)) 25 | return false; 26 | 27 | var anvil = hud.Render.GetOrRegisterAndGetUiElement(UiPathConstants.Blacksmith.ANVIL); 28 | if (anvil == null || !anvil.Visible) 29 | return false; 30 | 31 | return anvil.AnimState > 10; 32 | } 33 | 34 | public override void Invoke(IController hud) 35 | { 36 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Blacksmith.SALVAGE_DIALOG_OK, 250); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /autoactions/actions/town/AutoMainstat.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.autoactions.actions.town 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Windows.Forms; 6 | using Turbo.plugins.patrick.util.input; 7 | using parameters; 8 | using parameters.types; 9 | using Plugins; 10 | using util.diablo; 11 | using util.thud; 12 | 13 | public class AutoMainstat : AbstractAutoAction 14 | { 15 | public bool Vitality { get; set; } 16 | 17 | public override string tooltip => "Automatically assigns mainstat in town."; 18 | 19 | public override string GetAttributes() => $"[ Vitality: {Vitality}]"; 20 | 21 | public override List GetParameters() 22 | { 23 | return new List 24 | { 25 | SimpleParameter.of(nameof(Vitality), x => Vitality = x) 26 | }; 27 | } 28 | 29 | public override bool Applicable(IController hud) 30 | { 31 | return hud.Game.IsInTown 32 | && hud.Render.IsUiElementVisible(UiPathConstants.Paragon.NEW_PARAGON_BUTTON) 33 | && !hud.Render.IsUiElementVisible(UiPathConstants.Dialogs.QUEST_COMPLETED) 34 | && !hud.Render.IsUiElementVisible(UiPathConstants.Dialogs.HORADRIC_CACHE) 35 | && !hud.Render.IsUiElementVisible(UiPathConstants.Dialogs.GREATER_RIFT_COMPLETED) 36 | && !hud.Render.IsUiElementVisible(UiPathConstants.Dialogs.GREATER_RIFT_INVITE); 37 | } 38 | 39 | public override void Invoke(IController hud) 40 | { 41 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Paragon.NEW_PARAGON_BUTTON); 42 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Paragon.PARAGON_TAB_CORE); 43 | var paragonAvailable = Double.Parse(hud.Render.GetUiElement(UiPathConstants.Paragon.PARAGON_UNSPENT_CORE).ReadText(System.Text.Encoding.ASCII, true)); 44 | var amountOfClicks = (int) Math.Ceiling(paragonAvailable / 100); 45 | 46 | if (amountOfClicks == 0) 47 | { 48 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Paragon.PARAGON_BUTTON_CLOSE); 49 | } 50 | 51 | InputSimulator.PostMessageKeyDown(Keys.ControlKey); 52 | for (int i = 0; i < amountOfClicks; i++) 53 | { 54 | if (Vitality) 55 | { 56 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Paragon.PARAGON_BUTTON_SECOND); 57 | } 58 | else 59 | { 60 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Paragon.PARAGON_BUTTON_FIRST); 61 | } 62 | } 63 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Paragon.PARAGON_BUTTON_ACCEPT); 64 | //Call keyUp after closing the interface because it can block the accept button click going through 65 | InputSimulator.PostMessageKeyUp(Keys.ControlKey); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /autoactions/actions/town/Kadala.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.autoactions.actions.town 2 | { 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using parameters; 6 | using parameters.types; 7 | using Plugins; 8 | using util.diablo; 9 | using util.thud; 10 | 11 | public class Kadala : AbstractAutoAction 12 | { 13 | private const string BIG = "BIG"; 14 | 15 | private static readonly Dictionary ItemLocationMapping = new Dictionary 16 | { 17 | {"1-H Weapon", new[] {UiPathConstants.Vendor.FIRST_ITEM, UiPathConstants.Vendor.FIRST_TAB, BIG}}, 18 | {"2-H Weapon", new[] {UiPathConstants.Vendor.SECOND_ITEM, UiPathConstants.Vendor.FIRST_TAB, BIG}}, 19 | {"Quiver", new[] {UiPathConstants.Vendor.THIRD_ITEM, UiPathConstants.Vendor.FIRST_TAB, BIG}}, 20 | {"Orb", new[] {UiPathConstants.Vendor.FOURTH_ITEM, UiPathConstants.Vendor.FIRST_TAB, BIG}}, 21 | {"Mojo", new[] {UiPathConstants.Vendor.FIFTH_ITEM, UiPathConstants.Vendor.FIRST_TAB, BIG}}, 22 | {"Phylactery", new[] {UiPathConstants.Vendor.SIXTH_ITEM, UiPathConstants.Vendor.FIRST_TAB, BIG}}, 23 | {"Helm", new[] {UiPathConstants.Vendor.FIRST_ITEM, UiPathConstants.Vendor.SECOND_TAB, BIG}}, 24 | {"Gloves", new[] {UiPathConstants.Vendor.SECOND_ITEM, UiPathConstants.Vendor.SECOND_TAB, BIG}}, 25 | {"Boots", new[] {UiPathConstants.Vendor.THIRD_ITEM, UiPathConstants.Vendor.SECOND_TAB, BIG}}, 26 | {"Chest Armor", new[] {UiPathConstants.Vendor.FOURTH_ITEM, UiPathConstants.Vendor.SECOND_TAB, BIG}}, 27 | {"Belt", new[] {UiPathConstants.Vendor.FIFTH_ITEM, UiPathConstants.Vendor.SECOND_TAB, null}}, 28 | {"Shoulders", new[] {UiPathConstants.Vendor.SIXTH_ITEM, UiPathConstants.Vendor.SECOND_TAB, BIG}}, 29 | {"Pants", new[] {UiPathConstants.Vendor.SEVENTH_ITEM, UiPathConstants.Vendor.SECOND_TAB, BIG}}, 30 | {"Bracers", new[] {UiPathConstants.Vendor.EIGHTH_ITEM, UiPathConstants.Vendor.SECOND_TAB, BIG}}, 31 | {"Shield", new[] {UiPathConstants.Vendor.NINTH_ITEM, UiPathConstants.Vendor.SECOND_TAB, BIG}}, 32 | {"Ring", new[] {UiPathConstants.Vendor.FIRST_ITEM, UiPathConstants.Vendor.THIRD_TAB, null}}, 33 | {"Amulet", new[] {UiPathConstants.Vendor.SECOND_ITEM, UiPathConstants.Vendor.THIRD_TAB, null}} 34 | }; 35 | 36 | public string Item { get; set; } = "1-H Weapon"; 37 | 38 | public override string tooltip => "Auto gamble items at Kadala."; 39 | 40 | public override string GetAttributes() => $"[ Item: {Item} ]"; 41 | 42 | public override List GetParameters() 43 | { 44 | return new List 45 | { 46 | ContextParameter.of( 47 | nameof(Item), 48 | x => Item = (string) x, 49 | ItemLocationMapping.Keys 50 | ), 51 | }; 52 | } 53 | 54 | public override bool Applicable(IController hud) 55 | { 56 | return hud.Game.Me.IsInTown 57 | && hud.Render.IsShopOpen() 58 | && hud.Render.GetUiElement(UiPathConstants.Vendor.CURRENCY_TYPE) 59 | .ReadText(Encoding.ASCII, true).Contains("icon:x1_shard"); 60 | } 61 | 62 | //Since a user can close the Kadala interface unexpectedly we check before each action if the shop is still open 63 | //if not we return early, this is to prevent randomly moving the user's character around 64 | public override void Invoke(IController hud) 65 | { 66 | //Sometimes it doesnt properly register the first click, double clicking just to be sure prevents any accidental buys 67 | var itemLocation = ItemLocationMapping[Item]; 68 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(itemLocation[1]); 69 | hud.Render.GetOrRegisterAndGetUiElement(itemLocation[1]).Click(); 70 | 71 | var maxItems = 120; 72 | 73 | hud.Render.WaitForVisiblityAndRightClickOrAbortHotkeyEvent(itemLocation[0]); 74 | for (var i = 0; i < --maxItems; i++) 75 | { 76 | if (!hud.Render.IsShopOpen()) 77 | return; 78 | hud.Render.GetOrRegisterAndGetUiElement(itemLocation[0]).RightClick(); 79 | } 80 | 81 | if (hud.Render.IsShopOpen()) 82 | hud.Render.GetOrRegisterAndGetUiElement(UiPathConstants.Vendor.CLOSE_BUTTON).Click(); 83 | 84 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Buttons.INVENTORY); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /autoactions/actions/town/OpenRift.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.autoactions.actions.town 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using parameters.types; 6 | using Plugins; 7 | using util.diablo; 8 | using util.thud; 9 | 10 | public class OpenRift : AbstractAutoAction 11 | { 12 | public bool GreaterRift { get; set; } 13 | 14 | public bool Empowered { get; set; } 15 | 16 | public override string tooltip => "Automatically opens a rift when clicking on the obelisk."; 17 | 18 | public override string GetAttributes() => $"[ GreaterRift: {GreaterRift}, Empowered: {Empowered} ]"; 19 | 20 | public override List GetParameters() 21 | { 22 | return new List 23 | { 24 | SimpleParameter.of(nameof(GreaterRift), x => GreaterRift = x), 25 | SimpleParameter.of(nameof(Empowered), x => Empowered = x), 26 | }; 27 | } 28 | 29 | public override bool Applicable(IController hud) 30 | { 31 | return hud.Game.IsInTown && hud.Render.IsUiElementVisible(UiPathConstants.RiftObelisk.OBELISK_WINDOW); 32 | } 33 | 34 | public override void Invoke(IController hud) 35 | { 36 | if (!GreaterRift) 37 | { 38 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.RiftObelisk.NORMAL_RIFT_BUTTON); 39 | } 40 | else 41 | { 42 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.RiftObelisk.GREATER_RIFT_BUTTON); 43 | 44 | var empoweredCheckbox = hud.Render.GetOrRegisterAndGetUiElement(UiPathConstants.RiftObelisk.EMPOWERED_CHECKBOX); 45 | var animState = empoweredCheckbox.AnimState; 46 | if ((animState < 7) != Empowered) 47 | empoweredCheckbox.Click(); 48 | 49 | RenderControllerFunctions.WaitForConditionOrAbortHotkeyEvent(() => empoweredCheckbox.AnimState != animState, 1000, 100); 50 | } 51 | 52 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.RiftObelisk.ACCEPT_BUTTON); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /autoactions/actions/town/SalvageYBW.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.autoactions.actions.town 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading; 7 | using parameters; 8 | using parameters.types; 9 | using Plugins; 10 | using util.diablo; 11 | using util.thud; 12 | 13 | public class SalvageYBW : AbstractAutoAction 14 | { 15 | public bool Yellows { get; set; } 16 | 17 | public bool Blues { get; set; } 18 | 19 | public bool Whites { get; set; } 20 | 21 | private bool hasSalvaged; 22 | 23 | public override string tooltip => "Automatically salvages Yellow/Blue/White items when visiting the blacksmith"; 24 | 25 | public override long minimumExecutionDelta => 2000; 26 | 27 | public override string GetAttributes() => $"[ Yellows: {Yellows}, Blues: {Blues}, Whites: {Whites} ]"; 28 | 29 | public override List GetParameters() 30 | { 31 | return new List 32 | { 33 | SimpleParameter.of(nameof(Yellows), x => Yellows = x), 34 | SimpleParameter.of(nameof(Blues), x => Blues = x), 35 | SimpleParameter.of(nameof(Whites), x => Whites = x) 36 | }; 37 | } 38 | 39 | public override bool Applicable(IController hud) 40 | { 41 | if (!hud.Game.IsInTown) 42 | return false; 43 | 44 | var blacksmithOpen = hud.Render.IsUiElementVisible(UiPathConstants.Blacksmith.UNIQUE_PAGE); 45 | if (!blacksmithOpen) 46 | hasSalvaged = false; 47 | 48 | return blacksmithOpen; 49 | } 50 | 51 | public override void Invoke(IController hud) 52 | { 53 | if (hasSalvaged) 54 | return; 55 | 56 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Blacksmith.SALVAGE_PAGE, 500); 57 | 58 | if (Yellows && hud.Inventory.ItemsInInventory.ToList().Any(x => x.IsRare)) 59 | { 60 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Blacksmith.SALVAGE_RARE, 500); 61 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Blacksmith.SALVAGE_DIALOG_OK, 500); 62 | } 63 | if (Blues && hud.Inventory.ItemsInInventory.ToList().Any(x => x.IsMagic)) 64 | { 65 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Blacksmith.SALVAGE_BLUE, 500); 66 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Blacksmith.SALVAGE_DIALOG_OK, 500); 67 | } 68 | if (Whites && hud.Inventory.ItemsInInventory.ToList().Any(x => x.IsNormal && x.SnoItem.Kind == ItemKind.loot)) 69 | { 70 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Blacksmith.SALVAGE_WHITE, 500); 71 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Blacksmith.SALVAGE_DIALOG_OK, 500); 72 | } 73 | 74 | hasSalvaged = true; 75 | 76 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Blacksmith.ANVIL); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /forms/Settings.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /forms/autoaction/AutoActionEditor.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.forms.autoaction 2 | { 3 | using System.ComponentModel; 4 | 5 | partial class AutoActionEditor 6 | { 7 | /// 8 | /// Required designer variable. 9 | /// 10 | private IContainer components = null; 11 | 12 | /// 13 | /// Clean up any resources being used. 14 | /// 15 | /// true if managed resources should be disposed; otherwise, false. 16 | protected override void Dispose(bool disposing) 17 | { 18 | if (disposing && (components != null)) 19 | { 20 | components.Dispose(); 21 | } 22 | 23 | base.Dispose(disposing); 24 | } 25 | 26 | #region Windows Form Designer generated code 27 | 28 | /// 29 | /// Required method for Designer support - do not modify 30 | /// the contents of this method with the code editor. 31 | /// 32 | private void InitializeComponent() 33 | { 34 | this.b_Save = new System.Windows.Forms.Button(); 35 | this.b_Cancel = new System.Windows.Forms.Button(); 36 | this.l_AutoActionName = new System.Windows.Forms.Label(); 37 | this.SuspendLayout(); 38 | // 39 | // b_Save 40 | // 41 | this.b_Save.Location = new System.Drawing.Point(175, 90); 42 | this.b_Save.Name = "b_Save"; 43 | this.b_Save.Size = new System.Drawing.Size(94, 40); 44 | this.b_Save.TabIndex = 7; 45 | this.b_Save.Text = "Save"; 46 | this.b_Save.UseVisualStyleBackColor = true; 47 | this.b_Save.Click += new System.EventHandler(this.b_Save_Click); 48 | // 49 | // b_Cancel 50 | // 51 | this.b_Cancel.Location = new System.Drawing.Point(284, 90); 52 | this.b_Cancel.Name = "b_Cancel"; 53 | this.b_Cancel.Size = new System.Drawing.Size(94, 40); 54 | this.b_Cancel.TabIndex = 6; 55 | this.b_Cancel.Text = "Cancel"; 56 | this.b_Cancel.UseVisualStyleBackColor = true; 57 | this.b_Cancel.Click += new System.EventHandler(this.b_Cancel_Click); 58 | // 59 | // l_AutoActionName 60 | // 61 | this.l_AutoActionName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte) (0))); 62 | this.l_AutoActionName.Location = new System.Drawing.Point(24, 9); 63 | this.l_AutoActionName.Name = "l_AutoActionName"; 64 | this.l_AutoActionName.Size = new System.Drawing.Size(343, 49); 65 | this.l_AutoActionName.TabIndex = 8; 66 | this.l_AutoActionName.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 67 | // 68 | // AutoActionEditor 69 | // 70 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 71 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 72 | this.ClientSize = new System.Drawing.Size(390, 142); 73 | this.Controls.Add(this.l_AutoActionName); 74 | this.Controls.Add(this.b_Save); 75 | this.Controls.Add(this.b_Cancel); 76 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D; 77 | this.Name = "AutoActionEditor"; 78 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 79 | this.Text = "AutoActionEditor"; 80 | this.ResumeLayout(false); 81 | } 82 | 83 | private System.Windows.Forms.Button b_Cancel; 84 | private System.Windows.Forms.Button b_Save; 85 | private System.Windows.Forms.Label l_AutoActionName; 86 | 87 | #endregion 88 | } 89 | } -------------------------------------------------------------------------------- /forms/autoaction/AutoActionEditor.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.forms.autoaction 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Windows.Forms; 8 | using autoactions.actions; 9 | using parameters; 10 | using Plugins.Patrick.autoactions; 11 | using Plugins.Patrick.util.winformutil; 12 | 13 | public partial class AutoActionEditor : Form 14 | { 15 | private readonly AbstractAutoAction autoAction; 16 | 17 | private List parameters; 18 | 19 | private readonly List addedControls = new List(); 20 | 21 | private bool modified; 22 | 23 | private int yOffset; 24 | 25 | private AutoActionEditor(AbstractAutoAction autoAction) 26 | { 27 | InitializeComponent(); 28 | Icon = Icon.ExtractAssociatedIcon(@"plugins\patrick\resource\icon.ico"); 29 | 30 | this.autoAction = autoAction; 31 | LoadExistingAutoAction(); 32 | } 33 | 34 | public static bool EditAutoAction(AbstractAutoAction autoAction) 35 | { 36 | var autoActionEditor = new AutoActionEditor(autoAction) {Text = "AutoActionEditor - " + autoAction.action}; 37 | autoActionEditor.ShowDialog(); 38 | 39 | return autoActionEditor.modified; 40 | } 41 | 42 | private void LoadExistingAutoAction() 43 | { 44 | l_AutoActionName.Text = autoAction.action; 45 | parameters = autoAction.GetParameters(); 46 | 47 | GenerateForm(); 48 | 49 | parameters.ForEach(parameter => 50 | { 51 | var controlForParameter = addedControls.First(control => control.Name.Equals(parameter.propertyName)); 52 | var value = ControlHelper.GetParameterValue(autoAction, parameter.propertyName); 53 | ControlHelper.ControlTypeToControlSetter[controlForParameter.GetType()](value, controlForParameter); 54 | }); 55 | } 56 | 57 | private void GenerateForm() 58 | { 59 | Size = new Size(Size.Width, Size.Height + (parameters.Count * 40)); 60 | b_Save.Location = new Point(b_Save.Location.X, b_Save.Location.Y + (parameters.Count * 40)); 61 | b_Cancel.Location = new Point(b_Cancel.Location.X, b_Cancel.Location.Y + (parameters.Count * 40)); 62 | 63 | parameters.ForEach(AddParameterToForm); 64 | } 65 | 66 | private void AddParameterToForm(AbstractParameter parameter) 67 | { 68 | yOffset++; 69 | 70 | var label = ControlHelper.CreateLabel(parameter.propertyName, 1, yOffset); 71 | Controls.Add(label); 72 | addedControls.Add(label); 73 | 74 | var inputControl = ControlHelper.CreateParameterInputControl(parameter, 1, yOffset); 75 | Controls.Add(inputControl); 76 | addedControls.Add(inputControl); 77 | } 78 | 79 | private void b_Save_Click(object sender, EventArgs e) 80 | { 81 | parameters.ForEach(parameter => 82 | { 83 | var control = addedControls.First(addedControl => addedControl.Name.Equals(parameter.propertyName)); 84 | ControlHelper.ControlTypeToParameterSetter[control.GetType()](parameter, control); 85 | }); 86 | 87 | modified = true; 88 | 89 | Close(); 90 | } 91 | 92 | private void b_Cancel_Click(object sender, EventArgs e) 93 | { 94 | modified = false; 95 | Close(); 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /forms/autoaction/AutoActionEditor.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /forms/definitions/AddMasterProfile.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.forms.definitions 2 | { 3 | using System.ComponentModel; 4 | 5 | partial class AddMasterProfile 6 | { 7 | /// 8 | /// Required designer variable. 9 | /// 10 | private IContainer components = null; 11 | 12 | /// 13 | /// Clean up any resources being used. 14 | /// 15 | /// true if managed resources should be disposed; otherwise, false. 16 | protected override void Dispose(bool disposing) 17 | { 18 | if (disposing && (components != null)) 19 | { 20 | components.Dispose(); 21 | } 22 | 23 | base.Dispose(disposing); 24 | } 25 | 26 | #region Windows Form Designer generated code 27 | 28 | /// 29 | /// Required method for Designer support - do not modify 30 | /// the contents of this method with the code editor. 31 | /// 32 | private void InitializeComponent() 33 | { 34 | this.tb_ConfigProfileName = new System.Windows.Forms.TextBox(); 35 | this.label1 = new System.Windows.Forms.Label(); 36 | this.b_Save = new System.Windows.Forms.Button(); 37 | this.b_Cancel = new System.Windows.Forms.Button(); 38 | this.SuspendLayout(); 39 | // 40 | // tb_ConfigProfileName 41 | // 42 | this.tb_ConfigProfileName.Location = new System.Drawing.Point(126, 31); 43 | this.tb_ConfigProfileName.Name = "tb_ConfigProfileName"; 44 | this.tb_ConfigProfileName.Size = new System.Drawing.Size(209, 20); 45 | this.tb_ConfigProfileName.TabIndex = 0; 46 | // 47 | // label1 48 | // 49 | this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte) (0))); 50 | this.label1.Location = new System.Drawing.Point(21, 32); 51 | this.label1.Name = "label1"; 52 | this.label1.Size = new System.Drawing.Size(87, 19); 53 | this.label1.TabIndex = 1; 54 | this.label1.Text = "Profile name:"; 55 | // 56 | // b_Save 57 | // 58 | this.b_Save.Cursor = System.Windows.Forms.Cursors.Arrow; 59 | this.b_Save.Location = new System.Drawing.Point(165, 73); 60 | this.b_Save.Name = "b_Save"; 61 | this.b_Save.Size = new System.Drawing.Size(93, 28); 62 | this.b_Save.TabIndex = 2; 63 | this.b_Save.Text = "Save"; 64 | this.b_Save.UseVisualStyleBackColor = true; 65 | this.b_Save.Click += new System.EventHandler(this.b_Save_Click); 66 | // 67 | // b_Cancel 68 | // 69 | this.b_Cancel.Location = new System.Drawing.Point(264, 73); 70 | this.b_Cancel.Name = "b_Cancel"; 71 | this.b_Cancel.Size = new System.Drawing.Size(93, 28); 72 | this.b_Cancel.TabIndex = 3; 73 | this.b_Cancel.Text = "Cancel"; 74 | this.b_Cancel.UseVisualStyleBackColor = true; 75 | this.b_Cancel.Click += new System.EventHandler(this.b_Cancel_Click); 76 | // 77 | // AddMasterProfile 78 | // 79 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 80 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 81 | this.ClientSize = new System.Drawing.Size(369, 113); 82 | this.ControlBox = false; 83 | this.Controls.Add(this.b_Cancel); 84 | this.Controls.Add(this.b_Save); 85 | this.Controls.Add(this.label1); 86 | this.Controls.Add(this.tb_ConfigProfileName); 87 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 88 | this.Name = "AddMasterProfile"; 89 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 90 | this.Text = "Create Master Profile"; 91 | this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.AddMasterProfile_KeyDown); 92 | this.ResumeLayout(false); 93 | this.PerformLayout(); 94 | } 95 | 96 | private System.Windows.Forms.Button b_Cancel; 97 | private System.Windows.Forms.Button b_Save; 98 | private System.Windows.Forms.Label label1; 99 | private System.Windows.Forms.TextBox tb_ConfigProfileName; 100 | 101 | #endregion 102 | } 103 | } -------------------------------------------------------------------------------- /forms/definitions/AddMasterProfile.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | namespace Turbo.plugins.patrick.forms.definitions 4 | { 5 | using System; 6 | 7 | public partial class AddMasterProfile : Form 8 | { 9 | 10 | private string name; 11 | 12 | private AddMasterProfile() 13 | { 14 | InitializeComponent(); 15 | } 16 | 17 | public static string GetNewMasterProfileName() 18 | { 19 | var form = new AddMasterProfile(); 20 | form.ShowDialog(); 21 | 22 | return form.name; 23 | } 24 | 25 | private void b_Save_Click(object sender, EventArgs e) 26 | { 27 | name = tb_ConfigProfileName.Text; 28 | Close(); 29 | } 30 | 31 | private void b_Cancel_Click(object sender, EventArgs e) 32 | { 33 | name = null; 34 | Close(); 35 | } 36 | 37 | private void AddMasterProfile_KeyDown(object sender, KeyEventArgs e) 38 | { 39 | if (e.KeyData == Keys.Enter) 40 | b_Save.PerformClick(); 41 | 42 | if (e.KeyData == Keys.Escape) 43 | b_Cancel.PerformClick(); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /forms/definitions/AddMasterProfile.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /forms/definitions/DefinitionGroupEditor.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.forms.definitions 2 | { 3 | using System.ComponentModel; 4 | 5 | partial class DefinitionGroupEditor 6 | { 7 | /// 8 | /// Required designer variable. 9 | /// 10 | private IContainer components = null; 11 | 12 | /// 13 | /// Clean up any resources being used. 14 | /// 15 | /// true if managed resources should be disposed; otherwise, false. 16 | protected override void Dispose(bool disposing) 17 | { 18 | if (disposing && (components != null)) 19 | { 20 | components.Dispose(); 21 | } 22 | 23 | base.Dispose(disposing); 24 | } 25 | 26 | #region Windows Form Designer generated code 27 | 28 | /// 29 | /// Required method for Designer support - do not modify 30 | /// the contents of this method with the code editor. 31 | /// 32 | private void InitializeComponent() 33 | { 34 | this.dgv_Definitions = new System.Windows.Forms.DataGridView(); 35 | this.b_Close = new System.Windows.Forms.Button(); 36 | this.b_AddDefinition = new System.Windows.Forms.Button(); 37 | ((System.ComponentModel.ISupportInitialize) (this.dgv_Definitions)).BeginInit(); 38 | this.SuspendLayout(); 39 | // 40 | // dgv_Definitions 41 | // 42 | this.dgv_Definitions.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 43 | this.dgv_Definitions.Location = new System.Drawing.Point(1, 1); 44 | this.dgv_Definitions.Name = "dgv_Definitions"; 45 | this.dgv_Definitions.Size = new System.Drawing.Size(730, 310); 46 | this.dgv_Definitions.TabIndex = 0; 47 | // 48 | // b_Close 49 | // 50 | this.b_Close.Location = new System.Drawing.Point(611, 320); 51 | this.b_Close.Name = "b_Close"; 52 | this.b_Close.Size = new System.Drawing.Size(102, 40); 53 | this.b_Close.TabIndex = 1; 54 | this.b_Close.Text = "Close"; 55 | this.b_Close.UseVisualStyleBackColor = true; 56 | this.b_Close.Click += new System.EventHandler(this.b_Close_Click); 57 | // 58 | // b_AddDefinition 59 | // 60 | this.b_AddDefinition.Location = new System.Drawing.Point(12, 320); 61 | this.b_AddDefinition.Name = "b_AddDefinition"; 62 | this.b_AddDefinition.Size = new System.Drawing.Size(102, 40); 63 | this.b_AddDefinition.TabIndex = 3; 64 | this.b_AddDefinition.Text = "Add Definition"; 65 | this.b_AddDefinition.UseVisualStyleBackColor = true; 66 | this.b_AddDefinition.Click += new System.EventHandler(this.b_AddDefinition_Click); 67 | // 68 | // DefinitionGroupEditor 69 | // 70 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 71 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 72 | this.ClientSize = new System.Drawing.Size(732, 372); 73 | this.Controls.Add(this.b_AddDefinition); 74 | this.Controls.Add(this.b_Close); 75 | this.Controls.Add(this.dgv_Definitions); 76 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D; 77 | this.Name = "DefinitionGroupEditor"; 78 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 79 | this.Text = "Definition Group Editor"; 80 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.DefinitionGroupEditor_FormClosing); 81 | this.Load += new System.EventHandler(this.EditDefinitionGroup_Load); 82 | ((System.ComponentModel.ISupportInitialize) (this.dgv_Definitions)).EndInit(); 83 | this.ResumeLayout(false); 84 | } 85 | 86 | private System.Windows.Forms.Button b_AddDefinition; 87 | private System.Windows.Forms.Button b_Close; 88 | private System.Windows.Forms.DataGridView dgv_Definitions; 89 | 90 | #endregion 91 | } 92 | } -------------------------------------------------------------------------------- /forms/definitions/DefinitionGroupEditor.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.forms.definitions 2 | { 3 | using System; 4 | using System.Drawing; 5 | using System.Windows.Forms; 6 | using Plugins; 7 | using skills; 8 | using util.winformutil; 9 | 10 | public partial class DefinitionGroupEditor : Form 11 | { 12 | private static DefinitionGroupEditor Instance; 13 | 14 | private DefinitionGroup parentDefinitionGroup; 15 | 16 | private bool modified; 17 | 18 | private IController hud; 19 | 20 | private DefinitionGroupEditor(IController hud) 21 | { 22 | this.hud = hud; 23 | InitializeComponent(); 24 | InitializeDataGridView(); 25 | Icon = Icon.ExtractAssociatedIcon(@"plugins\patrick\resource\icon.ico"); 26 | } 27 | 28 | public static bool ShowDefinitionGroupEditor(DefinitionGroup definitionGroup, IController hud) 29 | { 30 | if (Instance == null || Instance.IsDisposed) 31 | { 32 | Instance = new DefinitionGroupEditor(hud); 33 | } 34 | 35 | Instance.Text = "Definition Group Editor - " + definitionGroup.name; 36 | Instance.ShowEditor(definitionGroup); 37 | 38 | return Instance.modified; 39 | } 40 | 41 | private void ShowEditor(DefinitionGroup definitionGroup) 42 | { 43 | parentDefinitionGroup = definitionGroup; 44 | modified = false; 45 | ShowDialog(); 46 | } 47 | 48 | private void EditDefinitionGroup_Load(object sender, EventArgs e) 49 | { 50 | ReloadDefinitions(); 51 | } 52 | 53 | private void b_AddDefinition_Click(object sender, EventArgs e) 54 | { 55 | var definition = DefinitionEditor.GetNewDefinition(hud, parentDefinitionGroup); 56 | 57 | if (definition is null) 58 | return; 59 | 60 | definition.SetParentDefinitionGroup(parentDefinitionGroup); 61 | parentDefinitionGroup.definitions.Add(definition); 62 | modified = true; 63 | 64 | ReloadDefinitions(); 65 | } 66 | 67 | private void DefinitionGroupEditor_FormClosing(object sender, FormClosingEventArgs e) 68 | { 69 | if (e.CloseReason != CloseReason.UserClosing) 70 | return; 71 | 72 | e.Cancel = true; 73 | dgv_Definitions.Rows.Clear(); 74 | Hide(); 75 | } 76 | 77 | private void b_Close_Click(object sender, EventArgs e) 78 | { 79 | dgv_Definitions.Rows.Clear(); 80 | Hide(); 81 | } 82 | 83 | private void ReloadDefinitions() 84 | { 85 | dgv_Definitions.Rows.Clear(); 86 | 87 | parentDefinitionGroup.definitions.ForEach(definition => 88 | { 89 | var index = dgv_Definitions.Rows.Add(definition.active, definition.inverted, definition.name, definition.attributes); 90 | dgv_Definitions.Rows[index].Cells[2].ToolTipText = definition.tooltip; 91 | dgv_Definitions.Rows[index].Cells[3].ToolTipText = definition.tooltip; 92 | } 93 | ); 94 | } 95 | 96 | private void InitializeDataGridView() 97 | { 98 | dgv_Definitions.RowHeadersVisible = false; 99 | dgv_Definitions.AllowUserToAddRows = false; 100 | dgv_Definitions.AllowUserToResizeColumns = false; 101 | dgv_Definitions.AllowUserToResizeRows = false; 102 | dgv_Definitions.DefaultCellStyle.SelectionBackColor = dgv_Definitions.DefaultCellStyle.BackColor; 103 | dgv_Definitions.DefaultCellStyle.SelectionForeColor = dgv_Definitions.DefaultCellStyle.ForeColor; 104 | 105 | var columns = DgvFormUtil.GetDefinitionGroupEditorColumns(); 106 | columns.ForEach(column => dgv_Definitions.Columns.Add(column)); 107 | 108 | dgv_Definitions.CurrentCellDirtyStateChanged += (sender, args) => 109 | { 110 | if (dgv_Definitions.IsCurrentCellDirty && 111 | (dgv_Definitions.CurrentCell.OwningColumn == dgv_Definitions.Columns["active"] || 112 | dgv_Definitions.CurrentCell.OwningColumn == dgv_Definitions.Columns["inverted"]) 113 | ) 114 | { 115 | dgv_Definitions.CommitEdit(DataGridViewDataErrorContexts.Commit); 116 | } 117 | }; 118 | 119 | dgv_Definitions.CellContentClick += (sender, args) => 120 | { 121 | if (args.ColumnIndex == dgv_Definitions.Columns["active"]?.Index) 122 | { 123 | var val = (DataGridViewCheckBoxCell)dgv_Definitions.Rows[args.RowIndex].Cells["active"]; 124 | var isChecked = Convert.ToBoolean(val.Value); 125 | parentDefinitionGroup.definitions[args.RowIndex].active = isChecked; 126 | modified = true; 127 | } 128 | 129 | else if (args.ColumnIndex == dgv_Definitions.Columns["inverted"]?.Index) 130 | { 131 | var val = (DataGridViewCheckBoxCell)dgv_Definitions.Rows[args.RowIndex].Cells["inverted"]; 132 | var isChecked = Convert.ToBoolean(val.Value); 133 | parentDefinitionGroup.definitions[args.RowIndex].inverted = isChecked; 134 | modified = true; 135 | } 136 | }; 137 | 138 | dgv_Definitions.CellClick += (sender, args) => 139 | { 140 | if (args.ColumnIndex == dgv_Definitions.Columns["edit"]?.Index) 141 | modified |= DefinitionEditor.EditExistingDefinition(hud, parentDefinitionGroup.definitions[args.RowIndex]); 142 | 143 | else if (args.ColumnIndex == dgv_Definitions.Columns["delete"]?.Index) 144 | { 145 | parentDefinitionGroup.definitions.RemoveAt(args.RowIndex); 146 | modified = true; 147 | } 148 | 149 | if (modified) 150 | ReloadDefinitions(); 151 | }; 152 | } 153 | } 154 | } -------------------------------------------------------------------------------- /forms/definitions/DefinitionGroupEditor.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | True 122 | 123 | 124 | True 125 | 126 | -------------------------------------------------------------------------------- /forms/hotkeys/HotkeyEditor.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.forms.hotkeys 2 | { 3 | using System.ComponentModel; 4 | 5 | partial class HotkeyEditor 6 | { 7 | /// 8 | /// Required designer variable. 9 | /// 10 | private IContainer components = null; 11 | 12 | /// 13 | /// Clean up any resources being used. 14 | /// 15 | /// true if managed resources should be disposed; otherwise, false. 16 | protected override void Dispose(bool disposing) 17 | { 18 | if (disposing && (components != null)) 19 | { 20 | components.Dispose(); 21 | } 22 | 23 | base.Dispose(disposing); 24 | } 25 | 26 | #region Windows Form Designer generated code 27 | 28 | /// 29 | /// Required method for Designer support - do not modify 30 | /// the contents of this method with the code editor. 31 | /// 32 | private void InitializeComponent() 33 | { 34 | this.b_Save = new System.Windows.Forms.Button(); 35 | this.b_Cancel = new System.Windows.Forms.Button(); 36 | this.l_HotkeyName = new System.Windows.Forms.Label(); 37 | this.SuspendLayout(); 38 | // 39 | // b_Save 40 | // 41 | this.b_Save.Location = new System.Drawing.Point(175, 90); 42 | this.b_Save.Name = "b_Save"; 43 | this.b_Save.Size = new System.Drawing.Size(94, 40); 44 | this.b_Save.TabIndex = 9; 45 | this.b_Save.Text = "Save"; 46 | this.b_Save.UseVisualStyleBackColor = true; 47 | this.b_Save.Click += new System.EventHandler(this.b_Save_Click); 48 | // 49 | // b_Cancel 50 | // 51 | this.b_Cancel.Location = new System.Drawing.Point(284, 90); 52 | this.b_Cancel.Name = "b_Cancel"; 53 | this.b_Cancel.Size = new System.Drawing.Size(94, 40); 54 | this.b_Cancel.TabIndex = 8; 55 | this.b_Cancel.Text = "Cancel"; 56 | this.b_Cancel.UseVisualStyleBackColor = true; 57 | this.b_Cancel.Click += new System.EventHandler(this.b_Cancel_Click); 58 | // 59 | // l_HotkeyName 60 | // 61 | this.l_HotkeyName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte) (0))); 62 | this.l_HotkeyName.Location = new System.Drawing.Point(24, 9); 63 | this.l_HotkeyName.Name = "l_HotkeyName"; 64 | this.l_HotkeyName.Size = new System.Drawing.Size(343, 49); 65 | this.l_HotkeyName.TabIndex = 10; 66 | this.l_HotkeyName.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 67 | // 68 | // HotkeyEditor 69 | // 70 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 71 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 72 | this.ClientSize = new System.Drawing.Size(390, 142); 73 | this.Controls.Add(this.l_HotkeyName); 74 | this.Controls.Add(this.b_Save); 75 | this.Controls.Add(this.b_Cancel); 76 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D; 77 | this.Name = "HotkeyEditor"; 78 | this.Text = "HotkeyEditor"; 79 | this.ResumeLayout(false); 80 | } 81 | 82 | private System.Windows.Forms.Button b_Cancel; 83 | private System.Windows.Forms.Button b_Save; 84 | private System.Windows.Forms.Label l_HotkeyName; 85 | 86 | #endregion 87 | } 88 | } -------------------------------------------------------------------------------- /forms/hotkeys/HotkeyEditor.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.forms.hotkeys 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Windows.Forms; 8 | using parameters; 9 | using patrick.hotkeys.actions; 10 | using Plugins.Patrick.util.winformutil; 11 | 12 | public partial class HotkeyEditor : Form 13 | { 14 | private readonly AbstractHotkeyAction hotkey; 15 | 16 | private List parameters; 17 | 18 | private readonly List addedControls = new List(); 19 | 20 | private bool modified; 21 | 22 | private int yOffset; 23 | 24 | private HotkeyEditor(AbstractHotkeyAction hotkey) 25 | { 26 | InitializeComponent(); 27 | Icon = Icon.ExtractAssociatedIcon(@"plugins\patrick\resource\icon.ico"); 28 | 29 | this.hotkey = hotkey; 30 | LoadExistingHotkey(); 31 | } 32 | 33 | public static bool EditHotkeyAction(AbstractHotkeyAction hotkey) 34 | { 35 | var hotkeyEditor = new HotkeyEditor(hotkey) {Text = "HotkeyEditor - " + hotkey.action}; 36 | hotkeyEditor.ShowDialog(); 37 | 38 | return hotkeyEditor.modified; 39 | } 40 | 41 | private void LoadExistingHotkey() 42 | { 43 | l_HotkeyName.Text = hotkey.action; 44 | parameters = hotkey.GetParameters(); 45 | 46 | GenerateForm(); 47 | 48 | parameters.ForEach(parameter => 49 | { 50 | var controlForParameter = addedControls.First(control => control.Name.Equals(parameter.propertyName)); 51 | var value = ControlHelper.GetParameterValue(hotkey, parameter.propertyName); 52 | ControlHelper.ControlTypeToControlSetter[controlForParameter.GetType()](value, controlForParameter); 53 | }); 54 | } 55 | 56 | private void GenerateForm() 57 | { 58 | Size = new Size(Size.Width, Size.Height + (parameters.Count * 40)); 59 | b_Save.Location = new Point(b_Save.Location.X, b_Save.Location.Y + (parameters.Count * 40)); 60 | b_Cancel.Location = new Point(b_Cancel.Location.X, b_Cancel.Location.Y + (parameters.Count * 40)); 61 | 62 | parameters.ForEach(AddParameterToForm); 63 | } 64 | 65 | private void AddParameterToForm(AbstractParameter parameter) 66 | { 67 | yOffset++; 68 | 69 | var label = ControlHelper.CreateLabel(parameter.propertyName, 1, yOffset); 70 | Controls.Add(label); 71 | addedControls.Add(label); 72 | 73 | var inputControl = ControlHelper.CreateParameterInputControl(parameter, 1, yOffset); 74 | Controls.Add(inputControl); 75 | addedControls.Add(inputControl); 76 | } 77 | 78 | private void b_Save_Click(object sender, EventArgs e) 79 | { 80 | parameters.ForEach(parameter => 81 | { 82 | var control = addedControls.First(addedControl => addedControl.Name.Equals(parameter.propertyName)); 83 | ControlHelper.ControlTypeToParameterSetter[control.GetType()](parameter, control); 84 | }); 85 | 86 | modified = true; 87 | 88 | Close(); 89 | } 90 | 91 | private void b_Cancel_Click(object sender, EventArgs e) 92 | { 93 | modified = false; 94 | Close(); 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /forms/hotkeys/HotkeyEditor.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /forms/hotkeys/HotkeyPopup.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.forms.hotkeys 2 | { 3 | using System.ComponentModel; 4 | 5 | partial class HotkeyPopup 6 | { 7 | /// 8 | /// Required designer variable. 9 | /// 10 | private IContainer components = null; 11 | 12 | /// 13 | /// Clean up any resources being used. 14 | /// 15 | /// true if managed resources should be disposed; otherwise, false. 16 | protected override void Dispose(bool disposing) 17 | { 18 | if (disposing && (components != null)) 19 | { 20 | components.Dispose(); 21 | } 22 | 23 | base.Dispose(disposing); 24 | } 25 | 26 | #region Windows Form Designer generated code 27 | 28 | /// 29 | /// Required method for Designer support - do not modify 30 | /// the contents of this method with the code editor. 31 | /// 32 | private void InitializeComponent() 33 | { 34 | this.label1 = new System.Windows.Forms.Label(); 35 | this.SuspendLayout(); 36 | // 37 | // label1 38 | // 39 | this.label1.Location = new System.Drawing.Point(12, 20); 40 | this.label1.Name = "label1"; 41 | this.label1.Size = new System.Drawing.Size(153, 16); 42 | this.label1.TabIndex = 0; 43 | this.label1.Text = "Press key! Escape to cancel."; 44 | // 45 | // HotkeyPopup 46 | // 47 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 48 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 49 | this.ClientSize = new System.Drawing.Size(174, 65); 50 | this.ControlBox = false; 51 | this.Controls.Add(this.label1); 52 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D; 53 | this.MaximumSize = new System.Drawing.Size(184, 98); 54 | this.MinimumSize = new System.Drawing.Size(184, 98); 55 | this.Name = "HotkeyPopup"; 56 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 57 | this.Text = "Press Key"; 58 | this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.KeypressPopup_KeyDown); 59 | this.ResumeLayout(false); 60 | } 61 | 62 | private System.Windows.Forms.Label label1; 63 | 64 | #endregion 65 | } 66 | } -------------------------------------------------------------------------------- /forms/hotkeys/HotkeyPopup.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.forms.hotkeys 2 | { 3 | using System.Windows.Forms; 4 | using Plugins; 5 | using util.input; 6 | 7 | public partial class HotkeyPopup : Form 8 | { 9 | private MyKeyEvent keyEvent; 10 | 11 | private HotkeyPopup() 12 | { 13 | keyEvent = new MyKeyEvent(); 14 | InitializeComponent(); 15 | } 16 | 17 | public static MyKeyEvent getHotkey() 18 | { 19 | var hotkeyPopup = new HotkeyPopup(); 20 | hotkeyPopup.ShowDialog(); 21 | 22 | return hotkeyPopup.keyEvent; 23 | } 24 | 25 | private void KeypressPopup_KeyDown(object sender, KeyEventArgs e) 26 | { 27 | if (e.KeyCode == Keys.ControlKey || e.KeyCode == Keys.Menu || e.KeyCode == Keys.ShiftKey) 28 | { 29 | return; 30 | } 31 | 32 | if (e.KeyCode == Keys.Escape) 33 | { 34 | keyEvent = null; 35 | } 36 | else 37 | { 38 | keyEvent.AltPressed = e.Modifiers.ToString().Contains("Alt"); 39 | keyEvent.ControlPressed = e.Modifiers.ToString().Contains("Control"); 40 | keyEvent.ShiftPressed = e.Modifiers.ToString().Contains("Shift"); 41 | keyEvent.Key = e.KeyCode; 42 | } 43 | 44 | Close(); 45 | } 46 | 47 | public class MyKeyEvent 48 | { 49 | public Keys Key { get; set; } 50 | 51 | public bool ControlPressed { get; set; } 52 | 53 | public bool AltPressed { get; set; } 54 | 55 | public bool ShiftPressed { get; set; } 56 | 57 | public MyKeyEvent() 58 | { 59 | } 60 | 61 | public MyKeyEvent(Keys key, bool controlPressed, bool altPressed, bool shiftPressed) 62 | { 63 | Key = key; 64 | ControlPressed = controlPressed; 65 | AltPressed = altPressed; 66 | ShiftPressed = shiftPressed; 67 | } 68 | 69 | public IKeyEvent toIKeyEvent(IInputController inputController) 70 | { 71 | return inputController.CreateKeyEvent( 72 | true, 73 | InputUtil.KeysToKey(Key), 74 | ControlPressed, 75 | AltPressed, 76 | ShiftPressed); 77 | } 78 | 79 | public override string ToString() 80 | { 81 | var result = ControlPressed ? "Control + " : ""; 82 | result += AltPressed ? "Alt + " : ""; 83 | result += ShiftPressed ? "Shift + " : ""; 84 | result += Key; 85 | return result; 86 | } 87 | 88 | protected bool Equals(MyKeyEvent other) 89 | { 90 | return Key == other.Key && ControlPressed == other.ControlPressed && AltPressed == other.AltPressed && 91 | ShiftPressed == other.ShiftPressed; 92 | } 93 | 94 | public override bool Equals(object obj) 95 | { 96 | if (ReferenceEquals(null, obj)) return false; 97 | if (ReferenceEquals(this, obj)) return true; 98 | if (obj.GetType() != this.GetType()) return false; 99 | return Equals((MyKeyEvent)obj); 100 | } 101 | 102 | public override int GetHashCode() 103 | { 104 | unchecked 105 | { 106 | var hashCode = (int)Key; 107 | hashCode = (hashCode * 397) ^ ControlPressed.GetHashCode(); 108 | hashCode = (hashCode * 397) ^ AltPressed.GetHashCode(); 109 | hashCode = (hashCode * 397) ^ ShiftPressed.GetHashCode(); 110 | return hashCode; 111 | } 112 | } 113 | } 114 | } 115 | } -------------------------------------------------------------------------------- /forms/hotkeys/HotkeyPopup.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /hotkeys/HotkeyContainer.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.Plugins.Patrick.hotkeys 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using Default; 7 | using Newtonsoft.Json; 8 | using plugins.patrick.hotkeys.actions; 9 | using plugins.patrick.util.executors; 10 | using util; 11 | using util.config.jsonconverter; 12 | 13 | public class HotkeyContainer 14 | { 15 | [JsonProperty(ItemConverterType = typeof(HotkeyConverter))] 16 | public List hotkeyActions { get; } 17 | 18 | [JsonIgnore] private readonly ThreadedExecutor executor = new ThreadedExecutor(); 19 | 20 | public HotkeyContainer() 21 | { 22 | hotkeyActions = new List(); 23 | } 24 | 25 | public HotkeyContainer(List hotkeyActions) 26 | { 27 | this.hotkeyActions = hotkeyActions; 28 | } 29 | 30 | public void InitializeIKeyEventsAndSort(IInputController inputController) 31 | { 32 | hotkeyActions 33 | .Where(hotkey => !(hotkey.keyEvent is null)) 34 | .ForEach(hotkey => hotkey.iKeyEvent = hotkey.keyEvent.toIKeyEvent(inputController)); 35 | 36 | hotkeyActions.Sort((left, right) => string.Compare(left.action, right.action, StringComparison.Ordinal)); 37 | } 38 | 39 | public void InvokeIfExists(IKeyEvent keyEvent, IController hud) 40 | { 41 | var hotkey = hotkeyActions 42 | .Where(hk => !(hk.iKeyEvent is null) && 43 | hk.active && 44 | hk.iKeyEvent.Matches(keyEvent)) 45 | .FirstOrDefault(hk => hk.PreconditionSatisfied(hud)); 46 | 47 | if (hotkey != null) 48 | executor.Execute(() => hotkey.Invoke(hud), hotkey.GetType().ToString(), hotkey.minimumExecutionDelta); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /hotkeys/HotkeyType.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys 2 | { 3 | 4 | public enum HotkeyType 5 | { 6 | All, 7 | Settings, 8 | Teleport, 9 | General 10 | } 11 | } -------------------------------------------------------------------------------- /hotkeys/actions/AbstractHotkeyAction.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using forms.hotkeys; 7 | using hotkeys; 8 | using Newtonsoft.Json; 9 | using parameters; 10 | using Plugins; 11 | using Plugins.Patrick.util; 12 | 13 | public abstract class AbstractHotkeyAction 14 | { 15 | public static readonly List HotkeyTypes = Misc.GetAllSubTypesFromType(typeof(AbstractHotkeyAction)); 16 | 17 | public bool active { get; set; } 18 | 19 | [JsonIgnore] 20 | public string action => $"{type} - " + GetType().Name; 21 | 22 | [JsonIgnore] public string attributes => GetAttributes(); 23 | 24 | [JsonIgnore] public string hotkey => keyEvent == null ? "None" : keyEvent.ToString(); 25 | 26 | [Browsable(false)] public HotkeyPopup.MyKeyEvent keyEvent { get; set; } 27 | 28 | [JsonIgnore] 29 | [Browsable(false)] 30 | public virtual string tooltip => "No tooltip available for this hotkey!"; 31 | 32 | 33 | [JsonIgnore] 34 | [Browsable(false)] 35 | public virtual long minimumExecutionDelta => 1000; 36 | 37 | 38 | [JsonIgnore] [Browsable(false)] public IKeyEvent iKeyEvent { get; set; } 39 | 40 | [JsonIgnore] [Browsable(false)] public abstract HotkeyType type { get; } 41 | 42 | protected abstract string GetAttributes(); 43 | 44 | public abstract List GetParameters(); 45 | 46 | public abstract bool PreconditionSatisfied(IController hud); 47 | 48 | public abstract void Invoke(IController hud); 49 | 50 | public void SetKeyEvent(HotkeyPopup.MyKeyEvent keyEvent, IKeyEvent iKeyEvent) 51 | { 52 | this.keyEvent = keyEvent; 53 | this.iKeyEvent = iKeyEvent; 54 | } 55 | 56 | public void RemoveKeybind() 57 | { 58 | keyEvent = null; 59 | iKeyEvent = null; 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /hotkeys/actions/general/LeaveGame.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.general 2 | { 3 | using System.Collections.Generic; 4 | using actions; 5 | using parameters; 6 | using Plugins; 7 | using util.diablo; 8 | using util.thud; 9 | 10 | public class LeaveGame : AbstractHotkeyAction 11 | { 12 | public override HotkeyType type => HotkeyType.General; 13 | 14 | protected override string GetAttributes() => ""; 15 | 16 | public override List GetParameters() 17 | { 18 | return new List(); 19 | } 20 | 21 | public override bool PreconditionSatisfied(IController hud) 22 | { 23 | return hud.Game.IsInGame && !hud.Game.IsLoading; 24 | } 25 | 26 | public override string tooltip 27 | { 28 | get 29 | { 30 | return "Leaves the game instantly"; 31 | } 32 | } 33 | 34 | public override void Invoke(IController hud) 35 | { 36 | hud.Render.CloseChatAndOpenWindows(); 37 | 38 | var leaveGameButton = hud.Render.GetOrRegisterAndGetUiElement(UiPathConstants.Buttons.LEAVE_GAME); 39 | 40 | if (leaveGameButton.Visible) 41 | { 42 | leaveGameButton.Click(); 43 | return; 44 | } 45 | 46 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Buttons.GAME_MENU); 47 | 48 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.Buttons.LEAVE_GAME); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /hotkeys/actions/general/LowerDifficulty.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.general 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using actions; 6 | using parameters; 7 | using Plugins; 8 | using util.input; 9 | using util.thud; 10 | using Settings = Plugins.Patrick.forms.Settings; 11 | 12 | public class LowerDifficulty : AbstractHotkeyAction 13 | { 14 | public override HotkeyType type => HotkeyType.General; 15 | 16 | protected override string GetAttributes() => ""; 17 | 18 | public override List GetParameters() 19 | { 20 | return new List(); 21 | } 22 | 23 | public override bool PreconditionSatisfied(IController hud) 24 | { 25 | return hud.Game.GameDifficulty != GameDifficulty.n; 26 | } 27 | 28 | public override string tooltip => "Lowers game difficulty to normal."; 29 | 30 | public override void Invoke(IController hud) 31 | { 32 | try 33 | { 34 | var lowerDifficultyButton = hud.Render.GetUiElement( 35 | "Root.NormalLayer.gamemenu_dialog.gamemenu_bkgrnd.GameParams.RightButtonStackContainer.button_lowerDifficulty" 36 | ); 37 | 38 | if (!lowerDifficultyButton.Visible) 39 | { 40 | InputSimulator.PressKey(Settings.Keybinds[(int)ActionKey.Close]); 41 | 42 | hud.Render.GetUiElement( 43 | "Root.NormalLayer.GameOptions_main.LayoutRoot.OverlayContainer.KeyBindings.ListContainer.BindingList.HotKeyGameMenu.HotKeyGameMenuText" 44 | ).Click(); 45 | } 46 | 47 | while (hud.Game.GameDifficulty != GameDifficulty.n) 48 | lowerDifficultyButton.Click(); 49 | 50 | hud.Render.GetUiElement("Root.NormalLayer.gamemenu_dialog.gamemenu_bkgrnd.button_resumeGame").Click(); 51 | } 52 | catch (Exception e) 53 | { 54 | hud.Debug(e.ToString()); 55 | } 56 | } 57 | 58 | } 59 | } -------------------------------------------------------------------------------- /hotkeys/actions/settings/ToggleActive.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.settings 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using Plugins; 6 | using Plugins.Patrick.forms; 7 | 8 | public class ToggleActive : AbstractHotkeyAction 9 | { 10 | public override HotkeyType type => HotkeyType.Settings; 11 | 12 | protected override string GetAttributes() => ""; 13 | 14 | public override List GetParameters() 15 | { 16 | return new List(); 17 | } 18 | 19 | public override bool PreconditionSatisfied(IController hud) 20 | { 21 | return true; 22 | } 23 | 24 | public override void Invoke(IController hud) 25 | { 26 | Settings.Active = !Settings.Active; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /hotkeys/actions/settings/ToggleActivePowerOverlay.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.settings 2 | { 3 | using System.Collections.Generic; 4 | using Newtonsoft.Json; 5 | using parameters; 6 | using Plugins; 7 | using util.thud; 8 | 9 | public class ToggleActivePowerOverlay : AbstractHotkeyAction 10 | { 11 | 12 | [JsonIgnore] private ActivePowerOverlay activePowerOverlay; 13 | 14 | public override HotkeyType type => HotkeyType.Settings; 15 | 16 | protected override string GetAttributes() => ""; 17 | 18 | public override List GetParameters() 19 | { 20 | return new List(); 21 | } 22 | 23 | public override bool PreconditionSatisfied(IController hud) 24 | { 25 | return true; 26 | } 27 | 28 | public override void Invoke(IController hud) 29 | { 30 | if (activePowerOverlay == null) 31 | activePowerOverlay = hud.GetPlugin(); 32 | 33 | activePowerOverlay.Reset(); 34 | activePowerOverlay.Enabled = !activePowerOverlay.Enabled; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /hotkeys/actions/settings/ToggleLeftSkill.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.settings 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using Plugins; 6 | using Plugins.Patrick.forms; 7 | 8 | public class ToggleLeftSkill : AbstractHotkeyAction 9 | { 10 | public override HotkeyType type => HotkeyType.Settings; 11 | 12 | protected override string GetAttributes() => ""; 13 | 14 | public override List GetParameters() 15 | { 16 | return new List(); 17 | } 18 | 19 | public override bool PreconditionSatisfied(IController hud) 20 | { 21 | return true; 22 | } 23 | 24 | public override void Invoke(IController hud) 25 | { 26 | Settings.KeyToActive[ActionKey.LeftSkill] = !Settings.KeyToActive[ActionKey.LeftSkill]; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /hotkeys/actions/settings/ToggleRightSkill.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.settings 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using Plugins; 6 | using Plugins.Patrick.forms; 7 | 8 | public class ToggleRightSkill: AbstractHotkeyAction 9 | { 10 | public override HotkeyType type => HotkeyType.Settings; 11 | 12 | protected override string GetAttributes() => ""; 13 | 14 | public override List GetParameters() 15 | { 16 | return new List(); 17 | } 18 | 19 | public override bool PreconditionSatisfied(IController hud) 20 | { 21 | return true; 22 | } 23 | 24 | public override void Invoke(IController hud) 25 | { 26 | Settings.KeyToActive[ActionKey.RightSkill] = !Settings.KeyToActive[ActionKey.RightSkill]; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /hotkeys/actions/settings/ToggleSkill1.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.settings 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using Plugins; 6 | using Plugins.Patrick.forms; 7 | 8 | public class ToggleSkill1 : AbstractHotkeyAction 9 | { 10 | public override HotkeyType type => HotkeyType.Settings; 11 | 12 | protected override string GetAttributes() => ""; 13 | 14 | public override List GetParameters() 15 | { 16 | return new List(); 17 | } 18 | 19 | public override bool PreconditionSatisfied(IController hud) 20 | { 21 | return true; 22 | } 23 | 24 | public override void Invoke(IController hud) 25 | { 26 | Settings.KeyToActive[ActionKey.Skill1] = !Settings.KeyToActive[ActionKey.Skill1]; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /hotkeys/actions/settings/ToggleSkill2.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.settings 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using Plugins; 6 | using Plugins.Patrick.forms; 7 | 8 | public class ToggleSkill2 : AbstractHotkeyAction 9 | { 10 | public override HotkeyType type => HotkeyType.Settings; 11 | 12 | protected override string GetAttributes() => ""; 13 | 14 | public override List GetParameters() 15 | { 16 | return new List(); 17 | } 18 | 19 | public override bool PreconditionSatisfied(IController hud) 20 | { 21 | return true; 22 | } 23 | 24 | public override void Invoke(IController hud) 25 | { 26 | Settings.KeyToActive[ActionKey.Skill2] = !Settings.KeyToActive[ActionKey.Skill2]; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /hotkeys/actions/settings/ToggleSkill3.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.settings 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using Plugins; 6 | using Plugins.Patrick.forms; 7 | 8 | public class ToggleSkill3 : AbstractHotkeyAction 9 | { 10 | public override HotkeyType type => HotkeyType.Settings; 11 | 12 | protected override string GetAttributes() => ""; 13 | 14 | public override List GetParameters() 15 | { 16 | return new List(); 17 | } 18 | 19 | public override bool PreconditionSatisfied(IController hud) 20 | { 21 | return true; 22 | } 23 | 24 | public override void Invoke(IController hud) 25 | { 26 | Settings.KeyToActive[ActionKey.Skill3] = !Settings.KeyToActive[ActionKey.Skill3]; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /hotkeys/actions/settings/ToggleSkill4.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.settings 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using Plugins; 6 | using Plugins.Patrick.forms; 7 | 8 | public class ToggleSkill4 : AbstractHotkeyAction 9 | { 10 | public override HotkeyType type => HotkeyType.Settings; 11 | 12 | protected override string GetAttributes() => ""; 13 | 14 | public override List GetParameters() 15 | { 16 | return new List(); 17 | } 18 | 19 | public override bool PreconditionSatisfied(IController hud) 20 | { 21 | return true; 22 | } 23 | 24 | public override void Invoke(IController hud) 25 | { 26 | Settings.KeyToActive[ActionKey.Skill4] = !Settings.KeyToActive[ActionKey.Skill4]; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /hotkeys/actions/teleport/Act1.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.teleport 2 | { 3 | using System.Collections.Generic; 4 | using actions; 5 | using hotkeys; 6 | using parameters; 7 | using Plugins; 8 | using Plugins.Patrick.forms; 9 | using util.diablo; 10 | using util.input; 11 | using util.thud; 12 | 13 | public class Act1 : AbstractHotkeyAction 14 | { 15 | public override HotkeyType type => HotkeyType.Teleport; 16 | 17 | protected override string GetAttributes() => ""; 18 | 19 | public override List GetParameters() 20 | { 21 | return new List(); 22 | } 23 | 24 | public override bool PreconditionSatisfied(IController hud) 25 | { 26 | return hud.Game.CurrentAct != 1; 27 | } 28 | 29 | public override void Invoke(IController hud) 30 | { 31 | hud.Render.CloseChatAndOpenWindows(); 32 | 33 | InputSimulator.PressKey(Settings.Keybinds[(int)ActionKey.Map]); 34 | 35 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ZOOM_OUT); 36 | 37 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ACT_ONE); 38 | 39 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ActOne.TOWN); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /hotkeys/actions/teleport/Act2.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.teleport 2 | { 3 | using System.Collections.Generic; 4 | using actions; 5 | using hotkeys; 6 | using parameters; 7 | using Plugins; 8 | using Plugins.Patrick.forms; 9 | using util.diablo; 10 | using util.input; 11 | using util.thud; 12 | 13 | public class Act2 : AbstractHotkeyAction 14 | { 15 | public override HotkeyType type => HotkeyType.Teleport; 16 | 17 | protected override string GetAttributes() => ""; 18 | 19 | public override List GetParameters() 20 | { 21 | return new List(); 22 | } 23 | 24 | public override bool PreconditionSatisfied(IController hud) 25 | { 26 | return hud.Game.CurrentAct != 2; 27 | } 28 | 29 | public override void Invoke(IController hud) 30 | { 31 | hud.Render.CloseChatAndOpenWindows(); 32 | 33 | InputSimulator.PressKey(Settings.Keybinds[(int)ActionKey.Map]); 34 | 35 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ZOOM_OUT); 36 | 37 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ACT_TWO); 38 | 39 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ActTwo.TOWN); 40 | } 41 | 42 | } 43 | } -------------------------------------------------------------------------------- /hotkeys/actions/teleport/Act3.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.teleport 2 | { 3 | using System.Collections.Generic; 4 | using actions; 5 | using hotkeys; 6 | using parameters; 7 | using Plugins; 8 | using Plugins.Patrick.forms; 9 | using util.diablo; 10 | using util.input; 11 | using util.thud; 12 | 13 | public class Act3 : AbstractHotkeyAction 14 | { 15 | 16 | public override HotkeyType type => HotkeyType.Teleport; 17 | 18 | protected override string GetAttributes() => ""; 19 | 20 | public override List GetParameters() 21 | { 22 | return new List(); 23 | } 24 | 25 | public override bool PreconditionSatisfied(IController hud) 26 | { 27 | return hud.Game.CurrentAct != 3; 28 | } 29 | 30 | public override void Invoke(IController hud) 31 | { 32 | hud.Render.CloseChatAndOpenWindows(); 33 | 34 | InputSimulator.PressKey(Settings.Keybinds[(int)ActionKey.Map]); 35 | 36 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ZOOM_OUT); 37 | 38 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ACT_THREE); 39 | 40 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ActThree.TOWN); 41 | } 42 | 43 | } 44 | } -------------------------------------------------------------------------------- /hotkeys/actions/teleport/Act4.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.teleport 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using Plugins; 6 | using Plugins.Patrick.forms; 7 | using util.diablo; 8 | using util.input; 9 | using util.thud; 10 | 11 | public class Act4 : AbstractHotkeyAction 12 | { 13 | public override HotkeyType type => HotkeyType.Teleport; 14 | 15 | protected override string GetAttributes() => ""; 16 | 17 | public override List GetParameters() 18 | { 19 | return new List(); 20 | } 21 | 22 | public override bool PreconditionSatisfied(IController hud) 23 | { 24 | return hud.Game.CurrentAct != 3; 25 | } 26 | 27 | public override void Invoke(IController hud) 28 | { 29 | hud.Render.CloseChatAndOpenWindows(); 30 | 31 | InputSimulator.PressKey(Settings.Keybinds[(int)ActionKey.Map]); 32 | 33 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ZOOM_OUT); 34 | 35 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ACT_FOUR); 36 | 37 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ActFour.TOWN); 38 | } 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /hotkeys/actions/teleport/Act5.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.hotkeys.actions.teleport 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using Plugins; 6 | using Plugins.Patrick.forms; 7 | using util.diablo; 8 | using util.input; 9 | using util.thud; 10 | 11 | public class Act5 : AbstractHotkeyAction 12 | { 13 | public override HotkeyType type => HotkeyType.Teleport; 14 | 15 | protected override string GetAttributes() => ""; 16 | 17 | public override List GetParameters() 18 | { 19 | return new List(); 20 | } 21 | 22 | public override bool PreconditionSatisfied(IController hud) 23 | { 24 | return hud.Game.CurrentAct != 5; 25 | } 26 | 27 | public override void Invoke(IController hud) 28 | { 29 | hud.Render.CloseChatAndOpenWindows(); 30 | 31 | InputSimulator.PressKey(Settings.Keybinds[(int)ActionKey.Map]); 32 | 33 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ZOOM_OUT); 34 | 35 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ACT_FIVE); 36 | 37 | hud.Render.WaitForVisiblityAndClickOrAbortHotkeyEvent(UiPathConstants.WaitpointMap.ActFive.TOWN); 38 | } 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /pHelper.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.Plugins.Patrick 2 | { 3 | using System.Linq; 4 | using System.Threading; 5 | using Default; 6 | using forms; 7 | using plugins.patrick.skills; 8 | using plugins.patrick.util.config; 9 | using plugins.patrick.util.diablo; 10 | using plugins.patrick.util.input; 11 | using plugins.patrick.util.thud; 12 | 13 | public class pHelper : BasePlugin, IInGameTopPainter, IKeyEventHandler, IAfterCollectHandler, INewAreaHandler 14 | { 15 | private IFont watermarkEnabled, watermarkDisabled, version; 16 | 17 | private IBrush activeSkillBrush, inactiveSkillBrush; 18 | 19 | private Settings settings; 20 | 21 | private SkillExecutor skillExecutor; 22 | 23 | private Thread settingsThread; 24 | 25 | public pHelper() 26 | { 27 | Enabled = true; 28 | } 29 | 30 | public override void Load(IController hud) 31 | { 32 | base.Load(hud); 33 | 34 | settings = new Settings(Hud); 35 | skillExecutor = new SkillExecutor(settings); 36 | 37 | settingsThread = new Thread(() => 38 | { 39 | settings.ShowDialog(); 40 | }); 41 | settingsThread.SetApartmentState(ApartmentState.STA); 42 | settingsThread.Start(); 43 | 44 | watermarkEnabled = Hud.Render.CreateFont("tahoma", 8, 255, 0, 170, 0, true, false, false); 45 | watermarkDisabled = Hud.Render.CreateFont("tahoma", 8, 255, 170, 0, 0, true, false, false); 46 | 47 | version = Hud.Render.CreateFont("tahoma", 8, 255, 227, 227, 0, false, false, false); 48 | 49 | activeSkillBrush = settings.Hud.Render.CreateBrush(255, 0, 170, 0, 3.14f); 50 | inactiveSkillBrush = settings.Hud.Render.CreateBrush(255, 170, 0, 0, 3.14f); 51 | } 52 | 53 | public void OnNewArea(bool newGame, ISnoArea area) 54 | { 55 | if (newGame) 56 | settings.cb_ShowOnlyForCurrentClass_CheckedChanged(null, null); 57 | } 58 | 59 | public void OnKeyEvent(IKeyEvent keyEvent) 60 | { 61 | settings.Hotkeys.InvokeIfExists(keyEvent, Hud); 62 | } 63 | 64 | public void PaintTopInGame(ClipState clipState) 65 | { 66 | if (clipState != ClipState.BeforeClip) 67 | return; 68 | 69 | DrawSkillBrushes(); 70 | 71 | if (Settings.Active) 72 | watermarkEnabled.DrawText("pHelper", 4, Hud.Window.Size.Height * 0.966f); 73 | else 74 | watermarkDisabled.DrawText("pHelper", 4, Hud.Window.Size.Height * 0.966f); 75 | 76 | if (Hud.Window.CursorInsideRect(4, Hud.Window.Size.Height * 0.966f, 70, 20)) 77 | version.DrawText("v" + ConfigPersistence.VERSION, 4, Hud.Window.Size.Height * 0.946f); 78 | } 79 | 80 | private void DrawSkillBrushes() 81 | { 82 | Hud.Game.Me.Powers.UsedSkills.ForEach(skill => 83 | { 84 | if (!settings.SnoToDefinitionGroups.TryGetValue(skill.SnoPower.Sno, out var definitionGroupsForSkill) || !definitionGroupsForSkill.active || !Settings.KeyToActive[skill.Key]) 85 | inactiveSkillBrush.DrawRectangle(settings.Hud.Render.GetPlayerSkillUiElement(skill.Key).Rectangle); 86 | else 87 | activeSkillBrush.DrawRectangle(settings.Hud.Render.GetPlayerSkillUiElement(skill.Key).Rectangle); 88 | }); 89 | } 90 | 91 | public void AfterCollect() 92 | { 93 | if (Hud.Game.IsLoading || Hud.Game.IsPaused || !D3Client.IsInForeground() || !Settings.Active) 94 | return; 95 | 96 | if (Hud.Input.IsKeyDown(Settings.Keybinds[ConfigPersistence.QOL_KEY_INDEX])) 97 | ExecuteQolMacro(); 98 | 99 | settings.AutoActions.ExecuteAutoActions(Hud); 100 | 101 | if (CharacterCanCast()) 102 | ExecuteClassMacros(); 103 | } 104 | 105 | private void ExecuteQolMacro() 106 | { 107 | if (!Hud.Game.IsInTown || (!Hud.Render.IsShopOpen() && !Hud.Inventory.StashMainUiElement.Visible)) 108 | InputSimulator.PostMessageMouseClickLeft(Hud.Window.CursorX, Hud.Window.CursorY); 109 | else if (Hud.Inventory.HoveredItem != null) 110 | Hud.Inventory.GetItemRect(Hud.Inventory.HoveredItem).RightClick(); 111 | } 112 | 113 | private void ExecuteClassMacros() 114 | { 115 | Hud.Game.Me.Powers.CurrentSkills.ForEach(skill => 116 | skillExecutor.Cast(skill) 117 | ); 118 | } 119 | 120 | private bool CharacterCanCast() 121 | { 122 | if (ShouldUpGems()) 123 | return false; 124 | 125 | 126 | return Hud.Game.IsInGame 127 | && !Hud.Game.IsInTown 128 | && !Hud.Game.IsLoading 129 | && Hud.Game.MapMode == MapMode.Minimap 130 | && !Hud.Game.Me.IsDead 131 | && Hud.Game.Me.AnimationState != AcdAnimationState.CastingPortal 132 | && !Hud.Render.IsUiElementVisible(UiPathConstants.Ui.CHAT_INPUT) 133 | && !Hud.Game.Me.Powers.BuffIsActive(Hud.Sno.SnoPowers.Generic_ActorInvulBuff.Sno) 134 | && !Hud.Game.Me.Powers.BuffIsActive(Hud.Sno.SnoPowers.Generic_TeleportToPlayerCast.Sno) 135 | && !Hud.Game.Me.Powers.BuffIsActive(Hud.Sno.SnoPowers.Generic_TeleportToWaypointCast.Sno) 136 | && !Hud.Game.Me.Powers.BuffIsActive(Hud.Sno.SnoPowers.Generic_AxeOperateGizmo.Sno); 137 | } 138 | 139 | private bool ShouldUpGems() 140 | { 141 | if (Hud.Game.Quests.FirstOrDefault(quest => quest.SnoQuest.Sno == Hud.Sno.SnoQuests.NephalemRift_337492.Sno) is IQuest riftQuest) 142 | return riftQuest.QuestStepId == 34; 143 | 144 | return false; 145 | } 146 | } 147 | } -------------------------------------------------------------------------------- /parameters/AbstractParameter.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.parameters 2 | { 3 | using System; 4 | 5 | public abstract class AbstractParameter 6 | { 7 | public string propertyName { get; } 8 | 9 | // TODO Used as a cheap parameter to know what to cast to. 10 | public Type templateType { get; } 11 | 12 | public abstract ParameterType parameterType { get; } 13 | 14 | protected AbstractParameter(string propertyName, Type templateType) 15 | { 16 | this.propertyName = propertyName; 17 | this.templateType = templateType; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /parameters/ParameterType.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.parameters 2 | { 3 | public enum ParameterType 4 | { 5 | Simple, 6 | ContextParameter 7 | } 8 | } -------------------------------------------------------------------------------- /parameters/types/ContextParameter.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.parameters.types 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using parameters; 7 | 8 | public class ContextParameter : AbstractParameter 9 | { 10 | public Action setter { get; } 11 | 12 | public List options { get; } 13 | 14 | public string displayMember { get; } 15 | 16 | private ContextParameter(string propertyName, Action setter, List options, string displayMember) : base(propertyName, typeof(object)) 17 | { 18 | this.setter = setter; 19 | this.options = options; 20 | this.displayMember = displayMember; 21 | } 22 | 23 | public static ContextParameter of(string propertyName, Action setter, IEnumerable options, string displayMember = null) 24 | { 25 | return new ContextParameter(propertyName, setter, options.Cast().ToList(), displayMember); 26 | } 27 | 28 | public override ParameterType parameterType => ParameterType.ContextParameter; 29 | } 30 | } -------------------------------------------------------------------------------- /parameters/types/SimpleParameter.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.parameters.types 2 | { 3 | using System; 4 | using parameters; 5 | 6 | public class SimpleParameter : AbstractParameter 7 | { 8 | public Action setter { get; } 9 | 10 | public T defaultValue { get; } 11 | 12 | private SimpleParameter(string propertyName, Action setter, T defaultValue = default(T)) : base(propertyName, typeof(T)) 13 | { 14 | this.defaultValue = defaultValue; 15 | this.setter = setter; 16 | } 17 | 18 | public static SimpleParameter of(string attributeName, Action setter, T defaultValue = default(T)) 19 | { 20 | return new SimpleParameter(attributeName, setter, defaultValue); 21 | } 22 | 23 | public override ParameterType parameterType => ParameterType.Simple; 24 | } 25 | } -------------------------------------------------------------------------------- /resource/donate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patschl/pHelperPlugin/57610fbd8bf6ef8172f3216d088baf5e90af2996/resource/donate.jpg -------------------------------------------------------------------------------- /resource/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patschl/pHelperPlugin/57610fbd8bf6ef8172f3216d088baf5e90af2996/resource/icon.ico -------------------------------------------------------------------------------- /skills/DefinitionGroup.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills 2 | { 3 | using System.Collections.Generic; 4 | using castactions; 5 | using castactions.actions; 6 | using definitions; 7 | using Newtonsoft.Json; 8 | using Plugins; 9 | using Plugins.Patrick.util.config.jsonconverter; 10 | 11 | public class DefinitionGroup 12 | { 13 | public bool active { get; set; } 14 | 15 | public string name { get; } 16 | 17 | public uint sno { get; } 18 | 19 | [JsonConverter(typeof(CastActionConverter))] 20 | public AbstractCastAction castAction { get; set; } 21 | 22 | [JsonProperty(ItemConverterType = typeof(DefinitionConverter))] 23 | public List definitions { get; } 24 | 25 | public DefinitionGroup(string name, uint sno) 26 | { 27 | active = true; 28 | this.name = name; 29 | this.sno = sno; 30 | definitions = new List(); 31 | castAction = new DefaultCastAction(); 32 | } 33 | 34 | public bool Applicable(IController hud, IPlayerSkill skill) 35 | { 36 | return active && definitions.TrueForAll(definition => definition.Handle(hud, skill)); 37 | } 38 | 39 | public bool Invoke(IController hud, IPlayerSkill skill) 40 | { 41 | return castAction.Invoke(hud, skill); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /skills/DefinitionGroupsForSkill.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class DefinitionGroupsForSkill 6 | { 7 | public bool active { get; set; } 8 | 9 | public string heroClassName { get; } 10 | 11 | public string skillName { get; } 12 | 13 | public string configProfileName { get; } 14 | 15 | public List definitionGroups { get; } 16 | 17 | public DefinitionGroupsForSkill() 18 | { 19 | active = true; 20 | definitionGroups = new List(); 21 | } 22 | 23 | public DefinitionGroupsForSkill(string heroClassName, string skillName, string configProfileName) 24 | { 25 | active = true; 26 | definitionGroups = new List(); 27 | this.heroClassName = heroClassName; 28 | this.skillName = skillName; 29 | this.configProfileName = configProfileName; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /skills/SkillExecutor.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using Plugins; 7 | using Plugins.Patrick.forms; 8 | 9 | public class SkillExecutor 10 | { 11 | private readonly Dictionary lastSkillExectuion = new Dictionary(); 12 | 13 | private readonly Settings settings; 14 | 15 | private const long MINIMUM_CAST_DELTA = 500; 16 | 17 | public SkillExecutor(Settings settings) 18 | { 19 | this.settings = settings; 20 | } 21 | 22 | public void Cast(IPlayerSkill skill) 23 | { 24 | if (!settings.SnoToDefinitionGroups.TryGetValue(skill.SnoPower.Sno, out var definitionGroupsForSkill)) 25 | return; 26 | 27 | if (!definitionGroupsForSkill.active || !AllowedToCast(skill) || !Settings.KeyToActive[skill.Key]) 28 | return; 29 | 30 | var applicableGroup = 31 | definitionGroupsForSkill.definitionGroups.FirstOrDefault(definitionGroup => 32 | definitionGroup.Applicable(settings.Hud, skill)); 33 | 34 | if (applicableGroup?.Invoke(settings.Hud, skill) ?? false) 35 | lastSkillExectuion[applicableGroup.sno] = DateTimeOffset.Now.ToUnixTimeMilliseconds(); 36 | } 37 | 38 | private bool AllowedToCast(IPlayerSkill skill) 39 | { 40 | var sno = skill.SnoPower.Sno; 41 | var now = DateTimeOffset.Now.ToUnixTimeMilliseconds(); 42 | 43 | if (!lastSkillExectuion.ContainsKey(sno)) 44 | { 45 | lastSkillExectuion.Add(sno, now); 46 | return true; 47 | } 48 | 49 | var lastExecutionTime = lastSkillExectuion[sno]; 50 | return now - lastExecutionTime >= MINIMUM_CAST_DELTA; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /skills/SnoPowerList.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills 2 | { 3 | using System.Collections.Generic; 4 | 5 | public static class SnoPowerList 6 | { 7 | public static readonly Dictionary CoeElementToIndex = new Dictionary 8 | { 9 | {"Arcane", 1}, 10 | {"Cold", 2}, 11 | {"Fire", 3}, 12 | {"Holy", 4}, 13 | {"Lightning", 5}, 14 | {"Physical", 6}, 15 | {"Poison", 7} 16 | }; 17 | } 18 | } -------------------------------------------------------------------------------- /skills/castactions/AbstractCastAction.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.castactions 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using Plugins; 6 | using Plugins.Patrick.util; 7 | 8 | public abstract class AbstractCastAction 9 | { 10 | public static readonly List CastActionTypes = Misc.GetAllSubTypesFromType(typeof(AbstractCastAction)); 11 | 12 | public abstract string name { get; } 13 | 14 | public abstract bool Invoke(IController hud, IPlayerSkill skill); 15 | } 16 | } -------------------------------------------------------------------------------- /skills/castactions/actions/DefaultCastAction.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.castactions.actions 2 | { 3 | using patrick.util.thud; 4 | using Plugins; 5 | 6 | public class DefaultCastAction : AbstractCastAction 7 | { 8 | public override string name 9 | { 10 | get 11 | { 12 | return "DefaultCastAction"; 13 | } 14 | } 15 | 16 | public override bool Invoke(IController hud, IPlayerSkill skill) 17 | { 18 | if (skill.IsOnCooldown) 19 | return false; 20 | 21 | var resourceCostType = skill.SnoPower.ResourceCostTypeByRune[skill.Rune == 255 ? 0 : skill.Rune]; 22 | var currentResource = resourceCostType == PowerResourceCostType.primary 23 | ? hud.Game.Me.Stats.ResourceCurPri 24 | : hud.Game.Me.Stats.ResourceCurSec; 25 | 26 | if (currentResource < skill.GetResourceRequirement(skill.ResourceCost)) 27 | return false; 28 | 29 | skill.Cast(); 30 | return true; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /skills/definitions/AbstractDefinition.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using Newtonsoft.Json; 7 | using parameters; 8 | using Plugins; 9 | using Plugins.Patrick.util; 10 | 11 | public abstract class AbstractDefinition 12 | { 13 | 14 | public static readonly List DefinitionTypes = Misc.GetAllSubTypesFromType(typeof(AbstractDefinition)); 15 | 16 | public static readonly Dictionary> CategoryToType = DefinitionTypes 17 | .Select(type => (AbstractDefinition)Activator.CreateInstance(type)) 18 | .GroupBy(def => def.category, def => def.GetType()) 19 | .ToDictionary(def => def.Key, def => def.ToList()); 20 | 21 | [JsonIgnore] 22 | public DefinitionGroup definitionGroup { get; set; } 23 | 24 | public bool active { get; set; } 25 | 26 | public bool inverted { get; set; } 27 | 28 | protected AbstractDefinition() 29 | { 30 | active = true; 31 | inverted = false; 32 | } 33 | 34 | protected AbstractDefinition(bool inverted) 35 | { 36 | active = true; 37 | this.inverted = inverted; 38 | } 39 | 40 | public void SetParentDefinitionGroup(DefinitionGroup definitionGroup) 41 | { 42 | this.definitionGroup = definitionGroup; 43 | } 44 | 45 | public string name 46 | { 47 | get 48 | { 49 | return $"{category} - " + GetType().Name; 50 | } 51 | } 52 | 53 | [JsonIgnore] 54 | public virtual string tooltip 55 | { 56 | get 57 | { 58 | return "No tooltip available for this definition type!"; 59 | } 60 | } 61 | 62 | [JsonIgnore] 63 | public abstract DefinitionType category { get; } 64 | 65 | [JsonIgnore] 66 | public abstract string attributes { get; } 67 | 68 | public abstract List GetParameters(IController hud); 69 | 70 | public bool Handle(IController hud, IPlayerSkill skill) 71 | { 72 | var result = Applicable(hud, skill); 73 | 74 | return inverted ? !result : result; 75 | } 76 | 77 | protected abstract bool Applicable(IController hud, IPlayerSkill skill); 78 | } 79 | } -------------------------------------------------------------------------------- /skills/definitions/DefinitionType.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions 2 | { 3 | public enum DefinitionType 4 | { 5 | All, 6 | Party, 7 | Player, 8 | Skill, 9 | ItemSpecific, 10 | World 11 | } 12 | } -------------------------------------------------------------------------------- /skills/definitions/itemspecific/CoeRotation.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.itemspecific 2 | { 3 | using System.Collections.Generic; 4 | using Newtonsoft.Json; 5 | using parameters; 6 | using parameters.types; 7 | using Plugins; 8 | 9 | public class CoeRotation : AbstractDefinition 10 | { 11 | public string Element { get; set; } 12 | 13 | public int TimeLeft { get; set; } 14 | 15 | public override DefinitionType category => DefinitionType.ItemSpecific; 16 | 17 | public override string attributes => $"[ Element: {Element}, TimeLeft: {TimeLeft} ]"; 18 | 19 | public override List GetParameters(IController hud) 20 | { 21 | return new List 22 | { 23 | ContextParameter.of( 24 | nameof(Element), 25 | x => Element = (string)x, 26 | SnoPowerList.CoeElementToIndex.Keys 27 | ), 28 | SimpleParameter.of(nameof(TimeLeft), x => TimeLeft = x, 4000) 29 | }; 30 | } 31 | 32 | protected override bool Applicable(IController hud, IPlayerSkill skill) 33 | { 34 | if (!hud.Game.Me.Powers.BuffIsActive(hud.Sno.SnoPowers.ConventionOfElements.Sno)) 35 | return false; 36 | 37 | var buff = hud.Game.Me.Powers.GetBuff(hud.Sno.SnoPowers.ConventionOfElements.Sno); 38 | var elementIndex = SnoPowerList.CoeElementToIndex[Element]; 39 | if (buff.IconCounts[elementIndex] == 0) 40 | return false; 41 | 42 | return buff.TimeLeftSeconds[elementIndex] < TimeLeft / 1000.0; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /skills/definitions/itemspecific/CoeRotationOnHeroClass.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.itemspecific 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using parameters; 7 | using parameters.types; 8 | using Plugins; 9 | 10 | public class CoeRotationOnHeroClass : AbstractDefinition 11 | { 12 | public HeroClass Class { get; set; } 13 | 14 | public string Element { get; set; } 15 | 16 | public int TimeLeft { get; set; } 17 | 18 | public override DefinitionType category => DefinitionType.ItemSpecific; 19 | 20 | public override string attributes 21 | { 22 | get 23 | { 24 | var assembledHeroName = Class == HeroClass.None ? "" : $"Hero: {Class}, "; 25 | return 26 | $"[ {assembledHeroName}Element: {Element}, TimeLeft: {TimeLeft} ]"; 27 | } 28 | } 29 | 30 | public override List GetParameters(IController hud) 31 | { 32 | return new List 33 | { 34 | ContextParameter.of( 35 | nameof(Class), 36 | input => Class = (HeroClass)input, 37 | Enum.GetValues(typeof(HeroClass)).Cast() 38 | ), 39 | ContextParameter.of( 40 | nameof(Element), 41 | x => Element = (string)x, 42 | SnoPowerList.CoeElementToIndex.Keys 43 | ), 44 | SimpleParameter.of(nameof(TimeLeft), x => TimeLeft = x, 4000) 45 | }; 46 | } 47 | 48 | protected override bool Applicable(IController hud, IPlayerSkill skill) 49 | { 50 | if (!(hud.Game.Players 51 | .FirstOrDefault(player => 52 | !player.IsMe && (player.HeroClassDefinition.HeroClass == Class || Class == HeroClass.None) && 53 | player.Powers.BuffIsActive(hud.Sno.SnoPowers.ConventionOfElements.Sno)) 54 | ?.Powers.GetBuff(hud.Sno.SnoPowers.ConventionOfElements.Sno) is IBuff coe)) 55 | 56 | return false; 57 | 58 | var elementIndex = SnoPowerList.CoeElementToIndex[Element]; 59 | if (coe.IconCounts[elementIndex] == 0) 60 | return false; 61 | 62 | return coe.TimeLeftSeconds[elementIndex] < TimeLeft / 1000.0; 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /skills/definitions/party/AllPartyMembersInRange.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.party 2 | { 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using parameters; 6 | using parameters.types; 7 | using Plugins; 8 | 9 | public class AllPartyMembersInRange : AbstractDefinition 10 | { 11 | public int range { get; set; } 12 | 13 | public override DefinitionType category => DefinitionType.Party; 14 | 15 | public override string attributes => $"[ Range: {range} ]"; 16 | 17 | public override string tooltip 18 | { 19 | get 20 | { 21 | return "Checks if all party members are in the given range."; 22 | } 23 | } 24 | 25 | public override List GetParameters(IController hud) 26 | { 27 | return new List 28 | { 29 | SimpleParameter.of(nameof(range), x => range = x) 30 | }; 31 | } 32 | 33 | protected override bool Applicable(IController hud, IPlayerSkill skill) 34 | { 35 | return hud.Game.Players.Count(player => player.CentralXyDistanceToMe < range) == hud.Game.NumberOfPlayersInGame; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /skills/definitions/party/AllPlayersAlive.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.party 2 | { 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using parameters; 6 | using Plugins; 7 | 8 | public class AllPlayersAlive : AbstractDefinition 9 | { 10 | public override DefinitionType category => DefinitionType.Party; 11 | 12 | public override string attributes => ""; 13 | 14 | public override List GetParameters(IController hud) 15 | { 16 | return new List(); 17 | } 18 | 19 | protected override bool Applicable(IController hud, IPlayerSkill skill) 20 | { 21 | return hud.Game.Players.Count(player => !player.IsDead) == hud.Game.NumberOfPlayersInGame; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /skills/definitions/party/BuffStacksOnHeroClass.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.party 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Drawing; 6 | using System.Linq; 7 | using parameters; 8 | using parameters.types; 9 | using Plugins; 10 | using Plugins.Patrick.forms; 11 | using util; 12 | 13 | public class BuffStacksOnHeroClass : AbstractDefinition 14 | { 15 | public HeroClass Class { get; set; } 16 | 17 | public string BuffName { get; set; } 18 | 19 | public int Range { get; set; } 20 | 21 | public int Stacks { get; set; } 22 | 23 | public string Operator { get; set; } 24 | 25 | public uint SelectedSno { get; set; } 26 | 27 | public bool OverrideSelected { get; set; } 28 | 29 | public uint Sno { get; set; } 30 | 31 | public int IconIndex { get; set; } 32 | 33 | public override DefinitionType category => DefinitionType.Party; 34 | 35 | public override string attributes 36 | { 37 | get 38 | { 39 | var assembledHeroName = Class == HeroClass.None ? "" : $"Hero: {Class}, "; 40 | var assembledBuffName = OverrideSelected ? $"Sno: {Sno}, " : $"Buff: {BuffName}, "; 41 | var assembledRange = Range == 0 ? "" : $"Range: {Range}, "; 42 | return $"[ {assembledHeroName}{assembledBuffName}{assembledRange}Stacks {Operator} {Stacks}, IconIndex: {IconIndex} ]"; 43 | } 44 | } 45 | 46 | public override List GetParameters(IController hud) 47 | { 48 | return new List 49 | { 50 | ContextParameter.of( 51 | nameof(Class), 52 | input => Class = (HeroClass)input, 53 | Enum.GetValues(typeof(HeroClass)).Cast() 54 | ), 55 | SimpleParameter.of(nameof(Range), x => Range = x), 56 | ContextParameter.of( 57 | nameof(BuffName), 58 | input => 59 | { 60 | if (!(input is KeyValuePair pair)) 61 | return; 62 | BuffName = pair.Key; 63 | SelectedSno = pair.Value.Sno; 64 | }, 65 | Settings.NameToSnoPower, 66 | "Key" 67 | ), 68 | ContextParameter.of( 69 | nameof(Operator), 70 | x => Operator = (string)x, 71 | CompareWithOperator.AllOperators 72 | ), 73 | SimpleParameter.of(nameof(Stacks), x => Stacks = x), 74 | SimpleParameter.of(nameof(IconIndex), x => IconIndex = x), 75 | SimpleParameter.of(nameof(OverrideSelected), x => OverrideSelected = x), 76 | SimpleParameter.of(nameof(Sno), x => Sno = (uint)x), 77 | }; 78 | } 79 | 80 | protected override bool Applicable(IController hud, IPlayerSkill skill) 81 | { 82 | var playerWithBuff = hud.Game.Players.FirstOrDefault(player => !player.IsMe && 83 | (Class == HeroClass.None || player.HeroClassDefinition.HeroClass == Class) && 84 | (Range == 0 || player.CentralXyDistanceToMe <= Range) && 85 | player.Powers.GetBuff(OverrideSelected ? Sno : SelectedSno) != null); 86 | 87 | if (!(playerWithBuff?.Powers?.GetBuff(OverrideSelected ? Sno : SelectedSno) is IBuff buff)) 88 | return false; 89 | 90 | return CompareWithOperator.Compare(buff.IconCounts[IconIndex], Stacks, Operator); 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /skills/definitions/party/BuffTimeLeftOnHeroClass.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.party 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Drawing; 6 | using System.Linq; 7 | using parameters; 8 | using parameters.types; 9 | using Plugins; 10 | using Plugins.Patrick.forms; 11 | using util; 12 | 13 | public class BuffTimeLeftOnHeroClass : AbstractDefinition 14 | { 15 | public HeroClass Class { get; set; } 16 | 17 | public string BuffName { get; set; } 18 | 19 | public int Range { get; set; } 20 | 21 | public int TimeLeftInMs { get; set; } 22 | 23 | public string Operator { get; set; } 24 | 25 | public uint SelectedSno { get; set; } 26 | 27 | public bool OverrideSelected { get; set; } 28 | 29 | public uint Sno { get; set; } 30 | 31 | public int IconIndex { get; set; } 32 | 33 | public override DefinitionType category => DefinitionType.Party; 34 | 35 | public override string attributes 36 | { 37 | get 38 | { 39 | var assembledHeroName = Class == HeroClass.None ? "" : $"Hero: {Class}, "; 40 | var assembledBuffName = OverrideSelected ? $"Sno: {Sno}, " : $"Buff: {BuffName}, "; 41 | var assembledRange = Range == 0 ? "" : $"Range: {Range}, "; 42 | return $"[ {assembledHeroName}{assembledBuffName}{assembledRange}TimeLeft {Operator} {TimeLeftInMs}ms, IconIndex: {IconIndex} ]"; 43 | } 44 | } 45 | 46 | public override List GetParameters(IController hud) 47 | { 48 | return new List 49 | { 50 | ContextParameter.of( 51 | nameof(Class), 52 | input => Class = (HeroClass)input, 53 | Enum.GetValues(typeof(HeroClass)).Cast() 54 | ), 55 | SimpleParameter.of(nameof(Range), x => Range = x), 56 | ContextParameter.of( 57 | nameof(BuffName), 58 | input => 59 | { 60 | if (!(input is KeyValuePair pair)) 61 | return; 62 | BuffName = pair.Key; 63 | SelectedSno = pair.Value.Sno; 64 | }, 65 | Settings.NameToSnoPower, 66 | "Key" 67 | ), 68 | ContextParameter.of( 69 | nameof(Operator), 70 | x => Operator = (string)x, 71 | CompareWithOperator.AllOperators 72 | ), 73 | SimpleParameter.of(nameof(TimeLeftInMs), x => TimeLeftInMs = x), 74 | SimpleParameter.of(nameof(IconIndex), x => IconIndex = x), 75 | SimpleParameter.of(nameof(OverrideSelected), x => OverrideSelected = x), 76 | SimpleParameter.of(nameof(Sno), x => Sno = (uint)x), 77 | }; 78 | } 79 | 80 | protected override bool Applicable(IController hud, IPlayerSkill skill) 81 | { 82 | var playerWithBuff = hud.Game.Players.FirstOrDefault(player => !player.IsMe && 83 | (Class == HeroClass.None || player.HeroClassDefinition.HeroClass == Class) && 84 | (Range == 0 || player.CentralXyDistanceToMe <= Range) && 85 | player.Powers.GetBuff(OverrideSelected ? Sno : SelectedSno) != null); 86 | 87 | if (!(playerWithBuff?.Powers?.GetBuff(OverrideSelected ? Sno : SelectedSno) is IBuff buff)) 88 | return false; 89 | 90 | return !buff.Active || CompareWithOperator.Compare((int) (buff.TimeLeftSeconds[IconIndex] * 1000L), TimeLeftInMs, Operator); 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /skills/definitions/party/HeroClassCountInParty.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.party 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using parameters; 7 | using parameters.types; 8 | using Plugins; 9 | 10 | public class NumberOfHeroClassInParty : AbstractDefinition 11 | { 12 | public int Count { get; set; } 13 | 14 | public HeroClass Class { get; set; } 15 | 16 | public override DefinitionType category => DefinitionType.Party; 17 | 18 | public override string attributes => $"[ HeroClass: {Class}, Count: {Count} ]"; 19 | 20 | public override List GetParameters(IController hud) 21 | { 22 | return new List 23 | { 24 | ContextParameter.of( 25 | nameof(Class), 26 | input => Class = (HeroClass)input, 27 | Enum.GetValues(typeof(HeroClass)).Cast() 28 | ), 29 | SimpleParameter.of(nameof(Count), input => Count = input) 30 | }; 31 | } 32 | 33 | protected override bool Applicable(IController hud, IPlayerSkill skill) 34 | { 35 | return hud.Game.Players.Count(player => player.HeroClassDefinition.HeroClass == Class) == Count; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /skills/definitions/party/HeroClassHasSkillEquipped.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.party 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using parameters; 7 | using parameters.types; 8 | using Plugins; 9 | using Plugins.Patrick.forms; 10 | 11 | public class HeroClassHasSkillEquipped : AbstractDefinition 12 | { 13 | public HeroClass Class { get; set; } 14 | 15 | public uint sno { get; set; } 16 | 17 | public string SkillName { get; set; } 18 | 19 | public override DefinitionType category => DefinitionType.Party; 20 | 21 | public override string attributes => $"[ HeroClass: {Class}, Skill: {SkillName} ]"; 22 | 23 | public override List GetParameters(IController hud) 24 | { 25 | return new List 26 | { 27 | ContextParameter.of( 28 | nameof(Class), 29 | input => Class = (HeroClass)input, 30 | Enum.GetValues(typeof(HeroClass)).Cast() 31 | ), 32 | ContextParameter.of( 33 | nameof(SkillName), 34 | input => 35 | { 36 | if (!(input is ISnoPower power)) 37 | return; 38 | SkillName = power.NameEnglish; 39 | sno = power.Sno; 40 | }, 41 | Settings.HeroClassToSnoPowers[HeroClass.None], 42 | "NameEnglish" 43 | ) 44 | }; 45 | } 46 | 47 | protected override bool Applicable(IController hud, IPlayerSkill skill) 48 | { 49 | return hud.Game.Players.Where(player => player.HeroClassDefinition.HeroClass == Class) 50 | .Any(player => player.Powers.UsedSkills.Any(s => s.SnoPower.Sno == sno)); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /skills/definitions/party/IsBuffActiveOnHeroClass.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.party 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Drawing; 6 | using System.Linq; 7 | using parameters; 8 | using parameters.types; 9 | using Plugins; 10 | using Plugins.Patrick.forms; 11 | 12 | public class IsBuffActiveOnHeroClass : AbstractDefinition 13 | { 14 | public HeroClass Class { get; set; } 15 | 16 | public string BuffName { get; set; } 17 | 18 | public int Range { get; set; } 19 | 20 | public uint SelectedSno { get; set; } 21 | 22 | public bool OverrideSelected { get; set; } 23 | 24 | public uint Sno { get; set; } 25 | 26 | public int IconIndex { get; set; } 27 | 28 | public override DefinitionType category => DefinitionType.Party; 29 | 30 | public override string attributes 31 | { 32 | get 33 | { 34 | var assembledHeroName = Class == HeroClass.None ? "" : $"Hero: {Class}, "; 35 | var assembledBuffName = OverrideSelected ? $"Sno: {Sno}, " : $"Buff: {BuffName}, "; 36 | var assembledRange = Range == 0 ? "" : $"Range: {Range}, "; 37 | return $"[ {assembledHeroName}{assembledRange}{assembledBuffName}IconIndex: {IconIndex} ]"; 38 | } 39 | } 40 | 41 | public override List GetParameters(IController hud) 42 | { 43 | return new List 44 | { 45 | ContextParameter.of( 46 | nameof(Class), 47 | input => Class = (HeroClass)input, 48 | Enum.GetValues(typeof(HeroClass)).Cast() 49 | ), 50 | SimpleParameter.of(nameof(Range), x => Range = x), 51 | ContextParameter.of( 52 | nameof(BuffName), 53 | input => 54 | { 55 | if (!(input is KeyValuePair pair)) 56 | return; 57 | BuffName = pair.Key; 58 | SelectedSno = pair.Value.Sno; 59 | }, 60 | Settings.NameToSnoPower, 61 | "Key" 62 | ), 63 | SimpleParameter.of(nameof(IconIndex), x => IconIndex = x), 64 | SimpleParameter.of(nameof(OverrideSelected), x => OverrideSelected = x), 65 | SimpleParameter.of(nameof(Sno), x => Sno = (uint)x) 66 | }; 67 | } 68 | 69 | protected override bool Applicable(IController hud, IPlayerSkill skill) 70 | { 71 | return hud.Game.Players.Any(player => !player.IsMe && 72 | (Class == HeroClass.None || player.HeroClassDefinition.HeroClass == Class) && 73 | (Range == 0 || player.CentralXyDistanceToMe <= Range) && 74 | player.Powers.BuffIsActive(OverrideSelected ? Sno : SelectedSno, IconIndex)); 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /skills/definitions/party/IsSkillBuffActiveOnHeroClass.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.party 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using parameters; 7 | using parameters.types; 8 | using Plugins; 9 | using Plugins.Patrick.forms; 10 | 11 | public class IsSkillBuffActiveOnHeroClass : AbstractDefinition 12 | { 13 | public HeroClass Class { get; set; } 14 | 15 | public string BuffName { get; set; } 16 | 17 | public int Range { get; set; } 18 | 19 | public uint SelectedSno { get; set; } 20 | 21 | public bool OverrideSelected { get; set; } 22 | 23 | public uint Sno { get; set; } 24 | 25 | public override DefinitionType category => DefinitionType.Party; 26 | 27 | public override string attributes 28 | { 29 | get 30 | { 31 | var assembledHeroName = Class == HeroClass.None ? "" : $"Hero: {Class}, "; 32 | var assembledBuffName = OverrideSelected ? $"Sno: {Sno}" : $"Buff: {BuffName}"; 33 | var assembledRange = Range == 0 ? "" : $"Range: {Range}, "; 34 | return $"[ {assembledHeroName}{assembledRange}{assembledBuffName} ]"; 35 | } 36 | } 37 | 38 | public override List GetParameters(IController hud) 39 | { 40 | return new List 41 | { 42 | ContextParameter.of( 43 | nameof(Class), 44 | input => Class = (HeroClass)input, 45 | Enum.GetValues(typeof(HeroClass)).Cast() 46 | ), 47 | SimpleParameter.of(nameof(Range), x => Range = x), 48 | ContextParameter.of( 49 | nameof(BuffName), 50 | input => 51 | { 52 | if (!(input is KeyValuePair pair)) 53 | return; 54 | BuffName = pair.Key; 55 | SelectedSno = pair.Value.Sno; 56 | }, 57 | Settings.HeroClassToSnoPowers[HeroClass.None], 58 | "NameEnglish" 59 | ), 60 | SimpleParameter.of(nameof(OverrideSelected), x => OverrideSelected = x), 61 | SimpleParameter.of(nameof(Sno), x => Sno = (uint)x) 62 | }; 63 | } 64 | 65 | protected override bool Applicable(IController hud, IPlayerSkill skill) 66 | { 67 | return hud.Game.Players.Any(player => !player.IsMe && 68 | (Class == HeroClass.None || player.HeroClassDefinition.HeroClass == Class) && 69 | (Range == 0 || player.CentralXyDistanceToMe <= Range) && 70 | player.Powers.BuffIsActive(OverrideSelected ? Sno : SelectedSno)); 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /skills/definitions/party/PartyIsBuffable.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.party 2 | { 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using parameters; 6 | using Plugins; 7 | 8 | public class PartyIsBuffable : AbstractDefinition 9 | { 10 | public override DefinitionType category => DefinitionType.Party; 11 | 12 | public override string attributes => ""; 13 | 14 | public override List GetParameters(IController hud) 15 | { 16 | return new List(); 17 | } 18 | 19 | protected override bool Applicable(IController hud, IPlayerSkill skill) 20 | { 21 | return !hud.Game.Players.Any(player => PlayerUnbuffable(hud, player)); 22 | } 23 | 24 | private static bool PlayerUnbuffable(IController hud, IPlayer player) 25 | { 26 | return player.Powers.BuffIsActive(hud.Sno.SnoPowers.Generic_ActorLoadingBuff.Sno) || 27 | player.Powers.BuffIsActive(hud.Sno.SnoPowers.Generic_ActorGhostedBuff.Sno) || 28 | player.Powers.BuffIsActive(hud.Sno.SnoPowers.Generic_ActorInvulBuff.Sno) || 29 | player.Powers.BuffIsActive(hud.Sno.SnoPowers.Generic_UntargetableDuringBuff.Sno); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /skills/definitions/party/PlayerCountInParty.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.party 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using parameters.types; 6 | using Plugins; 7 | 8 | public class PlayerCountInParty : AbstractDefinition 9 | { 10 | public int playerCountInParty { get; set; } 11 | 12 | public override DefinitionType category => DefinitionType.Party; 13 | 14 | public override string attributes => $"[ Player count: {playerCountInParty} ]"; 15 | 16 | public override List GetParameters(IController hud) 17 | { 18 | return new List 19 | { 20 | SimpleParameter.of(nameof(playerCountInParty), x => playerCountInParty = x) 21 | }; 22 | } 23 | 24 | protected override bool Applicable(IController hud, IPlayerSkill skill) 25 | { 26 | return hud.Game.NumberOfPlayersInGame == playerCountInParty; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /skills/definitions/player/BuffStacks.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.player 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using parameters.types; 6 | using Plugins; 7 | using Plugins.Patrick.forms; 8 | using util; 9 | 10 | public class BuffStacks : AbstractDefinition 11 | { 12 | public string BuffName { get; set; } 13 | 14 | public int Stacks { get; set; } 15 | 16 | public string Operator { get; set; } 17 | 18 | public uint SelectedSno { get; set; } 19 | 20 | public bool OverrideSelected { get; set; } 21 | 22 | public uint Sno { get; set; } 23 | 24 | public int IconIndex { get; set; } 25 | 26 | public override DefinitionType category => DefinitionType.Player; 27 | 28 | public override string attributes 29 | { 30 | get 31 | { 32 | var assembledBuffName = OverrideSelected ? $"Sno: {Sno}, " : $"Buff: {BuffName}, "; 33 | return $"[ {assembledBuffName}Stacks {Operator} {Stacks}, IconIndex: {IconIndex} ]"; 34 | } 35 | } 36 | 37 | public override List GetParameters(IController hud) 38 | { 39 | return new List 40 | { 41 | ContextParameter.of( 42 | nameof(BuffName), 43 | input => 44 | { 45 | if (!(input is KeyValuePair pair)) 46 | return; 47 | BuffName = pair.Key; 48 | SelectedSno = pair.Value.Sno; 49 | }, 50 | Settings.NameToSnoPower, 51 | "Key" 52 | ), 53 | ContextParameter.of( 54 | nameof(Operator), 55 | x => Operator = (string)x, 56 | CompareWithOperator.AllOperators 57 | ), 58 | SimpleParameter.of(nameof(Stacks), x => Stacks = x), 59 | SimpleParameter.of(nameof(IconIndex), x => IconIndex = x), 60 | SimpleParameter.of(nameof(OverrideSelected), x => 61 | { 62 | OverrideSelected = x; 63 | if (OverrideSelected) 64 | BuffName = ""; 65 | }), 66 | SimpleParameter.of(nameof(Sno), x => Sno = (uint)x), 67 | }; 68 | } 69 | 70 | protected override bool Applicable(IController hud, IPlayerSkill skill) 71 | { 72 | if (!(hud.Game.Me.Powers.GetBuff(OverrideSelected ? Sno : SelectedSno) is IBuff buff)) 73 | return false; 74 | 75 | return CompareWithOperator.Compare(buff.IconCounts[IconIndex], Stacks, Operator); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /skills/definitions/player/BuffTimeLeft.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.player 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using parameters.types; 6 | using Plugins; 7 | using Plugins.Patrick.forms; 8 | using util; 9 | 10 | public class BuffTimeLeft : AbstractDefinition 11 | { 12 | public string BuffName { get; set; } 13 | 14 | public int TimeLeftInMs { get; set; } 15 | 16 | public string Operator { get; set; } 17 | 18 | public uint SelectedSno { get; set; } 19 | 20 | public bool OverrideSelected { get; set; } 21 | 22 | public uint Sno { get; set; } 23 | 24 | public int IconIndex { get; set; } 25 | 26 | public override DefinitionType category => DefinitionType.Player; 27 | 28 | public override string attributes 29 | { 30 | get 31 | { 32 | var assembledBuffName = OverrideSelected ? $"Sno: {Sno}, " : $"Buff: {BuffName}, "; 33 | return $"[ {assembledBuffName}TimeLeft {Operator} {TimeLeftInMs}ms, IconIndex: {IconIndex} ]"; 34 | } 35 | } 36 | 37 | public override List GetParameters(IController hud) 38 | { 39 | return new List 40 | { 41 | ContextParameter.of( 42 | nameof(BuffName), 43 | input => 44 | { 45 | if (!(input is KeyValuePair pair)) 46 | return; 47 | BuffName = pair.Key; 48 | SelectedSno = pair.Value.Sno; 49 | }, 50 | Settings.NameToSnoPower, 51 | "Key" 52 | ), 53 | ContextParameter.of( 54 | nameof(Operator), 55 | x => Operator = (string)x, 56 | CompareWithOperator.AllOperators 57 | ), 58 | SimpleParameter.of(nameof(TimeLeftInMs), x => TimeLeftInMs = x), 59 | SimpleParameter.of(nameof(IconIndex), x => IconIndex = x), 60 | SimpleParameter.of(nameof(OverrideSelected), x => 61 | { 62 | OverrideSelected = x; 63 | if (OverrideSelected) 64 | BuffName = ""; 65 | }), 66 | SimpleParameter.of(nameof(Sno), x => Sno = (uint)x), 67 | }; 68 | } 69 | 70 | protected override bool Applicable(IController hud, IPlayerSkill skill) 71 | { 72 | var timeLeft = hud.Game.Me.Powers.GetBuff(OverrideSelected ? Sno : SelectedSno) is IBuff buff 73 | ? buff.TimeLeftSeconds[IconIndex] 74 | : 0; 75 | 76 | return CompareWithOperator.Compare((int) (timeLeft * 1000L), TimeLeftInMs, Operator); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /skills/definitions/player/CoolExampleDefinitionType.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.player 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using parameters; 7 | using parameters.types; 8 | using Plugins; 9 | 10 | public class CoolExampleDefinitionType : AbstractDefinition 11 | { 12 | public string Rune { get; set; } 13 | 14 | public string MateWithName { get; set; } 15 | 16 | public bool BossIsSpawned { get; set; } 17 | 18 | public int NumberOfDhsInGame { get; set; } 19 | 20 | public SpecialArea SpecialArea { get; set; } 21 | 22 | public override DefinitionType category => DefinitionType.Player; 23 | 24 | public override string attributes => 25 | $"[ Rune: {Rune}, BossIsSpawned: {BossIsSpawned}, Number of DHs: {NumberOfDhsInGame}, Area: {SpecialArea} ]"; 26 | 27 | public override List GetParameters(IController hud) 28 | { 29 | return new List 30 | { 31 | ContextParameter.of( 32 | nameof(Rune), 33 | x => Rune = (string)x, 34 | hud.Sno.GetSnoPower(definitionGroup.sno)?.RuneNamesEnglish 35 | ), 36 | SimpleParameter.of(nameof(MateWithName), x => MateWithName = x), 37 | SimpleParameter.of(nameof(BossIsSpawned), x => BossIsSpawned = x), 38 | SimpleParameter.of(nameof(NumberOfDhsInGame), input => NumberOfDhsInGame = input), 39 | ContextParameter.of( 40 | nameof(SpecialArea), 41 | input => SpecialArea = (SpecialArea)input, 42 | Enum.GetValues(typeof(SpecialArea)).Cast() 43 | ) 44 | }; 45 | } 46 | 47 | public override string tooltip 48 | { 49 | get 50 | { 51 | return "Exmaple definition type to show off some settings!"; 52 | } 53 | } 54 | 55 | protected override bool Applicable(IController hud, IPlayerSkill skill) 56 | { 57 | var correctRune = skill.RuneNameEnglish.Equals(Rune); 58 | var mateWithNameInGame = hud.Game.Players.Any(p => p.HeroName.Equals(MateWithName)); 59 | var bossIsSpawnedCorrect = hud.Game.Monsters.Any(monster => monster.Rarity == ActorRarity.Boss) == BossIsSpawned; 60 | var numberOfDhsInGameCorrect = hud.Game.Players 61 | .Where(player => !player.IsMe) 62 | .Count(player => player.HeroClassDefinition.HeroClass == HeroClass.DemonHunter) == 63 | NumberOfDhsInGame; 64 | var correctSpecialArea = hud.Game.SpecialArea == SpecialArea; 65 | 66 | 67 | return correctRune && bossIsSpawnedCorrect && numberOfDhsInGameCorrect && correctSpecialArea && mateWithNameInGame; 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /skills/definitions/player/CurrentAnimationState.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.player 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using parameters; 7 | using parameters.types; 8 | using Plugins; 9 | 10 | public class CurrentAnimationState : AbstractDefinition 11 | { 12 | 13 | public AcdAnimationState AnimationState { get; set; } 14 | 15 | public override DefinitionType category => DefinitionType.Player; 16 | 17 | public override string attributes => $"[ AnimationState: {AnimationState} ]"; 18 | 19 | public override List GetParameters(IController hud) 20 | { 21 | return new List 22 | { 23 | ContextParameter.of( 24 | nameof(AnimationState), 25 | input => AnimationState = (AcdAnimationState)input, 26 | Enum.GetValues(typeof(AcdAnimationState)).Cast() 27 | ) 28 | }; 29 | } 30 | 31 | protected override bool Applicable(IController hud, IPlayerSkill skill) 32 | { 33 | return hud.Game.Me.AnimationState == AnimationState; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /skills/definitions/player/EliteInFocus.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.player 2 | { 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using parameters; 6 | using parameters.types; 7 | using Plugins; 8 | 9 | public class EliteInFocus : AbstractDefinition 10 | { 11 | public bool IncludeShocktower { get; set; } 12 | 13 | public override DefinitionType category => DefinitionType.Player; 14 | 15 | public override string attributes => $"[ Include Shocktower: {IncludeShocktower} ]"; 16 | 17 | public override List GetParameters(IController hud) 18 | { 19 | return new List {SimpleParameter.of(nameof(IncludeShocktower), x => IncludeShocktower = x)}; 20 | } 21 | 22 | protected override bool Applicable(IController hud, IPlayerSkill skill) 23 | { 24 | var selectedMonster = hud.Game.SelectedMonster2 ?? hud.Game.SelectedMonster1; 25 | if (selectedMonster is null) 26 | return false; 27 | 28 | var eliteTargeted = selectedMonster.Rarity == ActorRarity.Champion || selectedMonster.Rarity == ActorRarity.Rare || 29 | selectedMonster.Rarity == ActorRarity.Unique || selectedMonster.Rarity == ActorRarity.Boss; 30 | 31 | return eliteTargeted || (IncludeShocktower && hud.Game.AliveMonsters.Any(monster => monster.SnoActor.Sno == ActorSnoEnum._x1_pand_ext_ordnance_tower_shock_a)); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /skills/definitions/player/HasSkillEquipped.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.player 2 | { 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using parameters; 6 | using parameters.types; 7 | using Plugins; 8 | using Plugins.Patrick.forms; 9 | 10 | public class HasSkillEquipped : AbstractDefinition 11 | { 12 | public uint sno { get; set; } 13 | 14 | public string SkillName { get; set; } 15 | 16 | public override DefinitionType category => DefinitionType.Player; 17 | 18 | public override string attributes => $"[ SkillName: {SkillName} ]"; 19 | 20 | public override List GetParameters(IController hud) 21 | { 22 | return new List 23 | { 24 | ContextParameter.of( 25 | nameof(SkillName), 26 | input => 27 | { 28 | if (!(input is ISnoPower power)) 29 | return; 30 | SkillName = power.NameEnglish; 31 | sno = power.Sno; 32 | }, 33 | Settings.HeroClassToSnoPowers[hud.Game.Me.HeroClassDefinition.HeroClass], 34 | "NameEnglish" 35 | ) 36 | }; 37 | } 38 | 39 | protected override bool Applicable(IController hud, IPlayerSkill skill) 40 | { 41 | return hud.Game.Me.Powers.UsedSkills.Any(usedSkill => usedSkill.SnoPower.Sno == sno); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /skills/definitions/player/IsBuffActive.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.player 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using parameters.types; 6 | using Plugins; 7 | using Plugins.Patrick.forms; 8 | 9 | public class IsBuffActive : AbstractDefinition 10 | { 11 | public string BuffName { get; set; } 12 | 13 | public uint SelectedSno { get; set; } 14 | 15 | public int IconIndex { get; set; } 16 | 17 | public bool OverrideSelected { get; set; } 18 | 19 | public uint Sno { get; set; } 20 | 21 | public override DefinitionType category => DefinitionType.Player; 22 | 23 | public override string attributes 24 | { 25 | get 26 | { 27 | var assembledOverride = OverrideSelected ? $"Sno: {Sno}, " : $"Buff: {BuffName}, "; 28 | return $"[ {assembledOverride}IconIndex: {IconIndex} ]"; 29 | } 30 | } 31 | 32 | public override List GetParameters(IController hud) 33 | { 34 | return new List 35 | { 36 | ContextParameter.of( 37 | nameof(BuffName), 38 | input => 39 | { 40 | if (!(input is KeyValuePair pair)) 41 | return; 42 | BuffName = pair.Key; 43 | SelectedSno = pair.Value.Sno; 44 | }, 45 | Settings.NameToSnoPower, 46 | "Key" 47 | ), 48 | SimpleParameter.of(nameof(IconIndex), x => IconIndex = x), 49 | SimpleParameter.of(nameof(OverrideSelected), x => OverrideSelected = x), 50 | SimpleParameter.of(nameof(Sno), x => Sno = (uint)x) 51 | }; 52 | } 53 | 54 | protected override bool Applicable(IController hud, IPlayerSkill skill) 55 | { 56 | return hud.Game.Me.Powers.BuffIsActive(OverrideSelected ? Sno : SelectedSno, IconIndex); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /skills/definitions/player/IsSkillBuffActive.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.player 2 | { 3 | using System.Collections.Generic; 4 | using System.Drawing; 5 | using parameters; 6 | using parameters.types; 7 | using Plugins; 8 | using Plugins.Patrick.forms; 9 | 10 | public class IsSkillBuffActive : AbstractDefinition 11 | { 12 | public string BuffName { get; set; } 13 | 14 | public uint SelectedSno { get; set; } 15 | 16 | public bool OverrideSelected { get; set; } 17 | 18 | public uint Sno { get; set; } 19 | 20 | public int IconIndex { get; set; } 21 | 22 | public override DefinitionType category => DefinitionType.Player; 23 | 24 | public override string attributes 25 | { 26 | get 27 | { 28 | var assembledBuffName = OverrideSelected ? $"Sno: {Sno}, " : $"SkillBuff: {BuffName}, "; 29 | return $"[ {assembledBuffName}IconIndex: {IconIndex} ]"; 30 | } 31 | } 32 | 33 | public override List GetParameters(IController hud) 34 | { 35 | return new List 36 | { 37 | ContextParameter.of( 38 | nameof(BuffName), 39 | input => 40 | { 41 | if (!(input is ISnoPower power)) 42 | return; 43 | BuffName = power.NameEnglish; 44 | SelectedSno = power.Sno; 45 | }, 46 | Settings.HeroClassToSnoPowers[HeroClass.None], 47 | "NameEnglish" 48 | ), 49 | SimpleParameter.of(nameof(IconIndex), x => IconIndex = x), 50 | SimpleParameter.of(nameof(OverrideSelected), x => OverrideSelected = x), 51 | SimpleParameter.of(nameof(Sno), x => Sno = (uint)x) 52 | }; 53 | } 54 | 55 | protected override bool Applicable(IController hud, IPlayerSkill skill) 56 | { 57 | return hud.Game.Me.Powers.BuffIsActive(OverrideSelected ? Sno : SelectedSno, IconIndex); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /skills/definitions/player/MinimumHealthPercent.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.player 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using parameters; 6 | using parameters.types; 7 | using Plugins; 8 | 9 | public class MinimumHealthPercent : AbstractDefinition 10 | { 11 | public int minimumHealthPercent { get; set; } 12 | 13 | public override DefinitionType category => DefinitionType.Player; 14 | 15 | public override string attributes => $"[ minimumHealthPercent: {minimumHealthPercent} ]"; 16 | 17 | public override List GetParameters(IController hud) 18 | { 19 | return new List 20 | { 21 | SimpleParameter.of(nameof(minimumHealthPercent), x => minimumHealthPercent = x) 22 | }; 23 | } 24 | 25 | protected override bool Applicable(IController hud, IPlayerSkill skill) 26 | { 27 | return hud.Game.Me.Defense.HealthPct >= minimumHealthPercent; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /skills/definitions/player/MinimumResource.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.player 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using parameters.types; 6 | using Plugins; 7 | 8 | public class MinimumResource : AbstractDefinition 9 | { 10 | public bool UsePercentage { get; set; } 11 | 12 | public bool UseSecondaryResource { get; set; } 13 | 14 | public int MinimumAmount { get; set; } 15 | 16 | public override DefinitionType category => DefinitionType.Player; 17 | 18 | public override string attributes => $"[ Minimum {(UseSecondaryResource ? "secondary" : "primary")} resource: {MinimumAmount}{(UsePercentage ? "%" : " (absolute)")} ]"; 19 | 20 | public override List GetParameters(IController hud) 21 | { 22 | return new List 23 | { 24 | SimpleParameter.of(nameof(UsePercentage), x => UsePercentage = x), 25 | SimpleParameter.of(nameof(UseSecondaryResource), x => UseSecondaryResource = x), 26 | SimpleParameter.of(nameof(MinimumAmount), x => MinimumAmount = x) 27 | }; 28 | } 29 | 30 | protected override bool Applicable(IController hud, IPlayerSkill skill) 31 | { 32 | var resourceAmount = UsePercentage 33 | ? UseSecondaryResource ? hud.Game.Me.Stats.ResourcePctSec : hud.Game.Me.Stats.ResourcePctPri 34 | : UseSecondaryResource ? hud.Game.Me.Stats.ResourceCurSec : hud.Game.Me.Stats.ResourceCurPri; 35 | 36 | return resourceAmount >= MinimumAmount; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /skills/definitions/skill/ForceCastInterval.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.skill 2 | { 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using Newtonsoft.Json; 6 | using parameters; 7 | using parameters.types; 8 | using Plugins; 9 | 10 | public class ForceCastInterval : AbstractDefinition 11 | { 12 | public int IntervalInMs { get; set; } 13 | 14 | [JsonIgnore] 15 | private readonly Stopwatch watch = Stopwatch.StartNew(); 16 | 17 | public override DefinitionType category => DefinitionType.Skill; 18 | 19 | public override string attributes => $"[ Interval: {IntervalInMs}ms ]"; 20 | 21 | public override List GetParameters(IController hud) 22 | { 23 | return new List {SimpleParameter.of(nameof(IntervalInMs), x => IntervalInMs = x)}; 24 | } 25 | 26 | protected override bool Applicable(IController hud, IPlayerSkill skill) 27 | { 28 | if (watch.ElapsedMilliseconds <= IntervalInMs) 29 | return false; 30 | 31 | watch.Restart(); 32 | return true; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /skills/definitions/skill/HasRuneEquipped.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.skill 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using parameters.types; 6 | using Plugins; 7 | 8 | public class HasRuneEquipped : AbstractDefinition 9 | { 10 | public string Rune { get; set; } 11 | 12 | public override DefinitionType category => DefinitionType.Skill; 13 | 14 | public override string attributes => $"[ rune: {Rune} ]"; 15 | 16 | public override List GetParameters(IController hud) 17 | { 18 | return new List 19 | { 20 | ContextParameter.of( 21 | nameof(Rune), 22 | x => Rune = (string)x, 23 | hud.Sno.GetSnoPower(definitionGroup.sno)?.RuneNamesEnglish 24 | ) 25 | }; 26 | } 27 | 28 | protected override bool Applicable(IController hud, IPlayerSkill skill) 29 | { 30 | return skill.RuneNameEnglish.Equals(Rune); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /skills/definitions/skill/MinimumResourcePercent.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.skill 2 | { 3 | using System.Collections.Generic; 4 | using parameters; 5 | using parameters.types; 6 | using Plugins; 7 | 8 | public class MinimumResourcePercent : AbstractDefinition 9 | { 10 | public int minimumResourcePercent { get; set; } 11 | 12 | public override DefinitionType category => DefinitionType.Skill; 13 | 14 | public override string attributes => $"[ minimumResourcePercent: {minimumResourcePercent} ]"; 15 | 16 | public override List GetParameters(IController hud) 17 | { 18 | return new List 19 | { 20 | SimpleParameter.of(nameof(minimumResourcePercent), x => minimumResourcePercent = x) 21 | }; 22 | } 23 | 24 | protected override bool Applicable(IController hud, IPlayerSkill skill) 25 | { 26 | var resourceType = skill.SnoPower.ResourceCostTypeByRune[skill.Rune == 255 ? 0 : skill.Rune]; 27 | var resourcePercent = resourceType == PowerResourceCostType.primary 28 | ? hud.Game.Me.Stats.ResourcePctPri 29 | : hud.Game.Me.Stats.ResourcePctSec; 30 | 31 | return resourcePercent >= minimumResourcePercent; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /skills/definitions/world/BossSpawned.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.world 2 | { 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using parameters; 6 | using parameters.types; 7 | using Plugins; 8 | 9 | public class BossIsSpawned : AbstractDefinition 10 | { 11 | public override DefinitionType category => DefinitionType.World; 12 | 13 | public override string attributes => ""; 14 | 15 | public override List GetParameters(IController hud) 16 | { 17 | return new List(); 18 | } 19 | 20 | protected override bool Applicable(IController hud, IPlayerSkill skill) 21 | { 22 | return hud.Game.Monsters.Any(monster => monster.Rarity == ActorRarity.Boss); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /skills/definitions/world/CorpsesInRange.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.world 2 | { 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using parameters; 6 | using parameters.types; 7 | using Plugins; 8 | 9 | public class CorpsesInRange : AbstractDefinition 10 | { 11 | public int MinimumAmount { get; set; } 12 | 13 | public int Range { get; set; } 14 | 15 | public override DefinitionType category => DefinitionType.World; 16 | 17 | public override string attributes => $"[ Minimum amount: {MinimumAmount}, Range: {Range} ]"; 18 | 19 | public override List GetParameters(IController hud) 20 | { 21 | return new List 22 | { 23 | SimpleParameter.of(nameof(MinimumAmount), x => MinimumAmount = x), 24 | SimpleParameter.of(nameof(Range), x => Range = x) 25 | }; 26 | } 27 | 28 | protected override bool Applicable(IController hud, IPlayerSkill skill) 29 | { 30 | return hud.Game.Actors.Count(actor => 31 | (Range == 0 || actor.CentralXyDistanceToMe <= Range) && 32 | actor.SnoActor.Sno == ActorSnoEnum._p6_necro_corpse_flesh) >= MinimumAmount; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /skills/definitions/world/CurrentSpecialArea.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.world 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using parameters; 7 | using parameters.types; 8 | using Plugins; 9 | 10 | public class CurrentSpecialArea : AbstractDefinition 11 | { 12 | public SpecialArea Area { get; set; } 13 | 14 | public override DefinitionType category => DefinitionType.World; 15 | 16 | public override string attributes => $"[ area: {Area} ]"; 17 | 18 | public override List GetParameters(IController hud) 19 | { 20 | return new List 21 | { 22 | ContextParameter.of( 23 | nameof(Area), 24 | input => Area = (SpecialArea)input, 25 | Enum.GetValues(typeof(SpecialArea)).Cast() 26 | ) 27 | }; 28 | } 29 | 30 | protected override bool Applicable(IController hud, IPlayerSkill skill) 31 | { 32 | return hud.Game.SpecialArea == Area; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /skills/definitions/world/EliteInRange.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.world 2 | { 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using parameters; 6 | using parameters.types; 7 | using Plugins; 8 | 9 | public class EliteInRange : AbstractDefinition 10 | { 11 | 12 | public int MinimumAmount { get; set; } 13 | 14 | public int Range { get; set; } 15 | 16 | public override DefinitionType category => DefinitionType.World; 17 | 18 | public override string attributes => $"[ Minimum amount: {MinimumAmount}, Range: {Range} ]"; 19 | 20 | public override List GetParameters(IController hud) 21 | { 22 | return new List 23 | { 24 | SimpleParameter.of(nameof(MinimumAmount), x => MinimumAmount = x), 25 | SimpleParameter.of(nameof(Range), x => Range = x) 26 | }; 27 | } 28 | 29 | protected override bool Applicable(IController hud, IPlayerSkill skill) 30 | { 31 | return hud.Game.AliveMonsters.Count(mon => IsElite(mon) && mon.CentralXyDistanceToMe <= Range) >= MinimumAmount; 32 | } 33 | 34 | private static bool IsElite(IMonster monster) 35 | { 36 | return monster.Rarity == ActorRarity.Champion || monster.Rarity == ActorRarity.Rare || monster.Rarity == ActorRarity.Unique || 37 | monster.Rarity == ActorRarity.Boss; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /skills/definitions/world/MonstersInRange.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.definitions.world 2 | { 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using parameters; 6 | using parameters.types; 7 | using Plugins; 8 | 9 | public class MonstersInRange : AbstractDefinition 10 | { 11 | public int MinimumAmount { get; set; } 12 | 13 | public int Range { get; set; } 14 | 15 | public override DefinitionType category => DefinitionType.World; 16 | 17 | public override string attributes => $"[ Minimum amount: {MinimumAmount}, Range: {Range} ]"; 18 | 19 | public override List GetParameters(IController hud) 20 | { 21 | return new List 22 | { 23 | SimpleParameter.of(nameof(MinimumAmount), x => MinimumAmount = x), 24 | SimpleParameter.of(nameof(Range), x => Range = x) 25 | }; 26 | } 27 | 28 | protected override bool Applicable(IController hud, IPlayerSkill skill) 29 | { 30 | return hud.Game.AliveMonsters.Count(monster => monster.CentralXyDistanceToMe <= Range) >= MinimumAmount; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /skills/util/CompareWithOperator.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.skills.util 2 | { 3 | using System.Collections.Generic; 4 | 5 | public static class CompareWithOperator 6 | { 7 | public static readonly List AllOperators = new List 8 | { 9 | "equal to", 10 | "unequal to", 11 | "less than", 12 | "greater than" 13 | }; 14 | 15 | public static bool Compare(int actual, int excepted, string op) 16 | { 17 | switch (op) 18 | { 19 | case "equal to": 20 | return actual == excepted; 21 | case "unequal to": 22 | return actual != excepted; 23 | case "less than": 24 | return actual < excepted; 25 | case "greater than": 26 | return actual > excepted; 27 | default: 28 | return false; 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /util/Misc.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.Plugins.Patrick.util 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Diagnostics; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Reflection; 9 | using System.Runtime.InteropServices; 10 | using System.Text; 11 | using System.Windows.Forms; 12 | 13 | public static class Misc 14 | { 15 | public static void ForEachWithIndex(this IEnumerable enumerable, Action action) 16 | { 17 | var index = 0; 18 | foreach (var item in enumerable) 19 | action(item, index++); 20 | } 21 | 22 | public static bool AreYouSureDialogConfirmed(string text) 23 | { 24 | return MessageBox.Show(text, "Are you sure?", MessageBoxButtons.YesNo) == DialogResult.Yes; 25 | } 26 | 27 | public static List GetAllSubTypesFromType(Type baseType) 28 | { 29 | return Assembly.GetAssembly(baseType).GetTypes() 30 | .Where(type => type.IsClass && !type.IsAbstract && type.IsSubclassOf(baseType)) 31 | .ToList(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /util/config/jsonconverter/AutoActionConverter.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.Plugins.Patrick.util.config.jsonconverter 2 | { 3 | using System; 4 | using System.Linq; 5 | using autoactions; 6 | using Newtonsoft.Json; 7 | using Newtonsoft.Json.Linq; 8 | using plugins.patrick.autoactions.actions; 9 | 10 | public class AutoActionConverter : JsonConverter 11 | { 12 | public override void WriteJson(JsonWriter writer, AbstractAutoAction value, JsonSerializer serializer) 13 | { 14 | var token = JObject.FromObject(value); 15 | token.AddFirst(new JProperty("type", value.GetType().ToString())); 16 | token.WriteTo(writer); 17 | } 18 | 19 | public override AbstractAutoAction ReadJson(JsonReader reader, Type objectType, AbstractAutoAction existingValue, bool hasExistingValue, 20 | JsonSerializer serializer) 21 | { 22 | var autoAction = JObject.Load(reader); 23 | autoAction.Remove("name"); 24 | 25 | var autoActionTypeName = (autoAction["type"] ?? throw new InvalidOperationException("Type missing from AutoAction!")).Value(); 26 | var autoActionType = GetAutoActionType(autoActionTypeName); 27 | 28 | var result = Activator.CreateInstance(autoActionType); 29 | serializer.Populate(autoAction.CreateReader(), result); 30 | 31 | return result as AbstractAutoAction; 32 | } 33 | 34 | private static Type GetAutoActionType(string typeName) 35 | { 36 | return AbstractAutoAction.AutoActionTypes.First(type => type.ToString().Equals(typeName)); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /util/config/jsonconverter/CastActionConverter.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.Plugins.Patrick.util.config.jsonconverter 2 | { 3 | using System; 4 | using System.Linq; 5 | using Newtonsoft.Json; 6 | using Newtonsoft.Json.Linq; 7 | using plugins.patrick.skills.castactions; 8 | 9 | public class CastActionConverter : JsonConverter 10 | { 11 | public override void WriteJson(JsonWriter writer, AbstractCastAction value, JsonSerializer serializer) 12 | { 13 | var token = JObject.FromObject(value); 14 | token.AddFirst(new JProperty("type", value.GetType().ToString())); 15 | token.WriteTo(writer); 16 | } 17 | 18 | public override AbstractCastAction ReadJson(JsonReader reader, Type objectType, AbstractCastAction existingValue, 19 | bool hasExistingValue, 20 | JsonSerializer serializer) 21 | { 22 | var castAction = JObject.Load(reader); 23 | 24 | var typeName = (castAction["type"] ?? throw new InvalidOperationException("Type missing from CastAction!")).Value(); 25 | var type = GetCastActionType(typeName); 26 | 27 | var result = Activator.CreateInstance(type); 28 | serializer.Populate(castAction.CreateReader(), result); 29 | 30 | return result as AbstractCastAction; 31 | } 32 | 33 | private static Type GetCastActionType(string typeName) 34 | { 35 | return AbstractCastAction.CastActionTypes.First(type => type.ToString().Equals(typeName)); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /util/config/jsonconverter/DefinitionConverter.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.Plugins.Patrick.util.config.jsonconverter 2 | { 3 | using System; 4 | using System.Linq; 5 | using Newtonsoft.Json; 6 | using Newtonsoft.Json.Linq; 7 | using plugins.patrick.skills.definitions; 8 | 9 | public class DefinitionConverter : JsonConverter 10 | { 11 | public override void WriteJson(JsonWriter writer, AbstractDefinition value, JsonSerializer serializer) 12 | { 13 | var token = JObject.FromObject(value); 14 | token.AddFirst(new JProperty("type", value.GetType().ToString())); 15 | token.WriteTo(writer); 16 | } 17 | 18 | public override AbstractDefinition ReadJson( 19 | JsonReader reader, 20 | Type objectType, 21 | AbstractDefinition existingValue, 22 | bool hasExistingValue, 23 | JsonSerializer serializer 24 | ) 25 | { 26 | var definition = JObject.Load(reader); 27 | 28 | var definitionTypeName = (definition["type"] ?? throw new InvalidOperationException("Type missing from Definition!")).Value(); 29 | var definitionType = GetDefinitionType(definitionTypeName); 30 | 31 | var result = Activator.CreateInstance(definitionType); 32 | serializer.Populate(definition.CreateReader(), result); 33 | 34 | return result as AbstractDefinition; 35 | } 36 | 37 | private static Type GetDefinitionType(string typeName) 38 | { 39 | return AbstractDefinition.DefinitionTypes.First(type => type.ToString().Equals(typeName)); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /util/config/jsonconverter/HotkeyConverter.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.Plugins.Patrick.util.config.jsonconverter 2 | { 3 | using System; 4 | using System.Linq; 5 | using Newtonsoft.Json; 6 | using Newtonsoft.Json.Linq; 7 | using plugins.patrick.hotkeys.actions; 8 | 9 | public class HotkeyConverter: JsonConverter 10 | { 11 | public override void WriteJson(JsonWriter writer, AbstractHotkeyAction value, JsonSerializer serializer) 12 | { 13 | var token = JObject.FromObject(value); 14 | token.AddFirst(new JProperty("type", value.GetType().ToString())); 15 | token.WriteTo(writer); 16 | } 17 | 18 | public override AbstractHotkeyAction ReadJson(JsonReader reader, Type objectType, AbstractHotkeyAction existingValue, bool hasExistingValue, 19 | JsonSerializer serializer) 20 | { 21 | var hotkey = JObject.Load(reader); 22 | hotkey.Remove("name"); 23 | 24 | var hotkeyTypeName = (hotkey["type"] ?? throw new InvalidOperationException("Type missing from Hotkey!")).Value(); 25 | var hotkeyType = GetHotkeyType(hotkeyTypeName); 26 | 27 | var result = Activator.CreateInstance(hotkeyType); 28 | serializer.Populate(hotkey.CreateReader(), result); 29 | 30 | return result as AbstractHotkeyAction; 31 | } 32 | 33 | 34 | private static Type GetHotkeyType(string typeName) 35 | { 36 | return AbstractHotkeyAction.HotkeyTypes.First(type => type.ToString().Equals(typeName)); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /util/diablo/D3Client.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.util.diablo 2 | { 3 | using System; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Runtime.InteropServices; 7 | using System.Windows.Forms; 8 | 9 | public static class D3Client 10 | { 11 | private static Process Handle; 12 | 13 | public static Process GetHandle() 14 | { 15 | if (Handle != null) 16 | return Handle; 17 | 18 | var processList = Process.GetProcessesByName("Diablo III"); 19 | 20 | if (!processList.Any()) 21 | { 22 | processList = Process.GetProcessesByName("Diablo III64"); 23 | 24 | if (!processList.Any()) 25 | { 26 | MessageBox.Show("Diablo not found!"); 27 | Application.Exit(); 28 | Environment.Exit(0); 29 | } 30 | } 31 | 32 | Handle = processList[0]; 33 | return Handle; 34 | } 35 | 36 | public static bool IsInForeground() 37 | { 38 | return GetForegroundWindow() == GetHandle().MainWindowHandle; 39 | } 40 | 41 | public static void BringToFront() 42 | { 43 | SetForegroundWindow(Handle.MainWindowHandle); 44 | } 45 | 46 | [DllImport("user32.dll")] 47 | private static extern IntPtr GetForegroundWindow(); 48 | 49 | [DllImport("user32.dll")] 50 | private static extern bool SetForegroundWindow(IntPtr hWnd); 51 | } 52 | } -------------------------------------------------------------------------------- /util/executors/ThreadedExecutor.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.util.executors 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Threading; 6 | using logger; 7 | 8 | public class ThreadedExecutor 9 | { 10 | private readonly Dictionary identifierToExecutionTime = new Dictionary(); 11 | 12 | public void Execute(Action action, string identifier, long minimumTimeElapsed) 13 | { 14 | var now = DateTimeOffset.Now.ToUnixTimeMilliseconds(); 15 | 16 | if (!identifierToExecutionTime.ContainsKey(identifier)) 17 | identifierToExecutionTime.Add(identifier, now); 18 | else 19 | { 20 | var lastExecutionTime = identifierToExecutionTime[identifier]; 21 | if (now - lastExecutionTime < minimumTimeElapsed) 22 | return; 23 | 24 | identifierToExecutionTime[identifier] = now; 25 | } 26 | 27 | new Thread(() => ExecuteWithErrorHandling(action)).Start(); 28 | } 29 | 30 | private static void ExecuteWithErrorHandling(Action action) 31 | { 32 | try 33 | { 34 | action.Invoke(); 35 | } 36 | catch (Exception e) 37 | { 38 | Logger.error("ThreadedExecutor execution error: " + e); 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /util/executors/TimedRetryExecutor.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.util.executors 2 | { 3 | using System; 4 | using System.Threading; 5 | 6 | public class TimedRetryExecutor 7 | { 8 | private int elapsed; 9 | 10 | private bool success; 11 | 12 | private readonly int intervalMs; 13 | 14 | private readonly int maxTimeMs; 15 | 16 | private readonly Func condition; 17 | 18 | public TimedRetryExecutor(int maxTimeMs, int intervalMs, Func condition) 19 | { 20 | this.intervalMs = intervalMs; 21 | this.maxTimeMs = maxTimeMs; 22 | this.condition = condition; 23 | } 24 | 25 | public bool Invoke() 26 | { 27 | while (!success && elapsed < maxTimeMs) 28 | { 29 | Execute(); 30 | Thread.Sleep(intervalMs); 31 | } 32 | 33 | return success; 34 | } 35 | 36 | private void Execute() 37 | { 38 | success = condition.Invoke(); 39 | elapsed += intervalMs; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /util/logger/LogLevel.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.Plugins.Patrick.util 2 | { 3 | public enum LogLevel 4 | { 5 | ERROR = 3, 6 | WARN = 2, 7 | INFO = 1, 8 | DEBUG = 0 9 | } 10 | } -------------------------------------------------------------------------------- /util/logger/Logger.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.util.logger 2 | { 3 | using Plugins; 4 | using Plugins.Patrick.util; 5 | 6 | public static class Logger 7 | { 8 | private const string LOG_FILE_PATH = @"phelper.log"; 9 | 10 | private static ITextLogController LogController; 11 | 12 | public static LogLevel LogLevel = LogLevel.WARN; 13 | 14 | public static void Initialize(IController hud) 15 | { 16 | LogController = hud.TextLog; 17 | } 18 | 19 | private static void log(string text) 20 | { 21 | LogController?.Log(LOG_FILE_PATH, text); 22 | } 23 | 24 | public static void error(string text) 25 | { 26 | log("[ ERROR ] " + text); 27 | } 28 | 29 | public static void warn(string text) 30 | { 31 | if (LogLevel > LogLevel.WARN) 32 | return; 33 | 34 | log("[ WARN ] " + text); 35 | } 36 | 37 | public static void info(string text) 38 | { 39 | if (LogLevel > LogLevel.INFO) 40 | return; 41 | 42 | log("[ INFO ] " + text); 43 | } 44 | 45 | public static void debug(string text) 46 | { 47 | if (LogLevel > LogLevel.DEBUG) 48 | return; 49 | 50 | log("[ DEBUG ] " + text); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /util/thud/MethodExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.util.thud 2 | { 3 | using System.Drawing; 4 | using input; 5 | using Plugins.Patrick.forms; 6 | using Plugins.Patrick.util; 7 | using Plugins; 8 | 9 | public static class MethodExtensions 10 | { 11 | public static void Click(this IUiElement uiElement) 12 | { 13 | uiElement.Rectangle.Click(); 14 | } 15 | 16 | public static void RightClick(this IUiElement uiElement) 17 | { 18 | uiElement.Rectangle.RightClick(); 19 | } 20 | 21 | public static void Click(this RectangleF rectangleF) 22 | { 23 | InputSimulator.PostMessageMouseClickLeft(rectangleF.GetCenter()); 24 | } 25 | 26 | public static void RightClick(this RectangleF rectangleF) 27 | { 28 | InputSimulator.PostMessageMouseClickRight(rectangleF.GetCenter()); 29 | } 30 | 31 | public static void Click(this IItem item) 32 | { 33 | InputSimulator.PostMessageMouseClickLeft((int)item.FloorCoordinate.ToScreenCoordinate().X, (int)item.FloorCoordinate.ToScreenCoordinate().Y); 34 | } 35 | 36 | public static void Cast(this IPlayerSkill skill) 37 | { 38 | InputSimulator.PressKey(Settings.Keybinds[(int)skill.Key]); 39 | } 40 | 41 | public static bool CursorInsideRect(this IWindow window, RectangleF rectangle) 42 | { 43 | return window.CursorInsideRect(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height); 44 | } 45 | 46 | private static Point GetCenter(this RectangleF rectangleF) 47 | { 48 | return new Point( 49 | (int)(rectangleF.X + (rectangleF.Width / 2)), 50 | (int)(rectangleF.Y + (rectangleF.Height / 2)) 51 | ); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /util/thud/RenderControllerMethodExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Turbo.plugins.patrick.util.thud 2 | { 3 | using System; 4 | using System.Threading; 5 | using System.Windows.Forms; 6 | using diablo; 7 | using executors; 8 | using input; 9 | using logger; 10 | using Plugins; 11 | using Plugins.Patrick.forms; 12 | 13 | public static class RenderControllerFunctions 14 | { 15 | public static void WaitForVisiblityAndRightClickOrAbortHotkeyEvent(this IRenderController renderController, string path, 16 | int maxWaitTimeMs = 2000, int intervalMs = 25) 17 | { 18 | WaitForVisiblityAndClickOrAbortHotkeyEvent(renderController, path, maxWaitTimeMs, intervalMs, false); 19 | } 20 | 21 | public static void WaitForVisiblityAndClickOrAbortHotkeyEvent(this IRenderController renderController, string path, 22 | int maxWaitTimeMs = 2000, int intervalMs = 25, bool leftClick = true) 23 | { 24 | WaitForConditionOrAbortHotkeyEvent(() => renderController.IsUiElementVisible(path), maxWaitTimeMs, intervalMs); 25 | if (leftClick) 26 | renderController.GetOrRegisterAndGetUiElement(path).Click(); 27 | else 28 | renderController.GetOrRegisterAndGetUiElement(path).RightClick(); 29 | } 30 | 31 | public static void WaitForConditionOrAbortHotkeyEvent(Func condition, int maxWaitTimeMs = 2000, int intervalMs = 25) 32 | { 33 | var result = new TimedRetryExecutor(maxWaitTimeMs, intervalMs, condition).Invoke(); 34 | 35 | if (!result) 36 | Logger.warn("WaitForConditionOrAbortHotkeyEvent - Condition was not met after max time elapsed: " + condition.Method); 37 | } 38 | 39 | public static void CloseChatAndOpenWindows(this IRenderController renderController) 40 | { 41 | if (renderController.IsUiElementVisible(UiPathConstants.Ui.CHAT_INPUT)) 42 | { 43 | InputSimulator.PressKey(Keys.Escape); 44 | WaitForConditionOrAbortHotkeyEvent(() => !renderController.IsUiElementVisible(UiPathConstants.Ui.CHAT_INPUT)); 45 | } 46 | 47 | InputSimulator.PressKey(Settings.Keybinds[(int)ActionKey.Close]); 48 | Thread.Sleep(25); 49 | } 50 | 51 | public static bool IsUiElementVisible(this IRenderController renderController, string path) 52 | { 53 | var uiElement = renderController.GetOrRegisterAndGetUiElement(path); 54 | return !(uiElement is null) && uiElement.Visible; 55 | } 56 | 57 | public static IUiElement GetOrRegisterAndGetUiElement(this IRenderController renderController, string path) 58 | { 59 | var layer = renderController.GetUiElement(path) ?? 60 | renderController.RegisterUiElement(path, null, null); 61 | 62 | return layer; 63 | } 64 | 65 | public static bool IsShopOpen(this IRenderController renderController) 66 | { 67 | return renderController.IsUiElementVisible(UiPathConstants.Vendor.CURRENCY_TYPE); 68 | } 69 | } 70 | } --------------------------------------------------------------------------------